ooo-build r12657 - in trunk: . patches/dev300 patches/unittesting



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]