diff options
Diffstat (limited to 'sc')
92 files changed, 1146 insertions, 594 deletions
diff --git a/sc/inc/cellsuno.hxx b/sc/inc/cellsuno.hxx index a53f167b164a..d3d02818b358 100644 --- a/sc/inc/cellsuno.hxx +++ b/sc/inc/cellsuno.hxx @@ -205,7 +205,6 @@ private: const ScPatternAttr* GetCurrentAttrsFlat(); const ScPatternAttr* GetCurrentAttrsDeep(); SfxItemSet* GetCurrentDataSet(bool bNoDflt = false); - const ScMarkData* GetMarkData(); void ForgetMarkData(); void ForgetCurrentAttrs(); @@ -218,6 +217,8 @@ private: const ScAddress* pLastPos); protected: + const ScMarkData* GetMarkData(); + // GetItemPropertyMap for derived classes must contain all entries, including base class virtual const SfxItemPropertyMap* GetItemPropertyMap(); virtual ::com::sun::star::beans::PropertyState GetOnePropertyState( @@ -815,7 +816,7 @@ public: //! really derive cell from range? -class ScCellObj : public ScCellRangeObj, +class SC_DLLPUBLIC ScCellObj : public ScCellRangeObj, public com::sun::star::text::XText, public com::sun::star::container::XEnumerationAccess, public com::sun::star::table::XCell, @@ -874,6 +875,8 @@ public: const ::rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar ); const ScAddress& GetPosition() const { return aCellPos; } + void InputEnglishString( const ::rtl::OUString& rText ); + // XText virtual void SAL_CALL insertTextContent( const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange >& xRange, diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 5c4685223281..90aac02aab7f 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -556,7 +556,7 @@ public: SC_DLLPUBLIC BOOL HasTable( SCTAB nTab ) const; SC_DLLPUBLIC BOOL GetName( SCTAB nTab, String& rName ) const; SC_DLLPUBLIC BOOL GetCodeName( SCTAB nTab, String& rName ) const; - SC_DLLPUBLIC BOOL SetCodeName( SCTAB nTab, String& rName ); + SC_DLLPUBLIC BOOL SetCodeName( SCTAB nTab, const String& rName ); SC_DLLPUBLIC BOOL GetTable( const String& rName, SCTAB& rTab ) const; SC_DLLPUBLIC inline SCTAB GetTableCount() const { return nMaxTableNumber; } SvNumberFormatterIndexTable* GetFormatExchangeList() const { return pFormatExchangeList; } @@ -748,6 +748,7 @@ public: bool HasSheetEventScript( SCTAB nTab, sal_Int32 nEvent, bool bWithVbaEvents = false ) const; bool HasAnySheetEventScript( sal_Int32 nEvent, bool bWithVbaEvents = false ) const; // on any sheet + bool HasAnyCalcNotification() const; BOOL HasCalcNotification( SCTAB nTab ) const; void SetCalcNotification( SCTAB nTab ); void ResetCalcNotifications(); @@ -926,8 +927,8 @@ public: /** Shrink a range to only include used data area. */ bool ShrinkToUsedDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly ) const; - void GetDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, - SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld, bool bOnlyDown ) const; + SC_DLLPUBLIC void GetDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, + SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld, bool bOnlyDown ) const; SC_DLLPUBLIC BOOL GetCellArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) const; SC_DLLPUBLIC BOOL GetTableArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) const; SC_DLLPUBLIC BOOL GetPrintArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow, diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx index 14c9515dfacb..92424e8178f4 100644 --- a/sc/inc/docuno.hxx +++ b/sc/inc/docuno.hxx @@ -105,6 +105,7 @@ private: com::sun::star::uno::Reference<com::sun::star::uno::XInterface> xDrawMarkerTab; com::sun::star::uno::Reference<com::sun::star::uno::XInterface> xDrawDashTab; com::sun::star::uno::Reference<com::sun::star::uno::XInterface> xChartDataProv; + com::sun::star::uno::Reference<com::sun::star::uno::XInterface> xObjProvider; ::cppu::OInterfaceContainerHelper maChangesListeners; diff --git a/sc/inc/viewuno.hxx b/sc/inc/viewuno.hxx index 19b5c60fd070..0f03e0e9b111 100644 --- a/sc/inc/viewuno.hxx +++ b/sc/inc/viewuno.hxx @@ -225,7 +225,8 @@ public: void SelectionChanged(); void VisAreaChanged(); - void SheetChanged(); + // bSameTabButMoved = true if the same sheet as before is activated, used after moving/copying/inserting/deleting a sheet + void SheetChanged( bool bSameTabButMoved = false ); bool IsMouseListening() const; sal_Bool MousePressed( const ::com::sun::star::awt::MouseEvent& e ) throw (::com::sun::star::uno::RuntimeException); sal_Bool MouseReleased( const ::com::sun::star::awt::MouseEvent& e ) throw (::com::sun::star::uno::RuntimeException); diff --git a/sc/prj/build.lst b/sc/prj/build.lst index 08d9f97b23f4..f5ab2a5f73fe 100644 --- a/sc/prj/build.lst +++ b/sc/prj/build.lst @@ -1,4 +1,4 @@ -sc sc : filter l10n vbahelper oovbaapi svx uui stoc BOOST:boost formula MDDS:mdds oox NULL +sc sc : filter l10n vbahelper oovbaapi svx uui stoc BOOST:boost formula MDDS:mdds oox LIBXSLT:libxslt NULL sc sc usr1 - all sc_mkout NULL sc sc\inc nmake - all sc_inc NULL sc sc\prj get - all sc_prj NULL diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index 8fea4b8af2b9..f3b3f1ab32c6 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -544,6 +544,14 @@ bool ScDocument::HasAnySheetEventScript( sal_Int32 nEvent, bool bWithVbaEvents ) return false; } +bool ScDocument::HasAnyCalcNotification() const +{ + for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++) + if (pTab[nTab] && pTab[nTab]->GetCalcNotification()) + return true; + return false; +} + BOOL ScDocument::HasCalcNotification( SCTAB nTab ) const { if (VALIDTAB(nTab) && pTab[nTab]) diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx index 148cc367534c..e8b58b0f71d3 100644 --- a/sc/source/core/data/documen4.cxx +++ b/sc/source/core/data/documen4.cxx @@ -505,7 +505,7 @@ double ScDocument::RoundValueAsShown( double fVal, ULONG nFormat ) && nType != NUMBERFORMAT_TIME && nType != NUMBERFORMAT_DATETIME ) { short nPrecision; - if ( nFormat ) + if ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) != 0) { nPrecision = (short)GetFormatTable()->GetFormatPrecision( nFormat ); switch ( nType ) @@ -524,7 +524,12 @@ double ScDocument::RoundValueAsShown( double fVal, ULONG nFormat ) } } else + { nPrecision = (short)GetDocOptions().GetStdPrecision(); + // #i115512# no rounding for automatic decimals + if (nPrecision == static_cast<short>(SvNumberFormatter::UNLIMITED_PRECISION)) + return fVal; + } double fRound = ::rtl::math::round( fVal, nPrecision ); if ( ::rtl::math::approxEqual( fVal, fRound ) ) return fVal; // durch Rundung hoechstens Fehler diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 192e6f69bc67..3711b1b68603 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -158,7 +158,7 @@ BOOL ScDocument::GetName( SCTAB nTab, String& rName ) const return FALSE; } -BOOL ScDocument::SetCodeName( SCTAB nTab, String& rName ) +BOOL ScDocument::SetCodeName( SCTAB nTab, const String& rName ) { if (VALIDTAB(nTab)) { diff --git a/sc/source/core/data/dptablecache.cxx b/sc/source/core/data/dptablecache.cxx index 8f25b70e41b6..8d2a5ec070f5 100755..100644 --- a/sc/source/core/data/dptablecache.cxx +++ b/sc/source/core/data/dptablecache.cxx @@ -201,8 +201,11 @@ ScDPItemData::ScDPItemData( ScDocument* pDoc, SCROW nRow, USHORT nCol, USHORT nD ScBaseCell* pCell = pDoc->GetCell( aPos ); if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA && ((ScFormulaCell*)pCell)->GetErrCode() ) + { SetString ( aDocStr ); //[SODC_19347] add liyi //bErr = TRUE; //[SODC_19347] del liyi + mbFlag |= MK_ERR; + } else if ( pDoc->HasValueData( nCol, nRow, nDocTab ) ) { double fVal = pDoc->GetValue(ScAddress(nCol, nRow, nDocTab)); @@ -672,8 +675,15 @@ bool ScDPTableDataCache::ValidQuery( SCROW nRow, const ScQueryParam &rParam, BOO { ScQueryEntry& rEntry = rParam.GetEntry(i); // we can only handle one single direct query - SCROW nId = GetItemDataId( (SCCOL)rEntry.nField, nRow, FALSE ); - const ScDPItemData* pCellData = GetItemDataById( (SCCOL)rEntry.nField, nId); + // #i115431# nField in QueryParam is the sheet column, not the field within the source range + SCCOL nQueryCol = (SCCOL)rEntry.nField; + if ( nQueryCol < rParam.nCol1 ) + nQueryCol = rParam.nCol1; + if ( nQueryCol > rParam.nCol2 ) + nQueryCol = rParam.nCol2; + SCCOL nSourceField = nQueryCol - rParam.nCol1; + SCROW nId = GetItemDataId( nSourceField, nRow, FALSE ); + const ScDPItemData* pCellData = GetItemDataById( nSourceField, nId ); BOOL bOk = FALSE; BOOL bTestEqual = FALSE; diff --git a/sc/source/core/tool/progress.cxx b/sc/source/core/tool/progress.cxx index a2fa45764bcc..d36f4d431fdf 100644 --- a/sc/source/core/tool/progress.cxx +++ b/sc/source/core/tool/progress.cxx @@ -46,6 +46,7 @@ #include "global.hxx" #include "globstr.hrc" +using namespace com::sun::star; static ScProgress theDummyInterpretProgress; @@ -78,6 +79,14 @@ BOOL lcl_IsHiddenDocument( SfxObjectShell* pObjSh ) return FALSE; } +bool lcl_HasControllersLocked( SfxObjectShell& rObjSh ) +{ + uno::Reference<frame::XModel> xModel( rObjSh.GetBaseModel() ); + if (xModel.is()) + return xModel->hasControllersLocked(); + return false; +} + ScProgress::ScProgress( SfxObjectShell* pObjSh, const String& rText, ULONG nRange, BOOL bAllDocs, BOOL bWait ) { @@ -104,10 +113,12 @@ ScProgress::ScProgress( SfxObjectShell* pObjSh, const String& rText, pProgress = NULL; } else if ( pObjSh && ( pObjSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED || - pObjSh->GetProgress() ) ) + pObjSh->GetProgress() || + lcl_HasControllersLocked(*pObjSh) ) ) { // #62808# no own progress for embedded objects, // #73633# no second progress if the document already has one + // #163566# no progress while controllers are locked (repaint disabled) pProgress = NULL; } diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx index 458629979172..f20b63efe7ba 100644 --- a/sc/source/filter/excel/excdoc.cxx +++ b/sc/source/filter/excel/excdoc.cxx @@ -222,7 +222,7 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList ) else { if( IsDocumentEncrypted() ) - Add( new XclExpFilePass( GetRoot() ) ); + Add( new XclExpFileEncryption( GetRoot() ) ); Add( new XclExpInterfaceHdr( nCodePage ) ); Add( new XclExpUInt16Record( EXC_ID_MMS, 0 ) ); Add( new XclExpInterfaceEnd ); diff --git a/sc/source/filter/excel/excel.cxx b/sc/source/filter/excel/excel.cxx index 3a43a23cd624..90ac8011a4bf 100644 --- a/sc/source/filter/excel/excel.cxx +++ b/sc/source/filter/excel/excel.cxx @@ -31,6 +31,8 @@ #include <sfx2/docfile.hxx> #include <sfx2/objsh.hxx> #include <sfx2/app.hxx> +#include <sfx2/frame.hxx> +#include <sfx2/request.hxx> #include <sot/storage.hxx> #include <sot/exchange.hxx> #include <tools/globname.hxx> @@ -99,10 +101,17 @@ FltError ScFormatFilterPluginImpl::ScImportExcel( SfxMedium& rMedium, ScDocument SfxItemSet* pItemSet = rMedium.GetItemSet(); if( pItemSet ) { - if( const SfxStringItem* pItem = static_cast< const SfxStringItem* >( pItemSet->GetItem( SID_FILE_NAME ) ) ) - aMediaDesc[ MediaDescriptor::PROP_URL() ] <<= ::rtl::OUString( pItem->GetValue() ); - if( const SfxStringItem* pItem = static_cast< const SfxStringItem* >( pItemSet->GetItem( SID_PASSWORD ) ) ) - aMediaDesc[ MediaDescriptor::PROP_PASSWORD() ] <<= ::rtl::OUString( pItem->GetValue() ); + SFX_ITEMSET_ARG( pItemSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False); + if( pFileNameItem ) + aMediaDesc[ MediaDescriptor::PROP_URL() ] <<= ::rtl::OUString( pFileNameItem->GetValue() ); + + SFX_ITEMSET_ARG( pItemSet, pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False); + if( pPasswordItem ) + aMediaDesc[ MediaDescriptor::PROP_PASSWORD() ] <<= ::rtl::OUString( pPasswordItem->GetValue() ); + + SFX_ITEMSET_ARG( pItemSet, pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False); + if( pEncryptionDataItem ) + aMediaDesc[ MediaDescriptor::PROP_ENCRYPTIONDATA() ] = pEncryptionDataItem->GetValue(); } aMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ] <<= rMedium.GetInputStream(); aMediaDesc[ MediaDescriptor::PROP_INTERACTIONHANDLER() ] <<= rMedium.GetInteractionHandler(); diff --git a/sc/source/filter/excel/excimp8.cxx b/sc/source/filter/excel/excimp8.cxx index d75a0e669603..77afeb58d945 100644 --- a/sc/source/filter/excel/excimp8.cxx +++ b/sc/source/filter/excel/excimp8.cxx @@ -55,6 +55,7 @@ #include <editeng/flditem.hxx> #include <svx/xflclit.hxx> #include <filter/msfilter/svxmsbas.hxx> +#include <oox/xls/excelvbaproject.hxx> #include <basic/basmgr.hxx> #include <vcl/graph.hxx> @@ -243,6 +244,10 @@ void ImportExcel8::ReadBasic( void ) SvxImportMSVBasic aBasicImport( *pShell, *xRootStrg, bLoadCode, bLoadStrg ); bool bAsComment = !bLoadExecutable; aBasicImport.Import( EXC_STORAGE_VBA_PROJECT, EXC_STORAGE_VBA, bAsComment ); + + uno::Reference< sheet::XSpreadsheetDocument > xDocument( pShell->GetModel(), uno::UNO_QUERY ); + ::oox::xls::ExcelVbaProject aVbaProject( ::comphelper::getProcessServiceFactory(), xDocument ); + aVbaProject.createMissingModules(); } } } diff --git a/sc/source/filter/excel/xeroot.cxx b/sc/source/filter/excel/xeroot.cxx index 50e07ae1f2ed..4632a10a088e 100644 --- a/sc/source/filter/excel/xeroot.cxx +++ b/sc/source/filter/excel/xeroot.cxx @@ -28,7 +28,10 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" +#include <rtl/random.h> #include <sfx2/docfile.hxx> +#include <sfx2/request.hxx> +#include <sfx2/frame.hxx> #include <sfx2/sfxsids.hrc> #include <unotools/saveopt.hxx> #include <svl/itemset.hxx> @@ -51,6 +54,8 @@ #include "document.hxx" #include "scextopt.hxx" +using namespace ::com::sun::star; + // Global data ================================================================ XclExpRootData::XclExpRootData( XclBiff eBiff, SfxMedium& rMedium, @@ -241,23 +246,66 @@ bool XclExpRoot::IsDocumentEncrypted() const if (pDocProt && pDocProt->isProtected() && pDocProt->isOptionEnabled(ScDocProtection::STRUCTURE)) return true; - if (GetPassword().Len() > 0) + if ( GetEncryptionData().getLength() > 0 ) // Password is entered directly into the save dialog. return true; return false; } -String XclExpRoot::GetPassword() const +uno::Sequence< beans::NamedValue > XclExpRoot::GenerateEncryptionData( const ::rtl::OUString& aPass ) const { - if( SfxItemSet* pItemSet = GetMedium().GetItemSet() ) + uno::Sequence< beans::NamedValue > aEncryptionData; + + if ( aPass.getLength() > 0 && aPass.getLength() < 16 ) { - const SfxPoolItem* pItem = 0; - if( pItemSet->GetItemState( SID_PASSWORD, TRUE, &pItem ) == SFX_ITEM_SET ) - if( const SfxStringItem* pStrItem = dynamic_cast< const SfxStringItem* >( pItem ) ) - return pStrItem->GetValue(); + TimeValue aTime; + osl_getSystemTime( &aTime ); + rtlRandomPool aRandomPool = rtl_random_createPool (); + rtl_random_addBytes ( aRandomPool, &aTime, 8 ); + + sal_uInt8 pnDocId[16]; + rtl_random_getBytes( aRandomPool, pnDocId, 16 ); + + rtl_random_destroyPool( aRandomPool ); + + sal_uInt16 pnPasswd[16]; + memset( pnPasswd, 0, sizeof( pnPasswd ) ); + for (xub_StrLen nChar = 0; nChar < aPass.getLength(); ++nChar ) + pnPasswd[nChar] = aPass.getStr()[nChar]; + + ::msfilter::MSCodec_Std97 aCodec; + aCodec.InitKey( pnPasswd, pnDocId ); + aEncryptionData = aCodec.GetEncryptionData(); } - return String::EmptyString(); + + return aEncryptionData; +} + +uno::Sequence< beans::NamedValue > XclExpRoot::GetEncryptionData() const +{ + uno::Sequence< beans::NamedValue > aEncryptionData; + SFX_ITEMSET_ARG( GetMedium().GetItemSet(), pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False ); + if ( pEncryptionDataItem ) + pEncryptionDataItem->GetValue() >>= aEncryptionData; + else + { + // try to get the encryption data from the password + SFX_ITEMSET_ARG( GetMedium().GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False ); + if ( pPasswordItem && pPasswordItem->GetValue().Len() ) + aEncryptionData = GenerateEncryptionData( pPasswordItem->GetValue() ); + } + + return aEncryptionData; +} + +uno::Sequence< beans::NamedValue > XclExpRoot::GenerateDefaultEncryptionData() const +{ + uno::Sequence< beans::NamedValue > aEncryptionData; + if ( GetDefaultPassword().Len() > 0 ) + aEncryptionData = GenerateEncryptionData( GetDefaultPassword() ); + + return aEncryptionData; } XclExpRootData::XclExpLinkMgrRef XclExpRoot::GetLocalLinkMgrRef() const diff --git a/sc/source/filter/excel/xestream.cxx b/sc/source/filter/excel/xestream.cxx index f828079c8735..356b0d8bab42 100644 --- a/sc/source/filter/excel/xestream.cxx +++ b/sc/source/filter/excel/xestream.cxx @@ -32,6 +32,7 @@ #include <utility> #include <rtl/ustring.hxx> +#include <rtl/random.h> #include <sax/fshelper.hxx> #include <unotools/streamwrap.hxx> @@ -65,6 +66,7 @@ using ::utl::OStreamWrapper; using ::std::vector; using namespace formula; +using namespace ::com::sun::star; // ============================================================================ @@ -484,17 +486,16 @@ void XclExpStream::WriteRawZeroBytes( sal_Size nBytes ) // ============================================================================ -XclExpBiff8Encrypter::XclExpBiff8Encrypter( const XclExpRoot& rRoot, const sal_uInt8 nDocId[16], - const sal_uInt8 nSalt[16] ) : +XclExpBiff8Encrypter::XclExpBiff8Encrypter( const XclExpRoot& rRoot ) : mrRoot(rRoot), mnOldPos(STREAM_SEEK_TO_END), mbValid(false) { - String aPass = rRoot.GetPassword(); - if (aPass.Len() == 0) + uno::Sequence< beans::NamedValue > aEncryptionData = rRoot.GetEncryptionData(); + if ( aEncryptionData.getLength() == 0 ) // Empty password. Get the default biff8 password. - aPass = rRoot.GetDefaultPassword(); - Init(aPass, nDocId, nSalt); + aEncryptionData = rRoot.GenerateDefaultEncryptionData(); + Init( aEncryptionData ); } XclExpBiff8Encrypter::~XclExpBiff8Encrypter() @@ -506,9 +507,22 @@ bool XclExpBiff8Encrypter::IsValid() const return mbValid; } -void XclExpBiff8Encrypter::GetSaltDigest( sal_uInt8 nSaltDigest[16] ) const +void XclExpBiff8Encrypter::GetSaltDigest( sal_uInt8 pnSaltDigest[16] ) const { - memcpy(nSaltDigest, mnSaltDigest, 16); + if ( sizeof( mpnSaltDigest ) == 16 ) + memcpy( pnSaltDigest, mpnSaltDigest, 16 ); +} + +void XclExpBiff8Encrypter::GetSalt( sal_uInt8 pnSalt[16] ) const +{ + if ( sizeof( mpnSalt ) == 16 ) + memcpy( pnSalt, mpnSalt, 16 ); +} + +void XclExpBiff8Encrypter::GetDocId( sal_uInt8 pnDocId[16] ) const +{ + if ( sizeof( mpnDocId ) == 16 ) + memcpy( pnDocId, mpnDocId, 16 ); } void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_uInt8 nData ) @@ -565,36 +579,32 @@ 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] ) +void XclExpBiff8Encrypter::Init( const uno::Sequence< beans::NamedValue >& aEncryptionData ) { - memset(mnSaltDigest, 0, sizeof(mnSaltDigest)); + mbValid = false; - xub_StrLen nLen = aPass.Len(); - bool bValid = (0 < nLen) && (nLen < 16); - if ( bValid ) + if ( maCodec.InitCodec( aEncryptionData ) ) { - // 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)); + maCodec.GetDocId( mpnDocId ); - // copy document ID - memcpy(mnDocId, nDocId, sizeof(mnDocId)); + // generate the salt here + TimeValue aTime; + osl_getSystemTime( &aTime ); + rtlRandomPool aRandomPool = rtl_random_createPool (); + rtl_random_addBytes( aRandomPool, &aTime, 8 ); + rtl_random_getBytes( aRandomPool, mpnSalt, 16 ); + rtl_random_destroyPool( aRandomPool ); - // init codec - maCodec.InitKey(mnPassw, mnDocId); + memset( mpnSaltDigest, 0, sizeof( mpnSaltDigest ) ); // generate salt hash. ::msfilter::MSCodec_Std97 aCodec; - aCodec.InitKey(mnPassw, mnDocId); - aCodec.CreateSaltDigest(nSalt, mnSaltDigest); + aCodec.InitCodec( aEncryptionData ); + aCodec.CreateSaltDigest( mpnSalt, mpnSaltDigest ); // verify to make sure it's in good shape. - bValid = maCodec.VerifyKey(nSalt, mnSaltDigest); + mbValid = maCodec.VerifyKey( mpnSalt, mpnSaltDigest ); } - - mbValid = bValid; } sal_uInt32 XclExpBiff8Encrypter::GetBlockPos( sal_Size nStrmPos ) const diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx index fb1eb9a3bf44..b210d18f479c 100644 --- a/sc/source/filter/excel/xicontent.cxx +++ b/sc/source/filter/excel/xicontent.cxx @@ -1118,7 +1118,7 @@ ErrCode XclImpDecryptHelper::ReadFilepass( XclImpStream& rStrm ) // request and verify a password (decrypter implements IDocPasswordVerifier) if( xDecr.is() ) - rStrm.GetRoot().RequestPassword( *xDecr ); + rStrm.GetRoot().RequestEncryptionData( *xDecr ); // return error code (success, wrong password, etc.) return xDecr.is() ? xDecr->GetError() : EXC_ENCR_ERROR_UNSUPP_CRYPT; diff --git a/sc/source/filter/excel/xiroot.cxx b/sc/source/filter/excel/xiroot.cxx index 5f8bcbd481e5..9f83dacf4ca0 100644 --- a/sc/source/filter/excel/xiroot.cxx +++ b/sc/source/filter/excel/xiroot.cxx @@ -107,7 +107,7 @@ void XclImpRoot::SetAppFontEncoding( rtl_TextEncoding eAppFontEnc ) SetTextEncoding( eAppFontEnc ); } -void XclImpRoot::InitializeTable( SCTAB /*nScTab*/ ) +void XclImpRoot::InitializeTable( SCTAB nScTab ) { if( GetBiff() <= EXC_BIFF4 ) { @@ -119,6 +119,8 @@ void XclImpRoot::InitializeTable( SCTAB /*nScTab*/ ) GetXFRangeBuffer().Initialize(); GetPageSettings().Initialize(); GetTabViewSettings().Initialize(); + // delete the automatically generated codename + GetDoc().SetCodeName( nScTab, String::EmptyString() ); } void XclImpRoot::FinalizeTable() diff --git a/sc/source/filter/excel/xistream.cxx b/sc/source/filter/excel/xistream.cxx index 98db9dcb4471..534d40fa5cd5 100644 --- a/sc/source/filter/excel/xistream.cxx +++ b/sc/source/filter/excel/xistream.cxx @@ -28,6 +28,9 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" +#include <comphelper/docpasswordhelper.hxx> +#include <comphelper/sequenceashashmap.hxx> + #include "xistream.hxx" #include "xlstring.hxx" #include "xiroot.hxx" @@ -38,6 +41,8 @@ using ::rtl::OString; using ::rtl::OUString; using ::rtl::OUStringToOString; +using namespace ::com::sun::star; + // ============================================================================ // Decryption // ============================================================================ @@ -69,9 +74,16 @@ XclImpDecrypterRef XclImpDecrypter::Clone() const return xNewDecr; } -::comphelper::DocPasswordVerifierResult XclImpDecrypter::verifyPassword( const OUString& rPassword ) +::comphelper::DocPasswordVerifierResult XclImpDecrypter::verifyPassword( const ::rtl::OUString& rPassword, uno::Sequence< beans::NamedValue >& o_rEncryptionData ) +{ + o_rEncryptionData = OnVerifyPassword( rPassword ); + mnError = o_rEncryptionData.getLength() ? ERRCODE_NONE : ERRCODE_ABORT; + return o_rEncryptionData.getLength() ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD; +} + +::comphelper::DocPasswordVerifierResult XclImpDecrypter::verifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData ) { - bool bValid = OnVerify( rPassword ); + bool bValid = OnVerifyEncryptionData( rEncryptionData ); mnError = bValid ? ERRCODE_NONE : ERRCODE_ABORT; return bValid ? ::comphelper::DocPasswordVerifierResult_OK : ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD; } @@ -110,7 +122,6 @@ sal_uInt16 XclImpDecrypter::Read( SvStream& rStrm, void* pData, sal_uInt16 nByte // ---------------------------------------------------------------------------- XclImpBiff5Decrypter::XclImpBiff5Decrypter( sal_uInt16 nKey, sal_uInt16 nHash ) : - maPassword( 16 ), mnKey( nKey ), mnHash( nHash ) { @@ -118,12 +129,12 @@ XclImpBiff5Decrypter::XclImpBiff5Decrypter( sal_uInt16 nKey, sal_uInt16 nHash ) XclImpBiff5Decrypter::XclImpBiff5Decrypter( const XclImpBiff5Decrypter& rSrc ) : XclImpDecrypter( rSrc ), - maPassword( rSrc.maPassword ), + maEncryptionData( rSrc.maEncryptionData ), mnKey( rSrc.mnKey ), mnHash( rSrc.mnHash ) { if( IsValid() ) - maCodec.InitKey( &maPassword.front() ); + maCodec.InitCodec( maEncryptionData ); } XclImpBiff5Decrypter* XclImpBiff5Decrypter::OnClone() const @@ -131,24 +142,59 @@ XclImpBiff5Decrypter* XclImpBiff5Decrypter::OnClone() const return new XclImpBiff5Decrypter( *this ); } -bool XclImpBiff5Decrypter::OnVerify( const OUString& rPassword ) +uno::Sequence< beans::NamedValue > XclImpBiff5Decrypter::OnVerifyPassword( const ::rtl::OUString& rPassword ) { + maEncryptionData.realloc( 0 ); + /* Convert password to a byte string. TODO: this needs some finetuning according to the spec... */ OString aBytePassword = OUStringToOString( rPassword, osl_getThreadTextEncoding() ); sal_Int32 nLen = aBytePassword.getLength(); if( (0 < nLen) && (nLen < 16) ) { - // copy byte string to sal_uInt8 array - maPassword.clear(); - maPassword.resize( 16, 0 ); - memcpy( &maPassword.front(), aBytePassword.getStr(), static_cast< size_t >( nLen ) ); + // init codec + maCodec.InitKey( (sal_uInt8*)aBytePassword.getStr() ); + + if ( maCodec.VerifyKey( mnKey, mnHash ) ) + { + maEncryptionData = maCodec.GetEncryptionData(); + + // since the export uses Std97 encryption always we have to request it here + ::std::vector< sal_uInt16 > aPassVect( 16 ); + ::std::vector< sal_uInt16 >::iterator aIt = aPassVect.begin(); + for( sal_Int32 nInd = 0; nInd < nLen; ++nInd, ++aIt ) + *aIt = static_cast< sal_uInt16 >( rPassword.getStr()[nInd] ); + + uno::Sequence< sal_Int8 > aDocId = ::comphelper::DocPasswordHelper::GenerateRandomByteSequence( 16 ); + OSL_ENSURE( aDocId.getLength() == 16, "Unexpected length of the senquence!" ); + + ::msfilter::MSCodec_Std97 aCodec97; + aCodec97.InitKey( &aPassVect.front(), (sal_uInt8*)aDocId.getConstArray() ); + + // merge the EncryptionData, there should be no conflicts + ::comphelper::SequenceAsHashMap aEncryptionHash( maEncryptionData ); + aEncryptionHash.update( ::comphelper::SequenceAsHashMap( aCodec97.GetEncryptionData() ) ); + aEncryptionHash >> maEncryptionData; + } + } + + return maEncryptionData; +} +bool XclImpBiff5Decrypter::OnVerifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData ) +{ + maEncryptionData.realloc( 0 ); + + if( rEncryptionData.getLength() ) + { // init codec - maCodec.InitKey( &maPassword.front() ); - return maCodec.VerifyKey( mnKey, mnHash ); + maCodec.InitCodec( rEncryptionData ); + + if ( maCodec.VerifyKey( mnKey, mnHash ) ) + maEncryptionData = rEncryptionData; } - return false; + + return maEncryptionData.getLength(); } void XclImpBiff5Decrypter::OnUpdate( sal_Size /*nOldStrmPos*/, sal_Size nNewStrmPos, sal_uInt16 nRecSize ) @@ -168,7 +214,6 @@ sal_uInt16 XclImpBiff5Decrypter::OnRead( SvStream& rStrm, sal_uInt8* pnData, sal XclImpBiff8Decrypter::XclImpBiff8Decrypter( sal_uInt8 pnSalt[ 16 ], sal_uInt8 pnVerifier[ 16 ], sal_uInt8 pnVerifierHash[ 16 ] ) : - maPassword( 16, 0 ), maSalt( pnSalt, pnSalt + 16 ), maVerifier( pnVerifier, pnVerifier + 16 ), maVerifierHash( pnVerifierHash, pnVerifierHash + 16 ) @@ -177,13 +222,13 @@ XclImpBiff8Decrypter::XclImpBiff8Decrypter( sal_uInt8 pnSalt[ 16 ], XclImpBiff8Decrypter::XclImpBiff8Decrypter( const XclImpBiff8Decrypter& rSrc ) : XclImpDecrypter( rSrc ), - maPassword( rSrc.maPassword ), + maEncryptionData( rSrc.maEncryptionData ), maSalt( rSrc.maSalt ), maVerifier( rSrc.maVerifier ), maVerifierHash( rSrc.maVerifierHash ) { if( IsValid() ) - maCodec.InitKey( &maPassword.front(), &maSalt.front() ); + maCodec.InitCodec( maEncryptionData ); } XclImpBiff8Decrypter* XclImpBiff8Decrypter::OnClone() const @@ -191,25 +236,44 @@ XclImpBiff8Decrypter* XclImpBiff8Decrypter::OnClone() const return new XclImpBiff8Decrypter( *this ); } -bool XclImpBiff8Decrypter::OnVerify( const OUString& rPassword ) +uno::Sequence< beans::NamedValue > XclImpBiff8Decrypter::OnVerifyPassword( const ::rtl::OUString& rPassword ) { + maEncryptionData.realloc( 0 ); + sal_Int32 nLen = rPassword.getLength(); if( (0 < nLen) && (nLen < 16) ) { // copy string to sal_uInt16 array - maPassword.clear(); - maPassword.resize( 16, 0 ); + ::std::vector< sal_uInt16 > aPassVect( 16 ); const sal_Unicode* pcChar = rPassword.getStr(); const sal_Unicode* pcCharEnd = pcChar + nLen; - ::std::vector< sal_uInt16 >::iterator aIt = maPassword.begin(); + ::std::vector< sal_uInt16 >::iterator aIt = aPassVect.begin(); for( ; pcChar < pcCharEnd; ++pcChar, ++aIt ) *aIt = static_cast< sal_uInt16 >( *pcChar ); // init codec - maCodec.InitKey( &maPassword.front(), &maSalt.front() ); - return maCodec.VerifyKey( &maVerifier.front(), &maVerifierHash.front() ); + maCodec.InitKey( &aPassVect.front(), &maSalt.front() ); + if ( maCodec.VerifyKey( &maVerifier.front(), &maVerifierHash.front() ) ) + maEncryptionData = maCodec.GetEncryptionData(); + } + + return maEncryptionData; +} + +bool XclImpBiff8Decrypter::OnVerifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData ) +{ + maEncryptionData.realloc( 0 ); + + if( rEncryptionData.getLength() ) + { + // init codec + maCodec.InitCodec( rEncryptionData ); + + if ( maCodec.VerifyKey( &maVerifier.front(), &maVerifierHash.front() ) ) + maEncryptionData = rEncryptionData; } - return false; + + return maEncryptionData.getLength(); } void XclImpBiff8Decrypter::OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 /*nRecSize*/ ) diff --git a/sc/source/filter/excel/xlroot.cxx b/sc/source/filter/excel/xlroot.cxx index 2b2180db5e6a..c6d6c5b9246a 100644 --- a/sc/source/filter/excel/xlroot.cxx +++ b/sc/source/filter/excel/xlroot.cxx @@ -71,6 +71,8 @@ using ::com::sun::star::frame::XFrame; using ::com::sun::star::frame::XFramesSupplier; using ::com::sun::star::lang::XMultiServiceFactory; +using namespace ::com::sun::star; + // Global data ================================================================ #ifdef DBG_UTIL @@ -240,11 +242,11 @@ sal_Int32 XclRoot::GetHmmFromPixelY( double fPixelY ) const return static_cast< sal_Int32 >( fPixelY * mrData.mfScreenPixelY + 0.5 ); } -String XclRoot::RequestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const +uno::Sequence< beans::NamedValue > XclRoot::RequestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) const { ::std::vector< OUString > aDefaultPasswords; aDefaultPasswords.push_back( mrData.maDefPassword ); - return ScfApiHelper::QueryPasswordForMedium( mrData.mrMedium, rVerifier, &aDefaultPasswords ); + return ScfApiHelper::QueryEncryptionDataForMedium( mrData.mrMedium, rVerifier, &aDefaultPasswords ); } bool XclRoot::HasVbaStorage() const diff --git a/sc/source/filter/ftools/fapihelper.cxx b/sc/source/filter/ftools/fapihelper.cxx index eeef52aed550..185923b28277 100644 --- a/sc/source/filter/ftools/fapihelper.cxx +++ b/sc/source/filter/ftools/fapihelper.cxx @@ -38,6 +38,8 @@ #include <tools/urlobj.hxx> #include <sfx2/objsh.hxx> #include <sfx2/docfile.hxx> +#include <sfx2/request.hxx> +#include <sfx2/frame.hxx> #include <sfx2/sfxsids.hrc> #include <svl/stritem.hxx> #include <svl/itemset.hxx> @@ -59,6 +61,8 @@ using ::com::sun::star::lang::XServiceName; using ::com::sun::star::lang::XMultiServiceFactory; using ::com::sun::star::task::PasswordRequestMode_PASSWORD_ENTER; +using namespace ::com::sun::star; + // Static helper functions ==================================================== OUString ScfApiHelper::GetServiceName( Reference< XInterface > xInt ) @@ -136,25 +140,33 @@ Reference< XInterface > ScfApiHelper::CreateInstanceWithArgs( return CreateInstanceWithArgs( ::comphelper::getProcessServiceFactory(), rServiceName, rArgs ); } -String ScfApiHelper::QueryPasswordForMedium( SfxMedium& rMedium, +uno::Sequence< beans::NamedValue > ScfApiHelper::QueryEncryptionDataForMedium( SfxMedium& rMedium, ::comphelper::IDocPasswordVerifier& rVerifier, const ::std::vector< OUString >* pDefaultPasswords ) { - OUString aMediaPassword; - SfxItemSet* pItemSet = rMedium.GetItemSet(); - const SfxPoolItem *pPasswordItem; - if( pItemSet && (SFX_ITEM_SET == pItemSet->GetItemState( SID_PASSWORD, TRUE, &pPasswordItem )) ) - aMediaPassword = static_cast< const SfxStringItem* >( pPasswordItem )->GetValue(); + uno::Sequence< beans::NamedValue > aEncryptionData; + SFX_ITEMSET_ARG( rMedium.GetItemSet(), pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False); + if ( pEncryptionDataItem ) + pEncryptionDataItem->GetValue() >>= aEncryptionData; + + ::rtl::OUString aPassword; + SFX_ITEMSET_ARG( rMedium.GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False); + if ( pPasswordItem ) + aPassword = pPasswordItem->GetValue(); + OUString aDocName = INetURLObject( rMedium.GetOrigURL() ).GetName( INetURLObject::DECODE_WITH_CHARSET ); bool bIsDefaultPassword = false; - OUString aPassword = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( - rVerifier, aMediaPassword, rMedium.GetInteractionHandler(), aDocName, + aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword( + rVerifier, aEncryptionData, aPassword, rMedium.GetInteractionHandler(), aDocName, ::comphelper::DocPasswordRequestType_MS, pDefaultPasswords, &bIsDefaultPassword ); - if( !bIsDefaultPassword && (aPassword.getLength() > 0) && pItemSet ) - pItemSet->Put( SfxStringItem( SID_PASSWORD, aPassword ) ); + rMedium.GetItemSet()->ClearItem( SID_PASSWORD ); + rMedium.GetItemSet()->ClearItem( SID_ENCRYPTIONDATA ); + + if( !bIsDefaultPassword && (aEncryptionData.getLength() > 0) ) + rMedium.GetItemSet()->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) ); - return aPassword; + return aEncryptionData; } // Property sets ============================================================== diff --git a/sc/source/filter/inc/fapihelper.hxx b/sc/source/filter/inc/fapihelper.hxx index 8c204f1cef35..699a4e28720a 100644 --- a/sc/source/filter/inc/fapihelper.hxx +++ b/sc/source/filter/inc/fapihelper.hxx @@ -33,6 +33,7 @@ #include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/beans/XMultiPropertySet.hpp> +#include <com/sun/star/beans/NamedValue.hpp> #include <tools/color.hxx> #include <comphelper/types.hxx> #include "ftools.hxx" @@ -106,9 +107,9 @@ public: const ::rtl::OUString& rServiceName, const UnoAnySequence& rArgs ); - /** Opens a password dialog and returns the entered password. - @return The entered password or an empty string on 'Cancel' or any error. */ - static String QueryPasswordForMedium( SfxMedium& rMedium, + /** Opens a password dialog and returns the encryption data. + @return The encryption data or an empty sequence on 'Cancel' or any error. */ + static ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > QueryEncryptionDataForMedium( SfxMedium& rMedium, ::comphelper::IDocPasswordVerifier& rVerifier, const ::std::vector< ::rtl::OUString >* pDefaultPasswords = 0 ); }; diff --git a/sc/source/filter/inc/xcl97rec.hxx b/sc/source/filter/inc/xcl97rec.hxx index 201562fa752c..8afbe946d2f7 100644 --- a/sc/source/filter/inc/xcl97rec.hxx +++ b/sc/source/filter/inc/xcl97rec.hxx @@ -478,11 +478,11 @@ public: // ============================================================================ -class XclExpFilePass : public XclExpRecord +class XclExpFileEncryption : public XclExpRecord { public: - explicit XclExpFilePass( const XclExpRoot& rRoot ); - virtual ~XclExpFilePass(); + explicit XclExpFileEncryption( const XclExpRoot& rRoot ); + virtual ~XclExpFileEncryption(); private: virtual void WriteBody( XclExpStream& rStrm ); diff --git a/sc/source/filter/inc/xeroot.hxx b/sc/source/filter/inc/xeroot.hxx index 980590f9d4ff..ba51abdef1a2 100644 --- a/sc/source/filter/inc/xeroot.hxx +++ b/sc/source/filter/inc/xeroot.hxx @@ -28,6 +28,8 @@ #ifndef SC_XEROOT_HXX #define SC_XEROOT_HXX +#include <com/sun/star/beans/NamedValue.hpp> + #include "xlroot.hxx" // Forward declarations of objects in public use ============================== @@ -158,7 +160,9 @@ public: bool IsDocumentEncrypted() const; - String GetPassword() const; + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GenerateEncryptionData( const ::rtl::OUString& aPass ) const; + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GetEncryptionData() const; + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > GenerateDefaultEncryptionData() const; private: diff --git a/sc/source/filter/inc/xestream.hxx b/sc/source/filter/inc/xestream.hxx index 3308827441dd..38acef2783e8 100644 --- a/sc/source/filter/inc/xestream.hxx +++ b/sc/source/filter/inc/xestream.hxx @@ -30,6 +30,8 @@ #ifndef SC_XESTREAM_HXX #define SC_XESTREAM_HXX +#include <com/sun/star/beans/NamedValue.hpp> + #include <map> #include <stack> #include <string> @@ -216,13 +218,14 @@ private: class XclExpBiff8Encrypter { public: - explicit XclExpBiff8Encrypter( const XclExpRoot& rRoot, const sal_uInt8 nDocId[16], - const sal_uInt8 nSalt[16] ); + explicit XclExpBiff8Encrypter( const XclExpRoot& rRoot ); ~XclExpBiff8Encrypter(); bool IsValid() const; - void GetSaltDigest( sal_uInt8 nSaltDigest[16] ) const; + void GetSaltDigest( sal_uInt8 pnSaltDigest[16] ) const; + void GetSalt( sal_uInt8 pnSalt[16] ) const; + void GetDocId( sal_uInt8 pnDocId[16] ) const; void Encrypt( SvStream& rStrm, sal_uInt8 nData ); void Encrypt( SvStream& rStrm, sal_uInt16 nData ); @@ -238,17 +241,16 @@ public: 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] ); + void Init( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aEncryptionData ); sal_uInt32 GetBlockPos( sal_Size nStrmPos ) const; sal_uInt16 GetOffsetInBlock( sal_Size nStrmPos ) const; private: ::msfilter::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]; + sal_uInt8 mpnDocId[16]; + sal_uInt8 mpnSalt[16]; + sal_uInt8 mpnSaltDigest[16]; const XclExpRoot& mrRoot; sal_Size mnOldPos; /// Last known stream position diff --git a/sc/source/filter/inc/xistream.hxx b/sc/source/filter/inc/xistream.hxx index 9b27077d78e7..4aec7c337a32 100644 --- a/sc/source/filter/inc/xistream.hxx +++ b/sc/source/filter/inc/xistream.hxx @@ -64,10 +64,9 @@ public: /** Creates a (ref-counted) copy of this decrypter object. */ XclImpDecrypterRef Clone() const; - /** Implementation of the ::comphelper::IDocPasswordVerifier interface, - calls the new virtual function implVerify(). */ - virtual ::comphelper::DocPasswordVerifierResult - verifyPassword( const ::rtl::OUString& rPassword ); + /** Implementation of the ::comphelper::IDocPasswordVerifier interface */ + virtual ::comphelper::DocPasswordVerifierResult verifyPassword( const ::rtl::OUString& rPassword, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& o_rEncryptionData ); + virtual ::comphelper::DocPasswordVerifierResult verifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData ); /** Updates the decrypter on start of a new record or after seeking stream. */ void Update( SvStream& rStrm, sal_uInt16 nRecSize ); @@ -84,7 +83,10 @@ private: virtual XclImpDecrypter* OnClone() const = 0; /** Derived classes implement password verification and initialization of the decoder. */ - virtual bool OnVerify( const ::rtl::OUString& rPassword ) = 0; + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > + OnVerifyPassword( const ::rtl::OUString& rPassword ) = 0; + virtual bool OnVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData ) = 0; + /** Implementation of updating the decrypter. */ virtual void OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 nRecSize ) = 0; /** Implementation of the decryption. */ @@ -111,7 +113,9 @@ private: /** Implementation of cloning this object. */ virtual XclImpBiff5Decrypter* OnClone() const; /** Implements password verification and initialization of the decoder. */ - virtual bool OnVerify( const ::rtl::OUString& rPassword ); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > + OnVerifyPassword( const ::rtl::OUString& rPassword ); + virtual bool OnVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData ); /** Implementation of updating the decrypter. */ virtual void OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 nRecSize ); /** Implementation of the decryption. */ @@ -119,7 +123,7 @@ private: private: ::msfilter::MSCodec_XorXLS95 maCodec; /// Crypto algorithm implementation. - ::std::vector< sal_uInt8 > maPassword; + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > maEncryptionData; sal_uInt16 mnKey; sal_uInt16 mnHash; }; @@ -140,7 +144,9 @@ private: /** Implementation of cloning this object. */ virtual XclImpBiff8Decrypter* OnClone() const; /** Implements password verification and initialization of the decoder. */ - virtual bool OnVerify( const ::rtl::OUString& rPassword ); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > + OnVerifyPassword( const ::rtl::OUString& rPassword ); + virtual bool OnVerifyEncryptionData( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rEncryptionData ); /** Implementation of updating the decrypter. */ virtual void OnUpdate( sal_Size nOldStrmPos, sal_Size nNewStrmPos, sal_uInt16 nRecSize ); /** Implementation of the decryption. */ @@ -153,7 +159,7 @@ private: private: ::msfilter::MSCodec_Std97 maCodec; /// Crypto algorithm implementation. - ::std::vector< sal_uInt16 > maPassword; + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > maEncryptionData; ::std::vector< sal_uInt8 > maSalt; ::std::vector< sal_uInt8 > maVerifier; ::std::vector< sal_uInt8 > maVerifierHash; diff --git a/sc/source/filter/inc/xlroot.hxx b/sc/source/filter/inc/xlroot.hxx index 2f029c74baa9..44ded449cd76 100644 --- a/sc/source/filter/inc/xlroot.hxx +++ b/sc/source/filter/inc/xlroot.hxx @@ -28,6 +28,8 @@ #ifndef SC_XLROOT_HXX #define SC_XLROOT_HXX +#include <com/sun/star/beans/NamedValue.hpp> + #include <i18npool/lang.h> #include <sot/storage.hxx> #include "xlconst.hxx" @@ -196,7 +198,8 @@ public: /** Returns the default password used for stream encryption. */ inline const String& GetDefaultPassword() const { return mrData.maDefPassword; } /** Requests and verifies a password from the medium or the user. */ - String RequestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const; + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > + RequestEncryptionData( ::comphelper::IDocPasswordVerifier& rVerifier ) const; /** Returns the OLE2 root storage of the imported/exported file. @return Pointer to root storage or 0, if the file is a simple stream. */ diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx index df6bdcbbe671..209bbc83f6c3 100644 --- a/sc/source/filter/xcl97/xcl97rec.cxx +++ b/sc/source/filter/xcl97/xcl97rec.cxx @@ -1251,27 +1251,18 @@ void XclDelta::SaveXml( XclExpXmlStream& rStrm ) // ============================================================================ -XclExpFilePass::XclExpFilePass( const XclExpRoot& rRoot ) : +XclExpFileEncryption::XclExpFileEncryption( const XclExpRoot& rRoot ) : XclExpRecord(0x002F, 54), mrRoot(rRoot) { } -XclExpFilePass::~XclExpFilePass() +XclExpFileEncryption::~XclExpFileEncryption() { } -void XclExpFilePass::WriteBody( XclExpStream& rStrm ) +void XclExpFileEncryption::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); @@ -1281,13 +1272,17 @@ void XclExpFilePass::WriteBody( XclExpStream& rStrm ) 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); + sal_uInt8 pnDocId[16]; + sal_uInt8 pnSalt[16]; + sal_uInt8 pnSaltHash[16]; + XclExpEncrypterRef xEnc( new XclExpBiff8Encrypter(mrRoot) ); + xEnc->GetDocId(pnDocId); + xEnc->GetSalt(pnSalt); + xEnc->GetSaltDigest(pnSaltHash); + + rStrm.Write(pnDocId, 16); + rStrm.Write(pnSalt, 16); + rStrm.Write(pnSaltHash, 16); rStrm.SetEncrypter(xEnc); } diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx index bfd9b2b69dae..ddd6dbb3ce24 100644 --- a/sc/source/filter/xml/xmlexprt.cxx +++ b/sc/source/filter/xml/xmlexprt.cxx @@ -4338,15 +4338,20 @@ void ScXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>& ++nPropsToAdd; } + bool bVBACompat = false; uno::Reference <container::XNameAccess> xCodeNameAccess; DBG_ASSERT( pDoc, "ScXMLExport::GetConfigurationSettings - no ScDocument!" ); if( pDoc && pDoc->IsInVBAMode() ) { + // VBA compatibility mode + bVBACompat = true; + ++nPropsToAdd; + // code names xCodeNameAccess = new XMLCodeNameProvider( pDoc ); - if( xCodeNameAccess.is() && xCodeNameAccess->hasElements() ) + if( xCodeNameAccess->hasElements() ) ++nPropsToAdd; else - xCodeNameAccess = 0; + xCodeNameAccess.clear(); } if( nPropsToAdd > 0 ) @@ -4359,10 +4364,17 @@ void ScXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>& rProps[nCount].Value <<= aTrackedChangesKey.makeStringAndClear(); ++nCount; } + if( bVBACompat ) + { + rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VBACompatibilityMode")); + rProps[nCount].Value <<= bVBACompat; + ++nCount; + } if( xCodeNameAccess.is() ) { rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration")); rProps[nCount].Value <<= xCodeNameAccess; + ++nCount; } } } diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx index 269e1dd9a7e4..e83f68bb2bbd 100644 --- a/sc/source/filter/xml/xmlimprt.cxx +++ b/sc/source/filter/xml/xmlimprt.cxx @@ -2219,6 +2219,7 @@ void ScXMLImport::SetConfigurationSettings(const uno::Sequence<beans::PropertyVa { sal_Int32 nCount(aConfigProps.getLength()); rtl::OUString sCTName(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesProtectionKey")); + rtl::OUString sVBName(RTL_CONSTASCII_USTRINGPARAM("VBACompatibilityMode")); rtl::OUString sSCName(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration")); for (sal_Int32 i = nCount - 1; i >= 0; --i) { @@ -2243,26 +2244,15 @@ void ScXMLImport::SetConfigurationSettings(const uno::Sequence<beans::PropertyVa } } } - else if (aConfigProps[i].Name == sSCName) + // store the following items for later use (after document is loaded) + else if ((aConfigProps[i].Name == sVBName) || (aConfigProps[i].Name == sSCName)) { - uno::Type aType = aConfigProps[i].Value.getValueType(); - uno::Reference<beans::XPropertySet> xImportInfo = - getImportInfo(); - - if (xImportInfo.is() && - (aType.equals(getCppuType( - (uno::Reference<container::XNameContainer> *)0 ) ) || - aType.equals(getCppuType( - (uno::Reference<container::XNameAccess> *)0 ) ) ) ) + uno::Reference< beans::XPropertySet > xImportInfo = getImportInfo(); + if (xImportInfo.is()) { - uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = - xImportInfo->getPropertySetInfo(); - if (xPropertySetInfo.is() && - xPropertySetInfo->hasPropertyByName(sSCName) ) - { - xImportInfo->setPropertyValue(sSCName, - aConfigProps[i].Value ); - } + uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = xImportInfo->getPropertySetInfo(); + if (xPropertySetInfo.is() && xPropertySetInfo->hasPropertyByName(aConfigProps[i].Name)) + xImportInfo->setPropertyValue( aConfigProps[i].Name, aConfigProps[i].Value ); } } } diff --git a/sc/source/filter/xml/xmlwrap.cxx b/sc/source/filter/xml/xmlwrap.cxx index dbe647bc433f..7721260367c9 100644 --- a/sc/source/filter/xml/xmlwrap.cxx +++ b/sc/source/filter/xml/xmlwrap.cxx @@ -65,6 +65,7 @@ #include <com/sun/star/lang/DisposedException.hpp> #include <com/sun/star/packages/zip/ZipIOException.hpp> #include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/script/vba/XVBACompatibility.hpp> #include <svx/xmleohlp.hxx> #include <rtl/logfile.hxx> @@ -426,6 +427,7 @@ sal_Bool ScXMLImportWrapper::Import(sal_Bool bStylesOnly, ErrCode& nError) { MAP_LEN( "StreamRelPath" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { MAP_LEN( "StreamName" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { MAP_LEN( "BuildId" ), 0, &::getCppuType( (OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "VBACompatibilityMode" ), 0, &::getBooleanCppuType(), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { MAP_LEN( "ScriptConfiguration" ), 0, &::getCppuType((uno::Reference<container::XNameAccess> *)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, { NULL, 0, 0, NULL, 0, 0 } @@ -643,6 +645,24 @@ sal_Bool ScXMLImportWrapper::Import(sal_Bool bStylesOnly, ErrCode& nError) uno::Reference <container::XNameAccess> xCodeNameAccess; if( aAny >>= xCodeNameAccess ) XMLCodeNameProvider::set( xCodeNameAccess, &rDoc ); + + // VBA compatibility + bool bVBACompat = false; + if ( (xInfoSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("VBACompatibilityMode"))) >>= bVBACompat) && bVBACompat ) + { + /* Set library container to VBA compatibility mode, this + forces loading the Basic project, which in turn creates the + VBA Globals object and does all related initialization. */ + if ( xModelSet.is() ) try + { + uno::Reference< script::vba::XVBACompatibility > xVBACompat( xModelSet->getPropertyValue( + OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicLibraries" ) ) ), uno::UNO_QUERY_THROW ); + xVBACompat->setVBACompatibilityMode( sal_True ); + } + catch( uno::Exception& ) + { + } + } } // Don't test bStylesRetval and bMetaRetval, because it could be an older file which not contain such streams diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx index 4b268b9da791..e6b8b3b5049a 100644 --- a/sc/source/ui/app/transobj.cxx +++ b/sc/source/ui/app/transobj.cxx @@ -134,7 +134,8 @@ ScTransferObj::ScTransferObj( ScDocument* pClipDoc, const TransferableObjectDesc nDragHandleY( 0 ), nDragSourceFlags( 0 ), bDragWasInternal( FALSE ), - bUsedForLink( FALSE ) + bUsedForLink( FALSE ), + bUseInApi( false ) { DBG_ASSERT(pDoc->IsClipboard(), "wrong document"); @@ -540,6 +541,11 @@ void ScTransferObj::SetDragWasInternal() bDragWasInternal = TRUE; } +void ScTransferObj::SetUseInApi( bool bSet ) +{ + bUseInApi = bSet; +} + ScDocument* ScTransferObj::GetSourceDocument() { ScDocShell* pSourceDocSh = GetSourceDocShell(); diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index fc8ba28a217e..038d0a72e824 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -851,13 +851,13 @@ BOOL ScDocFunc::PutCell( const ScAddress& rPos, ScBaseCell* pNewCell, BOOL bApi return TRUE; } -void ScDocFunc::NotifyInputHandler( const ScAddress& /* rPos */ ) +void ScDocFunc::NotifyInputHandler( const ScAddress& rPos ) { ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); if ( pViewSh && pViewSh->GetViewData()->GetDocShell() == &rDocShell ) { ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl(); - if ( pInputHdl ) + if ( pInputHdl && pInputHdl->GetCursorPos() == rPos ) { sal_Bool bIsEditMode(pInputHdl->IsEditMode()); @@ -986,7 +986,7 @@ ScTokenArray* lcl_ScDocFunc_CreateTokenArrayXML( const String& rText, const Stri ScBaseCell* ScDocFunc::InterpretEnglishString( const ScAddress& rPos, - const String& rText, const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar ) + const String& rText, const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar, short* pRetFormatType ) { ScDocument* pDoc = rDocShell.GetDocument(); ScBaseCell* pNewCell = NULL; @@ -1020,7 +1020,12 @@ ScBaseCell* ScDocFunc::InterpretEnglishString( const ScAddress& rPos, sal_uInt32 nEnglish = pFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US); double fVal; if ( pFormatter->IsNumberFormat( rText, nEnglish, fVal ) ) + { pNewCell = new ScValueCell( fVal ); + // return the format type from the English format, so a localized format can be created + if ( pRetFormatType ) + *pRetFormatType = pFormatter->GetType( nEnglish ); + } else if ( rText.Len() ) pNewCell = ScBaseCell::CreateTextCell( rText, pDoc ); @@ -2650,8 +2655,7 @@ void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, String& sModuleName, String uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY ); if ( xVBAModuleInfo.is() ) { - String sCodeName( genModuleName ); - rDoc.SetCodeName( nTab, sCodeName ); + rDoc.SetCodeName( nTab, genModuleName ); script::ModuleInfo sModuleInfo = lcl_InitModuleInfo( rDocSh, genModuleName ); xVBAModuleInfo->insertModuleInfo( genModuleName, sModuleInfo ); xLib->insertByName( genModuleName, aSourceAny ); diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index d5d7f6e09292..e7089349fdb7 100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -72,7 +72,6 @@ #include <com/sun/star/task/XJob.hpp> #include <basic/sbstar.hxx> #include <basic/basmgr.hxx> -#include <vbahelper/vbaaccesshelper.hxx> #include "scabstdlg.hxx" //CHINA001 #include <sot/formats.hxx> @@ -554,6 +553,13 @@ void __EXPORT ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint ) xVbaEvents->processVbaEvent( WORKBOOK_AFTERSAVE, aArgs ); } break; + case SFX_EVENT_CLOSEDOC: + { + // #163655# prevent event processing after model is disposed + aDocument.SetVbaEventProcessor( uno::Reference< script::vba::XVBAEventProcessor >() ); + uno::Reference< lang::XEventListener >( xVbaEvents, uno::UNO_QUERY_THROW )->disposing( lang::EventObject() ); + } + break; } } } @@ -619,25 +625,6 @@ void __EXPORT ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint ) SetReadOnlyUI( sal_True ); } } - - // VBA specific initialization - if( aDocument.IsInVBAMode() ) try - { - uno::Reference< frame::XModel > xModel( GetModel(), uno::UNO_SET_THROW ); - - // create VBAGlobals object if not yet done (this also creates the "ThisExcelDoc" symbol) - uno::Reference< lang::XMultiServiceFactory > xFactory( xModel, uno::UNO_QUERY_THROW ); - xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals" ) ) ); - - // create the VBA document event processor - uno::Sequence< uno::Any > aArgs( 1 ); - aArgs[ 0 ] <<= xModel; - xVbaEvents.set( ooo::vba::createVBAUnoAPIServiceWithArgs( this, "com.sun.star.script.vba.VBASpreadsheetEventProcessor" , aArgs ), uno::UNO_QUERY ); - aDocument.SetVbaEventProcessor( xVbaEvents ); - } - catch( uno::Exception& ) - { - } } break; case SFX_EVENT_VIEWCREATED: diff --git a/sc/source/ui/inc/anyrefdg.hxx b/sc/source/ui/inc/anyrefdg.hxx index 0e7560fe0c50..62f7bfd865e7 100644 --- a/sc/source/ui/inc/anyrefdg.hxx +++ b/sc/source/ui/inc/anyrefdg.hxx @@ -29,7 +29,7 @@ #define SC_ANYREFDG_HXX #ifndef _IMAGEBTN_HXX -#include <vcl/imagebtn.hxx> +#include <vcl/button.hxx> #endif #ifndef _EDIT_HXX #include <vcl/edit.hxx> diff --git a/sc/source/ui/inc/crdlg.hxx b/sc/source/ui/inc/crdlg.hxx index 20dd79f359ad..77d844d161b3 100644 --- a/sc/source/ui/inc/crdlg.hxx +++ b/sc/source/ui/inc/crdlg.hxx @@ -30,7 +30,7 @@ #include <vcl/dialog.hxx> -#include <vcl/imagebtn.hxx> +#include <vcl/button.hxx> #include <vcl/fixed.hxx> #include "scui_def.hxx" //CHINA001 diff --git a/sc/source/ui/inc/delcldlg.hxx b/sc/source/ui/inc/delcldlg.hxx index e1a816e78c0f..ae5cb565b4e7 100644 --- a/sc/source/ui/inc/delcldlg.hxx +++ b/sc/source/ui/inc/delcldlg.hxx @@ -30,7 +30,7 @@ #include <vcl/dialog.hxx> -#include <vcl/imagebtn.hxx> +#include <vcl/button.hxx> #include <vcl/fixed.hxx> diff --git a/sc/source/ui/inc/delcodlg.hxx b/sc/source/ui/inc/delcodlg.hxx index 8773b9c78f3a..3991184d7c5e 100644 --- a/sc/source/ui/inc/delcodlg.hxx +++ b/sc/source/ui/inc/delcodlg.hxx @@ -30,7 +30,7 @@ #include <vcl/dialog.hxx> #include <vcl/fixed.hxx> -#include <vcl/imagebtn.hxx> +#include <vcl/button.hxx> #include "global.hxx" //------------------------------------------------------------------------ diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx index c92cc082986d..e36e1a9af92f 100644 --- a/sc/source/ui/inc/docfunc.hxx +++ b/sc/source/ui/inc/docfunc.hxx @@ -92,7 +92,8 @@ public: // creates a new cell for use with PutCell ScBaseCell* InterpretEnglishString( const ScAddress& rPos, const String& rText, - const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar ); + const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar, + short* pRetFormatType = NULL ); bool ShowNote( const ScAddress& rPos, bool bShow = true ); inline bool HideNote( const ScAddress& rPos ) { return ShowNote( rPos, false ); } diff --git a/sc/source/ui/inc/dwfunctr.hxx b/sc/source/ui/inc/dwfunctr.hxx index 800696970fbd..5d23172f7d8c 100644 --- a/sc/source/ui/inc/dwfunctr.hxx +++ b/sc/source/ui/inc/dwfunctr.hxx @@ -37,7 +37,7 @@ #endif #ifndef _IMAGEBTN_HXX //autogen -#include <vcl/imagebtn.hxx> +#include <vcl/button.hxx> #endif #ifndef _COMBOBOX_HXX //autogen diff --git a/sc/source/ui/inc/groupdlg.hxx b/sc/source/ui/inc/groupdlg.hxx index 38b96f21e90e..03f05ab0705d 100644 --- a/sc/source/ui/inc/groupdlg.hxx +++ b/sc/source/ui/inc/groupdlg.hxx @@ -30,7 +30,7 @@ #include <vcl/dialog.hxx> -#include <vcl/imagebtn.hxx> +#include <vcl/button.hxx> #include <vcl/fixed.hxx> //------------------------------------------------------------------------ diff --git a/sc/source/ui/inc/imoptdlg.hxx b/sc/source/ui/inc/imoptdlg.hxx index 01e10f9a3983..d959069c46b6 100644 --- a/sc/source/ui/inc/imoptdlg.hxx +++ b/sc/source/ui/inc/imoptdlg.hxx @@ -32,7 +32,7 @@ #include <vcl/fixed.hxx> #include <vcl/combobox.hxx> #include <vcl/lstbox.hxx> -#include <vcl/imagebtn.hxx> +#include <vcl/button.hxx> #include <svx/txencbox.hxx> #include "scdllapi.h" #include "global.hxx" diff --git a/sc/source/ui/inc/inputhdl.hxx b/sc/source/ui/inc/inputhdl.hxx index 61974cf7464d..f3eba8b26f6b 100644 --- a/sc/source/ui/inc/inputhdl.hxx +++ b/sc/source/ui/inc/inputhdl.hxx @@ -168,6 +168,8 @@ public: const String& GetEditString(); const String& GetFormString() const { return aFormText; } + const ScAddress& GetCursorPos() const { return aCursorPos; } + BOOL GetTextAndFields( ScEditEngineDefaulter& rDestEngine ); BOOL KeyInput( const KeyEvent& rKEvt, BOOL bStartEdit = FALSE ); diff --git a/sc/source/ui/inc/inscldlg.hxx b/sc/source/ui/inc/inscldlg.hxx index fd8c090cfd33..110c914f294c 100644 --- a/sc/source/ui/inc/inscldlg.hxx +++ b/sc/source/ui/inc/inscldlg.hxx @@ -29,7 +29,7 @@ #define SC_INSCLDLG_HXX #include <vcl/dialog.hxx> -#include <vcl/imagebtn.hxx> +#include <vcl/button.hxx> #include <vcl/fixed.hxx> diff --git a/sc/source/ui/inc/inscodlg.hxx b/sc/source/ui/inc/inscodlg.hxx index ffdccaba6a10..cf8008809d52 100644 --- a/sc/source/ui/inc/inscodlg.hxx +++ b/sc/source/ui/inc/inscodlg.hxx @@ -29,7 +29,7 @@ #define SC_INSCODLG_HXX #include <vcl/dialog.hxx> -#include <vcl/imagebtn.hxx> +#include <vcl/button.hxx> #include <vcl/fixed.hxx> #include "global.hxx" diff --git a/sc/source/ui/inc/mtrindlg.hxx b/sc/source/ui/inc/mtrindlg.hxx index f88f57a74e58..c9249f9fe945 100644 --- a/sc/source/ui/inc/mtrindlg.hxx +++ b/sc/source/ui/inc/mtrindlg.hxx @@ -30,7 +30,7 @@ #include <vcl/dialog.hxx> #include <vcl/field.hxx> -#include <vcl/imagebtn.hxx> +#include <vcl/button.hxx> #include <vcl/fixed.hxx> diff --git a/sc/source/ui/inc/mvtabdlg.hxx b/sc/source/ui/inc/mvtabdlg.hxx index d5ce7726243f..6ca196a4fbb5 100644 --- a/sc/source/ui/inc/mvtabdlg.hxx +++ b/sc/source/ui/inc/mvtabdlg.hxx @@ -31,7 +31,7 @@ #include "address.hxx" #include <vcl/dialog.hxx> -#include <vcl/imagebtn.hxx> +#include <vcl/button.hxx> #include <vcl/lstbox.hxx> #include <vcl/fixed.hxx> diff --git a/sc/source/ui/inc/namecrea.hxx b/sc/source/ui/inc/namecrea.hxx index e4e053fe0bcf..8f2e90bcacfc 100644 --- a/sc/source/ui/inc/namecrea.hxx +++ b/sc/source/ui/inc/namecrea.hxx @@ -29,7 +29,7 @@ #define SC_NAMECREA_HXX #include <vcl/dialog.hxx> -#include <vcl/imagebtn.hxx> +#include <vcl/button.hxx> #include <vcl/fixed.hxx> #include "scui_def.hxx" //CHINA001 diff --git a/sc/source/ui/inc/namepast.hxx b/sc/source/ui/inc/namepast.hxx index 3286af7b81bc..c3e408d0c373 100644 --- a/sc/source/ui/inc/namepast.hxx +++ b/sc/source/ui/inc/namepast.hxx @@ -29,7 +29,7 @@ #define SC_NAMEPAST_HXX #include <vcl/dialog.hxx> -#include <vcl/imagebtn.hxx> +#include <vcl/button.hxx> #include <vcl/fixed.hxx> #include <vcl/lstbox.hxx> diff --git a/sc/source/ui/inc/scendlg.hxx b/sc/source/ui/inc/scendlg.hxx index 6281bb58b02c..5be21d87a6f2 100644 --- a/sc/source/ui/inc/scendlg.hxx +++ b/sc/source/ui/inc/scendlg.hxx @@ -32,7 +32,7 @@ #include <vcl/dialog.hxx> #include <vcl/edit.hxx> #include <vcl/fixed.hxx> -#include <vcl/imagebtn.hxx> +#include <vcl/button.hxx> #include <svtools/svmedit.hxx> #include <svtools/ctrlbox.hxx> diff --git a/sc/source/ui/inc/strindlg.hxx b/sc/source/ui/inc/strindlg.hxx index b5dd140a4109..a3a99684cddc 100644 --- a/sc/source/ui/inc/strindlg.hxx +++ b/sc/source/ui/inc/strindlg.hxx @@ -31,7 +31,7 @@ #include <vcl/dialog.hxx> #include <vcl/fixed.hxx> -#include <vcl/imagebtn.hxx> +#include <vcl/button.hxx> #include <vcl/edit.hxx> #include <layout/layout.hxx> diff --git a/sc/source/ui/inc/tabbgcolordlg.hxx b/sc/source/ui/inc/tabbgcolordlg.hxx index e7ca3da290b0..64145a58a07c 100644 --- a/sc/source/ui/inc/tabbgcolordlg.hxx +++ b/sc/source/ui/inc/tabbgcolordlg.hxx @@ -32,7 +32,8 @@ #define SC_TABBGCOLORDLG_HXX #include <vcl/dialog.hxx> -#include <vcl/imagebtn.hxx> +#include <vcl/fixed.hxx> +#include <vcl/button.hxx> #include <svtools/valueset.hxx> //------------------------------------------------------------------------ diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx index a6e99613f2ea..ab21a6161752 100644 --- a/sc/source/ui/inc/tabview.hxx +++ b/sc/source/ui/inc/tabview.hxx @@ -287,7 +287,8 @@ public: BOOL IsMinimized() const { return bMinimized; } - void TabChanged(); + // bSameTabButMoved = true if the same sheet as before is activated, used after moving/copying/inserting/deleting a sheet + void TabChanged( bool bSameTabButMoved = false ); void SetZoom( const Fraction& rNewX, const Fraction& rNewY, BOOL bAll ); SC_DLLPUBLIC void RefreshZoom(); void SetPagebreakMode( BOOL bSet ); @@ -387,10 +388,8 @@ public: void SetNewStartIfMarking(); - //<!--Added by PengYunQuan for Validity Cell Range Picker - //void SetTabNo( SCTAB nTab, BOOL bNew = FALSE, BOOL bExtendSelection = FALSE ); - SC_DLLPUBLIC void SetTabNo( SCTAB nTab, BOOL bNew = FALSE, BOOL bExtendSelection = FALSE ); - //-->Added by PengYunQuan for Validity Cell Range Picker + // bSameTabButMoved = true if the same sheet as before is activated, used after moving/copying/inserting/deleting a sheet + SC_DLLPUBLIC void SetTabNo( SCTAB nTab, BOOL bNew = FALSE, BOOL bExtendSelection = FALSE, bool bSameTabButMoved = false ); void SelectNextTab( short nDir, BOOL bExtendSelection = FALSE ); void ActivateView( BOOL bActivate, BOOL bFirst ); diff --git a/sc/source/ui/inc/tphf.hxx b/sc/source/ui/inc/tphf.hxx index dcf730712a40..efd681a688a6 100644 --- a/sc/source/ui/inc/tphf.hxx +++ b/sc/source/ui/inc/tphf.hxx @@ -29,7 +29,7 @@ #define SC_TPHF_HXX -#include <svx/hdft2.hxx> +#include <svx/hdft.hxx> class ScStyleDlg; diff --git a/sc/source/ui/inc/transobj.hxx b/sc/source/ui/inc/transobj.hxx index e2dbad485812..546637c726d0 100644 --- a/sc/source/ui/inc/transobj.hxx +++ b/sc/source/ui/inc/transobj.hxx @@ -64,6 +64,7 @@ private: BOOL bDragWasInternal; BOOL bUsedForLink; bool bHasFiltered; // if has filtered rows + bool bUseInApi; // to recognize clipboard content copied from API void InitDocShell(); static void StripRefs( ScDocument* pDoc, SCCOL nStartX, SCROW nStartY, @@ -93,6 +94,7 @@ public: SCTAB GetVisibleTab() const { return nVisibleTab; } USHORT GetDragSourceFlags() const { return nDragSourceFlags; } bool HasFilteredRows() const { return bHasFiltered; } + bool GetUseInApi() const { return bUseInApi; } ScDocShell* GetSourceDocShell(); ScDocument* GetSourceDocument(); ScMarkData GetSourceMarkData(); @@ -103,6 +105,7 @@ public: void SetDragSource( ScDocShell* pSourceShell, const ScMarkData& rMark ); void SetDragSourceFlags( USHORT nFlags ); void SetDragWasInternal(); + SC_DLLPUBLIC void SetUseInApi( bool bSet ); static SC_DLLPUBLIC ScTransferObj* GetOwnClipboard( Window* pUIWin ); diff --git a/sc/source/ui/inc/ui_pch.hxx b/sc/source/ui/inc/ui_pch.hxx index 1ef2f02d405b..a1dcbf904694 100644 --- a/sc/source/ui/inc/ui_pch.hxx +++ b/sc/source/ui/inc/ui_pch.hxx @@ -208,7 +208,7 @@ #include <svl/stritem.hxx> #include <collect.hxx> #include <svx/svdsob.hxx> -#include <vcl/imagebtn.hxx> +#include <vcl/button.hxx> #include <svx/svdobj.hxx> #include <svx/svdglue.hxx> #include <svx/svdlayer.hxx> diff --git a/sc/source/ui/miscdlgs/acredlin.cxx b/sc/source/ui/miscdlgs/acredlin.cxx index 6f59b64c52fc..d2cc5a7390cf 100644 --- a/sc/source/ui/miscdlgs/acredlin.cxx +++ b/sc/source/ui/miscdlgs/acredlin.cxx @@ -179,7 +179,7 @@ ScAcceptChgDlg::ScAcceptChgDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pP pTPView->SetRejectAllClickHdl( LINK( this, ScAcceptChgDlg,RejectAllHandle)); pTPView->SetAcceptAllClickHdl( LINK(this, ScAcceptChgDlg, AcceptAllHandle)); pTheView->SetCalcView(); - pTheView->SetWindowBits(WB_HASLINES|WB_CLIPCHILDREN|WB_HASBUTTONS|WB_HASBUTTONSATROOT|WB_HSCROLL); + pTheView->SetStyle(pTheView->GetStyle()|WB_HASLINES|WB_CLIPCHILDREN|WB_HASBUTTONS|WB_HASBUTTONSATROOT|WB_HSCROLL); pTheView->SetExpandingHdl( LINK(this, ScAcceptChgDlg, ExpandingHandle)); pTheView->SetSelectHdl( LINK(this, ScAcceptChgDlg, SelectHandle)); pTheView->SetDeselectHdl( LINK(this, ScAcceptChgDlg, SelectHandle)); diff --git a/sc/source/ui/miscdlgs/conflictsdlg.cxx b/sc/source/ui/miscdlgs/conflictsdlg.cxx index 89f818e21928..5ff5ca570ee4 100644 --- a/sc/source/ui/miscdlgs/conflictsdlg.cxx +++ b/sc/source/ui/miscdlgs/conflictsdlg.cxx @@ -514,7 +514,7 @@ ScConflictsDlg::ScConflictsDlg( Window* pParent, ScViewData* pViewData, ScDocume aHeader += maStrTitleDate; maLbConflicts.InsertHeaderEntry( aHeader, HEADERBAR_APPEND, HIB_LEFT | HIB_LEFTIMAGE | HIB_VCENTER ); - maLbConflicts.SetWindowBits( WB_HASLINES | WB_CLIPCHILDREN | WB_HASBUTTONS | WB_HASBUTTONSATROOT | WB_HSCROLL ); + maLbConflicts.SetStyle( maLbConflicts.GetStyle() | WB_HASLINES | WB_CLIPCHILDREN | WB_HASBUTTONS | WB_HASBUTTONSATROOT | WB_HSCROLL ); maLbConflicts.SetSelectionMode( MULTIPLE_SELECTION ); maLbConflicts.SetHighlightRange(); diff --git a/sc/source/ui/miscdlgs/scuiautofmt.cxx b/sc/source/ui/miscdlgs/scuiautofmt.cxx index 1b14b15e24c8..7594dddd914b 100644 --- a/sc/source/ui/miscdlgs/scuiautofmt.cxx +++ b/sc/source/ui/miscdlgs/scuiautofmt.cxx @@ -49,7 +49,7 @@ #include <svl/zforlist.hxx> #include <vcl/msgbox.hxx> #include <comphelper/processfactory.hxx> - +#include <sfx2/sfxresid.hxx> #include "sc.hrc" #include "scmod.hxx" #include "attrib.hxx" @@ -251,7 +251,7 @@ IMPL_LINK( ScAutoFormatDlg, AddHdl, void *, EMPTYARG ) { if ( !bFmtInserted && pSelFmtData ) { - String aStrStandard( ScResId(STR_STANDARD) ); + String aStrStandard( SfxResId(STR_STANDARD) ); String aFormatName; ScStringInputDlg* pDlg; BOOL bOk = FALSE; diff --git a/sc/source/ui/miscdlgs/solveroptions.cxx b/sc/source/ui/miscdlgs/solveroptions.cxx index 418a88b3cbea..d165c2362d7e 100644 --- a/sc/source/ui/miscdlgs/solveroptions.cxx +++ b/sc/source/ui/miscdlgs/solveroptions.cxx @@ -145,7 +145,7 @@ ScSolverOptionsDialog::ScSolverOptionsDialog( Window* pParent, maBtnEdit.SetClickHdl( LINK( this, ScSolverOptionsDialog, ButtonHdl ) ); - maLbSettings.SetWindowBits( WB_CLIPCHILDREN|WB_FORCE_MAKEVISIBLE ); + maLbSettings.SetStyle( maLbSettings.GetStyle()|WB_CLIPCHILDREN|WB_FORCE_MAKEVISIBLE ); maLbSettings.SetHelpId( HID_SC_SOLVEROPTIONS_LB ); maLbSettings.SetHighlightRange(); diff --git a/sc/source/ui/navipi/content.cxx b/sc/source/ui/navipi/content.cxx index a417621bb303..0b991bb83220 100644 --- a/sc/source/ui/navipi/content.cxx +++ b/sc/source/ui/navipi/content.cxx @@ -145,6 +145,8 @@ ScContentTree::ScContentTree( Window* pParent, const ResId& rResId ) : SetNodeDefaultImages(); SetDoubleClickHdl( LINK( this, ScContentTree, ContentDoubleClickHdl ) ); + + SetStyle( GetStyle() | WB_QUICK_SEARCH ); } ScContentTree::~ScContentTree() @@ -1327,11 +1329,11 @@ BOOL ScContentTree::LoadFile( const String& rUrl ) void ScContentTree::InitWindowBits( BOOL bButtons ) { - WinBits nFlags = WB_CLIPCHILDREN|WB_HSCROLL; + WinBits nFlags = GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL; if (bButtons) nFlags |= WB_HASBUTTONS|WB_HASBUTTONSATROOT; - SetWindowBits( nFlags ); + SetStyle( nFlags ); } void ScContentTree::SetRootType( USHORT nNew ) diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx index dea7cc056756..53ac57ee2318 100644 --- a/sc/source/ui/unoobj/cellsuno.cxx +++ b/sc/source/ui/unoobj/cellsuno.cxx @@ -6272,6 +6272,53 @@ void ScCellObj::SetFormulaWithGrammar( const ::rtl::OUString& rFormula, } } +void ScCellObj::InputEnglishString( const ::rtl::OUString& rText ) +{ + // This is like a mixture of setFormula and property FormulaLocal: + // The cell's number format is checked for "text", a new cell format may be set, + // but all parsing is in English. + + ScDocShell* pDocSh = GetDocShell(); + if ( pDocSh ) + { + String aString(rText); + ScDocument* pDoc = pDocSh->GetDocument(); + SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); + sal_uInt32 nOldFormat = pDoc->GetNumberFormat( aCellPos ); + if ( pFormatter->GetType( nOldFormat ) == NUMBERFORMAT_TEXT ) + { + SetString_Impl(aString, FALSE, FALSE); // text cell + } + else + { + ScDocFunc aFunc(*pDocSh); + short nFormatType = 0; + ScBaseCell* pNewCell = aFunc.InterpretEnglishString( aCellPos, aString, + EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1, &nFormatType ); + if (pNewCell) + { + if ( ( nOldFormat % SV_COUNTRY_LANGUAGE_OFFSET ) == 0 && nFormatType != 0 ) + { + // apply a format for the recognized type and the old format's language + sal_uInt32 nNewFormat = ScGlobal::GetStandardFormat( *pFormatter, nOldFormat, nFormatType ); + if ( nNewFormat != nOldFormat ) + { + ScPatternAttr aPattern( pDoc->GetPool() ); + aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) ); + // ATTR_LANGUAGE_FORMAT remains unchanged + aFunc.ApplyAttributes( *GetMarkData(), aPattern, TRUE, TRUE ); + } + } + // put the cell into the document + // (after applying the format, so possible formula recalculation already uses the new format) + (void)aFunc.PutCell( aCellPos, pNewCell, TRUE ); + } + else + SetString_Impl(aString, FALSE, FALSE); // no cell from InterpretEnglishString, probably empty string + } + } +} + // XText uno::Reference<text::XTextCursor> SAL_CALL ScCellObj::createTextCursor() @@ -8482,8 +8529,7 @@ void ScTableSheetObj::SetOnePropertyValue( const SfxItemPropertySimpleEntry* pEn rtl::OUString aCodeName; if ( pDocSh && ( aValue >>= aCodeName ) ) { - String sNewName( aCodeName ); - pDocSh->GetDocument()->SetCodeName( GetTab_Impl(), sNewName ); + pDocSh->GetDocument()->SetCodeName( GetTab_Impl(), aCodeName ); } } else diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index c92525b8ca57..828ec8f09297 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -590,8 +590,21 @@ void ScModelObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) DELETEZ( pPrintFuncCache ); // handle "OnCalculate" sheet events (search also for VBA event handlers) - if ( pDocShell && pDocShell->GetDocument()->HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE, true ) ) - HandleCalculateEvents(); + if ( pDocShell ) + { + ScDocument* pDoc = pDocShell->GetDocument(); + if ( pDoc->GetVbaEventProcessor().is() ) + { + // If the VBA event processor is set, HasAnyCalcNotification is much faster than HasAnySheetEventScript + if ( pDoc->HasAnyCalcNotification() && pDoc->HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE, true ) ) + HandleCalculateEvents(); + } + else + { + if ( pDoc->HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE ) ) + HandleCalculateEvents(); + } + } } } else if ( rHint.ISA( ScPointerChangedHint ) ) @@ -1275,6 +1288,8 @@ void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelec rBookmarks.clear(); } + if ( pDrawView ) + pDrawView->HideSdrPage(); delete pDrawView; } @@ -1957,6 +1972,7 @@ uno::Reference<uno::XInterface> SAL_CALL ScModelObj::createInstance( case SC_SERVICE_MARKERTAB: xRet.set(xDrawMarkerTab); break; case SC_SERVICE_DASHTAB: xRet.set(xDrawDashTab); break; case SC_SERVICE_CHDATAPROV: xRet.set(xChartDataProv); break; + case SC_SERVICE_VBAOBJECTPROVIDER: xRet.set(xObjProvider); break; } // #i64497# If a chart is in a temporary document during clipoard paste, @@ -1982,6 +1998,7 @@ uno::Reference<uno::XInterface> SAL_CALL ScModelObj::createInstance( case SC_SERVICE_MARKERTAB: xDrawMarkerTab.set(xRet); break; case SC_SERVICE_DASHTAB: xDrawDashTab.set(xRet); break; case SC_SERVICE_CHDATAPROV: xChartDataProv.set(xRet); break; + case SC_SERVICE_VBAOBJECTPROVIDER: xObjProvider.set(xRet); break; } } } diff --git a/sc/source/ui/unoobj/scdetect.cxx b/sc/source/ui/unoobj/scdetect.cxx index 03d6d14a3ac7..affedff83c7b 100644 --- a/sc/source/ui/unoobj/scdetect.cxx +++ b/sc/source/ui/unoobj/scdetect.cxx @@ -400,20 +400,16 @@ static BOOL lcl_IsAnyXMLFilter( const SfxFilter* pFilter ) if ( !bRepairPackage ) { // ask the user whether he wants to try to repair - RequestPackageReparation* pRequest = new RequestPackageReparation( aDocumentTitle ); - uno::Reference< task::XInteractionRequest > xRequest ( pRequest ); - - xInteraction->handle( xRequest ); - - bRepairAllowed = pRequest->isApproved(); + RequestPackageReparation aRequest( aDocumentTitle ); + xInteraction->handle( aRequest.GetRequest() ); + bRepairAllowed = aRequest.isApproved(); } if ( !bRepairAllowed ) { // repair either not allowed or not successful - NotifyBrokenPackage* pNotifyRequest = new NotifyBrokenPackage( aDocumentTitle ); - uno::Reference< task::XInteractionRequest > xRequest ( pNotifyRequest ); - xInteraction->handle( xRequest ); + NotifyBrokenPackage aNotifyRequest( aDocumentTitle ); + xInteraction->handle( aNotifyRequest.GetRequest() ); } } diff --git a/sc/source/ui/unoobj/servuno.cxx b/sc/source/ui/unoobj/servuno.cxx index a173e6d1e051..0a1f86afd7d1 100644 --- a/sc/source/ui/unoobj/servuno.cxx +++ b/sc/source/ui/unoobj/servuno.cxx @@ -28,8 +28,6 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" - - #include <tools/debug.hxx> #include <svtools/unoimap.hxx> #include <svx/unofill.hxx> @@ -61,6 +59,7 @@ #include <sfx2/docfile.hxx> #include <sfx2/docfilt.hxx> #include <com/sun/star/script/ScriptEventDescriptor.hpp> +#include <com/sun/star/script/vba/XVBAEventProcessor.hpp> #include <com/sun/star/document/XCodeNameQuery.hpp> #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> #include <com/sun/star/form/XFormsSupplier.hpp> @@ -573,6 +572,11 @@ uno::Reference<uno::XInterface> ScServiceProvider::MakeInstance( BasicManager* pAppMgr = SFX_APP()->GetBasicManager(); if ( pAppMgr ) pAppMgr->SetGlobalUNOConstant( "ThisExcelDoc", aArgs[ 0 ] ); + + // create the VBA document event processor + uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( + ::ooo::vba::createVBAUnoAPIServiceWithArgs( pDocShell, "com.sun.star.script.vba.VBASpreadsheetEventProcessor", aArgs ), uno::UNO_QUERY ); + pDocShell->GetDocument()->SetVbaEventProcessor( xVbaEvents ); } } break; diff --git a/sc/source/ui/unoobj/viewuno.cxx b/sc/source/ui/unoobj/viewuno.cxx index fd1e655b8ffb..7646e52c030f 100644 --- a/sc/source/ui/unoobj/viewuno.cxx +++ b/sc/source/ui/unoobj/viewuno.cxx @@ -572,7 +572,7 @@ void lcl_CallActivate( ScDocShell* pDocSh, SCTAB nTab, sal_Int32 nEvent ) } } -void ScTabViewObj::SheetChanged() +void ScTabViewObj::SheetChanged( bool bSameTabButMoved ) { if ( !GetViewShell() ) return; @@ -600,9 +600,10 @@ void ScTabViewObj::SheetChanged() } } - // handle sheet events + /* Handle sheet events, but do not trigger event handlers, if the old + active sheet gets re-activated after inserting/deleting/moving a sheet. */ SCTAB nNewTab = pViewData->GetTabNo(); - if ( nNewTab != nPreviousTab ) + if ( !bSameTabButMoved && (nNewTab != nPreviousTab) ) { lcl_CallActivate( pDocSh, nPreviousTab, SC_SHEETEVENT_UNFOCUS ); lcl_CallActivate( pDocSh, nNewTab, SC_SHEETEVENT_FOCUS ); diff --git a/sc/source/ui/vba/excelvbahelper.cxx b/sc/source/ui/vba/excelvbahelper.cxx index 2c39d7154b4b..42a415d68e32 100644 --- a/sc/source/ui/vba/excelvbahelper.cxx +++ b/sc/source/ui/vba/excelvbahelper.cxx @@ -24,24 +24,25 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ -#include <docuno.hxx> + #include "excelvbahelper.hxx" + +#include <comphelper/processfactory.hxx> +#include <com/sun/star/sheet/XSheetCellRange.hpp> +#include "docuno.hxx" #include "tabvwsh.hxx" #include "transobj.hxx" #include "scmod.hxx" #include "cellsuno.hxx" -#include <comphelper/processfactory.hxx> -#include <com/sun/star/sheet/XSheetCellRange.hpp> + +namespace ooo { +namespace vba { +namespace excel { using namespace ::com::sun::star; using namespace ::ooo::vba; -namespace ooo -{ -namespace vba -{ -namespace excel -{ +// ============================================================================ ScDocShell* GetDocShellFromRange( const uno::Reference< uno::XInterface >& xRange ) throw ( uno::RuntimeException ) { @@ -150,7 +151,14 @@ implnCopy( const uno::Reference< frame::XModel>& xModel ) { ScTabViewShell* pViewShell = getBestViewShell( xModel ); if ( pViewShell ) + { pViewShell->CopyToClip(NULL,false,false,true); + + // mark the copied transfer object so it is used in ScVbaRange::Insert + ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard( NULL ); + if (pClipObj) + pClipObj->SetUseInApi( true ); + } } void @@ -158,7 +166,14 @@ implnCut( const uno::Reference< frame::XModel>& xModel ) { ScTabViewShell* pViewShell = getBestViewShell( xModel ); if ( pViewShell ) + { pViewShell->CutToClip( NULL, TRUE ); + + // mark the copied transfer object so it is used in ScVbaRange::Insert + ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard( NULL ); + if (pClipObj) + pClipObj->SetUseInApi( true ); + } } void implnPasteSpecial( const uno::Reference< frame::XModel>& xModel, USHORT nFlags,USHORT nFunction,sal_Bool bSkipEmpty, sal_Bool bTranspose) @@ -181,7 +196,10 @@ void implnPasteSpecial( const uno::Reference< frame::XModel>& xModel, USHORT nFl ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin ); ScDocument* pDoc = NULL; if ( pOwnClip ) + { pDoc = pOwnClip->GetDocument(); + pOwnClip->SetUseInApi( false ); // don't use in Insert after it was pasted once + } pTabViewShell->PasteFromClip( nFlags, pDoc, nFunction, bSkipEmpty, bTranspose, bAsLink, eMoveMode, IDF_NONE, TRUE ); @@ -229,11 +247,10 @@ getViewFrame( const uno::Reference< frame::XModel >& xModel ) return NULL; } -uno::Reference< XHelperInterface > -getUnoSheetModuleObj( const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException ) +uno::Reference< vba::XHelperInterface > +getUnoSheetModuleObj( const uno::Reference< sheet::XSpreadsheet >& xSheet ) throw ( uno::RuntimeException ) { - uno::Reference< sheet::XSheetCellRange > xSheetRange( xRange, uno::UNO_QUERY_THROW ); - uno::Reference< beans::XPropertySet > xProps( xSheetRange->getSpreadsheet(), uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xProps( xSheet, uno::UNO_QUERY_THROW ); rtl::OUString sCodeName; xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CodeName") ) ) >>= sCodeName; // #TODO #FIXME ideally we should 'throw' here if we don't get a valid parent, but... it is possible @@ -241,28 +258,52 @@ getUnoSheetModuleObj( const uno::Reference< table::XCellRange >& xRange ) throw // are *NO* special document module objects ( of course being able to switch between vba/non vba mode at // the document in the future could fix this, especially IF the switching of the vba mode takes care to // create the special document module objects if they don't exist. - uno::Reference< XHelperInterface > xParent( ov::getUnoDocModule( sCodeName, GetDocShellFromRange( xRange ) ), uno::UNO_QUERY ); - + uno::Reference< XHelperInterface > xParent( ov::getUnoDocModule( sCodeName, GetDocShellFromRange( xSheet ) ), uno::UNO_QUERY ); return xParent; } uno::Reference< XHelperInterface > +getUnoSheetModuleObj( const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException ) +{ + uno::Reference< sheet::XSheetCellRange > xSheetRange( xRange, uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSpreadsheet > xSheet( xSheetRange->getSpreadsheet(), uno::UNO_SET_THROW ); + return getUnoSheetModuleObj( xSheet ); +} + +uno::Reference< XHelperInterface > getUnoSheetModuleObj( const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges ) throw ( uno::RuntimeException ) { uno::Reference< container::XEnumerationAccess > xEnumAccess( xRanges, uno::UNO_QUERY_THROW ); uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration(); uno::Reference< table::XCellRange > xRange( xEnum->nextElement(), uno::UNO_QUERY_THROW ); - return getUnoSheetModuleObj( xRange ); } +uno::Reference< XHelperInterface > +getUnoSheetModuleObj( const uno::Reference< table::XCell >& xCell ) throw ( uno::RuntimeException ) +{ + uno::Reference< sheet::XSheetCellRange > xSheetRange( xCell, uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSpreadsheet > xSheet( xSheetRange->getSpreadsheet(), uno::UNO_SET_THROW ); + return getUnoSheetModuleObj( xSheet ); +} + +uno::Reference< XHelperInterface > +getUnoSheetModuleObj( const uno::Reference< frame::XModel >& xModel, SCTAB nTab ) throw ( uno::RuntimeException ) +{ + uno::Reference< sheet::XSpreadsheetDocument > xDoc( xModel, uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xSheets( xDoc->getSheets(), uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSpreadsheet > xSheet( xSheets->getByIndex( nTab ), uno::UNO_QUERY_THROW ); + return getUnoSheetModuleObj( xSheet ); +} + SfxItemSet* ScVbaCellRangeAccess::GetDataSet( ScCellRangesBase* pRangeObj ) { return pRangeObj ? pRangeObj->GetCurrentDataSet( true ) : 0; } +// ============================================================================ -} //excel -} //vba -} //ooo +} // namespace excel +} // namespace vba +} // namespace ooo diff --git a/sc/source/ui/vba/excelvbahelper.hxx b/sc/source/ui/vba/excelvbahelper.hxx index da0474e6ceb0..be04fefa1639 100644 --- a/sc/source/ui/vba/excelvbahelper.hxx +++ b/sc/source/ui/vba/excelvbahelper.hxx @@ -27,41 +27,54 @@ #ifndef SC_EXCEL_VBA_HELPER_HXX #define SC_EXCEL_VBA_HELPER_HXX -#include<vbahelper/vbahelper.hxx> -#include <docsh.hxx> +#include <vbahelper/vbahelper.hxx> +#include "docsh.hxx" #include <com/sun/star/table/XCellRange.hpp> #include <com/sun/star/sheet/XSheetCellRangeContainer.hpp> +#include <com/sun/star/sheet/XSpreadsheet.hpp> #include <ooo/vba/XHelperInterface.hpp> class ScCellRangesBase; -namespace ooo +namespace ooo { +namespace vba { +namespace excel { + +// ============================================================================ + +// nTabs empty means apply zoom to all sheets +void implSetZoom( const css::uno::Reference< css::frame::XModel >& xModel, sal_Int16 nZoom, std::vector< SCTAB >& nTabs ); +void implnCopy( const css::uno::Reference< css::frame::XModel>& xModel ); +void implnPaste ( const css::uno::Reference< css::frame::XModel>& xModel ); +void implnCut( const css::uno::Reference< css::frame::XModel>& xModel ); +void implnPasteSpecial( const css::uno::Reference< css::frame::XModel>& xModel, sal_uInt16 nFlags,sal_uInt16 nFunction,sal_Bool bSkipEmpty, sal_Bool bTranspose); +ScTabViewShell* getBestViewShell( const css::uno::Reference< css::frame::XModel>& xModel ) ; +ScDocShell* getDocShell( const css::uno::Reference< css::frame::XModel>& xModel ) ; +ScTabViewShell* getCurrentBestViewShell( const css::uno::Reference< css::uno::XComponentContext >& xContext ); +SfxViewFrame* getViewFrame( const css::uno::Reference< css::frame::XModel >& xModel ); + +css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::sheet::XSpreadsheet >& xSheet ) throw ( css::uno::RuntimeException ); +css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::sheet::XSheetCellRangeContainer >& xRanges ) throw ( css::uno::RuntimeException ); +css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::table::XCellRange >& xRange ) throw ( css::uno::RuntimeException ); +css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::table::XCell >& xCell ) throw ( css::uno::RuntimeException ); +css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::frame::XModel >& xModel, SCTAB nTab ) throw ( css::uno::RuntimeException ); + +ScDocShell* GetDocShellFromRange( const css::uno::Reference< css::uno::XInterface >& xRange ) throw ( css::uno::RuntimeException ); +ScDocument* GetDocumentFromRange( const css::uno::Reference< css::uno::XInterface >& xRange ) throw ( css::uno::RuntimeException ); +css::uno::Reference< css::frame::XModel > GetModelFromRange( const css::uno::Reference< css::uno::XInterface >& xRange ) throw ( css::uno::RuntimeException ); + +// ============================================================================ + +class ScVbaCellRangeAccess { - namespace vba - { - namespace excel - { - // nTabs empty means apply zoom to all sheets - void implSetZoom( const css::uno::Reference< css::frame::XModel >& xModel, sal_Int16 nZoom, std::vector< SCTAB >& nTabs ); - void implnCopy( const css::uno::Reference< css::frame::XModel>& xModel ); - void implnPaste ( const css::uno::Reference< css::frame::XModel>& xModel ); - void implnCut( const css::uno::Reference< css::frame::XModel>& xModel ); - void implnPasteSpecial( const css::uno::Reference< css::frame::XModel>& xModel, sal_uInt16 nFlags,sal_uInt16 nFunction,sal_Bool bSkipEmpty, sal_Bool bTranspose); - ScTabViewShell* getBestViewShell( const css::uno::Reference< css::frame::XModel>& xModel ) ; - ScDocShell* getDocShell( const css::uno::Reference< css::frame::XModel>& xModel ) ; - ScTabViewShell* getCurrentBestViewShell( const css::uno::Reference< css::uno::XComponentContext >& xContext ); - SfxViewFrame* getViewFrame( const css::uno::Reference< css::frame::XModel >& xModel ); - css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::sheet::XSheetCellRangeContainer >& xRanges ) throw ( css::uno::RuntimeException ); - css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::table::XCellRange >& xRange ) throw ( css::uno::RuntimeException ); - ScDocShell* GetDocShellFromRange( const css::uno::Reference< css::uno::XInterface >& xRange ) throw ( css::uno::RuntimeException ); - ScDocument* GetDocumentFromRange( const css::uno::Reference< css::uno::XInterface >& xRange ) throw ( css::uno::RuntimeException ); - css::uno::Reference< css::frame::XModel > GetModelFromRange( const css::uno::Reference< css::uno::XInterface >& xRange ) throw ( css::uno::RuntimeException ); - class ScVbaCellRangeAccess - { - public: - static SfxItemSet* GetDataSet( ScCellRangesBase* pRangeObj ); - }; -} -} -} +public: + static SfxItemSet* GetDataSet( ScCellRangesBase* pRangeObj ); +}; + +// ============================================================================ + +} // namespace excel +} // namespace vba +} // namespace ooo + #endif diff --git a/sc/source/ui/vba/makefile.mk b/sc/source/ui/vba/makefile.mk index 92bb3fd39db0..5842b90237ff 100644 --- a/sc/source/ui/vba/makefile.mk +++ b/sc/source/ui/vba/makefile.mk @@ -110,15 +110,3 @@ SLOFILES= \ .INCLUDE : target.mk -.IF "$(L10N_framework)"=="" - -ALLTAR : \ - $(MISC)$/$(TARGET).don \ - -$(SLOFILES) : $(MISC)$/$(TARGET).don - -$(MISC)$/$(TARGET).don : $(SOLARBINDIR)$/oovbaapi.rdb - +$(CPPUMAKER) -O$(INCCOM)$/$(TARGET) -BUCR $(SOLARBINDIR)$/oovbaapi.rdb -X$(SOLARBINDIR)$/types.rdb && echo > $@ - echo $@ - -.ENDIF diff --git a/sc/source/ui/vba/vbaapplication.cxx b/sc/source/ui/vba/vbaapplication.cxx index f3965393e919..30d4bd4d39a0 100644 --- a/sc/source/ui/vba/vbaapplication.cxx +++ b/sc/source/ui/vba/vbaapplication.cxx @@ -60,6 +60,7 @@ #include "sc.hrc" #include <osl/file.hxx> +#include <rtl/instance.hxx> #include <sfx2/request.hxx> #include <sfx2/objsh.hxx> @@ -108,11 +109,32 @@ public: ActiveWorkbook( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext) : ScVbaWorkbook( xParent, xContext ){} }; +// ============================================================================ + +/** Global application settings shared by all open workbooks. */ +struct ScVbaAppSettings +{ + sal_Int32 mnCalculation; + sal_Bool mbDisplayAlerts; + sal_Bool mbEnableEvents; + + explicit ScVbaAppSettings(); +}; + +ScVbaAppSettings::ScVbaAppSettings() : + mnCalculation( excel::XlCalculation::xlCalculationAutomatic ), + mbDisplayAlerts( sal_True ), + mbEnableEvents( sal_True ) +{ +} + +struct ScVbaStaticAppSettings : public ::rtl::Static< ScVbaAppSettings, ScVbaStaticAppSettings > {}; + +// ============================================================================ + ScVbaApplication::ScVbaApplication( const uno::Reference<uno::XComponentContext >& xContext ) : ScVbaApplication_BASE( xContext ), - m_xCalculation( excel::XlCalculation::xlCalculationAutomatic ), - m_bDisplayAlerts( sal_True ), - m_bEnableEvents( sal_True ) + mrAppSettings( ScVbaStaticAppSettings::get() ) { } @@ -120,6 +142,11 @@ ScVbaApplication::~ScVbaApplication() { } +/*static*/ bool ScVbaApplication::getDocumentEventsEnabled() +{ + return ScVbaStaticAppSettings::get().mbEnableEvents; +} + SfxObjectShell* ScVbaApplication::GetDocShell( const uno::Reference< frame::XModel >& xModel ) throw (uno::RuntimeException) { return static_cast< SfxObjectShell* >( excel::getDocShell( xModel ) ); @@ -396,8 +423,10 @@ ScVbaApplication::setStatusBar( const uno::Any& _statusbar ) throw (uno::Runtime if( _statusbar >>= sText ) { setDisplayStatusBar( sal_True ); - xStatusIndicator->start( sText, 100 ); - //xStatusIndicator->setText( sText ); + if ( sText.getLength() ) + xStatusIndicator->start( sText, 100 ); + else + xStatusIndicator->end(); // restore normal state for empty text } else if( _statusbar >>= bDefault ) { @@ -415,6 +444,7 @@ ScVbaApplication::setStatusBar( const uno::Any& _statusbar ) throw (uno::Runtime ::sal_Int32 SAL_CALL ScVbaApplication::getCalculation() throw (uno::RuntimeException) { + // TODO: in Excel, this is an application-wide setting uno::Reference<sheet::XCalculatable> xCalc(getCurrentDocument(), uno::UNO_QUERY_THROW); if(xCalc->isAutomaticCalculationEnabled()) return excel::XlCalculation::xlCalculationAutomatic; @@ -425,6 +455,7 @@ ScVbaApplication::getCalculation() throw (uno::RuntimeException) void SAL_CALL ScVbaApplication::setCalculation( ::sal_Int32 _calculation ) throw (uno::RuntimeException) { + // TODO: in Excel, this is an application-wide setting uno::Reference< sheet::XCalculatable > xCalc(getCurrentDocument(), uno::UNO_QUERY_THROW); switch(_calculation) { @@ -704,25 +735,25 @@ ScVbaApplication::getName() throw (uno::RuntimeException) void SAL_CALL ScVbaApplication::setDisplayAlerts(sal_Bool displayAlerts) throw (uno::RuntimeException) { - m_bDisplayAlerts = displayAlerts; + mrAppSettings.mbDisplayAlerts = displayAlerts; } sal_Bool SAL_CALL ScVbaApplication::getDisplayAlerts() throw (uno::RuntimeException) { - return m_bDisplayAlerts; + return mrAppSettings.mbDisplayAlerts; } void SAL_CALL ScVbaApplication::setEnableEvents(sal_Bool bEnable) throw (uno::RuntimeException) { - m_bEnableEvents = bEnable; + mrAppSettings.mbEnableEvents = bEnable; } sal_Bool SAL_CALL ScVbaApplication::getEnableEvents() throw (uno::RuntimeException) { - return m_bEnableEvents; + return mrAppSettings.mbEnableEvents; } void SAL_CALL diff --git a/sc/source/ui/vba/vbaapplication.hxx b/sc/source/ui/vba/vbaapplication.hxx index a7be5feb1d27..bb696c967a37 100644 --- a/sc/source/ui/vba/vbaapplication.hxx +++ b/sc/source/ui/vba/vbaapplication.hxx @@ -39,12 +39,13 @@ //typedef InheritedHelperInterfaceImpl1< ov::excel::XApplication > ScVbaApplication_BASE; typedef cppu::ImplInheritanceHelper1< VbaApplicationBase, ov::excel::XApplication > ScVbaApplication_BASE; +struct ScVbaAppSettings; + class ScVbaApplication : public ScVbaApplication_BASE { private: - sal_Int32 m_xCalculation; - sal_Bool m_bDisplayAlerts; - sal_Bool m_bEnableEvents; + // note: member variables moved to struct "ScVbaAppSettings", see cxx file, to be shared by all application instances + ScVbaAppSettings& mrAppSettings; rtl::OUString getOfficePath( const rtl::OUString& sPath ) throw ( css::uno::RuntimeException ); @@ -55,6 +56,9 @@ public: ScVbaApplication( const css::uno::Reference< css::uno::XComponentContext >& m_xContext ); virtual ~ScVbaApplication(); + /** Returns true, if VBA document events are enabled. */ + static bool getDocumentEventsEnabled(); + virtual SfxObjectShell* GetDocShell( const css::uno::Reference< css::frame::XModel >& xModel ) throw (css::uno::RuntimeException); // XExactName diff --git a/sc/source/ui/vba/vbaeventshelper.cxx b/sc/source/ui/vba/vbaeventshelper.cxx index 45667adf2f2c..6ea807a16eae 100755 --- a/sc/source/ui/vba/vbaeventshelper.cxx +++ b/sc/source/ui/vba/vbaeventshelper.cxx @@ -48,6 +48,7 @@ #include "cellsuno.hxx" #include "convuno.hxx" +#include "vbaapplication.hxx" using namespace ::com::sun::star; using namespace ::com::sun::star::script::vba::VBAEventId; @@ -55,6 +56,51 @@ using namespace ::ooo::vba; // ============================================================================ +namespace { + +/** Extracts a sheet index from the specified element of the passed sequence. + The element may be an integer, a Calc range or ranges object, or a VBA Range object. */ +SCTAB lclGetTabFromArgs( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) throw (lang::IllegalArgumentException) +{ + VbaEventsHelperBase::checkArgument( rArgs, nIndex ); + + // first try to extract a sheet index + SCTAB nTab = -1; + if( rArgs[ nIndex ] >>= nTab ) + return nTab; + + // try VBA Range object + uno::Reference< excel::XRange > xVbaRange = getXSomethingFromArgs< excel::XRange >( rArgs, nIndex ); + if( xVbaRange.is() ) + { + uno::Reference< XHelperInterface > xVbaHelper( xVbaRange, uno::UNO_QUERY_THROW ); + // TODO: in the future, the parent may be an excel::XChart (chart sheet) -> will there be a common base interface? + uno::Reference< excel::XWorksheet > xVbaSheet( xVbaHelper->getParent(), uno::UNO_QUERY_THROW ); + // VBA sheet index is 1-based + return static_cast< SCTAB >( xVbaSheet->getIndex() - 1 ); + } + + // try single UNO range object + uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable = getXSomethingFromArgs< sheet::XCellRangeAddressable >( rArgs, nIndex ); + if( xCellRangeAddressable.is() ) + return xCellRangeAddressable->getRangeAddress().Sheet; + + // at last, try UNO range list + uno::Reference< sheet::XSheetCellRangeContainer > xRanges = getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( rArgs, nIndex ); + if( xRanges.is() ) + { + uno::Sequence< table::CellRangeAddress > aRangeAddresses = xRanges->getRangeAddresses(); + if( aRangeAddresses.getLength() > 0 ) + return aRangeAddresses[ 0 ].Sheet; + } + + throw lang::IllegalArgumentException(); +} + +} // namespace + +// ============================================================================ + typedef ::cppu::WeakImplHelper4< awt::XWindowListener, util::XCloseListener, frame::XBorderResizeListener, util::XChangesListener > ScVbaEventsListener_BASE; @@ -90,7 +136,6 @@ private: uno::Reference< awt::XWindow > getContainerWindow(); bool isMouseReleased(); DECL_LINK( fireResizeMacro, void* ); - void processWindowResizeMacro(); private: ::osl::Mutex maMutex; @@ -287,7 +332,7 @@ void SAL_CALL ScVbaEventsListener::changesOccurred( const util::ChangesEvent& aE aChange.ReplacedElement >>= xRangeObj; if( xRangeObj.is() ) { - uno::Sequence< uno::Any > aArgs(1); + uno::Sequence< uno::Any > aArgs( 1 ); aArgs[0] <<= xRangeObj; mrVbaEvents.processVbaEvent( WORKSHEET_CHANGE, aArgs ); } @@ -362,19 +407,18 @@ bool ScVbaEventsListener::isMouseReleased() IMPL_LINK( ScVbaEventsListener, fireResizeMacro, void*, EMPTYARG ) { - if( !mbDisposed && isMouseReleased() ) - processWindowResizeMacro(); + if( !mbDisposed && isMouseReleased() ) try + { + mrVbaEvents.processVbaEvent( WORKBOOK_WINDOWRESIZE, uno::Sequence< uno::Any >() ); + } + catch( uno::Exception& ) + { + // #163419# do not throw exceptions into application core + } release(); return 0; } -void ScVbaEventsListener::processWindowResizeMacro() -{ - OSL_TRACE( "**** Attempt to FIRE MACRO **** " ); - if( !mbDisposed ) - mrVbaEvents.processVbaEvent( WORKBOOK_WINDOWRESIZE, uno::Sequence< uno::Any >() ); -} - // ============================================================================ ScVbaEventsHelper::ScVbaEventsHelper( const uno::Sequence< uno::Any >& rArgs, const uno::Reference< uno::XComponentContext >& xContext ) : @@ -441,43 +485,19 @@ void SAL_CALL ScVbaEventsHelper::disposing( const lang::EventObject& rSource ) t // protected ------------------------------------------------------------------ -bool ScVbaEventsHelper::implEventsEnabled() throw (uno::RuntimeException) +bool ScVbaEventsHelper::implPrepareEvent( EventQueue& rEventQueue, + const EventHandlerInfo& rInfo, const uno::Sequence< uno::Any >& rArgs ) throw (uno::RuntimeException) { // document and document shell are needed during event processing - if( !mpDocShell || !mpDoc ) + if( !mpShell || !mpDoc ) throw uno::RuntimeException(); - // get Application object and check if events are enabled (this is an Excel-only attribute) - uno::Reference< excel::XApplication > xApplication( mxApplication.get(), uno::UNO_QUERY ); - if( !xApplication.is() && mpShell ) - { - uno::Any aVBAGlobals; - mpShell->GetBasicManager()->GetGlobalUNOConstant( "VBAGlobals", aVBAGlobals ); - uno::Reference< XHelperInterface > xHelperInterface( aVBAGlobals, uno::UNO_QUERY ); - if( xHelperInterface.is() ) - { - xApplication.set( xHelperInterface->Application(), uno::UNO_QUERY ); - mxApplication = xApplication; - } - } - if( !xApplication.is() ) - throw uno::RuntimeException(); + // framework and Calc fire a few events before 'opened', ignore them + bool bExecuteEvent = mbOpened; - // return whether event processing is enabled - return xApplication->getEnableEvents(); -} - -bool ScVbaEventsHelper::implPrepareEvent( EventQueue& rEventQueue, - const EventHandlerInfo& rInfo, const uno::Sequence< uno::Any >& rArgs ) throw (uno::RuntimeException) -{ - // check preconditions for some events, add more events if needed - bool bExecuteEvent = true; + // special handling for some events switch( rInfo.mnEventId ) { - case WORKBOOK_ACTIVATE: - // while loading, framework fires this before 'opened' event, delay it - bExecuteEvent = mbOpened; - break; case WORKBOOK_OPEN: bExecuteEvent = !mbOpened; if( bExecuteEvent ) @@ -490,15 +510,25 @@ bool ScVbaEventsHelper::implPrepareEvent( EventQueue& rEventQueue, break; case WORKSHEET_SELECTIONCHANGE: // if selection is not changed, then do not fire the event - bExecuteEvent = mbOpened && isSelectionChanged( rArgs, 0 ); + bExecuteEvent = bExecuteEvent && isSelectionChanged( rArgs, 0 ); break; } - // add workbook event associated to a sheet event - bool bSheetEvent = false; - rInfo.maUserData >>= bSheetEvent; - if( bSheetEvent && bExecuteEvent ) - rEventQueue.push_back( EventQueueEntry( rInfo.mnEventId + USERDEFINED_START, rArgs ) ); + if( bExecuteEvent ) + { + // add workbook event associated to a sheet event + bool bSheetEvent = false; + if( (rInfo.maUserData >>= bSheetEvent) && bSheetEvent ) + rEventQueue.push_back( EventQueueEntry( rInfo.mnEventId + USERDEFINED_START, rArgs ) ); + + /* For document events: check if events are enabled via the + Application.EnableEvents symbol (this is an Excel-only attribute). + Check this again for every event, as the event handler may change + the state of the EnableEvents symbol. Global events such as + AUTO_OPEN and AUTO_CLOSE are always enabled. */ + if( rInfo.meType == EVENTHANDLER_DOCUMENT ) + bExecuteEvent = ScVbaApplication::getDocumentEventsEnabled(); + } return bExecuteEvent; } @@ -622,7 +652,7 @@ void ScVbaEventsHelper::implPostProcessEvent( EventQueue& rEventQueue, { bool bSheetEvent = false; rInfo.maUserData >>= bSheetEvent; - SCTAB nTab = bSheetEvent ? getTabFromArgs( rArgs, 0 ) : -1; + SCTAB nTab = bSheetEvent ? lclGetTabFromArgs( rArgs, 0 ) : -1; if( bSheetEvent && (nTab < 0) ) throw lang::IllegalArgumentException(); @@ -636,95 +666,82 @@ void ScVbaEventsHelper::implPostProcessEvent( EventQueue& rEventQueue, // private -------------------------------------------------------------------- -SCTAB ScVbaEventsHelper::getTabFromArgs( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) throw (lang::IllegalArgumentException) -{ - checkArgument( rArgs, nIndex ); +namespace { - // first try to extract a sheet index - SCTAB nTab = -1; - if( rArgs[ nIndex ] >>= nTab ) - return nTab; +/** Compares the passed range lists representing sheet selections. Ignores + selections that refer to different sheets (returns false in this case). */ +bool lclSelectionChanged( const ScRangeList& rLeft, const ScRangeList& rRight ) +{ + // one of the range lists empty? -> return false, if both lists empty + bool bLeftEmpty = rLeft.Count() == 0; + bool bRightEmpty = rRight.Count() == 0; + if( bLeftEmpty || bRightEmpty ) + return !(bLeftEmpty && bRightEmpty); - // next, try single range object - uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable = getXSomethingFromArgs< sheet::XCellRangeAddressable >( rArgs, nIndex ); - if( xCellRangeAddressable.is() ) - return xCellRangeAddressable->getRangeAddress().Sheet; + // check sheet indexes of the range lists (assuming that all ranges in a list are on the same sheet) + if( rLeft.GetObject( 0 )->aStart.Tab() != rRight.GetObject( 0 )->aStart.Tab() ) + return false; - // at last, try range list - uno::Reference< sheet::XSheetCellRangeContainer > xRanges = getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( rArgs, nIndex ); - if( xRanges.is() ) - { - uno::Sequence< table::CellRangeAddress > aRangeAddresses = xRanges->getRangeAddresses(); - if( aRangeAddresses.getLength() > 0 ) - return aRangeAddresses[ 0 ].Sheet; - } - - throw lang::IllegalArgumentException(); + // compare all ranges + return rLeft != rRight; } +} // namespace + bool ScVbaEventsHelper::isSelectionChanged( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) throw (lang::IllegalArgumentException, uno::RuntimeException) { + uno::Reference< uno::XInterface > xOldSelection( maOldSelection, uno::UNO_QUERY ); uno::Reference< uno::XInterface > xNewSelection = getXSomethingFromArgs< uno::XInterface >( rArgs, nIndex, false ); - if( ScCellRangesBase* pNewCellRanges = ScCellRangesBase::getImplementation( xNewSelection ) ) - { - bool bChanged = maOldSelection != pNewCellRanges->GetRangeList(); - maOldSelection = pNewCellRanges->GetRangeList(); - return bChanged; - } - maOldSelection.Clear(); - return true; + ScCellRangesBase* pOldCellRanges = ScCellRangesBase::getImplementation( xOldSelection ); + ScCellRangesBase* pNewCellRanges = ScCellRangesBase::getImplementation( xNewSelection ); + bool bChanged = !pOldCellRanges || !pNewCellRanges || lclSelectionChanged( pOldCellRanges->GetRangeList(), pNewCellRanges->GetRangeList() ); + maOldSelection <<= xNewSelection; + return bChanged; } uno::Any ScVbaEventsHelper::createWorksheet( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const throw (lang::IllegalArgumentException, uno::RuntimeException) { - // Eventually we will be able to pull the Workbook/Worksheet objects - // directly from basic and register them as listeners - // extract sheet index, will throw, if parameter is invalid - SCTAB nTab = getTabFromArgs( rArgs, nIndex ); - - // create Workbook - uno::Sequence< uno::Any > aArgs( 2 ); - aArgs[ 0 ] <<= uno::Reference< uno::XInterface >(); - aArgs[ 1 ] <<= mxModel; - uno::Reference< uno::XInterface > xWorkbook( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Workbook", aArgs ), uno::UNO_SET_THROW ); - - // create WorkSheet - String aSheetName; - mpDoc->GetName( nTab, aSheetName ); - aArgs = uno::Sequence< uno::Any >( 3 ); - aArgs[ 0 ] <<= xWorkbook; - aArgs[ 1 ] <<= mxModel; - aArgs[ 2 ] <<= ::rtl::OUString( aSheetName ); - uno::Reference< uno::XInterface > xWorksheet( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Worksheet", aArgs ), uno::UNO_SET_THROW ); - return uno::Any( xWorksheet ); + SCTAB nTab = lclGetTabFromArgs( rArgs, nIndex ); + return uno::Any( excel::getUnoSheetModuleObj( mxModel, nTab ) ); } uno::Any ScVbaEventsHelper::createRange( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const throw (lang::IllegalArgumentException, uno::RuntimeException) { - uno::Reference< sheet::XSheetCellRangeContainer > xRanges = getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( rArgs, nIndex ); - uno::Reference< table::XCellRange > xRange = getXSomethingFromArgs< table::XCellRange >( rArgs, nIndex ); - if ( !xRanges.is() && !xRange.is() ) - throw lang::IllegalArgumentException(); + // it is possible to pass an existing VBA Range object + uno::Reference< excel::XRange > xVbaRange = getXSomethingFromArgs< excel::XRange >( rArgs, nIndex ); + if( !xVbaRange.is() ) + { + uno::Reference< sheet::XSheetCellRangeContainer > xRanges = getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( rArgs, nIndex ); + uno::Reference< table::XCellRange > xRange = getXSomethingFromArgs< table::XCellRange >( rArgs, nIndex ); + if ( !xRanges.is() && !xRange.is() ) + throw lang::IllegalArgumentException(); - uno::Sequence< uno::Any > aArgs( 2 ); - aArgs[ 0 ] <<= uno::Reference< uno::XInterface >(); // dummy parent - if ( xRanges.is() ) - aArgs[ 1 ] <<= xRanges; - else - aArgs[ 1 ] <<= xRange; - uno::Reference< uno::XInterface > xVbaRange( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Range", aArgs ), uno::UNO_SET_THROW ); + uno::Sequence< uno::Any > aArgs( 2 ); + if ( xRanges.is() ) + { + aArgs[ 0 ] <<= excel::getUnoSheetModuleObj( xRanges ); + aArgs[ 1 ] <<= xRanges; + } + else + { + aArgs[ 0 ] <<= excel::getUnoSheetModuleObj( xRange ); + aArgs[ 1 ] <<= xRange; + } + xVbaRange.set( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Range", aArgs ), uno::UNO_QUERY_THROW ); + } return uno::Any( xVbaRange ); } uno::Any ScVbaEventsHelper::createHyperlink( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const throw (lang::IllegalArgumentException, uno::RuntimeException) { + uno::Reference< table::XCell > xCell = getXSomethingFromArgs< table::XCell >( rArgs, nIndex, false ); uno::Sequence< uno::Any > aArgs( 2 ); - aArgs[ 0 ] <<= uno::Reference< uno::XInterface >(); // dummy parent - aArgs[ 1 ] <<= getXSomethingFromArgs< table::XCell >( rArgs, nIndex, false ); + aArgs[ 0 ] <<= excel::getUnoSheetModuleObj( xCell ); + aArgs[ 1 ] <<= xCell; uno::Reference< uno::XInterface > xHyperlink( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Hyperlink", aArgs ), uno::UNO_SET_THROW ); return uno::Any( xHyperlink ); } diff --git a/sc/source/ui/vba/vbaeventshelper.hxx b/sc/source/ui/vba/vbaeventshelper.hxx index a77f5128b3e9..f1e8a4fb712d 100755 --- a/sc/source/ui/vba/vbaeventshelper.hxx +++ b/sc/source/ui/vba/vbaeventshelper.hxx @@ -33,8 +33,6 @@ #include "excelvbahelper.hxx" #include "rangelst.hxx" -namespace ooo { namespace vba { namespace excel { class XApplication; } } } - class ScVbaEventsListener; // ============================================================================ @@ -51,16 +49,12 @@ public: virtual void SAL_CALL disposing( const css::lang::EventObject& rSource ) throw (css::uno::RuntimeException); protected: - virtual bool implEventsEnabled() throw (css::uno::RuntimeException); virtual bool implPrepareEvent( EventQueue& rEventQueue, const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::uno::RuntimeException); virtual css::uno::Sequence< css::uno::Any > implBuildArgumentList( const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::lang::IllegalArgumentException); virtual void implPostProcessEvent( EventQueue& rEventQueue, const EventHandlerInfo& rInfo, bool bSuccess, bool bCancel ) throw (css::uno::RuntimeException); virtual ::rtl::OUString implGetDocumentModuleName( const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) const throw (css::lang::IllegalArgumentException); private: - /** Extracts a sheet index from the first element of the passed sequence. The - element may be an integer, or a Calc range or ranges object. */ - static SCTAB getTabFromArgs( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) throw (css::lang::IllegalArgumentException); /** Checks if selection has been changed compared to selection of last call. @return true, if the selection has been changed. */ bool isSelectionChanged( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); @@ -75,11 +69,10 @@ private: css::uno::Any createWindow() const throw (css::uno::RuntimeException); private: - mutable css::uno::WeakReference< ov::excel::XApplication > mxApplication; ::rtl::Reference< ScVbaEventsListener > mxListener; + css::uno::Any maOldSelection; ScDocShell* mpDocShell; ScDocument* mpDoc; - ScRangeList maOldSelection; bool mbOpened; }; diff --git a/sc/source/ui/vba/vbanames.cxx b/sc/source/ui/vba/vbanames.cxx index 9fd22bf89f7a..1386bec7fa70 100644 --- a/sc/source/ui/vba/vbanames.cxx +++ b/sc/source/ui/vba/vbanames.cxx @@ -100,7 +100,6 @@ ScVbaNames::Add( const css::uno::Any& Name , const css::uno::Any& RefersToR1C1, const css::uno::Any& RefersToR1C1Local ) throw (css::uno::RuntimeException) { - rtl::OUString sName; uno::Reference< excel::XRange > xRange; if ( Name.hasValue() ) @@ -158,6 +157,8 @@ ScVbaNames::Add( const css::uno::Any& Name , if ( mxNames->hasByName( sName ) ) mxNames->removeByName(sName); mxNames->addNewByName( sName , rtl::OUString(sTmp) , aCellAddr , (sal_Int32)nType); + uno::Reference< sheet::XNamedRange > xName( mxNames->getByName( sName ), uno::UNO_QUERY_THROW ); + return uno::Any( uno::Reference< excel::XName >( new ScVbaName( getParent(), mxContext, xName, mxNames, mxModel ) ) ); } } return css::uno::Any(); @@ -174,7 +175,7 @@ uno::Reference< container::XEnumeration > ScVbaNames::createEnumeration() throw (uno::RuntimeException) { uno::Reference< container::XEnumerationAccess > xEnumAccess( mxNames, uno::UNO_QUERY_THROW ); - return new NamesEnumeration( this, mxContext, xEnumAccess->createEnumeration(), mxModel , mxNames ); + return new NamesEnumeration( getParent(), mxContext, xEnumAccess->createEnumeration(), mxModel , mxNames ); } uno::Any diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx index 455af075306c..6cd129a6ae2d 100755 --- a/sc/source/ui/vba/vbarange.cxx +++ b/sc/source/ui/vba/vbarange.cxx @@ -24,6 +24,9 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ + +#include "vbarange.hxx" + #include <vbahelper/helperdecl.hxx> #include <comphelper/unwrapargs.hxx> @@ -31,6 +34,8 @@ #include <sfx2/objsh.hxx> #include <com/sun/star/script/ArrayWrapper.hpp> +#include <com/sun/star/script/vba/VBAEventId.hpp> +#include <com/sun/star/script/vba/XVBAEventProcessor.hpp> #include <com/sun/star/sheet/XDatabaseRange.hpp> #include <com/sun/star/sheet/XDatabaseRanges.hpp> #include <com/sun/star/sheet/XGoalSeek.hpp> @@ -123,6 +128,7 @@ #include <cellsuno.hxx> #include <dbcolect.hxx> #include "docfunc.hxx" +#include "transobj.hxx" #include <sfx2/dispatch.hxx> #include <sfx2/app.hxx> @@ -134,7 +140,7 @@ #include <globstr.hrc> #include <unonames.hxx> -#include "vbarange.hxx" +#include "vbaapplication.hxx" #include "vbafont.hxx" #include "vbacomment.hxx" #include "vbainterior.hxx" @@ -172,6 +178,9 @@ using namespace ::ooo::vba; using namespace ::com::sun::star; using ::std::vector; +// difference between VBA and file format width, in character units +const double fExtraWidth = 182.0 / 256.0; + // * 1 point = 1/72 inch = 20 twips // * 1 inch = 72 points = 1440 twips // * 1 cm = 567 twips @@ -264,6 +273,26 @@ SfxItemSet* ScVbaRange::getCurrentDataSet( ) throw ( uno::RuntimeException ) return pDataSet; } +void ScVbaRange::fireChangeEvent() +{ + if( ScVbaApplication::getDocumentEventsEnabled() ) + { + if( ScDocument* pDoc = getScDocument() ) + { + uno::Reference< script::vba::XVBAEventProcessor > xVBAEvents = pDoc->GetVbaEventProcessor(); + if( xVBAEvents.is() ) try + { + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[ 0 ] <<= uno::Reference< excel::XRange >( this ); + xVBAEvents->processVbaEvent( script::vba::VBAEventId::WORKSHEET_CHANGE, aArgs ); + } + catch( uno::Exception& ) + { + } + } + } +} + class SingleRangeEnumeration : public EnumerationHelper_BASE { uno::Reference< XHelperInterface > m_xParent; @@ -539,19 +568,22 @@ public: { uno::Reference< beans::XPropertySet > xNumberProps = getNumberProps(); sal_Int16 nType = ::comphelper::getINT16( - xNumberProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Type" ) ) ); + xNumberProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ) ) ); return nType; } - bool setNumberFormat( const rtl::OUString& rFormat ) + bool setNumberFormat( const rtl::OUString& rFormat ) { - lang::Locale aLocale; - uno::Reference< beans::XPropertySet > xNumProps = getNumberProps(); - xNumProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Locale" ) ) >>= aLocale; - sal_Int32 nNewIndex = mxFormats->queryKey(rFormat, aLocale, false ); - if ( nNewIndex == -1 ) // format not defined + // #163288# treat "General" as "Standard" format + sal_Int32 nNewIndex = 0; + if( !rFormat.equalsIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "General" ) ) ) { - nNewIndex = mxFormats->addNew( rFormat, aLocale ); + lang::Locale aLocale; + uno::Reference< beans::XPropertySet > xNumProps = getNumberProps(); + xNumProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Locale" ) ) ) >>= aLocale; + nNewIndex = mxFormats->queryKey( rFormat, aLocale, false ); + if ( nNewIndex == -1 ) // format not defined + nNewIndex = mxFormats->addNew( rFormat, aLocale ); } mxRangeProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NumberFormat") ), uno::makeAny( nNewIndex ) ); return true; @@ -561,7 +593,7 @@ public: { uno::Reference< beans::XPropertySet > xNumberProps = getNumberProps(); lang::Locale aLocale; - xNumberProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Locale" ) ) >>= aLocale; + xNumberProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Locale" ) ) ) >>= aLocale; uno::Reference<util::XNumberFormatTypes> xTypes( mxFormats, uno::UNO_QUERY ); if ( xTypes.is() ) { @@ -733,8 +765,26 @@ CellValueSetter::processValue( const uno::Any& aValue, const uno::Reference< tab rtl::OUString aString; if ( aValue >>= aString ) { - uno::Reference< text::XTextRange > xTextRange( xCell, uno::UNO_QUERY_THROW ); - xTextRange->setString( aString ); + // The required behavior for a string value is: + // 1. If the first character is a single quote, use the rest as a string cell, regardless of the cell's number format. + // 2. Otherwise, if the cell's number format is "text", use the string value as a string cell. + // 3. Otherwise, parse the string value in English locale, and apply a corresponding number format with the cell's locale + // if the cell's number format was "General". + // Case 1 is handled here, the rest in ScCellObj::InputEnglishString + + if ( aString.toChar() == '\'' ) // case 1 - handle with XTextRange + { + rtl::OUString aRemainder( aString.copy(1) ); // strip the quote + uno::Reference< text::XTextRange > xTextRange( xCell, uno::UNO_QUERY_THROW ); + xTextRange->setString( aRemainder ); + } + else + { + // call implementation method InputEnglishString + ScCellObj* pCellObj = dynamic_cast< ScCellObj* >( xCell.get() ); + if ( pCellObj ) + pCellObj->InputEnglishString( aString ); + } } else isExtracted = false; @@ -1473,7 +1523,7 @@ ScVbaRange::getValue() throw (uno::RuntimeException) void -ScVbaRange::setValue( const uno::Any &aValue, ValueSetter& valueSetter ) throw (uno::RuntimeException) +ScVbaRange::setValue( const uno::Any& aValue, ValueSetter& valueSetter, bool bFireEvent ) throw (uno::RuntimeException) { uno::TypeClass aClass = aValue.getValueTypeClass(); if ( aClass == uno::TypeClass_SEQUENCE ) @@ -1508,6 +1558,7 @@ ScVbaRange::setValue( const uno::Any &aValue, ValueSetter& valueSetter ) thro { visitArray( valueSetter ); } + if( bFireEvent ) fireChangeEvent(); } void SAL_CALL @@ -1522,20 +1573,20 @@ ScVbaRange::setValue( const uno::Any &aValue ) throw (uno::RuntimeException) return; } CellValueSetter valueSetter( aValue ); - setValue( aValue, valueSetter ); + setValue( aValue, valueSetter, true ); } -void +void SAL_CALL ScVbaRange::Clear() throw (uno::RuntimeException) { using namespace ::com::sun::star::sheet::CellFlags; sal_Int32 nFlags = VALUE | DATETIME | STRING | FORMULA | HARDATTR | EDITATTR | FORMATTED; - ClearContents( nFlags ); + ClearContents( nFlags, true ); } //helper ClearContent void -ScVbaRange::ClearContents( sal_Int32 nFlags ) throw (uno::RuntimeException) +ScVbaRange::ClearContents( sal_Int32 nFlags, bool bFireEvent ) throw (uno::RuntimeException) { // #TODO code within the test below "if ( m_Areas.... " can be removed // Test is performed only because m_xRange is NOT set to be @@ -1549,40 +1600,44 @@ ScVbaRange::ClearContents( sal_Int32 nFlags ) throw (uno::RuntimeException) uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW ); ScVbaRange* pRange = getImplementation( xRange ); if ( pRange ) - pRange->ClearContents( nFlags ); + pRange->ClearContents( nFlags, false ); // do not fire for single ranges } + // fire change event for the entire range list + if( bFireEvent ) fireChangeEvent(); return; } uno::Reference< sheet::XSheetOperation > xSheetOperation(mxRange, uno::UNO_QUERY_THROW); xSheetOperation->clearContents( nFlags ); + if( bFireEvent ) fireChangeEvent(); } -void + +void SAL_CALL ScVbaRange::ClearComments() throw (uno::RuntimeException) { - ClearContents( sheet::CellFlags::ANNOTATION ); + ClearContents( sheet::CellFlags::ANNOTATION, false ); } -void +void SAL_CALL ScVbaRange::ClearContents() throw (uno::RuntimeException) { - sal_Int32 nClearFlags = ( sheet::CellFlags::VALUE | - sheet::CellFlags::STRING | sheet::CellFlags::DATETIME | - sheet::CellFlags::FORMULA ); - ClearContents( nClearFlags ); + using namespace ::com::sun::star::sheet::CellFlags; + sal_Int32 nFlags = VALUE | STRING | DATETIME | FORMULA; + ClearContents( nFlags, true ); } -void +void SAL_CALL ScVbaRange::ClearFormats() throw (uno::RuntimeException) { - //FIXME: need to check if we need to combine sheet::CellFlags::FORMATTED - sal_Int32 nClearFlags = sheet::CellFlags::HARDATTR | sheet::CellFlags::FORMATTED | sheet::CellFlags::EDITATTR; - ClearContents( nClearFlags ); + //FIXME: need to check if we need to combine FORMATTED + using namespace ::com::sun::star::sheet::CellFlags; + sal_Int32 nFlags = HARDATTR | FORMATTED | EDITATTR; + ClearContents( nFlags, false ); } void -ScVbaRange::setFormulaValue( const uno::Any& rFormula, formula::FormulaGrammar::Grammar eGram ) throw (uno::RuntimeException) +ScVbaRange::setFormulaValue( const uno::Any& rFormula, formula::FormulaGrammar::Grammar eGram, bool bFireEvent ) throw (uno::RuntimeException) { // If this is a multiple selection apply setFormula over all areas if ( m_Areas->getCount() > 1 ) @@ -1593,7 +1648,7 @@ ScVbaRange::setFormulaValue( const uno::Any& rFormula, formula::FormulaGrammar:: return; } CellFormulaValueSetter formulaValueSetter( rFormula, getScDocument(), eGram ); - setValue( rFormula, formulaValueSetter ); + setValue( rFormula, formulaValueSetter, bFireEvent ); } uno::Any @@ -1617,7 +1672,7 @@ void ScVbaRange::setFormula(const uno::Any &rFormula ) throw (uno::RuntimeException) { // #FIXME converting "=$a$1" e.g. CONV_XL_A1 -> CONV_OOO // results in "=$a$1:a1", temporalily disable conversion - setFormulaValue( rFormula,formula::FormulaGrammar::GRAM_NATIVE_XL_A1 );; + setFormulaValue( rFormula,formula::FormulaGrammar::GRAM_NATIVE_XL_A1, true ); } uno::Any @@ -1629,7 +1684,7 @@ ScVbaRange::getFormulaR1C1() throw (::com::sun::star::uno::RuntimeException) void ScVbaRange::setFormulaR1C1(const uno::Any& rFormula ) throw (uno::RuntimeException) { - setFormulaValue( rFormula,formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1 ); + setFormulaValue( rFormula,formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1, true ); } uno::Any @@ -2054,6 +2109,18 @@ ScVbaRange::Cells( const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) thr return xRange->Cells( nRowIndex, nColumnIndex ); } + // Performance: Use a common helper method for ScVbaRange::Cells and ScVbaWorksheet::Cells, + // instead of creating a new ScVbaRange object in often-called ScVbaWorksheet::Cells + return CellsHelper( mxParent, mxContext, mxRange, nRowIndex, nColumnIndex ); +} + +// static +uno::Reference< excel::XRange > +ScVbaRange::CellsHelper( const uno::Reference< ov::XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< css::table::XCellRange >& xRange, + const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) throw(uno::RuntimeException) +{ sal_Int32 nRow = 0, nColumn = 0; sal_Bool bIsIndex = nRowIndex.hasValue(); @@ -2065,7 +2132,7 @@ ScVbaRange::Cells( const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) thr // convertion routine e.g. bSuccess = getValueFromAny( nRow, nRowIndex, getCppuType((sal_Int32*)0) ) if ( nRowIndex.hasValue() && !( nRowIndex >>= nRow ) ) { - uno::Reference< script::XTypeConverter > xConverter = getTypeConverter( mxContext ); + uno::Reference< script::XTypeConverter > xConverter = getTypeConverter( xContext ); uno::Any aConverted; try { @@ -2076,7 +2143,7 @@ ScVbaRange::Cells( const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) thr } if ( bIsColumnIndex && !( nColumnIndex >>= nColumn ) ) { - uno::Reference< script::XTypeConverter > xConverter = getTypeConverter( mxContext ); + uno::Reference< script::XTypeConverter > xConverter = getTypeConverter( xContext ); uno::Any aConverted; try { @@ -2086,17 +2153,17 @@ ScVbaRange::Cells( const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) thr catch( uno::Exception& ) {} // silence any errors } - RangeHelper thisRange( mxRange ); + RangeHelper thisRange( xRange ); table::CellRangeAddress thisRangeAddress = thisRange.getCellRangeAddressable()->getRangeAddress(); uno::Reference< table::XCellRange > xSheetRange = thisRange.getCellRangeFromSheet(); if( !bIsIndex && !bIsColumnIndex ) // .Cells // #FIXE needs proper parent ( Worksheet ) - return uno::Reference< excel::XRange >( new ScVbaRange( mxParent, mxContext, mxRange ) ); + return uno::Reference< excel::XRange >( new ScVbaRange( xParent, xContext, xRange ) ); sal_Int32 nIndex = --nRow; if( bIsIndex && !bIsColumnIndex ) // .Cells(n) { - uno::Reference< table::XColumnRowRange > xColumnRowRange(mxRange, ::uno::UNO_QUERY_THROW); + uno::Reference< table::XColumnRowRange > xColumnRowRange(xRange, ::uno::UNO_QUERY_THROW); sal_Int32 nColCount = xColumnRowRange->getColumns()->getCount(); if ( !nIndex || nIndex < 0 ) @@ -2109,7 +2176,7 @@ ScVbaRange::Cells( const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) thr --nColumn; nRow = nRow + thisRangeAddress.StartRow; nColumn = nColumn + thisRangeAddress.StartColumn; - return new ScVbaRange( mxParent, mxContext, xSheetRange->getCellRangeByPosition( nColumn, nRow, nColumn, nRow ) ); + return new ScVbaRange( xParent, xContext, xSheetRange->getCellRangeByPosition( nColumn, nRow, nColumn, nRow ) ); } void @@ -3236,7 +3303,7 @@ ScVbaRange::Sort( const uno::Any& Key1, const uno::Any& Order1, const uno::Any& throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("That command cannot be used on multiple selections" ) ), uno::Reference< uno::XInterface >() ); sal_Int16 nDataOption1 = excel::XlSortDataOption::xlSortNormal; - sal_Int16 nDataOption2 = excel::XlSortDataOption::xlSortNormal;; + sal_Int16 nDataOption2 = excel::XlSortDataOption::xlSortNormal; sal_Int16 nDataOption3 = excel::XlSortDataOption::xlSortNormal; ScDocument* pDoc = getScDocument(); @@ -3611,15 +3678,6 @@ ScVbaRange::getDefaultMethodName( ) throw (uno::RuntimeException) } -uno::Reference< awt::XDevice > -getDeviceFromDoc( const uno::Reference< frame::XModel >& xModel ) throw( uno::RuntimeException ) -{ - uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_QUERY_THROW ); - uno::Reference< frame::XFrame> xFrame( xController->getFrame(), uno::UNO_QUERY_THROW ); - uno::Reference< awt::XDevice > xDevice( xFrame->getComponentWindow(), uno::UNO_QUERY_THROW ); - return xDevice; -} - // returns calc internal col. width ( in points ) double ScVbaRange::getCalcColWidth( const table::CellRangeAddress& rAddress) throw (uno::RuntimeException) @@ -3642,29 +3700,16 @@ ScVbaRange::getCalcRowHeight( const table::CellRangeAddress& rAddress ) throw (u } // return Char Width in points -double getDefaultCharWidth( const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) -{ - const static rtl::OUString sDflt( RTL_CONSTASCII_USTRINGPARAM("Default")); - const static rtl::OUString sCharFontName( RTL_CONSTASCII_USTRINGPARAM("CharFontName")); - const static rtl::OUString sPageStyles( RTL_CONSTASCII_USTRINGPARAM("PageStyles")); - // get the font from the default style - uno::Reference< style::XStyleFamiliesSupplier > xStyleSupplier( xModel, uno::UNO_QUERY_THROW ); - uno::Reference< container::XNameAccess > xNameAccess( xStyleSupplier->getStyleFamilies(), uno::UNO_QUERY_THROW ); - uno::Reference< container::XNameAccess > xNameAccess2( xNameAccess->getByName( sPageStyles ), uno::UNO_QUERY_THROW ); - uno::Reference< beans::XPropertySet > xProps( xNameAccess2->getByName( sDflt ), uno::UNO_QUERY_THROW ); - rtl::OUString sFontName; - xProps->getPropertyValue( sCharFontName ) >>= sFontName; - - uno::Reference< awt::XDevice > xDevice = getDeviceFromDoc( xModel ); - awt::FontDescriptor aDesc; - aDesc.Name = sFontName; - uno::Reference< awt::XFont > xFont( xDevice->getFont( aDesc ), uno::UNO_QUERY_THROW ); - double nCharPixelWidth = xFont->getCharWidth( (sal_Int8)'0' ); - - double nPixelsPerMeter = xDevice->getInfo().PixelPerMeterX; - double nCharWidth = nCharPixelWidth / nPixelsPerMeter; - nCharWidth = nCharWidth * (double)56700;// in twips - return lcl_TwipsToPoints( (USHORT)nCharWidth ); +double getDefaultCharWidth( ScDocShell* pDocShell ) +{ + ScDocument* pDoc = pDocShell->GetDocument(); + OutputDevice* pRefDevice = pDoc->GetRefDevice(); + ScPatternAttr* pAttr = pDoc->GetDefPattern(); + ::Font aDefFont; + pAttr->GetFont( aDefFont, SC_AUTOCOL_BLACK, pRefDevice ); + pRefDevice->SetFont( aDefFont ); + long nCharWidth = pRefDevice->GetTextWidth( String( '0' ) ); // 1/100th mm + return lcl_hmmToPoints( nCharWidth ); } uno::Any SAL_CALL @@ -3682,7 +3727,7 @@ ScVbaRange::getColumnWidth() throw (uno::RuntimeException) if ( pShell ) { uno::Reference< frame::XModel > xModel = pShell->GetModel(); - double defaultCharWidth = getDefaultCharWidth( xModel ); + double defaultCharWidth = getDefaultCharWidth( pShell ); RangeHelper thisRange( mxRange ); table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress(); sal_Int32 nStartCol = thisAddress.StartColumn; @@ -3697,9 +3742,9 @@ ScVbaRange::getColumnWidth() throw (uno::RuntimeException) if ( nColTwips != nCurTwips ) return aNULL(); } - nColWidth = lcl_Round2DecPlaces( lcl_TwipsToPoints( nColTwips ) ); - if ( xModel.is() ) - nColWidth = nColWidth / defaultCharWidth; + nColWidth = lcl_TwipsToPoints( nColTwips ); + if ( nColWidth != 0.0 ) + nColWidth = ( nColWidth / defaultCharWidth ) - fExtraWidth; } nColWidth = lcl_Round2DecPlaces( nColWidth ); return uno::makeAny( nColWidth ); @@ -3724,11 +3769,8 @@ ScVbaRange::setColumnWidth( const uno::Any& _columnwidth ) throw (uno::RuntimeEx ScDocShell* pDocShell = getScDocShell(); if ( pDocShell ) { - uno::Reference< frame::XModel > xModel = pDocShell->GetModel(); - if ( xModel.is() ) - { - - nColWidth = ( nColWidth * getDefaultCharWidth( xModel ) ); + if ( nColWidth != 0.0 ) + nColWidth = ( nColWidth + fExtraWidth ) * getDefaultCharWidth( pDocShell ); RangeHelper thisRange( mxRange ); table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress(); USHORT nTwips = lcl_pointsToTwips( nColWidth ); @@ -3737,11 +3779,11 @@ ScVbaRange::setColumnWidth( const uno::Any& _columnwidth ) throw (uno::RuntimeEx SCCOLROW nColArr[2]; nColArr[0] = thisAddress.StartColumn; nColArr[1] = thisAddress.EndColumn; - aFunc.SetWidthOrHeight( TRUE, 1, nColArr, thisAddress.Sheet, SC_SIZE_ORIGINAL, + // #163561# use mode SC_SIZE_DIRECT: hide for width 0, show for other values + aFunc.SetWidthOrHeight( TRUE, 1, nColArr, thisAddress.Sheet, SC_SIZE_DIRECT, nTwips, TRUE, TRUE ); } - } } uno::Any SAL_CALL @@ -3901,7 +3943,8 @@ ScVbaRange::setRowHeight( const uno::Any& _rowheight) throw (uno::RuntimeExcepti SCCOLROW nRowArr[2]; nRowArr[0] = thisAddress.StartRow; nRowArr[1] = thisAddress.EndRow; - aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, thisAddress.Sheet, SC_SIZE_ORIGINAL, + // #163561# use mode SC_SIZE_DIRECT: hide for height 0, show for other values + aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, thisAddress.Sheet, SC_SIZE_DIRECT, nTwips, TRUE, TRUE ); } @@ -4350,6 +4393,20 @@ ScVbaRange::AutoFilter( const uno::Any& Field, const uno::Any& Criteria1, const { RangeHelper multiCellRange( mxRange ); autoFiltAddress = multiCellRange.getCellRangeAddressable()->getRangeAddress(); + // #163530# Filter box shows only entry of first row + ScDocument* pDocument = ( pShell ? pShell->GetDocument() : NULL ); + if ( pDocument ) + { + SCCOL nStartCol = autoFiltAddress.StartColumn; + SCROW nStartRow = autoFiltAddress.StartRow; + SCCOL nEndCol = autoFiltAddress.EndColumn; + SCROW nEndRow = autoFiltAddress.EndRow; + pDocument->GetDataArea( autoFiltAddress.Sheet, nStartCol, nStartRow, nEndCol, nEndRow, TRUE, true ); + autoFiltAddress.StartColumn = nStartCol; + autoFiltAddress.StartRow = nStartRow; + autoFiltAddress.EndColumn = nEndCol; + autoFiltAddress.EndRow = nEndRow; + } } uno::Reference< sheet::XDatabaseRanges > xDBRanges = lcl_GetDataBaseRanges( pShell ); @@ -4369,13 +4426,9 @@ ScVbaRange::AutoFilter( const uno::Any& Field, const uno::Any& Criteria1, const uno::Reference< beans::XPropertySet > xDBRangeProps( xDataBaseRange, uno::UNO_QUERY_THROW ); // set autofilt xDBRangeProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("AutoFilter") ), uno::Any(sal_True) ); - // set header + // set header (autofilter always need column headers) uno::Reference< beans::XPropertySet > xFiltProps( xDataBaseRange->getFilterDescriptor(), uno::UNO_QUERY_THROW ); - sal_Bool bHasColHeader = sal_False; - ScDocument* pDoc = pShell ? pShell->GetDocument() : NULL; - - bHasColHeader = pDoc->HasColHeader( static_cast< SCCOL >( autoFiltAddress.StartColumn ), static_cast< SCROW >( autoFiltAddress.StartRow ), static_cast< SCCOL >( autoFiltAddress.EndColumn ), static_cast< SCROW >( autoFiltAddress.EndRow ), static_cast< SCTAB >( autoFiltAddress.Sheet ) ) ? sal_True : sal_False; - xFiltProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ContainsHeader") ), uno::Any( bHasColHeader ) ); + xFiltProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ContainsHeader") ), uno::Any( sal_True ) ); } @@ -4405,7 +4458,7 @@ ScVbaRange::AutoFilter( const uno::Any& Field, const uno::Any& Criteria1, const // Use the normal uno api, sometimes e.g. when you want to use ALL as the filter // we can't use refresh as the uno interface doesn't have a concept of ALL // in this case we just call the core calc functionality - - bool bAll = false;; + bool bAll = false; if ( ( Field >>= nField ) ) { uno::Reference< sheet::XSheetFilterDescriptor2 > xDesc( @@ -4543,10 +4596,8 @@ ScVbaRange::AutoFilter( const uno::Any& Field, const uno::Any& Criteria1, const } void SAL_CALL -ScVbaRange::Insert( const uno::Any& Shift, const uno::Any& CopyOrigin ) throw (uno::RuntimeException) +ScVbaRange::Insert( const uno::Any& Shift, const uno::Any& /* CopyOrigin */ ) throw (uno::RuntimeException) { - sal_Bool bCopyOrigin = sal_True; - CopyOrigin >>= bCopyOrigin; // It appears ( from the web ) that the undocumented CopyOrigin // param should contain member of enum XlInsertFormatOrigin // which can have values xlFormatFromLeftOrAbove or xlFormatFromRightOrBelow @@ -4581,7 +4632,11 @@ ScVbaRange::Insert( const uno::Any& Shift, const uno::Any& CopyOrigin ) throw (u table::CellRangeAddress thisAddress = thisRange.getCellRangeAddressable()->getRangeAddress(); uno::Reference< sheet::XCellRangeMovement > xCellRangeMove( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW ); xCellRangeMove->insertCells( thisAddress, mode ); - if ( bCopyOrigin ) + + // Paste from clipboard only if the clipboard content was copied via VBA, and not already pasted via VBA again. + // "Insert" behavior should not depend on random clipboard content previously copied by the user. + ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard( NULL ); + if ( pClipObj && pClipObj->GetUseInApi() ) { // After the insert ( this range ) actually has moved ScRange aRange( static_cast< SCCOL >( thisAddress.StartColumn ), static_cast< SCROW >( thisAddress.StartRow ), static_cast< SCTAB >( thisAddress.Sheet ), static_cast< SCCOL >( thisAddress.EndColumn ), static_cast< SCROW >( thisAddress.EndRow ), static_cast< SCTAB >( thisAddress.Sheet ) ); diff --git a/sc/source/ui/vba/vbarange.hxx b/sc/source/ui/vba/vbarange.hxx index e7488e434f30..e8079a855544 100644 --- a/sc/source/ui/vba/vbarange.hxx +++ b/sc/source/ui/vba/vbarange.hxx @@ -99,6 +99,7 @@ class ScVbaRange : public ScVbaRange_BASE sal_Bool mbIsRows; sal_Bool mbIsColumns; css::uno::Reference< ov::excel::XValidation > m_xValidation; + double getCalcColWidth( const css::table::CellRangeAddress& ) throw (css::uno::RuntimeException); double getCalcRowHeight( const css::table::CellRangeAddress& ) throw (css::uno::RuntimeException); void visitArray( ArrayVisitor& vistor ); @@ -107,11 +108,14 @@ class ScVbaRange : public ScVbaRange_BASE void fillSeries( css::sheet::FillDirection nFillDirection, css::sheet::FillMode nFillMode, css::sheet::FillDateMode nFillDateMode, double fStep, double fEndValue ) throw( css::uno::RuntimeException ); - void ClearContents( sal_Int32 nFlags ) throw (css::uno::RuntimeException); - virtual void setValue( const css::uno::Any& aValue, ValueSetter& setter) throw ( css::uno::RuntimeException); - virtual css::uno::Any getValue( ValueGetter& rValueGetter ) throw (css::uno::RuntimeException); - virtual css::uno::Any getFormulaValue( formula::FormulaGrammar::Grammar ) throw (css::uno::RuntimeException); - virtual void setFormulaValue( const css::uno::Any& aValue, formula::FormulaGrammar::Grammar ) throw ( css::uno::RuntimeException); + void ClearContents( sal_Int32 nFlags, bool bFireEvent ) throw (css::uno::RuntimeException); + + css::uno::Any getValue( ValueGetter& rValueGetter ) throw (css::uno::RuntimeException); + void setValue( const css::uno::Any& aValue, ValueSetter& setter, bool bFireEvent ) throw ( css::uno::RuntimeException); + + css::uno::Any getFormulaValue( formula::FormulaGrammar::Grammar ) throw (css::uno::RuntimeException); + void setFormulaValue( const css::uno::Any& aValue, formula::FormulaGrammar::Grammar, bool bFireEvent ) throw ( css::uno::RuntimeException); + css::uno::Reference< ov::excel::XRange > getArea( sal_Int32 nIndex ) throw( css::uno::RuntimeException ); ScCellRangeObj* getCellRangeObj( ) throw ( css::uno::RuntimeException ); ScCellRangesObj* getCellRangesObj() throw ( css::uno::RuntimeException ); @@ -120,6 +124,10 @@ class ScVbaRange : public ScVbaRange_BASE css::uno::Reference< ov::excel::XRange > PreviousNext( bool bIsPrevious ); css::uno::Reference< ov::excel::XRange > SpecialCellsImpl( sal_Int32 nType, const css::uno::Any& _oValue) throw ( css::script::BasicErrorException ); css::awt::Point getPosition() throw ( css::uno::RuntimeException ); + + /** Fires a Worksheet_Change event for this range or range list. */ + void fireChangeEvent(); + protected: virtual ScCellRangesBase* getCellRangesBase() throw ( css::uno::RuntimeException ); virtual SfxItemSet* getCurrentDataSet( ) throw ( css::uno::RuntimeException ); @@ -149,6 +157,12 @@ public: const rtl::OUString& sRangeName, ScDocShell* pDocSh, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( css::uno::RuntimeException ); + static css::uno::Reference< ov::excel::XRange > CellsHelper( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::table::XCellRange >& xRange, + const css::uno::Any &nRowIndex, const css::uno::Any &nColumnIndex ) throw(css::uno::RuntimeException); + // Attributes virtual css::uno::Any SAL_CALL getValue() throw (css::uno::RuntimeException); virtual void SAL_CALL setValue( const css::uno::Any& aValue ) throw ( css::uno::RuntimeException); diff --git a/sc/source/ui/vba/vbasheetobject.cxx b/sc/source/ui/vba/vbasheetobject.cxx index 4bd0f1d60547..28e54de859ad 100644 --- a/sc/source/ui/vba/vbasheetobject.cxx +++ b/sc/source/ui/vba/vbasheetobject.cxx @@ -38,7 +38,9 @@ #include <rtl/ustrbuf.hxx> #include <filter/msfilter/msvbahelper.hxx> #include <oox/helper/helper.hxx> +#include <svx/unoshape.hxx> #include "vbafont.hxx" +#include "drwlayer.hxx" using ::rtl::OUString; using namespace ::com::sun::star; @@ -237,13 +239,38 @@ void SAL_CALL ScVbaSheetObjectBase::setName( const OUString& rName ) throw (uno: sal_Int32 SAL_CALL ScVbaSheetObjectBase::getPlacement() throw (uno::RuntimeException) { - // TODO - return excel::XlPlacement::xlMoveAndSize; + sal_Int32 nRet = excel::XlPlacement::xlMoveAndSize; + SvxShape* pShape = SvxShape::getImplementation( mxShape ); + if(pShape) + { + SdrObject* pObj = pShape->GetSdrObject(); + if (pObj) + { + ScAnchorType eType = ScDrawLayer::GetAnchor(pObj); + if (eType == SCA_PAGE) + nRet = excel::XlPlacement::xlFreeFloating; + } + } + return nRet; } -void SAL_CALL ScVbaSheetObjectBase::setPlacement( sal_Int32 /*nPlacement*/ ) throw (uno::RuntimeException) +void SAL_CALL ScVbaSheetObjectBase::setPlacement( sal_Int32 nPlacement ) throw (uno::RuntimeException) { - // TODO + SvxShape* pShape = SvxShape::getImplementation( mxShape ); + if(pShape) + { + SdrObject* pObj = pShape->GetSdrObject(); + if (pObj) + { + ScAnchorType eType = SCA_CELL; + if ( nPlacement == excel::XlPlacement::xlFreeFloating ) + eType = SCA_PAGE; + + // xlMove is not supported, treated as SCA_CELL (xlMoveAndSize) + + ScDrawLayer::SetAnchor(pObj, eType); + } + } } sal_Bool SAL_CALL ScVbaSheetObjectBase::getPrintObject() throw (uno::RuntimeException) diff --git a/sc/source/ui/vba/vbaworkbook.cxx b/sc/source/ui/vba/vbaworkbook.cxx index 28469c4685a2..1e2acd6252b8 100644 --- a/sc/source/ui/vba/vbaworkbook.cxx +++ b/sc/source/ui/vba/vbaworkbook.cxx @@ -300,7 +300,7 @@ ScVbaWorkbook::SaveCopyAs( const rtl::OUString& sFileName ) throw ( uno::Runtime } css::uno::Any SAL_CALL -ScVbaWorkbook::Styles( const::uno::Any& Item ) throw (uno::RuntimeException) +ScVbaWorkbook::Styles( const uno::Any& Item ) throw (uno::RuntimeException) { // quick look and Styles object doesn't seem to have a valid parent // or a least the object browser just shows an object that has no @@ -313,18 +313,16 @@ ScVbaWorkbook::Styles( const::uno::Any& Item ) throw (uno::RuntimeException) // Amelia Wang uno::Any SAL_CALL -ScVbaWorkbook::Names( const css::uno::Any& aIndex ) throw (uno::RuntimeException) +ScVbaWorkbook::Names( const uno::Any& aIndex ) throw (uno::RuntimeException) { - uno::Reference< frame::XModel > xModel( getModel() ); + uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_SET_THROW ); uno::Reference< beans::XPropertySet > xProps( xModel, uno::UNO_QUERY_THROW ); uno::Reference< sheet::XNamedRanges > xNamedRanges( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NamedRanges") ) ), uno::UNO_QUERY_THROW ); - uno::Reference< XCollection > xNames( new ScVbaNames( this , mxContext , xNamedRanges , xModel )); - if ( aIndex.getValueTypeClass() == uno::TypeClass_VOID ) - { + uno::Reference< XCollection > xNames( new ScVbaNames( this, mxContext, xNamedRanges, xModel ) ); + if ( aIndex.hasValue() ) + return uno::Any( xNames->Item( aIndex, uno::Any() ) ); return uno::Any( xNames ); } - return uno::Any( xNames->Item( aIndex, uno::Any() ) ); -} rtl::OUString& ScVbaWorkbook::getServiceImplName() diff --git a/sc/source/ui/vba/vbaworkbooks.cxx b/sc/source/ui/vba/vbaworkbooks.cxx index 7efee1505dcb..a9f1970be34e 100644 --- a/sc/source/ui/vba/vbaworkbooks.cxx +++ b/sc/source/ui/vba/vbaworkbooks.cxx @@ -46,7 +46,9 @@ #include <com/sun/star/document/XTypeDetection.hpp> #include <com/sun/star/uri/XUriReference.hpp> #include <com/sun/star/uri/XUriReferenceFactory.hpp> +#include <com/sun/star/script/vba/VBAEventId.hpp> #include <com/sun/star/script/vba/XVBACompatibility.hpp> +#include <com/sun/star/script/vba/XVBAEventProcessor.hpp> #include <com/sun/star/script/vba/XVBAModuleInfo.hpp> #include <com/sun/star/script/ModuleInfo.hpp> #include <com/sun/star/script/ModuleType.hpp> @@ -73,15 +75,19 @@ void setUpDocumentModules( const uno::Reference< sheet::XSpreadsheetDocument >& ScDocShell* pShell = excel::getDocShell( xModel ); if ( pShell ) { + String aPrjName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) ); + pShell->GetBasicManager()->SetName( aPrjName ); + + /* Set library container to VBA compatibility mode. This will create + the VBA Globals object and store it in the Basic manager of the + document. */ uno::Reference<script::XLibraryContainer> xLibContainer = pShell->GetBasicContainer(); uno::Reference<script::vba::XVBACompatibility> xVBACompat( xLibContainer, uno::UNO_QUERY_THROW ); xVBACompat->setVBACompatibilityMode( sal_True ); - String aPrjName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) ); - pShell->GetBasicManager()->SetName( aPrjName ); if( xLibContainer.is() ) { - if( !xLibContainer->hasByName( aPrjName ) ) + if( !xLibContainer->hasByName( aPrjName ) ) xLibContainer->createLibrary( aPrjName ); uno::Any aLibAny = xLibContainer->getByName( aPrjName ); uno::Reference< container::XNameContainer > xLib; @@ -90,8 +96,6 @@ void setUpDocumentModules( const uno::Reference< sheet::XSpreadsheetDocument >& { uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY_THROW ); uno::Reference< lang::XMultiServiceFactory> xSF( pShell->GetModel(), uno::UNO_QUERY_THROW); - // bootstrap vbaglobals - xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals"))); uno::Reference< container::XNameAccess > xVBACodeNamedObjectAccess( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAObjectModuleObjectProvider"))), uno::UNO_QUERY_THROW ); // set up the module info for the workbook and sheets in the nealy created // spreadsheet @@ -130,6 +134,18 @@ void setUpDocumentModules( const uno::Reference< sheet::XSpreadsheetDocument >& } } } + + /* Trigger the Workbook_Open event, event processor will register + itself as listener for specific events. */ + try + { + uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( pShell->GetDocument()->GetVbaEventProcessor(), uno::UNO_SET_THROW ); + uno::Sequence< uno::Any > aArgs; + xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKBOOK_OPEN, aArgs ); + } + catch( uno::Exception& ) + { + } } } @@ -200,9 +216,41 @@ ScVbaWorkbooks::createCollectionObject( const css::uno::Any& aSource ) uno::Any SAL_CALL -ScVbaWorkbooks::Add() throw (uno::RuntimeException) +ScVbaWorkbooks::Add( const uno::Any& Template ) throw (uno::RuntimeException) { - uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( VbaDocumentsBase::Add() , uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSpreadsheetDocument > xSpreadDoc; + sal_Int32 nWorkbookType = 0; + ::rtl::OUString aTemplateFileName; + if( Template >>= nWorkbookType ) + { + // nWorkbookType is a constant from XlWBATemplate (added in Excel 2007) + // TODO: create chart-sheet if supported by Calc + + xSpreadDoc.set( createDocument(), uno::UNO_QUERY_THROW ); + // create a document with one sheet only + uno::Reference< sheet::XSpreadsheets > xSheets( xSpreadDoc->getSheets(), uno::UNO_SET_THROW ); + uno::Reference< container::XIndexAccess > xSheetsIA( xSheets, uno::UNO_QUERY_THROW ); + while( xSheetsIA->getCount() > 1 ) + { + uno::Reference< container::XNamed > xSheetName( xSheetsIA->getByIndex( xSheetsIA->getCount() - 1 ), uno::UNO_QUERY_THROW ); + xSheets->removeByName( xSheetName->getName() ); + } + } + else if( Template >>= aTemplateFileName ) + { + // TODO: create document from template + xSpreadDoc.set( createDocument(), uno::UNO_QUERY_THROW ); + } + else if( !Template.hasValue() ) + { + // regular spreadsheet document with configured number of sheets + xSpreadDoc.set( createDocument(), uno::UNO_QUERY_THROW ); + } + else + { + // illegal argument + throw uno::RuntimeException(); + } // need to set up the document modules ( and vba mode ) here setUpDocumentModules( xSpreadDoc ); @@ -211,10 +259,10 @@ ScVbaWorkbooks::Add() throw (uno::RuntimeException) return uno::Any(); } -void +void SAL_CALL ScVbaWorkbooks::Close() throw (uno::RuntimeException) { - VbaDocumentsBase::Close(); + closeDocuments(); } bool @@ -254,7 +302,7 @@ ScVbaWorkbooks::getFileFilterType( const rtl::OUString& rFileName ) } // #TODO# #FIXME# can any of the unused params below be used? -uno::Any +uno::Any SAL_CALL ScVbaWorkbooks::Open( const rtl::OUString& rFileName, const uno::Any& /*UpdateLinks*/, const uno::Any& ReadOnly, const uno::Any& Format, const uno::Any& /*Password*/, const uno::Any& /*WriteResPassword*/, const uno::Any& /*IgnoreReadOnlyRecommended*/, const uno::Any& /*Origin*/, const uno::Any& Delimiter, const uno::Any& /*Editable*/, const uno::Any& /*Notify*/, const uno::Any& /*Converter*/, const uno::Any& /*AddToMru*/ ) throw (uno::RuntimeException) { // we need to detect if this is a URL, if not then assume its a file path @@ -333,7 +381,7 @@ ScVbaWorkbooks::Open( const rtl::OUString& rFileName, const uno::Any& /*UpdateLi else if ( !isSpreadSheetFile( sType ) ) throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Bad Format")), uno::Reference< uno::XInterface >() ); - uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( VbaDocumentsBase::Open( rFileName, ReadOnly, sProps ), uno::UNO_QUERY_THROW ); + uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( openDocument( rFileName, ReadOnly, sProps ), uno::UNO_QUERY_THROW ); uno::Any aRet = getWorkbook( mxContext, xSpreadDoc, mxParent ); uno::Reference< excel::XWorkbook > xWBook( aRet, uno::UNO_QUERY ); if ( xWBook.is() ) @@ -341,12 +389,6 @@ ScVbaWorkbooks::Open( const rtl::OUString& rFileName, const uno::Any& /*UpdateLi return aRet; } -uno::Any -ScVbaWorkbooks::Open( const rtl::OUString& Filename, const uno::Any& ReadOnly, const uno::Sequence< beans::PropertyValue >& rProps ) throw (css::uno::RuntimeException) -{ - return VbaDocumentsBase::Open( Filename, ReadOnly, rProps ); -} - rtl::OUString& ScVbaWorkbooks::getServiceImplName() { diff --git a/sc/source/ui/vba/vbaworkbooks.hxx b/sc/source/ui/vba/vbaworkbooks.hxx index 5d6210244d80..3392829f1a05 100644 --- a/sc/source/ui/vba/vbaworkbooks.hxx +++ b/sc/source/ui/vba/vbaworkbooks.hxx @@ -60,12 +60,9 @@ public: virtual css::uno::Sequence<rtl::OUString> getServiceNames(); // XWorkbooks - virtual css::uno::Any SAL_CALL Add() throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Add( const css::uno::Any& Template ) throw (css::uno::RuntimeException); virtual void SAL_CALL Close( ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Open( const ::rtl::OUString& Filename, const css::uno::Any& UpdateLinks, const css::uno::Any& ReadOnly, const css::uno::Any& Format, const css::uno::Any& Password, const css::uno::Any& WriteResPassword, const css::uno::Any& IgnoreReadOnlyRecommended, const css::uno::Any& Origin, const css::uno::Any& Delimiter, const css::uno::Any& Editable, const css::uno::Any& Notify, const css::uno::Any& Converter, const css::uno::Any& AddToMru ) throw (css::uno::RuntimeException); - - // VbaDocumentsBase / XDocumentsBase (to avoid warning C4266 for hiding function on wntmsci) - virtual css::uno::Any SAL_CALL Open( const ::rtl::OUString& Filename, const css::uno::Any& ReadOnly, const css::uno::Sequence< css::beans::PropertyValue >& rProps ) throw (css::uno::RuntimeException); }; #endif /* SC_VBA_WORKBOOKS_HXX */ diff --git a/sc/source/ui/vba/vbaworksheet.cxx b/sc/source/ui/vba/vbaworksheet.cxx index 6ee6fa1f6b19..6491024071b2 100644 --- a/sc/source/ui/vba/vbaworksheet.cxx +++ b/sc/source/ui/vba/vbaworksheet.cxx @@ -51,6 +51,7 @@ #include <com/sun/star/sheet/XSheetOutline.hpp> #include <com/sun/star/sheet/XSheetPageBreak.hpp> #include <com/sun/star/sheet/XDataPilotTablesSupplier.hpp> +#include <com/sun/star/sheet/XNamedRanges.hpp> #include <com/sun/star/util/XURLTransformer.hpp> #include <com/sun/star/frame/XDispatchProvider.hpp> #include <com/sun/star/frame/XComponentLoader.hpp> @@ -61,6 +62,7 @@ #include <com/sun/star/form/FormComponentType.hpp> #include <com/sun/star/form/XFormsSupplier.hpp> #include <ooo/vba/excel/XlEnableSelection.hpp> +#include <ooo/vba/excel/XlSheetVisibility.hpp> #include <ooo/vba/excel/XWorkbook.hpp> #include <ooo/vba/XControlProvider.hpp> @@ -94,6 +96,7 @@ #include "vbaworksheets.hxx" #include "vbahyperlinks.hxx" #include "vbasheetobjects.hxx" +#include "vbanames.hxx" #define STANDARDWIDTH 2267 #define STANDARDHEIGHT 427 @@ -179,20 +182,20 @@ openNewDoc(rtl::OUString aSheetName ) return xModel; } -ScVbaWorksheet::ScVbaWorksheet( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext ) : WorksheetImpl_BASE( xParent, xContext ) +ScVbaWorksheet::ScVbaWorksheet( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext ) : WorksheetImpl_BASE( xParent, xContext ), mbVeryHidden( false ) { } ScVbaWorksheet::ScVbaWorksheet(const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSpreadsheet >& xSheet, - const uno::Reference< frame::XModel >& xModel ) throw (uno::RuntimeException) : WorksheetImpl_BASE( xParent, xContext ), mxSheet( xSheet ), mxModel(xModel) + const uno::Reference< frame::XModel >& xModel ) throw (uno::RuntimeException) : WorksheetImpl_BASE( xParent, xContext ), mxSheet( xSheet ), mxModel(xModel), mbVeryHidden( false ) { } ScVbaWorksheet::ScVbaWorksheet( uno::Sequence< uno::Any> const & args, - uno::Reference< uno::XComponentContext> const & xContext ) throw ( lang::IllegalArgumentException ) : WorksheetImpl_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext ), mxModel( getXSomethingFromArgs< frame::XModel >( args, 1 ) ) + uno::Reference< uno::XComponentContext> const & xContext ) throw ( lang::IllegalArgumentException ) : WorksheetImpl_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext ), mxModel( getXSomethingFromArgs< frame::XModel >( args, 1 ) ), mbVeryHidden( false ) { - if ( args.getLength() < 2 ) + if ( args.getLength() < 3 ) throw lang::IllegalArgumentException(); rtl::OUString sSheetName; @@ -221,24 +224,40 @@ ScVbaWorksheet::setName(const ::rtl::OUString &rName ) throw (uno::RuntimeExcept xNamed->setName( rName ); } -sal_Bool +sal_Int32 ScVbaWorksheet::getVisible() throw (uno::RuntimeException) { uno::Reference< beans::XPropertySet > xProps( getSheet(), uno::UNO_QUERY_THROW ); - uno::Any aValue = xProps->getPropertyValue - (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVisible" ) ) ); - sal_Bool bRet = false; - aValue >>= bRet; - return bRet; + bool bVisible = false; + xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVisible" ) ) ) >>= bVisible; + using namespace ::ooo::vba::excel::XlSheetVisibility; + return bVisible ? xlSheetVisible : (mbVeryHidden ? xlSheetVeryHidden : xlSheetHidden); } void -ScVbaWorksheet::setVisible( sal_Bool bVisible ) throw (uno::RuntimeException) +ScVbaWorksheet::setVisible( sal_Int32 nVisible ) throw (uno::RuntimeException) { + using namespace ::ooo::vba::excel::XlSheetVisibility; + bool bVisible = true; + switch( nVisible ) + { + case xlSheetVisible: case 1: // Excel accepts -1 and 1 for visible sheets + bVisible = true; + mbVeryHidden = false; + break; + case xlSheetHidden: + bVisible = false; + mbVeryHidden = false; + break; + case xlSheetVeryHidden: + bVisible = false; + mbVeryHidden = true; + break; + default: + throw uno::RuntimeException(); + } uno::Reference< beans::XPropertySet > xProps( getSheet(), uno::UNO_QUERY_THROW ); - uno::Any aValue( bVisible ); - xProps->setPropertyValue - (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVisible" ) ), aValue); + xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVisible" ) ), uno::Any( bVisible ) ); } sal_Int16 @@ -639,7 +658,10 @@ uno::Reference< excel::XRange > ScVbaWorksheet::Cells( const ::uno::Any &nRow, const ::uno::Any &nCol ) throw (uno::RuntimeException) { - return getSheetRange()->Cells( nRow, nCol ); + // Performance optimization for often-called Cells method: + // Use a common helper method instead of creating a new ScVbaRange object + uno::Reference< table::XCellRange > xRange( getSheet(), uno::UNO_QUERY_THROW ); + return ScVbaRange::CellsHelper( this, mxContext, xRange, nRow, nCol ); } uno::Reference< excel::XRange > @@ -716,8 +738,15 @@ ScVbaWorksheet::Hyperlinks( const uno::Any& aIndex ) throw (uno::RuntimeExceptio uno::Any SAL_CALL ScVbaWorksheet::Names( const css::uno::Any& aIndex ) throw (uno::RuntimeException) { - uno::Reference< excel::XWorkbook > xWorkbook( getParent(), uno::UNO_QUERY_THROW ); - return xWorkbook->Names( aIndex ); + // fake sheet-local names by returning all global names + // #163498# initialize Names object with correct parent (this worksheet) + // TODO: real sheet-local names... + uno::Reference< beans::XPropertySet > xProps( mxModel, uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XNamedRanges > xNamedRanges( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NamedRanges") ) ), uno::UNO_QUERY_THROW ); + uno::Reference< XCollection > xNames( new ScVbaNames( this, mxContext, xNamedRanges, mxModel ) ); + if ( aIndex.hasValue() ) + return uno::Any( xNames->Item( aIndex, uno::Any() ) ); + return uno::Any( xNames ); } uno::Any SAL_CALL @@ -888,7 +917,8 @@ ScVbaWorksheet::getFormControls() // get the www-standard container ( maybe we should access the // 'www-standard' by name rather than index, this seems an // implementation detail - xFormControls.set( xIndexAccess->getByIndex(0), uno::UNO_QUERY_THROW ); + if( xIndexAccess->hasElements() ) + xFormControls.set( xIndexAccess->getByIndex(0), uno::UNO_QUERY ); } catch( uno::Exception& ) diff --git a/sc/source/ui/vba/vbaworksheet.hxx b/sc/source/ui/vba/vbaworksheet.hxx index 78bcc2503a49..ff5850b7c445 100644 --- a/sc/source/ui/vba/vbaworksheet.hxx +++ b/sc/source/ui/vba/vbaworksheet.hxx @@ -62,6 +62,7 @@ class ScVbaWorksheet : public WorksheetImpl_BASE css::uno::Reference< ov::excel::XChartObjects > mxCharts; css::uno::Reference< ov::excel::XHyperlinks > mxHlinks; ::rtl::Reference< ScVbaSheetObjectsBase > mxButtons; + bool mbVeryHidden; css::uno::Reference< ov::excel::XWorksheet > getSheetAtOffset(SCTAB offset) throw (css::uno::RuntimeException); css::uno::Reference< ov::excel::XRange > getSheetRange() throw (css::uno::RuntimeException); @@ -91,8 +92,8 @@ public: // Attributes virtual ::rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException); virtual void SAL_CALL setName( const ::rtl::OUString &rName ) throw (css::uno::RuntimeException); - virtual sal_Bool SAL_CALL getVisible() throw (css::uno::RuntimeException); - virtual void SAL_CALL setVisible( sal_Bool bVisible ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getVisible() throw (css::uno::RuntimeException); + virtual void SAL_CALL setVisible( sal_Int32 nVisible ) throw (css::uno::RuntimeException); virtual ::sal_Int32 SAL_CALL getStandardWidth() throw (css::uno::RuntimeException); virtual ::sal_Int32 SAL_CALL getStandardHeight() throw (css::uno::RuntimeException); virtual ::sal_Bool SAL_CALL getProtectionMode() throw (css::uno::RuntimeException); diff --git a/sc/source/ui/view/drawvie4.cxx b/sc/source/ui/view/drawvie4.cxx index 3a28096d2853..d4c5d714b2ee 100644 --- a/sc/source/ui/view/drawvie4.cxx +++ b/sc/source/ui/view/drawvie4.cxx @@ -282,7 +282,7 @@ void ScDrawView::CalcNormScale( Fraction& rFractX, Fraction& rFractY ) const pDoc->GetTableArea( nTab, nEndCol, nEndRow ); if (nEndCol<20) nEndCol = 20; - if (nEndRow<1000) + if (nEndRow<20) nEndRow = 1000; Fraction aZoom(1,1); diff --git a/sc/source/ui/view/drawview.cxx b/sc/source/ui/view/drawview.cxx index 1d2b797b3a9b..489da0cc4899 100644 --- a/sc/source/ui/view/drawview.cxx +++ b/sc/source/ui/view/drawview.cxx @@ -376,7 +376,7 @@ void ScDrawView::RecalcScale() pDoc->GetTableArea( nTab, nEndCol, nEndRow ); if (nEndCol<20) nEndCol = 20; - if (nEndRow<1000) + if (nEndRow<20) nEndRow = 1000; ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, pDev,aZoomX,aZoomY,nPPTX,nPPTY, diff --git a/sc/source/ui/view/gridwin3.cxx b/sc/source/ui/view/gridwin3.cxx index f16c2fe1ada7..cdb7e8acfba7 100644 --- a/sc/source/ui/view/gridwin3.cxx +++ b/sc/source/ui/view/gridwin3.cxx @@ -265,7 +265,7 @@ MapMode ScGridWindow::GetDrawMapMode( BOOL bForce ) SCROW nEndRow = 0; pDoc->GetTableArea( nTab, nEndCol, nEndRow ); if (nEndCol<20) nEndCol = 20; - if (nEndRow<1000) nEndRow = 1000; + if (nEndRow<20) nEndRow = 1000; ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, this, pViewData->GetZoomX(),pViewData->GetZoomY(), pViewData->GetPPTX(),pViewData->GetPPTY(), diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx index 61289cc7f931..b0df298315bf 100644 --- a/sc/source/ui/view/output2.cxx +++ b/sc/source/ui/view/output2.cxx @@ -529,9 +529,18 @@ void ScDrawStringsVars::SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth ) // must be a value or formula cell. return; - if (eType == CELLTYPE_FORMULA && !static_cast<ScFormulaCell*>(pCell)->IsValue()) + if (eType == CELLTYPE_FORMULA) + { + ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell); + if (pFCell->GetErrCode() != 0) + { + SetHashText(); // If the error string doesn't fit, always use "###" + return; + } // If it's formula, the result must be a value. - return; + if (!pFCell->IsValue()) + return; + } ULONG nFormat = GetValueFormat(); if ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) != 0) diff --git a/sc/source/ui/view/prevwsh.cxx b/sc/source/ui/view/prevwsh.cxx index 48ffd4fd39a4..6e28d6ba846d 100644 --- a/sc/source/ui/view/prevwsh.cxx +++ b/sc/source/ui/view/prevwsh.cxx @@ -140,7 +140,6 @@ void ScPreviewShell::Construct( Window* pParent ) if (pDrawBC) StartListening(*pDrawBC); -// pPreview->Show(); // wird vom Sfx angezeigt pHorScroll->Show(); pVerScroll->Show(); pCorner->Show(); diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx index 90bfe0c24e5c..93d1edd7fee5 100644 --- a/sc/source/ui/view/tabview3.cxx +++ b/sc/source/ui/view/tabview3.cxx @@ -1549,7 +1549,7 @@ void ScTabView::SelectNextTab( short nDir, BOOL bExtendSelection ) // SetTabNo - angezeigte Tabelle -void ScTabView::SetTabNo( SCTAB nTab, BOOL bNew, BOOL bExtendSelection ) +void ScTabView::SetTabNo( SCTAB nTab, BOOL bNew, BOOL bExtendSelection, bool bSameTabButMoved ) { if ( !ValidTab(nTab) ) { @@ -1681,7 +1681,7 @@ void ScTabView::SetTabNo( SCTAB nTab, BOOL bNew, BOOL bExtendSelection ) pGridWin[i]->UpdateEditViewPos(); } - TabChanged(); // DrawView + TabChanged( bSameTabButMoved ); // DrawView aViewData.GetViewShell()->WindowChanged(); // falls das aktive Fenster anders ist if ( !bUnoRefDialog ) diff --git a/sc/source/ui/view/tabview5.cxx b/sc/source/ui/view/tabview5.cxx index f0ac3fc42869..f5a4a37784a9 100644 --- a/sc/source/ui/view/tabview5.cxx +++ b/sc/source/ui/view/tabview5.cxx @@ -267,7 +267,7 @@ void ScTabView::DoAddWin( ScGridWindow* pWin ) //================================================================== -void ScTabView::TabChanged() +void ScTabView::TabChanged( bool bSameTabButMoved ) { if (pDrawView) { @@ -339,7 +339,7 @@ void ScTabView::TabChanged() { ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); if (pImp) - pImp->SheetChanged(); + pImp->SheetChanged( bSameTabButMoved ); } } } diff --git a/sc/source/ui/view/tabvwsh.cxx b/sc/source/ui/view/tabvwsh.cxx index 2fc2bba072d9..4b0060c88c4d 100644 --- a/sc/source/ui/view/tabvwsh.cxx +++ b/sc/source/ui/view/tabvwsh.cxx @@ -96,10 +96,7 @@ SFX_IMPL_INTERFACE(ScTabViewShell,SfxViewShell,ScResId(SCSTR_TABVIEWSHELL)) SFX_CHILDWINDOW_REGISTRATION(GalleryChildWindow::GetChildWindowId()); SFX_CHILDWINDOW_REGISTRATION(ScSpellDialogChildWindow::GetChildWindowId()); SFX_CHILDWINDOW_REGISTRATION( ::avmedia::MediaPlayer::GetChildWindowId() ); - - //<!--Added by PengYunQuan for Validity Cell Range Picker SFX_CHILDWINDOW_REGISTRATION(ScValidityRefChildWin::GetChildWindowId()); - //-->Added by PengYunQuan for Validity Cell Range Picker } SFX_IMPL_NAMED_VIEWFACTORY( ScTabViewShell, "Default" ) diff --git a/sc/source/ui/view/tabvwsh5.cxx b/sc/source/ui/view/tabvwsh5.cxx index 1a3dd6928a17..12f08ec6d0e2 100644 --- a/sc/source/ui/view/tabvwsh5.cxx +++ b/sc/source/ui/view/tabvwsh5.cxx @@ -249,7 +249,7 @@ void __EXPORT ScTabViewShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint // kann und dann auch die aktive View umgeschaltet werden muss. SCTAB nNewTab = nActiveTab; - BOOL bForce = FALSE; + bool bStayOnActiveTab = true; switch (nId) { case SC_TAB_INSERTED: @@ -260,7 +260,7 @@ void __EXPORT ScTabViewShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint if ( nTab1 < nNewTab ) // vorher geloescht --nNewTab; else if ( nTab1 == nNewTab ) // aktuelle geloescht - bForce = TRUE; + bStayOnActiveTab = false; break; case SC_TAB_MOVED: if ( nNewTab == nTab1 ) // verschobene Tabelle @@ -282,7 +282,7 @@ void __EXPORT ScTabViewShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint break; case SC_TAB_HIDDEN: if ( nTab1 == nNewTab ) // aktuelle ausgeblendet - bForce = TRUE; + bStayOnActiveTab = false; break; } @@ -290,7 +290,8 @@ void __EXPORT ScTabViewShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint if ( nNewTab >= pDoc->GetTableCount() ) nNewTab = pDoc->GetTableCount() - 1; - SetTabNo( nNewTab, bForce ); + BOOL bForce = !bStayOnActiveTab; + SetTabNo( nNewTab, bForce, FALSE, bStayOnActiveTab ); } else if (rHint.ISA(ScIndexHint)) { diff --git a/sc/util/makefile.mk b/sc/util/makefile.mk index 09578f6ef6a8..ff4696409d48 100644 --- a/sc/util/makefile.mk +++ b/sc/util/makefile.mk @@ -51,7 +51,7 @@ RESLIB1LIST=\ $(SRS)$/pagedlg.srs \ $(SRS)$/navipi.srs \ $(SRS)$/cctrl.srs \ - $(SOLARCOMMONRESDIR)$/sfx.srs + RESLIB1NAME=sc RESLIB1IMAGES=\ diff --git a/sc/workben/test.cxx b/sc/workben/test.cxx index 4caa49e3adcd..b6b640a8a4ba 100644 --- a/sc/workben/test.cxx +++ b/sc/workben/test.cxx @@ -29,7 +29,7 @@ #include <svtools/libcall.hxx> #include <vcl/msgbox.hxx> #include <vcl/window.hxx> -#include <vcl/imagebtn.hxx> +#include <vcl/button.hxx> #include <vcl/field.hxx> #include <vcl/fixed.hxx> #include <vcl/help.hxx> |