tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / miscdlgs / retypepassdlg.cxx
blob4dc5808a8bae532e83acb7f93a524b98533e20b7
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 .
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>
27 ScRetypePassDlg::ScRetypePassDlg(weld::Window* pParent)
28 : GenericDialogController(pParent, u"modules/scalc/ui/retypepassdialog.ui"_ustr,
29 u"RetypePass"_ustr)
30 , maTextNotProtected(ScResId(STR_NOT_PROTECTED))
31 , maTextNotPassProtected(ScResId(STR_NOT_PASS_PROTECTED))
32 , maTextHashBad(ScResId(STR_HASH_BAD))
33 , maTextHashGood(ScResId(STR_HASH_GOOD))
34 , meDesiredHash(PASSHASH_SHA1)
35 , mxBtnOk(m_xBuilder->weld_button(u"ok"_ustr))
36 , mxTextDocStatus(m_xBuilder->weld_label(u"docStatusLabel"_ustr))
37 , mxBtnRetypeDoc(m_xBuilder->weld_button(u"retypeDocButton"_ustr))
38 , mxScrolledWindow(m_xBuilder->weld_scrolled_window(u"scrolledwindow"_ustr))
39 , mxSheetsBox(m_xBuilder->weld_container(u"sheetsBox"_ustr))
41 mxScrolledWindow->set_size_request(mxScrolledWindow->get_approximate_digit_width() * 46,
42 mxScrolledWindow->get_text_height() * 10);
43 Init();
46 ScRetypePassDlg::~ScRetypePassDlg() {}
48 void ScRetypePassDlg::DeleteSheets() { maSheets.clear(); }
50 short ScRetypePassDlg::run()
52 PopulateDialog();
53 CheckHashStatus();
54 return GenericDialogController::run();
57 PassFragment::PassFragment(weld::Widget* pParent)
58 : m_xBuilder(Application::CreateBuilder(pParent, u"modules/scalc/ui/passfragment.ui"_ustr))
59 , m_xSheetsBox(m_xBuilder->weld_container(u"PassEntry"_ustr))
60 , m_xName(m_xBuilder->weld_label(u"name"_ustr))
61 , m_xStatus(m_xBuilder->weld_label(u"status"_ustr))
62 , m_xButton(m_xBuilder->weld_button(u"button"_ustr))
64 m_xButton->set_label(ScResId(STR_RETYPE));
67 void ScRetypePassDlg::SetDataFromDocument(const ScDocument& rDoc)
69 DeleteSheets();
70 const ScDocProtection* pDocProtect = rDoc.GetDocProtection();
71 if (pDocProtect && pDocProtect->isProtected())
72 mpDocItem = std::make_shared<ScDocProtection>(*pDocProtect);
74 SCTAB nTabCount = rDoc.GetTableCount();
75 maTableItems.reserve(nTabCount);
76 maSheets.reserve(nTabCount);
77 for (SCTAB i = 0; i < nTabCount; ++i)
79 TableItem aTabItem;
80 rDoc.GetName(i, aTabItem.maName);
82 const ScTableProtection* pTabProtect = rDoc.GetTabProtection(i);
83 if (pTabProtect && pTabProtect->isProtected())
84 aTabItem.mpProtect = std::make_shared<ScTableProtection>(*pTabProtect);
86 maTableItems.push_back(aTabItem);
87 maSheets.emplace_back(new PassFragment(mxSheetsBox.get()));
88 maSheets.back()->m_xButton->connect_clicked(LINK(this, ScRetypePassDlg, RetypeBtnHdl));
92 void ScRetypePassDlg::SetDesiredHash(ScPasswordHash eHash) { meDesiredHash = eHash; }
94 void ScRetypePassDlg::WriteNewDataToDocument(ScDocument& rDoc) const
96 if (mpDocItem)
97 rDoc.SetDocProtection(mpDocItem.get());
99 size_t nTabCount = static_cast<size_t>(rDoc.GetTableCount());
100 size_t n = maTableItems.size();
101 for (size_t i = 0; i < n; ++i)
103 if (i >= nTabCount)
104 break;
106 ScTableProtection* pTabProtect = maTableItems[i].mpProtect.get();
107 if (pTabProtect)
108 rDoc.SetTabProtection(static_cast<SCTAB>(i), pTabProtect);
112 void ScRetypePassDlg::Init()
114 Link<weld::Button&, void> aLink = LINK(this, ScRetypePassDlg, OKHdl);
115 mxBtnOk->connect_clicked(aLink);
117 aLink = LINK(this, ScRetypePassDlg, RetypeBtnHdl);
118 mxBtnRetypeDoc->connect_clicked(aLink);
120 mxTextDocStatus->set_label(maTextNotProtected);
121 mxBtnRetypeDoc->set_sensitive(false);
124 void ScRetypePassDlg::PopulateDialog()
126 // Document protection first.
127 SetDocData();
129 // Sheet protection next.
130 for (size_t i = 0; i < maTableItems.size(); ++i)
131 SetTableData(i, static_cast<SCTAB>(i));
134 void ScRetypePassDlg::SetDocData()
136 bool bBtnEnabled = false;
137 if (mpDocItem && mpDocItem->isProtected())
139 if (mpDocItem->isPasswordEmpty())
140 mxTextDocStatus->set_label(maTextNotPassProtected);
141 else if (mpDocItem->hasPasswordHash(meDesiredHash))
142 mxTextDocStatus->set_label(maTextHashGood);
143 else
145 // incompatible hash
146 mxTextDocStatus->set_label(maTextHashBad);
147 bBtnEnabled = true;
150 mxBtnRetypeDoc->set_sensitive(bBtnEnabled);
153 void ScRetypePassDlg::SetTableData(size_t nRowPos, SCTAB nTab)
155 if (nRowPos >= maSheets.size())
156 return;
158 weld::Label& rName = *maSheets[nRowPos]->m_xName;
159 weld::Label& rStatus = *maSheets[nRowPos]->m_xStatus;
160 weld::Button& rBtn = *maSheets[nRowPos]->m_xButton;
162 bool bBtnEnabled = false;
163 rName.set_label(maTableItems[nTab].maName);
164 const ScTableProtection* pTabProtect = maTableItems[nTab].mpProtect.get();
165 if (pTabProtect && pTabProtect->isProtected())
167 if (pTabProtect->isPasswordEmpty())
168 rStatus.set_label(maTextNotPassProtected);
169 else if (pTabProtect->hasPasswordHash(meDesiredHash))
170 rStatus.set_label(maTextHashGood);
171 else
173 // incompatible hash
174 rStatus.set_label(maTextHashBad);
175 bBtnEnabled = true;
178 else
179 rStatus.set_label(maTextNotProtected);
181 rBtn.set_sensitive(bBtnEnabled);
184 static bool lcl_IsInGoodStatus(const ScPassHashProtectable* pProtected, ScPasswordHash eDesiredHash)
186 if (!pProtected || !pProtected->isProtected())
187 // Not protected.
188 return true;
190 if (pProtected->isPasswordEmpty())
191 return true;
193 if (pProtected->hasPasswordHash(eDesiredHash))
194 return true;
196 return false;
199 void ScRetypePassDlg::CheckHashStatus()
203 if (!lcl_IsInGoodStatus(mpDocItem.get(), meDesiredHash))
204 break;
206 bool bStatusGood = true;
207 size_t nTabCount = maTableItems.size();
208 for (size_t i = 0; i < nTabCount && bStatusGood; ++i)
210 if (!lcl_IsInGoodStatus(maTableItems[i].mpProtect.get(), meDesiredHash))
211 bStatusGood = false;
213 if (!bStatusGood)
214 break;
216 mxBtnOk->set_sensitive(true);
217 return;
218 } while (false);
220 mxBtnOk->set_sensitive(false);
223 IMPL_LINK_NOARG(ScRetypePassDlg, OKHdl, weld::Button&, void) { m_xDialog->response(RET_OK); }
225 IMPL_LINK(ScRetypePassDlg, RetypeBtnHdl, weld::Button&, rBtn, void)
227 ScPassHashProtectable* pProtected = nullptr;
228 if (&rBtn == mxBtnRetypeDoc.get())
230 // document protection.
231 pProtected = mpDocItem.get();
233 else
235 // sheet protection.
236 size_t aPos = 0;
237 while (aPos < maSheets.size() && &rBtn != maSheets[aPos]->m_xButton.get())
238 ++aPos;
240 pProtected = aPos < maSheets.size() ? maTableItems[aPos].mpProtect.get() : nullptr;
243 if (!pProtected)
244 // What the ... !?
245 return;
247 ScRetypePassInputDlg aDlg(m_xDialog.get(), pProtected);
248 if (aDlg.run() != RET_OK)
249 return;
251 // OK is pressed. Update the protected item.
252 if (aDlg.IsRemovePassword())
254 // Remove password from this item.
255 pProtected->setPassword(OUString());
257 else
259 // Set a new password.
260 OUString aNewPass = aDlg.GetNewPassword();
261 pProtected->setPassword(aNewPass);
264 SetDocData();
265 CheckHashStatus();
268 ScRetypePassInputDlg::ScRetypePassInputDlg(weld::Window* pParent, ScPassHashProtectable* pProtected)
269 : GenericDialogController(pParent, u"modules/scalc/ui/retypepassworddialog.ui"_ustr,
270 u"RetypePasswordDialog"_ustr)
271 , m_pProtected(pProtected)
272 , m_xBtnOk(m_xBuilder->weld_button(u"ok"_ustr))
273 , m_xBtnRetypePassword(m_xBuilder->weld_radio_button(u"retypepassword"_ustr))
274 , m_xPasswordGrid(m_xBuilder->weld_widget(u"passwordgrid"_ustr))
275 , m_xPassword1Edit(m_xBuilder->weld_entry(u"newpassEntry"_ustr))
276 , m_xPassword2Edit(m_xBuilder->weld_entry(u"confirmpassEntry"_ustr))
277 , m_xBtnMatchOldPass(m_xBuilder->weld_check_button(u"mustmatch"_ustr))
278 , m_xBtnRemovePassword(m_xBuilder->weld_radio_button(u"removepassword"_ustr))
280 Init();
283 ScRetypePassInputDlg::~ScRetypePassInputDlg() {}
285 bool ScRetypePassInputDlg::IsRemovePassword() const { return m_xBtnRemovePassword->get_active(); }
287 OUString ScRetypePassInputDlg::GetNewPassword() const { return m_xPassword1Edit->get_text(); }
289 void ScRetypePassInputDlg::Init()
291 m_xBtnOk->connect_clicked(LINK(this, ScRetypePassInputDlg, OKHdl));
292 m_xBtnRetypePassword->connect_toggled(LINK(this, ScRetypePassInputDlg, RadioBtnHdl));
293 m_xBtnRemovePassword->connect_toggled(LINK(this, ScRetypePassInputDlg, RadioBtnHdl));
294 m_xBtnMatchOldPass->connect_toggled(LINK(this, ScRetypePassInputDlg, CheckBoxHdl));
295 Link<weld::Entry&, void> aLink2 = LINK(this, ScRetypePassInputDlg, PasswordModifyHdl);
296 m_xPassword1Edit->connect_changed(aLink2);
297 m_xPassword2Edit->connect_changed(aLink2);
299 m_xBtnOk->set_sensitive(false);
300 m_xBtnRetypePassword->set_active(true);
301 m_xBtnMatchOldPass->set_active(true);
302 m_xPassword1Edit->grab_focus();
305 void ScRetypePassInputDlg::CheckPasswordInput()
307 OUString aPass1 = m_xPassword1Edit->get_text();
308 OUString aPass2 = m_xPassword2Edit->get_text();
310 if (aPass1.isEmpty() || aPass2.isEmpty())
312 // Empty password is not allowed.
313 m_xBtnOk->set_sensitive(false);
314 return;
317 if (aPass1 != aPass2)
319 // The two passwords differ.
320 m_xBtnOk->set_sensitive(false);
321 return;
324 if (!m_xBtnMatchOldPass->get_active())
326 m_xBtnOk->set_sensitive(true);
327 return;
330 if (!m_pProtected)
332 // This should never happen!
333 m_xBtnOk->set_sensitive(false);
334 return;
337 bool bPassGood = m_pProtected->verifyPassword(aPass1);
338 m_xBtnOk->set_sensitive(bPassGood);
341 IMPL_LINK_NOARG(ScRetypePassInputDlg, OKHdl, weld::Button&, void) { m_xDialog->response(RET_OK); }
343 IMPL_LINK_NOARG(ScRetypePassInputDlg, RadioBtnHdl, weld::Toggleable&, void)
345 if (m_xBtnRetypePassword->get_active())
347 m_xPasswordGrid->set_sensitive(true);
348 CheckPasswordInput();
350 else
352 m_xPasswordGrid->set_sensitive(false);
353 m_xBtnOk->set_sensitive(true);
357 IMPL_LINK_NOARG(ScRetypePassInputDlg, CheckBoxHdl, weld::Toggleable&, void)
359 CheckPasswordInput();
362 IMPL_LINK_NOARG(ScRetypePassInputDlg, PasswordModifyHdl, weld::Entry&, void)
364 CheckPasswordInput();
367 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */