Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / ui / miscdlgs / retypepassdlg.cxx
blob307966bb328835e21a54775b650f96778209ae27
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "retypepassdlg.hxx"
22 #include "retypepassdlg.hrc"
23 #include "scresid.hxx"
24 #include "document.hxx"
25 #include "tabprotection.hxx"
27 #include <stdio.h>
29 #include <vcl/msgbox.hxx>
31 ScRetypePassDlg::ScRetypePassDlg(Window* pParent) :
32 ModalDialog(pParent, ScResId(RID_SCDLG_RETYPEPASS)),
34 maBtnOk (this, ScResId(BTN_OK)),
35 maBtnCancel (this, ScResId(BTN_CANCEL)),
36 maBtnHelp (this, ScResId(BTN_HELP)),
38 maTextDescription(this, ScResId(FT_DESC)),
39 maLineDocument(this, ScResId(FL_DOCUMENT)),
40 maTextDocStatus(this, ScResId(FT_DOCSTATUS)),
41 maBtnRetypeDoc(this, ScResId(BTN_RETYPE_DOC)),
43 maLineSheet(this, ScResId(FL_SHEET)),
44 maTextSheetName1(this, ScResId(FT_SHEETNAME1)),
45 maTextSheetStatus1(this, ScResId(FT_SHEETSTATUS1)),
46 maBtnRetypeSheet1(this, ScResId(BTN_RETYPE_SHEET1)),
48 maTextSheetName2(this, ScResId(FT_SHEETNAME2)),
49 maTextSheetStatus2(this, ScResId(FT_SHEETSTATUS2)),
50 maBtnRetypeSheet2(this, ScResId(BTN_RETYPE_SHEET2)),
52 maTextSheetName3(this, ScResId(FT_SHEETNAME3)),
53 maTextSheetStatus3(this, ScResId(FT_SHEETSTATUS3)),
54 maBtnRetypeSheet3(this, ScResId(BTN_RETYPE_SHEET3)),
56 maTextSheetName4(this, ScResId(FT_SHEETNAME4)),
57 maTextSheetStatus4(this, ScResId(FT_SHEETSTATUS4)),
58 maBtnRetypeSheet4(this, ScResId(BTN_RETYPE_SHEET4)),
60 maScrollBar (this, ScResId(SB_SCROLL)),
62 maTextNotProtected(ScResId(STR_NOT_PROTECTED)),
63 maTextNotPassProtected(ScResId(STR_NOT_PASS_PROTECTED)),
64 maTextHashBad(ScResId(STR_HASH_BAD)),
65 maTextHashGood(ScResId(STR_HASH_GOOD)),
66 maTextHashRegen(ScResId(STR_HASH_REGENERATED)),
68 mpDocItem(static_cast<ScDocProtection*>(NULL)),
69 mnCurScrollPos(0),
70 meDesiredHash(PASSHASH_SHA1)
72 Init();
73 FreeResource();
76 ScRetypePassDlg::~ScRetypePassDlg()
80 short ScRetypePassDlg::Execute()
82 PopulateDialog();
83 CheckHashStatus();
84 return ModalDialog::Execute();
87 void ScRetypePassDlg::SetDataFromDocument(const ScDocument& rDoc)
89 const ScDocProtection* pDocProtect = rDoc.GetDocProtection();
90 if (pDocProtect && pDocProtect->isProtected())
91 mpDocItem.reset(new ScDocProtection(*pDocProtect));
93 SCTAB nTabCount = rDoc.GetTableCount();
94 maTableItems.reserve(nTabCount);
95 for (SCTAB i = 0; i < nTabCount; ++i)
97 TableItem aTabItem;
98 rDoc.GetName(i, aTabItem.maName);
100 const ScTableProtection* pTabProtect = rDoc.GetTabProtection(i);
101 if (pTabProtect && pTabProtect->isProtected())
102 aTabItem.mpProtect.reset(new ScTableProtection(*pTabProtect));
104 maTableItems.push_back(aTabItem);
108 void ScRetypePassDlg::SetDesiredHash(ScPasswordHash eHash)
110 meDesiredHash = eHash;
113 void ScRetypePassDlg::WriteNewDataToDocument(ScDocument& rDoc) const
115 if (mpDocItem.get())
116 rDoc.SetDocProtection(mpDocItem.get());
118 size_t nTabCount = static_cast<size_t>(rDoc.GetTableCount());
119 size_t n = maTableItems.size();
120 for (size_t i = 0; i < n; ++i)
122 if (i >= nTabCount)
123 break;
125 ScTableProtection* pTabProtect = maTableItems[i].mpProtect.get();
126 if (pTabProtect)
127 rDoc.SetTabProtection(static_cast<SCTAB>(i), pTabProtect);
131 void ScRetypePassDlg::Init()
133 Link aLink = LINK( this, ScRetypePassDlg, OKHdl );
134 maBtnOk.SetClickHdl(aLink);
136 aLink = LINK( this, ScRetypePassDlg, RetypeBtnHdl );
137 maBtnRetypeDoc.SetClickHdl(aLink);
138 maBtnRetypeSheet1.SetClickHdl(aLink);
139 maBtnRetypeSheet2.SetClickHdl(aLink);
140 maBtnRetypeSheet3.SetClickHdl(aLink);
141 maBtnRetypeSheet4.SetClickHdl(aLink);
143 maTextDocStatus.SetText(maTextNotProtected);
144 maTextSheetStatus1.SetText(maTextNotProtected);
145 maTextSheetStatus2.SetText(maTextNotProtected);
146 maTextSheetStatus3.SetText(maTextNotProtected);
147 maTextSheetStatus4.SetText(maTextNotProtected);
148 maBtnRetypeDoc.Disable();
150 // Make all sheet rows invisible.
152 maTextSheetName1.Show(false);
153 maTextSheetStatus1.Show(false);
154 maBtnRetypeSheet1.Show(false);
155 maBtnRetypeSheet1.Disable();
157 maTextSheetName2.Show(false);
158 maTextSheetStatus2.Show(false);
159 maBtnRetypeSheet2.Show(false);
160 maBtnRetypeSheet2.Disable();
162 maTextSheetName3.Show(false);
163 maTextSheetStatus3.Show(false);
164 maBtnRetypeSheet3.Show(false);
165 maBtnRetypeSheet3.Disable();
167 maTextSheetName4.Show(false);
168 maTextSheetStatus4.Show(false);
169 maBtnRetypeSheet4.Show(false);
170 maBtnRetypeSheet4.Disable();
172 maScrollBar.Show(false);
174 maScrollBar.SetEndScrollHdl( LINK( this, ScRetypePassDlg, ScrollHdl ) );
175 maScrollBar.SetScrollHdl( LINK( this, ScRetypePassDlg, ScrollHdl ) );
177 maScrollBar.SetPageSize(4);
178 maScrollBar.SetVisibleSize(4);
179 maScrollBar.SetLineSize(1);
182 void ScRetypePassDlg::PopulateDialog()
184 // Document protection first.
185 SetDocData();
187 // Sheet protection next. We're only interested in the first 4 sheets
188 // (or less).
189 size_t n = maTableItems.size();
190 for (size_t i = 0; i < n && i < 4; ++i)
191 SetTableData(i, static_cast< SCTAB >( i ));
193 if (n > 4)
195 maScrollBar.Show(true);
196 maScrollBar.SetRange(Range(0, n));
200 void ScRetypePassDlg::SetDocData()
202 bool bBtnEnabled = false;
203 if (mpDocItem.get() && mpDocItem->isProtected())
205 if (mpDocItem->isPasswordEmpty())
206 maTextDocStatus.SetText(maTextNotPassProtected);
207 else if (mpDocItem->hasPasswordHash(meDesiredHash))
208 maTextDocStatus.SetText(maTextHashGood);
209 else
211 // incompatible hash
212 maTextDocStatus.SetText(maTextHashBad);
213 bBtnEnabled = true;
216 maBtnRetypeDoc.Enable(bBtnEnabled);
219 void ScRetypePassDlg::SetTableData(size_t nRowPos, SCTAB nTab)
221 if (nRowPos >= 4)
222 return;
224 FixedText* pName = NULL;
225 FixedText* pStatus = NULL;
226 PushButton* pBtn = NULL;
227 switch (nRowPos)
229 case 0:
230 pName = &maTextSheetName1;
231 pStatus = &maTextSheetStatus1;
232 pBtn = &maBtnRetypeSheet1;
233 break;
234 case 1:
235 pName = &maTextSheetName2;
236 pStatus = &maTextSheetStatus2;
237 pBtn = &maBtnRetypeSheet2;
238 break;
239 case 2:
240 pName = &maTextSheetName3;
241 pStatus = &maTextSheetStatus3;
242 pBtn = &maBtnRetypeSheet3;
243 break;
244 case 3:
245 pName = &maTextSheetName4;
246 pStatus = &maTextSheetStatus4;
247 pBtn = &maBtnRetypeSheet4;
248 break;
249 default:
250 return;
253 bool bBtnEnabled = false;
254 pName->SetText(maTableItems[nTab].maName);
255 pName->Show(true);
256 const ScTableProtection* pTabProtect = maTableItems[nTab].mpProtect.get();
257 if (pTabProtect && pTabProtect->isProtected())
259 if (pTabProtect->isPasswordEmpty())
260 pStatus->SetText(maTextNotPassProtected);
261 else if (pTabProtect->hasPasswordHash(meDesiredHash))
262 pStatus->SetText(maTextHashGood);
263 else
265 // incompatible hash
266 pStatus->SetText(maTextHashBad);
267 bBtnEnabled = true;
270 else
271 pStatus->SetText(maTextNotProtected);
273 pStatus->Show(true);
274 pBtn->Show(true);
275 pBtn->Enable(bBtnEnabled);
278 void ScRetypePassDlg::ResetTableRows()
280 long nScrollPos = maScrollBar.GetThumbPos();
281 mnCurScrollPos = nScrollPos < 0 ? 0 : nScrollPos;
282 size_t nRowCount = maTableItems.size() - nScrollPos;
283 for (size_t i = 0; i < nRowCount; ++i)
284 SetTableData(i, static_cast< SCTAB >( i + nScrollPos ));
287 static bool lcl_IsInGoodStatus(ScPassHashProtectable* pProtected, ScPasswordHash eDesiredHash)
289 if (!pProtected || !pProtected->isProtected())
290 // Not protected.
291 return true;
293 if (pProtected->isPasswordEmpty())
294 return true;
296 if (pProtected->hasPasswordHash(eDesiredHash))
297 return true;
299 return false;
302 void ScRetypePassDlg::CheckHashStatus()
306 if (!lcl_IsInGoodStatus(mpDocItem.get(), meDesiredHash))
307 break;
309 bool bStatusGood = true;
310 size_t nTabCount = maTableItems.size();
311 for (size_t i = 0; i < nTabCount && bStatusGood; ++i)
313 if (!lcl_IsInGoodStatus(maTableItems[i].mpProtect.get(), meDesiredHash))
314 bStatusGood = false;
316 if (!bStatusGood)
317 break;
319 maBtnOk.Enable();
320 return;
322 while (false);
324 maBtnOk.Disable();
327 IMPL_LINK_NOARG(ScRetypePassDlg, OKHdl)
329 EndDialog(RET_OK);
330 return 0;
333 IMPL_LINK( ScRetypePassDlg, RetypeBtnHdl, PushButton*, pBtn )
335 ScPassHashProtectable* pProtected = NULL;
336 if (pBtn == &maBtnRetypeDoc)
338 // document protection.
339 pProtected = mpDocItem.get();
341 else
343 // sheet protection.
344 size_t nTabPos = mnCurScrollPos;
345 if (pBtn == &maBtnRetypeSheet2)
346 nTabPos += 1;
347 else if (pBtn == &maBtnRetypeSheet3)
348 nTabPos += 2;
349 else if (pBtn == &maBtnRetypeSheet4)
350 nTabPos += 3;
351 else if (pBtn != &maBtnRetypeSheet1)
352 // This should never happen !
353 return 0;
355 if (nTabPos >= maTableItems.size())
356 // Likewise, this should never happen !
357 return 0;
359 pProtected = maTableItems[nTabPos].mpProtect.get();
362 if (!pProtected)
363 // What the ... !?
364 return 0;
366 ScRetypePassInputDlg aDlg(this, pProtected);
367 if (aDlg.Execute() == RET_OK)
369 // OK is pressed. Update the protected item.
370 if (aDlg.IsRemovePassword())
372 // Remove password from this item.
373 pProtected->setPassword(OUString());
375 else
377 // Set a new password.
378 OUString aNewPass = aDlg.GetNewPassword();
379 pProtected->setPassword(aNewPass);
382 SetDocData();
383 ResetTableRows();
384 CheckHashStatus();
386 return 0;
389 IMPL_LINK_NOARG(ScRetypePassDlg, ScrollHdl)
391 ResetTableRows();
392 return 0;
395 // ============================================================================
397 ScRetypePassInputDlg::ScRetypePassInputDlg(Window* pParent, ScPassHashProtectable* pProtected) :
398 ModalDialog(pParent, ScResId(RID_SCDLG_RETYPEPASS_INPUT)),
400 maBtnOk (this, ScResId(BTN_OK)),
401 maBtnCancel (this, ScResId(BTN_CANCEL)),
402 maBtnHelp (this, ScResId(BTN_HELP)),
404 maBtnRetypePassword(this, ScResId(BTN_RETYPE_PASSWORD)),
406 maPassword1Text (this, ScResId(FT_PASSWORD1)),
407 maPassword1Edit (this, ScResId(ED_PASSWORD1)),
408 maPassword2Text (this, ScResId(FT_PASSWORD2)),
409 maPassword2Edit (this, ScResId(ED_PASSWORD2)),
410 maBtnMatchOldPass(this, ScResId(BTN_MATCH_OLD_PASSWORD)),
412 maBtnRemovePassword(this, ScResId(BTN_REMOVE_PASSWORD)),
414 mpProtected(pProtected)
416 Init();
417 FreeResource();
420 ScRetypePassInputDlg::~ScRetypePassInputDlg()
424 short ScRetypePassInputDlg::Execute()
426 return ModalDialog::Execute();
429 bool ScRetypePassInputDlg::IsRemovePassword() const
431 return maBtnRemovePassword.IsChecked();
434 OUString ScRetypePassInputDlg::GetNewPassword() const
436 return maPassword1Edit.GetText();
439 void ScRetypePassInputDlg::Init()
441 Link aLink = LINK( this, ScRetypePassInputDlg, OKHdl );
442 maBtnOk.SetClickHdl(aLink);
443 aLink = LINK( this, ScRetypePassInputDlg, RadioBtnHdl );
444 maBtnRetypePassword.SetClickHdl(aLink);
445 maBtnRemovePassword.SetClickHdl(aLink);
446 aLink = LINK( this, ScRetypePassInputDlg, CheckBoxHdl );
447 maBtnMatchOldPass.SetClickHdl(aLink);
448 aLink = LINK( this, ScRetypePassInputDlg, PasswordModifyHdl );
449 maPassword1Edit.SetModifyHdl(aLink);
450 maPassword2Edit.SetModifyHdl(aLink);
452 maBtnOk.Disable();
453 maBtnRetypePassword.Check(true);
454 maBtnMatchOldPass.Check(true);
455 maPassword1Edit.GrabFocus();
458 void ScRetypePassInputDlg::CheckPasswordInput()
460 OUString aPass1 = maPassword1Edit.GetText();
461 OUString aPass2 = maPassword2Edit.GetText();
463 if (aPass1.isEmpty() || aPass2.isEmpty())
465 // Empty password is not allowed.
466 maBtnOk.Disable();
467 return;
470 if (aPass1 != aPass2)
472 // The two passwords differ.
473 maBtnOk.Disable();
474 return;
477 if (!maBtnMatchOldPass.IsChecked())
479 maBtnOk.Enable();
480 return;
483 if (!mpProtected)
485 // This should never happen!
486 maBtnOk.Disable();
487 return;
490 bool bPassGood = mpProtected->verifyPassword(aPass1);
491 maBtnOk.Enable(bPassGood);
494 IMPL_LINK_NOARG(ScRetypePassInputDlg, OKHdl)
496 EndDialog(RET_OK);
497 return 0;
500 IMPL_LINK( ScRetypePassInputDlg, RadioBtnHdl, RadioButton*, pBtn )
502 if (pBtn == &maBtnRetypePassword)
504 maBtnRemovePassword.Check(false);
505 maPassword1Text.Enable();
506 maPassword1Edit.Enable();
507 maPassword2Text.Enable();
508 maPassword2Edit.Enable();
509 maBtnMatchOldPass.Enable();
510 CheckPasswordInput();
512 else if (pBtn == &maBtnRemovePassword)
514 maBtnRetypePassword.Check(false);
515 maPassword1Text.Disable();
516 maPassword1Edit.Disable();
517 maPassword2Text.Disable();
518 maPassword2Edit.Disable();
519 maBtnMatchOldPass.Disable();
520 maBtnOk.Enable();
523 return 0;
526 IMPL_LINK_NOARG(ScRetypePassInputDlg, CheckBoxHdl)
528 CheckPasswordInput();
529 return 0;
532 IMPL_LINK_NOARG(ScRetypePassInputDlg, PasswordModifyHdl)
534 CheckPasswordInput();
535 return 0;
538 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */