diff -ur --exclude=CVS sc.clean/inc/document.hxx sc/inc/document.hxx
--- sc.clean/inc/document.hxx	2007-06-14 06:31:15.000000000 -0400
+++ sc/inc/document.hxx	2007-06-14 06:31:36.000000000 -0400
@@ -518,6 +518,7 @@
 	BOOL			IsDocProtected() const;
 	BOOL			IsDocEditable() const;
 	BOOL			IsTabProtected( SCTAB nTab ) const;
+    ScTableProtection& GetTabProtection( 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;
 
diff -ur --exclude=CVS sc.clean/inc/table.hxx sc/inc/table.hxx
--- sc.clean/inc/table.hxx	2007-06-14 06:31:15.000000000 -0400
+++ sc/inc/table.hxx	2007-06-14 06:31:36.000000000 -0400
@@ -58,6 +58,8 @@
 #include "compressedarray.hxx"
 #endif
 
+#include "tabprotection.hxx"
+
 namespace utl {
 	class SearchParam;
 	class TextSearch;
@@ -121,8 +123,7 @@
 	SCROW			nRepeatStartY;
 	SCROW			nRepeatEndY;
 
-	BOOL			bProtected;
-	com::sun::star::uno::Sequence<sal_Int8>	aProtectPass;
+    ScTableProtection aTabProtection;
 
 	USHORT*			pColWidth;
 	ScSummableCompressedArray< SCROW, USHORT>*  pRowHeight;
@@ -237,10 +238,10 @@
 	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;
+    const com::sun::star::uno::Sequence<sal_Int8>&  GetPassword() const;
+    void            SetProtection( BOOL bProtect, const com::sun::star::uno::Sequence<sal_Int8>& rPasswd );
+    ScTableProtection& GetProtection();
 
 	Size			GetPageSize() const;
 	void			SetPageSize( const Size& rSize );
Only in sc/inc: tabprotection.hxx
diff -ur --exclude=CVS sc.clean/source/core/data/documen3.cxx sc/source/core/data/documen3.cxx
--- sc.clean/source/core/data/documen3.cxx	2007-06-14 06:31:17.000000000 -0400
+++ sc/source/core/data/documen3.cxx	2007-06-14 06:31:36.000000000 -0400
@@ -1707,6 +1707,16 @@
 	return FALSE;
 }
 
+ScTableProtection& ScDocument::GetTabProtection( SCTAB nTab ) const
+{
+    if (VALIDTAB(nTab) && pTab[nTab])
+        return pTab[nTab]->GetProtection();
+
+    DBG_ERROR("Wrong table number");
+    static ScTableProtection aEmptyProtection;
+    return aEmptyProtection;
+}
+
 const uno::Sequence<sal_Int8>& ScDocument::GetDocPassword() const
 {
 	return aProtectPass;
diff -ur --exclude=CVS sc.clean/source/core/data/makefile.mk sc/source/core/data/makefile.mk
--- sc.clean/source/core/data/makefile.mk	2007-06-14 06:31:17.000000000 -0400
+++ sc/source/core/data/makefile.mk	2007-06-14 06:31:36.000000000 -0400
@@ -111,6 +111,7 @@
 	$(SLO)$/table4.obj \
 	$(SLO)$/table5.obj \
 	$(SLO)$/table6.obj \
+	$(SLO)$/tabprotection.obj \
 	$(SLO)$/userdat.obj \
 	$(SLO)$/validat.obj \
 	$(SLO)$/postit.obj
diff -ur --exclude=CVS sc.clean/source/core/data/table1.cxx sc/source/core/data/table1.cxx
--- sc.clean/source/core/data/table1.cxx	2007-06-14 06:31:17.000000000 -0400
+++ sc/source/core/data/table1.cxx	2007-06-14 06:33:57.000000000 -0400
@@ -137,7 +137,6 @@
 	bPageSizeValid( FALSE ),
 	nRepeatStartX( SCCOL_REPEAT_NONE ),
 	nRepeatStartY( SCROW_REPEAT_NONE ),
-	bProtected( FALSE ),
 	pColWidth( NULL ),
 	pRowHeight( NULL ),
 	pColFlags( NULL ),
diff -ur --exclude=CVS sc.clean/source/core/data/table2.cxx sc/source/core/data/table2.cxx
--- sc.clean/source/core/data/table2.cxx	2007-06-14 06:31:17.000000000 -0400
+++ sc/source/core/data/table2.cxx	2007-06-14 06:31:36.000000000 -0400
@@ -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 ) );
@@ -317,7 +317,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 );
@@ -360,7 +360,7 @@
 
 		//	ggf. Formeln durch Werte ersetzen
 
-		if (bProtected)
+		if ( IsProtected() )
 			for (i = nCol1; i <= nCol2; i++)
 				pTable->aCol[i].RemoveProtected(nRow1, nRow2);
 	}
@@ -405,7 +405,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 ) );
@@ -1435,7 +1435,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)
         {
@@ -1502,7 +1502,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)
         {
@@ -2784,11 +2784,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;
@@ -3060,6 +3065,7 @@
 		rStream << bScenario;
 		rStream.WriteByteString( aComment, rStream.GetStreamCharSet() );
 
+        BOOL bProtected = IsProtected();
 		rStream << bProtected;
 		String aPass;
 		//rStream.WriteByteString( aProtectPass, rStream.GetStreamCharSet() );
diff -ur --exclude=CVS sc.clean/source/core/data/table5.cxx sc/source/core/data/table5.cxx
--- sc.clean/source/core/data/table5.cxx	2007-06-14 06:31:17.000000000 -0400
+++ sc/source/core/data/table5.cxx	2007-06-14 06:31:36.000000000 -0400
@@ -56,6 +56,7 @@
 #include "stlpool.hxx"
 #include "stlsheet.hxx"
 #include "brdcst.hxx"
+#include "tabprotection.hxx"
 #include "globstr.hrc"
 
 // STATIC DATA -----------------------------------------------------------
@@ -278,6 +279,27 @@
 		bPageSizeValid = FALSE;
 }
 
+BOOL ScTable::IsProtected() const
+{
+    return aTabProtection.isProtected();
+}
+
+const ::com::sun::star::uno::Sequence<sal_Int8>& ScTable::GetPassword() const
+{
+    return aTabProtection.getPassword();
+}
+
+void ScTable::SetProtection( BOOL bProtect, const com::sun::star::uno::Sequence<sal_Int8>& rPasswd )
+{
+    aTabProtection.setProtected( bProtect );
+    aTabProtection.setPassword( rPasswd );
+}
+
+ScTableProtection& ScTable::GetProtection()
+{
+    return aTabProtection;
+}
+
 Size ScTable::GetPageSize() const
 {
 	if ( bPageSizeValid )
Only in sc/source/core/data: tabprotection.cxx
diff -ur --exclude=CVS sc.clean/source/filter/excel/excdoc.cxx sc/source/filter/excel/excdoc.cxx
--- sc.clean/source/filter/excel/excdoc.cxx	2007-06-14 06:31:17.000000000 -0400
+++ sc/source/filter/excel/excdoc.cxx	2007-06-14 06:31:36.000000000 -0400
@@ -393,6 +393,9 @@
 
     if( eBiff == EXC_BIFF8 )
 	{
+        // sheet protection options
+        Add( new XclExpSheetProtect( GetRoot(), mnScTab ) );
+
 		// web queries
         Add( new XclExpWebQueryBuffer( GetRoot() ) );
 
diff -ur --exclude=CVS sc.clean/source/filter/excel/excimp8.cxx sc/source/filter/excel/excimp8.cxx
--- sc.clean/source/filter/excel/excimp8.cxx	2007-06-14 06:31:17.000000000 -0400
+++ sc/source/filter/excel/excimp8.cxx	2007-06-14 06:31:36.000000000 -0400
@@ -286,6 +286,10 @@
 	}
 }
 
+void ImportExcel8::SheetProtection( void )
+{
+    GetSheetProtectBuffer().ReadOptions( aIn, GetCurrScTab() );
+}
 
 void ImportExcel8::ReadBasic( void )
 {
@@ -321,6 +325,7 @@
         pExcRoot->pAutoFilterBuffer->Apply();
 
     GetWebQueryBuffer().Apply();    //! test if extant
+    GetSheetProtectBuffer().Apply();
 
 	ImportExcel::PostDocLoad();
 
diff -ur --exclude=CVS sc.clean/source/filter/excel/read.cxx sc/source/filter/excel/read.cxx
--- sc.clean/source/filter/excel/read.cxx	2007-06-14 06:31:17.000000000 -0400
+++ sc/source/filter/excel/read.cxx	2007-06-14 06:31:36.000000000 -0400
@@ -1111,6 +1111,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;
diff -ur --exclude=CVS sc.clean/source/filter/excel/xetable.cxx sc/source/filter/excel/xetable.cxx
--- sc.clean/source/filter/excel/xetable.cxx	2007-06-14 06:31:17.000000000 -0400
+++ sc/source/filter/excel/xetable.cxx	2007-06-14 06:31:36.000000000 -0400
@@ -2238,3 +2238,63 @@
 
 // ============================================================================
 
+struct XclExpTabProtectOption
+{
+    ScTableProtection::Option   eOption;
+    sal_uInt16                  nMask;
+};
+
+XclExpSheetProtect::XclExpSheetProtect( const XclExpRoot& rRoot, SCTAB nTab ) :
+    XclExpRecord( 0x0867, 23 )
+{
+    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 }
+    };
+
+    ScTableProtection& rProtect = rRoot.GetDoc().GetTabProtection(nTab);
+    mnOptions = 0x0000;
+    for (int i = 0; aTable[i].nMask != 0x0000; ++i)
+    {
+        if ( rProtect.isOptionEnabled(aTable[i].eOption) )
+            mnOptions |= aTable[i].nMask;
+    }
+}
+
+void XclExpSheetProtect::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;
+}
diff -ur --exclude=CVS sc.clean/source/filter/excel/xicontent.cxx sc/source/filter/excel/xicontent.cxx
--- sc.clean/source/filter/excel/xicontent.cxx	2007-06-14 06:31:17.000000000 -0400
+++ sc/source/filter/excel/xicontent.cxx	2007-06-14 06:31:36.000000000 -0400
@@ -1091,5 +1091,49 @@
     return xDecr.is() ? xDecr->GetError() : EXC_ENCR_ERROR_UNSUPP_CRYPT;
 }
 
+// ----------------------------------------------------------------------------
+
+XclImpSheetProtectBuffer::XclImpSheetProtectBuffer( const XclImpRoot& rRoot ) :
+    XclImpRoot( rRoot )
+{
+}
+
+void XclImpSheetProtectBuffer::ReadOptions( XclImpStream& rStrm, SCTAB nTab )
+{
+    rStrm.Ignore(19);
+    sal_uInt16 nOptions;
+    rStrm >> nOptions;
+    maOptions.push_back(nOptions);
+}
+
+void XclImpSheetProtectBuffer::Apply() const
+{
+    ::std::list<sal_uInt16>::const_iterator itr = maOptions.begin(), itrEnd = maOptions.end();
+    SCTAB nCurTab = 0;
+    ScDocument& rDoc = GetDoc();
+    for (; itr != itrEnd; ++itr, ++nCurTab)
+    {
+        sal_uInt16 rOptions = *itr;
+
+        ScTableProtection& rProtect = rDoc.GetTabProtection(nCurTab);
+        rProtect.setOption( ScTableProtection::OBJECTS,               (rOptions & 0x0001) );
+        rProtect.setOption( ScTableProtection::SCENARIOS,             (rOptions & 0x0002) );
+        rProtect.setOption( ScTableProtection::FORMAT_CELLS,          (rOptions & 0x0004) );
+        rProtect.setOption( ScTableProtection::FORMAT_COLUMNS,        (rOptions & 0x0008) );
+        rProtect.setOption( ScTableProtection::FORMAT_ROWS,           (rOptions & 0x0010) );
+        rProtect.setOption( ScTableProtection::INSERT_COLUMNS,        (rOptions & 0x0020) );
+        rProtect.setOption( ScTableProtection::INSERT_ROWS,           (rOptions & 0x0040) );
+        rProtect.setOption( ScTableProtection::INSERT_HYPERLINKS,     (rOptions & 0x0080) );
+
+        rProtect.setOption( ScTableProtection::DELETE_COLUMNS,        (rOptions & 0x0100) );
+        rProtect.setOption( ScTableProtection::DELETE_ROWS,           (rOptions & 0x0200) );
+        rProtect.setOption( ScTableProtection::SELECT_LOCKED_CELLS,   (rOptions & 0x0400) );
+        rProtect.setOption( ScTableProtection::SORT,                  (rOptions & 0x0800) );
+        rProtect.setOption( ScTableProtection::AUTOFILTER,            (rOptions & 0x1000) );
+        rProtect.setOption( ScTableProtection::PIVOT_TABLES,          (rOptions & 0x2000) );
+        rProtect.setOption( ScTableProtection::SELECT_UNLOCKED_CELLS, (rOptions & 0x4000) );
+    }
+}
+
 // ============================================================================
 
diff -ur --exclude=CVS sc.clean/source/filter/excel/xiroot.cxx sc/source/filter/excel/xiroot.cxx
--- sc.clean/source/filter/excel/xiroot.cxx	2007-06-14 06:31:17.000000000 -0400
+++ sc/source/filter/excel/xiroot.cxx	2007-06-14 06:31:36.000000000 -0400
@@ -117,6 +117,7 @@
         GetOldRoot().pAutoFilterBuffer = new XclImpAutoFilterBuffer;
         mrImpData.mxWebQueryBfr.reset( new XclImpWebQueryBuffer( GetRoot() ) );
         mrImpData.mxPTableMgr.reset( new XclImpPivotTableManager( GetRoot() ) );
+        mrImpData.mxTabProtect.reset( new XclImpSheetProtectBuffer( GetRoot() ) );
     }
 
     mrImpData.mxPageSett.reset( new XclImpPageSettings( GetRoot() ) );
@@ -255,6 +256,12 @@
     return *mrImpData.mxPTableMgr;
 }
 
