blob: 726c296b9aa6ec5a4024ae7c6c9bc6be2bc729ff [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
#include "retypepassdlg.hxx"
#include "retypepassdlg.hrc"
#include "scresid.hxx"
#include "document.hxx"
#include "tabprotection.hxx"
#include <stdio.h>
#include <vcl/msgbox.hxx>
ScRetypePassDlg::ScRetypePassDlg(Window* pParent) :
ModalDialog(pParent, ScResId(RID_SCDLG_RETYPEPASS)),
maBtnOk (this, ScResId(BTN_OK)),
maBtnCancel (this, ScResId(BTN_CANCEL)),
maBtnHelp (this, ScResId(BTN_HELP)),
maTextDescription(this, ScResId(FT_DESC)),
maLineDocument(this, ScResId(FL_DOCUMENT)),
maTextDocStatus(this, ScResId(FT_DOCSTATUS)),
maBtnRetypeDoc(this, ScResId(BTN_RETYPE_DOC)),
maLineSheet(this, ScResId(FL_SHEET)),
maTextSheetName1(this, ScResId(FT_SHEETNAME1)),
maTextSheetStatus1(this, ScResId(FT_SHEETSTATUS1)),
maBtnRetypeSheet1(this, ScResId(BTN_RETYPE_SHEET1)),
maTextSheetName2(this, ScResId(FT_SHEETNAME2)),
maTextSheetStatus2(this, ScResId(FT_SHEETSTATUS2)),
maBtnRetypeSheet2(this, ScResId(BTN_RETYPE_SHEET2)),
maTextSheetName3(this, ScResId(FT_SHEETNAME3)),
maTextSheetStatus3(this, ScResId(FT_SHEETSTATUS3)),
maBtnRetypeSheet3(this, ScResId(BTN_RETYPE_SHEET3)),
maTextSheetName4(this, ScResId(FT_SHEETNAME4)),
maTextSheetStatus4(this, ScResId(FT_SHEETSTATUS4)),
maBtnRetypeSheet4(this, ScResId(BTN_RETYPE_SHEET4)),
maScrollBar (this, ScResId(SB_SCROLL)),
maTextNotProtected(ScResId(STR_NOT_PROTECTED)),
maTextNotPassProtected(ScResId(STR_NOT_PASS_PROTECTED)),
maTextHashBad(ScResId(STR_HASH_BAD)),
maTextHashGood(ScResId(STR_HASH_GOOD)),
maTextHashRegen(ScResId(STR_HASH_REGENERATED)),
mpDocItem(static_cast<ScDocProtection*>(NULL)),
mnCurScrollPos(0),
meDesiredHash(PASSHASH_OOO)
{
Init();
}
ScRetypePassDlg::~ScRetypePassDlg()
{
}
short ScRetypePassDlg::Execute()
{
PopulateDialog();
CheckHashStatus();
return ModalDialog::Execute();
}
void ScRetypePassDlg::SetDataFromDocument(const ScDocument& rDoc)
{
const ScDocProtection* pDocProtect = rDoc.GetDocProtection();
if (pDocProtect && pDocProtect->isProtected())
mpDocItem.reset(new ScDocProtection(*pDocProtect));
SCTAB nTabCount = rDoc.GetTableCount();
maTableItems.reserve(nTabCount);
for (SCTAB i = 0; i < nTabCount; ++i)
{
TableItem aTabItem;
rDoc.GetName(i, aTabItem.maName);
const ScTableProtection* pTabProtect = rDoc.GetTabProtection(i);
if (pTabProtect && pTabProtect->isProtected())
aTabItem.mpProtect.reset(new ScTableProtection(*pTabProtect));
maTableItems.push_back(aTabItem);
}
}
void ScRetypePassDlg::SetDesiredHash(ScPasswordHash eHash)
{
meDesiredHash = eHash;
}
void ScRetypePassDlg::WriteNewDataToDocument(ScDocument& rDoc) const
{
if (mpDocItem.get())
rDoc.SetDocProtection(mpDocItem.get());
size_t nTabCount = static_cast<size_t>(rDoc.GetTableCount());
size_t n = maTableItems.size();
for (size_t i = 0; i < n; ++i)
{
if (i >= nTabCount)
break;
ScTableProtection* pTabProtect = maTableItems[i].mpProtect.get();
if (pTabProtect)
rDoc.SetTabProtection(static_cast<SCTAB>(i), pTabProtect);
}
}
void ScRetypePassDlg::Init()
{
Link aLink = LINK( this, ScRetypePassDlg, OKHdl );
maBtnOk.SetClickHdl(aLink);
aLink = LINK( this, ScRetypePassDlg, RetypeBtnHdl );
maBtnRetypeDoc.SetClickHdl(aLink);
maBtnRetypeSheet1.SetClickHdl(aLink);
maBtnRetypeSheet2.SetClickHdl(aLink);
maBtnRetypeSheet3.SetClickHdl(aLink);
maBtnRetypeSheet4.SetClickHdl(aLink);
maTextDocStatus.SetText(maTextNotProtected);
maTextSheetStatus1.SetText(maTextNotProtected);
maTextSheetStatus2.SetText(maTextNotProtected);
maTextSheetStatus3.SetText(maTextNotProtected);
maTextSheetStatus4.SetText(maTextNotProtected);
maBtnRetypeDoc.Disable();
// Make all sheet rows invisible.
maTextSheetName1.Show(false);
maTextSheetStatus1.Show(false);
maBtnRetypeSheet1.Show(false);
maBtnRetypeSheet1.Disable();
maTextSheetName2.Show(false);
maTextSheetStatus2.Show(false);
maBtnRetypeSheet2.Show(false);
maBtnRetypeSheet2.Disable();
maTextSheetName3.Show(false);
maTextSheetStatus3.Show(false);
maBtnRetypeSheet3.Show(false);
maBtnRetypeSheet3.Disable();
maTextSheetName4.Show(false);
maTextSheetStatus4.Show(false);
maBtnRetypeSheet4.Show(false);
maBtnRetypeSheet4.Disable();
maScrollBar.Show(false);
maScrollBar.SetEndScrollHdl( LINK( this, ScRetypePassDlg, ScrollHdl ) );
maScrollBar.SetScrollHdl( LINK( this, ScRetypePassDlg, ScrollHdl ) );
maScrollBar.SetPageSize(4);
maScrollBar.SetVisibleSize(4);
maScrollBar.SetLineSize(1);
}
void ScRetypePassDlg::PopulateDialog()
{
// Document protection first.
SetDocData();
// Sheet protection next. We're only interested in the first 4 sheets
// (or less).
size_t n = maTableItems.size();
for (size_t i = 0; i < n && i < 4; ++i)
SetTableData(i, static_cast< SCTAB >( i ));
if (n > 4)
{
maScrollBar.Show(true);
maScrollBar.SetRange(Range(0, n));
}
}
void ScRetypePassDlg::SetDocData()
{
bool bBtnEnabled = false;
if (mpDocItem.get() && mpDocItem->isProtected())
{
if (mpDocItem->isPasswordEmpty())
maTextDocStatus.SetText(maTextNotPassProtected);
else if (mpDocItem->hasPasswordHash(meDesiredHash))
maTextDocStatus.SetText(maTextHashGood);
else
{
// incompatible hash
maTextDocStatus.SetText(maTextHashBad);
bBtnEnabled = true;
}
}
maBtnRetypeDoc.Enable(bBtnEnabled);
}
void ScRetypePassDlg::SetTableData(size_t nRowPos, SCTAB nTab)
{
if (nRowPos >= 4)
return;
FixedText* pName = NULL;
FixedText* pStatus = NULL;
PushButton* pBtn = NULL;
switch (nRowPos)
{
case 0:
pName = &maTextSheetName1;
pStatus = &maTextSheetStatus1;
pBtn = &maBtnRetypeSheet1;
break;
case 1:
pName = &maTextSheetName2;
pStatus = &maTextSheetStatus2;
pBtn = &maBtnRetypeSheet2;
break;
case 2:
pName = &maTextSheetName3;
pStatus = &maTextSheetStatus3;
pBtn = &maBtnRetypeSheet3;
break;
case 3:
pName = &maTextSheetName4;
pStatus = &maTextSheetStatus4;
pBtn = &maBtnRetypeSheet4;
break;
default:
return;
}
bool bBtnEnabled = false;
pName->SetText(maTableItems[nTab].maName);
pName->Show(true);
const ScTableProtection* pTabProtect = maTableItems[nTab].mpProtect.get();
if (pTabProtect && pTabProtect->isProtected())
{
if (pTabProtect->isPasswordEmpty())
pStatus->SetText(maTextNotPassProtected);
else if (pTabProtect->hasPasswordHash(meDesiredHash))
pStatus->SetText(maTextHashGood);
else
{
// incompatible hash
pStatus->SetText(maTextHashBad);
bBtnEnabled = true;
}
}
else
pStatus->SetText(maTextNotProtected);
pStatus->Show(true);
pBtn->Show(true);
pBtn->Enable(bBtnEnabled);
}
void ScRetypePassDlg::ResetTableRows()
{
long nScrollPos = maScrollBar.GetThumbPos();
mnCurScrollPos = nScrollPos < 0 ? 0 : nScrollPos;
size_t nRowCount = maTableItems.size() - nScrollPos;
for (size_t i = 0; i < nRowCount; ++i)
SetTableData(i, static_cast< SCTAB >( i + nScrollPos ));
}
bool lcl_IsInGoodStatus(ScPassHashProtectable* pProtected, ScPasswordHash eDesiredHash)
{
if (!pProtected || !pProtected->isProtected())
// Not protected.
return true;
if (pProtected->isPasswordEmpty())
return true;
if (pProtected->hasPasswordHash(eDesiredHash))
return true;
return false;
}
void ScRetypePassDlg::CheckHashStatus()
{
do
{
if (!lcl_IsInGoodStatus(mpDocItem.get(), meDesiredHash))
break;
bool bStatusGood = true;
size_t nTabCount = maTableItems.size();
for (size_t i = 0; i < nTabCount && bStatusGood; ++i)
{
if (!lcl_IsInGoodStatus(maTableItems[i].mpProtect.get(), meDesiredHash))
bStatusGood = false;
}
if (!bStatusGood)
break;
maBtnOk.Enable();
return;
}
while (false);
maBtnOk.Disable();
}
IMPL_LINK( ScRetypePassDlg, OKHdl, OKButton*, EMPTYARG )
{
EndDialog(RET_OK);
return 0;
}
IMPL_LINK( ScRetypePassDlg, RetypeBtnHdl, PushButton*, pBtn )
{
ScPassHashProtectable* pProtected = NULL;
if (pBtn == &maBtnRetypeDoc)
{
// document protection.
pProtected = mpDocItem.get();
}
else
{
// sheet protection.
size_t nTabPos = mnCurScrollPos;
if (pBtn == &maBtnRetypeSheet2)
nTabPos += 1;
else if (pBtn == &maBtnRetypeSheet3)
nTabPos += 2;
else if (pBtn == &maBtnRetypeSheet4)
nTabPos += 3;
else if (pBtn != &maBtnRetypeSheet1)
// This should never happen !
return 0;
if (nTabPos >= maTableItems.size())
// Likewise, this should never happen !
return 0;
pProtected = maTableItems[nTabPos].mpProtect.get();
}
if (!pProtected)
// What the ... !?
return 0;
ScRetypePassInputDlg aDlg(this, pProtected);
if (aDlg.Execute() == RET_OK)
{
// OK is pressed. Update the protected item.
if (aDlg.IsRemovePassword())
{
// Remove password from this item.
pProtected->setPassword(String());
}
else
{
// Set a new password.
String aNewPass = aDlg.GetNewPassword();
pProtected->setPassword(aNewPass);
}
SetDocData();
ResetTableRows();
CheckHashStatus();
}
return 0;
}
IMPL_LINK( ScRetypePassDlg, ScrollHdl, ScrollBar*, EMPTYARG )
{
ResetTableRows();
return 0;
}
// ============================================================================
ScRetypePassInputDlg::ScRetypePassInputDlg(Window* pParent, ScPassHashProtectable* pProtected) :
ModalDialog(pParent, ScResId(RID_SCDLG_RETYPEPASS_INPUT)),
maBtnOk (this, ScResId(BTN_OK)),
maBtnCancel (this, ScResId(BTN_CANCEL)),
maBtnHelp (this, ScResId(BTN_HELP)),
maBtnRetypePassword(this, ScResId(BTN_RETYPE_PASSWORD)),
maPassword1Text (this, ScResId(FT_PASSWORD1)),
maPassword1Edit (this, ScResId(ED_PASSWORD1)),
maPassword2Text (this, ScResId(FT_PASSWORD2)),
maPassword2Edit (this, ScResId(ED_PASSWORD2)),
maBtnMatchOldPass(this, ScResId(BTN_MATCH_OLD_PASSWORD)),
maBtnRemovePassword(this, ScResId(BTN_REMOVE_PASSWORD)),
mpProtected(pProtected)
{
Init();
}
ScRetypePassInputDlg::~ScRetypePassInputDlg()
{
}
short ScRetypePassInputDlg::Execute()
{
return ModalDialog::Execute();
}
bool ScRetypePassInputDlg::IsRemovePassword() const
{
return maBtnRemovePassword.IsChecked();
}
String ScRetypePassInputDlg::GetNewPassword() const
{
return maPassword1Edit.GetText();
}
void ScRetypePassInputDlg::Init()
{
Link aLink = LINK( this, ScRetypePassInputDlg, OKHdl );
maBtnOk.SetClickHdl(aLink);
aLink = LINK( this, ScRetypePassInputDlg, RadioBtnHdl );
maBtnRetypePassword.SetClickHdl(aLink);
maBtnRemovePassword.SetClickHdl(aLink);
aLink = LINK( this, ScRetypePassInputDlg, CheckBoxHdl );
maBtnMatchOldPass.SetClickHdl(aLink);
aLink = LINK( this, ScRetypePassInputDlg, PasswordModifyHdl );
maPassword1Edit.SetModifyHdl(aLink);
maPassword2Edit.SetModifyHdl(aLink);
maBtnOk.Disable();
maBtnRetypePassword.Check(true);
maBtnMatchOldPass.Check(true);
maPassword1Edit.GrabFocus();
}
void ScRetypePassInputDlg::CheckPasswordInput()
{
String aPass1 = maPassword1Edit.GetText();
String aPass2 = maPassword2Edit.GetText();
if (!aPass1.Len() || !aPass2.Len())
{
// Empty password is not allowed.
maBtnOk.Disable();
return;
}
if (!aPass1.Equals(aPass2))
{
// The two passwords differ.
maBtnOk.Disable();
return;
}
if (!maBtnMatchOldPass.IsChecked())
{
maBtnOk.Enable();
return;
}
if (!mpProtected)
{
// This should never happen!
maBtnOk.Disable();
return;
}
bool bPassGood = mpProtected->verifyPassword(aPass1);
maBtnOk.Enable(bPassGood);
}
IMPL_LINK( ScRetypePassInputDlg, OKHdl, OKButton*, EMPTYARG )
{
EndDialog(RET_OK);
return 0;
}
IMPL_LINK( ScRetypePassInputDlg, RadioBtnHdl, RadioButton*, pBtn )
{
if (pBtn == &maBtnRetypePassword)
{
maBtnRemovePassword.Check(false);
maPassword1Text.Enable();
maPassword1Edit.Enable();
maPassword2Text.Enable();
maPassword2Edit.Enable();
maBtnMatchOldPass.Enable();
CheckPasswordInput();
}
else if (pBtn == &maBtnRemovePassword)
{
maBtnRetypePassword.Check(false);
maPassword1Text.Disable();
maPassword1Edit.Disable();
maPassword2Text.Disable();
maPassword2Edit.Disable();
maBtnMatchOldPass.Disable();
maBtnOk.Enable();
}
return 0;
}
IMPL_LINK( ScRetypePassInputDlg, CheckBoxHdl, CheckBox*, EMPTYARG )
{
CheckPasswordInput();
return 0;
}
IMPL_LINK( ScRetypePassInputDlg, PasswordModifyHdl, Edit*, EMPTYARG )
{
CheckPasswordInput();
return 0;
}