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