ooo-build r12657 - in trunk: . patches/dev300 patches/unittesting
- From: kyoshida svn gnome org
- To: svn-commits-list gnome org
- Subject: ooo-build r12657 - in trunk: . patches/dev300 patches/unittesting
- Date: Fri, 23 May 2008 23:53:50 +0000 (UTC)
Author: kyoshida
Date: Fri May 23 23:53:50 2008
New Revision: 12657
URL: http://svn.gnome.org/viewvc/ooo-build?rev=12657&view=rev
Log:
2008-05-23 Kohei Yoshida <kyoshida novell com>
* patches/dev300/cws-scsheetprotection02-sc.diff:
* patches/dev300/cws-scsheetprotection02-sfx2.diff:
* patches/dev300/cws-scsheetprotection02-svx.diff: extracted from
scsheetprotection02 CWS (i#60305, i#71468, i#84766).
* patches/dev300/sc-datapilot-dynamic-range.diff: fixed for > m12.
* patches/dev300/sc-datapilot-dynamic-range-m12.diff: added for <= m12.
* patches/dev300/webdav-locking-serve-dav-uri-m12.diff:
* patches/unittesting/unittesting-ucb-m12.diff: added for <= m12.
* patches/dev300/apply: worked on supporting dev300-m13.
Added:
trunk/patches/dev300/cws-scsheetprotection02-sc.diff
trunk/patches/dev300/cws-scsheetprotection02-sfx2.diff
trunk/patches/dev300/cws-scsheetprotection02-svx.diff
trunk/patches/dev300/sc-datapilot-dynamic-range-m12.diff
trunk/patches/dev300/webdav-locking-serve-dav-uri-m12.diff
trunk/patches/unittesting/unittesting-ucb-m12.diff
Modified:
trunk/ChangeLog
trunk/patches/dev300/apply
trunk/patches/dev300/sc-datapilot-dynamic-range.diff
Modified: trunk/patches/dev300/apply
==============================================================================
--- trunk/patches/dev300/apply (original)
+++ trunk/patches/dev300/apply Fri May 23 23:53:50 2008
@@ -594,8 +594,13 @@
# Implement uploading the changed stream to the server
webdav-locking-stream-can-save.diff, n#346711, i#29152, jholesov
+[ GnomeVFS > dev300-m12 ]
# Serve dav:// and webdav:// protocols in the WebDAV UCP
-webdav-locking-serve-dav-uri.diff, n#346713, i#29152, jholesov
+#FIXME webdav-locking-serve-dav-uri.diff, n#346713, i#29152, jholesov
+
+[ GnomeVFS <= dev300-m12 ]
+# Serve dav:// and webdav:// protocols in the WebDAV UCP
+webdav-locking-serve-dav-uri-m12.diff, n#346713, i#29152, jholesov
# Fix the runtime for neon 0.24
webdav-locking-neon24.diff, n#357048, i#29152, jholesov
@@ -676,10 +681,16 @@
# Autofill doesnt fill filtered rows bxc 62499
sc-filters-fill-fix.diff, jody
+[ CalcFixes > dev300-m12 ]
# Support modification of data source range in DataPilot after table output has
# been generated.
sc-datapilot-dynamic-range.diff, i#23658, kohei
+[ CalcFixes <= dev300-m12 ]
+# Support modification of data source range in DataPilot after table output has
+# been generated.
+sc-datapilot-dynamic-range-m12.diff, i#23658, kohei
+
# Provision for data-pilot to give autoformat bxc #62162
#
# Upstream has already rejected this patch, and closed the issue as WONTFIX.
@@ -753,11 +764,18 @@
# able to paste it elsewhere (similar to Insert Cut Cells in Excel)
sc-delete-rows-columns-remembers-content.diff, i#71921, jholesov
+[ CalcFixes < dev300-m12 ]
# load, store and save the sheet protection options from and to an Excel file,
# and use that information to constrain cell cursor movement when the sheet is
# protected.
sc-sheet-protection-options.diff, i#71468, kohei
+[ CalcFixes >= dev300-m12 ]
+cws-scsheetprotection02-sc.diff, i#60305, i#71468, i#84766, kohei
+cws-scsheetprotection02-sfx2.diff, i#60305, i#71468, i#84766, kohei
+cws-scsheetprotection02-svx.diff, i#60305, i#71468, i#84766, kohei
+
+[ CalcFixes ]
# Ensure that Print Preview is consistent with Print output.
sc-print-selected-sheets.diff, n#335684, i#45497, jonp
@@ -2089,7 +2107,6 @@
unittesting-testtools.diff
unittesting-toolkit.diff
unittesting-tools.diff
-unittesting-ucb.diff
unittesting-ucbhelper.diff
unittesting-udkapi.diff
unittesting-vcl.diff
@@ -2100,6 +2117,12 @@
unittesting-xmlscript.diff
unittesting-xmlsecurity.diff
+[ UnitTesting > dev300-m12 ]
+#FIXME unittesting-ucb.diff
+
+[ UnitTesting <= dev300-m12 ]
+unittesting-ucb-m12.diff
+
[ UnitBootstrap ]
SectionOwner => michael
SectionIssue => i#86525
Added: trunk/patches/dev300/cws-scsheetprotection02-sc.diff
==============================================================================
--- (empty file)
+++ trunk/patches/dev300/cws-scsheetprotection02-sc.diff Fri May 23 23:53:50 2008
@@ -0,0 +1,7448 @@
+? sc/sc.vpj
+Index: sc/inc/document.hxx
+===================================================================
+RCS file: /cvs/sc/sc/inc/document.hxx,v
+retrieving revision 1.112
+retrieving revision 1.109.28.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.112 -r1.109.28.3
+--- sc/inc/document.hxx 14 May 2008 09:49:46 -0000 1.112
++++ sc/inc/document.hxx 23 May 2008 01:50:10 -0000 1.109.28.3
+@@ -88,6 +88,7 @@
+ class ScDetOpData;
+ class ScDetOpList;
+ class ScDocOptions;
++class ScDocProtection;
+ class ScDocumentPool;
+ class ScDrawLayer;
+ class ScExtDocOptions;
+@@ -103,6 +104,7 @@
+ class ScStyleSheet;
+ class ScStyleSheetPool;
+ class ScTable;
++class ScTableProtection;
+ class ScTokenArray;
+ class ScValidationData;
+ class ScValidationDataList;
+@@ -275,7 +277,7 @@
+
+ ScFieldEditEngine* pCacheFieldEditEngine;
+
+- com::sun::star::uno::Sequence<sal_Int8> aProtectPass;
++ ::std::auto_ptr<ScDocProtection> pDocProtection;
+ String aDocName; // opt: Dokumentname
+ ScRangePairListRef xColNameRanges;
+ ScRangePairListRef xRowNameRanges;
+@@ -339,7 +341,6 @@
+
+ ScLkUpdMode eLinkMode;
+
+- BOOL bProtected;
+ BOOL bAutoCalc; // Automatisch Berechnen
+ BOOL bAutoCalcShellDisabled; // in/von/fuer ScDocShell disabled
+ // ob noch ForcedFormulas berechnet werden muessen,
+@@ -518,13 +519,16 @@
+ inline SCTAB GetTableCount() const { return nMaxTableNumber; }
+ SvNumberFormatterIndexTable* GetFormatExchangeList() const { return pFormatExchangeList; }
+
+- void SetDocProtection( BOOL bProtect, const com::sun::star::uno::Sequence <sal_Int8>& aPass );
+- void SetTabProtection( SCTAB nTab, BOOL bProtect, const com::sun::star::uno::Sequence <sal_Int8>& aPass );
++ ScDocProtection* GetDocProtection() const;
++ void SetDocProtection(bool bProtect, const String& aPassText);
++ void SetDocProtection(const ScDocProtection* pProtect);
+ BOOL IsDocProtected() const;
+ BOOL IsDocEditable() const;
+ 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;
++ ScTableProtection* GetTabProtection( SCTAB nTab ) const;
++ void SetTabProtection(SCTAB nTab, bool bProtect, const String& aPassText);
++ void SetTabProtection(SCTAB nTab, const ScTableProtection* pProtect);
++ void CopyTabProtection(SCTAB nTabSrc, SCTAB nTabDest);
+
+ void LockTable(SCTAB nTab);
+ void UnlockTable(SCTAB nTab);
+@@ -1484,6 +1488,8 @@
+
+
+ private:
++ ScDocument(const ScDocument& r); // disabled with no definition
++
+ void SetAutoFilterFlags();
+ void FindMaxRotCol( SCTAB nTab, RowInfo* pRowInfo, SCSIZE nArrCount,
+ SCCOL nX1, SCCOL nX2 ) const;
+Index: sc/inc/sc.hrc
+===================================================================
+RCS file: /cvs/sc/sc/inc/sc.hrc,v
+retrieving revision 1.62
+retrieving revision 1.62.30.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.62 -r1.62.30.3
+--- sc/inc/sc.hrc 10 Apr 2008 18:49:17 -0000 1.62
++++ sc/inc/sc.hrc 20 May 2008 00:25:46 -0000 1.62.30.3
+@@ -1622,7 +1622,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; }
+Index: sc/inc/scextopt.hxx
+===================================================================
+RCS file: /cvs/sc/sc/inc/scextopt.hxx,v
+retrieving revision 1.13
+retrieving revision 1.12.694.4
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.13 -r1.12.694.4
+--- sc/inc/scextopt.hxx 10 Apr 2008 18:50:45 -0000 1.13
++++ sc/inc/scextopt.hxx 22 May 2008 21:44:02 -0000 1.12.694.4
+@@ -46,8 +46,6 @@
+ 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();
+ };
+Index: sc/inc/table.hxx
+===================================================================
+RCS file: /cvs/sc/sc/inc/table.hxx,v
+retrieving revision 1.35
+retrieving revision 1.34.28.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.35 -r1.34.28.3
+--- sc/inc/table.hxx 10 Apr 2008 18:57:06 -0000 1.35
++++ sc/inc/table.hxx 8 May 2008 23:23:38 -0000 1.34.28.3
+@@ -39,6 +39,8 @@
+ #include "sortparam.hxx"
+ #include "compressedarray.hxx"
+
++#include <memory>
++
+ namespace utl {
+ class SearchParam;
+ class TextSearch;
+@@ -65,6 +67,7 @@
+ class ScSortInfoArray;
+ class ScStyleSheet;
+ class ScTableLink;
++class ScTableProtection;
+ class ScUserListData;
+ class ScIndexMap;
+ struct RowInfo;
+@@ -102,8 +105,7 @@
+ 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,11 @@
+ 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(BOOL bProtect, const com::sun::star::uno::Sequence<sal_Int8>& rPasswd);
++ void SetProtection(bool bProtect, const String& aPassText);
++ void SetProtection(const ScTableProtection* pProtect);
++ ScTableProtection* GetProtection();
+
+ Size GetPageSize() const;
+ void SetPageSize( const Size& rSize );
+Index: sc/inc/tabprotection.hxx
+===================================================================
+RCS file: sc/inc/tabprotection.hxx
+diff -N sc/inc/tabprotection.hxx
+--- /dev/null 1 Jan 1970 00:00:00 -0000
++++ sc/inc/tabprotection.hxx 20 May 2008 05:17:39 -0000 1.1.4.4
+@@ -0,0 +1,166 @@
++/*************************************************************************
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: tabprotection.hxx,v $
++ *
++ * $Revision: 1.1.4.4 $
++ *
++ * last change: $Author: kohei $ $Date: 2008/05/20 05:17:39 $
++ *
++ * The Contents of this file are made available subject to
++ * the terms of GNU Lesser General Public License Version 2.1.
++ *
++ *
++ * GNU Lesser General Public License Version 2.1
++ * =============================================
++ * Copyright 2005 by Sun Microsystems, Inc.
++ * 901 San Antonio Road, Palo Alto, CA 94303, USA
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License version 2.1, as published by the Free Software Foundation.
++ *
++ * This library 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 for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ *
++ ************************************************************************/
++
++#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 <memory>
++
++class ScTableProtectionImpl;
++
++enum ScPasswordHash
++{
++ PASSHASH_OOO = 0,
++ PASSHASH_XL
++};
++
++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 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:
++ ::std::auto_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 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:
++ ::std::auto_ptr<ScTableProtectionImpl> mpImpl;
++};
++
++
++#endif
+Index: sc/inc/warnpassword.hxx
+===================================================================
+RCS file: /cvs/sc/sc/inc/warnpassword.hxx,v
+retrieving revision 1.4
+retrieving revision 1.4.30.1
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.4 -r1.4.30.1
+--- sc/inc/warnpassword.hxx 10 Apr 2008 19:02:48 -0000 1.4
++++ sc/inc/warnpassword.hxx 22 May 2008 21:47:09 -0000 1.4.30.1
+@@ -31,7 +31,7 @@
+ #ifndef SC_WARNPASSWORD_HXX
+ #define SC_WARNPASSWORD_HXX
+
+-
++#if 0
+
+ class SfxMedium;
+ /** Static API helper functions. */
+@@ -46,6 +46,7 @@
+ static bool WarningOnPassword( SfxMedium& rMedium );
+ };
+
++#endif
+
+ #endif
+
+Index: sc/source/core/data/documen2.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/core/data/documen2.cxx,v
+retrieving revision 1.73
+retrieving revision 1.71.28.4
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.73 -r1.71.28.4
+--- sc/source/core/data/documen2.cxx 14 May 2008 09:50:52 -0000 1.73
++++ sc/source/core/data/documen2.cxx 23 May 2008 01:50:49 -0000 1.71.28.4
+@@ -138,6 +138,7 @@
+ pChangeViewSettings( NULL ),
+ pScriptTypeData( NULL ),
+ pCacheFieldEditEngine( NULL ),
++ pDocProtection( NULL ),
+ pViewOptions( NULL ),
+ pDocOptions( NULL ),
+ pExtDocOptions( NULL ),
+@@ -161,7 +162,6 @@
+ nHardRecalcState(0),
+ nVisibleTab( 0 ),
+ eLinkMode(LM_UNKNOWN),
+- bProtected( FALSE ),
+ bAutoCalc( eMode == SCDOCMODE_DOCUMENT ),
+ bAutoCalcShellDisabled( FALSE ),
+ bForcedFormulaPending( FALSE ),
+@@ -602,6 +602,7 @@
+
+ BOOL ScDocument::Load( SvStream& rStream, ScProgress* pProgress )
+ {
++#if 0
+ bLoadingDone = FALSE;
+
+ //----------------------------------------------------
+@@ -956,10 +957,13 @@
+ bLoadingDone = TRUE;
+
+ return !bError;
++#endif
++ return false;
+ }
+
+ BOOL ScDocument::Save( SvStream& rStream, ScProgress* pProgress ) const
+ {
++#if 0
+ ((ScDocument*)this)->bLoadingDone = FALSE; // nicht zwischendrin reinpfuschen lassen
+
+ ((ScDocument*)this)->bLostData = FALSE; // wird beim Speichern gesetzt
+@@ -1193,6 +1197,8 @@
+ ((ScDocument*)this)->bLoadingDone = TRUE;
+
+ return ( rStream.GetError() == SVSTREAM_OK );
++#endif
++ return false;
+ }
+
+ void ScDocument::SetLostData()
+Index: sc/source/core/data/documen3.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/core/data/documen3.cxx,v
+retrieving revision 1.42
+retrieving revision 1.40.80.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.42 -r1.40.80.3
+--- sc/source/core/data/documen3.cxx 14 May 2008 09:51:05 -0000 1.42
++++ sc/source/core/data/documen3.cxx 23 May 2008 01:50:53 -0000 1.40.80.3
+@@ -78,6 +78,8 @@
+ #include "listenercalls.hxx"
+ #include "editutil.hxx" // ScPostIt EditTextObject
+ #include "postit.hxx"
++#include "svtools/PasswordHelper.hxx"
++#include "tabprotection.hxx"
+
+ using namespace com::sun::star;
+
+@@ -1690,28 +1692,37 @@
+ 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(bool bProtect, const String& aPassText)
+ {
+- if (VALIDTAB(nTab))
+- if (pTab[nTab])
+- pTab[nTab]->SetProtection( bProtect, rPasswd );
++ if (!pDocProtection.get())
++ pDocProtection.reset(new ScDocProtection);
++
++ pDocProtection->setProtected(bProtect);
++ pDocProtection->setPassword(aPassText);
++}
++
++void ScDocument::SetDocProtection(const ScDocProtection* pProtect)
++{
++ 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
+@@ -1724,19 +1735,34 @@
+ 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, bool bProtect, const String& aPassText)
+ {
+- if (VALIDTAB(nTab))
+- if (pTab[nTab])
+- return pTab[nTab]->GetPassword();
++ if (ValidTab(nTab) && pTab[nTab])
++ pTab[nTab]->SetProtection(bProtect, aPassText);
++}
+
+- DBG_ERROR("Falsche Tabellennummer");
+- return aProtectPass;
++void ScDocument::SetTabProtection(SCTAB nTab, const ScTableProtection* pProtect)
++{
++ if (!ValidTab(nTab))
++ return;
++
++ 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
+Index: sc/source/core/data/document.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/core/data/document.cxx,v
+retrieving revision 1.88
+retrieving revision 1.86.28.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.88 -r1.86.28.2
+--- sc/source/core/data/document.cxx 18 Apr 2008 11:32:11 -0000 1.88
++++ sc/source/core/data/document.cxx 6 May 2008 23:27:32 -0000 1.86.28.2
+@@ -90,6 +90,7 @@
+ #include "autonamecache.hxx"
+ #include "bcaslot.hxx"
+ #include "postit.hxx"
++#include "tabprotection.hxx"
+
+ struct ScDefaultAttr
+ {
+Index: sc/source/core/data/makefile.mk
+===================================================================
+RCS file: /cvs/sc/sc/source/core/data/makefile.mk,v
+retrieving revision 1.24
+retrieving revision 1.23.26.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.24 -r1.23.26.2
+--- sc/source/core/data/makefile.mk 10 Apr 2008 19:30:13 -0000 1.24
++++ sc/source/core/data/makefile.mk 6 May 2008 23:27:15 -0000 1.23.26.2
+@@ -107,6 +107,7 @@
+ $(SLO)$/table4.obj \
+ $(SLO)$/table5.obj \
+ $(SLO)$/table6.obj \
++ $(SLO)$/tabprotection.obj \
+ $(SLO)$/userdat.obj \
+ $(SLO)$/validat.obj \
+ $(SLO)$/postit.obj
+Index: sc/source/core/data/table1.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/core/data/table1.cxx,v
+retrieving revision 1.25
+retrieving revision 1.24.28.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.25 -r1.24.28.2
+--- sc/source/core/data/table1.cxx 10 Apr 2008 19:34:43 -0000 1.25
++++ sc/source/core/data/table1.cxx 6 May 2008 23:27:26 -0000 1.24.28.2
+@@ -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 @@
+ bPageSizeValid( FALSE ),
+ nRepeatStartX( SCCOL_REPEAT_NONE ),
+ nRepeatStartY( SCROW_REPEAT_NONE ),
+- bProtected( FALSE ),
++ pTabProtection( NULL ),
+ pColWidth( NULL ),
+ pRowHeight( NULL ),
+ pColFlags( NULL ),
+Index: sc/source/core/data/table2.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/core/data/table2.cxx,v
+retrieving revision 1.40
+retrieving revision 1.39.78.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.40 -r1.39.78.2
+--- sc/source/core/data/table2.cxx 10 Apr 2008 19:35:09 -0000 1.40
++++ sc/source/core/data/table2.cxx 6 May 2008 23:27:37 -0000 1.39.78.2
+@@ -294,7 +294,7 @@
+ // 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 ) );
+@@ -320,7 +320,7 @@
+ // 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 );
+@@ -363,7 +363,7 @@
+
+ // ggf. Formeln durch Werte ersetzen
+
+- if (bProtected)
++ if ( IsProtected() )
+ for (i = nCol1; i <= nCol2; i++)
+ pTable->aCol[i].RemoveProtected(nRow1, nRow2);
+ }
+@@ -408,7 +408,7 @@
+ // 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 ) );
+@@ -1438,7 +1438,7 @@
+ 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)
+ {
+@@ -1505,7 +1505,7 @@
+ 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)
+ {
+@@ -2809,11 +2809,16 @@
+ rStream >> bScenario;
+ rStream.ReadByteString( aComment, rStream.GetStreamCharSet() );
+
++ BOOL bProtected;
+ rStream >> bProtected;
+ String aPass;
+ rStream.ReadByteString( aPass, rStream.GetStreamCharSet() );
+ if (aPass.Len())
++ {
++ ::com::sun::star::uno::Sequence<sal_Int8> aProtectPass;
+ SvPasswordHelper::GetHashPassword(aProtectPass, aPass);
++ SetProtection(bProtected, aProtectPass);
++ }
+
+ BOOL bOutline;
+ rStream >> bOutline;
+@@ -3085,6 +3090,7 @@
+ rStream << bScenario;
+ rStream.WriteByteString( aComment, rStream.GetStreamCharSet() );
+
++ BOOL bProtected = IsProtected();
+ rStream << bProtected;
+ String aPass;
+ //rStream.WriteByteString( aProtectPass, rStream.GetStreamCharSet() );
+Index: sc/source/core/data/table5.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/core/data/table5.cxx,v
+retrieving revision 1.14
+retrieving revision 1.13.324.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.14 -r1.13.324.3
+--- sc/source/core/data/table5.cxx 10 Apr 2008 19:36:13 -0000 1.14
++++ sc/source/core/data/table5.cxx 8 May 2008 23:23:44 -0000 1.13.324.3
+@@ -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,42 @@
+ bPageSizeValid = FALSE;
+ }
+
++BOOL ScTable::IsProtected() const
++{
++ return pTabProtection.get() && pTabProtection->isProtected();
++}
++
++void ScTable::SetProtection(BOOL bProtect, const com::sun::star::uno::Sequence<sal_Int8>& rPasswd)
++{
++ if (!pTabProtection.get())
++ pTabProtection.reset(new ScTableProtection);
++
++ pTabProtection->setProtected( bProtect );
++ pTabProtection->setPasswordHash(rPasswd, PASSHASH_OOO);
++}
++
++void ScTable::SetProtection(bool bProtect, const String& aPassText)
++{
++ if (!pTabProtection.get())
++ pTabProtection.reset(new ScTableProtection);
++
++ pTabProtection->setProtected( bProtect );
++ pTabProtection->setPassword(aPassText);
++}
++
++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 )
+Index: sc/source/core/data/tabprotection.cxx
+===================================================================
+RCS file: sc/source/core/data/tabprotection.cxx
+diff -N sc/source/core/data/tabprotection.cxx
+--- /dev/null 1 Jan 1970 00:00:00 -0000
++++ sc/source/core/data/tabprotection.cxx 22 May 2008 22:31:10 -0000 1.1.4.6
+@@ -0,0 +1,436 @@
++/*************************************************************************
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: tabprotection.cxx,v $
++ *
++ * $Revision: 1.1.4.6 $
++ *
++ * last change: $Author: kohei $ $Date: 2008/05/22 22:31:10 $
++ *
++ * The Contents of this file are made available subject to
++ * the terms of GNU Lesser General Public License Version 2.1.
++ *
++ *
++ * GNU Lesser General Public License Version 2.1
++ * =============================================
++ * Copyright 2005 by Sun Microsystems, Inc.
++ * 901 San Antonio Road, Palo Alto, CA 94303, USA
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License version 2.1, as published by the Free Software Foundation.
++ *
++ * This library 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 for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ *
++ ************************************************************************/
++
++#include "tabprotection.hxx"
++#include "tools/debug.hxx"
++#include "svtools/PasswordHelper.hxx"
++
++#define DEBUG_TAB_PROTECTION 0
++
++using namespace ::com::sun::star;
++using ::com::sun::star::uno::Sequence;
++using ::rtl::OUString;
++
++// ============================================================================
++
++ScPassHashProtectable::~ScPassHashProtectable()
++{
++}
++
++// ============================================================================
++
++static sal_uInt16 lcl_getXLHashFromChar(const sal_Char* szPassword)
++{
++ sal_uInt16 cchPassword = 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) :
++ mpImpl(new ScTableProtectionImpl(*r.mpImpl.get()))
++{
++}
++
++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) :
++ mpImpl(new ScTableProtectionImpl(*r.mpImpl.get()))
++{
++}
++
++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);
++}
++
+Index: sc/source/filter/excel/excdoc.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/excel/excdoc.cxx,v
+retrieving revision 1.69
+retrieving revision 1.67.284.7
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.69 -r1.67.284.7
+--- sc/source/filter/excel/excdoc.cxx 13 May 2008 12:07:58 -0000 1.69
++++ sc/source/filter/excel/excdoc.cxx 23 May 2008 01:51:00 -0000 1.67.284.7
+@@ -73,7 +73,6 @@
+ #include "excdoc.hxx"
+ #include "namebuff.hxx"
+
+-#include "xcl97dum.hxx"
+ #include "xcl97rec.hxx"
+ #include "xcl97esc.hxx"
+ #include "xetable.hxx"
+@@ -86,6 +85,8 @@
+ #include "xepivot.hxx"
+ #include "XclExpChangeTrack.hxx"
+
++#include "tabprotection.hxx"
++
+
+ static String lcl_GetVbaTabName( SCTAB n )
+ {
+@@ -151,7 +152,16 @@
+ 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() )
+@@ -161,7 +171,8 @@
+ if( rCodeName.Len() )
+ Add( new XclCodename( rCodeName ) );
+ }
+- Add( new ExcDummy8_00b );
++
++ Add( new XclExpFnGroupCount );
+ }
+
+ // erst Namen- und Tabellen-Eintraege aufbauen
+@@ -181,15 +192,29 @@
+ 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)) );
++ Add( new XclExpPassHash(pProtect->getPasswordHash(PASSHASH_XL)) );
++ }
+
+ if( GetBiff() == EXC_BIFF8 )
+- Add( new ExcDummy8_040 );
++ {
++ Add( new XclExpProt4Rev );
++ Add( new XclExpProt4RevPass );
++ }
+
+ aRecList.AppendNewRecord( new XclExpWindow1( GetRoot() ) );
+
++ if ( GetBiff() == EXC_BIFF8 )
++ {
++ Add( new XclExpBoolRecord(0x0040, false) ); // BACKUP
++ Add( new XclExpBoolRecord(0x008D, false) ); // HIDEOBJ
++ }
++
+ if( GetBiff() <= EXC_BIFF5 )
+ {
+ Add( new ExcDummy_040 );
+@@ -198,9 +223,11 @@
+ }
+ 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
+ }
+
+ // Formatting: FONT, FORMAT, XF, STYLE, PALETTE
+@@ -259,10 +286,14 @@
+ aRecList.AppendRecord( CreateRecord( EXC_ID_EXTERNSHEET ) );
+ aRecList.AppendRecord( CreateRecord( EXC_ID_NAME ) );
+
++ Add( new XclExpUnknown01C1 );
++
+ // MSODRAWINGGROUP per-document data
+ Add( new XclMsodrawinggroup( rR, ESCHER_DggContainer ) );
+ // Shared string table: SST, EXTSST
+ aRecList.AppendRecord( CreateRecord( EXC_ID_SST ) );
++
++ Add( new XclExpUnknown0863 );
+ }
+
+ Add( new ExcEof );
+@@ -304,7 +335,7 @@
+ Add( new XclRefmode( rDoc ) );
+ Add( new XclIteration( rDoc ) );
+ Add( new XclDelta( rDoc ) );
+- Add( new ExcDummy8_02 );
++ Add( new XclExpBoolRecord(0x005F, true) ); // SAVERECALC
+ }
+
+ // GUTS (count & size of outline icons)
+@@ -321,8 +352,14 @@
+ // 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)) );
++ Add( new XclExpPassHash(pTabProtect->getPasswordHash(PASSHASH_XL)) );
++ }
+
+ // local link table: EXTERNCOUNT, EXTERNSHEET
+ if( eBiff <= EXC_BIFF5 )
+@@ -368,6 +405,9 @@
+
+ if( eBiff == EXC_BIFF8 )
+ {
++ // sheet protection options
++ Add( new XclExpSheetProtectOptions( GetRoot(), mnScTab ) );
++
+ // web queries
+ Add( new XclExpWebQueryBuffer( GetRoot() ) );
+
+Index: sc/source/filter/excel/excimp8.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/excel/excimp8.cxx,v
+retrieving revision 1.124
+retrieving revision 1.123.38.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.124 -r1.123.38.3
+--- sc/source/filter/excel/excimp8.cxx 10 Apr 2008 20:06:14 -0000 1.124
++++ sc/source/filter/excel/excimp8.cxx 22 May 2008 23:32:47 -0000 1.123.38.3
+@@ -163,12 +163,6 @@
+ }
+
+
+-void ImportExcel8:: WinProtection( void )
+-{
+- if( aIn.ReaduInt16() != 0 )
+- GetExtDocOptions().GetDocSettings().mbWinProtected = true;
+-}
+-
+ void ImportExcel8::Note( void )
+ {
+ GetObjectManager().ReadNote( maStrm );
+@@ -259,6 +253,11 @@
+ }
+ }
+
++void ImportExcel8::SheetProtection( void )
++{
++ GetSheetProtectBuffer().ReadOptions( aIn, GetCurrScTab() );
++}
++
+ bool lcl_hasVBAEnabled()
+ {
+ uno::Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY);
+@@ -303,6 +302,8 @@
+ pExcRoot->pAutoFilterBuffer->Apply();
+
+ GetWebQueryBuffer().Apply(); //! test if extant
++ GetSheetProtectBuffer().Apply();
++ GetDocProtectBuffer().Apply();
+
+ ImportExcel::PostDocLoad();
+
+Index: sc/source/filter/excel/excrecds.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/excel/excrecds.cxx,v
+retrieving revision 1.88
+retrieving revision 1.87.286.4
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.88 -r1.87.286.4
+--- sc/source/filter/excel/excrecds.cxx 10 Apr 2008 20:06:49 -0000 1.88
++++ sc/source/filter/excel/excrecds.cxx 22 May 2008 23:33:21 -0000 1.87.286.4
+@@ -99,6 +99,7 @@
+ #include "xcl97rec.hxx"
+
+
++using ::com::sun::star::uno::Sequence;
+
+ //--------------------------------------------------------- class ExcDummy_00 -
+ const BYTE ExcDummy_00::pMyData[] = {
+@@ -418,7 +419,9 @@
+ void ExcBundlesheetBase::UpdateStreamPos( XclExpStream& rStrm )
+ {
+ rStrm.SetSvStreamPos( nOwnPos );
++ rStrm.DisableEncryption();
+ rStrm << static_cast<sal_uInt32>(nStrPos);
++ rStrm.EnableEncryption();
+ }
+
+
+@@ -494,19 +497,41 @@
+ // XclExpWindowProtection ===============================================================
+
+ XclExpWindowProtection::XclExpWindowProtection(bool bValue) :
+- XclExpBoolRecord(EXC_ID_WINDOWPROTECT,bValue)
++ XclExpBoolRecord(EXC_ID_WINDOWPROTECT, bValue)
+ {
+ }
+
+ // 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 )
+ {
+Index: sc/source/filter/excel/impop.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/excel/impop.cxx,v
+retrieving revision 1.94
+retrieving revision 1.93.26.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.94 -r1.93.26.2
+--- sc/source/filter/excel/impop.cxx 10 Apr 2008 20:08:24 -0000 1.94
++++ sc/source/filter/excel/impop.cxx 6 May 2008 23:28:42 -0000 1.93.26.2
+@@ -90,6 +90,7 @@
+ #include "xiview.hxx"
+ #include "xilink.hxx"
+ #include "xiescher.hxx"
++#include "xicontent.hxx"
+
+ #include "excimp8.hxx"
+ #include "excform.hxx"
+@@ -418,14 +419,9 @@
+ }
+
+
+-BOOL ImportExcel::Password( void )
++void ImportExcel::SheetPassword( void )
+ {
+- // POST: return = TRUE, wenn Password <> 0
+- UINT16 nPasswd;
+-
+- aIn >> nPasswd;
+-
+- return nPasswd != 0x0000;
++ GetSheetProtectBuffer().ReadPasswordHash( aIn, GetCurrScTab() );
+ }
+
+
+@@ -440,6 +436,12 @@
+ }
+
+
++void ImportExcel:: WinProtection( void )
++{
++ GetRoot().GetDocProtectBuffer().ReadWinProtect( aIn );
++}
++
++
+ void ImportExcel::Note( void )
+ {
+ XclAddress aXclPos;
+@@ -585,27 +587,24 @@
+ }
+
+
+-void ImportExcel::Protect( void )
++void ImportExcel::SheetProtect( void )
+ {
+- if( aIn.ReaduInt16() )
+- {
+- uno::Sequence<sal_Int8> aEmptyPass;
+- GetDoc().SetTabProtection( GetCurrScTab(), TRUE, aEmptyPass );
+- }
++ GetRoot().GetSheetProtectBuffer().ReadProtect( aIn, GetCurrScTab() );
+ }
+
+ void ImportExcel::DocProtect( void )
+ {
+- if( aIn.ReaduInt16() )
+- {
+- uno::Sequence<sal_Int8> aEmptyPass;
+- GetDoc().SetDocProtection( TRUE, aEmptyPass );
+- }
++ GetRoot().GetDocProtectBuffer().ReadDocProtect( aIn );
+ }
+
++void ImportExcel::DocPasssword( void )
++{
++ GetRoot().GetDocProtectBuffer().ReadPasswordHash( aIn );
++}
+
+ void ImportExcel::Codepage( void )
+ {
++ maStrm.EnableDecryption();
+ SetCodePage( maStrm.ReaduInt16() );
+ }
+
+Index: sc/source/filter/excel/read.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/excel/read.cxx,v
+retrieving revision 1.70
+retrieving revision 1.69.80.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.70 -r1.69.80.2
+--- sc/source/filter/excel/read.cxx 10 Apr 2008 20:09:20 -0000 1.70
++++ sc/source/filter/excel/read.cxx 6 May 2008 23:28:32 -0000 1.69.80.2
+@@ -363,7 +363,7 @@
+ 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]
+@@ -477,7 +477,7 @@
+ 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:
+@@ -603,7 +603,7 @@
+ 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;
+@@ -902,6 +902,7 @@
+ }
+ break;
+ case 0x12: DocProtect(); break; // PROTECT [ 5678]
++ case 0x13: DocPasssword(); break;
+ case 0x19: WinProtection(); break;
+ case 0x2F: // FILEPASS [ 2345 ]
+ eLastErr = XclImpDecryptHelper::ReadFilepass( maStrm );
+@@ -1046,7 +1047,8 @@
+ 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 ]
+@@ -1062,6 +1064,7 @@
+ case 0x0221: Array34(); break; // ARRAY [ 34 ]
+ case 0x0225: Defrowheight345();break;//DEFAULTROWHEI[ 345 ]
+ case 0x04BC: Shrfmla(); break; // SHRFMLA [ 5 ]
++ case 0x0867: SheetProtection(); break; // SHEETPROTECTION
+ }
+ }
+ break;
+Index: sc/source/filter/excel/xecontent.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/excel/xecontent.cxx,v
+retrieving revision 1.23
+retrieving revision 1.22.80.4
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.23 -r1.22.80.4
+Index: sc/source/filter/excel/xeroot.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/excel/xeroot.cxx,v
+retrieving revision 1.23
+retrieving revision 1.22.152.6
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.23 -r1.22.152.6
+--- sc/source/filter/excel/xeroot.cxx 10 Apr 2008 20:13:37 -0000 1.23
++++ sc/source/filter/excel/xeroot.cxx 22 May 2008 21:42:34 -0000 1.22.152.6
+@@ -32,7 +32,11 @@
+ #include "precompiled_sc.hxx"
+ #include "xeroot.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 "xltracer.hxx"
+ #include "xehelper.hxx"
+ #include "xeformula.hxx"
+@@ -42,8 +46,10 @@
+ #include "xecontent.hxx"
+ #include "xepivot.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 @@
+ 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;
+Index: sc/source/filter/excel/xestream.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/excel/xestream.cxx,v
+retrieving revision 1.11
+retrieving revision 1.10.324.6
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.11 -r1.10.324.6
+--- sc/source/filter/excel/xestream.cxx 10 Apr 2008 20:13:53 -0000 1.11
++++ sc/source/filter/excel/xestream.cxx 22 May 2008 23:34:37 -0000 1.10.324.6
+@@ -34,6 +34,9 @@
+ #include "xlstring.hxx"
+ #include "xeroot.hxx"
+
++#define DEBUG_XL_ENCRYPTION 0
++
++using ::std::vector;
+
+ // ============================================================================
+
+@@ -63,16 +66,19 @@
+ 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;
+@@ -84,6 +90,86 @@
+ 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;
+@@ -98,9 +184,21 @@
+ 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;
+@@ -236,6 +334,26 @@
+ 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" );
+@@ -327,3 +445,187 @@
+
+ // ============================================================================
+
++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_uInt16 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 = 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_uInt16 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!!");
++
++ sal_Size nRet = rStrm.Write(&aBytes[nPos], nEncBytes);
++ DBG_ASSERT(nRet == nEncBytes, "XclExpBiff8Encrypter::EncryptBytes: fail to write to stream!!");
++
++ nStrmPos = rStrm.Tell();
++ nBlockOffset = GetOffsetInBlock(nStrmPos);
++ nBlockPos = GetBlockPos(nStrmPos);
++ if (nBlockOffset == 0)
++ maCodec.InitCipher(nBlockPos);
++
++ nBytesLeft -= nEncBytes;
++ nPos += nEncBytes;
++ }
++ mnOldPos = nStrmPos;
++}
+Index: sc/source/filter/excel/xetable.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/excel/xetable.cxx,v
+retrieving revision 1.18
+retrieving revision 1.17.80.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.18 -r1.17.80.3
+Index: sc/source/filter/excel/xicontent.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/excel/xicontent.cxx,v
+retrieving revision 1.31
+retrieving revision 1.30.80.6
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.31 -r1.30.80.6
+--- sc/source/filter/excel/xicontent.cxx 10 Apr 2008 20:15:50 -0000 1.31
++++ sc/source/filter/excel/xicontent.cxx 22 May 2008 23:35:38 -0000 1.30.80.6
+@@ -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 ========================================================
+
+@@ -1074,11 +1081,182 @@
+ };
+ // set decrypter at import stream
+ rStrm.SetDecrypter( xDecr );
+- // remember encryption for export
+- rStrm.GetRoot().GetExtDocOptions().GetDocSettings().mbEncrypted = true;
++
++ // 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.is() ? xDecr->GetError() : EXC_ENCR_ERROR_UNSUPP_CRYPT;
+ }
+
++// 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 (mnPassHash)
++ {
++ // 16-bit password pash.
++ Sequence<sal_Int8> aPass(2);
++ aPass[0] = (mnPassHash >> 8) & 0xFF;
++ aPass[1] = mnPassHash & 0xFF;
++ pProtect->setPasswordHash(aPass, PASSHASH_XL);
++ }
++
++ // 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);
++
++ // 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);
++ }
++
++ // 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;
++}
++
+ // ============================================================================
+
+Index: sc/source/filter/excel/xilink.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/excel/xilink.cxx,v
+retrieving revision 1.24
+retrieving revision 1.23.28.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.24 -r1.23.28.2
+--- sc/source/filter/excel/xilink.cxx 10 Apr 2008 20:16:58 -0000 1.24
++++ sc/source/filter/excel/xilink.cxx 6 May 2008 23:28:59 -0000 1.23.28.2
+@@ -264,6 +264,7 @@
+ 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();
+Index: sc/source/filter/excel/xiroot.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/excel/xiroot.cxx,v
+retrieving revision 1.24
+retrieving revision 1.23.286.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.24 -r1.23.286.3
+--- sc/source/filter/excel/xiroot.cxx 10 Apr 2008 20:18:01 -0000 1.24
++++ sc/source/filter/excel/xiroot.cxx 6 May 2008 23:28:52 -0000 1.23.286.3
+@@ -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 @@
+ 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() ) );
+@@ -224,6 +227,18 @@
+ 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;
+@@ -247,5 +262,18 @@
+ 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;
++ fprintf(stdout, "XclImpRoot::QueryPassword: password = '%s'\n",
++ OUStringToOString(rtl::OUString(mrImpData.maPassw), RTL_TEXTENCODING_UTF8).getStr());fflush(stdout);
++ }
++ return mrImpData.maPassw;
++}
++
+ // ============================================================================
+
+Index: sc/source/filter/excel/xistream.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/excel/xistream.cxx,v
+retrieving revision 1.22
+retrieving revision 1.21.322.5
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.22 -r1.21.322.5
+--- sc/source/filter/excel/xistream.cxx 10 Apr 2008 20:18:15 -0000 1.22
++++ sc/source/filter/excel/xistream.cxx 22 May 2008 23:56:02 -0000 1.21.322.5
+@@ -36,6 +36,8 @@
+ #include "xlstring.hxx"
+ #include "xiroot.hxx"
+
++#include <vector>
++
+ // ============================================================================
+ // Decryption
+ // ============================================================================
+@@ -97,11 +99,21 @@
+ 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 @@
+ // 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 @@
+ // init codec
+ maCodec.InitKey( mpnPassw, mpnDocId );
+ bValid = maCodec.VerifyKey( pnSaltData, pnSaltHash );
++
++ SetPassword(rPass);
+ }
+
+ SetHasValidPassword( bValid );
+Index: sc/source/filter/excel/xlroot.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/excel/xlroot.cxx,v
+retrieving revision 1.32
+retrieving revision 1.31.238.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.32 -r1.31.238.3
+--- sc/source/filter/excel/xlroot.cxx 10 Apr 2008 20:22:11 -0000 1.32
++++ sc/source/filter/excel/xlroot.cxx 6 May 2008 23:29:13 -0000 1.31.238.3
+@@ -91,8 +91,7 @@
+ mxRD( new RootData ),//!
+ mnCharWidth( 110 ),
+ mnScTab( 0 ),
+- mbExport( bExport ),
+- mbHasPassw( false )
++ mbExport( bExport )
+ {
+ // default script type, e.g. for empty cells
+ switch( ScGlobal::GetDefaultScriptType() )
+@@ -198,17 +197,6 @@
+ }
+ }
+
+-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();
+Index: sc/source/filter/inc/excimp8.hxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/inc/excimp8.hxx,v
+retrieving revision 1.70
+retrieving revision 1.69.80.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.70 -r1.69.80.2
+--- sc/source/filter/inc/excimp8.hxx 10 Apr 2008 20:30:57 -0000 1.70
++++ sc/source/filter/inc/excimp8.hxx 6 May 2008 23:27:53 -0000 1.69.80.2
+@@ -62,7 +62,6 @@
+ void Delta( void ); // 0x10
+ void Iteration( void ); // 0x11
+ void Note( void ); // 0x1C
+- void WinProtection( void ); // 0x19
+ void Boundsheet( void ); // 0x85
+ void FilterMode( void ); // 0x9B
+ void AutoFilterInfo( void ); // 0x9D
+@@ -74,6 +73,7 @@
+
+ void Hlink( void ); // 0x01B8
+ void Codename( BOOL bWBGlobals ); // 0x01BA
++ void SheetProtection( void ); // 0x0867
+
+ virtual void EndSheet( void );
+ virtual void PostDocLoad( void );
+Index: sc/source/filter/inc/excrecds.hxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/inc/excrecds.hxx,v
+retrieving revision 1.50
+retrieving revision 1.49.324.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.50 -r1.49.324.2
+--- sc/source/filter/inc/excrecds.hxx 10 Apr 2008 20:31:14 -0000 1.50
++++ sc/source/filter/inc/excrecds.hxx 6 May 2008 23:27:50 -0000 1.49.324.2
+@@ -244,10 +244,23 @@
+ };
+
+ // 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;
+ };
+
+
+Index: sc/source/filter/inc/fdumper.hxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/inc/fdumper.hxx,v
+retrieving revision 1.9
+retrieving revision 1.7.320.4
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.9 -r1.7.320.4
+Index: sc/source/filter/inc/imp_op.hxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/inc/imp_op.hxx,v
+retrieving revision 1.42
+retrieving revision 1.41.286.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.42 -r1.41.286.2
+--- sc/source/filter/inc/imp_op.hxx 10 Apr 2008 20:35:51 -0000 1.42
++++ sc/source/filter/inc/imp_op.hxx 6 May 2008 23:28:08 -0000 1.41.286.2
+@@ -136,9 +136,11 @@
+ 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 Note( void ); // 0x1C
+ void Columndefault( void ); // 0x20
+ void Array25( void ); // 0x21
+Index: sc/source/filter/inc/xcl97rec.hxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/inc/xcl97rec.hxx,v
+retrieving revision 1.48
+retrieving revision 1.47.338.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.48 -r1.47.338.3
+--- sc/source/filter/inc/xcl97rec.hxx 10 Apr 2008 20:42:30 -0000 1.48
++++ sc/source/filter/inc/xcl97rec.hxx 6 May 2008 23:27:57 -0000 1.47.338.3
+@@ -35,6 +35,8 @@
+ #include "xcl97esc.hxx"
+ #include "xlstyle.hxx"
+
++#include <vector>
++
+ // --- class XclMsodrawing_Base --------------------------------------
+
+ class XclMsodrawing_Base
+@@ -57,29 +59,26 @@
+
+ // --- 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 @@
+ UINT16 nEscherType = 0,
+ sal_Size nInitialSize = 0 );
+ virtual ~XclMsodrawing();
+-
+- virtual UINT16 GetNum() const;
+- virtual sal_Size GetLen() const;
+ };
+
+
+@@ -484,23 +480,24 @@
+ 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
+ {
+@@ -556,5 +553,162 @@
+ XclRefmode( const ScDocument& );
+ };
+
++// ============================================================================
++
++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 XclExpUnknown01C1 : public XclExpDummyRecord
++{
++public:
++ explicit XclExpUnknown01C1();
++};
++
++// ============================================================================
++
++class XclExpUnknown0863 : public XclExpDummyRecord
++{
++public:
++ explicit XclExpUnknown0863();
++};
++
+
+ #endif // _XCL97REC_HXX
+Index: sc/source/filter/inc/xeroot.hxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/inc/xeroot.hxx,v
+retrieving revision 1.21
+retrieving revision 1.20.380.5
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.21 -r1.20.380.5
+--- sc/source/filter/inc/xeroot.hxx 10 Apr 2008 20:45:28 -0000 1.21
++++ sc/source/filter/inc/xeroot.hxx 22 May 2008 21:42:40 -0000 1.20.380.5
+@@ -154,7 +154,12 @@
+ @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;
+
+Index: sc/source/filter/inc/xestream.hxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/inc/xestream.hxx,v
+retrieving revision 1.8
+retrieving revision 1.7.494.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.8 -r1.7.494.3
+--- sc/source/filter/inc/xestream.hxx 10 Apr 2008 20:45:44 -0000 1.8
++++ sc/source/filter/inc/xestream.hxx 6 May 2008 23:28:00 -0000 1.7.494.3
+@@ -35,6 +35,9 @@
+
+ #include "xlstream.hxx"
+
++#include <svx/mscodec.hxx>
++#include <vector>
++
+ /* ============================================================================
+ Output stream class for Excel export
+ - CONTINUE record handling
+@@ -42,6 +45,8 @@
+ ============================================================================ */
+
+ 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
+@@ -100,14 +105,14 @@
+ /** 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 );
+@@ -148,6 +153,14 @@
+ /** 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 );
+@@ -170,6 +183,9 @@
+ 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.
+@@ -187,64 +203,51 @@
+
+ // ----------------------------------------------------------------------------
+
+-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;
++};
+
+ #endif
+
+Index: sc/source/filter/inc/xetable.hxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/inc/xetable.hxx,v
+retrieving revision 1.11
+retrieving revision 1.10.80.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.11 -r1.10.80.2
+--- sc/source/filter/inc/xetable.hxx 10 Apr 2008 20:46:38 -0000 1.11
++++ sc/source/filter/inc/xetable.hxx 6 May 2008 23:27:41 -0000 1.10.80.2
+@@ -1069,7 +1069,5 @@
+ XclExpDvalRef mxDval; /// Data validation with DVAL and DV records.
+ };
+
+-// ============================================================================
+-
+ #endif
+
+Index: sc/source/filter/inc/xicontent.hxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/inc/xicontent.hxx,v
+retrieving revision 1.16
+retrieving revision 1.15.80.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.16 -r1.15.80.2
+--- sc/source/filter/inc/xicontent.hxx 10 Apr 2008 20:47:26 -0000 1.16
++++ sc/source/filter/inc/xicontent.hxx 6 May 2008 23:28:03 -0000 1.15.80.2
+@@ -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 @@
+
+ // ============================================================================
+
++// 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
+
+Index: sc/source/filter/inc/xiroot.hxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/inc/xiroot.hxx,v
+retrieving revision 1.22
+retrieving revision 1.21.380.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.22 -r1.21.380.3
+--- sc/source/filter/inc/xiroot.hxx 10 Apr 2008 20:49:45 -0000 1.22
++++ sc/source/filter/inc/xiroot.hxx 6 May 2008 23:28:11 -0000 1.21.380.3
+@@ -61,6 +61,8 @@
+ class XclImpPageSettings;
+ class XclImpDocViewSettings;
+ class XclImpTabViewSettings;
++class XclImpSheetProtectBuffer;
++class XclImpDocProtectBuffer;
+
+ class _ScRangeListTabs;
+ class ExcelToSc;
+@@ -87,6 +89,8 @@
+ 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 @@
+ 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 @@
+ 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 @@
+ /** 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.
+ };
+Index: sc/source/filter/inc/xistream.hxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/inc/xistream.hxx,v
+retrieving revision 1.13
+retrieving revision 1.12.324.4
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.13 -r1.12.324.4
+--- sc/source/filter/inc/xistream.hxx 10 Apr 2008 20:50:03 -0000 1.13
++++ sc/source/filter/inc/xistream.hxx 22 May 2008 23:56:25 -0000 1.12.324.4
+@@ -73,6 +73,8 @@
+ @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 @@
+ /** 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 @@
+ 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.
+Index: sc/source/filter/inc/xlroot.hxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/inc/xlroot.hxx,v
+retrieving revision 1.31
+retrieving revision 1.30.238.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.31 -r1.30.238.2
+--- sc/source/filter/inc/xlroot.hxx 10 Apr 2008 20:54:26 -0000 1.31
++++ sc/source/filter/inc/xlroot.hxx 6 May 2008 23:27:47 -0000 1.30.238.2
+@@ -91,7 +91,6 @@
+ 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).
+@@ -115,7 +114,6 @@
+ 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,
+@@ -181,8 +179,6 @@
+ 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. */
+Index: sc/source/filter/starcalc/scflt.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/starcalc/scflt.cxx,v
+retrieving revision 1.25
+retrieving revision 1.24.26.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.25 -r1.24.26.2
+--- sc/source/filter/starcalc/scflt.cxx 10 Apr 2008 21:04:01 -0000 1.25
++++ sc/source/filter/starcalc/scflt.cxx 6 May 2008 23:29:31 -0000 1.24.26.2
+@@ -1148,9 +1148,9 @@
+ //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);
++// uno::Sequence<sal_Int8> aPass;
++// SvPasswordHelper::GetHashPassword(aPass, SC10TOSTRING( SheetProtect.PassWord ));
++// pDoc->SetDocProtection( SheetProtect.Protect, SC10TOSTRING( SheetProtect.PassWord ));
+ }
+
+
+@@ -1502,10 +1502,10 @@
+
+ //rStream.Read(&TabProtect, sizeof(TabProtect));
+ lcl_ReadTabProtect(rStream, TabProtect);
+- uno::Sequence<sal_Int8> aPass;
+- SvPasswordHelper::GetHashPassword(aPass, SC10TOSTRING( TabProtect.PassWord ));
++// uno::Sequence<sal_Int8> aPass;
++// SvPasswordHelper::GetHashPassword(aPass, SC10TOSTRING( TabProtect.PassWord ));
+
+- pDoc->SetTabProtection( static_cast<SCTAB>(Tab), TabProtect.Protect, aPass);
++ pDoc->SetTabProtection( static_cast<SCTAB>(Tab), TabProtect.Protect, SC10TOSTRING( TabProtect.PassWord ));
+
+ rStream >> TabNo;
+
+Index: sc/source/filter/xcl97/XclExpChangeTrack.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/xcl97/XclExpChangeTrack.cxx,v
+retrieving revision 1.26
+retrieving revision 1.25.324.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.26 -r1.25.324.2
+--- sc/source/filter/xcl97/XclExpChangeTrack.cxx 10 Apr 2008 21:04:41 -0000 1.26
++++ sc/source/filter/xcl97/XclExpChangeTrack.cxx 6 May 2008 23:29:27 -0000 1.25.324.2
+@@ -491,6 +491,7 @@
+
+ void XclExpChTrTabId::SaveCont( XclExpStream& rStrm )
+ {
++ rStrm.EnableEncryption();
+ if( pBuffer )
+ for( sal_uInt16* pElem = pBuffer; pElem < (pBuffer + nTabCount); pElem++ )
+ rStrm << *pElem;
+Index: sc/source/filter/xcl97/makefile.mk
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/xcl97/makefile.mk,v
+retrieving revision 1.16
+retrieving revision 1.15.324.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.16 -r1.15.324.2
+--- sc/source/filter/xcl97/makefile.mk 10 Apr 2008 21:05:15 -0000 1.16
++++ sc/source/filter/xcl97/makefile.mk 6 May 2008 23:29:23 -0000 1.15.324.2
+@@ -50,7 +50,6 @@
+ # --- Files --------------------------------------------------------
+
+ SLOFILES = \
+- $(SLO)$/xcl97dum.obj \
+ $(SLO)$/xcl97esc.obj \
+ $(SLO)$/xcl97rec.obj \
+ $(SLO)$/XclImpChangeTrack.obj \
+Index: sc/source/filter/xcl97/xcl97rec.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/xcl97/xcl97rec.cxx,v
+retrieving revision 1.87
+retrieving revision 1.86.292.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.87 -r1.86.292.3
+--- sc/source/filter/xcl97/xcl97rec.cxx 10 Apr 2008 21:06:48 -0000 1.87
++++ sc/source/filter/xcl97/xcl97rec.cxx 6 May 2008 23:29:20 -0000 1.86.292.3
+@@ -83,6 +83,7 @@
+ #include "scextopt.hxx"
+ #include "docoptio.hxx"
+ #include "patattr.hxx"
++#include "tabprotection.hxx"
+
+ using ::rtl::OUString;
+ using namespace ::com::sun::star;
+@@ -137,9 +138,9 @@
+
+ // --- 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 )
+ {
+@@ -184,7 +185,7 @@
+ }
+
+
+-void XclMsodrawinggroup::SaveCont( XclExpStream& rStrm )
++void XclMsodrawinggroup::WriteBody( XclExpStream& rStrm )
+ {
+ DBG_ASSERT( GetEscherEx()->GetStreamPos() == GetEscherEx()->GetOffsetFromMap( nStartPos ),
+ "XclMsodrawinggroup::SaveCont: Escher stream position mismatch" );
+@@ -192,23 +193,11 @@
+ }
+
+
+-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 )
+ {
+@@ -234,7 +223,7 @@
+ }
+
+
+-void XclMsodrawing::SaveCont( XclExpStream& rStrm )
++void XclMsodrawing::WriteBody( XclExpStream& rStrm )
+ {
+ DBG_ASSERT( GetEscherEx()->GetStreamPos() == GetEscherEx()->GetOffsetFromMap( nStartPos ),
+ "XclMsodrawing::SaveCont: Escher stream position mismatch" );
+@@ -242,16 +231,6 @@
+ }
+
+
+-UINT16 XclMsodrawing::GetNum() const
+-{
+- return 0x00EC;
+-}
+-
+-
+-sal_Size XclMsodrawing::GetLen() const
+-{
+- return GetDataLen();
+-}
+
+
+ // --- class XclObjList ----------------------------------------------
+@@ -888,6 +867,7 @@
+
+ void ExcBof8_Base::SaveCont( XclExpStream& rStrm )
+ {
++ rStrm.DisableEncryption();
+ rStrm << nVers << nDocType << nRupBuild << nRupYear
+ << nFileHistory << nLowestBiffVer;
+ }
+@@ -948,7 +928,10 @@
+ {
+ nOwnPos = rStrm.GetSvStreamPos();
+ // write dummy position, real position comes later
+- rStrm << sal_uInt32( 0 ) << nGrbit << aUnicodeName;
++ rStrm.DisableEncryption();
++ rStrm << sal_uInt32(0);
++ rStrm.EnableEncryption();
++ rStrm << nGrbit << aUnicodeName;
+ }
+
+
+@@ -1228,33 +1211,73 @@
+ 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 }
++ };
+
+-const BYTE* XclProtection::GetData( void ) const
+-{
+- return pMyData;
++ mnOptions = 0x0000;
++ ScTableProtection* pProtect = rRoot.GetDoc().GetTabProtection(nTab);
++ if (!pProtect)
++ return;
++
++ 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;
++}
+
++// ============================================================================
+
+
+
+@@ -1342,3 +1365,250 @@
+ XclExpBoolRecord( 0x000F, rDoc.GetAddressConvention() != ScAddress::CONV_XL_R1C1 )
+ {
+ }
++
++// ============================================================================
++
++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 nData01C1[] = {
++ 0xC1, 0x01, 0x00, 0x00, 0x54, 0x8D, 0x01, 0x00
++};
++
++XclExpUnknown01C1::XclExpUnknown01C1() :
++ XclExpDummyRecord(0x01C1, nData01C1, sizeof(nData01C1))
++{
++}
++
++// ============================================================================
++
++static const sal_uInt8 nData0863[] = {
++ 0x63, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x02
++};
++
++XclExpUnknown0863::XclExpUnknown0863() :
++ XclExpDummyRecord(0x0863, nData0863, sizeof(nData0863))
++{
++}
++
+Index: sc/source/filter/xml/xmlbodyi.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/xml/xmlbodyi.cxx,v
+retrieving revision 1.30
+retrieving revision 1.29.324.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.30 -r1.29.324.2
+--- sc/source/filter/xml/xmlbodyi.cxx 10 Apr 2008 21:24:07 -0000 1.30
++++ sc/source/filter/xml/xmlbodyi.cxx 6 May 2008 23:28:19 -0000 1.29.324.2
+@@ -50,6 +50,7 @@
+ #include "XMLTrackedChangesContext.hxx"
+ #include "XMLEmptyContext.hxx"
+ #include "scerrors.hxx"
++#include "tabprotection.hxx"
+
+ #include <xmloff/xmltkmap.hxx>
+ #include <xmloff/xmltoken.hxx>
+@@ -60,6 +61,8 @@
+ #include <sal/types.h>
+ #include <tools/debug.hxx>
+
++#include <memory>
++
+ using namespace com::sun::star;
+ using namespace xmloff::token;
+
+@@ -252,10 +255,17 @@
+ // #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();
+Index: sc/source/filter/xml/xmlexprt.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/xml/xmlexprt.cxx,v
+retrieving revision 1.212
+retrieving revision 1.211.28.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.212 -r1.211.28.3
+--- sc/source/filter/xml/xmlexprt.cxx 10 Apr 2008 21:29:11 -0000 1.212
++++ sc/source/filter/xml/xmlexprt.cxx 23 May 2008 00:17:47 -0000 1.211.28.3
+@@ -67,6 +67,7 @@
+ #include "rangeutl.hxx"
+ #include "convuno.hxx"
+ #include "postit.hxx"
++#include "tabprotection.hxx"
+
+ #include <xmloff/xmltoken.hxx>
+ #include <xmloff/xmlnmspe.hxx>
+@@ -1399,7 +1400,11 @@
+ {
+ 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());
+ }
+@@ -1417,11 +1422,13 @@
+ DBG_ERROR("no shared data setted");
+ }
+ ScXMLExportDatabaseRanges aExportDatabaseRanges(*this);
+- if (GetModel().is())
+- {
++ if (!GetModel().is())
++ return;
++
+ uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY );
+- if ( xSpreadDoc.is() )
+- {
++ if ( !xSpreadDoc.is() )
++ return;
++
+ uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
+ if ( xIndex.is() )
+ {
+@@ -1471,7 +1478,11 @@
+ 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());
+ }
+@@ -1585,8 +1596,6 @@
+ aExportDDELinks.WriteDDELinks(xSpreadDoc);
+ IncrementProgressBar(sal_True, 0);
+ GetProgressBarHelper()->SetValue(GetProgressBarHelper()->GetReference());
+- }
+- }
+ }
+
+ void ScXMLExport::_ExportStyles( sal_Bool bUsed )
+Index: sc/source/filter/xml/xmlsubti.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/filter/xml/xmlsubti.cxx,v
+retrieving revision 1.50
+retrieving revision 1.49.28.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.50 -r1.49.28.2
+--- sc/source/filter/xml/xmlsubti.cxx 10 Apr 2008 21:36:36 -0000 1.50
++++ sc/source/filter/xml/xmlsubti.cxx 6 May 2008 23:28:28 -0000 1.49.28.2
+@@ -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;
+@@ -639,13 +644,10 @@
+ {
+ 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();
+Index: sc/source/ui/docshell/docfunc.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/ui/docshell/docfunc.cxx,v
+retrieving revision 1.70
+retrieving revision 1.68.28.4
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.70 -r1.68.28.4
+--- sc/source/ui/docshell/docfunc.cxx 14 May 2008 09:56:37 -0000 1.70
++++ sc/source/ui/docshell/docfunc.cxx 23 May 2008 01:50:45 -0000 1.68.28.4
+@@ -92,7 +92,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 -----------------------------------------------------------
+
+@@ -2601,103 +2606,152 @@
+
+ //------------------------------------------------------------------------
+
+-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 )
++ ScDocument* pDoc = rDocShell.GetDocument();
++
++ pDoc->SetTabProtection(nTab, &rProtect);
++ if (pDoc->IsUndoEnabled())
+ {
+- if (pDoc->IsDocProtected())
+- aOldPassword = pDoc->GetDocPassword();
+- }
+- else
++ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
++ DBG_ASSERT(pProtect, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
++ if (pProtect)
+ {
+- if (pDoc->IsTabProtected(nTab))
+- aOldPassword = pDoc->GetTabPassword(nTab);
+- }
++ ::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 )
++ if (nTab == TABLEID_DOC)
+ {
+- uno::Sequence<sal_Int8> aPass;
+- if (rPassword.Len())
+- SvPasswordHelper::GetHashPassword(aPass, rPassword);
++ // document protection
+
+- if (bUndo)
++ pDoc->SetDocProtection(true, rPassword);
++ if (pDoc->IsUndoEnabled())
++ {
++ 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 ScUndoProtect( &rDocShell, nTab, TRUE, aPass ) );
++ 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();
++ pDoc->SetTabProtection(nTab, true, rPassword);
++ 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 )
++
++ if (nTab == TABLEID_DOC)
+ {
+- uno::Sequence<sal_Int8> aEmptyPass;
+- if ( nTab == TABLEID_DOC )
+- pDoc->SetDocProtection( FALSE, aEmptyPass );
+- else
+- pDoc->SetTabProtection( nTab, FALSE, aEmptyPass );
++ // document protection
+
+- if (bUndo)
++ 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 ScUndoTabProtect.
+ }
+- else if (!bApi)
++ }
++ else
+ {
+-//! rDocShell.ErrorMessage(...);
++ // sheet protection
++
++ ScTableProtection* pTabProtect = pDoc->GetTabProtection(nTab);
++ if (!pTabProtect || !pTabProtect->isProtected())
++ // already unprotected (should not happen)!
++ return true;
++
++ // 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.
++ }
++ }
++
++ rDocShell.PostPaintGridAll();
++ ScDocShellModificator aModificator( rDocShell );
++ aModificator.SetDocumentModified();
+
+- return bOk;
++ return true;
+ }
+
+ //------------------------------------------------------------------------
+Index: sc/source/ui/docshell/docsh.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/ui/docshell/docsh.cxx,v
+retrieving revision 1.100
+retrieving revision 1.98.28.6
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.100 -r1.98.28.6
+--- sc/source/ui/docshell/docsh.cxx 15 Apr 2008 14:12:23 -0000 1.100
++++ sc/source/ui/docshell/docsh.cxx 22 May 2008 21:47:16 -0000 1.98.28.6
+@@ -78,11 +78,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"
+@@ -96,7 +91,6 @@
+ #include "scresid.hxx"
+ #include "sc.hrc"
+ #include "globstr.hrc"
+-//CHINA001 #include "tpstat.hxx"
+ #include "scerrors.hxx"
+ #include "brdcst.hxx"
+ #include "stlpool.hxx"
+@@ -125,6 +119,7 @@
+ #include "cfgids.hxx"
+ #include "warnpassword.hxx"
+ #include "optsolver.hxx"
++#include "tabprotection.hxx"
+
+ #include "docsh.hxx"
+ #include "docshimp.hxx"
+@@ -1948,6 +1943,32 @@
+ rStream.SetNumberFormatInt( nOldNumberFormatInt );
+ }
+
++/** 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 Excel-compatible, then it returns false. */
++bool lcl_NeedHashRegen(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;
++}
+
+ BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed )
+ {
+@@ -2001,6 +2022,14 @@
+ aDocument.SetExtDocOptions( pExtDocOpt = new ScExtDocOptions );
+ pViewShell->GetViewData()->WriteExtOptions( *pExtDocOpt );
+
++ bool bNeedRetypePassDlg = lcl_NeedHashRegen(aDocument, PASSHASH_XL);
++ if (bNeedRetypePassDlg && !pViewShell->ExecuteRetypePassDlg(PASSHASH_XL))
++ {
++ SetError( ERRCODE_ABORT );
++ return false;
++ }
++
++#if 0
+ /* #115980 #If the imported document contained an encrypted password -
+ determine if we should save without it. */
+ ScExtDocSettings& rDocSett = pExtDocOpt->GetDocSettings();
+@@ -2010,6 +2039,7 @@
+ // #i42858# warn only on time
+ rDocSett.mbEncrypted = false;
+ }
++#endif
+ }
+
+ if( bDoSave )
+Index: sc/source/ui/docshell/docsh5.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/ui/docshell/docsh5.cxx,v
+retrieving revision 1.20
+retrieving revision 1.19.28.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.20 -r1.19.28.2
+--- sc/source/ui/docshell/docsh5.cxx 10 Apr 2008 22:12:43 -0000 1.20
++++ sc/source/ui/docshell/docsh5.cxx 6 May 2008 23:27:03 -0000 1.19.28.2
+@@ -820,7 +820,7 @@
+ ++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)
+ {
+Index: sc/source/ui/inc/docfunc.hxx
+===================================================================
+RCS file: /cvs/sc/sc/source/ui/inc/docfunc.hxx,v
+retrieving revision 1.19
+retrieving revision 1.18.28.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.19 -r1.18.28.2
+--- sc/source/ui/inc/docfunc.hxx 14 May 2008 09:58:47 -0000 1.19
++++ sc/source/ui/inc/docfunc.hxx 23 May 2008 01:50:16 -0000 1.18.28.2
+@@ -47,7 +47,7 @@
+ class ScBaseCell;
+ class ScTokenArray;
+ struct ScTabOpParam;
+-
++class ScTableProtection;
+
+ // ---------------------------------------------------------------------------
+
+@@ -129,6 +129,8 @@
+ 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 );
+
+Index: sc/source/ui/inc/protectiondlg.hrc
+===================================================================
+RCS file: sc/source/ui/inc/protectiondlg.hrc
+diff -N sc/source/ui/inc/protectiondlg.hrc
+--- /dev/null 1 Jan 1970 00:00:00 -0000
++++ sc/source/ui/inc/protectiondlg.hrc 7 May 2008 22:15:40 -0000 1.1.2.1
+@@ -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
+Index: sc/source/ui/inc/protectiondlg.hxx
+===================================================================
+RCS file: sc/source/ui/inc/protectiondlg.hxx
+diff -N sc/source/ui/inc/protectiondlg.hxx
+--- /dev/null 1 Jan 1970 00:00:00 -0000
++++ sc/source/ui/inc/protectiondlg.hxx 23 May 2008 00:05:23 -0000 1.1.2.4
+@@ -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
+Index: sc/source/ui/inc/retypepassdlg.hrc
+===================================================================
+RCS file: sc/source/ui/inc/retypepassdlg.hrc
+diff -N sc/source/ui/inc/retypepassdlg.hrc
+--- /dev/null 1 Jan 1970 00:00:00 -0000
++++ sc/source/ui/inc/retypepassdlg.hrc 20 May 2008 00:25:53 -0000 1.1.2.2
+@@ -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
+Index: sc/source/ui/inc/retypepassdlg.hxx
+===================================================================
+RCS file: sc/source/ui/inc/retypepassdlg.hxx
+diff -N sc/source/ui/inc/retypepassdlg.hxx
+--- /dev/null 1 Jan 1970 00:00:00 -0000
++++ sc/source/ui/inc/retypepassdlg.hxx 23 May 2008 00:09:48 -0000 1.1.2.7
+@@ -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 SetData(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(sal_uInt8 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
+Index: sc/source/ui/inc/tabvwsh.hxx
+===================================================================
+RCS file: /cvs/sc/sc/source/ui/inc/tabvwsh.hxx,v
+retrieving revision 1.30
+retrieving revision 1.30.30.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.30 -r1.30.30.2
+--- sc/source/ui/inc/tabvwsh.hxx 10 Apr 2008 23:29:18 -0000 1.30
++++ sc/source/ui/inc/tabvwsh.hxx 21 May 2008 04:37:25 -0000 1.30.30.2
+@@ -38,6 +38,7 @@
+ #include "target.hxx"
+ #include "rangelst.hxx" // ScRangeListRef
+ #include "shellids.hxx"
++#include "tabprotection.hxx" // for ScPasswordHash
+
+ class FmFormShell;
+ class SbxObject;
+@@ -430,6 +431,8 @@
+ void BroadcastAccessibility( const SfxHint &rHint );
+ BOOL HasAccessibilityObjects();
+
++ bool ExecuteRetypePassDlg(ScPasswordHash eDesiredHash);
++
+ using ScTabView::ShowCursor;
+ };
+
+Index: sc/source/ui/inc/undotab.hxx
+===================================================================
+RCS file: /cvs/sc/sc/source/ui/inc/undotab.hxx,v
+retrieving revision 1.11
+retrieving revision 1.9.424.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.11 -r1.9.424.3
+--- sc/source/ui/inc/undotab.hxx 14 May 2008 09:59:00 -0000 1.11
++++ sc/source/ui/inc/undotab.hxx 23 May 2008 01:50:19 -0000 1.9.424.3
+@@ -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;
+
+ //----------------------------------------------------------------------------
+
+@@ -336,14 +340,15 @@
+ 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();
+@@ -353,11 +358,34 @@
+ 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);
+ };
+
+
+Index: sc/source/ui/inc/viewfunc.hxx
+===================================================================
+RCS file: /cvs/sc/sc/source/ui/inc/viewfunc.hxx,v
+retrieving revision 1.34
+retrieving revision 1.34.30.1
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.34 -r1.34.30.1
+--- sc/source/ui/inc/viewfunc.hxx 10 Apr 2008 23:37:14 -0000 1.34
++++ sc/source/ui/inc/viewfunc.hxx 8 May 2008 21:53:47 -0000 1.34.30.1
+@@ -69,6 +69,7 @@
+ class ScRangeList;
+ class SvxHyperlinkItem;
+ class ScTransferObj;
++class ScTableProtection;
+
+ namespace com { namespace sun { namespace star { namespace datatransfer { class XTransferable; } } } }
+
+@@ -199,6 +200,8 @@
+
+ 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 );
+
+Index: sc/source/ui/miscdlgs/makefile.mk
+===================================================================
+RCS file: /cvs/sc/sc/source/ui/miscdlgs/makefile.mk,v
+retrieving revision 1.14
+retrieving revision 1.13.30.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.14 -r1.13.30.3
+--- sc/source/ui/miscdlgs/makefile.mk 16 May 2008 10:09:52 -0000 1.14
++++ sc/source/ui/miscdlgs/makefile.mk 23 May 2008 01:50:39 -0000 1.13.30.3
+@@ -78,7 +78,9 @@
+ $(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 @@
+ $(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 @@
+ highred.src \
+ linkarea.src \
+ conflictsdlg.src \
+- sharedocdlg.src
++ sharedocdlg.src \
++ protectiondlg.src \
++ retypepassdlg.src
+
+ LIB1TARGET = $(SLB)$/$(TARGET).lib
+
+@@ -116,7 +122,9 @@
+ $(SLO)$/redcom.obj \
+ $(SLO)$/warnbox.obj \
+ $(SLO)$/conflictsdlg.obj \
+- $(SLO)$/sharedocdlg.obj
++ $(SLO)$/sharedocdlg.obj \
++ $(SLO)$/protectiondlg.obj \
++ $(SLO)$/retypepassdlg.obj
+
+ # --- Tagets -------------------------------------------------------
+
+Index: sc/source/ui/miscdlgs/protectiondlg.cxx
+===================================================================
+RCS file: sc/source/ui/miscdlgs/protectiondlg.cxx
+diff -N sc/source/ui/miscdlgs/protectiondlg.cxx
+--- /dev/null 1 Jan 1970 00:00:00 -0000
++++ sc/source/ui/miscdlgs/protectiondlg.cxx 23 May 2008 17:39:36 -0000 1.1.2.6
+@@ -0,0 +1,161 @@
++/*************************************************************************
++ *
++ * 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.
++ *
++ ************************************************************************/
++
++#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;
++}
+Index: sc/source/ui/miscdlgs/protectiondlg.src
+===================================================================
+RCS file: sc/source/ui/miscdlgs/protectiondlg.src
+diff -N sc/source/ui/miscdlgs/protectiondlg.src
+--- /dev/null 1 Jan 1970 00:00:00 -0000
++++ sc/source/ui/miscdlgs/protectiondlg.src 23 May 2008 00:07:53 -0000 1.1.2.6
+@@ -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";
++ };
++};
+Index: sc/source/ui/miscdlgs/retypepassdlg.cxx
+===================================================================
+RCS file: sc/source/ui/miscdlgs/retypepassdlg.cxx
+diff -N sc/source/ui/miscdlgs/retypepassdlg.cxx
+--- /dev/null 1 Jan 1970 00:00:00 -0000
++++ sc/source/ui/miscdlgs/retypepassdlg.cxx 23 May 2008 00:10:22 -0000 1.1.2.7
+@@ -0,0 +1,544 @@
++/*************************************************************************
++ *
++ * 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.
++ *
++ ************************************************************************/
++
++#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::SetData(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());
++
++ SCTAB nTabCount = 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, 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(sal_uInt8 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, 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*, pBtn )
++{
++ CheckPasswordInput();
++ return 0;
++}
++
++IMPL_LINK( ScRetypePassInputDlg, PasswordModifyHdl, Edit*, pEdit )
++{
++ CheckPasswordInput();
++ return 0;
++}
+Index: sc/source/ui/miscdlgs/retypepassdlg.src
+===================================================================
+RCS file: sc/source/ui/miscdlgs/retypepassdlg.src
+diff -N sc/source/ui/miscdlgs/retypepassdlg.src
+--- /dev/null 1 Jan 1970 00:00:00 -0000
++++ sc/source/ui/miscdlgs/retypepassdlg.src 23 May 2008 00:11:30 -0000 1.1.2.3
+@@ -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 an incompatible password hash. Please re-type your password to re-generate password hash that is compatible with the exported format." ;
++ };
++
++ 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." ;
++ };
++};
++
++
+Index: sc/source/ui/undo/undotab.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/ui/undo/undotab.cxx,v
+retrieving revision 1.20
+retrieving revision 1.18.56.4
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.20 -r1.18.56.4
+--- sc/source/ui/undo/undotab.cxx 14 May 2008 10:02:11 -0000 1.20
++++ sc/source/ui/undo/undotab.cxx 23 May 2008 01:50:23 -0000 1.18.56.4
+@@ -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(ScUndoImportTab, SfxUndoAction);
+ TYPEINIT1(ScUndoRemoveLink, SfxUndoAction);
+ TYPEINIT1(ScUndoShowHideTab, SfxUndoAction);
+-TYPEINIT1(ScUndoProtect, SfxUndoAction);
+ TYPEINIT1(ScUndoPrintRange, SfxUndoAction);
+ TYPEINIT1(ScUndoScenarioFlags, SfxUndoAction);
+ TYPEINIT1(ScUndoRenameObject, SfxUndoAction);
+@@ -112,12 +114,12 @@
+ 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 @@
+ nEndChangeAction = 0;
+ }
+
+-void __EXPORT ScUndoInsertTab::Undo()
++void ScUndoInsertTab::Undo()
+ {
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ pViewShell->SetTabNo(nTab);
+@@ -159,7 +161,7 @@
+ pDocShell->Broadcast( SfxSimpleHint( SC_HINT_FORCESETTAB ) );
+ }
+
+-void __EXPORT ScUndoInsertTab::Redo()
++void ScUndoInsertTab::Redo()
+ {
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+@@ -180,14 +182,14 @@
+ 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 @@
+ SetChangeTrack();
+ }
+
+-__EXPORT ScUndoInsertTables::~ScUndoInsertTables()
++ScUndoInsertTables::~ScUndoInsertTables()
+ {
+ String *pStr=NULL;
+ if(pNameList!=NULL)
+@@ -227,7 +229,7 @@
+ DeleteSdrUndoAction( pDrawUndo );
+ }
+
+-String __EXPORT ScUndoInsertTables::GetComment() const
++String ScUndoInsertTables::GetComment() const
+ {
+ return ScGlobal::GetRscString( STR_UNDO_INSERT_TAB );
+ }
+@@ -252,7 +254,7 @@
+ nStartChangeAction = nEndChangeAction = 0;
+ }
+
+-void __EXPORT ScUndoInsertTables::Undo()
++void ScUndoInsertTables::Undo()
+ {
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ pViewShell->SetTabNo(nTab);
+@@ -282,7 +284,7 @@
+ pDocShell->Broadcast( SfxSimpleHint( SC_HINT_FORCESETTAB ) );
+ }
+
+-void __EXPORT ScUndoInsertTables::Redo()
++void ScUndoInsertTables::Redo()
+ {
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+@@ -299,14 +301,14 @@
+ 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 @@
+ 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 @@
+ return nTab;
+ }
+
+-void __EXPORT ScUndoDeleteTab::Undo()
++void ScUndoDeleteTab::Undo()
+ {
+ BeginUndo();
+ int i=0;
+@@ -414,7 +416,7 @@
+ 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 @@
+ // EndUndo();
+ }
+
+-void __EXPORT ScUndoDeleteTab::Redo()
++void ScUndoDeleteTab::Redo()
+ {
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ pViewShell->SetTabNo( lcl_GetVisibleTabBefore( *pDocShell->GetDocument(), theTabs[0] ) );
+@@ -469,7 +471,7 @@
+ 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 @@
+ }
+ }
+
+-BOOL __EXPORT ScUndoDeleteTab::CanRepeat(SfxRepeatTarget& rTarget) const
++BOOL ScUndoDeleteTab::CanRepeat(SfxRepeatTarget& rTarget) const
+ {
+ return (rTarget.ISA(ScTabViewTarget));
+ }
+@@ -500,11 +502,11 @@
+ 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 @@
+ 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 @@
+ 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 @@
+ 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 @@
+ 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 @@
+ pDocShell->PostDataChanged();
+ }
+
+-void __EXPORT ScUndoCopyTab::Undo()
++void ScUndoCopyTab::Undo()
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+@@ -717,7 +719,7 @@
+ DoChange();
+ }
+
+-void __EXPORT ScUndoCopyTab::Redo()
++void ScUndoCopyTab::Redo()
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+@@ -756,7 +758,7 @@
+ }
+
+ 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::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;
+ }
+@@ -800,17 +802,17 @@
+ {
+ }
+
+-__EXPORT ScUndoMakeScenario::~ScUndoMakeScenario()
++ScUndoMakeScenario::~ScUndoMakeScenario()
+ {
+ delete pUndoDoc;
+ }
+
+-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();
+ pDoc->DeleteTab( nDestTab );
+@@ -824,7 +826,7 @@
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ }
+
+-void __EXPORT ScUndoMakeScenario::Redo()
++void ScUndoMakeScenario::Redo()
+ {
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ if (pViewShell)
+@@ -838,7 +840,7 @@
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ }
+
+-void __EXPORT ScUndoMakeScenario::Repeat(SfxRepeatTarget& rTarget)
++void ScUndoMakeScenario::Repeat(SfxRepeatTarget& rTarget)
+ {
+ if (rTarget.ISA(ScTabViewTarget))
+ {
+@@ -846,7 +848,7 @@
+ }
+ }
+
+-BOOL __EXPORT ScUndoMakeScenario::CanRepeat(SfxRepeatTarget& rTarget) const
++BOOL ScUndoMakeScenario::CanRepeat(SfxRepeatTarget& rTarget) const
+ {
+ return (rTarget.ISA(ScTabViewTarget));
+ }
+@@ -869,13 +871,13 @@
+ 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 );
+ }
+@@ -902,7 +904,7 @@
+ PAINT_GRID | PAINT_TOP | PAINT_LEFT | PAINT_EXTRAS );
+ }
+
+-void __EXPORT ScUndoImportTab::Undo()
++void ScUndoImportTab::Undo()
+ {
+ //! eingefuegte Bereichsnamen etc.
+
+@@ -938,7 +940,7 @@
+ }
+
+ if ( pDoc->IsTabProtected( nTabPos ) )
+- pRedoDoc->SetTabProtection( nTabPos, TRUE, pDoc->GetTabPassword( nTabPos ) );
++ pRedoDoc->SetTabProtection(nTabPos, pDoc->GetTabProtection(nTabPos));
+ }
+
+ }
+@@ -953,7 +955,7 @@
+ DoChange();
+ }
+
+-void __EXPORT ScUndoImportTab::Redo()
++void ScUndoImportTab::Redo()
+ {
+ if (!pRedoDoc)
+ {
+@@ -992,7 +994,7 @@
+ }
+
+ if ( pRedoDoc->IsTabProtected( nTabPos ) )
+- pDoc->SetTabProtection( nTabPos, TRUE, pRedoDoc->GetTabPassword( nTabPos ) );
++ pDoc->SetTabProtection(nTabPos, pRedoDoc->GetTabProtection(nTabPos));
+ }
+
+ RedoSdrUndoAction( pDrawUndo ); // after the sheets are inserted
+@@ -1000,14 +1002,14 @@
+ 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));
+ }
+@@ -1055,14 +1057,14 @@
+ }
+ }
+
+-__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 );
+ }
+@@ -1079,22 +1081,22 @@
+ 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;
+ }
+@@ -1112,7 +1114,7 @@
+ {
+ }
+
+-__EXPORT ScUndoShowHideTab::~ScUndoShowHideTab()
++ScUndoShowHideTab::~ScUndoShowHideTab()
+ {
+ }
+
+@@ -1129,17 +1131,17 @@
+ 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().
+@@ -1147,53 +1149,44 @@
+ 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();
+@@ -1206,37 +1199,103 @@
+ 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 );
+ }
+
+@@ -1254,7 +1313,7 @@
+ {
+ }
+
+-__EXPORT ScUndoPrintRange::~ScUndoPrintRange()
++ScUndoPrintRange::~ScUndoPrintRange()
+ {
+ delete pOldRanges;
+ delete pNewRanges;
+@@ -1277,31 +1336,31 @@
+ 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 );
+ }
+@@ -1330,16 +1389,16 @@
+ {
+ }
+
+-__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();
+
+@@ -1356,7 +1415,7 @@
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ }
+
+-void __EXPORT ScUndoScenarioFlags::Redo()
++void ScUndoScenarioFlags::Redo()
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+@@ -1373,12 +1432,12 @@
+ 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;
+ }
+@@ -1478,7 +1537,7 @@
+ {
+ }
+
+-__EXPORT ScUndoLayoutRTL::~ScUndoLayoutRTL()
++ScUndoLayoutRTL::~ScUndoLayoutRTL()
+ {
+ }
+
+@@ -1498,29 +1557,29 @@
+ 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 );
+ }
+@@ -1540,7 +1599,7 @@
+ meOldGrammar = pDocShell->GetDocument()->GetGrammar();
+ }
+
+-__EXPORT ScUndoSetGrammar::~ScUndoSetGrammar()
++ScUndoSetGrammar::~ScUndoSetGrammar()
+ {
+ }
+
+@@ -1553,17 +1612,17 @@
+ 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
+@@ -1573,12 +1632,12 @@
+ #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 );
+ }
+Index: sc/source/ui/unoobj/warnpassword.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/ui/unoobj/warnpassword.cxx,v
+retrieving revision 1.5
+retrieving revision 1.5.30.1
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.5 -r1.5.30.1
+--- sc/source/ui/unoobj/warnpassword.cxx 11 Apr 2008 00:46:26 -0000 1.5
++++ sc/source/ui/unoobj/warnpassword.cxx 22 May 2008 21:47:22 -0000 1.5.30.1
+@@ -32,6 +32,9 @@
+ #include "precompiled_sc.hxx"
+
+ // ============================================================================
++
++#if 0
++
+ #include "warnpassword.hxx"
+ #include <com/sun/star/task/XInteractionHandler.hpp>
+ #include <com/sun/star/task/XInteractionRequest.hpp>
+@@ -95,3 +98,5 @@
+ }
+ return bReturn;
+ }
++
++#endif
+Index: sc/source/ui/view/gridwin.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/ui/view/gridwin.cxx,v
+retrieving revision 1.94
+retrieving revision 1.92.26.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.94 -r1.92.26.2
+--- sc/source/ui/view/gridwin.cxx 18 Apr 2008 11:47:50 -0000 1.94
++++ sc/source/ui/view/gridwin.cxx 6 May 2008 23:26:52 -0000 1.92.26.2
+@@ -135,6 +135,7 @@
+ #include "userdat.hxx"
+ #include "drwlayer.hxx"
+ #include "attrib.hxx"
++#include "tabprotection.hxx"
+
+ // #114409#
+ #include <vcl/salbtype.hxx> // FRound
+@@ -2006,11 +2007,12 @@
+ 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() );
++ ScAddress aCellPos( nPosX, nPosY, nTab );
+ ScDPPositionData aData;
+ pDPObj->GetPositionData( aData, aCellPos );
+
+@@ -2047,6 +2049,23 @@
+ return;
+ }
+
++ // 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 )
++ {
+ // edit cell contents
+ pViewData->GetViewShell()->UpdateInputHandler();
+ pScMod->SetInputMode( SC_INPUT_TABLE );
+@@ -2057,9 +2076,10 @@
+ MouseEvent aEditEvt( rMEvt.GetPosPixel(), 1, MOUSE_SYNTHETIC, MOUSE_LEFT, 0 );
+ pEditView->MouseButtonDown( aEditEvt );
+ pEditView->MouseButtonUp( aEditEvt );
+- return;
+ }
+ }
++ return;
++ }
+
+ //
+ // Links in edit cells
+Index: sc/source/ui/view/scextopt.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/ui/view/scextopt.cxx,v
+retrieving revision 1.5
+retrieving revision 1.4.486.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.5 -r1.4.486.3
+--- sc/source/ui/view/scextopt.cxx 11 Apr 2008 01:37:36 -0000 1.5
++++ sc/source/ui/view/scextopt.cxx 22 May 2008 21:44:08 -0000 1.4.486.3
+@@ -42,9 +42,7 @@
+ maOleSize( ScAddress::INITIALIZE_INVALID ),
+ mfTabBarWidth( -1.0 ),
+ mnLinkCnt( 0 ),
+- mnDisplTab( 0 ),
+- mbWinProtected( false ),
+- mbEncrypted( false )
++ mnDisplTab( 0 )
+ {
+ }
+
+Index: sc/source/ui/view/select.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/ui/view/select.cxx,v
+retrieving revision 1.19
+retrieving revision 1.18.324.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.19 -r1.18.324.2
+--- sc/source/ui/view/select.cxx 11 Apr 2008 01:37:56 -0000 1.19
++++ sc/source/ui/view/select.cxx 6 May 2008 23:26:55 -0000 1.18.324.2
+@@ -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 @@
+ {
+ 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();
+ BOOL bRefMode = pScMod->IsFormulaMode();
+
+@@ -374,7 +395,6 @@
+
+ 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 &&
+@@ -510,7 +530,6 @@
+ 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);
+Index: sc/source/ui/view/tabview3.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/ui/view/tabview3.cxx,v
+retrieving revision 1.67
+retrieving revision 1.65.56.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.67 -r1.65.56.2
+--- sc/source/ui/view/tabview3.cxx 18 Apr 2008 11:48:39 -0000 1.67
++++ sc/source/ui/view/tabview3.cxx 6 May 2008 23:26:39 -0000 1.65.56.2
+@@ -79,6 +79,7 @@
+ #include "AccessibilityHints.hxx"
+ #include "rangeutl.hxx"
+ #include "client.hxx"
++#include "tabprotection.hxx"
+
+ #include <com/sun/star/chart2/data/HighlightedRange.hpp>
+
+@@ -1020,6 +1021,17 @@
+ 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;
+@@ -1039,7 +1051,7 @@
+ nCurY = (nMovY != 0) ? nOldY+nMovY : (SCsROW) aViewData.GetOldCurY();
+ }
+
+- BOOL bHidden;
++ BOOL bSkipCell = FALSE;
+ aViewData.ResetOldCursor();
+
+ if (nMovX != 0 && VALIDCOLROW(nCurX,nCurY))
+@@ -1048,15 +1060,20 @@
+ 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
+ {
+@@ -1069,7 +1086,8 @@
+ if (nMovX > 0) ++nCurX; else --nCurX;
+ }
+ }
+- while (bHidden);
++ while (bSkipCell);
++
+ if (pDoc->IsVerOverlapped( nCurX, nCurY, nTab ))
+ {
+ aViewData.SetOldCursor( nCurX,nCurY );
+@@ -1084,15 +1102,20 @@
+ 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
+ {
+@@ -1105,7 +1128,8 @@
+ if (nMovY > 0) ++nCurY; else --nCurY;
+ }
+ }
+- while (bHidden);
++ while (bSkipCell);
++
+ if (pDoc->IsHorOverlapped( nCurX, nCurY, nTab ))
+ {
+ aViewData.SetOldCursor( nCurX,nCurY );
+Index: sc/source/ui/view/tabvwsh3.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/ui/view/tabvwsh3.cxx,v
+retrieving revision 1.40
+retrieving revision 1.38.80.4
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.40 -r1.38.80.4
+--- sc/source/ui/view/tabvwsh3.cxx 14 May 2008 10:05:09 -0000 1.40
++++ sc/source/ui/view/tabvwsh3.cxx 23 May 2008 01:50:32 -0000 1.38.80.4
+@@ -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
+@@ -84,6 +86,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)
+@@ -972,12 +978,13 @@
+ }
+ }
+
+- 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) );
+
+@@ -1030,15 +1037,12 @@
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+- SfxPasswordDialog* pDlg;
+- String aPassword;
+- BOOL bCancel = FALSE;
+- BOOL bOldProtection = pDoc->IsTabProtected(nTab);
+- BOOL bNewProtection = ! bOldProtection;
++ bool bOldProtection = pDoc->IsTabProtected(nTab);
+
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
++ bool bNewProtection = !bOldProtection;
+ if( IS_AVAILABLE( FID_PROTECT_TABLE, &pItem ) )
+ bNewProtection = ((const SfxBoolItem*)pItem)->GetValue();
+ if( bNewProtection == bOldProtection )
+@@ -1048,13 +1052,16 @@
+ }
+ }
+
+- if ( bOldProtection)
++ if (bOldProtection)
+ {
+- if (pDoc->GetTabPassword(nTab).getLength())
+- {
+- String aText( ScResId(SCSTR_PASSWORD) );
++ // Unprotect a protected sheet.
+
+- pDlg = new SfxPasswordDialog( GetDialogParent(), &aText );
++ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
++ String aPassword;
++ if (pProtect && pProtect->isProtectedWithPass())
++ {
++ 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 );
+@@ -1062,51 +1069,42 @@
+
+ if (pDlg->Execute() == RET_OK)
+ aPassword = pDlg->GetPassword();
+- else
+- bCancel = TRUE;
++ }
+
+- delete pDlg;
++ Unprotect(nTab, aPassword);
++ if (!pReqArgs)
++ {
++ rReq.AppendItem( SfxBoolItem(FID_PROTECT_TABLE, false) );
++ rReq.Done();
+ }
+ }
+ else
+ {
+- String aText( ScResId(SCSTR_PASSWORDOPT) );
++ // Protect a current sheet.
+
+- 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 );
+-
+- if (pDlg->Execute() == RET_OK)
+- aPassword = pDlg->GetPassword();
+- else
+- bCancel = TRUE;
++ auto_ptr<ScTableProtectionDlg> pDlg(new ScTableProtectionDlg(GetDialogParent()));
+
+- delete pDlg;
+- }
++ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
++ if (pProtect)
++ pDlg->SetDialogData(*pProtect);
+
+- if( !bCancel )
+- {
+- if ( bOldProtection )
+- Unprotect( nTab, aPassword );
+- else
++ if (pDlg->Execute() == RET_OK)
+ {
+ pScMod->InputEnterHandler();
+
+- Protect( nTab, aPassword );
+- }
+-
+- if( !pReqArgs )
++ ScTableProtection aNewProtect;
++ pDlg->WriteData(aNewProtect);
++ ProtectSheet(nTab, aNewProtect);
++ if (!pReqArgs)
+ {
+- rReq.AppendItem( SfxBoolItem( FID_PROTECT_TABLE, bNewProtection ) );
++ rReq.AppendItem( SfxBoolItem(FID_PROTECT_TABLE, true) );
+ rReq.Done();
+ }
+ }
++ }
+
+ TabChanged();
+- UpdateInputHandler(TRUE); // damit sofort wieder eingegeben werden kann
++ UpdateInputHandler(true); // damit sofort wieder eingegeben werden kann
+ SelectionChanged();
+ }
+ break;
+Index: sc/source/ui/view/tabvwshh.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/ui/view/tabvwshh.cxx,v
+retrieving revision 1.16
+retrieving revision 1.16.30.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.16 -r1.16.30.3
+--- sc/source/ui/view/tabvwshh.cxx 11 Apr 2008 01:45:43 -0000 1.16
++++ sc/source/ui/view/tabvwshh.cxx 21 May 2008 04:37:42 -0000 1.16.30.3
+@@ -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 @@
+ return pAccessibilityBroadcaster != NULL;
+ }
+
++bool ScTabViewShell::ExecuteRetypePassDlg(ScPasswordHash eDesiredHash)
++{
++ using ::std::auto_ptr;
++
++ ScDocument* pDoc = GetViewData()->GetDocument();
++
++ auto_ptr<ScRetypePassDlg> pDlg(new ScRetypePassDlg(GetDialogParent()));
++ pDlg->SetData(*pDoc);
++ pDlg->SetDesiredHash(eDesiredHash);
++ if (pDlg->Execute() != RET_OK)
++ return false;
++
++ pDlg->WriteNewDataToDocument(*pDoc);
++ return true;
++}
++
+
+
+
+Index: sc/source/ui/view/viewfun2.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/ui/view/viewfun2.cxx,v
+retrieving revision 1.41
+retrieving revision 1.38.28.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.41 -r1.38.28.3
+--- sc/source/ui/view/viewfun2.cxx 14 May 2008 10:05:47 -0000 1.41
++++ sc/source/ui/view/viewfun2.cxx 23 May 2008 01:50:28 -0000 1.38.28.3
+@@ -2150,7 +2150,7 @@
+ 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);
+@@ -2565,7 +2565,7 @@
+ }
+
+ if ( nErrVal > 0 && pDoc->IsTabProtected( TheTabs[i] ) )
+- pDestDoc->SetTabProtection( nDestTab1, TRUE, pDoc->GetTabPassword( TheTabs[i] ) );
++ pDestDoc->SetTabProtection(nDestTab1, pDoc->GetTabProtection(TheTabs[i]));
+
+ nDestTab1++;
+ }
+Index: sc/source/ui/view/viewfunc.cxx
+===================================================================
+RCS file: /cvs/sc/sc/source/ui/view/viewfunc.cxx,v
+retrieving revision 1.45
+retrieving revision 1.44.20.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.45 -r1.44.20.2
+--- sc/source/ui/view/viewfunc.cxx 14 May 2008 10:06:28 -0000 1.45
++++ sc/source/ui/view/viewfunc.cxx 23 May 2008 01:50:36 -0000 1.44.20.2
+@@ -2390,6 +2390,36 @@
+ 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();
Added: trunk/patches/dev300/cws-scsheetprotection02-sfx2.diff
==============================================================================
--- (empty file)
+++ trunk/patches/dev300/cws-scsheetprotection02-sfx2.diff Fri May 23 23:53:50 2008
@@ -0,0 +1,105 @@
+? sfx2/sfx2.vpj
+Index: sfx2/inc/sfx2/passwd.hxx
+===================================================================
+RCS file: /cvs/framework/sfx2/inc/sfx2/passwd.hxx,v
+retrieving revision 1.3
+retrieving revision 1.2.272.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.3 -r1.2.272.2
+--- sfx2/inc/sfx2/passwd.hxx 11 Apr 2008 11:37:34 -0000 1.3
++++ sfx2/inc/sfx2/passwd.hxx 6 May 2008 23:39:22 -0000 1.2.272.2
+@@ -81,6 +81,7 @@
+ String GetConfirm() const { return maConfirmED.GetText(); }
+
+ void SetMinLen( USHORT Len );
++ void SetMaxLen( USHORT Len );
+ void SetEditHelpId( ULONG nId ) { maPasswordED.SetHelpId( nId ); }
+ void ShowExtras( USHORT nExtras ) { mnExtras = nExtras; }
+
+Index: sfx2/source/dialog/filedlghelper.cxx
+===================================================================
+RCS file: /cvs/framework/sfx2/source/dialog/filedlghelper.cxx,v
+retrieving revision 1.142
+retrieving revision 1.140.2.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.142 -r1.140.2.3
+--- sfx2/source/dialog/filedlghelper.cxx 15 Apr 2008 14:18:43 -0000 1.142
++++ sfx2/source/dialog/filedlghelper.cxx 6 May 2008 23:39:30 -0000 1.140.2.3
+@@ -556,6 +556,11 @@
+ {
+ sal_Bool operator() ( const SfxFilter* _pFilter )
+ {
++ if (_pFilter->GetFilterName().EqualsAscii("MS Excel 97"))
++ // temporary hack to enable password protection for Excel 97. Is
++ // there a better way to enable password protection of a filter?
++ return true;
++
+ return _pFilter && _pFilter->IsOwnFormat()
+ && _pFilter->UsesStorage()
+ && ( SOFFICE_FILEFORMAT_60 <= _pFilter->GetVersion() );
+@@ -1538,6 +1543,9 @@
+ if( !rpSet )
+ rpSet = new SfxAllItemSet( SFX_APP()->GetPool() );
+
++ // set the filter
++ getRealFilter( rFilter );
++
+ // check, wether or not we have to display a password box
+ if ( mbHasPassword && mbIsPwdEnabled && xCtrlAccess.is() )
+ {
+@@ -1547,9 +1555,16 @@
+ sal_Bool bPassWord = sal_False;
+ if ( ( aValue >>= bPassWord ) && bPassWord )
+ {
+- // ask for the password
++ // ask for a password
+ SfxPasswordDialog aPasswordDlg( NULL );
+ aPasswordDlg.ShowExtras( SHOWEXTRAS_CONFIRM );
++ if ( rFilter.EqualsAscii("MS Excel 97") )
++ {
++ // Excel allows 1-15 length password.
++ aPasswordDlg.SetMinLen(1);
++ aPasswordDlg.SetMaxLen(15);
++ }
++
+ short nRet = aPasswordDlg.Execute();
+ if ( RET_OK == nRet )
+ {
+@@ -1616,9 +1631,6 @@
+ catch( IllegalArgumentException ){}
+ }
+
+- // set the filter
+- getRealFilter( rFilter );
+-
+ // fill the rpURLList
+ implGetAndCacheFiles(mxFileDlg, rpURLList, getCurentSfxFilter());
+ if ( rpURLList == NULL )
+Index: sfx2/source/dialog/passwd.cxx
+===================================================================
+RCS file: /cvs/framework/sfx2/source/dialog/passwd.cxx,v
+retrieving revision 1.9
+retrieving revision 1.8.72.2
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.9 -r1.8.72.2
+--- sfx2/source/dialog/passwd.cxx 11 Apr 2008 12:45:35 -0000 1.9
++++ sfx2/source/dialog/passwd.cxx 6 May 2008 23:39:25 -0000 1.8.72.2
+@@ -112,6 +112,15 @@
+
+ // -----------------------------------------------------------------------
+
++void SfxPasswordDialog::SetMaxLen( USHORT nLen )
++{
++ maPasswordED.SetMaxTextLen( nLen );
++ maConfirmED.SetMaxTextLen( nLen );
++ EditModifyHdl( NULL );
++}
++
++// -----------------------------------------------------------------------
++
+ short SfxPasswordDialog::Execute()
+ {
+ if ( mnExtras < SHOWEXTRAS_ALL )
+Index: sfx2/source/doc/objserv.cxx
+===================================================================
+RCS file: /cvs/framework/sfx2/source/doc/objserv.cxx,v
+retrieving revision 1.105
+retrieving revision 1.104.20.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.105 -r1.104.20.3
Added: trunk/patches/dev300/cws-scsheetprotection02-svx.diff
==============================================================================
--- (empty file)
+++ trunk/patches/dev300/cws-scsheetprotection02-svx.diff Fri May 23 23:53:50 2008
@@ -0,0 +1,271 @@
+? svx/svx.vpj
+? svx/source/table/localize.sdf
+Index: svx/inc/mscodec.hxx
+===================================================================
+RCS file: /cvs/graphics/svx/inc/mscodec.hxx,v
+retrieving revision 1.5
+retrieving revision 1.4.1248.5
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.5 -r1.4.1248.5
+--- svx/inc/mscodec.hxx 10 Apr 2008 18:46:33 -0000 1.5
++++ svx/inc/mscodec.hxx 22 May 2008 23:30:40 -0000 1.4.1248.5
+@@ -235,6 +235,14 @@
+ */
+ bool InitCipher( sal_uInt32 nCounter );
+
++ /** Creates an MD5 digest of salt digest. */
++ bool CreateSaltDigest(
++ const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16] );
++
++ bool Encode(
++ const void* pData, sal_Size nDatLen,
++ sal_uInt8* pBuffer, sal_Size nBufLen );
++
+ /** Decodes a block of memory.
+
+ @see rtl_cipher_decode()
+@@ -276,6 +284,9 @@
+ bool Skip( sal_Size nDatLen );
+
+ private:
++ void GetDigestFromSalt( const sal_uInt8 pSaltData[16], sal_uInt8 pDigest[16] );
++
++private:
+ SVX_DLLPRIVATE MSCodec_Std97( const MSCodec_Std97& );
+ SVX_DLLPRIVATE MSCodec_Std97& operator=( const MSCodec_Std97& );
+
+Index: svx/source/msfilter/mscodec.cxx
+===================================================================
+RCS file: /cvs/graphics/svx/source/msfilter/mscodec.cxx,v
+retrieving revision 1.7
+retrieving revision 1.6.104.5
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.7 -r1.6.104.5
+--- svx/source/msfilter/mscodec.cxx 11 Apr 2008 02:05:35 -0000 1.7
++++ svx/source/msfilter/mscodec.cxx 22 May 2008 23:01:29 -0000 1.6.104.5
+@@ -37,6 +37,13 @@
+ #include <string.h>
+ #include <tools/solar.h>
+
++#define DEBUG_MSO_ENCRYPTION_STD97 0
++
++#if DEBUG_MSO_ENCRYPTION_STD97
++#include <stdio.h>
++#endif
++
++
+ namespace svx {
+
+ // ============================================================================
+@@ -241,15 +248,50 @@
+ rtl_cipher_destroy (m_hCipher);
+ }
+
++#if DEBUG_MSO_ENCRYPTION_STD97
++static void lcl_PrintKeyData(const sal_uInt8* pKeyData, const char* msg)
++{
++ printf("pKeyData: (%s)\n", msg);
++ for (int j = 0; j < 4; ++j)
++ {
++ for (int i = 0; i < 16; ++i)
++ printf("%2.2x ", pKeyData[j*16+i]);
++ printf("\n");
++ }
++}
++#else
++static void lcl_PrintKeyData(const sal_uInt8* /*pKeyData*/, const char* /*msg*/)
++{
++}
++#endif
++
++#if DEBUG_MSO_ENCRYPTION_STD97
++static void lcl_PrintDigest(const sal_uInt8* pDigest, const char* msg)
++{
++ printf("digest: (%s)\n", msg);
++ for (int i = 0; i < 16; ++i)
++ printf("%2.2x ", pDigest[i]);
++ printf("\n");
++}
++#else
++static void lcl_PrintDigest(const sal_uInt8* /*pDigest*/, const char* /*msg*/)
++{
++}
++#endif
++
+ void MSCodec_Std97::InitKey (
+ const sal_uInt16 pPassData[16],
+ const sal_uInt8 pUnique[16])
+ {
++#if DEBUG_MSO_ENCRYPTION_STD97
++ fprintf(stdout, "MSCodec_Std97::InitKey: --begin\n");fflush(stdout);
++#endif
+ sal_uInt8 pKeyData[64];
+ int i, n;
+
+ // Fill PassData into KeyData.
+ (void)memset (pKeyData, 0, sizeof(pKeyData));
++ lcl_PrintKeyData(pKeyData, "initial");
+ for (i = 0, n = 16; (i < n) && pPassData[i]; i++)
+ {
+ pKeyData[2*i ] = sal::static_int_cast< sal_uInt8 >(
+@@ -260,12 +302,16 @@
+ pKeyData[2*i] = 0x80;
+ pKeyData[ 56] = sal::static_int_cast< sal_uInt8 >(i << 4);
+
++ lcl_PrintKeyData(pKeyData, "password data");
++
+ // Fill raw digest of KeyData into KeyData.
+ (void)rtl_digest_updateMD5 (
+ m_hDigest, pKeyData, sizeof(pKeyData));
+ (void)rtl_digest_rawMD5 (
+ m_hDigest, pKeyData, RTL_DIGEST_LENGTH_MD5);
+
++ lcl_PrintKeyData(pKeyData, "raw digest of key data");
++
+ // Update digest with KeyData and Unique.
+ for (i = 0; i < 16; i++)
+ {
+@@ -279,6 +325,8 @@
+ pKeyData[56] = 0x80;
+ pKeyData[57] = 0x0a;
+
++ lcl_PrintKeyData(pKeyData, "update digest with padding");
++
+ rtl_digest_updateMD5 (
+ m_hDigest, &(pKeyData[16]), sizeof(pKeyData) - 16);
+
+@@ -286,6 +334,8 @@
+ rtl_digest_rawMD5 (
+ m_hDigest, m_pDigestValue, sizeof(m_pDigestValue));
+
++ lcl_PrintDigest(m_pDigestValue, "digest value");
++
+ // Erase KeyData array and leave.
+ (void)memset (pKeyData, 0, sizeof(pKeyData));
+ }
+@@ -294,27 +344,21 @@
+ const sal_uInt8 pSaltData[16],
+ const sal_uInt8 pSaltDigest[16])
+ {
++ // both the salt data and salt digest (hash) come from the document being imported.
++
++#if DEBUG_MSO_ENCRYPTION_STD97
++ fprintf(stdout, "MSCodec_Std97::VerifyKey: \n");
++ lcl_PrintDigest(pSaltData, "salt data");
++ lcl_PrintDigest(pSaltDigest, "salt hash");
++#endif
+ bool result = false;
+
+ if (InitCipher(0))
+ {
+ sal_uInt8 pDigest[RTL_DIGEST_LENGTH_MD5];
+- sal_uInt8 pBuffer[64];
+-
+- // Decode SaltData into Buffer.
+- rtl_cipher_decode (
+- m_hCipher, pSaltData, 16, pBuffer, sizeof(pBuffer));
+-
+- pBuffer[16] = 0x80;
+- (void)memset (pBuffer + 17, 0, sizeof(pBuffer) - 17);
+- pBuffer[56] = 0x80;
+-
+- // Fill raw digest of Buffer into Digest.
+- rtl_digest_updateMD5 (
+- m_hDigest, pBuffer, sizeof(pBuffer));
+- rtl_digest_rawMD5 (
+- m_hDigest, pDigest, sizeof(pDigest));
++ GetDigestFromSalt(pSaltData, pDigest);
+
++ sal_uInt8 pBuffer[16];
+ // Decode original SaltDigest into Buffer.
+ rtl_cipher_decode (
+ m_hCipher, pSaltDigest, 16, pBuffer, sizeof(pBuffer));
+@@ -333,7 +377,7 @@
+ bool MSCodec_Std97::InitCipher (sal_uInt32 nCounter)
+ {
+ rtlCipherError result;
+- sal_uInt8 pKeyData[64];
++ sal_uInt8 pKeyData[64]; // 512-bit message block
+
+ // Initialize KeyData array.
+ (void)memset (pKeyData, 0, sizeof(pKeyData));
+@@ -358,7 +402,7 @@
+
+ // Initialize Cipher with KeyData (for decoding).
+ result = rtl_cipher_init (
+- m_hCipher, rtl_Cipher_DirectionDecode,
++ m_hCipher, rtl_Cipher_DirectionBoth,
+ pKeyData, RTL_DIGEST_LENGTH_MD5, 0, 0);
+
+ // Erase KeyData array and leave.
+@@ -367,6 +411,38 @@
+ return (result == rtl_Cipher_E_None);
+ }
+
++bool MSCodec_Std97::CreateSaltDigest( const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16] )
++{
++#if DEBUG_MSO_ENCRYPTION_STD97
++ lcl_PrintDigest(pSaltData, "salt data");
++#endif
++ bool result = false;
++
++ if (InitCipher(0))
++ {
++ sal_uInt8 pDigest[RTL_DIGEST_LENGTH_MD5];
++ GetDigestFromSalt(nSaltData, pDigest);
++
++ rtl_cipher_decode (
++ m_hCipher, pDigest, 16, pDigest, sizeof(pDigest));
++
++ (void)memcpy(nSaltDigest, pDigest, 16);
++ }
++
++ return (result);
++}
++
++bool MSCodec_Std97::Encode(
++ const void *pData, sal_Size nDatLen,
++ sal_uInt8 *pBuffer, sal_Size nBufLen)
++{
++ rtlCipherError result;
++ result = rtl_cipher_encode (
++ m_hCipher, pData, nDatLen, pBuffer, nBufLen);
++
++ return (result == rtl_Cipher_E_None);
++}
++
+ bool MSCodec_Std97::Decode (
+ const void *pData, sal_Size nDatLen,
+ sal_uInt8 *pBuffer, sal_Size nBufLen)
+@@ -395,6 +471,33 @@
+ return bResult;
+ }
+
++void MSCodec_Std97::GetDigestFromSalt( const sal_uInt8 pSaltData[16], sal_uInt8 pDigest[16] )
++{
++ sal_uInt8 pBuffer[64];
++ sal_uInt8 pDigestLocal[16];
++
++ // Decode SaltData into Buffer.
++ rtl_cipher_decode (
++ m_hCipher, pSaltData, 16, pBuffer, sizeof(pBuffer));
++
++ // set the 129th bit to make the buffer 128-bit in length.
++ pBuffer[16] = 0x80;
++
++ // erase the rest of the buffer with zeros.
++ (void)memset (pBuffer + 17, 0, sizeof(pBuffer) - 17);
++
++ // set the 441st bit.
++ pBuffer[56] = 0x80;
++
++ // Fill raw digest of Buffer into Digest.
++ rtl_digest_updateMD5 (
++ m_hDigest, pBuffer, sizeof(pBuffer));
++ rtl_digest_rawMD5 (
++ m_hDigest, pDigestLocal, sizeof(pDigestLocal));
++
++ memcpy(pDigest, pDigestLocal, 16);
++}
++
+ // ============================================================================
+
+ } // namespace svx
Added: trunk/patches/dev300/sc-datapilot-dynamic-range-m12.diff
==============================================================================
--- (empty file)
+++ trunk/patches/dev300/sc-datapilot-dynamic-range-m12.diff Fri May 23 23:53:50 2008
@@ -0,0 +1,564 @@
+diff -urp --exclude=CVS --exclude=unxlngi6.pro --exclude=sc.vpj sc.clean/source/ui/dbgui/fieldwnd.cxx sc/source/ui/dbgui/fieldwnd.cxx
+--- sc.clean/source/ui/dbgui/fieldwnd.cxx 2008-03-11 09:39:36.000000000 -0400
++++ sc/source/ui/dbgui/fieldwnd.cxx 2008-03-20 12:38:26.000000000 -0400
+@@ -644,7 +644,7 @@ void ScDPFieldWindow::DelField( size_t n
+
+ void ScDPFieldWindow::ClearFields()
+ {
+- if( eType == TYPE_SELECT )
++ if( eType == TYPE_SELECT || eType == TYPE_PAGE || eType == TYPE_COL || eType == TYPE_ROW || eType == TYPE_DATA)
+ {
+ com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible;
+ if (!xTempAcc.is() && pAccessible)
+diff -urp --exclude=CVS --exclude=unxlngi6.pro --exclude=sc.vpj sc.clean/source/ui/dbgui/pivot.hrc sc/source/ui/dbgui/pivot.hrc
+--- sc.clean/source/ui/dbgui/pivot.hrc 2008-03-11 09:39:36.000000000 -0400
++++ sc/source/ui/dbgui/pivot.hrc 2008-03-20 12:38:26.000000000 -0400
+@@ -71,6 +71,10 @@
+ #define BTN_FILTER 29
+ #define BTN_DRILLDOWN 30
+
++#define FT_INAREA 40
++#define RB_INAREA 41
++#define ED_INAREA 42
++
+ #define PIVOTSTR_SUM 1
+ #define PIVOTSTR_COUNT 2
+ #define PIVOTSTR_AVG 3
+diff -urp --exclude=CVS --exclude=unxlngi6.pro --exclude=sc.vpj sc.clean/source/ui/dbgui/pivot.src sc/source/ui/dbgui/pivot.src
+--- sc.clean/source/ui/dbgui/pivot.src 2008-03-11 09:39:36.000000000 -0400
++++ sc/source/ui/dbgui/pivot.src 2008-03-20 12:38:26.000000000 -0400
+@@ -163,7 +163,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+ Size = MAP_APPFONT ( 50 , 14 ) ;
+ TabStop = TRUE ;
+ MapUnit = MAP_APPFONT ;
+- Delta = 73 ;
++ Delta = 90 ;
+ };
+ Window WND_FIELD
+ {
+@@ -183,17 +183,42 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+ Text [ en-US ] = "Result" ;
+ Hide = TRUE ;
+ };
+- FixedText FT_OUTAREA
++
++ FixedText FT_INAREA
+ {
+ Pos = MAP_APPFONT ( 12 , 203 ) ;
+ Size = MAP_APPFONT ( 59 , 8 ) ;
+ Hide = TRUE ;
++ Text [ en-US ] = "Selection from" ;
++ };
++ Edit ED_INAREA
++ {
++ Border = TRUE ;
++ Pos = MAP_APPFONT ( 73 , 201 ) ;
++ Size = MAP_APPFONT ( 100 , 12 ) ;
++ TabStop = TRUE ;
++ Hide = TRUE ;
++ };
++ ImageButton RB_INAREA
++ {
++ Pos = MAP_APPFONT ( 177 , 200 ) ;
++ Size = MAP_APPFONT ( 13 , 15 ) ;
++ TabStop = TRUE ;
++ Hide = TRUE ;
++ QuickHelpText [ en-US ] = "Shrink" ;
++ };
++
++ FixedText FT_OUTAREA
++ {
++ Pos = MAP_APPFONT ( 12 , 221 ) ;
++ Size = MAP_APPFONT ( 59 , 8 ) ;
++ Hide = TRUE ;
+ Text [ en-US ] = "Results to" ;
+ };
+ ListBox LB_OUTAREA
+ {
+ Border = TRUE ;
+- Pos = MAP_APPFONT ( 73 , 201 ) ;
++ Pos = MAP_APPFONT ( 73 , 219 ) ;
+ Size = MAP_APPFONT ( 75 , 90 ) ;
+ TabStop = TRUE ;
+ DropDown = TRUE ;
+@@ -202,14 +227,14 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+ Edit ED_OUTAREA
+ {
+ Border = TRUE ;
+- Pos = MAP_APPFONT ( 152 , 201 ) ;
++ Pos = MAP_APPFONT ( 152 , 219 ) ;
+ Size = MAP_APPFONT ( 100 , 12 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+ };
+ ImageButton RB_OUTAREA
+ {
+- Pos = MAP_APPFONT ( 256 , 200 ) ;
++ Pos = MAP_APPFONT ( 256 , 218 ) ;
+ Size = MAP_APPFONT ( 13 , 15 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+@@ -217,7 +242,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+ };
+ CheckBox BTN_IGNEMPTYROWS
+ {
+- Pos = MAP_APPFONT ( 12 , 219 ) ;
++ Pos = MAP_APPFONT ( 12 , 237 ) ;
+ Size = MAP_APPFONT ( 124 , 10 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+@@ -225,7 +250,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+ };
+ CheckBox BTN_DETECTCAT
+ {
+- Pos = MAP_APPFONT ( 142 , 219 ) ;
++ Pos = MAP_APPFONT ( 142 , 237 ) ;
+ Size = MAP_APPFONT ( 124 , 10 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+@@ -233,7 +258,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+ };
+ CheckBox BTN_TOTALCOL
+ {
+- Pos = MAP_APPFONT ( 12 , 233 ) ;
++ Pos = MAP_APPFONT ( 12 , 251 ) ;
+ Size = MAP_APPFONT ( 124 , 10 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+@@ -241,7 +266,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+ };
+ CheckBox BTN_TOTALROW
+ {
+- Pos = MAP_APPFONT ( 142 , 233 ) ;
++ Pos = MAP_APPFONT ( 142 , 251 ) ;
+ Size = MAP_APPFONT ( 124 , 10 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+@@ -249,7 +274,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+ };
+ CheckBox BTN_FILTER
+ {
+- Pos = MAP_APPFONT ( 12 , 247 ) ;
++ Pos = MAP_APPFONT ( 12 , 265 ) ;
+ Size = MAP_APPFONT ( 124 , 10 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+@@ -257,7 +282,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+ };
+ CheckBox BTN_DRILLDOWN
+ {
+- Pos = MAP_APPFONT ( 142 , 247 ) ;
++ Pos = MAP_APPFONT ( 142 , 265 ) ;
+ Size = MAP_APPFONT ( 124 , 10 ) ;
+ TabStop = TRUE ;
+ Hide = TRUE ;
+diff -urp --exclude=CVS --exclude=unxlngi6.pro --exclude=sc.vpj sc.clean/source/ui/dbgui/pvlaydlg.cxx sc/source/ui/dbgui/pvlaydlg.cxx
+--- sc.clean/source/ui/dbgui/pvlaydlg.cxx 2008-03-11 09:39:36.000000000 -0400
++++ sc/source/ui/dbgui/pvlaydlg.cxx 2008-03-20 12:53:18.000000000 -0400
+@@ -41,6 +41,7 @@
+ //----------------------------------------------------------------------------
+
+ #include "pvlaydlg.hxx"
++#include "dbdocfun.hxx"
+
+ #include <sfx2/dispatch.hxx>
+ #include <vcl/msgbox.hxx>
+@@ -61,6 +62,7 @@
+ #include "pivot.hrc"
+ #include "dpobject.hxx"
+ #include "dpsave.hxx"
++#include "dpshttab.hxx"
+ #include "scmod.hxx"
+
+ #include "sc.hrc" //CHINA001
+@@ -125,6 +127,11 @@ ScDPLayoutDlg::ScDPLayoutDlg( SfxBinding
+ aFtInfo ( this, ScResId( FT_INFO ) ),
+
+ aFlAreas ( this, ScResId( FL_OUTPUT ) ),
++
++ aFtInArea ( this, ScResId( FT_INAREA) ),
++ aEdInPos ( this, ScResId( ED_INAREA) ),
++ aRbInPos ( this, ScResId( RB_INAREA ), &aEdInPos ),
++
+ aLbOutPos ( this, ScResId( LB_OUTAREA ) ),
+ aFtOutArea ( this, ScResId( FT_OUTAREA ) ),
+ aEdOutPos ( this, ScResId( ED_OUTAREA ) ),
+@@ -148,6 +155,8 @@ ScDPLayoutDlg::ScDPLayoutDlg( SfxBinding
+
+ bIsDrag ( FALSE ),
+
++ pEditActive ( NULL ),
++
+ eLastActiveType ( TYPE_SELECT ),
+ nOffset ( 0 ),
+ //
+@@ -209,6 +218,10 @@ void __EXPORT ScDPLayoutDlg::Init()
+ for ( USHORT i = 0; i < FUNC_COUNT; ++i )
+ aFuncNameArr.push_back( String( ScResId( i + 1 ) ) );
+
++ aBtnMore.AddWindow( &aFlAreas );
++ aBtnMore.AddWindow( &aFtInArea );
++ aBtnMore.AddWindow( &aEdInPos );
++ aBtnMore.AddWindow( &aRbInPos );
+ aBtnMore.AddWindow( &aFtOutArea );
+ aBtnMore.AddWindow( &aLbOutPos );
+ aBtnMore.AddWindow( &aEdOutPos );
+@@ -219,7 +232,6 @@ void __EXPORT ScDPLayoutDlg::Init()
+ aBtnMore.AddWindow( &aBtnTotalRow );
+ aBtnMore.AddWindow( &aBtnFilter );
+ aBtnMore.AddWindow( &aBtnDrillDown );
+- aBtnMore.AddWindow( &aFlAreas );
+ aBtnMore.SetClickHdl( LINK( this, ScDPLayoutDlg, MoreClickHdl ) );
+
+ {
+@@ -237,31 +249,35 @@ void __EXPORT ScDPLayoutDlg::Init()
+ aRowArr.resize( MAX_FIELDS );
+ aDataArr.resize( MAX_FIELDS );
+
+- InitWndSelect( thePivotData.ppLabelArr, static_cast<long>(thePivotData.nLabels) );
+- InitWnd( thePivotData.aPageArr, static_cast<long>(thePivotData.nPageCount), TYPE_PAGE );
+- InitWnd( thePivotData.aColArr, static_cast<long>(thePivotData.nColCount), TYPE_COL );
+- InitWnd( thePivotData.aRowArr, static_cast<long>(thePivotData.nRowCount), TYPE_ROW );
+- InitWnd( thePivotData.aDataArr, static_cast<long>(thePivotData.nDataCount), TYPE_DATA );
+-
+- aSlider.SetPageSize( PAGE_SIZE );
+- aSlider.SetVisibleSize( PAGE_SIZE );
+- aSlider.SetLineSize( LINE_SIZE );
+- aSlider.SetRange( Range( 0, static_cast<long>(((thePivotData.nLabels+LINE_SIZE-1)/LINE_SIZE)*LINE_SIZE) ) );
+-
+- if ( thePivotData.nLabels > PAGE_SIZE )
+- {
+- aSlider.SetEndScrollHdl( LINK( this, ScDPLayoutDlg, ScrollHdl ) );
+- aSlider.Show();
++ ScRange inRange;
++ String inString;
++ if (xDlgDPObject->GetSheetDesc())
++ {
++ aEdInPos.Enable();
++ aRbInPos.Enable();
++ aOldRange = xDlgDPObject->GetSheetDesc()->aSourceRange;
++ aOldRange.Format( inString, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() );
++ aEdInPos.SetText(inString);
+ }
+ else
+- aSlider.Hide();
++ {
++ /* Data is not reachable, so could be a remote database */
++ aEdInPos.Disable();
++ aRbInPos.Disable();
++ }
+
+- // Ein-/Ausgabebereiche: ----------------------------------------------
++ InitFields();
+
+ aLbOutPos .SetSelectHdl( LINK( this, ScDPLayoutDlg, SelAreaHdl ) );
+ aEdOutPos .SetModifyHdl( LINK( this, ScDPLayoutDlg, EdModifyHdl ) );
++ aEdInPos .SetModifyHdl( LINK( this, ScDPLayoutDlg, EdInModifyHdl ) );
+ aBtnOk .SetClickHdl ( LINK( this, ScDPLayoutDlg, OkHdl ) );
+ aBtnCancel.SetClickHdl ( LINK( this, ScDPLayoutDlg, CancelHdl ) );
++ Link aLink = LINK( this, ScDPLayoutDlg, GetFocusHdl );
++ if ( aEdInPos.IsEnabled() )
++ // Once disabled it will never get enabled, so no need to handle focus.
++ aEdInPos.SetGetFocusHdl( aLink );
++ aEdOutPos.SetGetFocusHdl( aLink );
+
+ if ( pViewData && pDoc )
+ {
+@@ -285,7 +301,7 @@ void __EXPORT ScDPLayoutDlg::Init()
+ {
+ USHORT nInsert = aLbOutPos.InsertEntry( aName );
+
+- aRange.aStart.Format( aRefStr, SCA_ABS_3D, pDoc );
++ aRange.aStart.Format( aRefStr, SCA_ABS_3D, pDoc, pDoc->GetAddressConvention() );
+ aLbOutPos.SetEntryData( nInsert, new String( aRefStr ) );
+ }
+ }
+@@ -296,7 +312,7 @@ void __EXPORT ScDPLayoutDlg::Init()
+ String aStr;
+ ScAddress( thePivotData.nCol,
+ thePivotData.nRow,
+- thePivotData.nTab ).Format( aStr, STD_FORMAT, pDoc );
++ thePivotData.nTab ).Format( aStr, STD_FORMAT, pDoc, pDoc->GetAddressConvention() );
+ aEdOutPos.SetText( aStr );
+ EdModifyHdl(0);
+ }
+@@ -480,6 +496,27 @@ void ScDPLayoutDlg::InitFocus()
+ aWndSelect.GrabFocus();
+ }
+
++void ScDPLayoutDlg::InitFields()
++{
++ InitWndSelect( thePivotData.ppLabelArr, static_cast<long>(thePivotData.nLabels) );
++ InitWnd( thePivotData.aPageArr, static_cast<long>(thePivotData.nPageCount), TYPE_PAGE );
++ InitWnd( thePivotData.aColArr, static_cast<long>(thePivotData.nColCount), TYPE_COL );
++ InitWnd( thePivotData.aRowArr, static_cast<long>(thePivotData.nRowCount), TYPE_ROW );
++ InitWnd( thePivotData.aDataArr, static_cast<long>(thePivotData.nDataCount), TYPE_DATA );
++
++ aSlider.SetPageSize( PAGE_SIZE );
++ aSlider.SetVisibleSize( PAGE_SIZE );
++ aSlider.SetLineSize( LINE_SIZE );
++ aSlider.SetRange( Range( 0, static_cast<long>(((thePivotData.nLabels+LINE_SIZE-1)/LINE_SIZE)*LINE_SIZE) ) );
++
++ if ( thePivotData.nLabels > PAGE_SIZE )
++ {
++ aSlider.SetEndScrollHdl( LINK( this, ScDPLayoutDlg, ScrollHdl ) );
++ aSlider.Show();
++ }
++ else
++ aSlider.Hide();
++}
+
+ //----------------------------------------------------------------------------
+
+@@ -1314,22 +1351,78 @@ BOOL ScDPLayoutDlg::GetPivotArrays( P
+ return bFit;
+ }
+
++void ScDPLayoutDlg::UpdateSrcRange()
++{
++ String theCurPosStr = aEdInPos.GetText();
++ USHORT nResult = ScRange().Parse(theCurPosStr, pDoc, pDoc->GetAddressConvention());
++
++ if ( SCA_VALID != (nResult & SCA_VALID) )
++ // invalid source range.
++ return;
++
++ ScRefAddress start, end;
++ ConvertDoubleRef(pDoc, theCurPosStr, 1, start, end, pDoc->GetAddressConvention());
++ ScRange aNewRange(start.GetAddress(), end.GetAddress());
++ ScSheetSourceDesc inSheet = *xDlgDPObject->GetSheetDesc();
++
++ if (inSheet.aSourceRange == aNewRange)
++ // new range is identical to the current range. Nothing to do.
++ return;
++
++ ScTabViewShell * pTabViewShell = pViewData->GetViewShell();
++ inSheet.aSourceRange = aNewRange;
++ xDlgDPObject->SetSheetDesc(inSheet);
++ xDlgDPObject->InvalidateSource();
++ xDlgDPObject->FillOldParam( thePivotData, FALSE );
++ xDlgDPObject->FillLabelData(thePivotData);
++
++ pTabViewShell->SetDialogDPObject(xDlgDPObject.get());
++ aLabelDataArr.clear();
++ aWndSelect.ClearFields();
++ aWndData.ClearFields();
++ aWndRow.ClearFields();
++ aWndCol.ClearFields();
++ aWndPage.ClearFields();
++
++ for (USHORT i = 0; i < MAX_LABELS; ++i)
++ aSelectArr[i].reset();
++
++ for (USHORT i = 0; i < MAX_FIELDS; ++i)
++ {
++ RemoveField(TYPE_COL, i);
++ RemoveField(TYPE_ROW, i);
++ RemoveField(TYPE_DATA, i);
++ }
++
++ for (USHORT i = 0; i < MAX_PAGEFIELDS; ++i)
++ RemoveField(TYPE_PAGE, i);
++
++ InitFields();
++
++ return;
++}
+
+ //----------------------------------------------------------------------------
+
+ void ScDPLayoutDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
+ {
+- if ( bRefInputMode )
+- {
++ if ( !bRefInputMode || !pEditActive )
++ return;
++
+ if ( rRef.aStart != rRef.aEnd )
+- RefInputStart( &aEdOutPos );
+-/*
+- ScAddress aAdr( nStartCol, nStartRow, nStartTab );
+- aAdr.PutInOrder( ScAddress( nEndCol, nEndRow, nEndTab ) );
+-*/
++ RefInputStart( pEditActive );
++
++ if ( pEditActive == &aEdInPos )
++ {
+ String aRefStr;
+- rRef.aStart.Format( aRefStr, STD_FORMAT, pDocP );
+- aEdOutPos.SetRefString( aRefStr );
++ rRef.Format( aRefStr, SCR_ABS_3D, pDocP, pDocP->GetAddressConvention() );
++ pEditActive->SetRefString( aRefStr );
++ }
++ else if ( pEditActive == &aEdOutPos )
++ {
++ String aRefStr;
++ rRef.aStart.Format( aRefStr, STD_FORMAT, pDocP, pDocP->GetAddressConvention() );
++ pEditActive->SetRefString( aRefStr );
+ }
+ }
+
+@@ -1340,7 +1433,12 @@ void ScDPLayoutDlg::SetActive()
+ {
+ if ( bRefInputMode )
+ {
+- aEdOutPos.GrabFocus();
++ if ( pEditActive )
++ pEditActive->GrabFocus();
++
++ if ( pEditActive == &aEdInPos )
++ EdInModifyHdl( NULL );
++ else if ( pEditActive == &aEdOutPos )
+ EdModifyHdl( NULL );
+ }
+ else
+@@ -1379,7 +1477,7 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButto
+ String aOutPosStr( aEdOutPos.GetText() );
+ ScAddress aAdrDest;
+ BOOL bToNewTable = (aLbOutPos.GetSelectEntryPos() == 1);
+- USHORT nResult = !bToNewTable ? aAdrDest.Parse( aOutPosStr, pDoc ) : 0;
++ USHORT nResult = !bToNewTable ? aAdrDest.Parse( aOutPosStr, pDoc, pDoc->GetAddressConvention() ) : 0;
+
+ if ( bToNewTable
+ || ( (aOutPosStr.Len() > 0) && (SCA_VALID == (nResult & SCA_VALID)) ) )
+@@ -1497,12 +1595,11 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButto
+
+ //----------------------------------------------------------------------------
+
+-IMPL_LINK_INLINE_START( ScDPLayoutDlg, CancelHdl, CancelButton *, EMPTYARG )
++IMPL_LINK( ScDPLayoutDlg, CancelHdl, CancelButton *, EMPTYARG )
+ {
+ Close();
+ return 0;
+ }
+-IMPL_LINK_INLINE_END( ScDPLayoutDlg, CancelHdl, CancelButton *, EMPTYARG )
+
+
+ //----------------------------------------------------------------------------
+@@ -1514,9 +1611,18 @@ IMPL_LINK( ScDPLayoutDlg, MoreClickHdl,
+ bRefInputMode = TRUE;
+ //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
+ //SFX_APPWINDOW->Enable();
++ if ( aEdInPos.IsEnabled() )
++ {
++ aEdInPos.Enable();
++ aEdInPos.GrabFocus();
++ aEdInPos.Enable();
++ }
++ else
++ {
+ aEdOutPos.Enable();
+ aEdOutPos.GrabFocus();
+- aRbOutPos.Enable();
++ aEdOutPos.Enable();
++ }
+ }
+ else
+ {
+@@ -1533,7 +1639,7 @@ IMPL_LINK( ScDPLayoutDlg, MoreClickHdl,
+ IMPL_LINK( ScDPLayoutDlg, EdModifyHdl, Edit *, EMPTYARG )
+ {
+ String theCurPosStr = aEdOutPos.GetText();
+- USHORT nResult = ScAddress().Parse( theCurPosStr, pDoc );
++ USHORT nResult = ScAddress().Parse( theCurPosStr, pDoc, pDoc->GetAddressConvention() );
+
+ if ( SCA_VALID == (nResult & SCA_VALID) )
+ {
+@@ -1557,6 +1663,13 @@ IMPL_LINK( ScDPLayoutDlg, EdModifyHdl, E
+ }
+
+
++IMPL_LINK( ScDPLayoutDlg, EdInModifyHdl, Edit *, EMPTYARG )
++{
++ UpdateSrcRange();
++ return 0;
++}
++
++
+ //----------------------------------------------------------------------------
+
+ IMPL_LINK( ScDPLayoutDlg, SelAreaHdl, ListBox *, EMPTYARG )
+@@ -1610,4 +1723,16 @@ IMPL_LINK( ScDPLayoutDlg, ScrollHdl, Scr
+ return 0;
+ }
+
++//----------------------------------------------------------------------------
++
++IMPL_LINK( ScDPLayoutDlg, GetFocusHdl, Control*, pCtrl )
++{
++ pEditActive = NULL;
++ if ( pCtrl == &aEdInPos )
++ pEditActive = &aEdInPos;
++ else if ( pCtrl == &aEdOutPos )
++ pEditActive = &aEdOutPos;
++
++ return 0;
++}
+
+diff -urp --exclude=CVS --exclude=unxlngi6.pro --exclude=sc.vpj sc.clean/source/ui/inc/pvlaydlg.hxx sc/source/ui/inc/pvlaydlg.hxx
+--- sc.clean/source/ui/inc/pvlaydlg.hxx 2008-03-11 09:39:34.000000000 -0400
++++ sc/source/ui/inc/pvlaydlg.hxx 2008-03-20 12:38:26.000000000 -0400
+@@ -143,10 +143,18 @@ private:
+ FixedInfo aFtInfo;
+
+ FixedLine aFlAreas;
++
++ // DP source selection
++ FixedText aFtInArea;
++ ScRefEdit aEdInPos;
++ ScRefButton aRbInPos;
++
++ // DP output location
+ ListBox aLbOutPos;
+ FixedText aFtOutArea;
+ ScRefEdit aEdOutPos;
+ ScRefButton aRbOutPos;
++
+ CheckBox aBtnIgnEmptyRows;
+ CheckBox aBtnDetectCat;
+ CheckBox aBtnTotalCol;
+@@ -169,6 +177,8 @@ private:
+ size_t nDnDFromIndex;
+ BOOL bIsDrag;
+
++ ScRefEdit* pEditActive;
++
+ Rectangle aRectPage;
+ Rectangle aRectRow;
+ Rectangle aRectCol;
+@@ -187,6 +197,7 @@ private:
+ ScDPFuncDataVec aDataArr;
+
+ ScDPObjectPtr xDlgDPObject;
++ ScRange aOldRange;
+ ScPivotParam thePivotData;
+ ScViewData* pViewData;
+ ScDocument* pDoc;
+@@ -198,6 +209,7 @@ private:
+ void InitWndSelect ( LabelData** ppLabelArr, long nLabels );
+ void InitWnd ( PivotField* pArr, long nCount, ScDPFieldType eType );
+ void InitFocus ();
++ void InitFields ();
+ void CalcWndSizes ();
+ Point DlgPos2WndPos ( const Point& rPt, Window& rWnd );
+ ScDPLabelData* GetLabelData ( SCsCOL nCol, size_t* pPos = NULL );
+@@ -221,14 +233,19 @@ private:
+ USHORT& rColCount,
+ USHORT& rRowCount,
+ USHORT& rDataCount );
++
++ void UpdateSrcRange();
++
+ // Handler
+ DECL_LINK( ClickHdl, PushButton * );
+ DECL_LINK( ScrollHdl, ScrollBar * );
+ DECL_LINK( SelAreaHdl, ListBox * );
+ DECL_LINK( MoreClickHdl, MoreButton * );
+ DECL_LINK( EdModifyHdl, Edit * );
++ DECL_LINK( EdInModifyHdl, Edit * );
+ DECL_LINK( OkHdl, OKButton * );
+ DECL_LINK( CancelHdl, CancelButton * );
++ DECL_LINK( GetFocusHdl, Control* );
+ };
+
+
Modified: trunk/patches/dev300/sc-datapilot-dynamic-range.diff
==============================================================================
--- trunk/patches/dev300/sc-datapilot-dynamic-range.diff (original)
+++ trunk/patches/dev300/sc-datapilot-dynamic-range.diff Fri May 23 23:53:50 2008
@@ -1,7 +1,7 @@
diff -urp --exclude=CVS --exclude=unxlngi6.pro --exclude=sc.vpj sc.clean/source/ui/dbgui/fieldwnd.cxx sc/source/ui/dbgui/fieldwnd.cxx
---- sc.clean/source/ui/dbgui/fieldwnd.cxx 2008-03-11 09:39:36.000000000 -0400
-+++ sc/source/ui/dbgui/fieldwnd.cxx 2008-03-20 12:38:26.000000000 -0400
-@@ -644,7 +644,7 @@ void ScDPFieldWindow::DelField( size_t n
+--- sc.clean/source/ui/dbgui/fieldwnd.cxx 2008-05-23 19:00:55.000000000 -0400
++++ sc/source/ui/dbgui/fieldwnd.cxx 2008-05-23 19:08:04.000000000 -0400
+@@ -632,7 +632,7 @@ void ScDPFieldWindow::DelField( size_t n
void ScDPFieldWindow::ClearFields()
{
@@ -10,10 +10,11 @@
{
com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible;
if (!xTempAcc.is() && pAccessible)
+Only in sc/source/ui/dbgui: fieldwnd.cxx.orig
diff -urp --exclude=CVS --exclude=unxlngi6.pro --exclude=sc.vpj sc.clean/source/ui/dbgui/pivot.hrc sc/source/ui/dbgui/pivot.hrc
---- sc.clean/source/ui/dbgui/pivot.hrc 2008-03-11 09:39:36.000000000 -0400
-+++ sc/source/ui/dbgui/pivot.hrc 2008-03-20 12:38:26.000000000 -0400
-@@ -71,6 +71,10 @@
+--- sc.clean/source/ui/dbgui/pivot.hrc 2008-05-23 19:00:55.000000000 -0400
++++ sc/source/ui/dbgui/pivot.hrc 2008-05-23 19:08:04.000000000 -0400
+@@ -66,6 +66,10 @@
#define BTN_FILTER 29
#define BTN_DRILLDOWN 30
@@ -24,10 +25,11 @@
#define PIVOTSTR_SUM 1
#define PIVOTSTR_COUNT 2
#define PIVOTSTR_AVG 3
+Only in sc/source/ui/dbgui: pivot.hrc.orig
diff -urp --exclude=CVS --exclude=unxlngi6.pro --exclude=sc.vpj sc.clean/source/ui/dbgui/pivot.src sc/source/ui/dbgui/pivot.src
---- sc.clean/source/ui/dbgui/pivot.src 2008-03-11 09:39:36.000000000 -0400
-+++ sc/source/ui/dbgui/pivot.src 2008-03-20 12:38:26.000000000 -0400
-@@ -163,7 +163,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+--- sc.clean/source/ui/dbgui/pivot.src 2008-05-23 19:00:55.000000000 -0400
++++ sc/source/ui/dbgui/pivot.src 2008-05-23 19:08:04.000000000 -0400
+@@ -158,7 +158,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
Size = MAP_APPFONT ( 50 , 14 ) ;
TabStop = TRUE ;
MapUnit = MAP_APPFONT ;
@@ -36,7 +38,7 @@
};
Window WND_FIELD
{
-@@ -183,17 +183,42 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+@@ -178,17 +178,42 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
Text [ en-US ] = "Result" ;
Hide = TRUE ;
};
@@ -81,7 +83,7 @@
Size = MAP_APPFONT ( 75 , 90 ) ;
TabStop = TRUE ;
DropDown = TRUE ;
-@@ -202,14 +227,14 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+@@ -197,14 +222,14 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
Edit ED_OUTAREA
{
Border = TRUE ;
@@ -98,7 +100,7 @@
Size = MAP_APPFONT ( 13 , 15 ) ;
TabStop = TRUE ;
Hide = TRUE ;
-@@ -217,7 +242,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+@@ -212,7 +237,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
};
CheckBox BTN_IGNEMPTYROWS
{
@@ -107,7 +109,7 @@
Size = MAP_APPFONT ( 124 , 10 ) ;
TabStop = TRUE ;
Hide = TRUE ;
-@@ -225,7 +250,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+@@ -220,7 +245,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
};
CheckBox BTN_DETECTCAT
{
@@ -116,7 +118,7 @@
Size = MAP_APPFONT ( 124 , 10 ) ;
TabStop = TRUE ;
Hide = TRUE ;
-@@ -233,7 +258,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+@@ -228,7 +253,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
};
CheckBox BTN_TOTALCOL
{
@@ -125,7 +127,7 @@
Size = MAP_APPFONT ( 124 , 10 ) ;
TabStop = TRUE ;
Hide = TRUE ;
-@@ -241,7 +266,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+@@ -236,7 +261,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
};
CheckBox BTN_TOTALROW
{
@@ -134,7 +136,7 @@
Size = MAP_APPFONT ( 124 , 10 ) ;
TabStop = TRUE ;
Hide = TRUE ;
-@@ -249,7 +274,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+@@ -244,7 +269,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
};
CheckBox BTN_FILTER
{
@@ -143,7 +145,7 @@
Size = MAP_APPFONT ( 124 , 10 ) ;
TabStop = TRUE ;
Hide = TRUE ;
-@@ -257,7 +282,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
+@@ -252,7 +277,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT
};
CheckBox BTN_DRILLDOWN
{
@@ -152,10 +154,11 @@
Size = MAP_APPFONT ( 124 , 10 ) ;
TabStop = TRUE ;
Hide = TRUE ;
+Only in sc/source/ui/dbgui: pivot.src.orig
diff -urp --exclude=CVS --exclude=unxlngi6.pro --exclude=sc.vpj sc.clean/source/ui/dbgui/pvlaydlg.cxx sc/source/ui/dbgui/pvlaydlg.cxx
---- sc.clean/source/ui/dbgui/pvlaydlg.cxx 2008-03-11 09:39:36.000000000 -0400
-+++ sc/source/ui/dbgui/pvlaydlg.cxx 2008-03-20 12:53:18.000000000 -0400
-@@ -41,6 +41,7 @@
+--- sc.clean/source/ui/dbgui/pvlaydlg.cxx 2008-05-23 19:00:55.000000000 -0400
++++ sc/source/ui/dbgui/pvlaydlg.cxx 2008-05-23 19:14:05.000000000 -0400
+@@ -36,6 +36,7 @@
//----------------------------------------------------------------------------
#include "pvlaydlg.hxx"
@@ -163,7 +166,7 @@
#include <sfx2/dispatch.hxx>
#include <vcl/msgbox.hxx>
-@@ -61,6 +62,7 @@
+@@ -56,6 +57,7 @@
#include "pivot.hrc"
#include "dpobject.hxx"
#include "dpsave.hxx"
@@ -171,7 +174,7 @@
#include "scmod.hxx"
#include "sc.hrc" //CHINA001
-@@ -125,6 +127,11 @@ ScDPLayoutDlg::ScDPLayoutDlg( SfxBinding
+@@ -120,6 +122,11 @@ ScDPLayoutDlg::ScDPLayoutDlg( SfxBinding
aFtInfo ( this, ScResId( FT_INFO ) ),
aFlAreas ( this, ScResId( FL_OUTPUT ) ),
@@ -183,7 +186,7 @@
aLbOutPos ( this, ScResId( LB_OUTAREA ) ),
aFtOutArea ( this, ScResId( FT_OUTAREA ) ),
aEdOutPos ( this, ScResId( ED_OUTAREA ) ),
-@@ -148,6 +155,8 @@ ScDPLayoutDlg::ScDPLayoutDlg( SfxBinding
+@@ -143,6 +150,8 @@ ScDPLayoutDlg::ScDPLayoutDlg( SfxBinding
bIsDrag ( FALSE ),
@@ -192,7 +195,7 @@
eLastActiveType ( TYPE_SELECT ),
nOffset ( 0 ),
//
-@@ -209,6 +218,10 @@ void __EXPORT ScDPLayoutDlg::Init()
+@@ -204,6 +213,10 @@ void __EXPORT ScDPLayoutDlg::Init()
for ( USHORT i = 0; i < FUNC_COUNT; ++i )
aFuncNameArr.push_back( String( ScResId( i + 1 ) ) );
@@ -203,7 +206,7 @@
aBtnMore.AddWindow( &aFtOutArea );
aBtnMore.AddWindow( &aLbOutPos );
aBtnMore.AddWindow( &aEdOutPos );
-@@ -219,7 +232,6 @@ void __EXPORT ScDPLayoutDlg::Init()
+@@ -214,7 +227,6 @@ void __EXPORT ScDPLayoutDlg::Init()
aBtnMore.AddWindow( &aBtnTotalRow );
aBtnMore.AddWindow( &aBtnFilter );
aBtnMore.AddWindow( &aBtnDrillDown );
@@ -211,7 +214,7 @@
aBtnMore.SetClickHdl( LINK( this, ScDPLayoutDlg, MoreClickHdl ) );
{
-@@ -237,31 +249,35 @@ void __EXPORT ScDPLayoutDlg::Init()
+@@ -232,31 +244,35 @@ void __EXPORT ScDPLayoutDlg::Init()
aRowArr.resize( MAX_FIELDS );
aDataArr.resize( MAX_FIELDS );
@@ -264,25 +267,7 @@
if ( pViewData && pDoc )
{
-@@ -285,7 +301,7 @@ void __EXPORT ScDPLayoutDlg::Init()
- {
- USHORT nInsert = aLbOutPos.InsertEntry( aName );
-
-- aRange.aStart.Format( aRefStr, SCA_ABS_3D, pDoc );
-+ aRange.aStart.Format( aRefStr, SCA_ABS_3D, pDoc, pDoc->GetAddressConvention() );
- aLbOutPos.SetEntryData( nInsert, new String( aRefStr ) );
- }
- }
-@@ -296,7 +312,7 @@ void __EXPORT ScDPLayoutDlg::Init()
- String aStr;
- ScAddress( thePivotData.nCol,
- thePivotData.nRow,
-- thePivotData.nTab ).Format( aStr, STD_FORMAT, pDoc );
-+ thePivotData.nTab ).Format( aStr, STD_FORMAT, pDoc, pDoc->GetAddressConvention() );
- aEdOutPos.SetText( aStr );
- EdModifyHdl(0);
- }
-@@ -480,6 +496,27 @@ void ScDPLayoutDlg::InitFocus()
+@@ -475,6 +491,27 @@ void ScDPLayoutDlg::InitFocus()
aWndSelect.GrabFocus();
}
@@ -310,7 +295,7 @@
//----------------------------------------------------------------------------
-@@ -1314,22 +1351,78 @@ BOOL ScDPLayoutDlg::GetPivotArrays( P
+@@ -1309,23 +1346,79 @@ BOOL ScDPLayoutDlg::GetPivotArrays( P
return bFit;
}
@@ -371,34 +356,37 @@
{
- if ( bRefInputMode )
- {
-+ if ( !bRefInputMode || !pEditActive )
-+ return;
-+
- if ( rRef.aStart != rRef.aEnd )
+- if ( rRef.aStart != rRef.aEnd )
- RefInputStart( &aEdOutPos );
-/*
- ScAddress aAdr( nStartCol, nStartRow, nStartTab );
- aAdr.PutInOrder( ScAddress( nEndCol, nEndRow, nEndTab ) );
-*/
+- String aRefStr;
++ if ( !bRefInputMode || !pEditActive )
++ return;
++
++ if ( rRef.aStart != rRef.aEnd )
+ RefInputStart( pEditActive );
+
+ if ( pEditActive == &aEdInPos )
+ {
- String aRefStr;
-- rRef.aStart.Format( aRefStr, STD_FORMAT, pDocP );
-- aEdOutPos.SetRefString( aRefStr );
++ String aRefStr;
+ rRef.Format( aRefStr, SCR_ABS_3D, pDocP, pDocP->GetAddressConvention() );
+ pEditActive->SetRefString( aRefStr );
+ }
+ else if ( pEditActive == &aEdOutPos )
+ {
+ String aRefStr;
-+ rRef.aStart.Format( aRefStr, STD_FORMAT, pDocP, pDocP->GetAddressConvention() );
+ rRef.aStart.Format( aRefStr, STD_FORMAT, pDocP, pDocP->GetAddressConvention() );
+- aEdOutPos.SetRefString( aRefStr );
+- }
+ pEditActive->SetRefString( aRefStr );
- }
++ }
}
-@@ -1340,7 +1433,12 @@ void ScDPLayoutDlg::SetActive()
+
+@@ -1335,7 +1428,12 @@ void ScDPLayoutDlg::SetActive()
{
if ( bRefInputMode )
{
@@ -412,7 +400,7 @@
EdModifyHdl( NULL );
}
else
-@@ -1379,7 +1477,7 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButto
+@@ -1374,7 +1472,7 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButto
String aOutPosStr( aEdOutPos.GetText() );
ScAddress aAdrDest;
BOOL bToNewTable = (aLbOutPos.GetSelectEntryPos() == 1);
@@ -421,7 +409,7 @@
if ( bToNewTable
|| ( (aOutPosStr.Len() > 0) && (SCA_VALID == (nResult & SCA_VALID)) ) )
-@@ -1497,12 +1595,11 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButto
+@@ -1492,12 +1590,11 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButto
//----------------------------------------------------------------------------
@@ -435,7 +423,7 @@
//----------------------------------------------------------------------------
-@@ -1514,9 +1611,18 @@ IMPL_LINK( ScDPLayoutDlg, MoreClickHdl,
+@@ -1509,9 +1606,18 @@ IMPL_LINK( ScDPLayoutDlg, MoreClickHdl,
bRefInputMode = TRUE;
//@BugID 54702 Enablen/Disablen nur noch in Basisklasse
//SFX_APPWINDOW->Enable();
@@ -455,7 +443,7 @@
}
else
{
-@@ -1533,7 +1639,7 @@ IMPL_LINK( ScDPLayoutDlg, MoreClickHdl,
+@@ -1528,7 +1634,7 @@ IMPL_LINK( ScDPLayoutDlg, MoreClickHdl,
IMPL_LINK( ScDPLayoutDlg, EdModifyHdl, Edit *, EMPTYARG )
{
String theCurPosStr = aEdOutPos.GetText();
@@ -464,7 +452,7 @@
if ( SCA_VALID == (nResult & SCA_VALID) )
{
-@@ -1557,6 +1663,13 @@ IMPL_LINK( ScDPLayoutDlg, EdModifyHdl, E
+@@ -1552,6 +1658,13 @@ IMPL_LINK( ScDPLayoutDlg, EdModifyHdl, E
}
@@ -478,7 +466,7 @@
//----------------------------------------------------------------------------
IMPL_LINK( ScDPLayoutDlg, SelAreaHdl, ListBox *, EMPTYARG )
-@@ -1610,4 +1723,16 @@ IMPL_LINK( ScDPLayoutDlg, ScrollHdl, Scr
+@@ -1605,4 +1718,16 @@ IMPL_LINK( ScDPLayoutDlg, ScrollHdl, Scr
return 0;
}
@@ -495,10 +483,11 @@
+ return 0;
+}
+Only in sc/source/ui/dbgui: pvlaydlg.cxx.orig
diff -urp --exclude=CVS --exclude=unxlngi6.pro --exclude=sc.vpj sc.clean/source/ui/inc/pvlaydlg.hxx sc/source/ui/inc/pvlaydlg.hxx
---- sc.clean/source/ui/inc/pvlaydlg.hxx 2008-03-11 09:39:34.000000000 -0400
-+++ sc/source/ui/inc/pvlaydlg.hxx 2008-03-20 12:38:26.000000000 -0400
-@@ -143,10 +143,18 @@ private:
+--- sc.clean/source/ui/inc/pvlaydlg.hxx 2008-05-23 19:00:53.000000000 -0400
++++ sc/source/ui/inc/pvlaydlg.hxx 2008-05-23 19:08:04.000000000 -0400
+@@ -129,10 +129,18 @@ private:
FixedInfo aFtInfo;
FixedLine aFlAreas;
@@ -517,7 +506,7 @@
CheckBox aBtnIgnEmptyRows;
CheckBox aBtnDetectCat;
CheckBox aBtnTotalCol;
-@@ -169,6 +177,8 @@ private:
+@@ -155,6 +163,8 @@ private:
size_t nDnDFromIndex;
BOOL bIsDrag;
@@ -526,7 +515,7 @@
Rectangle aRectPage;
Rectangle aRectRow;
Rectangle aRectCol;
-@@ -187,6 +197,7 @@ private:
+@@ -173,6 +183,7 @@ private:
ScDPFuncDataVec aDataArr;
ScDPObjectPtr xDlgDPObject;
@@ -534,7 +523,7 @@
ScPivotParam thePivotData;
ScViewData* pViewData;
ScDocument* pDoc;
-@@ -198,6 +209,7 @@ private:
+@@ -184,6 +195,7 @@ private:
void InitWndSelect ( LabelData** ppLabelArr, long nLabels );
void InitWnd ( PivotField* pArr, long nCount, ScDPFieldType eType );
void InitFocus ();
@@ -542,7 +531,7 @@
void CalcWndSizes ();
Point DlgPos2WndPos ( const Point& rPt, Window& rWnd );
ScDPLabelData* GetLabelData ( SCsCOL nCol, size_t* pPos = NULL );
-@@ -221,14 +233,19 @@ private:
+@@ -207,14 +219,19 @@ private:
USHORT& rColCount,
USHORT& rRowCount,
USHORT& rDataCount );
@@ -562,3 +551,4 @@
};
+Only in sc/source/ui/inc: pvlaydlg.hxx.orig
Added: trunk/patches/dev300/webdav-locking-serve-dav-uri-m12.diff
==============================================================================
--- (empty file)
+++ trunk/patches/dev300/webdav-locking-serve-dav-uri-m12.diff Fri May 23 23:53:50 2008
@@ -0,0 +1,313 @@
+diff --git officecfg/registry/data/org/openoffice/ucb/Configuration.xcu officecfg/registry/data/org/openoffice/ucb/Configuration.xcu
+index 4c5f119..e553404 100644
+--- officecfg/registry/data/org/openoffice/ucb/Configuration.xcu
++++ officecfg/registry/data/org/openoffice/ucb/Configuration.xcu
+@@ -150,18 +150,62 @@
+ <value/>
+ </prop>
+ </node>
+- <node oor:name="Provider12" oor:op="replace">
+- <prop oor:name="ServiceName">
+- <value>com.sun.star.ucb.WebDAVContentProvider</value>
+- </prop>
+- <prop oor:name="URLTemplate">
+- <value>https</value>
+- </prop>
+- <prop oor:name="Arguments">
+- <value/>
+- </prop>
+- </node>
+- </node>
++ <node oor:name="Provider12" oor:op="replace">
++ <prop oor:name="ServiceName">
++ <value>com.sun.star.ucb.WebDAVContentProvider</value>
++ </prop>
++ <prop oor:name="URLTemplate">
++ <value>https</value>
++ </prop>
++ <prop oor:name="Arguments">
++ <value/>
++ </prop>
++ </node>
++ <node oor:name="Provider13" oor:op="replace">
++ <prop oor:name="ServiceName">
++ <value>com.sun.star.ucb.WebDAVContentProvider</value>
++ </prop>
++ <prop oor:name="URLTemplate">
++ <value>dav</value>
++ </prop>
++ <prop oor:name="Arguments">
++ <value/>
++ </prop>
++ </node>
++ <node oor:name="Provider14" oor:op="replace">
++ <prop oor:name="ServiceName">
++ <value>com.sun.star.ucb.WebDAVContentProvider</value>
++ </prop>
++ <prop oor:name="URLTemplate">
++ <value>davs</value>
++ </prop>
++ <prop oor:name="Arguments">
++ <value/>
++ </prop>
++ </node>
++ <node oor:name="Provider15" oor:op="replace">
++ <prop oor:name="ServiceName">
++ <value>com.sun.star.ucb.WebDAVContentProvider</value>
++ </prop>
++ <prop oor:name="URLTemplate">
++ <value>webdav</value>
++ </prop>
++ <prop oor:name="Arguments">
++ <value/>
++ </prop>
++ </node>
++ <node oor:name="Provider16" oor:op="replace">
++ <prop oor:name="ServiceName">
++ <value>com.sun.star.ucb.WebDAVContentProvider</value>
++ </prop>
++ <prop oor:name="URLTemplate">
++ <value>webdavs</value>
++ </prop>
++ <prop oor:name="Arguments">
++ <value/>
++ </prop>
++ </node>
++ </node>
+ </node>
+ </node>
+ </node>
+diff --git tools/inc/tools/urlobj.hxx tools/inc/tools/urlobj.hxx
+index 199079f..477c1ec 100644
+--- tools/inc/tools/urlobj.hxx
++++ tools/inc/tools/urlobj.hxx
+@@ -163,9 +163,13 @@ enum INetProtocol
+ INET_PROT_VND_SUN_STAR_EXPAND = 29,
+ INET_PROT_VND_SUN_STAR_TDOC = 30,
+ INET_PROT_SMB = 31,
+- INET_PROT_GENERIC = 32,
+- INET_PROT_GENERIC_HIERARCHICAL = 33,
+- INET_PROT_END = 34
++ INET_PROT_DAV = 32,
++ INET_PROT_DAVS = 33,
++ INET_PROT_WEBDAV = 34,
++ INET_PROT_WEBDAVS = 35,
++ INET_PROT_GENERIC = 36,
++ INET_PROT_GENERIC_HIERARCHICAL = 37,
++ INET_PROT_END = 38
+ };
+
+ //============================================================================
+diff --git tools/source/fsys/urlobj.cxx tools/source/fsys/urlobj.cxx
+index 431bfb5..b5a51f9 100644
+--- tools/source/fsys/urlobj.cxx
++++ tools/source/fsys/urlobj.cxx
+@@ -464,6 +464,14 @@ static INetURLObject::SchemeInfo const aSchemeInfoMap[INET_PROT_END]
+ false, false, false, true, false },
+ { "smb", "smb://", 139, true, true, false, true, true, true, true,
+ true },
++ { "dav", "dav://", 80, true, false, false, false, true, true, true,
++ true },
++ { "davs", "davs://", 443, true, false, false, false, true, true,
++ true, true },
++ { "webdav", "webdav://", 80, true, false, false, false, true, true, true,
++ true },
++ { "webdavs", "webdavs://", 443, true, false, false, false, true, true,
++ true, true },
+ { "", "", 0, false, false, false, false, false, false, false, false },
+ { "", "", 0, false, false, false, false, false, false, true, false }
+ };
+@@ -2113,6 +2121,8 @@ INetURLObject::getPrefix(sal_Unicode const *& rBegin,
+ PrefixInfo::INTERNAL },
+ { "cid:", 0, INET_PROT_CID, PrefixInfo::OFFICIAL },
+ { "data:", 0, INET_PROT_DATA, PrefixInfo::OFFICIAL },
++ { "dav:", 0, INET_PROT_DAV, PrefixInfo::OFFICIAL },
++ { "davs:", 0, INET_PROT_DAVS, PrefixInfo::OFFICIAL },
+ { "db:", "staroffice.db:", INET_PROT_DB, PrefixInfo::INTERNAL },
+ { "file:", 0, INET_PROT_FILE, PrefixInfo::OFFICIAL },
+ { "ftp:", 0, INET_PROT_FTP, PrefixInfo::OFFICIAL },
+@@ -2194,6 +2204,8 @@ INetURLObject::getPrefix(sal_Unicode const *& rBegin,
+ PrefixInfo::OFFICIAL },
+ { "vnd.sun.star.wfs:", 0, INET_PROT_VND_SUN_STAR_WFS,
+ PrefixInfo::OFFICIAL },
++ { "webdav:", 0, INET_PROT_WEBDAV, PrefixInfo::OFFICIAL },
++ { "webdavs:", 0, INET_PROT_WEBDAVS, PrefixInfo::OFFICIAL },
+ { "wfs:", "vnd.sun.star.wfs:", INET_PROT_VND_SUN_STAR_WFS,
+ PrefixInfo::ALIAS } };
+ PrefixInfo const * pFirst = aMap + 1;
+@@ -2986,6 +2998,10 @@ bool INetURLObject::parsePath(INetProtocol eScheme,
+ case INET_PROT_VND_SUN_STAR_WEBDAV:
+ case INET_PROT_HTTPS:
+ case INET_PROT_SMB:
++ case INET_PROT_DAV:
++ case INET_PROT_DAVS:
++ case INET_PROT_WEBDAV:
++ case INET_PROT_WEBDAVS:
+ if (pPos < pEnd && *pPos != '/')
+ return false;
+ while (pPos < pEnd && *pPos != nQueryDelimiter
+diff --git ucb/source/ucp/webdav/webdavcontent.cxx ucb/source/ucp/webdav/webdavcontent.cxx
+index 16223f6..6fae616 100644
+--- ucb/source/ucp/webdav/webdavcontent.cxx
++++ ucb/source/ucp/webdav/webdavcontent.cxx
+@@ -2814,11 +2814,23 @@ void Content::transfer(
+ //
+ const rtl::OUString aScheme = sourceURI.GetScheme().toAsciiLowerCase();
+ if ( aScheme.equalsAsciiL(
+- RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) )
++ RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) ||
++ aScheme.equalsAsciiL(
++ RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) ||
++ aScheme.equalsAsciiL(
++ RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAV_URL_SCHEME ) ) )
+ {
+ sourceURI.SetScheme(
+ rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) );
+ }
++ else if ( aScheme.equalsAsciiL(
++ RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) ||
++ aScheme.equalsAsciiL(
++ RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAVS_URL_SCHEME ) ) )
++ {
++ sourceURI.SetScheme(
++ rtl::OUString::createFromAscii( HTTPS_URL_SCHEME ) );
++ }
+ else
+ {
+ if ( !aScheme.equalsAsciiL(
+@@ -2838,9 +2850,23 @@ void Content::transfer(
+ }
+
+ if ( targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL(
+- RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) )
++ RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) ||
++ targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL(
++ RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) ||
++ targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL(
++ RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAV_URL_SCHEME ) ) )
++ {
+ targetURI.SetScheme(
+ rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) );
++ }
++ else if ( targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL(
++ RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) ||
++ targetURI.GetScheme().toAsciiLowerCase().equalsAsciiL(
++ RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAVS_URL_SCHEME ) ) )
++ {
++ targetURI.SetScheme(
++ rtl::OUString::createFromAscii( HTTPS_URL_SCHEME ) );
++ }
+
+ // @@@ This implementation of 'transfer' only works
+ // if the source and target are located at same host.
+diff --git ucb/source/ucp/webdav/webdavprovider.cxx ucb/source/ucp/webdav/webdavprovider.cxx
+index 9790870..6b219ef 100644
+--- ucb/source/ucp/webdav/webdavprovider.cxx
++++ ucb/source/ucp/webdav/webdavprovider.cxx
+@@ -42,6 +42,8 @@
+ **************************************************************************
+
+ *************************************************************************/
++
++#include <string.h>
+ #include <ucbhelper/contentidentifier.hxx>
+ #include "webdavprovider.hxx"
+ #include "webdavcontent.hxx"
+@@ -146,10 +146,17 @@ ContentProvider::queryContent(
+ !aScheme.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( HTTPS_URL_SCHEME ) ) &&
+ !aScheme.equalsAsciiL(
+- RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) )
+- &&
++ RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) &&
+ !aScheme.equalsAsciiL(
+- RTL_CONSTASCII_STRINGPARAM( FTP_URL_SCHEME ) )
++ RTL_CONSTASCII_STRINGPARAM( FTP_URL_SCHEME ) ) &&
++ !aScheme.equalsAsciiL(
++ RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) &&
++ !aScheme.equalsAsciiL(
++ RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) &&
++ !aScheme.equalsAsciiL(
++ RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAV_URL_SCHEME ) ) &&
++ !aScheme.equalsAsciiL(
++ RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAVS_URL_SCHEME ) )
+ )
+ throw ucb::IllegalIdentifierException();
+
+@@ -168,14 +175,27 @@ ContentProvider::queryContent(
+ uno::Reference< ucb::XContentIdentifier > xCanonicId;
+
+ bool bNewId = false;
+- if ( aScheme.equalsAsciiL(
+- RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) )
++ struct {
++ const char *from;
++ const char *to;
++ } const *pScheme, pReplace[] = {
++ { WEBDAV_URL_SCHEME, HTTP_URL_SCHEME },
++ { DAV_URL_SCHEME, HTTP_URL_SCHEME },
++ { DAVS_URL_SCHEME, HTTPS_URL_SCHEME },
++ { PLAIN_WEBDAV_URL_SCHEME, HTTP_URL_SCHEME },
++ { PLAIN_WEBDAVS_URL_SCHEME, HTTPS_URL_SCHEME },
++ { NULL, NULL }
++ };
++ for ( pScheme = pReplace; pScheme->from ; ++pScheme )
+ {
+- aURL = aURL.replaceAt( 0,
+- WEBDAV_URL_SCHEME_LENGTH,
+- rtl::OUString::createFromAscii(
+- HTTP_URL_SCHEME ) );
+- bNewId = true;
++ if ( aScheme.equalsAscii( pScheme->from ) )
++ {
++ aURL = aURL.replaceAt( 0,
++ strlen( pScheme->from ),
++ rtl::OUString::createFromAscii( pScheme->to ) );
++ bNewId = true;
++ break;
++ }
+ }
+
+ sal_Int32 nPos = aURL.lastIndexOf( '/' );
+diff --git ucb/source/ucp/webdav/webdavprovider.hxx ucb/source/ucp/webdav/webdavprovider.hxx
+index 7068b41..f6d7228 100644
+--- ucb/source/ucp/webdav/webdavprovider.hxx
++++ ucb/source/ucp/webdav/webdavprovider.hxx
+@@ -71,16 +71,19 @@ namespace webdav_ucp {
+ // contents ) according to this scheme.
+ #define WEBDAV_URL_SCHEME \
+ "vnd.sun.star.webdav"
+-#define WEBDAV_URL_SCHEME_LENGTH 19
+
+ #define HTTP_URL_SCHEME "http"
+-#define HTTP_URL_SCHEME_LENGTH 4
+
+ #define HTTPS_URL_SCHEME "https"
+-#define HTTPS_URL_SCHEME_LENGTH 5
+
+ #define FTP_URL_SCHEME "ftp"
+
++#define DAV_URL_SCHEME "dav"
++#define DAVS_URL_SCHEME "davs"
++
++#define PLAIN_WEBDAV_URL_SCHEME "webdav"
++#define PLAIN_WEBDAVS_URL_SCHEME "webdavs"
++
+ #define HTTP_CONTENT_TYPE \
+ "application/" HTTP_URL_SCHEME "-content"
+
+diff --git unotools/source/ucbhelper/ucblockbytes.cxx unotools/source/ucbhelper/ucblockbytes.cxx
+index 7cda473..ab428c2 100644
+--- unotools/source/ucbhelper/ucblockbytes.cxx
++++ unotools/source/ucbhelper/ucblockbytes.cxx
+@@ -1026,6 +1026,10 @@ static sal_Bool UCBOpenContentSync(
+ if( ! aScheme.equalsIgnoreAsciiCaseAscii("http") &&
+ ! aScheme.equalsIgnoreAsciiCaseAscii("https") &&
+ ! aScheme.equalsIgnoreAsciiCaseAscii("vnd.sun.star.webdav") &&
++ ! aScheme.equalsIgnoreAsciiCaseAscii("dav") &&
++ ! aScheme.equalsIgnoreAsciiCaseAscii("davs") &&
++ ! aScheme.equalsIgnoreAsciiCaseAscii("webdav") &&
++ ! aScheme.equalsIgnoreAsciiCaseAscii("webdavs") &&
+ ! aScheme.equalsIgnoreAsciiCaseAscii("ftp"))
+ return _UCBOpenContentSync(
+ xLockBytes,xContent,rArg,xSink,xInteract,xProgress,xHandler);
Added: trunk/patches/unittesting/unittesting-ucb-m12.diff
==============================================================================
--- (empty file)
+++ trunk/patches/unittesting/unittesting-ucb-m12.diff Fri May 23 23:53:50 2008
@@ -0,0 +1,30 @@
+--- ucb/prj/build.lst 2007-06-19 18:10:23.000000000 +0200
++++ ucb/prj/build.lst 2007-09-07 11:52:29.000000000 +0200
+@@ -1,4 +1,4 @@
+-uc ucb : cppuhelper CURL:curl OPENSSL:openssl NEON:neon LIBXML2:libxml2 offapi sal salhelper ucbhelper udkapi comphelper vcl NULL
++uc ucb : cppuhelper CURL:curl OPENSSL:openssl NEON:neon LIBXML2:libxml2 offapi sal salhelper ucbhelper udkapi comphelper vcl tools NULL
+ uc ucb usr1 - all uc_mkout NULL
+ uc ucb\inc nmake - all uc_inc NULL
+ uc ucb\source\regexp nmake - all uc_regexp uc_inc NULL
+--- ucb/prj/tests.lst 1970-01-01 01:00:00.000000000 +0100
++++ ucb/prj/tests.lst 2007-09-07 18:02:58.000000000 +0200
+@@ -0,0 +1,9 @@
++uc ucb\qa\complex\tdoc\interfaces nmake - all uc_qa_complex_tdoc_interfaces NULL
++#does not build: uc ucb\qa\complex\tdoc nmake - all uc_qa_complex_tdoc NULL
++uc ucb\qa\complex\ucb nmake - all uc_qa_complex_ucb NULL
++#does not build: uc ucb\qa\unoapi nmake - all uc_qa_unoapi NULL
++
++# older tests:
++#doest not build: uc ucb\test\com\sun\star\comp\ucb nmake - all uc_test_com_sun_star_comp_ucb NULL
++uc ucb\workben\cachemap nmake - all uc_workben_cachemap NULL
++uc ucb\workben\ucb nmake - all uc_workben_ucb NULL
+--- ucb/workben/ucb/makefile.mk 2007-03-09 10:23:41.000000000 +0100
++++ ucb/workben/ucb/makefile.mk 2007-09-07 12:12:33.000000000 +0200
+@@ -82,7 +82,6 @@ APP1STDLIBS=\
+ $(CPPUHELPERLIB) \
+ $(COMPHELPERLIB) \
+ $(TOOLSLIB) \
+- $(SVTOOLLIB) \
+ $(VCLLIB) \
+ $(UCBHELPERLIB)
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]