+XclImpSheetProtectBuffer& XclImpRoot::GetSheetProtectBuffer() const
+{
+    DBG_ASSERT( mrImpData.mxTabProtect.is(), "XclImpRoot::GetSheetProtectBuffer - invalid call, wrong BIFF" );
+    return *mrImpData.mxTabProtect;
+}
+
 XclImpPageSettings& XclImpRoot::GetPageSettings() const
 {
     return *mrImpData.mxPageSett;
diff -ur --exclude=CVS sc.clean/source/filter/inc/excimp8.hxx sc/source/filter/inc/excimp8.hxx
--- sc.clean/source/filter/inc/excimp8.hxx	2007-06-14 06:31:17.000000000 -0400
+++ sc/source/filter/inc/excimp8.hxx	2007-06-14 06:31:36.000000000 -0400
@@ -91,6 +91,7 @@
 
 		void					Hlink( void );					// 0x01B8
 		void					Codename( BOOL bWBGlobals );	// 0x01BA
+        void                    SheetProtection( void );        // 0x0867
 
         virtual void            EndSheet( void );
 		virtual void			PostDocLoad( void );
diff -ur --exclude=CVS sc.clean/source/filter/inc/xetable.hxx sc/source/filter/inc/xetable.hxx
--- sc.clean/source/filter/inc/xetable.hxx	2007-06-14 06:31:17.000000000 -0400
+++ sc/source/filter/inc/xetable.hxx	2007-06-14 06:31:36.000000000 -0400
@@ -1091,5 +1091,20 @@
 
 // ============================================================================
 
+/** 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 XclExpSheetProtect : public XclExpRecord
+{
+public:
+    explicit            XclExpSheetProtect( const XclExpRoot& rRoot, SCTAB nTab );
+
+private:
+    virtual void        WriteBody( XclExpStream& rStrm );
+
+private:
+    sal_uInt16      mnOptions;      /// Encoded sheet protection options.
+};
+
 #endif
 
diff -ur --exclude=CVS sc.clean/source/filter/inc/xicontent.hxx sc/source/filter/inc/xicontent.hxx
--- sc.clean/source/filter/inc/xicontent.hxx	2007-06-14 06:31:17.000000000 -0400
+++ sc/source/filter/inc/xicontent.hxx	2007-06-14 06:31:36.000000000 -0400
@@ -50,6 +50,8 @@
 #include "xihelper.hxx"
 #endif
 
+#include <list>
+
 /* ============================================================================
 Classes to import the big Excel document contents (related to several cells or
 globals for the document).
@@ -253,5 +255,24 @@
 
 // ============================================================================
 
+
+// Sheet protection ===========================================================
+
+class XclImpSheetProtectBuffer : protected XclImpRoot
+{
+public:
+    explicit            XclImpSheetProtectBuffer( const XclImpRoot& rRoot );
+
+    void                ReadOptions( XclImpStream& rStrm, SCTAB nTab );
+
+    void                Apply() const;
+
+private:
+    ::std::list<sal_uInt16>          maOptions;
+};
+
+
+// ============================================================================
+
 #endif
 
diff -ur --exclude=CVS sc.clean/source/filter/inc/xiroot.hxx sc/source/filter/inc/xiroot.hxx
--- sc.clean/source/filter/inc/xiroot.hxx	2007-06-14 06:31:17.000000000 -0400
+++ sc/source/filter/inc/xiroot.hxx	2007-06-14 06:31:36.000000000 -0400
@@ -68,6 +68,7 @@
 class XclImpPageSettings;
 class XclImpDocViewSettings;
 class XclImpTabViewSettings;
+class XclImpSheetProtectBuffer;
 
 class _ScRangeListTabs;
 class ExcelToSc;
@@ -94,6 +95,7 @@
     typedef ScfRef< XclImpPageSettings >        XclImpPageSettRef;
     typedef ScfRef< XclImpDocViewSettings >     XclImpDocViewSettRef;
     typedef ScfRef< XclImpTabViewSettings >     XclImpTabViewSettRef;
+    typedef ScfRef< XclImpSheetProtectBuffer >  XclImpTabProtectRef;
 
     XclImpAddrConvRef   mxAddrConv;         /// The address converter.
     XclImpFmlaCompRef   mxFmlaComp;         /// The formula compiler.
@@ -117,6 +119,7 @@
     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.
 
     bool                mbHasCodePage;      /// true = CODEPAGE record exists.
 
@@ -188,6 +191,9 @@
     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 page settings of the current sheet. */
     XclImpPageSettings& GetPageSettings() const;
diff -ur --exclude=CVS sc.clean/source/ui/view/gridwin.cxx sc/source/ui/view/gridwin.cxx
--- sc.clean/source/ui/view/gridwin.cxx	2007-06-14 06:31:15.000000000 -0400
+++ sc/source/ui/view/gridwin.cxx	2007-06-14 06:44:14.000000000 -0400
@@ -2176,11 +2176,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 );
 
@@ -2209,17 +2210,35 @@
 			return;
 		}
 
