1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
,
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);
46 ScRetypePassDlg::~ScRetypePassDlg() {}
48 void ScRetypePassDlg::DeleteSheets() { maSheets
.clear(); }
50 short ScRetypePassDlg::run()
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
)
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
)
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
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
)
106 ScTableProtection
* pTabProtect
= maTableItems
[i
].mpProtect
.get();
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.
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
);
146 mxTextDocStatus
->set_label(maTextHashBad
);
150 mxBtnRetypeDoc
->set_sensitive(bBtnEnabled
);
153 void ScRetypePassDlg::SetTableData(size_t nRowPos
, SCTAB nTab
)
155 if (nRowPos
>= maSheets
.size())
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
);
174 rStatus
.set_label(maTextHashBad
);
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())
190 if (pProtected
->isPasswordEmpty())
193 if (pProtected
->hasPasswordHash(eDesiredHash
))
199 void ScRetypePassDlg::CheckHashStatus()
203 if (!lcl_IsInGoodStatus(mpDocItem
.get(), meDesiredHash
))
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
))
216 mxBtnOk
->set_sensitive(true);
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();
237 while (aPos
< maSheets
.size() && &rBtn
!= maSheets
[aPos
]->m_xButton
.get())
240 pProtected
= aPos
< maSheets
.size() ? maTableItems
[aPos
].mpProtect
.get() : nullptr;
247 ScRetypePassInputDlg
aDlg(m_xDialog
.get(), pProtected
);
248 if (aDlg
.run() != RET_OK
)
251 // OK is pressed. Update the protected item.
252 if (aDlg
.IsRemovePassword())
254 // Remove password from this item.
255 pProtected
->setPassword(OUString());
259 // Set a new password.
260 OUString aNewPass
= aDlg
.GetNewPassword();
261 pProtected
->setPassword(aNewPass
);
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
))
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);
317 if (aPass1
!= aPass2
)
319 // The two passwords differ.
320 m_xBtnOk
->set_sensitive(false);
324 if (!m_xBtnMatchOldPass
->get_active())
326 m_xBtnOk
->set_sensitive(true);
332 // This should never happen!
333 m_xBtnOk
->set_sensitive(false);
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();
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: */