diff options
Diffstat (limited to 'sc/source/ui')
121 files changed, 5459 insertions, 1145 deletions
diff --git a/sc/source/ui/Accessibility/AccessibleCellBase.cxx b/sc/source/ui/Accessibility/AccessibleCellBase.cxx index 92ff551f2724..cc93d0a93350 100644 --- a/sc/source/ui/Accessibility/AccessibleCellBase.cxx +++ b/sc/source/ui/Accessibility/AccessibleCellBase.cxx @@ -92,10 +92,12 @@ sal_Bool SAL_CALL ScAccessibleCellBase::isVisible( ) sal_Bool bVisible(sal_True); if (mpDoc) { - BYTE nColFlags = mpDoc->GetColFlags(maCellAddress.Col(), maCellAddress.Tab()); - BYTE nRowFlags = mpDoc->GetRowFlags(maCellAddress.Row(), maCellAddress.Tab()); - if (((nColFlags & CR_HIDDEN) == CR_HIDDEN) || ((nColFlags & CR_FILTERED) == CR_FILTERED) || - ((nRowFlags & CR_HIDDEN) == CR_HIDDEN) || ((nRowFlags & CR_FILTERED) == CR_FILTERED)) + bool bColHidden = mpDoc->ColHidden(maCellAddress.Col(), maCellAddress.Tab()); + bool bRowHidden = mpDoc->RowHidden(maCellAddress.Row(), maCellAddress.Tab()); + bool bColFiltered = mpDoc->ColFiltered(maCellAddress.Col(), maCellAddress.Tab()); + bool bRowFiltered = mpDoc->RowFiltered(maCellAddress.Row(), maCellAddress.Tab()); + + if (bColHidden || bColFiltered || bRowHidden || bRowFiltered) bVisible = sal_False; } return bVisible; diff --git a/sc/source/ui/Accessibility/AccessibleContextBase.cxx b/sc/source/ui/Accessibility/AccessibleContextBase.cxx index e438224ecfb6..0f1fcfa337a5 100644 --- a/sc/source/ui/Accessibility/AccessibleContextBase.cxx +++ b/sc/source/ui/Accessibility/AccessibleContextBase.cxx @@ -626,7 +626,3 @@ void ScAccessibleContextBase::IsObjectValid() const throw lang::DisposedException(); } -void ScAccessibleContextBase::SetRole(sal_Int16 nRole) -{ - maRole = nRole; -} diff --git a/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx index f536b8b9a8f7..2af69faa33c8 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx @@ -99,13 +99,6 @@ OUString ScAccessibleFilterTopWindow::getImplementationName() throw (RuntimeExce return OUString::createFromAscii("ScAccessibleFilterTopWindow"); } -Reference<XAccessible> ScAccessibleFilterTopWindow::getAccessibleChildMenu() -{ - if (!mxAccMenu.is()) - mxAccMenu.set(new ScAccessibleFilterMenu(this, mpWindow, getAccessibleName(), ScMenuFloatingWindow::MENU_NOT_SELECTED, mpDoc)); - return mxAccMenu; -} - void ScAccessibleFilterTopWindow::setAccessibleChild( const Reference<XAccessible>& rAccessible, ChildControlType eType) { diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx index f6fc2cb27b71..2cabe7f9f2d6 100644 --- a/sc/source/ui/app/inputwin.cxx +++ b/sc/source/ui/app/inputwin.cxx @@ -289,7 +289,7 @@ sal_Bool ScInputWindow::UseSubTotal(ScRangeList* pRangeList) const SCROW nRow(pRange->aStart.Row()); while (!bSubTotal && nRow <= nRowEnd) { - if (pDoc->IsFiltered(nRow, nTab)) + if (pDoc->RowFiltered(nRow, nTab)) bSubTotal = sal_True; else ++nRow; diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx index 94e18def8a11..272852efcf71 100644 --- a/sc/source/ui/app/scmod.cxx +++ b/sc/source/ui/app/scmod.cxx @@ -1908,21 +1908,19 @@ IMPL_LINK( ScModule, IdleHandler, Timer*, EMPTYARG ) if ( pDocSh ) { ScDocument* pDoc = pDocSh->GetDocument(); - if ( pDoc->IsLoadingDone() ) - { - BOOL bLinks = pDoc->IdleCheckLinks(); - BOOL bWidth = pDoc->IdleCalcTextWidth(); - BOOL bSpell = pDoc->ContinueOnlineSpelling(); - if ( bSpell ) - aSpellTimer.Start(); // da ist noch was - - bMore = bLinks || bWidth || bSpell; // ueberhaupt noch was? - - // While calculating a Basic formula, a paint event may have occured, - // so check the bNeedsRepaint flags for this document's views - if (bWidth) - lcl_CheckNeedsRepaint( pDocSh ); - } + + BOOL bLinks = pDoc->IdleCheckLinks(); + BOOL bWidth = pDoc->IdleCalcTextWidth(); + BOOL bSpell = pDoc->ContinueOnlineSpelling(); + if ( bSpell ) + aSpellTimer.Start(); // da ist noch was + + bMore = bLinks || bWidth || bSpell; // ueberhaupt noch was? + + // While calculating a Basic formula, a paint event may have occured, + // so check the bNeedsRepaint flags for this document's views + if (bWidth) + lcl_CheckNeedsRepaint( pDocSh ); } ULONG nOldTime = aIdleTimer.GetTimeout(); @@ -2192,9 +2190,6 @@ IMPL_LINK( ScModule, CalcFieldValueHdl, EditFieldInfo*, pInfo ) return 0; } - - -//<!--Added by PengYunQuan for Validity Cell Range Picker BOOL ScModule::RegisterRefWindow( USHORT nSlotId, Window *pWnd ) { std::list<Window*> & rlRefWindow = m_mapRefWindow[nSlotId]; @@ -2244,10 +2239,13 @@ BOOL ScModule::IsAliveRefDlg( USHORT nSlotId, Window *pWnd ) Window * ScModule::Find1RefWindow( USHORT nSlotId, Window *pWndAncestor ) { + if (!pWndAncestor) + return NULL; + std::map<USHORT, std::list<Window*> >::iterator iSlot = m_mapRefWindow.find( nSlotId ); if( iSlot == m_mapRefWindow.end() ) - return FALSE; + return NULL; std::list<Window*> & rlRefWindow = iSlot->second; @@ -2262,6 +2260,9 @@ Window * ScModule::Find1RefWindow( USHORT nSlotId, Window *pWndAncestor ) Window * ScModule::Find1RefWindow( Window *pWndAncestor ) { + if (!pWndAncestor) + return NULL; + while( Window *pParent = pWndAncestor->GetParent() ) pWndAncestor = pParent; for( std::map<USHORT, std::list<Window*> >::iterator i = m_mapRefWindow.begin(); @@ -2272,4 +2273,4 @@ Window * ScModule::Find1RefWindow( Window *pWndAncestor ) return NULL; } -//<!--Added by PengYunQuan for Validity Cell Range Picker + diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx index a5b286e8a9ea..4b268b9da791 100644 --- a/sc/source/ui/app/transobj.cxx +++ b/sc/source/ui/app/transobj.cxx @@ -602,25 +602,23 @@ void ScTransferObj::InitDocShell() // widths / heights // (must be copied before CopyFromClip, for drawing objects) - SCCOL nCol; - SCROW nRow; + SCCOL nCol, nLastCol; SCTAB nSrcTab = aBlock.aStart.Tab(); pDestDoc->SetLayoutRTL(0, pDoc->IsLayoutRTL(nSrcTab)); for (nCol=nStartX; nCol<=nEndX; nCol++) - if ( pDoc->GetColFlags( nCol, nSrcTab ) & CR_HIDDEN ) + if ( pDoc->ColHidden(nCol, nSrcTab, nLastCol) ) pDestDoc->ShowCol( nCol, 0, FALSE ); else pDestDoc->SetColWidth( nCol, 0, pDoc->GetColWidth( nCol, nSrcTab ) ); ScBitMaskCompressedArray< SCROW, BYTE> & rDestRowFlags = pDestDoc->GetRowFlagsArrayModifiable(0); - ScCompressedArrayIterator< SCROW, BYTE> aIter( pDoc->GetRowFlagsArray( - nSrcTab), nStartY, nEndY); - for ( ; aIter; ++aIter ) + + for (SCROW nRow = nStartY; nRow <= nEndY; ++nRow) { - nRow = aIter.GetPos(); - BYTE nSourceFlags = *aIter; - if ( nSourceFlags & CR_HIDDEN ) + BYTE nSourceFlags = pDoc->GetRowFlags(nRow, nSrcTab); + SCROW nLastRow = -1; + if ( pDoc->RowHidden(nRow, nSrcTab, nLastRow) ) pDestDoc->ShowRow( nRow, 0, FALSE ); else { @@ -684,7 +682,7 @@ void ScTransferObj::InitDocShell() for (nCol=0; nCol<nStartX; nCol++) nPosX += pDestDoc->GetColWidth( nCol, 0 ); - nPosY += pDestDoc->FastGetRowHeight( 0, nStartY-1, 0 ); + nPosY += pDestDoc->GetRowHeight( 0, nStartY-1, 0 ); nPosX = (long) ( nPosX * HMM_PER_TWIPS ); nPosY = (long) ( nPosY * HMM_PER_TWIPS ); @@ -701,9 +699,9 @@ void ScTransferObj::InitDocShell() break; nSizeX += nAdd; } - for (nRow=nStartY; nRow<=nEndY; nRow++) + for (SCROW nRow=nStartY; nRow<=nEndY; nRow++) { - long nAdd = pDestDoc->FastGetRowHeight( nRow, 0 ); + long nAdd = pDestDoc->GetRowHeight( nRow, 0 ); if ( nSizeY+nAdd > aPaperSize.Height() && nSizeY ) // above limit? break; nSizeY += nAdd; diff --git a/sc/source/ui/attrdlg/scdlgfact.cxx b/sc/source/ui/attrdlg/scdlgfact.cxx index 0af2c30d628f..73a5f1a1c4ee 100644 --- a/sc/source/ui/attrdlg/scdlgfact.cxx +++ b/sc/source/ui/attrdlg/scdlgfact.cxx @@ -62,6 +62,7 @@ #include "scendlg.hxx" //add for ScNewScenarioDlg #include "shtabdlg.hxx" //add for ScShowTabDlg #include "strindlg.hxx" //add for ScStringInputDlg +#include "tabbgcolordlg.hxx"//add for ScTabBgColorDlg #include "scuiimoptdlg.hxx" //add for ScImportOptionsDlg #include "attrdlg.hxx" //add for ScAttrDlg #include "hfedtdlg.hxx" //add for ScHFEditDlg @@ -112,6 +113,7 @@ IMPL_ABSTDLG_BASE(AbstractScDPShowDetailDlg_Impl); //add for ScDPShowDetailDlg IMPL_ABSTDLG_BASE(AbstractScNewScenarioDlg_Impl); //add for ScNewScenarioDlg IMPL_ABSTDLG_BASE(AbstractScShowTabDlg_Impl); //add for ScShowTabDlg IMPL_ABSTDLG_BASE(AbstractScStringInputDlg_Impl); //add for ScStringInputDlg +IMPL_ABSTDLG_BASE(AbstractScTabBgColorDlg_Impl); //add for ScTabBgColorDlg IMPL_ABSTDLG_BASE(AbstractScImportOptionsDlg_Impl); //add for ScImportOptionsDlg IMPL_ABSTDLG_BASE(AbstractScTextImportOptionsDlg_Impl); IMPL_ABSTDLG_BASE(AbstractTabDialog_Impl); //add for ScAttrDlg, ScHFEditDlg, ScStyleDlg, ScSubTotalDlg,ScCharDlg, ScParagraphDlg, ScValidationDlg, ScSortDlg @@ -618,6 +620,14 @@ void AbstractScStringInputDlg_Impl::GetInputString( String& rString ) const //a } //add for AbstractScStringInputDlg_Impl end +//add for AbstractScTabBgColorDlg_Impl begin +void AbstractScTabBgColorDlg_Impl::GetSelectedColor( Color& rColor ) const //add for ScTabBgColorDlg +{ + pDlg->GetSelectedColor( rColor ); +} +//add for AbstractScTabBgColorDlg_Impl end + + //add for AbstractScImportOptionsDlg_Impl begin void AbstractScImportOptionsDlg_Impl::GetImportOptions( ScImportOptions& rOptions ) const //add for ScImportOptionsDlg { @@ -1293,6 +1303,31 @@ AbstractScShowTabDlg * ScAbstractDialogFactory_Impl::CreateScShowTabDlg ( Window } //add for ScStringInputDlg end +//add for ScTabBgColorDlg begin +AbstractScTabBgColorDlg * ScAbstractDialogFactory_Impl::CreateScTabBgColorDlg ( + Window* pParent, + const String& rTitle, + const String& rTabBgColorNoColorText, + const Color& rDefaultColor, + ULONG nHelpId , + int nId ) +{ +ScTabBgColorDlg * pDlg=NULL; +switch ( nId ) +{ + case RID_SCDLG_TAB_BG_COLOR : + pDlg = new ScTabBgColorDlg( pParent, rTitle, rTabBgColorNoColorText, rDefaultColor, nHelpId ); + break; + default: + break; +} + +if ( pDlg ) + return new AbstractScTabBgColorDlg_Impl( pDlg ); +return 0; +} +//add for ScTabBgColorDlg end + //add for ScImportOptionsDlg begin AbstractScImportOptionsDlg * ScAbstractDialogFactory_Impl::CreateScImportOptionsDlg ( Window* pParent, int nId, diff --git a/sc/source/ui/attrdlg/scdlgfact.hxx b/sc/source/ui/attrdlg/scdlgfact.hxx index d9752c83da9a..cd0f79dd1598 100644 --- a/sc/source/ui/attrdlg/scdlgfact.hxx +++ b/sc/source/ui/attrdlg/scdlgfact.hxx @@ -58,6 +58,7 @@ class ScDPShowDetailDlg; class ScNewScenarioDlg; class ScShowTabDlg; class ScStringInputDlg; +class ScTabBgColorDlg; class ScImportOptionsDlg; class SfxTabDialog; class ScSortWarningDlg; @@ -336,6 +337,12 @@ class AbstractScStringInputDlg_Impl : public AbstractScStringInputDlg //add fo virtual void GetInputString( String& rString ) const; }; +class AbstractScTabBgColorDlg_Impl : public AbstractScTabBgColorDlg //add for ScTabBgColorDlg +{ + DECL_ABSTDLG_BASE( AbstractScTabBgColorDlg_Impl, ScTabBgColorDlg ) + virtual void GetSelectedColor( Color& rColor ) const; +}; + class AbstractScImportOptionsDlg_Impl : public AbstractScImportOptionsDlg //add for ScImportOptionsDlg { DECL_ABSTDLG_BASE( AbstractScImportOptionsDlg_Impl, ScImportOptionsDlg) @@ -519,6 +526,14 @@ public: const String& rDefault, ULONG nHelpId , int nId ); + + virtual AbstractScTabBgColorDlg * CreateScTabBgColorDlg ( Window* pParent, //add for ScStringInputDlg + const String& rTitle, //Dialog Title + const String& rTabBgColorNoColorText, //Label for no tab color + const Color& rDefaultColor, //Currently selected Color + ULONG nHelpId , + int nId ); + virtual AbstractScImportOptionsDlg * CreateScImportOptionsDlg ( Window* pParent, //add for ScImportOptionsDlg int nId, BOOL bAscii = TRUE, diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index fa14a5497826..52aae575b7d7 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -169,11 +169,6 @@ void ScDPFieldButton::getPopupBoundingBox(Point& rPos, Size& rSize) const rSize.setHeight(nH); } -bool ScDPFieldButton::isPopupButton() const -{ - return mbPopupButton; -} - void ScDPFieldButton::drawPopupButton() { Point aPos; @@ -732,27 +727,6 @@ ScMenuFloatingWindow* ScMenuFloatingWindow::getSubMenuWindow(size_t nPos) const return maMenuItems[nPos].mpSubMenuWin.get(); } -size_t ScMenuFloatingWindow::getMenuItemCount() const -{ - return maMenuItems.size(); -} - -OUString ScMenuFloatingWindow::getMenuItemName(size_t nPos) const -{ - if (maMenuItems.size() <= nPos) - return ScGlobal::GetEmptyString(); - - return maMenuItems[nPos].maText; -} - -bool ScMenuFloatingWindow::isMenuItemEnabled(size_t nPos) const -{ - if (maMenuItems.size() <= nPos) - return false; - - return maMenuItems[nPos].mbEnabled; -} - bool ScMenuFloatingWindow::isMenuItemSelected(size_t nPos) const { return nPos == mnSelectedMenu; diff --git a/sc/source/ui/dbgui/asciiopt.cxx b/sc/source/ui/dbgui/asciiopt.cxx index cd1f85fb99cc..a22953ade25b 100644 --- a/sc/source/ui/dbgui/asciiopt.cxx +++ b/sc/source/ui/dbgui/asciiopt.cxx @@ -253,20 +253,13 @@ void ScAsciiOptions::ReadFromString( const String& rString ) eCharSet = ScGlobal::GetCharsetValue( aToken ); } - // Language - if (nCount >= 4) - { - aToken = rString.GetToken(3, ','); - eLang = static_cast<LanguageType>(aToken.ToInt32()); - } - // // Startzeile // - if ( nCount >= 5 ) + if ( nCount >= 4 ) { - aToken = rString.GetToken(4,','); + aToken = rString.GetToken(3,','); nStartRow = aToken.ToInt32(); } @@ -274,12 +267,12 @@ void ScAsciiOptions::ReadFromString( const String& rString ) // Spalten-Infos // - if ( nCount >= 6 ) + if ( nCount >= 5 ) { delete[] pColStart; delete[] pColFormat; - aToken = rString.GetToken(5,','); + aToken = rString.GetToken(4,','); nSub = aToken.GetTokenCount('/'); nInfoCount = nSub / 2; if (nInfoCount) @@ -299,6 +292,13 @@ void ScAsciiOptions::ReadFromString( const String& rString ) } } + // Language + if (nCount >= 6) + { + aToken = rString.GetToken(5, ','); + eLang = static_cast<LanguageType>(aToken.ToInt32()); + } + // Import quoted field as text. if (nCount >= 7) { @@ -362,10 +362,6 @@ String ScAsciiOptions::WriteToString() const aOutStr += ScGlobal::GetCharsetString( eCharSet ); aOutStr += ','; // Token-Ende - // Language - aOutStr += String::CreateFromInt32(eLang); - aOutStr += ','; - // // Startzeile // @@ -387,6 +383,13 @@ String ScAsciiOptions::WriteToString() const aOutStr += String::CreateFromInt32(pColFormat[nInfo]); } + // #i112025# the options string is used in macros and linked sheets, + // so new options must be added at the end, to remain compatible + + aOutStr += ','; + + // Language + aOutStr += String::CreateFromInt32(eLang); aOutStr += ','; // Import quoted field as text. diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx index 9895f0f43610..cf149d258062 100644 --- a/sc/source/ui/docshell/dbdocfun.cxx +++ b/sc/source/ui/docshell/dbdocfun.cxx @@ -937,7 +937,10 @@ BOOL ScDBDocFunc::Query( SCTAB nTab, const ScQueryParam& rQueryParam, } if (!bCopy) + { + pDoc->InvalidatePageBreaks(nTab); pDoc->UpdatePageBreaks( nTab ); + } // #i23299# because of Subtotal functions, the whole rows must be set dirty ScRange aDirtyRange( 0 , aLocalParam.nRow1, nDestTab, @@ -1275,6 +1278,13 @@ BOOL ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb // output range must be set at pNewObj pDestObj = new ScDPObject( *pNewObj ); + + // #i94570# When changing the output position in the dialog, a new table is created + // with the settings from the old table, including the name. + // So we have to check for duplicate names here (before inserting). + if ( pDoc->GetDPCollection()->GetByName(pDestObj->GetName()) ) + pDestObj->SetName( String() ); // ignore the invalid name, create a new name below + pDestObj->SetAlive(TRUE); if ( !pDoc->GetDPCollection()->InsertNewTable(pDestObj) ) { diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index e08c930301cf..27b8eef7bbd6 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -2791,6 +2791,8 @@ BOOL ScDocFunc::DeleteTable( SCTAB nTab, BOOL bRecord, BOOL /* bApi */ ) pUndoDoc->SetActiveScenario( nTab, bActive ); } pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) ); + pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) ); + pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) ); // Drawing-Layer muss sein Undo selbst in der Hand behalten !!! pDoc->BeginDrawUndo(); // DeleteTab erzeugt ein SdrUndoDelPage @@ -2995,6 +2997,104 @@ BOOL ScDocFunc::RenameTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL return bSuccess; } +bool ScDocFunc::SetTabBgColor( SCTAB nTab, const Color& rColor, bool bRecord, bool bApi ) +{ + + ScDocument* pDoc = rDocShell.GetDocument(); + if (bRecord && !pDoc->IsUndoEnabled()) + bRecord = false; + if ( !pDoc->IsDocEditable() || pDoc->IsTabProtected(nTab) ) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Check to see what this string is... + return false; + } + + Color aOldTabBgColor; + aOldTabBgColor = pDoc->GetTabBgColor(nTab); + + bool bSuccess = false; + pDoc->SetTabBgColor(nTab, rColor); + if ( pDoc->GetTabBgColor(nTab) == rColor) + bSuccess = true; + if (bSuccess) + { + if (bRecord) + { + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoTabColor( &rDocShell, nTab, aOldTabBgColor, rColor)); + } + rDocShell.PostPaintExtras(); + ScDocShellModificator aModificator( rDocShell ); + aModificator.SetDocumentModified(); + SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); + + bSuccess = true; + } + return bSuccess; +} + +bool ScDocFunc::SetTabBgColor( + ScUndoTabColorInfo::List& rUndoTabColorList, bool bRecord, bool bApi ) +{ + ScDocument* pDoc = rDocShell.GetDocument(); + if (bRecord && !pDoc->IsUndoEnabled()) + bRecord = false; + + if ( !pDoc->IsDocEditable() ) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Get a better String Error... + return false; + } + + USHORT nTab; + Color aNewTabBgColor; + bool bSuccess = true; + size_t nTabProtectCount = 0; + size_t nTabListCount = rUndoTabColorList.size(); + for ( size_t i = 0; i < nTabListCount; ++i ) + { + ScUndoTabColorInfo& rInfo = rUndoTabColorList[i]; + nTab = rInfo.mnTabId; + if ( !pDoc->IsTabProtected(nTab) ) + { + aNewTabBgColor = rInfo.maNewTabBgColor; + rInfo.maOldTabBgColor = pDoc->GetTabBgColor(nTab); + pDoc->SetTabBgColor(nTab, aNewTabBgColor); + if ( pDoc->GetTabBgColor(nTab) != aNewTabBgColor) + { + bSuccess = false; + break; + } + } + else + { + nTabProtectCount++; + } + } + + if ( nTabProtectCount == nTabListCount ) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Get a better String Error... + return false; + } + + if (bSuccess) + { + if (bRecord) + { + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoTabColor( &rDocShell, rUndoTabColorList)); + } + rDocShell.PostPaintExtras(); + ScDocShellModificator aModificator( rDocShell ); + aModificator.SetDocumentModified(); + } + return bSuccess; +} + //------------------------------------------------------------------------ //! SetWidthOrHeight - noch doppelt zu ViewFunc !!!!!! @@ -3097,7 +3197,9 @@ BOOL ScDocFunc::SetWidthOrHeight( BOOL bWidth, SCCOLROW nRangeCnt, SCCOLROW* pRa for (SCROW nRow=nStartNo; nRow<=nEndNo; nRow++) { BYTE nOld = pDoc->GetRowFlags(nRow,nTab); - if ( (nOld & CR_HIDDEN) == 0 && ( nOld & CR_MANUALSIZE ) ) + SCROW nLastRow = -1; + bool bHidden = pDoc->RowHidden(nRow, nTab, nLastRow); + if ( !bHidden && ( nOld & CR_MANUALSIZE ) ) pDoc->SetRowFlags( nRow, nTab, nOld & ~CR_MANUALSIZE ); } } @@ -3132,8 +3234,8 @@ BOOL ScDocFunc::SetWidthOrHeight( BOOL bWidth, SCCOLROW nRangeCnt, SCCOLROW* pRa { for (SCCOL nCol=static_cast<SCCOL>(nStartNo); nCol<=static_cast<SCCOL>(nEndNo); nCol++) { - if ( eMode != SC_SIZE_VISOPT || - (pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN) == 0 ) + SCCOL nLastCol = -1; + if ( eMode != SC_SIZE_VISOPT || !pDoc->ColHidden(nCol, nTab, nLastCol) ) { USHORT nThisSize = nSizeTwips; @@ -3203,20 +3305,22 @@ BOOL ScDocFunc::InsertPageBreak( BOOL bColumn, const ScAddress& rPos, if (nPos == 0) return FALSE; // erste Spalte / Zeile - BYTE nFlags = bColumn ? pDoc->GetColFlags( static_cast<SCCOL>(nPos), nTab ) - : pDoc->GetRowFlags( static_cast<SCROW>(nPos), nTab ); - if (nFlags & CR_MANUALBREAK) - return TRUE; // Umbruch schon gesetzt + ScBreakType nBreak = bColumn ? + pDoc->HasColBreak(static_cast<SCCOL>(nPos), nTab) : + pDoc->HasRowBreak(static_cast<SCROW>(nPos), nTab); + if (nBreak & BREAK_MANUAL) + return true; if (bRecord) rDocShell.GetUndoManager()->AddUndoAction( new ScUndoPageBreak( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, TRUE ) ); - nFlags |= CR_MANUALBREAK; if (bColumn) - pDoc->SetColFlags( static_cast<SCCOL>(nPos), nTab, nFlags ); + pDoc->SetColBreak(static_cast<SCCOL>(nPos), nTab, false, true); else - pDoc->SetRowFlags( static_cast<SCROW>(nPos), nTab, nFlags ); + pDoc->SetRowBreak(static_cast<SCROW>(nPos), nTab, false, true); + + pDoc->InvalidatePageBreaks(nTab); pDoc->UpdatePageBreaks( nTab ); if (pDoc->IsStreamValid(nTab)) @@ -3262,20 +3366,25 @@ BOOL ScDocFunc::RemovePageBreak( BOOL bColumn, const ScAddress& rPos, SCCOLROW nPos = bColumn ? static_cast<SCCOLROW>(rPos.Col()) : static_cast<SCCOLROW>(rPos.Row()); - BYTE nFlags = bColumn ? pDoc->GetColFlags( static_cast<SCCOL>(nPos), nTab ) - : pDoc->GetRowFlags( static_cast<SCROW>(nPos), nTab ); - if ((nFlags & CR_MANUALBREAK)==0) - return FALSE; // kein Umbruch gesetzt + + ScBreakType nBreak; + if (bColumn) + nBreak = pDoc->HasColBreak(static_cast<SCCOL>(nPos), nTab); + else + nBreak = pDoc->HasRowBreak(static_cast<SCROW>(nPos), nTab); + if ((nBreak & BREAK_MANUAL) == 0) + // There is no manual break. + return false; if (bRecord) rDocShell.GetUndoManager()->AddUndoAction( new ScUndoPageBreak( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, FALSE ) ); - nFlags &= ~CR_MANUALBREAK; if (bColumn) - pDoc->SetColFlags( static_cast<SCCOL>(nPos), nTab, nFlags ); + pDoc->RemoveColBreak(static_cast<SCCOL>(nPos), nTab, false, true); else - pDoc->SetRowFlags( static_cast<SCROW>(nPos), nTab, nFlags ); + pDoc->RemoveRowBreak(static_cast<SCROW>(nPos), nTab, false, true); + pDoc->UpdatePageBreaks( nTab ); if (pDoc->IsStreamValid(nTab)) diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index 135bbcdace49..a446c86b4d1b 100644..100755 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -49,6 +49,7 @@ #include <svtools/ctrltool.hxx> #include <svtools/sfxecode.hxx> #include <svl/zforlist.hxx> +#include <svl/PasswordHelper.hxx> #include <sfx2/app.hxx> #include <sfx2/bindings.hxx> #include <sfx2/dinfdlg.hxx> @@ -68,6 +69,9 @@ #include "chgviset.hxx" #include <sfx2/request.hxx> #include <com/sun/star/document/UpdateDocMode.hpp> +#include <com/sun/star/container/XContentEnumerationAccess.hpp> +#include <com/sun/star/sheet/XSpreadsheetView.hpp> +#include <com/sun/star/task/XJob.hpp> #include "scabstdlg.hxx" //CHINA001 @@ -351,6 +355,20 @@ void ScDocShell::AfterXMLLoading(sal_Bool bRet) // else; nothing has to happen, because it is a user given name } } + + // #i94570# DataPilot table names have to be unique, or the tables can't be accessed by API. + // If no name (or an invalid name, skipped in ScXMLDataPilotTableContext::EndElement) was set, create a new name. + ScDPCollection* pDPCollection = aDocument.GetDPCollection(); + if ( pDPCollection ) + { + USHORT nDPCount = pDPCollection->GetCount(); + for (USHORT nDP=0; nDP<nDPCount; nDP++) + { + ScDPObject* pDPObj = (*pDPCollection)[nDP]; + if ( !pDPObj->GetName().Len() ) + pDPObj->SetName( pDPCollection->CreateNewName() ); + } + } } ScColumn::bDoubleAlloc = sal_False; } @@ -457,7 +475,7 @@ BOOL __EXPORT ScDocShell::Load( SfxMedium& rMedium ) // only the latin script language is loaded // -> initialize the others from options (before loading) - InitOptions(); + InitOptions(true); GetUndoManager()->Clear(); @@ -581,6 +599,46 @@ void __EXPORT ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint ) } } } + + try + { + uno::Reference< uno::XComponentContext > xContext; + uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory(); + uno::Reference< beans::XPropertySet > xProp( xServiceManager, uno::UNO_QUERY_THROW ); + xProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ) >>= xContext; + if ( xContext.is() ) + { + uno::Reference< container::XContentEnumerationAccess > xEnumAccess( xServiceManager, uno::UNO_QUERY_THROW ); + uno::Reference< container::XEnumeration> xEnum = xEnumAccess->createContentEnumeration( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.SpreadsheetDocumentJob" ) ) ); + if ( xEnum.is() ) + { + while ( xEnum->hasMoreElements() ) + { + uno::Any aAny = xEnum->nextElement(); + uno::Reference< lang::XSingleComponentFactory > xFactory; + aAny >>= xFactory; + if ( xFactory.is() ) + { + uno::Reference< task::XJob > xJob( xFactory->createInstanceWithContext( xContext ), uno::UNO_QUERY_THROW ); + uno::Sequence< beans::NamedValue > aArgsForJob(1); + ScViewData* pViewData = GetViewData(); + SfxViewShell* pViewShell = ( pViewData ? pViewData->GetViewShell() : NULL ); + SfxViewFrame* pViewFrame = ( pViewShell ? pViewShell->GetViewFrame() : NULL ); + SfxFrame* pFrame = ( pViewFrame ? &pViewFrame->GetFrame() : NULL ); + uno::Reference< frame::XController > xController = ( pFrame ? pFrame->GetController() : 0 ); + uno::Reference< sheet::XSpreadsheetView > xSpreadsheetView( xController, uno::UNO_QUERY_THROW ); + aArgsForJob[0] = beans::NamedValue( ::rtl::OUString::createFromAscii( "SpreadsheetView" ), + uno::makeAny( xSpreadsheetView ) ); + xJob->execute( aArgsForJob ); + } + } + } + } + } + catch ( uno::Exception & ) + { + } } break; case SFX_EVENT_SAVEDOC: @@ -867,10 +925,33 @@ static void lcl_parseHtmlFilterOption(const OUString& rOption, LanguageType& rLa rDateConvert = static_cast<bool>(aTokens[1].toInt32()); } +namespace { + +class LoadMediumGuard +{ +public: + explicit LoadMediumGuard(ScDocument* pDoc) : + mpDoc(pDoc) + { + mpDoc->SetLoadingMedium(true); + } + + ~LoadMediumGuard() + { + mpDoc->SetLoadingMedium(false); + } +private: + ScDocument* mpDoc; +}; + +} + BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium ) { RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ConvertFrom" ); + LoadMediumGuard aLoadGuard(&aDocument); + BOOL bRet = FALSE; // FALSE heisst Benutzerabbruch !! // bei Fehler: Fehler am Stream setzen!! @@ -1937,7 +2018,7 @@ BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed ) /* #115980# #i104990# If the imported document contains a medium password, determine if we can save it, otherwise ask the users whether they want to save without it. */ - if( !::sfx2::CheckMSPasswordCapabilityForExport( aFltName ) ) + if( (rMed.GetFilter()->GetFilterFlags() & SFX_FILTER_ENCRYPTION) == 0 ) { SfxItemSet* pItemSet = rMed.GetItemSet(); const SfxPoolItem* pItem = 0; @@ -2652,3 +2733,97 @@ sal_Bool ScDocShell::AcceptStateUpdate() const return sal_False; } //-->Added by PengYunQuan for Validity Cell Range Picker + + +bool ScDocShell::IsChangeRecording() const +{ + ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack(); + return pChangeTrack != NULL; +} + + +bool ScDocShell::HasChangeRecordProtection() const +{ + bool bRes = false; + ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack(); + if (pChangeTrack) + bRes = pChangeTrack->IsProtected(); + return bRes; +} + + +void ScDocShell::SetChangeRecording( bool bActivate ) +{ + bool bOldChangeRecording = IsChangeRecording(); + + if (bActivate) + { + aDocument.StartChangeTracking(); + ScChangeViewSettings aChangeViewSet; + aChangeViewSet.SetShowChanges(TRUE); + aDocument.SetChangeViewSettings(aChangeViewSet); + } + else + { + aDocument.EndChangeTracking(); + PostPaintGridAll(); + } + + if (bOldChangeRecording != IsChangeRecording()) + { + UpdateAcceptChangesDialog(); + // Slots invalidieren + SfxBindings* pBindings = GetViewBindings(); + if (pBindings) + pBindings->InvalidateAll(FALSE); + } +} + + +bool ScDocShell::SetProtectionPassword( const String &rNewPassword ) +{ + bool bRes = false; + ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack(); + if (pChangeTrack) + { + sal_Bool bProtected = pChangeTrack->IsProtected(); + + if (rNewPassword.Len()) + { + // when password protection is applied change tracking must always be active + SetChangeRecording( true ); + + ::com::sun::star::uno::Sequence< sal_Int8 > aProtectionHash; + SvPasswordHelper::GetHashPassword( aProtectionHash, rNewPassword ); + pChangeTrack->SetProtection( aProtectionHash ); + } + else + { + pChangeTrack->SetProtection( ::com::sun::star::uno::Sequence< sal_Int8 >() ); + } + bRes = true; + + if ( bProtected != pChangeTrack->IsProtected() ) + { + UpdateAcceptChangesDialog(); + SetDocumentModified(); + } + } + + return bRes; +} + + +bool ScDocShell::GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence< sal_Int8 > &rPasswordHash ) +{ + bool bRes = false; + ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack(); + if (pChangeTrack && pChangeTrack->IsProtected()) + { + rPasswordHash = pChangeTrack->GetProtection(); + bRes = true; + } + return bRes; +} + + diff --git a/sc/source/ui/docshell/docsh2.cxx b/sc/source/ui/docshell/docsh2.cxx index 9e3ed217382f..14ff7622818c 100644 --- a/sc/source/ui/docshell/docsh2.cxx +++ b/sc/source/ui/docshell/docsh2.cxx @@ -93,7 +93,7 @@ BOOL __EXPORT ScDocShell::InitNew( const uno::Reference < embed::XStorage >& xSt aDocument.SetDrawDefaults(); // drawing layer defaults that are set only in InitNew // InitOptions sets the document languages, must be called before CreateStandardStyles - InitOptions(); + InitOptions(false); aDocument.GetStyleSheetPool()->CreateStandardStyles(); aDocument.UpdStlShtPtrsFrmNms(); diff --git a/sc/source/ui/docshell/docsh3.cxx b/sc/source/ui/docshell/docsh3.cxx index 4709a065792f..233843935bbd 100644 --- a/sc/source/ui/docshell/docsh3.cxx +++ b/sc/source/ui/docshell/docsh3.cxx @@ -424,7 +424,7 @@ double ScDocShell::GetOutputFactor() const //--------------------------------------------------------------------- -void ScDocShell::InitOptions() // Fortsetzung von InitNew (CLOOKs) +void ScDocShell::InitOptions(bool bForLoading) // called from InitNew and Load { // Einstellungen aus dem SpellCheckCfg kommen in Doc- und ViewOptions @@ -440,6 +440,14 @@ void ScDocShell::InitOptions() // Fortsetzung von InitNew (CLOOKs) // zweistellige Jahreszahleneingabe aus Extras->Optionen->Allgemein->Sonstiges aDocOpt.SetYear2000( sal::static_int_cast<USHORT>( ::utl::MiscCfg().GetYear2000() ) ); + if (bForLoading) + { + // #i112123# No style:decimal-places attribute means automatic decimals, not the configured default, + // so it must not be taken from the global options. + // Calculation settings are handled separately in ScXMLBodyContext::EndElement. + aDocOpt.SetStdPrecision( SvNumberFormatter::UNLIMITED_PRECISION ); + } + aDocument.SetDocOptions( aDocOpt ); aDocument.SetViewOptions( aViewOpt ); diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx index 157b98497e83..0993d2ce4a14 100644..100755 --- a/sc/source/ui/docshell/docsh4.cxx +++ b/sc/source/ui/docshell/docsh4.cxx @@ -66,6 +66,7 @@ using namespace ::com::sun::star; #include <svx/svditer.hxx> #include <svx/svdpage.hxx> #include <svx/fmshell.hxx> +#include <svtools/xwindowitem.hxx> #include <sfx2/passwd.hxx> #include <sfx2/filedlghelper.hxx> #include <sfx2/docinsert.hxx> @@ -120,9 +121,9 @@ using namespace ::com::sun::star; #include "scresid.hxx" //add by CHINA001 #include "scabstdlg.hxx" //CHINA001 #include "externalrefmgr.hxx" - #include "sharedocdlg.hxx" #include "conditio.hxx" +#include "sheetevents.hxx" //------------------------------------------------------------------ @@ -623,8 +624,8 @@ void ScDocShell::Execute( SfxRequest& rReq ) // getting real parent window when called from Security-Options TP Window* pParent = NULL; const SfxPoolItem* pParentItem; - if( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( SID_ATTR_PARENTWINDOW, FALSE, &pParentItem ) ) - pParent = ( Window* ) ( ( const OfaPtrItem* ) pParentItem )->GetValue(); + if( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( SID_ATTR_XWINDOW, FALSE, &pParentItem ) ) + pParent = ( ( const XWindowItem* ) pParentItem )->GetWindowPtr(); // desired state ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack(); @@ -664,17 +665,7 @@ void ScDocShell::Execute( SfxRequest& rReq ) if ( bDo ) { - // update "accept changes" dialog - //! notify all views - SfxViewFrame* pViewFrm = SfxViewFrame::Current(); - if ( pViewFrm && pViewFrm->HasChildWindow(FID_CHG_ACCEPT) ) - { - SfxChildWindow* pChild = pViewFrm->GetChildWindow(FID_CHG_ACCEPT); - if (pChild) - { - ((ScAcceptChgDlgWrapper*)pChild)->ReInitDlg(); - } - } + UpdateAcceptChangesDialog(); // Slots invalidieren if (pBindings) @@ -693,8 +684,8 @@ void ScDocShell::Execute( SfxRequest& rReq ) { Window* pParent = NULL; const SfxPoolItem* pParentItem; - if( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( SID_ATTR_PARENTWINDOW, FALSE, &pParentItem ) ) - pParent = ( Window* ) ( ( const OfaPtrItem* ) pParentItem )->GetValue(); + if( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( SID_ATTR_XWINDOW, FALSE, &pParentItem ) ) + pParent = ( ( const XWindowItem* ) pParentItem )->GetWindowPtr(); if ( ExecuteChangeProtectionDialog( pParent ) ) { rReq.Done(); @@ -1164,6 +1155,21 @@ void ScDocShell::Execute( SfxRequest& rReq ) //------------------------------------------------------------------ +void UpdateAcceptChangesDialog() +{ + // update "accept changes" dialog + //! notify all views + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); + if ( pViewFrm && pViewFrm->HasChildWindow( FID_CHG_ACCEPT ) ) + { + SfxChildWindow* pChild = pViewFrm->GetChildWindow( FID_CHG_ACCEPT ); + if ( pChild ) + ((ScAcceptChgDlgWrapper*)pChild)->ReInitDlg(); + } +} + +//------------------------------------------------------------------ + BOOL ScDocShell::ExecuteChangeProtectionDialog( Window* _pParent, BOOL bJustQueryIfProtected ) { BOOL bDone = FALSE; @@ -1217,15 +1223,7 @@ BOOL ScDocShell::ExecuteChangeProtectionDialog( Window* _pParent, BOOL bJustQuer } if ( bProtected != pChangeTrack->IsProtected() ) { - // update "accept changes" dialog - //! notify all views - SfxViewFrame* pViewFrm = SfxViewFrame::Current(); - if ( pViewFrm && pViewFrm->HasChildWindow( FID_CHG_ACCEPT ) ) - { - SfxChildWindow* pChild = pViewFrm->GetChildWindow( FID_CHG_ACCEPT ); - if ( pChild ) - ((ScAcceptChgDlgWrapper*)pChild)->ReInitDlg(); - } + UpdateAcceptChangesDialog(); bDone = TRUE; } } @@ -1291,6 +1289,14 @@ void ScDocShell::DoHardRecalc( BOOL /* bApi */ ) if ( pSh ) pSh->UpdateCharts(TRUE); + // set notification flags for "calculate" event (used in SFX_HINT_DATACHANGED broadcast) + // (might check for the presence of any formulas on each sheet) + SCTAB nTabCount = aDocument.GetTableCount(); + SCTAB nTab; + if (aDocument.HasSheetEventScript( SC_SHEETEVENT_CALCULATE )) + for (nTab=0; nTab<nTabCount; nTab++) + aDocument.SetCalcNotification(nTab); + // CalcAll doesn't broadcast value changes, so SC_HINT_CALCALL is broadcasted globally // in addition to SFX_HINT_DATACHANGED. aDocument.BroadcastUno( SfxSimpleHint( SC_HINT_CALCALL ) ); @@ -1298,8 +1304,7 @@ void ScDocShell::DoHardRecalc( BOOL /* bApi */ ) // use hard recalc also to disable stream-copying of all sheets // (somewhat consistent with charts) - SCTAB nTabCount = aDocument.GetTableCount(); - for (SCTAB nTab=0; nTab<nTabCount; nTab++) + for (nTab=0; nTab<nTabCount; nTab++) if (aDocument.IsStreamValid(nTab)) aDocument.SetStreamValid(nTab, FALSE); @@ -1484,12 +1489,12 @@ BOOL ScDocShell::AdjustPrintZoom( const ScRange& rRange ) SCROW nEndRow = rRange.aEnd.Row(); if ( pRepeatRow && nStartRow >= pRepeatRow->aStart.Row() ) { - nBlkTwipsY += aDocument.FastGetRowHeight( pRepeatRow->aStart.Row(), + nBlkTwipsY += aDocument.GetRowHeight( pRepeatRow->aStart.Row(), pRepeatRow->aEnd.Row(), nTab ); if ( nStartRow <= pRepeatRow->aEnd.Row() ) nStartRow = pRepeatRow->aEnd.Row() + 1; } - nBlkTwipsY += aDocument.FastGetRowHeight( nStartRow, nEndRow, nTab ); + nBlkTwipsY += aDocument.GetRowHeight( nStartRow, nEndRow, nTab ); Size aPhysPage; long nHdr, nFtr; diff --git a/sc/source/ui/docshell/impex.cxx b/sc/source/ui/docshell/impex.cxx index 46b6b7af3a63..a17279f409a9 100644 --- a/sc/source/ui/docshell/impex.cxx +++ b/sc/source/ui/docshell/impex.cxx @@ -1441,7 +1441,7 @@ BOOL ScImportExport::Doc2Text( SvStream& rStrm ) for (nRow = nStartRow; nRow <= nEndRow; nRow++) { - if (bIncludeFiltered || !pDoc->IsFiltered( nRow, aRange.aStart.Tab() )) + if (bIncludeFiltered || !pDoc->RowFiltered( nRow, aRange.aStart.Tab() )) { for (nCol = nStartCol; nCol <= nEndCol; nCol++) { diff --git a/sc/source/ui/docshell/olinefun.cxx b/sc/source/ui/docshell/olinefun.cxx index 2f42c77ed5f4..822c74800ab2 100644 --- a/sc/source/ui/docshell/olinefun.cxx +++ b/sc/source/ui/docshell/olinefun.cxx @@ -420,7 +420,7 @@ BOOL ScOutlineDocFunc::SelectLevel( SCTAB nTab, BOOL bColumns, USHORT nLevel, if ( bColumns ) pDoc->ShowCol( static_cast<SCCOL>(i), nTab, bShow ); else - if ( !bShow || !pDoc->IsFiltered( i,nTab ) ) + if ( !bShow || !pDoc->RowFiltered( i,nTab ) ) pDoc->ShowRow( i, nTab, bShow ); } } @@ -518,7 +518,7 @@ BOOL ScOutlineDocFunc::ShowMarkedOutlines( const ScRange& rRange, BOOL bRecord, } } for ( i=nMin; i<=nMax; i++ ) - if ( !pDoc->IsFiltered( i,nTab ) ) // weggefilterte nicht einblenden + if ( !pDoc->RowFiltered( i,nTab ) ) // weggefilterte nicht einblenden pDoc->ShowRow( i, nTab, TRUE ); pDoc->UpdatePageBreaks( nTab ); @@ -678,7 +678,7 @@ BOOL ScOutlineDocFunc::ShowOutline( SCTAB nTab, BOOL bColumns, USHORT nLevel, US if ( bColumns ) pDoc->ShowCol( static_cast<SCCOL>(i), nTab, TRUE ); else - if ( !pDoc->IsFiltered( i,nTab ) ) // weggefilterte nicht einblenden + if ( !pDoc->RowFiltered( i,nTab ) ) // weggefilterte nicht einblenden pDoc->ShowRow( i, nTab, TRUE ); } @@ -701,6 +701,7 @@ BOOL ScOutlineDocFunc::ShowOutline( SCTAB nTab, BOOL bColumns, USHORT nLevel, US pArray->SetVisibleBelow( nLevel, nEntry, TRUE, TRUE ); + pDoc->InvalidatePageBreaks(nTab); pDoc->UpdatePageBreaks( nTab ); if (bPaint) @@ -766,6 +767,7 @@ BOOL ScOutlineDocFunc::HideOutline( SCTAB nTab, BOOL bColumns, USHORT nLevel, US pArray->SetVisibleBelow( nLevel, nEntry, FALSE ); + pDoc->InvalidatePageBreaks(nTab); pDoc->UpdatePageBreaks( nTab ); if (bPaint) diff --git a/sc/source/ui/inc/AccessibleContextBase.hxx b/sc/source/ui/inc/AccessibleContextBase.hxx index 191f56c22d3d..ecfeff96af39 100644 --- a/sc/source/ui/inc/AccessibleContextBase.hxx +++ b/sc/source/ui/inc/AccessibleContextBase.hxx @@ -316,8 +316,6 @@ protected: /// Use this method to set initial Description without notification void SetDescription(const rtl::OUString& rDesc) { msDescription = rDesc; } - void SetRole(sal_Int16 nRole); - /// Reference to the parent object. ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> mxParent; diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx index df4ff685816f..c92cc082986d 100644 --- a/sc/source/ui/inc/docfunc.hxx +++ b/sc/source/ui/inc/docfunc.hxx @@ -31,6 +31,7 @@ #include <tools/link.hxx> #include "global.hxx" #include "formula/grammar.hxx" +#include "tabbgcolor.hxx" class ScEditEngineDefaulter; class SdrUndoAction; @@ -117,6 +118,9 @@ public: BOOL RenameTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL bApi ); BOOL DeleteTable( SCTAB nTab, BOOL bRecord, BOOL bApi ); + bool SetTabBgColor( SCTAB nTab, const Color& rColor, bool bRecord, bool bApi ); + bool SetTabBgColor( ScUndoTabColorInfo::List& rUndoTabColorList, bool bRecord, bool bApi ); + BOOL SetTableVisible( SCTAB nTab, BOOL bVisible, BOOL bApi ); BOOL SetLayoutRTL( SCTAB nTab, BOOL bRTL, BOOL bApi ); diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx index 09d34c661995..5b4fc6227225 100644..100755 --- a/sc/source/ui/inc/docsh.hxx +++ b/sc/source/ui/inc/docsh.hxx @@ -125,7 +125,7 @@ class SC_DLLPUBLIC ScDocShell: public SfxObjectShell, public SfxListener SC_DLLPRIVATE void InitItems(); SC_DLLPRIVATE void DoEnterHandler(); - SC_DLLPRIVATE void InitOptions(); + SC_DLLPRIVATE void InitOptions(bool bForLoading); SC_DLLPRIVATE void ResetDrawObjectShell(); // SUNWS needs a forward declared friend, otherwise types and members @@ -418,8 +418,20 @@ public: sal_Bool AcceptStateUpdate() const; //-->Added by PengYunQuan for Validity Cell Range Picker ScSheetSaveData* GetSheetSaveData(); + + // passwword protection for Calc (derived from SfxObjectShell) + // see also: FID_CHG_RECORD, SID_CHG_PROTECT + virtual bool IsChangeRecording() const; + virtual bool HasChangeRecordProtection() const; + virtual void SetChangeRecording( bool bActivate ); + virtual bool SetProtectionPassword( const String &rPassword ); + virtual bool GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence< sal_Int8 > &rPasswordHash ); }; + +void UpdateAcceptChangesDialog(); + + SO2_DECL_REF(ScDocShell) SO2_IMPL_REF(ScDocShell) diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 40e6167aee48..15f0c9174cc8 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -76,7 +76,6 @@ public: void draw(); void getPopupBoundingBox(Point& rPos, Size& rSize) const; - bool isPopupButton() const; private: void drawPopupButton(); @@ -127,9 +126,6 @@ public: void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer); void clearSelectedMenuItem(); ScMenuFloatingWindow* getSubMenuWindow(size_t nPos) const; - size_t getMenuItemCount() const; - ::rtl::OUString getMenuItemName(size_t nPos) const; - bool isMenuItemEnabled(size_t nPos) const; bool isMenuItemSelected(size_t nPos) const; size_t getSelectedMenuItem() const; diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx index 4d6ef782aed6..a2283bf2b7de 100644 --- a/sc/source/ui/inc/gridwin.hxx +++ b/sc/source/ui/inc/gridwin.hxx @@ -39,6 +39,7 @@ #include <vector> #include <memory> +#include <boost/shared_ptr.hpp> // --------------------------------------------------------------------------- @@ -112,6 +113,25 @@ private: ::sdr::overlay::OverlayObjectList* mpOOHeader; ::sdr::overlay::OverlayObjectList* mpOOShrink; + ::boost::shared_ptr<Rectangle> mpAutoFillRect; + + /** + * Stores current visible column and row ranges, used to avoid expensive + * operations on objects that are outside visible area. + */ + struct VisibleRange + { + SCCOL mnCol1; + SCCOL mnCol2; + SCROW mnRow1; + SCROW mnRow2; + + VisibleRange(); + + bool isInside(SCCOL nCol, SCROW nRow) const; + }; + VisibleRange maVisibleRange; + private: ScViewData* pViewData; ScSplitPos eWhich; diff --git a/sc/source/ui/inc/miscdlgs.hrc b/sc/source/ui/inc/miscdlgs.hrc index 908a6bd2221c..becd05165a4e 100644 --- a/sc/source/ui/inc/miscdlgs.hrc +++ b/sc/source/ui/inc/miscdlgs.hrc @@ -181,3 +181,9 @@ #define BTN_GROUP_ROWS 3 #define STR_GROUP 1 #define STR_UNGROUP 2 + +// Tab Bg Color +#define TAB_BG_COLOR_CT_BORDER 1 +#define TAB_BG_COLOR_SET_BGDCOLOR 2 +#define TAB_BG_COLOR_GB_BGDCOLOR 3 + diff --git a/sc/source/ui/inc/tabbgcolordlg.hxx b/sc/source/ui/inc/tabbgcolordlg.hxx new file mode 100644 index 000000000000..241fc806022d --- /dev/null +++ b/sc/source/ui/inc/tabbgcolordlg.hxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tabbgcolordlg.hxx,v $ + * $Revision: 1.0 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_TABBGCOLORDLG_HXX +#define SC_TABBGCOLORDLG_HXX + +#include <vcl/dialog.hxx> +#include <vcl/fixed.hxx> +#include <vcl/imagebtn.hxx> +#include <svtools/valueset.hxx> + +//------------------------------------------------------------------------ + +class ScTabBgColorDlg : public ModalDialog +{ +public: + ScTabBgColorDlg( Window* pParent, + const String& rTitle, + const String& rTabBgColorNoColorText, + const Color& rDefaultColor, + ULONG nHelpId ); + ~ScTabBgColorDlg(); + + void GetSelectedColor( Color& rColor ) const; + +private: + class ScTabBgColorValueSet : public ValueSet + { + public: + ScTabBgColorValueSet(Control* pParent, const ResId& rResId, ScTabBgColorDlg* pTabBgColorDlg); + + virtual void KeyInput( const KeyEvent& rKEvt ); + private: + ScTabBgColorDlg* aTabBgColorDlg; + }; + + Control aBorderWin; + ScTabBgColorValueSet aTabBgColorSet; + FixedLine aTabBgColorBox; + OKButton aBtnOk; + CancelButton aBtnCancel; + HelpButton aBtnHelp; + Color aTabBgColor; + const String aTabBgColorNoColorText; + ULONG mnHelpId; + + void FillColorValueSets_Impl(); + + DECL_LINK( TabBgColorDblClickHdl_Impl, ValueSet* ); + DECL_LINK( TabBgColorOKHdl_Impl, OKButton* pBtn ); +}; + +#endif // SC_TABBGCOLORDLG_HXX diff --git a/sc/source/ui/inc/undotab.hxx b/sc/source/ui/inc/undotab.hxx index 276ea3d7e204..c8d135070ab1 100644 --- a/sc/source/ui/inc/undotab.hxx +++ b/sc/source/ui/inc/undotab.hxx @@ -32,6 +32,7 @@ #include "markdata.hxx" #include "formula/grammar.hxx" #include <tools/color.hxx> +#include "tabbgcolor.hxx" #ifndef _SVSTDARR_SHORTS @@ -223,6 +224,33 @@ private: void DoChange() const; }; +class ScUndoTabColor: public ScSimpleUndo +{ +public: + TYPEINFO(); + ScUndoTabColor( + ScDocShell* pNewDocShell, + SCTAB nT, + const Color& aOTabBgColor, + const Color& aNTabBgColor); + ScUndoTabColor( + ScDocShell* pNewDocShell, + const ScUndoTabColorInfo::List& rUndoTabColorList); + virtual ~ScUndoTabColor(); + + virtual void Undo(); + virtual void Redo(); + virtual void Repeat(SfxRepeatTarget& rTarget); + virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const; + +virtual String GetComment() const; + +private: + ScUndoTabColorInfo::List aTabColorList; + bool bIsMultipleUndo; + + void DoChange(bool bUndoType) const; +}; class ScUndoMakeScenario: public ScSimpleUndo { diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx index 21feb272c339..59da2966cc60 100644 --- a/sc/source/ui/inc/viewfunc.hxx +++ b/sc/source/ui/inc/viewfunc.hxx @@ -29,6 +29,8 @@ #include "tabview.hxx" +#include "tabbgcolor.hxx" + #ifndef _SVSTDARR_SHORTS #define _SVSTDARR_SHORTS #include <svl/svstdarr.hxx> @@ -273,6 +275,9 @@ public: SCTAB nCount, const SCTAB* pSrcTabs, BOOL bLink,SCTAB nTab); + bool SetTabBgColor( const Color& rColor, SCTAB nTabNr ); + bool SetTabBgColor( ScUndoTabColorInfo::List& rUndoSetTabBgColorInfoList ); + void InsertTableLink( const String& rFile, const String& rFilter, const String& rOptions, const String& rTabName ); diff --git a/sc/source/ui/inc/viewutil.hxx b/sc/source/ui/inc/viewutil.hxx index 8b103d3761d8..eb1c6df2f902 100644 --- a/sc/source/ui/inc/viewutil.hxx +++ b/sc/source/ui/inc/viewutil.hxx @@ -68,10 +68,10 @@ public: static sal_Int32 GetTransliterationType( USHORT nSlotID ); - static bool HasFiltered( const ScRange& rRange, const ScDocument* pDoc ); + static bool HasFiltered( const ScRange& rRange, ScDocument* pDoc ); /** Fit a range to cover nRows number of unfiltered rows. @return <TRUE/> if the resulting range covers nRows unfiltered rows. */ - static bool FitToUnfilteredRows( ScRange & rRange, const ScDocument * pDoc, size_t nRows ); + static bool FitToUnfilteredRows( ScRange & rRange, ScDocument * pDoc, size_t nRows ); static void UnmarkFiltered( ScMarkData& rMark, ScDocument* pDoc ); static void HideDisabledSlot( SfxItemSet& rSet, SfxBindings& rBindings, USHORT nSlotId ); diff --git a/sc/source/ui/miscdlgs/acredlin.src b/sc/source/ui/miscdlgs/acredlin.src index cad4747acb63..4baa9f3d388c 100644 --- a/sc/source/ui/miscdlgs/acredlin.src +++ b/sc/source/ui/miscdlgs/acredlin.src @@ -170,7 +170,6 @@ Menu RID_POPUP_CHANGES MenuItem { Identifier = SC_SUB_SORT ; - RadioCheck = TRUE ; SubMenu = Menu { ItemList = diff --git a/sc/source/ui/miscdlgs/makefile.mk b/sc/source/ui/miscdlgs/makefile.mk index ac210bcfaa83..d34994341ade 100644 --- a/sc/source/ui/miscdlgs/makefile.mk +++ b/sc/source/ui/miscdlgs/makefile.mk @@ -46,6 +46,7 @@ SLOFILES = \ $(SLO)$/delcodlg.obj \ $(SLO)$/inscodlg.obj \ $(SLO)$/strindlg.obj \ + $(SLO)$/tabbgcolordlg.obj \ $(SLO)$/mtrindlg.obj \ $(SLO)$/lbseldlg.obj \ $(SLO)$/filldlg.obj \ diff --git a/sc/source/ui/miscdlgs/tabbgcolordlg.cxx b/sc/source/ui/miscdlgs/tabbgcolordlg.cxx new file mode 100644 index 000000000000..fdc4c9fd34bf --- /dev/null +++ b/sc/source/ui/miscdlgs/tabbgcolordlg.cxx @@ -0,0 +1,199 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tabbgcolordlg.cxx,v $ + * $Revision: 1.0 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +#undef SC_DLLIMPLEMENTATION + +//------------------------------------------------------------------ + +#include "tabbgcolordlg.hxx" +#include "scresid.hxx" +#include "miscdlgs.hrc" + +#include "tools/debug.hxx" +#include "tools/color.hxx" +#include "sfx2/objsh.hxx" +#include "svx/xtable.hxx" +#include "svx/drawitem.hxx" +#include "unotools/pathoptions.hxx" +#include "tools/resid.hxx" +#include "editeng/editrids.hrc" + +#include <boost/scoped_ptr.hpp> + +//================================================================== + +#define HDL(hdl) LINK(this,ScTabBgColorDlg,hdl) + +ScTabBgColorDlg::ScTabBgColorDlg( Window* pParent, + const String& rTitle, + const String& rTabBgColorNoColorText, + const Color& rDefaultColor, + ULONG nHelpId ) : + ModalDialog ( pParent, ScResId( RID_SCDLG_TAB_BG_COLOR ) ), + aBorderWin ( this, ScResId( TAB_BG_COLOR_CT_BORDER ) ), + aTabBgColorSet ( &aBorderWin, ScResId( TAB_BG_COLOR_SET_BGDCOLOR ), this ), + aTabBgColorBox ( this, ScResId( TAB_BG_COLOR_GB_BGDCOLOR ) ), + aBtnOk ( this, ScResId( BTN_OK ) ), + aBtnCancel ( this, ScResId( BTN_CANCEL ) ), + aBtnHelp ( this, ScResId( BTN_HELP ) ), + aTabBgColor ( rDefaultColor ), + aTabBgColorNoColorText ( rTabBgColorNoColorText ), + mnHelpId ( nHelpId ) + +{ + SetHelpId( nHelpId ); + this->SetText( rTitle ); + this->SetStyle(GetStyle() | WB_BORDER | WB_STDFLOATWIN | WB_3DLOOK | WB_DIALOGCONTROL | WB_SYSTEMWINDOW | WB_STANDALONE | WB_HIDE); + + aTabBgColorBox.SetText(rTitle); + FillColorValueSets_Impl(); + aTabBgColorSet.SetDoubleClickHdl( HDL(TabBgColorDblClickHdl_Impl) ); + aBtnOk.SetClickHdl( HDL(TabBgColorOKHdl_Impl) ); + FreeResource(); +} + +//------------------------------------------------------------------------ + +void ScTabBgColorDlg::GetSelectedColor( Color& rColor ) const +{ + rColor = this->aTabBgColor; +} + +ScTabBgColorDlg::~ScTabBgColorDlg() +{ +} + +void ScTabBgColorDlg::FillColorValueSets_Impl() +{ + SfxObjectShell* pDocSh = SfxObjectShell::Current(); + const SfxPoolItem* pItem = NULL; + XColorTable* pColorTable = NULL; + ::boost::scoped_ptr<XColorTable> pOwnColorTable; // locally instantiated in case the doc shell doesn't have one. + + const Size aSize15x15 = Size( 15, 15 ); + const Size aSize10x10 = Size( 10, 10 ); + const Size aSize5x5 = Size( 5, 5 ); + USHORT nSelectedItem = 0; + + DBG_ASSERT( pDocSh, "DocShell not found!" ); + + if ( pDocSh && ( 0 != ( pItem = pDocSh->GetItem(SID_COLOR_TABLE) ) ) ) + pColorTable = ( (SvxColorTableItem*)pItem )->GetColorTable(); + if ( !pColorTable ) + { + pOwnColorTable.reset(new XColorTable(SvtPathOptions().GetPalettePath())); + pColorTable = pOwnColorTable.get(); + } + if ( pColorTable ) + { + sal_uInt16 i = 0; + long nCount = pColorTable->Count(); + XColorEntry* pEntry = NULL; + Color aColWhite( COL_WHITE ); + String aStrWhite( ScResId( RID_SVXITEMS_COLOR_WHITE ) ); + WinBits nBits = ( aTabBgColorSet.GetStyle() | WB_NAMEFIELD | WB_ITEMBORDER | WB_NONEFIELD | WB_3DLOOK | WB_NO_DIRECTSELECT | WB_NOPOINTERFOCUS); + aTabBgColorSet.SetText( aTabBgColorNoColorText ); + aTabBgColorSet.SetStyle( nBits ); + for ( i = 0; i < nCount; i++ ) + { + pEntry = pColorTable->GetColor(i); + aTabBgColorSet.InsertItem( i + 1, pEntry->GetColor(), pEntry->GetName() ); + if (pEntry->GetColor() == aTabBgColor) + nSelectedItem = (i + 1); + } + + while ( i < 80 ) + { + aTabBgColorSet.InsertItem( i + 1, aColWhite, aStrWhite ); + i++; + } + + if ( nCount > 80 ) + { + aTabBgColorSet.SetStyle( nBits | WB_VSCROLL ); + } + } + aTabBgColorSet.SetColCount( 10 ); + aTabBgColorSet.SetLineCount( 10 ); + aTabBgColorSet.CalcWindowSizePixel( aSize15x15 ); + aTabBgColorSet.Format(); + aTabBgColorSet.SelectItem(nSelectedItem); + aTabBgColorSet.Resize(); +} + +IMPL_LINK( ScTabBgColorDlg, TabBgColorDblClickHdl_Impl, ValueSet*, EMPTYARG ) +/* + Handler, called when color selection is changed +*/ +{ + USHORT nItemId = aTabBgColorSet.GetSelectItemId(); + Color aColor = nItemId ? ( aTabBgColorSet.GetItemColor( nItemId ) ) : Color( COL_AUTO ); + aTabBgColor = aColor; + EndDialog( TRUE ); + return 0; +} + +IMPL_LINK( ScTabBgColorDlg, TabBgColorOKHdl_Impl, OKButton*, EMPTYARG ) +{ + +// Handler, called when the OK button is pushed + + USHORT nItemId = aTabBgColorSet.GetSelectItemId(); + Color aColor = nItemId ? ( aTabBgColorSet.GetItemColor( nItemId ) ) : Color( COL_AUTO ); + aTabBgColor = aColor; + EndDialog( TRUE ); + return 0; +} + +ScTabBgColorDlg::ScTabBgColorValueSet::ScTabBgColorValueSet( Control* pParent, const ResId& rResId, ScTabBgColorDlg* pTabBgColorDlg ) : + ValueSet(pParent, rResId) +{ + aTabBgColorDlg = pTabBgColorDlg; +} + +void ScTabBgColorDlg::ScTabBgColorValueSet::KeyInput( const KeyEvent& rKEvt ) +{ + switch ( rKEvt.GetKeyCode().GetCode() ) + { + case KEY_SPACE: + case KEY_RETURN: + { + USHORT nItemId = GetSelectItemId(); + const Color& aColor = nItemId ? ( GetItemColor( nItemId ) ) : Color( COL_AUTO ); + aTabBgColorDlg->aTabBgColor = aColor; + aTabBgColorDlg->EndDialog(TRUE); + } + break; + } + ValueSet::KeyInput(rKEvt); +} diff --git a/sc/source/ui/src/globstr.src b/sc/source/ui/src/globstr.src index bbf20c436065..6c15762bda6a 100644 --- a/sc/source/ui/src/globstr.src +++ b/sc/source/ui/src/globstr.src @@ -1123,6 +1123,14 @@ Resource RID_GLOBSTR { Text [ en-US ] = "Rename Sheet" ; }; + String STR_UNDO_SET_TAB_BG_COLOR + { + Text [ en-US ] = "Color Tab" ; + }; + String STR_UNDO_SET_MULTI_TAB_BG_COLOR + { + Text [ en-US ] = "Color Tabs" ; + }; String STR_UNDO_MOVE_TAB { Text [ en-US ] = "Move Sheets" ; diff --git a/sc/source/ui/src/miscdlgs.src b/sc/source/ui/src/miscdlgs.src index 06a19af7a8a7..6d4761c8589c 100644 --- a/sc/source/ui/src/miscdlgs.src +++ b/sc/source/ui/src/miscdlgs.src @@ -538,6 +538,96 @@ ModalDialog RID_SCDLG_STRINPUT Size = MAP_APPFONT ( 110 , 8 ) ; }; }; +ModalDialog RID_SCDLG_TAB_BG_COLOR +{ + OutputSize = TRUE ; + SVLook = TRUE ; + Size = MAP_APPFONT ( 118 , 167 ) ; + Moveable = TRUE ; + Closeable = TRUE ; + Control TAB_BG_COLOR_CT_BORDER + { + Border = TRUE ; + Pos = MAP_APPFONT ( 1 , 1 ) ; //12, 32 + Size = MAP_APPFONT ( 116+2 , 145+2 ) ; + DialogControl = TRUE; + }; + Control TAB_BG_COLOR_SET_BGDCOLOR + { + // * HelpId = HID_BACKGROUND_CTL_BGDCOLORSET ; + Hide = FALSE ; + Pos = MAP_APPFONT ( 0 , 0 ) ; + Size = MAP_APPFONT ( 116 , 145 ) ; + TabStop = TRUE ; + }; + CancelButton BTN_CANCEL + { + Pos = MAP_APPFONT ( 82 , 151 ) ; + Size = MAP_APPFONT ( 35 , 14 ) ; + TabStop = TRUE ; + DefButton = FALSE ; + }; + OKButton BTN_OK + { + Pos = MAP_APPFONT ( 45 , 151 ) ; + Size = MAP_APPFONT ( 35 , 14 ) ; + TabStop = TRUE ; + DefButton = TRUE ; + }; + HelpButton BTN_HELP + { + Pos = MAP_APPFONT ( 2 , 151 ) ; + Size = MAP_APPFONT ( 35 , 14 ) ; + TabStop = TRUE ; + DefButton = FALSE ; + }; +}; +/* +ModalDialog RID_SCDLG_TAB_BG_COLOR +{ + OutputSize = TRUE ; + SVLook = TRUE ; + Size = MAP_APPFONT ( 180 , 150 ) ; + Moveable = TRUE ; + Closeable = TRUE ; + Control TAB_BG_COLOR_CT_BORDER + { + Border = TRUE ; + Pos = MAP_APPFONT ( 1 , 1 ) ; //12, 32 + Size = MAP_APPFONT ( 116+2 , 145+2 ) ; + DialogControl = TRUE; + }; + Control TAB_BG_COLOR_SET_BGDCOLOR + { + // * HelpId = HID_BACKGROUND_CTL_BGDCOLORSET ; + Hide = FALSE ; + Pos = MAP_APPFONT ( 0 , 0 ) ; + Size = MAP_APPFONT ( 116 , 145 ) ; + TabStop = TRUE ; + }; + OKButton BTN_OK + { + Pos = MAP_APPFONT ( 125 , 50 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; + DefButton = TRUE ; + }; + CancelButton BTN_CANCEL + { + Pos = MAP_APPFONT ( 125 , 67 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; + DefButton = FALSE ; + }; + HelpButton BTN_HELP + { + Pos = MAP_APPFONT ( 125 , 84 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; + DefButton = FALSE ; + }; +}; +*/ /* ModalDialog RID_SCDLG_MTRINPUT { diff --git a/sc/source/ui/src/popup.src b/sc/source/ui/src/popup.src index abda5c9a0994..9753aa1590e3 100644 --- a/sc/source/ui/src/popup.src +++ b/sc/source/ui/src/popup.src @@ -190,6 +190,21 @@ Menu RID_POPUP_TAB HelpId = FID_TAB_RTL ; Text [ en-US ] = "S~heet Right-To-Left" ; }; + MenuItem + { + Identifier = FID_TAB_EVENTS ; + HelpId = FID_TAB_EVENTS ; + Text [ en-US ] = "Sheet E~vents..." ; + }; + //------------------------------ + MenuItem { Separator = TRUE ; }; + //------------------------------ + MenuItem + { + Identifier = FID_TAB_MENU_SET_TAB_BG_COLOR ; + HelpId = FID_TAB_MENU_SET_TAB_BG_COLOR ; + Text [ en-US ] = "~Tab Color..." ; + }; }; }; diff --git a/sc/source/ui/src/scstring.src b/sc/source/ui/src/scstring.src index 7f5337e11b89..9c47a42239cc 100644 --- a/sc/source/ui/src/scstring.src +++ b/sc/source/ui/src/scstring.src @@ -280,6 +280,14 @@ String SCSTR_RENAMETAB { Text [ en-US ] = "Rename Sheet" ; }; +String SCSTR_SET_TAB_BG_COLOR +{ + Text [ en-US ] = "Tab Color" ; +}; +String SCSTR_NO_TAB_BG_COLOR +{ + Text [ en-US ] = "Default" ; +}; String SCSTR_RENAMEOBJECT { Text [ en-US ] = "Name Object"; diff --git a/sc/source/ui/undo/makefile.mk b/sc/source/ui/undo/makefile.mk index 01edd92f8553..50fab82972ca 100644 --- a/sc/source/ui/undo/makefile.mk +++ b/sc/source/ui/undo/makefile.mk @@ -76,7 +76,8 @@ SLOFILES = \ EXCEPTIONSFILES= \ $(SLO)$/undoblk3.obj \ $(SLO)$/undocell.obj \ - $(SLO)$/undostyl.obj + $(SLO)$/undostyl.obj \ + $(SLO)$/undotab.obj # --- Tagets ------------------------------------------------------- diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx index a35ba96112e3..c284045c5b11 100644 --- a/sc/source/ui/undo/undoblk.cxx +++ b/sc/source/ui/undo/undoblk.cxx @@ -1148,10 +1148,10 @@ ScUndoDragDrop::ScUndoDragDrop( ScDocShell* pNewDocShell, BOOL bIncludeFiltered = bCut; if ( !bIncludeFiltered ) { - // manually find number of non-filtered rows - SCROW nPastedCount = pDocShell->GetDocument()->GetRowFlagsArray( - aSrcRange.aStart.Tab()).CountForCondition( - aSrcRange.aStart.Row(), aSrcRange.aEnd.Row(), CR_FILTERED, 0); + // find number of non-filtered rows + SCROW nPastedCount = pDocShell->GetDocument()->CountNonFilteredRows( + aSrcRange.aStart.Row(), aSrcRange.aEnd.Row(), aSrcRange.aStart.Tab()); + if ( nPastedCount == 0 ) nPastedCount = 1; aDestEnd.SetRow( aNewDestPos.Row() + nPastedCount - 1 ); diff --git a/sc/source/ui/undo/undoblk3.cxx b/sc/source/ui/undo/undoblk3.cxx index 4011d4755ab1..506afeac138e 100644 --- a/sc/source/ui/undo/undoblk3.cxx +++ b/sc/source/ui/undo/undoblk3.cxx @@ -1028,17 +1028,20 @@ void __EXPORT ScUndoAutoFormat::Redo() aDestMark.MarkToMulti(); // wie SC_SIZE_VISOPT + SCROW nLastRow = -1; for (SCROW nRow=nStartY; nRow<=nEndY; nRow++) { BYTE nOld = pDoc->GetRowFlags(nRow,nTab); - if ( (nOld & CR_HIDDEN) == 0 && ( nOld & CR_MANUALSIZE ) ) + bool bHidden = pDoc->RowHidden(nRow, nTab, nLastRow); + if ( !bHidden && ( nOld & CR_MANUALSIZE ) ) pDoc->SetRowFlags( nRow, nTab, nOld & ~CR_MANUALSIZE ); } pDoc->SetOptimalHeight( nStartY, nEndY, nTab, 0, &aVirtDev, nPPTX, nPPTY, aZoomX, aZoomY, FALSE ); + SCCOL nLastCol = -1; for (SCCOL nCol=nStartX; nCol<=nEndX; nCol++) - if ((pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN) == 0) + if (!pDoc->ColHidden(nCol, nTab, nLastCol)) { USHORT nThisSize = STD_EXTRA_WIDTH + pDoc->GetOptimalColWidth( nCol, nTab, &aVirtDev, nPPTX, nPPTY, aZoomX, aZoomY, bFormula, diff --git a/sc/source/ui/undo/undocell.cxx b/sc/source/ui/undo/undocell.cxx index 77142bb13799..cc13ce9f1412 100644 --- a/sc/source/ui/undo/undocell.cxx +++ b/sc/source/ui/undo/undocell.cxx @@ -568,6 +568,8 @@ void ScUndoPageBreak::DoChange( BOOL bInsertP ) const pViewShell->InsertPageBreak(bColumn, FALSE); else pViewShell->DeletePageBreak(bColumn, FALSE); + + pDocShell->GetDocument()->InvalidatePageBreaks(nTab); } } diff --git a/sc/source/ui/undo/undodat.cxx b/sc/source/ui/undo/undodat.cxx index d550d54f1aea..0f7834b2a8df 100644 --- a/sc/source/ui/undo/undodat.cxx +++ b/sc/source/ui/undo/undodat.cxx @@ -1027,7 +1027,10 @@ void __EXPORT ScUndoQuery::Undo() pDoc->SetDBCollection( new ScDBCollection( *pUndoDB ), TRUE ); if (!bCopy) + { + pDoc->InvalidatePageBreaks(nTab); pDoc->UpdatePageBreaks( nTab ); + } ScRange aDirtyRange( 0 , aQueryParam.nRow1, nTab, MAXCOL, aQueryParam.nRow2, nTab ); diff --git a/sc/source/ui/undo/undotab.cxx b/sc/source/ui/undo/undotab.cxx index 17f15af54701..2d8340ad030b 100644 --- a/sc/source/ui/undo/undotab.cxx +++ b/sc/source/ui/undo/undotab.cxx @@ -59,6 +59,7 @@ #include "printfun.hxx" #include "chgtrack.hxx" #include "tabprotection.hxx" +#include "viewdata.hxx" // for ScUndoRenameObject - might me moved to another file later #include <svx/svditer.hxx> @@ -90,6 +91,7 @@ TYPEINIT1(ScUndoScenarioFlags, SfxUndoAction); TYPEINIT1(ScUndoRenameObject, SfxUndoAction); TYPEINIT1(ScUndoLayoutRTL, SfxUndoAction); //UNUSED2009-05 TYPEINIT1(ScUndoSetGrammar, SfxUndoAction); +TYPEINIT1(ScUndoTabColor, SfxUndoAction); // ----------------------------------------------------------------------- @@ -411,6 +413,8 @@ void ScUndoDeleteTab::Undo() pDoc->SetActiveScenario( nTab, bActive ); } pDoc->SetVisible( nTab, pRefUndoDoc->IsVisible( nTab ) ); + pDoc->SetTabBgColor( nTab, pRefUndoDoc->GetTabBgColor(nTab) ); + pDoc->SetSheetEvents( nTab, pRefUndoDoc->GetSheetEvents( nTab ) ); if ( pRefUndoDoc->IsTabProtected( nTab ) ) pDoc->SetTabProtection(nTab, pRefUndoDoc->GetTabProtection(nTab)); @@ -776,6 +780,78 @@ BOOL ScUndoCopyTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const return FALSE; } +//--------------------------------------------------------------------------------- +// +// Tab Bg Color +// + +ScUndoTabColor::ScUndoTabColor( + ScDocShell* pNewDocShell, SCTAB nT, const Color& aOTabBgColor, const Color& aNTabBgColor) : + ScSimpleUndo( pNewDocShell ) +{ + ScUndoTabColorInfo aInfo(nT); + aInfo.maOldTabBgColor = aOTabBgColor; + aInfo.maNewTabBgColor = aNTabBgColor; + aTabColorList.push_back(aInfo); +} + +ScUndoTabColor::ScUndoTabColor( + ScDocShell* pNewDocShell, + const ScUndoTabColorInfo::List& rUndoTabColorList) : + ScSimpleUndo(pNewDocShell), + aTabColorList(rUndoTabColorList) +{ +} + +ScUndoTabColor::~ScUndoTabColor() +{ +} + +String ScUndoTabColor::GetComment() const +{ + if (aTabColorList.size() > 1) + return ScGlobal::GetRscString(STR_UNDO_SET_MULTI_TAB_BG_COLOR); + return ScGlobal::GetRscString(STR_UNDO_SET_TAB_BG_COLOR); +} + +void ScUndoTabColor::DoChange(bool bUndoType) const +{ + ScDocument* pDoc = pDocShell->GetDocument(); + if (!pDoc) + return; + + size_t nTabColorCount = aTabColorList.size(); + for (size_t i = 0; i < nTabColorCount; ++i) + { + const ScUndoTabColorInfo& rTabColor = aTabColorList[i]; + pDoc->SetTabBgColor(rTabColor.mnTabId, + bUndoType ? rTabColor.maOldTabBgColor : rTabColor.maNewTabBgColor); + } + + pDocShell->PostPaintExtras(); + ScDocShellModificator aModificator( *pDocShell ); + aModificator.SetDocumentModified(); +} + +void ScUndoTabColor::Undo() +{ + DoChange(true); +} + +void ScUndoTabColor::Redo() +{ + DoChange(false); +} + +void ScUndoTabColor::Repeat(SfxRepeatTarget& /* rTarget */) +{ + // No Repeat +} + +BOOL ScUndoTabColor::CanRepeat(SfxRepeatTarget& /* rTarget */) const +{ + return FALSE; +} // ----------------------------------------------------------------------- // diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx index 980a73307797..dea7cc056756 100644 --- a/sc/source/ui/unoobj/cellsuno.cxx +++ b/sc/source/ui/unoobj/cellsuno.cxx @@ -84,6 +84,7 @@ #include "srchuno.hxx" #include "targuno.hxx" #include "tokenuno.hxx" +#include "eventuno.hxx" #include "docsh.hxx" #include "markdata.hxx" #include "patattr.hxx" @@ -769,6 +770,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_UNONAME_TABCOLOR), SC_WID_UNO_TABCOLOR, &getCppuType((sal_Int32*)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} }; @@ -3375,18 +3377,25 @@ uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryVisibleC ScMarkData aMarkData(*GetMarkData()); ScDocument* pDoc = pDocShell->GetDocument(); - for (SCCOL nCol=0; nCol<=MAXCOL; nCol++) - if (pDoc->GetColFlags(nCol,nTab) & CR_HIDDEN) - aMarkData.SetMultiMarkArea( ScRange( nCol,0,nTab, nCol,MAXROW,nTab ), FALSE ); + SCCOL nCol = 0, nLastCol; + while (nCol <= MAXCOL) + { + if (pDoc->ColHidden(nCol, nTab, nLastCol)) + // hidden columns. Unselect them. + aMarkData.SetMultiMarkArea(ScRange(nCol, 0, nTab, nLastCol, MAXROW, nTab), false); - //! nur bis zur letzten selektierten Zeile testen? - ScCompressedArrayIterator< SCROW, BYTE> aIter( pDoc->GetRowFlagsArray( nTab), 0, MAXROW); - do + nCol = nLastCol + 1; + } + + SCROW nRow = 0, nLastRow; + while (nRow <= MAXROW) { - if (*aIter & CR_HIDDEN) - aMarkData.SetMultiMarkArea( ScRange( 0, aIter.GetRangeStart(), - nTab, MAXCOL, aIter.GetRangeEnd(), nTab ), FALSE ); - } while (aIter.NextRange()); + if (pDoc->RowHidden(nRow, nTab, nLastRow)) + // These rows are hidden. Unselect them. + aMarkData.SetMultiMarkArea(ScRange(0, nRow, nTab, MAXCOL, nLastRow, nTab), false); + + nRow = nLastRow + 1; + } ScRangeList aNewRanges; aMarkData.FillRangeListWithMarks( &aNewRanges, FALSE ); @@ -6837,6 +6846,7 @@ uno::Any SAL_CALL ScTableSheetObj::queryInterface( const uno::Type& rType ) thro SC_QUERYINTERFACE( sheet::XScenarioEnhanced ) SC_QUERYINTERFACE( sheet::XSheetLinkable ) SC_QUERYINTERFACE( sheet::XExternalSheetName ) + SC_QUERYINTERFACE( document::XEventsSupplier ) return ScCellRangeObj::queryInterface( rType ); } @@ -6860,7 +6870,7 @@ uno::Sequence<uno::Type> SAL_CALL ScTableSheetObj::getTypes() throw(uno::Runtime long nParentLen = aParentTypes.getLength(); const uno::Type* pParentPtr = aParentTypes.getConstArray(); - aTypes.realloc( nParentLen + 17 ); + aTypes.realloc( nParentLen + 18 ); uno::Type* pPtr = aTypes.getArray(); pPtr[nParentLen + 0] = getCppuType((const uno::Reference<sheet::XSpreadsheet>*)0); pPtr[nParentLen + 1] = getCppuType((const uno::Reference<container::XNamed>*)0); @@ -6879,6 +6889,7 @@ uno::Sequence<uno::Type> SAL_CALL ScTableSheetObj::getTypes() throw(uno::Runtime pPtr[nParentLen +14] = getCppuType((const uno::Reference<sheet::XScenarioEnhanced>*)0); pPtr[nParentLen +15] = getCppuType((const uno::Reference<sheet::XSheetLinkable>*)0); pPtr[nParentLen +16] = getCppuType((const uno::Reference<sheet::XExternalSheetName>*)0); + pPtr[nParentLen +17] = getCppuType((const uno::Reference<document::XEventsSupplier>*)0); for (long i=0; i<nParentLen; i++) pPtr[i] = pParentPtr[i]; // parent types first @@ -7050,7 +7061,7 @@ uno::Sequence<sheet::TablePageBreakData> SAL_CALL ScTableSheetObj::getColumnPage SCCOL nCount = 0; SCCOL nCol; for (nCol=0; nCol<=MAXCOL; nCol++) - if (pDoc->GetColFlags( nCol, nTab ) & ( CR_PAGEBREAK | CR_MANUALBREAK )) + if (pDoc->HasColBreak(nCol, nTab)) ++nCount; sheet::TablePageBreakData aData; @@ -7059,11 +7070,11 @@ uno::Sequence<sheet::TablePageBreakData> SAL_CALL ScTableSheetObj::getColumnPage USHORT nPos = 0; for (nCol=0; nCol<=MAXCOL; nCol++) { - BYTE nFlags = pDoc->GetColFlags( nCol, nTab ); - if (nFlags & ( CR_PAGEBREAK | CR_MANUALBREAK )) + ScBreakType nBreak = pDoc->HasColBreak(nCol, nTab); + if (nBreak) { aData.Position = nCol; - aData.ManualBreak = ( nFlags & CR_MANUALBREAK ) != 0; + aData.ManualBreak = (nBreak & BREAK_MANUAL); pAry[nPos] = aData; ++nPos; } @@ -7092,33 +7103,7 @@ uno::Sequence<sheet::TablePageBreakData> SAL_CALL ScTableSheetObj::getRowPageBre ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab ); aPrintFunc.UpdatePages(); } - - SCROW nCount = pDoc->GetRowFlagsArray( nTab).CountForAnyBitCondition( - 0, MAXROW, (CR_PAGEBREAK | CR_MANUALBREAK)); - - uno::Sequence<sheet::TablePageBreakData> aSeq(nCount); - if (nCount) - { - sheet::TablePageBreakData aData; - sheet::TablePageBreakData* pAry = aSeq.getArray(); - size_t nPos = 0; - ScCompressedArrayIterator< SCROW, BYTE> aIter( pDoc->GetRowFlagsArray( nTab), 0, MAXROW); - do - { - BYTE nFlags = *aIter; - if (nFlags & ( CR_PAGEBREAK | CR_MANUALBREAK )) - { - for (SCROW nRow = aIter.GetRangeStart(); nRow <= aIter.GetRangeEnd(); ++nRow) - { - aData.Position = nRow; - aData.ManualBreak = ( nFlags & CR_MANUALBREAK ) != 0; - pAry[nPos] = aData; - ++nPos; - } - } - } while (aIter.NextRange()); - } - return aSeq; + return pDoc->GetRowBreakData(nTab); } return uno::Sequence<sheet::TablePageBreakData>(0); } @@ -8160,6 +8145,18 @@ void ScTableSheetObj::setExternalName( const ::rtl::OUString& aUrl, const ::rtl: } } +// XEventsSupplier + +uno::Reference<container::XNameReplace> SAL_CALL ScTableSheetObj::getEvents() throw (uno::RuntimeException) +{ + ScUnoGuard aGuard; + ScDocShell* pDocSh = GetDocShell(); + if ( pDocSh ) + return new ScSheetEventsObj( pDocSh, GetTab_Impl() ); + + return NULL; +} + // XPropertySet erweitert fuer Sheet-Properties uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableSheetObj::getPropertySetInfo() @@ -8471,15 +8468,24 @@ 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 ) + else if ( pEntry->nWID == SC_WID_UNO_TABCOLOR ) { - rtl::OUString aCodeName; - if ( pDocSh && ( aValue >>= aCodeName ) ) + sal_Int32 nColor = COL_AUTO; + if (aValue >>= nColor) + { + if (static_cast<ColorData>(nColor) != COL_AUTO) + pDoc->SetTabBgColor(nTab, Color(static_cast<ColorData>(nColor))); + } + } + else if ( pEntry->nWID == SC_WID_UNO_CODENAME ) { - String sNewName( aCodeName ); - pDocSh->GetDocument()->SetCodeName( GetTab_Impl(), sNewName ); + 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 } @@ -8618,13 +8624,17 @@ void ScTableSheetObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEn BOOL bAutoPrint = pDoc->IsPrintEntireSheet( nTab ); ScUnoHelpFunctions::SetBoolInAny( rAny, bAutoPrint ); } + else if ( pEntry->nWID == SC_WID_UNO_TABCOLOR ) + { + rAny <<= sal_Int32(pDoc->GetTabBgColor(nTab).GetColor()); + } else if ( pEntry->nWID == SC_WID_UNO_CODENAME ) { - String aCodeName; - if ( pDocSh ) - pDocSh->GetDocument()->GetCodeName( GetTab_Impl(), aCodeName ); - rAny <<= rtl::OUString( aCodeName ); - } + String aCodeName; + if ( pDocSh ) + pDocSh->GetDocument()->GetCodeName( GetTab_Impl(), aCodeName ); + rAny <<= rtl::OUString( aCodeName ); + } else ScCellRangeObj::GetOnePropertyValue(pEntry, rAny); } @@ -8893,8 +8903,9 @@ void ScTableColumnObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pE } else if ( pEntry->nWID == SC_WID_UNO_CELLVIS ) { - BOOL bVis = !(pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN); - ScUnoHelpFunctions::SetBoolInAny( rAny, bVis ); + SCCOL nDummy; + bool bHidden = pDoc->ColHidden(nCol, nTab, nDummy); + ScUnoHelpFunctions::SetBoolInAny( rAny, !bHidden ); } else if ( pEntry->nWID == SC_WID_UNO_OWIDTH ) { @@ -8904,13 +8915,13 @@ void ScTableColumnObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pE } else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE ) { - BOOL bBreak = ( 0 != (pDoc->GetColFlags( nCol, nTab ) & (CR_PAGEBREAK|CR_MANUALBREAK)) ); - ScUnoHelpFunctions::SetBoolInAny( rAny, bBreak ); + ScBreakType nBreak = pDoc->HasColBreak(nCol, nTab); + ScUnoHelpFunctions::SetBoolInAny( rAny, nBreak ); } else if ( pEntry->nWID == SC_WID_UNO_MANPAGE ) { - BOOL bBreak = ( 0 != (pDoc->GetColFlags( nCol, nTab ) & (CR_MANUALBREAK)) ); - ScUnoHelpFunctions::SetBoolInAny( rAny, bBreak ); + ScBreakType nBreak = pDoc->HasColBreak(nCol, nTab); + ScUnoHelpFunctions::SetBoolInAny(rAny, (nBreak & BREAK_MANUAL)); } else ScCellRangeObj::GetOnePropertyValue(pEntry, rAny); @@ -8996,12 +9007,7 @@ void ScTableRowObj::SetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntr // ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT; // aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, nTab, eMode, 0, TRUE, TRUE ); // SC_SIZE_DIRECT mit Groesse 0 blendet aus - BYTE nFlags = pDoc->GetRowFlags(nRow, nTab); - if (bFil) - nFlags |= CR_FILTERED; - else - nFlags &= ~CR_FILTERED; - pDoc->SetRowFlags(nRow, nTab, nFlags); + pDoc->SetRowFiltered(nRow, nRow, nTab, bFil); } else if ( pEntry->nWID == SC_WID_UNO_OHEIGHT ) { @@ -9053,12 +9059,13 @@ void ScTableRowObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntr } else if ( pEntry->nWID == SC_WID_UNO_CELLVIS ) { - BOOL bVis = !(pDoc->GetRowFlags( nRow, nTab ) & CR_HIDDEN); - ScUnoHelpFunctions::SetBoolInAny( rAny, bVis ); + SCROW nDummy; + bool bHidden = pDoc->RowHidden(nRow, nTab, nDummy); + ScUnoHelpFunctions::SetBoolInAny( rAny, !bHidden ); } else if ( pEntry->nWID == SC_WID_UNO_CELLFILT ) { - BOOL bVis = ((pDoc->GetRowFlags( nRow, nTab ) & CR_FILTERED) != 0); + bool bVis = pDoc->RowFiltered(nRow, nTab); ScUnoHelpFunctions::SetBoolInAny( rAny, bVis ); } else if ( pEntry->nWID == SC_WID_UNO_OHEIGHT ) @@ -9068,13 +9075,13 @@ void ScTableRowObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntr } else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE ) { - BOOL bBreak = ( 0 != (pDoc->GetRowFlags( nRow, nTab ) & (CR_PAGEBREAK|CR_MANUALBREAK)) ); - ScUnoHelpFunctions::SetBoolInAny( rAny, bBreak ); + ScBreakType nBreak = pDoc->HasRowBreak(nRow, nTab); + ScUnoHelpFunctions::SetBoolInAny( rAny, nBreak ); } else if ( pEntry->nWID == SC_WID_UNO_MANPAGE ) { - BOOL bBreak = ( 0 != (pDoc->GetRowFlags( nRow, nTab ) & (CR_MANUALBREAK)) ); - ScUnoHelpFunctions::SetBoolInAny( rAny, bBreak ); + ScBreakType nBreak = (pDoc->HasRowBreak(nRow, nTab) & BREAK_MANUAL); + ScUnoHelpFunctions::SetBoolInAny( rAny, nBreak ); } else ScCellRangeObj::GetOnePropertyValue(pEntry, rAny); diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx index 8654de8a429e..8a8081e412d3 100644 --- a/sc/source/ui/unoobj/chart2uno.cxx +++ b/sc/source/ui/unoobj/chart2uno.cxx @@ -2569,14 +2569,17 @@ void ScChart2DataSequence::BuildDataCache() if (!ScRefTokenHelper::getRangeFromToken(aRange, *itr)) continue; + SCCOL nLastCol = -1; + SCROW nLastRow = -1; for (SCTAB nTab = aRange.aStart.Tab(); nTab <= aRange.aEnd.Tab(); ++nTab) { for (SCCOL nCol = aRange.aStart.Col(); nCol <= aRange.aEnd.Col(); ++nCol) { for (SCROW nRow = aRange.aStart.Row(); nRow <= aRange.aEnd.Row(); ++nRow) { - bool bColHidden = (m_pDocument->GetColFlags(nCol, nTab) & CR_HIDDEN); - bool bRowHidden = (m_pDocument->GetRowFlags(nRow, nTab) & CR_HIDDEN); + bool bColHidden = m_pDocument->ColHidden(nCol, nTab, nLastCol); + bool bRowHidden = m_pDocument->RowHidden(nRow, nTab, nLastRow); + if (bColHidden || bRowHidden) { // hidden cell diff --git a/sc/source/ui/unoobj/chartuno.cxx b/sc/source/ui/unoobj/chartuno.cxx index 201c411ea45c..86f59d66a7a4 100644 --- a/sc/source/ui/unoobj/chartuno.cxx +++ b/sc/source/ui/unoobj/chartuno.cxx @@ -31,10 +31,12 @@ #include <com/sun/star/embed/Aspects.hpp> #include <com/sun/star/awt/Size.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> #include <com/sun/star/chart2/data/XDataReceiver.hpp> #include <com/sun/star/chart/ChartDataRowSource.hpp> #include <com/sun/star/chart2/XChartDocument.hpp> #include <com/sun/star/embed/Aspects.hpp> +#include <com/sun/star/table/CellRangeAddress.hpp> #include <svx/svditer.hxx> #include <svx/svdoole2.hxx> @@ -54,9 +56,12 @@ #include "chartlis.hxx" #include "unoguard.hxx" #include "chart2uno.hxx" +#include "convuno.hxx" using namespace com::sun::star; +#define PROP_HANDLE_RELATED_CELLRANGES 1 + //------------------------------------------------------------------------ SC_SIMPLE_SERVICE_INFO( ScChartObj, "ScChartObj", "com.sun.star.table.TableChart" ) @@ -222,7 +227,7 @@ void SAL_CALL ScChartsObj::addNewByName( const rtl::OUString& aName, xObj = pDocShell->GetEmbeddedObjectContainer().CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID ).GetByteSequence(), aTmp ); if ( xObj.is() ) { - String aObjName = aNameString; // wirklich eingefuegter Name... + String aObjName = aTmp; // wirklich eingefuegter Name... // Rechteck anpassen //! Fehler/Exception, wenn leer/ungueltig ??? @@ -451,12 +456,19 @@ sal_Bool SAL_CALL ScChartsObj::hasByName( const rtl::OUString& aName ) //------------------------------------------------------------------------ -ScChartObj::ScChartObj(ScDocShell* pDocSh, SCTAB nT, const String& rN) : - pDocShell( pDocSh ), - nTab( nT ), - aChartName( rN ) +ScChartObj::ScChartObj(ScDocShell* pDocSh, SCTAB nT, const String& rN) + :ScChartObj_Base( m_aMutex ) + ,ScChartObj_PBase( ScChartObj_Base::rBHelper ) + ,pDocShell( pDocSh ) + ,nTab( nT ) + ,aChartName( rN ) { pDocShell->GetDocument()->AddUnoObject(*this); + + uno::Sequence< table::CellRangeAddress > aInitialPropValue; + registerPropertyNoMember( ::rtl::OUString::createFromAscii( "RelatedCellRanges" ), + PROP_HANDLE_RELATED_CELLRANGES, beans::PropertyAttribute::MAYBEVOID, + ::getCppuType( &aInitialPropValue ), &aInitialPropValue ); } ScChartObj::~ScChartObj() @@ -552,6 +564,117 @@ void ScChartObj::Update_Impl( const ScRangeListRef& rRanges, bool bColHeaders, b } } +// ::comphelper::OPropertySetHelper + +::cppu::IPropertyArrayHelper& ScChartObj::getInfoHelper() +{ + return *ScChartObj_PABase::getArrayHelper(); +} + +void ScChartObj::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const uno::Any& rValue ) throw (uno::Exception) +{ + switch ( nHandle ) + { + case PROP_HANDLE_RELATED_CELLRANGES: + { + uno::Sequence< table::CellRangeAddress > aCellRanges; + if ( rValue >>= aCellRanges ) + { + ScRangeListRef rRangeList = new ScRangeList(); + const table::CellRangeAddress* pCellRanges = aCellRanges.getArray(); + sal_Int32 nCount = aCellRanges.getLength(); + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + table::CellRangeAddress aCellRange = pCellRanges[ i ]; + ScRange aRange; + ScUnoConversion::FillScRange( aRange, aCellRange ); + rRangeList->Append( aRange ); + } + ScDocument* pDoc = ( pDocShell ? pDocShell->GetDocument() : NULL ); + ScChartListenerCollection* pCollection = ( pDoc ? pDoc->GetChartListenerCollection() : NULL ); + if ( pCollection ) + { + pCollection->ChangeListening( aChartName, rRangeList ); + } + } + } + break; + default: + { + } + break; + } +} + +void ScChartObj::getFastPropertyValue( uno::Any& rValue, sal_Int32 nHandle ) const +{ + switch ( nHandle ) + { + case PROP_HANDLE_RELATED_CELLRANGES: + { + ScDocument* pDoc = ( pDocShell ? pDocShell->GetDocument() : NULL ); + if ( pDoc ) + { + ScRange aEmptyRange; + USHORT nIndex = 0; + ScChartListener aSearcher( aChartName, pDoc, aEmptyRange ); + ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection(); + if ( pCollection && pCollection->Search( &aSearcher, nIndex ) ) + { + ScChartListener* pListener = static_cast< ScChartListener* >( pCollection->At( nIndex ) ); + if ( pListener ) + { + const ScRangeListRef& rRangeList = pListener->GetRangeList(); + if ( rRangeList.Is() ) + { + ULONG nCount = rRangeList->Count(); + uno::Sequence< table::CellRangeAddress > aCellRanges( nCount ); + table::CellRangeAddress* pCellRanges = aCellRanges.getArray(); + for ( USHORT i = 0; i < nCount; ++i ) + { + ScRange aRange( *rRangeList->GetObject( i ) ); + table::CellRangeAddress aCellRange; + ScUnoConversion::FillApiRange( aCellRange, aRange ); + pCellRanges[ i ] = aCellRange; + } + rValue <<= aCellRanges; + } + } + } + } + } + break; + default: + { + } + break; + } +} + +// ::comphelper::OPropertyArrayUsageHelper + +::cppu::IPropertyArrayHelper* ScChartObj::createArrayHelper() const +{ + uno::Sequence< beans::Property > aProps; + describeProperties( aProps ); + return new ::cppu::OPropertyArrayHelper( aProps ); +} + +// XInterface + +IMPLEMENT_FORWARD_XINTERFACE2( ScChartObj, ScChartObj_Base, ScChartObj_PBase ) + +// XTypeProvider + +IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScChartObj, ScChartObj_Base, ScChartObj_PBase ) + +// XComponent + +void ScChartObj::disposing() +{ + ScChartObj_Base::disposing(); +} + // XTableChart sal_Bool SAL_CALL ScChartObj::getHasColumnHeaders() throw(uno::RuntimeException) @@ -681,6 +804,13 @@ void SAL_CALL ScChartObj::setName( const rtl::OUString& /* aName */ ) throw(uno: throw uno::RuntimeException(); // name cannot be changed } +// XPropertySet + +uno::Reference< beans::XPropertySetInfo > ScChartObj::getPropertySetInfo() throw (uno::RuntimeException) +{ + return createPropertySetInfo( getInfoHelper() ) ; +} + //------------------------------------------------------------------------ diff --git a/sc/source/ui/unoobj/confuno.cxx b/sc/source/ui/unoobj/confuno.cxx index dd8f15359559..75e415b8f018 100644 --- a/sc/source/ui/unoobj/confuno.cxx +++ b/sc/source/ui/unoobj/confuno.cxx @@ -88,6 +88,7 @@ const SfxItemPropertyMapEntry* lcl_GetConfigPropertyMap() {MAP_CHAR_LEN(SC_UNO_LOADREADONLY), 0, &getBooleanCppuType(), 0, 0}, // <-- {MAP_CHAR_LEN(SC_UNO_SHAREDOC), 0, &getBooleanCppuType(), 0, 0}, + {MAP_CHAR_LEN(SC_UNO_MODIFYPASSWORDINFO), 0, &getCppuType((uno::Sequence< beans::PropertyValue >*)0), 0, 0}, {0,0,0,0,0,0} }; return aConfigPropertyMap_Impl; @@ -274,6 +275,20 @@ void SAL_CALL ScDocumentConfiguration::setPropertyValue( pDocShell->SetSharedXMLFlag( bDocShared ); } } + else if ( aPropertyName.compareToAscii( SC_UNO_MODIFYPASSWORDINFO ) == 0 ) + { + uno::Sequence< beans::PropertyValue > aInfo; + if ( !( aValue >>= aInfo ) ) + throw lang::IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Value of type Sequence<PropertyValue> expected!" ) ), + uno::Reference< uno::XInterface >(), + 2 ); + + if ( !pDocShell->SetModifyPasswordInfo( aInfo ) ) + throw beans::PropertyVetoException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "The hash is not allowed to be changed now!" ) ), + uno::Reference< uno::XInterface >() ); + } else { ScGridOptions aGridOpt(aViewOpt.GetGridOptions()); @@ -407,6 +422,8 @@ uno::Any SAL_CALL ScDocumentConfiguration::getPropertyValue( const rtl::OUString { ScUnoHelpFunctions::SetBoolInAny( aRet, pDocShell->HasSharedXMLFlagSet() ); } + else if ( aPropertyName.compareToAscii( SC_UNO_MODIFYPASSWORDINFO ) == 0 ) + aRet <<= pDocShell->GetModifyPasswordInfo(); else { const ScGridOptions& aGridOpt = aViewOpt.GetGridOptions(); diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index d9fb4d53e634..6d267d4098ff 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -96,6 +96,7 @@ #include "scmod.hxx" #include "rangeutl.hxx" #include "ViewSettingsSequenceDefines.hxx" +#include "sheetevents.hxx" #include "sc.hrc" #include "scresid.hxx" @@ -367,8 +368,7 @@ ScModelObj::ScModelObj( ScDocShell* pDocSh ) : pDocShell( pDocSh ), pPrintFuncCache( NULL ), pPrinterOptions( NULL ), - maChangesListeners( m_aMutex ), - mnXlsWriteProtPass( 0 ) + maChangesListeners( m_aMutex ) { // pDocShell may be NULL if this is the base of a ScDocOptionsObj if ( pDocShell ) @@ -591,6 +591,10 @@ void ScModelObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) // (if a broadcast is added to SetDrawModified, is has to be tested here, too) DELETEZ( pPrintFuncCache ); + + // handle "OnCalculate" sheet events + if ( pDocShell && pDocShell->GetDocument()->HasSheetEventScript( SC_SHEETEVENT_CALCULATE ) ) + HandleCalculateEvents(); } } else if ( rHint.ISA( ScPointerChangedHint ) ) @@ -1746,14 +1750,6 @@ void SAL_CALL ScModelObj::setPropertyValue( if ( aObjName.getLength() ) pDoc->RestoreChartListener( aObjName ); } - else if ( aString.EqualsAscii( "WriteProtectionPassword" ) ) - { - /* This is a hack for #160550# to preserve the write-protection - password in an XLS roundtrip. This property MUST NOT be used - for any other purpose. This property will be deleted when the - feature "Write Protection With Password" will be implemented. */ - aValue >>= mnXlsWriteProtPass; - } if ( aNewOpt != rOldOpt ) { @@ -1922,14 +1918,6 @@ uno::Any SAL_CALL ScModelObj::getPropertyValue( const rtl::OUString& aPropertyNa { ScUnoHelpFunctions::SetBoolInAny( aRet, (pDocShell->GetCreateMode() == SFX_CREATE_MODE_INTERNAL) ); } - else if ( aString.EqualsAscii( "WriteProtectionPassword" ) ) - { - /* This is a hack for #160550# to preserve the write-protection - password in an XLS roundtrip. This property MUST NOT be used - for any other purpose. This property will be deleted when the - feature "Write Protection With Password" will be implemented. */ - aRet <<= mnXlsWriteProtPass; - } } return aRet; @@ -2092,11 +2080,11 @@ sal_Int64 SAL_CALL ScModelObj::getSomething( } if ( rId.getLength() == 16 && - 0 == rtl_compareMemory( SfxObjectShell::getUnoTunnelId().getConstArray(), + 0 == rtl_compareMemory( SfxObjectShell::getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) - { - return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(pDocShell )); - } + { + 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 @@ -2165,7 +2153,23 @@ void ScModelObj::removeChangesListener( const uno::Reference< util::XChangesList bool ScModelObj::HasChangesListeners() const { - return ( maChangesListeners.getLength() > 0 ); + if ( maChangesListeners.getLength() > 0 ) + return true; + + if ( pDocShell ) + { + // "change" event set in any sheet? + ScDocument* pDoc = pDocShell->GetDocument(); + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab = 0; nTab < nTabCount; nTab++) + { + const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); + if (pEvents && pEvents->GetScript(SC_SHEETEVENT_CHANGE)) + return true; + } + } + + return false; } void ScModelObj::NotifyChanges( const ::rtl::OUString& rOperation, const ScRangeList& rRanges, @@ -2211,6 +2215,91 @@ void ScModelObj::NotifyChanges( const ::rtl::OUString& rOperation, const ScRange } } } + + // handle sheet events + //! separate method with ScMarkData? Then change HasChangesListeners back. + if ( rOperation.compareToAscii("cell-change") == 0 && pDocShell ) + { + ScMarkData aMarkData; + aMarkData.MarkFromRangeList( rRanges, FALSE ); + ScDocument* pDoc = pDocShell->GetDocument(); + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab = 0; nTab < nTabCount; nTab++) + if (aMarkData.GetTableSelect(nTab)) + { + const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); + if (pEvents) + { + const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_CHANGE); + if (pScript) + { + ScRangeList aTabRanges; // collect ranges on this sheet + ULONG nRangeCount = rRanges.Count(); + for ( ULONG nIndex = 0; nIndex < nRangeCount; ++nIndex ) + { + ScRange aRange( *rRanges.GetObject( nIndex ) ); + if ( aRange.aStart.Tab() == nTab ) + aTabRanges.Append( aRange ); + } + ULONG nTabRangeCount = aTabRanges.Count(); + if ( nTabRangeCount > 0 ) + { + uno::Reference<uno::XInterface> xTarget; + if ( nTabRangeCount == 1 ) + { + ScRange aRange( *aTabRanges.GetObject( 0 ) ); + if ( aRange.aStart == aRange.aEnd ) + xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellObj( pDocShell, aRange.aStart ) ) ); + else + xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellRangeObj( pDocShell, aRange ) ) ); + } + else + xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellRangesObj( pDocShell, aTabRanges ) ) ); + + uno::Sequence<uno::Any> aParams(1); + aParams[0] <<= xTarget; + + uno::Any aRet; + uno::Sequence<sal_Int16> aOutArgsIndex; + uno::Sequence<uno::Any> aOutArgs; + + /*ErrCode eRet =*/ pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); + } + } + } + } + } +} + +void ScModelObj::HandleCalculateEvents() +{ + if (pDocShell) + { + ScDocument* pDoc = pDocShell->GetDocument(); + // don't call events before the document is visible + // (might also set a flag on SFX_EVENT_LOADFINISHED and only disable while loading) + if ( pDoc->IsDocVisible() ) + { + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab = 0; nTab < nTabCount; nTab++) + { + const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); + if (pEvents) + { + const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_CALCULATE); + if (pScript && pDoc->HasCalcNotification(nTab)) + { + uno::Any aRet; + uno::Sequence<uno::Any> aParams; + uno::Sequence<sal_Int16> aOutArgsIndex; + uno::Sequence<uno::Any> aOutArgs; + pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); + } + } + } + } + pDoc->ResetCalcNotifications(); + } } //------------------------------------------------------------------------ @@ -2965,7 +3054,8 @@ uno::Any SAL_CALL ScTableColumnsObj::getPropertyValue( const rtl::OUString& aPro } else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) ) { - BOOL bVis = !(pDoc->GetColFlags( nStartCol, nTab ) & CR_HIDDEN); + SCCOL nLastCol; + bool bVis = !pDoc->ColHidden(nStartCol, nTab, nLastCol); ScUnoHelpFunctions::SetBoolInAny( aAny, bVis ); } else if ( aNameString.EqualsAscii( SC_UNONAME_OWIDTH ) ) @@ -2975,13 +3065,13 @@ uno::Any SAL_CALL ScTableColumnsObj::getPropertyValue( const rtl::OUString& aPro } else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) ) { - BOOL bBreak = ( 0 != (pDoc->GetColFlags( nStartCol, nTab ) & (CR_PAGEBREAK|CR_MANUALBREAK)) ); - ScUnoHelpFunctions::SetBoolInAny( aAny, bBreak ); + ScBreakType nBreak = pDoc->HasColBreak(nStartCol, nTab); + ScUnoHelpFunctions::SetBoolInAny( aAny, nBreak ); } else if ( aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) ) { - BOOL bBreak = ( 0 != (pDoc->GetColFlags( nStartCol, nTab ) & (CR_MANUALBREAK)) ); - ScUnoHelpFunctions::SetBoolInAny( aAny, bBreak ); + ScBreakType nBreak = pDoc->HasColBreak(nStartCol, nTab); + ScUnoHelpFunctions::SetBoolInAny( aAny, (nBreak & BREAK_MANUAL) ); } return aAny; @@ -3141,8 +3231,11 @@ void SAL_CALL ScTableRowsObj::setPropertyValue( sal_Int32 nNewHeight = 0; if ( pDoc->IsImportingXML() && ( aValue >>= nNewHeight ) ) { - // used to set the stored row height for rows with optimal height when loading - pDoc->SetRowHeightRange( nStartRow, nEndRow, nTab, (USHORT)HMMToTwips(nNewHeight) ); + // used to set the stored row height for rows with optimal height when loading. + + // TODO: It's probably cleaner to use a different property name + // for this. + pDoc->SetRowHeightOnly( nStartRow, nEndRow, nTab, (USHORT)HMMToTwips(nNewHeight) ); } else { @@ -3173,9 +3266,9 @@ void SAL_CALL ScTableRowsObj::setPropertyValue( { //! undo etc. if (ScUnoHelpFunctions::GetBoolFromAny( aValue )) - pDoc->GetRowFlagsArrayModifiable( nTab).OrValue( nStartRow, nEndRow, CR_FILTERED); + pDoc->SetRowFiltered(nStartRow, nEndRow, nTab, true); else - pDoc->GetRowFlagsArrayModifiable( nTab).AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~CR_FILTERED) ); + pDoc->SetRowFiltered(nStartRow, nEndRow, nTab, false); } else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE) || aNameString.EqualsAscii( SC_UNONAME_MANPAGE) ) { @@ -3223,12 +3316,13 @@ uno::Any SAL_CALL ScTableRowsObj::getPropertyValue( const rtl::OUString& aProper } else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) ) { - BOOL bVis = !(pDoc->GetRowFlags( nStartRow, nTab ) & CR_HIDDEN); + SCROW nLastRow; + bool bVis = !pDoc->RowHidden(nStartRow, nTab, nLastRow); ScUnoHelpFunctions::SetBoolInAny( aAny, bVis ); } else if ( aNameString.EqualsAscii( SC_UNONAME_CELLFILT ) ) { - BOOL bVis = ((pDoc->GetRowFlags( nStartRow, nTab ) & CR_FILTERED) != 0); + bool bVis = pDoc->RowFiltered(nStartRow, nTab); ScUnoHelpFunctions::SetBoolInAny( aAny, bVis ); } else if ( aNameString.EqualsAscii( SC_UNONAME_OHEIGHT ) ) @@ -3238,13 +3332,13 @@ uno::Any SAL_CALL ScTableRowsObj::getPropertyValue( const rtl::OUString& aProper } else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) ) { - BOOL bBreak = ( 0 != (pDoc->GetRowFlags( nStartRow, nTab ) & (CR_PAGEBREAK|CR_MANUALBREAK)) ); - ScUnoHelpFunctions::SetBoolInAny( aAny, bBreak ); + ScBreakType nBreak = pDoc->HasRowBreak(nStartRow, nTab); + ScUnoHelpFunctions::SetBoolInAny( aAny, nBreak ); } else if ( aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) ) { - BOOL bBreak = ( 0 != (pDoc->GetRowFlags( nStartRow, nTab ) & (CR_MANUALBREAK)) ); - ScUnoHelpFunctions::SetBoolInAny( aAny, bBreak ); + ScBreakType nBreak = pDoc->HasRowBreak(nStartRow, nTab); + ScUnoHelpFunctions::SetBoolInAny( aAny, (nBreak & BREAK_MANUAL) ); } else if ( aNameString.EqualsAscii( SC_UNONAME_CELLBACK ) || aNameString.EqualsAscii( SC_UNONAME_CELLTRAN ) ) { diff --git a/sc/source/ui/unoobj/eventuno.cxx b/sc/source/ui/unoobj/eventuno.cxx new file mode 100755 index 000000000000..d7de00f4cc56 --- /dev/null +++ b/sc/source/ui/unoobj/eventuno.cxx @@ -0,0 +1,201 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tokenuno.cxx,v $ + * $Revision: 1.6.108.8 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +#include "eventuno.hxx" +#include "miscuno.hxx" +#include "unoguard.hxx" +#include "docsh.hxx" +#include "sheetevents.hxx" +#include "unonames.hxx" + +using namespace ::com::sun::star; + +//------------------------------------------------------------------------ + +SC_SIMPLE_SERVICE_INFO( ScSheetEventsObj, "ScSheetEventsObj", "com.sun.star.document.Events" ) + +//------------------------------------------------------------------------ + +ScSheetEventsObj::ScSheetEventsObj(ScDocShell* pDocSh, SCTAB nT) : + mpDocShell( pDocSh ), + mnTab( nT ) +{ + mpDocShell->GetDocument()->AddUnoObject(*this); +} + +ScSheetEventsObj::~ScSheetEventsObj() +{ + if (mpDocShell) + mpDocShell->GetDocument()->RemoveUnoObject(*this); +} + +void ScSheetEventsObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + //! reference update + if ( rHint.ISA( SfxSimpleHint ) && + ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) + { + mpDocShell = NULL; + } +} + +sal_Int32 lcl_GetEventFromName( const rtl::OUString& aName ) +{ + for (sal_Int32 nEvent=0; nEvent<SC_SHEETEVENT_COUNT; ++nEvent) + if ( aName == ScSheetEvents::GetEventName(nEvent) ) + return nEvent; + + return -1; // not found +} + +// XNameReplace + +void SAL_CALL ScSheetEventsObj::replaceByName( const rtl::OUString& aName, const uno::Any& aElement ) + throw(lang::IllegalArgumentException, container::NoSuchElementException, + lang::WrappedTargetException, uno::RuntimeException) +{ + ScUnoGuard aGuard; + if (!mpDocShell) + throw uno::RuntimeException(); + + sal_Int32 nEvent = lcl_GetEventFromName(aName); + if (nEvent < 0) + throw container::NoSuchElementException(); + + ScSheetEvents aNewEvents; + const ScSheetEvents* pOldEvents = mpDocShell->GetDocument()->GetSheetEvents(mnTab); + if (pOldEvents) + aNewEvents = *pOldEvents; + + rtl::OUString aScript; + if ( aElement.hasValue() ) // empty Any -> reset event + { + uno::Sequence<beans::PropertyValue> aPropSeq; + if ( aElement >>= aPropSeq ) + { + sal_Int32 nPropCount = aPropSeq.getLength(); + for (sal_Int32 nPos=0; nPos<nPropCount; ++nPos) + { + const beans::PropertyValue& rProp = aPropSeq[nPos]; + if ( rProp.Name.compareToAscii( SC_UNO_EVENTTYPE ) == 0 ) + { + rtl::OUString aEventType; + if ( rProp.Value >>= aEventType ) + { + // only "Script" is supported + if ( aEventType.compareToAscii( SC_UNO_SCRIPT ) != 0 ) + throw lang::IllegalArgumentException(); + } + } + else if ( rProp.Name.compareToAscii( SC_UNO_SCRIPT ) == 0 ) + rProp.Value >>= aScript; + } + } + } + if (aScript.getLength()) + aNewEvents.SetScript( nEvent, &aScript ); + else + aNewEvents.SetScript( nEvent, NULL ); // reset + + mpDocShell->GetDocument()->SetSheetEvents( mnTab, &aNewEvents ); + mpDocShell->SetDocumentModified(); +} + +// XNameAccess + +uno::Any SAL_CALL ScSheetEventsObj::getByName( const rtl::OUString& aName ) + throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) +{ + ScUnoGuard aGuard; + sal_Int32 nEvent = lcl_GetEventFromName(aName); + if (nEvent < 0) + throw container::NoSuchElementException(); + + const rtl::OUString* pScript = NULL; + if (mpDocShell) + { + const ScSheetEvents* pEvents = mpDocShell->GetDocument()->GetSheetEvents(mnTab); + if (pEvents) + pScript = pEvents->GetScript(nEvent); + } + + uno::Any aRet; + if (pScript) + { + uno::Sequence<beans::PropertyValue> aPropSeq( 2 ); + aPropSeq[0] = beans::PropertyValue( + rtl::OUString::createFromAscii("EventType"), -1, + uno::makeAny( rtl::OUString::createFromAscii("Script") ), beans::PropertyState_DIRECT_VALUE ); + aPropSeq[1] = beans::PropertyValue( + rtl::OUString::createFromAscii("Script"), -1, + uno::makeAny( *pScript ), beans::PropertyState_DIRECT_VALUE ); + aRet <<= aPropSeq; + } + // empty Any if nothing was set + return aRet; +} + +uno::Sequence<rtl::OUString> SAL_CALL ScSheetEventsObj::getElementNames() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + uno::Sequence<rtl::OUString> aNames(SC_SHEETEVENT_COUNT); + for (sal_Int32 nEvent=0; nEvent<SC_SHEETEVENT_COUNT; ++nEvent) + aNames[nEvent] = ScSheetEvents::GetEventName(nEvent); + return aNames; +} + +sal_Bool SAL_CALL ScSheetEventsObj::hasByName( const ::rtl::OUString& aName ) throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + sal_Int32 nEvent = lcl_GetEventFromName(aName); + return (nEvent >= 0); +} + +// XElementAccess + +uno::Type SAL_CALL ScSheetEventsObj::getElementType() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return getCppuType((uno::Sequence<beans::PropertyValue>*)0); +} + +sal_Bool SAL_CALL ScSheetEventsObj::hasElements() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + if (mpDocShell) + return sal_True; + return sal_False; +} + + + diff --git a/sc/source/ui/unoobj/funcuno.cxx b/sc/source/ui/unoobj/funcuno.cxx index 0c197a8b738d..7012b477050c 100644 --- a/sc/source/ui/unoobj/funcuno.cxx +++ b/sc/source/ui/unoobj/funcuno.cxx @@ -34,6 +34,7 @@ #include <sfx2/app.hxx> #include <svl/itemprop.hxx> +#include "scitems.hxx" #include "funcuno.hxx" #include "miscuno.hxx" #include "cellsuno.hxx" @@ -55,6 +56,7 @@ #include "docpool.hxx" #include "attrib.hxx" #include "clipparam.hxx" +#include "dociter.hxx" using namespace com::sun::star; @@ -185,6 +187,32 @@ BOOL lcl_CopyData( ScDocument* pSrcDoc, const ScRange& rSrcRange, pClipDoc->ApplyPatternAreaTab( 0,0, MAXCOL,MAXROW, nSrcTab, aPattern ); } + // If the range contains formula cells with default number format, + // apply a number format for the formula result + ScCellIterator aIter( pClipDoc, rSrcRange ); + ScBaseCell* pCell = aIter.GetFirst(); + while (pCell) + { + if (pCell->GetCellType() == CELLTYPE_FORMULA) + { + ScAddress aCellPos = aIter.GetPos(); + sal_uInt32 nFormat = pClipDoc->GetNumberFormat(aCellPos); + if ( (nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 ) + { + ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell); + USHORT nErrCode = pFCell->GetErrCode(); + if ( nErrCode == 0 && pFCell->IsValue() ) + { + sal_uInt32 nNewFormat = pFCell->GetStandardFormat( *pClipDoc->GetFormatTable(), nFormat ); + if ( nNewFormat != nFormat ) + pClipDoc->ApplyAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), + SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) ); + } + } + } + pCell = aIter.GetNext(); + } + ScMarkData aDestMark; aDestMark.SelectOneTable( nDestTab ); aDestMark.SetMarkArea( aNewRange ); @@ -199,7 +227,8 @@ BOOL lcl_CopyData( ScDocument* pSrcDoc, const ScRange& rSrcRange, ScFunctionAccess::ScFunctionAccess() : pOptions( NULL ), aPropertyMap( ScDocOptionsHelper::GetPropertyMap() ), - bInvalid( FALSE ) + mbArray( true ), // default according to behaviour of older Office versions + mbValid( true ) { StartListening( *SFX_APP() ); // for SFX_HINT_DEINITIALIZING } @@ -216,7 +245,7 @@ void ScFunctionAccess::Notify( SfxBroadcaster&, const SfxHint& rHint ) { // document must not be used anymore aDocCache.Clear(); - bInvalid = TRUE; + mbValid = false; } } @@ -288,14 +317,22 @@ void SAL_CALL ScFunctionAccess::setPropertyValue( { ScUnoGuard aGuard; - if ( !pOptions ) - pOptions = new ScDocOptions(); + if( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsArrayFunction" ) ) ) + { + if( !(aValue >>= mbArray) ) + throw lang::IllegalArgumentException(); + } + else + { + if ( !pOptions ) + pOptions = new ScDocOptions(); - // options aren't initialized from configuration - always get the same default behaviour + // options aren't initialized from configuration - always get the same default behaviour - BOOL bDone = ScDocOptionsHelper::setPropertyValue( *pOptions, aPropertyMap, aPropertyName, aValue ); - if (!bDone) - throw beans::UnknownPropertyException(); + BOOL bDone = ScDocOptionsHelper::setPropertyValue( *pOptions, aPropertyMap, aPropertyName, aValue ); + if (!bDone) + throw beans::UnknownPropertyException(); + } } uno::Any SAL_CALL ScFunctionAccess::getPropertyValue( const rtl::OUString& aPropertyName ) @@ -304,6 +341,9 @@ uno::Any SAL_CALL ScFunctionAccess::getPropertyValue( const rtl::OUString& aProp { ScUnoGuard aGuard; + if( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsArrayFunction" ) ) ) + return uno::Any( mbArray ); + if ( !pOptions ) pOptions = new ScDocOptions(); @@ -497,7 +537,7 @@ uno::Any SAL_CALL ScFunctionAccess::callFunction( const rtl::OUString& aName, { ScUnoGuard aGuard; - if (bInvalid) + if (!mbValid) throw uno::RuntimeException(); // use cached document if not in use, temporary document otherwise @@ -556,12 +596,13 @@ uno::Any SAL_CALL ScFunctionAccess::callFunction( const rtl::OUString& aName, uno::TypeClass eClass = rArg.getValueTypeClass(); uno::Type aType = rArg.getValueType(); if ( eClass == uno::TypeClass_BYTE || - eClass == uno::TypeClass_SHORT || - eClass == uno::TypeClass_UNSIGNED_SHORT || - eClass == uno::TypeClass_LONG || - eClass == uno::TypeClass_UNSIGNED_LONG || - eClass == uno::TypeClass_FLOAT || - eClass == uno::TypeClass_DOUBLE ) + eClass == uno::TypeClass_BOOLEAN || + eClass == uno::TypeClass_SHORT || + eClass == uno::TypeClass_UNSIGNED_SHORT || + eClass == uno::TypeClass_LONG || + eClass == uno::TypeClass_UNSIGNED_LONG || + eClass == uno::TypeClass_FLOAT || + eClass == uno::TypeClass_DOUBLE ) { // #87871# accept integer types because Basic passes a floating point // variable as byte, short or long if it's an integer number. @@ -650,13 +691,13 @@ uno::Any SAL_CALL ScFunctionAccess::callFunction( const rtl::OUString& aName, // GRAM_PODF_A1 doesn't really matter for the token array but fits with // other API compatibility grammars. ScFormulaCell* pFormula = new ScFormulaCell( pDoc, aFormulaPos, - &aTokenArr,formula::FormulaGrammar::GRAM_PODF_A1, MM_FORMULA ); + &aTokenArr, formula::FormulaGrammar::GRAM_PODF_A1, (BYTE)(mbArray ? MM_FORMULA : MM_NONE) ); pDoc->PutCell( aFormulaPos, pFormula ); //! necessary? // call GetMatrix before GetErrCode because GetMatrix always recalculates // if there is no matrix result - const ScMatrix* pMat = pFormula->GetMatrix(); + const ScMatrix* pMat = mbArray ? pFormula->GetMatrix() : 0; USHORT nErrCode = pFormula->GetErrCode(); if ( nErrCode == 0 ) { diff --git a/sc/source/ui/unoobj/makefile.mk b/sc/source/ui/unoobj/makefile.mk index 35fdf164bf92..36c3493ceefc 100644 --- a/sc/source/ui/unoobj/makefile.mk +++ b/sc/source/ui/unoobj/makefile.mk @@ -79,6 +79,7 @@ SLO1FILES = \ $(SLO)$/filtuno.obj \ $(SLO)$/unodoc.obj \ $(SLO)$/addruno.obj \ + $(SLO)$/eventuno.obj \ $(SLO)$/listenercalls.obj \ $(SLO)$/cellvaluebinding.obj \ $(SLO)$/celllistsource.obj \ diff --git a/sc/source/ui/unoobj/scdetect.cxx b/sc/source/ui/unoobj/scdetect.cxx index 80cb88595b11..03d6d14a3ac7 100644..100755 --- a/sc/source/ui/unoobj/scdetect.cxx +++ b/sc/source/ui/unoobj/scdetect.cxx @@ -298,7 +298,7 @@ static BOOL lcl_IsAnyXMLFilter( const SfxFilter* pFilter ) } else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("InteractionHandler")) ) lDescriptor[nProperty].Value >>= xInteraction; - else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("RapairPackage")) ) + else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("RepairPackage")) ) lDescriptor[nProperty].Value >>= bRepairPackage; else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentTitle")) ) nIndexOfDocumentTitle = nProperty; diff --git a/sc/source/ui/unoobj/viewuno.cxx b/sc/source/ui/unoobj/viewuno.cxx index 15fb8183a88f..d10d3ba54f86 100644 --- a/sc/source/ui/unoobj/viewuno.cxx +++ b/sc/source/ui/unoobj/viewuno.cxx @@ -66,7 +66,9 @@ #include "scmod.hxx" #include "appoptio.hxx" #include "gridwin.hxx" +#include "sheetevents.hxx" #include <com/sun/star/view/DocumentZoomType.hpp> +#include <com/sun/star/awt/MouseButton.hpp> #include "AccessibilityHints.hxx" #include <svx/sdrhittesthelper.hxx> @@ -476,9 +478,11 @@ ScTabViewObj::ScTabViewObj( ScTabViewShell* pViewSh ) : aPropSet( lcl_GetViewOptPropertyMap() ), aMouseClickHandlers( 0 ), aActivationListeners( 0 ), + nPreviousTab( 0 ), bDrawSelModeSet(sal_False) { - //! Listening oder so + if (pViewSh) + nPreviousTab = pViewSh->GetViewData()->GetTabNo(); } ScTabViewObj::~ScTabViewObj() @@ -529,15 +533,44 @@ void SAL_CALL ScTabViewObj::release() throw() SfxBaseController::release(); } +void lcl_CallActivate( ScDocShell* pDocSh, SCTAB nTab, sal_Int32 nEvent ) +{ + ScDocument* pDoc = pDocSh->GetDocument(); + // when deleting a sheet, nPreviousTab can be invalid + // (could be handled with reference updates) + if (!pDoc->HasTable(nTab)) + return; + + const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); + if (pEvents) + { + const rtl::OUString* pScript = pEvents->GetScript(nEvent); + if (pScript) + { + uno::Any aRet; + uno::Sequence<uno::Any> aParams; + uno::Sequence<sal_Int16> aOutArgsIndex; + uno::Sequence<uno::Any> aOutArgs; + + /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); + } + } +} + void ScTabViewObj::SheetChanged() { - if (aActivationListeners.Count() > 0 && GetViewShell()) + if ( !GetViewShell() ) + return; + + ScViewData* pViewData = GetViewShell()->GetViewData(); + ScDocShell* pDocSh = pViewData->GetDocShell(); + if (aActivationListeners.Count() > 0) { sheet::ActivationEvent aEvent; uno::Reference< sheet::XSpreadsheetView > xView(this); uno::Reference< uno::XInterface > xSource(xView, uno::UNO_QUERY); aEvent.Source = xSource; - aEvent.ActiveSheet = new ScTableSheetObj(GetViewShell()->GetViewData()->GetDocShell(), GetViewShell()->GetViewData()->GetTabNo()); + aEvent.ActiveSheet = new ScTableSheetObj(pDocSh, pViewData->GetTabNo()); for ( USHORT n=0; n<aActivationListeners.Count(); n++ ) { try @@ -551,6 +584,15 @@ void ScTabViewObj::SheetChanged() } } } + + // handle sheet events + SCTAB nNewTab = pViewData->GetTabNo(); + if ( nNewTab != nPreviousTab ) + { + lcl_CallActivate( pDocSh, nPreviousTab, SC_SHEETEVENT_UNFOCUS ); + lcl_CallActivate( pDocSh, nNewTab, SC_SHEETEVENT_FOCUS ); + } + nPreviousTab = nNewTab; } uno::Sequence<uno::Type> SAL_CALL ScTabViewObj::getTypes() throw(uno::RuntimeException) @@ -1194,6 +1236,22 @@ uno::Reference< uno::XInterface > ScTabViewObj::GetClickedObject(const Point& rP return xTarget; } +bool ScTabViewObj::IsMouseListening() const +{ + if ( aMouseClickHandlers.Count() > 0 ) + return true; + + // also include sheet events, because MousePressed must be called for them + ScTabViewShell* pViewSh = GetViewShell(); + ScViewData* pViewData = pViewSh->GetViewData(); + const ScSheetEvents* pEvents = pViewData->GetDocument()->GetSheetEvents(pViewData->GetTabNo()); + if ( pEvents && ( pEvents->GetScript(SC_SHEETEVENT_RIGHTCLICK) != NULL || + pEvents->GetScript(SC_SHEETEVENT_DOUBLECLICK) != NULL ) ) + return true; + + return false; +} + sal_Bool ScTabViewObj::MousePressed( const awt::MouseEvent& e ) throw (::uno::RuntimeException) { @@ -1229,6 +1287,50 @@ sal_Bool ScTabViewObj::MousePressed( const awt::MouseEvent& e ) } } } + + // handle sheet events + bool bDoubleClick = ( e.Buttons == awt::MouseButton::LEFT && e.ClickCount == 2 ); + bool bRightClick = ( e.Buttons == awt::MouseButton::RIGHT && e.ClickCount == 1 ); + if ( ( bDoubleClick || bRightClick ) && !bReturn ) + { + sal_Int32 nEvent = bDoubleClick ? SC_SHEETEVENT_DOUBLECLICK : SC_SHEETEVENT_RIGHTCLICK; + + ScTabViewShell* pViewSh = GetViewShell(); + ScViewData* pViewData = pViewSh->GetViewData(); + ScDocShell* pDocSh = pViewData->GetDocShell(); + ScDocument* pDoc = pDocSh->GetDocument(); + SCTAB nTab = pViewData->GetTabNo(); + const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); + if (pEvents) + { + const rtl::OUString* pScript = pEvents->GetScript(nEvent); + if (pScript) + { + // the macro parameter is the clicked object, as in the mousePressed call above + uno::Reference< uno::XInterface > xTarget = GetClickedObject(Point(e.X, e.Y)); + if (xTarget.is()) + { + uno::Sequence<uno::Any> aParams(1); + aParams[0] <<= xTarget; + + uno::Any aRet; + uno::Sequence<sal_Int16> aOutArgsIndex; + uno::Sequence<uno::Any> aOutArgs; + + /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); + + // look for a boolean return value of true + sal_Bool bRetValue = sal_False; + if (aRet >>= bRetValue) + { + if (bRetValue) + bReturn = sal_True; + } + } + } + } + } + return bReturn; } @@ -1702,6 +1804,30 @@ void ScTabViewObj::SelectionChanged() aEvent.Source.set(static_cast<cppu::OWeakObject*>(this)); for ( USHORT n=0; n<aSelectionListeners.Count(); n++ ) (*aSelectionListeners[n])->selectionChanged( aEvent ); + + // handle sheet events + ScTabViewShell* pViewSh = GetViewShell(); + ScViewData* pViewData = pViewSh->GetViewData(); + ScDocShell* pDocSh = pViewData->GetDocShell(); + ScDocument* pDoc = pDocSh->GetDocument(); + SCTAB nTab = pViewData->GetTabNo(); + const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); + if (pEvents) + { + const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_SELECT); + if (pScript) + { + // the macro parameter is the selection as returned by getSelection + uno::Sequence<uno::Any> aParams(1); + aParams[0] = getSelection(); + + uno::Any aRet; + uno::Sequence<sal_Int16> aOutArgsIndex; + uno::Sequence<uno::Any> aOutArgs; + + /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); + } + } } diff --git a/sc/source/ui/vba/makefile.mk b/sc/source/ui/vba/makefile.mk index 00a26e2f94de..0a84b8dd12a5 100644 --- a/sc/source/ui/vba/makefile.mk +++ b/sc/source/ui/vba/makefile.mk @@ -78,28 +78,31 @@ SLOFILES= \ $(SLO)$/vbaborders.obj \ $(SLO)$/vbacharacters.obj \ $(SLO)$/vbavalidation.obj \ - $(SLO)$/vbaoleobject.obj \ - $(SLO)$/vbaoleobjects.obj \ - $(SLO)$/vbatextboxshape.obj \ - $(SLO)$/vbapane.obj \ - $(SLO)$/vbatextframe.obj \ - $(SLO)$/vbacharttitle.obj \ - $(SLO)$/vbacharts.obj \ - $(SLO)$/vbaaxistitle.obj \ - $(SLO)$/vbaaxes.obj \ - $(SLO)$/vbaaxis.obj \ - $(SLO)$/vbaformat.obj \ - $(SLO)$/vbacondition.obj \ - $(SLO)$/vbaformatcondition.obj \ - $(SLO)$/vbaformatconditions.obj \ - $(SLO)$/vbastyle.obj \ - $(SLO)$/vbastyles.obj \ - $(SLO)$/vbaassistant.obj \ - $(SLO)$/vbahyperlink.obj \ - $(SLO)$/vbapagesetup.obj \ - $(SLO)$/vbapagebreak.obj \ - $(SLO)$/vbapagebreaks.obj \ - $(SLO)$/service.obj + $(SLO)$/vbasheetobject.obj \ + $(SLO)$/vbasheetobjects.obj \ + $(SLO)$/vbaoleobject.obj \ + $(SLO)$/vbaoleobjects.obj \ + $(SLO)$/vbatextboxshape.obj \ + $(SLO)$/vbapane.obj \ + $(SLO)$/vbatextframe.obj \ + $(SLO)$/vbacharttitle.obj \ + $(SLO)$/vbacharts.obj \ + $(SLO)$/vbaaxistitle.obj \ + $(SLO)$/vbaaxes.obj \ + $(SLO)$/vbaaxis.obj \ + $(SLO)$/vbaformat.obj \ + $(SLO)$/vbacondition.obj \ + $(SLO)$/vbaformatcondition.obj \ + $(SLO)$/vbaformatconditions.obj \ + $(SLO)$/vbastyle.obj \ + $(SLO)$/vbastyles.obj \ + $(SLO)$/vbaassistant.obj \ + $(SLO)$/vbahyperlink.obj \ + $(SLO)$/vbahyperlinks.obj \ + $(SLO)$/vbapagesetup.obj \ + $(SLO)$/vbapagebreak.obj \ + $(SLO)$/vbapagebreaks.obj \ + $(SLO)$/service.obj .ENDIF # --- Targets ------------------------------------------------------ diff --git a/sc/source/ui/vba/vbaapplication.cxx b/sc/source/ui/vba/vbaapplication.cxx index 3d5af01acef1..aea8d8bc11d4 100644 --- a/sc/source/ui/vba/vbaapplication.cxx +++ b/sc/source/ui/vba/vbaapplication.cxx @@ -114,7 +114,10 @@ public: ActiveWorkbook( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext) : ScVbaWorkbook( xParent, xContext ){} }; -ScVbaApplication::ScVbaApplication( const uno::Reference<uno::XComponentContext >& xContext ): ScVbaApplication_BASE( xContext ), m_xCalculation( excel::XlCalculation::xlCalculationAutomatic ) +ScVbaApplication::ScVbaApplication( const uno::Reference<uno::XComponentContext >& xContext ) : + ScVbaApplication_BASE( xContext ), + m_xCalculation( excel::XlCalculation::xlCalculationAutomatic ), + m_xDisplayAlerts( sal_True) { } @@ -127,6 +130,66 @@ SfxObjectShell* ScVbaApplication::GetDocShell( const uno::Reference< frame::XMod return static_cast< SfxObjectShell* >( excel::getDocShell( xModel ) ); } +::rtl::OUString SAL_CALL +ScVbaApplication::getExactName( const ::rtl::OUString& aApproximateName ) throw (uno::RuntimeException) +{ + uno::Reference< beans::XExactName > xWSF( new ScVbaWSFunction( this, mxContext ) ); + return xWSF->getExactName( aApproximateName ); +} + +uno::Reference< beans::XIntrospectionAccess > SAL_CALL +ScVbaApplication::getIntrospection() throw(css::uno::RuntimeException) +{ + uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); + return xWSF->getIntrospection(); +} + +uno::Any SAL_CALL +ScVbaApplication::invoke( const ::rtl::OUString& FunctionName, const uno::Sequence< uno::Any >& Params, uno::Sequence< sal_Int16 >& OutParamIndex, uno::Sequence< uno::Any >& OutParam) throw(lang::IllegalArgumentException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException) +{ + /* When calling the functions directly at the Application object, no runtime + errors are thrown, but the error is inserted into the return value. */ + uno::Any aAny; + try + { + uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); + aAny = xWSF->invoke( FunctionName, Params, OutParamIndex, OutParam ); + } + catch( uno::Exception& ) + { + aAny <<= script::BasicErrorException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), 1000, ::rtl::OUString() ); + } + return aAny; +} + +void SAL_CALL +ScVbaApplication::setValue( const ::rtl::OUString& PropertyName, const uno::Any& Value ) throw(beans::UnknownPropertyException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException) +{ + uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); + xWSF->setValue( PropertyName, Value ); +} + +uno::Any SAL_CALL +ScVbaApplication::getValue( const ::rtl::OUString& PropertyName ) throw(beans::UnknownPropertyException, uno::RuntimeException) +{ + uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); + return xWSF->getValue( PropertyName ); +} + +sal_Bool SAL_CALL +ScVbaApplication::hasMethod( const ::rtl::OUString& Name ) throw(uno::RuntimeException) +{ + uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); + return xWSF->hasMethod( Name ); +} + +sal_Bool SAL_CALL +ScVbaApplication::hasProperty( const ::rtl::OUString& Name ) throw(uno::RuntimeException) +{ + uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); + return xWSF->hasProperty( Name ); +} + uno::Reference< excel::XWorkbook > ScVbaApplication::getActiveWorkbook() throw (uno::RuntimeException) { @@ -190,7 +253,7 @@ ScVbaApplication::getSelection() throw (uno::RuntimeException) } else { - throw uno::RuntimeException( sImpementaionName + rtl::OUString::createFromAscii(" donot be surpported"), uno::Reference< uno::XInterface >() ); + throw uno::RuntimeException( sImpementaionName + rtl::OUString::createFromAscii(" not suported"), uno::Reference< uno::XInterface >() ); } } @@ -244,7 +307,7 @@ ScVbaApplication::Worksheets( const uno::Any& aIndex ) throw (uno::RuntimeExcept uno::Any SAL_CALL ScVbaApplication::WorksheetFunction( ) throw (::com::sun::star::uno::RuntimeException) { - return uno::makeAny( uno::Reference< script::XInvocation >( new ScVbaWSFunction( this, mxContext) ) ); + return uno::makeAny( uno::Reference< script::XInvocation >( new ScVbaWSFunction( this, mxContext ) ) ); } uno::Any SAL_CALL @@ -270,7 +333,10 @@ uno::Reference< excel::XWindow > SAL_CALL ScVbaApplication::getActiveWindow() throw (uno::RuntimeException) { // #FIXME sofar can't determine Parent - return new ScVbaWindow( uno::Reference< XHelperInterface >(), mxContext, getCurrentDocument() ); + uno::Reference< frame::XModel > xModel = getCurrentDocument(); + ScVbaWindow* pWin = new ScVbaWindow( uno::Reference< XHelperInterface >(), mxContext, xModel ); + uno::Reference< excel::XWindow > xWin( pWin ); + return xWin; } uno::Any SAL_CALL @@ -321,23 +387,6 @@ ScVbaApplication::setStatusBar( const uno::Any& _statusbar ) throw (uno::Runtime uno::Reference< uno::XInterface >() ); } -double SAL_CALL -ScVbaApplication::CountA( const uno::Any& arg1 ) throw (uno::RuntimeException) -{ - double result = 0; - uno::Reference< script::XInvocation > xInvoc( WorksheetFunction(), uno::UNO_QUERY_THROW ); - if ( xInvoc.is() ) - { - static rtl::OUString FunctionName( RTL_CONSTASCII_USTRINGPARAM("CountA" ) ); - uno::Sequence< uno::Any > Params(1); - Params[0] = arg1; - uno::Sequence< sal_Int16 > OutParamIndex; - uno::Sequence< uno::Any > OutParam; - xInvoc->invoke( FunctionName, Params, OutParamIndex, OutParam ) >>= result; - } - return result; -} - ::sal_Int32 SAL_CALL ScVbaApplication::getCalculation() throw (uno::RuntimeException) { @@ -482,8 +531,11 @@ ScVbaApplication::GoTo( const uno::Any& Reference, const uno::Any& Scroll ) thro ScGridWindow* gridWindow = (ScGridWindow*)pShell->GetWindow(); try { - uno::Reference< excel::XRange > xVbaSheetRange = ScVbaRange::getRangeObjectForName( mxContext, sRangeName, excel::getDocShell( xModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); -; + // FIXME: pass proper Worksheet parent + uno::Reference< excel::XRange > xVbaSheetRange = ScVbaRange::getRangeObjectForName( + uno::Reference< XHelperInterface >(), mxContext, sRangeName, + excel::getDocShell( xModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); + if( bScroll ) { xVbaSheetRange->Select(); @@ -621,15 +673,21 @@ ScVbaApplication::getName() throw (uno::RuntimeException) } // #TODO #FIXME get/setDisplayAlerts are just stub impl +// here just the status of the switch is set +// the function that throws an error message needs to +// evaluate this switch in order to know whether it has to disable the +// error message thrown by OpenOffice + void SAL_CALL -ScVbaApplication::setDisplayAlerts(sal_Bool /*displayAlerts*/) throw (uno::RuntimeException) +ScVbaApplication::setDisplayAlerts(sal_Bool displayAlerts) throw (uno::RuntimeException) { + m_xDisplayAlerts = displayAlerts; } sal_Bool SAL_CALL ScVbaApplication::getDisplayAlerts() throw (uno::RuntimeException) { - return sal_True; + return m_xDisplayAlerts; } void SAL_CALL ScVbaApplication::Calculate() throw( script::BasicErrorException , uno::RuntimeException ) @@ -889,7 +947,8 @@ lcl_intersectionImpl( ScRangeList& rl1, ScRangeList& rl2 ) RangesList lcl_intersections( RangesList& vRanges ) { RangesList intersections; - for( RangesList::iterator it = vRanges.begin(); it != vRanges.end(); ++it ) + RangesList::iterator it = vRanges.begin(); + while( it != vRanges.end() ) { Ranges intermediateList; for( RangesList::iterator it_inner = vRanges.begin(); it_inner != vRanges.end(); ++it_inner ) @@ -902,6 +961,7 @@ RangesList lcl_intersections( RangesList& vRanges ) } } it = vRanges.erase( it ); // remove it so we don't include it in the next pass. + // 'it' is removed uncontidionally from vRanges, so the while loop will terminate ScRangeList argIntersect; lcl_strip_containedRanges( intermediateList ); diff --git a/sc/source/ui/vba/vbaapplication.hxx b/sc/source/ui/vba/vbaapplication.hxx index 02822e9f18ad..96638651bcd1 100644 --- a/sc/source/ui/vba/vbaapplication.hxx +++ b/sc/source/ui/vba/vbaapplication.hxx @@ -43,15 +43,29 @@ class ScVbaApplication : public ScVbaApplication_BASE { private: sal_Int32 m_xCalculation; + sal_Bool m_xDisplayAlerts; rtl::OUString getOfficePath( const rtl::OUString& sPath ) throw ( css::uno::RuntimeException ); + protected: - virtual css::uno::Reference< css::frame::XModel > getCurrentDocument() throw (css::uno::RuntimeException); + virtual css::uno::Reference< css::frame::XModel > getCurrentDocument() throw (css::uno::RuntimeException); + public: ScVbaApplication( const css::uno::Reference< css::uno::XComponentContext >& m_xContext ); virtual ~ScVbaApplication(); virtual SfxObjectShell* GetDocShell( const css::uno::Reference< css::frame::XModel >& xModel ) throw (css::uno::RuntimeException); + // XExactName + virtual ::rtl::OUString SAL_CALL getExactName( const ::rtl::OUString& aApproximateName ) throw (css::uno::RuntimeException); + + // XInvocation + virtual css::uno::Reference< css::beans::XIntrospectionAccess > SAL_CALL getIntrospection(void) throw(css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL invoke(const rtl::OUString& FunctionName, const css::uno::Sequence< css::uno::Any >& Params, css::uno::Sequence< sal_Int16 >& OutParamIndex, css::uno::Sequence< css::uno::Any >& OutParam) throw(css::lang::IllegalArgumentException, css::script::CannotConvertException, css::reflection::InvocationTargetException, css::uno::RuntimeException); + virtual void SAL_CALL setValue(const rtl::OUString& PropertyName, const css::uno::Any& Value) throw(css::beans::UnknownPropertyException, css::script::CannotConvertException, css::reflection::InvocationTargetException, css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL getValue(const rtl::OUString& PropertyName) throw(css::beans::UnknownPropertyException, css::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasMethod(const rtl::OUString& Name) throw(css::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasProperty(const rtl::OUString& Name) throw(css::uno::RuntimeException); + // XApplication virtual ::rtl::OUString SAL_CALL PathSeparator( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); virtual void SAL_CALL setDefaultFilePath( const ::rtl::OUString& DefaultFilePath ) throw (css::script::BasicErrorException, css::uno::RuntimeException); @@ -67,8 +81,8 @@ public: virtual css::uno::Any SAL_CALL getSelection() throw (css::uno::RuntimeException); virtual css::uno::Reference< ov::excel::XWorkbook > SAL_CALL getActiveWorkbook() throw (css::uno::RuntimeException); virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getActiveCell() throw ( css::uno::RuntimeException); - virtual css::uno::Reference< ov::excel::XWindow > SAL_CALL getActiveWindow() throw (css::uno::RuntimeException); - virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getActiveSheet() throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XWindow > SAL_CALL getActiveWindow() throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getActiveSheet() throw (css::uno::RuntimeException); virtual ::sal_Bool SAL_CALL getDisplayFormulaBar() throw ( css::uno::RuntimeException ); virtual void SAL_CALL setDisplayFormulaBar( ::sal_Bool _displayformulabar ) throw ( css::uno::RuntimeException ); @@ -86,8 +100,6 @@ public: virtual ::sal_Int32 SAL_CALL getCursor() throw (css::uno::RuntimeException); virtual void SAL_CALL setCursor( ::sal_Int32 _cursor ) throw (css::uno::RuntimeException); - virtual double SAL_CALL CountA( const css::uno::Any& arg1 ) throw (css::uno::RuntimeException) ; - virtual css::uno::Any SAL_CALL Windows( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); virtual void SAL_CALL wait( double time ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Range( const css::uno::Any& Cell1, const css::uno::Any& Cell2 ) throw (css::uno::RuntimeException); diff --git a/sc/source/ui/vba/vbacomment.cxx b/sc/source/ui/vba/vbacomment.cxx index a8026f151c79..9c50a25b8b7c 100644 --- a/sc/source/ui/vba/vbacomment.cxx +++ b/sc/source/ui/vba/vbacomment.cxx @@ -27,14 +27,17 @@ #include "vbacomment.hxx" #include <ooo/vba/excel/XlCreator.hpp> +#include <com/sun/star/drawing/XDrawPageSupplier.hpp> #include <com/sun/star/sheet/XSpreadsheet.hpp> #include <com/sun/star/sheet/XSheetAnnotationAnchor.hpp> #include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp> +#include <com/sun/star/sheet/XSheetAnnotationShapeSupplier.hpp> #include <com/sun/star/sheet/XSheetCellRange.hpp> #include <com/sun/star/table/CellAddress.hpp> #include <com/sun/star/table/XCell.hpp> #include <com/sun/star/text/XText.hpp> +#include <vbahelper/vbashape.hxx> #include "vbaglobals.hxx" #include "vbacomments.hxx" @@ -42,8 +45,14 @@ using namespace ::ooo::vba; using namespace ::com::sun::star; -ScVbaComment::ScVbaComment( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ) throw( lang::IllegalArgumentException ) -: ScVbaComment_BASE( xParent, xContext ), mxRange( xRange ) +ScVbaComment::ScVbaComment( + const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< frame::XModel >& xModel, + const uno::Reference< table::XCellRange >& xRange ) throw( lang::IllegalArgumentException ) : + ScVbaComment_BASE( xParent, xContext ), + mxModel( xModel, uno::UNO_SET_THROW ), + mxRange( xRange ) { if ( !xRange.is() ) throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "range is not set " ) ), uno::Reference< uno::XInterface >() , 1 ); @@ -100,7 +109,7 @@ ScVbaComment::getCommentByIndex( sal_Int32 Index ) throw (uno::RuntimeException) { uno::Reference< container::XIndexAccess > xIndexAccess( getAnnotations(), uno::UNO_QUERY_THROW ); // parent is sheet ( parent of the range which is the parent of the comment ) - uno::Reference< XCollection > xColl( new ScVbaComments( getParent()->getParent(), mxContext, xIndexAccess ) ); + uno::Reference< XCollection > xColl( new ScVbaComments( getParent()->getParent(), mxContext, mxModel, xIndexAccess ) ); return uno::Reference< excel::XComment > ( xColl->Item( uno::makeAny( Index ), uno::Any() ), uno::UNO_QUERY_THROW ); } @@ -119,6 +128,17 @@ ScVbaComment::setAuthor( const rtl::OUString& /*_author*/ ) throw (uno::RuntimeE // #TODO #FIXME implementation needed } +uno::Reference< msforms::XShape > SAL_CALL +ScVbaComment::getShape() throw (uno::RuntimeException) +{ + uno::Reference< sheet::XSheetAnnotationShapeSupplier > xAnnoShapeSupp( getAnnotation(), uno::UNO_QUERY_THROW ); + uno::Reference< drawing::XShape > xAnnoShape( xAnnoShapeSupp->getAnnotationShape(), uno::UNO_SET_THROW ); + uno::Reference< sheet::XSheetCellRange > xCellRange( mxRange, uno::UNO_QUERY_THROW ); + uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupp( xCellRange->getSpreadsheet(), uno::UNO_QUERY_THROW ); + uno::Reference< drawing::XShapes > xShapes( xDrawPageSupp->getDrawPage(), uno::UNO_QUERY_THROW ); + return new ScVbaShape( this, mxContext, xAnnoShape, xShapes, mxModel, office::MsoShapeType::msoComment ); +} + sal_Bool SAL_CALL ScVbaComment::getVisible() throw (uno::RuntimeException) { @@ -186,12 +206,15 @@ ScVbaComment::Text( const uno::Any& aText, const uno::Any& aStart, const uno::An uno::Reference< text::XTextRange > xRange( xTextCursor, uno::UNO_QUERY_THROW ); xAnnoText->insertString( xRange, sText, bOverwrite ); + return xAnnoText->getString(); } - else - throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScVbaComment::Text - bad Start value " ) ), uno::Reference< uno::XInterface >() ); + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScVbaComment::Text - bad Start value " ) ), uno::Reference< uno::XInterface >() ); } else if ( aText.hasValue() ) + { xAnnoText->setString( sText ); + return sText; + } return sAnnoText; } diff --git a/sc/source/ui/vba/vbacomment.hxx b/sc/source/ui/vba/vbacomment.hxx index 91d8a8a8e437..4a7d2fab91ef 100644 --- a/sc/source/ui/vba/vbacomment.hxx +++ b/sc/source/ui/vba/vbacomment.hxx @@ -31,6 +31,7 @@ #include <ooo/vba/excel/XComment.hpp> #include <ooo/vba/excel/XApplication.hpp> +#include <ooo/vba/msforms/XShape.hpp> #include <com/sun/star/sheet/XSheetAnnotations.hpp> #include <com/sun/star/sheet/XSheetAnnotation.hpp> #include <com/sun/star/table/XCellRange.hpp> @@ -42,6 +43,7 @@ typedef InheritedHelperInterfaceImpl1< ov::excel::XComment > ScVbaComment_BASE; class ScVbaComment : public ScVbaComment_BASE { + css::uno::Reference< css::frame::XModel > mxModel; css::uno::Reference< css::table::XCellRange > mxRange; private: @@ -50,13 +52,18 @@ private: sal_Int32 SAL_CALL getAnnotationIndex() throw (css::uno::RuntimeException); css::uno::Reference< ov::excel::XComment > SAL_CALL getCommentByIndex( sal_Int32 Index ) throw (css::uno::RuntimeException); public: - ScVbaComment( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::table::XCellRange >& xRange ) throw ( css::lang::IllegalArgumentException ); + ScVbaComment( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::frame::XModel >& xModel, + const css::uno::Reference< css::table::XCellRange >& xRange ) throw ( css::lang::IllegalArgumentException ); virtual ~ScVbaComment() {} // Attributes virtual rtl::OUString SAL_CALL getAuthor() throw (css::uno::RuntimeException); virtual void SAL_CALL setAuthor( const rtl::OUString& _author ) throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::msforms::XShape > SAL_CALL getShape() throw (css::uno::RuntimeException); virtual sal_Bool SAL_CALL getVisible() throw (css::uno::RuntimeException); virtual void SAL_CALL setVisible( sal_Bool _visible ) throw (css::uno::RuntimeException); diff --git a/sc/source/ui/vba/vbacomments.cxx b/sc/source/ui/vba/vbacomments.cxx index 5090fa6f5ee6..a68dd4245741 100644 --- a/sc/source/ui/vba/vbacomments.cxx +++ b/sc/source/ui/vba/vbacomments.cxx @@ -34,30 +34,43 @@ using namespace ::ooo::vba; using namespace ::com::sun::star; -uno::Any AnnotationToComment( const uno::Any& aSource, uno::Reference< uno::XComponentContext > & xContext ) +uno::Any AnnotationToComment( const uno::Any& aSource, uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel ) { uno::Reference< sheet::XSheetAnnotation > xAnno( aSource, uno::UNO_QUERY_THROW ); uno::Reference< container::XChild > xChild( xAnno, uno::UNO_QUERY_THROW ); uno::Reference< table::XCellRange > xCellRange( xChild->getParent(), uno::UNO_QUERY_THROW ); // #FIXME needs to find the correct Parent - return uno::makeAny( uno::Reference< excel::XComment > ( new ScVbaComment( uno::Reference< XHelperInterface >(), xContext, xCellRange ) ) ); + return uno::makeAny( uno::Reference< excel::XComment > ( + new ScVbaComment( uno::Reference< XHelperInterface >(), xContext, xModel, xCellRange ) ) ); } class CommentEnumeration : public EnumerationHelperImpl { + css::uno::Reference< css::frame::XModel > mxModel; public: - CommentEnumeration( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ) {} + CommentEnumeration( + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< container::XEnumeration >& xEnumeration, + const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) : + EnumerationHelperImpl( xContext, xEnumeration ), + mxModel( xModel, uno::UNO_SET_THROW ) + {} virtual uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { - return AnnotationToComment( m_xEnumeration->nextElement(), m_xContext ); + return AnnotationToComment( m_xEnumeration->nextElement(), m_xContext, mxModel ); } }; -ScVbaComments::ScVbaComments( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess ) -: ScVbaComments_BASE( xParent, xContext, xIndexAccess ) +ScVbaComments::ScVbaComments( + const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext > & xContext, + const uno::Reference< frame::XModel >& xModel, + const uno::Reference< container::XIndexAccess >& xIndexAccess ) : + ScVbaComments_BASE( xParent, xContext, xIndexAccess ), + mxModel( xModel, uno::UNO_SET_THROW ) { } @@ -68,13 +81,13 @@ ScVbaComments::createEnumeration() throw (uno::RuntimeException) { uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); - return new CommentEnumeration( mxContext, xEnumAccess->createEnumeration() ); + return new CommentEnumeration( mxContext, xEnumAccess->createEnumeration(), mxModel ); } uno::Any ScVbaComments::createCollectionObject( const css::uno::Any& aSource ) { - return AnnotationToComment( aSource, mxContext ); + return AnnotationToComment( aSource, mxContext, mxModel ); } uno::Type diff --git a/sc/source/ui/vba/vbacomments.hxx b/sc/source/ui/vba/vbacomments.hxx index 0ab11e8d5e97..2f98e5b71897 100644 --- a/sc/source/ui/vba/vbacomments.hxx +++ b/sc/source/ui/vba/vbacomments.hxx @@ -40,7 +40,11 @@ typedef CollTestImplHelper< ov::excel::XComments > ScVbaComments_BASE; class ScVbaComments : public ScVbaComments_BASE { public: - ScVbaComments( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess ); + ScVbaComments( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext > & xContext, + const css::uno::Reference< css::frame::XModel >& xModel, + const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess ); virtual ~ScVbaComments() {} @@ -53,6 +57,8 @@ public: virtual rtl::OUString& getServiceImplName(); virtual css::uno::Sequence<rtl::OUString> getServiceNames(); +private: + css::uno::Reference< css::frame::XModel > mxModel; }; #endif /* SC_VBA_COMMENTS_HXX */ diff --git a/sc/source/ui/vba/vbafont.cxx b/sc/source/ui/vba/vbafont.cxx index a8aac44770a9..5894d3ea8c71 100644 --- a/sc/source/ui/vba/vbafont.cxx +++ b/sc/source/ui/vba/vbafont.cxx @@ -36,6 +36,7 @@ #include <ooo/vba/excel/XlColorIndex.hpp> #include <ooo/vba/excel/XlUnderlineStyle.hpp> #include <svl/itemset.hxx> +#include "excelvbahelper.hxx" #include "vbafont.hxx" #include "scitems.hxx" #include "cellsuno.hxx" @@ -43,15 +44,22 @@ using namespace ::ooo::vba; using namespace ::com::sun::star; -ScVbaFont::ScVbaFont( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const ScVbaPalette& dPalette, uno::Reference< beans::XPropertySet > xPropertySet, ScCellRangeObj* pRangeObj ) throw ( uno::RuntimeException ) : ScVbaFont_BASE( xParent, xContext, dPalette.getPalette(), xPropertySet ), mPalette( dPalette ), mpRangeObj( pRangeObj ) +ScVbaFont::ScVbaFont( + const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const ScVbaPalette& dPalette, + const uno::Reference< beans::XPropertySet >& xPropertySet, + ScCellRangeObj* pRangeObj, bool bFormControl ) throw ( uno::RuntimeException ) : + ScVbaFont_BASE( xParent, xContext, dPalette.getPalette(), xPropertySet, bFormControl ), + mPalette( dPalette ), + mpRangeObj( pRangeObj ) { } SfxItemSet* ScVbaFont::GetDataSet() { - SfxItemSet* pDataSet = excel::ScVbaCellRangeAccess::GetDataSet( mpRangeObj ); - return pDataSet; + return mpRangeObj ? excel::ScVbaCellRangeAccess::GetDataSet( mpRangeObj ) : 0; } ScVbaFont::~ScVbaFont() diff --git a/sc/source/ui/vba/vbafont.hxx b/sc/source/ui/vba/vbafont.hxx index 4cbcd483b2d8..3ef52c6d240f 100644 --- a/sc/source/ui/vba/vbafont.hxx +++ b/sc/source/ui/vba/vbafont.hxx @@ -46,7 +46,12 @@ class ScVbaFont : public ScVbaFont_BASE ScCellRangeObj* mpRangeObj; SfxItemSet* GetDataSet(); public: - ScVbaFont( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const ScVbaPalette& dPalette, css::uno::Reference< css::beans::XPropertySet > xPropertySet, ScCellRangeObj* pRangeObj = NULL ) throw ( css::uno::RuntimeException ); + ScVbaFont( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const ScVbaPalette& dPalette, + const css::uno::Reference< css::beans::XPropertySet >& xPropertySet, + ScCellRangeObj* pRangeObj = 0, bool bFormControl = false ) throw ( css::uno::RuntimeException ); virtual ~ScVbaFont();// {} // Attributes diff --git a/sc/source/ui/vba/vbaformat.cxx b/sc/source/ui/vba/vbaformat.cxx index 23c2bf96a810..d08451af63f4 100644 --- a/sc/source/ui/vba/vbaformat.cxx +++ b/sc/source/ui/vba/vbaformat.cxx @@ -40,6 +40,7 @@ #include <rtl/math.hxx> +#include "excelvbahelper.hxx" #include "vbaborders.hxx" #include "vbapalette.hxx" #include "vbafont.hxx" diff --git a/sc/source/ui/vba/vbahelper.cxx b/sc/source/ui/vba/vbahelper.cxx index 4bc57e150c8f..cc76b1e60125 100644 --- a/sc/source/ui/vba/vbahelper.cxx +++ b/sc/source/ui/vba/vbahelper.cxx @@ -160,73 +160,6 @@ public: } }; -void -dispatchRequests (uno::Reference< frame::XModel>& xModel,rtl::OUString & aUrl, uno::Sequence< beans::PropertyValue >& sProps ) -{ - - util::URL url ; - url.Complete = aUrl; - rtl::OUString emptyString = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "" )); - uno::Reference<frame::XController> xController = xModel->getCurrentController(); - uno::Reference<frame::XFrame> xFrame = xController->getFrame(); - uno::Reference<frame::XDispatchProvider> xDispatchProvider (xFrame,uno::UNO_QUERY_THROW); - try - { - uno::Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW ); - uno::Reference<uno::XComponentContext > xContext( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), uno::UNO_QUERY_THROW ); - if ( !xContext.is() ) - { - return ; - } - - uno::Reference<lang::XMultiComponentFactory > xServiceManager( - xContext->getServiceManager() ); - if ( !xServiceManager.is() ) - { - return ; - } - uno::Reference<util::XURLTransformer> xParser( xServiceManager->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ) ) - ,xContext), uno::UNO_QUERY_THROW ); - if (!xParser.is()) - return; - xParser->parseStrict (url); - } - catch ( uno::Exception & /*e*/ ) - { - return ; - } - - uno::Reference<frame::XDispatch> xDispatcher = xDispatchProvider->queryDispatch(url,emptyString,0); - - uno::Sequence<beans::PropertyValue> dispatchProps(1); - - sal_Int32 nProps = sProps.getLength(); - beans::PropertyValue* pDest = dispatchProps.getArray(); - if ( nProps ) - { - dispatchProps.realloc( nProps + 1 ); - // need to reaccquire pDest after realloc - pDest = dispatchProps.getArray(); - beans::PropertyValue* pSrc = sProps.getArray(); - for ( sal_Int32 index=0; index<nProps; ++index, ++pSrc, ++pDest ) - *pDest = *pSrc; - } - - (*pDest).Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Silent" )); - (*pDest).Value <<= (sal_Bool)sal_True; - - if (xDispatcher.is()) - xDispatcher->dispatch( url, dispatchProps ); -} - -void -dispatchRequests (uno::Reference< frame::XModel>& xModel,rtl::OUString & aUrl) -{ - uno::Sequence<beans::PropertyValue> dispatchProps; - dispatchRequests( xModel, aUrl, dispatchProps ); -} - - void dispatchExecute(css::uno::Reference< css::frame::XModel>& xModel, USHORT nSlot, SfxCallMode nCall) { ScTabViewShell* pViewShell = getBestViewShell( xModel ); @@ -821,7 +754,5 @@ ScVbaCellRangeAccess::GetDataSet( ScCellRangeObj* pRangeObj ) } -} // openoffice -} //org -======= ->>>>>>> other +} // vba +} // ooo diff --git a/sc/source/ui/vba/vbahyperlink.cxx b/sc/source/ui/vba/vbahyperlink.cxx index f3203b130bf2..e37df1e118b4 100644 --- a/sc/source/ui/vba/vbahyperlink.cxx +++ b/sc/source/ui/vba/vbahyperlink.cxx @@ -24,100 +24,213 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ -#include <vbahelper/helperdecl.hxx> + #include "vbahyperlink.hxx" +#include <vbahelper/helperdecl.hxx> #include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/text/XText.hpp> #include <com/sun/star/text/XTextFieldsSupplier.hpp> #include <com/sun/star/container/XEnumerationAccess.hpp> +#include <ooo/vba/office/MsoHyperlinkType.hpp> +#include <ooo/vba/msforms/XShape.hpp> #include "vbarange.hxx" using namespace ::ooo::vba; using namespace ::com::sun::star; +using ::rtl::OUString; +using ::rtl::OUStringBuffer; -ScVbaHyperlink::ScVbaHyperlink( uno::Sequence< uno::Any> const & args, - uno::Reference< uno::XComponentContext> const & xContext ) throw ( lang::IllegalArgumentException ) : HyperlinkImpl_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext ), mxCell( getXSomethingFromArgs< table::XCell >( args, 1, false ) ) +// ============================================================================ + +ScVbaHyperlink::ScVbaHyperlink( const uno::Sequence< uno::Any >& rArgs, + const uno::Reference< uno::XComponentContext >& rxContext ) throw (lang::IllegalArgumentException) : + HyperlinkImpl_BASE( getXSomethingFromArgs< XHelperInterface >( rArgs, 0 ), rxContext ), + mxCell( getXSomethingFromArgs< table::XCell >( rArgs, 1, false ) ), + mnType( office::MsoHyperlinkType::msoHyperlinkRange ) { - mxCell = getXSomethingFromArgs< table::XCell >( args, 1, false ); uno::Reference< text::XTextFieldsSupplier > xTextFields( mxCell, uno::UNO_QUERY_THROW ); uno::Reference< container::XIndexAccess > xIndex( xTextFields->getTextFields(), uno::UNO_QUERY_THROW ); mxTextField.set( xIndex->getByIndex(0), uno::UNO_QUERY_THROW ); } -ScVbaHyperlink::~ScVbaHyperlink() +ScVbaHyperlink::ScVbaHyperlink( const uno::Reference< XHelperInterface >& rxAnchor, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Any& rAddress, const uno::Any& rSubAddress, + const uno::Any& rScreenTip, const uno::Any& rTextToDisplay ) throw (uno::RuntimeException) : + HyperlinkImpl_BASE( rxAnchor, rxContext ) // parent of Hyperlink is the anchor object { -} + // extract parameters, Address must not be empty + UrlComponents aUrlComp; + OUString aTextToDisplay; + if( !(rAddress >>= aUrlComp.first) || (aUrlComp.first.getLength() == 0) ) + throw uno::RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot get address" ) ), uno::Reference< uno::XInterface >() ); + rSubAddress >>= aUrlComp.second; + rScreenTip >>= maScreenTip; + rTextToDisplay >>= aTextToDisplay; -::rtl::OUString -ScVbaHyperlink::getAddress() throw (css::uno::RuntimeException) -{ - rtl::OUString aAddress; - uno::Any aValue = mxTextField->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) ); - aValue >>= aAddress; - return aAddress; + // get anchor range or anchor shape + uno::Reference< excel::XRange > xAnchorRange( rxAnchor, uno::UNO_QUERY ); + if( xAnchorRange.is() ) + { + mnType = office::MsoHyperlinkType::msoHyperlinkRange; + // only single ranges are allowed + uno::Reference< table::XCellRange > xUnoRange( ScVbaRange::getCellRange( xAnchorRange ), uno::UNO_QUERY_THROW ); + // insert the hyperlink into the top-left cell only + mxCell.set( xUnoRange->getCellByPosition( 0, 0 ), uno::UNO_SET_THROW ); + uno::Reference< text::XText > xText( mxCell, uno::UNO_QUERY_THROW ); + // use cell text or URL if no TextToDisplay has been passed + if( aTextToDisplay.getLength() == 0 ) + { + aTextToDisplay = xText->getString(); + if( aTextToDisplay.getLength() == 0 ) + { + OUStringBuffer aBuffer( aUrlComp.first ); + if( aUrlComp.second.getLength() > 0 ) + aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " - " ) ).append( aUrlComp.second ); + aTextToDisplay = aBuffer.makeStringAndClear(); + } + } + // create and initialize a new URL text field + uno::Reference< lang::XMultiServiceFactory > xFactory( ScVbaRange::getUnoModel( xAnchorRange ), uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextContent > xUrlField( xFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextField.URL" ) ) ), uno::UNO_QUERY_THROW ); + mxTextField.set( xUrlField, uno::UNO_QUERY_THROW ); + setUrlComponents( aUrlComp ); + setTextToDisplay( aTextToDisplay ); + // insert the text field into the document + xText->setString( OUString() ); + uno::Reference< text::XTextRange > xRange( xText->createTextCursor(), uno::UNO_QUERY_THROW ); + xText->insertTextContent( xRange, xUrlField, sal_False ); + } + else + { + uno::Reference< msforms::XShape > xAnchorShape( rxAnchor, uno::UNO_QUERY_THROW ); + mnType = office::MsoHyperlinkType::msoHyperlinkShape; + // FIXME: insert hyperlink into shape + throw uno::RuntimeException(); + } } -void -ScVbaHyperlink::setAddress( const ::rtl::OUString & rAddress ) throw (css::uno::RuntimeException) +ScVbaHyperlink::~ScVbaHyperlink() { - uno::Any aValue; - aValue <<= rAddress; - mxTextField->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ), aValue ); } -::rtl::OUString -ScVbaHyperlink::getName() throw (css::uno::RuntimeException) +OUString ScVbaHyperlink::getName() throw (uno::RuntimeException) { // it seems this attribute is same as TextToDisplay return getTextToDisplay(); } -void -ScVbaHyperlink::setName( const ::rtl::OUString & rName ) throw (css::uno::RuntimeException) +void ScVbaHyperlink::setName( const OUString& rName ) throw (uno::RuntimeException) { setTextToDisplay( rName ); } -::rtl::OUString -ScVbaHyperlink::getTextToDisplay() throw (css::uno::RuntimeException) +OUString ScVbaHyperlink::getAddress() throw (uno::RuntimeException) { - rtl::OUString aTextToDisplay; - uno::Any aValue = mxTextField->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Representation" ) ) ); - aValue >>= aTextToDisplay; - return aTextToDisplay; + return getUrlComponents().first; +} + +void ScVbaHyperlink::setAddress( const OUString& rAddress ) throw (uno::RuntimeException) +{ + UrlComponents aUrlComp = getUrlComponents(); + aUrlComp.first = rAddress; + setUrlComponents( aUrlComp ); +} + +OUString ScVbaHyperlink::getSubAddress() throw (uno::RuntimeException) +{ + return getUrlComponents().second; +} + +void ScVbaHyperlink::setSubAddress( const OUString& rSubAddress ) throw (uno::RuntimeException) +{ + UrlComponents aUrlComp = getUrlComponents(); + aUrlComp.second = rSubAddress; + setUrlComponents( aUrlComp ); } -void -ScVbaHyperlink::setTextToDisplay( const ::rtl::OUString & rTextToDisplay ) throw (css::uno::RuntimeException) +OUString SAL_CALL ScVbaHyperlink::getScreenTip() throw (uno::RuntimeException) { - uno::Any aValue; - aValue <<= rTextToDisplay; - mxTextField->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Representation" ) ), aValue ); + return maScreenTip; } -css::uno::Reference< ov::excel::XRange > SAL_CALL ScVbaHyperlink::Range() throw (css::uno::RuntimeException) +void SAL_CALL ScVbaHyperlink::setScreenTip( const OUString& rScreenTip ) throw (uno::RuntimeException) { - uno::Reference< table::XCellRange > xRange( mxCell,uno::UNO_QUERY_THROW ); - // FIXME: need to pass current worksheet as the parent of XRange. - return uno::Reference< excel::XRange >( new ScVbaRange( uno::Reference< XHelperInterface > (), mxContext, xRange ) ); + maScreenTip = rScreenTip; } -rtl::OUString& -ScVbaHyperlink::getServiceImplName() +OUString ScVbaHyperlink::getTextToDisplay() throw (uno::RuntimeException) { - static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaHyperlink") ); - return sImplName; + ensureTextField(); + OUString aTextToDisplay; + mxTextField->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Representation" ) ) ) >>= aTextToDisplay; + return aTextToDisplay; +} + +void ScVbaHyperlink::setTextToDisplay( const OUString& rTextToDisplay ) throw (uno::RuntimeException) +{ + ensureTextField(); + mxTextField->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Representation" ) ), uno::Any( rTextToDisplay ) ); } -uno::Sequence< rtl::OUString > -ScVbaHyperlink::getServiceNames() +sal_Int32 SAL_CALL ScVbaHyperlink::getType() throw (uno::RuntimeException) { - static uno::Sequence< rtl::OUString > aServiceNames; - if ( aServiceNames.getLength() == 0 ) + return mnType; +} + +uno::Reference< excel::XRange > SAL_CALL ScVbaHyperlink::getRange() throw (uno::RuntimeException) +{ + if( mnType == office::MsoHyperlinkType::msoHyperlinkRange ) { - aServiceNames.realloc( 1 ); - aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Hyperlink" ) ); + // if constructed from Hyperlinks object, range has been passed as parent + uno::Reference< excel::XRange > xAnchorRange( getParent(), uno::UNO_QUERY ); + if( !xAnchorRange.is() ) + { + // if constructed via service c'tor, create new range based on cell + uno::Reference< table::XCellRange > xRange( mxCell, uno::UNO_QUERY_THROW ); + // FIXME: need to pass current worksheet as the parent of XRange. + xAnchorRange.set( new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, xRange ) ); + } + return xAnchorRange; } - return aServiceNames; + // error if called at a shape Hyperlink object + throw uno::RuntimeException(); +} + +uno::Reference< msforms::XShape > SAL_CALL ScVbaHyperlink::getShape() throw (uno::RuntimeException) +{ + // error if called at a range Hyperlink object + return uno::Reference< msforms::XShape >( getParent(), uno::UNO_QUERY_THROW ); +} + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaHyperlink, "ooo.vba.excel.Hyperlink" ) + +// private -------------------------------------------------------------------- + +void ScVbaHyperlink::ensureTextField() throw (uno::RuntimeException) +{ + if( !mxTextField.is() ) + throw uno::RuntimeException(); +} + +ScVbaHyperlink::UrlComponents ScVbaHyperlink::getUrlComponents() throw (uno::RuntimeException) +{ + ensureTextField(); + OUString aUrl; + mxTextField->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) ) >>= aUrl; + sal_Int32 nHashPos = aUrl.indexOf( '#' ); + if( nHashPos < 0 ) + return UrlComponents( aUrl, OUString() ); + return UrlComponents( aUrl.copy( 0, nHashPos ), aUrl.copy( nHashPos + 1 ) ); +} + +void ScVbaHyperlink::setUrlComponents( const UrlComponents& rUrlComp ) throw (uno::RuntimeException) +{ + ensureTextField(); + OUStringBuffer aUrl( rUrlComp.first ); + if( rUrlComp.second.getLength() > 0 ) + aUrl.append( sal_Unicode( '#' ) ).append( rUrlComp.second ); + mxTextField->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ), uno::Any( aUrl.makeStringAndClear() ) ); } namespace hyperlink @@ -129,3 +242,5 @@ extern sdecl::ServiceDecl const serviceDecl( "ScVbaHyperlink", "ooo.vba.excel.Hyperlink" ); } + +// ============================================================================ diff --git a/sc/source/ui/vba/vbahyperlink.hxx b/sc/source/ui/vba/vbahyperlink.hxx index 570ecdcc2f45..e1520b59c15a 100644 --- a/sc/source/ui/vba/vbahyperlink.hxx +++ b/sc/source/ui/vba/vbahyperlink.hxx @@ -24,6 +24,7 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ + #ifndef SC_VBA_HYPERLINK_HXX #define SC_VBA_HYPERLINK_HXX @@ -38,27 +39,50 @@ typedef InheritedHelperInterfaceImpl1< ov::excel::XHyperlink > HyperlinkImpl_BAS class ScVbaHyperlink : public HyperlinkImpl_BASE { - css::uno::Reference< css::table::XCell > mxCell; - css::uno::Reference< css::beans::XPropertySet > mxTextField; - public: - ScVbaHyperlink( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext > const& xContext ) throw ( css::lang::IllegalArgumentException ); + ScVbaHyperlink( + const css::uno::Sequence< css::uno::Any >& rArgs, + const css::uno::Reference< css::uno::XComponentContext >& rxContext ) throw (css::lang::IllegalArgumentException); + + ScVbaHyperlink( + const css::uno::Reference< ov::XHelperInterface >& rxAnchor, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Any& rAddress, const css::uno::Any& rSubAddress, + const css::uno::Any& rScreenTip, const css::uno::Any& rTextToDisplay ) throw (css::uno::RuntimeException); + virtual ~ScVbaHyperlink(); // Attributes - virtual ::rtl::OUString SAL_CALL getAddress() throw (css::uno::RuntimeException); - virtual void SAL_CALL setAddress( const ::rtl::OUString &rAddress ) throw (css::uno::RuntimeException); virtual ::rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException); - virtual void SAL_CALL setName( const ::rtl::OUString &rName ) throw (css::uno::RuntimeException); + virtual void SAL_CALL setName( const ::rtl::OUString& rName ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getAddress() throw (css::uno::RuntimeException); + virtual void SAL_CALL setAddress( const ::rtl::OUString& rAddress ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getSubAddress() throw (css::uno::RuntimeException); + virtual void SAL_CALL setSubAddress( const ::rtl::OUString& rSubAddress ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getScreenTip() throw (css::uno::RuntimeException); + virtual void SAL_CALL setScreenTip( const ::rtl::OUString& rScreenTip ) throw (css::uno::RuntimeException); virtual ::rtl::OUString SAL_CALL getTextToDisplay() throw (css::uno::RuntimeException); - virtual void SAL_CALL setTextToDisplay( const ::rtl::OUString &rTextToDisplay ) throw (css::uno::RuntimeException); - - // Methods - virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Range() throw (css::uno::RuntimeException); + virtual void SAL_CALL setTextToDisplay( const ::rtl::OUString& rTextToDisplay ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getType() throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getRange() throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::msforms::XShape > SAL_CALL getShape() throw (css::uno::RuntimeException); // XHelperInterface - virtual rtl::OUString& getServiceImplName(); - virtual css::uno::Sequence<rtl::OUString> getServiceNames(); + VBAHELPER_DECL_XHELPERINTERFACE + +private: + typedef ::std::pair< ::rtl::OUString, ::rtl::OUString > UrlComponents; + + void ensureTextField() throw (css::uno::RuntimeException); + UrlComponents getUrlComponents() throw (css::uno::RuntimeException); + void setUrlComponents( const UrlComponents& rUrlComp ) throw (css::uno::RuntimeException); + +private: + css::uno::Reference< css::table::XCell > mxCell; + css::uno::Reference< css::beans::XPropertySet > mxTextField; + ::rtl::OUString maScreenTip; + long mnType; }; + #endif /* SC_VBA_HYPERLINK_HXX */ diff --git a/sc/source/ui/vba/vbahyperlinks.cxx b/sc/source/ui/vba/vbahyperlinks.cxx new file mode 100755 index 000000000000..89a8109e6aa2 --- /dev/null +++ b/sc/source/ui/vba/vbahyperlinks.cxx @@ -0,0 +1,293 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "vbahyperlinks.hxx" +#include <algorithm> +#include <vector> +#include <ooo/vba/office/MsoHyperlinkType.hpp> +#include "rangelst.hxx" +#include "vbahyperlink.hxx" +#include "vbarange.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; +using ::rtl::OUString; + +// ============================================================================ + +namespace { + +/** Returns true, if every range of rxInner is contained in any range of rScOuter. */ +bool lclContains( const ScRangeList& rScOuter, const uno::Reference< excel::XRange >& rxInner ) throw (uno::RuntimeException) +{ + const ScRangeList& rScInner = ScVbaRange::getScRangeList( rxInner ); + if( (rScInner.Count() == 0) || (rScOuter.Count() == 0) ) + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Empty range objects" ) ), uno::Reference< uno::XInterface >() ); + + for( ULONG nIndex = 0, nCount = rScInner.Count(); nIndex < nCount; ++nIndex ) + if( !rScOuter.In( *rScInner.GetObject( nIndex ) ) ) + return false; + return true; +} + +// ---------------------------------------------------------------------------- + +/** Functor to decide whether the anchors of two Hyperlink objects are equal. */ +struct EqualAnchorFunctor +{ + uno::Reference< excel::XRange > mxAnchorRange; + uno::Reference< msforms::XShape > mxAnchorShape; + sal_Int32 mnType; + EqualAnchorFunctor( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException); + bool operator()( const uno::Reference< excel::XHyperlink >& rxHlink ) const throw (uno::RuntimeException); +}; + +EqualAnchorFunctor::EqualAnchorFunctor( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException) : + mnType( rxHlink->getType() ) +{ + switch( mnType ) + { + case office::MsoHyperlinkType::msoHyperlinkRange: + mxAnchorRange.set( rxHlink->getRange(), uno::UNO_QUERY_THROW ); + break; + case office::MsoHyperlinkType::msoHyperlinkShape: + case office::MsoHyperlinkType::msoHyperlinkInlineShape: + mxAnchorShape.set( rxHlink->getShape(), uno::UNO_QUERY_THROW ); + break; + default: + throw uno::RuntimeException(); + } +} + +bool EqualAnchorFunctor::operator()( const uno::Reference< excel::XHyperlink >& rxHlink ) const throw (uno::RuntimeException) +{ + sal_Int32 nType = rxHlink->getType(); + if( nType != mnType ) + return false; + + switch( nType ) + { + case office::MsoHyperlinkType::msoHyperlinkRange: + { + uno::Reference< excel::XRange > xAnchorRange( rxHlink->getRange(), uno::UNO_QUERY_THROW ); + const ScRangeList& rScRanges1 = ScVbaRange::getScRangeList( xAnchorRange ); + const ScRangeList& rScRanges2 = ScVbaRange::getScRangeList( mxAnchorRange ); + return (rScRanges1.Count() == 1) && (rScRanges2.Count() == 1) && (*rScRanges1.GetObject( 0 ) == *rScRanges2.GetObject( 0 )); + } + case office::MsoHyperlinkType::msoHyperlinkShape: + case office::MsoHyperlinkType::msoHyperlinkInlineShape: + { + uno::Reference< msforms::XShape > xAnchorShape( rxHlink->getShape(), uno::UNO_QUERY_THROW ); + return xAnchorShape.get() == mxAnchorShape.get(); + } + default: + throw uno::RuntimeException(); + } +} + +} // namespace + +// ============================================================================ + +namespace detail { + +class ScVbaHlinkContainer : public ::cppu::WeakImplHelper1< container::XIndexAccess > +{ +public: + explicit ScVbaHlinkContainer() throw (uno::RuntimeException); + explicit ScVbaHlinkContainer( const ScVbaHlinkContainerRef& rxSheetContainer, const ScRangeList& rScRanges ) throw (uno::RuntimeException); + virtual ~ScVbaHlinkContainer(); + + /** Inserts the passed hyperlink into the collection. Will remove a + Hyperlink object with the same anchor as the passed Hyperlink object. */ + void insertHyperlink( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException); + + // XIndexAccess + virtual sal_Int32 SAL_CALL getCount() throw (uno::RuntimeException); + virtual uno::Any SAL_CALL getByIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException); + + // XElementAccess + virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException); + virtual sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException); + +private: + typedef ::std::vector< uno::Reference< excel::XHyperlink > > HyperlinkVector; + HyperlinkVector maHlinks; +}; + +// ---------------------------------------------------------------------------- + +ScVbaHlinkContainer::ScVbaHlinkContainer() throw (uno::RuntimeException) +{ + // TODO FIXME: fill with existing hyperlinks +} + +ScVbaHlinkContainer::ScVbaHlinkContainer( const ScVbaHlinkContainerRef& rxSheetContainer, + const ScRangeList& rScRanges ) throw (uno::RuntimeException) +{ + for( sal_Int32 nIndex = 0, nCount = rxSheetContainer->getCount(); nIndex < nCount; ++nIndex ) + { + uno::Reference< excel::XHyperlink > xHlink( rxSheetContainer->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + uno::Reference< excel::XRange > xHlinkRange( xHlink->getRange(), uno::UNO_QUERY_THROW ); + if( lclContains( rScRanges, xHlinkRange ) ) + maHlinks.push_back( xHlink ); + } +} + +ScVbaHlinkContainer::~ScVbaHlinkContainer() +{ +} + +void ScVbaHlinkContainer::insertHyperlink( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException) +{ + HyperlinkVector::iterator aIt = ::std::find_if( maHlinks.begin(), maHlinks.end(), EqualAnchorFunctor( rxHlink ) ); + if( aIt == maHlinks.end() ) + maHlinks.push_back( rxHlink ); + else + *aIt = rxHlink; +} + +sal_Int32 SAL_CALL ScVbaHlinkContainer::getCount() throw (uno::RuntimeException) +{ + return static_cast< sal_Int32 >( maHlinks.size() ); +} + +uno::Any SAL_CALL ScVbaHlinkContainer::getByIndex( sal_Int32 nIndex ) + throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException) +{ + if( (0 <= nIndex) && (nIndex < getCount()) ) + return uno::Any( maHlinks[ static_cast< size_t >( nIndex ) ] ); + throw lang::IndexOutOfBoundsException(); +} + +uno::Type SAL_CALL ScVbaHlinkContainer::getElementType() throw (uno::RuntimeException) +{ + return excel::XHyperlink::static_type( 0 ); +} + +sal_Bool SAL_CALL ScVbaHlinkContainer::hasElements() throw (uno::RuntimeException) +{ + return !maHlinks.empty(); +} + +// ============================================================================ + +ScVbaHlinkContainerMember::ScVbaHlinkContainerMember( ScVbaHlinkContainer* pContainer ) : + mxContainer( pContainer ) +{ +} + +ScVbaHlinkContainerMember::~ScVbaHlinkContainerMember() +{ +} + +} // namespace detail + +// ============================================================================ + +ScVbaHyperlinks::ScVbaHyperlinks( const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext ) throw (uno::RuntimeException) : + detail::ScVbaHlinkContainerMember( new detail::ScVbaHlinkContainer ), + ScVbaHyperlinks_BASE( rxParent, rxContext, uno::Reference< container::XIndexAccess >( mxContainer.get() ) ) +{ +} + +ScVbaHyperlinks::ScVbaHyperlinks( const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const ScVbaHyperlinksRef& rxSheetHlinks, const ScRangeList& rScRanges ) throw (uno::RuntimeException) : + detail::ScVbaHlinkContainerMember( new detail::ScVbaHlinkContainer( rxSheetHlinks->mxContainer, rScRanges ) ), + ScVbaHyperlinks_BASE( rxParent, rxContext, uno::Reference< container::XIndexAccess >( mxContainer.get() ) ), + mxSheetHlinks( rxSheetHlinks ) +{ +} + +ScVbaHyperlinks::~ScVbaHyperlinks() +{ +} + +// XHyperlinks ---------------------------------------------------------------- + +uno::Reference< excel::XHyperlink > SAL_CALL ScVbaHyperlinks::Add( + const uno::Any& rAnchor, const uno::Any& rAddress, const uno::Any& rSubAddress, + const uno::Any& rScreenTip, const uno::Any& rTextToDisplay ) throw (uno::RuntimeException) +{ + /* If this Hyperlinks object has been craeted from a Range object, the + call to Add() is passed to the Hyperlinks object of the parent + worksheet. This container will not be modified (it will not contain the + inserted hyperlink). + For details, see documentation in hyperlinks.hxx. + */ + if( mxSheetHlinks.is() ) + return mxSheetHlinks->Add( rAnchor, rAddress, rSubAddress, rScreenTip, rTextToDisplay ); + + // get anchor object (can be a Range or a Shape object) + uno::Reference< XHelperInterface > xAnchor( rAnchor, uno::UNO_QUERY_THROW ); + + /* Create the Hyperlink object, this tries to insert the hyperlink into + the spreadsheet document. Parent of the Hyperlink is the anchor object. */ + uno::Reference< excel::XHyperlink > xHlink( new ScVbaHyperlink( + xAnchor, mxContext, rAddress, rSubAddress, rScreenTip, rTextToDisplay ) ); + + /* If creation of the hyperlink did not throw, insert it into the + collection. */ + mxContainer->insertHyperlink( xHlink ); + return xHlink; +} + +void SAL_CALL ScVbaHyperlinks::Delete() throw (uno::RuntimeException) +{ + // FIXME not implemented + throw uno::RuntimeException(); +} + +// XEnumerationAccess --------------------------------------------------------- + +uno::Reference< container::XEnumeration > SAL_CALL ScVbaHyperlinks::createEnumeration() throw (uno::RuntimeException) +{ + return new SimpleIndexAccessToEnumeration( m_xIndexAccess ); +} + +// XElementAccess ------------------------------------------------------------- + +uno::Type SAL_CALL ScVbaHyperlinks::getElementType() throw (uno::RuntimeException) +{ + return excel::XHyperlink::static_type( 0 ); +} + +// ScVbaCollectionBase -------------------------------------------------------- + +uno::Any ScVbaHyperlinks::createCollectionObject( const uno::Any& rSource ) +{ + // container stores XHyperlink objects, just return the passed object + return rSource; +} + +// XHelperInterface ----------------------------------------------------------- + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaHyperlinks, "ooo.vba.excel.Hyperlinks" ) + +// ============================================================================ diff --git a/sc/source/ui/vba/vbahyperlinks.hxx b/sc/source/ui/vba/vbahyperlinks.hxx new file mode 100755 index 000000000000..ca7d990ad6a8 --- /dev/null +++ b/sc/source/ui/vba/vbahyperlinks.hxx @@ -0,0 +1,150 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_VBA_HYPERLINKS_HXX +#define SC_VBA_HYPERLINKS_HXX + +#include <ooo/vba/excel/XHyperlinks.hpp> +#include <rtl/ref.hxx> +#include <vbahelper/vbacollectionimpl.hxx> + +class ScRangeList; + +// ============================================================================ + +namespace detail { + +class ScVbaHlinkContainer; +typedef ::rtl::Reference< ScVbaHlinkContainer > ScVbaHlinkContainerRef; + +/** Base class for ScVbaHyperlinks to get an initialized ScVbaHlinkContainer + class member before the ScVbaHyperlinks_BASE base class will be constructed. + */ +struct ScVbaHlinkContainerMember +{ + ScVbaHlinkContainerRef mxContainer; + + explicit ScVbaHlinkContainerMember( ScVbaHlinkContainer* pContainer ); + ~ScVbaHlinkContainerMember(); +}; + +} // namespace detail + +// ============================================================================ + +class ScVbaHyperlinks; +typedef ::rtl::Reference< ScVbaHyperlinks > ScVbaHyperlinksRef; + +typedef CollTestImplHelper< ov::excel::XHyperlinks > ScVbaHyperlinks_BASE; + +/** Represents a collection of hyperlinks of a worksheet or of a range. + + When a Hyperlinks collection object has been constructed from a VBA + Worksheet object, it will always represent the current set of all + hyperlinks existing in the sheet. Insertion and deletion of hyperlinks will + be reflected by the instance. + + When a Hyperlinks collection object has been constructed from a VBA Range + object, it will represent the set of hyperlinks that have existed at its + construction time, and that are located completely inside the range(s) + represented by the Range object. Insertion and deletion of hyperlinks will + *not* be reflected by that instance. The instance will always offer all + hyperlinks it has been constructed with, even if they no longer exist. + Furthermore, the instance will not offer hyperlinks inserted later, even if + the instance itself has been used to insert the new hyperlinks. + + VBA code example: + + With ThisWorkbook.Worksheets(1) + + Set hlinks = .Hyperlinks ' global Hyperlinks object + Set myrange = .Range("A1:C3") + Set rangelinks1 = myrange.Hyperlinks ' hyperlinks of range A1:C3 + + MsgBox hlinks.Count ' 0 + MsgBox rangelinks1.Count ' 0 + + hlinks.Add .Range("A1"), "http://example.com" + ' a new hyperlink has been added in cell A1 + + MsgBox hlinks.Count ' 1 + MsgBox rangelinks1.Count ' still 0! + Set rangelinks2 = myrange.Hyperlinks ' hyperlinks of range A1:C3 + MsgBox rangelinks2.Count ' 1 (constructed after Add) + + rangelinks1.Add .Range("A2"), "http://example.com" + ' a new hyperlink has been constructed via the rangelinks1 object + ' but this addition has been done by the worksheet Hyperlinks object + + MsgBox hlinks.Count ' 2 + MsgBox rangelinks1.Count ' still 0!!! + MsgBox rangelinks2.Count ' still 1!!! + MsgBox myrange.Hyperlinks.Count ' 2 (constructed after Add) + + End With + */ +class ScVbaHyperlinks : private detail::ScVbaHlinkContainerMember, public ScVbaHyperlinks_BASE +{ +public: + explicit ScVbaHyperlinks( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext ) throw (css::uno::RuntimeException); + + explicit ScVbaHyperlinks( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const ScVbaHyperlinksRef& rxSheetHlinks, const ScRangeList& rScRanges ) throw (css::uno::RuntimeException); + + virtual ~ScVbaHyperlinks(); + + // XHyperlinks + virtual css::uno::Reference< ov::excel::XHyperlink > SAL_CALL Add( + const css::uno::Any& rAnchor, const css::uno::Any& rAddress, const css::uno::Any& rSubAddress, + const css::uno::Any& rScreenTip, const css::uno::Any& rTextToDisplay ) + throw (css::uno::RuntimeException); + + virtual void SAL_CALL Delete() throw (css::uno::RuntimeException); + + // XEnumerationAccess + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException); + + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException); + + // ScVbaCollectionBase + virtual css::uno::Any createCollectionObject( const css::uno::Any& rSource ); + + // XHelperInterface + VBAHELPER_DECL_XHELPERINTERFACE + +private: + ScVbaHyperlinksRef mxSheetHlinks; +}; + +// ============================================================================ + +#endif diff --git a/sc/source/ui/vba/vbainterior.cxx b/sc/source/ui/vba/vbainterior.cxx index 3af6243e0fa7..face47767bdc 100644 --- a/sc/source/ui/vba/vbainterior.cxx +++ b/sc/source/ui/vba/vbainterior.cxx @@ -40,10 +40,13 @@ #include <comphelper/processfactory.hxx> #include <cppuhelper/queryinterface.hxx> +#include <map> + #include <svx/xtable.hxx> #include "vbainterior.hxx" #include "vbapalette.hxx" +#include "document.hxx" #define STATIC_TABLE_SIZE( array ) (sizeof(array)/sizeof(*(array))) #define COLORMAST 0xFFFFFF diff --git a/sc/source/ui/vba/vbainterior.hxx b/sc/source/ui/vba/vbainterior.hxx index f0d4db1334fd..027d06040af9 100644 --- a/sc/source/ui/vba/vbainterior.hxx +++ b/sc/source/ui/vba/vbainterior.hxx @@ -36,6 +36,8 @@ #include <com/sun/star/script/XInvocation.hpp> #include <vbahelper/vbahelperinterface.hxx> +#include <tools/color.hxx> + class ScDocument; typedef InheritedHelperInterfaceImpl1< ov::excel::XInterior > ScVbaInterior_BASE; diff --git a/sc/source/ui/vba/vbaname.cxx b/sc/source/ui/vba/vbaname.cxx index bc0b016177c7..a6e8a402425f 100644 --- a/sc/source/ui/vba/vbaname.cxx +++ b/sc/source/ui/vba/vbaname.cxx @@ -232,7 +232,10 @@ ScVbaName::setRefersToR1C1Local( const ::rtl::OUString & rRefersTo ) throw (css: css::uno::Reference< ov::excel::XRange > ScVbaName::getRefersToRange() throw (css::uno::RuntimeException) { - uno::Reference< ov::excel::XRange > xRange = ScVbaRange::getRangeObjectForName( mxContext, mxNamedRange->getName(), excel::getDocShell( mxModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); + // FIXME: pass proper Worksheet parent + uno::Reference< ov::excel::XRange > xRange = ScVbaRange::getRangeObjectForName( + uno::Reference< XHelperInterface >(), mxContext, + mxNamedRange->getName(), excel::getDocShell( mxModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); return xRange; } diff --git a/sc/source/ui/vba/vbapalette.cxx b/sc/source/ui/vba/vbapalette.cxx index 0ce55547d4a1..c6ae5c488a20 100644 --- a/sc/source/ui/vba/vbapalette.cxx +++ b/sc/source/ui/vba/vbapalette.cxx @@ -24,10 +24,12 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ + #include "vbapalette.hxx" #include <cppuhelper/implbase1.hxx> #include <com/sun/star/beans/XPropertySet.hpp> - +#include <com/sun/star/container/XIndexAccess.hpp> +#include "excelvbahelper.hxx" using namespace ::com::sun::star; using namespace ::ooo::vba; @@ -82,6 +84,11 @@ public: }; +ScVbaPalette::ScVbaPalette( const uno::Reference< frame::XModel >& rxModel ) : + m_pShell( excel::getDocShell( rxModel ) ) +{ +} + uno::Reference< container::XIndexAccess > ScVbaPalette::getDefaultPalette() { diff --git a/sc/source/ui/vba/vbapalette.hxx b/sc/source/ui/vba/vbapalette.hxx index 9c7ea2ebc3f1..b51483772674 100644 --- a/sc/source/ui/vba/vbapalette.hxx +++ b/sc/source/ui/vba/vbapalette.hxx @@ -24,19 +24,26 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ + #ifndef SC_VBAPALETTE_HXX #define SC_VBAPALETTE_HXX -#include "excelvbahelper.hxx" -#include <document.hxx> -#include <com/sun/star/container/XIndexAccess.hpp> +#include <vbahelper/vbahelper.hxx> + +namespace com { namespace sun { namespace star { + namespace container { class XIndexAccess; } + namespace frame { class XModel; } +} } } + +class SfxObjectShell; class ScVbaPalette { private: SfxObjectShell* m_pShell; public: - ScVbaPalette( SfxObjectShell* pShell = NULL ) : m_pShell( pShell ){} + ScVbaPalette( SfxObjectShell* pShell = 0 ) : m_pShell( pShell ) {} + ScVbaPalette( const css::uno::Reference< css::frame::XModel >& rxModel ); // if no palette available e.g. because the document doesn't have a // palette defined then a default palette will be returned. css::uno::Reference< css::container::XIndexAccess > getPalette() const; diff --git a/sc/source/ui/vba/vbapane.cxx b/sc/source/ui/vba/vbapane.cxx index 263529dde145..29d7a286b402 100644 --- a/sc/source/ui/vba/vbapane.cxx +++ b/sc/source/ui/vba/vbapane.cxx @@ -24,18 +24,26 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ -#include<com/sun/star/table/CellRangeAddress.hpp> -#include<vbapane.hxx> + +#include "vbapane.hxx" +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/table/CellRangeAddress.hpp> +#include "vbarange.hxx" using namespace com::sun::star; using namespace ooo::vba; -/* -ScVbaPane::ScVbaPane( uno::Reference< uno::XComponentContext > xContext, uno::Refrence< sheet::XViewPane > xViewPane ) - : m_xContext( xContext ), m_xViewPane( xViewPane ) +ScVbaPane::ScVbaPane( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< frame::XModel >& xModel, + const uno::Reference< sheet::XViewPane > xViewPane ) throw (uno::RuntimeException) : + ScVbaPane_BASE( xParent, xContext ), + m_xModel( xModel, uno::UNO_SET_THROW ), + m_xViewPane( xViewPane, uno::UNO_SET_THROW ) { } -*/ sal_Int32 SAL_CALL ScVbaPane::getScrollColumn() throw (uno::RuntimeException) @@ -71,6 +79,19 @@ ScVbaPane::setScrollRow( sal_Int32 _scrollrow ) throw (uno::RuntimeException) m_xViewPane->setFirstVisibleRow( _scrollrow - 1 ); } +uno::Reference< excel::XRange > SAL_CALL +ScVbaPane::getVisibleRange() throw (uno::RuntimeException) +{ + // TODO: Excel includes partly visible rows/columns, Calc does not + table::CellRangeAddress aRangeAddr = m_xViewPane->getVisibleRange(); + uno::Reference< sheet::XSpreadsheetDocument > xDoc( m_xModel, uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xSheetsIA( xDoc->getSheets(), uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSpreadsheet > xSheet( xSheetsIA->getByIndex( aRangeAddr.Sheet ), uno::UNO_QUERY_THROW ); + uno::Reference< table::XCellRange > xRange( xSheet->getCellRangeByPosition( aRangeAddr.StartColumn, aRangeAddr.StartRow, aRangeAddr.EndColumn, aRangeAddr.EndRow ), uno::UNO_SET_THROW ); + // TODO: getParent() returns the window, Range needs the worksheet + return new ScVbaRange( getParent(), mxContext, xRange ); +} + //Method void SAL_CALL ScVbaPane::SmallScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft ) throw (uno::RuntimeException) @@ -83,54 +104,34 @@ ScVbaPane::SmallScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any if( Down.hasValue() ) { sal_Int32 down = 0; - try - { - Down >>= down; + if( Down >>= down ) downRows += down; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: Down\n" ); - } } if( Up.hasValue() ) { sal_Int32 up = 0; - try - { - Up >>= up; + if( Up >>= up ) downRows -= up; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: Up\n" ); - } } if( ToRight.hasValue() ) { sal_Int32 right = 0; - try - { - ToRight >>= right; + if( ToRight >>= right ) rightCols += right; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: ToRight\n" ); - } } if( ToLeft.hasValue() ) { sal_Int32 left = 0; - try - { - ToLeft >>= left; + if( ToLeft >>= left ) rightCols -= left; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: ToLeft\n" ); - } } if( messageBuffer.getLength() > 0 ) throw(uno::RuntimeException( messageBuffer, uno::Reference< uno::XInterface >() ) ); @@ -158,56 +159,35 @@ ScVbaPane::LargeScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any if( Down.hasValue() ) { sal_Int32 down = 0; - try - { - Down >>= down; + if( Down >>= down ) downPages += down; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: Down\n" ); - } } if( Up.hasValue() ) { sal_Int32 up = 0; - try - { - Up >>= up; + if( Up >>= up ) downPages -= up; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: Up\n" ); - } } if( ToRight.hasValue() ) { sal_Int32 right = 0; - try - { - ToRight >>= right; + if( ToRight >>= right ) acrossPages += right; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: ToRight\n" ); - } } if( ToLeft.hasValue() ) { sal_Int32 left = 0; - try - { - ToLeft >>= left; + if( ToLeft >>= left ) acrossPages -= left; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: ToLeft\n" ); - } } - if( messageBuffer.getLength() > 0 ) throw(uno::RuntimeException( messageBuffer, uno::Reference< uno::XInterface >() ) ); @@ -220,3 +200,7 @@ ScVbaPane::LargeScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any m_xViewPane->setFirstVisibleRow( newStartRow ); m_xViewPane->setFirstVisibleColumn( newStartCol ); } + +// XHelperInterface + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaPane, "ooo.vba.excel.Pane" ) diff --git a/sc/source/ui/vba/vbapane.hxx b/sc/source/ui/vba/vbapane.hxx index 0fa1d49709de..ff87a9966d80 100644 --- a/sc/source/ui/vba/vbapane.hxx +++ b/sc/source/ui/vba/vbapane.hxx @@ -27,34 +27,41 @@ #ifndef SC_VBA_PANE_HXX #define SC_VBA_PANE_HXX -#include<cppuhelper/implbase1.hxx> -#include<com/sun/star/sheet/XViewPane.hpp> -#include<ooo/vba/excel/XPane.hpp> +#include <com/sun/star/sheet/XViewPane.hpp> +#include <ooo/vba/excel/XPane.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include "excelvbahelper.hxx" -#include"excelvbahelper.hxx" +typedef InheritedHelperInterfaceImpl1< ov::excel::XPane > ScVbaPane_BASE; -typedef cppu::WeakImplHelper1< ov::excel::XPane > PaneImpl_Base; - -class ScVbaPane : public PaneImpl_Base +class ScVbaPane : public ScVbaPane_BASE { -protected: - css::uno::Reference< css::uno::XComponentContext > m_xContext; - css::uno::Reference< css::sheet::XViewPane > m_xViewPane; public: - ScVbaPane( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::sheet::XViewPane > xViewPane ) : m_xContext( xContext ), m_xViewPane( xViewPane ) {} + ScVbaPane( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::frame::XModel >& xModel, + const css::uno::Reference< css::sheet::XViewPane > xViewPane ) throw (css::uno::RuntimeException); css::uno::Reference< css::sheet::XViewPane > getViewPane() { return m_xViewPane; } - //Attribute + // XPane attributes virtual sal_Int32 SAL_CALL getScrollColumn() throw (css::uno::RuntimeException); virtual void SAL_CALL setScrollColumn( sal_Int32 _scrollcolumn ) throw (css::uno::RuntimeException); virtual sal_Int32 SAL_CALL getScrollRow() throw (css::uno::RuntimeException); virtual void SAL_CALL setScrollRow( sal_Int32 _scrollrow ) throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getVisibleRange() throw (css::uno::RuntimeException); - //Method + // XPane methods virtual void SAL_CALL SmallScroll( const css::uno::Any& Down, const css::uno::Any& Up, const css::uno::Any& ToRight, const css::uno::Any& ToLeft ) throw (css::uno::RuntimeException); virtual void SAL_CALL LargeScroll( const css::uno::Any& Down, const css::uno::Any& Up, const css::uno::Any& ToRight, const css::uno::Any& ToLeft ) throw (css::uno::RuntimeException); + // XHelperInterface + VBAHELPER_DECL_XHELPERINTERFACE + +protected: + css::uno::Reference< css::frame::XModel > m_xModel; + css::uno::Reference< css::sheet::XViewPane > m_xViewPane; }; -#endif//SC_VBA_PANE_HXX +#endif //SC_VBA_PANE_HXX diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx index 1a153b440b15..ccf5a3bc5b54 100644 --- a/sc/source/ui/vba/vbarange.cxx +++ b/sc/source/ui/vba/vbarange.cxx @@ -81,6 +81,7 @@ #include <com/sun/star/sheet/XSheetFilterable.hpp> #include <com/sun/star/sheet/FilterConnection.hpp> #include <com/sun/star/util/CellProtection.hpp> +#include <com/sun/star/util/TriState.hpp> #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> #include <com/sun/star/awt/XDevice.hpp> @@ -141,6 +142,7 @@ #include "vbaborders.hxx" #include "vbaworksheet.hxx" #include "vbavalidation.hxx" +#include "vbahyperlinks.hxx" #include "tabvwsh.hxx" #include "rangelst.hxx" @@ -367,7 +369,7 @@ ScVbaRangeAreas::createCollectionObject( const uno::Any& aSource ) ScDocShell* getDocShellFromIf( const uno::Reference< uno::XInterface >& xIf ) throw ( uno::RuntimeException ) { - ScCellRangesBase* pUno= dynamic_cast< ScCellRangesBase* >( xIf.get() ); + ScCellRangesBase* pUno = ScCellRangesBase::getImplementation( xIf ); if ( !pUno ) throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying uno range object" ) ), uno::Reference< uno::XInterface >() ); return pUno->GetDocShell(); @@ -381,6 +383,14 @@ getDocShellFromRange( const uno::Reference< table::XCellRange >& xRange ) throw return getDocShellFromIf(xIf ); } +ScDocShell* +getDocShellFromRanges( const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges ) throw ( uno::RuntimeException ) +{ + // need the ScCellRangesBase to get docshell + uno::Reference< uno::XInterface > xIf( xRanges, uno::UNO_QUERY_THROW ); + return getDocShellFromIf(xIf ); +} + uno::Reference< frame::XModel > getModelFromXIf( const uno::Reference< uno::XInterface >& xIf ) throw ( uno::RuntimeException ) { ScDocShell* pDocShell = getDocShellFromIf(xIf ); @@ -405,7 +415,7 @@ getDocumentFromRange( const uno::Reference< table::XCellRange >& xRange ) ScDocument* -ScVbaRange::getScDocument() +ScVbaRange::getScDocument() throw (uno::RuntimeException) { if ( mxRanges.is() ) { @@ -417,7 +427,7 @@ ScVbaRange::getScDocument() } ScDocShell* -ScVbaRange::getScDocShell() +ScVbaRange::getScDocShell() throw (uno::RuntimeException) { if ( mxRanges.is() ) { @@ -428,6 +438,41 @@ ScVbaRange::getScDocShell() return getDocShellFromRange( mxRange ); } +/*static*/ ScVbaRange* ScVbaRange::getImplementation( const uno::Reference< excel::XRange >& rxRange ) +{ + // FIXME: always save to use dynamic_cast? Or better to (implement and) use XTunnel? + return dynamic_cast< ScVbaRange* >( rxRange.get() ); +} + +uno::Reference< frame::XModel > ScVbaRange::getUnoModel() throw (uno::RuntimeException) +{ + if( ScDocShell* pDocShell = getScDocShell() ) + return pDocShell->GetModel(); + throw uno::RuntimeException(); +} + +/*static*/ uno::Reference< frame::XModel > ScVbaRange::getUnoModel( const uno::Reference< excel::XRange >& rxRange ) throw (uno::RuntimeException) +{ + if( ScVbaRange* pScVbaRange = getImplementation( rxRange ) ) + return pScVbaRange->getUnoModel(); + throw uno::RuntimeException(); +} + +const ScRangeList& ScVbaRange::getScRangeList() throw (uno::RuntimeException) +{ + if( ScCellRangesBase* pScRangesBase = getCellRangesBase() ) + return pScRangesBase->GetRangeList(); + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain UNO range implementation object" ) ), uno::Reference< uno::XInterface >() ); +} + +/*static*/ const ScRangeList& ScVbaRange::getScRangeList( const uno::Reference< excel::XRange >& rxRange ) throw (uno::RuntimeException) +{ + if( ScVbaRange* pScVbaRange = getImplementation( rxRange ) ) + return pScVbaRange->getScRangeList(); + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain VBA range implementation object" ) ), uno::Reference< uno::XInterface >() ); +} + + class NumFormatHelper { uno::Reference< util::XNumberFormatsSupplier > mxSupplier; @@ -472,7 +517,7 @@ public: rtl::OUString getNumberFormatString() { uno::Reference< uno::XInterface > xIf( mxRangeProps, uno::UNO_QUERY_THROW ); - ScCellRangeObj* pUnoCellRange = dynamic_cast< ScCellRangeObj* >( xIf.get() ); + ScCellRangesBase* pUnoCellRange = ScCellRangesBase::getImplementation( xIf ); if ( pUnoCellRange ) { @@ -577,20 +622,17 @@ class CellsEnumeration : public CellsEnumeration_BASE uno::Reference< XCollection > m_xAreas; vCellPos m_CellPositions; vCellPos::const_iterator m_it; + uno::Reference< table::XCellRange > getArea( sal_Int32 nVBAIndex ) throw ( uno::RuntimeException ) { if ( nVBAIndex < 1 || nVBAIndex > m_xAreas->getCount() ) throw uno::RuntimeException(); uno::Reference< excel::XRange > xRange( m_xAreas->Item( uno::makeAny(nVBAIndex), uno::Any() ), uno::UNO_QUERY_THROW ); - ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xRange.get() ); - uno::Reference< table::XCellRange > xCellRange; - if ( !pRange ) - throw uno::RuntimeException(); - xCellRange.set( pRange->getCellRange(), uno::UNO_QUERY_THROW );; + uno::Reference< table::XCellRange > xCellRange( ScVbaRange::getCellRange( xRange ), uno::UNO_QUERY_THROW ); return xCellRange; - } - void populateArea( sal_Int32 nVBAIndex ) + + void populateArea( sal_Int32 nVBAIndex ) { uno::Reference< table::XCellRange > xRange = getArea( nVBAIndex ); uno::Reference< table::XColumnRowRange > xColumnRowRange(xRange, uno::UNO_QUERY_THROW ); @@ -1136,7 +1178,7 @@ bool getScRangeListForAddress( const rtl::OUString& sName, ScDocShell* pDocSh, S ScVbaRange* -getRangeForName( const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sName, ScDocShell* pDocSh, table::CellRangeAddress& pAddr, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( uno::RuntimeException ) +getRangeForName( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sName, ScDocShell* pDocSh, table::CellRangeAddress& pAddr, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( uno::RuntimeException ) { ScRangeList aCellRanges; ScRange refRange; @@ -1147,20 +1189,107 @@ getRangeForName( const uno::Reference< uno::XComponentContext >& xContext, const if ( aCellRanges.First() == aCellRanges.Last() ) { uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pDocSh, *aCellRanges.First() ) ); - // #FIXME need proper (WorkSheet) parent - return new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, xRange ); + return new ScVbaRange( xParent, xContext, xRange ); } uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocSh, aCellRanges ) ); + return new ScVbaRange( xParent, xContext, xRanges ); +} - // #FIXME need proper (WorkSheet) parent - return new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, xRanges ); +// ---------------------------------------------------------------------------- + +namespace { + +template< typename RangeType > +inline table::CellRangeAddress lclGetRangeAddress( const uno::Reference< RangeType >& rxCellRange ) throw (uno::RuntimeException) +{ + return uno::Reference< sheet::XCellRangeAddressable >( rxCellRange, uno::UNO_QUERY_THROW )->getRangeAddress(); +} + +uno::Reference< sheet::XSheetCellRange > lclExpandToMerged( const uno::Reference< table::XCellRange >& rxCellRange, bool bRecursive ) throw (uno::RuntimeException) +{ + uno::Reference< sheet::XSheetCellRange > xNewCellRange( rxCellRange, uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSpreadsheet > xSheet( xNewCellRange->getSpreadsheet(), uno::UNO_SET_THROW ); + table::CellRangeAddress aNewAddress = lclGetRangeAddress( xNewCellRange ); + table::CellRangeAddress aOldAddress; + // expand as long as there are new merged ranges included + do + { + aOldAddress = aNewAddress; + uno::Reference< sheet::XSheetCellCursor > xCursor( xSheet->createCursorByRange( xNewCellRange ), uno::UNO_SET_THROW ); + xCursor->collapseToMergedArea(); + xNewCellRange.set( xCursor, uno::UNO_QUERY_THROW ); + aNewAddress = lclGetRangeAddress( xNewCellRange ); + } + while( bRecursive && (aOldAddress != aNewAddress) ); + return xNewCellRange; } +uno::Reference< sheet::XSheetCellRangeContainer > lclExpandToMerged( const uno::Reference< sheet::XSheetCellRangeContainer >& rxCellRanges, bool bRecursive ) throw (uno::RuntimeException) +{ + if( !rxCellRanges.is() ) + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Missing cell ranges object" ) ), uno::Reference< uno::XInterface >() ); + sal_Int32 nCount = rxCellRanges->getCount(); + if( nCount < 1 ) + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Missing cell ranges object" ) ), uno::Reference< uno::XInterface >() ); + + ScRangeList aScRanges; + for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) + { + uno::Reference< table::XCellRange > xRange( rxCellRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + table::CellRangeAddress aRangeAddr = lclGetRangeAddress( lclExpandToMerged( xRange, bRecursive ) ); + ScRange aScRange; + ScUnoConversion::FillScRange( aScRange, aRangeAddr ); + aScRanges.Append( aScRange ); + } + return new ScCellRangesObj( getDocShellFromRanges( rxCellRanges ), aScRanges ); +} + +void lclExpandAndMerge( const uno::Reference< table::XCellRange >& rxCellRange, bool bMerge ) throw (uno::RuntimeException) +{ + uno::Reference< util::XMergeable > xMerge( lclExpandToMerged( rxCellRange, true ), uno::UNO_QUERY_THROW ); + // Calc cannot merge over merged ranges, always unmerge first + xMerge->merge( sal_False ); + if( bMerge ) + xMerge->merge( sal_True ); + // FIXME need to check whether all the cell contents are retained or lost by popping up a dialog +} + +util::TriState lclGetMergedState( const uno::Reference< table::XCellRange >& rxCellRange ) throw (uno::RuntimeException) +{ + /* 1) Check if range is completely inside one single merged range. To do + this, try to extend from top-left cell only (not from entire range). + This will excude cases where this range consists of several merged + ranges (or parts of them). */ + table::CellRangeAddress aRangeAddr = lclGetRangeAddress( rxCellRange ); + uno::Reference< table::XCellRange > xTopLeft( rxCellRange->getCellRangeByPosition( 0, 0, 0, 0 ), uno::UNO_SET_THROW ); + uno::Reference< sheet::XSheetCellRange > xExpanded( lclExpandToMerged( xTopLeft, false ), uno::UNO_SET_THROW ); + table::CellRangeAddress aExpAddr = lclGetRangeAddress( xExpanded ); + // check that expanded range has more than one cell (really merged) + if( ((aExpAddr.StartColumn < aExpAddr.EndColumn) || (aExpAddr.StartRow < aExpAddr.EndRow)) && ScUnoConversion::Contains( aExpAddr, aRangeAddr ) ) + return util::TriState_YES; + + /* 2) Check if this range contains any merged cells (completely or + partly). This seems to be hardly possible via API, as + XMergeable::getIsMerged() returns only true, if the top-left cell of a + merged range is part of this range, so cases where just the lower part + of a merged range is part of this range are not covered. */ + ScRange aScRange; + ScUnoConversion::FillScRange( aScRange, aRangeAddr ); + bool bHasMerged = getDocumentFromRange( rxCellRange )->HasAttrib( aScRange, HASATTR_MERGED | HASATTR_OVERLAPPED ); + return bHasMerged ? util::TriState_INDETERMINATE : util::TriState_NO; +} + +} // namespace + +// ---------------------------------------------------------------------------- + css::uno::Reference< excel::XRange > -ScVbaRange::getRangeObjectForName( const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sRangeName, ScDocShell* pDocSh, formula::FormulaGrammar::AddressConvention eConv ) throw ( uno::RuntimeException ) +ScVbaRange::getRangeObjectForName( const css::uno::Reference< ov::XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sRangeName, + ScDocShell* pDocSh, formula::FormulaGrammar::AddressConvention eConv ) throw ( uno::RuntimeException ) { table::CellRangeAddress refAddr; - return getRangeForName( xContext, sRangeName, pDocSh, refAddr, eConv ); + return getRangeForName( xParent, xContext, sRangeName, pDocSh, refAddr, eConv ); } @@ -1196,9 +1325,7 @@ table::CellRangeAddress getCellRangeAddressForVBARange( const uno::Any& aParam, default: throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can't extact CellRangeAddress from type" ) ), uno::Reference< uno::XInterface >() ); } - uno::Reference< sheet::XCellRangeAddressable > xAddressable( xRangeParam, uno::UNO_QUERY_THROW ); - return xAddressable->getRangeAddress(); - + return lclGetRangeAddress( xRangeParam ); } uno::Reference< XCollection > @@ -1398,7 +1525,7 @@ ScVbaRange::ClearContents( sal_Int32 nFlags ) throw (uno::RuntimeException) for ( sal_Int32 index=1; index <= nItems; ++index ) { uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW ); - ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xRange.get() ); + ScVbaRange* pRange = getImplementation( xRange ); if ( pRange ) pRange->ClearContents( nFlags ); } @@ -1595,7 +1722,7 @@ ScVbaRange::fillSeries( sheet::FillDirection nFillDirection, sheet::FillMode nFi for ( sal_Int32 index = 1; index <= xCollection->getCount(); ++index ) { uno::Reference< excel::XRange > xRange( xCollection->Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); - ScVbaRange* pThisRange = dynamic_cast< ScVbaRange* >( xRange.get() ); + ScVbaRange* pThisRange = getImplementation( xRange ); pThisRange->fillSeries( nFillDirection, nFillMode, nFillDateMode, fStep, fEndValue ); } @@ -1975,9 +2102,9 @@ ScVbaRange::Select() throw (uno::RuntimeException) uno::Reference< frame::XModel > xModel( pShell->GetModel(), uno::UNO_QUERY_THROW ); uno::Reference< view::XSelectionSupplier > xSelection( xModel->getCurrentController(), uno::UNO_QUERY_THROW ); if ( mxRanges.is() ) - xSelection->select( uno::makeAny( mxRanges ) ); + xSelection->select( uno::Any( lclExpandToMerged( mxRanges, true ) ) ); else - xSelection->select( uno::makeAny( mxRange ) ); + xSelection->select( uno::Any( lclExpandToMerged( mxRange, true ) ) ); // set focus on document e.g. // ThisComponent.CurrentController.Frame.getContainerWindow.SetFocus try @@ -1990,7 +2117,6 @@ ScVbaRange::Select() throw (uno::RuntimeException) catch( uno::Exception& ) { } - } } @@ -2168,36 +2294,65 @@ ScVbaRange::Columns(const uno::Any& aIndex ) throw (uno::RuntimeException) void ScVbaRange::setMergeCells( const uno::Any& aIsMerged ) throw (script::BasicErrorException, uno::RuntimeException) { - sal_Bool bIsMerged = sal_False; - aIsMerged >>= bIsMerged; - uno::Reference< util::XMergeable > xMerge( mxRange, ::uno::UNO_QUERY_THROW ); - //FIXME need to check whether all the cell contents are retained or lost by popping up a dialog - xMerge->merge( bIsMerged ); + bool bMerge = false; + aIsMerged >>= bMerge; + + if( mxRanges.is() ) + { + sal_Int32 nCount = mxRanges->getCount(); + + // VBA does nothing (no error) if the own ranges overlap somehow + ::std::vector< table::CellRangeAddress > aList; + for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) + { + uno::Reference< sheet::XCellRangeAddressable > xRangeAddr( mxRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + table::CellRangeAddress aAddress = xRangeAddr->getRangeAddress(); + for( ::std::vector< table::CellRangeAddress >::const_iterator aIt = aList.begin(), aEnd = aList.end(); aIt != aEnd; ++aIt ) + if( ScUnoConversion::Intersects( *aIt, aAddress ) ) + return; + aList.push_back( aAddress ); + } + + // (un)merge every range after it has been extended to intersecting merged ranges from sheet + for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) + { + uno::Reference< table::XCellRange > xRange( mxRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + lclExpandAndMerge( xRange, bMerge ); + } + return; + } + + // otherwise, merge single range + lclExpandAndMerge( mxRange, bMerge ); } uno::Any ScVbaRange::getMergeCells() throw (script::BasicErrorException, uno::RuntimeException) { - sal_Int32 nItems = m_Areas->getCount(); - - if ( nItems > 1 ) + if( mxRanges.is() ) { - uno::Any aResult = aNULL(); - for ( sal_Int32 index=1; index != nItems; ++index ) + sal_Int32 nCount = mxRanges->getCount(); + for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) { - uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW ); - if ( index > 1 ) - if ( aResult != xRange->getMergeCells() ) - return aNULL(); - aResult = xRange->getMergeCells(); - if ( aNULL() == aResult ) + uno::Reference< table::XCellRange > xRange( mxRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + util::TriState eMerged = lclGetMergedState( xRange ); + /* Excel always returns NULL, if one range of the range list is + partly or completely merged. Even if all ranges are completely + merged, the return value is still NULL. */ + if( eMerged != util::TriState_NO ) return aNULL(); } - return aResult; + // no range is merged anyhow, return false + return uno::Any( false ); + } + // otherwise, check single range + switch( lclGetMergedState( mxRange ) ) + { + case util::TriState_YES: return uno::Any( true ); + case util::TriState_NO: return uno::Any( false ); + default: return aNULL(); } - uno::Reference< util::XMergeable > xMerge( mxRange, ::uno::UNO_QUERY_THROW ); - return uno::makeAny( xMerge->getIsMerged() ); } void @@ -2425,7 +2580,7 @@ ScVbaRange::Range( const uno::Any &Cell1, const uno::Any &Cell2, bool bForceUseI Cell1 >>= sName; RangeHelper referRange( xReferrer ); table::CellRangeAddress referAddress = referRange.getCellRangeAddressable()->getRangeAddress(); - return getRangeForName( mxContext, sName, getScDocShell(), referAddress ); + return getRangeForName( getParent(), mxContext, sName, getScDocShell(), referAddress ); } else @@ -2488,8 +2643,7 @@ ScVbaRange::Range( const uno::Any &Cell1, const uno::Any &Cell2, bool bForceUseI // Allow access to underlying openoffice uno api ( useful for debugging // with openoffice basic ) -::com::sun::star::uno::Any SAL_CALL -ScVbaRange::getCellRange( ) throw (::com::sun::star::uno::RuntimeException) +uno::Any SAL_CALL ScVbaRange::getCellRange( ) throw (uno::RuntimeException) { uno::Any aAny; if ( mxRanges.is() ) @@ -2499,6 +2653,13 @@ ScVbaRange::getCellRange( ) throw (::com::sun::star::uno::RuntimeException) return aAny; } +/*static*/ uno::Any ScVbaRange::getCellRange( const uno::Reference< excel::XRange >& rxRange ) throw (uno::RuntimeException) +{ + if( ScVbaRange* pVbaRange = getImplementation( rxRange ) ) + return pVbaRange->getCellRange(); + throw uno::RuntimeException(); +} + static USHORT getPasteFlags (sal_Int32 Paste) { @@ -2632,14 +2793,25 @@ ScVbaRange::getEntireColumn() throw (uno::RuntimeException) uno::Reference< excel::XComment > SAL_CALL ScVbaRange::AddComment( const uno::Any& Text ) throw (uno::RuntimeException) { + // if there is already a comment in the top-left cell then throw + if( getComment().is() ) + throw uno::RuntimeException(); - uno::Reference< excel::XComment > xComment( new ScVbaComment( this, mxContext, mxRange ) ); - // if you don't pass a valid text or if there is already a comment - // associated with the range then return NULL - if ( !xComment->Text( Text, uno::Any(), uno::Any() ).getLength() - || xComment->Text( uno::Any(), uno::Any(), uno::Any() ).getLength() ) - return NULL; - return xComment; + // workaround: Excel allows to create empty comment, Calc does not + ::rtl::OUString aNoteText; + if( Text.hasValue() && !(Text >>= aNoteText) ) + throw uno::RuntimeException(); + if( aNoteText.getLength() == 0 ) + aNoteText = ::rtl::OUString( sal_Unicode( ' ' ) ); + + // try to create a new annotation + table::CellRangeAddress aRangePos = lclGetRangeAddress( mxRange ); + table::CellAddress aNotePos( aRangePos.Sheet, aRangePos.StartColumn, aRangePos.StartRow ); + uno::Reference< sheet::XSheetCellRange > xCellRange( mxRange, uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSheetAnnotationsSupplier > xAnnosSupp( xCellRange->getSpreadsheet(), uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), uno::UNO_SET_THROW ); + xAnnos->insertNew( aNotePos, aNoteText ); + return new ScVbaComment( this, mxContext, getUnoModel(), mxRange ); } uno::Reference< excel::XComment > SAL_CALL @@ -2647,7 +2819,7 @@ ScVbaRange::getComment() throw (uno::RuntimeException) { // intentional behavior to return a null object if no // comment defined - uno::Reference< excel::XComment > xComment( new ScVbaComment( this, mxContext, mxRange ) ); + uno::Reference< excel::XComment > xComment( new ScVbaComment( this, mxContext, getUnoModel(), mxRange ) ); if ( !xComment->Text( uno::Any(), uno::Any(), uno::Any() ).getLength() ) return NULL; return xComment; @@ -2976,7 +3148,7 @@ uno::Reference< table::XCellRange > processKey( const uno::Any& Key, uno::Refere table::CellRangeAddress aRefAddr; if ( !pDocSh ) throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Range::Sort no docshell to calculate key param")), uno::Reference< uno::XInterface >() ); - xKeyRange = getRangeForName( xContext, sRangeName, pDocSh, aRefAddr ); + xKeyRange = getRangeForName( uno::Reference< XHelperInterface >(), xContext, sRangeName, pDocSh, aRefAddr ); } else throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Range::Sort illegal type value for key param")), uno::Reference< uno::XInterface >() ); @@ -3734,16 +3906,16 @@ ScVbaRange::getPageBreak() throw (uno::RuntimeException) { ScDocument* pDoc = getDocumentFromRange( mxRange ); - BYTE nFlag = 0; + ScBreakType nBreak = BREAK_NONE; if ( !bColumn ) - nFlag = pDoc -> GetRowFlags(thisAddress.StartRow, thisAddress.Sheet); + nBreak = pDoc->HasRowBreak(thisAddress.StartRow, thisAddress.Sheet); else - nFlag = pDoc -> GetColFlags(static_cast<SCCOL>(thisAddress.StartColumn), thisAddress.Sheet); + nBreak = pDoc->HasColBreak(thisAddress.StartColumn, thisAddress.Sheet); - if ( nFlag & CR_PAGEBREAK) + if (nBreak & BREAK_PAGE) nPageBreak = excel::XlPageBreak::xlPageBreakAutomatic; - if ( nFlag & CR_MANUALBREAK) + if (nBreak & BREAK_MANUAL) nPageBreak = excel::XlPageBreak::xlPageBreakManual; } } @@ -4147,7 +4319,7 @@ ScVbaRange::AutoFilter( const uno::Any& Field, const uno::Any& Criteria1, const uno::Reference< excel::XRange > xCurrent( CurrentRegion() ); if ( xCurrent.is() ) { - ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xCurrent.get() ); + ScVbaRange* pRange = getImplementation( xCurrent ); if ( pRange->isSingleCellRange() ) throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can't create AutoFilter") ), uno::Reference< uno::XInterface >() ); if ( pRange ) @@ -4569,6 +4741,27 @@ ScVbaRange::TextToColumns( const css::uno::Any& Destination, const css::uno::Any //TODO* TrailingMinusNumbers Optional Variant. Numbers that begin with a minus character. } +uno::Any SAL_CALL +ScVbaRange::Hyperlinks( const uno::Any& aIndex ) throw (uno::RuntimeException) +{ + /* The range object always returns a new Hyperlinks object containing a + fixed list of existing hyperlinks in the range. + See vbahyperlinks.hxx for more details. */ + + // get the global hyperlink object of the sheet (sheet should always be the parent of a Range object) + uno::Reference< excel::XWorksheet > xWorksheet( getParent(), uno::UNO_QUERY_THROW ); + uno::Reference< excel::XHyperlinks > xSheetHlinks( xWorksheet->Hyperlinks( uno::Any() ), uno::UNO_QUERY_THROW ); + ScVbaHyperlinksRef xScSheetHlinks( dynamic_cast< ScVbaHyperlinks* >( xSheetHlinks.get() ) ); + if( !xScSheetHlinks.is() ) + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain hyperlinks implementation object" ) ), uno::Reference< uno::XInterface >() ); + + // create a new local hyperlinks object based on the sheet hyperlinks + ScVbaHyperlinksRef xHlinks( new ScVbaHyperlinks( getParent(), mxContext, xScSheetHlinks, getScRangeList() ) ); + if( aIndex.hasValue() ) + return xHlinks->Item( aIndex, uno::Any() ); + return uno::Any( uno::Reference< excel::XHyperlinks >( xHlinks.get() ) ); +} + css::uno::Reference< excel::XValidation > SAL_CALL ScVbaRange::getValidation() throw (css::uno::RuntimeException) { @@ -4577,6 +4770,97 @@ ScVbaRange::getValidation() throw (css::uno::RuntimeException) return m_xValidation; } +namespace { + +sal_Unicode lclGetPrefixChar( const uno::Reference< table::XCell >& rxCell ) throw (uno::RuntimeException) +{ + /* TODO/FIXME: We need an apostroph-prefix property at the cell to + implement this correctly. For now, return an apostroph for every text + cell. + + TODO/FIXME: When Application.TransitionNavigKeys is supported and true, + this function needs to inspect the cell formatting and return different + prefixes according to the horizontal cell alignment. + */ + return (rxCell->getType() == table::CellContentType_TEXT) ? '\'' : 0; +} + +sal_Unicode lclGetPrefixChar( const uno::Reference< table::XCellRange >& rxRange ) throw (uno::RuntimeException) +{ + /* This implementation is able to handle different prefixes (needed if + Application.TransitionNavigKeys is true). The function lclGetPrefixChar + for single cells called from here may return any prefix. If that + function returns an empty prefix (NUL character) or different non-empty + prefixes for two cells, this function returns 0. + */ + sal_Unicode cCurrPrefix = 0; + table::CellRangeAddress aRangeAddr = lclGetRangeAddress( rxRange ); + sal_Int32 nEndCol = aRangeAddr.EndColumn - aRangeAddr.StartColumn; + sal_Int32 nEndRow = aRangeAddr.EndRow - aRangeAddr.StartRow; + for( sal_Int32 nRow = 0; nRow <= nEndRow; ++nRow ) + { + for( sal_Int32 nCol = 0; nCol <= nEndCol; ++nCol ) + { + uno::Reference< table::XCell > xCell( rxRange->getCellByPosition( nCol, nRow ), uno::UNO_SET_THROW ); + sal_Unicode cNewPrefix = lclGetPrefixChar( xCell ); + if( (cNewPrefix == 0) || ((cCurrPrefix != 0) && (cNewPrefix != cCurrPrefix)) ) + return 0; + cCurrPrefix = cNewPrefix; + } + } + // all cells contain the same prefix - return it + return cCurrPrefix; +} + +sal_Unicode lclGetPrefixChar( const uno::Reference< sheet::XSheetCellRangeContainer >& rxRanges ) throw (uno::RuntimeException) +{ + sal_Unicode cCurrPrefix = 0; + uno::Reference< container::XEnumerationAccess > xRangesEA( rxRanges, uno::UNO_QUERY_THROW ); + uno::Reference< container::XEnumeration > xRangesEnum( xRangesEA->createEnumeration(), uno::UNO_SET_THROW ); + while( xRangesEnum->hasMoreElements() ) + { + uno::Reference< table::XCellRange > xRange( xRangesEnum->nextElement(), uno::UNO_QUERY_THROW ); + sal_Unicode cNewPrefix = lclGetPrefixChar( xRange ); + if( (cNewPrefix == 0) || ((cCurrPrefix != 0) && (cNewPrefix != cCurrPrefix)) ) + return 0; + cCurrPrefix = cNewPrefix; + } + // all ranges contain the same prefix - return it + return cCurrPrefix; +} + +inline uno::Any lclGetPrefixVariant( sal_Unicode cPrefixChar ) +{ + return uno::Any( (cPrefixChar == 0) ? ::rtl::OUString() : ::rtl::OUString( cPrefixChar ) ); +} + +} // namespace + +uno::Any SAL_CALL ScVbaRange::getPrefixCharacter() throw (uno::RuntimeException) +{ + /* (1) If Application.TransitionNavigKeys is false, this function returns + an apostroph character if the text cell begins with an apostroph + character (formula return values are not taken into account); otherwise + an empty string. + + (2) If Application.TransitionNavigKeys is true, this function returns + an apostroph character, if the cell is left-aligned; a double-quote + character, if the cell is right-aligned; a circumflex character, if the + cell is centered; a backslash character, if the cell is set to filled; + or an empty string, if nothing of the above. + + If a range or a list of ranges contains texts with leading apostroph + character as well as other cells, this function returns an empty + string. + */ + + if( mxRange.is() ) + return lclGetPrefixVariant( lclGetPrefixChar( mxRange ) ); + if( mxRanges.is() ) + return lclGetPrefixVariant( lclGetPrefixChar( mxRanges ) ); + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected empty Range object" ) ), uno::Reference< uno::XInterface >() ); +} + uno::Any ScVbaRange::getShowDetail() throw ( css::uno::RuntimeException) { // #FIXME, If the specified range is in a PivotTable report @@ -4701,7 +4985,7 @@ ScVbaRange::PrintOut( const uno::Any& From, const uno::Any& To, const uno::Any& table::CellRangeAddress rangeAddress = thisRange.getCellRangeAddressable()->getRangeAddress(); if ( index == 1 ) { - ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xRange.get() ); + ScVbaRange* pRange = getImplementation( xRange ); // initialise the doc shell and the printareas pShell = getDocShellFromRange( pRange->mxRange ); xPrintAreas.set( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW ); @@ -4723,7 +5007,7 @@ void SAL_CALL ScVbaRange::AutoFill( const uno::Reference< excel::XRange >& Destination, const uno::Any& Type ) throw (uno::RuntimeException) { uno::Reference< excel::XRange > xDest( Destination, uno::UNO_QUERY_THROW ); - ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xDest.get() ); + ScVbaRange* pRange = getImplementation( xDest ); RangeHelper destRangeHelper( pRange->mxRange ); table::CellRangeAddress destAddress = destRangeHelper.getCellRangeAddressable()->getRangeAddress(); @@ -5133,7 +5417,7 @@ ScVbaRange::SpecialCells( const uno::Any& _oType, const uno::Any& _oValue) throw { uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW ); xRange = xRange->SpecialCells( _oType, _oValue); - ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xRange.get() ); + ScVbaRange* pRange = getImplementation( xRange ); if ( xRange.is() && pRange ) { sal_Int32 nElems = ( pRange->m_Areas->getCount() + 1 ); diff --git a/sc/source/ui/vba/vbarange.hxx b/sc/source/ui/vba/vbarange.hxx index 1f161a79d973..a9147a0d7840 100644 --- a/sc/source/ui/vba/vbarange.hxx +++ b/sc/source/ui/vba/vbarange.hxx @@ -60,6 +60,7 @@ class ScCellRangeObj; class ScCellRangesObj; class ScDocShell; class ScDocument; +class ScRangeList; //typedef InheritedHelperInterfaceImpl1< ov::excel::XRange > ScVbaRange_BASE; typedef ScVbaFormat< ov::excel::XRange > ScVbaRange_BASE; @@ -127,13 +128,27 @@ public: 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 ); ScVbaRange( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext ) throw ( css::lang::IllegalArgumentException ); - ScDocument* getScDocument(); - ScDocShell* getScDocShell(); + ScDocument* getScDocument() throw (css::uno::RuntimeException); + ScDocShell* getScDocShell() throw (css::uno::RuntimeException); + + /** Returns the ScVbaRange implementation object for the passed VBA Range object. */ + static ScVbaRange* getImplementation( const css::uno::Reference< ov::excel::XRange >& rxRange ); + + css::uno::Reference< css::frame::XModel > getUnoModel() throw (css::uno::RuntimeException); + static css::uno::Reference< css::frame::XModel > getUnoModel( const css::uno::Reference< ov::excel::XRange >& rxRange ) throw (css::uno::RuntimeException); + + const ScRangeList& getScRangeList() throw (css::uno::RuntimeException); + static const ScRangeList& getScRangeList( const css::uno::Reference< ov::excel::XRange >& rxRange ) throw (css::uno::RuntimeException); virtual ~ScVbaRange(); virtual css::uno::Reference< ov::XHelperInterface > thisHelperIface() { return this; } bool isSingleCellRange(); - static css::uno::Reference< ov::excel::XRange > getRangeObjectForName( const css::uno::Reference< css::uno::XComponentContext >& xContext, 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 > getRangeObjectForName( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const rtl::OUString& sRangeName, ScDocShell* pDocSh, + formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( css::uno::RuntimeException ); // Attributes virtual css::uno::Any SAL_CALL getValue() throw (css::uno::RuntimeException); @@ -173,6 +188,7 @@ 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 getPrefixCharacter() throw (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 @@ -212,6 +228,7 @@ public: virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Range( const css::uno::Any &Cell1, const css::uno::Any &Cell2 ) throw (css::uno::RuntimeException); virtual css::uno::Reference< ov::excel::XRange > Range( const css::uno::Any &Cell1, const css::uno::Any &Cell2, bool bForceUseInpuRangeTab ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL getCellRange( ) throw (css::uno::RuntimeException); + static css::uno::Any getCellRange( const css::uno::Reference< ov::excel::XRange >& rxRange ) throw (css::uno::RuntimeException); virtual void SAL_CALL PasteSpecial( const css::uno::Any& Paste, const css::uno::Any& Operation, const css::uno::Any& SkipBlanks, const css::uno::Any& Transpose ) throw (css::uno::RuntimeException); virtual ::sal_Bool SAL_CALL Replace( const ::rtl::OUString& What, const ::rtl::OUString& Replacement, const css::uno::Any& LookAt, const css::uno::Any& SearchOrder, const css::uno::Any& MatchCase, const css::uno::Any& MatchByte, const css::uno::Any& SearchFormat, const css::uno::Any& ReplaceFormat ) throw (css::uno::RuntimeException); virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Find( const css::uno::Any& What, const css::uno::Any& After, const css::uno::Any& LookIn, const css::uno::Any& LookAt, const css::uno::Any& SearchOrder, const css::uno::Any& SearchDirection, const css::uno::Any& MatchCase, const css::uno::Any& MatchByte, const css::uno::Any& SearchFormat ) throw (css::uno::RuntimeException); @@ -227,6 +244,7 @@ public: const css::uno::Any& ConsecutinveDelimiter, const css::uno::Any& Tab, const css::uno::Any& Semicolon, const css::uno::Any& Comma, const css::uno::Any& Space, const css::uno::Any& Other, const css::uno::Any& OtherChar, const css::uno::Any& FieldInfo, const css::uno::Any& DecimalSeparator, const css::uno::Any& ThousandsSeparator, const css::uno::Any& TrailingMinusNumbers ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Hyperlinks( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); virtual void SAL_CALL AutoFilter( const css::uno::Any& Field, const css::uno::Any& Criteria1, const css::uno::Any& Operator, const css::uno::Any& Criteria2, const css::uno::Any& VisibleDropDown ) throw (css::uno::RuntimeException); virtual void SAL_CALL Insert( const css::uno::Any& Shift, const css::uno::Any& CopyOrigin ) throw (css::uno::RuntimeException); diff --git a/sc/source/ui/vba/vbasheetobject.cxx b/sc/source/ui/vba/vbasheetobject.cxx new file mode 100755 index 000000000000..4bd0f1d60547 --- /dev/null +++ b/sc/source/ui/vba/vbasheetobject.cxx @@ -0,0 +1,517 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "vbasheetobject.hxx" +#include <com/sun/star/awt/TextAlign.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/drawing/XControlShape.hpp> +#include <com/sun/star/script/ScriptEventDescriptor.hpp> +#include <com/sun/star/script/XEventAttacherManager.hpp> +#include <com/sun/star/style/VerticalAlignment.hpp> +#include <ooo/vba/excel/Constants.hpp> +#include <ooo/vba/excel/XlOrientation.hpp> +#include <ooo/vba/excel/XlPlacement.hpp> +#include <rtl/ustrbuf.hxx> +#include <filter/msfilter/msvbahelper.hxx> +#include <oox/helper/helper.hxx> +#include "vbafont.hxx" + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::ooo::vba; + +// ============================================================================ + +ScVbaButtonCharacters::ScVbaButtonCharacters( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< beans::XPropertySet >& rxPropSet, + const ScVbaPalette& rPalette, + const uno::Any& rStart, + const uno::Any& rLength ) throw (uno::RuntimeException) : + ScVbaButtonCharacters_BASE( rxParent, rxContext ), + maPalette( rPalette ), + mxPropSet( rxPropSet, uno::UNO_SET_THROW ) +{ + // extract optional start parameter (missing or invalid -> from beginning) + if( !(rStart >>= mnStart) || (mnStart < 1) ) + mnStart = 1; + --mnStart; // VBA is 1-based, rtl string is 0-based + + // extract optional length parameter (missing or invalid -> to end) + if( !(rLength >>= mnLength) || (mnLength < 1) ) + mnLength = SAL_MAX_INT32; +} + +ScVbaButtonCharacters::~ScVbaButtonCharacters() +{ +} + +// XCharacters attributes + +OUString SAL_CALL ScVbaButtonCharacters::getCaption() throw (uno::RuntimeException) +{ + // ignore invalid mnStart and/or mnLength members + OUString aString = getFullString(); + sal_Int32 nStart = ::std::min( mnStart, aString.getLength() ); + sal_Int32 nLength = ::std::min( mnLength, aString.getLength() - nStart ); + return aString.copy( nStart, nLength ); +} + +void SAL_CALL ScVbaButtonCharacters::setCaption( const OUString& rCaption ) throw (uno::RuntimeException) +{ + /* Replace the covered text with the passed text, ignore invalid mnStart + and/or mnLength members. This operation does not affect the mnLength + parameter. If the inserted text is longer than mnLength, the additional + characters are not covered by this object. If the inserted text is + shorter than mnLength, other uncovered characters from the original + string will be covered now, thus may be changed with subsequent + operations. */ + OUString aString = getFullString(); + sal_Int32 nStart = ::std::min( mnStart, aString.getLength() ); + sal_Int32 nLength = ::std::min( mnLength, aString.getLength() - nStart ); + setFullString( aString.replaceAt( nStart, nLength, rCaption ) ); +} + +sal_Int32 SAL_CALL ScVbaButtonCharacters::getCount() throw (uno::RuntimeException) +{ + // always return the total length of the caption + return getFullString().getLength(); +} + +OUString SAL_CALL ScVbaButtonCharacters::getText() throw (uno::RuntimeException) +{ + // Text attribute same as Caption attribute? + return getCaption(); +} + +void SAL_CALL ScVbaButtonCharacters::setText( const OUString& rText ) throw (uno::RuntimeException) +{ + // Text attribute same as Caption attribute? + setCaption( rText ); +} + +uno::Reference< excel::XFont > SAL_CALL ScVbaButtonCharacters::getFont() throw (uno::RuntimeException) +{ + return new ScVbaFont( this, mxContext, maPalette, mxPropSet, 0, true ); +} + +void SAL_CALL ScVbaButtonCharacters::setFont( const uno::Reference< excel::XFont >& /*rxFont*/ ) throw (uno::RuntimeException) +{ + // TODO +} + +// XCharacters methods + +void SAL_CALL ScVbaButtonCharacters::Insert( const OUString& rString ) throw (uno::RuntimeException) +{ + /* The Insert() operation is in fact "replace covered characters", at + least for buttons... It seems there is no easy way to really insert a + substring. This operation does not affect the mnLength parameter. */ + setCaption( rString ); +} + +void SAL_CALL ScVbaButtonCharacters::Delete() throw (uno::RuntimeException) +{ + /* The Delete() operation is nothing else than "replace with empty string". + This does not affect the mnLength parameter, multiple calls of Delete() + will remove characters as long as there are some more covered by this + object. */ + setCaption( OUString() ); +} + +// XHelperInterface + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButtonCharacters, "ooo.vba.excel.Characters" ) + +// private + +OUString ScVbaButtonCharacters::getFullString() const throw (uno::RuntimeException) +{ + return mxPropSet->getPropertyValue( CREATE_OUSTRING( "Label" ) ).get< OUString >(); +} + +void ScVbaButtonCharacters::setFullString( const OUString& rString ) throw (uno::RuntimeException) +{ + mxPropSet->setPropertyValue( CREATE_OUSTRING( "Label" ), uno::Any( rString ) ); +} + +// ============================================================================ + +ScVbaSheetObjectBase::ScVbaSheetObjectBase( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) : + ScVbaSheetObject_BASE( rxParent, rxContext ), + maPalette( rxModel ), + mxModel( rxModel, uno::UNO_SET_THROW ), + mxShape( rxShape, uno::UNO_SET_THROW ), + mxShapeProps( rxShape, uno::UNO_QUERY_THROW ) +{ +} + +// XSheetObject attributes + +double SAL_CALL ScVbaSheetObjectBase::getLeft() throw (uno::RuntimeException) +{ + return HmmToPoints( mxShape->getPosition().X ); +} + +void SAL_CALL ScVbaSheetObjectBase::setLeft( double fLeft ) throw (uno::RuntimeException) +{ + if( fLeft < 0.0 ) + throw uno::RuntimeException(); + mxShape->setPosition( awt::Point( PointsToHmm( fLeft ), mxShape->getPosition().Y ) ); +} + +double SAL_CALL ScVbaSheetObjectBase::getTop() throw (uno::RuntimeException) +{ + return HmmToPoints( mxShape->getPosition().Y ); +} + +void SAL_CALL ScVbaSheetObjectBase::setTop( double fTop ) throw (uno::RuntimeException) +{ + if( fTop < 0.0 ) + throw uno::RuntimeException(); + mxShape->setPosition( awt::Point( mxShape->getPosition().X, PointsToHmm( fTop ) ) ); +} + +double SAL_CALL ScVbaSheetObjectBase::getWidth() throw (uno::RuntimeException) +{ + return HmmToPoints( mxShape->getSize().Width ); +} + +void SAL_CALL ScVbaSheetObjectBase::setWidth( double fWidth ) throw (uno::RuntimeException) +{ + if( fWidth <= 0.0 ) + throw uno::RuntimeException(); + mxShape->setSize( awt::Size( PointsToHmm( fWidth ), mxShape->getSize().Height ) ); +} + +double SAL_CALL ScVbaSheetObjectBase::getHeight() throw (uno::RuntimeException) +{ + return HmmToPoints( mxShape->getSize().Height ); +} + +void SAL_CALL ScVbaSheetObjectBase::setHeight( double fHeight ) throw (uno::RuntimeException) +{ + if( fHeight <= 0.0 ) + throw uno::RuntimeException(); + mxShape->setSize( awt::Size( mxShape->getSize().Width, PointsToHmm( fHeight ) ) ); +} + +OUString SAL_CALL ScVbaSheetObjectBase::getName() throw (uno::RuntimeException) +{ + return mxShapeProps->getPropertyValue( CREATE_OUSTRING( "Name" ) ).get< OUString >(); +} + +void SAL_CALL ScVbaSheetObjectBase::setName( const OUString& rName ) throw (uno::RuntimeException) +{ + mxShapeProps->setPropertyValue( CREATE_OUSTRING( "Name" ), uno::Any( rName ) ); +} + +sal_Int32 SAL_CALL ScVbaSheetObjectBase::getPlacement() throw (uno::RuntimeException) +{ + // TODO + return excel::XlPlacement::xlMoveAndSize; +} + +void SAL_CALL ScVbaSheetObjectBase::setPlacement( sal_Int32 /*nPlacement*/ ) throw (uno::RuntimeException) +{ + // TODO +} + +sal_Bool SAL_CALL ScVbaSheetObjectBase::getPrintObject() throw (uno::RuntimeException) +{ + // not supported + return sal_True; +} + +void SAL_CALL ScVbaSheetObjectBase::setPrintObject( sal_Bool /*bPrintObject*/ ) throw (uno::RuntimeException) +{ + // not supported +} + +// private + +void ScVbaSheetObjectBase::setDefaultProperties( sal_Int32 nIndex ) throw (uno::RuntimeException) +{ + OUString aName = ::rtl::OUStringBuffer( implGetBaseName() ).append( sal_Unicode( ' ' ) ).append( nIndex + 1 ).makeStringAndClear(); + setName( aName ); + implSetDefaultProperties(); +} + +void ScVbaSheetObjectBase::implSetDefaultProperties() throw (uno::RuntimeException) +{ +} + +// ============================================================================ + +ScVbaControlObjectBase::ScVbaControlObjectBase( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< container::XIndexContainer >& rxFormIC, + const uno::Reference< drawing::XControlShape >& rxControlShape, + ListenerType eListenerType ) throw (uno::RuntimeException) : + ScVbaControlObject_BASE( rxParent, rxContext, rxModel, uno::Reference< drawing::XShape >( rxControlShape, uno::UNO_QUERY_THROW ) ), + mxFormIC( rxFormIC, uno::UNO_SET_THROW ), + mxControlProps( rxControlShape->getControl(), uno::UNO_QUERY_THROW ) +{ + // set listener and event name to be used for OnAction attribute + switch( eListenerType ) + { + case LISTENER_ACTION: + maListenerType = CREATE_OUSTRING( "XActionListener" ); + maEventMethod = CREATE_OUSTRING( "actionPerformed" ); + break; + case LISTENER_MOUSE: + maListenerType = CREATE_OUSTRING( "XMouseListener" ); + maEventMethod = CREATE_OUSTRING( "mouseReleased" ); + break; + case LISTENER_TEXT: + maListenerType = CREATE_OUSTRING( "XTextListener" ); + maEventMethod = CREATE_OUSTRING( "textChanged" ); + break; + case LISTENER_VALUE: + maListenerType = CREATE_OUSTRING( "XAdjustmentListener" ); + maEventMethod = CREATE_OUSTRING( "adjustmentValueChanged" ); + break; + case LISTENER_CHANGE: + maListenerType = CREATE_OUSTRING( "XChangeListener" ); + maEventMethod = CREATE_OUSTRING( "changed" ); + break; + // no default, to let the compiler complain about missing case + } +} + +// XSheetObject attributes + +OUString SAL_CALL ScVbaControlObjectBase::getName() throw (uno::RuntimeException) +{ + return mxControlProps->getPropertyValue( CREATE_OUSTRING( "Name" ) ).get< OUString >(); +} + +void SAL_CALL ScVbaControlObjectBase::setName( const OUString& rName ) throw (uno::RuntimeException) +{ + mxControlProps->setPropertyValue( CREATE_OUSTRING( "Name" ), uno::Any( rName ) ); +} + +OUString SAL_CALL ScVbaControlObjectBase::getOnAction() throw (uno::RuntimeException) +{ + uno::Reference< script::XEventAttacherManager > xEventMgr( mxFormIC, uno::UNO_QUERY_THROW ); + sal_Int32 nIndex = getModelIndexInForm(); + uno::Sequence< script::ScriptEventDescriptor > aEvents = xEventMgr->getScriptEvents( nIndex ); + if( aEvents.hasElements() ) + { + const script::ScriptEventDescriptor* pEvent = aEvents.getConstArray(); + const script::ScriptEventDescriptor* pEventEnd = pEvent + aEvents.getLength(); + const OUString aScriptType = CREATE_OUSTRING( "Script" ); + for( ; pEvent < pEventEnd; ++pEvent ) + if( (pEvent->ListenerType == maListenerType) && (pEvent->EventMethod == maEventMethod) && (pEvent->ScriptType == aScriptType) ) + return extractMacroName( pEvent->ScriptCode ); + } + return OUString(); +} + +void SAL_CALL ScVbaControlObjectBase::setOnAction( const OUString& rMacroName ) throw (uno::RuntimeException) +{ + uno::Reference< script::XEventAttacherManager > xEventMgr( mxFormIC, uno::UNO_QUERY_THROW ); + sal_Int32 nIndex = getModelIndexInForm(); + + // first, remove a registered event (try/catch just in case implementation throws) + try { xEventMgr->revokeScriptEvent( nIndex, maListenerType, maEventMethod, OUString() ); } catch( uno::Exception& ) {} + + // if a macro name has been passed, try to attach it to the event + if( rMacroName.getLength() > 0 ) + { + VBAMacroResolvedInfo aResolvedMacro = resolveVBAMacro( getSfxObjShell( mxModel ), rMacroName ); + if( !aResolvedMacro.IsResolved() ) + throw uno::RuntimeException(); + script::ScriptEventDescriptor aDescriptor; + aDescriptor.ListenerType = maListenerType; + aDescriptor.EventMethod = maEventMethod; + aDescriptor.ScriptType = CREATE_OUSTRING( "Script" ); + aDescriptor.ScriptCode = makeMacroURL( aResolvedMacro.ResolvedMacro() ); + xEventMgr->registerScriptEvent( nIndex, aDescriptor ); + } +} + +sal_Bool SAL_CALL ScVbaControlObjectBase::getPrintObject() throw (uno::RuntimeException) +{ + return mxControlProps->getPropertyValue( CREATE_OUSTRING( "Printable" ) ).get< sal_Bool >(); +} + +void SAL_CALL ScVbaControlObjectBase::setPrintObject( sal_Bool bPrintObject ) throw (uno::RuntimeException) +{ + mxControlProps->setPropertyValue( CREATE_OUSTRING( "Printable" ), uno::Any( bPrintObject ) ); +} + +// XControlObject attributes + +sal_Bool SAL_CALL ScVbaControlObjectBase::getAutoSize() throw (uno::RuntimeException) +{ + // not supported + return sal_False; +} + +void SAL_CALL ScVbaControlObjectBase::setAutoSize( sal_Bool /*bAutoSize*/ ) throw (uno::RuntimeException) +{ + // not supported +} + +// private + +sal_Int32 ScVbaControlObjectBase::getModelIndexInForm() const throw (uno::RuntimeException) +{ + for( sal_Int32 nIndex = 0, nCount = mxFormIC->getCount(); nIndex < nCount; ++nIndex ) + { + uno::Reference< beans::XPropertySet > xProps( mxFormIC->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + if( mxControlProps.get() == xProps.get() ) + return nIndex; + } + throw uno::RuntimeException(); +} + +// ============================================================================ + +ScVbaButton::ScVbaButton( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< container::XIndexContainer >& rxFormIC, + const uno::Reference< drawing::XControlShape >& rxControlShape ) throw (uno::RuntimeException) : + ScVbaButton_BASE( rxParent, rxContext, rxModel, rxFormIC, rxControlShape, LISTENER_ACTION ) +{ +} + +// XButton attributes + +OUString SAL_CALL ScVbaButton::getCaption() throw (uno::RuntimeException) +{ + return mxControlProps->getPropertyValue( CREATE_OUSTRING( "Label" ) ).get< OUString >(); +} + +void SAL_CALL ScVbaButton::setCaption( const OUString& rCaption ) throw (uno::RuntimeException) +{ + mxControlProps->setPropertyValue( CREATE_OUSTRING( "Label" ), uno::Any( rCaption ) ); +} + +uno::Reference< excel::XFont > SAL_CALL ScVbaButton::getFont() throw (uno::RuntimeException) +{ + return new ScVbaFont( this, mxContext, maPalette, mxControlProps, 0, true ); +} + +void SAL_CALL ScVbaButton::setFont( const uno::Reference< excel::XFont >& /*rxFont*/ ) throw (uno::RuntimeException) +{ + // TODO +} + +sal_Int32 SAL_CALL ScVbaButton::getHorizontalAlignment() throw (uno::RuntimeException) +{ + switch( mxControlProps->getPropertyValue( CREATE_OUSTRING( "Align" ) ).get< sal_Int16 >() ) + { + case awt::TextAlign::LEFT: return excel::Constants::xlLeft; + case awt::TextAlign::RIGHT: return excel::Constants::xlRight; + case awt::TextAlign::CENTER: return excel::Constants::xlCenter; + } + return excel::Constants::xlCenter; +} + +void SAL_CALL ScVbaButton::setHorizontalAlignment( sal_Int32 nAlign ) throw (uno::RuntimeException) +{ + sal_Int32 nAwtAlign = awt::TextAlign::CENTER; + switch( nAlign ) + { + case excel::Constants::xlLeft: nAwtAlign = awt::TextAlign::LEFT; break; + case excel::Constants::xlRight: nAwtAlign = awt::TextAlign::RIGHT; break; + case excel::Constants::xlCenter: nAwtAlign = awt::TextAlign::CENTER; break; + } + // form controls expect short value + mxControlProps->setPropertyValue( CREATE_OUSTRING( "Align" ), uno::Any( static_cast< sal_Int16 >( nAwtAlign ) ) ); +} + +sal_Int32 SAL_CALL ScVbaButton::getVerticalAlignment() throw (uno::RuntimeException) +{ + switch( mxControlProps->getPropertyValue( CREATE_OUSTRING( "VerticalAlign" ) ).get< style::VerticalAlignment >() ) + { + case style::VerticalAlignment_TOP: return excel::Constants::xlTop; + case style::VerticalAlignment_BOTTOM: return excel::Constants::xlBottom; + case style::VerticalAlignment_MIDDLE: return excel::Constants::xlCenter; + default:; + } + return excel::Constants::xlCenter; +} + +void SAL_CALL ScVbaButton::setVerticalAlignment( sal_Int32 nAlign ) throw (uno::RuntimeException) +{ + style::VerticalAlignment eAwtAlign = style::VerticalAlignment_MIDDLE; + switch( nAlign ) + { + case excel::Constants::xlTop: eAwtAlign = style::VerticalAlignment_TOP; break; + case excel::Constants::xlBottom: eAwtAlign = style::VerticalAlignment_BOTTOM; break; + case excel::Constants::xlCenter: eAwtAlign = style::VerticalAlignment_MIDDLE; break; + } + mxControlProps->setPropertyValue( CREATE_OUSTRING( "VerticalAlign" ), uno::Any( eAwtAlign ) ); +} + +sal_Int32 SAL_CALL ScVbaButton::getOrientation() throw (uno::RuntimeException) +{ + // not supported + return excel::XlOrientation::xlHorizontal; +} + +void SAL_CALL ScVbaButton::setOrientation( sal_Int32 /*nOrientation*/ ) throw (uno::RuntimeException) +{ + // not supported +} + +// XButton methods + +uno::Reference< excel::XCharacters > SAL_CALL ScVbaButton::Characters( const uno::Any& rStart, const uno::Any& rLength ) throw (uno::RuntimeException) +{ + return new ScVbaButtonCharacters( this, mxContext, mxControlProps, maPalette, rStart, rLength ); +} + +// XHelperInterface + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButton, "ooo.vba.excel.Button" ) + +// private + +OUString ScVbaButton::implGetBaseName() const +{ + return CREATE_OUSTRING( "Button" ); +} + +void ScVbaButton::implSetDefaultProperties() throw (uno::RuntimeException) +{ + setCaption( getName() ); +} + +// ============================================================================ diff --git a/sc/source/ui/vba/vbasheetobject.hxx b/sc/source/ui/vba/vbasheetobject.hxx new file mode 100755 index 000000000000..b2546ca09c93 --- /dev/null +++ b/sc/source/ui/vba/vbasheetobject.hxx @@ -0,0 +1,220 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_VBA_SHEETOBJECT_HXX +#define SC_VBA_SHEETOBJECT_HXX + +#include <memory> +#include <ooo/vba/excel/XButton.hpp> +#include <ooo/vba/excel/XControlObject.hpp> +#include <ooo/vba/excel/XSheetObject.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include "vbapalette.hxx" + +namespace com { namespace sun { namespace star { + namespace container { class XIndexContainer; } + namespace drawing { class XControlShape; } +} } } + +// ============================================================================ + +typedef InheritedHelperInterfaceImpl1< ov::excel::XCharacters > ScVbaButtonCharacters_BASE; + +/** Simple implementation of the Characters symbol for drawing button objects. */ +class ScVbaButtonCharacters : public ScVbaButtonCharacters_BASE +{ +public: + explicit ScVbaButtonCharacters( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::beans::XPropertySet >& rxPropSet, + const ScVbaPalette& rPalette, + const css::uno::Any& rStart, + const css::uno::Any& rLength ) throw (css::uno::RuntimeException); + virtual ~ScVbaButtonCharacters(); + + // XCharacters attributes + virtual ::rtl::OUString SAL_CALL getCaption() throw (css::uno::RuntimeException); + virtual void SAL_CALL setCaption( const ::rtl::OUString& rCaption ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getText() throw (css::uno::RuntimeException); + virtual void SAL_CALL setText( const ::rtl::OUString& rText ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getCount() throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XFont > SAL_CALL getFont() throw (css::uno::RuntimeException); + virtual void SAL_CALL setFont( const css::uno::Reference< ov::excel::XFont >& rxFont ) throw (css::uno::RuntimeException); + + // XCharacters methods + virtual void SAL_CALL Insert( const ::rtl::OUString& rString ) throw (css::uno::RuntimeException); + virtual void SAL_CALL Delete() throw (css::uno::RuntimeException); + + // XHelperInterface + VBAHELPER_DECL_XHELPERINTERFACE + +private: + ::rtl::OUString getFullString() const throw (css::uno::RuntimeException); + void setFullString( const ::rtl::OUString& rString ) throw (css::uno::RuntimeException); + +private: + ScVbaPalette maPalette; + css::uno::Reference< css::beans::XPropertySet > mxPropSet; + sal_Int32 mnStart; + sal_Int32 mnLength; +}; + +// ============================================================================ + +typedef InheritedHelperInterfaceImpl1< ov::excel::XSheetObject > ScVbaSheetObject_BASE; + +/** Base class for drawing objects embedded in sheets. */ +class ScVbaSheetObjectBase : public ScVbaSheetObject_BASE +{ +public: + explicit ScVbaSheetObjectBase( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::frame::XModel >& rxModel, + const css::uno::Reference< css::drawing::XShape >& rxShape ) throw (css::uno::RuntimeException); + + // XSheetObject attributes + virtual double SAL_CALL getLeft() throw (css::uno::RuntimeException); + virtual void SAL_CALL setLeft( double fLeft ) throw (css::uno::RuntimeException); + virtual double SAL_CALL getTop() throw (css::uno::RuntimeException); + virtual void SAL_CALL setTop( double fTop ) throw (css::uno::RuntimeException); + virtual double SAL_CALL getWidth() throw (css::uno::RuntimeException); + virtual void SAL_CALL setWidth( double fWidth ) throw (css::uno::RuntimeException); + virtual double SAL_CALL getHeight() throw (css::uno::RuntimeException); + virtual void SAL_CALL setHeight( double fHeight ) throw (css::uno::RuntimeException); + 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_Int32 SAL_CALL getPlacement() throw (css::uno::RuntimeException); + virtual void SAL_CALL setPlacement( sal_Int32 nPlacement ) throw (css::uno::RuntimeException); + virtual sal_Bool SAL_CALL getPrintObject() throw (css::uno::RuntimeException); + virtual void SAL_CALL setPrintObject( sal_Bool bPrintObject ) throw (css::uno::RuntimeException); + + /** Sets default properties after a new object has been created. */ + void setDefaultProperties( sal_Int32 nIndex ) throw (css::uno::RuntimeException); + +protected: + /** Derived classes return the base name used for new objects. */ + virtual ::rtl::OUString implGetBaseName() const = 0; + /** Derived classes set default properties for new drawing objects. */ + virtual void implSetDefaultProperties() throw (css::uno::RuntimeException); + +protected: + ScVbaPalette maPalette; + css::uno::Reference< css::frame::XModel > mxModel; + css::uno::Reference< css::drawing::XShape > mxShape; + css::uno::Reference< css::beans::XPropertySet > mxShapeProps; +}; + +// ============================================================================ + +typedef ::cppu::ImplInheritanceHelper1< ScVbaSheetObjectBase, ov::excel::XControlObject > ScVbaControlObject_BASE; + +class ScVbaControlObjectBase : public ScVbaControlObject_BASE +{ +public: + /** Specifies the listener used for OnAction events. */ + enum ListenerType + { + LISTENER_ACTION, /// XActionListener.actionPerformed + LISTENER_MOUSE, /// XMouseListener.mouseReleased + LISTENER_TEXT, /// XTextListener.textChanged + LISTENER_VALUE, /// XAdjustmentListener.adjustmentValueChanged + LISTENER_CHANGE /// XChangeListener.changed + }; + + explicit ScVbaControlObjectBase( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::frame::XModel >& rxModel, + const css::uno::Reference< css::container::XIndexContainer >& rxFormIC, + const css::uno::Reference< css::drawing::XControlShape >& rxControlShape, + ListenerType eListenerType ) throw (css::uno::RuntimeException); + + // XSheetObject 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 ::rtl::OUString SAL_CALL getOnAction() throw (css::uno::RuntimeException); + virtual void SAL_CALL setOnAction( const ::rtl::OUString& rMacroName ) throw (css::uno::RuntimeException); + virtual sal_Bool SAL_CALL getPrintObject() throw (css::uno::RuntimeException); + virtual void SAL_CALL setPrintObject( sal_Bool bPrintObject ) throw (css::uno::RuntimeException); + + // XControlObject attributes + virtual sal_Bool SAL_CALL getAutoSize() throw (css::uno::RuntimeException); + virtual void SAL_CALL setAutoSize( sal_Bool bAutoSize ) throw (css::uno::RuntimeException); + +protected: + sal_Int32 getModelIndexInForm() const throw (css::uno::RuntimeException); + +protected: + css::uno::Reference< css::container::XIndexContainer > mxFormIC; + css::uno::Reference< css::beans::XPropertySet > mxControlProps; + ::rtl::OUString maListenerType; + ::rtl::OUString maEventMethod; +}; + +// ============================================================================ + +typedef ::cppu::ImplInheritanceHelper1< ScVbaControlObjectBase, ov::excel::XButton > ScVbaButton_BASE; + +class ScVbaButton : public ScVbaButton_BASE +{ +public: + explicit ScVbaButton( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::frame::XModel >& rxModel, + const css::uno::Reference< css::container::XIndexContainer >& rxFormIC, + const css::uno::Reference< css::drawing::XControlShape >& rxControlShape ) throw (css::uno::RuntimeException); + + // XButton attributes + virtual ::rtl::OUString SAL_CALL getCaption() throw (css::uno::RuntimeException); + virtual void SAL_CALL setCaption( const ::rtl::OUString& rCaption ) throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XFont > SAL_CALL getFont() throw (css::uno::RuntimeException); + virtual void SAL_CALL setFont( const css::uno::Reference< ov::excel::XFont >& rxFont ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getHorizontalAlignment() throw (css::uno::RuntimeException); + virtual void SAL_CALL setHorizontalAlignment( sal_Int32 nAlign ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getVerticalAlignment() throw (css::uno::RuntimeException); + virtual void SAL_CALL setVerticalAlignment( sal_Int32 nAlign ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getOrientation() throw (css::uno::RuntimeException); + virtual void SAL_CALL setOrientation( sal_Int32 nOrientation ) throw (css::uno::RuntimeException); + + // XButton methods + css::uno::Reference< ov::excel::XCharacters > SAL_CALL Characters( + const css::uno::Any& rStart, const css::uno::Any& rLength ) throw (css::uno::RuntimeException); + + // XHelperInterface + VBAHELPER_DECL_XHELPERINTERFACE + +protected: + virtual ::rtl::OUString implGetBaseName() const; + virtual void implSetDefaultProperties() throw (css::uno::RuntimeException); +}; + +// ============================================================================ + +#endif diff --git a/sc/source/ui/vba/vbasheetobjects.cxx b/sc/source/ui/vba/vbasheetobjects.cxx new file mode 100755 index 000000000000..ced94db5ba76 --- /dev/null +++ b/sc/source/ui/vba/vbasheetobjects.cxx @@ -0,0 +1,534 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "vbasheetobjects.hxx" +#include <vector> +#include <rtl/math.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/drawing/XControlShape.hpp> +#include <com/sun/star/drawing/XDrawPageSupplier.hpp> +#include <com/sun/star/drawing/XShapes.hpp> +#include <com/sun/star/form/FormComponentType.hpp> +#include <com/sun/star/form/XForm.hpp> +#include <com/sun/star/form/XFormComponent.hpp> +#include <com/sun/star/form/XFormsSupplier.hpp> +#include <oox/helper/helper.hxx> +#include "vbasheetobject.hxx" + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::ooo::vba; + +// ============================================================================ + +namespace { + +template< typename Type > +inline bool lclGetProperty( Type& orValue, const uno::Reference< beans::XPropertySet >& rxPropSet, const OUString& rPropName ) +{ + try + { + return rxPropSet->getPropertyValue( rPropName ) >>= orValue; + } + catch( uno::Exception& ) + { + } + return false; +} + +/** Rounds the passed value to a multiple of 0.75 and converts it to 1/100 mm. */ +inline double lclPointsToHmm( const uno::Any& rPoints ) throw (uno::RuntimeException) +{ + return PointsToHmm( ::rtl::math::approxFloor( rPoints.get< double >() / 0.75 ) * 0.75 ); +} + +} // namespace + +// ============================================================================ +// Base implementations +// ============================================================================ + +/** Container for a specific type of drawing object in a spreadsheet. + + Derived classes provide all required functionality specific to the type of + shapes covered by the container. + */ +class ScVbaObjectContainer : public ::cppu::WeakImplHelper1< container::XIndexAccess > +{ +public: + explicit ScVbaObjectContainer( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet, + const uno::Type& rVbaType ) throw (uno::RuntimeException); + + /** Returns the VBA helper interface of the VBA collection object. */ + inline const uno::Reference< XHelperInterface >& getParent() const { return mxParent; } + /** Returns the component context of the VBA collection object. */ + inline const uno::Reference< uno::XComponentContext >& getContext() const { return mxContext; } + /** Returns the VBA type information of the objects in this container. */ + inline const uno::Type& getVbaType() const { return maVbaType; } + + /** Collects all shapes supported by this instance and inserts them into + the internal shape vector. */ + void collectShapes() throw (uno::RuntimeException); + /** Creates and returns a new UNO shape. */ + uno::Reference< drawing::XShape > createShape( const awt::Point& rPos, const awt::Size& rSize ) throw (uno::RuntimeException); + /** Inserts the passed shape into the draw page and into this container, and returns its index in the draw page. */ + sal_Int32 insertShape( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException); + /** Creates and returns a new VBA implementation object for the passed shape. */ + ::rtl::Reference< ScVbaSheetObjectBase > createVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException); + /** Creates and returns a new VBA implementation object for the passed shape in an Any. */ + uno::Any createCollectionObject( const uno::Any& rSource ) throw (uno::RuntimeException); + /** Returns the VBA implementation object with the specified name. */ + uno::Any getItemByStringIndex( const OUString& rIndex ) throw (uno::RuntimeException); + + // XIndexAccess + virtual sal_Int32 SAL_CALL getCount() throw (uno::RuntimeException); + virtual uno::Any SAL_CALL getByIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException); + + // XElementAccess + virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException); + virtual sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException); + +protected: + /** Derived classes return true, if the passed shape is supported by the instance. */ + virtual bool implPickShape( const uno::Reference< drawing::XShape >& rxShape ) const = 0; + /** Derived classes create and return a new VBA implementation object for the passed shape. */ + virtual ScVbaSheetObjectBase* implCreateVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) = 0; + /** Derived classes return the service name of the UNO shape. */ + virtual OUString implGetShapeServiceName() const = 0; + + /** Returns the shape name via 'Name' property of the UNO shape. May be overwritten. */ + virtual OUString implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException); + /** Is called when a new UNO shape has been created but not yet inserted into the drawing page. */ + virtual void implOnShapeCreated( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException); + /** Is called when a new UNO shape has been inserted into the drawing page. */ + virtual void implOnShapeInserted( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException); + +protected: + uno::Reference< XHelperInterface > mxParent; + uno::Reference< uno::XComponentContext > mxContext; + uno::Reference< frame::XModel > mxModel; + uno::Reference< lang::XMultiServiceFactory > mxFactory; + uno::Reference< drawing::XShapes > mxShapes; + +private: + typedef ::std::vector< uno::Reference< drawing::XShape > > ShapeVector; + const uno::Type maVbaType; + ShapeVector maShapes; +}; + +// ---------------------------------------------------------------------------- + +ScVbaObjectContainer::ScVbaObjectContainer( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet, + const uno::Type& rVbaType ) throw (uno::RuntimeException) : + mxParent( rxParent ), + mxContext( rxContext ), + mxModel( rxModel, uno::UNO_SET_THROW ), + mxFactory( rxModel, uno::UNO_QUERY_THROW ), + maVbaType( rVbaType ) +{ + uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupp( rxSheet, uno::UNO_QUERY_THROW ); + mxShapes.set( xDrawPageSupp->getDrawPage(), uno::UNO_QUERY_THROW ); +} + +void ScVbaObjectContainer::collectShapes() throw (uno::RuntimeException) +{ + maShapes.clear(); + for( sal_Int32 nIndex = 0, nCount = mxShapes->getCount(); nIndex < nCount; ++nIndex ) + { + uno::Reference< drawing::XShape > xShape( mxShapes->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + if( implPickShape( xShape ) ) + maShapes.push_back( xShape ); + } +} + +uno::Reference< drawing::XShape > ScVbaObjectContainer::createShape( const awt::Point& rPos, const awt::Size& rSize ) throw (uno::RuntimeException) +{ + uno::Reference< drawing::XShape > xShape( mxFactory->createInstance( implGetShapeServiceName() ), uno::UNO_QUERY_THROW ); + xShape->setPosition( rPos ); + xShape->setSize( rSize ); + implOnShapeCreated( xShape ); + return xShape; +} + +sal_Int32 ScVbaObjectContainer::insertShape( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) +{ + mxShapes->add( rxShape ); + maShapes.push_back( rxShape ); + implOnShapeInserted( rxShape ); + return mxShapes->getCount() - 1; +} + +::rtl::Reference< ScVbaSheetObjectBase > ScVbaObjectContainer::createVbaObject( + const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) +{ + return implCreateVbaObject( rxShape ); +} + +uno::Any ScVbaObjectContainer::createCollectionObject( const uno::Any& rSource ) throw (uno::RuntimeException) +{ + uno::Reference< drawing::XShape > xShape( rSource, uno::UNO_QUERY_THROW ); + uno::Reference< excel::XSheetObject > xSheetObject( implCreateVbaObject( xShape ) ); + return uno::Any( xSheetObject ); +} + +uno::Any ScVbaObjectContainer::getItemByStringIndex( const OUString& rIndex ) throw (uno::RuntimeException) +{ + for( ShapeVector::iterator aIt = maShapes.begin(), aEnd = maShapes.end(); aIt != aEnd; ++aIt ) + if( rIndex == implGetShapeName( *aIt ) ) + return createCollectionObject( uno::Any( *aIt ) ); + throw uno::RuntimeException(); +} + +// XIndexAccess + +sal_Int32 SAL_CALL ScVbaObjectContainer::getCount() throw (uno::RuntimeException) +{ + return static_cast< sal_Int32 >( maShapes.size() ); +} + +uno::Any SAL_CALL ScVbaObjectContainer::getByIndex( sal_Int32 nIndex ) + throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException) +{ + if( (0 <= nIndex) && (nIndex < getCount()) ) + return uno::Any( maShapes[ static_cast< size_t >( nIndex ) ] ); + throw lang::IndexOutOfBoundsException(); +} + +// XElementAccess + +uno::Type SAL_CALL ScVbaObjectContainer::getElementType() throw (uno::RuntimeException) +{ + return drawing::XShape::static_type( 0 ); +} + +sal_Bool SAL_CALL ScVbaObjectContainer::hasElements() throw (uno::RuntimeException) +{ + return !maShapes.empty(); +} + +// private + +OUString ScVbaObjectContainer::implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException) +{ + uno::Reference< beans::XPropertySet > xPropSet( rxShape, uno::UNO_QUERY_THROW ); + return xPropSet->getPropertyValue( CREATE_OUSTRING( "Name" ) ).get< OUString >(); +} + +void ScVbaObjectContainer::implOnShapeCreated( const uno::Reference< drawing::XShape >& /*rxShape*/ ) throw (uno::RuntimeException) +{ +} + +void ScVbaObjectContainer::implOnShapeInserted( const uno::Reference< drawing::XShape >& /*rxShape*/ ) throw (uno::RuntimeException) +{ +} + +// ============================================================================ + +class ScVbaObjectEnumeration : public SimpleEnumerationBase +{ +public: + explicit ScVbaObjectEnumeration( const ScVbaObjectContainerRef& rxContainer ); + virtual uno::Any createCollectionObject( const uno::Any& rSource ); + +private: + ScVbaObjectContainerRef mxContainer; +}; + +// ---------------------------------------------------------------------------- + +ScVbaObjectEnumeration::ScVbaObjectEnumeration( const ScVbaObjectContainerRef& rxContainer ) : + SimpleEnumerationBase( rxContainer->getParent(), rxContainer->getContext(), rxContainer.get() ), + mxContainer( rxContainer ) +{ +} + +uno::Any ScVbaObjectEnumeration::createCollectionObject( const uno::Any& rSource ) +{ + return mxContainer->createCollectionObject( rSource ); +} + +// ============================================================================ + +ScVbaSheetObjectsBase::ScVbaSheetObjectsBase( const ScVbaObjectContainerRef& rxContainer ) throw (css::uno::RuntimeException) : + ScVbaSheetObjects_BASE( rxContainer->getParent(), rxContainer->getContext(), rxContainer.get() ), + mxContainer( rxContainer ) +{ + mxContainer->collectShapes(); +} + +ScVbaSheetObjectsBase::~ScVbaSheetObjectsBase() +{ +} + +void ScVbaSheetObjectsBase::collectShapes() throw (uno::RuntimeException) +{ + mxContainer->collectShapes(); +} + +// XEnumerationAccess + +uno::Reference< container::XEnumeration > SAL_CALL ScVbaSheetObjectsBase::createEnumeration() throw (uno::RuntimeException) +{ + return new ScVbaObjectEnumeration( mxContainer ); +} + +// XElementAccess + +uno::Type SAL_CALL ScVbaSheetObjectsBase::getElementType() throw (uno::RuntimeException) +{ + return mxContainer->getVbaType(); +} + +// ScVbaCollectionBase + +uno::Any ScVbaSheetObjectsBase::createCollectionObject( const uno::Any& rSource ) +{ + return mxContainer->createCollectionObject( rSource ); +} + +uno::Any ScVbaSheetObjectsBase::getItemByStringIndex( const OUString& rIndex ) throw (uno::RuntimeException) +{ + return mxContainer->getItemByStringIndex( rIndex ); +} + +// ============================================================================ +// Graphic object containers supporting ooo.vba.excel.XGraphicObject +// ============================================================================ + +ScVbaGraphicObjectsBase::ScVbaGraphicObjectsBase( const ScVbaObjectContainerRef& rxContainer ) throw (uno::RuntimeException) : + ScVbaGraphicObjects_BASE( rxContainer ) +{ +} + +// XGraphicObjects + +uno::Any SAL_CALL ScVbaGraphicObjectsBase::Add( const uno::Any& rLeft, const uno::Any& rTop, const uno::Any& rWidth, const uno::Any& rHeight ) throw (uno::RuntimeException) +{ + /* Extract double values from passed Anys (the lclPointsToHmm() helper + function will throw a RuntimeException on any error), and convert from + points to 1/100 mm. */ + awt::Point aPos( lclPointsToHmm( rLeft ), lclPointsToHmm( rTop ) ); + awt::Size aSize( lclPointsToHmm( rWidth ), lclPointsToHmm( rHeight ) ); + // TODO: translate coordinates for RTL sheets + if( (aPos.X < 0) || (aPos.Y < 0) || (aSize.Width <= 0) || (aSize.Height <= 0) ) + throw uno::RuntimeException(); + + // create the UNO shape + uno::Reference< drawing::XShape > xShape( mxContainer->createShape( aPos, aSize ), uno::UNO_SET_THROW ); + sal_Int32 nIndex = mxContainer->insertShape( xShape ); + + // create and return the VBA object + ::rtl::Reference< ScVbaSheetObjectBase > xVbaObject = mxContainer->createVbaObject( xShape ); + xVbaObject->setDefaultProperties( nIndex ); + return uno::Any( uno::Reference< excel::XSheetObject >( xVbaObject.get() ) ); +} + +// ============================================================================ +// Drawing controls +// ============================================================================ + +class ScVbaControlContainer : public ScVbaObjectContainer +{ +public: + explicit ScVbaControlContainer( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet, + const uno::Type& rVbaType, + const OUString& rModelServiceName, + sal_Int16 nComponentType ) throw (uno::RuntimeException); + +protected: + uno::Reference< container::XIndexContainer > createForm() throw (uno::RuntimeException); + + virtual bool implPickShape( const uno::Reference< drawing::XShape >& rxShape ) const; + virtual OUString implGetShapeServiceName() const; + virtual bool implCheckProperties( const uno::Reference< beans::XPropertySet >& rxModelProps ) const; + virtual OUString implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException); + virtual void implOnShapeCreated( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException); + +protected: + uno::Reference< container::XIndexContainer > mxFormIC; + OUString maModelServiceName; + sal_Int16 mnComponentType; +}; + +// ---------------------------------------------------------------------------- + +ScVbaControlContainer::ScVbaControlContainer( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet, + const uno::Type& rVbaType, + const OUString& rModelServiceName, + sal_Int16 nComponentType ) throw (uno::RuntimeException) : + ScVbaObjectContainer( rxParent, rxContext, rxModel, rxSheet, rVbaType ), + maModelServiceName( rModelServiceName ), + mnComponentType( nComponentType ) +{ +} + +uno::Reference< container::XIndexContainer > ScVbaControlContainer::createForm() throw (uno::RuntimeException) +{ + if( !mxFormIC.is() ) + { + uno::Reference< form::XFormsSupplier > xFormsSupp( mxShapes, uno::UNO_QUERY_THROW ); + uno::Reference< container::XNameContainer > xFormsNC( xFormsSupp->getForms(), uno::UNO_SET_THROW ); + OUString aFormName = CREATE_OUSTRING( "Standard" ); + if( xFormsNC->hasByName( aFormName ) ) + { + mxFormIC.set( xFormsNC->getByName( aFormName ), uno::UNO_QUERY_THROW ); + } + else + { + uno::Reference< form::XForm > xForm( mxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.form.component.Form" ) ), uno::UNO_QUERY_THROW ); + xFormsNC->insertByName( aFormName, uno::Any( xForm ) ); + mxFormIC.set( xForm, uno::UNO_QUERY_THROW ); + } + } + return mxFormIC; +} + +bool ScVbaControlContainer::implPickShape( const uno::Reference< drawing::XShape >& rxShape ) const +{ + try + { + uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xModelProps( xControlShape->getControl(), uno::UNO_QUERY_THROW ); + sal_Int16 nClassId = -1; + return lclGetProperty( nClassId, xModelProps, CREATE_OUSTRING( "ClassId" ) ) && + (nClassId == mnComponentType) && implCheckProperties( xModelProps ); + } + catch( uno::Exception& ) + { + } + return false; +} + +OUString ScVbaControlContainer::implGetShapeServiceName() const +{ + return CREATE_OUSTRING( "com.sun.star.drawing.ControlShape" ); +} + +bool ScVbaControlContainer::implCheckProperties( const uno::Reference< beans::XPropertySet >& /*rxModelProps*/ ) const +{ + return true; +} + +OUString ScVbaControlContainer::implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException) +{ + uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW ); + return uno::Reference< container::XNamed >( xControlShape->getControl(), uno::UNO_QUERY_THROW )->getName(); +} + +void ScVbaControlContainer::implOnShapeCreated( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) +{ + // passed shape must be a control shape + uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW ); + + // create the UNO control model + uno::Reference< form::XFormComponent > xFormComponent( mxFactory->createInstance( maModelServiceName ), uno::UNO_QUERY_THROW ); + uno::Reference< awt::XControlModel > xControlModel( xFormComponent, uno::UNO_QUERY_THROW ); + + // insert the control model into the form and the shape + createForm(); + mxFormIC->insertByIndex( mxFormIC->getCount(), uno::Any( xFormComponent ) ); + xControlShape->setControl( xControlModel ); +} + +// ============================================================================ +// Push button +// ============================================================================ + +class ScVbaButtonContainer : public ScVbaControlContainer +{ +public: + explicit ScVbaButtonContainer( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet ) throw (uno::RuntimeException); + +protected: + virtual ScVbaSheetObjectBase* implCreateVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException); + virtual bool implCheckProperties( const uno::Reference< beans::XPropertySet >& rxModelProps ) const; +}; + +// ---------------------------------------------------------------------------- + +ScVbaButtonContainer::ScVbaButtonContainer( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet ) throw (uno::RuntimeException) : + ScVbaControlContainer( + rxParent, rxContext, rxModel, rxSheet, + excel::XButton::static_type( 0 ), + CREATE_OUSTRING( "com.sun.star.form.component.CommandButton" ), + form::FormComponentType::COMMANDBUTTON ) +{ +} + +ScVbaSheetObjectBase* ScVbaButtonContainer::implCreateVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) +{ + uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW ); + return new ScVbaButton( mxParent, mxContext, mxModel, createForm(), xControlShape ); +} + +bool ScVbaButtonContainer::implCheckProperties( const uno::Reference< beans::XPropertySet >& rxModelProps ) const +{ + // do not insert toggle buttons into the 'Buttons' collection + bool bToggle = false; + return lclGetProperty( bToggle, rxModelProps, CREATE_OUSTRING( "Toggle" ) ) && !bToggle; +} + +// ============================================================================ + +ScVbaButtons::ScVbaButtons( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet ) throw (uno::RuntimeException) : + ScVbaGraphicObjectsBase( new ScVbaButtonContainer( rxParent, rxContext, rxModel, rxSheet ) ) +{ +} + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButtons, "ooo.vba.excel.Buttons" ) + +// ============================================================================ diff --git a/sc/source/ui/vba/vbasheetobjects.hxx b/sc/source/ui/vba/vbasheetobjects.hxx new file mode 100755 index 000000000000..fd69d4927a20 --- /dev/null +++ b/sc/source/ui/vba/vbasheetobjects.hxx @@ -0,0 +1,113 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_VBA_SHEETOBJECTS_HXX +#define SC_VBA_SHEETOBJECTS_HXX + +#include <ooo/vba/excel/XGraphicObjects.hpp> +#include <vbahelper/vbacollectionimpl.hxx> +#include <rtl/ref.hxx> + +namespace com { namespace sun { namespace star { + namespace container { class XEnumeration; } + namespace frame { class XModel; } + namespace sheet { class XSpreadsheet; } +} } } + +// ============================================================================ + +class ScVbaObjectContainer; +typedef ::rtl::Reference< ScVbaObjectContainer > ScVbaObjectContainerRef; + +// ============================================================================ + +typedef CollTestImplHelper< ov::XCollection > ScVbaSheetObjects_BASE; + +/** Base class for collections containing a specific type of drawing object + embedded in a sheet (worksheet, chart sheet, or dialog sheet). + */ +class ScVbaSheetObjectsBase : public ScVbaSheetObjects_BASE +{ +public: + explicit ScVbaSheetObjectsBase( const ScVbaObjectContainerRef& rxContainer ) throw (css::uno::RuntimeException); + virtual ~ScVbaSheetObjectsBase(); + + /** Updates the collection by fetching all shapes from the draw page. */ + void collectShapes() throw (css::uno::RuntimeException); + + // XEnumerationAccess + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException); + + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException); + + // ScVbaCollectionBase + virtual css::uno::Any createCollectionObject( const css::uno::Any& rSource ); + virtual css::uno::Any getItemByStringIndex( const ::rtl::OUString& rIndex ) throw (css::uno::RuntimeException); + +protected: + ScVbaObjectContainerRef mxContainer; +}; + +// ============================================================================ + +typedef ::cppu::ImplInheritanceHelper1< ScVbaSheetObjectsBase, ov::excel::XGraphicObjects > ScVbaGraphicObjects_BASE; + +/** Base class for collections containing a specific type of graphic object + from a sheet. + */ +class ScVbaGraphicObjectsBase : public ScVbaGraphicObjects_BASE +{ +public: + explicit ScVbaGraphicObjectsBase( const ScVbaObjectContainerRef& rxContainer ) throw (css::uno::RuntimeException); + + // XGraphicObjects + virtual css::uno::Any SAL_CALL Add( + const css::uno::Any& rLeft, + const css::uno::Any& rTop, + const css::uno::Any& rWidth, + const css::uno::Any& rHeight ) throw (css::uno::RuntimeException); +}; + +// ============================================================================ + +/** Collection containing all button controls from a sheet (not ActiveX controls). */ +class ScVbaButtons : public ScVbaGraphicObjectsBase +{ +public: + explicit ScVbaButtons( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::frame::XModel >& rxModel, + const css::uno::Reference< css::sheet::XSpreadsheet >& rxSheet ) throw (css::uno::RuntimeException); + + VBAHELPER_DECL_XHELPERINTERFACE +}; + +// ============================================================================ + +#endif diff --git a/sc/source/ui/vba/vbawindow.cxx b/sc/source/ui/vba/vbawindow.cxx index f0aafe83908b..10dad39341b7 100644 --- a/sc/source/ui/vba/vbawindow.cxx +++ b/sc/source/ui/vba/vbawindow.cxx @@ -55,9 +55,6 @@ using namespace ::com::sun::star; using namespace ::ooo::vba; using namespace ::ooo::vba::excel::XlWindowState; -// nameExists defined in vbaworksheet.cxx -bool nameExists( uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc, ::rtl::OUString & name, SCTAB& nTab ) throw ( lang::IllegalArgumentException ); - typedef std::hash_map< rtl::OUString, SCTAB, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > NameIndexHash; @@ -213,18 +210,25 @@ ScVbaWindow::ScVbaWindow( uno::Sequence< uno::Any > const & args, uno::Reference { init(); } + void ScVbaWindow::init() { + /* This method is called from the constructor, thus the own refcount is + still zero. The implementation of ActivePane() uses a UNO reference of + this (to set this window as parent of the pane obejct). This requires + the own refcount to be non-zero, otherwise this instance will be + desctructed immediately! */ + osl_incrementInterlockedCount( &m_refCount ); uno::Reference< frame::XController > xController( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); m_xViewPane.set( xController, uno::UNO_QUERY_THROW ); m_xViewFreezable.set( xController, uno::UNO_QUERY_THROW ); m_xViewSplitable.set( xController, uno::UNO_QUERY_THROW ); m_xPane.set( ActivePane(), uno::UNO_QUERY_THROW ); m_xDevice.set( xController->getFrame()->getComponentWindow(), uno::UNO_QUERY_THROW ); + osl_decrementInterlockedCount( &m_refCount ); } - void ScVbaWindow::Scroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft, bool bLargeScroll ) throw (uno::RuntimeException) { @@ -233,11 +237,13 @@ ScVbaWindow::Scroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& T else m_xPane->SmallScroll( Down, Up, ToRight, ToLeft ); } + void SAL_CALL ScVbaWindow::SmallScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft ) throw (uno::RuntimeException) { Scroll( Down, Up, ToRight, ToLeft ); } + void SAL_CALL ScVbaWindow::LargeScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft ) throw (uno::RuntimeException) { @@ -450,7 +456,7 @@ ScVbaWindow::Close( const uno::Any& SaveChanges, const uno::Any& FileName, const uno::Reference< excel::XPane > SAL_CALL ScVbaWindow::ActivePane() throw (script::BasicErrorException, uno::RuntimeException) { - return new ScVbaPane( mxContext, m_xViewPane ); + return new ScVbaPane( this, mxContext, m_xModel, m_xViewPane ); } uno::Reference< excel::XRange > SAL_CALL @@ -467,6 +473,14 @@ ScVbaWindow::Selection( ) throw (script::BasicErrorException, uno::RuntimeExcep return xApplication->getSelection(); } +uno::Reference< excel::XRange > SAL_CALL +ScVbaWindow::RangeSelection() throw (script::BasicErrorException, uno::RuntimeException) +{ + /* TODO / FIXME: According to documentation, this method returns the range + selection even if shapes are selected. */ + return uno::Reference< excel::XRange >( Selection(), uno::UNO_QUERY_THROW ); +} + ::sal_Bool SAL_CALL ScVbaWindow::getDisplayGridlines() throw (uno::RuntimeException) { @@ -732,9 +746,7 @@ ScVbaWindow::setZoom( const uno::Any& _zoom ) throw (uno::RuntimeException) uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( m_xModel, uno::UNO_QUERY_THROW ); uno::Reference< excel::XWorksheet > xActiveSheet = ActiveSheet(); SCTAB nTab = 0; - rtl::OUString sName = xActiveSheet->getName(); - bool bSheetExists = nameExists (xSpreadDoc, sName, nTab); - if ( !bSheetExists ) + if ( !ScVbaWorksheets::nameExists (xSpreadDoc, xActiveSheet->getName(), nTab) ) throw uno::RuntimeException(); std::vector< SCTAB > vTabs; vTabs.push_back( nTab ); @@ -778,6 +790,15 @@ ScVbaWindow::setView( const uno::Any& _view) throw (uno::RuntimeException) dispatchExecute( pViewShell, nSlot ); } +uno::Reference< excel::XRange > SAL_CALL +ScVbaWindow::getVisibleRange() throw (uno::RuntimeException) +{ + uno::Reference< container::XIndexAccess > xPanesIA( m_xViewPane, uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XViewPane > xTopLeftPane( xPanesIA->getByIndex( 0 ), uno::UNO_QUERY_THROW ); + uno::Reference< excel::XPane > xPane( new ScVbaPane( this, mxContext, m_xModel, xTopLeftPane ) ); + return xPane->getVisibleRange(); +} + sal_Int32 SAL_CALL ScVbaWindow::PointsToScreenPixelsX(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException) { diff --git a/sc/source/ui/vba/vbawindow.hxx b/sc/source/ui/vba/vbawindow.hxx index e72401a2baac..d58d2a07cb4b 100644 --- a/sc/source/ui/vba/vbawindow.hxx +++ b/sc/source/ui/vba/vbawindow.hxx @@ -26,6 +26,7 @@ ************************************************************************/ #ifndef SC_VBA_WINDOW_HXX #define SC_VBA_WINDOW_HXX + #include <cppuhelper/implbase1.hxx> #include <ooo/vba/excel/XWindow.hpp> #include <com/sun/star/uno/XComponentContext.hpp> @@ -40,7 +41,6 @@ #include <vbahelper/vbawindowbase.hxx> #include "vbaworkbook.hxx" -//typedef InheritedHelperInterfaceImpl1<ov::excel::XWindow > WindowImpl_BASE; typedef cppu::ImplInheritanceHelper1< VbaWindowBase, ov::excel::XWindow > WindowImpl_BASE; class ScVbaWindow : public WindowImpl_BASE @@ -96,6 +96,7 @@ public: virtual void SAL_CALL setScrollColumn( const css::uno::Any& _scrollcolumn ) throw (css::uno::RuntimeException) ; virtual css::uno::Any SAL_CALL getView() throw (css::uno::RuntimeException); virtual void SAL_CALL setView( const css::uno::Any& _view ) throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getVisibleRange() throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL getWindowState() throw (css::uno::RuntimeException); virtual void SAL_CALL setWindowState( const css::uno::Any& _windowstate ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL getZoom() throw (css::uno::RuntimeException); @@ -108,11 +109,12 @@ public: virtual void SAL_CALL ScrollWorkbookTabs( const css::uno::Any& Sheets, const css::uno::Any& Position ) throw (css::uno::RuntimeException); virtual void SAL_CALL Activate( ) throw (css::uno::RuntimeException); virtual void SAL_CALL Close( const css::uno::Any& SaveChanges, const css::uno::Any& FileName, const css::uno::Any& RouteWorkBook ) throw (css::uno::RuntimeException); - virtual css::uno::Any SAL_CALL Selection( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); - virtual sal_Int32 SAL_CALL PointsToScreenPixelsX(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException); - virtual sal_Int32 SAL_CALL PointsToScreenPixelsY(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException); - virtual void SAL_CALL PrintOut( const css::uno::Any& From, const css::uno::Any&To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName ) throw (css::script::BasicErrorException, css::uno::RuntimeException); - virtual void SAL_CALL PrintPreview( const css::uno::Any& EnableChanges ) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Selection( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XRange > SAL_CALL RangeSelection() throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL PointsToScreenPixelsX(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL PointsToScreenPixelsY(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual void SAL_CALL PrintOut( const css::uno::Any& From, const css::uno::Any&To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName ) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual void SAL_CALL PrintPreview( const css::uno::Any& EnableChanges ) throw (css::script::BasicErrorException, css::uno::RuntimeException); // XHelperInterface virtual rtl::OUString& getServiceImplName(); virtual css::uno::Sequence<rtl::OUString> getServiceNames(); diff --git a/sc/source/ui/vba/vbaworkbook.cxx b/sc/source/ui/vba/vbaworkbook.cxx index 6694f4e5e135..365c8b35a00c 100644 --- a/sc/source/ui/vba/vbaworkbook.cxx +++ b/sc/source/ui/vba/vbaworkbook.cxx @@ -345,32 +345,8 @@ ScVbaWorkbook::getServiceNames() ::rtl::OUString SAL_CALL ScVbaWorkbook::getCodeName() throw (css::uno::RuntimeException) { -#ifdef VBA_OOBUILD_HACK - uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); - ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument(); - ScExtDocOptions* pExtOptions = pDoc->GetExtDocOptions(); - ScExtDocSettings pExtSettings = pExtOptions->GetDocSettings(); - ::rtl::OUString sGlobCodeName = pExtSettings.maGlobCodeName; - return sGlobCodeName; -#else - throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() ); -#endif -} -#ifdef VBA_OOBUILD_HACK -void SAL_CALL -ScVbaWorkbook::setCodeName( const ::rtl::OUString& sGlobCodeName ) throw (css::uno::RuntimeException) -{ - uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); - ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument(); - ScExtDocOptions* pExtOptions = pDoc->GetExtDocOptions(); - ScExtDocSettings pExtSettings = pExtOptions->GetDocSettings(); - pExtSettings.maGlobCodeName = sGlobCodeName; -#else -void SAL_CALL -ScVbaWorkbook::setCodeName( const ::rtl::OUString& ) throw (css::uno::RuntimeException) -{ - throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() ); -#endif + uno::Reference< beans::XPropertySet > xModelProp( getModel(), uno::UNO_QUERY_THROW ); + return xModelProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CodeName" ) ) ).get< ::rtl::OUString >(); } namespace workbook diff --git a/sc/source/ui/vba/vbaworkbook.hxx b/sc/source/ui/vba/vbaworkbook.hxx index 40234aca21d7..4aff58078403 100644 --- a/sc/source/ui/vba/vbaworkbook.hxx +++ b/sc/source/ui/vba/vbaworkbook.hxx @@ -71,7 +71,6 @@ public: virtual void SAL_CALL SaveCopyAs( const rtl::OUString& Filename ) throw ( css::uno::RuntimeException); // code name virtual ::rtl::OUString SAL_CALL getCodeName() throw ( css::uno::RuntimeException); - virtual void SAL_CALL setCodeName( const ::rtl::OUString& sGlobCodeName ) throw (css::uno::RuntimeException); // XHelperInterface virtual rtl::OUString& getServiceImplName(); diff --git a/sc/source/ui/vba/vbaworksheet.cxx b/sc/source/ui/vba/vbaworksheet.cxx index be988509aa68..5b1963e3d242 100644 --- a/sc/source/ui/vba/vbaworksheet.cxx +++ b/sc/source/ui/vba/vbaworksheet.cxx @@ -24,9 +24,12 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ + #include <vbahelper/helperdecl.hxx> #include <cppuhelper/queryinterface.hxx> +#include "vbaworksheet.hxx" + #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/beans/XIntrospectionAccess.hpp> #include <com/sun/star/beans/XIntrospection.hpp> @@ -60,14 +63,15 @@ #include <ooo/vba/XControlProvider.hpp> #include <comphelper/processfactory.hxx> +#include <vbahelper/vbashapes.hxx> #include <tools/string.hxx> //zhangyun showdataform #include <sfx2/sfxdlg.hxx> -#include <scabstdlg.hxx> -#include <tabvwsh.hxx> -#include <scitems.hxx> +#include "scabstdlg.hxx" +#include "tabvwsh.hxx" +#include "scitems.hxx" #include <svx/svdouno.hxx> #include <svx/svdpage.hxx> @@ -79,43 +83,22 @@ #include "vbaoutline.hxx" #include "vbarange.hxx" #include "vbacomments.hxx" -#include "vbaworksheet.hxx" #include "vbachartobjects.hxx" #include "vbapivottables.hxx" #include "vbaoleobject.hxx" #include "vbaoleobjects.hxx" -#include <vbahelper/vbashapes.hxx> #include "vbapagesetup.hxx" #include "vbapagebreaks.hxx" +#include "vbaworksheets.hxx" +#include "vbahyperlinks.hxx" +#include "vbasheetobjects.hxx" #define STANDARDWIDTH 2267 #define STANDARDHEIGHT 427 #define DOESNOTEXIST -1 + using namespace com::sun::star; using namespace ooo::vba; -bool -nameExists( uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc, ::rtl::OUString & name, SCTAB& nTab ) throw ( lang::IllegalArgumentException ) -{ - if (!xSpreadDoc.is()) - throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nameExists() xSpreadDoc is null" ) ), uno::Reference< uno::XInterface >(), 1 ); - uno::Reference <sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets(); - uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY ); - if ( xIndex.is() ) - { - SCTAB nCount = static_cast< SCTAB >( xIndex->getCount() ); - for (SCTAB i=0; i < nCount; i++) - { - uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(i), uno::UNO_QUERY); - uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW ); - if (xNamed->getName() == name) - { - nTab = i; - return true; - } - } - } - return false; -} static void getNewSpreadsheetName (rtl::OUString &aNewName, rtl::OUString aOldName, uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc ) { @@ -125,7 +108,7 @@ static void getNewSpreadsheetName (rtl::OUString &aNewName, rtl::OUString aOldNa int currentNum =2; aNewName = aOldName + aUnderScre+ String::CreateFromInt32(currentNum) ; SCTAB nTab = 0; - while ( nameExists(xSpreadDoc,aNewName, nTab ) ) + while ( ScVbaWorksheets::nameExists(xSpreadDoc,aNewName, nTab ) ) { aNewName = aOldName + aUnderScre + String::CreateFromInt32(++currentNum) ; @@ -152,7 +135,8 @@ static void removeAllSheets( uno::Reference <sheet::XSpreadsheetDocument>& xSpre } } - uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(0), uno::UNO_QUERY); uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(0), uno::UNO_QUERY); + uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW ); if (xNamed.is()) { xNamed->setName(aSheetName); @@ -196,6 +180,7 @@ openNewDoc(rtl::OUString aSheetName ) 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, const uno::Reference< sheet::XSpreadsheet >& xSheet, const uno::Reference< frame::XModel >& xModel ) throw (uno::RuntimeException) : WorksheetImpl_BASE( xParent, xContext ), mxSheet( xSheet ), mxModel(xModel) @@ -216,6 +201,10 @@ ScVbaWorksheet::ScVbaWorksheet( uno::Sequence< uno::Any> const & args, mxSheet.set( xNameAccess->getByName( sSheetName ), uno::UNO_QUERY_THROW ); } +ScVbaWorksheet::~ScVbaWorksheet() +{ +} + ::rtl::OUString ScVbaWorksheet::getName() throw (uno::RuntimeException) { @@ -261,9 +250,7 @@ ScVbaWorksheet::getEnableSelection() throw (uno::RuntimeException) { uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW ); SCTAB nTab = 0; - rtl::OUString aSheetName = getName(); - bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nTab); - if ( bSheetExists ) + if ( ScVbaWorksheets::nameExists(xSpreadDoc, getName(), nTab) ) { uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument(); @@ -301,9 +288,7 @@ ScVbaWorksheet::setEnableSelection( sal_Int32 nSelection ) throw (uno::RuntimeEx uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW ); SCTAB nTab = 0; - rtl::OUString aSheetName = getName(); - bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nTab); - if ( bSheetExists ) + if ( ScVbaWorksheets::nameExists(xSpreadDoc, getName(), nTab) ) { uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument(); @@ -426,9 +411,8 @@ ScVbaWorksheet::Select() throw (uno::RuntimeException) void ScVbaWorksheet::Move( const uno::Any& Before, const uno::Any& After ) throw (uno::RuntimeException) { - rtl::OUString aSheetName; uno::Reference<excel::XWorksheet> xSheet; - rtl::OUString aCurrSheetName =getName(); + rtl::OUString aCurrSheetName = getName(); if (!(Before >>= xSheet) && !(After >>=xSheet)&& !(Before.hasValue()) && !(After.hasValue())) { @@ -451,9 +435,7 @@ ScVbaWorksheet::Move( const uno::Any& Before, const uno::Any& After ) throw (uno uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW ); SCTAB nDest = 0; - aSheetName = xSheet->getName(); - bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nDest); - if ( bSheetExists ) + if ( ScVbaWorksheets::nameExists (xSpreadDoc, xSheet->getName(), nDest) ) { sal_Bool bAfter = After.hasValue(); if (bAfter) @@ -466,7 +448,6 @@ ScVbaWorksheet::Move( const uno::Any& Before, const uno::Any& After ) throw (uno void ScVbaWorksheet::Copy( const uno::Any& Before, const uno::Any& After ) throw (uno::RuntimeException) { - rtl::OUString aSheetName; uno::Reference<excel::XWorksheet> xSheet; rtl::OUString aCurrSheetName =getName(); if (!(Before >>= xSheet) && !(After >>=xSheet)&& !(Before.hasValue()) && !(After.hasValue())) @@ -488,10 +469,8 @@ ScVbaWorksheet::Copy( const uno::Any& Before, const uno::Any& After ) throw (uno uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY ); SCTAB nDest = 0; - aSheetName = xSheet->getName(); - bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nDest ); - - if ( bSheetExists ) + rtl::OUString aSheetName = xSheet->getName(); + if ( ScVbaWorksheets::nameExists (xSpreadDoc, aSheetName, nDest ) ) { sal_Bool bAfter = After.hasValue(); if(bAfter) @@ -521,7 +500,7 @@ ScVbaWorksheet::Delete() throw (uno::RuntimeException) if ( xSpreadDoc.is() ) { SCTAB nTab = 0; - if (!nameExists(xSpreadDoc, aSheetName, nTab )) + if (!ScVbaWorksheets::nameExists(xSpreadDoc, aSheetName, nTab )) { return; } @@ -539,11 +518,8 @@ ScVbaWorksheet::getSheetAtOffset(SCTAB offset) throw (uno::RuntimeException) uno::Reference <sheet::XSpreadsheets> xSheets( xSpreadDoc->getSheets(), uno::UNO_QUERY_THROW ); uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY_THROW ); - rtl::OUString aName = getName(); SCTAB nIdx = 0; - bool bSheetExists = nameExists (xSpreadDoc, aName, nIdx ); - - if ( !bSheetExists ) + if ( !ScVbaWorksheets::nameExists (xSpreadDoc, getName(), nIdx ) ) return uno::Reference< excel::XWorksheet >(); nIdx = nIdx + offset; uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(nIdx), uno::UNO_QUERY_THROW); @@ -677,13 +653,25 @@ ScVbaWorksheet::Comments( const uno::Any& Index ) throw (uno::RuntimeException) uno::Reference< sheet::XSheetAnnotationsSupplier > xAnnosSupp( xSheet, uno::UNO_QUERY_THROW ); uno::Reference< sheet::XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), uno::UNO_QUERY_THROW ); uno::Reference< container::XIndexAccess > xIndexAccess( xAnnos, uno::UNO_QUERY_THROW ); - uno::Reference< XCollection > xColl( new ScVbaComments( this, mxContext, xIndexAccess ) ); + uno::Reference< XCollection > xColl( new ScVbaComments( this, mxContext, mxModel, xIndexAccess ) ); if ( Index.hasValue() ) return xColl->Item( Index, uno::Any() ); return uno::makeAny( xColl ); } uno::Any SAL_CALL +ScVbaWorksheet::Hyperlinks( const uno::Any& aIndex ) throw (uno::RuntimeException) +{ + /* The worksheet always returns the same Hyperlinks object. + See vbahyperlinks.hxx for more details. */ + if( !mxHlinks.is() ) + mxHlinks.set( new ScVbaHyperlinks( this, mxContext ) ); + if( aIndex.hasValue() ) + return uno::Reference< XCollection >( mxHlinks, uno::UNO_QUERY_THROW )->Item( aIndex, uno::Any() ); + return uno::Any( mxHlinks ); +} + +uno::Any SAL_CALL ScVbaWorksheet::OLEObjects( const uno::Any& Index ) throw (uno::RuntimeException) { ScVbaOLEObjects* aOleObjects; @@ -716,6 +704,66 @@ ScVbaWorksheet::Shapes( const uno::Any& aIndex ) throw (uno::RuntimeException) return uno::makeAny( xVbaShapes ); } +uno::Any SAL_CALL +ScVbaWorksheet::Buttons( const uno::Any& rIndex ) throw (uno::RuntimeException) +{ + if( !mxButtons.is() ) + mxButtons.set( new ScVbaButtons( this, mxContext, mxModel, mxSheet ) ); + else + mxButtons->collectShapes(); + if( rIndex.hasValue() ) + return mxButtons->Item( rIndex, uno::Any() ); + return uno::Any( uno::Reference< XCollection >( mxButtons.get() ) ); +} + +uno::Any SAL_CALL +ScVbaWorksheet::CheckBoxes( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::DropDowns( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::GroupBoxes( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::Labels( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::ListBoxes( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::OptionButtons( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::ScrollBars( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::Spinners( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + void SAL_CALL ScVbaWorksheet::ShowDataForm( ) throw (uno::RuntimeException) { @@ -882,52 +930,8 @@ ScVbaWorksheet::getServiceNames() rtl::OUString SAL_CALL ScVbaWorksheet::getCodeName() throw (css::uno::RuntimeException) { -#ifdef VBA_OOBUILD_HACK - uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW ); - SCTAB nTab = 0; - rtl::OUString aSheetName = getName(); - bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nTab); - if ( bSheetExists ) - { - uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); - ScDocument* pDoc = getDocShell( xModel )->GetDocument(); - ScExtDocOptions* pExtOptions = pDoc->GetExtDocOptions(); - rtl::OUString sCodeName = pExtOptions->GetCodeName( nTab ); - return sCodeName; - } - else - throw uno::RuntimeException(::rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( "Sheet Name does not exist. ") ), - uno::Reference< XInterface >() ); -#else - throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() ); -#endif -} -#ifdef VBA_OOBUILD_HACK -void SAL_CALL -ScVbaWorksheet::setCodeName( const rtl::OUString& sCodeName ) throw (css::uno::RuntimeException) -{ - uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW ); - SCTAB nTab = 0; - rtl::OUString aSheetName = getName(); - bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nTab); - if ( bSheetExists ) - { - uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); - ScDocument* pDoc = getDocShell( xModel )->GetDocument(); - ScExtDocOptions* pExtOptions = pDoc->GetExtDocOptions(); - pExtOptions->SetCodeName( sCodeName, nTab ); - } - else - throw uno::RuntimeException(::rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( "Sheet Name does not exist. ") ), - uno::Reference< XInterface >() ); -#else -void SAL_CALL -ScVbaWorksheet::setCodeName( const rtl::OUString& ) throw (css::uno::RuntimeException) -{ - throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() ); -#endif + uno::Reference< beans::XPropertySet > xSheetProp( mxSheet, uno::UNO_QUERY_THROW ); + return xSheetProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CodeName" ) ) ).get< ::rtl::OUString >(); } sal_Int16 diff --git a/sc/source/ui/vba/vbaworksheet.hxx b/sc/source/ui/vba/vbaworksheet.hxx index 5fe1343f9237..d07cc1a8d55c 100644 --- a/sc/source/ui/vba/vbaworksheet.hxx +++ b/sc/source/ui/vba/vbaworksheet.hxx @@ -42,11 +42,17 @@ #include <ooo/vba/excel/XPageSetup.hpp> #include <ooo/vba/excel/XHPageBreaks.hpp> #include <ooo/vba/excel/XVPageBreaks.hpp> -#include <ooo/vba/excel/XChartObjects.hpp> #include <vbahelper/vbahelperinterface.hxx> #include "address.hxx" +namespace ooo { namespace vba { namespace excel { + class XChartObjects; + class XHyperlinks; +} } } + +class ScVbaSheetObjectsBase; + typedef InheritedHelperInterfaceImpl1< ov::excel::XWorksheet > WorksheetImpl_BASE; class ScVbaWorksheet : public WorksheetImpl_BASE @@ -54,6 +60,8 @@ class ScVbaWorksheet : public WorksheetImpl_BASE css::uno::Reference< css::sheet::XSpreadsheet > mxSheet; css::uno::Reference< css::frame::XModel > mxModel; css::uno::Reference< ov::excel::XChartObjects > mxCharts; + css::uno::Reference< ov::excel::XHyperlinks > mxHlinks; + ::rtl::Reference< ScVbaSheetObjectsBase > mxButtons; css::uno::Reference< ov::excel::XWorksheet > getSheetAtOffset(SCTAB offset) throw (css::uno::RuntimeException); css::uno::Reference< ov::excel::XRange > getSheetRange() throw (css::uno::RuntimeException); @@ -70,7 +78,7 @@ public: const css::uno::Reference< css::frame::XModel >& xModel )throw (css::uno::RuntimeException) ; ScVbaWorksheet( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext ) throw ( css::lang::IllegalArgumentException ); - virtual ~ScVbaWorksheet() {} + virtual ~ScVbaWorksheet(); virtual css::uno::Reference< css::frame::XModel > getModel() { return mxModel; } @@ -120,9 +128,21 @@ public: virtual css::uno::Any SAL_CALL Evaluate( const ::rtl::OUString& Name ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL PivotTables( const css::uno::Any& Index ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Comments( const css::uno::Any& Index ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Hyperlinks( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL OLEObjects( const css::uno::Any& Index ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Shapes( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); + + virtual css::uno::Any SAL_CALL Buttons( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL CheckBoxes( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL DropDowns( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL GroupBoxes( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Labels( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL ListBoxes( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL OptionButtons( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL ScrollBars( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Spinners( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual void SAL_CALL setEnableCalculation( ::sal_Bool EnableCalculation ) throw ( css::script::BasicErrorException, css::uno::RuntimeException); virtual ::sal_Bool SAL_CALL getEnableCalculation( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); virtual void SAL_CALL ShowDataForm( ) throw (css::uno::RuntimeException); @@ -135,7 +155,6 @@ public: virtual ::sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName ) throw (css::uno::RuntimeException); // CodeName virtual rtl::OUString SAL_CALL getCodeName() throw (css::uno::RuntimeException); - virtual void SAL_CALL setCodeName( const rtl::OUString& sCodeName ) throw (css::uno::RuntimeException); sal_Int16 getSheetID() throw (css::uno::RuntimeException); virtual void SAL_CALL PrintOut( const css::uno::Any& From, const css::uno::Any& To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName, const css::uno::Any& IgnorePrintAreas ) throw (css::uno::RuntimeException); diff --git a/sc/source/ui/vba/vbaworksheets.cxx b/sc/source/ui/vba/vbaworksheets.cxx index e7de0b82fcaa..60cf7b904026 100644 --- a/sc/source/ui/vba/vbaworksheets.cxx +++ b/sc/source/ui/vba/vbaworksheets.cxx @@ -435,3 +435,24 @@ ScVbaWorksheets::getServiceNames() } return sNames; } + +/*static*/ bool ScVbaWorksheets::nameExists( uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc, const ::rtl::OUString & name, SCTAB& nTab ) throw ( lang::IllegalArgumentException ) +{ + if (!xSpreadDoc.is()) + throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nameExists() xSpreadDoc is null" ) ), uno::Reference< uno::XInterface >(), 1 ); + uno::Reference <container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY ); + if ( xIndex.is() ) + { + SCTAB nCount = static_cast< SCTAB >( xIndex->getCount() ); + for (SCTAB i=0; i < nCount; i++) + { + uno::Reference< container::XNamed > xNamed( xIndex->getByIndex(i), uno::UNO_QUERY_THROW ); + if (xNamed->getName() == name) + { + nTab = i; + return true; + } + } + } + return false; +} diff --git a/sc/source/ui/vba/vbaworksheets.hxx b/sc/source/ui/vba/vbaworksheets.hxx index 4c8120084b02..2ced68bc9e27 100644 --- a/sc/source/ui/vba/vbaworksheets.hxx +++ b/sc/source/ui/vba/vbaworksheets.hxx @@ -31,11 +31,14 @@ #include <ooo/vba/excel/XWorksheets.hpp> #include <com/sun/star/sheet/XSpreadsheets.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> #include <com/sun/star/container/XEnumerationAccess.hpp> #include <com/sun/star/uno/XComponentContext.hpp> #include <vbahelper/vbacollectionimpl.hxx> +#include "address.hxx" + class ScModelObj; @@ -74,6 +77,7 @@ public: virtual rtl::OUString& getServiceImplName(); virtual css::uno::Sequence<rtl::OUString> getServiceNames(); + static bool nameExists( css::uno::Reference <css::sheet::XSpreadsheetDocument>& xSpreadDoc, const ::rtl::OUString & name, SCTAB& nTab ) throw ( css::lang::IllegalArgumentException ); }; #endif /* SC_VBA_WORKSHEETS_HXX */ diff --git a/sc/source/ui/vba/vbawsfunction.cxx b/sc/source/ui/vba/vbawsfunction.cxx index c355244f6815..60daa7303f2e 100644 --- a/sc/source/ui/vba/vbawsfunction.cxx +++ b/sc/source/ui/vba/vbawsfunction.cxx @@ -31,6 +31,7 @@ #include <com/sun/star/beans/XIntrospectionAccess.hpp> #include <com/sun/star/sheet/XFunctionAccess.hpp> #include <com/sun/star/sheet/XCellRangesQuery.hpp> +#include <com/sun/star/sheet/XCellRangeAddressable.hpp> #include <com/sun/star/sheet/CellFlags.hpp> #include <com/sun/star/reflection/XIdlMethod.hpp> #include <com/sun/star/beans/MethodConcept.hpp> @@ -44,10 +45,27 @@ using namespace com::sun::star; using namespace ooo::vba; -ScVbaWSFunction::ScVbaWSFunction( const uno::Reference< XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext): ScVbaWSFunction_BASE( xParent, xContext ) +namespace { + +void lclConvertDoubleToBoolean( uno::Any& rAny ) { + if( rAny.has< double >() ) + { + double fValue = rAny.get< double >(); + if( fValue == 0.0 ) + rAny <<= false; + else if( fValue == 1.0 ) + rAny <<= true; + // do nothing for other values or types + } } +} // namespace + +ScVbaWSFunction::ScVbaWSFunction( const uno::Reference< XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext ) : + ScVbaWSFunction_BASE( xParent, xContext ) +{ +} uno::Reference< beans::XIntrospectionAccess > ScVbaWSFunction::getIntrospection(void) throw(uno::RuntimeException) @@ -58,33 +76,101 @@ ScVbaWSFunction::getIntrospection(void) throw(uno::RuntimeException) uno::Any SAL_CALL ScVbaWSFunction::invoke(const rtl::OUString& FunctionName, const uno::Sequence< uno::Any >& Params, uno::Sequence< sal_Int16 >& /*OutParamIndex*/, uno::Sequence< uno::Any >& /*OutParam*/) throw(lang::IllegalArgumentException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException) { - uno::Reference< lang::XMultiComponentFactory > xSMgr( mxContext->getServiceManager(), uno::UNO_QUERY_THROW ); - uno::Reference< sheet::XFunctionAccess > xFunctionAccess( - xSMgr->createInstanceWithContext(::rtl::OUString::createFromAscii( - "com.sun.star.sheet.FunctionAccess"), mxContext), - ::uno::UNO_QUERY_THROW); - uno::Sequence< uno::Any > aParamTemp; - sal_Int32 nParamCount = Params.getLength(); - aParamTemp.realloc(nParamCount); - const uno::Any* aArray = Params.getConstArray(); - uno::Any* aArrayTemp = aParamTemp.getArray(); - - for (int i=0; i < Params.getLength();i++) + // create copy of parameters, replace Excel range objects with UNO range objects + uno::Sequence< uno::Any > aParamTemp( Params ); + if( aParamTemp.hasElements() ) + { + uno::Any* pArray = aParamTemp.getArray(); + uno::Any* pArrayEnd = pArray + aParamTemp.getLength(); + for( ; pArray < pArrayEnd; ++pArray ) + { + uno::Reference< excel::XRange > myRange( *pArray, uno::UNO_QUERY ); + if( myRange.is() ) + *pArray = myRange->getCellRange(); + OSL_TRACE("Param[%d] is %s", (int)(pArray - aParamTemp.getConstArray()), rtl::OUStringToOString( comphelper::anyToString( *pArray ), RTL_TEXTENCODING_UTF8 ).getStr() ); + } + } + + uno::Any aRet; + bool bAsArray = true; + + // special handing for some functions that don't work correctly in FunctionAccess + ScCompiler aCompiler( 0, ScAddress() ); + OpCode eOpCode = aCompiler.GetEnglishOpCode( FunctionName.toAsciiUpperCase() ); + switch( eOpCode ) { - uno::Reference<excel::XRange> myRange( aArray[ i ], uno::UNO_QUERY ); - if ( myRange.is() ) + // ISLOGICAL does not work in array formula mode + case ocIsLogical: { - aArrayTemp[i] = myRange->getCellRange(); - continue; + if( aParamTemp.getLength() != 1 ) + throw lang::IllegalArgumentException(); + const uno::Any& rParam = aParamTemp[ 0 ]; + if( rParam.has< bool >() ) + { + aRet <<= true; + } + else if( rParam.has< uno::Reference< table::XCellRange > >() ) try + { + uno::Reference< sheet::XCellRangeAddressable > xRangeAddr( rParam, uno::UNO_QUERY_THROW ); + table::CellRangeAddress aRangeAddr = xRangeAddr->getRangeAddress(); + bAsArray = (aRangeAddr.StartColumn != aRangeAddr.EndColumn) || (aRangeAddr.StartRow != aRangeAddr.EndRow); + } + catch( uno::Exception& ) + { + } } - aArrayTemp[i]= aArray[i]; + break; + default:; } - for ( int count=0; count < aParamTemp.getLength(); ++count ) - OSL_TRACE("Param[%d] is %s", - count, rtl::OUStringToOString( comphelper::anyToString( aParamTemp[count] ), RTL_TEXTENCODING_UTF8 ).getStr() ); + if( !aRet.hasValue() ) + { + uno::Reference< lang::XMultiComponentFactory > xSMgr( mxContext->getServiceManager(), uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XFunctionAccess > xFunctionAccess( xSMgr->createInstanceWithContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.FunctionAccess" ) ), mxContext ), + uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xPropSet( xFunctionAccess, uno::UNO_QUERY_THROW ); + xPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsArrayFunction" ) ), uno::Any( bAsArray ) ); + aRet = xFunctionAccess->callFunction( FunctionName, aParamTemp ); + } - uno::Any aRet = xFunctionAccess->callFunction(FunctionName,aParamTemp); + /* Convert return value from double to to Boolean for some functions that + return Booleans. */ + typedef uno::Sequence< uno::Sequence< uno::Any > > AnySeqSeq; + if( (eOpCode == ocIsEmpty) || (eOpCode == ocIsString) || (eOpCode == ocIsNonString) || (eOpCode == ocIsLogical) || + (eOpCode == ocIsRef) || (eOpCode == ocIsValue) || (eOpCode == ocIsFormula) || (eOpCode == ocIsNA) || + (eOpCode == ocIsErr) || (eOpCode == ocIsError) || (eOpCode == ocIsEven) || (eOpCode == ocIsOdd) || + (eOpCode == ocAnd) || (eOpCode == ocOr) || (eOpCode == ocNot) || (eOpCode == ocTrue) || (eOpCode == ocFalse) ) + { + if( aRet.has< AnySeqSeq >() ) + { + AnySeqSeq aAnySeqSeq = aRet.get< AnySeqSeq >(); + for( sal_Int32 nRow = 0; nRow < aAnySeqSeq.getLength(); ++nRow ) + for( sal_Int32 nCol = 0; nCol < aAnySeqSeq[ nRow ].getLength(); ++nCol ) + lclConvertDoubleToBoolean( aAnySeqSeq[ nRow ][ nCol ] ); + aRet <<= aAnySeqSeq; + } + else + { + lclConvertDoubleToBoolean( aRet ); + } + } + + /* Hack/workaround (?): shorten single-row matrix to simple array, shorten + 1x1 matrix to single value. */ + if( aRet.has< AnySeqSeq >() ) + { + AnySeqSeq aAnySeqSeq = aRet.get< AnySeqSeq >(); + if( aAnySeqSeq.getLength() == 1 ) + { + if( aAnySeqSeq[ 0 ].getLength() == 1 ) + aRet = aAnySeqSeq[ 0 ][ 0 ]; + else + aRet <<= aAnySeqSeq[ 0 ]; + } + } + +#if 0 // MATCH function should alwayse return a double value, but currently if the first argument is XCellRange, MATCH function returns an array instead of a double value. Don't know why? // To fix this issue in safe, current solution is to convert this array to a double value just for MATCH function. String aUpper( FunctionName ); @@ -101,6 +187,8 @@ ScVbaWSFunction::invoke(const rtl::OUString& FunctionName, const uno::Sequence< throw uno::RuntimeException(); aRet <<= fVal; } +#endif + return aRet; } @@ -122,7 +210,7 @@ ScVbaWSFunction::hasMethod(const rtl::OUString& Name) throw(uno::RuntimeExcepti sal_Bool bIsFound = sal_False; try { - // the function name contained in the com.sun.star.sheet.FunctionDescription service is alwayse localized. + // the function name contained in the com.sun.star.sheet.FunctionDescription service is alwayse localized. // but the function name used in WorksheetFunction is a programmatic name (seems English). // So m_xNameAccess->hasByName( Name ) may fail to find name when a function name has a localized name. ScCompiler aCompiler( NULL, ScAddress() ); diff --git a/sc/source/ui/vba/vbawsfunction.hxx b/sc/source/ui/vba/vbawsfunction.hxx index 58a895f6d47b..ffd33849afe5 100644 --- a/sc/source/ui/vba/vbawsfunction.hxx +++ b/sc/source/ui/vba/vbawsfunction.hxx @@ -52,7 +52,6 @@ public: // XHelperInterface virtual rtl::OUString& getServiceImplName(); virtual css::uno::Sequence<rtl::OUString> getServiceNames(); - }; #endif diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx index a461c54f255e..c880a29f8067 100644 --- a/sc/source/ui/view/cellsh.cxx +++ b/sc/source/ui/view/cellsh.cxx @@ -715,22 +715,22 @@ void ScCellShell::GetState(SfxItemSet &rSet) break; case FID_INS_ROWBRK: - if ( nPosY==0 || (pDoc->GetRowFlags(nPosY,nTab) & CR_MANUALBREAK) ) + if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) ) rSet.DisableItem( nWhich ); break; case FID_INS_COLBRK: - if ( nPosX==0 || (pDoc->GetColFlags(nPosX,nTab) & CR_MANUALBREAK) ) + if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) ) rSet.DisableItem( nWhich ); break; case FID_DEL_ROWBRK: - if ( nPosY==0 || (pDoc->GetRowFlags(nPosY,nTab) & CR_MANUALBREAK)==0 ) + if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) == 0 ) rSet.DisableItem( nWhich ); break; case FID_DEL_COLBRK: - if ( nPosX==0 || (pDoc->GetColFlags(nPosX,nTab) & CR_MANUALBREAK)==0 ) + if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) == 0 ) rSet.DisableItem( nWhich ); break; diff --git a/sc/source/ui/view/colrowba.cxx b/sc/source/ui/view/colrowba.cxx index 8916624fdb52..d802c08f642f 100644 --- a/sc/source/ui/view/colrowba.cxx +++ b/sc/source/ui/view/colrowba.cxx @@ -98,7 +98,8 @@ USHORT ScColBar::GetEntrySize( SCCOLROW nEntryNo ) { ScDocument* pDoc = pViewData->GetDocument(); SCTAB nTab = pViewData->GetTabNo(); - if ( pDoc->GetColFlags( static_cast<SCCOL>(nEntryNo), nTab ) & CR_HIDDEN ) + SCCOL nLastCol = -1; + if (pDoc->ColHidden(static_cast<SCCOL>(nEntryNo), nTab, nLastCol)) return 0; else return (USHORT) ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(nEntryNo), nTab ), pViewData->GetPPTX() ); @@ -265,7 +266,8 @@ USHORT ScRowBar::GetEntrySize( SCCOLROW nEntryNo ) { ScDocument* pDoc = pViewData->GetDocument(); SCTAB nTab = pViewData->GetTabNo(); - if ( pDoc->GetRowFlags( nEntryNo, nTab ) & CR_HIDDEN ) + SCROW nLastRow = -1; + if (pDoc->RowHidden(nEntryNo, nTab, nLastRow)) return 0; else return (USHORT) ScViewData::ToPixel( pDoc->GetOriginalHeight( nEntryNo, diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index 35befa8f7a36..dbdeae1ae0b1 100755 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -694,6 +694,9 @@ ULONG RefreshDPObject( ScDPObject *pDPObj, ScDocument *pDoc, ScDocShell *pDocSh, if( !pDPObj ) return STR_PIVOT_NOTFOUND; + if ( pDocSh && !pDoc ) + pDoc = pDocSh->GetDocument(); + if( !pDoc ) return static_cast<ULONG>(-1); diff --git a/sc/source/ui/view/drawutil.cxx b/sc/source/ui/view/drawutil.cxx index 3885b0adc752..ba250767c169 100644 --- a/sc/source/ui/view/drawutil.cxx +++ b/sc/source/ui/view/drawutil.cxx @@ -66,14 +66,19 @@ void ScDrawUtil::CalcScale( ScDocument* pDoc, SCTAB nTab, nTwipsX += (long) nWidth; nPixelX += ScViewData::ToPixel( nWidth, nPPTX ); } - ScCoupledCompressedArrayIterator< SCROW, BYTE, USHORT> aIter( - pDoc->GetRowFlagsArray( nTab), nStartRow, nEndRow-1, CR_HIDDEN, 0, - pDoc->GetRowHeightArray( nTab)); - for ( ; aIter; ++aIter ) + + for (SCROW nRow = nStartRow; nRow <= nEndRow-1; ++nRow) { - USHORT nHeight = *aIter; - nTwipsY += (long) nHeight; - nPixelY += ScViewData::ToPixel( nHeight, nPPTY ); + SCROW nLastRow = nRow; + if (pDoc->RowHidden(nRow, nTab, NULL, &nLastRow)) + { + nRow = nLastRow; + continue; + } + + USHORT nHeight = pDoc->GetRowHeight(nRow, nTab); + nTwipsY += static_cast<long>(nHeight); + nPixelY += ScViewData::ToPixel(nHeight, nPPTY); } MapMode aHMMMode( MAP_100TH_MM, Point(), rZoomX, rZoomY ); @@ -100,10 +105,10 @@ void ScDrawUtil::CalcScale( ScDocument* pDoc, SCTAB nTab, else rScaleY = Fraction( 1, 1 ); - // 17 bits of accuracy are needed to always hit the right part of - // cells in the last rows - rScaleX.ReduceInaccurate( 17 ); - rScaleY.ReduceInaccurate( 17 ); + // 25 bits of accuracy are needed to always hit the right part of + // cells in the last rows (was 17 before 1M rows). + rScaleX.ReduceInaccurate( 25 ); + rScaleY.ReduceInaccurate( 25 ); } diff --git a/sc/source/ui/view/drawvie4.cxx b/sc/source/ui/view/drawvie4.cxx index 8b9debdabfae..3a28096d2853 100644 --- a/sc/source/ui/view/drawvie4.cxx +++ b/sc/source/ui/view/drawvie4.cxx @@ -282,8 +282,8 @@ void ScDrawView::CalcNormScale( Fraction& rFractX, Fraction& rFractY ) const pDoc->GetTableArea( nTab, nEndCol, nEndRow ); if (nEndCol<20) nEndCol = 20; - if (nEndRow<20) - nEndRow = 20; + if (nEndRow<1000) + nEndRow = 1000; Fraction aZoom(1,1); ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, pDev, aZoom,aZoom, diff --git a/sc/source/ui/view/drawview.cxx b/sc/source/ui/view/drawview.cxx index cc09722530ad..1d2b797b3a9b 100644 --- a/sc/source/ui/view/drawview.cxx +++ b/sc/source/ui/view/drawview.cxx @@ -187,7 +187,7 @@ void ScDrawView::AddCustomHdl() if(nCol > 0) --nCol; - SCROW nRow = nPosY <= 0 ? 0 : pDoc->FastGetRowForHeight( nTab, + SCROW nRow = nPosY <= 0 ? 0 : pDoc->GetRowForHeight( nTab, (ULONG) nPosY); if(nRow > 0) --nRow; @@ -376,8 +376,8 @@ void ScDrawView::RecalcScale() pDoc->GetTableArea( nTab, nEndCol, nEndRow ); if (nEndCol<20) nEndCol = 20; - if (nEndRow<20) - nEndRow = 20; + if (nEndRow<1000) + nEndRow = 1000; ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, pDev,aZoomX,aZoomY,nPPTX,nPPTY, aScaleX,aScaleY ); diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index 87740a88e4df..db72d87f30a2 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -153,7 +153,19 @@ extern USHORT nScFillModeMouseModifier; // global.cxx #define SC_FILTERLISTBOX_LINES 12 -//================================================================== +// ============================================================================ + +ScGridWindow::VisibleRange::VisibleRange() : + mnCol1(0), mnCol2(MAXCOL), mnRow1(0), mnRow2(MAXROW) +{ +} + +bool ScGridWindow::VisibleRange::isInside(SCCOL nCol, SCROW nRow) const +{ + return mnCol1 <= nCol && nCol <= mnCol2 && mnRow1 <= nRow && nRow <= mnRow2; +} + +// ============================================================================ class ScFilterListBox : public ListBox { @@ -366,6 +378,7 @@ ScGridWindow::ScGridWindow( Window* pParent, ScViewData* pData, ScSplitPos eWhic mpOODragRect( NULL ), mpOOHeader( NULL ), mpOOShrink( NULL ), + mpAutoFillRect(static_cast<Rectangle*>(NULL)), pViewData( pData ), eWhich( eWhichPos ), pNoteMarker( NULL ), @@ -1323,37 +1336,23 @@ BOOL ScGridWindow::TestMouse( const MouseEvent& rMEvt, BOOL bAction ) ScDocument* pDoc = pViewData->GetDocument(); SCTAB nTab = pViewData->GetTabNo(); BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab ); - long nLayoutSign = bLayoutRTL ? -1 : 1; // Auto-Fill ScRange aMarkRange; if (pViewData->GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE) { - if ( aMarkRange.aStart.Tab() == pViewData->GetTabNo() ) + if (aMarkRange.aStart.Tab() == pViewData->GetTabNo() && mpAutoFillRect) { - // Block-Ende wie in DrawAutoFillMark - SCCOL nX = aMarkRange.aEnd.Col(); - SCROW nY = aMarkRange.aEnd.Row(); - - Point aFillPos = pViewData->GetScrPos( nX, nY, eWhich, TRUE ); - long nSizeXPix; - long nSizeYPix; - pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix ); - aFillPos.X() += nSizeXPix * nLayoutSign; - aFillPos.Y() += nSizeYPix; - if ( bLayoutRTL ) - aFillPos.X() -= 1; - Point aMousePos = rMEvt.GetPosPixel(); - // Abfrage hier passend zu DrawAutoFillMark - // (ein Pixel mehr als markiert) - if ( aMousePos.X() >= aFillPos.X()-3 && aMousePos.X() <= aFillPos.X()+4 && - aMousePos.Y() >= aFillPos.Y()-3 && aMousePos.Y() <= aFillPos.Y()+4 ) + if (mpAutoFillRect->IsInside(aMousePos)) { SetPointer( Pointer( POINTER_CROSS ) ); //! dickeres Kreuz ? if (bAction) { + SCCOL nX = aMarkRange.aEnd.Col(); + SCROW nY = aMarkRange.aEnd.Row(); + if ( lcl_IsEditableMatrix( pViewData->GetDocument(), aMarkRange ) ) pViewData->SetDragMode( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nX, nY, SC_FILL_MATRIX ); @@ -2405,6 +2404,7 @@ void lcl_InitMouseEvent( ::com::sun::star::awt::MouseEvent& rEvent, const MouseE long ScGridWindow::PreNotify( NotifyEvent& rNEvt ) { + bool bDone = false; USHORT nType = rNEvt.GetType(); if ( nType == EVENT_MOUSEBUTTONUP || nType == EVENT_MOUSEBUTTONDOWN ) { @@ -2425,16 +2425,31 @@ long ScGridWindow::PreNotify( NotifyEvent& rNEvt ) if ( rNEvt.GetWindow() ) aEvent.Source = rNEvt.GetWindow()->GetComponentInterface(); if ( nType == EVENT_MOUSEBUTTONDOWN) - pImp->MousePressed( aEvent ); + bDone = pImp->MousePressed( aEvent ); else - pImp->MouseReleased( aEvent ); + bDone = pImp->MouseReleased( aEvent ); } } } } } + if (bDone) // event consumed by a listener + { + if ( nType == EVENT_MOUSEBUTTONDOWN ) + { + const MouseEvent* pMouseEvent = rNEvt.GetMouseEvent(); + if ( pMouseEvent->IsRight() && pMouseEvent->GetClicks() == 1 ) + { + // If a listener returned true for a right-click call, also prevent opening the context menu + // (this works only if the context menu is opened on mouse-down) + nMouseStatus = SC_GM_IGNORE; + } + } - return Window::PreNotify( rNEvt ); + return 1; + } + else + return Window::PreNotify( rNEvt ); } void ScGridWindow::Tracking( const TrackingEvent& rTEvt ) @@ -2678,6 +2693,10 @@ void __EXPORT ScGridWindow::Command( const CommandEvent& rCEvt ) if ( nCmd == COMMAND_CONTEXTMENU && !SC_MOD()->GetIsWaterCan() ) { + BOOL bMouse = rCEvt.IsMouseEvent(); + if ( bMouse && nMouseStatus == SC_GM_IGNORE ) + return; + if (pViewData->IsAnyFillMode()) { pViewData->GetView()->StopRefMode(); @@ -2688,7 +2707,6 @@ void __EXPORT ScGridWindow::Command( const CommandEvent& rCEvt ) Point aPosPixel = rCEvt.GetMousePosPixel(); Point aMenuPos = aPosPixel; - BOOL bMouse = rCEvt.IsMouseEvent(); if ( bMouse ) { @@ -2934,7 +2952,7 @@ void ScGridWindow::SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, // clicked on selected object -> don't change anything bHitSelected = TRUE; } - else if ( pViewData->GetMarkData().IsCellMarked( (USHORT) nCellX, (USHORT) nCellY ) ) + else if ( pViewData->GetMarkData().IsCellMarked(nCellX, nCellY) ) { // clicked on selected cell -> don't change anything bHitSelected = TRUE; @@ -2958,7 +2976,7 @@ void ScGridWindow::SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, if ( !bHitDraw ) { pView->Unmark(); - pView->SetCursor( (USHORT) nCellX, (USHORT) nCellY ); + pView->SetCursor(nCellX, nCellY); if ( bWasDraw ) pViewData->GetViewShell()->SetDrawShell( FALSE ); // switch shells } @@ -4533,18 +4551,17 @@ void lcl_PaintOneRange( ScDocShell* pDocSh, const ScRange& rRange, USHORT nEdges SCROW nTmp; ScDocument* pDoc = pDocSh->GetDocument(); - while ( nCol1 > 0 && ( pDoc->GetColFlags( nCol1, nTab1 ) & CR_HIDDEN ) ) + while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab1) ) { --nCol1; bHiddenEdge = TRUE; } - while ( nCol2 < MAXCOL && ( pDoc->GetColFlags( nCol2, nTab1 ) & CR_HIDDEN ) ) + while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab1) ) { ++nCol2; bHiddenEdge = TRUE; } - nTmp = pDoc->GetRowFlagsArray( nTab1).GetLastForCondition( 0, nRow1, - CR_HIDDEN, 0); + nTmp = pDoc->FirstVisibleRow(0, nRow1, nTab1); if (!ValidRow(nTmp)) nTmp = 0; if (nTmp < nRow1) @@ -4552,8 +4569,7 @@ void lcl_PaintOneRange( ScDocShell* pDocSh, const ScRange& rRange, USHORT nEdges nRow1 = nTmp; bHiddenEdge = TRUE; } - nTmp = pDoc->GetRowFlagsArray( nTab1).GetFirstForCondition( nRow2, MAXROW, - CR_HIDDEN, 0); + nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab1); if (!ValidRow(nTmp)) nTmp = MAXROW; if (nTmp > nRow2) @@ -5123,6 +5139,9 @@ void ScGridWindow::UpdateCursorOverlay() SCCOL nX = pViewData->GetCurX(); SCROW nY = pViewData->GetCurY(); + if (!maVisibleRange.isInside(nX, nY)) + return; + // don't show the cursor in overlapped cells ScDocument* pDoc = pViewData->GetDocument(); @@ -5298,6 +5317,7 @@ void ScGridWindow::UpdateSelectionOverlay() void ScGridWindow::DeleteAutoFillOverlay() { DELETEZ( mpOOAutoFill ); + mpAutoFillRect.reset(); } void ScGridWindow::UpdateAutoFillOverlay() @@ -5318,6 +5338,11 @@ void ScGridWindow::UpdateAutoFillOverlay() { SCCOL nX = aAutoMarkPos.Col(); SCROW nY = aAutoMarkPos.Row(); + + if (!maVisibleRange.isInside(nX, nY)) + // Autofill mark is not visible. Bail out. + return; + SCTAB nTab = pViewData->GetTabNo(); ScDocument* pDoc = pViewData->GetDocument(); BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab ); @@ -5333,7 +5358,7 @@ void ScGridWindow::UpdateAutoFillOverlay() aFillPos.Y() += nSizeYPix; aFillPos.Y() -= 2; - Rectangle aFillRect( aFillPos, Size(6,6) ); + mpAutoFillRect.reset(new Rectangle(aFillPos, Size(6, 6))); // #i70788# get the OverlayManager safely ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); @@ -5343,7 +5368,7 @@ void ScGridWindow::UpdateAutoFillOverlay() const Color aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor ); std::vector< basegfx::B2DRange > aRanges; const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); - basegfx::B2DRange aRB(aFillRect.Left(), aFillRect.Top(), aFillRect.Right() + 1, aFillRect.Bottom() + 1); + basegfx::B2DRange aRB(mpAutoFillRect->Left(), mpAutoFillRect->Top(), mpAutoFillRect->Right() + 1, mpAutoFillRect->Bottom() + 1); aRB.transform(aTransform); aRanges.push_back(aRB); @@ -5358,10 +5383,10 @@ void ScGridWindow::UpdateAutoFillOverlay() mpOOAutoFill = new ::sdr::overlay::OverlayObjectList; mpOOAutoFill->append(*pOverlay); } - } - if ( aOldMode != aDrawMode ) - SetMapMode( aOldMode ); + if ( aOldMode != aDrawMode ) + SetMapMode( aOldMode ); + } } void ScGridWindow::DeleteDragRectOverlay() diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx index 6d9bb94eb76b..f8b5c25c4a70 100644 --- a/sc/source/ui/view/gridwin2.cxx +++ b/sc/source/ui/view/gridwin2.cxx @@ -933,7 +933,7 @@ void ScGridWindow::PagebreakMove( const MouseEvent& rMEvt, BOOL bUp ) BOOL bGrow = !bHide && nNew > nPagebreakBreak; if ( bColumn ) { - if ( pDoc->GetColFlags( static_cast<SCCOL>(nPagebreakBreak), nTab ) & CR_MANUALBREAK ) + if (pDoc->HasColBreak(static_cast<SCCOL>(nPagebreakBreak), nTab) & BREAK_MANUAL) { ScAddress aOldAddr( static_cast<SCCOL>(nPagebreakBreak), nPosY, nTab ); pViewFunc->DeletePageBreak( TRUE, TRUE, &aOldAddr, FALSE ); @@ -946,8 +946,8 @@ void ScGridWindow::PagebreakMove( const MouseEvent& rMEvt, BOOL bUp ) if ( bGrow ) { // vorigen Break auf hart, und Skalierung aendern - if ( static_cast<SCCOL>(nPagebreakPrev) > aPagebreakSource.aStart.Col() && - !(pDoc->GetColFlags( static_cast<SCCOL>(nPagebreakPrev), nTab ) & CR_MANUALBREAK) ) + bool bManualBreak = (pDoc->HasColBreak(static_cast<SCCOL>(nPagebreakPrev), nTab) & BREAK_MANUAL); + if ( static_cast<SCCOL>(nPagebreakPrev) > aPagebreakSource.aStart.Col() && !bManualBreak ) { ScAddress aPrev( static_cast<SCCOL>(nPagebreakPrev), nPosY, nTab ); pViewFunc->InsertPageBreak( TRUE, TRUE, &aPrev, FALSE ); @@ -960,7 +960,7 @@ void ScGridWindow::PagebreakMove( const MouseEvent& rMEvt, BOOL bUp ) } else { - if ( pDoc->GetRowFlags( nPagebreakBreak, nTab ) & CR_MANUALBREAK ) + if (pDoc->HasRowBreak(nPagebreakBreak, nTab) & BREAK_MANUAL) { ScAddress aOldAddr( nPosX, nPagebreakBreak, nTab ); pViewFunc->DeletePageBreak( FALSE, TRUE, &aOldAddr, FALSE ); @@ -973,8 +973,8 @@ void ScGridWindow::PagebreakMove( const MouseEvent& rMEvt, BOOL bUp ) if ( bGrow ) { // vorigen Break auf hart, und Skalierung aendern - if ( nPagebreakPrev > aPagebreakSource.aStart.Row() && - !(pDoc->GetRowFlags( nPagebreakPrev, nTab ) & CR_MANUALBREAK) ) + bool bManualBreak = (pDoc->HasRowBreak(nPagebreakPrev, nTab) & BREAK_MANUAL); + if ( nPagebreakPrev > aPagebreakSource.aStart.Row() && !bManualBreak ) { ScAddress aPrev( nPosX, nPagebreakPrev, nTab ); pViewFunc->InsertPageBreak( FALSE, TRUE, &aPrev, FALSE ); diff --git a/sc/source/ui/view/gridwin3.cxx b/sc/source/ui/view/gridwin3.cxx index 5bfc0483b553..f16c2fe1ada7 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<20) nEndRow = 20; + if (nEndRow<1000) 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/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx index f698913ea758..d8024e439173 100644 --- a/sc/source/ui/view/gridwin4.cxx +++ b/sc/source/ui/view/gridwin4.cxx @@ -449,6 +449,12 @@ void ScGridWindow::Draw( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, ScUpdateMod SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich); if (nYBottom > MAXROW) nYBottom = MAXROW; + // Store the current visible range. + maVisibleRange.mnCol1 = nPosX; + maVisibleRange.mnCol2 = nXRight; + maVisibleRange.mnRow1 = nPosY; + maVisibleRange.mnRow2 = nYBottom; + if (nX1 > nXRight || nY1 > nYBottom) return; // unsichtbar if (nX2 > nXRight) nX2 = nXRight; @@ -1086,7 +1092,7 @@ void ScGridWindow::DrawPagePreview( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, if ( nBreak >= nX1 && nBreak <= nX2+1 ) { //! hidden suchen - if ( pDoc->GetColFlags( nBreak, nTab ) & CR_MANUALBREAK ) + if (pDoc->HasColBreak(nBreak, nTab) & BREAK_MANUAL) pContentDev->SetFillColor( aManual ); else pContentDev->SetFillColor( aAutomatic ); @@ -1105,7 +1111,7 @@ void ScGridWindow::DrawPagePreview( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, if ( nBreak >= nY1 && nBreak <= nY2+1 ) { //! hidden suchen - if ( pDoc->GetRowFlags( nBreak, nTab ) & CR_MANUALBREAK ) + if (pDoc->HasRowBreak(nBreak, nTab) & BREAK_MANUAL) pContentDev->SetFillColor( aManual ); else pContentDev->SetFillColor( aAutomatic ); @@ -1374,7 +1380,7 @@ Rectangle ScGridWindow::GetListValButtonRect( const ScAddress& rButtonPos ) const ScMergeAttr* pMerge = static_cast<const ScMergeAttr*>(pDoc->GetAttr( nCol,nRow,nTab, ATTR_MERGE )); if ( pMerge->GetColMerge() > 1 ) nNextCol = nCol + pMerge->GetColMerge(); // next cell after the merged area - while ( nNextCol <= MAXCOL && (pDoc->GetColFlags( nNextCol, nTab ) & CR_HIDDEN) ) + while ( nNextCol <= MAXCOL && pDoc->ColHidden(nNextCol, nTab) ) ++nNextCol; BOOL bNextCell = ( nNextCol <= MAXCOL ); if ( bNextCell ) @@ -1577,7 +1583,7 @@ void ScGridWindow::InvertSimple( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, if ( pMergeFlag->IsVerOverlapped() && ( bDoHidden || bFirstRow ) ) { while ( pMergeFlag->IsVerOverlapped() && nThisY > 0 && - ( (pDoc->GetRowFlags( nThisY-1, nTab ) & CR_HIDDEN) || bFirstRow ) ) + (pDoc->RowHidden(nThisY-1, nTab) || bFirstRow) ) { --nThisY; pPattern = pDoc->GetPattern( nX, nThisY, nTab ); @@ -1764,7 +1770,7 @@ void ScGridWindow::GetSelectionRects( ::std::vector< Rectangle >& rPixelRects ) if ( pMergeFlag->IsVerOverlapped() && ( bDoHidden || bFirstRow ) ) { while ( pMergeFlag->IsVerOverlapped() && nThisY > 0 && - ( (pDoc->GetRowFlags( nThisY-1, nTab ) & CR_HIDDEN) || bFirstRow ) ) + (pDoc->RowHidden(nThisY-1, nTab) || bFirstRow) ) { --nThisY; pPattern = pDoc->GetPattern( nX, nThisY, nTab ); diff --git a/sc/source/ui/view/hdrcont.cxx b/sc/source/ui/view/hdrcont.cxx index 6c389d496b73..25f3c1c8f10a 100644 --- a/sc/source/ui/view/hdrcont.cxx +++ b/sc/source/ui/view/hdrcont.cxx @@ -102,7 +102,7 @@ ScHeaderControl::ScHeaderControl( Window* pParent, SelectionEngine* pSelectionEn nWidth = nSmallWidth = aSize.Width(); nBigWidth = LogicToPixel( Size( GetTextWidth( - String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("88888")) ), 0 ) ).Width() + 4; + String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("8888888")) ), 0 ) ).Width() + 5; SetBackground(); // sonst Probleme auf OS/2 !?!?! } diff --git a/sc/source/ui/view/makefile.mk b/sc/source/ui/view/makefile.mk index feeacc865fba..1b2fef913fc2 100644 --- a/sc/source/ui/view/makefile.mk +++ b/sc/source/ui/view/makefile.mk @@ -155,6 +155,7 @@ EXCEPTIONSFILES= \ $(SLO)$/gridwin2.obj \ $(SLO)$/scextopt.obj \ $(SLO)$/tabvwshb.obj \ + $(SLO)$/tabvwshf.obj \ $(SLO)$/viewdata.obj \ $(SLO)$/viewfunc.obj \ $(SLO)$/viewfun2.obj \ diff --git a/sc/source/ui/view/olinewin.cxx b/sc/source/ui/view/olinewin.cxx index bec88920f989..b1e82fd9217f 100644 --- a/sc/source/ui/view/olinewin.cxx +++ b/sc/source/ui/view/olinewin.cxx @@ -183,16 +183,15 @@ const ScOutlineEntry* ScOutlineWindow::GetOutlineEntry( size_t nLevel, size_t nE bool ScOutlineWindow::IsHidden( SCCOLROW nColRowIndex ) const { - sal_uInt8 nFlags = mbHoriz ? - GetDoc().GetColFlags( static_cast<SCCOL>(nColRowIndex), GetTab() ) : - GetDoc().GetRowFlags( static_cast<SCROW>(nColRowIndex), GetTab() ); - return (nFlags & CR_HIDDEN) != 0; + return mbHoriz ? + GetDoc().ColHidden(static_cast<SCCOL>(nColRowIndex), GetTab()) : + GetDoc().RowHidden(static_cast<SCROW>(nColRowIndex), GetTab()); } bool ScOutlineWindow::IsFiltered( SCCOLROW nColRowIndex ) const { // columns cannot be filtered - return !mbHoriz && GetDoc().IsFiltered( static_cast<SCROW>(nColRowIndex), GetTab() ); + return !mbHoriz && GetDoc().RowFiltered( static_cast<SCROW>(nColRowIndex), GetTab() ); } bool ScOutlineWindow::IsFirstVisible( SCCOLROW nColRowIndex ) const diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx index 265e54fe0e12..961572fc0185 100644 --- a/sc/source/ui/view/output.cxx +++ b/sc/source/ui/view/output.cxx @@ -322,8 +322,9 @@ void ScOutputData::DrawGrid( BOOL bGrid, BOOL bPage ) long nPosX; long nPosY; SCSIZE nArrY; - BYTE nOldFlags = 0; - BYTE nFlags; + ScBreakType nBreak = BREAK_NONE; + ScBreakType nBreakOld = BREAK_NONE; + BOOL bSingle; Color aPageColor; Color aManualColor; @@ -378,27 +379,27 @@ void ScOutputData::DrawGrid( BOOL bGrid, BOOL bPage ) if ( bPage ) { // Seitenumbrueche auch in ausgeblendeten suchen - nFlags = 0; SCCOL nCol = nXplus1; while (nCol <= MAXCOL) { - BYTE nDocFl = pDoc->GetColFlags( nCol, nTab ); - nFlags = nDocFl & ( CR_PAGEBREAK | CR_MANUALBREAK ); - if ( nFlags || !(nDocFl & CR_HIDDEN) ) + nBreak = pDoc->HasColBreak(nCol, nTab); + bool bHidden = pDoc->ColHidden(nCol, nTab); + + if ( nBreak || !bHidden ) break; ++nCol; } - if (nFlags != nOldFlags) + if (nBreak != nBreakOld) { aGrid.Flush(); - pDev->SetLineColor( (nFlags & CR_MANUALBREAK) ? aManualColor : - (nFlags) ? aPageColor : aGridColor ); - nOldFlags = nFlags; + pDev->SetLineColor( (nBreak & BREAK_MANUAL) ? aManualColor : + nBreak ? aPageColor : aGridColor ); + nBreakOld = nBreak; } } - BOOL bDraw = bGrid || nOldFlags; // einfaches Gitter nur wenn eingestellt + BOOL bDraw = bGrid || nBreakOld; // einfaches Gitter nur wenn eingestellt //! Mit dieser Abfrage wird zuviel weggelassen, wenn ein automatischer //! Umbruch mitten in den Wiederholungsspalten liegt. @@ -409,7 +410,7 @@ void ScOutputData::DrawGrid( BOOL bGrid, BOOL bPage ) { if ( nX == MAXCOL ) bDraw = FALSE; - else if (pDoc->GetColFlags(nXplus1,nTab) & ( CR_PAGEBREAK | CR_MANUALBREAK )) + else if (pDoc->HasColBreak(nXplus1, nTab)) bDraw = FALSE; } #endif @@ -500,28 +501,24 @@ void ScOutputData::DrawGrid( BOOL bGrid, BOOL bPage ) { if ( bPage ) { - // Seitenumbrueche auch in ausgeblendeten suchen - nFlags = 0; - ScCompressedArrayIterator< SCROW, BYTE > aIter( - pDoc->GetRowFlagsArray( nTab), nYplus1, MAXROW); - do + for (SCROW i = nYplus1; i <= MAXROW; ++i) { - BYTE nDocFl = *aIter; - nFlags = nDocFl & ( CR_PAGEBREAK | CR_MANUALBREAK ); - if ( nFlags || !(nDocFl & CR_HIDDEN) ) + nBreak = pDoc->HasRowBreak(i, nTab); + bool bHidden = pDoc->RowHidden(i, nTab); + if (nBreak || !bHidden) break; - } while (aIter.NextRange()); + } - if (nFlags != nOldFlags) + if (nBreakOld != nBreak) { aGrid.Flush(); - pDev->SetLineColor( (nFlags & CR_MANUALBREAK) ? aManualColor : - (nFlags) ? aPageColor : aGridColor ); - nOldFlags = nFlags; + pDev->SetLineColor( (nBreak & BREAK_MANUAL) ? aManualColor : + (nBreak) ? aPageColor : aGridColor ); + nBreakOld = nBreak; } } - BOOL bDraw = bGrid || nOldFlags; // einfaches Gitter nur wenn eingestellt + BOOL bDraw = bGrid || nBreakOld; // einfaches Gitter nur wenn eingestellt //! Mit dieser Abfrage wird zuviel weggelassen, wenn ein automatischer //! Umbruch mitten in den Wiederholungszeilen liegt. @@ -532,7 +529,7 @@ void ScOutputData::DrawGrid( BOOL bGrid, BOOL bPage ) { if ( nY == MAXROW ) bDraw = FALSE; - else if (pDoc->GetRowFlags(nYplus1,nTab) & ( CR_PAGEBREAK | CR_MANUALBREAK )) + else if (pDoc->HasRowBreak(nYplus1, nTab)) bDraw = FALSE; } #endif @@ -654,7 +651,7 @@ void ScOutputData::FindRotated() const ScPatternAttr* pPattern = pInfo->pPatternAttr; const SfxItemSet* pCondSet = pInfo->pConditionSet; - if ( !pPattern && (pDoc->GetColFlags(nX,nTab) & CR_HIDDEN) == 0 ) + if ( !pPattern && !pDoc->ColHidden(nX, nTab) ) { pPattern = pDoc->GetPattern( nX, nY, nTab ); pCondSet = pDoc->GetCondResult( nX, nY, nTab ); diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx index 37bc941c0f16..b0b040f9b5e0 100644 --- a/sc/source/ui/view/output2.cxx +++ b/sc/source/ui/view/output2.cxx @@ -114,6 +114,7 @@ class ScDrawStringsVars long nMaxDigitWidth; long nSignWidth; long nDotWidth; + long nExpWidth; ScBaseCell* pLastCell; ULONG nValueFormat; @@ -173,6 +174,7 @@ private: long GetMaxDigitWidth(); long GetSignWidth(); long GetDotWidth(); + long GetExpWidth(); void TextChanged(); long ConvertWidthLogicToPixel( long nWidth ) const; }; @@ -193,6 +195,7 @@ ScDrawStringsVars::ScDrawStringsVars(ScOutputData* pData, BOOL bPTL) : nMaxDigitWidth( 0 ), nSignWidth( 0 ), nDotWidth( 0 ), + nExpWidth( 0 ), pLastCell ( NULL ), nValueFormat( 0 ), bLineBreak ( FALSE ), @@ -262,6 +265,7 @@ void ScDrawStringsVars::SetPattern( const ScPatternAttr* pNew, const SfxItemSet* nMaxDigitWidth = 0; nSignWidth = 0; nDotWidth = 0; + nExpWidth = 0; pPattern = pNew; pCondSet = pSet; @@ -417,6 +421,7 @@ void ScDrawStringsVars::SetPatternSimple( const ScPatternAttr* pNew, const SfxIt nMaxDigitWidth = 0; nSignWidth = 0; nDotWidth = 0; + nExpWidth = 0; // wird gerufen, wenn sich die Font-Variablen nicht aendern (!StringDiffer) pPattern = pNew; @@ -547,7 +552,7 @@ void ScDrawStringsVars::SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth ) // Failed to get output string. Bail out. return; - sal_uInt8 nSignCount = 0, nDecimalCount = 0; + sal_uInt8 nSignCount = 0, nDecimalCount = 0, nExpCount = 0; xub_StrLen nLen = aString.Len(); sal_Unicode cDecSep = ScGlobal::GetpLocaleData()->getLocaleItem().decimalSeparator.getStr()[0]; for (xub_StrLen i = 0; i < nLen; ++i) @@ -557,13 +562,17 @@ void ScDrawStringsVars::SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth ) ++nSignCount; else if (c == cDecSep) ++nDecimalCount; + else if (c == sal_Unicode('E')) + ++nExpCount; } if (nDecimalCount) nWidth += (nMaxDigit - GetDotWidth()) * nDecimalCount; if (nSignCount) nWidth += (nMaxDigit - GetSignWidth()) * nSignCount; + if (nExpCount) + nWidth += (nMaxDigit - GetExpWidth()) * nExpCount; - if (nDecimalCount || nSignCount) + if (nDecimalCount || nSignCount || nExpCount) { // Re-calculate. nNumDigits = static_cast<sal_uInt16>(nWidth / nMaxDigit); @@ -658,6 +667,17 @@ long ScDrawStringsVars::GetDotWidth() return nDotWidth; } +long ScDrawStringsVars::GetExpWidth() +{ + if (nExpWidth > 0) + return nExpWidth; + + nExpWidth = pOutput->pFmtDevice->GetTextWidth(String('E')); + if (bPixelToLogic) + nExpWidth = ConvertWidthLogicToPixel(nExpWidth); + return nExpWidth; +} + void ScDrawStringsVars::TextChanged() { OutputDevice* pRefDevice = pOutput->pRefDevice; @@ -844,7 +864,7 @@ BOOL ScOutputData::GetMergeOrigin( SCCOL nX, SCROW nY, SCSIZE nArrY, while (bHOver) // nY konstant { --rOverX; - bHidden = ( (pDoc->GetColFlags(rOverX,nTab) & CR_HIDDEN) != 0 ); + bHidden = pDoc->ColHidden(rOverX, nTab); if ( !bDoMerge && !bHidden ) return FALSE; @@ -868,7 +888,7 @@ BOOL ScOutputData::GetMergeOrigin( SCCOL nX, SCROW nY, SCSIZE nArrY, while (bVOver) { --rOverY; - bHidden = ( (pDoc->GetRowFlags(rOverY,nTab) & CR_HIDDEN) != 0 ); + bHidden = pDoc->RowHidden(rOverY, nTab); if ( !bDoMerge && !bHidden ) return FALSE; @@ -876,8 +896,8 @@ BOOL ScOutputData::GetMergeOrigin( SCCOL nX, SCROW nY, SCSIZE nArrY, --nArrY; // lokale Kopie ! if (rOverX >= nX1 && rOverY >= nY1 && - (pDoc->GetColFlags(rOverX,nTab) & CR_HIDDEN) == 0 && - (pDoc->GetRowFlags(rOverY,nTab) & CR_HIDDEN) == 0 && + !pDoc->ColHidden(rOverX, nTab) && + !pDoc->RowHidden(rOverY, nTab) && pRowInfo[nArrY].nRowNo == rOverY) { // rVirtPosY -= pRowInfo[nArrY].nHeight; @@ -2176,7 +2196,7 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) if (bDoCell) { if ( nCellY == nY && nCellX >= nX1 && nCellX <= nX2 && - (pDoc->GetColFlags(nCellX,nTab) & CR_HIDDEN) == 0 ) + !pDoc->ColHidden(nCellX, nTab) ) { CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nCellX+1]; pPattern = rCellInfo.pPatternAttr; diff --git a/sc/source/ui/view/prevloc.cxx b/sc/source/ui/view/prevloc.cxx index 67e1aa86553a..fd36a1b2c1d0 100644 --- a/sc/source/ui/view/prevloc.cxx +++ b/sc/source/ui/view/prevloc.cxx @@ -350,9 +350,9 @@ Rectangle ScPreviewLocationData::GetOffsetPixel( const ScAddress& rCellPos, cons long nSizeX = (long) ( pDoc->GetColWidth( nEndCol, nTab ) * nScaleX ); SCROW nEndRow = rCellPos.Row(); - long nPosY = (long) pDoc->FastGetScaledRowHeight( rRange.aStart.Row(), + long nPosY = (long) pDoc->GetScaledRowHeight( rRange.aStart.Row(), nEndRow, nTab, nScaleY); - long nSizeY = (long) ( pDoc->FastGetRowHeight( nEndRow, nTab ) * nScaleY ); + long nSizeY = (long) ( pDoc->GetRowHeight( nEndRow, nTab ) * nScaleY ); Size aOffsetLogic( nPosX, nPosY ); Size aSizeLogic( nSizeX, nSizeY ); @@ -599,11 +599,11 @@ void ScPreviewLocationData::GetTableInfo( const Rectangle& rVisiblePixel, ScPrev ++nColCount; if ( bHasRepCols ) for ( nCol=nRepeatColStart; nCol<=nRepeatColEnd; nCol++ ) - if ( ( pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN ) == 0 ) + if (!pDoc->ColHidden(nCol, nTab)) ++nColCount; if ( bHasMainCols ) for ( nCol=nMainColStart; nCol<=nMainColEnd; nCol++ ) - if ( ( pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN ) == 0 ) + if (!pDoc->ColHidden(nCol, nTab)) ++nColCount; if ( nColCount > 0 ) @@ -620,7 +620,7 @@ void ScPreviewLocationData::GetTableInfo( const Rectangle& rVisiblePixel, ScPrev { long nPosX = 0; for ( nCol=nRepeatColStart; nCol<=nRepeatColEnd; nCol++ ) - if ( ( pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN ) == 0 ) + if (!pDoc->ColHidden(nCol, nTab)) { USHORT nDocW = pDoc->GetColWidth( nCol, nTab ); long nNextX = nPosX + (long) (nDocW * nScaleX); @@ -639,7 +639,7 @@ void ScPreviewLocationData::GetTableInfo( const Rectangle& rVisiblePixel, ScPrev { long nPosX = 0; for ( nCol=nMainColStart; nCol<=nMainColEnd; nCol++ ) - if ( ( pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN ) == 0 ) + if (!pDoc->ColHidden(nCol, nTab)) { USHORT nDocW = pDoc->GetColWidth( nCol, nTab ); long nNextX = nPosX + (long) (nDocW * nScaleX); @@ -667,11 +667,9 @@ void ScPreviewLocationData::GetTableInfo( const Rectangle& rVisiblePixel, ScPrev if ( bHasHeaderRow ) ++nRowCount; if ( bHasRepRows ) - nRowCount += pDoc->GetRowFlagsArray( nTab).CountForCondition( - nRepeatRowStart, nRepeatRowEnd, CR_HIDDEN, 0); + nRowCount += pDoc->CountVisibleRows(nRepeatRowStart, nRepeatRowEnd, nTab); if ( bHasMainRows ) - nRowCount += pDoc->GetRowFlagsArray( nTab).CountForCondition( - nMainRowStart, nMainRowEnd, CR_HIDDEN, 0); + nRowCount += pDoc->CountVisibleRows(nMainRowStart, nMainRowEnd, nTab); if ( nRowCount > 0 ) { @@ -686,58 +684,44 @@ void ScPreviewLocationData::GetTableInfo( const Rectangle& rVisiblePixel, ScPrev if ( bHasRepRows ) { long nPosY = 0; - ScCompressedArrayIterator< SCROW, BYTE> aIter( - pDoc->GetRowFlagsArray( nTab), nRepeatRowStart, - nRepeatRowEnd); - do + for (SCROW nRow = nRepeatRowStart; nRow <= nRepeatRowEnd; ++nRow) { - if ((*aIter & CR_HIDDEN) == 0) - { - SCROW nRangeEnd = aIter.GetRangeEnd(); - for (SCROW nRow=aIter.GetRangeStart(); nRow<=nRangeEnd; ++nRow) - { - USHORT nDocH = pDoc->FastGetOriginalRowHeight( nRow, nTab ); - long nNextY = nPosY + (long) (nDocH * nScaleY); - - long nPixelStart = pWindow->LogicToPixel( Size( 0, nPosY ), aCellMapMode ).Height(); - long nPixelEnd = pWindow->LogicToPixel( Size( 0, nNextY ), aCellMapMode ).Height() - 1; - pRowInfo[nRowPos].Set( FALSE, nRow, - aRepeatRect.Top() + nPixelStart, - aRepeatRect.Top() + nPixelEnd ); - - nPosY = nNextY; - ++nRowPos; - } - } - } while (aIter.NextRange()); + if (pDoc->RowHidden(nRow, nTab)) + continue; + + USHORT nDocH = pDoc->GetOriginalHeight( nRow, nTab ); + long nNextY = nPosY + (long) (nDocH * nScaleY); + + long nPixelStart = pWindow->LogicToPixel( Size( 0, nPosY ), aCellMapMode ).Height(); + long nPixelEnd = pWindow->LogicToPixel( Size( 0, nNextY ), aCellMapMode ).Height() - 1; + pRowInfo[nRowPos].Set( FALSE, nRow, + aRepeatRect.Top() + nPixelStart, + aRepeatRect.Top() + nPixelEnd ); + + nPosY = nNextY; + ++nRowPos; + } } if ( bHasMainRows ) { long nPosY = 0; - ScCompressedArrayIterator< SCROW, BYTE> aIter( - pDoc->GetRowFlagsArray( nTab), nMainRowStart, - nMainRowEnd); - do + for (SCROW nRow = nMainRowStart; nRow <= nMainRowEnd; ++nRow) { - if ((*aIter & CR_HIDDEN) == 0) - { - SCROW nRangeEnd = aIter.GetRangeEnd(); - for (SCROW nRow=aIter.GetRangeStart(); nRow<=nRangeEnd; ++nRow) - { - USHORT nDocH = pDoc->FastGetOriginalRowHeight( nRow, nTab ); - long nNextY = nPosY + (long) (nDocH * nScaleY); - - long nPixelStart = pWindow->LogicToPixel( Size( 0, nPosY ), aCellMapMode ).Height(); - long nPixelEnd = pWindow->LogicToPixel( Size( 0, nNextY ), aCellMapMode ).Height() - 1; - pRowInfo[nRowPos].Set( FALSE, nRow, - aMainRect.Top() + nPixelStart, - aMainRect.Top() + nPixelEnd ); - - nPosY = nNextY; - ++nRowPos; - } - } - } while (aIter.NextRange()); + if (pDoc->RowHidden(nRow, nTab)) + continue; + + USHORT nDocH = pDoc->GetOriginalHeight( nRow, nTab ); + long nNextY = nPosY + (long) (nDocH * nScaleY); + + long nPixelStart = pWindow->LogicToPixel( Size( 0, nPosY ), aCellMapMode ).Height(); + long nPixelEnd = pWindow->LogicToPixel( Size( 0, nNextY ), aCellMapMode ).Height() - 1; + pRowInfo[nRowPos].Set( FALSE, nRow, + aMainRect.Top() + nPixelStart, + aMainRect.Top() + nPixelEnd ); + + nPosY = nNextY; + ++nRowPos; + } } rInfo.SetRowInfo( nRowCount, pRowInfo ); } diff --git a/sc/source/ui/view/printfun.cxx b/sc/source/ui/view/printfun.cxx index afe23892e786..378ea1233cf9 100644 --- a/sc/source/ui/view/printfun.cxx +++ b/sc/source/ui/view/printfun.cxx @@ -85,6 +85,8 @@ #include <vcl/lineinfo.hxx> #include <tools/pstm.hxx> +#include <boost/scoped_ptr.hpp> + #define ZOOM_MIN 10 #define GET_BOOL(set,which) ((const SfxBoolItem&)(set)->Get((which))).GetValue() @@ -1501,7 +1503,7 @@ void ScPrintFunc::PrintRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY ) for (SCROW nRow=nY1; nRow<=nY2; nRow++) { - USHORT nDocH = pDoc->FastGetRowHeight( nRow, nPrintTab ); + USHORT nDocH = pDoc->GetRowHeight( nRow, nPrintTab ); if (nDocH) { long nHeight = (long) (nDocH * nScaleY); @@ -1557,7 +1559,7 @@ void ScPrintFunc::LocateRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY, nEndX -= nOneX; long nPosY = nScrY - nOneY; - nPosY += pDoc->FastGetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY); + nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY); Rectangle aCellRect( nScrX, nScrY, nEndX, nPosY ); rLocationData.AddRowHeaders( aCellRect, nY1, nY2, bRepRow ); } @@ -1599,7 +1601,7 @@ void ScPrintFunc::LocateArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, } long nPosY = nScrY - nOneY; - nPosY += pDoc->FastGetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY); + nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY); Rectangle aCellRect( nScrX, nScrY, nPosX, nPosY ); rLocationData.AddCellRange( aCellRect, ScRange( nX1,nY1,nPrintTab, nX2,nY2,nPrintTab ), bRepCol, bRepRow, aDrawMapMode ); @@ -2181,9 +2183,9 @@ void ScPrintFunc::PrintPage( long nPageNo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCRO } if ( bCenterVer ) { - long nDataHeight = pDoc->FastGetRowHeight( nY1, nY2, nPrintTab); + long nDataHeight = pDoc->GetRowHeight( nY1, nY2, nPrintTab); if (bDoRepRow) - nDataHeight += pDoc->FastGetRowHeight( nRepeatStartRow, + nDataHeight += pDoc->GetRowHeight( nRepeatStartRow, nRepeatEndRow, nPrintTab); if (aTableParam.bHeaders) nDataHeight += (long) PRINT_HEADER_HEIGHT; @@ -2216,11 +2218,11 @@ void ScPrintFunc::PrintPage( long nPageNo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCRO for (SCCOL i=nRepeatStartCol; i<=nRepeatEndCol; i++) nRepeatWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX); if (bDoRepRow) - nRepeatHeight += pDoc->FastGetScaledRowHeight( nRepeatStartRow, + nRepeatHeight += pDoc->GetScaledRowHeight( nRepeatStartRow, nRepeatEndRow, nPrintTab, nScaleY); for (SCCOL i=nX1; i<=nX2; i++) nContentWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX); - nContentHeight += pDoc->FastGetScaledRowHeight( nY1, nY2, nPrintTab, + nContentHeight += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY); // partition the page @@ -2886,30 +2888,84 @@ void ScPrintFunc::CalcZoom( USHORT nRangeNo ) // Zoom bere if (aTableParam.bScalePageNum) { nZoom = 100; - BOOL bFound = FALSE; USHORT nPagesToFit = aTableParam.nScalePageNum; - while (!bFound) + + sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0; + while (true) { + if (nZoom <= ZOOM_MIN) + break; + CalcPages(); - if ( nPagesX * nPagesY <= nPagesToFit || nZoom <= ZOOM_MIN ) - bFound = TRUE; + bool bFitsPage = (nPagesX * nPagesY <= nPagesToFit); + + if (bFitsPage) + { + if (nZoom == 100) + // If it fits at 100 %, it's good enough for me. + break; + + nLastFitZoom = nZoom; + nZoom = (nLastNonFitZoom + nZoom) / 2; + + if (nLastFitZoom == nZoom) + // It converged. Use this zoom level. + break; + } else - --nZoom; + { + if (nZoom - nLastFitZoom <= 1) + { + nZoom = nLastFitZoom; + CalcPages(); + break; + } + + nLastNonFitZoom = nZoom; + nZoom = (nLastFitZoom + nZoom) / 2; + } } } else if (aTableParam.bScaleTo) { nZoom = 100; - BOOL bFound = FALSE; USHORT nW = aTableParam.nScaleWidth; USHORT nH = aTableParam.nScaleHeight; - while (!bFound) + + sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0; + while (true) { + if (nZoom <= ZOOM_MIN) + break; + CalcPages(); - if ( ((!nW || (nPagesX <= nW)) && (!nH || (nPagesY <= nH))) || (nZoom <= ZOOM_MIN) ) - bFound = TRUE; + bool bFitsPage = ((!nW || (nPagesX <= nW)) && (!nH || (nPagesY <= nH))); + + if (bFitsPage) + { + if (nZoom == 100) + // If it fits at 100 %, it's good enough for me. + break; + + nLastFitZoom = nZoom; + nZoom = (nLastNonFitZoom + nZoom) / 2; + + if (nLastFitZoom == nZoom) + // It converged. Use this zoom level. + break; + } else - --nZoom; + { + if (nZoom - nLastFitZoom <= 1) + { + nZoom = nLastFitZoom; + CalcPages(); + break; + } + + nLastNonFitZoom = nZoom; + nZoom = (nLastFitZoom + nZoom) / 2; + } } } else if (aTableParam.bScaleAll) @@ -3029,18 +3085,20 @@ void ScPrintFunc::CalcPages() // berechnet aPageRect und Seiten au nPagesY = 0; nTotalY = 0; - BOOL bVisCol = FALSE; + bool bVisCol = false; + SCCOL nLastCol = -1; for (SCCOL i=nStartCol; i<=nEndCol; i++) { - BYTE nFlags = pDoc->GetColFlags(i,nPrintTab); - if ( i>nStartCol && bVisCol && (nFlags & CR_PAGEBREAK) ) + bool bHidden = pDoc->ColHidden(i, nPrintTab, nLastCol); + bool bPageBreak = (pDoc->HasColBreak(i, nPrintTab) & BREAK_PAGE); + if ( i>nStartCol && bVisCol && bPageBreak ) { pPageEndX[nPagesX] = i-1; ++nPagesX; - bVisCol = FALSE; + bVisCol = false; } - if (!(nFlags & CR_HIDDEN)) - bVisCol = TRUE; + if (!bHidden) + bVisCol = true; } if (bVisCol) // auch am Ende keine leeren Seiten { @@ -3048,39 +3106,60 @@ void ScPrintFunc::CalcPages() // berechnet aPageRect und Seiten au ++nPagesX; } - BOOL bVisRow = FALSE; + bool bVisRow = false; SCROW nPageStartRow = nStartRow; - ScCompressedArrayIterator< SCROW, BYTE> aIter( pDoc->GetRowFlagsArray( - nPrintTab), nStartRow, nEndRow); - do + SCROW nLastVisibleRow = -1; + + ::boost::scoped_ptr<ScRowBreakIterator> pRowBreakIter(pDoc->GetRowBreakIterator(nPrintTab)); + SCROW nNextPageBreak = pRowBreakIter->first(); + while (nNextPageBreak != ScRowBreakIterator::NOT_FOUND && nNextPageBreak < nStartRow) + // Skip until the page break position is at the start row or greater. + nNextPageBreak = pRowBreakIter->next(); + + for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow) { - BYTE nFlags = *aIter; - SCROW nRangeEnd = aIter.GetRangeEnd(); - for (SCROW j=aIter.GetRangeStart(); j<=nRangeEnd; ++j) + bool bPageBreak = (nNextPageBreak == nRow); + if (bPageBreak) + nNextPageBreak = pRowBreakIter->next(); + + if (nRow > nStartRow && bVisRow && bPageBreak ) { - if ( j>nStartRow && bVisRow && (nFlags & CR_PAGEBREAK) ) + pPageEndY[nTotalY] = nRow-1; + ++nTotalY; + + if ( !aTableParam.bSkipEmpty || + !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nRow-1 ) ) { - pPageEndY[nTotalY] = j-1; - ++nTotalY; + pPageRows[nPagesY].SetStartRow( nPageStartRow ); + pPageRows[nPagesY].SetEndRow( nRow-1 ); + pPageRows[nPagesY].SetPagesX( nPagesX ); + if (aTableParam.bSkipEmpty) + lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX ); + ++nPagesY; + } - if ( !aTableParam.bSkipEmpty || - !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, j-1 ) ) - { - pPageRows[nPagesY].SetStartRow( nPageStartRow ); - pPageRows[nPagesY].SetEndRow( j-1 ); - pPageRows[nPagesY].SetPagesX( nPagesX ); - if (aTableParam.bSkipEmpty) - lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX ); - ++nPagesY; - } + nPageStartRow = nRow; + bVisRow = false; + } - nPageStartRow = j; - bVisRow = FALSE; - } - if (!(nFlags & CR_HIDDEN)) - bVisRow = TRUE; + if (nRow <= nLastVisibleRow) + { + // This row is still visible. Don't bother calling RowHidden() to + // find out, for speed optimization. + bVisRow = true; + continue; + } + + SCROW nLastRow = -1; + if (!pDoc->RowHidden(nRow, nPrintTab, NULL, &nLastRow)) + { + bVisRow = true; + nLastVisibleRow = nLastRow; } - } while (aIter.NextRange()); + else + // skip all hidden rows. + nRow = nLastRow; + } if (bVisRow) { diff --git a/sc/source/ui/view/scextopt.cxx b/sc/source/ui/view/scextopt.cxx index bead62419bb3..1faa105d2bd7 100644 --- a/sc/source/ui/view/scextopt.cxx +++ b/sc/source/ui/view/scextopt.cxx @@ -36,7 +36,6 @@ // ============================================================================ ScExtDocSettings::ScExtDocSettings() : - maOleSize( ScAddress::INITIALIZE_INVALID ), mfTabBarWidth( -1.0 ), mnLinkCnt( 0 ), mnDisplTab( 0 ) diff --git a/sc/source/ui/view/select.cxx b/sc/source/ui/view/select.cxx index 4887895c8e6b..b2c9ffdc1395 100644 --- a/sc/source/ui/view/select.cxx +++ b/sc/source/ui/view/select.cxx @@ -275,12 +275,12 @@ BOOL __EXPORT ScViewFunctionSet::SetCursorAtPoint( const Point& rPointPixel, BOO ScDocument* pDoc = pViewData->GetDocument(); SCTAB nTab = pViewData->GetTabNo(); if ( bLeft && !bRightScroll ) - do --nPosX; while ( nPosX>=0 && ( pDoc->GetColFlags( nPosX, nTab ) & CR_HIDDEN ) ); + do --nPosX; while ( nPosX>=0 && pDoc->ColHidden( nPosX, nTab ) ); if ( bTop && !bBottomScroll ) { if (--nPosY >= 0) { - pDoc->GetRowFlagsArray( nTab).GetLastForCondition( 0, nPosY, CR_HIDDEN, 0); + nPosY = pDoc->LastVisibleRow(0, nPosY, nTab); if (!ValidRow(nPosY)) nPosY = -1; } @@ -476,7 +476,7 @@ BOOL ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScrol { // #94321# in SetCursorAtPoint hidden columns are skipped. // They must be skipped here too, or the result will always be the first hidden column. - do ++nPosX; while ( nPosX<nStartX && ( pDoc->GetColFlags( nPosX, nTab ) & CR_HIDDEN ) ); + do ++nPosX; while ( nPosX<nStartX && pDoc->ColHidden(nPosX, nTab) ); for (SCCOL i=nPosX; i<nStartX; i++) nSizeX += pDoc->GetColWidth( i, nTab ); } @@ -491,8 +491,7 @@ BOOL ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScrol // They must be skipped here too, or the result will always be the first hidden row. if (++nPosY < nStartY) { - nPosY = pDoc->GetRowFlagsArray( nTab).GetFirstForCondition( - nPosY, nStartY-1, CR_HIDDEN, 0); + nPosY = pDoc->FirstVisibleRow(nPosY, nStartY-1, nTab); if (!ValidRow(nPosY)) nPosY = nStartY; } diff --git a/sc/source/ui/view/tabcont.cxx b/sc/source/ui/view/tabcont.cxx index c5572fb9844a..6014ded96e1e 100644 --- a/sc/source/ui/view/tabcont.cxx +++ b/sc/source/ui/view/tabcont.cxx @@ -59,13 +59,14 @@ ScTabControl::ScTabControl( Window* pParent, ScViewData* pData ) : DropTargetHelper( this ), DragSourceHelper( this ), pViewData( pData ), - nMouseClickPageId( TABBAR_PAGE_NOTFOUND ), - nSelPageIdByMouse( TABBAR_PAGE_NOTFOUND ), + nMouseClickPageId( TabBar::PAGE_NOT_FOUND ), + nSelPageIdByMouse( TabBar::PAGE_NOT_FOUND ), bErrorShown( FALSE ) { ScDocument* pDoc = pViewData->GetDocument(); String aString; + Color aTabBgColor; SCTAB nCount = pDoc->GetTableCount(); for (SCTAB i=0; i<nCount; i++) { @@ -77,6 +78,11 @@ ScTabControl::ScTabControl( Window* pParent, ScViewData* pData ) : InsertPage( static_cast<sal_uInt16>(i)+1, aString, TPB_SPECIAL ); else InsertPage( static_cast<sal_uInt16>(i)+1, aString ); + if ( !pDoc->IsDefaultTabBgColor(i) ) + { + aTabBgColor = pDoc->GetTabBgColor(i); + SetTabBgColor( static_cast<sal_uInt16>(i)+1, aTabBgColor ); + } } } } @@ -157,7 +163,7 @@ void ScTabControl::MouseButtonDown( const MouseEvent& rMEvt ) if( rMEvt.IsLeft() && (rMEvt.GetModifier() == 0) ) nMouseClickPageId = GetPageId( rMEvt.GetPosPixel() ); else - nMouseClickPageId = TABBAR_PAGE_NOTFOUND; + nMouseClickPageId = TabBar::PAGE_NOT_FOUND; TabBar::MouseButtonDown( rMEvt ); } @@ -168,7 +174,7 @@ void ScTabControl::MouseButtonUp( const MouseEvent& rMEvt ) // mouse button down and up on same page? if( nMouseClickPageId != GetPageId( aPos ) ) - nMouseClickPageId = TABBAR_PAGE_NOTFOUND; + nMouseClickPageId = TabBar::PAGE_NOT_FOUND; if ( rMEvt.GetClicks() == 2 && rMEvt.IsLeft() && nMouseClickPageId != 0 && nMouseClickPageId != TAB_PAGE_NOTFOUND ) { @@ -185,7 +191,7 @@ void ScTabControl::MouseButtonUp( const MouseEvent& rMEvt ) SfxDispatcher* pDispatcher = pViewData->GetViewShell()->GetViewFrame()->GetDispatcher(); pDispatcher->Execute( nSlot, SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD ); // forget page ID, to be really sure that the dialog is not called twice - nMouseClickPageId = TABBAR_PAGE_NOTFOUND; + nMouseClickPageId = TabBar::PAGE_NOT_FOUND; } TabBar::MouseButtonUp( rMEvt ); @@ -197,7 +203,7 @@ void ScTabControl::Select() nSelPageIdByMouse = nMouseClickPageId; /* Reset nMouseClickPageId, so that next Select() call may invalidate nSelPageIdByMouse (i.e. if called from keyboard). */ - nMouseClickPageId = TABBAR_PAGE_NOTFOUND; + nMouseClickPageId = TabBar::PAGE_NOT_FOUND; ScModule* pScMod = SC_MOD(); ScDocument* pDoc = pViewData->GetDocument(); @@ -262,6 +268,7 @@ void ScTabControl::Select() rBind.Invalidate( FID_DELETE_TABLE ); rBind.Invalidate( FID_TABLE_SHOW ); rBind.Invalidate( FID_TABLE_HIDE ); + rBind.Invalidate( FID_TAB_SET_TAB_BG_COLOR ); // SetReference nur wenn der Konsolidieren-Dialog offen ist // (fuer Referenzen ueber mehrere Tabellen) @@ -288,16 +295,22 @@ void ScTabControl::UpdateStatus() SCTAB i; String aString; SCTAB nMaxCnt = Max( nCount, static_cast<SCTAB>(GetMaxId()) ); + Color aTabBgColor; BOOL bModified = FALSE; // Tabellen-Namen for (i=0; i<nMaxCnt && !bModified; i++) { if (pDoc->IsVisible(i)) + { pDoc->GetName(i,aString); + aTabBgColor = pDoc->GetTabBgColor(i); + } else + { aString.Erase(); + } - if (GetPageText(static_cast<sal_uInt16>(i)+1) != aString) + if ( (GetPageText(static_cast<sal_uInt16>(i)+1) != aString) || (GetTabBgColor(static_cast<sal_uInt16>(i)+1) != aTabBgColor) ) bModified = TRUE; } @@ -314,6 +327,11 @@ void ScTabControl::UpdateStatus() InsertPage( static_cast<sal_uInt16>(i)+1, aString, TPB_SPECIAL ); else InsertPage( static_cast<sal_uInt16>(i)+1, aString ); + if ( !pDoc->IsDefaultTabBgColor(i) ) + { + aTabBgColor = pDoc->GetTabBgColor(i); + SetTabBgColor( static_cast<sal_uInt16>(i)+1, aTabBgColor ); + } } } } @@ -371,7 +389,7 @@ void ScTabControl::ActivateView(BOOL bActivate) void ScTabControl::SetSheetLayoutRTL( BOOL bSheetRTL ) { SetEffectiveRTL( bSheetRTL ); - nSelPageIdByMouse = TABBAR_PAGE_NOTFOUND; + nSelPageIdByMouse = TabBar::PAGE_NOT_FOUND; } @@ -607,12 +625,12 @@ void ScTabControl::EndRenaming() void ScTabControl::Mirror() { TabBar::Mirror(); - if( nSelPageIdByMouse != TABBAR_PAGE_NOTFOUND ) + if( nSelPageIdByMouse != TabBar::PAGE_NOT_FOUND ) { Rectangle aRect( GetPageRect( GetCurPageId() ) ); if( !aRect.IsEmpty() ) SetPointerPosPixel( aRect.Center() ); - nSelPageIdByMouse = TABBAR_PAGE_NOTFOUND; // only once after a Select() + nSelPageIdByMouse = TabBar::PAGE_NOT_FOUND; // only once after a Select() } } diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx index 4938defa437d..0bc4617a9af4 100644 --- a/sc/source/ui/view/tabview.cxx +++ b/sc/source/ui/view/tabview.cxx @@ -1439,7 +1439,7 @@ void ScTabView::ScrollX( long nDeltaX, ScHSplitPos eWhich, BOOL bUpdBars ) SCsCOL nDir = ( nDeltaX > 0 ) ? 1 : -1; ScDocument* pDoc = aViewData.GetDocument(); SCTAB nTab = aViewData.GetTabNo(); - while ( ( pDoc->GetColFlags( nNewX, nTab ) & CR_HIDDEN ) && + while ( pDoc->ColHidden(nNewX, nTab) && nNewX+nDir >= 0 && nNewX+nDir <= MAXCOL ) nNewX = sal::static_int_cast<SCsCOL>( nNewX + nDir ); @@ -1528,7 +1528,7 @@ void ScTabView::ScrollY( long nDeltaY, ScVSplitPos eWhich, BOOL bUpdBars ) SCsROW nDir = ( nDeltaY > 0 ) ? 1 : -1; ScDocument* pDoc = aViewData.GetDocument(); SCTAB nTab = aViewData.GetTabNo(); - while ( ( pDoc->GetRowFlags( nNewY, nTab ) & CR_HIDDEN ) && + while ( pDoc->RowHidden(nNewY, nTab) && nNewY+nDir >= 0 && nNewY+nDir <= MAXROW ) nNewY += nDir; @@ -1615,7 +1615,7 @@ SCROW lcl_LastVisible( ScViewData& rViewData ) SCTAB nTab = rViewData.GetTabNo(); SCROW nVis = MAXROW; - while ( nVis > 0 && pDoc->FastGetRowHeight( nVis, nTab ) == 0 ) + while ( nVis > 0 && pDoc->GetRowHeight( nVis, nTab ) == 0 ) --nVis; return nVis; } diff --git a/sc/source/ui/view/tabview2.cxx b/sc/source/ui/view/tabview2.cxx index b7a773ab2abd..674f6f8ae0ff 100644 --- a/sc/source/ui/view/tabview2.cxx +++ b/sc/source/ui/view/tabview2.cxx @@ -640,13 +640,13 @@ BOOL lcl_FitsInWindow( double fScaleX, double fScaleY, USHORT nZoom, } long nBlockY = 0; - ScCoupledCompressedArrayIterator< SCROW, BYTE, USHORT> aIter( - pDoc->GetRowFlagsArray( nTab), 0, nFixPosY-1, CR_HIDDEN, 0, - pDoc->GetRowHeightArray( nTab)); - for ( ; aIter; ++aIter) + for (SCROW nRow = 0; nRow <= nFixPosY-1; ++nRow) { + if (pDoc->RowHidden(nRow, nTab)) + continue; + // for frozen panes, add both parts - USHORT nRowTwips = *aIter; + USHORT nRowTwips = pDoc->GetRowHeight(nRow, nTab); if (nRowTwips) { nBlockY += (long)(nRowTwips * fScaleY); @@ -654,10 +654,9 @@ BOOL lcl_FitsInWindow( double fScaleX, double fScaleY, USHORT nZoom, return FALSE; } } - aIter.NewLimits( nStartRow, nEndRow); - for ( ; aIter; ++aIter) + for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow) { - USHORT nRowTwips = *aIter; + USHORT nRowTwips = pDoc->GetRowHeight(nRow, nTab); if (nRowTwips) { nBlockY += (long)(nRowTwips * fScaleY); diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx index 750e49ec2334..86f68a1878cc 100644 --- a/sc/source/ui/view/tabview3.cxx +++ b/sc/source/ui/view/tabview3.cxx @@ -968,8 +968,8 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, BOOL bHFlip = FALSE; do { - BYTE nColFlags = pDoc->GetColFlags( nCurX, nTab ); - bSkipCell = (nColFlags & CR_HIDDEN) || pDoc->IsHorOverlapped( nCurX, nCurY, nTab ); + SCCOL nLastCol = -1; + bSkipCell = pDoc->ColHidden(nCurX, nTab, nLastCol) || pDoc->IsHorOverlapped( nCurX, nCurY, nTab ); if (bSkipProtected && !bSkipCell) bSkipCell = pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED); if (bSkipUnprotected && !bSkipCell) @@ -1010,8 +1010,8 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, BOOL bVFlip = FALSE; do { - BYTE nRowFlags = pDoc->GetRowFlags( nCurY, nTab ); - bSkipCell = (nRowFlags & CR_HIDDEN) || pDoc->IsVerOverlapped( nCurX, nCurY, nTab ); + SCROW nLastRow = -1; + bSkipCell = pDoc->RowHidden(nCurY, nTab, nLastRow) || pDoc->IsVerOverlapped( nCurX, nCurY, nTab ); if (bSkipProtected && !bSkipCell) bSkipCell = pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED); if (bSkipUnprotected && !bSkipCell) @@ -2093,17 +2093,18 @@ void ScTabView::PaintRangeFinder( long nNumber ) BOOL bHiddenEdge = FALSE; SCROW nTmp; ScDocument* pDoc = aViewData.GetDocument(); - while ( nCol1 > 0 && ( pDoc->GetColFlags( nCol1, nTab ) & CR_HIDDEN ) ) + SCCOL nLastCol = -1; + while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab, nLastCol) ) { --nCol1; bHiddenEdge = TRUE; } - while ( nCol2 < MAXCOL && ( pDoc->GetColFlags( nCol2, nTab ) & CR_HIDDEN ) ) + while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab, nLastCol) ) { ++nCol2; bHiddenEdge = TRUE; } - nTmp = pDoc->GetRowFlagsArray( nTab).GetLastForCondition( 0, nRow1, CR_HIDDEN, 0); + nTmp = pDoc->LastVisibleRow(0, nRow1, nTab); if (!ValidRow(nTmp)) nTmp = 0; if (nTmp < nRow1) @@ -2111,7 +2112,7 @@ void ScTabView::PaintRangeFinder( long nNumber ) nRow1 = nTmp; bHiddenEdge = TRUE; } - nTmp = pDoc->GetRowFlagsArray( nTab).GetFirstForCondition( nRow2, MAXROW, CR_HIDDEN, 0); + nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab); if (!ValidRow(nTmp)) nTmp = MAXROW; if (nTmp > nRow2) diff --git a/sc/source/ui/view/tabview5.cxx b/sc/source/ui/view/tabview5.cxx index bc5c94c271e2..f0ac3fc42869 100644 --- a/sc/source/ui/view/tabview5.cxx +++ b/sc/source/ui/view/tabview5.cxx @@ -666,7 +666,7 @@ void ScTabView::MakeVisible( const Rectangle& rHMMRect ) if (nScrollY > 0) while (nScrollY > 0 && nPosY < MAXROW) { - nScrollY -= (long) ( pDoc->FastGetRowHeight(nPosY, nTab) * nPPTY ); + nScrollY -= (long) ( pDoc->GetRowHeight(nPosY, nTab) * nPPTY ); ++nPosY; ++nLinesY; } @@ -674,7 +674,7 @@ void ScTabView::MakeVisible( const Rectangle& rHMMRect ) while (nScrollY < 0 && nPosY > 0) { --nPosY; - nScrollY += (long) ( pDoc->FastGetRowHeight(nPosY, nTab) * nPPTY ); + nScrollY += (long) ( pDoc->GetRowHeight(nPosY, nTab) * nPPTY ); --nLinesY; } diff --git a/sc/source/ui/view/tabvwshe.cxx b/sc/source/ui/view/tabvwshe.cxx index a94d73a4b022..c0af39226c3f 100644 --- a/sc/source/ui/view/tabvwshe.cxx +++ b/sc/source/ui/view/tabvwshe.cxx @@ -52,6 +52,7 @@ #include "editsh.hxx" #include "dociter.hxx" #include "inputhdl.hxx" +#include "document.hxx" //================================================================== @@ -88,6 +89,22 @@ String __EXPORT ScTabViewShell::GetSelectionText( BOOL bWholeWord ) else aRange.aEnd = aRange.aStart; } + else + { + // #i111531# with 1M rows it was necessary to limit the range + // to the actually used data area. + SCCOL nCol1, nCol2; + SCROW nRow1, nRow2; + SCTAB nTab1, nTab2; + aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + if (pDoc->ShrinkToUsedDataArea( nTab1, nCol1, nRow1, nCol2, nRow2, false)) + { + aRange.aStart.SetCol( nCol1 ); + aRange.aStart.SetRow( nRow1 ); + aRange.aEnd.SetCol( nCol2 ); + aRange.aEnd.SetRow( nRow2 ); + } + } ScImportExport aObj( pDoc, aRange ); aObj.SetFormulas( GetViewData()->GetOptions().GetOption( VOPT_FORMULAS ) ); diff --git a/sc/source/ui/view/tabvwshf.cxx b/sc/source/ui/view/tabvwshf.cxx index 68a852c4a3b7..20a10f149a3a 100644 --- a/sc/source/ui/view/tabvwshf.cxx +++ b/sc/source/ui/view/tabvwshf.cxx @@ -28,18 +28,19 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" - - -// INCLUDE --------------------------------------------------------------- +#include <boost/scoped_ptr.hpp> #include "scitems.hxx" #include <sfx2/request.hxx> +#include <sfx2/viewfrm.hxx> #include <basic/sbstar.hxx> #include <layout/layout.hxx> #include <svl/languageoptions.hxx> #include <svl/stritem.hxx> #include <svl/whiter.hxx> #include <vcl/msgbox.hxx> +#include <svx/svxdlg.hxx> +#include <editeng/colritem.hxx> #include "tabvwsh.hxx" #include "sc.hrc" @@ -52,9 +53,16 @@ //CHINA001 #include "strindlg.hxx" //CHINA001 #include "mvtabdlg.hxx" #include "docfunc.hxx" +#include "eventuno.hxx" #include "scabstdlg.hxx" //CHINA001 +#include "tabbgcolor.hxx" +#include "tabbgcolordlg.hxx" + +using ::boost::scoped_ptr; +using namespace com::sun::star; + #define IS_AVAILABLE(WhichId,ppItem) \ (pReqArgs->GetItemState((WhichId), TRUE, ppItem ) == SFX_ITEM_SET) @@ -683,6 +691,134 @@ void ScTabViewShell::ExecuteTable( SfxRequest& rReq ) } break; + case FID_TAB_SET_TAB_BG_COLOR: + case FID_TAB_MENU_SET_TAB_BG_COLOR: + { + if ( nSlot == FID_TAB_MENU_SET_TAB_BG_COLOR ) + nSlot = FID_TAB_SET_TAB_BG_COLOR; + SCTAB nTabNr = pViewData->GetTabNo(); + ScMarkData& rMark = pViewData->GetMarkData(); + SCTAB nTabSelCount = rMark.GetSelectCount(); + if ( !pDoc->IsDocEditable() ) + break; + + if ( pDoc->IsTabProtected( nTabNr ) ) // ||nTabSelCount > 1 + break; + + if( pReqArgs != NULL ) + { + BOOL bDone = FALSE; + const SfxPoolItem* pItem; + Color aColor; + if( IS_AVAILABLE( FN_PARAM_1, &pItem ) ) + nTabNr = ((const SfxUInt16Item*)pItem)->GetValue(); + + if( IS_AVAILABLE( nSlot, &pItem ) ) + aColor = ((const SvxColorItem*)pItem)->GetValue(); + + if ( nTabSelCount > 1 ) + { + scoped_ptr<ScUndoTabColorInfo::List> + pTabColorList(new ScUndoTabColorInfo::List); + for (SCTAB nTab=0; nTab<nTabCount; nTab++) + { + if ( rMark.GetTableSelect(nTab) && !pDoc->IsTabProtected(nTab) ) + { + ScUndoTabColorInfo aTabColorInfo(nTab); + aTabColorInfo.maNewTabBgColor = aColor; + pTabColorList->push_back(aTabColorInfo); + } + } + bDone = SetTabBgColor( *pTabColorList ); + } + else + { + bDone = SetTabBgColor( aColor, nCurrentTab ); //ScViewFunc.SetTabBgColor + } + if( bDone ) + { + rReq.Done( *pReqArgs ); + } + } + else + { + USHORT nRet = RET_OK; /// temp + BOOL bDone = FALSE; /// temp + Color aTabBgColor; + Color aNewTabBgColor; + + aTabBgColor = pDoc->GetTabBgColor( nCurrentTab ); + ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); + DBG_ASSERT(pFact, "ScAbstractFactory create fail!"); + AbstractScTabBgColorDlg* pDlg = pFact->CreateScTabBgColorDlg( + GetDialogParent(), + String(ScResId(SCSTR_SET_TAB_BG_COLOR)), + String(ScResId(SCSTR_NO_TAB_BG_COLOR)), + aTabBgColor, + nSlot,RID_SCDLG_TAB_BG_COLOR); + while ( !bDone && nRet == RET_OK ) + { + nRet = pDlg->Execute(); + if( nRet == RET_OK ) + { + Color aSelectedColor; + pDlg->GetSelectedColor(aSelectedColor); + scoped_ptr<ScUndoTabColorInfo::List> + pTabColorList(new ScUndoTabColorInfo::List); + if ( nTabSelCount > 1 ) + { + for (SCTAB nTab=0; nTab<nTabCount; nTab++) + { + if ( rMark.GetTableSelect(nTab) && !pDoc->IsTabProtected(nTab) ) + { + ScUndoTabColorInfo aTabColorInfo(nTab); + aTabColorInfo.maNewTabBgColor = aSelectedColor; + pTabColorList->push_back(aTabColorInfo); + } + } + bDone = SetTabBgColor( *pTabColorList ); + } + else + { + bDone = SetTabBgColor( aSelectedColor, nCurrentTab ); //ScViewFunc.SetTabBgColor + } + if ( bDone ) + { + rReq.AppendItem( SvxColorItem( aTabBgColor, nSlot ) ); + rReq.Done(); + } + else + { + if( rReq.IsAPI() ) + { + StarBASIC::Error( SbERR_SETPROP_FAILED ); + } + } + } + } + delete( pDlg ); + } + } + break; + + case FID_TAB_EVENTS: + { + ScDocShell* pDocSh = pViewData->GetDocShell(); + uno::Reference<container::XNameReplace> xEvents( new ScSheetEventsObj( pDocSh, nCurrentTab ) ); + uno::Reference<frame::XFrame> xFrame = GetViewFrame()->GetFrame().GetFrameInterface(); + SvxAbstractDialogFactory* pDlgFactory = SvxAbstractDialogFactory::Create(); + if (pDlgFactory) + { + std::auto_ptr<VclAbstractDialog> pDialog( pDlgFactory->CreateSvxMacroAssignDlg( + GetDialogParent(), xFrame, false, xEvents, 0 ) ); + if ( pDialog.get() && pDialog->Execute() == RET_OK ) + { + // the dialog modifies the settings directly + } + } + } + break; + default: DBG_ERROR("Unbekannte Message bei ViewShell"); break; @@ -801,6 +937,23 @@ void ScTabViewShell::GetStateTable( SfxItemSet& rSet ) rSet.Put( SfxBoolItem( nWhich, pDoc->IsLayoutRTL( nTab ) ) ); } break; + + case FID_TAB_MENU_SET_TAB_BG_COLOR: + { + if ( !pDoc->IsDocEditable() + || ( pDocShell && pDocShell->IsDocShared() ) + || pDoc->IsTabProtected(nTab) ) + rSet.DisableItem( nWhich ); + } + break; + + case FID_TAB_SET_TAB_BG_COLOR: + { + Color aColor; + aColor = pDoc->GetTabBgColor( nTab ); + rSet.Put( SvxColorItem( aColor, nWhich ) ); + } + break; } nWhich = aIter.NextWhich(); } diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx index 6b13c1bedcbf..c034836d4d4a 100644 --- a/sc/source/ui/view/viewdata.cxx +++ b/sc/source/ui/view/viewdata.cxx @@ -160,9 +160,6 @@ void ScViewDataTable::WriteUserDataSequence(uno::Sequence <beans::PropertyValue> pSettings[SC_TABLE_ZOOM_VALUE].Value <<= nZoomValue; pSettings[SC_TABLE_PAGE_VIEW_ZOOM_VALUE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_PAGEVIEWZOOMVALUE)); pSettings[SC_TABLE_PAGE_VIEW_ZOOM_VALUE].Value <<= nPageZoomValue; - -// pSettings[SC_TABLE_SELECTED].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_TABLESELECTED)); -// pSettings[SC_TABLE_SELECTED].Value <<= bool(rViewData.GetMarkData().GetTableSelect( nTab )); } } @@ -273,6 +270,17 @@ void ScViewDataTable::ReadUserDataSequence(const uno::Sequence <beans::PropertyV aSettings[i].Value >>= bSelected; rViewData.GetMarkData().SelectTable( nTab, bSelected ); } + else if (sName.compareToAscii(SC_UNONAME_TABCOLOR) == 0) + { + // There are documents out there that have their tab color defined as a view setting. + sal_Int32 nColor = COL_AUTO; + aSettings[i].Value >>= nColor; + if (static_cast<ColorData>(nColor) != COL_AUTO) + { + ScDocument* pDoc = rViewData.GetDocument(); + pDoc->SetTabBgColor(nTab, Color(static_cast<ColorData>(nColor))); + } + } } if (eHSplitMode == SC_SPLIT_FIX) nFixPosX = SanitizeCol( static_cast<SCCOL>( bHasHSplitInTwips ? nTempPosHTw : nTempPosH )); @@ -1595,7 +1603,7 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich, nScrPosY = 65535; else { - nTSize = pDoc->FastGetRowHeight( nY, nTabNo ); + nTSize = pDoc->GetRowHeight( nY, nTabNo ); if (nTSize) { long nSizeYPix = ToPixel( nTSize, nPPTY ); @@ -1604,7 +1612,7 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich, else if ( nY < MAXROW ) { // skip multiple hidden rows (forward only for now) - SCROW nNext = pDoc->FastGetFirstNonHiddenRow( nY + 1, nTabNo ); + SCROW nNext = pDoc->FirstVisibleRow(nY + 1, MAXROW, nTabNo); if ( nNext > MAXROW ) nY = MAXROW; else @@ -1616,7 +1624,7 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich, for (nY=nPosY; nY>nWhereY;) { --nY; - nTSize = pDoc->FastGetRowHeight( nY, nTabNo ); + nTSize = pDoc->GetRowHeight( nY, nTabNo ); if (nTSize) { long nSizeYPix = ToPixel( nTSize, nPPTY ); @@ -1706,8 +1714,7 @@ SCROW ScViewData::CellsAtY( SCsROW nPosY, SCsROW nDir, ScVSplitPos eWhichY, USHO bOut = TRUE; else { -// USHORT nTSize = pDoc->GetRowHeight( nRowNo, nTabNo ); - USHORT nTSize = pDoc->FastGetRowHeight( nRowNo, nTabNo ); + USHORT nTSize = pDoc->GetRowHeight( nRowNo, nTabNo ); if (nTSize) { long nSizeYPix = ToPixel( nTSize, nPPTY ); @@ -1716,7 +1723,7 @@ SCROW ScViewData::CellsAtY( SCsROW nPosY, SCsROW nDir, ScVSplitPos eWhichY, USHO else if ( nDir == 1 && nRowNo < MAXROW ) { // skip multiple hidden rows (forward only for now) - SCROW nNext = pDoc->FastGetFirstNonHiddenRow( nRowNo + 1, nTabNo ); + SCROW nNext = pDoc->FirstVisibleRow(nRowNo + 1, MAXROW, nTabNo); if ( nNext > MAXROW ) { // same behavior as without the optimization: set bOut with nY=MAXROW+1 @@ -1779,11 +1786,19 @@ BOOL ScViewData::GetMergeSizePixel( SCCOL nX, SCROW nY, long& rSizeXPix, long& r for (SCCOL i=0; i<nCountX; i++) nOutWidth += ToPixel( pDoc->GetColWidth(nX+i,nTabNo), nPPTX ); SCROW nCountY = pMerge->GetRowMerge(); - ScCoupledCompressedArrayIterator< SCROW, BYTE, USHORT> aIter( - pDoc->GetRowFlagsArray( nTabNo), nY, nY+nCountY-1, CR_HIDDEN, - 0, pDoc->GetRowHeightArray( nTabNo)); - for ( ; aIter; ++aIter ) - nOutHeight += ToPixel( *aIter, nPPTY ); + + for (SCROW nRow = nY; nRow <= nY+nCountY-1; ++nRow) + { + SCROW nLastRow = nRow; + if (pDoc->RowHidden(nRow, nTabNo, NULL, &nLastRow)) + { + nRow = nLastRow; + continue; + } + + USHORT nHeight = pDoc->GetRowHeight(nRow, nTabNo); + nOutHeight += ToPixel(nHeight, nPPTY); + } rSizeXPix = nOutWidth; rSizeYPix = nOutHeight; @@ -1843,7 +1858,7 @@ BOOL ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich, { while ( rPosY<=MAXROW && nClickY >= nScrY ) { - nScrY += ToPixel( pDoc->FastGetRowHeight( rPosY, nTabNo ), nPPTY ); + nScrY += ToPixel( pDoc->GetRowHeight( rPosY, nTabNo ), nPPTY ); ++rPosY; } --rPosY; @@ -1853,7 +1868,7 @@ BOOL ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich, while ( rPosY>0 && nClickY < nScrY ) { --rPosY; - nScrY -= ToPixel( pDoc->FastGetRowHeight( rPosY, nTabNo ), nPPTY ); + nScrY -= ToPixel( pDoc->GetRowHeight( rPosY, nTabNo ), nPPTY ); } } @@ -1973,14 +1988,14 @@ void ScViewData::SetPosY( ScVSplitPos eWhich, SCROW nNewPosY ) if ( nNewPosY > nOldPosY ) for ( i=nOldPosY; i<nNewPosY; i++ ) { - long nThis = pDoc->FastGetRowHeight( i,nTabNo ); + long nThis = pDoc->GetRowHeight( i,nTabNo ); nTPosY -= nThis; nPixPosY -= ToPixel(sal::static_int_cast<USHORT>(nThis), nPPTY); } else for ( i=nNewPosY; i<nOldPosY; i++ ) { - long nThis = pDoc->FastGetRowHeight( i,nTabNo ); + long nThis = pDoc->GetRowHeight( i,nTabNo ); nTPosY += nThis; nPixPosY += ToPixel(sal::static_int_cast<USHORT>(nThis), nPPTY); } @@ -2010,7 +2025,7 @@ void ScViewData::RecalcPixPos() // nach Zoom-Aenderungen long nPixPosY = 0; SCROW nPosY = pThisTab->nPosY[eWhich]; for (SCROW j=0; j<nPosY; j++) - nPixPosY -= ToPixel(pDoc->FastGetRowHeight(j,nTabNo), nPPTY); + nPixPosY -= ToPixel(pDoc->GetRowHeight(j,nTabNo), nPPTY); pThisTab->nPixPosY[eWhich] = nPixPosY; } } @@ -2053,7 +2068,7 @@ void ScViewData::SetScreen( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) for (nRow=nRow1; nRow<=nRow2; nRow++) { - nTSize = pDoc->FastGetRowHeight( nRow, nTabNo ); + nTSize = pDoc->GetRowHeight( nRow, nTabNo ); if (nTSize) { nSizePix = ToPixel( nTSize, nPPTY ); @@ -2095,7 +2110,7 @@ void ScViewData::SetScreenPos( const Point& rVisAreaStart ) bEnd = FALSE; while (!bEnd) { - nAdd = (long) pDoc->FastGetRowHeight(nY1,nTabNo); + nAdd = (long) pDoc->GetRowHeight(nY1,nTabNo); if (nSize+nAdd <= nTwips+1 && nY1<MAXROW) { nSize += nAdd; @@ -3047,7 +3062,7 @@ BOOL ScViewData::UpdateFixY( SCTAB nTab ) // TRUE = Wert geaendert long nNewPos = 0; for (SCROW nY=pTabData[nTab]->nPosY[SC_SPLIT_TOP]; nY<nFix; nY++) { - USHORT nTSize = pLocalDoc->FastGetRowHeight( nY, nTab ); + USHORT nTSize = pLocalDoc->GetRowHeight( nY, nTab ); if (nTSize) { long nPix = ToPixel( nTSize, nPPTY ); diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx index 11ecfa5aae8c..34fbbfdad5b5 100644 --- a/sc/source/ui/view/viewfun2.cxx +++ b/sc/source/ui/view/viewfun2.cxx @@ -86,6 +86,7 @@ #include "funcdesc.hxx" #include "docuno.hxx" #include "charthelper.hxx" +#include "tabbgcolor.hxx" #include <basic/sbstar.hxx> #include <com/sun/star/container/XNameContainer.hpp> @@ -2201,6 +2202,8 @@ BOOL ScViewFunc::DeleteTables(const SvShorts &TheTabs, BOOL bRecord ) pUndoDoc->SetActiveScenario( nTab, bActive ); } pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) ); + pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) ); + pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) ); if ( pDoc->IsTabProtected( nTab ) ) pUndoDoc->SetTabProtection(nTab, pDoc->GetTabProtection(nTab)); @@ -2291,6 +2294,28 @@ BOOL ScViewFunc::RenameTable( const String& rName, SCTAB nTab ) //---------------------------------------------------------------------------- +bool ScViewFunc::SetTabBgColor( const Color& rColor, SCTAB nTab ) +{ + bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( nTab, rColor, TRUE, FALSE ); + if (bSuccess) + { + GetViewData()->GetViewShell()->UpdateInputHandler(); + } + return bSuccess; +} + +bool ScViewFunc::SetTabBgColor( ScUndoTabColorInfo::List& rUndoSetTabBgColorInfoList ) +{ + bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( rUndoSetTabBgColorInfoList, TRUE, FALSE ); + if (bSuccess) + { + GetViewData()->GetViewShell()->UpdateInputHandler(); + } + return bSuccess; +} + +//---------------------------------------------------------------------------- + void ScViewFunc::InsertAreaLink( const String& rFile, const String& rFilter, const String& rOptions, const String& rSource, ULONG nRefresh ) diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx index dacb41cd1aea..24fab9ac2eba 100644 --- a/sc/source/ui/view/viewfun3.cxx +++ b/sc/source/ui/view/viewfun3.cxx @@ -1723,10 +1723,10 @@ BOOL ScViewFunc::MoveBlockTo( const ScRange& rSource, const ScAddress& rDestPos, BOOL bIncludeFiltered = bCut; if ( !bIncludeFiltered ) { - // manually find number of non-filtered rows - SCROW nPastedCount = pDocSh->GetDocument()->GetRowFlagsArray( - rSource.aStart.Tab()).CountForCondition( - rSource.aStart.Row(), rSource.aEnd.Row(), CR_FILTERED, 0); + // find number of non-filtered rows + SCROW nPastedCount = pDocSh->GetDocument()->CountNonFilteredRows( + rSource.aStart.Row(), rSource.aEnd.Row(), rSource.aStart.Tab()); + if ( nPastedCount == 0 ) nPastedCount = 1; aDestEnd.SetRow( rDestPos.Row() + nPastedCount - 1 ); diff --git a/sc/source/ui/view/viewfun5.cxx b/sc/source/ui/view/viewfun5.cxx index 9697cae3a57e..dc4e96bbbf34 100644 --- a/sc/source/ui/view/viewfun5.cxx +++ b/sc/source/ui/view/viewfun5.cxx @@ -110,7 +110,7 @@ BOOL ScViewFunc::PasteDataFormat( ULONG nFormatId, nXT += pDoc->GetColWidth(i,nTab); if (pDoc->IsNegativePage(nTab)) nXT = -nXT; - ULONG nYT = pDoc->FastGetRowHeight( 0, nPosY-1, nTab); + ULONG nYT = pDoc->GetRowHeight( 0, nPosY-1, nTab); aPos = Point( (long)(nXT * HMM_PER_TWIPS), (long)(nYT * HMM_PER_TWIPS) ); } } diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx index 5d3bf97aa29c..231eb4e67562 100644 --- a/sc/source/ui/view/viewfunc.cxx +++ b/sc/source/ui/view/viewfunc.cxx @@ -2195,28 +2195,19 @@ void ScViewFunc::SetWidthOrHeight( BOOL bWidth, SCCOLROW nRangeCnt, SCCOLROW* pR { // fuer alle eingeblendeten CR_MANUALSIZE loeschen, // dann SetOptimalHeight mit bShrink = FALSE - ScCompressedArrayIterator< SCROW, BYTE> aIter( - pDoc->GetRowFlagsArray( nTab), nStartNo, - nEndNo); - do + for (SCROW nRow = nStartNo; nRow <= nEndNo; ++nRow) { - BYTE nOld = *aIter; - if ( (nOld & CR_HIDDEN) == 0 && ( nOld & CR_MANUALSIZE ) ) + SCROW nLastRow = nRow; + if (pDoc->RowHidden(nRow, nTab, NULL, &nLastRow)) { - SCROW nRangeEnd = aIter.GetRangeEnd(); - pDoc->SetRowFlags( aIter.GetRangeStart(), - nRangeEnd, nTab, - nOld & ~CR_MANUALSIZE); - aIter.Resync( nRangeEnd); - // Range may be extended due to merges and - // now aIter.GetRangeEnd() may point behind - // the previous row, but all flags of this - // range have the CR_MANUALSIZE bit - // removed, so it is safe to continue with - // the next range, not necessary to catch - // up with the remaining rows. + nRow = nLastRow; + continue; } - } while (aIter.NextRange()); + + BYTE nOld = pDoc->GetRowFlags(nRow, nTab); + if (nOld & CR_MANUALSIZE) + pDoc->SetRowFlags(nRow, nTab, nOld & ~CR_MANUALSIZE); + } } double nPPTX = GetViewData()->GetPPTX(); @@ -2258,8 +2249,7 @@ void ScViewFunc::SetWidthOrHeight( BOOL bWidth, SCCOLROW nRangeCnt, SCCOLROW* pR { for (SCCOL nCol=static_cast<SCCOL>(nStartNo); nCol<=static_cast<SCCOL>(nEndNo); nCol++) { - if ( eMode != SC_SIZE_VISOPT || - (pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN) == 0 ) + if ( eMode != SC_SIZE_VISOPT || !pDoc->ColHidden(nCol, nTab) ) { USHORT nThisSize = nSizeTwips; diff --git a/sc/source/ui/view/viewutil.cxx b/sc/source/ui/view/viewutil.cxx index d887aec8bc5b..a6b4e320d3ab 100644 --- a/sc/source/ui/view/viewutil.cxx +++ b/sc/source/ui/view/viewutil.cxx @@ -271,20 +271,19 @@ void ScViewUtil::UnmarkFiltered( ScMarkData& rMark, ScDocument* pDoc ) for (SCTAB nTab=0; nTab<nTabCount; nTab++) if ( rMark.GetTableSelect(nTab ) ) { - ScCompressedArrayIterator<SCROW, BYTE> aIter(pDoc->GetRowFlagsArray(nTab), nStartRow, nEndRow); - do + for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow) { - if (*aIter & CR_FILTERED) + SCROW nLastRow = nRow; + if (pDoc->RowFiltered(nRow, nTab, NULL, &nLastRow)) { // use nStartCol/nEndCol, so the multi mark area isn't extended to all columns // (visible in repaint for indentation) - - rMark.SetMultiMarkArea( ScRange( nStartCol, aIter.GetRangeStart(), nTab, - nEndCol, aIter.GetRangeEnd(), nTab ), FALSE ); + rMark.SetMultiMarkArea( + ScRange(nStartCol, nRow, nTab, nEndCol, nLastRow, nTab), false); bChanged = true; + nRow = nLastRow; } } - while (aIter.NextRange()); } if ( bChanged && !rMark.HasAnyMultiMarks() ) @@ -295,34 +294,29 @@ void ScViewUtil::UnmarkFiltered( ScMarkData& rMark, ScDocument* pDoc ) // static -bool ScViewUtil::FitToUnfilteredRows( ScRange & rRange, const ScDocument * pDoc, size_t nRows ) +bool ScViewUtil::FitToUnfilteredRows( ScRange & rRange, ScDocument * pDoc, size_t nRows ) { SCTAB nTab = rRange.aStart.Tab(); bool bOneTabOnly = (nTab == rRange.aEnd.Tab()); // Always fit the range on its first sheet. DBG_ASSERT( bOneTabOnly, "ScViewUtil::ExtendToUnfilteredRows: works only on one sheet"); SCROW nStartRow = rRange.aStart.Row(); - // FillArrayForCondition() usually is the fastest to determine such a set - // in one pass, even if the array isn't used but the last element. - SCROW* pArr = new SCROW[nRows]; - size_t nCount = pDoc->GetRowFlagsArray( nTab).FillArrayForCondition( - nStartRow, MAXROW, CR_FILTERED, 0, pArr, nRows); - if (nCount) - rRange.aEnd.SetRow( pArr[nCount-1]); - delete [] pArr; - return nCount == nRows && bOneTabOnly; + SCROW nLastRow = pDoc->LastNonFilteredRow(nStartRow, MAXROW, nTab); + if (ValidRow(nLastRow)) + rRange.aEnd.SetRow(nLastRow); + SCROW nCount = pDoc->CountNonFilteredRows(nStartRow, MAXROW, nTab); + return static_cast<size_t>(nCount) == nRows && bOneTabOnly; } // static -bool ScViewUtil::HasFiltered( const ScRange& rRange, const ScDocument* pDoc ) +bool ScViewUtil::HasFiltered( const ScRange& rRange, ScDocument* pDoc ) { SCROW nStartRow = rRange.aStart.Row(); SCROW nEndRow = rRange.aEnd.Row(); for (SCTAB nTab=rRange.aStart.Tab(); nTab<=rRange.aEnd.Tab(); nTab++) { - if ( pDoc->GetRowFlagsArray( nTab).HasCondition( nStartRow, nEndRow, - CR_FILTERED, CR_FILTERED ) ) + if (pDoc->HasFilteredRows(nStartRow, nEndRow, nTab)) return true; } |