Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : #include "retypepassdlg.hxx"
22 : #include "retypepassdlg.hrc"
23 : #include "scresid.hxx"
24 : #include "document.hxx"
25 : #include "tabprotection.hxx"
26 :
27 : #include <stdio.h>
28 :
29 : #include <vcl/msgbox.hxx>
30 :
31 0 : ScRetypePassDlg::ScRetypePassDlg(Window* pParent) :
32 : ModalDialog(pParent, ScResId(RID_SCDLG_RETYPEPASS)),
33 :
34 : maBtnOk (this, ScResId(BTN_OK)),
35 : maBtnCancel (this, ScResId(BTN_CANCEL)),
36 : maBtnHelp (this, ScResId(BTN_HELP)),
37 :
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)),
42 :
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)),
47 :
48 : maTextSheetName2(this, ScResId(FT_SHEETNAME2)),
49 : maTextSheetStatus2(this, ScResId(FT_SHEETSTATUS2)),
50 : maBtnRetypeSheet2(this, ScResId(BTN_RETYPE_SHEET2)),
51 :
52 : maTextSheetName3(this, ScResId(FT_SHEETNAME3)),
53 : maTextSheetStatus3(this, ScResId(FT_SHEETSTATUS3)),
54 : maBtnRetypeSheet3(this, ScResId(BTN_RETYPE_SHEET3)),
55 :
56 : maTextSheetName4(this, ScResId(FT_SHEETNAME4)),
57 : maTextSheetStatus4(this, ScResId(FT_SHEETSTATUS4)),
58 : maBtnRetypeSheet4(this, ScResId(BTN_RETYPE_SHEET4)),
59 :
60 : maScrollBar (this, ScResId(SB_SCROLL)),
61 :
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)),
67 :
68 : mpDocItem(static_cast<ScDocProtection*>(NULL)),
69 : mnCurScrollPos(0),
70 0 : meDesiredHash(PASSHASH_SHA1)
71 : {
72 0 : Init();
73 0 : }
74 :
75 0 : ScRetypePassDlg::~ScRetypePassDlg()
76 : {
77 0 : }
78 :
79 0 : short ScRetypePassDlg::Execute()
80 : {
81 0 : PopulateDialog();
82 0 : CheckHashStatus();
83 0 : return ModalDialog::Execute();
84 : }
85 :
86 0 : void ScRetypePassDlg::SetDataFromDocument(const ScDocument& rDoc)
87 : {
88 0 : const ScDocProtection* pDocProtect = rDoc.GetDocProtection();
89 0 : if (pDocProtect && pDocProtect->isProtected())
90 0 : mpDocItem.reset(new ScDocProtection(*pDocProtect));
91 :
92 0 : SCTAB nTabCount = rDoc.GetTableCount();
93 0 : maTableItems.reserve(nTabCount);
94 0 : for (SCTAB i = 0; i < nTabCount; ++i)
95 : {
96 0 : TableItem aTabItem;
97 0 : rDoc.GetName(i, aTabItem.maName);
98 :
99 0 : const ScTableProtection* pTabProtect = rDoc.GetTabProtection(i);
100 0 : if (pTabProtect && pTabProtect->isProtected())
101 0 : aTabItem.mpProtect.reset(new ScTableProtection(*pTabProtect));
102 :
103 0 : maTableItems.push_back(aTabItem);
104 0 : }
105 0 : }
106 :
107 0 : void ScRetypePassDlg::SetDesiredHash(ScPasswordHash eHash)
108 : {
109 0 : meDesiredHash = eHash;
110 0 : }
111 :
112 0 : void ScRetypePassDlg::WriteNewDataToDocument(ScDocument& rDoc) const
113 : {
114 0 : if (mpDocItem.get())
115 0 : rDoc.SetDocProtection(mpDocItem.get());
116 :
117 0 : size_t nTabCount = static_cast<size_t>(rDoc.GetTableCount());
118 0 : size_t n = maTableItems.size();
119 0 : for (size_t i = 0; i < n; ++i)
120 : {
121 0 : if (i >= nTabCount)
122 0 : break;
123 :
124 0 : ScTableProtection* pTabProtect = maTableItems[i].mpProtect.get();
125 0 : if (pTabProtect)
126 0 : rDoc.SetTabProtection(static_cast<SCTAB>(i), pTabProtect);
127 : }
128 0 : }
129 :
130 0 : void ScRetypePassDlg::Init()
131 : {
132 0 : Link aLink = LINK( this, ScRetypePassDlg, OKHdl );
133 0 : maBtnOk.SetClickHdl(aLink);
134 :
135 0 : aLink = LINK( this, ScRetypePassDlg, RetypeBtnHdl );
136 0 : maBtnRetypeDoc.SetClickHdl(aLink);
137 0 : maBtnRetypeSheet1.SetClickHdl(aLink);
138 0 : maBtnRetypeSheet2.SetClickHdl(aLink);
139 0 : maBtnRetypeSheet3.SetClickHdl(aLink);
140 0 : maBtnRetypeSheet4.SetClickHdl(aLink);
141 :
142 0 : maTextDocStatus.SetText(maTextNotProtected);
143 0 : maTextSheetStatus1.SetText(maTextNotProtected);
144 0 : maTextSheetStatus2.SetText(maTextNotProtected);
145 0 : maTextSheetStatus3.SetText(maTextNotProtected);
146 0 : maTextSheetStatus4.SetText(maTextNotProtected);
147 0 : maBtnRetypeDoc.Disable();
148 :
149 : // Make all sheet rows invisible.
150 :
151 0 : maTextSheetName1.Show(false);
152 0 : maTextSheetStatus1.Show(false);
153 0 : maBtnRetypeSheet1.Show(false);
154 0 : maBtnRetypeSheet1.Disable();
155 :
156 0 : maTextSheetName2.Show(false);
157 0 : maTextSheetStatus2.Show(false);
158 0 : maBtnRetypeSheet2.Show(false);
159 0 : maBtnRetypeSheet2.Disable();
160 :
161 0 : maTextSheetName3.Show(false);
162 0 : maTextSheetStatus3.Show(false);
163 0 : maBtnRetypeSheet3.Show(false);
164 0 : maBtnRetypeSheet3.Disable();
165 :
166 0 : maTextSheetName4.Show(false);
167 0 : maTextSheetStatus4.Show(false);
168 0 : maBtnRetypeSheet4.Show(false);
169 0 : maBtnRetypeSheet4.Disable();
170 :
171 0 : maScrollBar.Show(false);
172 :
173 0 : maScrollBar.SetEndScrollHdl( LINK( this, ScRetypePassDlg, ScrollHdl ) );
174 0 : maScrollBar.SetScrollHdl( LINK( this, ScRetypePassDlg, ScrollHdl ) );
175 :
176 0 : maScrollBar.SetPageSize(4);
177 0 : maScrollBar.SetVisibleSize(4);
178 0 : maScrollBar.SetLineSize(1);
179 0 : }
180 :
181 0 : void ScRetypePassDlg::PopulateDialog()
182 : {
183 : // Document protection first.
184 0 : SetDocData();
185 :
186 : // Sheet protection next. We're only interested in the first 4 sheets
187 : // (or less).
188 0 : size_t n = maTableItems.size();
189 0 : for (size_t i = 0; i < n && i < 4; ++i)
190 0 : SetTableData(i, static_cast< SCTAB >( i ));
191 :
192 0 : if (n > 4)
193 : {
194 0 : maScrollBar.Show(true);
195 0 : maScrollBar.SetRange(Range(0, n));
196 : }
197 0 : }
198 :
199 0 : void ScRetypePassDlg::SetDocData()
200 : {
201 0 : bool bBtnEnabled = false;
202 0 : if (mpDocItem.get() && mpDocItem->isProtected())
203 : {
204 0 : if (mpDocItem->isPasswordEmpty())
205 0 : maTextDocStatus.SetText(maTextNotPassProtected);
206 0 : else if (mpDocItem->hasPasswordHash(meDesiredHash))
207 0 : maTextDocStatus.SetText(maTextHashGood);
208 : else
209 : {
210 : // incompatible hash
211 0 : maTextDocStatus.SetText(maTextHashBad);
212 0 : bBtnEnabled = true;
213 : }
214 : }
215 0 : maBtnRetypeDoc.Enable(bBtnEnabled);
216 0 : }
217 :
218 0 : void ScRetypePassDlg::SetTableData(size_t nRowPos, SCTAB nTab)
219 : {
220 0 : if (nRowPos >= 4)
221 0 : return;
222 :
223 0 : FixedText* pName = NULL;
224 0 : FixedText* pStatus = NULL;
225 0 : PushButton* pBtn = NULL;
226 0 : switch (nRowPos)
227 : {
228 : case 0:
229 0 : pName = &maTextSheetName1;
230 0 : pStatus = &maTextSheetStatus1;
231 0 : pBtn = &maBtnRetypeSheet1;
232 0 : break;
233 : case 1:
234 0 : pName = &maTextSheetName2;
235 0 : pStatus = &maTextSheetStatus2;
236 0 : pBtn = &maBtnRetypeSheet2;
237 0 : break;
238 : case 2:
239 0 : pName = &maTextSheetName3;
240 0 : pStatus = &maTextSheetStatus3;
241 0 : pBtn = &maBtnRetypeSheet3;
242 0 : break;
243 : case 3:
244 0 : pName = &maTextSheetName4;
245 0 : pStatus = &maTextSheetStatus4;
246 0 : pBtn = &maBtnRetypeSheet4;
247 0 : break;
248 : default:
249 0 : return;
250 : }
251 :
252 0 : bool bBtnEnabled = false;
253 0 : pName->SetText(maTableItems[nTab].maName);
254 0 : pName->Show(true);
255 0 : const ScTableProtection* pTabProtect = maTableItems[nTab].mpProtect.get();
256 0 : if (pTabProtect && pTabProtect->isProtected())
257 : {
258 0 : if (pTabProtect->isPasswordEmpty())
259 0 : pStatus->SetText(maTextNotPassProtected);
260 0 : else if (pTabProtect->hasPasswordHash(meDesiredHash))
261 0 : pStatus->SetText(maTextHashGood);
262 : else
263 : {
264 : // incompatible hash
265 0 : pStatus->SetText(maTextHashBad);
266 0 : bBtnEnabled = true;
267 : }
268 : }
269 : else
270 0 : pStatus->SetText(maTextNotProtected);
271 :
272 0 : pStatus->Show(true);
273 0 : pBtn->Show(true);
274 0 : pBtn->Enable(bBtnEnabled);
275 : }
276 :
277 0 : void ScRetypePassDlg::ResetTableRows()
278 : {
279 0 : long nScrollPos = maScrollBar.GetThumbPos();
280 0 : mnCurScrollPos = nScrollPos < 0 ? 0 : nScrollPos;
281 0 : size_t nRowCount = maTableItems.size() - nScrollPos;
282 0 : for (size_t i = 0; i < nRowCount; ++i)
283 0 : SetTableData(i, static_cast< SCTAB >( i + nScrollPos ));
284 0 : }
285 :
286 0 : static bool lcl_IsInGoodStatus(ScPassHashProtectable* pProtected, ScPasswordHash eDesiredHash)
287 : {
288 0 : if (!pProtected || !pProtected->isProtected())
289 : // Not protected.
290 0 : return true;
291 :
292 0 : if (pProtected->isPasswordEmpty())
293 0 : return true;
294 :
295 0 : if (pProtected->hasPasswordHash(eDesiredHash))
296 0 : return true;
297 :
298 0 : return false;
299 : }
300 :
301 0 : void ScRetypePassDlg::CheckHashStatus()
302 : {
303 : do
304 : {
305 0 : if (!lcl_IsInGoodStatus(mpDocItem.get(), meDesiredHash))
306 0 : break;
307 :
308 0 : bool bStatusGood = true;
309 0 : size_t nTabCount = maTableItems.size();
310 0 : for (size_t i = 0; i < nTabCount && bStatusGood; ++i)
311 : {
312 0 : if (!lcl_IsInGoodStatus(maTableItems[i].mpProtect.get(), meDesiredHash))
313 0 : bStatusGood = false;
314 : }
315 0 : if (!bStatusGood)
316 0 : break;
317 :
318 0 : maBtnOk.Enable();
319 0 : return;
320 : }
321 : while (false);
322 :
323 0 : maBtnOk.Disable();
324 : }
325 :
326 0 : IMPL_LINK_NOARG(ScRetypePassDlg, OKHdl)
327 : {
328 0 : EndDialog(RET_OK);
329 0 : return 0;
330 : }
331 :
332 0 : IMPL_LINK( ScRetypePassDlg, RetypeBtnHdl, PushButton*, pBtn )
333 : {
334 0 : ScPassHashProtectable* pProtected = NULL;
335 0 : if (pBtn == &maBtnRetypeDoc)
336 : {
337 : // document protection.
338 0 : pProtected = mpDocItem.get();
339 : }
340 : else
341 : {
342 : // sheet protection.
343 0 : size_t nTabPos = mnCurScrollPos;
344 0 : if (pBtn == &maBtnRetypeSheet2)
345 0 : nTabPos += 1;
346 0 : else if (pBtn == &maBtnRetypeSheet3)
347 0 : nTabPos += 2;
348 0 : else if (pBtn == &maBtnRetypeSheet4)
349 0 : nTabPos += 3;
350 0 : else if (pBtn != &maBtnRetypeSheet1)
351 : // This should never happen !
352 0 : return 0;
353 :
354 0 : if (nTabPos >= maTableItems.size())
355 : // Likewise, this should never happen !
356 0 : return 0;
357 :
358 0 : pProtected = maTableItems[nTabPos].mpProtect.get();
359 : }
360 :
361 0 : if (!pProtected)
362 : // What the ... !?
363 0 : return 0;
364 :
365 0 : ScRetypePassInputDlg aDlg(this, pProtected);
366 0 : if (aDlg.Execute() == RET_OK)
367 : {
368 : // OK is pressed. Update the protected item.
369 0 : if (aDlg.IsRemovePassword())
370 : {
371 : // Remove password from this item.
372 0 : pProtected->setPassword(String());
373 : }
374 : else
375 : {
376 : // Set a new password.
377 0 : String aNewPass = aDlg.GetNewPassword();
378 0 : pProtected->setPassword(aNewPass);
379 : }
380 :
381 0 : SetDocData();
382 0 : ResetTableRows();
383 0 : CheckHashStatus();
384 : }
385 0 : return 0;
386 : }
387 :
388 0 : IMPL_LINK_NOARG(ScRetypePassDlg, ScrollHdl)
389 : {
390 0 : ResetTableRows();
391 0 : return 0;
392 : }
393 :
394 : // ============================================================================
395 :
396 0 : ScRetypePassInputDlg::ScRetypePassInputDlg(Window* pParent, ScPassHashProtectable* pProtected) :
397 : ModalDialog(pParent, ScResId(RID_SCDLG_RETYPEPASS_INPUT)),
398 :
399 : maBtnOk (this, ScResId(BTN_OK)),
400 : maBtnCancel (this, ScResId(BTN_CANCEL)),
401 : maBtnHelp (this, ScResId(BTN_HELP)),
402 :
403 : maBtnRetypePassword(this, ScResId(BTN_RETYPE_PASSWORD)),
404 :
405 : maPassword1Text (this, ScResId(FT_PASSWORD1)),
406 : maPassword1Edit (this, ScResId(ED_PASSWORD1)),
407 : maPassword2Text (this, ScResId(FT_PASSWORD2)),
408 : maPassword2Edit (this, ScResId(ED_PASSWORD2)),
409 : maBtnMatchOldPass(this, ScResId(BTN_MATCH_OLD_PASSWORD)),
410 :
411 : maBtnRemovePassword(this, ScResId(BTN_REMOVE_PASSWORD)),
412 :
413 0 : mpProtected(pProtected)
414 : {
415 0 : Init();
416 0 : }
417 :
418 0 : ScRetypePassInputDlg::~ScRetypePassInputDlg()
419 : {
420 0 : }
421 :
422 0 : short ScRetypePassInputDlg::Execute()
423 : {
424 0 : return ModalDialog::Execute();
425 : }
426 :
427 0 : bool ScRetypePassInputDlg::IsRemovePassword() const
428 : {
429 0 : return maBtnRemovePassword.IsChecked();
430 : }
431 :
432 0 : String ScRetypePassInputDlg::GetNewPassword() const
433 : {
434 0 : return maPassword1Edit.GetText();
435 : }
436 :
437 0 : void ScRetypePassInputDlg::Init()
438 : {
439 0 : Link aLink = LINK( this, ScRetypePassInputDlg, OKHdl );
440 0 : maBtnOk.SetClickHdl(aLink);
441 0 : aLink = LINK( this, ScRetypePassInputDlg, RadioBtnHdl );
442 0 : maBtnRetypePassword.SetClickHdl(aLink);
443 0 : maBtnRemovePassword.SetClickHdl(aLink);
444 0 : aLink = LINK( this, ScRetypePassInputDlg, CheckBoxHdl );
445 0 : maBtnMatchOldPass.SetClickHdl(aLink);
446 0 : aLink = LINK( this, ScRetypePassInputDlg, PasswordModifyHdl );
447 0 : maPassword1Edit.SetModifyHdl(aLink);
448 0 : maPassword2Edit.SetModifyHdl(aLink);
449 :
450 0 : maBtnOk.Disable();
451 0 : maBtnRetypePassword.Check(true);
452 0 : maBtnMatchOldPass.Check(true);
453 0 : maPassword1Edit.GrabFocus();
454 0 : }
455 :
456 0 : void ScRetypePassInputDlg::CheckPasswordInput()
457 : {
458 0 : String aPass1 = maPassword1Edit.GetText();
459 0 : String aPass2 = maPassword2Edit.GetText();
460 :
461 0 : if (!aPass1.Len() || !aPass2.Len())
462 : {
463 : // Empty password is not allowed.
464 0 : maBtnOk.Disable();
465 : return;
466 : }
467 :
468 0 : if (!aPass1.Equals(aPass2))
469 : {
470 : // The two passwords differ.
471 0 : maBtnOk.Disable();
472 : return;
473 : }
474 :
475 0 : if (!maBtnMatchOldPass.IsChecked())
476 : {
477 0 : maBtnOk.Enable();
478 : return;
479 : }
480 :
481 0 : if (!mpProtected)
482 : {
483 : // This should never happen!
484 0 : maBtnOk.Disable();
485 : return;
486 : }
487 :
488 0 : bool bPassGood = mpProtected->verifyPassword(aPass1);
489 0 : maBtnOk.Enable(bPassGood);
490 : }
491 :
492 0 : IMPL_LINK_NOARG(ScRetypePassInputDlg, OKHdl)
493 : {
494 0 : EndDialog(RET_OK);
495 0 : return 0;
496 : }
497 :
498 0 : IMPL_LINK( ScRetypePassInputDlg, RadioBtnHdl, RadioButton*, pBtn )
499 : {
500 0 : if (pBtn == &maBtnRetypePassword)
501 : {
502 0 : maBtnRemovePassword.Check(false);
503 0 : maPassword1Text.Enable();
504 0 : maPassword1Edit.Enable();
505 0 : maPassword2Text.Enable();
506 0 : maPassword2Edit.Enable();
507 0 : maBtnMatchOldPass.Enable();
508 0 : CheckPasswordInput();
509 : }
510 0 : else if (pBtn == &maBtnRemovePassword)
511 : {
512 0 : maBtnRetypePassword.Check(false);
513 0 : maPassword1Text.Disable();
514 0 : maPassword1Edit.Disable();
515 0 : maPassword2Text.Disable();
516 0 : maPassword2Edit.Disable();
517 0 : maBtnMatchOldPass.Disable();
518 0 : maBtnOk.Enable();
519 : }
520 :
521 0 : return 0;
522 : }
523 :
524 0 : IMPL_LINK_NOARG(ScRetypePassInputDlg, CheckBoxHdl)
525 : {
526 0 : CheckPasswordInput();
527 0 : return 0;
528 : }
529 :
530 0 : IMPL_LINK_NOARG(ScRetypePassInputDlg, PasswordModifyHdl)
531 : {
532 0 : CheckPasswordInput();
533 0 : return 0;
534 : }
535 :
536 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|