LibreOffice Module sc (master) 1
retypepassdlg.cxx
Go to the documentation of this file.
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#include <vcl/svapp.hxx>
21#include <strings.hrc>
22#include <retypepassdlg.hxx>
23#include <scresid.hxx>
24#include <document.hxx>
25#include <tabprotection.hxx>
26
28 : GenericDialogController(pParent, "modules/scalc/ui/retypepassdialog.ui", "RetypePass")
29 , maTextNotProtected(ScResId(STR_NOT_PROTECTED))
30 , maTextNotPassProtected(ScResId(STR_NOT_PASS_PROTECTED))
31 , maTextHashBad(ScResId(STR_HASH_BAD))
32 , maTextHashGood(ScResId(STR_HASH_GOOD))
33 , meDesiredHash(PASSHASH_SHA1)
34 , mxBtnOk(m_xBuilder->weld_button("ok"))
35 , mxTextDocStatus(m_xBuilder->weld_label("docStatusLabel"))
36 , mxBtnRetypeDoc(m_xBuilder->weld_button("retypeDocButton"))
37 , mxScrolledWindow(m_xBuilder->weld_scrolled_window("scrolledwindow"))
38 , mxSheetsBox(m_xBuilder->weld_container("sheetsBox"))
39{
40 mxScrolledWindow->set_size_request(mxScrolledWindow->get_approximate_digit_width() * 46,
41 mxScrolledWindow->get_text_height() * 10);
42 Init();
43}
44
46
48
50{
53 return GenericDialogController::run();
54}
55
57 : m_xBuilder(Application::CreateBuilder(pParent, "modules/scalc/ui/passfragment.ui"))
58 , m_xSheetsBox(m_xBuilder->weld_container("PassEntry"))
59 , m_xName(m_xBuilder->weld_label("name"))
60 , m_xStatus(m_xBuilder->weld_label("status"))
61 , m_xButton(m_xBuilder->weld_button("button"))
62{
63 m_xButton->set_label(ScResId(STR_RETYPE));
64}
65
67{
69 const ScDocProtection* pDocProtect = rDoc.GetDocProtection();
70 if (pDocProtect && pDocProtect->isProtected())
71 mpDocItem = std::make_shared<ScDocProtection>(*pDocProtect);
72
73 SCTAB nTabCount = rDoc.GetTableCount();
74 maTableItems.reserve(nTabCount);
75 maSheets.reserve(nTabCount);
76 for (SCTAB i = 0; i < nTabCount; ++i)
77 {
78 TableItem aTabItem;
79 rDoc.GetName(i, aTabItem.maName);
80
81 const ScTableProtection* pTabProtect = rDoc.GetTabProtection(i);
82 if (pTabProtect && pTabProtect->isProtected())
83 aTabItem.mpProtect = std::make_shared<ScTableProtection>(*pTabProtect);
84
85 maTableItems.push_back(aTabItem);
86 maSheets.emplace_back(new PassFragment(mxSheetsBox.get()));
87 maSheets.back()->m_xButton->connect_clicked(LINK(this, ScRetypePassDlg, RetypeBtnHdl));
88 }
89}
90
92
94{
95 if (mpDocItem)
96 rDoc.SetDocProtection(mpDocItem.get());
97
98 size_t nTabCount = static_cast<size_t>(rDoc.GetTableCount());
99 size_t n = maTableItems.size();
100 for (size_t i = 0; i < n; ++i)
101 {
102 if (i >= nTabCount)
103 break;
104
105 ScTableProtection* pTabProtect = maTableItems[i].mpProtect.get();
106 if (pTabProtect)
107 rDoc.SetTabProtection(static_cast<SCTAB>(i), pTabProtect);
108 }
109}
110
112{
113 Link<weld::Button&, void> aLink = LINK(this, ScRetypePassDlg, OKHdl);
114 mxBtnOk->connect_clicked(aLink);
115
116 aLink = LINK(this, ScRetypePassDlg, RetypeBtnHdl);
117 mxBtnRetypeDoc->connect_clicked(aLink);
118
120 mxBtnRetypeDoc->set_sensitive(false);
121}
122
124{
125 // Document protection first.
126 SetDocData();
127
128 // Sheet protection next.
129 for (size_t i = 0; i < maTableItems.size(); ++i)
130 SetTableData(i, static_cast<SCTAB>(i));
131}
132
134{
135 bool bBtnEnabled = false;
136 if (mpDocItem && mpDocItem->isProtected())
137 {
138 if (mpDocItem->isPasswordEmpty())
140 else if (mpDocItem->hasPasswordHash(meDesiredHash))
142 else
143 {
144 // incompatible hash
145 mxTextDocStatus->set_label(maTextHashBad);
146 bBtnEnabled = true;
147 }
148 }
149 mxBtnRetypeDoc->set_sensitive(bBtnEnabled);
150}
151
152void ScRetypePassDlg::SetTableData(size_t nRowPos, SCTAB nTab)
153{
154 if (nRowPos >= maSheets.size())
155 return;
156
157 weld::Label& rName = *maSheets[nRowPos]->m_xName;
158 weld::Label& rStatus = *maSheets[nRowPos]->m_xStatus;
159 weld::Button& rBtn = *maSheets[nRowPos]->m_xButton;
160
161 bool bBtnEnabled = false;
162 rName.set_label(maTableItems[nTab].maName);
163 const ScTableProtection* pTabProtect = maTableItems[nTab].mpProtect.get();
164 if (pTabProtect && pTabProtect->isProtected())
165 {
166 if (pTabProtect->isPasswordEmpty())
168 else if (pTabProtect->hasPasswordHash(meDesiredHash))
169 rStatus.set_label(maTextHashGood);
170 else
171 {
172 // incompatible hash
173 rStatus.set_label(maTextHashBad);
174 bBtnEnabled = true;
175 }
176 }
177 else
179
180 rBtn.set_sensitive(bBtnEnabled);
181}
182
183static bool lcl_IsInGoodStatus(const ScPassHashProtectable* pProtected, ScPasswordHash eDesiredHash)
184{
185 if (!pProtected || !pProtected->isProtected())
186 // Not protected.
187 return true;
188
189 if (pProtected->isPasswordEmpty())
190 return true;
191
192 if (pProtected->hasPasswordHash(eDesiredHash))
193 return true;
194
195 return false;
196}
197
199{
200 do
201 {
203 break;
204
205 bool bStatusGood = true;
206 size_t nTabCount = maTableItems.size();
207 for (size_t i = 0; i < nTabCount && bStatusGood; ++i)
208 {
209 if (!lcl_IsInGoodStatus(maTableItems[i].mpProtect.get(), meDesiredHash))
210 bStatusGood = false;
211 }
212 if (!bStatusGood)
213 break;
214
215 mxBtnOk->set_sensitive(true);
216 return;
217 } while (false);
218
219 mxBtnOk->set_sensitive(false);
220}
221
223
224IMPL_LINK(ScRetypePassDlg, RetypeBtnHdl, weld::Button&, rBtn, void)
225{
226 ScPassHashProtectable* pProtected = nullptr;
227 if (&rBtn == mxBtnRetypeDoc.get())
228 {
229 // document protection.
230 pProtected = mpDocItem.get();
231 }
232 else
233 {
234 // sheet protection.
235 size_t aPos = 0;
236 while (aPos < maSheets.size() && &rBtn != maSheets[aPos]->m_xButton.get())
237 ++aPos;
238
239 pProtected = aPos < maSheets.size() ? maTableItems[aPos].mpProtect.get() : nullptr;
240 }
241
242 if (!pProtected)
243 // What the ... !?
244 return;
245
246 ScRetypePassInputDlg aDlg(m_xDialog.get(), pProtected);
247 if (aDlg.run() != RET_OK)
248 return;
249
250 // OK is pressed. Update the protected item.
251 if (aDlg.IsRemovePassword())
252 {
253 // Remove password from this item.
254 pProtected->setPassword(OUString());
255 }
256 else
257 {
258 // Set a new password.
259 OUString aNewPass = aDlg.GetNewPassword();
260 pProtected->setPassword(aNewPass);
261 }
262
263 SetDocData();
264 CheckHashStatus();
265}
266
268 : GenericDialogController(pParent, "modules/scalc/ui/retypepassworddialog.ui",
269 "RetypePasswordDialog")
270 , m_pProtected(pProtected)
271 , m_xBtnOk(m_xBuilder->weld_button("ok"))
272 , m_xBtnRetypePassword(m_xBuilder->weld_radio_button("retypepassword"))
273 , m_xPasswordGrid(m_xBuilder->weld_widget("passwordgrid"))
274 , m_xPassword1Edit(m_xBuilder->weld_entry("newpassEntry"))
275 , m_xPassword2Edit(m_xBuilder->weld_entry("confirmpassEntry"))
276 , m_xBtnMatchOldPass(m_xBuilder->weld_check_button("mustmatch"))
277 , m_xBtnRemovePassword(m_xBuilder->weld_radio_button("removepassword"))
278{
279 Init();
280}
281
283
285
286OUString ScRetypePassInputDlg::GetNewPassword() const { return m_xPassword1Edit->get_text(); }
287
289{
290 m_xBtnOk->connect_clicked(LINK(this, ScRetypePassInputDlg, OKHdl));
291 m_xBtnRetypePassword->connect_toggled(LINK(this, ScRetypePassInputDlg, RadioBtnHdl));
292 m_xBtnRemovePassword->connect_toggled(LINK(this, ScRetypePassInputDlg, RadioBtnHdl));
293 m_xBtnMatchOldPass->connect_toggled(LINK(this, ScRetypePassInputDlg, CheckBoxHdl));
294 Link<weld::Entry&, void> aLink2 = LINK(this, ScRetypePassInputDlg, PasswordModifyHdl);
295 m_xPassword1Edit->connect_changed(aLink2);
296 m_xPassword2Edit->connect_changed(aLink2);
297
298 m_xBtnOk->set_sensitive(false);
299 m_xBtnRetypePassword->set_active(true);
300 m_xBtnMatchOldPass->set_active(true);
301 m_xPassword1Edit->grab_focus();
302}
303
305{
306 OUString aPass1 = m_xPassword1Edit->get_text();
307 OUString aPass2 = m_xPassword2Edit->get_text();
308
309 if (aPass1.isEmpty() || aPass2.isEmpty())
310 {
311 // Empty password is not allowed.
312 m_xBtnOk->set_sensitive(false);
313 return;
314 }
315
316 if (aPass1 != aPass2)
317 {
318 // The two passwords differ.
319 m_xBtnOk->set_sensitive(false);
320 return;
321 }
322
323 if (!m_xBtnMatchOldPass->get_active())
324 {
325 m_xBtnOk->set_sensitive(true);
326 return;
327 }
328
329 if (!m_pProtected)
330 {
331 // This should never happen!
332 m_xBtnOk->set_sensitive(false);
333 return;
334 }
335
336 bool bPassGood = m_pProtected->verifyPassword(aPass1);
337 m_xBtnOk->set_sensitive(bPassGood);
338}
339
341
343{
344 if (m_xBtnRetypePassword->get_active())
345 {
346 m_xPasswordGrid->set_sensitive(true);
347 CheckPasswordInput();
348 }
349 else
350 {
351 m_xPasswordGrid->set_sensitive(false);
352 m_xBtnOk->set_sensitive(true);
353 }
354}
355
357{
358 CheckPasswordInput();
359}
360
362{
363 CheckPasswordInput();
364}
365
366/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XExecutableDialog > m_xDialog
OUString maName
virtual bool isProtected() const override
SC_DLLPUBLIC const ScTableProtection * GetTabProtection(SCTAB nTab) const
Definition: documen3.cxx:1928
SC_DLLPUBLIC ScDocProtection * GetDocProtection() const
Definition: documen3.cxx:1895
SC_DLLPUBLIC void SetDocProtection(const ScDocProtection *pProtect)
Definition: documen3.cxx:1900
SC_DLLPUBLIC void SetTabProtection(SCTAB nTab, const ScTableProtection *pProtect)
Definition: documen3.cxx:1936
SC_DLLPUBLIC bool GetName(SCTAB nTab, OUString &rName) const
Definition: document.cxx:217
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:317
virtual bool verifyPassword(const OUString &aPassText) const =0
virtual bool isProtected() const =0
virtual void setPassword(const OUString &aPassText)=0
virtual bool isPasswordEmpty() const =0
virtual bool hasPasswordHash(ScPasswordHash eHash, ScPasswordHash eHash2=PASSHASH_UNSPECIFIED) const =0
std::unique_ptr< weld::Button > mxBtnRetypeDoc
void WriteNewDataToDocument(ScDocument &rDoc) const
Write the new set of password data to the document instance to overwrite the current ones.
void SetDataFromDocument(const ScDocument &rDoc)
void SetDesiredHash(ScPasswordHash eHash)
OUString maTextNotPassProtected
std::shared_ptr< ScDocProtection > mpDocItem
void CheckHashStatus()
Check the status of all hash values to see if it's okay to enable the OK button.
::std::vector< TableItem > maTableItems
virtual ~ScRetypePassDlg() override
std::unique_ptr< weld::Container > mxSheetsBox
virtual short run() override
OUString maTextHashGood
ScPasswordHash meDesiredHash
std::unique_ptr< weld::ScrolledWindow > mxScrolledWindow
OUString maTextHashBad
ScRetypePassDlg(weld::Window *pParent)
OUString maTextNotProtected
std::unique_ptr< weld::Button > mxBtnOk
std::unique_ptr< weld::Label > mxTextDocStatus
void SetTableData(size_t nRowPos, SCTAB nTab)
std::vector< std::unique_ptr< PassFragment > > maSheets
std::unique_ptr< weld::RadioButton > m_xBtnRetypePassword
bool IsRemovePassword() const
std::unique_ptr< weld::RadioButton > m_xBtnRemovePassword
std::unique_ptr< weld::CheckButton > m_xBtnMatchOldPass
ScRetypePassInputDlg()=delete
std::unique_ptr< weld::Entry > m_xPassword2Edit
std::unique_ptr< weld::Button > m_xBtnOk
OUString GetNewPassword() const
std::unique_ptr< weld::Entry > m_xPassword1Edit
ScPassHashProtectable * m_pProtected
virtual ~ScRetypePassInputDlg() override
sheet protection state container
virtual bool hasPasswordHash(ScPasswordHash eHash, ScPasswordHash eHash2=PASSHASH_UNSPECIFIED) const override
virtual bool isPasswordEmpty() const override
virtual bool isProtected() const override
virtual short run()
virtual void set_label(const OUString &rText)=0
virtual void set_sensitive(bool sensitive)=0
sal_Int64 n
int i
IMPL_LINK(ScRetypePassDlg, RetypeBtnHdl, weld::Button &, rBtn, void)
static bool lcl_IsInGoodStatus(const ScPassHashProtectable *pProtected, ScPasswordHash eDesiredHash)
IMPL_LINK_NOARG(ScRetypePassDlg, OKHdl, weld::Button &, void)
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
std::unique_ptr< weld::Button > m_xButton
PassFragment(weld::Widget *pParent)
std::shared_ptr< ScTableProtection > mpProtect
ScPasswordHash
@ PASSHASH_SHA1
sal_Int16 SCTAB
Definition: types.hxx:22
RET_OK