-		//	edit cell contents
-		pViewData->GetViewShell()->UpdateInputHandler();
-		pScMod->SetInputMode( SC_INPUT_TABLE );
-		if (pViewData->HasEditView(eWhich))
-		{
-			//	Text-Cursor gleich an die geklickte Stelle setzen
-			EditView* pEditView = pViewData->GetEditView( eWhich );
-			MouseEvent aEditEvt( rMEvt.GetPosPixel(), 1, MOUSE_SYNTHETIC, MOUSE_LEFT, 0 );
-			pEditView->MouseButtonDown( aEditEvt );
-			pEditView->MouseButtonUp( aEditEvt );
-		}
+        ScTableProtection& rProtect = pDoc->GetTabProtection( nTab );
+        bool bEditAllowed = true;
+        if ( rProtect.isProtected() )
+        {
+            bool bCellProtected = pDoc->HasAttrib(nPosX, nPosY, nTab, nPosX, nPosY, nTab, HASATTR_PROTECTED);
+            bool bSkipProtected = !rProtect.isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+            bool bSkipUnprotected = !rProtect.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 );
+            if (pViewData->HasEditView(eWhich))
+            {
+                    //	Text-Cursor gleich an die geklickte Stelle setzen
+                EditView* pEditView = pViewData->GetEditView( eWhich );
+                MouseEvent aEditEvt( rMEvt.GetPosPixel(), 1, MOUSE_SYNTHETIC, MOUSE_LEFT, 0 );
+                pEditView->MouseButtonDown( aEditEvt );
+                pEditView->MouseButtonUp( aEditEvt );
+            }
+        }
+        return;
 	}
 
 			//
diff -ur --exclude=CVS sc.clean/source/ui/view/select.cxx sc/source/ui/view/select.cxx
--- sc.clean/source/ui/view/select.cxx	2007-06-14 06:31:15.000000000 -0400
+++ sc/source/ui/view/select.cxx	2007-06-14 06:31:36.000000000 -0400
@@ -327,6 +327,23 @@
 {
 	ScTabView* pView = pViewData->GetView();
 	SCTAB nTab = pViewData->GetTabNo();
+    ScDocument* pDoc = pViewData->GetDocument();
+
+    if ( pDoc->IsTabProtected(nTab) )
+    {
+        ScTableProtection& rProtect = pDoc->GetTabProtection(nTab);
+        bool bSkipProtected   = !rProtect.isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+        bool bSkipUnprotected = !rProtect.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();
 
@@ -379,7 +396,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 &&
diff -ur --exclude=CVS sc.clean/source/ui/view/tabview3.cxx sc/source/ui/view/tabview3.cxx
--- sc.clean/source/ui/view/tabview3.cxx	2007-06-14 06:31:15.000000000 -0400
+++ sc/source/ui/view/tabview3.cxx	2007-06-14 06:31:36.000000000 -0400
@@ -83,6 +83,7 @@
 #include "AccessibilityHints.hxx"
 #include "rangeutl.hxx"
 #include "client.hxx"
+#include "tabprotection.hxx"
 
 #include <com/sun/star/chart2/data/HighlightedRange.hpp>
 
@@ -994,6 +995,17 @@
 	ScDocument* pDoc = aViewData.GetDocument();
 	SCTAB nTab = aViewData.GetTabNo();
 
+    bool bSkipProtected = false, bSkipUnprotected = false;
+    if ( pDoc->IsTabProtected(nTab) )
+    {
+        ScTableProtection& rProtect = pDoc->GetTabProtection(nTab);
+        bSkipProtected   = !rProtect.isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+        bSkipUnprotected = !rProtect.isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
+    }
+
+    if ( bSkipProtected && bSkipUnprotected )
+        return;
+
 	SCsCOL nOldX;
 	SCsROW nOldY;
 	SCsCOL nCurX;
@@ -1013,7 +1025,7 @@
 		nCurY = (nMovY != 0) ? nOldY+nMovY : (SCsROW) aViewData.GetOldCurY();
 	}
 
-	BOOL bHidden;
+	BOOL bSkipCell = FALSE;
 	aViewData.ResetOldCursor();
 
 	if (nMovX != 0 && VALIDCOLROW(nCurX,nCurY))
@@ -1022,15 +1034,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
 					{
@@ -1043,7 +1060,8 @@
 					if (nMovX > 0) ++nCurX; else --nCurX;
 			}
 		}
