diff options
author | Caolán McNamara <cmc@openoffice.org> | 2010-05-26 14:41:36 +0100 |
---|---|---|
committer | Caolán McNamara <cmc@openoffice.org> | 2010-05-26 14:41:36 +0100 |
commit | 85de4721f807f238a58c501c72932c6721e865dd (patch) | |
tree | c194418b5b7448e9c2bba9fdcaa60aed46b58487 /sc/source | |
parent | 5d7f8a80ada3792adf51b47ddeee3b526d1084de (diff) | |
parent | fc1ac6254cde85bedfff1f8f78d678d4e10cc3dd (diff) |
cmcfixes74: merge with DEV300 m79
Diffstat (limited to 'sc/source')
51 files changed, 898 insertions, 238 deletions
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx index 9a3670d2a9e0..4de78c71fe79 100644 --- a/sc/source/core/data/cell2.cxx +++ b/sc/source/core/data/cell2.cxx @@ -996,6 +996,8 @@ void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode, pDocument->RemoveFromFormulaTree( this ); // update formula count delete pCode; pCode = pRangeData->GetCode()->Clone(); + // #i18937# #i110008# call MoveRelWrap, but with the old position + ScCompiler::MoveRelWrap(*pCode, pDocument, aOldPos, pRangeData->GetMaxCol(), pRangeData->GetMaxRow()); ScCompiler aComp2(pDocument, aPos, *pCode); aComp2.SetGrammar(pDocument->GetGrammar()); aComp2.UpdateSharedFormulaReference( eUpdateRefMode, aOldPos, r, diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index dc206950b3ea..22b75b8d4a6a 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -1467,8 +1467,9 @@ BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString, } -void ScColumn::GetFilterEntries(SCROW nStartRow, SCROW nEndRow, TypedScStrCollection& rStrings) +void ScColumn::GetFilterEntries(SCROW nStartRow, SCROW nEndRow, TypedScStrCollection& rStrings, bool& rHasDates) { + bool bHasDates = false; SvNumberFormatter* pFormatter = pDocument->GetFormatTable(); String aString; SCROW nRow = 0; @@ -1504,6 +1505,18 @@ void ScColumn::GetFilterEntries(SCROW nStartRow, SCROW nEndRow, TypedScStrCollec nValue = 0.0; } + if (pFormatter) + { + short nType = pFormatter->GetType(nFormat); + if ((nType & NUMBERFORMAT_DATE) && !(nType & NUMBERFORMAT_TIME)) + { + // special case for date values. Disregard the time + // element if the number format is of date type. + nValue = ::rtl::math::approxFloor(nValue); + bHasDates = true; + } + } + pData = new TypedStrData( aString, nValue, SC_STRTYPE_VALUE ); } #if 0 // DR @@ -1522,6 +1535,8 @@ void ScColumn::GetFilterEntries(SCROW nStartRow, SCROW nEndRow, TypedScStrCollec ++nIndex; } + + rHasDates = bHasDates; } // diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index c08fb7a10228..138b55f0794c 100644..100755 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -93,6 +93,7 @@ #include "tabprotection.hxx" #include "formulaparserpool.hxx" #include "clipparam.hxx" +#include <basic/basmgr.hxx> // pImpl because including lookupcache.hxx in document.hxx isn't wanted, and // dtor plus helpers are convenient. @@ -934,6 +935,8 @@ BOOL ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM return bValid; } +void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, String& sModuleName, String& sModuleSource ); + ULONG ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos, SCTAB nDestPos, BOOL bInsertNew, BOOL bResultsOnly ) @@ -1104,6 +1107,43 @@ ULONG ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos, } if (!bValid) nRetVal = 0; + BOOL bVbaEnabled = IsInVBAMode(); + + if ( bVbaEnabled ) + { + SfxObjectShell* pSrcShell = pSrcDoc ? pSrcDoc->GetDocumentShell() : NULL; + if ( pSrcShell ) + { + StarBASIC* pStarBASIC = pSrcShell ? pSrcShell->GetBasic() : NULL; + String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) ); + if ( pSrcShell && pSrcShell->GetBasicManager()->GetName().Len() > 0 ) + { + aLibName = pSrcShell->GetBasicManager()->GetName(); + pStarBASIC = pSrcShell->GetBasicManager()->GetLib( aLibName ); + } + + String sCodeName; + String sSource; + com::sun::star::uno::Reference< com::sun::star::script::XLibraryContainer > xLibContainer = pSrcShell->GetBasicContainer(); + com::sun::star::uno::Reference< com::sun::star::container::XNameContainer > xLib; + if( xLibContainer.is() ) + { + com::sun::star::uno::Any aLibAny = xLibContainer->getByName( aLibName ); + aLibAny >>= xLib; + } + + if( xLib.is() ) + { + String sSrcCodeName; + pSrcDoc->GetCodeName( nSrcPos, sSrcCodeName ); + rtl::OUString sRTLSource; + xLib->getByName( sSrcCodeName ) >>= sRTLSource; + sSource = sRTLSource; + } + VBA_InsertModule( *this, nDestPos, sCodeName, sSource ); + } + } + return nRetVal; } diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index fd2b2f1fd309..557f181c9d8f 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -1263,7 +1263,8 @@ BOOL ScDocument::HasRowHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, // GetFilterEntries - Eintraege fuer AutoFilter-Listbox // -BOOL ScDocument::GetFilterEntries( SCCOL nCol, SCROW nRow, SCTAB nTab, TypedScStrCollection& rStrings, bool bFilter ) +BOOL ScDocument::GetFilterEntries( + SCCOL nCol, SCROW nRow, SCTAB nTab, bool bFilter, TypedScStrCollection& rStrings, bool& rHasDates) { if ( ValidTab(nTab) && pTab[nTab] && pDBCollection ) { @@ -1300,11 +1301,11 @@ BOOL ScDocument::GetFilterEntries( SCCOL nCol, SCROW nRow, SCTAB nTab, TypedScSt if ( bFilter ) { - pTab[nTab]->GetFilteredFilterEntries( nCol, nStartRow, nEndRow, aParam, rStrings ); + pTab[nTab]->GetFilteredFilterEntries( nCol, nStartRow, nEndRow, aParam, rStrings, rHasDates ); } else { - pTab[nTab]->GetFilterEntries( nCol, nStartRow, nEndRow, rStrings ); + pTab[nTab]->GetFilterEntries( nCol, nStartRow, nEndRow, rStrings, rHasDates ); } return TRUE; @@ -1319,11 +1320,11 @@ BOOL ScDocument::GetFilterEntries( SCCOL nCol, SCROW nRow, SCTAB nTab, TypedScSt // BOOL ScDocument::GetFilterEntriesArea( SCCOL nCol, SCROW nStartRow, SCROW nEndRow, - SCTAB nTab, TypedScStrCollection& rStrings ) + SCTAB nTab, TypedScStrCollection& rStrings, bool& rHasDates ) { if ( ValidTab(nTab) && pTab[nTab] ) { - pTab[nTab]->GetFilterEntries( nCol, nStartRow, nEndRow, rStrings ); + pTab[nTab]->GetFilterEntries( nCol, nStartRow, nEndRow, rStrings, rHasDates ); return TRUE; } diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 3f25ad5a310e..ff132a1f204b 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -51,6 +51,7 @@ #include <tools/tenccvt.hxx> #include <com/sun/star/text/WritingMode2.hpp> +#include <com/sun/star/script/XVBACompat.hpp> #include "document.hxx" #include "table.hxx" @@ -4972,4 +4973,13 @@ void ScDocument::EnableUndo( bool bVal ) mbUndoEnabled = bVal; } - +bool ScDocument::IsInVBAMode() const +{ + bool bResult = false; + if ( pShell ) + { + com::sun::star::uno::Reference< com::sun::star::script::XVBACompat > xVBA( pShell->GetBasicContainer(), com::sun::star::uno::UNO_QUERY ); + bResult = xVBA->getVBACompatModeOn(); + } + return bResult; +} diff --git a/sc/source/core/data/dpcachetable.cxx b/sc/source/core/data/dpcachetable.cxx index ad5e921cb278..d97900e6b904 100644 --- a/sc/source/core/data/dpcachetable.cxx +++ b/sc/source/core/data/dpcachetable.cxx @@ -183,39 +183,9 @@ sal_Int32 ScDPCacheTable::getColSize() const return GetCache()->GetColumnCount(); } -namespace { - -/** - * While the macro interpret level is incremented, the formula cells are - * (semi-)guaranteed to be interpreted. - */ -class MacroInterpretIncrementer -{ -public: - MacroInterpretIncrementer(ScDocument* pDoc) : - mpDoc(pDoc) - { - mpDoc->IncMacroInterpretLevel(); - } - ~MacroInterpretIncrementer() - { - mpDoc->DecMacroInterpretLevel(); - } -private: - ScDocument* mpDoc; -}; - -} - void ScDPCacheTable::fillTable( const ScQueryParam& rQuery, BOOL* pSpecial, bool bIgnoreEmptyRows, bool bRepeatIfEmpty ) { - // Make sure the formula cells within the data range are interpreted - // during this call, for this method may be called from the interpretation - // of GETPIVOTDATA, which disables nested formula interpretation without - // increasing the macro level. - MacroInterpretIncrementer aMacroInc(GetCache()->GetDoc()); - if ( mpCache == NULL ) InitNoneCache( NULL ); //check cache diff --git a/sc/source/core/data/dptablecache.cxx b/sc/source/core/data/dptablecache.cxx index 5032c3ba5933..8f25b70e41b6 100755 --- a/sc/source/core/data/dptablecache.cxx +++ b/sc/source/core/data/dptablecache.cxx @@ -304,7 +304,7 @@ void ScDPItemData::dump() const DBG_TRACE1( "Numberformat= %o", nNumFormat ); DBG_TRACESTR(aString ); DBG_TRACE1( "fValue= %f", fValue ); - DBG_TRACE1( "bHasValue= %d", bHasValue ? 1:0); + DBG_TRACE1( "mbFlag= %d", mbFlag); } #endif //End @@ -489,8 +489,40 @@ bool ScDPTableDataCache::IsValid() const } // ----------------------------------------------------------------------- + +namespace { + +/** + * While the macro interpret level is incremented, the formula cells are + * (semi-)guaranteed to be interpreted. + */ +class MacroInterpretIncrementer +{ +public: + MacroInterpretIncrementer(ScDocument* pDoc) : + mpDoc(pDoc) + { + mpDoc->IncMacroInterpretLevel(); + } + ~MacroInterpretIncrementer() + { + mpDoc->DecMacroInterpretLevel(); + } +private: + ScDocument* mpDoc; +}; + +} + +// ----------------------------------------------------------------------- bool ScDPTableDataCache::InitFromDoc( ScDocument* pDoc, const ScRange& rRange ) { + // Make sure the formula cells within the data range are interpreted + // during this call, for this method may be called from the interpretation + // of GETPIVOTDATA, which disables nested formula interpretation without + // increasing the macro level. + MacroInterpretIncrementer aMacroInc(pDoc); + // SCROW nStartRow = rRange.aStart.Row(); // start of data SCROW nEndRow = rRange.aEnd.Row(); diff --git a/sc/source/core/data/global2.cxx b/sc/source/core/data/global2.cxx index d32ebdafbf78..3234340ae9dd 100644 --- a/sc/source/core/data/global2.cxx +++ b/sc/source/core/data/global2.cxx @@ -145,30 +145,32 @@ BOOL ScImportParam::operator==( const ScImportParam& rOther ) const //------------------------------------------------------------------------ // struct ScQueryParam: -ScQueryEntry::ScQueryEntry() +ScQueryEntry::ScQueryEntry() : + bDoQuery(FALSE), + bQueryByString(FALSE), + bQueryByDate(false), + nField(0), + eOp(SC_EQUAL), + eConnect(SC_AND), + pStr(new String), + nVal(0.0), + pSearchParam(NULL), + pSearchText(NULL) +{ +} + +ScQueryEntry::ScQueryEntry(const ScQueryEntry& r) : + bDoQuery(r.bDoQuery), + bQueryByString(r.bQueryByString), + bQueryByDate(r.bQueryByDate), + nField(r.nField), + eOp(r.eOp), + eConnect(r.eConnect), + pStr(new String(*r.pStr)), + nVal(r.nVal), + pSearchParam(NULL), + pSearchText(NULL) { - bDoQuery = FALSE; - bQueryByString = FALSE; - eOp = SC_EQUAL; - eConnect = SC_AND; - nField = 0; - nVal = 0.0; - pStr = new String; - pSearchParam = NULL; - pSearchText = NULL; -} - -ScQueryEntry::ScQueryEntry(const ScQueryEntry& r) -{ - bDoQuery = r.bDoQuery; - bQueryByString = r.bQueryByString; - eOp = r.eOp; - eConnect = r.eConnect; - nField = r.nField; - nVal = r.nVal; - pStr = new String(*r.pStr); - pSearchParam = NULL; - pSearchText = NULL; } ScQueryEntry::~ScQueryEntry() @@ -185,6 +187,7 @@ ScQueryEntry& ScQueryEntry::operator=( const ScQueryEntry& r ) { bDoQuery = r.bDoQuery; bQueryByString = r.bQueryByString; + bQueryByDate = r.bQueryByDate; eOp = r.eOp; eConnect = r.eConnect; nField = r.nField; @@ -205,6 +208,7 @@ void ScQueryEntry::Clear() { bDoQuery = FALSE; bQueryByString = FALSE; + bQueryByDate = false; eOp = SC_EQUAL; eConnect = SC_AND; nField = 0; @@ -223,6 +227,7 @@ BOOL ScQueryEntry::operator==( const ScQueryEntry& r ) const { return bDoQuery == r.bDoQuery && bQueryByString == r.bQueryByString + && bQueryByDate == r.bQueryByDate && eOp == r.eOp && eConnect == r.eConnect && nField == r.nField diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index 09a9f41929b5..90993367dde6 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -31,6 +31,7 @@ #include <rtl/math.hxx> #include <unotools/textsearch.hxx> #include <svl/zforlist.hxx> +#include <svl/zformat.hxx> #include <unotools/charclass.hxx> #include <unotools/collatorwrapper.hxx> #include <com/sun/star/i18n/CollatorOptions.hpp> @@ -989,6 +990,35 @@ BOOL ScTable::ValidQuery(SCROW nRow, const ScQueryParam& rParam, } else nCellVal = GetValue( static_cast<SCCOL>(rEntry.nField), nRow ); + + /* NOTE: lcl_PrepareQuery() prepares a filter query such that if a + * date+time format was queried rEntry.bQueryByDate is not set. In + * case other queries wanted to use this mechanism they should do + * the same, in other words only if rEntry.nVal is an integer value + * rEntry.bQueryByDate should be true and the time fraction be + * stripped here. */ + if (rEntry.bQueryByDate) + { + sal_uInt32 nNumFmt = GetNumberFormat(static_cast<SCCOL>(rEntry.nField), nRow); + const SvNumberformat* pEntry = pDocument->GetFormatTable()->GetEntry(nNumFmt); + if (pEntry) + { + short nNumFmtType = pEntry->GetType(); + /* NOTE: Omitting the check for absence of + * NUMBERFORMAT_TIME would include also date+time formatted + * values of the same day. That may be desired in some + * cases, querying all time values of a day, but confusing + * in other cases. A user can always setup a standard + * filter query for x >= date AND x < date+1 */ + if ((nNumFmtType & NUMBERFORMAT_DATE) && !(nNumFmtType & NUMBERFORMAT_TIME)) + { + // The format is of date type. Strip off the time + // element. + nCellVal = ::rtl::math::approxFloor(nCellVal); + } + } + } + switch (rEntry.eOp) { case SC_EQUAL : @@ -1393,6 +1423,23 @@ static void lcl_PrepareQuery( ScDocument* pDoc, ScTable* pTab, ScQueryParam& rPa sal_uInt32 nIndex = 0; rEntry.bQueryByString = !( pDoc->GetFormatTable()-> IsNumberFormat( *rEntry.pStr, nIndex, rEntry.nVal ) ); + if (rEntry.bQueryByDate) + { + if (!rEntry.bQueryByString && ((nIndex % SV_COUNTRY_LANGUAGE_OFFSET) != 0)) + { + const SvNumberformat* pEntry = pDoc->GetFormatTable()->GetEntry(nIndex); + if (pEntry) + { + short nNumFmtType = pEntry->GetType(); + if (!((nNumFmtType & NUMBERFORMAT_DATE) && !(nNumFmtType & NUMBERFORMAT_TIME))) + rEntry.bQueryByDate = false; // not a date only + } + else + rEntry.bQueryByDate = false; // what the ... not a date + } + else + rEntry.bQueryByDate = false; // not a date + } } else { @@ -1776,12 +1823,13 @@ BOOL ScTable::HasRowHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL /* nEndCol * return TRUE; } -void ScTable::GetFilterEntries(SCCOL nCol, SCROW nRow1, SCROW nRow2, TypedScStrCollection& rStrings) +void ScTable::GetFilterEntries(SCCOL nCol, SCROW nRow1, SCROW nRow2, TypedScStrCollection& rStrings, bool& rHasDates) { - aCol[nCol].GetFilterEntries( nRow1, nRow2, rStrings ); + aCol[nCol].GetFilterEntries( nRow1, nRow2, rStrings, rHasDates ); } -void ScTable::GetFilteredFilterEntries( SCCOL nCol, SCROW nRow1, SCROW nRow2, const ScQueryParam& rParam, TypedScStrCollection& rStrings ) +void ScTable::GetFilteredFilterEntries( + SCCOL nCol, SCROW nRow1, SCROW nRow2, const ScQueryParam& rParam, TypedScStrCollection& rStrings, bool& rHasDates ) { // remove the entry for this column from the query parameter ScQueryParam aParam( rParam ); @@ -1799,15 +1847,18 @@ void ScTable::GetFilteredFilterEntries( SCCOL nCol, SCROW nRow1, SCROW nRow2, co BOOL* pSpecial = new BOOL[nEntryCount]; lcl_PrepareQuery( pDocument, this, aParam, pSpecial ); - + bool bHasDates = false; for ( SCROW j = nRow1; j <= nRow2; ++j ) { if ( ValidQuery( j, aParam, pSpecial ) ) { - aCol[nCol].GetFilterEntries( j, j, rStrings ); + bool bThisHasDates = false; + aCol[nCol].GetFilterEntries( j, j, rStrings, bThisHasDates ); + bHasDates |= bThisHasDates; } } + rHasDates = bHasDates; delete[] pSpecial; } diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index 2394bfb56799..2075129e4f6e 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -171,6 +171,7 @@ private: short nFuncFmtType; // NumberFormatType of a function short nCurFmtType; // current NumberFormatType short nRetFmtType; // NumberFormatType of an expression + USHORT mnStringNoValueError; // the error set in ConvertStringToValue() if no value BOOL glSubTotal; // flag for subtotal functions BYTE cPar; // current count of parameters BOOL bCalcAsShown; // precision as shown diff --git a/sc/source/core/tool/dbcolect.cxx b/sc/source/core/tool/dbcolect.cxx index 4eea4db97a0a..7f94cb64c827 100644 --- a/sc/source/core/tool/dbcolect.cxx +++ b/sc/source/core/tool/dbcolect.cxx @@ -155,6 +155,7 @@ ScDBData::ScDBData( const ScDBData& rData ) : nQueryField[i] = rData.nQueryField[i]; eQueryOp[i] = rData.eQueryOp[i]; bQueryByString[i] = rData.bQueryByString[i]; + bQueryByDate[i] = rData.bQueryByDate[i]; pQueryStr[i] = new String( *(rData.pQueryStr[i]) ); nQueryVal[i] = rData.nQueryVal[i]; eQueryConnect[i] = rData.eQueryConnect[i]; @@ -244,6 +245,7 @@ ScDBData& ScDBData::operator= (const ScDBData& rData) nQueryField[i] = rData.nQueryField[i]; eQueryOp[i] = rData.eQueryOp[i]; bQueryByString[i] = rData.bQueryByString[i]; + bQueryByDate[i] = rData.bQueryByDate[i]; *pQueryStr[i] = *rData.pQueryStr[i]; nQueryVal[i] = rData.nQueryVal[i]; eQueryConnect[i] = rData.eQueryConnect[i]; @@ -512,6 +514,7 @@ void ScDBData::GetQueryParam( ScQueryParam& rQueryParam ) const rEntry.nField = nQueryField[i]; rEntry.eOp = eQueryOp[i]; rEntry.bQueryByString = bQueryByString[i]; + rEntry.bQueryByDate = bQueryByDate[i]; *rEntry.pStr = *pQueryStr[i]; rEntry.nVal = nQueryVal[i]; rEntry.eConnect = eQueryConnect[i]; @@ -543,6 +546,7 @@ void ScDBData::SetQueryParam(const ScQueryParam& rQueryParam) nQueryField[i] = rEntry.nField; eQueryOp[i] = rEntry.eOp; bQueryByString[i] = rEntry.bQueryByString; + bQueryByDate[i] = rEntry.bQueryByDate; *pQueryStr[i] = *rEntry.pStr; nQueryVal[i] = rEntry.nVal; eQueryConnect[i] = rEntry.eConnect; diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 94cd5c1a02e9..30aa0b8aa13e 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -2488,7 +2488,14 @@ void ScInterpreter::ScN() Pop(); } else + { + // Temporarily override the ConvertStringToValue() error for + // GetCellValue() / GetCellValueOrZero() + USHORT nSErr = mnStringNoValueError; + mnStringNoValueError = errCellNoValue; fVal = GetDouble(); + mnStringNoValueError = nSErr; + } if ( nGlobalError == NOTAVAILABLE || nGlobalError == errIllegalArgument ) nGlobalError = 0; // N(#NA) and N("text") are ok if ( !nGlobalError && nErr != NOTAVAILABLE ) diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index ffba9aafc511..c576cd5ca6c3 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -261,7 +261,7 @@ double ScInterpreter::ConvertStringToValue( const String& rStr ) while (p < pStop && *p == ' ') ++p; if (p < pStop) - SetError( errNoValue); + SetError( mnStringNoValueError); break; case '-': case ':': @@ -281,7 +281,7 @@ double ScInterpreter::ConvertStringToValue( const String& rStr ) while (p < pStop && *p == ' ') ++p; if (p < pStop && !CharClass::isAsciiDigit(*p)) - SetError( errNoValue); + SetError( mnStringNoValueError); p = pLastStart; while (p < pStop && !nGlobalError && eState < blank) { @@ -291,7 +291,7 @@ double ScInterpreter::ConvertStringToValue( const String& rStr ) { // Maximum 2 digits per unit, except fractions. if (p - pLastStart >= 2 && eState != fraction) - SetError( errNoValue); + SetError( mnStringNoValueError); } else if (p > pLastStart) { @@ -300,7 +300,7 @@ double ScInterpreter::ConvertStringToValue( const String& rStr ) { nUnit[eState] = aStr.copy( pLastStart - pStart, p - pLastStart).toInt32(); if (nLimit[eState] && nLimit[eState] < nUnit[eState]) - SetError( errNoValue); + SetError( mnStringNoValueError); } pLastStart = p + 1; // hypothetical next start // Delimiters must match, a trailing delimiter @@ -311,11 +311,11 @@ double ScInterpreter::ConvertStringToValue( const String& rStr ) // Month must be followed by separator and // day, no trailing blanks. if (*p != '-' || (p+1 == pStop)) - SetError( errNoValue); + SetError( mnStringNoValueError); break; case day: if ((*p != 'T' || (p+1 == pStop)) && *p != ' ') - SetError( errNoValue); + SetError( mnStringNoValueError); // Take one blank as a valid delimiter // between date and time. break; @@ -323,17 +323,17 @@ double ScInterpreter::ConvertStringToValue( const String& rStr ) // Hour must be followed by separator and // minute, no trailing blanks. if (*p != ':' || (p+1 == pStop)) - SetError( errNoValue); + SetError( mnStringNoValueError); break; case minute: if ((*p != ':' || (p+1 == pStop)) && *p != ' ') - SetError( errNoValue); + SetError( mnStringNoValueError); if (*p == ' ') eState = done; break; case second: if (((*p != ',' && *p != '.') || (p+1 == pStop)) && *p != ' ') - SetError( errNoValue); + SetError( mnStringNoValueError); if (*p == ' ') eState = done; break; @@ -344,13 +344,13 @@ double ScInterpreter::ConvertStringToValue( const String& rStr ) case done: case blank: case stop: - SetError( errNoValue); + SetError( mnStringNoValueError); break; } eState = static_cast<State>(eState + 1); } else - SetError( errNoValue); + SetError( mnStringNoValueError); ++p; } if (eState == blank) @@ -358,14 +358,14 @@ double ScInterpreter::ConvertStringToValue( const String& rStr ) while (p < pStop && *p == ' ') ++p; if (p < pStop) - SetError( errNoValue); + SetError( mnStringNoValueError); eState = stop; } // Month without day, or hour without minute. if (eState == month || (eState == day && p <= pLastStart) || eState == hour || (eState == minute && p <= pLastStart)) - SetError( errNoValue); + SetError( mnStringNoValueError); if (!nGlobalError) { @@ -374,10 +374,10 @@ double ScInterpreter::ConvertStringToValue( const String& rStr ) { nUnit[eState] = aStr.copy( pLastStart - pStart, p - pLastStart).toInt32(); if (nLimit[eState] && nLimit[eState] < nUnit[eState]) - SetError( errNoValue); + SetError( mnStringNoValueError); } if (bDate && nUnit[hour] > 23) - SetError( errNoValue); + SetError( mnStringNoValueError); if (!nGlobalError) { if (bDate && nUnit[day] == 0) @@ -396,7 +396,7 @@ double ScInterpreter::ConvertStringToValue( const String& rStr ) } break; default: - SetError( errNoValue); + SetError( mnStringNoValueError); } if (nGlobalError) fValue = 0.0; @@ -3549,6 +3549,7 @@ ScInterpreter::ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, pTokenMatrixMap( NULL ), pMyFormulaCell( pCell ), pFormatter( pDoc->GetFormatTable() ), + mnStringNoValueError( errNoValue), bCalcAsShown( pDoc->GetDocOptions().IsCalcAsShown() ) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTTT" ); diff --git a/sc/source/filter/excel/excimp8.cxx b/sc/source/filter/excel/excimp8.cxx index e424ad2d95fe..a3ea403bf4c3 100644 --- a/sc/source/filter/excel/excimp8.cxx +++ b/sc/source/filter/excel/excimp8.cxx @@ -104,7 +104,6 @@ #include <com/sun/star/container/XNameContainer.hpp> #include <sfx2/app.hxx> - using namespace com::sun::star; @@ -257,8 +256,6 @@ void ImportExcel8::SheetProtection( void ) void ImportExcel8::ReadBasic( void ) { - bHasBasic = TRUE; - SfxObjectShell* pShell = GetDocShell(); SotStorageRef xRootStrg = GetRootStorage(); SvtFilterOptions* pFilterOpt = SvtFilterOptions::Get(); @@ -270,7 +267,18 @@ void ImportExcel8::ReadBasic( void ) if( bLoadCode || bLoadStrg ) { SvxImportMSVBasic aBasicImport( *pShell, *xRootStrg, bLoadCode, bLoadStrg ); - bool bAsComment = !bLoadExecutable; + bool bAsComment = !bLoadExecutable; + if ( !bAsComment ) + { + uno::Any aGlobs; + uno::Sequence< uno::Any > aArgs(1); + aArgs[ 0 ] <<= pShell->GetModel(); + aGlobs <<= ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.excel.Globals" ) ), aArgs ); + pShell->GetBasicManager()->SetGlobalUNOConstant( "VBAGlobals", aGlobs ); + BasicManager* pAppMgr = SFX_APP()->GetBasicManager(); + if ( pAppMgr ) + pAppMgr->SetGlobalUNOConstant( "ThisExcelDoc", aArgs[ 0 ] ); + } aBasicImport.Import( EXC_STORAGE_VBA_PROJECT, EXC_STORAGE_VBA, bAsComment ); } } @@ -286,6 +294,10 @@ void ImportExcel8::EndSheet( void ) void ImportExcel8::PostDocLoad( void ) { + // delay reading basic until sheet object ( codenames etc. ) are read + + if ( bHasBasic ) + ReadBasic(); // #i11776# filtered ranges before outlines and hidden rows if( pExcRoot->pAutoFilterBuffer ) pExcRoot->pAutoFilterBuffer->Apply(); diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx index 637a4777c8ed..5b9cc3180699 100644 --- a/sc/source/filter/excel/read.cxx +++ b/sc/source/filter/excel/read.cxx @@ -986,7 +986,7 @@ FltError ImportExcel8::Read( void ) case 0x22: Rec1904(); break; // 1904 [ 2345 ] case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ] case 0x8D: Hideobj(); break; // HIDEOBJ [ 345 ] - case 0xD3: ReadBasic(); break; + case 0xD3: bHasBasic = true; break; case 0xDE: Olesize(); break; case 0x01BA: Codename( TRUE ); break; diff --git a/sc/source/filter/excel/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx index 64ed79e3d3b2..3d055d94a498 100644 --- a/sc/source/filter/excel/xiescher.cxx +++ b/sc/source/filter/excel/xiescher.cxx @@ -478,14 +478,14 @@ void XclImpDrawObjBase::PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrOb { if( ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( &rSdrObj, TRUE ) ) { - pInfo->SetMacro( XclControlHelper::GetScMacroName( maMacroName ) ); + pInfo->SetMacro( XclControlHelper::GetScMacroName( maMacroName, GetDocShell() ) ); pInfo->SetHlink( maHyperlink ); } } #else if( mbSimpleMacro && (maMacroName.Len() > 0) ) if( ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( &rSdrObj, TRUE ) ) - pInfo->SetMacro( XclControlHelper::GetScMacroName( maMacroName ) ); + pInfo->SetMacro( XclControlHelper::GetScMacroName( maMacroName, GetDocShell() ) ); #endif // call virtual function for object type specific processing @@ -1947,7 +1947,7 @@ void XclImpTbxObjBase::SetDffProperties( const DffPropSet& rDffPropSet ) bool XclImpTbxObjBase::FillMacroDescriptor( ScriptEventDescriptor& rDescriptor ) const { - return XclControlHelper::FillMacroDescriptor( rDescriptor, DoGetEventType(), GetMacroName() ); + return XclControlHelper::FillMacroDescriptor( rDescriptor, DoGetEventType(), GetMacroName(), GetDocShell() ); } void XclImpTbxObjBase::ConvertFont( ScfPropertySet& rPropSet ) const diff --git a/sc/source/filter/excel/xlescher.cxx b/sc/source/filter/excel/xlescher.cxx index 538fd7fd7242..e1132c1b5606 100644 --- a/sc/source/filter/excel/xlescher.cxx +++ b/sc/source/filter/excel/xlescher.cxx @@ -35,6 +35,7 @@ #include "document.hxx" #include "xistream.hxx" #include "xlescher.hxx" +#include <filter/msfilter/msvbahelper.hxx> using ::rtl::OUString; using ::com::sun::star::uno::Reference; @@ -328,10 +329,16 @@ Reference< XControlModel > XclControlHelper::GetControlModel( Reference< XShape #define EXC_MACRONAME_PRE "vnd.sun.star.script:Standard." #define EXC_MACRONAME_SUF "?language=Basic&location=document" -OUString XclControlHelper::GetScMacroName( const String& rXclMacroName ) +OUString XclControlHelper::GetScMacroName( const String& rXclMacroName, SfxObjectShell* pDocShell ) { + String sTmp( rXclMacroName ); if( rXclMacroName.Len() > 0 ) - return CREATE_OUSTRING( EXC_MACRONAME_PRE ) + rXclMacroName + CREATE_OUSTRING( EXC_MACRONAME_SUF ); + { + ooo::vba::VBAMacroResolvedInfo aMacro = ooo::vba::resolveVBAMacro( pDocShell, rXclMacroName, false ); + if ( aMacro.IsResolved() ) + return ooo::vba::makeMacroURL( aMacro.ResolvedMacro() ); + + } return OUString(); } @@ -365,14 +372,14 @@ spTbxListenerData[] = #define EXC_MACROSCRIPT "Script" bool XclControlHelper::FillMacroDescriptor( ScriptEventDescriptor& rDescriptor, - XclTbxEventType eEventType, const String& rXclMacroName ) + XclTbxEventType eEventType, const String& rXclMacroName, SfxObjectShell* pShell ) { if( rXclMacroName.Len() > 0 ) { rDescriptor.ListenerType = OUString::createFromAscii( spTbxListenerData[ eEventType ].mpcListenerType ); rDescriptor.EventMethod = OUString::createFromAscii( spTbxListenerData[ eEventType ].mpcEventMethod ); rDescriptor.ScriptType = CREATE_OUSTRING( EXC_MACROSCRIPT ); - rDescriptor.ScriptCode = GetScMacroName( rXclMacroName ); + rDescriptor.ScriptCode = GetScMacroName( rXclMacroName, pShell ); return true; } return false; diff --git a/sc/source/filter/html/htmlpars.cxx b/sc/source/filter/html/htmlpars.cxx index 2716dc216ed1..7b0652e7cce9 100644 --- a/sc/source/filter/html/htmlpars.cxx +++ b/sc/source/filter/html/htmlpars.cxx @@ -2562,8 +2562,9 @@ void ScHTMLTable::SetDocSize( ScHTMLOrient eOrient, SCCOLROW nCellPos, SCCOLROW while( nIndex >= rSizes.size() ) rSizes.push_back( rSizes.empty() ? 1 : (rSizes.back() + 1) ); // update size of passed position and all following + // #i109987# only grow, don't shrink - use the largest needed size SCsCOLROW nDiff = nSize - ((nIndex == 0) ? rSizes.front() : (rSizes[ nIndex ] - rSizes[ nIndex - 1 ])); - if( nDiff != 0 ) + if( nDiff > 0 ) for( ScSizeVec::iterator aIt = rSizes.begin() + nIndex, aEnd = rSizes.end(); aIt != aEnd; ++aIt ) *aIt += nDiff; } diff --git a/sc/source/filter/inc/xlescher.hxx b/sc/source/filter/inc/xlescher.hxx index 33b75af8cd2c..95a87b51de12 100644 --- a/sc/source/filter/inc/xlescher.hxx +++ b/sc/source/filter/inc/xlescher.hxx @@ -432,7 +432,7 @@ public: GetControlModel( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape ); /** Returns the Calc macro name from an Excel macro name. */ - static ::rtl::OUString GetScMacroName( const String& rXclMacroName ); + static ::rtl::OUString GetScMacroName( const String& rXclMacroName, SfxObjectShell* pShell = NULL ); /** Returns the Excel macro name from a Calc macro name. */ static String GetXclMacroName( const ::rtl::OUString& rScMacroName ); @@ -440,7 +440,7 @@ public: static bool FillMacroDescriptor( ::com::sun::star::script::ScriptEventDescriptor& rDescriptor, XclTbxEventType eEventType, - const String& rXclMacroName ); + const String& rXclMacroName, SfxObjectShell* pShell = NULL ); /** Tries to extract an Excel macro name from the passed macro descriptor. */ static String ExtractFromMacroDescriptor( const ::com::sun::star::script::ScriptEventDescriptor& rDescriptor, diff --git a/sc/source/filter/xml/sheetdata.cxx b/sc/source/filter/xml/sheetdata.cxx index 66b1c2579dd4..947c1370fa4b 100644 --- a/sc/source/filter/xml/sheetdata.cxx +++ b/sc/source/filter/xml/sheetdata.cxx @@ -43,7 +43,8 @@ ScSheetSaveData::ScSheetSaveData() : mnStartTab( -1 ), mnStartOffset( -1 ), - maPreviousNote( rtl::OUString(), rtl::OUString(), ScAddress(ScAddress::INITIALIZE_INVALID) ) + maPreviousNote( rtl::OUString(), rtl::OUString(), ScAddress(ScAddress::INITIALIZE_INVALID) ), + mbInSupportedSave( false ) { } @@ -270,3 +271,13 @@ bool ScSheetSaveData::AddLoadedNamespaces( SvXMLNamespaceMap& rNamespaces ) cons return true; // success } +bool ScSheetSaveData::IsInSupportedSave() const +{ + return mbInSupportedSave; +} + +void ScSheetSaveData::SetInSupportedSave( bool bSet ) +{ + mbInSupportedSave = bSet; +} + diff --git a/sc/source/filter/xml/xmlwrap.cxx b/sc/source/filter/xml/xmlwrap.cxx index fde7f00bb05a..f21ed7d55ac2 100644 --- a/sc/source/filter/xml/xmlwrap.cxx +++ b/sc/source/filter/xml/xmlwrap.cxx @@ -78,6 +78,8 @@ #include "globstr.hrc" #include "scerrors.hxx" #include "XMLExportSharedData.hxx" +#include "docuno.hxx" +#include "sheetdata.hxx" #define MAP_LEN(x) x, sizeof(x) - 1 @@ -738,16 +740,23 @@ sal_Bool ScXMLImportWrapper::ExportToComponent(uno::Reference<lang::XMultiServic uno::Reference<embed::XStorage> xTmpStorage = rDoc.GetDocumentShell()->GetStorage(); uno::Reference<io::XStream> xSrcStream; uno::Reference<io::XInputStream> xSrcInput; - try - { - if (xTmpStorage.is()) - xSrcStream = xTmpStorage->openStreamElement( sName, embed::ElementModes::READ ); - if (xSrcStream.is()) - xSrcInput = xSrcStream->getInputStream(); - } - catch (uno::Exception&) + + // #i108978# If an embedded object is saved and no events are notified, don't use the stream + // because without the ...DONE events, stream positions aren't updated. + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xModel)->GetSheetSaveData(); + if (pSheetData && pSheetData->IsInSupportedSave()) { - // stream not available (for example, password protected) - save normally (xSrcInput is null) + try + { + if (xTmpStorage.is()) + xSrcStream = xTmpStorage->openStreamElement( sName, embed::ElementModes::READ ); + if (xSrcStream.is()) + xSrcInput = xSrcStream->getInputStream(); + } + catch (uno::Exception&) + { + // stream not available (for example, password protected) - save normally (xSrcInput is null) + } } pExport->SetSourceStream( xSrcInput ); @@ -755,7 +764,10 @@ sal_Bool ScXMLImportWrapper::ExportToComponent(uno::Reference<lang::XMultiServic pExport->SetSourceStream( uno::Reference<io::XInputStream>() ); // If there was an error, reset all stream flags, so the next save attempt will use normal saving. - if (!bRet) + // #i110692# For embedded objects, the stream may be unavailable for one save operation (m_pAntiImpl) + // and become available again later. But after saving normally once, the stream positions aren't + // valid anymore, so the flags also have to be reset if the stream wasn't available. + if ( !bRet || !xSrcInput.is() ) { SCTAB nTabCount = rDoc.GetTableCount(); for (SCTAB nTab=0; nTab<nTabCount; nTab++) diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx index 485ea4b88589..40b65ce401ad 100644 --- a/sc/source/ui/app/inputhdl.cxx +++ b/sc/source/ui/app/inputhdl.cxx @@ -189,6 +189,14 @@ handle_r1c1: if ( (nFlags & SCA_TAB2_3D) == 0 ) aRange.aEnd.SetTab( aRange.aStart.Tab() ); + if ( ( nFlags & ( SCA_VALID_COL2 | SCA_VALID_ROW2 | SCA_VALID_TAB2 ) ) == 0 ) + { + // #i73766# if a single ref was parsed, set the same "abs" flags for ref2, + // so Format doesn't output a double ref because of different flags. + USHORT nAbsFlags = nFlags & ( SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE ); + nFlags |= nAbsFlags << 4; + } + if (!nCount) { pEngine->SetUpdateMode( FALSE ); diff --git a/sc/source/ui/dbgui/filtdlg.cxx b/sc/source/ui/dbgui/filtdlg.cxx index 56878f623828..b5dd2f3242c2 100644 --- a/sc/source/ui/dbgui/filtdlg.cxx +++ b/sc/source/ui/dbgui/filtdlg.cxx @@ -448,24 +448,27 @@ void ScFilterDlg::UpdateValueList( USHORT nList ) SCCOL nColumn = theQueryData.nCol1 + static_cast<SCCOL>(nFieldSelPos) - 1; if (!pEntryLists[nColumn]) { + USHORT nOffset = GetSliderPos(); SCTAB nTab = nSrcTab; SCROW nFirstRow = theQueryData.nRow1; SCROW nLastRow = theQueryData.nRow2; + mbHasDates[nOffset+nList-1] = false; // erstmal ohne die erste Zeile pEntryLists[nColumn] = new TypedScStrCollection( 128, 128 ); pEntryLists[nColumn]->SetCaseSensitive( aBtnCase.IsChecked() ); pDoc->GetFilterEntriesArea( nColumn, nFirstRow+1, nLastRow, - nTab, *pEntryLists[nColumn] ); + nTab, *pEntryLists[nColumn], mbHasDates[nOffset+nList-1] ); // Eintrag fuer die erste Zeile //! Eintrag (pHdrEntry) ohne Collection erzeugen? nHeaderPos[nColumn] = USHRT_MAX; TypedScStrCollection aHdrColl( 1, 1 ); + bool bDummy = false; pDoc->GetFilterEntriesArea( nColumn, nFirstRow, nFirstRow, - nTab, aHdrColl ); + nTab, aHdrColl, bDummy ); TypedStrData* pHdrEntry = aHdrColl[0]; if ( pHdrEntry ) { @@ -1061,7 +1064,8 @@ IMPL_LINK( ScFilterDlg, ValModifyHdl, ComboBox*, pEd ) static_cast<SCCOL>(nField) - 1) : static_cast<SCCOL>(0); ScQueryOp eOp = (ScQueryOp)pLbCond->GetSelectEntryPos(); - rEntry.eOp = eOp; + rEntry.eOp = eOp; + rEntry.bQueryByDate = mbHasDates[nQE]; } } diff --git a/sc/source/ui/dbgui/makefile.mk b/sc/source/ui/dbgui/makefile.mk index 2d4fa71f690e..1e7000d0cb07 100644 --- a/sc/source/ui/dbgui/makefile.mk +++ b/sc/source/ui/dbgui/makefile.mk @@ -106,7 +106,6 @@ LIB1OBJFILES = \ $(SLO)$/expftext.obj \ $(SLO)$/fieldwnd.obj \ $(SLO)$/pvlaydlg.obj \ - $(SLO)$/pvfundlg.obj \ $(SLO)$/consdlg.obj \ $(SLO)$/imoptdlg.obj \ $(SLO)$/csvsplits.obj \ diff --git a/sc/source/ui/dbgui/pfiltdlg.cxx b/sc/source/ui/dbgui/pfiltdlg.cxx index cde18fcc3b52..d590ffb83457 100644 --- a/sc/source/ui/dbgui/pfiltdlg.cxx +++ b/sc/source/ui/dbgui/pfiltdlg.cxx @@ -349,11 +349,12 @@ void ScPivotFilterDlg::UpdateValueList( USHORT nList ) SCROW nFirstRow = theQueryData.nRow1; SCROW nLastRow = theQueryData.nRow2; nFirstRow++; + bool bHasDates = false; pEntryLists[nColumn] = new TypedScStrCollection( 128, 128 ); pEntryLists[nColumn]->SetCaseSensitive( aBtnCase.IsChecked() ); pDoc->GetFilterEntriesArea( nColumn, nFirstRow, nLastRow, - nTab, *pEntryLists[nColumn] ); + nTab, *pEntryLists[nColumn], bHasDates ); } TypedScStrCollection* pColl = pEntryLists[nColumn]; diff --git a/sc/source/ui/dbgui/pvfundlg.cxx b/sc/source/ui/dbgui/pvfundlg.cxx index 03de0b8914a3..6b04993ba0bc 100644 --- a/sc/source/ui/dbgui/pvfundlg.cxx +++ b/sc/source/ui/dbgui/pvfundlg.cxx @@ -28,6 +28,8 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" +#undef SC_DLLIMPLEMENTATION + #include "pvfundlg.hxx" #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp> diff --git a/sc/source/ui/dbgui/validate.cxx b/sc/source/ui/dbgui/validate.cxx index 5fdf386323d9..1ee02badefe1 100644 --- a/sc/source/ui/dbgui/validate.cxx +++ b/sc/source/ui/dbgui/validate.cxx @@ -581,7 +581,7 @@ void ScTPValidationValue::TidyListBoxes() pWnd = GetChild(0); - while( std::find( alstOrder.begin(), alstOrder.end(), pWnd ) != alstOrder.end() && NULL != ( pWnd = pWnd->GetWindow( WINDOW_NEXT) ) ); + while( std::find( alstOrder.begin(), alstOrder.end(), pWnd ) != alstOrder.end() && NULL != ( pWnd = pWnd->GetWindow( WINDOW_NEXT) ) ) ; if ( pWnd ) { diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index cd28daa99401..01d03d49b50a 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -48,6 +48,12 @@ #include <svl/zforlist.hxx> #include <svl/PasswordHelper.hxx> +#include <basic/sbstar.hxx> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/script/XLibraryContainer.hpp> +#include <com/sun/star/script/XVBAModuleInfo.hpp> +#include <com/sun/star/script/ModuleType.hpp> + #include <list> #include "docfunc.hxx" @@ -94,6 +100,7 @@ #include "clipparam.hxx" #include <memory> +#include <basic/basmgr.hxx> using namespace com::sun::star; using ::com::sun::star::uno::Sequence; @@ -2576,6 +2583,106 @@ BOOL ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos, } //------------------------------------------------------------------------ +uno::Reference< uno::XInterface > GetDocModuleObject( SfxObjectShell& rDocSh, String& sCodeName ) +{ + uno::Reference< lang::XMultiServiceFactory> xSF(rDocSh.GetModel(), uno::UNO_QUERY); + uno::Reference< container::XNameAccess > xVBACodeNamedObjectAccess; + uno::Reference< uno::XInterface > xDocModuleApiObject; + if ( xSF.is() ) + { + xVBACodeNamedObjectAccess.set( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAObjectModuleObjectProvider"))), uno::UNO_QUERY ); + xDocModuleApiObject.set( xVBACodeNamedObjectAccess->getByName( sCodeName ), uno::UNO_QUERY ); + } + return xDocModuleApiObject; + +} + +script::ModuleInfo lcl_InitModuleInfo( SfxObjectShell& rDocSh, String& sModule ) +{ + ::rtl::OUString sVbaOption( RTL_CONSTASCII_USTRINGPARAM( "Rem Attribute VBA_ModuleType=VBADocumentModule\nOption VBASupport 1\n" )); + script::ModuleInfo sModuleInfo; + sModuleInfo.ModuleType = script::ModuleType::DOCUMENT; + sModuleInfo.ModuleObject = GetDocModuleObject( rDocSh, sModule ); + return sModuleInfo; +} + +void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, String& sModuleName, String& sSource ) +{ + SFX_APP()->EnterBasicCall(); + SfxObjectShell& rDocSh = *rDoc.GetDocumentShell(); + uno::Reference< script::XLibraryContainer > xLibContainer = rDocSh.GetBasicContainer(); + DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" ); + + uno::Reference< container::XNameContainer > xLib; + if( xLibContainer.is() ) + { + String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) ); + if ( rDocSh.GetBasicManager() && rDocSh.GetBasicManager()->GetName().Len() ) + aLibName = rDocSh.GetBasicManager()->GetName(); + uno::Any aLibAny = xLibContainer->getByName( aLibName ); + aLibAny >>= xLib; + } + if( xLib.is() ) + { + // if the Module with codename exists then find a new name + sal_Int32 nNum = 0; + String genModuleName; + if ( sModuleName.Len() ) + sModuleName = sModuleName; + else + { + genModuleName = String::CreateFromAscii( "Sheet1" ); + nNum = 1; + } + while( xLib->hasByName( genModuleName ) ) + genModuleName = rtl::OUString::createFromAscii( "Sheet" ) + rtl::OUString::valueOf( ++nNum ); + + uno::Any aSourceAny; + rtl::OUString sTmpSource = sSource; + if ( sTmpSource.getLength() == 0 ) + sTmpSource = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Rem Attribute VBA_ModuleType=VBADocumentModule\nOption VBASupport 1\n" )); + aSourceAny <<= sTmpSource; + uno::Reference< script::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY ); + if ( xVBAModuleInfo.is() ) + { + String sCodeName( genModuleName ); + rDoc.SetCodeName( nTab, sCodeName ); + script::ModuleInfo sModuleInfo = lcl_InitModuleInfo( rDocSh, genModuleName ); + xVBAModuleInfo->insertModuleInfo( genModuleName, sModuleInfo ); + xLib->insertByName( genModuleName, aSourceAny ); + } + + } + SFX_APP()->LeaveBasicCall(); +} + +void VBA_DeleteModule( ScDocShell& rDocSh, String& sModuleName ) +{ + SFX_APP()->EnterBasicCall(); + uno::Reference< script::XLibraryContainer > xLibContainer = rDocSh.GetBasicContainer(); + DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" ); + + uno::Reference< container::XNameContainer > xLib; + if( xLibContainer.is() ) + { + String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) ); + if ( rDocSh.GetBasicManager() && rDocSh.GetBasicManager()->GetName().Len() ) + aLibName = rDocSh.GetBasicManager()->GetName(); + uno::Any aLibAny = xLibContainer->getByName( aLibName ); + aLibAny >>= xLib; + } + if( xLib.is() ) + { + uno::Reference< script::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY ); + if( xLib->hasByName( sModuleName ) ) + xLib->removeByName( sModuleName ); + if ( xVBAModuleInfo.is() ) + xVBAModuleInfo->removeModuleInfo( sModuleName ); + + } + SFX_APP()->LeaveBasicCall(); +} + BOOL ScDocFunc::InsertTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL bApi ) { @@ -2585,8 +2692,19 @@ BOOL ScDocFunc::InsertTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL ScDocShellModificator aModificator( rDocShell ); ScDocument* pDoc = rDocShell.GetDocument(); - if (bRecord && !pDoc->IsUndoEnabled()) + + + // Strange loop, also basic is loaded too early ( InsertTable ) + // is called via the xml import for sheets in described in odf + BOOL bInsertDocModule = false; + + if( !rDocShell.GetDocument()->IsImportingXML() ) + { + bInsertDocModule = pDoc ? pDoc->IsInVBAMode() : false; + } + if ( bInsertDocModule || ( bRecord && !pDoc->IsUndoEnabled() ) ) bRecord = FALSE; + if (bRecord) pDoc->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage @@ -2597,10 +2715,17 @@ BOOL ScDocFunc::InsertTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL if (pDoc->InsertTab( nTab, rName )) { + String sCodeName; if (bRecord) rDocShell.GetUndoManager()->AddUndoAction( new ScUndoInsertTab( &rDocShell, nTab, bAppend, rName)); // Views updaten: + // Only insert vba modules if vba mode ( and not currently importing XML ) + if( bInsertDocModule ) + { + String sSource; + VBA_InsertModule( *pDoc, nTab, sCodeName, sSource ); + } rDocShell.Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab ) ); rDocShell.PostPaintExtras(); @@ -2622,8 +2747,11 @@ BOOL ScDocFunc::DeleteTable( SCTAB nTab, BOOL bRecord, BOOL /* bApi */ ) BOOL bSuccess = FALSE; ScDocument* pDoc = rDocShell.GetDocument(); + BOOL bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : false; if (bRecord && !pDoc->IsUndoEnabled()) bRecord = FALSE; + if ( bVbaEnabled ) + bRecord = FALSE; BOOL bWasLinked = pDoc->IsLinked(nTab); ScDocument* pUndoDoc = NULL; ScRefUndoData* pUndoData = NULL; @@ -2664,6 +2792,8 @@ BOOL ScDocFunc::DeleteTable( SCTAB nTab, BOOL bRecord, BOOL /* bApi */ ) pUndoData = new ScRefUndoData( pDoc ); } + String sCodeName; + BOOL bHasCodeName = pDoc->GetCodeName( nTab, sCodeName ); if (pDoc->DeleteTab( nTab, pUndoDoc )) { if (bRecord) @@ -2674,6 +2804,13 @@ BOOL ScDocFunc::DeleteTable( SCTAB nTab, BOOL bRecord, BOOL /* bApi */ ) new ScUndoDeleteTab( &rDocShell, theTabs, pUndoDoc, pUndoData )); } // Views updaten: + if( bVbaEnabled ) + { + if( bHasCodeName ) + { + VBA_DeleteModule( rDocShell, sCodeName ); + } + } rDocShell.Broadcast( ScTablesHint( SC_TAB_DELETED, nTab ) ); if (bWasLinked) diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index 821b2a6ad880..135bbcdace49 100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -356,6 +356,7 @@ void ScDocShell::AfterXMLLoading(sal_Bool bRet) } else aDocument.SetInsertingFromOtherDoc( FALSE ); +#if 0 // disable load of vba related libraries // add vba globals ( if they are availabl ) uno::Any aGlobs; uno::Sequence< uno::Any > aArgs(1); @@ -376,7 +377,7 @@ void ScDocShell::AfterXMLLoading(sal_Bool bRet) BasicManager* pAppMgr = SFX_APP()->GetBasicManager(); if ( pAppMgr ) pAppMgr->SetGlobalUNOConstant( "ThisExcelDoc", aArgs[ 0 ] ); - +#endif aDocument.SetImportingXML( FALSE ); aDocument.EnableExecuteLink( true ); aDocument.EnableUndo( TRUE ); @@ -767,19 +768,38 @@ void __EXPORT ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint ) if ( !bSuccess ) SetError( ERRCODE_IO_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); // this error code will produce no error message, but will break the further saving process } + if (pSheetSaveData) + pSheetSaveData->SetInSupportedSave(true); } break; + case SFX_EVENT_SAVEASDOC: + case SFX_EVENT_SAVETODOC: + // #i108978# If no event is sent before saving, there will also be no "...DONE" event, + // and SAVE/SAVEAS can't be distinguished from SAVETO. So stream copying is only enabled + // if there is a SAVE/SAVEAS/SAVETO event first. + if (pSheetSaveData) + pSheetSaveData->SetInSupportedSave(true); + break; case SFX_EVENT_SAVEDOCDONE: { if ( IsDocShared() && !SC_MOD()->IsInSharedDocSaving() ) { } UseSheetSaveEntries(); // use positions from saved file for next saving + if (pSheetSaveData) + pSheetSaveData->SetInSupportedSave(false); } break; case SFX_EVENT_SAVEASDOCDONE: // new positions are used after "save" and "save as", but not "save to" UseSheetSaveEntries(); // use positions from saved file for next saving + if (pSheetSaveData) + pSheetSaveData->SetInSupportedSave(false); + break; + case SFX_EVENT_SAVETODOCDONE: + // only reset the flag, don't use the new positions + if (pSheetSaveData) + pSheetSaveData->SetInSupportedSave(false); break; default: { diff --git a/sc/source/ui/docshell/docsh2.cxx b/sc/source/ui/docshell/docsh2.cxx index 4b76c18edbe6..9e3ed217382f 100644 --- a/sc/source/ui/docshell/docsh2.cxx +++ b/sc/source/ui/docshell/docsh2.cxx @@ -102,6 +102,7 @@ BOOL __EXPORT ScDocShell::InitNew( const uno::Reference < embed::XStorage >& xSt InitItems(); CalcOutputFactor(); +#if 0 uno::Any aGlobs; uno::Sequence< uno::Any > aArgs(1); aArgs[ 0 ] <<= GetModel(); @@ -121,6 +122,7 @@ BOOL __EXPORT ScDocShell::InitNew( const uno::Reference < embed::XStorage >& xSt BasicManager* pAppMgr = SFX_APP()->GetBasicManager(); if ( pAppMgr ) pAppMgr->SetGlobalUNOConstant( "ThisExcelDoc", aArgs[ 0 ] ); +#endif return bRet; } diff --git a/sc/source/ui/docshell/docsh5.cxx b/sc/source/ui/docshell/docsh5.cxx index 1bbf9437bc1c..84979e3dbcdf 100644 --- a/sc/source/ui/docshell/docsh5.cxx +++ b/sc/source/ui/docshell/docsh5.cxx @@ -65,6 +65,11 @@ #include "sc.hrc" #include "waitoff.hxx" #include "sizedev.hxx" +#include <basic/sbstar.hxx> +#include <basic/basmgr.hxx> + +// defined in docfunc.cxx +void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, String& sModuleName, String& sModuleSource ); // --------------------------------------------------------------------------- @@ -97,8 +102,9 @@ void ScDocShell::ErrorMessage( USHORT nGlobStrId ) BOOL ScDocShell::IsEditable() const { // import into read-only document is possible - must be extended if other filters use api + // #i108547# MSOOXML filter uses "IsChangeReadOnlyEnabled" property - return !IsReadOnly() || aDocument.IsImportingXML(); + return !IsReadOnly() || aDocument.IsImportingXML() || aDocument.IsChangeReadOnlyEnabled(); } void ScDocShell::DBAreaDeleted( SCTAB nTab, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW /* nY2 */ ) @@ -865,6 +871,8 @@ BOOL ScDocShell::MoveTable( SCTAB nSrcTab, SCTAB nDestTab, BOOL bCopy, BOOL bRec if (bRecord) aDocument.BeginDrawUndo(); // drawing layer must do its own undo actions + String sSrcCodeName; + aDocument.GetCodeName( nSrcTab, sSrcCodeName ); if (!aDocument.CopyTab( nSrcTab, nDestTab )) { //! EndDrawUndo? @@ -888,8 +896,38 @@ BOOL ScDocShell::MoveTable( SCTAB nSrcTab, SCTAB nDestTab, BOOL bCopy, BOOL bRec GetUndoManager()->AddUndoAction( new ScUndoCopyTab( this, aSrcList, aDestList ) ); } - } + BOOL bVbaEnabled = aDocument.IsInVBAMode(); + if ( bVbaEnabled ) + { + StarBASIC* pStarBASIC = GetBasic(); + String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) ); + if ( GetBasicManager()->GetName().Len() > 0 ) + { + aLibName = GetBasicManager()->GetName(); + pStarBASIC = GetBasicManager()->GetLib( aLibName ); + } + SCTAB nTabToUse = nDestTab; + if ( nDestTab == SC_TAB_APPEND ) + nTabToUse = aDocument.GetMaxTableNumber() - 1; + String sCodeName; + String sSource; + com::sun::star::uno::Reference< com::sun::star::script::XLibraryContainer > xLibContainer = GetBasicContainer(); + com::sun::star::uno::Reference< com::sun::star::container::XNameContainer > xLib; + if( xLibContainer.is() ) + { + com::sun::star::uno::Any aLibAny = xLibContainer->getByName( aLibName ); + aLibAny >>= xLib; + } + if( xLib.is() ) + { + rtl::OUString sRTLSource; + xLib->getByName( sSrcCodeName ) >>= sRTLSource; + sSource = sRTLSource; + } + VBA_InsertModule( aDocument, nTabToUse, sCodeName, sSource ); + } + } Broadcast( ScTablesHint( SC_TAB_COPIED, nSrcTab, nDestTab ) ); } else diff --git a/sc/source/ui/drawfunc/drformsh.src b/sc/source/ui/drawfunc/drformsh.src index b20ceb9841a5..65e98eea7b2c 100644 --- a/sc/source/ui/drawfunc/drformsh.src +++ b/sc/source/ui/drawfunc/drformsh.src @@ -117,12 +117,14 @@ {\ MenuItem\ {\ + RadioCheck = TRUE ; \ Identifier = SID_ANCHOR_PAGE ; \ HelpId = SID_ANCHOR_PAGE ; \ Text [ en-US ] = "To P~age" ; \ };\ MenuItem\ {\ + RadioCheck = TRUE ; \ Identifier = SID_ANCHOR_CELL ; \ HelpId = SID_ANCHOR_CELL ; \ Text [ en-US ] = "To ~Cell" ; \ diff --git a/sc/source/ui/drawfunc/objdraw.src b/sc/source/ui/drawfunc/objdraw.src index 0cd8fdd54e4b..82649044b38c 100644 --- a/sc/source/ui/drawfunc/objdraw.src +++ b/sc/source/ui/drawfunc/objdraw.src @@ -339,6 +339,7 @@ {\ MenuItem\ {\ + RadioCheck = TRUE ; \ Identifier = SID_ANCHOR_PAGE ; \ HelpId = SID_ANCHOR_PAGE ; \ Text [ en-US ] = "To P~age" ; \ @@ -346,6 +347,7 @@ };\ MenuItem\ {\ + RadioCheck = TRUE ; \ Identifier = SID_ANCHOR_CELL ; \ HelpId = SID_ANCHOR_CELL ; \ Text [ en-US ] = "To ~Cell" ; \ diff --git a/sc/source/ui/inc/filtdlg.hxx b/sc/source/ui/inc/filtdlg.hxx index 068a48b8d689..31e0e3a5d4b1 100644 --- a/sc/source/ui/inc/filtdlg.hxx +++ b/sc/source/ui/inc/filtdlg.hxx @@ -164,6 +164,7 @@ private: ListBox* aFieldLbArr[4]; ListBox* aCondLbArr[4]; ListBox* aConnLbArr[4]; + bool mbHasDates[MAXQUERY]; BOOL bRefreshExceptQuery[MAXQUERY]; USHORT nFieldCount; BOOL bRefInputMode; diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx index 149498a8314d..4d6ef782aed6 100644 --- a/sc/source/ui/inc/gridwin.hxx +++ b/sc/source/ui/inc/gridwin.hxx @@ -215,7 +215,7 @@ private: BOOL IsAutoFilterActive( SCCOL nCol, SCROW nRow, SCTAB nTab ); void ExecFilter( ULONG nSel, SCCOL nCol, SCROW nRow, - const String& aValue ); + const String& aValue, bool bCheckForDates ); void FilterSelect( ULONG nSel ); void ExecDataSelect( SCCOL nCol, SCROW nRow, const String& rStr ); diff --git a/sc/source/ui/src/scfuncs.src b/sc/source/ui/src/scfuncs.src index 18adf9883373..2f5a2d8c88fb 100644 --- a/sc/source/ui/src/scfuncs.src +++ b/sc/source/ui/src/scfuncs.src @@ -1024,7 +1024,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1 }; String 3 // Description of Parameter 1 { - Text [ en-US ] = "An interger between 1583 and 9956, or 0 and 99 (19xx or 20xx depending on the option set)."; + Text [ en-US ] = "An integer between 1583 and 9956, or 0 and 99 (19xx or 20xx depending on the option set)."; }; }; // -=*# Resource for function BW #*=- @@ -1576,7 +1576,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1 { String 1 // Description { - Text [ en-US ] = "Calulates the arithmetically declining value of an asset (depreciation) for a specified period." ; + Text [ en-US ] = "Calculates the arithmetically declining value of an asset (depreciation) for a specified period." ; }; ExtraData = { @@ -4064,7 +4064,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1 { String 1 // Description { - Text [ en-US ] = "Array transposition. Exchanges the rows and columns of an aray." ; + Text [ en-US ] = "Array transposition. Exchanges the rows and columns of an array." ; }; ExtraData = { @@ -4724,7 +4724,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2 }; String 3 // Description of Parameter 1 { - Text [ en-US ] = "Value 1; value 2;.. .are 1 to 30 arguments representing a sample taken from a basic total population."; + Text [ en-US ] = "Value 1; value 2; ... are 1 to 30 arguments representing a sample taken from a basic total population."; }; }; // -=*# Resource for function VARIANZEN #*=- @@ -4820,7 +4820,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2 }; String 3 // Description of Parameter 1 { - Text [ en-US ] = "Value 1; value 2;.. .are 1 to 30 arguments representing a sample taken from a basic total population."; + Text [ en-US ] = "Value 1; value 2; ... are 1 to 30 arguments representing a sample taken from a basic total population."; }; }; // -=*# Resource for function STABWN #*=- @@ -4916,7 +4916,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2 }; String 3 // Description of Parameter 1 { - Text [ en-US ] = "Value 1; value 2;.. .are 1 to 30 arguments representing a sample taken from a basic total population."; + Text [ en-US ] = "Value 1; value 2; ... are 1 to 30 arguments representing a sample taken from a basic total population."; }; }; // -=*# Resource for function SUMQUADABW #*=- @@ -6358,7 +6358,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2 }; String 7 // Description of Parameter 3 { - Text [ en-US ] = "Mode = 1calculates the one-tailed test, 2 = two-tailed distribution." ; + Text [ en-US ] = "Mode = 1 calculates the one-tailed test, 2 = two-tailed distribution." ; }; }; // -=*# Resource for function TINV #*=- @@ -7525,7 +7525,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2 }; String 9 // Description of Parameter 4 { - Text [ en-US ] = "if the value is TRUE or not given, the search column of the array must be sorted in ascending order." ; + Text [ en-US ] = "If the value is TRUE or not given, the search column of the array must be sorted in ascending order." ; }; }; // -=*# Resource for function INDEX #*=- @@ -8397,7 +8397,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2 { String 1 // Description { - Text [ en-US ] = "Converts a value into text." ; + Text [ en-US ] = "Returns a value if it is text, otherwise an empty string." ; }; ExtraData = { @@ -8413,7 +8413,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2 }; String 3 // Description of Parameter 1 { - Text [ en-US ] = "The value to be converted." ; + Text [ en-US ] = "The value to be checked and returned if it is text." ; }; }; // -=*# Resource for function ERSETZEN #*=- @@ -8709,7 +8709,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2 }; String 9 // Description of Parameter 4 { - Text [ en-US ] = "Which occurence of the old text is to be replaced." ; + Text [ en-US ] = "Which occurrence of the old text is to be replaced." ; }; }; // -=*# Resource for function BASIS #*=- diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx index 4eddb447e8a9..afe29a8309a7 100644 --- a/sc/source/ui/unoobj/cellsuno.cxx +++ b/sc/source/ui/unoobj/cellsuno.cxx @@ -769,6 +769,7 @@ const SfxItemPropertySet* lcl_GetSheetPropertySet() {MAP_CHAR_LEN(SC_UNONAME_VALIXML), SC_WID_UNO_VALIXML, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 }, {MAP_CHAR_LEN(SC_UNONAME_CELLVJUS), ATTR_VER_JUSTIFY, &getCppuType((table::CellVertJustify*)0), 0, 0 }, {MAP_CHAR_LEN(SC_UNONAME_WRITING), ATTR_WRITINGDIR, &getCppuType((sal_Int16*)0), 0, 0 }, + {MAP_CHAR_LEN(SC_UNO_CODENAME), SC_WID_UNO_CODENAME, &getCppuType(static_cast< const rtl::OUString * >(0)), 0, 0}, {0,0,0,0,0,0} }; static SfxItemPropertySet aSheetPropertySet( aSheetPropertyMap_Impl ); @@ -7912,7 +7913,8 @@ void SAL_CALL ScTableSheetObj::protect( const rtl::OUString& aPassword ) { ScUnoGuard aGuard; ScDocShell* pDocSh = GetDocShell(); - if ( pDocSh ) + // #i108245# if already protected, don't change anything + if ( pDocSh && !pDocSh->GetDocument()->IsTabProtected( GetTab_Impl() ) ) { String aString(aPassword); ScDocFunc aFunc(*pDocSh); @@ -7929,9 +7931,9 @@ void SAL_CALL ScTableSheetObj::unprotect( const rtl::OUString& aPassword ) { String aString(aPassword); ScDocFunc aFunc(*pDocSh); - aFunc.Unprotect( GetTab_Impl(), aString, TRUE ); - - //! Rueckgabewert auswerten, Exception oder so + BOOL bDone = aFunc.Unprotect( GetTab_Impl(), aString, TRUE ); + if (!bDone) + throw lang::IllegalArgumentException(); } } @@ -8467,6 +8469,15 @@ void ScTableSheetObj::SetOnePropertyValue( const SfxItemPropertySimpleEntry* pEn pDoc->ClearPrintRanges( nTab ); // if this flag is true, there are no PrintRanges, so Clear clears only the flag. } } + else if ( pEntry->nWID == SC_WID_UNO_CODENAME ) + { + rtl::OUString aCodeName; + if ( pDocSh && ( aValue >>= aCodeName ) ) + { + String sNewName( aCodeName ); + pDocSh->GetDocument()->SetCodeName( GetTab_Impl(), sNewName ); + } + } else ScCellRangeObj::SetOnePropertyValue(pEntry, aValue); // base class, no Item WID } @@ -8605,6 +8616,13 @@ void ScTableSheetObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEn BOOL bAutoPrint = pDoc->IsPrintEntireSheet( nTab ); ScUnoHelpFunctions::SetBoolInAny( rAny, bAutoPrint ); } + else if ( pEntry->nWID == SC_WID_UNO_CODENAME ) + { + String aCodeName; + if ( pDocSh ) + pDocSh->GetDocument()->GetCodeName( GetTab_Impl(), aCodeName ); + rAny <<= rtl::OUString( aCodeName ); + } else ScCellRangeObj::GetOnePropertyValue(pEntry, rAny); } diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx index 7e23d6b2f9f5..c7bf89671161 100755 --- a/sc/source/ui/unoobj/dapiuno.cxx +++ b/sc/source/ui/unoobj/dapiuno.cxx @@ -1891,9 +1891,10 @@ void SAL_CALL ScDataPilotFieldObj::setPropertyValue( const OUString& aPropertyNa String aNameString(aPropertyName); if ( aNameString.EqualsAscii( SC_UNONAME_FUNCTION ) ) { - GeneralFunction eFunction = GeneralFunction_NONE; - if( aValue >>= eFunction ) - setFunction( eFunction ); + // #i109350# use GetEnumFromAny because it also allows sal_Int32 + GeneralFunction eFunction = (GeneralFunction) + ScUnoHelpFunctions::GetEnumFromAny( aValue ); + setFunction( eFunction ); } else if ( aNameString.EqualsAscii( SC_UNONAME_SUBTOTALS ) ) { diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index 8e857adca09c..e67103cf75e5 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -152,6 +152,7 @@ const SfxItemPropertyMapEntry* lcl_GetDocOptPropertyMap() {MAP_CHAR_LEN(SC_UNO_ISCHANGEREADONLYENABLED), 0, &getBooleanCppuType(), 0, 0}, {MAP_CHAR_LEN(SC_UNO_REFERENCEDEVICE), 0, &getCppuType((uno::Reference<awt::XDevice>*)0), beans::PropertyAttribute::READONLY, 0}, {MAP_CHAR_LEN("BuildId"), 0, &::getCppuType(static_cast< const rtl::OUString * >(0)), 0, 0}, + {MAP_CHAR_LEN(SC_UNO_CODENAME), 0, &getCppuType(static_cast< const rtl::OUString * >(0)), 0, 0}, {0,0,0,0,0,0} }; @@ -1392,7 +1393,8 @@ void SAL_CALL ScModelObj::enableAutomaticCalculation( sal_Bool bEnabled ) void SAL_CALL ScModelObj::protect( const rtl::OUString& aPassword ) throw(uno::RuntimeException) { ScUnoGuard aGuard; - if (pDocShell) + // #i108245# if already protected, don't change anything + if ( pDocShell && !pDocShell->GetDocument()->IsDocProtected() ) { String aString(aPassword); @@ -1410,9 +1412,9 @@ void SAL_CALL ScModelObj::unprotect( const rtl::OUString& aPassword ) String aString(aPassword); ScDocFunc aFunc(*pDocShell); - aFunc.Unprotect( TABLEID_DOC, aString, TRUE ); - - //! Rueckgabewert auswerten, Exception oder so + BOOL bDone = aFunc.Unprotect( TABLEID_DOC, aString, TRUE ); + if (!bDone) + throw lang::IllegalArgumentException(); } } @@ -1651,6 +1653,12 @@ void SAL_CALL ScModelObj::setPropertyValue( pDoc->SetLanguage( eLatin, eCjk, eCtl ); } } + else if ( aString.EqualsAscii( SC_UNO_CODENAME ) ) + { + rtl::OUString sCodeName; + if ( aValue >>= sCodeName ) + pDoc->SetCodeName( sCodeName ); + } else if ( aString.EqualsAscii( SC_UNO_CJK_CLOCAL ) ) { lang::Locale aLocale; @@ -1783,6 +1791,12 @@ uno::Any SAL_CALL ScModelObj::getPropertyValue( const rtl::OUString& aPropertyNa ScUnoConversion::FillLocale( aLocale, eLatin ); aRet <<= aLocale; } + else if ( aString.EqualsAscii( SC_UNO_CODENAME ) ) + { + rtl::OUString sCodeName = pDoc->GetCodeName(); + aRet <<= sCodeName; + } + else if ( aString.EqualsAscii( SC_UNO_CJK_CLOCAL ) ) { LanguageType eLatin, eCjk, eCtl; @@ -2074,6 +2088,13 @@ sal_Int64 SAL_CALL ScModelObj::getSomething( return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this)); } + if ( rId.getLength() == 16 && + 0 == rtl_compareMemory( SfxObjectShell::getUnoTunnelId().getConstArray(), + rId.getConstArray(), 16 ) ) + { + return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(pDocShell )); + } + // aggregated number formats supplier has XUnoTunnel, too // interface from aggregated object must be obtained via queryAggregation diff --git a/sc/source/ui/unoobj/servuno.cxx b/sc/source/ui/unoobj/servuno.cxx index 0c57963a4f12..0b3a6f01f9ea 100644 --- a/sc/source/ui/unoobj/servuno.cxx +++ b/sc/source/ui/unoobj/servuno.cxx @@ -37,6 +37,7 @@ #include <com/sun/star/sheet/XSpreadsheetDocument.hpp> #include "servuno.hxx" +#include "unoguard.hxx" #include "unonames.hxx" #include "cellsuno.hxx" #include "fielduno.hxx" @@ -65,8 +66,127 @@ #include <com/sun/star/form/XFormsSupplier.hpp> #include <svx/unomod.hxx> +#include <comphelper/processfactory.hxx> +#include <basic/basmgr.hxx> +#include <sfx2/app.hxx> + using namespace ::com::sun::star; +#ifndef CWS_NPOWER14MISCFIXES +uno::Reference< uno::XInterface > lcl_createVBAUnoAPIServiceWithArgs( SfxObjectShell* pShell, const sal_Char* _pAsciiName, const uno::Sequence< uno::Any >& aArgs ) throw (uno::RuntimeException) +{ + uno::Any aUnoVar; + if ( !pShell || !pShell->GetBasicManager()->GetGlobalUNOConstant( "VBAGlobals", aUnoVar ) ) + throw lang::IllegalArgumentException(); + uno::Reference< lang::XMultiServiceFactory > xVBAFactory( aUnoVar, uno::UNO_QUERY_THROW ); + ::rtl::OUString sVarName( ::rtl::OUString::createFromAscii( _pAsciiName ) ); + uno::Reference< uno::XInterface > xIf = xVBAFactory->createInstanceWithArguments( sVarName, aArgs ); + return xIf; +} +#endif + +class ScVbaObjectForCodeNameProvider : public ::cppu::WeakImplHelper1< container::XNameAccess > +{ + uno::Any maWorkbook; + uno::Any maCachedObject; + ScDocShell* mpDocShell; +public: + ScVbaObjectForCodeNameProvider( ScDocShell* pDocShell ) : mpDocShell( pDocShell ) + { + ScDocument* pDoc = mpDocShell->GetDocument(); + if ( !pDoc ) + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("")), uno::Reference< uno::XInterface >() ); + + uno::Sequence< uno::Any > aArgs(2); + aArgs[0] = uno::Any( uno::Reference< uno::XInterface >() ); + aArgs[1] = uno::Any( mpDocShell->GetModel() ); +#ifdef CWS_NPOWER14MISCFIXES + maWorkbook <<= ooo::vba::createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.excel.Workbook", aArgs ); +#else + maWorkbook <<= lcl_createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.excel.Workbook", aArgs ); +#endif + } + + virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException ) + { + ScUnoGuard aGuard; + maCachedObject = uno::Any(); // clear cached object + String sName = aName; + + ScDocument* pDoc = mpDocShell->GetDocument(); + if ( !pDoc ) + throw uno::RuntimeException(); + if ( sName == pDoc->GetCodeName() ) + maCachedObject = maWorkbook; + else + { + String sCodeName; + SCTAB nCount = pDoc->GetTableCount(); + for( SCTAB i = 0; i < nCount; i++ ) + { + pDoc->GetCodeName( i, sCodeName ); + if( sCodeName == sName ) + { + String sSheetName; + if( pDoc->GetName( i, sSheetName ) ) + { + uno::Reference< frame::XModel > xModel( mpDocShell->GetModel() ); + uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( xModel, uno::UNO_QUERY_THROW ); + uno::Reference<sheet::XSpreadsheets > xSheets( xSpreadDoc->getSheets(), uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xIndexAccess( xSheets, uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSpreadsheet > xSheet( xIndexAccess->getByIndex( i ), uno::UNO_QUERY_THROW ); + uno::Sequence< uno::Any > aArgs(3); + aArgs[0] = maWorkbook; + aArgs[1] = uno::Any( xModel ); + aArgs[2] = uno::Any( rtl::OUString( sSheetName ) ); +#ifdef CWS_NPOWER14MISCFIXES + // use the convience function + maCachedObject <<= ooo::vba::createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.excel.Worksheet", aArgs ); +#else + // use the temp function + maCachedObject <<= lcl_createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.excel.Worksheet", aArgs ); +#endif + break; + } + } + } + } + return maCachedObject.hasValue(); + + } + ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) + { + ScUnoGuard aGuard; + OSL_TRACE("ScVbaObjectForCodeNameProvider::getByName( %s )", + rtl::OUStringToOString( aName, RTL_TEXTENCODING_UTF8 ).getStr() ); + if ( !hasByName( aName ) ) + throw ::com::sun::star::container::NoSuchElementException(); + return maCachedObject; + } + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (::com::sun::star::uno::RuntimeException) + { + ScUnoGuard aGuard; + ScDocument* pDoc = mpDocShell->GetDocument(); + if ( !pDoc ) + throw uno::RuntimeException(); + SCTAB nCount = pDoc->GetTableCount(); + uno::Sequence< rtl::OUString > aNames( nCount + 1 ); + SCTAB index = 0; + String sCodeName; + for( ; index < nCount; ++index ) + { + pDoc->GetCodeName( index, sCodeName ); + aNames[ index ] = sCodeName; + } + aNames[ index ] = pDoc->GetCodeName(); + return aNames; + } + // XElemenAccess + virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) throw (::com::sun::star::uno::RuntimeException){ return uno::Type(); } + virtual ::sal_Bool SAL_CALL hasElements( ) throw (::com::sun::star::uno::RuntimeException ) { return sal_True; } + +}; + class ScVbaCodeNameProvider : public ::cppu::WeakImplHelper1< document::XCodeNameQuery > { ScDocShell* mpDocShell; @@ -75,6 +195,7 @@ public: // XCodeNameQuery rtl::OUString SAL_CALL getCodeNameForObject( const uno::Reference< uno::XInterface >& xIf ) throw( uno::RuntimeException ) { + ScUnoGuard aGuard; rtl::OUString sCodeName; if ( mpDocShell ) { @@ -172,7 +293,9 @@ static const ProvNamesId_Type __FAR_DATA aProvNamesId[] = { SC_SERVICENAME_CHDATAPROV, SC_SERVICE_CHDATAPROV }, { SC_SERVICENAME_FORMULAPARS, SC_SERVICE_FORMULAPARS }, { SC_SERVICENAME_OPCODEMAPPER, SC_SERVICE_OPCODEMAPPER }, + { "ooo.vba.VBAObjectModuleObjectProvider", SC_SERVICE_VBAOBJECTPROVIDER }, { "ooo.vba.VBACodeNameProvider", SC_SERVICE_VBACODENAMEPROVIDER }, + { "ooo.vba.VBAGlobals", SC_SERVICE_VBAGLOBALS }, // case-correct versions of the service names (#i102468#) { "com.sun.star.text.textfield.URL", SC_SERVICE_URLFIELD }, @@ -182,7 +305,7 @@ static const ProvNamesId_Type __FAR_DATA aProvNamesId[] = { "com.sun.star.text.textfield.Time", SC_SERVICE_TIMEFIELD }, { "com.sun.star.text.textfield.DocumentTitle", SC_SERVICE_TITLEFIELD }, { "com.sun.star.text.textfield.FileName", SC_SERVICE_FILEFIELD }, - { "com.sun.star.text.textfield.SheetName", SC_SERVICE_SHEETFIELD }, + { "com.sun.star.text.textfield.SheetName", SC_SERVICE_SHEETFIELD } }; // @@ -235,7 +358,9 @@ static const sal_Char* __FAR_DATA aOldNames[SC_SERVICE_COUNT] = "", // SC_SERVICE_CHDATAPROV "", // SC_SERVICE_FORMULAPARS "", // SC_SERVICE_OPCODEMAPPER + "", // SC_SERVICE_VBAOBJECTPROVIDER "", // SC_SERVICE_VBACODENAMEPROVIDER + "", // SC_SERVICE_VBAGLOBALS }; @@ -440,6 +565,13 @@ uno::Reference<uno::XInterface> ScServiceProvider::MakeInstance( xRet.set(static_cast<sheet::XFormulaOpCodeMapper*>(new ScFormulaOpCodeMapperObj(::std::auto_ptr<formula::FormulaCompiler> (pComp)))); break; } + case SC_SERVICE_VBAOBJECTPROVIDER: + if ( pDocShell ) + { + OSL_TRACE("**** creating VBA Object mapper"); + xRet.set(static_cast<container::XNameAccess*>(new ScVbaObjectForCodeNameProvider( pDocShell ))); + } + break; case SC_SERVICE_VBACODENAMEPROVIDER: { // Only create the excel faking service for excel docs @@ -453,6 +585,25 @@ uno::Reference<uno::XInterface> ScServiceProvider::MakeInstance( } break; } + case SC_SERVICE_VBAGLOBALS: + { + uno::Any aGlobs; + ScDocument* pDoc = pDocShell->GetDocument(); + if ( pDoc ) + { + if ( !pDocShell->GetBasicManager()->GetGlobalUNOConstant( "VBAGlobals", aGlobs ) ) + { + uno::Sequence< uno::Any > aArgs(1); + aArgs[ 0 ] <<= pDocShell->GetModel(); + aGlobs <<= ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.excel.Globals" ) ), aArgs ); + pDocShell->GetBasicManager()->SetGlobalUNOConstant( "VBAGlobals", aGlobs ); + BasicManager* pAppMgr = SFX_APP()->GetBasicManager(); + if ( pAppMgr ) + pAppMgr->SetGlobalUNOConstant( "ThisExcelDoc", aArgs[ 0 ] ); + } + aGlobs >>= xRet; + } + } } return xRet; diff --git a/sc/source/ui/vba/excelvbahelper.cxx b/sc/source/ui/vba/excelvbahelper.cxx index 4912863a446e..b1c4db637434 100644 --- a/sc/source/ui/vba/excelvbahelper.cxx +++ b/sc/source/ui/vba/excelvbahelper.cxx @@ -208,12 +208,11 @@ getViewFrame( const uno::Reference< frame::XModel >& xModel ) } SfxItemSet* -ScVbaCellRangeAccess::GetDataSet( ScCellRangeObj* pRangeObj ) +ScVbaCellRangeAccess::GetDataSet( ScCellRangesBase* pRangeObj ) { - SfxItemSet* pDataSet = pRangeObj ? pRangeObj->GetCurrentDataSet( true ) : NULL ; - return pDataSet; - + return pRangeObj ? pRangeObj->GetCurrentDataSet( true ) : 0; } + } //excel } //vba } //ooo diff --git a/sc/source/ui/vba/excelvbahelper.hxx b/sc/source/ui/vba/excelvbahelper.hxx index 34b099e6db46..9af804ab169f 100644 --- a/sc/source/ui/vba/excelvbahelper.hxx +++ b/sc/source/ui/vba/excelvbahelper.hxx @@ -30,7 +30,7 @@ #include<vbahelper/vbahelper.hxx> #include <docsh.hxx> -class ScCellRangeObj; +class ScCellRangesBase; namespace ooo { @@ -51,7 +51,7 @@ namespace ooo class ScVbaCellRangeAccess { public: - static SfxItemSet* GetDataSet( ScCellRangeObj* pRangeObj ); + static SfxItemSet* GetDataSet( ScCellRangesBase* pRangeObj ); }; } } diff --git a/sc/source/ui/vba/testvba/runTests.pl b/sc/source/ui/vba/testvba/runTests.pl index f5051516a9c4..e686a1d4cb89 100644..100755 --- a/sc/source/ui/vba/testvba/runTests.pl +++ b/sc/source/ui/vba/testvba/runTests.pl @@ -20,7 +20,7 @@ my $theResult; my $officepath = shift || die "please specify path to office installation program dir"; my $DocName = shift || ""; my $programpath = "$officepath"."3/program:$officepath/program:"; -my $basiclibrarypath = "$officepath/basis3.2/program"; +my $basiclibrarypath = "$officepath/basis3.3/program"; my $urelibpath = "$officepath/ure/lib"; my $binext = ""; my $testDocDir = "$binDir/TestDocuments"; diff --git a/sc/source/ui/vba/testvba/testclient b/sc/source/ui/vba/testvba/testclient Binary files differindex 12e9ca1659f4..c9cde8c5b052 100755 --- a/sc/source/ui/vba/testvba/testclient +++ b/sc/source/ui/vba/testvba/testclient diff --git a/sc/source/ui/vba/vbaapplication.cxx b/sc/source/ui/vba/vbaapplication.cxx index 5d9e513dabeb..3d5af01acef1 100644 --- a/sc/source/ui/vba/vbaapplication.cxx +++ b/sc/source/ui/vba/vbaapplication.cxx @@ -132,10 +132,16 @@ ScVbaApplication::getActiveWorkbook() throw (uno::RuntimeException) { return new ActiveWorkbook( this, mxContext ); } + uno::Reference< excel::XWorkbook > SAL_CALL ScVbaApplication::getThisWorkbook() throw (uno::RuntimeException) { - return getActiveWorkbook(); + uno::Reference< frame::XModel > xModel = getThisExcelDoc(mxContext); + if( !xModel.is() ) + return uno::Reference< excel::XWorkbook >(); + + ScVbaWorkbook *pWb = new ScVbaWorkbook( this, mxContext, xModel ); + return uno::Reference< excel::XWorkbook > (pWb); } uno::Reference< XAssistant > SAL_CALL @@ -769,46 +775,74 @@ bool lcl_canJoin( ScRange& r1, ScRange& r2 ) void lcl_strip_containedRanges( Ranges& vRanges ) { // get rid of ranges that are surrounded by other ranges - for( Ranges::iterator it = vRanges.begin(); it != vRanges.end(); ++it ) + Ranges::iterator it_outer = vRanges.begin(); + while( it_outer != vRanges.end() ) { - for( Ranges::iterator it_inner = vRanges.begin(); it_inner != vRanges.end(); ++it_inner ) + bool it_outer_erased = false; // true = it_outer erased from vRanges + Ranges::iterator it_inner = vRanges.begin(); + /* Exit the inner loop if outer iterator has been erased in its last + iteration (this means it has been joined to last it_inner, or that + the it_inner contains it completely). The inner loop will restart + with next element of the outer loop, and all elements (from the + beginning of the list) will be checked against that new element. */ + while( !it_outer_erased && (it_inner != vRanges.end()) ) { - if ( it != it_inner ) + bool it_inner_erased = false; // true = it_inner erased from vRanges + if ( it_outer != it_inner ) { #ifdef DEBUG - String r1; - String r2; - it->Format( r1, SCA_VALID ) ; - it_inner->Format( r2, SCA_VALID ) ; - OSL_TRACE( "try strip/join address %s with %s ", - rtl::OUStringToOString( r1, RTL_TEXTENCODING_UTF8 ).getStr(), - rtl::OUStringToOString( r2, RTL_TEXTENCODING_UTF8 ).getStr() ); + String r1; + String r2; + it_outer->Format( r1, SCA_VALID ) ; + it_inner->Format( r2, SCA_VALID ) ; + OSL_TRACE( "try strip/join address %s with %s ", + rtl::OUStringToOString( r1, RTL_TEXTENCODING_UTF8 ).getStr(), + rtl::OUStringToOString( r2, RTL_TEXTENCODING_UTF8 ).getStr() ); #endif - if ( it->In( *it_inner ) ) + if ( it_outer->In( *it_inner ) ) + { it_inner = vRanges.erase( it_inner ); - else if ( it_inner->In( *it ) ) - it = vRanges.erase( it ); + it_inner_erased = true; + } + else if ( it_inner->In( *it_outer ) ) + { + it_outer = vRanges.erase( it_outer ); + it_outer_erased = true; + } #ifndef OWN_JOIN - else if ( (*it_inner).aStart.Row() == (*it).aStart.Row() - && (*it_inner).aEnd.Row() == (*it).aEnd.Row() ) + else if ( (*it_inner).aStart.Row() == (*it_outer).aStart.Row() + && (*it_inner).aEnd.Row() == (*it_outer).aEnd.Row() ) { - it->ExtendTo( *it_inner ); + it_outer->ExtendTo( *it_inner ); it_inner = vRanges.erase( it_inner ); + it_inner_erased = true; } #else - else if ( lcl_canJoin( *it, *it_inner ) ) + else if ( lcl_canJoin( *it_outer, *it_inner ) ) { - it->ExtendTo( *it_inner ); + it_outer->ExtendTo( *it_inner ); it_inner = vRanges.erase( it_inner ); + it_inner_erased = true; } - else if ( lcl_canJoin( *it_inner, *it) ) + else if ( lcl_canJoin( *it_inner, *it_outer) ) { - it_inner->ExtendTo( *it ); - it = vRanges.erase( it ); + it_inner->ExtendTo( *it_outer ); + it_outer = vRanges.erase( it_outer ); + it_outer_erased = true; } #endif } + /* If it_inner has not been erased from vRanges, continue inner + loop with next element. Otherwise, it_inner already points to + the next element (return value of list::erase()). */ + if( !it_inner_erased ) + ++it_inner; } + /* If it_outer has not been erased from vRanges, continue outer loop + with next element. Otherwise, it_outer already points to the next + element (return value of list::erase()). */ + if( !it_outer_erased ) + ++it_outer; } } diff --git a/sc/source/ui/vba/vbaformat.cxx b/sc/source/ui/vba/vbaformat.cxx index c98029fb1292..23c2bf96a810 100644 --- a/sc/source/ui/vba/vbaformat.cxx +++ b/sc/source/ui/vba/vbaformat.cxx @@ -45,7 +45,10 @@ #include "vbafont.hxx" #include "vbainterior.hxx" -#include "unonames.hxx" +#include <unonames.hxx> +#include <cellsuno.hxx> +#include <scitems.hxx> +#include <attrib.hxx> using namespace ::ooo::vba; using namespace ::com::sun::star; @@ -571,14 +574,24 @@ ScVbaFormat<Ifc1>::getLocked( ) throw (script::BasicErrorException, uno::Runtim uno::Any aCellProtection = aNULL(); try { - rtl::OUString sCellProt( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLPRO ) ); + if (!isAmbiguous(sCellProt)) { - util::CellProtection cellProtection; - mxPropertySet->getPropertyValue(sCellProt) >>= cellProtection; - - aCellProtection = uno::makeAny( cellProtection.IsLocked ); + SfxItemSet* pDataSet = getCurrentDataSet(); + if ( pDataSet ) + { + const ScProtectionAttr& rProtAttr = (const ScProtectionAttr &) pDataSet->Get(ATTR_PROTECTION, TRUE); + SfxItemState eState = pDataSet->GetItemState(ATTR_PROTECTION, TRUE, NULL); + if(eState != SFX_ITEM_DONTCARE) + aCellProtection = uno::makeAny(rProtAttr.GetProtection()); + } + else // fallback to propertyset + { + util::CellProtection cellProtection; + mxPropertySet->getPropertyValue(sCellProt) >>= aCellProtection; + aCellProtection = uno::makeAny( cellProtection.IsLocked ); + } } } catch (uno::Exception& ) @@ -598,9 +611,20 @@ ScVbaFormat<Ifc1>::getFormulaHidden( ) throw (script::BasicErrorException, uno: rtl::OUString sCellProt( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLPRO ) ); if (!isAmbiguous(sCellProt)) { - util::CellProtection aCellProtection; - mxPropertySet->getPropertyValue(sCellProt) >>= aCellProtection; - aBoolRet = uno::makeAny( aCellProtection.IsFormulaHidden ); + SfxItemSet* pDataSet = getCurrentDataSet(); + if ( pDataSet ) + { + const ScProtectionAttr& rProtAttr = (const ScProtectionAttr &) pDataSet->Get(ATTR_PROTECTION, TRUE); + SfxItemState eState = pDataSet->GetItemState(ATTR_PROTECTION, TRUE, NULL); + if(eState != SFX_ITEM_DONTCARE) + aBoolRet = uno::makeAny(rProtAttr.GetHideFormula()); + } + else + { + util::CellProtection aCellProtection; + mxPropertySet->getPropertyValue(sCellProt) >>= aCellProtection; + aBoolRet = uno::makeAny( aCellProtection.IsFormulaHidden ); + } } } catch (uno::Exception e) @@ -794,6 +818,24 @@ ScVbaFormat<Ifc1>::getServiceNames() return aServiceNames; } +template< typename Ifc1 > +ScCellRangesBase* +ScVbaFormat<Ifc1>::getCellRangesBase() throw ( ::uno::RuntimeException ) +{ + return ScCellRangesBase::getImplementation( mxPropertySet ); +} + +template< typename Ifc1 > +SfxItemSet* +ScVbaFormat<Ifc1>::getCurrentDataSet( ) throw ( uno::RuntimeException ) +{ + SfxItemSet* pDataSet = excel::ScVbaCellRangeAccess::GetDataSet( getCellRangesBase() ); + if ( !pDataSet ) + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can't access Itemset for XPropertySet" ) ), uno::Reference< uno::XInterface >() ); + return pDataSet; +} + + template class ScVbaFormat< excel::XStyle >; template class ScVbaFormat< excel::XRange >; diff --git a/sc/source/ui/vba/vbaformat.hxx b/sc/source/ui/vba/vbaformat.hxx index e024cd68b9ad..bfa88d6c7cb8 100644 --- a/sc/source/ui/vba/vbaformat.hxx +++ b/sc/source/ui/vba/vbaformat.hxx @@ -38,6 +38,8 @@ #include <com/sun/star/beans/XPropertyState.hpp> #include <vbahelper/vbahelperinterface.hxx> +class ScCellRangesBase; + template< typename Ifc1 > class ScVbaFormat : public InheritedHelperInterfaceImpl1< Ifc1 > { @@ -60,6 +62,9 @@ protected: css::uno::Reference< css::beans::XPropertyState > getXPropertyState() throw ( css::uno::RuntimeException ); void initializeNumberFormats() throw ( css::script::BasicErrorException ); void setNumberFormat( css::lang::Locale _aLocale, const rtl::OUString& _sFormatString) throw( css::script::BasicErrorException ); + SfxItemSet* getCurrentDataSet( ) throw ( css::uno::RuntimeException ); +protected: + virtual ScCellRangesBase* getCellRangesBase() throw ( css::uno::RuntimeException ); public: ScVbaFormat( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::beans::XPropertySet >& _xPropertySet, const css::uno::Reference< css::frame::XModel >& xModel, bool bCheckAmbiguoity ) throw ( css::script::BasicErrorException ); virtual ~ScVbaFormat() {} diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx index b3307ffdc55d..1a153b440b15 100644 --- a/sc/source/ui/vba/vbarange.cxx +++ b/sc/source/ui/vba/vbarange.cxx @@ -238,21 +238,28 @@ uno::Reference< excel::XRange > lcl_makeXRangeFromSheetCellRanges( const uno::Re return xRange; } -ScCellRangeObj* ScVbaRange::getCellRangeObj() throw ( uno::RuntimeException ) +ScCellRangesBase* ScVbaRange::getCellRangesBase() throw ( uno::RuntimeException ) { - uno::Reference< uno::XInterface > xIf; - if ( mxRanges.is() ) - xIf.set( mxRanges, uno::UNO_QUERY_THROW ); - else - xIf.set( mxRange, uno::UNO_QUERY_THROW ); - ScCellRangeObj* pUnoCellRange = dynamic_cast< ScCellRangeObj* >( xIf.get() ); - return pUnoCellRange; + if( mxRanges.is() ) + return ScCellRangesBase::getImplementation( mxRanges ); + if( mxRange.is() ) + return ScCellRangesBase::getImplementation( mxRange ); + throw uno::RuntimeException( rtl::OUString::createFromAscii("General Error creating range - Unknown" ), uno::Reference< uno::XInterface >() ); +} + +ScCellRangeObj* ScVbaRange::getCellRangeObj() throw ( uno::RuntimeException ) +{ + return dynamic_cast< ScCellRangeObj* >( getCellRangesBase() ); +} + +ScCellRangesObj* ScVbaRange::getCellRangesObj() throw ( uno::RuntimeException ) +{ + return dynamic_cast< ScCellRangesObj* >( getCellRangesBase() ); } SfxItemSet* ScVbaRange::getCurrentDataSet( ) throw ( uno::RuntimeException ) { - ScCellRangeObj* pUnoCellRange = getCellRangeObj(); - SfxItemSet* pDataSet = excel::ScVbaCellRangeAccess::GetDataSet( pUnoCellRange ); + SfxItemSet* pDataSet = excel::ScVbaCellRangeAccess::GetDataSet( getCellRangesBase() ); if ( !pDataSet ) throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can't access Itemset for range" ) ), uno::Reference< uno::XInterface >() ); return pDataSet; @@ -3852,25 +3859,6 @@ ScVbaRange::getWorksheet() throw (uno::RuntimeException) return xSheet; } -ScCellRangesBase* -ScVbaRange::getCellRangesBase() throw( uno::RuntimeException ) -{ - ScCellRangesBase* pUnoRangesBase = NULL; - if ( mxRanges.is() ) - { - uno::Reference< uno::XInterface > xIf( mxRanges, uno::UNO_QUERY_THROW ); - pUnoRangesBase = dynamic_cast< ScCellRangesBase* >( xIf.get() ); - } - else if ( mxRange.is() ) - { - uno::Reference< uno::XInterface > xIf( mxRange, uno::UNO_QUERY_THROW ); - pUnoRangesBase = dynamic_cast< ScCellRangesBase* >( xIf.get() ); - } - else - throw uno::RuntimeException( rtl::OUString::createFromAscii("General Error creating range - Unknown" ), uno::Reference< uno::XInterface >() ); - return pUnoRangesBase; -} - // #TODO remove this ugly application processing // Process an application Range request e.g. 'Range("a1,b2,a4:b6") uno::Reference< excel::XRange > @@ -4589,26 +4577,6 @@ ScVbaRange::getValidation() throw (css::uno::RuntimeException) return m_xValidation; } -uno::Any ScVbaRange::getFormulaHidden() throw ( script::BasicErrorException, css::uno::RuntimeException) -{ - SfxItemSet* pDataSet = getCurrentDataSet(); - const ScProtectionAttr& rProtAttr = (const ScProtectionAttr &) - pDataSet->Get(ATTR_PROTECTION, TRUE); - SfxItemState eState = pDataSet->GetItemState(ATTR_PROTECTION, TRUE, NULL); - if(eState == SFX_ITEM_DONTCARE) - return aNULL(); - return uno::makeAny(rProtAttr.GetHideFormula()); - -} -void ScVbaRange::setFormulaHidden(const uno::Any& Hidden) throw ( script::BasicErrorException, css::uno::RuntimeException) -{ - uno::Reference< beans::XPropertySet > xProps(mxRange, ::uno::UNO_QUERY_THROW); - util::CellProtection rCellAttr; - xProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLPRO))) >>= rCellAttr; - Hidden >>= rCellAttr.IsFormulaHidden; - xProps->setPropertyValue(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLPRO)), uno::makeAny(rCellAttr)); -} - uno::Any ScVbaRange::getShowDetail() throw ( css::uno::RuntimeException) { // #FIXME, If the specified range is in a PivotTable report diff --git a/sc/source/ui/vba/vbarange.hxx b/sc/source/ui/vba/vbarange.hxx index 89ae741c7535..1f161a79d973 100644 --- a/sc/source/ui/vba/vbarange.hxx +++ b/sc/source/ui/vba/vbarange.hxx @@ -57,6 +57,7 @@ class ScTableSheetsObj; class ScCellRangesBase; class ScCellRangeObj; +class ScCellRangesObj; class ScDocShell; class ScDocument; @@ -111,14 +112,16 @@ class ScVbaRange : public ScVbaRange_BASE 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); css::uno::Reference< ov::excel::XRange > getArea( sal_Int32 nIndex ) throw( css::uno::RuntimeException ); - ScCellRangesBase* getCellRangesBase() throw ( css::uno::RuntimeException ); ScCellRangeObj* getCellRangeObj( ) throw ( css::uno::RuntimeException ); - SfxItemSet* getCurrentDataSet( ) throw ( css::uno::RuntimeException ); + ScCellRangesObj* getCellRangesObj() throw ( css::uno::RuntimeException ); css::uno::Reference< ov::XCollection >& getBorders(); void groupUnGroup( bool bUnGroup = false ) throw ( css::script::BasicErrorException, css::uno::RuntimeException ); 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 ); +protected: + virtual ScCellRangesBase* getCellRangesBase() throw ( css::uno::RuntimeException ); + virtual SfxItemSet* getCurrentDataSet( ) throw ( css::uno::RuntimeException ); public: ScVbaRange( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::table::XCellRange >& xRange, sal_Bool bIsRows = false, sal_Bool bIsColumns = false ) throw ( css::lang::IllegalArgumentException ); ScVbaRange( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::sheet::XSheetCellRangeContainer >& xRanges, sal_Bool bIsRows = false, sal_Bool bIsColumns = false ) throw ( css::lang::IllegalArgumentException ); @@ -170,10 +173,6 @@ public: virtual css::uno::Any SAL_CALL getPageBreak() throw (css::uno::RuntimeException); virtual void SAL_CALL setPageBreak( const css::uno::Any& _pagebreak ) throw (css::uno::RuntimeException); virtual css::uno::Reference< ov::excel::XValidation > SAL_CALL getValidation() throw (css::uno::RuntimeException); - virtual css::uno::Any SAL_CALL getFormulaHidden() throw (css::script::BasicErrorException, css::uno::RuntimeException); - virtual void SAL_CALL setFormulaHidden(const css::uno::Any& aHidden) throw (css::script::BasicErrorException, css::uno::RuntimeException); - //virtual css::uno::Any SAL_CALL getLocked() throw (css::script::BasicErrorException, css::uno::RuntimeException); - //virtual void SAL_CALL setLocked(const css::uno::Any& aLocked) throw (css::script::BasicErrorException, css::uno::RuntimeException); virtual css::uno::Any SAL_CALL getShowDetail() throw (css::uno::RuntimeException); virtual void SAL_CALL setShowDetail(const css::uno::Any& aShowDetail) throw (css::uno::RuntimeException); // Methods diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index b8eeb868809e..87740a88e4df 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -165,6 +165,7 @@ private: BOOL bInit; BOOL bCancelled; BOOL bInSelect; + bool mbListHasDates; ULONG nSel; ScFilterBoxMode eMode; @@ -188,6 +189,8 @@ public: BOOL IsInInit() const { return bInit; } void SetCancelled() { bCancelled = TRUE; } BOOL IsInSelect() const { return bInSelect; } + void SetListHasDates(bool b) { mbListHasDates = b; } + bool HasDates() const { return mbListHasDates; } }; //------------------------------------------------------------------- @@ -203,6 +206,7 @@ ScFilterListBox::ScFilterListBox( Window* pParent, ScGridWindow* pGrid, bInit( TRUE ), bCancelled( FALSE ), bInSelect( FALSE ), + mbListHasDates(false), nSel( 0 ), eMode( eNewMode ) { @@ -907,7 +911,9 @@ void ScGridWindow::DoAutoFilterMenue( SCCOL nCol, SCROW nRow, BOOL bDataSelect ) pFilterBox->SetSeparatorPos( nDefCount - 1 ); // get list entries - pDoc->GetFilterEntries( nCol, nRow, nTab, aStrings, true ); + bool bHasDates = false; + pDoc->GetFilterEntries( nCol, nRow, nTab, true, aStrings, bHasDates); + pFilterBox->SetListHasDates(bHasDates); // check widths of numerical entries (string entries are not included) // so all numbers are completely visible @@ -1117,7 +1123,7 @@ void ScGridWindow::FilterSelect( ULONG nSel ) ExecDataSelect( nCol, nRow, aString ); break; case SC_FILTERBOX_FILTER: - ExecFilter( nSel, nCol, nRow, aString ); + ExecFilter( nSel, nCol, nRow, aString, pFilterBox->HasDates() ); break; case SC_FILTERBOX_SCENARIO: pViewData->GetView()->UseScenario( aString ); @@ -1150,7 +1156,7 @@ void ScGridWindow::ExecDataSelect( SCCOL nCol, SCROW nRow, const String& rStr ) void ScGridWindow::ExecFilter( ULONG nSel, SCCOL nCol, SCROW nRow, - const String& aValue ) + const String& aValue, bool bCheckForDates ) { SCTAB nTab = pViewData->GetTabNo(); ScDocument* pDoc = pViewData->GetDocument(); @@ -1222,6 +1228,7 @@ void ScGridWindow::ExecFilter( ULONG nSel, rNewEntry.bDoQuery = TRUE; rNewEntry.bQueryByString = TRUE; rNewEntry.nField = nCol; + rNewEntry.bQueryByDate = bCheckForDates; if ( nSel == SC_AUTOFILTER_TOP10 ) { rNewEntry.eOp = SC_TOPVAL; diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx index 5fcd094acffc..11ecfa5aae8c 100644 --- a/sc/source/ui/view/viewfun2.cxx +++ b/sc/source/ui/view/viewfun2.cxx @@ -87,6 +87,13 @@ #include "docuno.hxx" #include "charthelper.hxx" +#include <basic/sbstar.hxx> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/script/XLibraryContainer.hpp> +using namespace com::sun::star; + +// helper func defined in docfunc.cxx +void VBA_DeleteModule( ScDocShell& rDocSh, String& sModuleName ); // STATIC DATA --------------------------------------------------------------- @@ -2141,6 +2148,7 @@ BOOL ScViewFunc::DeleteTables(const SvShorts &TheTabs, BOOL bRecord ) { ScDocShell* pDocSh = GetViewData()->GetDocShell(); ScDocument* pDoc = pDocSh->GetDocument(); + BOOL bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : FALSE; SCTAB nNewTab = TheTabs[0]; int i; WaitObject aWait( GetFrameWin() ); @@ -2212,9 +2220,18 @@ BOOL ScViewFunc::DeleteTables(const SvShorts &TheTabs, BOOL bRecord ) for(i=TheTabs.Count()-1;i>=0;i--) { + String sCodeName; + BOOL bHasCodeName = pDoc->GetCodeName( TheTabs[sal::static_int_cast<USHORT>(i)], sCodeName ); if (pDoc->DeleteTab( TheTabs[sal::static_int_cast<USHORT>(i)], pUndoDoc )) { bDelDone = TRUE; + if( bVbaEnabled ) + { + if( bHasCodeName ) + { + VBA_DeleteModule( *pDocSh, sCodeName ); + } + } pDocSh->Broadcast( ScTablesHint( SC_TAB_DELETED, TheTabs[sal::static_int_cast<USHORT>(i)] ) ); } } |