summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorRelease Engineers <releng@openoffice.org>2009-07-01 08:58:41 +0000
committerRelease Engineers <releng@openoffice.org>2009-07-01 08:58:41 +0000
commit43bafd9dd74489bac28edb5bbdb8a7d0b2442cc5 (patch)
tree79b0b96d1002e5c06d1c8a00d7f2d8fc721521e2 /sc
parent6c06d29d13dedc08dd7cfbf74c8b8768b6297250 (diff)
CWS-TOOLING: integrate CWS scsheetprotection02
2009-06-18 16:48:14 +0200 kohei r273124 : #i102906# Fix a crasher when loading an xls document with unsupported encrytpion. 2009-06-15 14:02:00 +0200 dr r272982 : #i10000# compiler warnings 2009-04-13 23:06:21 +0200 kohei r270740 : Renamed SetData() to SetDataFromDocument(), in order to resolve name clash with the method of the same name in class Window. This caused a compiler warning on Solaris Intel. 2009-04-13 04:09:59 +0200 kohei r270729 : CWS-TOOLING: rebase CWS scsheetprotection02 to trunk@270723 (milestone: DEV300:m46) 2009-02-23 16:13:45 +0100 kohei r268361 : added tabprotection.obj to the exception file list. Apparently the older versions of boost::shared_ptr rely on C++ exceptions for its implementation. 2009-02-18 19:59:05 +0100 kohei r268253 : Switched to using ::boost::shared_ptr to wrap a pimpl class, because using ::std::auto_ptr in this header breaks the build on win32. The MSVC implementation of ::std::auto_ptr has some weird quirks... 2009-02-17 21:47:13 +0100 kohei r268192 : fixed linkage issue due to library split. 2009-02-17 04:50:34 +0100 kohei r267842 : CWS-TOOLING: rebase CWS scsheetprotection02 to trunk@267171 (milestone: DEV300:m41) 2009-02-17 02:36:10 +0100 kohei r267841 : reverted the last commit, to re-surrect the removed src files. 2009-02-03 22:02:34 +0100 kohei r267342 : removed the src files to prevent them from being entered into the translation process. The dialogs that need the strings are not yet enabled in the code, so their removal will not cause any harm. 2009-01-14 12:24:29 +0100 dr r266280 : #i10000# wntmsci12 compiler warnings #4 2009-01-14 09:35:46 +0100 dr r266267 : #i10000# wntmsci12 compiler warnings #3 2009-01-13 15:42:07 +0100 dr r266231 : #i10000# wntmsci12 compiler warnings #2 2009-01-13 13:18:28 +0100 dr r266216 : #i10000# wntmsci12 compiler warnings 2009-01-07 03:59:11 +0100 kohei r265943 : remove the fscking compiler warnings. 2009-01-06 15:55:32 +0100 kohei r265925 : removed compiler warnings that caused the buildbot build to fail.... 2009-01-05 23:24:59 +0100 kohei r265888 : Undoing my own local build fix to work around the libmoz... issue. 2008-12-30 21:39:58 +0100 kohei r265833 : Duh! Sheet protection was supposed to be disabled. :-/ 2008-12-23 20:25:55 +0100 kohei r265792 : recovered the code block that was accidentally removed during cws rebase. 2008-12-23 19:03:19 +0100 kohei r265791 : fixed breakage in ods export filter due to rebase to m38. 2008-12-23 16:41:49 +0100 kohei r265787 : CWS-TOOLING: rebase CWS scsheetprotection02 to trunk@265758 (milestone: DEV300:m38) 2008-12-23 05:37:47 +0100 kohei r265768 : deliberately forget document and sheet passwords when importing from or exporting to excel, to emulate the current behavior. 2008-12-23 05:12:59 +0100 kohei r265767 : removed commented-out unused method ScDocument::SetAutoFilterFlags(). 2008-12-23 05:05:19 +0100 kohei r265766 : removed one duplicate method and made associated changes with the removal, and a little more code cleanup. 2008-12-23 04:24:58 +0100 kohei r265765 : a typo in in-line comment 2008-12-23 04:23:08 +0100 kohei r265764 : remove fprintf statement that blatantly prints out document encryption password to stdout. not a good practice. 2008-12-23 04:14:21 +0100 kohei r265763 : we actually don't want to clear all options, because if we do, then we would no longer be able to select any cells on a protected sheet. 2008-12-23 04:07:10 +0100 kohei r265762 : * minor code cleanup (indentation inconsistencies & use of tab) * fixed unprotecting a sheet with password to make it work again. 2008-12-23 03:22:50 +0100 kohei r265761 : reverted all the new functionalities to the existing ones, while keeping the new code in as much as I could. 2008-12-22 23:11:08 +0100 kohei r265760 : in xls export filter, renamed two unknown records into records of known name. 2008-12-22 22:34:50 +0100 kohei r265759 : temporarily disable password capability on file export for MS Excel 97. 2008-12-22 17:01:21 +0100 kohei r265754 : CWS-TOOLING: rebase CWS scsheetprotection02 to trunk@264807 (milestone: DEV300:m37) 2008-11-26 03:12:58 +0100 kohei r264335 : recovered a method that was actually used. 2008-11-25 21:51:10 +0100 kohei r264334 : CWS-TOOLING: rebase CWS scsheetprotection02 to trunk@264325 (milestone: DEV300:m36) 2008-10-08 19:57:35 +0200 kohei r262094 : changed description string to make it less technical. 2008-10-01 05:56:58 +0200 kohei r261986 : migrated from the cvs-based cws. 2008-10-01 05:55:19 +0200 kohei r261985 : migrated from the cvs-based cws. 2008-10-01 05:55:00 +0200 kohei r261984 : migrated from the cvs-based cws.
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/document.hxx17
-rw-r--r--sc/inc/sc.hrc7
-rw-r--r--sc/inc/scextopt.hxx2
-rw-r--r--sc/inc/table.hxx13
-rw-r--r--sc/inc/tabprotection.hxx180
-rw-r--r--sc/source/core/data/documen2.cxx3
-rw-r--r--sc/source/core/data/documen3.cxx44
-rw-r--r--sc/source/core/data/document.cxx19
-rw-r--r--sc/source/core/data/makefile.mk2
-rw-r--r--sc/source/core/data/table1.cxx3
-rw-r--r--sc/source/core/data/table2.cxx12
-rw-r--r--sc/source/core/data/table5.cxx21
-rw-r--r--sc/source/core/data/tabprotection.cxx465
-rw-r--r--sc/source/filter/excel/excdoc.cxx65
-rw-r--r--sc/source/filter/excel/excimp8.cxx13
-rw-r--r--sc/source/filter/excel/excrecds.cxx31
-rw-r--r--sc/source/filter/excel/impop.cxx48
-rw-r--r--sc/source/filter/excel/read.cxx11
-rw-r--r--sc/source/filter/excel/xeroot.cxx44
-rw-r--r--sc/source/filter/excel/xestream.cxx309
-rw-r--r--sc/source/filter/excel/xicontent.cxx192
-rw-r--r--sc/source/filter/excel/xilink.cxx1
-rw-r--r--sc/source/filter/excel/xiroot.cxx26
-rw-r--r--sc/source/filter/excel/xistream.cxx17
-rw-r--r--sc/source/filter/excel/xlroot.cxx14
-rw-r--r--sc/source/filter/inc/excimp8.hxx2
-rw-r--r--sc/source/filter/inc/excrecds.hxx17
-rw-r--r--sc/source/filter/inc/imp_op.hxx6
-rw-r--r--sc/source/filter/inc/xcl97rec.hxx196
-rw-r--r--sc/source/filter/inc/xeroot.hxx5
-rw-r--r--sc/source/filter/inc/xestream.hxx114
-rw-r--r--sc/source/filter/inc/xetable.hxx2
-rw-r--r--sc/source/filter/inc/xicontent.hxx61
-rw-r--r--sc/source/filter/inc/xiroot.hxx16
-rw-r--r--sc/source/filter/inc/xistream.hxx5
-rw-r--r--sc/source/filter/inc/xlroot.hxx4
-rw-r--r--sc/source/filter/starcalc/scflt.cxx16
-rw-r--r--sc/source/filter/xcl97/XclExpChangeTrack.cxx1
-rw-r--r--sc/source/filter/xcl97/makefile.mk1
-rw-r--r--sc/source/filter/xcl97/xcl97rec.cxx358
-rw-r--r--sc/source/filter/xml/xmlbodyi.cxx13
-rw-r--r--sc/source/filter/xml/xmlexprt.cxx13
-rw-r--r--sc/source/filter/xml/xmlsubti.cxx16
-rw-r--r--sc/source/ui/docshell/docfunc.cxx194
-rw-r--r--sc/source/ui/docshell/docsh.cxx54
-rw-r--r--sc/source/ui/docshell/docsh5.cxx2
-rw-r--r--sc/source/ui/inc/docfunc.hxx4
-rw-r--r--sc/source/ui/inc/protectiondlg.hrc47
-rw-r--r--sc/source/ui/inc/protectiondlg.hxx85
-rw-r--r--sc/source/ui/inc/retypepassdlg.hrc74
-rw-r--r--sc/source/ui/inc/retypepassdlg.hxx177
-rw-r--r--sc/source/ui/inc/tabvwsh.hxx3
-rw-r--r--sc/source/ui/inc/undotab.hxx46
-rw-r--r--sc/source/ui/inc/viewfunc.hxx3
-rw-r--r--sc/source/ui/miscdlgs/makefile.mk16
-rw-r--r--sc/source/ui/miscdlgs/protectiondlg.cxx164
-rw-r--r--sc/source/ui/miscdlgs/protectiondlg.src130
-rw-r--r--sc/source/ui/miscdlgs/retypepassdlg.cxx547
-rw-r--r--sc/source/ui/miscdlgs/retypepassdlg.src316
-rw-r--r--sc/source/ui/undo/undotab.cxx303
-rw-r--r--sc/source/ui/unoobj/warnpassword.cxx1
-rw-r--r--sc/source/ui/view/gridwin.cxx40
-rw-r--r--sc/source/ui/view/scextopt.cxx4
-rw-r--r--sc/source/ui/view/select.cxx23
-rw-r--r--sc/source/ui/view/tabview3.cxx42
-rw-r--r--sc/source/ui/view/tabvwsh3.cxx210
-rw-r--r--sc/source/ui/view/tabvwshh.cxx21
-rw-r--r--sc/source/ui/view/viewfun2.cxx4
-rw-r--r--sc/source/ui/view/viewfunc.cxx30
69 files changed, 4369 insertions, 576 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 246a60a4b9d9..8185a3cb0735 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -90,6 +90,7 @@ class ScDBData;
class ScDetOpData;
class ScDetOpList;
class ScDocOptions;
+class ScDocProtection;
class ScDocumentPool;
class ScDrawLayer;
class ScExtDocOptions;
@@ -108,6 +109,7 @@ class ScRangeName;
class ScStyleSheet;
class ScStyleSheetPool;
class ScTable;
+class ScTableProtection;
class ScTokenArray;
class ScValidationData;
class ScValidationDataList;
@@ -286,7 +288,7 @@ private:
ScFieldEditEngine* pCacheFieldEditEngine;
- com::sun::star::uno::Sequence<sal_Int8> aProtectPass;
+ ::std::auto_ptr<ScDocProtection> pDocProtection;
::std::auto_ptr<ScExternalRefManager> pExternalRefMgr;
String aDocName; // opt: Dokumentname
@@ -350,7 +352,6 @@ private:
ScLkUpdMode eLinkMode;
- BOOL bProtected;
BOOL bAutoCalc; // Automatisch Berechnen
BOOL bAutoCalcShellDisabled; // in/von/fuer ScDocShell disabled
// ob noch ForcedFormulas berechnet werden muessen,
@@ -530,13 +531,14 @@ public:
SC_DLLPUBLIC inline SCTAB GetTableCount() const { return nMaxTableNumber; }
SvNumberFormatterIndexTable* GetFormatExchangeList() const { return pFormatExchangeList; }
- SC_DLLPUBLIC void SetDocProtection( BOOL bProtect, const com::sun::star::uno::Sequence <sal_Int8>& aPass );
- SC_DLLPUBLIC void SetTabProtection( SCTAB nTab, BOOL bProtect, const com::sun::star::uno::Sequence <sal_Int8>& aPass );
+ SC_DLLPUBLIC ScDocProtection* GetDocProtection() const;
+ SC_DLLPUBLIC void SetDocProtection(const ScDocProtection* pProtect);
SC_DLLPUBLIC BOOL IsDocProtected() const;
BOOL IsDocEditable() const;
SC_DLLPUBLIC BOOL IsTabProtected( SCTAB nTab ) const;
- const com::sun::star::uno::Sequence <sal_Int8>& GetDocPassword() const;
- const com::sun::star::uno::Sequence <sal_Int8>& GetTabPassword( SCTAB nTab ) const;
+ SC_DLLPUBLIC ScTableProtection* GetTabProtection( SCTAB nTab ) const;
+ SC_DLLPUBLIC void SetTabProtection(SCTAB nTab, const ScTableProtection* pProtect);
+ void CopyTabProtection(SCTAB nTabSrc, SCTAB nTabDest);
void LockTable(SCTAB nTab);
void UnlockTable(SCTAB nTab);
@@ -1475,7 +1477,8 @@ public:
private:
-//UNUSED2008-05 void SetAutoFilterFlags();
+ ScDocument(const ScDocument& r); // disabled with no definition
+
void FindMaxRotCol( SCTAB nTab, RowInfo* pRowInfo, SCSIZE nArrCount,
SCCOL nX1, SCCOL nX2 ) const;
diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc
index 35b6a403816d..8a36846da720 100644
--- a/sc/inc/sc.hrc
+++ b/sc/inc/sc.hrc
@@ -1631,7 +1631,12 @@
#define RID_SCDLG_CONFLICTS (SC_DIALOGS_START + 145)
#define RID_SCDLG_SHAREDOCUMENT (SC_DIALOGS_START + 146)
-#define SC_DIALOGS_END (SC_DIALOGS_START + 150)
+#define RID_SCDLG_TABPROTECTION (SC_DIALOGS_START + 147)
+#define RID_SCDLG_DOCPROTECTION (SC_DIALOGS_START + 148)
+#define RID_SCDLG_RETYPEPASS (SC_DIALOGS_START + 149)
+#define RID_SCDLG_RETYPEPASS_INPUT (SC_DIALOGS_START + 150)
+
+#define SC_DIALOGS_END (SC_DIALOGS_START + 151)
#ifndef STD_MASKCOLOR
#define STD_MASKCOLOR Color { Red = 0xFF00; Green = 0x0000; Blue = 0xFF00; }
diff --git a/sc/inc/scextopt.hxx b/sc/inc/scextopt.hxx
index 4b3f763b4e8c..fdf05430cc69 100644
--- a/sc/inc/scextopt.hxx
+++ b/sc/inc/scextopt.hxx
@@ -46,8 +46,6 @@ struct ScExtDocSettings
double mfTabBarWidth; /// Width of the tabbar, relative to frame window width (0.0 ... 1.0).
sal_uInt32 mnLinkCnt; /// Recursive counter for loading external documents.
SCTAB mnDisplTab; /// Index of displayed sheet.
- bool mbWinProtected; /// true = Window properties are protected.
- bool mbEncrypted; /// true = Imported file was encrypted.
explicit ScExtDocSettings();
};
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index e738ff5fbdb8..185d016e0dee 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -39,6 +39,8 @@
#include "sortparam.hxx"
#include "compressedarray.hxx"
+#include <memory>
+
namespace utl {
class SearchParam;
class TextSearch;
@@ -65,6 +67,7 @@ class ScRangeList;
class ScSortInfoArray;
class ScStyleSheet;
class ScTableLink;
+class ScTableProtection;
class ScUserListData;
class ScIndexMap;
struct RowInfo;
@@ -102,8 +105,7 @@ private:
SCROW nRepeatStartY;
SCROW nRepeatEndY;
- BOOL bProtected;
- com::sun::star::uno::Sequence<sal_Int8> aProtectPass;
+ ::std::auto_ptr<ScTableProtection> pTabProtection;
USHORT* pColWidth;
ScSummableCompressedArray< SCROW, USHORT>* pRowHeight;
@@ -218,10 +220,9 @@ public:
void SetPageStyle( const String& rName );
void PageStyleModified( const String& rNewName );
- BOOL IsProtected() const { return bProtected; }
- const com::sun::star::uno::Sequence<sal_Int8>& GetPassword() const { return aProtectPass; }
- void SetProtection( BOOL bProtect, const com::sun::star::uno::Sequence<sal_Int8>& rPasswd )
- { bProtected = bProtect; aProtectPass = rPasswd; }
+ BOOL IsProtected() const;
+ void SetProtection(const ScTableProtection* pProtect);
+ ScTableProtection* GetProtection();
Size GetPageSize() const;
void SetPageSize( const Size& rSize );
diff --git a/sc/inc/tabprotection.hxx b/sc/inc/tabprotection.hxx
new file mode 100644
index 000000000000..a11355833e4c
--- /dev/null
+++ b/sc/inc/tabprotection.hxx
@@ -0,0 +1,180 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: tabprotection.hxx,v $
+ * $Revision: 1.1.4.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_TAB_PROTECTION_HXX
+#define SC_TAB_PROTECTION_HXX
+
+#include "sal/types.h"
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include "global.hxx"
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+#define ENABLE_SHEET_PROTECTION 0
+
+class ScDocument;
+class ScTableProtectionImpl;
+
+enum ScPasswordHash
+{
+ PASSHASH_OOO = 0,
+ PASSHASH_XL
+};
+
+class ScPassHashHelper
+{
+public:
+ /** Check for the compatibility of all password hashes. If there is at
+ least one hash that needs to be regenerated, it returns true. If all
+ hash values are compatible with the specified hash type, then it
+ returns false. */
+ static bool needsPassHashRegen(const ScDocument& rDoc, ScPasswordHash eHash);
+
+private:
+ ScPassHashHelper();
+ ~ScPassHashHelper();
+};
+
+// ============================================================================
+
+class SAL_NO_VTABLE ScPassHashProtectable
+{
+public:
+ virtual ~ScPassHashProtectable() = 0;
+
+ virtual bool isProtected() const = 0;
+ virtual bool isProtectedWithPass() const = 0;
+ virtual void setProtected(bool bProtected) = 0;
+
+ virtual bool isPasswordEmpty() const = 0;
+ virtual bool hasPasswordHash(ScPasswordHash eHash) const = 0;
+ virtual void setPassword(const String& aPassText) = 0;
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> getPasswordHash(ScPasswordHash eHash) const = 0;
+ virtual void setPasswordHash(const ::com::sun::star::uno::Sequence<sal_Int8>& aPassword,
+ ScPasswordHash eHash = PASSHASH_OOO) = 0;
+ virtual bool verifyPassword(const String& aPassText) const = 0;
+};
+
+// ============================================================================
+
+class SC_DLLPUBLIC ScDocProtection : public ScPassHashProtectable
+{
+public:
+ enum Option
+ {
+ STRUCTURE = 0,
+ WINDOWS,
+ CONTENT,
+ NONE // last item - used to resize the vector
+ };
+
+ explicit ScDocProtection();
+ explicit ScDocProtection(const ScDocProtection& r);
+ virtual ~ScDocProtection();
+
+ virtual bool isProtected() const;
+ virtual bool isProtectedWithPass() const;
+ virtual void setProtected(bool bProtected);
+
+ virtual bool isPasswordEmpty() const;
+ virtual bool hasPasswordHash(ScPasswordHash eHash) const;
+ virtual void setPassword(const String& aPassText);
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> getPasswordHash(ScPasswordHash eHash) const;
+ virtual void setPasswordHash(const ::com::sun::star::uno::Sequence<sal_Int8>& aPassword,
+ ScPasswordHash eHash = PASSHASH_OOO);
+ virtual bool verifyPassword(const String& aPassText) const;
+
+ bool isOptionEnabled(Option eOption) const;
+ void setOption(Option eOption, bool bEnabled);
+
+private:
+ ::boost::shared_ptr<ScTableProtectionImpl> mpImpl;
+};
+
+// ============================================================================
+
+/** sheet protection state container
+
+ This class stores sheet's protection state: 1) whether the protection
+ is on, 2) password and/or password hash, and 3) any associated
+ protection options. This class is also used as a protection state
+ container for the undo/redo stack, in which case the password, hash and
+ the options need to be preserved even when the protection flag is
+ off. */
+class SC_DLLPUBLIC ScTableProtection : public ScPassHashProtectable
+{
+public:
+ enum Option
+ {
+ AUTOFILTER = 0,
+ DELETE_COLUMNS,
+ DELETE_ROWS,
+ FORMAT_CELLS,
+ FORMAT_COLUMNS,
+ FORMAT_ROWS,
+ INSERT_COLUMNS,
+ INSERT_HYPERLINKS,
+ INSERT_ROWS,
+ OBJECTS,
+ PIVOT_TABLES,
+ SCENARIOS,
+ SELECT_LOCKED_CELLS,
+ SELECT_UNLOCKED_CELLS,
+ SHEET,
+ SORT,
+ NONE // last item - used to resize the vector
+ };
+
+ explicit ScTableProtection();
+ explicit ScTableProtection(const ScTableProtection& r);
+ virtual ~ScTableProtection();
+
+ virtual bool isProtected() const;
+ virtual bool isProtectedWithPass() const;
+ virtual void setProtected(bool bProtected);
+
+ virtual bool isPasswordEmpty() const;
+ virtual bool hasPasswordHash(ScPasswordHash eHash) const;
+ virtual void setPassword(const String& aPassText);
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> getPasswordHash(ScPasswordHash eHash) const;
+ virtual void setPasswordHash(const ::com::sun::star::uno::Sequence<sal_Int8>& aPassword,
+ ScPasswordHash eHash = PASSHASH_OOO);
+ virtual bool verifyPassword(const String& aPassText) const;
+
+ bool isOptionEnabled(Option eOption) const;
+ void setOption(Option eOption, bool bEnabled);
+
+private:
+ ::boost::shared_ptr<ScTableProtectionImpl> mpImpl;
+};
+
+
+#endif
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index f5dbb14e9ff9..4bafff97c179 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -94,6 +94,7 @@
#include "recursionhelper.hxx"
#include "lookupcache.hxx"
#include "externalrefmgr.hxx"
+#include "tabprotection.hxx"
// pImpl because including lookupcache.hxx in document.hxx isn't wanted, and
// dtor plus helpers are convenient.
@@ -152,6 +153,7 @@ ScDocument::ScDocument( ScDocumentMode eMode,
pChangeViewSettings( NULL ),
pScriptTypeData( NULL ),
pCacheFieldEditEngine( NULL ),
+ pDocProtection( NULL ),
pExternalRefMgr( NULL ),
pViewOptions( NULL ),
pDocOptions( NULL ),
@@ -175,7 +177,6 @@ ScDocument::ScDocument( ScDocumentMode eMode,
nHardRecalcState(0),
nVisibleTab( 0 ),
eLinkMode(LM_UNKNOWN),
- bProtected( FALSE ),
bAutoCalc( eMode == SCDOCMODE_DOCUMENT ),
bAutoCalcShellDisabled( FALSE ),
bForcedFormulaPending( FALSE ),
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 2b3fbb359988..b194ecc4aa73 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -77,6 +77,8 @@
#include "drwlayer.hxx"
#include "unoreflist.hxx"
#include "listenercalls.hxx"
+#include "svtools/PasswordHelper.hxx"
+#include "tabprotection.hxx"
#include <memory>
@@ -1701,28 +1703,28 @@ void ScDocument::SnapVisArea( Rectangle& rRect ) const
ScDrawLayer::MirrorRectRTL( rRect ); // back to real rectangle
}
-void ScDocument::SetDocProtection( BOOL bProtect, const uno::Sequence<sal_Int8>& rPasswd )
+ScDocProtection* ScDocument::GetDocProtection() const
{
- bProtected = bProtect;
- aProtectPass = rPasswd;
+ return pDocProtection.get();
}
-void ScDocument::SetTabProtection( SCTAB nTab, BOOL bProtect, const uno::Sequence<sal_Int8>& rPasswd )
+void ScDocument::SetDocProtection(const ScDocProtection* pProtect)
{
- if (VALIDTAB(nTab))
- if (pTab[nTab])
- pTab[nTab]->SetProtection( bProtect, rPasswd );
+ if (pProtect)
+ pDocProtection.reset(new ScDocProtection(*pProtect));
+ else
+ pDocProtection.reset(NULL);
}
BOOL ScDocument::IsDocProtected() const
{
- return bProtected;
+ return pDocProtection.get() && pDocProtection->isProtected();
}
BOOL ScDocument::IsDocEditable() const
{
// import into read-only document is possible
- return !bProtected && ( bImportingXML || mbChangeReadOnlyEnabled || !pShell || !pShell->IsReadOnly() );
+ return !IsDocProtected() && ( bImportingXML || mbChangeReadOnlyEnabled || !pShell || !pShell->IsReadOnly() );
}
BOOL ScDocument::IsTabProtected( SCTAB nTab ) const
@@ -1734,18 +1736,28 @@ BOOL ScDocument::IsTabProtected( SCTAB nTab ) const
return FALSE;
}
-const uno::Sequence<sal_Int8>& ScDocument::GetDocPassword() const
+ScTableProtection* ScDocument::GetTabProtection( SCTAB nTab ) const
{
- return aProtectPass;
+ if (VALIDTAB(nTab) && pTab[nTab])
+ return pTab[nTab]->GetProtection();
+
+ return NULL;
}
-const uno::Sequence<sal_Int8>& ScDocument::GetTabPassword( SCTAB nTab ) const
+void ScDocument::SetTabProtection(SCTAB nTab, const ScTableProtection* pProtect)
{
- if (VALIDTAB(nTab) && pTab[nTab])
- return pTab[nTab]->GetPassword();
+ if (!ValidTab(nTab))
+ return;
- DBG_ERROR("Falsche Tabellennummer");
- return aProtectPass;
+ pTab[nTab]->SetProtection(pProtect);
+}
+
+void ScDocument::CopyTabProtection(SCTAB nTabSrc, SCTAB nTabDest)
+{
+ if (!ValidTab(nTabSrc) || !ValidTab(nTabDest))
+ return;
+
+ pTab[nTabDest]->SetProtection( pTab[nTabSrc]->GetProtection() );
}
const ScDocOptions& ScDocument::GetDocOptions() const
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 0dd6a5db10e2..c3074fae0b10 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -93,6 +93,7 @@
#include "bcaslot.hxx"
#include "postit.hxx"
#include "externalrefmgr.hxx"
+#include "tabprotection.hxx"
namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
@@ -4104,24 +4105,6 @@ BOOL ScDocument::RefreshAutoFilter( SCCOL nStartCol, SCROW nStartRow,
}
-//UNUSED2008-05 void ScDocument::SetAutoFilterFlags()
-//UNUSED2008-05 {
-//UNUSED2008-05 USHORT nCount = pDBCollection->GetCount();
-//UNUSED2008-05 for (USHORT i=0; i<nCount; i++)
-//UNUSED2008-05 {
-//UNUSED2008-05 ScDBData* pData = (*pDBCollection)[i];
-//UNUSED2008-05 SCTAB nDBTab;
-//UNUSED2008-05 SCCOL nDBStartCol;
-//UNUSED2008-05 SCROW nDBStartRow;
-//UNUSED2008-05 SCCOL nDBEndCol;
-//UNUSED2008-05 SCROW nDBEndRow;
-//UNUSED2008-05 pData->GetArea( nDBTab, nDBStartCol,nDBStartRow, nDBEndCol,nDBEndRow );
-//UNUSED2008-05 pData->SetAutoFilter( HasAttrib( nDBStartCol,nDBStartRow,nDBTab,
-//UNUSED2008-05 nDBEndCol,nDBStartRow,nDBTab, HASATTR_AUTOFILTER ) );
-//UNUSED2008-05 }
-//UNUSED2008-05 }
-
-
BOOL ScDocument::IsHorOverlapped( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
{
const ScMergeFlagAttr* pAttr = (const ScMergeFlagAttr*)
diff --git a/sc/source/core/data/makefile.mk b/sc/source/core/data/makefile.mk
index 7129198c204f..71d7ba627ced 100644
--- a/sc/source/core/data/makefile.mk
+++ b/sc/source/core/data/makefile.mk
@@ -108,6 +108,7 @@ SLOFILES = \
$(SLO)$/table4.obj \
$(SLO)$/table5.obj \
$(SLO)$/table6.obj \
+ $(SLO)$/tabprotection.obj \
$(SLO)$/userdat.obj \
$(SLO)$/validat.obj \
$(SLO)$/postit.obj
@@ -128,6 +129,7 @@ EXCEPTIONSFILES= \
$(SLO)$/global2.obj \
$(SLO)$/table1.obj \
$(SLO)$/table3.obj \
+ $(SLO)$/tabprotection.obj \
$(SLO)$/postit.obj \
$(SLO)$/documen3.obj \
$(SLO)$/documen5.obj \
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 03b9fc9d90be..fb53a4050eb8 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -114,6 +114,7 @@
#include "progress.hxx"
#include "hints.hxx" // fuer Paint-Broadcast
#include "prnsave.hxx"
+#include "tabprotection.hxx"
// STATIC DATA -----------------------------------------------------------
@@ -132,7 +133,7 @@ ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName,
bPageSizeValid( FALSE ),
nRepeatStartX( SCCOL_REPEAT_NONE ),
nRepeatStartY( SCROW_REPEAT_NONE ),
- bProtected( FALSE ),
+ pTabProtection( NULL ),
pColWidth( NULL ),
pRowHeight( NULL ),
pColFlags( NULL ),
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 5b726467c3ba..9b0540df9966 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -292,7 +292,7 @@ void ScTable::DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USH
// Zellschutz auf geschuetzter Tabelle nicht setzen
//
- if ( bProtected && (nDelFlag & IDF_ATTRIB) )
+ if ( IsProtected() && (nDelFlag & IDF_ATTRIB) )
{
ScPatternAttr aPattern(pDocument->GetPool());
aPattern.GetItemSet().Put( ScProtectionAttr( FALSE ) );
@@ -318,7 +318,7 @@ void ScTable::DeleteSelection( USHORT nDelFlag, const ScMarkData& rMark )
// Zellschutz auf geschuetzter Tabelle nicht setzen
//
- if ( bProtected && (nDelFlag & IDF_ATTRIB) )
+ if ( IsProtected() && (nDelFlag & IDF_ATTRIB) )
{
ScDocumentPool* pPool = pDocument->GetPool();
SfxItemSet aSet( *pPool, ATTR_PATTERN_START, ATTR_PATTERN_END );
@@ -361,7 +361,7 @@ void ScTable::CopyToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
// ggf. Formeln durch Werte ersetzen
- if (bProtected)
+ if ( IsProtected() )
for (i = nCol1; i <= nCol2; i++)
pTable->aCol[i].RemoveProtected(nRow1, nRow2);
}
@@ -406,7 +406,7 @@ void ScTable::CopyFromClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
// Zellschutz auf geschuetzter Tabelle nicht setzen
//
- if ( bProtected && (nInsFlag & IDF_ATTRIB) )
+ if ( IsProtected() && (nInsFlag & IDF_ATTRIB) )
{
ScPatternAttr aPattern(pDocument->GetPool());
aPattern.GetItemSet().Put( ScProtectionAttr( FALSE ) );
@@ -1457,7 +1457,7 @@ BOOL ScTable::IsBlockEditable( SCCOL nCol1, SCROW nRow1, SCCOL nCol2,
BOOL bIsEditable = TRUE;
if ( nLockCount )
bIsEditable = FALSE;
- else if ( bProtected && !pDocument->IsScenario(nTab) )
+ else if ( IsProtected() && !pDocument->IsScenario(nTab) )
{
if((bIsEditable = !HasAttrib( nCol1, nRow1, nCol2, nRow2, HASATTR_PROTECTED )) != FALSE)
{
@@ -1524,7 +1524,7 @@ BOOL ScTable::IsSelectionEditable( const ScMarkData& rMark,
BOOL bIsEditable = TRUE;
if ( nLockCount )
bIsEditable = FALSE;
- else if ( bProtected && !pDocument->IsScenario(nTab))
+ else if ( IsProtected() && !pDocument->IsScenario(nTab) )
{
if((bIsEditable = !HasAttribSelection( rMark, HASATTR_PROTECTED )) != FALSE)
{
diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx
index a6ef174e326c..021385678160 100644
--- a/sc/source/core/data/table5.cxx
+++ b/sc/source/core/data/table5.cxx
@@ -51,8 +51,11 @@
#include "stlpool.hxx"
#include "stlsheet.hxx"
#include "brdcst.hxx"
+#include "tabprotection.hxx"
#include "globstr.hrc"
+using ::com::sun::star::uno::Sequence;
+
// STATIC DATA -----------------------------------------------------------
#define GET_SCALEVALUE(set,id) ((const SfxUInt16Item&)(set.Get( id ))).GetValue()
@@ -273,6 +276,24 @@ void ScTable::SetPageSize( const Size& rSize )
bPageSizeValid = FALSE;
}
+BOOL ScTable::IsProtected() const
+{
+ return pTabProtection.get() && pTabProtection->isProtected();
+}
+
+void ScTable::SetProtection(const ScTableProtection* pProtect)
+{
+ if (pProtect)
+ pTabProtection.reset(new ScTableProtection(*pProtect));
+ else
+ pTabProtection.reset(NULL);
+}
+
+ScTableProtection* ScTable::GetProtection()
+{
+ return pTabProtection.get();
+}
+
Size ScTable::GetPageSize() const
{
if ( bPageSizeValid )
diff --git a/sc/source/core/data/tabprotection.cxx b/sc/source/core/data/tabprotection.cxx
new file mode 100644
index 000000000000..1620c5194e92
--- /dev/null
+++ b/sc/source/core/data/tabprotection.cxx
@@ -0,0 +1,465 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: tabprotection.cxx,v $
+ * $Revision: 1.1.4.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "tabprotection.hxx"
+#include "tools/debug.hxx"
+#include "svtools/PasswordHelper.hxx"
+#include "document.hxx"
+
+#define DEBUG_TAB_PROTECTION 0
+
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
+
+// ============================================================================
+
+bool ScPassHashHelper::needsPassHashRegen(const ScDocument& rDoc, ScPasswordHash eHash)
+{
+ if (rDoc.IsDocProtected())
+ {
+ const ScDocProtection* p = rDoc.GetDocProtection();
+ if (!p->isPasswordEmpty() && !p->hasPasswordHash(eHash))
+ return true;
+ }
+
+ SCTAB nTabCount = rDoc.GetTableCount();
+ for (SCTAB i = 0; i < nTabCount; ++i)
+ {
+ const ScTableProtection* p = rDoc.GetTabProtection(i);
+ if (!p || !p->isProtected())
+ // Sheet not protected. Skip it.
+ continue;
+
+ if (!p->isPasswordEmpty() && !p->hasPasswordHash(eHash))
+ return true;
+ }
+
+ return false;
+}
+
+// ============================================================================
+
+ScPassHashProtectable::~ScPassHashProtectable()
+{
+}
+
+// ============================================================================
+
+static sal_uInt16 lcl_getXLHashFromChar(const sal_Char* szPassword)
+{
+ sal_uInt16 cchPassword = static_cast< sal_uInt16 >( strlen(szPassword) );
+ sal_uInt16 wPasswordHash = 0;
+ if (!cchPassword)
+ return wPasswordHash;
+
+ const char* pch = &szPassword[cchPassword];
+ while (pch-- != szPassword)
+ {
+ wPasswordHash = ((wPasswordHash >> 14) & 0x01) |
+ ((wPasswordHash << 1) & 0x7fff);
+ wPasswordHash ^= *pch;
+ }
+
+ wPasswordHash = ((wPasswordHash >> 14) & 0x01) |
+ ((wPasswordHash << 1) & 0x7fff);
+
+ wPasswordHash ^= (0x8000 | ('N' << 8) | 'K');
+ wPasswordHash ^= cchPassword;
+
+ return wPasswordHash;
+}
+
+static Sequence<sal_Int8> lcl_getXLHash(const String& aPassText)
+{
+ const sal_Char* szBuf = OUStringToOString(OUString(aPassText), RTL_TEXTENCODING_UTF8).getStr();
+ sal_uInt16 nHash = lcl_getXLHashFromChar(szBuf);
+ Sequence<sal_Int8> aHash(2);
+ aHash[0] = (nHash >> 8) & 0xFF;
+ aHash[1] = nHash & 0xFF;
+ return aHash;
+}
+
+class ScTableProtectionImpl
+{
+public:
+ static ::com::sun::star::uno::Sequence<sal_Int8> hashPassword(const String& aPassText, ScPasswordHash eHash = PASSHASH_OOO);
+
+ explicit ScTableProtectionImpl(SCSIZE nOptSize);
+ explicit ScTableProtectionImpl(const ScTableProtectionImpl& r);
+
+ bool isProtected() const;
+ bool isProtectedWithPass() const;
+ void setProtected(bool bProtected);
+
+ bool isPasswordEmpty() const;
+ bool hasPasswordHash(ScPasswordHash eHash) const;
+ void setPassword(const String& aPassText);
+ ::com::sun::star::uno::Sequence<sal_Int8> getPasswordHash(ScPasswordHash eHash) const;
+ void setPasswordHash(const ::com::sun::star::uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash = PASSHASH_OOO);
+ bool verifyPassword(const String& aPassText) const;
+
+ bool isOptionEnabled(SCSIZE nOptId) const;
+ void setOption(SCSIZE nOptId, bool bEnabled);
+
+private:
+ String maPassText;
+ ::com::sun::star::uno::Sequence<sal_Int8> maPassHash;
+ ::std::vector<bool> maOptions;
+ bool mbEmptyPass;
+ bool mbProtected;
+ ScPasswordHash meHash;
+};
+
+Sequence<sal_Int8> ScTableProtectionImpl::hashPassword(const String& aPassText, ScPasswordHash eHash)
+{
+ Sequence<sal_Int8> aHash;
+ switch (eHash)
+ {
+ case PASSHASH_XL:
+ aHash = lcl_getXLHash(aPassText);
+ break;
+ case PASSHASH_OOO:
+ default:
+ SvPasswordHelper::GetHashPassword(aHash, aPassText);
+ break;
+ }
+ return aHash;
+}
+
+ScTableProtectionImpl::ScTableProtectionImpl(SCSIZE nOptSize) :
+ maOptions(nOptSize),
+ mbEmptyPass(true),
+ mbProtected(false),
+ meHash(PASSHASH_OOO)
+{
+}
+
+ScTableProtectionImpl::ScTableProtectionImpl(const ScTableProtectionImpl& r) :
+ maPassText(r.maPassText),
+ maPassHash(r.maPassHash),
+ maOptions(r.maOptions),
+ mbEmptyPass(r.mbEmptyPass),
+ mbProtected(r.mbProtected),
+ meHash(r.meHash)
+{
+}
+
+bool ScTableProtectionImpl::isProtected() const
+{
+ return mbProtected;
+}
+
+bool ScTableProtectionImpl::isProtectedWithPass() const
+{
+ if (!mbProtected)
+ return false;
+
+ return maPassText.Len() || maPassHash.getLength();
+}
+
+void ScTableProtectionImpl::setProtected(bool bProtected)
+{
+ mbProtected = bProtected;
+ // We need to keep the old password even when the protection is off. So,
+ // don't erase the password data here.
+}
+
+void ScTableProtectionImpl::setPassword(const String& aPassText)
+{
+ // We can't hash it here because we don't know whether this document will
+ // get saved to Excel or ODF, depending on which we will need to use a
+ // different hashing algorithm. One alternative is to hash it using all
+ // hash algorithms that we support, and store them all.
+
+ maPassText = aPassText;
+ mbEmptyPass = aPassText.Len() == 0;
+ if (mbEmptyPass)
+ {
+ maPassHash = Sequence<sal_Int8>();
+ }
+}
+
+bool ScTableProtectionImpl::isPasswordEmpty() const
+{
+ return mbEmptyPass;
+}
+
+bool ScTableProtectionImpl::hasPasswordHash(ScPasswordHash eHash) const
+{
+ if (mbEmptyPass)
+ return true;
+
+ if (maPassText.Len())
+ return true;
+
+ if (meHash == eHash)
+ return true;
+
+ return false;
+}
+
+Sequence<sal_Int8> ScTableProtectionImpl::getPasswordHash(ScPasswordHash eHash) const
+{
+ if (mbEmptyPass)
+ // Flaged as empty.
+ return Sequence<sal_Int8>();
+
+ if (maPassText.Len())
+ // Cleartext password exists. Hash it.
+ return hashPassword(maPassText, eHash);
+
+ if (meHash == eHash)
+ // Stored hash exists.
+ return maPassHash;
+
+ // Failed to find a matching hash.
+ return Sequence<sal_Int8>();
+}
+
+void ScTableProtectionImpl::setPasswordHash(const uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash)
+{
+ sal_Int32 nLen = aPassword.getLength();
+ mbEmptyPass = nLen <= 0 ? true : false;
+ meHash = eHash;
+ maPassHash = aPassword;
+
+#if DEBUG_TAB_PROTECTION
+ for (sal_Int32 i = 0; i < nLen; ++i)
+ printf("%2.2X ", static_cast<sal_uInt8>(aPassword[i]));
+ printf("\n");
+#endif
+}
+
+bool ScTableProtectionImpl::verifyPassword(const String& aPassText) const
+{
+#if DEBUG_TAB_PROTECTION
+ fprintf(stdout, "ScTableProtectionImpl::verifyPassword: input = '%s'\n",
+ OUStringToOString(rtl::OUString(aPassText), RTL_TEXTENCODING_UTF8).getStr());
+#endif
+
+ if (mbEmptyPass)
+ return aPassText.Len() == 0;
+
+ if (maPassText.Len())
+ // Clear text password exists, and this one takes precedence.
+ return aPassText.Equals(maPassText);
+
+ Sequence<sal_Int8> aHash = hashPassword(aPassText, meHash);
+
+#if DEBUG_TAB_PROTECTION
+ fprintf(stdout, "ScTableProtectionImpl::verifyPassword: hash = ");
+ for (sal_Int32 i = 0; i < aHash.getLength(); ++i)
+ printf("%2.2X ", static_cast<sal_uInt8>(aHash[i]));
+ printf("\n");
+#endif
+
+ return aHash == maPassHash;
+}
+
+bool ScTableProtectionImpl::isOptionEnabled(SCSIZE nOptId) const
+{
+ if ( maOptions.size() <= static_cast<size_t>(nOptId) )
+ {
+ DBG_ERROR("ScTableProtectionImpl::isOptionEnabled: wrong size");
+ return false;
+ }
+
+ return maOptions[nOptId];
+}
+
+void ScTableProtectionImpl::setOption(SCSIZE nOptId, bool bEnabled)
+{
+ if ( maOptions.size() <= static_cast<size_t>(nOptId) )
+ {
+ DBG_ERROR("ScTableProtectionImpl::setOption: wrong size");
+ return;
+ }
+
+ maOptions[nOptId] = bEnabled;
+}
+
+// ============================================================================
+
+ScDocProtection::ScDocProtection() :
+ mpImpl(new ScTableProtectionImpl(static_cast<SCSIZE>(ScDocProtection::NONE)))
+{
+}
+
+ScDocProtection::ScDocProtection(const ScDocProtection& r) :
+ ScPassHashProtectable(),
+ mpImpl(new ScTableProtectionImpl(*r.mpImpl))
+{
+}
+
+ScDocProtection::~ScDocProtection()
+{
+}
+
+bool ScDocProtection::isProtected() const
+{
+ return mpImpl->isProtected();
+}
+
+bool ScDocProtection::isProtectedWithPass() const
+{
+ return mpImpl->isProtectedWithPass();
+}
+
+void ScDocProtection::setProtected(bool bProtected)
+{
+ mpImpl->setProtected(bProtected);
+
+ // Currently Calc doesn't support document protection options. So, let's
+ // assume that when the document is protected, its structure is protected.
+ // We need to do this for Excel export.
+ mpImpl->setOption(ScDocProtection::STRUCTURE, bProtected);
+}
+
+bool ScDocProtection::isPasswordEmpty() const
+{
+ return mpImpl->isPasswordEmpty();
+}
+
+bool ScDocProtection::hasPasswordHash(ScPasswordHash eHash) const
+{
+ return mpImpl->hasPasswordHash(eHash);
+}
+
+void ScDocProtection::setPassword(const String& aPassText)
+{
+ mpImpl->setPassword(aPassText);
+}
+
+uno::Sequence<sal_Int8> ScDocProtection::getPasswordHash(ScPasswordHash eHash) const
+{
+ return mpImpl->getPasswordHash(eHash);
+}
+
+void ScDocProtection::setPasswordHash(const uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash)
+{
+ mpImpl->setPasswordHash(aPassword, eHash);
+}
+
+bool ScDocProtection::verifyPassword(const String& aPassText) const
+{
+ return mpImpl->verifyPassword(aPassText);
+}
+
+bool ScDocProtection::isOptionEnabled(Option eOption) const
+{
+ return mpImpl->isOptionEnabled(eOption);
+}
+
+void ScDocProtection::setOption(Option eOption, bool bEnabled)
+{
+ mpImpl->setOption(eOption, bEnabled);
+}
+
+// ============================================================================
+
+ScTableProtection::ScTableProtection() :
+ mpImpl(new ScTableProtectionImpl(static_cast<SCSIZE>(ScTableProtection::NONE)))
+{
+ // Set default values for the options.
+ mpImpl->setOption(SELECT_LOCKED_CELLS, true);
+ mpImpl->setOption(SELECT_UNLOCKED_CELLS, true);
+}
+
+ScTableProtection::ScTableProtection(const ScTableProtection& r) :
+ ScPassHashProtectable(),
+ mpImpl(new ScTableProtectionImpl(*r.mpImpl))
+{
+}
+
+ScTableProtection::~ScTableProtection()
+{
+}
+
+bool ScTableProtection::isProtected() const
+{
+ return mpImpl->isProtected();
+}
+
+bool ScTableProtection::isProtectedWithPass() const
+{
+ return mpImpl->isProtectedWithPass();
+}
+
+void ScTableProtection::setProtected(bool bProtected)
+{
+ mpImpl->setProtected(bProtected);
+}
+
+bool ScTableProtection::isPasswordEmpty() const
+{
+ return mpImpl->isPasswordEmpty();
+}
+
+bool ScTableProtection::hasPasswordHash(ScPasswordHash eHash) const
+{
+ return mpImpl->hasPasswordHash(eHash);
+}
+
+void ScTableProtection::setPassword(const String& aPassText)
+{
+ mpImpl->setPassword(aPassText);
+}
+
+Sequence<sal_Int8> ScTableProtection::getPasswordHash(ScPasswordHash eHash) const
+{
+ return mpImpl->getPasswordHash(eHash);
+}
+
+void ScTableProtection::setPasswordHash(const uno::Sequence<sal_Int8>& aPassword, ScPasswordHash eHash)
+{
+ mpImpl->setPasswordHash(aPassword, eHash);
+}
+
+bool ScTableProtection::verifyPassword(const String& aPassText) const
+{
+ return mpImpl->verifyPassword(aPassText);
+}
+
+bool ScTableProtection::isOptionEnabled(Option eOption) const
+{
+ return mpImpl->isOptionEnabled(eOption);
+}
+
+void ScTableProtection::setOption(Option eOption, bool bEnabled)
+{
+ mpImpl->setOption(eOption, bEnabled);
+}
+
diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx
index 811097183b1e..60563366281c 100644
--- a/sc/source/filter/excel/excdoc.cxx
+++ b/sc/source/filter/excel/excdoc.cxx
@@ -68,11 +68,11 @@
#include "convuno.hxx"
#include "patattr.hxx"
#include "docoptio.hxx"
+#include "tabprotection.hxx"
#include "excdoc.hxx"
#include "namebuff.hxx"
-#include "xcl97dum.hxx"
#include "xcl97rec.hxx"
#include "xcl97esc.hxx"
#include "xetable.hxx"
@@ -118,7 +118,7 @@ static void lcl_AddCalcPr( XclExpRecordList<>& aRecList, ExcTable& self )
aRecList.AppendNewRecord( new XclRefmode( rDoc ) );
aRecList.AppendNewRecord( new XclIteration( rDoc ) );
aRecList.AppendNewRecord( new XclDelta( rDoc ) );
- aRecList.AppendNewRecord( new ExcDummy8_02 );
+ aRecList.AppendNewRecord( new XclExpBoolRecord(0x005F, true) ); // SAVERECALC
aRecList.AppendNewRecord( new XclExpXmlEndSingleElementRecord() ); // XML_calcPr
}
@@ -209,7 +209,16 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList )
Add( new ExcDummy_00 );
else
{
- Add( new ExcDummy8_00a );
+ if ( IsDocumentEncrypted() )
+ Add( new XclExpFilePass(GetRoot()) );
+
+ Add( new XclExpInterfaceHdr );
+ Add( new XclExpMMS );
+ Add( new XclExpInterfaceEnd );
+ Add( new XclExpWriteAccess );
+ Add( new XclExpCodePage );
+ Add( new XclExpDSF );
+ Add( new XclExpExcel9File );
rR.pTabId = new XclExpChTrTabId( Max( nExcTabCount, nCodenames ) );
Add( rR.pTabId );
if( HasVbaStorage() )
@@ -219,7 +228,8 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList )
if( rCodeName.Len() )
Add( new XclCodename( rCodeName ) );
}
- Add( new ExcDummy8_00b );
+
+ Add( new XclExpFnGroupCount );
}
// erst Namen- und Tabellen-Eintraege aufbauen
@@ -239,12 +249,22 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList )
aRecList.AppendRecord( CreateRecord( EXC_ID_NAME ) );
}
- aRecList.AppendNewRecord( new XclExpWindowProtection( GetExtDocOptions().GetDocSettings().mbWinProtected ) );
- aRecList.AppendNewRecord( new XclExpDocProtection( rDoc.IsDocProtected() ) );
- aRecList.AppendNewRecord( new XclExpBoolRecord( EXC_ID_PASSWORD, false ) );
+ // document protection options
+ const ScDocProtection* pProtect = GetDoc().GetDocProtection();
+ if (pProtect && pProtect->isProtected())
+ {
+ Add( new XclExpWindowProtection(pProtect->isOptionEnabled(ScDocProtection::WINDOWS)) );
+ Add( new XclExpProtection(pProtect->isOptionEnabled(ScDocProtection::STRUCTURE)) );
+#if ENABLE_SHEET_PROTECTION
+ Add( new XclExpPassHash(pProtect->getPasswordHash(PASSHASH_XL)) );
+#endif
+ }
if( GetBiff() == EXC_BIFF8 )
- Add( new ExcDummy8_040 );
+ {
+ Add( new XclExpProt4Rev );
+ Add( new XclExpProt4RevPass );
+ }
// document protection options
if( GetOutput() == EXC_OUTPUT_BINARY )
@@ -255,6 +275,12 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList )
Add( new XclExpXmlStartSingleElementRecord( XML_workbookPr ) );
+ if ( GetBiff() == EXC_BIFF8 )
+ {
+ Add( new XclExpBoolRecord(0x0040, false) ); // BACKUP
+ Add( new XclExpBoolRecord(0x008D, false) ); // HIDEOBJ
+ }
+
if( GetBiff() <= EXC_BIFF5 )
{
Add( new ExcDummy_040 );
@@ -263,9 +289,11 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList )
}
else
{
+ // BIFF8
Add( new Exc1904( rDoc ) );
Add( new XclExpBoolRecord( 0x000E, !rDoc.GetDocOptions().IsCalcAsShown() ) );
- Add( new ExcDummy8_041 );
+ Add( new XclExpBoolRecord(0x01B7, false) ); // REFRESHALL
+ Add( new XclExpBoolRecord(0x00DA, false) ); // BOOKBOOL
// OOXTODO: The following /workbook/workbookPr attributes are mapped
// to various BIFF records that are not currently supported:
//
@@ -361,10 +389,14 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList )
if( GetOutput() != EXC_OUTPUT_BINARY )
lcl_AddCalcPr( aRecList, *this );
+ Add( new XclExpRecalcId );
+
// MSODRAWINGGROUP per-document data
Add( new XclMsodrawinggroup( rR, ESCHER_DggContainer ) );
// Shared string table: SST, EXTSST
aRecList.AppendRecord( CreateRecord( EXC_ID_SST ) );
+
+ Add( new XclExpBookExt );
}
Add( new ExcEof );
@@ -425,8 +457,16 @@ void ExcTable::FillAsTable( size_t nCodeNameIdx )
// page settings (SETUP and various other records)
aRecList.AppendRecord( xPageSett );
- if( rDoc.IsTabProtected( mnScTab ) )
- Add( new XclProtection() );
+ const ScTableProtection* pTabProtect = rDoc.GetTabProtection(mnScTab);
+ if (pTabProtect && pTabProtect->isProtected())
+ {
+ Add( new XclExpProtection(true) );
+ Add( new XclExpBoolRecord(0x00DD, pTabProtect->isOptionEnabled(ScTableProtection::SCENARIOS)) );
+ Add( new XclExpBoolRecord(0x0063, pTabProtect->isOptionEnabled(ScTableProtection::OBJECTS)) );
+#if ENABLE_SHEET_PROTECTION
+ Add( new XclExpPassHash(pTabProtect->getPasswordHash(PASSHASH_XL)) );
+#endif
+ }
// local link table: EXTERNCOUNT, EXTERNSHEET
if( eBiff <= EXC_BIFF5 )
@@ -467,6 +507,9 @@ void ExcTable::FillAsTable( size_t nCodeNameIdx )
if( eBiff == EXC_BIFF8 )
{
+ // sheet protection options
+ Add( new XclExpSheetProtectOptions( GetRoot(), mnScTab ) );
+
// web queries
Add( new XclExpWebQueryBuffer( GetRoot() ) );
diff --git a/sc/source/filter/excel/excimp8.cxx b/sc/source/filter/excel/excimp8.cxx
index b62470ceee3b..c4063c74add6 100644
--- a/sc/source/filter/excel/excimp8.cxx
+++ b/sc/source/filter/excel/excimp8.cxx
@@ -160,12 +160,6 @@ void ImportExcel8::Iteration( void )
}
-void ImportExcel8:: WinProtection( void )
-{
- if( aIn.ReaduInt16() != 0 )
- GetExtDocOptions().GetDocSettings().mbWinProtected = true;
-}
-
void ImportExcel8::Boundsheet( void )
{
UINT8 nLen;
@@ -249,6 +243,11 @@ void ImportExcel8::Codename( BOOL bWorkbookGlobals )
}
}
+void ImportExcel8::SheetProtection( void )
+{
+ GetSheetProtectBuffer().ReadOptions( aIn, GetCurrScTab() );
+}
+
bool lcl_hasVBAEnabled()
{
uno::Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY);
@@ -295,6 +294,8 @@ void ImportExcel8::PostDocLoad( void )
pExcRoot->pAutoFilterBuffer->Apply();
GetWebQueryBuffer().Apply(); //! test if extant
+ GetSheetProtectBuffer().Apply();
+ GetDocProtectBuffer().Apply();
ImportExcel::PostDocLoad();
diff --git a/sc/source/filter/excel/excrecds.cxx b/sc/source/filter/excel/excrecds.cxx
index e97a0d9fdd6f..89a814c8f3c3 100644
--- a/sc/source/filter/excel/excrecds.cxx
+++ b/sc/source/filter/excel/excrecds.cxx
@@ -100,6 +100,7 @@
#include <oox/core/tokens.hxx>
+using ::com::sun::star::uno::Sequence;
using ::rtl::OString;
@@ -432,7 +433,9 @@ ExcBundlesheetBase::ExcBundlesheetBase() :
void ExcBundlesheetBase::UpdateStreamPos( XclExpStream& rStrm )
{
rStrm.SetSvStreamPos( nOwnPos );
+ rStrm.DisableEncryption();
rStrm << static_cast<sal_uInt32>(nStrPos);
+ rStrm.EnableEncryption();
}
@@ -532,7 +535,7 @@ void XclExpWsbool::SaveXml( XclExpXmlStream& rStrm )
// XclExpWindowProtection ===============================================================
XclExpWindowProtection::XclExpWindowProtection(bool bValue) :
- XclExpBoolRecord(EXC_ID_WINDOWPROTECT,bValue)
+ XclExpBoolRecord(EXC_ID_WINDOWPROTECT, bValue)
{
}
@@ -545,13 +548,35 @@ void XclExpWindowProtection::SaveXml( XclExpXmlStream& rStrm )
// XclExpDocProtection ===============================================================
-XclExpDocProtection::XclExpDocProtection(bool bValue) :
- XclExpBoolRecord(EXC_ID_PROTECT,bValue)
+XclExpProtection::XclExpProtection(bool bValue) :
+ XclExpBoolRecord(EXC_ID_PROTECT, bValue)
{
}
// ============================================================================
+XclExpPassHash::XclExpPassHash(const Sequence<sal_Int8>& aHash) :
+ XclExpRecord(EXC_ID_PASSWORD, 2),
+ mnHash(0x0000)
+{
+ if (aHash.getLength() >= 2)
+ {
+ mnHash = ((aHash[0] << 8) & 0xFFFF);
+ mnHash |= (aHash[1] & 0xFF);
+ }
+}
+
+XclExpPassHash::~XclExpPassHash()
+{
+}
+
+void XclExpPassHash::WriteBody(XclExpStream& rStrm)
+{
+ rStrm << mnHash;
+}
+
+// ============================================================================
+
XclExpFiltermode::XclExpFiltermode() :
XclExpEmptyRecord( EXC_ID_FILTERMODE )
{
diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx
index a2c5e786abbe..cfbef0a15a6e 100644
--- a/sc/source/filter/excel/impop.cxx
+++ b/sc/source/filter/excel/impop.cxx
@@ -84,6 +84,7 @@
#include "xiview.hxx"
#include "xilink.hxx"
#include "xiescher.hxx"
+#include "xicontent.hxx"
#include "excimp8.hxx"
#include "excform.hxx"
@@ -418,14 +419,12 @@ void ImportExcel::Eof( void )
}
-BOOL ImportExcel::Password( void )
+void ImportExcel::SheetPassword( void )
{
- // POST: return = TRUE, wenn Password <> 0
- UINT16 nPasswd;
-
- aIn >> nPasswd;
+ if (GetRoot().GetBiff() != EXC_BIFF8)
+ return;
- return nPasswd != 0x0000;
+ GetRoot().GetSheetProtectBuffer().ReadPasswordHash( aIn, GetCurrScTab() );
}
@@ -439,6 +438,15 @@ void ImportExcel::Externsheet( void )
}
+void ImportExcel:: WinProtection( void )
+{
+ if (GetRoot().GetBiff() != EXC_BIFF8)
+ return;
+
+ GetRoot().GetDocProtectBuffer().ReadWinProtect( aIn );
+}
+
+
void ImportExcel::Columndefault( void )
{// Default Cell Attributes
UINT16 nColMic, nColMac;
@@ -570,27 +578,33 @@ void ImportExcel::Defrowheight2( void )
}
-void ImportExcel::Protect( void )
+void ImportExcel::SheetProtect( void )
{
- if( aIn.ReaduInt16() )
- {
- uno::Sequence<sal_Int8> aEmptyPass;
- GetDoc().SetTabProtection( GetCurrScTab(), TRUE, aEmptyPass );
- }
+ if (GetRoot().GetBiff() != EXC_BIFF8)
+ return;
+
+ GetRoot().GetSheetProtectBuffer().ReadProtect( aIn, GetCurrScTab() );
}
void ImportExcel::DocProtect( void )
{
- if( aIn.ReaduInt16() )
- {
- uno::Sequence<sal_Int8> aEmptyPass;
- GetDoc().SetDocProtection( TRUE, aEmptyPass );
- }
+ if (GetRoot().GetBiff() != EXC_BIFF8)
+ return;
+
+ GetRoot().GetDocProtectBuffer().ReadDocProtect( aIn );
}
+void ImportExcel::DocPasssword( void )
+{
+ if (GetRoot().GetBiff() != EXC_BIFF8)
+ return;
+
+ GetRoot().GetDocProtectBuffer().ReadPasswordHash( aIn );
+}
void ImportExcel::Codepage( void )
{
+ maStrm.EnableDecryption();
SetCodePage( maStrm.ReaduInt16() );
}
diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx
index a06cf041e7cf..e7473ba23d02 100644
--- a/sc/source/filter/excel/read.cxx
+++ b/sc/source/filter/excel/read.cxx
@@ -354,7 +354,7 @@ FltError ImportExcel::Read( void )
Eof();
eAkt = Z_Ende;
break;
- case 0x12: Protect(); break; // SHEET PROTECTION
+ case 0x12: SheetProtect(); break; // SHEET PROTECTION
case 0x14:
case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break;
case 0x17: Externsheet(); break; // EXTERNSHEET [ 2345]
@@ -469,7 +469,7 @@ FltError ImportExcel::Read( void )
Eof();
eAkt = Z_Biff4E;
break;
- case 0x12: Protect(); break; // SHEET PROTECTION
+ case 0x12: SheetProtect(); break; // SHEET PROTECTION
case 0x14:
case 0x15: rPageSett.ReadHeaderFooter( maStrm ); break;
case 0x1A:
@@ -596,7 +596,7 @@ FltError ImportExcel::Read( void )
eAkt = Z_Biff5T;
aIn.SeekGlobalPosition(); // und zurueck an alte Position
break;
- case 0x12: Protect(); break; // SHEET PROTECTION
+ case 0x12: SheetProtect(); break; // SHEET PROTECTION
case 0x1A:
case 0x1B: rPageSett.ReadPageBreaks( maStrm ); break;
case 0x1D: rTabViewSett.ReadSelection( maStrm ); break;
@@ -895,6 +895,7 @@ FltError ImportExcel8::Read( void )
}
break;
case 0x12: DocProtect(); break; // PROTECT [ 5678]
+ case 0x13: DocPasssword(); break;
case 0x19: WinProtection(); break;
case 0x2F: // FILEPASS [ 2345 ]
eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
@@ -1039,7 +1040,8 @@ FltError ImportExcel8::Read( void )
eAkt = EXC_STATE_SHEET;
aIn.SeekGlobalPosition(); // und zurueck an alte Position
break;
- case 0x12: Protect(); break;
+ case 0x12: SheetProtect(); break;
+ case 0x13: SheetPassword(); break;
case 0x42: Codepage(); break; // CODEPAGE [ 2345 ]
case 0x55: DefColWidth(); break;
case 0x7D: Colinfo(); break; // COLINFO [ 345 ]
@@ -1055,6 +1057,7 @@ FltError ImportExcel8::Read( void )
case 0x0221: Array34(); break; // ARRAY [ 34 ]
case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[ 345 ]
case 0x04BC: Shrfmla(); break; // SHRFMLA [ 5 ]
+ case 0x0867: SheetProtection(); break; // SHEETPROTECTION
}
}
break;
diff --git a/sc/source/filter/excel/xeroot.cxx b/sc/source/filter/excel/xeroot.cxx
index 100f1bc54af1..7c4974db3029 100644
--- a/sc/source/filter/excel/xeroot.cxx
+++ b/sc/source/filter/excel/xeroot.cxx
@@ -31,7 +31,11 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
#include <sfx2/docfile.hxx>
+#include <sfx2/sfxsids.hrc>
#include <svtools/saveopt.hxx>
+#include <svtools/itemset.hxx>
+#include <svtools/stritem.hxx>
+#include <svtools/eitem.hxx>
#include "xecontent.hxx"
#include "xltracer.hxx"
#include "xehelper.hxx"
@@ -42,8 +46,10 @@
#include "xepivot.hxx"
#include "xeroot.hxx"
-// for filter manager
-#include "excrecds.hxx"
+#include "excrecds.hxx" // for filter manager
+#include "tabprotection.hxx"
+#include "document.hxx"
+#include "scextopt.hxx"
// Global data ================================================================
@@ -221,6 +227,40 @@ XclExpRecordRef XclExpRoot::CreateRecord( sal_uInt16 nRecId ) const
return xRec;
}
+bool XclExpRoot::IsDocumentEncrypted() const
+{
+ // We need to encrypt the content when the document structure is protected.
+ const ScDocProtection* pDocProt = GetDoc().GetDocProtection();
+ if (pDocProt && pDocProt->isProtected() && pDocProt->isOptionEnabled(ScDocProtection::STRUCTURE))
+ return true;
+
+ if (GetPassword().Len() > 0)
+ // Password is entered directly into the save dialog.
+ return true;
+
+ return false;
+}
+
+const String XclExpRoot::GetPassword() const
+{
+ SfxItemSet* pSet = GetMedium().GetItemSet();
+ if (!pSet)
+ return String();
+
+ const SfxPoolItem* pItem = NULL;
+ if (SFX_ITEM_SET == pSet->GetItemState(SID_PASSWORD, sal_True, &pItem))
+ {
+ const SfxStringItem* pStrItem = dynamic_cast<const SfxStringItem*>(pItem);
+ if (pStrItem)
+ {
+ // Password from the save dialog.
+ return pStrItem->GetValue();
+ }
+ }
+
+ return String();
+}
+
XclExpRootData::XclExpLinkMgrRef XclExpRoot::GetLocalLinkMgrRef() const
{
return IsInGlobals() ? mrExpData.mxGlobLinkMgr : mrExpData.mxLocLinkMgr;
diff --git a/sc/source/filter/excel/xestream.cxx b/sc/source/filter/excel/xestream.cxx
index 9cb054d2ada2..82221b67668c 100644
--- a/sc/source/filter/excel/xestream.cxx
+++ b/sc/source/filter/excel/xestream.cxx
@@ -51,6 +51,8 @@
#include <oox/core/tokens.hxx>
#include <formula/grammar.hxx>
+#define DEBUG_XL_ENCRYPTION 0
+
using ::com::sun::star::beans::PropertyValue;
using ::com::sun::star::io::XOutputStream;
using ::com::sun::star::io::XStream;
@@ -63,7 +65,10 @@ using ::com::sun::star::uno::UNO_QUERY;
using ::rtl::OString;
using ::rtl::OUString;
using ::utl::OStreamWrapper;
+using ::std::vector;
+
using namespace formula;
+
// ============================================================================
XclExpStream::XclExpStream( SvStream& rOutStrm, const XclExpRoot& rRoot, sal_uInt16 nMaxRecSize ) :
@@ -92,16 +97,19 @@ XclExpStream::~XclExpStream()
void XclExpStream::StartRecord( sal_uInt16 nRecId, sal_Size nRecSize )
{
DBG_ASSERT( !mbInRec, "XclExpStream::StartRecord - another record still open" );
+ DisableEncryption();
mnMaxContSize = mnCurrMaxSize = mnMaxRecSize;
mnPredictSize = nRecSize;
mbInRec = true;
InitRecord( nRecId );
SetSliceSize( 0 );
+ EnableEncryption();
}
void XclExpStream::EndRecord()
{
DBG_ASSERT( mbInRec, "XclExpStream::EndRecord - no record open" );
+ DisableEncryption();
UpdateRecSize();
mrStrm.Seek( STREAM_SEEK_TO_END );
mbInRec = false;
@@ -113,6 +121,86 @@ void XclExpStream::SetSliceSize( sal_uInt16 nSize )
mnSliceSize = 0;
}
+XclExpStream& XclExpStream::operator<<( sal_Int8 nValue )
+{
+ PrepareWrite( 1 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, nValue);
+ else
+ mrStrm << nValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( sal_uInt8 nValue )
+{
+ PrepareWrite( 1 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, nValue);
+ else
+ mrStrm << nValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( sal_Int16 nValue )
+{
+ PrepareWrite( 2 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, nValue);
+ else
+ mrStrm << nValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( sal_uInt16 nValue )
+{
+ PrepareWrite( 2 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, nValue);
+ else
+ mrStrm << nValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( sal_Int32 nValue )
+{
+ PrepareWrite( 4 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, nValue);
+ else
+ mrStrm << nValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( sal_uInt32 nValue )
+{
+ PrepareWrite( 4 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, nValue);
+ else
+ mrStrm << nValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( float fValue )
+{
+ PrepareWrite( 4 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, fValue);
+ else
+ mrStrm << fValue;
+ return *this;
+}
+
+XclExpStream& XclExpStream::operator<<( double fValue )
+{
+ PrepareWrite( 8 );
+ if (mbUseEncrypter && HasValidEncrypter())
+ mxEncrypter->Encrypt(mrStrm, fValue);
+ else
+ mrStrm << fValue;
+ return *this;
+}
+
sal_Size XclExpStream::Write( const void* pData, sal_Size nBytes )
{
sal_Size nRet = 0;
@@ -127,9 +215,21 @@ sal_Size XclExpStream::Write( const void* pData, sal_Size nBytes )
while( bValid && (nBytesLeft > 0) )
{
sal_Size nWriteLen = ::std::min< sal_Size >( PrepareWrite(), nBytesLeft );
- sal_Size nWriteRet = mrStrm.Write( pBuffer, nWriteLen );
+ sal_Size nWriteRet = nWriteLen;
+ if (mbUseEncrypter && HasValidEncrypter())
+ {
+ DBG_ASSERT(nWriteLen > 0, "XclExpStream::Write: write length is 0!");
+ vector<sal_uInt8> aBytes(nWriteLen);
+ memcpy(&aBytes[0], pBuffer, nWriteLen);
+ mxEncrypter->EncryptBytes(mrStrm, aBytes);
+ // TODO: How do I check if all the bytes have been successfully written ?
+ }
+ else
+ {
+ nWriteRet = mrStrm.Write( pBuffer, nWriteLen );
bValid = (nWriteLen == nWriteRet);
DBG_ASSERT( bValid, "XclExpStream::Write - stream write error" );
+ }
pBuffer += nWriteRet;
nRet += nWriteRet;
nBytesLeft -= nWriteRet;
@@ -265,6 +365,26 @@ void XclExpStream::WriteCharBuffer( const ScfUInt8Vec& rBuffer )
Write( &rBuffer[ 0 ], rBuffer.size() );
}
+void XclExpStream::SetEncrypter( XclExpEncrypterRef xEncrypter )
+{
+ mxEncrypter = xEncrypter;
+}
+
+bool XclExpStream::HasValidEncrypter() const
+{
+ return mxEncrypter.is() && mxEncrypter->IsValid();
+}
+
+void XclExpStream::EnableEncryption( bool bEnable )
+{
+ mbUseEncrypter = bEnable && HasValidEncrypter();
+}
+
+void XclExpStream::DisableEncryption()
+{
+ EnableEncryption(false);
+}
+
sal_Size XclExpStream::SetSvStreamPos( sal_Size nPos )
{
DBG_ASSERT( !mbInRec, "XclExpStream::SetSvStreamPos - not allowed inside of a record" );
@@ -356,6 +476,193 @@ void XclExpStream::WriteRawZeroBytes( sal_Size nBytes )
// ============================================================================
+XclExpBiff8Encrypter::XclExpBiff8Encrypter( const XclExpRoot& rRoot, const sal_uInt8 nDocId[16],
+ const sal_uInt8 nSalt[16] ) :
+ mrRoot(rRoot),
+ mnOldPos(STREAM_SEEK_TO_END),
+ mbValid(false)
+{
+ String aPass = rRoot.GetPassword();
+ if (aPass.Len() == 0)
+ // Empty password. Get the default biff8 password.
+ aPass = XclCryptoHelper::GetBiff8WbProtPassword();
+ Init(aPass, nDocId, nSalt);
+}
+
+XclExpBiff8Encrypter::~XclExpBiff8Encrypter()
+{
+}
+
+bool XclExpBiff8Encrypter::IsValid() const
+{
+ return mbValid;
+}
+
+void XclExpBiff8Encrypter::GetSaltDigest( sal_uInt8 nSaltDigest[16] ) const
+{
+ memcpy(nSaltDigest, mnSaltDigest, 16);
+}
+
+void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_uInt8 nData )
+{
+ vector<sal_uInt8> aByte(1);
+ aByte[0] = nData;
+ EncryptBytes(rStrm, aByte);
+}
+
+void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_uInt16 nData )
+{
+ ::std::vector<sal_uInt8> pnBytes(2);
+ pnBytes[0] = nData & 0xFF;
+ pnBytes[1] = (nData >> 8) & 0xFF;
+ EncryptBytes(rStrm, pnBytes);
+}
+
+void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_uInt32 nData )
+{
+ ::std::vector<sal_uInt8> pnBytes(4);
+ pnBytes[0] = nData & 0xFF;
+ pnBytes[1] = (nData >> 8) & 0xFF;
+ pnBytes[2] = (nData >> 16) & 0xFF;
+ pnBytes[3] = (nData >> 24) & 0xFF;
+ EncryptBytes(rStrm, pnBytes);
+}
+
+void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, float fValue )
+{
+ ::std::vector<sal_uInt8> pnBytes(4);
+ memcpy(&pnBytes[0], &fValue, 4);
+ EncryptBytes(rStrm, pnBytes);
+}
+
+void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, double fValue )
+{
+ ::std::vector<sal_uInt8> pnBytes(8);
+ memcpy(&pnBytes[0], &fValue, 8);
+ EncryptBytes(rStrm, pnBytes);
+}
+
+void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_Int8 nData )
+{
+ Encrypt(rStrm, static_cast<sal_uInt8>(nData));
+}
+
+void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_Int16 nData )
+{
+ Encrypt(rStrm, static_cast<sal_uInt16>(nData));
+}
+
+void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_Int32 nData )
+{
+ Encrypt(rStrm, static_cast<sal_uInt32>(nData));
+}
+
+void XclExpBiff8Encrypter::Init( const String& aPass, const sal_uInt8 nDocId[16],
+ const sal_uInt8 nSalt[16] )
+{
+ memset(mnSaltDigest, 0, sizeof(mnSaltDigest));
+
+ xub_StrLen nLen = aPass.Len();
+ bool bValid = (0 < nLen) && (nLen < 16);
+ if ( bValid )
+ {
+ // transform String to sal_uInt16 array
+ memset(mnPassw, 0, sizeof(mnPassw));
+ for (xub_StrLen nChar = 0; nChar < nLen; ++nChar)
+ mnPassw[nChar] = static_cast<sal_uInt16>(aPass.GetChar(nChar));
+
+ // copy document ID
+ memcpy(mnDocId, nDocId, sizeof(mnDocId));
+
+ // init codec
+ maCodec.InitKey(mnPassw, mnDocId);
+
+ // generate salt hash.
+ ::svx::MSCodec_Std97 aCodec;
+ aCodec.InitKey(mnPassw, mnDocId);
+ aCodec.CreateSaltDigest(nSalt, mnSaltDigest);
+
+ // verify to make sure it's in good shape.
+ bValid = maCodec.VerifyKey(nSalt, mnSaltDigest);
+ }
+
+ mbValid = bValid;
+}
+
+sal_uInt32 XclExpBiff8Encrypter::GetBlockPos( sal_Size nStrmPos ) const
+{
+ return static_cast<sal_uInt32>(nStrmPos / EXC_ENCR_BLOCKSIZE);
+}
+
+sal_uInt16 XclExpBiff8Encrypter::GetOffsetInBlock( sal_Size nStrmPos ) const
+{
+ return static_cast<sal_uInt16>(nStrmPos % EXC_ENCR_BLOCKSIZE);
+}
+
+void XclExpBiff8Encrypter::EncryptBytes( SvStream& rStrm, vector<sal_uInt8>& aBytes )
+{
+ sal_Size nStrmPos = rStrm.Tell();
+ sal_uInt16 nBlockOffset = GetOffsetInBlock(nStrmPos);
+ sal_uInt32 nBlockPos = GetBlockPos(nStrmPos);
+
+#if DEBUG_XL_ENCRYPTION
+ fprintf(stdout, "XclExpBiff8Encrypter::EncryptBytes: stream pos = %ld offset in block = %d block pos = %ld\n",
+ nStrmPos, nBlockOffset, nBlockPos);
+#endif
+
+ sal_uInt16 nSize = static_cast< sal_uInt16 >( aBytes.size() );
+ if (nSize == 0)
+ return;
+
+#if DEBUG_XL_ENCRYPTION
+ fprintf(stdout, "RAW: ");
+ for (sal_uInt16 i = 0; i < nSize; ++i)
+ fprintf(stdout, "%2.2X ", aBytes[i]);
+ fprintf(stdout, "\n");
+#endif
+
+ if (mnOldPos != nStrmPos)
+ {
+ sal_uInt16 nOldOffset = GetOffsetInBlock(mnOldPos);
+ sal_uInt32 nOldBlockPos = GetBlockPos(mnOldPos);
+
+ if ( (nBlockPos != nOldBlockPos) || (nBlockOffset < nOldOffset) )
+ {
+ maCodec.InitCipher(nBlockPos);
+ nOldOffset = 0;
+ }
+
+ if (nBlockOffset > nOldOffset)
+ maCodec.Skip(nBlockOffset - nOldOffset);
+ }
+
+ sal_uInt16 nBytesLeft = nSize;
+ sal_uInt16 nPos = 0;
+ while (nBytesLeft > 0)
+ {
+ sal_uInt16 nBlockLeft = EXC_ENCR_BLOCKSIZE - nBlockOffset;
+ sal_uInt16 nEncBytes = ::std::min(nBlockLeft, nBytesLeft);
+
+ bool bRet = maCodec.Encode(&aBytes[nPos], nEncBytes, &aBytes[nPos], nEncBytes);
+ DBG_ASSERT(bRet, "XclExpBiff8Encrypter::EncryptBytes: encryption failed!!");
+ bRet = bRet; // to remove a silly compiler warning.
+
+ sal_Size nRet = rStrm.Write(&aBytes[nPos], nEncBytes);
+ DBG_ASSERT(nRet == nEncBytes, "XclExpBiff8Encrypter::EncryptBytes: fail to write to stream!!");
+ nRet = nRet; // to remove a silly compiler warning.
+
+ nStrmPos = rStrm.Tell();
+ nBlockOffset = GetOffsetInBlock(nStrmPos);
+ nBlockPos = GetBlockPos(nStrmPos);
+ if (nBlockOffset == 0)
+ maCodec.InitCipher(nBlockPos);
+
+ nBytesLeft -= nEncBytes;
+ nPos += nEncBytes;
+ }
+ mnOldPos = nStrmPos;
+}
+
rtl::OUString XclXmlUtils::GetStreamName( const char* sStreamDir, const char* sStream, sal_Int32 nId )
{
rtl::OUStringBuffer sBuf;
diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx
index d4c5ba5a1bcf..24c1999b581b 100644
--- a/sc/source/filter/excel/xicontent.cxx
+++ b/sc/source/filter/excel/xicontent.cxx
@@ -41,6 +41,7 @@
#include "scitems.hxx"
#include <svx/eeitem.hxx>
#include <svtools/intitem.hxx>
+#include <svtools/stritem.hxx>
#include <svx/flditem.hxx>
#include <svx/fhgtitem.hxx>
#include <svx/wghtitem.hxx>
@@ -67,6 +68,12 @@
#include "xiname.hxx"
#include "excform.hxx"
+#include "tabprotection.hxx"
+
+#include <memory>
+
+using ::com::sun::star::uno::Sequence;
+using ::std::auto_ptr;
// Shared string table ========================================================
@@ -1089,12 +1096,191 @@ ErrCode XclImpDecryptHelper::ReadFilepass( XclImpStream& rStrm )
case EXC_BIFF8: xDecr = lclReadFilepass8( rStrm ); break;
default: DBG_ERROR_BIFF();
};
+
+ if (!xDecr.is())
+ return EXC_ENCR_ERROR_UNSUPP_CRYPT;
+
// set decrypter at import stream
rStrm.SetDecrypter( xDecr );
- // remember encryption for export
- rStrm.GetRoot().GetExtDocOptions().GetDocSettings().mbEncrypted = true;
- return xDecr.is() ? xDecr->GetError() : EXC_ENCR_ERROR_UNSUPP_CRYPT;
+ // Store the document password for export.
+ SfxItemSet* pSet = rStrm.GetRoot().GetDocShell()->GetMedium()->GetItemSet();
+ if (pSet)
+ {
+ String aPass = xDecr->GetPassword();
+ pSet->Put( SfxStringItem(SID_PASSWORD, aPass) );
+ }
+
+ return xDecr->GetError();
+}
+
+// Document protection ========================================================
+
+XclImpDocProtectBuffer::XclImpDocProtectBuffer( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot ),
+ mnPassHash(0x0000),
+ mbDocProtect(false),
+ mbWinProtect(false)
+{
+}
+
+void XclImpDocProtectBuffer::ReadDocProtect( XclImpStream& rStrm )
+{
+ mbDocProtect = rStrm.ReaduInt16() ? true : false;
+}
+
+void XclImpDocProtectBuffer::ReadWinProtect( XclImpStream& rStrm )
+{
+ mbWinProtect = rStrm.ReaduInt16() ? true : false;
+}
+
+void XclImpDocProtectBuffer::ReadPasswordHash( XclImpStream& rStrm )
+{
+ rStrm.EnableDecryption();
+ mnPassHash = rStrm.ReaduInt16();
+}
+
+void XclImpDocProtectBuffer::Apply() const
+{
+ if (!mbDocProtect && !mbWinProtect)
+ // Excel requires either the structure or windows protection is set.
+ // If neither is set then the document is not protected at all.
+ return;
+
+ auto_ptr<ScDocProtection> pProtect(new ScDocProtection);
+ pProtect->setProtected(true);
+
+#if ENABLE_SHEET_PROTECTION
+ if (mnPassHash)
+ {
+ // 16-bit password pash.
+ Sequence<sal_Int8> aPass(2);
+ aPass[0] = (mnPassHash >> 8) & 0xFF;
+ aPass[1] = mnPassHash & 0xFF;
+ pProtect->setPasswordHash(aPass, PASSHASH_XL);
+ }
+#endif
+
+ // document protection options
+ pProtect->setOption(ScDocProtection::STRUCTURE, mbDocProtect);
+ pProtect->setOption(ScDocProtection::WINDOWS, mbWinProtect);
+
+ GetDoc().SetDocProtection(pProtect.get());
+}
+
+// Sheet Protection ===========================================================
+
+XclImpSheetProtectBuffer::Sheet::Sheet() :
+ mbProtected(false),
+ mnPasswordHash(0x0000),
+ mnOptions(0x4400)
+{
+}
+
+// ----------------------------------------------------------------------------
+
+XclImpSheetProtectBuffer::Sheet::Sheet(const Sheet& r) :
+ mbProtected(r.mbProtected),
+ mnPasswordHash(r.mnPasswordHash),
+ mnOptions(r.mnOptions)
+{
+}
+
+XclImpSheetProtectBuffer::XclImpSheetProtectBuffer( const XclImpRoot& rRoot ) :
+ XclImpRoot( rRoot )
+{
+}
+
+void XclImpSheetProtectBuffer::ReadProtect( XclImpStream& rStrm, SCTAB nTab )
+{
+ if ( rStrm.ReaduInt16() )
+ {
+ Sheet* pSheet = GetSheetItem(nTab);
+ if (pSheet)
+ pSheet->mbProtected = true;
+ }
+}
+
+void XclImpSheetProtectBuffer::ReadOptions( XclImpStream& rStrm, SCTAB nTab )
+{
+ rStrm.Ignore(19);
+ sal_uInt16 nOptions;
+ rStrm >> nOptions;
+
+ Sheet* pSheet = GetSheetItem(nTab);
+ if (pSheet)
+ pSheet->mnOptions = nOptions;
+}
+
+void XclImpSheetProtectBuffer::ReadPasswordHash( XclImpStream& rStrm, SCTAB nTab )
+{
+ sal_uInt16 nHash;
+ rStrm >> nHash;
+ Sheet* pSheet = GetSheetItem(nTab);
+ if (pSheet)
+ pSheet->mnPasswordHash = nHash;
+}
+
+void XclImpSheetProtectBuffer::Apply() const
+{
+ for (ProtectedSheetMap::const_iterator itr = maProtectedSheets.begin(), itrEnd = maProtectedSheets.end();
+ itr != itrEnd; ++itr)
+ {
+ if (!itr->second.mbProtected)
+ // This sheet is (for whatever reason) not protected.
+ continue;
+
+ auto_ptr<ScTableProtection> pProtect(new ScTableProtection);
+ pProtect->setProtected(true);
+
+#if ENABLE_SHEET_PROTECTION
+ // 16-bit hash password
+ const sal_uInt16 nHash = itr->second.mnPasswordHash;
+ if (nHash)
+ {
+ Sequence<sal_Int8> aPass(2);
+ aPass[0] = (nHash >> 8) & 0xFF;
+ aPass[1] = nHash & 0xFF;
+ pProtect->setPasswordHash(aPass, PASSHASH_XL);
+ }
+#endif
+
+ // sheet protection options
+ const sal_uInt16 nOptions = itr->second.mnOptions;
+ pProtect->setOption( ScTableProtection::OBJECTS, (nOptions & 0x0001) );
+ pProtect->setOption( ScTableProtection::SCENARIOS, (nOptions & 0x0002) );
+ pProtect->setOption( ScTableProtection::FORMAT_CELLS, (nOptions & 0x0004) );
+ pProtect->setOption( ScTableProtection::FORMAT_COLUMNS, (nOptions & 0x0008) );
+ pProtect->setOption( ScTableProtection::FORMAT_ROWS, (nOptions & 0x0010) );
+ pProtect->setOption( ScTableProtection::INSERT_COLUMNS, (nOptions & 0x0020) );
+ pProtect->setOption( ScTableProtection::INSERT_ROWS, (nOptions & 0x0040) );
+ pProtect->setOption( ScTableProtection::INSERT_HYPERLINKS, (nOptions & 0x0080) );
+ pProtect->setOption( ScTableProtection::DELETE_COLUMNS, (nOptions & 0x0100) );
+ pProtect->setOption( ScTableProtection::DELETE_ROWS, (nOptions & 0x0200) );
+ pProtect->setOption( ScTableProtection::SELECT_LOCKED_CELLS, (nOptions & 0x0400) );
+ pProtect->setOption( ScTableProtection::SORT, (nOptions & 0x0800) );
+ pProtect->setOption( ScTableProtection::AUTOFILTER, (nOptions & 0x1000) );
+ pProtect->setOption( ScTableProtection::PIVOT_TABLES, (nOptions & 0x2000) );
+ pProtect->setOption( ScTableProtection::SELECT_UNLOCKED_CELLS, (nOptions & 0x4000) );
+
+ // all done. now commit.
+ GetDoc().SetTabProtection(itr->first, pProtect.get());
+ }
+}
+
+XclImpSheetProtectBuffer::Sheet* XclImpSheetProtectBuffer::GetSheetItem( SCTAB nTab )
+{
+ ProtectedSheetMap::iterator itr = maProtectedSheets.find(nTab);
+ if (itr == maProtectedSheets.end())
+ {
+ // new sheet
+ if ( !maProtectedSheets.insert( ProtectedSheetMap::value_type(nTab, Sheet()) ).second )
+ return NULL;
+
+ itr = maProtectedSheets.find(nTab);
+ }
+
+ return &itr->second;
}
// ============================================================================
diff --git a/sc/source/filter/excel/xilink.cxx b/sc/source/filter/excel/xilink.cxx
index 16a3edf46373..2c2426382178 100644
--- a/sc/source/filter/excel/xilink.cxx
+++ b/sc/source/filter/excel/xilink.cxx
@@ -263,6 +263,7 @@ void XclImpTabInfo::ReadTabid( XclImpStream& rStrm )
DBG_ASSERT_BIFF( rStrm.GetRoot().GetBiff() == EXC_BIFF8 );
if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
{
+ rStrm.EnableDecryption();
sal_Size nReadCount = rStrm.GetRecLeft() / 2;
DBG_ASSERT( nReadCount <= 0xFFFF, "XclImpTabInfo::ReadTabid - record too long" );
maTabIdVec.clear();
diff --git a/sc/source/filter/excel/xiroot.cxx b/sc/source/filter/excel/xiroot.cxx
index d5d11196e9a3..55ba4bdc4cb4 100644
--- a/sc/source/filter/excel/xiroot.cxx
+++ b/sc/source/filter/excel/xiroot.cxx
@@ -52,6 +52,7 @@
XclImpRootData::XclImpRootData( XclBiff eBiff, SfxMedium& rMedium,
SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc ) :
XclRootData( eBiff, rMedium, xRootStrg, rDoc, eTextEnc, false ),
+ mbPassQueried( false ),
mbHasCodePage( false )
{
}
@@ -86,6 +87,8 @@ XclImpRoot::XclImpRoot( XclImpRootData& rImpRootData ) :
GetOldRoot().pAutoFilterBuffer = new XclImpAutoFilterBuffer;
mrImpData.mxWebQueryBfr.reset( new XclImpWebQueryBuffer( GetRoot() ) );
mrImpData.mxPTableMgr.reset( new XclImpPivotTableManager( GetRoot() ) );
+ mrImpData.mxTabProtect.reset( new XclImpSheetProtectBuffer( GetRoot() ) );
+ mrImpData.mxDocProtect.reset( new XclImpDocProtectBuffer( GetRoot() ) );
}
mrImpData.mxPageSett.reset( new XclImpPageSettings( GetRoot() ) );
@@ -232,6 +235,18 @@ XclImpPivotTableManager& XclImpRoot::GetPivotTableManager() const
return *mrImpData.mxPTableMgr;
}
+XclImpSheetProtectBuffer& XclImpRoot::GetSheetProtectBuffer() const
+{
+ DBG_ASSERT( mrImpData.mxTabProtect.is(), "XclImpRoot::GetSheetProtectBuffer - invalid call, wrong BIFF" );
+ return *mrImpData.mxTabProtect;
+}
+
+XclImpDocProtectBuffer& XclImpRoot::GetDocProtectBuffer() const
+{
+ DBG_ASSERT( mrImpData.mxDocProtect.is(), "XclImpRoot::GetDocProtectBuffer - invalid call, wrong BIFF" );
+ return *mrImpData.mxDocProtect;
+}
+
XclImpPageSettings& XclImpRoot::GetPageSettings() const
{
return *mrImpData.mxPageSett;
@@ -255,5 +270,16 @@ String XclImpRoot::GetScAddInName( const String& rXclName ) const
return rXclName;
}
+const String& XclImpRoot::QueryPassword() const
+{
+ if( !mrImpData.mbPassQueried )
+ {
+ mrImpData.maPassw = ScfApiHelper::QueryPasswordForMedium( GetMedium() );
+ // set to true, even if dialog has been cancelled (never ask twice)
+ mrImpData.mbPassQueried = true;
+ }
+ return mrImpData.maPassw;
+}
+
// ============================================================================
diff --git a/sc/source/filter/excel/xistream.cxx b/sc/source/filter/excel/xistream.cxx
index b7f0d3841645..e7780c065118 100644
--- a/sc/source/filter/excel/xistream.cxx
+++ b/sc/source/filter/excel/xistream.cxx
@@ -36,6 +36,8 @@
#include "xlstring.hxx"
#include "xiroot.hxx"
+#include <vector>
+
// ============================================================================
// Decryption
// ============================================================================
@@ -97,11 +99,21 @@ sal_uInt16 XclImpDecrypter::Read( SvStream& rStrm, void* pData, sal_uInt16 nByte
return nRet;
}
+const String XclImpDecrypter::GetPassword() const
+{
+ return maPass;
+}
+
void XclImpDecrypter::SetHasValidPassword( bool bValid )
{
mnError = bValid ? ERRCODE_NONE : EXC_ENCR_ERROR_WRONG_PASS;
}
+void XclImpDecrypter::SetPassword( const String& rPass )
+{
+ maPass = rPass;
+}
+
// ----------------------------------------------------------------------------
XclImpBiff5Decrypter::XclImpBiff5Decrypter( const XclImpRoot& rRoot, sal_uInt16 nKey, sal_uInt16 nHash )
@@ -157,6 +169,9 @@ void XclImpBiff5Decrypter::Init( const ByteString& rPass, sal_uInt16 nKey, sal_u
// init codec
maCodec.InitKey( mpnPassw );
bValid = maCodec.VerifyKey( nKey, nHash );
+
+ String aUniPass( rPass, RTL_TEXTENCODING_MS_1252 );
+ SetPassword( aUniPass );
}
SetHasValidPassword( bValid );
@@ -255,6 +270,8 @@ void XclImpBiff8Decrypter::Init(
// init codec
maCodec.InitKey( mpnPassw, mpnDocId );
bValid = maCodec.VerifyKey( pnSaltData, pnSaltHash );
+
+ SetPassword(rPass);
}
SetHasValidPassword( bValid );
diff --git a/sc/source/filter/excel/xlroot.cxx b/sc/source/filter/excel/xlroot.cxx
index bdc75df21c13..8f5ddadd0370 100644
--- a/sc/source/filter/excel/xlroot.cxx
+++ b/sc/source/filter/excel/xlroot.cxx
@@ -92,8 +92,7 @@ XclRootData::XclRootData( XclBiff eBiff, SfxMedium& rMedium,
mxRD( new RootData ),//!
mnCharWidth( 110 ),
mnScTab( 0 ),
- mbExport( bExport ),
- mbHasPassw( false )
+ mbExport( bExport )
{
// default script type, e.g. for empty cells
switch( ScGlobal::GetDefaultScriptType() )
@@ -199,17 +198,6 @@ void XclRoot::SetCharWidth( const XclFontData& rFontData )
}
}
-const String& XclRoot::QueryPassword() const
-{
- if( !mrData.mbHasPassw )
- {
- mrData.maPassw = ScfApiHelper::QueryPasswordForMedium( GetMedium() );
- // set to true, even if dialog has been cancelled (never ask twice)
- mrData.mbHasPassw = true;
- }
- return mrData.maPassw;
-}
-
bool XclRoot::HasVbaStorage() const
{
SotStorageRef xRootStrg = GetRootStorage();
diff --git a/sc/source/filter/inc/excimp8.hxx b/sc/source/filter/inc/excimp8.hxx
index 2f3913f01c57..9bd633eae879 100644
--- a/sc/source/filter/inc/excimp8.hxx
+++ b/sc/source/filter/inc/excimp8.hxx
@@ -61,7 +61,6 @@ class ImportExcel8 : public ImportExcel
void Precision( void ); // 0x0E
void Delta( void ); // 0x10
void Iteration( void ); // 0x11
- void WinProtection( void ); // 0x19
void Boundsheet( void ); // 0x85
void FilterMode( void ); // 0x9B
void AutoFilterInfo( void ); // 0x9D
@@ -73,6 +72,7 @@ class ImportExcel8 : public ImportExcel
void Hlink( void ); // 0x01B8
void Codename( BOOL bWBGlobals ); // 0x01BA
+ void SheetProtection( void ); // 0x0867
virtual void EndSheet( void );
virtual void PostDocLoad( void );
diff --git a/sc/source/filter/inc/excrecds.hxx b/sc/source/filter/inc/excrecds.hxx
index da4115fc8003..1f2eee05fd55 100644
--- a/sc/source/filter/inc/excrecds.hxx
+++ b/sc/source/filter/inc/excrecds.hxx
@@ -246,10 +246,23 @@ class XclExpWindowProtection : public XclExpBoolRecord
};
// EXC_ID_PROTECT Document Protection
-class XclExpDocProtection : public XclExpBoolRecord
+class XclExpProtection : public XclExpBoolRecord
{
public:
- XclExpDocProtection(bool bValue);
+ XclExpProtection(bool bValue);
+};
+
+class XclExpPassHash : public XclExpRecord
+{
+public:
+ XclExpPassHash(const ::com::sun::star::uno::Sequence<sal_Int8>& aHash);
+ virtual ~XclExpPassHash();
+
+private:
+ virtual void WriteBody(XclExpStream& rStrm);
+
+private:
+ sal_uInt16 mnHash;
};
diff --git a/sc/source/filter/inc/imp_op.hxx b/sc/source/filter/inc/imp_op.hxx
index 66a58ffb67a4..f8dad9a45c48 100644
--- a/sc/source/filter/inc/imp_op.hxx
+++ b/sc/source/filter/inc/imp_op.hxx
@@ -135,9 +135,11 @@ protected:
void Bof2( void ); // 0x09
void Eof( void ); // 0x0A
void DocProtect( void ); // 0x12
- void Protect( void ); // 0x12 Sheet Protection
- BOOL Password( void ); // 0x13
+ void SheetProtect( void ); // 0x12 Sheet Protection
+ void DocPasssword( void ); // 0x13 document password
+ void SheetPassword( void ); // 0x13 sheet password
void Externsheet( void ); // 0x17
+ void WinProtection( void ); // 0x19
void Columndefault( void ); // 0x20
void Array25( void ); // 0x21
void Rec1904( void ); // 0x22
diff --git a/sc/source/filter/inc/xcl97rec.hxx b/sc/source/filter/inc/xcl97rec.hxx
index d01f81ba8013..649a7bd02702 100644
--- a/sc/source/filter/inc/xcl97rec.hxx
+++ b/sc/source/filter/inc/xcl97rec.hxx
@@ -35,6 +35,8 @@
#include "xcl97esc.hxx"
#include "xlstyle.hxx"
+#include <vector>
+
// --- class XclMsodrawing_Base --------------------------------------
class XclMsodrawing_Base
@@ -57,29 +59,26 @@ public:
// --- class XclMsodrawinggroup --------------------------------------
-class XclMsodrawinggroup : public XclMsodrawing_Base, public ExcRecord
+class XclMsodrawinggroup : public XclMsodrawing_Base, public XclExpRecord
{
private:
- virtual void SaveCont( XclExpStream& rStrm );
+ virtual void WriteBody( XclExpStream& rStrm );
public:
XclMsodrawinggroup( RootData& rRoot,
UINT16 nEscherType = 0 );
virtual ~XclMsodrawinggroup();
-
- virtual UINT16 GetNum() const;
- virtual sal_Size GetLen() const;
};
// --- class XclMsodrawing -------------------------------------------
-class XclMsodrawing : public XclMsodrawing_Base, public ExcRecord
+class XclMsodrawing : public XclMsodrawing_Base, public XclExpRecord
{
private:
- virtual void SaveCont( XclExpStream& rStrm );
+ virtual void WriteBody( XclExpStream& rStrm );
public:
XclMsodrawing(
@@ -87,9 +86,6 @@ public:
UINT16 nEscherType = 0,
sal_Size nInitialSize = 0 );
virtual ~XclMsodrawing();
-
- virtual UINT16 GetNum() const;
- virtual sal_Size GetLen() const;
};
@@ -464,23 +460,24 @@ public:
virtual sal_Size GetLen() const;
};
+// ============================================================================
-// ---- class XclProtection ------------------------------------------
-
-class XclProtection : public ExcDummyRec
+/** Represents a SHEETPROTECTION record that stores sheet protection
+ options. Note that a sheet still needs to save its sheet protection
+ options even when it's not protected. */
+class XclExpSheetProtectOptions : public XclExpRecord
{
- // replacement for records PROTECT, SCENPROTECT, OBJPROTECT...
-private:
- static const BYTE pMyData[];
- static const sal_Size nMyLen;
public:
- virtual sal_Size GetLen( void ) const;
- virtual const BYTE* GetData( void ) const;
-};
+ explicit XclExpSheetProtectOptions( const XclExpRoot& rRoot, SCTAB nTab );
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
-// -------------------------------------------------------------------
+private:
+ sal_uInt16 mnOptions; /// Encoded sheet protection options.
+};
+// ============================================================================
class XclCalccount : public ExcRecord
{
@@ -544,5 +541,162 @@ public:
virtual void SaveXml( XclExpXmlStream& rStrm );
};
+// ============================================================================
+
+class XclExpFilePass : public XclExpRecord
+{
+public:
+ explicit XclExpFilePass( const XclExpRoot& rRoot );
+ virtual ~XclExpFilePass();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+
+private:
+ const XclExpRoot& mrRoot;
+};
+
+// ============================================================================
+
+class XclExpFnGroupCount : public XclExpRecord
+{
+public:
+ explicit XclExpFnGroupCount();
+ virtual ~XclExpFnGroupCount();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+/** Beginning of User Interface Records */
+class XclExpInterfaceHdr : public XclExpRecord
+{
+public:
+ explicit XclExpInterfaceHdr();
+ virtual ~XclExpInterfaceHdr();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+/** Beginning of User Interface Records */
+class XclExpInterfaceEnd : public XclExpRecord
+{
+public:
+ explicit XclExpInterfaceEnd();
+ virtual ~XclExpInterfaceEnd();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+/** ADDMENU/DELMENU Record Group Count */
+class XclExpMMS : public XclExpRecord
+{
+public:
+ explicit XclExpMMS();
+ virtual ~XclExpMMS();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+/** Write Access User Name - This record contains the user name, which is
+ the name you type when you install Excel. */
+class XclExpWriteAccess : public XclExpRecord
+{
+public:
+ explicit XclExpWriteAccess();
+ virtual ~XclExpWriteAccess();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+class XclExpCodePage : public XclExpRecord
+{
+public:
+ explicit XclExpCodePage();
+ virtual ~XclExpCodePage();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+class XclExpDSF : public XclExpRecord
+{
+public:
+ explicit XclExpDSF();
+ virtual ~XclExpDSF();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+class XclExpProt4Rev : public XclExpRecord
+{
+public:
+ explicit XclExpProt4Rev();
+ virtual ~XclExpProt4Rev();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+class XclExpProt4RevPass : public XclExpRecord
+{
+public:
+ explicit XclExpProt4RevPass();
+ virtual ~XclExpProt4RevPass();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+/** What's this record for? It is a zero-byte record. */
+class XclExpExcel9File : public XclExpRecord
+{
+public:
+ explicit XclExpExcel9File();
+ virtual ~XclExpExcel9File();
+
+private:
+ virtual void WriteBody( XclExpStream& rStrm );
+};
+
+// ============================================================================
+
+class XclExpRecalcId : public XclExpDummyRecord
+{
+public:
+ explicit XclExpRecalcId();
+};
+
+// ============================================================================
+
+class XclExpBookExt : public XclExpDummyRecord
+{
+public:
+ explicit XclExpBookExt();
+};
+
#endif // _XCL97REC_HXX
diff --git a/sc/source/filter/inc/xeroot.hxx b/sc/source/filter/inc/xeroot.hxx
index d050ea82ac81..178bb19763f8 100644
--- a/sc/source/filter/inc/xeroot.hxx
+++ b/sc/source/filter/inc/xeroot.hxx
@@ -154,7 +154,12 @@ public:
@param nRecId Identifier that specifies which record is returned. */
XclExpRecordRef CreateRecord( sal_uInt16 nRecId ) const;
+ bool IsDocumentEncrypted() const;
+
+ const String GetPassword() const;
+
private:
+
/** Returns the local or global link manager, depending on current context. */
XclExpRootData::XclExpLinkMgrRef GetLocalLinkMgrRef() const;
diff --git a/sc/source/filter/inc/xestream.hxx b/sc/source/filter/inc/xestream.hxx
index 8792f26c6582..e2b9d263c735 100644
--- a/sc/source/filter/inc/xestream.hxx
+++ b/sc/source/filter/inc/xestream.hxx
@@ -43,6 +43,9 @@
#include "xlstream.hxx"
#include "xestring.hxx"
+#include <svx/mscodec.hxx>
+#include <vector>
+
/* ============================================================================
Output stream class for Excel export
- CONTINUE record handling
@@ -50,6 +53,8 @@ Output stream class for Excel export
============================================================================ */
class XclExpRoot;
+class XclExpBiff8Encrypter;
+typedef ScfRef< XclExpBiff8Encrypter > XclExpEncrypterRef;
/** This class is used to export Excel record streams.
@descr An instance is constructed with an SvStream and the maximum size of Excel
@@ -108,14 +113,14 @@ public:
/** Sets data slice length. 0 = no slices. */
void SetSliceSize( sal_uInt16 nSize );
- inline XclExpStream& operator<<( sal_Int8 nValue );
- inline XclExpStream& operator<<( sal_uInt8 nValue );
- inline XclExpStream& operator<<( sal_Int16 nValue );
- inline XclExpStream& operator<<( sal_uInt16 nValue );
- inline XclExpStream& operator<<( sal_Int32 nValue );
- inline XclExpStream& operator<<( sal_uInt32 nValue );
- inline XclExpStream& operator<<( float fValue );
- inline XclExpStream& operator<<( double fValue );
+ XclExpStream& operator<<( sal_Int8 nValue );
+ XclExpStream& operator<<( sal_uInt8 nValue );
+ XclExpStream& operator<<( sal_Int16 nValue );
+ XclExpStream& operator<<( sal_uInt16 nValue );
+ XclExpStream& operator<<( sal_Int32 nValue );
+ XclExpStream& operator<<( sal_uInt32 nValue );
+ XclExpStream& operator<<( float fValue );
+ XclExpStream& operator<<( double fValue );
/** Writes nBytes bytes from memory. */
sal_Size Write( const void* pData, sal_Size nBytes );
@@ -158,6 +163,14 @@ public:
/** Returns the absolute position of the system stream. */
inline sal_Size GetSvStreamPos() const { return mrStrm.Tell(); }
+ void SetEncrypter( XclExpEncrypterRef xEncrypter );
+
+ bool HasValidEncrypter() const;
+
+ void EnableEncryption( bool bEnable = true );
+
+ void DisableEncryption();
+
private:
/** Writes header data, internal setup. */
void InitRecord( sal_uInt16 nRecId );
@@ -180,6 +193,9 @@ private:
SvStream& mrStrm; /// Reference to the system output stream.
const XclExpRoot& mrRoot; /// Filter root data.
+ bool mbUseEncrypter;
+ XclExpEncrypterRef mxEncrypter;
+
// length data
sal_uInt16 mnMaxRecSize; /// Maximum size of record content.
sal_uInt16 mnMaxContSize; /// Maximum size of CONTINUE content.
@@ -197,64 +213,50 @@ private:
// ----------------------------------------------------------------------------
-inline XclExpStream& XclExpStream::operator<<( sal_Int8 nValue )
-{
- PrepareWrite( 1 );
- mrStrm << nValue;
- return *this;
-}
-inline XclExpStream& XclExpStream::operator<<( sal_uInt8 nValue )
-{
- PrepareWrite( 1 );
- mrStrm << nValue;
- return *this;
-}
+// ============================================================================
-inline XclExpStream& XclExpStream::operator<<( sal_Int16 nValue )
+class XclExpBiff8Encrypter
{
- PrepareWrite( 2 );
- mrStrm << nValue;
- return *this;
-}
+public:
+ explicit XclExpBiff8Encrypter( const XclExpRoot& rRoot, const sal_uInt8 nDocId[16],
+ const sal_uInt8 nSalt[16] );
+ ~XclExpBiff8Encrypter();
-inline XclExpStream& XclExpStream::operator<<( sal_uInt16 nValue )
-{
- PrepareWrite( 2 );
- mrStrm << nValue;
- return *this;
-}
+ bool IsValid() const;
-inline XclExpStream& XclExpStream::operator<<( sal_Int32 nValue )
-{
- PrepareWrite( 4 );
- mrStrm << nValue;
- return *this;
-}
+ void GetSaltDigest( sal_uInt8 nSaltDigest[16] ) const;
-inline XclExpStream& XclExpStream::operator<<( sal_uInt32 nValue )
-{
- PrepareWrite( 4 );
- mrStrm << nValue;
- return *this;
-}
+ void Encrypt( SvStream& rStrm, sal_uInt8 nData );
+ void Encrypt( SvStream& rStrm, sal_uInt16 nData );
+ void Encrypt( SvStream& rStrm, sal_uInt32 nData );
-inline XclExpStream& XclExpStream::operator<<( float fValue )
-{
- PrepareWrite( 4 );
- mrStrm << fValue;
- return *this;
-}
+ void Encrypt( SvStream& rStrm, sal_Int8 nData );
+ void Encrypt( SvStream& rStrm, sal_Int16 nData );
+ void Encrypt( SvStream& rStrm, sal_Int32 nData );
-inline XclExpStream& XclExpStream::operator<<( double fValue )
-{
- PrepareWrite( 8 );
- mrStrm << fValue;
- return *this;
-}
+ void Encrypt( SvStream& rStrm, float fValue );
+ void Encrypt( SvStream& rStrm, double fValue );
+ void EncryptBytes( SvStream& rStrm, ::std::vector<sal_uInt8>& aBytes );
-// ============================================================================
+private:
+ void Init( const String& aPass, const sal_uInt8 nDocId[16],
+ const sal_uInt8 nSalt[16] );
+
+ sal_uInt32 GetBlockPos( sal_Size nStrmPos ) const;
+ sal_uInt16 GetOffsetInBlock( sal_Size nStrmPos ) const;
+
+private:
+ ::svx::MSCodec_Std97 maCodec; /// Crypto algorithm implementation.
+ sal_uInt16 mnPassw[16]; /// Cached password data for copy construction.
+ sal_uInt8 mnDocId[16]; /// Cached document ID for copy construction.
+ sal_uInt8 mnSaltDigest[16];
+
+ const XclExpRoot& mrRoot;
+ sal_Size mnOldPos; /// Last known stream position
+ bool mbValid;
+};
// ----------------------------------------------------------------------------
diff --git a/sc/source/filter/inc/xetable.hxx b/sc/source/filter/inc/xetable.hxx
index 7be4f406ee23..5322b0c47f01 100644
--- a/sc/source/filter/inc/xetable.hxx
+++ b/sc/source/filter/inc/xetable.hxx
@@ -1088,7 +1088,5 @@ private:
XclExpDvalRef mxDval; /// Data validation with DVAL and DV records.
};
-// ============================================================================
-
#endif
diff --git a/sc/source/filter/inc/xicontent.hxx b/sc/source/filter/inc/xicontent.hxx
index 2b777e57600c..53ed10583249 100644
--- a/sc/source/filter/inc/xicontent.hxx
+++ b/sc/source/filter/inc/xicontent.hxx
@@ -37,6 +37,8 @@
#include "xistring.hxx"
#include "xiroot.hxx"
+#include <map>
+
/* ============================================================================
Classes to import the big Excel document contents (related to several cells or
globals for the document).
@@ -249,5 +251,64 @@ public:
// ============================================================================
+// Document protection ========================================================
+
+class XclImpDocProtectBuffer : protected XclImpRoot
+{
+public:
+ explicit XclImpDocProtectBuffer( const XclImpRoot& rRoot );
+
+ /** document structure protection flag */
+ void ReadDocProtect( XclImpStream& rStrm );
+
+ /** document windows properties protection flag */
+ void ReadWinProtect( XclImpStream& rStrm );
+
+ void ReadPasswordHash( XclImpStream& rStrm );
+
+ void Apply() const;
+
+private:
+ sal_uInt16 mnPassHash;
+ bool mbDocProtect:1;
+ bool mbWinProtect:1;
+};
+
+// Sheet protection ===========================================================
+
+class XclImpSheetProtectBuffer : protected XclImpRoot
+{
+public:
+ explicit XclImpSheetProtectBuffer( const XclImpRoot& rRoot );
+
+ void ReadProtect( XclImpStream& rStrm, SCTAB nTab );
+
+ void ReadOptions( XclImpStream& rStrm, SCTAB nTab );
+
+ void ReadPasswordHash( XclImpStream& rStrm, SCTAB nTab );
+
+ void Apply() const;
+
+private:
+ struct Sheet
+ {
+ bool mbProtected;
+ sal_uInt16 mnPasswordHash;
+ sal_uInt16 mnOptions;
+
+ Sheet();
+ Sheet(const Sheet& r);
+ };
+
+ Sheet* GetSheetItem( SCTAB nTab );
+
+private:
+ typedef ::std::map<SCTAB, Sheet> ProtectedSheetMap;
+ ProtectedSheetMap maProtectedSheets;
+};
+
+
+// ============================================================================
+
#endif
diff --git a/sc/source/filter/inc/xiroot.hxx b/sc/source/filter/inc/xiroot.hxx
index dfa2ca030efe..915f9610a1f3 100644
--- a/sc/source/filter/inc/xiroot.hxx
+++ b/sc/source/filter/inc/xiroot.hxx
@@ -61,6 +61,8 @@ class XclImpPivotTableManager;
class XclImpPageSettings;
class XclImpDocViewSettings;
class XclImpTabViewSettings;
+class XclImpSheetProtectBuffer;
+class XclImpDocProtectBuffer;
class _ScRangeListTabs;
class ExcelToSc;
@@ -87,6 +89,8 @@ struct XclImpRootData : public XclRootData
typedef ScfRef< XclImpPageSettings > XclImpPageSettRef;
typedef ScfRef< XclImpDocViewSettings > XclImpDocViewSettRef;
typedef ScfRef< XclImpTabViewSettings > XclImpTabViewSettRef;
+ typedef ScfRef< XclImpSheetProtectBuffer > XclImpTabProtectRef;
+ typedef ScfRef< XclImpDocProtectBuffer > XclImpDocProtectRef;
XclImpAddrConvRef mxAddrConv; /// The address converter.
XclImpFmlaCompRef mxFmlaComp; /// The formula compiler.
@@ -110,6 +114,11 @@ struct XclImpRootData : public XclRootData
XclImpPageSettRef mxPageSett; /// Page settings for current sheet.
XclImpDocViewSettRef mxDocViewSett; /// View settings for entire document.
XclImpTabViewSettRef mxTabViewSett; /// View settings for current sheet.
+ XclImpTabProtectRef mxTabProtect; /// Sheet protection options for current sheet.
+ XclImpDocProtectRef mxDocProtect; /// Document protection options.
+
+ String maPassw; /// Entered password for stream decryption.
+ bool mbPassQueried; /// true = Password already querried.
bool mbHasCodePage; /// true = CODEPAGE record exists.
@@ -181,6 +190,10 @@ public:
XclImpWebQueryBuffer& GetWebQueryBuffer() const;
/** Returns the pivot table manager. */
XclImpPivotTableManager& GetPivotTableManager() const;
+ /** Returns the sheet protection options of the current sheet. */
+ XclImpSheetProtectBuffer& GetSheetProtectBuffer() const;
+ /** Returns the document protection options. */
+ XclImpDocProtectBuffer& GetDocProtectBuffer() const;
/** Returns the page settings of the current sheet. */
XclImpPageSettings& GetPageSettings() const;
@@ -192,6 +205,9 @@ public:
/** Returns the Calc add-in function name for an Excel function name. */
String GetScAddInName( const String& rXclName ) const;
+ /** Queries a password from the user and returns it (empty string -> input cancelled). */
+ const String& QueryPassword() const;
+
private:
mutable XclImpRootData& mrImpData; /// Reference to the global import data struct.
};
diff --git a/sc/source/filter/inc/xistream.hxx b/sc/source/filter/inc/xistream.hxx
index aa1cae84d8f6..ccaaccdc0357 100644
--- a/sc/source/filter/inc/xistream.hxx
+++ b/sc/source/filter/inc/xistream.hxx
@@ -73,6 +73,8 @@ public:
@return Count of bytes really read. */
sal_uInt16 Read( SvStream& rStrm, void* pData, sal_uInt16 nBytes );
+ const String GetPassword() const;
+
protected:
/** Protected copy c'tor for OnClone(). */
explicit XclImpDecrypter( const XclImpDecrypter& rSrc );
@@ -80,6 +82,8 @@ protected:
/** Sets the decrypter to a state showing whether the password was correct. */
void SetHasValidPassword( bool bValid );
+ void SetPassword( const String& rPass );
+
private:
/** Implementation of cloning this object. */
virtual XclImpDecrypter* OnClone() const = 0;
@@ -89,6 +93,7 @@ private:
virtual sal_uInt16 OnRead( SvStream& rStrm, sal_uInt8* pnData, sal_uInt16 nBytes ) = 0;
private:
+ String maPass; /// Stored password (needed for export)
ErrCode mnError; /// Decrypter error code.
sal_Size mnOldPos; /// Last known stream position.
sal_uInt16 mnRecSize; /// Current record size.
diff --git a/sc/source/filter/inc/xlroot.hxx b/sc/source/filter/inc/xlroot.hxx
index 12ab2808a1ab..36056ead2fe2 100644
--- a/sc/source/filter/inc/xlroot.hxx
+++ b/sc/source/filter/inc/xlroot.hxx
@@ -92,7 +92,6 @@ struct XclRootData
ScDocument& mrDoc; /// The source or destination document.
String maDocUrl; /// Document URL of imported/exported file.
String maBasePath; /// Base path of imported/exported file (path of maDocUrl).
- String maPassw; /// Entered password for stream encryption/decryption.
rtl_TextEncoding meTextEnc; /// Text encoding to import/export byte strings.
LanguageType meSysLang; /// System language.
LanguageType meDocLang; /// Document language (import: from file, export: from system).
@@ -116,7 +115,6 @@ struct XclRootData
long mnCharWidth; /// Width of '0' in default font (twips).
SCTAB mnScTab; /// Current Calc sheet index.
const bool mbExport; /// false = Import, true = Export.
- bool mbHasPassw; /// true = Password already querried.
explicit XclRootData( XclBiff eBiff, SfxMedium& rMedium,
SotStorageRef xRootStrg, ScDocument& rDoc,
@@ -184,8 +182,6 @@ public:
inline const String& GetDocUrl() const { return mrData.maDocUrl; }
/** Returns the base path of the imported/exported file. */
inline const String& GetBasePath() const { return mrData.maBasePath; }
- /** Queries a password from the user and returns it (empty string -> input cancelled). */
- const String& QueryPassword() const;
/** Returns the OLE2 root storage of the imported/exported file.
@return Pointer to root storage or 0, if the file is a simple stream. */
diff --git a/sc/source/filter/starcalc/scflt.cxx b/sc/source/filter/starcalc/scflt.cxx
index 511c706abdfb..8decce39fe6f 100644
--- a/sc/source/filter/starcalc/scflt.cxx
+++ b/sc/source/filter/starcalc/scflt.cxx
@@ -81,6 +81,7 @@
#include "postit.hxx"
#include "globstr.hrc"
#include "ftools.hxx"
+#include "tabprotection.hxx"
#include "fprogressbar.hxx"
@@ -1087,9 +1088,11 @@ void Sc10Import::LoadProtect()
//rStream.Read(&SheetProtect, sizeof(SheetProtect));
lcl_ReadSheetProtect(rStream, SheetProtect);
nError = rStream.GetError();
- uno::Sequence<sal_Int8> aPass;
- SvPasswordHelper::GetHashPassword(aPass, SC10TOSTRING( SheetProtect.PassWord ));
- pDoc->SetDocProtection( SheetProtect.Protect, aPass);
+
+ ScDocProtection aProtection;
+ aProtection.setProtected(static_cast<bool>(SheetProtect.Protect));
+ aProtection.setPassword(SC10TOSTRING(SheetProtect.PassWord));
+ pDoc->SetDocProtection(&aProtection);
}
@@ -1441,10 +1444,11 @@ void Sc10Import::LoadTables()
//rStream.Read(&TabProtect, sizeof(TabProtect));
lcl_ReadTabProtect(rStream, TabProtect);
- uno::Sequence<sal_Int8> aPass;
- SvPasswordHelper::GetHashPassword(aPass, SC10TOSTRING( TabProtect.PassWord ));
- pDoc->SetTabProtection( static_cast<SCTAB>(Tab), TabProtect.Protect, aPass);
+ ScTableProtection aProtection;
+ aProtection.setProtected(static_cast<bool>(TabProtect.Protect));
+ aProtection.setPassword(SC10TOSTRING(TabProtect.PassWord));
+ pDoc->SetTabProtection(static_cast<SCTAB>(Tab), &aProtection);
rStream >> TabNo;
diff --git a/sc/source/filter/xcl97/XclExpChangeTrack.cxx b/sc/source/filter/xcl97/XclExpChangeTrack.cxx
index 760599ff594b..a38b023d4f55 100644
--- a/sc/source/filter/xcl97/XclExpChangeTrack.cxx
+++ b/sc/source/filter/xcl97/XclExpChangeTrack.cxx
@@ -491,6 +491,7 @@ void XclExpChTrTabId::Copy( const XclExpChTrTabIdBuffer& rBuffer )
void XclExpChTrTabId::SaveCont( XclExpStream& rStrm )
{
+ rStrm.EnableEncryption();
if( pBuffer )
for( sal_uInt16* pElem = pBuffer; pElem < (pBuffer + nTabCount); pElem++ )
rStrm << *pElem;
diff --git a/sc/source/filter/xcl97/makefile.mk b/sc/source/filter/xcl97/makefile.mk
index c40209d40819..58e2b8cb3074 100644
--- a/sc/source/filter/xcl97/makefile.mk
+++ b/sc/source/filter/xcl97/makefile.mk
@@ -51,7 +51,6 @@ VISIBILITY_HIDDEN=TRUE
# --- Files --------------------------------------------------------
SLOFILES = \
- $(SLO)$/xcl97dum.obj \
$(SLO)$/xcl97esc.obj \
$(SLO)$/xcl97rec.obj \
$(SLO)$/XclImpChangeTrack.obj \
diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx
index 93dc77c71a01..ac71dbb01fbb 100644
--- a/sc/source/filter/xcl97/xcl97rec.cxx
+++ b/sc/source/filter/xcl97/xcl97rec.cxx
@@ -78,6 +78,7 @@
#include "scextopt.hxx"
#include "docoptio.hxx"
#include "patattr.hxx"
+#include "tabprotection.hxx"
#include <oox/core/tokens.hxx>
@@ -135,9 +136,9 @@ sal_Size XclMsodrawing_Base::GetDataLen() const
// --- class XclMsodrawinggroup --------------------------------------
-XclMsodrawinggroup::XclMsodrawinggroup( RootData& rRoot, UINT16 nEscherType )
- :
- XclMsodrawing_Base( *rRoot.pEscher )
+XclMsodrawinggroup::XclMsodrawinggroup( RootData& rRoot, UINT16 nEscherType ) :
+ XclMsodrawing_Base( *rRoot.pEscher ),
+ XclExpRecord(0x00EB, 2) // bogus record size since we don't know the actual size yet.
{
if ( nEscherType )
{
@@ -182,7 +183,7 @@ XclMsodrawinggroup::~XclMsodrawinggroup()
}
-void XclMsodrawinggroup::SaveCont( XclExpStream& rStrm )
+void XclMsodrawinggroup::WriteBody( XclExpStream& rStrm )
{
DBG_ASSERT( GetEscherEx()->GetStreamPos() == GetEscherEx()->GetOffsetFromMap( nStartPos ),
"XclMsodrawinggroup::SaveCont: Escher stream position mismatch" );
@@ -190,23 +191,11 @@ void XclMsodrawinggroup::SaveCont( XclExpStream& rStrm )
}
-UINT16 XclMsodrawinggroup::GetNum() const
-{
- return 0x00EB;
-}
-
-
-sal_Size XclMsodrawinggroup::GetLen() const
-{
- return GetDataLen();
-}
-
-
-
// --- class XclMsodrawing --------------------------------------
XclMsodrawing::XclMsodrawing( const XclExpRoot& rRoot, UINT16 nEscherType, sal_Size nInitialSize ) :
- XclMsodrawing_Base( *rRoot.GetOldRoot().pEscher, nInitialSize )
+ XclMsodrawing_Base( *rRoot.GetOldRoot().pEscher, nInitialSize ),
+ XclExpRecord( 0x00EC, nInitialSize )
{
if ( nEscherType )
{
@@ -232,7 +221,7 @@ XclMsodrawing::~XclMsodrawing()
}
-void XclMsodrawing::SaveCont( XclExpStream& rStrm )
+void XclMsodrawing::WriteBody( XclExpStream& rStrm )
{
DBG_ASSERT( GetEscherEx()->GetStreamPos() == GetEscherEx()->GetOffsetFromMap( nStartPos ),
"XclMsodrawing::SaveCont: Escher stream position mismatch" );
@@ -240,16 +229,6 @@ void XclMsodrawing::SaveCont( XclExpStream& rStrm )
}
-UINT16 XclMsodrawing::GetNum() const
-{
- return 0x00EC;
-}
-
-
-sal_Size XclMsodrawing::GetLen() const
-{
- return GetDataLen();
-}
// --- class XclObjList ----------------------------------------------
@@ -887,6 +866,7 @@ ExcBof8_Base::ExcBof8_Base()
void ExcBof8_Base::SaveCont( XclExpStream& rStrm )
{
+ rStrm.DisableEncryption();
rStrm << nVers << nDocType << nRupBuild << nRupYear
<< nFileHistory << nLowestBiffVer;
}
@@ -946,7 +926,10 @@ void ExcBundlesheet8::SaveCont( XclExpStream& rStrm )
{
nOwnPos = rStrm.GetSvStreamPos();
// write dummy position, real position comes later
- rStrm << sal_uInt32( 0 ) << nGrbit << GetName();
+ rStrm.DisableEncryption();
+ rStrm << sal_uInt32(0);
+ rStrm.EnableEncryption();
+ rStrm << nGrbit << GetName();
}
@@ -1254,33 +1237,73 @@ sal_Size ExcEScenarioManager::GetLen() const
return 8;
}
+// ============================================================================
-
-// ---- class XclProtection ------------------------------------------
-
-const BYTE XclProtection::pMyData[] =
+struct XclExpTabProtectOption
{
- 0x12, 0x00, 0x02, 0x00, 0x01, 0x00, // PROTECT
- 0xDD, 0x00, 0x02, 0x00, 0x01, 0x00, // SCENPROTECT
- 0x63, 0x00, 0x02, 0x00, 0x01, 0x00 // OBJPROTECT
+ ScTableProtection::Option eOption;
+ sal_uInt16 nMask;
};
-const sal_Size XclProtection::nMyLen = sizeof( XclProtection::pMyData );
-sal_Size XclProtection::GetLen( void ) const
+XclExpSheetProtectOptions::XclExpSheetProtectOptions( const XclExpRoot& rRoot, SCTAB nTab ) :
+ XclExpRecord( 0x0867, 23 )
{
- return nMyLen;
-}
-
+ static const XclExpTabProtectOption aTable[] =
+ {
+ { ScTableProtection::OBJECTS, 0x0001 },
+ { ScTableProtection::SCENARIOS, 0x0002 },
+ { ScTableProtection::FORMAT_CELLS, 0x0004 },
+ { ScTableProtection::FORMAT_COLUMNS, 0x0008 },
+ { ScTableProtection::FORMAT_ROWS, 0x0010 },
+ { ScTableProtection::INSERT_COLUMNS, 0x0020 },
+ { ScTableProtection::INSERT_ROWS, 0x0040 },
+ { ScTableProtection::INSERT_HYPERLINKS, 0x0080 },
+
+ { ScTableProtection::DELETE_COLUMNS, 0x0100 },
+ { ScTableProtection::DELETE_ROWS, 0x0200 },
+ { ScTableProtection::SELECT_LOCKED_CELLS, 0x0400 },
+ { ScTableProtection::SORT, 0x0800 },
+ { ScTableProtection::AUTOFILTER, 0x1000 },
+ { ScTableProtection::PIVOT_TABLES, 0x2000 },
+ { ScTableProtection::SELECT_UNLOCKED_CELLS, 0x4000 },
+
+ { ScTableProtection::NONE, 0x0000 }
+ };
+
+ mnOptions = 0x0000;
+ ScTableProtection* pProtect = rRoot.GetDoc().GetTabProtection(nTab);
+ if (!pProtect)
+ return;
-const BYTE* XclProtection::GetData( void ) const
-{
- return pMyData;
+ for (int i = 0; aTable[i].nMask != 0x0000; ++i)
+ {
+ if ( pProtect->isOptionEnabled(aTable[i].eOption) )
+ mnOptions |= aTable[i].nMask;
+ }
}
+void XclExpSheetProtectOptions::WriteBody( XclExpStream& rStrm )
+{
+ sal_uInt16 nBytes = 0x0867;
+ rStrm << nBytes;
+ sal_uChar nZero = 0x00;
+ for (int i = 0; i < 9; ++i)
+ rStrm << nZero;
+ nBytes = 0x0200;
+ rStrm << nBytes;
+ nBytes = 0x0100;
+ rStrm << nBytes;
+ nBytes = 0xFFFF;
+ rStrm << nBytes << nBytes;
+ rStrm << mnOptions;
+ nBytes = 0;
+ rStrm << nBytes;
+}
+// ============================================================================
@@ -1385,8 +1408,253 @@ void XclDelta::SaveXml( XclExpXmlStream& rStrm )
FSEND );
}
+// ============================================================================
+
+XclExpFilePass::XclExpFilePass( const XclExpRoot& rRoot ) :
+ XclExpRecord(0x002F, 54),
+ mrRoot(rRoot)
+{
+}
+
+XclExpFilePass::~XclExpFilePass()
+{
+}
+
+void XclExpFilePass::WriteBody( XclExpStream& rStrm )
+{
+ static const sal_uInt8 nDocId[] = {
+ 0x17, 0xf7, 0x01, 0x08, 0xea, 0xad, 0x30, 0x5c,
+ 0x1a, 0x95, 0xa5, 0x75, 0xd6, 0x79, 0xcd, 0x8d };
+
+
+ static const sal_uInt8 nSalt[] = {
+ 0xa4, 0x5b, 0xf7, 0xe9, 0x9f, 0x55, 0x21, 0xc5,
+ 0xc5, 0x56, 0xa8, 0x0d, 0x39, 0x05, 0x3a, 0xb4 };
+
+ // 0x0000 - neither standard nor strong encryption
+ // 0x0001 - standard or strong encryption
+ rStrm << static_cast<sal_uInt16>(0x0001);
+
+ // 0x0000 - non standard encryption
+ // 0x0001 - standard encryption
+ sal_uInt16 nStdEnc = 0x0001;
+ rStrm << nStdEnc << nStdEnc;
+
+ sal_uInt8 nSaltHash[16];
+ XclExpEncrypterRef xEnc( new XclExpBiff8Encrypter(mrRoot, nDocId, nSalt) );
+ xEnc->GetSaltDigest(nSaltHash);
+
+ rStrm.Write(nDocId, 16);
+ rStrm.Write(nSalt, 16);
+ rStrm.Write(nSaltHash, 16);
+
+ rStrm.SetEncrypter(xEnc);
+}
+
+// ============================================================================
+
+XclExpFnGroupCount::XclExpFnGroupCount() :
+ XclExpRecord(0x009C, 2)
+{
+}
+
+XclExpFnGroupCount::~XclExpFnGroupCount()
+{
+}
+
+void XclExpFnGroupCount::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast<sal_uInt16>(14);
+}
+
+// ============================================================================
+XclExpInterfaceHdr::XclExpInterfaceHdr() :
+ XclExpRecord(0x00E1, 2)
+{
+}
+
+XclExpInterfaceHdr::~XclExpInterfaceHdr()
+{
+}
+
+void XclExpInterfaceHdr::WriteBody( XclExpStream& rStrm )
+{
+ // The value must be the same value as the CODEPAGE record.
+ rStrm.DisableEncryption();
+ rStrm << static_cast<sal_uInt16>(0x04B0);
+}
+
+// ============================================================================
+
+XclExpInterfaceEnd::XclExpInterfaceEnd() :
+ XclExpRecord(0x00E2, 0)
+{
+}
+
+XclExpInterfaceEnd::~XclExpInterfaceEnd()
+{
+}
+
+void XclExpInterfaceEnd::WriteBody( XclExpStream& /*rStrm*/ )
+{
+}
+
+// ============================================================================
+
+XclExpMMS::XclExpMMS() :
+ XclExpRecord(0x00C1, 2)
+{
+}
+
+XclExpMMS::~XclExpMMS()
+{
+}
+
+void XclExpMMS::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast<sal_uInt16>(0x0000);
+}
+
+// ============================================================================
+
+XclExpWriteAccess::XclExpWriteAccess() :
+ XclExpRecord(0x005C, 112)
+{
+}
+
+XclExpWriteAccess::~XclExpWriteAccess()
+{
+}
+
+void XclExpWriteAccess::WriteBody( XclExpStream& rStrm )
+{
+ static const sal_uInt8 aData[] = {
+ 0x04, 0x00, 0x00, 'C', 'a', 'l', 'c', 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
+
+ sal_Size nDataSize = sizeof(aData);
+ for (sal_Size i = 0; i < nDataSize; ++i)
+ rStrm << aData[i];
+}
+
+// ============================================================================
+
+XclExpCodePage::XclExpCodePage() :
+ XclExpRecord(0x0042, 2)
+{
+}
+
+XclExpCodePage::~XclExpCodePage()
+{
+}
+
+void XclExpCodePage::WriteBody( XclExpStream& rStrm )
+{
+ // 0x04B0 : UTF-16 (BIFF8)
+ rStrm << static_cast<sal_uInt16>(0x04B0);
+}
+
+// ============================================================================
+
+XclExpDSF::XclExpDSF() :
+ XclExpRecord(0x0161, 2)
+{
+}
+
+XclExpDSF::~XclExpDSF()
+{
+}
+
+void XclExpDSF::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast<sal_uInt16>(0x0000);
+}
+
+// ============================================================================
+
+XclExpProt4Rev::XclExpProt4Rev() :
+ XclExpRecord(0x01AF, 2)
+{
+}
+
+XclExpProt4Rev::~XclExpProt4Rev()
+{
+}
+
+void XclExpProt4Rev::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast<sal_uInt16>(0x0000);
+}
+
+// ============================================================================
+
+XclExpProt4RevPass::XclExpProt4RevPass() :
+ XclExpRecord(0x01BC, 2)
+{
+}
+
+XclExpProt4RevPass::~XclExpProt4RevPass()
+{
+}
+
+void XclExpProt4RevPass::WriteBody( XclExpStream& rStrm )
+{
+ rStrm << static_cast<sal_uInt16>(0x0000);
+}
+
+// ============================================================================
+
+XclExpExcel9File::XclExpExcel9File() :
+ XclExpRecord(0x01C0, 0)
+{
+}
+
+XclExpExcel9File::~XclExpExcel9File()
+{
+}
+
+void XclExpExcel9File::WriteBody( XclExpStream& /*rStrm*/ )
+{
+}
+
+// ============================================================================
+
+static const sal_uInt8 nDataRecalcId[] = {
+ 0xC1, 0x01, 0x00, 0x00, 0x54, 0x8D, 0x01, 0x00
+};
+
+XclExpRecalcId::XclExpRecalcId() :
+ XclExpDummyRecord(0x01C1, nDataRecalcId, sizeof(nDataRecalcId))
+{
+}
+
+// ============================================================================
+
+static const sal_uInt8 nDataBookExt[] = {
+ 0x63, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02
+};
+
+XclExpBookExt::XclExpBookExt() :
+ XclExpDummyRecord(0x0863, nDataBookExt, sizeof(nDataBookExt))
+{
+}
+// ============================================================================
XclRefmode::XclRefmode( const ScDocument& rDoc ) :
XclExpBoolRecord( 0x000F, rDoc.GetAddressConvention() != formula::FormulaGrammar::CONV_XL_R1C1 )
diff --git a/sc/source/filter/xml/xmlbodyi.cxx b/sc/source/filter/xml/xmlbodyi.cxx
index fd9562a9b1fb..048f1ec0c549 100644
--- a/sc/source/filter/xml/xmlbodyi.cxx
+++ b/sc/source/filter/xml/xmlbodyi.cxx
@@ -52,6 +52,7 @@
#include "XMLTrackedChangesContext.hxx"
#include "XMLEmptyContext.hxx"
#include "scerrors.hxx"
+#include "tabprotection.hxx"
#include <xmloff/xmltkmap.hxx>
#include <xmloff/xmltoken.hxx>
@@ -62,7 +63,10 @@
#include <sal/types.h>
#include <tools/debug.hxx>
+#include <memory>
+
using rtl::OUString;
+
using namespace com::sun::star;
using namespace xmloff::token;
@@ -281,10 +285,17 @@ void ScXMLBodyContext::EndElement()
// #i37959# handle document protection after the sheet settings
if (bProtected)
{
+ ::std::auto_ptr<ScDocProtection> pProtection(new ScDocProtection);
+ pProtection->setProtected(true);
+
uno::Sequence<sal_Int8> aPass;
if (sPassword.getLength())
+ {
SvXMLUnitConverter::decodeBase64(aPass, sPassword);
- pDoc->SetDocProtection(bProtected, aPass);
+ pProtection->setPasswordHash(aPass, PASSHASH_OOO);
+ }
+
+ pDoc->SetDocProtection(pProtection.get());
}
}
GetScImport().UnlockSolarMutex();
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index 7d95e92c2891..bd7d37536795 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -69,6 +69,7 @@
#include "postit.hxx"
#include "externalrefmgr.hxx"
#include "editutil.hxx"
+#include "tabprotection.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmlnmspe.hxx>
@@ -1469,7 +1470,11 @@ void ScXMLExport::SetBodyAttributes()
{
AddAttribute(XML_NAMESPACE_TABLE, XML_STRUCTURE_PROTECTED, XML_TRUE);
rtl::OUStringBuffer aBuffer;
- SvXMLUnitConverter::encodeBase64(aBuffer, pDoc->GetDocPassword());
+ uno::Sequence<sal_Int8> aPassHash;
+ const ScDocProtection* p = pDoc->GetDocProtection();
+ if (p)
+ aPassHash = p->getPasswordHash(PASSHASH_OOO);
+ SvXMLUnitConverter::encodeBase64(aBuffer, aPassHash);
if (aBuffer.getLength())
AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear());
}
@@ -1543,7 +1548,11 @@ void ScXMLExport::_ExportContent()
AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE);
rtl::OUStringBuffer aBuffer;
if (pDoc)
- SvXMLUnitConverter::encodeBase64(aBuffer, pDoc->GetTabPassword(static_cast<SCTAB>(nTable)));
+ {
+ ScTableProtection* pProtect = pDoc->GetTabProtection(static_cast<SCTAB>(nTable));
+ if (pProtect)
+ SvXMLUnitConverter::encodeBase64(aBuffer, pProtect->getPasswordHash(PASSHASH_OOO));
+ }
if (aBuffer.getLength())
AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear());
}
diff --git a/sc/source/filter/xml/xmlsubti.cxx b/sc/source/filter/xml/xmlsubti.cxx
index 03437449ec61..787a38ef86bf 100644
--- a/sc/source/filter/xml/xmlsubti.cxx
+++ b/sc/source/filter/xml/xmlsubti.cxx
@@ -42,6 +42,7 @@
#include "docuno.hxx"
#include "cellsuno.hxx"
#include "XMLStylesImportHelper.hxx"
+#include "tabprotection.hxx"
#include <xmloff/xmltkmap.hxx>
#include <xmloff/nmspmap.hxx>
@@ -58,6 +59,10 @@
#include <com/sun/star/util/XProtectable.hpp>
#include <com/sun/star/sheet/XArrayFormulaRange.hpp>
+#include <memory>
+
+using ::std::auto_ptr;
+
//------------------------------------------------------------------
using namespace com::sun::star;
@@ -616,13 +621,10 @@ void ScMyTables::DeleteTable()
{
uno::Sequence<sal_Int8> aPass;
SvXMLUnitConverter::decodeBase64(aPass, sPassword);
- rImport.GetDocument()->SetTabProtection(static_cast<SCTAB>(nCurrentSheet), bProtection, aPass);
- /*uno::Reference <util::XProtectable> xProtectable(xCurrentSheet, uno::UNO_QUERY);
- if (xProtectable.is())
- {
- rtl::OUString sKey;
- xProtectable->protect(sKey);
- }*/
+ auto_ptr<ScTableProtection> pProtect(new ScTableProtection);
+ pProtect->setProtected(bProtection);
+ pProtect->setPasswordHash(aPass, PASSHASH_OOO);
+ rImport.GetDocument()->SetTabProtection(static_cast<SCTAB>(nCurrentSheet), pProtect.get());
}
rImport.UnlockSolarMutex();
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index 84b2330a533b..a9eb1a94b867 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -93,7 +93,12 @@
#include "editable.hxx"
#include "compiler.hxx"
#include "scui_def.hxx" //CHINA001
+#include "tabprotection.hxx"
+
+#include <memory>
+
using namespace com::sun::star;
+using ::com::sun::star::uno::Sequence;
// STATIC DATA -----------------------------------------------------------
@@ -3126,103 +3131,156 @@ BOOL ScDocFunc::RemovePageBreak( BOOL bColumn, const ScAddress& rPos,
//------------------------------------------------------------------------
-BOOL lcl_ValidPassword( ScDocument* pDoc, SCTAB nTab,
- const String& rPassword,
- uno::Sequence<sal_Int8>* pReturnOld = NULL )
+void ScDocFunc::ProtectSheet( SCTAB nTab, const ScTableProtection& rProtect )
{
- uno::Sequence<sal_Int8> aOldPassword;
- if ( nTab == TABLEID_DOC )
- {
- if (pDoc->IsDocProtected())
- aOldPassword = pDoc->GetDocPassword();
- }
- else
+ ScDocument* pDoc = rDocShell.GetDocument();
+
+ pDoc->SetTabProtection(nTab, &rProtect);
+ if (pDoc->IsUndoEnabled())
{
- if (pDoc->IsTabProtected(nTab))
- aOldPassword = pDoc->GetTabPassword(nTab);
- }
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ DBG_ASSERT(pProtect, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
+ if (pProtect)
+ {
+ ::std::auto_ptr<ScTableProtection> p(new ScTableProtection(*pProtect));
+ p->setProtected(true); // just in case ...
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoTabProtect(&rDocShell, nTab, p) );
- if (pReturnOld)
- *pReturnOld = aOldPassword;
+ // ownership of auto_ptr now transferred to ScUndoTabProtect.
+ }
+ }
- return ((aOldPassword.getLength() == 0) || SvPasswordHelper::CompareHashPassword(aOldPassword, rPassword));
+ rDocShell.PostPaintGridAll();
+ ScDocShellModificator aModificator(rDocShell);
+ aModificator.SetDocumentModified();
}
-BOOL ScDocFunc::Protect( SCTAB nTab, const String& rPassword, BOOL bApi )
+BOOL ScDocFunc::Protect( SCTAB nTab, const String& rPassword, BOOL /*bApi*/ )
{
- ScDocShellModificator aModificator( rDocShell );
-
ScDocument* pDoc = rDocShell.GetDocument();
- BOOL bUndo(pDoc->IsUndoEnabled());
- BOOL bOk = lcl_ValidPassword( pDoc, nTab, rPassword);
- if ( bOk )
- {
- uno::Sequence<sal_Int8> aPass;
- if (rPassword.Len())
- SvPasswordHelper::GetHashPassword(aPass, rPassword);
-
- if (bUndo)
+ if (nTab == TABLEID_DOC)
+ {
+ // document protection
+ ScDocProtection aProtection;
+ aProtection.setProtected(true);
+ aProtection.setPassword(rPassword);
+ pDoc->SetDocProtection(&aProtection);
+ if (pDoc->IsUndoEnabled())
{
- rDocShell.GetUndoManager()->AddUndoAction(
- new ScUndoProtect( &rDocShell, nTab, TRUE, aPass ) );
+ ScDocProtection* pProtect = pDoc->GetDocProtection();
+ DBG_ASSERT(pProtect, "ScDocFunc::Unprotect: ScDocProtection pointer is NULL!");
+ if (pProtect)
+ {
+ ::std::auto_ptr<ScDocProtection> p(new ScDocProtection(*pProtect));
+ p->setProtected(true); // just in case ...
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDocProtect(&rDocShell, p) );
+ // ownership of auto_ptr is transferred to ScUndoDocProtect.
+ }
}
-
- if ( nTab == TABLEID_DOC )
- pDoc->SetDocProtection( TRUE, aPass );
- else
- pDoc->SetTabProtection( nTab, TRUE, aPass );
-
- rDocShell.PostPaintGridAll();
- aModificator.SetDocumentModified();
}
- else if (!bApi)
+ else
{
- // different password was set before
-
-//! rDocShell.ErrorMessage(...);
+ // sheet protection
- InfoBox aBox( rDocShell.GetActiveDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD ) ) );
- aBox.Execute();
+ ScTableProtection aProtection;
+ aProtection.setProtected(true);
+ aProtection.setPassword(rPassword);
+ pDoc->SetTabProtection(nTab, &aProtection);
+ if (pDoc->IsUndoEnabled())
+ {
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ DBG_ASSERT(pProtect, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
+ if (pProtect)
+ {
+ ::std::auto_ptr<ScTableProtection> p(new ScTableProtection(*pProtect));
+ p->setProtected(true); // just in case ...
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoTabProtect(&rDocShell, nTab, p) );
+ // ownership of auto_ptr now transferred to ScUndoTabProtect.
+ }
+ }
}
- return bOk;
+ rDocShell.PostPaintGridAll();
+ ScDocShellModificator aModificator( rDocShell );
+ aModificator.SetDocumentModified();
+
+ return true;
}
BOOL ScDocFunc::Unprotect( SCTAB nTab, const String& rPassword, BOOL bApi )
{
- ScDocShellModificator aModificator( rDocShell );
-
ScDocument* pDoc = rDocShell.GetDocument();
- BOOL bUndo(pDoc->IsUndoEnabled());
- uno::Sequence<sal_Int8> aOldPassword;
- uno::Sequence<sal_Int8> aPass;
- BOOL bOk = lcl_ValidPassword( pDoc, nTab, rPassword, &aOldPassword );
- if ( bOk )
- {
- uno::Sequence<sal_Int8> aEmptyPass;
- if ( nTab == TABLEID_DOC )
- pDoc->SetDocProtection( FALSE, aEmptyPass );
- else
- pDoc->SetTabProtection( nTab, FALSE, aEmptyPass );
- if (bUndo)
+ if (nTab == TABLEID_DOC)
+ {
+ // document protection
+
+ ScDocProtection* pDocProtect = pDoc->GetDocProtection();
+ if (!pDocProtect || !pDocProtect->isProtected())
+ // already unprotected (should not happen)!
+ return true;
+
+ // save the protection state before unprotect (for undo).
+ ::std::auto_ptr<ScDocProtection> pProtectCopy(new ScDocProtection(*pDocProtect));
+
+ if (!pDocProtect->verifyPassword(rPassword))
{
- rDocShell.GetUndoManager()->AddUndoAction(
- new ScUndoProtect( &rDocShell, nTab, FALSE, aOldPassword ) );
+ if (!bApi)
+ {
+ InfoBox aBox( rDocShell.GetActiveDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD ) ) );
+ aBox.Execute();
+ }
+ return false;
}
- rDocShell.PostPaintGridAll();
- aModificator.SetDocumentModified();
+ pDoc->SetDocProtection(NULL);
+ if (pDoc->IsUndoEnabled())
+ {
+ pProtectCopy->setProtected(false);
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoDocProtect(&rDocShell, pProtectCopy) );
+ // ownership of auto_ptr now transferred to ScUndoDocProtect.
+ }
}
- else if (!bApi)
+ else
{
-//! rDocShell.ErrorMessage(...);
+ // sheet protection
+
+ ScTableProtection* pTabProtect = pDoc->GetTabProtection(nTab);
+ if (!pTabProtect || !pTabProtect->isProtected())
+ // already unprotected (should not happen)!
+ return true;
- InfoBox aBox( rDocShell.GetActiveDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD ) ) );
- aBox.Execute();
+ // save the protection state before unprotect (for undo).
+ ::std::auto_ptr<ScTableProtection> pProtectCopy(new ScTableProtection(*pTabProtect));
+ if (!pTabProtect->verifyPassword(rPassword))
+ {
+ if (!bApi)
+ {
+ InfoBox aBox( rDocShell.GetActiveDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD ) ) );
+ aBox.Execute();
+ }
+ return false;
+ }
+
+ pDoc->SetTabProtection(nTab, NULL);
+ if (pDoc->IsUndoEnabled())
+ {
+ pProtectCopy->setProtected(false);
+ rDocShell.GetUndoManager()->AddUndoAction(
+ new ScUndoTabProtect(&rDocShell, nTab, pProtectCopy) );
+ // ownership of auto_ptr now transferred to ScUndoTabProtect.
+ }
}
- return bOk;
+ rDocShell.PostPaintGridAll();
+ ScDocShellModificator aModificator( rDocShell );
+ aModificator.SetDocumentModified();
+
+ return true;
}
//------------------------------------------------------------------------
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index f8ce7cf8a70e..c62c2dc41fdf 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -79,11 +79,6 @@
#include <sot/formats.hxx>
#define SOT_FORMATSTR_ID_STARCALC_30 SOT_FORMATSTR_ID_STARCALC
-//REMOVE #ifndef SO2_DECL_SVSTORAGESTREAM_DEFINED
-//REMOVE #define SO2_DECL_SVSTORAGESTREAM_DEFINED
-//REMOVE SO2_DECL_REF(SotStorageStream)
-//REMOVE #endif
-
// INCLUDE ---------------------------------------------------------------
#include "cell.hxx"
@@ -97,7 +92,6 @@
#include "scresid.hxx"
#include "sc.hrc"
#include "globstr.hrc"
-//CHINA001 #include "tpstat.hxx"
#include "scerrors.hxx"
#include "brdcst.hxx"
#include "stlpool.hxx"
@@ -126,6 +120,7 @@
#include "cfgids.hxx"
#include "warnpassword.hxx"
#include "optsolver.hxx"
+#include "tabprotection.hxx"
#include "docsh.hxx"
#include "docshimp.hxx"
@@ -1327,6 +1322,16 @@ BOOL __EXPORT ScDocShell::SaveAs( SfxMedium& rMedium )
{
RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::SaveAs" );
+#if ENABLE_SHEET_PROTECTION
+ ScTabViewShell* pViewShell = GetBestViewShell();
+ if (pViewShell && ScPassHashHelper::needsPassHashRegen(aDocument, PASSHASH_OOO))
+ {
+ if (!pViewShell->ExecuteRetypePassDlg(PASSHASH_OOO))
+ // password re-type cancelled. Don't save the document.
+ return false;
+ }
+#endif
+
ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
PrepareSaveGuard aPrepareGuard( *this);
@@ -1792,7 +1797,6 @@ void ScDocShell::AsciiSave( SvStream& rStream, const ScImportOptions& rAsciiOpt
rStream.SetNumberFormatInt( nOldNumberFormatInt );
}
-
BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed )
{
RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ConvertTo" );
@@ -1846,15 +1850,39 @@ BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed )
aDocument.SetExtDocOptions( pExtDocOpt = new ScExtDocOptions );
pViewShell->GetViewData()->WriteExtOptions( *pExtDocOpt );
- /* #115980 #If the imported document contained an encrypted password -
- determine if we should save without it. */
- ScExtDocSettings& rDocSett = pExtDocOpt->GetDocSettings();
- if( rDocSett.mbEncrypted )
+#if ENABLE_SHEET_PROTECTION
+ bool bNeedRetypePassDlg = ScPassHashHelper::needsPassHashRegen(aDocument, PASSHASH_XL);
+ if (bNeedRetypePassDlg && !pViewShell->ExecuteRetypePassDlg(PASSHASH_XL))
+ {
+ SetError( ERRCODE_ABORT );
+ return false;
+ }
+#else
+
+ do
{
+ SfxItemSet* pSet = rMed.GetItemSet();
+ if (!pSet)
+ break;
+
+ const SfxPoolItem* pItem = NULL;
+ if (SFX_ITEM_SET != pSet->GetItemState(SID_PASSWORD, sal_True, &pItem))
+ // password is not set.
+ break;
+
+ /* #115980 #If the imported document contained an encrypted password -
+ determine if we should save without it. */
bDoSave = ScWarnPassword::WarningOnPassword( rMed );
- // #i42858# warn only on time
- rDocSett.mbEncrypted = false;
+
+ if (bDoSave)
+ {
+ // #i42858# warn only one time
+ pSet->ClearItem(SID_PASSWORD);
+ }
}
+ while (false);
+
+#endif
}
if( bDoSave )
diff --git a/sc/source/ui/docshell/docsh5.cxx b/sc/source/ui/docshell/docsh5.cxx
index d3b6bb55dcdd..3c3d00469970 100644
--- a/sc/source/ui/docshell/docsh5.cxx
+++ b/sc/source/ui/docshell/docsh5.cxx
@@ -827,7 +827,7 @@ BOOL ScDocShell::MoveTable( SCTAB nSrcTab, SCTAB nDestTab, BOOL bCopy, BOOL bRec
++nAdjSource; // new position of source table after CopyTab
if ( aDocument.IsTabProtected( nAdjSource ) )
- aDocument.SetTabProtection( nDestTab, TRUE, aDocument.GetTabPassword( nAdjSource ) );
+ aDocument.CopyTabProtection(nAdjSource, nDestTab);
if (bRecord)
{
diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx
index ecdaceb55294..a1df1fffc984 100644
--- a/sc/source/ui/inc/docfunc.hxx
+++ b/sc/source/ui/inc/docfunc.hxx
@@ -47,7 +47,7 @@ class ScRangeName;
class ScBaseCell;
class ScTokenArray;
struct ScTabOpParam;
-
+class ScTableProtection;
// ---------------------------------------------------------------------------
@@ -135,6 +135,8 @@ public:
BOOL RemovePageBreak( BOOL bColumn, const ScAddress& rPos,
BOOL bRecord, BOOL bSetModified, BOOL bApi );
+ void ProtectSheet( SCTAB nTab, const ScTableProtection& rProtect );
+
BOOL Protect( SCTAB nTab, const String& rPassword, BOOL bApi );
BOOL Unprotect( SCTAB nTab, const String& rPassword, BOOL bApi );
diff --git a/sc/source/ui/inc/protectiondlg.hrc b/sc/source/ui/inc/protectiondlg.hrc
new file mode 100644
index 000000000000..79285d3ce125
--- /dev/null
+++ b/sc/source/ui/inc/protectiondlg.hrc
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: protectiondlg.hrc,v $
+ * $Revision: 1.1.2.1 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <sc.hrc>
+
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 3
+
+#define BTN_PROTECT 4
+#define FT_PASSWORD1 5
+#define ED_PASSWORD1 6
+#define FT_PASSWORD2 7
+#define ED_PASSWORD2 8
+#define FL_OPTIONS 9
+#define FT_OPTIONS 10
+#define CLB_OPTIONS 11
+
+#define ST_SELECT_LOCKED_CELLS 50
+#define ST_SELECT_UNLOCKED_CELLS 51
diff --git a/sc/source/ui/inc/protectiondlg.hxx b/sc/source/ui/inc/protectiondlg.hxx
new file mode 100644
index 000000000000..36330498c941
--- /dev/null
+++ b/sc/source/ui/inc/protectiondlg.hxx
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: protectiondlg.hxx,v $
+ * $Revision: 1.1.2.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_UI_PROTECTION_DLG_HXX
+#define SC_UI_PROTECTION_DLG_HXX
+
+#include <vcl/dialog.hxx>
+#include <vcl/button.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/edit.hxx>
+#include <svx/checklbx.hxx>
+
+class Window;
+class ScTableProtection;
+
+class ScTableProtectionDlg : public ModalDialog
+{
+public:
+ explicit ScTableProtectionDlg(Window* pParent);
+ virtual ~ScTableProtectionDlg();
+
+ virtual short Execute();
+
+ void SetDialogData(const ScTableProtection& rData);
+
+ void WriteData(ScTableProtection& rData) const;
+
+private:
+ ScTableProtectionDlg(); // disabled
+
+ void Init();
+
+ void EnableOptionalWidgets(bool bEnable = true);
+
+ CheckBox maBtnProtect;
+
+ FixedText maPassword1Text;
+ Edit maPassword1Edit;
+ FixedText maPassword2Text;
+ Edit maPassword2Edit;
+
+ FixedLine maOptionsLine;
+ FixedText maOptionsText;
+ SvxCheckListBox maOptionsListBox;
+
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+ HelpButton maBtnHelp;
+
+ String maSelectLockedCells;
+ String maSelectUnlockedCells;
+
+ DECL_LINK( OKHdl, OKButton* );
+ DECL_LINK( CheckBoxHdl, CheckBox* );
+ DECL_LINK( PasswordModifyHdl, Edit* );
+};
+
+#endif
diff --git a/sc/source/ui/inc/retypepassdlg.hrc b/sc/source/ui/inc/retypepassdlg.hrc
new file mode 100644
index 000000000000..fe0f7e8a760a
--- /dev/null
+++ b/sc/source/ui/inc/retypepassdlg.hrc
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: retypepassdlg.hrc,v $
+ * $Revision: 1.1.2.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <sc.hrc>
+
+#define BTN_OK 1
+#define BTN_CANCEL 2
+#define BTN_HELP 3
+
+#define FT_DESC 10
+#define FL_DOCUMENT 11
+#define FT_DOCSTATUS 12
+#define BTN_RETYPE_DOC 13
+
+#define FL_SHEET 112
+
+#define FT_SHEETNAME1 113
+#define FT_SHEETSTATUS1 114
+#define BTN_RETYPE_SHEET1 115
+
+#define FT_SHEETNAME2 116
+#define FT_SHEETSTATUS2 117
+#define BTN_RETYPE_SHEET2 118
+
+#define FT_SHEETNAME3 119
+#define FT_SHEETSTATUS3 120
+#define BTN_RETYPE_SHEET3 121
+
+#define FT_SHEETNAME4 122
+#define FT_SHEETSTATUS4 123
+#define BTN_RETYPE_SHEET4 124
+
+#define SB_SCROLL 190
+
+#define STR_NOT_PROTECTED 200
+#define STR_NOT_PASS_PROTECTED 201
+#define STR_HASH_BAD 202
+#define STR_HASH_GOOD 203
+#define STR_HASH_REGENERATED 204
+
+#define FT_PASSWORD1 301
+#define ED_PASSWORD1 302
+#define FT_PASSWORD2 303
+#define ED_PASSWORD2 304
+#define BTN_MATCH_OLD_PASSWORD 305
+#define BTN_RETYPE_PASSWORD 306
+#define BTN_REMOVE_PASSWORD 307
diff --git a/sc/source/ui/inc/retypepassdlg.hxx b/sc/source/ui/inc/retypepassdlg.hxx
new file mode 100644
index 000000000000..657773d112f7
--- /dev/null
+++ b/sc/source/ui/inc/retypepassdlg.hxx
@@ -0,0 +1,177 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: retypepassdlg.hxx,v $
+ * $Revision: 1.1.2.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_UI_RETYPEPASS_DLG_HXX
+#define SC_UI_RETYPEPASS_DLG_HXX
+
+#include <vcl/dialog.hxx>
+#include <vcl/button.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/scrbar.hxx>
+#include <svx/checklbx.hxx>
+#include <svtools/stdctrl.hxx>
+
+#include "tabprotection.hxx"
+
+#include <boost/shared_ptr.hpp>
+
+class Window;
+class ScDocProtection;
+class ScTableProtection;
+class ScDocument;
+
+class ScRetypePassDlg : public ModalDialog
+{
+public:
+ typedef ::boost::shared_ptr<ScDocProtection> DocProtectionPtr;
+ typedef ::boost::shared_ptr<ScTableProtection> TabProtectionPtr;
+
+ explicit ScRetypePassDlg(Window* pParent);
+ virtual ~ScRetypePassDlg();
+
+ virtual short Execute();
+
+ void SetDataFromDocument(const ScDocument& rDoc);
+ void SetDesiredHash(ScPasswordHash eHash);
+
+ /** Write the new set of password data to the document instance to
+ overwrite the current ones. */
+ void WriteNewDataToDocument(ScDocument& rDoc) const;
+
+private:
+ ScRetypePassDlg(); // disabled
+
+ void Init();
+ void PopulateDialog();
+ void SetDocData();
+ void SetTableData(size_t nRowPos, SCTAB nTab);
+ void ResetTableRows();
+
+ /** Check the status of all hash values to see if it's okay to enable
+ the OK button. */
+ void CheckHashStatus();
+
+private:
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+ HelpButton maBtnHelp;
+
+ FixedInfo maTextDescription;
+
+ FixedLine maLineDocument;
+ FixedText maTextDocStatus;
+ PushButton maBtnRetypeDoc;
+
+ FixedLine maLineSheet;
+ FixedText maTextSheetName1;
+ FixedText maTextSheetStatus1;
+ PushButton maBtnRetypeSheet1;
+
+ FixedText maTextSheetName2;
+ FixedText maTextSheetStatus2;
+ PushButton maBtnRetypeSheet2;
+
+ FixedText maTextSheetName3;
+ FixedText maTextSheetStatus3;
+ PushButton maBtnRetypeSheet3;
+
+ FixedText maTextSheetName4;
+ FixedText maTextSheetStatus4;
+ PushButton maBtnRetypeSheet4;
+
+ ScrollBar maScrollBar;
+
+ String maTextNotProtected;
+ String maTextNotPassProtected;
+ String maTextHashBad;
+ String maTextHashGood;
+ String maTextHashRegen;
+
+ DECL_LINK( OKHdl, OKButton* );
+ DECL_LINK( RetypeBtnHdl, PushButton* );
+ DECL_LINK( ScrollHdl, ScrollBar* );
+
+ struct TableItem
+ {
+ String maName;
+ TabProtectionPtr mpProtect;
+ };
+ ::std::vector<TableItem> maTableItems;
+
+ DocProtectionPtr mpDocItem;
+ size_t mnCurScrollPos;
+ ScPasswordHash meDesiredHash;
+};
+
+// ============================================================================
+
+class ScRetypePassInputDlg : public ModalDialog
+{
+public:
+ explicit ScRetypePassInputDlg(Window* pParent, ScPassHashProtectable* pProtected);
+ virtual ~ScRetypePassInputDlg();
+
+ virtual short Execute();
+
+ bool IsRemovePassword() const;
+ String GetNewPassword() const;
+
+private:
+ ScRetypePassInputDlg(); // disabled
+
+ void Init();
+ void CheckPasswordInput();
+
+private:
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+ HelpButton maBtnHelp;
+
+ RadioButton maBtnRetypePassword;
+
+ FixedText maPassword1Text;
+ Edit maPassword1Edit;
+ FixedText maPassword2Text;
+ Edit maPassword2Edit;
+
+ CheckBox maBtnMatchOldPass;
+
+ RadioButton maBtnRemovePassword;
+
+ DECL_LINK( OKHdl, OKButton* );
+ DECL_LINK( RadioBtnHdl, RadioButton* );
+ DECL_LINK( CheckBoxHdl, CheckBox* );
+ DECL_LINK( PasswordModifyHdl, Edit* );
+
+ ScPassHashProtectable* mpProtected;
+};
+
+#endif
diff --git a/sc/source/ui/inc/tabvwsh.hxx b/sc/source/ui/inc/tabvwsh.hxx
index 13cd49df6879..10224536bf0b 100644
--- a/sc/source/ui/inc/tabvwsh.hxx
+++ b/sc/source/ui/inc/tabvwsh.hxx
@@ -39,6 +39,7 @@
#include "target.hxx"
#include "rangelst.hxx" // ScRangeListRef
#include "shellids.hxx"
+#include "tabprotection.hxx" // for ScPasswordHash
class FmFormShell;
class SbxObject;
@@ -430,6 +431,8 @@ public:
void BroadcastAccessibility( const SfxHint &rHint );
BOOL HasAccessibilityObjects();
+ bool ExecuteRetypePassDlg(ScPasswordHash eDesiredHash);
+
using ScTabView::ShowCursor;
};
diff --git a/sc/source/ui/inc/undotab.hxx b/sc/source/ui/inc/undotab.hxx
index ff76ebd16702..1eadf24041db 100644
--- a/sc/source/ui/inc/undotab.hxx
+++ b/sc/source/ui/inc/undotab.hxx
@@ -52,11 +52,15 @@
#include <com/sun/star/uno/Sequence.hxx>
+#include <memory>
+
class ScDocShell;
class ScDocument;
class SdrUndoAction;
class ScPrintRangeSaver;
class SdrObject;
+class ScDocProtection;
+class ScTableProtection;
//----------------------------------------------------------------------------
@@ -335,14 +339,15 @@ private:
void DoChange( BOOL bShow ) const;
};
+// ============================================================================
-class ScUndoProtect : public ScSimpleUndo
+/** This class implements undo & redo of document protect & unprotect
+ operations. */
+class ScUndoDocProtect : public ScSimpleUndo
{
public:
- TYPEINFO();
- ScUndoProtect( ScDocShell* pShell, SCTAB nNewTab,
- BOOL bNewProtect, const com::sun::star::uno::Sequence<sal_Int8>& rNewPassword );
- virtual ~ScUndoProtect();
+ ScUndoDocProtect(ScDocShell* pShell, ::std::auto_ptr<ScDocProtection> pProtectSettings);
+ virtual ~ScUndoDocProtect();
virtual void Undo();
virtual void Redo();
@@ -352,11 +357,34 @@ public:
virtual String GetComment() const;
private:
- SCTAB nTab;
- BOOL bProtect;
- com::sun::star::uno::Sequence<sal_Int8> aPassword;
+ ::std::auto_ptr<ScDocProtection> mpProtectSettings;
+
+ void DoProtect(bool bProtect);
+};
+
+// ============================================================================
+
+/** This class implements undo & redo of both protect and unprotect of
+ sheet. */
+class ScUndoTabProtect : public ScSimpleUndo
+{
+public:
+ ScUndoTabProtect(ScDocShell* pShell, SCTAB nTab,
+ ::std::auto_ptr<ScTableProtection> pProtectSettings);
+ virtual ~ScUndoTabProtect();
+
+ virtual void Undo();
+ virtual void Redo();
+ virtual void Repeat(SfxRepeatTarget& rTarget);
+ virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const;
+
+ virtual String GetComment() const;
+
+private:
+ SCTAB mnTab;
+ ::std::auto_ptr<ScTableProtection> mpProtectSettings;
- void DoProtect( BOOL bDo );
+ void DoProtect(bool bProtect);
};
diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx
index 0759d1fe2893..a5b044ce4f32 100644
--- a/sc/source/ui/inc/viewfunc.hxx
+++ b/sc/source/ui/inc/viewfunc.hxx
@@ -69,6 +69,7 @@ class Exchange;
class ScRangeList;
class SvxHyperlinkItem;
class ScTransferObj;
+class ScTableProtection;
namespace com { namespace sun { namespace star { namespace datatransfer { class XTransferable; } } } }
@@ -199,6 +200,8 @@ public:
void ChangeIndent( BOOL bIncrement );
+ void ProtectSheet( SCTAB nTab, const ScTableProtection& rProtect );
+
void Protect( SCTAB nTab, const String& rPassword );
BOOL Unprotect( SCTAB nTab, const String& rPassword );
diff --git a/sc/source/ui/miscdlgs/makefile.mk b/sc/source/ui/miscdlgs/makefile.mk
index 988b288da625..66e1f33618e2 100644
--- a/sc/source/ui/miscdlgs/makefile.mk
+++ b/sc/source/ui/miscdlgs/makefile.mk
@@ -78,7 +78,9 @@ SLOFILES = \
$(SLO)$/warnbox.obj \
$(SLO)$/scuiautofmt.obj \
$(SLO)$/conflictsdlg.obj \
- $(SLO)$/sharedocdlg.obj
+ $(SLO)$/sharedocdlg.obj \
+ $(SLO)$/protectiondlg.obj \
+ $(SLO)$/retypepassdlg.obj
EXCEPTIONSFILES = \
$(SLO)$/acredlin.obj \
@@ -87,7 +89,9 @@ EXCEPTIONSFILES = \
$(SLO)$/optsolver.obj \
$(SLO)$/solveroptions.obj \
$(SLO)$/crnrdlg.obj \
- $(SLO)$/solverutil.obj
+ $(SLO)$/solverutil.obj \
+ $(SLO)$/protectiondlg.obj \
+ $(SLO)$/retypepassdlg.obj
SRS1NAME=$(TARGET)
SRC1FILES = \
@@ -96,7 +100,9 @@ SRC1FILES = \
highred.src \
linkarea.src \
conflictsdlg.src \
- sharedocdlg.src
+ sharedocdlg.src \
+ protectiondlg.src \
+ retypepassdlg.src
LIB1TARGET = $(SLB)$/$(TARGET).lib
@@ -116,7 +122,9 @@ LIB1OBJFILES = \
$(SLO)$/redcom.obj \
$(SLO)$/warnbox.obj \
$(SLO)$/conflictsdlg.obj \
- $(SLO)$/sharedocdlg.obj
+ $(SLO)$/sharedocdlg.obj \
+ $(SLO)$/protectiondlg.obj \
+ $(SLO)$/retypepassdlg.obj
# --- Tagets -------------------------------------------------------
diff --git a/sc/source/ui/miscdlgs/protectiondlg.cxx b/sc/source/ui/miscdlgs/protectiondlg.cxx
new file mode 100644
index 000000000000..a5116ef61d66
--- /dev/null
+++ b/sc/source/ui/miscdlgs/protectiondlg.cxx
@@ -0,0 +1,164 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: protectiondlg.cxx,v $
+ * $Revision: 1.1.2.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "protectiondlg.hxx"
+#include "protectiondlg.hrc"
+#include "scresid.hxx"
+#include "tabprotection.hxx"
+
+#include <vcl/msgbox.hxx>
+
+
+// The order must match that of the list box.
+static const ScTableProtection::Option aOptions[] = {
+ ScTableProtection::SELECT_LOCKED_CELLS,
+ ScTableProtection::SELECT_UNLOCKED_CELLS,
+};
+static const USHORT nOptionCount = sizeof(aOptions)/sizeof(aOptions[0]);
+
+
+ScTableProtectionDlg::ScTableProtectionDlg(Window* pParent) :
+ ModalDialog(pParent, ScResId(RID_SCDLG_TABPROTECTION)),
+
+ maBtnProtect (this, ScResId(BTN_PROTECT)),
+ maPassword1Text (this, ScResId(FT_PASSWORD1)),
+ maPassword1Edit (this, ScResId(ED_PASSWORD1)),
+ maPassword2Text (this, ScResId(FT_PASSWORD2)),
+ maPassword2Edit (this, ScResId(ED_PASSWORD2)),
+ maOptionsLine (this, ScResId(FL_OPTIONS)),
+ maOptionsText (this, ScResId(FT_OPTIONS)),
+ maOptionsListBox(this, ScResId(CLB_OPTIONS)),
+
+ maBtnOk (this, ScResId(BTN_OK)),
+ maBtnCancel (this, ScResId(BTN_CANCEL)),
+ maBtnHelp (this, ScResId(BTN_HELP)),
+
+ maSelectLockedCells(ScResId(ST_SELECT_LOCKED_CELLS)),
+ maSelectUnlockedCells(ScResId(ST_SELECT_UNLOCKED_CELLS))
+{
+ Init();
+ FreeResource();
+}
+
+ScTableProtectionDlg::~ScTableProtectionDlg()
+{
+}
+
+short ScTableProtectionDlg::Execute()
+{
+ return ModalDialog::Execute();
+}
+
+void ScTableProtectionDlg::SetDialogData(const ScTableProtection& rData)
+{
+ for (USHORT i = 0; i < nOptionCount; ++i)
+ maOptionsListBox.CheckEntryPos(i, rData.isOptionEnabled(aOptions[i]));
+}
+
+void ScTableProtectionDlg::WriteData(ScTableProtection& rData) const
+{
+ rData.setProtected(maBtnProtect.IsChecked());
+
+ // We assume that the two password texts match.
+ rData.setPassword(maPassword1Edit.GetText());
+
+ for (USHORT i = 0; i < nOptionCount; ++i)
+ rData.setOption(aOptions[i], maOptionsListBox.IsChecked(i));
+}
+
+void ScTableProtectionDlg::Init()
+{
+ Link aLink = LINK( this, ScTableProtectionDlg, CheckBoxHdl );
+ maBtnProtect.SetClickHdl(aLink);
+
+ aLink = LINK( this, ScTableProtectionDlg, OKHdl );
+ maBtnOk.SetClickHdl(aLink);
+
+ aLink = LINK( this, ScTableProtectionDlg, PasswordModifyHdl );
+ maPassword1Edit.SetModifyHdl(aLink);
+ maPassword2Edit.SetModifyHdl(aLink);
+
+ maOptionsListBox.SetUpdateMode(false);
+ maOptionsListBox.Clear();
+
+ maOptionsListBox.InsertEntry(maSelectLockedCells);
+ maOptionsListBox.InsertEntry(maSelectUnlockedCells);
+
+ maOptionsListBox.CheckEntryPos(0, true);
+ maOptionsListBox.CheckEntryPos(1, true);
+
+ maOptionsListBox.SetUpdateMode(true);
+
+ // Set the default state of the dialog.
+ maBtnProtect.Check(true);
+ maPassword1Edit.GrabFocus();
+}
+
+void ScTableProtectionDlg::EnableOptionalWidgets(bool bEnable)
+{
+ maPassword1Text.Enable(bEnable);
+ maPassword1Edit.Enable(bEnable);
+ maPassword2Text.Enable(bEnable);
+ maPassword2Edit.Enable(bEnable);
+ maOptionsLine.Enable(bEnable);
+ maOptionsText.Enable(bEnable);
+
+ maOptionsListBox.Enable(bEnable);
+ maOptionsListBox.Invalidate();
+}
+
+IMPL_LINK( ScTableProtectionDlg, CheckBoxHdl, CheckBox*, pBtn )
+{
+ if (pBtn == &maBtnProtect)
+ {
+ bool bChecked = maBtnProtect.IsChecked();
+ EnableOptionalWidgets(bChecked);
+ maBtnOk.Enable(bChecked);
+ }
+
+ return 0;
+}
+
+IMPL_LINK( ScTableProtectionDlg, OKHdl, OKButton*, EMPTYARG )
+{
+ EndDialog(RET_OK);
+ return 0;
+}
+
+IMPL_LINK( ScTableProtectionDlg, PasswordModifyHdl, Edit*, EMPTYARG )
+{
+ String aPass1 = maPassword1Edit.GetText();
+ String aPass2 = maPassword2Edit.GetText();
+ maBtnOk.Enable(aPass1.Equals(aPass2));
+ return 0;
+}
diff --git a/sc/source/ui/miscdlgs/protectiondlg.src b/sc/source/ui/miscdlgs/protectiondlg.src
new file mode 100644
index 000000000000..4919f93ca6f4
--- /dev/null
+++ b/sc/source/ui/miscdlgs/protectiondlg.src
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: protectiondlg.src,v $
+ * $Revision: 1.1.2.6 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "protectiondlg.hrc"
+
+ModalDialog RID_SCDLG_TABPROTECTION
+{
+ Text [ en-US ] = "Protect Sheet" ;
+ Size = MAP_APPFONT ( 220 , 135 ) ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 164 , 6 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 164 , 23 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 164 , 43 ) ;
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ };
+
+ CheckBox BTN_PROTECT
+ {
+ Pos = MAP_APPFONT ( 6 , 6 ) ;
+ Size = MAP_APPFONT ( 150 , 10 );
+
+ Text [ en-US ] = "P~rotect this sheet and the contents of locked cells" ;
+ };
+
+ FixedText FT_PASSWORD1
+ {
+ Pos = MAP_APPFONT ( 11, 23 );
+ Size = MAP_APPFONT ( 42, 10 );
+
+ Text [ en-US ] = "~Password" ;
+ };
+
+ Edit ED_PASSWORD1
+ {
+ Border = TRUE;
+ PassWord = TRUE;
+ Pos = MAP_APPFONT ( 56, 22 );
+ Size = MAP_APPFONT ( 75, 12 );
+ };
+
+ FixedText FT_PASSWORD2
+ {
+ Pos = MAP_APPFONT ( 11, 40 );
+ Size = MAP_APPFONT ( 42, 10 );
+
+ Text [ en-US ] = "~Confirm" ;
+ };
+
+ Edit ED_PASSWORD2
+ {
+ Border = TRUE;
+ PassWord = TRUE;
+ Pos = MAP_APPFONT ( 56, 39 );
+ Size = MAP_APPFONT ( 75, 12 );
+ };
+
+ FixedLine FL_OPTIONS
+ {
+ Pos = MAP_APPFONT ( 6, 60 );
+ Size = MAP_APPFONT ( 150, 8 );
+
+ Text [ en-US ] = "Options";
+ };
+
+ FixedText FT_OPTIONS
+ {
+ Pos = MAP_APPFONT ( 11, 74 );
+ Size = MAP_APPFONT ( 140, 8 );
+
+ Text [ en-US ] = "Allow all users of this sheet to:";
+ };
+
+ Control CLB_OPTIONS
+ {
+ Pos = MAP_APPFONT ( 11, 85 );
+ Size = MAP_APPFONT ( 140, 40 );
+ Border = TRUE ;
+ TabStop = TRUE ;
+ };
+
+ String ST_SELECT_LOCKED_CELLS
+ {
+ Text [ en-US ] = "Select locked cells";
+ };
+
+ String ST_SELECT_UNLOCKED_CELLS
+ {
+ Text [ en-US ] = "Select unlocked cells";
+ };
+};
diff --git a/sc/source/ui/miscdlgs/retypepassdlg.cxx b/sc/source/ui/miscdlgs/retypepassdlg.cxx
new file mode 100644
index 000000000000..84a008f68f5f
--- /dev/null
+++ b/sc/source/ui/miscdlgs/retypepassdlg.cxx
@@ -0,0 +1,547 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: retypepassdlg.cxx,v $
+ * $Revision: 1.1.2.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 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;
+}
diff --git a/sc/source/ui/miscdlgs/retypepassdlg.src b/sc/source/ui/miscdlgs/retypepassdlg.src
new file mode 100644
index 000000000000..87d436881f69
--- /dev/null
+++ b/sc/source/ui/miscdlgs/retypepassdlg.src
@@ -0,0 +1,316 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: retypepassdlg.src,v $
+ * $Revision: 1.1.2.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "retypepassdlg.hrc"
+
+
+ModalDialog RID_SCDLG_RETYPEPASS
+{
+ Text [ en-US ] = "Re-type Password" ;
+ Size = MAP_APPFONT ( 260 , 165 ) ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 204, 6 ) ;
+ Size = MAP_APPFONT ( 50, 14 ) ;
+ DefButton = TRUE ;
+ };
+
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 204, 23 ) ;
+ Size = MAP_APPFONT ( 50, 14 ) ;
+ };
+
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 204, 43 ) ;
+ Size = MAP_APPFONT ( 50, 14 ) ;
+ };
+
+ FixedText FT_DESC
+ {
+ Pos = MAP_APPFONT ( 6, 6 ) ;
+ Size = MAP_APPFONT ( 190, 36 );
+
+ WordBreak = TRUE ;
+
+ Text [ en-US ] = "The document you are about to export has one or more protected items with password that cannot be exported. Please re-type your password to be able to export your document." ;
+ };
+
+ FixedLine FL_DOCUMENT
+ {
+ Pos = MAP_APPFONT ( 6, 48 );
+ Size = MAP_APPFONT ( 190, 8 );
+
+ Text [ en-US ] = "Document protection" ;
+ };
+
+ FixedText FT_DOCSTATUS
+ {
+ Pos = MAP_APPFONT ( 10, 62 );
+ Size = MAP_APPFONT ( 140, 8 );
+
+ Text [ en-US ] = "Status unknown" ;
+ };
+
+ PushButton BTN_RETYPE_DOC
+ {
+ Pos = MAP_APPFONT ( 158, 59 );
+ Size = MAP_APPFONT ( 30, 14 );
+
+ Text [ en-US ] = "Re-type" ;
+ };
+
+ FixedLine FL_SHEET
+ {
+ Pos = MAP_APPFONT ( 6, 83 );
+ Size = MAP_APPFONT ( 190, 8 );
+
+ Text [ en-US ] = "Sheet protection" ;
+ };
+
+ FixedText FT_SHEETNAME1
+ {
+ Pos = MAP_APPFONT ( 10, 97 );
+ Size = MAP_APPFONT ( 68, 8 );
+
+ Text [ en-US ] = "Sheet1 has a really long name" ;
+ };
+
+ FixedText FT_SHEETSTATUS1
+ {
+ Pos = MAP_APPFONT ( 82, 97 );
+ Size = MAP_APPFONT ( 72, 8 );
+
+ Text [ en-US ] = "Status unknown" ;
+ };
+
+ PushButton BTN_RETYPE_SHEET1
+ {
+ Pos = MAP_APPFONT ( 158, 94 );
+ Size = MAP_APPFONT ( 30, 14 );
+
+ Text [ en-US ] = "Re-type" ;
+ };
+
+ FixedText FT_SHEETNAME2
+ {
+ Pos = MAP_APPFONT ( 10, 113 );
+ Size = MAP_APPFONT ( 68, 8 );
+
+ Text [ en-US ] = "Sheet2" ;
+ };
+
+ FixedText FT_SHEETSTATUS2
+ {
+ Pos = MAP_APPFONT ( 82, 113 );
+ Size = MAP_APPFONT ( 72, 8 );
+
+ Text [ en-US ] = "Status unknown" ;
+ };
+
+ PushButton BTN_RETYPE_SHEET2
+ {
+ Pos = MAP_APPFONT ( 158, 110 );
+ Size = MAP_APPFONT ( 30, 14 );
+
+ Text [ en-US ] = "Re-type" ;
+ };
+
+ FixedText FT_SHEETNAME3
+ {
+ Pos = MAP_APPFONT ( 10, 129 );
+ Size = MAP_APPFONT ( 68, 8 );
+
+ Text [ en-US ] = "Sheet3" ;
+ };
+
+ FixedText FT_SHEETSTATUS3
+ {
+ Pos = MAP_APPFONT ( 82, 129 );
+ Size = MAP_APPFONT ( 72, 8 );
+
+ Text [ en-US ] = "Status unknown" ;
+ };
+
+ PushButton BTN_RETYPE_SHEET3
+ {
+ Pos = MAP_APPFONT ( 158, 126 );
+ Size = MAP_APPFONT ( 30, 14 );
+
+ Text [ en-US ] = "Re-type" ;
+ };
+
+ FixedText FT_SHEETNAME4
+ {
+ Pos = MAP_APPFONT ( 10, 145 );
+ Size = MAP_APPFONT ( 68, 8 );
+
+ Text [ en-US ] = "Sheet4" ;
+ };
+
+ FixedText FT_SHEETSTATUS4
+ {
+ Pos = MAP_APPFONT ( 82, 145 );
+ Size = MAP_APPFONT ( 72, 8 );
+
+ Text [ en-US ] = "Status unknown" ;
+ };
+
+ PushButton BTN_RETYPE_SHEET4
+ {
+ Pos = MAP_APPFONT ( 158, 142 );
+ Size = MAP_APPFONT ( 30, 14 );
+
+ Text [ en-US ] = "Re-type" ;
+ };
+
+ ScrollBar SB_SCROLL
+ {
+ Pos = MAP_APPFONT ( 190, 94 ) ;
+ Size = MAP_APPFONT ( 8, 61 ) ;
+ VScroll = TRUE ;
+ };
+
+ String STR_NOT_PROTECTED
+ {
+ Text [ en-US ] = "Not protected" ;
+ };
+
+ String STR_NOT_PASS_PROTECTED
+ {
+ Text [ en-US ] = "Not password-protected" ;
+ };
+
+ String STR_HASH_BAD
+ {
+ Text [ en-US ] = "Hash incompatible" ;
+ };
+
+ String STR_HASH_GOOD
+ {
+ Text [ en-US ] = "Hash compatible" ;
+ };
+
+ String STR_HASH_REGENERATED
+ {
+ Text [ en-US ] = "Hash re-generated" ;
+ };
+};
+
+// ----------------------------------------------------------------------------
+
+ModalDialog RID_SCDLG_RETYPEPASS_INPUT
+{
+ Text [ en-US ] = "Re-type Password" ;
+ Size = MAP_APPFONT ( 230 , 110 ) ;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 174, 6 ) ;
+ Size = MAP_APPFONT ( 50, 14 ) ;
+ DefButton = TRUE ;
+ };
+
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 174, 23 ) ;
+ Size = MAP_APPFONT ( 50, 14 ) ;
+ };
+
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 174, 43 ) ;
+ Size = MAP_APPFONT ( 50, 14 ) ;
+ };
+
+ RadioButton BTN_RETYPE_PASSWORD
+ {
+ Pos = MAP_APPFONT ( 11, 10 );
+ Size = MAP_APPFONT ( 150, 10 );
+
+ Text [ en-US ] = "Re-type password" ;
+ };
+
+ FixedText FT_PASSWORD1
+ {
+ Pos = MAP_APPFONT ( 20, 30 );
+ Size = MAP_APPFONT ( 42, 10 );
+
+ Text [ en-US ] = "~Password" ;
+ };
+
+ Edit ED_PASSWORD1
+ {
+ Border = TRUE;
+ PassWord = TRUE;
+ Pos = MAP_APPFONT ( 65, 29 );
+ Size = MAP_APPFONT ( 75, 12 );
+ };
+
+ FixedText FT_PASSWORD2
+ {
+ Pos = MAP_APPFONT ( 20, 45 );
+ Size = MAP_APPFONT ( 42, 10 );
+
+ Text [ en-US ] = "~Confirm" ;
+ };
+
+ Edit ED_PASSWORD2
+ {
+ Border = TRUE;
+ PassWord = TRUE;
+ Pos = MAP_APPFONT ( 65, 44 );
+ Size = MAP_APPFONT ( 75, 12 );
+ };
+
+ CheckBox BTN_MATCH_OLD_PASSWORD
+ {
+ Pos = MAP_APPFONT ( 20, 65 );
+ Size = MAP_APPFONT ( 150, 10 );
+
+ Text [ en-US ] = "New password must match the original password." ;
+ };
+
+ RadioButton BTN_REMOVE_PASSWORD
+ {
+ Pos = MAP_APPFONT ( 11, 90 );
+ Size = MAP_APPFONT ( 150, 10 );
+
+ Text [ en-US ] = "Remove password from this protected item." ;
+ };
+};
+
+
diff --git a/sc/source/ui/undo/undotab.cxx b/sc/source/ui/undo/undotab.cxx
index d3ff10783c27..abd6f815abf9 100644
--- a/sc/source/ui/undo/undotab.cxx
+++ b/sc/source/ui/undo/undotab.cxx
@@ -61,6 +61,7 @@
#include "prnsave.hxx"
#include "printfun.hxx"
#include "chgtrack.hxx"
+#include "tabprotection.hxx"
// for ScUndoRenameObject - might me moved to another file later
#include <svx/svditer.hxx>
@@ -72,6 +73,8 @@
extern BOOL bDrawIsInUndo; //! irgendwo als Member !!!
using namespace com::sun::star;
+using ::com::sun::star::uno::Sequence;
+using ::std::auto_ptr;
// STATIC DATA -----------------------------------------------------------
@@ -85,7 +88,6 @@ TYPEINIT1(ScUndoMakeScenario, SfxUndoAction);
TYPEINIT1(ScUndoImportTab, SfxUndoAction);
TYPEINIT1(ScUndoRemoveLink, SfxUndoAction);
TYPEINIT1(ScUndoShowHideTab, SfxUndoAction);
-TYPEINIT1(ScUndoProtect, SfxUndoAction);
TYPEINIT1(ScUndoPrintRange, SfxUndoAction);
TYPEINIT1(ScUndoScenarioFlags, SfxUndoAction);
TYPEINIT1(ScUndoRenameObject, SfxUndoAction);
@@ -112,12 +114,12 @@ ScUndoInsertTab::ScUndoInsertTab( ScDocShell* pNewDocShell,
SetChangeTrack();
}
-__EXPORT ScUndoInsertTab::~ScUndoInsertTab()
+ScUndoInsertTab::~ScUndoInsertTab()
{
DeleteSdrUndoAction( pDrawUndo );
}
-String __EXPORT ScUndoInsertTab::GetComment() const
+String ScUndoInsertTab::GetComment() const
{
if (bAppend)
return ScGlobal::GetRscString( STR_UNDO_APPEND_TAB );
@@ -138,7 +140,7 @@ void ScUndoInsertTab::SetChangeTrack()
nEndChangeAction = 0;
}
-void __EXPORT ScUndoInsertTab::Undo()
+void ScUndoInsertTab::Undo()
{
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
pViewShell->SetTabNo(nTab);
@@ -159,7 +161,7 @@ void __EXPORT ScUndoInsertTab::Undo()
pDocShell->Broadcast( SfxSimpleHint( SC_HINT_FORCESETTAB ) );
}
-void __EXPORT ScUndoInsertTab::Redo()
+void ScUndoInsertTab::Redo()
{
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
@@ -180,14 +182,14 @@ void __EXPORT ScUndoInsertTab::Redo()
SetChangeTrack();
}
-void __EXPORT ScUndoInsertTab::Repeat(SfxRepeatTarget& rTarget)
+void ScUndoInsertTab::Repeat(SfxRepeatTarget& rTarget)
{
if (rTarget.ISA(ScTabViewTarget))
((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData()->GetDispatcher().
Execute(FID_INS_TABLE, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
}
-BOOL __EXPORT ScUndoInsertTab::CanRepeat(SfxRepeatTarget& rTarget) const
+BOOL ScUndoInsertTab::CanRepeat(SfxRepeatTarget& rTarget) const
{
return (rTarget.ISA(ScTabViewTarget));
}
@@ -211,7 +213,7 @@ ScUndoInsertTables::ScUndoInsertTables( ScDocShell* pNewDocShell,
SetChangeTrack();
}
-__EXPORT ScUndoInsertTables::~ScUndoInsertTables()
+ScUndoInsertTables::~ScUndoInsertTables()
{
String *pStr=NULL;
if(pNameList!=NULL)
@@ -227,7 +229,7 @@ __EXPORT ScUndoInsertTables::~ScUndoInsertTables()
DeleteSdrUndoAction( pDrawUndo );
}
-String __EXPORT ScUndoInsertTables::GetComment() const
+String ScUndoInsertTables::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_INSERT_TAB );
}
@@ -252,7 +254,7 @@ void ScUndoInsertTables::SetChangeTrack()
nStartChangeAction = nEndChangeAction = 0;
}
-void __EXPORT ScUndoInsertTables::Undo()
+void ScUndoInsertTables::Undo()
{
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
pViewShell->SetTabNo(nTab);
@@ -282,7 +284,7 @@ void __EXPORT ScUndoInsertTables::Undo()
pDocShell->Broadcast( SfxSimpleHint( SC_HINT_FORCESETTAB ) );
}
-void __EXPORT ScUndoInsertTables::Redo()
+void ScUndoInsertTables::Redo()
{
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
@@ -299,14 +301,14 @@ void __EXPORT ScUndoInsertTables::Redo()
SetChangeTrack();
}
-void __EXPORT ScUndoInsertTables::Repeat(SfxRepeatTarget& rTarget)
+void ScUndoInsertTables::Repeat(SfxRepeatTarget& rTarget)
{
if (rTarget.ISA(ScTabViewTarget))
((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData()->GetDispatcher().
Execute(FID_INS_TABLE, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
}
-BOOL __EXPORT ScUndoInsertTables::CanRepeat(SfxRepeatTarget& rTarget) const
+BOOL ScUndoInsertTables::CanRepeat(SfxRepeatTarget& rTarget) const
{
return (rTarget.ISA(ScTabViewTarget));
}
@@ -327,12 +329,12 @@ ScUndoDeleteTab::ScUndoDeleteTab( ScDocShell* pNewDocShell,const SvShorts &aTab,
SetChangeTrack();
}
-__EXPORT ScUndoDeleteTab::~ScUndoDeleteTab()
+ScUndoDeleteTab::~ScUndoDeleteTab()
{
theTabs.Remove(0,theTabs.Count());
}
-String __EXPORT ScUndoDeleteTab::GetComment() const
+String ScUndoDeleteTab::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_DELETE_TAB );
}
@@ -366,7 +368,7 @@ SCTAB lcl_GetVisibleTabBefore( ScDocument& rDoc, SCTAB nTab )
return nTab;
}
-void __EXPORT ScUndoDeleteTab::Undo()
+void ScUndoDeleteTab::Undo()
{
BeginUndo();
int i=0;
@@ -414,7 +416,7 @@ void __EXPORT ScUndoDeleteTab::Undo()
pDoc->SetVisible( nTab, pRefUndoDoc->IsVisible( nTab ) );
if ( pRefUndoDoc->IsTabProtected( nTab ) )
- pDoc->SetTabProtection( nTab, TRUE, pRefUndoDoc->GetTabPassword( nTab ) );
+ pDoc->SetTabProtection(nTab, pRefUndoDoc->GetTabProtection(nTab));
// Drawing-Layer passiert beim MoveUndo::EndUndo
// pDoc->TransferDrawPage(pRefUndoDoc, nTab,nTab);
@@ -450,7 +452,7 @@ void __EXPORT ScUndoDeleteTab::Undo()
// EndUndo();
}
-void __EXPORT ScUndoDeleteTab::Redo()
+void ScUndoDeleteTab::Redo()
{
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
pViewShell->SetTabNo( lcl_GetVisibleTabBefore( *pDocShell->GetDocument(), theTabs[0] ) );
@@ -469,7 +471,7 @@ void __EXPORT ScUndoDeleteTab::Redo()
pDocShell->Broadcast( SfxSimpleHint( SC_HINT_FORCESETTAB ) );
}
-void __EXPORT ScUndoDeleteTab::Repeat(SfxRepeatTarget& rTarget)
+void ScUndoDeleteTab::Repeat(SfxRepeatTarget& rTarget)
{
if (rTarget.ISA(ScTabViewTarget))
{
@@ -478,7 +480,7 @@ void __EXPORT ScUndoDeleteTab::Repeat(SfxRepeatTarget& rTarget)
}
}
-BOOL __EXPORT ScUndoDeleteTab::CanRepeat(SfxRepeatTarget& rTarget) const
+BOOL ScUndoDeleteTab::CanRepeat(SfxRepeatTarget& rTarget) const
{
return (rTarget.ISA(ScTabViewTarget));
}
@@ -500,11 +502,11 @@ ScUndoRenameTab::ScUndoRenameTab( ScDocShell* pNewDocShell,
sNewName = rNewName;
}
-__EXPORT ScUndoRenameTab::~ScUndoRenameTab()
+ScUndoRenameTab::~ScUndoRenameTab()
{
}
-String __EXPORT ScUndoRenameTab::GetComment() const
+String ScUndoRenameTab::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_RENAME_TAB );
}
@@ -526,22 +528,22 @@ void ScUndoRenameTab::DoChange( SCTAB nTabP, const String& rName ) const
pViewShell->UpdateInputHandler();
}
-void __EXPORT ScUndoRenameTab::Undo()
+void ScUndoRenameTab::Undo()
{
DoChange(nTab, sOldName);
}
-void __EXPORT ScUndoRenameTab::Redo()
+void ScUndoRenameTab::Redo()
{
DoChange(nTab, sNewName);
}
-void __EXPORT ScUndoRenameTab::Repeat(SfxRepeatTarget& /* rTarget */)
+void ScUndoRenameTab::Repeat(SfxRepeatTarget& /* rTarget */)
{
// Repeat macht keinen Sinn
}
-BOOL __EXPORT ScUndoRenameTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+BOOL ScUndoRenameTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
return FALSE;
}
@@ -565,13 +567,13 @@ ScUndoMoveTab::ScUndoMoveTab( ScDocShell* pNewDocShell,
theNewTabs.Insert(aNewTab[sal::static_int_cast<USHORT>(i)],theNewTabs.Count());
}
-__EXPORT ScUndoMoveTab::~ScUndoMoveTab()
+ScUndoMoveTab::~ScUndoMoveTab()
{
theNewTabs.Remove(0,theNewTabs.Count());
theOldTabs.Remove(0,theOldTabs.Count());
}
-String __EXPORT ScUndoMoveTab::GetComment() const
+String ScUndoMoveTab::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_MOVE_TAB );
}
@@ -618,22 +620,22 @@ void ScUndoMoveTab::DoChange( BOOL bUndo ) const
pDocShell->PostDataChanged();
}
-void __EXPORT ScUndoMoveTab::Undo()
+void ScUndoMoveTab::Undo()
{
DoChange( TRUE );
}
-void __EXPORT ScUndoMoveTab::Redo()
+void ScUndoMoveTab::Redo()
{
DoChange( FALSE );
}
-void __EXPORT ScUndoMoveTab::Repeat(SfxRepeatTarget& /* rTarget */)
+void ScUndoMoveTab::Repeat(SfxRepeatTarget& /* rTarget */)
{
// kein Repeat ! ? !
}
-BOOL __EXPORT ScUndoMoveTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+BOOL ScUndoMoveTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
return FALSE;
}
@@ -660,12 +662,12 @@ ScUndoCopyTab::ScUndoCopyTab( ScDocShell* pNewDocShell,
theNewTabs.Insert(aNewTab[sal::static_int_cast<USHORT>(i)],theNewTabs.Count());
}
-__EXPORT ScUndoCopyTab::~ScUndoCopyTab()
+ScUndoCopyTab::~ScUndoCopyTab()
{
DeleteSdrUndoAction( pDrawUndo );
}
-String __EXPORT ScUndoCopyTab::GetComment() const
+String ScUndoCopyTab::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_COPY_TAB );
}
@@ -684,7 +686,7 @@ void ScUndoCopyTab::DoChange() const
pDocShell->PostDataChanged();
}
-void __EXPORT ScUndoCopyTab::Undo()
+void ScUndoCopyTab::Undo()
{
ScDocument* pDoc = pDocShell->GetDocument();
@@ -717,7 +719,7 @@ void __EXPORT ScUndoCopyTab::Undo()
DoChange();
}
-void __EXPORT ScUndoCopyTab::Redo()
+void ScUndoCopyTab::Redo()
{
ScDocument* pDoc = pDocShell->GetDocument();
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
@@ -756,7 +758,7 @@ void __EXPORT ScUndoCopyTab::Redo()
}
if ( pDoc->IsTabProtected( nAdjSource ) )
- pDoc->SetTabProtection( nNewTab, TRUE, pDoc->GetTabPassword( nAdjSource ) );
+ pDoc->CopyTabProtection(nAdjSource, nNewTab);
}
RedoSdrUndoAction( pDrawUndo ); // after the sheets are inserted
@@ -767,12 +769,12 @@ void __EXPORT ScUndoCopyTab::Redo()
}
-void __EXPORT ScUndoCopyTab::Repeat(SfxRepeatTarget& /* rTarget */)
+void ScUndoCopyTab::Repeat(SfxRepeatTarget& /* rTarget */)
{
// kein Repeat ! ? !
}
-BOOL __EXPORT ScUndoCopyTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+BOOL ScUndoCopyTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
return FALSE;
}
@@ -801,17 +803,17 @@ ScUndoMakeScenario::ScUndoMakeScenario( ScDocShell* pNewDocShell,
pDrawUndo = GetSdrUndoAction( pDocShell->GetDocument() );
}
-__EXPORT ScUndoMakeScenario::~ScUndoMakeScenario()
+ScUndoMakeScenario::~ScUndoMakeScenario()
{
DeleteSdrUndoAction( pDrawUndo );
}
-String __EXPORT ScUndoMakeScenario::GetComment() const
+String ScUndoMakeScenario::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_MAKESCENARIO );
}
-void __EXPORT ScUndoMakeScenario::Undo()
+void ScUndoMakeScenario::Undo()
{
ScDocument* pDoc = pDocShell->GetDocument();
@@ -836,7 +838,7 @@ void __EXPORT ScUndoMakeScenario::Undo()
pDocShell->Broadcast( SfxSimpleHint( SC_HINT_FORCESETTAB ) );
}
-void __EXPORT ScUndoMakeScenario::Redo()
+void ScUndoMakeScenario::Redo()
{
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
if (pViewShell)
@@ -858,7 +860,7 @@ void __EXPORT ScUndoMakeScenario::Redo()
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
}
-void __EXPORT ScUndoMakeScenario::Repeat(SfxRepeatTarget& rTarget)
+void ScUndoMakeScenario::Repeat(SfxRepeatTarget& rTarget)
{
if (rTarget.ISA(ScTabViewTarget))
{
@@ -866,7 +868,7 @@ void __EXPORT ScUndoMakeScenario::Repeat(SfxRepeatTarget& rTarget)
}
}
-BOOL __EXPORT ScUndoMakeScenario::CanRepeat(SfxRepeatTarget& rTarget) const
+BOOL ScUndoMakeScenario::CanRepeat(SfxRepeatTarget& rTarget) const
{
return (rTarget.ISA(ScTabViewTarget));
}
@@ -889,13 +891,13 @@ ScUndoImportTab::ScUndoImportTab( ScDocShell* pShell,
pDrawUndo = GetSdrUndoAction( pDocShell->GetDocument() );
}
-__EXPORT ScUndoImportTab::~ScUndoImportTab()
+ScUndoImportTab::~ScUndoImportTab()
{
delete pRedoDoc;
DeleteSdrUndoAction( pDrawUndo );
}
-String __EXPORT ScUndoImportTab::GetComment() const
+String ScUndoImportTab::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_INSERT_TAB );
}
@@ -922,7 +924,7 @@ void ScUndoImportTab::DoChange() const
PAINT_GRID | PAINT_TOP | PAINT_LEFT | PAINT_EXTRAS );
}
-void __EXPORT ScUndoImportTab::Undo()
+void ScUndoImportTab::Undo()
{
//! eingefuegte Bereichsnamen etc.
@@ -958,7 +960,7 @@ void __EXPORT ScUndoImportTab::Undo()
}
if ( pDoc->IsTabProtected( nTabPos ) )
- pRedoDoc->SetTabProtection( nTabPos, TRUE, pDoc->GetTabPassword( nTabPos ) );
+ pRedoDoc->SetTabProtection(nTabPos, pDoc->GetTabProtection(nTabPos));
}
}
@@ -973,7 +975,7 @@ void __EXPORT ScUndoImportTab::Undo()
DoChange();
}
-void __EXPORT ScUndoImportTab::Redo()
+void ScUndoImportTab::Redo()
{
if (!pRedoDoc)
{
@@ -1012,7 +1014,7 @@ void __EXPORT ScUndoImportTab::Redo()
}
if ( pRedoDoc->IsTabProtected( nTabPos ) )
- pDoc->SetTabProtection( nTabPos, TRUE, pRedoDoc->GetTabPassword( nTabPos ) );
+ pDoc->SetTabProtection(nTabPos, pRedoDoc->GetTabProtection(nTabPos));
}
RedoSdrUndoAction( pDrawUndo ); // after the sheets are inserted
@@ -1020,14 +1022,14 @@ void __EXPORT ScUndoImportTab::Redo()
DoChange();
}
-void __EXPORT ScUndoImportTab::Repeat(SfxRepeatTarget& rTarget)
+void ScUndoImportTab::Repeat(SfxRepeatTarget& rTarget)
{
if (rTarget.ISA(ScTabViewTarget))
((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData()->GetDispatcher().
Execute(FID_INS_TABLE, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
}
-BOOL __EXPORT ScUndoImportTab::CanRepeat(SfxRepeatTarget& rTarget) const
+BOOL ScUndoImportTab::CanRepeat(SfxRepeatTarget& rTarget) const
{
return (rTarget.ISA(ScTabViewTarget));
}
@@ -1075,14 +1077,14 @@ ScUndoRemoveLink::ScUndoRemoveLink( ScDocShell* pShell, const String& rDoc ) :
}
}
-__EXPORT ScUndoRemoveLink::~ScUndoRemoveLink()
+ScUndoRemoveLink::~ScUndoRemoveLink()
{
delete pTabs;
delete pModes;
delete[] pTabNames;
}
-String __EXPORT ScUndoRemoveLink::GetComment() const
+String ScUndoRemoveLink::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_REMOVELINK );
}
@@ -1099,22 +1101,22 @@ void ScUndoRemoveLink::DoChange( BOOL bLink ) const
pDocShell->UpdateLinks();
}
-void __EXPORT ScUndoRemoveLink::Undo()
+void ScUndoRemoveLink::Undo()
{
DoChange( TRUE );
}
-void __EXPORT ScUndoRemoveLink::Redo()
+void ScUndoRemoveLink::Redo()
{
DoChange( FALSE );
}
-void __EXPORT ScUndoRemoveLink::Repeat(SfxRepeatTarget& /* rTarget */)
+void ScUndoRemoveLink::Repeat(SfxRepeatTarget& /* rTarget */)
{
// gippsnich
}
-BOOL __EXPORT ScUndoRemoveLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+BOOL ScUndoRemoveLink::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
return FALSE;
}
@@ -1132,7 +1134,7 @@ ScUndoShowHideTab::ScUndoShowHideTab( ScDocShell* pShell, SCTAB nNewTab, BOOL bN
{
}
-__EXPORT ScUndoShowHideTab::~ScUndoShowHideTab()
+ScUndoShowHideTab::~ScUndoShowHideTab()
{
}
@@ -1149,17 +1151,17 @@ void ScUndoShowHideTab::DoChange( BOOL bShowP ) const
pDocShell->SetDocumentModified();
}
-void __EXPORT ScUndoShowHideTab::Undo()
+void ScUndoShowHideTab::Undo()
{
DoChange(!bShow);
}
-void __EXPORT ScUndoShowHideTab::Redo()
+void ScUndoShowHideTab::Redo()
{
DoChange(bShow);
}
-void __EXPORT ScUndoShowHideTab::Repeat(SfxRepeatTarget& rTarget)
+void ScUndoShowHideTab::Repeat(SfxRepeatTarget& rTarget)
{
if (rTarget.ISA(ScTabViewTarget))
((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData()->GetDispatcher().
@@ -1167,53 +1169,44 @@ void __EXPORT ScUndoShowHideTab::Repeat(SfxRepeatTarget& rTarget)
SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
}
-BOOL __EXPORT ScUndoShowHideTab::CanRepeat(SfxRepeatTarget& rTarget) const
+BOOL ScUndoShowHideTab::CanRepeat(SfxRepeatTarget& rTarget) const
{
return (rTarget.ISA(ScTabViewTarget));
}
-String __EXPORT ScUndoShowHideTab::GetComment() const
+String ScUndoShowHideTab::GetComment() const
{
USHORT nId = bShow ? STR_UNDO_SHOWTAB : STR_UNDO_HIDETAB;
return ScGlobal::GetRscString( nId );
}
-// -----------------------------------------------------------------------
-//
-// Tabelle/Dokument schuetzen oder Schutz aufheben
-//
+// ============================================================================
-ScUndoProtect::ScUndoProtect( ScDocShell* pShell, SCTAB nNewTab,
- BOOL bNewProtect, const uno::Sequence<sal_Int8>& rNewPassword ) :
- ScSimpleUndo( pShell ),
- nTab( nNewTab ),
- bProtect( bNewProtect ),
- aPassword( rNewPassword )
+ScUndoDocProtect::ScUndoDocProtect(ScDocShell* pShell, auto_ptr<ScDocProtection> pProtectSettings) :
+ ScSimpleUndo(pShell),
+ mpProtectSettings(pProtectSettings)
{
}
-__EXPORT ScUndoProtect::~ScUndoProtect()
+ScUndoDocProtect::~ScUndoDocProtect()
{
}
-void ScUndoProtect::DoProtect( BOOL bDo )
+void ScUndoDocProtect::DoProtect(bool bProtect)
{
ScDocument* pDoc = pDocShell->GetDocument();
- if (bDo)
+ if (bProtect)
{
- if ( nTab == TABLEID_DOC )
- pDoc->SetDocProtection( TRUE, aPassword );
- else
- pDoc->SetTabProtection( nTab, TRUE, aPassword );
+ // set protection.
+ auto_ptr<ScDocProtection> pCopy(new ScDocProtection(*mpProtectSettings));
+ pCopy->setProtected(true);
+ pDoc->SetDocProtection(pCopy.get());
}
else
{
- uno::Sequence<sal_Int8> aEmptyPass;
- if ( nTab == TABLEID_DOC )
- pDoc->SetDocProtection( FALSE, aEmptyPass );
- else
- pDoc->SetTabProtection( nTab, FALSE, aEmptyPass );
+ // remove protection.
+ pDoc->SetDocProtection(NULL);
}
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
@@ -1226,37 +1219,103 @@ void ScUndoProtect::DoProtect( BOOL bDo )
pDocShell->PostPaintGridAll();
}
-void __EXPORT ScUndoProtect::Undo()
+void ScUndoDocProtect::Undo()
{
BeginUndo();
- DoProtect( !bProtect );
+ DoProtect(!mpProtectSettings->isProtected());
EndUndo();
}
-void __EXPORT ScUndoProtect::Redo()
+void ScUndoDocProtect::Redo()
{
BeginRedo();
- DoProtect( bProtect );
+ DoProtect(mpProtectSettings->isProtected());
EndRedo();
}
-void __EXPORT ScUndoProtect::Repeat(SfxRepeatTarget& /* rTarget */)
+void ScUndoDocProtect::Repeat(SfxRepeatTarget& /* rTarget */)
{
// gippsnich
}
-BOOL __EXPORT ScUndoProtect::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+BOOL ScUndoDocProtect::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
return FALSE; // gippsnich
}
-String __EXPORT ScUndoProtect::GetComment() const
+String ScUndoDocProtect::GetComment() const
{
- USHORT nId;
- if ( nTab == TABLEID_DOC )
- nId = bProtect ? STR_UNDO_PROTECT_DOC : STR_UNDO_UNPROTECT_DOC;
+ USHORT nId = mpProtectSettings->isProtected() ? STR_UNDO_PROTECT_DOC : STR_UNDO_UNPROTECT_DOC;
+ return ScGlobal::GetRscString( nId );
+}
+
+// ============================================================================
+
+ScUndoTabProtect::ScUndoTabProtect(ScDocShell* pShell, SCTAB nTab, auto_ptr<ScTableProtection> pProtectSettings) :
+ ScSimpleUndo(pShell),
+ mnTab(nTab),
+ mpProtectSettings(pProtectSettings)
+{
+}
+
+ScUndoTabProtect::~ScUndoTabProtect()
+{
+}
+
+void ScUndoTabProtect::DoProtect(bool bProtect)
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ if (bProtect)
+ {
+ // set protection.
+ auto_ptr<ScTableProtection> pCopy(new ScTableProtection(*mpProtectSettings));
+ pCopy->setProtected(true);
+ pDoc->SetTabProtection(mnTab, pCopy.get());
+ }
else
- nId = bProtect ? STR_UNDO_PROTECT_TAB : STR_UNDO_UNPROTECT_TAB;
+ {
+ // remove protection.
+ pDoc->SetTabProtection(mnTab, NULL);
+ }
+
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+ {
+ pViewShell->UpdateLayerLocks();
+ pViewShell->UpdateInputHandler(TRUE); // damit sofort wieder eingegeben werden kann
+ }
+
+ pDocShell->PostPaintGridAll();
+}
+
+void ScUndoTabProtect::Undo()
+{
+ BeginUndo();
+ DoProtect(!mpProtectSettings->isProtected());
+ EndUndo();
+}
+
+void ScUndoTabProtect::Redo()
+{
+ BeginRedo();
+ DoProtect(mpProtectSettings->isProtected());
+ EndRedo();
+}
+
+void ScUndoTabProtect::Repeat(SfxRepeatTarget& /* rTarget */)
+{
+ // gippsnich
+}
+
+BOOL ScUndoTabProtect::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+{
+ return FALSE; // gippsnich
+}
+
+String ScUndoTabProtect::GetComment() const
+{
+ USHORT nId = mpProtectSettings->isProtected() ? STR_UNDO_PROTECT_TAB : STR_UNDO_UNPROTECT_TAB;
return ScGlobal::GetRscString( nId );
}
@@ -1274,7 +1333,7 @@ ScUndoPrintRange::ScUndoPrintRange( ScDocShell* pShell, SCTAB nNewTab,
{
}
-__EXPORT ScUndoPrintRange::~ScUndoPrintRange()
+ScUndoPrintRange::~ScUndoPrintRange()
{
delete pOldRanges;
delete pNewRanges;
@@ -1297,31 +1356,31 @@ void ScUndoPrintRange::DoChange(BOOL bUndo)
pDocShell->PostPaint( ScRange(0,0,nTab,MAXCOL,MAXROW,nTab), PAINT_GRID );
}
-void __EXPORT ScUndoPrintRange::Undo()
+void ScUndoPrintRange::Undo()
{
BeginUndo();
DoChange( TRUE );
EndUndo();
}
-void __EXPORT ScUndoPrintRange::Redo()
+void ScUndoPrintRange::Redo()
{
BeginRedo();
DoChange( FALSE );
EndRedo();
}
-void __EXPORT ScUndoPrintRange::Repeat(SfxRepeatTarget& /* rTarget */)
+void ScUndoPrintRange::Repeat(SfxRepeatTarget& /* rTarget */)
{
// gippsnich
}
-BOOL __EXPORT ScUndoPrintRange::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+BOOL ScUndoPrintRange::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
return FALSE; // gippsnich
}
-String __EXPORT ScUndoPrintRange::GetComment() const
+String ScUndoPrintRange::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_PRINTRANGES );
}
@@ -1350,16 +1409,16 @@ ScUndoScenarioFlags::ScUndoScenarioFlags( ScDocShell* pNewDocShell, SCTAB nT,
{
}
-__EXPORT ScUndoScenarioFlags::~ScUndoScenarioFlags()
+ScUndoScenarioFlags::~ScUndoScenarioFlags()
{
}
-String __EXPORT ScUndoScenarioFlags::GetComment() const
+String ScUndoScenarioFlags::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_EDITSCENARIO );
}
-void __EXPORT ScUndoScenarioFlags::Undo()
+void ScUndoScenarioFlags::Undo()
{
ScDocument* pDoc = pDocShell->GetDocument();
@@ -1376,7 +1435,7 @@ void __EXPORT ScUndoScenarioFlags::Undo()
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
}
-void __EXPORT ScUndoScenarioFlags::Redo()
+void ScUndoScenarioFlags::Redo()
{
ScDocument* pDoc = pDocShell->GetDocument();
@@ -1393,12 +1452,12 @@ void __EXPORT ScUndoScenarioFlags::Redo()
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
}
-void __EXPORT ScUndoScenarioFlags::Repeat(SfxRepeatTarget& /* rTarget */)
+void ScUndoScenarioFlags::Repeat(SfxRepeatTarget& /* rTarget */)
{
// Repeat macht keinen Sinn
}
-BOOL __EXPORT ScUndoScenarioFlags::CanRepeat(SfxRepeatTarget& /* rTarget */) const
+BOOL ScUndoScenarioFlags::CanRepeat(SfxRepeatTarget& /* rTarget */) const
{
return FALSE;
}
@@ -1498,7 +1557,7 @@ ScUndoLayoutRTL::ScUndoLayoutRTL( ScDocShell* pShell, SCTAB nNewTab, BOOL bNewRT
{
}
-__EXPORT ScUndoLayoutRTL::~ScUndoLayoutRTL()
+ScUndoLayoutRTL::~ScUndoLayoutRTL()
{
}
@@ -1518,29 +1577,29 @@ void ScUndoLayoutRTL::DoChange( BOOL bNew )
pDocShell->SetInUndo( FALSE );
}
-void __EXPORT ScUndoLayoutRTL::Undo()
+void ScUndoLayoutRTL::Undo()
{
DoChange(!bRTL);
}
-void __EXPORT ScUndoLayoutRTL::Redo()
+void ScUndoLayoutRTL::Redo()
{
DoChange(bRTL);
}
-void __EXPORT ScUndoLayoutRTL::Repeat(SfxRepeatTarget& rTarget)
+void ScUndoLayoutRTL::Repeat(SfxRepeatTarget& rTarget)
{
if (rTarget.ISA(ScTabViewTarget))
((ScTabViewTarget&)rTarget).GetViewShell()->GetViewData()->GetDispatcher().
Execute( FID_TAB_RTL, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
}
-BOOL __EXPORT ScUndoLayoutRTL::CanRepeat(SfxRepeatTarget& rTarget) const
+BOOL ScUndoLayoutRTL::CanRepeat(SfxRepeatTarget& rTarget) const
{
return (rTarget.ISA(ScTabViewTarget));
}
-String __EXPORT ScUndoLayoutRTL::GetComment() const
+String ScUndoLayoutRTL::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_TAB_RTL );
}
@@ -1560,7 +1619,7 @@ ScUndoSetGrammar::ScUndoSetGrammar( ScDocShell* pShell,
meOldGrammar = pDocShell->GetDocument()->GetGrammar();
}
-__EXPORT ScUndoSetGrammar::~ScUndoSetGrammar()
+ScUndoSetGrammar::~ScUndoSetGrammar()
{
}
@@ -1573,17 +1632,17 @@ void ScUndoSetGrammar::DoChange( formula::FormulaGrammar::Grammar eGrammar )
pDocShell->SetInUndo( FALSE );
}
-void __EXPORT ScUndoSetGrammar::Undo()
+void ScUndoSetGrammar::Undo()
{
DoChange( meOldGrammar );
}
-void __EXPORT ScUndoSetGrammar::Redo()
+void ScUndoSetGrammar::Redo()
{
DoChange( meNewGrammar );
}
-void __EXPORT ScUndoSetGrammar::Repeat(SfxRepeatTarget& /* rTarget */)
+void ScUndoSetGrammar::Repeat(SfxRepeatTarget& /* rTarget */)
{
#if 0
// erAck: 2006-09-07T23:00+0200 commented out in CWS scr1c1
@@ -1593,12 +1652,12 @@ void __EXPORT ScUndoSetGrammar::Repeat(SfxRepeatTarget& /* rTarget */)
#endif
}
-BOOL __EXPORT ScUndoSetGrammar::CanRepeat(SfxRepeatTarget& rTarget) const
+BOOL ScUndoSetGrammar::CanRepeat(SfxRepeatTarget& rTarget) const
{
return (rTarget.ISA(ScTabViewTarget));
}
-String __EXPORT ScUndoSetGrammar::GetComment() const
+String ScUndoSetGrammar::GetComment() const
{
return ScGlobal::GetRscString( STR_UNDO_TAB_R1C1 );
}
diff --git a/sc/source/ui/unoobj/warnpassword.cxx b/sc/source/ui/unoobj/warnpassword.cxx
index 6453bcbd0de7..6b11ac7c6641 100644
--- a/sc/source/ui/unoobj/warnpassword.cxx
+++ b/sc/source/ui/unoobj/warnpassword.cxx
@@ -95,3 +95,4 @@ bool ScWarnPassword::WarningOnPassword( SfxMedium& rMedium )
}
return bReturn;
}
+
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index dda608037012..918341294e9d 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -119,6 +119,7 @@
#include "drwlayer.hxx"
#include "attrib.hxx"
#include "validat.hxx"
+#include "tabprotection.hxx"
// #114409#
#include <vcl/salbtype.hxx> // FRound
@@ -2027,8 +2028,9 @@ void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt )
Point aPos = rMEvt.GetPosPixel();
SCsCOL nPosX;
SCsROW nPosY;
+ SCTAB nTab = pViewData->GetTabNo();
pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
- ScDPObject* pDPObj = pDoc->GetDPAtCursor( nPosX, nPosY, pViewData->GetTabNo() );
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor( nPosX, nPosY, nTab );
if ( pDPObj && pDPObj->GetSaveData()->GetDrillDown() )
{
ScAddress aCellPos( nPosX, nPosY, pViewData->GetTabNo() );
@@ -2070,16 +2072,34 @@ void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt )
return;
}
- // edit cell contents
- pViewData->GetViewShell()->UpdateInputHandler();
- pScMod->SetInputMode( SC_INPUT_TABLE );
- if (pViewData->HasEditView(eWhich))
+ // Check for cell protection attribute.
+ ScTableProtection* pProtect = pDoc->GetTabProtection( nTab );
+ bool bEditAllowed = true;
+ if ( pProtect && pProtect->isProtected() )
+ {
+ bool bCellProtected = pDoc->HasAttrib(nPosX, nPosY, nTab, nPosX, nPosY, nTab, HASATTR_PROTECTED);
+ bool bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+ bool bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
+
+ if ( bSkipProtected && bSkipUnprotected )
+ bEditAllowed = false;
+ else if ( (bCellProtected && bSkipProtected) || (!bCellProtected && bSkipUnprotected) )
+ bEditAllowed = false;
+ }
+
+ if ( bEditAllowed )
{
- // Text-Cursor gleich an die geklickte Stelle setzen
- EditView* pEditView = pViewData->GetEditView( eWhich );
- MouseEvent aEditEvt( rMEvt.GetPosPixel(), 1, MOUSE_SYNTHETIC, MOUSE_LEFT, 0 );
- pEditView->MouseButtonDown( aEditEvt );
- pEditView->MouseButtonUp( aEditEvt );
+ // edit cell contents
+ pViewData->GetViewShell()->UpdateInputHandler();
+ pScMod->SetInputMode( SC_INPUT_TABLE );
+ if (pViewData->HasEditView(eWhich))
+ {
+ // Text-Cursor gleich an die geklickte Stelle setzen
+ EditView* pEditView = pViewData->GetEditView( eWhich );
+ MouseEvent aEditEvt( rMEvt.GetPosPixel(), 1, MOUSE_SYNTHETIC, MOUSE_LEFT, 0 );
+ pEditView->MouseButtonDown( aEditEvt );
+ pEditView->MouseButtonUp( aEditEvt );
+ }
}
return;
}
diff --git a/sc/source/ui/view/scextopt.cxx b/sc/source/ui/view/scextopt.cxx
index 15b4329fb00e..e6b4a3d0c20e 100644
--- a/sc/source/ui/view/scextopt.cxx
+++ b/sc/source/ui/view/scextopt.cxx
@@ -42,9 +42,7 @@ ScExtDocSettings::ScExtDocSettings() :
maOleSize( ScAddress::INITIALIZE_INVALID ),
mfTabBarWidth( -1.0 ),
mnLinkCnt( 0 ),
- mnDisplTab( 0 ),
- mbWinProtected( false ),
- mbEncrypted( false )
+ mnDisplTab( 0 )
{
}
diff --git a/sc/source/ui/view/select.cxx b/sc/source/ui/view/select.cxx
index 288b50daed19..b8d0da840db7 100644
--- a/sc/source/ui/view/select.cxx
+++ b/sc/source/ui/view/select.cxx
@@ -47,6 +47,7 @@
//#include "dataobj.hxx"
#include "transobj.hxx"
#include "docsh.hxx"
+#include "tabprotection.hxx"
extern USHORT nScFillModeMouseModifier; // global.cxx
@@ -322,6 +323,26 @@ BOOL ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScrol
{
ScTabView* pView = pViewData->GetView();
SCTAB nTab = pViewData->GetTabNo();
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ if ( pDoc->IsTabProtected(nTab) )
+ {
+ if (nPosX < 0 || nPosY < 0)
+ return false;
+
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ bool bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+ bool bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
+
+ if ( bSkipProtected && bSkipUnprotected )
+ return FALSE;
+
+ bool bCellProtected = pDoc->HasAttrib(nPosX, nPosY, nTab, nPosX, nPosY, nTab, HASATTR_PROTECTED);
+ if ( (bCellProtected && bSkipProtected) || (!bCellProtected && bSkipUnprotected) )
+ // Don't select this cell!
+ return FALSE;
+ }
+
ScModule* pScMod = SC_MOD();
ScTabViewShell* pViewShell = pViewData->GetViewShell();
bool bRefMode = ( pViewShell ? pViewShell->IsRefInputMode() : false );
@@ -375,7 +396,6 @@ BOOL ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScrol
ScRange aDelRange;
BOOL bOldDelMark = pViewData->GetDelMark( aDelRange );
- ScDocument* pDoc = pViewData->GetDocument();
if ( nPosX+1 >= (SCsCOL) nStartX && nPosX <= (SCsCOL) nEndX &&
nPosY+1 >= (SCsROW) nStartY && nPosY <= (SCsROW) nEndY &&
@@ -511,7 +531,6 @@ BOOL ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScrol
BYTE nMode = pViewData->GetFillMode();
if ( nMode == SC_FILL_EMBED_LT || nMode == SC_FILL_EMBED_RB )
{
- ScDocument* pDoc = pViewData->GetDocument();
DBG_ASSERT( pDoc->IsEmbedded(), "!pDoc->IsEmbedded()" );
ScRange aRange;
pDoc->GetEmbedded( aRange);
diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx
index 1be33a37cd26..41789b3c6da5 100644
--- a/sc/source/ui/view/tabview3.cxx
+++ b/sc/source/ui/view/tabview3.cxx
@@ -79,6 +79,7 @@
#include "AccessibilityHints.hxx"
#include "rangeutl.hxx"
#include "client.hxx"
+#include "tabprotection.hxx"
#include <com/sun/star/chart2/data/HighlightedRange.hpp>
@@ -946,6 +947,17 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
ScDocument* pDoc = aViewData.GetDocument();
SCTAB nTab = aViewData.GetTabNo();
+ bool bSkipProtected = false, bSkipUnprotected = false;
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ if ( pProtect && pProtect->isProtected() )
+ {
+ bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+ bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
+ }
+
+ if ( bSkipProtected && bSkipUnprotected )
+ return;
+
SCsCOL nOldX;
SCsROW nOldY;
SCsCOL nCurX;
@@ -965,7 +977,7 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
nCurY = (nMovY != 0) ? nOldY+nMovY : (SCsROW) aViewData.GetOldCurY();
}
- BOOL bHidden;
+ BOOL bSkipCell = FALSE;
aViewData.ResetOldCursor();
if (nMovX != 0 && VALIDCOLROW(nCurX,nCurY))
@@ -974,15 +986,20 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
do
{
BYTE nColFlags = pDoc->GetColFlags( nCurX, nTab );
- bHidden = (nColFlags & CR_HIDDEN) || pDoc->IsHorOverlapped( nCurX, nCurY, nTab );
- if (bHidden)
+ bSkipCell = (nColFlags & CR_HIDDEN) || pDoc->IsHorOverlapped( nCurX, nCurY, nTab );
+ if (bSkipProtected && !bSkipCell)
+ bSkipCell = pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
+ if (bSkipUnprotected && !bSkipCell)
+ bSkipCell = !pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
+
+ if (bSkipCell)
{
if ( nCurX<=0 || nCurX>=MAXCOL )
{
if (bHFlip)
{
nCurX = nOldX;
- bHidden = FALSE;
+ bSkipCell = FALSE;
}
else
{
@@ -995,7 +1012,8 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
if (nMovX > 0) ++nCurX; else --nCurX;
}
}
- while (bHidden);
+ while (bSkipCell);
+
if (pDoc->IsVerOverlapped( nCurX, nCurY, nTab ))
{
aViewData.SetOldCursor( nCurX,nCurY );
@@ -1010,15 +1028,20 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
do
{
BYTE nRowFlags = pDoc->GetRowFlags( nCurY, nTab );
- bHidden = (nRowFlags & CR_HIDDEN) || pDoc->IsVerOverlapped( nCurX, nCurY, nTab );
- if (bHidden)
+ bSkipCell = (nRowFlags & CR_HIDDEN) || pDoc->IsVerOverlapped( nCurX, nCurY, nTab );
+ if (bSkipProtected && !bSkipCell)
+ bSkipCell = pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
+ if (bSkipUnprotected && !bSkipCell)
+ bSkipCell = !pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
+
+ if (bSkipCell)
{
if ( nCurY<=0 || nCurY>=MAXROW )
{
if (bVFlip)
{
nCurY = nOldY;
- bHidden = FALSE;
+ bSkipCell = FALSE;
}
else
{
@@ -1031,7 +1054,8 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
if (nMovY > 0) ++nCurY; else --nCurY;
}
}
- while (bHidden);
+ while (bSkipCell);
+
if (pDoc->IsHorOverlapped( nCurX, nCurY, nTab ))
{
aViewData.SetOldCursor( nCurX,nCurY );
diff --git a/sc/source/ui/view/tabvwsh3.cxx b/sc/source/ui/view/tabvwsh3.cxx
index 7461d884c5b2..115f14cafc1c 100644
--- a/sc/source/ui/view/tabvwsh3.cxx
+++ b/sc/source/ui/view/tabvwsh3.cxx
@@ -75,6 +75,8 @@
#include "autofmt.hxx"
#include "dwfunctr.hxx"
#include "shtabdlg.hxx"
+#include "tabprotection.hxx"
+#include "protectiondlg.hxx"
#include <svtools/ilstitem.hxx>
#define _SVSTDARR_ULONGS
@@ -85,6 +87,10 @@
#include <svx/dialogs.hrc> //CHINA001
#include "scabstdlg.hxx" //CHINA001
+#include <memory>
+
+using ::std::auto_ptr;
+
#define IS_EDITMODE() GetViewData()->HasEditView( GetViewData()->GetActivePart() )
#define IS_AVAILABLE(WhichId,ppItem) \
(pReqArgs->GetItemState((WhichId), TRUE, ppItem ) == SFX_ITEM_SET)
@@ -1009,12 +1015,13 @@ void ScTabViewShell::Execute( SfxRequest& rReq )
}
}
- if (pDoc->IsDocProtected())
+ ScDocProtection* pProtect = pDoc->GetDocProtection();
+ if (pProtect && pProtect->isProtected())
{
BOOL bCancel = FALSE;
String aPassword;
- if (pDoc->GetDocPassword().getLength())
+ if (pProtect->isProtectedWithPass())
{
String aText( ScResId(SCSTR_PASSWORD) );
@@ -1064,89 +1071,164 @@ void ScTabViewShell::Execute( SfxRequest& rReq )
case FID_PROTECT_TABLE:
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ bool bOldProtection = pDoc->IsTabProtected(nTab);
+
+#if ENABLE_SHEET_PROTECTION
+
+ if( pReqArgs )
{
- ScDocument* pDoc = GetViewData()->GetDocument();
- SCTAB nTab = GetViewData()->GetTabNo();
- SfxPasswordDialog* pDlg;
- String aPassword;
- BOOL bCancel = FALSE;
- BOOL bOldProtection = pDoc->IsTabProtected(nTab);
- BOOL bNewProtection = ! bOldProtection;
+ const SfxPoolItem* pItem;
+ bool bNewProtection = !bOldProtection;
+ if( IS_AVAILABLE( FID_PROTECT_TABLE, &pItem ) )
+ bNewProtection = ((const SfxBoolItem*)pItem)->GetValue();
+ if( bNewProtection == bOldProtection )
+ {
+ rReq.Ignore();
+ break;
+ }
+ }
- if( pReqArgs )
+ if (bOldProtection)
+ {
+ // Unprotect a protected sheet.
+
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ if (pProtect && pProtect->isProtectedWithPass())
{
- const SfxPoolItem* pItem;
- if( IS_AVAILABLE( FID_PROTECT_TABLE, &pItem ) )
- bNewProtection = ((const SfxBoolItem*)pItem)->GetValue();
- if( bNewProtection == bOldProtection )
+ String aText( ScResId(SCSTR_PASSWORDOPT) );
+ auto_ptr<SfxPasswordDialog> pDlg(new SfxPasswordDialog(GetDialogParent(), &aText));
+ pDlg->SetText( ScResId(SCSTR_UNPROTECTTAB) );
+ pDlg->SetMinLen( 0 );
+ pDlg->SetHelpId( FID_PROTECT_TABLE );
+ pDlg->SetEditHelpId( HID_PASSWD_TABLE );
+
+ if (pDlg->Execute() == RET_OK)
{
- rReq.Ignore();
- break;
+ String aPassword = pDlg->GetPassword();
+ Unprotect(nTab, aPassword);
}
}
+ else
+ // this sheet is not password-protected.
+ Unprotect(nTab, String());
- if ( bOldProtection)
- {
- if (pDoc->GetTabPassword(nTab).getLength())
- {
- String aText( ScResId(SCSTR_PASSWORD) );
+ if (!pReqArgs)
+ {
+ rReq.AppendItem( SfxBoolItem(FID_PROTECT_TABLE, false) );
+ rReq.Done();
+ }
+ }
+ else
+ {
+ // Protect a current sheet.
- pDlg = new SfxPasswordDialog( GetDialogParent(), &aText );
- pDlg->SetText( ScResId(SCSTR_UNPROTECTTAB) );
- pDlg->SetMinLen( 0 );
- pDlg->SetHelpId( FID_PROTECT_TABLE );
- pDlg->SetEditHelpId( HID_PASSWD_TABLE );
+ auto_ptr<ScTableProtectionDlg> pDlg(new ScTableProtectionDlg(GetDialogParent()));
- if (pDlg->Execute() == RET_OK)
- aPassword = pDlg->GetPassword();
- else
- bCancel = TRUE;
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ if (pProtect)
+ pDlg->SetDialogData(*pProtect);
- delete pDlg;
- }
- }
- else
- {
- String aText( ScResId(SCSTR_PASSWORDOPT) );
+ if (pDlg->Execute() == RET_OK)
+ {
+ pScMod->InputEnterHandler();
- pDlg = new SfxPasswordDialog( GetDialogParent(), &aText );
- pDlg->SetText( ScResId(SCSTR_PROTECTTAB) );
- pDlg->SetMinLen( 0 );
- pDlg->SetHelpId( FID_PROTECT_TABLE );
- pDlg->SetEditHelpId( HID_PASSWD_TABLE );
- pDlg->ShowExtras( SHOWEXTRAS_CONFIRM );
+ ScTableProtection aNewProtect;
+ pDlg->WriteData(aNewProtect);
+ ProtectSheet(nTab, aNewProtect);
+ if (!pReqArgs)
+ {
+ rReq.AppendItem( SfxBoolItem(FID_PROTECT_TABLE, true) );
+ rReq.Done();
+ }
+ }
+ }
+#else
+ auto_ptr<SfxPasswordDialog> pDlg;
+ String aPassword;
+ BOOL bCancel = FALSE;
+ bool bNewProtection = ! bOldProtection;
- if (pDlg->Execute() == RET_OK)
- aPassword = pDlg->GetPassword();
- else
- bCancel = TRUE;
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FID_PROTECT_TABLE, &pItem ) )
+ bNewProtection = ((const SfxBoolItem*)pItem)->GetValue();
+ if( bNewProtection == bOldProtection )
+ {
+ rReq.Ignore();
+ break;
+ }
+ }
- delete pDlg;
- }
+ if ( bOldProtection)
+ {
+ // Unprotect a protected sheet.
- if( !bCancel )
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ if (pProtect && pProtect->isProtectedWithPass())
{
- if ( bOldProtection )
- Unprotect( nTab, aPassword );
+ String aText( ScResId(SCSTR_PASSWORDOPT) );
+ pDlg.reset(new SfxPasswordDialog(GetDialogParent(), &aText));
+ pDlg->SetText( ScResId(SCSTR_UNPROTECTTAB) );
+ pDlg->SetMinLen( 0 );
+ pDlg->SetHelpId( FID_PROTECT_TABLE );
+ pDlg->SetEditHelpId( HID_PASSWD_TABLE );
+
+ if (pDlg->Execute() == RET_OK)
+ aPassword = pDlg->GetPassword();
else
- {
- pScMod->InputEnterHandler();
+ bCancel = TRUE;
+ }
- Protect( nTab, aPassword );
- }
+ if (!pReqArgs)
+ {
+ rReq.AppendItem( SfxBoolItem(FID_PROTECT_TABLE, false) );
+ rReq.Done();
+ }
+ }
+ else
+ {
+ String aText( ScResId(SCSTR_PASSWORDOPT) );
- if( !pReqArgs )
- {
- rReq.AppendItem( SfxBoolItem( FID_PROTECT_TABLE, bNewProtection ) );
- rReq.Done();
- }
+ pDlg.reset(new SfxPasswordDialog(GetDialogParent(), &aText));
+ pDlg->SetText( ScResId(SCSTR_PROTECTTAB) );
+ pDlg->SetMinLen( 0 );
+ pDlg->SetHelpId( FID_PROTECT_TABLE );
+ pDlg->SetEditHelpId( HID_PASSWD_TABLE );
+ pDlg->ShowExtras( SHOWEXTRAS_CONFIRM );
+
+ if (pDlg->Execute() == RET_OK)
+ aPassword = pDlg->GetPassword();
+ else
+ bCancel = TRUE;
+ }
+
+ if( !bCancel )
+ {
+ if ( bOldProtection )
+ Unprotect( nTab, aPassword );
+ else
+ {
+ pScMod->InputEnterHandler();
+
+ Protect( nTab, aPassword );
}
- TabChanged();
- UpdateInputHandler(TRUE); // damit sofort wieder eingegeben werden kann
- SelectionChanged();
+ if( !pReqArgs )
+ {
+ rReq.AppendItem( SfxBoolItem( FID_PROTECT_TABLE, bNewProtection ) );
+ rReq.Done();
+ }
}
- break;
+#endif
+ TabChanged();
+ UpdateInputHandler(true); // damit sofort wieder eingegeben werden kann
+ SelectionChanged();
+ }
+ break;
case SID_OPT_LOCALE_CHANGED :
{ // locale changed, SYSTEM number formats changed => repaint cell contents
diff --git a/sc/source/ui/view/tabvwshh.cxx b/sc/source/ui/view/tabvwshh.cxx
index 5c6ca6843833..7526a3de19bd 100644
--- a/sc/source/ui/view/tabvwshh.cxx
+++ b/sc/source/ui/view/tabvwshh.cxx
@@ -43,6 +43,7 @@
#include <sfx2/request.hxx>
#include <basic/sbxcore.hxx>
#include <svtools/whiter.hxx>
+#include <vcl/msgbox.hxx>
#include "tabvwsh.hxx"
#include "client.hxx"
@@ -50,6 +51,10 @@
#include "docsh.hxx"
#include "sc.hrc"
#include "drwlayer.hxx" // GetVisibleName
+#include "retypepassdlg.hxx"
+#include "tabprotection.hxx"
+
+#include <memory>
using namespace com::sun::star;
@@ -270,6 +275,22 @@ BOOL ScTabViewShell::HasAccessibilityObjects()
return pAccessibilityBroadcaster != NULL;
}
+bool ScTabViewShell::ExecuteRetypePassDlg(ScPasswordHash eDesiredHash)
+{
+ using ::std::auto_ptr;
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ auto_ptr<ScRetypePassDlg> pDlg(new ScRetypePassDlg(GetDialogParent()));
+ pDlg->SetDataFromDocument(*pDoc);
+ pDlg->SetDesiredHash(eDesiredHash);
+ if (pDlg->Execute() != RET_OK)
+ return false;
+
+ pDlg->WriteNewDataToDocument(*pDoc);
+ return true;
+}
+
diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx
index a7b2f634bd6c..50ede74ab06b 100644
--- a/sc/source/ui/view/viewfun2.cxx
+++ b/sc/source/ui/view/viewfun2.cxx
@@ -2197,7 +2197,7 @@ BOOL ScViewFunc::DeleteTables(const SvShorts &TheTabs, BOOL bRecord )
pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) );
if ( pDoc->IsTabProtected( nTab ) )
- pUndoDoc->SetTabProtection( nTab, TRUE, pDoc->GetTabPassword( nTab ) );
+ pUndoDoc->SetTabProtection(nTab, pDoc->GetTabProtection(nTab));
// Drawing-Layer muss sein Undo selbst in der Hand behalten !!!
// pUndoDoc->TransferDrawPage(pDoc, nTab,nTab);
@@ -2612,7 +2612,7 @@ void ScViewFunc::MoveTable( USHORT nDestDocNo, SCTAB nDestTab, BOOL bCopy )
}
if ( nErrVal > 0 && pDoc->IsTabProtected( TheTabs[i] ) )
- pDestDoc->SetTabProtection( nDestTab1, TRUE, pDoc->GetTabPassword( TheTabs[i] ) );
+ pDestDoc->SetTabProtection(nDestTab1, pDoc->GetTabProtection(TheTabs[i]));
nDestTab1++;
}
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index 015c5fd2c083..62a8e7713d92 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -2546,6 +2546,36 @@ void ScViewFunc::ModifyCellSize( ScDirection eDir, BOOL bOptimal )
ShowAllCursors();
}
+void ScViewFunc::ProtectSheet( SCTAB nTab, const ScTableProtection& rProtect )
+{
+ if (nTab == TABLEID_DOC)
+ return;
+
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScDocFunc aFunc(*pDocSh);
+ bool bUndo(pDoc->IsUndoEnabled());
+
+ // modifying several tables is handled here
+
+ if (bUndo)
+ {
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_PROTECT_TAB );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+ }
+
+ SCTAB nCount = pDocSh->GetDocument()->GetTableCount();
+ for ( SCTAB i=0; i<nCount; i++ )
+ if ( rMark.GetTableSelect(i) )
+ aFunc.ProtectSheet(i, rProtect);
+
+ if (bUndo)
+ pDocSh->GetUndoManager()->LeaveListAction();
+
+ UpdateLayerLocks(); //! broadcast to all views
+}
+
void ScViewFunc::Protect( SCTAB nTab, const String& rPassword )
{
ScMarkData& rMark = GetViewData()->GetMarkData();