-		while (bHidden);
+		while (bSkipCell);
+
 		if (pDoc->IsVerOverlapped( nCurX, nCurY, nTab ))
 		{
 			aViewData.SetOldCursor( nCurX,nCurY );
@@ -1058,15 +1076,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
 					{
@@ -1079,7 +1102,8 @@
 					if (nMovY > 0) ++nCurY; else --nCurY;
 			}
 		}
-		while (bHidden);
+		while (bSkipCell);
+
 		if (pDoc->IsHorOverlapped( nCurX, nCurY, nTab ))
 		{
 			aViewData.SetOldCursor( nCurX,nCurY );
--- /dev/null	2007-03-30 11:25:40.000000000 -0400
+++ sc/inc/tabprotection.hxx	2007-06-14 06:31:36.000000000 -0400
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: table.hxx,v $
+ *
+ *  $Revision: 1.30 $
+ *
+ *  last change: $Author: obo $ $Date: 2006/03/27 09:26:33 $
+ *
+ *  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 <vector>
+
+
+class ScTableProtection
+{
+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;
+    };
+
+    bool isProtected() const;
+    void setProtected(bool bProtected);
+
+    const ::com::sun::star::uno::Sequence<sal_Int8>& getPassword() const;
+    void setPassword(const ::com::sun::star::uno::Sequence<sal_Int8>& aPassword);
+
+    bool isOptionEnabled(Option eOption) const;
+    void setOption(Option eOption, bool bEnabled);
+
+    ScTableProtection();
+
+private:
+    ::com::sun::star::uno::Sequence<sal_Int8>   maPassword;
+    ::std::vector<bool> maOptions;
+    bool mbProtected;
+};
+
+
+#endif
--- /dev/null	2007-03-30 11:25:40.000000000 -0400
+++ sc/source/core/data/tabprotection.cxx	2007-06-14 06:31:36.000000000 -0400
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ *  OpenOffice.org - a multi-platform office productivity suite
+ *
+ *  $RCSfile: table.hxx,v $
+ *
+ *  $Revision: 1.30 $
+ *
+ *  last change: $Author: obo $ $Date: 2006/03/27 09:26:33 $
+ *
+ *  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"
+
+using namespace ::com::sun::star;
+
+ScTableProtection::ScTableProtection() :
+    maOptions(NONE),
+    mbProtected(false)
+{
+    // Set default values for the options.
+    maOptions[SELECT_LOCKED_CELLS]   = true;
+    maOptions[SELECT_UNLOCKED_CELLS] = true;
+}
+
+bool ScTableProtection::isProtected() const
+{
+    return mbProtected;
+}
+
+void ScTableProtection::setProtected(bool bProtected)
+{
+    mbProtected = bProtected;
+}
+
+const uno::Sequence<sal_Int8>& ScTableProtection::getPassword() const
+{
+    return maPassword;
+}
+
+void ScTableProtection::setPassword(const uno::Sequence<sal_Int8>& aPassword)
+{
+    maPassword = aPassword;
+}
+
+bool ScTableProtection::isOptionEnabled(Option eOption) const
+{
+    if ( maOptions.size() <= static_cast<size_t>(eOption) )
+    {
+        DBG_ERROR("ScTableProtection::isOptionEnabled: wrong size");
+        return false;
+    }
+
+    return maOptions[eOption];
+}
+
+void ScTableProtection::setOption(Option eOption, bool bEnabled)
+{
+    if ( maOptions.size() <= static_cast<size_t>(eOption) )
+    {
+        DBG_ERROR("ScTableProtection::setOption: wrong size");
+        return;
+    }
+
+    maOptions[eOption] = bEnabled;
+}
