summaryrefslogtreecommitdiff
path: root/sc/source/ui/view
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/view')
-rw-r--r--sc/source/ui/view/auditsh.cxx155
-rw-r--r--sc/source/ui/view/cellsh.cxx1002
-rw-r--r--sc/source/ui/view/cellsh1.cxx2206
-rw-r--r--sc/source/ui/view/cellsh2.cxx1432
-rw-r--r--sc/source/ui/view/cellsh3.cxx966
-rw-r--r--sc/source/ui/view/cellsh4.cxx382
-rw-r--r--sc/source/ui/view/colrowba.cxx419
-rw-r--r--sc/source/ui/view/dbfunc.cxx512
-rw-r--r--sc/source/ui/view/dbfunc2.cxx77
-rw-r--r--sc/source/ui/view/dbfunc3.cxx2375
-rw-r--r--sc/source/ui/view/dbfunc4.cxx102
-rw-r--r--sc/source/ui/view/drawattr.cxx82
-rw-r--r--sc/source/ui/view/drawutil.cxx116
-rw-r--r--sc/source/ui/view/drawvie2.cxx62
-rw-r--r--sc/source/ui/view/drawvie3.cxx182
-rw-r--r--sc/source/ui/view/drawvie4.cxx394
-rw-r--r--sc/source/ui/view/drawview.cxx845
-rw-r--r--sc/source/ui/view/editsh.cxx1206
-rw-r--r--sc/source/ui/view/formatsh.cxx2165
-rw-r--r--sc/source/ui/view/galwrap.cxx79
-rw-r--r--sc/source/ui/view/gridmerg.cxx174
-rw-r--r--sc/source/ui/view/gridwin.cxx5706
-rw-r--r--sc/source/ui/view/gridwin2.cxx1061
-rw-r--r--sc/source/ui/view/gridwin3.cxx443
-rw-r--r--sc/source/ui/view/gridwin4.cxx2069
-rw-r--r--sc/source/ui/view/gridwin5.cxx439
-rw-r--r--sc/source/ui/view/hdrcont.cxx1046
-rw-r--r--sc/source/ui/view/hintwin.cxx108
-rw-r--r--sc/source/ui/view/imapwrap.cxx76
-rw-r--r--sc/source/ui/view/invmerge.cxx192
-rw-r--r--sc/source/ui/view/makefile.mk173
-rw-r--r--sc/source/ui/view/notemark.cxx200
-rw-r--r--sc/source/ui/view/olinewin.cxx1045
-rw-r--r--sc/source/ui/view/olkact.cxx282
-rw-r--r--sc/source/ui/view/output.cxx2476
-rw-r--r--sc/source/ui/view/output2.cxx3705
-rw-r--r--sc/source/ui/view/output3.cxx276
-rw-r--r--sc/source/ui/view/pfuncache.cxx198
-rw-r--r--sc/source/ui/view/pgbrksh.cxx85
-rw-r--r--sc/source/ui/view/pivotsh.cxx204
-rw-r--r--sc/source/ui/view/preview.cxx1603
-rw-r--r--sc/source/ui/view/prevloc.cxx792
-rw-r--r--sc/source/ui/view/prevwsh.cxx1145
-rw-r--r--sc/source/ui/view/prevwsh2.cxx353
-rw-r--r--sc/source/ui/view/printfun.cxx3202
-rw-r--r--sc/source/ui/view/reffact.cxx434
-rw-r--r--sc/source/ui/view/scextopt.cxx224
-rw-r--r--sc/source/ui/view/select.cxx891
-rw-r--r--sc/source/ui/view/selectionstate.cxx89
-rw-r--r--sc/source/ui/view/spelldialog.cxx279
-rw-r--r--sc/source/ui/view/spelleng.cxx458
-rw-r--r--sc/source/ui/view/tabcont.cxx638
-rw-r--r--sc/source/ui/view/tabpopsh.cxx72
-rw-r--r--sc/source/ui/view/tabsplit.cxx105
-rw-r--r--sc/source/ui/view/tabview.cxx2535
-rw-r--r--sc/source/ui/view/tabview2.cxx982
-rw-r--r--sc/source/ui/view/tabview3.cxx2792
-rw-r--r--sc/source/ui/view/tabview4.cxx573
-rw-r--r--sc/source/ui/view/tabview5.cxx722
-rw-r--r--sc/source/ui/view/tabvwsh.cxx111
-rw-r--r--sc/source/ui/view/tabvwsh2.cxx481
-rw-r--r--sc/source/ui/view/tabvwsh3.cxx1234
-rw-r--r--sc/source/ui/view/tabvwsh4.cxx1990
-rw-r--r--sc/source/ui/view/tabvwsh5.cxx429
-rw-r--r--sc/source/ui/view/tabvwsh8.cxx104
-rw-r--r--sc/source/ui/view/tabvwsh9.cxx295
-rw-r--r--sc/source/ui/view/tabvwsha.cxx803
-rw-r--r--sc/source/ui/view/tabvwshb.cxx586
-rw-r--r--sc/source/ui/view/tabvwshc.cxx327
-rw-r--r--sc/source/ui/view/tabvwshd.cxx100
-rw-r--r--sc/source/ui/view/tabvwshe.cxx343
-rw-r--r--sc/source/ui/view/tabvwshf.cxx964
-rw-r--r--sc/source/ui/view/tabvwshg.cxx140
-rw-r--r--sc/source/ui/view/tabvwshh.cxx293
-rw-r--r--sc/source/ui/view/viewdata.cxx3179
-rw-r--r--sc/source/ui/view/viewfun2.cxx3144
-rw-r--r--sc/source/ui/view/viewfun3.cxx1837
-rw-r--r--sc/source/ui/view/viewfun4.cxx848
-rw-r--r--sc/source/ui/view/viewfun5.cxx749
-rw-r--r--sc/source/ui/view/viewfun6.cxx197
-rw-r--r--sc/source/ui/view/viewfun7.cxx492
-rw-r--r--sc/source/ui/view/viewfunc.cxx3018
-rw-r--r--sc/source/ui/view/viewutil.cxx640
-rw-r--r--sc/source/ui/view/waitoff.cxx70
84 files changed, 74980 insertions, 0 deletions
diff --git a/sc/source/ui/view/auditsh.cxx b/sc/source/ui/view/auditsh.cxx
new file mode 100644
index 000000000000..12851346be2e
--- /dev/null
+++ b/sc/source/ui/view/auditsh.cxx
@@ -0,0 +1,155 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svl/srchitem.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/request.hxx>
+
+#include "auditsh.hxx"
+#include "tabvwsh.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "document.hxx"
+
+//------------------------------------------------------------------------
+
+#define ScAuditingShell
+#include "scslots.hxx"
+
+//------------------------------------------------------------------------
+
+TYPEINIT1( ScAuditingShell, SfxShell );
+
+SFX_IMPL_INTERFACE(ScAuditingShell, SfxShell, ScResId(SCSTR_AUDITSHELL))
+{
+ SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_AUDIT) );
+}
+
+
+//------------------------------------------------------------------------
+
+ScAuditingShell::ScAuditingShell(ScViewData* pData) :
+ SfxShell(pData->GetViewShell()),
+ pViewData( pData ),
+ nFunction( SID_FILL_ADD_PRED )
+{
+ SetPool( &pViewData->GetViewShell()->GetPool() );
+ ::svl::IUndoManager* pMgr = pViewData->GetSfxDocShell()->GetUndoManager();
+ SetUndoManager( pMgr );
+ if ( !pViewData->GetDocument()->IsUndoEnabled() )
+ {
+ pMgr->SetMaxUndoActionCount( 0 );
+ }
+ SetHelpId( HID_SCSHELL_AUDIT );
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Auditing")));
+}
+
+//------------------------------------------------------------------------
+
+ScAuditingShell::~ScAuditingShell()
+{
+}
+
+//------------------------------------------------------------------------
+
+void ScAuditingShell::Execute( SfxRequest& rReq )
+{
+ SfxBindings& rBindings = pViewData->GetBindings();
+ sal_uInt16 nSlot = rReq.GetSlot();
+ switch ( nSlot )
+ {
+ case SID_FILL_ADD_PRED:
+ case SID_FILL_DEL_PRED:
+ case SID_FILL_ADD_SUCC:
+ case SID_FILL_DEL_SUCC:
+ nFunction = nSlot;
+ rBindings.Invalidate( SID_FILL_ADD_PRED );
+ rBindings.Invalidate( SID_FILL_DEL_PRED );
+ rBindings.Invalidate( SID_FILL_ADD_SUCC );
+ rBindings.Invalidate( SID_FILL_DEL_SUCC );
+ break;
+ case SID_CANCEL: // Escape
+ case SID_FILL_NONE:
+ pViewData->GetViewShell()->SetAuditShell( sal_False );
+ break;
+
+ case SID_FILL_SELECT:
+ {
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ if ( pReqArgs )
+ {
+ const SfxPoolItem* pXItem;
+ const SfxPoolItem* pYItem;
+ if ( pReqArgs->GetItemState( SID_RANGE_COL, sal_True, &pXItem ) == SFX_ITEM_SET
+ && pReqArgs->GetItemState( SID_RANGE_ROW, sal_True, &pYItem ) == SFX_ITEM_SET )
+ {
+ DBG_ASSERT( pXItem->ISA(SfxInt16Item) && pYItem->ISA(SfxInt32Item),
+ "falsche Items" );
+ SCsCOL nCol = static_cast<SCsCOL>(((const SfxInt16Item*) pXItem)->GetValue());
+ SCsROW nRow = static_cast<SCsROW>(((const SfxInt32Item*) pYItem)->GetValue());
+ ScViewFunc* pView = pViewData->GetView();
+ pView->MoveCursorAbs( nCol, nRow, SC_FOLLOW_LINE, sal_False, sal_False );
+ switch ( nFunction )
+ {
+ case SID_FILL_ADD_PRED:
+ pView->DetectiveAddPred();
+ break;
+ case SID_FILL_DEL_PRED:
+ pView->DetectiveDelPred();
+ break;
+ case SID_FILL_ADD_SUCC:
+ pView->DetectiveAddSucc();
+ break;
+ case SID_FILL_DEL_SUCC:
+ pView->DetectiveDelSucc();
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScAuditingShell::GetState( SfxItemSet& rSet )
+{
+ rSet.Put( SfxBoolItem( nFunction, sal_True ) ); // aktive Funktion markieren
+}
+
+
diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx
new file mode 100644
index 000000000000..20f65bd03e93
--- /dev/null
+++ b/sc/source/ui/view/cellsh.cxx
@@ -0,0 +1,1002 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+
+#include <svl/slstitm.hxx>
+#include <svl/stritem.hxx>
+#include <svl/whiter.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <svtools/cliplistener.hxx>
+#include <svtools/insdlg.hxx>
+#include <sot/formats.hxx>
+#include <svx/hlnkitem.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/childwin.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svx/clipfmtitem.hxx>
+#include <editeng/langitem.hxx>
+
+#include "cellsh.hxx"
+#include "sc.hrc"
+#include "docsh.hxx"
+#include "attrib.hxx"
+#include "scresid.hxx"
+#include "tabvwsh.hxx"
+#include "impex.hxx"
+#include "cell.hxx"
+#include "scmod.hxx"
+#include "globstr.hrc"
+#include "transobj.hxx"
+#include "drwtrans.hxx"
+#include "scabstdlg.hxx"
+#include "dociter.hxx"
+#include "postit.hxx"
+
+//------------------------------------------------------------------
+
+#define ScCellShell
+#define CellMovement
+#include "scslots.hxx"
+
+TYPEINIT1( ScCellShell, ScFormatShell );
+
+SFX_IMPL_INTERFACE(ScCellShell, ScFormatShell , ScResId(SCSTR_CELLSHELL) )
+{
+ SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT | SFX_VISIBILITY_STANDARD |
+ SFX_VISIBILITY_SERVER,
+ ScResId(RID_OBJECTBAR_FORMAT));
+ SFX_POPUPMENU_REGISTRATION(ScResId(RID_POPUP_CELLS));
+}
+
+
+ScCellShell::ScCellShell(ScViewData* pData) :
+ ScFormatShell(pData),
+ pImpl( new CellShell_Impl() ),
+ bPastePossible(sal_False)
+{
+ SetHelpId(HID_SCSHELL_CELLSH);
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Cell")));
+}
+
+ScCellShell::~ScCellShell()
+{
+ if ( pImpl->m_pClipEvtLstnr )
+ {
+ pImpl->m_pClipEvtLstnr->AddRemoveListener( GetViewData()->GetActiveWin(), sal_False );
+
+ // #103849# The listener may just now be waiting for the SolarMutex and call the link
+ // afterwards, in spite of RemoveListener. So the link has to be reset, too.
+ pImpl->m_pClipEvtLstnr->ClearCallbackLink();
+
+ pImpl->m_pClipEvtLstnr->release();
+ }
+
+ delete pImpl->m_pLinkedDlg;
+ delete pImpl->m_pRequest;
+ delete pImpl;
+}
+
+//------------------------------------------------------------------
+
+void ScCellShell::GetBlockState( SfxItemSet& rSet )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ ScRange aMarkRange;
+ ScMarkType eMarkType = GetViewData()->GetSimpleArea( aMarkRange );
+ sal_Bool bSimpleArea = (eMarkType == SC_MARK_SIMPLE);
+ sal_Bool bOnlyNotBecauseOfMatrix;
+ sal_Bool bEditable = pTabViewShell->SelectionEditable( &bOnlyNotBecauseOfMatrix );
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ nCol1 = aMarkRange.aStart.Col();
+ nRow1 = aMarkRange.aStart.Row();
+ nCol2 = aMarkRange.aEnd.Col();
+ nRow2 = aMarkRange.aEnd.Row();
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ sal_Bool bDisable = sal_False;
+ sal_Bool bNeedEdit = sal_True; // muss Selektion editierbar sein?
+ switch ( nWhich )
+ {
+ case FID_FILL_TO_BOTTOM: // Fuellen oben/unten
+ case FID_FILL_TO_TOP: // mind. 2 Zeilen markiert?
+ bDisable = (!bSimpleArea) || (nRow1 == nRow2);
+ if ( !bDisable && bEditable )
+ { // Matrix nicht zerreissen
+ if ( nWhich == FID_FILL_TO_BOTTOM )
+ bDisable = pDoc->HasSelectedBlockMatrixFragment(
+ nCol1, nRow1, nCol2, nRow1, rMark ); // erste Zeile
+ else
+ bDisable = pDoc->HasSelectedBlockMatrixFragment(
+ nCol1, nRow2, nCol2, nRow2, rMark ); // letzte Zeile
+ }
+ break;
+
+ case FID_FILL_TO_RIGHT: // Fuellen links/rechts
+ case FID_FILL_TO_LEFT: // mind. 2 Spalten markiert?
+ bDisable = (!bSimpleArea) || (nCol1 == nCol2);
+ if ( !bDisable && bEditable )
+ { // Matrix nicht zerreissen
+ if ( nWhich == FID_FILL_TO_RIGHT )
+ bDisable = pDoc->HasSelectedBlockMatrixFragment(
+ nCol1, nRow1, nCol1, nRow2, rMark ); // erste Spalte
+ else
+ bDisable = pDoc->HasSelectedBlockMatrixFragment(
+ nCol2, nRow1, nCol2, nRow2, rMark ); // letzte Spalte
+ }
+ break;
+
+ case FID_FILL_SERIES: // Block fuellen
+ case SID_OPENDLG_TABOP: // Mehrfachoperationen, mind. 2 Zellen markiert?
+ if (pDoc->GetChangeTrack()!=NULL &&nWhich ==SID_OPENDLG_TABOP)
+ bDisable = sal_True;
+ else
+ bDisable = (!bSimpleArea) || (nCol1 == nCol2 && nRow1 == nRow2);
+
+ if ( !bDisable && bEditable && nWhich == FID_FILL_SERIES )
+ { // Matrix nicht zerreissen
+ bDisable = pDoc->HasSelectedBlockMatrixFragment(
+ nCol1, nRow1, nCol2, nRow1, rMark ) // erste Zeile
+ || pDoc->HasSelectedBlockMatrixFragment(
+ nCol1, nRow2, nCol2, nRow2, rMark ) // letzte Zeile
+ || pDoc->HasSelectedBlockMatrixFragment(
+ nCol1, nRow1, nCol1, nRow2, rMark ) // erste Spalte
+ || pDoc->HasSelectedBlockMatrixFragment(
+ nCol2, nRow1, nCol2, nRow2, rMark ); // letzte Spalte
+ }
+ break;
+
+ case SID_CUT: // Ausschneiden,
+ case FID_INS_CELL: // Zellen einfuegen, nur einf. Selektion
+ bDisable = (!bSimpleArea);
+ break;
+
+ case FID_INS_ROW: // insert rows
+ case FID_INS_CELLSDOWN:
+ bDisable = (!bSimpleArea) || GetViewData()->SimpleColMarked();
+ break;
+
+ case FID_INS_COLUMN: // insert columns
+ case FID_INS_CELLSRIGHT:
+ bDisable = (!bSimpleArea) || GetViewData()->SimpleRowMarked();
+ break;
+
+ case SID_COPY: // Kopieren
+ // nur wegen Matrix nicht editierbar? Matrix nicht zerreissen
+ //! schlaegt nicht zu, wenn geschuetzt UND Matrix, aber damit
+ //! muss man leben.. wird in Copy-Routine abgefangen, sonst
+ //! muesste hier nochmal Aufwand getrieben werden
+ if ( !(!bEditable && bOnlyNotBecauseOfMatrix) )
+ bNeedEdit = sal_False; // erlaubt, wenn geschuetzt/ReadOnly
+ break;
+
+ case SID_AUTOFORMAT: // Autoformat, mind. 3x3 selektiert
+ bDisable = (!bSimpleArea)
+ || ((nCol2 - nCol1) < 2) || ((nRow2 - nRow1) < 2);
+ break;
+
+ case SID_OPENDLG_CONDFRMT :
+ {
+ if ( !bEditable && bOnlyNotBecauseOfMatrix )
+ {
+ bNeedEdit = sal_False;
+ }
+ if ( pDocShell && pDocShell->IsDocShared() )
+ {
+ bDisable = sal_True;
+ }
+ }
+ break;
+
+ case FID_CONDITIONAL_FORMAT :
+ case SID_CELL_FORMAT_RESET :
+ case FID_CELL_FORMAT :
+ case SID_ENABLE_HYPHENATION :
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ if ( !bEditable && bOnlyNotBecauseOfMatrix )
+ bNeedEdit = sal_False;
+ break;
+
+ case FID_VALIDATION:
+ {
+ if ( pDocShell && pDocShell->IsDocShared() )
+ {
+ bDisable = sal_True;
+ }
+ }
+ break;
+
+ case SID_TRANSLITERATE_HALFWIDTH:
+ case SID_TRANSLITERATE_FULLWIDTH:
+ case SID_TRANSLITERATE_HIRAGANA:
+ case SID_TRANSLITERATE_KATAGANA:
+ ScViewUtil::HideDisabledSlot( rSet, GetViewData()->GetBindings(), nWhich );
+ break;
+ }
+ if (!bDisable && bNeedEdit && !bEditable)
+ bDisable = sal_True;
+
+ if (bDisable)
+ rSet.DisableItem(nWhich);
+ else if (nWhich == SID_ENABLE_HYPHENATION)
+ {
+ // toggle slots need a bool item
+ rSet.Put( SfxBoolItem( nWhich, sal_False ) );
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+// Funktionen, die je nach Cursorposition disabled sind
+// Default:
+// SID_INSERT_POSTIT, SID_CHARMAP, SID_OPENDLG_FUNCTION
+
+void ScCellShell::GetCellState( SfxItemSet& rSet )
+{
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
+ ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
+ GetViewData()->GetTabNo() );
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ sal_Bool bDisable = sal_False;
+ sal_Bool bNeedEdit = sal_True; // muss Cursorposition editierbar sein?
+ switch ( nWhich )
+ {
+ case SID_THESAURUS:
+ {
+ CellType eType = pDoc->GetCellType( aCursor );
+ bDisable = ( eType != CELLTYPE_STRING && eType != CELLTYPE_EDIT);
+ if (!bDisable)
+ {
+ // test for available languages
+ sal_uInt16 nLang = ScViewUtil::GetEffLanguage( pDoc, aCursor );
+ bDisable = !ScModule::HasThesaurusLanguage( nLang );
+ }
+ }
+ break;
+ case SID_OPENDLG_FUNCTION:
+ {
+ ScMarkData aMarkData=GetViewData()->GetMarkData();
+ aMarkData.MarkToSimple();
+ ScRange aRange;
+ aMarkData.GetMarkArea(aRange);
+ if(aMarkData.IsMarked())
+ {
+ if (!pDoc->IsBlockEditable( aCursor.Tab(), aRange.aStart.Col(),aRange.aStart.Row(),
+ aRange.aEnd.Col(),aRange.aEnd.Row() ))
+ {
+ bDisable = sal_True;
+ }
+ bNeedEdit=sal_False;
+ }
+
+ }
+ break;
+ case SID_INSERT_POSTIT:
+ {
+ if ( pDocShell && pDocShell->IsDocShared() )
+ {
+ bDisable = sal_True;
+ }
+ }
+ break;
+ }
+ if (!bDisable && bNeedEdit)
+ if (!pDoc->IsBlockEditable( aCursor.Tab(), aCursor.Col(),aCursor.Row(),
+ aCursor.Col(),aCursor.Row() ))
+ bDisable = sal_True;
+ if (bDisable)
+ rSet.DisableItem(nWhich);
+ nWhich = aIter.NextWhich();
+ }
+}
+
+sal_Bool lcl_TestFormat( SvxClipboardFmtItem& rFormats, const TransferableDataHelper& rDataHelper,
+ SotFormatStringId nFormatId )
+{
+ if ( rDataHelper.HasFormat( nFormatId ) )
+ {
+ // #90675# translated format name strings are no longer inserted here,
+ // handled by "paste special" dialog / toolbox controller instead.
+ // Only the object type name has to be set here:
+ String aStrVal;
+ if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE )
+ {
+ TransferableObjectDescriptor aDesc;
+ if ( ((TransferableDataHelper&)rDataHelper).GetTransferableObjectDescriptor(
+ SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aDesc ) )
+ aStrVal = aDesc.maTypeName;
+ }
+ else if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE_OLE
+ || nFormatId == SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE )
+ {
+ String aSource;
+ SvPasteObjectHelper::GetEmbeddedName( rDataHelper, aStrVal, aSource, nFormatId );
+ }
+
+ if ( aStrVal.Len() )
+ rFormats.AddClipbrdFormat( nFormatId, aStrVal );
+ else
+ rFormats.AddClipbrdFormat( nFormatId );
+
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+void ScCellShell::GetPossibleClipboardFormats( SvxClipboardFmtItem& rFormats )
+{
+ Window* pWin = GetViewData()->GetActiveWin();
+ sal_Bool bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != NULL );
+
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
+
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DRAWING );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_SVXB );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_GDIMETAFILE );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_BITMAP );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE );
+
+ if ( !bDraw )
+ {
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_LINK );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_STRING );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_DIF );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMAT_RTF );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_HTML_SIMPLE );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_8 );
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_BIFF_5 );
+ }
+
+ if ( !lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) )
+ lcl_TestFormat( rFormats, aDataHelper, SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE );
+}
+
+// Einfuegen, Inhalte einfuegen
+
+sal_Bool lcl_IsCellPastePossible( const TransferableDataHelper& rData )
+{
+ sal_Bool bPossible = sal_False;
+ if ( ScTransferObj::GetOwnClipboard( NULL ) || ScDrawTransferObj::GetOwnClipboard( NULL ) )
+ bPossible = sal_True;
+ else
+ {
+ if ( rData.HasFormat( SOT_FORMAT_BITMAP ) ||
+ rData.HasFormat( SOT_FORMAT_GDIMETAFILE ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_SVXB ) ||
+ rData.HasFormat( FORMAT_PRIVATE ) ||
+ rData.HasFormat( SOT_FORMAT_RTF ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ||
+ rData.HasFormat( SOT_FORMAT_STRING ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_SYLK ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_LINK ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_HTML ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) ||
+ rData.HasFormat( SOT_FORMATSTR_ID_DIF ) )
+ {
+ bPossible = sal_True;
+ }
+ }
+ return bPossible;
+}
+
+IMPL_LINK( ScCellShell, ClipboardChanged, TransferableDataHelper*, pDataHelper )
+{
+ if ( pDataHelper )
+ {
+ bPastePossible = lcl_IsCellPastePossible( *pDataHelper );
+
+ SfxBindings& rBindings = GetViewData()->GetBindings();
+ rBindings.Invalidate( SID_PASTE );
+ rBindings.Invalidate( SID_PASTE_SPECIAL );
+ rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
+ }
+ return 0;
+}
+
+
+void __EXPORT ScCellShell::GetClipState( SfxItemSet& rSet )
+{
+// SID_PASTE
+// SID_PASTE_SPECIAL
+// SID_CLIPBOARD_FORMAT_ITEMS
+
+ if ( !pImpl->m_pClipEvtLstnr )
+ {
+ // create listener
+ pImpl->m_pClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScCellShell, ClipboardChanged ) );
+ pImpl->m_pClipEvtLstnr->acquire();
+ Window* pWin = GetViewData()->GetActiveWin();
+ pImpl->m_pClipEvtLstnr->AddRemoveListener( pWin, sal_True );
+
+ // get initial state
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
+ bPastePossible = lcl_IsCellPastePossible( aDataHelper );
+ }
+
+ sal_Bool bDisable = !bPastePossible;
+
+ // Zellschutz / Multiselektion
+
+ if (!bDisable)
+ {
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
+ if (!pDoc->IsBlockEditable( nTab, nCol,nRow, nCol,nRow ))
+ bDisable = sal_True;
+ ScRange aDummy;
+ ScMarkType eMarkType = GetViewData()->GetSimpleArea( aDummy);
+ if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
+ bDisable = sal_True;
+ }
+
+ if (bDisable)
+ {
+ rSet.DisableItem( SID_PASTE );
+ rSet.DisableItem( SID_PASTE_SPECIAL );
+ rSet.DisableItem( SID_CLIPBOARD_FORMAT_ITEMS );
+ }
+ else if ( rSet.GetItemState( SID_CLIPBOARD_FORMAT_ITEMS ) != SFX_ITEM_UNKNOWN )
+ {
+ SvxClipboardFmtItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
+ GetPossibleClipboardFormats( aFormats );
+ rSet.Put( aFormats );
+ }
+}
+
+// only SID_HYPERLINK_GETLINK:
+
+void ScCellShell::GetHLinkState( SfxItemSet& rSet )
+{
+ // always return an item (or inserting will be disabled)
+ // if the cell at the cursor contains only a link, return that link
+
+ SvxHyperlinkItem aHLinkItem;
+ if ( !GetViewData()->GetView()->HasBookmarkAtCursor( &aHLinkItem ) )
+ {
+ //! put selected text into item?
+ }
+
+ rSet.Put(aHLinkItem);
+}
+
+void ScCellShell::GetState(SfxItemSet &rSet)
+{
+ // removed: SID_BORDER_OBJECT (old Basic)
+
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+// sal_Bool bOle = pTabViewShell->GetViewFrame()->GetFrame().IsInPlace();
+// sal_Bool bTabProt = GetViewData()->GetDocument()->IsTabProtected(GetViewData()->GetTabNo());
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScViewData* pData = GetViewData();
+ ScDocument* pDoc = pData->GetDocument();
+ ScMarkData& rMark = pData->GetMarkData();
+ SCCOL nPosX = pData->GetCurX();
+ SCROW nPosY = pData->GetCurY();
+ SCTAB nTab = pData->GetTabNo();
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+
+
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case SID_DETECTIVE_REFRESH:
+ if (!pDoc->HasDetectiveOperations())
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_RANGE_ADDRESS:
+ {
+ ScRange aRange;
+ if ( pData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
+ {
+ String aStr;
+ sal_uInt16 nFlags = SCA_VALID | SCA_TAB_3D;
+ aRange.Format(aStr,nFlags,pDoc);
+ rSet.Put( SfxStringItem( nWhich, aStr ) );
+ }
+ }
+ break;
+
+ case SID_RANGE_NOTETEXT:
+ {
+ // #43343# always take cursor position, do not use top-left cell of selection
+ ScAddress aPos( nPosX, nPosY, nTab );
+ String aNoteText;
+ if ( const ScPostIt* pNote = pDoc->GetNote( aPos ) )
+ aNoteText = pNote->GetText();
+ rSet.Put( SfxStringItem( nWhich, aNoteText ) );
+ }
+ break;
+
+ case SID_RANGE_ROW:
+ rSet.Put( SfxInt32Item( nWhich, nPosY+1 ) );
+ break;
+
+ case SID_RANGE_COL:
+ rSet.Put( SfxInt16Item( nWhich, nPosX+1 ) );
+ break;
+
+ case SID_RANGE_TABLE:
+ rSet.Put( SfxInt16Item( nWhich, nTab+1 ) );
+ break;
+
+ case SID_RANGE_VALUE:
+ {
+ double nValue;
+ pDoc->GetValue( nPosX, nPosY, nTab, nValue );
+ rSet.Put( ScDoubleItem( nWhich, nValue ) );
+ }
+ break;
+
+ case SID_RANGE_FORMULA:
+ {
+ String aString;
+ pDoc->GetFormula( nPosX, nPosY, nTab, aString );
+ if( aString.Len() == 0 )
+ {
+ pDoc->GetInputString( nPosX, nPosY, nTab, aString );
+ }
+ rSet.Put( SfxStringItem( nWhich, aString ) );
+ }
+ break;
+
+ case SID_RANGE_TEXTVALUE:
+ {
+ String aString;
+ pDoc->GetString( nPosX, nPosY, nTab, aString );
+ rSet.Put( SfxStringItem( nWhich, aString ) );
+ }
+ break;
+
+ case SID_STATUS_SELMODE:
+ {
+ /* 0: STD Click hebt Sel auf
+ * 1: ER Click erweitert Selektion
+ * 2: ERG Click definiert weitere Selektion
+ */
+ sal_uInt16 nMode = pTabViewShell->GetLockedModifiers();
+
+ switch ( nMode )
+ {
+ case KEY_SHIFT: nMode = 1; break;
+ case KEY_MOD1: nMode = 2; break; // Control-Taste
+ case 0:
+ default:
+ nMode = 0;
+ }
+
+ rSet.Put( SfxUInt16Item( nWhich, nMode ) );
+ }
+ break;
+
+ case SID_STATUS_DOCPOS:
+ {
+ String aStr( ScGlobal::GetRscString( STR_TABLE ) );
+
+ aStr += ' ';
+ aStr += String::CreateFromInt32( nTab + 1 );
+ aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " / " ));
+ aStr += String::CreateFromInt32( nTabCount );
+ rSet.Put( SfxStringItem( nWhich, aStr ) );
+ }
+ break;
+
+ // Summe etc. mit Datum/Zeit/Fehler/Pos&Groesse zusammengefasst
+
+ // #i34458# The SfxStringItem belongs only into SID_TABLE_CELL. It no longer has to be
+ // duplicated in SID_ATTR_POSITION or SID_ATTR_SIZE for SvxPosSizeStatusBarControl.
+ case SID_TABLE_CELL:
+ {
+ // Testen, ob Fehler unter Cursor
+ // (nicht pDoc->GetErrCode, um keine zirkulaeren Referenzen auszuloesen)
+
+ // In interpreter may happen via rescheduled Basic
+ if ( pDoc->IsInInterpreter() )
+ rSet.Put( SfxStringItem( nWhich,
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("...")) ) );
+ else
+ {
+ sal_uInt16 nErrCode = 0;
+ ScBaseCell* pCell;
+ pDoc->GetCell( nPosX, nPosY, nTab, pCell );
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
+ if (!pFCell->IsRunning())
+ nErrCode = pFCell->GetErrCode();
+ }
+
+ String aFuncStr;
+ if ( pTabViewShell->GetFunction( aFuncStr, nErrCode ) )
+ rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
+ }
+ }
+ break;
+
+ case SID_DATA_SELECT:
+ // HasSelectionData includes column content and validity,
+ // page fields have to be checked separately.
+ if ( !pDoc->HasSelectionData( nPosX, nPosY, nTab ) &&
+ !pTabViewShell->HasPageFieldDataAtCursor() )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_STATUS_SUM:
+ {
+ String aFuncStr;
+ if ( pTabViewShell->GetFunction( aFuncStr ) )
+ rSet.Put( SfxStringItem( nWhich, aFuncStr ) );
+ }
+ break;
+
+ case FID_MERGE_ON:
+ if ( pDoc->GetChangeTrack() || !pTabViewShell->TestMergeCells() )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_MERGE_OFF:
+ if ( pDoc->GetChangeTrack() || !pTabViewShell->TestRemoveMerge() )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_MERGE_TOGGLE:
+ if ( pDoc->GetChangeTrack() )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ bool bCanMerge = pTabViewShell->TestMergeCells();
+ bool bCanSplit = pTabViewShell->TestRemoveMerge();
+ if( !bCanMerge && !bCanSplit )
+ rSet.DisableItem( nWhich );
+ else
+ rSet.Put( SfxBoolItem( nWhich, bCanSplit ) );
+ }
+ break;
+
+ case FID_INS_ROWBRK:
+ if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_INS_COLBRK:
+ if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_DEL_ROWBRK:
+ if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) == 0 )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_DEL_COLBRK:
+ if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) == 0 )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_FILL_TAB:
+ if ( nTabSelCount < 2 )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_SELECT_SCENARIO:
+ {
+ // ScDocument* pDoc = GetViewData()->GetDocument();
+ // SCTAB nTab = GetViewData()->GetTabNo();
+ List aList;
+
+ Color aDummyCol;
+
+ if ( !pDoc->IsScenario(nTab) )
+ {
+ String aStr;
+ sal_uInt16 nFlags;
+ SCTAB nScTab = nTab + 1;
+ String aProtect;
+ bool bSheetProtected = pDoc->IsTabProtected(nTab);
+
+ while ( pDoc->IsScenario(nScTab) )
+ {
+ pDoc->GetName( nScTab, aStr );
+ aList.Insert( new String( aStr ), LIST_APPEND );
+ pDoc->GetScenarioData( nScTab, aStr, aDummyCol, nFlags );
+ aList.Insert( new String( aStr ), LIST_APPEND );
+ // Protection is sal_True if both Sheet and Scenario are protected
+ aProtect = (bSheetProtected && (nFlags & SC_SCENARIO_PROTECT)) ? '1' : '0';
+ aList.Insert( new String( aProtect), LIST_APPEND );
+ ++nScTab;
+ }
+ }
+ else
+ {
+ String aComment;
+ sal_uInt16 nDummyFlags;
+ pDoc->GetScenarioData( nTab, aComment, aDummyCol, nDummyFlags );
+ DBG_ASSERT( aList.Count() == 0, "List not empty!" );
+ aList.Insert( new String( aComment ) );
+ }
+
+ rSet.Put( SfxStringListItem( nWhich, &aList ) );
+
+ sal_uLong nCount = aList.Count();
+ for ( sal_uLong i=0; i<nCount; i++ )
+ delete (String*) aList.GetObject(i);
+ }
+ break;
+
+ case FID_ROW_HIDE:
+ case FID_ROW_SHOW:
+ case FID_COL_HIDE:
+ case FID_COL_SHOW:
+ case FID_COL_OPT_WIDTH:
+ case FID_ROW_OPT_HEIGHT:
+ case FID_DELETE_CELL:
+ if ( pDoc->IsTabProtected(nTab) || pDocSh->IsReadOnly())
+ rSet.DisableItem( nWhich );
+ break;
+
+/* Zellschutz bei selektierten Zellen wird bei anderen Funktionen auch nicht abgefragt...
+ case SID_DELETE:
+ {
+ if ( pDoc->IsTabProtected(nTab) )
+ {
+ const SfxItemSet& rAttrSet = GetSelectionPattern()->GetItemSet();
+ const ScProtectionAttr& rProtAttr = (const ScProtectionAttr&)rAttrSet.Get( ATTR_PROTECTION, sal_True );
+ if ( rProtAttr.GetProtection() )
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+*/
+ case SID_OUTLINE_MAKE:
+ {
+ if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
+ {
+ //! test for data pilot operation
+ }
+ else if (pDoc->GetChangeTrack()!=NULL || GetViewData()->IsMultiMarked())
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+ case SID_OUTLINE_SHOW:
+ if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
+ {
+ //! test for data pilot operation
+ }
+ else if (!pTabViewShell->OutlinePossible(sal_False))
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_OUTLINE_HIDE:
+ if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
+ {
+ //! test for data pilot operation
+ }
+ else if (!pTabViewShell->OutlinePossible(sal_True))
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_OUTLINE_REMOVE:
+ {
+ if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
+ {
+ //! test for data pilot operation
+ }
+ else
+ {
+ sal_Bool bCol, bRow;
+ pTabViewShell->TestRemoveOutline( bCol, bRow );
+ if ( !bCol && !bRow )
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case FID_COL_WIDTH:
+ {
+ //GetViewData()->GetCurX();
+ SfxUInt16Item aWidthItem( FID_COL_WIDTH, pDoc->GetColWidth( nPosX , nTab) );
+ rSet.Put( aWidthItem );
+ if ( pDocSh->IsReadOnly())
+ rSet.DisableItem( nWhich );
+
+ //XXX Disablen wenn nicht eindeutig
+ }
+ break;
+
+ case FID_ROW_HEIGHT:
+ {
+ //GetViewData()->GetCurY();
+ SfxUInt16Item aHeightItem( FID_ROW_HEIGHT, pDoc->GetRowHeight( nPosY , nTab) );
+ rSet.Put( aHeightItem );
+ //XXX Disablen wenn nicht eindeutig
+ if ( pDocSh->IsReadOnly())
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_DETECTIVE_FILLMODE:
+ rSet.Put(SfxBoolItem( nWhich, pTabViewShell->IsAuditShell() ));
+ break;
+
+ case FID_INPUTLINE_STATUS:
+ DBG_ERROR( "Old update method. Use ScTabViewShell::UpdateInputHandler()." );
+ break;
+
+ case SID_SCENARIOS: // Szenarios:
+ if (!(rMark.IsMarked() || rMark.IsMultiMarked())) // nur, wenn etwas selektiert
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_NOTE_VISIBLE:
+ {
+ const ScPostIt* pNote = pDoc->GetNote( ScAddress( nPosX, nPosY, nTab ) );
+ if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) )
+ rSet.Put( SfxBoolItem( nWhich, pNote->IsCaptionShown() ) );
+ else
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_DELETE_NOTE:
+ {
+ sal_Bool bEnable = sal_False;
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ {
+ if ( pDoc->IsSelectionEditable( rMark ) )
+ {
+ // look for at least one note in selection
+ ScRangeList aRanges;
+ rMark.FillRangeListWithMarks( &aRanges, sal_False );
+ sal_uLong nCount = aRanges.Count();
+ for (sal_uLong nPos=0; nPos<nCount && !bEnable; nPos++)
+ {
+ ScCellIterator aCellIter( pDoc, *aRanges.GetObject(nPos) );
+ for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell && !bEnable; pCell = aCellIter.GetNext() )
+ if ( pCell->HasNote() )
+ bEnable = sal_True; // note found
+ }
+ }
+ }
+ else
+ {
+ bEnable = pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) &&
+ pDoc->GetNote( ScAddress( nPosX, nPosY, nTab ) );
+ }
+ if ( !bEnable )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_OPENDLG_CONSOLIDATE:
+ case SCITEM_CONSOLIDATEDATA:
+ {
+ if(pDoc->GetChangeTrack()!=NULL)
+ rSet.DisableItem( nWhich);
+ }
+ break;
+
+ case SID_CHINESE_CONVERSION:
+ case SID_HANGUL_HANJA_CONVERSION:
+ ScViewUtil::HideDisabledSlot( rSet, pData->GetBindings(), nWhich );
+ break;
+
+ case FID_USE_NAME:
+ {
+ if ( pDocSh && pDocSh->IsDocShared() )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ ScRange aRange;
+ if ( pData->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case FID_DEFINE_NAME:
+ case FID_INSERT_NAME:
+ case SID_DEFINE_COLROWNAMERANGES:
+ {
+ if ( pDocSh && pDocSh->IsDocShared() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case SID_SPELL_DIALOG:
+ {
+ if ( pDoc && pData && pDoc->IsTabProtected( pData->GetTabNo() ) )
+ {
+ bool bVisible = false;
+ SfxViewFrame* pViewFrame = ( pTabViewShell ? pTabViewShell->GetViewFrame() : NULL );
+ if ( pViewFrame && pViewFrame->HasChildWindow( nWhich ) )
+ {
+ SfxChildWindow* pChild = pViewFrame->GetChildWindow( nWhich );
+ Window* pWin = ( pChild ? pChild->GetWindow() : NULL );
+ if ( pWin && pWin->IsVisible() )
+ {
+ bVisible = true;
+ }
+ }
+ if ( !bVisible )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ }
+ break;
+
+ } // switch ( nWitch )
+ nWhich = aIter.NextWhich();
+ } // while ( nWitch )
+}
+
+//------------------------------------------------------------------
+
+
+
diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
new file mode 100644
index 000000000000..3803a318fb21
--- /dev/null
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -0,0 +1,2206 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+//------------------------------------------------------------------
+
+//svdraw.hxx
+#define _SDR_NOITEMS
+#define _SDR_NOTOUCH
+#define _SDR_NOTRANSFORM
+#define _SI_NOSBXCONTROLS
+#define _VCONT_HXX
+#define _SI_NOOTHERFORMS
+#define _VCTRLS_HXX
+#define _SI_NOCONTROL
+#define _SETBRW_HXX
+#define _VCBRW_HXX
+#define _SI_NOSBXCONTROLS
+
+//------------------------------------------------------------------
+#include <com/sun/star/i18n/TextConversionOption.hpp>
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+
+#include "scitems.hxx"
+#include <sfx2/viewfrm.hxx>
+
+#define _ZFORLIST_DECLARE_TABLE
+#include <svl/stritem.hxx>
+#include <svl/whiter.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/request.hxx>
+#include <vcl/msgbox.hxx>
+#include <svx/svxdlg.hxx>
+#include <sot/formats.hxx>
+#include <svx/postattr.hxx>
+#include <editeng/fontitem.hxx>
+#include <svx/clipfmtitem.hxx>
+#include <sfx2/passwd.hxx>
+#include <svx/hlnkitem.hxx>
+#include <basic/sbxcore.hxx>
+#include <unotools/useroptions.hxx>
+#include <vcl/waitobj.hxx>
+#include <unotools/localedatawrapper.hxx>
+
+#include "cellsh.hxx"
+#include "sc.hrc"
+#include "document.hxx"
+#include "patattr.hxx"
+#include "scmod.hxx"
+#include "scresid.hxx"
+#include "tabvwsh.hxx"
+//CHINA001 #include "inscldlg.hxx"
+//CHINA001 #include "inscodlg.hxx"
+//CHINA001 #include "delcldlg.hxx"
+//CHINA001 #include "delcodlg.hxx"
+//CHINA001 #include "filldlg.hxx"
+//CHINA001 #include "groupdlg.hxx"
+#include "impex.hxx"
+#include "reffind.hxx"
+//CHINA001 #include "namecrea.hxx"
+#include "uiitems.hxx"
+#include "reffact.hxx"
+//CHINA001 #include "namepast.hxx"
+#include "inputhdl.hxx"
+#include "transobj.hxx"
+#include "drwtrans.hxx"
+//CHINA001 #include "linkarea.hxx"
+#include "docfunc.hxx"
+#include "editable.hxx"
+#include "dpobject.hxx"
+#include "dpsave.hxx"
+#include "dpgroup.hxx" // for ScDPNumGroupInfo
+#include "spellparam.hxx"
+#include "postit.hxx"
+#include "clipparam.hxx"
+
+#include "globstr.hrc"
+#include "scui_def.hxx" //CHINA001
+#include <svx/svxdlg.hxx> //CHINA001
+#include <svx/dialogs.hrc> //CHINA001
+#include "scabstdlg.hxx" //CHINA001
+#define IS_AVAILABLE(WhichId,ppItem) \
+ (pReqArgs->GetItemState((WhichId), sal_True, ppItem ) == SFX_ITEM_SET)
+
+#define C2U(cChar) rtl::OUString::createFromAscii(cChar)
+
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <cppuhelper/bootstrap.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+
+//------------------------------------------------------------------
+void ScCellShell::ExecuteEdit( SfxRequest& rReq )
+{
+ ScModule* pScMod = SC_MOD();
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ SfxBindings& rBindings = pTabViewShell->GetViewFrame()->GetBindings();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ sal_uInt16 nSlot = rReq.GetSlot();
+
+ pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
+
+ // Eingabe beenden
+ if ( GetViewData()->HasEditView( GetViewData()->GetActivePart() ) )
+ {
+ switch ( nSlot )
+ {
+ case FID_DEFINE_NAME:
+ case FID_USE_NAME:
+ case FID_INSERT_NAME:
+ case SID_SPELL_DIALOG:
+ case SID_HANGUL_HANJA_CONVERSION:
+
+ pScMod->InputEnterHandler();
+ pTabViewShell->UpdateInputHandler();
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch ( nSlot )
+ {
+ //
+ // Einfuegen / Loeschen von Zellen / Zeilen / Spalten
+ //
+
+ case FID_INS_ROW:
+ pTabViewShell->InsertCells(INS_INSROWS);
+ rReq.Done();
+ break;
+
+ case FID_INS_COLUMN:
+ pTabViewShell->InsertCells(INS_INSCOLS);
+ rReq.Done();
+ break;
+
+ case FID_INS_CELLSDOWN:
+ pTabViewShell->InsertCells(INS_CELLSDOWN);
+ rReq.Done();
+ break;
+
+ case FID_INS_CELLSRIGHT:
+ pTabViewShell->InsertCells(INS_CELLSRIGHT);
+ rReq.Done();
+ break;
+
+ case SID_DEL_ROWS:
+ pTabViewShell->DeleteCells( DEL_DELROWS );
+ rReq.Done();
+ break;
+
+ case SID_DEL_COLS:
+ pTabViewShell->DeleteCells( DEL_DELCOLS );
+ rReq.Done();
+ break;
+
+ case FID_INS_CELL:
+ {
+ InsCellCmd eCmd=INS_NONE;
+
+ if ( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ String aFlags;
+
+ if( IS_AVAILABLE( FID_INS_CELL, &pItem ) )
+ aFlags = ((const SfxStringItem*)pItem)->GetValue();
+ if( aFlags.Len() )
+ {
+ switch( aFlags.GetChar(0) )
+ {
+ case 'V': eCmd = INS_CELLSDOWN ;break;
+ case '>': eCmd = INS_CELLSRIGHT ;break;
+ case 'R': eCmd = INS_INSROWS ;break;
+ case 'C': eCmd = INS_INSCOLS ;break;
+ }
+ }
+ }
+ else
+ {
+ if ( GetViewData()->SimpleColMarked() )
+ eCmd = INS_INSCOLS;
+ else if ( GetViewData()->SimpleRowMarked() )
+ eCmd = INS_INSROWS;
+ else
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ sal_Bool bTheFlag=(pDoc->GetChangeTrack()!=NULL);
+
+//CHINA001 ScInsertCellDlg* pDlg = new ScInsertCellDlg( pTabViewShell->GetDialogParent(),
+//CHINA001 bTheFlag);
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScInsertCellDlg* pDlg = pFact->CreateScInsertCellDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_INSCELL, bTheFlag);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if (pDlg->Execute() == RET_OK)
+ eCmd = pDlg->GetInsCellCmd();
+ delete pDlg;
+ }
+ }
+
+ if (eCmd!=INS_NONE)
+ {
+ pTabViewShell->InsertCells( eCmd );
+
+ if( ! rReq.IsAPI() )
+ {
+ String aParam;
+
+ switch( eCmd )
+ {
+ case INS_CELLSDOWN: aParam='V'; break;
+ case INS_CELLSRIGHT: aParam='>'; break;
+ case INS_INSROWS: aParam='R'; break;
+ case INS_INSCOLS: aParam='C'; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ rReq.AppendItem( SfxStringItem( FID_INS_CELL, aParam ) );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+
+ case FID_DELETE_CELL:
+ {
+ DelCellCmd eCmd = DEL_NONE;
+
+ if ( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ String aFlags;
+
+ if( IS_AVAILABLE( FID_DELETE_CELL, &pItem ) )
+ aFlags = ((const SfxStringItem*)pItem)->GetValue();
+ if( aFlags.Len() )
+ {
+ switch( aFlags.GetChar(0) )
+ {
+ case 'U': eCmd = DEL_CELLSUP ;break;
+ case 'L': eCmd = DEL_CELLSLEFT ;break;
+ case 'R': eCmd = DEL_DELROWS ;break;
+ case 'C': eCmd = DEL_DELCOLS ;break;
+ }
+ }
+ }
+ else
+ {
+ if ( GetViewData()->SimpleColMarked() )
+ eCmd = DEL_DELCOLS;
+ else if ( GetViewData()->SimpleRowMarked() )
+ eCmd = DEL_DELROWS;
+ else
+ {
+ ScRange aRange;
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ sal_Bool bTheFlag=GetViewData()->IsMultiMarked() ||
+ (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE_FILTERED) ||
+ (pDoc->GetChangeTrack() != NULL);
+
+ //CHINA001 ScDeleteCellDlg* pDlg = new ScDeleteCellDlg(
+ //CHINA001 pTabViewShell->GetDialogParent(),bTheFlag);
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScDeleteCellDlg* pDlg = pFact->CreateScDeleteCellDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_DELCELL, bTheFlag );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ if (pDlg->Execute() == RET_OK)
+ eCmd = pDlg->GetDelCellCmd();
+ delete pDlg;
+ }
+ }
+
+ if (eCmd != DEL_NONE )
+ {
+ pTabViewShell->DeleteCells( eCmd );
+
+ if( ! rReq.IsAPI() )
+ {
+ String aParam;
+
+ switch( eCmd )
+ {
+ case DEL_CELLSUP: aParam='U'; break;
+ case DEL_CELLSLEFT: aParam='L'; break;
+ case DEL_DELROWS: aParam='R'; break;
+ case DEL_DELCOLS: aParam='C'; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ rReq.AppendItem( SfxStringItem( FID_DELETE_CELL, aParam ) );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+
+ //
+ // Inhalte von Zellen loeschen
+ //
+
+ case SID_DELETE_CONTENTS:
+ pTabViewShell->DeleteContents( IDF_CONTENTS );
+ rReq.Done();
+ break;
+
+ case SID_DELETE:
+ {
+ sal_uInt16 nFlags = IDF_NONE;
+
+ if ( pReqArgs!=NULL && pTabViewShell->SelectionEditable() )
+ {
+ const SfxPoolItem* pItem;
+ String aFlags = 'A';
+
+ if( IS_AVAILABLE( SID_DELETE, &pItem ) )
+ aFlags = ((const SfxStringItem*)pItem)->GetValue();
+
+ aFlags.ToUpperAscii();
+ sal_Bool bCont = sal_True;
+
+ for( xub_StrLen i=0 ; bCont && i<aFlags.Len() ; i++ )
+ {
+ switch( aFlags.GetChar(i) )
+ {
+ case 'A': // Alle
+ nFlags |= IDF_ALL;
+ bCont = sal_False; // nicht mehr weitermachen!
+ break;
+ case 'S': nFlags |= IDF_STRING; break;
+ case 'V': nFlags |= IDF_VALUE; break;
+ case 'D': nFlags |= IDF_DATETIME; break;
+ case 'F': nFlags |= IDF_FORMULA; break;
+ case 'N': nFlags |= IDF_NOTE; break;
+ case 'T': nFlags |= IDF_ATTRIB; break;
+ case 'O': nFlags |= IDF_OBJECTS; break;
+ }
+ }
+ }
+ else
+ {
+ ScEditableTester aTester( pTabViewShell );
+ if (aTester.IsEditable())
+ {
+ //CHINA001 ScDeleteContentsDlg* pDlg = new ScDeleteContentsDlg( pTabViewShell->GetDialogParent() );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScDeleteContentsDlg* pDlg = pFact->CreateScDeleteContentsDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_DELCONT );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ if ( pDoc->IsTabProtected(nTab) )
+ pDlg->DisableObjects();
+ if (pDlg->Execute() == RET_OK)
+ {
+ nFlags = pDlg->GetDelContentsCmdBits();
+ }
+ delete pDlg;
+ }
+ else
+ pTabViewShell->ErrorMessage(aTester.GetMessageId());
+ }
+
+ if( nFlags != IDF_NONE )
+ {
+ pTabViewShell->DeleteContents( nFlags );
+
+ if( ! rReq.IsAPI() )
+ {
+ String aFlags;
+
+ if( nFlags == IDF_ALL )
+ {
+ aFlags += 'A';
+ }
+ else
+ {
+ if( nFlags & IDF_STRING ) aFlags += 'S';
+ if( nFlags & IDF_VALUE ) aFlags += 'V';
+ if( nFlags & IDF_DATETIME ) aFlags += 'D';
+ if( nFlags & IDF_FORMULA ) aFlags += 'F';
+ if( nFlags & IDF_NOTE ) aFlags += 'N';
+ if( nFlags & IDF_ATTRIB ) aFlags += 'T';
+ if( nFlags & IDF_OBJECTS ) aFlags += 'O';
+ }
+
+ rReq.AppendItem( SfxStringItem( SID_DELETE, aFlags ) );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+
+ //
+ // Ausfuellen...
+ //
+
+ case FID_FILL_TO_BOTTOM:
+ pTabViewShell->FillSimple( FILL_TO_BOTTOM );
+ rReq.Done();
+ break;
+
+ case FID_FILL_TO_RIGHT:
+ pTabViewShell->FillSimple( FILL_TO_RIGHT );
+ rReq.Done();
+ break;
+
+ case FID_FILL_TO_TOP:
+ pTabViewShell->FillSimple( FILL_TO_TOP );
+ rReq.Done();
+ break;
+
+ case FID_FILL_TO_LEFT:
+ pTabViewShell->FillSimple( FILL_TO_LEFT );
+ rReq.Done();
+ break;
+
+ case FID_FILL_TAB:
+ {
+ sal_uInt16 nFlags = IDF_NONE;
+ sal_uInt16 nFunction = PASTE_NOFUNC;
+ sal_Bool bSkipEmpty = sal_False;
+ sal_Bool bAsLink = sal_False;
+
+ if ( pReqArgs!=NULL && pTabViewShell->SelectionEditable() )
+ {
+ const SfxPoolItem* pItem;
+ String aFlags = 'A';
+
+ if( IS_AVAILABLE( FID_FILL_TAB, &pItem ) )
+ aFlags = ((const SfxStringItem*)pItem)->GetValue();
+
+ aFlags.ToUpperAscii();
+ sal_Bool bCont = sal_True;
+
+ for( xub_StrLen i=0 ; bCont && i<aFlags.Len() ; i++ )
+ {
+ switch( aFlags.GetChar(i) )
+ {
+ case 'A': // Alle
+ nFlags |= IDF_ALL;
+ bCont = sal_False; // nicht mehr weitermachen!
+ break;
+ case 'S': nFlags |= IDF_STRING; break;
+ case 'V': nFlags |= IDF_VALUE; break;
+ case 'D': nFlags |= IDF_DATETIME; break;
+ case 'F': nFlags |= IDF_FORMULA; break;
+ case 'N': nFlags |= IDF_NOTE; break;
+ case 'T': nFlags |= IDF_ATTRIB; break;
+ }
+ }
+ }
+ else
+ {
+//CHINA001 ScInsertContentsDlg* pDlg =
+//CHINA001 new ScInsertContentsDlg(pTabViewShell->GetDialogParent(),
+//CHINA001 0, /* nCheckDefaults */
+//CHINA001 &ScGlobal::GetRscString(STR_FILL_TAB) );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScInsertContentsDlg* pDlg = pFact->CreateScInsertContentsDlg( pTabViewShell->GetDialogParent(),
+ RID_SCDLG_INSCONT, 0, /* nCheckDefaults */
+ &ScGlobal::GetRscString(STR_FILL_TAB));
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ pDlg->SetFillMode(sal_True);
+
+ if (pDlg->Execute() == RET_OK)
+ {
+ nFlags = pDlg->GetInsContentsCmdBits();
+ nFunction = pDlg->GetFormulaCmdBits();
+ bSkipEmpty = pDlg->IsSkipEmptyCells();
+ bAsLink = pDlg->IsLink();
+ // MoveMode gibt's bei Tabelle fuellen nicht
+ }
+ delete pDlg;
+ }
+
+ if( nFlags != IDF_NONE )
+ {
+ pTabViewShell->FillTab( nFlags, nFunction, bSkipEmpty, bAsLink );
+
+ if( ! rReq.IsAPI() )
+ {
+ String aFlags;
+
+ if( nFlags == IDF_ALL )
+ {
+ aFlags += 'A';
+ }
+ else
+ {
+ if( nFlags & IDF_STRING ) aFlags += 'S';
+ if( nFlags & IDF_VALUE ) aFlags += 'V';
+ if( nFlags & IDF_DATETIME ) aFlags += 'D';
+ if( nFlags & IDF_FORMULA ) aFlags += 'F';
+ if( nFlags & IDF_NOTE ) aFlags += 'N';
+ if( nFlags & IDF_ATTRIB ) aFlags += 'T';
+ }
+
+ rReq.AppendItem( SfxStringItem( FID_FILL_TAB, aFlags ) );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+
+ case FID_FILL_SERIES:
+ {
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+ sal_uInt16 nPossDir = FDS_OPT_NONE;
+ FillDir eFillDir = FILL_TO_BOTTOM;
+ FillCmd eFillCmd = FILL_LINEAR;
+ FillDateCmd eFillDateCmd = FILL_DAY;
+ double fStartVal = MAXDOUBLE;
+ double fIncVal = 1;
+ double fMaxVal = MAXDOUBLE;
+ sal_Bool bDoIt = sal_False;
+
+ GetViewData()->GetSimpleArea( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab );
+
+ if( nStartCol!=nEndCol )
+ {
+ nPossDir |= FDS_OPT_HORZ;
+ eFillDir=FILL_TO_RIGHT;
+ }
+
+ if( nStartRow!=nEndRow )
+ {
+ nPossDir |= FDS_OPT_VERT;
+ eFillDir=FILL_TO_BOTTOM;
+ }
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ String aFillDir, aFillCmd, aFillDateCmd;
+ String aFillStep, aFillStart, aFillMax;
+ sal_uInt32 nKey;
+ double fTmpVal;
+
+ bDoIt=sal_False;
+
+ if( IS_AVAILABLE( FID_FILL_SERIES, &pItem ) )
+ aFillDir = ((const SfxStringItem*)pItem)->GetValue();
+ if( IS_AVAILABLE( FN_PARAM_1, &pItem ) )
+ aFillCmd = ((const SfxStringItem*)pItem)->GetValue();
+ if( IS_AVAILABLE( FN_PARAM_2, &pItem ) )
+ aFillDateCmd = ((const SfxStringItem*)pItem)->GetValue();
+ if( IS_AVAILABLE( FN_PARAM_3, &pItem ) )
+ aFillStep = ((const SfxStringItem*)pItem)->GetValue();
+ if( IS_AVAILABLE( FN_PARAM_4, &pItem ) )
+ aFillStart = ((const SfxStringItem*)pItem)->GetValue();
+ if( IS_AVAILABLE( FN_PARAM_5, &pItem ) )
+ aFillMax = ((const SfxStringItem*)pItem)->GetValue();
+
+ if( aFillDir.Len() )
+ switch( aFillDir.GetChar(0) )
+ {
+ case 'B': case 'b': eFillDir=FILL_TO_BOTTOM; break;
+ case 'R': case 'r': eFillDir=FILL_TO_RIGHT; break;
+ case 'T': case 't': eFillDir=FILL_TO_TOP; break;
+ case 'L': case 'l': eFillDir=FILL_TO_LEFT; break;
+ }
+
+ if( aFillCmd.Len() )
+ switch( aFillCmd.GetChar(0) )
+ {
+ case 'S': case 's': eFillCmd=FILL_SIMPLE; break;
+ case 'L': case 'l': eFillCmd=FILL_LINEAR; break;
+ case 'G': case 'g': eFillCmd=FILL_GROWTH; break;
+ case 'D': case 'd': eFillCmd=FILL_DATE; break;
+ case 'A': case 'a': eFillCmd=FILL_AUTO; break;
+ }
+
+ if( aFillDateCmd.Len() )
+ switch( aFillDateCmd.GetChar(0) )
+ {
+ case 'D': case 'd': eFillDateCmd=FILL_DAY; break;
+ case 'W': case 'w': eFillDateCmd=FILL_WEEKDAY; break;
+ case 'M': case 'm': eFillDateCmd=FILL_MONTH; break;
+ case 'Y': case 'y': eFillDateCmd=FILL_YEAR; break;
+ }
+
+ nKey = 0;
+ if( pFormatter->IsNumberFormat( aFillStart, nKey, fTmpVal ))
+ fStartVal = fTmpVal;
+
+ nKey = 0;
+ if( pFormatter->IsNumberFormat( aFillStep, nKey, fTmpVal ))
+ fIncVal = fTmpVal;
+
+ nKey = 0;
+ if( pFormatter->IsNumberFormat( aFillMax, nKey, fTmpVal ))
+ fMaxVal = fTmpVal;
+
+ bDoIt = sal_True;
+
+ }
+ else // (pReqArgs == NULL) => Dialog hochziehen
+ {
+ //
+ sal_uInt32 nPrivFormat;
+ CellType eCellType;
+ pDoc->GetNumberFormat( nStartCol, nStartRow, nStartTab, nPrivFormat );
+ pDoc->GetCellType( nStartCol, nStartRow, nStartTab,eCellType );
+ const SvNumberformat* pPrivEntry = pFormatter->GetEntry( nPrivFormat );
+ if (!pPrivEntry)
+ {
+ DBG_ERROR("Zahlformat nicht gefunden !!!");
+ }
+ else
+ {
+ short nPrivType = pPrivEntry->GetType();
+ if ( ( nPrivType & NUMBERFORMAT_DATE)>0)
+ {
+ eFillCmd=FILL_DATE;
+ }
+ else if(eCellType==CELLTYPE_STRING)
+ {
+ eFillCmd=FILL_AUTO;
+ }
+ }
+
+ //
+ String aStartStr;
+
+ // Startwert nur vorbelegen, wenn nur 1 Zeile oder Spalte:
+ if ( nStartCol == nEndCol || nStartRow == nEndRow )
+ {
+ double fInputEndVal = 0.0;
+ String aEndStr;
+
+ pDoc->GetInputString( nStartCol, nStartRow, nStartTab, aStartStr);
+ pDoc->GetValue( nStartCol, nStartRow, nStartTab, fStartVal );
+
+
+ if(eFillDir==FILL_TO_BOTTOM && nStartRow < nEndRow )
+ {
+ pDoc->GetInputString( nStartCol, nStartRow+1, nStartTab, aEndStr);
+ if(aEndStr.Len()>0)
+ {
+ pDoc->GetValue( nStartCol, nStartRow+1, nStartTab, fInputEndVal);
+ fIncVal=fInputEndVal-fStartVal;
+ }
+ }
+ else
+ {
+ if(nStartCol < nEndCol)
+ {
+ pDoc->GetInputString( nStartCol+1, nStartRow, nStartTab, aEndStr);
+ if(aEndStr.Len()>0)
+ {
+ pDoc->GetValue( nStartCol+1, nStartRow, nStartTab, fInputEndVal);
+ fIncVal=fInputEndVal-fStartVal;
+ }
+ }
+ }
+ if(eFillCmd==FILL_DATE)
+ {
+ Date aNullDate = *pDoc->GetFormatTable()->GetNullDate();
+ Date aStartDate = aNullDate;
+ aStartDate+= (long)fStartVal;
+ Date aEndDate = aNullDate;
+ aEndDate+= (long)fInputEndVal;
+ double fTempDate=0;
+
+ if(aStartDate.GetYear()!=aEndDate.GetYear())
+ {
+ eFillDateCmd = FILL_YEAR;
+ fTempDate=aEndDate.GetYear()-aStartDate.GetYear();
+ }
+ if(aStartDate.GetMonth()!=aEndDate.GetMonth())
+ {
+ eFillDateCmd = FILL_MONTH;
+ fTempDate=fTempDate*12+aEndDate.GetMonth()-aStartDate.GetMonth();
+ }
+ if(aStartDate.GetDay()==aEndDate.GetDay())
+ {
+ fIncVal=fTempDate;
+ }
+ }
+ }
+//CHINA001 ScFillSeriesDlg* pDlg = new ScFillSeriesDlg(
+//CHINA001 pTabViewShell->GetDialogParent(), *pDoc,
+//CHINA001 eFillDir, eFillCmd, eFillDateCmd,
+//CHINA001 aStartStr, fIncVal, fMaxVal,
+//CHINA001 nPossDir);
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScFillSeriesDlg* pDlg = pFact->CreateScFillSeriesDlg( pTabViewShell->GetDialogParent(),
+ *pDoc,
+ eFillDir, eFillCmd, eFillDateCmd,
+ aStartStr, fIncVal, fMaxVal,
+ nPossDir,
+ RID_SCDLG_FILLSERIES);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ if ( nStartCol != nEndCol && nStartRow != nEndRow )
+ {
+ pDlg->SetEdStartValEnabled(sal_False);
+ }
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ eFillDir = pDlg->GetFillDir();
+ eFillCmd = pDlg->GetFillCmd();
+ eFillDateCmd = pDlg->GetFillDateCmd();
+
+ if(eFillCmd==FILL_AUTO)
+ {
+ String aStr=pDlg->GetStartStr();
+ if(aStr.Len()>0)
+ pTabViewShell->EnterData( nStartCol, nStartRow, nStartTab, aStr );
+ }
+ fStartVal = pDlg->GetStart();
+ fIncVal = pDlg->GetStep();
+ fMaxVal = pDlg->GetMax();
+ bDoIt = sal_True;
+ }
+ delete pDlg;
+ }
+
+ if( bDoIt )
+ {
+ //nScFillModeMouseModifier = 0; // kein Ctrl/Copy
+ pTabViewShell->FillSeries( eFillDir, eFillCmd, eFillDateCmd, fStartVal, fIncVal, fMaxVal );
+
+ if( ! rReq.IsAPI() )
+ {
+ String aPara;
+ Color* pColor=0;
+
+ switch( eFillDir )
+ {
+ case FILL_TO_BOTTOM: aPara = 'B'; break;
+ case FILL_TO_RIGHT: aPara = 'R'; break;
+ case FILL_TO_TOP: aPara = 'T'; break;
+ case FILL_TO_LEFT: aPara = 'L'; break;
+ default: aPara.Erase(); break;
+ }
+ rReq.AppendItem( SfxStringItem( FID_FILL_SERIES, aPara ) );
+
+ switch( eFillCmd )
+ {
+ case FILL_SIMPLE: aPara = 'S'; break;
+ case FILL_LINEAR: aPara = 'L'; break;
+ case FILL_GROWTH: aPara = 'G'; break;
+ case FILL_DATE: aPara = 'D'; break;
+ case FILL_AUTO: aPara = 'A'; break;
+ default: aPara.Erase(); break;
+ }
+ rReq.AppendItem( SfxStringItem( FN_PARAM_1, aPara ) );
+
+ switch( eFillDateCmd )
+ {
+ case FILL_DAY: aPara = 'D'; break;
+ case FILL_WEEKDAY: aPara = 'W'; break;
+ case FILL_MONTH: aPara = 'M'; break;
+ case FILL_YEAR: aPara = 'Y'; break;
+ default: aPara.Erase(); break;
+ }
+ rReq.AppendItem( SfxStringItem( FN_PARAM_2, aPara ) );
+
+ sal_uLong nFormatKey = pFormatter->GetStandardFormat(NUMBERFORMAT_NUMBER,
+ ScGlobal::eLnge );
+
+ pFormatter->GetOutputString( fIncVal, nFormatKey, aPara, &pColor );
+ rReq.AppendItem( SfxStringItem( FN_PARAM_3, aPara ) );
+
+ pFormatter->GetOutputString( fStartVal, nFormatKey, aPara, &pColor );
+ rReq.AppendItem( SfxStringItem( FN_PARAM_4, aPara ) );
+
+ pFormatter->GetOutputString( fMaxVal, nFormatKey, aPara, &pColor );
+ rReq.AppendItem( SfxStringItem( FN_PARAM_5, aPara ) );
+
+ rReq.Done();
+ }
+ }
+ }
+ break;
+
+ case FID_FILL_AUTO:
+ {
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nStartTab, nEndTab;
+
+ GetViewData()->GetFillData( nStartCol, nStartRow, nEndCol, nEndRow );
+ SCCOL nFillCol = GetViewData()->GetRefEndX();
+ SCROW nFillRow = GetViewData()->GetRefEndY();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ if( pReqArgs != NULL )
+ {
+ const SfxPoolItem* pItem;
+
+ if( IS_AVAILABLE( FID_FILL_AUTO, &pItem ) )
+ {
+ ScAddress aScAddress;
+ String aArg = ((const SfxStringItem*)pItem)->GetValue();
+
+ if( aScAddress.Parse( aArg, pDoc, pDoc->GetAddressConvention() ) & SCA_VALID )
+ {
+ nFillRow = aScAddress.Row();
+ nFillCol = aScAddress.Col();
+ }
+ }
+
+ GetViewData()->GetSimpleArea( nStartCol,nStartRow,nStartTab,
+ nEndCol,nEndRow,nEndTab );
+ }
+ else // Aufruf per Maus
+ {
+ // #55284# nicht innerhalb einer zusammengefassten Zelle
+
+ if ( nStartCol == nEndCol && nStartRow == nEndRow )
+ {
+ SCCOL nMergeCol = nStartCol;
+ SCROW nMergeRow = nStartRow;
+ if ( GetViewData()->GetDocument()->ExtendMerge(
+ nStartCol, nStartRow, nMergeCol, nMergeRow,
+ GetViewData()->GetTabNo() ) )
+ {
+ if ( nFillCol >= nStartCol && nFillCol <= nMergeCol && nFillRow == nStartRow )
+ nFillCol = nStartCol;
+ if ( nFillRow >= nStartRow && nFillRow <= nMergeRow && nFillCol == nStartCol )
+ nFillRow = nStartRow;
+ }
+ }
+ }
+
+ if ( nFillCol != nEndCol || nFillRow != nEndRow )
+ {
+ if ( nFillCol==nEndCol || nFillRow==nEndRow )
+ {
+ FillDir eDir = FILL_TO_BOTTOM;
+ SCCOLROW nCount = 0;
+
+ if ( nFillCol==nEndCol )
+ {
+ if ( nFillRow > nEndRow )
+ {
+ eDir = FILL_TO_BOTTOM;
+ nCount = nFillRow - nEndRow;
+ }
+ else if ( nFillRow < nStartRow )
+ {
+ eDir = FILL_TO_TOP;
+ nCount = nStartRow - nFillRow;
+ }
+ }
+ else
+ {
+ if ( nFillCol > nEndCol )
+ {
+ eDir = FILL_TO_RIGHT;
+ nCount = nFillCol - nEndCol;
+ }
+ else if ( nFillCol < nStartCol )
+ {
+ eDir = FILL_TO_LEFT;
+ nCount = nStartCol - nFillCol;
+ }
+ }
+
+ if ( nCount != 0)
+ {
+ pTabViewShell->FillAuto( eDir, nStartCol, nStartRow, nEndCol, nEndRow, nCount );
+
+ if( ! rReq.IsAPI() )
+ {
+ String aAdrStr;
+ ScAddress aAdr( nFillCol, nFillRow, 0 );
+ aAdr.Format( aAdrStr, SCR_ABS, pDoc, pDoc->GetAddressConvention() );
+
+ rReq.AppendItem( SfxStringItem( FID_FILL_AUTO, aAdrStr ) );
+ rReq.Done();
+ }
+ }
+
+ }
+ else
+ {
+ DBG_ERROR( "Richtung nicht eindeutig fuer AutoFill" );
+ }
+ }
+ }
+ break;
+
+ //
+ // Gliederung (Outlines)
+ // SID_AUTO_OUTLINE, SID_OUTLINE_DELETEALL in Execute (in docsh.idl)
+ //
+
+ case SID_OUTLINE_HIDE:
+ if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
+ pTabViewShell->SetDataPilotDetails( sal_False );
+ else
+ pTabViewShell->HideMarkedOutlines();
+ rReq.Done();
+ break;
+
+ case SID_OUTLINE_SHOW:
+ {
+ ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ if ( pDPObj )
+ {
+ Sequence<sheet::DataPilotFieldFilter> aFilters;
+ sal_uInt16 nOrientation;
+ if ( pTabViewShell->HasSelectionForDrillDown( nOrientation ) )
+ {
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScDPShowDetailDlg* pDlg = pFact->CreateScDPShowDetailDlg(
+ pTabViewShell->GetDialogParent(), RID_SCDLG_DPSHOWDETAIL, *pDPObj, nOrientation );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( pDlg->Execute() == RET_OK )
+ {
+ String aNewDimName( pDlg->GetDimensionName() );
+ pTabViewShell->SetDataPilotDetails( sal_True, &aNewDimName );
+ }
+ }
+ else if ( !pDPObj->IsServiceData() &&
+ pDPObj->GetDataFieldPositionData(
+ ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() ),
+ aFilters ) )
+ pTabViewShell->ShowDataPilotSourceData( *pDPObj, aFilters );
+ else
+ pTabViewShell->SetDataPilotDetails( sal_True );
+ }
+ else
+ pTabViewShell->ShowMarkedOutlines();
+ rReq.Done();
+ }
+ break;
+
+ case SID_OUTLINE_MAKE:
+ {
+ sal_Bool bColumns = sal_False;
+ sal_Bool bOk = sal_True;
+
+ if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
+ {
+ ScDPNumGroupInfo aNumInfo;
+ aNumInfo.Enable = sal_True;
+ aNumInfo.AutoStart = sal_True;
+ aNumInfo.AutoEnd = sal_True;
+ sal_Int32 nParts = 0;
+ if ( pTabViewShell->HasSelectionForDateGroup( aNumInfo, nParts ) )
+ {
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT( pFact, "ScAbstractFactory create fail!" );
+ Date aNullDate( *GetViewData()->GetDocument()->GetFormatTable()->GetNullDate() );
+ AbstractScDPDateGroupDlg* pDlg = pFact->CreateScDPDateGroupDlg(
+ pTabViewShell->GetDialogParent(), RID_SCDLG_DPDATEGROUP,
+ aNumInfo, nParts, aNullDate );
+ DBG_ASSERT( pDlg, "Dialog create fail!" );
+ if( pDlg->Execute() == RET_OK )
+ {
+ aNumInfo = pDlg->GetGroupInfo();
+ pTabViewShell->DateGroupDataPilot( aNumInfo, pDlg->GetDatePart() );
+ }
+ }
+ else if ( pTabViewShell->HasSelectionForNumGroup( aNumInfo ) )
+ {
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT( pFact, "ScAbstractFactory create fail!" );
+ AbstractScDPNumGroupDlg* pDlg = pFact->CreateScDPNumGroupDlg(
+ pTabViewShell->GetDialogParent(), RID_SCDLG_DPNUMGROUP, aNumInfo );
+ DBG_ASSERT( pDlg, "Dialog create fail!" );
+ if( pDlg->Execute() == RET_OK )
+ pTabViewShell->NumGroupDataPilot( pDlg->GetGroupInfo() );
+ }
+ else
+ pTabViewShell->GroupDataPilot();
+
+ bOk = sal_False;
+ }
+ else if( pReqArgs != NULL )
+ {
+ const SfxPoolItem* pItem;
+ bOk = sal_False;
+
+ if( IS_AVAILABLE( SID_OUTLINE_MAKE, &pItem ) )
+ {
+ String aCol = ((const SfxStringItem*)pItem)->GetValue();
+ aCol.ToUpperAscii();
+
+ switch( aCol.GetChar(0) )
+ {
+ case 'R': bColumns=sal_False; bOk = sal_True;break;
+ case 'C': bColumns=sal_True; bOk = sal_True;break;
+ }
+ }
+ }
+ else // Dialog, wenn nicht ganze Zeilen/Spalten markiert
+ {
+ if ( GetViewData()->SimpleColMarked() && !GetViewData()->SimpleRowMarked() )
+ bColumns = sal_True;
+ else if ( !GetViewData()->SimpleColMarked() && GetViewData()->SimpleRowMarked() )
+ bColumns = sal_False;
+ else
+ {
+//CHINA001 ScGroupDlg* pDlg = new ScGroupDlg(pTabViewShell->GetDialogParent(),
+//CHINA001 RID_SCDLG_GRP_MAKE, sal_False );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScGroupDlg* pDlg = pFact->CreateAbstractScGroupDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_GRP_MAKE, RID_SCDLG_GRP_MAKE,sal_False);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( pDlg->Execute() == RET_OK )
+ bColumns = pDlg->GetColsChecked();
+ else
+ bOk = sal_False;
+ delete pDlg;
+ }
+ }
+ if (bOk)
+ {
+ pTabViewShell->MakeOutline( bColumns );
+
+ if( ! rReq.IsAPI() )
+ {
+ String aCol = bColumns ? 'C' : 'R';
+ rReq.AppendItem( SfxStringItem( SID_OUTLINE_MAKE, aCol ) );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+
+ case SID_OUTLINE_REMOVE:
+ {
+ sal_Bool bColumns = sal_False;
+ sal_Bool bOk = sal_True;
+
+ if ( GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() ) )
+ {
+ pTabViewShell->UngroupDataPilot();
+ bOk = sal_False;
+ }
+ else if( pReqArgs != NULL )
+ {
+ const SfxPoolItem* pItem;
+ bOk = sal_False;
+
+ if( IS_AVAILABLE( SID_OUTLINE_REMOVE, &pItem ) )
+ {
+ String aCol = ((const SfxStringItem*)pItem)->GetValue();
+ aCol.ToUpperAscii();
+
+ switch( aCol.GetChar(0) )
+ {
+ case 'R': bColumns=sal_False; bOk = sal_True;break;
+ case 'C': bColumns=sal_True; bOk = sal_True;break;
+ }
+ }
+ }
+ else // Dialog nur, wenn Aufheben fuer Zeilen und Spalten moeglich
+ {
+ sal_Bool bColPoss, bRowPoss;
+ pTabViewShell->TestRemoveOutline( bColPoss, bRowPoss );
+ if ( bColPoss && bRowPoss )
+ {
+ //CHINA001 ScGroupDlg* pDlg = new ScGroupDlg( pTabViewShell->GetDialogParent(),
+ //CHINA001 RID_SCDLG_GRP_KILL, sal_True );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScGroupDlg* pDlg = pFact->CreateAbstractScGroupDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_GRP_KILL, RID_SCDLG_GRP_KILL,sal_True);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( pDlg->Execute() == RET_OK )
+ bColumns = pDlg->GetColsChecked();
+ else
+ bOk = sal_False;
+ delete pDlg;
+ }
+ else if ( bColPoss )
+ bColumns = sal_True;
+ else if ( bRowPoss )
+ bColumns = sal_False;
+ else
+ bOk = sal_False;
+ }
+ if (bOk)
+ {
+ pTabViewShell->RemoveOutline( bColumns );
+
+ if( ! rReq.IsAPI() )
+ {
+ String aCol = bColumns ? 'C' : 'R';
+ rReq.AppendItem( SfxStringItem( SID_OUTLINE_REMOVE, aCol ) );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+
+ //
+ // Clipboard
+ //
+
+ case SID_COPY: // fuer Grafiken in DrawShell
+ {
+ WaitObject aWait( GetViewData()->GetDialogParent() );
+ pTabViewShell->CopyToClip( NULL, sal_False, sal_False, sal_True );
+ rReq.Done();
+ }
+ break;
+
+ case SID_CUT: // fuer Grafiken in DrawShell
+ {
+ WaitObject aWait( GetViewData()->GetDialogParent() );
+ pTabViewShell->CutToClip( NULL, sal_True );
+ rReq.Done();
+ }
+ break;
+
+ case SID_PASTE:
+ {
+ PasteFromClipboard ( GetViewData(), pTabViewShell, true );
+ rReq.Done();
+ }
+ break;
+
+ case SID_CLIPBOARD_FORMAT_ITEMS:
+ {
+ WaitObject aWait( GetViewData()->GetDialogParent() );
+
+ sal_uLong nFormat = 0;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs &&
+ pReqArgs->GetItemState(nSlot, sal_True, &pItem) == SFX_ITEM_SET &&
+ pItem->ISA(SfxUInt32Item) )
+ {
+ nFormat = ((const SfxUInt32Item*)pItem)->GetValue();
+ }
+
+ if ( nFormat )
+ {
+ Window* pWin = GetViewData()->GetActiveWin();
+ sal_Bool bCells = ( ScTransferObj::GetOwnClipboard( pWin ) != NULL );
+ sal_Bool bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != NULL );
+ sal_Bool bOle = ( nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE );
+
+ if ( bCells && bOle )
+ pTabViewShell->PasteFromSystem();
+ else if ( bDraw && bOle )
+ pTabViewShell->PasteDraw();
+ else
+ pTabViewShell->PasteFromSystem(nFormat);
+ }
+ //?else
+ //? pTabViewShell->PasteFromSystem();
+
+ rReq.Done();
+ }
+ pTabViewShell->CellContentChanged();
+ break;
+
+ case FID_INS_CELL_CONTENTS:
+ {
+ sal_uInt16 nFlags = IDF_NONE;
+ sal_uInt16 nFunction = PASTE_NOFUNC;
+ sal_Bool bSkipEmpty = sal_False;
+ sal_Bool bTranspose = sal_False;
+ sal_Bool bAsLink = sal_False;
+ InsCellCmd eMoveMode = INS_NONE;
+
+ Window* pWin = GetViewData()->GetActiveWin();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ sal_Bool bOtherDoc = !pDoc->IsClipboardSource();
+ ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin );
+ if ( pOwnClip )
+ {
+ // #129384# keep a reference in case the clipboard is changed during dialog or PasteFromClip
+ uno::Reference<datatransfer::XTransferable> aOwnClipRef( pOwnClip );
+ if ( pReqArgs!=NULL && pTabViewShell->SelectionEditable() )
+ {
+ const SfxPoolItem* pItem;
+ String aFlags = 'A';
+
+ if( IS_AVAILABLE( FID_INS_CELL_CONTENTS, &pItem ) )
+ aFlags = ((const SfxStringItem*)pItem)->GetValue();
+
+ aFlags.ToUpperAscii();
+ sal_Bool bCont = sal_True;
+
+ for( xub_StrLen i=0 ; bCont && i<aFlags.Len() ; i++ )
+ {
+ switch( aFlags.GetChar(i) )
+ {
+ case 'A': // Alle
+ nFlags |= IDF_ALL;
+ bCont = sal_False; // nicht mehr weitermachen!
+ break;
+ case 'S': nFlags |= IDF_STRING; break;
+ case 'V': nFlags |= IDF_VALUE; break;
+ case 'D': nFlags |= IDF_DATETIME; break;
+ case 'F': nFlags |= IDF_FORMULA; break;
+ case 'N': nFlags |= IDF_NOTE; break;
+ case 'T': nFlags |= IDF_ATTRIB; break;
+ }
+ }
+
+ SFX_REQUEST_ARG( rReq, pFuncItem, SfxUInt16Item, FN_PARAM_1, sal_False );
+ SFX_REQUEST_ARG( rReq, pSkipItem, SfxBoolItem, FN_PARAM_2, sal_False );
+ SFX_REQUEST_ARG( rReq, pTransposeItem, SfxBoolItem, FN_PARAM_3, sal_False );
+ SFX_REQUEST_ARG( rReq, pLinkItem, SfxBoolItem, FN_PARAM_4, sal_False );
+ SFX_REQUEST_ARG( rReq, pMoveItem, SfxInt16Item, FN_PARAM_5, sal_False );
+ if ( pFuncItem )
+ nFunction = pFuncItem->GetValue();
+ if ( pSkipItem )
+ bSkipEmpty = pSkipItem->GetValue();
+ if ( pTransposeItem )
+ bTranspose = pTransposeItem->GetValue();
+ if ( pLinkItem )
+ bAsLink = pLinkItem->GetValue();
+ if ( pMoveItem )
+ eMoveMode = (InsCellCmd) pMoveItem->GetValue();
+ }
+ else
+ {
+ ScEditableTester aTester( pTabViewShell );
+ if (aTester.IsEditable())
+ {
+ //CHINA001 ScInsertContentsDlg* pDlg = new ScInsertContentsDlg( pTabViewShell->GetDialogParent() );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScInsertContentsDlg* pDlg = pFact->CreateScInsertContentsDlg( pTabViewShell->GetDialogParent(),
+ RID_SCDLG_INSCONT);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ pDlg->SetOtherDoc( bOtherDoc );
+ // #53661# bei ChangeTrack MoveMode disablen
+ pDlg->SetChangeTrack( pDoc->GetChangeTrack() != NULL );
+ // #72930# cut/move references may disable shift
+ // directions if source and destination ranges intersect
+ if ( !bOtherDoc )
+ {
+ if ( pOwnClip && pOwnClip->GetDocument()->IsCutMode() )
+ {
+ ScViewData* pData = GetViewData();
+ if ( pData->GetMarkData().GetTableSelect(
+ pData->GetTabNo() ) )
+ {
+ SCCOL nPosX = pData->GetCurX();
+ SCROW nPosY = pData->GetCurY();
+ SCCOL nClipStartX, nClipSizeX;
+ SCROW nClipStartY, nClipSizeY;
+ pOwnClip->GetDocument()->GetClipStart( nClipStartX, nClipStartY );
+ // for CutMode, filtered rows can always be included
+ pOwnClip->GetDocument()->GetClipArea( nClipSizeX, nClipSizeY, sal_True );
+ int nDisableShift = 0;
+ if ( nClipStartX <= nPosX + nClipSizeX &&
+ nPosX <= nClipStartX + nClipSizeX )
+ nDisableShift |= SC_CELL_SHIFT_DISABLE_DOWN;
+ if ( nClipStartY <= nPosY + nClipSizeY &&
+ nPosY <= nClipStartY + nClipSizeY )
+ nDisableShift |= SC_CELL_SHIFT_DISABLE_RIGHT;
+ if ( nDisableShift )
+ pDlg->SetCellShiftDisabled( nDisableShift );
+ }
+ }
+ }
+ if (pDlg->Execute() == RET_OK)
+ {
+ nFlags = pDlg->GetInsContentsCmdBits();
+ nFunction = pDlg->GetFormulaCmdBits();
+ bSkipEmpty = pDlg->IsSkipEmptyCells();
+ bTranspose = pDlg->IsTranspose();
+ bAsLink = pDlg->IsLink();
+ eMoveMode = pDlg->GetMoveMode();
+ }
+ delete pDlg;
+ }
+ else
+ pTabViewShell->ErrorMessage(aTester.GetMessageId());
+ }
+
+ if( nFlags != IDF_NONE )
+ {
+ {
+ WaitObject aWait( GetViewData()->GetDialogParent() );
+ if ( bAsLink && bOtherDoc )
+ pTabViewShell->PasteFromSystem(SOT_FORMATSTR_ID_LINK); // DDE einfuegen
+ else
+ pTabViewShell->PasteFromClip( nFlags, pOwnClip->GetDocument(),
+ nFunction, bSkipEmpty, bTranspose, bAsLink,
+ eMoveMode, IDF_NONE, sal_True ); // allow warning dialog
+ }
+
+ if( !pReqArgs )
+ {
+ String aFlags;
+
+ if( nFlags == IDF_ALL )
+ {
+ aFlags += 'A';
+ }
+ else
+ {
+ if( nFlags & IDF_STRING ) aFlags += 'S';
+ if( nFlags & IDF_VALUE ) aFlags += 'V';
+ if( nFlags & IDF_DATETIME ) aFlags += 'D';
+ if( nFlags & IDF_FORMULA ) aFlags += 'F';
+ if( nFlags & IDF_NOTE ) aFlags += 'N';
+ if( nFlags & IDF_ATTRIB ) aFlags += 'T';
+ }
+
+ rReq.AppendItem( SfxStringItem( FID_INS_CELL_CONTENTS, aFlags ) );
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_2, bSkipEmpty ) );
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_3, bTranspose ) );
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_4, bAsLink ) );
+ rReq.AppendItem( SfxUInt16Item( FN_PARAM_1, nFunction ) );
+ rReq.AppendItem( SfxInt16Item( FN_PARAM_5, (sal_Int16) eMoveMode ) );
+ rReq.Done();
+ }
+ }
+ }
+ }
+ pTabViewShell->CellContentChanged(); // => PasteFromXXX ???
+ break;
+
+ case SID_PASTE_SPECIAL:
+ // Unterscheidung, ob eigene oder fremde Daten,
+ // dadurch FID_INS_CELL_CONTENTS ueberfluessig
+ {
+ Window* pWin = GetViewData()->GetActiveWin();
+
+ // Clipboard-ID als Parameter angegeben? Basic "PasteSpecial(Format)"
+ const SfxPoolItem* pItem=NULL;
+ if ( pReqArgs &&
+ pReqArgs->GetItemState(nSlot, sal_True, &pItem) == SFX_ITEM_SET &&
+ pItem->ISA(SfxUInt32Item) )
+ {
+ sal_uLong nFormat = ((const SfxUInt32Item*)pItem)->GetValue();
+ sal_Bool bRet=sal_True;
+ {
+ WaitObject aWait( GetViewData()->GetDialogParent() );
+ sal_Bool bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != NULL );
+ if ( bDraw && nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE )
+ pTabViewShell->PasteDraw();
+ else
+ bRet = pTabViewShell->PasteFromSystem(nFormat, sal_True); // TRUE: keine Fehlermeldungen
+ }
+
+ if ( bRet )
+ {
+ rReq.SetReturnValue(SfxInt16Item(nSlot, bRet)); // 1 = Erfolg, 0 = Fehler
+ rReq.Done();
+ }
+ else
+ // if format is not available -> fallback to request without parameters
+ pItem = NULL;
+ }
+
+ if ( !pItem )
+ {
+ if ( ScTransferObj::GetOwnClipboard( pWin ) ) // own cell data
+ {
+ rReq.SetSlot( FID_INS_CELL_CONTENTS );
+ ExecuteSlot( rReq, GetInterface() );
+ rReq.SetReturnValue(SfxInt16Item(nSlot, 1)); // 1 = Erfolg
+ }
+ else // Zeichenobjekte oder fremde Daten
+ {
+ sal_Bool bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != NULL );
+
+ SvxClipboardFmtItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
+ GetPossibleClipboardFormats( aFormats );
+
+ sal_uInt16 nFormatCount = aFormats.Count();
+ if ( nFormatCount )
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ SfxAbstractPasteDialog* pDlg = pFact->CreatePasteDialog( pTabViewShell->GetDialogParent() );
+ if ( pDlg )
+ {
+ for (sal_uInt16 i=0; i<nFormatCount; i++)
+ {
+ sal_uLong nFormatId = aFormats.GetClipbrdFormatId( i );
+ String aName = aFormats.GetClipbrdFormatName( i );
+ // special case for paste dialog: '*' is replaced by object type
+ if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE )
+ aName.Assign((sal_Unicode)'*');
+ pDlg->Insert( nFormatId, aName );
+ }
+
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
+ sal_uLong nFormat = pDlg->GetFormat( aDataHelper.GetTransferable() );
+ if (nFormat > 0)
+ {
+ {
+ WaitObject aWait( GetViewData()->GetDialogParent() );
+ if ( bDraw && nFormat == SOT_FORMATSTR_ID_EMBED_SOURCE )
+ pTabViewShell->PasteDraw();
+ else
+ pTabViewShell->PasteFromSystem(nFormat);
+ }
+ rReq.SetReturnValue(SfxInt16Item(nSlot, 1)); // 1 = Erfolg
+ rReq.AppendItem( SfxUInt32Item( nSlot, nFormat ) );
+ rReq.Done();
+ }
+ else
+ {
+ rReq.SetReturnValue(SfxInt16Item(nSlot, 0)); // 0 = Fehler
+ rReq.Ignore();
+ }
+
+ delete pDlg;
+ }
+ }
+ else
+ rReq.SetReturnValue(SfxInt16Item(nSlot, 0)); // 0 = Fehler
+ }
+ }
+ }
+ pTabViewShell->CellContentChanged(); // => PasteFromSystem() ???
+ break;
+
+ //
+ // sonstiges
+ //
+
+ case FID_INS_ROWBRK:
+ pTabViewShell->InsertPageBreak( sal_False );
+ rReq.Done();
+ break;
+
+ case FID_INS_COLBRK:
+ pTabViewShell->InsertPageBreak( sal_True );
+ rReq.Done();
+ break;
+
+ case FID_DEL_ROWBRK:
+ pTabViewShell->DeletePageBreak( sal_False );
+ rReq.Done();
+ break;
+
+ case FID_DEL_COLBRK:
+ pTabViewShell->DeletePageBreak( sal_True );
+ rReq.Done();
+ break;
+
+ case SID_DETECTIVE_ADD_PRED:
+ pTabViewShell->DetectiveAddPred();
+ rReq.Done();
+ break;
+
+ case SID_DETECTIVE_DEL_PRED:
+ pTabViewShell->DetectiveDelPred();
+ rReq.Done();
+ break;
+
+ case SID_DETECTIVE_ADD_SUCC:
+ pTabViewShell->DetectiveAddSucc();
+ rReq.Done();
+ break;
+
+ case SID_DETECTIVE_DEL_SUCC:
+ pTabViewShell->DetectiveDelSucc();
+ rReq.Done();
+ break;
+
+ case SID_DETECTIVE_ADD_ERR:
+ pTabViewShell->DetectiveAddError();
+ rReq.Done();
+ break;
+
+ case SID_DETECTIVE_INVALID:
+ pTabViewShell->DetectiveMarkInvalid();
+ rReq.Done();
+ break;
+
+ case SID_DETECTIVE_REFRESH:
+ pTabViewShell->DetectiveRefresh();
+ rReq.Done();
+ break;
+
+ case SID_SPELL_DIALOG:
+// pTabViewShell->DoSpellingChecker();
+ {
+ SfxViewFrame* pViewFrame = pTabViewShell->GetViewFrame();
+ if( rReq.GetArgs() )
+ pViewFrame->SetChildWindow( SID_SPELL_DIALOG,
+ static_cast< const SfxBoolItem& >( rReq.GetArgs()->
+ Get( SID_SPELL_DIALOG ) ).GetValue() );
+ else
+ pViewFrame->ToggleChildWindow( SID_SPELL_DIALOG );
+
+ pViewFrame->GetBindings().Invalidate( SID_SPELL_DIALOG );
+ rReq.Ignore();
+ }
+ break;
+
+ case SID_HANGUL_HANJA_CONVERSION:
+ pTabViewShell->DoHangulHanjaConversion();
+ break;
+
+ case SID_CHINESE_CONVERSION:
+ {
+ //open ChineseTranslationDialog
+ Reference< XComponentContext > xContext(
+ ::cppu::defaultBootstrap_InitialComponentContext() ); //@todo get context from calc if that has one
+ if(xContext.is())
+ {
+ Reference< lang::XMultiComponentFactory > xMCF( xContext->getServiceManager() );
+ if(xMCF.is())
+ {
+ Reference< ui::dialogs::XExecutableDialog > xDialog(
+ xMCF->createInstanceWithContext(
+ rtl::OUString::createFromAscii("com.sun.star.linguistic2.ChineseTranslationDialog")
+ , xContext), UNO_QUERY);
+ Reference< lang::XInitialization > xInit( xDialog, UNO_QUERY );
+ if( xInit.is() )
+ {
+ // initialize dialog
+ Reference< awt::XWindow > xDialogParentWindow(0);
+ Sequence<Any> aSeq(1);
+ Any* pArray = aSeq.getArray();
+ PropertyValue aParam;
+ aParam.Name = rtl::OUString::createFromAscii("ParentWindow");
+ aParam.Value <<= makeAny(xDialogParentWindow);
+ pArray[0] <<= makeAny(aParam);
+ xInit->initialize( aSeq );
+
+ //execute dialog
+ sal_Int16 nDialogRet = xDialog->execute();
+ if( RET_OK == nDialogRet )
+ {
+ //get some parameters from the dialog
+ sal_Bool bToSimplified = sal_True;
+ sal_Bool bUseVariants = sal_True;
+ sal_Bool bCommonTerms = sal_True;
+ Reference< beans::XPropertySet > xProp( xDialog, UNO_QUERY );
+ if( xProp.is() )
+ {
+ try
+ {
+ xProp->getPropertyValue( C2U("IsDirectionToSimplified") ) >>= bToSimplified;
+ xProp->getPropertyValue( C2U("IsUseCharacterVariants") ) >>= bUseVariants;
+ xProp->getPropertyValue( C2U("IsTranslateCommonTerms") ) >>= bCommonTerms;
+ }
+ catch( Exception& )
+ {
+ }
+ }
+
+ //execute translation
+ LanguageType eSourceLang = bToSimplified ? LANGUAGE_CHINESE_TRADITIONAL : LANGUAGE_CHINESE_SIMPLIFIED;
+ LanguageType eTargetLang = bToSimplified ? LANGUAGE_CHINESE_SIMPLIFIED : LANGUAGE_CHINESE_TRADITIONAL;
+ sal_Int32 nOptions = bUseVariants ? i18n::TextConversionOption::USE_CHARACTER_VARIANTS : 0;
+ if( !bCommonTerms )
+ nOptions |= i18n::TextConversionOption::CHARACTER_BY_CHARACTER;
+
+ Font aTargetFont = GetViewData()->GetActiveWin()->GetDefaultFont(
+ DEFAULTFONT_CJK_SPREADSHEET,
+ eTargetLang, DEFAULTFONT_FLAGS_ONLYONE );
+ ScConversionParam aConvParam( SC_CONVERSION_CHINESE_TRANSL,
+ eSourceLang, eTargetLang, aTargetFont, nOptions, false );
+ pTabViewShell->DoSheetConversion( aConvParam );
+ }
+ }
+ Reference< lang::XComponent > xComponent( xDialog, UNO_QUERY );
+ if( xComponent.is() )
+ xComponent->dispose();
+ }
+ }
+ }
+ break;
+
+ case SID_THESAURUS:
+ pTabViewShell->DoThesaurus();
+ break;
+
+ case SID_TOGGLE_REL:
+ pTabViewShell->DoRefConversion();
+ break;
+
+ case SID_DEC_INDENT:
+ pTabViewShell->ChangeIndent( sal_False );
+ break;
+ case SID_INC_INDENT:
+ pTabViewShell->ChangeIndent( sal_True );
+ break;
+
+ case FID_USE_NAME:
+ {
+ sal_uInt16 nFlags = pTabViewShell->GetCreateNameFlags();
+
+ //CHINA001 ScNameCreateDlg* pDlg = new ScNameCreateDlg( pTabViewShell->GetDialogParent(), nFlags );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScNameCreateDlg* pDlg = pFact->CreateScNameCreateDlg(pTabViewShell->GetDialogParent(), nFlags, RID_SCDLG_NAMES_CREATE );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ if( pDlg->Execute() )
+ {
+ nFlags = pDlg->GetFlags();
+ pTabViewShell->CreateNames(nFlags);
+ rReq.Done();
+ }
+ delete pDlg;
+ }
+ break;
+
+ case SID_CONSOLIDATE:
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && SFX_ITEM_SET ==
+ pReqArgs->GetItemState( SCITEM_CONSOLIDATEDATA, sal_True, &pItem ) )
+ {
+ const ScConsolidateParam& rParam =
+ ((const ScConsolidateItem*)pItem)->GetData();
+
+ pTabViewShell->Consolidate( rParam );
+ GetViewData()->GetDocument()->SetConsolidateDlgData( &rParam );
+
+ rReq.Done();
+ }
+ else if (rReq.IsAPI())
+ SbxBase::SetError(SbxERR_BAD_PARAMETER);
+ }
+ break;
+
+ case SID_INS_FUNCTION:
+ {
+ const SfxBoolItem* pOkItem = (const SfxBoolItem*)&pReqArgs->Get( SID_DLG_RETOK );
+
+// pScMod->SetFunctionDlg( NULL );
+
+ if ( pOkItem->GetValue() ) // OK
+ {
+ String aFormula;
+ const SfxStringItem* pSItem = (const SfxStringItem*)&pReqArgs->Get( SCITEM_STRING );
+ const SfxBoolItem* pMatrixItem = (const SfxBoolItem*) &pReqArgs->Get( SID_DLG_MATRIX );
+
+ aFormula += pSItem->GetValue();
+ pScMod->ActivateInputWindow( &aFormula, pMatrixItem->GetValue() );
+ }
+ else // CANCEL
+ {
+ pScMod->ActivateInputWindow( NULL );
+ }
+ rReq.Ignore(); // only SID_ENTER_STRING is recorded
+ }
+ break;
+
+ case FID_DEFINE_NAME:
+ if ( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ String aName, aSymbol, aAttrib;
+
+ if( IS_AVAILABLE( FID_DEFINE_NAME, &pItem ) )
+ aName = ((const SfxStringItem*)pItem)->GetValue();
+
+ if( IS_AVAILABLE( FN_PARAM_1, &pItem ) )
+ aSymbol = ((const SfxStringItem*)pItem)->GetValue();
+
+ if( IS_AVAILABLE( FN_PARAM_2, &pItem ) )
+ aAttrib = ((const SfxStringItem*)pItem)->GetValue();
+
+ if ( aName.Len() && aSymbol.Len() )
+ {
+ if (pTabViewShell->InsertName( aName, aSymbol, aAttrib ))
+ rReq.Done();
+ else
+ SbxBase::SetError( SbxERR_BAD_PARAMETER ); // Basic-Fehler
+ }
+ }
+ else
+ {
+ sal_uInt16 nId = ScNameDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? sal_False : sal_True );
+ }
+ break;
+
+ case SID_DEFINE_COLROWNAMERANGES:
+ {
+
+ sal_uInt16 nId = ScColRowNameRangesDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? sal_False : sal_True );
+
+ }
+ break;
+
+ case SID_UPDATECHART:
+ {
+ sal_Bool bAll = sal_False;
+
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+
+ if( IS_AVAILABLE( SID_UPDATECHART, &pItem ) )
+ bAll = ((const SfxBoolItem*)pItem)->GetValue();
+ }
+
+ pTabViewShell->UpdateCharts( bAll );
+
+ if( ! rReq.IsAPI() )
+ {
+ rReq.AppendItem( SfxBoolItem( SID_UPDATECHART, bAll ) );
+ rReq.Done();
+ }
+ }
+ break;
+
+
+ case SID_TABOP:
+ if (pReqArgs)
+ {
+ const ScTabOpItem& rItem =
+ (const ScTabOpItem&)
+ pReqArgs->Get( SID_TABOP );
+
+ pTabViewShell->TabOp( rItem.GetData() );
+
+ rReq.Done( *pReqArgs );
+ }
+ break;
+
+ case SID_SOLVE:
+ if (pReqArgs)
+ {
+ const ScSolveItem& rItem =
+ (const ScSolveItem&)
+ pReqArgs->Get( SCITEM_SOLVEDATA );
+
+ pTabViewShell->Solve( rItem.GetData() );
+
+ rReq.Done( *pReqArgs );
+ }
+ break;
+
+ case FID_INSERT_NAME:
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ //CHINA001 ScNamePasteDlg* pDlg = new ScNamePasteDlg( pTabViewShell->GetDialogParent(), pDoc->GetRangeName() );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScNamePasteDlg* pDlg = pFact->CreateScNamePasteDlg( pTabViewShell->GetDialogParent(), pDoc->GetRangeName(), RID_SCDLG_NAMES_PASTE );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ switch( pDlg->Execute() )
+ {
+ case BTN_PASTE_LIST:
+ pTabViewShell->InsertNameList();
+ break;
+ case BTN_PASTE_NAME:
+ {
+ ScInputHandler* pHdl = pScMod->GetInputHdl( pTabViewShell );
+ if (pHdl)
+ {
+ // das "=" per Key-Event, schaltet in den Eingabe-Modus
+ pScMod->InputKeyEvent( KeyEvent('=',KeyCode()) );
+
+ String aName = pDlg->GetSelectedName();
+ pHdl->InsertFunction( aName, sal_False ); // ohne "()"
+ }
+ }
+ break;
+ }
+ delete pDlg;
+ }
+ break;
+
+ case SID_RANGE_NOTETEXT:
+ if (pReqArgs)
+ {
+ const SfxStringItem& rTextItem = (const SfxStringItem&)pReqArgs->Get( SID_RANGE_NOTETEXT );
+
+ // #43343# immer Cursorposition
+ ScAddress aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ pTabViewShell->SetNoteText( aPos, rTextItem.GetValue() );
+ rReq.Done();
+ }
+ break;
+
+ case SID_INSERT_POSTIT:
+ if ( pReqArgs )
+ {
+ const SvxPostItAuthorItem& rAuthorItem = (const SvxPostItAuthorItem&)pReqArgs->Get( SID_ATTR_POSTIT_AUTHOR );
+ const SvxPostItDateItem& rDateItem = (const SvxPostItDateItem&) pReqArgs->Get( SID_ATTR_POSTIT_DATE );
+ const SvxPostItTextItem& rTextItem = (const SvxPostItTextItem&) pReqArgs->Get( SID_ATTR_POSTIT_TEXT );
+
+ ScAddress aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ pTabViewShell->ReplaceNote( aPos, rTextItem.GetValue(), &rAuthorItem.GetValue(), &rDateItem.GetValue() );
+ rReq.Done();
+ }
+ else
+ {
+ pTabViewShell->EditNote(); // Zeichenobjekt zum Editieren
+ }
+ break;
+
+ case FID_NOTE_VISIBLE:
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScAddress aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ if( ScPostIt* pNote = pDoc->GetNote( aPos ) )
+ {
+ bool bShow;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && (pReqArgs->GetItemState( FID_NOTE_VISIBLE, sal_True, &pItem ) == SFX_ITEM_SET) )
+ bShow = ((const SfxBoolItem*) pItem)->GetValue();
+ else
+ bShow = !pNote->IsCaptionShown();
+
+ pTabViewShell->ShowNote( bShow );
+
+ if (!pReqArgs)
+ rReq.AppendItem( SfxBoolItem( FID_NOTE_VISIBLE, bShow ) );
+
+ rReq.Done();
+ rBindings.Invalidate( FID_NOTE_VISIBLE );
+ }
+ else
+ rReq.Ignore();
+ }
+ break;
+
+ case SID_DELETE_NOTE:
+ pTabViewShell->DeleteContents( IDF_NOTE ); // delete all notes in selection
+ rReq.Done();
+ break;
+
+ case SID_CHARMAP:
+ if( pReqArgs != NULL )
+ {
+ String aChars, aFontName;
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem = 0;
+ if ( pArgs )
+ pArgs->GetItemState(GetPool().GetWhich(SID_CHARMAP), sal_False, &pItem);
+ if ( pItem )
+ {
+ const SfxStringItem* pStringItem = PTR_CAST( SfxStringItem, pItem );
+ if ( pStringItem )
+ aChars = pStringItem->GetValue();
+ const SfxPoolItem* pFtItem = NULL;
+ pArgs->GetItemState( GetPool().GetWhich(SID_ATTR_SPECIALCHAR), sal_False, &pFtItem);
+ const SfxStringItem* pFontItem = PTR_CAST( SfxStringItem, pFtItem );
+ if ( pFontItem )
+ aFontName = pFontItem->GetValue();
+ }
+
+ if ( aChars.Len() )
+ {
+ Font aFont;
+ pTabViewShell->GetSelectionPattern()->GetFont( aFont, SC_AUTOCOL_BLACK, NULL, NULL, NULL,
+ pTabViewShell->GetSelectionScriptType() );
+ if ( aFontName.Len() )
+ aFont = Font( aFontName, Size(1,1) );
+ pTabViewShell->InsertSpecialChar( aChars, aFont );
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ }
+ else
+ {
+ //CHINA001 SvxCharacterMap* pDlg = new SvxCharacterMap( pTabViewShell->GetDialogParent(), sal_False );
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+
+ // font color doesn't matter here
+ Font aCurFont;
+ pTabViewShell->GetSelectionPattern()->GetFont( aCurFont, SC_AUTOCOL_BLACK, NULL, NULL, NULL,
+ pTabViewShell->GetSelectionScriptType() );
+
+ SfxAllItemSet aSet( GetPool() );
+ aSet.Put( SfxBoolItem( FN_PARAM_1, sal_False ) );
+ aSet.Put( SvxFontItem( aCurFont.GetFamily(), aCurFont.GetName(), aCurFont.GetStyleName(), aCurFont.GetPitch(), aCurFont.GetCharSet(), GetPool().GetWhich(SID_ATTR_CHAR_FONT) ) );
+
+ SfxAbstractDialog* pDlg = pFact->CreateSfxDialog( pTabViewShell->GetDialogParent(), aSet,
+ pTabViewShell->GetViewFrame()->GetFrame().GetFrameInterface(), RID_SVXDLG_CHARMAP );
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pItem, SfxStringItem, SID_CHARMAP, sal_False );
+ SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pFontItem, SvxFontItem, SID_ATTR_CHAR_FONT, sal_False );
+
+ if ( pItem && pFontItem )
+ {
+ Font aNewFont( pFontItem->GetFamilyName(), pFontItem->GetStyleName(), Size(1,1) );
+ aNewFont.SetCharSet( pFontItem->GetCharSet() );
+ aNewFont.SetPitch( pFontItem->GetPitch() );
+ pTabViewShell->InsertSpecialChar( pItem->GetValue(), aNewFont );
+ rReq.AppendItem( *pFontItem );
+ rReq.AppendItem( *pItem );
+ rReq.Done();
+ }
+ }
+ delete pDlg;
+ }
+ break;
+
+ case SID_SELECT_SCENARIO:
+ {
+ // Testing
+
+ if ( pReqArgs )
+ {
+ const SfxStringItem* pItem =
+ (const SfxStringItem*)&pReqArgs->Get( SID_SELECT_SCENARIO );
+
+ if( pItem )
+ {
+ pTabViewShell->UseScenario( pItem->GetValue() );
+ //! wofuer soll der Return-Wert gut sein?!?!
+ rReq.SetReturnValue( SfxStringItem( SID_SELECT_SCENARIO, pItem->GetValue() ) );
+ rReq.Done();
+ }
+ else
+ {
+ DBG_ERROR("NULL");
+ }
+ }
+ }
+ break;
+
+ case SID_HYPERLINK_SETLINK:
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( SID_HYPERLINK_SETLINK, &pItem ) )
+ {
+ const SvxHyperlinkItem* pHyper = (const SvxHyperlinkItem*) pItem;
+ const String& rName = pHyper->GetName();
+ const String& rURL = pHyper->GetURL();
+ const String& rTarget = pHyper->GetTargetFrame();
+ sal_uInt16 nType = (sal_uInt16) pHyper->GetInsertMode();
+
+ pTabViewShell->InsertURL( rName, rURL, rTarget, nType );
+ rReq.Done();
+ }
+ else
+ rReq.Ignore();
+ }
+ break;
+
+ case FID_CONDITIONAL_FORMAT:
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FID_CONDITIONAL_FORMAT, &pItem ) )
+ {
+ // Wenn RefInput auf andere Tabelle als Datentabelle umgeschaltet
+ // hat wieder zurueckschalten:
+ if ( GetViewData()->GetTabNo() != GetViewData()->GetRefTabNo() )
+ {
+ pTabViewShell->SetTabNo( GetViewData()->GetRefTabNo() );
+ pTabViewShell->PaintExtras();
+ }
+
+ const ScCondFrmtItem* pCndFmtItem = (const ScCondFrmtItem*) pItem;
+ pTabViewShell->SetConditionalFormat( pCndFmtItem->GetData() );
+ rReq.Done();
+ }
+ }
+ break;
+
+ case SID_EXTERNAL_SOURCE:
+ {
+ String aFile;
+ String aFilter;
+ String aOptions;
+ String aSource;
+ sal_uLong nRefresh=0;
+
+ SFX_REQUEST_ARG( rReq, pFile, SfxStringItem, SID_FILE_NAME, sal_False );
+ SFX_REQUEST_ARG( rReq, pSource, SfxStringItem, FN_PARAM_1, sal_False );
+ if ( pFile && pSource )
+ {
+ aFile = pFile->GetValue();
+ aSource = pSource->GetValue();
+ SFX_REQUEST_ARG( rReq, pFilter, SfxStringItem, SID_FILTER_NAME, sal_False );
+ if ( pFilter )
+ aFilter = pFilter->GetValue();
+ SFX_REQUEST_ARG( rReq, pOptions, SfxStringItem, SID_FILE_FILTEROPTIONS, sal_False );
+ if ( pOptions )
+ aOptions = pOptions->GetValue();
+ SFX_REQUEST_ARG( rReq, pRefresh, SfxUInt32Item, FN_PARAM_2, sal_False );
+ if ( pRefresh )
+ nRefresh = pRefresh->GetValue();
+ }
+ else
+ {
+ //CHINA001 ScLinkedAreaDlg* pDlg = new ScLinkedAreaDlg( pTabViewShell->GetDialogParent() );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ delete pImpl->m_pLinkedDlg;
+ pImpl->m_pLinkedDlg =
+ pFact->CreateScLinkedAreaDlg( pTabViewShell->GetDialogParent(),
+ RID_SCDLG_LINKAREA);
+ DBG_ASSERT(pImpl->m_pLinkedDlg, "Dialog create fail!");//CHINA001
+ delete pImpl->m_pRequest;
+ pImpl->m_pRequest = new SfxRequest( rReq );
+ pImpl->m_pLinkedDlg->StartExecuteModal( LINK( this, ScCellShell, DialogClosed ) );
+ return;
+ }
+
+ ExecuteExternalSource( aFile, aFilter, aOptions, aSource, nRefresh, rReq );
+ }
+ break;
+
+ //
+ //
+ //
+
+ default:
+ DBG_ERROR("falscher Slot bei ExecuteEdit");
+ break;
+ }
+}
+
+void ScCellShell::ExecuteTrans( SfxRequest& rReq )
+{
+ sal_Int32 nType = ScViewUtil::GetTransliterationType( rReq.GetSlot() );
+ if ( nType )
+ {
+ GetViewData()->GetView()->TransliterateText( nType );
+ rReq.Done();
+ }
+}
+
+void ScCellShell::ExecuteExternalSource(
+ const String& _rFile, const String& _rFilter, const String& _rOptions,
+ const String& _rSource, sal_uLong _nRefresh, SfxRequest& _rRequest )
+{
+ if ( _rFile.Len() && _rSource.Len() ) // filter may be empty
+ {
+ ScRange aLinkRange;
+ sal_Bool bMove = sal_False;
+
+ ScViewData* pData = GetViewData();
+ ScMarkData& rMark = pData->GetMarkData();
+ rMark.MarkToSimple();
+ if ( rMark.IsMarked() )
+ {
+ rMark.GetMarkArea( aLinkRange );
+ bMove = sal_True; // insert/delete cells to fit range
+ }
+ else
+ aLinkRange = ScRange( pData->GetCurX(), pData->GetCurY(), pData->GetTabNo() );
+
+ ScDocFunc aFunc(*pData->GetDocShell());
+ aFunc.InsertAreaLink( _rFile, _rFilter, _rOptions, _rSource,
+ aLinkRange, _nRefresh, bMove, sal_False );
+ _rRequest.Done();
+ }
+ else
+ _rRequest.Ignore();
+}
+
+IMPL_LINK( ScCellShell, DialogClosed, AbstractScLinkedAreaDlg*, EMPTYARG )
+{
+ DBG_ASSERT( pImpl->m_pLinkedDlg, "ScCellShell::DialogClosed(): invalid request" );
+ DBG_ASSERT( pImpl->m_pRequest, "ScCellShell::DialogClosed(): invalid request" );
+ String sFile, sFilter, sOptions, sSource;
+ sal_uLong nRefresh = 0;
+
+ if ( pImpl->m_pLinkedDlg->GetResult() == RET_OK )
+ {
+ sFile = pImpl->m_pLinkedDlg->GetURL();
+ sFilter = pImpl->m_pLinkedDlg->GetFilter();
+ sOptions = pImpl->m_pLinkedDlg->GetOptions();
+ sSource = pImpl->m_pLinkedDlg->GetSource();
+ nRefresh = pImpl->m_pLinkedDlg->GetRefresh();
+ if ( sFile.Len() )
+ pImpl->m_pRequest->AppendItem( SfxStringItem( SID_FILE_NAME, sFile ) );
+ if ( sFilter.Len() )
+ pImpl->m_pRequest->AppendItem( SfxStringItem( SID_FILTER_NAME, sFilter ) );
+ if ( sOptions.Len() )
+ pImpl->m_pRequest->AppendItem( SfxStringItem( SID_FILE_FILTEROPTIONS, sOptions ) );
+ if ( sSource.Len() )
+ pImpl->m_pRequest->AppendItem( SfxStringItem( FN_PARAM_1, sSource ) );
+ if ( nRefresh )
+ pImpl->m_pRequest->AppendItem( SfxUInt32Item( FN_PARAM_2, nRefresh ) );
+ }
+
+ ExecuteExternalSource( sFile, sFilter, sOptions, sSource, nRefresh, *(pImpl->m_pRequest) );
+ return 0;
+}
+
+void ScCellShell::PasteFromClipboard( ScViewData* pViewData, ScTabViewShell* pTabViewShell, bool bShowDialog )
+{
+ Window* pWin = pViewData->GetActiveWin();
+ ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin );
+ ScDocument* pThisDoc = pViewData->GetDocument();
+ ScDPObject* pDPObj = pThisDoc->GetDPAtCursor( pViewData->GetCurX(),
+ pViewData->GetCurY(), pViewData->GetTabNo() );
+ if ( pOwnClip && pDPObj )
+ {
+ // paste from Calc into DataPilot table: sort (similar to drag & drop)
+
+ ScDocument* pClipDoc = pOwnClip->GetDocument();
+ SCTAB nSourceTab = pOwnClip->GetVisibleTab();
+
+ SCCOL nClipStartX;
+ SCROW nClipStartY;
+ SCCOL nClipEndX;
+ SCROW nClipEndY;
+ pClipDoc->GetClipStart( nClipStartX, nClipStartY );
+ pClipDoc->GetClipArea( nClipEndX, nClipEndY, sal_True );
+ nClipEndX = nClipEndX + nClipStartX;
+ nClipEndY = nClipEndY + nClipStartY; // GetClipArea returns the difference
+
+ ScRange aSource( nClipStartX, nClipStartY, nSourceTab, nClipEndX, nClipEndY, nSourceTab );
+ sal_Bool bDone = pTabViewShell->DataPilotMove( aSource, pViewData->GetCurPos() );
+ if ( !bDone )
+ pTabViewShell->ErrorMessage( STR_ERR_DATAPILOT_INPUT );
+ }
+ else
+ {
+ // normal paste
+ WaitObject aWait( pViewData->GetDialogParent() );
+ if (!pOwnClip)
+ pTabViewShell->PasteFromSystem();
+ else
+ {
+ ScDocument* pClipDoc = pOwnClip->GetDocument();
+ sal_uInt16 nFlags = IDF_ALL;
+ if (pClipDoc->GetClipParam().isMultiRange())
+ // For multi-range paste, we paste values by default.
+ nFlags &= ~IDF_FORMULA;
+
+ pTabViewShell->PasteFromClip( nFlags, pClipDoc,
+ PASTE_NOFUNC, sal_False, sal_False, sal_False, INS_NONE, IDF_NONE,
+ bShowDialog ); // allow warning dialog
+ }
+ }
+ pTabViewShell->CellContentChanged(); // => PasteFromSystem() ???
+}
diff --git a/sc/source/ui/view/cellsh2.cxx b/sc/source/ui/view/cellsh2.cxx
new file mode 100644
index 000000000000..eda6b5cb0efd
--- /dev/null
+++ b/sc/source/ui/view/cellsh2.cxx
@@ -0,0 +1,1432 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/request.hxx>
+#include <svl/aeitem.hxx>
+#include <basic/sbxcore.hxx>
+#include <svl/whiter.hxx>
+#include <svl/zforlist.hxx>
+#include <vcl/msgbox.hxx>
+#include <svl/stritem.hxx>
+#include <svl/visitem.hxx>
+#include <unotools/moduleoptions.hxx>
+
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+
+#include "cellsh.hxx"
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "scmod.hxx"
+#include "docsh.hxx"
+#include "document.hxx"
+#include "uiitems.hxx"
+#include "dbfunc.hxx"
+#include "dbdocfun.hxx"
+//CHINA001 #include "lbseldlg.hxx"
+//CHINA001 #include "sortdlg.hxx"
+#include "filtdlg.hxx"
+#include "dbnamdlg.hxx"
+//CHINA001 #include "subtdlg.hxx"
+#include "reffact.hxx"
+#include "pvlaydlg.hxx"
+#include "validat.hxx"
+#include "scresid.hxx"
+//CHINA001 #include "validate.hxx"
+#include "pivot.hxx"
+#include "dpobject.hxx"
+//CHINA001 #include "dapitype.hxx"
+//CHINA001 #include "dapidata.hxx"
+#include "dpsdbtab.hxx" // ScImportSourceDesc
+#include "dpshttab.hxx" // ScSheetSourceDesc
+
+#include "validate.hrc" //CHINA001 add for ScValidationDlg
+#include "scui_def.hxx" //CHINA001
+#include "scabstdlg.hxx" //CHINA001
+#include "impex.hxx"
+#include "asciiopt.hxx"
+using namespace com::sun::star;
+
+//#include "strindlg.hxx" //! Test !!!!!
+
+//static ScArea aPivotSource; //! wohin? (ueber den Dialog retten)
+
+
+#define IS_AVAILABLE(WhichId,ppItem) \
+ (pReqArgs->GetItemState((WhichId), sal_True, ppItem ) == SFX_ITEM_SET)
+
+//------------------------------------------------------------------
+
+bool lcl_GetTextToColumnsRange( const ScViewData* pData, ScRange& rRange )
+{
+ DBG_ASSERT( pData, "lcl_GetTextToColumnsRange: pData is null!" );
+
+ bool bRet = false;
+ const ScMarkData& rMark = pData->GetMarkData();
+
+ if ( rMark.IsMarked() )
+ {
+ if ( !rMark.IsMultiMarked() )
+ {
+ rMark.GetMarkArea( rRange );
+ if ( rRange.aStart.Col() == rRange.aEnd.Col() )
+ {
+ bRet = true;
+ }
+ }
+ }
+ else
+ {
+ const SCCOL nCol = pData->GetCurX();
+ const SCROW nRow = pData->GetCurY();
+ const SCTAB nTab = pData->GetTabNo();
+ rRange = ScRange( nCol, nRow, nTab, nCol, nRow, nTab );
+ bRet = true;
+ }
+
+ const ScDocument* pDoc = pData->GetDocument();
+ DBG_ASSERT( pDoc, "lcl_GetTextToColumnsRange: pDoc is null!" );
+
+ if ( bRet && pDoc->IsBlockEmpty( rRange.aStart.Tab(), rRange.aStart.Col(),
+ rRange.aStart.Row(), rRange.aEnd.Col(),
+ rRange.aEnd.Row() ) )
+ {
+ bRet = false;
+ }
+
+ return bRet;
+}
+
+sal_Bool lcl_GetSortParam( const ScViewData* pData, ScSortParam& rSortParam )
+{
+ ScTabViewShell* pTabViewShell = pData->GetViewShell();
+ ScDBData* pDBData = pTabViewShell->GetDBData();
+ ScDocument* pDoc = pData->GetDocument();
+ SCTAB nTab = pData->GetTabNo();
+ ScDirection eFillDir = DIR_TOP;
+ sal_Bool bSort = sal_True;
+ ScRange aExternalRange;
+
+ if( rSortParam.nCol1 != rSortParam.nCol2 )
+ eFillDir = DIR_LEFT;
+ if( rSortParam.nRow1 != rSortParam.nRow2 )
+ eFillDir = DIR_TOP;
+
+ SCSIZE nCount = pDoc->GetEmptyLinesInBlock( rSortParam.nCol1, rSortParam.nRow1, nTab, rSortParam.nCol2, rSortParam.nRow2, nTab, eFillDir );
+
+ if( rSortParam.nRow2 == MAXROW )
+ aExternalRange = ScRange( rSortParam.nCol1,sal::static_int_cast<SCROW>( nCount ), nTab );
+ else
+ aExternalRange = ScRange( pData->GetCurX(), pData->GetCurY(), nTab );
+
+ SCROW nStartRow = aExternalRange.aStart.Row();
+ SCCOL nStartCol = aExternalRange.aStart.Col();
+ SCROW nEndRow = aExternalRange.aEnd.Row();
+ SCCOL nEndCol = aExternalRange.aEnd.Col();
+ pDoc->GetDataArea( aExternalRange.aStart.Tab(), nStartCol, nStartRow, nEndCol, nEndRow, sal_False, false );
+ aExternalRange.aStart.SetRow( nStartRow );
+ aExternalRange.aStart.SetCol( nStartCol );
+ aExternalRange.aEnd.SetRow( nEndRow );
+ aExternalRange.aEnd.SetCol( nEndCol );
+
+ if(( rSortParam.nCol1 == rSortParam.nCol2 && aExternalRange.aStart.Col() != aExternalRange.aEnd.Col() ) ||
+ ( rSortParam.nRow1 == rSortParam.nRow2 && aExternalRange.aStart.Row() != aExternalRange.aEnd.Row() ) )
+ {
+ sal_uInt16 nFmt = SCA_VALID;
+ String aExtendStr,aCurrentStr;
+
+ pTabViewShell->AddHighlightRange( aExternalRange,Color( COL_LIGHTBLUE ) );
+ ScRange rExtendRange( aExternalRange.aStart.Col(), aExternalRange.aStart.Row(), nTab, aExternalRange.aEnd.Col(), aExternalRange.aEnd.Row(), nTab );
+ rExtendRange.Format( aExtendStr, nFmt, pDoc );
+
+ ScRange rCurrentRange( rSortParam.nCol1, rSortParam.nRow1, nTab, rSortParam.nCol2, rSortParam.nRow2, nTab );
+ rCurrentRange.Format( aCurrentStr, nFmt, pDoc );
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ VclAbstractDialog* pWarningDlg = pFact->CreateScSortWarningDlg( pTabViewShell->GetDialogParent(),aExtendStr,aCurrentStr,RID_SCDLG_SORT_WARNING );
+ DBG_ASSERT(pWarningDlg, "Dialog create fail!");//CHINA001
+ short bResult = pWarningDlg->Execute();
+ if( bResult == BTN_EXTEND_RANGE || bResult == BTN_CURRENT_SELECTION )
+ {
+ if( bResult == BTN_EXTEND_RANGE )
+ {
+ pTabViewShell->MarkRange( aExternalRange, sal_False );
+ pDBData->SetArea( nTab, aExternalRange.aStart.Col(), aExternalRange.aStart.Row(), aExternalRange.aEnd.Col(), aExternalRange.aEnd.Row() );
+ }
+ }
+ else
+ {
+ bSort = sal_False;
+ pData->GetDocShell()->CancelAutoDBRange();
+ }
+
+ delete pWarningDlg;
+ pTabViewShell->ClearHighlightRanges();
+ }
+ return bSort;
+}
+
+//<!-- Added by PengYunQuan for Validity Cell Range Picker
+//after end execute from !IsModalInputMode, it is safer to delay deleting
+namespace
+{
+ long DelayDeleteAbstractDialog( void *pAbstractDialog, void * /*pArg*/ )
+ {
+ delete reinterpret_cast<VclAbstractDialog*>( pAbstractDialog );
+ return 0;
+ }
+}
+//--> Added by PengYunQuan for Validity Cell Range Picker
+
+void ScCellShell::ExecuteDB( SfxRequest& rReq )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ sal_uInt16 nSlotId = rReq.GetSlot();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ ScModule* pScMod = SC_MOD();
+
+ pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
+
+ if ( GetViewData()->HasEditView( GetViewData()->GetActivePart() ) )
+ {
+ pScMod->InputEnterHandler();
+ pTabViewShell->UpdateInputHandler();
+ }
+
+ switch ( nSlotId )
+ {
+ case SID_VIEW_DATA_SOURCE_BROWSER:
+ {
+ // check if database beamer is open
+
+ SfxViewFrame* pViewFrame = pTabViewShell->GetViewFrame();
+ sal_Bool bWasOpen = sal_False;
+ {
+ uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface();
+ uno::Reference<frame::XFrame> xBeamerFrame = xFrame->findFrame(
+ rtl::OUString::createFromAscii("_beamer"),
+ frame::FrameSearchFlag::CHILDREN);
+ if ( xBeamerFrame.is() )
+ bWasOpen = sal_True;
+ }
+
+ if ( bWasOpen )
+ {
+ // close database beamer: just forward to SfxViewFrame
+
+ pViewFrame->ExecuteSlot( rReq );
+ }
+ else
+ {
+ // show database beamer: SfxViewFrame call must be synchronous
+
+ pViewFrame->ExecuteSlot( rReq, (sal_Bool) sal_False ); // sal_False = synchronous
+
+ // select current database in database beamer
+
+ ScImportParam aImportParam;
+ ScDBData* pDBData = pTabViewShell->GetDBData(sal_True,SC_DB_OLD); // don't create if none found
+ if (pDBData)
+ pDBData->GetImportParam( aImportParam );
+
+ ScDBDocFunc::ShowInBeamer( aImportParam, pTabViewShell->GetViewFrame() );
+ }
+ rReq.Done(); // needed because it's a toggle slot
+ }
+ break;
+
+ case SID_REIMPORT_DATA:
+ {
+ sal_Bool bOk = sal_False;
+ ScDBData* pDBData = pTabViewShell->GetDBData(sal_True,SC_DB_OLD);
+ if (pDBData)
+ {
+ ScImportParam aImportParam;
+ pDBData->GetImportParam( aImportParam );
+ if (aImportParam.bImport && !pDBData->HasImportSelection())
+ {
+ pTabViewShell->ImportData( aImportParam );
+ pDBData->SetImportParam( aImportParam ); //! Undo ??
+ bOk = sal_True;
+ }
+ }
+
+ if (!bOk && ! rReq.IsAPI() )
+ pTabViewShell->ErrorMessage(STR_REIMPORT_EMPTY);
+
+ if( bOk )
+ rReq.Done();
+ }
+ break;
+
+ case SID_REFRESH_DBAREA:
+ {
+ ScDBData* pDBData = pTabViewShell->GetDBData(sal_True,SC_DB_OLD);
+ if (pDBData)
+ {
+ // Import wiederholen wie SID_REIMPORT_DATA
+
+ sal_Bool bContinue = sal_True;
+ ScImportParam aImportParam;
+ pDBData->GetImportParam( aImportParam );
+ if (aImportParam.bImport && !pDBData->HasImportSelection())
+ {
+ bContinue = pTabViewShell->ImportData( aImportParam );
+ pDBData->SetImportParam( aImportParam ); //! Undo ??
+
+ // markieren (Groesse kann sich geaendert haben)
+ ScRange aNewRange;
+ pDBData->GetArea(aNewRange);
+ pTabViewShell->MarkRange(aNewRange);
+ }
+
+ if ( bContinue ) // #41905# Fehler beim Import -> Abbruch
+ {
+ // interne Operationen, wenn welche gespeichert
+
+ if ( pDBData->HasQueryParam() || pDBData->HasSortParam() ||
+ pDBData->HasSubTotalParam() )
+ pTabViewShell->RepeatDB();
+
+ // Pivottabellen die den Bereich als Quelldaten haben
+
+ ScRange aRange;
+ pDBData->GetArea(aRange);
+ GetViewData()->GetDocShell()->RefreshPivotTables(aRange);
+ }
+ }
+ rReq.Done();
+ }
+ break;
+
+ case SID_SBA_BRW_INSERT:
+ {
+ DBG_ERROR( "Deprecated Slot" );
+ }
+ break;
+
+ case SID_SUBTOTALS:
+ {
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ if ( pArgs )
+ {
+ pTabViewShell->DoSubTotals( ((const ScSubTotalItem&) pArgs->Get( SCITEM_SUBTDATA )).
+ GetSubTotalData() );
+ rReq.Done();
+ }
+ else
+ {
+ //CHINA001 ScSubTotalDlg* pDlg = NULL;
+ SfxAbstractTabDialog * pDlg = NULL;
+ ScSubTotalParam aSubTotalParam;
+ SfxItemSet aArgSet( GetPool(), SCITEM_SUBTDATA, SCITEM_SUBTDATA );
+
+ ScDBData* pDBData = pTabViewShell->GetDBData();
+ pDBData->GetSubTotalParam( aSubTotalParam );
+ aSubTotalParam.bRemoveOnly = sal_False;
+
+ aArgSet.Put( ScSubTotalItem( SCITEM_SUBTDATA, GetViewData(), &aSubTotalParam ) );
+ //CHINA001 pDlg = new ScSubTotalDlg( pTabViewShell->GetDialogParent(), &aArgSet );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ pDlg = pFact->CreateScSubTotalDlg( pTabViewShell->GetDialogParent(), &aArgSet, RID_SCDLG_SUBTOTALS );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ pDlg->SetCurPageId(1);
+
+ short bResult = pDlg->Execute();
+
+ if ( (bResult == RET_OK) || (bResult == SCRET_REMOVE) )
+ {
+ const SfxItemSet* pOutSet = NULL;
+
+ if ( bResult == RET_OK )
+ {
+ pOutSet = pDlg->GetOutputItemSet();
+ aSubTotalParam =
+ ((const ScSubTotalItem&)
+ pOutSet->Get( SCITEM_SUBTDATA )).
+ GetSubTotalData();
+ }
+ else // if (bResult == SCRET_REMOVE)
+ {
+ pOutSet = &aArgSet;
+ aSubTotalParam.bRemoveOnly = sal_True;
+ aSubTotalParam.bReplace = sal_True;
+ aArgSet.Put( ScSubTotalItem( SCITEM_SUBTDATA,
+ GetViewData(),
+ &aSubTotalParam ) );
+ }
+
+ pTabViewShell->DoSubTotals( aSubTotalParam );
+ rReq.Done( *pOutSet );
+ }
+ else
+ GetViewData()->GetDocShell()->CancelAutoDBRange();
+
+ delete pDlg;
+ }
+ }
+ break;
+
+ case SID_SORT_DESCENDING:
+ case SID_SORT_ASCENDING:
+ {
+ //#i60401 ux-ctest: Calc does not support all users' strategies regarding sorting data
+ //the patch comes from maoyg
+ ScSortParam aSortParam;
+ ScDBData* pDBData = pTabViewShell->GetDBData();
+ ScViewData* pData = GetViewData();
+
+ pDBData->GetSortParam( aSortParam );
+
+ if( lcl_GetSortParam( pData, aSortParam ) )
+ {
+ SfxItemSet aArgSet( GetPool(), SCITEM_SORTDATA, SCITEM_SORTDATA );
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCCOL nTab = GetViewData()->GetTabNo();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ pDBData->GetSortParam( aSortParam );
+ sal_Bool bHasHeader = pDoc->HasColHeader( aSortParam.nCol1, aSortParam.nRow1, aSortParam.nCol2, aSortParam.nRow2, nTab );
+
+ if( nCol < aSortParam.nCol1 )
+ nCol = aSortParam.nCol1;
+ else if( nCol > aSortParam.nCol2 )
+ nCol = aSortParam.nCol2;
+
+ aSortParam.bHasHeader = bHasHeader;
+ aSortParam.bByRow = sal_True;
+ aSortParam.bCaseSens = sal_False;
+ aSortParam.bIncludePattern = sal_True;
+ aSortParam.bInplace = sal_True;
+ aSortParam.bDoSort[0] = sal_True;
+ aSortParam.nField[0] = nCol;
+ aSortParam.bAscending[0] = (nSlotId == SID_SORT_ASCENDING);
+
+ for ( sal_uInt16 i=1; i<MAXSORT; i++ )
+ aSortParam.bDoSort[i] = sal_False;
+
+ aArgSet.Put( ScSortItem( SCITEM_SORTDATA, GetViewData(), &aSortParam ) );
+
+ pTabViewShell->UISort( aSortParam ); // Teilergebnisse bei Bedarf neu
+
+ rReq.Done();
+ }
+ }
+ break;
+
+ case SID_SORT:
+ {
+ const SfxItemSet* pArgs = rReq.GetArgs();
+
+ //#i60401 ux-ctest: Calc does not support all users' strategies regarding sorting data
+ //the patch comes from maoyg
+
+ if ( pArgs ) // Basic
+ {
+ ScSortParam aSortParam;
+ ScDBData* pDBData = pTabViewShell->GetDBData();
+ ScViewData* pData = GetViewData();
+
+ pDBData->GetSortParam( aSortParam );
+
+ if( lcl_GetSortParam( pData, aSortParam ) )
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ pDBData->GetSortParam( aSortParam );
+ sal_Bool bHasHeader = pDoc->HasColHeader( aSortParam.nCol1, aSortParam.nRow1, aSortParam.nCol2, aSortParam.nRow2, pData->GetTabNo() );
+ if( bHasHeader )
+ aSortParam.bHasHeader = bHasHeader;
+
+ aSortParam.bInplace = sal_True; // von Basic immer
+
+ const SfxPoolItem* pItem;
+ if ( pArgs->GetItemState( SID_SORT_BYROW, sal_True, &pItem ) == SFX_ITEM_SET )
+ aSortParam.bByRow = ((const SfxBoolItem*)pItem)->GetValue();
+ if ( pArgs->GetItemState( SID_SORT_HASHEADER, sal_True, &pItem ) == SFX_ITEM_SET )
+ aSortParam.bHasHeader = ((const SfxBoolItem*)pItem)->GetValue();
+ if ( pArgs->GetItemState( SID_SORT_CASESENS, sal_True, &pItem ) == SFX_ITEM_SET )
+ aSortParam.bCaseSens = ((const SfxBoolItem*)pItem)->GetValue();
+ if ( pArgs->GetItemState( SID_SORT_ATTRIBS, sal_True, &pItem ) == SFX_ITEM_SET )
+ aSortParam.bIncludePattern = ((const SfxBoolItem*)pItem)->GetValue();
+ if ( pArgs->GetItemState( SID_SORT_USERDEF, sal_True, &pItem ) == SFX_ITEM_SET )
+ {
+ sal_uInt16 nUserIndex = ((const SfxUInt16Item*)pItem)->GetValue();
+ aSortParam.bUserDef = ( nUserIndex != 0 );
+ if ( nUserIndex )
+ aSortParam.nUserIndex = nUserIndex - 1; // Basic: 1-basiert
+ }
+
+ SCCOLROW nField0 = 0;
+ if ( pArgs->GetItemState( FN_PARAM_1, sal_True, &pItem ) == SFX_ITEM_SET )
+ nField0 = ((const SfxInt32Item*)pItem)->GetValue();
+ aSortParam.bDoSort[0] = ( nField0 != 0 );
+ aSortParam.nField[0] = nField0 > 0 ? (nField0-1) : 0;
+ if ( pArgs->GetItemState( FN_PARAM_2, sal_True, &pItem ) == SFX_ITEM_SET )
+ aSortParam.bAscending[0] = ((const SfxBoolItem*)pItem)->GetValue();
+ SCCOLROW nField1 = 0;
+ if ( pArgs->GetItemState( FN_PARAM_3, sal_True, &pItem ) == SFX_ITEM_SET )
+ nField1 = ((const SfxInt32Item*)pItem)->GetValue();
+ aSortParam.bDoSort[1] = ( nField1 != 0 );
+ aSortParam.nField[1] = nField1 > 0 ? (nField1-1) : 0;
+ if ( pArgs->GetItemState( FN_PARAM_4, sal_True, &pItem ) == SFX_ITEM_SET )
+ aSortParam.bAscending[1] = ((const SfxBoolItem*)pItem)->GetValue();
+ SCCOLROW nField2 = 0;
+ if ( pArgs->GetItemState( FN_PARAM_5, sal_True, &pItem ) == SFX_ITEM_SET )
+ nField2 = ((const SfxInt32Item*)pItem)->GetValue();
+ aSortParam.bDoSort[2] = ( nField2 != 0 );
+ aSortParam.nField[2] = nField2 > 0 ? (nField2-1) : 0;
+ if ( pArgs->GetItemState( FN_PARAM_6, sal_True, &pItem ) == SFX_ITEM_SET )
+ aSortParam.bAscending[2] = ((const SfxBoolItem*)pItem)->GetValue();
+
+ // Teilergebnisse bei Bedarf neu
+ pTabViewShell->UISort( aSortParam );
+ rReq.Done();
+ }
+ }
+ else
+ {
+ ScSortParam aSortParam;
+ ScDBData* pDBData = pTabViewShell->GetDBData();
+ ScViewData* pData = GetViewData();
+
+ pDBData->GetSortParam( aSortParam );
+
+ if( lcl_GetSortParam( pData, aSortParam ) )
+ {
+ SfxAbstractTabDialog* pDlg = NULL;
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SfxItemSet aArgSet( GetPool(), SCITEM_SORTDATA, SCITEM_SORTDATA );
+
+ pDBData->GetSortParam( aSortParam );
+ sal_Bool bHasHeader = pDoc->HasColHeader( aSortParam.nCol1, aSortParam.nRow1, aSortParam.nCol2, aSortParam.nRow2, pData->GetTabNo() );
+ if( bHasHeader )
+ aSortParam.bHasHeader = bHasHeader;
+
+ aArgSet.Put( ScSortItem( SCITEM_SORTDATA, GetViewData(), &aSortParam ) );
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ pDlg = pFact->CreateScSortDlg( pTabViewShell->GetDialogParent(), &aArgSet, RID_SCDLG_SORT );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ pDlg->SetCurPageId(1);
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
+ const ScSortParam& rOutParam = ((const ScSortItem&)
+ pOutSet->Get( SCITEM_SORTDATA )).GetSortData();
+
+ // Teilergebnisse bei Bedarf neu
+ pTabViewShell->UISort( rOutParam );
+
+ if ( rOutParam.bInplace )
+ {
+ rReq.AppendItem( SfxBoolItem( SID_SORT_BYROW,
+ rOutParam.bByRow ) );
+ rReq.AppendItem( SfxBoolItem( SID_SORT_HASHEADER,
+ rOutParam.bHasHeader ) );
+ rReq.AppendItem( SfxBoolItem( SID_SORT_CASESENS,
+ rOutParam.bCaseSens ) );
+ rReq.AppendItem( SfxBoolItem( SID_SORT_ATTRIBS,
+ rOutParam.bIncludePattern ) );
+ sal_uInt16 nUser = rOutParam.bUserDef ? ( rOutParam.nUserIndex + 1 ) : 0;
+ rReq.AppendItem( SfxUInt16Item( SID_SORT_USERDEF, nUser ) );
+ if ( rOutParam.bDoSort[0] )
+ {
+ rReq.AppendItem( SfxInt32Item( FN_PARAM_1,
+ rOutParam.nField[0] + 1 ) );
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_2,
+ rOutParam.bAscending[0] ) );
+ }
+ if ( rOutParam.bDoSort[1] )
+ {
+ rReq.AppendItem( SfxInt32Item( FN_PARAM_3,
+ rOutParam.nField[1] + 1 ) );
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_4,
+ rOutParam.bAscending[1] ) );
+ }
+ if ( rOutParam.bDoSort[2] )
+ {
+ rReq.AppendItem( SfxInt32Item( FN_PARAM_5,
+ rOutParam.nField[2] + 1 ) );
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_6,
+ rOutParam.bAscending[2] ) );
+ }
+ }
+
+ rReq.Done();
+ }
+ else
+ GetViewData()->GetDocShell()->CancelAutoDBRange();
+
+ delete pDlg;
+ }
+ }
+ }
+ break;
+
+ case SID_FILTER:
+ {
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ if ( pArgs )
+ {
+ DBG_ERROR("SID_FILTER with arguments?");
+ pTabViewShell->Query( ((const ScQueryItem&)
+ pArgs->Get( SCITEM_QUERYDATA )).GetQueryData(), NULL, sal_True );
+ rReq.Done();
+ }
+ else
+ {
+ sal_uInt16 nId = ScFilterDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? sal_False : sal_True );
+ }
+ }
+ break;
+
+ case SID_SPECIAL_FILTER:
+ {
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ if ( pArgs )
+ {
+ DBG_ERROR("SID_SPECIAL_FILTER with arguments?");
+ pTabViewShell->Query( ((const ScQueryItem&)
+ pArgs->Get( SCITEM_QUERYDATA )).GetQueryData(), NULL, sal_True );
+ rReq.Done();
+ }
+ else
+ {
+ sal_uInt16 nId = ScSpecialFilterDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? sal_False : sal_True );
+ }
+ }
+ break;
+
+ case FID_FILTER_OK:
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && SFX_ITEM_SET ==
+ pReqArgs->GetItemState( SCITEM_QUERYDATA, sal_True, &pItem ) )
+ {
+ const ScQueryItem& rQueryItem = static_cast<const ScQueryItem&>(*pItem);
+
+ SCTAB nCurTab = GetViewData()->GetTabNo();
+ SCTAB nRefTab = GetViewData()->GetRefTabNo();
+
+ // If RefInput switched to a different sheet from the data sheet,
+ // switch back:
+
+ if ( nCurTab != nRefTab )
+ {
+ pTabViewShell->SetTabNo( nRefTab );
+ pTabViewShell->PaintExtras();
+ }
+
+ ScRange aAdvSource;
+ if (rQueryItem.GetAdvancedQuerySource(aAdvSource))
+ pTabViewShell->Query( rQueryItem.GetQueryData(), &aAdvSource, sal_True );
+ else
+ pTabViewShell->Query( rQueryItem.GetQueryData(), NULL, sal_True );
+ rReq.Done( *pReqArgs );
+ }
+ }
+ break;
+
+ case SID_UNFILTER:
+ {
+ ScQueryParam aParam;
+ ScDBData* pDBData = pTabViewShell->GetDBData();
+
+ pDBData->GetQueryParam( aParam );
+ SCSIZE nEC = aParam.GetEntryCount();
+ for (SCSIZE i=0; i<nEC; i++)
+ aParam.GetEntry(i).bDoQuery = sal_False;
+ aParam.bDuplicate = sal_True;
+ pTabViewShell->Query( aParam, NULL, sal_True );
+ rReq.Done();
+ }
+ break;
+
+ case SID_AUTO_FILTER:
+ pTabViewShell->ToggleAutoFilter();
+ rReq.Done();
+ break;
+
+ case SID_AUTOFILTER_HIDE:
+ pTabViewShell->HideAutoFilter();
+ rReq.Done();
+ break;
+
+ case SID_PIVOT_TABLE:
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && SFX_ITEM_SET ==
+ pReqArgs->GetItemState( SCITEM_PIVOTDATA, sal_True, &pItem ) )
+ {
+ SCTAB nCurTab = GetViewData()->GetTabNo();
+ SCTAB nRefTab = GetViewData()->GetRefTabNo();
+
+ // Wenn RefInput auf andere Tabelle als Datentabelle umgeschaltet
+ // hat wieder zurueckschalten:
+
+ if ( nCurTab != nRefTab )
+ {
+ pTabViewShell->SetTabNo( nRefTab );
+ pTabViewShell->PaintExtras();
+ }
+
+ const ScDPObject* pDPObject = pTabViewShell->GetDialogDPObject();
+ if ( pDPObject )
+ {
+ const ScPivotItem* pPItem = (const ScPivotItem*)pItem;
+ bool bSuccess = pTabViewShell->MakePivotTable(
+ pPItem->GetData(), pPItem->GetDestRange(), pPItem->IsNewSheet(), *pDPObject );
+ SfxBoolItem aRet(0, bSuccess);
+ rReq.SetReturnValue(aRet);
+ }
+ rReq.Done();
+ }
+ else if (rReq.IsAPI())
+ SbxBase::SetError(SbxERR_BAD_PARAMETER);
+ }
+ break;
+
+ case SID_OPENDLG_PIVOTTABLE:
+ {
+ ScViewData* pData = GetViewData();
+ ScDocument* pDoc = pData->GetDocument();
+
+ ScDPObject* pNewDPObject = NULL;
+
+ // ScPivot is no longer used...
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor(
+ pData->GetCurX(), pData->GetCurY(),
+ pData->GetTabNo() );
+ if ( pDPObj ) // on an existing table?
+ {
+ pNewDPObject = new ScDPObject( *pDPObj );
+ }
+ else // create new table
+ {
+ // select database range or data
+ pTabViewShell->GetDBData( sal_True, SC_DB_OLD );
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
+ pTabViewShell->MarkDataArea( sal_False );
+
+ // output to cursor position for non-sheet data
+ ScAddress aDestPos( pData->GetCurX(), pData->GetCurY(),
+ pData->GetTabNo() );
+
+ // first select type of source data
+
+ sal_Bool bEnableExt = ScDPObject::HasRegisteredSources();
+ //CHINA001 ScDataPilotSourceTypeDlg* pTypeDlg = new ScDataPilotSourceTypeDlg(
+ //CHINA001 pTabViewShell->GetDialogParent(), bEnableExt );
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScDataPilotSourceTypeDlg* pTypeDlg = pFact->CreateScDataPilotSourceTypeDlg( pTabViewShell->GetDialogParent(), bEnableExt, RID_SCDLG_DAPITYPE );
+ DBG_ASSERT(pTypeDlg, "Dialog create fail!");//CHINA001
+ if ( pTypeDlg->Execute() == RET_OK )
+ {
+ if ( pTypeDlg->IsExternal() )
+ {
+ uno::Sequence<rtl::OUString> aSources = ScDPObject::GetRegisteredSources();
+ //CHINA001 ScDataPilotServiceDlg* pServDlg = new ScDataPilotServiceDlg(
+ //CHINA001 pTabViewShell->GetDialogParent(), aSources );
+ AbstractScDataPilotServiceDlg* pServDlg = pFact->CreateScDataPilotServiceDlg( pTabViewShell->GetDialogParent(), aSources, RID_SCDLG_DAPISERVICE );
+ DBG_ASSERT(pServDlg, "Dialog create fail!");//CHINA001
+ if ( pServDlg->Execute() == RET_OK )
+ {
+ ScDPServiceDesc aServDesc(
+ pServDlg->GetServiceName(),
+ pServDlg->GetParSource(),
+ pServDlg->GetParName(),
+ pServDlg->GetParUser(),
+ pServDlg->GetParPass() );
+ pNewDPObject = new ScDPObject( pDoc );
+ pNewDPObject->SetServiceData( aServDesc );
+ }
+ delete pServDlg;
+ }
+ else if ( pTypeDlg->IsDatabase() )
+ {
+ //CHINA001 ScDataPilotDatabaseDlg* pDataDlg = new ScDataPilotDatabaseDlg(
+ //CHINA001 pTabViewShell->GetDialogParent() );
+ //ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScDataPilotDatabaseDlg* pDataDlg = pFact->CreateScDataPilotDatabaseDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_DAPIDATA);
+ DBG_ASSERT(pDataDlg, "Dialog create fail!");//CHINA001
+ if ( pDataDlg->Execute() == RET_OK )
+ {
+ ScImportSourceDesc aImpDesc;
+ pDataDlg->GetValues( aImpDesc );
+ pNewDPObject = new ScDPObject( pDoc );
+ pNewDPObject->SetImportDesc( aImpDesc );
+ }
+ delete pDataDlg;
+ }
+ else // selection
+ {
+ //! use database ranges (select before type dialog?)
+ ScRange aRange;
+ ScMarkType eType = GetViewData()->GetSimpleArea(aRange);
+ if ( (eType & SC_MARK_SIMPLE) == SC_MARK_SIMPLE )
+ {
+ // Shrink the range to the data area.
+ SCCOL nStartCol = aRange.aStart.Col(), nEndCol = aRange.aEnd.Col();
+ SCROW nStartRow = aRange.aStart.Row(), nEndRow = aRange.aEnd.Row();
+ if (pDoc->ShrinkToDataArea(aRange.aStart.Tab(), nStartCol, nStartRow, nEndCol, nEndRow))
+ {
+ aRange.aStart.SetCol(nStartCol);
+ aRange.aStart.SetRow(nStartRow);
+ aRange.aEnd.SetCol(nEndCol);
+ aRange.aEnd.SetRow(nEndRow);
+ rMark.SetMarkArea(aRange);
+ pTabViewShell->MarkRange(aRange);
+ }
+
+ sal_Bool bOK = sal_True;
+ if ( pDoc->HasSubTotalCells( aRange ) )
+ {
+ // confirm selection if it contains SubTotal cells
+
+ QueryBox aBox( pTabViewShell->GetDialogParent(),
+ WinBits(WB_YES_NO | WB_DEF_YES),
+ ScGlobal::GetRscString(STR_DATAPILOT_SUBTOTAL) );
+ if (aBox.Execute() == RET_NO)
+ bOK = sal_False;
+ }
+ if (bOK)
+ {
+ ScSheetSourceDesc aShtDesc;
+ aShtDesc.aSourceRange = aRange;
+ pNewDPObject = new ScDPObject( pDoc );
+ pNewDPObject->SetSheetDesc( aShtDesc );
+
+ // output below source data
+ if ( aRange.aEnd.Row()+2 <= MAXROW - 4 )
+ aDestPos = ScAddress( aRange.aStart.Col(),
+ aRange.aEnd.Row()+2,
+ aRange.aStart.Tab() );
+ }
+ }
+ }
+ }
+ delete pTypeDlg;
+
+ if ( pNewDPObject )
+ pNewDPObject->SetOutRange( aDestPos );
+
+#if 0
+ ScDBData* pDBData = pTabViewShell->GetDBData();
+ String aErrMsg;
+
+ pDBData->GetArea( nTab, nCol1, nRow1, nCol2, nRow2 );
+
+ bAreaOk = sal_True;
+ if ( nRow2-nRow1 < 1 )
+ {
+ // "mindestens eine Datenzeile"
+ pTabViewShell->ErrorMessage(STR_PIVOT_INVALID_DBAREA);
+ bAreaOk = sal_False;
+ }
+ else if (!pDBData->HasHeader())
+ {
+ if ( MessBox( pTabViewShell->GetDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), // "StarCalc"
+ ScGlobal::GetRscString( STR_MSSG_MAKEAUTOFILTER_0 ) // Koepfe aus erster Zeile?
+ ).Execute() == RET_YES )
+ {
+ pDBData->SetHeader( sal_True ); //! Undo ??
+ }
+ else
+ bAreaOk = sal_False;
+ }
+#endif
+ }
+
+ pTabViewShell->SetDialogDPObject( pNewDPObject ); // is copied
+ if ( pNewDPObject )
+ {
+ // start layout dialog
+
+ sal_uInt16 nId = ScPivotLayoutWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+ pScMod->SetRefDialog( nId, pWnd ? sal_False : sal_True );
+ }
+ delete pNewDPObject;
+ }
+ break;
+
+ case SID_DEFINE_DBNAME:
+ {
+
+ sal_uInt16 nId = ScDbNameDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? sal_False : sal_True );
+
+ }
+ break;
+
+ case SID_SELECT_DB:
+ {
+ if ( pReqArgs )
+ {
+ const SfxStringItem* pItem =
+ (const SfxStringItem*)&pReqArgs->Get( SID_SELECT_DB );
+
+ if( pItem )
+ {
+ pTabViewShell->GotoDBArea( pItem->GetValue() );
+ rReq.Done();
+ }
+ else
+ {
+ DBG_ERROR("NULL");
+ }
+ }
+ else
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDBCollection* pDBCol = pDoc->GetDBCollection();
+
+ if ( pDBCol )
+ {
+ const String aStrNoName( ScGlobal::GetRscString(STR_DB_NONAME) );
+ List aList;
+ sal_uInt16 nDBCount = pDBCol->GetCount();
+ ScDBData* pDbData = NULL;
+ String* pDBName = NULL;
+
+ for ( sal_uInt16 i=0; i < nDBCount; i++ )
+ {
+ pDbData = (ScDBData*)(pDBCol->At( i ));
+ if ( pDbData )
+ {
+ pDBName = new String;
+ pDbData->GetName( *pDBName );
+
+ if ( *pDBName != aStrNoName )
+ aList.Insert( pDBName );
+ else
+ DELETEZ(pDBName);
+ }
+ }
+
+//CHINA001 ScSelEntryDlg* pDlg =
+//CHINA001 new ScSelEntryDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_SELECTDB,
+//CHINA001 String(ScResId(SCSTR_SELECTDB)),
+//CHINA001 String(ScResId(SCSTR_AREAS)),
+//CHINA001 aList );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScSelEntryDlg* pDlg = pFact->CreateScSelEntryDlg( pTabViewShell->GetDialogParent(),
+ RID_SCDLG_SELECTDB,
+ String(ScResId(SCSTR_SELECTDB)),
+ String(ScResId(SCSTR_AREAS)),
+ aList,
+ RID_SCDLG_SELECTDB);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( pDlg->Execute() == RET_OK )
+ {
+ String aName = pDlg->GetSelectEntry();
+ pTabViewShell->GotoDBArea( aName );
+ rReq.AppendItem( SfxStringItem( SID_SELECT_DB, aName ) );
+ rReq.Done();
+ }
+
+ delete pDlg;
+
+ void* pEntry = aList.First();
+ while ( pEntry )
+ {
+ delete (String*) aList.Remove( pEntry );
+ pEntry = aList.Next();
+ }
+ }
+ }
+ }
+ break;
+
+ case FID_VALIDATION:
+ {
+ const SfxPoolItem* pItem;
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ if ( pArgs )
+ {
+ DBG_ERROR("spaeter...");
+ }
+ else
+ {
+ //CHINA001 SfxItemSet aArgSet( GetPool(), ScTPValidationValue::GetRanges() );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+ ::GetTabPageRanges ScTPValidationValueGetRanges = pFact->GetTabPageRangesFunc(TP_VALIDATION_VALUES);
+ DBG_ASSERT(ScTPValidationValueGetRanges, "TabPage create fail!");//CHINA001
+ SfxItemSet aArgSet( GetPool(), (*ScTPValidationValueGetRanges)() );//CHINA001
+ ScValidationMode eMode = SC_VALID_ANY;
+ ScConditionMode eOper = SC_COND_EQUAL;
+ String aExpr1, aExpr2;
+ sal_Bool bBlank = sal_True;
+ sal_Int16 nListType = ValidListType::UNSORTED;
+ sal_Bool bShowHelp = sal_False;
+ String aHelpTitle, aHelpText;
+ sal_Bool bShowError = sal_False;
+ ScValidErrorStyle eErrStyle = SC_VALERR_STOP;
+ String aErrTitle, aErrText;
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SCCOL nCurX = GetViewData()->GetCurX();
+ SCROW nCurY = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScAddress aCursorPos( nCurX, nCurY, nTab );
+ sal_uLong nIndex = ((SfxUInt32Item*)pDoc->GetAttr(
+ nCurX, nCurY, nTab, ATTR_VALIDDATA ))->GetValue();
+ if ( nIndex )
+ {
+ const ScValidationData* pOldData = pDoc->GetValidationEntry( nIndex );
+ if ( pOldData )
+ {
+ eMode = pOldData->GetDataMode();
+ eOper = pOldData->GetOperation();
+ sal_uLong nNumFmt = 0;
+ if ( eMode == SC_VALID_DATE || eMode == SC_VALID_TIME )
+ {
+ short nType = ( eMode == SC_VALID_DATE ) ? NUMBERFORMAT_DATE
+ : NUMBERFORMAT_TIME;
+ nNumFmt = pDoc->GetFormatTable()->GetStandardFormat(
+ nType, ScGlobal::eLnge );
+ }
+ aExpr1 = pOldData->GetExpression( aCursorPos, 0, nNumFmt );
+ aExpr2 = pOldData->GetExpression( aCursorPos, 1, nNumFmt );
+ bBlank = pOldData->IsIgnoreBlank();
+ nListType = pOldData->GetListType();
+
+ bShowHelp = pOldData->GetInput( aHelpTitle, aHelpText );
+ bShowError = pOldData->GetErrMsg( aErrTitle, aErrText, eErrStyle );
+
+ aArgSet.Put( SfxAllEnumItem( FID_VALID_MODE, sal::static_int_cast<sal_uInt16>(eMode) ) );
+ aArgSet.Put( SfxAllEnumItem( FID_VALID_CONDMODE, sal::static_int_cast<sal_uInt16>(eOper) ) );
+ aArgSet.Put( SfxStringItem( FID_VALID_VALUE1, aExpr1 ) );
+ aArgSet.Put( SfxStringItem( FID_VALID_VALUE2, aExpr2 ) );
+ aArgSet.Put( SfxBoolItem( FID_VALID_BLANK, bBlank ) );
+ aArgSet.Put( SfxInt16Item( FID_VALID_LISTTYPE, nListType ) );
+ aArgSet.Put( SfxBoolItem( FID_VALID_SHOWHELP, bShowHelp ) );
+ aArgSet.Put( SfxStringItem( FID_VALID_HELPTITLE, aHelpTitle ) );
+ aArgSet.Put( SfxStringItem( FID_VALID_HELPTEXT, aHelpText ) );
+ aArgSet.Put( SfxBoolItem( FID_VALID_SHOWERR, bShowError ) );
+ aArgSet.Put( SfxAllEnumItem( FID_VALID_ERRSTYLE, sal::static_int_cast<sal_uInt16>(eErrStyle) ) );
+ aArgSet.Put( SfxStringItem( FID_VALID_ERRTITLE, aErrTitle ) );
+ aArgSet.Put( SfxStringItem( FID_VALID_ERRTEXT, aErrText ) );
+ }
+ }
+
+ //CHINA001 ScValidationDlg* pDlg = new ScValidationDlg( NULL, &aArgSet );
+ //CHINA001 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ //CHINA001 DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //SfxAbstractTabDialog* pDlg = pFact->CreateScValidationDlg( NULL, &aArgSet, TAB_DLG_VALIDATION );
+ SfxAbstractTabDialog* pDlg = pFact->CreateScValidationDlg( NULL, &aArgSet, TAB_DLG_VALIDATION, pTabViewShell );
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ //<!--Modified by PengYunQuan for Validity Cell Range Picker
+ //if ( pDlg->Execute() == RET_OK )
+ short nResult = pDlg->Execute();
+ pTabViewShell->SetTabNo( nTab );//When picking Cell Range ,other Tab may be switched. Need restore the correct tab
+ if ( nResult == RET_OK )
+ //-->Modified by PengYunQuan for Validity Cell Range Picker
+ {
+ const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
+
+ if ( pOutSet->GetItemState( FID_VALID_MODE, sal_True, &pItem ) == SFX_ITEM_SET )
+ eMode = (ScValidationMode) ((const SfxAllEnumItem*)pItem)->GetValue();
+ if ( pOutSet->GetItemState( FID_VALID_CONDMODE, sal_True, &pItem ) == SFX_ITEM_SET )
+ eOper = (ScConditionMode) ((const SfxAllEnumItem*)pItem)->GetValue();
+ if ( pOutSet->GetItemState( FID_VALID_VALUE1, sal_True, &pItem ) == SFX_ITEM_SET )
+ {
+ String aTemp1 = ((const SfxStringItem*)pItem)->GetValue();
+ if (eMode == SC_VALID_DATE || eMode == SC_VALID_TIME)
+ {
+ sal_uInt32 nNumIndex = 0;
+ double nVal;
+ if (pDoc->GetFormatTable()->IsNumberFormat(aTemp1, nNumIndex, nVal))
+ aExpr1 =String( ::rtl::math::doubleToUString( nVal,
+ rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
+ ScGlobal::pLocaleData->getNumDecimalSep().GetChar(0), sal_True));
+ else
+ aExpr1 = aTemp1;
+ }
+ else
+ aExpr1 = aTemp1;
+ }
+ if ( pOutSet->GetItemState( FID_VALID_VALUE2, sal_True, &pItem ) == SFX_ITEM_SET )
+ {
+ String aTemp2 = ((const SfxStringItem*)pItem)->GetValue();
+ if (eMode == SC_VALID_DATE || eMode == SC_VALID_TIME)
+ {
+ sal_uInt32 nNumIndex = 0;
+ double nVal;
+ if (pDoc->GetFormatTable()->IsNumberFormat(aTemp2, nNumIndex, nVal))
+ aExpr2 =String( ::rtl::math::doubleToUString( nVal,
+ rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
+ ScGlobal::pLocaleData->getNumDecimalSep().GetChar(0), sal_True));
+ else
+ aExpr2 = aTemp2;
+ }
+ else
+ aExpr2 = aTemp2;
+ }
+
+ if ( pOutSet->GetItemState( FID_VALID_BLANK, sal_True, &pItem ) == SFX_ITEM_SET )
+ bBlank = ((const SfxBoolItem*)pItem)->GetValue();
+ if ( pOutSet->GetItemState( FID_VALID_LISTTYPE, sal_True, &pItem ) == SFX_ITEM_SET )
+ nListType = ((const SfxInt16Item*)pItem)->GetValue();
+
+ if ( pOutSet->GetItemState( FID_VALID_SHOWHELP, sal_True, &pItem ) == SFX_ITEM_SET )
+ bShowHelp = ((const SfxBoolItem*)pItem)->GetValue();
+ if ( pOutSet->GetItemState( FID_VALID_HELPTITLE, sal_True, &pItem ) == SFX_ITEM_SET )
+ aHelpTitle = ((const SfxStringItem*)pItem)->GetValue();
+ if ( pOutSet->GetItemState( FID_VALID_HELPTEXT, sal_True, &pItem ) == SFX_ITEM_SET )
+ aHelpText = ((const SfxStringItem*)pItem)->GetValue();
+
+ if ( pOutSet->GetItemState( FID_VALID_SHOWERR, sal_True, &pItem ) == SFX_ITEM_SET )
+ bShowError = ((const SfxBoolItem*)pItem)->GetValue();
+ if ( pOutSet->GetItemState( FID_VALID_ERRSTYLE, sal_True, &pItem ) == SFX_ITEM_SET )
+ eErrStyle = (ScValidErrorStyle) ((const SfxAllEnumItem*)pItem)->GetValue();
+ if ( pOutSet->GetItemState( FID_VALID_ERRTITLE, sal_True, &pItem ) == SFX_ITEM_SET )
+ aErrTitle = ((const SfxStringItem*)pItem)->GetValue();
+ if ( pOutSet->GetItemState( FID_VALID_ERRTEXT, sal_True, &pItem ) == SFX_ITEM_SET )
+ aErrText = ((const SfxStringItem*)pItem)->GetValue();
+
+ ScValidationData aData( eMode, eOper, aExpr1, aExpr2, pDoc, aCursorPos );
+ aData.SetIgnoreBlank( bBlank );
+ aData.SetListType( nListType );
+
+ aData.SetInput(aHelpTitle, aHelpText); // sets bShowInput to TRUE
+ if (!bShowHelp)
+ aData.ResetInput(); // reset only bShowInput
+
+ aData.SetError(aErrTitle, aErrText, eErrStyle); // sets bShowError to TRUE
+ if (!bShowError)
+ aData.ResetError(); // reset only bShowError
+
+ pTabViewShell->SetValidation( aData );
+ rReq.Done( *pOutSet );
+ }
+ //<!-- Modified by PengYunQuan for Validity Cell Range Picker
+ //after end execute from !IsModalInputMode, it is safer to delay deleting
+ //delete pDlg;
+ Application::PostUserEvent( Link( pDlg, &DelayDeleteAbstractDialog ) );
+ //--> Modified by PengYunQuan for Validity Cell Range Picker
+ }
+ }
+ break;
+
+ case SID_TEXT_TO_COLUMNS:
+ {
+ ScViewData* pData = GetViewData();
+ DBG_ASSERT( pData, "ScCellShell::ExecuteDB: SID_TEXT_TO_COLUMNS - pData is null!" );
+ ScRange aRange;
+
+ if ( lcl_GetTextToColumnsRange( pData, aRange ) )
+ {
+ ScDocument* pDoc = pData->GetDocument();
+ DBG_ASSERT( pDoc, "ScCellShell::ExecuteDB: SID_TEXT_TO_COLUMNS - pDoc is null!" );
+
+ ScImportExport aExport( pDoc, aRange );
+ aExport.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::None, 0, false ) );
+
+ // #i87703# text to columns fails with tab separator
+ aExport.SetDelimiter( static_cast< sal_Unicode >( 0 ) );
+
+ SvMemoryStream aStream;
+ aStream.SetStreamCharSet( RTL_TEXTENCODING_UNICODE );
+ ScImportExport::SetNoEndianSwap( aStream );
+ aExport.ExportStream( aStream, String(), FORMAT_STRING );
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT( pFact, "ScCellShell::ExecuteDB: SID_TEXT_TO_COLUMNS - pFact is null!" );
+ AbstractScImportAsciiDlg *pDlg = pFact->CreateScImportAsciiDlg(
+ NULL, String(), &aStream, RID_SCDLG_ASCII );
+ DBG_ASSERT( pDlg, "ScCellShell::ExecuteDB: SID_TEXT_TO_COLUMNS - pDlg is null!" );
+ pDlg->SetTextToColumnsMode();
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ ScDocShell* pDocSh = pData->GetDocShell();
+ DBG_ASSERT( pDocSh, "ScCellShell::ExecuteDB: SID_TEXT_TO_COLUMNS - pDocSh is null!" );
+
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_TEXTTOCOLUMNS );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+
+ ScImportExport aImport( pDoc, aRange.aStart );
+ ScAsciiOptions aOptions;
+ pDlg->GetOptions( aOptions );
+ aImport.SetExtOptions( aOptions );
+ aImport.SetApi( false );
+ aStream.Seek( 0 );
+ aImport.ImportStream( aStream, String(), FORMAT_STRING );
+
+ pDocSh->GetUndoManager()->LeaveListAction();
+ }
+ delete pDlg;
+ }
+ }
+ break;
+ }
+}
+
+void __EXPORT ScCellShell::GetDBState( SfxItemSet& rSet )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ ScViewData* pData = GetViewData();
+ ScDocShell* pDocSh = pData->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCCOL nPosX = pData->GetCurX();
+ SCROW nPosY = pData->GetCurY();
+ SCTAB nTab = pData->GetTabNo();
+
+ sal_Bool bAutoFilter = sal_False;
+ sal_Bool bAutoFilterTested = sal_False;
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ switch (nWhich)
+ {
+ case SID_REFRESH_DBAREA:
+ {
+ // importierte Daten ohne Selektion
+ // oder Filter,Sortierung,Teilergebis (auch ohne Import)
+ sal_Bool bOk = sal_False;
+ ScDBData* pDBData = pTabViewShell->GetDBData(sal_False,SC_DB_OLD);
+ if (pDBData && pDoc->GetChangeTrack() == NULL)
+ {
+ if ( pDBData->HasImportParam() )
+ bOk = !pDBData->HasImportSelection();
+ else
+ {
+ bOk = pDBData->HasQueryParam() ||
+ pDBData->HasSortParam() ||
+ pDBData->HasSubTotalParam();
+ }
+ }
+ if (!bOk)
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_FILTER:
+ case SID_SPECIAL_FILTER:
+ {
+ ScRange aDummy;
+ ScMarkType eMarkType = GetViewData()->GetSimpleArea( aDummy);
+ if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+
+ //Bei Redlining und Multiselektion Disablen
+ case SID_SORT_ASCENDING:
+ case SID_SORT_DESCENDING:
+ case SCITEM_SORTDATA:
+ case SCITEM_SUBTDATA:
+ case SID_OPENDLG_PIVOTTABLE:
+ {
+ //! move ReadOnly check to idl flags
+
+ if ( pDocSh->IsReadOnly() || pDoc->GetChangeTrack()!=NULL ||
+ GetViewData()->IsMultiMarked() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case SID_REIMPORT_DATA:
+ {
+ // nur importierte Daten ohne Selektion
+ ScDBData* pDBData = pTabViewShell->GetDBData(sal_False,SC_DB_OLD);
+ if (!pDBData || !pDBData->HasImportParam() || pDBData->HasImportSelection() ||
+ pDoc->GetChangeTrack()!=NULL)
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case SID_VIEW_DATA_SOURCE_BROWSER:
+ {
+ if (!SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SDATABASE))
+ rSet.Put(SfxVisibilityItem(nWhich, sal_False));
+ else
+ // get state (BoolItem) from SfxViewFrame
+ pTabViewShell->GetViewFrame()->GetSlotState( nWhich, NULL, &rSet );
+ }
+ break;
+ case SID_SBA_BRW_INSERT:
+ {
+ // SBA will ein sal_Bool-Item, damit ueberhaupt enabled
+
+ sal_Bool bEnable = sal_True;
+ rSet.Put(SfxBoolItem(nWhich, bEnable));
+ }
+ break;
+
+ case SID_AUTO_FILTER:
+ case SID_AUTOFILTER_HIDE:
+ {
+ if (!bAutoFilterTested)
+ {
+ bAutoFilter = pDoc->HasAutoFilter( nPosX, nPosY, nTab );
+ bAutoFilterTested = sal_True;
+ }
+ if ( nWhich == SID_AUTO_FILTER )
+ {
+ ScRange aDummy;
+ ScMarkType eMarkType = GetViewData()->GetSimpleArea( aDummy);
+ if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
+ {
+ rSet.DisableItem( nWhich );
+ }
+ else if (pDoc->GetDPAtBlock(aDummy))
+ {
+ rSet.DisableItem( nWhich );
+ }
+ else
+ rSet.Put( SfxBoolItem( nWhich, bAutoFilter ) );
+ }
+ else
+ if (!bAutoFilter)
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_UNFILTER:
+ {
+ SCCOL nStartCol, nEndCol;
+ SCROW nStartRow, nEndRow;
+ SCTAB nStartTab, nEndTab;
+ sal_Bool bAnyQuery = sal_False;
+
+ sal_Bool bSelected = (GetViewData()->GetSimpleArea(
+ nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab )
+ == SC_MARK_SIMPLE);
+
+ if ( bSelected )
+ {
+ if (nStartCol==nEndCol && nStartRow==nEndRow)
+ bSelected = sal_False;
+ }
+ else
+ {
+ nStartCol = GetViewData()->GetCurX();
+ nStartRow = GetViewData()->GetCurY();
+ nStartTab = GetViewData()->GetTabNo();
+ }
+
+ ScDBData* pDBData = bSelected
+ ? pDoc->GetDBAtArea( nStartTab, nStartCol, nStartRow, nEndCol, nEndRow )
+ : pDoc->GetDBAtCursor( nStartCol, nStartRow, nStartTab );
+
+ if ( pDBData )
+ {
+ ScQueryParam aParam;
+ pDBData->GetQueryParam( aParam );
+ if ( aParam.GetEntry(0).bDoQuery )
+ bAnyQuery = sal_True;
+ }
+
+ if ( !bAnyQuery )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_DEFINE_DBNAME:
+ {
+ if ( pDocSh && pDocSh->IsDocShared() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case SID_TEXT_TO_COLUMNS:
+ {
+ ScRange aRange;
+ if ( !lcl_GetTextToColumnsRange( pData, aRange ) )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+
+
diff --git a/sc/source/ui/view/cellsh3.cxx b/sc/source/ui/view/cellsh3.cxx
new file mode 100644
index 000000000000..7001cd9faff4
--- /dev/null
+++ b/sc/source/ui/view/cellsh3.cxx
@@ -0,0 +1,966 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/request.hxx>
+#include <svl/stritem.hxx>
+#include <vcl/msgbox.hxx>
+#include <sfx2/app.hxx>
+#include "globstr.hrc"
+#include "scmod.hxx"
+#include "appoptio.hxx"
+#include "tabvwsh.hxx"
+#include "document.hxx"
+#include "sc.hrc"
+#include "docsh.hxx"
+#include "reffact.hxx"
+#include "uiitems.hxx"
+//CHINA001 #include "scendlg.hxx"
+//CHINA001 #include "mtrindlg.hxx"
+#include "autoform.hxx"
+#include "autofmt.hxx"
+#include "cellsh.hxx"
+#include "attrdlg.hrc" // TP_ALIGNMENT
+#include "inputhdl.hxx"
+#include "editable.hxx"
+
+#include "scabstdlg.hxx" //CHINA001
+
+#define IS_EDITMODE() GetViewData()->HasEditView( GetViewData()->GetActivePart() )
+
+inline long TwipsToHMM(long nTwips) { return (nTwips * 127 + 36) / 72; }
+inline long HMMToTwips(long nHMM) { return (nHMM * 72 + 63) / 127; }
+inline long TwipsToEvenHMM(long nTwips) { return ( (nTwips * 127 + 72) / 144 ) * 2; }
+
+//------------------------------------------------------------------
+
+void ScCellShell::Execute( SfxRequest& rReq )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ SfxBindings& rBindings = pTabViewShell->GetViewFrame()->GetBindings();
+ ScModule* pScMod = SC_MOD();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ sal_uInt16 nSlot = rReq.GetSlot();
+
+ if (nSlot != SID_CURRENTCELL) // der kommt beim MouseButtonUp
+ pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
+
+ if ( IS_EDITMODE() )
+ {
+ switch ( nSlot )
+ {
+ // beim Oeffnen eines Referenz-Dialogs darf die SubShell nicht umgeschaltet werden
+ // (beim Schliessen des Dialogs wird StopEditShell gerufen)
+ case SID_OPENDLG_FUNCTION:
+ // #53318# inplace macht die EditShell Aerger...
+ //! kann nicht immer umgeschaltet werden ????
+ if (!pTabViewShell->GetViewFrame()->GetFrame().IsInPlace())
+ pTabViewShell->SetDontSwitch(sal_True); // EditShell nicht abschalten
+ // kein break
+
+ case FID_CELL_FORMAT:
+ case SID_ENABLE_HYPHENATION:
+ case SID_DATA_SELECT:
+ case SID_OPENDLG_CONSOLIDATE:
+ case SID_OPENDLG_SOLVE:
+ case SID_OPENDLG_OPTSOLVER:
+
+ pScMod->InputEnterHandler();
+ pTabViewShell->UpdateInputHandler();
+
+ pTabViewShell->SetDontSwitch(sal_False);
+
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch ( nSlot )
+ {
+
+
+
+ case SID_ATTR_SIZE://XXX ???
+ break;
+
+ case SID_STATUS_SELMODE:
+ if ( pReqArgs )
+ {
+ /* 0: STD Click hebt Sel auf
+ * 1: ER Click erweitert Selektion
+ * 2: ERG Click definiert weitere Selektion
+ */
+ sal_uInt16 nMode = ((const SfxUInt16Item&)pReqArgs->Get( nSlot )).GetValue();
+
+ switch ( nMode )
+ {
+ case 1: nMode = KEY_SHIFT; break;
+ case 2: nMode = KEY_MOD1; break; // Control-Taste
+ case 0:
+ default:
+ nMode = 0;
+ }
+
+ pTabViewShell->LockModifiers( nMode );
+ }
+ else
+ {
+ // no arguments (also executed by double click on the status bar controller):
+ // advance to next selection mode
+
+ sal_uInt16 nModifiers = pTabViewShell->GetLockedModifiers();
+ switch ( nModifiers )
+ {
+ case KEY_SHIFT: nModifiers = KEY_MOD1; break; // EXT -> ADD
+ case KEY_MOD1: nModifiers = 0; break; // ADD -> STD
+ default: nModifiers = KEY_SHIFT; break; // STD -> EXT
+ }
+ pTabViewShell->LockModifiers( nModifiers );
+ }
+
+ rBindings.Invalidate( SID_STATUS_SELMODE );
+ rReq.Done();
+ break;
+
+ // SID_STATUS_SELMODE_NORM wird nicht benutzt ???
+
+ case SID_STATUS_SELMODE_NORM:
+ pTabViewShell->LockModifiers( 0 );
+ rBindings.Invalidate( SID_STATUS_SELMODE );
+ break;
+
+ // SID_STATUS_SELMODE_ERG / SID_STATUS_SELMODE_ERW als Toggles:
+
+ case SID_STATUS_SELMODE_ERG:
+ if ( pTabViewShell->GetLockedModifiers() & KEY_MOD1 )
+ pTabViewShell->LockModifiers( 0 );
+ else
+ pTabViewShell->LockModifiers( KEY_MOD1 );
+ rBindings.Invalidate( SID_STATUS_SELMODE );
+ break;
+
+ case SID_STATUS_SELMODE_ERW:
+ if ( pTabViewShell->GetLockedModifiers() & KEY_SHIFT )
+ pTabViewShell->LockModifiers( 0 );
+ else
+ pTabViewShell->LockModifiers( KEY_SHIFT );
+ rBindings.Invalidate( SID_STATUS_SELMODE );
+ break;
+
+ case SID_ENTER_STRING:
+ {
+ if ( pReqArgs )
+ {
+ String aStr( ((const SfxStringItem&)pReqArgs->
+ Get( SID_ENTER_STRING )).GetValue() );
+
+ pTabViewShell->EnterData( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(),
+ GetViewData()->GetTabNo(),
+ aStr );
+
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pTabViewShell );
+ if ( !pHdl || !pHdl->IsInEnterHandler() )
+ {
+ // #101061# UpdateInputHandler is needed after the cell content
+ // has changed, but if called from EnterHandler, UpdateInputHandler
+ // will be called later when moving the cursor.
+
+ pTabViewShell->UpdateInputHandler();
+ }
+
+ rReq.Done();
+
+ // hier kein GrabFocus, weil sonst auf dem Mac die Tabelle vor die
+ // Seitenansicht springt, wenn die Eingabe nicht abgeschlossen war
+ // (GrabFocus passiert in KillEditView)
+ }
+ }
+ break;
+
+ case SID_INSERT_MATRIX:
+ {
+ if ( pReqArgs )
+ {
+ String aStr = ((const SfxStringItem&)pReqArgs->
+ Get( SID_INSERT_MATRIX )).GetValue();
+ pTabViewShell->EnterMatrix( aStr );
+ rReq.Done();
+ }
+ }
+ break;
+
+ case FID_INPUTLINE_ENTER:
+ case FID_INPUTLINE_BLOCK:
+ case FID_INPUTLINE_MATRIX:
+ {
+ if( pReqArgs == 0 ) //XXX vorlaufiger HACK um GPF zu vermeiden
+ break;
+
+ const ScInputStatusItem* pStatusItem
+ = (const ScInputStatusItem*)&pReqArgs->
+ Get( FID_INPUTLINE_STATUS );
+
+ ScAddress aCursorPos = pStatusItem->GetPos();
+ String aString = pStatusItem->GetString();
+ const EditTextObject* pData = pStatusItem->GetEditData();
+ if (pData)
+ {
+ if (nSlot == FID_INPUTLINE_BLOCK)
+ {
+ pTabViewShell->EnterBlock( aString, pData );
+ }
+ else if ( aString.Len() > 0 && ( aString.GetChar(0) == '=' || aString.GetChar(0) == '+' || aString.GetChar(0) == '-' ) )
+ {
+ pTabViewShell->EnterData( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), aString, sal_True, pData );
+ }
+ else
+ {
+ pTabViewShell->EnterData( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), pData );
+ }
+ }
+ else
+ {
+ if (nSlot == FID_INPUTLINE_ENTER)
+ {
+ if (
+ aCursorPos.Col() == GetViewData()->GetCurX() &&
+ aCursorPos.Row() == GetViewData()->GetCurY() &&
+ aCursorPos.Tab() == GetViewData()->GetTabNo()
+ )
+ {
+ SfxStringItem aItem( SID_ENTER_STRING, aString );
+
+ // SfxBindings& rBindings = pTabViewShell->GetViewFrame()->GetBindings();
+ const SfxPoolItem* aArgs[2];
+ aArgs[0] = &aItem;
+ aArgs[1] = NULL;
+ rBindings.Execute( SID_ENTER_STRING, aArgs );
+ }
+ else
+ {
+ pTabViewShell->EnterData( aCursorPos.Col(),
+ aCursorPos.Row(),
+ aCursorPos.Tab(),
+ aString );
+ rReq.Done();
+ }
+ }
+ else if (nSlot == FID_INPUTLINE_BLOCK)
+ {
+ pTabViewShell->EnterBlock( aString, NULL );
+ rReq.Done();
+ }
+ else
+ {
+ pTabViewShell->EnterMatrix( aString );
+ rReq.Done();
+ }
+
+ }
+
+ // hier kein GrabFocus, weil sonst auf dem Mac die Tabelle vor die
+ // Seitenansicht springt, wenn die Eingabe nicht abgeschlossen war
+ // (GrabFocus passiert in KillEditView)
+ }
+ break;
+
+ case SID_OPENDLG_FUNCTION:
+ {
+ sal_uInt16 nId = SID_OPENDLG_FUNCTION;
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? sal_False : sal_True );
+ rReq.Ignore();
+ }
+ break;
+
+ case SID_OPENDLG_CONSOLIDATE:
+ {
+ sal_uInt16 nId = ScConsolidateDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? sal_False : sal_True );
+ }
+ break;
+
+ case FID_CELL_FORMAT:
+ {
+ if ( pReqArgs != NULL )
+ {
+ //----------------------------------
+ // Zellattribute ohne Dialog setzen:
+ //----------------------------------
+ SfxItemSet* pEmptySet =
+ new SfxItemSet( *pReqArgs->GetPool(),
+ ATTR_PATTERN_START,
+ ATTR_PATTERN_END );
+
+ SfxItemSet* pNewSet =
+ new SfxItemSet( *pReqArgs->GetPool(),
+ ATTR_PATTERN_START,
+ ATTR_PATTERN_END );
+
+ const SfxPoolItem* pAttr = NULL;
+ sal_uInt16 nWhich = 0;
+
+ for ( nWhich=ATTR_PATTERN_START; nWhich<=ATTR_PATTERN_END; nWhich++ )
+ if ( pReqArgs->GetItemState( nWhich, sal_True, &pAttr ) == SFX_ITEM_SET )
+ pNewSet->Put( *pAttr );
+
+ pTabViewShell->ApplyAttributes( pNewSet, pEmptySet );
+
+ delete pNewSet;
+ delete pEmptySet;
+
+ rReq.Done();
+ }
+ else if ( pReqArgs == NULL )
+ {
+ pTabViewShell->ExecuteCellFormatDlg( rReq );
+ }
+ }
+ break;
+
+ case SID_ENABLE_HYPHENATION:
+ pTabViewShell->ExecuteCellFormatDlg( rReq, TP_ALIGNMENT );
+ break;
+
+ case SID_OPENDLG_SOLVE:
+ {
+ sal_uInt16 nId = ScSolverDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? sal_False : sal_True );
+ }
+ break;
+
+ case SID_OPENDLG_OPTSOLVER:
+ {
+ sal_uInt16 nId = ScOptSolverDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? sal_False : sal_True );
+ }
+ break;
+
+ case SID_OPENDLG_TABOP:
+ {
+ sal_uInt16 nId = ScTabOpDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? sal_False : sal_True );
+ }
+ break;
+
+ case SID_SCENARIOS:
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ if ( pDoc->IsScenario(nTab) )
+ {
+ rMark.MarkToMulti();
+ if ( rMark.IsMultiMarked() )
+ {
+ if ( rReq.IsAPI()
+ || RET_YES ==
+ QueryBox( pTabViewShell->GetDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
+ ScGlobal::GetRscString(STR_UPDATE_SCENARIO) ).
+ Execute() )
+ {
+ pTabViewShell->ExtendScenario();
+ rReq.Done();
+ }
+ }
+ else if( ! rReq.IsAPI() )
+ {
+ ErrorBox aErrorBox( pTabViewShell->GetDialogParent(), WinBits(WB_OK | WB_DEF_OK),
+ ScGlobal::GetRscString(STR_NOAREASELECTED) );
+ aErrorBox.Execute();
+ }
+ }
+ else
+ {
+ rMark.MarkToMulti();
+ if ( rMark.IsMultiMarked() )
+ {
+ SCTAB i=1;
+ String aBaseName;
+ String aName;
+ String aComment;
+ Color aColor;
+ sal_uInt16 nFlags;
+
+ pDoc->GetName( nTab, aBaseName );
+ aBaseName += '_';
+ aBaseName += ScGlobal::GetRscString(STR_SCENARIO);
+ aBaseName += '_';
+
+ // vorneweg testen, ob der Prefix als gueltig erkannt wird
+ // wenn nicht, nur doppelte vermeiden
+ sal_Bool bPrefix = pDoc->ValidTabName( aBaseName );
+ DBG_ASSERT(bPrefix, "ungueltiger Tabellenname");
+
+ while ( pDoc->IsScenario(nTab+i) )
+ i++;
+
+ sal_Bool bValid;
+ SCTAB nDummy;
+ do
+ {
+ aName = aBaseName;
+ aName += String::CreateFromInt32( i );
+ if (bPrefix)
+ bValid = pDoc->ValidNewTabName( aName );
+ else
+ bValid = !pDoc->GetTable( aName, nDummy );
+ ++i;
+ }
+ while ( !bValid && i <= 2*MAXTAB );
+
+ if ( pReqArgs != NULL )
+ {
+ String aArgName;
+ String aArgComment;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( SID_SCENARIOS, sal_True, &pItem ) == SFX_ITEM_SET )
+ aArgName = ((const SfxStringItem*)pItem)->GetValue();
+ if ( pReqArgs->GetItemState( SID_NEW_TABLENAME, sal_True, &pItem ) == SFX_ITEM_SET )
+ aArgComment = ((const SfxStringItem*)pItem)->GetValue();
+
+ aColor = Color( COL_LIGHTGRAY ); // Default
+ nFlags = 0; // nicht-TwoWay
+
+ pTabViewShell->MakeScenario( aArgName, aArgComment, aColor, nFlags );
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ else
+ {
+ sal_Bool bSheetProtected = pDoc->IsTabProtected(nTab);
+ //CHINA001 ScNewScenarioDlg* pNewDlg =
+ //CHINA001 new ScNewScenarioDlg( pTabViewShell->GetDialogParent(), aName, sal_False, bSheetProtected );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScNewScenarioDlg* pNewDlg = pFact->CreateScNewScenarioDlg( pTabViewShell->GetDialogParent(), aName, RID_SCDLG_NEWSCENARIO, sal_False,bSheetProtected);
+ DBG_ASSERT(pNewDlg, "Dialog create fail!");//CHINA001
+ if ( pNewDlg->Execute() == RET_OK )
+ {
+ pNewDlg->GetScenarioData( aName, aComment, aColor, nFlags );
+ pTabViewShell->MakeScenario( aName, aComment, aColor, nFlags );
+
+ rReq.AppendItem( SfxStringItem( SID_SCENARIOS, aName ) );
+ rReq.AppendItem( SfxStringItem( SID_NEW_TABLENAME, aComment ) );
+ rReq.Done();
+ }
+ delete pNewDlg;
+ }
+ }
+ else if( ! rReq.IsAPI() )
+ {
+ pTabViewShell->ErrorMessage(STR_ERR_NEWSCENARIO);
+ }
+ }
+ }
+ break;
+
+
+ case SID_SELECTALL:
+ {
+ pTabViewShell->SelectAll();
+ rReq.Done();
+ }
+ break;
+
+ //----------------------------------------------------------------
+
+ case FID_ROW_HEIGHT:
+ {
+ if ( pReqArgs )
+ {
+ const SfxUInt16Item& rUInt16Item = (const SfxUInt16Item&)pReqArgs->Get( FID_ROW_HEIGHT );
+
+ // #101390#; the value of the macro is in HMM so use HMMToTwips to convert
+ pTabViewShell->SetMarkedWidthOrHeight( sal_False, SC_SIZE_DIRECT,
+ sal::static_int_cast<sal_uInt16>( HMMToTwips(rUInt16Item.GetValue()) ) );
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ else
+ {
+ ScViewData* pData = GetViewData();
+ FieldUnit eMetric = SC_MOD()->GetAppOptions().GetAppMetric();
+ sal_uInt16 nCurHeight = pData->GetDocument()->
+ GetRowHeight( pData->GetCurY(),
+ pData->GetTabNo() );
+//CHINA001 ScMetricInputDlg* pDlg =
+//CHINA001 new ScMetricInputDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_ROW_MAN,
+//CHINA001 nCurHeight,
+//CHINA001 ScGlobal::nStdRowHeight,
+//CHINA001 eMetric,
+//CHINA001 2,
+//CHINA001 MAX_COL_HEIGHT );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScMetricInputDlg* pDlg = pFact->CreateScMetricInputDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_ROW_MAN,
+ nCurHeight,
+ ScGlobal::nStdRowHeight,
+ RID_SCDLG_ROW_MAN,
+ eMetric,
+ 2,
+ MAX_COL_HEIGHT);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ long nVal = pDlg->GetInputValue();
+ pTabViewShell->SetMarkedWidthOrHeight( sal_False, SC_SIZE_DIRECT, (sal_uInt16)nVal );
+
+ // #101390#; the value of the macro should be in HMM so use TwipsToEvenHMM to convert
+ rReq.AppendItem( SfxUInt16Item( FID_ROW_HEIGHT, (sal_uInt16)TwipsToEvenHMM(nVal) ) );
+ rReq.Done();
+
+ }
+ delete pDlg;
+ }
+ }
+ break;
+
+ case FID_ROW_OPT_HEIGHT:
+ {
+ if ( pReqArgs )
+ {
+ const SfxUInt16Item& rUInt16Item = (const SfxUInt16Item&)pReqArgs->Get( FID_ROW_OPT_HEIGHT );
+
+ // #101390#; the value of the macro is in HMM so use HMMToTwips to convert
+ pTabViewShell->SetMarkedWidthOrHeight( sal_False, SC_SIZE_OPTIMAL,
+ sal::static_int_cast<sal_uInt16>( HMMToTwips(rUInt16Item.GetValue()) ) );
+ ScGlobal::nLastRowHeightExtra = rUInt16Item.GetValue();
+
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ else
+ {
+ FieldUnit eMetric = SC_MOD()->GetAppOptions().GetAppMetric();
+
+//CHINA001 ScMetricInputDlg* pDlg =
+//CHINA001 new ScMetricInputDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_ROW_OPT,
+//CHINA001 ScGlobal::nLastRowHeightExtra,
+//CHINA001 0,
+//CHINA001 eMetric,
+//CHINA001 1,
+//CHINA001 MAX_EXTRA_HEIGHT );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScMetricInputDlg* pDlg = pFact->CreateScMetricInputDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_ROW_OPT,
+ ScGlobal::nLastRowHeightExtra,
+ 0,
+ RID_SCDLG_ROW_OPT,
+ eMetric,
+ 1,
+ MAX_EXTRA_HEIGHT);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ long nVal = pDlg->GetInputValue();
+ pTabViewShell->SetMarkedWidthOrHeight( sal_False, SC_SIZE_OPTIMAL, (sal_uInt16)nVal );
+ ScGlobal::nLastRowHeightExtra = nVal;
+
+ // #101390#; the value of the macro should be in HMM so use TwipsToEvenHMM to convert
+ rReq.AppendItem( SfxUInt16Item( FID_ROW_OPT_HEIGHT, (sal_uInt16)TwipsToEvenHMM(nVal) ) );
+ rReq.Done();
+
+ }
+ delete pDlg;
+ }
+ }
+ break;
+
+ case FID_COL_WIDTH:
+ {
+ if ( pReqArgs )
+ {
+ const SfxUInt16Item& rUInt16Item = (const SfxUInt16Item&)pReqArgs->Get( FID_COL_WIDTH );
+
+ // #101390#; the value of the macro is in HMM so use HMMToTwips to convert
+ pTabViewShell->SetMarkedWidthOrHeight( sal_True, SC_SIZE_DIRECT,
+ sal::static_int_cast<sal_uInt16>( HMMToTwips(rUInt16Item.GetValue()) ) );
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ else
+ {
+ FieldUnit eMetric = SC_MOD()->GetAppOptions().GetAppMetric();
+ ScViewData* pData = GetViewData();
+ sal_uInt16 nCurHeight = pData->GetDocument()->
+ GetColWidth( pData->GetCurX(),
+ pData->GetTabNo() );
+//CHINA001 ScMetricInputDlg* pDlg =
+//CHINA001 new ScMetricInputDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_COL_MAN,
+//CHINA001 nCurHeight,
+//CHINA001 STD_COL_WIDTH,
+//CHINA001 eMetric,
+//CHINA001 2,
+//CHINA001 MAX_COL_WIDTH );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScMetricInputDlg* pDlg = pFact->CreateScMetricInputDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_COL_MAN,
+ nCurHeight,
+ STD_COL_WIDTH,
+ RID_SCDLG_COL_MAN,
+ eMetric,
+ 2,
+ MAX_COL_WIDTH);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ long nVal = pDlg->GetInputValue();
+ pTabViewShell->SetMarkedWidthOrHeight( sal_True, SC_SIZE_DIRECT, (sal_uInt16)nVal );
+
+ // #101390#; the value of the macro should be in HMM so use TwipsToEvenHMM to convert
+ rReq.AppendItem( SfxUInt16Item( FID_COL_WIDTH, (sal_uInt16)TwipsToEvenHMM(nVal)) );
+ rReq.Done();
+
+ }
+ delete pDlg;
+ }
+ }
+ break;
+
+ case FID_COL_OPT_WIDTH:
+ {
+ if ( pReqArgs )
+ {
+ const SfxUInt16Item& rUInt16Item = (const SfxUInt16Item&)pReqArgs->Get( FID_COL_OPT_WIDTH );
+
+ // #101390#; the value of the macro is in HMM so use HMMToTwips to convert
+ pTabViewShell->SetMarkedWidthOrHeight( sal_True, SC_SIZE_OPTIMAL,
+ sal::static_int_cast<sal_uInt16>( HMMToTwips(rUInt16Item.GetValue()) ) );
+ ScGlobal::nLastColWidthExtra = rUInt16Item.GetValue();
+
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ else
+ {
+ FieldUnit eMetric = SC_MOD()->GetAppOptions().GetAppMetric();
+
+//CHINA001 ScMetricInputDlg* pDlg =
+//CHINA001 new ScMetricInputDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_COL_OPT,
+//CHINA001 ScGlobal::nLastColWidthExtra,
+//CHINA001 STD_EXTRA_WIDTH,
+//CHINA001 eMetric,
+//CHINA001 1,
+//CHINA001 MAX_EXTRA_WIDTH );
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScMetricInputDlg* pDlg = pFact->CreateScMetricInputDlg( pTabViewShell->GetDialogParent(), RID_SCDLG_COL_OPT,
+ ScGlobal::nLastColWidthExtra,
+ STD_EXTRA_WIDTH,
+ RID_SCDLG_COL_OPT,
+ eMetric,
+ 1,
+ MAX_EXTRA_WIDTH);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( pDlg->Execute() == RET_OK )
+ {
+ long nVal = pDlg->GetInputValue();
+ pTabViewShell->SetMarkedWidthOrHeight( sal_True, SC_SIZE_OPTIMAL, (sal_uInt16)nVal );
+ ScGlobal::nLastColWidthExtra = nVal;
+
+ // #101390#; the value of the macro should be in HMM so use TwipsToEvenHMM to convert
+ rReq.AppendItem( SfxUInt16Item( FID_COL_OPT_WIDTH, (sal_uInt16)TwipsToEvenHMM(nVal) ) );
+ rReq.Done();
+ }
+ delete pDlg;
+ }
+ }
+ break;
+
+ case FID_COL_OPT_DIRECT:
+ pTabViewShell->SetMarkedWidthOrHeight( sal_True, SC_SIZE_OPTIMAL, STD_EXTRA_WIDTH );
+ rReq.Done();
+ break;
+
+ case FID_ROW_HIDE:
+ pTabViewShell->SetMarkedWidthOrHeight( sal_False, SC_SIZE_DIRECT, 0 );
+ rReq.Done();
+ break;
+ case FID_ROW_SHOW:
+ pTabViewShell->SetMarkedWidthOrHeight( sal_False, SC_SIZE_SHOW, 0 );
+ rReq.Done();
+ break;
+ case FID_COL_HIDE:
+ pTabViewShell->SetMarkedWidthOrHeight( sal_True, SC_SIZE_DIRECT, 0 );
+ rReq.Done();
+ break;
+ case FID_COL_SHOW:
+ pTabViewShell->SetMarkedWidthOrHeight( sal_True, SC_SIZE_SHOW, 0 );
+ rReq.Done();
+ break;
+
+ //----------------------------------------------------------------
+
+
+ case SID_CELL_FORMAT_RESET:
+ {
+ pTabViewShell->DeleteContents( IDF_HARDATTR | IDF_EDITATTR );
+ rReq.Done();
+ }
+ break;
+
+ case FID_MERGE_ON:
+ case FID_MERGE_OFF:
+ case FID_MERGE_TOGGLE:
+ {
+ if ( !GetViewData()->GetDocument()->GetChangeTrack() )
+ {
+ // test whether to merge or to split
+ bool bMerge = false;
+ switch( nSlot )
+ {
+ case FID_MERGE_ON:
+ bMerge = true;
+ break;
+ case FID_MERGE_OFF:
+ bMerge = false;
+ break;
+ case FID_MERGE_TOGGLE:
+ {
+ SfxPoolItem* pItem = 0;
+ if( rBindings.QueryState( nSlot, pItem ) >= SFX_ITEM_DEFAULT )
+ bMerge = !static_cast< SfxBoolItem* >( pItem )->GetValue();
+ }
+ break;
+ }
+
+ if( bMerge )
+ {
+ // merge - check if to move contents of covered cells
+ sal_Bool bMoveContents = sal_False;
+ sal_Bool bApi = rReq.IsAPI();
+ const SfxPoolItem* pItem;
+ if ( pReqArgs &&
+ pReqArgs->GetItemState(nSlot, sal_True, &pItem) == SFX_ITEM_SET )
+ {
+ DBG_ASSERT(pItem && pItem->ISA(SfxBoolItem), "falsches Item");
+ bMoveContents = ((const SfxBoolItem*)pItem)->GetValue();
+ }
+
+ if (pTabViewShell->MergeCells( bApi, bMoveContents ))
+ {
+ if (!bApi && bMoveContents) // "ja" im Dialog geklickt
+ rReq.AppendItem( SfxBoolItem( nSlot, bMoveContents ) );
+ rBindings.Invalidate( nSlot );
+ rReq.Done();
+ }
+ }
+ else
+ {
+ // split cells
+ if (pTabViewShell->RemoveMerge())
+ {
+ rBindings.Invalidate( nSlot );
+ rReq.Done();
+ }
+ }
+ break;
+ }
+ }
+ break;
+
+ case SID_AUTOFORMAT:
+ {
+ Window* pDlgParent = pTabViewShell->GetDialogParent();
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
+ pTabViewShell->MarkDataArea( sal_True );
+
+ GetViewData()->GetSimpleArea( nStartCol,nStartRow,nStartTab,
+ nEndCol,nEndRow,nEndTab );
+
+ if ( ( Abs((SCsCOL)nEndCol-(SCsCOL)nStartCol) > 1 )
+ && ( Abs((SCsROW)nEndRow-(SCsROW)nStartRow) > 1 ) )
+ {
+ if ( pReqArgs )
+ {
+ const SfxStringItem& rNameItem = (const SfxStringItem&)pReqArgs->Get( SID_AUTOFORMAT );
+ ScAutoFormat* pFormat = ScGlobal::GetAutoFormat();
+ sal_uInt16 nIndex = pFormat->FindIndexPerName( rNameItem.GetValue() );
+
+ pTabViewShell->AutoFormat( nIndex );
+
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ else
+ {
+ ScGlobal::ClearAutoFormat();
+ ScAutoFormatData* pNewEntry = pTabViewShell->CreateAutoFormatData();
+//CHINA001 ScAutoFormatDlg* pDlg = new ScAutoFormatDlg(
+//CHINA001 pDlgParent,
+//CHINA001 ScGlobal::GetAutoFormat(),
+//CHINA001 pNewEntry,
+//CHINA001 GetViewData()->GetDocument() );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScAutoFormatDlg* pDlg = pFact->CreateScAutoFormatDlg( pDlgParent, ScGlobal::GetAutoFormat(), pNewEntry,GetViewData()->GetDocument(), RID_SCDLG_AUTOFORMAT );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ ScEditableTester aTester( pTabViewShell );
+ if ( !aTester.IsEditable() )
+ {
+ pTabViewShell->ErrorMessage(aTester.GetMessageId());
+ }
+ else
+ {
+ pTabViewShell->AutoFormat( pDlg->GetIndex() );
+
+ rReq.AppendItem( SfxStringItem( SID_AUTOFORMAT, pDlg->GetCurrFormatName() ) );
+ rReq.Done();
+ }
+ }
+ delete pDlg;
+ delete pNewEntry;
+ }
+ }
+ else
+ ErrorBox( pDlgParent, WinBits( WB_OK | WB_DEF_OK ),
+ ScGlobal::GetRscString(STR_INVALID_AFAREA) ).Execute();
+ }
+ break;
+
+ case SID_CANCEL:
+ {
+ if (GetViewData()->HasEditView(GetViewData()->GetActivePart()))
+ pScMod->InputCancelHandler();
+ else if (pTabViewShell->HasPaintBrush())
+ pTabViewShell->ResetBrushDocument(); // abort format paint brush
+ else if (pTabViewShell->HasHintWindow())
+ pTabViewShell->RemoveHintWindow(); // Eingabemeldung abschalten
+ else if( ScViewUtil::IsFullScreen( *pTabViewShell ) )
+ ScViewUtil::SetFullScreen( *pTabViewShell, false );
+ else
+ {
+ // TODO/LATER: when is this code executed?
+ pTabViewShell->Escape();
+ //SfxObjectShell* pObjSh = GetViewData()->GetSfxDocShell();
+ //if (pObjSh->GetInPlaceObject() &&
+ // pObjSh->GetInPlaceObject()->GetIPClient())
+ //{
+ // GetViewData()->GetDocShell()->
+ // DoInPlaceActivate(sal_False); // OLE beenden
+ //}
+ }
+
+// SetSumAssignMode(); //ScInputWindow
+ }
+ break;
+
+ case SID_DATA_SELECT:
+ pTabViewShell->StartDataSelect();
+ break;
+
+ case SID_DETECTIVE_FILLMODE:
+ {
+ sal_Bool bOldMode = pTabViewShell->IsAuditShell();
+ pTabViewShell->SetAuditShell( !bOldMode );
+ pTabViewShell->Invalidate( nSlot );
+ }
+ break;
+
+ case SID_OPENDLG_CONDFRMT:
+ {
+ sal_uInt16 nId = ScCondFormatDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
+ SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? sal_False : sal_True );
+ }
+ break;
+
+ // ----------------------------------------------------------------
+
+ case FID_INPUTLINE_STATUS:
+ DBG_ERROR("Execute von InputLine-Status");
+ break;
+
+ case SID_STATUS_DOCPOS:
+ // Launch navigator.
+ GetViewData()->GetDispatcher().Execute(
+ SID_NAVIGATOR, SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD );
+ break;
+
+ case SID_MARKAREA:
+ // called from Basic at the hidden view to select a range in the visible view
+ DBG_ERROR("old slot SID_MARKAREA");
+ break;
+
+ default:
+ DBG_ERROR("Unbekannter Slot bei ScCellShell::Execute");
+ break;
+ }
+}
+
diff --git a/sc/source/ui/view/cellsh4.cxx b/sc/source/ui/view/cellsh4.cxx
new file mode 100644
index 000000000000..545aba28ff47
--- /dev/null
+++ b/sc/source/ui/view/cellsh4.cxx
@@ -0,0 +1,382 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#ifdef _MSC_VER
+#pragma optimize ("", off)
+#endif
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <sfx2/request.hxx>
+
+#include "cellsh.hxx"
+#include "tabvwsh.hxx"
+#include "global.hxx"
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+#include "inputwin.hxx"
+#include "document.hxx"
+#include "sc.hrc"
+
+
+//------------------------------------------------------------------
+
+#define IS_AVAILABLE(WhichId,ppItem) \
+ (pReqArgs->GetItemState((WhichId), sal_True, ppItem ) == SFX_ITEM_SET)
+
+
+void ScCellShell::ExecuteCursor( SfxRequest& rReq )
+{
+ ScViewData* pData = GetViewData();
+ ScTabViewShell* pTabViewShell = pData->GetViewShell();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ sal_uInt16 nSlotId = rReq.GetSlot();
+ SCsCOLROW nRepeat = 1;
+ sal_Bool bSel = sal_False;
+ sal_Bool bKeep = sal_False;
+
+ if ( pReqArgs != NULL )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FN_PARAM_1, &pItem ) )
+ nRepeat = static_cast<SCsCOLROW>(((const SfxInt16Item*)pItem)->GetValue());
+ if( IS_AVAILABLE( FN_PARAM_2, &pItem ) )
+ bSel = ((const SfxBoolItem*)pItem)->GetValue();
+ }
+ else
+ {
+ // evaluate locked selection mode
+
+ sal_uInt16 nLocked = pTabViewShell->GetLockedModifiers();
+ if ( nLocked & KEY_SHIFT )
+ bSel = sal_True; // EXT
+ else if ( nLocked & KEY_MOD1 )
+ {
+ // ADD mode: keep the selection, start a new block when marking with shift again
+ bKeep = sal_True;
+ pTabViewShell->SetNewStartIfMarking();
+ }
+ }
+
+ SCsCOLROW nRTLSign = 1;
+ if ( pData->GetDocument()->IsLayoutRTL( pData->GetTabNo() ) )
+ {
+ //! evaluate cursor movement option?
+ nRTLSign = -1;
+ }
+
+ // einmal extra, damit der Cursor bei ExecuteInputDirect nicht zuoft gemalt wird:
+ pTabViewShell->HideAllCursors();
+
+ //OS: einmal fuer alle wird doch reichen!
+ pTabViewShell->ExecuteInputDirect();
+ switch ( nSlotId )
+ {
+ case SID_CURSORDOWN:
+ pTabViewShell->MoveCursorRel( 0, nRepeat, SC_FOLLOW_LINE, bSel, bKeep );
+ break;
+
+ case SID_CURSORBLKDOWN:
+ pTabViewShell->MoveCursorArea( 0, nRepeat, SC_FOLLOW_JUMP, bSel, bKeep );
+ break;
+
+ case SID_CURSORUP:
+ pTabViewShell->MoveCursorRel( 0, -nRepeat, SC_FOLLOW_LINE, bSel, bKeep );
+ break;
+
+ case SID_CURSORBLKUP:
+ pTabViewShell->MoveCursorArea( 0, -nRepeat, SC_FOLLOW_JUMP, bSel, bKeep );
+ break;
+
+ case SID_CURSORLEFT:
+ pTabViewShell->MoveCursorRel( static_cast<SCsCOL>(-nRepeat * nRTLSign), 0, SC_FOLLOW_LINE, bSel, bKeep );
+ break;
+
+ case SID_CURSORBLKLEFT:
+ pTabViewShell->MoveCursorArea( static_cast<SCsCOL>(-nRepeat * nRTLSign), 0, SC_FOLLOW_JUMP, bSel, bKeep );
+ break;
+
+ case SID_CURSORRIGHT:
+ pTabViewShell->MoveCursorRel( static_cast<SCsCOL>(nRepeat * nRTLSign), 0, SC_FOLLOW_LINE, bSel, bKeep );
+ break;
+
+ case SID_CURSORBLKRIGHT:
+ pTabViewShell->MoveCursorArea( static_cast<SCsCOL>(nRepeat * nRTLSign), 0, SC_FOLLOW_JUMP, bSel, bKeep );
+ break;
+
+ case SID_CURSORPAGEDOWN:
+ pTabViewShell->MoveCursorPage( 0, nRepeat, SC_FOLLOW_FIX, bSel, bKeep );
+ break;
+
+ case SID_CURSORPAGEUP:
+ pTabViewShell->MoveCursorPage( 0, -nRepeat, SC_FOLLOW_FIX, bSel, bKeep );
+ break;
+
+ case SID_CURSORPAGERIGHT_: //XXX !!!
+ pTabViewShell->MoveCursorPage( static_cast<SCsCOL>(nRepeat), 0, SC_FOLLOW_FIX, bSel, bKeep );
+ break;
+
+ case SID_CURSORPAGELEFT_: //XXX !!!
+ pTabViewShell->MoveCursorPage( static_cast<SCsCOL>(-nRepeat), 0, SC_FOLLOW_FIX, bSel, bKeep );
+ break;
+
+ default:
+ DBG_ERROR("Unbekannte Message bei ViewShell (Cursor)");
+ return;
+ }
+
+ pTabViewShell->ShowAllCursors();
+
+ rReq.AppendItem( SfxInt16Item(FN_PARAM_1, static_cast<sal_Int16>(nRepeat)) );
+ rReq.AppendItem( SfxBoolItem(FN_PARAM_2, bSel) );
+ rReq.Done();
+}
+
+void ScCellShell::GetStateCursor( SfxItemSet& /* rSet */ )
+{
+}
+
+void ScCellShell::ExecuteCursorSel( SfxRequest& rReq )
+{
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ sal_uInt16 nSlotId = rReq.GetSlot();
+ short nRepeat = 1;
+
+ if ( pReqArgs != NULL )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FN_PARAM_1, &pItem ) )
+ nRepeat = ((const SfxInt16Item*)pItem)->GetValue();
+ }
+
+ switch ( nSlotId )
+ {
+ case SID_CURSORDOWN_SEL: rReq.SetSlot( SID_CURSORDOWN ); break;
+ case SID_CURSORBLKDOWN_SEL: rReq.SetSlot( SID_CURSORBLKDOWN ); break;
+ case SID_CURSORUP_SEL: rReq.SetSlot( SID_CURSORUP ); break;
+ case SID_CURSORBLKUP_SEL: rReq.SetSlot( SID_CURSORBLKUP ); break;
+ case SID_CURSORLEFT_SEL: rReq.SetSlot( SID_CURSORLEFT ); break;
+ case SID_CURSORBLKLEFT_SEL: rReq.SetSlot( SID_CURSORBLKLEFT ); break;
+ case SID_CURSORRIGHT_SEL: rReq.SetSlot( SID_CURSORRIGHT ); break;
+ case SID_CURSORBLKRIGHT_SEL: rReq.SetSlot( SID_CURSORBLKRIGHT ); break;
+ case SID_CURSORPAGEDOWN_SEL: rReq.SetSlot( SID_CURSORPAGEDOWN ); break;
+ case SID_CURSORPAGEUP_SEL: rReq.SetSlot( SID_CURSORPAGEUP ); break;
+ case SID_CURSORPAGERIGHT_SEL: rReq.SetSlot( SID_CURSORPAGERIGHT_ ); break;
+ case SID_CURSORPAGELEFT_SEL: rReq.SetSlot( SID_CURSORPAGELEFT_ ); break;
+ default:
+ DBG_ERROR("Unbekannte Message bei ViewShell (CursorSel)");
+ return;
+ }
+ rReq.AppendItem( SfxInt16Item(FN_PARAM_1, nRepeat ) );
+ rReq.AppendItem( SfxBoolItem(FN_PARAM_2, sal_True) );
+ ExecuteSlot( rReq, GetInterface() );
+}
+
+void ScCellShell::ExecuteMove( SfxRequest& rReq )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ sal_uInt16 nSlotId = rReq.GetSlot();
+
+ if(nSlotId != SID_CURSORTOPOFSCREEN && nSlotId != SID_CURSORENDOFSCREEN)
+ pTabViewShell->ExecuteInputDirect();
+ switch ( nSlotId )
+ {
+ case SID_NEXT_TABLE:
+ case SID_NEXT_TABLE_SEL:
+ pTabViewShell->SelectNextTab( 1, (nSlotId == SID_NEXT_TABLE_SEL) );
+ break;
+
+ case SID_PREV_TABLE:
+ case SID_PREV_TABLE_SEL:
+ pTabViewShell->SelectNextTab( -1, (nSlotId == SID_PREV_TABLE_SEL) );
+ break;
+
+ // Cursorbewegungen in Bloecken gehen nicht von Basic aus,
+ // weil das ScSbxRange-Objekt bei Eingaben die Markierung veraendert
+
+ case SID_NEXT_UNPROTECT:
+ pTabViewShell->FindNextUnprot( sal_False, !rReq.IsAPI() );
+ break;
+
+ case SID_PREV_UNPROTECT:
+ pTabViewShell->FindNextUnprot( sal_True, !rReq.IsAPI() );
+ break;
+
+ case SID_CURSORENTERUP:
+ if (rReq.IsAPI())
+ pTabViewShell->MoveCursorRel( 0, -1, SC_FOLLOW_LINE, sal_False );
+ else
+ pTabViewShell->MoveCursorEnter( sal_True );
+ break;
+
+ case SID_CURSORENTERDOWN:
+ if (rReq.IsAPI())
+ pTabViewShell->MoveCursorRel( 0, 1, SC_FOLLOW_LINE, sal_False );
+ else
+ pTabViewShell->MoveCursorEnter( sal_False );
+ break;
+
+ case SID_SELECT_COL:
+ pTabViewShell->MarkColumns();
+ break;
+
+ case SID_SELECT_ROW:
+ pTabViewShell->MarkRows();
+ break;
+
+ case SID_SELECT_NONE:
+ pTabViewShell->Unmark();
+ break;
+
+ case SID_ALIGNCURSOR:
+ pTabViewShell->AlignToCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(), SC_FOLLOW_JUMP );
+ break;
+
+ case SID_MARKDATAAREA:
+ pTabViewShell->MarkDataArea();
+ break;
+
+ case SID_MARKARRAYFORMULA:
+ pTabViewShell->MarkMatrixFormula();
+ break;
+
+ case SID_SETINPUTMODE:
+ SC_MOD()->SetInputMode( SC_INPUT_TABLE );
+ break;
+
+ case SID_FOCUS_INPUTLINE:
+ {
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pTabViewShell );
+ if (pHdl)
+ {
+ ScInputWindow* pWin = pHdl->GetInputWindow();
+ if (pWin)
+ pWin->SwitchToTextWin();
+ }
+ }
+ break;
+
+ case SID_CURSORTOPOFSCREEN:
+ pTabViewShell->MoveCursorScreen( 0, -1, SC_FOLLOW_LINE, sal_False );
+ break;
+
+ case SID_CURSORENDOFSCREEN:
+ pTabViewShell->MoveCursorScreen( 0, 1, SC_FOLLOW_LINE, sal_False );
+ break;
+
+ default:
+ DBG_ERROR("Unbekannte Message bei ViewShell (Cursor)");
+ return;
+ }
+
+ rReq.Done();
+}
+
+void ScCellShell::ExecutePageSel( SfxRequest& rReq )
+{
+ sal_uInt16 nSlotId = rReq.GetSlot();
+ switch ( nSlotId )
+ {
+ case SID_CURSORHOME_SEL: rReq.SetSlot( SID_CURSORHOME ); break;
+ case SID_CURSOREND_SEL: rReq.SetSlot( SID_CURSOREND ); break;
+ case SID_CURSORTOPOFFILE_SEL: rReq.SetSlot( SID_CURSORTOPOFFILE ); break;
+ case SID_CURSORENDOFFILE_SEL: rReq.SetSlot( SID_CURSORENDOFFILE ); break;
+ default:
+ DBG_ERROR("Unbekannte Message bei ViewShell (ExecutePageSel)");
+ return;
+ }
+ rReq.AppendItem( SfxBoolItem(FN_PARAM_2, sal_True) );
+ ExecuteSlot( rReq, GetInterface() );
+}
+
+void ScCellShell::ExecutePage( SfxRequest& rReq )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ sal_uInt16 nSlotId = rReq.GetSlot();
+ sal_Bool bSel = sal_False;
+ sal_Bool bKeep = sal_False;
+
+ if ( pReqArgs != NULL )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FN_PARAM_2, &pItem ) )
+ bSel = ((const SfxBoolItem*)pItem)->GetValue();
+ }
+ else
+ {
+ // evaluate locked selection mode
+
+ sal_uInt16 nLocked = pTabViewShell->GetLockedModifiers();
+ if ( nLocked & KEY_SHIFT )
+ bSel = sal_True; // EXT
+ else if ( nLocked & KEY_MOD1 )
+ {
+ // ADD mode: keep the selection, start a new block when marking with shift again
+ bKeep = sal_True;
+ pTabViewShell->SetNewStartIfMarking();
+ }
+ }
+
+ pTabViewShell->ExecuteInputDirect();
+ switch ( nSlotId )
+ {
+ case SID_CURSORHOME:
+ pTabViewShell->MoveCursorEnd( -1, 0, SC_FOLLOW_LINE, bSel, bKeep );
+ break;
+
+ case SID_CURSOREND:
+ pTabViewShell->MoveCursorEnd( 1, 0, SC_FOLLOW_JUMP, bSel, bKeep );
+ break;
+
+ case SID_CURSORTOPOFFILE:
+ pTabViewShell->MoveCursorEnd( -1, -1, SC_FOLLOW_LINE, bSel, bKeep );
+ break;
+
+ case SID_CURSORENDOFFILE:
+ pTabViewShell->MoveCursorEnd( 1, 1, SC_FOLLOW_JUMP, bSel, bKeep );
+ break;
+
+ default:
+ DBG_ERROR("Unbekannte Message bei ViewShell (ExecutePage)");
+ return;
+ }
+
+ rReq.AppendItem( SfxBoolItem(FN_PARAM_2, bSel) );
+ rReq.Done();
+}
+
+
+
+
diff --git a/sc/source/ui/view/colrowba.cxx b/sc/source/ui/view/colrowba.cxx
new file mode 100644
index 000000000000..13bc1e8eb1f5
--- /dev/null
+++ b/sc/source/ui/view/colrowba.cxx
@@ -0,0 +1,419 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svx/svdtrans.hxx>
+#include <unotools/localedatawrapper.hxx>
+
+#include "colrowba.hxx"
+#include "document.hxx"
+#include "scmod.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "appoptio.hxx"
+#include "globstr.hrc"
+
+// STATIC DATA -----------------------------------------------------------
+
+//==================================================================
+
+String lcl_MetricString( long nTwips, const String& rText )
+{
+ if ( nTwips <= 0 )
+ return ScGlobal::GetRscString(STR_TIP_HIDE);
+ else
+ {
+ FieldUnit eUserMet = SC_MOD()->GetAppOptions().GetAppMetric();
+
+ sal_Int64 nUserVal = MetricField::ConvertValue( nTwips*100, 1, 2, FUNIT_TWIP, eUserMet );
+
+ String aStr = rText;
+ aStr += ' ';
+ aStr += ScGlobal::pLocaleData->getNum( nUserVal, 2 );
+ aStr += ' ';
+ aStr += SdrFormatter::GetUnitStr(eUserMet);
+
+ return aStr;
+ }
+}
+
+//==================================================================
+
+ScColBar::ScColBar( Window* pParent, ScViewData* pData, ScHSplitPos eWhichPos,
+ ScHeaderFunctionSet* pFunc, ScHeaderSelectionEngine* pEng ) :
+ ScHeaderControl( pParent, pEng, MAXCOL+1, HDR_HORIZONTAL ),
+ pViewData( pData ),
+ eWhich( eWhichPos ),
+ pFuncSet( pFunc ),
+ pSelEngine( pEng )
+{
+ Show();
+}
+
+ScColBar::~ScColBar()
+{
+}
+
+inline sal_Bool ScColBar::UseNumericHeader() const
+{
+ return pViewData->GetDocument()->GetAddressConvention() == formula::FormulaGrammar::CONV_XL_R1C1;
+}
+
+SCCOLROW ScColBar::GetPos()
+{
+ return pViewData->GetPosX(eWhich);
+}
+
+sal_uInt16 ScColBar::GetEntrySize( SCCOLROW nEntryNo )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ SCCOL nLastCol = -1;
+ if (pDoc->ColHidden(static_cast<SCCOL>(nEntryNo), nTab, nLastCol))
+ return 0;
+ else
+ return (sal_uInt16) ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(nEntryNo), nTab ), pViewData->GetPPTX() );
+}
+
+String ScColBar::GetEntryText( SCCOLROW nEntryNo )
+{
+ return UseNumericHeader()
+ ? String::CreateFromInt32( nEntryNo + 1 )
+ : ScColToAlpha( static_cast<SCCOL>(nEntryNo) );
+}
+
+void ScColBar::SetEntrySize( SCCOLROW nPos, sal_uInt16 nNewSize )
+{
+ sal_uInt16 nSizeTwips;
+ ScSizeMode eMode = SC_SIZE_DIRECT;
+ if (nNewSize>0 && nNewSize<10) nNewSize=10; // (Pixel)
+
+ if ( nNewSize == HDR_SIZE_OPTIMUM )
+ {
+ nSizeTwips = STD_EXTRA_WIDTH;
+ eMode = SC_SIZE_OPTIMAL;
+ }
+ else
+ nSizeTwips = (sal_uInt16) ( nNewSize / pViewData->GetPPTX() );
+
+ ScMarkData& rMark = pViewData->GetMarkData();
+// SCTAB nTab = pViewData->GetTabNo();
+
+ SCCOLROW* pRanges = new SCCOLROW[MAXCOL+1];
+ SCCOL nRangeCnt = 0;
+ if ( rMark.IsColumnMarked( static_cast<SCCOL>(nPos) ) )
+ {
+ SCCOL nStart = 0;
+ while (nStart<=MAXCOL)
+ {
+ while (nStart<MAXCOL && !rMark.IsColumnMarked(nStart))
+ ++nStart;
+ if (rMark.IsColumnMarked(nStart))
+ {
+ SCCOL nEnd = nStart;
+ while (nEnd<MAXCOL && rMark.IsColumnMarked(nEnd))
+ ++nEnd;
+ if (!rMark.IsColumnMarked(nEnd))
+ --nEnd;
+ pRanges[static_cast<size_t>(2*nRangeCnt) ] = nStart;
+ pRanges[static_cast<size_t>(2*nRangeCnt+1)] = nEnd;
+ ++nRangeCnt;
+ nStart = nEnd+1;
+ }
+ else
+ nStart = MAXCOL+1;
+ }
+ }
+ else
+ {
+ pRanges[0] = nPos;
+ pRanges[1] = nPos;
+ nRangeCnt = 1;
+ }
+
+ pViewData->GetView()->SetWidthOrHeight( sal_True, nRangeCnt, pRanges, eMode, nSizeTwips );
+ delete[] pRanges;
+}
+
+void ScColBar::HideEntries( SCCOLROW nStart, SCCOLROW nEnd )
+{
+ SCCOLROW nRange[2];
+ nRange[0] = nStart;
+ nRange[1] = nEnd;
+ pViewData->GetView()->SetWidthOrHeight( sal_True, 1, nRange, SC_SIZE_DIRECT, 0 );
+}
+
+void ScColBar::SetMarking( sal_Bool bSet )
+{
+ pViewData->GetMarkData().SetMarking( bSet );
+ if (!bSet)
+ {
+ pViewData->GetView()->UpdateAutoFillMark();
+ }
+}
+
+void ScColBar::SelectWindow()
+{
+ ScTabViewShell* pViewSh = pViewData->GetViewShell();
+
+ pViewSh->SetActive(); // Appear und SetViewFrame
+ pViewSh->DrawDeselectAll();
+
+ ScSplitPos eActive = pViewData->GetActivePart();
+ if (eWhich==SC_SPLIT_LEFT)
+ {
+ if (eActive==SC_SPLIT_TOPRIGHT) eActive=SC_SPLIT_TOPLEFT;
+ if (eActive==SC_SPLIT_BOTTOMRIGHT) eActive=SC_SPLIT_BOTTOMLEFT;
+ }
+ else
+ {
+ if (eActive==SC_SPLIT_TOPLEFT) eActive=SC_SPLIT_TOPRIGHT;
+ if (eActive==SC_SPLIT_BOTTOMLEFT) eActive=SC_SPLIT_BOTTOMRIGHT;
+ }
+ pViewSh->ActivatePart( eActive );
+
+ pFuncSet->SetColumn( sal_True );
+ pFuncSet->SetWhich( eActive );
+
+ pViewSh->ActiveGrabFocus();
+}
+
+sal_Bool ScColBar::IsDisabled()
+{
+ ScModule* pScMod = SC_MOD();
+ return pScMod->IsFormulaMode() || pScMod->IsModalMode();
+}
+
+sal_Bool ScColBar::ResizeAllowed()
+{
+ return !pViewData->HasEditView( pViewData->GetActivePart() ) &&
+ !pViewData->GetDocShell()->IsReadOnly();
+}
+
+void ScColBar::DrawInvert( long nDragPosP )
+{
+ Rectangle aRect( nDragPosP,0, nDragPosP+HDR_SLIDERSIZE-1,GetOutputSizePixel().Width()-1 );
+ Update();
+ Invert(aRect);
+
+ pViewData->GetView()->InvertVertical(eWhich,nDragPosP);
+}
+
+String ScColBar::GetDragHelp( long nVal )
+{
+ long nTwips = (long) ( nVal / pViewData->GetPPTX() );
+ return lcl_MetricString( nTwips, ScGlobal::GetRscString(STR_TIP_WIDTH) );
+}
+
+sal_Bool ScColBar::IsLayoutRTL() // overloaded only for columns
+{
+ return pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
+}
+
+//==================================================================
+
+ScRowBar::ScRowBar( Window* pParent, ScViewData* pData, ScVSplitPos eWhichPos,
+ ScHeaderFunctionSet* pFunc, ScHeaderSelectionEngine* pEng ) :
+ ScHeaderControl( pParent, pEng, MAXROW+1, HDR_VERTICAL ),
+ pViewData( pData ),
+ eWhich( eWhichPos ),
+ pFuncSet( pFunc ),
+ pSelEngine( pEng )
+{
+ Show();
+}
+
+ScRowBar::~ScRowBar()
+{
+}
+
+SCCOLROW ScRowBar::GetPos()
+{
+ return pViewData->GetPosY(eWhich);
+}
+
+sal_uInt16 ScRowBar::GetEntrySize( SCCOLROW nEntryNo )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ SCROW nLastRow = -1;
+ if (pDoc->RowHidden(nEntryNo, nTab, nLastRow))
+ return 0;
+ else
+ return (sal_uInt16) ScViewData::ToPixel( pDoc->GetOriginalHeight( nEntryNo,
+ nTab ), pViewData->GetPPTY() );
+}
+
+String ScRowBar::GetEntryText( SCCOLROW nEntryNo )
+{
+ return String::CreateFromInt32( nEntryNo + 1 );
+}
+
+void ScRowBar::SetEntrySize( SCCOLROW nPos, sal_uInt16 nNewSize )
+{
+ sal_uInt16 nSizeTwips;
+ ScSizeMode eMode = SC_SIZE_DIRECT;
+ if (nNewSize>0 && nNewSize<10) nNewSize=10; // (Pixel)
+
+ if ( nNewSize == HDR_SIZE_OPTIMUM )
+ {
+ nSizeTwips = 0;
+ eMode = SC_SIZE_OPTIMAL;
+ }
+ else
+ nSizeTwips = (sal_uInt16) ( nNewSize / pViewData->GetPPTY() );
+
+ ScMarkData& rMark = pViewData->GetMarkData();
+// SCTAB nTab = pViewData->GetTabNo();
+
+ SCCOLROW* pRanges = new SCCOLROW[MAXROW+1];
+ SCROW nRangeCnt = 0;
+ if ( rMark.IsRowMarked( nPos ) )
+ {
+ SCROW nStart = 0;
+ while (nStart<=MAXROW)
+ {
+ while (nStart<MAXROW && !rMark.IsRowMarked(nStart))
+ ++nStart;
+ if (rMark.IsRowMarked(nStart))
+ {
+ SCROW nEnd = nStart;
+ while (nEnd<MAXROW && rMark.IsRowMarked(nEnd))
+ ++nEnd;
+ if (!rMark.IsRowMarked(nEnd))
+ --nEnd;
+ pRanges[static_cast<size_t>(2*nRangeCnt) ] = nStart;
+ pRanges[static_cast<size_t>(2*nRangeCnt+1)] = nEnd;
+ ++nRangeCnt;
+ nStart = nEnd+1;
+ }
+ else
+ nStart = MAXROW+1;
+ }
+ }
+ else
+ {
+ pRanges[0] = nPos;
+ pRanges[1] = nPos;
+ nRangeCnt = 1;
+ }
+
+ pViewData->GetView()->SetWidthOrHeight( sal_False, nRangeCnt, pRanges, eMode, nSizeTwips );
+ delete[] pRanges;
+}
+
+void ScRowBar::HideEntries( SCCOLROW nStart, SCCOLROW nEnd )
+{
+ SCCOLROW nRange[2];
+ nRange[0] = nStart;
+ nRange[1] = nEnd;
+ pViewData->GetView()->SetWidthOrHeight( sal_False, 1, nRange, SC_SIZE_DIRECT, 0 );
+}
+
+void ScRowBar::SetMarking( sal_Bool bSet )
+{
+ pViewData->GetMarkData().SetMarking( bSet );
+ if (!bSet)
+ {
+ pViewData->GetView()->UpdateAutoFillMark();
+ }
+}
+
+void ScRowBar::SelectWindow()
+{
+ ScTabViewShell* pViewSh = pViewData->GetViewShell();
+
+ pViewSh->SetActive(); // Appear und SetViewFrame
+ pViewSh->DrawDeselectAll();
+
+ ScSplitPos eActive = pViewData->GetActivePart();
+ if (eWhich==SC_SPLIT_TOP)
+ {
+ if (eActive==SC_SPLIT_BOTTOMLEFT) eActive=SC_SPLIT_TOPLEFT;
+ if (eActive==SC_SPLIT_BOTTOMRIGHT) eActive=SC_SPLIT_TOPRIGHT;
+ }
+ else
+ {
+ if (eActive==SC_SPLIT_TOPLEFT) eActive=SC_SPLIT_BOTTOMLEFT;
+ if (eActive==SC_SPLIT_TOPRIGHT) eActive=SC_SPLIT_BOTTOMRIGHT;
+ }
+ pViewSh->ActivatePart( eActive );
+
+ pFuncSet->SetColumn( sal_False );
+ pFuncSet->SetWhich( eActive );
+
+ pViewSh->ActiveGrabFocus();
+}
+
+sal_Bool ScRowBar::IsDisabled()
+{
+ ScModule* pScMod = SC_MOD();
+ return pScMod->IsFormulaMode() || pScMod->IsModalMode();
+}
+
+sal_Bool ScRowBar::ResizeAllowed()
+{
+ return !pViewData->HasEditView( pViewData->GetActivePart() ) &&
+ !pViewData->GetDocShell()->IsReadOnly();
+}
+
+void ScRowBar::DrawInvert( long nDragPosP )
+{
+ Rectangle aRect( 0,nDragPosP, GetOutputSizePixel().Width()-1,nDragPosP+HDR_SLIDERSIZE-1 );
+ Update();
+ Invert(aRect);
+
+ pViewData->GetView()->InvertHorizontal(eWhich,nDragPosP);
+}
+
+String ScRowBar::GetDragHelp( long nVal )
+{
+ long nTwips = (long) ( nVal / pViewData->GetPPTY() );
+ return lcl_MetricString( nTwips, ScGlobal::GetRscString(STR_TIP_HEIGHT) );
+}
+
+// GetHiddenCount ist nur fuer Zeilen ueberladen
+
+SCROW ScRowBar::GetHiddenCount( SCROW nEntryNo )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ return pDoc->GetHiddenRowCount( nEntryNo, nTab );
+}
+
+sal_Bool ScRowBar::IsMirrored() // overloaded only for rows
+{
+ return pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
+}
+
+
diff --git a/sc/source/ui/view/dbfunc.cxx b/sc/source/ui/view/dbfunc.cxx
new file mode 100644
index 000000000000..8db71ad9752f
--- /dev/null
+++ b/sc/source/ui/view/dbfunc.cxx
@@ -0,0 +1,512 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <sfx2/app.hxx>
+#include <sfx2/bindings.hxx>
+#include <vcl/msgbox.hxx>
+
+#include <com/sun/star/sdbc/XResultSet.hpp>
+
+#include "dbfunc.hxx"
+#include "docsh.hxx"
+#include "attrib.hxx"
+#include "sc.hrc"
+#include "undodat.hxx"
+#include "dbcolect.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "dbdocfun.hxx"
+#include "editable.hxx"
+
+//==================================================================
+
+ScDBFunc::ScDBFunc( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
+ ScViewFunc( pParent, rDocSh, pViewShell )
+{
+}
+
+//UNUSED2008-05 ScDBFunc::ScDBFunc( Window* pParent, const ScDBFunc& rDBFunc, ScTabViewShell* pViewShell ) :
+//UNUSED2008-05 ScViewFunc( pParent, rDBFunc, pViewShell )
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+
+ScDBFunc::~ScDBFunc()
+{
+}
+
+//
+// Hilfsfunktionen
+//
+
+void ScDBFunc::GotoDBArea( const String& rDBName )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDBCollection* pDBCol = pDoc->GetDBCollection();
+
+ sal_uInt16 nFoundAt = 0;
+ if ( pDBCol->SearchName( rDBName, nFoundAt ) )
+ {
+ ScDBData* pData = (*pDBCol)[nFoundAt];
+ DBG_ASSERT( pData, "GotoDBArea: Datenbankbereich nicht gefunden!" );
+
+ if ( pData )
+ {
+ SCTAB nTab = 0;
+ SCCOL nStartCol = 0;
+ SCROW nStartRow = 0;
+ SCCOL nEndCol = 0;
+ SCROW nEndRow = 0;
+
+ pData->GetArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow );
+ SetTabNo( nTab );
+
+ MoveCursorAbs( nStartCol, nStartRow, ScFollowMode( SC_FOLLOW_JUMP ),
+ sal_False, sal_False ); // bShift,bControl
+ DoneBlockMode();
+ InitBlockMode( nStartCol, nStartRow, nTab );
+ MarkCursor( nEndCol, nEndRow, nTab );
+ SelectionChanged();
+ }
+ }
+}
+
+// aktuellen Datenbereich fuer Sortieren / Filtern suchen
+
+ScDBData* ScDBFunc::GetDBData( sal_Bool bMark, ScGetDBMode eMode, ScGetDBSelection eSel )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDBData* pData = NULL;
+ ScRange aRange;
+ ScMarkType eMarkType = GetViewData()->GetSimpleArea(aRange);
+ if ( eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED )
+ {
+ bool bShrinkColumnsOnly = false;
+ if (eSel == SC_DBSEL_ROW_DOWN)
+ {
+ // Don't alter row range, additional rows may have been selected on
+ // purpose to append data, or to have a fake header row.
+ bShrinkColumnsOnly = true;
+ // Select further rows only if only one row or a portion thereof is
+ // selected.
+ if (aRange.aStart.Row() != aRange.aEnd.Row())
+ {
+ // If an area is selected shrink that to the actual used
+ // columns, don't draw filter buttons for empty columns.
+ eSel = SC_DBSEL_SHRINK_TO_USED_DATA;
+ }
+ else if (aRange.aStart.Col() == aRange.aEnd.Col())
+ {
+ // One cell only, if it is not marked obtain entire used data
+ // area.
+ const ScMarkData& rMarkData = GetViewData()->GetMarkData();
+ if (!(rMarkData.IsMarked() || rMarkData.IsMultiMarked()))
+ eSel = SC_DBSEL_KEEP;
+ }
+ }
+ switch (eSel)
+ {
+ case SC_DBSEL_SHRINK_TO_SHEET_DATA:
+ {
+ // Shrink the selection to sheet data area.
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCCOL nCol1 = aRange.aStart.Col(), nCol2 = aRange.aEnd.Col();
+ SCROW nRow1 = aRange.aStart.Row(), nRow2 = aRange.aEnd.Row();
+ if (pDoc->ShrinkToDataArea( aRange.aStart.Tab(), nCol1, nRow1, nCol2, nRow2))
+ {
+ aRange.aStart.SetCol(nCol1);
+ aRange.aEnd.SetCol(nCol2);
+ aRange.aStart.SetRow(nRow1);
+ aRange.aEnd.SetRow(nRow2);
+ }
+ }
+ break;
+ case SC_DBSEL_SHRINK_TO_USED_DATA:
+ case SC_DBSEL_ROW_DOWN:
+ {
+ // Shrink the selection to actual used area.
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCCOL nCol1 = aRange.aStart.Col(), nCol2 = aRange.aEnd.Col();
+ SCROW nRow1 = aRange.aStart.Row(), nRow2 = aRange.aEnd.Row();
+ bool bShrunk;
+ pDoc->ShrinkToUsedDataArea( bShrunk, aRange.aStart.Tab(),
+ nCol1, nRow1, nCol2, nRow2, bShrinkColumnsOnly);
+ if (bShrunk)
+ {
+ aRange.aStart.SetCol(nCol1);
+ aRange.aEnd.SetCol(nCol2);
+ aRange.aStart.SetRow(nRow1);
+ aRange.aEnd.SetRow(nRow2);
+ }
+ }
+ break;
+ default:
+ ; // nothing
+ }
+ pData = pDocSh->GetDBData( aRange, eMode, eSel );
+ }
+ else if ( eMode != SC_DB_OLD )
+ pData = pDocSh->GetDBData(
+ ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
+ GetViewData()->GetTabNo() ),
+ eMode, SC_DBSEL_KEEP );
+
+ if ( pData && bMark )
+ {
+ ScRange aFound;
+ pData->GetArea(aFound);
+ MarkRange( aFound, sal_False );
+ }
+ return pData;
+}
+
+// Datenbankbereiche aendern (Dialog)
+
+void ScDBFunc::NotifyCloseDbNameDlg( const ScDBCollection& rNewColl, const List& rDelAreaList )
+{
+
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ ScDocShellModificator aModificator( *pDocShell );
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDBCollection* pOldColl = pDoc->GetDBCollection();
+ ScDBCollection* pUndoColl = NULL;
+ ScDBCollection* pRedoColl = NULL;
+ const sal_Bool bRecord (pDoc->IsUndoEnabled());
+
+ long nDelCount = rDelAreaList.Count();
+ for (long nDelPos=0; nDelPos<nDelCount; nDelPos++)
+ {
+ ScRange* pEntry = (ScRange*) rDelAreaList.GetObject(nDelPos);
+
+ if ( pEntry )
+ {
+ ScAddress& rStart = pEntry->aStart;
+ ScAddress& rEnd = pEntry->aEnd;
+ pDocShell->DBAreaDeleted( rStart.Tab(),
+ rStart.Col(), rStart.Row(),
+ rEnd.Col(), rEnd.Row() );
+
+ // Targets am SBA abmelden nicht mehr noetig
+ }
+ }
+
+ if (bRecord)
+ pUndoColl = new ScDBCollection( *pOldColl );
+
+ // neue Targets am SBA anmelden nicht mehr noetig
+
+ pDoc->CompileDBFormula( sal_True ); // CreateFormulaString
+ pDoc->SetDBCollection( new ScDBCollection( rNewColl ) );
+ pDoc->CompileDBFormula( sal_False ); // CompileFormulaString
+ pOldColl = NULL;
+ pDocShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID );
+ aModificator.SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
+
+ if (bRecord)
+ {
+ pRedoColl = new ScDBCollection( rNewColl );
+ pDocShell->GetUndoManager()->AddUndoAction(
+ new ScUndoDBData( pDocShell, pUndoColl, pRedoColl ) );
+ }
+}
+
+//
+// wirkliche Funktionen
+//
+
+// Sortieren
+
+void ScDBFunc::UISort( const ScSortParam& rSortParam, sal_Bool bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDBData* pDBData = pDoc->GetDBAtArea( nTab, rSortParam.nCol1, rSortParam.nRow1,
+ rSortParam.nCol2, rSortParam.nRow2 );
+ if (!pDBData)
+ {
+ DBG_ERROR( "Sort: keine DBData" );
+ return;
+ }
+
+ ScSubTotalParam aSubTotalParam;
+ pDBData->GetSubTotalParam( aSubTotalParam );
+ if (aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly)
+ {
+ // Subtotals wiederholen, mit neuer Sortierung
+
+ DoSubTotals( aSubTotalParam, bRecord, &rSortParam );
+ }
+ else
+ {
+ Sort( rSortParam, bRecord ); // nur sortieren
+ }
+}
+
+void ScDBFunc::Sort( const ScSortParam& rSortParam, sal_Bool bRecord, sal_Bool bPaint )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDBDocFunc aDBDocFunc( *pDocSh );
+ sal_Bool bSuccess = aDBDocFunc.Sort( nTab, rSortParam, bRecord, bPaint, sal_False );
+ if ( bSuccess && !rSortParam.bInplace )
+ {
+ // Ziel markieren
+ ScRange aDestRange( rSortParam.nDestCol, rSortParam.nDestRow, rSortParam.nDestTab,
+ rSortParam.nDestCol + rSortParam.nCol2 - rSortParam.nCol1,
+ rSortParam.nDestRow + rSortParam.nRow2 - rSortParam.nRow1,
+ rSortParam.nDestTab );
+ MarkRange( aDestRange );
+ }
+}
+
+// Filtern
+
+void ScDBFunc::Query( const ScQueryParam& rQueryParam, const ScRange* pAdvSource, sal_Bool bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDBDocFunc aDBDocFunc( *pDocSh );
+ sal_Bool bSuccess = aDBDocFunc.Query( nTab, rQueryParam, pAdvSource, bRecord, sal_False );
+
+ if (bSuccess)
+ {
+ sal_Bool bCopy = !rQueryParam.bInplace;
+ if (bCopy)
+ {
+ // Zielbereich markieren (DB-Bereich wurde ggf. angelegt)
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScDBData* pDestData = pDoc->GetDBAtCursor(
+ rQueryParam.nDestCol, rQueryParam.nDestRow,
+ rQueryParam.nDestTab, sal_True );
+ if (pDestData)
+ {
+ ScRange aDestRange;
+ pDestData->GetArea(aDestRange);
+ MarkRange( aDestRange );
+ }
+ }
+
+ if (!bCopy)
+ {
+ UpdateScrollBars();
+ SelectionChanged(); // for attribute states (filtered rows are ignored)
+ }
+
+ GetViewData()->GetBindings().Invalidate( SID_UNFILTER );
+ }
+}
+
+// Autofilter-Knoepfe ein-/ausblenden
+
+void ScDBFunc::ToggleAutoFilter()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocShellModificator aModificator( *pDocSh );
+
+ ScQueryParam aParam;
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDBData* pDBData = GetDBData( sal_False, SC_DB_MAKE, SC_DBSEL_ROW_DOWN );
+
+ pDBData->SetByRow( sal_True ); //! Undo, vorher abfragen ??
+ pDBData->GetQueryParam( aParam );
+
+
+ SCCOL nCol;
+ SCROW nRow = aParam.nRow1;
+ SCTAB nTab = GetViewData()->GetTabNo();
+ sal_Int16 nFlag;
+ sal_Bool bHasAuto = sal_True;
+ sal_Bool bHeader = pDBData->HasHeader();
+ sal_Bool bPaint = sal_False;
+
+ //! stattdessen aus DB-Bereich abfragen?
+
+ for (nCol=aParam.nCol1; nCol<=aParam.nCol2 && bHasAuto; nCol++)
+ {
+ nFlag = ((ScMergeFlagAttr*) pDoc->
+ GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->GetValue();
+
+ if ( (nFlag & SC_MF_AUTO) == 0 )
+ bHasAuto = sal_False;
+ }
+
+ if (bHasAuto) // aufheben
+ {
+ // Filterknoepfe ausblenden
+
+ for (nCol=aParam.nCol1; nCol<=aParam.nCol2; nCol++)
+ {
+ nFlag = ((ScMergeFlagAttr*) pDoc->
+ GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->GetValue();
+ pDoc->ApplyAttr( nCol, nRow, nTab, ScMergeFlagAttr( nFlag & ~SC_MF_AUTO ) );
+ }
+
+ // use a list action for the AutoFilter buttons (ScUndoAutoFilter) and the filter operation
+
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_QUERY );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+
+ ScRange aRange;
+ pDBData->GetArea( aRange );
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoAutoFilter( pDocSh, aRange, pDBData->GetName(), sal_False ) );
+
+ pDBData->SetAutoFilter(sal_False);
+
+ // Filter aufheben (incl. Paint / Undo)
+
+ SCSIZE nEC = aParam.GetEntryCount();
+ for (SCSIZE i=0; i<nEC; i++)
+ aParam.GetEntry(i).bDoQuery = sal_False;
+ aParam.bDuplicate = sal_True;
+ Query( aParam, NULL, sal_True );
+
+ pDocSh->GetUndoManager()->LeaveListAction();
+
+ bPaint = sal_True;
+ }
+ else // Filterknoepfe einblenden
+ {
+ if ( !pDoc->IsBlockEmpty( nTab,
+ aParam.nCol1, aParam.nRow1,
+ aParam.nCol2, aParam.nRow2 ) )
+ {
+ if (!bHeader)
+ {
+ if ( MessBox( GetViewData()->GetDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), // "StarCalc"
+ ScGlobal::GetRscString( STR_MSSG_MAKEAUTOFILTER_0 ) // Koepfe aus erster Zeile?
+ ).Execute() == RET_YES )
+ {
+ pDBData->SetHeader( sal_True ); //! Undo ??
+ bHeader = sal_True;
+ }
+ }
+
+ ScRange aRange;
+ pDBData->GetArea( aRange );
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoAutoFilter( pDocSh, aRange, pDBData->GetName(), sal_True ) );
+
+ pDBData->SetAutoFilter(sal_True);
+
+ for (nCol=aParam.nCol1; nCol<=aParam.nCol2; nCol++)
+ {
+ nFlag = ((ScMergeFlagAttr*) pDoc->
+ GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->GetValue();
+ pDoc->ApplyAttr( nCol, nRow, nTab, ScMergeFlagAttr( nFlag | SC_MF_AUTO ) );
+ }
+ pDocSh->PostPaint( aParam.nCol1, nRow, nTab, aParam.nCol2, nRow, nTab,
+ PAINT_GRID );
+ bPaint = sal_True;
+ }
+ else
+ {
+ ErrorBox aErrorBox( GetViewData()->GetDialogParent(), WinBits( WB_OK | WB_DEF_OK ),
+ ScGlobal::GetRscString( STR_ERR_AUTOFILTER ) );
+ aErrorBox.Execute();
+ }
+ }
+
+ if ( bPaint )
+ {
+ aModificator.SetDocumentModified();
+
+ SfxBindings& rBindings = GetViewData()->GetBindings();
+ rBindings.Invalidate( SID_AUTO_FILTER );
+ rBindings.Invalidate( SID_AUTOFILTER_HIDE );
+ }
+}
+
+// nur ausblenden, keine Daten veraendern
+
+void ScDBFunc::HideAutoFilter()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocShellModificator aModificator( *pDocSh );
+
+ ScDocument* pDoc = pDocSh->GetDocument();
+
+ ScQueryParam aParam;
+ ScDBData* pDBData = GetDBData( sal_False );
+
+ SCTAB nTab;
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ pDBData->GetArea(nTab, nCol1, nRow1, nCol2, nRow2);
+
+ for (SCCOL nCol=nCol1; nCol<=nCol2; nCol++)
+ {
+ sal_Int16 nFlag = ((ScMergeFlagAttr*) pDoc->
+ GetAttr( nCol, nRow1, nTab, ATTR_MERGE_FLAG ))->GetValue();
+ pDoc->ApplyAttr( nCol, nRow1, nTab, ScMergeFlagAttr( nFlag & ~SC_MF_AUTO ) );
+ }
+
+ ScRange aRange;
+ pDBData->GetArea( aRange );
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoAutoFilter( pDocSh, aRange, pDBData->GetName(), sal_False ) );
+
+ pDBData->SetAutoFilter(sal_False);
+
+ pDocSh->PostPaint( nCol1,nRow1,nTab, nCol2,nRow1,nTab, PAINT_GRID );
+ aModificator.SetDocumentModified();
+
+ SfxBindings& rBindings = GetViewData()->GetBindings();
+ rBindings.Invalidate( SID_AUTO_FILTER );
+ rBindings.Invalidate( SID_AUTOFILTER_HIDE );
+}
+
+// Re-Import
+
+sal_Bool ScDBFunc::ImportData( const ScImportParam& rParam, sal_Bool bRecord )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScEditableTester aTester( pDoc, GetViewData()->GetTabNo(), rParam.nCol1,rParam.nRow1,
+ rParam.nCol2,rParam.nRow2 );
+ if ( !aTester.IsEditable() )
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return sal_False;
+ }
+
+ ScDBDocFunc aDBDocFunc( *GetViewData()->GetDocShell() );
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > xResultSet;
+ return aDBDocFunc.DoImport( GetViewData()->GetTabNo(), rParam, xResultSet, NULL, bRecord );
+}
+
+
+
diff --git a/sc/source/ui/view/dbfunc2.cxx b/sc/source/ui/view/dbfunc2.cxx
new file mode 100644
index 000000000000..d3e4229736d3
--- /dev/null
+++ b/sc/source/ui/view/dbfunc2.cxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+
+#include "dbfunc.hxx"
+#include "docsh.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+
+
+// STATIC DATA -----------------------------------------------------------
+
+
+#ifdef _MSC_VER
+#pragma optimize ( "", off )
+#endif
+
+//==================================================================
+
+class ScDrawLayer;
+class ScChartCollection;
+
+void ScDBFunc::UpdateCharts( sal_Bool bAllCharts )
+{
+ sal_uInt16 nFound = 0;
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ if ( pDoc->GetDrawLayer() )
+ nFound = DoUpdateCharts( ScAddress( pViewData->GetCurX(),
+ pViewData->GetCurY(),
+ pViewData->GetTabNo()),
+ pDoc,
+ bAllCharts );
+
+ if ( !nFound && !bAllCharts )
+ ErrorMessage(STR_NOCHARTATCURSOR);
+}
+
+
+
+
+
+
diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx
new file mode 100644
index 000000000000..bfb3b1de0f82
--- /dev/null
+++ b/sc/source/ui/view/dbfunc3.cxx
@@ -0,0 +1,2375 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "dbfunc.hxx"
+#include "scitems.hxx"
+#include <sfx2/bindings.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/sound.hxx>
+#include <vcl/waitobj.hxx>
+#include <svl/zforlist.hxx>
+#include <sfx2/app.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
+#include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
+#include <com/sun/star/sheet/GeneralFunction.hpp>
+#include <com/sun/star/sheet/MemberResultFlags.hpp>
+#include <com/sun/star/sheet/XDimensionsSupplier.hpp>
+#include <com/sun/star/sheet/XDrillDownDataSupplier.hpp>
+
+#include "global.hxx"
+#include "globstr.hrc"
+#include "sc.hrc"
+#include "undotab.hxx"
+#include "undodat.hxx"
+#include "dbcolect.hxx"
+#include "rangenam.hxx"
+#include "rangeutl.hxx"
+#include "docsh.hxx"
+#include "olinetab.hxx"
+#include "consoli.hxx"
+#include "olinefun.hxx"
+#include "dpobject.hxx"
+#include "dpsave.hxx"
+#include "dpdimsave.hxx"
+#include "dbdocfun.hxx"
+#include "dpoutput.hxx"
+#include "dptabsrc.hxx"
+#include "editable.hxx"
+#include "docpool.hxx"
+#include "patattr.hxx"
+#include "unonames.hxx"
+#include "cell.hxx"
+#include "userlist.hxx"
+
+#include <hash_set>
+#include <hash_map>
+#include <memory>
+#include <list>
+#include <vector>
+
+using namespace com::sun::star;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::container::XNameAccess;
+using ::com::sun::star::sheet::XDimensionsSupplier;
+using ::rtl::OUString;
+using ::rtl::OUStringHash;
+using ::rtl::OUStringBuffer;
+using ::std::auto_ptr;
+using ::std::list;
+using ::std::vector;
+using ::std::hash_map;
+using ::std::hash_set;
+
+// STATIC DATA -----------------------------------------------------------
+
+
+//==================================================================
+
+//
+// Outliner
+//
+
+// Outline-Gruppierung erzeugen
+
+void ScDBFunc::MakeOutline( sal_Bool bColumns, sal_Bool bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScOutlineDocFunc aFunc(*pDocSh);
+ aFunc.MakeOutline( aRange, bColumns, bRecord, sal_False );
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+// Outline-Gruppierung loeschen
+
+void ScDBFunc::RemoveOutline( sal_Bool bColumns, sal_Bool bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScOutlineDocFunc aFunc(*pDocSh);
+ aFunc.RemoveOutline( aRange, bColumns, bRecord, sal_False );
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+// Menue-Status: Outlines loeschen
+
+void ScDBFunc::TestRemoveOutline( sal_Bool& rCol, sal_Bool& rRow )
+{
+ sal_Bool bColFound = sal_False;
+ sal_Bool bRowFound = sal_False;
+
+ SCCOL nStartCol, nEndCol;
+ SCROW nStartRow, nEndRow;
+ SCTAB nStartTab, nEndTab;
+ if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
+ {
+ SCTAB nTab = nStartTab;
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
+ if (pTable)
+ {
+ ScOutlineArray* pArray;
+ ScOutlineEntry* pEntry;
+ SCCOLROW nStart;
+ SCCOLROW nEnd;
+ sal_Bool bColMarked = ( nStartRow == 0 && nEndRow == MAXROW );
+ sal_Bool bRowMarked = ( nStartCol == 0 && nEndCol == MAXCOL );
+
+ // Spalten
+
+ if ( !bRowMarked || bColMarked ) // nicht wenn ganze Zeilen markiert
+ {
+ pArray = pTable->GetColArray();
+ ScSubOutlineIterator aColIter( pArray );
+ while ((pEntry=aColIter.GetNext()) != NULL && !bColFound)
+ {
+ nStart = pEntry->GetStart();
+ nEnd = pEntry->GetEnd();
+ if ( nStartCol<=static_cast<SCCOL>(nEnd) && nEndCol>=static_cast<SCCOL>(nStart) )
+ bColFound = sal_True;
+ }
+ }
+
+ // Zeilen
+
+ if ( !bColMarked || bRowMarked ) // nicht wenn ganze Spalten markiert
+ {
+ pArray = pTable->GetRowArray();
+ ScSubOutlineIterator aRowIter( pArray );
+ while ((pEntry=aRowIter.GetNext()) != NULL && !bRowFound)
+ {
+ nStart = pEntry->GetStart();
+ nEnd = pEntry->GetEnd();
+ if ( nStartRow<=nEnd && nEndRow>=nStart )
+ bRowFound = sal_True;
+ }
+ }
+ }
+ }
+
+ rCol = bColFound;
+ rRow = bRowFound;
+}
+
+void ScDBFunc::RemoveAllOutlines( sal_Bool bRecord )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScOutlineDocFunc aFunc(*pDocSh);
+
+ HideCursor();
+ sal_Bool bOk = aFunc.RemoveAllOutlines( nTab, bRecord, sal_False );
+ ShowCursor();
+
+ if (bOk)
+ UpdateScrollBars();
+}
+
+// Auto-Outlines
+
+void ScDBFunc::AutoOutline( sal_Bool bRecord )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScRange aRange( 0,0,nTab, MAXCOL,MAXROW,nTab ); // ganze Tabelle, wenn nichts markiert
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ {
+ rMark.MarkToMulti();
+ rMark.GetMultiMarkArea( aRange );
+ }
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScOutlineDocFunc aFunc(*pDocSh);
+ aFunc.AutoOutline( aRange, bRecord, sal_False );
+}
+
+// Outline-Ebene auswaehlen
+
+void ScDBFunc::SelectLevel( sal_Bool bColumns, sal_uInt16 nLevel, sal_Bool bRecord, sal_Bool bPaint )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScOutlineDocFunc aFunc(*pDocSh);
+
+ HideCursor();
+ sal_Bool bOk = aFunc.SelectLevel( nTab, bColumns, nLevel, bRecord, bPaint, sal_False );
+ ShowCursor();
+
+ if (bOk)
+ UpdateScrollBars();
+}
+
+// einzelne Outline-Gruppe einblenden
+
+void ScDBFunc::ShowOutline( sal_Bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry, sal_Bool bRecord, sal_Bool bPaint )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScOutlineDocFunc aFunc(*pDocSh);
+
+ HideCursor();
+ sal_Bool bOk = aFunc.ShowOutline( nTab, bColumns, nLevel, nEntry, bRecord, bPaint, sal_False );
+ ShowCursor();
+
+ if ( bOk && bPaint )
+ UpdateScrollBars();
+}
+
+// einzelne Outline-Gruppe ausblenden
+
+void ScDBFunc::HideOutline( sal_Bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry, sal_Bool bRecord, sal_Bool bPaint )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScOutlineDocFunc aFunc(*pDocSh);
+
+ HideCursor();
+ sal_Bool bOk = aFunc.HideOutline( nTab, bColumns, nLevel, nEntry, bRecord, bPaint, sal_False );
+ ShowCursor();
+
+ if ( bOk && bPaint )
+ UpdateScrollBars();
+}
+
+// Menue-Status: markierten Bereich ein-/ausblenden
+
+sal_Bool ScDBFunc::OutlinePossible(sal_Bool bHide)
+{
+ sal_Bool bEnable = sal_False;
+
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+
+ if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
+ if (pTable)
+ {
+ ScOutlineArray* pArray;
+ ScOutlineEntry* pEntry;
+ SCCOLROW nStart;
+ SCCOLROW nEnd;
+
+ // Spalten
+
+ pArray = pTable->GetColArray();
+ ScSubOutlineIterator aColIter( pArray );
+ while ((pEntry=aColIter.GetNext()) != NULL && !bEnable)
+ {
+ nStart = pEntry->GetStart();
+ nEnd = pEntry->GetEnd();
+ if ( bHide )
+ {
+ if ( nStartCol<=static_cast<SCCOL>(nEnd) && nEndCol>=static_cast<SCCOL>(nStart) )
+ if (!pEntry->IsHidden())
+ bEnable = sal_True;
+ }
+ else
+ {
+ if ( nStart>=nStartCol && nEnd<=nEndCol )
+ if (pEntry->IsHidden())
+ bEnable = sal_True;
+ }
+ }
+
+ // Zeilen
+
+ pArray = pTable->GetRowArray();
+ ScSubOutlineIterator aRowIter( pArray );
+ while ((pEntry=aRowIter.GetNext()) != NULL)
+ {
+ nStart = pEntry->GetStart();
+ nEnd = pEntry->GetEnd();
+ if ( bHide )
+ {
+ if ( nStartRow<=nEnd && nEndRow>=nStart )
+ if (!pEntry->IsHidden())
+ bEnable = sal_True;
+ }
+ else
+ {
+ if ( nStart>=nStartRow && nEnd<=nEndRow )
+ if (pEntry->IsHidden())
+ bEnable = sal_True;
+ }
+ }
+ }
+ }
+
+ return bEnable;
+}
+
+// markierten Bereich einblenden
+
+void ScDBFunc::ShowMarkedOutlines( sal_Bool bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScOutlineDocFunc aFunc(*pDocSh);
+ HideCursor();
+ sal_Bool bDone = aFunc.ShowMarkedOutlines( aRange, bRecord, sal_False );
+ ShowCursor();
+ if (bDone)
+ UpdateScrollBars();
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+// markierten Bereich ausblenden
+
+void ScDBFunc::HideMarkedOutlines( sal_Bool bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScOutlineDocFunc aFunc(*pDocSh);
+ HideCursor();
+ sal_Bool bDone = aFunc.HideMarkedOutlines( aRange, bRecord, sal_False );
+ ShowCursor();
+ if (bDone)
+ UpdateScrollBars();
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+// --------------------------------------------------------------------------
+
+//
+// Teilergebnisse
+//
+
+void ScDBFunc::DoSubTotals( const ScSubTotalParam& rParam, sal_Bool bRecord,
+ const ScSortParam* pForceNewSort )
+{
+ sal_Bool bDo = !rParam.bRemoveOnly; // sal_False = nur loeschen
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = sal_False;
+
+ ScDBData* pDBData = pDoc->GetDBAtArea( nTab, rParam.nCol1, rParam.nRow1,
+ rParam.nCol2, rParam.nRow2 );
+ if (!pDBData)
+ {
+ DBG_ERROR( "SubTotals: keine DBData" );
+ return;
+ }
+
+ ScEditableTester aTester( pDoc, nTab, 0,rParam.nRow1+1, MAXCOL,MAXROW );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return;
+ }
+
+ if (pDoc->HasAttrib( rParam.nCol1, rParam.nRow1+1, nTab,
+ rParam.nCol2, rParam.nRow2, nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ))
+ {
+ ErrorMessage(STR_MSSG_INSERTCELLS_0); // nicht in zusammengefasste einfuegen
+ return;
+ }
+
+ WaitObject aWait( GetViewData()->GetDialogParent() );
+ sal_Bool bOk = sal_True;
+ sal_Bool bDelete = sal_False;
+ if (rParam.bReplace)
+ if (pDoc->TestRemoveSubTotals( nTab, rParam ))
+ {
+ bDelete = sal_True;
+ bOk = ( MessBox( GetViewData()->GetDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
+ // "StarCalc" "Daten loeschen?"
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_1 ) ).Execute()
+ == RET_YES );
+ }
+
+ if (bOk)
+ {
+ ScDocShellModificator aModificator( *pDocSh );
+
+ ScSubTotalParam aNewParam( rParam ); // Bereichsende wird veraendert
+ ScDocument* pUndoDoc = NULL;
+ ScOutlineTable* pUndoTab = NULL;
+ ScRangeName* pUndoRange = NULL;
+ ScDBCollection* pUndoDB = NULL;
+ SCTAB nTabCount = 0; // fuer Referenz-Undo
+
+ if (bRecord) // alte Daten sichern
+ {
+ sal_Bool bOldFilter = bDo && rParam.bDoSort;
+
+ nTabCount = pDoc->GetTableCount();
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
+ if (pTable)
+ {
+ pUndoTab = new ScOutlineTable( *pTable );
+
+ SCCOLROW nOutStartCol; // Zeilen/Spaltenstatus
+ SCCOLROW nOutStartRow;
+ SCCOLROW nOutEndCol;
+ SCCOLROW nOutEndRow;
+ pTable->GetColArray()->GetRange( nOutStartCol, nOutEndCol );
+ pTable->GetRowArray()->GetRange( nOutStartRow, nOutEndRow );
+
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
+ pDoc->CopyToDocument( static_cast<SCCOL>(nOutStartCol), 0, nTab, static_cast<SCCOL>(nOutEndCol), MAXROW, nTab, IDF_NONE, sal_False, pUndoDoc );
+ pDoc->CopyToDocument( 0, nOutStartRow, nTab, MAXCOL, nOutEndRow, nTab, IDF_NONE, sal_False, pUndoDoc );
+ }
+ else
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_False, bOldFilter );
+
+ // Datenbereich sichern - incl. Filter-Ergebnis
+ pDoc->CopyToDocument( 0,rParam.nRow1+1,nTab, MAXCOL,rParam.nRow2,nTab,
+ IDF_ALL, sal_False, pUndoDoc );
+
+ // alle Formeln wegen Referenzen
+ pDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTabCount-1,
+ IDF_FORMULA, sal_False, pUndoDoc );
+
+ // DB- und andere Bereiche
+ ScRangeName* pDocRange = pDoc->GetRangeName();
+ if (pDocRange->GetCount())
+ pUndoRange = new ScRangeName( *pDocRange );
+ ScDBCollection* pDocDB = pDoc->GetDBCollection();
+ if (pDocDB->GetCount())
+ pUndoDB = new ScDBCollection( *pDocDB );
+ }
+
+// pDoc->SetOutlineTable( nTab, NULL );
+ ScOutlineTable* pOut = pDoc->GetOutlineTable( nTab );
+ if (pOut)
+ pOut->GetRowArray()->RemoveAll(); // nur Zeilen-Outlines loeschen
+
+ if (rParam.bReplace)
+ pDoc->RemoveSubTotals( nTab, aNewParam );
+ sal_Bool bSuccess = sal_True;
+ if (bDo)
+ {
+ // Sortieren
+ if ( rParam.bDoSort || pForceNewSort )
+ {
+ pDBData->SetArea( nTab, aNewParam.nCol1,aNewParam.nRow1, aNewParam.nCol2,aNewParam.nRow2 );
+
+ // Teilergebnis-Felder vor die Sortierung setzen
+ // (doppelte werden weggelassen, kann darum auch wieder aufgerufen werden)
+
+ ScSortParam aOldSort;
+ pDBData->GetSortParam( aOldSort );
+ ScSortParam aSortParam( aNewParam, pForceNewSort ? *pForceNewSort : aOldSort );
+ Sort( aSortParam, sal_False, sal_False );
+ }
+
+ bSuccess = pDoc->DoSubTotals( nTab, aNewParam );
+ }
+ ScRange aDirtyRange( aNewParam.nCol1, aNewParam.nRow1, nTab,
+ aNewParam.nCol2, aNewParam.nRow2, nTab );
+ pDoc->SetDirty( aDirtyRange );
+
+ if (bRecord)
+ {
+// ScDBData* pUndoDBData = pDBData ? new ScDBData( *pDBData ) : NULL;
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoSubTotals( pDocSh, nTab,
+ rParam, aNewParam.nRow2,
+ pUndoDoc, pUndoTab, // pUndoDBData,
+ pUndoRange, pUndoDB ) );
+ }
+
+ if (!bSuccess)
+ {
+ // "Kann keine Zeilen einfuegen"
+ ErrorMessage(STR_MSSG_DOSUBTOTALS_2);
+ }
+
+ // merken
+ pDBData->SetSubTotalParam( aNewParam );
+ pDBData->SetArea( nTab, aNewParam.nCol1,aNewParam.nRow1, aNewParam.nCol2,aNewParam.nRow2 );
+ pDoc->CompileDBFormula();
+
+ DoneBlockMode();
+ InitOwnBlockMode();
+ rMark.SetMarkArea( ScRange( aNewParam.nCol1,aNewParam.nRow1,nTab,
+ aNewParam.nCol2,aNewParam.nRow2,nTab ) );
+ MarkDataChanged();
+
+ pDocSh->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab,
+ PAINT_GRID | PAINT_LEFT | PAINT_TOP | PAINT_SIZE );
+
+ aModificator.SetDocumentModified();
+
+ SelectionChanged();
+ }
+}
+
+//
+// Consolidate
+//
+
+void ScDBFunc::Consolidate( const ScConsolidateParam& rParam, sal_Bool bRecord )
+{
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ pDocShell->DoConsolidate( rParam, bRecord );
+ SetTabNo( rParam.nTab, sal_True );
+}
+
+//
+// Pivot
+//
+
+String lcl_MakePivotTabName( const String& rPrefix, SCTAB nNumber )
+{
+ String aName = rPrefix;
+ aName += String::CreateFromInt32( nNumber );
+ return aName;
+}
+
+bool ScDBFunc::MakePivotTable( const ScDPSaveData& rData, const ScRange& rDest, sal_Bool bNewTable,
+ const ScDPObject& rSource, sal_Bool bApi )
+{
+ // #70096# error message if no fields are set
+ // this must be removed when drag&drop of fields from a toolbox is available
+
+ if ( rData.IsEmpty() && !bApi )
+ {
+ ErrorMessage(STR_PIVOT_NODATA);
+ return false;
+ }
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ sal_Bool bUndo(pDoc->IsUndoEnabled());
+
+ ScRange aDestRange = rDest;
+ if ( bNewTable )
+ {
+ SCTAB nSrcTab = GetViewData()->GetTabNo();
+
+ String aName( ScGlobal::GetRscString(STR_PIVOT_TABLE) );
+ String aStr;
+
+ pDoc->GetName( nSrcTab, aStr );
+ aName += '_';
+ aName += aStr;
+ aName += '_';
+
+ SCTAB nNewTab = nSrcTab+1;
+
+ SCTAB i=1;
+ while ( !pDoc->InsertTab( nNewTab, lcl_MakePivotTabName( aName, i ) ) && i <= MAXTAB )
+ i++;
+
+ sal_Bool bAppend = ( nNewTab+1 == pDoc->GetTableCount() );
+ if (bUndo)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoInsertTab( pDocSh, nNewTab, bAppend, lcl_MakePivotTabName( aName, i ) ));
+ }
+
+ GetViewData()->InsertTab( nNewTab );
+ SetTabNo( nNewTab, sal_True );
+
+ aDestRange = ScRange( 0, 0, nNewTab );
+ }
+
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor(
+ aDestRange.aStart.Col(), aDestRange.aStart.Row(), aDestRange.aStart.Tab() );
+
+ ScDPObject aObj( rSource );
+ aObj.SetOutRange( aDestRange );
+ if ( pDPObj && !rData.GetExistingDimensionData() )
+ {
+ // copy dimension data from old object - lost in the dialog
+ //! change the dialog to keep the dimension data
+
+ ScDPSaveData aNewData( rData );
+ const ScDPSaveData* pOldData = pDPObj->GetSaveData();
+ if ( pOldData )
+ {
+ const ScDPDimensionSaveData* pDimSave = pOldData->GetExistingDimensionData();
+ aNewData.SetDimensionData( pDimSave );
+ }
+ aObj.SetSaveData( aNewData );
+ }
+ else
+ aObj.SetSaveData( rData );
+
+ sal_Bool bAllowMove = ( pDPObj != NULL ); // allow re-positioning when editing existing table
+
+ ScDBDocFunc aFunc( *pDocSh );
+ bool bSuccess = aFunc.DataPilotUpdate( pDPObj, &aObj, sal_True, sal_False, bAllowMove );
+
+ CursorPosChanged(); // shells may be switched
+
+ if ( bNewTable )
+ {
+ pDocSh->PostPaintExtras();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ }
+
+ return bSuccess;
+}
+
+void ScDBFunc::DeletePivotTable()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(),
+ GetViewData()->GetTabNo() );
+ if ( pDPObj )
+ {
+ ScDBDocFunc aFunc( *pDocSh );
+ aFunc.DataPilotUpdate( pDPObj, NULL, sal_True, sal_False );
+ CursorPosChanged(); // shells may be switched
+ }
+ else
+ ErrorMessage(STR_PIVOT_NOTFOUND);
+}
+sal_uLong RefreshDPObject( ScDPObject *pDPObj, ScDocument *pDoc, ScDocShell *pDocSh, sal_Bool bRecord, sal_Bool bApi )
+{
+ if( !pDPObj )
+ return STR_PIVOT_NOTFOUND;
+
+ if ( pDocSh && !pDoc )
+ pDoc = pDocSh->GetDocument();
+
+ if( !pDoc )
+ return static_cast<sal_uLong>(-1);
+
+ if( !pDocSh && ( pDocSh = PTR_CAST( ScDocShell, pDoc->GetDocumentShell() ) ) == NULL )
+ return static_cast<sal_uLong>(-1);
+
+ if( sal_uLong nErrId = pDPObj->RefreshCache() )
+ return nErrId;
+ else if ( nErrId == 0 )
+ {
+ //Refresh all dpobjects
+ ScDPCollection* pDPCollection = pDoc->GetDPCollection();
+ sal_uInt16 nCount = pDPCollection->GetCount();
+ for (sal_uInt16 i=0; i<nCount; i++)
+ {
+ if ( (*pDPCollection)[i]->GetCacheId() == pDPObj->GetCacheId() )
+ {
+ ScDBDocFunc aFunc( * pDocSh );
+ if ( !aFunc.DataPilotUpdate( (*pDPCollection)[i], (*pDPCollection)[i], bRecord, bApi ) )
+ break;
+ }
+ }
+
+ return nErrId;
+ }
+
+ return 0U;
+}
+
+sal_uLong ScDBFunc::RecalcPivotTable()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ // old pivot not used any more
+
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(),
+ GetViewData()->GetTabNo() );
+ if ( pDPObj )
+ {
+ // Wang Xu Ming -- 2009-6-17
+ // DataPilot Migration
+ //ScDBDocFunc aFunc( *pDocSh );
+ //aFunc.DataPilotUpdate( pDPObj, pDPObj, sal_True, sal_False );
+ //CursorPosChanged(); // shells may be switched
+ sal_uLong nErrId = RefreshDPObject( pDPObj, pDoc, pDocSh, sal_True, sal_False );//pDPObj->RefreshCache();
+ if ( nErrId == 0 )
+ {
+ // There is no undo for the refresh of the cache table, but the undo history for cell changes
+ // remains valid and should be preserved, so the history isn't cleared here.
+ //GetViewData()->GetDocShell()->GetUndoManager()->Clear();
+ }
+ else if (nErrId <= USHRT_MAX)
+ ErrorMessage(static_cast<sal_uInt16>(nErrId));
+ return nErrId;
+ // End Comments
+ }
+ else
+ ErrorMessage(STR_PIVOT_NOTFOUND);
+ return STR_PIVOT_NOTFOUND;
+}
+
+void ScDBFunc::GetSelectedMemberList( ScStrCollection& rEntries, long& rDimension )
+{
+ ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ if ( !pDPObj )
+ return;
+
+ long nStartDimension = -1;
+ long nStartHierarchy = -1;
+ long nStartLevel = -1;
+
+ ScRangeListRef xRanges;
+ GetViewData()->GetMultiArea( xRanges ); // incl. cursor if nothing is selected
+ sal_uLong nRangeCount = xRanges->Count();
+ sal_Bool bContinue = sal_True;
+
+ for (sal_uLong nRangePos=0; nRangePos<nRangeCount && bContinue; nRangePos++)
+ {
+ ScRange aRange = *xRanges->GetObject(nRangePos);
+ SCCOL nStartCol = aRange.aStart.Col();
+ SCROW nStartRow = aRange.aStart.Row();
+ SCCOL nEndCol = aRange.aEnd.Col();
+ SCROW nEndRow = aRange.aEnd.Row();
+ SCTAB nTab = aRange.aStart.Tab();
+
+ for (SCROW nRow=nStartRow; nRow<=nEndRow && bContinue; nRow++)
+ for (SCCOL nCol=nStartCol; nCol<=nEndCol && bContinue; nCol++)
+ {
+ sheet::DataPilotTableHeaderData aData;
+ pDPObj->GetHeaderPositionData(ScAddress(nCol, nRow, nTab), aData);
+ if ( aData.Dimension < 0 )
+ bContinue = sal_False; // not part of any dimension
+ else
+ {
+ if ( nStartDimension < 0 ) // first member?
+ {
+ nStartDimension = aData.Dimension;
+ nStartHierarchy = aData.Hierarchy;
+ nStartLevel = aData.Level;
+ }
+ if ( aData.Dimension != nStartDimension ||
+ aData.Hierarchy != nStartHierarchy ||
+ aData.Level != nStartLevel )
+ {
+ bContinue = sal_False; // cannot mix dimensions
+ }
+ }
+ if ( bContinue )
+ {
+ // accept any part of a member description, also subtotals,
+ // but don't stop if empty parts are contained
+ if ( aData.Flags & sheet::MemberResultFlags::HASMEMBER )
+ {
+ StrData* pNew = new StrData( aData.MemberName );
+ if ( !rEntries.Insert( pNew ) )
+ delete pNew;
+ }
+ }
+ }
+ }
+
+ rDimension = nStartDimension; // dimension from which the found members came
+ if (!bContinue)
+ rEntries.FreeAll(); // remove all if not valid
+}
+
+sal_Bool ScDBFunc::HasSelectionForDateGroup( ScDPNumGroupInfo& rOldInfo, sal_Int32& rParts )
+{
+ // determine if the date group dialog has to be shown for the current selection
+
+ sal_Bool bFound = sal_False;
+
+ SCCOL nCurX = GetViewData()->GetCurX();
+ SCROW nCurY = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor( nCurX, nCurY, nTab );
+ if ( pDPObj )
+ {
+ ScStrCollection aEntries;
+ long nSelectDimension = -1;
+ GetSelectedMemberList( aEntries, nSelectDimension );
+
+ if ( aEntries.GetCount() > 0 )
+ {
+ sal_Bool bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout );
+ String aBaseDimName( aDimName );
+
+ sal_Bool bInGroupDim = sal_False;
+ sal_Bool bFoundParts = sal_False;
+
+ ScDPDimensionSaveData* pDimData =
+ const_cast<ScDPDimensionSaveData*>( pDPObj->GetSaveData()->GetExistingDimensionData() );
+ if ( pDimData )
+ {
+ const ScDPSaveNumGroupDimension* pNumGroupDim = pDimData->GetNumGroupDim( aDimName );
+ const ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDim( aDimName );
+ if ( pNumGroupDim )
+ {
+ // existing num group dimension
+
+ if ( pNumGroupDim->GetDatePart() != 0 )
+ {
+ // dimension has date info -> edit settings of this dimension
+ // (parts are collected below)
+
+ rOldInfo = pNumGroupDim->GetDateInfo();
+ bFound = sal_True;
+ }
+ else if ( pNumGroupDim->GetInfo().DateValues )
+ {
+ // Numerical grouping with DateValues flag is used for grouping
+ // of days with a "Number of days" value.
+
+ rOldInfo = pNumGroupDim->GetInfo();
+ rParts = com::sun::star::sheet::DataPilotFieldGroupBy::DAYS; // not found in CollectDateParts
+ bFoundParts = sal_True;
+ bFound = sal_True;
+ }
+ bInGroupDim = sal_True;
+ }
+ else if ( pGroupDim )
+ {
+ // existing additional group dimension
+
+ if ( pGroupDim->GetDatePart() != 0 )
+ {
+ // dimension has date info -> edit settings of this dimension
+ // (parts are collected below)
+
+ rOldInfo = pGroupDim->GetDateInfo();
+ aBaseDimName = pGroupDim->GetSourceDimName();
+ bFound = sal_True;
+ }
+ bInGroupDim = sal_True;
+ }
+ }
+ if ( bFound && !bFoundParts )
+ {
+ // collect date parts from all group dimensions
+ rParts = pDimData->CollectDateParts( aBaseDimName );
+ }
+ if ( !bFound && !bInGroupDim )
+ {
+ // create new date group dimensions if the selection is a single cell
+ // in a normal dimension with date content
+
+ ScRange aSelRange;
+ if ( (GetViewData()->GetSimpleArea( aSelRange ) == SC_MARK_SIMPLE) &&
+ aSelRange.aStart == aSelRange.aEnd )
+ {
+ SCCOL nSelCol = aSelRange.aStart.Col();
+ SCROW nSelRow = aSelRange.aStart.Row();
+ SCTAB nSelTab = aSelRange.aStart.Tab();
+ if ( pDoc->HasValueData( nSelCol, nSelRow, nSelTab ) )
+ {
+ sal_uLong nIndex = static_cast<const SfxUInt32Item*>(pDoc->GetAttr(
+ nSelCol, nSelRow, nSelTab, ATTR_VALUE_FORMAT))->GetValue();
+ short nType = pDoc->GetFormatTable()->GetType(nIndex);
+ if ( nType == NUMBERFORMAT_DATE || nType == NUMBERFORMAT_TIME || nType == NUMBERFORMAT_DATETIME )
+ {
+ bFound = sal_True;
+ // use currently selected value for automatic limits
+ if( rOldInfo.AutoStart )
+ rOldInfo.Start = pDoc->GetValue( aSelRange.aStart );
+ if( rOldInfo.AutoEnd )
+ rOldInfo.End = pDoc->GetValue( aSelRange.aStart );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return bFound;
+}
+
+sal_Bool ScDBFunc::HasSelectionForNumGroup( ScDPNumGroupInfo& rOldInfo )
+{
+ // determine if the numeric group dialog has to be shown for the current selection
+
+ sal_Bool bFound = sal_False;
+
+ SCCOL nCurX = GetViewData()->GetCurX();
+ SCROW nCurY = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor( nCurX, nCurY, nTab );
+ if ( pDPObj )
+ {
+ ScStrCollection aEntries;
+ long nSelectDimension = -1;
+ GetSelectedMemberList( aEntries, nSelectDimension );
+
+ if ( aEntries.GetCount() > 0 )
+ {
+ sal_Bool bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout );
+
+ sal_Bool bInGroupDim = sal_False;
+
+ ScDPDimensionSaveData* pDimData =
+ const_cast<ScDPDimensionSaveData*>( pDPObj->GetSaveData()->GetExistingDimensionData() );
+ if ( pDimData )
+ {
+ const ScDPSaveNumGroupDimension* pNumGroupDim = pDimData->GetNumGroupDim( aDimName );
+ if ( pNumGroupDim )
+ {
+ // existing num group dimension
+ // -> edit settings of this dimension
+
+ rOldInfo = pNumGroupDim->GetInfo();
+ bFound = sal_True;
+ }
+ else if ( pDimData->GetNamedGroupDim( aDimName ) )
+ bInGroupDim = sal_True; // in a group dimension
+ }
+ if ( !bFound && !bInGroupDim )
+ {
+ // create a new num group dimension if the selection is a single cell
+ // in a normal dimension with numeric content
+
+ ScRange aSelRange;
+ if ( (GetViewData()->GetSimpleArea( aSelRange ) == SC_MARK_SIMPLE) &&
+ aSelRange.aStart == aSelRange.aEnd )
+ {
+ if ( pDoc->HasValueData( aSelRange.aStart.Col(), aSelRange.aStart.Row(),
+ aSelRange.aStart.Tab() ) )
+ {
+ bFound = sal_True;
+ // use currently selected value for automatic limits
+ if( rOldInfo.AutoStart )
+ rOldInfo.Start = pDoc->GetValue( aSelRange.aStart );
+ if( rOldInfo.AutoEnd )
+ rOldInfo.End = pDoc->GetValue( aSelRange.aStart );
+ }
+ }
+ }
+ }
+ }
+
+ return bFound;
+}
+
+void ScDBFunc::DateGroupDataPilot( const ScDPNumGroupInfo& rInfo, sal_Int32 nParts )
+{
+ ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ if ( pDPObj )
+ {
+ ScStrCollection aEntries;
+ long nSelectDimension = -1;
+ GetSelectedMemberList( aEntries, nSelectDimension );
+
+ if ( aEntries.GetCount() > 0 )
+ {
+ sal_Bool bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout );
+
+ ScDPSaveData aData( *pDPObj->GetSaveData() );
+ ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); // created if not there
+
+ // find original base
+ String aBaseDimName = aDimName;
+ if( const ScDPSaveGroupDimension* pBaseGroupDim = pDimData->GetNamedGroupDim( aDimName ) )
+ aBaseDimName = pBaseGroupDim->GetSourceDimName();
+
+ // remove all existing parts (the grouping is built completely new)
+
+ /* Remove numeric group dimension (exists once at most). No need
+ to delete anything in save data (grouping was done inplace in
+ an existing base dimension). */
+ pDimData->RemoveNumGroupDimension( aBaseDimName );
+
+ /* Remove named group dimension(s). Collect deleted dimension
+ names which may be reused while recreating the groups.
+ Dimensions have to be removed from dimension save data and from
+ save data too. */
+ std::vector< String > aDeletedNames;
+ const ScDPSaveGroupDimension* pExistingGroup = pDimData->GetGroupDimForBase( aBaseDimName );
+ while ( pExistingGroup )
+ {
+ String aGroupDimName = pExistingGroup->GetGroupDimName();
+ pDimData->RemoveGroupDimension( aGroupDimName ); // pExistingGroup is deleted
+
+ // also remove SaveData settings for the dimension that no longer exists
+ aData.RemoveDimensionByName( aGroupDimName );
+
+ /* The name can be used for the new group dimensions, although
+ it is still in use with the DataPilotSource. */
+ aDeletedNames.push_back( aGroupDimName );
+
+ // see if there are more group dimensions
+ pExistingGroup = pDimData->GetGroupDimForBase( aBaseDimName );
+
+ if ( pExistingGroup && pExistingGroup->GetGroupDimName() == aGroupDimName )
+ {
+ // still get the same group dimension?
+ DBG_ERROR("couldn't remove group dimension");
+ pExistingGroup = NULL; // avoid endless loop
+ }
+ }
+
+ if ( nParts )
+ {
+ // create date group dimensions
+
+ ScDPNumGroupInfo aEmpty;
+ bool bFirst = true;
+ sal_Int32 nMask = 1;
+ for (sal_uInt16 nBit=0; nBit<32; nBit++)
+ {
+ if ( nParts & nMask )
+ {
+ if ( bFirst )
+ {
+ // innermost part: create NumGroupDimension (replacing original values)
+ // Dimension name is left unchanged
+
+ if ( (nParts == sheet::DataPilotFieldGroupBy::DAYS) && (rInfo.Step >= 1.0) )
+ {
+ // only days, and a step value specified: use numerical grouping
+ // with DateValues flag, not date grouping
+
+ ScDPNumGroupInfo aNumInfo( rInfo );
+ aNumInfo.DateValues = sal_True;
+
+ ScDPSaveNumGroupDimension aNumGroupDim( aBaseDimName, aNumInfo );
+ pDimData->AddNumGroupDimension( aNumGroupDim );
+ }
+ else
+ {
+ ScDPSaveNumGroupDimension aNumGroupDim( aBaseDimName, rInfo, nMask );
+ pDimData->AddNumGroupDimension( aNumGroupDim );
+ }
+
+ bFirst = false;
+ }
+ else
+ {
+ // additional parts: create GroupDimension (shown as additional dimensions)
+ String aGroupDimName = pDimData->CreateDateGroupDimName( nMask, *pDPObj, true, &aDeletedNames );
+ ScDPSaveGroupDimension aGroupDim( aBaseDimName, aGroupDimName );
+ aGroupDim.SetDateInfo( rInfo, nMask );
+ pDimData->AddGroupDimension( aGroupDim );
+
+ // set orientation
+ ScDPSaveDimension* pSaveDimension = aData.GetDimensionByName( aGroupDimName );
+ if ( pSaveDimension->GetOrientation() == sheet::DataPilotFieldOrientation_HIDDEN )
+ {
+ ScDPSaveDimension* pOldDimension = aData.GetDimensionByName( aBaseDimName );
+ pSaveDimension->SetOrientation( pOldDimension->GetOrientation() );
+ long nPosition = 0; //! before (immediate) base
+ aData.SetPosition( pSaveDimension, nPosition );
+ }
+ }
+ }
+ nMask *= 2;
+ }
+ }
+
+ // apply changes
+ ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
+ ScDPObject* pNewObj = new ScDPObject( *pDPObj );
+ pNewObj->SetSaveData( aData );
+ aFunc.DataPilotUpdate( pDPObj, pNewObj, sal_True, sal_False );
+ delete pNewObj;
+
+ // unmark cell selection
+ Unmark();
+ }
+ }
+}
+
+void ScDBFunc::NumGroupDataPilot( const ScDPNumGroupInfo& rInfo )
+{
+ ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ if ( pDPObj )
+ {
+ ScStrCollection aEntries;
+ long nSelectDimension = -1;
+ GetSelectedMemberList( aEntries, nSelectDimension );
+
+ if ( aEntries.GetCount() > 0 )
+ {
+ sal_Bool bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout );
+
+ ScDPSaveData aData( *pDPObj->GetSaveData() );
+ ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); // created if not there
+
+ ScDPSaveNumGroupDimension* pExisting = pDimData->GetNumGroupDimAcc( aDimName );
+ if ( pExisting )
+ {
+ // modify existing group dimension
+ pExisting->SetGroupInfo( rInfo );
+ }
+ else
+ {
+ // create new group dimension
+ ScDPSaveNumGroupDimension aNumGroupDim( aDimName, rInfo );
+ pDimData->AddNumGroupDimension( aNumGroupDim );
+ }
+
+ // apply changes
+ ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
+ ScDPObject* pNewObj = new ScDPObject( *pDPObj );
+ pNewObj->SetSaveData( aData );
+ aFunc.DataPilotUpdate( pDPObj, pNewObj, sal_True, sal_False );
+ delete pNewObj;
+
+ // unmark cell selection
+ Unmark();
+ }
+ }
+}
+
+void ScDBFunc::GroupDataPilot()
+{
+ ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ if ( pDPObj )
+ {
+ ScStrCollection aEntries;
+ long nSelectDimension = -1;
+ GetSelectedMemberList( aEntries, nSelectDimension );
+
+ if ( aEntries.GetCount() > 0 )
+ {
+ sal_Bool bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout );
+
+ ScDPSaveData aData( *pDPObj->GetSaveData() );
+ ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); // created if not there
+
+ // find original base
+ String aBaseDimName( aDimName );
+ const ScDPSaveGroupDimension* pBaseGroupDim = pDimData->GetNamedGroupDim( aDimName );
+ if ( pBaseGroupDim )
+ {
+ // any entry's SourceDimName is the original base
+ aBaseDimName = pBaseGroupDim->GetSourceDimName();
+ }
+
+ // find existing group dimension
+ // (using the selected dim, can be intermediate group dim)
+ ScDPSaveGroupDimension* pGroupDimension = pDimData->GetGroupDimAccForBase( aDimName );
+
+ // remove the selected items from their groups
+ // (empty groups are removed, too)
+ sal_uInt16 nEntryCount = aEntries.GetCount();
+ sal_uInt16 nEntry;
+ if ( pGroupDimension )
+ {
+ for (nEntry=0; nEntry<nEntryCount; nEntry++)
+ {
+ String aEntryName = aEntries[nEntry]->GetString();
+ if ( pBaseGroupDim )
+ {
+ // for each selected (intermediate) group, remove all its items
+ // (same logic as for adding, below)
+ const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName );
+ if ( pBaseGroup )
+ pBaseGroup->RemoveElementsFromGroups( *pGroupDimension ); // remove all elements
+ else
+ pGroupDimension->RemoveFromGroups( aEntryName );
+ }
+ else
+ pGroupDimension->RemoveFromGroups( aEntryName );
+ }
+ }
+
+ ScDPSaveGroupDimension* pNewGroupDim = NULL;
+ if ( !pGroupDimension )
+ {
+ // create a new group dimension
+ String aGroupDimName = pDimData->CreateGroupDimName( aBaseDimName, *pDPObj, false, NULL );
+ pNewGroupDim = new ScDPSaveGroupDimension( aBaseDimName, aGroupDimName );
+
+ pGroupDimension = pNewGroupDim; // make changes to the new dim if none existed
+
+ if ( pBaseGroupDim )
+ {
+ // If it's a higher-order group dimension, pre-allocate groups for all
+ // non-selected original groups, so the individual base members aren't
+ // used for automatic groups (this would make the original groups hard
+ // to find).
+ //! Also do this when removing groups?
+ //! Handle this case dynamically with automatic groups?
+
+ long nGroupCount = pBaseGroupDim->GetGroupCount();
+ for ( long nGroup = 0; nGroup < nGroupCount; nGroup++ )
+ {
+ const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetGroupByIndex( nGroup );
+
+ StrData aStrData( pBaseGroup->GetGroupName() );
+ sal_uInt16 nCollIndex;
+ if ( !aEntries.Search( &aStrData, nCollIndex ) ) //! ignore case?
+ {
+ // add an additional group for each item that is not in the selection
+ ScDPSaveGroupItem aGroup( pBaseGroup->GetGroupName() );
+ aGroup.AddElementsFromGroup( *pBaseGroup );
+ pGroupDimension->AddGroupItem( aGroup );
+ }
+ }
+ }
+ }
+ String aGroupDimName = pGroupDimension->GetGroupDimName();
+
+ //! localized prefix string
+ String aGroupName = pGroupDimension->CreateGroupName( String::CreateFromAscii("Group") );
+ ScDPSaveGroupItem aGroup( aGroupName );
+ for (nEntry=0; nEntry<nEntryCount; nEntry++)
+ {
+ String aEntryName = aEntries[nEntry]->GetString();
+ if ( pBaseGroupDim )
+ {
+ // for each selected (intermediate) group, add all its items
+ const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName );
+ if ( pBaseGroup )
+ aGroup.AddElementsFromGroup( *pBaseGroup );
+ else
+ aGroup.AddElement( aEntryName ); // no group found -> automatic group, add the item itself
+ }
+ else
+ aGroup.AddElement( aEntryName ); // no group dimension, add all items directly
+ }
+
+ pGroupDimension->AddGroupItem( aGroup );
+
+ if ( pNewGroupDim )
+ {
+ pDimData->AddGroupDimension( *pNewGroupDim );
+ delete pNewGroupDim; // AddGroupDimension copies the object
+ // don't access pGroupDimension after here
+ }
+ pGroupDimension = pNewGroupDim = NULL;
+
+ // set orientation
+ ScDPSaveDimension* pSaveDimension = aData.GetDimensionByName( aGroupDimName );
+ if ( pSaveDimension->GetOrientation() == sheet::DataPilotFieldOrientation_HIDDEN )
+ {
+ ScDPSaveDimension* pOldDimension = aData.GetDimensionByName( aDimName );
+ pSaveDimension->SetOrientation( pOldDimension->GetOrientation() );
+ long nPosition = 0; //! before (immediate) base
+ aData.SetPosition( pSaveDimension, nPosition );
+ }
+
+ // apply changes
+ ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
+ ScDPObject* pNewObj = new ScDPObject( *pDPObj );
+ pNewObj->SetSaveData( aData );
+ aFunc.DataPilotUpdate( pDPObj, pNewObj, sal_True, sal_False );
+ delete pNewObj;
+
+ // unmark cell selection
+ Unmark();
+ }
+ }
+}
+
+void ScDBFunc::UngroupDataPilot()
+{
+ ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ if ( pDPObj )
+ {
+ ScStrCollection aEntries;
+ long nSelectDimension = -1;
+ GetSelectedMemberList( aEntries, nSelectDimension );
+
+ if ( aEntries.GetCount() > 0 )
+ {
+ sal_Bool bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout );
+
+ ScDPSaveData aData( *pDPObj->GetSaveData() );
+ ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); // created if not there
+ //! test first if DimensionData exists?
+
+ sal_Bool bApply = sal_False;
+
+ ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aDimName );
+ const ScDPSaveNumGroupDimension* pNumGroupDim = pDimData->GetNumGroupDim( aDimName );
+ if ( ( pGroupDim && pGroupDim->GetDatePart() != 0 ) ||
+ ( pNumGroupDim && pNumGroupDim->GetDatePart() != 0 ) )
+ {
+ // Date grouping: need to remove all affected group dimensions.
+ // This is done using DateGroupDataPilot with nParts=0.
+
+ DateGroupDataPilot( ScDPNumGroupInfo(), 0 );
+ // bApply remains FALSE
+ // dimension pointers become invalid
+ }
+ else if ( pGroupDim )
+ {
+ sal_uInt16 nEntryCount = aEntries.GetCount();
+ for (sal_uInt16 nEntry=0; nEntry<nEntryCount; nEntry++)
+ {
+ String aEntryName = aEntries[nEntry]->GetString();
+ pGroupDim->RemoveGroup( aEntryName );
+ }
+ // remove group dimension if empty
+ bool bEmptyDim = pGroupDim->IsEmpty();
+ if ( !bEmptyDim )
+ {
+ // If all remaining groups in the dimension aren't shown, remove
+ // the dimension too, as if it was completely empty.
+ ScStrCollection aVisibleEntries;
+ pDPObj->GetMemberResultNames( aVisibleEntries, nSelectDimension );
+ bEmptyDim = pGroupDim->HasOnlyHidden( aVisibleEntries );
+ }
+ if ( bEmptyDim )
+ {
+ pDimData->RemoveGroupDimension( aDimName ); // pGroupDim is deleted
+
+ // also remove SaveData settings for the dimension that no longer exists
+ aData.RemoveDimensionByName( aDimName );
+ }
+ bApply = sal_True;
+ }
+ else if ( pNumGroupDim )
+ {
+ // remove the numerical grouping
+ pDimData->RemoveNumGroupDimension( aDimName );
+ // SaveData settings can remain unchanged - the same dimension still exists
+ bApply = sal_True;
+ }
+
+ if ( bApply )
+ {
+ // apply changes
+ ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
+ ScDPObject* pNewObj = new ScDPObject( *pDPObj );
+ pNewObj->SetSaveData( aData );
+ aFunc.DataPilotUpdate( pDPObj, pNewObj, sal_True, sal_False );
+ delete pNewObj;
+
+ // unmark cell selection
+ Unmark();
+ }
+ }
+ }
+}
+
+static OUString lcl_replaceMemberNameInSubtotal(const OUString& rSubtotal, const OUString& rMemberName)
+{
+ sal_Int32 n = rSubtotal.getLength();
+ const sal_Unicode* p = rSubtotal.getStr();
+ OUStringBuffer aBuf, aWordBuf;
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ sal_Unicode c = p[i];
+ if (c == sal_Unicode(' '))
+ {
+ OUString aWord = aWordBuf.makeStringAndClear();
+ if (aWord.equals(rMemberName))
+ aBuf.append(sal_Unicode('?'));
+ else
+ aBuf.append(aWord);
+ aBuf.append(c);
+ }
+ else if (c == sal_Unicode('\\'))
+ {
+ // Escape a backslash character.
+ aWordBuf.append(c);
+ aWordBuf.append(c);
+ }
+ else if (c == sal_Unicode('?'))
+ {
+ // A literal '?' must be escaped with a backslash ('\');
+ aWordBuf.append(sal_Unicode('\\'));
+ aWordBuf.append(c);
+ }
+ else
+ aWordBuf.append(c);
+ }
+
+ if (aWordBuf.getLength() > 0)
+ {
+ OUString aWord = aWordBuf.makeStringAndClear();
+ if (aWord.equals(rMemberName))
+ aBuf.append(sal_Unicode('?'));
+ else
+ aBuf.append(aWord);
+ }
+
+ return aBuf.makeStringAndClear();
+}
+
+void ScDBFunc::DataPilotInput( const ScAddress& rPos, const String& rString )
+{
+ using namespace ::com::sun::star::sheet;
+
+ String aNewName( rString );
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor( rPos.Col(), rPos.Row(), rPos.Tab() );
+ if (!pDPObj)
+ return;
+
+ String aOldText;
+ pDoc->GetString( rPos.Col(), rPos.Row(), rPos.Tab(), aOldText );
+
+ if ( aOldText == rString )
+ {
+ // nothing to do: silently exit
+ return;
+ }
+
+ sal_uInt16 nErrorId = 0;
+
+ pDPObj->BuildAllDimensionMembers();
+ ScDPSaveData aData( *pDPObj->GetSaveData() );
+ sal_Bool bChange = sal_False;
+
+ sal_uInt16 nOrient = DataPilotFieldOrientation_HIDDEN;
+ long nField = pDPObj->GetHeaderDim( rPos, nOrient );
+ if ( nField >= 0 )
+ {
+ // changing a field title
+ if ( aData.GetExistingDimensionData() )
+ {
+ // only group dimensions can be renamed
+
+ ScDPDimensionSaveData* pDimData = aData.GetDimensionData();
+ ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aOldText );
+ if ( pGroupDim )
+ {
+ // valid name: not empty, no existing dimension (group or other)
+ if ( rString.Len() && !pDPObj->IsDimNameInUse(rString) )
+ {
+ pGroupDim->Rename( aNewName );
+
+ // also rename in SaveData to preserve the field settings
+ ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aOldText );
+ pSaveDim->SetName( aNewName );
+
+ bChange = sal_True;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ else if (nOrient == DataPilotFieldOrientation_COLUMN || nOrient == DataPilotFieldOrientation_ROW)
+ {
+ sal_Bool bDataLayout = false;
+ String aDimName = pDPObj->GetDimName(nField, bDataLayout);
+ ScDPSaveDimension* pDim = bDataLayout ? aData.GetDataLayoutDimension() : aData.GetDimensionByName(aDimName);
+ if (pDim)
+ {
+ if (rString.Len())
+ {
+ if (rString.EqualsIgnoreCaseAscii(aDimName))
+ {
+ pDim->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDPObj->IsDimNameInUse(rString))
+ {
+ pDim->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ }
+ else if (pDPObj->IsDataDescriptionCell(rPos))
+ {
+ // There is only one data dimension.
+ ScDPSaveDimension* pDim = aData.GetFirstDimension(sheet::DataPilotFieldOrientation_DATA);
+ if (pDim)
+ {
+ if (rString.Len())
+ {
+ if (rString.EqualsIgnoreCaseAscii(pDim->GetName()))
+ {
+ pDim->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDPObj->IsDimNameInUse(rString))
+ {
+ pDim->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ else
+ {
+ // This is not a field header.
+ sheet::DataPilotTableHeaderData aPosData;
+ pDPObj->GetHeaderPositionData(rPos, aPosData);
+
+ if ( (aPosData.Flags & MemberResultFlags::HASMEMBER) && aOldText.Len() )
+ {
+ if ( aData.GetExistingDimensionData() && !(aPosData.Flags & MemberResultFlags::SUBTOTAL))
+ {
+ sal_Bool bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( aPosData.Dimension, bIsDataLayout );
+
+ ScDPDimensionSaveData* pDimData = aData.GetDimensionData();
+ ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aDimName );
+ if ( pGroupDim )
+ {
+ // valid name: not empty, no existing group in this dimension
+ //! ignore case?
+ if ( aNewName.Len() && !pGroupDim->GetNamedGroup( aNewName ) )
+ {
+ ScDPSaveGroupItem* pGroup = pGroupDim->GetNamedGroupAcc( aOldText );
+ if ( pGroup )
+ pGroup->Rename( aNewName ); // rename the existing group
+ else
+ {
+ // create a new group to replace the automatic group
+ ScDPSaveGroupItem aGroup( aNewName );
+ aGroup.AddElement( aOldText );
+ pGroupDim->AddGroupItem( aGroup );
+ }
+
+ // in both cases also adjust savedata, to preserve member settings (show details)
+ ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aDimName );
+ ScDPSaveMember* pSaveMember = pSaveDim->GetExistingMemberByName( aOldText );
+ if ( pSaveMember )
+ pSaveMember->SetName( aNewName );
+
+ bChange = sal_True;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ else if ((aPosData.Flags & MemberResultFlags::GRANDTOTAL))
+ {
+ aData.SetGrandTotalName(rString);
+ bChange = true;
+ }
+ else if (aPosData.Dimension >= 0 && aPosData.MemberName.getLength() > 0)
+ {
+ sal_Bool bDataLayout = false;
+ String aDimName = pDPObj->GetDimName(static_cast<long>(aPosData.Dimension), bDataLayout);
+ if (bDataLayout)
+ {
+ // data dimension
+ do
+ {
+ if ((aPosData.Flags & MemberResultFlags::SUBTOTAL))
+ break;
+
+ ScDPSaveDimension* pDim = aData.GetDimensionByName(aPosData.MemberName);
+ if (!pDim)
+ break;
+
+ if (!rString.Len())
+ {
+ nErrorId = STR_INVALIDNAME;
+ break;
+ }
+
+ if (aPosData.MemberName.equalsIgnoreAsciiCase(rString))
+ {
+ pDim->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDPObj->IsDimNameInUse(rString))
+ {
+ pDim->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ while (false);
+ }
+ else
+ {
+ // field member
+ do
+ {
+ ScDPSaveDimension* pDim = aData.GetDimensionByName(aDimName);
+ if (!pDim)
+ break;
+
+ ScDPSaveMember* pMem = pDim->GetExistingMemberByName(aPosData.MemberName);
+ if (!pMem)
+ break;
+
+ if ((aPosData.Flags & MemberResultFlags::SUBTOTAL))
+ {
+ // Change subtotal only when the table has one data dimension.
+ if (aData.GetDataDimensionCount() > 1)
+ break;
+
+ // display name for subtotal is allowed only if the subtotal type is 'Automatic'.
+ if (pDim->GetSubTotalsCount() != 1)
+ break;
+
+ if (pDim->GetSubTotalFunc(0) != sheet::GeneralFunction_AUTO)
+ break;
+
+ const OUString* pLayoutName = pMem->GetLayoutName();
+ String aMemberName;
+ if (pLayoutName)
+ aMemberName = *pLayoutName;
+ else
+ aMemberName = aPosData.MemberName;
+
+ String aNew = lcl_replaceMemberNameInSubtotal(rString, aMemberName);
+ pDim->SetSubtotalName(aNew);
+ bChange = true;
+ }
+ else
+ {
+ // Check to make sure the member name isn't
+ // already used.
+ if (rString.Len())
+ {
+ if (rString.EqualsIgnoreCaseAscii(pMem->GetName()))
+ {
+ pMem->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDim->IsMemberNameInUse(rString))
+ {
+ pMem->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ while (false);
+ }
+ }
+ }
+ }
+
+ if ( bChange )
+ {
+ // apply changes
+ ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
+ ScDPObject* pNewObj = new ScDPObject( *pDPObj );
+ pNewObj->SetSaveData( aData );
+ aFunc.DataPilotUpdate( pDPObj, pNewObj, sal_True, sal_False );
+ delete pNewObj;
+ }
+ else
+ {
+ if ( !nErrorId )
+ nErrorId = STR_ERR_DATAPILOT_INPUT;
+ ErrorMessage( nErrorId );
+ }
+}
+
+void lcl_MoveToEnd( ScDPSaveDimension& rDim, const String& rItemName )
+{
+ ScDPSaveMember* pNewMember = NULL;
+ const ScDPSaveMember* pOldMember = rDim.GetExistingMemberByName( rItemName );
+ if ( pOldMember )
+ pNewMember = new ScDPSaveMember( *pOldMember );
+ else
+ pNewMember = new ScDPSaveMember( rItemName );
+ rDim.AddMember( pNewMember );
+ // AddMember takes ownership of the new pointer,
+ // puts it to the end of the list even if it was in the list before.
+}
+
+struct ScOUStringCollate
+{
+ CollatorWrapper* mpCollator;
+
+ ScOUStringCollate(CollatorWrapper* pColl) : mpCollator(pColl) {}
+
+ bool operator()(const rtl::OUString& rStr1, const rtl::OUString& rStr2) const
+ {
+ return ( mpCollator->compareString(rStr1, rStr2) < 0 );
+ }
+};
+
+bool ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16* pUserListId )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor(rPos.Col(), rPos.Row(), rPos.Tab());
+ if (!pDPObj)
+ return false;
+
+ // We need to run this to get all members later.
+ if ( pUserListId )
+ pDPObj->BuildAllDimensionMembers();
+
+ sal_uInt16 nOrientation;
+ long nDimIndex = pDPObj->GetHeaderDim(rPos, nOrientation);
+ if (nDimIndex < 0)
+ // Invalid dimension index. Bail out.
+ return false;
+
+ sal_Bool bDataLayout;
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ if (!pSaveData)
+ return false;
+
+ ScDPSaveData aNewSaveData(*pSaveData);
+ String aDimName = pDPObj->GetDimName(nDimIndex, bDataLayout);
+ ScDPSaveDimension* pSaveDim = aNewSaveData.GetDimensionByName(aDimName);
+ if (!pSaveDim)
+ return false;
+
+ // manual evaluation of sort order is only needed if a user list id is given
+ if ( pUserListId )
+ {
+ typedef ScDPSaveDimension::MemberList MemList;
+ const MemList& rDimMembers = pSaveDim->GetMembers();
+ list<OUString> aMembers;
+ hash_set<OUString, ::rtl::OUStringHash> aMemberSet;
+ size_t nMemberCount = 0;
+ for (MemList::const_iterator itr = rDimMembers.begin(), itrEnd = rDimMembers.end();
+ itr != itrEnd; ++itr)
+ {
+ ScDPSaveMember* pMem = *itr;
+ aMembers.push_back(pMem->GetName());
+ aMemberSet.insert(pMem->GetName());
+ ++nMemberCount;
+ }
+
+ // Sort the member list in ascending order.
+ ScOUStringCollate aCollate( ScGlobal::GetCollator() );
+ aMembers.sort(aCollate);
+
+ // Collect and rank those custom sort strings that also exist in the member name list.
+
+ typedef hash_map<OUString, sal_uInt16, OUStringHash> UserSortMap;
+ UserSortMap aSubStrs;
+ sal_uInt16 nSubCount = 0;
+ if (pUserListId)
+ {
+ ScUserList* pUserList = ScGlobal::GetUserList();
+ if (!pUserList)
+ return false;
+
+ {
+ sal_uInt16 n = pUserList->GetCount();
+ if (!n || *pUserListId >= n)
+ return false;
+ }
+
+ ScUserListData* pData = static_cast<ScUserListData*>((*pUserList)[*pUserListId]);
+ if (pData)
+ {
+ sal_uInt16 n = pData->GetSubCount();
+ for (sal_uInt16 i = 0; i < n; ++i)
+ {
+ OUString aSub = pData->GetSubStr(i);
+ if (!aMemberSet.count(aSub))
+ // This string doesn't exist in the member name set. Don't add this.
+ continue;
+
+ aSubStrs.insert(UserSortMap::value_type(aSub, nSubCount++));
+ }
+ }
+ }
+
+ // Rank all members.
+
+ vector<OUString> aRankedNames(nMemberCount);
+ sal_uInt16 nCurStrId = 0;
+ for (list<OUString>::const_iterator itr = aMembers.begin(), itrEnd = aMembers.end();
+ itr != itrEnd; ++itr)
+ {
+ OUString aName = *itr;
+ sal_uInt16 nRank = 0;
+ UserSortMap::const_iterator itrSub = aSubStrs.find(aName);
+ if (itrSub == aSubStrs.end())
+ nRank = nSubCount + nCurStrId++;
+ else
+ nRank = itrSub->second;
+
+ if (!bAscending)
+ nRank = static_cast< sal_uInt16 >( nMemberCount - nRank - 1 );
+
+ aRankedNames[nRank] = aName;
+ }
+
+ // Re-order ScDPSaveMember instances with the new ranks.
+
+ for (vector<OUString>::const_iterator itr = aRankedNames.begin(), itrEnd = aRankedNames.end();
+ itr != itrEnd; ++itr)
+ {
+ const ScDPSaveMember* pOldMem = pSaveDim->GetExistingMemberByName(*itr);
+ if (!pOldMem)
+ // All members are supposed to be present.
+ continue;
+
+ ScDPSaveMember* pNewMem = new ScDPSaveMember(*pOldMem);
+ pSaveDim->AddMember(pNewMem);
+ }
+
+ // Set the sorting mode to manual for now. We may introduce a new sorting
+ // mode later on.
+
+ sheet::DataPilotFieldSortInfo aSortInfo;
+ aSortInfo.Mode = sheet::DataPilotFieldSortMode::MANUAL;
+ pSaveDim->SetSortInfo(&aSortInfo);
+ }
+ else
+ {
+ // without user list id, just apply sorting mode
+
+ sheet::DataPilotFieldSortInfo aSortInfo;
+ aSortInfo.Mode = sheet::DataPilotFieldSortMode::NAME;
+ aSortInfo.IsAscending = bAscending;
+ pSaveDim->SetSortInfo(&aSortInfo);
+ }
+
+ // Update the datapilot with the newly sorted field members.
+
+ auto_ptr<ScDPObject> pNewObj(new ScDPObject(*pDPObj));
+ pNewObj->SetSaveData(aNewSaveData);
+ ScDBDocFunc aFunc(*GetViewData()->GetDocShell());
+
+ return aFunc.DataPilotUpdate(pDPObj, pNewObj.get(), true, false);
+}
+
+sal_Bool ScDBFunc::DataPilotMove( const ScRange& rSource, const ScAddress& rDest )
+{
+ sal_Bool bRet = sal_False;
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor( rSource.aStart.Col(), rSource.aStart.Row(), rSource.aStart.Tab() );
+ if ( pDPObj && pDPObj == pDoc->GetDPAtCursor( rDest.Col(), rDest.Row(), rDest.Tab() ) )
+ {
+ sheet::DataPilotTableHeaderData aDestData;
+ pDPObj->GetHeaderPositionData( rDest, aDestData );
+ bool bValid = ( aDestData.Dimension >= 0 ); // dropping onto a field
+
+ // look through the source range
+ std::hash_set< rtl::OUString, rtl::OUStringHash, std::equal_to<rtl::OUString> > aMembersSet; // for lookup
+ std::vector< rtl::OUString > aMembersVector; // members in original order, for inserting
+ aMembersVector.reserve( std::max( static_cast<SCSIZE>( rSource.aEnd.Col() - rSource.aStart.Col() + 1 ),
+ static_cast<SCSIZE>( rSource.aEnd.Row() - rSource.aStart.Row() + 1 ) ) );
+ for (SCROW nRow = rSource.aStart.Row(); bValid && nRow <= rSource.aEnd.Row(); ++nRow )
+ for (SCCOL nCol = rSource.aStart.Col(); bValid && nCol <= rSource.aEnd.Col(); ++nCol )
+ {
+ sheet::DataPilotTableHeaderData aSourceData;
+ pDPObj->GetHeaderPositionData( ScAddress( nCol, nRow, rSource.aStart.Tab() ), aSourceData );
+ if ( aSourceData.Dimension == aDestData.Dimension && aSourceData.MemberName.getLength() )
+ {
+ if ( aMembersSet.find( aSourceData.MemberName ) == aMembersSet.end() )
+ {
+ aMembersSet.insert( aSourceData.MemberName );
+ aMembersVector.push_back( aSourceData.MemberName );
+ }
+ // duplicates are ignored
+ }
+ else
+ bValid = false; // empty (subtotal) or different field
+ }
+
+ if ( bValid )
+ {
+ sal_Bool bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( aDestData.Dimension, bIsDataLayout );
+ if ( !bIsDataLayout )
+ {
+ ScDPSaveData aData( *pDPObj->GetSaveData() );
+ ScDPSaveDimension* pDim = aData.GetDimensionByName( aDimName );
+
+ // get all member names in source order
+ uno::Sequence<rtl::OUString> aMemberNames;
+ pDPObj->GetMemberNames( aDestData.Dimension, aMemberNames );
+
+ bool bInserted = false;
+
+ sal_Int32 nMemberCount = aMemberNames.getLength();
+ for (sal_Int32 nMemberPos=0; nMemberPos<nMemberCount; ++nMemberPos)
+ {
+ String aMemberStr( aMemberNames[nMemberPos] );
+
+ if ( !bInserted && aMemberNames[nMemberPos] == aDestData.MemberName )
+ {
+ // insert dragged items before this item
+ for ( std::vector<rtl::OUString>::const_iterator aIter = aMembersVector.begin();
+ aIter != aMembersVector.end(); ++aIter )
+ lcl_MoveToEnd( *pDim, *aIter );
+ bInserted = true;
+ }
+
+ if ( aMembersSet.find( aMemberStr ) == aMembersSet.end() ) // skip dragged items
+ lcl_MoveToEnd( *pDim, aMemberStr );
+ }
+ // insert dragged item at end if dest wasn't found (for example, empty)
+ if ( !bInserted )
+ for ( std::vector<rtl::OUString>::const_iterator aIter = aMembersVector.begin();
+ aIter != aMembersVector.end(); ++aIter )
+ lcl_MoveToEnd( *pDim, *aIter );
+
+ // Items that were in SaveData, but not in the source, end up at the start of the list.
+
+ // set flag for manual sorting
+ sheet::DataPilotFieldSortInfo aSortInfo;
+ aSortInfo.Mode = sheet::DataPilotFieldSortMode::MANUAL;
+ pDim->SetSortInfo( &aSortInfo );
+
+ // apply changes
+ ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
+ ScDPObject* pNewObj = new ScDPObject( *pDPObj );
+ pNewObj->SetSaveData( aData );
+ aFunc.DataPilotUpdate( pDPObj, pNewObj, sal_True, sal_False ); //! bApi for drag&drop?
+ delete pNewObj;
+
+ Unmark(); // entry was moved - no use in leaving the old cell selected
+
+ bRet = sal_True;
+ }
+ }
+ }
+
+ return bRet;
+}
+
+sal_Bool ScDBFunc::HasSelectionForDrillDown( sal_uInt16& rOrientation )
+{
+ sal_Bool bRet = sal_False;
+
+ ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ if ( pDPObj )
+ {
+ ScStrCollection aEntries;
+ long nSelectDimension = -1;
+ GetSelectedMemberList( aEntries, nSelectDimension );
+
+ if ( aEntries.GetCount() > 0 )
+ {
+ sal_Bool bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout );
+ if ( !bIsDataLayout )
+ {
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ ScDPSaveDimension* pDim = pSaveData->GetExistingDimensionByName( aDimName );
+ if ( pDim )
+ {
+ sal_uInt16 nDimOrient = pDim->GetOrientation();
+ ScDPSaveDimension* pInner = pSaveData->GetInnermostDimension( nDimOrient );
+ if ( pDim == pInner )
+ {
+ rOrientation = nDimOrient;
+ bRet = sal_True;
+ }
+ }
+ }
+ }
+ }
+
+ return bRet;
+}
+
+void ScDBFunc::SetDataPilotDetails( sal_Bool bShow, const String* pNewDimensionName )
+{
+ ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ if ( pDPObj )
+ {
+ ScStrCollection aEntries;
+ long nSelectDimension = -1;
+ GetSelectedMemberList( aEntries, nSelectDimension );
+
+ if ( aEntries.GetCount() > 0 )
+ {
+ sal_Bool bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout );
+ if ( !bIsDataLayout )
+ {
+ ScDPSaveData aData( *pDPObj->GetSaveData() );
+ ScDPSaveDimension* pDim = aData.GetDimensionByName( aDimName );
+
+ if ( bShow && pNewDimensionName )
+ {
+ // add the new dimension with the same orientation, at the end
+
+ ScDPSaveDimension* pNewDim = aData.GetDimensionByName( *pNewDimensionName );
+ ScDPSaveDimension* pDuplicated = NULL;
+ if ( pNewDim->GetOrientation() == sheet::DataPilotFieldOrientation_DATA )
+ {
+ // Need to duplicate the dimension, create column/row in addition to data:
+ // The duplicated dimension inherits the existing settings, pNewDim is modified below.
+ pDuplicated = aData.DuplicateDimension( *pNewDimensionName );
+ }
+
+ sal_uInt16 nOrientation = pDim->GetOrientation();
+ pNewDim->SetOrientation( nOrientation );
+
+ long nPosition = LONG_MAX;
+ aData.SetPosition( pNewDim, nPosition );
+
+ ScDPSaveDimension* pDataLayout = aData.GetDataLayoutDimension();
+ if ( pDataLayout->GetOrientation() == nOrientation &&
+ aData.GetDataDimensionCount() <= 1 )
+ {
+ // If there is only one data dimension, the data layout dimension
+ // must still be the last one in its orientation.
+ aData.SetPosition( pDataLayout, nPosition );
+ }
+
+ if ( pDuplicated )
+ {
+ // The duplicated (data) dimension needs to be behind the original dimension
+ aData.SetPosition( pDuplicated, nPosition );
+ }
+
+ // Hide details for all visible members (selected are changed below).
+ //! Use all members from source level instead (including non-visible)?
+
+ ScStrCollection aVisibleEntries;
+ pDPObj->GetMemberResultNames( aVisibleEntries, nSelectDimension );
+
+ sal_uInt16 nVisCount = aVisibleEntries.GetCount();
+ for (sal_uInt16 nVisPos=0; nVisPos<nVisCount; nVisPos++)
+ {
+ String aVisName = aVisibleEntries[nVisPos]->GetString();
+ ScDPSaveMember* pMember = pDim->GetMemberByName( aVisName );
+ pMember->SetShowDetails( sal_False );
+ }
+ }
+
+ sal_uInt16 nEntryCount = aEntries.GetCount();
+ for (sal_uInt16 nEntry=0; nEntry<nEntryCount; nEntry++)
+ {
+ String aEntryName = aEntries[nEntry]->GetString();
+ ScDPSaveMember* pMember = pDim->GetMemberByName( aEntryName );
+ pMember->SetShowDetails( bShow );
+ }
+
+ // apply changes
+ ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
+ ScDPObject* pNewObj = new ScDPObject( *pDPObj );
+ pNewObj->SetSaveData( aData );
+ aFunc.DataPilotUpdate( pDPObj, pNewObj, sal_True, sal_False );
+ delete pNewObj;
+
+ // unmark cell selection
+ Unmark();
+ }
+ }
+ }
+}
+
+void ScDBFunc::ShowDataPilotSourceData( ScDPObject& rDPObj, const Sequence<sheet::DataPilotFieldFilter>& rFilters )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if (pDoc->GetDocumentShell()->IsReadOnly())
+ {
+ ErrorMessage(STR_READONLYERR);
+ return;
+ }
+
+ Reference<sheet::XDimensionsSupplier> xDimSupplier = rDPObj.GetSource();
+ Reference<container::XNameAccess> xDims = xDimSupplier->getDimensions();
+ Reference<sheet::XDrillDownDataSupplier> xDDSupplier(xDimSupplier, UNO_QUERY);
+ if (!xDDSupplier.is())
+ return;
+
+ Sequence< Sequence<Any> > aTabData = xDDSupplier->getDrillDownData(rFilters);
+ sal_Int32 nRowSize = aTabData.getLength();
+ if (nRowSize <= 1)
+ // There is no data to show. Bail out.
+ return;
+
+ sal_Int32 nColSize = aTabData[0].getLength();
+
+ SCTAB nNewTab = GetViewData()->GetTabNo();
+
+ auto_ptr<ScDocument> pInsDoc(new ScDocument(SCDOCMODE_CLIP));
+ pInsDoc->ResetClip( pDoc, nNewTab );
+ for (SCROW nRow = 0; nRow < nRowSize; ++nRow)
+ {
+ for (SCCOL nCol = 0; nCol < nColSize; ++nCol)
+ {
+ const Any& rAny = aTabData[nRow][nCol];
+ rtl::OUString aStr;
+ double fVal;
+ if (rAny >>= aStr)
+ pInsDoc->PutCell( ScAddress(nCol, nRow, nNewTab), new ScStringCell(String(aStr)) );
+ else if (rAny >>= fVal)
+ pInsDoc->SetValue(nCol, nRow, nNewTab, fVal);
+ }
+ }
+
+ // set number format (important for dates)
+ for (SCCOL nCol = 0; nCol < nColSize; ++nCol)
+ {
+ rtl::OUString aStr;
+ if (!(aTabData[0][nCol] >>= aStr))
+ continue;
+
+ Reference<XPropertySet> xPropSet(xDims->getByName(aStr), UNO_QUERY);
+ if (!xPropSet.is())
+ continue;
+
+ Any any = xPropSet->getPropertyValue( rtl::OUString::createFromAscii(SC_UNO_NUMBERFO) );
+ sal_Int32 nNumFmt = 0;
+ if (!(any >>= nNumFmt))
+ continue;
+
+ ScPatternAttr aPattern( pInsDoc->GetPool() );
+ aPattern.GetItemSet().Put( SfxUInt32Item(ATTR_VALUE_FORMAT, static_cast<sal_uInt32>(nNumFmt)) );
+ pInsDoc->ApplyPatternAreaTab(nCol, 1, nCol, nRowSize-1, nNewTab, aPattern);
+ }
+
+ SCCOL nEndCol = 0;
+ SCROW nEndRow = 0;
+ pInsDoc->GetCellArea( nNewTab, nEndCol, nEndRow );
+ pInsDoc->SetClipArea( ScRange( 0, 0, nNewTab, nEndCol, nEndRow, nNewTab ) );
+
+ ::svl::IUndoManager* pMgr = GetViewData()->GetDocShell()->GetUndoManager();
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_DOOUTLINE );
+ pMgr->EnterListAction( aUndo, aUndo );
+
+ String aNewTabName;
+ pDoc->CreateValidTabName(aNewTabName);
+ if ( InsertTable(aNewTabName, nNewTab) )
+ PasteFromClip( IDF_ALL, pInsDoc.get() );
+
+ pMgr->LeaveListAction();
+}
+
+//
+// DB-Operationen (Sortieren, Filtern, Teilergebnisse) wiederholen
+//
+
+void ScDBFunc::RepeatDB( sal_Bool bRecord )
+{
+ SCCOL nCurX = GetViewData()->GetCurX();
+ SCROW nCurY = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDBData* pDBData = GetDBData();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = sal_False;
+
+ ScQueryParam aQueryParam;
+ pDBData->GetQueryParam( aQueryParam );
+ sal_Bool bQuery = aQueryParam.GetEntry(0).bDoQuery;
+
+ ScSortParam aSortParam;
+ pDBData->GetSortParam( aSortParam );
+ sal_Bool bSort = aSortParam.bDoSort[0];
+
+ ScSubTotalParam aSubTotalParam;
+ pDBData->GetSubTotalParam( aSubTotalParam );
+ sal_Bool bSubTotal = aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly;
+
+ if ( bQuery || bSort || bSubTotal )
+ {
+ sal_Bool bQuerySize = sal_False;
+ ScRange aOldQuery;
+ ScRange aNewQuery;
+ if (bQuery && !aQueryParam.bInplace)
+ {
+ ScDBData* pDest = pDoc->GetDBAtCursor( aQueryParam.nDestCol, aQueryParam.nDestRow,
+ aQueryParam.nDestTab, sal_True );
+ if (pDest && pDest->IsDoSize())
+ {
+ pDest->GetArea( aOldQuery );
+ bQuerySize = sal_True;
+ }
+ }
+
+ SCTAB nDummy;
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ pDBData->GetArea( nDummy, nStartCol, nStartRow, nEndCol, nEndRow );
+
+ //! Undo nur benoetigte Daten ?
+
+ ScDocument* pUndoDoc = NULL;
+ ScOutlineTable* pUndoTab = NULL;
+ ScRangeName* pUndoRange = NULL;
+ ScDBCollection* pUndoDB = NULL;
+
+ if (bRecord)
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
+ if (pTable)
+ {
+ pUndoTab = new ScOutlineTable( *pTable );
+
+ SCCOLROW nOutStartCol; // Zeilen/Spaltenstatus
+ SCCOLROW nOutStartRow;
+ SCCOLROW nOutEndCol;
+ SCCOLROW nOutEndRow;
+ pTable->GetColArray()->GetRange( nOutStartCol, nOutEndCol );
+ pTable->GetRowArray()->GetRange( nOutStartRow, nOutEndRow );
+
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
+ pDoc->CopyToDocument( static_cast<SCCOL>(nOutStartCol), 0, nTab, static_cast<SCCOL>(nOutEndCol), MAXROW, nTab, IDF_NONE, sal_False, pUndoDoc );
+ pDoc->CopyToDocument( 0, nOutStartRow, nTab, MAXCOL, nOutEndRow, nTab, IDF_NONE, sal_False, pUndoDoc );
+ }
+ else
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_False, sal_True );
+
+ // Datenbereich sichern - incl. Filter-Ergebnis
+ pDoc->CopyToDocument( 0,nStartRow,nTab, MAXCOL,nEndRow,nTab, IDF_ALL, sal_False, pUndoDoc );
+
+ // alle Formeln wegen Referenzen
+ pDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTabCount-1, IDF_FORMULA, sal_False, pUndoDoc );
+
+ // DB- und andere Bereiche
+ ScRangeName* pDocRange = pDoc->GetRangeName();
+ if (pDocRange->GetCount())
+ pUndoRange = new ScRangeName( *pDocRange );
+ ScDBCollection* pDocDB = pDoc->GetDBCollection();
+ if (pDocDB->GetCount())
+ pUndoDB = new ScDBCollection( *pDocDB );
+ }
+
+ if (bSort && bSubTotal)
+ {
+ // Sortieren ohne SubTotals
+
+ aSubTotalParam.bRemoveOnly = sal_True; // wird unten wieder zurueckgesetzt
+ DoSubTotals( aSubTotalParam, sal_False );
+ }
+
+ if (bSort)
+ {
+ pDBData->GetSortParam( aSortParam ); // Bereich kann sich geaendert haben
+ Sort( aSortParam, sal_False, sal_False);
+ }
+ if (bQuery)
+ {
+ pDBData->GetQueryParam( aQueryParam ); // Bereich kann sich geaendert haben
+ ScRange aAdvSource;
+ if (pDBData->GetAdvancedQuerySource(aAdvSource))
+ {
+ pDoc->CreateQueryParam(
+ aAdvSource.aStart.Col(), aAdvSource.aStart.Row(),
+ aAdvSource.aEnd.Col(), aAdvSource.aEnd.Row(),
+ aAdvSource.aStart.Tab(), aQueryParam );
+ Query( aQueryParam, &aAdvSource, sal_False );
+ }
+ else
+ Query( aQueryParam, NULL, sal_False );
+
+ // bei nicht-inplace kann die Tabelle umgestellt worden sein
+ if ( !aQueryParam.bInplace && aQueryParam.nDestTab != nTab )
+ SetTabNo( nTab );
+ }
+ if (bSubTotal)
+ {
+ pDBData->GetSubTotalParam( aSubTotalParam ); // Bereich kann sich geaendert haben
+ aSubTotalParam.bRemoveOnly = sal_False;
+ DoSubTotals( aSubTotalParam, sal_False );
+ }
+
+ if (bRecord)
+ {
+ SCTAB nDummyTab;
+ SCCOL nDummyCol;
+ SCROW nDummyRow, nNewEndRow;
+ pDBData->GetArea( nDummyTab, nDummyCol,nDummyRow, nDummyCol,nNewEndRow );
+
+ const ScRange* pOld = NULL;
+ const ScRange* pNew = NULL;
+ if (bQuerySize)
+ {
+ ScDBData* pDest = pDoc->GetDBAtCursor( aQueryParam.nDestCol, aQueryParam.nDestRow,
+ aQueryParam.nDestTab, sal_True );
+ if (pDest)
+ {
+ pDest->GetArea( aNewQuery );
+ pOld = &aOldQuery;
+ pNew = &aNewQuery;
+ }
+ }
+
+ GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
+ new ScUndoRepeatDB( GetViewData()->GetDocShell(), nTab,
+ nStartCol, nStartRow, nEndCol, nEndRow,
+ nNewEndRow,
+ nCurX, nCurY,
+ pUndoDoc, pUndoTab,
+ pUndoRange, pUndoDB,
+ pOld, pNew ) );
+ }
+
+ GetViewData()->GetDocShell()->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab,
+ PAINT_GRID | PAINT_LEFT | PAINT_TOP | PAINT_SIZE );
+ }
+ else // "Keine Operationen auszufuehren"
+ ErrorMessage(STR_MSSG_REPEATDB_0);
+}
+
+
+
+
diff --git a/sc/source/ui/view/dbfunc4.cxx b/sc/source/ui/view/dbfunc4.cxx
new file mode 100644
index 000000000000..cb2c049f3200
--- /dev/null
+++ b/sc/source/ui/view/dbfunc4.cxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svx/svditer.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdpage.hxx>
+
+#include "dbfunc.hxx"
+#include "drwlayer.hxx"
+#include "document.hxx"
+
+// -----------------------------------------------------------------------
+
+#ifdef _MSC_VER
+#pragma optimize ( "", off )
+#endif
+
+using namespace com::sun::star;
+
+//==================================================================
+
+// static
+sal_uInt16 ScDBFunc::DoUpdateCharts( const ScAddress& rPos, ScDocument* pDoc, sal_Bool bAllCharts )
+{
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel)
+ return 0;
+
+ sal_uInt16 nFound = 0;
+
+ sal_uInt16 nPageCount = pModel->GetPageCount();
+ for (sal_uInt16 nPageNo=0; nPageNo<nPageCount; nPageNo++)
+ {
+ SdrPage* pPage = pModel->GetPage(nPageNo);
+ DBG_ASSERT(pPage,"Page ?");
+
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart( pObject ) )
+ {
+ String aName = ((SdrOle2Obj*)pObject)->GetPersistName();
+ sal_Bool bHit = sal_True;
+ if ( !bAllCharts )
+ {
+ ScRangeList aRanges;
+ sal_Bool bColHeaders = sal_False;
+ sal_Bool bRowHeaders = sal_False;
+ pDoc->GetOldChartParameters( aName, aRanges, bColHeaders, bRowHeaders );
+ bHit = aRanges.In( rPos );
+ }
+ if ( bHit )
+ {
+ pDoc->UpdateChart( aName );
+ ++nFound;
+ }
+ }
+ pObject = aIter.Next();
+ }
+ }
+ return nFound;
+}
+
+
+
+
+
+
diff --git a/sc/source/ui/view/drawattr.cxx b/sc/source/ui/view/drawattr.cxx
new file mode 100644
index 000000000000..4f79673bcc91
--- /dev/null
+++ b/sc/source/ui/view/drawattr.cxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "drawattr.hxx"
+#include "global.hxx"
+
+//------------------------------------------------------------------------
+
+String __EXPORT SvxDrawToolItem::GetValueText() const
+{
+ return GetValueText(GetValue());
+}
+
+//------------------------------------------------------------------------
+
+String __EXPORT SvxDrawToolItem::GetValueText( sal_uInt16 nVal ) const
+{
+ const sal_Char* p;
+
+ switch (nVal)
+ {
+ case 0 : p = "SVX_SNAP_DRAW_SELECT" ; break;
+ //
+ case 1 : p = "SVX_SNAP_DRAW_LINE" ; break;
+ case 2 : p = "SVX_SNAP_DRAW_RECT" ; break;
+ case 3 : p = "SVX_SNAP_DRAW_ELLIPSE" ; break;
+ case 4 : p = "SVX_SNAP_DRAW_POLYGON" ; break;
+ case 5 : p = "SVX_SNAP_DRAW_ARC" ; break;
+ case 6 : p = "SVX_SNAP_DRAW_PIE" ; break;
+ case 7 : p = "SVX_SNAP_DRAW_CIRCLECUT" ; break;
+ case 8 : p = "SVX_SNAP_DRAW_TEXT" ; break;
+ default : return EMPTY_STRING;
+ }
+ return String::CreateFromAscii( p );
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* __EXPORT SvxDrawToolItem::Clone( SfxItemPool * ) const
+{
+ return new SvxDrawToolItem(*this);
+}
+
+//------------------------------------------------------------------------
+
+SfxPoolItem* __EXPORT SvxDrawToolItem::Create( SvStream& rStream, sal_uInt16 nVer ) const
+{
+ sal_uInt16 nVal;
+ rStream >> nVal;
+ return new SvxDrawToolItem(nVal);
+}
+
+
+
diff --git a/sc/source/ui/view/drawutil.cxx b/sc/source/ui/view/drawutil.cxx
new file mode 100644
index 000000000000..a5a4a7ee1c1d
--- /dev/null
+++ b/sc/source/ui/view/drawutil.cxx
@@ -0,0 +1,116 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <vcl/outdev.hxx>
+
+#include "drawutil.hxx"
+#include "document.hxx"
+#include "global.hxx"
+#include "viewdata.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+// -----------------------------------------------------------------------
+
+
+inline Fraction MakeFraction( long nA, long nB )
+{
+ return ( nA && nB ) ? Fraction(nA,nB) : Fraction(1,1);
+}
+
+void ScDrawUtil::CalcScale( ScDocument* pDoc, SCTAB nTab,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ OutputDevice* pDev,
+ const Fraction& rZoomX, const Fraction& rZoomY,
+ double nPPTX, double nPPTY,
+ Fraction& rScaleX, Fraction& rScaleY )
+{
+ long nPixelX = 0;
+ long nTwipsX = 0;
+ long nPixelY = 0;
+ long nTwipsY = 0;
+ for (SCCOL i=nStartCol; i<nEndCol; i++)
+ {
+ sal_uInt16 nWidth = pDoc->GetColWidth(i,nTab);
+ nTwipsX += (long) nWidth;
+ nPixelX += ScViewData::ToPixel( nWidth, nPPTX );
+ }
+
+ for (SCROW nRow = nStartRow; nRow <= nEndRow-1; ++nRow)
+ {
+ SCROW nLastRow = nRow;
+ if (pDoc->RowHidden(nRow, nTab, NULL, &nLastRow))
+ {
+ nRow = nLastRow;
+ continue;
+ }
+
+ sal_uInt16 nHeight = pDoc->GetRowHeight(nRow, nTab);
+ nTwipsY += static_cast<long>(nHeight);
+ nPixelY += ScViewData::ToPixel(nHeight, nPPTY);
+ }
+
+ MapMode aHMMMode( MAP_100TH_MM, Point(), rZoomX, rZoomY );
+ Point aPixelLog = pDev->PixelToLogic( Point( nPixelX,nPixelY ), aHMMMode );
+
+ // Fraction(double) ctor can be used here (and avoid overflows of PixelLog * Zoom)
+ // because ReduceInaccurate is called later anyway.
+
+ if ( aPixelLog.X() && nTwipsX )
+ rScaleX = Fraction( ((double)aPixelLog.X()) *
+ ((double)rZoomX.GetNumerator()) /
+ ((double)nTwipsX) /
+ ((double)HMM_PER_TWIPS) /
+ ((double)rZoomX.GetDenominator()) );
+ else
+ rScaleX = Fraction( 1, 1 );
+
+ if ( aPixelLog.Y() && nTwipsY )
+ rScaleY = Fraction( ((double)aPixelLog.Y()) *
+ ((double)rZoomY.GetNumerator()) /
+ ((double)nTwipsY) /
+ ((double)HMM_PER_TWIPS) /
+ ((double)rZoomY.GetDenominator()) );
+ else
+ rScaleY = Fraction( 1, 1 );
+
+ // 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/drawvie2.cxx b/sc/source/ui/view/drawvie2.cxx
new file mode 100644
index 000000000000..c760ce86a3d7
--- /dev/null
+++ b/sc/source/ui/view/drawvie2.cxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "drawview.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+// -----------------------------------------------------------------------
+
+
+// UpdateBrowser in MarkListHasChanged gerufen
+
+void ScDrawView::UpdateBrowser()
+{
+ // VC's und den Browser dazu gibts nicht mehr...
+}
+
+void ScDrawView::VCAddWin( Window* /* pWin */ )
+{
+ // GetSbxForm gibt's nicht mehr, muss auch nichts mehr angemeldet werden
+}
+
+void ScDrawView::VCRemoveWin( Window* /* pWin */ )
+{
+ // GetSbxForm gibt's nicht mehr, muss auch nichts mehr angemeldet werden
+}
+
+
+
+
+
diff --git a/sc/source/ui/view/drawvie3.cxx b/sc/source/ui/view/drawvie3.cxx
new file mode 100644
index 000000000000..670782f5af9c
--- /dev/null
+++ b/sc/source/ui/view/drawvie3.cxx
@@ -0,0 +1,182 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svx/svdograf.hxx>
+#include <svx/svdoole2.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include "drawview.hxx"
+#include "drwlayer.hxx"
+#include "viewdata.hxx"
+#include "dbfunc.hxx"
+#include "document.hxx"
+#include "userdat.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+
+void ScIMapDlgSet( const Graphic& rGraphic, const ImageMap* pImageMap,
+ const TargetList* pTargetList, void* pEditingObj ); // imapwrap
+sal_uInt16 ScIMapChildWindowId();
+
+// STATIC DATA -----------------------------------------------------------
+
+ScDrawView::ScDrawView( OutputDevice* pOut, ScViewData* pData ) :
+ FmFormView( pData->GetDocument()->GetDrawLayer(), pOut ),
+ pViewData( pData ),
+ pDev( pOut ),
+ pDoc( pData->GetDocument() ),
+ nTab( pData->GetTabNo() ),
+ pDropMarker( NULL ),
+ pDropMarkObj( NULL ),
+ bInConstruct( sal_True )
+ //HMHbDisableHdl( sal_False )
+{
+ // #i73602# Use default from the configuration
+ SetBufferedOverlayAllowed(getOptionsDrawinglayer().IsOverlayBuffer_Calc());
+
+ // #i74769#, #i75172# Use default from the configuration
+ SetBufferedOutputAllowed(getOptionsDrawinglayer().IsPaintBuffer_Calc());
+
+ Construct();
+}
+
+// Verankerung setzen
+
+void ScDrawView::SetAnchor( ScAnchorType eType )
+{
+ SdrObject* pObj = NULL;
+ if( AreObjectsMarked() )
+ {
+ const SdrMarkList* pMark = &GetMarkedObjectList();
+ sal_uLong nCount = pMark->GetMarkCount();
+ for( sal_uLong i=0; i<nCount; i++ )
+ {
+ pObj = pMark->GetMark(i)->GetMarkedSdrObj();
+ ScDrawLayer::SetAnchor( pObj, eType );
+ }
+
+ if ( pViewData )
+ pViewData->GetDocShell()->SetDrawModified();
+ }
+}
+
+ScAnchorType ScDrawView::GetAnchor() const
+{
+ sal_Bool bPage = sal_False;
+ sal_Bool bCell = sal_False;
+ const SdrObject* pObj = NULL;
+ if( AreObjectsMarked() )
+ {
+ const SdrMarkList* pMark = &GetMarkedObjectList();
+ sal_uLong nCount = pMark->GetMarkCount();
+ Point p0;
+ for( sal_uLong i=0; i<nCount; i++ )
+ {
+ pObj = pMark->GetMark(i)->GetMarkedSdrObj();
+ if( ScDrawLayer::GetAnchor( pObj ) == SCA_CELL )
+ bCell =sal_True;
+ else
+ bPage = sal_True;
+ }
+ }
+ if( bPage && !bCell )
+ return SCA_PAGE;
+ if( !bPage && bCell )
+ return SCA_CELL;
+ return SCA_DONTKNOW;
+}
+
+void __EXPORT ScDrawView::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA(ScTabDeletedHint)) // Tabelle geloescht
+ {
+ SCTAB nDelTab = ((ScTabDeletedHint&)rHint).GetTab();
+ if (ValidTab(nDelTab))
+ {
+ // used to be: HidePagePgNum(nDelTab) - hide only if the deleted sheet is shown here
+ if ( nDelTab == nTab )
+ HideSdrPage();
+ }
+ }
+ else if (rHint.ISA(ScTabSizeChangedHint)) // Groesse geaendert
+ {
+ if ( nTab == ((ScTabSizeChangedHint&)rHint).GetTab() )
+ UpdateWorkArea();
+ }
+ else
+ FmFormView::Notify( rBC,rHint );
+}
+
+void ScDrawView::UpdateIMap( SdrObject* pObj )
+{
+ if ( pViewData &&
+ pViewData->GetViewShell()->GetViewFrame()->HasChildWindow( ScIMapChildWindowId() ) &&
+ pObj && ( pObj->ISA(SdrGrafObj) || pObj->ISA(SdrOle2Obj) ) )
+ {
+ Graphic aGraphic;
+ TargetList aTargetList;
+ ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo( pObj );
+ const ImageMap* pImageMap = NULL;
+ if ( pIMapInfo )
+ pImageMap = &pIMapInfo->GetImageMap();
+
+ // Target-Liste besorgen
+ pViewData->GetViewShell()->GetViewFrame()->GetTargetList( aTargetList );
+
+ // Grafik vom Objekt besorgen
+ if ( pObj->ISA( SdrGrafObj ) )
+ aGraphic = ( (SdrGrafObj*) pObj )->GetGraphic();
+ else
+ {
+ Graphic* pGraphic = ((const SdrOle2Obj*) pObj )->GetGraphic();
+ if ( pGraphic )
+ aGraphic = *pGraphic;
+ }
+
+ ScIMapDlgSet( aGraphic, pImageMap, &aTargetList, pObj ); // aus imapwrap
+
+ // TargetListe kann von uns wieder geloescht werden
+ String* pEntry = aTargetList.First();
+ while( pEntry )
+ {
+ delete pEntry;
+ pEntry = aTargetList.Next();
+ }
+ }
+}
+
+
+
+
diff --git a/sc/source/ui/view/drawvie4.cxx b/sc/source/ui/view/drawvie4.cxx
new file mode 100644
index 000000000000..1c0d38ee18e5
--- /dev/null
+++ b/sc/source/ui/view/drawvie4.cxx
@@ -0,0 +1,394 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include <svx/svditer.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdundo.hxx>
+#include <sfx2/docfile.hxx>
+#include <tools/urlobj.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include "drawview.hxx"
+#include "global.hxx"
+#include "drwlayer.hxx"
+#include "viewdata.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "drwtrans.hxx"
+#include "transobj.hxx" // SetDrawClipDoc
+#include "drawutil.hxx"
+#include "scmod.hxx"
+#include "globstr.hrc"
+#include "chartarr.hxx"
+
+using namespace com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+Point aDragStartDiff;
+
+// -----------------------------------------------------------------------
+
+//! welche Funktionen aus drawview/drawvie4 muessen wirklich ohne Optimierung sein?
+
+#ifdef _MSC_VER
+#pragma optimize ( "", off )
+#endif
+
+// -----------------------------------------------------------------------
+
+void lcl_CheckOle( const SdrMarkList& rMarkList, sal_Bool& rAnyOle, sal_Bool& rOneOle )
+{
+ rAnyOle = rOneOle = sal_False;
+ sal_uLong nCount = rMarkList.GetMarkCount();
+ for (sal_uLong i=0; i<nCount; i++)
+ {
+ SdrMark* pMark = rMarkList.GetMark(i);
+ SdrObject* pObj = pMark->GetMarkedSdrObj();
+ sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier();
+ if (nSdrObjKind == OBJ_OLE2)
+ {
+ rAnyOle = sal_True;
+ rOneOle = (nCount == 1);
+ break;
+ }
+ else if ( pObj->ISA(SdrObjGroup) )
+ {
+ SdrObjListIter aIter( *pObj, IM_DEEPNOGROUPS );
+ SdrObject* pSubObj = aIter.Next();
+ while (pSubObj)
+ {
+ if ( pSubObj->GetObjIdentifier() == OBJ_OLE2 )
+ {
+ rAnyOle = sal_True;
+ // rOneOle remains sal_False - a group isn't treated like a single OLE object
+ return;
+ }
+ pSubObj = aIter.Next();
+ }
+ }
+ }
+}
+
+#if 0
+void lcl_RefreshChartData( SdrModel* pModel, ScDocument* pSourceDoc )
+{
+ sal_uInt16 nPages = pModel->GetPageCount();
+ for (SCTAB nTab=0; nTab<nPages; nTab++)
+ {
+ SdrPage* pPage = pModel->GetPage(nTab);
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->GetObjIdentifier() == OBJ_OLE2 )
+ {
+ SvInPlaceObjectRef aIPObj = ((SdrOle2Obj*)pObject)->GetObjRef();
+ if ( aIPObj.Is() && SotExchange::IsChart( aIPObj->GetStorage()->GetClassName() ) )
+ {
+ SchMemChart* pOldData = SchDLL::GetChartData(aIPObj);
+ if ( pOldData )
+ {
+ // create data from source document
+ ScChartArray aArray( pSourceDoc, *pOldData );
+ if ( aArray.IsValid() )
+ {
+ SchMemChart* pNewData = aArray.CreateMemChart();
+ SchDLL::Update( aIPObj, pNewData );
+ delete pNewData;
+ ((SdrOle2Obj*)pObject)->GetNewReplacement();
+ }
+ }
+ }
+ }
+ pObject = aIter.Next();
+ }
+ }
+}
+#endif
+
+
+sal_Bool ScDrawView::BeginDrag( Window* pWindow, const Point& rStartPos )
+{
+ sal_Bool bReturn = sal_False;
+
+ if ( AreObjectsMarked() )
+ {
+ BrkAction();
+
+ Rectangle aMarkedRect = GetAllMarkedRect();
+ Region aRegion( aMarkedRect );
+
+ aDragStartDiff = rStartPos - aMarkedRect.TopLeft();
+
+ sal_Bool bAnyOle, bOneOle;
+ const SdrMarkList& rMarkList = GetMarkedObjectList();
+ lcl_CheckOle( rMarkList, bAnyOle, bOneOle );
+
+ ScDocShellRef aDragShellRef;
+ if (bAnyOle)
+ {
+ aDragShellRef = new ScDocShell; // DocShell needs a Ref immediately
+ aDragShellRef->DoInitNew(NULL);
+ }
+ ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
+ SdrModel* pModel = GetAllMarkedModel();
+ ScDrawLayer::SetGlobalDrawPersist(NULL);
+
+ // Charts now always copy their data in addition to the source reference, so
+ // there's no need to call SchDLL::Update for the charts in the clipboard doc.
+ // Update with the data (including NumberFormatter) from the live document would
+ // also store the NumberFormatter in the clipboard chart (#88749#)
+ // lcl_RefreshChartData( pModel, pViewData->GetDocument() );
+
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScDrawTransferObj ctor
+
+ ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
+ uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ pTransferObj->SetDrawPersist( &aDragShellRef ); // keep persist for ole objects alive
+ pTransferObj->SetDragSource( this ); // copies selection
+
+ SC_MOD()->SetDragObject( NULL, pTransferObj ); // for internal D&D
+ pTransferObj->StartDrag( pWindow, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
+ }
+
+ return bReturn;
+}
+
+void ScDrawView::DoCopy()
+{
+ sal_Bool bAnyOle, bOneOle;
+ const SdrMarkList& rMarkList = GetMarkedObjectList();
+ lcl_CheckOle( rMarkList, bAnyOle, bOneOle );
+
+ // update ScGlobal::pDrawClipDocShellRef
+ ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) );
+ SdrModel* pModel = GetAllMarkedModel();
+ ScDrawLayer::SetGlobalDrawPersist(NULL);
+
+ // Charts now always copy their data in addition to the source reference, so
+ // there's no need to call SchDLL::Update for the charts in the clipboard doc.
+ // Update with the data (including NumberFormatter) from the live document would
+ // also store the NumberFormatter in the clipboard chart (#88749#)
+ // lcl_RefreshChartData( pModel, pViewData->GetDocument() );
+
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScDrawTransferObj ctor
+
+ ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
+ uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ if ( ScGlobal::pDrawClipDocShellRef )
+ {
+ pTransferObj->SetDrawPersist( &(*ScGlobal::pDrawClipDocShellRef) ); // keep persist for ole objects alive
+ }
+
+ pTransferObj->CopyToClipboard( pViewData->GetActiveWin() ); // system clipboard
+ SC_MOD()->SetClipObject( NULL, pTransferObj ); // internal clipboard
+}
+
+uno::Reference<datatransfer::XTransferable> ScDrawView::CopyToTransferable()
+{
+ sal_Bool bAnyOle, bOneOle;
+ const SdrMarkList& rMarkList = GetMarkedObjectList();
+ lcl_CheckOle( rMarkList, bAnyOle, bOneOle );
+
+ // update ScGlobal::pDrawClipDocShellRef
+ ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) );
+ SdrModel* pModel = GetAllMarkedModel();
+ ScDrawLayer::SetGlobalDrawPersist(NULL);
+
+ // Charts now always copy their data in addition to the source reference, so
+ // there's no need to call SchDLL::Update for the charts in the clipboard doc.
+ // Update with the data (including NumberFormatter) from the live document would
+ // also store the NumberFormatter in the clipboard chart (#88749#)
+ // lcl_RefreshChartData( pModel, pViewData->GetDocument() );
+
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScDrawTransferObj ctor
+
+ ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc );
+ uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ if ( ScGlobal::pDrawClipDocShellRef )
+ {
+ pTransferObj->SetDrawPersist( &(*ScGlobal::pDrawClipDocShellRef) ); // keep persist for ole objects alive
+ }
+
+ return xTransferable;
+}
+
+// Korrektur fuer 100% berechnen, unabhaengig von momentanen Einstellungen
+
+void ScDrawView::CalcNormScale( Fraction& rFractX, Fraction& rFractY ) const
+{
+ Point aLogic = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
+ double nPPTX = ScGlobal::nScreenPPTX;
+ double nPPTY = ScGlobal::nScreenPPTY;
+
+ if (pViewData)
+ nPPTX /= pViewData->GetDocShell()->GetOutputFactor();
+
+ SCCOL nEndCol = 0;
+ SCROW nEndRow = 0;
+ pDoc->GetTableArea( nTab, nEndCol, nEndRow );
+ if (nEndCol<20)
+ nEndCol = 20;
+ if (nEndRow<20)
+ nEndRow = 1000;
+
+ Fraction aZoom(1,1);
+ ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, pDev, aZoom,aZoom,
+ nPPTX, nPPTY, rFractX,rFractY );
+}
+
+void ScDrawView::SetMarkedOriginalSize()
+{
+ SdrUndoGroup* pUndoGroup = new SdrUndoGroup(*GetModel());
+
+ const SdrMarkList& rMarkList = GetMarkedObjectList();
+ long nDone = 0;
+ sal_uLong nCount = rMarkList.GetMarkCount();
+ for (sal_uLong i=0; i<nCount; i++)
+ {
+ SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
+ sal_uInt16 nIdent = pObj->GetObjIdentifier();
+ sal_Bool bDo = sal_False;
+ Size aOriginalSize;
+ if (nIdent == OBJ_OLE2)
+ {
+ // TODO/LEAN: working with visual area can switch object to running state
+ uno::Reference < embed::XEmbeddedObject > xObj( ((SdrOle2Obj*)pObj)->GetObjRef(), uno::UNO_QUERY );
+ if ( xObj.is() ) // #121612# NULL for an invalid object that couldn't be loaded
+ {
+ sal_Int64 nAspect = ((SdrOle2Obj*)pObj)->GetAspect();
+
+ if ( nAspect == embed::Aspects::MSOLE_ICON )
+ {
+ MapMode aMapMode( MAP_100TH_MM );
+ aOriginalSize = ((SdrOle2Obj*)pObj)->GetOrigObjSize( &aMapMode );
+ bDo = sal_True;
+ }
+ else
+ {
+ MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( ((SdrOle2Obj*)pObj)->GetAspect() ) );
+ awt::Size aSz;
+ try
+ {
+ aSz = xObj->getVisualAreaSize( ((SdrOle2Obj*)pObj)->GetAspect() );
+ aOriginalSize = OutputDevice::LogicToLogic(
+ Size( aSz.Width, aSz.Height ),
+ aUnit, MAP_100TH_MM );
+ bDo = sal_True;
+ } catch( embed::NoVisualAreaSizeException& )
+ {
+ OSL_ENSURE( sal_False, "Can't get the original size of the object!" );
+ }
+ }
+ }
+ }
+ else if (nIdent == OBJ_GRAF)
+ {
+ const Graphic& rGraphic = ((SdrGrafObj*)pObj)->GetGraphic();
+
+ MapMode aSourceMap = rGraphic.GetPrefMapMode();
+ MapMode aDestMap( MAP_100TH_MM );
+ if (aSourceMap.GetMapUnit() == MAP_PIXEL)
+ {
+ // Pixel-Korrektur beruecksichtigen, damit Bitmap auf dem Bildschirm stimmt
+
+ Fraction aNormScaleX, aNormScaleY;
+ CalcNormScale( aNormScaleX, aNormScaleY );
+ aDestMap.SetScaleX(aNormScaleX);
+ aDestMap.SetScaleY(aNormScaleY);
+ }
+ if (pViewData)
+ {
+ Window* pActWin = pViewData->GetActiveWin();
+ if (pActWin)
+ {
+ aOriginalSize = pActWin->LogicToLogic(
+ rGraphic.GetPrefSize(), &aSourceMap, &aDestMap );
+ bDo = sal_True;
+ }
+ }
+ }
+
+ if ( bDo )
+ {
+ Rectangle aDrawRect = pObj->GetLogicRect();
+
+ pUndoGroup->AddAction( new SdrUndoGeoObj( *pObj ) );
+ pObj->Resize( aDrawRect.TopLeft(), Fraction( aOriginalSize.Width(), aDrawRect.GetWidth() ),
+ Fraction( aOriginalSize.Height(), aDrawRect.GetHeight() ) );
+ ++nDone;
+ }
+ }
+
+ if (nDone)
+ {
+ pUndoGroup->SetComment(ScGlobal::GetRscString( STR_UNDO_ORIGINALSIZE ));
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ pDocSh->GetUndoManager()->AddUndoAction(pUndoGroup);
+ pDocSh->SetDrawModified();
+ }
+ else
+ delete pUndoGroup;
+}
+
+
+#ifdef _MSC_VER
+#pragma optimize ( "", on )
+#endif
+
+
+
+
diff --git a/sc/source/ui/view/drawview.cxx b/sc/source/ui/view/drawview.cxx
new file mode 100644
index 000000000000..cc63f9b97a62
--- /dev/null
+++ b/sc/source/ui/view/drawview.cxx
@@ -0,0 +1,845 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <com/sun/star/embed/EmbedStates.hpp>
+
+#include <svx/svditer.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdomedia.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/svdocapt.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/writingmodeitem.hxx>
+#include <svx/sdrpaintwindow.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include "drawview.hxx"
+#include "global.hxx"
+#include "viewdata.hxx"
+#include "document.hxx"
+#include "drawutil.hxx"
+#include "futext.hxx"
+#include "globstr.hrc"
+#include "tabvwsh.hxx"
+#include "client.hxx"
+#include "scmod.hxx"
+#include "drwlayer.hxx"
+#include "docsh.hxx"
+#include "viewuno.hxx"
+#include "userdat.hxx"
+#include "postit.hxx"
+#include "undocell.hxx"
+
+#include "sc.hrc"
+
+using namespace com::sun::star;
+
+// -----------------------------------------------------------------------
+
+#define SC_HANDLESIZE_BIG 9
+#define SC_HANDLESIZE_SMALL 7
+
+// -----------------------------------------------------------------------
+
+#ifdef _MSC_VER
+#pragma optimize ( "", off )
+#endif
+
+
+void ScDrawView::Construct()
+{
+ EnableExtendedKeyInputDispatcher(sal_False);
+ EnableExtendedMouseEventDispatcher(sal_False);
+ EnableExtendedCommandEventDispatcher(sal_False);
+
+ SetFrameDragSingles(sal_True);
+// SetSolidMarkHdl(sal_True); // einstellbar -> UpdateUserViewOptions
+
+ SetMinMoveDistancePixel( 2 );
+ SetHitTolerancePixel( 2 );
+
+ if (pViewData)
+ {
+ SCTAB nViewTab = pViewData->GetTabNo();
+ ShowSdrPage(GetModel()->GetPage(nViewTab));
+
+ sal_Bool bEx = pViewData->GetViewShell()->IsDrawSelMode();
+ sal_Bool bProt = pDoc->IsTabProtected( nViewTab ) ||
+ pViewData->GetSfxDocShell()->IsReadOnly();
+
+ SdrLayer* pLayer;
+ SdrLayerAdmin& rAdmin = GetModel()->GetLayerAdmin();
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_BACK);
+ if (pLayer)
+ SetLayerLocked( pLayer->GetName(), bProt || !bEx );
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_INTERN);
+ if (pLayer)
+ SetLayerLocked( pLayer->GetName(), sal_True );
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_FRONT);
+ if (pLayer)
+ {
+ SetLayerLocked( pLayer->GetName(), bProt );
+ SetActiveLayer( pLayer->GetName() ); // FRONT als aktiven Layer setzen
+ }
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_CONTROLS);
+ if (pLayer)
+ SetLayerLocked( pLayer->GetName(), bProt );
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_HIDDEN);
+ if (pLayer)
+ {
+ SetLayerLocked( pLayer->GetName(), bProt );
+ SetLayerVisible( pLayer->GetName(), sal_False);
+ }
+
+ SetSwapAsynchron(sal_True);
+ }
+ else
+ {
+ ShowSdrPage(GetModel()->GetPage(nTab));
+ }
+
+ UpdateUserViewOptions();
+ RecalcScale();
+ UpdateWorkArea();
+
+ bInConstruct = sal_False;
+}
+
+void ScDrawView::ImplClearCalcDropMarker()
+{
+ if(pDropMarker)
+ {
+ delete pDropMarker;
+ pDropMarker = 0L;
+ }
+}
+
+__EXPORT ScDrawView::~ScDrawView()
+{
+ ImplClearCalcDropMarker();
+}
+
+void ScDrawView::AddCustomHdl()
+{
+ sal_Bool bNegativePage = pDoc->IsNegativePage( nTab );
+
+ const SdrMarkList &rMrkList = GetMarkedObjectList();
+ sal_uInt32 nCount = rMrkList.GetMarkCount();
+ for(sal_uInt32 nPos=0; nPos<nCount; nPos++ )
+ {
+ const SdrObject* pObj = rMrkList.GetMark(nPos)->GetMarkedSdrObj();
+ if(ScDrawLayer::GetAnchor(pObj) == SCA_CELL)
+ {
+ const sal_Int32 nDelta = 1;
+
+ Rectangle aBoundRect = pObj->GetCurrentBoundRect();
+ Point aPos;
+ if (bNegativePage)
+ {
+ aPos = aBoundRect.TopRight();
+ aPos.X() = -aPos.X(); // so the loop below is the same
+ }
+ else
+ aPos = aBoundRect.TopLeft();
+ long nPosX = (long) (aPos.X() / HMM_PER_TWIPS) + nDelta;
+ long nPosY = (long) (aPos.Y() / HMM_PER_TWIPS) + nDelta;
+
+ SCCOL nCol;
+ sal_Int32 nWidth = 0;
+
+ for(nCol=0; nCol<=MAXCOL && nWidth<=nPosX; nCol++)
+ nWidth += pDoc->GetColWidth(nCol,nTab);
+
+ if(nCol > 0)
+ --nCol;
+
+ SCROW nRow = nPosY <= 0 ? 0 : pDoc->GetRowForHeight( nTab,
+ (sal_uLong) nPosY);
+ if(nRow > 0)
+ --nRow;
+
+ ScTabView* pView = pViewData->GetView();
+ ScAddress aScAddress(nCol, nRow, nTab);
+ pView->CreateAnchorHandles(aHdl, aScAddress);
+ }
+ }
+}
+
+void ScDrawView::InvalidateAttribs()
+{
+ if (!pViewData) return;
+ SfxBindings& rBindings = pViewData->GetBindings();
+
+ // echte Statuswerte:
+ rBindings.InvalidateAll( sal_True );
+}
+
+void ScDrawView::InvalidateDrawTextAttrs()
+{
+ if (!pViewData) return;
+ SfxBindings& rBindings = pViewData->GetBindings();
+
+ // cjk/ctl font items have no configured slots,
+ // need no invalidate
+
+ rBindings.Invalidate( SID_ATTR_CHAR_FONT );
+ rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
+ rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
+ rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
+ rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
+ rBindings.Invalidate( SID_ULINE_VAL_NONE );
+ rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
+ rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
+ rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
+ rBindings.Invalidate( SID_ATTR_CHAR_OVERLINE );
+ rBindings.Invalidate( SID_ATTR_CHAR_COLOR );
+ rBindings.Invalidate( SID_ALIGNLEFT );
+ rBindings.Invalidate( SID_ALIGNCENTERHOR );
+ rBindings.Invalidate( SID_ALIGNRIGHT );
+ rBindings.Invalidate( SID_ALIGNBLOCK );
+ rBindings.Invalidate( SID_ATTR_PARA_LINESPACE_10 );
+ rBindings.Invalidate( SID_ATTR_PARA_LINESPACE_15 );
+ rBindings.Invalidate( SID_ATTR_PARA_LINESPACE_20 );
+ rBindings.Invalidate( SID_SET_SUPER_SCRIPT );
+ rBindings.Invalidate( SID_SET_SUB_SCRIPT );
+ rBindings.Invalidate( SID_TEXTDIRECTION_LEFT_TO_RIGHT );
+ rBindings.Invalidate( SID_TEXTDIRECTION_TOP_TO_BOTTOM );
+ rBindings.Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
+ rBindings.Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
+ // pseudo slots for Format menu
+ rBindings.Invalidate( SID_ALIGN_ANY_LEFT );
+ rBindings.Invalidate( SID_ALIGN_ANY_HCENTER );
+ rBindings.Invalidate( SID_ALIGN_ANY_RIGHT );
+ rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED );
+}
+
+//void ScDrawView::DrawMarks( OutputDevice* pOut ) const
+//{
+// DBG_ASSERT(pOut, "ScDrawView::DrawMarks: No OutputDevice (!)");
+// SdrPaintWindow* pPaintWindow = FindPaintWindow(*pOut);
+//
+// if(pPaintWindow)
+// {
+// if(pPaintWindow->isXorVisible())
+// {
+// ToggleShownXor(pOut, 0L);
+// }
+// }
+//}
+
+void ScDrawView::SetMarkedToLayer( sal_uInt8 nLayerNo )
+{
+ if (AreObjectsMarked())
+ {
+ // #i11702# use SdrUndoObjectLayerChange for undo
+ // STR_UNDO_SELATTR is "Attributes" - should use a different text later
+ BegUndo( ScGlobal::GetRscString( STR_UNDO_SELATTR ) );
+
+ const SdrMarkList& rMark = GetMarkedObjectList();
+ sal_uLong nCount = rMark.GetMarkCount();
+ for (sal_uLong i=0; i<nCount; i++)
+ {
+ SdrObject* pObj = rMark.GetMark(i)->GetMarkedSdrObj();
+ if ( !pObj->ISA(SdrUnoObj) && (pObj->GetLayer() != SC_LAYER_INTERN) )
+ {
+ AddUndo( new SdrUndoObjectLayerChange( *pObj, pObj->GetLayer(), (SdrLayerID)nLayerNo) );
+ pObj->SetLayer( nLayerNo );
+ }
+ }
+
+ EndUndo();
+
+ // repaint is done in SetLayer
+
+ pViewData->GetDocShell()->SetDrawModified();
+
+ // #84073# check mark list now instead of later in a timer
+ CheckMarked();
+ MarkListHasChanged();
+ }
+}
+
+bool ScDrawView::HasMarkedControl() const
+{
+ SdrObjListIter aIter( GetMarkedObjectList() );
+ for( SdrObject* pObj = aIter.Next(); pObj; pObj = aIter.Next() )
+ if( pObj->ISA( SdrUnoObj ) )
+ return true;
+ return false;
+}
+
+bool ScDrawView::HasMarkedInternal() const
+{
+ // internal objects should not be inside a group, but who knows...
+ SdrObjListIter aIter( GetMarkedObjectList() );
+ for( SdrObject* pObj = aIter.Next(); pObj; pObj = aIter.Next() )
+ if( pObj->GetLayer() == SC_LAYER_INTERN )
+ return true;
+ return false;
+}
+
+void ScDrawView::UpdateWorkArea()
+{
+ SdrPage* pPage = GetModel()->GetPage(static_cast<sal_uInt16>(nTab));
+ if (pPage)
+ {
+ Point aPos;
+ Size aPageSize( pPage->GetSize() );
+ Rectangle aNewArea( aPos, aPageSize );
+ if ( aPageSize.Width() < 0 )
+ {
+ // RTL: from max.negative (left) to zero (right)
+ aNewArea.Right() = 0;
+ aNewArea.Left() = aPageSize.Width() + 1;
+ }
+ SetWorkArea( aNewArea );
+ }
+ else
+ {
+ DBG_ERROR("Page nicht gefunden");
+ }
+}
+
+void ScDrawView::DoCut()
+{
+ DoCopy();
+ BegUndo( ScGlobal::GetRscString( STR_UNDO_CUT ) );
+ DeleteMarked(); // auf dieser View - von der 505f Umstellung nicht betroffen
+ EndUndo();
+}
+
+void ScDrawView::GetScale( Fraction& rFractX, Fraction& rFractY ) const
+{
+ rFractX = aScaleX;
+ rFractY = aScaleY;
+}
+
+void ScDrawView::RecalcScale()
+{
+ double nPPTX;
+ double nPPTY;
+ Fraction aZoomX(1,1);
+ Fraction aZoomY(1,1);
+
+ if (pViewData)
+ {
+ nTab = pViewData->GetTabNo();
+ nPPTX = pViewData->GetPPTX();
+ nPPTY = pViewData->GetPPTY();
+ aZoomX = pViewData->GetZoomX();
+ aZoomY = pViewData->GetZoomY();
+ }
+ else
+ {
+ Point aLogic = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
+ nPPTX = aLogic.X() / 1000.0;
+ nPPTY = aLogic.Y() / 1000.0;
+ //! Zoom uebergeben ???
+ }
+
+ SCCOL nEndCol = 0;
+ SCROW nEndRow = 0;
+ pDoc->GetTableArea( nTab, nEndCol, nEndRow );
+ if (nEndCol<20)
+ nEndCol = 20;
+ if (nEndRow<20)
+ nEndRow = 1000;
+
+ ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, pDev,aZoomX,aZoomY,nPPTX,nPPTY,
+ aScaleX,aScaleY );
+}
+
+void ScDrawView::DoConnect(SdrOle2Obj* pOleObj)
+{
+ if ( pViewData )
+ pViewData->GetViewShell()->ConnectObject( pOleObj );
+}
+
+void ScDrawView::MarkListHasChanged()
+{
+ FmFormView::MarkListHasChanged();
+
+ UpdateBrowser();
+
+ ScTabViewShell* pViewSh = pViewData->GetViewShell();
+
+ // #i110829# remove the cell selection only if drawing objects are selected
+ if ( !bInConstruct && GetMarkedObjectList().GetMarkCount() )
+ {
+ pViewSh->Unmark(); // remove cell selection
+
+ // #65379# end cell edit mode if drawing objects are selected
+ SC_MOD()->InputEnterHandler();
+ }
+
+ // IP deaktivieren
+
+ ScModule* pScMod = SC_MOD();
+ bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF;
+
+ ScClient* pClient = (ScClient*) pViewSh->GetIPClient();
+ if ( pClient && pClient->IsObjectInPlaceActive() && !bUnoRefDialog )
+ {
+ // #41730# beim ViewShell::Activate aus dem Reset2Open nicht die Handles anzeigen
+ //HMHbDisableHdl = sal_True;
+ pClient->DeactivateObject();
+ //HMHbDisableHdl = sal_False;
+ // Image-Ole wieder durch Grafik ersetzen passiert jetzt in ScClient::UIActivate
+ }
+
+ // Ole-Objekt selektiert?
+
+ SdrOle2Obj* pOle2Obj = NULL;
+ SdrGrafObj* pGrafObj = NULL;
+ SdrMediaObj* pMediaObj = NULL;
+
+ const SdrMarkList& rMarkList = GetMarkedObjectList();
+ sal_uLong nMarkCount = rMarkList.GetMarkCount();
+
+ if ( nMarkCount == 0 && !pViewData->GetViewShell()->IsDrawSelMode() && !bInConstruct )
+ {
+ // relock layers that may have been unlocked before
+ LockBackgroundLayer();
+ LockInternalLayer();
+ }
+
+ sal_Bool bSubShellSet = sal_False;
+ if (nMarkCount == 1)
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ if (pObj->GetObjIdentifier() == OBJ_OLE2)
+ {
+ pOle2Obj = (SdrOle2Obj*) pObj;
+ if (!pDoc->IsChart(pObj) )
+ pViewSh->SetOleObjectShell(sal_True);
+ else
+ pViewSh->SetChartShell(sal_True);
+ bSubShellSet = sal_True;
+ }
+ else if (pObj->GetObjIdentifier() == OBJ_GRAF)
+ {
+ pGrafObj = (SdrGrafObj*) pObj;
+ pViewSh->SetGraphicShell(sal_True);
+ bSubShellSet = sal_True;
+ }
+ else if (pObj->GetObjIdentifier() == OBJ_MEDIA)
+ {
+ pMediaObj = (SdrMediaObj*) pObj;
+ pViewSh->SetMediaShell(sal_True);
+ bSubShellSet = sal_True;
+ }
+ else if (pObj->GetObjIdentifier() != OBJ_TEXT // Verhindern, das beim Anlegen
+ || !pViewSh->IsDrawTextShell()) // eines TextObjekts auf die
+ { // DrawShell umgeschaltet wird.
+ pViewSh->SetDrawShell(sal_True); //@#70206#
+ }
+ }
+
+ if ( nMarkCount && !bSubShellSet )
+ {
+ sal_Bool bOnlyControls = sal_True;
+ sal_Bool bOnlyGraf = sal_True;
+ for (sal_uLong i=0; i<nMarkCount; i++)
+ {
+ SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
+ if ( pObj->ISA( SdrObjGroup ) )
+ {
+ const SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList();
+ sal_uLong nListCount = pLst->GetObjCount();
+ if ( nListCount == 0 )
+ {
+ // #104156# An empty group (may occur during Undo) is no control or graphics object.
+ // Creating the form shell during undo would lead to problems with the undo manager.
+ bOnlyControls = sal_False;
+ bOnlyGraf = sal_False;
+ }
+ for ( sal_uInt16 j = 0; j < nListCount; ++j )
+ {
+ SdrObject *pSubObj = pLst->GetObj( j );
+
+ if (!pSubObj->ISA(SdrUnoObj))
+ bOnlyControls = sal_False;
+ if (pSubObj->GetObjIdentifier() != OBJ_GRAF)
+ bOnlyGraf = sal_False;
+
+ if ( !bOnlyControls && !bOnlyGraf ) break;
+ }
+ }
+ else
+ {
+ if (!pObj->ISA(SdrUnoObj))
+ bOnlyControls = sal_False;
+ if (pObj->GetObjIdentifier() != OBJ_GRAF)
+ bOnlyGraf = sal_False;
+ }
+
+ if ( !bOnlyControls && !bOnlyGraf ) break;
+ }
+
+ if(bOnlyControls)
+ {
+ pViewSh->SetDrawFormShell(sal_True); // jetzt UNO-Controls
+ }
+ else if(bOnlyGraf)
+ {
+ pViewSh->SetGraphicShell(sal_True);
+ }
+ else if(nMarkCount>1)
+ {
+ pViewSh->SetDrawShell(sal_True);
+ }
+ }
+
+
+
+ // Verben anpassen
+
+ SfxViewFrame* pViewFrame = pViewSh->GetViewFrame();
+ sal_Bool bOle = pViewSh->GetViewFrame()->GetFrame().IsInPlace();
+ uno::Sequence< embed::VerbDescriptor > aVerbs;
+ if ( pOle2Obj && !bOle )
+ {
+ uno::Reference < embed::XEmbeddedObject > xObj = pOle2Obj->GetObjRef();
+ DBG_ASSERT( xObj.is(), "SdrOle2Obj ohne ObjRef" );
+ if (xObj.is())
+ aVerbs = xObj->getSupportedVerbs();
+ }
+ pViewSh->SetVerbs( aVerbs );
+
+ // Image-Map Editor
+
+ if ( pOle2Obj )
+ UpdateIMap( pOle2Obj );
+ else if ( pGrafObj )
+ UpdateIMap( pGrafObj );
+
+ InvalidateAttribs(); // nach dem IMap-Editor Update
+ InvalidateDrawTextAttrs();
+
+ for(sal_uInt32 a(0L); a < PaintWindowCount(); a++)
+ {
+ SdrPaintWindow* pPaintWindow = GetPaintWindow(a);
+ OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
+
+ if(OUTDEV_WINDOW == rOutDev.GetOutDevType())
+ {
+ ((Window&)rOutDev).Update();
+ }
+ }
+
+ // uno object for view returns drawing objects as selection,
+ // so it must notify its SelectionChangeListeners
+
+ if (pViewFrame)
+ {
+ SfxFrame& rFrame = pViewFrame->GetFrame();
+ uno::Reference<frame::XController> xController = rFrame.GetController();
+ if (xController.is())
+ {
+ ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
+ if (pImp)
+ pImp->SelectionChanged();
+ }
+ }
+
+ // update selection transfer object
+
+ pViewSh->CheckSelectionTransfer();
+
+}
+
+void __EXPORT ScDrawView::ModelHasChanged()
+{
+ SdrObject* pEditObj = GetTextEditObject();
+ if ( pEditObj && !pEditObj->IsInserted() && pViewData )
+ {
+ // #111700# SdrObjEditView::ModelHasChanged will end text edit in this case,
+ // so make sure the EditEngine's undo manager is no longer used.
+ pViewData->GetViewShell()->SetDrawTextUndo(NULL);
+ SetCreateMode(); // don't leave FuText in a funny state
+ }
+
+ FmFormView::ModelHasChanged();
+}
+
+void __EXPORT ScDrawView::UpdateUserViewOptions()
+{
+ if (pViewData)
+ {
+ const ScViewOptions& rOpt = pViewData->GetOptions();
+ const ScGridOptions& rGrid = rOpt.GetGridOptions();
+
+ sal_Bool bBigHdl = rOpt.GetOption( VOPT_BIGHANDLES );
+
+ SetDragStripes( rOpt.GetOption( VOPT_HELPLINES ) );
+ SetSolidMarkHdl( rOpt.GetOption( VOPT_SOLIDHANDLES ) );
+ SetMarkHdlSizePixel( bBigHdl ? SC_HANDLESIZE_BIG : SC_HANDLESIZE_SMALL );
+
+ SetGridVisible( rGrid.GetGridVisible() );
+ SetSnapEnabled( rGrid.GetUseGridSnap() );
+ SetGridSnap( rGrid.GetUseGridSnap() );
+
+ // Snap from grid options is no longer used
+// SetSnapGrid( Size( rGrid.GetFldSnapX(), rGrid.GetFldSnapY() ) );
+
+ Fraction aFractX( rGrid.GetFldDrawX(), rGrid.GetFldDivisionX() + 1 );
+ Fraction aFractY( rGrid.GetFldDrawY(), rGrid.GetFldDivisionY() + 1 );
+ SetSnapGridWidth( aFractX, aFractY );
+
+ SetGridCoarse( Size( rGrid.GetFldDrawX(), rGrid.GetFldDrawY() ) );
+ SetGridFine( Size( rGrid.GetFldDrawX() / (rGrid.GetFldDivisionX() + 1),
+ rGrid.GetFldDrawY() / (rGrid.GetFldDivisionY() + 1) ) );
+ }
+}
+
+#ifdef _MSC_VER
+#pragma optimize ( "", on )
+#endif
+
+sal_Bool ScDrawView::SelectObject( const String& rName )
+{
+ UnmarkAll();
+
+ SCTAB nObjectTab = 0;
+ SdrObject* pFound = NULL;
+
+ SfxObjectShell* pShell = pDoc->GetDocumentShell();
+ if (pShell)
+ {
+ SdrModel* pDrawLayer = GetModel();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount && !pFound; i++)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(i));
+ DBG_ASSERT(pPage,"Page ?");
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject && !pFound)
+ {
+ if ( ScDrawLayer::GetVisibleName( pObject ) == rName )
+ {
+ pFound = pObject;
+ nObjectTab = i;
+ }
+ pObject = aIter.Next();
+ }
+ }
+ }
+ }
+
+ if ( pFound )
+ {
+ ScTabView* pView = pViewData->GetView();
+ if ( nObjectTab != nTab ) // Tabelle umschalten
+ pView->SetTabNo( nObjectTab );
+
+ DBG_ASSERT( nTab == nObjectTab, "Tabellen umschalten hat nicht geklappt" );
+
+ pView->ScrollToObject( pFound );
+
+ /* #61585# To select an object on the background layer, the layer has to
+ be unlocked even if exclusive drawing selection mode is not active
+ (this is reversed in MarkListHasChanged when nothing is selected) */
+ if ( pFound->GetLayer() == SC_LAYER_BACK &&
+ !pViewData->GetViewShell()->IsDrawSelMode() &&
+ !pDoc->IsTabProtected( nTab ) &&
+ !pViewData->GetSfxDocShell()->IsReadOnly() )
+ {
+ UnlockBackgroundLayer();
+ }
+
+ SdrPageView* pPV = GetSdrPageView();
+ MarkObj( pFound, pPV );
+ }
+
+ return ( pFound != NULL );
+}
+
+//UNUSED2008-05 String ScDrawView::GetSelectedChartName() const
+//UNUSED2008-05 {
+//UNUSED2008-05 // used for modifying a chart's data area - PersistName must always be used
+//UNUSED2008-05 // (as in ScDocument::FindChartData and UpdateChartArea)
+//UNUSED2008-05
+//UNUSED2008-05 const SdrMarkList& rMarkList = GetMarkedObjectList();
+//UNUSED2008-05 if (rMarkList.GetMarkCount() == 1)
+//UNUSED2008-05 {
+//UNUSED2008-05 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+//UNUSED2008-05 if (pObj->GetObjIdentifier() == OBJ_OLE2)
+//UNUSED2008-05 if ( pDoc->IsChart(pObj) )
+//UNUSED2008-05 return static_cast<SdrOle2Obj*>(pObj)->GetPersistName();
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 return EMPTY_STRING; // nichts gefunden
+//UNUSED2008-05 }
+
+FASTBOOL ScDrawView::InsertObjectSafe(SdrObject* pObj, SdrPageView& rPV, sal_uLong nOptions)
+{
+ // Markierung nicht aendern, wenn Ole-Objekt aktiv
+ // (bei Drop aus Ole-Objekt wuerde sonst mitten im ExecuteDrag deaktiviert!)
+
+ if (pViewData)
+ {
+ SfxInPlaceClient* pClient = pViewData->GetViewShell()->GetIPClient();
+ if ( pClient && pClient->IsObjectInPlaceActive() )
+ nOptions |= SDRINSERT_DONTMARK;
+ }
+
+ return InsertObjectAtView( pObj, rPV, nOptions );
+}
+
+SdrObject* ScDrawView::GetMarkedNoteCaption( ScDrawObjData** ppCaptData )
+{
+ const SdrMarkList& rMarkList = GetMarkedObjectList();
+ if( pViewData && (rMarkList.GetMarkCount() == 1) )
+ {
+ SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ if( ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObj, pViewData->GetTabNo() ) )
+ {
+ if( ppCaptData ) *ppCaptData = pCaptData;
+ return pObj;
+ }
+ }
+ return 0;
+}
+
+void ScDrawView::LockCalcLayer( SdrLayerID nLayer, bool bLock )
+{
+ SdrLayer* pLockLayer = GetModel()->GetLayerAdmin().GetLayerPerID( nLayer );
+ if( pLockLayer && (IsLayerLocked( pLockLayer->GetName() ) != bLock) )
+ SetLayerLocked( pLockLayer->GetName(), bLock );
+}
+
+void __EXPORT ScDrawView::MakeVisible( const Rectangle& rRect, Window& rWin )
+{
+ //! rWin richtig auswerten
+ //! ggf Zoom aendern
+
+ if ( pViewData && pViewData->GetActiveWin() == &rWin )
+ pViewData->GetView()->MakeVisible( rRect );
+}
+
+void ScDrawView::DeleteMarked()
+{
+ // try to delete a note caption object with its cell note in the Calc document
+ ScDrawObjData* pCaptData = 0;
+ if( SdrObject* pCaptObj = GetMarkedNoteCaption( &pCaptData ) )
+ {
+ (void)pCaptObj; // prevent 'unused variable' compiler warning in pro builds
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ ScDocShell* pDocShell = pViewData ? pViewData->GetDocShell() : 0;
+ ::svl::IUndoManager* pUndoMgr = pDocShell ? pDocShell->GetUndoManager() : 0;
+ bool bUndo = pDrawLayer && pDocShell && pUndoMgr && pDoc->IsUndoEnabled();
+
+ // remove the cell note from document, we are its owner now
+ ScPostIt* pNote = pDoc->ReleaseNote( pCaptData->maStart );
+ DBG_ASSERT( pNote, "ScDrawView::DeleteMarked - cell note missing in document" );
+ if( pNote )
+ {
+ // rescue note data for undo (with pointer to caption object)
+ ScNoteData aNoteData = pNote->GetNoteData();
+ DBG_ASSERT( aNoteData.mpCaption == pCaptObj, "ScDrawView::DeleteMarked - caption object does not match" );
+ // collect the drawing undo action created while deleting the note
+ if( bUndo )
+ pDrawLayer->BeginCalcUndo();
+ // delete the note (already removed from document above)
+ delete pNote;
+ // add the undo action for the note
+ if( bUndo )
+ pUndoMgr->AddUndoAction( new ScUndoReplaceNote( *pDocShell, pCaptData->maStart, aNoteData, false, pDrawLayer->GetCalcUndo() ) );
+ // repaint the cell to get rid of the note marker
+ if( pDocShell )
+ pDocShell->PostPaintCell( pCaptData->maStart );
+ // done, return now to skip call of FmFormView::DeleteMarked()
+ return;
+ }
+ }
+
+ FmFormView::DeleteMarked();
+}
+
+SdrEndTextEditKind ScDrawView::ScEndTextEdit()
+{
+ sal_Bool bIsTextEdit = IsTextEdit();
+ SdrEndTextEditKind eKind = SdrEndTextEdit();
+
+ if ( bIsTextEdit && pViewData )
+ pViewData->GetViewShell()->SetDrawTextUndo(NULL); // "normaler" Undo-Manager
+
+ return eKind;
+}
+
+void ScDrawView::MarkDropObj( SdrObject* pObj )
+{
+ if ( pDropMarkObj != pObj )
+ {
+ pDropMarkObj = pObj;
+ ImplClearCalcDropMarker();
+
+ if(pDropMarkObj)
+ {
+ pDropMarker = new SdrDropMarkerOverlay(*this, *pDropMarkObj);
+ }
+ }
+}
+
+//UNUSED2009-05 void ScDrawView::CaptionTextDirection( sal_uInt16 nSlot )
+//UNUSED2009-05 {
+//UNUSED2009-05 if(nSlot != SID_TEXTDIRECTION_LEFT_TO_RIGHT && nSlot != SID_TEXTDIRECTION_TOP_TO_BOTTOM)
+//UNUSED2009-05 return;
+//UNUSED2009-05
+//UNUSED2009-05 SdrObject* pObject = GetTextEditObject();
+//UNUSED2009-05 if ( ScDrawLayer::IsNoteCaption( pObject ) )
+//UNUSED2009-05 {
+//UNUSED2009-05 if( SdrCaptionObj* pCaption = dynamic_cast< SdrCaptionObj* >( pObject ) )
+//UNUSED2009-05 {
+//UNUSED2009-05 SfxItemSet aAttr(pCaption->GetMergedItemSet());
+//UNUSED2009-05 aAttr.Put( SvxWritingModeItem(
+//UNUSED2009-05 nSlot == SID_TEXTDIRECTION_LEFT_TO_RIGHT ?
+//UNUSED2009-05 com::sun::star::text::WritingMode_LR_TB : com::sun::star::text::WritingMode_TB_RL,
+//UNUSED2009-05 SDRATTR_TEXTDIRECTION ) );
+//UNUSED2009-05 pCaption->SetMergedItemSet(aAttr);
+//UNUSED2009-05 FuPoor* pPoor = pViewData->GetView()->GetDrawFuncPtr();
+//UNUSED2009-05 if ( pPoor )
+//UNUSED2009-05 {
+//UNUSED2009-05 FuText* pText = static_cast<FuText*>(pPoor);
+//UNUSED2009-05 pText->StopEditMode(sal_True);
+//UNUSED2009-05 }
+//UNUSED2009-05 }
+//UNUSED2009-05 }
+//UNUSED2009-05 }
diff --git a/sc/source/ui/view/editsh.cxx b/sc/source/ui/view/editsh.cxx
new file mode 100644
index 000000000000..e07e15267198
--- /dev/null
+++ b/sc/source/ui/view/editsh.cxx
@@ -0,0 +1,1206 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include <com/sun/star/linguistic2/XThesaurus.hpp>
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <svx/clipfmtitem.hxx>
+#include <svx/svxdlg.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/unolingu.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/fontitem.hxx>
+#include <svx/hlnkitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <svl/srchitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/msg.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sot/exchange.hxx>
+#include <svtools/cliplistener.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/sound.hxx>
+#include <sot/formats.hxx>
+#include <svtools/transfer.hxx>
+#include <svl/stritem.hxx>
+
+#define _EDITSH_CXX
+#include "editsh.hxx"
+
+#include "scresid.hxx"
+#include "global.hxx"
+#include "sc.hrc"
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+#include "viewutil.hxx"
+#include "viewdata.hxx"
+#include "document.hxx"
+//CHINA001 #include "namepast.hxx"
+#include "reffind.hxx"
+#include "tabvwsh.hxx"
+//CHINA001 #include "textdlgs.hxx"
+#include "editutil.hxx"
+#include "globstr.hrc"
+
+#define ScEditShell
+#include "scslots.hxx"
+
+#include "scui_def.hxx" //CHINA001
+#include "scabstdlg.hxx" //CHINA001
+
+
+using namespace ::com::sun::star;
+
+
+TYPEINIT1( ScEditShell, SfxShell );
+
+SFX_IMPL_INTERFACE(ScEditShell, SfxShell, ScResId(SCSTR_EDITSHELL))
+{
+ SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_EDIT) );
+}
+
+
+ScEditShell::ScEditShell(EditView* pView, ScViewData* pData) :
+ pEditView (pView),
+ pViewData (pData),
+ pClipEvtLstnr (NULL),
+ bPastePossible (sal_False),
+ bIsInsertMode (sal_True)
+{
+ SetPool( pEditView->GetEditEngine()->GetEmptyItemSet().GetPool() );
+ SetUndoManager( &pEditView->GetEditEngine()->GetUndoManager() );
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("EditCell")));
+}
+
+ScEditShell::~ScEditShell()
+{
+ if ( pClipEvtLstnr )
+ {
+ pClipEvtLstnr->AddRemoveListener( pViewData->GetActiveWin(), sal_False );
+
+ // #122057# The listener may just now be waiting for the SolarMutex and call the link
+ // afterwards, in spite of RemoveListener. So the link has to be reset, too.
+ pClipEvtLstnr->ClearCallbackLink();
+
+ pClipEvtLstnr->release();
+ }
+}
+
+ScInputHandler* ScEditShell::GetMyInputHdl()
+{
+ return SC_MOD()->GetInputHdl( pViewData->GetViewShell() );
+}
+
+void ScEditShell::SetEditView(EditView* pView)
+{
+ pEditView = pView;
+ pEditView->SetInsertMode( bIsInsertMode );
+ SetPool( pEditView->GetEditEngine()->GetEmptyItemSet().GetPool() );
+ SetUndoManager( &pEditView->GetEditEngine()->GetUndoManager() );
+}
+
+void lcl_RemoveAttribs( EditView& rEditView )
+{
+ ScEditEngineDefaulter* pEngine = static_cast<ScEditEngineDefaulter*>(rEditView.GetEditEngine());
+
+ sal_Bool bOld = pEngine->GetUpdateMode();
+ pEngine->SetUpdateMode(sal_False);
+
+ String aName = ScGlobal::GetRscString( STR_UNDO_DELETECONTENTS );
+ pEngine->GetUndoManager().EnterListAction( aName, aName );
+
+ rEditView.RemoveAttribs(sal_True);
+ pEngine->RepeatDefaults(); // #97226# paragraph attributes from cell formats must be preserved
+
+ pEngine->GetUndoManager().LeaveListAction();
+
+ pEngine->SetUpdateMode(bOld);
+}
+
+void lclInsertCharacter( EditView* pTableView, EditView* pTopView, sal_Unicode cChar )
+{
+ String aString( cChar );
+ if( pTableView )
+ pTableView->InsertText( aString );
+ if( pTopView )
+ pTopView->InsertText( aString );
+}
+
+void ScEditShell::Execute( SfxRequest& rReq )
+{
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ sal_uInt16 nSlot = rReq.GetSlot();
+ SfxBindings& rBindings = pViewData->GetBindings();
+
+ ScInputHandler* pHdl = GetMyInputHdl();
+ DBG_ASSERT(pHdl,"kein ScInputHandler");
+
+ EditView* pTopView = pHdl->GetTopView(); // hat Eingabezeile den Focus?
+ EditView* pTableView = pHdl->GetTableView();
+
+ DBG_ASSERT(pTableView,"no EditView :-(");
+ /* #i91683# No EditView if spell-check dialog is active and positioned on
+ * an error and user immediately (without double click or F2) selected a
+ * text portion of that cell with the mouse and wanted to modify it. */
+ /* FIXME: Bailing out only cures the symptom and prevents a crash, no edit
+ * action is possible. A real fix somehow would need to create a valid
+ * EditView from the spell-check view. */
+ if (!pTableView)
+ return;
+
+ EditEngine* pEngine = pTableView->GetEditEngine();
+
+ pHdl->DataChanging();
+ sal_Bool bSetSelIsRef = sal_False;
+
+ switch ( nSlot )
+ {
+ case FID_INS_CELL_CONTENTS: // Insert-Taste, weil als Acc definiert
+ bIsInsertMode = !pTableView->IsInsertMode();
+ pTableView->SetInsertMode( bIsInsertMode );
+ if (pTopView)
+ pTopView->SetInsertMode( bIsInsertMode );
+ rBindings.Invalidate( SID_ATTR_INSERT );
+ break;
+
+ case SID_ATTR_INSERT:
+ if ( pReqArgs )
+ {
+ bIsInsertMode = ((const SfxBoolItem&)pReqArgs->Get(nSlot)).GetValue();
+ pTableView->SetInsertMode( bIsInsertMode );
+ if (pTopView)
+ pTopView->SetInsertMode( bIsInsertMode );
+ rBindings.Invalidate( SID_ATTR_INSERT );
+ }
+ break;
+
+ case SID_THES:
+ {
+ String aReplaceText;
+ SFX_REQUEST_ARG( rReq, pItem2, SfxStringItem, SID_THES , sal_False );
+ if (pItem2)
+ aReplaceText = pItem2->GetValue();
+ if (aReplaceText.Len() > 0)
+ ReplaceTextWithSynonym( *pEditView, aReplaceText );
+ }
+ break;
+
+ case SID_COPY:
+ pTableView->Copy();
+ break;
+
+ case SID_CUT:
+ pTableView->Cut();
+ if (pTopView)
+ pTopView->DeleteSelected();
+ break;
+
+ case SID_PASTE:
+ pTableView->PasteSpecial();
+ if (pTopView)
+ pTopView->Paste();
+ break;
+
+ case SID_DELETE:
+ pTableView->DeleteSelected();
+ if (pTopView)
+ pTopView->DeleteSelected();
+ break;
+
+ case SID_CELL_FORMAT_RESET: // "Standard"
+ lcl_RemoveAttribs( *pTableView );
+ if ( pTopView )
+ lcl_RemoveAttribs( *pTopView );
+ break;
+
+ case SID_CLIPBOARD_FORMAT_ITEMS:
+ {
+ sal_uLong nFormat = 0;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs &&
+ pReqArgs->GetItemState(nSlot, sal_True, &pItem) == SFX_ITEM_SET &&
+ pItem->ISA(SfxUInt32Item) )
+ {
+ nFormat = ((const SfxUInt32Item*)pItem)->GetValue();
+ }
+
+ if ( nFormat )
+ {
+ if (SOT_FORMAT_STRING == nFormat)
+ pTableView->Paste();
+ else
+ pTableView->PasteSpecial();
+
+ if (pTopView)
+ pTopView->Paste();
+ }
+ }
+ break;
+
+ case SID_PASTE_SPECIAL:
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ SfxAbstractPasteDialog* pDlg = pFact->CreatePasteDialog( pViewData->GetDialogParent() );
+ sal_uLong nFormat = 0;
+ if ( pDlg )
+ {
+ pDlg->Insert( SOT_FORMAT_STRING, EMPTY_STRING );
+ pDlg->Insert( SOT_FORMAT_RTF, EMPTY_STRING );
+
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard( pViewData->GetActiveWin() ) );
+
+ nFormat = pDlg->GetFormat( aDataHelper.GetTransferable() );
+ DELETEZ(pDlg);
+ }
+
+ // while the dialog was open, edit mode may have been stopped
+ if (!SC_MOD()->IsInputMode())
+ {
+ Sound::Beep();
+ return;
+ }
+
+ if (nFormat > 0)
+ {
+ if (SOT_FORMAT_STRING == nFormat)
+ pTableView->Paste();
+ else
+ pTableView->PasteSpecial();
+
+ if (pTopView)
+ pTopView->Paste();
+ }
+
+ if (pTopView)
+ pTopView->GetWindow()->GrabFocus();
+ }
+ break;
+
+ case SID_SELECTALL:
+ {
+ sal_uInt16 nPar = pEngine->GetParagraphCount();
+ if (nPar)
+ {
+ xub_StrLen nLen = pEngine->GetTextLen(nPar-1);
+ pTableView->SetSelection(ESelection(0,0,nPar-1,nLen));
+ if (pTopView)
+ pTopView->SetSelection(ESelection(0,0,nPar-1,nLen));
+ }
+ }
+ break;
+
+ case SID_CHARMAP:
+ {
+ sal_uInt16 nScript = pTableView->GetSelectedScriptType();
+ sal_uInt16 nFontWhich = ( nScript == SCRIPTTYPE_ASIAN ) ? EE_CHAR_FONTINFO_CJK :
+ ( ( nScript == SCRIPTTYPE_COMPLEX ) ? EE_CHAR_FONTINFO_CTL :
+ EE_CHAR_FONTINFO );
+ const SvxFontItem& rItem = (const SvxFontItem&)
+ pTableView->GetAttribs().Get(nFontWhich);
+
+ String aString;
+ SvxFontItem aNewItem( EE_CHAR_FONTINFO );
+
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem = 0;
+ if( pArgs )
+ pArgs->GetItemState(GetPool().GetWhich(SID_CHARMAP), sal_False, &pItem);
+
+ if ( pItem )
+ {
+ aString = ((const SfxStringItem*)pItem)->GetValue();
+ const SfxPoolItem* pFtItem = NULL;
+ pArgs->GetItemState( GetPool().GetWhich(SID_ATTR_SPECIALCHAR), sal_False, &pFtItem);
+ const SfxStringItem* pFontItem = PTR_CAST( SfxStringItem, pFtItem );
+ if ( pFontItem )
+ {
+ String aFontName(pFontItem->GetValue());
+ Font aFont(aFontName, Size(1,1)); // Size nur wg. CTOR
+ aNewItem = SvxFontItem( aFont.GetFamily(), aFont.GetName(),
+ aFont.GetStyleName(), aFont.GetPitch(),
+ aFont.GetCharSet(), ATTR_FONT );
+ }
+ else
+ aNewItem = rItem;
+ }
+ else
+ {
+ ScViewUtil::ExecuteCharMap( rItem, *pViewData->GetViewShell()->GetViewFrame(), aNewItem, aString );
+
+ // while the dialog was open, edit mode may have been stopped
+ if (!SC_MOD()->IsInputMode())
+ {
+ Sound::Beep();
+ return;
+ }
+ }
+
+ if ( aString.Len() )
+ {
+ // if string contains WEAK characters, set all fonts
+ sal_uInt8 nSetScript;
+ ScDocument* pDoc = pViewData->GetDocument();
+ if ( pDoc->HasStringWeakCharacters( aString ) )
+ nSetScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
+ else
+ nSetScript = pDoc->GetStringScriptType( aString );
+
+ SfxItemSet aSet( pTableView->GetEmptyItemSet() );
+ SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, GetPool() );
+ aSetItem.PutItemForScriptType( nSetScript, aNewItem );
+ aSet.Put( aSetItem.GetItemSet(), sal_False );
+
+ // SetAttribs an der View selektiert ein Wort, wenn nichts selektiert ist
+ pTableView->GetEditEngine()->QuickSetAttribs( aSet, pTableView->GetSelection() );
+ pTableView->InsertText(aString);
+ if (pTopView)
+ pTopView->InsertText(aString);
+
+ SfxStringItem aStringItem( SID_CHARMAP, aString );
+ SfxStringItem aFontItem( SID_ATTR_SPECIALCHAR, aNewItem.GetFamilyName() );
+ rReq.AppendItem( aFontItem );
+ rReq.AppendItem( aStringItem );
+ rReq.Done();
+
+
+ }
+
+ if (pTopView)
+ pTopView->GetWindow()->GrabFocus();
+ }
+ break;
+
+ case FID_INSERT_NAME:
+ {
+ ScDocument* pDoc = pViewData->GetDocument();
+ //CHINA001 ScNamePasteDlg* pDlg = new ScNamePasteDlg( pViewData->GetDialogParent(),
+ //CHINA001 pDoc->GetRangeName(), sal_False );
+ // "Liste" disablen
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScNamePasteDlg* pDlg = pFact->CreateScNamePasteDlg( pViewData->GetDialogParent(), pDoc->GetRangeName(), RID_SCDLG_NAMES_PASTE, sal_False );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ short nRet = pDlg->Execute();
+ // pDlg is needed below
+
+ // while the dialog was open, edit mode may have been stopped
+ if (!SC_MOD()->IsInputMode())
+ {
+ Sound::Beep();
+ delete pDlg;
+ return;
+ }
+
+ if ( nRet == BTN_PASTE_NAME )
+ {
+ String aName = pDlg->GetSelectedName();
+ pTableView->InsertText(aName);
+ if (pTopView)
+ pTopView->InsertText(aName);
+ }
+ delete pDlg;
+
+ if (pTopView)
+ pTopView->GetWindow()->GrabFocus();
+ }
+ break;
+
+ case SID_CHAR_DLG:
+ {
+ SfxItemSet aAttrs( pTableView->GetAttribs() );
+
+ SfxObjectShell* pObjSh = pViewData->GetSfxDocShell();
+
+ //CHINA001 ScCharDlg* pDlg = new ScCharDlg( pViewData->GetDialogParent(), &aAttrs, pObjSh );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ SfxAbstractTabDialog* pDlg = pFact->CreateScCharDlg( pViewData->GetDialogParent(), &aAttrs,
+ pObjSh, RID_SCDLG_CHAR );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ short nRet = pDlg->Execute();
+ // pDlg is needed below
+
+ // while the dialog was open, edit mode may have been stopped
+ if (!SC_MOD()->IsInputMode())
+ {
+ Sound::Beep();
+ delete pDlg;
+ return;
+ }
+
+ if ( nRet == RET_OK )
+ {
+ const SfxItemSet* pOut = pDlg->GetOutputItemSet();
+ pTableView->SetAttribs( *pOut );
+ }
+ delete pDlg;
+ }
+ break;
+
+ case SID_TOGGLE_REL:
+ {
+ sal_Bool bOk = sal_False;
+ if (pEngine->GetParagraphCount() == 1)
+ {
+ String aText = pEngine->GetText();
+ ESelection aSel = pEditView->GetSelection(); // aktuelle View
+
+ ScRefFinder aFinder( aText, pViewData->GetDocument() );
+ aFinder.ToggleRel( aSel.nStartPos, aSel.nEndPos );
+ if (aFinder.GetFound())
+ {
+ String aNew = aFinder.GetText();
+ ESelection aNewSel( 0,aFinder.GetSelStart(), 0,aFinder.GetSelEnd() );
+ pEngine->SetText( aNew );
+ pTableView->SetSelection( aNewSel );
+ if ( pTopView )
+ {
+ pTopView->GetEditEngine()->SetText( aNew );
+ pTopView->SetSelection( aNewSel );
+ }
+ bOk = sal_True;
+
+ // Referenz wird selektiert -> beim Tippen nicht ueberschreiben
+ bSetSelIsRef = sal_True;
+ }
+ }
+ if (!bOk)
+ Sound::Beep(); // keine Referenzen oder mehrere Absaetze
+ }
+ break;
+
+ case SID_HYPERLINK_SETLINK:
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( SID_HYPERLINK_SETLINK, sal_True, &pItem ) == SFX_ITEM_SET )
+ {
+ const SvxHyperlinkItem* pHyper = (const SvxHyperlinkItem*) pItem;
+ const String& rName = pHyper->GetName();
+ const String& rURL = pHyper->GetURL();
+ const String& rTarget = pHyper->GetTargetFrame();
+ SvxLinkInsertMode eMode = pHyper->GetInsertMode();
+
+ sal_Bool bDone = sal_False;
+ if ( eMode == HLINK_DEFAULT || eMode == HLINK_FIELD )
+ {
+ const SvxURLField* pURLField = GetURLField();
+ if ( pURLField )
+ {
+ // altes Feld selektieren
+
+ ESelection aSel = pTableView->GetSelection();
+ aSel.Adjust();
+ aSel.nEndPara = aSel.nStartPara;
+ aSel.nEndPos = aSel.nStartPos + 1;
+ pTableView->SetSelection( aSel );
+
+ // neues Feld einfuegen
+
+ SvxURLField aURLField( rURL, rName, SVXURLFORMAT_REPR );
+ aURLField.SetTargetFrame( rTarget );
+ SvxFieldItem aURLItem( aURLField, EE_FEATURE_FIELD );
+ pTableView->InsertField( aURLItem );
+ pTableView->SetSelection( aSel ); // select inserted field
+
+ // #57254# jetzt doch auch Felder in der Top-View
+
+ if ( pTopView )
+ {
+ aSel = pTopView->GetSelection();
+ aSel.nEndPara = aSel.nStartPara;
+ aSel.nEndPos = aSel.nStartPos + 1;
+ pTopView->SetSelection( aSel );
+ pTopView->InsertField( aURLItem );
+ pTopView->SetSelection( aSel ); // select inserted field
+ }
+
+ bDone = sal_True;
+ }
+ }
+
+ if (!bDone)
+ {
+ pViewData->GetViewShell()->
+ InsertURL( rName, rURL, rTarget, (sal_uInt16) eMode );
+
+ // InsertURL an der ViewShell schaltet bei "Button"
+ // die EditShell ab, darum sofort return
+
+ return;
+ }
+ }
+ }
+ break;
+
+ case SID_OPEN_HYPERLINK:
+ {
+ const SvxURLField* pURLField = GetURLField();
+ if ( pURLField )
+ ScGlobal::OpenURL( pURLField->GetURL(), pURLField->GetTargetFrame() );
+ return;
+ }
+ //break;
+
+ case FN_INSERT_SOFT_HYPHEN:
+ lclInsertCharacter( pTableView, pTopView, CHAR_SHY );
+ break;
+ case FN_INSERT_HARDHYPHEN:
+ lclInsertCharacter( pTableView, pTopView, CHAR_NBHY );
+ break;
+ case FN_INSERT_HARD_SPACE:
+ lclInsertCharacter( pTableView, pTopView, CHAR_NBSP );
+ break;
+ case SID_INSERT_RLM:
+ lclInsertCharacter( pTableView, pTopView, CHAR_RLM );
+ break;
+ case SID_INSERT_LRM:
+ lclInsertCharacter( pTableView, pTopView, CHAR_LRM );
+ break;
+ case SID_INSERT_ZWSP:
+ lclInsertCharacter( pTableView, pTopView, CHAR_ZWSP );
+ break;
+ case SID_INSERT_ZWNBSP:
+ lclInsertCharacter( pTableView, pTopView, CHAR_ZWNBSP );
+ break;
+ }
+
+ pHdl->DataChanged();
+ if (bSetSelIsRef)
+ pHdl->SetSelIsRef(sal_True);
+}
+
+void lcl_DisableAll( SfxItemSet& rSet ) // disable all slots
+{
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ rSet.DisableItem( nWhich );
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void __EXPORT ScEditShell::GetState( SfxItemSet& rSet )
+{
+ // #125326# When deactivating the view, edit mode is stopped, but the EditShell is left active
+ // (a shell can't be removed from within Deactivate). In that state, the EditView isn't inserted
+ // into the EditEngine, so it can have an invalid selection and must not be used.
+ if ( !pViewData->HasEditView( pViewData->GetActivePart() ) )
+ {
+ lcl_DisableAll( rSet );
+ return;
+ }
+
+ ScInputHandler* pHdl = GetMyInputHdl();
+ EditView* pActiveView = pHdl ? pHdl->GetActiveView() : pEditView;
+
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ switch (nWhich)
+ {
+ case SID_ATTR_INSERT: // Statuszeile
+ {
+ if ( pActiveView )
+ rSet.Put( SfxBoolItem( nWhich, pActiveView->IsInsertMode() ) );
+ else
+ rSet.Put( SfxBoolItem( nWhich, 42 ) );
+ }
+ break;
+
+ case SID_HYPERLINK_GETLINK:
+ {
+ SvxHyperlinkItem aHLinkItem;
+ const SvxURLField* pURLField = GetURLField();
+ if ( pURLField )
+ {
+ aHLinkItem.SetName( pURLField->GetRepresentation() );
+ aHLinkItem.SetURL( pURLField->GetURL() );
+ aHLinkItem.SetTargetFrame( pURLField->GetTargetFrame() );
+ }
+ else if ( pActiveView )
+ {
+ // use selected text as name for urls
+ String sReturn = pActiveView->GetSelected();
+ sReturn.Erase(255);
+ sReturn.EraseTrailingChars();
+ aHLinkItem.SetName(sReturn);
+ }
+ rSet.Put(aHLinkItem);
+ }
+ break;
+
+ case SID_OPEN_HYPERLINK:
+ {
+ if ( !GetURLField() )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_TRANSLITERATE_HALFWIDTH:
+ case SID_TRANSLITERATE_FULLWIDTH:
+ case SID_TRANSLITERATE_HIRAGANA:
+ case SID_TRANSLITERATE_KATAGANA:
+ case SID_INSERT_RLM:
+ case SID_INSERT_LRM:
+ case SID_INSERT_ZWNBSP:
+ case SID_INSERT_ZWSP:
+ ScViewUtil::HideDisabledSlot( rSet, pViewData->GetBindings(), nWhich );
+ break;
+
+ case SID_THES:
+ {
+ String aStatusVal;
+ LanguageType nLang = LANGUAGE_NONE;
+ bool bIsLookUpWord = GetStatusValueForThesaurusFromContext( aStatusVal, nLang, *pActiveView );
+ rSet.Put( SfxStringItem( SID_THES, aStatusVal ) );
+
+ // disable thesaurus context menu entry if there is nothing to look up
+ sal_Bool bCanDoThesaurus = ScModule::HasThesaurusLanguage( nLang );
+ if (!bIsLookUpWord || !bCanDoThesaurus)
+ rSet.DisableItem( SID_THES );
+ }
+ break;
+
+
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+const SvxURLField* ScEditShell::GetURLField()
+{
+ ScInputHandler* pHdl = GetMyInputHdl();
+ EditView* pActiveView = pHdl ? pHdl->GetActiveView() : pEditView;
+ if ( pActiveView )
+ {
+ const SvxFieldItem* pFieldItem = pActiveView->GetFieldAtSelection();
+ if (pFieldItem)
+ {
+ const SvxFieldData* pField = pFieldItem->GetField();
+ if ( pField && pField->ISA(SvxURLField) )
+ return (const SvxURLField*)pField;
+ }
+ }
+
+ return NULL;
+}
+
+IMPL_LINK( ScEditShell, ClipboardChanged, TransferableDataHelper*, pDataHelper )
+{
+ if ( pDataHelper )
+ {
+ bPastePossible = ( pDataHelper->HasFormat( SOT_FORMAT_STRING ) || pDataHelper->HasFormat( SOT_FORMAT_RTF ) );
+
+ SfxBindings& rBindings = pViewData->GetBindings();
+ rBindings.Invalidate( SID_PASTE );
+ rBindings.Invalidate( SID_PASTE_SPECIAL );
+ rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
+ }
+ return 0;
+}
+
+void __EXPORT ScEditShell::GetClipState( SfxItemSet& rSet )
+{
+ if ( !pClipEvtLstnr )
+ {
+ // create listener
+ pClipEvtLstnr = new TransferableClipboardListener( LINK( this, ScEditShell, ClipboardChanged ) );
+ pClipEvtLstnr->acquire();
+ Window* pWin = pViewData->GetActiveWin();
+ pClipEvtLstnr->AddRemoveListener( pWin, sal_True );
+
+ // get initial state
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pViewData->GetActiveWin() ) );
+ bPastePossible = ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) || aDataHelper.HasFormat( SOT_FORMAT_RTF ) );
+ }
+
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ switch (nWhich)
+ {
+ case SID_PASTE:
+ case SID_PASTE_SPECIAL:
+ if( !bPastePossible )
+ rSet.DisableItem( nWhich );
+ break;
+ case SID_CLIPBOARD_FORMAT_ITEMS:
+ if( bPastePossible )
+ {
+ SvxClipboardFmtItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS );
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard( pViewData->GetActiveWin() ) );
+
+ if ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) )
+ aFormats.AddClipbrdFormat( SOT_FORMAT_STRING );
+ if ( aDataHelper.HasFormat( SOT_FORMAT_RTF ) )
+ aFormats.AddClipbrdFormat( SOT_FORMAT_RTF );
+
+ rSet.Put( aFormats );
+ }
+ else
+ rSet.DisableItem( nWhich );
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void lcl_InvalidateUnder( SfxBindings& rBindings )
+{
+ rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
+ rBindings.Invalidate( SID_ULINE_VAL_NONE );
+ rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
+ rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
+ rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
+}
+
+void ScEditShell::ExecuteAttr(SfxRequest& rReq)
+{
+ SfxItemSet aSet( pEditView->GetEmptyItemSet() );
+ SfxBindings& rBindings = pViewData->GetBindings();
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ sal_uInt16 nSlot = rReq.GetSlot();
+
+ switch ( nSlot )
+ {
+ case SID_ATTR_CHAR_FONTHEIGHT:
+ case SID_ATTR_CHAR_FONT:
+ {
+ if (pArgs)
+ {
+ // #i78017 establish the same behaviour as in Writer
+ sal_uInt16 nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
+ if (nSlot == SID_ATTR_CHAR_FONT)
+ {
+ nScript = pEditView->GetSelectedScriptType();
+ if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType();
+ }
+
+ SfxItemPool& rPool = GetPool();
+ SvxScriptSetItem aSetItem( nSlot, rPool );
+ sal_uInt16 nWhich = rPool.GetWhich( nSlot );
+ aSetItem.PutItemForScriptType( nScript, pArgs->Get( nWhich ) );
+
+ aSet.Put( aSetItem.GetItemSet(), sal_False );
+ }
+ }
+ break;
+
+ case SID_ATTR_CHAR_COLOR:
+ {
+ if (pArgs)
+ {
+ aSet.Put( pArgs->Get( pArgs->GetPool()->GetWhich( nSlot ) ) );
+ rBindings.Invalidate( nSlot );
+ }
+ }
+ break;
+
+ // Toggles
+
+ case SID_ATTR_CHAR_WEIGHT:
+ {
+ // #i78017 establish the same behaviour as in Writer
+ sal_uInt16 nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
+
+ SfxItemPool& rPool = GetPool();
+
+ sal_Bool bOld = sal_False;
+ SvxScriptSetItem aOldSetItem( nSlot, rPool );
+ aOldSetItem.GetItemSet().Put( pEditView->GetAttribs(), sal_False );
+ const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript );
+ if ( pCore && ((const SvxWeightItem*)pCore)->GetWeight() > WEIGHT_NORMAL )
+ bOld = sal_True;
+
+ SvxScriptSetItem aSetItem( nSlot, rPool );
+ aSetItem.PutItemForScriptType( nScript,
+ SvxWeightItem( bOld ? WEIGHT_NORMAL : WEIGHT_BOLD, EE_CHAR_WEIGHT ) );
+ aSet.Put( aSetItem.GetItemSet(), sal_False );
+
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_ATTR_CHAR_POSTURE:
+ {
+ // #i78017 establish the same behaviour as in Writer
+ sal_uInt16 nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
+
+ SfxItemPool& rPool = GetPool();
+
+ sal_Bool bOld = sal_False;
+ SvxScriptSetItem aOldSetItem( nSlot, rPool );
+ aOldSetItem.GetItemSet().Put( pEditView->GetAttribs(), sal_False );
+ const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript );
+ if ( pCore && ((const SvxPostureItem*)pCore)->GetValue() != ITALIC_NONE )
+ bOld = sal_True;
+
+ SvxScriptSetItem aSetItem( nSlot, rPool );
+ aSetItem.PutItemForScriptType( nScript,
+ SvxPostureItem( bOld ? ITALIC_NONE : ITALIC_NORMAL, EE_CHAR_ITALIC ) );
+ aSet.Put( aSetItem.GetItemSet(), sal_False );
+
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_ULINE_VAL_NONE:
+ aSet.Put( SvxUnderlineItem( UNDERLINE_NONE, EE_CHAR_UNDERLINE ) );
+ lcl_InvalidateUnder( rBindings );
+ break;
+
+ case SID_ATTR_CHAR_UNDERLINE: // Toggles
+ case SID_ULINE_VAL_SINGLE:
+ case SID_ULINE_VAL_DOUBLE:
+ case SID_ULINE_VAL_DOTTED:
+ {
+ FontUnderline eOld = ((const SvxUnderlineItem&) pEditView->
+ GetAttribs().Get(EE_CHAR_UNDERLINE)).GetLineStyle();
+ FontUnderline eNew = eOld;
+ switch (nSlot)
+ {
+ case SID_ATTR_CHAR_UNDERLINE:
+ eNew = ( eOld != UNDERLINE_NONE ) ? UNDERLINE_NONE : UNDERLINE_SINGLE;
+ break;
+ case SID_ULINE_VAL_SINGLE:
+ eNew = ( eOld == UNDERLINE_SINGLE ) ? UNDERLINE_NONE : UNDERLINE_SINGLE;
+ break;
+ case SID_ULINE_VAL_DOUBLE:
+ eNew = ( eOld == UNDERLINE_DOUBLE ) ? UNDERLINE_NONE : UNDERLINE_DOUBLE;
+ break;
+ case SID_ULINE_VAL_DOTTED:
+ eNew = ( eOld == UNDERLINE_DOTTED ) ? UNDERLINE_NONE : UNDERLINE_DOTTED;
+ break;
+ }
+ aSet.Put( SvxUnderlineItem( eNew, EE_CHAR_UNDERLINE ) );
+ lcl_InvalidateUnder( rBindings );
+ }
+ break;
+
+ case SID_ATTR_CHAR_OVERLINE:
+ {
+ FontUnderline eOld = ((const SvxOverlineItem&) pEditView->
+ GetAttribs().Get(EE_CHAR_OVERLINE)).GetLineStyle();
+ FontUnderline eNew = ( eOld != UNDERLINE_NONE ) ? UNDERLINE_NONE : UNDERLINE_SINGLE;
+ aSet.Put( SvxOverlineItem( eNew, EE_CHAR_OVERLINE ) );
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_ATTR_CHAR_STRIKEOUT:
+ {
+ sal_Bool bOld = ((const SvxCrossedOutItem&)pEditView->GetAttribs().
+ Get(EE_CHAR_STRIKEOUT)).GetValue() != STRIKEOUT_NONE;
+ aSet.Put( SvxCrossedOutItem( bOld ? STRIKEOUT_NONE : STRIKEOUT_SINGLE, EE_CHAR_STRIKEOUT ) );
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_ATTR_CHAR_SHADOWED:
+ {
+ sal_Bool bOld = ((const SvxShadowedItem&)pEditView->GetAttribs().
+ Get(EE_CHAR_SHADOW)).GetValue();
+ aSet.Put( SvxShadowedItem( !bOld, EE_CHAR_SHADOW ) );
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_ATTR_CHAR_CONTOUR:
+ {
+ sal_Bool bOld = ((const SvxContourItem&)pEditView->GetAttribs().
+ Get(EE_CHAR_OUTLINE)).GetValue();
+ aSet.Put( SvxContourItem( !bOld, EE_CHAR_OUTLINE ) );
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_SET_SUPER_SCRIPT:
+ {
+ SvxEscapement eOld = (SvxEscapement) ((const SvxEscapementItem&)
+ pEditView->GetAttribs().Get(EE_CHAR_ESCAPEMENT)).GetEnumValue();
+ SvxEscapement eNew = (eOld == SVX_ESCAPEMENT_SUPERSCRIPT) ?
+ SVX_ESCAPEMENT_OFF : SVX_ESCAPEMENT_SUPERSCRIPT;
+ aSet.Put( SvxEscapementItem( eNew, EE_CHAR_ESCAPEMENT ) );
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+ case SID_SET_SUB_SCRIPT:
+ {
+ SvxEscapement eOld = (SvxEscapement) ((const SvxEscapementItem&)
+ pEditView->GetAttribs().Get(EE_CHAR_ESCAPEMENT)).GetEnumValue();
+ SvxEscapement eNew = (eOld == SVX_ESCAPEMENT_SUBSCRIPT) ?
+ SVX_ESCAPEMENT_OFF : SVX_ESCAPEMENT_SUBSCRIPT;
+ aSet.Put( SvxEscapementItem( eNew, EE_CHAR_ESCAPEMENT ) );
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+ }
+
+ //
+ // anwenden
+ //
+
+ EditEngine* pEngine = pEditView->GetEditEngine();
+ sal_Bool bOld = pEngine->GetUpdateMode();
+ pEngine->SetUpdateMode(sal_False);
+
+ pEditView->SetAttribs( aSet );
+
+ pEngine->SetUpdateMode(bOld);
+ pEditView->Invalidate();
+
+ ScInputHandler* pHdl = GetMyInputHdl();
+ pHdl->SetModified();
+
+ rReq.Done();
+}
+
+void ScEditShell::GetAttrState(SfxItemSet &rSet)
+{
+ if ( !pViewData->HasEditView( pViewData->GetActivePart() ) ) // #125326#
+ {
+ lcl_DisableAll( rSet );
+ return;
+ }
+
+ SfxItemSet aAttribs = pEditView->GetAttribs();
+ rSet.Put( aAttribs );
+
+ // choose font info according to selection script type
+
+ sal_uInt16 nScript = pEditView->GetSelectedScriptType();
+ if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType();
+
+ // #i55929# input-language-dependent script type (depends on input language if nothing selected)
+ sal_uInt16 nInputScript = nScript;
+ if ( !pEditView->GetSelection().HasRange() )
+ {
+ LanguageType nInputLang = pViewData->GetActiveWin()->GetInputLanguage();
+ if (nInputLang != LANGUAGE_DONTKNOW && nInputLang != LANGUAGE_SYSTEM)
+ nInputScript = SvtLanguageOptions::GetScriptTypeOfLanguage( nInputLang );
+ }
+
+ // #i55929# according to spec, nInputScript is used for font and font height only
+ if ( rSet.GetItemState( EE_CHAR_FONTINFO ) != SFX_ITEM_UNKNOWN )
+ ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_FONTINFO, nInputScript );
+ if ( rSet.GetItemState( EE_CHAR_FONTHEIGHT ) != SFX_ITEM_UNKNOWN )
+ ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_FONTHEIGHT, nInputScript );
+ if ( rSet.GetItemState( EE_CHAR_WEIGHT ) != SFX_ITEM_UNKNOWN )
+ ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_WEIGHT, nScript );
+ if ( rSet.GetItemState( EE_CHAR_ITALIC ) != SFX_ITEM_UNKNOWN )
+ ScViewUtil::PutItemScript( rSet, aAttribs, EE_CHAR_ITALIC, nScript );
+
+ // Unterstreichung
+
+ SfxItemState eState = aAttribs.GetItemState( EE_CHAR_UNDERLINE, sal_True );
+ if ( eState == SFX_ITEM_DONTCARE )
+ {
+ rSet.InvalidateItem( SID_ULINE_VAL_NONE );
+ rSet.InvalidateItem( SID_ULINE_VAL_SINGLE );
+ rSet.InvalidateItem( SID_ULINE_VAL_DOUBLE );
+ rSet.InvalidateItem( SID_ULINE_VAL_DOTTED );
+ }
+ else
+ {
+ FontUnderline eUnderline = ((const SvxUnderlineItem&)
+ aAttribs.Get(EE_CHAR_UNDERLINE)).GetLineStyle();
+ sal_uInt16 nId = SID_ULINE_VAL_NONE;
+ switch (eUnderline)
+ {
+ case UNDERLINE_SINGLE: nId = SID_ULINE_VAL_SINGLE; break;
+ case UNDERLINE_DOUBLE: nId = SID_ULINE_VAL_DOUBLE; break;
+ case UNDERLINE_DOTTED: nId = SID_ULINE_VAL_DOTTED; break;
+ default:
+ break;
+ }
+ rSet.Put( SfxBoolItem( nId, sal_True ) );
+ }
+
+ //! Testen, ob Klammer-Hervorhebung aktiv ist !!!!
+ ScInputHandler* pHdl = GetMyInputHdl();
+ if ( pHdl && pHdl->IsFormulaMode() )
+ rSet.ClearItem( EE_CHAR_WEIGHT ); // hervorgehobene Klammern hier nicht
+}
+
+String ScEditShell::GetSelectionText( sal_Bool bWholeWord )
+{
+ String aStrSelection;
+
+ if ( pViewData->HasEditView( pViewData->GetActivePart() ) ) // #125326#
+ {
+ if ( bWholeWord )
+ {
+ EditEngine* pEngine = pEditView->GetEditEngine();
+ ESelection aSel = pEditView->GetSelection();
+ String aStrCurrentDelimiters = pEngine->GetWordDelimiters();
+
+ pEngine->SetWordDelimiters( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(" .,;\"'")) );
+ aStrSelection = pEngine->GetWord( aSel.nEndPara, aSel.nEndPos );
+ pEngine->SetWordDelimiters( aStrCurrentDelimiters );
+ }
+ else
+ {
+ aStrSelection = pEditView->GetSelected();
+ }
+ }
+
+ return aStrSelection;
+}
+
+void ScEditShell::ExecuteUndo(SfxRequest& rReq)
+{
+ // #81733# Undo must be handled here because it's called for both EditViews
+
+ ScInputHandler* pHdl = GetMyInputHdl();
+ DBG_ASSERT(pHdl,"no ScInputHandler");
+ EditView* pTopView = pHdl->GetTopView();
+ EditView* pTableView = pHdl->GetTableView();
+ DBG_ASSERT(pTableView,"no EditView");
+
+ pHdl->DataChanging();
+
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ sal_uInt16 nSlot = rReq.GetSlot();
+ switch ( nSlot )
+ {
+ case SID_UNDO:
+ case SID_REDO:
+ {
+ sal_Bool bIsUndo = ( nSlot == SID_UNDO );
+
+ sal_uInt16 nCount = 1;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && pReqArgs->GetItemState( nSlot, sal_True, &pItem ) == SFX_ITEM_SET )
+ nCount = ((const SfxUInt16Item*)pItem)->GetValue();
+
+ for (sal_uInt16 i=0; i<nCount; i++)
+ {
+ if ( bIsUndo )
+ {
+ pTableView->Undo();
+ if (pTopView)
+ pTopView->Undo();
+ }
+ else
+ {
+ pTableView->Redo();
+ if (pTopView)
+ pTopView->Redo();
+ }
+ }
+ }
+ break;
+ }
+ pViewData->GetBindings().InvalidateAll(sal_False);
+
+ pHdl->DataChanged();
+}
+
+void ScEditShell::GetUndoState(SfxItemSet &rSet)
+{
+ // Undo state is taken from normal ViewFrame state function
+
+ SfxViewFrame* pViewFrm = pViewData->GetViewShell()->GetViewFrame();
+ if ( pViewFrm && GetUndoManager() )
+ {
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while( nWhich )
+ {
+ pViewFrm->GetSlotState( nWhich, NULL, &rSet );
+ nWhich = aIter.NextWhich();
+ }
+ }
+
+ // disable if no action in input line EditView
+
+ ScInputHandler* pHdl = GetMyInputHdl();
+ DBG_ASSERT(pHdl,"no ScInputHandler");
+ EditView* pTopView = pHdl->GetTopView();
+ if (pTopView)
+ {
+ ::svl::IUndoManager& rTopMgr = pTopView->GetEditEngine()->GetUndoManager();
+ if ( rTopMgr.GetUndoActionCount() == 0 )
+ rSet.DisableItem( SID_UNDO );
+ if ( rTopMgr.GetRedoActionCount() == 0 )
+ rSet.DisableItem( SID_REDO );
+ }
+}
+
+void ScEditShell::ExecuteTrans( SfxRequest& rReq )
+{
+ sal_Int32 nType = ScViewUtil::GetTransliterationType( rReq.GetSlot() );
+ if ( nType )
+ {
+ ScInputHandler* pHdl = GetMyInputHdl();
+ DBG_ASSERT( pHdl, "no ScInputHandler" );
+
+ EditView* pTopView = pHdl->GetTopView();
+ EditView* pTableView = pHdl->GetTableView();
+ DBG_ASSERT( pTableView, "no EditView" );
+
+ pHdl->DataChanging();
+
+ pTableView->TransliterateText( nType );
+ if (pTopView)
+ pTopView->TransliterateText( nType );
+
+ pHdl->DataChanged();
+ }
+}
+
diff --git a/sc/source/ui/view/formatsh.cxx b/sc/source/ui/view/formatsh.cxx
new file mode 100644
index 000000000000..ecc6f19d43e5
--- /dev/null
+++ b/sc/source/ui/view/formatsh.cxx
@@ -0,0 +1,2165 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+
+//------------------------------------------------------------------
+
+//svdraw.hxx
+#define _SDR_NOITEMS
+#define _SDR_NOTOUCH
+#define _SDR_NOTRANSFORM
+#define _SI_NOSBXCONTROLS
+#define _VCONT_HXX
+#define _SI_NOOTHERFORMS
+#define _VCTRLS_HXX
+#define _SI_NOCONTROL
+#define _SETBRW_HXX
+#define _VCBRW_HXX
+#define _SI_NOSBXCONTROLS
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/app.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/request.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/msgbox.hxx>
+
+#define _ZFORLIST_DECLARE_TABLE
+#include <svl/stritem.hxx>
+#include <svl/zformat.hxx>
+#include <svl/languageoptions.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/langitem.hxx>
+#include <svx/numinf.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/templdlg.hxx>
+#include <sfx2/tplpitem.hxx>
+#include <editeng/svxenum.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/bolnitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <svtools/colorcfg.hxx>
+#include <editeng/shaditem.hxx>
+
+#include "formatsh.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "docsh.hxx"
+#include "patattr.hxx"
+#include "scmod.hxx"
+//CHINA001 #include "styledlg.hxx"
+#include "attrdlg.hrc"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "printfun.hxx"
+#include "docpool.hxx"
+#include "scresid.hxx"
+#include "tabvwsh.hxx"
+#include "undostyl.hxx"
+
+
+#define ScFormatShell
+#define TableFont
+#define FormatForSelection
+#include "scslots.hxx"
+
+#include "scabstdlg.hxx" //CHINA001
+
+namespace {
+
+SvxCellHorJustify lclConvertSlotToHAlign( sal_uInt16 nSlot )
+{
+ SvxCellHorJustify eHJustify = SVX_HOR_JUSTIFY_STANDARD;
+ switch( nSlot )
+ {
+ case SID_ALIGN_ANY_HDEFAULT: eHJustify = SVX_HOR_JUSTIFY_STANDARD; break;
+ case SID_ALIGN_ANY_LEFT: eHJustify = SVX_HOR_JUSTIFY_LEFT; break;
+ case SID_ALIGN_ANY_HCENTER: eHJustify = SVX_HOR_JUSTIFY_CENTER; break;
+ case SID_ALIGN_ANY_RIGHT: eHJustify = SVX_HOR_JUSTIFY_RIGHT; break;
+ case SID_ALIGN_ANY_JUSTIFIED: eHJustify = SVX_HOR_JUSTIFY_BLOCK; break;
+ default: DBG_ERRORFILE( "lclConvertSlotToHAlign - invalid slot" );
+ }
+ return eHJustify;
+}
+
+SvxCellVerJustify lclConvertSlotToVAlign( sal_uInt16 nSlot )
+{
+ SvxCellVerJustify eVJustify = SVX_VER_JUSTIFY_STANDARD;
+ switch( nSlot )
+ {
+ case SID_ALIGN_ANY_VDEFAULT: eVJustify = SVX_VER_JUSTIFY_STANDARD; break;
+ case SID_ALIGN_ANY_TOP: eVJustify = SVX_VER_JUSTIFY_TOP; break;
+ case SID_ALIGN_ANY_VCENTER: eVJustify = SVX_VER_JUSTIFY_CENTER; break;
+ case SID_ALIGN_ANY_BOTTOM: eVJustify = SVX_VER_JUSTIFY_BOTTOM; break;
+ default: DBG_ERRORFILE( "lclConvertSlotToVAlign - invalid slot" );
+ }
+ return eVJustify;
+}
+
+} // namespace
+
+TYPEINIT1( ScFormatShell, SfxShell );
+
+SFX_IMPL_INTERFACE(ScFormatShell, SfxShell, ScResId(SCSTR_FORMATSHELL) )
+{
+ SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT | SFX_VISIBILITY_STANDARD |
+ SFX_VISIBILITY_SERVER,
+ ScResId(RID_OBJECTBAR_FORMAT));
+
+}
+
+
+ScFormatShell::ScFormatShell(ScViewData* pData) :
+ SfxShell(pData->GetViewShell()),
+ pViewData(pData)
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+
+ SetPool( &pTabViewShell->GetPool() );
+ ::svl::IUndoManager* pMgr = pViewData->GetSfxDocShell()->GetUndoManager();
+ SetUndoManager( pMgr );
+ if ( !pViewData->GetDocument()->IsUndoEnabled() )
+ {
+ pMgr->SetMaxUndoActionCount( 0 );
+ }
+ SetHelpId(HID_SCSHELL_FORMATSH);
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Format")));
+}
+
+ScFormatShell::~ScFormatShell()
+{
+}
+
+//------------------------------------------------------------------
+
+void __EXPORT ScFormatShell::GetStyleState( SfxItemSet& rSet )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ SfxStyleSheetBasePool* pStylePool = pDoc->GetStyleSheetPool();
+
+ sal_Bool bProtected = sal_False;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (pDoc->IsTabProtected(i)) // ueberhaupt eine Tabelle geschuetzt?
+ bProtected = sal_True;
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ sal_uInt16 nSlotId = 0;
+
+ while ( nWhich )
+ {
+ nSlotId = SfxItemPool::IsWhich( nWhich )
+ ? GetPool().GetSlotId( nWhich )
+ : nWhich;
+
+ switch ( nSlotId )
+ {
+ case SID_STYLE_APPLY:
+ if ( !pStylePool )
+ rSet.DisableItem( nSlotId );
+ break;
+
+ case SID_STYLE_FAMILY2: // Zellvorlagen
+ {
+ SfxStyleSheet* pStyleSheet = (SfxStyleSheet*)
+ pTabViewShell->GetStyleSheetFromMarked();
+
+ if ( pStyleSheet )
+ rSet.Put( SfxTemplateItem( nSlotId, pStyleSheet->GetName() ) );
+ else
+ rSet.Put( SfxTemplateItem( nSlotId, String() ) );
+ }
+ break;
+
+ case SID_STYLE_FAMILY4: // Seitenvorlagen
+ {
+ SCTAB nCurTab = GetViewData()->GetTabNo();
+ String aPageStyle = pDoc->GetPageStyle( nCurTab );
+ SfxStyleSheet* pStyleSheet = (SfxStyleSheet*)pStylePool->
+ Find( aPageStyle, SFX_STYLE_FAMILY_PAGE );
+
+ if ( pStyleSheet )
+ rSet.Put( SfxTemplateItem( nSlotId, aPageStyle ) );
+ else
+ rSet.Put( SfxTemplateItem( nSlotId, String() ) );
+ }
+ break;
+
+ case SID_STYLE_WATERCAN:
+ {
+ rSet.Put( SfxBoolItem( nSlotId, SC_MOD()->GetIsWaterCan() ) );
+ }
+ break;
+
+ case SID_STYLE_UPDATE_BY_EXAMPLE:
+ {
+ ISfxTemplateCommon* pDesigner = SFX_APP()->
+ GetCurrentTemplateCommon(pTabViewShell->GetViewFrame()->GetBindings());
+ sal_Bool bPage = pDesigner && SFX_STYLE_FAMILY_PAGE == pDesigner->GetActualFamily();
+
+ if ( bProtected || bPage )
+ rSet.DisableItem( nSlotId );
+ }
+ break;
+
+ case SID_STYLE_EDIT:
+ case SID_STYLE_DELETE:
+ {
+ ISfxTemplateCommon* pDesigner = SFX_APP()->
+ GetCurrentTemplateCommon(pTabViewShell->GetViewFrame()->GetBindings());
+ sal_Bool bPage = pDesigner && SFX_STYLE_FAMILY_PAGE == pDesigner->GetActualFamily();
+
+ if ( bProtected && !bPage )
+ rSet.DisableItem( nSlotId );
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+//------------------------------------------------------------------
+
+void __EXPORT ScFormatShell::ExecuteStyle( SfxRequest& rReq )
+{
+ // Wenn ToolBar vertikal :
+ if ( !rReq.GetArgs() )
+ {
+ pViewData->GetDispatcher().Execute( SID_STYLE_DESIGNER, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD );
+ return;
+ }
+
+ //--------------------------------------------------------------------
+ SfxBindings& rBindings = pViewData->GetBindings();
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const sal_uInt16 nSlotId = rReq.GetSlot();
+ const SCTAB nCurTab = GetViewData()->GetTabNo();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScTabViewShell* pTabViewShell= GetViewData()->GetViewShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ ScModule* pScMod = SC_MOD();
+ String aRefName;
+ sal_Bool bUndo = pDoc->IsUndoEnabled();
+
+ if ( (nSlotId == SID_STYLE_NEW)
+ || (nSlotId == SID_STYLE_EDIT)
+ || (nSlotId == SID_STYLE_DELETE)
+ || (nSlotId == SID_STYLE_APPLY)
+ || (nSlotId == SID_STYLE_WATERCAN)
+ || (nSlotId == SID_STYLE_FAMILY)
+ || (nSlotId == SID_STYLE_NEW_BY_EXAMPLE)
+ || (nSlotId == SID_STYLE_UPDATE_BY_EXAMPLE) )
+ {
+ SfxStyleSheetBasePool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = NULL;
+
+ sal_Bool bStyleToMarked = sal_False;
+ sal_Bool bListAction = sal_False;
+ sal_Bool bAddUndo = sal_False; // add ScUndoModifyStyle (style modified)
+ ScStyleSaveData aOldData; // for undo/redo
+ ScStyleSaveData aNewData;
+
+ SfxStyleFamily eFamily = SFX_STYLE_FAMILY_PARA;
+ const SfxPoolItem* pFamItem;
+ if ( pArgs && SFX_ITEM_SET == pArgs->GetItemState( SID_STYLE_FAMILY, sal_True, &pFamItem ) )
+ eFamily = (SfxStyleFamily)((const SfxUInt16Item*)pFamItem)->GetValue();
+ else
+ if ( pArgs && SFX_ITEM_SET == pArgs->GetItemState( SID_STYLE_FAMILYNAME, sal_True, &pFamItem ) )
+ {
+ String sFamily = ((const SfxStringItem*)pFamItem)->GetValue();
+ if (sFamily.CompareToAscii("CellStyles") == COMPARE_EQUAL)
+ eFamily = SFX_STYLE_FAMILY_PARA;
+ else
+ if (sFamily.CompareToAscii("PageStyles") == COMPARE_EQUAL)
+ eFamily = SFX_STYLE_FAMILY_PAGE;
+ }
+
+ String aStyleName;
+ sal_uInt16 nRetMask = 0xffff;
+// #96983# only stylist sends focus to sheet
+// sal_Bool bGrabFocus = ( SID_STYLE_APPLY == nSlotId );
+
+ pStylePool->SetSearchMask( eFamily, SFXSTYLEBIT_ALL );
+
+ switch ( nSlotId )
+ {
+ case SID_STYLE_NEW:
+ {
+ const SfxPoolItem* pNameItem;
+ if (pArgs && SFX_ITEM_SET == pArgs->GetItemState( nSlotId, sal_True, &pNameItem ))
+ aStyleName = ((const SfxStringItem*)pNameItem)->GetValue();
+
+ const SfxPoolItem* pRefItem=NULL;
+ if (pArgs && SFX_ITEM_SET == pArgs->GetItemState( SID_STYLE_REFERENCE, sal_True, &pRefItem ))
+ {
+ if(pRefItem!=NULL)
+ aRefName = ((const SfxStringItem*)pRefItem)->GetValue();
+ }
+
+ pStyleSheet = &(pStylePool->Make( aStyleName, eFamily,
+ SFXSTYLEBIT_USERDEF ) );
+
+ if ( pStyleSheet && pStyleSheet->HasParentSupport() )
+ pStyleSheet->SetParent(aRefName);
+ }
+ break;
+
+ case SID_STYLE_APPLY:
+ {
+ SFX_REQUEST_ARG( rReq, pNameItem, SfxStringItem, SID_APPLY_STYLE, sal_False );
+ SFX_REQUEST_ARG( rReq, pFamilyItem, SfxStringItem, SID_STYLE_FAMILYNAME, sal_False );
+ if ( pFamilyItem && pNameItem )
+ {
+ com::sun::star::uno::Reference< com::sun::star::style::XStyleFamiliesSupplier > xModel(pDocSh->GetModel(), com::sun::star::uno::UNO_QUERY);
+ try
+ {
+ com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > xStyles;
+ com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > xCont = xModel->getStyleFamilies();
+ xCont->getByName(pFamilyItem->GetValue()) >>= xStyles;
+ com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > xInfo;
+ xStyles->getByName( pNameItem->GetValue() ) >>= xInfo;
+ ::rtl::OUString aUIName;
+ xInfo->getPropertyValue( ::rtl::OUString::createFromAscii("DisplayName") ) >>= aUIName;
+ if ( aUIName.getLength() )
+ rReq.AppendItem( SfxStringItem( SID_STYLE_APPLY, aUIName ) );
+ }
+ catch( com::sun::star::uno::Exception& )
+ {
+ }
+ }
+ }
+ case SID_STYLE_EDIT:
+ case SID_STYLE_DELETE:
+ case SID_STYLE_NEW_BY_EXAMPLE:
+ {
+ const SfxPoolItem* pNameItem;
+ if (pArgs && SFX_ITEM_SET == pArgs->GetItemState( nSlotId, sal_True, &pNameItem ))
+ aStyleName = ((const SfxStringItem*)pNameItem)->GetValue();
+ pStyleSheet = pStylePool->Find( aStyleName, eFamily );
+
+ aOldData.InitFromStyle( pStyleSheet );
+ }
+ break;
+
+ case SID_STYLE_WATERCAN:
+ {
+ sal_Bool bWaterCan = pScMod->GetIsWaterCan();
+
+ if( !bWaterCan )
+ {
+ const SfxPoolItem* pItem;
+
+ if ( SFX_ITEM_SET ==
+ pArgs->GetItemState( nSlotId, sal_True, &pItem ) )
+ {
+ const SfxStringItem* pStrItem = PTR_CAST(SfxStringItem,pItem);
+ if ( pStrItem )
+ {
+ aStyleName = pStrItem->GetValue();
+ pStyleSheet = pStylePool->Find( aStyleName, eFamily );
+
+ if ( pStyleSheet )
+ {
+ ((ScStyleSheetPool*)pStylePool)->
+ SetActualStyleSheet( pStyleSheet );
+ rReq.Done();
+ }
+ }
+ }
+ }
+
+ if ( !bWaterCan && pStyleSheet )
+ {
+ pScMod->SetWaterCan( sal_True );
+ pTabViewShell->SetActivePointer( Pointer(POINTER_FILL) );
+ rReq.Done();
+ }
+ else
+ {
+ pScMod->SetWaterCan( sal_False );
+ pTabViewShell->SetActivePointer( Pointer(POINTER_ARROW) );
+ rReq.Done();
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // Neuen Style fuer WaterCan-Mode setzen
+ if ( nSlotId == SID_STYLE_APPLY && pScMod->GetIsWaterCan() && pStyleSheet )
+ ((ScStyleSheetPool*)pStylePool)->SetActualStyleSheet( pStyleSheet );
+
+ switch ( eFamily )
+ {
+ case SFX_STYLE_FAMILY_PARA:
+ {
+ switch ( nSlotId )
+ {
+ case SID_STYLE_DELETE:
+ {
+ if ( pStyleSheet )
+ {
+ pTabViewShell->RemoveStyleSheetInUse( pStyleSheet );
+ pStylePool->Remove( pStyleSheet );
+ pTabViewShell->InvalidateAttribs();
+ nRetMask = sal_True;
+ bAddUndo = sal_True;
+ rReq.Done();
+ }
+ else
+ nRetMask = sal_False;
+ }
+ break;
+
+ case SID_STYLE_APPLY:
+ {
+ if ( pStyleSheet && !pScMod->GetIsWaterCan() )
+ {
+ // Anwenden der Vorlage auf das Dokument
+ pTabViewShell->SetStyleSheetToMarked( (SfxStyleSheet*)pStyleSheet );
+ pTabViewShell->InvalidateAttribs();
+ rReq.Done();
+ }
+ }
+ break;
+
+ case SID_STYLE_NEW_BY_EXAMPLE:
+ case SID_STYLE_UPDATE_BY_EXAMPLE:
+ {
+ // Vorlage erzeugen/ersetzen durch Attribute
+ // an der Cursor-Position:
+
+ const ScPatternAttr* pAttrItem = NULL;
+
+ // Die Abfrage, ob markiert ist, war hier immer falsch,
+ // darum jetzt gar nicht mehr, und einfach vom Cursor.
+ // Wenn Attribute aus der Selektion genommen werden sollen,
+ // muss noch darauf geachtet werden, Items aus Vorlagen nicht
+ // zu uebernehmen (GetSelectionPattern sammelt auch Items aus
+ // Vorlagen zusammen) (#44748#)
+ // pAttrItem = GetSelectionPattern();
+
+ // ScViewData* pViewData = GetViewData();
+ SCCOL nCol = pViewData->GetCurX();
+ SCROW nRow = pViewData->GetCurY();
+ pAttrItem = pDoc->GetPattern( nCol, nRow, nCurTab );
+
+ SfxItemSet aAttrSet = pAttrItem->GetItemSet();
+ aAttrSet.ClearItem( ATTR_MERGE );
+ aAttrSet.ClearItem( ATTR_MERGE_FLAG );
+ // bedingte Formatierung und Gueltigkeit nicht uebernehmen,
+ // weil sie in der Vorlage nicht editiert werden koennen
+ aAttrSet.ClearItem( ATTR_VALIDDATA );
+ aAttrSet.ClearItem( ATTR_CONDITIONAL );
+
+ if ( SID_STYLE_NEW_BY_EXAMPLE == nSlotId )
+ {
+ if ( bUndo )
+ {
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_EDITCELLSTYLE );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+ bListAction = sal_True;
+ }
+
+ sal_Bool bConvertBack = sal_False;
+ SfxStyleSheet* pSheetInUse = (SfxStyleSheet*)
+ pTabViewShell->GetStyleSheetFromMarked();
+
+ // wenn neuer Style vorhanden und in der Selektion
+ // verwendet wird, so darf der Parent nicht uebernommen
+ // werden:
+
+ if ( pStyleSheet && pSheetInUse && pStyleSheet == pSheetInUse )
+ pSheetInUse = NULL;
+
+ // wenn bereits vorhanden, erstmal entfernen...
+ if ( pStyleSheet )
+ {
+ // Style-Pointer zu Namen vor Erase,
+ // weil Zellen sonst ungueltige Pointer
+ // enthalten.
+ //!!! bei Gelenheit mal eine Methode, die
+ // das fuer einen bestimmten Style macht
+ pDoc->StylesToNames();
+ bConvertBack = sal_True;
+ pStylePool->Remove(pStyleSheet);
+ }
+
+ // ...und neu anlegen
+ pStyleSheet = &pStylePool->Make( aStyleName, eFamily,
+ SFXSTYLEBIT_USERDEF );
+
+ // wenn ein Style vorhanden ist, so wird dieser
+ // Parent der neuen Vorlage:
+ if ( pSheetInUse && pStyleSheet->HasParentSupport() )
+ pStyleSheet->SetParent( pSheetInUse->GetName() );
+
+ if ( bConvertBack )
+ // Namen zu Style-Pointer
+ pDoc->UpdStlShtPtrsFrmNms();
+ else
+ pDoc->GetPool()->CellStyleCreated( aStyleName );
+
+ // Attribute uebernehmen und Style anwenden
+ pStyleSheet->GetItemSet().Put( aAttrSet );
+ pTabViewShell->UpdateStyleSheetInUse( pStyleSheet );
+
+ // call SetStyleSheetToMarked after adding the ScUndoModifyStyle
+ // (pStyleSheet pointer is used!)
+ bStyleToMarked = sal_True;
+ }
+ else // ( nSlotId == SID_STYLE_UPDATE_BY_EXAMPLE )
+ {
+ pStyleSheet = (SfxStyleSheet*)pTabViewShell->GetStyleSheetFromMarked();
+
+ if ( pStyleSheet )
+ {
+ aOldData.InitFromStyle( pStyleSheet );
+
+ if ( bUndo )
+ {
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_EDITCELLSTYLE );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+ bListAction = sal_True;
+ }
+
+ pStyleSheet->GetItemSet().Put( aAttrSet );
+ pTabViewShell->UpdateStyleSheetInUse( pStyleSheet );
+
+ // call SetStyleSheetToMarked after adding the ScUndoModifyStyle
+ // (pStyleSheet pointer is used!)
+ bStyleToMarked = sal_True;
+ }
+ }
+
+ aNewData.InitFromStyle( pStyleSheet );
+ bAddUndo = sal_True;
+ rReq.Done();
+ }
+ break;
+
+ default:
+ break;
+ }
+ } // case SFX_STYLE_FAMILY_PARA:
+ break;
+
+ case SFX_STYLE_FAMILY_PAGE:
+ {
+ switch ( nSlotId )
+ {
+ case SID_STYLE_DELETE:
+ {
+ nRetMask = ( NULL != pStyleSheet );
+ if ( pStyleSheet )
+ {
+ if ( pDoc->RemovePageStyleInUse( pStyleSheet->GetName() ) )
+ {
+ ScPrintFunc( pDocSh, pTabViewShell->GetPrinter(sal_True), nCurTab ).UpdatePages();
+ rBindings.Invalidate( SID_STATUS_PAGESTYLE );
+ rBindings.Invalidate( FID_RESET_PRINTZOOM );
+ }
+ pStylePool->Remove( pStyleSheet );
+ rBindings.Invalidate( SID_STYLE_FAMILY4 );
+ pDocSh->SetDocumentModified();
+ bAddUndo = sal_True;
+ rReq.Done();
+ }
+ }
+ break;
+
+ case SID_STYLE_APPLY:
+ {
+ nRetMask = ( NULL != pStyleSheet );
+ if ( pStyleSheet && !pScMod->GetIsWaterCan() )
+ {
+ ScUndoApplyPageStyle* pUndoAction = 0;
+ for( SCTAB nTab = 0, nTabCount = pDoc->GetTableCount(); nTab < nTabCount; ++nTab )
+ {
+ if( rMark.GetTableSelect( nTab ) )
+ {
+ String aOldName = pDoc->GetPageStyle( nTab );
+ if ( aOldName != aStyleName )
+ {
+ pDoc->SetPageStyle( nTab, aStyleName );
+ ScPrintFunc( pDocSh, pTabViewShell->GetPrinter(sal_True), nTab ).UpdatePages();
+ if( !pUndoAction )
+ pUndoAction = new ScUndoApplyPageStyle( pDocSh, aStyleName );
+ pUndoAction->AddSheetAction( nTab, aOldName );
+ }
+ }
+ }
+ if( pUndoAction )
+ {
+ pDocSh->GetUndoManager()->AddUndoAction( pUndoAction );
+ pDocSh->SetDocumentModified();
+ rBindings.Invalidate( SID_STYLE_FAMILY4 );
+ rBindings.Invalidate( SID_STATUS_PAGESTYLE );
+ rBindings.Invalidate( FID_RESET_PRINTZOOM );
+ }
+ rReq.Done();
+ }
+ }
+ break;
+
+ case SID_STYLE_NEW_BY_EXAMPLE:
+ {
+ const String& rStrCurStyle = pDoc->GetPageStyle( nCurTab );
+
+ if ( rStrCurStyle != aStyleName )
+ {
+ SfxStyleSheetBase* pCurStyle = pStylePool->Find( rStrCurStyle, eFamily );
+ SfxItemSet aAttrSet = pCurStyle->GetItemSet();
+ SCTAB nInTab;
+ sal_Bool bUsed = pDoc->IsPageStyleInUse( aStyleName, &nInTab );
+
+ // wenn bereits vorhanden, erstmal entfernen...
+ if ( pStyleSheet )
+ pStylePool->Remove( pStyleSheet );
+
+ // ...und neu anlegen
+ pStyleSheet = &pStylePool->Make( aStyleName, eFamily,
+ SFXSTYLEBIT_USERDEF );
+
+ // Attribute uebernehmen
+ pStyleSheet->GetItemSet().Put( aAttrSet );
+ pDocSh->SetDocumentModified();
+
+ // wenn in Verwendung -> Update
+ if ( bUsed )
+ ScPrintFunc( pDocSh, pTabViewShell->GetPrinter(sal_True), nInTab ).UpdatePages();
+
+ aNewData.InitFromStyle( pStyleSheet );
+ bAddUndo = sal_True;
+ rReq.Done();
+ nRetMask = sal_True;
+ }
+ }
+ break;
+
+ default:
+ break;
+ } // switch ( nSlotId )
+ } // case SFX_STYLE_FAMILY_PAGE:
+ break;
+
+ default:
+ break;
+ } // switch ( eFamily )
+
+ // Neu anlegen oder bearbeiten ueber Dialog:
+ if ( nSlotId == SID_STYLE_NEW || nSlotId == SID_STYLE_EDIT )
+ {
+ if ( pStyleSheet )
+ {
+ SvxNumberInfoItem* pNumberInfoItem = NULL;
+
+ SfxStyleFamily eFam = pStyleSheet->GetFamily();
+ // ScDocument* pDoc = GetViewData()->GetDocument();
+ // ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ //CHINA001 ScStyleDlg* pDlg = NULL;
+ SfxAbstractTabDialog* pDlg = NULL; //CHINA001
+ sal_uInt16 nRsc = 0;
+
+ // #37034#/#37245# alte Items aus der Vorlage merken
+ SfxItemSet aOldSet = pStyleSheet->GetItemSet();
+ String aOldName = pStyleSheet->GetName();
+
+ switch ( eFam )
+ {
+ case SFX_STYLE_FAMILY_PAGE:
+ nRsc = RID_SCDLG_STYLES_PAGE;
+ break;
+
+ case SFX_STYLE_FAMILY_PARA:
+ default:
+ {
+ SfxItemSet& rSet = pStyleSheet->GetItemSet();
+
+ const SfxPoolItem* pItem;
+ if ( rSet.GetItemState( ATTR_VALUE_FORMAT,
+ sal_False, &pItem ) == SFX_ITEM_SET )
+ {
+ // NumberFormat Value aus Value und Language
+ // erzeugen und eintueten
+ sal_uLong nFormat =
+ ((SfxUInt32Item*)pItem)->GetValue();
+ LanguageType eLang =
+ ((SvxLanguageItem*)&rSet.Get(
+ ATTR_LANGUAGE_FORMAT ))->GetLanguage();
+ sal_uLong nLangFormat = pDoc->GetFormatTable()->
+ GetFormatForLanguageIfBuiltIn( nFormat, eLang );
+ if ( nLangFormat != nFormat )
+ {
+ SfxUInt32Item aNewItem( ATTR_VALUE_FORMAT, nLangFormat );
+ rSet.Put( aNewItem );
+ aOldSet.Put( aNewItem );
+ // auch in aOldSet fuer Vergleich nach dem Dialog,
+ // sonst geht evtl. eine Aenderung der Sprache verloren
+ }
+ }
+
+ pTabViewShell->MakeNumberInfoItem( pDoc, GetViewData(), &pNumberInfoItem );
+ pDocSh->PutItem( *pNumberInfoItem );
+ nRsc = RID_SCDLG_STYLES_PAR;
+
+ // auf jeden Fall ein SvxBoxInfoItem mit Table = sal_False im Set:
+ // (wenn gar kein Item da ist, loescht der Dialog auch das
+ // BORDER_OUTER SvxBoxItem aus dem Vorlagen-Set)
+
+ if ( rSet.GetItemState( ATTR_BORDER_INNER, sal_False ) != SFX_ITEM_SET )
+ {
+ SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
+ aBoxInfoItem.SetTable(sal_False); // keine inneren Linien
+ aBoxInfoItem.SetDist(sal_True);
+ aBoxInfoItem.SetMinDist(sal_False);
+ rSet.Put( aBoxInfoItem );
+ }
+ }
+ break;
+ }
+
+ // If GetDefDialogParent is a dialog, it must be used
+ // (style catalog)
+
+ Window* pParent = Application::GetDefDialogParent();
+ if ( !pParent || !pParent->IsDialog() )
+ {
+ // #107256# GetDefDialogParent currently doesn't return the window
+ // that was set with SetDefDialogParent (but dynamically finds the
+ // topmost parent of the focus window), so IsDialog above is FALSE
+ // even if called from the style catalog.
+ // -> Use NULL if a modal dialog is open, to enable the Dialog's
+ // default parent handling.
+ if ( Application::IsInModalMode() )
+ pParent = NULL;
+ else
+ pParent = pTabViewShell->GetDialogParent();
+ }
+
+ pTabViewShell->SetInFormatDialog(sal_True);
+
+ //CHINA001 pDlg = new ScStyleDlg( pParent, *pStyleSheet, nRsc );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ pDlg = pFact->CreateScStyleDlg( pParent, *pStyleSheet, nRsc, nRsc );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ short nResult = pDlg->Execute();
+ pTabViewShell->SetInFormatDialog(sal_False);
+
+ if ( nResult == RET_OK )
+ {
+ const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
+
+ if ( pOutSet )
+ {
+ nRetMask = pStyleSheet->GetMask();
+
+ // #37034#/#37245# Attribut-Vergleiche (frueher in ModifyStyleSheet)
+ // jetzt hier mit den alten Werten (Style ist schon veraendert)
+
+ if ( SFX_STYLE_FAMILY_PARA == eFam )
+ {
+// pDoc->CellStyleChanged( *pStyleSheet, aOldSet );
+
+ SfxItemSet& rNewSet = pStyleSheet->GetItemSet();
+ sal_Bool bNumFormatChanged;
+ if ( ScGlobal::CheckWidthInvalidate(
+ bNumFormatChanged, aOldSet, rNewSet ) )
+ pDoc->InvalidateTextWidth( NULL, NULL, bNumFormatChanged );
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (pDoc->IsStreamValid(nTab))
+ pDoc->SetStreamValid(nTab, sal_False);
+
+ sal_uLong nOldFormat = ((const SfxUInt32Item&)aOldSet.
+ Get( ATTR_VALUE_FORMAT )).GetValue();
+ sal_uLong nNewFormat = ((const SfxUInt32Item&)rNewSet.
+ Get( ATTR_VALUE_FORMAT )).GetValue();
+ if ( nNewFormat != nOldFormat )
+ {
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ const SvNumberformat* pOld = pFormatter->GetEntry( nOldFormat );
+ const SvNumberformat* pNew = pFormatter->GetEntry( nNewFormat );
+ if ( pOld && pNew && pOld->GetLanguage() != pNew->GetLanguage() )
+ rNewSet.Put( SvxLanguageItem(
+ pNew->GetLanguage(), ATTR_LANGUAGE_FORMAT ) );
+ }
+
+ pDoc->GetPool()->CellStyleCreated( pStyleSheet->GetName() );
+ }
+ else
+ {
+ //! auch fuer Seitenvorlagen die Abfragen hier
+
+ String aNewName = pStyleSheet->GetName();
+ if ( aNewName != aOldName &&
+ pDoc->RenamePageStyleInUse( aOldName, aNewName ) )
+ {
+ rBindings.Invalidate( SID_STATUS_PAGESTYLE );
+ rBindings.Invalidate( FID_RESET_PRINTZOOM );
+ }
+
+ pDoc->ModifyStyleSheet( *pStyleSheet, *pOutSet );
+ rBindings.Invalidate( FID_RESET_PRINTZOOM );
+ }
+
+ pDocSh->SetDocumentModified();
+
+ if ( SFX_STYLE_FAMILY_PARA == eFam )
+ {
+ pTabViewShell->UpdateNumberFormatter( pDoc,
+ (const SvxNumberInfoItem&)
+ *(pDocSh->GetItem(SID_ATTR_NUMBERFORMAT_INFO)) );
+
+ pTabViewShell->UpdateStyleSheetInUse( pStyleSheet );
+ pTabViewShell->InvalidateAttribs();
+ }
+
+ aNewData.InitFromStyle( pStyleSheet );
+ bAddUndo = sal_True;
+ }
+ }
+ else
+ {
+ if ( nSlotId == SID_STYLE_NEW )
+ pStylePool->Remove( pStyleSheet );
+ else
+ {
+ // falls zwischendurch etwas mit dem temporaer geaenderten
+ // ItemSet gepainted wurde:
+ pDocSh->PostPaintGridAll();
+ }
+ }
+ delete pDlg;
+ }
+ }
+
+// if ( nRetMask != 0xffff )// Irgendein Wert MUSS geliefert werden JN
+ rReq.SetReturnValue( SfxUInt16Item( nSlotId, nRetMask ) );
+
+// #96983# only stylist sends focus to sheet
+// if ( bGrabFocus )
+// pTabViewShell->GetActiveWin()->GrabFocus();
+
+ if ( bAddUndo && bUndo)
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoModifyStyle( pDocSh, eFamily, aOldData, aNewData ) );
+
+ if ( bStyleToMarked )
+ {
+ // call SetStyleSheetToMarked after adding the ScUndoModifyStyle,
+ // so redo will find the modified style
+ pTabViewShell->SetStyleSheetToMarked( (SfxStyleSheet*)pStyleSheet );
+ pTabViewShell->InvalidateAttribs();
+ }
+
+ if ( bListAction )
+ pDocSh->GetUndoManager()->LeaveListAction();
+ }
+ else
+ {
+ DBG_ERROR( "Unknown slot (ScViewShell::ExecuteStyle)" );
+ }
+}
+
+void ScFormatShell::ExecuteNumFormat( SfxRequest& rReq )
+{
+ ScModule* pScMod = SC_MOD();
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ sal_uInt16 nSlot = rReq.GetSlot();
+
+ pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
+
+ // Eingabe beenden
+ if ( GetViewData()->HasEditView( GetViewData()->GetActivePart() ) )
+ {
+ switch ( nSlot )
+ {
+ case SID_NUMBER_TWODEC:
+ case SID_NUMBER_SCIENTIFIC:
+ case SID_NUMBER_DATE:
+ case SID_NUMBER_CURRENCY:
+ case SID_NUMBER_PERCENT:
+ case SID_NUMBER_STANDARD:
+ case SID_NUMBER_FORMAT:
+ case SID_NUMBER_INCDEC:
+ case SID_NUMBER_DECDEC:
+ case FID_DEFINE_NAME:
+ case FID_USE_NAME:
+ case FID_INSERT_NAME:
+ case SID_SPELL_DIALOG:
+ case SID_HANGUL_HANJA_CONVERSION:
+
+ pScMod->InputEnterHandler();
+ pTabViewShell->UpdateInputHandler();
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch ( nSlot )
+ {
+ case SID_NUMBER_TWODEC:
+ pTabViewShell->SetNumberFormat( NUMBERFORMAT_NUMBER, 4 ); // Standard+4 = #.##0,00
+ rReq.Done();
+ break;
+ case SID_NUMBER_SCIENTIFIC:
+ pTabViewShell->SetNumberFormat( NUMBERFORMAT_SCIENTIFIC );
+ rReq.Done();
+ break;
+ case SID_NUMBER_DATE:
+ pTabViewShell->SetNumberFormat( NUMBERFORMAT_DATE );
+ rReq.Done();
+ break;
+ case SID_NUMBER_TIME:
+ pTabViewShell->SetNumberFormat( NUMBERFORMAT_TIME );
+ rReq.Done();
+ break;
+ case SID_NUMBER_CURRENCY:
+ pTabViewShell->SetNumberFormat( NUMBERFORMAT_CURRENCY );
+ rReq.Done();
+ break;
+ case SID_NUMBER_PERCENT:
+ pTabViewShell->SetNumberFormat( NUMBERFORMAT_PERCENT );
+ rReq.Done();
+ break;
+ case SID_NUMBER_STANDARD:
+ pTabViewShell->SetNumberFormat( NUMBERFORMAT_NUMBER );
+ rReq.Done();
+ break;
+ case SID_NUMBER_INCDEC:
+ pTabViewShell->ChangeNumFmtDecimals( sal_True );
+ rReq.Done();
+ break;
+ case SID_NUMBER_DECDEC:
+ pTabViewShell->ChangeNumFmtDecimals( sal_False );
+ rReq.Done();
+ break;
+
+ case SID_NUMBER_FORMAT:
+ if ( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if(pReqArgs->GetItemState(nSlot, sal_True, &pItem) == SFX_ITEM_SET)
+ {
+ String aCode = ((const SfxStringItem*)pItem)->GetValue();
+ pTabViewShell->SetNumFmtByStr( aCode );
+ }
+ }
+ break;
+
+ case SID_ATTR_NUMBERFORMAT_VALUE:
+ if ( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( ATTR_VALUE_FORMAT, sal_True, &pItem ) == SFX_ITEM_SET )
+ {
+ // We have to accomplish this using ApplyAttributes()
+ // because we also need the language information to be
+ // considered.
+ const SfxItemSet& rOldSet =
+ pTabViewShell->GetSelectionPattern()->GetItemSet();
+ SfxItemPool* pDocPool = GetViewData()->GetDocument()->GetPool();
+ SfxItemSet aNewSet( *pDocPool, ATTR_PATTERN_START, ATTR_PATTERN_END );
+ aNewSet.Put( *pItem );
+ pTabViewShell->ApplyAttributes( &aNewSet, &rOldSet, sal_True );
+ }
+ }
+ break;
+
+ default:
+ DBG_ERROR("falscher Slot bei ExecuteEdit");
+ break;
+ }
+}
+
+
+//------------------------------------------------------------------
+
+#define APPLY_HOR_JUSTIFY(j) \
+ { \
+ if ( !pHorJustify || (eHorJustify != (j) ) ) \
+ pTabViewShell->ApplyAttr( SvxHorJustifyItem( (j) ) ); \
+ else \
+ pTabViewShell->ApplyAttr( SvxHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD ) ); \
+ }
+
+#define APPLY_VER_JUSTIFY(j) \
+ { \
+ if ( !pVerJustify || (eVerJustify != (j) ) ) \
+ pTabViewShell->ApplyAttr( SvxVerJustifyItem( (j) ) ); \
+ else \
+ pTabViewShell->ApplyAttr( SvxVerJustifyItem( SVX_VER_JUSTIFY_STANDARD ) ); \
+ }
+
+void ScFormatShell::ExecuteAlignment( SfxRequest& rReq )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ SfxBindings& rBindings = pViewData->GetBindings();
+ const SfxItemSet* pSet = rReq.GetArgs();
+ sal_uInt16 nSlot = rReq.GetSlot();
+
+ pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
+
+ switch( nSlot )
+ {
+ // pseudo slots for Format menu
+ case SID_ALIGN_ANY_HDEFAULT:
+ case SID_ALIGN_ANY_LEFT:
+ case SID_ALIGN_ANY_HCENTER:
+ case SID_ALIGN_ANY_RIGHT:
+ case SID_ALIGN_ANY_JUSTIFIED:
+ pTabViewShell->ApplyAttr( SvxHorJustifyItem( lclConvertSlotToHAlign( nSlot ), ATTR_HOR_JUSTIFY ) );
+ break;
+ case SID_ALIGN_ANY_VDEFAULT:
+ case SID_ALIGN_ANY_TOP:
+ case SID_ALIGN_ANY_VCENTER:
+ case SID_ALIGN_ANY_BOTTOM:
+ pTabViewShell->ApplyAttr( SvxVerJustifyItem( lclConvertSlotToVAlign( nSlot ), ATTR_VER_JUSTIFY ) );
+ break;
+
+ default:
+ if( pSet )
+ {
+ const SfxPoolItem* pItem = NULL;
+ if( pSet->GetItemState(GetPool().GetWhich(nSlot), sal_True, &pItem ) == SFX_ITEM_SET )
+ {
+
+ switch ( nSlot )
+ {
+ case SID_ATTR_ALIGN_HOR_JUSTIFY:
+ case SID_ATTR_ALIGN_VER_JUSTIFY:
+ case SID_ATTR_ALIGN_INDENT:
+ case SID_ATTR_ALIGN_HYPHENATION:
+ case SID_ATTR_ALIGN_DEGREES:
+ case SID_ATTR_ALIGN_LOCKPOS:
+ case SID_ATTR_ALIGN_MARGIN:
+ case SID_ATTR_ALIGN_STACKED:
+ pTabViewShell->ApplyAttr( *pItem );
+ break;
+
+ case SID_H_ALIGNCELL:
+ {
+ SvxCellHorJustify eJust = (SvxCellHorJustify)((const SvxHorJustifyItem*)pItem)->GetValue();
+ // #i78476# update alignment of text in cell edit mode
+ pTabViewShell->UpdateInputHandlerCellAdjust( eJust );
+ pTabViewShell->ApplyAttr( SvxHorJustifyItem( eJust, ATTR_HOR_JUSTIFY ) );
+ }
+ break;
+ case SID_V_ALIGNCELL:
+ pTabViewShell->ApplyAttr( SvxVerJustifyItem( (SvxCellVerJustify)((const SvxVerJustifyItem*)pItem)->GetValue(), ATTR_VER_JUSTIFY ) );
+ break;
+ default:
+ DBG_ERROR( "ExecuteAlignment: invalid slot" );
+ return;
+ }
+ }
+ }
+ }
+
+ rBindings.Invalidate( SID_ALIGNLEFT );
+ rBindings.Invalidate( SID_ALIGNRIGHT );
+ rBindings.Invalidate( SID_ALIGNCENTERHOR );
+ rBindings.Invalidate( SID_ALIGNBLOCK );
+ rBindings.Invalidate( SID_ALIGNTOP );
+ rBindings.Invalidate( SID_ALIGNBOTTOM );
+ rBindings.Invalidate( SID_ALIGNCENTERVER );
+ rBindings.Invalidate( SID_V_ALIGNCELL );
+ rBindings.Invalidate( SID_H_ALIGNCELL );
+ // pseudo slots for Format menu
+ rBindings.Invalidate( SID_ALIGN_ANY_HDEFAULT );
+ rBindings.Invalidate( SID_ALIGN_ANY_LEFT );
+ rBindings.Invalidate( SID_ALIGN_ANY_HCENTER );
+ rBindings.Invalidate( SID_ALIGN_ANY_RIGHT );
+ rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED );
+ rBindings.Invalidate( SID_ALIGN_ANY_VDEFAULT );
+ rBindings.Invalidate( SID_ALIGN_ANY_TOP );
+ rBindings.Invalidate( SID_ALIGN_ANY_VCENTER );
+ rBindings.Invalidate( SID_ALIGN_ANY_BOTTOM );
+ rBindings.Update();
+
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+}
+
+void ScFormatShell::ExecuteTextAttr( SfxRequest& rReq )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ SfxBindings& rBindings = pViewData->GetBindings();
+ const ScPatternAttr* pAttrs = pTabViewShell->GetSelectionPattern();
+ const SfxItemSet* pSet = rReq.GetArgs();
+ sal_uInt16 nSlot = rReq.GetSlot();
+ SfxAllItemSet* pNewSet = 0;
+
+ pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
+
+ if ( (nSlot == SID_ATTR_CHAR_WEIGHT)
+ ||(nSlot == SID_ATTR_CHAR_POSTURE)
+ ||(nSlot == SID_ATTR_CHAR_UNDERLINE)
+ ||(nSlot == SID_ULINE_VAL_NONE)
+ ||(nSlot == SID_ULINE_VAL_SINGLE)
+ ||(nSlot == SID_ULINE_VAL_DOUBLE)
+ ||(nSlot == SID_ULINE_VAL_DOTTED) )
+ {
+ pNewSet = new SfxAllItemSet( GetPool() );
+
+ switch ( nSlot )
+ {
+ case SID_ATTR_CHAR_WEIGHT:
+ {
+ // #i78017 establish the same behaviour as in Writer
+ sal_uInt8 nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
+
+ SfxItemPool& rPool = GetPool();
+ SvxScriptSetItem aSetItem( nSlot, rPool );
+ if ( pSet )
+ aSetItem.PutItemForScriptType( nScript, pSet->Get( ATTR_FONT_WEIGHT ) );
+ else
+ {
+ // toggle manually
+
+ FontWeight eWeight = WEIGHT_BOLD;
+ SvxScriptSetItem aOldSetItem( nSlot, rPool );
+ aOldSetItem.GetItemSet().Put( pAttrs->GetItemSet(), sal_False );
+ const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript );
+ if ( pCore && ((const SvxWeightItem*)pCore)->GetWeight() == WEIGHT_BOLD )
+ eWeight = WEIGHT_NORMAL;
+
+ aSetItem.PutItemForScriptType( nScript, SvxWeightItem( eWeight, ATTR_FONT_WEIGHT ) );
+ }
+ pTabViewShell->ApplyUserItemSet( aSetItem.GetItemSet() );
+ pNewSet->Put( aSetItem.GetItemSet(), sal_False );
+ }
+ break;
+
+ case SID_ATTR_CHAR_POSTURE:
+ {
+ // #i78017 establish the same behaviour as in Writer
+ sal_uInt8 nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
+
+ SfxItemPool& rPool = GetPool();
+ SvxScriptSetItem aSetItem( nSlot, rPool );
+ if ( pSet )
+ aSetItem.PutItemForScriptType( nScript, pSet->Get( ATTR_FONT_POSTURE ) );
+ else
+ {
+ // toggle manually
+
+ FontItalic eItalic = ITALIC_NORMAL;
+ SvxScriptSetItem aOldSetItem( nSlot, rPool );
+ aOldSetItem.GetItemSet().Put( pAttrs->GetItemSet(), sal_False );
+ const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript );
+ if ( pCore && ((const SvxPostureItem*)pCore)->GetPosture() == ITALIC_NORMAL )
+ eItalic = ITALIC_NONE;
+
+ aSetItem.PutItemForScriptType( nScript, SvxPostureItem( eItalic, ATTR_FONT_POSTURE ) );
+ }
+ pTabViewShell->ApplyUserItemSet( aSetItem.GetItemSet() );
+ pNewSet->Put( aSetItem.GetItemSet(), sal_False );
+ }
+ break;
+
+ case SID_ATTR_CHAR_UNDERLINE:
+ {
+ FontUnderline eUnderline;
+
+ if( pSet )
+ {
+ const SvxUnderlineItem& rUnderline = (const SvxUnderlineItem&)pSet->Get( ATTR_FONT_UNDERLINE );
+
+ if( rUnderline.ISA(SvxUnderlineItem) )
+ {
+ pTabViewShell->ApplyAttr( rUnderline );
+ pNewSet->Put( rUnderline,rUnderline.Which() );
+ }
+ }
+ else
+ {
+ SvxUnderlineItem aUnderline( (const SvxUnderlineItem&)
+ pAttrs->GetItem(
+ ATTR_FONT_UNDERLINE ) );
+ eUnderline = (UNDERLINE_NONE != aUnderline.GetLineStyle())
+ ? UNDERLINE_NONE
+ : UNDERLINE_SINGLE;
+ aUnderline.SetLineStyle( eUnderline );
+ pTabViewShell->ApplyAttr( aUnderline );
+ pNewSet->Put( aUnderline,aUnderline.Which() );
+ }
+ }
+ break;
+
+ case SID_ULINE_VAL_NONE:
+ pTabViewShell->ApplyAttr( SvxUnderlineItem( UNDERLINE_NONE, ATTR_FONT_UNDERLINE ) );
+ break;
+ case SID_ULINE_VAL_SINGLE: // Toggles
+ case SID_ULINE_VAL_DOUBLE:
+ case SID_ULINE_VAL_DOTTED:
+ {
+ FontUnderline eOld = ((const SvxUnderlineItem&)
+ pAttrs->GetItem(ATTR_FONT_UNDERLINE)).GetLineStyle();
+ FontUnderline eNew = eOld;
+ switch (nSlot)
+ {
+ case SID_ULINE_VAL_SINGLE:
+ eNew = ( eOld == UNDERLINE_SINGLE ) ? UNDERLINE_NONE : UNDERLINE_SINGLE;
+ break;
+ case SID_ULINE_VAL_DOUBLE:
+ eNew = ( eOld == UNDERLINE_DOUBLE ) ? UNDERLINE_NONE : UNDERLINE_DOUBLE;
+ break;
+ case SID_ULINE_VAL_DOTTED:
+ eNew = ( eOld == UNDERLINE_DOTTED ) ? UNDERLINE_NONE : UNDERLINE_DOTTED;
+ break;
+ }
+ pTabViewShell->ApplyAttr( SvxUnderlineItem( eNew, ATTR_FONT_UNDERLINE ) );
+ }
+ break;
+
+ default:
+ break;
+ }
+ rBindings.Invalidate( nSlot );
+ }
+ else
+ {
+ /*
+ * "Selbstgemachte" RadioButton-Funktionalitaet
+ * Beim Toggle gibt es den Standard-State, d.h. kein
+ * Button ist gedrueckt
+ */
+
+ const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
+ const SfxPoolItem* pItem = NULL;
+ const SvxHorJustifyItem* pHorJustify = NULL;
+ const SvxVerJustifyItem* pVerJustify = NULL;
+ SvxCellHorJustify eHorJustify = SVX_HOR_JUSTIFY_STANDARD;
+ SvxCellVerJustify eVerJustify = SVX_VER_JUSTIFY_STANDARD;
+
+ if (rAttrSet.GetItemState(ATTR_HOR_JUSTIFY, sal_True,&pItem ) == SFX_ITEM_SET)
+ {
+ pHorJustify = (const SvxHorJustifyItem*)pItem;
+ eHorJustify = SvxCellHorJustify( pHorJustify->GetValue() );
+ }
+ if (rAttrSet.GetItemState(ATTR_VER_JUSTIFY, sal_True,&pItem ) == SFX_ITEM_SET)
+ {
+ pVerJustify = (const SvxVerJustifyItem*)pItem;
+ eVerJustify = SvxCellVerJustify( pVerJustify->GetValue() );
+ }
+
+ switch ( nSlot )
+ {
+ case SID_ALIGNLEFT:
+ rReq.SetSlot( SID_H_ALIGNCELL );
+ rReq.AppendItem( SvxHorJustifyItem(
+ !pHorJustify || (eHorJustify != SVX_HOR_JUSTIFY_LEFT) ?
+ SVX_HOR_JUSTIFY_LEFT : SVX_HOR_JUSTIFY_STANDARD, SID_H_ALIGNCELL ) );
+ ExecuteSlot( rReq, GetInterface() );
+ return;
+// APPLY_HOR_JUSTIFY( SVX_HOR_JUSTIFY_LEFT );
+ //break;
+
+ case SID_ALIGNRIGHT:
+ rReq.SetSlot( SID_H_ALIGNCELL );
+ rReq.AppendItem( SvxHorJustifyItem(
+ !pHorJustify || (eHorJustify != SVX_HOR_JUSTIFY_RIGHT) ?
+ SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_STANDARD, SID_H_ALIGNCELL ) );
+ ExecuteSlot( rReq, GetInterface() );
+ return;
+// APPLY_HOR_JUSTIFY( SVX_HOR_JUSTIFY_RIGHT );
+ //break;
+
+ case SID_ALIGNCENTERHOR:
+ rReq.SetSlot( SID_H_ALIGNCELL );
+ rReq.AppendItem( SvxHorJustifyItem(
+ !pHorJustify || (eHorJustify != SVX_HOR_JUSTIFY_CENTER) ?
+ SVX_HOR_JUSTIFY_CENTER : SVX_HOR_JUSTIFY_STANDARD, SID_H_ALIGNCELL ) );
+ ExecuteSlot( rReq, GetInterface() );
+ return;
+// APPLY_HOR_JUSTIFY( SVX_HOR_JUSTIFY_CENTER );
+ //break;
+
+ case SID_ALIGNBLOCK:
+ rReq.SetSlot( SID_H_ALIGNCELL );
+ rReq.AppendItem( SvxHorJustifyItem(
+ !pHorJustify || (eHorJustify != SVX_HOR_JUSTIFY_BLOCK) ?
+ SVX_HOR_JUSTIFY_BLOCK : SVX_HOR_JUSTIFY_STANDARD, SID_H_ALIGNCELL ) );
+ ExecuteSlot( rReq, GetInterface() );
+ return;
+// APPLY_HOR_JUSTIFY( SVX_HOR_JUSTIFY_BLOCK );
+ //break;
+
+ case SID_ALIGNTOP:
+ rReq.SetSlot( SID_V_ALIGNCELL );
+ rReq.AppendItem( SvxVerJustifyItem(
+ !pVerJustify || (eVerJustify != SVX_VER_JUSTIFY_TOP) ?
+ SVX_VER_JUSTIFY_TOP : SVX_VER_JUSTIFY_STANDARD, SID_V_ALIGNCELL ) );
+ ExecuteSlot( rReq, GetInterface() );
+ return;
+// APPLY_VER_JUSTIFY( SVX_VER_JUSTIFY_TOP );
+ //break;
+
+ case SID_ALIGNBOTTOM:
+ rReq.SetSlot( SID_V_ALIGNCELL );
+ rReq.AppendItem( SvxVerJustifyItem(
+ !pVerJustify || (eVerJustify != SVX_VER_JUSTIFY_BOTTOM) ?
+ SVX_VER_JUSTIFY_BOTTOM : SVX_VER_JUSTIFY_STANDARD, SID_V_ALIGNCELL ) );
+ ExecuteSlot( rReq, GetInterface() );
+ return;
+// APPLY_VER_JUSTIFY( SVX_VER_JUSTIFY_BOTTOM );
+ //break;
+
+ case SID_ALIGNCENTERVER:
+ rReq.SetSlot( SID_V_ALIGNCELL );
+ rReq.AppendItem( SvxVerJustifyItem(
+ !pVerJustify || (eVerJustify != SVX_VER_JUSTIFY_CENTER) ?
+ SVX_VER_JUSTIFY_CENTER : SVX_VER_JUSTIFY_STANDARD, SID_V_ALIGNCELL ) );
+ ExecuteSlot( rReq, GetInterface() );
+ return;
+// APPLY_VER_JUSTIFY( SVX_VER_JUSTIFY_CENTER );
+ //break;
+
+ default:
+ break;
+ }
+
+ }
+
+ rBindings.Update();
+// rReq.Done();
+
+ if( pNewSet )
+ {
+ rReq.Done( *pNewSet );
+ delete pNewSet;
+ }
+ else
+ {
+ rReq.Done();
+ }
+
+}
+
+#undef APPLY_HOR_JUSTIFY
+#undef APPLY_VER_JUSTIFY
+
+//------------------------------------------------------------------
+
+void ScFormatShell::ExecuteAttr( SfxRequest& rReq )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ SfxBindings& rBindings = pViewData->GetBindings();
+ const SfxItemSet* pNewAttrs = rReq.GetArgs();
+
+ pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
+
+ if ( !pNewAttrs )
+ {
+ sal_uInt16 nSlot = rReq.GetSlot();
+
+ switch ( nSlot )
+ {
+ case SID_ATTR_CHAR_FONT:
+ case SID_ATTR_CHAR_FONTHEIGHT:
+ pTabViewShell->ExecuteCellFormatDlg( rReq, TP_FONT ); // wenn ToolBar vertikal
+ break;
+
+ case SID_ATTR_ALIGN_LINEBREAK: // ohne Parameter als Toggle
+ {
+ const ScPatternAttr* pAttrs = pTabViewShell->GetSelectionPattern();
+ sal_Bool bOld = ((const SfxBoolItem&)pAttrs->GetItem(ATTR_LINEBREAK)).GetValue();
+ SfxBoolItem aBreakItem( ATTR_LINEBREAK, !bOld );
+ pTabViewShell->ApplyAttr( aBreakItem );
+
+ SfxAllItemSet aNewSet( GetPool() );
+ aNewSet.Put( aBreakItem,aBreakItem.Which() );
+ rReq.Done( aNewSet );
+
+ rBindings.Invalidate( nSlot );
+ }
+ break;
+
+ case SID_BACKGROUND_COLOR:
+ {
+ // SID_BACKGROUND_COLOR without arguments -> set transparent background
+
+ SvxBrushItem aBrushItem( (const SvxBrushItem&)
+ pTabViewShell->GetSelectionPattern()->
+ GetItem( ATTR_BACKGROUND ) );
+
+ aBrushItem.SetColor( COL_TRANSPARENT );
+
+ pTabViewShell->ApplyAttr( aBrushItem );
+ }
+ break;
+ }
+ }
+ else
+ {
+ sal_uInt16 nSlot = rReq.GetSlot();
+
+ switch ( nSlot )
+ {
+ case SID_ATTR_CHAR_OVERLINE:
+ case SID_ATTR_CHAR_STRIKEOUT:
+ case SID_ATTR_ALIGN_LINEBREAK:
+ case SID_ATTR_CHAR_COLOR:
+ case SID_ATTR_CHAR_CONTOUR:
+ case SID_ATTR_CHAR_SHADOWED:
+ case SID_ATTR_CHAR_RELIEF:
+ case SID_SCATTR_PROTECTION :
+ pTabViewShell->ApplyAttr( pNewAttrs->Get( pNewAttrs->GetPool()->GetWhich( nSlot ) ) );
+ rBindings.Invalidate( nSlot );
+ rBindings.Update( nSlot );
+ break;
+
+ case SID_ATTR_CHAR_FONT:
+ case SID_ATTR_CHAR_FONTHEIGHT:
+ {
+ // #i78017 establish the same behaviour as in Writer
+ sal_uInt8 nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
+ if (nSlot == SID_ATTR_CHAR_FONT)
+ nScript = pTabViewShell->GetSelectionScriptType();
+
+ SfxItemPool& rPool = GetPool();
+ SvxScriptSetItem aSetItem( nSlot, rPool );
+ sal_uInt16 nWhich = rPool.GetWhich( nSlot );
+ aSetItem.PutItemForScriptType( nScript, pNewAttrs->Get( nWhich ) );
+
+ pTabViewShell->ApplyUserItemSet( aSetItem.GetItemSet() );
+
+ rBindings.Invalidate( nSlot );
+ rBindings.Update( nSlot );
+ }
+ break;
+
+ case SID_FRAME_LINESTYLE:
+ {
+ // Default-Linie aktualisieren
+ const SvxBorderLine* pLine =
+ ((const SvxLineItem&)
+ pNewAttrs->Get( SID_FRAME_LINESTYLE )).
+ GetLine();
+
+ if ( pLine )
+ {
+ SvxBorderLine* pDefLine = pTabViewShell->GetDefaultFrameLine();
+
+ if ( pDefLine )
+ {
+ pDefLine->SetOutWidth( pLine->GetOutWidth() );
+ pDefLine->SetInWidth ( pLine->GetInWidth() );
+ pDefLine->SetDistance( pLine->GetDistance() );
+ pTabViewShell->SetSelectionFrameLines( pDefLine, sal_False );
+ }
+ else
+ {
+ pTabViewShell->SetDefaultFrameLine( pLine );
+ pTabViewShell->GetDefaultFrameLine()->SetColor( COL_BLACK );
+ pTabViewShell->SetSelectionFrameLines( pLine, sal_False );
+ }
+ }
+ else
+ {
+ Color aColorBlack( COL_BLACK );
+ SvxBorderLine aDefLine( &aColorBlack, 20, 0, 0 );
+ pTabViewShell->SetDefaultFrameLine( &aDefLine );
+ pTabViewShell->SetSelectionFrameLines( NULL, sal_False );
+ }
+ }
+ break;
+
+ case SID_FRAME_LINECOLOR:
+ {
+ SvxBorderLine* pDefLine = pTabViewShell->GetDefaultFrameLine();
+ const Color& rColor = ((const SvxColorItem&)
+ pNewAttrs->Get( SID_FRAME_LINECOLOR )).
+ GetValue();
+
+ // Default-Linie aktualisieren
+ if ( pDefLine )
+ {
+ pDefLine->SetColor( rColor );
+ pTabViewShell->SetSelectionFrameLines( pDefLine, sal_True );
+ }
+ else
+ {
+ SvxBorderLine aDefLine( &rColor, 20, 0, 0 );
+ pTabViewShell->SetDefaultFrameLine( &aDefLine );
+ pTabViewShell->SetSelectionFrameLines( &aDefLine, sal_False );
+ }
+ }
+ break;
+
+ case SID_ATTR_BORDER_OUTER:
+ case SID_ATTR_BORDER:
+ {
+ SvxBorderLine* pDefLine = pTabViewShell->GetDefaultFrameLine();
+ const ScPatternAttr* pOldAttrs = pTabViewShell->GetSelectionPattern();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SfxItemSet* pOldSet =
+ new SfxItemSet(
+ *(pDoc->GetPool()),
+ ATTR_PATTERN_START,
+ ATTR_PATTERN_END );
+ SfxItemSet* pNewSet =
+ new SfxItemSet(
+ *(pDoc->GetPool()),
+ ATTR_PATTERN_START,
+ ATTR_PATTERN_END );
+ const SfxPoolItem& rBorderAttr =
+ pOldAttrs->GetItemSet().
+ Get( ATTR_BORDER );
+
+ // Border-Items vom Controller auswerten:
+ const SfxPoolItem* pItem = 0;
+
+ if ( pNewAttrs->GetItemState( ATTR_BORDER, sal_True, &pItem )
+ == SFX_ITEM_SET )
+ {
+ // #100959# The SvxFrameToolBoxControl toolbox controller uses a default
+ // SvxBorderLine (all widths 0) to mark the lines that should be set.
+ // Macro recording uses a SvxBoxItem with the real values (OutWidth > 0)
+ // or NULL pointers for no lines.
+ // -> Substitute existing lines with pDefLine only if widths are 0.
+ SvxBoxItem aBoxItem ( *(const SvxBoxItem*)pItem );
+ if ( aBoxItem.GetTop() && aBoxItem.GetTop()->GetOutWidth() == 0 )
+ aBoxItem.SetLine( pDefLine, BOX_LINE_TOP );
+ if ( aBoxItem.GetBottom() && aBoxItem.GetBottom()->GetOutWidth() == 0 )
+ aBoxItem.SetLine( pDefLine, BOX_LINE_BOTTOM );
+ if ( aBoxItem.GetLeft() && aBoxItem.GetLeft()->GetOutWidth() == 0 )
+ aBoxItem.SetLine( pDefLine, BOX_LINE_LEFT );
+ if ( aBoxItem.GetRight() && aBoxItem.GetRight()->GetOutWidth() == 0 )
+ aBoxItem.SetLine( pDefLine, BOX_LINE_RIGHT );
+ pNewSet->Put( aBoxItem );
+ rReq.AppendItem( aBoxItem );
+ }
+
+ if ( pNewAttrs->GetItemState( ATTR_BORDER_INNER, sal_True, &pItem )
+ == SFX_ITEM_SET )
+ {
+ SvxBoxInfoItem aBoxInfoItem( *(const SvxBoxInfoItem*)pItem );
+ if ( aBoxInfoItem.GetHori() && aBoxInfoItem.GetHori()->GetOutWidth() == 0 )
+ aBoxInfoItem.SetLine( pDefLine, BOXINFO_LINE_HORI );
+ if ( aBoxInfoItem.GetVert() && aBoxInfoItem.GetVert()->GetOutWidth() == 0 )
+ aBoxInfoItem.SetLine( pDefLine, BOXINFO_LINE_VERT );
+ pNewSet->Put( aBoxInfoItem );
+ rReq.AppendItem( aBoxInfoItem );
+ }
+ else
+ {
+ SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
+ aBoxInfoItem.SetLine( NULL, BOXINFO_LINE_HORI );
+ aBoxInfoItem.SetLine( NULL, BOXINFO_LINE_VERT );
+ pNewSet->Put( aBoxInfoItem );
+ }
+
+ pOldSet->Put( rBorderAttr );
+ pTabViewShell->ApplyAttributes( pNewSet, pOldSet );
+
+ delete pOldSet;
+ delete pNewSet;
+ }
+ break;
+
+ // ATTR_BACKGROUND (=SID_ATTR_BRUSH) muss ueber zwei IDs
+ // gesetzt werden:
+ case SID_BACKGROUND_COLOR:
+ {
+ const SvxColorItem rNewColorItem = (const SvxColorItem&)
+ pNewAttrs->Get( SID_BACKGROUND_COLOR );
+
+ SvxBrushItem aBrushItem( (const SvxBrushItem&)
+ pTabViewShell->GetSelectionPattern()->
+ GetItem( ATTR_BACKGROUND ) );
+
+ aBrushItem.SetColor( rNewColorItem.GetValue() );
+
+ pTabViewShell->ApplyAttr( aBrushItem );
+ }
+ break;
+
+ case SID_ATTR_BRUSH:
+ {
+ SvxBrushItem aBrushItem( (const SvxBrushItem&)
+ pTabViewShell->GetSelectionPattern()->
+ GetItem( ATTR_BACKGROUND ) );
+ const SvxBrushItem& rNewBrushItem = (const SvxBrushItem&)
+ pNewAttrs->Get( GetPool().GetWhich(nSlot) );
+ aBrushItem.SetColor(rNewBrushItem.GetColor());
+ pTabViewShell->ApplyAttr( aBrushItem );
+ }
+ break;
+
+ case SID_ATTR_BORDER_SHADOW:
+ {
+ const SvxShadowItem& rNewShadowItem = (const SvxShadowItem&)
+ pNewAttrs->Get( ATTR_SHADOW );
+ pTabViewShell->ApplyAttr( rNewShadowItem );
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if( ! rReq.IsAPI() )
+ if( ! rReq.IsDone() )
+ rReq.Done();
+ }
+}
+
+void ScFormatShell::GetAttrState( SfxItemSet& rSet )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
+ const SvxBorderLine* pLine = pTabViewShell->GetDefaultFrameLine();
+ const SvxBrushItem& rBrushItem = (const SvxBrushItem&)rAttrSet.Get( ATTR_BACKGROUND );
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ rSet.Put( rAttrSet, sal_False );
+
+ // choose font info according to selection script type
+ sal_uInt8 nScript = 0; // GetSelectionScriptType never returns 0
+ if ( rSet.GetItemState( ATTR_FONT ) != SFX_ITEM_UNKNOWN )
+ {
+ if (!nScript) nScript = pTabViewShell->GetSelectionScriptType();
+ ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT, nScript );
+ }
+ if ( rSet.GetItemState( ATTR_FONT_HEIGHT ) != SFX_ITEM_UNKNOWN )
+ {
+ if (!nScript) nScript = pTabViewShell->GetSelectionScriptType();
+ ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT_HEIGHT, nScript );
+ }
+
+ while ( nWhich )
+ {
+ switch(nWhich)
+ {
+ case SID_BACKGROUND_COLOR:
+ {
+ rSet.Put( SvxColorItem( rBrushItem.GetColor(), SID_BACKGROUND_COLOR ) );
+ }
+ break;
+ case SID_FRAME_LINECOLOR:
+ {
+ rSet.Put( SvxColorItem( pLine ? pLine->GetColor() : Color(), SID_FRAME_LINECOLOR ) );
+ }
+ break;
+ case SID_ATTR_BRUSH:
+ {
+ rSet.Put( rBrushItem, GetPool().GetWhich(nWhich) );
+ }
+ break;
+/* case SID_ATTR_ALIGN_LINEBREAK:
+ {
+ const SfxBoolItem& rBreakItem = (const SfxBoolItem&)rAttrSet.Get( ATTR_LINEBREAK );
+ rSet.Put( rBreakItem, GetPool().GetWhich(nWhich) );
+ }
+ break;
+*/
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScFormatShell::GetTextAttrState( SfxItemSet& rSet )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
+ rSet.Put( rAttrSet, sal_False ); // ItemStates mitkopieren
+
+ // choose font info according to selection script type
+ sal_uInt8 nScript = 0; // GetSelectionScriptType never returns 0
+ if ( rSet.GetItemState( ATTR_FONT_WEIGHT ) != SFX_ITEM_UNKNOWN )
+ {
+ if (!nScript) nScript = pTabViewShell->GetSelectionScriptType();
+ ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT_WEIGHT, nScript );
+ }
+ if ( rSet.GetItemState( ATTR_FONT_POSTURE ) != SFX_ITEM_UNKNOWN )
+ {
+ if (!nScript) nScript = pTabViewShell->GetSelectionScriptType();
+ ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT_POSTURE, nScript );
+ }
+
+ SfxItemState eState;
+// const SfxPoolItem* pItem;
+
+ //--------------------------------------------------------------------
+ // eigene Kontrolle ueber RadioButton-Funktionalitaet:
+ //--------------------------------------------------------------------
+ // Unterstreichung
+ //------------------------
+
+ eState = rAttrSet.GetItemState( ATTR_FONT_UNDERLINE, sal_True );
+ if ( eState == SFX_ITEM_DONTCARE )
+ {
+ rSet.InvalidateItem( SID_ULINE_VAL_NONE );
+ rSet.InvalidateItem( SID_ULINE_VAL_SINGLE );
+ rSet.InvalidateItem( SID_ULINE_VAL_DOUBLE );
+ rSet.InvalidateItem( SID_ULINE_VAL_DOTTED );
+ }
+ else
+ {
+ FontUnderline eUnderline = ((const SvxUnderlineItem&)
+ rAttrSet.Get(ATTR_FONT_UNDERLINE)).GetLineStyle();
+ sal_uInt16 nId = SID_ULINE_VAL_NONE;
+ switch (eUnderline)
+ {
+ case UNDERLINE_SINGLE: nId = SID_ULINE_VAL_SINGLE; break;
+ case UNDERLINE_DOUBLE: nId = SID_ULINE_VAL_DOUBLE; break;
+ case UNDERLINE_DOTTED: nId = SID_ULINE_VAL_DOTTED; break;
+ default:
+ break;
+ }
+ rSet.Put( SfxBoolItem( nId, sal_True ) );
+ }
+
+ //------------------------
+ // horizontale Ausrichtung
+ //------------------------
+
+ const SvxHorJustifyItem* pHorJustify = NULL;
+ const SvxVerJustifyItem* pVerJustify = NULL;
+ SvxCellHorJustify eHorJustify = SVX_HOR_JUSTIFY_STANDARD;
+ SvxCellVerJustify eVerJustify = SVX_VER_JUSTIFY_STANDARD;
+ sal_uInt16 nWhich = 0;
+ sal_Bool bJustifyStd = sal_False;
+ SfxBoolItem aBoolItem ( 0, sal_True );
+
+ eState = rAttrSet.GetItemState( ATTR_HOR_JUSTIFY, sal_True,
+ (const SfxPoolItem**)&pHorJustify );
+ switch ( eState )
+ {
+ case SFX_ITEM_SET:
+ {
+ eHorJustify = SvxCellHorJustify( pHorJustify->GetValue() );
+
+ switch ( SvxCellHorJustify( pHorJustify->GetValue() ) )
+ {
+ case SVX_HOR_JUSTIFY_STANDARD:
+ break;
+
+ case SVX_HOR_JUSTIFY_LEFT:
+ nWhich = SID_ALIGNLEFT;
+ break;
+
+ case SVX_HOR_JUSTIFY_RIGHT:
+ nWhich = SID_ALIGNRIGHT;
+ break;
+
+ case SVX_HOR_JUSTIFY_CENTER:
+ nWhich = SID_ALIGNCENTERHOR;
+ break;
+
+ case SVX_HOR_JUSTIFY_BLOCK:
+ nWhich = SID_ALIGNBLOCK;
+ break;
+
+ case SVX_HOR_JUSTIFY_REPEAT:
+ default:
+ bJustifyStd = sal_True;
+ break;
+ }
+ }
+ break;
+
+ case SFX_ITEM_DONTCARE:
+ rSet.InvalidateItem( SID_ALIGNLEFT );
+ rSet.InvalidateItem( SID_ALIGNRIGHT );
+ rSet.InvalidateItem( SID_ALIGNCENTERHOR );
+ rSet.InvalidateItem( SID_ALIGNBLOCK );
+ break;
+
+ default:
+ bJustifyStd = sal_True;
+ break;
+ }
+
+ if ( nWhich )
+ {
+ aBoolItem.SetWhich( nWhich );
+ rSet.Put( aBoolItem );
+ }
+ else if ( bJustifyStd )
+ {
+ aBoolItem.SetValue( sal_False );
+ aBoolItem.SetWhich( SID_ALIGNLEFT ); rSet.Put( aBoolItem );
+ aBoolItem.SetWhich( SID_ALIGNRIGHT ); rSet.Put( aBoolItem );
+ aBoolItem.SetWhich( SID_ALIGNCENTERHOR ); rSet.Put( aBoolItem );
+ aBoolItem.SetWhich( SID_ALIGNBLOCK ); rSet.Put( aBoolItem );
+ bJustifyStd = sal_False;
+ }
+
+ //------------------------
+ // vertikale Ausrichtung
+ //------------------------
+
+ nWhich = 0;
+ aBoolItem.SetValue( sal_True );
+
+ eState = rAttrSet.GetItemState( ATTR_VER_JUSTIFY, sal_True,
+ (const SfxPoolItem**)&pVerJustify );
+
+ switch ( eState )
+ {
+ case SFX_ITEM_SET:
+ {
+ eVerJustify = SvxCellVerJustify( pVerJustify->GetValue() );
+
+ switch ( eVerJustify )
+ {
+ case SVX_VER_JUSTIFY_TOP:
+ nWhich = SID_ALIGNTOP;
+ break;
+
+ case SVX_VER_JUSTIFY_BOTTOM:
+ nWhich = SID_ALIGNBOTTOM;
+ break;
+
+ case SVX_VER_JUSTIFY_CENTER:
+ nWhich = SID_ALIGNCENTERVER;
+ break;
+
+ case SVX_VER_JUSTIFY_STANDARD:
+ default:
+ bJustifyStd = sal_True;
+ break;
+ }
+ }
+ break;
+
+ case SFX_ITEM_DONTCARE:
+ rSet.InvalidateItem( SID_ALIGNTOP );
+ rSet.InvalidateItem( SID_ALIGNBOTTOM );
+ rSet.InvalidateItem( SID_ALIGNCENTERVER );
+ break;
+
+ default:
+ bJustifyStd = sal_True;
+ break;
+ }
+
+ if ( nWhich )
+ {
+ aBoolItem.SetWhich( nWhich );
+ rSet.Put( aBoolItem );
+ }
+ else if ( bJustifyStd )
+ {
+ aBoolItem.SetValue( sal_False );
+ aBoolItem.SetWhich( SID_ALIGNTOP ); rSet.Put( aBoolItem );
+ aBoolItem.SetWhich( SID_ALIGNBOTTOM ); rSet.Put( aBoolItem );
+ aBoolItem.SetWhich( SID_ALIGNCENTERVER ); rSet.Put( aBoolItem );
+ }
+}
+
+
+//------------------------------------------------------------------
+
+void ScFormatShell::GetBorderState( SfxItemSet& rSet )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ SvxBoxItem aBoxItem( ATTR_BORDER );
+ SvxBoxInfoItem aInfoItem( ATTR_BORDER_INNER );
+
+ pTabViewShell->GetSelectionFrame( aBoxItem, aInfoItem );
+
+ if ( rSet.GetItemState( ATTR_BORDER ) != SFX_ITEM_UNKNOWN )
+ rSet.Put( aBoxItem );
+ if ( rSet.GetItemState( ATTR_BORDER_INNER ) != SFX_ITEM_UNKNOWN )
+ rSet.Put( aInfoItem );
+}
+
+//------------------------------------------------------------------
+
+void ScFormatShell::GetAlignState( SfxItemSet& rSet )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ SvxCellHorJustify eHAlign = SVX_HOR_JUSTIFY_STANDARD;
+ bool bHasHAlign = rAttrSet.GetItemState( ATTR_HOR_JUSTIFY ) != SFX_ITEM_DONTCARE;
+ if( bHasHAlign )
+ eHAlign = (SvxCellHorJustify)((const SvxHorJustifyItem&) rAttrSet.Get( ATTR_HOR_JUSTIFY )).GetValue();
+
+ SvxCellVerJustify eVAlign = SVX_VER_JUSTIFY_STANDARD;
+ bool bHasVAlign = rAttrSet.GetItemState( ATTR_VER_JUSTIFY ) != SFX_ITEM_DONTCARE;
+ if( bHasVAlign )
+ eVAlign = (SvxCellVerJustify)((const SvxVerJustifyItem&) rAttrSet.Get( ATTR_VER_JUSTIFY )).GetValue();
+
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case SID_H_ALIGNCELL:
+ if ( bHasHAlign )
+ rSet.Put( SvxHorJustifyItem( eHAlign, nWhich ));
+ break;
+ case SID_V_ALIGNCELL:
+ if ( bHasVAlign )
+ rSet.Put( SvxVerJustifyItem( eVAlign, nWhich ));
+ break;
+
+ // pseudo slots for Format menu
+ case SID_ALIGN_ANY_HDEFAULT:
+ case SID_ALIGN_ANY_LEFT:
+ case SID_ALIGN_ANY_HCENTER:
+ case SID_ALIGN_ANY_RIGHT:
+ case SID_ALIGN_ANY_JUSTIFIED:
+ rSet.Put( SfxBoolItem( nWhich, bHasHAlign && (eHAlign == lclConvertSlotToHAlign( nWhich )) ) );
+ break;
+ case SID_ALIGN_ANY_VDEFAULT:
+ case SID_ALIGN_ANY_TOP:
+ case SID_ALIGN_ANY_VCENTER:
+ case SID_ALIGN_ANY_BOTTOM:
+ rSet.Put( SfxBoolItem( nWhich, bHasVAlign && (eVAlign == lclConvertSlotToVAlign( nWhich )) ) );
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void ScFormatShell::GetNumFormatState( SfxItemSet& rSet )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+
+ // ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case SID_NUMBER_FORMAT:
+ {
+ String aFormatCode; // bleibt leer, wenn dont-care
+
+ const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
+ if ( rAttrSet.GetItemState( ATTR_VALUE_FORMAT ) != SFX_ITEM_DONTCARE )
+ {
+ sal_uLong nNumberFormat = ((const SfxUInt32Item&)rAttrSet.Get(
+ ATTR_VALUE_FORMAT )).GetValue();
+
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ const SvNumberformat* pFormatEntry = pFormatter->GetEntry( nNumberFormat );
+ if ( pFormatEntry )
+ aFormatCode = pFormatEntry->GetFormatstring();
+ }
+
+ rSet.Put( SfxStringItem( nWhich, aFormatCode ) );
+ }
+ break;
+
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+
+void ScFormatShell::ExecuteTextDirection( SfxRequest& rReq )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
+ if ( GetViewData()->HasEditView( GetViewData()->GetActivePart() ) )
+ {
+ SC_MOD()->InputEnterHandler();
+ pTabViewShell->UpdateInputHandler();
+ }
+
+ sal_uInt16 nSlot = rReq.GetSlot();
+ switch( nSlot )
+ {
+ case SID_TEXTDIRECTION_LEFT_TO_RIGHT:
+ case SID_TEXTDIRECTION_TOP_TO_BOTTOM:
+ {
+ sal_Bool bVert = (nSlot == SID_TEXTDIRECTION_TOP_TO_BOTTOM);
+ ScPatternAttr aAttr( GetViewData()->GetDocument()->GetPool() );
+ SfxItemSet& rItemSet = aAttr.GetItemSet();
+ rItemSet.Put( SfxBoolItem( ATTR_STACKED, bVert ) );
+ rItemSet.Put( SfxBoolItem( ATTR_VERTICAL_ASIAN, bVert ) );
+ pTabViewShell->ApplySelectionPattern( aAttr );
+ pTabViewShell->AdjustBlockHeight();
+ }
+ break;
+
+ case SID_ATTR_PARA_LEFT_TO_RIGHT:
+ case SID_ATTR_PARA_RIGHT_TO_LEFT:
+ {
+ SvxFrameDirection eDirection = ( nSlot == SID_ATTR_PARA_LEFT_TO_RIGHT ) ?
+ FRMDIR_HORI_LEFT_TOP : FRMDIR_HORI_RIGHT_TOP;
+ pTabViewShell->ApplyAttr( SvxFrameDirectionItem( eDirection, ATTR_WRITINGDIR ) );
+ }
+ break;
+ }
+}
+
+void ScFormatShell::GetTextDirectionState( SfxItemSet& rSet )
+{
+ ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell();
+ const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
+
+ sal_Bool bVertDontCare =
+ (rAttrSet.GetItemState( ATTR_VERTICAL_ASIAN ) == SFX_ITEM_DONTCARE) ||
+ (rAttrSet.GetItemState( ATTR_STACKED ) == SFX_ITEM_DONTCARE);
+ sal_Bool bLeftRight = !bVertDontCare &&
+ !((const SfxBoolItem&) rAttrSet.Get( ATTR_STACKED )).GetValue();
+ sal_Bool bTopBottom = !bVertDontCare && !bLeftRight &&
+ ((const SfxBoolItem&) rAttrSet.Get( ATTR_VERTICAL_ASIAN )).GetValue();
+
+ sal_Bool bBidiDontCare = (rAttrSet.GetItemState( ATTR_WRITINGDIR ) == SFX_ITEM_DONTCARE);
+ EEHorizontalTextDirection eBidiDir = EE_HTEXTDIR_DEFAULT;
+ if ( !bBidiDontCare )
+ {
+ SvxFrameDirection eCellDir = (SvxFrameDirection)((const SvxFrameDirectionItem&)
+ rAttrSet.Get( ATTR_WRITINGDIR )).GetValue();
+ if ( eCellDir == FRMDIR_ENVIRONMENT )
+ eBidiDir = (EEHorizontalTextDirection)GetViewData()->GetDocument()->
+ GetEditTextDirection( GetViewData()->GetTabNo() );
+ else if ( eCellDir == FRMDIR_HORI_RIGHT_TOP )
+ eBidiDir = EE_HTEXTDIR_R2L;
+ else
+ eBidiDir = EE_HTEXTDIR_L2R;
+ }
+
+ SvtLanguageOptions aLangOpt;
+ sal_Bool bDisableCTLFont = !aLangOpt.IsCTLFontEnabled();
+ sal_Bool bDisableVerticalText = !aLangOpt.IsVerticalTextEnabled();
+
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while( nWhich )
+ {
+ switch( nWhich )
+ {
+ case SID_TEXTDIRECTION_LEFT_TO_RIGHT:
+ case SID_TEXTDIRECTION_TOP_TO_BOTTOM:
+ if ( bDisableVerticalText )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ if( bVertDontCare )
+ rSet.InvalidateItem( nWhich );
+ else if ( nWhich == SID_TEXTDIRECTION_LEFT_TO_RIGHT )
+ rSet.Put( SfxBoolItem( nWhich, bLeftRight ) );
+ else
+ rSet.Put( SfxBoolItem( nWhich, bTopBottom ) );
+ }
+ break;
+
+ case SID_ATTR_PARA_LEFT_TO_RIGHT:
+ case SID_ATTR_PARA_RIGHT_TO_LEFT:
+ if ( bDisableCTLFont )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ if ( bTopBottom )
+ rSet.DisableItem( nWhich );
+ else if ( bBidiDontCare )
+ rSet.InvalidateItem( nWhich );
+ else if ( nWhich == SID_ATTR_PARA_LEFT_TO_RIGHT )
+ rSet.Put( SfxBoolItem( nWhich, eBidiDir == EE_HTEXTDIR_L2R ) );
+ else
+ rSet.Put( SfxBoolItem( nWhich, eBidiDir == EE_HTEXTDIR_R2L ) );
+ }
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void ScFormatShell::ExecFormatPaintbrush( SfxRequest& rReq )
+{
+ ScViewFunc* pView = pViewData->GetView();
+ if ( pView->HasPaintBrush() )
+ {
+ // cancel paintbrush mode
+ pView->ResetBrushDocument();
+ }
+ else
+ {
+ sal_Bool bLock = sal_False;
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ if( pArgs && pArgs->Count() >= 1 )
+ bLock = static_cast<const SfxBoolItem&>(pArgs->Get(SID_FORMATPAINTBRUSH)).GetValue();
+
+ // in case of multi selection, deselect all and use the cursor position
+ ScRange aDummy;
+ if ( pViewData->GetSimpleArea(aDummy) != SC_MARK_SIMPLE )
+ pView->Unmark();
+
+ ScDocument* pBrushDoc = new ScDocument( SCDOCMODE_CLIP );
+ pView->CopyToClip( pBrushDoc, sal_False, sal_True );
+ pView->SetBrushDocument( pBrushDoc, bLock );
+ }
+}
+
+void ScFormatShell::StateFormatPaintbrush( SfxItemSet& rSet )
+{
+ if ( pViewData->HasEditView( pViewData->GetActivePart() ) )
+ rSet.DisableItem( SID_FORMATPAINTBRUSH );
+ else
+ rSet.Put( SfxBoolItem( SID_FORMATPAINTBRUSH, pViewData->GetView()->HasPaintBrush() ) );
+}
+
diff --git a/sc/source/ui/view/galwrap.cxx b/sc/source/ui/view/galwrap.cxx
new file mode 100644
index 000000000000..2be622ced2c8
--- /dev/null
+++ b/sc/source/ui/view/galwrap.cxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <vcl/graph.hxx>
+#include <svx/gallery.hxx>
+#include <sfx2/app.hxx>
+
+// -----------------------------------------------------------------------
+
+Graphic GalleryGetGraphic()
+{
+ GalleryExplorer* pGal = SVX_GALLERY();
+ DBG_ASSERT( pGal, "Wo ist die Gallery?" );
+ return pGal->GetGraphic();
+}
+
+sal_uInt16 GallerySGA_FORMAT_GRAPHIC()
+{
+ return SGA_FORMAT_GRAPHIC;
+}
+
+sal_Bool GalleryIsLinkage()
+{
+ GalleryExplorer* pGal = SVX_GALLERY();
+ DBG_ASSERT( pGal, "Wo ist die Gallery?" );
+ return pGal->IsLinkage();
+}
+
+String GalleryGetFullPath()
+{
+ GalleryExplorer* pGal = SVX_GALLERY();
+ DBG_ASSERT( pGal, "Wo ist die Gallery?" );
+// return pGal->GetPath().GetFull();
+ return pGal->GetURL().GetMainURL(INetURLObject::NO_DECODE);
+ // URL as stored in GraphicLink must be encoded
+}
+
+String GalleryGetFilterName()
+{
+ GalleryExplorer* pGal = SVX_GALLERY();
+ DBG_ASSERT( pGal, "Wo ist die Gallery?" );
+ return pGal->GetFilterName();
+}
+
+
+
+
diff --git a/sc/source/ui/view/gridmerg.cxx b/sc/source/ui/view/gridmerg.cxx
new file mode 100644
index 000000000000..6bcc4ad42f30
--- /dev/null
+++ b/sc/source/ui/view/gridmerg.cxx
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <vcl/outdev.hxx>
+
+#include "gridmerg.hxx"
+
+//------------------------------------------------------------------
+
+ScGridMerger::ScGridMerger( OutputDevice* pOutDev, long nOnePixelX, long nOnePixelY ) :
+ pDev( pOutDev ),
+ nOneX( nOnePixelX ),
+ nOneY( nOnePixelY ),
+ nCount( 0 ),
+ bVertical( sal_False )
+{
+ // optimize (DrawGrid) only for pixel MapMode,
+ // to avoid rounding errors
+
+ bOptimize = ( pDev->GetMapMode().GetMapUnit() == MAP_PIXEL );
+}
+
+ScGridMerger::~ScGridMerger()
+{
+ Flush();
+}
+
+void ScGridMerger::AddLine( long nStart, long nEnd, long nPos )
+{
+ if ( nCount )
+ {
+ // not first line - test fix position
+ // more than one previous line - test distance
+
+ if ( nStart != nFixStart || nEnd != nFixEnd )
+ {
+ if ( nCount == 1 && nPos == nVarStart &&
+ ( nStart == nFixEnd ||
+ nStart == nFixEnd + ( bVertical ? nOneY : nOneX ) ) )
+ {
+ // additional optimization: extend connected lines
+ // keep nCount at 1
+ nFixEnd = nEnd;
+ }
+ else
+ Flush();
+ }
+ else if ( nCount == 1 )
+ {
+ nVarDiff = nPos - nVarStart;
+ ++nCount;
+ }
+ else if ( nPos != nVarStart + nCount * nVarDiff ) //! keep VarEnd?
+ Flush();
+ else
+ ++nCount;
+ }
+
+ if ( !nCount )
+ {
+ // first line (or flushed above) - just store
+
+ nFixStart = nStart;
+ nFixEnd = nEnd;
+ nVarStart = nPos;
+ nVarDiff = 0;
+ nCount = 1;
+ }
+}
+
+void ScGridMerger::AddHorLine( long nX1, long nX2, long nY )
+{
+ if ( bOptimize )
+ {
+ if ( bVertical )
+ {
+ Flush();
+ bVertical = sal_False;
+ }
+ AddLine( nX1, nX2, nY );
+ }
+ else
+ pDev->DrawLine( Point( nX1, nY ), Point( nX2, nY ) );
+}
+
+void ScGridMerger::AddVerLine( long nX, long nY1, long nY2 )
+{
+ if ( bOptimize )
+ {
+ if ( !bVertical )
+ {
+ Flush();
+ bVertical = sal_True;
+ }
+ AddLine( nY1, nY2, nX );
+ }
+ else
+ pDev->DrawLine( Point( nX, nY1 ), Point( nX, nY2 ) );
+}
+
+void ScGridMerger::Flush()
+{
+ if (nCount)
+ {
+ if (bVertical)
+ {
+ if ( nCount == 1 )
+ pDev->DrawLine( Point( nVarStart, nFixStart ), Point( nVarStart, nFixEnd ) );
+ else
+ {
+ long nVarEnd = nVarStart + ( nCount - 1 ) * nVarDiff;
+ if ( nVarDiff < 0 )
+ {
+ // nVarDiff is negative in RTL layout mode
+ // Change the positions so DrawGrid is called with a positive distance
+ // (nVarStart / nVarDiff can be modified, aren't used after Flush)
+
+ nVarDiff = -nVarDiff;
+ long nTemp = nVarStart;
+ nVarStart = nVarEnd;
+ nVarEnd = nTemp;
+ }
+ pDev->DrawGrid( Rectangle( nVarStart, nFixStart, nVarEnd, nFixEnd ),
+ Size( nVarDiff, nFixEnd - nFixStart ),
+ GRID_VERTLINES );
+ }
+ }
+ else
+ {
+ if ( nCount == 1 )
+ pDev->DrawLine( Point( nFixStart, nVarStart ), Point( nFixEnd, nVarStart ) );
+ else
+ {
+ long nVarEnd = nVarStart + ( nCount - 1 ) * nVarDiff;
+ pDev->DrawGrid( Rectangle( nFixStart, nVarStart, nFixEnd, nVarEnd ),
+ Size( nFixEnd - nFixStart, nVarDiff ),
+ GRID_HORZLINES );
+ }
+ }
+ nCount = 0;
+ }
+}
+
+
+
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
new file mode 100644
index 000000000000..d350da754433
--- /dev/null
+++ b/sc/source/ui/view/gridwin.cxx
@@ -0,0 +1,5706 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "scitems.hxx"
+
+#include <memory> //auto_ptr
+#include <editeng/adjitem.hxx>
+#include <svx/algitem.hxx>
+#include <svx/dbexch.hrc>
+#include <editeng/editview.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/svdetc.hxx>
+#include <editeng/editobj.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/docfile.hxx>
+#include <svl/stritem.hxx>
+#include <svtools/svlbox.hxx>
+#include <svtools/svtabbx.hxx>
+#include <svl/urlbmk.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/cursor.hxx>
+#include <vcl/sound.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/hatch.hxx>
+#include <sot/formats.hxx>
+#include <sot/clsids.hxx>
+
+#include <svx/svdview.hxx> // fuer Command-Handler (COMMAND_INSERTTEXT)
+#include <editeng/outliner.hxx> // fuer Command-Handler (COMMAND_INSERTTEXT)
+#include <svx/svditer.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdpagv.hxx>
+
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
+#include <com/sun/star/sheet/DataPilotTableResultData.hpp>
+#include <com/sun/star/sheet/DataPilotTablePositionData.hpp>
+#include <com/sun/star/sheet/DataPilotTablePositionType.hpp>
+#include <com/sun/star/sheet/MemberResultFlags.hpp>
+#include <com/sun/star/awt/KeyModifier.hpp>
+#include <com/sun/star/awt/MouseButton.hpp>
+#include <com/sun/star/script/vba/VBAEventId.hpp>
+#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
+
+#include "gridwin.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "viewdata.hxx"
+#include "tabview.hxx"
+#include "select.hxx"
+#include "scmod.hxx"
+#include "document.hxx"
+#include "attrib.hxx"
+#include "dbcolect.hxx"
+#include "stlpool.hxx"
+#include "printfun.hxx"
+#include "cbutton.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "editutil.hxx"
+#include "scresid.hxx"
+#include "inputhdl.hxx"
+#include "uiitems.hxx" // Filter-Dialog - auslagern !!!
+#include "filtdlg.hxx"
+#include "impex.hxx" // Sylk-ID fuer CB
+#include "cell.hxx" // fuer Edit-Felder
+#include "patattr.hxx"
+#include "notemark.hxx"
+#include "rfindlst.hxx"
+#include "docpool.hxx"
+#include "output.hxx"
+#include "docfunc.hxx"
+#include "dbdocfun.hxx"
+#include "dpobject.hxx"
+#include "dpoutput.hxx"
+#include "transobj.hxx"
+#include "drwtrans.hxx"
+#include "seltrans.hxx"
+#include "sizedev.hxx"
+#include "AccessibilityHints.hxx"
+#include "dpsave.hxx"
+#include "viewuno.hxx"
+#include "compiler.hxx"
+#include "editable.hxx"
+#include "fillinfo.hxx"
+#include "scitems.hxx"
+#include "userdat.hxx"
+#include "drwlayer.hxx"
+#include "attrib.hxx"
+#include "validat.hxx"
+#include "tabprotection.hxx"
+#include "postit.hxx"
+#include "dpcontrol.hxx"
+#include "cellsuno.hxx"
+
+#include "drawview.hxx"
+#include <svx/sdrpagewindow.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <vcl/svapp.hxx>
+#include <svx/sdr/overlay/overlayselection.hxx>
+
+using namespace com::sun::star;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::Any;
+
+const sal_uInt8 SC_NESTEDBUTTON_NONE = 0;
+const sal_uInt8 SC_NESTEDBUTTON_DOWN = 1;
+const sal_uInt8 SC_NESTEDBUTTON_UP = 2;
+
+#define SC_AUTOFILTER_ALL 0
+#define SC_AUTOFILTER_TOP10 1
+#define SC_AUTOFILTER_CUSTOM 2
+
+// Modi fuer die FilterListBox
+enum ScFilterBoxMode
+{
+ SC_FILTERBOX_FILTER,
+ SC_FILTERBOX_DATASELECT,
+ SC_FILTERBOX_SCENARIO,
+ SC_FILTERBOX_PAGEFIELD
+};
+
+extern SfxViewShell* pScActiveViewShell; // global.cxx
+extern sal_uInt16 nScClickMouseModifier; // global.cxx
+extern sal_uInt16 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
+{
+private:
+ ScGridWindow* pGridWin;
+ SCCOL nCol;
+ SCROW nRow;
+ sal_Bool bButtonDown;
+ sal_Bool bInit;
+ sal_Bool bCancelled;
+ sal_Bool bInSelect;
+ bool mbListHasDates;
+ sal_uLong nSel;
+ ScFilterBoxMode eMode;
+
+protected:
+ virtual void LoseFocus();
+ void SelectHdl();
+
+public:
+ ScFilterListBox( Window* pParent, ScGridWindow* pGrid,
+ SCCOL nNewCol, SCROW nNewRow, ScFilterBoxMode eNewMode );
+ ~ScFilterListBox();
+
+ virtual long PreNotify( NotifyEvent& rNEvt );
+ virtual void Select();
+
+ SCCOL GetCol() const { return nCol; }
+ SCROW GetRow() const { return nRow; }
+ ScFilterBoxMode GetMode() const { return eMode; }
+ sal_Bool IsDataSelect() const { return (eMode == SC_FILTERBOX_DATASELECT); }
+ void EndInit();
+ sal_Bool IsInInit() const { return bInit; }
+ void SetCancelled() { bCancelled = sal_True; }
+ sal_Bool IsInSelect() const { return bInSelect; }
+ void SetListHasDates(bool b) { mbListHasDates = b; }
+ bool HasDates() const { return mbListHasDates; }
+};
+
+//-------------------------------------------------------------------
+
+// ListBox in einem FloatingWindow (pParent)
+ScFilterListBox::ScFilterListBox( Window* pParent, ScGridWindow* pGrid,
+ SCCOL nNewCol, SCROW nNewRow, ScFilterBoxMode eNewMode ) :
+ ListBox( pParent, WB_AUTOHSCROLL ),
+ pGridWin( pGrid ),
+ nCol( nNewCol ),
+ nRow( nNewRow ),
+ bButtonDown( sal_False ),
+ bInit( sal_True ),
+ bCancelled( sal_False ),
+ bInSelect( sal_False ),
+ mbListHasDates(false),
+ nSel( 0 ),
+ eMode( eNewMode )
+{
+}
+
+__EXPORT ScFilterListBox::~ScFilterListBox()
+{
+ if (IsMouseCaptured())
+ ReleaseMouse();
+}
+
+void ScFilterListBox::EndInit()
+{
+ sal_uInt16 nPos = GetSelectEntryPos();
+ if ( LISTBOX_ENTRY_NOTFOUND == nPos )
+ nSel = 0;
+ else
+ nSel = nPos;
+
+ bInit = sal_False;
+}
+
+void __EXPORT ScFilterListBox::LoseFocus()
+{
+#ifndef UNX
+ Hide();
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+long ScFilterListBox::PreNotify( NotifyEvent& rNEvt )
+{
+ long nDone = 0;
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
+ KeyCode aCode = aKeyEvt.GetKeyCode();
+ if ( !aCode.GetModifier() ) // ohne alle Modifiers
+ {
+ sal_uInt16 nKey = aCode.GetCode();
+ if ( nKey == KEY_RETURN )
+ {
+ SelectHdl(); // auswaehlen
+ nDone = 1;
+ }
+ else if ( nKey == KEY_ESCAPE )
+ {
+ pGridWin->ClickExtern(); // loescht die List-Box !!!
+ nDone = 1;
+ }
+ }
+ }
+
+ return nDone ? nDone : ListBox::PreNotify( rNEvt );
+}
+
+void __EXPORT ScFilterListBox::Select()
+{
+ ListBox::Select();
+ SelectHdl();
+}
+
+void __EXPORT ScFilterListBox::SelectHdl()
+{
+ if ( !IsTravelSelect() && !bInit && !bCancelled )
+ {
+ sal_uInt16 nPos = GetSelectEntryPos();
+ if ( LISTBOX_ENTRY_NOTFOUND != nPos )
+ {
+ nSel = nPos;
+ if (!bButtonDown)
+ {
+ // #i81298# set bInSelect flag, so the box isn't deleted from modifications within FilterSelect
+ bInSelect = sal_True;
+ pGridWin->FilterSelect( nSel );
+ bInSelect = sal_False;
+ }
+ }
+ }
+}
+
+// ============================================================================
+
+// use a System floating window for the above filter listbox
+class ScFilterFloatingWindow : public FloatingWindow
+{
+public:
+ ScFilterFloatingWindow( Window* pParent, WinBits nStyle = WB_STDFLOATWIN );
+ virtual ~ScFilterFloatingWindow();
+ // required for System FloatingWindows that will not process KeyInput by themselves
+ virtual Window* GetPreferredKeyInputWindow();
+};
+
+ScFilterFloatingWindow::ScFilterFloatingWindow( Window* pParent, WinBits nStyle ) :
+ FloatingWindow( pParent, nStyle|WB_SYSTEMWINDOW ) // make it a system floater
+ {}
+
+ScFilterFloatingWindow::~ScFilterFloatingWindow()
+{
+ EndPopupMode();
+}
+
+Window* ScFilterFloatingWindow::GetPreferredKeyInputWindow()
+{
+ // redirect keyinput in the child window
+ return GetWindow(WINDOW_FIRSTCHILD) ? GetWindow(WINDOW_FIRSTCHILD)->GetPreferredKeyInputWindow() : NULL; // will be the FilterBox
+}
+
+// ============================================================================
+
+sal_Bool lcl_IsEditableMatrix( ScDocument* pDoc, const ScRange& rRange )
+{
+ // wenn es ein editierbarer Bereich ist, und rechts unten eine Matrix-Zelle
+ // mit Origin links oben liegt, enthaelt der Bereich genau die Matrix.
+ //! Direkt die MatrixEdges Funktionen von der Column herausreichen ???
+
+ if ( !pDoc->IsBlockEditable( rRange.aStart.Tab(), rRange.aStart.Col(),rRange.aStart.Row(),
+ rRange.aEnd.Col(),rRange.aEnd.Row() ) )
+ return sal_False;
+
+ ScAddress aPos;
+ const ScBaseCell* pCell = pDoc->GetCell( rRange.aEnd );
+ return ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA &&
+ ((ScFormulaCell*)pCell)->GetMatrixOrigin(aPos) && aPos == rRange.aStart );
+
+}
+
+void lcl_UnLockComment( ScDrawView* pView, SdrPageView* pPV, SdrModel* pDrDoc, const Point& rPos, ScViewData* pViewData )
+{
+ if (!pView && !pPV && !pDrDoc && !pViewData)
+ return;
+
+ ScDocument& rDoc = *pViewData->GetDocument();
+ ScAddress aCellPos( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() );
+ ScPostIt* pNote = rDoc.GetNote( aCellPos );
+ SdrObject* pObj = pNote ? pNote->GetCaption() : 0;
+ if( pObj && pObj->GetLogicRect().IsInside( rPos ) && ScDrawLayer::IsNoteCaption( pObj ) )
+ {
+ const ScProtectionAttr* pProtAttr = static_cast< const ScProtectionAttr* > (rDoc.GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_PROTECTION ) );
+ bool bProtectAttr = pProtAttr->GetProtection() || pProtAttr->GetHideCell() ;
+ bool bProtectDoc = rDoc.IsTabProtected( aCellPos.Tab() ) || pViewData->GetSfxDocShell()->IsReadOnly() ;
+ // unlock internal layer (if not protected), will be relocked in ScDrawView::MarkListHasChanged()
+ pView->LockInternalLayer( bProtectDoc && bProtectAttr );
+ }
+}
+
+sal_Bool lcl_GetHyperlinkCell(ScDocument* pDoc, SCCOL& rPosX, SCROW& rPosY, SCTAB nTab, ScBaseCell*& rpCell )
+{
+ sal_Bool bFound = sal_False;
+ do
+ {
+ pDoc->GetCell( rPosX, rPosY, nTab, rpCell );
+ if ( !rpCell || rpCell->GetCellType() == CELLTYPE_NOTE )
+ {
+ if ( rPosX <= 0 )
+ return sal_False; // alles leer bis links
+ else
+ --rPosX; // weitersuchen
+ }
+ else if ( rpCell->GetCellType() == CELLTYPE_EDIT)
+ bFound = sal_True;
+ else if (rpCell->GetCellType() == CELLTYPE_FORMULA &&
+ static_cast<ScFormulaCell*>(rpCell)->IsHyperLinkCell())
+ bFound = sal_True;
+ else
+ return sal_False; // andere Zelle
+ }
+ while ( !bFound );
+
+ return bFound;
+}
+
+// ---------------------------------------------------------------------------
+// WB_DIALOGCONTROL noetig fuer UNO-Controls
+ScGridWindow::ScGridWindow( Window* pParent, ScViewData* pData, ScSplitPos eWhichPos )
+: Window( pParent, WB_CLIPCHILDREN | WB_DIALOGCONTROL ),
+ DropTargetHelper( this ),
+ DragSourceHelper( this ),
+ mpOOCursors( NULL ),
+ mpOOSelection( NULL ),
+ mpOOAutoFill( NULL ),
+ mpOODragRect( NULL ),
+ mpOOHeader( NULL ),
+ mpOOShrink( NULL ),
+ mpAutoFillRect(static_cast<Rectangle*>(NULL)),
+ pViewData( pData ),
+ eWhich( eWhichPos ),
+ pNoteMarker( NULL ),
+ pFilterBox( NULL ),
+ pFilterFloat( NULL ),
+ mpDPFieldPopup(NULL),
+ mpFilterButton(NULL),
+ nCursorHideCount( 0 ),
+ bMarking( sal_False ),
+ nButtonDown( 0 ),
+ bEEMouse( sal_False ),
+ nMouseStatus( SC_GM_NONE ),
+ nNestedButtonState( SC_NESTEDBUTTON_NONE ),
+ bDPMouse( sal_False ),
+ bRFMouse( sal_False ),
+ nPagebreakMouse( SC_PD_NONE ),
+ bPagebreakDrawn( sal_False ),
+ nPageScript( 0 ),
+ bDragRect( sal_False ),
+ meDragInsertMode( INS_NONE ),
+ nCurrentPointer( 0 ),
+ bIsInScroll( sal_False ),
+ bIsInPaint( sal_False ),
+ aComboButton( this ),
+ aCurMousePos( 0,0 ),
+ nPaintCount( 0 ),
+ bNeedsRepaint( sal_False ),
+ bAutoMarkVisible( sal_False ),
+ bListValButton( sal_False )
+{
+ switch(eWhich)
+ {
+ case SC_SPLIT_TOPLEFT:
+ eHWhich = SC_SPLIT_LEFT;
+ eVWhich = SC_SPLIT_TOP;
+ break;
+ case SC_SPLIT_TOPRIGHT:
+ eHWhich = SC_SPLIT_RIGHT;
+ eVWhich = SC_SPLIT_TOP;
+ break;
+ case SC_SPLIT_BOTTOMLEFT:
+ eHWhich = SC_SPLIT_LEFT;
+ eVWhich = SC_SPLIT_BOTTOM;
+ break;
+ case SC_SPLIT_BOTTOMRIGHT:
+ eHWhich = SC_SPLIT_RIGHT;
+ eVWhich = SC_SPLIT_BOTTOM;
+ break;
+ default:
+ DBG_ERROR("GridWindow: falsche Position");
+ }
+
+ SetBackground();
+
+ SetMapMode(pViewData->GetLogicMode(eWhich));
+// EnableDrop();
+ EnableChildTransparentMode();
+ SetDialogControlFlags( WINDOW_DLGCTRL_RETURN | WINDOW_DLGCTRL_WANTFOCUS );
+
+ SetHelpId( HID_SC_WIN_GRIDWIN );
+ SetUniqueId( HID_SC_WIN_GRIDWIN );
+
+ SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
+ EnableRTL( sal_False );
+}
+
+__EXPORT ScGridWindow::~ScGridWindow()
+{
+ // #114409#
+ ImpDestroyOverlayObjects();
+
+ delete pFilterBox;
+ delete pFilterFloat;
+ delete pNoteMarker;
+}
+
+void __EXPORT ScGridWindow::Resize( const Size& )
+{
+ // gar nix
+}
+
+void ScGridWindow::ClickExtern()
+{
+ do
+ {
+ // #i81298# don't delete the filter box when called from its select handler
+ // (possible through row header size update)
+ // #i84277# when initializing the filter box, a Basic error can deactivate the view
+ if ( pFilterBox && ( pFilterBox->IsInSelect() || pFilterBox->IsInInit() ) )
+ {
+ break;
+ }
+
+ DELETEZ(pFilterBox);
+ DELETEZ(pFilterFloat);
+ }
+ while (false);
+
+ if (mpDPFieldPopup.get())
+ {
+ mpDPFieldPopup->close(false);
+ mpDPFieldPopup.reset();
+ }
+}
+
+IMPL_LINK( ScGridWindow, PopupModeEndHdl, FloatingWindow*, EMPTYARG )
+{
+ if (pFilterBox)
+ pFilterBox->SetCancelled(); // nicht mehr auswaehlen
+ GrabFocus();
+ return 0;
+}
+
+IMPL_LINK( ScGridWindow, PopupSpellingHdl, SpellCallbackInfo*, pInfo )
+{
+ if( pInfo->nCommand == SPELLCMD_STARTSPELLDLG )
+ pViewData->GetDispatcher().Execute( SID_SPELL_DIALOG, SFX_CALLMODE_ASYNCHRON );
+ return 0;
+}
+
+void ScGridWindow::ExecPageFieldSelect( SCCOL nCol, SCROW nRow, sal_Bool bHasSelection, const String& rStr )
+{
+ //! gridwin2 ?
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
+ if ( pDPObj && nCol > 0 )
+ {
+ // look for the dimension header left of the drop-down arrow
+ sal_uInt16 nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
+ long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient );
+ if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE )
+ {
+ ScDPSaveData aSaveData( *pDPObj->GetSaveData() );
+
+ sal_Bool bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nField, bIsDataLayout );
+ if ( !bIsDataLayout )
+ {
+ ScDPSaveDimension* pDim = aSaveData.GetDimensionByName(aDimName);
+
+ if ( bHasSelection )
+ pDim->SetCurrentPage( &rStr );
+ else
+ pDim->SetCurrentPage( NULL );
+
+ ScDPObject aNewObj( *pDPObj );
+ aNewObj.SetSaveData( aSaveData );
+ ScDBDocFunc aFunc( *pViewData->GetDocShell() );
+ aFunc.DataPilotUpdate( pDPObj, &aNewObj, sal_True, sal_False );
+ pViewData->GetView()->CursorPosChanged(); // shells may be switched
+ }
+ }
+ }
+}
+
+void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol, SCROW nRow )
+{
+ //! merge position/size handling with DoAutoFilterMenue
+
+ delete pFilterBox;
+ delete pFilterFloat;
+
+ sal_uInt16 i;
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ long nSizeX = 0;
+ long nSizeY = 0;
+ long nHeight = 0;
+ pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
+ Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich );
+ if ( bLayoutRTL )
+ aPos.X() -= nSizeX;
+
+ Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) );
+
+ aPos.X() -= 1;
+ aPos.Y() += nSizeY - 1;
+
+ pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) ); // not resizable etc.
+ pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) );
+ pFilterBox = new ScFilterListBox( pFilterFloat, this, nCol, nRow, SC_FILTERBOX_PAGEFIELD );
+ if ( bLayoutRTL )
+ pFilterBox->EnableMirroring();
+
+ nSizeX += 1;
+
+ {
+ Font aOldFont = GetFont(); SetFont( pFilterBox->GetFont() );
+ MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL );
+
+ nHeight = GetTextHeight();
+ nHeight *= SC_FILTERLISTBOX_LINES;
+
+ SetMapMode( aOldMode );
+ SetFont( aOldFont );
+ }
+
+ // SetSize comes later
+
+ TypedScStrCollection aStrings( 128, 128 );
+
+ // get list box entries and selection
+ sal_Bool bHasCurrentPage = sal_False;
+ String aCurrentPage;
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
+ if ( pDPObj && nCol > 0 )
+ {
+ // look for the dimension header left of the drop-down arrow
+ sal_uInt16 nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
+ long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient );
+ if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE )
+ {
+ pDPObj->FillPageList( aStrings, nField );
+
+ // get current page from SaveData
+
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ sal_Bool bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( nField, bIsDataLayout );
+ if ( pSaveData && !bIsDataLayout )
+ {
+ ScDPSaveDimension* pDim = pSaveData->GetExistingDimensionByName(aDimName);
+ if ( pDim && pDim->HasCurrentPage() )
+ {
+ aCurrentPage = pDim->GetCurrentPage();
+ bHasCurrentPage = sal_True;
+ }
+ }
+ }
+ }
+
+ // include all entry widths for the size of the drop-down
+ long nMaxText = 0;
+ sal_uInt16 nCount = aStrings.GetCount();
+ for (i=0; i<nCount; i++)
+ {
+ TypedStrData* pData = aStrings[i];
+ long nTextWidth = pFilterBox->GetTextWidth( pData->GetString() );
+ if ( nTextWidth > nMaxText )
+ nMaxText = nTextWidth;
+ }
+
+ // add scrollbar width if needed (string entries are counted here)
+ // (scrollbar is shown if the box is exactly full?)
+ if ( nCount >= SC_FILTERLISTBOX_LINES )
+ nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize();
+
+ nMaxText += 4; // for borders
+
+ if ( nMaxText > nSizeX )
+ nSizeX = nMaxText; // just modify width - starting position is unchanged
+
+ // adjust position and size to window
+
+ Size aParentSize = GetParent()->GetOutputSizePixel();
+ Size aSize( nSizeX, nHeight );
+
+ if ( aSize.Height() > aParentSize.Height() )
+ aSize.Height() = aParentSize.Height();
+ if ( aPos.Y() + aSize.Height() > aParentSize.Height() )
+ aPos.Y() = aParentSize.Height() - aSize.Height();
+
+ pFilterBox->SetSizePixel( aSize );
+ pFilterBox->Show(); // Show must be called before SetUpdateMode
+ pFilterBox->SetUpdateMode(sal_False);
+
+ pFilterFloat->SetOutputSizePixel( aSize );
+ pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS);
+
+ // fill the list box
+ sal_Bool bWait = ( nCount > 100 );
+
+ if (bWait)
+ EnterWait();
+
+ for (i=0; i<nCount; i++)
+ pFilterBox->InsertEntry( aStrings[i]->GetString() );
+
+ pFilterBox->SetSeparatorPos( 0 );
+
+ if (bWait)
+ LeaveWait();
+
+ pFilterBox->SetUpdateMode(sal_True);
+
+ sal_uInt16 nSelPos = LISTBOX_ENTRY_NOTFOUND;
+ if (bHasCurrentPage)
+ nSelPos = pFilterBox->GetEntryPos( aCurrentPage );
+
+ if ( nSelPos == LISTBOX_ENTRY_NOTFOUND )
+ nSelPos = 0; // first entry
+
+ pFilterBox->GrabFocus();
+
+ // call Select after GrabFocus, so the focus rectangle ends up in the right position
+ if ( nSelPos != LISTBOX_ENTRY_NOTFOUND )
+ pFilterBox->SelectEntryPos( nSelPos );
+
+ pFilterBox->EndInit();
+
+ nMouseStatus = SC_GM_FILTER;
+ CaptureMouse();
+}
+
+void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol, SCROW nRow )
+{
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDPObject* pDPObj = pViewData->GetDocument()->GetDPAtCursor(nCol, nRow, nTab);
+ if (!pDPObj)
+ return;
+
+ // Get the geometry of the cell.
+ Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich);
+ long nSizeX, nSizeY;
+ pViewData->GetMergeSizePixel(nCol, nRow, nSizeX, nSizeY);
+ Size aScrSize(nSizeX-1, nSizeY-1);
+
+ DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, ScAddress(nCol, nRow, nTab), pDPObj);
+}
+
+void ScGridWindow::DoScenarioMenue( const ScRange& rScenRange )
+{
+ delete pFilterBox;
+ delete pFilterFloat;
+
+ SCCOL nCol = rScenRange.aEnd.Col(); // Zelle unterhalb des Buttons
+ SCROW nRow = rScenRange.aStart.Row();
+ if (nRow == 0)
+ {
+ nRow = rScenRange.aEnd.Row() + 1; // Bereich ganz oben -> Button unterhalb
+ if (nRow>MAXROW) nRow = MAXROW;
+ //! Texthoehe addieren (wenn sie an der View gespeichert ist...)
+ }
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ long nSizeX = 0;
+ long nSizeY = 0;
+ long nHeight = 0;
+ pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
+ Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich );
+ if ( bLayoutRTL )
+ aPos.X() -= nSizeX;
+ Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) );
+ aCellRect.Top() -= nSizeY;
+ aCellRect.Bottom() -= nSizeY - 1;
+ // Die ListBox direkt unter der schwarzen Linie auf dem Zellgitter
+ // (wenn die Linie verdeckt wird, sieht es komisch aus...)
+
+ pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) ); // nicht resizable etc.
+ pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) );
+ pFilterBox = new ScFilterListBox( pFilterFloat, this, nCol, nRow, SC_FILTERBOX_SCENARIO );
+ if ( bLayoutRTL )
+ pFilterBox->EnableMirroring();
+
+ nSizeX += 1;
+
+ {
+ Font aOldFont = GetFont(); SetFont( pFilterBox->GetFont() );
+ MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL );
+
+ nHeight = GetTextHeight();
+ nHeight *= SC_FILTERLISTBOX_LINES;
+
+ SetMapMode( aOldMode );
+ SetFont( aOldFont );
+ }
+
+ // SetSize spaeter
+/*
+ pFilterBox->SetSelectionMode( SINGLE_SELECTION );
+ pFilterBox->SetTabs( nFilterBoxTabs, MapUnit( MAP_APPFONT ));
+ pFilterBox->SetTabJustify( 1, bLayoutRTL ? AdjustRight : AdjustLeft );
+*/
+
+ // ParentSize Abfrage fehlt
+ Size aSize( nSizeX, nHeight );
+ pFilterBox->SetSizePixel( aSize );
+ pFilterBox->Show(); // Show muss vor SetUpdateMode kommen !!!
+ pFilterBox->SetUpdateMode(sal_False);
+
+ // SetOutputSizePixel/StartPopupMode erst unten, wenn die Groesse feststeht
+
+ // Listbox fuellen
+
+ long nMaxText = 0;
+ String aCurrent;
+ String aTabName;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nEntryCount = 0;
+ for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
+ {
+ if (pDoc->HasScenarioRange( i, rScenRange ))
+ if (pDoc->GetName( i, aTabName ))
+ {
+ pFilterBox->InsertEntry( aTabName );
+ if (pDoc->IsActiveScenario(i))
+ aCurrent = aTabName;
+ long nTextWidth = pFilterBox->GetTextWidth( aTabName );
+ if ( nTextWidth > nMaxText )
+ nMaxText = nTextWidth;
+ ++nEntryCount;
+ }
+ }
+ if (nEntryCount > SC_FILTERLISTBOX_LINES)
+ nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize();
+ nMaxText += 4; // fuer Rand
+ if ( nMaxText > 300 )
+ nMaxText = 300; // auch nicht uebertreiben (Pixel)
+
+ if (nMaxText > nSizeX) // Groesse auf benoetigte Groesse anpassen
+ {
+ long nDiff = nMaxText - nSizeX;
+ aSize = Size( nMaxText, nHeight );
+ pFilterBox->SetSizePixel( aSize );
+ pFilterFloat->SetOutputSizePixel( aSize );
+
+ if ( !bLayoutRTL )
+ {
+ // also move popup position
+ long nNewX = aCellRect.Left() - nDiff;
+ if ( nNewX < 0 )
+ nNewX = 0;
+ aCellRect.Left() = nNewX;
+ }
+ }
+
+ pFilterFloat->SetOutputSizePixel( aSize );
+ pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS );
+
+ pFilterBox->SetUpdateMode(sal_True);
+ pFilterBox->GrabFocus();
+
+ // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
+//! SvLBoxEntry* pSelect = NULL;
+ sal_uInt16 nPos = LISTBOX_ENTRY_NOTFOUND;
+ if (aCurrent.Len())
+ {
+ nPos = pFilterBox->GetEntryPos( aCurrent );
+//! pSelect = pFilterBox->GetEntry( nPos );
+ }
+ if (/*!pSelect*/ LISTBOX_ENTRY_NOTFOUND == nPos && pFilterBox->GetEntryCount() > 0 )
+ nPos = 0;
+//! pSelect = pFilterBox->GetEntry(0); // einer sollte immer selektiert sein
+ if (/*pSelect*/ LISTBOX_ENTRY_NOTFOUND != nPos )
+ pFilterBox->SelectEntryPos(nPos);
+
+ pFilterBox->EndInit();
+
+ // Szenario-Auswahl kommt aus MouseButtonDown:
+ // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
+
+ nMouseStatus = SC_GM_FILTER;
+ CaptureMouse();
+}
+
+void ScGridWindow::DoAutoFilterMenue( SCCOL nCol, SCROW nRow, sal_Bool bDataSelect )
+{
+ delete pFilterBox;
+ delete pFilterFloat;
+
+ sal_uInt16 i;
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ long nSizeX = 0;
+ long nSizeY = 0;
+ long nHeight = 0;
+ pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
+ Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich );
+ if ( bLayoutRTL )
+ aPos.X() -= nSizeX;
+
+ Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) );
+
+ aPos.X() -= 1;
+ aPos.Y() += nSizeY - 1;
+
+ pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) ); // nicht resizable etc.
+ pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) );
+ pFilterBox = new ScFilterListBox(
+ pFilterFloat, this, nCol, nRow, bDataSelect ? SC_FILTERBOX_DATASELECT : SC_FILTERBOX_FILTER );
+ if ( bLayoutRTL )
+ pFilterBox->EnableMirroring();
+
+ nSizeX += 1;
+
+ {
+ Font aOldFont = GetFont(); SetFont( pFilterBox->GetFont() );
+ MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL );
+
+ nHeight = GetTextHeight();
+ nHeight *= SC_FILTERLISTBOX_LINES;
+
+ SetMapMode( aOldMode );
+ SetFont( aOldFont );
+ }
+
+ // SetSize spaeter
+/*
+ pFilterBox->SetSelectionMode( SINGLE_SELECTION );
+ pFilterBox->SetTabs( nFilterBoxTabs, MapUnit( MAP_APPFONT ));
+ pFilterBox->SetTabJustify( 1, bLayoutRTL ? AdjustRight : AdjustLeft );
+*/
+
+ sal_Bool bEmpty = sal_False;
+ TypedScStrCollection aStrings( 128, 128 );
+ if ( bDataSelect ) // Auswahl-Liste
+ {
+ // Liste fuellen
+ aStrings.SetCaseSensitive( sal_True );
+ pDoc->GetDataEntries( nCol, nRow, nTab, aStrings );
+ if ( aStrings.GetCount() == 0 )
+ bEmpty = sal_True;
+ }
+ else // AutoFilter
+ {
+ //! wird der Titel ueberhaupt ausgewertet ???
+ String aString;
+ pDoc->GetString( nCol, nRow, nTab, aString );
+ pFilterBox->SetText( aString );
+
+ long nMaxText = 0;
+
+ // default entries
+ static const sal_uInt16 nDefIDs[] = { SCSTR_ALLFILTER, SCSTR_TOP10FILTER, SCSTR_STDFILTER };
+ const sal_uInt16 nDefCount = sizeof(nDefIDs) / sizeof(sal_uInt16);
+ for (i=0; i<nDefCount; i++)
+ {
+ String aEntry( (ScResId) nDefIDs[i] );
+ pFilterBox->InsertEntry( aEntry );
+ long nTextWidth = pFilterBox->GetTextWidth( aEntry );
+ if ( nTextWidth > nMaxText )
+ nMaxText = nTextWidth;
+ }
+ pFilterBox->SetSeparatorPos( nDefCount - 1 );
+
+ // get list entries
+ bool bHasDates = false;
+ pDoc->GetFilterEntries( nCol, nRow, nTab, true, aStrings, bHasDates);
+ pFilterBox->SetListHasDates(bHasDates);
+
+ // check widths of numerical entries (string entries are not included)
+ // so all numbers are completely visible
+ sal_uInt16 nCount = aStrings.GetCount();
+ for (i=0; i<nCount; i++)
+ {
+ TypedStrData* pData = aStrings[i];
+ if ( !pData->IsStrData() ) // only numerical entries
+ {
+ long nTextWidth = pFilterBox->GetTextWidth( pData->GetString() );
+ if ( nTextWidth > nMaxText )
+ nMaxText = nTextWidth;
+ }
+ }
+
+ // add scrollbar width if needed (string entries are counted here)
+ // (scrollbar is shown if the box is exactly full?)
+ if ( nCount + nDefCount >= SC_FILTERLISTBOX_LINES )
+ nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize();
+
+ nMaxText += 4; // for borders
+
+ if ( nMaxText > nSizeX )
+ nSizeX = nMaxText; // just modify width - starting position is unchanged
+ }
+
+ if (!bEmpty)
+ {
+ // Position und Groesse an Fenster anpassen
+ //! vorher Abfrage, ob die Eintraege hineinpassen (Breite)
+
+ Size aParentSize = GetParent()->GetOutputSizePixel();
+ Size aSize( nSizeX, nHeight );
+
+ if ( aSize.Height() > aParentSize.Height() )
+ aSize.Height() = aParentSize.Height();
+ if ( aPos.Y() + aSize.Height() > aParentSize.Height() )
+ aPos.Y() = aParentSize.Height() - aSize.Height();
+
+ pFilterBox->SetSizePixel( aSize );
+ pFilterBox->Show(); // Show muss vor SetUpdateMode kommen !!!
+ pFilterBox->SetUpdateMode(sal_False);
+
+ pFilterFloat->SetOutputSizePixel( aSize );
+ pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS);
+
+ // Listbox fuellen
+ sal_uInt16 nCount = aStrings.GetCount();
+ sal_Bool bWait = ( nCount > 100 );
+
+ if (bWait)
+ EnterWait();
+
+ for (i=0; i<nCount; i++)
+ pFilterBox->InsertEntry( aStrings[i]->GetString() );
+
+ if (bWait)
+ LeaveWait();
+
+ pFilterBox->SetUpdateMode(sal_True);
+ }
+
+//! SvLBoxEntry* pSelect = NULL;
+ sal_uInt16 nSelPos = LISTBOX_ENTRY_NOTFOUND;
+
+ if (!bDataSelect) // AutoFilter: aktiven Eintrag selektieren
+ {
+ ScDBData* pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab );
+ if (pDBData)
+ {
+ ScQueryParam aParam;
+ pDBData->GetQueryParam( aParam ); // kann nur MAXQUERY Eintraege ergeben
+
+ sal_Bool bValid = sal_True;
+ for (SCSIZE j=0; j<MAXQUERY && bValid; j++) // bisherige Filter-Einstellungen
+ if (aParam.GetEntry(j).bDoQuery)
+ {
+ //! Abfrage mit DrawButtons zusammenfassen!
+
+ ScQueryEntry& rEntry = aParam.GetEntry(j);
+ if (j>0)
+ if (rEntry.eConnect != SC_AND)
+ bValid = sal_False;
+ if (rEntry.nField == nCol)
+ {
+ if (rEntry.eOp == SC_EQUAL)
+ {
+ String* pStr = rEntry.pStr;
+ if (pStr)
+ {
+ nSelPos = pFilterBox->GetEntryPos( *pStr );
+//! pSelect = pFilterBox->GetEntry( nPos );
+ }
+ }
+ else if (rEntry.eOp == SC_TOPVAL && rEntry.pStr &&
+ rEntry.pStr->EqualsAscii("10"))
+ nSelPos = SC_AUTOFILTER_TOP10;
+ else
+ nSelPos = SC_AUTOFILTER_CUSTOM;
+ }
+ }
+
+ if (!bValid)
+ nSelPos = SC_AUTOFILTER_CUSTOM;
+ }
+ }
+ else
+ {
+
+ sal_uLong nIndex = ((SfxUInt32Item*)pDoc->GetAttr(
+ nCol, nRow, nTab, ATTR_VALIDDATA ))->GetValue();
+ if ( nIndex )
+ {
+ const ScValidationData* pData = pDoc->GetValidationEntry( nIndex );
+ if (pData)
+ {
+ TypedStrData* pNew = NULL;
+ String aDocStr;
+ pDoc->GetString( nCol, nRow, nTab, aDocStr );
+ if ( pDoc->HasValueData( nCol, nRow, nTab ) )
+ {
+ double fVal = pDoc->GetValue(ScAddress(nCol, nRow, nTab));
+ pNew = new TypedStrData( aDocStr, fVal, SC_STRTYPE_VALUE );
+ }
+ else
+ pNew = new TypedStrData( aDocStr, 0.0, SC_STRTYPE_STANDARD );
+
+ bool bSortList = ( pData->GetListType() == ValidListType::SORTEDASCENDING);
+ if ( bSortList )
+ {
+ sal_uInt16 nStrIndex;
+ if (aStrings.Search(pNew,nStrIndex))
+ nSelPos = nStrIndex;
+ }
+ else
+ {
+ sal_uInt16 nCount = aStrings.GetCount();
+ for (i = 0; ((i < nCount) && ( LISTBOX_ENTRY_NOTFOUND == nSelPos)); i++)
+ {
+ if ( aStrings.Compare(aStrings[i], pNew)==0 )
+ nSelPos = i;
+ }
+ }
+ delete pNew;
+ }
+ }
+ }
+
+ // neu (309): irgendwas muss immer selektiert sein:
+ if ( LISTBOX_ENTRY_NOTFOUND == nSelPos && pFilterBox->GetEntryCount() > 0 && !bDataSelect)
+ nSelPos = 0;
+
+ // keine leere Auswahl-Liste anzeigen:
+
+ if ( bEmpty )
+ {
+ DELETEZ(pFilterBox); // war nix
+ DELETEZ(pFilterFloat);
+ Sound::Beep(); // bemerkbar machen
+ }
+ else
+ {
+// pFilterBox->Show(); // schon vorne
+ pFilterBox->GrabFocus();
+
+ // Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
+ if ( LISTBOX_ENTRY_NOTFOUND != nSelPos )
+ pFilterBox->SelectEntryPos( nSelPos );
+ else
+ {
+ if (bDataSelect)
+ pFilterBox->SetNoSelection();
+ }
+
+ pFilterBox->EndInit();
+
+ if (!bDataSelect)
+ {
+ // AutoFilter (aus MouseButtonDown):
+ // der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
+
+ nMouseStatus = SC_GM_FILTER;
+ CaptureMouse();
+ }
+ }
+}
+
+void ScGridWindow::FilterSelect( sal_uLong nSel )
+{
+ String aString;
+/*
+ SvLBoxEntry* pEntry = pFilterBox->GetEntry( nSel );
+ if (pEntry)
+ {
+ SvLBoxString* pStringEntry = (SvLBoxString*) pEntry->GetFirstItem( SV_ITEM_ID_LBOXSTRING );
+ if ( pStringEntry )
+ aString = pStringEntry->GetText();
+ }
+*/
+ aString = pFilterBox->GetEntry( static_cast< sal_uInt16 >( nSel ) );
+
+ SCCOL nCol = pFilterBox->GetCol();
+ SCROW nRow = pFilterBox->GetRow();
+ switch ( pFilterBox->GetMode() )
+ {
+ case SC_FILTERBOX_DATASELECT:
+ ExecDataSelect( nCol, nRow, aString );
+ break;
+ case SC_FILTERBOX_FILTER:
+ ExecFilter( nSel, nCol, nRow, aString, pFilterBox->HasDates() );
+ break;
+ case SC_FILTERBOX_SCENARIO:
+ pViewData->GetView()->UseScenario( aString );
+ break;
+ case SC_FILTERBOX_PAGEFIELD:
+ // first entry is "all"
+ ExecPageFieldSelect( nCol, nRow, (nSel != 0), aString );
+ break;
+ }
+
+ if (pFilterFloat)
+ pFilterFloat->EndPopupMode();
+
+ GrabFocus(); // unter OS/2 stimmt der Focus sonst nicht
+}
+
+void ScGridWindow::ExecDataSelect( SCCOL nCol, SCROW nRow, const String& rStr )
+{
+ if ( rStr.Len() )
+ {
+ SCTAB nTab = pViewData->GetTabNo();
+ ScViewFunc* pView = pViewData->GetView();
+ pView->EnterData( nCol, nRow, nTab, rStr );
+
+ // #i52307# CellContentChanged is not in EnterData so it isn't called twice
+ // if the cursor is moved afterwards.
+ pView->CellContentChanged();
+ }
+}
+
+void ScGridWindow::ExecFilter( sal_uLong nSel,
+ SCCOL nCol, SCROW nRow,
+ const String& aValue, bool bCheckForDates )
+{
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ ScDBData* pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab );
+ if (pDBData)
+ {
+ ScQueryParam aParam;
+ pDBData->GetQueryParam( aParam ); // kann nur MAXQUERY Eintraege ergeben
+
+ if (SC_AUTOFILTER_CUSTOM == nSel)
+ {
+ SCTAB nAreaTab;
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ pDBData->GetArea( nAreaTab, nStartCol,nStartRow,nEndCol,nEndRow );
+ pViewData->GetView()->MarkRange( ScRange( nStartCol,nStartRow,nAreaTab,nEndCol,nEndRow,nAreaTab));
+ pViewData->GetView()->SetCursor(nCol,nRow); //! auch ueber Slot ??
+ pViewData->GetDispatcher().Execute( SID_FILTER, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
+ }
+ else
+ {
+ sal_Bool bDeleteOld = sal_False;
+ SCSIZE nQueryPos = 0;
+ sal_Bool bFound = sal_False;
+ if (!aParam.bInplace)
+ bDeleteOld = sal_True;
+ if (aParam.bRegExp)
+ bDeleteOld = sal_True;
+ for (SCSIZE i=0; i<MAXQUERY && !bDeleteOld; i++) // bisherige Filter-Einstellungen
+ if (aParam.GetEntry(i).bDoQuery)
+ {
+ //! Abfrage mit DrawButtons zusammenfassen!
+
+ ScQueryEntry& rEntry = aParam.GetEntry(i);
+ if (i>0)
+ if (rEntry.eConnect != SC_AND)
+ bDeleteOld = sal_True;
+
+ if (rEntry.nField == nCol)
+ {
+ if (bFound) // diese Spalte zweimal?
+ bDeleteOld = sal_True;
+ nQueryPos = i;
+ bFound = sal_True;
+ }
+ if (!bFound)
+ nQueryPos = i + 1;
+ }
+
+ if (bDeleteOld)
+ {
+ SCSIZE nEC = aParam.GetEntryCount();
+ for (SCSIZE i=0; i<nEC; i++)
+ aParam.GetEntry(i).Clear();
+ nQueryPos = 0;
+ aParam.bInplace = sal_True;
+ aParam.bRegExp = sal_False;
+ }
+
+ if ( nQueryPos < MAXQUERY || SC_AUTOFILTER_ALL == nSel ) // loeschen geht immer
+ {
+ if (nSel)
+ {
+ ScQueryEntry& rNewEntry = aParam.GetEntry(nQueryPos);
+
+ rNewEntry.bDoQuery = sal_True;
+ rNewEntry.bQueryByString = sal_True;
+ rNewEntry.nField = nCol;
+ rNewEntry.bQueryByDate = bCheckForDates;
+ if ( nSel == SC_AUTOFILTER_TOP10 )
+ {
+ rNewEntry.eOp = SC_TOPVAL;
+ *rNewEntry.pStr = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("10"));
+ }
+ else
+ {
+ rNewEntry.eOp = SC_EQUAL;
+ *rNewEntry.pStr = aValue;
+ }
+ if (nQueryPos > 0)
+ rNewEntry.eConnect = SC_AND;
+ }
+ else
+ {
+ if (bFound)
+ aParam.DeleteQuery(nQueryPos);
+ }
+
+ // #100597# end edit mode - like in ScCellShell::ExecuteDB
+ if ( pViewData->HasEditView( pViewData->GetActivePart() ) )
+ {
+ SC_MOD()->InputEnterHandler();
+ pViewData->GetViewShell()->UpdateInputHandler();
+ }
+
+ pViewData->GetView()->Query( aParam, NULL, sal_True );
+ pDBData->SetQueryParam( aParam ); // speichern
+ }
+ else // "Zuviele Bedingungen"
+ pViewData->GetView()->ErrorMessage( STR_FILTER_TOOMANY );
+ }
+ }
+ else
+ {
+ DBG_ERROR("Wo ist der Datenbankbereich?");
+ }
+}
+
+void ScGridWindow::SetPointer( const Pointer& rPointer )
+{
+ nCurrentPointer = 0;
+ Window::SetPointer( rPointer );
+}
+
+void ScGridWindow::MoveMouseStatus( ScGridWindow& rDestWin )
+{
+ if (nButtonDown)
+ {
+ rDestWin.nButtonDown = nButtonDown;
+ rDestWin.nMouseStatus = nMouseStatus;
+ }
+
+ if (bRFMouse)
+ {
+ rDestWin.bRFMouse = bRFMouse;
+ rDestWin.bRFSize = bRFSize;
+ rDestWin.nRFIndex = nRFIndex;
+ rDestWin.nRFAddX = nRFAddX;
+ rDestWin.nRFAddY = nRFAddY;
+ bRFMouse = sal_False;
+ }
+
+ if (nPagebreakMouse)
+ {
+ rDestWin.nPagebreakMouse = nPagebreakMouse;
+ rDestWin.nPagebreakBreak = nPagebreakBreak;
+ rDestWin.nPagebreakPrev = nPagebreakPrev;
+ rDestWin.aPagebreakSource = aPagebreakSource;
+ rDestWin.aPagebreakDrag = aPagebreakDrag;
+ nPagebreakMouse = SC_PD_NONE;
+ }
+}
+
+sal_Bool ScGridWindow::TestMouse( const MouseEvent& rMEvt, sal_Bool bAction )
+{
+ // MouseEvent buttons must only be checked if bAction==TRUE
+ // to allow changing the mouse pointer in MouseMove,
+ // but not start AutoFill with right button (#74229#).
+ // with bAction==sal_True, SetFillMode / SetDragMode is called
+
+ if ( bAction && !rMEvt.IsLeft() )
+ return sal_False;
+
+ sal_Bool bNewPointer = sal_False;
+
+ SfxInPlaceClient* pClient = pViewData->GetViewShell()->GetIPClient();
+ sal_Bool bOleActive = ( pClient && pClient->IsObjectInPlaceActive() );
+
+ if ( pViewData->IsActive() && !bOleActive )
+ {
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ // Auto-Fill
+
+ ScRange aMarkRange;
+ if (pViewData->GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE)
+ {
+ if (aMarkRange.aStart.Tab() == pViewData->GetTabNo() && mpAutoFillRect)
+ {
+ Point aMousePos = rMEvt.GetPosPixel();
+ 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 );
+ else
+ pViewData->SetFillMode(
+ aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nX, nY );
+
+ // #108266# The simple selection must also be recognized when dragging,
+ // where the Marking flag is set and MarkToSimple won't work anymore.
+ pViewData->GetMarkData().MarkToSimple();
+ }
+ bNewPointer = sal_True;
+ }
+ }
+ }
+
+ // Embedded-Rechteck
+
+ if (pDoc->IsEmbedded())
+ {
+ ScRange aRange;
+ pDoc->GetEmbedded( aRange );
+ if ( pViewData->GetTabNo() == aRange.aStart.Tab() )
+ {
+ Point aStartPos = pViewData->GetScrPos( aRange.aStart.Col(), aRange.aStart.Row(), eWhich );
+ Point aEndPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aEnd.Row()+1, eWhich );
+ Point aMousePos = rMEvt.GetPosPixel();
+ if ( bLayoutRTL )
+ {
+ aStartPos.X() += 2;
+ aEndPos.X() += 2;
+ }
+ sal_Bool bTop = ( aMousePos.X() >= aStartPos.X()-3 && aMousePos.X() <= aStartPos.X()+1 &&
+ aMousePos.Y() >= aStartPos.Y()-3 && aMousePos.Y() <= aStartPos.Y()+1 );
+ sal_Bool bBottom = ( aMousePos.X() >= aEndPos.X()-3 && aMousePos.X() <= aEndPos.X()+1 &&
+ aMousePos.Y() >= aEndPos.Y()-3 && aMousePos.Y() <= aEndPos.Y()+1 );
+ if ( bTop || bBottom )
+ {
+ SetPointer( Pointer( POINTER_CROSS ) );
+ if (bAction)
+ {
+ sal_uInt8 nMode = bTop ? SC_FILL_EMBED_LT : SC_FILL_EMBED_RB;
+ pViewData->SetDragMode(
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(), nMode );
+ }
+ bNewPointer = sal_True;
+ }
+ }
+ }
+ }
+
+ if (!bNewPointer && bAction)
+ {
+// SetPointer( POINTER_ARROW ); // in Fu...
+ pViewData->ResetFillMode();
+ }
+
+ return bNewPointer;
+}
+
+void __EXPORT ScGridWindow::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ nNestedButtonState = SC_NESTEDBUTTON_DOWN;
+
+ HandleMouseButtonDown( rMEvt );
+
+ if ( nNestedButtonState == SC_NESTEDBUTTON_UP )
+ {
+ // #i41690# If an object is deactivated from MouseButtonDown, it might reschedule,
+ // so MouseButtonUp comes before the MouseButtonDown call is finished. In this case,
+ // simulate another MouseButtonUp call, so the selection state is consistent.
+
+ nButtonDown = rMEvt.GetButtons();
+ FakeButtonUp();
+
+ if ( IsTracking() )
+ EndTracking(); // normally done in VCL as part of MouseButtonUp handling
+ }
+ nNestedButtonState = SC_NESTEDBUTTON_NONE;
+}
+
+void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt )
+{
+ // We have to check if a context menu is shown and we have an UI
+ // active inplace client. In that case we have to ignore the event.
+ // Otherwise we would crash (context menu has been
+ // opened by inplace client and we would deactivate the inplace client,
+ // the contex menu is closed by VCL asynchronously which in the end
+ // would work on deleted objects or the context menu has no parent anymore)
+ // See #126086# and #128122#
+ SfxViewShell* pViewSh = pViewData->GetViewShell();
+ SfxInPlaceClient* pClient = pViewSh->GetIPClient();
+ if ( pClient &&
+ pClient->IsObjectInPlaceActive() &&
+ PopupMenu::IsInExecute() )
+ return;
+
+ aCurMousePos = rMEvt.GetPosPixel();
+
+ // Filter-Popup beendet sich mit eigenem Mausklick, nicht erst beim Klick
+ // in das GridWindow, darum ist die folgende Abfrage nicht mehr noetig:
+#if 0
+ // merken, dass FilterBox geloescht wird, damit sichergestellt
+ // ist, dass in diesem Handler nicht an gleicher Stelle wieder
+ // eine neue geoeffnet wird.
+ sal_Bool bWasFilterBox = ( pFilterBox != NULL &&
+ ((Window*)pFilterBox)->IsVisible() &&
+ !pFilterBox->IsDataSelect() );
+ SCCOL nOldColFBox = bWasFilterBox ? pFilterBox->GetCol() : 0;
+ SCROW nOldRowFBox = bWasFilterBox ? pFilterBox->GetRow() : 0;
+#endif
+
+ ClickExtern(); // loescht FilterBox, wenn vorhanden
+
+ HideNoteMarker(); // Notiz-Anzeige
+
+ bEEMouse = sal_False;
+
+ ScModule* pScMod = SC_MOD();
+ if (pScMod->IsModalMode(pViewData->GetSfxDocShell()))
+ {
+ Sound::Beep();
+ return;
+ }
+
+ pScActiveViewShell = pViewData->GetViewShell(); // falls auf Link geklickt wird
+ nScClickMouseModifier = rMEvt.GetModifier(); // um Control-Klick immer zu erkennen
+
+ sal_Bool bDetective = pViewData->GetViewShell()->IsAuditShell();
+ sal_Bool bRefMode = pViewData->IsRefMode(); // Referenz angefangen
+ sal_Bool bFormulaMode = pScMod->IsFormulaMode(); // naechster Klick -> Referenz
+ sal_Bool bEditMode = pViewData->HasEditView(eWhich); // auch bei Mode==SC_INPUT_TYPE
+ sal_Bool bDouble = (rMEvt.GetClicks() == 2);
+
+ // DeactivateIP passiert nur noch bei MarkListHasChanged
+
+ // im GrabFocus Aufruf kann eine Fehlermeldung hochkommen
+ // (z.B. beim Umbenennen von Tabellen per Tab-Reiter)
+
+ if ( !nButtonDown || !bDouble ) // single (first) click is always valid
+ nButtonDown = rMEvt.GetButtons(); // set nButtonDown first, so StopMarking works
+
+// pViewData->GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
+ if ( ( bEditMode && pViewData->GetActivePart() == eWhich ) || !bFormulaMode )
+ GrabFocus();
+
+ // #i31846# need to cancel a double click if the first click has set the "ignore" state,
+ // but a single (first) click is always valid
+ if ( nMouseStatus == SC_GM_IGNORE && bDouble )
+ {
+ nButtonDown = 0;
+ nMouseStatus = SC_GM_NONE;
+ return;
+ }
+
+ if ( bDetective ) // Detektiv-Fuell-Modus
+ {
+ if ( rMEvt.IsLeft() && !rMEvt.GetModifier() )
+ {
+ Point aPos = rMEvt.GetPosPixel();
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+
+ SfxInt16Item aPosXItem( SID_RANGE_COL, nPosX );
+ SfxInt32Item aPosYItem( SID_RANGE_ROW, nPosY );
+ pViewData->GetDispatcher().Execute( SID_FILL_SELECT, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
+ &aPosXItem, &aPosYItem, (void*)0L );
+
+ }
+ nButtonDown = 0;
+ nMouseStatus = SC_GM_NONE;
+ return;
+ }
+
+ if (!bDouble)
+ nMouseStatus = SC_GM_NONE;
+
+ if (!bFormulaMode)
+ {
+ if ( pViewData->GetActivePart() != eWhich )
+ pViewData->GetView()->ActivatePart( eWhich );
+ }
+ else
+ {
+ ScViewSelectionEngine* pSelEng = pViewData->GetView()->GetSelEngine();
+ pSelEng->SetWindow(this);
+ pSelEng->SetWhich(eWhich);
+ pSelEng->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
+ }
+
+ if (bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()))
+ {
+ Point aPos = rMEvt.GetPosPixel();
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+
+ EditView* pEditView;
+ SCCOL nEditCol;
+ SCROW nEditRow;
+ pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
+ SCCOL nEndCol = pViewData->GetEditEndCol();
+ SCROW nEndRow = pViewData->GetEditEndRow();
+
+ if ( nPosX >= (SCsCOL) nEditCol && nPosX <= (SCsCOL) nEndCol &&
+ nPosY >= (SCsROW) nEditRow && nPosY <= (SCsROW) nEndRow )
+ {
+ // #53966# beim Klick in die Tabellen-EditView immer den Focus umsetzen
+ if (bFormulaMode) // sonst ist es oben schon passiert
+ GrabFocus();
+
+ pScMod->SetInputMode( SC_INPUT_TABLE );
+ bEEMouse = sal_True;
+ bEditMode = pEditView->MouseButtonDown( rMEvt );
+ return;
+ }
+ }
+
+ if (pScMod->GetIsWaterCan())
+ {
+ //! was is mit'm Mac ???
+ if ( rMEvt.GetModifier() + rMEvt.GetButtons() == MOUSE_RIGHT )
+ {
+ nMouseStatus = SC_GM_WATERUNDO;
+ return;
+ }
+ }
+
+ // Reihenfolge passend zum angezeigten Cursor:
+ // RangeFinder, AutoFill, PageBreak, Drawing
+
+ if ( HitRangeFinder( rMEvt.GetPosPixel(), bRFSize, &nRFIndex, &nRFAddX, &nRFAddY ) )
+ {
+ bRFMouse = sal_True; // die anderen Variablen sind oben initialisiert
+
+ if ( pViewData->GetActivePart() != eWhich )
+ pViewData->GetView()->ActivatePart( eWhich ); //! schon oben immer ???
+
+ // CaptureMouse();
+ StartTracking();
+ return;
+ }
+
+ sal_Bool bCrossPointer = TestMouse( rMEvt, sal_True );
+ if ( bCrossPointer )
+ {
+ if ( bDouble )
+ pViewData->GetView()->FillCrossDblClick();
+ else
+ pScMod->InputEnterHandler(); // Autofill etc.
+ }
+
+ if ( !bCrossPointer )
+ {
+ nPagebreakMouse = HitPageBreak( rMEvt.GetPosPixel(), &aPagebreakSource,
+ &nPagebreakBreak, &nPagebreakPrev );
+ if (nPagebreakMouse)
+ {
+ bPagebreakDrawn = sal_False;
+ // CaptureMouse();
+ StartTracking();
+ PagebreakMove( rMEvt, sal_False );
+ return;
+ }
+ }
+
+ if (!bFormulaMode && !bEditMode && rMEvt.IsLeft())
+ {
+ if ( !bCrossPointer && DrawMouseButtonDown(rMEvt) )
+ {
+ //if (DrawHasMarkedObj())
+ // pViewData->GetViewShell()->SetDrawShellOrSub(); // Draw-Objekt selektiert
+ return;
+ }
+
+ pViewData->GetViewShell()->SetDrawShell( sal_False ); // kein Draw-Objekt selektiert
+
+ // TestMouse schon oben passiert
+ }
+
+ Point aPos = rMEvt.GetPosPixel();
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDocument* pDoc = pViewData->GetDocument();
+
+
+ //
+ // AutoFilter buttons
+ //
+
+ if ( !bDouble && !bFormulaMode && rMEvt.IsLeft() )
+ {
+ ScMergeFlagAttr* pAttr = (ScMergeFlagAttr*)
+ pDoc->GetAttr( nPosX, nPosY, nTab, ATTR_MERGE_FLAG );
+ if (pAttr->HasAutoFilter())
+ {
+ if (DoAutoFilterButton(nPosX, nPosY, rMEvt))
+ return;
+ }
+ if (pAttr->HasButton())
+ {
+ DoPushButton( nPosX, nPosY, rMEvt ); // setzt evtl. bPivotMouse / bDPMouse
+ return;
+ }
+
+ // List Validity drop-down button
+
+ if ( bListValButton )
+ {
+ Rectangle aButtonRect = GetListValButtonRect( aListValPos );
+ if ( aButtonRect.IsInside( aPos ) )
+ {
+ DoAutoFilterMenue( aListValPos.Col(), aListValPos.Row(), sal_True );
+
+ nMouseStatus = SC_GM_FILTER; // not set in DoAutoFilterMenue for bDataSelect
+ CaptureMouse();
+ return;
+ }
+ }
+ }
+
+ //
+ // scenario selection
+ //
+
+ ScRange aScenRange;
+ if ( rMEvt.IsLeft() && HasScenarioButton( aPos, aScenRange ) )
+ {
+ DoScenarioMenue( aScenRange );
+ return;
+ }
+
+ //
+ // Doppelklick angefangen ?
+ //
+
+ // StopMarking kann aus DrawMouseButtonDown gerufen werden
+
+ if ( nMouseStatus != SC_GM_IGNORE && !bRefMode )
+ {
+ if ( bDouble && !bCrossPointer )
+ {
+ if (nMouseStatus == SC_GM_TABDOWN)
+ nMouseStatus = SC_GM_DBLDOWN;
+ }
+ else
+ nMouseStatus = SC_GM_TABDOWN;
+ }
+
+ //
+ // Links in Edit-Zellen
+ //
+
+ sal_Bool bAlt = rMEvt.IsMod2();
+ if ( !bAlt && rMEvt.IsLeft() &&
+ GetEditUrl(rMEvt.GetPosPixel()) ) // Klick auf Link: Cursor nicht bewegen
+ {
+ SetPointer( Pointer( POINTER_REFHAND ) );
+ nMouseStatus = SC_GM_URLDOWN; // auch nur dann beim ButtonUp ausfuehren
+ return;
+ }
+
+ //
+ // Gridwin - SelectionEngine
+ //
+
+ if ( rMEvt.IsLeft() )
+ {
+ ScViewSelectionEngine* pSelEng = pViewData->GetView()->GetSelEngine();
+ pSelEng->SetWindow(this);
+ pSelEng->SetWhich(eWhich);
+ pSelEng->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
+
+ // SelMouseButtonDown an der View setzt noch das bMoveIsShift Flag
+ if ( pViewData->GetView()->SelMouseButtonDown( rMEvt ) )
+ {
+ if (IsMouseCaptured())
+ {
+ // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
+ //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
+ ReleaseMouse();
+ StartTracking();
+ }
+ pViewData->GetMarkData().SetMarking(sal_True);
+ return;
+ }
+ }
+}
+
+void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ aCurMousePos = rMEvt.GetPosPixel();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScMarkData& rMark = pViewData->GetMarkData();
+
+ // #i41690# detect a MouseButtonUp call from within MouseButtonDown
+ // (possible through Reschedule from storing an OLE object that is deselected)
+
+ if ( nNestedButtonState == SC_NESTEDBUTTON_DOWN )
+ nNestedButtonState = SC_NESTEDBUTTON_UP;
+
+ if (nButtonDown != rMEvt.GetButtons())
+ nMouseStatus = SC_GM_IGNORE; // reset und return
+
+ nButtonDown = 0;
+
+ if (nMouseStatus == SC_GM_IGNORE)
+ {
+ nMouseStatus = SC_GM_NONE;
+ // Selection-Engine: Markieren abbrechen
+ pViewData->GetView()->GetSelEngine()->Reset();
+ rMark.SetMarking(sal_False);
+ if (pViewData->IsAnyFillMode())
+ {
+ pViewData->GetView()->StopRefMode();
+ pViewData->ResetFillMode();
+ }
+ StopMarking();
+ DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
+ ReleaseMouse();
+ return;
+ }
+
+ if (nMouseStatus == SC_GM_FILTER)
+ {
+ if ( pFilterBox && pFilterBox->GetMode() == SC_FILTERBOX_FILTER )
+ {
+ if (mpFilterButton.get())
+ {
+ bool bFilterActive = IsAutoFilterActive(
+ pFilterBox->GetCol(), pFilterBox->GetRow(), pViewData->GetTabNo() );
+
+ mpFilterButton->setHasHiddenMember(bFilterActive);
+ mpFilterButton->setPopupPressed(false);
+ HideCursor();
+ mpFilterButton->draw();
+ ShowCursor();
+ }
+ }
+ nMouseStatus = SC_GM_NONE;
+ ReleaseMouse();
+ return; // da muss nix mehr passieren
+ }
+
+ ScModule* pScMod = SC_MOD();
+ if (pScMod->IsModalMode(pViewData->GetSfxDocShell()))
+ return;
+
+ SfxBindings& rBindings = pViewData->GetBindings();
+ if (bEEMouse && pViewData->HasEditView( eWhich ))
+ {
+ EditView* pEditView;
+ SCCOL nEditCol;
+ SCROW nEditRow;
+ pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
+ pEditView->MouseButtonUp( rMEvt );
+
+ if ( rMEvt.IsMiddle() &&
+ GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION )
+ {
+ // EditView may have pasted from selection
+ pScMod->InputChanged( pEditView );
+ }
+ else
+ pScMod->InputSelection( pEditView ); // parentheses etc.
+
+ pViewData->GetView()->InvalidateAttribs();
+ rBindings.Invalidate( SID_HYPERLINK_GETLINK );
+ bEEMouse = sal_False;
+ return;
+ }
+
+ if (bDPMouse)
+ {
+ DPMouseButtonUp( rMEvt ); // resets bDPMouse
+ return;
+ }
+
+ if (bRFMouse)
+ {
+ RFMouseMove( rMEvt, sal_True ); // Range wieder richtigherum
+ bRFMouse = sal_False;
+ SetPointer( Pointer( POINTER_ARROW ) );
+ ReleaseMouse();
+ return;
+ }
+
+ if (nPagebreakMouse)
+ {
+ PagebreakMove( rMEvt, sal_True );
+ nPagebreakMouse = SC_PD_NONE;
+ SetPointer( Pointer( POINTER_ARROW ) );
+ ReleaseMouse();
+ return;
+ }
+
+ if (nMouseStatus == SC_GM_WATERUNDO) // Undo im Giesskannenmodus
+ {
+ ::svl::IUndoManager* pMgr = pViewData->GetDocShell()->GetUndoManager();
+ if ( pMgr->GetUndoActionCount() && pMgr->GetUndoActionId() == STR_UNDO_APPLYCELLSTYLE )
+ pMgr->Undo();
+ else
+ Sound::Beep();
+ return;
+ }
+
+ if (DrawMouseButtonUp(rMEvt)) // includes format paint brush handling for drawing objects
+ return;
+
+ rMark.SetMarking(sal_False);
+
+ SetPointer( Pointer( POINTER_ARROW ) );
+
+ if (pViewData->IsFillMode() ||
+ ( pViewData->GetFillMode() == SC_FILL_MATRIX && rMEvt.IsMod1() ))
+ {
+ nScFillModeMouseModifier = rMEvt.GetModifier();
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ pViewData->GetFillData( nStartCol, nStartRow, nEndCol, nEndRow );
+// DBG_ASSERT( nStartCol==pViewData->GetRefStartX() && nStartRow==pViewData->GetRefStartY(),
+// "Block falsch fuer AutoFill" );
+ ScRange aDelRange;
+ sal_Bool bIsDel = pViewData->GetDelMark( aDelRange );
+
+ ScViewFunc* pView = pViewData->GetView();
+ pView->StopRefMode();
+ pViewData->ResetFillMode();
+ pView->GetFunctionSet()->SetAnchorFlag( sal_False ); // #i5819# don't use AutoFill anchor flag for selection
+
+ if ( bIsDel )
+ {
+ pView->MarkRange( aDelRange, sal_False );
+ pView->DeleteContents( IDF_CONTENTS );
+ SCTAB nTab = pViewData->GetTabNo();
+ ScRange aBlockRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab );
+ if ( aBlockRange != aDelRange )
+ {
+ if ( aDelRange.aStart.Row() == nStartRow )
+ aBlockRange.aEnd.SetCol( aDelRange.aStart.Col() - 1 );
+ else
+ aBlockRange.aEnd.SetRow( aDelRange.aStart.Row() - 1 );
+ pView->MarkRange( aBlockRange, sal_False );
+ }
+ }
+ else
+ pViewData->GetDispatcher().Execute( FID_FILL_AUTO, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
+ }
+ else if (pViewData->GetFillMode() == SC_FILL_MATRIX)
+ {
+ SCTAB nTab = pViewData->GetTabNo();
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ pViewData->GetFillData( nStartCol, nStartRow, nEndCol, nEndRow );
+ ScRange aBlockRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab );
+ SCCOL nFillCol = pViewData->GetRefEndX();
+ SCROW nFillRow = pViewData->GetRefEndY();
+ ScAddress aEndPos( nFillCol, nFillRow, nTab );
+
+ ScTabView* pView = pViewData->GetView();
+ pView->StopRefMode();
+ pViewData->ResetFillMode();
+ pView->GetFunctionSet()->SetAnchorFlag( sal_False );
+
+ if ( aEndPos != aBlockRange.aEnd )
+ {
+ pViewData->GetDocShell()->GetDocFunc().ResizeMatrix( aBlockRange, aEndPos, sal_False );
+ pViewData->GetView()->MarkRange( ScRange( aBlockRange.aStart, aEndPos ) );
+ }
+ }
+ else if (pViewData->IsAnyFillMode())
+ {
+ // Embedded-Area has been changed
+ ScTabView* pView = pViewData->GetView();
+ pView->StopRefMode();
+ pViewData->ResetFillMode();
+ pView->GetFunctionSet()->SetAnchorFlag( sal_False );
+ pViewData->GetDocShell()->UpdateOle(pViewData);
+ }
+
+ sal_Bool bRefMode = pViewData->IsRefMode();
+ if (bRefMode)
+ pScMod->EndReference();
+
+ //
+ // Giesskannen-Modus (Gestalter)
+ //
+
+ if (pScMod->GetIsWaterCan())
+ {
+ // Abfrage auf Undo schon oben
+
+ ScStyleSheetPool* pStylePool = (ScStyleSheetPool*)
+ (pViewData->GetDocument()->
+ GetStyleSheetPool());
+ if ( pStylePool )
+ {
+ SfxStyleSheet* pStyleSheet = (SfxStyleSheet*)
+ pStylePool->GetActualStyleSheet();
+
+ if ( pStyleSheet )
+ {
+ SfxStyleFamily eFamily = pStyleSheet->GetFamily();
+
+ switch ( eFamily )
+ {
+ case SFX_STYLE_FAMILY_PARA:
+ pViewData->GetView()->SetStyleSheetToMarked( pStyleSheet );
+ pViewData->GetView()->DoneBlockMode();
+ break;
+
+ case SFX_STYLE_FAMILY_PAGE:
+ pViewData->GetDocument()->SetPageStyle( pViewData->GetTabNo(),
+ pStyleSheet->GetName() );
+
+ ScPrintFunc( pViewData->GetDocShell(),
+ pViewData->GetViewShell()->GetPrinter(sal_True),
+ pViewData->GetTabNo() ).UpdatePages();
+
+ rBindings.Invalidate( SID_STATUS_PAGESTYLE );
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ ScDBFunc* pView = pViewData->GetView();
+ ScDocument* pBrushDoc = pView->GetBrushDocument();
+ if ( pBrushDoc )
+ {
+ pView->PasteFromClip( IDF_ATTRIB, pBrushDoc );
+ if ( !pView->IsPaintBrushLocked() )
+ pView->ResetBrushDocument(); // invalidates pBrushDoc pointer
+ }
+
+ //
+ // double click (only left button)
+ //
+
+ sal_Bool bDouble = ( rMEvt.GetClicks() == 2 && rMEvt.IsLeft() );
+ if ( bDouble && !bRefMode && nMouseStatus == SC_GM_DBLDOWN && !pScMod->IsRefDialogOpen() )
+ {
+ // data pilot table
+ Point aPos = rMEvt.GetPosPixel();
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ SCTAB nTab = pViewData->GetTabNo();
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor( nPosX, nPosY, nTab );
+ if ( pDPObj && pDPObj->GetSaveData()->GetDrillDown() )
+ {
+ ScAddress aCellPos( nPosX, nPosY, pViewData->GetTabNo() );
+
+ // Check for header drill-down first.
+ sheet::DataPilotTableHeaderData aData;
+ pDPObj->GetHeaderPositionData(aCellPos, aData);
+
+ if ( ( aData.Flags & sheet::MemberResultFlags::HASMEMBER ) &&
+ ! ( aData.Flags & sheet::MemberResultFlags::SUBTOTAL ) )
+ {
+ sal_uInt16 nDummy;
+ if ( pView->HasSelectionForDrillDown( nDummy ) )
+ {
+ // execute slot to show dialog
+ pViewData->GetDispatcher().Execute( SID_OUTLINE_SHOW, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
+ }
+ else
+ {
+ // toggle single entry
+ ScDPObject aNewObj( *pDPObj );
+ pDPObj->ToggleDetails( aData, &aNewObj );
+ ScDBDocFunc aFunc( *pViewData->GetDocShell() );
+ aFunc.DataPilotUpdate( pDPObj, &aNewObj, sal_True, sal_False );
+ pViewData->GetView()->CursorPosChanged(); // shells may be switched
+ }
+ }
+ else
+ {
+ // Check if the data area is double-clicked.
+
+ Sequence<sheet::DataPilotFieldFilter> aFilters;
+ if ( pDPObj->GetDataFieldPositionData(aCellPos, aFilters) )
+ pViewData->GetView()->ShowDataPilotSourceData( *pDPObj, aFilters );
+ else
+ Sound::Beep(); // nothing to expand/collapse/show
+ }
+
+ return;
+ }
+
+ // Check for cell protection attribute.
+ ScTableProtection* pProtect = pDoc->GetTabProtection( nTab );
+ bool bEditAllowed = true;
+ if ( pProtect && pProtect->isProtected() )
+ {
+ bool bCellProtected = pDoc->HasAttrib(nPosX, nPosY, nTab, nPosX, nPosY, nTab, HASATTR_PROTECTED);
+ bool bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+ bool bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
+
+ if ( bSkipProtected && bSkipUnprotected )
+ bEditAllowed = false;
+ else if ( (bCellProtected && bSkipProtected) || (!bCellProtected && bSkipUnprotected) )
+ bEditAllowed = false;
+ }
+
+ if ( bEditAllowed )
+ {
+ // edit cell contents
+ pViewData->GetViewShell()->UpdateInputHandler();
+ pScMod->SetInputMode( SC_INPUT_TABLE );
+ if (pViewData->HasEditView(eWhich))
+ {
+ // Text-Cursor gleich an die geklickte Stelle setzen
+ EditView* pEditView = pViewData->GetEditView( eWhich );
+ MouseEvent aEditEvt( rMEvt.GetPosPixel(), 1, MOUSE_SYNTHETIC, MOUSE_LEFT, 0 );
+ pEditView->MouseButtonDown( aEditEvt );
+ pEditView->MouseButtonUp( aEditEvt );
+ }
+ }
+ return;
+ }
+
+ //
+ // Links in edit cells
+ //
+
+ sal_Bool bAlt = rMEvt.IsMod2();
+ if ( !bAlt && !bRefMode && !bDouble && nMouseStatus == SC_GM_URLDOWN )
+ {
+ // beim ButtonUp nur ausfuehren, wenn ButtonDown auch ueber einer URL war
+
+ String aName, aUrl, aTarget;
+ if ( GetEditUrl( rMEvt.GetPosPixel(), &aName, &aUrl, &aTarget ) )
+ {
+ nMouseStatus = SC_GM_NONE; // keinen Doppelklick anfangen
+ ScGlobal::OpenURL( aUrl, aTarget );
+
+ // fire worksheet_followhyperlink event
+ uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = pDoc->GetVbaEventProcessor();
+ if( xVbaEvents.is() ) try
+ {
+ Point aPos = rMEvt.GetPosPixel();
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ SCTAB nTab = pViewData->GetTabNo();
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+ ScBaseCell* pCell = NULL;
+ if( lcl_GetHyperlinkCell( pDoc, nPosX, nPosY, nTab, pCell ) )
+ {
+ ScAddress aCellPos( nPosX, nPosY, nTab );
+ uno::Reference< table::XCell > xCell( new ScCellObj( pViewData->GetDocShell(), aCellPos ) );
+ uno::Sequence< uno::Any > aArgs(1);
+ aArgs[0] <<= xCell;
+ xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKSHEET_FOLLOWHYPERLINK, aArgs );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ return;
+ }
+ }
+
+ //
+ // Gridwin - SelectionEngine
+ //
+
+ // SelMouseButtonDown is called only for left button, but SelMouseButtonUp would return
+ // sal_True for any call, so IsLeft must be checked here, too.
+
+ if ( rMEvt.IsLeft() && pViewData->GetView()->GetSelEngine()->SelMouseButtonUp( rMEvt ) )
+ {
+// rMark.MarkToSimple();
+ pViewData->GetView()->UpdateAutoFillMark();
+
+ SfxDispatcher* pDisp = pViewData->GetViewShell()->GetDispatcher();
+ sal_Bool bFormulaMode = pScMod->IsFormulaMode();
+ DBG_ASSERT( pDisp || bFormulaMode, "Cursor auf nicht aktiver View bewegen ?" );
+
+ // #i14927# execute SID_CURRENTCELL (for macro recording) only if there is no
+ // multiple selection, so the argument string completely describes the selection,
+ // and executing the slot won't change the existing selection (executing the slot
+ // here and from a recorded macro is treated equally)
+
+ if ( pDisp && !bFormulaMode && !rMark.IsMultiMarked() )
+ {
+ String aAddr; // CurrentCell
+ if( rMark.IsMarked() )
+ {
+// sal_Bool bKeep = rMark.IsMultiMarked(); //! wohin damit ???
+
+ ScRange aScRange;
+ rMark.GetMarkArea( aScRange );
+ aScRange.Format( aAddr, SCR_ABS );
+ if ( aScRange.aStart == aScRange.aEnd )
+ {
+ // make sure there is a range selection string even for a single cell
+ String aSingle = aAddr;
+ aAddr.Append( (sal_Char) ':' );
+ aAddr.Append( aSingle );
+ }
+
+ //! SID_MARKAREA gibts nicht mehr ???
+ //! was passiert beim Markieren mit dem Cursor ???
+ }
+ else // nur Cursor bewegen
+ {
+ ScAddress aScAddress( pViewData->GetCurX(), pViewData->GetCurY(), 0 );
+ aScAddress.Format( aAddr, SCA_ABS );
+ }
+
+ SfxStringItem aPosItem( SID_CURRENTCELL, aAddr );
+ pDisp->Execute( SID_CURRENTCELL, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
+ &aPosItem, (void*)0L );
+
+ pViewData->GetView()->InvalidateAttribs();
+ }
+ return;
+ }
+}
+
+void ScGridWindow::FakeButtonUp()
+{
+ if ( nButtonDown )
+ {
+ MouseEvent aEvent( aCurMousePos ); // nButtons = 0 -> ignore
+ MouseButtonUp( aEvent );
+ }
+}
+
+void __EXPORT ScGridWindow::MouseMove( const MouseEvent& rMEvt )
+{
+ aCurMousePos = rMEvt.GetPosPixel();
+
+ if ( rMEvt.IsLeaveWindow() && pNoteMarker && !pNoteMarker->IsByKeyboard() )
+ HideNoteMarker();
+
+ ScModule* pScMod = SC_MOD();
+ if (pScMod->IsModalMode(pViewData->GetSfxDocShell()))
+ return;
+
+ // Ob aus dem Edit-Modus Drag&Drop gestartet wurde, bekommt man leider
+ // nicht anders mit:
+
+ if (bEEMouse && nButtonDown && !rMEvt.GetButtons())
+ {
+ bEEMouse = sal_False;
+ nButtonDown = 0;
+ nMouseStatus = SC_GM_NONE;
+ return;
+ }
+
+ if (nMouseStatus == SC_GM_IGNORE)
+ return;
+
+ if (nMouseStatus == SC_GM_WATERUNDO) // Undo im Giesskannenmodus -> nur auf Up warten
+ return;
+
+ if ( pViewData->GetViewShell()->IsAuditShell() ) // Detektiv-Fuell-Modus
+ {
+ SetPointer( Pointer( POINTER_FILL ) );
+ return;
+ }
+
+ if (nMouseStatus == SC_GM_FILTER && pFilterBox)
+ {
+ Point aRelPos = pFilterBox->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) );
+ if ( Rectangle(Point(),pFilterBox->GetOutputSizePixel()).IsInside(aRelPos) )
+ {
+ nButtonDown = 0;
+ nMouseStatus = SC_GM_NONE;
+ if ( pFilterBox->GetMode() == SC_FILTERBOX_FILTER )
+ {
+ if (mpFilterButton.get())
+ {
+ mpFilterButton->setHasHiddenMember(false);
+ mpFilterButton->setPopupPressed(false);
+ HideCursor();
+ mpFilterButton->draw();
+ ShowCursor();
+ }
+ }
+ ReleaseMouse();
+ pFilterBox->MouseButtonDown( MouseEvent( aRelPos, 1, MOUSE_SIMPLECLICK, MOUSE_LEFT ) );
+ return;
+ }
+ }
+
+ sal_Bool bFormulaMode = pScMod->IsFormulaMode(); // naechster Klick -> Referenz
+
+ if (bEEMouse && pViewData->HasEditView( eWhich ))
+ {
+ EditView* pEditView;
+ SCCOL nEditCol;
+ SCROW nEditRow;
+ pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
+ pEditView->MouseMove( rMEvt );
+ return;
+ }
+
+ if (bDPMouse)
+ {
+ DPMouseMove( rMEvt );
+ return;
+ }
+
+ if (bRFMouse)
+ {
+ RFMouseMove( rMEvt, sal_False );
+ return;
+ }
+
+ if (nPagebreakMouse)
+ {
+ PagebreakMove( rMEvt, sal_False );
+ return;
+ }
+
+ // anderen Mauszeiger anzeigen?
+
+ sal_Bool bEditMode = pViewData->HasEditView(eWhich);
+
+ //! Testen ob RefMode-Dragging !!!
+ if ( bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()) )
+ {
+ Point aPos = rMEvt.GetPosPixel();
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+
+ EditView* pEditView;
+ SCCOL nEditCol;
+ SCROW nEditRow;
+ pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
+ SCCOL nEndCol = pViewData->GetEditEndCol();
+ SCROW nEndRow = pViewData->GetEditEndRow();
+
+ if ( nPosX >= (SCsCOL) nEditCol && nPosX <= (SCsCOL) nEndCol &&
+ nPosY >= (SCsROW) nEditRow && nPosY <= (SCsROW) nEndRow )
+ {
+ // Field can only be URL field
+ sal_Bool bAlt = rMEvt.IsMod2();
+ if ( !bAlt && !nButtonDown && pEditView && pEditView->GetFieldUnderMousePointer() )
+ SetPointer( Pointer( POINTER_REFHAND ) );
+ else if ( pEditView && pEditView->GetEditEngine()->IsVertical() )
+ SetPointer( Pointer( POINTER_TEXT_VERTICAL ) );
+ else
+ SetPointer( Pointer( POINTER_TEXT ) );
+ return;
+ }
+ }
+
+ sal_Bool bWater = SC_MOD()->GetIsWaterCan() || pViewData->GetView()->HasPaintBrush();
+ if (bWater)
+ SetPointer( Pointer(POINTER_FILL) );
+
+ if (!bWater)
+ {
+ sal_Bool bCross = sal_False;
+
+ // Range-Finder
+
+ sal_Bool bCorner;
+ if ( HitRangeFinder( rMEvt.GetPosPixel(), bCorner ) )
+ {
+ if (bCorner)
+ SetPointer( Pointer( POINTER_CROSS ) );
+ else
+ SetPointer( Pointer( POINTER_HAND ) );
+ bCross = sal_True;
+ }
+
+ // Page-Break-Modus
+
+ sal_uInt16 nBreakType;
+ if ( !nButtonDown && pViewData->IsPagebreakMode() &&
+ ( nBreakType = HitPageBreak( rMEvt.GetPosPixel() ) ) != 0 )
+ {
+ PointerStyle eNew = POINTER_ARROW;
+ switch ( nBreakType )
+ {
+ case SC_PD_RANGE_L:
+ case SC_PD_RANGE_R:
+ case SC_PD_BREAK_H:
+ eNew = POINTER_ESIZE;
+ break;
+ case SC_PD_RANGE_T:
+ case SC_PD_RANGE_B:
+ case SC_PD_BREAK_V:
+ eNew = POINTER_SSIZE;
+ break;
+ case SC_PD_RANGE_TL:
+ case SC_PD_RANGE_BR:
+ eNew = POINTER_SESIZE;
+ break;
+ case SC_PD_RANGE_TR:
+ case SC_PD_RANGE_BL:
+ eNew = POINTER_NESIZE;
+ break;
+ }
+ SetPointer( Pointer( eNew ) );
+ bCross = sal_True;
+ }
+
+ // Fill-Cursor anzeigen ?
+
+ if ( !bFormulaMode && !nButtonDown )
+ if (TestMouse( rMEvt, sal_False ))
+ bCross = sal_True;
+
+ if ( nButtonDown && pViewData->IsAnyFillMode() )
+ {
+ SetPointer( Pointer( POINTER_CROSS ) );
+ bCross = sal_True;
+ nScFillModeMouseModifier = rMEvt.GetModifier(); // ausgewertet bei AutoFill und Matrix
+ }
+
+ if (!bCross)
+ {
+ sal_Bool bAlt = rMEvt.IsMod2();
+
+ if (bEditMode) // Edit-Mode muss zuerst kommen!
+ SetPointer( Pointer( POINTER_ARROW ) );
+ else if ( !bAlt && !nButtonDown &&
+ GetEditUrl(rMEvt.GetPosPixel()) )
+ SetPointer( Pointer( POINTER_REFHAND ) );
+ else if ( DrawMouseMove(rMEvt) ) // setzt Pointer um
+ return;
+ }
+ }
+
+ if ( pViewData->GetView()->GetSelEngine()->SelMouseMove( rMEvt ) )
+ return;
+}
+
+void lcl_InitMouseEvent( ::com::sun::star::awt::MouseEvent& rEvent, const MouseEvent& rEvt )
+{
+ rEvent.Modifiers = 0;
+ if ( rEvt.IsShift() )
+ rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::SHIFT;
+ if ( rEvt.IsMod1() )
+ rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD1;
+ if ( rEvt.IsMod2() )
+ rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD2;
+ if ( rEvt.IsMod3() )
+ rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD3;
+
+ rEvent.Buttons = 0;
+ if ( rEvt.IsLeft() )
+ rEvent.Buttons |= ::com::sun::star::awt::MouseButton::LEFT;
+ if ( rEvt.IsRight() )
+ rEvent.Buttons |= ::com::sun::star::awt::MouseButton::RIGHT;
+ if ( rEvt.IsMiddle() )
+ rEvent.Buttons |= ::com::sun::star::awt::MouseButton::MIDDLE;
+
+ rEvent.X = rEvt.GetPosPixel().X();
+ rEvent.Y = rEvt.GetPosPixel().Y();
+ rEvent.ClickCount = rEvt.GetClicks();
+ rEvent.PopupTrigger = sal_False;
+}
+
+long ScGridWindow::PreNotify( NotifyEvent& rNEvt )
+{
+ bool bDone = false;
+ sal_uInt16 nType = rNEvt.GetType();
+ if ( nType == EVENT_MOUSEBUTTONUP || nType == EVENT_MOUSEBUTTONDOWN )
+ {
+ Window* pWindow = rNEvt.GetWindow();
+ if (pWindow == this && pViewData)
+ {
+ SfxViewFrame* pViewFrame = pViewData->GetViewShell()->GetViewFrame();
+ if (pViewFrame)
+ {
+ com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = pViewFrame->GetFrame().GetController();
+ if (xController.is())
+ {
+ ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
+ if (pImp && pImp->IsMouseListening())
+ {
+ ::com::sun::star::awt::MouseEvent aEvent;
+ lcl_InitMouseEvent( aEvent, *rNEvt.GetMouseEvent() );
+ if ( rNEvt.GetWindow() )
+ aEvent.Source = rNEvt.GetWindow()->GetComponentInterface();
+ if ( nType == EVENT_MOUSEBUTTONDOWN)
+ bDone = pImp->MousePressed( aEvent );
+ else
+ 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 1;
+ }
+ else
+ return Window::PreNotify( rNEvt );
+}
+
+void ScGridWindow::Tracking( const TrackingEvent& rTEvt )
+{
+ // Weil die SelectionEngine kein Tracking kennt, die Events nur auf
+ // die verschiedenen MouseHandler verteilen...
+
+ const MouseEvent& rMEvt = rTEvt.GetMouseEvent();
+
+ if ( rTEvt.IsTrackingCanceled() ) // alles abbrechen...
+ {
+ if (!pViewData->GetView()->IsInActivatePart())
+ {
+ if (bDPMouse)
+ bDPMouse = sal_False; // gezeichnet wird per bDragRect
+ if (bDragRect)
+ {
+ // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
+ bDragRect = sal_False;
+ UpdateDragRectOverlay();
+ }
+ if (bRFMouse)
+ {
+ RFMouseMove( rMEvt, sal_True ); // richtig abbrechen geht dabei nicht...
+ bRFMouse = sal_False;
+ }
+ if (nPagebreakMouse)
+ {
+ // if (bPagebreakDrawn)
+ // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
+ // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), sal_False );
+ bPagebreakDrawn = sal_False;
+ UpdateDragRectOverlay();
+ nPagebreakMouse = SC_PD_NONE;
+ }
+
+ SetPointer( Pointer( POINTER_ARROW ) );
+ StopMarking();
+ MouseButtonUp( rMEvt ); // mit Status SC_GM_IGNORE aus StopMarking
+
+ sal_Bool bRefMode = pViewData->IsRefMode();
+ if (bRefMode)
+ SC_MOD()->EndReference(); // #63148# Dialog nicht verkleinert lassen
+ }
+ }
+ else if ( rTEvt.IsTrackingEnded() )
+ {
+ // MouseButtonUp immer mit passenden Buttons (z.B. wegen Testtool, #63148#)
+ // Schliesslich behauptet der Tracking-Event ja, dass normal beendet und nicht
+ // abgebrochen wurde.
+
+ MouseEvent aUpEvt( rMEvt.GetPosPixel(), rMEvt.GetClicks(),
+ rMEvt.GetMode(), nButtonDown, rMEvt.GetModifier() );
+ MouseButtonUp( aUpEvt );
+ }
+ else
+ MouseMove( rMEvt );
+}
+
+void ScGridWindow::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel )
+{
+ if ( pFilterBox || nPagebreakMouse )
+ return;
+
+ HideNoteMarker();
+
+ CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, sal_True );
+
+ if (bEEMouse && pViewData->HasEditView( eWhich ))
+ {
+ EditView* pEditView;
+ SCCOL nEditCol;
+ SCROW nEditRow;
+ pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
+
+ // #63263# don't remove the edit view while switching views
+ ScModule* pScMod = SC_MOD();
+ pScMod->SetInEditCommand( sal_True );
+
+ pEditView->Command( aDragEvent );
+
+ ScInputHandler* pHdl = pScMod->GetInputHdl();
+ if (pHdl)
+ pHdl->DataChanged();
+
+ pScMod->SetInEditCommand( sal_False );
+ if (!pViewData->IsActive()) // dropped to different view?
+ {
+ ScInputHandler* pViewHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
+ if ( pViewHdl && pViewData->HasEditView( eWhich ) )
+ {
+ pViewHdl->CancelHandler();
+ ShowCursor(); // missing from KillEditView
+ }
+ }
+ }
+ else
+ if ( !DrawCommand(aDragEvent) )
+ pViewData->GetView()->GetSelEngine()->Command( aDragEvent );
+}
+
+void lcl_SetTextCursorPos( ScViewData* pViewData, ScSplitPos eWhich, Window* pWin )
+{
+ SCCOL nCol = pViewData->GetCurX();
+ SCROW nRow = pViewData->GetCurY();
+ Rectangle aEditArea = pViewData->GetEditArea( eWhich, nCol, nRow, pWin, NULL, sal_True );
+ aEditArea.Right() = aEditArea.Left();
+ aEditArea = pWin->PixelToLogic( aEditArea );
+ pWin->SetCursorRect( &aEditArea );
+}
+
+void __EXPORT ScGridWindow::Command( const CommandEvent& rCEvt )
+{
+ // The command event is send to the window after a possible context
+ // menu from an inplace client is closed. Now we have the chance to
+ // deactivate the inplace client without any problem regarding parent
+ // windows and code on the stack.
+ // For more information, see #126086# and #128122#
+ sal_uInt16 nCmd = rCEvt.GetCommand();
+ ScTabViewShell* pTabViewSh = pViewData->GetViewShell();
+ SfxInPlaceClient* pClient = pTabViewSh->GetIPClient();
+ if ( pClient &&
+ pClient->IsObjectInPlaceActive() &&
+ nCmd == COMMAND_CONTEXTMENU )
+ {
+ pTabViewSh->DeactivateOle();
+ return;
+ }
+
+ ScModule* pScMod = SC_MOD();
+ DBG_ASSERT( nCmd != COMMAND_STARTDRAG, "ScGridWindow::Command called with COMMAND_STARTDRAG" );
+
+ if ( nCmd == COMMAND_STARTEXTTEXTINPUT ||
+ nCmd == COMMAND_ENDEXTTEXTINPUT ||
+ nCmd == COMMAND_EXTTEXTINPUT ||
+ nCmd == COMMAND_CURSORPOS )
+ {
+ sal_Bool bEditView = pViewData->HasEditView( eWhich );
+ if (!bEditView)
+ {
+ // only if no cell editview is active, look at drawview
+ SdrView* pSdrView = pViewData->GetView()->GetSdrView();
+ if ( pSdrView )
+ {
+ OutlinerView* pOlView = pSdrView->GetTextEditOutlinerView();
+ if ( pOlView && pOlView->GetWindow() == this )
+ {
+ pOlView->Command( rCEvt );
+ return; // done
+ }
+ }
+ }
+
+ if ( nCmd == COMMAND_CURSORPOS && !bEditView )
+ {
+ // #88458# CURSORPOS may be called without following text input,
+ // to set the input method window position
+ // -> input mode must not be started,
+ // manually calculate text insert position if not in input mode
+
+ lcl_SetTextCursorPos( pViewData, eWhich, this );
+ return;
+ }
+
+ ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
+ if ( pHdl )
+ {
+ pHdl->InputCommand( rCEvt, sal_True );
+ return; // done
+ }
+
+ Window::Command( rCEvt );
+ return;
+ }
+
+ if ( nCmd == COMMAND_VOICE )
+ {
+ // Der Handler wird nur gerufen, wenn ein Text-Cursor aktiv ist,
+ // also muss es eine EditView oder ein editiertes Zeichenobjekt geben
+
+ ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
+ if ( pHdl && pViewData->HasEditView( eWhich ) )
+ {
+ EditView* pEditView = pViewData->GetEditView( eWhich ); // ist dann nicht 0
+ pHdl->DataChanging();
+ pEditView->Command( rCEvt );
+ pHdl->DataChanged();
+ return; // erledigt
+ }
+ SdrView* pSdrView = pViewData->GetView()->GetSdrView();
+ if ( pSdrView )
+ {
+ OutlinerView* pOlView = pSdrView->GetTextEditOutlinerView();
+ if ( pOlView && pOlView->GetWindow() == this )
+ {
+ pOlView->Command( rCEvt );
+ return; // erledigt
+ }
+ }
+ Window::Command(rCEvt); // sonst soll sich die Basisklasse drum kuemmern...
+ return;
+ }
+
+ if ( nCmd == COMMAND_PASTESELECTION )
+ {
+ if ( bEEMouse )
+ {
+ // EditEngine handles selection in MouseButtonUp - no action
+ // needed in command handler
+ }
+ else
+ {
+ PasteSelection( rCEvt.GetMousePosPixel() );
+ }
+ return;
+ }
+
+ if ( nCmd == COMMAND_INPUTLANGUAGECHANGE )
+ {
+ // #i55929# Font and font size state depends on input language if nothing is selected,
+ // so the slots have to be invalidated when the input language is changed.
+
+ SfxBindings& rBindings = pViewData->GetBindings();
+ rBindings.Invalidate( SID_ATTR_CHAR_FONT );
+ rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
+ return;
+ }
+
+ if ( nCmd == COMMAND_WHEEL || nCmd == COMMAND_STARTAUTOSCROLL || nCmd == COMMAND_AUTOSCROLL )
+ {
+ sal_Bool bDone = pViewData->GetView()->ScrollCommand( rCEvt, eWhich );
+ if (!bDone)
+ Window::Command(rCEvt);
+ return;
+ }
+ // #i7560# FormulaMode check is below scrolling - scrolling is allowed during formula input
+ sal_Bool bDisable = pScMod->IsFormulaMode() ||
+ pScMod->IsModalMode(pViewData->GetSfxDocShell());
+ if (bDisable)
+ return;
+
+ if ( nCmd == COMMAND_CONTEXTMENU && !SC_MOD()->GetIsWaterCan() )
+ {
+ sal_Bool bMouse = rCEvt.IsMouseEvent();
+ if ( bMouse && nMouseStatus == SC_GM_IGNORE )
+ return;
+
+ if (pViewData->IsAnyFillMode())
+ {
+ pViewData->GetView()->StopRefMode();
+ pViewData->ResetFillMode();
+ }
+ ReleaseMouse();
+ StopMarking();
+
+ Point aPosPixel = rCEvt.GetMousePosPixel();
+ Point aMenuPos = aPosPixel;
+
+ if ( bMouse )
+ {
+ SCsCOL nCellX = -1;
+ SCsROW nCellY = -1;
+ pViewData->GetPosFromPixel(aPosPixel.X(), aPosPixel.Y(), eWhich, nCellX, nCellY);
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ const ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ bool bSelectAllowed = true;
+ if ( pProtect && pProtect->isProtected() )
+ {
+ // This sheet is protected. Check if a context menu is allowed on this cell.
+ bool bCellProtected = pDoc->HasAttrib(nCellX, nCellY, nTab, nCellX, nCellY, nTab, HASATTR_PROTECTED);
+ bool bSelProtected = pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+ bool bSelUnprotected = pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
+
+ if (bCellProtected)
+ bSelectAllowed = bSelProtected;
+ else
+ bSelectAllowed = bSelUnprotected;
+ }
+ if (!bSelectAllowed)
+ // Selecting this cell is not allowed, neither is context menu.
+ return;
+
+ // #i18735# First select the item under the mouse pointer.
+ // This can change the selection, and the view state (edit mode, etc).
+ SelectForContextMenu( aPosPixel, nCellX, nCellY );
+ }
+
+ sal_Bool bDone = sal_False;
+ sal_Bool bEdit = pViewData->HasEditView(eWhich);
+ if ( !bEdit )
+ {
+ // Edit-Zelle mit Spelling-Errors ?
+ if ( bMouse && GetEditUrlOrError( sal_True, aPosPixel ) )
+ {
+ // GetEditUrlOrError hat den Cursor schon bewegt
+
+ pScMod->SetInputMode( SC_INPUT_TABLE );
+ bEdit = pViewData->HasEditView(eWhich); // hat's geklappt ?
+
+ DBG_ASSERT( bEdit, "kann nicht in Edit-Modus schalten" );
+ }
+ }
+ if ( bEdit )
+ {
+ EditView* pEditView = pViewData->GetEditView( eWhich ); // ist dann nicht 0
+
+ if ( !bMouse )
+ {
+ Cursor* pCur = pEditView->GetCursor();
+ if ( pCur )
+ {
+ Point aLogicPos = pCur->GetPos();
+ // use the position right of the cursor (spell popup is opened if
+ // the cursor is before the word, but not if behind it)
+ aLogicPos.X() += pCur->GetWidth();
+ aLogicPos.Y() += pCur->GetHeight() / 2; // center vertically
+ aMenuPos = LogicToPixel( aLogicPos );
+ }
+ }
+
+ // if edit mode was just started above, online spelling may be incomplete
+ pEditView->GetEditEngine()->CompleteOnlineSpelling();
+
+ // IsCursorAtWrongSpelledWord could be used for !bMouse
+ // if there was a corresponding ExecuteSpellPopup call
+
+ if( pEditView->IsWrongSpelledWordAtPos( aMenuPos ) )
+ {
+ // Wenn man unter OS/2 neben das Popupmenue klickt, kommt MouseButtonDown
+ // vor dem Ende des Menue-Execute, darum muss SetModified vorher kommen
+ // (Bug #40968#)
+ ScInputHandler* pHdl = pScMod->GetInputHdl();
+ if (pHdl)
+ pHdl->SetModified();
+
+ Link aLink = LINK( this, ScGridWindow, PopupSpellingHdl );
+ pEditView->ExecuteSpellPopup( aMenuPos, &aLink );
+
+ bDone = sal_True;
+ }
+ }
+ else if ( !bMouse )
+ {
+ // non-edit menu by keyboard -> use lower right of cell cursor position
+
+ SCCOL nCurX = pViewData->GetCurX();
+ SCROW nCurY = pViewData->GetCurY();
+ aMenuPos = pViewData->GetScrPos( nCurX, nCurY, eWhich, sal_True );
+ long nSizeXPix;
+ long nSizeYPix;
+ pViewData->GetMergeSizePixel( nCurX, nCurY, nSizeXPix, nSizeYPix );
+ aMenuPos.X() += nSizeXPix;
+ aMenuPos.Y() += nSizeYPix;
+
+ if (pViewData)
+ {
+ ScTabViewShell* pViewSh = pViewData->GetViewShell();
+ if (pViewSh)
+ {
+ // Is a draw object selected?
+
+ SdrView* pDrawView = pViewSh->GetSdrView();
+ if (pDrawView && pDrawView->AreObjectsMarked())
+ {
+ // #100442#; the conext menu should open in the middle of the selected objects
+ Rectangle aSelectRect(LogicToPixel(pDrawView->GetAllMarkedBoundRect()));
+ aMenuPos = aSelectRect.Center();
+ }
+ }
+ }
+ }
+
+ if (!bDone)
+ {
+ SfxDispatcher::ExecutePopup( 0, this, &aMenuPos );
+ }
+ }
+}
+
+void ScGridWindow::SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, SCsROW nCellY )
+{
+ // #i18735# if the click was outside of the current selection,
+ // the cursor is moved or an object at the click position selected.
+ // (see SwEditWin::SelectMenuPosition in Writer)
+
+ ScTabView* pView = pViewData->GetView();
+ ScDrawView* pDrawView = pView->GetScDrawView();
+
+ // check cell edit mode
+
+ if ( pViewData->HasEditView(eWhich) )
+ {
+ ScModule* pScMod = SC_MOD();
+ SCCOL nEditStartCol = pViewData->GetEditViewCol(); //! change to GetEditStartCol after calcrtl is integrated
+ SCROW nEditStartRow = pViewData->GetEditViewRow();
+ SCCOL nEditEndCol = pViewData->GetEditEndCol();
+ SCROW nEditEndRow = pViewData->GetEditEndRow();
+
+ if ( nCellX >= (SCsCOL) nEditStartCol && nCellX <= (SCsCOL) nEditEndCol &&
+ nCellY >= (SCsROW) nEditStartRow && nCellY <= (SCsROW) nEditEndRow )
+ {
+ // handle selection within the EditView
+
+ EditView* pEditView = pViewData->GetEditView( eWhich ); // not NULL (HasEditView)
+ EditEngine* pEditEngine = pEditView->GetEditEngine();
+ Rectangle aOutputArea = pEditView->GetOutputArea();
+ Rectangle aVisArea = pEditView->GetVisArea();
+
+ Point aTextPos = PixelToLogic( rPosPixel );
+ if ( pEditEngine->IsVertical() ) // have to manually transform position
+ {
+ aTextPos -= aOutputArea.TopRight();
+ long nTemp = -aTextPos.X();
+ aTextPos.X() = aTextPos.Y();
+ aTextPos.Y() = nTemp;
+ }
+ else
+ aTextPos -= aOutputArea.TopLeft();
+ aTextPos += aVisArea.TopLeft(); // position in the edit document
+
+ EPosition aDocPosition = pEditEngine->FindDocPosition(aTextPos);
+ ESelection aCompare(aDocPosition.nPara, aDocPosition.nIndex);
+ ESelection aSelection = pEditView->GetSelection();
+ aSelection.Adjust(); // needed for IsLess/IsGreater
+ if ( aCompare.IsLess(aSelection) || aCompare.IsGreater(aSelection) )
+ {
+ // clicked outside the selected text - deselect and move text cursor
+ MouseEvent aEvent( rPosPixel );
+ pEditView->MouseButtonDown( aEvent );
+ pEditView->MouseButtonUp( aEvent );
+ pScMod->InputSelection( pEditView );
+ }
+
+ return; // clicked within the edit view - keep edit mode
+ }
+ else
+ {
+ // outside of the edit view - end edit mode, regardless of cell selection, then continue
+ pScMod->InputEnterHandler();
+ }
+ }
+
+ // check draw text edit mode
+
+ Point aLogicPos = PixelToLogic( rPosPixel ); // after cell edit mode is ended
+ if ( pDrawView && pDrawView->GetTextEditObject() && pDrawView->GetTextEditOutlinerView() )
+ {
+ OutlinerView* pOlView = pDrawView->GetTextEditOutlinerView();
+ Rectangle aOutputArea = pOlView->GetOutputArea();
+ if ( aOutputArea.IsInside( aLogicPos ) )
+ {
+ // handle selection within the OutlinerView
+
+ Outliner* pOutliner = pOlView->GetOutliner();
+ const EditEngine& rEditEngine = pOutliner->GetEditEngine();
+ Rectangle aVisArea = pOlView->GetVisArea();
+
+ Point aTextPos = aLogicPos;
+ if ( pOutliner->IsVertical() ) // have to manually transform position
+ {
+ aTextPos -= aOutputArea.TopRight();
+ long nTemp = -aTextPos.X();
+ aTextPos.X() = aTextPos.Y();
+ aTextPos.Y() = nTemp;
+ }
+ else
+ aTextPos -= aOutputArea.TopLeft();
+ aTextPos += aVisArea.TopLeft(); // position in the edit document
+
+ EPosition aDocPosition = rEditEngine.FindDocPosition(aTextPos);
+ ESelection aCompare(aDocPosition.nPara, aDocPosition.nIndex);
+ ESelection aSelection = pOlView->GetSelection();
+ aSelection.Adjust(); // needed for IsLess/IsGreater
+ if ( aCompare.IsLess(aSelection) || aCompare.IsGreater(aSelection) )
+ {
+ // clicked outside the selected text - deselect and move text cursor
+ // use DrawView to allow extra handling there (none currently)
+ MouseEvent aEvent( rPosPixel );
+ pDrawView->MouseButtonDown( aEvent, this );
+ pDrawView->MouseButtonUp( aEvent, this );
+ }
+
+ return; // clicked within the edit area - keep edit mode
+ }
+ else
+ {
+ // Outside of the edit area - end text edit mode, then continue.
+ // DrawDeselectAll also ends text edit mode and updates the shells.
+ // If the click was on the edited object, it will be selected again below.
+ pView->DrawDeselectAll();
+ }
+ }
+
+ // look for existing selection
+
+ sal_Bool bHitSelected = sal_False;
+ if ( pDrawView && pDrawView->IsMarkedObjHit( aLogicPos ) )
+ {
+ // clicked on selected object -> don't change anything
+ bHitSelected = sal_True;
+ }
+ else if ( pViewData->GetMarkData().IsCellMarked(nCellX, nCellY) )
+ {
+ // clicked on selected cell -> don't change anything
+ bHitSelected = sal_True;
+ }
+
+ // select drawing object or move cell cursor
+
+ if ( !bHitSelected )
+ {
+ sal_Bool bWasDraw = ( pDrawView && pDrawView->AreObjectsMarked() );
+ sal_Bool bHitDraw = sal_False;
+ if ( pDrawView )
+ {
+ pDrawView->UnmarkAllObj();
+ // Unlock the Internal Layer in order to activate the context menu.
+ // re-lock in ScDrawView::MarkListHasChanged()
+ lcl_UnLockComment( pDrawView, pDrawView->GetSdrPageView(), pDrawView->GetModel(), aLogicPos ,pViewData);
+ bHitDraw = pDrawView->MarkObj( aLogicPos );
+ // draw shell is activated in MarkListHasChanged
+ }
+ if ( !bHitDraw )
+ {
+ pView->Unmark();
+ pView->SetCursor(nCellX, nCellY);
+ if ( bWasDraw )
+ pViewData->GetViewShell()->SetDrawShell( sal_False ); // switch shells
+ }
+ }
+}
+
+void __EXPORT ScGridWindow::KeyInput(const KeyEvent& rKEvt)
+{
+ // #96965# Cursor control for ref input dialog
+ if( SC_MOD()->IsRefDialogOpen() )
+ {
+ const KeyCode& rKeyCode = rKEvt.GetKeyCode();
+ if( !rKeyCode.GetModifier() && (rKeyCode.GetCode() == KEY_F2) )
+ {
+ SC_MOD()->EndReference();
+ return;
+ }
+ else if( pViewData->GetViewShell()->MoveCursorKeyInput( rKEvt ) )
+ {
+ ScRange aRef(
+ pViewData->GetRefStartX(), pViewData->GetRefStartY(), pViewData->GetRefStartZ(),
+ pViewData->GetRefEndX(), pViewData->GetRefEndY(), pViewData->GetRefEndZ() );
+ SC_MOD()->SetReference( aRef, pViewData->GetDocument() );
+ return;
+ }
+ }
+ // wenn semi-Modeless-SfxChildWindow-Dialog oben, keine KeyInputs:
+ else if( !pViewData->IsAnyFillMode() )
+ {
+ // query for existing note marker before calling ViewShell's keyboard handling
+ // which may remove the marker
+ sal_Bool bHadKeyMarker = ( pNoteMarker && pNoteMarker->IsByKeyboard() );
+ ScTabViewShell* pViewSh = pViewData->GetViewShell();
+
+ if (pViewData->GetDocShell()->GetProgress())
+ return;
+
+ if (DrawKeyInput(rKEvt))
+ return;
+
+ if (!pViewData->GetView()->IsDrawSelMode() && !DrawHasMarkedObj()) // keine Eingaben im Zeichenmodus
+ { //! DrawShell abfragen !!!
+ if (pViewSh->TabKeyInput(rKEvt))
+ return;
+ }
+ else
+ if (pViewSh->SfxViewShell::KeyInput(rKEvt)) // von SfxViewShell
+ return;
+
+ KeyCode aCode = rKEvt.GetKeyCode();
+ if ( aCode.GetCode() == KEY_ESCAPE && aCode.GetModifier() == 0 )
+ {
+ if ( bHadKeyMarker )
+ HideNoteMarker();
+ else
+ pViewSh->Escape();
+ return;
+ }
+ if ( aCode.GetCode() == KEY_F1 && aCode.GetModifier() == KEY_MOD1 )
+ {
+ // ctrl-F1 shows or hides the note or redlining info for the cursor position
+ // (hard-coded because F1 can't be configured)
+
+ if ( bHadKeyMarker )
+ HideNoteMarker(); // hide when previously visible
+ else
+ ShowNoteMarker( pViewData->GetCurX(), pViewData->GetCurY(), sal_True );
+ return;
+ }
+ }
+
+ Window::KeyInput(rKEvt);
+}
+
+void ScGridWindow::StopMarking()
+{
+ DrawEndAction(); // Markieren/Verschieben auf Drawing-Layer abbrechen
+
+ if (nButtonDown)
+ {
+ pViewData->GetMarkData().SetMarking(sal_False);
+ nMouseStatus = SC_GM_IGNORE;
+ }
+}
+
+void ScGridWindow::UpdateInputContext()
+{
+ sal_Bool bReadOnly = pViewData->GetDocShell()->IsReadOnly();
+ sal_uLong nOptions = bReadOnly ? 0 : ( INPUTCONTEXT_TEXT | INPUTCONTEXT_EXTTEXTINPUT );
+
+ // when font from InputContext is used,
+ // it must be taken from the cursor position's cell attributes
+
+ InputContext aContext;
+ aContext.SetOptions( nOptions );
+ SetInputContext( aContext );
+}
+
+//--------------------------------------------------------
+
+ // sensitiver Bereich (Pixel)
+#define SCROLL_SENSITIVE 20
+
+sal_Bool ScGridWindow::DropScroll( const Point& rMousePos )
+{
+/* doch auch auf nicht aktiven Views...
+ if ( !pViewData->IsActive() )
+ return sal_False;
+*/
+ SCsCOL nDx = 0;
+ SCsROW nDy = 0;
+ Size aSize = GetOutputSizePixel();
+
+ if (aSize.Width() > SCROLL_SENSITIVE * 3)
+ {
+ if ( rMousePos.X() < SCROLL_SENSITIVE && pViewData->GetPosX(WhichH(eWhich)) > 0 )
+ nDx = -1;
+ if ( rMousePos.X() >= aSize.Width() - SCROLL_SENSITIVE
+ && pViewData->GetPosX(WhichH(eWhich)) < MAXCOL )
+ nDx = 1;
+ }
+ if (aSize.Height() > SCROLL_SENSITIVE * 3)
+ {
+ if ( rMousePos.Y() < SCROLL_SENSITIVE && pViewData->GetPosY(WhichV(eWhich)) > 0 )
+ nDy = -1;
+ if ( rMousePos.Y() >= aSize.Height() - SCROLL_SENSITIVE
+ && pViewData->GetPosY(WhichV(eWhich)) < MAXROW )
+ nDy = 1;
+ }
+
+ if ( nDx != 0 || nDy != 0 )
+ {
+// if (bDragRect)
+// pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
+
+ if ( nDx != 0 )
+ pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
+ if ( nDy != 0 )
+ pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );
+
+// if (bDragRect)
+// pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
+ }
+
+ return sal_False;
+}
+
+sal_Bool lcl_TestScenarioRedliningDrop( ScDocument* pDoc, const ScRange& aDragRange)
+{
+ // Testet, ob bei eingeschalteten RedLining,
+ // bei einem Drop ein Scenario betroffen ist.
+
+ sal_Bool bReturn = sal_False;
+ SCTAB nTab = aDragRange.aStart.Tab();
+ SCTAB nTabCount = pDoc->GetTableCount();
+
+ if(pDoc->GetChangeTrack()!=NULL)
+ {
+ if( pDoc->IsScenario(nTab) && pDoc->HasScenarioRange(nTab, aDragRange))
+ {
+ bReturn = sal_True;
+ }
+ else
+ {
+ for(SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
+ {
+ if(pDoc->HasScenarioRange(i, aDragRange))
+ {
+ bReturn = sal_True;
+ break;
+ }
+ }
+ }
+ }
+ return bReturn;
+}
+
+ScRange lcl_MakeDropRange( SCCOL nPosX, SCROW nPosY, SCTAB nTab, const ScRange& rSource )
+{
+ SCCOL nCol1 = nPosX;
+ SCCOL nCol2 = nCol1 + ( rSource.aEnd.Col() - rSource.aStart.Col() );
+ if ( nCol2 > MAXCOL )
+ {
+ nCol1 -= nCol2 - MAXCOL;
+ nCol2 = MAXCOL;
+ }
+ SCROW nRow1 = nPosY;
+ SCROW nRow2 = nRow1 + ( rSource.aEnd.Row() - rSource.aStart.Row() );
+ if ( nRow2 > MAXROW )
+ {
+ nRow1 -= nRow2 - MAXROW;
+ nRow2 = MAXROW;
+ }
+
+ return ScRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
+}
+
+//--------------------------------------------------------
+
+extern sal_Bool bPasteIsDrop; // viewfun4 -> move to header
+extern sal_Bool bPasteIsMove; // viewfun7 -> move to header
+
+//--------------------------------------------------------
+
+sal_Int8 ScGridWindow::AcceptPrivateDrop( const AcceptDropEvent& rEvt )
+{
+ if ( rEvt.mbLeaving )
+ {
+ // if (bDragRect)
+ // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
+ bDragRect = sal_False;
+ UpdateDragRectOverlay();
+ return rEvt.mnAction;
+ }
+
+ const ScDragData& rData = SC_MOD()->GetDragData();
+ if ( rData.pCellTransfer )
+ {
+ // Don't move source that would include filtered rows.
+ if ((rEvt.mnAction & DND_ACTION_MOVE) && rData.pCellTransfer->HasFilteredRows())
+ {
+ if (bDragRect)
+ {
+ bDragRect = sal_False;
+ UpdateDragRectOverlay();
+ }
+ return DND_ACTION_NONE;
+ }
+
+ Point aPos = rEvt.maPosPixel;
+
+ ScDocument* pSourceDoc = rData.pCellTransfer->GetSourceDocument();
+ ScDocument* pThisDoc = pViewData->GetDocument();
+ if (pSourceDoc == pThisDoc)
+ {
+ if ( pThisDoc->HasChartAtPoint(pViewData->GetTabNo(), PixelToLogic(aPos)) )
+ {
+ if (bDragRect) // Rechteck loeschen
+ {
+ // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
+ bDragRect = sal_False;
+ UpdateDragRectOverlay();
+ }
+
+ //! highlight chart? (selection border?)
+
+ sal_Int8 nRet = rEvt.mnAction;
+//! if ( rEvt.GetAction() == DROP_LINK )
+//! bOk = rEvt.SetAction( DROP_COPY ); // can't link onto chart
+ return nRet;
+ }
+ }
+//! else
+//! if ( rEvt.GetAction() == DROP_MOVE )
+//! rEvt.SetAction( DROP_COPY ); // different doc: default=COPY
+
+
+ if ( rData.pCellTransfer->GetDragSourceFlags() & SC_DROP_TABLE ) // whole sheet?
+ {
+ sal_Bool bOk = pThisDoc->IsDocEditable();
+ return bOk ? rEvt.mnAction : 0; // don't draw selection frame
+ }
+
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+
+ ScRange aSourceRange = rData.pCellTransfer->GetRange();
+ SCCOL nSourceStartX = aSourceRange.aStart.Col();
+ SCROW nSourceStartY = aSourceRange.aStart.Row();
+ SCCOL nSourceEndX = aSourceRange.aEnd.Col();
+ SCROW nSourceEndY = aSourceRange.aEnd.Row();
+ SCCOL nSizeX = nSourceEndX - nSourceStartX + 1;
+ SCROW nSizeY = nSourceEndY - nSourceStartY + 1;
+
+ if ( rEvt.mnAction != DND_ACTION_MOVE )
+ nSizeY = rData.pCellTransfer->GetNonFilteredRows(); // copy/link: no filtered rows
+
+ SCsCOL nNewDragX = nPosX - rData.pCellTransfer->GetDragHandleX();
+ if (nNewDragX<0) nNewDragX=0;
+ if (nNewDragX+(nSizeX-1) > MAXCOL)
+ nNewDragX = MAXCOL-(nSizeX-1);
+ SCsROW nNewDragY = nPosY - rData.pCellTransfer->GetDragHandleY();
+ if (nNewDragY<0) nNewDragY=0;
+ if (nNewDragY+(nSizeY-1) > MAXROW)
+ nNewDragY = MAXROW-(nSizeY-1);
+
+ // don't break scenario ranges, don't drop on filtered
+ SCTAB nTab = pViewData->GetTabNo();
+ ScRange aDropRange = lcl_MakeDropRange( nNewDragX, nNewDragY, nTab, aSourceRange );
+ if ( lcl_TestScenarioRedliningDrop( pThisDoc, aDropRange ) ||
+ lcl_TestScenarioRedliningDrop( pSourceDoc, aSourceRange ) ||
+ ScViewUtil::HasFiltered( aDropRange, pThisDoc) )
+ {
+ if (bDragRect)
+ {
+ // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
+ bDragRect = sal_False;
+ UpdateDragRectOverlay();
+ }
+ return DND_ACTION_NONE;
+ }
+
+ InsCellCmd eDragInsertMode = INS_NONE;
+ Window::PointerState aState = GetPointerState();
+
+ // check for datapilot item sorting
+ ScDPObject* pDPObj = NULL;
+ if ( pThisDoc == pSourceDoc && ( pDPObj = pThisDoc->GetDPAtCursor( nNewDragX, nNewDragY, nTab ) ) != NULL )
+ {
+ // drop on DataPilot table: sort or nothing
+
+ bool bDPSort = false;
+ if ( pThisDoc->GetDPAtCursor( nSourceStartX, nSourceStartY, aSourceRange.aStart.Tab() ) == pDPObj )
+ {
+ sheet::DataPilotTableHeaderData aDestData;
+ pDPObj->GetHeaderPositionData( ScAddress(nNewDragX, nNewDragY, nTab), aDestData );
+ bool bValid = ( aDestData.Dimension >= 0 ); // dropping onto a field
+
+ // look through the source range
+ for (SCROW nRow = aSourceRange.aStart.Row(); bValid && nRow <= aSourceRange.aEnd.Row(); ++nRow )
+ for (SCCOL nCol = aSourceRange.aStart.Col(); bValid && nCol <= aSourceRange.aEnd.Col(); ++nCol )
+ {
+ sheet::DataPilotTableHeaderData aSourceData;
+ pDPObj->GetHeaderPositionData( ScAddress( nCol, nRow, aSourceRange.aStart.Tab() ), aSourceData );
+ if ( aSourceData.Dimension != aDestData.Dimension || !aSourceData.MemberName.getLength() )
+ bValid = false; // empty (subtotal) or different field
+ }
+
+ if ( bValid )
+ {
+ sal_Bool bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( aDestData.Dimension, bIsDataLayout );
+ const ScDPSaveDimension* pDim = pDPObj->GetSaveData()->GetExistingDimensionByName( aDimName );
+ if ( pDim )
+ {
+ ScRange aOutRange = pDPObj->GetOutRange();
+
+ sal_uInt16 nOrient = pDim->GetOrientation();
+ if ( nOrient == sheet::DataPilotFieldOrientation_COLUMN )
+ {
+ eDragInsertMode = INS_CELLSRIGHT;
+ nSizeY = aOutRange.aEnd.Row() - nNewDragY + 1;
+ bDPSort = true;
+ }
+ else if ( nOrient == sheet::DataPilotFieldOrientation_ROW )
+ {
+ eDragInsertMode = INS_CELLSDOWN;
+ nSizeX = aOutRange.aEnd.Col() - nNewDragX + 1;
+ bDPSort = true;
+ }
+ }
+ }
+ }
+
+ if ( !bDPSort )
+ {
+ // no valid sorting in a DataPilot table -> disallow
+ if ( bDragRect )
+ {
+ bDragRect = sal_False;
+ UpdateDragRectOverlay();
+ }
+ return DND_ACTION_NONE;
+ }
+ }
+ else if ( aState.mnState & KEY_MOD2 )
+ {
+ if ( pThisDoc == pSourceDoc && nTab == aSourceRange.aStart.Tab() )
+ {
+ long nDeltaX = labs( static_cast< long >( nNewDragX - nSourceStartX ) );
+ long nDeltaY = labs( static_cast< long >( nNewDragY - nSourceStartY ) );
+ if ( nDeltaX <= nDeltaY )
+ {
+ eDragInsertMode = INS_CELLSDOWN;
+ }
+ else
+ {
+ eDragInsertMode = INS_CELLSRIGHT;
+ }
+
+ if ( ( eDragInsertMode == INS_CELLSDOWN && nNewDragY <= nSourceEndY &&
+ ( nNewDragX + nSizeX - 1 ) >= nSourceStartX && nNewDragX <= nSourceEndX &&
+ ( nNewDragX != nSourceStartX || nNewDragY >= nSourceStartY ) ) ||
+ ( eDragInsertMode == INS_CELLSRIGHT && nNewDragX <= nSourceEndX &&
+ ( nNewDragY + nSizeY - 1 ) >= nSourceStartY && nNewDragY <= nSourceEndY &&
+ ( nNewDragY != nSourceStartY || nNewDragX >= nSourceStartX ) ) )
+ {
+ if ( bDragRect )
+ {
+ bDragRect = sal_False;
+ UpdateDragRectOverlay();
+ }
+ return DND_ACTION_NONE;
+ }
+ }
+ else
+ {
+ if ( static_cast< long >( nSizeX ) >= static_cast< long >( nSizeY ) )
+ {
+ eDragInsertMode = INS_CELLSDOWN;
+
+ }
+ else
+ {
+ eDragInsertMode = INS_CELLSRIGHT;
+ }
+ }
+ }
+
+ if ( nNewDragX != (SCsCOL) nDragStartX || nNewDragY != (SCsROW) nDragStartY ||
+ nDragStartX+nSizeX-1 != nDragEndX || nDragStartY+nSizeY-1 != nDragEndY ||
+ !bDragRect || eDragInsertMode != meDragInsertMode )
+ {
+ // if (bDragRect)
+ // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
+
+ nDragStartX = nNewDragX;
+ nDragStartY = nNewDragY;
+ nDragEndX = nDragStartX+nSizeX-1;
+ nDragEndY = nDragStartY+nSizeY-1;
+ bDragRect = sal_True;
+ meDragInsertMode = eDragInsertMode;
+
+ // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
+
+ UpdateDragRectOverlay();
+
+ // show target position as tip help
+#if 0
+ if (Help::IsQuickHelpEnabled())
+ {
+ ScRange aRange( nDragStartX, nDragStartY, nTab, nDragEndX, nDragEndY, nTab );
+ String aHelpStr;
+ aRange.Format( aHelpStr, SCA_VALID ); // non-3D
+
+ Point aPos = Pointer::GetPosPixel();
+ sal_uInt16 nAlign = QUICKHELP_BOTTOM|QUICKHELP_RIGHT;
+ Rectangle aRect( aPos, aPos );
+ Help::ShowQuickHelp(aRect, aHelpStr, nAlign);
+ }
+#endif
+ }
+ }
+
+ return rEvt.mnAction;
+}
+
+sal_Int8 ScGridWindow::AcceptDrop( const AcceptDropEvent& rEvt )
+{
+ const ScDragData& rData = SC_MOD()->GetDragData();
+ if ( rEvt.mbLeaving )
+ {
+ DrawMarkDropObj( NULL );
+ if ( rData.pCellTransfer )
+ return AcceptPrivateDrop( rEvt ); // hide drop marker for internal D&D
+ else
+ return rEvt.mnAction;
+ }
+
+ if ( pViewData->GetDocShell()->IsReadOnly() )
+ return DND_ACTION_NONE;
+
+
+ sal_Int8 nRet = DND_ACTION_NONE;
+
+ if (rData.pCellTransfer)
+ {
+ ScRange aSource = rData.pCellTransfer->GetRange();
+ if ( aSource.aStart.Col() != 0 || aSource.aEnd.Col() != MAXCOL ||
+ aSource.aStart.Row() != 0 || aSource.aEnd.Row() != MAXROW )
+ DropScroll( rEvt.maPosPixel );
+
+ nRet = AcceptPrivateDrop( rEvt );
+ }
+ else
+ {
+ if ( rData.aLinkDoc.Len() )
+ {
+ String aThisName;
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ if (pDocSh && pDocSh->HasName())
+ aThisName = pDocSh->GetMedium()->GetName();
+
+ if ( rData.aLinkDoc != aThisName )
+ nRet = rEvt.mnAction;
+ }
+ else if (rData.aJumpTarget.Len())
+ {
+ // internal bookmarks (from Navigator)
+ // local jumps from an unnamed document are possible only within a document
+
+ if ( !rData.pJumpLocalDoc || rData.pJumpLocalDoc == pViewData->GetDocument() )
+ nRet = rEvt.mnAction;
+ }
+ else
+ {
+ sal_Int8 nMyAction = rEvt.mnAction;
+
+ if ( !rData.pDrawTransfer ||
+ !IsMyModel(rData.pDrawTransfer->GetDragSourceView()) ) // drawing within the document
+ if ( rEvt.mbDefault && nMyAction == DND_ACTION_MOVE )
+ nMyAction = DND_ACTION_COPY;
+
+ ScDocument* pThisDoc = pViewData->GetDocument();
+ SdrObject* pHitObj = pThisDoc->GetObjectAtPoint(
+ pViewData->GetTabNo(), PixelToLogic(rEvt.maPosPixel) );
+ if ( pHitObj && nMyAction == DND_ACTION_LINK && !rData.pDrawTransfer )
+ {
+ if ( IsDropFormatSupported(SOT_FORMATSTR_ID_SVXB)
+ || IsDropFormatSupported(SOT_FORMAT_GDIMETAFILE)
+ || IsDropFormatSupported(SOT_FORMAT_BITMAP) )
+ {
+ // graphic dragged onto drawing object
+ DrawMarkDropObj( pHitObj );
+ nRet = nMyAction;
+ }
+ }
+ if (!nRet)
+ DrawMarkDropObj( NULL );
+
+ if (!nRet)
+ {
+ switch ( nMyAction )
+ {
+ case DND_ACTION_COPY:
+ case DND_ACTION_MOVE:
+ case DND_ACTION_COPYMOVE:
+ {
+ sal_Bool bMove = ( nMyAction == DND_ACTION_MOVE );
+ if ( IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ||
+ IsDropFormatSupported( SOT_FORMAT_STRING ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_SYLK ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_HTML ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_HTML_SIMPLE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_DIF ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_DRAWING ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_SVXB ) ||
+ IsDropFormatSupported( SOT_FORMAT_RTF ) ||
+ IsDropFormatSupported( SOT_FORMAT_GDIMETAFILE ) ||
+ IsDropFormatSupported( SOT_FORMAT_BITMAP ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ) ||
+ ( !bMove && (
+ IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) ||
+ IsDropFormatSupported( SOT_FORMAT_FILE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) ) ) )
+ {
+ nRet = nMyAction;
+ }
+ }
+ break;
+ case DND_ACTION_LINK:
+ if ( IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) ||
+ IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) ||
+ IsDropFormatSupported( SOT_FORMAT_FILE ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) ||
+ IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) )
+ {
+ nRet = nMyAction;
+ }
+ break;
+ }
+
+ if ( nRet )
+ {
+ // Simple check for protection: It's not known here if the drop will result
+ // in cells or drawing objects (some formats can be both) and how many cells
+ // the result will be. But if IsFormatEditable for the drop cell position
+ // is sal_False (ignores matrix formulas), nothing can be pasted, so the drop
+ // can already be rejected here.
+
+ Point aPos = rEvt.maPosPixel;
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ ScEditableTester aTester( pDoc, nTab, nPosX,nPosY, nPosX,nPosY );
+ if ( !aTester.IsFormatEditable() )
+ nRet = DND_ACTION_NONE; // forbidden
+ }
+ }
+ }
+
+ // scroll only for accepted formats
+ if (nRet)
+ DropScroll( rEvt.maPosPixel );
+ }
+
+ return nRet;
+}
+
+sal_uLong lcl_GetDropFormatId( const uno::Reference<datatransfer::XTransferable>& xTransfer, bool bPreferText = false )
+{
+ TransferableDataHelper aDataHelper( xTransfer );
+
+ if ( !aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) )
+ {
+ // use bookmark formats if no sba is present
+
+ if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) )
+ return SOT_FORMATSTR_ID_SOLK;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) )
+ return SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) )
+ return SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) )
+ return SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR;
+ }
+
+ sal_uLong nFormatId = 0;
+ if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ) )
+ nFormatId = SOT_FORMATSTR_ID_DRAWING;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ) )
+ nFormatId = SOT_FORMATSTR_ID_SVXB;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) )
+ {
+ // If it's a Writer object, insert RTF instead of OLE
+
+ sal_Bool bDoRtf = sal_False;
+ SotStorageStreamRef xStm;
+ TransferableObjectDescriptor aObjDesc;
+ if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) &&
+ aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_EMBED_SOURCE, xStm ) )
+ {
+ SotStorageRef xStore( new SotStorage( *xStm ) );
+ bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) ||
+ aObjDesc.maClassName == SvGlobalName( SO3_SWWEB_CLASSID ) )
+ && aDataHelper.HasFormat( SOT_FORMAT_RTF ) );
+ }
+ if ( bDoRtf )
+ nFormatId = FORMAT_RTF;
+ else
+ nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE;
+ }
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) )
+ nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) )
+ nFormatId = SOT_FORMATSTR_ID_SBA_DATAEXCHANGE;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ) )
+ nFormatId = SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_BIFF_8 ) )
+ nFormatId = SOT_FORMATSTR_ID_BIFF_8;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_BIFF_5 ) )
+ nFormatId = SOT_FORMATSTR_ID_BIFF_5;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) )
+ nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE_OLE;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) )
+ nFormatId = SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) )
+ nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE;
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_RTF ) )
+ nFormatId = SOT_FORMAT_RTF;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_HTML ) )
+ nFormatId = SOT_FORMATSTR_ID_HTML;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) )
+ nFormatId = SOT_FORMATSTR_ID_HTML_SIMPLE;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SYLK ) )
+ nFormatId = SOT_FORMATSTR_ID_SYLK;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK ) )
+ nFormatId = SOT_FORMATSTR_ID_LINK;
+ else if ( bPreferText && aDataHelper.HasFormat( SOT_FORMAT_STRING ) ) // #i86734# the behaviour introduced in #i62773# is wrong when pasting
+ nFormatId = SOT_FORMAT_STRING;
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE_LIST ) )
+ nFormatId = SOT_FORMAT_FILE_LIST;
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE ) ) // #i62773# FILE_LIST/FILE before STRING (Unix file managers)
+ nFormatId = SOT_FORMAT_FILE;
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) )
+ nFormatId = SOT_FORMAT_STRING;
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_GDIMETAFILE ) )
+ nFormatId = SOT_FORMAT_GDIMETAFILE;
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_BITMAP ) )
+ nFormatId = SOT_FORMAT_BITMAP;
+
+ return nFormatId;
+}
+
+sal_uLong lcl_GetDropLinkId( const uno::Reference<datatransfer::XTransferable>& xTransfer )
+{
+ TransferableDataHelper aDataHelper( xTransfer );
+
+ sal_uLong nFormatId = 0;
+ if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) )
+ nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) )
+ nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK ) )
+ nFormatId = SOT_FORMATSTR_ID_LINK;
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE_LIST ) )
+ nFormatId = SOT_FORMAT_FILE_LIST;
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE ) )
+ nFormatId = SOT_FORMAT_FILE;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) )
+ nFormatId = SOT_FORMATSTR_ID_SOLK;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) )
+ nFormatId = SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) )
+ nFormatId = SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK;
+ else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) )
+ nFormatId = SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR;
+
+ return nFormatId;
+}
+
+
+sal_Int8 ScGridWindow::ExecutePrivateDrop( const ExecuteDropEvent& rEvt )
+{
+ // hide drop marker
+ // if (bDragRect)
+ // pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
+ bDragRect = sal_False;
+ UpdateDragRectOverlay();
+
+ ScModule* pScMod = SC_MOD();
+ const ScDragData& rData = pScMod->GetDragData();
+
+ return DropTransferObj( rData.pCellTransfer, nDragStartX, nDragStartY,
+ PixelToLogic(rEvt.maPosPixel), rEvt.mnAction );
+}
+
+sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPosX, SCROW nDestPosY,
+ const Point& rLogicPos, sal_Int8 nDndAction )
+{
+ if ( !pTransObj )
+ return 0;
+
+ ScDocument* pSourceDoc = pTransObj->GetSourceDocument();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pThisDoc = pViewData->GetDocument();
+ ScViewFunc* pView = pViewData->GetView();
+ SCTAB nThisTab = pViewData->GetTabNo();
+ sal_uInt16 nFlags = pTransObj->GetDragSourceFlags();
+
+ sal_Bool bIsNavi = ( nFlags & SC_DROP_NAVIGATOR ) != 0;
+ sal_Bool bIsMove = ( nDndAction == DND_ACTION_MOVE && !bIsNavi );
+
+ // workaround for wrong nDndAction on Windows when pressing solely
+ // the Alt key during drag and drop;
+ // can be removed after #i79215# has been fixed
+ if ( meDragInsertMode != INS_NONE )
+ {
+ bIsMove = ( nDndAction & DND_ACTION_MOVE && !bIsNavi );
+ }
+
+ sal_Bool bIsLink = ( nDndAction == DND_ACTION_LINK );
+
+ ScRange aSource = pTransObj->GetRange();
+
+ // only use visible tab from source range - when dragging within one table,
+ // all selected tables at the time of dropping are used (handled in MoveBlockTo)
+ SCTAB nSourceTab = pTransObj->GetVisibleTab();
+ aSource.aStart.SetTab( nSourceTab );
+ aSource.aEnd.SetTab( nSourceTab );
+
+ SCCOL nSizeX = aSource.aEnd.Col() - aSource.aStart.Col() + 1;
+ SCROW nSizeY = (bIsMove ? (aSource.aEnd.Row() - aSource.aStart.Row() + 1) :
+ pTransObj->GetNonFilteredRows()); // copy/link: no filtered rows
+ ScRange aDest( nDestPosX, nDestPosY, nThisTab,
+ nDestPosX + nSizeX - 1, nDestPosY + nSizeY - 1, nThisTab );
+
+
+ /* NOTE: AcceptPrivateDrop() already checked for filtered conditions during
+ * dragging and adapted drawing of the selection frame. We check here
+ * (again) because this may actually also be called from PasteSelection(),
+ * we would have to duplicate determination of flags and destination range
+ * and would lose the context of the "filtered destination is OK" cases
+ * below, which is already awkward enough as is. */
+
+ // Don't move filtered source.
+ bool bFiltered = (bIsMove && pTransObj->HasFilteredRows());
+ if (!bFiltered)
+ {
+ if (pSourceDoc != pThisDoc && ((nFlags & SC_DROP_TABLE) ||
+ (!bIsLink && meDragInsertMode == INS_NONE)))
+ {
+ // Nothing. Either entire sheet to be dropped, or the one case
+ // where PasteFromClip() is to be called that handles a filtered
+ // destination itself. Drag-copy from another document without
+ // inserting cells.
+ }
+ else
+ // Don't copy or move to filtered destination.
+ bFiltered = ScViewUtil::HasFiltered( aDest, pThisDoc);
+ }
+
+ sal_Bool bDone = sal_False;
+
+ if (!bFiltered && pSourceDoc == pThisDoc)
+ {
+ if ( nFlags & SC_DROP_TABLE ) // whole sheet?
+ {
+ if ( pThisDoc->IsDocEditable() )
+ {
+ SCTAB nSrcTab = aSource.aStart.Tab();
+ pViewData->GetDocShell()->MoveTable( nSrcTab, nThisTab, !bIsMove, sal_True ); // with Undo
+ pView->SetTabNo( nThisTab, sal_True );
+ bDone = sal_True;
+ }
+ }
+ else // move/copy block
+ {
+ String aChartName;
+ if (pThisDoc->HasChartAtPoint( nThisTab, rLogicPos, &aChartName ))
+ {
+ String aRangeName;
+ aSource.Format( aRangeName, SCR_ABS_3D, pThisDoc );
+ SfxStringItem aNameItem( SID_CHART_NAME, aChartName );
+ SfxStringItem aRangeItem( SID_CHART_SOURCE, aRangeName );
+ sal_uInt16 nId = bIsMove ? SID_CHART_SOURCE : SID_CHART_ADDSOURCE;
+ pViewData->GetDispatcher().Execute( nId, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
+ &aRangeItem, &aNameItem, (void*) NULL );
+ bDone = sal_True;
+ }
+ else if ( pThisDoc->GetDPAtCursor( nDestPosX, nDestPosY, nThisTab ) )
+ {
+ // drop on DataPilot table: try to sort, fail if that isn't possible
+
+ ScAddress aDestPos( nDestPosX, nDestPosY, nThisTab );
+ if ( aDestPos != aSource.aStart )
+ bDone = pViewData->GetView()->DataPilotMove( aSource, aDestPos );
+ else
+ bDone = sal_True; // same position: nothing
+ }
+ else if ( nDestPosX != aSource.aStart.Col() || nDestPosY != aSource.aStart.Row() ||
+ nSourceTab != nThisTab )
+ {
+ String aUndo = ScGlobal::GetRscString( bIsMove ? STR_UNDO_MOVE : STR_UNDO_COPY );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+
+ bDone = sal_True;
+ if ( meDragInsertMode != INS_NONE )
+ {
+ // call with bApi = sal_True to avoid error messages in drop handler
+ bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ );
+ if ( bDone )
+ {
+ if ( nThisTab == nSourceTab )
+ {
+ if ( meDragInsertMode == INS_CELLSDOWN &&
+ nDestPosX == aSource.aStart.Col() && nDestPosY < aSource.aStart.Row() )
+ {
+ bDone = aSource.Move( 0, nSizeY, 0, pSourceDoc );
+ }
+ else if ( meDragInsertMode == INS_CELLSRIGHT &&
+ nDestPosY == aSource.aStart.Row() && nDestPosX < aSource.aStart.Col() )
+ {
+ bDone = aSource.Move( nSizeX, 0, 0, pSourceDoc );
+ }
+ }
+ pDocSh->UpdateOle( pViewData );
+ pView->CellContentChanged();
+ }
+ }
+
+ if ( bDone )
+ {
+ if ( bIsLink )
+ {
+ // call with bApi = sal_True to avoid error messages in drop handler
+ bDone = pView->LinkBlock( aSource, aDest.aStart, sal_True /*bApi*/ );
+ }
+ else
+ {
+ // call with bApi = sal_True to avoid error messages in drop handler
+ bDone = pView->MoveBlockTo( aSource, aDest.aStart, bIsMove, sal_True /*bRecord*/, sal_True /*bPaint*/, sal_True /*bApi*/ );
+ }
+ }
+
+ if ( bDone && meDragInsertMode != INS_NONE && bIsMove && nThisTab == nSourceTab )
+ {
+ DelCellCmd eCmd = DEL_NONE;
+ if ( meDragInsertMode == INS_CELLSDOWN )
+ {
+ eCmd = DEL_CELLSUP;
+ }
+ else if ( meDragInsertMode == INS_CELLSRIGHT )
+ {
+ eCmd = DEL_CELLSLEFT;
+ }
+
+ if ( ( eCmd == DEL_CELLSUP && nDestPosX == aSource.aStart.Col() ) ||
+ ( eCmd == DEL_CELLSLEFT && nDestPosY == aSource.aStart.Row() ) )
+ {
+ // call with bApi = sal_True to avoid error messages in drop handler
+ bDone = pDocSh->GetDocFunc().DeleteCells( aSource, NULL, eCmd, sal_True /*bRecord*/, sal_True /*bApi*/ );
+ if ( bDone )
+ {
+ if ( eCmd == DEL_CELLSUP && nDestPosY > aSource.aEnd.Row() )
+ {
+ bDone = aDest.Move( 0, -nSizeY, 0, pThisDoc );
+ }
+ else if ( eCmd == DEL_CELLSLEFT && nDestPosX > aSource.aEnd.Col() )
+ {
+ bDone = aDest.Move( -nSizeX, 0, 0, pThisDoc );
+ }
+ pDocSh->UpdateOle( pViewData );
+ pView->CellContentChanged();
+ }
+ }
+ }
+
+ if ( bDone )
+ {
+ pView->MarkRange( aDest, sal_False, sal_False );
+ pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
+ }
+
+ pDocSh->GetUndoManager()->LeaveListAction();
+
+ if (!bDone)
+ Sound::Beep(); // instead of error message in drop handler
+ }
+ else
+ bDone = sal_True; // nothing to do
+ }
+
+ if (bDone)
+ pTransObj->SetDragWasInternal(); // don't delete source in DragFinished
+ }
+ else if ( !bFiltered && pSourceDoc ) // between documents
+ {
+ if ( nFlags & SC_DROP_TABLE ) // copy/link sheets between documents
+ {
+ if ( pThisDoc->IsDocEditable() )
+ {
+ ScDocShell* pSrcShell = pTransObj->GetSourceDocShell();
+
+ SCTAB nTabs[MAXTABCOUNT];
+
+ ScMarkData aMark = pTransObj->GetSourceMarkData();
+ SCTAB nTabCount = pSourceDoc->GetTableCount();
+ SCTAB nTabSelCount = 0;
+
+ for(SCTAB i=0; i<nTabCount; i++)
+ {
+ if(aMark.GetTableSelect(i))
+ {
+ nTabs[nTabSelCount++]=i;
+ for(SCTAB j=i+1;j<nTabCount;j++)
+ {
+ if((!pSourceDoc->IsVisible(j))&&(pSourceDoc->IsScenario(j)))
+ {
+ nTabs[nTabSelCount++]=j;
+ i=j;
+ }
+ else break;
+ }
+ }
+ }
+
+ pView->ImportTables( pSrcShell,nTabSelCount, nTabs, bIsLink, nThisTab );
+ bDone = sal_True;
+ }
+ }
+ else if ( bIsLink )
+ {
+ // as in PasteDDE
+ // (external references might be used instead?)
+
+ SfxObjectShell* pSourceSh = pSourceDoc->GetDocumentShell();
+ DBG_ASSERT(pSourceSh, "drag document has no shell");
+ if (pSourceSh)
+ {
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_COPY );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+
+ bDone = sal_True;
+ if ( meDragInsertMode != INS_NONE )
+ {
+ // call with bApi = sal_True to avoid error messages in drop handler
+ bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ );
+ if ( bDone )
+ {
+ pDocSh->UpdateOle( pViewData );
+ pView->CellContentChanged();
+ }
+ }
+
+ if ( bDone )
+ {
+ String aApp = Application::GetAppName();
+ String aTopic = pSourceSh->GetTitle( SFX_TITLE_FULLNAME );
+ String aItem;
+ aSource.Format( aItem, SCA_VALID | SCA_TAB_3D, pSourceDoc );
+
+ // TODO: we could define ocQuote for "
+ const String aQuote( '"' );
+ const String& sSep = ScCompiler::GetNativeSymbol( ocSep);
+ String aFormula( '=' );
+ aFormula += ScCompiler::GetNativeSymbol( ocDde);
+ aFormula += ScCompiler::GetNativeSymbol( ocOpen);
+ aFormula += aQuote;
+ aFormula += aApp;
+ aFormula += aQuote;
+ aFormula += sSep;
+ aFormula += aQuote;
+ aFormula += aTopic;
+ aFormula += aQuote;
+ aFormula += sSep;
+ aFormula += aQuote;
+ aFormula += aItem;
+ aFormula += aQuote;
+ aFormula += ScCompiler::GetNativeSymbol( ocClose);
+
+ pView->DoneBlockMode();
+ pView->InitBlockMode( nDestPosX, nDestPosY, nThisTab );
+ pView->MarkCursor( nDestPosX + nSizeX - 1,
+ nDestPosY + nSizeY - 1, nThisTab );
+
+ pView->EnterMatrix( aFormula );
+
+ pView->MarkRange( aDest, sal_False, sal_False );
+ pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
+ }
+
+ pDocSh->GetUndoManager()->LeaveListAction();
+ }
+ }
+ else
+ {
+ //! HasSelectedBlockMatrixFragment without selected sheet?
+ //! or don't start dragging on a part of a matrix
+
+ String aUndo = ScGlobal::GetRscString( bIsMove ? STR_UNDO_MOVE : STR_UNDO_COPY );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+
+ bDone = sal_True;
+ if ( meDragInsertMode != INS_NONE )
+ {
+ // call with bApi = sal_True to avoid error messages in drop handler
+ bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ );
+ if ( bDone )
+ {
+ pDocSh->UpdateOle( pViewData );
+ pView->CellContentChanged();
+ }
+ }
+
+ if ( bDone )
+ {
+ pView->Unmark(); // before SetCursor, so CheckSelectionTransfer isn't called with a selection
+ pView->SetCursor( nDestPosX, nDestPosY );
+ bDone = pView->PasteFromClip( IDF_ALL, pTransObj->GetDocument() ); // clip-doc
+ if ( bDone )
+ {
+ pView->MarkRange( aDest, sal_False, sal_False );
+ pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
+ }
+ }
+
+ pDocSh->GetUndoManager()->LeaveListAction();
+
+ // no longer call ResetMark here - the inserted block has been selected
+ // and may have been copied to primary selection
+ }
+ }
+
+ sal_Int8 nRet = bDone ? nDndAction : DND_ACTION_NONE;
+ return nRet;
+}
+
+sal_Int8 ScGridWindow::ExecuteDrop( const ExecuteDropEvent& rEvt )
+{
+ DrawMarkDropObj( NULL ); // drawing layer
+
+ ScModule* pScMod = SC_MOD();
+ const ScDragData& rData = pScMod->GetDragData();
+ if (rData.pCellTransfer)
+ return ExecutePrivateDrop( rEvt );
+
+ Point aPos = rEvt.maPosPixel;
+
+ if ( rData.aLinkDoc.Len() )
+ {
+ // try to insert a link
+
+ sal_Bool bOk = sal_True;
+ String aThisName;
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ if (pDocSh && pDocSh->HasName())
+ aThisName = pDocSh->GetMedium()->GetName();
+
+ if ( rData.aLinkDoc == aThisName ) // error - no link within a document
+ bOk = sal_False;
+ else
+ {
+ ScViewFunc* pView = pViewData->GetView();
+ if ( rData.aLinkTable.Len() )
+ pView->InsertTableLink( rData.aLinkDoc, EMPTY_STRING, EMPTY_STRING,
+ rData.aLinkTable );
+ else if ( rData.aLinkArea.Len() )
+ {
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+ pView->MoveCursorAbs( nPosX, nPosY, SC_FOLLOW_NONE, sal_False, sal_False );
+
+ pView->InsertAreaLink( rData.aLinkDoc, EMPTY_STRING, EMPTY_STRING,
+ rData.aLinkArea, 0 );
+ }
+ else
+ {
+ DBG_ERROR("drop with link: no sheet nor area");
+ bOk = sal_False;
+ }
+ }
+
+ return bOk ? rEvt.mnAction : DND_ACTION_NONE; // don't try anything else
+ }
+
+ Point aLogicPos = PixelToLogic(aPos);
+
+ if (rData.pDrawTransfer)
+ {
+ sal_uInt16 nFlags = rData.pDrawTransfer->GetDragSourceFlags();
+
+ sal_Bool bIsNavi = ( nFlags & SC_DROP_NAVIGATOR ) != 0;
+ sal_Bool bIsMove = ( rEvt.mnAction == DND_ACTION_MOVE && !bIsNavi );
+
+ bPasteIsMove = bIsMove;
+
+ pViewData->GetView()->PasteDraw( aLogicPos, rData.pDrawTransfer->GetModel() );
+
+ if (bPasteIsMove)
+ rData.pDrawTransfer->SetDragWasInternal();
+ bPasteIsMove = sal_False;
+
+ return rEvt.mnAction;
+ }
+
+
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+
+ if (rData.aJumpTarget.Len())
+ {
+ // internal bookmark (from Navigator)
+ // bookmark clipboard formats are in PasteScDataObject
+
+ if ( !rData.pJumpLocalDoc || rData.pJumpLocalDoc == pViewData->GetDocument() )
+ {
+ pViewData->GetViewShell()->InsertBookmark( rData.aJumpText, rData.aJumpTarget,
+ nPosX, nPosY );
+ return rEvt.mnAction;
+ }
+ }
+
+ sal_Bool bIsLink = ( rEvt.mnAction == DND_ACTION_LINK );
+
+ ScDocument* pThisDoc = pViewData->GetDocument();
+ SdrObject* pHitObj = pThisDoc->GetObjectAtPoint( pViewData->GetTabNo(), PixelToLogic(aPos) );
+ if ( pHitObj && bIsLink )
+ {
+ // dropped on drawing object
+ // PasteOnDrawObject checks for valid formats
+ if ( pViewData->GetView()->PasteOnDrawObject( rEvt.maDropEvent.Transferable, pHitObj, sal_True ) )
+ return rEvt.mnAction;
+ }
+
+ sal_Bool bDone = sal_False;
+
+ sal_uLong nFormatId = bIsLink ?
+ lcl_GetDropLinkId( rEvt.maDropEvent.Transferable ) :
+ lcl_GetDropFormatId( rEvt.maDropEvent.Transferable );
+ if ( nFormatId )
+ {
+ pScMod->SetInExecuteDrop( sal_True ); // #i28468# prevent error messages from PasteDataFormat
+ bPasteIsDrop = sal_True;
+ bDone = pViewData->GetView()->PasteDataFormat(
+ nFormatId, rEvt.maDropEvent.Transferable, nPosX, nPosY, &aLogicPos, bIsLink );
+ bPasteIsDrop = sal_False;
+ pScMod->SetInExecuteDrop( sal_False );
+ }
+
+ sal_Int8 nRet = bDone ? rEvt.mnAction : DND_ACTION_NONE;
+ return nRet;
+}
+
+//--------------------------------------------------------
+
+void ScGridWindow::PasteSelection( const Point& rPosPixel )
+{
+ Point aLogicPos = PixelToLogic( rPosPixel );
+
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( rPosPixel.X(), rPosPixel.Y(), eWhich, nPosX, nPosY );
+
+ ScSelectionTransferObj* pOwnSelection = SC_MOD()->GetSelectionTransfer();
+ if ( pOwnSelection )
+ {
+ // within Calc
+
+ ScTransferObj* pCellTransfer = pOwnSelection->GetCellData();
+ if ( pCellTransfer )
+ {
+ // keep a reference to the data in case the selection is changed during paste
+ uno::Reference<datatransfer::XTransferable> xRef( pCellTransfer );
+ DropTransferObj( pCellTransfer, nPosX, nPosY, aLogicPos, DND_ACTION_COPY );
+ }
+ else
+ {
+ ScDrawTransferObj* pDrawTransfer = pOwnSelection->GetDrawData();
+ if ( pDrawTransfer )
+ {
+ // keep a reference to the data in case the selection is changed during paste
+ uno::Reference<datatransfer::XTransferable> xRef( pDrawTransfer );
+
+ // #96821# bSameDocClipboard argument for PasteDraw is needed
+ // because only DragData is checked directly inside PasteDraw
+ pViewData->GetView()->PasteDraw( aLogicPos, pDrawTransfer->GetModel(), sal_False,
+ pDrawTransfer->GetSourceDocID() == pViewData->GetDocument()->GetDocumentID() );
+ }
+ }
+ }
+ else
+ {
+ // get selection from system
+
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSelection( this ) );
+ uno::Reference<datatransfer::XTransferable> xTransferable = aDataHelper.GetTransferable();
+ if ( xTransferable.is() )
+ {
+ sal_uLong nFormatId = lcl_GetDropFormatId( xTransferable, true );
+ if ( nFormatId )
+ {
+ bPasteIsDrop = sal_True;
+ pViewData->GetView()->PasteDataFormat( nFormatId, xTransferable, nPosX, nPosY, &aLogicPos );
+ bPasteIsDrop = sal_False;
+ }
+ }
+ }
+}
+
+//--------------------------------------------------------
+
+void ScGridWindow::UpdateEditViewPos()
+{
+ if (pViewData->HasEditView(eWhich))
+ {
+ EditView* pView;
+ SCCOL nCol;
+ SCROW nRow;
+ pViewData->GetEditView( eWhich, pView, nCol, nRow );
+ SCCOL nEndCol = pViewData->GetEditEndCol();
+ SCROW nEndRow = pViewData->GetEditEndRow();
+
+ // hide EditView?
+
+ sal_Bool bHide = ( nEndCol<pViewData->GetPosX(eHWhich) || nEndRow<pViewData->GetPosY(eVWhich) );
+ if ( SC_MOD()->IsFormulaMode() )
+ if ( pViewData->GetTabNo() != pViewData->GetRefTabNo() )
+ bHide = sal_True;
+
+ if (bHide)
+ {
+ Rectangle aRect = pView->GetOutputArea();
+ long nHeight = aRect.Bottom() - aRect.Top();
+ aRect.Top() = PixelToLogic(GetOutputSizePixel(), pViewData->GetLogicMode()).
+ Height() * 2;
+ aRect.Bottom() = aRect.Top() + nHeight;
+ pView->SetOutputArea( aRect );
+ pView->HideCursor();
+ }
+ else
+ {
+ // bForceToTop = sal_True for editing
+ Rectangle aPixRect = pViewData->GetEditArea( eWhich, nCol, nRow, this, NULL, sal_True );
+ Point aScrPos = PixelToLogic( aPixRect.TopLeft(), pViewData->GetLogicMode() );
+
+ Rectangle aRect = pView->GetOutputArea();
+ aRect.SetPos( aScrPos );
+ pView->SetOutputArea( aRect );
+ pView->ShowCursor();
+ }
+ }
+}
+
+void ScGridWindow::ScrollPixel( long nDifX, long nDifY )
+{
+ ClickExtern();
+ HideNoteMarker();
+
+ bIsInScroll = sal_True;
+ //sal_Bool bXor=DrawBeforeScroll();
+
+ SetMapMode(MAP_PIXEL);
+ Scroll( nDifX, nDifY, SCROLL_CHILDREN );
+ SetMapMode( GetDrawMapMode() ); // verschobenen MapMode erzeugen
+
+ UpdateEditViewPos();
+
+ DrawAfterScroll(); //bXor);
+ bIsInScroll = sal_False;
+}
+
+// Formeln neu zeichnen -------------------------------------------------
+
+void ScGridWindow::UpdateFormulas()
+{
+ if (pViewData->GetView()->IsMinimized())
+ return;
+
+ if ( nPaintCount )
+ {
+ // nicht anfangen, verschachtelt zu painten
+ // (dann wuerde zumindest der MapMode nicht mehr stimmen)
+
+ bNeedsRepaint = sal_True; // -> am Ende vom Paint nochmal Invalidate auf alles
+ aRepaintPixel = Rectangle(); // alles
+ return;
+ }
+
+ SCCOL nX1 = pViewData->GetPosX( eHWhich );
+ SCROW nY1 = pViewData->GetPosY( eVWhich );
+ SCCOL nX2 = nX1 + pViewData->VisibleCellsX( eHWhich );
+ SCROW nY2 = nY1 + pViewData->VisibleCellsY( eVWhich );
+
+ if (nX2 > MAXCOL) nX2 = MAXCOL;
+ if (nY2 > MAXROW) nY2 = MAXROW;
+
+ // Draw( nX1, nY1, nX2, nY2, SC_UPDATE_CHANGED );
+
+ // don't draw directly - instead use OutputData to find changed area and invalidate
+
+ SCROW nPosY = nY1;
+
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+
+ pDoc->ExtendHidden( nX1, nY1, nX2, nY2, nTab );
+
+ Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich );
+ long nMirrorWidth = GetSizePixel().Width();
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ // unused variable long nLayoutSign = bLayoutRTL ? -1 : 1;
+ if ( bLayoutRTL )
+ {
+ long nEndPixel = pViewData->GetScrPos( nX2+1, nPosY, eWhich ).X();
+ nMirrorWidth = aScrPos.X() - nEndPixel;
+ aScrPos.X() = nEndPixel + 1;
+ }
+
+ long nScrX = aScrPos.X();
+ long nScrY = aScrPos.Y();
+
+ double nPPTX = pViewData->GetPPTX();
+ double nPPTY = pViewData->GetPPTY();
+
+ ScTableInfo aTabInfo;
+ pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab, nPPTX, nPPTY, sal_False, sal_False );
+
+ Fraction aZoomX = pViewData->GetZoomX();
+ Fraction aZoomY = pViewData->GetZoomY();
+ ScOutputData aOutputData( this, OUTTYPE_WINDOW, aTabInfo, pDoc, nTab,
+ nScrX, nScrY, nX1, nY1, nX2, nY2, nPPTX, nPPTY,
+ &aZoomX, &aZoomY );
+ aOutputData.SetMirrorWidth( nMirrorWidth );
+
+ aOutputData.FindChanged();
+
+ PolyPolygon aChangedPoly( aOutputData.GetChangedArea() ); // logic (PixelToLogic)
+ if ( aChangedPoly.Count() )
+ {
+ Invalidate( aChangedPoly );
+ }
+
+ CheckNeedsRepaint(); // #i90362# used to be called via Draw() - still needed here
+}
+
+void ScGridWindow::UpdateAutoFillMark(sal_Bool bMarked, const ScRange& rMarkRange)
+{
+ if ( bMarked != bAutoMarkVisible || ( bMarked && rMarkRange.aEnd != aAutoMarkPos ) )
+ {
+ HideCursor();
+ bAutoMarkVisible = bMarked;
+ if ( bMarked )
+ aAutoMarkPos = rMarkRange.aEnd;
+ ShowCursor();
+
+ UpdateAutoFillOverlay();
+ }
+}
+
+void ScGridWindow::UpdateListValPos( sal_Bool bVisible, const ScAddress& rPos )
+{
+ sal_Bool bOldButton = bListValButton;
+ ScAddress aOldPos = aListValPos;
+
+ bListValButton = bVisible;
+ aListValPos = rPos;
+
+ if ( bListValButton )
+ {
+ if ( !bOldButton || aListValPos != aOldPos )
+ {
+ // paint area of new button
+ Invalidate( PixelToLogic( GetListValButtonRect( aListValPos ) ) );
+ }
+ }
+ if ( bOldButton )
+ {
+ if ( !bListValButton || aListValPos != aOldPos )
+ {
+ // paint area of old button
+ Invalidate( PixelToLogic( GetListValButtonRect( aOldPos ) ) );
+ }
+ }
+}
+
+void ScGridWindow::HideCursor()
+{
+ ++nCursorHideCount;
+ if (nCursorHideCount==1)
+ {
+ DrawCursor();
+ DrawAutoFillMark();
+ }
+}
+
+void ScGridWindow::ShowCursor()
+{
+ if (nCursorHideCount==0)
+ {
+ DBG_ERROR("zuviel ShowCursor");
+ return;
+ }
+
+ if (nCursorHideCount==1)
+ {
+ // #i57745# Draw the cursor before setting the variable, in case the
+ // GetSizePixel call from drawing causes a repaint (resize handler is called)
+ DrawAutoFillMark();
+ DrawCursor();
+ }
+
+ --nCursorHideCount;
+}
+
+void __EXPORT ScGridWindow::GetFocus()
+{
+ ScTabViewShell* pViewShell = pViewData->GetViewShell();
+ pViewShell->GotFocus();
+ pViewShell->SetFormShellAtTop( sal_False ); // focus in GridWindow -> FormShell no longer on top
+
+ if (pViewShell->HasAccessibilityObjects())
+ pViewShell->BroadcastAccessibility(ScAccGridWinFocusGotHint(eWhich, GetAccessible()));
+
+
+ if ( !SC_MOD()->IsFormulaMode() )
+ {
+ pViewShell->UpdateInputHandler();
+// StopMarking(); // falls Dialog (Fehler), weil dann kein ButtonUp
+ // MO: nur wenn nicht im RefInput-Modus
+ // -> GetFocus/MouseButtonDown-Reihenfolge
+ // auf dem Mac
+ }
+
+ Window::GetFocus();
+}
+
+void __EXPORT ScGridWindow::LoseFocus()
+{
+ ScTabViewShell* pViewShell = pViewData->GetViewShell();
+ pViewShell->LostFocus();
+
+ if (pViewShell->HasAccessibilityObjects())
+ pViewShell->BroadcastAccessibility(ScAccGridWinFocusLostHint(eWhich, GetAccessible()));
+
+ Window::LoseFocus();
+}
+
+Point ScGridWindow::GetMousePosPixel() const { return aCurMousePos; }
+
+//------------------------------------------------------------------------
+
+sal_Bool ScGridWindow::HitRangeFinder( const Point& rMouse, sal_Bool& rCorner,
+ sal_uInt16* pIndex, SCsCOL* pAddX, SCsROW* pAddY )
+{
+ sal_Bool bFound = sal_False;
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pViewData->GetViewShell() );
+ if (pHdl)
+ {
+ ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
+ if ( pRangeFinder && !pRangeFinder->IsHidden() &&
+ pRangeFinder->GetDocName() == pViewData->GetDocShell()->GetTitle() )
+ {
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( rMouse.X(), rMouse.Y(), eWhich, nPosX, nPosY );
+ // zusammengefasste (einzeln/Bereich) ???
+ ScAddress aAddr( nPosX, nPosY, nTab );
+
+// Point aNext = pViewData->GetScrPos( nPosX+1, nPosY+1, eWhich );
+
+ Point aNext = pViewData->GetScrPos( nPosX, nPosY, eWhich, sal_True );
+ long nSizeXPix;
+ long nSizeYPix;
+ pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeXPix, nSizeYPix );
+ aNext.X() += nSizeXPix * nLayoutSign;
+ aNext.Y() += nSizeYPix;
+
+ sal_Bool bCornerHor;
+ if ( bLayoutRTL )
+ bCornerHor = ( rMouse.X() >= aNext.X() && rMouse.X() <= aNext.X() + 8 );
+ else
+ bCornerHor = ( rMouse.X() >= aNext.X() - 8 && rMouse.X() <= aNext.X() );
+
+ sal_Bool bCellCorner = ( bCornerHor &&
+ rMouse.Y() >= aNext.Y() - 8 && rMouse.Y() <= aNext.Y() );
+ // corner is hit only if the mouse is within the cell
+
+ sal_uInt16 nCount = (sal_uInt16)pRangeFinder->Count();
+ for (sal_uInt16 i=nCount; i;)
+ {
+ // rueckwaerts suchen, damit der zuletzt gepaintete Rahmen gefunden wird
+ --i;
+ ScRangeFindData* pData = pRangeFinder->GetObject(i);
+ if ( pData && pData->aRef.In(aAddr) )
+ {
+ if (pIndex) *pIndex = i;
+ if (pAddX) *pAddX = nPosX - pData->aRef.aStart.Col();
+ if (pAddY) *pAddY = nPosY - pData->aRef.aStart.Row();
+ bFound = sal_True;
+ rCorner = ( bCellCorner && aAddr == pData->aRef.aEnd );
+ break;
+ }
+ }
+ }
+ }
+ return bFound;
+}
+
+#define SCE_TOP 1
+#define SCE_BOTTOM 2
+#define SCE_LEFT 4
+#define SCE_RIGHT 8
+#define SCE_ALL 15
+
+void lcl_PaintOneRange( ScDocShell* pDocSh, const ScRange& rRange, sal_uInt16 nEdges )
+{
+ // der Range ist immer richtigherum
+
+ SCCOL nCol1 = rRange.aStart.Col();
+ SCROW nRow1 = rRange.aStart.Row();
+ SCTAB nTab1 = rRange.aStart.Tab();
+ SCCOL nCol2 = rRange.aEnd.Col();
+ SCROW nRow2 = rRange.aEnd.Row();
+ SCTAB nTab2 = rRange.aEnd.Tab();
+ sal_Bool bHiddenEdge = sal_False;
+ SCROW nTmp;
+
+ ScDocument* pDoc = pDocSh->GetDocument();
+ while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab1) )
+ {
+ --nCol1;
+ bHiddenEdge = sal_True;
+ }
+ while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab1) )
+ {
+ ++nCol2;
+ bHiddenEdge = sal_True;
+ }
+ nTmp = pDoc->FirstVisibleRow(0, nRow1, nTab1);
+ if (!ValidRow(nTmp))
+ nTmp = 0;
+ if (nTmp < nRow1)
+ {
+ nRow1 = nTmp;
+ bHiddenEdge = sal_True;
+ }
+ nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab1);
+ if (!ValidRow(nTmp))
+ nTmp = MAXROW;
+ if (nTmp > nRow2)
+ {
+ nRow2 = nTmp;
+ bHiddenEdge = sal_True;
+ }
+
+ if ( nCol2 > nCol1 + 1 && nRow2 > nRow1 + 1 && !bHiddenEdge )
+ {
+ // nur an den Raendern entlang
+ // (die Ecken werden evtl. zweimal getroffen)
+
+ if ( nEdges & SCE_TOP )
+ pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol2, nRow1, nTab2, PAINT_MARKS );
+ if ( nEdges & SCE_LEFT )
+ pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol1, nRow2, nTab2, PAINT_MARKS );
+ if ( nEdges & SCE_RIGHT )
+ pDocSh->PostPaint( nCol2, nRow1, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS );
+ if ( nEdges & SCE_BOTTOM )
+ pDocSh->PostPaint( nCol1, nRow2, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS );
+ }
+ else // everything in one call
+ pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS );
+}
+
+void lcl_PaintRefChanged( ScDocShell* pDocSh, const ScRange& rOldUn, const ScRange& rNewUn )
+{
+ // Repaint fuer die Teile des Rahmens in Old, die bei New nicht mehr da sind
+
+ ScRange aOld = rOldUn;
+ ScRange aNew = rNewUn;
+ aOld.Justify();
+ aNew.Justify();
+
+ if ( aOld.aStart == aOld.aEnd ) //! Tab ignorieren?
+ pDocSh->GetDocument()->ExtendMerge(aOld);
+ if ( aNew.aStart == aNew.aEnd ) //! Tab ignorieren?
+ pDocSh->GetDocument()->ExtendMerge(aNew);
+
+ SCCOL nOldCol1 = aOld.aStart.Col();
+ SCROW nOldRow1 = aOld.aStart.Row();
+ SCCOL nOldCol2 = aOld.aEnd.Col();
+ SCROW nOldRow2 = aOld.aEnd.Row();
+ SCCOL nNewCol1 = aNew.aStart.Col();
+ SCROW nNewRow1 = aNew.aStart.Row();
+ SCCOL nNewCol2 = aNew.aEnd.Col();
+ SCROW nNewRow2 = aNew.aEnd.Row();
+ SCTAB nTab1 = aOld.aStart.Tab(); // Tab aendert sich nicht
+ SCTAB nTab2 = aOld.aEnd.Tab();
+
+ if ( nNewRow2 < nOldRow1 || nNewRow1 > nOldRow2 ||
+ nNewCol2 < nOldCol1 || nNewCol1 > nOldCol2 ||
+ ( nNewCol1 != nOldCol1 && nNewRow1 != nOldRow1 &&
+ nNewCol2 != nOldCol2 && nNewRow2 != nOldRow2 ) )
+ {
+ // komplett weggeschoben oder alle Seiten veraendert
+ // (Abfrage <= statt < geht schief bei einzelnen Zeilen/Spalten)
+
+ lcl_PaintOneRange( pDocSh, aOld, SCE_ALL );
+ }
+ else // alle vier Kanten einzeln testen
+ {
+ // oberer Teil
+ if ( nNewRow1 < nOldRow1 ) // nur obere Linie loeschen
+ lcl_PaintOneRange( pDocSh, ScRange(
+ nOldCol1, nOldRow1, nTab1, nOldCol2, nOldRow1, nTab2 ), SCE_ALL );
+ else if ( nNewRow1 > nOldRow1 ) // den Teil, der oben wegkommt
+ lcl_PaintOneRange( pDocSh, ScRange(
+ nOldCol1, nOldRow1, nTab1, nOldCol2, nNewRow1-1, nTab2 ),
+ SCE_ALL &~ SCE_BOTTOM );
+
+ // unterer Teil
+ if ( nNewRow2 > nOldRow2 ) // nur untere Linie loeschen
+ lcl_PaintOneRange( pDocSh, ScRange(
+ nOldCol1, nOldRow2, nTab1, nOldCol2, nOldRow2, nTab2 ), SCE_ALL );
+ else if ( nNewRow2 < nOldRow2 ) // den Teil, der unten wegkommt
+ lcl_PaintOneRange( pDocSh, ScRange(
+ nOldCol1, nNewRow2+1, nTab1, nOldCol2, nOldRow2, nTab2 ),
+ SCE_ALL &~ SCE_TOP );
+
+ // linker Teil
+ if ( nNewCol1 < nOldCol1 ) // nur linke Linie loeschen
+ lcl_PaintOneRange( pDocSh, ScRange(
+ nOldCol1, nOldRow1, nTab1, nOldCol1, nOldRow2, nTab2 ), SCE_ALL );
+ else if ( nNewCol1 > nOldCol1 ) // den Teil, der links wegkommt
+ lcl_PaintOneRange( pDocSh, ScRange(
+ nOldCol1, nOldRow1, nTab1, nNewCol1-1, nOldRow2, nTab2 ),
+ SCE_ALL &~ SCE_RIGHT );
+
+ // rechter Teil
+ if ( nNewCol2 > nOldCol2 ) // nur rechte Linie loeschen
+ lcl_PaintOneRange( pDocSh, ScRange(
+ nOldCol2, nOldRow1, nTab1, nOldCol2, nOldRow2, nTab2 ), SCE_ALL );
+ else if ( nNewCol2 < nOldCol2 ) // den Teil, der rechts wegkommt
+ lcl_PaintOneRange( pDocSh, ScRange(
+ nNewCol2+1, nOldRow1, nTab1, nOldCol2, nOldRow2, nTab2 ),
+ SCE_ALL &~ SCE_LEFT );
+ }
+}
+
+void ScGridWindow::RFMouseMove( const MouseEvent& rMEvt, sal_Bool bUp )
+{
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pViewData->GetViewShell() );
+ if (!pHdl)
+ return;
+ ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
+ if (!pRangeFinder || nRFIndex >= pRangeFinder->Count())
+ return;
+ ScRangeFindData* pData = pRangeFinder->GetObject( nRFIndex );
+ if (!pData)
+ return;
+
+ // Mauszeiger
+
+ if (bRFSize)
+ SetPointer( Pointer( POINTER_CROSS ) );
+ else
+ SetPointer( Pointer( POINTER_HAND ) );
+
+ // Scrolling
+
+ sal_Bool bTimer = sal_False;
+ Point aPos = rMEvt.GetPosPixel();
+ SCsCOL nDx = 0;
+ SCsROW nDy = 0;
+ if ( aPos.X() < 0 ) nDx = -1;
+ if ( aPos.Y() < 0 ) nDy = -1;
+ Size aSize = GetOutputSizePixel();
+ if ( aPos.X() >= aSize.Width() )
+ nDx = 1;
+ if ( aPos.Y() >= aSize.Height() )
+ nDy = 1;
+ if ( nDx != 0 || nDy != 0 )
+ {
+ if ( nDx != 0) pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
+ if ( nDy != 0 ) pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );
+ bTimer = sal_True;
+ }
+
+ // Umschalten bei Fixierung (damit Scrolling funktioniert)
+
+ if ( eWhich == pViewData->GetActivePart() ) //??
+ {
+ if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX )
+ if ( nDx > 0 )
+ {
+ if ( eWhich == SC_SPLIT_TOPLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT );
+ else if ( eWhich == SC_SPLIT_BOTTOMLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT );
+ }
+
+ if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX )
+ if ( nDy > 0 )
+ {
+ if ( eWhich == SC_SPLIT_TOPLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT );
+ else if ( eWhich == SC_SPLIT_TOPRIGHT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT );
+ }
+ }
+
+ // Verschieben
+
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+
+ ScRange aOld = pData->aRef;
+ ScRange aNew = aOld;
+ if ( bRFSize )
+ {
+ aNew.aEnd.SetCol((SCCOL)nPosX);
+ aNew.aEnd.SetRow((SCROW)nPosY);
+ }
+ else
+ {
+ long nStartX = nPosX - nRFAddX;
+ if ( nStartX < 0 ) nStartX = 0;
+ long nStartY = nPosY - nRFAddY;
+ if ( nStartY < 0 ) nStartY = 0;
+ long nEndX = nStartX + aOld.aEnd.Col() - aOld.aStart.Col();
+ if ( nEndX > MAXCOL )
+ {
+ nStartX -= ( nEndX - MAXROW );
+ nEndX = MAXCOL;
+ }
+ long nEndY = nStartY + aOld.aEnd.Row() - aOld.aStart.Row();
+ if ( nEndY > MAXROW )
+ {
+ nStartY -= ( nEndY - MAXROW );
+ nEndY = MAXROW;
+ }
+
+ aNew.aStart.SetCol((SCCOL)nStartX);
+ aNew.aStart.SetRow((SCROW)nStartY);
+ aNew.aEnd.SetCol((SCCOL)nEndX);
+ aNew.aEnd.SetRow((SCROW)nEndY);
+ }
+
+ if ( bUp )
+ aNew.Justify(); // beim ButtonUp wieder richtigherum
+
+ if ( aNew != aOld )
+ {
+ pHdl->UpdateRange( nRFIndex, aNew );
+
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+
+ // nur das neuzeichnen, was sich veraendert hat...
+ lcl_PaintRefChanged( pDocSh, aOld, aNew );
+
+ // neuen Rahmen nur drueberzeichnen (synchron)
+ pDocSh->Broadcast( ScIndexHint( SC_HINT_SHOWRANGEFINDER, nRFIndex ) );
+
+ Update(); // was man bewegt, will man auch sofort sehen
+ }
+
+ // Timer fuer Scrolling
+
+ if (bTimer)
+ pViewData->GetView()->SetTimer( this, rMEvt ); // Event wiederholen
+ else
+ pViewData->GetView()->ResetTimer();
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool ScGridWindow::GetEditUrl( const Point& rPos,
+ String* pName, String* pUrl, String* pTarget )
+{
+ return GetEditUrlOrError( sal_False, rPos, pName, pUrl, pTarget );
+}
+
+sal_Bool ScGridWindow::GetEditUrlOrError( sal_Bool bSpellErr, const Point& rPos,
+ String* pName, String* pUrl, String* pTarget )
+{
+ //! nPosX/Y mit uebergeben?
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( rPos.X(), rPos.Y(), eWhich, nPosX, nPosY );
+
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScBaseCell* pCell = NULL;
+
+ sal_Bool bFound = lcl_GetHyperlinkCell( pDoc, nPosX, nPosY, nTab, pCell );
+ if( !bFound )
+ return sal_False;
+
+ ScHideTextCursor aHideCursor( pViewData, eWhich ); // before GetEditArea (MapMode is changed)
+
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nPosX, nPosY, nTab );
+ // bForceToTop = sal_False, use the cell's real position
+ Rectangle aEditRect = pViewData->GetEditArea( eWhich, nPosX, nPosY, this, pPattern, sal_False );
+ if (rPos.Y() < aEditRect.Top())
+ return sal_False;
+
+ // vertikal kann (noch) nicht angeklickt werden:
+
+ if (pPattern->GetCellOrientation() != SVX_ORIENTATION_STANDARD)
+ return sal_False;
+
+ sal_Bool bBreak = ((SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue() ||
+ ((SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->
+ GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_BLOCK);
+ SvxCellHorJustify eHorJust = (SvxCellHorJustify)((SvxHorJustifyItem&)pPattern->
+ GetItem(ATTR_HOR_JUSTIFY)).GetValue();
+
+ // EditEngine
+
+ ScFieldEditEngine aEngine( pDoc->GetEditPool() );
+ ScSizeDeviceProvider aProv(pDocSh);
+ aEngine.SetRefDevice( aProv.GetDevice() );
+ aEngine.SetRefMapMode( MAP_100TH_MM );
+ SfxItemSet aDefault( aEngine.GetEmptyItemSet() );
+ pPattern->FillEditItemSet( &aDefault );
+ SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
+ switch (eHorJust)
+ {
+ case SVX_HOR_JUSTIFY_LEFT:
+ case SVX_HOR_JUSTIFY_REPEAT: // nicht implementiert
+ case SVX_HOR_JUSTIFY_STANDARD: // always Text if an EditCell type
+ eSvxAdjust = SVX_ADJUST_LEFT;
+ break;
+ case SVX_HOR_JUSTIFY_RIGHT:
+ eSvxAdjust = SVX_ADJUST_RIGHT;
+ break;
+ case SVX_HOR_JUSTIFY_CENTER:
+ eSvxAdjust = SVX_ADJUST_CENTER;
+ break;
+ case SVX_HOR_JUSTIFY_BLOCK:
+ eSvxAdjust = SVX_ADJUST_BLOCK;
+ break;
+ }
+ aDefault.Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
+ aEngine.SetDefaults( aDefault );
+ if (bSpellErr)
+ aEngine.SetControlWord( aEngine.GetControlWord() | EE_CNTRL_ONLINESPELLING );
+
+ MapMode aEditMode = pViewData->GetLogicMode(eWhich); // ohne Drawing-Skalierung
+ Rectangle aLogicEdit = PixelToLogic( aEditRect, aEditMode );
+ long nThisColLogic = aLogicEdit.Right() - aLogicEdit.Left() + 1;
+ Size aPaperSize = Size( 1000000, 1000000 );
+ if(pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ long nSizeX = 0;
+ long nSizeY = 0;
+ pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeX, nSizeY );
+ aPaperSize = Size(nSizeX, nSizeY );
+ aPaperSize = PixelToLogic(aPaperSize);
+ }
+
+ if (bBreak)
+ aPaperSize.Width() = nThisColLogic;
+ aEngine.SetPaperSize( aPaperSize );
+
+ ::std::auto_ptr< EditTextObject > pTextObj;
+ const EditTextObject* pData;
+ if(pCell->GetCellType() == CELLTYPE_EDIT)
+ {
+ ((ScEditCell*)pCell)->GetData(pData);
+ if (pData)
+ aEngine.SetText(*pData);
+ }
+ else // HyperLink Formula cell
+ {
+ pTextObj.reset((static_cast<ScFormulaCell*>(pCell))->CreateURLObject());
+ if (pTextObj.get())
+ aEngine.SetText(*pTextObj);
+ }
+
+ long nStartX = aLogicEdit.Left();
+
+ long nTextWidth = aEngine.CalcTextWidth();
+ long nTextHeight = aEngine.GetTextHeight();
+ if ( nTextWidth < nThisColLogic )
+ {
+ if (eHorJust == SVX_HOR_JUSTIFY_RIGHT)
+ nStartX += nThisColLogic - nTextWidth;
+ else if (eHorJust == SVX_HOR_JUSTIFY_CENTER)
+ nStartX += (nThisColLogic - nTextWidth) / 2;
+ }
+
+ aLogicEdit.Left() = nStartX;
+ if (!bBreak)
+ aLogicEdit.Right() = nStartX + nTextWidth;
+
+ // There is one glitch when dealing with a hyperlink cell and
+ // the cell content is NUMERIC. This defaults to right aligned and
+ // we need to adjust accordingly.
+ if(pCell->GetCellType() == CELLTYPE_FORMULA &&
+ static_cast<ScFormulaCell*>(pCell)->IsValue() &&
+ eHorJust == SVX_HOR_JUSTIFY_STANDARD)
+ {
+ aLogicEdit.Right() = aLogicEdit.Left() + nThisColLogic - 1;
+ aLogicEdit.Left() = aLogicEdit.Right() - nTextWidth;
+ }
+ aLogicEdit.Bottom() = aLogicEdit.Top() + nTextHeight;
+
+
+ Point aLogicClick = PixelToLogic(rPos,aEditMode);
+ if ( aLogicEdit.IsInside(aLogicClick) )
+ {
+// aEngine.SetUpdateMode(sal_False);
+ EditView aTempView( &aEngine, this );
+ aTempView.SetOutputArea( aLogicEdit );
+
+ sal_Bool bRet = sal_False;
+ MapMode aOld = GetMapMode();
+ SetMapMode(aEditMode); // kein return mehr
+
+ if (bSpellErr) // Spelling-Fehler suchen
+ {
+ bRet = aTempView.IsWrongSpelledWordAtPos( rPos );
+ if ( bRet )
+ pViewData->GetView()->SetCursor( nPosX, nPosY ); // Cursor setzen
+ }
+ else // URL suchen
+ {
+ const SvxFieldItem* pFieldItem = aTempView.GetFieldUnderMousePointer();
+
+ if (pFieldItem)
+ {
+ const SvxFieldData* pField = pFieldItem->GetField();
+ if ( pField && pField->ISA(SvxURLField) )
+ {
+ if ( pName || pUrl || pTarget )
+ {
+ const SvxURLField* pURLField = (const SvxURLField*)pField;
+ if (pName)
+ *pName = pURLField->GetRepresentation();
+ if (pUrl)
+ *pUrl = pURLField->GetURL();
+ if (pTarget)
+ *pTarget = pURLField->GetTargetFrame();
+ }
+ bRet = sal_True;
+ }
+ }
+ }
+
+ SetMapMode(aOld);
+
+ // text cursor is restored in ScHideTextCursor dtor
+
+ return bRet;
+ }
+ return sal_False;
+}
+
+sal_Bool ScGridWindow::HasScenarioButton( const Point& rPosPixel, ScRange& rScenRange )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ if ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) )
+ {
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ Size aButSize = pViewData->GetScenButSize();
+ long nBWidth = aButSize.Width();
+ if (!nBWidth)
+ return sal_False; // noch kein Button gezeichnet -> da ist auch keiner
+ long nBHeight = aButSize.Height();
+ long nHSpace = (long)( SC_SCENARIO_HSPACE * pViewData->GetPPTX() );
+
+ //! Ranges an der Table cachen!!!!
+
+ ScMarkData aMarks;
+ for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
+ pDoc->MarkScenario( i, nTab, aMarks, sal_False, SC_SCENARIO_SHOWFRAME );
+ ScRangeList aRanges;
+ aMarks.FillRangeListWithMarks( &aRanges, sal_False );
+
+
+ sal_uLong nRangeCount = aRanges.Count();
+ for (sal_uLong j=0; j<nRangeCount; j++)
+ {
+ ScRange aRange = *aRanges.GetObject(j);
+ // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
+ // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
+ pDoc->ExtendTotalMerge( aRange );
+
+ sal_Bool bTextBelow = ( aRange.aStart.Row() == 0 );
+
+ Point aButtonPos;
+ if ( bTextBelow )
+ {
+ aButtonPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aEnd.Row()+1,
+ eWhich, sal_True );
+ }
+ else
+ {
+ aButtonPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aStart.Row(),
+ eWhich, sal_True );
+ aButtonPos.Y() -= nBHeight;
+ }
+ if ( bLayoutRTL )
+ aButtonPos.X() -= nHSpace - 1;
+ else
+ aButtonPos.X() -= nBWidth - nHSpace; // same for top or bottom
+
+ Rectangle aButRect( aButtonPos, Size(nBWidth,nBHeight) );
+ if ( aButRect.IsInside( rPosPixel ) )
+ {
+ rScenRange = aRange;
+ return sal_True;
+ }
+ }
+ }
+
+ return sal_False;
+}
+
+// #114409#
+void ScGridWindow::DrawLayerCreated()
+{
+ SetMapMode( GetDrawMapMode() );
+
+ // initially create overlay objects
+ ImpCreateOverlayObjects();
+}
+
+// #114409#
+void ScGridWindow::CursorChanged()
+{
+ // here the created OverlayObjects may be transformed in later versions. For
+ // now, just re-create them
+
+ UpdateCursorOverlay();
+}
+
+// #114409#
+void ScGridWindow::ImpCreateOverlayObjects()
+{
+ UpdateCursorOverlay();
+ UpdateSelectionOverlay();
+ UpdateAutoFillOverlay();
+ UpdateDragRectOverlay();
+ UpdateHeaderOverlay();
+ UpdateShrinkOverlay();
+}
+
+// #114409#
+void ScGridWindow::ImpDestroyOverlayObjects()
+{
+ DeleteCursorOverlay();
+ DeleteSelectionOverlay();
+ DeleteAutoFillOverlay();
+ DeleteDragRectOverlay();
+ DeleteHeaderOverlay();
+ DeleteShrinkOverlay();
+}
+
+void ScGridWindow::UpdateAllOverlays()
+{
+ // delete and re-allocate all overlay objects
+
+ ImpDestroyOverlayObjects();
+ ImpCreateOverlayObjects();
+}
+
+void ScGridWindow::DeleteCursorOverlay()
+{
+ DELETEZ( mpOOCursors );
+}
+
+void ScGridWindow::UpdateCursorOverlay()
+{
+ MapMode aDrawMode = GetDrawMapMode();
+ MapMode aOldMode = GetMapMode();
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aDrawMode );
+
+ // Existing OverlayObjects may be transformed in later versions.
+ // For now, just re-create them.
+
+ DeleteCursorOverlay();
+
+ std::vector<Rectangle> aPixelRects;
+
+ //
+ // determine the cursor rectangles in pixels (moved from ScGridWindow::DrawCursor)
+ //
+
+ SCTAB nTab = pViewData->GetTabNo();
+ 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();
+ const ScPatternAttr* pPattern = pDoc->GetPattern(nX,nY,nTab);
+ const ScMergeFlagAttr& rMergeFlag = (const ScMergeFlagAttr&) pPattern->GetItem(ATTR_MERGE_FLAG);
+ sal_Bool bOverlapped = rMergeFlag.IsOverlapped();
+
+ // left or above of the screen?
+
+ sal_Bool bVis = ( nX>=pViewData->GetPosX(eHWhich) && nY>=pViewData->GetPosY(eVWhich) );
+ if (!bVis)
+ {
+ SCCOL nEndX = nX;
+ SCROW nEndY = nY;
+ const ScMergeAttr& rMerge = (const ScMergeAttr&) pPattern->GetItem(ATTR_MERGE);
+ if (rMerge.GetColMerge() > 1)
+ nEndX += rMerge.GetColMerge()-1;
+ if (rMerge.GetRowMerge() > 1)
+ nEndY += rMerge.GetRowMerge()-1;
+ bVis = ( nEndX>=pViewData->GetPosX(eHWhich) && nEndY>=pViewData->GetPosY(eVWhich) );
+ }
+
+ if ( bVis && !bOverlapped && !pViewData->HasEditView(eWhich) && pViewData->IsActive() )
+ {
+ Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True );
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ // completely right of/below the screen?
+ // (test with logical start position in aScrPos)
+ sal_Bool bMaybeVisible;
+ if ( bLayoutRTL )
+ bMaybeVisible = ( aScrPos.X() >= -2 && aScrPos.Y() >= -2 );
+ else
+ {
+ Size aOutSize = GetOutputSizePixel();
+ bMaybeVisible = ( aScrPos.X() <= aOutSize.Width() + 2 && aScrPos.Y() <= aOutSize.Height() + 2 );
+ }
+ if ( bMaybeVisible )
+ {
+ long nSizeXPix;
+ long nSizeYPix;
+ pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
+
+ if ( bLayoutRTL )
+ aScrPos.X() -= nSizeXPix - 2; // move instead of mirroring
+
+ sal_Bool bFix = ( pViewData->GetHSplitMode() == SC_SPLIT_FIX ||
+ pViewData->GetVSplitMode() == SC_SPLIT_FIX );
+ if ( pViewData->GetActivePart()==eWhich || bFix )
+ {
+ aScrPos.X() -= 2;
+ aScrPos.Y() -= 2;
+ Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
+
+ aPixelRects.push_back(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ));
+ aPixelRects.push_back(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ));
+ aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ));
+ aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ));
+ }
+ else
+ {
+ Rectangle aRect( aScrPos, Size( nSizeXPix - 1, nSizeYPix - 1 ) );
+ aPixelRects.push_back( aRect );
+ }
+ }
+ }
+
+ if ( aPixelRects.size() )
+ {
+ // #i70788# get the OverlayManager safely
+ ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
+
+ if(pOverlayManager)
+ {
+ const Color aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+ std::vector< basegfx::B2DRange > aRanges;
+ const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
+
+ for(sal_uInt32 a(0); a < aPixelRects.size(); a++)
+ {
+ const Rectangle aRA(aPixelRects[a]);
+ basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1);
+ aRB.transform(aTransform);
+ aRanges.push_back(aRB);
+ }
+
+ sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
+ sdr::overlay::OVERLAY_SOLID,
+ aCursorColor,
+ aRanges,
+ false);
+
+ pOverlayManager->add(*pOverlay);
+ mpOOCursors = new ::sdr::overlay::OverlayObjectList;
+ mpOOCursors->append(*pOverlay);
+ }
+ }
+
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aOldMode );
+}
+
+void ScGridWindow::DeleteSelectionOverlay()
+{
+ DELETEZ( mpOOSelection );
+}
+
+void ScGridWindow::UpdateSelectionOverlay()
+{
+ MapMode aDrawMode = GetDrawMapMode();
+ MapMode aOldMode = GetMapMode();
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aDrawMode );
+
+ DeleteSelectionOverlay();
+ std::vector<Rectangle> aPixelRects;
+ GetSelectionRects( aPixelRects );
+
+ if ( aPixelRects.size() && pViewData->IsActive() )
+ {
+ // #i70788# get the OverlayManager safely
+ ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
+
+ if(pOverlayManager)
+ {
+ std::vector< basegfx::B2DRange > aRanges;
+ const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
+
+ for(sal_uInt32 a(0); a < aPixelRects.size(); a++)
+ {
+ const Rectangle aRA(aPixelRects[a]);
+ basegfx::B2DRange aRB(aRA.Left() - 1, aRA.Top() - 1, aRA.Right(), aRA.Bottom());
+ aRB.transform(aTransform);
+ aRanges.push_back(aRB);
+ }
+
+ // #i97672# get the system's hilight color and limit it to the maximum
+ // allowed luminance. This is needed to react on too bright hilight colors
+ // which would otherwise vive a bad visualisation
+ Color aHighlight(GetSettings().GetStyleSettings().GetHighlightColor());
+ const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
+ const basegfx::BColor aSelection(aHighlight.getBColor());
+ const double fLuminance(aSelection.luminance());
+ const double fMaxLum(aSvtOptionsDrawinglayer.GetSelectionMaximumLuminancePercent() / 100.0);
+
+ if(fLuminance > fMaxLum)
+ {
+ const double fFactor(fMaxLum / fLuminance);
+ const basegfx::BColor aNewSelection(
+ aSelection.getRed() * fFactor,
+ aSelection.getGreen() * fFactor,
+ aSelection.getBlue() * fFactor);
+
+ aHighlight = Color(aNewSelection);
+ }
+
+ sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
+ sdr::overlay::OVERLAY_TRANSPARENT,
+ aHighlight,
+ aRanges,
+ true);
+
+ pOverlayManager->add(*pOverlay);
+ mpOOSelection = new ::sdr::overlay::OverlayObjectList;
+ mpOOSelection->append(*pOverlay);
+ }
+ }
+
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aOldMode );
+}
+
+void ScGridWindow::DeleteAutoFillOverlay()
+{
+ DELETEZ( mpOOAutoFill );
+ mpAutoFillRect.reset();
+}
+
+void ScGridWindow::UpdateAutoFillOverlay()
+{
+ MapMode aDrawMode = GetDrawMapMode();
+ MapMode aOldMode = GetMapMode();
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aDrawMode );
+
+ DeleteAutoFillOverlay();
+
+ //
+ // get the AutoFill handle rectangle in pixels (moved from ScGridWindow::DrawAutoFillMark)
+ //
+
+ if ( bAutoMarkVisible && aAutoMarkPos.Tab() == pViewData->GetTabNo() &&
+ !pViewData->HasEditView(eWhich) && pViewData->IsActive() )
+ {
+ 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();
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ Point aFillPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True );
+ long nSizeXPix;
+ long nSizeYPix;
+ pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
+ if ( bLayoutRTL )
+ aFillPos.X() -= nSizeXPix + 3;
+ else
+ aFillPos.X() += nSizeXPix - 2;
+
+ aFillPos.Y() += nSizeYPix;
+ aFillPos.Y() -= 2;
+ mpAutoFillRect.reset(new Rectangle(aFillPos, Size(6, 6)));
+
+ // #i70788# get the OverlayManager safely
+ ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
+
+ if(pOverlayManager)
+ {
+ const Color aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+ std::vector< basegfx::B2DRange > aRanges;
+ const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
+ basegfx::B2DRange aRB(mpAutoFillRect->Left(), mpAutoFillRect->Top(), mpAutoFillRect->Right() + 1, mpAutoFillRect->Bottom() + 1);
+
+ aRB.transform(aTransform);
+ aRanges.push_back(aRB);
+
+ sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
+ sdr::overlay::OVERLAY_SOLID,
+ aHandleColor,
+ aRanges,
+ false);
+
+ pOverlayManager->add(*pOverlay);
+ mpOOAutoFill = new ::sdr::overlay::OverlayObjectList;
+ mpOOAutoFill->append(*pOverlay);
+ }
+
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aOldMode );
+ }
+}
+
+void ScGridWindow::DeleteDragRectOverlay()
+{
+ DELETEZ( mpOODragRect );
+}
+
+void ScGridWindow::UpdateDragRectOverlay()
+{
+ MapMode aDrawMode = GetDrawMapMode();
+ MapMode aOldMode = GetMapMode();
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aDrawMode );
+
+ DeleteDragRectOverlay();
+
+ //
+ // get the rectangles in pixels (moved from DrawDragRect)
+ //
+
+ if ( bDragRect || bPagebreakDrawn )
+ {
+ std::vector<Rectangle> aPixelRects;
+
+ SCCOL nX1 = bDragRect ? nDragStartX : aPagebreakDrag.aStart.Col();
+ SCROW nY1 = bDragRect ? nDragStartY : aPagebreakDrag.aStart.Row();
+ SCCOL nX2 = bDragRect ? nDragEndX : aPagebreakDrag.aEnd.Col();
+ SCROW nY2 = bDragRect ? nDragEndY : aPagebreakDrag.aEnd.Row();
+
+ SCTAB nTab = pViewData->GetTabNo();
+
+ SCCOL nPosX = pViewData->GetPosX(WhichH(eWhich));
+ SCROW nPosY = pViewData->GetPosY(WhichV(eWhich));
+ if (nX1 < nPosX) nX1 = nPosX;
+ if (nX2 < nPosX) nX2 = nPosX;
+ if (nY1 < nPosY) nY1 = nPosY;
+ if (nY2 < nPosY) nY2 = nPosY;
+
+ Point aScrPos( pViewData->GetScrPos( nX1, nY1, eWhich ) );
+
+ long nSizeXPix=0;
+ long nSizeYPix=0;
+ ScDocument* pDoc = pViewData->GetDocument();
+ double nPPTX = pViewData->GetPPTX();
+ double nPPTY = pViewData->GetPPTY();
+ SCCOLROW i;
+
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ if (ValidCol(nX2) && nX2>=nX1)
+ for (i=nX1; i<=nX2; i++)
+ nSizeXPix += ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(i), nTab ), nPPTX );
+ else
+ {
+ aScrPos.X() -= nLayoutSign;
+ nSizeXPix += 2;
+ }
+
+ if (ValidRow(nY2) && nY2>=nY1)
+ for (i=nY1; i<=nY2; i++)
+ nSizeYPix += ScViewData::ToPixel( pDoc->GetRowHeight( i, nTab ), nPPTY );
+ else
+ {
+ aScrPos.Y() -= 1;
+ nSizeYPix += 2;
+ }
+
+ aScrPos.X() -= 2 * nLayoutSign;
+ aScrPos.Y() -= 2;
+// Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
+ Rectangle aRect( aScrPos.X(), aScrPos.Y(),
+ aScrPos.X() + ( nSizeXPix + 2 ) * nLayoutSign, aScrPos.Y() + nSizeYPix + 2 );
+ if ( bLayoutRTL )
+ {
+ aRect.Left() = aRect.Right(); // end position is left
+ aRect.Right() = aScrPos.X();
+ }
+
+ if ( meDragInsertMode == INS_CELLSDOWN )
+ {
+ aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Top()+3, aRect.Left()+1, aRect.Bottom()-2 ) );
+ aPixelRects.push_back( Rectangle( aRect.Right()-1, aRect.Top()+3, aRect.Right()-1, aRect.Bottom()-2 ) );
+ aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Top(), aRect.Right()-1, aRect.Top()+2 ) );
+ aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Bottom()-1, aRect.Right()-1, aRect.Bottom()-1 ) );
+ }
+ else if ( meDragInsertMode == INS_CELLSRIGHT )
+ {
+ aPixelRects.push_back( Rectangle( aRect.Left(), aRect.Top()+1, aRect.Left()+2, aRect.Bottom()-1 ) );
+ aPixelRects.push_back( Rectangle( aRect.Right()-1, aRect.Top()+1, aRect.Right()-1, aRect.Bottom()-1 ) );
+ aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Top()+1, aRect.Right()-2, aRect.Top()+1 ) );
+ aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Bottom()-1, aRect.Right()-2, aRect.Bottom()-1 ) );
+ }
+ else
+ {
+ aPixelRects.push_back( Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ) );
+ aPixelRects.push_back( Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ) );
+ aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ) );
+ aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ) );
+ }
+
+ // #i70788# get the OverlayManager safely
+ ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
+
+ if(pOverlayManager)
+ {
+ // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
+ std::vector< basegfx::B2DRange > aRanges;
+ const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
+
+ for(sal_uInt32 a(0); a < aPixelRects.size(); a++)
+ {
+ const Rectangle aRA(aPixelRects[a]);
+ basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1);
+ aRB.transform(aTransform);
+ aRanges.push_back(aRB);
+ }
+
+ sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
+ sdr::overlay::OVERLAY_INVERT,
+ Color(COL_BLACK),
+ aRanges,
+ false);
+
+ pOverlayManager->add(*pOverlay);
+ mpOODragRect = new ::sdr::overlay::OverlayObjectList;
+ mpOODragRect->append(*pOverlay);
+ }
+ }
+
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aOldMode );
+}
+
+void ScGridWindow::DeleteHeaderOverlay()
+{
+ DELETEZ( mpOOHeader );
+}
+
+void ScGridWindow::UpdateHeaderOverlay()
+{
+ MapMode aDrawMode = GetDrawMapMode();
+ MapMode aOldMode = GetMapMode();
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aDrawMode );
+
+ DeleteHeaderOverlay();
+
+ // Pixel rectangle is in aInvertRect
+ if ( !aInvertRect.IsEmpty() )
+ {
+ // #i70788# get the OverlayManager safely
+ ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
+
+ if(pOverlayManager)
+ {
+ // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
+ std::vector< basegfx::B2DRange > aRanges;
+ const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
+ basegfx::B2DRange aRB(aInvertRect.Left(), aInvertRect.Top(), aInvertRect.Right() + 1, aInvertRect.Bottom() + 1);
+
+ aRB.transform(aTransform);
+ aRanges.push_back(aRB);
+
+ sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
+ sdr::overlay::OVERLAY_INVERT,
+ Color(COL_BLACK),
+ aRanges,
+ false);
+
+ pOverlayManager->add(*pOverlay);
+ mpOOHeader = new ::sdr::overlay::OverlayObjectList;
+ mpOOHeader->append(*pOverlay);
+ }
+ }
+
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aOldMode );
+}
+
+void ScGridWindow::DeleteShrinkOverlay()
+{
+ DELETEZ( mpOOShrink );
+}
+
+void ScGridWindow::UpdateShrinkOverlay()
+{
+ MapMode aDrawMode = GetDrawMapMode();
+ MapMode aOldMode = GetMapMode();
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aDrawMode );
+
+ DeleteShrinkOverlay();
+
+ //
+ // get the rectangle in pixels
+ //
+
+ Rectangle aPixRect;
+ ScRange aRange;
+ SCTAB nTab = pViewData->GetTabNo();
+ if ( pViewData->IsRefMode() && nTab >= pViewData->GetRefStartZ() && nTab <= pViewData->GetRefEndZ() &&
+ pViewData->GetDelMark( aRange ) )
+ {
+ //! limit to visible area
+ if ( aRange.aStart.Col() <= aRange.aEnd.Col() &&
+ aRange.aStart.Row() <= aRange.aEnd.Row() )
+ {
+ Point aStart = pViewData->GetScrPos( aRange.aStart.Col(),
+ aRange.aStart.Row(), eWhich );
+ Point aEnd = pViewData->GetScrPos( aRange.aEnd.Col()+1,
+ aRange.aEnd.Row()+1, eWhich );
+ aEnd.X() -= 1;
+ aEnd.Y() -= 1;
+
+ aPixRect = Rectangle( aStart,aEnd );
+ }
+ }
+
+ if ( !aPixRect.IsEmpty() )
+ {
+ // #i70788# get the OverlayManager safely
+ ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
+
+ if(pOverlayManager)
+ {
+ // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
+ std::vector< basegfx::B2DRange > aRanges;
+ const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
+ basegfx::B2DRange aRB(aPixRect.Left(), aPixRect.Top(), aPixRect.Right() + 1, aPixRect.Bottom() + 1);
+
+ aRB.transform(aTransform);
+ aRanges.push_back(aRB);
+
+ sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
+ sdr::overlay::OVERLAY_INVERT,
+ Color(COL_BLACK),
+ aRanges,
+ false);
+
+ pOverlayManager->add(*pOverlay);
+ mpOOShrink = new ::sdr::overlay::OverlayObjectList;
+ mpOOShrink->append(*pOverlay);
+ }
+ }
+
+ if ( aOldMode != aDrawMode )
+ SetMapMode( aOldMode );
+}
+
+// #i70788# central method to get the OverlayManager safely
+::sdr::overlay::OverlayManager* ScGridWindow::getOverlayManager()
+{
+ SdrPageView* pPV = pViewData->GetView()->GetScDrawView()->GetSdrPageView();
+
+ if(pPV)
+ {
+ SdrPageWindow* pPageWin = pPV->FindPageWindow( *this );
+
+ if ( pPageWin )
+ {
+ return (pPageWin->GetOverlayManager());
+ }
+ }
+
+ return 0L;
+}
+
+void ScGridWindow::flushOverlayManager()
+{
+ // #i70788# get the OverlayManager safely
+ ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
+
+ if(pOverlayManager)
+ {
+ pOverlayManager->flush();
+ }
+}
+
+// ---------------------------------------------------------------------------
+// eof
diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx
new file mode 100644
index 000000000000..4a3689653ab6
--- /dev/null
+++ b/sc/source/ui/view/gridwin2.cxx
@@ -0,0 +1,1061 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <vcl/msgbox.hxx>
+#include <vcl/sound.hxx>
+
+#include "gridwin.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "viewdata.hxx"
+#include "pivot.hxx"
+//CHINA001 #include "pfiltdlg.hxx"
+#include "uiitems.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "pagedata.hxx"
+#include "dpobject.hxx"
+#include "dpsave.hxx"
+#include "dpoutput.hxx" // ScDPPositionData
+#include "dpshttab.hxx"
+#include "dbdocfun.hxx"
+#include "dpcontrol.hxx"
+#include "dpcontrol.hrc"
+#include "strload.hxx"
+#include "userlist.hxx"
+
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+#include "scabstdlg.hxx" //CHINA001
+
+#include <vector>
+#include <hash_map>
+
+using namespace com::sun::star;
+using ::com::sun::star::sheet::DataPilotFieldOrientation;
+using ::std::vector;
+using ::std::auto_ptr;
+using ::std::hash_map;
+using ::rtl::OUString;
+using ::rtl::OUStringHash;
+
+// STATIC DATA -----------------------------------------------------------
+
+// -----------------------------------------------------------------------
+
+DataPilotFieldOrientation ScGridWindow::GetDPFieldOrientation( SCCOL nCol, SCROW nRow ) const
+{
+ using namespace ::com::sun::star::sheet;
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
+ if (!pDPObj)
+ return DataPilotFieldOrientation_HIDDEN;
+
+ sal_uInt16 nOrient = DataPilotFieldOrientation_HIDDEN;
+
+ // Check for page field first.
+ if (nCol > 0)
+ {
+ // look for the dimension header left of the drop-down arrow
+ long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient );
+ if ( nField >= 0 && nOrient == DataPilotFieldOrientation_PAGE )
+ {
+ sal_Bool bIsDataLayout = sal_False;
+ String aFieldName = pDPObj->GetDimName( nField, bIsDataLayout );
+ if ( aFieldName.Len() && !bIsDataLayout )
+ return DataPilotFieldOrientation_PAGE;
+ }
+ }
+
+ nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
+
+ // Now, check for row/column field.
+ long nField = pDPObj->GetHeaderDim(ScAddress(nCol, nRow, nTab), nOrient);
+ if (nField >= 0 && (nOrient == DataPilotFieldOrientation_COLUMN || nOrient == DataPilotFieldOrientation_ROW) )
+ {
+ sal_Bool bIsDataLayout = sal_False;
+ String aFieldName = pDPObj->GetDimName(nField, bIsDataLayout);
+ if (aFieldName.Len() && !bIsDataLayout)
+ return static_cast<DataPilotFieldOrientation>(nOrient);
+ }
+
+ return DataPilotFieldOrientation_HIDDEN;
+}
+
+// private method for mouse button handling
+sal_Bool ScGridWindow::DoPageFieldSelection( SCCOL nCol, SCROW nRow )
+{
+ if (GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE)
+ {
+ LaunchPageFieldMenu( nCol, nRow );
+ return sal_True;
+ }
+ return sal_False;
+}
+
+bool ScGridWindow::DoAutoFilterButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich);
+ Point aDiffPix = rMEvt.GetPosPixel();
+
+ aDiffPix -= aScrPos;
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ if ( bLayoutRTL )
+ aDiffPix.X() = -aDiffPix.X();
+
+ long nSizeX, nSizeY;
+ pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
+ Size aScrSize(nSizeX-1, nSizeY-1);
+
+ // Check if the mouse cursor is clicking on the popup arrow box.
+ mpFilterButton.reset(new ScDPFieldButton(this, &GetSettings().GetStyleSettings(), &pViewData->GetZoomX(), &pViewData->GetZoomY(), pDoc));
+ mpFilterButton->setBoundingBox(aScrPos, aScrSize, bLayoutRTL);
+ mpFilterButton->setPopupLeft(bLayoutRTL); // #i114944# AutoFilter button is left-aligned in RTL
+ Point aPopupPos;
+ Size aPopupSize;
+ mpFilterButton->getPopupBoundingBox(aPopupPos, aPopupSize);
+ Rectangle aRec(aPopupPos, aPopupSize);
+ if (aRec.IsInside(rMEvt.GetPosPixel()))
+ {
+ if ( DoPageFieldSelection( nCol, nRow ) )
+ return true;
+
+ bool bFilterActive = IsAutoFilterActive(nCol, nRow, nTab);
+ mpFilterButton->setHasHiddenMember(bFilterActive);
+ mpFilterButton->setDrawBaseButton(false);
+ mpFilterButton->setDrawPopupButton(true);
+ mpFilterButton->setPopupPressed(true);
+ HideCursor();
+ mpFilterButton->draw();
+ ShowCursor();
+ DoAutoFilterMenue(nCol, nRow, false);
+ return true;
+ }
+
+ return false;
+}
+
+void ScGridWindow::DoPushButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
+
+ if (pDPObj)
+ {
+ sal_uInt16 nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
+ ScAddress aPos( nCol, nRow, nTab );
+ long nField = pDPObj->GetHeaderDim( aPos, nOrient );
+ if ( nField >= 0 )
+ {
+ bDPMouse = sal_True;
+ nDPField = nField;
+ pDragDPObj = pDPObj;
+
+ if (DPTestFieldPopupArrow(rMEvt, aPos, pDPObj))
+ {
+ // field name pop up menu has been launched. Don't activate
+ // field move.
+ bDPMouse = false;
+ return;
+ }
+
+ DPTestMouse( rMEvt, sal_True );
+ StartTracking();
+ }
+ else if ( pDPObj->IsFilterButton(aPos) )
+ {
+ ReleaseMouse(); // may have been captured in ButtonDown
+
+ ScQueryParam aQueryParam;
+ SCTAB nSrcTab = 0;
+ const ScSheetSourceDesc* pDesc = pDPObj->GetSheetDesc();
+ DBG_ASSERT(pDesc, "no sheet source for filter button");
+ if (pDesc)
+ {
+ aQueryParam = pDesc->aQueryParam;
+ nSrcTab = pDesc->aSourceRange.aStart.Tab();
+ }
+
+ SfxItemSet aArgSet( pViewData->GetViewShell()->GetPool(),
+ SCITEM_QUERYDATA, SCITEM_QUERYDATA );
+ aArgSet.Put( ScQueryItem( SCITEM_QUERYDATA, pViewData, &aQueryParam ) );
+
+//CHINA001 ScPivotFilterDlg* pDlg = new ScPivotFilterDlg(
+//CHINA001 pViewData->GetViewShell()->GetDialogParent(),
+//CHINA001 aArgSet, nSrcTab );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScPivotFilterDlg* pDlg = pFact->CreateScPivotFilterDlg( pViewData->GetViewShell()->GetDialogParent(),
+ aArgSet, nSrcTab,
+ RID_SCDLG_PIVOTFILTER);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( pDlg->Execute() == RET_OK )
+ {
+ ScSheetSourceDesc aNewDesc;
+ if (pDesc)
+ aNewDesc = *pDesc;
+
+ const ScQueryItem& rQueryItem = pDlg->GetOutputItem();
+ aNewDesc.aQueryParam = rQueryItem.GetQueryData();
+
+ ScDPObject aNewObj( *pDPObj );
+ aNewObj.SetSheetDesc( aNewDesc );
+ ScDBDocFunc aFunc( *pViewData->GetDocShell() );
+ aFunc.DataPilotUpdate( pDPObj, &aNewObj, sal_True, sal_False );
+ pViewData->GetView()->CursorPosChanged(); // shells may be switched
+ }
+ delete pDlg;
+ }
+ else
+ Sound::Beep();
+ }
+ else
+ {
+ DBG_ERROR("Da is ja garnix");
+ }
+}
+
+// -----------------------------------------------------------------------
+//
+// Data Pilot interaction
+//
+
+void ScGridWindow::DPTestMouse( const MouseEvent& rMEvt, sal_Bool bMove )
+{
+ DBG_ASSERT(pDragDPObj, "pDragDPObj missing");
+
+ // scroll window if at edges
+ //! move this to separate method
+
+ sal_Bool bTimer = sal_False;
+ Point aPixel = rMEvt.GetPosPixel();
+
+ SCsCOL nDx = 0;
+ SCsROW nDy = 0;
+ if ( aPixel.X() < 0 )
+ nDx = -1;
+ if ( aPixel.Y() < 0 )
+ nDy = -1;
+ Size aSize = GetOutputSizePixel();
+ if ( aPixel.X() >= aSize.Width() )
+ nDx = 1;
+ if ( aPixel.Y() >= aSize.Height() )
+ nDy = 1;
+ if ( nDx != 0 || nDy != 0 )
+ {
+ UpdateDragRect( sal_False, Rectangle() );
+
+ if ( nDx != 0)
+ pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
+ if ( nDy != 0 )
+ pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );
+
+ bTimer = sal_True;
+ }
+
+ // ---
+
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPixel.X(), aPixel.Y(), eWhich, nPosX, nPosY );
+ sal_Bool bMouseLeft;
+ sal_Bool bMouseTop;
+ pViewData->GetMouseQuadrant( aPixel, eWhich, nPosX, nPosY, bMouseLeft, bMouseTop );
+
+ ScAddress aPos( nPosX, nPosY, pViewData->GetTabNo() );
+
+ Rectangle aPosRect;
+ sal_uInt16 nOrient;
+ long nDimPos;
+ sal_Bool bHasRange = pDragDPObj->GetHeaderDrag( aPos, bMouseLeft, bMouseTop, nDPField,
+ aPosRect, nOrient, nDimPos );
+ UpdateDragRect( bHasRange && bMove, aPosRect );
+
+ sal_Bool bIsDataLayout;
+ sal_Int32 nDimFlags = 0;
+ String aDimName = pDragDPObj->GetDimName( nDPField, bIsDataLayout, &nDimFlags );
+ bool bAllowed = !bHasRange || ScDPObject::IsOrientationAllowed( nOrient, nDimFlags );
+
+ if (bMove) // set mouse pointer
+ {
+ PointerStyle ePointer = POINTER_PIVOT_DELETE;
+ if ( !bAllowed )
+ ePointer = POINTER_NOTALLOWED;
+ else if ( bHasRange )
+ switch (nOrient)
+ {
+ case sheet::DataPilotFieldOrientation_COLUMN: ePointer = POINTER_PIVOT_COL; break;
+ case sheet::DataPilotFieldOrientation_ROW: ePointer = POINTER_PIVOT_ROW; break;
+ case sheet::DataPilotFieldOrientation_PAGE:
+ case sheet::DataPilotFieldOrientation_DATA: ePointer = POINTER_PIVOT_FIELD; break;
+ }
+ SetPointer( ePointer );
+ }
+ else // execute change
+ {
+ if (!bHasRange)
+ nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
+
+ if ( bIsDataLayout && ( nOrient != sheet::DataPilotFieldOrientation_COLUMN &&
+ nOrient != sheet::DataPilotFieldOrientation_ROW ) )
+ {
+ // removing data layout is not allowed
+ pViewData->GetView()->ErrorMessage(STR_PIVOT_MOVENOTALLOWED);
+ }
+ else if ( bAllowed )
+ {
+ ScDPSaveData aSaveData( *pDragDPObj->GetSaveData() );
+
+ ScDPSaveDimension* pDim;
+ if ( bIsDataLayout )
+ pDim = aSaveData.GetDataLayoutDimension();
+ else
+ pDim = aSaveData.GetDimensionByName(aDimName);
+ pDim->SetOrientation( nOrient );
+ aSaveData.SetPosition( pDim, nDimPos );
+
+ //! docfunc method with ScDPSaveData as argument?
+
+ ScDPObject aNewObj( *pDragDPObj );
+ aNewObj.SetSaveData( aSaveData );
+ ScDBDocFunc aFunc( *pViewData->GetDocShell() );
+ // when dragging fields, allow re-positioning (bAllowMove)
+ aFunc.DataPilotUpdate( pDragDPObj, &aNewObj, sal_True, sal_False, sal_True );
+ pViewData->GetView()->CursorPosChanged(); // shells may be switched
+ }
+ }
+
+ if (bTimer && bMove)
+ pViewData->GetView()->SetTimer( this, rMEvt ); // repeat event
+ else
+ pViewData->GetView()->ResetTimer();
+}
+
+bool ScGridWindow::DPTestFieldPopupArrow(const MouseEvent& rMEvt, const ScAddress& rPos, ScDPObject* pDPObj)
+{
+ sal_Bool bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
+
+ // Get the geometry of the cell.
+ Point aScrPos = pViewData->GetScrPos(rPos.Col(), rPos.Row(), eWhich);
+ long nSizeX, nSizeY;
+ pViewData->GetMergeSizePixel(rPos.Col(), rPos.Row(), nSizeX, nSizeY);
+ Size aScrSize(nSizeX-1, nSizeY-1);
+
+ // Check if the mouse cursor is clicking on the popup arrow box.
+ ScDPFieldButton aBtn(this, &GetSettings().GetStyleSettings());
+ aBtn.setBoundingBox(aScrPos, aScrSize, bLayoutRTL);
+ aBtn.setPopupLeft(false); // DataPilot popup is always right-aligned for now
+ Point aPopupPos;
+ Size aPopupSize;
+ aBtn.getPopupBoundingBox(aPopupPos, aPopupSize);
+ Rectangle aRec(aPopupPos, aPopupSize);
+ if (aRec.IsInside(rMEvt.GetPosPixel()))
+ {
+ // Mouse cursor inside the popup arrow box. Launch the field menu.
+ DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, rPos, pDPObj);
+ return true;
+ }
+
+ return false;
+}
+
+namespace {
+
+struct DPFieldPopupData : public ScDPFieldPopupWindow::ExtendedData
+{
+ ScPivotParam maDPParam;
+ ScDPObject* mpDPObj;
+ long mnDim;
+};
+
+class DPFieldPopupOKAction : public ScMenuFloatingWindow::Action
+{
+public:
+ explicit DPFieldPopupOKAction(ScGridWindow* p) :
+ mpGridWindow(p) {}
+
+ virtual void execute()
+ {
+ mpGridWindow->UpdateDPFromFieldPopupMenu();
+ }
+private:
+ ScGridWindow* mpGridWindow;
+};
+
+class PopupSortAction : public ScMenuFloatingWindow::Action
+{
+public:
+ enum SortType { ASCENDING, DESCENDING, CUSTOM };
+
+ explicit PopupSortAction(const ScAddress& rPos, SortType eType, sal_uInt16 nUserListIndex, ScTabViewShell* pViewShell) :
+ maPos(rPos), meType(eType), mnUserListIndex(nUserListIndex), mpViewShell(pViewShell) {}
+
+ virtual void execute()
+ {
+ switch (meType)
+ {
+ case ASCENDING:
+ mpViewShell->DataPilotSort(maPos, true);
+ break;
+ case DESCENDING:
+ mpViewShell->DataPilotSort(maPos, false);
+ break;
+ case CUSTOM:
+ mpViewShell->DataPilotSort(maPos, true, &mnUserListIndex);
+ break;
+ default:
+ ;
+ }
+ }
+
+private:
+ ScAddress maPos;
+ SortType meType;
+ sal_uInt16 mnUserListIndex;
+ ScTabViewShell* mpViewShell;
+};
+
+}
+
+void ScGridWindow::DPLaunchFieldPopupMenu(
+ const Point& rScrPos, const Size& rScrSize, const ScAddress& rPos, ScDPObject* pDPObj)
+{
+ // We need to get the list of field members.
+ auto_ptr<DPFieldPopupData> pDPData(new DPFieldPopupData);
+ pDPObj->FillLabelData(pDPData->maDPParam);
+ pDPData->mpDPObj = pDPObj;
+
+ sal_uInt16 nOrient;
+ pDPData->mnDim = pDPObj->GetHeaderDim(rPos, nOrient);
+
+ if (pDPData->maDPParam.maLabelArray.size() <= static_cast<size_t>(pDPData->mnDim))
+ // out-of-bound dimension ID. This should never happen!
+ return;
+
+ const ScDPLabelData& rLabelData = *pDPData->maDPParam.maLabelArray[pDPData->mnDim];
+
+ mpDPFieldPopup.reset(new ScDPFieldPopupWindow(this, pViewData->GetDocument()));
+ mpDPFieldPopup->setName(OUString::createFromAscii("DataPilot field member popup"));
+ mpDPFieldPopup->setExtendedData(pDPData.release());
+ mpDPFieldPopup->setOKAction(new DPFieldPopupOKAction(this));
+ {
+ // Populate field members.
+ size_t n = rLabelData.maMembers.size();
+ mpDPFieldPopup->setMemberSize(n);
+ for (size_t i = 0; i < n; ++i)
+ {
+ const ScDPLabelData::Member& rMem = rLabelData.maMembers[i];
+ mpDPFieldPopup->addMember(rMem.getDisplayName(), rMem.mbVisible);
+ }
+ mpDPFieldPopup->initMembers();
+ }
+
+ vector<OUString> aUserSortNames;
+ ScUserList* pUserList = ScGlobal::GetUserList();
+ if (pUserList)
+ {
+ sal_uInt16 n = pUserList->GetCount();
+ aUserSortNames.reserve(n);
+ for (sal_uInt16 i = 0; i < n; ++i)
+ {
+ ScUserListData* pData = static_cast<ScUserListData*>((*pUserList)[i]);
+ aUserSortNames.push_back(pData->GetString());
+ }
+ }
+
+ // Populate the menus.
+ ScTabViewShell* pViewShell = pViewData->GetViewShell();
+ mpDPFieldPopup->addMenuItem(
+ ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_ASC).GetString(), true,
+ new PopupSortAction(rPos, PopupSortAction::ASCENDING, 0, pViewShell));
+ mpDPFieldPopup->addMenuItem(
+ ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_DESC).GetString(), true,
+ new PopupSortAction(rPos, PopupSortAction::DESCENDING, 0, pViewShell));
+ ScMenuFloatingWindow* pSubMenu = mpDPFieldPopup->addSubMenuItem(
+ ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_CUSTOM).GetString(), !aUserSortNames.empty());
+
+ if (pSubMenu && !aUserSortNames.empty())
+ {
+ size_t n = aUserSortNames.size();
+ for (size_t i = 0; i < n; ++i)
+ {
+ pSubMenu->addMenuItem(
+ aUserSortNames[i], true,
+ new PopupSortAction(rPos, PopupSortAction::CUSTOM, static_cast<sal_uInt16>(i), pViewShell));
+ }
+ }
+
+ sal_Bool bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
+
+ Rectangle aCellRect(rScrPos, rScrSize);
+ const Size& rPopupSize = mpDPFieldPopup->getWindowSize();
+ if (bLayoutRTL)
+ {
+ // RTL: rScrPos is logical-left (visual right) position, always right-align with that
+ aCellRect.SetPos(Point(rScrPos.X() - rPopupSize.Width() + 1, rScrPos.Y()));
+ }
+ else if (rScrSize.getWidth() > rPopupSize.getWidth())
+ {
+ // If the cell width is larger than the popup window width, launch it
+ // right-aligned with the cell.
+ long nXOffset = rScrSize.getWidth() - rPopupSize.getWidth();
+ aCellRect.SetPos(Point(rScrPos.X() + nXOffset, rScrPos.Y()));
+ }
+ mpDPFieldPopup->SetPopupModeEndHdl( LINK(this, ScGridWindow, PopupModeEndHdl) );
+ mpDPFieldPopup->StartPopupMode(aCellRect, (FLOATWIN_POPUPMODE_DOWN | FLOATWIN_POPUPMODE_GRABFOCUS));
+}
+
+void ScGridWindow::UpdateDPFromFieldPopupMenu()
+{
+ typedef hash_map<OUString, OUString, OUStringHash> MemNameMapType;
+ typedef hash_map<OUString, bool, OUStringHash> MemVisibilityType;
+
+ if (!mpDPFieldPopup.get())
+ return;
+
+ DPFieldPopupData* pDPData = static_cast<DPFieldPopupData*>(mpDPFieldPopup->getExtendedData());
+ if (!pDPData)
+ return;
+
+ ScDPObject* pDPObj = pDPData->mpDPObj;
+ ScDPObject aNewDPObj(*pDPObj);
+ aNewDPObj.BuildAllDimensionMembers();
+ ScDPSaveData* pSaveData = aNewDPObj.GetSaveData();
+
+ sal_Bool bIsDataLayout;
+ String aDimName = pDPObj->GetDimName(pDPData->mnDim, bIsDataLayout);
+ ScDPSaveDimension* pDim = pSaveData->GetDimensionByName(aDimName);
+ if (!pDim)
+ return;
+
+ // Build a map of layout names to original names.
+ const ScDPLabelData& rLabelData = *pDPData->maDPParam.maLabelArray[pDPData->mnDim];
+ MemNameMapType aMemNameMap;
+ for (vector<ScDPLabelData::Member>::const_iterator itr = rLabelData.maMembers.begin(), itrEnd = rLabelData.maMembers.end();
+ itr != itrEnd; ++itr)
+ aMemNameMap.insert(MemNameMapType::value_type(itr->maLayoutName, itr->maName));
+
+ // The raw result may contain a mixture of layout names and original names.
+ MemVisibilityType aRawResult;
+ mpDPFieldPopup->getResult(aRawResult);
+
+ MemVisibilityType aResult;
+ for (MemVisibilityType::const_iterator itr = aRawResult.begin(), itrEnd = aRawResult.end(); itr != itrEnd; ++itr)
+ {
+ MemNameMapType::const_iterator itrNameMap = aMemNameMap.find(itr->first);
+ if (itrNameMap == aMemNameMap.end())
+ // This is an original member name. Use it as-is.
+ aResult.insert(MemVisibilityType::value_type(itr->first, itr->second));
+ else
+ {
+ // This is a layout name. Get the original member name and use it.
+ aResult.insert(MemVisibilityType::value_type(itrNameMap->second, itr->second));
+ }
+ }
+ pDim->UpdateMemberVisibility(aResult);
+
+ ScDBDocFunc aFunc(*pViewData->GetDocShell());
+ aFunc.DataPilotUpdate(pDPObj, &aNewDPObj, true, false);
+}
+
+void ScGridWindow::DPMouseMove( const MouseEvent& rMEvt )
+{
+ DPTestMouse( rMEvt, sal_True );
+}
+
+void ScGridWindow::DPMouseButtonUp( const MouseEvent& rMEvt )
+{
+ bDPMouse = sal_False;
+ ReleaseMouse();
+
+ DPTestMouse( rMEvt, sal_False );
+ SetPointer( Pointer( POINTER_ARROW ) );
+}
+
+// -----------------------------------------------------------------------
+
+void ScGridWindow::UpdateDragRect( sal_Bool bShowRange, const Rectangle& rPosRect )
+{
+ SCCOL nStartX = ( rPosRect.Left() >= 0 ) ? static_cast<SCCOL>(rPosRect.Left()) : SCCOL_MAX;
+ SCROW nStartY = ( rPosRect.Top() >= 0 ) ? static_cast<SCROW>(rPosRect.Top()) : SCROW_MAX;
+ SCCOL nEndX = ( rPosRect.Right() >= 0 ) ? static_cast<SCCOL>(rPosRect.Right()) : SCCOL_MAX;
+ SCROW nEndY = ( rPosRect.Bottom() >= 0 ) ? static_cast<SCROW>(rPosRect.Bottom()) : SCROW_MAX;
+
+ if ( bShowRange == bDragRect && nDragStartX == nStartX && nDragEndX == nEndX &&
+ nDragStartY == nStartY && nDragEndY == nEndY )
+ {
+ return; // everything unchanged
+ }
+
+ // if ( bDragRect )
+ // DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, sal_False );
+ if ( bShowRange )
+ {
+ nDragStartX = nStartX;
+ nDragStartY = nStartY;
+ nDragEndX = nEndX;
+ nDragEndY = nEndY;
+ bDragRect = sal_True;
+ // DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, sal_False );
+ }
+ else
+ bDragRect = sal_False;
+
+ UpdateDragRectOverlay();
+}
+
+// -----------------------------------------------------------------------
+
+// Page-Break-Modus
+
+sal_uInt16 ScGridWindow::HitPageBreak( const Point& rMouse, ScRange* pSource,
+ SCCOLROW* pBreak, SCCOLROW* pPrev )
+{
+ sal_uInt16 nFound = SC_PD_NONE; // 0
+ ScRange aSource;
+ SCCOLROW nBreak = 0;
+ SCCOLROW nPrev = 0;
+
+ ScPageBreakData* pPageData = pViewData->GetView()->GetPageBreakData();
+ if ( pPageData )
+ {
+ sal_Bool bHori = sal_False;
+ sal_Bool bVert = sal_False;
+ SCCOL nHitX = 0;
+ SCROW nHitY = 0;
+
+ long nMouseX = rMouse.X();
+ long nMouseY = rMouse.Y();
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( nMouseX, nMouseY, eWhich, nPosX, nPosY );
+ Point aTL = pViewData->GetScrPos( nPosX, nPosY, eWhich );
+ Point aBR = pViewData->GetScrPos( nPosX+1, nPosY+1, eWhich );
+
+ // Horizontal mehr Toleranz als vertikal, weil mehr Platz ist
+ if ( nMouseX <= aTL.X() + 4 )
+ {
+ bHori = sal_True;
+ nHitX = nPosX;
+ }
+ else if ( nMouseX >= aBR.X() - 6 )
+ {
+ bHori = sal_True;
+ nHitX = nPosX+1; // linker Rand der naechsten Zelle
+ }
+ if ( nMouseY <= aTL.Y() + 2 )
+ {
+ bVert = sal_True;
+ nHitY = nPosY;
+ }
+ else if ( nMouseY >= aBR.Y() - 4 )
+ {
+ bVert = sal_True;
+ nHitY = nPosY+1; // oberer Rand der naechsten Zelle
+ }
+
+ if ( bHori || bVert )
+ {
+ sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( pPageData->GetCount() );
+ for (sal_uInt16 nPos=0; nPos<nCount && !nFound; nPos++)
+ {
+ ScPrintRangeData& rData = pPageData->GetData(nPos);
+ ScRange aRange = rData.GetPrintRange();
+ sal_Bool bLHit = ( bHori && nHitX == aRange.aStart.Col() );
+ sal_Bool bRHit = ( bHori && nHitX == aRange.aEnd.Col() + 1 );
+ sal_Bool bTHit = ( bVert && nHitY == aRange.aStart.Row() );
+ sal_Bool bBHit = ( bVert && nHitY == aRange.aEnd.Row() + 1 );
+ sal_Bool bInsideH = ( nPosX >= aRange.aStart.Col() && nPosX <= aRange.aEnd.Col() );
+ sal_Bool bInsideV = ( nPosY >= aRange.aStart.Row() && nPosY <= aRange.aEnd.Row() );
+
+ if ( bLHit )
+ {
+ if ( bTHit )
+ nFound = SC_PD_RANGE_TL;
+ else if ( bBHit )
+ nFound = SC_PD_RANGE_BL;
+ else if ( bInsideV )
+ nFound = SC_PD_RANGE_L;
+ }
+ else if ( bRHit )
+ {
+ if ( bTHit )
+ nFound = SC_PD_RANGE_TR;
+ else if ( bBHit )
+ nFound = SC_PD_RANGE_BR;
+ else if ( bInsideV )
+ nFound = SC_PD_RANGE_R;
+ }
+ else if ( bTHit && bInsideH )
+ nFound = SC_PD_RANGE_T;
+ else if ( bBHit && bInsideH )
+ nFound = SC_PD_RANGE_B;
+ if (nFound)
+ aSource = aRange;
+
+ // Umbrueche
+
+ if ( bVert && bInsideH && !nFound )
+ {
+ size_t nRowCount = rData.GetPagesY();
+ const SCROW* pRowEnd = rData.GetPageEndY();
+ for (size_t nRowPos=0; nRowPos+1<nRowCount; nRowPos++)
+ if ( pRowEnd[nRowPos]+1 == nHitY )
+ {
+ nFound = SC_PD_BREAK_V;
+ aSource = aRange;
+ nBreak = nHitY;
+ if ( nRowPos )
+ nPrev = pRowEnd[nRowPos-1]+1;
+ else
+ nPrev = aRange.aStart.Row();
+ }
+ }
+ if ( bHori && bInsideV && !nFound )
+ {
+ size_t nColCount = rData.GetPagesX();
+ const SCCOL* pColEnd = rData.GetPageEndX();
+ for (size_t nColPos=0; nColPos+1<nColCount; nColPos++)
+ if ( pColEnd[nColPos]+1 == nHitX )
+ {
+ nFound = SC_PD_BREAK_H;
+ aSource = aRange;
+ nBreak = nHitX;
+ if ( nColPos )
+ nPrev = pColEnd[nColPos-1]+1;
+ else
+ nPrev = aRange.aStart.Col();
+ }
+ }
+ }
+ }
+ }
+
+ if (pSource)
+ *pSource = aSource; // Druckbereich
+ if (pBreak)
+ *pBreak = nBreak; // X/Y Position des verchobenen Seitenumbruchs
+ if (pPrev)
+ *pPrev = nPrev; // X/Y Anfang der Seite, die am Umbruch zuende ist
+ return nFound;
+}
+
+void ScGridWindow::PagebreakMove( const MouseEvent& rMEvt, sal_Bool bUp )
+{
+ //! Scrolling und Umschalten mit RFMouseMove zusammenfassen !
+ //! (Weginvertieren vor dem Scrolling ist anders)
+
+ // Scrolling
+
+ sal_Bool bTimer = sal_False;
+ Point aPos = rMEvt.GetPosPixel();
+ SCsCOL nDx = 0;
+ SCsROW nDy = 0;
+ if ( aPos.X() < 0 ) nDx = -1;
+ if ( aPos.Y() < 0 ) nDy = -1;
+ Size aSize = GetOutputSizePixel();
+ if ( aPos.X() >= aSize.Width() )
+ nDx = 1;
+ if ( aPos.Y() >= aSize.Height() )
+ nDy = 1;
+ if ( nDx != 0 || nDy != 0 )
+ {
+ if ( bPagebreakDrawn ) // weginvertieren
+ {
+ // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
+ // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), sal_False );
+ bPagebreakDrawn = sal_False;
+ UpdateDragRectOverlay();
+ }
+
+ if ( nDx != 0 ) pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
+ if ( nDy != 0 ) pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );
+ bTimer = sal_True;
+ }
+
+ // Umschalten bei Fixierung (damit Scrolling funktioniert)
+
+ if ( eWhich == pViewData->GetActivePart() ) //??
+ {
+ if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX )
+ if ( nDx > 0 )
+ {
+ if ( eWhich == SC_SPLIT_TOPLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT );
+ else if ( eWhich == SC_SPLIT_BOTTOMLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT );
+ }
+
+ if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX )
+ if ( nDy > 0 )
+ {
+ if ( eWhich == SC_SPLIT_TOPLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT );
+ else if ( eWhich == SC_SPLIT_TOPRIGHT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT );
+ }
+ }
+
+ // ab hier neu
+
+ // gesucht wird eine Position zwischen den Zellen (vor nPosX / nPosY)
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
+ sal_Bool bLeft, bTop;
+ pViewData->GetMouseQuadrant( aPos, eWhich, nPosX, nPosY, bLeft, bTop );
+ if ( !bLeft ) ++nPosX;
+ if ( !bTop ) ++nPosY;
+
+ sal_Bool bBreak = ( nPagebreakMouse == SC_PD_BREAK_H || nPagebreakMouse == SC_PD_BREAK_V );
+ sal_Bool bHide = sal_False;
+ sal_Bool bToEnd = sal_False;
+ ScRange aDrawRange = aPagebreakSource;
+ if ( bBreak )
+ {
+ if ( nPagebreakMouse == SC_PD_BREAK_H )
+ {
+ if ( nPosX > aPagebreakSource.aStart.Col() &&
+ nPosX <= aPagebreakSource.aEnd.Col() + 1 ) // ans Ende ist auch erlaubt
+ {
+ bToEnd = ( nPosX == aPagebreakSource.aEnd.Col() + 1 );
+ aDrawRange.aStart.SetCol( nPosX );
+ aDrawRange.aEnd.SetCol( nPosX - 1 );
+ }
+ else
+ bHide = sal_True;
+ }
+ else
+ {
+ if ( nPosY > aPagebreakSource.aStart.Row() &&
+ nPosY <= aPagebreakSource.aEnd.Row() + 1 ) // ans Ende ist auch erlaubt
+ {
+ bToEnd = ( nPosY == aPagebreakSource.aEnd.Row() + 1 );
+ aDrawRange.aStart.SetRow( nPosY );
+ aDrawRange.aEnd.SetRow( nPosY - 1 );
+ }
+ else
+ bHide = sal_True;
+ }
+ }
+ else
+ {
+ if ( nPagebreakMouse & SC_PD_RANGE_L )
+ aDrawRange.aStart.SetCol( nPosX );
+ if ( nPagebreakMouse & SC_PD_RANGE_T )
+ aDrawRange.aStart.SetRow( nPosY );
+ if ( nPagebreakMouse & SC_PD_RANGE_R )
+ {
+ if ( nPosX > 0 )
+ aDrawRange.aEnd.SetCol( nPosX-1 );
+ else
+ bHide = sal_True;
+ }
+ if ( nPagebreakMouse & SC_PD_RANGE_B )
+ {
+ if ( nPosY > 0 )
+ aDrawRange.aEnd.SetRow( nPosY-1 );
+ else
+ bHide = sal_True;
+ }
+ if ( aDrawRange.aStart.Col() > aDrawRange.aEnd.Col() ||
+ aDrawRange.aStart.Row() > aDrawRange.aEnd.Row() )
+ bHide = sal_True;
+ }
+
+ if ( !bPagebreakDrawn || bUp || aDrawRange != aPagebreakDrag )
+ {
+ // zeichnen...
+
+ if ( bPagebreakDrawn )
+ {
+ // weginvertieren
+ // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
+ // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), sal_False );
+ bPagebreakDrawn = sal_False;
+ }
+ aPagebreakDrag = aDrawRange;
+ if ( !bUp && !bHide )
+ {
+ // hininvertieren
+ // DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
+ // aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), sal_False );
+ bPagebreakDrawn = sal_True;
+ }
+ UpdateDragRectOverlay();
+ }
+
+ // bei ButtonUp die Aenderung ausfuehren
+
+ if ( bUp )
+ {
+ ScViewFunc* pViewFunc = pViewData->GetView();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ sal_Bool bUndo (pDoc->IsUndoEnabled());
+
+ if ( bBreak )
+ {
+ sal_Bool bColumn = ( nPagebreakMouse == SC_PD_BREAK_H );
+ SCCOLROW nNew = bColumn ? static_cast<SCCOLROW>(nPosX) : static_cast<SCCOLROW>(nPosY);
+ if ( nNew != nPagebreakBreak )
+ {
+ if (bUndo)
+ {
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_DRAG_BREAK );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+ }
+
+ sal_Bool bGrow = !bHide && nNew > nPagebreakBreak;
+ if ( bColumn )
+ {
+ if (pDoc->HasColBreak(static_cast<SCCOL>(nPagebreakBreak), nTab) & BREAK_MANUAL)
+ {
+ ScAddress aOldAddr( static_cast<SCCOL>(nPagebreakBreak), nPosY, nTab );
+ pViewFunc->DeletePageBreak( sal_True, sal_True, &aOldAddr, sal_False );
+ }
+ if ( !bHide && !bToEnd ) // am Ende nicht
+ {
+ ScAddress aNewAddr( static_cast<SCCOL>(nNew), nPosY, nTab );
+ pViewFunc->InsertPageBreak( sal_True, sal_True, &aNewAddr, sal_False );
+ }
+ if ( bGrow )
+ {
+ // vorigen Break auf hart, und Skalierung aendern
+ 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( sal_True, sal_True, &aPrev, sal_False );
+ }
+
+ if (!pDocSh->AdjustPrintZoom( ScRange(
+ static_cast<SCCOL>(nPagebreakPrev),0,nTab, static_cast<SCCOL>(nNew-1),0,nTab ) ))
+ bGrow = sal_False;
+ }
+ }
+ else
+ {
+ if (pDoc->HasRowBreak(nPagebreakBreak, nTab) & BREAK_MANUAL)
+ {
+ ScAddress aOldAddr( nPosX, nPagebreakBreak, nTab );
+ pViewFunc->DeletePageBreak( sal_False, sal_True, &aOldAddr, sal_False );
+ }
+ if ( !bHide && !bToEnd ) // am Ende nicht
+ {
+ ScAddress aNewAddr( nPosX, nNew, nTab );
+ pViewFunc->InsertPageBreak( sal_False, sal_True, &aNewAddr, sal_False );
+ }
+ if ( bGrow )
+ {
+ // vorigen Break auf hart, und Skalierung aendern
+ bool bManualBreak = (pDoc->HasRowBreak(nPagebreakPrev, nTab) & BREAK_MANUAL);
+ if ( nPagebreakPrev > aPagebreakSource.aStart.Row() && !bManualBreak )
+ {
+ ScAddress aPrev( nPosX, nPagebreakPrev, nTab );
+ pViewFunc->InsertPageBreak( sal_False, sal_True, &aPrev, sal_False );
+ }
+
+ if (!pDocSh->AdjustPrintZoom( ScRange(
+ 0,nPagebreakPrev,nTab, 0,nNew-1,nTab ) ))
+ bGrow = sal_False;
+ }
+ }
+
+ if (bUndo)
+ {
+ pDocSh->GetUndoManager()->LeaveListAction();
+ }
+
+ if (!bGrow) // sonst in AdjustPrintZoom schon passiert
+ {
+ pViewFunc->UpdatePageBreakData( sal_True );
+ pDocSh->SetDocumentModified();
+ }
+ }
+ }
+ else if ( bHide || aPagebreakDrag != aPagebreakSource )
+ {
+ // Druckbereich setzen
+
+ String aNewRanges;
+ sal_uInt16 nOldCount = pDoc->GetPrintRangeCount( nTab );
+ if ( nOldCount )
+ {
+ for (sal_uInt16 nPos=0; nPos<nOldCount; nPos++)
+ {
+ const ScRange* pOld = pDoc->GetPrintRange( nTab, nPos );
+ if ( pOld )
+ {
+ String aTemp;
+ if ( *pOld != aPagebreakSource )
+ pOld->Format( aTemp, SCA_VALID );
+ else if ( !bHide )
+ aPagebreakDrag.Format( aTemp, SCA_VALID );
+ if (aTemp.Len())
+ {
+ if ( aNewRanges.Len() )
+ aNewRanges += ';';
+ aNewRanges += aTemp;
+ }
+ }
+ }
+ }
+ else if (!bHide)
+ aPagebreakDrag.Format( aNewRanges, SCA_VALID );
+
+ pViewFunc->SetPrintRanges( pDoc->IsPrintEntireSheet( nTab ), &aNewRanges, NULL, NULL, sal_False );
+ }
+ }
+
+ // Timer fuer Scrolling
+
+ if (bTimer && !bUp)
+ pViewData->GetView()->SetTimer( this, rMEvt ); // Event wiederholen
+ else
+ pViewData->GetView()->ResetTimer();
+}
+
+
+
+
diff --git a/sc/source/ui/view/gridwin3.cxx b/sc/source/ui/view/gridwin3.cxx
new file mode 100644
index 000000000000..295caae639af
--- /dev/null
+++ b/sc/source/ui/view/gridwin3.cxx
@@ -0,0 +1,443 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <svx/svdoutl.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/svdpagv.hxx>
+#include <editeng/sizeitem.hxx>
+#include <sfx2/bindings.hxx>
+#include <svl/ptitem.hxx>
+
+#include "tabvwsh.hxx"
+#include "gridwin.hxx"
+#include "dbfunc.hxx"
+#include "viewdata.hxx"
+#include "output.hxx"
+#include "drawview.hxx"
+#include "fupoor.hxx"
+
+#include "drawutil.hxx"
+#include "document.hxx"
+#include "drwlayer.hxx"
+#include <vcl/svapp.hxx>
+
+// -----------------------------------------------------------------------
+
+sal_Bool ScGridWindow::DrawMouseButtonDown(const MouseEvent& rMEvt)
+{
+ sal_Bool bRet = sal_False;
+ FuPoor* pDraw = pViewData->GetView()->GetDrawFuncPtr();
+ if (pDraw && !pViewData->IsRefMode())
+ {
+ pDraw->SetWindow( this );
+ Point aLogicPos = PixelToLogic(rMEvt.GetPosPixel());
+ if ( pDraw->IsDetectiveHit( aLogicPos ) )
+ {
+ // auf Detektiv-Pfeilen gar nichts (Doppelklick wird bei ButtonUp ausgewertet)
+ bRet = sal_True;
+ }
+ else
+ {
+ bRet = pDraw->MouseButtonDown( rMEvt );
+ if ( bRet )
+ UpdateStatusPosSize();
+ }
+ }
+
+ // bei rechter Taste Draw-Aktion abbrechen
+
+ ScDrawView* pDrView = pViewData->GetScDrawView();
+ if ( pDrView && !rMEvt.IsLeft() && !bRet )
+ {
+ pDrView->BrkAction();
+ bRet = sal_True;
+ }
+ return bRet;
+}
+
+sal_Bool ScGridWindow::DrawMouseButtonUp(const MouseEvent& rMEvt)
+{
+ ScViewFunc* pView = pViewData->GetView();
+ sal_Bool bRet = sal_False;
+ FuPoor* pDraw = pView->GetDrawFuncPtr();
+ if (pDraw && !pViewData->IsRefMode())
+ {
+ pDraw->SetWindow( this );
+ bRet = pDraw->MouseButtonUp( rMEvt );
+
+ // execute "format paint brush" for drawing objects
+ SfxItemSet* pDrawBrush = pView->GetDrawBrushSet();
+ if ( pDrawBrush )
+ {
+ ScDrawView* pDrView = pViewData->GetScDrawView();
+ if ( pDrView )
+ {
+ sal_Bool bReplaceAll = sal_True;
+ pDrView->SetAttrToMarked(*pDrawBrush, bReplaceAll);
+ }
+
+ if ( !pView->IsPaintBrushLocked() )
+ pView->ResetBrushDocument(); // end paint brush mode if not locked
+ }
+ }
+
+ return bRet;
+}
+
+sal_Bool ScGridWindow::DrawMouseMove(const MouseEvent& rMEvt)
+{
+ FuPoor* pDraw = pViewData->GetView()->GetDrawFuncPtr();
+ if (pDraw && !pViewData->IsRefMode())
+ {
+ pDraw->SetWindow( this );
+ sal_Bool bRet = pDraw->MouseMove( rMEvt );
+ if ( bRet )
+ UpdateStatusPosSize();
+ return bRet;
+ }
+ else
+ {
+ SetPointer( Pointer( POINTER_ARROW ) );
+ return sal_False;
+ }
+}
+
+void ScGridWindow::DrawEndAction()
+{
+ ScDrawView* pDrView = pViewData->GetScDrawView();
+ if ( pDrView && pDrView->IsAction() )
+ pDrView->BrkAction();
+
+ FuPoor* pDraw = pViewData->GetView()->GetDrawFuncPtr();
+ if (pDraw)
+ pDraw->StopDragTimer();
+
+ // ReleaseMouse beim Aufruf
+}
+
+sal_Bool ScGridWindow::DrawCommand(const CommandEvent& rCEvt)
+{
+ ScDrawView* pDrView = pViewData->GetScDrawView();
+ FuPoor* pDraw = pViewData->GetView()->GetDrawFuncPtr();
+ if (pDrView && pDraw && !pViewData->IsRefMode())
+ {
+ pDraw->SetWindow( this );
+ sal_uInt8 nUsed = pDraw->Command( rCEvt );
+ if( nUsed == SC_CMD_USED )
+ nButtonDown = 0; // MouseButtonUp wird verschluckt...
+ if( nUsed || pDrView->IsAction() )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+sal_Bool ScGridWindow::DrawKeyInput(const KeyEvent& rKEvt)
+{
+ ScDrawView* pDrView = pViewData->GetScDrawView();
+ FuPoor* pDraw = pViewData->GetView()->GetDrawFuncPtr();
+ if (pDrView && pDraw && !pViewData->IsRefMode())
+ {
+ pDraw->SetWindow( this );
+ sal_Bool bOldMarked = pDrView->AreObjectsMarked();
+ if (pDraw->KeyInput( rKEvt ))
+ {
+ sal_Bool bLeaveDraw = sal_False;
+ sal_Bool bUsed = sal_True;
+ sal_Bool bNewMarked = pDrView->AreObjectsMarked();
+ if ( !pViewData->GetView()->IsDrawSelMode() )
+ if ( !bNewMarked )
+ {
+ pViewData->GetViewShell()->SetDrawShell( sal_False );
+ bLeaveDraw = sal_True;
+ if ( !bOldMarked &&
+ rKEvt.GetKeyCode().GetCode() == KEY_DELETE )
+ bUsed = sal_False; // nichts geloescht
+ }
+ if (!bLeaveDraw)
+ UpdateStatusPosSize(); // #108137# for moving/resizing etc. by keyboard
+ return bUsed;
+ }
+ }
+
+ return sal_False;
+}
+
+void ScGridWindow::DrawRedraw( ScOutputData& rOutputData, ScUpdateMode eMode, sal_uLong nLayer )
+{
+ // #109985#
+ const ScViewOptions& rOpts = pViewData->GetOptions();
+
+ // use new flags at SdrPaintView for hiding objects
+ const bool bDrawOle(VOBJ_MODE_SHOW == rOpts.GetObjMode(VOBJ_TYPE_OLE));
+ const bool bDrawChart(VOBJ_MODE_SHOW == rOpts.GetObjMode(VOBJ_TYPE_CHART));
+ const bool bDrawDraw(VOBJ_MODE_SHOW == rOpts.GetObjMode(VOBJ_TYPE_DRAW));
+
+ if(bDrawOle || bDrawChart || bDrawDraw)
+ {
+ ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+
+ if(pDrView)
+ {
+ pDrView->setHideOle(!bDrawOle);
+ pDrView->setHideChart(!bDrawChart);
+ pDrView->setHideDraw(!bDrawDraw);
+ pDrView->setHideFormControl(!bDrawDraw);
+ }
+
+ if(SC_UPDATE_CHANGED == eMode)
+ {
+ rOutputData.DrawingSingle((sal_uInt16)nLayer);
+ }
+ else
+ {
+ rOutputData.DrawSelectiveObjects((sal_uInt16)nLayer);
+ }
+ }
+}
+
+void ScGridWindow::DrawSdrGrid( const Rectangle& rDrawingRect, OutputDevice* pContentDev )
+{
+ // Draw-Gitterlinien
+
+ ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+ if ( pDrView && pDrView->IsGridVisible() )
+ {
+ SdrPageView* pPV = pDrView->GetSdrPageView();
+ DBG_ASSERT(pPV, "keine PageView");
+ if (pPV)
+ {
+ pContentDev->SetLineColor(COL_GRAY);
+
+ pPV->DrawPageViewGrid( *pContentDev, rDrawingRect );
+ }
+ }
+}
+
+MapMode ScGridWindow::GetDrawMapMode( sal_Bool bForce )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ sal_Bool bNegativePage = pDoc->IsNegativePage( nTab );
+
+ MapMode aDrawMode = pViewData->GetLogicMode();
+
+ ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+ if ( pDrView || bForce )
+ {
+ Fraction aScaleX;
+ Fraction aScaleY;
+ if (pDrView)
+ pDrView->GetScale( aScaleX, aScaleY );
+ else
+ {
+ SCCOL nEndCol = 0;
+ SCROW nEndRow = 0;
+ pDoc->GetTableArea( nTab, nEndCol, nEndRow );
+ if (nEndCol<20) nEndCol = 20;
+ if (nEndRow<20) nEndRow = 1000;
+ ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, this,
+ pViewData->GetZoomX(),pViewData->GetZoomY(),
+ pViewData->GetPPTX(),pViewData->GetPPTY(),
+ aScaleX,aScaleY );
+ }
+ aDrawMode.SetScaleX(aScaleX);
+ aDrawMode.SetScaleY(aScaleY);
+ }
+ aDrawMode.SetOrigin(Point());
+ Point aStartPos = pViewData->GetPixPos(eWhich);
+ if ( bNegativePage )
+ {
+ // RTL uses negative positions for drawing objects
+ aStartPos.X() = -aStartPos.X() + GetOutputSizePixel().Width() - 1;
+ }
+ aDrawMode.SetOrigin( PixelToLogic( aStartPos, aDrawMode ) );
+
+ return aDrawMode;
+}
+
+//sal_Bool ScGridWindow::DrawBeforeScroll()
+//{
+// ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+//
+// sal_Bool bXor = sal_False;
+// if (pDrView)
+// {
+// bXor=pDrView->IsShownXorVisible(this);
+// if (bXor) pDrView->HideShownXor(this);
+// }
+// return bXor;
+//}
+
+void ScGridWindow::DrawAfterScroll(/*sal_Bool bVal*/)
+{
+ Update(); // immer, damit das Verhalten mit/ohne DrawingLayer gleich ist
+
+ ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+ if (pDrView)
+ {
+ //if (bVal)
+ // pDrView->ShowShownXor(this);
+
+ OutlinerView* pOlView = pDrView->GetTextEditOutlinerView();
+ if (pOlView && pOlView->GetWindow() == this)
+ pOlView->ShowCursor(sal_False); // ist beim Scrollen weggekommen
+ }
+}
+
+//void ScGridWindow::DrawMarks()
+//{
+// ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+// if (pDrView)
+// pDrView->DrawMarks(this);
+//}
+
+//sal_Bool ScGridWindow::NeedDrawMarks()
+//{
+// ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+// return pDrView && pDrView->IsMarkHdlShown() && pDrView->AreObjectsMarked();
+//}
+
+void ScGridWindow::CreateAnchorHandle(SdrHdlList& rHdl, const ScAddress& rAddress)
+{
+ ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+ if (pDrView)
+ {
+ const ScViewOptions& rOpts = pViewData->GetOptions();
+ if(rOpts.GetOption( VOPT_ANCHOR ))
+ {
+ sal_Bool bNegativePage = pViewData->GetDocument()->IsNegativePage( pViewData->GetTabNo() );
+ Point aPos = pViewData->GetScrPos( rAddress.Col(), rAddress.Row(), eWhich, sal_True );
+ aPos = PixelToLogic(aPos);
+ rHdl.AddHdl(new SdrHdl(aPos, bNegativePage ? HDL_ANCHOR_TR : HDL_ANCHOR));
+ }
+ }
+}
+
+SdrObject* ScGridWindow::GetEditObject()
+{
+ ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+ if (pDrView)
+ {
+ OutlinerView* pOlView = pDrView->GetTextEditOutlinerView();
+ if (pOlView && pOlView->GetWindow() == this)
+ return pDrView->GetTextEditObject();
+ }
+
+ return NULL;
+}
+
+void ScGridWindow::UpdateStatusPosSize()
+{
+ ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+ if (!pDrView)
+ return; // shouldn't be called in that case
+
+ SdrPageView* pPV = pDrView->GetSdrPageView();
+ if (!pPV)
+ return; // shouldn't be called in that case either
+
+ SfxItemSet aSet(pViewData->GetViewShell()->GetPool(), SID_ATTR_POSITION, SID_ATTR_SIZE);
+
+ // Fill items for position and size:
+ // #108137# show action rectangle during action,
+ // position and size of selected object(s) if something is selected,
+ // mouse position otherwise
+
+ sal_Bool bActionItem = sal_False;
+ if ( pDrView->IsAction() ) // action rectangle
+ {
+ Rectangle aRect;
+ pDrView->TakeActionRect( aRect );
+ if ( !aRect.IsEmpty() )
+ {
+ pPV->LogicToPagePos(aRect);
+ aSet.Put( SfxPointItem( SID_ATTR_POSITION, aRect.TopLeft() ) );
+ aSet.Put( SvxSizeItem( SID_ATTR_SIZE,
+ Size( aRect.Right() - aRect.Left(), aRect.Bottom() - aRect.Top() ) ) );
+ bActionItem = sal_True;
+ }
+ }
+ if ( !bActionItem )
+ {
+ if ( pDrView->AreObjectsMarked() ) // selected objects
+ {
+ Rectangle aRect = pDrView->GetAllMarkedRect();
+ pPV->LogicToPagePos(aRect);
+ aSet.Put( SfxPointItem( SID_ATTR_POSITION, aRect.TopLeft() ) );
+ aSet.Put( SvxSizeItem( SID_ATTR_SIZE,
+ Size( aRect.Right() - aRect.Left(), aRect.Bottom() - aRect.Top() ) ) );
+ }
+ else // mouse position
+ {
+ Point aPos = PixelToLogic(aCurMousePos);
+ pPV->LogicToPagePos(aPos);
+ aSet.Put( SfxPointItem( SID_ATTR_POSITION, aPos ) );
+ aSet.Put( SvxSizeItem( SID_ATTR_SIZE, Size( 0, 0 ) ) );
+ }
+ }
+
+ pViewData->GetBindings().SetState(aSet);
+}
+
+sal_Bool ScGridWindow::DrawHasMarkedObj()
+{
+ ScDrawView* p = pViewData->GetScDrawView();
+ return p ? p->AreObjectsMarked() : sal_False;
+}
+
+//void ScGridWindow::DrawStartTimer()
+//{
+ //ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+ //if (pDrView)
+ //{
+ /* jetzt in DrawMarks
+ sal_uInt16 nWinNum = pDrView->FindWin(this);
+ if (nWinNum!=SDRVIEWWIN_NOTFOUND)
+ pDrView->AfterInitRedraw(nWinNum);
+ */
+
+ // pDrView->PostPaint();
+ // pDrView->RestartAfterPaintTimer();
+ //}
+//}
+
+void ScGridWindow::DrawMarkDropObj( SdrObject* pObj )
+{
+ ScDrawView* pDrView = pViewData->GetView()->GetScDrawView();
+ if (pDrView)
+ pDrView->MarkDropObj(pObj);
+}
+
+
+
diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
new file mode 100644
index 000000000000..8e0e964de821
--- /dev/null
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -0,0 +1,2069 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <svtools/colorcfg.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/printer.hxx>
+
+#include <svx/svdview.hxx>
+#include "tabvwsh.hxx"
+
+#include "gridwin.hxx"
+#include "viewdata.hxx"
+#include "output.hxx"
+#include "document.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx" // InvertSimple
+#include "dbcolect.hxx"
+#include "docoptio.hxx"
+#include "notemark.hxx"
+#include "dbfunc.hxx" // oder GetPageBreakData an die ViewData
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+#include "rfindlst.hxx"
+#include "hiranges.hxx"
+#include "pagedata.hxx"
+#include "docpool.hxx"
+#include "globstr.hrc"
+#include "docsh.hxx" // oder GetSfxInPlaceObject
+#include "cbutton.hxx"
+#include "invmerge.hxx"
+#include "editutil.hxx"
+#include "inputopt.hxx"
+#include "fillinfo.hxx"
+#include "dpcontrol.hxx"
+#include "queryparam.hxx"
+#include "sc.hrc"
+#include <vcl/virdev.hxx>
+
+// #i74769#
+#include <svx/sdrpaintwindow.hxx>
+
+//#include "tabvwsh.hxx" //! Test !!!!
+
+//------------------------------------------------------------------------
+
+void lcl_LimitRect( Rectangle& rRect, const Rectangle& rVisible )
+{
+ if ( rRect.Top() < rVisible.Top()-1 ) rRect.Top() = rVisible.Top()-1;
+// if ( rRect.Left() < rVisible.Left()-1 ) rRect.Left() = rVisible.Left()-1;
+ if ( rRect.Bottom() > rVisible.Bottom()+1 ) rRect.Bottom() = rVisible.Bottom()+1;
+// if ( rRect.Right() > rVisible.Right()+1 ) rRect.Right() = rVisible.Right()+1;
+
+ // #51122# auch wenn das inner-Rectangle nicht sichtbar ist, muss evtl.
+ // die Titelzeile gezeichnet werden, darum kein Rueckgabewert mehr.
+ // Wenn's weit daneben liegt, wird lcl_DrawOneFrame erst gar nicht gerufen.
+}
+
+void lcl_DrawOneFrame( OutputDevice* pDev, const Rectangle& rInnerPixel,
+ const String& rTitle, const Color& rColor, sal_Bool bTextBelow,
+ double nPPTX, double nPPTY, const Fraction& rZoomY,
+ ScDocument* pDoc, ScViewData* pButtonViewData, sal_Bool bLayoutRTL )
+{
+ // pButtonViewData wird nur benutzt, um die Button-Groesse zu setzen,
+ // darf ansonsten NULL sein!
+
+ Rectangle aInner = rInnerPixel;
+ if ( bLayoutRTL )
+ {
+ aInner.Left() = rInnerPixel.Right();
+ aInner.Right() = rInnerPixel.Left();
+ }
+
+ Rectangle aVisible( Point(0,0), pDev->GetOutputSizePixel() );
+ lcl_LimitRect( aInner, aVisible );
+
+ Rectangle aOuter = aInner;
+ long nHor = (long) ( SC_SCENARIO_HSPACE * nPPTX );
+ long nVer = (long) ( SC_SCENARIO_VSPACE * nPPTY );
+ aOuter.Left() -= nHor;
+ aOuter.Right() += nHor;
+ aOuter.Top() -= nVer;
+ aOuter.Bottom() += nVer;
+
+ // use ScPatternAttr::GetFont only for font size
+ Font aAttrFont;
+ ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).
+ GetFont(aAttrFont,SC_AUTOCOL_BLACK,pDev,&rZoomY);
+
+ // everything else from application font
+ Font aAppFont = pDev->GetSettings().GetStyleSettings().GetAppFont();
+ aAppFont.SetSize( aAttrFont.GetSize() );
+
+ aAppFont.SetAlign( ALIGN_TOP );
+ pDev->SetFont( aAppFont );
+
+ Size aTextSize( pDev->GetTextWidth( rTitle ), pDev->GetTextHeight() );
+
+ if ( bTextBelow )
+ aOuter.Bottom() += aTextSize.Height();
+ else
+ aOuter.Top() -= aTextSize.Height();
+
+ pDev->SetLineColor();
+ pDev->SetFillColor( rColor );
+ // links, oben, rechts, unten
+ pDev->DrawRect( Rectangle( aOuter.Left(), aOuter.Top(), aInner.Left(), aOuter.Bottom() ) );
+ pDev->DrawRect( Rectangle( aOuter.Left(), aOuter.Top(), aOuter.Right(), aInner.Top() ) );
+ pDev->DrawRect( Rectangle( aInner.Right(), aOuter.Top(), aOuter.Right(), aOuter.Bottom() ) );
+ pDev->DrawRect( Rectangle( aOuter.Left(), aInner.Bottom(), aOuter.Right(), aOuter.Bottom() ) );
+
+ long nButtonY = bTextBelow ? aInner.Bottom() : aOuter.Top();
+
+ ScDDComboBoxButton aComboButton((Window*)pDev);
+ aComboButton.SetOptSizePixel();
+ long nBWidth = ( aComboButton.GetSizePixel().Width() * rZoomY.GetNumerator() )
+ / rZoomY.GetDenominator();
+ long nBHeight = nVer + aTextSize.Height() + 1;
+ Size aButSize( nBWidth, nBHeight );
+ long nButtonPos = bLayoutRTL ? aOuter.Left() : aOuter.Right()-nBWidth+1;
+ aComboButton.Draw( Point(nButtonPos, nButtonY), aButSize, sal_False );
+ if (pButtonViewData)
+ pButtonViewData->SetScenButSize( aButSize );
+
+ long nTextStart = bLayoutRTL ? aInner.Right() - aTextSize.Width() + 1 : aInner.Left();
+
+ sal_Bool bWasClip = sal_False;
+ Region aOldClip;
+ sal_Bool bClip = ( aTextSize.Width() > aOuter.Right() - nBWidth - aInner.Left() );
+ if ( bClip )
+ {
+ if (pDev->IsClipRegion())
+ {
+ bWasClip = sal_True;
+ aOldClip = pDev->GetActiveClipRegion();
+ }
+ long nClipStartX = bLayoutRTL ? aOuter.Left() + nBWidth : aInner.Left();
+ long nClipEndX = bLayoutRTL ? aInner.Right() : aOuter.Right() - nBWidth;
+ pDev->SetClipRegion( Rectangle( nClipStartX, nButtonY + nVer/2,
+ nClipEndX, nButtonY + nVer/2 + aTextSize.Height() ) );
+ }
+
+ pDev->DrawText( Point( nTextStart, nButtonY + nVer/2 ), rTitle );
+
+ if ( bClip )
+ {
+ if ( bWasClip )
+ pDev->SetClipRegion(aOldClip);
+ else
+ pDev->SetClipRegion();
+ }
+
+ pDev->SetFillColor();
+ pDev->SetLineColor( COL_BLACK );
+ pDev->DrawRect( aInner );
+ pDev->DrawRect( aOuter );
+}
+
+void lcl_DrawScenarioFrames( OutputDevice* pDev, ScViewData* pViewData, ScSplitPos eWhich,
+ SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ if ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) )
+ {
+ if ( nX1 > 0 ) --nX1;
+ if ( nY1>=2 ) nY1 -= 2; // Hack: Titelzeile beruehrt zwei Zellen
+ else if ( nY1 > 0 ) --nY1;
+ if ( nX2 < MAXCOL ) ++nX2;
+ if ( nY2 < MAXROW-1 ) nY2 += 2; // Hack: Titelzeile beruehrt zwei Zellen
+ else if ( nY2 < MAXROW ) ++nY2;
+ ScRange aViewRange( nX1,nY1,nTab, nX2,nY2,nTab );
+
+ //! Ranges an der Table cachen!!!!
+
+ ScMarkData aMarks;
+ for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
+ pDoc->MarkScenario( i, nTab, aMarks, sal_False, SC_SCENARIO_SHOWFRAME );
+ ScRangeListRef xRanges = new ScRangeList;
+ aMarks.FillRangeListWithMarks( xRanges, sal_False );
+
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ sal_uInt16 nRangeCount = (sal_uInt16)xRanges->Count();
+ for (sal_uInt16 j=0; j<nRangeCount; j++)
+ {
+ ScRange aRange = *xRanges->GetObject(j);
+ // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
+ // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
+ pDoc->ExtendTotalMerge( aRange );
+
+ //! -> Repaint beim Zusammenfassen erweitern !!!
+
+ if ( aRange.Intersects( aViewRange ) ) //! Platz fuer Text/Button?
+ {
+ Point aStartPos = pViewData->GetScrPos(
+ aRange.aStart.Col(), aRange.aStart.Row(), eWhich, sal_True );
+ Point aEndPos = pViewData->GetScrPos(
+ aRange.aEnd.Col()+1, aRange.aEnd.Row()+1, eWhich, sal_True );
+ // on the grid:
+ aStartPos.X() -= nLayoutSign;
+ aStartPos.Y() -= 1;
+ aEndPos.X() -= nLayoutSign;
+ aEndPos.Y() -= 1;
+
+ sal_Bool bTextBelow = ( aRange.aStart.Row() == 0 );
+
+ String aCurrent;
+ Color aColor( COL_LIGHTGRAY );
+ for (SCTAB nAct=nTab+1; nAct<nTabCount && pDoc->IsScenario(nAct); nAct++)
+ if ( pDoc->IsActiveScenario(nAct) && pDoc->HasScenarioRange(nAct,aRange) )
+ {
+ String aDummyComment;
+ sal_uInt16 nDummyFlags;
+ pDoc->GetName( nAct, aCurrent );
+ pDoc->GetScenarioData( nAct, aDummyComment, aColor, nDummyFlags );
+ }
+
+ if (!aCurrent.Len())
+ aCurrent = ScGlobal::GetRscString( STR_EMPTYDATA );
+
+ //! eigener Text "(keins)" statt "(leer)" ???
+
+ lcl_DrawOneFrame( pDev, Rectangle( aStartPos, aEndPos ),
+ aCurrent, aColor, bTextBelow,
+ pViewData->GetPPTX(), pViewData->GetPPTY(), pViewData->GetZoomY(),
+ pDoc, pViewData, bLayoutRTL );
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+void lcl_DrawHighlight( ScOutputData& rOutputData, ScViewData* pViewData,
+ ScHighlightRanges& rHighlightRanges )
+{
+ SCTAB nTab = pViewData->GetTabNo();
+ sal_uLong nCount = rHighlightRanges.Count();
+ for (sal_uLong i=0; i<nCount; i++)
+ {
+ ScHighlightEntry* pEntry = rHighlightRanges.GetObject( i );
+ if (pEntry)
+ {
+ ScRange aRange = pEntry->aRef;
+ if ( nTab >= aRange.aStart.Tab() && nTab <= aRange.aEnd.Tab() )
+ {
+ rOutputData.DrawRefMark(
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(),
+ pEntry->aColor, sal_False );
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+void ScGridWindow::DoInvertRect( const Rectangle& rPixel )
+{
+// Invert( PixelToLogic(rPixel) );
+
+ if ( rPixel == aInvertRect )
+ aInvertRect = Rectangle(); // aufheben
+ else
+ {
+ DBG_ASSERT( aInvertRect.IsEmpty(), "DoInvertRect nicht paarig" );
+
+ aInvertRect = rPixel; // neues Rechteck merken
+ }
+
+ UpdateHeaderOverlay(); // uses aInvertRect
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScGridWindow::PrePaint()
+{
+ // forward PrePaint to DrawingLayer
+ ScTabViewShell* pTabViewShell = pViewData->GetViewShell();
+
+ if(pTabViewShell)
+ {
+ SdrView* pDrawView = pTabViewShell->GetSdrView();
+
+ if(pDrawView)
+ {
+ pDrawView->PrePaint();
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScGridWindow::Paint( const Rectangle& rRect )
+{
+ //TODO/LATER: how to get environment? Do we need that?!
+ /*
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ SvInPlaceEnvironment* pEnv = pDocSh->GetIPEnv();
+ if (pEnv && pEnv->GetRectsChangedLockCount())
+ {
+ Invalidate(rRect);
+ return;
+ }*/
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ if ( pDoc->IsInInterpreter() )
+ {
+ // via Reschedule, interpretierende Zellen nicht nochmal anstossen
+ // hier kein Invalidate, sonst kommt z.B. eine Error-Box nie an die Reihe
+ // (Bug 36381). Durch bNeedsRepaint wird spaeter alles nochmal gemalt.
+
+ if ( bNeedsRepaint )
+ {
+ //! Rechtecke zusammenfassen?
+ aRepaintPixel = Rectangle(); // mehrfach -> alles painten
+ }
+ else
+ {
+ bNeedsRepaint = sal_True;
+ aRepaintPixel = LogicToPixel(rRect); // nur betroffenen Bereich
+ }
+ return;
+ }
+
+ if (bIsInPaint)
+ return;
+
+ bIsInPaint = sal_True;
+
+ Rectangle aPixRect = LogicToPixel( rRect );
+
+ SCCOL nX1 = pViewData->GetPosX(eHWhich);
+ SCROW nY1 = pViewData->GetPosY(eVWhich);
+
+ SCTAB nTab = pViewData->GetTabNo();
+
+ double nPPTX = pViewData->GetPPTX();
+ double nPPTY = pViewData->GetPPTY();
+
+ Rectangle aMirroredPixel = aPixRect;
+ if ( pDoc->IsLayoutRTL( nTab ) )
+ {
+ // mirror and swap
+ long nWidth = GetSizePixel().Width();
+ aMirroredPixel.Left() = nWidth - 1 - aPixRect.Right();
+ aMirroredPixel.Right() = nWidth - 1 - aPixRect.Left();
+ }
+
+ long nScrX = ScViewData::ToPixel( pDoc->GetColWidth( nX1, nTab ), nPPTX );
+ while ( nScrX <= aMirroredPixel.Left() && nX1 < MAXCOL )
+ {
+ ++nX1;
+ nScrX += ScViewData::ToPixel( pDoc->GetColWidth( nX1, nTab ), nPPTX );
+ }
+ SCCOL nX2 = nX1;
+ while ( nScrX <= aMirroredPixel.Right() && nX2 < MAXCOL )
+ {
+ ++nX2;
+ nScrX += ScViewData::ToPixel( pDoc->GetColWidth( nX2, nTab ), nPPTX );
+ }
+
+ long nScrY = 0;
+ ScViewData::AddPixelsWhile( nScrY, aPixRect.Top(), nY1, MAXROW, nPPTY, pDoc, nTab);
+ SCROW nY2 = nY1;
+ if (nScrY <= aPixRect.Bottom() && nY2 < MAXROW)
+ {
+ ++nY2;
+ ScViewData::AddPixelsWhile( nScrY, aPixRect.Bottom(), nY2, MAXROW, nPPTY, pDoc, nTab);
+ }
+
+ Draw( nX1,nY1,nX2,nY2, SC_UPDATE_MARKS ); // nicht weiterzeichnen
+
+ bIsInPaint = sal_False;
+}
+
+//
+// Draw ----------------------------------------------------------------
+//
+
+void ScGridWindow::Draw( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, ScUpdateMode eMode )
+{
+ ScModule* pScMod = SC_MOD();
+ sal_Bool bTextWysiwyg = pScMod->GetInputOptions().GetTextWysiwyg();
+ sal_Bool bGridFirst = sal_True; //! entscheiden!!!
+
+ if (pViewData->IsMinimized())
+ return;
+
+ PutInOrder( nX1, nX2 );
+ PutInOrder( nY1, nY2 );
+
+ DBG_ASSERT( ValidCol(nX2) && ValidRow(nY2), "GridWin Draw Bereich zu gross" );
+
+ SCCOL nPosX = pViewData->GetPosX( eHWhich );
+ SCROW nPosY = pViewData->GetPosY( eVWhich );
+ if (nX2 < nPosX || nY2 < nPosY)
+ return; // unsichtbar
+ if (nX1 < nPosX) nX1 = nPosX;
+ if (nY1 < nPosY) nY1 = nPosY;
+
+ SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich);
+ if (nXRight > MAXCOL) nXRight = MAXCOL;
+ 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;
+ if (nY2 > nYBottom) nY2 = nYBottom;
+
+ if ( eMode != SC_UPDATE_MARKS )
+ if (nX2 < nXRight)
+ nX2 = nXRight; // zum Weiterzeichnen
+
+ // ab hier kein return mehr
+
+ ++nPaintCount; // merken, dass gemalt wird (wichtig beim Invertieren)
+
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+
+ pDoc->ExtendHidden( nX1, nY1, nX2, nY2, nTab );
+
+ Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich );
+ long nMirrorWidth = GetSizePixel().Width();
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+ if ( bLayoutRTL )
+ {
+ long nEndPixel = pViewData->GetScrPos( nX2+1, nPosY, eWhich ).X();
+ nMirrorWidth = aScrPos.X() - nEndPixel;
+ aScrPos.X() = nEndPixel + 1;
+ }
+
+ long nScrX = aScrPos.X();
+ long nScrY = aScrPos.Y();
+
+ SCCOL nCurX = pViewData->GetCurX();
+ SCROW nCurY = pViewData->GetCurY();
+ SCCOL nCurEndX = nCurX;
+ SCROW nCurEndY = nCurY;
+ pDoc->ExtendMerge( nCurX, nCurY, nCurEndX, nCurEndY, nTab );
+ sal_Bool bCurVis = nCursorHideCount==0 &&
+ ( nCurEndX+1 >= nX1 && nCurX <= nX2+1 && nCurEndY+1 >= nY1 && nCurY <= nY2+1 );
+
+ // AutoFill-Anfasser
+ if ( !bCurVis && nCursorHideCount==0 && bAutoMarkVisible && aAutoMarkPos.Tab() == nTab &&
+ ( aAutoMarkPos.Col() != nCurX || aAutoMarkPos.Row() != nCurY ) )
+ {
+ SCCOL nHdlX = aAutoMarkPos.Col();
+ SCROW nHdlY = aAutoMarkPos.Row();
+ pDoc->ExtendMerge( nHdlX, nHdlY, nHdlX, nHdlY, nTab );
+ bCurVis = ( nHdlX+1 >= nX1 && nHdlX <= nX2 && nHdlY+1 >= nY1 && nHdlY <= nY2 );
+ // links und oben ist nicht betroffen
+
+ //! AutoFill-Anfasser alleine (ohne Cursor) zeichnen ???
+ }
+
+ double nPPTX = pViewData->GetPPTX();
+ double nPPTY = pViewData->GetPPTY();
+
+ const ScViewOptions& rOpts = pViewData->GetOptions();
+ sal_Bool bFormulaMode = rOpts.GetOption( VOPT_FORMULAS );
+ sal_Bool bMarkClipped = rOpts.GetOption( VOPT_CLIPMARKS );
+
+ // Datenblock
+
+ ScTableInfo aTabInfo;
+ pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab,
+ nPPTX, nPPTY, sal_False, bFormulaMode,
+ &pViewData->GetMarkData() );
+
+ //--------------------------------------------------------------------
+
+ Fraction aZoomX = pViewData->GetZoomX();
+ Fraction aZoomY = pViewData->GetZoomY();
+ ScOutputData aOutputData( this, OUTTYPE_WINDOW, aTabInfo, pDoc, nTab,
+ nScrX, nScrY, nX1, nY1, nX2, nY2, nPPTX, nPPTY,
+ &aZoomX, &aZoomY );
+
+ aOutputData.SetMirrorWidth( nMirrorWidth ); // needed for RTL
+
+ std::auto_ptr< VirtualDevice > xFmtVirtDev;
+ sal_Bool bLogicText = bTextWysiwyg; // call DrawStrings in logic MapMode?
+
+ if ( bTextWysiwyg )
+ {
+ // use printer for text formatting
+
+ OutputDevice* pFmtDev = pDoc->GetPrinter();
+ pFmtDev->SetMapMode( pViewData->GetLogicMode(eWhich) );
+ aOutputData.SetFmtDevice( pFmtDev );
+ }
+ else if ( aZoomX != aZoomY && pViewData->IsOle() )
+ {
+ // #i45033# For OLE inplace editing with different zoom factors,
+ // use a virtual device with 1/100th mm as text formatting reference
+
+ xFmtVirtDev.reset( new VirtualDevice );
+ xFmtVirtDev->SetMapMode( MAP_100TH_MM );
+ aOutputData.SetFmtDevice( xFmtVirtDev.get() );
+
+ bLogicText = sal_True; // use logic MapMode
+ }
+
+ const svtools::ColorConfig& rColorCfg = pScMod->GetColorConfig();
+ Color aGridColor( rColorCfg.GetColorValue( svtools::CALCGRID, sal_False ).nColor );
+ if ( aGridColor.GetColor() == COL_TRANSPARENT )
+ {
+ // use view options' grid color only if color config has "automatic" color
+ aGridColor = rOpts.GetGridColor();
+ }
+
+ aOutputData.SetSyntaxMode ( pViewData->IsSyntaxMode() );
+ aOutputData.SetGridColor ( aGridColor );
+ aOutputData.SetShowNullValues ( rOpts.GetOption( VOPT_NULLVALS ) );
+ aOutputData.SetShowFormulas ( bFormulaMode );
+ aOutputData.SetShowSpellErrors ( pDoc->GetDocOptions().IsAutoSpell() );
+ aOutputData.SetMarkClipped ( bMarkClipped );
+
+ aOutputData.SetUseStyleColor( sal_True ); // always set in table view
+
+ aOutputData.SetEditObject( GetEditObject() );
+ aOutputData.SetViewShell( pViewData->GetViewShell() );
+
+ sal_Bool bGrid = rOpts.GetOption( VOPT_GRID );
+ sal_Bool bPage = rOpts.GetOption( VOPT_PAGEBREAKS );
+
+ if ( eMode == SC_UPDATE_CHANGED )
+ {
+ aOutputData.FindChanged();
+ aOutputData.SetSingleGrid(sal_True);
+ }
+
+ sal_Bool bPageMode = pViewData->IsPagebreakMode();
+ if (bPageMode) // nach FindChanged
+ {
+ // SetPagebreakMode initialisiert auch bPrinted Flags
+ aOutputData.SetPagebreakMode( pViewData->GetView()->GetPageBreakData() );
+ }
+
+ EditView* pEditView = NULL;
+ sal_Bool bEditMode = pViewData->HasEditView(eWhich);
+ if ( bEditMode && pViewData->GetRefTabNo() == nTab )
+ {
+ SCCOL nEditCol;
+ SCROW nEditRow;
+ pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
+ SCCOL nEditEndCol = pViewData->GetEditEndCol();
+ SCROW nEditEndRow = pViewData->GetEditEndRow();
+
+ if ( nEditEndCol >= nX1 && nEditCol <= nX2 && nEditEndRow >= nY1 && nEditRow <= nY2 )
+ aOutputData.SetEditCell( nEditCol, nEditRow );
+ else
+ bEditMode = sal_False;
+
+ // nur Edit-Area zu zeichnen?
+ //! dann muss trotzdem noch der Rand / das Gitter gemalt werden!
+
+// if ( nEditCol <= nX1 && nEditEndCol >= nX2 && nEditRow <= nY1 && nEditEndRow >= nY2 )
+// bOnlyEdit = sal_True;
+ }
+
+ // define drawing layer map mode and paint rectangle
+ const MapMode aDrawMode = GetDrawMapMode();
+ Rectangle aDrawingRectLogic;
+
+ {
+ // get drawing pixel rect
+ Rectangle aDrawingRectPixel(Point(nScrX, nScrY), Size(aOutputData.GetScrW(), aOutputData.GetScrH()));
+
+ // correct for border (left/right)
+ if(MAXCOL == nX2)
+ {
+ if(bLayoutRTL)
+ {
+ aDrawingRectPixel.Left() = 0L;
+ }
+ else
+ {
+ aDrawingRectPixel.Right() = GetOutputSizePixel().getWidth();
+ }
+ }
+
+ // correct for border (bottom)
+ if(MAXROW == nY2)
+ {
+ aDrawingRectPixel.Bottom() = GetOutputSizePixel().getHeight();
+ }
+
+ // get logic positions
+ aDrawingRectLogic = PixelToLogic(aDrawingRectPixel, aDrawMode);
+ }
+
+// not necessary with overlay
+// if (bCurVis)
+// HideCursor();
+
+ OutputDevice* pContentDev = this; // device for document content, used by overlay manager
+ SdrPaintWindow* pTargetPaintWindow = 0; // #i74769# work with SdrPaintWindow directly
+
+ {
+ // init redraw
+ ScTabViewShell* pTabViewShell = pViewData->GetViewShell();
+
+ if(pTabViewShell)
+ {
+ MapMode aCurrentMapMode(pContentDev->GetMapMode());
+ pContentDev->SetMapMode(aDrawMode);
+ SdrView* pDrawView = pTabViewShell->GetSdrView();
+
+ if(pDrawView)
+ {
+ // #i74769# Use new BeginDrawLayers() interface
+ Region aDrawingRegion(aDrawingRectLogic);
+ pTargetPaintWindow = pDrawView->BeginDrawLayers(this, aDrawingRegion);
+ OSL_ENSURE(pTargetPaintWindow, "BeginDrawLayers: Got no SdrPaintWindow (!)");
+
+ // #i74769# get target device from SdrPaintWindow, this may be the prerender
+ // device now, too.
+ pContentDev = &(pTargetPaintWindow->GetTargetOutputDevice());
+ aOutputData.SetContentDevice( pContentDev );
+ }
+
+ pContentDev->SetMapMode(aCurrentMapMode);
+ }
+ }
+
+ // Rand (Wiese) (Pixel)
+ if ( nX2==MAXCOL || nY2==MAXROW )
+ {
+ // save MapMode and set to pixel
+ MapMode aCurrentMapMode(pContentDev->GetMapMode());
+ pContentDev->SetMapMode(MAP_PIXEL);
+
+ Rectangle aPixRect = Rectangle( Point(), GetOutputSizePixel() );
+ pContentDev->SetFillColor( rColorCfg.GetColorValue(svtools::APPBACKGROUND).nColor );
+ pContentDev->SetLineColor();
+ if ( nX2==MAXCOL )
+ {
+ Rectangle aDrawRect( aPixRect );
+ if ( bLayoutRTL )
+ aDrawRect.Right() = nScrX - 1;
+ else
+ aDrawRect.Left() = nScrX + aOutputData.GetScrW();
+ if (aDrawRect.Right() >= aDrawRect.Left())
+ pContentDev->DrawRect( aDrawRect );
+ }
+ if ( nY2==MAXROW )
+ {
+ Rectangle aDrawRect( aPixRect );
+ aDrawRect.Top() = nScrY + aOutputData.GetScrH();
+ if ( nX2==MAXCOL )
+ {
+ // no double painting of the corner
+ if ( bLayoutRTL )
+ aDrawRect.Left() = nScrX;
+ else
+ aDrawRect.Right() = nScrX + aOutputData.GetScrW() - 1;
+ }
+ if (aDrawRect.Bottom() >= aDrawRect.Top())
+ pContentDev->DrawRect( aDrawRect );
+ }
+
+ // restore MapMode
+ pContentDev->SetMapMode(aCurrentMapMode);
+ }
+
+ if ( pDoc->HasBackgroundDraw( nTab, aDrawingRectLogic ) )
+ {
+ pContentDev->SetMapMode(MAP_PIXEL);
+ aOutputData.DrawClear();
+
+ // Drawing Hintergrund
+
+ pContentDev->SetMapMode(aDrawMode);
+ DrawRedraw( aOutputData, eMode, SC_LAYER_BACK );
+ }
+ else
+ aOutputData.SetSolidBackground(sal_True);
+
+ pContentDev->SetMapMode(MAP_PIXEL);
+ aOutputData.DrawBackground();
+ if ( bGridFirst && ( bGrid || bPage ) )
+ aOutputData.DrawGrid( bGrid, bPage );
+ if ( bPageMode )
+ {
+ // #87655# DrawPagePreview draws complete lines/page numbers, must always be clipped
+ if ( aOutputData.SetChangedClip() )
+ {
+ DrawPagePreview(nX1,nY1,nX2,nY2, pContentDev);
+ pContentDev->SetClipRegion();
+ }
+ }
+ aOutputData.DrawShadow();
+ aOutputData.DrawFrame();
+ if ( !bLogicText )
+ aOutputData.DrawStrings(sal_False); // in pixel MapMode
+
+ // edit cells and printer-metrics text must be before the buttons
+ // (DataPilot buttons contain labels in UI font)
+
+ pContentDev->SetMapMode(pViewData->GetLogicMode(eWhich));
+ if ( bLogicText )
+ aOutputData.DrawStrings(sal_True); // in logic MapMode if bTextWysiwyg is set
+ aOutputData.DrawEdit(sal_True);
+ pContentDev->SetMapMode(MAP_PIXEL);
+
+ // Autofilter- und Pivot-Buttons
+
+ DrawButtons( nX1, nY1, nX2, nY2, aTabInfo, pContentDev ); // Pixel
+
+ // Notiz-Anzeiger
+
+ if ( rOpts.GetOption( VOPT_NOTES ) )
+ aOutputData.DrawNoteMarks();
+
+ if ( !bGridFirst && ( bGrid || bPage ) )
+ {
+ aOutputData.DrawGrid( bGrid, bPage );
+ }
+ aOutputData.DrawClipMarks();
+
+ // Szenario / ChangeTracking muss auf jeden Fall nach DrawGrid sein, auch bei !bGridFirst
+
+ //! Test, ob ChangeTrack-Anzeige aktiv ist
+ //! Szenario-Rahmen per View-Optionen abschaltbar?
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ ScHighlightRanges* pHigh = pViewData->GetView()->GetHighlightRanges();
+ sal_Bool bHasScenario = ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) );
+ sal_Bool bHasChange = ( pDoc->GetChangeTrack() != NULL );
+
+ if ( bHasChange || bHasScenario || pHigh != NULL )
+ {
+
+ //! SetChangedClip() mit DrawMarks() zusammenfassen?? (anderer MapMode!)
+
+ sal_Bool bAny = sal_True;
+ if (eMode == SC_UPDATE_CHANGED)
+ bAny = aOutputData.SetChangedClip();
+ if (bAny)
+ {
+ if ( bHasChange )
+ aOutputData.DrawChangeTrack();
+
+ if ( bHasScenario )
+ lcl_DrawScenarioFrames( pContentDev, pViewData, eWhich, nX1,nY1,nX2,nY2 );
+
+ if ( pHigh )
+ lcl_DrawHighlight( aOutputData, pViewData, *pHigh );
+
+ if (eMode == SC_UPDATE_CHANGED)
+ pContentDev->SetClipRegion();
+ }
+ }
+
+ // Drawing Vordergrund
+
+ pContentDev->SetMapMode(aDrawMode);
+
+ DrawRedraw( aOutputData, eMode, SC_LAYER_FRONT );
+ DrawRedraw( aOutputData, eMode, SC_LAYER_INTERN );
+ DrawSdrGrid( aDrawingRectLogic, pContentDev );
+
+ if (!bIsInScroll) // Drawing Markierungen
+ {
+ if(eMode == SC_UPDATE_CHANGED && aOutputData.SetChangedClip())
+ {
+ pContentDev->SetClipRegion();
+ }
+
+ //sal_Bool bDraw = sal_True;
+ //if (eMode == SC_UPDATE_CHANGED)
+ // bDraw = NeedDrawMarks() && aOutputData.SetChangedClip();
+ //if (bDraw)
+ //{
+ // DrawMarks();
+ // if (eMode == SC_UPDATE_CHANGED)
+ // pContentDev->SetClipRegion();
+ //}
+ }
+
+ pContentDev->SetMapMode(MAP_PIXEL);
+
+#ifdef OLD_SELECTION_PAINT
+ if (pViewData->IsActive())
+ aOutputData.DrawMark( this );
+#endif
+
+ if ( pViewData->IsRefMode() && nTab >= pViewData->GetRefStartZ() && nTab <= pViewData->GetRefEndZ() )
+ {
+ // The AutoFill shrink area has an own overlay now
+#if 0
+ // Schraffur beim Loeschen per AutoFill
+ if ( pViewData->GetRefType() == SC_REFTYPE_FILL )
+ {
+ ScRange aRange;
+ if ( pViewData->GetDelMark( aRange ) )
+ {
+ if ( aRange.aStart.Col() < nX1 ) aRange.aStart.SetCol(nX1);
+ if ( aRange.aEnd.Col() > nX2 ) aRange.aEnd.SetCol(nX2);
+ if ( aRange.aStart.Row() < nY1 ) aRange.aStart.SetRow(nY1);
+ if ( aRange.aEnd.Row() > nY2 ) aRange.aEnd.SetRow(nY2);
+ if ( aRange.aStart.Col() <= aRange.aEnd.Col() &&
+ aRange.aStart.Row() <= aRange.aEnd.Row() )
+ {
+ Point aStart = pViewData->GetScrPos( aRange.aStart.Col(),
+ aRange.aStart.Row(), eWhich );
+ Point aEnd = pViewData->GetScrPos( aRange.aEnd.Col()+1,
+ aRange.aEnd.Row()+1, eWhich );
+ aEnd.X() -= 1;
+ aEnd.Y() -= 1;
+
+ // Markierung aufheben - roter Rahmen bleibt stehen
+ Rectangle aRect( aStart,aEnd );
+ Invert( aRect, INVERT_HIGHLIGHT );
+
+ //! Delete-Bereich extra kennzeichnen?!?!?
+ }
+ }
+ }
+#endif
+
+ Color aRefColor( rColorCfg.GetColorValue(svtools::CALCREFERENCE).nColor );
+ aOutputData.DrawRefMark( pViewData->GetRefStartX(), pViewData->GetRefStartY(),
+ pViewData->GetRefEndX(), pViewData->GetRefEndY(),
+ aRefColor, sal_False );
+ }
+
+ // Range-Finder
+
+ ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
+ if (pHdl)
+ {
+ ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
+ if ( pRangeFinder && !pRangeFinder->IsHidden() &&
+ pRangeFinder->GetDocName() == pDocSh->GetTitle() )
+ {
+ sal_uInt16 nCount = (sal_uInt16)pRangeFinder->Count();
+ for (sal_uInt16 i=0; i<nCount; i++)
+ {
+ ScRangeFindData* pData = pRangeFinder->GetObject(i);
+ if (pData)
+ {
+ ScRange aRef = pData->aRef;
+ aRef.Justify();
+ if ( aRef.aStart.Tab() >= nTab && aRef.aEnd.Tab() <= nTab )
+ aOutputData.DrawRefMark( aRef.aStart.Col(), aRef.aStart.Row(),
+ aRef.aEnd.Col(), aRef.aEnd.Row(),
+ Color( ScRangeFindList::GetColorName( i ) ),
+ sal_True );
+ }
+ }
+ }
+ }
+
+ {
+ // end redraw
+ ScTabViewShell* pTabViewShell = pViewData->GetViewShell();
+
+ if(pTabViewShell)
+ {
+ MapMode aCurrentMapMode(pContentDev->GetMapMode());
+ pContentDev->SetMapMode(aDrawMode);
+ SdrView* pDrawView = pTabViewShell->GetSdrView();
+
+ if(pDrawView)
+ {
+ // #i74769# work with SdrPaintWindow directly
+ pDrawView->EndDrawLayers(*pTargetPaintWindow, true);
+ }
+
+ pContentDev->SetMapMode(aCurrentMapMode);
+ }
+ }
+
+ // InPlace Edit-View
+ // moved after EndDrawLayers() to get it outside the overlay buffer and
+ // on top of everything
+ if ( bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()) )
+ {
+ //! use pContentDev for EditView?
+ SetMapMode(MAP_PIXEL);
+ SCCOL nCol1 = pViewData->GetEditStartCol();
+ SCROW nRow1 = pViewData->GetEditStartRow();
+ SCCOL nCol2 = pViewData->GetEditEndCol();
+ SCROW nRow2 = pViewData->GetEditEndRow();
+ SetLineColor();
+ SetFillColor( pEditView->GetBackgroundColor() );
+ Point aStart = pViewData->GetScrPos( nCol1, nRow1, eWhich );
+ Point aEnd = pViewData->GetScrPos( nCol2+1, nRow2+1, eWhich );
+ aEnd.X() -= 2 * nLayoutSign; // don't overwrite grid
+ aEnd.Y() -= 2;
+ DrawRect( Rectangle( aStart,aEnd ) );
+
+ SetMapMode(pViewData->GetLogicMode());
+ pEditView->Paint( PixelToLogic( Rectangle( Point( nScrX, nScrY ),
+ Size( aOutputData.GetScrW(), aOutputData.GetScrH() ) ) ) );
+ SetMapMode(MAP_PIXEL);
+ }
+
+ if (pViewData->HasEditView(eWhich))
+ {
+ // flush OverlayManager before changing the MapMode
+ flushOverlayManager();
+
+ // set MapMode for text edit
+ SetMapMode(pViewData->GetLogicMode());
+ }
+ else
+ SetMapMode(aDrawMode);
+
+ if ( pNoteMarker )
+ pNoteMarker->Draw(); // ueber den Cursor, im Drawing-MapMode
+
+ //DrawStartTimer(); // fuer bunte Handles ohne System-Clipping
+
+ //
+ // Wenn waehrend des Paint etwas invertiert wurde (Selektion geaendert aus Basic-Macro),
+ // ist das jetzt durcheinandergekommen und es muss neu gemalt werden
+ //
+
+ DBG_ASSERT(nPaintCount, "nPaintCount falsch");
+ --nPaintCount;
+ if (!nPaintCount)
+ CheckNeedsRepaint();
+}
+
+void ScGridWindow::CheckNeedsRepaint()
+{
+ // called at the end of painting, and from timer after background text width calculation
+
+ if (bNeedsRepaint)
+ {
+ bNeedsRepaint = sal_False;
+ if (aRepaintPixel.IsEmpty())
+ Invalidate();
+ else
+ Invalidate(PixelToLogic(aRepaintPixel));
+ aRepaintPixel = Rectangle();
+
+ // selection function in status bar might also be invalid
+ SfxBindings& rBindings = pViewData->GetBindings();
+ rBindings.Invalidate( SID_STATUS_SUM );
+ rBindings.Invalidate( SID_ATTR_SIZE );
+ rBindings.Invalidate( SID_TABLE_CELL );
+ }
+}
+
+void ScGridWindow::DrawPagePreview( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, OutputDevice* pContentDev )
+{
+ ScPageBreakData* pPageData = pViewData->GetView()->GetPageBreakData();
+ if (pPageData)
+ {
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ Size aWinSize = GetOutputSizePixel();
+ const svtools::ColorConfig& rColorCfg = SC_MOD()->GetColorConfig();
+ Color aManual( rColorCfg.GetColorValue(svtools::CALCPAGEBREAKMANUAL).nColor );
+ Color aAutomatic( rColorCfg.GetColorValue(svtools::CALCPAGEBREAK).nColor );
+
+ String aPageText = ScGlobal::GetRscString( STR_PAGE );
+ if ( nPageScript == 0 )
+ {
+ // get script type of translated "Page" string only once
+ nPageScript = pDoc->GetStringScriptType( aPageText );
+ if (nPageScript == 0)
+ nPageScript = ScGlobal::GetDefaultScriptType();
+ }
+ aPageText += ' ';
+
+ Font aFont;
+ ScEditEngineDefaulter* pEditEng = NULL;
+ const ScPatternAttr& rDefPattern = ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN));
+ if ( nPageScript == SCRIPTTYPE_LATIN )
+ {
+ // use single font and call DrawText directly
+ rDefPattern.GetFont( aFont, SC_AUTOCOL_BLACK );
+ aFont.SetColor( Color( COL_LIGHTGRAY ) );
+ // font size is set as needed
+ }
+ else
+ {
+ // use EditEngine to draw mixed-script string
+ pEditEng = new ScEditEngineDefaulter( EditEngine::CreatePool(), sal_True );
+ pEditEng->SetRefMapMode( pContentDev->GetMapMode() );
+ SfxItemSet* pEditDefaults = new SfxItemSet( pEditEng->GetEmptyItemSet() );
+ rDefPattern.FillEditItemSet( pEditDefaults );
+ pEditDefaults->Put( SvxColorItem( Color( COL_LIGHTGRAY ), EE_CHAR_COLOR ) );
+ pEditEng->SetDefaults( pEditDefaults );
+ }
+
+ sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( pPageData->GetCount() );
+ for (sal_uInt16 nPos=0; nPos<nCount; nPos++)
+ {
+ ScPrintRangeData& rData = pPageData->GetData(nPos);
+ ScRange aRange = rData.GetPrintRange();
+ if ( aRange.aStart.Col() <= nX2+1 && aRange.aEnd.Col()+1 >= nX1 &&
+ aRange.aStart.Row() <= nY2+1 && aRange.aEnd.Row()+1 >= nY1 )
+ {
+ // 3 Pixel Rahmen um den Druckbereich
+ // (mittlerer Pixel auf den Gitterlinien)
+
+ pContentDev->SetLineColor();
+ if (rData.IsAutomatic())
+ pContentDev->SetFillColor( aAutomatic );
+ else
+ pContentDev->SetFillColor( aManual );
+
+ Point aStart = pViewData->GetScrPos(
+ aRange.aStart.Col(), aRange.aStart.Row(), eWhich, sal_True );
+ Point aEnd = pViewData->GetScrPos(
+ aRange.aEnd.Col() + 1, aRange.aEnd.Row() + 1, eWhich, sal_True );
+ aStart.X() -= 2;
+ aStart.Y() -= 2;
+
+ // Ueberlaeufe verhindern:
+ if ( aStart.X() < -10 ) aStart.X() = -10;
+ if ( aStart.Y() < -10 ) aStart.Y() = -10;
+ if ( aEnd.X() > aWinSize.Width() + 10 )
+ aEnd.X() = aWinSize.Width() + 10;
+ if ( aEnd.Y() > aWinSize.Height() + 10 )
+ aEnd.Y() = aWinSize.Height() + 10;
+
+ pContentDev->DrawRect( Rectangle( aStart, Point(aEnd.X(),aStart.Y()+2) ) );
+ pContentDev->DrawRect( Rectangle( aStart, Point(aStart.X()+2,aEnd.Y()) ) );
+ pContentDev->DrawRect( Rectangle( Point(aStart.X(),aEnd.Y()-2), aEnd ) );
+ pContentDev->DrawRect( Rectangle( Point(aEnd.X()-2,aStart.Y()), aEnd ) );
+
+ // Seitenumbrueche
+ //! anders darstellen (gestrichelt ????)
+
+ size_t nColBreaks = rData.GetPagesX();
+ const SCCOL* pColEnd = rData.GetPageEndX();
+ size_t nColPos;
+ for (nColPos=0; nColPos+1<nColBreaks; nColPos++)
+ {
+ SCCOL nBreak = pColEnd[nColPos]+1;
+ if ( nBreak >= nX1 && nBreak <= nX2+1 )
+ {
+ //! hidden suchen
+ if (pDoc->HasColBreak(nBreak, nTab) & BREAK_MANUAL)
+ pContentDev->SetFillColor( aManual );
+ else
+ pContentDev->SetFillColor( aAutomatic );
+ Point aBreak = pViewData->GetScrPos(
+ nBreak, aRange.aStart.Row(), eWhich, sal_True );
+ pContentDev->DrawRect( Rectangle( aBreak.X()-1, aStart.Y(), aBreak.X(), aEnd.Y() ) );
+ }
+ }
+
+ size_t nRowBreaks = rData.GetPagesY();
+ const SCROW* pRowEnd = rData.GetPageEndY();
+ size_t nRowPos;
+ for (nRowPos=0; nRowPos+1<nRowBreaks; nRowPos++)
+ {
+ SCROW nBreak = pRowEnd[nRowPos]+1;
+ if ( nBreak >= nY1 && nBreak <= nY2+1 )
+ {
+ //! hidden suchen
+ if (pDoc->HasRowBreak(nBreak, nTab) & BREAK_MANUAL)
+ pContentDev->SetFillColor( aManual );
+ else
+ pContentDev->SetFillColor( aAutomatic );
+ Point aBreak = pViewData->GetScrPos(
+ aRange.aStart.Col(), nBreak, eWhich, sal_True );
+ pContentDev->DrawRect( Rectangle( aStart.X(), aBreak.Y()-1, aEnd.X(), aBreak.Y() ) );
+ }
+ }
+
+ // Seitenzahlen
+
+ SCROW nPrStartY = aRange.aStart.Row();
+ for (nRowPos=0; nRowPos<nRowBreaks; nRowPos++)
+ {
+ SCROW nPrEndY = pRowEnd[nRowPos];
+ if ( nPrEndY >= nY1 && nPrStartY <= nY2 )
+ {
+ SCCOL nPrStartX = aRange.aStart.Col();
+ for (nColPos=0; nColPos<nColBreaks; nColPos++)
+ {
+ SCCOL nPrEndX = pColEnd[nColPos];
+ if ( nPrEndX >= nX1 && nPrStartX <= nX2 )
+ {
+ Point aPageStart = pViewData->GetScrPos(
+ nPrStartX, nPrStartY, eWhich, sal_True );
+ Point aPageEnd = pViewData->GetScrPos(
+ nPrEndX+1,nPrEndY+1, eWhich, sal_True );
+
+ long nPageNo = rData.GetFirstPage();
+ if ( rData.IsTopDown() )
+ nPageNo += ((long)nColPos)*nRowBreaks+nRowPos;
+ else
+ nPageNo += ((long)nRowPos)*nColBreaks+nColPos;
+ String aPageStr = aPageText;
+ aPageStr += String::CreateFromInt32(nPageNo);
+
+ if ( pEditEng )
+ {
+ // find right font size with EditEngine
+ long nHeight = 100;
+ pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
+ pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
+ pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
+ pEditEng->SetText( aPageStr );
+ Size aSize100( pEditEng->CalcTextWidth(), pEditEng->GetTextHeight() );
+
+ // 40% of width or 60% of height
+ long nSizeX = 40 * ( aPageEnd.X() - aPageStart.X() ) / aSize100.Width();
+ long nSizeY = 60 * ( aPageEnd.Y() - aPageStart.Y() ) / aSize100.Height();
+ nHeight = Min(nSizeX,nSizeY);
+ pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
+ pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
+ pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
+
+ // centered output with EditEngine
+ Size aTextSize( pEditEng->CalcTextWidth(), pEditEng->GetTextHeight() );
+ Point aPos( (aPageStart.X()+aPageEnd.X()-aTextSize.Width())/2,
+ (aPageStart.Y()+aPageEnd.Y()-aTextSize.Height())/2 );
+ pEditEng->Draw( pContentDev, aPos );
+ }
+ else
+ {
+ // find right font size for DrawText
+ aFont.SetSize( Size( 0,100 ) );
+ pContentDev->SetFont( aFont );
+ Size aSize100( pContentDev->GetTextWidth( aPageStr ), pContentDev->GetTextHeight() );
+
+ // 40% of width or 60% of height
+ long nSizeX = 40 * ( aPageEnd.X() - aPageStart.X() ) / aSize100.Width();
+ long nSizeY = 60 * ( aPageEnd.Y() - aPageStart.Y() ) / aSize100.Height();
+ aFont.SetSize( Size( 0,Min(nSizeX,nSizeY) ) );
+ pContentDev->SetFont( aFont );
+
+ // centered output with DrawText
+ Size aTextSize( pContentDev->GetTextWidth( aPageStr ), pContentDev->GetTextHeight() );
+ Point aPos( (aPageStart.X()+aPageEnd.X()-aTextSize.Width())/2,
+ (aPageStart.Y()+aPageEnd.Y()-aTextSize.Height())/2 );
+ pContentDev->DrawText( aPos, aPageStr );
+ }
+ }
+ nPrStartX = nPrEndX + 1;
+ }
+ }
+ nPrStartY = nPrEndY + 1;
+ }
+ }
+ }
+
+ delete pEditEng;
+ }
+}
+
+void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2*/, ScTableInfo& rTabInfo, OutputDevice* pContentDev )
+{
+ aComboButton.SetOutputDevice( pContentDev );
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScDPFieldButton aCellBtn(pContentDev, &GetSettings().GetStyleSettings(), &pViewData->GetZoomX(), &pViewData->GetZoomY(), pDoc);
+
+ SCCOL nCol;
+ SCROW nRow;
+ SCSIZE nArrY;
+ SCSIZE nQuery;
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDBData* pDBData = NULL;
+ ScQueryParam* pQueryParam = NULL;
+
+ RowInfo* pRowInfo = rTabInfo.mpRowInfo;
+ sal_uInt16 nArrCount = rTabInfo.mnArrCount;
+
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ Point aOldPos = aComboButton.GetPosPixel(); // Zustand fuer MouseDown/Up
+ Size aOldSize = aComboButton.GetSizePixel(); // merken
+
+ for (nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ if ( pRowInfo[nArrY].bAutoFilter && pRowInfo[nArrY].bChanged )
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+
+ nRow = pThisRowInfo->nRowNo;
+
+
+ for (nCol=nX1; nCol<=nX2; nCol++)
+ {
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nCol+1];
+ if ( pInfo->bAutoFilter && !pInfo->bHOverlapped && !pInfo->bVOverlapped )
+ {
+ if (!pQueryParam)
+ pQueryParam = new ScQueryParam;
+
+ sal_Bool bNewData = sal_True;
+ if (pDBData)
+ {
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nAreaTab;
+ pDBData->GetArea( nAreaTab, nStartCol, nStartRow, nEndCol, nEndRow );
+ if ( nCol >= nStartCol && nCol <= nEndCol &&
+ nRow >= nStartRow && nRow <= nEndRow )
+ bNewData = sal_False;
+ }
+ if (bNewData)
+ {
+ pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab );
+ if (pDBData)
+ pDBData->GetQueryParam( *pQueryParam );
+ else
+ {
+ // can also be part of DataPilot table
+ // DBG_ERROR("Auto-Filter-Button ohne DBData");
+ }
+ }
+
+ // pQueryParam kann nur MAXQUERY Eintraege enthalten
+
+ sal_Bool bSimpleQuery = sal_True;
+ sal_Bool bColumnFound = sal_False;
+ if (!pQueryParam->bInplace)
+ bSimpleQuery = sal_False;
+ for (nQuery=0; nQuery<MAXQUERY && bSimpleQuery; nQuery++)
+ if (pQueryParam->GetEntry(nQuery).bDoQuery)
+ {
+ // hier nicht auf EQUAL beschraenken
+ // (auch bei ">1" soll der Spaltenkopf blau werden)
+
+ if (pQueryParam->GetEntry(nQuery).nField == nCol)
+ bColumnFound = sal_True;
+ if (nQuery > 0)
+ if (pQueryParam->GetEntry(nQuery).eConnect != SC_AND)
+ bSimpleQuery = sal_False;
+ }
+
+ bool bArrowState = bSimpleQuery && bColumnFound;
+ long nSizeX;
+ long nSizeY;
+ pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
+ Point aScrPos = pViewData->GetScrPos( nCol, nRow, eWhich );
+
+ aCellBtn.setBoundingBox(aScrPos, Size(nSizeX-1, nSizeY-1), bLayoutRTL);
+ aCellBtn.setPopupLeft(bLayoutRTL); // #i114944# AutoFilter button is left-aligned in RTL
+ aCellBtn.setDrawBaseButton(false);
+ aCellBtn.setDrawPopupButton(true);
+ aCellBtn.setHasHiddenMember(bArrowState);
+ aCellBtn.draw();
+ }
+ }
+ }
+
+ if ( pRowInfo[nArrY].bPushButton && pRowInfo[nArrY].bChanged )
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ nRow = pThisRowInfo->nRowNo;
+ for (nCol=nX1; nCol<=nX2; nCol++)
+ {
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nCol+1];
+ if ( pInfo->bPushButton && !pInfo->bHOverlapped && !pInfo->bVOverlapped )
+ {
+ Point aScrPos = pViewData->GetScrPos( nCol, nRow, eWhich );
+ long nSizeX;
+ long nSizeY;
+ pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
+ long nPosX = aScrPos.X();
+ long nPosY = aScrPos.Y();
+ // bLayoutRTL is handled in setBoundingBox
+
+ String aStr;
+ pDoc->GetString(nCol, nRow, nTab, aStr);
+ aCellBtn.setText(aStr);
+ aCellBtn.setBoundingBox(Point(nPosX, nPosY), Size(nSizeX-1, nSizeY-1), bLayoutRTL);
+ aCellBtn.setPopupLeft(false); // DataPilot popup is always right-aligned for now
+ aCellBtn.setDrawBaseButton(true);
+ aCellBtn.setDrawPopupButton(pInfo->bPopupButton);
+ aCellBtn.setHasHiddenMember(pInfo->bFilterActive);
+ aCellBtn.draw();
+ }
+ }
+ }
+
+ if ( bListValButton && pRowInfo[nArrY].nRowNo == aListValPos.Row() && pRowInfo[nArrY].bChanged )
+ {
+ Rectangle aRect = GetListValButtonRect( aListValPos );
+ aComboButton.SetPosPixel( aRect.TopLeft() );
+ aComboButton.SetSizePixel( aRect.GetSize() );
+ pContentDev->SetClipRegion( aRect );
+ aComboButton.Draw( sal_False, sal_False );
+ pContentDev->SetClipRegion(); // always called from Draw() without clip region
+ aComboButton.SetPosPixel( aOldPos ); // restore old state
+ aComboButton.SetSizePixel( aOldSize ); // for MouseUp/Down (AutoFilter)
+ }
+ }
+
+ delete pQueryParam;
+ aComboButton.SetOutputDevice( this );
+}
+
+Rectangle ScGridWindow::GetListValButtonRect( const ScAddress& rButtonPos )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ ScDDComboBoxButton aButton( this ); // for optimal size
+ Size aBtnSize = aButton.GetSizePixel();
+
+ SCCOL nCol = rButtonPos.Col();
+ SCROW nRow = rButtonPos.Row();
+
+ long nCellSizeX; // width of this cell, including merged
+ long nDummy;
+ pViewData->GetMergeSizePixel( nCol, nRow, nCellSizeX, nDummy );
+
+ // for height, only the cell's row is used, excluding merged cells
+ long nCellSizeY = ScViewData::ToPixel( pDoc->GetRowHeight( nRow, nTab ), pViewData->GetPPTY() );
+ long nAvailable = nCellSizeX;
+
+ // left edge of next cell if there is a non-hidden next column
+ SCCOL nNextCol = nCol + 1;
+ 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->ColHidden(nNextCol, nTab) )
+ ++nNextCol;
+ sal_Bool bNextCell = ( nNextCol <= MAXCOL );
+ if ( bNextCell )
+ nAvailable = ScViewData::ToPixel( pDoc->GetColWidth( nNextCol, nTab ), pViewData->GetPPTX() );
+
+ if ( nAvailable < aBtnSize.Width() )
+ aBtnSize.Width() = nAvailable;
+ if ( nCellSizeY < aBtnSize.Height() )
+ aBtnSize.Height() = nCellSizeY;
+
+ Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich, sal_True );
+ aPos.X() += nCellSizeX * nLayoutSign; // start of next cell
+ if (!bNextCell)
+ aPos.X() -= aBtnSize.Width() * nLayoutSign; // right edge of cell if next cell not available
+ aPos.Y() += nCellSizeY - aBtnSize.Height();
+ // X remains at the left edge
+
+ if ( bLayoutRTL )
+ aPos.X() -= aBtnSize.Width()-1; // align right edge of button with cell border
+
+ return Rectangle( aPos, aBtnSize );
+}
+
+sal_Bool ScGridWindow::IsAutoFilterActive( SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScDBData* pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab );
+ ScQueryParam aQueryParam;
+
+ if ( pDBData )
+ pDBData->GetQueryParam( aQueryParam );
+ else
+ {
+ DBG_ERROR("Auto-Filter-Button ohne DBData");
+ }
+
+ sal_Bool bSimpleQuery = sal_True;
+ sal_Bool bColumnFound = sal_False;
+ SCSIZE nQuery;
+
+ if ( !aQueryParam.bInplace )
+ bSimpleQuery = sal_False;
+
+ // aQueryParam kann nur MAXQUERY Eintraege enthalten
+
+ for ( nQuery=0; nQuery<MAXQUERY && bSimpleQuery; nQuery++ )
+ if ( aQueryParam.GetEntry(nQuery).bDoQuery )
+ {
+ if (aQueryParam.GetEntry(nQuery).nField == nCol)
+ bColumnFound = sal_True;
+
+ if (nQuery > 0)
+ if (aQueryParam.GetEntry(nQuery).eConnect != SC_AND)
+ bSimpleQuery = sal_False;
+ }
+
+ return ( bSimpleQuery && bColumnFound );
+}
+
+void ScGridWindow::DrawComboButton( const Point& rCellPos,
+ long nCellSizeX,
+ long nCellSizeY,
+ sal_Bool bArrowState,
+ sal_Bool bBtnIn )
+{
+ Point aScrPos = rCellPos;
+ Size aBtnSize = aComboButton.GetSizePixel();
+
+ if ( nCellSizeX < aBtnSize.Width() || nCellSizeY < aBtnSize.Height() )
+ {
+ if ( nCellSizeX < aBtnSize.Width() )
+ aBtnSize.Width() = nCellSizeX;
+
+ if ( nCellSizeY < aBtnSize.Height() )
+ aBtnSize.Height() = nCellSizeY;
+
+ aComboButton.SetSizePixel( aBtnSize );
+ }
+
+ sal_Bool bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
+
+ if ( bLayoutRTL )
+ aScrPos.X() -= nCellSizeX - 1;
+ else
+ aScrPos.X() += nCellSizeX - aBtnSize.Width();
+ aScrPos.Y() += nCellSizeY - aBtnSize.Height();
+
+ aComboButton.SetPosPixel( aScrPos );
+
+ HideCursor();
+ aComboButton.Draw( bArrowState, bBtnIn );
+ ShowCursor();
+}
+
+void ScGridWindow::InvertSimple( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
+ sal_Bool bTestMerge, sal_Bool bRepeat )
+{
+ //! if INVERT_HIGHLIGHT swaps foreground and background (like on Mac),
+ //! use INVERT_HIGHLIGHT only for cells that have no background color set
+ //! (here and in ScOutputData::DrawMark)
+
+ PutInOrder( nX1, nX2 );
+ PutInOrder( nY1, nY2 );
+
+ ScMarkData& rMark = pViewData->GetMarkData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ SCCOL nTestX2 = nX2;
+ SCROW nTestY2 = nY2;
+ if (bTestMerge)
+ pDoc->ExtendMerge( nX1,nY1, nTestX2,nTestY2, nTab );
+
+ SCCOL nPosX = pViewData->GetPosX( eHWhich );
+ SCROW nPosY = pViewData->GetPosY( eVWhich );
+ if (nTestX2 < nPosX || nTestY2 < nPosY)
+ return; // unsichtbar
+ SCCOL nRealX1 = nX1;
+ if (nX1 < nPosX)
+ nX1 = nPosX;
+ if (nY1 < nPosY)
+ nY1 = nPosY;
+
+ SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich);
+ if (nXRight > MAXCOL) nXRight = MAXCOL;
+ SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich);
+ if (nYBottom > MAXROW) nYBottom = MAXROW;
+
+ if (nX1 > nXRight || nY1 > nYBottom)
+ return; // unsichtbar
+ if (nX2 > nXRight) nX2 = nXRight;
+ if (nY2 > nYBottom) nY2 = nYBottom;
+
+ MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL); // erst nach den return's !!!
+
+ double nPPTX = pViewData->GetPPTX();
+ double nPPTY = pViewData->GetPPTY();
+
+ ScInvertMerger aInvert( this );
+
+ Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich );
+ long nScrY = aScrPos.Y();
+ sal_Bool bWasHidden = sal_False;
+ for (SCROW nY=nY1; nY<=nY2; nY++)
+ {
+ sal_Bool bFirstRow = ( nY == nPosY ); // first visible row?
+ sal_Bool bDoHidden = sal_False; // versteckte nachholen ?
+ sal_uInt16 nHeightTwips = pDoc->GetRowHeight( nY,nTab );
+ sal_Bool bDoRow = ( nHeightTwips != 0 );
+ if (bDoRow)
+ {
+ if (bTestMerge)
+ if (bWasHidden) // auf versteckte zusammengefasste testen
+ {
+// --nY; // nY geaendert -> vorherige zeichnen
+ bDoHidden = sal_True;
+ bDoRow = sal_True;
+ }
+
+ bWasHidden = sal_False;
+ }
+ else
+ {
+ bWasHidden = sal_True;
+ if (bTestMerge)
+ if (nY==nY2)
+ bDoRow = sal_True; // letzte Zeile aus Block
+ }
+
+ if ( bDoRow )
+ {
+ SCCOL nLoopEndX = nX2;
+ if (nX2 < nX1) // Rest von zusammengefasst
+ {
+ SCCOL nStartX = nX1;
+ while ( ((const ScMergeFlagAttr*)pDoc->
+ GetAttr(nStartX,nY,nTab,ATTR_MERGE_FLAG))->IsHorOverlapped() )
+ --nStartX;
+ if (nStartX <= nX2)
+ nLoopEndX = nX1;
+ }
+
+ long nEndY = nScrY + ScViewData::ToPixel( nHeightTwips, nPPTY ) - 1;
+ long nScrX = aScrPos.X();
+ for (SCCOL nX=nX1; nX<=nLoopEndX; nX++)
+ {
+ long nWidth = ScViewData::ToPixel( pDoc->GetColWidth( nX,nTab ), nPPTX );
+ if ( nWidth > 0 )
+ {
+ long nEndX = nScrX + ( nWidth - 1 ) * nLayoutSign;
+ if (bTestMerge)
+ {
+ SCROW nThisY = nY;
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nX, nY, nTab );
+ const ScMergeFlagAttr* pMergeFlag = (const ScMergeFlagAttr*) &pPattern->
+ GetItem(ATTR_MERGE_FLAG);
+ if ( pMergeFlag->IsVerOverlapped() && ( bDoHidden || bFirstRow ) )
+ {
+ while ( pMergeFlag->IsVerOverlapped() && nThisY > 0 &&
+ (pDoc->RowHidden(nThisY-1, nTab) || bFirstRow) )
+ {
+ --nThisY;
+ pPattern = pDoc->GetPattern( nX, nThisY, nTab );
+ pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
+ }
+ }
+
+ // nur Rest von zusammengefasster zu sehen ?
+ SCCOL nThisX = nX;
+ if ( pMergeFlag->IsHorOverlapped() && nX == nPosX && nX > nRealX1 )
+ {
+ while ( pMergeFlag->IsHorOverlapped() )
+ {
+ --nThisX;
+ pPattern = pDoc->GetPattern( nThisX, nThisY, nTab );
+ pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
+ }
+ }
+
+ if ( rMark.IsCellMarked( nThisX, nThisY, sal_True ) == bRepeat )
+ {
+ if ( !pMergeFlag->IsOverlapped() )
+ {
+ ScMergeAttr* pMerge = (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
+ if (pMerge->GetColMerge() > 0 || pMerge->GetRowMerge() > 0)
+ {
+ Point aEndPos = pViewData->GetScrPos(
+ nThisX + pMerge->GetColMerge(),
+ nThisY + pMerge->GetRowMerge(), eWhich );
+ if ( aEndPos.X() * nLayoutSign > nScrX * nLayoutSign && aEndPos.Y() > nScrY )
+ {
+ aInvert.AddRect( Rectangle( nScrX,nScrY,
+ aEndPos.X()-nLayoutSign,aEndPos.Y()-1 ) );
+ }
+ }
+ else if ( nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY )
+ {
+ aInvert.AddRect( Rectangle( nScrX,nScrY,nEndX,nEndY ) );
+ }
+ }
+ }
+ }
+ else // !bTestMerge
+ {
+ if ( rMark.IsCellMarked( nX, nY, sal_True ) == bRepeat &&
+ nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY )
+ {
+ aInvert.AddRect( Rectangle( nScrX,nScrY,nEndX,nEndY ) );
+ }
+ }
+
+ nScrX = nEndX + nLayoutSign;
+ }
+ }
+ nScrY = nEndY + 1;
+ }
+ }
+
+ aInvert.Flush(); // before restoring MapMode
+
+ SetMapMode(aOld);
+
+ CheckInverted();
+}
+
+void ScGridWindow::GetSelectionRects( ::std::vector< Rectangle >& rPixelRects )
+{
+ // transformed from ScGridWindow::InvertSimple
+
+// ScMarkData& rMark = pViewData->GetMarkData();
+ ScMarkData aMultiMark( pViewData->GetMarkData() );
+ aMultiMark.SetMarking( sal_False );
+ aMultiMark.MarkToMulti();
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ if ( !aMultiMark.IsMultiMarked() )
+ return;
+
+ ScRange aMultiRange;
+ aMultiMark.GetMultiMarkArea( aMultiRange );
+ SCCOL nX1 = aMultiRange.aStart.Col();
+ SCROW nY1 = aMultiRange.aStart.Row();
+ SCCOL nX2 = aMultiRange.aEnd.Col();
+ SCROW nY2 = aMultiRange.aEnd.Row();
+
+ PutInOrder( nX1, nX2 );
+ PutInOrder( nY1, nY2 );
+
+ sal_Bool bTestMerge = sal_True;
+ sal_Bool bRepeat = sal_True;
+
+ SCCOL nTestX2 = nX2;
+ SCROW nTestY2 = nY2;
+ if (bTestMerge)
+ pDoc->ExtendMerge( nX1,nY1, nTestX2,nTestY2, nTab );
+
+ SCCOL nPosX = pViewData->GetPosX( eHWhich );
+ SCROW nPosY = pViewData->GetPosY( eVWhich );
+ if (nTestX2 < nPosX || nTestY2 < nPosY)
+ return; // unsichtbar
+ SCCOL nRealX1 = nX1;
+ if (nX1 < nPosX)
+ nX1 = nPosX;
+ if (nY1 < nPosY)
+ nY1 = nPosY;
+
+ SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich);
+ if (nXRight > MAXCOL) nXRight = MAXCOL;
+ SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich);
+ if (nYBottom > MAXROW) nYBottom = MAXROW;
+
+ if (nX1 > nXRight || nY1 > nYBottom)
+ return; // unsichtbar
+ if (nX2 > nXRight) nX2 = nXRight;
+ if (nY2 > nYBottom) nY2 = nYBottom;
+
+// MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL); // erst nach den return's !!!
+
+ double nPPTX = pViewData->GetPPTX();
+ double nPPTY = pViewData->GetPPTY();
+
+ ScInvertMerger aInvert( &rPixelRects );
+
+ Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich );
+ long nScrY = aScrPos.Y();
+ sal_Bool bWasHidden = sal_False;
+ for (SCROW nY=nY1; nY<=nY2; nY++)
+ {
+ sal_Bool bFirstRow = ( nY == nPosY ); // first visible row?
+ sal_Bool bDoHidden = sal_False; // versteckte nachholen ?
+ sal_uInt16 nHeightTwips = pDoc->GetRowHeight( nY,nTab );
+ sal_Bool bDoRow = ( nHeightTwips != 0 );
+ if (bDoRow)
+ {
+ if (bTestMerge)
+ if (bWasHidden) // auf versteckte zusammengefasste testen
+ {
+ bDoHidden = sal_True;
+ bDoRow = sal_True;
+ }
+
+ bWasHidden = sal_False;
+ }
+ else
+ {
+ bWasHidden = sal_True;
+ if (bTestMerge)
+ if (nY==nY2)
+ bDoRow = sal_True; // letzte Zeile aus Block
+ }
+
+ if ( bDoRow )
+ {
+ SCCOL nLoopEndX = nX2;
+ if (nX2 < nX1) // Rest von zusammengefasst
+ {
+ SCCOL nStartX = nX1;
+ while ( ((const ScMergeFlagAttr*)pDoc->
+ GetAttr(nStartX,nY,nTab,ATTR_MERGE_FLAG))->IsHorOverlapped() )
+ --nStartX;
+ if (nStartX <= nX2)
+ nLoopEndX = nX1;
+ }
+
+ long nEndY = nScrY + ScViewData::ToPixel( nHeightTwips, nPPTY ) - 1;
+ long nScrX = aScrPos.X();
+ for (SCCOL nX=nX1; nX<=nLoopEndX; nX++)
+ {
+ long nWidth = ScViewData::ToPixel( pDoc->GetColWidth( nX,nTab ), nPPTX );
+ if ( nWidth > 0 )
+ {
+ long nEndX = nScrX + ( nWidth - 1 ) * nLayoutSign;
+ if (bTestMerge)
+ {
+ SCROW nThisY = nY;
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nX, nY, nTab );
+ const ScMergeFlagAttr* pMergeFlag = (const ScMergeFlagAttr*) &pPattern->
+ GetItem(ATTR_MERGE_FLAG);
+ if ( pMergeFlag->IsVerOverlapped() && ( bDoHidden || bFirstRow ) )
+ {
+ while ( pMergeFlag->IsVerOverlapped() && nThisY > 0 &&
+ (pDoc->RowHidden(nThisY-1, nTab) || bFirstRow) )
+ {
+ --nThisY;
+ pPattern = pDoc->GetPattern( nX, nThisY, nTab );
+ pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
+ }
+ }
+
+ // nur Rest von zusammengefasster zu sehen ?
+ SCCOL nThisX = nX;
+ if ( pMergeFlag->IsHorOverlapped() && nX == nPosX && nX > nRealX1 )
+ {
+ while ( pMergeFlag->IsHorOverlapped() )
+ {
+ --nThisX;
+ pPattern = pDoc->GetPattern( nThisX, nThisY, nTab );
+ pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
+ }
+ }
+
+ if ( aMultiMark.IsCellMarked( nThisX, nThisY, sal_True ) == bRepeat )
+ {
+ if ( !pMergeFlag->IsOverlapped() )
+ {
+ ScMergeAttr* pMerge = (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
+ if (pMerge->GetColMerge() > 0 || pMerge->GetRowMerge() > 0)
+ {
+ Point aEndPos = pViewData->GetScrPos(
+ nThisX + pMerge->GetColMerge(),
+ nThisY + pMerge->GetRowMerge(), eWhich );
+ if ( aEndPos.X() * nLayoutSign > nScrX * nLayoutSign && aEndPos.Y() > nScrY )
+ {
+ aInvert.AddRect( Rectangle( nScrX,nScrY,
+ aEndPos.X()-nLayoutSign,aEndPos.Y()-1 ) );
+ }
+ }
+ else if ( nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY )
+ {
+ aInvert.AddRect( Rectangle( nScrX,nScrY,nEndX,nEndY ) );
+ }
+ }
+ }
+ }
+ else // !bTestMerge
+ {
+ if ( aMultiMark.IsCellMarked( nX, nY, sal_True ) == bRepeat &&
+ nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY )
+ {
+ aInvert.AddRect( Rectangle( nScrX,nScrY,nEndX,nEndY ) );
+ }
+ }
+
+ nScrX = nEndX + nLayoutSign;
+ }
+ }
+ nScrY = nEndY + 1;
+ }
+ }
+
+// aInvert.Flush(); // before restoring MapMode
+}
+
+// -------------------------------------------------------------------------
+
+//UNUSED2008-05 void ScGridWindow::DrawDragRect( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( nX2 < pViewData->GetPosX(eHWhich) || nY2 < pViewData->GetPosY(eVWhich) )
+//UNUSED2008-05 return;
+//UNUSED2008-05
+//UNUSED2008-05 Update(); // wegen XOR
+//UNUSED2008-05
+//UNUSED2008-05 MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL);
+//UNUSED2008-05
+//UNUSED2008-05 SCTAB nTab = pViewData->GetTabNo();
+//UNUSED2008-05
+//UNUSED2008-05 SCCOL nPosX = pViewData->GetPosX(WhichH(eWhich));
+//UNUSED2008-05 SCROW nPosY = pViewData->GetPosY(WhichV(eWhich));
+//UNUSED2008-05 if (nX1 < nPosX) nX1 = nPosX;
+//UNUSED2008-05 if (nX2 < nPosX) nX2 = nPosX;
+//UNUSED2008-05 if (nY1 < nPosY) nY1 = nPosY;
+//UNUSED2008-05 if (nY2 < nPosY) nY2 = nPosY;
+//UNUSED2008-05
+//UNUSED2008-05 Point aScrPos( pViewData->GetScrPos( nX1, nY1, eWhich ) );
+//UNUSED2008-05
+//UNUSED2008-05 long nSizeXPix=0;
+//UNUSED2008-05 long nSizeYPix=0;
+//UNUSED2008-05 ScDocument* pDoc = pViewData->GetDocument();
+//UNUSED2008-05 double nPPTX = pViewData->GetPPTX();
+//UNUSED2008-05 double nPPTY = pViewData->GetPPTY();
+//UNUSED2008-05 SCCOLROW i;
+//UNUSED2008-05
+//UNUSED2008-05 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+//UNUSED2008-05 long nLayoutSign = bLayoutRTL ? -1 : 1;
+//UNUSED2008-05
+//UNUSED2008-05 if (ValidCol(nX2) && nX2>=nX1)
+//UNUSED2008-05 for (i=nX1; i<=nX2; i++)
+//UNUSED2008-05 nSizeXPix += ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(i), nTab ), nPPTX );
+//UNUSED2008-05 else
+//UNUSED2008-05 {
+//UNUSED2008-05 aScrPos.X() -= nLayoutSign;
+//UNUSED2008-05 nSizeXPix += 2;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 if (ValidRow(nY2) && nY2>=nY1)
+//UNUSED2008-05 for (i=nY1; i<=nY2; i++)
+//UNUSED2008-05 nSizeYPix += ScViewData::ToPixel( pDoc->GetRowHeight( i, nTab ), nPPTY );
+//UNUSED2008-05 else
+//UNUSED2008-05 {
+//UNUSED2008-05 aScrPos.Y() -= 1;
+//UNUSED2008-05 nSizeYPix += 2;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 aScrPos.X() -= 2 * nLayoutSign;
+//UNUSED2008-05 aScrPos.Y() -= 2;
+//UNUSED2008-05 // Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
+//UNUSED2008-05 Rectangle aRect( aScrPos.X(), aScrPos.Y(),
+//UNUSED2008-05 aScrPos.X() + ( nSizeXPix + 2 ) * nLayoutSign, aScrPos.Y() + nSizeYPix + 2 );
+//UNUSED2008-05 if ( bLayoutRTL )
+//UNUSED2008-05 {
+//UNUSED2008-05 aRect.Left() = aRect.Right(); // end position is left
+//UNUSED2008-05 aRect.Right() = aScrPos.X();
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 Invert(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ));
+//UNUSED2008-05 Invert(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ));
+//UNUSED2008-05 Invert(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ));
+//UNUSED2008-05 Invert(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ));
+//UNUSED2008-05
+//UNUSED2008-05 SetMapMode(aOld);
+//UNUSED2008-05 }
+
+// -------------------------------------------------------------------------
+
+void ScGridWindow::DrawCursor()
+{
+// #114409#
+// SCTAB nTab = pViewData->GetTabNo();
+// SCCOL nX = pViewData->GetCurX();
+// SCROW nY = pViewData->GetCurY();
+//
+// // in verdeckten Zellen nicht zeichnen
+//
+// ScDocument* pDoc = pViewData->GetDocument();
+// const ScPatternAttr* pPattern = pDoc->GetPattern(nX,nY,nTab);
+// const ScMergeFlagAttr& rMerge = (const ScMergeFlagAttr&) pPattern->GetItem(ATTR_MERGE_FLAG);
+// if (rMerge.IsOverlapped())
+// return;
+//
+// // links/oben ausserhalb des Bildschirms ?
+//
+// sal_Bool bVis = ( nX>=pViewData->GetPosX(eHWhich) && nY>=pViewData->GetPosY(eVWhich) );
+// if (!bVis)
+// {
+// SCCOL nEndX = nX;
+// SCROW nEndY = nY;
+// ScDocument* pDoc = pViewData->GetDocument();
+// const ScMergeAttr& rMerge = (const ScMergeAttr&) pPattern->GetItem(ATTR_MERGE);
+// if (rMerge.GetColMerge() > 1)
+// nEndX += rMerge.GetColMerge()-1;
+// if (rMerge.GetRowMerge() > 1)
+// nEndY += rMerge.GetRowMerge()-1;
+// bVis = ( nEndX>=pViewData->GetPosX(eHWhich) && nEndY>=pViewData->GetPosY(eVWhich) );
+// }
+//
+// if ( bVis )
+// {
+// // hier kein Update, da aus Paint gerufen und laut Zaehler Cursor schon da
+// // wenn Update noetig, dann bei Hide/Showcursor vor dem Hoch-/Runterzaehlen
+//
+// MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL);
+//
+// Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True );
+// sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+//
+// // completely right of/below the screen?
+// // (test with logical start position in aScrPos)
+// sal_Bool bMaybeVisible;
+// if ( bLayoutRTL )
+// bMaybeVisible = ( aScrPos.X() >= -2 && aScrPos.Y() >= -2 );
+// else
+// {
+// Size aOutSize = GetOutputSizePixel();
+// bMaybeVisible = ( aScrPos.X() <= aOutSize.Width() + 2 && aScrPos.Y() <= aOutSize.Height() + 2 );
+// }
+// if ( bMaybeVisible )
+// {
+// long nSizeXPix;
+// long nSizeYPix;
+// pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
+//
+// if ( bLayoutRTL )
+// aScrPos.X() -= nSizeXPix - 2; // move instead of mirroring
+//
+// sal_Bool bFix = ( pViewData->GetHSplitMode() == SC_SPLIT_FIX ||
+// pViewData->GetVSplitMode() == SC_SPLIT_FIX );
+// if ( pViewData->GetActivePart()==eWhich || bFix )
+// {
+// // old UNX version with two Invert calls causes flicker.
+// // if optimization is needed, a new flag should be added
+// // to InvertTracking
+//
+// aScrPos.X() -= 2;
+// aScrPos.Y() -= 2;
+// Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
+//
+// Invert(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ));
+// Invert(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ));
+// Invert(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ));
+// Invert(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ));
+// }
+// else
+// {
+// Rectangle aRect( aScrPos, Size( nSizeXPix - 1, nSizeYPix - 1 ) );
+// Invert( aRect );
+// }
+// }
+//
+// SetMapMode(aOld);
+// }
+}
+
+ // AutoFill-Anfasser:
+
+void ScGridWindow::DrawAutoFillMark()
+{
+// #114409#
+// if ( bAutoMarkVisible && aAutoMarkPos.Tab() == pViewData->GetTabNo() )
+// {
+// SCCOL nX = aAutoMarkPos.Col();
+// SCROW nY = aAutoMarkPos.Row();
+// SCTAB nTab = pViewData->GetTabNo();
+// ScDocument* pDoc = pViewData->GetDocument();
+// sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+//
+// Point aFillPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True );
+// long nSizeXPix;
+// long nSizeYPix;
+// pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
+// if ( bLayoutRTL )
+// aFillPos.X() -= nSizeXPix + 3;
+// else
+// aFillPos.X() += nSizeXPix - 2;
+//
+// aFillPos.Y() += nSizeYPix;
+// aFillPos.Y() -= 2;
+// Rectangle aFillRect( aFillPos, Size(6,6) );
+// // Anfasser von Zeichenobjekten sind 7*7
+//
+// MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL);
+// Invert( aFillRect );
+// SetMapMode(aOld);
+// }
+}
+
+// -------------------------------------------------------------------------
+
+void ScGridWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged(rDCEvt);
+
+ if ( (rDCEvt.GetType() == DATACHANGED_PRINTER) ||
+ (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ if ( rDCEvt.GetType() == DATACHANGED_FONTS && eWhich == pViewData->GetActivePart() )
+ pViewData->GetDocShell()->UpdateFontList();
+
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ if ( eWhich == pViewData->GetActivePart() ) // only once for the view
+ {
+ ScTabView* pView = pViewData->GetView();
+
+ // update scale in case the UI ScreenZoom has changed
+ ScGlobal::UpdatePPT(this);
+ pView->RecalcPPT();
+
+ // RepeatResize in case scroll bar sizes have changed
+ pView->RepeatResize();
+ pView->UpdateAllOverlays();
+
+ // invalidate cell attribs in input handler, in case the
+ // EditEngine BackgroundColor has to be changed
+ if ( pViewData->IsActive() )
+ {
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
+ if (pHdl)
+ pHdl->ForgetLastPattern();
+ }
+ }
+ }
+
+ Invalidate();
+ }
+}
+
+
+
+
diff --git a/sc/source/ui/view/gridwin5.cxx b/sc/source/ui/view/gridwin5.cxx
new file mode 100644
index 000000000000..06e0e7f02f0e
--- /dev/null
+++ b/sc/source/ui/view/gridwin5.cxx
@@ -0,0 +1,439 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <editeng/eeitem.hxx>
+
+#include <editeng/flditem.hxx>
+
+#include <editeng/editview.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdpagv.hxx>
+#include <svtools/imapobj.hxx>
+#include <vcl/cursor.hxx>
+#include <vcl/help.hxx>
+#include <tools/urlobj.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include <unotools/localedatawrapper.hxx>
+
+#include "viewuno.hxx"
+#include "AccessibleDocument.hxx"
+#include <com/sun/star/accessibility/XAccessible.hpp>
+
+#include "gridwin.hxx"
+#include "viewdata.hxx"
+#include "drawview.hxx"
+#include "drwlayer.hxx"
+#include "drawpage.hxx"
+#include "document.hxx"
+#include "notemark.hxx"
+#include "chgtrack.hxx"
+#include "chgviset.hxx"
+#include "dbfunc.hxx"
+#include "tabvwsh.hxx"
+#include "userdat.hxx"
+#include "postit.hxx"
+
+// -----------------------------------------------------------------------
+
+ScHideTextCursor::ScHideTextCursor( ScViewData* pData, ScSplitPos eW ) :
+ pViewData(pData),
+ eWhich(eW)
+{
+ Window* pWin = pViewData->GetView()->GetWindowByPos( eWhich );
+ if (pWin)
+ {
+ Cursor* pCur = pWin->GetCursor();
+ if ( pCur && pCur->IsVisible() )
+ pCur->Hide();
+ }
+}
+
+ScHideTextCursor::~ScHideTextCursor()
+{
+ Window* pWin = pViewData->GetView()->GetWindowByPos( eWhich );
+ if (pWin)
+ {
+ // restore text cursor
+ if ( pViewData->HasEditView(eWhich) && pWin->HasFocus() )
+ pViewData->GetEditView(eWhich)->ShowCursor( sal_False, sal_True );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool ScGridWindow::ShowNoteMarker( SCsCOL nPosX, SCsROW nPosY, sal_Bool bKeyboard )
+{
+ sal_Bool bDone = sal_False;
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ ScAddress aCellPos( nPosX, nPosY, nTab );
+
+ String aTrackText;
+ sal_Bool bLeftEdge = sal_False;
+
+ // Change-Tracking
+
+ ScChangeTrack* pTrack = pDoc->GetChangeTrack();
+ ScChangeViewSettings* pSettings = pDoc->GetChangeViewSettings();
+ if ( pTrack && pTrack->GetFirst() && pSettings && pSettings->ShowChanges())
+ {
+ const ScChangeAction* pFound = NULL;
+ const ScChangeAction* pFoundContent = NULL;
+ const ScChangeAction* pFoundMove = NULL;
+ long nModified = 0;
+ const ScChangeAction* pAction = pTrack->GetFirst();
+ while (pAction)
+ {
+ if ( pAction->IsVisible() &&
+ ScViewUtil::IsActionShown( *pAction, *pSettings, *pDoc ) )
+ {
+ ScChangeActionType eType = pAction->GetType();
+ const ScBigRange& rBig = pAction->GetBigRange();
+ if ( rBig.aStart.Tab() == nTab )
+ {
+ ScRange aRange = rBig.MakeRange();
+
+ if ( eType == SC_CAT_DELETE_ROWS )
+ aRange.aEnd.SetRow( aRange.aStart.Row() );
+ else if ( eType == SC_CAT_DELETE_COLS )
+ aRange.aEnd.SetCol( aRange.aStart.Col() );
+
+ if ( aRange.In( aCellPos ) )
+ {
+ pFound = pAction; // der letzte gewinnt
+ switch ( eType )
+ {
+ case SC_CAT_CONTENT :
+ pFoundContent = pAction;
+ break;
+ case SC_CAT_MOVE :
+ pFoundMove = pAction;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ ++nModified;
+ }
+ }
+ if ( eType == SC_CAT_MOVE )
+ {
+ ScRange aRange =
+ ((const ScChangeActionMove*)pAction)->
+ GetFromRange().MakeRange();
+ if ( aRange.In( aCellPos ) )
+ {
+ pFound = pAction;
+ ++nModified;
+ }
+ }
+ }
+ pAction = pAction->GetNext();
+ }
+
+ if ( pFound )
+ {
+ if ( pFoundContent && pFound->GetType() != SC_CAT_CONTENT )
+ pFound = pFoundContent; // Content gewinnt
+ if ( pFoundMove && pFound->GetType() != SC_CAT_MOVE &&
+ pFoundMove->GetActionNumber() >
+ pFound->GetActionNumber() )
+ pFound = pFoundMove; // Move gewinnt
+
+ // bei geloeschten Spalten: Pfeil auf die linke Seite der Zelle
+ if ( pFound->GetType() == SC_CAT_DELETE_COLS )
+ bLeftEdge = sal_True;
+
+ DateTime aDT = pFound->GetDateTime();
+ aTrackText = pFound->GetUser();
+ aTrackText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ", " ));
+ aTrackText += ScGlobal::pLocaleData->getDate(aDT);
+ aTrackText += ' ';
+ aTrackText += ScGlobal::pLocaleData->getTime(aDT);
+ aTrackText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ":\n" ));
+ String aComStr=pFound->GetComment();
+ if(aComStr.Len()>0)
+ {
+ aTrackText += aComStr;
+ aTrackText.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "\n( " ));
+ }
+ pFound->GetDescription( aTrackText, pDoc );
+ if(aComStr.Len()>0)
+ {
+ aTrackText +=')';
+ }
+ }
+ }
+
+ // Notiz nur, wenn sie nicht schon auf dem Drawing-Layer angezeigt wird:
+ const ScPostIt* pNote = pDoc->GetNote( aCellPos );
+ if ( (aTrackText.Len() > 0) || (pNote && !pNote->IsCaptionShown()) )
+ {
+ sal_Bool bNew = sal_True;
+ sal_Bool bFast = sal_False;
+ if ( pNoteMarker ) // schon eine Notiz angezeigt
+ {
+ if ( pNoteMarker->GetDocPos() == aCellPos ) // dieselbe
+ bNew = sal_False; // dann stehenlassen
+ else
+ bFast = sal_True; // sonst sofort
+
+ // marker which was shown for ctrl-F1 isn't removed by mouse events
+ if ( pNoteMarker->IsByKeyboard() && !bKeyboard )
+ bNew = sal_False;
+ }
+ if ( bNew )
+ {
+ if ( bKeyboard )
+ bFast = sal_True; // keyboard also shows the marker immediately
+
+ delete pNoteMarker;
+
+ bool bHSplit = pViewData->GetHSplitMode() != SC_SPLIT_NONE;
+ bool bVSplit = pViewData->GetVSplitMode() != SC_SPLIT_NONE;
+
+ Window* pLeft = pViewData->GetView()->GetWindowByPos( bVSplit ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT );
+ Window* pRight = bHSplit ? pViewData->GetView()->GetWindowByPos( bVSplit ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT ) : 0;
+ Window* pBottom = bVSplit ? pViewData->GetView()->GetWindowByPos( SC_SPLIT_BOTTOMLEFT ) : 0;
+ Window* pDiagonal = (bHSplit && bVSplit) ? pViewData->GetView()->GetWindowByPos( SC_SPLIT_BOTTOMRIGHT ) : 0;
+ DBG_ASSERT( pLeft, "ScGridWindow::ShowNoteMarker - missing top-left grid window" );
+
+ /* If caption is shown from right or bottom windows, adjust
+ mapmode to include size of top-left window. */
+ MapMode aMapMode = GetDrawMapMode( sal_True );
+ Size aLeftSize = pLeft->PixelToLogic( pLeft->GetOutputSizePixel(), aMapMode );
+ Point aOrigin = aMapMode.GetOrigin();
+ if( (this == pRight) || (this == pDiagonal) )
+ aOrigin.X() += aLeftSize.Width();
+ if( (this == pBottom) || (this == pDiagonal) )
+ aOrigin.Y() += aLeftSize.Height();
+ aMapMode.SetOrigin( aOrigin );
+
+ pNoteMarker = new ScNoteMarker( pLeft, pRight, pBottom, pDiagonal,
+ pDoc, aCellPos, aTrackText,
+ aMapMode, bLeftEdge, bFast, bKeyboard );
+ }
+
+ bDone = sal_True; // something is shown (old or new)
+ }
+
+ return bDone;
+}
+
+// -----------------------------------------------------------------------
+
+void ScGridWindow::RequestHelp(const HelpEvent& rHEvt)
+{
+ sal_Bool bDone = sal_False;
+ sal_Bool bHelpEnabled = ( rHEvt.GetMode() & ( HELPMODE_BALLOON | HELPMODE_QUICK ) ) != 0;
+ SdrView* pDrView = pViewData->GetScDrawView();
+
+ sal_Bool bDrawTextEdit = sal_False;
+ if (pDrView)
+ bDrawTextEdit = pDrView->IsTextEdit();
+
+ // notes or change tracking
+
+ if ( bHelpEnabled && !bDrawTextEdit )
+ {
+ Point aPosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aPosPixel.X(), aPosPixel.Y(), eWhich, nPosX, nPosY );
+
+ if ( ShowNoteMarker( nPosX, nPosY, sal_False ) )
+ {
+ Window::RequestHelp( rHEvt ); // alte Tip/Balloon ausschalten
+ bDone = sal_True;
+ }
+ }
+
+ if ( !bDone && pNoteMarker )
+ {
+ if ( pNoteMarker->IsByKeyboard() )
+ {
+ // marker which was shown for ctrl-F1 isn't removed by mouse events
+ }
+ else
+ DELETEZ(pNoteMarker);
+ }
+
+ // Image-Map / Text-URL
+
+ if ( bHelpEnabled && !bDone && !nButtonDown ) // nur ohne gedrueckten Button
+ {
+ String aHelpText;
+ Rectangle aPixRect;
+ Point aPosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
+
+ if ( pDrView ) // URL / Image-Map
+ {
+ SdrViewEvent aVEvt;
+ MouseEvent aMEvt( aPosPixel, 1, 0, MOUSE_LEFT );
+ SdrHitKind eHit = pDrView->PickAnything( aMEvt, SDRMOUSEBUTTONDOWN, aVEvt );
+
+ if ( eHit != SDRHIT_NONE && aVEvt.pObj != NULL )
+ {
+ // URL fuer IMapObject unter Pointer ist Hilfetext
+ if ( ScDrawLayer::GetIMapInfo( aVEvt.pObj ) )
+ {
+ Point aLogicPos = PixelToLogic( aPosPixel );
+ IMapObject* pIMapObj = ScDrawLayer::GetHitIMapObject(
+ aVEvt.pObj, aLogicPos, *this );
+
+ if ( pIMapObj )
+ {
+ // #44990# Bei ImageMaps die Description anzeigen, wenn vorhanden
+ aHelpText = pIMapObj->GetAltText();
+ if (!aHelpText.Len())
+ aHelpText = pIMapObj->GetURL();
+ aPixRect = LogicToPixel(aVEvt.pObj->GetLogicRect());
+ }
+ }
+ // URL in shape text or at shape itself (URL in text overrides object URL)
+ if ( aHelpText.Len() == 0 )
+ {
+ if( aVEvt.eEvent == SDREVENT_EXECUTEURL )
+ {
+ aHelpText = aVEvt.pURLField->GetURL();
+ aPixRect = LogicToPixel(aVEvt.pObj->GetLogicRect());
+ }
+ else
+ {
+ SdrObject* pObj = 0;
+ SdrPageView* pPV = 0;
+ Point aMDPos = PixelToLogic( aPosPixel );
+ if ( pDrView->PickObj(aMDPos, pDrView->getHitTolLog(), pObj, pPV, SDRSEARCH_ALSOONMASTER) )
+ {
+ if ( pObj->IsGroupObject() )
+ {
+ SdrObject* pHit = 0;
+ if ( pDrView->PickObj(aMDPos, pDrView->getHitTolLog(), pHit, pPV, SDRSEARCH_DEEP ) )
+ pObj = pHit;
+ }
+#ifdef ISSUE66550_HLINK_FOR_SHAPES
+ ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( pObj );
+ if ( pInfo && (pInfo->GetHlink().getLength() > 0) )
+ {
+ aPixRect = LogicToPixel(aVEvt.pObj->GetLogicRect());
+ aHelpText = pInfo->GetHlink();
+ }
+#endif
+ }
+ }
+ }
+ }
+ }
+
+ if ( !aHelpText.Len() ) // Text-URL
+ {
+ String aUrl;
+ if ( GetEditUrl( aPosPixel, NULL, &aUrl, NULL ) )
+ {
+ aHelpText = INetURLObject::decode( aUrl, INET_HEX_ESCAPE,
+ INetURLObject::DECODE_UNAMBIGUOUS );
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ SCTAB nTab = pViewData->GetTabNo();
+ pViewData->GetPosFromPixel( aPosPixel.X(), aPosPixel.Y(), eWhich, nPosX, nPosY );
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nPosX, nPosY, nTab );
+
+ ScHideTextCursor aHideCursor( pViewData, eWhich ); // MapMode is changed in GetEditArea
+
+ // bForceToTop = sal_False, use the cell's real position
+ aPixRect = pViewData->GetEditArea( eWhich, nPosX, nPosY, this, pPattern, sal_False );
+ }
+ }
+
+ if ( aHelpText.Len() )
+ {
+ Rectangle aScreenRect(OutputToScreenPixel(aPixRect.TopLeft()),
+ OutputToScreenPixel(aPixRect.BottomRight()));
+
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ Help::ShowBalloon(this,rHEvt.GetMousePosPixel(), aScreenRect, aHelpText);
+ else if ( rHEvt.GetMode() & HELPMODE_QUICK )
+ Help::ShowQuickHelp(this,aScreenRect, aHelpText);
+
+ bDone = sal_True;
+ }
+ }
+
+ // Basic-Controls
+
+ if ( pDrView && bHelpEnabled && !bDone )
+ {
+ SdrPageView* pPV = pDrView->GetSdrPageView();
+ DBG_ASSERT( pPV, "SdrPageView* ist NULL" );
+ if (pPV)
+ bDone = ((ScDrawPage*)pPV->GetPage())->RequestHelp( this, pDrView, rHEvt );
+ }
+
+ // Wenn QuickHelp fuer AutoFill angezeigt wird, nicht wieder wegnehmen lassen
+
+ if ( nMouseStatus == SC_GM_TABDOWN && pViewData->GetRefType() == SC_REFTYPE_FILL &&
+ Help::IsQuickHelpEnabled() )
+ bDone = sal_True;
+
+ if (!bDone)
+ Window::RequestHelp( rHEvt );
+}
+
+sal_Bool ScGridWindow::IsMyModel(SdrEditView* pSdrView)
+{
+ return pSdrView &&
+ pSdrView->GetModel() == pViewData->GetDocument()->GetDrawLayer();
+}
+
+void ScGridWindow::HideNoteMarker()
+{
+ DELETEZ(pNoteMarker);
+}
+
+com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ ScGridWindow::CreateAccessible()
+{
+ ScAccessibleDocument* pAccessibleDocument =
+ new ScAccessibleDocument(GetAccessibleParentWindow()->GetAccessible(),
+ pViewData->GetViewShell(), eWhich);
+
+ com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessible > xAccessible = pAccessibleDocument;
+
+ pAccessibleDocument->Init();
+
+ return xAccessible;
+}
diff --git a/sc/source/ui/view/hdrcont.cxx b/sc/source/ui/view/hdrcont.cxx
new file mode 100644
index 000000000000..a3f30ba7ba59
--- /dev/null
+++ b/sc/source/ui/view/hdrcont.cxx
@@ -0,0 +1,1046 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <sfx2/dispatch.hxx>
+#include <vcl/help.hxx>
+#include <tools/poly.hxx>
+#include <svtools/colorcfg.hxx>
+
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "tabvwsh.hxx"
+#include "hdrcont.hxx"
+#include "scmod.hxx" // Optionen
+#include "inputopt.hxx" // Optionen
+#include "gridmerg.hxx"
+#include "document.hxx"
+
+// -----------------------------------------------------------------------
+
+#define SC_DRAG_MIN 2
+
+// passes in paint
+// (selection left/right must be first because the continuous lines
+// are partly overwritten later)
+
+#define SC_HDRPAINT_SEL_RIGHT 0
+#define SC_HDRPAINT_SEL_LEFT 1
+#define SC_HDRPAINT_TOP 2
+#define SC_HDRPAINT_SEL_TOP 3
+#define SC_HDRPAINT_SEL_BOTTOM 4
+#define SC_HDRPAINT_BOTTOM 5
+#define SC_HDRPAINT_TEXT 6
+#define SC_HDRPAINT_COUNT 7
+
+//==================================================================
+
+ScHeaderControl::ScHeaderControl( Window* pParent, SelectionEngine* pSelectionEngine,
+ SCCOLROW nNewSize, sal_uInt16 nNewFlags ) :
+ Window ( pParent ),
+ pSelEngine ( pSelectionEngine ),
+ nFlags ( nNewFlags ),
+ bVertical ( (nNewFlags & HDR_VERTICAL) != 0 ),
+ nSize ( nNewSize ),
+ nMarkStart ( 0 ),
+ nMarkEnd ( 0 ),
+ bMarkRange ( sal_False ),
+ bDragging ( sal_False ),
+ bIgnoreMove ( sal_False )
+{
+ // --- RTL --- no default mirroring for this window, the spreadsheet itself
+ // is also not mirrored
+ // #107811# mirror the vertical window for correct border drawing
+ // #106948# table layout depends on sheet format, not UI setting, so the
+ // borders of the vertical window have to be handled manually, too.
+ EnableRTL( sal_False );
+
+ aNormFont = GetFont();
+ aNormFont.SetTransparent( sal_True ); //! WEIGHT_NORMAL hart setzen ???
+ aBoldFont = aNormFont;
+ aBoldFont.SetWeight( WEIGHT_BOLD );
+
+ SetFont(aBoldFont);
+ bBoldSet = sal_True;
+
+ Size aSize = LogicToPixel( Size(
+ GetTextWidth( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("8888")) ),
+ GetTextHeight() ) );
+ aSize.Width() += 4; // Platz fuer hervorgehobene Umrandung
+ aSize.Height() += 3;
+ SetSizePixel( aSize );
+
+ nWidth = nSmallWidth = aSize.Width();
+ nBigWidth = LogicToPixel( Size( GetTextWidth(
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("8888888")) ), 0 ) ).Width() + 5;
+
+ SetBackground(); // sonst Probleme auf OS/2 !?!?!
+}
+
+void ScHeaderControl::SetWidth( long nNew )
+{
+ DBG_ASSERT( bVertical, "SetDigits nur fuer Zeilenkoepfe erlaubt" );
+ if ( nNew != nWidth )
+ {
+ Size aSize( nNew, GetSizePixel().Height() ); // Hoehe nicht aendern
+ SetSizePixel( aSize );
+
+ nWidth = nNew;
+
+ Invalidate(); // neu zentrieren
+ }
+}
+
+ScHeaderControl::~ScHeaderControl()
+{
+}
+
+void ScHeaderControl::DoPaint( SCCOLROW nStart, SCCOLROW nEnd )
+{
+ sal_Bool bLayoutRTL = IsLayoutRTL();
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ Rectangle aRect( Point(0,0), GetOutputSizePixel() );
+ if ( bVertical )
+ {
+ aRect.Top() = GetScrPos( nStart )-nLayoutSign; // extra pixel for line at top of selection
+ aRect.Bottom() = GetScrPos( nEnd+1 )-nLayoutSign;
+ }
+ else
+ {
+ aRect.Left() = GetScrPos( nStart )-nLayoutSign; // extra pixel for line left of selection
+ aRect.Right() = GetScrPos( nEnd+1 )-nLayoutSign;
+ }
+ Invalidate(aRect);
+}
+
+void ScHeaderControl::SetMark( sal_Bool bNewSet, SCCOLROW nNewStart, SCCOLROW nNewEnd )
+{
+ sal_Bool bEnabled = SC_MOD()->GetInputOptions().GetMarkHeader(); //! cachen?
+ if (!bEnabled)
+ bNewSet = sal_False;
+
+ // Variablen setzen
+
+ sal_Bool bOldSet = bMarkRange;
+ SCCOLROW nOldStart = nMarkStart;
+ SCCOLROW nOldEnd = nMarkEnd;
+ PutInOrder( nNewStart, nNewEnd );
+ bMarkRange = bNewSet;
+ nMarkStart = nNewStart;
+ nMarkEnd = nNewEnd;
+
+ // Paint
+
+ if ( bNewSet )
+ {
+ if ( bOldSet )
+ {
+ if ( nNewStart == nOldStart )
+ {
+ if ( nNewEnd != nOldEnd )
+ DoPaint( Min( nNewEnd, nOldEnd ) + 1, Max( nNewEnd, nOldEnd ) );
+ // sonst nix
+ }
+ else if ( nNewEnd == nOldEnd )
+ DoPaint( Min( nNewStart, nOldStart ), Max( nNewStart, nOldStart ) - 1 );
+ else if ( nNewStart > nOldEnd || nNewEnd < nOldStart )
+ {
+ // zwei Bereiche...
+ DoPaint( nOldStart, nOldEnd );
+ DoPaint( nNewStart, nNewEnd );
+ }
+ else // irgendwie ueberlappend... (kommt eh nicht oft vor)
+ DoPaint( Min( nNewStart, nOldStart ), Max( nNewEnd, nOldEnd ) );
+ }
+ else
+ DoPaint( nNewStart, nNewEnd ); // komplett neu
+ }
+ else if ( bOldSet )
+ DoPaint( nOldStart, nOldEnd ); // komplett aufheben
+
+ // sonst war nix, is nix
+}
+
+long ScHeaderControl::GetScrPos( SCCOLROW nEntryNo )
+{
+ long nScrPos;
+
+ long nMax = ( bVertical ? GetOutputSizePixel().Height() : GetOutputSizePixel().Width() ) + 1;
+ if (nEntryNo >= nSize)
+ nScrPos = nMax;
+ else
+ {
+ nScrPos = 0;
+ for (SCCOLROW i=GetPos(); i<nEntryNo && nScrPos<nMax; i++)
+ {
+ sal_uInt16 nAdd = GetEntrySize(i);
+ if (nAdd)
+ nScrPos += nAdd;
+ else
+ {
+ SCCOLROW nHidden = GetHiddenCount(i);
+ if (nHidden > 0)
+ i += nHidden - 1;
+ }
+ }
+ }
+
+ if ( IsLayoutRTL() )
+ nScrPos = nMax - nScrPos - 2;
+
+ return nScrPos;
+}
+
+// draw a rectangle across the window's width/height, with the outer part in a lighter color
+
+void ScHeaderControl::DrawShadedRect( long nStart, long nEnd, const Color& rBaseColor )
+{
+ Color aWhite( COL_WHITE );
+
+ Color aInner( rBaseColor ); // highlight color, unchanged
+ Color aCenter( rBaseColor );
+ aCenter.Merge( aWhite, 0xd0 ); // lighten up a bit
+ Color aOuter( rBaseColor );
+ aOuter.Merge( aWhite, 0xa0 ); // lighten up more
+
+ if ( IsMirrored() )
+ std::swap( aInner, aOuter ); // just swap colors instead of positions
+
+ Size aWinSize = GetSizePixel();
+ long nBarSize = bVertical ? aWinSize.Width() : aWinSize.Height();
+ long nCenterPos = (nBarSize / 2) - 1;
+
+ SetLineColor();
+ SetFillColor( aOuter );
+ if (bVertical)
+ DrawRect( Rectangle( 0, nStart, nCenterPos-1, nEnd ) );
+ else
+ DrawRect( Rectangle( nStart, 0, nEnd, nCenterPos-1 ) );
+ SetFillColor( aCenter );
+ if (bVertical)
+ DrawRect( Rectangle( nCenterPos, nStart, nCenterPos, nEnd ) );
+ else
+ DrawRect( Rectangle( nStart, nCenterPos, nEnd, nCenterPos ) );
+ SetFillColor( aInner );
+ if (bVertical)
+ DrawRect( Rectangle( nCenterPos+1, nStart, nBarSize-1, nEnd ) );
+ else
+ DrawRect( Rectangle( nStart, nCenterPos+1, nEnd, nBarSize-1 ) );
+}
+
+//
+// Paint
+//
+
+void ScHeaderControl::Paint( const Rectangle& rRect )
+{
+ // fuer VCL ist es wichtig, wenig Aufrufe zu haben, darum werden die aeusseren
+ // Linien zusammengefasst
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ sal_Bool bHighContrast = rStyleSettings.GetHighContrastMode();
+ sal_Bool bDark = rStyleSettings.GetFaceColor().IsDark();
+ // Use the same distinction for bDark as in Window::DrawSelectionBackground
+
+ Color aTextColor = rStyleSettings.GetButtonTextColor();
+ Color aSelTextColor = rStyleSettings.GetHighlightTextColor();
+ aNormFont.SetColor( aTextColor );
+ if ( bHighContrast )
+ aBoldFont.SetColor( aTextColor );
+ else
+ aBoldFont.SetColor( aSelTextColor );
+ SetTextColor( ( bBoldSet && !bHighContrast ) ? aSelTextColor : aTextColor );
+
+ Color aBlack( COL_BLACK );
+ Color aSelLineColor = rStyleSettings.GetHighlightColor();
+ aSelLineColor.Merge( aBlack, 0xe0 ); // darken just a little bit
+
+ sal_Bool bLayoutRTL = IsLayoutRTL();
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+ sal_Bool bMirrored = IsMirrored();
+
+// const FunctionSet* pFuncSet = pSelEngine->GetFunctionSet();
+ String aString;
+ sal_uInt16 nBarSize;
+ Point aScrPos;
+ Size aTextSize;
+// Size aSize = GetOutputSizePixel();
+
+ if (bVertical)
+ nBarSize = (sal_uInt16) GetSizePixel().Width();
+ else
+ nBarSize = (sal_uInt16) GetSizePixel().Height();
+
+ SCCOLROW nPos = GetPos();
+
+ long nPStart = bVertical ? rRect.Top() : rRect.Left();
+ long nPEnd = bVertical ? rRect.Bottom() : rRect.Right();
+
+ long nTransStart = nPEnd + 1;
+ long nTransEnd = 0;
+
+ long nInitScrPos = 0;
+ if ( bLayoutRTL )
+ {
+ long nTemp = nPStart; // swap nPStart / nPEnd
+ nPStart = nPEnd;
+ nPEnd = nTemp;
+ nTemp = nTransStart; // swap nTransStart / nTransEnd
+ nTransStart = nTransEnd;
+ nTransEnd = nTemp;
+ if ( bVertical ) // start loops from the end
+ nInitScrPos = GetSizePixel().Height() - 1;
+ else
+ nInitScrPos = GetSizePixel().Width() - 1;
+ }
+
+ // aeussere Linien komplett durchzeichnen
+ // Zuerst Ende der letzten Zelle finden
+
+// long nLineEnd = -1;
+ long nLineEnd = nInitScrPos - nLayoutSign;
+
+ for (SCCOLROW i=nPos; i<nSize; i++)
+ {
+ sal_uInt16 nSizePix = GetEntrySize( i );
+ if (nSizePix)
+ {
+ nLineEnd += nSizePix * nLayoutSign;
+
+ if ( bMarkRange && i >= nMarkStart && i <= nMarkEnd )
+ {
+ long nLineStart = nLineEnd - ( nSizePix - 1 ) * nLayoutSign;
+ if ( nLineStart * nLayoutSign < nTransStart * nLayoutSign )
+ nTransStart = nLineStart;
+ if ( nLineEnd * nLayoutSign > nTransEnd * nLayoutSign )
+ nTransEnd = nLineEnd;
+ }
+
+ if ( nLineEnd * nLayoutSign > nPEnd * nLayoutSign )
+ {
+ nLineEnd = nPEnd;
+ break;
+ }
+ }
+ else
+ {
+ SCCOLROW nHidden = GetHiddenCount(i);
+ if (nHidden > 0)
+ i += nHidden - 1;
+ }
+ }
+
+ // background is different for entry area and behind the entries
+
+ Rectangle aFillRect;
+ SetLineColor();
+
+ if ( nLineEnd * nLayoutSign >= nInitScrPos * nLayoutSign )
+ {
+ if ( bHighContrast )
+ {
+ // high contrast: single-color background
+ SetFillColor( rStyleSettings.GetFaceColor() );
+ if ( bVertical )
+ aFillRect = Rectangle( 0, nInitScrPos, nBarSize-1, nLineEnd );
+ else
+ aFillRect = Rectangle( nInitScrPos, 0, nLineEnd, nBarSize-1 );
+ DrawRect( aFillRect );
+ }
+ else
+ {
+ // normal: 3-part background
+ DrawShadedRect( nInitScrPos, nLineEnd, rStyleSettings.GetFaceColor() );
+ }
+ }
+
+ if ( nLineEnd * nLayoutSign < nPEnd * nLayoutSign )
+ {
+ SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::APPBACKGROUND).nColor );
+ if ( bVertical )
+ aFillRect = Rectangle( 0, nLineEnd+nLayoutSign, nBarSize-1, nPEnd );
+ else
+ aFillRect = Rectangle( nLineEnd+nLayoutSign, 0, nPEnd, nBarSize-1 );
+ DrawRect( aFillRect );
+ }
+
+ if ( nLineEnd * nLayoutSign >= nPStart * nLayoutSign )
+ {
+ if ( nTransEnd * nLayoutSign >= nTransStart * nLayoutSign )
+ {
+ if ( bHighContrast )
+ {
+ if ( bDark )
+ {
+ // solid grey background for dark face color is drawn before lines
+
+ SetLineColor();
+ SetFillColor( COL_LIGHTGRAY );
+ if (bVertical)
+ DrawRect( Rectangle( 0, nTransStart, nBarSize-1, nTransEnd ) );
+ else
+ DrawRect( Rectangle( nTransStart, 0, nTransEnd, nBarSize-1 ) );
+ }
+ }
+ else
+ {
+ // background for selection
+
+ DrawShadedRect( nTransStart, nTransEnd, rStyleSettings.GetHighlightColor() );
+ }
+ }
+
+#if 0
+ // 3D border is no longer used
+ SetLineColor( rStyleSettings.GetLightColor() );
+ if (bVertical)
+ DrawLine( Point( 0, nPStart ), Point( 0, nLineEnd ) );
+ else
+ DrawLine( Point( nPStart, 0 ), Point( nLineEnd, 0 ) );
+#endif
+
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ if (bVertical)
+ {
+ long nDarkPos = bMirrored ? 0 : nBarSize-1;
+ DrawLine( Point( nDarkPos, nPStart ), Point( nDarkPos, nLineEnd ) );
+ }
+ else
+ DrawLine( Point( nPStart, nBarSize-1 ), Point( nLineEnd, nBarSize-1 ) );
+
+ // line in different color for selection
+ if ( nTransEnd * nLayoutSign >= nTransStart * nLayoutSign && !bHighContrast )
+ {
+ SetLineColor( aSelLineColor );
+ if (bVertical)
+ {
+ long nDarkPos = bMirrored ? 0 : nBarSize-1;
+ DrawLine( Point( nDarkPos, nTransStart ), Point( nDarkPos, nTransEnd ) );
+ }
+ else
+ DrawLine( Point( nTransStart, nBarSize-1 ), Point( nTransEnd, nBarSize-1 ) );
+ }
+ }
+
+ //
+ // loop through entries several times to avoid changing the line color too often
+ // and to allow merging of lines
+ //
+
+ ScGridMerger aGrid( this, 1, 1 );
+
+ // start at SC_HDRPAINT_BOTTOM instead of 0 - selection doesn't get different
+ // borders, light border at top isn't used anymore
+ // use SC_HDRPAINT_SEL_BOTTOM for different color
+
+ for (sal_uInt16 nPass = SC_HDRPAINT_SEL_BOTTOM; nPass < SC_HDRPAINT_COUNT; nPass++)
+ {
+ // set line color etc. before entry loop
+ switch ( nPass )
+ {
+ case SC_HDRPAINT_SEL_BOTTOM:
+ // same as non-selected for high contrast
+ SetLineColor( bHighContrast ? rStyleSettings.GetDarkShadowColor() : aSelLineColor );
+ break;
+ case SC_HDRPAINT_BOTTOM:
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ break;
+ case SC_HDRPAINT_TEXT:
+ // DrawSelectionBackground is used only for high contrast on light background
+ if ( nTransEnd * nLayoutSign >= nTransStart * nLayoutSign && bHighContrast && !bDark )
+ {
+ // Transparent selection background is drawn after lines, before text.
+ // #109814# Use DrawSelectionBackground to make sure there is a visible
+ // difference. The case of a dark face color, where DrawSelectionBackground
+ // would just paint over the lines, is handled separately (bDark).
+ // Otherwise, GetHighlightColor is used with 80% transparency.
+ // The window's background color (SetBackground) has to be the background
+ // of the cell area, for the contrast comparison in DrawSelectionBackground.
+
+ Rectangle aTransRect;
+ if (bVertical)
+ aTransRect = Rectangle( 0, nTransStart, nBarSize-1, nTransEnd );
+ else
+ aTransRect = Rectangle( nTransStart, 0, nTransEnd, nBarSize-1 );
+ SetBackground( Color( rStyleSettings.GetFaceColor() ) );
+ DrawSelectionBackground( aTransRect, 0, sal_True, sal_False, sal_False );
+ SetBackground();
+ }
+ break;
+ }
+
+ SCCOLROW nCount=0;
+ long nScrPos=nInitScrPos;
+ do
+ {
+ if (bVertical)
+ aScrPos = Point( 0, nScrPos );
+ else
+ aScrPos = Point( nScrPos, 0 );
+
+ SCCOLROW nEntryNo = nCount + nPos;
+ if ( nEntryNo >= nSize ) // MAXCOL/MAXROW
+ nScrPos = nPEnd + nLayoutSign; // beyond nPEnd -> stop
+ else
+ {
+ sal_uInt16 nSizePix = GetEntrySize( nEntryNo );
+
+ if (nSizePix == 0)
+ {
+ SCCOLROW nHidden = GetHiddenCount(nEntryNo);
+ if (nHidden > 0)
+ nCount += nHidden - 1;
+ }
+ else if ((nScrPos+nSizePix*nLayoutSign)*nLayoutSign >= nPStart*nLayoutSign)
+ {
+ Point aEndPos(aScrPos);
+ if (bVertical)
+ aEndPos = Point( aScrPos.X()+nBarSize-1, aScrPos.Y()+(nSizePix-1)*nLayoutSign );
+ else
+ aEndPos = Point( aScrPos.X()+(nSizePix-1)*nLayoutSign, aScrPos.Y()+nBarSize-1 );
+
+ sal_Bool bMark = bMarkRange && nEntryNo >= nMarkStart && nEntryNo <= nMarkEnd;
+ sal_Bool bNextToMark = bMarkRange && nEntryNo + 1 >= nMarkStart && nEntryNo <= nMarkEnd;
+
+ switch ( nPass )
+ {
+ case SC_HDRPAINT_SEL_BOTTOM:
+ case SC_HDRPAINT_BOTTOM:
+ if ( nPass == ( bNextToMark ? SC_HDRPAINT_SEL_BOTTOM : SC_HDRPAINT_BOTTOM ) )
+ {
+ if (bVertical)
+ aGrid.AddHorLine( aScrPos.X(), aEndPos.X(), aEndPos.Y() );
+ else
+ aGrid.AddVerLine( aEndPos.X(), aScrPos.Y(), aEndPos.Y() );
+
+ // thick bottom for hidden rows
+ // (drawn directly, without aGrid)
+ if ( nEntryNo+1 < nSize )
+ if ( GetEntrySize(nEntryNo+1)==0 )
+ {
+ if (bVertical)
+ DrawLine( Point(aScrPos.X(),aEndPos.Y()-nLayoutSign),
+ Point(aEndPos.X(),aEndPos.Y()-nLayoutSign) );
+ else
+ DrawLine( Point(aEndPos.X()-nLayoutSign,aScrPos.Y()),
+ Point(aEndPos.X()-nLayoutSign,aEndPos.Y()) );
+ }
+ }
+ break;
+
+ case SC_HDRPAINT_TEXT:
+ if ( nSizePix > 1 ) // minimal check for small columns/rows
+ {
+ if ( bMark != bBoldSet )
+ {
+ if (bMark)
+ SetFont(aBoldFont);
+ else
+ SetFont(aNormFont);
+ bBoldSet = bMark;
+ }
+ aString = GetEntryText( nEntryNo );
+ aTextSize.Width() = GetTextWidth( aString );
+ aTextSize.Height() = GetTextHeight();
+
+ Point aTxtPos(aScrPos);
+ if (bVertical)
+ {
+ aTxtPos.X() += (nBarSize-aTextSize.Width())/2;
+ aTxtPos.Y() += (nSizePix*nLayoutSign-aTextSize.Height())/2;
+ if ( bMirrored )
+ aTxtPos.X() += 1; // dark border is left instead of right
+ }
+ else
+ {
+ aTxtPos.X() += (nSizePix*nLayoutSign-aTextSize.Width()+1)/2;
+ aTxtPos.Y() += (nBarSize-aTextSize.Height())/2;
+ }
+ DrawText( aTxtPos, aString );
+ }
+ break;
+ }
+
+ // bei Selektion der ganzen Zeile/Spalte:
+ // InvertRect( Rectangle( aScrPos, aEndPos ) );
+ }
+ nScrPos += nSizePix * nLayoutSign; // also if before the visible area
+ }
+ ++nCount;
+ }
+ while ( nScrPos * nLayoutSign <= nPEnd * nLayoutSign );
+
+ aGrid.Flush();
+ }
+}
+
+//
+// Maus - Handling
+//
+
+SCCOLROW ScHeaderControl::GetMousePos( const MouseEvent& rMEvt, sal_Bool& rBorder )
+{
+ sal_Bool bFound=sal_False;
+ SCCOLROW nCount = 1;
+ SCCOLROW nPos = GetPos();
+ SCCOLROW nHitNo = nPos;
+ long nScrPos;
+ long nMousePos = bVertical ? rMEvt.GetPosPixel().Y() : rMEvt.GetPosPixel().X();
+ long nDif;
+ Size aSize = GetOutputSizePixel();
+ long nWinSize = bVertical ? aSize.Height() : aSize.Width();
+
+ sal_Bool bLayoutRTL = IsLayoutRTL();
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+ long nEndPos = bLayoutRTL ? -1 : nWinSize;
+
+ nScrPos = GetScrPos( nPos ) - nLayoutSign;
+ do
+ {
+ SCCOLROW nEntryNo = nCount + nPos;
+
+// nScrPos = GetScrPos( nEntryNo ) - 1;
+
+ if (nEntryNo > nSize)
+ nScrPos = nEndPos + nLayoutSign;
+ else
+ nScrPos += GetEntrySize( nEntryNo - 1 ) * nLayoutSign; //! GetHiddenCount() ??
+
+ nDif = nMousePos - nScrPos;
+ if (nDif >= -2 && nDif <= 2 && nCount > 0)
+ {
+ bFound=sal_True;
+ nHitNo=nEntryNo-1;
+ }
+ else if (nDif * nLayoutSign >= 0 && nEntryNo < nSize)
+ nHitNo = nEntryNo;
+ ++nCount;
+ }
+ while ( nScrPos * nLayoutSign < nEndPos * nLayoutSign && nDif * nLayoutSign > 0 );
+
+ rBorder = bFound;
+ return nHitNo;
+}
+
+bool ScHeaderControl::IsSelectionAllowed(SCCOLROW nPos) const
+{
+ ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current());
+ if (!pViewSh)
+ return false;
+
+ ScViewData* pViewData = pViewSh->GetViewData();
+ sal_uInt16 nTab = pViewData->GetTabNo();
+ ScDocument* pDoc = pViewData->GetDocument();
+ const ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ bool bSelectAllowed = true;
+ if ( pProtect && pProtect->isProtected() )
+ {
+ // This sheet is protected. Check if a context menu is allowed on this cell.
+ bool bCellsProtected = false;
+ if (bVertical)
+ {
+ // row header
+ SCROW nRPos = static_cast<SCROW>(nPos);
+ bCellsProtected = pDoc->HasAttrib(0, nRPos, nTab, MAXCOL, nRPos, nTab, HASATTR_PROTECTED);
+ }
+ else
+ {
+ // column header
+ SCCOL nCPos = static_cast<SCCOL>(nPos);
+ bCellsProtected = pDoc->HasAttrib(nCPos, 0, nTab, nCPos, MAXROW, nTab, HASATTR_PROTECTED);
+ }
+
+ bool bSelProtected = pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+ bool bSelUnprotected = pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
+
+ if (bCellsProtected)
+ bSelectAllowed = bSelProtected;
+ else
+ bSelectAllowed = bSelUnprotected;
+ }
+ return bSelectAllowed;
+}
+
+void ScHeaderControl::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if (IsDisabled())
+ return;
+
+ bIgnoreMove = sal_False;
+ SelectWindow();
+
+ sal_Bool bFound;
+ SCCOLROW nHitNo = GetMousePos( rMEvt, bFound );
+ if (!IsSelectionAllowed(nHitNo))
+ return;
+
+ if ( bFound && rMEvt.IsLeft() && ResizeAllowed() )
+ {
+ nDragNo = nHitNo;
+ sal_uInt16 nClicks = rMEvt.GetClicks();
+ if ( nClicks && nClicks%2==0 )
+ {
+ SetEntrySize( nDragNo, HDR_SIZE_OPTIMUM );
+ SetPointer( Pointer( POINTER_ARROW ) );
+ }
+ else
+ {
+ if (bVertical)
+ nDragStart = rMEvt.GetPosPixel().Y();
+ else
+ nDragStart = rMEvt.GetPosPixel().X();
+ nDragPos = nDragStart;
+ ShowDragHelp();
+ DrawInvert( nDragPos );
+
+ // CaptureMouse();
+ StartTracking();
+ bDragging = sal_True;
+ bDragMoved = sal_False;
+ }
+ }
+ else if (rMEvt.IsLeft())
+ {
+ pSelEngine->SetWindow( this );
+ Point aPoint;
+ Rectangle aVis( aPoint,GetOutputSizePixel() );
+ if (bVertical)
+ aVis.Left() = LONG_MIN, aVis.Right() = LONG_MAX;
+ else
+ aVis.Top() = LONG_MIN, aVis.Bottom() = LONG_MAX;
+ pSelEngine->SetVisibleArea( aVis );
+
+ SetMarking( sal_True ); // muss vor SelMouseButtonDown sein
+ pSelEngine->SelMouseButtonDown( rMEvt );
+
+ // #74215# In column/row headers a simple click already is a selection.
+ // -> Call SelMouseMove to ensure CreateAnchor is called (and DestroyAnchor
+ // if the next click is somewhere else with Control key).
+ pSelEngine->SelMouseMove( rMEvt );
+
+ if (IsMouseCaptured())
+ {
+ // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
+ //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
+ ReleaseMouse();
+ StartTracking();
+ }
+ }
+}
+
+void ScHeaderControl::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if ( IsDisabled() )
+ return;
+
+ SetMarking( sal_False );
+ bIgnoreMove = sal_False;
+// sal_Bool bFound;
+// SCCOLROW nHitNo = GetMousePos( rMEvt, bFound );
+
+ if ( bDragging )
+ {
+ DrawInvert( nDragPos );
+ ReleaseMouse();
+ bDragging = sal_False;
+
+ long nScrPos = GetScrPos( nDragNo );
+ long nMousePos = bVertical ? rMEvt.GetPosPixel().Y() : rMEvt.GetPosPixel().X();
+ sal_Bool bLayoutRTL = IsLayoutRTL();
+ long nNewWidth = bLayoutRTL ? ( nScrPos - nMousePos + 1 )
+ : ( nMousePos + 2 - nScrPos );
+
+ if ( nNewWidth < 0 /* && !IsSelected(nDragNo) */ )
+ {
+ SCCOLROW nStart = 0;
+ SCCOLROW nEnd = nDragNo;
+ while (nNewWidth < 0)
+ {
+ nStart = nDragNo;
+ if (nDragNo>0)
+ {
+ --nDragNo;
+ nNewWidth += GetEntrySize( nDragNo ); //! GetHiddenCount() ???
+ }
+ else
+ nNewWidth = 0;
+ }
+ HideEntries( nStart, nEnd );
+ }
+ else
+ {
+ if (nNewWidth<0) nNewWidth=0;
+ if (bDragMoved)
+ SetEntrySize( nDragNo, (sal_uInt16) nNewWidth );
+ }
+ }
+ else
+ {
+ pSelEngine->SelMouseButtonUp( rMEvt );
+ ReleaseMouse();
+ }
+}
+
+void ScHeaderControl::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( IsDisabled() )
+ {
+ SetPointer( Pointer( POINTER_ARROW ) );
+ return;
+ }
+
+ sal_Bool bFound;
+ (void)GetMousePos( rMEvt, bFound );
+
+ if ( bDragging )
+ {
+ long nNewPos = bVertical ? rMEvt.GetPosPixel().Y() : rMEvt.GetPosPixel().X();
+ if ( nNewPos != nDragPos )
+ {
+ DrawInvert( nDragPos );
+ nDragPos = nNewPos;
+ ShowDragHelp();
+ DrawInvert( nDragPos );
+
+ if (nDragPos <= nDragStart-SC_DRAG_MIN || nDragPos >= nDragStart+SC_DRAG_MIN)
+ bDragMoved = sal_True;
+ }
+ }
+ else
+ {
+ if ( bFound && rMEvt.GetButtons()==0 && ResizeAllowed() )
+ SetPointer( Pointer( bVertical ? POINTER_VSIZEBAR : POINTER_HSIZEBAR ) );
+ else
+ SetPointer( Pointer( POINTER_ARROW ) );
+
+ if (!bIgnoreMove)
+ pSelEngine->SelMouseMove( rMEvt );
+ }
+}
+
+void ScHeaderControl::Tracking( const TrackingEvent& rTEvt )
+{
+ // Weil die SelectionEngine kein Tracking kennt, die Events nur auf
+ // die verschiedenen MouseHandler verteilen...
+
+ if ( rTEvt.IsTrackingCanceled() )
+ StopMarking();
+ else if ( rTEvt.IsTrackingEnded() )
+ MouseButtonUp( rTEvt.GetMouseEvent() );
+ else
+ MouseMove( rTEvt.GetMouseEvent() );
+}
+
+void ScHeaderControl::Command( const CommandEvent& rCEvt )
+{
+ sal_uInt16 nCmd = rCEvt.GetCommand();
+ if ( nCmd == COMMAND_CONTEXTMENU )
+ {
+ StopMarking(); // Selektion / Dragging beenden
+
+ // Popup ausfuehren
+
+ ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell,
+ SfxViewShell::Current() );
+ if ( pViewSh )
+ {
+ if ( rCEvt.IsMouseEvent() )
+ {
+ // #i18735# select the column/row under the mouse pointer
+ ScViewData* pViewData = pViewSh->GetViewData();
+
+ SelectWindow(); // also deselects drawing objects, stops draw text edit
+ if ( pViewData->HasEditView( pViewData->GetActivePart() ) )
+ SC_MOD()->InputEnterHandler(); // always end edit mode
+
+ MouseEvent aMEvt( rCEvt.GetMousePosPixel() );
+ sal_Bool bBorder;
+ SCCOLROW nPos = GetMousePos( aMEvt, bBorder );
+ if (!IsSelectionAllowed(nPos))
+ // Selecting this cell is not allowed, neither is context menu.
+ return;
+
+ SCTAB nTab = pViewData->GetTabNo();
+ ScRange aNewRange;
+ if ( bVertical )
+ aNewRange = ScRange( 0, sal::static_int_cast<SCROW>(nPos), nTab,
+ MAXCOL, sal::static_int_cast<SCROW>(nPos), nTab );
+ else
+ aNewRange = ScRange( sal::static_int_cast<SCCOL>(nPos), 0, nTab,
+ sal::static_int_cast<SCCOL>(nPos), MAXROW, nTab );
+
+ // see if any part of the range is already selected
+ sal_Bool bSelected = sal_False;
+ ScRangeList aRanges;
+ pViewData->GetMarkData().FillRangeListWithMarks( &aRanges, sal_False );
+ sal_uLong nRangeCount = aRanges.Count();
+ for (sal_uLong i=0; i<nRangeCount && !bSelected; i++)
+ if ( aRanges.GetObject(i)->Intersects( aNewRange ) )
+ bSelected = sal_True;
+
+ // select the range if no part of it was selected
+ if ( !bSelected )
+ pViewSh->MarkRange( aNewRange );
+ }
+
+ ScResId aResId( bVertical ? RID_POPUP_ROWHEADER : RID_POPUP_COLHEADER );
+ pViewSh->GetDispatcher()->ExecutePopup( aResId );
+ }
+ }
+ else if ( nCmd == COMMAND_STARTDRAG )
+ {
+ pSelEngine->Command( rCEvt );
+ }
+}
+
+void ScHeaderControl::StopMarking()
+{
+ if ( bDragging )
+ {
+ DrawInvert( nDragPos );
+ bDragging = sal_False;
+ }
+
+ SetMarking( sal_False );
+ bIgnoreMove = sal_True;
+
+ // #86260# don't call pSelEngine->Reset, so selection across the parts of
+ // a split/frozen view is possible
+
+ ReleaseMouse();
+}
+
+void ScHeaderControl::ShowDragHelp()
+{
+ if (Help::IsQuickHelpEnabled())
+ {
+ long nScrPos = GetScrPos( nDragNo );
+ sal_Bool bLayoutRTL = IsLayoutRTL();
+ long nVal = bLayoutRTL ? ( nScrPos - nDragPos + 1 )
+ : ( nDragPos + 2 - nScrPos );
+
+ String aHelpStr = GetDragHelp( nVal );
+ Point aPos = OutputToScreenPixel( Point(0,0) );
+ Size aSize = GetSizePixel();
+
+ Point aMousePos = OutputToScreenPixel(GetPointerPosPixel());
+
+ Rectangle aRect;
+ sal_uInt16 nAlign;
+ if (!bVertical)
+ {
+ // oberhalb
+ aRect.Left() = aMousePos.X();
+ aRect.Top() = aPos.Y() - 4;
+ nAlign = QUICKHELP_BOTTOM|QUICKHELP_CENTER;
+ }
+ else
+ {
+ // rechts oben
+ aRect.Left() = aPos.X() + aSize.Width() + 8;
+ aRect.Top() = aMousePos.Y() - 2;
+ nAlign = QUICKHELP_LEFT|QUICKHELP_BOTTOM;
+ }
+
+ aRect.Right() = aRect.Left();
+ aRect.Bottom() = aRect.Top();
+
+ Help::ShowQuickHelp(this, aRect, aHelpStr, nAlign);
+ }
+}
+
+void ScHeaderControl::RequestHelp( const HelpEvent& rHEvt )
+{
+ // Wenn eigene QuickHelp angezeigt wird, nicht durch RequestHelp
+ // wieder wegnehmen lassen
+
+ sal_Bool bOwn = bDragging && Help::IsQuickHelpEnabled();
+ if (!bOwn)
+ Window::RequestHelp(rHEvt);
+}
+
+// -----------------------------------------------------------------------
+// Dummys fuer virtuelle Methoden
+// -----------------------------------------------------------------------
+
+SCCOLROW ScHeaderControl::GetHiddenCount( SCCOLROW nEntryNo )
+{
+ SCCOLROW nHidden = 0;
+ while ( nEntryNo < nSize && GetEntrySize( nEntryNo ) == 0 )
+ {
+ ++nEntryNo;
+ ++nHidden;
+ }
+ return nHidden;
+}
+
+sal_Bool ScHeaderControl::IsLayoutRTL()
+{
+ return sal_False;
+}
+
+sal_Bool ScHeaderControl::IsMirrored()
+{
+ return sal_False;
+}
+
+sal_Bool ScHeaderControl::IsDisabled()
+{
+ return sal_False;
+}
+
+sal_Bool ScHeaderControl::ResizeAllowed()
+{
+ return sal_True;
+}
+
+void ScHeaderControl::SelectWindow()
+{
+}
+
+void ScHeaderControl::DrawInvert( long /* nDragPos */ )
+{
+}
+
+String ScHeaderControl::GetDragHelp( long /* nVal */ )
+{
+ return EMPTY_STRING;
+}
+
+void ScHeaderControl::SetMarking( sal_Bool /* bSet */ )
+{
+}
+
+
+
diff --git a/sc/source/ui/view/hintwin.cxx b/sc/source/ui/view/hintwin.cxx
new file mode 100644
index 000000000000..1828cbd83e55
--- /dev/null
+++ b/sc/source/ui/view/hintwin.cxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// System - Includes -----------------------------------------------------
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "hintwin.hxx"
+#include "global.hxx"
+
+#define HINT_LINESPACE 2
+#define HINT_INDENT 3
+#define HINT_MARGIN 4
+
+//==================================================================
+
+ScHintWindow::ScHintWindow( Window* pParent, const String& rTit, const String& rMsg ) :
+ Window( pParent, WinBits( WB_BORDER ) ),
+ aTitle( rTit ),
+ aMessage( rMsg )
+{
+ aMessage.ConvertLineEnd( LINEEND_CR );
+
+ // Hellgelb, wie Notizen in detfunc.cxx
+ Color aYellow( 255,255,192 ); // hellgelb
+ SetBackground( aYellow );
+
+ aTextFont = GetFont();
+ aTextFont.SetTransparent( sal_True );
+ aTextFont.SetWeight( WEIGHT_NORMAL );
+ aHeadFont = aTextFont;
+ aHeadFont.SetWeight( WEIGHT_BOLD );
+
+ SetFont( aHeadFont );
+ Size aHeadSize( GetTextWidth( aTitle ), GetTextHeight() );
+ SetFont( aTextFont );
+
+ Size aTextSize;
+ xub_StrLen nIndex = 0;
+ while ( nIndex != STRING_NOTFOUND )
+ {
+ String aLine = aMessage.GetToken( 0, CHAR_CR, nIndex );
+ Size aLineSize( GetTextWidth( aLine ), GetTextHeight() );
+ nTextHeight = aLineSize.Height();
+ aTextSize.Height() += nTextHeight;
+ if ( aLineSize.Width() > aTextSize.Width() )
+ aTextSize.Width() = aLineSize.Width();
+ }
+ aTextSize.Width() += HINT_INDENT;
+
+ aTextStart = Point( HINT_MARGIN + HINT_INDENT,
+ aHeadSize.Height() + HINT_MARGIN + HINT_LINESPACE );
+
+ Size aWinSize( Max( aHeadSize.Width(), aTextSize.Width() ) + 2 * HINT_MARGIN + 1,
+ aHeadSize.Height() + aTextSize.Height() + HINT_LINESPACE + 2 * HINT_MARGIN + 1 );
+ SetOutputSizePixel( aWinSize );
+}
+
+
+ScHintWindow::~ScHintWindow()
+{
+}
+
+
+void __EXPORT ScHintWindow::Paint( const Rectangle& /* rRect */ )
+{
+ SetFont( aHeadFont );
+ DrawText( Point(HINT_MARGIN,HINT_MARGIN), aTitle );
+
+ SetFont( aTextFont );
+ xub_StrLen nIndex = 0;
+ Point aLineStart = aTextStart;
+ while ( nIndex != STRING_NOTFOUND )
+ {
+ String aLine = aMessage.GetToken( 0, CHAR_CR, nIndex );
+ DrawText( aLineStart, aLine );
+ aLineStart.Y() += nTextHeight;
+ }
+}
diff --git a/sc/source/ui/view/imapwrap.cxx b/sc/source/ui/view/imapwrap.cxx
new file mode 100644
index 000000000000..0d1321e61709
--- /dev/null
+++ b/sc/source/ui/view/imapwrap.cxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svx/imapdlg.hxx>
+#include <sfx2/viewfrm.hxx>
+
+
+sal_uInt16 ScIMapChildWindowId()
+{
+ return SvxIMapDlgChildWindow::GetChildWindowId();
+}
+
+SvxIMapDlg* ScGetIMapDlg()
+{
+ //! pass view frame here and in SVXIMAPDLG()
+
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if( pViewFrm && pViewFrm->HasChildWindow( SvxIMapDlgChildWindow::GetChildWindowId() ) )
+ return SVXIMAPDLG();
+ else
+ return NULL;
+}
+
+void ScIMapDlgSet( const Graphic& rGraphic, const ImageMap* pImageMap,
+ const TargetList* pTargetList, void* pEditingObj )
+{
+ SvxIMapDlgChildWindow::UpdateIMapDlg( rGraphic, pImageMap, pTargetList, pEditingObj );
+}
+
+const void* ScIMapDlgGetObj( SvxIMapDlg* pDlg )
+{
+ if ( pDlg )
+ return pDlg->GetEditingObject();
+ else
+ return NULL;
+}
+
+const ImageMap& ScIMapDlgGetMap( SvxIMapDlg* pDlg )
+{
+ return pDlg->GetImageMap();
+}
+
+
+
+
diff --git a/sc/source/ui/view/invmerge.cxx b/sc/source/ui/view/invmerge.cxx
new file mode 100644
index 000000000000..587462d59267
--- /dev/null
+++ b/sc/source/ui/view/invmerge.cxx
@@ -0,0 +1,192 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include <vcl/window.hxx>
+#include <tools/debug.hxx>
+
+#include "invmerge.hxx"
+
+//------------------------------------------------------------------
+
+ScInvertMerger::ScInvertMerger( Window* pWindow ) :
+ pWin( pWindow ),
+ pRects( NULL )
+{
+ // both rectangles empty
+}
+
+ScInvertMerger::ScInvertMerger( ::std::vector< Rectangle >* pRectangles ) :
+ pWin( NULL ),
+ pRects( pRectangles )
+{
+ // collect rectangles instead of inverting
+}
+
+ScInvertMerger::~ScInvertMerger()
+{
+ Flush();
+}
+
+void ScInvertMerger::Flush()
+{
+ FlushLine();
+ FlushTotal();
+
+ DBG_ASSERT( aLineRect.IsEmpty() && aTotalRect.IsEmpty(), "Flush: not empty" );
+
+ if ( pRects )
+ {
+ //
+ // also join vertically if there are non-adjacent columns involved
+ //
+
+ size_t nComparePos = 0;
+ while ( nComparePos < pRects->size() )
+ {
+ Rectangle aCompRect = (*pRects)[nComparePos];
+ sal_Int32 nBottom = aCompRect.Bottom();
+ size_t nOtherPos = nComparePos + 1;
+
+ while ( nOtherPos < pRects->size() )
+ {
+ Rectangle aOtherRect = (*pRects)[nOtherPos];
+ if ( aOtherRect.Top() > nBottom + 1 )
+ {
+ // rectangles are sorted, so we can stop searching
+ break;
+ }
+ if ( aOtherRect.Top() == nBottom + 1 &&
+ aOtherRect.Left() == aCompRect.Left() &&
+ aOtherRect.Right() == aCompRect.Right() )
+ {
+ // extend first rectangle
+ nBottom = aOtherRect.Bottom();
+ aCompRect.Bottom() = nBottom;
+ (*pRects)[nComparePos].Bottom() = nBottom;
+
+ // remove second rectangle
+ pRects->erase( pRects->begin() + nOtherPos );
+
+ // continue at unmodified nOtherPos
+ }
+ else
+ ++nOtherPos;
+ }
+
+ ++nComparePos;
+ }
+ }
+}
+
+void ScInvertMerger::FlushTotal()
+{
+ if( aTotalRect.IsEmpty() )
+ return; // nothing to do
+
+ if ( pWin )
+ pWin->Invert( aTotalRect, INVERT_HIGHLIGHT );
+ else if ( pRects )
+ pRects->push_back( aTotalRect );
+
+ aTotalRect.SetEmpty();
+}
+
+void ScInvertMerger::FlushLine()
+{
+ if( aLineRect.IsEmpty() )
+ return; // nothing to do
+
+ if ( aTotalRect.IsEmpty() )
+ {
+ aTotalRect = aLineRect; // start new total rect
+ }
+ else
+ {
+ if ( aLineRect.Left() == aTotalRect.Left() &&
+ aLineRect.Right() == aTotalRect.Right() &&
+ aLineRect.Top() == aTotalRect.Bottom() + 1 )
+ {
+ // extend total rect
+ aTotalRect.Bottom() = aLineRect.Bottom();
+ }
+ else
+ {
+ FlushTotal(); // draw old total rect
+ aTotalRect = aLineRect; // and start new one
+ }
+ }
+
+ aLineRect.SetEmpty();
+}
+
+void ScInvertMerger::AddRect( const Rectangle& rRect )
+{
+ Rectangle aJustified = rRect;
+ if ( rRect.Left() > rRect.Right() ) // switch for RTL layout
+ {
+ aJustified.Left() = rRect.Right();
+ aJustified.Right() = rRect.Left();
+ }
+
+ if ( aLineRect.IsEmpty() )
+ {
+ aLineRect = aJustified; // start new line rect
+ }
+ else
+ {
+ sal_Bool bDone = sal_False;
+ if ( aJustified.Top() == aLineRect.Top() &&
+ aJustified.Bottom() == aLineRect.Bottom() )
+ {
+ // try to extend line rect
+ if ( aJustified.Left() == aLineRect.Right() + 1 )
+ {
+ aLineRect.Right() = aJustified.Right();
+ bDone = sal_True;
+ }
+ else if ( aJustified.Right() + 1 == aLineRect.Left() ) // for RTL layout
+ {
+ aLineRect.Left() = aJustified.Left();
+ bDone = sal_True;
+ }
+ }
+ if (!bDone)
+ {
+ FlushLine(); // use old line rect for total rect
+ aLineRect = aJustified; // and start new one
+ }
+ }
+}
+
+
+
+
diff --git a/sc/source/ui/view/makefile.mk b/sc/source/ui/view/makefile.mk
new file mode 100644
index 000000000000..1b2fef913fc2
--- /dev/null
+++ b/sc/source/ui/view/makefile.mk
@@ -0,0 +1,173 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+PRJ=..$/..$/..
+
+PRJNAME=sc
+TARGET=view
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : scpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sc.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+# drawattr.cxx fuer IDL (enums), sollte in den Svx gehen??
+
+
+SLOFILES = \
+ $(SLO)$/tabview.obj \
+ $(SLO)$/tabview2.obj \
+ $(SLO)$/tabview3.obj \
+ $(SLO)$/tabview4.obj \
+ $(SLO)$/tabview5.obj \
+ $(SLO)$/viewfunc.obj \
+ $(SLO)$/viewfun2.obj \
+ $(SLO)$/viewfun3.obj \
+ $(SLO)$/viewfun4.obj \
+ $(SLO)$/viewfun5.obj \
+ $(SLO)$/viewfun6.obj \
+ $(SLO)$/viewfun7.obj \
+ $(SLO)$/dbfunc.obj \
+ $(SLO)$/dbfunc2.obj \
+ $(SLO)$/dbfunc3.obj \
+ $(SLO)$/dbfunc4.obj \
+ $(SLO)$/tabvwsh.obj \
+ $(SLO)$/tabvwsh2.obj \
+ $(SLO)$/tabvwsh3.obj \
+ $(SLO)$/tabvwsh4.obj \
+ $(SLO)$/tabvwsh5.obj \
+ $(SLO)$/tabvwsh8.obj \
+ $(SLO)$/tabvwsh9.obj \
+ $(SLO)$/tabvwsha.obj \
+ $(SLO)$/tabvwshb.obj \
+ $(SLO)$/tabvwshc.obj \
+ $(SLO)$/tabvwshd.obj \
+ $(SLO)$/tabvwshe.obj \
+ $(SLO)$/tabvwshf.obj \
+ $(SLO)$/tabvwshg.obj \
+ $(SLO)$/tabvwshh.obj \
+ $(SLO)$/printfun.obj \
+ $(SLO)$/pfuncache.obj \
+ $(SLO)$/preview.obj \
+ $(SLO)$/prevwsh.obj \
+ $(SLO)$/prevwsh2.obj \
+ $(SLO)$/prevloc.obj \
+ $(SLO)$/editsh.obj \
+ $(SLO)$/pivotsh.obj \
+ $(SLO)$/auditsh.obj \
+ $(SLO)$/gridwin.obj \
+ $(SLO)$/gridwin2.obj \
+ $(SLO)$/gridwin3.obj \
+ $(SLO)$/gridwin4.obj \
+ $(SLO)$/gridwin5.obj \
+ $(SLO)$/drawview.obj \
+ $(SLO)$/drawvie2.obj \
+ $(SLO)$/drawvie3.obj \
+ $(SLO)$/drawvie4.obj \
+ $(SLO)$/drawutil.obj \
+ $(SLO)$/output.obj \
+ $(SLO)$/output2.obj \
+ $(SLO)$/output3.obj \
+ $(SLO)$/gridmerg.obj \
+ $(SLO)$/invmerge.obj \
+ $(SLO)$/select.obj \
+ $(SLO)$/olinewin.obj \
+ $(SLO)$/hintwin.obj \
+ $(SLO)$/notemark.obj \
+ $(SLO)$/tabcont.obj \
+ $(SLO)$/tabsplit.obj \
+ $(SLO)$/viewutil.obj \
+ $(SLO)$/hdrcont.obj \
+ $(SLO)$/colrowba.obj \
+ $(SLO)$/olkact.obj \
+ $(SLO)$/galwrap.obj \
+ $(SLO)$/imapwrap.obj \
+ $(SLO)$/reffact.obj \
+ $(SLO)$/selectionstate.obj \
+ $(SLO)$/spelleng.obj \
+ $(SLO)$/spelldialog.obj \
+ $(SLO)$/waitoff.obj \
+ $(SLO)$/cellsh.obj \
+ $(SLO)$/cellsh1.obj\
+ $(SLO)$/cellsh2.obj\
+ $(SLO)$/cellsh3.obj\
+ $(SLO)$/cellsh4.obj\
+ $(SLO)$/formatsh.obj\
+ $(SLO)$/pgbrksh.obj\
+ $(SLO)$/viewdata.obj\
+ $(SLO)$/scextopt.obj
+
+.IF "$(OS)$(COM)$(CPUNAME)"=="LINUXGCCSPARC"
+ NOOPTFILES= \
+ $(SLO)$/drawview.obj \
+ $(SLO)$/dbfunc2.obj \
+ $(SLO)$/tabvwsh2.obj \
+ $(SLO)$/viewfun4.obj \
+ $(SLO)$/viewfun2.obj
+.ELIF "$(OS)$(COM)$(CPUNAME)"=="SOLARISC52INTEL"
+ NOOPTFILES=\
+ $(SLO)$/drawview.obj \
+ $(SLO)$/dbfunc2.obj \
+ $(SLO)$/tabvwsh2.obj
+.ELSE
+ NOOPTFILES=\
+ $(SLO)$/drawview.obj \
+ $(SLO)$/dbfunc2.obj \
+ $(SLO)$/tabvwsh2.obj
+.ENDIF
+
+EXCEPTIONSFILES= \
+ $(SLO)$/dbfunc3.obj \
+ $(SLO)$/gridwin.obj \
+ $(SLO)$/invmerge.obj \
+ $(SLO)$/output2.obj \
+ $(SLO)$/pfuncache.obj \
+ $(SLO)$/spelldialog.obj \
+ $(SLO)$/cellsh1.obj \
+ $(SLO)$/drawvie4.obj \
+ $(SLO)$/formatsh.obj \
+ $(SLO)$/gridwin2.obj \
+ $(SLO)$/scextopt.obj \
+ $(SLO)$/tabvwshb.obj \
+ $(SLO)$/tabvwshf.obj \
+ $(SLO)$/viewdata.obj \
+ $(SLO)$/viewfunc.obj \
+ $(SLO)$/viewfun2.obj \
+ $(SLO)$/viewfun3.obj \
+ $(SLO)$/viewfun5.obj \
+ $(SLO)$/viewfun7.obj \
+ $(SLO)$/reffact.obj
+
+# goal seek -O2
+
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/sc/source/ui/view/notemark.cxx b/sc/source/ui/view/notemark.cxx
new file mode 100644
index 000000000000..2bcbf481069e
--- /dev/null
+++ b/sc/source/ui/view/notemark.cxx
@@ -0,0 +1,200 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <svx/svdoutl.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdocapt.hxx>
+#include <sfx2/printer.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svl/itempool.hxx>
+#include <vcl/svapp.hxx>
+
+#include "notemark.hxx"
+#include "document.hxx"
+#include "postit.hxx"
+
+#define SC_NOTEMARK_TIME 800
+#define SC_NOTEMARK_SHORT 70
+
+// -----------------------------------------------------------------------
+
+ScNoteMarker::ScNoteMarker( Window* pWin, Window* pRight, Window* pBottom, Window* pDiagonal,
+ ScDocument* pD, ScAddress aPos, const String& rUser,
+ const MapMode& rMap, sal_Bool bLeftEdge, sal_Bool bForce, sal_Bool bKeyboard ) :
+ pWindow( pWin ),
+ pRightWin( pRight ),
+ pBottomWin( pBottom ),
+ pDiagWin( pDiagonal ),
+ pDoc( pD ),
+ aDocPos( aPos ),
+ aUserText( rUser ),
+ aMapMode( rMap ),
+ bLeft( bLeftEdge ),
+ bByKeyboard( bKeyboard ),
+ pModel( NULL ),
+ pObject( NULL ),
+ bVisible( sal_False )
+{
+ Size aSizePixel = pWindow->GetOutputSizePixel();
+ if( pRightWin )
+ aSizePixel.Width() += pRightWin->GetOutputSizePixel().Width();
+ if( pBottomWin )
+ aSizePixel.Height() += pBottomWin->GetOutputSizePixel().Height();
+ Rectangle aVisPixel( Point( 0, 0 ), aSizePixel );
+ aVisRect = pWindow->PixelToLogic( aVisPixel, aMapMode );
+
+ aTimer.SetTimeoutHdl( LINK( this, ScNoteMarker, TimeHdl ) );
+ aTimer.SetTimeout( bForce ? SC_NOTEMARK_SHORT : SC_NOTEMARK_TIME );
+ aTimer.Start();
+}
+
+ScNoteMarker::~ScNoteMarker()
+{
+ InvalidateWin();
+
+ delete pModel;
+}
+
+IMPL_LINK( ScNoteMarker, TimeHdl, Timer*, EMPTYARG )
+{
+ if (!bVisible)
+ {
+ SvtPathOptions aPathOpt;
+ String aPath = aPathOpt.GetPalettePath();
+ pModel = new SdrModel(aPath);
+ pModel->SetScaleUnit(MAP_100TH_MM);
+ SfxItemPool& rPool = pModel->GetItemPool();
+ rPool.SetDefaultMetric(SFX_MAPUNIT_100TH_MM);
+ rPool.FreezeIdRanges();
+
+ OutputDevice* pPrinter = pDoc->GetRefDevice();
+ if (pPrinter)
+ {
+ // Am Outliner des Draw-Model ist auch der Drucker als RefDevice gesetzt,
+ // und es soll einheitlich aussehen.
+ Outliner& rOutliner = pModel->GetDrawOutliner();
+ rOutliner.SetRefDevice(pPrinter);
+ }
+
+ if( SdrPage* pPage = pModel->AllocPage( sal_False ) )
+ {
+ pObject = ScNoteUtil::CreateTempCaption( *pDoc, aDocPos, *pPage, aUserText, aVisRect, bLeft );
+ if( pObject )
+ aRect = pObject->GetCurrentBoundRect();
+
+ // #39351# Page einfuegen damit das Model sie kennt und auch deleted
+ pModel->InsertPage( pPage );
+
+ }
+ bVisible = sal_True;
+ }
+
+ Draw();
+ return 0;
+}
+
+void lcl_DrawWin( SdrObject* pObject, Window* pWindow, const MapMode& rMap )
+{
+ MapMode aOld = pWindow->GetMapMode();
+ pWindow->SetMapMode( rMap );
+
+ sal_uLong nOldDrawMode = pWindow->GetDrawMode();
+ if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ pWindow->SetDrawMode( nOldDrawMode | DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL |
+ DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT );
+ }
+
+ pObject->SingleObjectPainter( *pWindow ); // #110094#-17
+
+ pWindow->SetDrawMode( nOldDrawMode );
+ pWindow->SetMapMode( aOld );
+}
+
+MapMode lcl_MoveMapMode( const MapMode& rMap, const Size& rMove )
+{
+ MapMode aNew = rMap;
+ Point aOrigin = aNew.GetOrigin();
+ aOrigin.X() -= rMove.Width();
+ aOrigin.Y() -= rMove.Height();
+ aNew.SetOrigin(aOrigin);
+ return aNew;
+}
+
+void ScNoteMarker::Draw()
+{
+ if ( pObject && bVisible )
+ {
+ lcl_DrawWin( pObject, pWindow, aMapMode );
+
+ if ( pRightWin || pBottomWin )
+ {
+ Size aWinSize = pWindow->PixelToLogic( pWindow->GetOutputSizePixel(), aMapMode );
+ if ( pRightWin )
+ lcl_DrawWin( pObject, pRightWin,
+ lcl_MoveMapMode( aMapMode, Size( aWinSize.Width(), 0 ) ) );
+ if ( pBottomWin )
+ lcl_DrawWin( pObject, pBottomWin,
+ lcl_MoveMapMode( aMapMode, Size( 0, aWinSize.Height() ) ) );
+ if ( pDiagWin )
+ lcl_DrawWin( pObject, pDiagWin, lcl_MoveMapMode( aMapMode, aWinSize ) );
+ }
+ }
+}
+
+void ScNoteMarker::InvalidateWin()
+{
+ if (bVisible)
+ {
+ pWindow->Invalidate( pWindow->LogicToLogic(aRect, aMapMode, pWindow->GetMapMode()) );
+
+ if ( pRightWin || pBottomWin )
+ {
+ Size aWinSize = pWindow->PixelToLogic( pWindow->GetOutputSizePixel(), aMapMode );
+ if ( pRightWin )
+ pRightWin->Invalidate( pRightWin->LogicToLogic(aRect,
+ lcl_MoveMapMode( aMapMode, Size( aWinSize.Width(), 0 ) ),
+ pRightWin->GetMapMode()) );
+ if ( pBottomWin )
+ pBottomWin->Invalidate( pBottomWin->LogicToLogic(aRect,
+ lcl_MoveMapMode( aMapMode, Size( 0, aWinSize.Height() ) ),
+ pBottomWin->GetMapMode()) );
+ if ( pDiagWin )
+ pDiagWin->Invalidate( pDiagWin->LogicToLogic(aRect,
+ lcl_MoveMapMode( aMapMode, aWinSize ),
+ pDiagWin->GetMapMode()) );
+ }
+ }
+}
+
+
+
+
diff --git a/sc/source/ui/view/olinewin.cxx b/sc/source/ui/view/olinewin.cxx
new file mode 100644
index 000000000000..d3a750845154
--- /dev/null
+++ b/sc/source/ui/view/olinewin.cxx
@@ -0,0 +1,1045 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include <vcl/svapp.hxx>
+#include <vcl/taskpanelist.hxx>
+
+#include "olinewin.hxx"
+#include "olinetab.hxx"
+#include "document.hxx"
+#include "dbfunc.hxx"
+#include "sc.hrc"
+
+// ============================================================================
+
+const long SC_OL_BITMAPSIZE = 12;
+const long SC_OL_POSOFFSET = 2;
+
+const size_t SC_OL_NOLEVEL = static_cast< size_t >( -1 );
+const size_t SC_OL_HEADERENTRY = static_cast< size_t >( -1 );
+
+const sal_uInt16 SC_OL_IMAGE_PLUS = 9;
+const sal_uInt16 SC_OL_IMAGE_MINUS = SC_OL_IMAGE_PLUS + 1;
+const sal_uInt16 SC_OL_IMAGE_NOTPRESSED = SC_OL_IMAGE_MINUS + 1;
+const sal_uInt16 SC_OL_IMAGE_PRESSED = SC_OL_IMAGE_NOTPRESSED + 1;
+
+// ============================================================================
+
+ScOutlineWindow::ScOutlineWindow( Window* pParent, ScOutlineMode eMode, ScViewData* pViewData, ScSplitPos eWhich ) :
+ Window( pParent ),
+ mrViewData( *pViewData ),
+ meWhich( eWhich ),
+ mbHoriz( eMode == SC_OUTLINE_HOR ),
+ mbMirrorEntries( false ), // updated in SetHeaderSize
+ mbMirrorLevels( false ), // updated in SetHeaderSize
+ mpSymbols( NULL ),
+ maLineColor( COL_BLACK ),
+ mnHeaderSize( 0 ),
+ mnHeaderPos( 0 ),
+ mnMainFirstPos( 0 ),
+ mnMainLastPos( 0 ),
+ mbMTActive( false ),
+ mbMTPressed( false ),
+ mnFocusLevel( 0 ),
+ mnFocusEntry( SC_OL_HEADERENTRY ),
+ mbDontDrawFocus( false )
+{
+ EnableRTL( sal_False ); // mirroring is done manually
+
+ InitSettings();
+ maFocusRect.SetEmpty();
+ SetHeaderSize( 0 );
+
+ // insert the window into task pane list for "F6 cycling"
+ if( SystemWindow* pSysWin = GetSystemWindow() )
+ if( TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList() )
+ pTaskPaneList->AddWindow( this );
+}
+
+ScOutlineWindow::~ScOutlineWindow()
+{
+ // remove the window from task pane list
+ if( SystemWindow* pSysWin = GetSystemWindow() )
+ if( TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList() )
+ pTaskPaneList->RemoveWindow( this );
+}
+
+void ScOutlineWindow::SetHeaderSize( long nNewSize )
+{
+ sal_Bool bLayoutRTL = GetDoc().IsLayoutRTL( GetTab() );
+ mbMirrorEntries = bLayoutRTL && mbHoriz;
+ mbMirrorLevels = bLayoutRTL && !mbHoriz;
+
+ bool bNew = (nNewSize != mnHeaderSize);
+ mnHeaderSize = nNewSize;
+ mnHeaderPos = mbMirrorEntries ? (GetOutputSizeEntry() - mnHeaderSize) : 0;
+ mnMainFirstPos = mbMirrorEntries ? 0 : mnHeaderSize;
+ mnMainLastPos = GetOutputSizeEntry() - (mbMirrorEntries ? mnHeaderSize : 0) - 1;
+ if ( bNew )
+ Invalidate();
+}
+
+long ScOutlineWindow::GetDepthSize() const
+{
+ long nSize = GetLevelCount() * SC_OL_BITMAPSIZE;
+ if ( nSize > 0 )
+ nSize += 2 * SC_OL_POSOFFSET + 1;
+ return nSize;
+}
+
+void ScOutlineWindow::ScrollPixel( long nDiff )
+{
+ HideFocus();
+ mbDontDrawFocus = true;
+
+ long nStart = mnMainFirstPos;
+ long nEnd = mnMainLastPos;
+
+ long nInvStart, nInvEnd;
+ if (nDiff < 0)
+ {
+ nStart -= nDiff;
+ nInvStart = nEnd + nDiff;
+ nInvEnd = nEnd;
+ }
+ else
+ {
+ nEnd -= nDiff;
+ nInvStart = nStart;
+ nInvEnd = nStart + nDiff;
+ }
+
+ ScrollRel( nDiff, nStart, nEnd );
+ Invalidate( GetRectangle( 0, nInvStart, GetOutputSizeLevel() - 1, nInvEnd ) );
+ Update();
+
+ // if focus becomes invisible, move it to next visible button
+ ImplMoveFocusToVisible( nDiff < 0 );
+
+ mbDontDrawFocus = false;
+ ShowFocus();
+}
+
+void ScOutlineWindow::ScrollRel( long nEntryDiff, long nEntryStart, long nEntryEnd )
+{
+ Rectangle aRect( GetRectangle( 0, nEntryStart, GetOutputSizeLevel() - 1, nEntryEnd ) );
+ if ( mbHoriz )
+ Scroll( nEntryDiff, 0, aRect );
+ else
+ Scroll( 0, nEntryDiff, aRect );
+}
+
+// internal -------------------------------------------------------------------
+
+void ScOutlineWindow::InitSettings()
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetBackground( rStyleSettings.GetFaceColor() );
+ maLineColor = rStyleSettings.GetButtonTextColor();
+ mpSymbols = ScGlobal::GetOutlineSymbols( rStyleSettings.GetHighContrastMode() );
+ Invalidate();
+}
+
+const ScOutlineArray* ScOutlineWindow::GetOutlineArray() const
+{
+ const ScOutlineTable* pTable = GetDoc().GetOutlineTable( GetTab() );
+ if ( !pTable ) return NULL;
+ return mbHoriz ? pTable->GetColArray() : pTable->GetRowArray();
+}
+
+const ScOutlineEntry* ScOutlineWindow::GetOutlineEntry( size_t nLevel, size_t nEntry ) const
+{
+ const ScOutlineArray* pArray = GetOutlineArray();
+ return pArray ? pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel), sal::static_int_cast<sal_uInt16>(nEntry) ) : NULL;
+}
+
+bool ScOutlineWindow::IsHidden( SCCOLROW nColRowIndex ) const
+{
+ 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().RowFiltered( static_cast<SCROW>(nColRowIndex), GetTab() );
+}
+
+bool ScOutlineWindow::IsFirstVisible( SCCOLROW nColRowIndex ) const
+{
+ bool bAllHidden = true;
+ for ( SCCOLROW nPos = 0; (nPos < nColRowIndex) && bAllHidden; ++nPos )
+ bAllHidden = IsHidden( nPos );
+ return bAllHidden;
+}
+
+void ScOutlineWindow::GetVisibleRange( SCCOLROW& rnColRowStart, SCCOLROW& rnColRowEnd ) const
+{
+ if ( mbHoriz )
+ {
+ rnColRowStart = mrViewData.GetPosX( WhichH( meWhich ) );
+ rnColRowEnd = rnColRowStart + mrViewData.VisibleCellsX( WhichH( meWhich ) );
+ }
+ else
+ {
+ rnColRowStart = mrViewData.GetPosY( WhichV( meWhich ) );
+ rnColRowEnd = rnColRowStart + mrViewData.VisibleCellsY( WhichV( meWhich ) );
+ }
+
+ // include collapsed columns/rows in front of visible range
+ while ( (rnColRowStart > 0) && IsHidden( rnColRowStart - 1 ) )
+ --rnColRowStart;
+}
+
+Point ScOutlineWindow::GetPoint( long nLevelPos, long nEntryPos ) const
+{
+ return mbHoriz ? Point( nEntryPos, nLevelPos ) : Point( nLevelPos, nEntryPos );
+}
+
+Rectangle ScOutlineWindow::GetRectangle(
+ long nLevelStart, long nEntryStart, long nLevelEnd, long nEntryEnd ) const
+{
+ return Rectangle( GetPoint( nLevelStart, nEntryStart ), GetPoint( nLevelEnd, nEntryEnd ) );
+}
+
+long ScOutlineWindow::GetOutputSizeLevel() const
+{
+ Size aSize( GetOutputSizePixel() );
+ return mbHoriz ? aSize.Height() : aSize.Width();
+}
+
+long ScOutlineWindow::GetOutputSizeEntry() const
+{
+ Size aSize( GetOutputSizePixel() );
+ return mbHoriz ? aSize.Width() : aSize.Height();
+}
+
+size_t ScOutlineWindow::GetLevelCount() const
+{
+ const ScOutlineArray* pArray = GetOutlineArray();
+ size_t nLevelCount = pArray ? pArray->GetDepth() : 0;
+ return nLevelCount ? (nLevelCount + 1) : 0;
+}
+
+long ScOutlineWindow::GetLevelPos( size_t nLevel ) const
+{
+ // #i51970# must always return the *left* edge of the area used by a level
+ long nPos = static_cast< long >( SC_OL_POSOFFSET + nLevel * SC_OL_BITMAPSIZE );
+ return mbMirrorLevels ? (GetOutputSizeLevel() - nPos - SC_OL_BITMAPSIZE) : nPos;
+}
+
+size_t ScOutlineWindow::GetLevelFromPos( long nLevelPos ) const
+{
+ if( mbMirrorLevels ) nLevelPos = GetOutputSizeLevel() - nLevelPos - 1;
+ long nStart = SC_OL_POSOFFSET;
+ if ( nLevelPos < nStart ) return SC_OL_NOLEVEL;
+ size_t nLevel = static_cast< size_t >( (nLevelPos - nStart) / SC_OL_BITMAPSIZE );
+ return (nLevel < GetLevelCount()) ? nLevel : SC_OL_NOLEVEL;
+}
+
+long ScOutlineWindow::GetColRowPos( SCCOLROW nColRowIndex ) const
+{
+ long nDocPos = mbHoriz ?
+ mrViewData.GetScrPos( static_cast<SCCOL>(nColRowIndex), 0, meWhich, sal_True ).X() :
+ mrViewData.GetScrPos( 0, static_cast<SCROW>(nColRowIndex), meWhich, sal_True ).Y();
+ return mnMainFirstPos + nDocPos;
+}
+
+long ScOutlineWindow::GetHeaderEntryPos() const
+{
+ return mnHeaderPos + (mnHeaderSize - SC_OL_BITMAPSIZE) / 2;
+}
+
+bool ScOutlineWindow::GetEntryPos(
+ size_t nLevel, size_t nEntry,
+ long& rnStartPos, long& rnEndPos, long& rnImagePos ) const
+{
+ const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
+ if ( !pEntry || !pEntry->IsVisible() )
+ return false;
+
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+
+ long nEntriesSign = mbMirrorEntries ? -1 : 1;
+
+ // --- common calculation ---
+
+ rnStartPos = GetColRowPos( nStart );
+ rnEndPos = GetColRowPos( nEnd + 1 );
+
+ bool bHidden = IsHidden( nStart );
+ rnImagePos = bHidden ?
+ (rnStartPos - ( SC_OL_BITMAPSIZE / 2 ) * nEntriesSign) :
+ rnStartPos + nEntriesSign;
+ long nCenter = (rnStartPos + rnEndPos - SC_OL_BITMAPSIZE * nEntriesSign +
+ ( mbMirrorEntries ? 1 : 0 )) / 2L;
+ rnImagePos = mbMirrorEntries ? Max( rnImagePos, nCenter ) : Min( rnImagePos, nCenter );
+
+ // --- refinements ---
+
+ // do not cut leftmost/topmost image
+ if ( bHidden && IsFirstVisible( nStart ) )
+ rnImagePos = rnStartPos;
+
+ // do not cover previous collapsed image
+ if ( !bHidden && nEntry )
+ {
+ const ScOutlineEntry* pPrevEntry = GetOutlineEntry( nLevel, nEntry - 1 );
+ SCCOLROW nPrevEnd = pPrevEntry->GetEnd();
+ if ( (nPrevEnd + 1 == nStart) && IsHidden( nPrevEnd ) )
+ {
+ if ( IsFirstVisible( pPrevEntry->GetStart() ) )
+ rnStartPos += SC_OL_BITMAPSIZE * nEntriesSign;
+ else
+ rnStartPos += ( SC_OL_BITMAPSIZE / 2 ) * nEntriesSign;
+ rnImagePos = rnStartPos;
+ }
+ }
+
+ // restrict rnStartPos...rnEndPos to valid area
+ rnStartPos = std::max( rnStartPos, mnMainFirstPos );
+ rnEndPos = std::max( rnEndPos, mnMainFirstPos );
+
+ if ( mbMirrorEntries )
+ rnImagePos -= SC_OL_BITMAPSIZE - 1; // start pos aligns with right edge of bitmap
+
+ // --- all rows filtered? ---
+
+ bool bVisible = true;
+ if ( !mbHoriz )
+ {
+ bVisible = false;
+ for ( SCCOLROW nRow = nStart; (nRow <= nEnd) && !bVisible; ++nRow )
+ bVisible = !IsFiltered( nRow );
+ }
+ return bVisible;
+}
+
+bool ScOutlineWindow::GetImagePos( size_t nLevel, size_t nEntry, Point& rPos ) const
+{
+ bool bRet = nLevel < GetLevelCount();
+ if ( bRet )
+ {
+ long nLevelPos = GetLevelPos( nLevel );
+ if ( nEntry == SC_OL_HEADERENTRY )
+ rPos = GetPoint( nLevelPos, GetHeaderEntryPos() );
+ else
+ {
+ long nStartPos, nEndPos, nImagePos;
+ bRet = GetEntryPos( nLevel, nEntry, nStartPos, nEndPos, nImagePos );
+ rPos = GetPoint( nLevelPos, nImagePos );
+ }
+ }
+ return bRet;
+}
+
+bool ScOutlineWindow::IsButtonVisible( size_t nLevel, size_t nEntry ) const
+{
+ bool bRet = false;
+ if ( nEntry == SC_OL_HEADERENTRY )
+ bRet = (mnHeaderSize > 0) && (nLevel < GetLevelCount());
+ else
+ {
+ const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
+ if ( pEntry && pEntry->IsVisible() )
+ {
+ SCCOLROW nStart, nEnd;
+ GetVisibleRange( nStart, nEnd );
+ bRet = (nStart <= pEntry->GetStart()) && (pEntry->GetStart() <= nEnd);
+ }
+ }
+ return bRet;
+}
+
+bool ScOutlineWindow::ItemHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry, bool& rbButton ) const
+{
+ const ScOutlineArray* pArray = GetOutlineArray();
+ if ( !pArray ) return false;
+
+ SCCOLROW nStartIndex, nEndIndex;
+ GetVisibleRange( nStartIndex, nEndIndex );
+
+ size_t nLevel = GetLevelFromPos( mbHoriz ? rPos.Y() : rPos.X() );
+ if ( nLevel == SC_OL_NOLEVEL )
+ return false;
+
+// long nLevelPos = GetLevelPos( nLevel );
+ long nEntryMousePos = mbHoriz ? rPos.X() : rPos.Y();
+
+ // --- level buttons ---
+
+ if ( mnHeaderSize > 0 )
+ {
+ long nImagePos = GetHeaderEntryPos();
+ if ( (nImagePos <= nEntryMousePos) && (nEntryMousePos < nImagePos + SC_OL_BITMAPSIZE) )
+ {
+ rnLevel = nLevel;
+ rnEntry = SC_OL_HEADERENTRY;
+ rbButton = true;
+ return true;
+ }
+ }
+
+ // --- expand/collapse buttons and expanded lines ---
+
+ // search outline entries backwards
+ size_t nEntry = pArray->GetCount( sal::static_int_cast<sal_uInt16>(nLevel) );
+ while ( nEntry )
+ {
+ --nEntry;
+
+ const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel),
+ sal::static_int_cast<sal_uInt16>(nEntry) );
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+
+ if ( (nEnd >= nStartIndex) && (nStart <= nEndIndex) )
+ {
+ long nStartPos, nEndPos, nImagePos;
+ if ( GetEntryPos( nLevel, nEntry, nStartPos, nEndPos, nImagePos ) )
+ {
+ rnLevel = nLevel;
+ rnEntry = nEntry;
+
+ // button?
+ if ( (nStart >= nStartIndex) && (nImagePos <= nEntryMousePos) && (nEntryMousePos < nImagePos + SC_OL_BITMAPSIZE) )
+ {
+ rbButton = true;
+ return true;
+ }
+
+ // line?
+ if ( mbMirrorEntries )
+ ::std::swap( nStartPos, nEndPos ); // in RTL mode, nStartPos is the larger value
+ if ( (nStartPos <= nEntryMousePos) && (nEntryMousePos <= nEndPos) )
+ {
+ rbButton = false;
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+bool ScOutlineWindow::ButtonHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry ) const
+{
+ bool bButton;
+ bool bRet = ItemHit( rPos, rnLevel, rnEntry, bButton );
+ return bRet && bButton;
+}
+
+bool ScOutlineWindow::LineHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry ) const
+{
+ bool bButton;
+ bool bRet = ItemHit( rPos, rnLevel, rnEntry, bButton );
+ return bRet && !bButton;
+}
+
+void ScOutlineWindow::DoFunction( size_t nLevel, size_t nEntry ) const
+{
+ ScDBFunc& rFunc = *mrViewData.GetView();
+ if ( nEntry == SC_OL_HEADERENTRY )
+ rFunc.SelectLevel( mbHoriz, sal::static_int_cast<sal_uInt16>(nLevel) );
+ else
+ {
+ const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
+ if ( pEntry )
+ {
+ if ( pEntry->IsHidden() )
+ rFunc.ShowOutline( mbHoriz, sal::static_int_cast<sal_uInt16>(nLevel), sal::static_int_cast<sal_uInt16>(nEntry) );
+ else
+ rFunc.HideOutline( mbHoriz, sal::static_int_cast<sal_uInt16>(nLevel), sal::static_int_cast<sal_uInt16>(nEntry) );
+ }
+ }
+}
+
+void ScOutlineWindow::DoExpand( size_t nLevel, size_t nEntry ) const
+{
+ const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
+ if ( pEntry && pEntry->IsHidden() )
+ DoFunction( nLevel, nEntry );
+}
+
+void ScOutlineWindow::DoCollapse( size_t nLevel, size_t nEntry ) const
+{
+ const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
+ if ( pEntry && !pEntry->IsHidden() )
+ DoFunction( nLevel, nEntry );
+}
+
+void ScOutlineWindow::Resize()
+{
+ Window::Resize();
+ SetHeaderSize( mnHeaderSize ); // recalculates header/group positions
+ if ( !IsFocusButtonVisible() )
+ {
+ HideFocus();
+ ShowFocus(); // calculates valid position
+ }
+}
+
+void ScOutlineWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ InitSettings();
+ Invalidate();
+ }
+ Window::DataChanged( rDCEvt );
+}
+
+// drawing --------------------------------------------------------------------
+
+void ScOutlineWindow::SetEntryAreaClipRegion()
+{
+ SetClipRegion( Rectangle(
+ GetPoint( 0, mnMainFirstPos ),
+ GetPoint( GetOutputSizeLevel() - 1, mnMainLastPos ) ) );
+}
+
+void ScOutlineWindow::DrawLineRel(
+ long nLevelStart, long nEntryStart, long nLevelEnd, long nEntryEnd )
+{
+ DrawLine( GetPoint( nLevelStart, nEntryStart ), GetPoint( nLevelEnd, nEntryEnd ) );
+}
+
+void ScOutlineWindow::DrawRectRel(
+ long nLevelStart, long nEntryStart, long nLevelEnd, long nEntryEnd )
+{
+ DrawRect( GetRectangle( nLevelStart, nEntryStart, nLevelEnd, nEntryEnd ) );
+}
+
+void ScOutlineWindow::DrawImageRel( long nLevelPos, long nEntryPos, sal_uInt16 nId )
+{
+ DBG_ASSERT( mpSymbols, "ScOutlineWindow::DrawImageRel - no images" );
+ const Image& rImage = mpSymbols->GetImage( nId );
+ SetLineColor();
+ SetFillColor( GetBackground().GetColor() );
+ Point aPos( GetPoint( nLevelPos, nEntryPos ) );
+ DrawRect( Rectangle( aPos, rImage.GetSizePixel() ) );
+ DrawImage( aPos, rImage );
+}
+
+void ScOutlineWindow::DrawBorderRel( size_t nLevel, size_t nEntry, bool bPressed )
+{
+ Point aPos;
+ if ( GetImagePos( nLevel, nEntry, aPos ) )
+ {
+ DBG_ASSERT( mpSymbols, "ScOutlineWindow::DrawBorderRel - no images" );
+ sal_uInt16 nId = bPressed ? SC_OL_IMAGE_PRESSED : SC_OL_IMAGE_NOTPRESSED;
+ bool bClip = (nEntry != SC_OL_HEADERENTRY);
+ if ( bClip )
+ SetEntryAreaClipRegion();
+ DrawImage( aPos, mpSymbols->GetImage( nId ) );
+ if ( bClip )
+ SetClipRegion();
+ }
+ mbMTPressed = bPressed;
+}
+
+void ScOutlineWindow::ShowFocus()
+{
+ if ( HasFocus() )
+ {
+ // first move to a visible position
+ ImplMoveFocusToVisible( true );
+
+ if ( IsFocusButtonVisible() )
+ {
+ Point aPos;
+ if ( GetImagePos( mnFocusLevel, mnFocusEntry, aPos ) )
+ {
+ aPos += Point( 1, 1 );
+ maFocusRect = Rectangle( aPos, Size( SC_OL_BITMAPSIZE - 2, SC_OL_BITMAPSIZE - 2 ) );
+ bool bClip = (mnFocusEntry != SC_OL_HEADERENTRY);
+ if ( bClip )
+ SetEntryAreaClipRegion();
+ InvertTracking( maFocusRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
+ if ( bClip )
+ SetClipRegion();
+ }
+ }
+ }
+}
+
+void ScOutlineWindow::HideFocus()
+{
+ if ( !maFocusRect.IsEmpty() )
+ {
+ bool bClip = (mnFocusEntry != SC_OL_HEADERENTRY);
+ if ( bClip )
+ SetEntryAreaClipRegion();
+ InvertTracking( maFocusRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
+ if ( bClip )
+ SetClipRegion();
+ maFocusRect.SetEmpty();
+ }
+}
+
+void ScOutlineWindow::Paint( const Rectangle& /* rRect */ )
+{
+ long nEntriesSign = mbMirrorEntries ? -1 : 1;
+ long nLevelsSign = mbMirrorLevels ? -1 : 1;
+
+ Size aSize = GetOutputSizePixel();
+ long nLevelEnd = (mbHoriz ? aSize.Height() : aSize.Width()) - 1;
+ long nEntryEnd = (mbHoriz ? aSize.Width() : aSize.Height()) - 1;
+
+ SetLineColor( maLineColor );
+ long nBorderPos = mbMirrorLevels ? 0 : nLevelEnd;
+ DrawLineRel( nBorderPos, 0, nBorderPos, nEntryEnd );
+
+ const ScOutlineArray* pArray = GetOutlineArray();
+ if ( !pArray ) return;
+
+ size_t nLevelCount = GetLevelCount();
+
+ // --- draw header images ---
+
+ if ( mnHeaderSize > 0 )
+ {
+ long nEntryPos = GetHeaderEntryPos();
+ for ( size_t nLevel = 0; nLevel < nLevelCount; ++nLevel )
+ DrawImageRel( GetLevelPos( nLevel ), nEntryPos, static_cast< sal_uInt16 >( nLevel + 1 ) );
+
+ SetLineColor( maLineColor );
+ long nLinePos = mnHeaderPos + (mbMirrorEntries ? 0 : (mnHeaderSize - 1));
+ DrawLineRel( 0, nLinePos, nLevelEnd, nLinePos );
+ }
+
+ // --- draw lines & collapse/expand images ---
+
+ SetEntryAreaClipRegion();
+
+ SCCOLROW nStartIndex, nEndIndex;
+ GetVisibleRange( nStartIndex, nEndIndex );
+
+ for ( size_t nLevel = 0; nLevel + 1 < nLevelCount; ++nLevel )
+ {
+ long nLevelPos = GetLevelPos( nLevel );
+ long nEntryPos1 = 0, nEntryPos2 = 0, nImagePos = 0;
+
+ size_t nEntryCount = pArray->GetCount( sal::static_int_cast<sal_uInt16>(nLevel) );
+ size_t nEntry;
+
+ // first draw all lines in the current level
+ SetLineColor();
+ SetFillColor( maLineColor );
+ for ( nEntry = 0; nEntry < nEntryCount; ++nEntry )
+ {
+ const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel),
+ sal::static_int_cast<sal_uInt16>(nEntry) );
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+
+ // visible range?
+ bool bDraw = (nEnd >= nStartIndex) && (nStart <= nEndIndex);
+ // find output coordinates
+ if ( bDraw )
+ bDraw = GetEntryPos( nLevel, nEntry, nEntryPos1, nEntryPos2, nImagePos );
+ // draw, if not collapsed
+ if ( bDraw && !pEntry->IsHidden() )
+ {
+ if ( nStart >= nStartIndex )
+ nEntryPos1 += nEntriesSign;
+ nEntryPos2 -= 2 * nEntriesSign;
+ long nLinePos = nLevelPos;
+ if ( mbMirrorLevels )
+ nLinePos += SC_OL_BITMAPSIZE - 1; // align with right edge of bitmap
+ DrawRectRel( nLinePos, nEntryPos1, nLinePos + nLevelsSign, nEntryPos2 );
+
+ if ( nEnd <= nEndIndex )
+ DrawRectRel( nLinePos, nEntryPos2 - nEntriesSign,
+ nLinePos + ( SC_OL_BITMAPSIZE / 3 ) * nLevelsSign, nEntryPos2 );
+ }
+ }
+
+ // draw all images in the level from last to first
+ nEntry = nEntryCount;
+ while ( nEntry )
+ {
+ --nEntry;
+
+ const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel),
+ sal::static_int_cast<sal_uInt16>(nEntry) );
+ SCCOLROW nStart = pEntry->GetStart();
+// SCCOLROW nEnd = pEntry->GetEnd();
+
+ // visible range?
+ bool bDraw = (nStartIndex <= nStart) && (nStart <= nEndIndex + 1);
+ // find output coordinates
+ if ( bDraw )
+ bDraw = GetEntryPos( nLevel, nEntry, nEntryPos1, nEntryPos2, nImagePos );
+ // draw, if not hidden by higher levels
+ if ( bDraw )
+ {
+ sal_uInt16 nImageId = pEntry->IsHidden() ? SC_OL_IMAGE_PLUS : SC_OL_IMAGE_MINUS;
+ DrawImageRel( nLevelPos, nImagePos, nImageId );
+ }
+ }
+ }
+
+ SetClipRegion();
+
+ if ( !mbDontDrawFocus )
+ ShowFocus();
+}
+
+// focus ----------------------------------------------------------------------
+
+/** Increments or decrements a value and wraps at the specified limits.
+ @return true = value wrapped. */
+bool lcl_RotateValue( size_t& rnValue, size_t nMin, size_t nMax, bool bForward )
+{
+ DBG_ASSERT( nMin <= nMax, "lcl_RotateValue - invalid range" );
+ DBG_ASSERT( nMax < static_cast< size_t >( -1 ), "lcl_RotateValue - range overflow" );
+ bool bWrap = false;
+ if ( bForward )
+ {
+ if ( rnValue < nMax )
+ ++rnValue;
+ else
+ {
+ rnValue = nMin;
+ bWrap = true;
+ }
+ }
+ else
+ {
+ if ( rnValue > nMin )
+ --rnValue;
+ else
+ {
+ rnValue = nMax;
+ bWrap = true;
+ }
+ }
+ return bWrap;
+}
+
+bool ScOutlineWindow::IsFocusButtonVisible() const
+{
+ return IsButtonVisible( mnFocusLevel, mnFocusEntry );
+}
+
+bool ScOutlineWindow::ImplMoveFocusByEntry( bool bForward, bool bFindVisible )
+{
+ const ScOutlineArray* pArray = GetOutlineArray();
+ if ( !pArray )
+ return false;
+
+ bool bWrapped = false;
+ size_t nEntryCount = pArray->GetCount( sal::static_int_cast<sal_uInt16>(mnFocusLevel) );
+ // #i29530# entry count may be decreased after changing active sheet
+ if( mnFocusEntry >= nEntryCount )
+ mnFocusEntry = SC_OL_HEADERENTRY;
+ size_t nOldEntry = mnFocusEntry;
+
+ do
+ {
+ if ( mnFocusEntry == SC_OL_HEADERENTRY )
+ {
+ // move from header to first or last entry
+ if ( nEntryCount > 0 )
+ mnFocusEntry = bForward ? 0 : (nEntryCount - 1);
+ /* wrapped, if forward from right header to first entry,
+ or if backward from left header to last entry */
+ // Header and entries are now always in consistent order,
+ // so there's no need to check for mirroring here.
+ if ( !nEntryCount || !bForward )
+ bWrapped = true;
+ }
+ else if ( lcl_RotateValue( mnFocusEntry, 0, nEntryCount - 1, bForward ) )
+ {
+ // lcl_RotateValue returns true -> wrapped the entry range -> move to header
+ mnFocusEntry = SC_OL_HEADERENTRY;
+ /* wrapped, if forward from last entry to left header,
+ or if backward from first entry to right header */
+ if ( bForward )
+ bWrapped = true;
+ }
+ }
+ while ( bFindVisible && !IsFocusButtonVisible() && (nOldEntry != mnFocusEntry) );
+
+ return bWrapped;
+}
+
+bool ScOutlineWindow::ImplMoveFocusByLevel( bool bForward )
+{
+ const ScOutlineArray* pArray = GetOutlineArray();
+ if ( !pArray )
+ return false;
+
+ bool bWrapped = false;
+ size_t nLevelCount = GetLevelCount();
+
+ if ( mnFocusEntry == SC_OL_HEADERENTRY )
+ {
+ if ( nLevelCount > 0 )
+ bWrapped = lcl_RotateValue( mnFocusLevel, 0, nLevelCount - 1, bForward );
+ }
+ else
+ {
+ const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<sal_uInt16>(mnFocusLevel),
+ sal::static_int_cast<sal_uInt16>(mnFocusEntry) );
+ if ( pEntry )
+ {
+ SCCOLROW nStart = pEntry->GetStart();
+ SCCOLROW nEnd = pEntry->GetEnd();
+ size_t nNewLevel = mnFocusLevel;
+ size_t nNewEntry = 0;
+
+ bool bFound = false;
+ if ( bForward && (mnFocusLevel + 2 < nLevelCount) )
+ {
+ // next level -> find first child entry
+ nNewLevel = mnFocusLevel + 1;
+ // TODO - change ScOutlineArray interface to size_t usage
+ sal_uInt16 nTmpEntry = 0;
+ bFound = pArray->GetEntryIndexInRange( sal::static_int_cast<sal_uInt16>(nNewLevel), nStart, nEnd, nTmpEntry );
+ nNewEntry = nTmpEntry;
+ }
+ else if ( !bForward && (mnFocusLevel > 0) )
+ {
+ // previous level -> find parent entry
+ nNewLevel = mnFocusLevel - 1;
+ // TODO - change ScOutlineArray interface to size_t usage
+ sal_uInt16 nTmpEntry = 0;
+ bFound = pArray->GetEntryIndex( sal::static_int_cast<sal_uInt16>(nNewLevel), nStart, nTmpEntry );
+ nNewEntry = nTmpEntry;
+ }
+
+ if ( bFound && IsButtonVisible( nNewLevel, nNewEntry ) )
+ {
+ mnFocusLevel = nNewLevel;
+ mnFocusEntry = nNewEntry;
+ }
+ }
+ }
+
+ return bWrapped;
+}
+
+bool ScOutlineWindow::ImplMoveFocusByTabOrder( bool bForward, bool bFindVisible )
+{
+ bool bRet = false;
+ size_t nOldLevel = mnFocusLevel;
+ size_t nOldEntry = mnFocusEntry;
+
+ do
+ {
+ /* one level up, if backward from left header,
+ or one level down, if forward from right header */
+ if ( (!bForward) && (mnFocusEntry == SC_OL_HEADERENTRY) )
+ bRet |= ImplMoveFocusByLevel( bForward );
+ // move to next/previous entry
+ bool bWrapInLevel = ImplMoveFocusByEntry( bForward, false );
+ bRet |= bWrapInLevel;
+ /* one level up, if wrapped backward to right header,
+ or one level down, if wrapped forward to right header */
+ if ( bForward && bWrapInLevel )
+ bRet |= ImplMoveFocusByLevel( bForward );
+ }
+ while ( bFindVisible && !IsFocusButtonVisible() && ((nOldLevel != mnFocusLevel) || (nOldEntry != mnFocusEntry)) );
+
+ return bRet;
+}
+
+void ScOutlineWindow::ImplMoveFocusToVisible( bool bForward )
+{
+ // first try to find an entry in the same level
+ if ( !IsFocusButtonVisible() )
+ ImplMoveFocusByEntry( bForward, true );
+ // then try to find any other entry
+ if ( !IsFocusButtonVisible() )
+ ImplMoveFocusByTabOrder( bForward, true );
+}
+
+void ScOutlineWindow::MoveFocusByEntry( bool bForward )
+{
+ HideFocus();
+ ImplMoveFocusByEntry( bForward, true );
+ ShowFocus();
+}
+
+void ScOutlineWindow::MoveFocusByLevel( bool bForward )
+{
+ HideFocus();
+ ImplMoveFocusByLevel( bForward );
+ ShowFocus();
+}
+
+void ScOutlineWindow::MoveFocusByTabOrder( bool bForward )
+{
+ HideFocus();
+ ImplMoveFocusByTabOrder( bForward, true );
+ ShowFocus();
+}
+
+void ScOutlineWindow::GetFocus()
+{
+ Window::GetFocus();
+ ShowFocus();
+}
+
+void ScOutlineWindow::LoseFocus()
+{
+ HideFocus();
+ Window::LoseFocus();
+}
+
+
+// mouse ----------------------------------------------------------------------
+
+void ScOutlineWindow::StartMouseTracking( size_t nLevel, size_t nEntry )
+{
+ mbMTActive = true;
+ mnMTLevel = nLevel;
+ mnMTEntry = nEntry;
+ DrawBorderRel( nLevel, nEntry, true );
+}
+
+void ScOutlineWindow::EndMouseTracking()
+{
+ if ( mbMTPressed )
+ DrawBorderRel( mnMTLevel, mnMTEntry, false );
+ mbMTActive = false;
+}
+
+void ScOutlineWindow::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( IsMouseTracking() )
+ {
+ size_t nLevel, nEntry;
+ bool bHit = false;
+
+ if ( ButtonHit( rMEvt.GetPosPixel(), nLevel, nEntry ) )
+ bHit = (nLevel == mnMTLevel) && (nEntry == mnMTEntry);
+
+ if ( bHit != mbMTPressed )
+ DrawBorderRel( mnMTLevel, mnMTEntry, bHit );
+ }
+}
+
+void ScOutlineWindow::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if ( IsMouseTracking() )
+ {
+ EndMouseTracking();
+
+ size_t nLevel, nEntry;
+ if ( ButtonHit( rMEvt.GetPosPixel(), nLevel, nEntry ) )
+ if ( (nLevel == mnMTLevel) && (nEntry == mnMTEntry) )
+ DoFunction( nLevel, nEntry );
+ }
+}
+
+void ScOutlineWindow::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ size_t nLevel, nEntry;
+ bool bHit = ButtonHit( rMEvt.GetPosPixel(), nLevel, nEntry );
+ if ( bHit )
+ StartMouseTracking( nLevel, nEntry );
+ else if ( rMEvt.GetClicks() == 2 )
+ {
+ bHit = LineHit( rMEvt.GetPosPixel(), nLevel, nEntry );
+ if ( bHit )
+ DoFunction( nLevel, nEntry );
+ }
+
+ // if an item has been hit and window is focused, move focus to this item
+ if ( bHit && HasFocus() )
+ {
+ HideFocus();
+ mnFocusLevel = nLevel;
+ mnFocusEntry = nEntry;
+ ShowFocus();
+ }
+}
+
+
+// keyboard -------------------------------------------------------------------
+
+void ScOutlineWindow::KeyInput( const KeyEvent& rKEvt )
+{
+ const KeyCode& rKCode = rKEvt.GetKeyCode();
+ bool bNoMod = !rKCode.GetModifier();
+ bool bShift = (rKCode.GetModifier() == KEY_SHIFT);
+ bool bCtrl = (rKCode.GetModifier() == KEY_MOD1);
+
+ sal_uInt16 nCode = rKCode.GetCode();
+ bool bUpDownKey = (nCode == KEY_UP) || (nCode == KEY_DOWN);
+ bool bLeftRightKey = (nCode == KEY_LEFT) || (nCode == KEY_RIGHT);
+
+ // TAB key
+ if ( (nCode == KEY_TAB) && (bNoMod || bShift) )
+ // move forward without SHIFT key
+ MoveFocusByTabOrder( bNoMod ); // TAB uses logical order, regardless of mirroring
+
+ // LEFT/RIGHT/UP/DOWN keys
+ else if ( bNoMod && (bUpDownKey || bLeftRightKey) )
+ {
+ bool bForward = (nCode == KEY_DOWN) || (nCode == KEY_RIGHT);
+ if ( mbHoriz == bLeftRightKey )
+ // move inside level with LEFT/RIGHT in horizontal and with UP/DOWN in vertical
+ MoveFocusByEntry( bForward != mbMirrorEntries );
+ else
+ // move to next/prev level with LEFT/RIGHT in vertical and with UP/DOWN in horizontal
+ MoveFocusByLevel( bForward != mbMirrorLevels );
+ }
+
+ // CTRL + number
+ else if ( bCtrl && (nCode >= KEY_1) && (nCode <= KEY_9) )
+ {
+ size_t nLevel = static_cast< size_t >( nCode - KEY_1 );
+ if ( nLevel < GetLevelCount() )
+ DoFunction( nLevel, SC_OL_HEADERENTRY );
+ }
+
+ // other key codes
+ else switch ( rKCode.GetFullCode() )
+ {
+ case KEY_ADD: DoExpand( mnFocusLevel, mnFocusEntry ); break;
+ case KEY_SUBTRACT: DoCollapse( mnFocusLevel, mnFocusEntry ); break;
+ case KEY_SPACE:
+ case KEY_RETURN: DoFunction( mnFocusLevel, mnFocusEntry ); break;
+ default: Window::KeyInput( rKEvt );
+ }
+}
+
+
+// ============================================================================
+
diff --git a/sc/source/ui/view/olkact.cxx b/sc/source/ui/view/olkact.cxx
new file mode 100644
index 000000000000..248777f4e473
--- /dev/null
+++ b/sc/source/ui/view/olkact.cxx
@@ -0,0 +1,282 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#define _BIGINT_HXX
+#define _CACHESTR_HXX
+#define _CONFIG_HXX
+#define _CURSOR_HXX
+#define _CTRLTOOL_HXX
+#define _DLGCFG_HXX
+#define _DYNARR_HXX
+#define _EXTATTR_HXX
+#define _FILDLG_HXX
+#define _FONTDLG_HXX
+#define _FRM3D_HXX
+#define _INTRO_HXX
+#define _ISETBWR_HXX
+#define _NO_SVRTF_PARSER_HXX
+#define _MACRODLG_HXX
+#define _MODALDLG_HXX
+#define _MOREBUTTON_HXX
+#define _OUTLINER_HXX
+#define _PASSWD_HXX
+#define _PRNDLG_HXX
+//#define _POLY_HXX
+#define _PVRWIN_HXX
+#define _QUEUE_HXX
+#define _RULER_HXX
+#define _SCRWIN_HXX
+#define _SETBRW_HXX
+#define _STACK_HXX
+//#define _STATUS_HXX ***
+#define _STDMENU_HXX
+#define _TABBAR_HXX
+//#define _VCBRW_HXX
+#define _VCTRLS_HXX
+//#define _VCSBX_HXX
+#define _VCONT_HXX
+#define _VDRWOBJ_HXX
+
+
+//sfx
+#define _SFXAPPWIN_HXX
+#define _SFXCTRLITEM
+#define _SFXDISPATCH_HXX
+#define _SFXFILEDLG_HXX
+#define _SFXIMGMGR_HXX
+#define _SFXIPFRM_HXX
+#define _SFX_MACRO_HXX
+#define _SFXMULTISEL_HXX
+#define _SFX_MINFITEM_HXX
+
+
+//sfxcore.hxx
+//#define _SFXINIMGR_HXX ***
+//#define _SFXCFGITEM_HXX
+//#define _SFX_PRINTER_HXX
+#define _SFXGENLINK_HXX
+#define _SFXHINTPOST_HXX
+#define _SFXDOCINF_HXX
+#define _SFXLINKHDL_HXX
+//#define _SFX_PROGRESS_HXX
+
+//sfxsh.hxx
+//#define _SFX_SHELL_HXX
+//#define _SFXAPP_HXX
+//#define _SFXDISPATCH_HXX
+//#define _SFXMSG_HXX ***
+//#define _SFXOBJFACE_HXX ***
+//#define _SFXREQUEST_HXX
+#define _SFXMACRO_HXX
+
+// SFX
+//#define _SFXAPPWIN_HXX ***
+#define _SFX_SAVEOPT_HXX
+//#define _SFX_CHILDWIN_HXX
+//#define _SFXCTRLITEM_HXX
+#define _SFXPRNMON_HXX
+#define _INTRO_HXX
+#define _SFXMSGDESCR_HXX
+#define _SFXMSGPOOL_HXX
+#define _SFXFILEDLG_HXX
+#define _PASSWD_HXX
+#define _SFXTBXCTRL_HXX
+#define _SFXSTBITEM_HXX
+#define _SFXMNUITEM_HXX
+#define _SFXIMGMGR_HXX
+#define _SFXTBXMGR_HXX
+#define _SFXSTBMGR_HXX
+#define _SFX_MINFITEM_HXX
+#define _SFXEVENT_HXX
+
+//sfxdoc.hxx
+//#define _SFX_OBJSH_HXX
+//#define _SFX_CLIENTSH_HXX
+//#define _SFXDOCINF_HXX
+//#define _SFX_OBJFAC_HXX
+#define _SFX_DOCFILT_HXX
+//#define _SFXDOCFILE_HXX ***
+//define _VIEWFAC_HXX
+//#define _SFXVIEWFRM_HXX
+//#define _SFXVIEWSH_HXX
+//#define _MDIFRM_HXX ***
+#define _SFX_IPFRM_HXX
+//#define _SFX_INTERNO_HXX
+
+//sfxdlg.hxx
+//#define _SFXTABDLG_HXX
+//#define _BASEDLGS_HXX ***
+#define _SFX_DINFDLG_HXX
+#define _SFXDINFEDT_HXX
+#define _SFX_MGETEMPL_HXX
+#define _SFX_TPLPITEM_HXX
+//#define _SFX_STYLEDLG_HXX
+#define _NEWSTYLE_HXX
+//#define _SFXDOCTEMPL_HXX ***
+//#define _SFXDOCTDLG_HXX ***
+//#define _SFX_TEMPLDLG_HXX ***
+//#define _SFXNEW_HXX ***
+#define _SFXDOCMAN_HXX
+//#define _SFXDOCKWIN_HXX
+
+//sfxitems.hxx
+#define _SFX_WHMAP_HXX
+#define _ARGS_HXX
+//#define _SFXPOOLITEM_HXX
+//#define _SFXINTITEM_HXX
+//#define _SFXENUMITEM_HXX
+#define _SFXFLAGITEM_HXX
+//#define _SFXSTRITEM_HXX
+#define _SFXPTITEM_HXX
+#define _SFXRECTITEM_HXX
+//#define _SFXITEMPOOL_HXX
+//#define _SFXITEMSET_HXX
+#define _SFXITEMITER_HXX
+#define _SFX_WHITER_HXX
+#define _SFXPOOLCACH_HXX
+//#define _AEITEM_HXX
+#define _SFXRNGITEM_HXX
+//#define _SFXSLSTITM_HXX
+//#define _SFXSTYLE_HXX
+
+//xout.hxx
+//#define _XENUM_HXX
+//#define _XPOLY_HXX
+//#define _XATTR_HXX
+//#define _XOUTX_HXX
+//#define _XPOOL_HXX
+//#define _XTABLE_HXX
+
+//svdraw.hxx
+#define _SDR_NOITEMS
+#define _SDR_NOTOUCH
+#define _SDR_NOTRANSFORM
+//#define _SDR_NOOBJECTS
+//#define _SDR_NOVIEWS
+
+
+
+
+#define _SFXBASIC_HXX
+#define _SFX_DOCFILE_HXX
+#define _SFX_DOCFILT_HXX
+#define _SFX_DOCINF_HXX
+#define _SFX_DOCSH_HXX
+#define _SFX_TEMPLDLG_HXX
+#define _SFXSTBMGR_HXX
+#define _SFXTBXMGR_HXX
+#define _SFXIMGMGR_HXX
+#define _SFXMNUITEM_HXX
+#define _SFXMNUMGR_HXX
+#define _SFXSTBITEM_HXX
+#define _SFXTBXCTRL_HXX
+#define _SFXFILEDLG_HXX
+#define _SFXREQUEST_HXX
+#define _SFXOBJFACE_HXX
+#define _SFXMSGPOOL_HXX
+#define _SFXMSGDESCR_HXX
+#define _SFXMSG_HXX
+#define _SFX_PRNMON_HXX
+
+//si
+#define _SI_NOSBXCONTROLS
+#define _SI_NOCONTROL
+//#define SI_NOITEMS
+//#define SI_NODRW
+//#define SI_NOOTHERFORMS
+#define _SIDLL_HXX
+//#define _VCSBX_HXX
+//#define _VCBRW_HXX
+
+//#define _SVDATTR_HXX <--- der wars
+#define _SVDXOUT_HXX
+#define _SVDEC_HXX
+//#define _SVDIO_HXX
+//#define _SVDLAYER_HXX
+//#define _SVDRAG_HXX
+#define _SVINCVW_HXX
+//#define _SV_MULTISEL_HXX
+#define _SVRTV_HXX
+#define _SVTABBX_HXX
+
+#define _SVX_DAILDLL_HXX
+#define _SVX_HYPHEN_HXX
+#define _SVX_IMPGRF_HXX
+#define _SVX_OPTITEMS_HXX
+#define _SVX_OPTGERL_HXX
+#define _SVX_OPTSAVE_HXX
+#define _SVX_OPTSPELL_HXX
+#define _SVX_OPTPATH_HXX
+#define _SVX_OPTLINGU_HXX
+#define _SVX_RULER_HXX
+#define _SVX_RULRITEM_HXX
+#define _SVX_SPLWRAP_HXX
+#define _SVX_SPLDLG_HXX
+#define _SVX_THESDLG_HXX
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <sfx2/childwin.hxx>
+#include <sfx2/objsh.hxx>
+
+#include "document.hxx"
+#include "viewdata.hxx"
+#include "drawview.hxx"
+#include "drawpage.hxx"
+#include "drwlayer.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+// -----------------------------------------------------------------------
+
+void ActivateOlk( ScViewData* /* pViewData */ )
+{
+ // Browser fuer Virtual Controls fuellen
+ // VC's und den Browser dazu gibts nicht mehr...
+
+ // GetSbxForm gibt's nicht mehr, muss auch nichts mehr angemeldet werden
+}
+
+void DeActivateOlk( ScViewData* /* pViewData */ )
+{
+ // Browser fuer Virtual Controls fuellen
+ // VC's und den Browser dazu gibts nicht mehr...
+
+ // GetSbxForm gibt's nicht mehr, muss auch nichts mehr angemeldet werden
+}
+
+
+
+
+
diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx
new file mode 100644
index 000000000000..885a1ae2a778
--- /dev/null
+++ b/sc/source/ui/view/output.cxx
@@ -0,0 +1,2476 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <com/sun/star/embed/EmbedMisc.hpp>
+
+#include "scitems.hxx"
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/editdata.hxx>
+#include <svtools/colorcfg.hxx>
+#include <svx/rotmodit.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/svxfont.hxx>
+#include <svx/svdoole2.hxx>
+#include <tools/poly.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/pdfextoutdevdata.hxx>
+#include <svtools/accessibilityoptions.hxx>
+#include <svx/framelinkarray.hxx>
+
+#include "output.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "tabvwsh.hxx"
+#include "progress.hxx"
+#include "pagedata.hxx"
+#include "chgtrack.hxx"
+#include "chgviset.hxx"
+#include "viewutil.hxx"
+#include "gridmerg.hxx"
+#include "invmerge.hxx"
+#include "fillinfo.hxx"
+#include "scmod.hxx"
+#include "appoptio.hxx"
+#include "postit.hxx"
+
+#include <math.h>
+
+using namespace com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+// Farben fuer ChangeTracking "nach Autor" wie im Writer (swmodul1.cxx)
+
+#define SC_AUTHORCOLORCOUNT 9
+
+static ColorData nAuthorColor[ SC_AUTHORCOLORCOUNT ] = {
+ COL_LIGHTRED, COL_LIGHTBLUE, COL_LIGHTMAGENTA,
+ COL_GREEN, COL_RED, COL_BLUE,
+ COL_BROWN, COL_MAGENTA, COL_CYAN };
+
+// Hilfsklasse, fuer die Farbzuordnung,
+// um nicht mehrfach hintereinander denselben User aus der Liste zu suchen
+
+class ScActionColorChanger
+{
+private:
+ const ScAppOptions& rOpt;
+ const ScStrCollection& rUsers;
+ String aLastUserName;
+ sal_uInt16 nLastUserIndex;
+ ColorData nColor;
+
+public:
+ ScActionColorChanger( const ScChangeTrack& rTrack );
+ ~ScActionColorChanger() {}
+
+ void Update( const ScChangeAction& rAction );
+ ColorData GetColor() const { return nColor; }
+};
+
+//------------------------------------------------------------------
+
+ScActionColorChanger::ScActionColorChanger( const ScChangeTrack& rTrack ) :
+ rOpt( SC_MOD()->GetAppOptions() ),
+ rUsers( rTrack.GetUserCollection() ),
+ nLastUserIndex( 0 ),
+ nColor( COL_BLACK )
+{
+}
+
+void ScActionColorChanger::Update( const ScChangeAction& rAction )
+{
+ ColorData nSetColor;
+ switch (rAction.GetType())
+ {
+ case SC_CAT_INSERT_COLS:
+ case SC_CAT_INSERT_ROWS:
+ case SC_CAT_INSERT_TABS:
+ nSetColor = rOpt.GetTrackInsertColor();
+ break;
+ case SC_CAT_DELETE_COLS:
+ case SC_CAT_DELETE_ROWS:
+ case SC_CAT_DELETE_TABS:
+ nSetColor = rOpt.GetTrackDeleteColor();
+ break;
+ case SC_CAT_MOVE:
+ nSetColor = rOpt.GetTrackMoveColor();
+ break;
+ default:
+ nSetColor = rOpt.GetTrackContentColor();
+ break;
+ }
+ if ( nSetColor != COL_TRANSPARENT ) // Farbe eingestellt
+ nColor = nSetColor;
+ else // nach Autor
+ {
+ if ( rAction.GetUser() != aLastUserName )
+ {
+ aLastUserName = rAction.GetUser();
+ StrData aData(aLastUserName);
+ sal_uInt16 nIndex;
+ if (!rUsers.Search(&aData, nIndex))
+ {
+ // empty string is possible if a name wasn't found while saving a 5.0 file
+ DBG_ASSERT( aLastUserName.Len() == 0, "Author not found" );
+ nIndex = 0;
+ }
+ nLastUserIndex = nIndex % SC_AUTHORCOLORCOUNT;
+ }
+ nColor = nAuthorColor[nLastUserIndex];
+ }
+}
+
+//==================================================================
+
+ScOutputData::ScOutputData( OutputDevice* pNewDev, ScOutputType eNewType,
+ ScTableInfo& rTabInfo, ScDocument* pNewDoc,
+ SCTAB nNewTab, long nNewScrX, long nNewScrY,
+ SCCOL nNewX1, SCROW nNewY1, SCCOL nNewX2, SCROW nNewY2,
+ double nPixelPerTwipsX, double nPixelPerTwipsY,
+ const Fraction* pZoomX, const Fraction* pZoomY ) :
+ pDev( pNewDev ),
+ pRefDevice( pNewDev ), // default is output device
+ pFmtDevice( pNewDev ), // default is output device
+ mrTabInfo( rTabInfo ),
+ pRowInfo( rTabInfo.mpRowInfo ),
+ nArrCount( rTabInfo.mnArrCount ),
+ pDoc( pNewDoc ),
+ nTab( nNewTab ),
+ nScrX( nNewScrX ),
+ nScrY( nNewScrY ),
+ nX1( nNewX1 ),
+ nY1( nNewY1 ),
+ nX2( nNewX2 ),
+ nY2( nNewY2 ),
+ eType( eNewType ),
+ nPPTX( nPixelPerTwipsX ),
+ nPPTY( nPixelPerTwipsY ),
+ pEditObj( NULL ),
+ pViewShell( NULL ),
+ pDrawView( NULL ), // #114135#
+ bEditMode( sal_False ),
+ bMetaFile( sal_False ),
+ bSingleGrid( sal_False ),
+ bPagebreakMode( sal_False ),
+ bSolidBackground( sal_False ),
+ bUseStyleColor( sal_False ),
+ bForceAutoColor( SC_MOD()->GetAccessOptions().GetIsAutomaticFontColor() ),
+ bSyntaxMode( sal_False ),
+ pValueColor( NULL ),
+ pTextColor( NULL ),
+ pFormulaColor( NULL ),
+ aGridColor( COL_BLACK ),
+ bShowNullValues( sal_True ),
+ bShowFormulas( sal_False ),
+ bShowSpellErrors( sal_False ),
+ bMarkClipped( sal_False ), // sal_False fuer Drucker/Metafile etc.
+ bSnapPixel( sal_False ),
+ bAnyRotated( sal_False ),
+ bAnyClipped( sal_False ),
+ mpTargetPaintWindow(0) // #i74769# use SdrPaintWindow direct
+{
+ if (pZoomX)
+ aZoomX = *pZoomX;
+ else
+ aZoomX = Fraction(1,1);
+ if (pZoomY)
+ aZoomY = *pZoomY;
+ else
+ aZoomY = Fraction(1,1);
+
+ nVisX1 = nX1;
+ nVisY1 = nY1;
+ nVisX2 = nX2;
+ nVisY2 = nY2;
+ pDoc->StripHidden( nVisX1, nVisY1, nVisX2, nVisY2, nTab );
+
+ nScrW = 0;
+ for (SCCOL nX=nVisX1; nX<=nVisX2; nX++)
+ nScrW += pRowInfo[0].pCellInfo[nX+1].nWidth;
+
+ nMirrorW = nScrW;
+
+ nScrH = 0;
+ for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
+ nScrH += pRowInfo[nArrY].nHeight;
+
+ bTabProtected = pDoc->IsTabProtected( nTab );
+ nTabTextDirection = pDoc->GetEditTextDirection( nTab );
+ bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+}
+
+ScOutputData::~ScOutputData()
+{
+ delete pValueColor;
+ delete pTextColor;
+ delete pFormulaColor;
+}
+
+void ScOutputData::SetContentDevice( OutputDevice* pContentDev )
+{
+ // use pContentDev instead of pDev where used
+
+ if ( pRefDevice == pDev )
+ pRefDevice = pContentDev;
+ if ( pFmtDevice == pDev )
+ pFmtDevice = pContentDev;
+ pDev = pContentDev;
+}
+
+void ScOutputData::SetMirrorWidth( long nNew )
+{
+ nMirrorW = nNew;
+}
+
+void ScOutputData::SetGridColor( const Color& rColor )
+{
+ aGridColor = rColor;
+}
+
+void ScOutputData::SetMarkClipped( sal_Bool bSet )
+{
+ bMarkClipped = bSet;
+}
+
+void ScOutputData::SetShowNullValues( sal_Bool bSet )
+{
+ bShowNullValues = bSet;
+}
+
+void ScOutputData::SetShowFormulas( sal_Bool bSet )
+{
+ bShowFormulas = bSet;
+}
+
+void ScOutputData::SetShowSpellErrors( sal_Bool bSet )
+{
+ bShowSpellErrors = bSet;
+}
+
+void ScOutputData::SetSnapPixel( sal_Bool bSet )
+{
+ bSnapPixel = bSet;
+}
+
+void ScOutputData::SetEditCell( SCCOL nCol, SCROW nRow )
+{
+ nEditCol = nCol;
+ nEditRow = nRow;
+ bEditMode = sal_True;
+}
+
+void ScOutputData::SetMetaFileMode( sal_Bool bNewMode )
+{
+ bMetaFile = bNewMode;
+}
+
+void ScOutputData::SetSingleGrid( sal_Bool bNewMode )
+{
+ bSingleGrid = bNewMode;
+}
+
+void ScOutputData::SetSyntaxMode( sal_Bool bNewMode )
+{
+ bSyntaxMode = bNewMode;
+ if (bNewMode)
+ if (!pValueColor)
+ {
+ pValueColor = new Color( COL_LIGHTBLUE );
+ pTextColor = new Color( COL_BLACK );
+ pFormulaColor = new Color( COL_GREEN );
+ }
+}
+
+void ScOutputData::DrawGrid( sal_Bool bGrid, sal_Bool bPage )
+{
+ SCCOL nX;
+ SCROW nY;
+ long nPosX;
+ long nPosY;
+ SCSIZE nArrY;
+ ScBreakType nBreak = BREAK_NONE;
+ ScBreakType nBreakOld = BREAK_NONE;
+
+ sal_Bool bSingle;
+ Color aPageColor;
+ Color aManualColor;
+
+ if (bPagebreakMode)
+ bPage = sal_False; // keine "normalen" Umbrueche ueber volle Breite/Hoehe
+
+ //! um den einen Pixel sieht das Metafile (oder die Druck-Ausgabe) anders aus
+ //! als die Bildschirmdarstellung, aber wenigstens passen Druck und Metafile zusammen
+
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ long nOneY = aOnePixel.Height();
+ if (bMetaFile)
+ nOneX = nOneY = 1;
+
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+ long nSignedOneX = nOneX * nLayoutSign;
+
+ if ( eType == OUTTYPE_WINDOW )
+ {
+ const svtools::ColorConfig& rColorCfg = SC_MOD()->GetColorConfig();
+ aPageColor.SetColor( rColorCfg.GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC).nColor );
+ aManualColor.SetColor( rColorCfg.GetColorValue(svtools::CALCPAGEBREAKMANUAL).nColor );
+ }
+ else
+ {
+ aPageColor = aGridColor;
+ aManualColor = aGridColor;
+ }
+
+ pDev->SetLineColor( aGridColor );
+ ScGridMerger aGrid( pDev, nOneX, nOneY );
+
+ //
+ // Vertikale Linien
+ //
+
+ nPosX = nScrX;
+ if ( bLayoutRTL )
+ nPosX += nMirrorW - nOneX;
+
+ for (nX=nX1; nX<=nX2; nX++)
+ {
+ SCCOL nXplus1 = nX+1;
+ SCCOL nXplus2 = nX+2;
+ sal_uInt16 nWidth = pRowInfo[0].pCellInfo[nXplus1].nWidth;
+ if (nWidth)
+ {
+ nPosX += nWidth * nLayoutSign;
+
+ if ( bPage )
+ {
+ // Seitenumbrueche auch in ausgeblendeten suchen
+ SCCOL nCol = nXplus1;
+ while (nCol <= MAXCOL)
+ {
+ nBreak = pDoc->HasColBreak(nCol, nTab);
+ bool bHidden = pDoc->ColHidden(nCol, nTab);
+
+ if ( nBreak || !bHidden )
+ break;
+ ++nCol;
+ }
+
+ if (nBreak != nBreakOld)
+ {
+ aGrid.Flush();
+ pDev->SetLineColor( (nBreak & BREAK_MANUAL) ? aManualColor :
+ nBreak ? aPageColor : aGridColor );
+ nBreakOld = nBreak;
+ }
+ }
+
+ sal_Bool bDraw = bGrid || nBreakOld; // einfaches Gitter nur wenn eingestellt
+
+ //! Mit dieser Abfrage wird zuviel weggelassen, wenn ein automatischer
+ //! Umbruch mitten in den Wiederholungsspalten liegt.
+ //! Dann lieber den aeusseren Rahmen zweimal ausgeben...
+#if 0
+ // auf dem Drucker die Aussen-Linien weglassen (werden getrennt ausgegeben)
+ if ( eType == OUTTYPE_PRINTER && !bMetaFile )
+ {
+ if ( nX == MAXCOL )
+ bDraw = sal_False;
+ else if (pDoc->HasColBreak(nXplus1, nTab))
+ bDraw = sal_False;
+ }
+#endif
+
+ sal_uInt16 nWidthXplus2 = pRowInfo[0].pCellInfo[nXplus2].nWidth;
+ bSingle = bSingleGrid; //! in Fillinfo holen !!!!!
+ if ( nX<MAXCOL && !bSingle )
+ {
+ bSingle = ( nWidthXplus2 == 0 );
+ for (nArrY=1; nArrY+1<nArrCount && !bSingle; nArrY++)
+ {
+ if (pRowInfo[nArrY].pCellInfo[nXplus2].bHOverlapped)
+ bSingle = sal_True;
+ if (pRowInfo[nArrY].pCellInfo[nXplus1].bHideGrid)
+ bSingle = sal_True;
+ }
+ }
+
+ if (bDraw)
+ {
+ if ( nX<MAXCOL && bSingle )
+ {
+ SCCOL nVisX = nXplus1;
+ while ( nVisX < MAXCOL && !pDoc->GetColWidth(nVisX,nTab) )
+ ++nVisX;
+
+ nPosY = nScrY;
+ long nNextY;
+ for (nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ nNextY = nPosY + pThisRowInfo->nHeight;
+
+ sal_Bool bHOver = pThisRowInfo->pCellInfo[nXplus1].bHideGrid;
+ if (!bHOver)
+ {
+ if (nWidthXplus2)
+ bHOver = pThisRowInfo->pCellInfo[nXplus2].bHOverlapped;
+ else
+ {
+ if (nVisX <= nX2)
+ bHOver = pThisRowInfo->pCellInfo[nVisX+1].bHOverlapped;
+ else
+ bHOver = ((ScMergeFlagAttr*)pDoc->GetAttr(
+ nVisX,pThisRowInfo->nRowNo,nTab,ATTR_MERGE_FLAG))
+ ->IsHorOverlapped();
+ if (bHOver)
+ bHOver = ((ScMergeFlagAttr*)pDoc->GetAttr(
+ nXplus1,pThisRowInfo->nRowNo,nTab,ATTR_MERGE_FLAG))
+ ->IsHorOverlapped();
+ }
+ }
+
+ if (pThisRowInfo->bChanged && !bHOver)
+ {
+ //Point aStart( nPosX-nSignedOneX, nPosY );
+ //Point aEnd( nPosX-nSignedOneX, nNextY-nOneY );
+ //pDev->DrawLine( aStart, aEnd );
+ aGrid.AddVerLine( nPosX-nSignedOneX, nPosY, nNextY-nOneY );
+ }
+ nPosY = nNextY;
+ }
+ }
+ else
+ {
+ //Point aStart( nPosX-nSignedOneX, nScrY );
+ //Point aEnd( nPosX-nSignedOneX, nScrY+nScrH-nOneY );
+ //pDev->DrawLine( aStart, aEnd );
+ aGrid.AddVerLine( nPosX-nSignedOneX, nScrY, nScrY+nScrH-nOneY );
+ }
+ }
+ }
+ }
+
+ //
+ // Horizontale Linien
+ //
+
+ bool bHiddenRow = true;
+ SCROW nHiddenEndRow = -1;
+ nPosY = nScrY;
+ for (nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ SCSIZE nArrYplus1 = nArrY+1;
+ nY = pRowInfo[nArrY].nRowNo;
+ SCROW nYplus1 = nY+1;
+ nPosY += pRowInfo[nArrY].nHeight;
+
+ if (pRowInfo[nArrY].bChanged)
+ {
+ if ( bPage )
+ {
+ for (SCROW i = nYplus1; i <= MAXROW; ++i)
+ {
+ if (i > nHiddenEndRow)
+ bHiddenRow = pDoc->RowHidden(i, nTab, nHiddenEndRow);
+ /* TODO: optimize the row break thing for large hidden
+ * segments where HasRowBreak() has to be called
+ * nevertheless for each row, as a row break is drawn also
+ * for hidden rows, above them. This needed to be done only
+ * once per hidden segment, maybe giving manual breaks
+ * priority. Something like GetNextRowBreak() and
+ * GetNextManualRowBreak(). */
+ nBreak = pDoc->HasRowBreak(i, nTab);
+ if (!bHiddenRow || nBreak)
+ break;
+ }
+
+ if (nBreakOld != nBreak)
+ {
+ aGrid.Flush();
+ pDev->SetLineColor( (nBreak & BREAK_MANUAL) ? aManualColor :
+ (nBreak) ? aPageColor : aGridColor );
+ nBreakOld = nBreak;
+ }
+ }
+
+ sal_Bool bDraw = bGrid || nBreakOld; // einfaches Gitter nur wenn eingestellt
+
+ //! Mit dieser Abfrage wird zuviel weggelassen, wenn ein automatischer
+ //! Umbruch mitten in den Wiederholungszeilen liegt.
+ //! Dann lieber den aeusseren Rahmen zweimal ausgeben...
+#if 0
+ // auf dem Drucker die Aussen-Linien weglassen (werden getrennt ausgegeben)
+ if ( eType == OUTTYPE_PRINTER && !bMetaFile )
+ {
+ if ( nY == MAXROW )
+ bDraw = sal_False;
+ else if (pDoc->HasRowBreak(nYplus1, nTab))
+ bDraw = sal_False;
+ }
+#endif
+
+ sal_Bool bNextYisNextRow = (pRowInfo[nArrYplus1].nRowNo == nYplus1);
+ bSingle = !bNextYisNextRow; // Hidden
+ for (SCCOL i=nX1; i<=nX2 && !bSingle; i++)
+ {
+ if (pRowInfo[nArrYplus1].pCellInfo[i+1].bVOverlapped)
+ bSingle = sal_True;
+ }
+
+ if (bDraw)
+ {
+ if ( bSingle && nY<MAXROW )
+ {
+ SCROW nVisY = pRowInfo[nArrYplus1].nRowNo;
+
+ nPosX = nScrX;
+ if ( bLayoutRTL )
+ nPosX += nMirrorW - nOneX;
+
+ long nNextX;
+ for (SCCOL i=nX1; i<=nX2; i++)
+ {
+ nNextX = nPosX + pRowInfo[0].pCellInfo[i+1].nWidth * nLayoutSign;
+ if (nNextX != nPosX) // sichtbar
+ {
+ sal_Bool bVOver;
+ if ( bNextYisNextRow )
+ bVOver = pRowInfo[nArrYplus1].pCellInfo[i+1].bVOverlapped;
+ else
+ {
+ bVOver = ((ScMergeFlagAttr*)pDoc->GetAttr(
+ i,nYplus1,nTab,ATTR_MERGE_FLAG))
+ ->IsVerOverlapped()
+ && ((ScMergeFlagAttr*)pDoc->GetAttr(
+ i,nVisY,nTab,ATTR_MERGE_FLAG))
+ ->IsVerOverlapped();
+ //! nVisY aus Array ??
+ }
+ if (!bVOver)
+ {
+ //Point aStart( nPosX, nPosY-nOneY );
+ //Point aEnd( nNextX-nSignedOneX, nPosY-nOneY );
+ //pDev->DrawLine( aStart, aEnd );
+ aGrid.AddHorLine( nPosX, nNextX-nSignedOneX, nPosY-nOneY );
+ }
+ }
+ nPosX = nNextX;
+ }
+ }
+ else
+ {
+ //Point aStart( nScrX, nPosY-nOneY );
+ //Point aEnd( nScrX+nScrW-nOneX, nPosY-nOneY );
+ //pDev->DrawLine( aStart, aEnd );
+ aGrid.AddHorLine( nScrX, nScrX+nScrW-nOneX, nPosY-nOneY );
+ }
+ }
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+void ScOutputData::SetPagebreakMode( ScPageBreakData* pPageData )
+{
+ bPagebreakMode = sal_True;
+ if (!pPageData)
+ return; // noch nicht initialisiert -> alles "nicht gedruckt"
+
+ // gedruckten Bereich markieren
+ // (in FillInfo ist schon alles auf sal_False initialisiert)
+
+ sal_uInt16 nRangeCount = sal::static_int_cast<sal_uInt16>(pPageData->GetCount());
+ for (sal_uInt16 nPos=0; nPos<nRangeCount; nPos++)
+ {
+ ScRange aRange = pPageData->GetData( nPos ).GetPrintRange();
+
+ SCCOL nStartX = Max( aRange.aStart.Col(), nX1 );
+ SCCOL nEndX = Min( aRange.aEnd.Col(), nX2 );
+ SCROW nStartY = Max( aRange.aStart.Row(), nY1 );
+ SCROW nEndY = Min( aRange.aEnd.Row(), nY2 );
+
+ for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ if ( pThisRowInfo->bChanged && pThisRowInfo->nRowNo >= nStartY &&
+ pThisRowInfo->nRowNo <= nEndY )
+ {
+ for (SCCOL nX=nStartX; nX<=nEndX; nX++)
+ pThisRowInfo->pCellInfo[nX+1].bPrinted = sal_True;
+ }
+ }
+ }
+}
+
+void ScOutputData::FindRotated()
+{
+ //! nRotMax speichern
+ SCCOL nRotMax = nX2;
+ for (SCSIZE nRotY=0; nRotY<nArrCount; nRotY++)
+ if (pRowInfo[nRotY].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nRotY].nRotMaxCol > nRotMax)
+ nRotMax = pRowInfo[nRotY].nRotMaxCol;
+
+ for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ if ( pThisRowInfo->nRotMaxCol != SC_ROTMAX_NONE &&
+ ( pThisRowInfo->bChanged || pRowInfo[nArrY-1].bChanged ||
+ ( nArrY+1<nArrCount && pRowInfo[nArrY+1].bChanged ) ) )
+ {
+ SCROW nY = pThisRowInfo->nRowNo;
+
+ for (SCCOL nX=0; nX<=nRotMax; nX++)
+ {
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+ const ScPatternAttr* pPattern = pInfo->pPatternAttr;
+ const SfxItemSet* pCondSet = pInfo->pConditionSet;
+
+ if ( !pPattern && !pDoc->ColHidden(nX, nTab) )
+ {
+ pPattern = pDoc->GetPattern( nX, nY, nTab );
+ pCondSet = pDoc->GetCondResult( nX, nY, nTab );
+ }
+
+ if ( pPattern ) // Spalte nicht ausgeblendet
+ {
+ sal_uInt8 nDir = pPattern->GetRotateDir( pCondSet );
+ if (nDir != SC_ROTDIR_NONE)
+ {
+ pInfo->nRotateDir = nDir;
+ bAnyRotated = sal_True;
+ }
+ }
+ }
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+sal_uInt16 lcl_GetRotateDir( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ const SfxItemSet* pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
+
+ sal_uInt16 nRet = SC_ROTDIR_NONE;
+
+ long nAttrRotate = pPattern->GetRotateVal( pCondSet );
+ if ( nAttrRotate )
+ {
+ SvxRotateMode eRotMode = (SvxRotateMode)((const SvxRotateModeItem&)
+ pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet)).GetValue();
+
+ if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
+ nRet = SC_ROTDIR_STANDARD;
+ else if ( eRotMode == SVX_ROTATE_MODE_CENTER )
+ nRet = SC_ROTDIR_CENTER;
+ else if ( eRotMode == SVX_ROTATE_MODE_TOP || eRotMode == SVX_ROTATE_MODE_BOTTOM )
+ {
+ long nRot180 = nAttrRotate % 18000; // 1/100 Grad
+ if ( nRot180 == 9000 )
+ nRet = SC_ROTDIR_CENTER;
+ else if ( ( eRotMode == SVX_ROTATE_MODE_TOP && nRot180 < 9000 ) ||
+ ( eRotMode == SVX_ROTATE_MODE_BOTTOM && nRot180 > 9000 ) )
+ nRet = SC_ROTDIR_LEFT;
+ else
+ nRet = SC_ROTDIR_RIGHT;
+ }
+ }
+
+ return nRet;
+}
+
+const SvxBrushItem* lcl_FindBackground( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ const SfxItemSet* pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
+ const SvxBrushItem* pBackground = (const SvxBrushItem*)
+ &pPattern->GetItem( ATTR_BACKGROUND, pCondSet );
+
+ sal_uInt16 nDir = lcl_GetRotateDir( pDoc, nCol, nRow, nTab );
+
+ // CENTER wird wie RIGHT behandelt...
+ if ( nDir == SC_ROTDIR_RIGHT || nDir == SC_ROTDIR_CENTER )
+ {
+ // Text geht nach rechts -> Hintergrund von links nehmen
+ while ( nCol > 0 && lcl_GetRotateDir( pDoc, nCol, nRow, nTab ) == nDir &&
+ pBackground->GetColor().GetTransparency() != 255 )
+ {
+ --nCol;
+ pPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
+ pBackground = (const SvxBrushItem*)&pPattern->GetItem( ATTR_BACKGROUND, pCondSet );
+ }
+ }
+ else if ( nDir == SC_ROTDIR_LEFT )
+ {
+ // Text geht nach links -> Hintergrund von rechts nehmen
+ while ( nCol < MAXCOL && lcl_GetRotateDir( pDoc, nCol, nRow, nTab ) == nDir &&
+ pBackground->GetColor().GetTransparency() != 255 )
+ {
+ ++nCol;
+ pPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
+ pBackground = (const SvxBrushItem*)&pPattern->GetItem( ATTR_BACKGROUND, pCondSet );
+ }
+ }
+
+ return pBackground;
+}
+
+// ----------------------------------------------------------------------------
+
+sal_Bool lcl_EqualBack( const RowInfo& rFirst, const RowInfo& rOther,
+ SCCOL nX1, SCCOL nX2, sal_Bool bShowProt, sal_Bool bPagebreakMode )
+{
+ if ( rFirst.bChanged != rOther.bChanged ||
+ rFirst.bEmptyBack != rOther.bEmptyBack )
+ return sal_False;
+
+ SCCOL nX;
+ if ( bShowProt )
+ {
+ for ( nX=nX1; nX<=nX2; nX++ )
+ {
+ const ScPatternAttr* pPat1 = rFirst.pCellInfo[nX+1].pPatternAttr;
+ const ScPatternAttr* pPat2 = rOther.pCellInfo[nX+1].pPatternAttr;
+ if ( !pPat1 || !pPat2 ||
+ &pPat1->GetItem(ATTR_PROTECTION) != &pPat2->GetItem(ATTR_PROTECTION) )
+ return sal_False;
+ }
+ }
+ else
+ {
+ for ( nX=nX1; nX<=nX2; nX++ )
+ if ( rFirst.pCellInfo[nX+1].pBackground != rOther.pCellInfo[nX+1].pBackground )
+ return sal_False;
+ }
+
+ if ( rFirst.nRotMaxCol != SC_ROTMAX_NONE || rOther.nRotMaxCol != SC_ROTMAX_NONE )
+ for ( nX=nX1; nX<=nX2; nX++ )
+ if ( rFirst.pCellInfo[nX+1].nRotateDir != rOther.pCellInfo[nX+1].nRotateDir )
+ return sal_False;
+
+ if ( bPagebreakMode )
+ for ( nX=nX1; nX<=nX2; nX++ )
+ if ( rFirst.pCellInfo[nX+1].bPrinted != rOther.pCellInfo[nX+1].bPrinted )
+ return sal_False;
+
+ return sal_True;
+}
+
+void ScOutputData::DrawBackground()
+{
+ FindRotated(); //! von aussen ?
+
+ ScModule* pScMod = SC_MOD();
+
+ // used only if bSolidBackground is set (only for ScGridWindow):
+ Color aBgColor( pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
+
+ Rectangle aRect;
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ long nOneY = aOnePixel.Height();
+
+ if (bMetaFile)
+ nOneX = nOneY = 0;
+
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+ long nSignedOneX = nOneX * nLayoutSign;
+
+ pDev->SetLineColor();
+
+ sal_Bool bShowProt = bSyntaxMode && pDoc->IsTabProtected(nTab);
+ sal_Bool bDoAll = bShowProt || bPagebreakMode || bSolidBackground;
+
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
+ sal_Bool bCellContrast = bUseStyleColor &&
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode();
+
+ long nPosY = nScrY;
+ for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ long nRowHeight = pThisRowInfo->nHeight;
+
+ if ( pThisRowInfo->bChanged )
+ {
+ if ( ( ( pThisRowInfo->bEmptyBack ) || bSyntaxMode ) && !bDoAll )
+ {
+ // nichts
+ }
+ else
+ {
+ // scan for rows with the same background:
+ SCSIZE nSkip = 0;
+ while ( nArrY+nSkip+2<nArrCount &&
+ lcl_EqualBack( *pThisRowInfo, pRowInfo[nArrY+nSkip+1],
+ nX1, nX2, bShowProt, bPagebreakMode ) )
+ {
+ ++nSkip;
+ nRowHeight += pRowInfo[nArrY+nSkip].nHeight; // after incrementing
+ }
+
+ long nPosX = nScrX;
+ if ( bLayoutRTL )
+ nPosX += nMirrorW - nOneX;
+ aRect = Rectangle( nPosX,nPosY, nPosX,nPosY+nRowHeight-nOneY );
+
+ const SvxBrushItem* pOldBackground = NULL;
+ const SvxBrushItem* pBackground;
+ for (SCCOL nX=nX1; nX<=nX2; nX++)
+ {
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+
+ if (bCellContrast)
+ {
+ // high contrast for cell borders and backgrounds -> empty background
+ pBackground = ScGlobal::GetEmptyBrushItem();
+ }
+ else if (bShowProt) // show cell protection in syntax mode
+ {
+ const ScPatternAttr* pP = pInfo->pPatternAttr;
+ if (pP)
+ {
+ const ScProtectionAttr& rProt = (const ScProtectionAttr&)
+ pP->GetItem(ATTR_PROTECTION);
+ if (rProt.GetProtection() || rProt.GetHideCell())
+ pBackground = ScGlobal::GetProtectedBrushItem();
+ else
+ pBackground = ScGlobal::GetEmptyBrushItem();
+ }
+ else
+ pBackground = NULL;
+ }
+ else
+ pBackground = pInfo->pBackground;
+
+ if ( bPagebreakMode && !pInfo->bPrinted )
+ pBackground = ScGlobal::GetProtectedBrushItem();
+
+ if ( pInfo->nRotateDir > SC_ROTDIR_STANDARD &&
+ pBackground->GetColor().GetTransparency() != 255 &&
+ !bCellContrast )
+ {
+ SCROW nY = pRowInfo[nArrY].nRowNo;
+ pBackground = lcl_FindBackground( pDoc, nX, nY, nTab );
+ }
+
+ if ( pBackground != pOldBackground )
+ {
+ aRect.Right() = nPosX-nSignedOneX;
+ if (pOldBackground) // ==0 if hidden
+ {
+ Color aBackCol = pOldBackground->GetColor();
+ if ( bSolidBackground && aBackCol.GetTransparency() )
+ aBackCol = aBgColor;
+ if ( !aBackCol.GetTransparency() ) //! partial transparency?
+ {
+ pDev->SetFillColor( aBackCol );
+ pDev->DrawRect( aRect );
+ }
+ }
+ aRect.Left() = nPosX;
+ pOldBackground = pBackground;
+ }
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+ }
+ aRect.Right() = nPosX-nSignedOneX;
+ if (pOldBackground)
+ {
+ Color aBackCol = pOldBackground->GetColor();
+ if ( bSolidBackground && aBackCol.GetTransparency() )
+ aBackCol = aBgColor;
+ if ( !aBackCol.GetTransparency() ) //! partial transparency?
+ {
+ pDev->SetFillColor( aBackCol );
+ pDev->DrawRect( aRect );
+ }
+ }
+
+ nArrY += nSkip;
+ }
+ }
+ nPosY += nRowHeight;
+ }
+}
+
+void ScOutputData::DrawShadow()
+{
+ DrawExtraShadow( sal_False, sal_False, sal_False, sal_False );
+}
+
+void ScOutputData::DrawExtraShadow(sal_Bool bLeft, sal_Bool bTop, sal_Bool bRight, sal_Bool bBottom)
+{
+ pDev->SetLineColor();
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
+ sal_Bool bCellContrast = bUseStyleColor && rStyleSettings.GetHighContrastMode();
+ Color aAutoTextColor;
+ if ( bCellContrast )
+ aAutoTextColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+
+ long nInitPosX = nScrX;
+ if ( bLayoutRTL )
+ {
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ nInitPosX += nMirrorW - nOneX;
+ }
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ long nPosY = nScrY - pRowInfo[0].nHeight;
+ for (SCSIZE nArrY=0; nArrY<nArrCount; nArrY++)
+ {
+ sal_Bool bCornerY = ( nArrY == 0 ) || ( nArrY+1 == nArrCount );
+ sal_Bool bSkipY = ( nArrY==0 && !bTop ) || ( nArrY+1 == nArrCount && !bBottom );
+
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ long nRowHeight = pThisRowInfo->nHeight;
+
+ if ( pThisRowInfo->bChanged && !bSkipY )
+ {
+ long nPosX = nInitPosX - pRowInfo[0].pCellInfo[nX1].nWidth * nLayoutSign;
+ for (SCCOL nArrX=nX1; nArrX<=nX2+2; nArrX++)
+ {
+ sal_Bool bCornerX = ( nArrX==nX1 || nArrX==nX2+2 );
+ sal_Bool bSkipX = ( nArrX==nX1 && !bLeft ) || ( nArrX==nX2+2 && !bRight );
+
+ for (sal_uInt16 nPass=0; nPass<2; nPass++) // horizontal / vertikal
+ {
+ const SvxShadowItem* pAttr = nPass ?
+ pThisRowInfo->pCellInfo[nArrX].pVShadowOrigin :
+ pThisRowInfo->pCellInfo[nArrX].pHShadowOrigin;
+ if ( pAttr && !bSkipX )
+ {
+ ScShadowPart ePart = nPass ?
+ pThisRowInfo->pCellInfo[nArrX].eVShadowPart :
+ pThisRowInfo->pCellInfo[nArrX].eHShadowPart;
+
+ sal_Bool bDo = sal_True;
+ if ( (nPass==0 && bCornerX) || (nPass==1 && bCornerY) )
+ if ( ePart != SC_SHADOW_CORNER )
+ bDo = sal_False;
+
+ if (bDo)
+ {
+ long nThisWidth = pRowInfo[0].pCellInfo[nArrX].nWidth;
+ long nMaxWidth = nThisWidth;
+ if (!nMaxWidth)
+ {
+ //! direction must depend on shadow location
+ SCCOL nWx = nArrX; // nX+1
+ while (nWx<nX2 && !pRowInfo[0].pCellInfo[nWx+1].nWidth)
+ ++nWx;
+ nMaxWidth = pRowInfo[0].pCellInfo[nWx+1].nWidth;
+ }
+
+// Rectangle aRect( Point(nPosX,nPosY),
+// Size( pRowInfo[0].pCellInfo[nArrX].nWidth,
+// pRowInfo[nArrY].nHeight ) );
+
+ // rectangle is in logical orientation
+ Rectangle aRect( nPosX, nPosY,
+ nPosX + ( nThisWidth - 1 ) * nLayoutSign,
+ nPosY + pRowInfo[nArrY].nHeight - 1 );
+
+ long nSize = pAttr->GetWidth();
+ long nSizeX = (long)(nSize*nPPTX);
+ if (nSizeX >= nMaxWidth) nSizeX = nMaxWidth-1;
+ long nSizeY = (long)(nSize*nPPTY);
+ if (nSizeY >= nRowHeight) nSizeY = nRowHeight-1;
+
+ nSizeX *= nLayoutSign; // used only to add to rectangle values
+
+ SvxShadowLocation eLoc = pAttr->GetLocation();
+ if ( bLayoutRTL )
+ {
+ // Shadow location is specified as "visual" (right is always right),
+ // so the attribute's location value is mirrored here and in FillInfo.
+ switch (eLoc)
+ {
+ case SVX_SHADOW_BOTTOMRIGHT: eLoc = SVX_SHADOW_BOTTOMLEFT; break;
+ case SVX_SHADOW_BOTTOMLEFT: eLoc = SVX_SHADOW_BOTTOMRIGHT; break;
+ case SVX_SHADOW_TOPRIGHT: eLoc = SVX_SHADOW_TOPLEFT; break;
+ case SVX_SHADOW_TOPLEFT: eLoc = SVX_SHADOW_TOPRIGHT; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+
+ if (ePart == SC_SHADOW_HORIZ || ePart == SC_SHADOW_HSTART ||
+ ePart == SC_SHADOW_CORNER)
+ {
+ if (eLoc == SVX_SHADOW_TOPLEFT || eLoc == SVX_SHADOW_TOPRIGHT)
+ aRect.Top() = aRect.Bottom() - nSizeY;
+ else
+ aRect.Bottom() = aRect.Top() + nSizeY;
+ }
+ if (ePart == SC_SHADOW_VERT || ePart == SC_SHADOW_VSTART ||
+ ePart == SC_SHADOW_CORNER)
+ {
+ if (eLoc == SVX_SHADOW_TOPLEFT || eLoc == SVX_SHADOW_BOTTOMLEFT)
+ aRect.Left() = aRect.Right() - nSizeX;
+ else
+ aRect.Right() = aRect.Left() + nSizeX;
+ }
+ if (ePart == SC_SHADOW_HSTART)
+ {
+ if (eLoc == SVX_SHADOW_TOPLEFT || eLoc == SVX_SHADOW_BOTTOMLEFT)
+ aRect.Right() -= nSizeX;
+ else
+ aRect.Left() += nSizeX;
+ }
+ if (ePart == SC_SHADOW_VSTART)
+ {
+ if (eLoc == SVX_SHADOW_TOPLEFT || eLoc == SVX_SHADOW_TOPRIGHT)
+ aRect.Bottom() -= nSizeY;
+ else
+ aRect.Top() += nSizeY;
+ }
+
+ //! merge rectangles?
+ pDev->SetFillColor( bCellContrast ? aAutoTextColor : pAttr->GetColor() );
+ pDev->DrawRect( aRect );
+ }
+ }
+ }
+
+ nPosX += pRowInfo[0].pCellInfo[nArrX].nWidth * nLayoutSign;
+ }
+ }
+ nPosY += nRowHeight;
+ }
+}
+
+//
+// Loeschen
+//
+
+void ScOutputData::DrawClear()
+{
+ Rectangle aRect;
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ long nOneY = aOnePixel.Height();
+
+ // (called only for ScGridWindow)
+ Color aBgColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
+
+ if (bMetaFile)
+ nOneX = nOneY = 0;
+
+ pDev->SetLineColor();
+
+ pDev->SetFillColor( aBgColor );
+
+ long nPosY = nScrY;
+ for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ long nRowHeight = pThisRowInfo->nHeight;
+
+ if ( pThisRowInfo->bChanged )
+ {
+ // scan for more rows which must be painted:
+ SCSIZE nSkip = 0;
+ while ( nArrY+nSkip+2<nArrCount && pRowInfo[nArrY+nSkip+1].bChanged )
+ {
+ ++nSkip;
+ nRowHeight += pRowInfo[nArrY+nSkip].nHeight; // after incrementing
+ }
+
+ aRect = Rectangle( Point( nScrX, nPosY ),
+ Size( nScrW+1-nOneX, nRowHeight+1-nOneY) );
+ pDev->DrawRect( aRect );
+
+ nArrY += nSkip;
+ }
+ nPosY += nRowHeight;
+ }
+}
+
+
+//
+// Linien
+//
+
+long lclGetSnappedX( OutputDevice& rDev, long nPosX, bool bSnapPixel )
+{
+ return (bSnapPixel && nPosX) ? rDev.PixelToLogic( rDev.LogicToPixel( Size( nPosX, 0 ) ) ).Width() : nPosX;
+}
+
+long lclGetSnappedY( OutputDevice& rDev, long nPosY, bool bSnapPixel )
+{
+ return (bSnapPixel && nPosY) ? rDev.PixelToLogic( rDev.LogicToPixel( Size( 0, nPosY ) ) ).Height() : nPosY;
+}
+
+size_t lclGetArrayColFromCellInfoX( sal_uInt16 nCellInfoX, sal_uInt16 nCellInfoFirstX, sal_uInt16 nCellInfoLastX, bool bRTL )
+{
+ return static_cast< size_t >( bRTL ? (nCellInfoLastX + 2 - nCellInfoX) : (nCellInfoX - nCellInfoFirstX) );
+}
+
+void ScOutputData::DrawFrame()
+{
+ sal_uLong nOldDrawMode = pDev->GetDrawMode();
+
+ Color aSingleColor;
+ sal_Bool bUseSingleColor = sal_False;
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
+ sal_Bool bCellContrast = bUseStyleColor && rStyleSettings.GetHighContrastMode();
+
+ // #107519# if a Calc OLE object is embedded in Draw/Impress, the VCL DrawMode is used
+ // for display mode / B&W printing. The VCL DrawMode handling doesn't work for lines
+ // that are drawn with DrawRect, so if the line/background bits are set, the DrawMode
+ // must be reset and the border colors handled here.
+
+ if ( ( nOldDrawMode & DRAWMODE_WHITEFILL ) && ( nOldDrawMode & DRAWMODE_BLACKLINE ) )
+ {
+ pDev->SetDrawMode( nOldDrawMode & (~DRAWMODE_WHITEFILL) );
+ aSingleColor.SetColor( COL_BLACK );
+ bUseSingleColor = sal_True;
+ }
+ else if ( ( nOldDrawMode & DRAWMODE_SETTINGSFILL ) && ( nOldDrawMode & DRAWMODE_SETTINGSLINE ) )
+ {
+ pDev->SetDrawMode( nOldDrawMode & (~DRAWMODE_SETTINGSFILL) );
+ aSingleColor = rStyleSettings.GetWindowTextColor(); // same as used in VCL for DRAWMODE_SETTINGSLINE
+ bUseSingleColor = sal_True;
+ }
+ else if ( bCellContrast )
+ {
+ aSingleColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+ bUseSingleColor = sal_True;
+ }
+
+ const Color* pForceColor = bUseSingleColor ? &aSingleColor : 0;
+
+ if (bAnyRotated)
+ DrawRotatedFrame( pForceColor ); // removes the lines that must not be painted here
+
+ long nInitPosX = nScrX;
+ if ( bLayoutRTL )
+ {
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ nInitPosX += nMirrorW - nOneX;
+ }
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+
+ // *** set column and row sizes of the frame border array ***
+
+ svx::frame::Array& rArray = mrTabInfo.maArray;
+ size_t nColCount = rArray.GetColCount();
+ size_t nRowCount = rArray.GetRowCount();
+
+ // row heights
+
+ // row 0 is not visible (dummy for borders from top) - subtract its height from initial position
+ // subtract 1 unit more, because position 0 is first *in* cell, grid line is one unit before
+ long nOldPosY = nScrY - 1 - pRowInfo[ 0 ].nHeight;
+ long nOldSnapY = lclGetSnappedY( *pDev, nOldPosY, bSnapPixel );
+ rArray.SetYOffset( nOldSnapY );
+ for( size_t nRow = 0; nRow < nRowCount; ++nRow )
+ {
+ long nNewPosY = nOldPosY + pRowInfo[ nRow ].nHeight;
+ long nNewSnapY = lclGetSnappedY( *pDev, nNewPosY, bSnapPixel );
+ rArray.SetRowHeight( nRow, nNewSnapY - nOldSnapY );
+ nOldPosY = nNewPosY;
+ nOldSnapY = nNewSnapY;
+ }
+
+ // column widths
+
+ // column nX1 is not visible (dummy for borders from left) - subtract its width from initial position
+ // subtract 1 unit more, because position 0 is first *in* cell, grid line is one unit above
+ long nOldPosX = nInitPosX - nLayoutSign * (1 + pRowInfo[ 0 ].pCellInfo[ nX1 ].nWidth);
+ long nOldSnapX = lclGetSnappedX( *pDev, nOldPosX, bSnapPixel );
+ // set X offset for left-to-right sheets; for right-to-left sheets this is done after for() loop
+ if( !bLayoutRTL )
+ rArray.SetXOffset( nOldSnapX );
+ for( sal_uInt16 nInfoIdx = nX1; nInfoIdx <= nX2 + 2; ++nInfoIdx )
+ {
+ size_t nCol = lclGetArrayColFromCellInfoX( nInfoIdx, nX1, nX2, bLayoutRTL );
+ long nNewPosX = nOldPosX + pRowInfo[ 0 ].pCellInfo[ nInfoIdx ].nWidth * nLayoutSign;
+ long nNewSnapX = lclGetSnappedX( *pDev, nNewPosX, bSnapPixel );
+ rArray.SetColWidth( nCol, Abs( nNewSnapX - nOldSnapX ) );
+ nOldPosX = nNewPosX;
+ nOldSnapX = nNewSnapX;
+ }
+ if( bLayoutRTL )
+ rArray.SetXOffset( nOldSnapX );
+
+ // *** draw the array ***
+
+ size_t nFirstCol = 1;
+ size_t nFirstRow = 1;
+ size_t nLastCol = nColCount - 2;
+ size_t nLastRow = nRowCount - 2;
+
+ if( mrTabInfo.mbPageMode )
+ rArray.SetClipRange( nFirstCol, nFirstRow, nLastCol, nLastRow );
+
+ // draw only rows with set RowInfo::bChanged flag
+ size_t nRow1 = nFirstRow;
+ while( nRow1 <= nLastRow )
+ {
+ while( (nRow1 <= nLastRow) && !pRowInfo[ nRow1 ].bChanged ) ++nRow1;
+ if( nRow1 <= nLastRow )
+ {
+ size_t nRow2 = nRow1;
+ while( (nRow2 + 1 <= nLastRow) && pRowInfo[ nRow2 + 1 ].bChanged ) ++nRow2;
+ rArray.DrawRange( *pDev, nFirstCol, nRow1, nLastCol, nRow2, pForceColor );
+ nRow1 = nRow2 + 1;
+ }
+ }
+
+ pDev->SetDrawMode(nOldDrawMode);
+}
+
+// -------------------------------------------------------------------------
+
+// Linie unter der Zelle
+
+const SvxBorderLine* lcl_FindHorLine( ScDocument* pDoc,
+ SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nRotDir,
+ sal_Bool bTopLine )
+{
+ if ( nRotDir != SC_ROTDIR_LEFT && nRotDir != SC_ROTDIR_RIGHT )
+ return NULL;
+
+ sal_Bool bFound = sal_False;
+ while (!bFound)
+ {
+ if ( nRotDir == SC_ROTDIR_LEFT )
+ {
+ // Text nach links -> Linie von rechts
+ if ( nCol < MAXCOL )
+ ++nCol;
+ else
+ return NULL; // war nix
+ }
+ else
+ {
+ // Text nach rechts -> Linie von links
+ if ( nCol > 0 )
+ --nCol;
+ else
+ return NULL; // war nix
+ }
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ const SfxItemSet* pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
+ if ( !pPattern->GetRotateVal( pCondSet ) ||
+ ((const SvxRotateModeItem&)pPattern->GetItem(
+ ATTR_ROTATE_MODE, pCondSet)).GetValue() == SVX_ROTATE_MODE_STANDARD )
+ bFound = sal_True;
+ }
+
+ if (bTopLine)
+ --nRow;
+ const SvxBorderLine* pThisBottom;
+ if ( ValidRow(nRow) )
+ pThisBottom = ((const SvxBoxItem*)pDoc->GetAttr( nCol, nRow, nTab, ATTR_BORDER ))->GetBottom();
+ else
+ pThisBottom = NULL;
+ const SvxBorderLine* pNextTop;
+ if ( nRow < MAXROW )
+ pNextTop = ((const SvxBoxItem*)pDoc->GetAttr( nCol, nRow+1, nTab, ATTR_BORDER ))->GetTop();
+ else
+ pNextTop = NULL;
+
+ if ( ScHasPriority( pThisBottom, pNextTop ) )
+ return pThisBottom;
+ else
+ return pNextTop;
+}
+
+// lcl_HorizLine muss genau zu normal ausgegebenen Linien passen!
+
+void lcl_HorizLine( OutputDevice& rDev, const Point& rLeft, const Point& rRight,
+ const svx::frame::Style& rLine, const Color* pForceColor )
+{
+ svx::frame::DrawHorFrameBorder( rDev, rLeft, rRight, rLine, pForceColor );
+}
+
+void lcl_VertLineEnds( OutputDevice& rDev, const Point& rTop, const Point& rBottom,
+ const Color& rColor, long nXOffs, long nWidth,
+ const svx::frame::Style& rTopLine, const svx::frame::Style& rBottomLine )
+{
+ rDev.SetLineColor(rColor); // PEN_NULL ???
+ rDev.SetFillColor(rColor);
+
+ // Position oben/unten muss unabhaengig von der Liniendicke sein,
+ // damit der Winkel stimmt (oder X-Position auch anpassen)
+ long nTopPos = rTop.Y();
+ long nBotPos = rBottom.Y();
+
+ long nTopLeft = rTop.X() + nXOffs;
+ long nTopRight = nTopLeft + nWidth - 1;
+
+ long nBotLeft = rBottom.X() + nXOffs;
+ long nBotRight = nBotLeft + nWidth - 1;
+
+ // oben abschliessen
+
+ if ( rTopLine.Prim() )
+ {
+ long nLineW = rTopLine.GetWidth();
+ if (nLineW >= 2)
+ {
+ Point aTriangle[3];
+ aTriangle[0] = Point( nTopLeft, nTopPos ); // wie aPoints[0]
+ aTriangle[1] = Point( nTopRight, nTopPos ); // wie aPoints[1]
+ aTriangle[2] = Point( rTop.X(), nTopPos - (nLineW - 1) / 2 );
+ Polygon aTriPoly( 3, aTriangle );
+ rDev.DrawPolygon( aTriPoly );
+ }
+ }
+
+ // unten abschliessen
+
+ if ( rBottomLine.Prim() )
+ {
+ long nLineW = rBottomLine.GetWidth();
+ if (nLineW >= 2)
+ {
+ Point aTriangle[3];
+ aTriangle[0] = Point( nBotLeft, nBotPos ); // wie aPoints[3]
+ aTriangle[1] = Point( nBotRight, nBotPos ); // wie aPoints[2]
+ aTriangle[2] = Point( rBottom.X(), nBotPos - (nLineW - 1) / 2 + nLineW - 1 );
+ Polygon aTriPoly( 3, aTriangle );
+ rDev.DrawPolygon( aTriPoly );
+ }
+ }
+}
+
+void lcl_VertLine( OutputDevice& rDev, const Point& rTop, const Point& rBottom,
+ const svx::frame::Style& rLine,
+ const svx::frame::Style& rTopLine, const svx::frame::Style& rBottomLine,
+ const Color* pForceColor )
+{
+ if( rLine.Prim() )
+ {
+ svx::frame::DrawVerFrameBorderSlanted( rDev, rTop, rBottom, rLine, pForceColor );
+
+ svx::frame::Style aScaled( rLine );
+ aScaled.ScaleSelf( 1.0 / cos( svx::frame::GetVerDiagAngle( rTop, rBottom ) ) );
+ if( pForceColor )
+ aScaled.SetColor( *pForceColor );
+
+ long nXOffs = (aScaled.GetWidth() - 1) / -2L;
+
+ lcl_VertLineEnds( rDev, rTop, rBottom, aScaled.GetColor(),
+ nXOffs, aScaled.Prim(), rTopLine, rBottomLine );
+
+ if( aScaled.Secn() )
+ lcl_VertLineEnds( rDev, rTop, rBottom, aScaled.GetColor(),
+ nXOffs + aScaled.Prim() + aScaled.Dist(), aScaled.Secn(), rTopLine, rBottomLine );
+ }
+}
+
+void ScOutputData::DrawRotatedFrame( const Color* pForceColor )
+{
+ //! nRotMax speichern
+ SCCOL nRotMax = nX2;
+ for (SCSIZE nRotY=0; nRotY<nArrCount; nRotY++)
+ if (pRowInfo[nRotY].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nRotY].nRotMaxCol > nRotMax)
+ nRotMax = pRowInfo[nRotY].nRotMaxCol;
+
+ const ScPatternAttr* pPattern;
+ const SfxItemSet* pCondSet;
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
+ sal_Bool bCellContrast = bUseStyleColor && rStyleSettings.GetHighContrastMode();
+
+ // color (pForceColor) is determined externally, including DrawMode changes
+
+ long nInitPosX = nScrX;
+ if ( bLayoutRTL )
+ {
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ nInitPosX += nMirrorW - nOneX;
+ }
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ Rectangle aClipRect( Point(nScrX, nScrY), Size(nScrW, nScrH) );
+ if (bMetaFile)
+ {
+ pDev->Push();
+ pDev->IntersectClipRegion( aClipRect );
+ }
+ else
+ pDev->SetClipRegion( Region( aClipRect ) );
+
+ svx::frame::Array& rArray = mrTabInfo.maArray;
+
+ long nPosY = nScrY;
+ for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++)
+ {
+ // Rotated wird auch 1 Zeile ueber/unter Changed gezeichnet, falls Teile
+ // in die Zeile hineinragen...
+
+ RowInfo& rPrevRowInfo = pRowInfo[nArrY-1];
+ RowInfo& rThisRowInfo = pRowInfo[nArrY];
+ RowInfo& rNextRowInfo = pRowInfo[nArrY+1];
+
+ size_t nRow = static_cast< size_t >( nArrY );
+
+ long nRowHeight = rThisRowInfo.nHeight;
+ if ( rThisRowInfo.nRotMaxCol != SC_ROTMAX_NONE &&
+ ( rThisRowInfo.bChanged || rPrevRowInfo.bChanged ||
+ ( nArrY+1<nArrCount && rNextRowInfo.bChanged ) ) )
+ {
+ SCROW nY = rThisRowInfo.nRowNo;
+ long nPosX = 0;
+ SCCOL nX;
+ for (nX=0; nX<=nRotMax; nX++)
+ {
+ if (nX==nX1) nPosX = nInitPosX; // calculated individually for preceding positions
+
+ sal_uInt16 nArrX = nX + 1;
+
+ CellInfo* pInfo = &rThisRowInfo.pCellInfo[nArrX];
+ long nColWidth = pRowInfo[0].pCellInfo[nArrX].nWidth;
+ if ( pInfo->nRotateDir > SC_ROTDIR_STANDARD &&
+ !pInfo->bHOverlapped && !pInfo->bVOverlapped )
+ {
+ pPattern = pInfo->pPatternAttr;
+ pCondSet = pInfo->pConditionSet;
+ if (!pPattern)
+ {
+ pPattern = pDoc->GetPattern( nX, nY, nTab );
+ pInfo->pPatternAttr = pPattern;
+ pCondSet = pDoc->GetCondResult( nX, nY, nTab );
+ pInfo->pConditionSet = pCondSet;
+ }
+
+ //! LastPattern etc.
+
+ long nAttrRotate = pPattern->GetRotateVal( pCondSet );
+ SvxRotateMode eRotMode = (SvxRotateMode)((const SvxRotateModeItem&)
+ pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet)).GetValue();
+
+ if ( nAttrRotate )
+ {
+ if (nX<nX1) // negative Position berechnen
+ {
+ nPosX = nInitPosX;
+ SCCOL nCol = nX1;
+ while (nCol > nX)
+ {
+ --nCol;
+ nPosX -= nLayoutSign * (long) pRowInfo[0].pCellInfo[nCol+1].nWidth;
+ }
+ }
+
+ // Startposition minus 1, damit auch schraege Hintergruende
+ // zur Umrandung passen (Umrandung ist auf dem Gitter)
+
+ long nTop = nPosY - 1;
+ long nBottom = nPosY + nRowHeight - 1;
+ long nTopLeft = nPosX - nLayoutSign;
+ long nTopRight = nPosX + ( nColWidth - 1 ) * nLayoutSign;
+ long nBotLeft = nTopLeft;
+ long nBotRight = nTopRight;
+
+ // inclusion of the sign here hasn't been decided yet
+ // (if not, the extension of the non-rotated background must also be changed)
+ double nRealOrient = nLayoutSign * nAttrRotate * F_PI18000; // 1/100th degrees
+ double nCos = cos( nRealOrient );
+ double nSin = sin( nRealOrient );
+ //! begrenzen !!!
+ long nSkew = (long) ( nRowHeight * nCos / nSin );
+
+ switch (eRotMode)
+ {
+ case SVX_ROTATE_MODE_BOTTOM:
+ nTopLeft += nSkew;
+ nTopRight += nSkew;
+ break;
+ case SVX_ROTATE_MODE_CENTER:
+ nSkew /= 2;
+ nTopLeft += nSkew;
+ nTopRight += nSkew;
+ nBotLeft -= nSkew;
+ nBotRight -= nSkew;
+ break;
+ case SVX_ROTATE_MODE_TOP:
+ nBotLeft -= nSkew;
+ nBotRight -= nSkew;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ Point aPoints[4];
+ aPoints[0] = Point( nTopLeft, nTop );
+ aPoints[1] = Point( nTopRight, nTop );
+ aPoints[2] = Point( nBotRight, nBottom );
+ aPoints[3] = Point( nBotLeft, nBottom );
+
+ const SvxBrushItem* pBackground = pInfo->pBackground;
+ if (!pBackground)
+ pBackground = (const SvxBrushItem*) &pPattern->GetItem(
+ ATTR_BACKGROUND, pCondSet );
+ if (bCellContrast)
+ {
+ // high contrast for cell borders and backgrounds -> empty background
+ pBackground = ScGlobal::GetEmptyBrushItem();
+ }
+ const Color& rColor = pBackground->GetColor();
+ if ( rColor.GetTransparency() != 255 )
+ {
+ // #95879# draw background only for the changed row itself
+ // (background doesn't extend into other cells).
+ // For the borders (rotated and normal), clipping should be
+ // set if the row isn't changed, but at least the borders
+ // don't cover the cell contents.
+ if ( rThisRowInfo.bChanged )
+ {
+ Polygon aPoly( 4, aPoints );
+
+ // ohne Pen wird bei DrawPolygon rechts und unten
+ // ein Pixel weggelassen...
+ if ( rColor.GetTransparency() == 0 )
+ pDev->SetLineColor(rColor);
+ else
+ pDev->SetLineColor();
+ pDev->SetFillColor(rColor);
+ pDev->DrawPolygon( aPoly );
+ }
+ }
+
+ svx::frame::Style aTopLine, aBottomLine, aLeftLine, aRightLine;
+
+ if ( nX < nX1 || nX > nX2 ) // Attribute in FillInfo nicht gesetzt
+ {
+ //! Seitengrenzen fuer Druck beruecksichtigen !!!!!
+ const SvxBorderLine* pLeftLine;
+ const SvxBorderLine* pTopLine;
+ const SvxBorderLine* pRightLine;
+ const SvxBorderLine* pBottomLine;
+ pDoc->GetBorderLines( nX, nY, nTab,
+ &pLeftLine, &pTopLine, &pRightLine, &pBottomLine );
+ aTopLine.Set( pTopLine, nPPTY );
+ aBottomLine.Set( pBottomLine, nPPTY );
+ aLeftLine.Set( pLeftLine, nPPTX );
+ aRightLine.Set( pRightLine, nPPTX );
+ }
+ else
+ {
+ size_t nCol = lclGetArrayColFromCellInfoX( nArrX, nX1, nX2, bLayoutRTL );
+ aTopLine = rArray.GetCellStyleTop( nCol, nRow );
+ aBottomLine = rArray.GetCellStyleBottom( nCol, nRow );
+ aLeftLine = rArray.GetCellStyleLeft( nCol, nRow );
+ aRightLine = rArray.GetCellStyleRight( nCol, nRow );
+ // in RTL mode the array is already mirrored -> swap back left/right borders
+ if( bLayoutRTL )
+ std::swap( aLeftLine, aRightLine );
+ }
+
+ lcl_HorizLine( *pDev, aPoints[bLayoutRTL?1:0], aPoints[bLayoutRTL?0:1], aTopLine, pForceColor );
+ lcl_HorizLine( *pDev, aPoints[bLayoutRTL?2:3], aPoints[bLayoutRTL?3:2], aBottomLine, pForceColor );
+
+ lcl_VertLine( *pDev, aPoints[0], aPoints[3], aLeftLine, aTopLine, aBottomLine, pForceColor );
+ lcl_VertLine( *pDev, aPoints[1], aPoints[2], aRightLine, aTopLine, aBottomLine, pForceColor );
+ }
+ }
+ nPosX += nColWidth * nLayoutSign;
+ }
+
+ // erst hinterher im zweiten Schritt die Linien fuer normale Ausgabe loeschen
+
+ nX = nX1 > 0 ? (nX1-1) : static_cast<SCCOL>(0);
+ for (; nX<=nX2+1; nX++) // sichtbarer Teil +- 1
+ {
+ sal_uInt16 nArrX = nX + 1;
+ CellInfo& rInfo = rThisRowInfo.pCellInfo[nArrX];
+ if ( rInfo.nRotateDir > SC_ROTDIR_STANDARD &&
+ !rInfo.bHOverlapped && !rInfo.bVOverlapped )
+ {
+ pPattern = rInfo.pPatternAttr;
+ pCondSet = rInfo.pConditionSet;
+ SvxRotateMode eRotMode = (SvxRotateMode)((const SvxRotateModeItem&)
+ pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet)).GetValue();
+
+ size_t nCol = lclGetArrayColFromCellInfoX( nArrX, nX1, nX2, bLayoutRTL );
+
+ // horizontal: angrenzende Linie verlaengern
+ // (nur, wenn die gedrehte Zelle eine Umrandung hat)
+ sal_uInt16 nDir = rInfo.nRotateDir;
+ if ( rArray.GetCellStyleTop( nCol, nRow ).Prim() && eRotMode != SVX_ROTATE_MODE_TOP )
+ {
+ svx::frame::Style aStyle( lcl_FindHorLine( pDoc, nX, nY, nTab, nDir, sal_True ), nPPTY );
+ rArray.SetCellStyleTop( nCol, nRow, aStyle );
+ if( nRow > 0 )
+ rArray.SetCellStyleBottom( nCol, nRow - 1, aStyle );
+ }
+ if ( rArray.GetCellStyleBottom( nCol, nRow ).Prim() && eRotMode != SVX_ROTATE_MODE_BOTTOM )
+ {
+ svx::frame::Style aStyle( lcl_FindHorLine( pDoc, nX, nY, nTab, nDir, sal_False ), nPPTY );
+ rArray.SetCellStyleBottom( nCol, nRow, aStyle );
+ if( nRow + 1 < rArray.GetRowCount() )
+ rArray.SetCellStyleTop( nCol, nRow + 1, aStyle );
+ }
+
+ // always remove vertical borders
+ if( !rArray.IsMergedOverlappedLeft( nCol, nRow ) )
+ {
+ rArray.SetCellStyleLeft( nCol, nRow, svx::frame::Style() );
+ if( nCol > 0 )
+ rArray.SetCellStyleRight( nCol - 1, nRow, svx::frame::Style() );
+ }
+ if( !rArray.IsMergedOverlappedRight( nCol, nRow ) )
+ {
+ rArray.SetCellStyleRight( nCol, nRow, svx::frame::Style() );
+ if( nCol + 1 < rArray.GetColCount() )
+ rArray.SetCellStyleLeft( nCol + 1, nRow, svx::frame::Style() );
+ }
+
+ // remove diagonal borders
+ rArray.SetCellStyleTLBR( nCol, nRow, svx::frame::Style() );
+ rArray.SetCellStyleBLTR( nCol, nRow, svx::frame::Style() );
+ }
+ }
+ }
+ nPosY += nRowHeight;
+ }
+
+ if (bMetaFile)
+ pDev->Pop();
+ else
+ pDev->SetClipRegion();
+}
+
+// Drucker
+
+PolyPolygon ScOutputData::GetChangedArea()
+{
+ PolyPolygon aPoly;
+
+ Rectangle aDrawingRect;
+ aDrawingRect.Left() = nScrX;
+ aDrawingRect.Right() = nScrX+nScrW-1;
+
+ sal_Bool bHad = sal_False;
+ long nPosY = nScrY;
+ SCSIZE nArrY;
+ for (nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+
+ if ( pThisRowInfo->bChanged )
+ {
+ if (!bHad)
+ {
+ aDrawingRect.Top() = nPosY;
+ bHad = sal_True;
+ }
+ aDrawingRect.Bottom() = nPosY + pRowInfo[nArrY].nHeight - 1;
+ }
+ else if (bHad)
+ {
+ aPoly.Insert( Polygon( pDev->PixelToLogic(aDrawingRect) ) );
+ bHad = sal_False;
+ }
+ nPosY += pRowInfo[nArrY].nHeight;
+ }
+
+ if (bHad)
+ aPoly.Insert( Polygon( pDev->PixelToLogic(aDrawingRect) ) );
+
+ return aPoly;
+}
+
+sal_Bool ScOutputData::SetChangedClip()
+{
+ PolyPolygon aPoly;
+
+ Rectangle aDrawingRect;
+ aDrawingRect.Left() = nScrX;
+ aDrawingRect.Right() = nScrX+nScrW-1;
+
+ sal_Bool bHad = sal_False;
+ long nPosY = nScrY;
+ SCSIZE nArrY;
+ for (nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+
+ if ( pThisRowInfo->bChanged )
+ {
+ if (!bHad)
+ {
+ aDrawingRect.Top() = nPosY;
+ bHad = sal_True;
+ }
+ aDrawingRect.Bottom() = nPosY + pRowInfo[nArrY].nHeight - 1;
+ }
+ else if (bHad)
+ {
+ aPoly.Insert( Polygon( pDev->PixelToLogic(aDrawingRect) ) );
+ bHad = sal_False;
+ }
+ nPosY += pRowInfo[nArrY].nHeight;
+ }
+
+ if (bHad)
+ aPoly.Insert( Polygon( pDev->PixelToLogic(aDrawingRect) ) );
+
+ sal_Bool bRet = (aPoly.Count() != 0);
+ if (bRet)
+ pDev->SetClipRegion(Region(aPoly));
+ return bRet;
+}
+
+void ScOutputData::FindChanged()
+{
+ SCCOL nX;
+ SCSIZE nArrY;
+
+ sal_Bool bWasIdleDisabled = pDoc->IsIdleDisabled();
+ pDoc->DisableIdle( sal_True );
+ for (nArrY=0; nArrY<nArrCount; nArrY++)
+ pRowInfo[nArrY].bChanged = sal_False;
+
+ sal_Bool bProgress = sal_False;
+ for (nArrY=0; nArrY<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ for (nX=nX1; nX<=nX2; nX++)
+ {
+ ScBaseCell* pCell = pThisRowInfo->pCellInfo[nX+1].pCell;
+ if (pCell)
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ if ( !bProgress && pFCell->GetDirty() )
+ {
+ ScProgress::CreateInterpretProgress( pDoc, sal_True );
+ bProgress = sal_True;
+ }
+ if (!pFCell->IsRunning())
+ {
+ (void)pFCell->GetValue();
+ if (pFCell->IsChanged())
+ {
+ pThisRowInfo->bChanged = sal_True;
+ if ( pThisRowInfo->pCellInfo[nX+1].bMerged )
+ {
+ SCSIZE nOverY = nArrY + 1;
+ while ( nOverY<nArrCount &&
+ pRowInfo[nOverY].pCellInfo[nX+1].bVOverlapped )
+ {
+ pRowInfo[nOverY].bChanged = sal_True;
+ ++nOverY;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if ( bProgress )
+ ScProgress::DeleteInterpretProgress();
+ pDoc->DisableIdle( bWasIdleDisabled );
+}
+
+#ifdef OLD_SELECTION_PAINT
+void ScOutputData::DrawMark( Window* pWin )
+{
+ Rectangle aRect;
+ ScInvertMerger aInvert( pWin );
+ //! additional method AddLineRect for ScInvertMerger?
+
+ long nPosY = nScrY;
+ for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ if (pThisRowInfo->bChanged)
+ {
+ long nPosX = nScrX;
+ if (bLayoutRTL)
+ nPosX += nMirrorW - 1; // always in pixels
+
+ aRect = Rectangle( Point( nPosX,nPosY ), Size(1, pThisRowInfo->nHeight) );
+ if (bLayoutRTL)
+ aRect.Left() = aRect.Right() + 1;
+ else
+ aRect.Right() = aRect.Left() - 1;
+
+ sal_Bool bOldMarked = sal_False;
+ for (SCCOL nX=nX1; nX<=nX2; nX++)
+ {
+ if (pThisRowInfo->pCellInfo[nX+1].bMarked != bOldMarked)
+ {
+ if (bOldMarked && aRect.Right() >= aRect.Left())
+ aInvert.AddRect( aRect );
+
+ if (bLayoutRTL)
+ aRect.Right() = nPosX;
+ else
+ aRect.Left() = nPosX;
+
+ bOldMarked = pThisRowInfo->pCellInfo[nX+1].bMarked;
+ }
+
+ if (bLayoutRTL)
+ {
+ nPosX -= pRowInfo[0].pCellInfo[nX+1].nWidth;
+ aRect.Left() = nPosX+1;
+ }
+ else
+ {
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth;
+ aRect.Right() = nPosX-1;
+ }
+ }
+ if (bOldMarked && aRect.Right() >= aRect.Left())
+ aInvert.AddRect( aRect );
+ }
+ nPosY += pThisRowInfo->nHeight;
+ }
+}
+#endif
+
+void ScOutputData::DrawRefMark( SCCOL nRefStartX, SCROW nRefStartY,
+ SCCOL nRefEndX, SCROW nRefEndY,
+ const Color& rColor, sal_Bool bHandle )
+{
+ PutInOrder( nRefStartX, nRefEndX );
+ PutInOrder( nRefStartY, nRefEndY );
+
+ if ( nRefStartX == nRefEndX && nRefStartY == nRefEndY )
+ pDoc->ExtendMerge( nRefStartX, nRefStartY, nRefEndX, nRefEndY, nTab );
+
+ if ( nRefStartX <= nVisX2 && nRefEndX >= nVisX1 &&
+ nRefStartY <= nVisY2 && nRefEndY >= nVisY1 )
+ {
+ long nMinX = nScrX;
+ long nMinY = nScrY;
+ long nMaxX = nScrX+nScrW-1;
+ long nMaxY = nScrY+nScrH-1;
+ if ( bLayoutRTL )
+ {
+ long nTemp = nMinX;
+ nMinX = nMaxX;
+ nMaxX = nTemp;
+ }
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ sal_Bool bTop = sal_False;
+ sal_Bool bBottom = sal_False;
+ sal_Bool bLeft = sal_False;
+ sal_Bool bRight = sal_False;
+
+ long nPosY = nScrY;
+ sal_Bool bNoStartY = ( nY1 < nRefStartY );
+ sal_Bool bNoEndY = sal_False;
+ for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++) // loop to end for bNoEndY check
+ {
+ SCROW nY = pRowInfo[nArrY].nRowNo;
+
+ if ( nY==nRefStartY || (nY>nRefStartY && bNoStartY) )
+ {
+ nMinY = nPosY;
+ bTop = sal_True;
+ }
+ if ( nY==nRefEndY )
+ {
+ nMaxY = nPosY + pRowInfo[nArrY].nHeight - 2;
+ bBottom = sal_True;
+ }
+ if ( nY>nRefEndY && bNoEndY )
+ {
+ nMaxY = nPosY-2;
+ bBottom = sal_True;
+ }
+ bNoStartY = ( nY < nRefStartY );
+ bNoEndY = ( nY < nRefEndY );
+ nPosY += pRowInfo[nArrY].nHeight;
+ }
+
+ long nPosX = nScrX;
+ if ( bLayoutRTL )
+ nPosX += nMirrorW - 1; // always in pixels
+
+ for (SCCOL nX=nX1; nX<=nX2; nX++)
+ {
+ if ( nX==nRefStartX )
+ {
+ nMinX = nPosX;
+ bLeft = sal_True;
+ }
+ if ( nX==nRefEndX )
+ {
+ nMaxX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 2 ) * nLayoutSign;
+ bRight = sal_True;
+ }
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+ }
+
+ if ( nMaxX * nLayoutSign >= nMinX * nLayoutSign &&
+ nMaxY >= nMinY )
+ {
+ pDev->SetLineColor( rColor );
+ if (bTop && bBottom && bLeft && bRight)
+ {
+ pDev->SetFillColor();
+ pDev->DrawRect( Rectangle( nMinX, nMinY, nMaxX, nMaxY ) );
+ }
+ else
+ {
+ if (bTop)
+ pDev->DrawLine( Point( nMinX,nMinY ), Point( nMaxX,nMinY ) );
+ if (bBottom)
+ pDev->DrawLine( Point( nMinX,nMaxY ), Point( nMaxX,nMaxY ) );
+ if (bLeft)
+ pDev->DrawLine( Point( nMinX,nMinY ), Point( nMinX,nMaxY ) );
+ if (bRight)
+ pDev->DrawLine( Point( nMaxX,nMinY ), Point( nMaxX,nMaxY ) );
+ }
+ if ( bHandle && bRight && bBottom )
+ {
+ pDev->SetLineColor();
+ pDev->SetFillColor( rColor );
+ pDev->DrawRect( Rectangle( nMaxX-3*nLayoutSign, nMaxY-3, nMaxX+nLayoutSign, nMaxY+1 ) );
+ }
+ }
+ }
+}
+
+void ScOutputData::DrawOneChange( SCCOL nRefStartX, SCROW nRefStartY,
+ SCCOL nRefEndX, SCROW nRefEndY,
+ const Color& rColor, sal_uInt16 nType )
+{
+ PutInOrder( nRefStartX, nRefEndX );
+ PutInOrder( nRefStartY, nRefEndY );
+
+ if ( nRefStartX == nRefEndX && nRefStartY == nRefEndY )
+ pDoc->ExtendMerge( nRefStartX, nRefStartY, nRefEndX, nRefEndY, nTab );
+
+ if ( nRefStartX <= nVisX2 + 1 && nRefEndX >= nVisX1 &&
+ nRefStartY <= nVisY2 + 1 && nRefEndY >= nVisY1 ) // +1 because it touches next cells left/top
+ {
+ long nMinX = nScrX;
+ long nMinY = nScrY;
+ long nMaxX = nScrX+nScrW-1;
+ long nMaxY = nScrY+nScrH-1;
+ if ( bLayoutRTL )
+ {
+ long nTemp = nMinX;
+ nMinX = nMaxX;
+ nMaxX = nTemp;
+ }
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ sal_Bool bTop = sal_False;
+ sal_Bool bBottom = sal_False;
+ sal_Bool bLeft = sal_False;
+ sal_Bool bRight = sal_False;
+
+ long nPosY = nScrY;
+ sal_Bool bNoStartY = ( nY1 < nRefStartY );
+ sal_Bool bNoEndY = sal_False;
+ for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++) // loop to end for bNoEndY check
+ {
+ SCROW nY = pRowInfo[nArrY].nRowNo;
+
+ if ( nY==nRefStartY || (nY>nRefStartY && bNoStartY) )
+ {
+ nMinY = nPosY - 1;
+ bTop = sal_True;
+ }
+ if ( nY==nRefEndY )
+ {
+ nMaxY = nPosY + pRowInfo[nArrY].nHeight - 1;
+ bBottom = sal_True;
+ }
+ if ( nY>nRefEndY && bNoEndY )
+ {
+ nMaxY = nPosY - 1;
+ bBottom = sal_True;
+ }
+ bNoStartY = ( nY < nRefStartY );
+ bNoEndY = ( nY < nRefEndY );
+ nPosY += pRowInfo[nArrY].nHeight;
+ }
+
+ long nPosX = nScrX;
+ if ( bLayoutRTL )
+ nPosX += nMirrorW - 1; // always in pixels
+
+ for (SCCOL nX=nX1; nX<=nX2+1; nX++)
+ {
+ if ( nX==nRefStartX )
+ {
+ nMinX = nPosX - nLayoutSign;
+ bLeft = sal_True;
+ }
+ if ( nX==nRefEndX )
+ {
+ nMaxX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 1 ) * nLayoutSign;
+ bRight = sal_True;
+ }
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+ }
+
+ if ( nMaxX * nLayoutSign >= nMinX * nLayoutSign &&
+ nMaxY >= nMinY )
+ {
+ if ( nType == SC_CAT_DELETE_ROWS )
+ bLeft = bRight = bBottom = sal_False; //! dicke Linie ???
+ else if ( nType == SC_CAT_DELETE_COLS )
+ bTop = bBottom = bRight = sal_False; //! dicke Linie ???
+
+ pDev->SetLineColor( rColor );
+ if (bTop && bBottom && bLeft && bRight)
+ {
+ pDev->SetFillColor();
+ pDev->DrawRect( Rectangle( nMinX, nMinY, nMaxX, nMaxY ) );
+ }
+ else
+ {
+ if (bTop)
+ {
+ pDev->DrawLine( Point( nMinX,nMinY ), Point( nMaxX,nMinY ) );
+ if ( nType == SC_CAT_DELETE_ROWS )
+ pDev->DrawLine( Point( nMinX,nMinY+1 ), Point( nMaxX,nMinY+1 ) );
+ }
+ if (bBottom)
+ pDev->DrawLine( Point( nMinX,nMaxY ), Point( nMaxX,nMaxY ) );
+ if (bLeft)
+ {
+ pDev->DrawLine( Point( nMinX,nMinY ), Point( nMinX,nMaxY ) );
+ if ( nType == SC_CAT_DELETE_COLS )
+ pDev->DrawLine( Point( nMinX+nLayoutSign,nMinY ), Point( nMinX+nLayoutSign,nMaxY ) );
+ }
+ if (bRight)
+ pDev->DrawLine( Point( nMaxX,nMinY ), Point( nMaxX,nMaxY ) );
+ }
+ if ( bLeft && bTop )
+ {
+ pDev->SetLineColor();
+ pDev->SetFillColor( rColor );
+ pDev->DrawRect( Rectangle( nMinX+nLayoutSign, nMinY+1, nMinX+3*nLayoutSign, nMinY+3 ) );
+ }
+ }
+ }
+}
+
+void ScOutputData::DrawChangeTrack()
+{
+ ScChangeTrack* pTrack = pDoc->GetChangeTrack();
+ ScChangeViewSettings* pSettings = pDoc->GetChangeViewSettings();
+ if ( !pTrack || !pTrack->GetFirst() || !pSettings || !pSettings->ShowChanges() )
+ return; // nix da oder abgeschaltet
+
+ ScActionColorChanger aColorChanger(*pTrack);
+
+ // Clipping passiert von aussen
+ //! ohne Clipping, nur betroffene Zeilen painten ??!??!?
+
+ SCCOL nEndX = nX2;
+ SCROW nEndY = nY2;
+ if ( nEndX < MAXCOL ) ++nEndX; // auch noch von der naechsten Zelle, weil die Markierung
+ if ( nEndY < MAXROW ) ++nEndY; // in die jeweils vorhergehende Zelle hineinragt
+ ScRange aViewRange( nX1, nY1, nTab, nEndX, nEndY, nTab );
+ const ScChangeAction* pAction = pTrack->GetFirst();
+ while (pAction)
+ {
+ ScChangeActionType eActionType;
+ if ( pAction->IsVisible() )
+ {
+ eActionType = pAction->GetType();
+ const ScBigRange& rBig = pAction->GetBigRange();
+ if ( rBig.aStart.Tab() == nTab )
+ {
+ ScRange aRange = rBig.MakeRange();
+
+ if ( eActionType == SC_CAT_DELETE_ROWS )
+ aRange.aEnd.SetRow( aRange.aStart.Row() );
+ else if ( eActionType == SC_CAT_DELETE_COLS )
+ aRange.aEnd.SetCol( aRange.aStart.Col() );
+
+ if ( aRange.Intersects( aViewRange ) &&
+ ScViewUtil::IsActionShown( *pAction, *pSettings, *pDoc ) )
+ {
+ aColorChanger.Update( *pAction );
+ Color aColor( aColorChanger.GetColor() );
+ DrawOneChange( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(), aColor, sal::static_int_cast<sal_uInt16>(eActionType) );
+
+ }
+ }
+ if ( eActionType == SC_CAT_MOVE &&
+ ((const ScChangeActionMove*)pAction)->
+ GetFromRange().aStart.Tab() == nTab )
+ {
+ ScRange aRange = ((const ScChangeActionMove*)pAction)->
+ GetFromRange().MakeRange();
+ if ( aRange.Intersects( aViewRange ) &&
+ ScViewUtil::IsActionShown( *pAction, *pSettings, *pDoc ) )
+ {
+ aColorChanger.Update( *pAction );
+ Color aColor( aColorChanger.GetColor() );
+ DrawOneChange( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(), aColor, sal::static_int_cast<sal_uInt16>(eActionType) );
+ }
+ }
+ }
+
+ pAction = pAction->GetNext();
+ }
+}
+
+void ScOutputData::DrawNoteMarks()
+{
+ sal_Bool bFirst = sal_True;
+
+ long nInitPosX = nScrX;
+ if ( bLayoutRTL )
+ nInitPosX += nMirrorW - 1; // always in pixels
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ long nPosY = nScrY;
+ for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ if ( pThisRowInfo->bChanged )
+ {
+ long nPosX = nInitPosX;
+ for (SCCOL nX=nX1; nX<=nX2; nX++)
+ {
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+ ScBaseCell* pCell = pInfo->pCell;
+ sal_Bool bIsMerged = sal_False;
+
+ if ( nX==nX1 && pInfo->bHOverlapped && !pInfo->bVOverlapped )
+ {
+ // find start of merged cell
+ bIsMerged = sal_True;
+ SCROW nY = pRowInfo[nArrY].nRowNo;
+ SCCOL nMergeX = nX;
+ SCROW nMergeY = nY;
+ pDoc->ExtendOverlapped( nMergeX, nMergeY, nX, nY, nTab );
+ pCell = pDoc->GetCell( ScAddress(nMergeX,nMergeY,nTab) );
+ // use origin's pCell for NotePtr test below
+ }
+
+ if ( pCell && pCell->HasNote() && ( bIsMerged ||
+ ( !pInfo->bHOverlapped && !pInfo->bVOverlapped ) ) )
+ {
+ if (bFirst)
+ {
+ pDev->SetLineColor();
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ if ( bUseStyleColor && rStyleSettings.GetHighContrastMode() )
+ pDev->SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+ else
+ pDev->SetFillColor(COL_LIGHTRED);
+
+ bFirst = sal_False;
+ }
+
+ long nMarkX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 4 ) * nLayoutSign;
+ if ( bIsMerged || pInfo->bMerged )
+ {
+ // if merged, add widths of all cells
+ SCCOL nNextX = nX + 1;
+ while ( nNextX <= nX2 + 1 && pThisRowInfo->pCellInfo[nNextX+1].bHOverlapped )
+ {
+ nMarkX += pRowInfo[0].pCellInfo[nNextX+1].nWidth * nLayoutSign;
+ ++nNextX;
+ }
+ }
+ if ( bLayoutRTL ? ( nMarkX >= 0 ) : ( nMarkX < nScrX+nScrW ) )
+ pDev->DrawRect( Rectangle( nMarkX,nPosY,nMarkX+2*nLayoutSign,nPosY+2 ) );
+ }
+
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+ }
+ }
+ nPosY += pThisRowInfo->nHeight;
+ }
+}
+
+void ScOutputData::AddPDFNotes()
+{
+ vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
+ if ( !pPDFData || !pPDFData->GetIsExportNotes() )
+ return;
+
+ long nInitPosX = nScrX;
+ if ( bLayoutRTL )
+ {
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ nInitPosX += nMirrorW - nOneX;
+ }
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ long nPosY = nScrY;
+ for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ if ( pThisRowInfo->bChanged )
+ {
+ long nPosX = nInitPosX;
+ for (SCCOL nX=nX1; nX<=nX2; nX++)
+ {
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+ ScBaseCell* pCell = pInfo->pCell;
+ sal_Bool bIsMerged = sal_False;
+ SCROW nY = pRowInfo[nArrY].nRowNo;
+ SCCOL nMergeX = nX;
+ SCROW nMergeY = nY;
+
+ if ( nX==nX1 && pInfo->bHOverlapped && !pInfo->bVOverlapped )
+ {
+ // find start of merged cell
+ bIsMerged = sal_True;
+ pDoc->ExtendOverlapped( nMergeX, nMergeY, nX, nY, nTab );
+ pCell = pDoc->GetCell( ScAddress(nMergeX,nMergeY,nTab) );
+ // use origin's pCell for NotePtr test below
+ }
+
+ if ( pCell && pCell->HasNote() && ( bIsMerged ||
+ ( !pInfo->bHOverlapped && !pInfo->bVOverlapped ) ) )
+ {
+ long nNoteWidth = (long)( SC_CLIPMARK_SIZE * nPPTX );
+ long nNoteHeight = (long)( SC_CLIPMARK_SIZE * nPPTY );
+
+ long nMarkX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - nNoteWidth ) * nLayoutSign;
+ if ( bIsMerged || pInfo->bMerged )
+ {
+ // if merged, add widths of all cells
+ SCCOL nNextX = nX + 1;
+ while ( nNextX <= nX2 + 1 && pThisRowInfo->pCellInfo[nNextX+1].bHOverlapped )
+ {
+ nMarkX += pRowInfo[0].pCellInfo[nNextX+1].nWidth * nLayoutSign;
+ ++nNextX;
+ }
+ }
+ if ( bLayoutRTL ? ( nMarkX >= 0 ) : ( nMarkX < nScrX+nScrW ) )
+ {
+ Rectangle aNoteRect( nMarkX, nPosY, nMarkX+nNoteWidth*nLayoutSign, nPosY+nNoteHeight );
+ const ScPostIt* pNote = pCell->GetNote();
+
+ // Note title is the cell address (as on printed note pages)
+ String aTitle;
+ ScAddress aAddress( nMergeX, nMergeY, nTab );
+ aAddress.Format( aTitle, SCA_VALID, pDoc, pDoc->GetAddressConvention() );
+
+ // Content has to be a simple string without line breaks
+ String aContent = pNote->GetText();
+ xub_StrLen nPos;
+ while ( (nPos=aContent.Search('\n')) != STRING_NOTFOUND )
+ aContent.SetChar( nPos, ' ' );
+
+ vcl::PDFNote aNote;
+ aNote.Title = aTitle;
+ aNote.Contents = aContent;
+ pPDFData->CreateNote( aNoteRect, aNote );
+ }
+ }
+
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+ }
+ }
+ nPosY += pThisRowInfo->nHeight;
+ }
+}
+
+void ScOutputData::DrawClipMarks()
+{
+ if (!bAnyClipped)
+ return;
+
+ Color aArrowFillCol( COL_LIGHTRED );
+
+ sal_uLong nOldDrawMode = pDev->GetDrawMode();
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ if ( bUseStyleColor && rStyleSettings.GetHighContrastMode() )
+ {
+ // use DrawMode to change the arrow's outline color
+ pDev->SetDrawMode( nOldDrawMode | DRAWMODE_SETTINGSLINE );
+ // use text color also for the fill color
+ aArrowFillCol.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+ }
+
+ long nInitPosX = nScrX;
+ if ( bLayoutRTL )
+ nInitPosX += nMirrorW - 1; // always in pixels
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ Rectangle aCellRect;
+ long nPosY = nScrY;
+ for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ if ( pThisRowInfo->bChanged )
+ {
+ SCROW nY = pThisRowInfo->nRowNo;
+ long nPosX = nInitPosX;
+ for (SCCOL nX=nX1; nX<=nX2; nX++)
+ {
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+ if (pInfo->nClipMark)
+ {
+ if (pInfo->bHOverlapped || pInfo->bVOverlapped)
+ {
+ // merge origin may be outside of visible area - use document functions
+
+ SCCOL nOverX = nX;
+ SCROW nOverY = nY;
+ long nStartPosX = nPosX;
+ long nStartPosY = nPosY;
+
+ while ( nOverX > 0 && ( ((const ScMergeFlagAttr*)pDoc->GetAttr(
+ nOverX, nOverY, nTab, ATTR_MERGE_FLAG ))->GetValue() & SC_MF_HOR ) )
+ {
+ --nOverX;
+ nStartPosX -= nLayoutSign * (long) ( pDoc->GetColWidth(nOverX,nTab) * nPPTX );
+ }
+
+ while ( nOverY > 0 && ( ((const ScMergeFlagAttr*)pDoc->GetAttr(
+ nOverX, nOverY, nTab, ATTR_MERGE_FLAG ))->GetValue() & SC_MF_VER ) )
+ {
+ --nOverY;
+ nStartPosY -= nLayoutSign * (long) ( pDoc->GetRowHeight(nOverY,nTab) * nPPTY );
+ }
+
+ long nOutWidth = (long) ( pDoc->GetColWidth(nOverX,nTab) * nPPTX );
+ long nOutHeight = (long) ( pDoc->GetRowHeight(nOverY,nTab) * nPPTY );
+
+ const ScMergeAttr* pMerge = (const ScMergeAttr*)
+ pDoc->GetAttr( nOverX, nOverY, nTab, ATTR_MERGE );
+ SCCOL nCountX = pMerge->GetColMerge();
+ for (SCCOL i=1; i<nCountX; i++)
+ nOutWidth += (long) ( pDoc->GetColWidth(nOverX+i,nTab) * nPPTX );
+ SCROW nCountY = pMerge->GetRowMerge();
+ nOutHeight += (long) pDoc->GetScaledRowHeight( nOverY+1, nOverY+nCountY-1, nTab, nPPTY);
+
+ if ( bLayoutRTL )
+ nStartPosX -= nOutWidth - 1;
+ aCellRect = Rectangle( Point( nStartPosX, nStartPosY ), Size( nOutWidth, nOutHeight ) );
+ }
+ else
+ {
+ long nOutWidth = pRowInfo[0].pCellInfo[nX+1].nWidth;
+ long nOutHeight = pThisRowInfo->nHeight;
+
+ if ( pInfo->bMerged && pInfo->pPatternAttr )
+ {
+ SCCOL nOverX = nX;
+ SCROW nOverY = nY;
+ const ScMergeAttr* pMerge =
+ (ScMergeAttr*)&pInfo->pPatternAttr->GetItem(ATTR_MERGE);
+ SCCOL nCountX = pMerge->GetColMerge();
+ for (SCCOL i=1; i<nCountX; i++)
+ nOutWidth += (long) ( pDoc->GetColWidth(nOverX+i,nTab) * nPPTX );
+ SCROW nCountY = pMerge->GetRowMerge();
+ nOutHeight += (long) pDoc->GetScaledRowHeight( nOverY+1, nOverY+nCountY-1, nTab, nPPTY);
+ }
+
+ long nStartPosX = nPosX;
+ if ( bLayoutRTL )
+ nStartPosX -= nOutWidth - 1;
+ // #i80447# create aCellRect from two points in case nOutWidth is 0
+ aCellRect = Rectangle( Point( nStartPosX, nPosY ),
+ Point( nStartPosX+nOutWidth-1, nPosY+nOutHeight-1 ) );
+ }
+
+ aCellRect.Bottom() -= 1; // don't paint over the cell grid
+ if ( bLayoutRTL )
+ aCellRect.Left() += 1;
+ else
+ aCellRect.Right() -= 1;
+
+ long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX );
+ Size aMarkSize( nMarkPixel, (nMarkPixel-1)*2 );
+
+ if ( pInfo->nClipMark & ( bLayoutRTL ? SC_CLIPMARK_RIGHT : SC_CLIPMARK_LEFT ) )
+ {
+ // visually left
+ Rectangle aMarkRect = aCellRect;
+ aMarkRect.Right() = aCellRect.Left()+nMarkPixel-1;
+#if 0
+ //! Test
+ pDev->SetLineColor(); pDev->SetFillColor(COL_YELLOW);
+ pDev->DrawRect(aMarkRect);
+ //! Test
+#endif
+ SvxFont::DrawArrow( *pDev, aMarkRect, aMarkSize, aArrowFillCol, sal_True );
+ }
+ if ( pInfo->nClipMark & ( bLayoutRTL ? SC_CLIPMARK_LEFT : SC_CLIPMARK_RIGHT ) )
+ {
+ // visually right
+ Rectangle aMarkRect = aCellRect;
+ aMarkRect.Left() = aCellRect.Right()-nMarkPixel+1;
+#if 0
+ //! Test
+ pDev->SetLineColor(); pDev->SetFillColor(COL_LIGHTGREEN);
+ pDev->DrawRect(aMarkRect);
+ //! Test
+#endif
+ SvxFont::DrawArrow( *pDev, aMarkRect, aMarkSize, aArrowFillCol, sal_False );
+ }
+ }
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+ }
+ }
+ nPosY += pThisRowInfo->nHeight;
+ }
+
+ pDev->SetDrawMode(nOldDrawMode);
+}
+
+
+
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
new file mode 100644
index 000000000000..b1d6787d3ce6
--- /dev/null
+++ b/sc/source/ui/view/output2.cxx
@@ -0,0 +1,3705 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <editeng/adjitem.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <svtools/colorcfg.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/forbiddencharacterstable.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/langitem.hxx>
+#include <svx/rotmodit.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/unolingu.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/metric.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/pdfextoutdevdata.hxx>
+
+#ifndef _SVSTDARR_USHORTS
+#define _SVSTDARR_USHORTS
+#include <svl/svstdarr.hxx>
+#endif
+
+#include "output.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "cellform.hxx"
+#include "editutil.hxx"
+#include "progress.hxx"
+#include "scmod.hxx"
+#include "fillinfo.hxx"
+
+#include <boost/ptr_container/ptr_vector.hpp>
+
+#include <math.h>
+
+//! Autofilter-Breite mit column.cxx zusammenfassen
+#define DROPDOWN_BITMAP_SIZE 18
+
+#define DRAWTEXT_MAX 32767
+
+const sal_uInt16 SC_SHRINKAGAIN_MAX = 7;
+
+// STATIC DATA -----------------------------------------------------------
+
+
+// -----------------------------------------------------------------------
+
+class ScDrawStringsVars
+{
+ ScOutputData* pOutput; // Verbindung
+
+ const ScPatternAttr* pPattern; // Attribute
+ const SfxItemSet* pCondSet; // aus bedingter Formatierung
+
+ Font aFont; // aus Attributen erzeugt
+ FontMetric aMetric;
+ long nAscentPixel; // always pixels
+ SvxCellOrientation eAttrOrient;
+ SvxCellHorJustify eAttrHorJust;
+ SvxCellVerJustify eAttrVerJust;
+ const SvxMarginItem* pMargin;
+ sal_uInt16 nIndent;
+ sal_Bool bRotated;
+
+ String aString; // Inhalte
+ Size aTextSize;
+ long nOriginalWidth;
+ long nMaxDigitWidth;
+ long nSignWidth;
+ long nDotWidth;
+ long nExpWidth;
+
+ ScBaseCell* pLastCell;
+ sal_uLong nValueFormat;
+ sal_Bool bLineBreak;
+ sal_Bool bRepeat;
+ sal_Bool bShrink;
+
+ sal_Bool bPixelToLogic;
+ sal_Bool bCellContrast;
+
+ Color aBackConfigColor; // used for ScPatternAttr::GetFont calls
+ Color aTextConfigColor;
+
+public:
+ ScDrawStringsVars(ScOutputData* pData, sal_Bool bPTL);
+ ~ScDrawStringsVars();
+
+ // SetPattern = ex-SetVars
+ // SetPatternSimple: ohne Font
+
+ void SetPattern( const ScPatternAttr* pNew, const SfxItemSet* pSet, ScBaseCell* pCell, sal_uInt8 nScript );
+ void SetPatternSimple( const ScPatternAttr* pNew, const SfxItemSet* pSet );
+
+ sal_Bool SetText( ScBaseCell* pCell ); // sal_True -> pOldPattern vergessen
+ void SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth );
+ void SetAutoText( const String& rAutoText );
+
+ const ScPatternAttr* GetPattern() const { return pPattern; }
+ SvxCellOrientation GetOrient() const { return eAttrOrient; }
+ SvxCellHorJustify GetHorJust() const { return eAttrHorJust; }
+ SvxCellVerJustify GetVerJust() const { return eAttrVerJust; }
+ const SvxMarginItem* GetMargin() const { return pMargin; }
+
+ sal_uInt16 GetLeftTotal() const { return pMargin->GetLeftMargin() + nIndent; }
+
+ const String& GetString() const { return aString; }
+ const Size& GetTextSize() const { return aTextSize; }
+ long GetOriginalWidth() const { return nOriginalWidth; }
+
+ sal_uLong GetValueFormat() const { return nValueFormat; }
+ sal_Bool GetLineBreak() const { return bLineBreak; }
+ sal_Bool IsRepeat() const { return bRepeat; }
+ sal_Bool IsShrink() const { return bShrink; }
+
+ long GetAscent() const { return nAscentPixel; }
+ sal_Bool IsRotated() const { return bRotated; }
+
+ void SetShrinkScale( long nScale, sal_uInt8 nScript );
+
+ sal_Bool HasCondHeight() const { return pCondSet && SFX_ITEM_SET ==
+ pCondSet->GetItemState( ATTR_FONT_HEIGHT, sal_True ); }
+
+ sal_Bool HasEditCharacters() const;
+
+private:
+ void SetHashText();
+ long GetMaxDigitWidth(); // in logic units
+ long GetSignWidth();
+ long GetDotWidth();
+ long GetExpWidth();
+ void TextChanged();
+};
+
+//==================================================================
+
+ScDrawStringsVars::ScDrawStringsVars(ScOutputData* pData, sal_Bool bPTL) :
+ pOutput ( pData ),
+ pPattern ( NULL ),
+ pCondSet ( NULL ),
+ eAttrOrient ( SVX_ORIENTATION_STANDARD ),
+ eAttrHorJust( SVX_HOR_JUSTIFY_STANDARD ),
+ eAttrVerJust( SVX_VER_JUSTIFY_BOTTOM ),
+ pMargin ( NULL ),
+ nIndent ( 0 ),
+ bRotated ( sal_False ),
+ nOriginalWidth( 0 ),
+ nMaxDigitWidth( 0 ),
+ nSignWidth( 0 ),
+ nDotWidth( 0 ),
+ nExpWidth( 0 ),
+ pLastCell ( NULL ),
+ nValueFormat( 0 ),
+ bLineBreak ( sal_False ),
+ bRepeat ( sal_False ),
+ bShrink ( sal_False ),
+ bPixelToLogic( bPTL )
+{
+ ScModule* pScMod = SC_MOD();
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
+ bCellContrast = pOutput->bUseStyleColor &&
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode();
+
+ const svtools::ColorConfig& rColorConfig = pScMod->GetColorConfig();
+ aBackConfigColor.SetColor( rColorConfig.GetColorValue(svtools::DOCCOLOR).nColor );
+ aTextConfigColor.SetColor( rColorConfig.GetColorValue(svtools::FONTCOLOR).nColor );
+}
+
+ScDrawStringsVars::~ScDrawStringsVars()
+{
+}
+
+void ScDrawStringsVars::SetShrinkScale( long nScale, sal_uInt8 nScript )
+{
+ // text remains valid, size is updated
+
+ OutputDevice* pDev = pOutput->pDev;
+ OutputDevice* pRefDevice = pOutput->pRefDevice;
+ OutputDevice* pFmtDevice = pOutput->pFmtDevice;
+
+ // call GetFont with a modified fraction, use only the height
+
+ Fraction aFraction( nScale, 100 );
+ if ( !bPixelToLogic )
+ aFraction *= pOutput->aZoomY;
+ Font aTmpFont;
+ pPattern->GetFont( aTmpFont, SC_AUTOCOL_RAW, pFmtDevice, &aFraction, pCondSet, nScript );
+ long nNewHeight = aTmpFont.GetHeight();
+ if ( nNewHeight > 0 )
+ aFont.SetHeight( nNewHeight );
+
+ // set font and dependent variables as in SetPattern
+
+ pDev->SetFont( aFont );
+ if ( pFmtDevice != pDev )
+ pFmtDevice->SetFont( aFont );
+
+ aMetric = pFmtDevice->GetFontMetric();
+ if ( pFmtDevice->GetOutDevType() == OUTDEV_PRINTER && aMetric.GetIntLeading() == 0 )
+ {
+ OutputDevice* pDefaultDev = Application::GetDefaultDevice();
+ MapMode aOld = pDefaultDev->GetMapMode();
+ pDefaultDev->SetMapMode( pFmtDevice->GetMapMode() );
+ aMetric = pDefaultDev->GetFontMetric( aFont );
+ pDefaultDev->SetMapMode( aOld );
+ }
+
+ nAscentPixel = aMetric.GetAscent();
+ if ( bPixelToLogic )
+ nAscentPixel = pRefDevice->LogicToPixel( Size( 0, nAscentPixel ) ).Height();
+
+ SetAutoText( aString ); // same text again, to get text size
+}
+
+void ScDrawStringsVars::SetPattern( const ScPatternAttr* pNew, const SfxItemSet* pSet,
+ ScBaseCell* pCell, sal_uInt8 nScript )
+{
+ nMaxDigitWidth = 0;
+ nSignWidth = 0;
+ nDotWidth = 0;
+ nExpWidth = 0;
+
+ pPattern = pNew;
+ pCondSet = pSet;
+
+ // pPattern auswerten
+
+ OutputDevice* pDev = pOutput->pDev;
+ OutputDevice* pRefDevice = pOutput->pRefDevice;
+ OutputDevice* pFmtDevice = pOutput->pFmtDevice;
+
+ // Font
+
+ ScAutoFontColorMode eColorMode;
+ if ( pOutput->bUseStyleColor )
+ {
+ if ( pOutput->bForceAutoColor )
+ eColorMode = bCellContrast ? SC_AUTOCOL_IGNOREALL : SC_AUTOCOL_IGNOREFONT;
+ else
+ eColorMode = bCellContrast ? SC_AUTOCOL_IGNOREBACK : SC_AUTOCOL_DISPLAY;
+ }
+ else
+ eColorMode = SC_AUTOCOL_PRINT;
+
+ if ( bPixelToLogic )
+ pPattern->GetFont( aFont, eColorMode, pFmtDevice, NULL, pCondSet, nScript,
+ &aBackConfigColor, &aTextConfigColor );
+ else
+ pPattern->GetFont( aFont, eColorMode, pFmtDevice, &pOutput->aZoomY, pCondSet, nScript,
+ &aBackConfigColor, &aTextConfigColor );
+ aFont.SetAlign(ALIGN_BASELINE);
+
+ // Orientierung
+
+ eAttrOrient = pPattern->GetCellOrientation( pCondSet );
+
+ // alignment
+
+ eAttrHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->GetItem( ATTR_HOR_JUSTIFY, pCondSet )).GetValue();
+
+ eAttrVerJust = (SvxCellVerJustify)((const SvxVerJustifyItem&)pPattern->GetItem( ATTR_VER_JUSTIFY, pCondSet )).GetValue();
+ if ( eAttrVerJust == SVX_VER_JUSTIFY_STANDARD )
+ eAttrVerJust = SVX_VER_JUSTIFY_BOTTOM;
+
+ // line break
+
+ bLineBreak = ((const SfxBoolItem&)pPattern->GetItem( ATTR_LINEBREAK, pCondSet )).GetValue();
+
+ // handle "repeat" alignment
+
+ bRepeat = ( eAttrHorJust == SVX_HOR_JUSTIFY_REPEAT );
+ if ( bRepeat )
+ {
+ // "repeat" disables rotation (before constructing the font)
+ eAttrOrient = SVX_ORIENTATION_STANDARD;
+
+ // #i31843# "repeat" with "line breaks" is treated as default alignment (but rotation is still disabled)
+ if ( bLineBreak )
+ eAttrHorJust = SVX_HOR_JUSTIFY_STANDARD;
+ }
+
+ short nRot;
+ switch (eAttrOrient)
+ {
+ case SVX_ORIENTATION_STANDARD:
+ nRot = 0;
+ bRotated = (((const SfxInt32Item&)pPattern->GetItem( ATTR_ROTATE_VALUE, pCondSet )).GetValue() != 0) &&
+ !bRepeat;
+ break;
+ case SVX_ORIENTATION_STACKED:
+ nRot = 0;
+ bRotated = sal_False;
+ break;
+ case SVX_ORIENTATION_TOPBOTTOM:
+ nRot = 2700;
+ bRotated = sal_False;
+ break;
+ case SVX_ORIENTATION_BOTTOMTOP:
+ nRot = 900;
+ bRotated = sal_False;
+ break;
+ default:
+ DBG_ERROR("Falscher SvxCellOrientation Wert");
+ nRot = 0;
+ bRotated = sal_False;
+ break;
+ }
+ aFont.SetOrientation( nRot );
+
+ // Syntax-Modus
+
+ if (pOutput->bSyntaxMode)
+ pOutput->SetSyntaxColor( &aFont, pCell );
+
+ pDev->SetFont( aFont );
+ if ( pFmtDevice != pDev )
+ pFmtDevice->SetFont( aFont );
+
+ aMetric = pFmtDevice->GetFontMetric();
+
+ //
+ // Wenn auf dem Drucker das Leading 0 ist, gibt es Probleme
+ // -> Metric vom Bildschirm nehmen (wie EditEngine!)
+ //
+
+ if ( pFmtDevice->GetOutDevType() == OUTDEV_PRINTER && aMetric.GetIntLeading() == 0 )
+ {
+ OutputDevice* pDefaultDev = Application::GetDefaultDevice();
+ MapMode aOld = pDefaultDev->GetMapMode();
+ pDefaultDev->SetMapMode( pFmtDevice->GetMapMode() );
+ aMetric = pDefaultDev->GetFontMetric( aFont );
+ pDefaultDev->SetMapMode( aOld );
+ }
+
+ nAscentPixel = aMetric.GetAscent();
+ if ( bPixelToLogic )
+ nAscentPixel = pRefDevice->LogicToPixel( Size( 0, nAscentPixel ) ).Height();
+
+ Color aULineColor( ((const SvxUnderlineItem&)pPattern->GetItem( ATTR_FONT_UNDERLINE, pCondSet )).GetColor() );
+ pDev->SetTextLineColor( aULineColor );
+
+ Color aOLineColor( ((const SvxOverlineItem&)pPattern->GetItem( ATTR_FONT_OVERLINE, pCondSet )).GetColor() );
+ pDev->SetOverlineColor( aOLineColor );
+
+ // Zahlenformat
+
+// sal_uLong nOld = nValueFormat;
+ nValueFormat = pPattern->GetNumberFormat( pOutput->pDoc->GetFormatTable(), pCondSet );
+
+/* s.u.
+ if (nValueFormat != nOld)
+ pLastCell = NULL; // immer neu formatieren
+*/
+ // Raender
+
+ pMargin = (const SvxMarginItem*)&pPattern->GetItem( ATTR_MARGIN, pCondSet );
+ if ( eAttrHorJust == SVX_HOR_JUSTIFY_LEFT )
+ nIndent = ((const SfxUInt16Item&)pPattern->GetItem( ATTR_INDENT, pCondSet )).GetValue();
+ else
+ nIndent = 0;
+
+ // "Shrink to fit"
+
+ bShrink = static_cast<const SfxBoolItem&>(pPattern->GetItem( ATTR_SHRINKTOFIT, pCondSet )).GetValue();
+
+ // zumindest die Text-Groesse muss neu geholt werden
+ //! unterscheiden, und den Text nicht neu vom Numberformatter holen?
+
+ pLastCell = NULL;
+}
+
+void ScDrawStringsVars::SetPatternSimple( const ScPatternAttr* pNew, const SfxItemSet* pSet )
+{
+ nMaxDigitWidth = 0;
+ nSignWidth = 0;
+ nDotWidth = 0;
+ nExpWidth = 0;
+ // wird gerufen, wenn sich die Font-Variablen nicht aendern (!StringDiffer)
+
+ pPattern = pNew;
+ pCondSet = pSet; //! noetig ???
+
+ // Zahlenformat
+
+ sal_uLong nOld = nValueFormat;
+// nValueFormat = pPattern->GetNumberFormat( pFormatter );
+ const SfxPoolItem* pFormItem;
+ if ( !pCondSet || pCondSet->GetItemState(ATTR_VALUE_FORMAT,sal_True,&pFormItem) != SFX_ITEM_SET )
+ pFormItem = &pPattern->GetItem(ATTR_VALUE_FORMAT);
+ const SfxPoolItem* pLangItem;
+ if ( !pCondSet || pCondSet->GetItemState(ATTR_LANGUAGE_FORMAT,sal_True,&pLangItem) != SFX_ITEM_SET )
+ pLangItem = &pPattern->GetItem(ATTR_LANGUAGE_FORMAT);
+ nValueFormat = pOutput->pDoc->GetFormatTable()->GetFormatForLanguageIfBuiltIn(
+ ((SfxUInt32Item*)pFormItem)->GetValue(),
+ ((SvxLanguageItem*)pLangItem)->GetLanguage() );
+
+ if (nValueFormat != nOld)
+ pLastCell = NULL; // immer neu formatieren
+
+ // Raender
+
+ pMargin = (const SvxMarginItem*)&pPattern->GetItem( ATTR_MARGIN, pCondSet );
+
+ if ( eAttrHorJust == SVX_HOR_JUSTIFY_LEFT )
+ nIndent = ((const SfxUInt16Item&)pPattern->GetItem( ATTR_INDENT, pCondSet )).GetValue();
+ else
+ nIndent = 0;
+
+ // "Shrink to fit"
+
+ bShrink = static_cast<const SfxBoolItem&>(pPattern->GetItem( ATTR_SHRINKTOFIT, pCondSet )).GetValue();
+}
+
+inline sal_Bool SameValue( ScBaseCell* pCell, ScBaseCell* pOldCell ) // pCell ist != 0
+{
+ return pOldCell && pOldCell->GetCellType() == CELLTYPE_VALUE &&
+ pCell->GetCellType() == CELLTYPE_VALUE &&
+ ((ScValueCell*)pCell)->GetValue() == ((ScValueCell*)pOldCell)->GetValue();
+}
+
+sal_Bool ScDrawStringsVars::SetText( ScBaseCell* pCell )
+{
+ sal_Bool bChanged = sal_False;
+
+ if (pCell)
+ {
+ if ( !SameValue( pCell, pLastCell ) )
+ {
+ pLastCell = pCell; // Zelle merken
+
+ Color* pColor;
+ sal_uLong nFormat = GetValueFormat();
+ ScCellFormat::GetString( pCell,
+ nFormat, aString, &pColor,
+ *pOutput->pDoc->GetFormatTable(),
+ pOutput->bShowNullValues,
+ pOutput->bShowFormulas,
+ ftCheck );
+
+ if (aString.Len() > DRAWTEXT_MAX)
+ aString.Erase(DRAWTEXT_MAX);
+
+ if ( pColor && !pOutput->bSyntaxMode && !( pOutput->bUseStyleColor && pOutput->bForceAutoColor ) )
+ {
+ OutputDevice* pDev = pOutput->pDev;
+ aFont.SetColor(*pColor);
+ pDev->SetFont( aFont ); // nur fuer Ausgabe
+ bChanged = sal_True;
+ pLastCell = NULL; // naechstes Mal wieder hierherkommen
+ }
+
+ TextChanged();
+ }
+ // sonst String/Groesse behalten
+ }
+ else
+ {
+ aString.Erase();
+ pLastCell = NULL;
+ aTextSize = Size(0,0);
+ nOriginalWidth = 0;
+ }
+
+ return bChanged;
+}
+
+void ScDrawStringsVars::SetHashText()
+{
+ SetAutoText( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("###")) );
+}
+
+void ScDrawStringsVars::SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth )
+{
+ // #i113045# do the single-character width calculations in logic units
+ if (bPixelToLogic)
+ nWidth = pOutput->pRefDevice->PixelToLogic(Size(nWidth,0)).Width();
+
+ if (!pCell)
+ return;
+
+ CellType eType = pCell->GetCellType();
+ if (eType != CELLTYPE_VALUE && eType != CELLTYPE_FORMULA)
+ // must be a value or formula cell.
+ return;
+
+ if (eType == CELLTYPE_FORMULA)
+ {
+ ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
+ if (pFCell->GetErrCode() != 0)
+ {
+ SetHashText(); // If the error string doesn't fit, always use "###"
+ return;
+ }
+ // If it's formula, the result must be a value.
+ if (!pFCell->IsValue())
+ return;
+ }
+
+ sal_uLong nFormat = GetValueFormat();
+ if ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) != 0)
+ {
+ // Not 'General' number format. Set hash text and bail out.
+ SetHashText();
+ return;
+ }
+
+ double fVal = (eType == CELLTYPE_VALUE) ?
+ static_cast<ScValueCell*>(pCell)->GetValue() : static_cast<ScFormulaCell*>(pCell)->GetValue();
+
+ const SvNumberformat* pNumFormat = pOutput->pDoc->GetFormatTable()->GetEntry(nFormat);
+ if (!pNumFormat)
+ return;
+
+ long nMaxDigit = GetMaxDigitWidth();
+ sal_uInt16 nNumDigits = static_cast<sal_uInt16>(nWidth / nMaxDigit);
+
+ if (!pNumFormat->GetOutputString(fVal, nNumDigits, aString))
+ // Failed to get output string. Bail out.
+ return;
+
+ 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)
+ {
+ sal_Unicode c = aString.GetChar(i);
+ if (c == sal_Unicode('-'))
+ ++nSignCount;
+ else if (c == cDecSep)
+ ++nDecimalCount;
+ else if (c == sal_Unicode('E'))
+ ++nExpCount;
+ }
+
+ // #i112250# A small value might be formatted as "0" when only counting the digits,
+ // but fit into the column when considering the smaller width of the decimal separator.
+ if (aString.EqualsAscii("0") && fVal != 0.0)
+ nDecimalCount = 1;
+
+ if (nDecimalCount)
+ nWidth += (nMaxDigit - GetDotWidth()) * nDecimalCount;
+ if (nSignCount)
+ nWidth += (nMaxDigit - GetSignWidth()) * nSignCount;
+ if (nExpCount)
+ nWidth += (nMaxDigit - GetExpWidth()) * nExpCount;
+
+ if (nDecimalCount || nSignCount || nExpCount)
+ {
+ // Re-calculate.
+ nNumDigits = static_cast<sal_uInt16>(nWidth / nMaxDigit);
+ if (!pNumFormat->GetOutputString(fVal, nNumDigits, aString))
+ // Failed to get output string. Bail out.
+ return;
+ }
+
+ long nActualTextWidth = pOutput->pFmtDevice->GetTextWidth(aString);
+ if (nActualTextWidth > nWidth)
+ {
+ // Even after the decimal adjustment the text doesn't fit. Give up.
+ SetHashText();
+ return;
+ }
+
+ TextChanged();
+ pLastCell = NULL; // #i113022# equal cell and format in another column may give different string
+}
+
+void ScDrawStringsVars::SetAutoText( const String& rAutoText )
+{
+ aString = rAutoText;
+
+ OutputDevice* pRefDevice = pOutput->pRefDevice;
+ OutputDevice* pFmtDevice = pOutput->pFmtDevice;
+ aTextSize.Width() = pFmtDevice->GetTextWidth( aString );
+ aTextSize.Height() = pFmtDevice->GetTextHeight();
+
+ if ( !pRefDevice->GetConnectMetaFile() || pRefDevice->GetOutDevType() == OUTDEV_PRINTER )
+ {
+ double fMul = pOutput->GetStretch();
+ aTextSize.Width() = (long)(aTextSize.Width() / fMul + 0.5);
+ }
+
+ aTextSize.Height() = aMetric.GetAscent() + aMetric.GetDescent();
+ if ( GetOrient() != SVX_ORIENTATION_STANDARD )
+ {
+ long nTemp = aTextSize.Height();
+ aTextSize.Height() = aTextSize.Width();
+ aTextSize.Width() = nTemp;
+ }
+
+ nOriginalWidth = aTextSize.Width();
+ if ( bPixelToLogic )
+ aTextSize = pRefDevice->LogicToPixel( aTextSize );
+
+ pLastCell = NULL; // derselbe Text kann in der naechsten Zelle wieder passen
+}
+
+long ScDrawStringsVars::GetMaxDigitWidth()
+{
+ if (nMaxDigitWidth > 0)
+ return nMaxDigitWidth;
+
+ sal_Char cZero = '0';
+ for (sal_Char i = 0; i < 10; ++i)
+ {
+ sal_Char cDigit = cZero + i;
+ long n = pOutput->pFmtDevice->GetTextWidth(String(cDigit));
+ nMaxDigitWidth = ::std::max(nMaxDigitWidth, n);
+ }
+ return nMaxDigitWidth;
+}
+
+long ScDrawStringsVars::GetSignWidth()
+{
+ if (nSignWidth > 0)
+ return nSignWidth;
+
+ nSignWidth = pOutput->pFmtDevice->GetTextWidth(String('-'));
+ return nSignWidth;
+}
+
+long ScDrawStringsVars::GetDotWidth()
+{
+ if (nDotWidth > 0)
+ return nDotWidth;
+
+ const ::rtl::OUString& sep = ScGlobal::GetpLocaleData()->getLocaleItem().decimalSeparator;
+ nDotWidth = pOutput->pFmtDevice->GetTextWidth(sep);
+ return nDotWidth;
+}
+
+long ScDrawStringsVars::GetExpWidth()
+{
+ if (nExpWidth > 0)
+ return nExpWidth;
+
+ nExpWidth = pOutput->pFmtDevice->GetTextWidth(String('E'));
+ return nExpWidth;
+}
+
+void ScDrawStringsVars::TextChanged()
+{
+ OutputDevice* pRefDevice = pOutput->pRefDevice;
+ OutputDevice* pFmtDevice = pOutput->pFmtDevice;
+ aTextSize.Width() = pFmtDevice->GetTextWidth( aString );
+ aTextSize.Height() = pFmtDevice->GetTextHeight();
+
+ if ( !pRefDevice->GetConnectMetaFile() || pRefDevice->GetOutDevType() == OUTDEV_PRINTER )
+ {
+ double fMul = pOutput->GetStretch();
+ aTextSize.Width() = (long)(aTextSize.Width() / fMul + 0.5);
+ }
+
+ aTextSize.Height() = aMetric.GetAscent() + aMetric.GetDescent();
+ if ( GetOrient() != SVX_ORIENTATION_STANDARD )
+ {
+ long nTemp = aTextSize.Height();
+ aTextSize.Height() = aTextSize.Width();
+ aTextSize.Width() = nTemp;
+ }
+
+ nOriginalWidth = aTextSize.Width();
+ if ( bPixelToLogic )
+ aTextSize = pRefDevice->LogicToPixel( aTextSize );
+}
+
+sal_Bool ScDrawStringsVars::HasEditCharacters() const
+{
+ static const sal_Unicode pChars[] =
+ {
+ CHAR_NBSP, CHAR_SHY, CHAR_ZWSP, CHAR_LRM, CHAR_RLM, CHAR_NBHY, CHAR_ZWNBSP, 0
+ };
+ return aString.SearchChar( pChars ) != STRING_NOTFOUND;
+}
+
+//==================================================================
+
+double ScOutputData::GetStretch()
+{
+ if ( pRefDevice->IsMapMode() )
+ {
+ // #95920# If a non-trivial MapMode is set, its scale is now already
+ // taken into account in the OutputDevice's font handling
+ // (OutputDevice::ImplNewFont, see #95414#).
+ // The old handling below is only needed for pixel output.
+ return 1.0;
+ }
+
+ // calculation in double is faster than Fraction multiplication
+ // and doesn't overflow
+
+ if ( pRefDevice == pFmtDevice )
+ {
+ MapMode aOld = pRefDevice->GetMapMode();
+ return ((double)aOld.GetScaleY()) / ((double)aOld.GetScaleX()) * ((double)aZoomY) / ((double)aZoomX);
+ }
+ else
+ {
+ // when formatting for printer, device map mode has already been taken care of
+ return ((double)aZoomY) / ((double)aZoomX);
+ }
+}
+
+//==================================================================
+
+//
+// output strings
+//
+
+void lcl_DoHyperlinkResult( OutputDevice* pDev, const Rectangle& rRect, ScBaseCell* pCell )
+{
+ vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
+
+ String aCellText;
+ String aURL;
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
+ if ( pFCell->IsHyperLinkCell() )
+ pFCell->GetURLResult( aURL, aCellText );
+ }
+
+ if ( aURL.Len() && pPDFData )
+ {
+ vcl::PDFExtOutDevBookmarkEntry aBookmark;
+ aBookmark.nLinkId = pPDFData->CreateLink( rRect );
+ aBookmark.aBookmark = aURL;
+ std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFData->GetBookmarks();
+ rBookmarks.push_back( aBookmark );
+ }
+}
+
+void ScOutputData::SetSyntaxColor( Font* pFont, ScBaseCell* pCell )
+{
+ if (pCell)
+ {
+ switch (pCell->GetCellType())
+ {
+ case CELLTYPE_VALUE:
+ pFont->SetColor( *pValueColor );
+ break;
+ case CELLTYPE_STRING:
+ pFont->SetColor( *pTextColor );
+ break;
+ case CELLTYPE_FORMULA:
+ pFont->SetColor( *pFormulaColor );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+}
+
+void lcl_SetEditColor( EditEngine& rEngine, const Color& rColor )
+{
+ ESelection aSel( 0, 0, rEngine.GetParagraphCount(), 0 );
+ SfxItemSet aSet( rEngine.GetEmptyItemSet() );
+ aSet.Put( SvxColorItem( rColor, EE_CHAR_COLOR ) );
+ rEngine.QuickSetAttribs( aSet, aSel );
+ // function is called with update mode set to FALSE
+}
+
+void ScOutputData::SetEditSyntaxColor( EditEngine& rEngine, ScBaseCell* pCell )
+{
+ if (pCell)
+ {
+ Color aColor;
+ switch (pCell->GetCellType())
+ {
+ case CELLTYPE_VALUE:
+ aColor = *pValueColor;
+ break;
+ case CELLTYPE_STRING:
+ aColor = *pTextColor;
+ break;
+ case CELLTYPE_FORMULA:
+ aColor = *pFormulaColor;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ lcl_SetEditColor( rEngine, aColor );
+ }
+}
+
+sal_Bool ScOutputData::GetMergeOrigin( SCCOL nX, SCROW nY, SCSIZE nArrY,
+ SCCOL& rOverX, SCROW& rOverY,
+ sal_Bool bVisRowChanged )
+{
+ sal_Bool bDoMerge = sal_False;
+ sal_Bool bIsLeft = ( nX == nVisX1 );
+ sal_Bool bIsTop = ( nY == nVisY1 ) || bVisRowChanged;
+
+ CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nX+1];
+ if ( pInfo->bHOverlapped && pInfo->bVOverlapped )
+ bDoMerge = bIsLeft && bIsTop;
+ else if ( pInfo->bHOverlapped )
+ bDoMerge = bIsLeft;
+ else if ( pInfo->bVOverlapped )
+ bDoMerge = bIsTop;
+
+ // weiter solange versteckt
+/* if (!bDoMerge)
+ return sal_False;
+*/
+
+ rOverX = nX;
+ rOverY = nY;
+ sal_Bool bHOver = pInfo->bHOverlapped;
+ sal_Bool bVOver = pInfo->bVOverlapped;
+ sal_Bool bHidden;
+
+ while (bHOver) // nY konstant
+ {
+ --rOverX;
+ bHidden = pDoc->ColHidden(rOverX, nTab);
+ if ( !bDoMerge && !bHidden )
+ return sal_False;
+
+ if (rOverX >= nX1 && !bHidden)
+ {
+// rVirtPosX -= pRowInfo[0].pCellInfo[rOverX+1].nWidth;
+ bHOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bHOverlapped;
+ bVOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bVOverlapped;
+ }
+ else
+ {
+// if (!bClipVirt)
+// rVirtPosX -= (long) (pDoc->GetColWidth( rOverX, nTab ) * nPPTX);
+ sal_uInt16 nOverlap = ((ScMergeFlagAttr*)pDoc->GetAttr(
+ rOverX, rOverY, nTab, ATTR_MERGE_FLAG ))->GetValue();
+ bHOver = ((nOverlap & SC_MF_HOR) != 0);
+ bVOver = ((nOverlap & SC_MF_VER) != 0);
+ }
+ }
+
+ while (bVOver)
+ {
+ --rOverY;
+ bHidden = pDoc->RowHidden(rOverY, nTab);
+ if ( !bDoMerge && !bHidden )
+ return sal_False;
+
+ if (nArrY>0)
+ --nArrY; // lokale Kopie !
+
+ if (rOverX >= nX1 && rOverY >= nY1 &&
+ !pDoc->ColHidden(rOverX, nTab) &&
+ !pDoc->RowHidden(rOverY, nTab) &&
+ pRowInfo[nArrY].nRowNo == rOverY)
+ {
+// rVirtPosY -= pRowInfo[nArrY].nHeight;
+ bHOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bHOverlapped;
+ bVOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bVOverlapped;
+ }
+ else
+ {
+// if (!bClipVirt)
+// rVirtPosY -= (long) (pDoc->GetRowHeight( rOverY, nTab ) * nPPTY);
+ sal_uInt16 nOverlap = ((ScMergeFlagAttr*)pDoc->GetAttr(
+ rOverX, rOverY, nTab, ATTR_MERGE_FLAG ))->GetValue();
+ bHOver = ((nOverlap & SC_MF_HOR) != 0);
+ bVOver = ((nOverlap & SC_MF_VER) != 0);
+ }
+ }
+
+ return sal_True;
+}
+
+inline sal_Bool StringDiffer( const ScPatternAttr*& rpOldPattern, const ScPatternAttr*& rpNewPattern )
+{
+ DBG_ASSERT( rpNewPattern, "pNewPattern" );
+
+ if ( rpNewPattern == rpOldPattern )
+ return sal_False;
+ else if ( !rpOldPattern )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT ) != &rpOldPattern->GetItem( ATTR_FONT ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT ) != &rpOldPattern->GetItem( ATTR_CJK_FONT ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT ) != &rpOldPattern->GetItem( ATTR_CTL_FONT ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_HEIGHT ) != &rpOldPattern->GetItem( ATTR_FONT_HEIGHT ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT_HEIGHT ) != &rpOldPattern->GetItem( ATTR_CJK_FONT_HEIGHT ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT_HEIGHT ) != &rpOldPattern->GetItem( ATTR_CTL_FONT_HEIGHT ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_WEIGHT ) != &rpOldPattern->GetItem( ATTR_FONT_WEIGHT ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT_WEIGHT ) != &rpOldPattern->GetItem( ATTR_CJK_FONT_WEIGHT ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT_WEIGHT ) != &rpOldPattern->GetItem( ATTR_CTL_FONT_WEIGHT ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_POSTURE ) != &rpOldPattern->GetItem( ATTR_FONT_POSTURE ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_CJK_FONT_POSTURE ) != &rpOldPattern->GetItem( ATTR_CJK_FONT_POSTURE ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_CTL_FONT_POSTURE ) != &rpOldPattern->GetItem( ATTR_CTL_FONT_POSTURE ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_UNDERLINE ) != &rpOldPattern->GetItem( ATTR_FONT_UNDERLINE ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_OVERLINE ) != &rpOldPattern->GetItem( ATTR_FONT_OVERLINE ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_WORDLINE ) != &rpOldPattern->GetItem( ATTR_FONT_WORDLINE ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_CROSSEDOUT ) != &rpOldPattern->GetItem( ATTR_FONT_CROSSEDOUT ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_CONTOUR ) != &rpOldPattern->GetItem( ATTR_FONT_CONTOUR ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_SHADOWED ) != &rpOldPattern->GetItem( ATTR_FONT_SHADOWED ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_COLOR ) != &rpOldPattern->GetItem( ATTR_FONT_COLOR ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_HOR_JUSTIFY ) != &rpOldPattern->GetItem( ATTR_HOR_JUSTIFY ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_VER_JUSTIFY ) != &rpOldPattern->GetItem( ATTR_VER_JUSTIFY ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_STACKED ) != &rpOldPattern->GetItem( ATTR_STACKED ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_LINEBREAK ) != &rpOldPattern->GetItem( ATTR_LINEBREAK ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_MARGIN ) != &rpOldPattern->GetItem( ATTR_MARGIN ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_ROTATE_VALUE ) != &rpOldPattern->GetItem( ATTR_ROTATE_VALUE ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_FORBIDDEN_RULES ) != &rpOldPattern->GetItem( ATTR_FORBIDDEN_RULES ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_EMPHASISMARK ) != &rpOldPattern->GetItem( ATTR_FONT_EMPHASISMARK ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_FONT_RELIEF ) != &rpOldPattern->GetItem( ATTR_FONT_RELIEF ) )
+ return sal_True;
+ else if ( &rpNewPattern->GetItem( ATTR_BACKGROUND ) != &rpOldPattern->GetItem( ATTR_BACKGROUND ) )
+ return sal_True; // needed with automatic text color
+ else
+ {
+ rpOldPattern = rpNewPattern;
+ return sal_False;
+ }
+}
+
+inline void lcl_CreateInterpretProgress( sal_Bool& bProgress, ScDocument* pDoc,
+ ScFormulaCell* pFCell )
+{
+ if ( !bProgress && pFCell->GetDirty() )
+ {
+ ScProgress::CreateInterpretProgress( pDoc, sal_True );
+ bProgress = sal_True;
+ }
+}
+
+inline sal_uInt8 GetScriptType( ScDocument* pDoc, ScBaseCell* pCell,
+ const ScPatternAttr* pPattern,
+ const SfxItemSet* pCondSet )
+{
+ return pDoc->GetCellScriptType( pCell, pPattern->GetNumberFormat( pDoc->GetFormatTable(), pCondSet ) );
+}
+
+inline sal_Bool IsAmbiguousScript( sal_uInt8 nScript )
+{
+ return ( nScript != SCRIPTTYPE_LATIN &&
+ nScript != SCRIPTTYPE_ASIAN &&
+ nScript != SCRIPTTYPE_COMPLEX );
+}
+
+sal_Bool ScOutputData::IsEmptyCellText( RowInfo* pThisRowInfo, SCCOL nX, SCROW nY )
+{
+ // pThisRowInfo may be NULL
+
+ sal_Bool bEmpty;
+ if ( pThisRowInfo && nX <= nX2 )
+ bEmpty = pThisRowInfo->pCellInfo[nX+1].bEmptyCellText;
+ else
+ bEmpty = ( pDoc->GetCell( ScAddress( nX, nY, nTab ) ) == NULL );
+
+ if ( !bEmpty && ( nX < nX1 || nX > nX2 || !pThisRowInfo ) )
+ {
+ // for the range nX1..nX2 in RowInfo, cell protection attribute is already evaluated
+ // into bEmptyCellText in ScDocument::FillInfo / lcl_HidePrint (printfun)
+
+ sal_Bool bIsPrint = ( eType == OUTTYPE_PRINTER );
+
+ if ( bIsPrint || bTabProtected )
+ {
+ const ScProtectionAttr* pAttr = (const ScProtectionAttr*)
+ pDoc->GetEffItem( nX, nY, nTab, ATTR_PROTECTION );
+ if ( bIsPrint && pAttr->GetHidePrint() )
+ bEmpty = sal_True;
+ else if ( bTabProtected )
+ {
+ if ( pAttr->GetHideCell() )
+ bEmpty = sal_True;
+ else if ( bShowFormulas && pAttr->GetHideFormula() )
+ {
+ ScBaseCell* pCell = pDoc->GetCell( ScAddress( nX, nY, nTab ) );
+ if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
+ bEmpty = sal_True;
+ }
+ }
+ }
+ }
+ return bEmpty;
+}
+
+void ScOutputData::GetVisibleCell( SCCOL nCol, SCROW nRow, SCTAB nTabP, ScBaseCell*& rpCell )
+{
+ pDoc->GetCell( nCol, nRow, nTabP, rpCell );
+ if ( rpCell && IsEmptyCellText( NULL, nCol, nRow ) )
+ rpCell = NULL;
+}
+
+sal_Bool ScOutputData::IsAvailable( SCCOL nX, SCROW nY )
+{
+ // apply the same logic here as in DrawStrings/DrawEdit:
+ // Stop at non-empty or merged or overlapped cell,
+ // where a note is empty as well as a cell that's hidden by protection settings
+
+ const ScBaseCell* pCell = pDoc->GetCell( ScAddress( nX, nY, nTab ) );
+ if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE && !IsEmptyCellText( NULL, nX, nY ) )
+ {
+ return sal_False;
+ }
+
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nX, nY, nTab );
+ if ( ((const ScMergeAttr&)pPattern->GetItem(ATTR_MERGE)).IsMerged() ||
+ ((const ScMergeFlagAttr&)pPattern->GetItem(ATTR_MERGE_FLAG)).IsOverlapped() )
+ {
+ return sal_False;
+ }
+
+ return sal_True;
+}
+
+// nX, nArrY: loop variables from DrawStrings / DrawEdit
+// nPosX, nPosY: corresponding positions for nX, nArrY
+// nCellX, nCellY: position of the cell that contains the text
+// nNeeded: Text width, including margin
+// rPattern: cell format at nCellX, nCellY
+// nHorJustify: horizontal alignment (visual) to determine which cells to use for long strings
+// bCellIsValue: if set, don't extend into empty cells
+// bBreak: if set, don't extend, and don't set clip marks (but rLeftClip/rRightClip is set)
+// bOverwrite: if set, also extend into non-empty cells (for rotated text)
+// rParam output: various area parameters.
+
+void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY,
+ SCCOL nCellX, SCROW nCellY, long nNeeded,
+ const ScPatternAttr& rPattern,
+ sal_uInt16 nHorJustify, bool bCellIsValue,
+ bool bBreak, bool bOverwrite,
+ OutputAreaParam& rParam )
+{
+ // rThisRowInfo may be for a different row than nCellY, is still used for clip marks
+ RowInfo& rThisRowInfo = pRowInfo[nArrY];
+
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ long nCellPosX = nPosX; // find nCellX position, starting at nX/nPosX
+ SCCOL nCompCol = nX;
+ while ( nCellX > nCompCol )
+ {
+ //! extra member function for width?
+ long nColWidth = ( nCompCol <= nX2 ) ?
+ pRowInfo[0].pCellInfo[nCompCol+1].nWidth :
+ (long) ( pDoc->GetColWidth( nCompCol, nTab ) * nPPTX );
+ nCellPosX += nColWidth * nLayoutSign;
+ ++nCompCol;
+ }
+ while ( nCellX < nCompCol )
+ {
+ --nCompCol;
+ long nColWidth = ( nCompCol <= nX2 ) ?
+ pRowInfo[0].pCellInfo[nCompCol+1].nWidth :
+ (long) ( pDoc->GetColWidth( nCompCol, nTab ) * nPPTX );
+ nCellPosX -= nColWidth * nLayoutSign;
+ }
+
+ long nCellPosY = nPosY; // find nCellY position, starting at nArrY/nPosY
+ SCSIZE nCompArr = nArrY;
+ SCROW nCompRow = pRowInfo[nCompArr].nRowNo;
+ while ( nCellY > nCompRow )
+ {
+ if ( nCompArr + 1 < nArrCount )
+ {
+ nCellPosY += pRowInfo[nCompArr].nHeight;
+ ++nCompArr;
+ nCompRow = pRowInfo[nCompArr].nRowNo;
+ }
+ else
+ {
+ sal_uInt16 nDocHeight = pDoc->GetRowHeight( nCompRow, nTab );
+ if ( nDocHeight )
+ nCellPosY += (long) ( nDocHeight * nPPTY );
+ ++nCompRow;
+ }
+ }
+ nCellPosY -= (long) pDoc->GetScaledRowHeight( nCellY, nCompRow-1, nTab, nPPTY );
+
+ const ScMergeAttr* pMerge = (const ScMergeAttr*)&rPattern.GetItem( ATTR_MERGE );
+ sal_Bool bMerged = pMerge->IsMerged();
+ long nMergeCols = pMerge->GetColMerge();
+ if ( nMergeCols == 0 )
+ nMergeCols = 1;
+ long nMergeRows = pMerge->GetRowMerge();
+ if ( nMergeRows == 0 )
+ nMergeRows = 1;
+
+ long i;
+ long nMergeSizeX = 0;
+ for ( i=0; i<nMergeCols; i++ )
+ {
+ long nColWidth = ( nCellX+i <= nX2 ) ?
+ pRowInfo[0].pCellInfo[nCellX+i+1].nWidth :
+ (long) ( pDoc->GetColWidth( sal::static_int_cast<SCCOL>(nCellX+i), nTab ) * nPPTX );
+ nMergeSizeX += nColWidth;
+ }
+ long nMergeSizeY = 0;
+ short nDirect = 0;
+ if ( rThisRowInfo.nRowNo == nCellY )
+ {
+ // take first row's height from row info
+ nMergeSizeY += rThisRowInfo.nHeight;
+ nDirect = 1; // skip in loop
+ }
+ // following rows always from document
+ nMergeSizeY += (long) pDoc->GetScaledRowHeight( nCellY+nDirect, nCellY+nMergeRows-1, nTab, nPPTY);
+
+ --nMergeSizeX; // leave out the grid horizontally, also for alignment (align between grid lines)
+
+ rParam.mnColWidth = nMergeSizeX; // store the actual column width.
+
+ //
+ // construct the rectangles using logical left/right values (justify is called at the end)
+ //
+
+ // rAlignRect is the single cell or merged area, used for alignment.
+
+ rParam.maAlignRect.Left() = nCellPosX;
+ rParam.maAlignRect.Right() = nCellPosX + ( nMergeSizeX - 1 ) * nLayoutSign;
+ rParam.maAlignRect.Top() = nCellPosY;
+ rParam.maAlignRect.Bottom() = nCellPosY + nMergeSizeY - 1;
+
+ // rClipRect is all cells that are used for output.
+ // For merged cells this is the same as rAlignRect, otherwise neighboring cells can also be used.
+
+ rParam.maClipRect = rParam.maAlignRect;
+ if ( nNeeded > nMergeSizeX )
+ {
+ SvxCellHorJustify eHorJust = (SvxCellHorJustify)nHorJustify;
+
+ long nMissing = nNeeded - nMergeSizeX;
+ long nLeftMissing = 0;
+ long nRightMissing = 0;
+ switch ( eHorJust )
+ {
+ case SVX_HOR_JUSTIFY_LEFT:
+ nRightMissing = nMissing;
+ break;
+ case SVX_HOR_JUSTIFY_RIGHT:
+ nLeftMissing = nMissing;
+ break;
+ case SVX_HOR_JUSTIFY_CENTER:
+ nLeftMissing = nMissing / 2;
+ nRightMissing = nMissing - nLeftMissing;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ // nLeftMissing, nRightMissing are logical, eHorJust values are visual
+ if ( bLayoutRTL )
+ ::std::swap( nLeftMissing, nRightMissing );
+
+ SCCOL nRightX = nCellX;
+ SCCOL nLeftX = nCellX;
+ if ( !bMerged && !bCellIsValue && !bBreak )
+ {
+ // look for empty cells into which the text can be extended
+
+ while ( nRightMissing > 0 && nRightX < MAXCOL && ( bOverwrite || IsAvailable( nRightX+1, nCellY ) ) )
+ {
+ ++nRightX;
+ long nAdd = (long) ( pDoc->GetColWidth( nRightX, nTab ) * nPPTX );
+ nRightMissing -= nAdd;
+ rParam.maClipRect.Right() += nAdd * nLayoutSign;
+
+ if ( rThisRowInfo.nRowNo == nCellY && nRightX >= nX1 && nRightX <= nX2 )
+ rThisRowInfo.pCellInfo[nRightX].bHideGrid = sal_True;
+ }
+
+ while ( nLeftMissing > 0 && nLeftX > 0 && ( bOverwrite || IsAvailable( nLeftX-1, nCellY ) ) )
+ {
+ if ( rThisRowInfo.nRowNo == nCellY && nLeftX >= nX1 && nLeftX <= nX2 )
+ rThisRowInfo.pCellInfo[nLeftX].bHideGrid = sal_True;
+
+ --nLeftX;
+ long nAdd = (long) ( pDoc->GetColWidth( nLeftX, nTab ) * nPPTX );
+ nLeftMissing -= nAdd;
+ rParam.maClipRect.Left() -= nAdd * nLayoutSign;
+ }
+ }
+
+ // Set flag and reserve space for clipping mark triangle,
+ // even if rThisRowInfo isn't for nCellY (merged cells).
+ if ( nRightMissing > 0 && bMarkClipped && nRightX >= nX1 && nRightX <= nX2 && !bBreak && !bCellIsValue )
+ {
+ rThisRowInfo.pCellInfo[nRightX+1].nClipMark |= SC_CLIPMARK_RIGHT;
+ bAnyClipped = sal_True;
+ long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX );
+ rParam.maClipRect.Right() -= nMarkPixel * nLayoutSign;
+ }
+ if ( nLeftMissing > 0 && bMarkClipped && nLeftX >= nX1 && nLeftX <= nX2 && !bBreak && !bCellIsValue )
+ {
+ rThisRowInfo.pCellInfo[nLeftX+1].nClipMark |= SC_CLIPMARK_LEFT;
+ bAnyClipped = sal_True;
+ long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX );
+ rParam.maClipRect.Left() += nMarkPixel * nLayoutSign;
+ }
+
+ rParam.mbLeftClip = ( nLeftMissing > 0 );
+ rParam.mbRightClip = ( nRightMissing > 0 );
+ }
+ else
+ {
+ rParam.mbLeftClip = rParam.mbRightClip = sal_False;
+
+ // leave space for AutoFilter on screen
+ // (for automatic line break: only if not formatting for printer, as in ScColumn::GetNeededSize)
+
+ if ( eType==OUTTYPE_WINDOW &&
+ ( static_cast<const ScMergeFlagAttr&>(rPattern.GetItem(ATTR_MERGE_FLAG)).GetValue() & SC_MF_AUTO ) &&
+ ( !bBreak || pRefDevice == pFmtDevice ) )
+ {
+ // filter drop-down width is now independent from row height
+ const long nFilter = DROPDOWN_BITMAP_SIZE;
+ sal_Bool bFit = ( nNeeded + nFilter <= nMergeSizeX );
+ if ( bFit || bCellIsValue )
+ {
+ // content fits even in the remaining area without the filter button
+ // -> align within that remaining area
+
+ rParam.maAlignRect.Right() -= nFilter * nLayoutSign;
+ rParam.maClipRect.Right() -= nFilter * nLayoutSign;
+
+ // if a number doesn't fit, don't hide part of the number behind the button
+ // -> set clip flags, so "###" replacement is used (but also within the smaller area)
+
+ if ( !bFit )
+ rParam.mbLeftClip = rParam.mbRightClip = sal_True;
+ }
+ }
+ }
+
+ // justify both rectangles for alignment calculation, use with DrawText etc.
+
+ rParam.maAlignRect.Justify();
+ rParam.maClipRect.Justify();
+
+#if 0
+ //! Test !!!
+ pDev->Push();
+ pDev->SetLineColor();
+ pDev->SetFillColor( COL_LIGHTGREEN );
+ pDev->DrawRect( pDev->PixelToLogic(rParam.maClipRect) );
+ pDev->DrawRect( rParam.maClipRect ); // print preview
+ pDev->Pop();
+ //! Test !!!
+#endif
+}
+
+void ScOutputData::DrawStrings( sal_Bool bPixelToLogic )
+{
+ DBG_ASSERT( pDev == pRefDevice ||
+ pDev->GetMapMode().GetMapUnit() == pRefDevice->GetMapMode().GetMapUnit(),
+ "DrawStrings: unterschiedliche MapUnits ?!?!" );
+
+ vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
+
+ sal_Bool bWasIdleDisabled = pDoc->IsIdleDisabled();
+ pDoc->DisableIdle( sal_True );
+ Size aMinSize = pRefDevice->PixelToLogic(Size(0,100)); // erst darueber wird ausgegeben
+// sal_uInt32 nMinHeight = aMinSize.Height() / 200; // 1/2 Pixel
+
+ ScDrawStringsVars aVars( this, bPixelToLogic );
+
+ sal_Bool bProgress = sal_False;
+
+ long nInitPosX = nScrX;
+ if ( bLayoutRTL )
+ nInitPosX += nMirrorW - 1; // pixels
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ SCCOL nLastContentCol = MAXCOL;
+ if ( nX2 < MAXCOL )
+ nLastContentCol = sal::static_int_cast<SCCOL>(
+ nLastContentCol - pDoc->GetEmptyLinesInBlock( nX2+1, nY1, nTab, MAXCOL, nY2, nTab, DIR_RIGHT ) );
+ SCCOL nLoopStartX = nX1;
+ if ( nX1 > 0 )
+ --nLoopStartX; // start before nX1 for rest of long text to the left
+
+ // variables for GetOutputArea
+ OutputAreaParam aAreaParam;
+ sal_Bool bCellIsValue = sal_False;
+ long nNeededWidth = 0;
+ SvxCellHorJustify eOutHorJust = SVX_HOR_JUSTIFY_STANDARD;
+ const ScPatternAttr* pPattern = NULL;
+ const SfxItemSet* pCondSet = NULL;
+ const ScPatternAttr* pOldPattern = NULL;
+ const SfxItemSet* pOldCondSet = NULL;
+ sal_uInt8 nOldScript = 0;
+
+ // alternative pattern instances in case we need to modify the pattern
+ // before processing the cell value.
+ ::boost::ptr_vector<ScPatternAttr> aAltPatterns;
+
+ long nPosY = nScrY;
+ for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ if ( pThisRowInfo->bChanged )
+ {
+ SCROW nY = pThisRowInfo->nRowNo;
+// long nCellHeight = (long) pThisRowInfo->nHeight;
+ long nPosX = nInitPosX;
+ if ( nLoopStartX < nX1 )
+ nPosX -= pRowInfo[0].pCellInfo[nLoopStartX+1].nWidth * nLayoutSign;
+ for (SCCOL nX=nLoopStartX; nX<=nX2; nX++)
+ {
+ sal_Bool bMergeEmpty = sal_False;
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+ sal_Bool bEmpty = nX < nX1 || pInfo->bEmptyCellText;
+
+ SCCOL nCellX = nX; // position where the cell really starts
+ SCROW nCellY = nY;
+ sal_Bool bDoCell = sal_False;
+ sal_Bool bNeedEdit = sal_False;
+
+ //
+ // Part of a merged cell?
+ //
+
+ sal_Bool bOverlapped = ( pInfo->bHOverlapped || pInfo->bVOverlapped );
+ if ( bOverlapped )
+ {
+ bEmpty = sal_True;
+
+ SCCOL nOverX; // start of the merged cells
+ SCROW nOverY;
+ sal_Bool bVisChanged = !pRowInfo[nArrY-1].bChanged;
+ if (GetMergeOrigin( nX,nY, nArrY, nOverX,nOverY, bVisChanged ))
+ {
+ nCellX = nOverX;
+ nCellY = nOverY;
+ bDoCell = sal_True;
+ }
+ else
+ bMergeEmpty = sal_True;
+ }
+
+ //
+ // Rest of a long text further to the left?
+ //
+
+ if ( bEmpty && !bMergeEmpty && nX < nX1 && !bOverlapped )
+ {
+ SCCOL nTempX=nX1;
+ while (nTempX > 0 && IsEmptyCellText( pThisRowInfo, nTempX, nY ))
+ --nTempX;
+
+ if ( nTempX < nX1 &&
+ !IsEmptyCellText( pThisRowInfo, nTempX, nY ) &&
+ !pDoc->HasAttrib( nTempX,nY,nTab, nX1,nY,nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+ {
+ nCellX = nTempX;
+ bDoCell = sal_True;
+ }
+ }
+
+ //
+ // Rest of a long text further to the right?
+ //
+
+ if ( bEmpty && !bMergeEmpty && nX == nX2 && !bOverlapped )
+ {
+ // don't have to look further than nLastContentCol
+
+ SCCOL nTempX=nX;
+ while (nTempX < nLastContentCol && IsEmptyCellText( pThisRowInfo, nTempX, nY ))
+ ++nTempX;
+
+ if ( nTempX > nX &&
+ !IsEmptyCellText( pThisRowInfo, nTempX, nY ) &&
+ !pDoc->HasAttrib( nTempX,nY,nTab, nX,nY,nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+ {
+ nCellX = nTempX;
+ bDoCell = sal_True;
+ }
+ }
+
+ //
+ // normal visible cell
+ //
+
+ if (!bEmpty)
+ bDoCell = sal_True;
+
+ //
+ // don't output the cell that's being edited
+ //
+
+ if ( bDoCell && bEditMode && nCellX == nEditCol && nCellY == nEditRow )
+ bDoCell = sal_False;
+
+ //
+ // output the cell text
+ //
+
+ ScBaseCell* pCell = NULL;
+ if (bDoCell)
+ {
+ if ( nCellY == nY && nCellX == nX && nCellX >= nX1 && nCellX <= nX2 )
+ pCell = pThisRowInfo->pCellInfo[nCellX+1].pCell;
+ else
+ GetVisibleCell( nCellX, nCellY, nTab, pCell ); // get from document
+ if ( !pCell )
+ bDoCell = sal_False;
+ else if ( pCell->GetCellType() == CELLTYPE_EDIT )
+ bNeedEdit = sal_True;
+ }
+ if (bDoCell && !bNeedEdit)
+ {
+ if ( nCellY == nY && nCellX >= nX1 && nCellX <= nX2 )
+ {
+ CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nCellX+1];
+ pPattern = rCellInfo.pPatternAttr;
+ pCondSet = rCellInfo.pConditionSet;
+
+ if ( !pPattern )
+ {
+ // #i68085# pattern from cell info for hidden columns is null,
+ // test for null is quicker than using column flags
+ pPattern = pDoc->GetPattern( nCellX, nCellY, nTab );
+ pCondSet = pDoc->GetCondResult( nCellX, nCellY, nTab );
+ }
+ }
+ else // get from document
+ {
+ pPattern = pDoc->GetPattern( nCellX, nCellY, nTab );
+ pCondSet = pDoc->GetCondResult( nCellX, nCellY, nTab );
+ }
+
+ if (pCell->HasValueData() &&
+ static_cast<const SfxBoolItem&>(
+ pPattern->GetItem(ATTR_LINEBREAK, pCondSet)).GetValue())
+ {
+ // Disable line break when the cell content is numeric.
+ aAltPatterns.push_back(new ScPatternAttr(*pPattern));
+ ScPatternAttr* pAltPattern = &aAltPatterns.back();
+ SfxBoolItem aLineBreak(ATTR_LINEBREAK, false);
+ pAltPattern->GetItemSet().Put(aLineBreak);
+ pPattern = pAltPattern;
+ }
+
+ sal_uInt8 nScript = GetScriptType( pDoc, pCell, pPattern, pCondSet );
+ if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType();
+ if ( pPattern != pOldPattern || pCondSet != pOldCondSet ||
+ nScript != nOldScript || bSyntaxMode )
+ {
+ if ( StringDiffer(pOldPattern,pPattern) ||
+ pCondSet != pOldCondSet || nScript != nOldScript || bSyntaxMode )
+ aVars.SetPattern( pPattern, pCondSet, pCell, nScript );
+ else
+ aVars.SetPatternSimple( pPattern, pCondSet );
+ pOldPattern = pPattern;
+ pOldCondSet = pCondSet;
+ nOldScript = nScript;
+ }
+
+ // use edit engine for rotated, stacked or mixed-script text
+ if ( aVars.GetOrient() == SVX_ORIENTATION_STACKED ||
+ aVars.IsRotated() || IsAmbiguousScript(nScript) )
+ bNeedEdit = sal_True;
+ }
+ if (bDoCell && !bNeedEdit)
+ {
+ sal_Bool bFormulaCell = (pCell->GetCellType() == CELLTYPE_FORMULA );
+ if ( bFormulaCell )
+ lcl_CreateInterpretProgress( bProgress, pDoc, (ScFormulaCell*)pCell );
+ if ( aVars.SetText(pCell) )
+ pOldPattern = NULL;
+ bNeedEdit = aVars.HasEditCharacters() ||
+ (bFormulaCell && ((ScFormulaCell*)pCell)->IsMultilineResult());
+ }
+ long nTotalMargin = 0;
+ if (bDoCell && !bNeedEdit)
+ {
+ CellType eCellType = pCell->GetCellType();
+ bCellIsValue = ( eCellType == CELLTYPE_VALUE );
+ if ( eCellType == CELLTYPE_FORMULA )
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ bCellIsValue = pFCell->IsRunning() || pFCell->IsValue();
+ }
+
+ eOutHorJust = ( aVars.GetHorJust() != SVX_HOR_JUSTIFY_STANDARD ) ?
+ aVars.GetHorJust() :
+ ( bCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT );
+
+ if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
+ eOutHorJust = SVX_HOR_JUSTIFY_LEFT; // repeat is not yet implemented
+
+ sal_Bool bBreak = ( aVars.GetLineBreak() || aVars.GetHorJust() == SVX_HOR_JUSTIFY_BLOCK );
+ sal_Bool bRepeat = aVars.IsRepeat() && !bBreak;
+ sal_Bool bShrink = aVars.IsShrink() && !bBreak && !bRepeat;
+
+ nTotalMargin =
+ static_cast<long>(aVars.GetLeftTotal() * nPPTX) +
+ static_cast<long>(aVars.GetMargin()->GetRightMargin() * nPPTX);
+
+ nNeededWidth = aVars.GetTextSize().Width() + nTotalMargin;
+
+ // GetOutputArea gives justfied rectangles
+ GetOutputArea( nX, nArrY, nPosX, nPosY, nCellX, nCellY, nNeededWidth,
+ *pPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
+ bCellIsValue || bRepeat || bShrink, bBreak, sal_False,
+ aAreaParam );
+
+ if ( bShrink )
+ {
+ if ( aVars.GetOrient() != SVX_ORIENTATION_STANDARD )
+ {
+ // Only horizontal scaling is handled here.
+ // DrawEdit is used to vertically scale 90 deg rotated text.
+ bNeedEdit = sal_True;
+ }
+ else if ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) // horizontal
+ {
+ long nAvailable = aAreaParam.maAlignRect.GetWidth() - nTotalMargin;
+ long nScaleSize = aVars.GetTextSize().Width(); // without margin
+
+ if ( nScaleSize > 0 ) // 0 if the text is empty (formulas, number formats)
+ {
+ long nScale = ( nAvailable * 100 ) / nScaleSize;
+
+ aVars.SetShrinkScale( nScale, nOldScript );
+ long nNewSize = aVars.GetTextSize().Width();
+
+ sal_uInt16 nShrinkAgain = 0;
+ while ( nNewSize > nAvailable && nShrinkAgain < SC_SHRINKAGAIN_MAX )
+ {
+ // If the text is still too large, reduce the scale again by 10%, until it fits,
+ // at most 7 times (it's less than 50% of the calculated scale then).
+
+ nScale = ( nScale * 9 ) / 10;
+ aVars.SetShrinkScale( nScale, nOldScript );
+ nNewSize = aVars.GetTextSize().Width();
+ ++nShrinkAgain;
+ }
+ // If even at half the size the font still isn't rendered smaller,
+ // fall back to normal clipping (showing ### for numbers).
+ if ( nNewSize <= nAvailable )
+ aAreaParam.mbLeftClip = aAreaParam.mbRightClip = sal_False;
+
+ pOldPattern = NULL;
+ }
+ }
+ }
+
+ if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip )
+ {
+ long nAvailable = aAreaParam.maAlignRect.GetWidth() - nTotalMargin;
+ long nRepeatSize = aVars.GetTextSize().Width(); // without margin
+ // When formatting for the printer, the text sizes don't always add up.
+ // Round down (too few repetitions) rather than exceeding the cell size then:
+ if ( pFmtDevice != pRefDevice )
+ ++nRepeatSize;
+ if ( nRepeatSize > 0 )
+ {
+ long nRepeatCount = nAvailable / nRepeatSize;
+ if ( nRepeatCount > 1 )
+ {
+ String aCellStr = aVars.GetString();
+ String aRepeated = aCellStr;
+ for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
+ aRepeated.Append( aCellStr );
+ aVars.SetAutoText( aRepeated );
+ }
+ }
+ }
+
+ // use edit engine if automatic line breaks are needed
+ if ( bBreak )
+ {
+ if ( aVars.GetOrient() == SVX_ORIENTATION_STANDARD )
+ bNeedEdit = ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip );
+ else
+ {
+ long nHeight = aVars.GetTextSize().Height() +
+ (long)(aVars.GetMargin()->GetTopMargin()*nPPTY) +
+ (long)(aVars.GetMargin()->GetBottomMargin()*nPPTY);
+ bNeedEdit = ( nHeight > aAreaParam.maClipRect.GetHeight() );
+ }
+ }
+ }
+ if (bNeedEdit)
+ {
+ // mark the cell in CellInfo to be drawn in DrawEdit:
+ // Cells to the left are marked directly, cells to the
+ // right are handled by the flag for nX2
+ SCCOL nMarkX = ( nCellX <= nX2 ) ? nCellX : nX2;
+ RowInfo* pMarkRowInfo = ( nCellY == nY ) ? pThisRowInfo : &pRowInfo[0];
+ pMarkRowInfo->pCellInfo[nMarkX+1].bEditEngine = sal_True;
+ bDoCell = sal_False; // don't draw here
+ }
+ if ( bDoCell )
+ {
+ if ( bCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
+ {
+ // Adjust the decimals to fit the available column width.
+ aVars.SetTextToWidthOrHash(pCell, aAreaParam.mnColWidth - nTotalMargin);
+ nNeededWidth = aVars.GetTextSize().Width() +
+ (long) ( aVars.GetLeftTotal() * nPPTX ) +
+ (long) ( aVars.GetMargin()->GetRightMargin() * nPPTX );
+ if ( nNeededWidth <= aAreaParam.maClipRect.GetWidth() )
+ aAreaParam.mbLeftClip = aAreaParam.mbRightClip = sal_False;
+
+ // If the "###" replacement doesn't fit into the cells, no clip marks
+ // are shown, as the "###" already denotes too little space.
+ // The rectangles from the first GetOutputArea call remain valid.
+ }
+
+ long nJustPosX = aAreaParam.maAlignRect.Left(); // "justified" - effect of alignment will be added
+ long nJustPosY = aAreaParam.maAlignRect.Top();
+ long nAvailWidth = aAreaParam.maAlignRect.GetWidth();
+ long nOutHeight = aAreaParam.maAlignRect.GetHeight();
+
+ sal_Bool bOutside = ( aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW );
+ if ( aAreaParam.maClipRect.Left() < nScrX )
+ {
+ aAreaParam.maClipRect.Left() = nScrX;
+ aAreaParam.mbLeftClip = sal_True;
+ }
+ if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
+ {
+ aAreaParam.maClipRect.Right() = nScrX + nScrW; //! minus one?
+ aAreaParam.mbRightClip = sal_True;
+ }
+
+ sal_Bool bHClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
+ sal_Bool bVClip = sal_False;
+
+ if ( aAreaParam.maClipRect.Top() < nScrY )
+ {
+ aAreaParam.maClipRect.Top() = nScrY;
+ bVClip = sal_True;
+ }
+ if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
+ {
+ aAreaParam.maClipRect.Bottom() = nScrY + nScrH; //! minus one?
+ bVClip = sal_True;
+ }
+
+ //
+ // horizontalen Platz testen
+ //
+
+ sal_Bool bRightAdjusted = sal_False; // to correct text width calculation later
+ sal_Bool bNeedEditEngine = sal_False;
+ if ( !bNeedEditEngine && !bOutside )
+ {
+ switch (eOutHorJust)
+ {
+ case SVX_HOR_JUSTIFY_LEFT:
+ nJustPosX += (long) ( aVars.GetLeftTotal() * nPPTX );
+ break;
+ case SVX_HOR_JUSTIFY_RIGHT:
+ nJustPosX += nAvailWidth - aVars.GetTextSize().Width() -
+ (long) ( aVars.GetMargin()->GetRightMargin() * nPPTX );
+ bRightAdjusted = sal_True;
+ break;
+ case SVX_HOR_JUSTIFY_CENTER:
+ nJustPosX += ( nAvailWidth - aVars.GetTextSize().Width() +
+ (long) ( aVars.GetLeftTotal() * nPPTX ) -
+ (long) ( aVars.GetMargin()->GetRightMargin() * nPPTX ) ) / 2;
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ long nTestClipHeight = aVars.GetTextSize().Height();
+ switch (aVars.GetVerJust())
+ {
+ case SVX_VER_JUSTIFY_TOP:
+ {
+ long nTop = (long)( aVars.GetMargin()->GetTopMargin() * nPPTY );
+ nJustPosY += nTop;
+ nTestClipHeight += nTop;
+ }
+ break;
+ case SVX_VER_JUSTIFY_BOTTOM:
+ {
+ long nBot = (long)( aVars.GetMargin()->GetBottomMargin() * nPPTY );
+ nJustPosY += nOutHeight - aVars.GetTextSize().Height() - nBot;
+ nTestClipHeight += nBot;
+ }
+ break;
+ case SVX_VER_JUSTIFY_CENTER:
+ {
+ long nTop = (long)( aVars.GetMargin()->GetTopMargin() * nPPTY );
+ long nBot = (long)( aVars.GetMargin()->GetBottomMargin() * nPPTY );
+ nJustPosY += ( nOutHeight + nTop -
+ aVars.GetTextSize().Height() - nBot ) / 2;
+ nTestClipHeight += Abs( nTop - nBot );
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if ( nTestClipHeight > nOutHeight )
+ {
+ // kein vertikales Clipping beim Drucken von Zellen mit
+ // optimaler Hoehe, ausser bei Groesse in bedingter Formatierung
+ if ( eType != OUTTYPE_PRINTER ||
+ ( pDoc->GetRowFlags( nCellY, nTab ) & CR_MANUALSIZE ) ||
+ ( aVars.HasCondHeight() ) )
+ bVClip = sal_True;
+ }
+
+ if ( bHClip || bVClip )
+ {
+ // nur die betroffene Dimension clippen,
+ // damit bei nicht-proportionalem Resize nicht alle
+ // rechtsbuendigen Zahlen abgeschnitten werden:
+
+ if (!bHClip)
+ {
+ aAreaParam.maClipRect.Left() = nScrX;
+ aAreaParam.maClipRect.Right() = nScrX+nScrW;
+ }
+ if (!bVClip)
+ {
+ aAreaParam.maClipRect.Top() = nScrY;
+ aAreaParam.maClipRect.Bottom() = nScrY+nScrH;
+ }
+
+ // aClipRect is not used after SetClipRegion/IntersectClipRegion,
+ // so it can be modified here
+ if (bPixelToLogic)
+ aAreaParam.maClipRect = pRefDevice->PixelToLogic( aAreaParam.maClipRect );
+
+ if (bMetaFile)
+ {
+ pDev->Push();
+ pDev->IntersectClipRegion( aAreaParam.maClipRect );
+ }
+ else
+ pDev->SetClipRegion( Region( aAreaParam.maClipRect ) );
+ }
+
+ Point aURLStart( nJustPosX, nJustPosY ); // copy before modifying for orientation
+
+ switch (aVars.GetOrient())
+ {
+ case SVX_ORIENTATION_STANDARD:
+ nJustPosY += aVars.GetAscent();
+ break;
+ case SVX_ORIENTATION_TOPBOTTOM:
+ nJustPosX += aVars.GetTextSize().Width() - aVars.GetAscent();
+ break;
+ case SVX_ORIENTATION_BOTTOMTOP:
+ nJustPosY += aVars.GetTextSize().Height();
+ nJustPosX += aVars.GetAscent();
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ // When clipping, the visible part is now completely defined by the alignment,
+ // there's no more special handling to show the right part of RTL text.
+
+ Point aDrawTextPos( nJustPosX, nJustPosY );
+ if ( bPixelToLogic )
+ {
+ // undo text width adjustment in pixels
+ if (bRightAdjusted)
+ aDrawTextPos.X() += aVars.GetTextSize().Width();
+
+ aDrawTextPos = pRefDevice->PixelToLogic( aDrawTextPos );
+
+ // redo text width adjustment in logic units
+ if (bRightAdjusted)
+ aDrawTextPos.X() -= aVars.GetOriginalWidth();
+ }
+
+ // in Metafiles immer DrawTextArray, damit die Positionen mit
+ // aufgezeichnet werden (fuer nicht-proportionales Resize):
+
+ String aString = aVars.GetString();
+ if (bMetaFile || pFmtDevice != pDev || aZoomX != aZoomY)
+ {
+ sal_Int32* pDX = new sal_Int32[aString.Len()];
+ pFmtDevice->GetTextArray( aString, pDX );
+
+ if ( !pRefDevice->GetConnectMetaFile() ||
+ pRefDevice->GetOutDevType() == OUTDEV_PRINTER )
+ {
+ double fMul = GetStretch();
+ xub_StrLen nLen = aString.Len();
+ for (xub_StrLen i=0; i<nLen; i++)
+ pDX[i] = (long)(pDX[i] / fMul + 0.5);
+ }
+
+ pDev->DrawTextArray( aDrawTextPos, aString, pDX );
+ delete[] pDX;
+ }
+ else
+ pDev->DrawText( aDrawTextPos, aString );
+
+ if ( bHClip || bVClip )
+ {
+ if (bMetaFile)
+ pDev->Pop();
+ else
+ pDev->SetClipRegion();
+ }
+
+ // PDF: whole-cell hyperlink from formula?
+ sal_Bool bHasURL = pPDFData && pCell && pCell->GetCellType() == CELLTYPE_FORMULA &&
+ static_cast<ScFormulaCell*>(pCell)->IsHyperLinkCell();
+ if ( bHasURL )
+ {
+ Rectangle aURLRect( aURLStart, aVars.GetTextSize() );
+ lcl_DoHyperlinkResult( pDev, aURLRect, pCell );
+ }
+ }
+ }
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+ }
+ }
+ nPosY += pRowInfo[nArrY].nHeight;
+ }
+ if ( bProgress )
+ ScProgress::DeleteInterpretProgress();
+ pDoc->DisableIdle( bWasIdleDisabled );
+}
+
+// -------------------------------------------------------------------------------
+
+void lcl_ClearEdit( EditEngine& rEngine ) // Text und Attribute
+{
+ rEngine.SetUpdateMode( sal_False );
+
+ rEngine.SetText(EMPTY_STRING);
+ // keine Para-Attribute uebrigbehalten...
+ const SfxItemSet& rPara = rEngine.GetParaAttribs(0);
+ if (rPara.Count())
+ rEngine.SetParaAttribs( 0,
+ SfxItemSet( *rPara.GetPool(), rPara.GetRanges() ) );
+}
+
+sal_Bool lcl_SafeIsValue( ScBaseCell* pCell )
+{
+ if (!pCell)
+ return sal_False;
+
+ sal_Bool bRet = sal_False;
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE:
+ bRet = sal_True;
+ break;
+ case CELLTYPE_FORMULA:
+ {
+ ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
+ if ( pFCell->IsRunning() || pFCell->IsValue() )
+ bRet = sal_True;
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ return bRet;
+}
+
+void lcl_ScaleFonts( EditEngine& rEngine, long nPercent )
+{
+ sal_Bool bUpdateMode = rEngine.GetUpdateMode();
+ if ( bUpdateMode )
+ rEngine.SetUpdateMode( sal_False );
+
+ sal_uInt16 nParCount = rEngine.GetParagraphCount();
+ for (sal_uInt16 nPar=0; nPar<nParCount; nPar++)
+ {
+ SvUShorts aPortions;
+ rEngine.GetPortions( nPar, aPortions );
+
+ sal_uInt16 nPCount = aPortions.Count();
+ sal_uInt16 nStart = 0;
+ for ( sal_uInt16 nPos=0; nPos<nPCount; nPos++ )
+ {
+ sal_uInt16 nEnd = aPortions.GetObject( nPos );
+ ESelection aSel( nPar, nStart, nPar, nEnd );
+ SfxItemSet aAttribs = rEngine.GetAttribs( aSel );
+
+ long nWestern = static_cast<const SvxFontHeightItem&>(aAttribs.Get(EE_CHAR_FONTHEIGHT)).GetHeight();
+ long nCJK = static_cast<const SvxFontHeightItem&>(aAttribs.Get(EE_CHAR_FONTHEIGHT_CJK)).GetHeight();
+ long nCTL = static_cast<const SvxFontHeightItem&>(aAttribs.Get(EE_CHAR_FONTHEIGHT_CTL)).GetHeight();
+
+ nWestern = ( nWestern * nPercent ) / 100;
+ nCJK = ( nCJK * nPercent ) / 100;
+ nCTL = ( nCTL * nPercent ) / 100;
+
+ aAttribs.Put( SvxFontHeightItem( nWestern, 100, EE_CHAR_FONTHEIGHT ) );
+ aAttribs.Put( SvxFontHeightItem( nCJK, 100, EE_CHAR_FONTHEIGHT_CJK ) );
+ aAttribs.Put( SvxFontHeightItem( nCTL, 100, EE_CHAR_FONTHEIGHT_CTL ) );
+
+ rEngine.QuickSetAttribs( aAttribs, aSel ); //! remove paragraph attributes from aAttribs?
+
+ nStart = nEnd;
+ }
+ }
+
+ if ( bUpdateMode )
+ rEngine.SetUpdateMode( sal_True );
+}
+
+long lcl_GetEditSize( EditEngine& rEngine, sal_Bool bWidth, sal_Bool bSwap, long nAttrRotate )
+{
+ if ( bSwap )
+ bWidth = !bWidth;
+
+ if ( nAttrRotate )
+ {
+ long nRealWidth = (long) rEngine.CalcTextWidth();
+ long nRealHeight = rEngine.GetTextHeight();
+
+ // assuming standard mode, otherwise width isn't used
+
+ double nRealOrient = nAttrRotate * F_PI18000; // 1/100th degrees
+ double nAbsCos = fabs( cos( nRealOrient ) );
+ double nAbsSin = fabs( sin( nRealOrient ) );
+ if ( bWidth )
+ return (long) ( nRealWidth * nAbsCos + nRealHeight * nAbsSin );
+ else
+ return (long) ( nRealHeight * nAbsCos + nRealWidth * nAbsSin );
+ }
+ else if ( bWidth )
+ return (long) rEngine.CalcTextWidth();
+ else
+ return rEngine.GetTextHeight();
+}
+
+
+void ScOutputData::ShrinkEditEngine( EditEngine& rEngine, const Rectangle& rAlignRect,
+ long nLeftM, long nTopM, long nRightM, long nBottomM,
+ sal_Bool bWidth, sal_uInt16 nOrient, long nAttrRotate, sal_Bool bPixelToLogic,
+ long& rEngineWidth, long& rEngineHeight, long& rNeededPixel, bool& rLeftClip, bool& rRightClip )
+{
+ if ( !bWidth )
+ {
+ // vertical
+
+ long nScaleSize = bPixelToLogic ?
+ pRefDevice->LogicToPixel(Size(0,rEngineHeight)).Height() : rEngineHeight;
+
+ // Don't scale if it fits already.
+ // Allowing to extend into the margin, to avoid scaling at optimal height.
+ if ( nScaleSize <= rAlignRect.GetHeight() )
+ return;
+
+ sal_Bool bSwap = ( nOrient == SVX_ORIENTATION_TOPBOTTOM || nOrient == SVX_ORIENTATION_BOTTOMTOP );
+ long nAvailable = rAlignRect.GetHeight() - nTopM - nBottomM;
+ long nScale = ( nAvailable * 100 ) / nScaleSize;
+
+ lcl_ScaleFonts( rEngine, nScale );
+ rEngineHeight = lcl_GetEditSize( rEngine, sal_False, bSwap, nAttrRotate );
+ long nNewSize = bPixelToLogic ?
+ pRefDevice->LogicToPixel(Size(0,rEngineHeight)).Height() : rEngineHeight;
+
+ sal_uInt16 nShrinkAgain = 0;
+ while ( nNewSize > nAvailable && nShrinkAgain < SC_SHRINKAGAIN_MAX )
+ {
+ // further reduce, like in DrawStrings
+ lcl_ScaleFonts( rEngine, 90 ); // reduce by 10%
+ rEngineHeight = lcl_GetEditSize( rEngine, sal_False, bSwap, nAttrRotate );
+ nNewSize = bPixelToLogic ?
+ pRefDevice->LogicToPixel(Size(0,rEngineHeight)).Height() : rEngineHeight;
+ ++nShrinkAgain;
+ }
+
+ // sizes for further processing (alignment etc):
+ rEngineWidth = lcl_GetEditSize( rEngine, sal_True, bSwap, nAttrRotate );
+ long nPixelWidth = bPixelToLogic ?
+ pRefDevice->LogicToPixel(Size(rEngineWidth,0)).Width() : rEngineWidth;
+ rNeededPixel = nPixelWidth + nLeftM + nRightM;
+ }
+ else if ( rLeftClip || rRightClip )
+ {
+ // horizontal
+
+ long nAvailable = rAlignRect.GetWidth() - nLeftM - nRightM;
+ long nScaleSize = rNeededPixel - nLeftM - nRightM; // without margin
+
+ if ( nScaleSize <= nAvailable )
+ return;
+
+ long nScale = ( nAvailable * 100 ) / nScaleSize;
+
+ lcl_ScaleFonts( rEngine, nScale );
+ rEngineWidth = lcl_GetEditSize( rEngine, sal_True, sal_False, nAttrRotate );
+ long nNewSize = bPixelToLogic ?
+ pRefDevice->LogicToPixel(Size(rEngineWidth,0)).Width() : rEngineWidth;
+
+ sal_uInt16 nShrinkAgain = 0;
+ while ( nNewSize > nAvailable && nShrinkAgain < SC_SHRINKAGAIN_MAX )
+ {
+ // further reduce, like in DrawStrings
+ lcl_ScaleFonts( rEngine, 90 ); // reduce by 10%
+ rEngineWidth = lcl_GetEditSize( rEngine, sal_True, sal_False, nAttrRotate );
+ nNewSize = bPixelToLogic ?
+ pRefDevice->LogicToPixel(Size(rEngineWidth,0)).Width() : rEngineWidth;
+ ++nShrinkAgain;
+ }
+ if ( nNewSize <= nAvailable )
+ rLeftClip = rRightClip = sal_False;
+
+ // sizes for further processing (alignment etc):
+ rNeededPixel = nNewSize + nLeftM + nRightM;
+ rEngineHeight = lcl_GetEditSize( rEngine, sal_False, sal_False, nAttrRotate );
+ }
+}
+
+void ScOutputData::DrawEdit(sal_Bool bPixelToLogic)
+{
+ vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
+
+ Size aMinSize = pRefDevice->PixelToLogic(Size(0,100)); // erst darueber wird ausgegeben
+// sal_uInt32 nMinHeight = aMinSize.Height() / 200; // 1/2 Pixel
+
+ ScModule* pScMod = SC_MOD();
+ sal_Int32 nConfBackColor = pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
+ sal_Bool bCellContrast = bUseStyleColor &&
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode();
+
+ ScFieldEditEngine* pEngine = NULL;
+ sal_Bool bHyphenatorSet = sal_False;
+ const ScPatternAttr* pOldPattern = NULL;
+ const SfxItemSet* pOldCondSet = NULL;
+ ScBaseCell* pCell = NULL;
+
+ Size aRefOne = pRefDevice->PixelToLogic(Size(1,1));
+
+ long nInitPosX = nScrX;
+ if ( bLayoutRTL )
+ {
+#if 0
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ nInitPosX += nMirrorW - nOneX;
+#endif
+ nInitPosX += nMirrorW - 1;
+ }
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ //! store nLastContentCol as member!
+ SCCOL nLastContentCol = MAXCOL;
+ if ( nX2 < MAXCOL )
+ nLastContentCol = sal::static_int_cast<SCCOL>(
+ nLastContentCol - pDoc->GetEmptyLinesInBlock( nX2+1, nY1, nTab, MAXCOL, nY2, nTab, DIR_RIGHT ) );
+
+ long nRowPosY = nScrY;
+ for (SCSIZE nArrY=0; nArrY+1<nArrCount; nArrY++) // 0 fuer Reste von zusammengefassten
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+// long nCellHeight = (long) pThisRowInfo->nHeight;
+ if (nArrY==1) nRowPosY = nScrY; // vorher wird einzeln berechnet
+
+ if ( pThisRowInfo->bChanged || nArrY==0 )
+ {
+ long nPosX = 0;
+ for (SCCOL nX=0; nX<=nX2; nX++) // wegen Ueberhaengen
+ {
+ if (nX==nX1) nPosX = nInitPosX; // positions before nX1 are calculated individually
+
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+ if (pInfo->bEditEngine)
+ {
+ SCROW nY = pThisRowInfo->nRowNo;
+
+ SCCOL nCellX = nX; // position where the cell really starts
+ SCROW nCellY = nY;
+ sal_Bool bDoCell = sal_False;
+
+ long nPosY = nRowPosY;
+ if ( nArrY == 0 )
+ {
+ nPosY = nScrY;
+ nY = pRowInfo[1].nRowNo;
+ SCCOL nOverX; // start of the merged cells
+ SCROW nOverY;
+ if (GetMergeOrigin( nX,nY, 1, nOverX,nOverY, sal_True ))
+ {
+ nCellX = nOverX;
+ nCellY = nOverY;
+ bDoCell = sal_True;
+ }
+ }
+ else if ( nX == nX2 && !pThisRowInfo->pCellInfo[nX+1].pCell )
+ {
+ // Rest of a long text further to the right?
+
+ SCCOL nTempX=nX;
+ while (nTempX < nLastContentCol && IsEmptyCellText( pThisRowInfo, nTempX, nY ))
+ ++nTempX;
+
+ if ( nTempX > nX &&
+ !IsEmptyCellText( pThisRowInfo, nTempX, nY ) &&
+ !pDoc->HasAttrib( nTempX,nY,nTab, nX,nY,nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+ {
+ nCellX = nTempX;
+ bDoCell = sal_True;
+ }
+ }
+ else
+ {
+ bDoCell = sal_True;
+ }
+
+ if ( bDoCell && bEditMode && nCellX == nEditCol && nCellY == nEditRow )
+ bDoCell = sal_False;
+
+ const ScPatternAttr* pPattern = NULL;
+ const SfxItemSet* pCondSet = NULL;
+ if (bDoCell)
+ {
+ if ( nCellY == nY && nCellX >= nX1 && nCellX <= nX2 &&
+ !pDoc->ColHidden(nCellX, nTab) )
+ {
+ CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nCellX+1];
+ pPattern = rCellInfo.pPatternAttr;
+ pCondSet = rCellInfo.pConditionSet;
+ pCell = rCellInfo.pCell;
+ }
+ else // get from document
+ {
+ pPattern = pDoc->GetPattern( nCellX, nCellY, nTab );
+ pCondSet = pDoc->GetCondResult( nCellX, nCellY, nTab );
+ GetVisibleCell( nCellX, nCellY, nTab, pCell );
+ }
+ if ( !pCell )
+ bDoCell = sal_False;
+ }
+ if (bDoCell)
+ {
+ sal_Bool bHidden = sal_False;
+
+ //
+ // Create EditEngine
+ //
+
+ if (!pEngine)
+ {
+ // Ein RefDevice muss auf jeden Fall gesetzt werden,
+ // sonst legt sich die EditEngine ein VirtualDevice an!
+ pEngine = new ScFieldEditEngine( pDoc->GetEnginePool() );
+ pEngine->SetUpdateMode( sal_False );
+ pEngine->SetRefDevice( pFmtDevice ); // always set
+ sal_uLong nCtrl = pEngine->GetControlWord();
+ if ( bShowSpellErrors )
+ nCtrl |= EE_CNTRL_ONLINESPELLING;
+ if ( eType == OUTTYPE_PRINTER )
+ nCtrl &= ~EE_CNTRL_MARKFIELDS;
+ pEngine->SetControlWord( nCtrl );
+ pEngine->SetForbiddenCharsTable( pDoc->GetForbiddenCharacters() );
+ pEngine->SetAsianCompressionMode( pDoc->GetAsianCompression() );
+ pEngine->SetKernAsianPunctuation( pDoc->GetAsianKerning() );
+ pEngine->EnableAutoColor( bUseStyleColor );
+ pEngine->SetDefaultHorizontalTextDirection(
+ (EEHorizontalTextDirection)pDoc->GetEditTextDirection( nTab ) );
+ }
+ else
+ lcl_ClearEdit( *pEngine ); // also calls SetUpdateMode(sal_False)
+
+
+ sal_Bool bCellIsValue = lcl_SafeIsValue(pCell);
+
+ SvxCellHorJustify eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
+ pPattern->GetItem(ATTR_HOR_JUSTIFY, pCondSet)).GetValue();
+ sal_Bool bBreak = ( eHorJust == SVX_HOR_JUSTIFY_BLOCK ) ||
+ ((const SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK, pCondSet)).GetValue();
+ sal_Bool bRepeat = ( eHorJust == SVX_HOR_JUSTIFY_REPEAT && !bBreak );
+ sal_Bool bShrink = !bBreak && !bRepeat && static_cast<const SfxBoolItem&>
+ (pPattern->GetItem( ATTR_SHRINKTOFIT, pCondSet )).GetValue();
+ SvxCellOrientation eOrient = pPattern->GetCellOrientation( pCondSet );
+ long nAttrRotate = ((const SfxInt32Item&)pPattern->
+ GetItem(ATTR_ROTATE_VALUE, pCondSet)).GetValue();
+ if ( eHorJust == SVX_HOR_JUSTIFY_REPEAT )
+ {
+ // ignore orientation/rotation if "repeat" is active
+ eOrient = SVX_ORIENTATION_STANDARD;
+ nAttrRotate = 0;
+
+ // #i31843# "repeat" with "line breaks" is treated as default alignment
+ // (but rotation is still disabled)
+ if ( bBreak )
+ eHorJust = SVX_HOR_JUSTIFY_STANDARD;
+ }
+ if ( eOrient==SVX_ORIENTATION_STANDARD && nAttrRotate )
+ {
+ //! Flag setzen, um die Zelle in DrawRotated wiederzufinden ?
+ //! (oder Flag schon bei DrawBackground, dann hier keine Abfrage)
+ bHidden = sal_True; // gedreht wird getrennt ausgegeben
+ }
+
+ sal_Bool bAsianVertical = ( eOrient == SVX_ORIENTATION_STACKED &&
+ ((const SfxBoolItem&)pPattern->GetItem( ATTR_VERTICAL_ASIAN, pCondSet )).GetValue() );
+ if ( bAsianVertical )
+ {
+ // in asian mode, use EditEngine::SetVertical instead of EE_CNTRL_ONECHARPERLINE
+ eOrient = SVX_ORIENTATION_STANDARD;
+ // default alignment for asian vertical mode is top-right
+ if ( eHorJust == SVX_HOR_JUSTIFY_STANDARD )
+ eHorJust = SVX_HOR_JUSTIFY_RIGHT;
+ }
+
+
+
+ SvxCellHorJustify eOutHorJust =
+ ( eHorJust != SVX_HOR_JUSTIFY_STANDARD ) ? eHorJust :
+ ( bCellIsValue ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT );
+
+ if ( eOutHorJust == SVX_HOR_JUSTIFY_BLOCK || eOutHorJust == SVX_HOR_JUSTIFY_REPEAT )
+ eOutHorJust = SVX_HOR_JUSTIFY_LEFT; // repeat is not yet implemented
+
+
+//! if ( !bHidden && eType == OUTTYPE_PRINTER &&
+//! pDev->GetOutDevType() == OUTDEV_WINDOW &&
+//! ((const SvxFontHeightItem&)pPattern->
+//! GetItem(ATTR_FONT_HEIGHT)).GetHeight() <= nMinHeight )
+//! {
+//! Point aPos( nStartX, nStartY );
+//! pDev->DrawPixel( aPos,
+//! ((const SvxColorItem&)pPattern->
+//! GetItem( ATTR_FONT_COLOR )).GetValue() );
+//! bHidden = sal_True;
+//! }
+
+ if (!bHidden)
+ {
+ //! mirror margin values for RTL?
+ //! move margin down to after final GetOutputArea call
+
+ const SvxMarginItem* pMargin = (const SvxMarginItem*)
+ &pPattern->GetItem(ATTR_MARGIN, pCondSet);
+ sal_uInt16 nIndent = 0;
+ if ( eHorJust == SVX_HOR_JUSTIFY_LEFT )
+ nIndent = ((const SfxUInt16Item&)pPattern->
+ GetItem(ATTR_INDENT, pCondSet)).GetValue();
+
+ long nLeftM = (long) ( (pMargin->GetLeftMargin() + nIndent) * nPPTX );
+ long nTopM = (long) ( pMargin->GetTopMargin() * nPPTY );
+ long nRightM = (long) ( pMargin->GetRightMargin() * nPPTX );
+ long nBottomM = (long) ( pMargin->GetBottomMargin() * nPPTY );
+
+ SCCOL nXForPos = nX;
+ if ( nXForPos < nX1 )
+ {
+ nXForPos = nX1;
+ nPosX = nInitPosX;
+ }
+ SCSIZE nArrYForPos = nArrY;
+ if ( nArrYForPos < 1 )
+ {
+ nArrYForPos = 1;
+ nPosY = nScrY;
+ }
+
+ OutputAreaParam aAreaParam;
+
+ //
+ // Initial page size - large for normal text, cell size for automatic line breaks
+ //
+
+ Size aPaperSize = Size( 1000000, 1000000 );
+ if ( bBreak || eOrient == SVX_ORIENTATION_STACKED || bAsianVertical )
+ {
+ //! also stacked, AsianVertical
+
+ // call GetOutputArea with nNeeded=0, to get only the cell width
+
+ //! handle nArrY == 0
+ GetOutputArea( nXForPos, nArrYForPos, nPosX, nPosY, nCellX, nCellY, 0,
+ *pPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
+ bCellIsValue, true, false, aAreaParam );
+
+ //! special ScEditUtil handling if formatting for printer
+
+ if ( eOrient == SVX_ORIENTATION_TOPBOTTOM || eOrient == SVX_ORIENTATION_BOTTOMTOP )
+ aPaperSize.Width() = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
+ else
+ aPaperSize.Width() = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM;
+
+ if (bAsianVertical && bBreak)
+ {
+ // add some extra height (default margin value) for safety
+ // as long as GetEditArea isn't used below
+ long nExtraHeight = (long)( 20 * nPPTY );
+ aPaperSize.Height() = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM + nExtraHeight;
+ }
+ }
+ if (bPixelToLogic)
+ {
+ Size aLogicSize = pRefDevice->PixelToLogic(aPaperSize);
+ if ( bBreak && !bAsianVertical && pRefDevice != pFmtDevice )
+ {
+ // #i85342# screen display and formatting for printer,
+ // use same GetEditArea call as in ScViewData::SetEditEngine
+
+ Fraction aFract(1,1);
+ Rectangle aUtilRect = ScEditUtil( pDoc, nCellX, nCellY, nTab, Point(0,0), pFmtDevice,
+ HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( pPattern, sal_False );
+ aLogicSize.Width() = aUtilRect.GetWidth();
+ }
+ pEngine->SetPaperSize(aLogicSize);
+ }
+ else
+ pEngine->SetPaperSize(aPaperSize);
+
+ //
+ // Fill the EditEngine (cell attributes and text)
+ //
+
+ SvxCellVerJustify eVerJust = (SvxCellVerJustify)((const SvxVerJustifyItem&)
+ pPattern->GetItem(ATTR_VER_JUSTIFY, pCondSet)).GetValue();
+
+ // default alignment for asian vertical mode is top-right
+ if ( bAsianVertical && eVerJust == SVX_VER_JUSTIFY_STANDARD )
+ eVerJust = SVX_VER_JUSTIFY_TOP;
+
+ // syntax highlighting mode is ignored here
+ // StringDiffer doesn't look at hyphenate, language items
+ if ( pPattern != pOldPattern || pCondSet != pOldCondSet )
+ {
+ SfxItemSet* pSet = new SfxItemSet( pEngine->GetEmptyItemSet() );
+ pPattern->FillEditItemSet( pSet, pCondSet );
+
+ pEngine->SetDefaults( pSet );
+ pOldPattern = pPattern;
+ pOldCondSet = pCondSet;
+
+ sal_uLong nControl = pEngine->GetControlWord();
+ if (eOrient==SVX_ORIENTATION_STACKED)
+ nControl |= EE_CNTRL_ONECHARPERLINE;
+ else
+ nControl &= ~EE_CNTRL_ONECHARPERLINE;
+ pEngine->SetControlWord( nControl );
+
+ if ( !bHyphenatorSet && ((const SfxBoolItem&)pSet->Get(EE_PARA_HYPHENATE)).GetValue() )
+ {
+ // set hyphenator the first time it is needed
+ com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() );
+ pEngine->SetHyphenator( xXHyphenator );
+ bHyphenatorSet = sal_True;
+ }
+
+ Color aBackCol = ((const SvxBrushItem&)
+ pPattern->GetItem( ATTR_BACKGROUND, pCondSet )).GetColor();
+ if ( bUseStyleColor && ( aBackCol.GetTransparency() > 0 || bCellContrast ) )
+ aBackCol.SetColor( nConfBackColor );
+ pEngine->SetBackgroundColor( aBackCol );
+ }
+
+ // horizontal alignment now may depend on cell content
+ // (for values with number formats with mixed script types)
+ // -> always set adjustment
+
+ SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
+ if (eOrient==SVX_ORIENTATION_STACKED)
+ eSvxAdjust = SVX_ADJUST_CENTER;
+ else if (bBreak)
+ {
+ if (eOrient==SVX_ORIENTATION_STANDARD && !bAsianVertical)
+ switch (eHorJust)
+ {
+ case SVX_HOR_JUSTIFY_STANDARD:
+ eSvxAdjust = bCellIsValue ? SVX_ADJUST_RIGHT : SVX_ADJUST_LEFT;
+ break;
+ case SVX_HOR_JUSTIFY_LEFT:
+ case SVX_HOR_JUSTIFY_REPEAT: // nicht implementiert
+ eSvxAdjust = SVX_ADJUST_LEFT;
+ break;
+ case SVX_HOR_JUSTIFY_RIGHT:
+ eSvxAdjust = SVX_ADJUST_RIGHT;
+ break;
+ case SVX_HOR_JUSTIFY_CENTER:
+ eSvxAdjust = SVX_ADJUST_CENTER;
+ break;
+ case SVX_HOR_JUSTIFY_BLOCK:
+ eSvxAdjust = SVX_ADJUST_BLOCK;
+ break;
+ }
+ else
+ switch (eVerJust)
+ {
+ case SVX_VER_JUSTIFY_TOP:
+ eSvxAdjust = (eOrient==SVX_ORIENTATION_TOPBOTTOM || bAsianVertical) ?
+ SVX_ADJUST_LEFT : SVX_ADJUST_RIGHT;
+ break;
+ case SVX_VER_JUSTIFY_CENTER:
+ eSvxAdjust = SVX_ADJUST_CENTER;
+ break;
+ case SVX_VER_JUSTIFY_BOTTOM:
+ case SVX_HOR_JUSTIFY_STANDARD:
+ eSvxAdjust = (eOrient==SVX_ORIENTATION_TOPBOTTOM || bAsianVertical) ?
+ SVX_ADJUST_RIGHT : SVX_ADJUST_LEFT;
+ break;
+ }
+ }
+ pEngine->SetDefaultItem( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
+
+ // Read content from cell
+
+ sal_Bool bWrapFields = sal_False;
+ if (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_EDIT)
+ {
+ const EditTextObject* pData;
+ ((ScEditCell*)pCell)->GetData(pData);
+
+ if (pData)
+ {
+ pEngine->SetText(*pData);
+
+ if ( bBreak && !bAsianVertical && pData->HasField() )
+ {
+ // Fields aren't wrapped, so clipping is enabled to prevent
+ // a field from being drawn beyond the cell size
+
+ bWrapFields = sal_True;
+ }
+ }
+ else
+ {
+ DBG_ERROR("pData == 0");
+ }
+ }
+ else
+ {
+ sal_uLong nFormat = pPattern->GetNumberFormat(
+ pDoc->GetFormatTable(), pCondSet );
+ String aString;
+ Color* pColor;
+ ScCellFormat::GetString( pCell,
+ nFormat,aString, &pColor,
+ *pDoc->GetFormatTable(),
+ bShowNullValues,
+ bShowFormulas,
+ ftCheck );
+
+ pEngine->SetText(aString);
+ if ( pColor && !bSyntaxMode && !( bUseStyleColor && bForceAutoColor ) )
+ lcl_SetEditColor( *pEngine, *pColor );
+ }
+
+ if ( bSyntaxMode )
+ SetEditSyntaxColor( *pEngine, pCell );
+ else if ( bUseStyleColor && bForceAutoColor )
+ lcl_SetEditColor( *pEngine, COL_AUTO ); //! or have a flag at EditEngine
+ }
+ else
+ {
+ DBG_ERROR("pCell == NULL");
+ }
+
+ pEngine->SetVertical( bAsianVertical );
+ pEngine->SetUpdateMode( sal_True ); // after SetText, before CalcTextWidth/GetTextHeight
+
+ //
+ // Get final output area using the calculated width
+ //
+
+ long nEngineWidth;
+ if ( bBreak && eOrient != SVX_ORIENTATION_STACKED && !bAsianVertical )
+ nEngineWidth = 0;
+ else
+ nEngineWidth = (long) pEngine->CalcTextWidth();
+ long nEngineHeight = pEngine->GetTextHeight();
+
+ if (eOrient != SVX_ORIENTATION_STANDARD &&
+ eOrient != SVX_ORIENTATION_STACKED)
+ {
+ long nTemp = nEngineWidth;
+ nEngineWidth = nEngineHeight;
+ nEngineHeight = nTemp;
+ }
+
+ if (eOrient == SVX_ORIENTATION_STACKED)
+ nEngineWidth = nEngineWidth * 11 / 10;
+
+ long nNeededPixel = nEngineWidth;
+ if (bPixelToLogic)
+ nNeededPixel = pRefDevice->LogicToPixel(Size(nNeededPixel,0)).Width();
+ nNeededPixel += nLeftM + nRightM;
+
+ if ( ( !bBreak && eOrient != SVX_ORIENTATION_STACKED ) || bAsianVertical || bShrink )
+ {
+ // for break, the first GetOutputArea call is sufficient
+ GetOutputArea( nXForPos, nArrYForPos, nPosX, nPosY, nCellX, nCellY, nNeededPixel,
+ *pPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
+ bCellIsValue || bRepeat || bShrink, false, false, aAreaParam );
+
+ if ( bShrink )
+ {
+ sal_Bool bWidth = ( eOrient == SVX_ORIENTATION_STANDARD && !bAsianVertical );
+ ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect,
+ nLeftM, nTopM, nRightM, nBottomM, bWidth,
+ sal::static_int_cast<sal_uInt16>(eOrient), 0, bPixelToLogic,
+ nEngineWidth, nEngineHeight, nNeededPixel,
+ aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
+ }
+
+ if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip && pEngine->GetParagraphCount() == 1 )
+ {
+ // First check if twice the space for the formatted text is available
+ // (otherwise just keep it unchanged).
+
+ long nFormatted = nNeededPixel - nLeftM - nRightM; // without margin
+ long nAvailable = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM;
+ if ( nAvailable >= 2 * nFormatted )
+ {
+ // "repeat" is handled with unformatted text (for performance reasons)
+ String aCellStr = pEngine->GetText();
+ pEngine->SetText( aCellStr );
+
+ long nRepeatSize = (long) pEngine->CalcTextWidth();
+ if (bPixelToLogic)
+ nRepeatSize = pRefDevice->LogicToPixel(Size(nRepeatSize,0)).Width();
+ if ( pFmtDevice != pRefDevice )
+ ++nRepeatSize;
+ if ( nRepeatSize > 0 )
+ {
+ long nRepeatCount = nAvailable / nRepeatSize;
+ if ( nRepeatCount > 1 )
+ {
+ String aRepeated = aCellStr;
+ for ( long nRepeat = 1; nRepeat < nRepeatCount; nRepeat++ )
+ aRepeated.Append( aCellStr );
+ pEngine->SetText( aRepeated );
+
+ nEngineHeight = pEngine->GetTextHeight();
+ nEngineWidth = (long) pEngine->CalcTextWidth();
+ if (bPixelToLogic)
+ nNeededPixel = pRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
+ else
+ nNeededPixel = nEngineWidth;
+ nNeededPixel += nLeftM + nRightM;
+ }
+ }
+ }
+ }
+
+ if ( bCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) )
+ {
+ pEngine->SetText( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("###")) );
+ nEngineWidth = (long) pEngine->CalcTextWidth();
+ if (bPixelToLogic)
+ nNeededPixel = pRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width();
+ else
+ nNeededPixel = nEngineWidth;
+ nNeededPixel += nLeftM + nRightM;
+
+ // No clip marks if "###" doesn't fit (same as in DrawStrings)
+ }
+
+ if ( eOutHorJust != SVX_HOR_JUSTIFY_LEFT && eOrient == SVX_ORIENTATION_STANDARD )
+ {
+ aPaperSize.Width() = nNeededPixel + 1;
+ if (bPixelToLogic)
+ pEngine->SetPaperSize(pRefDevice->PixelToLogic(aPaperSize));
+ else
+ pEngine->SetPaperSize(aPaperSize);
+ }
+ }
+
+ long nStartX = aAreaParam.maAlignRect.Left();
+ long nStartY = aAreaParam.maAlignRect.Top();
+ long nCellWidth = aAreaParam.maAlignRect.GetWidth();
+ long nOutWidth = nCellWidth - 1 - nLeftM - nRightM;
+ long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM;
+
+ if ( bBreak || eOrient != SVX_ORIENTATION_STANDARD || bAsianVertical )
+ {
+ // text with automatic breaks is aligned only within the
+ // edit engine's paper size, the output of the whole area
+ // is always left-aligned
+
+ nStartX += nLeftM;
+ }
+ else
+ {
+ if ( eOutHorJust == SVX_HOR_JUSTIFY_RIGHT )
+ nStartX -= nNeededPixel - nCellWidth + nRightM + 1;
+ else if ( eOutHorJust == SVX_HOR_JUSTIFY_CENTER )
+ nStartX -= ( nNeededPixel - nCellWidth + nRightM + 1 - nLeftM ) / 2;
+ else
+ nStartX += nLeftM;
+ }
+
+ sal_Bool bOutside = ( aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW );
+ if ( aAreaParam.maClipRect.Left() < nScrX )
+ {
+ aAreaParam.maClipRect.Left() = nScrX;
+ aAreaParam.mbLeftClip = true;
+ }
+ if ( aAreaParam.maClipRect.Right() > nScrX + nScrW )
+ {
+ aAreaParam.maClipRect.Right() = nScrX + nScrW; //! minus one?
+ aAreaParam.mbRightClip = true;
+ }
+
+ if ( !bHidden && !bOutside )
+ {
+ bool bClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip;
+ sal_Bool bSimClip = sal_False;
+
+ if ( bWrapFields )
+ {
+ // Fields in a cell with automatic breaks: clip to cell width
+ bClip = sal_True;
+ }
+
+ if ( aAreaParam.maClipRect.Top() < nScrY )
+ {
+ aAreaParam.maClipRect.Top() = nScrY;
+ bClip = sal_True;
+ }
+ if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH )
+ {
+ aAreaParam.maClipRect.Bottom() = nScrY + nScrH; //! minus one?
+ bClip = sal_True;
+ }
+
+ Size aCellSize; // output area, excluding margins, in logical units
+ if (bPixelToLogic)
+ aCellSize = pRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
+ else
+ aCellSize = Size( nOutWidth, nOutHeight );
+
+ if ( nEngineHeight >= aCellSize.Height() + aRefOne.Height() )
+ {
+ const ScMergeAttr* pMerge =
+ (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
+ sal_Bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
+
+ // Don't clip for text height when printing rows with optimal height,
+ // except when font size is from conditional formatting.
+ //! Allow clipping when vertically merged?
+ if ( eType != OUTTYPE_PRINTER ||
+ ( pDoc->GetRowFlags( nCellY, nTab ) & CR_MANUALSIZE ) ||
+ ( pCondSet && SFX_ITEM_SET ==
+ pCondSet->GetItemState(ATTR_FONT_HEIGHT, sal_True) ) )
+ bClip = sal_True;
+ else
+ bSimClip = sal_True;
+
+ // Show clip marks if height is at least 5pt too small and
+ // there are several lines of text.
+ // Not for asian vertical text, because that would interfere
+ // with the default right position of the text.
+ // Only with automatic line breaks, to avoid having to find
+ // the cells with the horizontal end of the text again.
+ if ( nEngineHeight - aCellSize.Height() > 100 &&
+ ( bBreak || eOrient == SVX_ORIENTATION_STACKED ) &&
+ !bAsianVertical && bMarkClipped &&
+ ( pEngine->GetParagraphCount() > 1 || pEngine->GetLineCount(0) > 1 ) )
+ {
+ CellInfo* pClipMarkCell = NULL;
+ if ( bMerged )
+ {
+ // anywhere in the merged area...
+ SCCOL nClipX = ( nX < nX1 ) ? nX1 : nX;
+ pClipMarkCell = &pRowInfo[(nArrY != 0) ? nArrY : 1].pCellInfo[nClipX+1];
+ }
+ else
+ pClipMarkCell = &pThisRowInfo->pCellInfo[nX+1];
+
+ pClipMarkCell->nClipMark |= SC_CLIPMARK_RIGHT; //! also allow left?
+ bAnyClipped = sal_True;
+
+ long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX );
+ if ( aAreaParam.maClipRect.Right() - nMarkPixel > aAreaParam.maClipRect.Left() )
+ aAreaParam.maClipRect.Right() -= nMarkPixel;
+ }
+ }
+
+#if 0
+ long nClipStartY = nStartY;
+ if (nArrY==0 || bVisChanged)
+ {
+ if ( nClipStartY < nRowPosY )
+ {
+ long nDif = nRowPosY - nClipStartY;
+ bClip = sal_True;
+ nClipStartY = nRowPosY;
+ aClipSize.Height() -= nDif;
+ }
+ }
+#endif
+
+ Rectangle aLogicClip;
+ if (bClip || bSimClip)
+ {
+ // Clip marks are already handled in GetOutputArea
+
+ if (bPixelToLogic)
+ aLogicClip = pRefDevice->PixelToLogic( aAreaParam.maClipRect );
+ else
+ aLogicClip = aAreaParam.maClipRect;
+
+ if (bClip) // bei bSimClip nur aClipRect initialisieren
+ {
+ if (bMetaFile)
+ {
+ pDev->Push();
+ pDev->IntersectClipRegion( aLogicClip );
+ }
+ else
+ pDev->SetClipRegion( Region( aLogicClip ) );
+ }
+ }
+
+ Point aLogicStart;
+ if (bPixelToLogic)
+ aLogicStart = pRefDevice->PixelToLogic( Point(nStartX,nStartY) );
+ else
+ aLogicStart = Point(nStartX, nStartY);
+ if ( eOrient!=SVX_ORIENTATION_STANDARD || bAsianVertical || !bBreak )
+ {
+ long nAvailWidth = aCellSize.Width();
+ // space for AutoFilter is already handled in GetOutputArea
+
+ // horizontal alignment
+
+ if (eOrient==SVX_ORIENTATION_STANDARD && !bAsianVertical)
+ {
+ if (eHorJust==SVX_HOR_JUSTIFY_RIGHT ||
+ eHorJust==SVX_HOR_JUSTIFY_CENTER ||
+ (eHorJust==SVX_HOR_JUSTIFY_STANDARD && bCellIsValue) )
+ {
+ pEngine->SetUpdateMode( sal_False );
+
+ SvxAdjust eEditAdjust =
+ (eHorJust==SVX_HOR_JUSTIFY_CENTER) ?
+ SVX_ADJUST_CENTER : SVX_ADJUST_RIGHT;
+ pEngine->SetDefaultItem(
+ SvxAdjustItem( eEditAdjust, EE_PARA_JUST ) );
+
+ // #55142# reset adjustment for the next cell
+ pOldPattern = NULL;
+
+ pEngine->SetUpdateMode( sal_True );
+ }
+ }
+ else
+ {
+ if (eHorJust==SVX_HOR_JUSTIFY_RIGHT)
+ aLogicStart.X() += nAvailWidth - nEngineWidth;
+ else if (eHorJust==SVX_HOR_JUSTIFY_CENTER)
+ aLogicStart.X() += (nAvailWidth - nEngineWidth) / 2;
+ }
+ }
+
+ if ( bAsianVertical )
+ {
+ // paper size is subtracted below
+ aLogicStart.X() += nEngineWidth;
+ }
+
+ if ( ( bAsianVertical || eOrient == SVX_ORIENTATION_TOPBOTTOM ||
+ eOrient == SVX_ORIENTATION_BOTTOMTOP ) && bBreak )
+ {
+ // vertical adjustment is within the EditEngine
+ if (bPixelToLogic)
+ aLogicStart.Y() += pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
+ else
+ aLogicStart.Y() += nTopM;
+ }
+
+ if ( ( eOrient==SVX_ORIENTATION_STANDARD && !bAsianVertical ) ||
+ eOrient==SVX_ORIENTATION_STACKED || !bBreak )
+ {
+ if (eVerJust==SVX_VER_JUSTIFY_BOTTOM ||
+ eVerJust==SVX_VER_JUSTIFY_STANDARD)
+ {
+ //! if pRefDevice != pFmtDevice, keep heights in logic units,
+ //! only converting margin?
+
+ if (bPixelToLogic)
+ aLogicStart.Y() += pRefDevice->PixelToLogic( Size(0, nTopM +
+ pRefDevice->LogicToPixel(aCellSize).Height() -
+ pRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height()
+ )).Height();
+ else
+ aLogicStart.Y() += nTopM + aCellSize.Height() - nEngineHeight;
+ }
+ else if (eVerJust==SVX_VER_JUSTIFY_CENTER)
+ {
+ if (bPixelToLogic)
+ aLogicStart.Y() += pRefDevice->PixelToLogic( Size(0, nTopM + (
+ pRefDevice->LogicToPixel(aCellSize).Height() -
+ pRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height() )
+ / 2)).Height();
+ else
+ aLogicStart.Y() += nTopM + (aCellSize.Height() - nEngineHeight) / 2;
+ }
+ else // top
+ {
+ if (bPixelToLogic)
+ aLogicStart.Y() += pRefDevice->PixelToLogic(Size(0,nTopM)).Height();
+ else
+ aLogicStart.Y() += nTopM;
+ }
+ }
+
+ Point aURLStart = aLogicStart; // copy before modifying for orientation
+
+ short nOriVal = 0;
+ if (eOrient==SVX_ORIENTATION_TOPBOTTOM)
+ {
+ // nOriVal = -900;
+ nOriVal = 2700;
+ aLogicStart.X() += nEngineWidth;
+ }
+ else if (eOrient==SVX_ORIENTATION_BOTTOMTOP)
+ {
+ nOriVal = 900;
+ aLogicStart.Y() += bBreak ? pEngine->GetPaperSize().Width() :
+ nEngineHeight;
+ }
+ else if (eOrient==SVX_ORIENTATION_STACKED)
+ {
+ Size aPaperLogic = pEngine->GetPaperSize();
+ aPaperLogic.Width() = nEngineWidth;
+ pEngine->SetPaperSize(aPaperLogic);
+ }
+
+ if ( pEngine->IsRightToLeft( 0 ) )
+ {
+ // For right-to-left, EditEngine always calculates its lines
+ // beginning from the right edge, but EditLine::nStartPosX is
+ // of sal_uInt16 type, so the PaperSize must be limited to USHRT_MAX.
+ Size aLogicPaper = pEngine->GetPaperSize();
+ if ( aLogicPaper.Width() > USHRT_MAX )
+ {
+ aLogicPaper.Width() = USHRT_MAX;
+ pEngine->SetPaperSize(aLogicPaper);
+ }
+ }
+
+ // bMoveClipped handling has been replaced by complete alignment
+ // handling (also extending to the left).
+
+ if ( bSimClip && !nOriVal && !bAsianVertical )
+ {
+ // kein hartes Clipping, aber nur die betroffenen
+ // Zeilen ausgeben
+
+ Point aDocStart = aLogicClip.TopLeft();
+ aDocStart -= aLogicStart;
+ pEngine->Draw( pDev, aLogicClip, aDocStart, sal_False );
+ }
+ else
+ {
+ if (bAsianVertical)
+ {
+ // with SetVertical, the start position is top left of
+ // the whole output area, not the text itself
+ aLogicStart.X() -= pEngine->GetPaperSize().Width();
+ }
+ pEngine->Draw( pDev, aLogicStart, nOriVal );
+ }
+
+ if (bClip)
+ {
+ if (bMetaFile)
+ pDev->Pop();
+ else
+ pDev->SetClipRegion();
+ }
+
+ // PDF: whole-cell hyperlink from formula?
+ sal_Bool bHasURL = pPDFData && pCell && pCell->GetCellType() == CELLTYPE_FORMULA &&
+ static_cast<ScFormulaCell*>(pCell)->IsHyperLinkCell();
+ if ( bHasURL )
+ {
+ long nURLWidth = (long) pEngine->CalcTextWidth();
+ long nURLHeight = pEngine->GetTextHeight();
+ if ( bBreak )
+ {
+ Size aPaper = pEngine->GetPaperSize();
+ if ( bAsianVertical )
+ nURLHeight = aPaper.Height();
+ else
+ nURLWidth = aPaper.Width();
+ }
+ if ( eOrient == SVX_ORIENTATION_TOPBOTTOM || eOrient == SVX_ORIENTATION_BOTTOMTOP )
+ std::swap( nURLWidth, nURLHeight );
+ else if ( bAsianVertical )
+ aURLStart.X() -= nURLWidth;
+
+ Rectangle aURLRect( aURLStart, Size( nURLWidth, nURLHeight ) );
+ lcl_DoHyperlinkResult( pDev, aURLRect, pCell );
+ }
+ }
+ }
+ }
+ }
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+ }
+ }
+ nRowPosY += pRowInfo[nArrY].nHeight;
+ }
+
+ delete pEngine;
+
+ if (bAnyRotated)
+ DrawRotated(bPixelToLogic); //! von aussen rufen ?
+}
+
+// -------------------------------------------------------------------------------
+
+void ScOutputData::DrawRotated(sal_Bool bPixelToLogic)
+{
+ //! nRotMax speichern
+ SCCOL nRotMax = nX2;
+ for (SCSIZE nRotY=0; nRotY<nArrCount; nRotY++)
+ if (pRowInfo[nRotY].nRotMaxCol != SC_ROTMAX_NONE && pRowInfo[nRotY].nRotMaxCol > nRotMax)
+ nRotMax = pRowInfo[nRotY].nRotMaxCol;
+
+
+ ScModule* pScMod = SC_MOD();
+ sal_Int32 nConfBackColor = pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
+ sal_Bool bCellContrast = bUseStyleColor &&
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode();
+
+ ScFieldEditEngine* pEngine = NULL;
+ sal_Bool bHyphenatorSet = sal_False;
+ const ScPatternAttr* pPattern;
+ const SfxItemSet* pCondSet;
+ const ScPatternAttr* pOldPattern = NULL;
+ const SfxItemSet* pOldCondSet = NULL;
+ ScBaseCell* pCell = NULL;
+
+ long nInitPosX = nScrX;
+ if ( bLayoutRTL )
+ {
+#if 0
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ nInitPosX += nMirrorW - nOneX;
+#endif
+ nInitPosX += nMirrorW - 1;
+ }
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ long nRowPosY = nScrY;
+ for (SCSIZE nArrY=0; nArrY+1<nArrCount; nArrY++) // 0 fuer Reste von zusammengefassten
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+ long nCellHeight = (long) pThisRowInfo->nHeight;
+ if (nArrY==1) nRowPosY = nScrY; // vorher wird einzeln berechnet
+
+ if ( ( pThisRowInfo->bChanged || nArrY==0 ) && pThisRowInfo->nRotMaxCol != SC_ROTMAX_NONE )
+ {
+ long nPosX = 0;
+ for (SCCOL nX=0; nX<=nRotMax; nX++)
+ {
+ if (nX==nX1) nPosX = nInitPosX; // positions before nX1 are calculated individually
+
+ CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+ if ( pInfo->nRotateDir != SC_ROTDIR_NONE )
+ {
+ SCROW nY = pThisRowInfo->nRowNo;
+
+ sal_Bool bHidden = sal_False;
+ if (bEditMode)
+ if ( nX == nEditCol && nY == nEditRow )
+ bHidden = sal_True;
+
+ if (!bHidden)
+ {
+ if (!pEngine)
+ {
+ // Ein RefDevice muss auf jeden Fall gesetzt werden,
+ // sonst legt sich die EditEngine ein VirtualDevice an!
+ pEngine = new ScFieldEditEngine( pDoc->GetEnginePool() );
+ pEngine->SetUpdateMode( sal_False );
+ pEngine->SetRefDevice( pFmtDevice ); // always set
+ sal_uLong nCtrl = pEngine->GetControlWord();
+ if ( bShowSpellErrors )
+ nCtrl |= EE_CNTRL_ONLINESPELLING;
+ if ( eType == OUTTYPE_PRINTER )
+ nCtrl &= ~EE_CNTRL_MARKFIELDS;
+ pEngine->SetControlWord( nCtrl );
+ pEngine->SetForbiddenCharsTable( pDoc->GetForbiddenCharacters() );
+ pEngine->SetAsianCompressionMode( pDoc->GetAsianCompression() );
+ pEngine->SetKernAsianPunctuation( pDoc->GetAsianKerning() );
+ pEngine->EnableAutoColor( bUseStyleColor );
+ pEngine->SetDefaultHorizontalTextDirection(
+ (EEHorizontalTextDirection)pDoc->GetEditTextDirection( nTab ) );
+ }
+ else
+ lcl_ClearEdit( *pEngine ); // also calls SetUpdateMode(sal_False)
+
+ long nPosY = nRowPosY;
+ sal_Bool bVisChanged = sal_False;
+
+ //! Rest von zusammengefasster Zelle weiter oben funktioniert nicht!
+
+ sal_Bool bFromDoc = sal_False;
+ pPattern = pInfo->pPatternAttr;
+ pCondSet = pInfo->pConditionSet;
+ if (!pPattern)
+ {
+ pPattern = pDoc->GetPattern( nX, nY, nTab );
+ bFromDoc = sal_True;
+ }
+ pCell = pInfo->pCell;
+ if (bFromDoc)
+ pCondSet = pDoc->GetCondResult( nX, nY, nTab );
+
+ if (!pCell && nX>nX2)
+ GetVisibleCell( nX, nY, nTab, pCell );
+
+ if ( !pCell || IsEmptyCellText( pThisRowInfo, nX, nY ) )
+ bHidden = sal_True; // nRotateDir is also set without a cell
+
+ long nCellWidth = (long) pRowInfo[0].pCellInfo[nX+1].nWidth;
+
+ SvxCellHorJustify eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
+ pPattern->GetItem(ATTR_HOR_JUSTIFY, pCondSet)).GetValue();
+ sal_Bool bBreak = ( eHorJust == SVX_HOR_JUSTIFY_BLOCK ) ||
+ ((const SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK, pCondSet)).GetValue();
+ sal_Bool bRepeat = ( eHorJust == SVX_HOR_JUSTIFY_REPEAT && !bBreak );
+ sal_Bool bShrink = !bBreak && !bRepeat && static_cast<const SfxBoolItem&>
+ (pPattern->GetItem( ATTR_SHRINKTOFIT, pCondSet )).GetValue();
+ SvxCellOrientation eOrient = pPattern->GetCellOrientation( pCondSet );
+
+ const ScMergeAttr* pMerge =
+ (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
+ sal_Bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
+
+ long nStartX = nPosX;
+ long nStartY = nPosY;
+ if (nX<nX1)
+ {
+ if ((bBreak || eOrient!=SVX_ORIENTATION_STANDARD) && !bMerged)
+ bHidden = sal_True;
+ else
+ {
+ nStartX = nInitPosX;
+ SCCOL nCol = nX1;
+ while (nCol > nX)
+ {
+ --nCol;
+ nStartX -= nLayoutSign * (long) pRowInfo[0].pCellInfo[nCol+1].nWidth;
+ }
+ }
+ }
+ long nCellStartX = nStartX;
+
+ // Ersatzdarstellung fuer zu kleinen Text weggelassen
+
+ if (!bHidden)
+ {
+ long nOutWidth = nCellWidth - 1;
+ long nOutHeight;
+ if (pInfo)
+ nOutHeight = nCellHeight;
+ else
+ nOutHeight = (long) ( pDoc->GetRowHeight(nY,nTab) * nPPTY );
+
+ if ( bMerged ) // Zusammengefasst
+ {
+ SCCOL nCountX = pMerge->GetColMerge();
+ for (SCCOL i=1; i<nCountX; i++)
+ nOutWidth += (long) ( pDoc->GetColWidth(nX+i,nTab) * nPPTX );
+ SCROW nCountY = pMerge->GetRowMerge();
+ nOutHeight += (long) pDoc->GetScaledRowHeight( nY+1, nY+nCountY-1, nTab, nPPTY);
+ }
+
+ SvxCellVerJustify eVerJust = (SvxCellVerJustify)((const SvxVerJustifyItem&)
+ pPattern->GetItem(ATTR_VER_JUSTIFY, pCondSet)).GetValue();
+
+ // Syntax-Modus wird hier ignoriert...
+
+ // StringDiffer doesn't look at hyphenate, language items
+ if ( pPattern != pOldPattern || pCondSet != pOldCondSet )
+ {
+ SfxItemSet* pSet = new SfxItemSet( pEngine->GetEmptyItemSet() );
+ pPattern->FillEditItemSet( pSet, pCondSet );
+
+ // Ausrichtung fuer EditEngine
+ SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
+ if (eOrient==SVX_ORIENTATION_STACKED)
+ eSvxAdjust = SVX_ADJUST_CENTER;
+ // Adjustment fuer bBreak ist hier weggelassen
+ pSet->Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
+
+ pEngine->SetDefaults( pSet );
+ pOldPattern = pPattern;
+ pOldCondSet = pCondSet;
+
+ sal_uLong nControl = pEngine->GetControlWord();
+ if (eOrient==SVX_ORIENTATION_STACKED)
+ nControl |= EE_CNTRL_ONECHARPERLINE;
+ else
+ nControl &= ~EE_CNTRL_ONECHARPERLINE;
+ pEngine->SetControlWord( nControl );
+
+ if ( !bHyphenatorSet && ((const SfxBoolItem&)pSet->Get(EE_PARA_HYPHENATE)).GetValue() )
+ {
+ // set hyphenator the first time it is needed
+ com::sun::star::uno::Reference<com::sun::star::linguistic2::XHyphenator> xXHyphenator( LinguMgr::GetHyphenator() );
+ pEngine->SetHyphenator( xXHyphenator );
+ bHyphenatorSet = sal_True;
+ }
+
+ Color aBackCol = ((const SvxBrushItem&)
+ pPattern->GetItem( ATTR_BACKGROUND, pCondSet )).GetColor();
+ if ( bUseStyleColor && ( aBackCol.GetTransparency() > 0 || bCellContrast ) )
+ aBackCol.SetColor( nConfBackColor );
+ pEngine->SetBackgroundColor( aBackCol );
+ }
+
+ // Raender
+
+ //! Position und Papersize auf EditUtil umstellen !!!
+
+ const SvxMarginItem* pMargin = (const SvxMarginItem*)
+ &pPattern->GetItem(ATTR_MARGIN, pCondSet);
+ sal_uInt16 nIndent = 0;
+ if ( eHorJust == SVX_HOR_JUSTIFY_LEFT )
+ nIndent = ((const SfxUInt16Item&)pPattern->
+ GetItem(ATTR_INDENT, pCondSet)).GetValue();
+
+ long nTotalHeight = nOutHeight; // ohne Rand abzuziehen
+ if ( bPixelToLogic )
+ nTotalHeight = pRefDevice->PixelToLogic(Size(0,nTotalHeight)).Height();
+
+ long nLeftM = (long) ( (pMargin->GetLeftMargin() + nIndent) * nPPTX );
+ long nTopM = (long) ( pMargin->GetTopMargin() * nPPTY );
+ long nRightM = (long) ( pMargin->GetRightMargin() * nPPTX );
+ long nBottomM = (long) ( pMargin->GetBottomMargin() * nPPTY );
+ nStartX += nLeftM;
+ nStartY += nTopM;
+ nOutWidth -= nLeftM + nRightM;
+ nOutHeight -= nTopM + nBottomM;
+
+ // Rotation schon hier, um bei Umbruch auch PaperSize anzupassen
+ long nAttrRotate = 0;
+ double nSin = 0.0;
+ double nCos = 1.0;
+ SvxRotateMode eRotMode = SVX_ROTATE_MODE_STANDARD;
+ if ( eOrient == SVX_ORIENTATION_STANDARD )
+ {
+ nAttrRotate = ((const SfxInt32Item&)pPattern->
+ GetItem(ATTR_ROTATE_VALUE, pCondSet)).GetValue();
+ if ( nAttrRotate )
+ {
+ eRotMode = (SvxRotateMode)((const SvxRotateModeItem&)
+ pPattern->GetItem(ATTR_ROTATE_MODE, pCondSet)).GetValue();
+
+ if ( nAttrRotate == 18000 )
+ eRotMode = SVX_ROTATE_MODE_STANDARD; // keinen Ueberlauf
+
+ if ( bLayoutRTL )
+ nAttrRotate = -nAttrRotate;
+
+ double nRealOrient = nAttrRotate * F_PI18000; // 1/100 Grad
+ nCos = cos( nRealOrient );
+ nSin = sin( nRealOrient );
+ }
+ }
+
+ Size aPaperSize = Size( 1000000, 1000000 );
+ if (eOrient==SVX_ORIENTATION_STACKED)
+ aPaperSize.Width() = nOutWidth; // zum Zentrieren
+ else if (bBreak)
+ {
+ if (nAttrRotate)
+ {
+ //! richtige PaperSize fuer Umbruch haengt von der Zeilenzahl
+ //! ab, solange die Zeilen nicht einzeln versetzt ausgegeben
+ //! werden koennen -> darum unbegrenzt, also kein Umbruch.
+ //! Mit versetzten Zeilen waere das folgende richtig:
+ aPaperSize.Width() = (long)(nOutHeight / fabs(nSin));
+ }
+ else if (eOrient == SVX_ORIENTATION_STANDARD)
+ aPaperSize.Width() = nOutWidth;
+ else
+ aPaperSize.Width() = nOutHeight - 1;
+ }
+ if (bPixelToLogic)
+ pEngine->SetPaperSize(pRefDevice->PixelToLogic(aPaperSize));
+ else
+ pEngine->SetPaperSize(aPaperSize); // Scale ist immer 1
+
+ // Daten aus Zelle lesen
+
+ if (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_EDIT)
+ {
+ const EditTextObject* pData;
+ ((ScEditCell*)pCell)->GetData(pData);
+
+ if (pData)
+ pEngine->SetText(*pData);
+ else
+ {
+ DBG_ERROR("pData == 0");
+ }
+ }
+ else
+ {
+ sal_uLong nFormat = pPattern->GetNumberFormat(
+ pDoc->GetFormatTable(), pCondSet );
+ String aString;
+ Color* pColor;
+ ScCellFormat::GetString( pCell,
+ nFormat,aString, &pColor,
+ *pDoc->GetFormatTable(),
+ bShowNullValues,
+ bShowFormulas,
+ ftCheck );
+
+ pEngine->SetText(aString);
+ if ( pColor && !bSyntaxMode && !( bUseStyleColor && bForceAutoColor ) )
+ lcl_SetEditColor( *pEngine, *pColor );
+ }
+
+ if ( bSyntaxMode )
+ SetEditSyntaxColor( *pEngine, pCell );
+ else if ( bUseStyleColor && bForceAutoColor )
+ lcl_SetEditColor( *pEngine, COL_AUTO ); //! or have a flag at EditEngine
+ }
+ else
+ {
+ DBG_ERROR("pCell == NULL");
+ }
+
+ pEngine->SetUpdateMode( sal_True ); // after SetText, before CalcTextWidth/GetTextHeight
+
+ long nEngineWidth = (long) pEngine->CalcTextWidth();
+ long nEngineHeight = pEngine->GetTextHeight();
+
+ if (nAttrRotate && bBreak)
+ {
+ double nAbsCos = fabs( nCos );
+ double nAbsSin = fabs( nSin );
+
+ // #47740# adjust witdh of papersize for height of text
+ int nSteps = 5;
+ while (nSteps > 0)
+ {
+ // everything is in pixels
+ long nEnginePixel = pRefDevice->LogicToPixel(
+ Size(0,nEngineHeight)).Height();
+ long nEffHeight = nOutHeight - (long)(nEnginePixel * nAbsCos) + 2;
+ long nNewWidth = (long)(nEffHeight / nAbsSin) + 2;
+ sal_Bool bFits = ( nNewWidth >= aPaperSize.Width() );
+ if ( bFits )
+ nSteps = 0;
+ else
+ {
+ if ( nNewWidth < 4 )
+ {
+ // can't fit -> fall back to using half height
+ nEffHeight = nOutHeight / 2;
+ nNewWidth = (long)(nEffHeight / nAbsSin) + 2;
+ nSteps = 0;
+ }
+ else
+ --nSteps;
+
+ // set paper width and get new text height
+ aPaperSize.Width() = nNewWidth;
+ if (bPixelToLogic)
+ pEngine->SetPaperSize(pRefDevice->PixelToLogic(aPaperSize));
+ else
+ pEngine->SetPaperSize(aPaperSize); // Scale ist immer 1
+ //pEngine->QuickFormatDoc( sal_True );
+ nEngineWidth = (long) pEngine->CalcTextWidth();
+ nEngineHeight = pEngine->GetTextHeight();
+ }
+ }
+ }
+
+ long nRealWidth = nEngineWidth;
+ long nRealHeight = nEngineHeight;
+
+ // wenn gedreht, Groesse anpassen
+ if (nAttrRotate)
+ {
+ double nAbsCos = fabs( nCos );
+ double nAbsSin = fabs( nSin );
+
+ if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
+ nEngineWidth = (long) ( nRealWidth * nAbsCos +
+ nRealHeight * nAbsSin );
+ else
+ nEngineWidth = (long) ( nRealHeight / nAbsSin );
+ //! begrenzen !!!
+
+ nEngineHeight = (long) ( nRealHeight * nAbsCos +
+ nRealWidth * nAbsSin );
+ }
+
+ if (!nAttrRotate) // hier nur gedrehter Text
+ bHidden = sal_True; //! vorher abfragen !!!
+
+ //! weglassen, was nicht hereinragt
+
+ if (!bHidden)
+ {
+ sal_Bool bClip = sal_False;
+ Size aClipSize = Size( nScrX+nScrW-nStartX, nScrY+nScrH-nStartY );
+
+ // weiterschreiben
+
+ Size aCellSize;
+ if (bPixelToLogic)
+ aCellSize = pRefDevice->PixelToLogic( Size( nOutWidth, nOutHeight ) );
+ else
+ aCellSize = Size( nOutWidth, nOutHeight ); // Scale ist 1
+
+ long nGridWidth = nEngineWidth;
+ sal_Bool bNegative = sal_False;
+ if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
+ {
+ nGridWidth = aCellSize.Width() +
+ Abs((long) ( aCellSize.Height() * nCos / nSin ));
+ bNegative = ( pInfo->nRotateDir == SC_ROTDIR_LEFT );
+ if ( bLayoutRTL )
+ bNegative = !bNegative;
+ }
+
+ // use GetOutputArea to hide the grid
+ // (clip region is done manually below)
+ OutputAreaParam aAreaParam;
+
+ SCCOL nCellX = nX;
+ SCROW nCellY = nY;
+ SvxCellHorJustify eOutHorJust = eHorJust;
+ if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
+ eOutHorJust = bNegative ? SVX_HOR_JUSTIFY_RIGHT : SVX_HOR_JUSTIFY_LEFT;
+ long nNeededWidth = nGridWidth; // in pixel for GetOutputArea
+ if ( bPixelToLogic )
+ nNeededWidth = pRefDevice->LogicToPixel(Size(nNeededWidth,0)).Width();
+
+ GetOutputArea( nX, nArrY, nCellStartX, nPosY, nCellX, nCellY, nNeededWidth,
+ *pPattern, sal::static_int_cast<sal_uInt16>(eOutHorJust),
+ sal_False, sal_False, sal_True, aAreaParam );
+
+ if ( bShrink )
+ {
+ long nPixelWidth = bPixelToLogic ?
+ pRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width() : nEngineWidth;
+ long nNeededPixel = nPixelWidth + nLeftM + nRightM;
+
+ aAreaParam.mbLeftClip = aAreaParam.mbRightClip = sal_True;
+
+ // always do height
+ ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM,
+ sal_False, sal::static_int_cast<sal_uInt16>(eOrient), nAttrRotate, bPixelToLogic,
+ nEngineWidth, nEngineHeight, nNeededPixel, aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
+
+ if ( eRotMode == SVX_ROTATE_MODE_STANDARD )
+ {
+ // do width only if rotating within the cell (standard mode)
+ ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM,
+ sal_True, sal::static_int_cast<sal_uInt16>(eOrient), nAttrRotate, bPixelToLogic,
+ nEngineWidth, nEngineHeight, nNeededPixel, aAreaParam.mbLeftClip, aAreaParam.mbRightClip );
+ }
+
+ // nEngineWidth/nEngineHeight is updated in ShrinkEditEngine
+ // (but width is only valid for standard mode)
+ nRealWidth = (long) pEngine->CalcTextWidth();
+ nRealHeight = pEngine->GetTextHeight();
+
+ if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
+ nEngineWidth = (long) ( nRealHeight / fabs( nSin ) );
+ }
+
+ // sal_Bool bVClip = ( nEngineHeight > aCellSize.Height() );
+
+ long nClipStartX = nStartX;
+ if (nX<nX1)
+ {
+ //! Clipping unnoetig, wenn links am Fenster
+
+ bClip = sal_True; // nur Rest ausgeben!
+ if (nStartX<nScrX)
+ {
+ long nDif = nScrX - nStartX;
+ nClipStartX = nScrX;
+ aClipSize.Width() -= nDif;
+ }
+ }
+
+ long nClipStartY = nStartY;
+ if (nArrY==0 || bVisChanged)
+ {
+ if ( nClipStartY < nRowPosY )
+ {
+ long nDif = nRowPosY - nClipStartY;
+ bClip = sal_True;
+ nClipStartY = nRowPosY;
+ aClipSize.Height() -= nDif;
+ }
+ }
+
+ bClip = sal_True; // always clip at the window/page border
+
+ //Rectangle aClipRect;
+ if (bClip)
+ {
+ if ( nAttrRotate /* && eRotMode != SVX_ROTATE_MODE_STANDARD */ )
+ {
+ // gedrehten, ausgerichteten Text nur an den
+ // Seitengrenzen clippen
+ nClipStartX = nScrX;
+ aClipSize.Width() = nScrW;
+ }
+
+ if (bPixelToLogic)
+ aAreaParam.maClipRect = pRefDevice->PixelToLogic( Rectangle(
+ Point(nClipStartX,nClipStartY), aClipSize ) );
+ else
+ aAreaParam.maClipRect = Rectangle(Point(nClipStartX, nClipStartY),
+ aClipSize ); // Scale = 1
+
+ if (bMetaFile)
+ {
+ pDev->Push();
+ pDev->IntersectClipRegion( aAreaParam.maClipRect );
+ }
+ else
+ pDev->SetClipRegion( Region( aAreaParam.maClipRect ) );
+ }
+
+ Point aLogicStart;
+ if (bPixelToLogic)
+ aLogicStart = pRefDevice->PixelToLogic( Point(nStartX,nStartY) );
+ else
+ aLogicStart = Point(nStartX, nStartY);
+ if ( eOrient!=SVX_ORIENTATION_STANDARD || !bBreak )
+ {
+ long nAvailWidth = aCellSize.Width();
+ if (eType==OUTTYPE_WINDOW &&
+ eOrient!=SVX_ORIENTATION_STACKED &&
+ pInfo && pInfo->bAutoFilter)
+ {
+ // filter drop-down width is now independent from row height
+ if (bPixelToLogic)
+ nAvailWidth -= pRefDevice->PixelToLogic(Size(0,DROPDOWN_BITMAP_SIZE)).Height();
+ else
+ nAvailWidth -= DROPDOWN_BITMAP_SIZE;
+ long nComp = nEngineWidth;
+ if (nAvailWidth<nComp) nAvailWidth=nComp;
+ }
+
+ // horizontale Ausrichtung
+
+ if (eOrient==SVX_ORIENTATION_STANDARD && !nAttrRotate)
+ {
+ if (eHorJust==SVX_HOR_JUSTIFY_RIGHT ||
+ eHorJust==SVX_HOR_JUSTIFY_CENTER)
+ {
+ pEngine->SetUpdateMode( sal_False );
+
+ SvxAdjust eSvxAdjust =
+ (eHorJust==SVX_HOR_JUSTIFY_RIGHT) ?
+ SVX_ADJUST_RIGHT : SVX_ADJUST_CENTER;
+ pEngine->SetDefaultItem(
+ SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
+
+ aPaperSize.Width() = nOutWidth;
+ if (bPixelToLogic)
+ pEngine->SetPaperSize(pRefDevice->PixelToLogic(aPaperSize));
+ else
+ pEngine->SetPaperSize(aPaperSize);
+
+ pEngine->SetUpdateMode( sal_True );
+ }
+ }
+ else
+ {
+ // bei gedrehtem Text ist Standard zentriert
+ if (eHorJust==SVX_HOR_JUSTIFY_RIGHT)
+ aLogicStart.X() += nAvailWidth - nEngineWidth;
+ else if (eHorJust==SVX_HOR_JUSTIFY_CENTER ||
+ eHorJust==SVX_HOR_JUSTIFY_STANDARD)
+ aLogicStart.X() += (nAvailWidth - nEngineWidth) / 2;
+ }
+ }
+
+ if ( bLayoutRTL )
+ {
+ if (bPixelToLogic)
+ aLogicStart.X() -= pRefDevice->PixelToLogic(
+ Size( nCellWidth, 0 ) ).Width();
+ else
+ aLogicStart.X() -= nCellWidth;
+ }
+
+ if ( eOrient==SVX_ORIENTATION_STANDARD ||
+ eOrient==SVX_ORIENTATION_STACKED || !bBreak )
+ {
+ if (eVerJust==SVX_VER_JUSTIFY_BOTTOM ||
+ eVerJust==SVX_VER_JUSTIFY_STANDARD)
+ {
+ if (bPixelToLogic)
+ aLogicStart.Y() += pRefDevice->PixelToLogic( Size(0,
+ pRefDevice->LogicToPixel(aCellSize).Height() -
+ pRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height()
+ )).Height();
+ else
+ aLogicStart.Y() += aCellSize.Height() - nEngineHeight;
+ }
+
+ else if (eVerJust==SVX_VER_JUSTIFY_CENTER)
+ {
+ if (bPixelToLogic)
+ aLogicStart.Y() += pRefDevice->PixelToLogic( Size(0,(
+ pRefDevice->LogicToPixel(aCellSize).Height() -
+ pRefDevice->LogicToPixel(Size(0,nEngineHeight)).Height())
+ / 2)).Height();
+ else
+ aLogicStart.Y() += (aCellSize.Height() - nEngineHeight) / 2;
+ }
+ }
+
+ // TOPBOTTON and BOTTOMTOP are handled in DrawStrings/DrawEdit
+ DBG_ASSERT( eOrient == SVX_ORIENTATION_STANDARD && nAttrRotate,
+ "DrawRotated: no rotation" );
+
+ long nOriVal = 0;
+ if ( nAttrRotate )
+ {
+ // Attribut ist 1/100, Font 1/10 Grad
+ nOriVal = nAttrRotate / 10;
+
+ double nAddX = 0.0;
+ double nAddY = 0.0;
+ if ( nCos > 0.0 && eRotMode != SVX_ROTATE_MODE_STANDARD )
+ {
+ //! begrenzen !!!
+ double nH = nRealHeight * nCos;
+ nAddX += nH * ( nCos / fabs(nSin) );
+ }
+ if ( nCos < 0.0 && eRotMode == SVX_ROTATE_MODE_STANDARD )
+ nAddX -= nRealWidth * nCos;
+ if ( nSin < 0.0 )
+ nAddX -= nRealHeight * nSin;
+ if ( nSin > 0.0 )
+ nAddY += nRealWidth * nSin;
+ if ( nCos < 0.0 )
+ nAddY -= nRealHeight * nCos;
+
+ if ( eRotMode != SVX_ROTATE_MODE_STANDARD )
+ {
+ //! begrenzen !!!
+ double nSkew = nTotalHeight * nCos / fabs(nSin);
+ if ( eRotMode == SVX_ROTATE_MODE_CENTER )
+ nAddX -= nSkew * 0.5;
+ if ( ( eRotMode == SVX_ROTATE_MODE_TOP && nSin > 0.0 ) ||
+ ( eRotMode == SVX_ROTATE_MODE_BOTTOM && nSin < 0.0 ) )
+ nAddX -= nSkew;
+
+ long nUp = 0;
+ if ( eVerJust == SVX_VER_JUSTIFY_CENTER )
+ nUp = ( aCellSize.Height() - nEngineHeight ) / 2;
+ else if ( eVerJust == SVX_VER_JUSTIFY_TOP )
+ {
+ if ( nSin > 0.0 )
+ nUp = aCellSize.Height() - nEngineHeight;
+ }
+ else // BOTTOM / STANDARD
+ {
+ if ( nSin < 0.0 )
+ nUp = aCellSize.Height() - nEngineHeight;
+ }
+ if ( nUp )
+ nAddX += ( nUp * nCos / fabs(nSin) );
+ }
+
+ aLogicStart.X() += (long) nAddX;
+ aLogicStart.Y() += (long) nAddY;
+ }
+
+ // bSimClip is not used here (because nOriVal is set)
+
+ if ( pEngine->IsRightToLeft( 0 ) )
+ {
+ // For right-to-left, EditEngine always calculates its lines
+ // beginning from the right edge, but EditLine::nStartPosX is
+ // of sal_uInt16 type, so the PaperSize must be limited to USHRT_MAX.
+ Size aLogicPaper = pEngine->GetPaperSize();
+ if ( aLogicPaper.Width() > USHRT_MAX )
+ {
+ aLogicPaper.Width() = USHRT_MAX;
+ pEngine->SetPaperSize(aLogicPaper);
+ }
+ }
+
+ pEngine->Draw( pDev, aLogicStart, (short)nOriVal );
+
+ if (bClip)
+ {
+ if (bMetaFile)
+ pDev->Pop();
+ else
+ pDev->SetClipRegion();
+ }
+ }
+ }
+ }
+ }
+ nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+ }
+ }
+ nRowPosY += pRowInfo[nArrY].nHeight;
+ }
+
+ delete pEngine;
+}
+
+
+
diff --git a/sc/source/ui/view/output3.cxx b/sc/source/ui/view/output3.cxx
new file mode 100644
index 000000000000..9265f6192b3c
--- /dev/null
+++ b/sc/source/ui/view/output3.cxx
@@ -0,0 +1,276 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <editeng/eeitem.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdoutl.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdview.hxx>
+#include <vcl/svapp.hxx>
+
+#include "output.hxx"
+#include "drwlayer.hxx"
+#include "document.hxx"
+#include "tabvwsh.hxx"
+#include "fillinfo.hxx"
+
+#include <svx/fmview.hxx>
+
+// STATIC DATA -----------------------------------------------------------
+
+SdrObject* pSkipPaintObj = NULL;
+
+//==================================================================
+
+// #i72502#
+Point ScOutputData::PrePrintDrawingLayer(long nLogStX, long nLogStY )
+{
+ Rectangle aRect;
+ SCCOL nCol;
+ Point aOffset;
+ long nLayoutSign(bLayoutRTL ? -1 : 1);
+
+ for (nCol=0; nCol<nX1; nCol++)
+ aOffset.X() -= pDoc->GetColWidth( nCol, nTab ) * nLayoutSign;
+ aOffset.Y() -= pDoc->GetRowHeight( 0, nY1-1, nTab );
+
+ long nDataWidth = 0;
+ long nDataHeight = 0;
+ for (nCol=nX1; nCol<=nX2; nCol++)
+ nDataWidth += pDoc->GetColWidth( nCol, nTab );
+ nDataHeight += pDoc->GetRowHeight( nY1, nY2, nTab );
+
+ if ( bLayoutRTL )
+ aOffset.X() += nDataWidth;
+
+ aRect.Left() = aRect.Right() = -aOffset.X();
+ aRect.Top() = aRect.Bottom() = -aOffset.Y();
+
+ Point aMMOffset( aOffset );
+ aMMOffset.X() = (long)(aMMOffset.X() * HMM_PER_TWIPS);
+ aMMOffset.Y() = (long)(aMMOffset.Y() * HMM_PER_TWIPS);
+
+ if (!bMetaFile)
+ aMMOffset += Point( nLogStX, nLogStY );
+
+ for (nCol=nX1; nCol<=nX2; nCol++)
+ aRect.Right() += pDoc->GetColWidth( nCol, nTab );
+ aRect.Bottom() += pDoc->GetRowHeight( nY1, nY2, nTab );
+
+ aRect.Left() = (long) (aRect.Left() * HMM_PER_TWIPS);
+ aRect.Top() = (long) (aRect.Top() * HMM_PER_TWIPS);
+ aRect.Right() = (long) (aRect.Right() * HMM_PER_TWIPS);
+ aRect.Bottom() = (long) (aRect.Bottom() * HMM_PER_TWIPS);
+
+ if(pViewShell || pDrawView)
+ {
+ SdrView* pLocalDrawView = (pDrawView) ? pDrawView : pViewShell->GetSdrView();
+
+ if(pLocalDrawView)
+ {
+ // #i76114# MapMode has to be set because BeginDrawLayers uses GetPaintRegion
+ MapMode aOldMode = pDev->GetMapMode();
+ if (!bMetaFile)
+ pDev->SetMapMode( MapMode( MAP_100TH_MM, aMMOffset, aOldMode.GetScaleX(), aOldMode.GetScaleY() ) );
+
+ // #i74769# work with SdrPaintWindow directly
+ // #i76114# pass bDisableIntersect = true, because the intersection of the table area
+ // with the Window's paint region can be empty
+ Region aRectRegion(aRect);
+ mpTargetPaintWindow = pLocalDrawView->BeginDrawLayers(pDev, aRectRegion, true);
+ OSL_ENSURE(mpTargetPaintWindow, "BeginDrawLayers: Got no SdrPaintWindow (!)");
+
+ if (!bMetaFile)
+ pDev->SetMapMode( aOldMode );
+ }
+ }
+
+ return aMMOffset;
+}
+
+// #i72502#
+void ScOutputData::PostPrintDrawingLayer(const Point& rMMOffset) // #i74768#
+{
+ // #i74768# just use offset as in PrintDrawingLayer() to also get the form controls
+ // painted with offset
+ MapMode aOldMode = pDev->GetMapMode();
+
+ if (!bMetaFile)
+ {
+ pDev->SetMapMode( MapMode( MAP_100TH_MM, rMMOffset, aOldMode.GetScaleX(), aOldMode.GetScaleY() ) );
+ }
+
+ if(pViewShell || pDrawView)
+ {
+ SdrView* pLocalDrawView = (pDrawView) ? pDrawView : pViewShell->GetSdrView();
+
+ if(pLocalDrawView)
+ {
+ // #i74769# work with SdrPaintWindow directly
+ pLocalDrawView->EndDrawLayers(*mpTargetPaintWindow, true);
+ mpTargetPaintWindow = 0;
+ }
+ }
+
+ // #i74768#
+ if (!bMetaFile)
+ {
+ pDev->SetMapMode( aOldMode );
+ }
+}
+
+// #i72502#
+void ScOutputData::PrintDrawingLayer(const sal_uInt16 nLayer, const Point& rMMOffset)
+{
+ bool bHideAllDrawingLayer(false);
+
+ if(pViewShell || pDrawView)
+ {
+ SdrView* pLocalDrawView = (pDrawView) ? pDrawView : pViewShell->GetSdrView();
+
+ if(pLocalDrawView)
+ {
+ bHideAllDrawingLayer = pLocalDrawView->getHideOle() && pLocalDrawView->getHideChart()
+ && pLocalDrawView->getHideDraw() && pLocalDrawView->getHideFormControl();
+ }
+ }
+
+ // #109985#
+ if(bHideAllDrawingLayer || (!pDoc->GetDrawLayer()))
+ {
+ return;
+ }
+
+ MapMode aOldMode = pDev->GetMapMode();
+
+ if (!bMetaFile)
+ {
+ pDev->SetMapMode( MapMode( MAP_100TH_MM, rMMOffset, aOldMode.GetScaleX(), aOldMode.GetScaleY() ) );
+ }
+
+ // #109985#
+ DrawSelectiveObjects( nLayer );
+
+ if (!bMetaFile)
+ {
+ pDev->SetMapMode( aOldMode );
+ }
+}
+
+// #109985#
+void ScOutputData::DrawSelectiveObjects(const sal_uInt16 nLayer)
+{
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ if (!pModel)
+ return;
+
+ // #i46362# high contrast mode (and default text direction) must be handled
+ // by the application, so it's still needed when using DrawLayer().
+
+ SdrOutliner& rOutl = pModel->GetDrawOutliner();
+ rOutl.EnableAutoColor( bUseStyleColor );
+ rOutl.SetDefaultHorizontalTextDirection(
+ (EEHorizontalTextDirection)pDoc->GetEditTextDirection( nTab ) );
+
+ // #i69767# The hyphenator must be set (used to be before drawing a text shape with hyphenation).
+ // LinguMgr::GetHyphenator (EditEngine) uses a wrapper now that creates the real hyphenator on demand,
+ // so it's not a performance problem to call UseHyphenator even when it's not needed.
+
+ pModel->UseHyphenator();
+
+ sal_uLong nOldDrawMode = pDev->GetDrawMode();
+ if ( bUseStyleColor && Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ pDev->SetDrawMode( nOldDrawMode | DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL |
+ DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT );
+ }
+
+ // #109985#
+ if(pViewShell || pDrawView)
+ {
+ SdrView* pLocalDrawView = (pDrawView) ? pDrawView : pViewShell->GetSdrView();
+
+ if(pLocalDrawView)
+ {
+ SdrPageView* pPageView = pLocalDrawView->GetSdrPageView();
+
+ if(pPageView)
+ {
+ pPageView->DrawLayer(sal::static_int_cast<SdrLayerID>(nLayer), pDev);
+ }
+ }
+ }
+
+ pDev->SetDrawMode(nOldDrawMode);
+
+ // #109985#
+ return;
+}
+
+// Teile nur fuer Bildschirm
+
+// #109985#
+void ScOutputData::DrawingSingle(const sal_uInt16 nLayer)
+{
+ sal_Bool bHad = sal_False;
+ long nPosY = nScrY;
+ SCSIZE nArrY;
+ for (nArrY=1; nArrY+1<nArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+
+ if ( pThisRowInfo->bChanged )
+ {
+ if (!bHad)
+ {
+ bHad = sal_True;
+ }
+ }
+ else if (bHad)
+ {
+ DrawSelectiveObjects( nLayer );
+ bHad = sal_False;
+ }
+ nPosY += pRowInfo[nArrY].nHeight;
+ }
+
+ if (bHad)
+ DrawSelectiveObjects( nLayer );
+}
+
+
+
+
diff --git a/sc/source/ui/view/pfuncache.cxx b/sc/source/ui/view/pfuncache.cxx
new file mode 100644
index 000000000000..6bb14163b227
--- /dev/null
+++ b/sc/source/ui/view/pfuncache.cxx
@@ -0,0 +1,198 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <tools/multisel.hxx>
+
+#include "pfuncache.hxx"
+#include "printfun.hxx"
+#include "docsh.hxx"
+#include "markdata.hxx"
+#include "prevloc.hxx"
+
+//------------------------------------------------------------------------
+
+ScPrintFuncCache::ScPrintFuncCache( ScDocShell* pD, const ScMarkData& rMark,
+ const ScPrintSelectionStatus& rStatus ) :
+ aSelection( rStatus ),
+ pDocSh( pD ),
+ nTotalPages( 0 ),
+ bLocInitialized( false )
+{
+ // page count uses the stored cell widths for the printer anyway,
+ // so ScPrintFunc with the document's printer can be used to count
+
+ SfxPrinter* pPrinter = pDocSh->GetPrinter();
+
+ ScRange aRange;
+ const ScRange* pSelRange = NULL;
+ if ( rMark.IsMarked() )
+ {
+ rMark.GetMarkArea( aRange );
+ pSelRange = &aRange;
+ }
+
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nTab;
+ for ( nTab=0; nTab<nTabCount; nTab++ )
+ {
+ long nAttrPage = nTab > 0 ? nFirstAttr[nTab-1] : 1;
+
+ long nThisTab = 0;
+ if ( rMark.GetTableSelect( nTab ) )
+ {
+ pDoc->InvalidatePageBreaks( nTab ); // user print area (selection) may be different
+
+ ScPrintFunc aFunc( pDocSh, pPrinter, nTab, nAttrPage, 0, pSelRange, &aSelection.GetOptions() );
+ nThisTab = aFunc.GetTotalPages();
+ nFirstAttr[nTab] = aFunc.GetFirstPageNo(); // from page style or previous sheet
+ }
+ else
+ nFirstAttr[nTab] = nAttrPage;
+
+ nPages[nTab] = nThisTab;
+ nTotalPages += nThisTab;
+ }
+}
+
+ScPrintFuncCache::~ScPrintFuncCache()
+{
+}
+
+void ScPrintFuncCache::InitLocations( const ScMarkData& rMark, OutputDevice* pDev )
+{
+ if ( bLocInitialized )
+ return; // initialize only once
+
+ ScRange aRange;
+ const ScRange* pSelRange = NULL;
+ if ( rMark.IsMarked() )
+ {
+ rMark.GetMarkArea( aRange );
+ pSelRange = &aRange;
+ }
+
+ long nRenderer = 0; // 0-based physical page number across sheets
+ long nTabStart = 0;
+
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for ( SCTAB nTab=0; nTab<nTabCount; nTab++ )
+ {
+ if ( rMark.GetTableSelect( nTab ) )
+ {
+ ScPrintFunc aFunc( pDev, pDocSh, nTab, nFirstAttr[nTab], nTotalPages, pSelRange, &aSelection.GetOptions() );
+ aFunc.SetRenderFlag( sal_True );
+
+ long nDisplayStart = GetDisplayStart( nTab );
+
+ for ( long nPage=0; nPage<nPages[nTab]; nPage++ )
+ {
+ Range aPageRange( nRenderer+1, nRenderer+1 );
+ MultiSelection aPage( aPageRange );
+ aPage.SetTotalRange( Range(0,RANGE_MAX) );
+ aPage.Select( aPageRange );
+
+ ScPreviewLocationData aLocData( pDoc, pDev );
+ aFunc.DoPrint( aPage, nTabStart, nDisplayStart, sal_False, NULL, &aLocData );
+
+ ScRange aCellRange;
+ Rectangle aPixRect;
+ if ( aLocData.GetMainCellRange( aCellRange, aPixRect ) )
+ aLocations.push_back( ScPrintPageLocation( nRenderer, aCellRange, aPixRect ) );
+
+ ++nRenderer;
+ }
+
+ nTabStart += nPages[nTab];
+ }
+ }
+
+ bLocInitialized = true;
+}
+
+bool ScPrintFuncCache::FindLocation( const ScAddress& rCell, ScPrintPageLocation& rLocation ) const
+{
+ for ( std::vector<ScPrintPageLocation>::const_iterator aIter(aLocations.begin());
+ aIter != aLocations.end(); aIter++ )
+ {
+ if ( aIter->aCellRange.In( rCell ) )
+ {
+ rLocation = *aIter;
+ return true;
+ }
+ }
+ return false; // not found
+}
+
+sal_Bool ScPrintFuncCache::IsSameSelection( const ScPrintSelectionStatus& rStatus ) const
+{
+ return aSelection == rStatus;
+}
+
+SCTAB ScPrintFuncCache::GetTabForPage( long nPage ) const
+{
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nTab = 0;
+ while ( nTab < nTabCount && nPage >= nPages[nTab] )
+ nPage -= nPages[nTab++];
+ return nTab;
+}
+
+long ScPrintFuncCache::GetTabStart( SCTAB nTab ) const
+{
+ long nRet = 0;
+ for ( SCTAB i=0; i<nTab; i++ )
+ nRet += nPages[i];
+ return nRet;
+}
+
+long ScPrintFuncCache::GetDisplayStart( SCTAB nTab ) const
+{
+ //! merge with lcl_GetDisplayStart in preview?
+
+ long nDisplayStart = 0;
+ ScDocument* pDoc = pDocSh->GetDocument();
+ for (SCTAB i=0; i<nTab; i++)
+ {
+ if ( pDoc->NeedPageResetAfterTab(i) )
+ nDisplayStart = 0;
+ else
+ nDisplayStart += nPages[i];
+ }
+ return nDisplayStart;
+}
+
+
diff --git a/sc/source/ui/view/pgbrksh.cxx b/sc/source/ui/view/pgbrksh.cxx
new file mode 100644
index 000000000000..d5e3450f3e5a
--- /dev/null
+++ b/sc/source/ui/view/pgbrksh.cxx
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svl/srchitem.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/request.hxx>
+#include <svl/whiter.hxx>
+
+#include "pgbrksh.hxx"
+#include "tabvwsh.hxx"
+#include "scresid.hxx"
+#include "document.hxx"
+#include "sc.hrc"
+
+//------------------------------------------------------------------------
+
+#define ScPageBreakShell
+#include "scslots.hxx"
+
+//------------------------------------------------------------------------
+
+TYPEINIT1( ScPageBreakShell, SfxShell );
+
+SFX_IMPL_INTERFACE(ScPageBreakShell, SfxShell, ScResId(SCSTR_PAGEBREAKSHELL))
+{
+ SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_PAGEBREAK) );
+}
+
+
+//------------------------------------------------------------------------
+ScPageBreakShell::ScPageBreakShell( ScTabViewShell* pViewSh ) :
+ SfxShell(pViewSh)
+{
+ SetPool( &pViewSh->GetPool() );
+ ScViewData* pViewData = pViewSh->GetViewData();
+ ::svl::IUndoManager* pMgr = pViewData->GetSfxDocShell()->GetUndoManager();
+ SetUndoManager( pMgr );
+ if ( !pViewData->GetDocument()->IsUndoEnabled() )
+ {
+ pMgr->SetMaxUndoActionCount( 0 );
+ }
+ SetHelpId( HID_SCSHELL_PAGEBREAK );
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("PageBreak")));
+}
+
+//------------------------------------------------------------------------
+ScPageBreakShell::~ScPageBreakShell()
+{
+}
+
+
diff --git a/sc/source/ui/view/pivotsh.cxx b/sc/source/ui/view/pivotsh.cxx
new file mode 100644
index 000000000000..028307400a2c
--- /dev/null
+++ b/sc/source/ui/view/pivotsh.cxx
@@ -0,0 +1,204 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svl/srchitem.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/request.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/msgbox.hxx>
+
+#include "sc.hrc"
+#include "pivotsh.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "scresid.hxx"
+#include "document.hxx"
+#include "dpobject.hxx"
+#include "dpshttab.hxx"
+#include "dbdocfun.hxx"
+#include "uiitems.hxx"
+//CHINA001 #include "pfiltdlg.hxx"
+#include "scabstdlg.hxx" //CHINA001
+//------------------------------------------------------------------------
+
+#define ScPivotShell
+#include "scslots.hxx"
+
+//------------------------------------------------------------------------
+
+TYPEINIT1( ScPivotShell, SfxShell );
+
+SFX_IMPL_INTERFACE(ScPivotShell, SfxShell, ScResId(SCSTR_PIVOTSHELL))
+{
+ SFX_POPUPMENU_REGISTRATION( ScResId(RID_POPUP_PIVOT) );
+}
+
+
+//------------------------------------------------------------------------
+
+ScPivotShell::ScPivotShell( ScTabViewShell* pViewSh ) :
+ SfxShell(pViewSh),
+ pViewShell( pViewSh )
+{
+ SetPool( &pViewSh->GetPool() );
+ ScViewData* pViewData = pViewSh->GetViewData();
+ ::svl::IUndoManager* pMgr = pViewData->GetSfxDocShell()->GetUndoManager();
+ SetUndoManager( pMgr );
+ if ( !pViewData->GetDocument()->IsUndoEnabled() )
+ {
+ pMgr->SetMaxUndoActionCount( 0 );
+ }
+ SetHelpId( HID_SCSHELL_PIVOTSH );
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Pivot")));
+}
+
+//------------------------------------------------------------------------
+ScPivotShell::~ScPivotShell()
+{
+}
+
+//------------------------------------------------------------------------
+void ScPivotShell::Execute( SfxRequest& rReq )
+{
+ switch ( rReq.GetSlot() )
+ {
+ case SID_PIVOT_RECALC:
+ pViewShell->RecalcPivotTable();
+ break;
+
+ case SID_PIVOT_KILL:
+ pViewShell->DeletePivotTable();
+ break;
+
+ case SID_DP_FILTER:
+ {
+ ScDPObject* pDPObj = GetCurrDPObject();
+ if( pDPObj )
+ {
+ ScQueryParam aQueryParam;
+ SCTAB nSrcTab = 0;
+ const ScSheetSourceDesc* pDesc = pDPObj->GetSheetDesc();
+ DBG_ASSERT( pDesc, "no sheet source for DP filter dialog" );
+ if( pDesc )
+ {
+ aQueryParam = pDesc->aQueryParam;
+ nSrcTab = pDesc->aSourceRange.aStart.Tab();
+ }
+
+ ScViewData* pViewData = pViewShell->GetViewData();
+ SfxItemSet aArgSet( pViewShell->GetPool(),
+ SCITEM_QUERYDATA, SCITEM_QUERYDATA );
+ aArgSet.Put( ScQueryItem( SCITEM_QUERYDATA, pViewData, &aQueryParam ) );
+
+ //CHINA001 ScPivotFilterDlg* pDlg = new ScPivotFilterDlg(
+ //CHINA001 pViewShell->GetDialogParent(), aArgSet, nSrcTab );
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScPivotFilterDlg* pDlg = pFact->CreateScPivotFilterDlg( pViewShell->GetDialogParent(),
+ aArgSet, nSrcTab,
+ RID_SCDLG_PIVOTFILTER);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ if( pDlg->Execute() == RET_OK )
+ {
+ ScSheetSourceDesc aNewDesc;
+ if( pDesc )
+ aNewDesc = *pDesc;
+
+ const ScQueryItem& rQueryItem = pDlg->GetOutputItem();
+ aNewDesc.aQueryParam = rQueryItem.GetQueryData();
+
+ ScDPObject aNewObj( *pDPObj );
+ aNewObj.SetSheetDesc( aNewDesc );
+ ScDBDocFunc aFunc( *pViewData->GetDocShell() );
+ aFunc.DataPilotUpdate( pDPObj, &aNewObj, sal_True, sal_False );
+ pViewData->GetView()->CursorPosChanged(); // shells may be switched
+ }
+ delete pDlg;
+ }
+ }
+ break;
+ }
+}
+
+//------------------------------------------------------------------------
+void __EXPORT ScPivotShell::GetState( SfxItemSet& rSet )
+{
+ ScDocShell* pDocSh = pViewShell->GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ sal_Bool bDisable = pDocSh->IsReadOnly() || pDoc->GetChangeTrack();
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while (nWhich)
+ {
+ switch (nWhich)
+ {
+ case SID_PIVOT_RECALC:
+ case SID_PIVOT_KILL:
+ {
+ //! move ReadOnly check to idl flags
+ if ( bDisable )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+ case SID_DP_FILTER:
+ {
+ ScDPObject* pDPObj = GetCurrDPObject();
+ if( bDisable || !pDPObj || !pDPObj->IsSheetData() )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+
+//------------------------------------------------------------------------
+
+ScDPObject* ScPivotShell::GetCurrDPObject()
+{
+ const ScViewData& rViewData = *pViewShell->GetViewData();
+ return rViewData.GetDocument()->GetDPAtCursor(
+ rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo() );
+}
+
diff --git a/sc/source/ui/view/preview.cxx b/sc/source/ui/view/preview.cxx
new file mode 100644
index 000000000000..4f3f1d753f32
--- /dev/null
+++ b/sc/source/ui/view/preview.cxx
@@ -0,0 +1,1603 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include <tools/pstm.hxx>
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <svtools/colorcfg.hxx>
+#include <svx/fmview.hxx>
+#include <editeng/sizeitem.hxx>
+#include <svx/svdpagv.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svtools/accessibilityoptions.hxx>
+#include <svl/itemset.hxx>
+#include <tools/multisel.hxx>
+#include <vcl/waitobj.hxx>
+#include <vcl/sound.hxx>
+
+#include "preview.hxx"
+#include "prevwsh.hxx"
+#include "prevloc.hxx"
+#include "docsh.hxx"
+#include "docfunc.hxx"
+#include "printfun.hxx"
+#include "printopt.hxx"
+#include "stlpool.hxx"
+#include "undostyl.hxx"
+#include "drwlayer.hxx"
+#include "scmod.hxx"
+#include "globstr.hrc"
+#include "sc.hrc" // fuer ShellInvalidate
+#include "AccessibleDocumentPagePreview.hxx"
+#include <vcl/lineinfo.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include "attrib.hxx"
+#include "pagepar.hxx"
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include "AccessibilityHints.hxx"
+#include <vcl/svapp.hxx>
+#include "viewutil.hxx"
+
+// STATIC DATA -----------------------------------------------------------
+
+//==================================================================
+
+#define SC_PREVIEW_SHADOWSIZE 2
+
+long lcl_GetDisplayStart( SCTAB nTab, ScDocument* pDoc, long* pPages )
+{
+ long nDisplayStart = 0;
+ for (SCTAB i=0; i<nTab; i++)
+ {
+ if ( pDoc->NeedPageResetAfterTab(i) )
+ nDisplayStart = 0;
+ else
+ nDisplayStart += pPages[i];
+ }
+ return nDisplayStart;
+}
+
+
+ScPreview::ScPreview( Window* pParent, ScDocShell* pDocSh, ScPreviewShell* pViewSh ) :
+ Window( pParent ),
+ nPageNo( 0 ),
+ nZoom( 100 ),
+ bValid( sal_False ),
+ nTabsTested( 0 ),
+ nTab( 0 ),
+ nTabStart( 0 ),
+ nDisplayStart( 0 ),
+ nTotalPages( 0 ),
+ bStateValid( sal_False ),
+ bLocationValid( sal_False ),
+ pLocationData( NULL ),
+ pDrawView( NULL ),
+ bInPaint( sal_False ),
+ bInGetState( sal_False ),
+ pDocShell( pDocSh ),
+ pViewShell( pViewSh ),
+ bLeftRulerMove( sal_False ),
+ bRightRulerMove( sal_False ),
+ bTopRulerMove( sal_False ),
+ bBottomRulerMove( sal_False ),
+ bHeaderRulerMove( sal_False ),
+ bFooterRulerMove( sal_False ),
+ bLeftRulerChange( sal_False ),
+ bRightRulerChange( sal_False ),
+ bTopRulerChange( sal_False ),
+ bBottomRulerChange( sal_False ),
+ bHeaderRulerChange( sal_False ),
+ bFooterRulerChange( sal_False ),
+ bPageMargin ( sal_False ),
+ bColRulerMove( sal_False ),
+ mnScale( 0 ),
+ nColNumberButttonDown( 0 ),
+ nHeaderHeight ( 0 ),
+ nFooterHeight ( 0 )
+{
+ SetOutDevViewType( OUTDEV_VIEWTYPE_PRINTPREVIEW ); //#106611#
+ SetBackground();
+
+ SetHelpId( HID_SC_WIN_PREVIEW );
+ SetUniqueId( HID_SC_WIN_PREVIEW );
+
+ SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
+}
+
+
+__EXPORT ScPreview::~ScPreview()
+{
+ delete pDrawView;
+ delete pLocationData;
+}
+
+void ScPreview::UpdateDrawView() // nTab muss richtig sein
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScDrawLayer* pModel = pDoc->GetDrawLayer(); // ist nicht 0
+
+ // #114135#
+ if ( pModel )
+ {
+ SdrPage* pPage = pModel->GetPage(nTab);
+ if ( pDrawView && ( !pDrawView->GetSdrPageView() || pDrawView->GetSdrPageView()->GetPage() != pPage ) )
+ {
+ // die angezeigte Page der DrawView umzustellen (s.u.) funktioniert nicht ?!?
+ delete pDrawView;
+ pDrawView = NULL;
+ }
+
+ if ( !pDrawView ) // neu anlegen?
+ {
+ pDrawView = new FmFormView( pModel, this );
+ // #55259# die DrawView uebernimmt den Design-Modus vom Model
+ // (Einstellung "Im Entwurfsmodus oeffnen"), darum hier zuruecksetzen
+ pDrawView->SetDesignMode( sal_True );
+ pDrawView->SetPrintPreview( sal_True );
+ pDrawView->ShowSdrPage(pPage);
+ }
+#if 0
+ else if ( !pDrawView->GetSdrPageView()) // angezeigte Page umstellen
+ {
+ pDrawView->HideSdrPage();
+ pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
+ }
+#endif
+ }
+ else if ( pDrawView )
+ {
+ delete pDrawView; // fuer diese Tabelle nicht gebraucht
+ pDrawView = NULL;
+ }
+}
+
+
+void ScPreview::TestLastPage()
+{
+ if (nPageNo >= nTotalPages)
+ {
+ if (nTotalPages)
+ {
+ nPageNo = nTotalPages - 1;
+ nTab = nTabCount - 1;
+ while (nTab > 0 && !nPages[nTab]) // letzte nicht leere Tabelle
+ --nTab;
+ DBG_ASSERT(nPages[nTab],"alle Tabellen leer?");
+ nTabPage = nPages[nTab] - 1;
+ nTabStart = 0;
+ for (sal_uInt16 i=0; i<nTab; i++)
+ nTabStart += nPages[i];
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ nDisplayStart = lcl_GetDisplayStart( nTab, pDoc, nPages );
+ }
+ else // leeres Dokument
+ {
+ nTab = 0;
+ nPageNo = nTabPage = nTabStart = nDisplayStart = 0;
+ aState.nPrintTab = 0;
+ aState.nStartCol = aState.nEndCol = 0;
+ aState.nStartRow = aState.nEndRow = 0;
+ aState.nZoom = 0;
+ aState.nPagesX = aState.nPagesY = 0;
+ aState.nTabPages = aState.nTotalPages =
+ aState.nPageStart = aState.nDocPages = 0;
+ }
+ }
+}
+
+
+void ScPreview::CalcPages( SCTAB /*nToWhichTab*/ )
+{
+ WaitObject( this );
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ nTabCount = pDoc->GetTableCount();
+
+ //SCTAB nAnz = Min( nTabCount, SCTAB(nToWhichTab+1) );
+ SCTAB nAnz = nTabCount;
+ SCTAB nStart = nTabsTested;
+ if (!bValid)
+ {
+ nStart = 0;
+ nTotalPages = 0;
+ nTabsTested = 0;
+ }
+
+ // update all pending row heights with a single progress bar,
+ // instead of a separate progress for each sheet from ScPrintFunc
+ pDocShell->UpdatePendingRowHeights( nAnz-1, true );
+
+ // PrintOptions is passed to PrintFunc for SkipEmpty flag,
+ // but always all sheets are used (there is no selected sheet)
+ ScPrintOptions aOptions = SC_MOD()->GetPrintOptions();
+
+ for (SCTAB i=nStart; i<nAnz; i++)
+ {
+ long nAttrPage = i > 0 ? nFirstAttr[i-1] : 1;
+
+ long nThisStart = nTotalPages;
+ ScPrintFunc aPrintFunc( this, pDocShell, i, nAttrPage, 0, NULL, &aOptions );
+ long nThisTab = aPrintFunc.GetTotalPages();
+ nPages[i] = nThisTab;
+ nTotalPages += nThisTab;
+ nFirstAttr[i] = aPrintFunc.GetFirstPageNo(); // behalten oder aus Vorlage
+
+ if (nPageNo>=nThisStart && nPageNo<nTotalPages)
+ {
+ nTab = i;
+ nTabPage = nPageNo - nThisStart;
+ nTabStart = nThisStart;
+
+ aPrintFunc.GetPrintState( aState );
+ aPageSize = aPrintFunc.GetPageSize();
+ }
+ }
+
+ nDisplayStart = lcl_GetDisplayStart( nTab, pDoc, nPages );
+
+ if (nAnz > nTabsTested)
+ nTabsTested = nAnz;
+
+ // testen, ob hinter letzter Seite
+
+ if ( nTabsTested >= nTabCount )
+ TestLastPage();
+
+ aState.nDocPages = nTotalPages;
+
+ bValid = sal_True;
+ bStateValid = sal_True;
+ DoInvalidate();
+}
+
+
+void ScPreview::RecalcPages() // nur nPageNo geaendert
+{
+ if (!bValid)
+ return; // dann wird CalcPages aufgerufen
+
+ SCTAB nOldTab = nTab;
+
+ sal_Bool bDone = sal_False;
+ while (nPageNo >= nTotalPages && nTabsTested < nTabCount)
+ {
+ CalcPages( nTabsTested );
+ bDone = sal_True;
+ }
+
+ if (!bDone)
+ {
+ long nPartPages = 0;
+ for (SCTAB i=0; i<nTabsTested; i++)
+ {
+ long nThisStart = nPartPages;
+ nPartPages += nPages[i];
+
+ if (nPageNo>=nThisStart && nPageNo<nPartPages)
+ {
+ nTab = i;
+ nTabPage = nPageNo - nThisStart;
+ nTabStart = nThisStart;
+
+// aPageSize = aPrintFunc.GetPageSize();
+ }
+ }
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ nDisplayStart = lcl_GetDisplayStart( nTab, pDoc, nPages );
+ }
+
+ TestLastPage(); // testen, ob hinter letzter Seite
+
+ if ( nTab != nOldTab )
+ bStateValid = sal_False;
+
+ DoInvalidate();
+}
+
+
+void ScPreview::DoPrint( ScPreviewLocationData* pFillLocation )
+{
+ if (!bValid)
+ {
+ CalcPages(0);
+ RecalcPages();
+ UpdateDrawView(); // Tabelle evtl. geaendert
+ }
+
+ Fraction aPreviewZoom( nZoom, 100 );
+ Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
+ MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
+
+ sal_Bool bDoPrint = ( pFillLocation == NULL );
+ sal_Bool bValidPage = ( nPageNo < nTotalPages );
+
+ ScModule* pScMod = SC_MOD();
+ const svtools::ColorConfig& rColorCfg = pScMod->GetColorConfig();
+ Color aBackColor( rColorCfg.GetColorValue(svtools::APPBACKGROUND).nColor );
+
+ if ( bDoPrint && ( aOffset.X() < 0 || aOffset.Y() < 0 ) && bValidPage )
+ {
+ SetMapMode( aMMMode );
+ SetLineColor();
+ SetFillColor(aBackColor);
+
+ Size aWinSize = GetOutputSize();
+ if ( aOffset.X() < 0 )
+ DrawRect(Rectangle( 0, 0, -aOffset.X(), aWinSize.Height() ));
+ if ( aOffset.Y() < 0 )
+ DrawRect(Rectangle( 0, 0, aWinSize.Width(), -aOffset.Y() ));
+ }
+
+ Size aLocalPageSize;
+ if ( bValidPage )
+ {
+ ScPrintOptions aOptions = pScMod->GetPrintOptions();
+
+ ScPrintFunc* pPrintFunc;
+ if (bStateValid)
+ pPrintFunc = new ScPrintFunc( this, pDocShell, aState, &aOptions );
+ else
+ pPrintFunc = new ScPrintFunc( this, pDocShell, nTab, nFirstAttr[nTab], nTotalPages, NULL, &aOptions );
+
+ pPrintFunc->SetOffset(aOffset);
+ pPrintFunc->SetManualZoom(nZoom);
+ pPrintFunc->SetDateTime(aDate,aTime);
+ pPrintFunc->SetClearFlag(sal_True);
+ pPrintFunc->SetUseStyleColor( pScMod->GetAccessOptions().GetIsForPagePreviews() );
+
+ pPrintFunc->SetDrawView( pDrawView );
+
+ // MultiSelection fuer die eine Seite muss etwas umstaendlich erzeugt werden...
+ Range aPageRange( nPageNo+1, nPageNo+1 );
+ MultiSelection aPage( aPageRange );
+ aPage.SetTotalRange( Range(0,RANGE_MAX) );
+ aPage.Select( aPageRange );
+
+ long nPrinted = pPrintFunc->DoPrint( aPage, nTabStart, nDisplayStart, bDoPrint, NULL, pFillLocation );
+ DBG_ASSERT(nPrinted<=1, "was'n nu los?");
+
+ SetMapMode(aMMMode);
+// sal_uInt16 nPrintZoom = pPrintFunc->GetZoom();
+
+ if (nPrinted) // wenn nichts, alles grau zeichnen
+ {
+ aLocalPageSize = pPrintFunc->GetPageSize();
+ aLocalPageSize.Width() = (long) (aLocalPageSize.Width() * HMM_PER_TWIPS );
+ aLocalPageSize.Height() = (long) (aLocalPageSize.Height() * HMM_PER_TWIPS );
+ }
+
+ if (!bStateValid)
+ {
+ pPrintFunc->GetPrintState( aState );
+ aState.nDocPages = nTotalPages;
+ bStateValid = sal_True;
+ }
+ delete pPrintFunc;
+ }
+
+ if ( bDoPrint )
+ {
+ long nPageEndX = aLocalPageSize.Width() - aOffset.X();
+ long nPageEndY = aLocalPageSize.Height() - aOffset.Y();
+ if ( !bValidPage )
+ nPageEndX = nPageEndY = 0;
+
+ Size aWinSize = GetOutputSize();
+ Point aWinEnd( aWinSize.Width(), aWinSize.Height() );
+ sal_Bool bRight = nPageEndX <= aWinEnd.X();
+ sal_Bool bBottom = nPageEndY <= aWinEnd.Y();
+ if (bRight || bBottom)
+ {
+ SetLineColor();
+ SetFillColor(aBackColor);
+ if (bRight)
+ DrawRect(Rectangle(nPageEndX,0, aWinEnd.X(),aWinEnd.Y()));
+ if (bBottom)
+ {
+ if (bRight)
+ DrawRect(Rectangle(0,nPageEndY, nPageEndX,aWinEnd.Y())); // Ecke nicht doppelt
+ else
+ DrawRect(Rectangle(0,nPageEndY, aWinEnd.X(),aWinEnd.Y()));
+ }
+ }
+
+ if ( bValidPage )
+ {
+ Color aBorderColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+
+ // draw border
+
+ if ( aOffset.X() <= 0 || aOffset.Y() <= 0 || bRight || bBottom )
+ {
+ SetLineColor( aBorderColor );
+ SetFillColor();
+
+ Rectangle aPixel( LogicToPixel( Rectangle( -aOffset.X(), -aOffset.Y(), nPageEndX, nPageEndY ) ) );
+ --aPixel.Right();
+ --aPixel.Bottom();
+ DrawRect( PixelToLogic( aPixel ) );
+ }
+
+ // draw shadow
+
+ SetLineColor();
+ SetFillColor( aBorderColor );
+
+ Rectangle aPixel;
+
+ aPixel = LogicToPixel( Rectangle( nPageEndX, -aOffset.Y(), nPageEndX, nPageEndY ) );
+ aPixel.Top() += SC_PREVIEW_SHADOWSIZE;
+ aPixel.Right() += SC_PREVIEW_SHADOWSIZE - 1;
+ aPixel.Bottom() += SC_PREVIEW_SHADOWSIZE - 1;
+ DrawRect( PixelToLogic( aPixel ) );
+
+ aPixel = LogicToPixel( Rectangle( -aOffset.X(), nPageEndY, nPageEndX, nPageEndY ) );
+ aPixel.Left() += SC_PREVIEW_SHADOWSIZE;
+ aPixel.Right() += SC_PREVIEW_SHADOWSIZE - 1;
+ aPixel.Bottom() += SC_PREVIEW_SHADOWSIZE - 1;
+ DrawRect( PixelToLogic( aPixel ) );
+ }
+ }
+}
+
+//Issue51656 Add resizeable margin on page preview from maoyg
+void __EXPORT ScPreview::Paint( const Rectangle& /* rRect */ )
+{
+ if (!bValid)
+ {
+ CalcPages(0);
+ RecalcPages();
+ UpdateDrawView(); // Table possibly amended
+ }
+
+ Fraction aPreviewZoom( nZoom, 100 );
+ Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
+ MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
+
+ ScModule* pScMod = SC_MOD();
+ const svtools::ColorConfig& rColorCfg = pScMod->GetColorConfig();
+ Color aBackColor( rColorCfg.GetColorValue(svtools::APPBACKGROUND).nColor );
+
+ if ( aOffset.X() < 0 || aOffset.Y() < 0 )
+ {
+ SetMapMode( aMMMode );
+ SetLineColor();
+ SetFillColor(aBackColor);
+
+ Size aWinSize = GetOutputSize();
+ if ( aOffset.X() < 0 )
+ DrawRect(Rectangle( 0, 0, -aOffset.X(), aWinSize.Height() ));
+ if ( aOffset.Y() < 0 )
+ DrawRect(Rectangle( 0, 0, aWinSize.Width(), -aOffset.Y() ));
+ }
+
+ long nLeftMargin = 0;
+ long nRightMargin = 0;
+ long nTopMargin = 0;
+ long nBottomMargin = 0;
+ sal_Bool bHeaderOn = sal_False;
+ sal_Bool bFooterOn = sal_False;
+
+ ScDocument* pDoc = pDocShell->GetDocument();
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ Size aPaintPageSize;
+ if ( nPageNo < nTotalPages )
+ {
+ ScPrintOptions aOptions = SC_MOD()->GetPrintOptions();
+
+ ScPrintFunc* pPrintFunc;
+ if ( bStateValid )
+ pPrintFunc = new ScPrintFunc( pDocShell, this, aState, &aOptions );
+ else
+ pPrintFunc = new ScPrintFunc( pDocShell, this, nTab, nFirstAttr[nTab], nTotalPages, NULL, &aOptions );
+
+ pPrintFunc->SetOffset(aOffset);
+ pPrintFunc->SetManualZoom(nZoom);
+ pPrintFunc->SetDateTime(aDate,aTime);
+ pPrintFunc->SetClearFlag(sal_True);
+ pPrintFunc->SetUseStyleColor( pScMod->GetAccessOptions().GetIsForPagePreviews() );
+ pPrintFunc->SetDrawView( pDrawView );
+
+ // Multi Selection for one side must be something umstaendlich generated ...
+ Range aPageRange( nPageNo+1, nPageNo+1 );
+ MultiSelection aPage( aPageRange );
+ aPage.SetTotalRange( Range(0,RANGE_MAX) );
+ aPage.Select( aPageRange );
+
+ long nPrinted = pPrintFunc->DoPrint( aPage, nTabStart, nDisplayStart );
+ DBG_ASSERT(nPrinted<=1, "was'n nu los?");
+
+ SetMapMode(aMMMode);
+
+ //init nLeftMargin ... in the ScPrintFunc::InitParam!!!
+ nLeftMargin = pPrintFunc->GetLeftMargin();
+ nRightMargin = pPrintFunc->GetRightMargin();
+ nTopMargin = pPrintFunc->GetTopMargin();
+ nBottomMargin = pPrintFunc->GetBottomMargin();
+ nHeaderHeight = pPrintFunc->GetHeader().nHeight;
+ nFooterHeight = pPrintFunc->GetFooter().nHeight;
+ bHeaderOn = pPrintFunc->GetHeader().bEnable;
+ bFooterOn = pPrintFunc->GetFooter().bEnable;
+ mnScale = pPrintFunc->GetZoom();
+
+ Rectangle aPixRect;
+ Rectangle aRectCellPosition;
+ Rectangle aRectPosition;
+ GetLocationData().GetMainCellRange( aPageArea, aPixRect );
+ if( !bLayoutRTL )
+ {
+ GetLocationData().GetCellPosition( aPageArea.aStart, aRectPosition );
+ nLeftPosition = aRectPosition.Left();
+ for( SCCOL i = aPageArea.aStart.Col(); i <= aPageArea.aEnd.Col(); i++ )
+ {
+ GetLocationData().GetCellPosition( ScAddress( i,aPageArea.aStart.Row(),aPageArea.aStart.Tab()),aRectCellPosition );
+ nRight[i] = aRectCellPosition.Right();
+ }
+ }
+ else
+ {
+ GetLocationData().GetCellPosition( aPageArea.aEnd, aRectPosition );
+ nLeftPosition = aRectPosition.Right()+1;
+
+ GetLocationData().GetCellPosition( aPageArea.aStart,aRectCellPosition );
+ nRight[ aPageArea.aEnd.Col() ] = aRectCellPosition.Left();
+ for( SCCOL i = aPageArea.aEnd.Col(); i > aPageArea.aStart.Col(); i-- )
+ {
+ GetLocationData().GetCellPosition( ScAddress( i,aPageArea.aEnd.Row(),aPageArea.aEnd.Tab()),aRectCellPosition );
+ nRight[ i-1 ] = nRight[ i ] + aRectCellPosition.Right() - aRectCellPosition.Left() + 1;
+ }
+ }
+
+ if ( nPrinted ) // If nothing, all gray draw
+ {
+ aPaintPageSize = pPrintFunc->GetPageSize();
+ aPaintPageSize.Width() = (long) (aPaintPageSize.Width() * HMM_PER_TWIPS );
+ aPaintPageSize.Height() = (long) (aPaintPageSize.Height() * HMM_PER_TWIPS );
+
+ nLeftMargin = (long) ( nLeftMargin * HMM_PER_TWIPS );
+ nRightMargin = (long) ( nRightMargin * HMM_PER_TWIPS );
+ nTopMargin = (long) ( nTopMargin * HMM_PER_TWIPS );
+ nBottomMargin = (long) ( nBottomMargin * HMM_PER_TWIPS );
+ nHeaderHeight = (long) ( nHeaderHeight * HMM_PER_TWIPS * mnScale / 100 + nTopMargin );
+ nFooterHeight = (long) ( nFooterHeight * HMM_PER_TWIPS * mnScale / 100 + nBottomMargin );
+ }
+
+ if ( !bStateValid )
+ {
+ pPrintFunc->GetPrintState( aState );
+ aState.nDocPages = nTotalPages;
+ bStateValid = sal_True;
+ }
+
+ delete pPrintFunc;
+ }
+
+
+ long nPageEndX = aPaintPageSize.Width() - aOffset.X();
+ long nPageEndY = aPaintPageSize.Height() - aOffset.Y();
+ Size aWinSize = GetOutputSize();
+ Point aWinEnd( aWinSize.Width(), aWinSize.Height() );
+ sal_Bool bRight = nPageEndX <= aWinEnd.X();
+ sal_Bool bBottom = nPageEndY <= aWinEnd.Y();
+
+ if( bPageMargin )
+ {
+ SetMapMode(aMMMode);
+ SetLineColor( COL_BLACK );
+ DrawInvert( (long)( nTopMargin - aOffset.Y() ), POINTER_VSIZEBAR );
+ DrawInvert( (long)(nPageEndY - nBottomMargin ), POINTER_VSIZEBAR );
+ DrawInvert( (long)( nLeftMargin - aOffset.X() ), POINTER_HSIZEBAR );
+ DrawInvert( (long)( nPageEndX - nRightMargin ) , POINTER_HSIZEBAR );
+ if( bHeaderOn )
+ {
+ DrawInvert( nHeaderHeight - aOffset.Y(), POINTER_VSIZEBAR );
+ }
+ if( bFooterOn )
+ {
+ DrawInvert( nPageEndY - nFooterHeight, POINTER_VSIZEBAR );
+ }
+
+ SetMapMode( MapMode( MAP_PIXEL ) );
+ for( int i= aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ )
+ {
+ Point aColumnTop = LogicToPixel( Point( 0, -aOffset.Y() ) ,aMMMode );
+ SetLineColor( COL_BLACK );
+ SetFillColor( COL_BLACK );
+ DrawRect( Rectangle( Point( nRight[i] - 2, aColumnTop.Y() ),Point( nRight[i] + 2 , 4 + aColumnTop.Y()) ));
+ DrawLine( Point( nRight[i], aColumnTop.Y() ), Point( nRight[i], 10 + aColumnTop.Y()) );
+ }
+ SetMapMode( aMMMode );
+ }
+
+ if (bRight || bBottom)
+ {
+ SetMapMode(aMMMode);
+ SetLineColor();
+ SetFillColor(aBackColor);
+ if (bRight)
+ DrawRect(Rectangle(nPageEndX,0, aWinEnd.X(),aWinEnd.Y()));
+ if (bBottom)
+ {
+ if (bRight)
+ DrawRect(Rectangle(0,nPageEndY, nPageEndX,aWinEnd.Y())); // Ecke nicht doppelt
+ else
+ DrawRect(Rectangle(0,nPageEndY, aWinEnd.X(),aWinEnd.Y()));
+ }
+ }
+ pViewShell->UpdateScrollBars();
+}
+//Issue51656 Add resizeable margin on page preview from maoyg
+
+void __EXPORT ScPreview::Command( const CommandEvent& rCEvt )
+{
+ sal_uInt16 nCmd = rCEvt.GetCommand();
+ if ( nCmd == COMMAND_WHEEL || nCmd == COMMAND_STARTAUTOSCROLL || nCmd == COMMAND_AUTOSCROLL )
+ {
+ sal_Bool bDone = pViewShell->ScrollCommand( rCEvt );
+ if (!bDone)
+ Window::Command(rCEvt);
+ }
+ else if ( nCmd == COMMAND_CONTEXTMENU )
+ SfxDispatcher::ExecutePopup();
+ else
+ Window::Command( rCEvt );
+}
+
+
+void __EXPORT ScPreview::KeyInput( const KeyEvent& rKEvt )
+{
+ // The + and - keys can't be configured as accelerator entries, so they must be handled directly
+ // (in ScPreview, not ScPreviewShell -> only if the preview window has the focus)
+
+ const KeyCode& rKeyCode = rKEvt.GetKeyCode();
+ sal_uInt16 nKey = rKeyCode.GetCode();
+ sal_Bool bHandled = sal_False;
+ if(!rKeyCode.GetModifier())
+ {
+ sal_uInt16 nSlot = 0;
+ switch(nKey)
+ {
+ case KEY_ADD: nSlot = SID_PREVIEW_ZOOMIN; break;
+ case KEY_ESCAPE: nSlot = ScViewUtil::IsFullScreen( *pViewShell ) ? SID_CANCEL : SID_PREVIEW_CLOSE; break;
+ case KEY_SUBTRACT: nSlot = SID_PREVIEW_ZOOMOUT; break;
+ }
+ if(nSlot)
+ {
+ bHandled = sal_True;
+ pViewShell->GetViewFrame()->GetDispatcher()->Execute( nSlot, SFX_CALLMODE_ASYNCHRON );
+ }
+ }
+
+ if ( !bHandled && !pViewShell->KeyInput(rKEvt) )
+ Window::KeyInput(rKEvt);
+}
+
+
+const ScPreviewLocationData& ScPreview::GetLocationData()
+{
+ if ( !pLocationData )
+ {
+ pLocationData = new ScPreviewLocationData( pDocShell->GetDocument(), this );
+ bLocationValid = sal_False;
+ }
+ if ( !bLocationValid )
+ {
+ pLocationData->Clear();
+ DoPrint( pLocationData );
+ bLocationValid = sal_True;
+ }
+ return *pLocationData;
+}
+
+
+void ScPreview::DataChanged(sal_Bool bNewTime)
+{
+ if (bNewTime)
+ {
+ aDate = Date();
+ aTime = Time();
+ }
+
+ bValid = sal_False;
+ InvalidateLocationData( SC_HINT_DATACHANGED );
+ Invalidate();
+}
+
+
+String ScPreview::GetPosString()
+{
+ if (!bValid)
+ {
+ CalcPages(nTab);
+ UpdateDrawView(); // Tabelle evtl. geaendert
+ }
+
+ String aString( ScGlobal::GetRscString( STR_PAGE ) );
+ aString += ' ';
+ aString += String::CreateFromInt32(nPageNo+1);
+
+ if (nTabsTested >= nTabCount)
+ {
+ aString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " / " ));
+ aString += String::CreateFromInt32(nTotalPages);
+ }
+
+ return aString;
+}
+
+
+void ScPreview::SetZoom(sal_uInt16 nNewZoom)
+{
+ if (nNewZoom < 20)
+ nNewZoom = 20;
+ if (nNewZoom > 400)
+ nNewZoom = 400;
+ if (nNewZoom != nZoom)
+ {
+ nZoom = nNewZoom;
+
+ // apply new MapMode and call UpdateScrollBars to update aOffset
+
+ Fraction aPreviewZoom( nZoom, 100 );
+ Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
+ MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
+ SetMapMode( aMMMode );
+
+ bInPaint = sal_True; // don't scroll during SetYOffset in UpdateScrollBars
+ pViewShell->UpdateScrollBars();
+ bInPaint = sal_False;
+
+ bStateValid = sal_False;
+ InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED );
+ DoInvalidate();
+ Invalidate();
+ }
+}
+
+
+void ScPreview::SetPageNo( long nPage )
+{
+ nPageNo = nPage;
+ RecalcPages();
+ UpdateDrawView(); // Tabelle evtl. geaendert
+ InvalidateLocationData( SC_HINT_DATACHANGED );
+ Invalidate();
+}
+
+
+long ScPreview::GetFirstPage(SCTAB nTabP)
+{
+ SCTAB nDocTabCount = pDocShell->GetDocument()->GetTableCount();
+ if (nTabP >= nDocTabCount)
+ nTabP = nDocTabCount-1;
+
+ long nPage = 0;
+ if (nTabP>0)
+ {
+ CalcPages( nTabP );
+ UpdateDrawView(); // Tabelle evtl. geaendert
+
+ for (SCTAB i=0; i<nTabP; i++)
+ nPage += nPages[i];
+
+ // bei leerer Tabelle vorhergehende Seite
+
+ if ( nPages[nTabP]==0 && nPage > 0 )
+ --nPage;
+ }
+
+ return nPage;
+}
+
+
+Size lcl_GetDocPageSize( ScDocument* pDoc, SCTAB nTab )
+{
+ String aName = pDoc->GetPageStyle( nTab );
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aName, SFX_STYLE_FAMILY_PAGE );
+ if ( pStyleSheet )
+ {
+ SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
+ return ((const SvxSizeItem&) rStyleSet.Get(ATTR_PAGE_SIZE)).GetSize();
+ }
+ else
+ {
+ DBG_ERROR( "PageStyle not found" );
+ return Size();
+ }
+}
+
+
+sal_uInt16 ScPreview::GetOptimalZoom(sal_Bool bWidthOnly)
+{
+ double nWinScaleX = ScGlobal::nScreenPPTX / pDocShell->GetOutputFactor();
+ double nWinScaleY = ScGlobal::nScreenPPTY;
+ Size aWinSize = GetOutputSizePixel();
+
+ // desired margin is 0.25cm in default MapMode (like Writer),
+ // but some additional margin is introduced by integer scale values
+ // -> add only 0.10cm, so there is some margin in all cases.
+ Size aMarginSize( LogicToPixel( Size( 100, 100 ), MAP_100TH_MM ) );
+ aWinSize.Width() -= 2 * aMarginSize.Width();
+ aWinSize.Height() -= 2 * aMarginSize.Height();
+
+ Size aLocalPageSize = lcl_GetDocPageSize( pDocShell->GetDocument(), nTab );
+ if ( aLocalPageSize.Width() && aLocalPageSize.Height() )
+ {
+ long nZoomX = (long) ( aWinSize.Width() * 100 / ( aLocalPageSize.Width() * nWinScaleX ));
+ long nZoomY = (long) ( aWinSize.Height() * 100 / ( aLocalPageSize.Height() * nWinScaleY ));
+
+ long nOptimal = nZoomX;
+ if (!bWidthOnly && nZoomY<nOptimal)
+ nOptimal = nZoomY;
+
+ if (nOptimal<20)
+ nOptimal = 20;
+ if (nOptimal>400)
+ nOptimal = 400;
+
+ return (sal_uInt16) nOptimal;
+ }
+ else
+ return nZoom;
+}
+
+
+void ScPreview::SetXOffset( long nX )
+{
+ if ( aOffset.X() == nX )
+ return;
+
+ if (bValid)
+ {
+ long nDif = LogicToPixel(aOffset).X() - LogicToPixel(Point(nX,0)).X();
+ aOffset.X() = nX;
+ if (nDif && !bInPaint)
+ {
+ MapMode aOldMode = GetMapMode(); SetMapMode(MAP_PIXEL);
+ Scroll( nDif, 0 );
+ SetMapMode(aOldMode);
+ }
+ }
+ else
+ {
+ aOffset.X() = nX;
+ if (!bInPaint)
+ Invalidate();
+ }
+ InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED );
+ Paint(Rectangle());
+}
+
+
+void ScPreview::SetYOffset( long nY )
+{
+ if ( aOffset.Y() == nY )
+ return;
+
+ if (bValid)
+ {
+ long nDif = LogicToPixel(aOffset).Y() - LogicToPixel(Point(0,nY)).Y();
+ aOffset.Y() = nY;
+ if (nDif && !bInPaint)
+ {
+ MapMode aOldMode = GetMapMode(); SetMapMode(MAP_PIXEL);
+ Scroll( 0, nDif );
+ SetMapMode(aOldMode);
+ }
+ }
+ else
+ {
+ aOffset.Y() = nY;
+ if (!bInPaint)
+ Invalidate();
+ }
+ InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED );
+ Paint(Rectangle());
+}
+
+
+void ScPreview::DoInvalidate()
+{
+ // Wenn das ganze aus dem GetState der Shell gerufen wird,
+ // muss das Invalidate hinterher asynchron kommen...
+
+ if (bInGetState)
+ Application::PostUserEvent( STATIC_LINK( this, ScPreview, InvalidateHdl ) );
+ else
+ StaticInvalidate(); // sofort
+}
+
+void ScPreview::StaticInvalidate()
+{
+ // static method, because it's called asynchronously
+ // -> must use current viewframe
+
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if (!pViewFrm)
+ return;
+
+ SfxBindings& rBindings = pViewFrm->GetBindings();
+ rBindings.Invalidate(SID_STATUS_DOCPOS);
+ rBindings.Invalidate(SID_STATUS_PAGESTYLE);
+ rBindings.Invalidate(SID_PREVIEW_PREVIOUS);
+ rBindings.Invalidate(SID_PREVIEW_NEXT);
+ rBindings.Invalidate(SID_PREVIEW_FIRST);
+ rBindings.Invalidate(SID_PREVIEW_LAST);
+ rBindings.Invalidate(SID_ATTR_ZOOM);
+ rBindings.Invalidate(SID_PREVIEW_ZOOMIN);
+ rBindings.Invalidate(SID_PREVIEW_ZOOMOUT);
+ rBindings.Invalidate(SID_PREVIEW_SCALINGFACTOR);
+ rBindings.Invalidate(SID_ATTR_ZOOMSLIDER);
+}
+
+IMPL_STATIC_LINK( ScPreview, InvalidateHdl, void*, EMPTYARG )
+{
+ (void)pThis; // avoid warning
+
+ StaticInvalidate();
+ return 0;
+}
+
+void ScPreview::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged(rDCEvt);
+
+ if ( (rDCEvt.GetType() == DATACHANGED_PRINTER) ||
+ (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ if ( rDCEvt.GetType() == DATACHANGED_FONTS )
+ pDocShell->UpdateFontList();
+
+ if ( rDCEvt.GetType() == DATACHANGED_SETTINGS &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ // scroll bar size may have changed
+ pViewShell->InvalidateBorder(); // calls OuterResizePixel
+ }
+
+ Invalidate();
+ InvalidateLocationData( SC_HINT_DATACHANGED );
+ }
+}
+
+//Issue51656 Add resizeable margin on page preview from maoyg
+void __EXPORT ScPreview::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ Fraction aPreviewZoom( nZoom, 100 );
+ Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
+ MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
+
+ aButtonDownChangePoint = PixelToLogic( rMEvt.GetPosPixel(),aMMMode );
+ aButtonDownPt = PixelToLogic( rMEvt.GetPosPixel(),aMMMode );
+
+ CaptureMouse();
+
+ if( rMEvt.IsLeft() && GetPointer() == POINTER_HSIZEBAR )
+ {
+ SetMapMode( aMMMode );
+ if( bLeftRulerChange )
+ {
+ DrawInvert( aButtonDownChangePoint.X(), POINTER_HSIZEBAR );
+ bLeftRulerMove = sal_True;
+ bRightRulerMove = sal_False;
+ }
+ else if( bRightRulerChange )
+ {
+ DrawInvert( aButtonDownChangePoint.X(), POINTER_HSIZEBAR );
+ bLeftRulerMove = sal_False;
+ bRightRulerMove = sal_True;
+ }
+ }
+
+ if( rMEvt.IsLeft() && GetPointer() == POINTER_VSIZEBAR )
+ {
+ SetMapMode( aMMMode );
+ if( bTopRulerChange )
+ {
+ DrawInvert( aButtonDownChangePoint.Y(), POINTER_VSIZEBAR );
+ bTopRulerMove = sal_True;
+ bBottomRulerMove = sal_False;
+ }
+ else if( bBottomRulerChange )
+ {
+ DrawInvert( aButtonDownChangePoint.Y(), POINTER_VSIZEBAR );
+ bTopRulerMove = sal_False;
+ bBottomRulerMove = sal_True;
+ }
+ else if( bHeaderRulerChange )
+ {
+ DrawInvert( aButtonDownChangePoint.Y(), POINTER_VSIZEBAR );
+ bHeaderRulerMove = sal_True;
+ bFooterRulerMove = sal_False;
+ }
+ else if( bFooterRulerChange )
+ {
+ DrawInvert( aButtonDownChangePoint.Y(), POINTER_VSIZEBAR );
+ bHeaderRulerMove = sal_False;
+ bFooterRulerMove = sal_True;
+ }
+ }
+
+ if( rMEvt.IsLeft() && GetPointer() == POINTER_HSPLIT )
+ {
+ Point aNowPt = rMEvt.GetPosPixel();
+ SCCOL i = 0;
+ for( i = aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ )
+ {
+ if( aNowPt.X() < nRight[i] + 2 && aNowPt.X() > nRight[i] - 2 )
+ {
+ nColNumberButttonDown = i;
+ break;
+ }
+ }
+ if( i == aPageArea.aEnd.Col()+1 )
+ return;
+
+ SetMapMode( aMMMode );
+ if( nColNumberButttonDown == aPageArea.aStart.Col() )
+ DrawInvert( PixelToLogic( Point( nLeftPosition, 0 ),aMMMode ).X() ,POINTER_HSPLIT );
+ else
+ DrawInvert( PixelToLogic( Point( nRight[ nColNumberButttonDown-1 ], 0 ),aMMMode ).X() ,POINTER_HSPLIT );
+
+ DrawInvert( aButtonDownChangePoint.X(), POINTER_HSPLIT );
+ bColRulerMove = sal_True;
+ }
+}
+
+void __EXPORT ScPreview::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ Fraction aPreviewZoom( nZoom, 100 );
+ Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
+ MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
+
+ aButtonUpPt = PixelToLogic( rMEvt.GetPosPixel(),aMMMode );
+
+ long nWidth = (long) lcl_GetDocPageSize(pDocShell->GetDocument(), nTab).Width();
+ long nHeight = (long) lcl_GetDocPageSize(pDocShell->GetDocument(), nTab).Height();
+
+ if( rMEvt.IsLeft() && GetPointer() == POINTER_HSIZEBAR )
+ {
+ SetPointer( Pointer( POINTER_ARROW ) );
+
+ sal_Bool bMoveRulerAction= sal_True;
+
+ ScDocument * pDoc = pDocShell->GetDocument();
+ String aOldName = pDoc->GetPageStyle( nTab );
+ sal_Bool bUndo( pDoc->IsUndoEnabled() );
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aOldName, SFX_STYLE_FAMILY_PAGE );
+
+ if ( pStyleSheet )
+ {
+ ScStyleSaveData aOldData;
+ if( bUndo )
+ aOldData.InitFromStyle( pStyleSheet );
+
+ SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
+
+ SvxLRSpaceItem aLRItem = ( const SvxLRSpaceItem& ) rStyleSet.Get( ATTR_LRSPACE );
+
+ if(( bLeftRulerChange || bRightRulerChange ) && ( aButtonUpPt.X() <= ( 0 - aOffset.X() ) || aButtonUpPt.X() > nWidth * HMM_PER_TWIPS - aOffset.X() ) )
+ {
+ bMoveRulerAction = sal_False;
+ Paint(Rectangle(0,0,10000,10000));
+ }
+ else if( bLeftRulerChange && ( aButtonUpPt.X() / HMM_PER_TWIPS > nWidth - aLRItem.GetRight() - aOffset.X() / HMM_PER_TWIPS ) )
+ {
+ bMoveRulerAction = sal_False;
+ Paint(Rectangle(0,0,10000,10000));
+ }
+ else if( bRightRulerChange && ( aButtonUpPt.X() / HMM_PER_TWIPS < aLRItem.GetLeft() - aOffset.X() / HMM_PER_TWIPS ) )
+ {
+ bMoveRulerAction = sal_False;
+ Paint(Rectangle(0,0,10000,10000));
+ }
+ else if( aButtonDownPt.X() == aButtonUpPt.X() )
+ {
+ bMoveRulerAction = sal_False;
+ DrawInvert( aButtonUpPt.X(), POINTER_HSIZEBAR );
+ }
+ if( bMoveRulerAction )
+ {
+ if( bLeftRulerChange && bLeftRulerMove )
+ {
+ aLRItem.SetLeft( (long)( aButtonUpPt.X() / HMM_PER_TWIPS + aOffset.X() / HMM_PER_TWIPS ));
+ rStyleSet.Put( aLRItem );
+ }
+ else if( bRightRulerChange && bRightRulerMove )
+ {
+ aLRItem.SetRight( (long)( nWidth - aButtonUpPt.X() / HMM_PER_TWIPS - aOffset.X() / HMM_PER_TWIPS ));
+ rStyleSet.Put( aLRItem );
+ }
+
+ ScStyleSaveData aNewData;
+ aNewData.InitFromStyle( pStyleSheet );
+ if( bUndo )
+ {
+ pDocShell->GetUndoManager()->AddUndoAction(
+ new ScUndoModifyStyle( pDocShell, SFX_STYLE_FAMILY_PAGE,
+ aOldData, aNewData ) );
+ }
+
+ if ( ValidTab( nTab ) )
+ {
+ ScPrintFunc aPrintFunc( pDocShell, this, nTab );
+ aPrintFunc.UpdatePages();
+ }
+
+ Rectangle aRect(0,0,10000,10000);
+ Paint( aRect );
+ bLeftRulerChange = sal_False;
+ bRightRulerChange = sal_False;
+ }
+ }
+ bLeftRulerMove = sal_False;
+ bRightRulerMove = sal_False;
+ }
+
+ if( rMEvt.IsLeft() && GetPointer() == POINTER_VSIZEBAR )
+ {
+ SetPointer( POINTER_ARROW );
+
+ sal_Bool bMoveRulerAction = sal_True;
+ if( ( bTopRulerChange || bBottomRulerChange || bHeaderRulerChange || bFooterRulerChange ) && ( aButtonUpPt.Y() <= ( 0 - aOffset.Y() ) || aButtonUpPt.Y() > nHeight * HMM_PER_TWIPS -aOffset.Y() ) )
+ {
+ bMoveRulerAction = sal_False;
+ Paint( Rectangle(0,0,10000,10000) );
+ }
+ else if( aButtonDownPt.Y() == aButtonUpPt.Y() )
+ {
+ bMoveRulerAction = sal_False;
+ DrawInvert( aButtonUpPt.Y(), POINTER_VSIZEBAR );
+ }
+ if( bMoveRulerAction )
+ {
+ ScDocument * pDoc = pDocShell->GetDocument();
+ sal_Bool bUndo( pDoc->IsUndoEnabled() );
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
+ DBG_ASSERT( pStyleSheet, "PageStyle not found" );
+ if ( pStyleSheet )
+ {
+ ScStyleSaveData aOldData;
+ if( bUndo )
+ aOldData.InitFromStyle( pStyleSheet );
+
+ SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
+
+ SvxULSpaceItem aULItem = ( const SvxULSpaceItem&)rStyleSet.Get( ATTR_ULSPACE );
+
+ if( bTopRulerMove && bTopRulerChange )
+ {
+ aULItem.SetUpperValue( (sal_uInt16)( aButtonUpPt.Y() / HMM_PER_TWIPS + aOffset.Y() / HMM_PER_TWIPS ) );
+ rStyleSet.Put( aULItem );
+ }
+ else if( bBottomRulerMove && bBottomRulerChange )
+ {
+ aULItem.SetLowerValue( (sal_uInt16)( nHeight - aButtonUpPt.Y() / HMM_PER_TWIPS - aOffset.Y() / HMM_PER_TWIPS ) );
+ rStyleSet.Put( aULItem );
+ }
+ else if( bHeaderRulerMove && bHeaderRulerChange )
+ {
+ const SfxPoolItem* pItem = NULL;
+ if ( rStyleSet.GetItemState( ATTR_PAGE_HEADERSET, sal_False, &pItem ) == SFX_ITEM_SET )
+ {
+ SfxItemSet& pHeaderSet = ((SvxSetItem*)pItem)->GetItemSet();
+ Size aHeaderSize = ((const SvxSizeItem&)pHeaderSet.Get(ATTR_PAGE_SIZE)).GetSize();
+ aHeaderSize.Height() = (long)( aButtonUpPt.Y() / HMM_PER_TWIPS + aOffset.Y() / HMM_PER_TWIPS - aULItem.GetUpper());
+ aHeaderSize.Height() = aHeaderSize.Height() * 100 / mnScale;
+ SvxSetItem aNewHeader( (const SvxSetItem&)rStyleSet.Get(ATTR_PAGE_HEADERSET) );
+ aNewHeader.GetItemSet().Put( SvxSizeItem( ATTR_PAGE_SIZE, aHeaderSize ) );
+ rStyleSet.Put( aNewHeader );
+ }
+ }
+ else if( bFooterRulerMove && bFooterRulerChange )
+ {
+ const SfxPoolItem* pItem = NULL;
+ if( rStyleSet.GetItemState( ATTR_PAGE_FOOTERSET, sal_False, &pItem ) == SFX_ITEM_SET )
+ {
+ SfxItemSet& pFooterSet = ((SvxSetItem*)pItem)->GetItemSet();
+ Size aFooterSize = ((const SvxSizeItem&)pFooterSet.Get(ATTR_PAGE_SIZE)).GetSize();
+ aFooterSize.Height() = (long)( nHeight - aButtonUpPt.Y() / HMM_PER_TWIPS - aOffset.Y() / HMM_PER_TWIPS - aULItem.GetLower() );
+ aFooterSize.Height() = aFooterSize.Height() * 100 / mnScale;
+ SvxSetItem aNewFooter( (const SvxSetItem&)rStyleSet.Get(ATTR_PAGE_FOOTERSET) );
+ aNewFooter.GetItemSet().Put( SvxSizeItem( ATTR_PAGE_SIZE, aFooterSize ) );
+ rStyleSet.Put( aNewFooter );
+ }
+ }
+
+ ScStyleSaveData aNewData;
+ aNewData.InitFromStyle( pStyleSheet );
+ if( bUndo )
+ {
+ pDocShell->GetUndoManager()->AddUndoAction(
+ new ScUndoModifyStyle( pDocShell, SFX_STYLE_FAMILY_PAGE,
+ aOldData, aNewData ) );
+ }
+
+ if ( ValidTab( nTab ) )
+ {
+ ScPrintFunc aPrintFunc( pDocShell, this, nTab );
+ aPrintFunc.UpdatePages();
+ }
+
+ Rectangle aRect(0,0,10000,10000);
+ Paint( aRect );
+ bTopRulerChange = sal_False;
+ bBottomRulerChange = sal_False;
+ bHeaderRulerChange = sal_False;
+ bFooterRulerChange = sal_False;
+ }
+ }
+ bTopRulerMove = sal_False;
+ bBottomRulerMove = sal_False;
+ bHeaderRulerMove = sal_False;
+ bFooterRulerMove = sal_False;
+ }
+ if( rMEvt.IsLeft() && GetPointer() == POINTER_HSPLIT )
+ {
+ SetPointer(POINTER_ARROW);
+ ScDocument* pDoc = pDocShell->GetDocument();
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ sal_Bool bMoveRulerAction = sal_True;
+ if( aButtonDownPt.X() == aButtonUpPt.X() )
+ {
+ bMoveRulerAction = sal_False;
+ if( nColNumberButttonDown == aPageArea.aStart.Col() )
+ DrawInvert( PixelToLogic( Point( nLeftPosition, 0 ),aMMMode ).X() ,POINTER_HSPLIT );
+ else
+ DrawInvert( PixelToLogic( Point( nRight[ nColNumberButttonDown-1 ], 0 ),aMMMode ).X() ,POINTER_HSPLIT );
+ DrawInvert( aButtonUpPt.X(), POINTER_HSPLIT );
+ }
+ if( bMoveRulerAction )
+ {
+ long nNewColWidth = 0;
+ ScDocFunc aFunc(*pDocShell);
+ SCCOLROW nCols[2] = { nColNumberButttonDown, nColNumberButttonDown };
+
+ if( !bLayoutRTL )
+ {
+ nNewColWidth = (long) ( PixelToLogic( Point( rMEvt.GetPosPixel().X() - nRight[ nColNumberButttonDown ], 0), aMMMode ).X() / HMM_PER_TWIPS ) * 100 / mnScale;
+ nNewColWidth += pDocShell->GetDocument()->GetColWidth( nColNumberButttonDown, nTab );
+ }
+ else
+ {
+
+ nNewColWidth = (long) ( PixelToLogic( Point( nRight[ nColNumberButttonDown ] - rMEvt.GetPosPixel().X(), 0), aMMMode ).X() / HMM_PER_TWIPS ) * 100 / mnScale;
+ nNewColWidth += pDocShell->GetDocument()->GetColWidth( nColNumberButttonDown, nTab );
+ }
+
+ if( nNewColWidth >= 0 )
+ {
+ aFunc.SetWidthOrHeight( sal_True, 1,nCols, nTab, SC_SIZE_DIRECT, (sal_uInt16)nNewColWidth, sal_True, sal_True);
+ }
+ if ( ValidTab( nTab ) )
+ {
+ ScPrintFunc aPrintFunc( pDocShell, this, nTab );
+ aPrintFunc.UpdatePages();
+ }
+ Rectangle nRect(0,0,10000,10000);
+ Paint( nRect );
+ }
+ bColRulerMove = sal_False;
+ }
+ ReleaseMouse();
+}
+
+void __EXPORT ScPreview::MouseMove( const MouseEvent& rMEvt )
+{
+ Fraction aPreviewZoom( nZoom, 100 );
+ Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
+ MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
+ Point aMouseMovePoint = PixelToLogic( rMEvt.GetPosPixel(), aMMMode );
+
+ long nLeftMargin = 0;
+ long nRightMargin = 0;
+ long nTopMargin = 0;
+ long nBottomMargin = 0;
+ Size PageSize;
+
+ long nWidth = (long) lcl_GetDocPageSize(pDocShell->GetDocument(), nTab).Width();
+ long nHeight = (long) lcl_GetDocPageSize(pDocShell->GetDocument(), nTab).Height();
+
+ if ( nPageNo < nTotalPages )
+ {
+ ScPrintOptions aOptions = SC_MOD()->GetPrintOptions();
+
+ ScPrintFunc* pPrintFunc;
+
+ if (bStateValid)
+ pPrintFunc = new ScPrintFunc( pDocShell, this, aState, &aOptions );
+ else
+ pPrintFunc = new ScPrintFunc( pDocShell, this, nTab, nFirstAttr[nTab], nTotalPages, NULL, &aOptions );
+
+ nLeftMargin = (long)( pPrintFunc->GetLeftMargin() * HMM_PER_TWIPS - aOffset.X() );
+ nRightMargin = (long)( pPrintFunc->GetRightMargin() * HMM_PER_TWIPS );
+ nRightMargin = (long)( nWidth * HMM_PER_TWIPS - nRightMargin - aOffset.X() );
+ nTopMargin = (long)( pPrintFunc->GetTopMargin() * HMM_PER_TWIPS - aOffset.Y() );
+ nBottomMargin = (long)( pPrintFunc->GetBottomMargin() * HMM_PER_TWIPS );
+ nBottomMargin = (long)( nHeight * HMM_PER_TWIPS - nBottomMargin - aOffset.Y() );
+ if( mnScale > 0 )
+ {
+ nHeaderHeight = (long)( nTopMargin + pPrintFunc->GetHeader().nHeight * HMM_PER_TWIPS * mnScale / 100 );
+ nFooterHeight = (long)( nBottomMargin - pPrintFunc->GetFooter().nHeight * HMM_PER_TWIPS * mnScale / 100 );
+ }
+ else
+ {
+ nHeaderHeight = (long)( nTopMargin + pPrintFunc->GetHeader().nHeight * HMM_PER_TWIPS );
+ nFooterHeight = (long)( nBottomMargin - pPrintFunc->GetFooter().nHeight * HMM_PER_TWIPS );
+ }
+ delete pPrintFunc;
+ }
+
+ Point aPixPt( rMEvt.GetPosPixel() );
+ Point aLeftTop = LogicToPixel( Point( nLeftMargin, -aOffset.Y() ) , aMMMode );
+ Point aLeftBottom = LogicToPixel( Point( nLeftMargin ,(long)(nHeight * HMM_PER_TWIPS - aOffset.Y()) ), aMMMode );
+ Point aRightTop = LogicToPixel( Point( nRightMargin, -aOffset.Y() ), aMMMode );
+ Point aTopLeft = LogicToPixel( Point( -aOffset.X(), nTopMargin ), aMMMode );
+ Point aTopRight = LogicToPixel( Point( (long)(nWidth * HMM_PER_TWIPS - aOffset.X()), nTopMargin ), aMMMode );
+ Point aBottomLeft = LogicToPixel( Point( -aOffset.X(), nBottomMargin ), aMMMode );
+ Point aHeaderLeft = LogicToPixel( Point( -aOffset.X(), nHeaderHeight ), aMMMode );
+ Point aFooderLeft = LogicToPixel( Point( -aOffset.X(), nFooterHeight ), aMMMode );
+
+ sal_Bool bOnColRulerChange = sal_False;
+
+ for( SCCOL i=aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ )
+ {
+ Point aColumnTop = LogicToPixel( Point( 0, -aOffset.Y() ) ,aMMMode );
+ Point aColumnBottom = LogicToPixel( Point( 0, (long)( nHeight * HMM_PER_TWIPS - aOffset.Y()) ), aMMMode );
+ if( aPixPt.X() < ( nRight[i] + 2 ) && ( aPixPt.X() > ( nRight[i] - 2 ) ) && ( aPixPt.X() < aRightTop.X() ) && ( aPixPt.X() > aLeftTop.X() )
+ && ( aPixPt.Y() > aColumnTop.Y() ) && ( aPixPt.Y() < aColumnBottom.Y() ) && !bLeftRulerMove && !bRightRulerMove
+ && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
+ {
+ bOnColRulerChange = sal_True;
+ if( !rMEvt.GetButtons() && GetPointer() == POINTER_HSPLIT )
+ nColNumberButttonDown = i;
+ break;
+ }
+ }
+
+ if( aPixPt.X() < ( aLeftTop.X() + 2 ) && aPixPt.X() > ( aLeftTop.X() - 2 ) && !bRightRulerMove )
+ {
+ bLeftRulerChange = sal_True;
+ bRightRulerChange = sal_False;
+ }
+ else if( aPixPt.X() < ( aRightTop.X() + 2 ) && aPixPt.X() > ( aRightTop.X() - 2 ) && !bLeftRulerMove )
+ {
+ bLeftRulerChange = sal_False;
+ bRightRulerChange = sal_True;
+ }
+ else if( aPixPt.Y() < ( aTopLeft.Y() + 2 ) && aPixPt.Y() > ( aTopLeft.Y() - 2 ) && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
+ {
+ bTopRulerChange = sal_True;
+ bBottomRulerChange = sal_False;
+ bHeaderRulerChange = sal_False;
+ bFooterRulerChange = sal_False;
+ }
+ else if( aPixPt.Y() < ( aBottomLeft.Y() + 2 ) && aPixPt.Y() > ( aBottomLeft.Y() - 2 ) && !bTopRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
+ {
+ bTopRulerChange = sal_False;
+ bBottomRulerChange = sal_True;
+ bHeaderRulerChange = sal_False;
+ bFooterRulerChange = sal_False;
+ }
+ else if( aPixPt.Y() < ( aHeaderLeft.Y() + 2 ) && aPixPt.Y() > ( aHeaderLeft.Y() - 2 ) && !bTopRulerMove && !bBottomRulerMove && !bFooterRulerMove )
+ {
+ bTopRulerChange = sal_False;
+ bBottomRulerChange = sal_False;
+ bHeaderRulerChange = sal_True;
+ bFooterRulerChange = sal_False;
+ }
+ else if( aPixPt.Y() < ( aFooderLeft.Y() + 2 ) && aPixPt.Y() > ( aFooderLeft.Y() - 2 ) && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove )
+ {
+ bTopRulerChange = sal_False;
+ bBottomRulerChange = sal_False;
+ bHeaderRulerChange = sal_False;
+ bFooterRulerChange = sal_True;
+ }
+
+ if( bPageMargin )
+ {
+ if(( (aPixPt.X() < ( aLeftTop.X() + 2 ) && aPixPt.X() > ( aLeftTop.X() - 2 )) || bLeftRulerMove ||
+ ( aPixPt.X() < ( aRightTop.X() + 2 ) && aPixPt.X() > ( aRightTop.X() - 2 ) ) || bRightRulerMove || bOnColRulerChange || bColRulerMove )
+ && aPixPt.Y() > aLeftTop.Y() && aPixPt.Y() < aLeftBottom.Y() )
+ {
+ if( bOnColRulerChange || bColRulerMove )
+ {
+ SetPointer( Pointer( POINTER_HSPLIT ) );
+ if( bColRulerMove )
+ {
+ if( aMouseMovePoint.X() > -aOffset.X() && aMouseMovePoint.X() < nWidth * HMM_PER_TWIPS - aOffset.X() )
+ DragMove( aMouseMovePoint.X(), POINTER_HSPLIT );
+ }
+ }
+ else
+ {
+ if( bLeftRulerChange && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
+ {
+ SetPointer( Pointer( POINTER_HSIZEBAR ) );
+ if( bLeftRulerMove )
+ {
+ if( aMouseMovePoint.X() > -aOffset.X() && aMouseMovePoint.X() < nWidth * HMM_PER_TWIPS - aOffset.X() )
+ DragMove( aMouseMovePoint.X(), POINTER_HSIZEBAR );
+ }
+ }
+ else if( bRightRulerChange && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
+ {
+ SetPointer( Pointer( POINTER_HSIZEBAR ) );
+ if( bRightRulerMove )
+ {
+ if( aMouseMovePoint.X() > -aOffset.X() && aMouseMovePoint.X() < nWidth * HMM_PER_TWIPS - aOffset.X() )
+ DragMove( aMouseMovePoint.X(), POINTER_HSIZEBAR );
+ }
+ }
+ }
+ }
+ else
+ {
+ if( ( ( aPixPt.Y() < ( aTopLeft.Y() + 2 ) && aPixPt.Y() > ( aTopLeft.Y() - 2 ) ) || bTopRulerMove ||
+ ( aPixPt.Y() < ( aBottomLeft.Y() + 2 ) && aPixPt.Y() > ( aBottomLeft.Y() - 2 ) ) || bBottomRulerMove ||
+ ( aPixPt.Y() < ( aHeaderLeft.Y() + 2 ) && aPixPt.Y() > ( aHeaderLeft.Y() - 2 ) ) || bHeaderRulerMove ||
+ ( aPixPt.Y() < ( aFooderLeft.Y() + 2 ) && aPixPt.Y() > ( aFooderLeft.Y() - 2 ) ) || bFooterRulerMove )
+ && aPixPt.X() > aTopLeft.X() && aPixPt.X() < aTopRight.X() )
+ {
+ if( bTopRulerChange )
+ {
+ SetPointer( Pointer( POINTER_VSIZEBAR ) );
+ if( bTopRulerMove )
+ {
+ if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
+ DragMove( aMouseMovePoint.Y(), POINTER_VSIZEBAR );
+ }
+ }
+ else if( bBottomRulerChange )
+ {
+ SetPointer( Pointer( POINTER_VSIZEBAR ) );
+ if( bBottomRulerMove )
+ {
+ if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
+ DragMove( aMouseMovePoint.Y(), POINTER_VSIZEBAR );
+ }
+ }
+ else if( bHeaderRulerChange )
+ {
+ SetPointer( Pointer( POINTER_VSIZEBAR ) );
+ if( bHeaderRulerMove )
+ {
+ if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
+ DragMove( aMouseMovePoint.Y(), POINTER_VSIZEBAR );
+ }
+ }
+ else if( bFooterRulerChange )
+ {
+ SetPointer( Pointer( POINTER_VSIZEBAR ) );
+ if( bFooterRulerMove )
+ {
+ if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
+ DragMove( aMouseMovePoint.Y(), POINTER_VSIZEBAR );
+ }
+ }
+ }
+ else
+ SetPointer( Pointer( POINTER_ARROW ) );
+ }
+ }
+}
+//Issue51656 Add resizeable margin on page preview from maoyg
+void ScPreview::InvalidateLocationData(sal_uLong nId)
+{
+ bLocationValid = sal_False;
+ if (pViewShell->HasAccessibilityObjects())
+ pViewShell->BroadcastAccessibility( SfxSimpleHint( nId ) );
+}
+
+void ScPreview::GetFocus()
+{
+ if (pViewShell->HasAccessibilityObjects())
+ pViewShell->BroadcastAccessibility( ScAccWinFocusGotHint(GetAccessible()) );
+}
+
+void ScPreview::LoseFocus()
+{
+ if (pViewShell->HasAccessibilityObjects())
+ pViewShell->BroadcastAccessibility( ScAccWinFocusLostHint(GetAccessible()) );
+}
+
+com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible> ScPreview::CreateAccessible()
+{
+ ScAccessibleDocumentPagePreview* pAccessible =
+ new ScAccessibleDocumentPagePreview( GetAccessibleParentWindow()->GetAccessible(), pViewShell );
+ com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xAccessible = pAccessible;
+ pAccessible->Init();
+ return xAccessible;
+}
+
+//Issue51656 Add resizeable margin on page preview from maoyg
+void ScPreview::DragMove( long nDragMovePos, sal_uInt16 nFlags )
+{
+ Fraction aPreviewZoom( nZoom, 100 );
+ Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
+ MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
+ SetMapMode( aMMMode );
+ long nPos = nDragMovePos;
+ if( nFlags == POINTER_HSIZEBAR || nFlags == POINTER_HSPLIT )
+ {
+ if( nDragMovePos != aButtonDownChangePoint.X() )
+ {
+ DrawInvert( aButtonDownChangePoint.X(), nFlags );
+ aButtonDownChangePoint.X() = nPos;
+ DrawInvert( aButtonDownChangePoint.X(), nFlags );
+ }
+ }
+ else if( nFlags == POINTER_VSIZEBAR )
+ {
+ if( nDragMovePos != aButtonDownChangePoint.Y() )
+ {
+ DrawInvert( aButtonDownChangePoint.Y(), nFlags );
+ aButtonDownChangePoint.Y() = nPos;
+ DrawInvert( aButtonDownChangePoint.Y(), nFlags );
+ }
+ }
+}
+
+void ScPreview::DrawInvert( long nDragPos, sal_uInt16 nFlags )
+{
+ long nHeight = (long) lcl_GetDocPageSize( pDocShell->GetDocument(), nTab ).Height();
+ long nWidth = (long) lcl_GetDocPageSize( pDocShell->GetDocument(), nTab ).Width();
+ if( nFlags == POINTER_HSIZEBAR || nFlags == POINTER_HSPLIT )
+ {
+ Rectangle aRect( nDragPos, -aOffset.Y(), nDragPos + 1,(long)( ( nHeight * HMM_PER_TWIPS ) - aOffset.Y()));
+ Invert( aRect,INVERT_50 );
+ }
+ else if( nFlags == POINTER_VSIZEBAR )
+ {
+ Rectangle aRect( -aOffset.X(), nDragPos,(long)( ( nWidth * HMM_PER_TWIPS ) - aOffset.X() ), nDragPos + 1 );
+ Invert( aRect,INVERT_50 );
+ }
+}
+//Issue51656 Add resizeable margin on page preview from maoyg
diff --git a/sc/source/ui/view/prevloc.cxx b/sc/source/ui/view/prevloc.cxx
new file mode 100644
index 000000000000..fb72bedd0999
--- /dev/null
+++ b/sc/source/ui/view/prevloc.cxx
@@ -0,0 +1,792 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <vcl/outdev.hxx>
+#include <tools/debug.hxx>
+
+#include "prevloc.hxx"
+#include "document.hxx"
+
+//==================================================================
+
+enum ScPreviewLocationType
+{
+ SC_PLOC_CELLRANGE,
+ SC_PLOC_COLHEADER,
+ SC_PLOC_ROWHEADER,
+ SC_PLOC_LEFTHEADER,
+ SC_PLOC_RIGHTHEADER,
+ SC_PLOC_LEFTFOOTER,
+ SC_PLOC_RIGHTFOOTER,
+ SC_PLOC_NOTEMARK,
+ SC_PLOC_NOTETEXT
+};
+
+struct ScPreviewLocationEntry
+{
+ ScPreviewLocationType eType;
+ Rectangle aPixelRect;
+ ScRange aCellRange;
+ sal_Bool bRepeatCol;
+ sal_Bool bRepeatRow;
+
+ ScPreviewLocationEntry( ScPreviewLocationType eNewType, const Rectangle& rPixel, const ScRange& rRange,
+ sal_Bool bRepCol, sal_Bool bRepRow ) :
+ eType( eNewType ),
+ aPixelRect( rPixel ),
+ aCellRange( rRange ),
+ bRepeatCol( bRepCol ),
+ bRepeatRow( bRepRow )
+ {
+ }
+};
+
+//==================================================================
+
+ScPreviewTableInfo::ScPreviewTableInfo() :
+ nTab(0),
+ nCols(0),
+ nRows(0),
+ pColInfo(NULL),
+ pRowInfo(NULL)
+{
+}
+
+ScPreviewTableInfo::~ScPreviewTableInfo()
+{
+ delete[] pColInfo;
+ delete[] pRowInfo;
+}
+
+void ScPreviewTableInfo::SetTab( SCTAB nNewTab )
+{
+ nTab = nNewTab;
+}
+
+void ScPreviewTableInfo::SetColInfo( SCCOL nCount, ScPreviewColRowInfo* pNewInfo )
+{
+ delete[] pColInfo;
+ pColInfo = pNewInfo;
+ nCols = nCount;
+}
+
+void ScPreviewTableInfo::SetRowInfo( SCROW nCount, ScPreviewColRowInfo* pNewInfo )
+{
+ delete[] pRowInfo;
+ pRowInfo = pNewInfo;
+ nRows = nCount;
+}
+
+void ScPreviewTableInfo::LimitToArea( const Rectangle& rPixelArea )
+{
+ if ( pColInfo )
+ {
+ // cells completely left of the visible area
+ SCCOL nStart = 0;
+ while ( nStart < nCols && pColInfo[nStart].nPixelEnd < rPixelArea.Left() )
+ ++nStart;
+
+ // cells completely right of the visible area
+ SCCOL nEnd = nCols;
+ while ( nEnd > 0 && pColInfo[nEnd-1].nPixelStart > rPixelArea.Right() )
+ --nEnd;
+
+ if ( nStart > 0 || nEnd < nCols )
+ {
+ if ( nEnd > nStart )
+ {
+ SCCOL nNewCount = nEnd - nStart;
+ ScPreviewColRowInfo* pNewInfo = new ScPreviewColRowInfo[nNewCount];
+ for (SCCOL i=0; i<nNewCount; i++)
+ pNewInfo[i] = pColInfo[nStart + i];
+ SetColInfo( nNewCount, pNewInfo );
+ }
+ else
+ SetColInfo( 0, NULL ); // all invisible
+ }
+ }
+
+ if ( pRowInfo )
+ {
+ // cells completely above the visible area
+ SCROW nStart = 0;
+ while ( nStart < nRows && pRowInfo[nStart].nPixelEnd < rPixelArea.Top() )
+ ++nStart;
+
+ // cells completely below the visible area
+ SCROW nEnd = nRows;
+ while ( nEnd > 0 && pRowInfo[nEnd-1].nPixelStart > rPixelArea.Bottom() )
+ --nEnd;
+
+ if ( nStart > 0 || nEnd < nRows )
+ {
+ if ( nEnd > nStart )
+ {
+ SCROW nNewCount = nEnd - nStart;
+ ScPreviewColRowInfo* pNewInfo = new ScPreviewColRowInfo[nNewCount];
+ for (SCROW i=0; i<nNewCount; i++)
+ pNewInfo[i] = pRowInfo[nStart + i];
+ SetRowInfo( nNewCount, pNewInfo );
+ }
+ else
+ SetRowInfo( 0, NULL ); // all invisible
+ }
+ }
+}
+
+//------------------------------------------------------------------
+
+ScPreviewLocationData::ScPreviewLocationData( ScDocument* pDocument, OutputDevice* pWin ) :
+ pWindow( pWin ),
+ pDoc( pDocument ),
+ nDrawRanges( 0 ),
+ nPrintTab( 0 )
+{
+}
+
+ScPreviewLocationData::~ScPreviewLocationData()
+{
+ Clear();
+}
+
+void ScPreviewLocationData::SetCellMapMode( const MapMode& rMapMode )
+{
+ aCellMapMode = rMapMode;
+}
+
+void ScPreviewLocationData::SetPrintTab( SCTAB nNew )
+{
+ nPrintTab = nNew;
+}
+
+void ScPreviewLocationData::Clear()
+{
+ void* pEntry = aEntries.First();
+ while ( pEntry )
+ {
+ delete (ScPreviewLocationEntry*) pEntry;
+ pEntry = aEntries.Next();
+ }
+ aEntries.Clear();
+
+ nDrawRanges = 0;
+}
+
+void ScPreviewLocationData::AddCellRange( const Rectangle& rRect, const ScRange& rRange, sal_Bool bRepCol, sal_Bool bRepRow,
+ const MapMode& rDrawMap )
+{
+ Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
+ aEntries.Insert( new ScPreviewLocationEntry( SC_PLOC_CELLRANGE, aPixelRect, rRange, bRepCol, bRepRow ) );
+
+ DBG_ASSERT( nDrawRanges < SC_PREVIEW_MAXRANGES, "too many ranges" );
+ if ( nDrawRanges < SC_PREVIEW_MAXRANGES )
+ {
+ aDrawRectangle[nDrawRanges] = aPixelRect;
+ aDrawMapMode[nDrawRanges] = rDrawMap;
+ if (bRepCol)
+ if (bRepRow)
+ aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_EDGE;
+ else
+ aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_REPCOL;
+ else
+ if (bRepRow)
+ aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_REPROW;
+ else
+ aDrawRangeId[nDrawRanges] = SC_PREVIEW_RANGE_TAB;
+ ++nDrawRanges;
+ }
+}
+
+void ScPreviewLocationData::AddColHeaders( const Rectangle& rRect, SCCOL nStartCol, SCCOL nEndCol, sal_Bool bRepCol )
+{
+ SCTAB nTab = 0; //! ?
+ ScRange aRange( nStartCol, 0, nTab, nEndCol, 0, nTab );
+ Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
+ aEntries.Insert( new ScPreviewLocationEntry( SC_PLOC_COLHEADER, aPixelRect, aRange, bRepCol, sal_False ) );
+}
+
+void ScPreviewLocationData::AddRowHeaders( const Rectangle& rRect, SCROW nStartRow, SCROW nEndRow, sal_Bool bRepRow )
+{
+ SCTAB nTab = 0; //! ?
+ ScRange aRange( 0, nStartRow, nTab, 0, nEndRow, nTab );
+ Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
+ aEntries.Insert( new ScPreviewLocationEntry( SC_PLOC_ROWHEADER, aPixelRect, aRange, sal_False, bRepRow ) );
+}
+
+void ScPreviewLocationData::AddHeaderFooter( const Rectangle& rRect, sal_Bool bHeader, sal_Bool bLeft )
+{
+ ScRange aRange; //! ?
+ Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
+
+ ScPreviewLocationType eType = bHeader ?
+ ( bLeft ? SC_PLOC_LEFTHEADER : SC_PLOC_RIGHTHEADER ) :
+ ( bLeft ? SC_PLOC_LEFTFOOTER : SC_PLOC_RIGHTFOOTER );
+ aEntries.Insert( new ScPreviewLocationEntry( eType, aPixelRect, aRange, sal_False, sal_False ) );
+}
+
+void ScPreviewLocationData::AddNoteMark( const Rectangle& rRect, const ScAddress& rPos )
+{
+ ScRange aRange( rPos );
+ Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
+ aEntries.Insert( new ScPreviewLocationEntry( SC_PLOC_NOTEMARK, aPixelRect, aRange, sal_False, sal_False ) );
+}
+
+void ScPreviewLocationData::AddNoteText( const Rectangle& rRect, const ScAddress& rPos )
+{
+ ScRange aRange( rPos );
+ Rectangle aPixelRect( pWindow->LogicToPixel( rRect ) );
+ aEntries.Insert( new ScPreviewLocationEntry( SC_PLOC_NOTETEXT, aPixelRect, aRange, sal_False, sal_False ) );
+}
+
+//------------------------------------------------------------------
+
+void ScPreviewLocationData::GetDrawRange( sal_uInt16 nPos, Rectangle& rPixelRect, MapMode& rMapMode, sal_uInt8& rRangeId ) const
+{
+ DBG_ASSERT( nPos < nDrawRanges, "wrong position" );
+ if ( nPos < nDrawRanges )
+ {
+ rPixelRect = aDrawRectangle[nPos];
+ rMapMode = aDrawMapMode[nPos];
+ rRangeId = aDrawRangeId[nPos];
+ }
+}
+
+ScPreviewLocationEntry* lcl_GetEntryByAddress( const List& rEntries, const ScAddress& rPos, ScPreviewLocationType eType )
+{
+ sal_uLong nCount = rEntries.Count();
+ for (sal_uLong nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)rEntries.GetObject(nListPos);
+ if ( pEntry->eType == eType && pEntry->aCellRange.In( rPos ) )
+ return pEntry;
+ }
+ return NULL;
+}
+
+//UNUSED2008-05 ScAddress ScPreviewLocationData::GetCellFromRange( const Size& rOffsetPixel, const ScRange& rRange ) const
+//UNUSED2008-05 {
+//UNUSED2008-05 const double nScaleX = HMM_PER_TWIPS;
+//UNUSED2008-05 const double nScaleY = HMM_PER_TWIPS;
+//UNUSED2008-05
+//UNUSED2008-05 Size aOffsetLogic = pWindow->PixelToLogic( rOffsetPixel, aCellMapMode );
+//UNUSED2008-05 SCTAB nTab = rRange.aStart.Tab();
+//UNUSED2008-05
+//UNUSED2008-05 long nPosX = 0;
+//UNUSED2008-05 SCCOL nCol = rRange.aStart.Col();
+//UNUSED2008-05 SCCOL nEndCol = rRange.aEnd.Col();
+//UNUSED2008-05 while ( nCol <= nEndCol && nPosX < aOffsetLogic.Width() )
+//UNUSED2008-05 {
+//UNUSED2008-05 sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nTab );
+//UNUSED2008-05 if (nDocW)
+//UNUSED2008-05 nPosX += (long) (nDocW * nScaleX);
+//UNUSED2008-05 ++nCol;
+//UNUSED2008-05 }
+//UNUSED2008-05 if ( nCol > rRange.aStart.Col() )
+//UNUSED2008-05 --nCol;
+//UNUSED2008-05
+//UNUSED2008-05 long nPosY = 0;
+//UNUSED2008-05 ScCoupledCompressedArrayIterator< SCROW, sal_uInt8, sal_uInt16> aIter(
+//UNUSED2008-05 pDoc->GetRowFlagsArray( nTab), rRange.aStart.Row(),
+//UNUSED2008-05 rRange.aEnd.Row(), CR_HIDDEN, 0, pDoc->GetRowHeightArray( nTab));
+//UNUSED2008-05 while ( aIter && nPosY < aOffsetLogic.Height() )
+//UNUSED2008-05 {
+//UNUSED2008-05 sal_uInt16 nDocH = *aIter;
+//UNUSED2008-05 if (nDocH)
+//UNUSED2008-05 nPosY += (long) (nDocH * nScaleY);
+//UNUSED2008-05 ++aIter;
+//UNUSED2008-05 }
+//UNUSED2008-05 SCROW nRow = aIter.GetPos();
+//UNUSED2008-05 if ( nRow > rRange.aStart.Row() )
+//UNUSED2008-05 --nRow;
+//UNUSED2008-05
+//UNUSED2008-05 return ScAddress( nCol, nRow, nTab );
+//UNUSED2008-05 }
+
+Rectangle ScPreviewLocationData::GetOffsetPixel( const ScAddress& rCellPos, const ScRange& rRange ) const
+{
+ const double nScaleX = HMM_PER_TWIPS;
+ const double nScaleY = HMM_PER_TWIPS;
+ SCTAB nTab = rRange.aStart.Tab();
+
+ long nPosX = 0;
+ SCCOL nEndCol = rCellPos.Col();
+ for (SCCOL nCol = rRange.aStart.Col(); nCol < nEndCol; nCol++)
+ {
+ sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nTab );
+ if (nDocW)
+ nPosX += (long) (nDocW * nScaleX);
+ }
+ long nSizeX = (long) ( pDoc->GetColWidth( nEndCol, nTab ) * nScaleX );
+
+ SCROW nEndRow = rCellPos.Row();
+ long nPosY = (long) pDoc->GetScaledRowHeight( rRange.aStart.Row(),
+ nEndRow, nTab, nScaleY);
+ long nSizeY = (long) ( pDoc->GetRowHeight( nEndRow, nTab ) * nScaleY );
+
+ Size aOffsetLogic( nPosX, nPosY );
+ Size aSizeLogic( nSizeX, nSizeY );
+ Size aOffsetPixel = pWindow->LogicToPixel( aOffsetLogic, aCellMapMode );
+ Size aSizePixel = pWindow->LogicToPixel( aSizeLogic, aCellMapMode );
+
+ return Rectangle( Point( aOffsetPixel.Width(), aOffsetPixel.Height() ), aSizePixel );
+}
+
+sal_Bool ScPreviewLocationData::GetCellPosition( const ScAddress& rCellPos, Rectangle& rCellRect ) const
+{
+ ScPreviewLocationEntry* pEntry = lcl_GetEntryByAddress( aEntries, rCellPos, SC_PLOC_CELLRANGE );
+ if ( pEntry )
+ {
+ Rectangle aOffsetRect = GetOffsetPixel( rCellPos, pEntry->aCellRange );
+ rCellRect = Rectangle( aOffsetRect.Left() + pEntry->aPixelRect.Left(),
+ aOffsetRect.Top() + pEntry->aPixelRect.Top(),
+ aOffsetRect.Right() + pEntry->aPixelRect.Left(),
+ aOffsetRect.Bottom() + pEntry->aPixelRect.Top() );
+ return sal_True;
+ }
+ return sal_False;
+}
+
+sal_Bool ScPreviewLocationData::HasCellsInRange( const Rectangle& rVisiblePixel ) const
+{
+ sal_uLong nCount = aEntries.Count();
+ for (sal_uLong nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ ScPreviewLocationType eType = pEntry->eType;
+ if ( eType == SC_PLOC_CELLRANGE || eType == SC_PLOC_COLHEADER || eType == SC_PLOC_ROWHEADER )
+ if ( pEntry->aPixelRect.IsOver( rVisiblePixel ) )
+ return sal_True;
+ }
+ return sal_False;
+}
+
+sal_Bool ScPreviewLocationData::GetHeaderPosition( Rectangle& rRect ) const
+{
+ sal_uLong nCount = aEntries.Count();
+ for (sal_uLong nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ if ( pEntry->eType == SC_PLOC_LEFTHEADER || pEntry->eType == SC_PLOC_RIGHTHEADER )
+ {
+ rRect = pEntry->aPixelRect;
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+
+sal_Bool ScPreviewLocationData::GetFooterPosition( Rectangle& rRect ) const
+{
+ sal_uLong nCount = aEntries.Count();
+ for (sal_uLong nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ if ( pEntry->eType == SC_PLOC_LEFTFOOTER || pEntry->eType == SC_PLOC_RIGHTFOOTER )
+ {
+ rRect = pEntry->aPixelRect;
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+
+sal_Bool ScPreviewLocationData::IsHeaderLeft() const
+{
+ sal_uLong nCount = aEntries.Count();
+ for (sal_uLong nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ if ( pEntry->eType == SC_PLOC_LEFTHEADER )
+ return sal_True;
+ if ( pEntry->eType == SC_PLOC_RIGHTHEADER )
+ return sal_False;
+ }
+ return sal_False;
+}
+
+sal_Bool ScPreviewLocationData::IsFooterLeft() const
+{
+ sal_uLong nCount = aEntries.Count();
+ for (sal_uLong nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ if ( pEntry->eType == SC_PLOC_LEFTFOOTER )
+ return sal_True;
+ if ( pEntry->eType == SC_PLOC_RIGHTFOOTER )
+ return sal_False;
+ }
+ return sal_False;
+}
+
+long ScPreviewLocationData::GetNoteCountInRange( const Rectangle& rVisiblePixel, sal_Bool bNoteMarks ) const
+{
+ ScPreviewLocationType eType = bNoteMarks ? SC_PLOC_NOTEMARK : SC_PLOC_NOTETEXT;
+
+ sal_uLong nRet = 0;
+ sal_uLong nCount = aEntries.Count();
+ for (sal_uLong nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ if ( pEntry->eType == eType && pEntry->aPixelRect.IsOver( rVisiblePixel ) )
+ ++nRet;
+ }
+ return nRet;
+}
+
+sal_Bool ScPreviewLocationData::GetNoteInRange( const Rectangle& rVisiblePixel, long nIndex, sal_Bool bNoteMarks,
+ ScAddress& rCellPos, Rectangle& rNoteRect ) const
+{
+ ScPreviewLocationType eType = bNoteMarks ? SC_PLOC_NOTEMARK : SC_PLOC_NOTETEXT;
+
+ sal_uLong nPos = 0;
+ sal_uLong nCount = aEntries.Count();
+ for (sal_uLong nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ if ( pEntry->eType == eType && pEntry->aPixelRect.IsOver( rVisiblePixel ) )
+ {
+ if ( nPos == sal::static_int_cast<sal_uLong>(nIndex) )
+ {
+ rCellPos = pEntry->aCellRange.aStart;
+ rNoteRect = pEntry->aPixelRect;
+ return sal_True;
+ }
+ ++nPos;
+ }
+ }
+ return sal_False;
+}
+
+Rectangle ScPreviewLocationData::GetNoteInRangeOutputRect(const Rectangle& rVisiblePixel, sal_Bool bNoteMarks, const ScAddress& aCellPos) const
+{
+ ScPreviewLocationType eType = bNoteMarks ? SC_PLOC_NOTEMARK : SC_PLOC_NOTETEXT;
+
+ sal_uLong nPos = 0;
+ sal_uLong nCount = aEntries.Count();
+ for (sal_uLong nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ if ( pEntry->eType == eType && pEntry->aPixelRect.IsOver( rVisiblePixel ) )
+ {
+ if ( aCellPos == pEntry->aCellRange.aStart )
+ return pEntry->aPixelRect;
+ ++nPos;
+ }
+ }
+ return Rectangle();
+}
+
+void ScPreviewLocationData::GetTableInfo( const Rectangle& rVisiblePixel, ScPreviewTableInfo& rInfo ) const
+{
+ const double nScaleX = HMM_PER_TWIPS;
+ const double nScaleY = HMM_PER_TWIPS;
+
+ // from left to right:
+ sal_Bool bHasHeaderCol = sal_False;
+ sal_Bool bHasRepCols = sal_False;
+ sal_Bool bHasMainCols = sal_False;
+ SCCOL nRepeatColStart = 0;
+ SCCOL nRepeatColEnd = 0;
+ SCCOL nMainColStart = 0;
+ SCCOL nMainColEnd = 0;
+
+ // from top to bottom:
+ sal_Bool bHasHeaderRow = sal_False;
+ sal_Bool bHasRepRows = sal_False;
+ sal_Bool bHasMainRows = sal_False;
+ SCROW nRepeatRowStart = 0;
+ SCROW nRepeatRowEnd = 0;
+ SCROW nMainRowStart = 0;
+ SCROW nMainRowEnd = 0;
+
+ Rectangle aHeaderRect, aRepeatRect, aMainRect;
+ SCTAB nTab = 0;
+
+ sal_uLong nCount = aEntries.Count();
+ for (sal_uLong nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ if ( pEntry->eType == SC_PLOC_CELLRANGE )
+ {
+ if ( pEntry->bRepeatCol )
+ {
+ bHasRepCols = sal_True;
+ nRepeatColStart = pEntry->aCellRange.aStart.Col();
+ nRepeatColEnd = pEntry->aCellRange.aEnd.Col();
+ aRepeatRect.Left() = pEntry->aPixelRect.Left();
+ aRepeatRect.Right() = pEntry->aPixelRect.Right();
+ }
+ else
+ {
+ bHasMainCols = sal_True;
+ nMainColStart = pEntry->aCellRange.aStart.Col();
+ nMainColEnd = pEntry->aCellRange.aEnd.Col();
+ aMainRect.Left() = pEntry->aPixelRect.Left();
+ aMainRect.Right() = pEntry->aPixelRect.Right();
+ }
+ if ( pEntry->bRepeatRow )
+ {
+ bHasRepRows = sal_True;
+ nRepeatRowStart = pEntry->aCellRange.aStart.Row();
+ nRepeatRowEnd = pEntry->aCellRange.aEnd.Row();
+ aRepeatRect.Top() = pEntry->aPixelRect.Top();
+ aRepeatRect.Bottom() = pEntry->aPixelRect.Bottom();
+ }
+ else
+ {
+ bHasMainRows = sal_True;
+ nMainRowStart = pEntry->aCellRange.aStart.Row();
+ nMainRowEnd = pEntry->aCellRange.aEnd.Row();
+ aMainRect.Top() = pEntry->aPixelRect.Top();
+ aMainRect.Bottom() = pEntry->aPixelRect.Bottom();
+ }
+ nTab = pEntry->aCellRange.aStart.Tab(); //! store separately?
+ }
+ else if ( pEntry->eType == SC_PLOC_ROWHEADER )
+ {
+ // row headers result in an additional column
+ bHasHeaderCol = sal_True;
+ aHeaderRect.Left() = pEntry->aPixelRect.Left();
+ aHeaderRect.Right() = pEntry->aPixelRect.Right();
+ }
+ else if ( pEntry->eType == SC_PLOC_COLHEADER )
+ {
+ // column headers result in an additional row
+ bHasHeaderRow = sal_True;
+ aHeaderRect.Top() = pEntry->aPixelRect.Top();
+ aHeaderRect.Bottom() = pEntry->aPixelRect.Bottom();
+ }
+ }
+
+ //
+ // get column info
+ //
+
+ SCCOL nColCount = 0;
+ SCCOL nCol;
+ if ( bHasHeaderCol )
+ ++nColCount;
+ if ( bHasRepCols )
+ for ( nCol=nRepeatColStart; nCol<=nRepeatColEnd; nCol++ )
+ if (!pDoc->ColHidden(nCol, nTab))
+ ++nColCount;
+ if ( bHasMainCols )
+ for ( nCol=nMainColStart; nCol<=nMainColEnd; nCol++ )
+ if (!pDoc->ColHidden(nCol, nTab))
+ ++nColCount;
+
+ if ( nColCount > 0 )
+ {
+ ScPreviewColRowInfo* pColInfo = new ScPreviewColRowInfo[ nColCount ];
+ SCCOL nColPos = 0;
+
+ if ( bHasHeaderCol )
+ {
+ pColInfo[nColPos].Set( sal_True, 0, aHeaderRect.Left(), aHeaderRect.Right() );
+ ++nColPos;
+ }
+ if ( bHasRepCols )
+ {
+ long nPosX = 0;
+ for ( nCol=nRepeatColStart; nCol<=nRepeatColEnd; nCol++ )
+ if (!pDoc->ColHidden(nCol, nTab))
+ {
+ sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nTab );
+ long nNextX = nPosX + (long) (nDocW * nScaleX);
+
+ long nPixelStart = pWindow->LogicToPixel( Size( nPosX, 0 ), aCellMapMode ).Width();
+ long nPixelEnd = pWindow->LogicToPixel( Size( nNextX, 0 ), aCellMapMode ).Width() - 1;
+ pColInfo[nColPos].Set( sal_False, nCol,
+ aRepeatRect.Left() + nPixelStart,
+ aRepeatRect.Left() + nPixelEnd );
+
+ nPosX = nNextX;
+ ++nColPos;
+ }
+ }
+ if ( bHasMainCols )
+ {
+ long nPosX = 0;
+ for ( nCol=nMainColStart; nCol<=nMainColEnd; nCol++ )
+ if (!pDoc->ColHidden(nCol, nTab))
+ {
+ sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nTab );
+ long nNextX = nPosX + (long) (nDocW * nScaleX);
+
+ long nPixelStart = pWindow->LogicToPixel( Size( nPosX, 0 ), aCellMapMode ).Width();
+ long nPixelEnd = pWindow->LogicToPixel( Size( nNextX, 0 ), aCellMapMode ).Width() - 1;
+ pColInfo[nColPos].Set( sal_False, nCol,
+ aMainRect.Left() + nPixelStart,
+ aMainRect.Left() + nPixelEnd );
+
+ nPosX = nNextX;
+ ++nColPos;
+ }
+ }
+ rInfo.SetColInfo( nColCount, pColInfo );
+ }
+ else
+ rInfo.SetColInfo( 0, NULL );
+
+ //
+ // get row info
+ //
+
+ SCROW nRowCount = 0;
+ if ( bHasHeaderRow )
+ ++nRowCount;
+ if ( bHasRepRows )
+ nRowCount += pDoc->CountVisibleRows(nRepeatRowStart, nRepeatRowEnd, nTab);
+ if ( bHasMainRows )
+ nRowCount += pDoc->CountVisibleRows(nMainRowStart, nMainRowEnd, nTab);
+
+ if ( nRowCount > 0 )
+ {
+ ScPreviewColRowInfo* pRowInfo = new ScPreviewColRowInfo[ nRowCount ];
+ SCROW nRowPos = 0;
+
+ if ( bHasHeaderRow )
+ {
+ pRowInfo[nRowPos].Set( sal_True, 0, aHeaderRect.Top(), aHeaderRect.Bottom() );
+ ++nRowPos;
+ }
+ if ( bHasRepRows )
+ {
+ long nPosY = 0;
+ for (SCROW nRow = nRepeatRowStart; nRow <= nRepeatRowEnd; ++nRow)
+ {
+ if (pDoc->RowHidden(nRow, nTab))
+ continue;
+
+ sal_uInt16 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( sal_False, nRow,
+ aRepeatRect.Top() + nPixelStart,
+ aRepeatRect.Top() + nPixelEnd );
+
+ nPosY = nNextY;
+ ++nRowPos;
+ }
+ }
+ if ( bHasMainRows )
+ {
+ long nPosY = 0;
+ for (SCROW nRow = nMainRowStart; nRow <= nMainRowEnd; ++nRow)
+ {
+ if (pDoc->RowHidden(nRow, nTab))
+ continue;
+
+ sal_uInt16 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( sal_False, nRow,
+ aMainRect.Top() + nPixelStart,
+ aMainRect.Top() + nPixelEnd );
+
+ nPosY = nNextY;
+ ++nRowPos;
+ }
+ }
+ rInfo.SetRowInfo( nRowCount, pRowInfo );
+ }
+ else
+ rInfo.SetRowInfo( 0, NULL );
+
+ //
+ // limit to visible area
+ //
+
+ rInfo.SetTab( nTab );
+ rInfo.LimitToArea( rVisiblePixel );
+}
+
+Rectangle ScPreviewLocationData::GetHeaderCellOutputRect(const Rectangle& rVisRect, const ScAddress& rCellPos, sal_Bool bColHeader) const
+{
+ // first a stupid implementation
+ // NN says here should be done more
+ Rectangle aClipRect;
+ ScPreviewTableInfo aTableInfo;
+ GetTableInfo( rVisRect, aTableInfo );
+
+ if ( (rCellPos.Col() >= 0) &&
+ (rCellPos.Row() >= 0) && (rCellPos.Col() < aTableInfo.GetCols()) &&
+ (rCellPos.Row() < aTableInfo.GetRows()) )
+ {
+ SCCOL nCol(0);
+ SCROW nRow(0);
+ if (bColHeader)
+ nCol = rCellPos.Col();
+ else
+ nRow = rCellPos.Row();
+ const ScPreviewColRowInfo& rColInfo = aTableInfo.GetColInfo()[nCol];
+ const ScPreviewColRowInfo& rRowInfo = aTableInfo.GetRowInfo()[nRow];
+
+ if ( rColInfo.bIsHeader || rRowInfo.bIsHeader )
+ aClipRect = Rectangle( rColInfo.nPixelStart, rRowInfo.nPixelStart, rColInfo.nPixelEnd, rRowInfo.nPixelEnd );
+ }
+ return aClipRect;
+}
+
+Rectangle ScPreviewLocationData::GetCellOutputRect(const ScAddress& rCellPos) const
+{
+ // first a stupid implementation
+ // NN says here should be done more
+ Rectangle aRect;
+ GetCellPosition(rCellPos, aRect);
+ return aRect;
+}
+
+// GetMainCellRange is used for links in PDF export
+
+sal_Bool ScPreviewLocationData::GetMainCellRange( ScRange& rRange, Rectangle& rPixRect ) const
+{
+ sal_uLong nCount = aEntries.Count();
+ for (sal_uLong nListPos=0; nListPos<nCount; nListPos++)
+ {
+ ScPreviewLocationEntry* pEntry = (ScPreviewLocationEntry*)aEntries.GetObject(nListPos);
+ if ( pEntry->eType == SC_PLOC_CELLRANGE && !pEntry->bRepeatCol && !pEntry->bRepeatRow )
+ {
+ rRange = pEntry->aCellRange;
+ rPixRect = pEntry->aPixelRect;
+ return sal_True;
+ }
+ }
+ return sal_False; // not found
+}
+
diff --git a/sc/source/ui/view/prevwsh.cxx b/sc/source/ui/view/prevwsh.cxx
new file mode 100644
index 000000000000..da4d4dfa28d7
--- /dev/null
+++ b/sc/source/ui/view/prevwsh.cxx
@@ -0,0 +1,1145 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/app.hxx>
+#include <editeng/sizeitem.hxx>
+#include <svl/srchitem.hxx>
+#include <svx/zoomslideritem.hxx>
+#include <svx/svdview.hxx>
+//CHINA001 #include <svx/zoom.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/request.hxx>
+#include <svl/stritem.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/help.hxx>
+#include <tools/urlobj.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/printer.hxx>
+
+#ifndef _SVX_ZOOMSLIDERITEM_HXX
+#include <svx/zoomslideritem.hxx>
+#endif
+#include "prevwsh.hxx"
+#include "preview.hxx"
+#include "printfun.hxx"
+#include "attrib.hxx"
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+#include "docsh.hxx"
+#include "tabvwsh.hxx"
+#include "stlpool.hxx"
+#include "editutil.hxx"
+#include "scresid.hxx"
+#include "globstr.hrc"
+#include "sc.hrc"
+#include "ViewSettingsSequenceDefines.hxx"
+#include "tpprint.hxx"
+#include "printopt.hxx"
+#include <xmloff/xmluconv.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <svx/svxdlg.hxx> //CHINA001
+#include <svx/dialogs.hrc> //CHINA001
+
+#ifndef _SVX_ZOOM_HXX
+#include <svx/zoom_def.hxx>
+#endif
+
+#include "sc.hrc" //CHINA001
+#include "scabstdlg.hxx" //CHINA001
+// fuer Rad-Maus
+#define SC_DELTA_ZOOM 10
+#define MINZOOM_SLIDER 10
+#define MAXZOOM_SLIDER 400
+
+#define SC_USERDATA_SEP ';'
+
+using namespace com::sun::star;
+
+// -----------------------------------------------------------------------
+
+#define ScPreviewShell
+#include "scslots.hxx"
+
+TYPEINIT1( ScPreviewShell, SfxViewShell );
+
+SFX_IMPL_INTERFACE( ScPreviewShell, SfxViewShell, ScResId(SCSTR_PREVIEWSHELL) )
+{
+ SFX_OBJECTBAR_REGISTRATION(SFX_OBJECTBAR_OBJECT|SFX_VISIBILITY_STANDARD|
+ SFX_VISIBILITY_SERVER|SFX_VISIBILITY_READONLYDOC,
+ ScResId(RID_OBJECTBAR_PREVIEW));
+ SFX_POPUPMENU_REGISTRATION(ScResId(RID_POPUP_PREVIEW));
+}
+
+SFX_IMPL_NAMED_VIEWFACTORY( ScPreviewShell, "PrintPreview" )
+{
+ SFX_VIEW_REGISTRATION(ScDocShell);
+}
+
+//------------------------------------------------------------------
+
+void ScPreviewShell::Construct( Window* pParent )
+{
+ eZoom = SVX_ZOOM_WHOLEPAGE;
+
+ pCorner = new ScrollBarBox( pParent, WB_SIZEABLE );
+
+ pHorScroll = new ScrollBar(pParent, WB_HSCROLL );
+ pVerScroll = new ScrollBar(pParent, WB_VSCROLL);
+
+ // SSA: --- RTL --- no mirroring for horizontal scrollbars
+ pHorScroll->EnableRTL( sal_False );
+
+ pHorScroll->SetEndScrollHdl( LINK( this, ScPreviewShell, ScrollHandler ) );
+ pVerScroll->SetEndScrollHdl( LINK( this, ScPreviewShell, ScrollHandler ) );
+
+ pPreview = new ScPreview( pParent, pDocShell, this );
+
+ SetPool( &SC_MOD()->GetPool() );
+ SetWindow( pPreview );
+ StartListening(*pDocShell,sal_True);
+ StartListening(*SFX_APP(),sal_True); // #i62045# #i62046# application is needed for Calc's own hints
+ SfxBroadcaster* pDrawBC = pDocShell->GetDocument()->GetDrawBroadcaster();
+ if (pDrawBC)
+ StartListening(*pDrawBC);
+
+ pHorScroll->Show();
+ pVerScroll->Show();
+ pCorner->Show();
+ SetHelpId( HID_SCSHELL_PREVWSH );
+ SetName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Preview")));
+}
+
+ScPreviewShell::ScPreviewShell( SfxViewFrame* pViewFrame,
+ SfxViewShell* pOldSh ) :
+ SfxViewShell( pViewFrame, SFX_VIEW_CAN_PRINT | SFX_VIEW_HAS_PRINTOPTIONS ),
+ pDocShell( (ScDocShell*)pViewFrame->GetObjectShell() ),
+ nSourceDesignMode( SC_FORCEMODE_NONE ),
+ pAccessibilityBroadcaster( NULL )
+{
+ Construct( &pViewFrame->GetWindow() );
+
+ if ( pOldSh && pOldSh->ISA( ScTabViewShell ) )
+ {
+ // store view settings, show table from TabView
+ //! store live ScViewData instead, and update on ScTablesHint?
+ //! or completely forget aSourceData on ScTablesHint?
+
+ ScTabViewShell* pTabViewShell = ((ScTabViewShell*)pOldSh);
+ ScViewData* pData = pTabViewShell->GetViewData();
+ pData->WriteUserDataSequence( aSourceData );
+ InitStartTable( pData->GetTabNo() );
+
+ // #106334# also have to store the TabView's DesignMode state
+ // (only if draw view exists)
+ SdrView* pDrawView = pTabViewShell->GetSdrView();
+ if ( pDrawView )
+ nSourceDesignMode = pDrawView->IsDesignMode();
+ }
+}
+
+__EXPORT ScPreviewShell::~ScPreviewShell()
+{
+ // #108333#; notify Accessibility that Shell is dying and before destroy all
+ BroadcastAccessibility( SfxSimpleHint( SFX_HINT_DYING ) );
+ DELETEZ(pAccessibilityBroadcaster);
+
+ SfxBroadcaster* pDrawBC = pDocShell->GetDocument()->GetDrawBroadcaster();
+ if (pDrawBC)
+ EndListening(*pDrawBC);
+ EndListening(*SFX_APP());
+ EndListening(*pDocShell);
+
+ SetWindow(0);
+ delete pPreview;
+ delete pHorScroll;
+ delete pVerScroll;
+ delete pCorner;
+
+ // #97612# normal mode of operation is switching back to default view in the same frame,
+ // so there's no need to activate any other window here anymore
+}
+
+void ScPreviewShell::InitStartTable(SCTAB nTab)
+{
+ pPreview->SetPageNo( pPreview->GetFirstPage(nTab) );
+}
+
+//------------------------------------------------------------------
+
+String __EXPORT ScPreviewShell::GetDescription() const
+{
+ return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(" ** Test ** "));
+}
+
+Size __EXPORT ScPreviewShell::GetOptimalSizePixel() const
+{
+ Size aOptSize(100,100);
+
+ ScTabViewShell* pViewSh = pDocShell->GetBestViewShell();
+
+ if ( pViewSh )
+ {
+ ScViewData* pViewData = pViewSh->GetViewData();
+ SCTAB nCurTab = pViewData->GetTabNo();
+ ScDocument* pDoc = pDocShell->GetDocument();
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find(
+ pDoc->GetPageStyle( nCurTab ),
+ SFX_STYLE_FAMILY_PAGE );
+
+ DBG_ASSERT( pStyleSheet, "PageStyle not found :-/" );
+
+ if ( pStyleSheet )
+ {
+ const SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ const SvxSizeItem& rItem = (const SvxSizeItem&)rSet.Get( ATTR_PAGE_SIZE );
+ const Size& rPageSize = rItem.GetSize();
+
+ aOptSize.Width() = (long) (rPageSize.Width() * pViewData->GetPPTX());
+ aOptSize.Height() = (long) (rPageSize.Height() * pViewData->GetPPTY());
+ }
+ }
+ else
+ {
+ DBG_ERROR( "TabViewShell not found :-/" );
+ }
+
+ return aOptSize;
+}
+
+void __EXPORT ScPreviewShell::AdjustPosSizePixel( const Point &rPos, const Size &rSize )
+{
+ long nBarW = GetViewFrame()->GetWindow().GetSettings().GetStyleSettings().GetScrollBarSize();
+ long nBarH = nBarW;
+// long nBarW = pVerScroll->GetSizePixel().Width();
+// long nBarH = pHorScroll->GetSizePixel().Height();
+
+ Size aOutSize( rSize.Width()-nBarW, rSize.Height()-nBarH );
+ pPreview->SetPosSizePixel( rPos, aOutSize );
+ pHorScroll->SetPosSizePixel( Point( rPos.X(), rPos.Y() + aOutSize.Height() ),
+ Size( aOutSize.Width(), nBarH ) );
+ pVerScroll->SetPosSizePixel( Point( rPos.X() + aOutSize.Width(), rPos.Y() ),
+ Size( nBarW, aOutSize.Height() ) );
+ pCorner->SetPosSizePixel( Point( rPos.X() + aOutSize.Width(), rPos.Y() + aOutSize.Height() ),
+ Size( nBarW, nBarH ) );
+
+ if ( SVX_ZOOM_WHOLEPAGE == eZoom )
+ pPreview->SetZoom( pPreview->GetOptimalZoom(sal_False) );
+ else if ( SVX_ZOOM_PAGEWIDTH == eZoom )
+ pPreview->SetZoom( pPreview->GetOptimalZoom(sal_True) );
+
+ UpdateScrollBars();
+}
+
+void __EXPORT ScPreviewShell::InnerResizePixel( const Point &rOfs, const Size &rSize )
+{
+ AdjustPosSizePixel( rOfs,rSize );
+}
+
+void __EXPORT ScPreviewShell::OuterResizePixel( const Point &rOfs, const Size &rSize )
+{
+ AdjustPosSizePixel( rOfs,rSize );
+}
+
+void ScPreviewShell::UpdateScrollBars()
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTab = pPreview->GetTab();
+
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ),
+ SFX_STYLE_FAMILY_PAGE );
+ DBG_ASSERT(pStyleSheet,"StyleSheet nicht gefunden");
+ if (!pStyleSheet) return;
+ const SfxItemSet* pParamSet = &pStyleSheet->GetItemSet();
+
+ Size aPageSize = ((const SvxSizeItem&) pParamSet->Get(ATTR_PAGE_SIZE)).GetSize();
+ aPageSize.Width() = (long) (aPageSize.Width() * HMM_PER_TWIPS );
+ aPageSize.Height() = (long) (aPageSize.Height() * HMM_PER_TWIPS );
+
+ // for centering, page size without the shadow is used
+
+ Size aWindowSize = pPreview->GetOutputSize();
+
+ Point aOfs = pPreview->GetOffset();
+ long nMaxPos;
+
+ if( pHorScroll )
+ {
+ pHorScroll->SetRange( Range( 0, aPageSize.Width() ) );
+ pHorScroll->SetLineSize( aWindowSize.Width() / 16 );
+ pHorScroll->SetPageSize( aWindowSize.Width() );
+ pHorScroll->SetVisibleSize( aWindowSize.Width() );
+ nMaxPos = aPageSize.Width() - aWindowSize.Width();
+ if ( nMaxPos<0 )
+ {
+ // page smaller than window -> center (but put scrollbar to 0)
+ aOfs.X() = 0;
+ pPreview->SetXOffset( nMaxPos / 2 );
+ }
+ else if (aOfs.X() < 0)
+ {
+ // page larger than window -> never use negative offset
+ aOfs.X() = 0;
+ pPreview->SetXOffset( 0 );
+ }
+ else if (aOfs.X() > nMaxPos)
+ {
+ // limit offset to align with right edge of window
+ aOfs.X() = nMaxPos;
+ pPreview->SetXOffset(nMaxPos);
+ }
+ pHorScroll->SetThumbPos( aOfs.X() );
+ }
+
+ if( pVerScroll )
+ {
+ long nPageNo = pPreview->GetPageNo();
+ long nTotalPages = pPreview->GetTotalPages();
+
+ nMaxVertPos = aPageSize.Height() - aWindowSize.Height();
+ pVerScroll->SetLineSize( aWindowSize.Height() / 16 );
+ pVerScroll->SetPageSize( aWindowSize.Height() );
+ pVerScroll->SetVisibleSize( aWindowSize.Height() );
+ if ( nMaxVertPos < 0 )
+ {
+ // page smaller than window -> center (but put scrollbar to 0)
+ aOfs.Y() = 0;
+ pPreview->SetYOffset( nMaxVertPos / 2 );
+ pVerScroll->SetThumbPos( nPageNo * aWindowSize.Height() );
+ pVerScroll->SetRange( Range( 0, aWindowSize.Height() * nTotalPages ));
+ }
+ else if (aOfs.Y() < 0)
+ {
+ // page larger than window -> never use negative offset
+ pVerScroll->SetRange( Range( 0, aPageSize.Height() ) );
+ aOfs.Y() = 0;
+ pPreview->SetYOffset( 0 );
+ pVerScroll->SetThumbPos( aOfs.Y() );
+ }
+ else if (aOfs.Y() > nMaxVertPos )
+ {
+ // limit offset to align with window bottom
+ pVerScroll->SetRange( Range( 0, aPageSize.Height() ) );
+ aOfs.Y() = nMaxVertPos;
+ pPreview->SetYOffset( nMaxVertPos );
+ pVerScroll->SetThumbPos( aOfs.Y() );
+ }
+ }
+}
+
+IMPL_LINK (ScPreviewShell,ScrollHandler, ScrollBar* ,pScroll )
+{
+ long nPos = pScroll->GetThumbPos();
+ long nDelta = pScroll->GetDelta();
+ long nMaxRange = pScroll->GetRangeMax();
+ long nTotalPages = pPreview->GetTotalPages();
+ long nPageNo = 0;
+ long nPerPageLength = 0;
+ sal_Bool bIsDivide = sal_True;
+
+ if( nTotalPages )
+ nPerPageLength = nMaxRange / nTotalPages;
+
+ if( nPerPageLength )
+ {
+ nPageNo = nPos / nPerPageLength;
+ if( nPos % nPerPageLength )
+ {
+ bIsDivide = sal_False;
+ nPageNo ++;
+ }
+ }
+
+ sal_Bool bHoriz = ( pScroll == pHorScroll );
+
+ if( bHoriz )
+ pPreview->SetXOffset( nPos );
+ else
+ {
+ if( nMaxVertPos > 0 )
+ pPreview->SetYOffset( nPos );
+ else
+ {
+ Point aMousePos = pScroll->OutputToNormalizedScreenPixel( pScroll->GetPointerPosPixel() );
+ Point aPos = pScroll->GetParent()->OutputToNormalizedScreenPixel( pScroll->GetPosPixel() );
+ String aHelpStr;
+ Rectangle aRect;
+ sal_uInt16 nAlign;
+
+ if( nDelta < 0 )
+ {
+ if ( nTotalPages && nPageNo > 0 && !bIsDivide )
+ pPreview->SetPageNo( nPageNo-1 );
+ if( bIsDivide )
+ pPreview->SetPageNo( nPageNo );
+
+ aHelpStr = ScGlobal::GetRscString( STR_PAGE );
+ aHelpStr += ' ';
+ aHelpStr += String::CreateFromInt32( nPageNo );
+
+ aHelpStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " / " ));
+ aHelpStr += String::CreateFromInt32( nTotalPages );
+ }
+ else if( nDelta > 0 )
+ {
+ sal_Bool bAllTested = pPreview->AllTested();
+ if ( nTotalPages && ( nPageNo < nTotalPages || !bAllTested ) )
+ pPreview->SetPageNo( nPageNo );
+
+ aHelpStr = ScGlobal::GetRscString( STR_PAGE );
+ aHelpStr += ' ';
+ aHelpStr += String::CreateFromInt32( nPageNo+1 );
+
+ aHelpStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " / " ));
+ aHelpStr += String::CreateFromInt32( nTotalPages );
+ }
+
+ aRect.Left() = aPos.X() - 8;
+ aRect.Top() = aMousePos.Y();
+ aRect.Right() = aRect.Left();
+ aRect.Top() = aRect.Top();
+ nAlign = QUICKHELP_BOTTOM|QUICKHELP_CENTER;
+ Help::ShowQuickHelp( pScroll->GetParent(), aRect, aHelpStr, nAlign );
+ }
+ }
+
+ return 0;
+}
+
+sal_Bool ScPreviewShell::ScrollCommand( const CommandEvent& rCEvt )
+{
+ sal_Bool bDone = sal_False;
+ const CommandWheelData* pData = rCEvt.GetWheelData();
+ if ( pData && pData->GetMode() == COMMAND_WHEEL_ZOOM )
+ {
+ long nOld = pPreview->GetZoom();
+ long nNew = nOld;
+ if ( pData->GetDelta() < 0 )
+ nNew = Max( (long) MINZOOM, (long)( nOld - SC_DELTA_ZOOM ) );
+ else
+ nNew = Min( (long) MAXZOOM, (long)( nOld + SC_DELTA_ZOOM ) );
+
+ if ( nNew != nOld )
+ {
+ eZoom = SVX_ZOOM_PERCENT;
+ pPreview->SetZoom( (sal_uInt16)nNew );
+ }
+
+ bDone = sal_True;
+ }
+ else
+ {
+ bDone = pPreview->HandleScrollCommand( rCEvt, pHorScroll, pVerScroll );
+ }
+
+ return bDone;
+}
+
+SfxPrinter* __EXPORT ScPreviewShell::GetPrinter( sal_Bool bCreate )
+{
+ return pDocShell->GetPrinter(bCreate);
+}
+
+sal_uInt16 __EXPORT ScPreviewShell::SetPrinter( SfxPrinter *pNewPrinter, sal_uInt16 nDiffFlags, bool )
+{
+ return pDocShell->SetPrinter( pNewPrinter, nDiffFlags );
+}
+
+SfxTabPage* ScPreviewShell::CreatePrintOptionsPage( Window *pParent, const SfxItemSet &rOptions )
+{
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+ //CHINA001 return ScTpPrintOptions::Create( pParent, rOptions );
+ ::CreateTabPage ScTpPrintOptionsCreate = pFact->GetTabPageCreatorFunc( RID_SCPAGE_PRINT );
+ if ( ScTpPrintOptionsCreate )
+ return (*ScTpPrintOptionsCreate)( pParent, rOptions);
+ return 0;
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScPreviewShell::Activate(sal_Bool bMDI)
+{
+ SfxViewShell::Activate(bMDI);
+
+ //! Basic etc. -> auslagern in eigene Datei (s. tabvwsh4)
+
+ if (bMDI)
+ {
+ // InputHdl ist jetzt meistens Null, keine Assertion mehr!
+ ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
+ if ( pInputHdl )
+ pInputHdl->NotifyChange( NULL );
+ }
+}
+
+void __EXPORT ScPreviewShell::Deactivate(sal_Bool bMDI)
+{
+ SfxViewShell::Deactivate(bMDI);
+
+ if (bMDI)
+ {
+ }
+}
+
+//------------------------------------------------------------------------
+
+void __EXPORT ScPreviewShell::Execute( SfxRequest& rReq )
+{
+ sal_uInt16 nSlot = rReq.GetSlot();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+
+ switch ( nSlot )
+ {
+ case SID_FORMATPAGE:
+ case SID_STATUS_PAGESTYLE:
+ case SID_HFEDIT:
+ pDocShell->ExecutePageStyle( *this, rReq, pPreview->GetTab() );
+ break;
+ case SID_REPAINT:
+ pPreview->Invalidate();
+ rReq.Done();
+ break;
+ case SID_PREV_TABLE: // Accelerator
+ case SID_PREVIEW_PREVIOUS:
+ {
+ long nPage = pPreview->GetPageNo();
+ long nTotal = pPreview->GetTotalPages();
+ if (nTotal && nPage > 0)
+ pPreview->SetPageNo( nPage-1 );
+ }
+ break;
+ case SID_NEXT_TABLE: // Accelerator
+ case SID_PREVIEW_NEXT:
+ {
+ sal_Bool bAllTested = pPreview->AllTested();
+ long nPage = pPreview->GetPageNo();
+ long nTotal = pPreview->GetTotalPages();
+ if (nTotal && (nPage+1 < nTotal || !bAllTested))
+ pPreview->SetPageNo( nPage+1 );
+ }
+ break;
+ case SID_CURSORTOPOFFILE: // Accelerator
+ case SID_PREVIEW_FIRST:
+ {
+ long nPage = pPreview->GetPageNo();
+ long nTotal = pPreview->GetTotalPages();
+ if (nTotal && nPage != 0)
+ pPreview->SetPageNo( 0 );
+ }
+ break;
+ case SID_CURSORENDOFFILE: // Accelerator
+ case SID_PREVIEW_LAST:
+ {
+ if (!pPreview->AllTested())
+ pPreview->CalcAll();
+
+ long nPage = pPreview->GetPageNo();
+ long nTotal = pPreview->GetTotalPages();
+ if (nTotal && nPage+1 != nTotal)
+ pPreview->SetPageNo( nTotal-1 );
+ }
+ break;
+ case SID_ATTR_ZOOM:
+ case FID_SCALE:
+ {
+ sal_uInt16 nZoom = 100;
+ sal_Bool bCancel = sal_False;
+
+ eZoom = SVX_ZOOM_PERCENT;
+
+ if ( pReqArgs )
+ {
+
+ const SvxZoomItem& rZoomItem = (const SvxZoomItem&)
+ pReqArgs->Get(SID_ATTR_ZOOM);
+
+ eZoom = rZoomItem.GetType();
+ nZoom = rZoomItem.GetValue();
+ }
+ else
+ {
+ SfxItemSet aSet ( GetPool(), SID_ATTR_ZOOM, SID_ATTR_ZOOM );
+ SvxZoomItem aZoomItem( SVX_ZOOM_PERCENT, pPreview->GetZoom(), SID_ATTR_ZOOM );
+
+ aSet.Put( aZoomItem );
+ //CHINA001 SvxZoomDialog* pDlg = pDlg = new SvxZoomDialog( NULL, aSet );
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ if(pFact)
+ {
+ AbstractSvxZoomDialog* pDlg = pFact->CreateSvxZoomDialog(NULL, aSet);
+ DBG_ASSERT(pDlg, "Dialogdiet fail!");//CHINA001
+ pDlg->SetLimits( 20, 400 );
+ pDlg->HideButton( ZOOMBTN_OPTIMAL );
+ bCancel = ( RET_CANCEL == pDlg->Execute() );
+
+ if ( !bCancel )
+ {
+ const SvxZoomItem& rZoomItem = (const SvxZoomItem&)
+ pDlg->GetOutputItemSet()->
+ Get( SID_ATTR_ZOOM );
+
+ eZoom = rZoomItem.GetType();
+ nZoom = rZoomItem.GetValue();
+ }
+
+ delete pDlg;
+ }
+ }
+
+ if ( !bCancel )
+ {
+ switch ( eZoom )
+ {
+ case SVX_ZOOM_OPTIMAL:
+ case SVX_ZOOM_WHOLEPAGE:
+ nZoom = pPreview->GetOptimalZoom(sal_False);
+ break;
+ case SVX_ZOOM_PAGEWIDTH:
+ nZoom = pPreview->GetOptimalZoom(sal_True);
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ pPreview->SetZoom( nZoom );
+ rReq.Done();
+ }
+ }
+ break;
+ case SID_PREVIEW_ZOOMIN:
+ {
+ sal_uInt16 nNew = pPreview->GetZoom() + 20 ;
+ nNew -= nNew % 20;
+ pPreview->SetZoom( nNew );
+ eZoom = SVX_ZOOM_PERCENT;
+ rReq.Done();
+ }
+ break;
+ case SID_PREVIEW_ZOOMOUT:
+ {
+ sal_uInt16 nNew = pPreview->GetZoom() - 1;
+ nNew -= nNew % 20;
+ pPreview->SetZoom( nNew );
+ eZoom = SVX_ZOOM_PERCENT;
+ rReq.Done();
+ }
+ break;
+ case SID_PREVIEW_MARGIN:
+ {
+ sal_Bool bMargin = pPreview->GetPageMargins();
+ pPreview->SetPageMargins( !bMargin );
+ pPreview->Invalidate();
+ rReq.Done();
+ }
+ break;
+ case SID_ATTR_ZOOMSLIDER:
+ {
+ const SfxPoolItem* pItem;
+ eZoom = SVX_ZOOM_PERCENT;
+ if( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( SID_ATTR_ZOOMSLIDER, sal_True, &pItem ) )
+ {
+ const sal_uInt16 nCurrentZoom = ((const SvxZoomSliderItem*)pItem)->GetValue();
+ if( nCurrentZoom )
+ {
+ pPreview->SetZoom( nCurrentZoom );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+ case SID_PREVIEW_SCALINGFACTOR:
+ {
+ const SfxPoolItem* pItem;
+ SCTAB nTab = pPreview->GetTab();
+ String aOldName = pDocShell->GetDocument()->GetPageStyle( pPreview->GetTab() );
+ ScStyleSheetPool* pStylePool = pDocShell->GetDocument()->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aOldName, SFX_STYLE_FAMILY_PAGE );
+ DBG_ASSERT( pStyleSheet, "PageStyle not found! :-/" );
+
+ if ( pReqArgs && pStyleSheet && SFX_ITEM_SET == pReqArgs->GetItemState( SID_PREVIEW_SCALINGFACTOR, sal_True, &pItem ) )
+ {
+ const sal_uInt16 nCurrentZoom = ((const SvxZoomSliderItem *)pItem)->GetValue();
+ SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, nCurrentZoom ) );
+ ScPrintFunc aPrintFunc( pDocShell, pDocShell->GetPrinter(), nTab );
+ aPrintFunc.UpdatePages();
+ rReq.Done();
+ }
+ GetViewFrame()->GetBindings().Invalidate( nSlot );
+ }
+ break;
+ case SID_PRINTPREVIEW:
+ case SID_PREVIEW_CLOSE:
+ // print preview is now always in the same frame as the tab view
+ // -> always switch this frame back to normal view
+ // (ScTabViewShell ctor reads stored view data)
+
+ GetViewFrame()->GetDispatcher()->Execute( SID_VIEWSHELL0, SFX_CALLMODE_ASYNCHRON );
+ break;
+ case SID_CURSORPAGEUP:
+ case SID_CURSORPAGEDOWN:
+ case SID_CURSORHOME:
+ case SID_CURSOREND:
+ case SID_CURSORUP:
+ case SID_CURSORDOWN:
+ case SID_CURSORLEFT:
+ case SID_CURSORRIGHT:
+ DoScroll( nSlot );
+ break;
+ case SID_CANCEL:
+ if( ScViewUtil::IsFullScreen( *this ) )
+ ScViewUtil::SetFullScreen( *this, false );
+ break;
+
+ default:
+ break;
+ }
+}
+
+void __EXPORT ScPreviewShell::GetState( SfxItemSet& rSet )
+{
+ pPreview->SetInGetState(sal_True);
+
+ SCTAB nTab = pPreview->GetTab();
+ long nPage = pPreview->GetPageNo();
+ long nTotal = pPreview->GetTotalPages();
+ sal_uInt16 nZoom = pPreview->GetZoom();
+ sal_Bool bAllTested = pPreview->AllTested();
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch (nWhich)
+ {
+ case SID_STATUS_PAGESTYLE:
+ case SID_HFEDIT:
+ pDocShell->GetStatePageStyle( *this, rSet, nTab );
+ break;
+ case SID_UNDO:
+ case SID_REDO:
+ case SID_REPEAT:
+ rSet.DisableItem(nWhich);
+ break;
+ case SID_PREVIEW_PREVIOUS:
+ case SID_PREVIEW_FIRST:
+ if (!nTotal || nPage==0)
+ rSet.DisableItem(nWhich);
+ break;
+ case SID_PREVIEW_NEXT:
+ case SID_PREVIEW_LAST:
+ if (bAllTested)
+ if (!nTotal || nPage==nTotal-1)
+ rSet.DisableItem(nWhich);
+ break;
+ case SID_PREVIEW_ZOOMIN:
+ if (nZoom >= 400)
+ rSet.DisableItem(nWhich);
+ break;
+ case SID_PREVIEW_ZOOMOUT:
+ if (nZoom <= 20)
+ rSet.DisableItem(nWhich);
+ break;
+ case SID_ATTR_ZOOM:
+ {
+ SvxZoomItem aZoom( eZoom, nZoom, nWhich );
+ aZoom.SetValueSet( SVX_ZOOM_ENABLE_ALL & ~SVX_ZOOM_ENABLE_OPTIMAL );
+ rSet.Put( aZoom );
+ }
+ break;
+ case SID_ATTR_ZOOMSLIDER:
+ {
+ SvxZoomSliderItem aZoomSliderItem( nZoom, MINZOOM, MAXZOOM, SID_ATTR_ZOOMSLIDER );
+ aZoomSliderItem.AddSnappingPoint( 100 );
+ rSet.Put( aZoomSliderItem );
+ }
+ break;
+ case SID_PREVIEW_SCALINGFACTOR:
+ {
+ if( pDocShell->IsReadOnly() )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ String aOldName = pDocShell->GetDocument()->GetPageStyle( pPreview->GetTab() );
+ ScStyleSheetPool* pStylePool = pDocShell->GetDocument()->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aOldName, SFX_STYLE_FAMILY_PAGE );
+ DBG_ASSERT( pStyleSheet, "PageStyle not found! :-/" );
+
+ if ( pStyleSheet )
+ {
+ SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
+ sal_uInt16 nCurrentZoom = ((const SfxUInt16Item&)rStyleSet.Get(ATTR_PAGE_SCALE)).GetValue();
+ if( nCurrentZoom )
+ {
+ SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM_SLIDER, MAXZOOM_SLIDER, SID_PREVIEW_SCALINGFACTOR );
+ aZoomSliderItem.AddSnappingPoint( 100 );
+ rSet.Put( aZoomSliderItem );
+ }
+ else
+ rSet.DisableItem( nWhich );
+ }
+ }
+ }
+ break;
+ case SID_STATUS_DOCPOS:
+ rSet.Put( SfxStringItem( nWhich, pPreview->GetPosString() ) );
+ break;
+ case SID_PRINTPREVIEW:
+ rSet.Put( SfxBoolItem( nWhich, sal_True ) );
+ break;
+ case SID_FORMATPAGE:
+ case SID_PREVIEW_MARGIN:
+ if( pDocShell->IsReadOnly() )
+ rSet.DisableItem( nWhich );
+ break;
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+
+ pPreview->SetInGetState(sal_False);
+}
+
+void ScPreviewShell::FillFieldData( ScHeaderFieldData& rData )
+{
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTab = pPreview->GetTab();
+ pDoc->GetName( nTab, rData.aTabName );
+
+ rData.aTitle = pDocShell->GetTitle();
+ const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject();
+ rData.aLongDocName = rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
+ if ( rData.aLongDocName.Len() )
+ rData.aShortDocName = rURLObj.GetName( INetURLObject::DECODE_UNAMBIGUOUS );
+ else
+ rData.aShortDocName = rData.aLongDocName = rData.aTitle;
+ rData.nPageNo = pPreview->GetPageNo() + 1;
+
+ sal_Bool bAllTested = pPreview->AllTested();
+ if (bAllTested)
+ rData.nTotalPages = pPreview->GetTotalPages();
+ else
+ rData.nTotalPages = 99;
+
+ // eNumType kennt der Dialog selber
+}
+
+void __EXPORT ScPreviewShell::WriteUserData(String& rData, sal_Bool /* bBrowse */)
+{
+ // nZoom
+ // nPageNo
+
+ rData = String::CreateFromInt32(pPreview->GetZoom());
+ rData += (sal_Unicode) SC_USERDATA_SEP;
+ rData += String::CreateFromInt32(pPreview->GetPageNo());
+}
+
+void __EXPORT ScPreviewShell::ReadUserData(const String& rData, sal_Bool /* bBrowse */)
+{
+ xub_StrLen nCount = rData.GetTokenCount();
+ if (nCount)
+ {
+ xub_StrLen nIndex = 0;
+ pPreview->SetZoom((sal_uInt16)rData.GetToken( 0, SC_USERDATA_SEP, nIndex ).ToInt32());
+ pPreview->SetPageNo(rData.GetToken( 0, SC_USERDATA_SEP, nIndex ).ToInt32());
+ eZoom = SVX_ZOOM_PERCENT;
+ }
+}
+
+void __EXPORT ScPreviewShell::WriteUserDataSequence(uno::Sequence < beans::PropertyValue >& rSeq, sal_Bool /* bBrowse */)
+{
+ rSeq.realloc(3);
+ beans::PropertyValue* pSeq = rSeq.getArray();
+ if(pSeq)
+ {
+ sal_uInt16 nViewID(GetViewFrame()->GetCurViewId());
+ pSeq[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_VIEWID));
+ rtl::OUStringBuffer sBuffer(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_VIEW)));
+ SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(nViewID));
+ pSeq[0].Value <<= sBuffer.makeStringAndClear();
+ pSeq[1].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ZOOMVALUE));
+ pSeq[1].Value <<= sal_Int32 (pPreview->GetZoom());
+ pSeq[2].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PageNumber"));
+ pSeq[2].Value <<= pPreview->GetPageNo();
+ }
+}
+
+void __EXPORT ScPreviewShell::ReadUserDataSequence(const uno::Sequence < beans::PropertyValue >& rSeq, sal_Bool /* bBrowse */)
+{
+ sal_Int32 nCount(rSeq.getLength());
+ if (nCount)
+ {
+ sal_Int32 nTemp = 0;
+ const beans::PropertyValue* pSeq = rSeq.getConstArray();
+ if(pSeq)
+ {
+ for(sal_Int32 i = 0; i < nCount; i++, pSeq++)
+ {
+ rtl::OUString sName(pSeq->Name);
+ if(sName.compareToAscii(SC_ZOOMVALUE) == 0)
+ {
+ if (pSeq->Value >>= nTemp)
+ pPreview->SetZoom(sal_uInt16(nTemp));
+ }
+ else if (sName.compareToAscii("PageNumber") == 0)
+ {
+ if (pSeq->Value >>= nTemp)
+ pPreview->SetPageNo(nTemp);
+ }
+ }
+ }
+ }
+}
+
+void ScPreviewShell::DoScroll( sal_uInt16 nMode )
+{
+ Point aCurPos, aPrevPos;
+
+ long nHRange = pHorScroll->GetRange().Max();
+ long nHLine = pHorScroll->GetLineSize();
+ long nHPage = pHorScroll->GetPageSize();
+ long nVRange = pVerScroll->GetRange().Max();
+ long nVLine = pVerScroll->GetLineSize();
+ long nVPage = pVerScroll->GetPageSize();
+
+ aCurPos.X() = pHorScroll->GetThumbPos();
+ aCurPos.Y() = pVerScroll->GetThumbPos();
+ aPrevPos = aCurPos;
+
+ long nThumbPos = pVerScroll->GetThumbPos();
+ long nRangeMax = pVerScroll->GetRangeMax();
+
+ switch( nMode )
+ {
+ case SID_CURSORUP:
+ if( nMaxVertPos<0 )
+ {
+ long nPage = pPreview->GetPageNo();
+
+ if( nPage>0 )
+ {
+ SfxViewFrame* pSfxViewFrame = GetViewFrame();
+ SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_PREVIOUS );
+ Execute( aSfxRequest );
+ }
+ }
+ else
+ aCurPos.Y() -= nVLine;
+ break;
+ case SID_CURSORDOWN:
+ if( nMaxVertPos<0 )
+ {
+ long nPage = pPreview->GetPageNo();
+ long nTotal = pPreview->GetTotalPages();
+
+ // before testing for last page, make sure all page counts are calculated
+ if ( nPage+1 == nTotal && !pPreview->AllTested() )
+ {
+ pPreview->CalcAll();
+ nTotal = pPreview->GetTotalPages();
+ }
+
+ if( nPage<nTotal-1 )
+ {
+ SfxViewFrame* pSfxViewFrame = GetViewFrame();
+ SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_NEXT );
+ Execute( aSfxRequest );
+ }
+ }
+ else
+ aCurPos.Y() += nVLine;
+ break;
+ case SID_CURSORLEFT:
+ aCurPos.X() -= nHLine;
+ break;
+ case SID_CURSORRIGHT:
+ aCurPos.X() += nHLine;
+ break;
+ case SID_CURSORPAGEUP:
+ if( nThumbPos==0 || nMaxVertPos<0 )
+ {
+ long nPage = pPreview->GetPageNo();
+
+ if( nPage>0 )
+ {
+ SfxViewFrame* pSfxViewFrame = GetViewFrame();
+ SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_PREVIOUS );
+ Execute( aSfxRequest );
+ aCurPos.Y() = nVRange;
+ }
+ }
+ else
+ aCurPos.Y() -= nVPage;
+ break;
+ case SID_CURSORPAGEDOWN:
+ if( (abs(nVPage+nThumbPos-nRangeMax)<10) || nMaxVertPos<0 )
+ {
+ long nPage = pPreview->GetPageNo();
+ long nTotal = pPreview->GetTotalPages();
+
+ // before testing for last page, make sure all page counts are calculated
+ if ( nPage+1 == nTotal && !pPreview->AllTested() )
+ {
+ pPreview->CalcAll();
+ nTotal = pPreview->GetTotalPages();
+ }
+ if( nPage<nTotal-1 )
+ {
+ SfxViewFrame* pSfxViewFrame = GetViewFrame();
+ SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_NEXT );
+ Execute( aSfxRequest );
+ aCurPos.Y() = 0;
+ }
+ }
+ else
+ aCurPos.Y() += nVPage;
+ break;
+ case SID_CURSORHOME:
+ if( nMaxVertPos<0 )
+ {
+ long nPage = pPreview->GetPageNo();
+ long nTotal = pPreview->GetTotalPages();
+ if( nTotal && nPage != 0 )
+ {
+ SfxViewFrame* pSfxViewFrame = GetViewFrame();
+ SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_FIRST );
+ Execute( aSfxRequest );
+ }
+ }
+ else
+ {
+ aCurPos.Y() = 0;
+ aCurPos.X() = 0;
+ }
+ break;
+ case SID_CURSOREND:
+ if( nMaxVertPos<0 )
+ {
+ if( !pPreview->AllTested() )
+ pPreview->CalcAll();
+ long nPage = pPreview->GetPageNo();
+ long nTotal = pPreview->GetTotalPages();
+ if( nTotal && nPage+1 != nTotal )
+ {
+ SfxViewFrame* pSfxViewFrame = GetViewFrame();
+ SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_LAST );
+ Execute( aSfxRequest );
+ }
+ }
+ else
+ {
+ aCurPos.Y() = nVRange;
+ aCurPos.X() = nHRange;
+ }
+ break;
+ }
+
+ // nHRange-nHPage kann negativ sein, deshalb Abfrage auf < 0 hinterher
+
+ if( aCurPos.Y() > (nVRange-nVPage) )
+ aCurPos.Y() = (nVRange-nVPage);
+ if( aCurPos.Y() < 0 )
+ aCurPos.Y() = 0;
+ if( aCurPos.X() > (nHRange-nHPage) )
+ aCurPos.X() = (nHRange-nHPage);
+ if( aCurPos.X() < 0 )
+ aCurPos.X() = 0;
+
+ if( nMaxVertPos>=0 )
+ {
+ if( aCurPos.Y() != aPrevPos.Y() )
+ {
+ pVerScroll->SetThumbPos( aCurPos.Y() );
+ pPreview->SetYOffset( aCurPos.Y() );
+ }
+ }
+
+ if( aCurPos.X() != aPrevPos.X() )
+ {
+ pHorScroll->SetThumbPos( aCurPos.X() );
+ pPreview->SetXOffset( aCurPos.X() );
+ }
+
+}
+
+void ScPreviewShell::AddAccessibilityObject( SfxListener& rObject )
+{
+ if (!pAccessibilityBroadcaster)
+ pAccessibilityBroadcaster = new SfxBroadcaster;
+
+ rObject.StartListening( *pAccessibilityBroadcaster );
+}
+
+void ScPreviewShell::RemoveAccessibilityObject( SfxListener& rObject )
+{
+ if (pAccessibilityBroadcaster)
+ rObject.EndListening( *pAccessibilityBroadcaster );
+ else
+ {
+ DBG_ERROR("kein Accessibility-Broadcaster?");
+ }
+}
+
+void ScPreviewShell::BroadcastAccessibility( const SfxHint &rHint )
+{
+ if (pAccessibilityBroadcaster)
+ pAccessibilityBroadcaster->Broadcast( rHint );
+}
+
+sal_Bool ScPreviewShell::HasAccessibilityObjects()
+{
+ return pAccessibilityBroadcaster && pAccessibilityBroadcaster->HasListeners();
+}
+
+const ScPreviewLocationData& ScPreviewShell::GetLocationData()
+{
+ return pPreview->GetLocationData();
+}
+
+ScDocument* ScPreviewShell::GetDocument()
+{
+ return pDocShell->GetDocument();
+}
+
+
diff --git a/sc/source/ui/view/prevwsh2.cxx b/sc/source/ui/view/prevwsh2.cxx
new file mode 100644
index 000000000000..22d511e762f9
--- /dev/null
+++ b/sc/source/ui/view/prevwsh2.cxx
@@ -0,0 +1,353 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+// TOOLS
+#define _BIGINT_HXX
+#define _SFXMULTISEL_HXX
+#define _STACK_HXX
+#define _QUEUE_HXX
+#define _DYNARR_HXX
+#define _TREELIST_HXX
+#define _CACHESTR_HXX
+#define _NEW_HXX
+//#define _SHL_HXX
+//#define _LINK_HXX
+//#define _ERRCODE_HXX
+//#define _GEN_HXX
+//#define _FRACT_HXX
+//#define _STRING_HXX
+//#define _MTF_HXX
+//#define _CONTNR_HXX
+//#define _LIST_HXX
+//#define _TABLE_HXX
+#define _DYNARY_HXX
+//#define _UNQIDX_HXX
+#define _SVMEMPOOL_HXX
+//#define _UNQID_HXX
+//#define _DEBUG_HXX
+//#define _DATE_HXX
+//#define _TIME_HXX
+//#define _DATETIME_HXX
+//#define _INTN_HXX
+//#define _WLDCRD_HXX
+//#define _FSYS_HXX
+//#define _STREAM_HXX
+#define _CACHESTR_HXX
+//#define _SV_MULTISEL_HXX
+
+//SV
+//#define _CLIP_HXX ***
+#define _CONFIG_HXX
+#define _CURSOR_HXX
+#define _FONTDLG_HXX
+#define _PRVWIN_HXX
+//#define _COLOR_HXX
+//#define _PAL_HXX
+//#define _BITMAP_HXX
+//#define _GDIOBJ_HXX
+//#define _POINTR_HXX
+//#define _ICON_HXX
+//#define _IMAGE_HXX
+//#define _KEYCOD_HXX
+//#define _EVENT_HXX
+#define _HELP_HXX
+//#define _APP_HXX
+//#define _MDIAPP_HXX
+//#define _TIMER_HXX
+//#define _METRIC_HXX
+//#define _REGION_HXX
+//#define _OUTDEV_HXX
+//#define _SYSTEM_HXX
+//#define _VIRDEV_HXX
+//#define _JOBSET_HXX
+//#define _PRINT_HXX
+//#define _WINDOW_HXX
+//#define _SYSWIN_HXX
+//#define _WRKWIN_HXX
+#define _MDIWIN_HXX
+//#define _FLOATWIN_HXX
+//#define _DOCKWIN_HXX
+//#define _CTRL_HXX
+//#define _SCRBAR_HXX
+//#define _BUTTON_HXX
+//#define _IMAGEBTN_HXX
+//#define _FIXED_HXX
+//#define _GROUP_HXX
+//#define _EDIT_HXX
+//#define _COMBOBOX_HXX
+//#define _LSTBOX_HXX
+//#define _SELENG_HXX ***
+//#define _SPLIT_HXX
+#define _SPIN_HXX
+//#define _FIELD_HXX
+//#define _MOREBTN_HXX ***
+//#define _TOOLBOX_HXX
+//#define _STATUS_HXX ***
+//#define _DIALOG_HXX
+//#define _MSGBOX_HXX
+//#define _SYSDLG_HXX
+//#define _PRNDLG_HXX
+#define _COLDLG_HXX
+//#define _TABDLG_HXX
+//#define _GDIMTF_HXX
+//#define _POLY_HXX
+//#define _ACCEL_HXX
+//#define _GRAPH_HXX
+#define _SOUND_HXX
+
+//svtools
+#define _SCRWIN_HXX
+#define _RULER_HXX
+//#define _TABBAR_HXX
+//#define _VALUESET_HXX
+#define _STDMENU_HXX
+//#define _STDCTRL_HXX
+//#define _CTRLBOX_HXX
+#define _CTRLTOOL_HXX
+#define _EXTATTR_HXX
+#define _FRM3D_HXX
+#define _EXTATTR_HXX
+
+//SVTOOLS
+//#define _SVTREELIST_HXX ***
+#define _FILTER_HXX
+//#define _SVLBOXITM_HXX ***
+//#define _SVTREEBOX_HXX ***
+#define _SVICNVW_HXX
+#define _SVTABBX_HXX
+
+//sfxcore.hxx
+//#define _SFXINIMGR_HXX ***
+//#define _SFXCFGITEM_HXX
+//#define _SFX_PRINTER_HXX
+#define _SFXGENLINK_HXX
+#define _SFXHINTPOST_HXX
+#define _SFXDOCINF_HXX
+#define _SFXLINKHDL_HXX
+//#define _SFX_PROGRESS_HXX
+
+//sfxsh.hxx
+//#define _SFX_SHELL_HXX
+//#define _SFXAPP_HXX
+//#define _SFXDISPATCH_HXX
+//#define _SFXMSG_HXX ***
+//#define _SFXOBJFACE_HXX ***
+//#define _SFXREQUEST_HXX
+#define _SFXMACRO_HXX
+
+// SFX
+//#define _SFXAPPWIN_HXX ***
+#define _SFX_SAVEOPT_HXX
+//#define _SFX_CHILDWIN_HXX
+//#define _SFXCTRLITEM_HXX
+#define _SFXPRNMON_HXX
+#define _INTRO_HXX
+#define _SFXMSGDESCR_HXX
+#define _SFXMSGPOOL_HXX
+#define _SFXFILEDLG_HXX
+#define _PASSWD_HXX
+#define _SFXTBXCTRL_HXX
+#define _SFXSTBITEM_HXX
+#define _SFXMNUITEM_HXX
+#define _SFXIMGMGR_HXX
+#define _SFXTBXMGR_HXX
+#define _SFXSTBMGR_HXX
+#define _SFX_MINFITEM_HXX
+#define _SFXEVENT_HXX
+
+//sfxdoc.hxx
+//#define _SFX_OBJSH_HXX
+//#define _SFX_CLIENTSH_HXX
+//#define _SFXDOCINF_HXX
+//#define _SFX_OBJFAC_HXX
+#define _SFX_DOCFILT_HXX
+//#define _SFXDOCFILE_HXX ***
+//define _VIEWFAC_HXX
+//#define _SFXVIEWFRM_HXX
+//#define _SFXVIEWSH_HXX
+//#define _MDIFRM_HXX ***
+#define _SFX_IPFRM_HXX
+//#define _SFX_INTERNO_HXX
+
+//sfxdlg.hxx
+//#define _SFXTABDLG_HXX
+//#define _BASEDLGS_HXX ***
+#define _SFX_DINFDLG_HXX
+#define _SFXDINFEDT_HXX
+#define _SFX_MGETEMPL_HXX
+#define _SFX_TPLPITEM_HXX
+//#define _SFX_STYLEDLG_HXX
+#define _NEWSTYLE_HXX
+//#define _SFXDOCTEMPL_HXX ***
+//#define _SFXDOCTDLG_HXX ***
+//#define _SFX_TEMPLDLG_HXX ***
+//#define _SFXNEW_HXX ***
+#define _SFXDOCMAN_HXX
+#define _SFXDOCKWIN_HXX
+
+//sfxitems.hxx
+#define _SFX_WHMAP_HXX
+//#define _ARGS_HXX ***
+//#define _SFXPOOLITEM_HXX
+//#define _SFXINTITEM_HXX
+//#define _SFXENUMITEM_HXX
+#define _SFXFLAGITEM_HXX
+//#define _SFXSTRITEM_HXX
+#define _SFXPTITEM_HXX
+#define _SFXRECTITEM_HXX
+//#define _SFXITEMPOOL_HXX
+//#define _SFXITEMSET_HXX
+#define _SFXITEMITER_HXX
+#define _SFX_WHITER_HXX
+#define _SFXPOOLCACH_HXX
+//#define _AEITEM_HXX
+#define _SFXRNGITEM_HXX
+//#define _SFXSLSTITM_HXX
+//#define _SFXSTYLE_HXX
+
+//xout.hxx
+//#define _XENUM_HXX
+//#define _XPOLY_HXX
+//#define _XATTR_HXX
+//#define _XOUTX_HXX
+//#define _XPOOL_HXX
+//#define _XTABLE_HXX
+
+//svdraw.hxx
+#define _SDR_NOITEMS
+#define _SDR_NOTOUCH
+#define _SDR_NOTRANSFORM
+//#define _SDR_NOOBJECTS
+//#define _SDR_NOVIEWS
+#define _SDR_NOTRANSFORM
+#define _SDR_NOVIEWMARKER
+#define _SDR_NODRAGMETHODS
+#define _SDR_NOUNDO
+#define _SDR_NOXOUTDEV
+
+
+//#define SI_NOITEMS
+//#define SI_NODRW
+#define _SI_NOSBXCONTROLS
+//#define _VCATTR_HXX
+#define _VCONT_HXX
+//#define _VCSBX_HXX
+#define _SI_NOOTHERFORMS
+#define _VCTRLS_HXX
+//#define _VCDRWOBJ_HXX
+#define _SI_NOCONTROL
+#define _SETBRW_HXX
+#define _VCBRW_HXX
+#define _SI_NOSBXCONTROLS
+//#define _SIDLL_HXX ***
+
+#define _SVX_DAILDLL_HXX
+#define _SVX_HYPHEN_HXX
+#define _SVX_IMPGRF_HXX
+#define _SVX_OPTITEMS_HXX
+#define _SVX_OPTGERL_HXX
+#define _SVX_OPTSAVE_HXX
+#define _SVX_OPTSPELL_HXX
+#define _SVX_OPTPATH_HXX
+#define _SVX_OPTLINGU_HXX
+#define _SVX_RULER_HXX
+#define _SVX_RULRITEM_HXX
+#define _SVX_SPLWRAP_HXX
+#define _SVX_SPLDLG_HXX
+#define _SVX_THESDLG_HXX
+
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svx/svdmodel.hxx>
+#include <svl/smplhint.hxx>
+
+#include "prevwsh.hxx"
+#include "docsh.hxx"
+#include "preview.hxx"
+#include "hints.hxx"
+#include "sc.hrc"
+
+// STATIC DATA -----------------------------------------------------------
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScPreviewShell::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ sal_Bool bDataChanged = sal_False;
+
+ if (rHint.ISA(SfxSimpleHint))
+ {
+ sal_uLong nSlot = ((const SfxSimpleHint&)rHint).GetId();
+ switch ( nSlot )
+ {
+ case FID_DATACHANGED:
+ case SID_SCPRINTOPTIONS:
+ bDataChanged = sal_True;
+ break;
+ case SC_HINT_DRWLAYER_NEW:
+ {
+ SfxBroadcaster* pDrawBC = pDocShell->GetDocument()->GetDrawBroadcaster();
+ if (pDrawBC)
+ StartListening(*pDrawBC);
+ }
+ break;
+ }
+ }
+ else if (rHint.ISA(ScPaintHint))
+ {
+ if ( ((const ScPaintHint&)rHint).GetPrintFlag() )
+ {
+ sal_uInt16 nParts = ((const ScPaintHint&)rHint).GetParts();
+ if (nParts & ( PAINT_GRID | PAINT_LEFT | PAINT_TOP | PAINT_SIZE ))
+ bDataChanged = sal_True;
+ }
+ }
+ else if (rHint.ISA(SdrHint))
+ {
+ // SdrHints are no longer used for invalidating, thus react on objectchange instead
+ if(HINT_OBJCHG == ((const SdrHint&)rHint).GetKind())
+ bDataChanged = sal_True;
+ }
+
+ if (bDataChanged)
+ pPreview->DataChanged(sal_True);
+}
+
+
+
+
+
diff --git a/sc/source/ui/view/printfun.cxx b/sc/source/ui/view/printfun.cxx
new file mode 100644
index 000000000000..c7cc92246536
--- /dev/null
+++ b/sc/source/ui/view/printfun.cxx
@@ -0,0 +1,3202 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include "printfun.hxx"
+
+#include <svx/svxids.hrc>
+#include <editeng/adjitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <svtools/colorcfg.hxx>
+#include <editeng/editstat.hxx> // EE_CNTRL_RTFSTYLESHEETS
+#include <svx/fmview.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/paperinf.hxx>
+#include <editeng/pbinitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <svx/svdpagv.hxx>
+#include <editeng/ulspitem.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/progress.hxx>
+#include <tools/multisel.hxx>
+#include <sfx2/docfile.hxx>
+#include <tools/urlobj.hxx>
+#include <svx/xoutbmp.hxx>
+
+#include "editutil.hxx"
+#include "docsh.hxx"
+#include "output.hxx"
+#include "viewdata.hxx"
+#include "viewopti.hxx"
+#include "stlpool.hxx"
+#include "pagepar.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "dociter.hxx"
+#include "cell.hxx"
+#include "drawutil.hxx"
+#include "globstr.hrc"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "pagedata.hxx"
+#include "printopt.hxx"
+#include "prevloc.hxx"
+#include "scmod.hxx"
+#include "drwlayer.hxx"
+#include "fillinfo.hxx"
+#include "postit.hxx"
+
+#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()
+#define GET_USHORT(set,which) ((const SfxUInt16Item&)(set)->Get((which))).GetValue()
+#define GET_SHOW(set,which) ( VOBJ_MODE_SHOW == ScVObjMode( ((const ScViewObjectModeItem&)(set)->Get((which))).GetValue()) )
+
+//------------------------------------------------------------------------
+
+ScPageRowEntry::ScPageRowEntry(const ScPageRowEntry& r)
+{
+ nStartRow = r.nStartRow;
+ nEndRow = r.nEndRow;
+ nPagesX = r.nPagesX;
+ if (r.pHidden && nPagesX)
+ {
+ pHidden = new sal_Bool[nPagesX];
+ memcpy( pHidden, r.pHidden, nPagesX * sizeof(sal_Bool) );
+ }
+ else
+ pHidden = NULL;
+}
+
+const ScPageRowEntry& ScPageRowEntry::operator=(const ScPageRowEntry& r)
+{
+ delete[] pHidden;
+
+ nStartRow = r.nStartRow;
+ nEndRow = r.nEndRow;
+ nPagesX = r.nPagesX;
+ if (r.pHidden && nPagesX)
+ {
+ pHidden = new sal_Bool[nPagesX];
+ memcpy( pHidden, r.pHidden, nPagesX * sizeof(sal_Bool) );
+ }
+ else
+ pHidden = NULL;
+
+ return *this;
+}
+
+void ScPageRowEntry::SetPagesX(size_t nNew)
+{
+ if (pHidden)
+ {
+ DBG_ERROR("SetPagesX nicht nach SetHidden");
+ delete[] pHidden;
+ pHidden = NULL;
+ }
+ nPagesX = nNew;
+}
+
+void ScPageRowEntry::SetHidden(size_t nX)
+{
+ if ( nX < nPagesX )
+ {
+ if ( nX+1 == nPagesX ) // letzte Seite?
+ --nPagesX;
+ else
+ {
+ if (!pHidden)
+ {
+ pHidden = new sal_Bool[nPagesX];
+ memset( pHidden, sal_False, nPagesX * sizeof(sal_Bool) );
+ }
+ pHidden[nX] = sal_True;
+ }
+ }
+}
+
+sal_Bool ScPageRowEntry::IsHidden(size_t nX) const
+{
+ return nX>=nPagesX || ( pHidden && pHidden[nX] ); //! inline?
+}
+
+size_t ScPageRowEntry::CountVisible() const
+{
+ if ( pHidden )
+ {
+ size_t nVis = 0;
+ for (size_t i=0; i<nPagesX; i++)
+ if (!pHidden[i])
+ ++nVis;
+ return nVis;
+ }
+ else
+ return nPagesX;
+}
+
+//------------------------------------------------------------------------
+
+long lcl_LineTotal(const SvxBorderLine* pLine)
+{
+ return pLine ? ( pLine->GetOutWidth() + pLine->GetInWidth() + pLine->GetDistance() ) : 0;
+}
+
+void ScPrintFunc::Construct( const ScPrintOptions* pOptions )
+{
+ pDocShell->UpdatePendingRowHeights( nPrintTab );
+ pDoc = pDocShell->GetDocument();
+
+ SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen
+ if (pDocPrinter)
+ aOldPrinterMode = pDocPrinter->GetMapMode();
+
+ // einheitlicher MapMode ueber alle Aufrufe (z.B. Repaint !!!),
+ // weil die EditEngine sonst unterschiedliche Texthoehen liefert
+ pDev->SetMapMode(MAP_PIXEL);
+
+ pPageEndX = NULL;
+ pPageEndY = NULL;
+ pPageRows = NULL;
+ pBorderItem = NULL;
+ pBackgroundItem = NULL;
+ pShadowItem = NULL;
+
+ pEditEngine = NULL;
+ pEditDefaults = NULL;
+
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find(
+ pDoc->GetPageStyle( nPrintTab ),
+ SFX_STYLE_FAMILY_PAGE );
+ if (pStyleSheet)
+ pParamSet = &pStyleSheet->GetItemSet();
+ else
+ {
+ DBG_ERROR("Seitenvorlage nicht gefunden" );
+ pParamSet = NULL;
+ }
+
+ if (!bState)
+ nZoom = 100;
+ nManualZoom = 100;
+ bClearWin = sal_False;
+ bUseStyleColor = sal_False;
+ bIsRender = sal_False;
+
+ InitParam(pOptions);
+
+ pPageData = NULL; // wird nur zur Initialisierung gebraucht
+}
+
+ScPrintFunc::ScPrintFunc( ScDocShell* pShell, SfxPrinter* pNewPrinter, SCTAB nTab,
+ long nPage, long nDocP, const ScRange* pArea,
+ const ScPrintOptions* pOptions,
+ ScPageBreakData* pData )
+ : pDocShell ( pShell ),
+ pPrinter ( pNewPrinter ),
+ pDrawView ( NULL ),
+ nPrintTab ( nTab ),
+ nPageStart ( nPage ),
+ nDocPages ( nDocP ),
+ pUserArea ( pArea ),
+ bState ( sal_False ),
+ bSourceRangeValid ( sal_False ),
+ bPrintCurrentTable ( sal_False ),
+ bMultiArea ( sal_False ),
+ nTabPages ( 0 ),
+ nTotalPages ( 0 ),
+ pPageData ( pData )
+{
+ pDev = pPrinter;
+ aSrcOffset = pPrinter->PixelToLogic( pPrinter->GetPageOffsetPixel(), MAP_100TH_MM );
+ Construct( pOptions );
+}
+
+ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell, SCTAB nTab,
+ long nPage, long nDocP, const ScRange* pArea,
+ const ScPrintOptions* pOptions )
+ : pDocShell ( pShell ),
+ pPrinter ( NULL ),
+ pDrawView ( NULL ),
+ nPrintTab ( nTab ),
+ nPageStart ( nPage ),
+ nDocPages ( nDocP ),
+ pUserArea ( pArea ),
+ bState ( sal_False ),
+ bSourceRangeValid ( sal_False ),
+ bPrintCurrentTable ( sal_False ),
+ bMultiArea ( sal_False ),
+ nTabPages ( 0 ),
+ nTotalPages ( 0 ),
+ pPageData ( NULL )
+{
+ pDev = pOutDev;
+ Construct( pOptions );
+}
+
+ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell,
+ const ScPrintState& rState, const ScPrintOptions* pOptions )
+ : pDocShell ( pShell ),
+ pPrinter ( NULL ),
+ pDrawView ( NULL ),
+ pUserArea ( NULL ),
+ bSourceRangeValid ( sal_False ),
+ bPrintCurrentTable ( sal_False ),
+ bMultiArea ( sal_False ),
+ pPageData ( NULL )
+{
+ pDev = pOutDev;
+
+ nPrintTab = rState.nPrintTab;
+ nStartCol = rState.nStartCol;
+ nStartRow = rState.nStartRow;
+ nEndCol = rState.nEndCol;
+ nEndRow = rState.nEndRow;
+ nZoom = rState.nZoom;
+ nPagesX = rState.nPagesX;
+ nPagesY = rState.nPagesY;
+ nTabPages = rState.nTabPages;
+ nTotalPages = rState.nTotalPages;
+ nPageStart = rState.nPageStart;
+ nDocPages = rState.nDocPages;
+ bState = sal_True;
+
+ Construct( pOptions );
+}
+ScPrintFunc::ScPrintFunc( ScDocShell* pShell, Window* pWindow, SCTAB nTab,
+ long nPage, long nDocP, const ScRange* pArea,
+ const ScPrintOptions* pOptions )
+ : pDocShell ( pShell ),
+ pPrinter ( NULL ),
+ pDrawView ( NULL ),
+ nPrintTab ( nTab ),
+ nPageStart ( nPage ),
+ nDocPages ( nDocP ),
+ pUserArea ( pArea ),
+ bState ( sal_False ),
+ bPrintCurrentTable ( sal_False ),
+ bMultiArea ( sal_False ),
+ nTabPages ( 0 ),
+ nTotalPages ( 0 ),
+ pPageData ( NULL )
+{
+ pDev = pWindow;
+ Construct( pOptions );
+}
+ScPrintFunc::ScPrintFunc( ScDocShell* pShell, Window* pWindow,
+ const ScPrintState& rState, const ScPrintOptions* pOptions )
+ : pDocShell ( pShell ),
+ pPrinter ( NULL ),
+ pDrawView ( NULL ),
+ pUserArea ( NULL ),
+ bPrintCurrentTable ( sal_False ),
+ bMultiArea ( sal_False ),
+ pPageData ( NULL )
+{
+ pDev = pWindow;
+
+ nPrintTab = rState.nPrintTab;
+ nStartCol = rState.nStartCol;
+ nStartRow = rState.nStartRow;
+ nEndCol = rState.nEndCol;
+ nEndRow = rState.nEndRow;
+ nZoom = rState.nZoom;
+ nPagesX = rState.nPagesX;
+ nPagesY = rState.nPagesY;
+ nTabPages = rState.nTabPages;
+ nTotalPages = rState.nTotalPages;
+ nPageStart = rState.nPageStart;
+ nDocPages = rState.nDocPages;
+ bState = sal_True;
+
+ Construct( pOptions );
+}
+
+void ScPrintFunc::GetPrintState( ScPrintState& rState )
+{
+ rState.nPrintTab = nPrintTab;
+ rState.nStartCol = nStartCol;
+ rState.nStartRow = nStartRow;
+ rState.nEndCol = nEndCol;
+ rState.nEndRow = nEndRow;
+ rState.nZoom = nZoom;
+ rState.nPagesX = nPagesX;
+ rState.nPagesY = nPagesY;
+ rState.nTabPages = nTabPages;
+ rState.nTotalPages = nTotalPages;
+ rState.nPageStart = nPageStart;
+ rState.nDocPages = nDocPages;
+}
+
+sal_Bool ScPrintFunc::GetLastSourceRange( ScRange& rRange ) const
+{
+ rRange = aLastSourceRange;
+ return bSourceRangeValid;
+}
+
+void ScPrintFunc::FillPageData()
+{
+ if (pPageData)
+ {
+ sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( pPageData->GetCount() );
+ ScPrintRangeData& rData = pPageData->GetData(nCount); // hochzaehlen
+
+ rData.SetPrintRange( ScRange( nStartCol, nStartRow, nPrintTab,
+ nEndCol, nEndRow, nPrintTab ) );
+ rData.SetPagesX( nPagesX, pPageEndX );
+ rData.SetPagesY( nTotalY, pPageEndY );
+
+ // Einstellungen
+ rData.SetTopDown( aTableParam.bTopDown );
+ rData.SetAutomatic( !aAreaParam.bPrintArea );
+ }
+}
+
+ScPrintFunc::~ScPrintFunc()
+{
+ ScAddress* pTripel = (ScAddress*) aNotePosList.First();
+ while (pTripel)
+ {
+ delete pTripel;
+ pTripel = (ScAddress*) aNotePosList.Next();
+ }
+ aNotePosList.Clear();
+
+ delete[] pPageEndX;
+ delete[] pPageEndY;
+ delete[] pPageRows;
+ delete pEditDefaults;
+ delete pEditEngine;
+
+ // Druckereinstellungen werden jetzt von aussen wiederhergestellt
+
+ // #64294# Fuer DrawingLayer/Charts muss der MapMode am Drucker (RefDevice) immer stimmen
+ SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen
+ if (pDocPrinter)
+ pDocPrinter->SetMapMode(aOldPrinterMode);
+}
+
+void ScPrintFunc::SetDrawView( FmFormView* pNew )
+{
+ pDrawView = pNew;
+}
+
+void lcl_HidePrint( ScTableInfo& rTabInfo, SCCOL nX1, SCCOL nX2 )
+{
+ for (SCSIZE nArrY=1; nArrY+1<rTabInfo.mnArrCount; nArrY++)
+ {
+ RowInfo* pThisRowInfo = &rTabInfo.mpRowInfo[nArrY];
+ for (SCCOL nX=nX1; nX<=nX2; nX++)
+ {
+ const CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nX+1];
+ if (!rCellInfo.bEmptyCellText)
+ if (((const ScProtectionAttr&)rCellInfo.pPatternAttr->
+ GetItem(ATTR_PROTECTION, rCellInfo.pConditionSet)).GetHidePrint())
+ {
+ pThisRowInfo->pCellInfo[nX+1].pCell = NULL;
+ pThisRowInfo->pCellInfo[nX+1].bEmptyCellText = sal_True;
+ }
+ }
+ }
+}
+
+//
+// Ausgabe auf Device (static)
+//
+// wird benutzt fuer:
+// - Clipboard/Bitmap
+// - Ole-Object (DocShell::Draw)
+// - Vorschau bei Vorlagen
+
+void ScPrintFunc::DrawToDev( ScDocument* pDoc, OutputDevice* pDev, double /* nPrintFactor */,
+ const Rectangle& rBound, ScViewData* pViewData, sal_Bool bMetaFile )
+{
+ //! nPrintFactor auswerten !!!
+
+ SCTAB nTab = 0;
+ if (pViewData)
+ nTab = pViewData->GetTabNo();
+
+ sal_Bool bDoGrid, bNullVal, bFormula;
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
+ if (pStyleSheet)
+ {
+ SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ bDoGrid = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_GRID)).GetValue();
+ bNullVal = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_NULLVALS)).GetValue();
+ bFormula = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_FORMULAS)).GetValue();
+ }
+ else
+ {
+ const ScViewOptions& rOpt = pDoc->GetViewOptions();
+ bDoGrid = rOpt.GetOption(VOPT_GRID);
+ bNullVal = rOpt.GetOption(VOPT_NULLVALS);
+ bFormula = rOpt.GetOption(VOPT_FORMULAS);
+ }
+
+ MapMode aMode = pDev->GetMapMode();
+
+ Rectangle aRect = rBound;
+
+ if (aRect.Right() < aRect.Left() || aRect.Bottom() < aRect.Top())
+ aRect = Rectangle( Point(), pDev->GetOutputSize() );
+
+ SCCOL nX1 = 0;
+ SCROW nY1 = 0;
+ SCCOL nX2 = OLE_STD_CELLS_X - 1;
+ SCROW nY2 = OLE_STD_CELLS_Y - 1;
+ if (bMetaFile)
+ {
+ ScRange aRange = pDoc->GetRange( nTab, rBound );
+ nX1 = aRange.aStart.Col();
+ nY1 = aRange.aStart.Row();
+ nX2 = aRange.aEnd.Col();
+ nY2 = aRange.aEnd.Row();
+ }
+ else if (pViewData)
+ {
+ ScSplitPos eWhich = pViewData->GetActivePart();
+ ScHSplitPos eHWhich = WhichH(eWhich);
+ ScVSplitPos eVWhich = WhichV(eWhich);
+ nX1 = pViewData->GetPosX(eHWhich);
+ nY1 = pViewData->GetPosY(eVWhich);
+ nX2 = nX1 + pViewData->VisibleCellsX(eHWhich);
+ if (nX2>nX1) --nX2;
+ nY2 = nY1 + pViewData->VisibleCellsY(eVWhich);
+ if (nY2>nY1) --nY2;
+ }
+
+ if (nX1 > MAXCOL) nX1 = MAXCOL;
+ if (nX2 > MAXCOL) nX2 = MAXCOL;
+ if (nY1 > MAXROW) nY1 = MAXROW;
+ if (nY2 > MAXROW) nY2 = MAXROW;
+
+ long nDevSizeX = aRect.Right()-aRect.Left()+1;
+ long nDevSizeY = aRect.Bottom()-aRect.Top()+1;
+
+ Rectangle aLines;
+ ScRange aRange( nX1,nY1,nTab, nX2,nY2,nTab );
+// sal_Bool bAddLines = pDoc->HasLines( aRange, aLines );
+
+ long nTwipsSizeX = 0;
+ for (SCCOL i=nX1; i<=nX2; i++)
+ nTwipsSizeX += pDoc->GetColWidth( i, nTab );
+ long nTwipsSizeY = (long) pDoc->GetRowHeight( nY1, nY2, nTab );
+
+ // wenn keine Linien, dann trotzdem Platz fuer den Aussenrahmen (20 Twips = 1pt)
+ // (HasLines initalisiert aLines auf 0,0,0,0)
+ nTwipsSizeX += aLines.Left() + Max( aLines.Right(), 20L );
+ nTwipsSizeY += aLines.Top() + Max( aLines.Bottom(), 20L );
+
+ double nScaleX = (double) nDevSizeX / nTwipsSizeX;
+ double nScaleY = (double) nDevSizeY / nTwipsSizeY;
+
+ //! Flag bei FillInfo uebergeben !!!!!
+ ScRange aERange;
+ sal_Bool bEmbed = pDoc->IsEmbedded();
+ if (bEmbed)
+ {
+ pDoc->GetEmbedded(aERange);
+ pDoc->ResetEmbedded();
+ }
+
+ // Daten zusammenstellen
+
+ ScTableInfo aTabInfo;
+ pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab,
+ nScaleX, nScaleY, sal_False, bFormula );
+ lcl_HidePrint( aTabInfo, nX1, nX2 );
+
+ if (bEmbed)
+ pDoc->SetEmbedded(aERange);
+
+/* if (!bMetaFile)
+ pDev->SetMapMode(MAP_PIXEL);
+*/
+ long nScrX = aRect.Left();
+ long nScrY = aRect.Top();
+
+ // Wenn keine Linien, trotzdem Platz fuer Gitterlinien lassen
+ // (werden sonst abgeschnitten)
+ long nAddX = (long)( aLines.Left() * nScaleX );
+ nScrX += ( nAddX ? nAddX : 1 );
+ long nAddY = (long)( aLines.Top() * nScaleY );
+ nScrY += ( nAddY ? nAddY : 1 );
+
+ ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nTab,
+ nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
+ aOutputData.SetMetaFileMode(bMetaFile);
+ aOutputData.SetShowNullValues(bNullVal);
+ aOutputData.SetShowFormulas(bFormula);
+
+ // #114135#
+ ScDrawLayer* pModel = pDoc->GetDrawLayer();
+ FmFormView* pDrawView = NULL;
+
+ if( pModel )
+ {
+ pDrawView = new FmFormView( pModel, pDev );
+ pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
+ pDrawView->SetPrintPreview( sal_True );
+ aOutputData.SetDrawView( pDrawView );
+ }
+
+ //! SetUseStyleColor ??
+
+ if ( bMetaFile && pDev->GetOutDevType() == OUTDEV_VIRDEV )
+ aOutputData.SetSnapPixel();
+
+ Point aLogStart = pDev->PixelToLogic( Point(nScrX,nScrY), MAP_100TH_MM );
+ long nLogStX = aLogStart.X();
+ long nLogStY = aLogStart.Y();
+
+ //! nZoom fuer GetFont in OutputData ???
+
+ if (!bMetaFile && pViewData)
+ pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart()));
+
+ // #i72502#
+ const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
+ aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
+
+ if (!bMetaFile && pViewData)
+ pDev->SetMapMode(aMode);
+
+ aOutputData.DrawBackground();
+
+#ifdef OS2
+ if (bMetaFile && !bDoGrid)
+ {
+ // unter OS2 fuer Metafiles gesamte Flaeche benutzen,
+ // weil sonst die Groesse nicht erkannt wird
+ pDev->SetLineColor();
+ pDev->SetFillColor();
+ pDev->DrawRect( Rectangle( nScrX,nScrY,
+ nScrX+aOutputData.GetScrW(), nScrY+aOutputData.GetScrH() ) );
+ }
+#endif
+
+ aOutputData.DrawShadow();
+ aOutputData.DrawFrame();
+ aOutputData.DrawStrings();
+
+ if (!bMetaFile && pViewData)
+ pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart()));
+
+ aOutputData.DrawEdit(!bMetaFile);
+
+ if (bDoGrid)
+ {
+ if (!bMetaFile && pViewData)
+ pDev->SetMapMode(aMode);
+
+ aOutputData.DrawGrid( sal_True, sal_False ); // keine Seitenumbrueche
+
+ pDev->SetLineColor( COL_BLACK );
+
+ Size aOne = pDev->PixelToLogic( Size(1,1) );
+ if (bMetaFile)
+ aOne = Size(1,1); // compatible with DrawGrid
+ long nRight = nScrX + aOutputData.GetScrW() - aOne.Width();
+ long nBottom = nScrY + aOutputData.GetScrH() - aOne.Height();
+
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ // extra line at the left edge for left-to-right, right for right-to-left
+ if ( bLayoutRTL )
+ pDev->DrawLine( Point(nRight,nScrY), Point(nRight,nBottom) );
+ else
+ pDev->DrawLine( Point(nScrX,nScrY), Point(nScrX,nBottom) );
+ // extra line at the top in both cases
+ pDev->DrawLine( Point(nScrX,nScrY), Point(nRight,nScrY) );
+ }
+
+ // #i72502#
+ aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
+ aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
+ aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
+
+ // #114135#
+ delete pDrawView;
+}
+
+//
+// Drucken
+//
+
+void lcl_FillHFParam( ScPrintHFParam& rParam, const SfxItemSet* pHFSet )
+{
+ // nDistance muss vorher unterschiedlich initalisiert sein
+
+ if ( pHFSet == NULL )
+ {
+ rParam.bEnable = sal_False;
+ rParam.pBorder = NULL;
+ rParam.pBack = NULL;
+ rParam.pShadow = NULL;
+ }
+ else
+ {
+ rParam.bEnable = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_ON)).GetValue();
+ rParam.bDynamic = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_DYNAMIC)).GetValue();
+ rParam.bShared = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_SHARED)).GetValue();
+ rParam.nHeight = ((const SvxSizeItem&) pHFSet->Get(ATTR_PAGE_SIZE)).GetSize().Height();
+ const SvxLRSpaceItem* pHFLR = &(const SvxLRSpaceItem&) pHFSet->Get(ATTR_LRSPACE);
+ long nTmp;
+ nTmp = pHFLR->GetLeft();
+ rParam.nLeft = nTmp < 0 ? 0 : sal_uInt16(nTmp);
+ nTmp = pHFLR->GetRight();
+ rParam.nRight = nTmp < 0 ? 0 : sal_uInt16(nTmp);
+ rParam.pBorder = (const SvxBoxItem*) &pHFSet->Get(ATTR_BORDER);
+ rParam.pBack = (const SvxBrushItem*) &pHFSet->Get(ATTR_BACKGROUND);
+ rParam.pShadow = (const SvxShadowItem*)&pHFSet->Get(ATTR_SHADOW);;
+
+// jetzt doch wieder schon im Dialog:
+// rParam.nHeight += rParam.nDistance; // nicht mehr im Dialog ???
+
+ if (rParam.pBorder)
+ rParam.nHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
+ lcl_LineTotal( rParam.pBorder->GetBottom() );
+
+ rParam.nManHeight = rParam.nHeight;
+ }
+
+ if (!rParam.bEnable)
+ rParam.nHeight = 0;
+}
+
+// bNew = TRUE: benutzten Bereich aus dem Dokument suchen
+// bNew = FALSE: nur ganze Zeilen/Spalten begrenzen
+
+sal_Bool ScPrintFunc::AdjustPrintArea( sal_Bool bNew )
+{
+ SCCOL nOldEndCol = nEndCol; // nur wichtig bei !bNew
+ SCROW nOldEndRow = nEndRow;
+ sal_Bool bChangeCol = sal_True; // bei bNew werden beide angepasst
+ sal_Bool bChangeRow = sal_True;
+
+ sal_Bool bNotes = aTableParam.bNotes;
+ if ( bNew )
+ {
+ nStartCol = 0;
+ nStartRow = 0;
+ if (!pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes ))
+ return sal_False; // nix
+ }
+ else
+ {
+ sal_Bool bFound = sal_True;
+ bChangeCol = ( nStartCol == 0 && nEndCol == MAXCOL );
+ bChangeRow = ( nStartRow == 0 && nEndRow == MAXROW );
+ sal_Bool bForcedChangeRow = sal_False;
+
+ // #i53558# Crop entire column of old row limit to real print area with
+ // some fuzzyness.
+ if (!bChangeRow && nStartRow == 0)
+ {
+ SCROW nPAEndRow;
+ bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nPAEndRow, bNotes );
+ // Say we don't want to print more than ~1000 empty rows, which are
+ // about 14 pages intentionally left blank..
+ const SCROW nFuzzy = 23*42;
+ if (nPAEndRow + nFuzzy < nEndRow)
+ {
+ bForcedChangeRow = sal_True;
+ nEndRow = nPAEndRow;
+ }
+ else
+ bFound = sal_True; // user seems to _want_ to print some empty rows
+ }
+ // TODO: in case we extend the number of columns we may have to do the
+ // same for horizontal cropping.
+
+ if ( bChangeCol && bChangeRow )
+ bFound = pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes );
+ else if ( bChangeCol )
+ bFound = pDoc->GetPrintAreaHor( nPrintTab, nStartRow, nEndRow, nEndCol, bNotes );
+ else if ( bChangeRow )
+ bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nEndRow, bNotes );
+
+ if (!bFound)
+ return sal_False; // leer
+
+ if (bForcedChangeRow)
+ bChangeRow = sal_True;
+ }
+
+ pDoc->ExtendMerge( nStartCol,nStartRow, nEndCol,nEndRow, nPrintTab,
+ sal_False, sal_True ); // kein Refresh, incl. Attrs
+
+ if ( bChangeCol )
+ {
+ OutputDevice* pRefDev = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen
+ pRefDev->SetMapMode( MAP_PIXEL ); // wichtig fuer GetNeededSize
+
+ pDoc->ExtendPrintArea( pRefDev,
+ nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow );
+ // nEndCol wird veraendert
+ }
+
+ if ( nEndCol < MAXCOL && pDoc->HasAttrib(
+ nEndCol,nStartRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_RIGHT ) )
+ ++nEndCol;
+ if ( nEndRow < MAXROW && pDoc->HasAttrib(
+ nStartCol,nEndRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_DOWN ) )
+ ++nEndRow;
+
+ if (!bChangeCol) nEndCol = nOldEndCol;
+ if (!bChangeRow) nEndRow = nOldEndRow;
+
+ return sal_True;
+}
+
+long ScPrintFunc::TextHeight( const EditTextObject* pObject )
+{
+ if (!pObject)
+ return 0;
+
+// pEditEngine->SetPageNo( nTotalPages );
+ pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, sal_False );
+
+ return (long) pEditEngine->GetTextHeight();
+}
+
+// nZoom muss gesetzt sein !!!
+// und der entsprechende Twip-MapMode eingestellt
+
+void ScPrintFunc::UpdateHFHeight( ScPrintHFParam& rParam )
+{
+ DBG_ASSERT( aPageSize.Width(), "UpdateHFHeight ohne aPageSize");
+
+ if (rParam.bEnable && rParam.bDynamic)
+ {
+ // nHeight aus Inhalten berechnen
+
+ MakeEditEngine();
+ long nPaperWidth = ( aPageSize.Width() - nLeftMargin - nRightMargin -
+ rParam.nLeft - rParam.nRight ) * 100 / nZoom;
+ if (rParam.pBorder)
+ nPaperWidth -= ( rParam.pBorder->GetDistance(BOX_LINE_LEFT) +
+ rParam.pBorder->GetDistance(BOX_LINE_RIGHT) +
+ lcl_LineTotal(rParam.pBorder->GetLeft()) +
+ lcl_LineTotal(rParam.pBorder->GetRight()) ) * 100 / nZoom;
+
+ if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
+ nPaperWidth -= ( rParam.pShadow->CalcShadowSpace(SHADOW_LEFT) +
+ rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT) ) * 100L / nZoom;
+
+ pEditEngine->SetPaperSize( Size( nPaperWidth, 10000 ) );
+
+ long nMaxHeight = 0;
+ if ( rParam.pLeft )
+ {
+ nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pLeft->GetLeftArea() ) );
+ nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pLeft->GetCenterArea() ) );
+ nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pLeft->GetRightArea() ) );
+ }
+ if ( rParam.pRight )
+ {
+ nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pRight->GetLeftArea() ) );
+ nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pRight->GetCenterArea() ) );
+ nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pRight->GetRightArea() ) );
+ }
+
+ rParam.nHeight = nMaxHeight + rParam.nDistance;
+ if (rParam.pBorder)
+ rParam.nHeight += rParam.pBorder->GetDistance(BOX_LINE_TOP) +
+ rParam.pBorder->GetDistance(BOX_LINE_BOTTOM) +
+ lcl_LineTotal( rParam.pBorder->GetTop() ) +
+ lcl_LineTotal( rParam.pBorder->GetBottom() );
+ if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
+ rParam.nHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) +
+ rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
+
+ if (rParam.nHeight < rParam.nManHeight)
+ rParam.nHeight = rParam.nManHeight; // eingestelltes Minimum
+ }
+}
+
+void ScPrintFunc::InitParam( const ScPrintOptions* pOptions )
+{
+ if (!pParamSet)
+ return;
+
+ // TabPage "Seite"
+ const SvxLRSpaceItem* pLRItem = (const SvxLRSpaceItem*) &pParamSet->Get( ATTR_LRSPACE );
+ long nTmp;
+ nTmp = pLRItem->GetLeft();
+ nLeftMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp);
+ nTmp = pLRItem->GetRight();
+ nRightMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp);
+ const SvxULSpaceItem* pULItem = (const SvxULSpaceItem*) &pParamSet->Get( ATTR_ULSPACE );
+ nTopMargin = pULItem->GetUpper();
+ nBottomMargin = pULItem->GetLower();
+
+ const SvxPageItem* pPageItem = (const SvxPageItem*) &pParamSet->Get( ATTR_PAGE );
+ nPageUsage = pPageItem->GetPageUsage();
+ bLandscape = pPageItem->IsLandscape();
+ aFieldData.eNumType = pPageItem->GetNumType();
+
+ bCenterHor = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_HORCENTER)).GetValue();
+ bCenterVer = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_VERCENTER)).GetValue();
+
+ aPageSize = ((const SvxSizeItem&) pParamSet->Get(ATTR_PAGE_SIZE)).GetSize();
+ if ( !aPageSize.Width() || !aPageSize.Height() )
+ {
+ DBG_ERROR("PageSize Null ?!?!?");
+ aPageSize = SvxPaperInfo::GetPaperSize( PAPER_A4 );
+ }
+
+ pBorderItem = (const SvxBoxItem*) &pParamSet->Get(ATTR_BORDER);
+ pBackgroundItem = (const SvxBrushItem*) &pParamSet->Get(ATTR_BACKGROUND);
+ pShadowItem = (const SvxShadowItem*) &pParamSet->Get(ATTR_SHADOW);
+
+ // TabPage "Kopfzeile"
+
+ aHdr.pLeft = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_HEADERLEFT); // Inhalt
+ aHdr.pRight = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_HEADERRIGHT);
+
+ const SvxSetItem* pHeaderSetItem;
+ const SfxItemSet* pHeaderSet = NULL;
+ if ( pParamSet->GetItemState( ATTR_PAGE_HEADERSET, sal_False,
+ (const SfxPoolItem**)&pHeaderSetItem ) == SFX_ITEM_SET )
+ {
+ pHeaderSet = &pHeaderSetItem->GetItemSet();
+ // Kopfzeile hat unteren Abstand
+ aHdr.nDistance = ((const SvxULSpaceItem&) pHeaderSet->Get(ATTR_ULSPACE)).GetLower();
+ }
+ lcl_FillHFParam( aHdr, pHeaderSet );
+
+ // TabPage "Fusszeile"
+
+ aFtr.pLeft = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_FOOTERLEFT); // Inhalt
+ aFtr.pRight = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_FOOTERRIGHT);
+
+ const SvxSetItem* pFooterSetItem;
+ const SfxItemSet* pFooterSet = NULL;
+ if ( pParamSet->GetItemState( ATTR_PAGE_FOOTERSET, sal_False,
+ (const SfxPoolItem**)&pFooterSetItem ) == SFX_ITEM_SET )
+ {
+ pFooterSet = &pFooterSetItem->GetItemSet();
+ // Fusszeile hat oberen Abstand
+ aFtr.nDistance = ((const SvxULSpaceItem&) pFooterSet->Get(ATTR_ULSPACE)).GetUpper();
+ }
+ lcl_FillHFParam( aFtr, pFooterSet );
+
+ //------------------------------------------------------
+ // Table-/Area-Params aus einzelnen Items zusammenbauen:
+ //------------------------------------------------------
+ // TabPage "Tabelle"
+
+ const SfxUInt16Item* pScaleItem = NULL;
+ const ScPageScaleToItem* pScaleToItem = NULL;
+ const SfxUInt16Item* pScaleToPagesItem = NULL;
+ SfxItemState eState;
+
+ eState = pParamSet->GetItemState( ATTR_PAGE_SCALE, sal_False,
+ (const SfxPoolItem**)&pScaleItem );
+ if ( SFX_ITEM_DEFAULT == eState )
+ pScaleItem = (const SfxUInt16Item*)
+ &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALE );
+
+ eState = pParamSet->GetItemState( ATTR_PAGE_SCALETO, sal_False,
+ (const SfxPoolItem**)&pScaleToItem );
+ if ( SFX_ITEM_DEFAULT == eState )
+ pScaleToItem = (const ScPageScaleToItem*)
+ &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETO );
+
+ eState = pParamSet->GetItemState( ATTR_PAGE_SCALETOPAGES, sal_False,
+ (const SfxPoolItem**)&pScaleToPagesItem );
+ if ( SFX_ITEM_DEFAULT == eState )
+ pScaleToPagesItem = (const SfxUInt16Item*)
+ &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETOPAGES );
+
+ DBG_ASSERT( pScaleItem && pScaleToItem && pScaleToPagesItem, "Missing ScaleItem! :-/" );
+
+ aTableParam.bCellContent = sal_True;
+ aTableParam.bNotes = GET_BOOL(pParamSet,ATTR_PAGE_NOTES);
+ aTableParam.bGrid = GET_BOOL(pParamSet,ATTR_PAGE_GRID);
+ aTableParam.bHeaders = GET_BOOL(pParamSet,ATTR_PAGE_HEADERS);
+ aTableParam.bFormulas = GET_BOOL(pParamSet,ATTR_PAGE_FORMULAS);
+ aTableParam.bNullVals = GET_BOOL(pParamSet,ATTR_PAGE_NULLVALS);
+ aTableParam.bCharts = GET_SHOW(pParamSet,ATTR_PAGE_CHARTS);
+ aTableParam.bObjects = GET_SHOW(pParamSet,ATTR_PAGE_OBJECTS);
+ aTableParam.bDrawings = GET_SHOW(pParamSet,ATTR_PAGE_DRAWINGS);
+ aTableParam.bTopDown = GET_BOOL(pParamSet,ATTR_PAGE_TOPDOWN);
+ aTableParam.bLeftRight = !aTableParam.bLeftRight;
+ aTableParam.nFirstPageNo = GET_USHORT(pParamSet,ATTR_PAGE_FIRSTPAGENO);
+ if (!aTableParam.nFirstPageNo)
+ aTableParam.nFirstPageNo = (sal_uInt16) nPageStart; // von vorheriger Tabelle
+
+ if ( pScaleItem && pScaleToItem && pScaleToPagesItem )
+ {
+ sal_uInt16 nScaleAll = pScaleItem->GetValue();
+ sal_uInt16 nScaleToPages = pScaleToPagesItem->GetValue();
+
+ aTableParam.bScaleNone = (nScaleAll == 100);
+ aTableParam.bScaleAll = (nScaleAll > 0 );
+ aTableParam.bScaleTo = pScaleToItem->IsValid();
+ aTableParam.bScalePageNum = (nScaleToPages > 0 );
+ aTableParam.nScaleAll = nScaleAll;
+ aTableParam.nScaleWidth = pScaleToItem->GetWidth();
+ aTableParam.nScaleHeight = pScaleToItem->GetHeight();
+ aTableParam.nScalePageNum = nScaleToPages;
+ }
+ else
+ {
+ aTableParam.bScaleNone = sal_True;
+ aTableParam.bScaleAll = sal_False;
+ aTableParam.bScaleTo = sal_False;
+ aTableParam.bScalePageNum = sal_False;
+ aTableParam.nScaleAll = 0;
+ aTableParam.nScaleWidth = 0;
+ aTableParam.nScaleHeight = 0;
+ aTableParam.nScalePageNum = 0;
+ }
+
+ // skip empty pages only if options with that flag are passed
+ aTableParam.bSkipEmpty = pOptions && pOptions->GetSkipEmpty();
+ if ( pPageData )
+ aTableParam.bSkipEmpty = sal_False;
+ // Wenn pPageData gesetzt ist, interessieren fuer die Umbruch-Vorschau
+ // nur die Umbrueche, leere Seiten werden nicht speziell behandelt
+
+ //------------------------------------------------------
+ // TabPage "Bereiche":
+ //------------------------------------------------------
+
+ //! alle PrintAreas der Tabelle durchgehen !!!
+ const ScRange* pPrintArea = pDoc->GetPrintRange( nPrintTab, 0 );
+ const ScRange* pRepeatCol = pDoc->GetRepeatColRange( nPrintTab );
+ const ScRange* pRepeatRow = pDoc->GetRepeatRowRange( nPrintTab );
+
+ // ATTR_PAGE_PRINTTABLES wird ignoriert
+
+ if ( pUserArea ) // UserArea (Selektion) hat Vorrang
+ {
+ bPrintCurrentTable =
+ aAreaParam.bPrintArea = sal_True; // Selektion
+ aAreaParam.aPrintArea = *pUserArea;
+
+ // Die Tabellen-Abfrage ist schon in DocShell::Print, hier immer
+ aAreaParam.aPrintArea.aStart.SetTab(nPrintTab);
+ aAreaParam.aPrintArea.aEnd.SetTab(nPrintTab);
+
+// lcl_LimitRange( aAreaParam.aPrintArea, nPrintTab ); // ganze Zeilen/Spalten...
+ }
+ else if ( pDoc->HasPrintRange() )
+ {
+ if ( pPrintArea ) // mindestens eine gesetzt ?
+ {
+ bPrintCurrentTable =
+ aAreaParam.bPrintArea = sal_True;
+ aAreaParam.aPrintArea = *pPrintArea;
+
+ bMultiArea = ( pDoc->GetPrintRangeCount(nPrintTab) > 1 );
+ }
+ else
+ {
+ // do not print hidden sheets with "Print entire sheet" flag
+ bPrintCurrentTable = pDoc->IsPrintEntireSheet( nPrintTab ) && pDoc->IsVisible( nPrintTab );
+ aAreaParam.bPrintArea = !bPrintCurrentTable; // otherwise the table is always counted
+ }
+ }
+ else
+ {
+ // #74834# don't print hidden tables if there's no print range defined there
+ if ( pDoc->IsVisible( nPrintTab ) )
+ {
+ aAreaParam.bPrintArea = sal_False;
+ bPrintCurrentTable = sal_True;
+ }
+ else
+ {
+ aAreaParam.bPrintArea = sal_True; // otherwise the table is always counted
+ bPrintCurrentTable = sal_False;
+ }
+ }
+
+ if ( pRepeatCol )
+ {
+ aAreaParam.bRepeatCol = sal_True;
+ aAreaParam.aRepeatCol = *pRepeatCol;
+ nRepeatStartCol = pRepeatCol->aStart.Col();
+ nRepeatEndCol = pRepeatCol->aEnd .Col();
+ }
+ else
+ {
+ aAreaParam.bRepeatCol = sal_False;
+ nRepeatStartCol = nRepeatEndCol = SCCOL_REPEAT_NONE;
+ }
+
+ if ( pRepeatRow )
+ {
+ aAreaParam.bRepeatRow = sal_True;
+ aAreaParam.aRepeatRow = *pRepeatRow;
+ nRepeatStartRow = pRepeatRow->aStart.Row();
+ nRepeatEndRow = pRepeatRow->aEnd .Row();
+ }
+ else
+ {
+ aAreaParam.bRepeatRow = sal_False;
+ nRepeatStartRow = nRepeatEndRow = SCROW_REPEAT_NONE;
+ }
+
+ //
+ // Seiten aufteilen
+ //
+
+ if (!bState)
+ {
+ nTabPages = CountPages(); // berechnet auch Zoom
+ nTotalPages = nTabPages;
+ nTotalPages += CountNotePages();
+ }
+ else
+ {
+ CalcPages(); // nur Umbrueche suchen
+ CountNotePages(); // Notizen zaehlen, auch wenn Seitenzahl schon bekannt
+ }
+
+ if (nDocPages)
+ aFieldData.nTotalPages = nDocPages;
+ else
+ aFieldData.nTotalPages = nTotalPages;
+
+ SetDateTime( Date(), Time() );
+
+ aFieldData.aTitle = pDocShell->GetTitle();
+ const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject();
+ aFieldData.aLongDocName = rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
+ if ( aFieldData.aLongDocName.Len() )
+ aFieldData.aShortDocName = rURLObj.GetName( INetURLObject::DECODE_UNAMBIGUOUS );
+ else
+ aFieldData.aShortDocName = aFieldData.aLongDocName = aFieldData.aTitle;
+
+ // Druckereinstellungen (Orientation, Paper) jetzt erst bei DoPrint
+}
+
+Size ScPrintFunc::GetDataSize() const
+{
+ Size aSize = aPageSize;
+ aSize.Width() -= nLeftMargin + nRightMargin;
+ aSize.Height() -= nTopMargin + nBottomMargin;
+ aSize.Height() -= aHdr.nHeight + aFtr.nHeight;
+ return aSize;
+}
+
+void ScPrintFunc::GetScaleData( Size& rPhysSize, long& rDocHdr, long& rDocFtr )
+{
+ rPhysSize = aPageSize;
+ rPhysSize.Width() -= nLeftMargin + nRightMargin;
+ rPhysSize.Height() -= nTopMargin + nBottomMargin;
+
+ rDocHdr = aHdr.nHeight;
+ rDocFtr = aFtr.nHeight;
+}
+
+void ScPrintFunc::SetDateTime( const Date& rDate, const Time& rTime )
+{
+ aFieldData.aDate = rDate;
+ aFieldData.aTime = rTime;
+}
+
+void lcl_DrawGraphic( const Graphic &rGraphic, OutputDevice *pOut,
+ const Rectangle &rGrf, const Rectangle &rOut )
+{
+ const FASTBOOL bNotInside = !rOut.IsInside( rGrf );
+ if ( bNotInside )
+ {
+ pOut->Push();
+ pOut->IntersectClipRegion( rOut );
+ }
+
+ ((Graphic&)rGraphic).Draw( pOut, rGrf.TopLeft(), rGrf.GetSize() );
+
+ if ( bNotInside )
+ pOut->Pop();
+}
+
+void lcl_DrawGraphic( const SvxBrushItem &rBrush, OutputDevice *pOut, OutputDevice* pRefDev,
+ const Rectangle &rOrg, const Rectangle &rOut )
+{
+ Size aGrfSize(0,0);
+ const Graphic *pGraphic = rBrush.GetGraphic();
+ SvxGraphicPosition ePos;
+ if ( pGraphic && pGraphic->IsSupportedGraphic() )
+ {
+ const MapMode aMapMM( MAP_100TH_MM );
+ if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
+ aGrfSize = pRefDev->PixelToLogic( pGraphic->GetPrefSize(), aMapMM );
+ else
+ aGrfSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
+ pGraphic->GetPrefMapMode(), aMapMM );
+ ePos = rBrush.GetGraphicPos();
+ }
+ else
+ ePos = GPOS_NONE;
+
+ Point aPos;
+ Size aDrawSize = aGrfSize;
+
+ FASTBOOL bDraw = sal_True;
+// FASTBOOL bRetouche = sal_True;
+ switch ( ePos )
+ {
+ case GPOS_LT: aPos = rOrg.TopLeft();
+ break;
+ case GPOS_MT: aPos.Y() = rOrg.Top();
+ aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
+ break;
+ case GPOS_RT: aPos.Y() = rOrg.Top();
+ aPos.X() = rOrg.Right() - aGrfSize.Width();
+ break;
+
+ case GPOS_LM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
+ aPos.X() = rOrg.Left();
+ break;
+ case GPOS_MM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
+ aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
+ break;
+ case GPOS_RM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
+ aPos.X() = rOrg.Right() - aGrfSize.Width();
+ break;
+
+ case GPOS_LB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
+ aPos.X() = rOrg.Left();
+ break;
+ case GPOS_MB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
+ aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
+ break;
+ case GPOS_RB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
+ aPos.X() = rOrg.Right() - aGrfSize.Width();
+ break;
+
+ case GPOS_AREA:
+ aPos = rOrg.TopLeft();
+ aDrawSize = rOrg.GetSize();
+// bRetouche = sal_False;
+ break;
+ case GPOS_TILED:
+ {
+ // #104004# use GraphicObject::DrawTiled instead of an own loop
+ // (pixel rounding is handled correctly, and a very small bitmap
+ // is duplicated into a bigger one for better performance)
+
+ GraphicObject aObject( *pGraphic );
+
+ if( pOut->GetPDFWriter() &&
+ (aObject.GetType() == GRAPHIC_BITMAP || aObject.GetType() == GRAPHIC_DEFAULT) )
+ {
+ // #104004# For PDF export, every draw
+ // operation for bitmaps takes a noticeable
+ // amount of place (~50 characters). Thus,
+ // optimize between tile bitmap size and
+ // number of drawing operations here.
+ //
+ // A_out
+ // n_chars = k1 * ---------- + k2 * A_bitmap
+ // A_bitmap
+ //
+ // minimum n_chars is obtained for (derive for
+ // A_bitmap, set to 0, take positive
+ // solution):
+ // k1
+ // A_bitmap = Sqrt( ---- A_out )
+ // k2
+ //
+ // where k1 is the number of chars per draw
+ // operation, and k2 is the number of chars
+ // per bitmap pixel. This is approximately 50
+ // and 7 for current PDF writer, respectively.
+ //
+ const double k1( 50 );
+ const double k2( 7 );
+ const Size aSize( rOrg.GetSize() );
+ const double Abitmap( k1/k2 * aSize.Width()*aSize.Height() );
+
+ aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0),
+ NULL, GRFMGR_DRAW_STANDARD,
+ ::std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) );
+ }
+ else
+ {
+ aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0) );
+ }
+
+ bDraw = sal_False;
+// bRetouche = sal_False;
+ }
+ break;
+
+ case GPOS_NONE:
+ bDraw = sal_False;
+ break;
+
+ default: DBG_ASSERT( !pOut, "new Graphic position?" );
+ }
+ Rectangle aGrf( aPos,aDrawSize );
+ if ( bDraw && aGrf.IsOver( rOut ) )
+ {
+ lcl_DrawGraphic( *pGraphic, pOut, aGrf, rOut );
+ }
+}
+
+// Rahmen wird nach innen gezeichnet
+
+void ScPrintFunc::DrawBorder( long nScrX, long nScrY, long nScrW, long nScrH,
+ const SvxBoxItem* pBorderData, const SvxBrushItem* pBackground,
+ const SvxShadowItem* pShadow )
+{
+ //! direkte Ausgabe aus SvxBoxItem !!!
+
+ if (pBorderData)
+ if ( !pBorderData->GetTop() && !pBorderData->GetBottom() && !pBorderData->GetLeft() &&
+ !pBorderData->GetRight() )
+ pBorderData = NULL;
+
+ if (!pBorderData && !pBackground && !pShadow)
+ return; // nichts zu tun
+
+ long nLeft = 0;
+ long nRight = 0;
+ long nTop = 0;
+ long nBottom = 0;
+
+ // aFrameRect - aussen um die Umrandung, ohne Schatten
+ if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE )
+ {
+ nLeft += (long) ( pShadow->CalcShadowSpace(SHADOW_LEFT) * nScaleX );
+ nRight += (long) ( pShadow->CalcShadowSpace(SHADOW_RIGHT) * nScaleX );
+ nTop += (long) ( pShadow->CalcShadowSpace(SHADOW_TOP) * nScaleY );
+ nBottom += (long) ( pShadow->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY );
+ }
+ Rectangle aFrameRect( Point(nScrX+nLeft, nScrY+nTop),
+ Size(nScrW-nLeft-nRight, nScrH-nTop-nBottom) );
+
+ // Mitte der Umrandung, um Linien ueber OutputData zu zeichnen:
+ if (pBorderData)
+ {
+ nLeft += (long) ( lcl_LineTotal(pBorderData->GetLeft()) * nScaleX / 2 );
+ nRight += (long) ( lcl_LineTotal(pBorderData->GetRight()) * nScaleX / 2 );
+ nTop += (long) ( lcl_LineTotal(pBorderData->GetTop()) * nScaleY / 2 );
+ nBottom += (long) ( lcl_LineTotal(pBorderData->GetBottom()) * nScaleY / 2 );
+ }
+ long nEffHeight = nScrH - nTop - nBottom;
+ long nEffWidth = nScrW - nLeft - nRight;
+ if (nEffHeight<=0 || nEffWidth<=0)
+ return; // leer
+
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
+ sal_Bool bCellContrast = bUseStyleColor &&
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode();
+
+ if ( pBackground && !bCellContrast )
+ {
+// Rectangle aBackRect( Point(nScrX+nLeft, nScrY+nTop), Size(nEffWidth,nEffHeight) );
+ if (pBackground->GetGraphicPos() != GPOS_NONE)
+ {
+ OutputDevice* pRefDev;
+ if ( bIsRender )
+ pRefDev = pDev; // don't use printer for PDF
+ else
+ pRefDev = pDoc->GetPrinter(); // use printer also for preview
+
+ lcl_DrawGraphic( *pBackground, pDev, pRefDev, aFrameRect, aFrameRect );
+ }
+ else
+ {
+ pDev->SetFillColor(pBackground->GetColor());
+ pDev->SetLineColor();
+ pDev->DrawRect(aFrameRect);
+ }
+ }
+
+ if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE )
+ {
+ if ( bCellContrast )
+ pDev->SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+ else
+ pDev->SetFillColor(pShadow->GetColor());
+ pDev->SetLineColor();
+ long nShadowX = (long) ( pShadow->GetWidth() * nScaleX );
+ long nShadowY = (long) ( pShadow->GetWidth() * nScaleY );
+ switch (pShadow->GetLocation())
+ {
+ case SVX_SHADOW_TOPLEFT:
+ pDev->DrawRect( Rectangle(
+ aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
+ aFrameRect.Right()-nShadowX, aFrameRect.Top() ) );
+ pDev->DrawRect( Rectangle(
+ aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
+ aFrameRect.Left(), aFrameRect.Bottom()-nShadowY ) );
+ break;
+ case SVX_SHADOW_TOPRIGHT:
+ pDev->DrawRect( Rectangle(
+ aFrameRect.Left()+nShadowX, aFrameRect.Top()-nShadowY,
+ aFrameRect.Right()+nShadowX, aFrameRect.Top() ) );
+ pDev->DrawRect( Rectangle(
+ aFrameRect.Right(), aFrameRect.Top()-nShadowY,
+ aFrameRect.Right()+nShadowX, aFrameRect.Bottom()-nShadowY ) );
+ break;
+ case SVX_SHADOW_BOTTOMLEFT:
+ pDev->DrawRect( Rectangle(
+ aFrameRect.Left()-nShadowX, aFrameRect.Bottom(),
+ aFrameRect.Right()-nShadowX, aFrameRect.Bottom()+nShadowY ) );
+ pDev->DrawRect( Rectangle(
+ aFrameRect.Left()-nShadowX, aFrameRect.Top()+nShadowY,
+ aFrameRect.Left(), aFrameRect.Bottom()+nShadowY ) );
+ break;
+ case SVX_SHADOW_BOTTOMRIGHT:
+ pDev->DrawRect( Rectangle(
+ aFrameRect.Left()+nShadowX, aFrameRect.Bottom(),
+ aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
+ pDev->DrawRect( Rectangle(
+ aFrameRect.Right(), aFrameRect.Top()+nShadowY,
+ aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+
+ if (pBorderData)
+ {
+ ScDocument* pBorderDoc = new ScDocument( SCDOCMODE_UNDO );
+ pBorderDoc->InitUndo( pDoc, 0,0, sal_True,sal_True );
+ if (pBorderData)
+ pBorderDoc->ApplyAttr( 0,0,0, *pBorderData );
+
+ ScTableInfo aTabInfo;
+ pBorderDoc->FillInfo( aTabInfo, 0,0, 0,0, 0,
+ nScaleX, nScaleY, sal_False, sal_False );
+ DBG_ASSERT(aTabInfo.mnArrCount,"nArrCount == 0");
+
+ aTabInfo.mpRowInfo[1].nHeight = (sal_uInt16) nEffHeight;
+ aTabInfo.mpRowInfo[0].pCellInfo[1].nWidth =
+ aTabInfo.mpRowInfo[1].pCellInfo[1].nWidth = (sal_uInt16) nEffWidth;
+
+ ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pBorderDoc, 0,
+ nScrX+nLeft, nScrY+nTop, 0,0, 0,0, nScaleX, nScaleY );
+ aOutputData.SetUseStyleColor( bUseStyleColor );
+
+// pDev->SetMapMode(aTwipMode);
+
+ if (pBorderData)
+ aOutputData.DrawFrame();
+
+ delete pBorderDoc;
+ }
+}
+
+void ScPrintFunc::PrintColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY )
+{
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ long nOneY = aOnePixel.Height();
+ SCCOL nCol;
+
+ long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
+ long nEndY = nScrY + nHeight - nOneY;
+
+ long nPosX = nScrX;
+ if ( bLayoutRTL )
+ {
+ for (nCol=nX1; nCol<=nX2; nCol++)
+ nPosX += (long)( pDoc->GetColWidth( nCol, nPrintTab ) * nScaleX );
+ }
+ else
+ nPosX -= nOneX;
+ long nPosY = nScrY - nOneY;
+ String aText;
+
+ for (nCol=nX1; nCol<=nX2; nCol++)
+ {
+ sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
+ if (nDocW)
+ {
+ long nWidth = (long) (nDocW * nScaleX);
+ long nEndX = nPosX + nWidth * nLayoutSign;
+
+ pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) );
+
+ aText = ::ScColToAlpha( nCol);
+ long nTextWidth = pDev->GetTextWidth(aText);
+ long nTextHeight = pDev->GetTextHeight();
+ long nAddX = ( nWidth - nTextWidth ) / 2;
+ long nAddY = ( nHeight - nTextHeight ) / 2;
+ long nTextPosX = nPosX+nAddX;
+ if ( bLayoutRTL )
+ nTextPosX -= nWidth;
+ pDev->DrawText( Point( nTextPosX,nPosY+nAddY ), aText );
+
+ nPosX = nEndX;
+ }
+ }
+}
+
+void ScPrintFunc::PrintRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY )
+{
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ long nOneY = aOnePixel.Height();
+
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
+
+ long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
+ long nEndX = nScrX + nWidth;
+ long nPosX = nScrX;
+ if ( !bLayoutRTL )
+ {
+ nEndX -= nOneX;
+ nPosX -= nOneX;
+ }
+ long nPosY = nScrY - nOneY;
+ String aText;
+
+ for (SCROW nRow=nY1; nRow<=nY2; nRow++)
+ {
+ sal_uInt16 nDocH = pDoc->GetRowHeight( nRow, nPrintTab );
+ if (nDocH)
+ {
+ long nHeight = (long) (nDocH * nScaleY);
+ long nEndY = nPosY + nHeight;
+
+ pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) );
+
+ aText = String::CreateFromInt32( nRow+1 );
+ long nTextWidth = pDev->GetTextWidth(aText);
+ long nTextHeight = pDev->GetTextHeight();
+ long nAddX = ( nWidth - nTextWidth ) / 2;
+ long nAddY = ( nHeight - nTextHeight ) / 2;
+ pDev->DrawText( Point( nPosX+nAddX,nPosY+nAddY ), aText );
+
+ nPosY = nEndY;
+ }
+ }
+}
+
+void ScPrintFunc::LocateColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY,
+ sal_Bool bRepCol, ScPreviewLocationData& rLocationData )
+{
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ long nOneY = aOnePixel.Height();
+
+ long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
+ long nEndY = nScrY + nHeight - nOneY;
+
+ long nPosX = nScrX - nOneX;
+ for (SCCOL nCol=nX1; nCol<=nX2; nCol++)
+ {
+ sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
+ if (nDocW)
+ nPosX += (long) (nDocW * nScaleX);
+ }
+ Rectangle aCellRect( nScrX, nScrY, nPosX, nEndY );
+ rLocationData.AddColHeaders( aCellRect, nX1, nX2, bRepCol );
+}
+
+void ScPrintFunc::LocateRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY,
+ sal_Bool bRepRow, ScPreviewLocationData& rLocationData )
+{
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ long nOneY = aOnePixel.Height();
+
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
+
+ long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
+ long nEndX = nScrX + nWidth;
+ if ( !bLayoutRTL )
+ nEndX -= nOneX;
+
+ long nPosY = nScrY - nOneY;
+ nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
+ Rectangle aCellRect( nScrX, nScrY, nEndX, nPosY );
+ rLocationData.AddRowHeaders( aCellRect, nY1, nY2, bRepRow );
+}
+
+void ScPrintFunc::LocateArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
+ long nScrX, long nScrY, sal_Bool bRepCol, sal_Bool bRepRow,
+ ScPreviewLocationData& rLocationData )
+{
+ // get MapMode for drawing objects (same MapMode as in ScOutputData::PrintDrawingLayer)
+
+ Point aLogPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
+ long nLogStX = aLogPos.X();
+ long nLogStY = aLogPos.Y();
+
+ SCCOL nCol;
+ Point aTwipOffset;
+ for (nCol=0; nCol<nX1; nCol++)
+ aTwipOffset.X() -= pDoc->GetColWidth( nCol, nPrintTab );
+ aTwipOffset.Y() -= pDoc->GetRowHeight( 0, nY1-1, nPrintTab );
+
+ Point aMMOffset( aTwipOffset );
+ aMMOffset.X() = (long)(aMMOffset.X() * HMM_PER_TWIPS);
+ aMMOffset.Y() = (long)(aMMOffset.Y() * HMM_PER_TWIPS);
+ aMMOffset += Point( nLogStX, nLogStY );
+ MapMode aDrawMapMode( MAP_100TH_MM, aMMOffset, aLogicMode.GetScaleX(), aLogicMode.GetScaleY() );
+
+ // get pixel rectangle
+
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ long nOneY = aOnePixel.Height();
+
+ long nPosX = nScrX - nOneX;
+ for (nCol=nX1; nCol<=nX2; nCol++)
+ {
+ sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
+ if (nDocW)
+ nPosX += (long) (nDocW * nScaleX);
+ }
+
+ long nPosY = nScrY - nOneY;
+ 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 );
+}
+
+void ScPrintFunc::PrintArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
+ long nScrX, long nScrY,
+ sal_Bool bShLeft, sal_Bool bShTop, sal_Bool bShRight, sal_Bool bShBottom )
+{
+ // #i47547# nothing to do if the end of the print area is before the end of
+ // the repeat columns/rows (don't use negative size for ScOutputData)
+ if ( nX2 < nX1 || nY2 < nY1 )
+ return;
+
+ //! Flag bei FillInfo uebergeben !!!!!
+ ScRange aERange;
+ sal_Bool bEmbed = pDoc->IsEmbedded();
+ if (bEmbed)
+ {
+ pDoc->GetEmbedded(aERange);
+ pDoc->ResetEmbedded();
+ }
+
+ Point aPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
+ long nLogStX = aPos.X();
+ long nLogStY = aPos.Y();
+
+ // Daten zusammenstellen
+
+ ScTableInfo aTabInfo;
+ pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nPrintTab,
+ nScaleX, nScaleY, sal_True, aTableParam.bFormulas );
+ lcl_HidePrint( aTabInfo, nX1, nX2 );
+
+ if (bEmbed)
+ pDoc->SetEmbedded(aERange);
+
+ ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nPrintTab,
+ nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
+
+ // #114135#
+ aOutputData.SetDrawView( pDrawView );
+
+ // test if all paint parts are hidden, then a paint is not necessary at all
+ const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
+ const bool bHideAllDrawingLayer( pDrawView && pDrawView->getHideOle() && pDrawView->getHideChart()
+ && pDrawView->getHideDraw() && pDrawView->getHideFormControl() );
+
+ if(!bHideAllDrawingLayer)
+ {
+ pDev->SetMapMode(aLogicMode);
+ // hier kein Clipping setzen (Mapmode wird verschoben)
+
+ // #i72502#
+ aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
+ }
+
+ pDev->SetMapMode(aOffsetMode);
+
+ aOutputData.SetShowFormulas( aTableParam.bFormulas );
+ aOutputData.SetShowNullValues( aTableParam.bNullVals );
+ aOutputData.SetUseStyleColor( bUseStyleColor );
+
+ Color aGridColor( COL_BLACK );
+ if ( bUseStyleColor )
+ aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+ aOutputData.SetGridColor( aGridColor );
+
+ if ( !pPrinter )
+ {
+ OutputDevice* pRefDev = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen
+ Fraction aPrintFrac( nZoom, 100 ); // ohne nManualZoom
+ // MapMode, wie er beim Drucken herauskommen wuerde:
+ pRefDev->SetMapMode( MapMode( MAP_100TH_MM, Point(), aPrintFrac, aPrintFrac ) );
+
+ // when rendering (PDF), don't use printer as ref device, but printer's MapMode
+ // has to be set anyway, as charts still use it (#106409#)
+ if ( !bIsRender )
+ aOutputData.SetRefDevice( pRefDev );
+ }
+
+// aOutputData.SetMetaFileMode(sal_True);
+ if( aTableParam.bCellContent )
+ aOutputData.DrawBackground();
+
+ pDev->SetClipRegion( Rectangle( aPos, Size( aOutputData.GetScrW(), aOutputData.GetScrH() ) ) );
+ pDev->SetClipRegion();
+
+// aOutputData.SetMetaFileMode(sal_False);
+ if( aTableParam.bCellContent )
+ {
+ aOutputData.DrawExtraShadow( bShLeft, bShTop, bShRight, bShBottom );
+ aOutputData.DrawFrame();
+ aOutputData.DrawStrings();
+
+ // pDev->SetMapMode(aLogicMode);
+ aOutputData.DrawEdit(sal_False);
+ }
+
+// pDev->SetMapMode(aOffsetMode);
+ if (aTableParam.bGrid)
+ aOutputData.DrawGrid( sal_True, sal_False ); // keine Seitenumbrueche
+
+/*!!!!!!!!!!! Notizen in Tabelle markieren ??????????????????????????
+
+ if (aTableParam.bNotes)
+ {
+ pDev->SetMapMode(aOffsetMode);
+ aOutputData.PrintNoteMarks(aNotePosList);
+ pDev->SetMapMode(aLogicMode);
+ }
+*/
+
+ aOutputData.AddPDFNotes(); // has no effect if not rendering PDF with notes enabled
+
+// pDev->SetMapMode(aDrawMode);
+
+ // test if all paint parts are hidden, then a paint is not necessary at all
+ if(!bHideAllDrawingLayer)
+ {
+ // #i72502#
+ aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
+ }
+
+ // #i72502#
+ aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
+ aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
+}
+
+sal_Bool ScPrintFunc::IsMirror( long nPageNo ) // Raender spiegeln ?
+{
+ SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f );
+ return ( eUsage == SVX_PAGE_MIRROR && (nPageNo & 1) );
+}
+
+sal_Bool ScPrintFunc::IsLeft( long nPageNo ) // linke Fussnoten ?
+{
+ SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f );
+ sal_Bool bLeft;
+ if (eUsage == SVX_PAGE_LEFT)
+ bLeft = sal_True;
+ else if (eUsage == SVX_PAGE_RIGHT)
+ bLeft = sal_False;
+ else
+ bLeft = (nPageNo & 1) != 0;
+ return bLeft;
+}
+
+void ScPrintFunc::MakeTableString()
+{
+ pDoc->GetName( nPrintTab, aFieldData.aTabName );
+}
+
+void ScPrintFunc::MakeEditEngine()
+{
+ if (!pEditEngine)
+ {
+ // can't use document's edit engine pool here,
+ // because pool must have twips as default metric
+ pEditEngine = new ScHeaderEditEngine( EditEngine::CreatePool(), sal_True );
+
+ pEditEngine->EnableUndo(sal_False);
+ pEditEngine->SetRefDevice( pDev );
+ pEditEngine->SetWordDelimiters(
+ ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) );
+ pEditEngine->SetControlWord( pEditEngine->GetControlWord() & ~EE_CNTRL_RTFSTYLESHEETS );
+ pEditEngine->EnableAutoColor( bUseStyleColor );
+
+ // Default-Set fuer Ausrichtung
+ pEditDefaults = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
+
+ const ScPatternAttr& rPattern = (const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN);
+ rPattern.FillEditItemSet( pEditDefaults );
+ // FillEditItemSet adjusts font height to 1/100th mm,
+ // but for header/footer twips is needed, as in the PatternAttr:
+ pEditDefaults->Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
+ pEditDefaults->Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
+ pEditDefaults->Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
+ // #69193# dont use font color, because background color is not used
+ //! there's no way to set the background for note pages
+ pEditDefaults->ClearItem( EE_CHAR_COLOR );
+ if (ScGlobal::IsSystemRTL())
+ pEditDefaults->Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
+ }
+
+ pEditEngine->SetData( aFieldData ); // Seitennummer etc. setzen
+}
+
+// nStartY = logic
+void ScPrintFunc::PrintHF( long nPageNo, sal_Bool bHeader, long nStartY,
+ sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
+{
+ const ScPrintHFParam& rParam = bHeader ? aHdr : aFtr;
+
+ pDev->SetMapMode( aTwipMode ); // Kopf-/Fusszeilen in Twips
+
+ sal_Bool bLeft = IsLeft(nPageNo) && !rParam.bShared;
+ const ScPageHFItem* pHFItem = bLeft ? rParam.pLeft : rParam.pRight;
+
+ long nLineStartX = aPageRect.Left() + rParam.nLeft;
+ long nLineEndX = aPageRect.Right() - rParam.nRight;
+ long nLineWidth = nLineEndX - nLineStartX + 1;
+
+ // Edit-Engine
+
+ Point aStart( nLineStartX, nStartY );
+ Size aPaperSize( nLineWidth, rParam.nHeight-rParam.nDistance );
+ if ( rParam.pBorder )
+ {
+ long nLeft = lcl_LineTotal( rParam.pBorder->GetLeft() ) + rParam.pBorder->GetDistance(BOX_LINE_LEFT);
+ long nTop = lcl_LineTotal( rParam.pBorder->GetTop() ) + rParam.pBorder->GetDistance(BOX_LINE_TOP);
+ aStart.X() += nLeft;
+ aStart.Y() += nTop;
+ aPaperSize.Width() -= nLeft + lcl_LineTotal( rParam.pBorder->GetRight() ) + rParam.pBorder->GetDistance(BOX_LINE_RIGHT);
+ aPaperSize.Height() -= nTop + lcl_LineTotal( rParam.pBorder->GetBottom() ) + rParam.pBorder->GetDistance(BOX_LINE_BOTTOM);
+ }
+
+ if ( rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE )
+ {
+ long nLeft = rParam.pShadow->CalcShadowSpace(SHADOW_LEFT);
+ long nTop = rParam.pShadow->CalcShadowSpace(SHADOW_TOP);
+ aStart.X() += nLeft;
+ aStart.Y() += nTop;
+ aPaperSize.Width() -= nLeft + rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT);
+ aPaperSize.Height() -= nTop + rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
+ }
+
+ aFieldData.nPageNo = nPageNo+aTableParam.nFirstPageNo;
+ MakeEditEngine();
+
+ pEditEngine->SetPaperSize(aPaperSize);
+ const EditTextObject* pObject;
+
+ // Rahmen / Hintergrund
+
+ Point aBorderStart( nLineStartX, nStartY );
+ Size aBorderSize( nLineWidth, rParam.nHeight-rParam.nDistance );
+ if ( rParam.bDynamic )
+ {
+ // hier nochmal anpassen, wegen geraden/ungeraden Kopf/Fusszeilen
+ // und evtl. anderen Umbruechen durch Variablen (Seitennummer etc.)
+
+ long nMaxHeight = 0;
+ nMaxHeight = Max( nMaxHeight, TextHeight( pHFItem->GetLeftArea() ) );
+ nMaxHeight = Max( nMaxHeight, TextHeight( pHFItem->GetCenterArea() ) );
+ nMaxHeight = Max( nMaxHeight, TextHeight( pHFItem->GetRightArea() ) );
+ if (rParam.pBorder)
+ nMaxHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
+ lcl_LineTotal( rParam.pBorder->GetBottom() ) +
+ rParam.pBorder->GetDistance(BOX_LINE_TOP) +
+ rParam.pBorder->GetDistance(BOX_LINE_BOTTOM);
+ if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
+ nMaxHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) +
+ rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
+
+ if (nMaxHeight < rParam.nManHeight-rParam.nDistance)
+ nMaxHeight = rParam.nManHeight-rParam.nDistance; // eingestelltes Minimum
+
+ aBorderSize.Height() = nMaxHeight;
+ }
+
+ if ( bDoPrint )
+ {
+ double nOldScaleX = nScaleX;
+ double nOldScaleY = nScaleY;
+ nScaleX = nScaleY = 1.0; // direkt in Twips ausgeben
+ DrawBorder( aBorderStart.X(), aBorderStart.Y(), aBorderSize.Width(), aBorderSize.Height(),
+ rParam.pBorder, rParam.pBack, rParam.pShadow );
+ nScaleX = nOldScaleX;
+ nScaleY = nOldScaleY;
+
+ // Clipping fuer Text
+
+ pDev->SetClipRegion( Rectangle( aStart, aPaperSize ) );
+
+ // links
+
+ pObject = pHFItem->GetLeftArea();
+ if (pObject)
+ {
+ pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
+ pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, sal_False );
+ Point aDraw = aStart;
+ long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
+ if (nDif > 0)
+ aDraw.Y() += nDif / 2;
+ pEditEngine->Draw( pDev, aDraw, 0 );
+ }
+
+ // Mitte
+
+ pObject = pHFItem->GetCenterArea();
+ if (pObject)
+ {
+ pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) );
+ pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, sal_False );
+ Point aDraw = aStart;
+ long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
+ if (nDif > 0)
+ aDraw.Y() += nDif / 2;
+ pEditEngine->Draw( pDev, aDraw, 0 );
+ }
+
+ // rechts
+
+ pObject = pHFItem->GetRightArea();
+ if (pObject)
+ {
+ pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
+ pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, sal_False );
+ Point aDraw = aStart;
+ long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
+ if (nDif > 0)
+ aDraw.Y() += nDif / 2;
+ pEditEngine->Draw( pDev, aDraw, 0 );
+ }
+
+ pDev->SetClipRegion();
+ }
+
+ if ( pLocationData )
+ {
+ Rectangle aHeaderRect( aBorderStart, aBorderSize );
+ pLocationData->AddHeaderFooter( aHeaderRect, bHeader, bLeft );
+ }
+}
+
+long ScPrintFunc::DoNotes( long nNoteStart, sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
+{
+ if (bDoPrint)
+ pDev->SetMapMode(aTwipMode);
+
+ MakeEditEngine();
+ pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
+ pEditEngine->SetDefaults( *pEditDefaults );
+
+ Font aMarkFont;
+ ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT;
+ ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).GetFont( aMarkFont, eColorMode );
+//? aMarkFont.SetWeight( WEIGHT_BOLD );
+ pDev->SetFont( aMarkFont );
+ long nMarkLen = pDev->GetTextWidth(
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("GW99999:")));
+ // ohne Space, weil's eh selten so weit kommt
+
+ Size aDataSize = aPageRect.GetSize();
+ if ( nMarkLen > aDataSize.Width() / 2 ) // alles viel zu klein?
+ nMarkLen = aDataSize.Width() / 2; // Seite bruederlich aufteilen
+ aDataSize.Width() -= nMarkLen;
+
+ pEditEngine->SetPaperSize( aDataSize );
+ long nPosX = aPageRect.Left() + nMarkLen;
+ long nPosY = aPageRect.Top();
+
+ long nCount = 0;
+ sal_Bool bOk;
+ do
+ {
+ bOk = sal_False;
+ ScAddress* pPos = (ScAddress*) aNotePosList.GetObject( nNoteStart+nCount );
+ if (pPos)
+ {
+ ScBaseCell* pCell = pDoc->GetCell( *pPos);
+ if( const ScPostIt* pNote = pCell->GetNote() )
+ {
+ if(const EditTextObject *pEditText = pNote->GetEditTextObject())
+ pEditEngine->SetText(*pEditText);
+ long nTextHeight = pEditEngine->GetTextHeight();
+ if ( nPosY + nTextHeight < aPageRect.Bottom() )
+ {
+ if (bDoPrint)
+ {
+ pEditEngine->Draw( pDev, Point( nPosX, nPosY ), 0 );
+
+ String aMarkStr;
+ pPos->Format( aMarkStr, SCA_VALID, pDoc, pDoc->GetAddressConvention() );
+ aMarkStr += ':';
+
+ // Zellposition auch per EditEngine, damit die Position stimmt
+ pEditEngine->SetText(aMarkStr);
+ pEditEngine->Draw( pDev, Point( aPageRect.Left(), nPosY ), 0 );
+ }
+
+ if ( pLocationData )
+ {
+ Rectangle aTextRect( Point( nPosX, nPosY ), Size( aDataSize.Width(), nTextHeight ) );
+ pLocationData->AddNoteText( aTextRect, *pPos );
+ Rectangle aMarkRect( Point( aPageRect.Left(), nPosY ), Size( nMarkLen, nTextHeight ) );
+ pLocationData->AddNoteMark( aMarkRect, *pPos );
+ }
+
+ nPosY += nTextHeight;
+ nPosY += 200; // Abstand
+ ++nCount;
+ bOk = sal_True;
+ }
+ }
+ }
+ }
+ while (bOk);
+
+ return nCount;
+}
+
+long ScPrintFunc::PrintNotes( long nPageNo, long nNoteStart, sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
+{
+ if ( nNoteStart >= (long) aNotePosList.Count() || !aTableParam.bNotes )
+ return 0;
+
+ if ( bDoPrint && bClearWin )
+ {
+ //! mit PrintPage zusammenfassen !!!
+
+ Color aBackgroundColor( COL_WHITE );
+ if ( bUseStyleColor )
+ aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
+
+ pDev->SetMapMode(aOffsetMode);
+ pDev->SetLineColor();
+ pDev->SetFillColor(aBackgroundColor);
+ pDev->DrawRect(Rectangle(Point(),
+ Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom),
+ (long)(aPageSize.Height() * nScaleY * 100 / nZoom))));
+ }
+
+
+ // aPageRect auf linke / rechte Seiten anpassen
+
+ Rectangle aTempRect = Rectangle( Point(), aPageSize );
+ if (IsMirror(nPageNo))
+ {
+ aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom;
+ aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom;
+ }
+ else
+ {
+ aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom;
+ aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom;
+ }
+
+ if ( pPrinter && bDoPrint )
+ {
+ DBG_ERROR( "StartPage does not exist anymore" );
+ // pPrinter->StartPage();
+ }
+
+ if ( bDoPrint || pLocationData )
+ {
+ // Kopf- und Fusszeilen
+
+ if (aHdr.bEnable)
+ {
+ long nHeaderY = aPageRect.Top()-aHdr.nHeight;
+ PrintHF( nPageNo, sal_True, nHeaderY, bDoPrint, pLocationData );
+ }
+ if (aFtr.bEnable)
+ {
+ long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
+ PrintHF( nPageNo, sal_False, nFooterY, bDoPrint, pLocationData );
+ }
+ }
+
+ long nCount = DoNotes( nNoteStart, bDoPrint, pLocationData );
+
+ if ( pPrinter && bDoPrint )
+ {
+ DBG_ERROR( "EndPage does not exist anymore" );
+ // pPrinter->EndPage();
+ }
+
+ return nCount;
+}
+
+void ScPrintFunc::PrintPage( long nPageNo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
+ sal_Bool bDoPrint, ScPreviewLocationData* pLocationData )
+{
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ // nPageNo is the page number within all sheets of one "start page" setting
+
+ if ( bClearWin && bDoPrint )
+ {
+ // muss genau zum Zeichnen des Rahmens in preview.cxx passen !!!
+
+ Color aBackgroundColor( COL_WHITE );
+ if ( bUseStyleColor )
+ aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
+
+ pDev->SetMapMode(aOffsetMode);
+ pDev->SetLineColor();
+ pDev->SetFillColor(aBackgroundColor);
+ pDev->DrawRect(Rectangle(Point(),
+ Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom),
+ (long)(aPageSize.Height() * nScaleY * 100 / nZoom))));
+ }
+
+
+ // aPageRect auf linke / rechte Seiten anpassen
+
+ Rectangle aTempRect = Rectangle( Point(), aPageSize );
+ if (IsMirror(nPageNo))
+ {
+ aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom;
+ aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom;
+ }
+ else
+ {
+ aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom;
+ aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom;
+ }
+
+ if ( aAreaParam.bRepeatCol )
+ if ( nX1 > nRepeatStartCol && nX1 <= nRepeatEndCol )
+ nX1 = nRepeatEndCol + 1;
+ sal_Bool bDoRepCol = (aAreaParam.bRepeatCol && nX1 > nRepeatEndCol);
+ if ( aAreaParam.bRepeatRow )
+ if ( nY1 > nRepeatStartRow && nY1 <= nRepeatEndRow )
+ nY1 = nRepeatEndRow + 1;
+ sal_Bool bDoRepRow = (aAreaParam.bRepeatRow && nY1 > nRepeatEndRow);
+
+ // use new object hide flags in SdrPaintView
+ if(pDrawView)
+ {
+ pDrawView->setHideOle(!aTableParam.bObjects);
+ pDrawView->setHideChart(!aTableParam.bCharts);
+ pDrawView->setHideDraw(!aTableParam.bDrawings);
+ pDrawView->setHideFormControl(!aTableParam.bDrawings);
+ }
+
+ if ( pPrinter && bDoPrint )
+ {
+ DBG_ERROR( "StartPage does not exist anymore" );
+ // pPrinter->StartPage();
+ }
+
+ // Kopf- und Fusszeilen (ohne Zentrierung)
+
+ if (aHdr.bEnable)
+ {
+ long nHeaderY = aPageRect.Top()-aHdr.nHeight;
+ PrintHF( nPageNo, sal_True, nHeaderY, bDoPrint, pLocationData );
+ }
+ if (aFtr.bEnable)
+ {
+ long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
+ PrintHF( nPageNo, sal_False, nFooterY, bDoPrint, pLocationData );
+ }
+
+ // Position ( Raender / zentrieren )
+
+ long nLeftSpace = aPageRect.Left(); // Document-Twips
+ long nTopSpace = aPageRect.Top();
+ if ( bCenterHor || bLayoutRTL )
+ {
+ long nDataWidth = 0;
+ SCCOL i;
+ for (i=nX1; i<=nX2; i++)
+ nDataWidth += pDoc->GetColWidth( i,nPrintTab );
+ if (bDoRepCol)
+ for (i=nRepeatStartCol; i<=nRepeatEndCol; i++)
+ nDataWidth += pDoc->GetColWidth( i,nPrintTab );
+ if (aTableParam.bHeaders)
+ nDataWidth += (long) PRINT_HEADER_WIDTH;
+ if (pBorderItem)
+ nDataWidth += pBorderItem->GetDistance(BOX_LINE_LEFT) +
+ pBorderItem->GetDistance(BOX_LINE_RIGHT); //! Line width?
+ if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
+ nDataWidth += pShadowItem->CalcShadowSpace(SHADOW_LEFT) +
+ pShadowItem->CalcShadowSpace(SHADOW_RIGHT);
+ if ( bCenterHor )
+ {
+ nLeftSpace += ( aPageRect.GetWidth() - nDataWidth ) / 2; // LTR or RTL
+ if (pBorderItem)
+ nLeftSpace -= lcl_LineTotal(pBorderItem->GetLeft());
+ }
+ else if ( bLayoutRTL )
+ nLeftSpace += aPageRect.GetWidth() - nDataWidth; // align to the right edge of the page
+ }
+ if ( bCenterVer )
+ {
+ long nDataHeight = pDoc->GetRowHeight( nY1, nY2, nPrintTab);
+ if (bDoRepRow)
+ nDataHeight += pDoc->GetRowHeight( nRepeatStartRow,
+ nRepeatEndRow, nPrintTab);
+ if (aTableParam.bHeaders)
+ nDataHeight += (long) PRINT_HEADER_HEIGHT;
+ if (pBorderItem)
+ nDataHeight += pBorderItem->GetDistance(BOX_LINE_TOP) +
+ pBorderItem->GetDistance(BOX_LINE_BOTTOM); //! Line width?
+ if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
+ nDataHeight += pShadowItem->CalcShadowSpace(SHADOW_TOP) +
+ pShadowItem->CalcShadowSpace(SHADOW_BOTTOM);
+ nTopSpace += ( aPageRect.GetHeight() - nDataHeight ) / 2;
+ if (pBorderItem)
+ nTopSpace -= lcl_LineTotal(pBorderItem->GetTop());
+ }
+
+ // calculate sizes of the elements for partitioning
+ // (header, repeat, data)
+
+ long nHeaderWidth = 0;
+ long nHeaderHeight = 0;
+ long nRepeatWidth = 0;
+ long nRepeatHeight = 0;
+ long nContentWidth = 0; // scaled - not the same as nDataWidth above
+ long nContentHeight = 0;
+ if (aTableParam.bHeaders)
+ {
+ nHeaderWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
+ nHeaderHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
+ }
+ if (bDoRepCol)
+ for (SCCOL i=nRepeatStartCol; i<=nRepeatEndCol; i++)
+ nRepeatWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX);
+ if (bDoRepRow)
+ nRepeatHeight += pDoc->GetScaledRowHeight( nRepeatStartRow,
+ nRepeatEndRow, nPrintTab, nScaleY);
+ for (SCCOL i=nX1; i<=nX2; i++)
+ nContentWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX);
+ nContentHeight += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab,
+ nScaleY);
+
+ // partition the page
+
+ long nStartX = ((long) ( nLeftSpace * nScaleX ));
+ long nStartY = ((long) ( nTopSpace * nScaleY ));
+// nStartX -= aOffset.X(); // schon im MapMode
+// nStartY -= aOffset.Y();
+
+ long nInnerStartX = nStartX;
+ long nInnerStartY = nStartY;
+ if (pBorderItem)
+ {
+ nInnerStartX += (long) ( ( lcl_LineTotal(pBorderItem->GetLeft()) +
+ pBorderItem->GetDistance(BOX_LINE_LEFT) ) * nScaleX );
+ nInnerStartY += (long) ( ( lcl_LineTotal(pBorderItem->GetTop()) +
+ pBorderItem->GetDistance(BOX_LINE_TOP) ) * nScaleY );
+ }
+ if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
+ {
+ nInnerStartX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_LEFT) * nScaleX );
+ nInnerStartY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_TOP) * nScaleY );
+ }
+
+ if ( bLayoutRTL )
+ {
+ // arrange elements starting from the right edge
+ nInnerStartX += nHeaderWidth + nRepeatWidth + nContentWidth;
+
+ // make rounding easier so the elements are really next to each other in preview
+ Size aOffsetOnePixel = pDev->PixelToLogic( Size(1,1), aOffsetMode );
+ long nOffsetOneX = aOffsetOnePixel.Width();
+ nInnerStartX += nOffsetOneX / 2;
+ }
+
+ long nFrameStartX = nInnerStartX;
+ long nFrameStartY = nInnerStartY;
+
+ long nRepStartX = nInnerStartX + nHeaderWidth * nLayoutSign; // widths/heights are 0 if not used
+ long nRepStartY = nInnerStartY + nHeaderHeight;
+ long nDataX = nRepStartX + nRepeatWidth * nLayoutSign;
+ long nDataY = nRepStartY + nRepeatHeight;
+ long nEndX = nDataX + nContentWidth * nLayoutSign;
+ long nEndY = nDataY + nContentHeight;
+ long nFrameEndX = nEndX;
+ long nFrameEndY = nEndY;
+
+ if ( bLayoutRTL )
+ {
+ // each element's start position is its left edge
+ //! subtract one pixel less?
+ nInnerStartX -= nHeaderWidth; // used for header
+ nRepStartX -= nRepeatWidth;
+ nDataX -= nContentWidth;
+
+ // continue right of the main elements again
+ nEndX += nHeaderWidth + nRepeatWidth + nContentWidth;
+ }
+
+ // Seiten-Rahmen / Hintergrund
+
+ //! nEndX/Y anpassen
+
+ long nBorderEndX = nEndX;
+ long nBorderEndY = nEndY;
+ if (pBorderItem)
+ {
+ nBorderEndX += (long) ( ( lcl_LineTotal(pBorderItem->GetRight()) +
+ pBorderItem->GetDistance(BOX_LINE_RIGHT) ) * nScaleX );
+ nBorderEndY += (long) ( ( lcl_LineTotal(pBorderItem->GetBottom()) +
+ pBorderItem->GetDistance(BOX_LINE_BOTTOM) ) * nScaleY );
+ }
+ if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
+ {
+ nBorderEndX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_RIGHT) * nScaleX );
+ nBorderEndY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY );
+ }
+
+ if ( bDoPrint )
+ {
+ pDev->SetMapMode( aOffsetMode );
+ DrawBorder( nStartX, nStartY, nBorderEndX-nStartX, nBorderEndY-nStartY,
+ pBorderItem, pBackgroundItem, pShadowItem );
+
+ pDev->SetMapMode( aTwipMode );
+ }
+
+ pDev->SetMapMode( aOffsetMode );
+
+ // Wiederholungszeilen/Spalten ausgeben
+
+ if (bDoRepCol && bDoRepRow)
+ {
+ if ( bDoPrint )
+ PrintArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
+ nRepStartX,nRepStartY, sal_True,sal_True,sal_False,sal_False );
+ if ( pLocationData )
+ LocateArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
+ nRepStartX,nRepStartY, sal_True,sal_True, *pLocationData );
+ }
+ if (bDoRepCol)
+ {
+ if ( bDoPrint )
+ PrintArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY,
+ sal_True,!bDoRepRow,sal_False,sal_True );
+ if ( pLocationData )
+ LocateArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY, sal_True,sal_False, *pLocationData );
+ }
+ if (bDoRepRow)
+ {
+ if ( bDoPrint )
+ PrintArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY,
+ !bDoRepCol,sal_True,sal_True,sal_False );
+ if ( pLocationData )
+ LocateArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY, sal_False,sal_True, *pLocationData );
+ }
+
+ // Daten ausgeben
+
+ if ( bDoPrint )
+ PrintArea( nX1,nY1, nX2,nY2, nDataX,nDataY, !bDoRepCol,!bDoRepRow,sal_True,sal_True );
+ if ( pLocationData )
+ LocateArea( nX1,nY1, nX2,nY2, nDataX,nDataY, sal_False,sal_False, *pLocationData );
+
+ // Spalten-/Zeilenkoepfe ausgeben
+ // nach den Daten (ueber evtl. weitergezeichneten Schatten)
+
+ Color aGridColor( COL_BLACK );
+ if ( bUseStyleColor )
+ aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+
+ if (aTableParam.bHeaders)
+ {
+ if ( bDoPrint )
+ {
+ pDev->SetLineColor( aGridColor );
+ pDev->SetFillColor();
+ pDev->SetMapMode(aOffsetMode);
+ }
+
+ ScPatternAttr aPattern( pDoc->GetPool() );
+ Font aFont;
+ ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT;
+ aPattern.GetFont( aFont, eColorMode, pDev );
+ pDev->SetFont( aFont );
+
+ if (bDoRepCol)
+ {
+ if ( bDoPrint )
+ PrintColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY );
+ if ( pLocationData )
+ LocateColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY, sal_True, *pLocationData );
+ }
+ if ( bDoPrint )
+ PrintColHdr( nX1,nX2, nDataX,nInnerStartY );
+ if ( pLocationData )
+ LocateColHdr( nX1,nX2, nDataX,nInnerStartY, sal_False, *pLocationData );
+ if (bDoRepRow)
+ {
+ if ( bDoPrint )
+ PrintRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY );
+ if ( pLocationData )
+ LocateRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY, sal_True, *pLocationData );
+ }
+ if ( bDoPrint )
+ PrintRowHdr( nY1,nY2, nInnerStartX,nDataY );
+ if ( pLocationData )
+ LocateRowHdr( nY1,nY2, nInnerStartX,nDataY, sal_False, *pLocationData );
+ }
+
+ // einfacher Rahmen
+
+ if ( bDoPrint && ( aTableParam.bGrid || aTableParam.bHeaders ) )
+ {
+ Size aOnePixel = pDev->PixelToLogic(Size(1,1));
+ long nOneX = aOnePixel.Width();
+ long nOneY = aOnePixel.Height();
+
+ long nLeftX = nFrameStartX;
+ long nTopY = nFrameStartY - nOneY;
+ long nRightX = nFrameEndX;
+ long nBottomY = nFrameEndY - nOneY;
+ if ( !bLayoutRTL )
+ {
+ nLeftX -= nOneX;
+ nRightX -= nOneX;
+ }
+ pDev->SetMapMode(aOffsetMode);
+ pDev->SetLineColor( aGridColor );
+ pDev->SetFillColor();
+ pDev->DrawRect( Rectangle( nLeftX, nTopY, nRightX, nBottomY ) );
+ // nEndX/Y ohne Rahmen-Anpassung
+ }
+
+ if ( pPrinter && bDoPrint )
+ {
+ DBG_ERROR( "EndPage does not exist anymore" );
+ // pPrinter->EndPage();
+ }
+
+ aLastSourceRange = ScRange( nX1, nY1, nPrintTab, nX2, nY2, nPrintTab );
+ bSourceRangeValid = sal_True;
+}
+
+void ScPrintFunc::SetOffset( const Point& rOfs )
+{
+ aSrcOffset = rOfs;
+}
+
+void ScPrintFunc::SetManualZoom( sal_uInt16 nNewZoom )
+{
+ nManualZoom = nNewZoom;
+}
+
+void ScPrintFunc::SetClearFlag( sal_Bool bFlag )
+{
+ bClearWin = bFlag;
+}
+
+void ScPrintFunc::SetUseStyleColor( sal_Bool bFlag )
+{
+ bUseStyleColor = bFlag;
+ if (pEditEngine)
+ pEditEngine->EnableAutoColor( bUseStyleColor );
+}
+
+void ScPrintFunc::SetRenderFlag( sal_Bool bFlag )
+{
+ bIsRender = bFlag; // set when using XRenderable (PDF)
+}
+
+void ScPrintFunc::SetExclusivelyDrawOleAndDrawObjects()
+{
+ aTableParam.bCellContent = false;
+ aTableParam.bNotes = false;
+ aTableParam.bGrid = false;
+ aTableParam.bHeaders = false;
+ aTableParam.bFormulas = false;;
+ aTableParam.bNullVals = false;;
+ aTableParam.bNullVals = false;;
+}
+
+//
+// UpdatePages wird nur von aussen gerufen, um die Umbrueche fuer die Anzeige
+// richtig zu setzen - immer ohne UserArea
+//
+
+sal_Bool ScPrintFunc::UpdatePages()
+{
+ if (!pParamSet)
+ return sal_False;
+
+ // Zoom
+
+ nZoom = 100;
+ if (aTableParam.bScalePageNum || aTableParam.bScaleTo)
+ nZoom = ZOOM_MIN; // stimmt fuer Umbrueche
+ else if (aTableParam.bScaleAll)
+ {
+ nZoom = aTableParam.nScaleAll;
+ if ( nZoom <= ZOOM_MIN )
+ nZoom = ZOOM_MIN;
+ }
+
+ String aName = pDoc->GetPageStyle( nPrintTab );
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if ( nTab==nPrintTab || pDoc->GetPageStyle(nTab)==aName )
+ {
+ // Wiederholungszeilen / Spalten
+ pDoc->SetRepeatArea( nTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );
+
+ // Umbrueche setzen
+ ResetBreaks(nTab);
+ pDocShell->PostPaint(0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID);
+ }
+
+ return sal_True;
+}
+
+long ScPrintFunc::CountPages() // setzt auch nPagesX, nPagesY
+{
+ sal_Bool bAreaOk = sal_False;
+
+ if (pDoc->HasTable( nPrintTab ))
+ {
+ if (aAreaParam.bPrintArea) // Druckbereich angegeben?
+ {
+ if ( bPrintCurrentTable )
+ {
+ ScRange& rRange = aAreaParam.aPrintArea;
+
+ // hier kein Vergleich der Tabellen mehr, die Area gilt immer fuer diese Tabelle
+ // wenn hier verglichen werden soll, muss die Tabelle der Druckbereiche beim
+ // Einfuegen von Tabellen etc. angepasst werden !
+
+ nStartCol = rRange.aStart.Col();
+ nStartRow = rRange.aStart.Row();
+ nEndCol = rRange.aEnd .Col();
+ nEndRow = rRange.aEnd .Row();
+ bAreaOk = AdjustPrintArea(sal_False); // begrenzen
+ }
+ else
+ bAreaOk = sal_False;
+ }
+ else // aus Dokument suchen
+ bAreaOk = AdjustPrintArea(sal_True);
+ }
+
+ if (bAreaOk)
+ {
+ long nPages = 0;
+ size_t nY;
+ if (bMultiArea)
+ {
+ sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab );
+ for (sal_uInt16 i=0; i<nRCount; i++)
+ {
+ CalcZoom(i);
+ if ( aTableParam.bSkipEmpty )
+ for (nY=0; nY<nPagesY; nY++)
+ nPages += pPageRows[nY].CountVisible();
+ else
+ nPages += ((long) nPagesX) * nPagesY;
+ if ( pPageData )
+ FillPageData();
+ }
+ }
+ else
+ {
+ CalcZoom(RANGENO_NORANGE); // Zoom berechnen
+ if ( aTableParam.bSkipEmpty )
+ for (nY=0; nY<nPagesY; nY++)
+ nPages += pPageRows[nY].CountVisible();
+ else
+ nPages += ((long) nPagesX) * nPagesY;
+ if ( pPageData )
+ FillPageData();
+ }
+ return nPages;
+ }
+ else
+ {
+// nZoom = 100; // nZoom auf letztem Wert stehenlassen !!!
+ nPagesX = nPagesY = nTotalY = 0;
+ return 0;
+ }
+}
+
+long ScPrintFunc::CountNotePages()
+{
+ if ( !aTableParam.bNotes || !bPrintCurrentTable )
+ return 0;
+
+ long nCount=0;
+ SCCOL nCol;
+ SCROW nRow;
+
+ sal_Bool bError = sal_False;
+ if (!aAreaParam.bPrintArea)
+ bError = !AdjustPrintArea(sal_True); // komplett aus Dok suchen
+
+ sal_uInt16 nRepeats = 1; // wie oft durchgehen ?
+ if (bMultiArea)
+ nRepeats = pDoc->GetPrintRangeCount(nPrintTab);
+ if (bError)
+ nRepeats = 0;
+
+ for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++)
+ {
+ sal_Bool bDoThis = sal_True;
+ if (bMultiArea) // alle Areas durchgehen
+ {
+ const ScRange* pThisRange = pDoc->GetPrintRange( nPrintTab, nStep );
+ if ( pThisRange )
+ {
+ nStartCol = pThisRange->aStart.Col();
+ nStartRow = pThisRange->aStart.Row();
+ nEndCol = pThisRange->aEnd .Col();
+ nEndRow = pThisRange->aEnd .Row();
+ bDoThis = AdjustPrintArea(sal_False);
+ }
+ }
+
+ if (bDoThis)
+ {
+ ScHorizontalCellIterator aIter( pDoc, nPrintTab, nStartCol,nStartRow, nEndCol,nEndRow );
+ ScBaseCell* pCell = aIter.GetNext( nCol, nRow );
+ while (pCell)
+ {
+ if (pCell->HasNote())
+ {
+ aNotePosList.Insert( new ScAddress( nCol,nRow,nPrintTab ), LIST_APPEND );
+ ++nCount;
+ }
+
+ pCell = aIter.GetNext( nCol, nRow );
+ }
+ }
+ }
+
+ long nPages = 0;
+ long nNoteNr = 0;
+ long nNoteAdd;
+ do
+ {
+ nNoteAdd = PrintNotes( nPages, nNoteNr, sal_False, NULL );
+ if (nNoteAdd)
+ {
+ nNoteNr += nNoteAdd;
+ ++nPages;
+ }
+ }
+ while (nNoteAdd);
+
+ return nPages;
+}
+
+void ScPrintFunc::InitModes() // aus nZoom etc. die MapModes setzen
+{
+ aOffset = Point( aSrcOffset.X()*100/nZoom, aSrcOffset.Y()*100/nZoom );
+
+ long nEffZoom = nZoom * (long) nManualZoom;
+
+// nScaleX = nScaleY = 1.0; // Ausgabe in Twips
+ nScaleX = nScaleY = HMM_PER_TWIPS; // Ausgabe in 1/100 mm
+
+ Fraction aZoomFract( nEffZoom,10000 );
+ Fraction aHorFract = aZoomFract;
+
+ if ( !pPrinter && !bIsRender ) // adjust scale for preview
+ {
+ double nFact = pDocShell->GetOutputFactor();
+ aHorFract = Fraction( (long)( nEffZoom / nFact ), 10000 );
+ }
+
+ aLogicMode = MapMode( MAP_100TH_MM, Point(), aHorFract, aZoomFract );
+
+ Point aLogicOfs( -aOffset.X(), -aOffset.Y() );
+ aOffsetMode = MapMode( MAP_100TH_MM, aLogicOfs, aHorFract, aZoomFract );
+
+ Point aTwipsOfs( (long) ( -aOffset.X() / nScaleX + 0.5 ), (long) ( -aOffset.Y() / nScaleY + 0.5 ) );
+ aTwipMode = MapMode( MAP_TWIP, aTwipsOfs, aHorFract, aZoomFract );
+}
+
+//--------------------------------------------------------------------
+
+void ScPrintFunc::ApplyPrintSettings()
+{
+ if ( pPrinter )
+ {
+ //
+ // Printer zum Drucken umstellen
+ //
+
+ Size aEnumSize = aPageSize;
+
+
+ pPrinter->SetOrientation( bLandscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT );
+ if ( bLandscape )
+ {
+ // landscape is always interpreted as a rotation by 90 degrees !
+ // this leads to non WYSIWIG but at least it prints!
+ // #i21775#
+ long nTemp = aEnumSize.Width();
+ aEnumSize.Width() = aEnumSize.Height();
+ aEnumSize.Height() = nTemp;
+ }
+ Paper ePaper = SvxPaperInfo::GetSvxPaper( aEnumSize, MAP_TWIP, sal_True );
+ sal_uInt16 nPaperBin = ((const SvxPaperBinItem&)pParamSet->Get(ATTR_PAGE_PAPERBIN)).GetValue();
+
+ pPrinter->SetPaper( ePaper );
+ if ( PAPER_USER == ePaper )
+ {
+ MapMode aPrinterMode = pPrinter->GetMapMode();
+ MapMode aLocalMode( MAP_TWIP );
+ pPrinter->SetMapMode( aLocalMode );
+ pPrinter->SetPaperSizeUser( aEnumSize );
+ pPrinter->SetMapMode( aPrinterMode );
+ }
+
+ pPrinter->SetPaperBin( nPaperBin );
+ }
+}
+
+//--------------------------------------------------------------------
+// rPageRanges = Range fuer alle Tabellen
+// nStartPage = in rPageRanges beginnen bei nStartPage
+// nDisplayStart = lfd. Nummer fuer Anzeige der Seitennummer
+
+long ScPrintFunc::DoPrint( const MultiSelection& rPageRanges,
+ long nStartPage, long nDisplayStart, sal_Bool bDoPrint,
+ SfxProgress* pProgress, ScPreviewLocationData* pLocationData )
+{
+ DBG_ASSERT(pDev,"Device == NULL");
+ if (!pParamSet)
+ return 0;
+
+ if ( pPrinter && bDoPrint )
+ ApplyPrintSettings();
+
+ //--------------------------------------------------------------------
+
+ InitModes();
+ if ( pLocationData )
+ {
+ pLocationData->SetCellMapMode( aOffsetMode );
+ pLocationData->SetPrintTab( nPrintTab );
+ }
+
+ MakeTableString();
+
+ if ( pProgress )
+ pProgress->SetText( String( ScResId( SCSTR_STAT_PRINT ) ) );
+
+ //--------------------------------------------------------------------
+
+ long nPageNo = 0;
+ long nPrinted = 0;
+ long nEndPage = rPageRanges.GetTotalRange().Max();
+
+ sal_uInt16 nRepeats = 1; // wie oft durchgehen ?
+ if (bMultiArea)
+ nRepeats = pDoc->GetPrintRangeCount(nPrintTab);
+ for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++)
+ {
+ if (bMultiArea) // Bereich neu belegen ?
+ {
+ CalcZoom(nStep); // setzt auch nStartCol etc. neu
+ InitModes();
+ }
+
+ SCCOL nX1;
+ SCROW nY1;
+ SCCOL nX2;
+ SCROW nY2;
+ size_t nCountX;
+ size_t nCountY;
+
+ if (aTableParam.bTopDown) // von oben nach unten
+ {
+ nX1 = nStartCol;
+ for (nCountX=0; nCountX<nPagesX; nCountX++)
+ {
+ nX2 = pPageEndX[nCountX];
+ for (nCountY=0; nCountY<nPagesY; nCountY++)
+ {
+ nY1 = pPageRows[nCountY].GetStartRow();
+ nY2 = pPageRows[nCountY].GetEndRow();
+ if ( !aTableParam.bSkipEmpty || !pPageRows[nCountY].IsHidden(nCountX) )
+ {
+ if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
+ {
+ PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
+ bDoPrint, pLocationData );
+
+ if ( pProgress )
+ {
+ pProgress->SetState( nPageNo+nStartPage+1, nEndPage );
+ pProgress->Reschedule(); //Mag der Anwender noch oder hat er genug?
+ }
+ ++nPrinted;
+ }
+ ++nPageNo;
+ }
+ }
+ nX1 = nX2 + 1;
+ }
+ }
+ else // von links nach rechts
+ {
+ for (nCountY=0; nCountY<nPagesY; nCountY++)
+ {
+ nY1 = pPageRows[nCountY].GetStartRow();
+ nY2 = pPageRows[nCountY].GetEndRow();
+ nX1 = nStartCol;
+ for (nCountX=0; nCountX<nPagesX; nCountX++)
+ {
+ nX2 = pPageEndX[nCountX];
+ if ( !aTableParam.bSkipEmpty || !pPageRows[nCountY].IsHidden(nCountX) )
+ {
+ if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
+ {
+ PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
+ bDoPrint, pLocationData );
+
+ if ( pProgress )
+ {
+ pProgress->SetState( nPageNo+nStartPage+1, nEndPage );
+ pProgress->Reschedule(); //Mag der Anwender noch oder hat er genug?
+ }
+ ++nPrinted;
+ }
+ ++nPageNo;
+ }
+ nX1 = nX2 + 1;
+ }
+ }
+ }
+ }
+
+ aFieldData.aTabName = ScGlobal::GetRscString( STR_NOTES );
+
+ long nNoteNr = 0;
+ long nNoteAdd;
+ do
+ {
+ if ( nPageNo+nStartPage <= nEndPage )
+ {
+ sal_Bool bPageSelected = rPageRanges.IsSelected( nPageNo+nStartPage+1 );
+ nNoteAdd = PrintNotes( nPageNo+nStartPage, nNoteNr, bDoPrint && bPageSelected,
+ ( bPageSelected ? pLocationData : NULL ) );
+ if ( nNoteAdd )
+ {
+ nNoteNr += nNoteAdd;
+ if ( pProgress && bPageSelected )
+ {
+ pProgress->SetState( nPageNo+nStartPage+1, nEndPage );
+ pProgress->Reschedule(); //Mag der Anwender noch oder hat er genug?
+ }
+ if (bPageSelected)
+ {
+ ++nPrinted;
+ bSourceRangeValid = sal_False; // last page was no cell range
+ }
+ ++nPageNo;
+ }
+ }
+ else
+ nNoteAdd = 0;
+ }
+ while (nNoteAdd);
+
+ if ( bMultiArea )
+ ResetBreaks(nPrintTab); // Breaks fuer Anzeige richtig
+
+ return nPrinted;
+}
+
+void ScPrintFunc::CalcZoom( sal_uInt16 nRangeNo ) // Zoom berechnen
+{
+ sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab );
+ const ScRange* pThisRange = NULL;
+ if ( nRangeNo != RANGENO_NORANGE || nRangeNo < nRCount )
+ pThisRange = pDoc->GetPrintRange( nPrintTab, nRangeNo );
+ if ( pThisRange )
+ {
+ nStartCol = pThisRange->aStart.Col();
+ nStartRow = pThisRange->aStart.Row();
+ nEndCol = pThisRange->aEnd .Col();
+ nEndRow = pThisRange->aEnd .Row();
+ }
+
+ if (!AdjustPrintArea(sal_False)) // leer
+ {
+ nZoom = 100;
+ nPagesX = nPagesY = nTotalY = 0;
+ return;
+ }
+
+ pDoc->SetRepeatArea( nPrintTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );
+
+ if (aTableParam.bScalePageNum)
+ {
+ nZoom = 100;
+ sal_uInt16 nPagesToFit = aTableParam.nScalePageNum;
+
+ sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
+ while (true)
+ {
+ if (nZoom <= ZOOM_MIN)
+ break;
+
+ CalcPages();
+ 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
+ {
+ if (nZoom - nLastFitZoom <= 1)
+ {
+ nZoom = nLastFitZoom;
+ CalcPages();
+ break;
+ }
+
+ nLastNonFitZoom = nZoom;
+ nZoom = (nLastFitZoom + nZoom) / 2;
+ }
+ }
+ }
+ else if (aTableParam.bScaleTo)
+ {
+ nZoom = 100;
+ sal_uInt16 nW = aTableParam.nScaleWidth;
+ sal_uInt16 nH = aTableParam.nScaleHeight;
+
+ sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
+ while (true)
+ {
+ if (nZoom <= ZOOM_MIN)
+ break;
+
+ CalcPages();
+ 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
+ {
+ if (nZoom - nLastFitZoom <= 1)
+ {
+ nZoom = nLastFitZoom;
+ CalcPages();
+ break;
+ }
+
+ nLastNonFitZoom = nZoom;
+ nZoom = (nLastFitZoom + nZoom) / 2;
+ }
+ }
+ }
+ else if (aTableParam.bScaleAll)
+ {
+ nZoom = aTableParam.nScaleAll;
+ if ( nZoom <= ZOOM_MIN )
+ nZoom = ZOOM_MIN;
+ CalcPages();
+ }
+ else
+ {
+ DBG_ASSERT( aTableParam.bScaleNone, "kein Scale-Flag gesetzt" );
+ nZoom = 100;
+ CalcPages();
+ }
+}
+
+Size ScPrintFunc::GetDocPageSize()
+{
+ // Hoehe Kopf-/Fusszeile anpassen
+
+ InitModes(); // aTwipMode aus nZoom initialisieren
+ pDev->SetMapMode( aTwipMode ); // Kopf-/Fusszeilen in Twips
+ UpdateHFHeight( aHdr );
+ UpdateHFHeight( aFtr );
+
+ // Seitengroesse in Document-Twips
+ // Berechnung Left / Right auch in PrintPage
+
+ aPageRect = Rectangle( Point(), aPageSize );
+ aPageRect.Left() = ( aPageRect.Left() + nLeftMargin ) * 100 / nZoom;
+ aPageRect.Right() = ( aPageRect.Right() - nRightMargin ) * 100 / nZoom;
+ aPageRect.Top() = ( aPageRect.Top() + nTopMargin ) * 100 / nZoom + aHdr.nHeight;
+ aPageRect.Bottom() = ( aPageRect.Bottom() - nBottomMargin ) * 100 / nZoom - aFtr.nHeight;
+
+ Size aDocPageSize = aPageRect.GetSize();
+ if (aTableParam.bHeaders)
+ {
+ aDocPageSize.Width() -= (long) PRINT_HEADER_WIDTH;
+ aDocPageSize.Height() -= (long) PRINT_HEADER_HEIGHT;
+ }
+ if (pBorderItem)
+ {
+ aDocPageSize.Width() -= lcl_LineTotal(pBorderItem->GetLeft()) +
+ lcl_LineTotal(pBorderItem->GetRight()) +
+ pBorderItem->GetDistance(BOX_LINE_LEFT) +
+ pBorderItem->GetDistance(BOX_LINE_RIGHT);
+ aDocPageSize.Height() -= lcl_LineTotal(pBorderItem->GetTop()) +
+ lcl_LineTotal(pBorderItem->GetBottom()) +
+ pBorderItem->GetDistance(BOX_LINE_TOP) +
+ pBorderItem->GetDistance(BOX_LINE_BOTTOM);
+ }
+ if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
+ {
+ aDocPageSize.Width() -= pShadowItem->CalcShadowSpace(SHADOW_LEFT) +
+ pShadowItem->CalcShadowSpace(SHADOW_RIGHT);
+ aDocPageSize.Height() -= pShadowItem->CalcShadowSpace(SHADOW_TOP) +
+ pShadowItem->CalcShadowSpace(SHADOW_BOTTOM);
+ }
+ return aDocPageSize;
+}
+
+void ScPrintFunc::ResetBreaks( SCTAB nTab ) // Breaks fuer Anzeige richtig setzen
+{
+ pDoc->SetPageSize( nTab, GetDocPageSize() );
+ pDoc->UpdatePageBreaks( nTab, NULL );
+}
+
+void lcl_SetHidden( ScDocument* pDoc, SCTAB nPrintTab, ScPageRowEntry& rPageRowEntry,
+ SCCOL nStartCol, const SCCOL* pPageEndX )
+{
+ size_t nPagesX = rPageRowEntry.GetPagesX();
+ SCROW nStartRow = rPageRowEntry.GetStartRow();
+ SCROW nEndRow = rPageRowEntry.GetEndRow();
+
+ sal_Bool bLeftIsEmpty = sal_False;
+ ScRange aTempRange;
+ Rectangle aTempRect = pDoc->GetMMRect( 0,0, 0,0, 0 );
+
+ for (size_t i=0; i<nPagesX; i++)
+ {
+ SCCOL nEndCol = pPageEndX[i];
+ if ( pDoc->IsPrintEmpty( nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow,
+ bLeftIsEmpty, &aTempRange, &aTempRect ) )
+ {
+ rPageRowEntry.SetHidden(i);
+ bLeftIsEmpty = sal_True;
+ }
+ else
+ bLeftIsEmpty = sal_False;
+
+ nStartCol = nEndCol+1;
+ }
+}
+
+void ScPrintFunc::CalcPages() // berechnet aPageRect und Seiten aus nZoom
+{
+ if (!pPageEndX) pPageEndX = new SCCOL[MAXCOL+1];
+ if (!pPageEndY) pPageEndY = new SCROW[MAXROW+1];
+ if (!pPageRows) pPageRows = new ScPageRowEntry[MAXROW+1]; //! vorher zaehlen !!!!
+
+ pDoc->SetPageSize( nPrintTab, GetDocPageSize() );
+ if (aAreaParam.bPrintArea)
+ {
+ ScRange aRange( nStartCol, nStartRow, nPrintTab, nEndCol, nEndRow, nPrintTab );
+ pDoc->UpdatePageBreaks( nPrintTab, &aRange );
+ }
+ else
+ pDoc->UpdatePageBreaks( nPrintTab, NULL ); // sonst wird das Ende markiert
+
+ //
+ // Seiteneinteilung nach Umbruechen in Col/RowFlags
+ // Von mehreren Umbruechen in einem ausgeblendeten Bereich zaehlt nur einer.
+ //
+
+ nPagesX = 0;
+ nPagesY = 0;
+ nTotalY = 0;
+
+ bool bVisCol = false;
+ SCCOL nLastCol = -1;
+ for (SCCOL i=nStartCol; i<=nEndCol; i++)
+ {
+ 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;
+ }
+ if (!bHidden)
+ bVisCol = true;
+ }
+ if (bVisCol) // auch am Ende keine leeren Seiten
+ {
+ pPageEndX[nPagesX] = nEndCol;
+ ++nPagesX;
+ }
+
+ bool bVisRow = false;
+ SCROW nPageStartRow = nStartRow;
+ 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)
+ {
+ bool bPageBreak = (nNextPageBreak == nRow);
+ if (bPageBreak)
+ nNextPageBreak = pRowBreakIter->next();
+
+ if (nRow > nStartRow && bVisRow && bPageBreak )
+ {
+ pPageEndY[nTotalY] = nRow-1;
+ ++nTotalY;
+
+ if ( !aTableParam.bSkipEmpty ||
+ !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nRow-1 ) )
+ {
+ 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;
+ }
+
+ nPageStartRow = nRow;
+ bVisRow = false;
+ }
+
+ 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;
+ }
+ else
+ // skip all hidden rows.
+ nRow = nLastRow;
+ }
+
+ if (bVisRow)
+ {
+ pPageEndY[nTotalY] = nEndRow;
+ ++nTotalY;
+
+ if ( !aTableParam.bSkipEmpty ||
+ !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nEndRow ) )
+ {
+ pPageRows[nPagesY].SetStartRow( nPageStartRow );
+ pPageRows[nPagesY].SetEndRow( nEndRow );
+ pPageRows[nPagesY].SetPagesX( nPagesX );
+ if (aTableParam.bSkipEmpty)
+ lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX );
+ ++nPagesY;
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+// class ScJobSetup
+//------------------------------------------------------------------------
+
+ScJobSetup::ScJobSetup( SfxPrinter* pPrinter )
+{
+ eOrientation = pPrinter->GetOrientation();
+ nPaperBin = pPrinter->GetPaperBin();
+ ePaper = pPrinter->GetPaper();
+
+ if ( PAPER_USER == ePaper )
+ {
+ aUserSize = pPrinter->GetPaperSize();
+ aUserMapMode = pPrinter->GetMapMode();
+ }
+};
+
+
+
+
+
diff --git a/sc/source/ui/view/reffact.cxx b/sc/source/ui/view/reffact.cxx
new file mode 100644
index 000000000000..0d35aacb04bb
--- /dev/null
+++ b/sc/source/ui/view/reffact.cxx
@@ -0,0 +1,434 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <sfx2/app.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+
+#include "reffact.hxx"
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "acredlin.hxx"
+#include "simpref.hxx"
+#include "scmod.hxx"
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+#include "validate.hxx"
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+
+// -----------------------------------------------------------------------
+
+SFX_IMPL_MODELESSDIALOG(ScNameDlgWrapper, FID_DEFINE_NAME )
+SFX_IMPL_MODELESSDIALOG(ScSolverDlgWrapper, SID_OPENDLG_SOLVE )
+SFX_IMPL_MODELESSDIALOG(ScOptSolverDlgWrapper, SID_OPENDLG_OPTSOLVER )
+SFX_IMPL_MODELESSDIALOG(ScPivotLayoutWrapper, SID_OPENDLG_PIVOTTABLE )
+SFX_IMPL_MODELESSDIALOG(ScTabOpDlgWrapper, SID_OPENDLG_TABOP )
+SFX_IMPL_MODELESSDIALOG(ScFilterDlgWrapper, SID_FILTER )
+SFX_IMPL_MODELESSDIALOG(ScSpecialFilterDlgWrapper, SID_SPECIAL_FILTER )
+SFX_IMPL_MODELESSDIALOG(ScDbNameDlgWrapper, SID_DEFINE_DBNAME )
+SFX_IMPL_MODELESSDIALOG(ScConsolidateDlgWrapper, SID_OPENDLG_CONSOLIDATE )
+SFX_IMPL_MODELESSDIALOG(ScPrintAreasDlgWrapper, SID_OPENDLG_EDIT_PRINTAREA )
+SFX_IMPL_MODELESSDIALOG(ScCondFormatDlgWrapper, SID_OPENDLG_CONDFRMT )
+SFX_IMPL_MODELESSDIALOG(ScColRowNameRangesDlgWrapper, SID_DEFINE_COLROWNAMERANGES )
+SFX_IMPL_MODELESSDIALOG(ScFormulaDlgWrapper, SID_OPENDLG_FUNCTION )
+SFX_IMPL_MODELESSDIALOG(ScAcceptChgDlgWrapper, FID_CHG_ACCEPT )
+SFX_IMPL_MODELESSDIALOG(ScHighlightChgDlgWrapper, FID_CHG_SHOW )
+SFX_IMPL_MODELESSDIALOG(ScSimpleRefDlgWrapper, WID_SIMPLE_REF )
+/*!!! dafuer muss der Funktionsautopilot noch umgebaut werden
+SFX_IMPL_CHILDWINDOW(ScFunctionDlgWrapper, SID_OPENDLG_FUNCTION )
+SFX_IMPL_CHILDWINDOW(ScEditFunctionDlgWrapper, SID_OPENDLG_EDITFUNCTION )
+SFX_IMPL_CHILDWINDOW(ScArgumentDlgWrapper, SID_OPENDLG_ARGUMENT )
+*/
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+//SFX_IMPL_MODELESSDIALOG(ScValidityRefChildWin, SID_VALIDITY_REFERENCE )
+SFX_IMPL_CHILDWINDOW(ScValidityRefChildWin, SID_VALIDITY_REFERENCE)
+SfxChildWinInfo __EXPORT ScValidityRefChildWin::GetInfo() const
+{
+ SfxChildWinInfo anInfo = SfxChildWindow::GetInfo();
+
+ if( Window *pWnd = GetWindow() )
+ {
+ anInfo.aSize = pWnd->GetSizePixel();
+
+ if( pWnd->IsDialog() )
+ if ( static_cast<Dialog*>(pWnd)->IsRollUp() )
+ anInfo.nFlags |= SFX_CHILDWIN_ZOOMIN;
+ }
+
+ return anInfo;
+}
+
+namespace { ScTabViewShell * lcl_GetTabViewShell( SfxBindings *pBindings ); }
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+
+#define IMPL_CHILD_CTOR(Class,sid) \
+ Class::Class( Window* pParentP, \
+ sal_uInt16 nId, \
+ SfxBindings* p, \
+ SfxChildWinInfo* pInfo ) \
+ : SfxChildWindow(pParentP, nId) \
+ { \
+ /*//<!--Added by PengYunQuan for Validity Cell Range Picker*/\
+ /************************************************************************************/\
+ /* When a new document is creating, the SfxViewFrame may be ready, */\
+ /* But the ScTabViewShell may have not been activated yet. In this */\
+ /* situation, SfxViewShell::Current() does not get the correct shell, */\
+ /* and we should lcl_GetTabViewShell( p ) instead of SfxViewShell::Current() */\
+ /************************************************************************************/\
+ ScTabViewShell* pViewShell = lcl_GetTabViewShell( p ); \
+ /*//-->Added by PengYunQuan for Validity Cell Range Picker*/\
+ if (!pViewShell) \
+ pViewShell = PTR_CAST( ScTabViewShell, SfxViewShell::Current() ); \
+ DBG_ASSERT( pViewShell, "missing view shell :-(" ); \
+ pWindow = pViewShell ? \
+ pViewShell->CreateRefDialog( p, this, pInfo, pParentP, sid ) : NULL; \
+ if (pViewShell && !pWindow) \
+ pViewShell->GetViewFrame()->SetChildWindow( nId, sal_False ); \
+ }
+
+
+//=========================================================================
+
+//-------------------------------------------------------------------------
+// ScNameDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScNameDlgWrapper, FID_DEFINE_NAME )
+
+//-------------------------------------------------------------------------
+// ScSolverDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScSolverDlgWrapper, SID_OPENDLG_SOLVE )
+
+//-------------------------------------------------------------------------
+// ScOptSolverDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScOptSolverDlgWrapper, SID_OPENDLG_OPTSOLVER )
+
+//-------------------------------------------------------------------------
+// ScPivotLayoutWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScPivotLayoutWrapper, SID_OPENDLG_PIVOTTABLE )
+
+//-------------------------------------------------------------------------
+// ScTabOpDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScTabOpDlgWrapper, SID_OPENDLG_TABOP )
+
+//-------------------------------------------------------------------------
+// ScFilterDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScFilterDlgWrapper, SID_FILTER )
+
+//-------------------------------------------------------------------------
+// ScSpecialFilterDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScSpecialFilterDlgWrapper, SID_SPECIAL_FILTER )
+
+//-------------------------------------------------------------------------
+// ScDbNameDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScDbNameDlgWrapper, SID_DEFINE_DBNAME )
+
+//-------------------------------------------------------------------------
+// ScColRowNameRangesDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScColRowNameRangesDlgWrapper, SID_DEFINE_COLROWNAMERANGES )
+
+//-------------------------------------------------------------------------
+// ScConsolidateDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScConsolidateDlgWrapper, SID_OPENDLG_CONSOLIDATE )
+
+//-------------------------------------------------------------------------
+// ScPrintAreasDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScPrintAreasDlgWrapper, SID_OPENDLG_EDIT_PRINTAREA )
+
+//-------------------------------------------------------------------------
+// ScCondFormatDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScCondFormatDlgWrapper, SID_OPENDLG_CONDFRMT )
+
+//-------------------------------------------------------------------------
+// ScFormulaDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScFormulaDlgWrapper, SID_OPENDLG_FUNCTION )
+
+
+//-------------------------------------------------------------------------
+// ScSimpleRefDlgWrapper
+//-------------------------------------------------------------------------
+
+static sal_Bool bScSimpleRefFlag;
+static long nScSimpleRefHeight;
+static long nScSimpleRefWidth;
+static long nScSimpleRefX;
+static long nScSimpleRefY;
+static sal_Bool bAutoReOpen=sal_True;
+
+ScSimpleRefDlgWrapper::ScSimpleRefDlgWrapper( Window* pParentP,
+ sal_uInt16 nId,
+ SfxBindings* p,
+ SfxChildWinInfo* pInfo )
+ : SfxChildWindow(pParentP, nId)
+{
+// ScTabViewShell* pViewShell =
+// PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
+
+ ScTabViewShell* pViewShell = NULL;
+ SfxDispatcher* pDisp = p->GetDispatcher();
+ if ( pDisp )
+ {
+ SfxViewFrame* pViewFrm = pDisp->GetFrame();
+ if ( pViewFrm )
+ pViewShell = PTR_CAST( ScTabViewShell, pViewFrm->GetViewShell() );
+ }
+
+ DBG_ASSERT( pViewShell, "missing view shell :-(" );
+
+ if(pInfo!=NULL && bScSimpleRefFlag)
+ {
+ pInfo->aPos.X()=nScSimpleRefX;
+ pInfo->aPos.Y()=nScSimpleRefY;
+ pInfo->aSize.Height()=nScSimpleRefHeight;
+ pInfo->aSize.Width()=nScSimpleRefWidth;
+ }
+ pWindow = NULL;
+
+ if(bAutoReOpen && pViewShell)
+ pWindow = pViewShell->CreateRefDialog( p, this, pInfo, pParentP, WID_SIMPLE_REF);
+
+ if (!pWindow)
+ {
+ SC_MOD()->SetRefDialog( nId, sal_False );
+ }
+}
+
+void ScSimpleRefDlgWrapper::SetDefaultPosSize(Point aPos, Size aSize, sal_Bool bSet)
+{
+ bScSimpleRefFlag=bSet;
+ if(bScSimpleRefFlag)
+ {
+ nScSimpleRefX=aPos.X();
+ nScSimpleRefY=aPos.Y();
+ nScSimpleRefHeight=aSize.Height();
+ nScSimpleRefWidth=aSize.Width();
+ }
+}
+
+
+String ScSimpleRefDlgWrapper::GetRefString()
+{
+ String aResult;
+ if(pWindow!=NULL)
+ {
+ aResult=((ScSimpleRefDlg*)pWindow)->GetRefString();
+ }
+ return aResult;
+}
+
+void ScSimpleRefDlgWrapper::SetAutoReOpen(sal_Bool bFlag)
+{
+ bAutoReOpen=bFlag;
+}
+
+void ScSimpleRefDlgWrapper::SetRefString(const String& rStr)
+{
+ if(pWindow!=NULL)
+ {
+ ((ScSimpleRefDlg*)pWindow)->SetRefString(rStr);
+ }
+}
+
+void ScSimpleRefDlgWrapper::SetCloseHdl( const Link& rLink )
+{
+ if(pWindow!=NULL)
+ {
+ ((ScSimpleRefDlg*)pWindow)->SetCloseHdl( rLink );
+ }
+}
+
+void ScSimpleRefDlgWrapper::SetUnoLinks( const Link& rDone,
+ const Link& rAbort, const Link& rChange )
+{
+ if(pWindow!=NULL)
+ {
+ ((ScSimpleRefDlg*)pWindow)->SetUnoLinks( rDone, rAbort, rChange );
+ }
+}
+
+void ScSimpleRefDlgWrapper::SetFlags( sal_Bool bCloseOnButtonUp, sal_Bool bSingleCell, sal_Bool bMultiSelection )
+{
+ if(pWindow!=NULL)
+ {
+ ((ScSimpleRefDlg*)pWindow)->SetFlags( bCloseOnButtonUp, bSingleCell, bMultiSelection );
+ }
+}
+
+void ScSimpleRefDlgWrapper::StartRefInput()
+{
+ if(pWindow!=NULL)
+ {
+ ((ScSimpleRefDlg*)pWindow)->StartRefInput();
+ }
+}
+
+
+
+//-------------------------------------------------------------------------
+// ScAcceptChgDlgWrapper //Kommentar: sollte in die ViewShell
+//-------------------------------------------------------------------------
+
+ScAcceptChgDlgWrapper::ScAcceptChgDlgWrapper( Window* pParentP,
+ sal_uInt16 nId,
+ SfxBindings* pBindings,
+ SfxChildWinInfo* pInfo ) :
+ SfxChildWindow( pParentP, nId )
+{
+ ScTabViewShell* pViewShell =
+ PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
+ DBG_ASSERT( pViewShell, "missing view shell :-(" );
+ pWindow = pViewShell ?
+ new ScAcceptChgDlg( pBindings, this, pParentP, pViewShell->GetViewData() ) :
+ NULL;
+ if(pWindow!=NULL)
+ {
+ ((ScAcceptChgDlg*)pWindow)->Initialize( pInfo );
+ }
+ if (pViewShell && !pWindow)
+ pViewShell->GetViewFrame()->SetChildWindow( nId, sal_False );
+}
+
+void ScAcceptChgDlgWrapper::ReInitDlg()
+{
+ ScTabViewShell* pViewShell =
+ PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
+ DBG_ASSERT( pViewShell, "missing view shell :-(" );
+
+ if(pWindow!=NULL && pViewShell)
+ {
+ ((ScAcceptChgDlg*)pWindow)->ReInit(pViewShell->GetViewData());
+ }
+}
+
+//-------------------------------------------------------------------------
+// ScHighlightChgDlgWrapper
+//-------------------------------------------------------------------------
+
+IMPL_CHILD_CTOR( ScHighlightChgDlgWrapper, FID_CHG_SHOW )
+
+/*------------------------------------------------------------------------*/
+/*@@@
+ //-------------------------------------------------------------------------
+ // ScFunctionDlgWrapper
+ //-------------------------------------------------------------------------
+
+ IMPL_CHILD_CTOR( ScFunctionDlgWrapper, SID_OPENDLG_FUNCTION )
+
+ //-------------------------------------------------------------------------
+ // ScEditFunctionDlgWrapper
+ //-------------------------------------------------------------------------
+
+ IMPL_CHILD_CTOR( ScEditFunctionDlgWrapper, SID_OPENDLG_EDITFUNCTION )
+
+ //-------------------------------------------------------------------------
+ // ScArgumentDlgWrapper
+ //-------------------------------------------------------------------------
+
+ IMPL_CHILD_CTOR( ScArgumentDlgWrapper, SID_OPENDLG_ARGUMENT )
+@@@*/
+/*------------------------------------------------------------------------*/
+
+
+//<!--Added by PengYunQuan for Validity Cell Range Picker
+namespace
+{
+ ScTabViewShell * lcl_GetTabViewShell( SfxBindings *pBindings )
+ {
+ if( pBindings )
+ if( SfxDispatcher* pDisp = pBindings ->GetDispatcher() )
+ if( SfxViewFrame *pFrm = pDisp->GetFrame() )
+ if( SfxViewShell* pViewSh = pFrm->GetViewShell() )
+ return dynamic_cast<ScTabViewShell*>( pViewSh );
+
+ return NULL;
+ }
+}
+
+ScValidityRefChildWin::ScValidityRefChildWin( Window* pParentP, \
+ sal_uInt16 nId, \
+ SfxBindings* p, \
+ SfxChildWinInfo* /*pInfo*/ ) \
+ : SfxChildWindow(pParentP, nId),
+ m_bVisibleLock( false ),
+ m_bFreeWindowLock( false ),
+ m_pSavedWndParent( NULL )
+{
+ SetWantsFocus( sal_False );\
+ ScTabViewShell* pViewShell = \
+ NULL != ( pWindow = ScValidationDlg::Find1AliveObject( pParentP ) ) ? static_cast<ScValidationDlg*>(pWindow)->GetTabViewShell() :
+ lcl_GetTabViewShell( p );
+ if (!pViewShell)
+ pViewShell = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
+ DBG_ASSERT( pViewShell, "missing view shell :-(" ); \
+ if (pViewShell && !pWindow) \
+ pViewShell->GetViewFrame()->SetChildWindow( nId, sal_False ); \
+ else if( pWindow /*&& pWindow->ISA(ScValidationDlg)*/ )
+ {}//pWindow = new Window( pParentP, WB_HIDE );
+
+ if( pWindow ) m_pSavedWndParent = pWindow->GetParent();
+}
+
+ScValidityRefChildWin::~ScValidityRefChildWin()
+{
+ if( pWindow ) pWindow->SetParent( m_pSavedWndParent );
+
+ if( m_bFreeWindowLock )
+ pWindow = NULL;
+}
+//-->Added by PengYunQuan for Validity Cell Range Picker
diff --git a/sc/source/ui/view/scextopt.cxx b/sc/source/ui/view/scextopt.cxx
new file mode 100644
index 000000000000..d5816ecdd289
--- /dev/null
+++ b/sc/source/ui/view/scextopt.cxx
@@ -0,0 +1,224 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "scextopt.hxx"
+
+#include <vector>
+#include <map>
+#include <boost/shared_ptr.hpp>
+
+// ============================================================================
+
+ScExtDocSettings::ScExtDocSettings() :
+ mfTabBarWidth( -1.0 ),
+ mnLinkCnt( 0 ),
+ mnDisplTab( 0 )
+{
+}
+
+// ============================================================================
+
+ScExtTabSettings::ScExtTabSettings() :
+ maUsedArea( ScAddress::INITIALIZE_INVALID ),
+ maCursor( ScAddress::INITIALIZE_INVALID ),
+ maFirstVis( ScAddress::INITIALIZE_INVALID ),
+ maSecondVis( ScAddress::INITIALIZE_INVALID ),
+ maFreezePos( 0, 0, 0 ),
+ maSplitPos( 0, 0 ),
+ meActivePane( SCEXT_PANE_TOPLEFT ),
+ maGridColor( COL_AUTO ),
+ mnNormalZoom( 0 ),
+ mnPageZoom( 0 ),
+ mbSelected( false ),
+ mbFrozenPanes( false ),
+ mbPageMode( false )
+{
+}
+
+// ============================================================================
+
+/** A container for ScExtTabSettings objects.
+ @descr Internally, a std::map with shared pointers to ScExtTabSettings is
+ used. The copy constructor and assignment operator make deep copies of the
+ objects. */
+class ScExtTabSettingsCont
+{
+public:
+ explicit ScExtTabSettingsCont();
+ ScExtTabSettingsCont( const ScExtTabSettingsCont& rSrc );
+ ScExtTabSettingsCont& operator=( const ScExtTabSettingsCont& rSrc );
+
+ const ScExtTabSettings* GetTabSettings( SCTAB nTab ) const;
+ ScExtTabSettings& GetOrCreateTabSettings( SCTAB nTab );
+
+private:
+ typedef ::boost::shared_ptr< ScExtTabSettings > ScExtTabSettingsRef;
+ typedef ::std::map< SCTAB, ScExtTabSettingsRef > ScExtTabSettingsMap;
+
+ /** Makes a deep copy of all objects in the passed map. */
+ void CopyFromMap( const ScExtTabSettingsMap& rMap );
+
+ ScExtTabSettingsMap maMap;
+};
+
+// ----------------------------------------------------------------------------
+
+ScExtTabSettingsCont::ScExtTabSettingsCont()
+{
+}
+
+ScExtTabSettingsCont::ScExtTabSettingsCont( const ScExtTabSettingsCont& rSrc )
+{
+ CopyFromMap( rSrc.maMap );
+}
+
+ScExtTabSettingsCont& ScExtTabSettingsCont::operator=( const ScExtTabSettingsCont& rSrc )
+{
+ CopyFromMap( rSrc.maMap );
+ return *this;
+}
+
+const ScExtTabSettings* ScExtTabSettingsCont::GetTabSettings( SCTAB nTab ) const
+{
+ ScExtTabSettingsMap::const_iterator aIt = maMap.find( nTab );
+ return (aIt == maMap.end()) ? 0 : aIt->second.get();
+}
+
+ScExtTabSettings& ScExtTabSettingsCont::GetOrCreateTabSettings( SCTAB nTab )
+{
+ ScExtTabSettingsRef& rxTabSett = maMap[ nTab ];
+ if( !rxTabSett )
+ rxTabSett.reset( new ScExtTabSettings );
+ return *rxTabSett;
+}
+
+void ScExtTabSettingsCont::CopyFromMap( const ScExtTabSettingsMap& rMap )
+{
+ maMap.clear();
+ for( ScExtTabSettingsMap::const_iterator aIt = rMap.begin(), aEnd = rMap.end(); aIt != aEnd; ++aIt )
+ maMap[ aIt->first ].reset( new ScExtTabSettings( *aIt->second ) );
+}
+
+// ============================================================================
+
+/** Implementation struct for ScExtDocOptions containing all members. */
+struct ScExtDocOptionsImpl
+{
+ typedef ::std::vector< String > StringVec;
+
+ ScExtDocSettings maDocSett; /// Global document settings.
+ ScExtTabSettingsCont maTabSett; /// Settings for all sheets.
+ StringVec maCodeNames; /// Codenames for all sheets (VBA module names).
+ bool mbChanged; /// Use only if something has been changed.
+
+ explicit ScExtDocOptionsImpl();
+};
+
+ScExtDocOptionsImpl::ScExtDocOptionsImpl() :
+ mbChanged( false )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ScExtDocOptions::ScExtDocOptions() :
+ mxImpl( new ScExtDocOptionsImpl )
+{
+}
+
+ScExtDocOptions::ScExtDocOptions( const ScExtDocOptions& rSrc ) :
+ mxImpl( new ScExtDocOptionsImpl( *rSrc.mxImpl ) )
+{
+}
+
+ScExtDocOptions::~ScExtDocOptions()
+{
+}
+
+ScExtDocOptions& ScExtDocOptions::operator=( const ScExtDocOptions& rSrc )
+{
+ *mxImpl = *rSrc.mxImpl;
+ return *this;
+}
+
+bool ScExtDocOptions::IsChanged() const
+{
+ return mxImpl->mbChanged;
+}
+
+void ScExtDocOptions::SetChanged( bool bChanged )
+{
+ mxImpl->mbChanged = bChanged;
+}
+
+const ScExtDocSettings& ScExtDocOptions::GetDocSettings() const
+{
+ return mxImpl->maDocSett;
+}
+
+ScExtDocSettings& ScExtDocOptions::GetDocSettings()
+{
+ return mxImpl->maDocSett;
+}
+
+const ScExtTabSettings* ScExtDocOptions::GetTabSettings( SCTAB nTab ) const
+{
+ return mxImpl->maTabSett.GetTabSettings( nTab );
+}
+
+ScExtTabSettings& ScExtDocOptions::GetOrCreateTabSettings( SCTAB nTab )
+{
+ return mxImpl->maTabSett.GetOrCreateTabSettings( nTab );
+}
+
+SCTAB ScExtDocOptions::GetCodeNameCount() const
+{
+ return static_cast< SCTAB >( mxImpl->maCodeNames.size() );
+}
+
+const String& ScExtDocOptions::GetCodeName( SCTAB nTab ) const
+{
+ DBG_ASSERT( (0 <= nTab) && (nTab < GetCodeNameCount()), "ScExtDocOptions::GetCodeName - invalid sheet index" );
+ return ((0 <= nTab) && (nTab < GetCodeNameCount())) ? mxImpl->maCodeNames[ static_cast< size_t >( nTab ) ] : EMPTY_STRING;
+}
+
+void ScExtDocOptions::SetCodeName( SCTAB nTab, const String& rCodeName )
+{
+ DBG_ASSERT( nTab >= 0, "ScExtDocOptions::SetCodeName - invalid sheet index" );
+ if( nTab >= 0 )
+ {
+ size_t nIndex = static_cast< size_t >( nTab );
+ if( nIndex >= mxImpl->maCodeNames.size() )
+ mxImpl->maCodeNames.resize( nIndex + 1 );
+ mxImpl->maCodeNames[ nIndex ] = rCodeName;
+ }
+}
+
+// ============================================================================
+
diff --git a/sc/source/ui/view/select.cxx b/sc/source/ui/view/select.cxx
new file mode 100644
index 000000000000..ab0cb8248813
--- /dev/null
+++ b/sc/source/ui/view/select.cxx
@@ -0,0 +1,891 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <tools/urlobj.hxx>
+#include <vcl/sound.hxx>
+#include <sfx2/docfile.hxx>
+
+#include "select.hxx"
+#include "sc.hrc"
+#include "tabvwsh.hxx"
+#include "scmod.hxx"
+#include "document.hxx"
+//#include "dataobj.hxx"
+#include "transobj.hxx"
+#include "docsh.hxx"
+#include "tabprotection.hxx"
+
+extern sal_uInt16 nScFillModeMouseModifier; // global.cxx
+
+using namespace com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+static Point aSwitchPos; //! Member
+static sal_Bool bDidSwitch = sal_False;
+
+// -----------------------------------------------------------------------
+
+//
+// View (Gridwin / Tastatur)
+//
+
+ScViewFunctionSet::ScViewFunctionSet( ScViewData* pNewViewData ) :
+ pViewData( pNewViewData ),
+ pEngine( NULL ),
+ bAnchor( sal_False ),
+ bStarted( sal_False )
+{
+ DBG_ASSERT(pViewData, "ViewData==0 bei FunctionSet");
+}
+
+ScSplitPos ScViewFunctionSet::GetWhich()
+{
+ if (pEngine)
+ return pEngine->GetWhich();
+ else
+ return pViewData->GetActivePart();
+}
+
+void ScViewFunctionSet::SetSelectionEngine( ScViewSelectionEngine* pSelEngine )
+{
+ pEngine = pSelEngine;
+}
+
+// Drag & Drop
+
+void __EXPORT ScViewFunctionSet::BeginDrag()
+{
+ SCTAB nTab = pViewData->GetTabNo();
+
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ if (pEngine)
+ {
+ Point aMPos = pEngine->GetMousePosPixel();
+ pViewData->GetPosFromPixel( aMPos.X(), aMPos.Y(), GetWhich(), nPosX, nPosY );
+ }
+ else
+ {
+ nPosX = pViewData->GetCurX();
+ nPosY = pViewData->GetCurY();
+ }
+
+ ScModule* pScMod = SC_MOD();
+ sal_Bool bRefMode = pScMod->IsFormulaMode();
+ if (!bRefMode)
+ {
+ pViewData->GetView()->FakeButtonUp( GetWhich() ); // ButtonUp wird verschluckt
+
+ ScMarkData& rMark = pViewData->GetMarkData();
+// rMark.SetMarking(sal_False); // es fehlt ein ButtonUp
+ rMark.MarkToSimple();
+ if ( rMark.IsMarked() && !rMark.IsMultiMarked() )
+ {
+ ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
+ // bApi = sal_True -> no error mesages
+ sal_Bool bCopied = pViewData->GetView()->CopyToClip( pClipDoc, sal_False, sal_True );
+ if ( bCopied )
+ {
+ sal_Int8 nDragActions = pViewData->GetView()->SelectionEditable() ?
+ ( DND_ACTION_COPYMOVE | DND_ACTION_LINK ) :
+ ( DND_ACTION_COPY | DND_ACTION_LINK );
+
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScTransferObj ctor
+
+ ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
+ uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ // set position of dragged cell within range
+ ScRange aMarkRange = pTransferObj->GetRange();
+ SCCOL nStartX = aMarkRange.aStart.Col();
+ SCROW nStartY = aMarkRange.aStart.Row();
+ SCCOL nHandleX = (nPosX >= (SCsCOL) nStartX) ? nPosX - nStartX : 0;
+ SCROW nHandleY = (nPosY >= (SCsROW) nStartY) ? nPosY - nStartY : 0;
+ pTransferObj->SetDragHandlePos( nHandleX, nHandleY );
+ pTransferObj->SetVisibleTab( nTab );
+
+ pTransferObj->SetDragSource( pDocSh, rMark );
+
+ Window* pWindow = pViewData->GetActiveWin();
+ if ( pWindow->IsTracking() )
+ pWindow->EndTracking( ENDTRACK_CANCEL ); // abort selecting
+
+ SC_MOD()->SetDragObject( pTransferObj, NULL ); // for internal D&D
+ pTransferObj->StartDrag( pWindow, nDragActions );
+
+ return; // dragging started
+ }
+ else
+ delete pClipDoc;
+ }
+ }
+
+ Sound::Beep(); // can't drag
+}
+
+// Selektion
+
+void __EXPORT ScViewFunctionSet::CreateAnchor()
+{
+ if (bAnchor) return;
+
+ sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
+ if (bRefMode)
+ SetAnchor( pViewData->GetRefStartX(), pViewData->GetRefStartY() );
+ else
+ SetAnchor( pViewData->GetCurX(), pViewData->GetCurY() );
+}
+
+void ScViewFunctionSet::SetAnchor( SCCOL nPosX, SCROW nPosY )
+{
+ sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
+ ScTabView* pView = pViewData->GetView();
+ SCTAB nTab = pViewData->GetTabNo();
+
+ if (bRefMode)
+ {
+ pView->DoneRefMode( sal_False );
+ aAnchorPos.Set( nPosX, nPosY, nTab );
+ pView->InitRefMode( aAnchorPos.Col(), aAnchorPos.Row(), aAnchorPos.Tab(),
+ SC_REFTYPE_REF );
+ bStarted = sal_True;
+ }
+ else if (pViewData->IsAnyFillMode())
+ {
+ aAnchorPos.Set( nPosX, nPosY, nTab );
+ bStarted = sal_True;
+ }
+ else
+ {
+ // nicht weg und gleich wieder hin
+ if ( bStarted && pView->IsMarking( nPosX, nPosY, nTab ) )
+ {
+ // nix
+ }
+ else
+ {
+ pView->DoneBlockMode( sal_True );
+ aAnchorPos.Set( nPosX, nPosY, nTab );
+ ScMarkData& rMark = pViewData->GetMarkData();
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ {
+ pView->InitBlockMode( aAnchorPos.Col(), aAnchorPos.Row(),
+ aAnchorPos.Tab(), sal_True );
+ bStarted = sal_True;
+ }
+ else
+ bStarted = sal_False;
+ }
+ }
+ bAnchor = sal_True;
+}
+
+void __EXPORT ScViewFunctionSet::DestroyAnchor()
+{
+ sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
+ if (bRefMode)
+ pViewData->GetView()->DoneRefMode( sal_True );
+ else
+ pViewData->GetView()->DoneBlockMode( sal_True );
+
+ bAnchor = sal_False;
+}
+
+void ScViewFunctionSet::SetAnchorFlag( sal_Bool bSet )
+{
+ bAnchor = bSet;
+}
+
+sal_Bool __EXPORT ScViewFunctionSet::SetCursorAtPoint( const Point& rPointPixel, sal_Bool /* bDontSelectAtCursor */ )
+{
+ if ( bDidSwitch )
+ {
+ if ( rPointPixel == aSwitchPos )
+ return sal_False; // nicht auf falschem Fenster scrollen
+ else
+ bDidSwitch = sal_False;
+ }
+ aSwitchPos = rPointPixel; // nur wichtig, wenn bDidSwitch
+
+ // treat position 0 as -1, so scrolling is always possible
+ // (with full screen and hidden headers, the top left border may be at 0)
+ // (moved from ScViewData::GetPosFromPixel)
+
+ Point aEffPos = rPointPixel;
+ if ( aEffPos.X() == 0 )
+ aEffPos.X() = -1;
+ if ( aEffPos.Y() == 0 )
+ aEffPos.Y() = -1;
+
+ // Scrolling
+
+ Size aWinSize = pEngine->GetWindow()->GetOutputSizePixel();
+ sal_Bool bRightScroll = ( aEffPos.X() >= aWinSize.Width() );
+ sal_Bool bBottomScroll = ( aEffPos.Y() >= aWinSize.Height() );
+ sal_Bool bNegScroll = ( aEffPos.X() < 0 || aEffPos.Y() < 0 );
+ sal_Bool bScroll = bRightScroll || bBottomScroll || bNegScroll;
+
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aEffPos.X(), aEffPos.Y(), GetWhich(),
+ nPosX, nPosY, sal_True, sal_True ); // mit Repair
+
+ // fuer AutoFill in der Mitte der Zelle umschalten
+ // dabei aber nicht das Scrolling nach rechts/unten verhindern
+ if ( pViewData->IsFillMode() || pViewData->GetFillMode() == SC_FILL_MATRIX )
+ {
+ sal_Bool bLeft, bTop;
+ pViewData->GetMouseQuadrant( aEffPos, GetWhich(), nPosX, nPosY, bLeft, bTop );
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ if ( bLeft && !bRightScroll )
+ do --nPosX; while ( nPosX>=0 && pDoc->ColHidden( nPosX, nTab ) );
+ if ( bTop && !bBottomScroll )
+ {
+ if (--nPosY >= 0)
+ {
+ nPosY = pDoc->LastVisibleRow(0, nPosY, nTab);
+ if (!ValidRow(nPosY))
+ nPosY = -1;
+ }
+ }
+ // negativ ist erlaubt
+ }
+
+ // ueber Fixier-Grenze bewegt?
+
+ ScSplitPos eWhich = GetWhich();
+ if ( eWhich == pViewData->GetActivePart() )
+ {
+ if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX )
+ if ( aEffPos.X() >= aWinSize.Width() )
+ {
+ if ( eWhich == SC_SPLIT_TOPLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT ), bScroll = sal_False, bDidSwitch = sal_True;
+ else if ( eWhich == SC_SPLIT_BOTTOMLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bScroll = sal_False, bDidSwitch = sal_True;
+ }
+
+ if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX )
+ if ( aEffPos.Y() >= aWinSize.Height() )
+ {
+ if ( eWhich == SC_SPLIT_TOPLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT ), bScroll = sal_False, bDidSwitch = sal_True;
+ else if ( eWhich == SC_SPLIT_TOPRIGHT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bScroll = sal_False, bDidSwitch = sal_True;
+ }
+ }
+
+ pViewData->ResetOldCursor();
+ return SetCursorAtCell( nPosX, nPosY, bScroll );
+}
+
+sal_Bool ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, sal_Bool bScroll )
+{
+ ScTabView* pView = pViewData->GetView();
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ if ( pDoc->IsTabProtected(nTab) )
+ {
+ if (nPosX < 0 || nPosY < 0)
+ return false;
+
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ bool bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+ bool bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
+
+ if ( bSkipProtected && bSkipUnprotected )
+ return sal_False;
+
+ bool bCellProtected = pDoc->HasAttrib(nPosX, nPosY, nTab, nPosX, nPosY, nTab, HASATTR_PROTECTED);
+ if ( (bCellProtected && bSkipProtected) || (!bCellProtected && bSkipUnprotected) )
+ // Don't select this cell!
+ return sal_False;
+ }
+
+ ScModule* pScMod = SC_MOD();
+ ScTabViewShell* pViewShell = pViewData->GetViewShell();
+ bool bRefMode = ( pViewShell ? pViewShell->IsRefInputMode() : false );
+
+ sal_Bool bHide = !bRefMode && !pViewData->IsAnyFillMode() &&
+ ( nPosX != (SCsCOL) pViewData->GetCurX() || nPosY != (SCsROW) pViewData->GetCurY() );
+
+ if (bHide)
+ pView->HideAllCursors();
+
+ if (bScroll)
+ {
+ if (bRefMode)
+ {
+ ScSplitPos eWhich = GetWhich();
+ pView->AlignToCursor( nPosX, nPosY, SC_FOLLOW_LINE, &eWhich );
+ }
+ else
+ pView->AlignToCursor( nPosX, nPosY, SC_FOLLOW_LINE );
+ }
+
+ if (bRefMode)
+ {
+ // #90910# if no input is possible from this doc, don't move the reference cursor around
+ if ( !pScMod->IsModalMode(pViewData->GetSfxDocShell()) )
+ {
+ if (!bAnchor)
+ {
+ pView->DoneRefMode( sal_True );
+ pView->InitRefMode( nPosX, nPosY, pViewData->GetTabNo(), SC_REFTYPE_REF );
+ }
+
+ pView->UpdateRef( nPosX, nPosY, pViewData->GetTabNo() );
+ }
+ }
+ else if (pViewData->IsFillMode() ||
+ (pViewData->GetFillMode() == SC_FILL_MATRIX && (nScFillModeMouseModifier & KEY_MOD1) ))
+ {
+ // Wenn eine Matrix angefasst wurde, kann mit Ctrl auf AutoFill zurueckgeschaltet werden
+
+ SCCOL nStartX, nEndX;
+ SCROW nStartY, nEndY; // Block
+ SCTAB nDummy;
+ pViewData->GetSimpleArea( nStartX, nStartY, nDummy, nEndX, nEndY, nDummy );
+
+ if (pViewData->GetRefType() != SC_REFTYPE_FILL)
+ {
+ pView->InitRefMode( nStartX, nStartY, nTab, SC_REFTYPE_FILL );
+ CreateAnchor();
+ }
+
+ ScRange aDelRange;
+ sal_Bool bOldDelMark = pViewData->GetDelMark( aDelRange );
+
+ if ( nPosX+1 >= (SCsCOL) nStartX && nPosX <= (SCsCOL) nEndX &&
+ nPosY+1 >= (SCsROW) nStartY && nPosY <= (SCsROW) nEndY &&
+ ( nPosX != nEndX || nPosY != nEndY ) ) // verkleinern ?
+ {
+ // Richtung (links oder oben)
+
+ long nSizeX = 0;
+ for (SCCOL i=nPosX+1; i<=nEndX; i++)
+ nSizeX += pDoc->GetColWidth( i, nTab );
+ long nSizeY = (long) pDoc->GetRowHeight( nPosY+1, nEndY, nTab );
+
+ SCCOL nDelStartX = nStartX;
+ SCROW nDelStartY = nStartY;
+ if ( nSizeX > nSizeY )
+ nDelStartX = nPosX + 1;
+ else
+ nDelStartY = nPosY + 1;
+ // 0 braucht nicht mehr getrennt abgefragt zu werden, weil nPosX/Y auch negativ wird
+
+ if ( nDelStartX < nStartX )
+ nDelStartX = nStartX;
+ if ( nDelStartY < nStartY )
+ nDelStartY = nStartY;
+
+ // Bereich setzen
+
+ pViewData->SetDelMark( ScRange( nDelStartX,nDelStartY,nTab,
+ nEndX,nEndY,nTab ) );
+ pViewData->GetView()->UpdateShrinkOverlay();
+
+#if 0
+ if ( bOldDelMark )
+ {
+ ScUpdateRect aRect( aDelRange.aStart.Col(), aDelRange.aStart.Row(),
+ aDelRange.aEnd.Col(), aDelRange.aEnd.Row() );
+ aRect.SetNew( nDelStartX,nDelStartY, nEndX,nEndY );
+ SCCOL nPaintStartX;
+ SCROW nPaintStartY;
+ SCCOL nPaintEndX;
+ SCROW nPaintEndY;
+ if (aRect.GetDiff( nPaintStartX, nPaintStartY, nPaintEndX, nPaintEndY ))
+ pViewData->GetView()->
+ PaintArea( nPaintStartX, nPaintStartY,
+ nPaintEndX, nPaintEndY, SC_UPDATE_MARKS );
+ }
+ else
+#endif
+ pViewData->GetView()->
+ PaintArea( nStartX,nDelStartY, nEndX,nEndY, SC_UPDATE_MARKS );
+
+ nPosX = nEndX; // roten Rahmen um ganzen Bereich lassen
+ nPosY = nEndY;
+
+ // Referenz wieder richtigherum, falls unten umgedreht
+ if ( nStartX != pViewData->GetRefStartX() || nStartY != pViewData->GetRefStartY() )
+ {
+ pViewData->GetView()->DoneRefMode();
+ pViewData->GetView()->InitRefMode( nStartX, nStartY, nTab, SC_REFTYPE_FILL );
+ }
+ }
+ else
+ {
+ if ( bOldDelMark )
+ {
+ pViewData->ResetDelMark();
+ pViewData->GetView()->UpdateShrinkOverlay();
+
+#if 0
+ pViewData->GetView()->
+ PaintArea( aDelRange.aStart.Col(), aDelRange.aStart.Row(),
+ aDelRange.aEnd.Col(), aDelRange.aEnd.Row(), SC_UPDATE_MARKS );
+#endif
+ }
+
+ sal_Bool bNegX = ( nPosX < (SCsCOL) nStartX );
+ sal_Bool bNegY = ( nPosY < (SCsROW) nStartY );
+
+ long nSizeX = 0;
+ if ( bNegX )
+ {
+ // #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->ColHidden(nPosX, nTab) );
+ for (SCCOL i=nPosX; i<nStartX; i++)
+ nSizeX += pDoc->GetColWidth( i, nTab );
+ }
+ else
+ for (SCCOL i=nEndX+1; i<=nPosX; i++)
+ nSizeX += pDoc->GetColWidth( i, nTab );
+
+ long nSizeY = 0;
+ if ( bNegY )
+ {
+ // #94321# in SetCursorAtPoint hidden rows are skipped.
+ // They must be skipped here too, or the result will always be the first hidden row.
+ if (++nPosY < nStartY)
+ {
+ nPosY = pDoc->FirstVisibleRow(nPosY, nStartY-1, nTab);
+ if (!ValidRow(nPosY))
+ nPosY = nStartY;
+ }
+ nSizeY += pDoc->GetRowHeight( nPosY, nStartY-1, nTab );
+ }
+ else
+ nSizeY += pDoc->GetRowHeight( nEndY+1, nPosY, nTab );
+
+ if ( nSizeX > nSizeY ) // Fill immer nur in einer Richtung
+ {
+ nPosY = nEndY;
+ bNegY = sal_False;
+ }
+ else
+ {
+ nPosX = nEndX;
+ bNegX = sal_False;
+ }
+
+ SCCOL nRefStX = bNegX ? nEndX : nStartX;
+ SCROW nRefStY = bNegY ? nEndY : nStartY;
+ if ( nRefStX != pViewData->GetRefStartX() || nRefStY != pViewData->GetRefStartY() )
+ {
+ pViewData->GetView()->DoneRefMode();
+ pViewData->GetView()->InitRefMode( nRefStX, nRefStY, nTab, SC_REFTYPE_FILL );
+ }
+ }
+
+ pView->UpdateRef( nPosX, nPosY, nTab );
+ }
+ else if (pViewData->IsAnyFillMode())
+ {
+ sal_uInt8 nMode = pViewData->GetFillMode();
+ if ( nMode == SC_FILL_EMBED_LT || nMode == SC_FILL_EMBED_RB )
+ {
+ DBG_ASSERT( pDoc->IsEmbedded(), "!pDoc->IsEmbedded()" );
+ ScRange aRange;
+ pDoc->GetEmbedded( aRange);
+ ScRefType eRefMode = (nMode == SC_FILL_EMBED_LT) ? SC_REFTYPE_EMBED_LT : SC_REFTYPE_EMBED_RB;
+ if (pViewData->GetRefType() != eRefMode)
+ {
+ if ( nMode == SC_FILL_EMBED_LT )
+ pView->InitRefMode( aRange.aEnd.Col(), aRange.aEnd.Row(), nTab, eRefMode );
+ else
+ pView->InitRefMode( aRange.aStart.Col(), aRange.aStart.Row(), nTab, eRefMode );
+ CreateAnchor();
+ }
+
+ pView->UpdateRef( nPosX, nPosY, nTab );
+ }
+ else if ( nMode == SC_FILL_MATRIX )
+ {
+ SCCOL nStartX, nEndX;
+ SCROW nStartY, nEndY; // Block
+ SCTAB nDummy;
+ pViewData->GetSimpleArea( nStartX, nStartY, nDummy, nEndX, nEndY, nDummy );
+
+ if (pViewData->GetRefType() != SC_REFTYPE_FILL)
+ {
+ pView->InitRefMode( nStartX, nStartY, nTab, SC_REFTYPE_FILL );
+ CreateAnchor();
+ }
+
+ if ( nPosX < nStartX ) nPosX = nStartX;
+ if ( nPosY < nStartY ) nPosY = nStartY;
+
+ pView->UpdateRef( nPosX, nPosY, nTab );
+ }
+ // else neue Modi
+ }
+ else // normales Markieren
+ {
+ sal_Bool bHideCur = bAnchor && ( (SCCOL)nPosX != pViewData->GetCurX() ||
+ (SCROW)nPosY != pViewData->GetCurY() );
+ if (bHideCur)
+ pView->HideAllCursors(); // sonst zweimal: Block und SetCursor
+
+ if (bAnchor)
+ {
+ if (!bStarted)
+ {
+ sal_Bool bMove = ( nPosX != (SCsCOL) aAnchorPos.Col() ||
+ nPosY != (SCsROW) aAnchorPos.Row() );
+ if ( bMove || ( pEngine && pEngine->GetMouseEvent().IsShift() ) )
+ {
+ pView->InitBlockMode( aAnchorPos.Col(), aAnchorPos.Row(),
+ aAnchorPos.Tab(), sal_True );
+ bStarted = sal_True;
+ }
+ }
+ if (bStarted)
+ pView->MarkCursor( (SCCOL) nPosX, (SCROW) nPosY, nTab, sal_False, sal_False, sal_True );
+ }
+ else
+ {
+ ScMarkData& rMark = pViewData->GetMarkData();
+ if (rMark.IsMarked() || rMark.IsMultiMarked())
+ {
+ pView->DoneBlockMode(sal_True);
+ pView->InitBlockMode( nPosX, nPosY, nTab, sal_True );
+ pView->MarkCursor( (SCCOL) nPosX, (SCROW) nPosY, nTab );
+
+ aAnchorPos.Set( nPosX, nPosY, nTab );
+ bStarted = sal_True;
+ }
+ // #i3875# *Hack* When a new cell is Ctrl-clicked with no pre-selected cells,
+ // it highlights that new cell as well as the old cell where the cursor is
+ // positioned prior to the click. A selection mode via Shift-F8 should also
+ // follow the same behavior.
+ else if ( pViewData->IsSelCtrlMouseClick() )
+ {
+ SCCOL nOldX = pViewData->GetCurX();
+ SCROW nOldY = pViewData->GetCurY();
+
+ pView->InitBlockMode( nOldX, nOldY, nTab, sal_True );
+ pView->MarkCursor( (SCCOL) nOldX, (SCROW) nOldY, nTab );
+
+ if ( nOldX != nPosX || nOldY != nPosY )
+ {
+ pView->DoneBlockMode( sal_True );
+ pView->InitBlockMode( nPosX, nPosY, nTab, sal_True );
+ pView->MarkCursor( (SCCOL) nPosX, (SCROW) nPosY, nTab );
+ aAnchorPos.Set( nPosX, nPosY, nTab );
+ }
+
+ bStarted = sal_True;
+ }
+ }
+
+ pView->SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
+ pViewData->SetRefStart( nPosX, nPosY, nTab );
+ if (bHideCur)
+ pView->ShowAllCursors();
+ }
+
+ if (bHide)
+ pView->ShowAllCursors();
+
+ return sal_True;
+}
+
+sal_Bool __EXPORT ScViewFunctionSet::IsSelectionAtPoint( const Point& rPointPixel )
+{
+ sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
+ if (bRefMode)
+ return sal_False;
+
+ if (pViewData->IsAnyFillMode())
+ return sal_False;
+
+ ScMarkData& rMark = pViewData->GetMarkData();
+ if (bAnchor || !rMark.IsMultiMarked())
+ {
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( rPointPixel.X(), rPointPixel.Y(), GetWhich(), nPosX, nPosY );
+ return pViewData->GetMarkData().IsCellMarked( (SCCOL) nPosX, (SCROW) nPosY );
+ }
+
+ return sal_False;
+}
+
+void __EXPORT ScViewFunctionSet::DeselectAtPoint( const Point& /* rPointPixel */ )
+{
+ // gibt's nicht
+}
+
+void __EXPORT ScViewFunctionSet::DeselectAll()
+{
+ if (pViewData->IsAnyFillMode())
+ return;
+
+ sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
+ if (bRefMode)
+ {
+ pViewData->GetView()->DoneRefMode( sal_False );
+ }
+ else
+ {
+ pViewData->GetView()->DoneBlockMode( sal_False );
+ pViewData->GetViewShell()->UpdateInputHandler();
+ }
+
+ bAnchor = sal_False;
+}
+
+//------------------------------------------------------------------------
+
+ScViewSelectionEngine::ScViewSelectionEngine( Window* pWindow, ScTabView* pView,
+ ScSplitPos eSplitPos ) :
+ SelectionEngine( pWindow, pView->GetFunctionSet() ),
+ eWhich( eSplitPos )
+{
+ // Parameter einstellen
+ SetSelectionMode( MULTIPLE_SELECTION );
+ EnableDrag( sal_True );
+}
+
+
+//------------------------------------------------------------------------
+
+//
+// Spalten- / Zeilenheader
+//
+
+ScHeaderFunctionSet::ScHeaderFunctionSet( ScViewData* pNewViewData ) :
+ pViewData( pNewViewData ),
+ bColumn( sal_False ),
+ eWhich( SC_SPLIT_TOPLEFT ),
+ bAnchor( sal_False ),
+ nCursorPos( 0 )
+{
+ DBG_ASSERT(pViewData, "ViewData==0 bei FunctionSet");
+}
+
+void ScHeaderFunctionSet::SetColumn( sal_Bool bSet )
+{
+ bColumn = bSet;
+}
+
+void ScHeaderFunctionSet::SetWhich( ScSplitPos eNew )
+{
+ eWhich = eNew;
+}
+
+void __EXPORT ScHeaderFunctionSet::BeginDrag()
+{
+ // gippsnich
+}
+
+void __EXPORT ScHeaderFunctionSet::CreateAnchor()
+{
+ if (bAnchor)
+ return;
+
+ ScTabView* pView = pViewData->GetView();
+ pView->DoneBlockMode( sal_True );
+ if (bColumn)
+ {
+ pView->InitBlockMode( static_cast<SCCOL>(nCursorPos), 0, pViewData->GetTabNo(), sal_True, sal_True, sal_False );
+ pView->MarkCursor( static_cast<SCCOL>(nCursorPos), MAXROW, pViewData->GetTabNo() );
+ }
+ else
+ {
+ pView->InitBlockMode( 0, nCursorPos, pViewData->GetTabNo(), sal_True, sal_False, sal_True );
+ pView->MarkCursor( MAXCOL, nCursorPos, pViewData->GetTabNo() );
+ }
+ bAnchor = sal_True;
+}
+
+void __EXPORT ScHeaderFunctionSet::DestroyAnchor()
+{
+ pViewData->GetView()->DoneBlockMode( sal_True );
+ bAnchor = sal_False;
+}
+
+sal_Bool __EXPORT ScHeaderFunctionSet::SetCursorAtPoint( const Point& rPointPixel, sal_Bool /* bDontSelectAtCursor */ )
+{
+ if ( bDidSwitch )
+ {
+ // die naechste gueltige Position muss vom anderen Fenster kommen
+ if ( rPointPixel == aSwitchPos )
+ return sal_False; // nicht auf falschem Fenster scrollen
+ else
+ bDidSwitch = sal_False;
+ }
+
+ // Scrolling
+
+ Size aWinSize = pViewData->GetActiveWin()->GetOutputSizePixel();
+ sal_Bool bScroll;
+ if (bColumn)
+ bScroll = ( rPointPixel.X() < 0 || rPointPixel.X() >= aWinSize.Width() );
+ else
+ bScroll = ( rPointPixel.Y() < 0 || rPointPixel.Y() >= aWinSize.Height() );
+
+ // ueber Fixier-Grenze bewegt?
+
+ sal_Bool bSwitched = sal_False;
+ if ( bColumn )
+ {
+ if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX )
+ {
+ if ( rPointPixel.X() > aWinSize.Width() )
+ {
+ if ( eWhich == SC_SPLIT_TOPLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT ), bSwitched = sal_True;
+ else if ( eWhich == SC_SPLIT_BOTTOMLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bSwitched = sal_True;
+ }
+ }
+ }
+ else // Zeilenkoepfe
+ {
+ if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX )
+ {
+ if ( rPointPixel.Y() > aWinSize.Height() )
+ {
+ if ( eWhich == SC_SPLIT_TOPLEFT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT ), bSwitched = sal_True;
+ else if ( eWhich == SC_SPLIT_TOPRIGHT )
+ pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bSwitched = sal_True;
+ }
+ }
+ }
+ if (bSwitched)
+ {
+ aSwitchPos = rPointPixel;
+ bDidSwitch = sal_True;
+ return sal_False; // nicht mit falschen Positionen rechnen
+ }
+
+ //
+
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( rPointPixel.X(), rPointPixel.Y(), pViewData->GetActivePart(),
+ nPosX, nPosY, sal_False );
+ if (bColumn)
+ {
+ nCursorPos = static_cast<SCCOLROW>(nPosX);
+ nPosY = pViewData->GetPosY(WhichV(pViewData->GetActivePart()));
+ }
+ else
+ {
+ nCursorPos = static_cast<SCCOLROW>(nPosY);
+ nPosX = pViewData->GetPosX(WhichH(pViewData->GetActivePart()));
+ }
+
+ ScTabView* pView = pViewData->GetView();
+ sal_Bool bHide = pViewData->GetCurX() != nPosX ||
+ pViewData->GetCurY() != nPosY;
+ if (bHide)
+ pView->HideAllCursors();
+
+ if (bScroll)
+ pView->AlignToCursor( nPosX, nPosY, SC_FOLLOW_LINE );
+ pView->SetCursor( nPosX, nPosY );
+
+ if ( !bAnchor || !pView->IsBlockMode() )
+ {
+ pView->DoneBlockMode( sal_True );
+ pViewData->GetMarkData().MarkToMulti(); //! wer verstellt das ???
+ pView->InitBlockMode( nPosX, nPosY, pViewData->GetTabNo(), sal_True, bColumn, !bColumn );
+
+ bAnchor = sal_True;
+ }
+
+ pView->MarkCursor( nPosX, nPosY, pViewData->GetTabNo(), bColumn, !bColumn );
+
+ // SelectionChanged innerhalb von HideCursor wegen UpdateAutoFillMark
+ pView->SelectionChanged();
+
+ if (bHide)
+ pView->ShowAllCursors();
+
+ return sal_True;
+}
+
+sal_Bool __EXPORT ScHeaderFunctionSet::IsSelectionAtPoint( const Point& rPointPixel )
+{
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( rPointPixel.X(), rPointPixel.Y(), pViewData->GetActivePart(),
+ nPosX, nPosY, sal_False );
+
+ ScMarkData& rMark = pViewData->GetMarkData();
+ if (bColumn)
+ return rMark.IsColumnMarked( nPosX );
+ else
+ return rMark.IsRowMarked( nPosY );
+}
+
+void __EXPORT ScHeaderFunctionSet::DeselectAtPoint( const Point& /* rPointPixel */ )
+{
+}
+
+void __EXPORT ScHeaderFunctionSet::DeselectAll()
+{
+ pViewData->GetView()->DoneBlockMode( sal_False );
+ bAnchor = sal_False;
+}
+
+//------------------------------------------------------------------------
+
+ScHeaderSelectionEngine::ScHeaderSelectionEngine( Window* pWindow, ScHeaderFunctionSet* pFuncSet ) :
+ SelectionEngine( pWindow, pFuncSet )
+{
+ // Parameter einstellen
+ SetSelectionMode( MULTIPLE_SELECTION );
+ EnableDrag( sal_False );
+}
+
+
+
+
+
diff --git a/sc/source/ui/view/selectionstate.cxx b/sc/source/ui/view/selectionstate.cxx
new file mode 100644
index 000000000000..d5101e68a2b7
--- /dev/null
+++ b/sc/source/ui/view/selectionstate.cxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "selectionstate.hxx"
+
+#include <editeng/editview.hxx>
+#include "viewdata.hxx"
+
+// ============================================================================
+
+ScSelectionState::ScSelectionState( ScViewData& rViewData ) :
+ meType( SC_SELECTTYPE_NONE )
+{
+ maCursor.SetTab( rViewData.GetTabNo() );
+ ScSplitPos eWhich = rViewData.GetActivePart();
+
+ if( rViewData.HasEditView( eWhich ) )
+ {
+ meType = SC_SELECTTYPE_EDITCELL;
+ maCursor.SetCol( rViewData.GetEditViewCol() );
+ maCursor.SetRow( rViewData.GetEditViewRow() );
+ maEditSel = rViewData.GetEditView( eWhich )->GetSelection();
+ }
+ else
+ {
+ maCursor.SetCol( rViewData.GetCurX() );
+ maCursor.SetRow( rViewData.GetCurY() );
+
+ ScMarkData& rMarkData = rViewData.GetMarkData();
+ rMarkData.MarkToMulti();
+ if( rMarkData.IsMultiMarked() )
+ {
+ meType = SC_SELECTTYPE_SHEET;
+ rMarkData.FillRangeListWithMarks( &maSheetSel, sal_False );
+ }
+ // else type is SC_SELECTTYPE_NONE - already initialized
+ }
+}
+
+bool operator==( const ScSelectionState& rL, const ScSelectionState& rR )
+{
+ bool bEqual = rL.GetSelectionType() == rR.GetSelectionType();
+ if( bEqual ) switch( rL.GetSelectionType() )
+ {
+ case SC_SELECTTYPE_EDITCELL:
+ bEqual &= ( rL.GetEditSelection().IsEqual( rR.GetEditSelection() ) != sal_False );
+ // run through!
+ case SC_SELECTTYPE_SHEET:
+ bEqual &= (rL.GetSheetSelection() == rR.GetSheetSelection()) == sal_True;
+ // run through!
+ case SC_SELECTTYPE_NONE:
+ bEqual &= rL.GetCellCursor() == rR.GetCellCursor();
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ return bEqual;
+}
+
+// ============================================================================
+
diff --git a/sc/source/ui/view/spelldialog.cxx b/sc/source/ui/view/spelldialog.cxx
new file mode 100644
index 000000000000..bdce01457094
--- /dev/null
+++ b/sc/source/ui/view/spelldialog.cxx
@@ -0,0 +1,279 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "spelldialog.hxx"
+
+#include <sfx2/app.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svx/svxids.hrc>
+#include <editeng/editstat.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/unolingu.hxx>
+#include "selectionstate.hxx"
+
+#include "spelleng.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "scmod.hxx"
+#include "editable.hxx"
+#include "undoblk.hxx"
+
+// ============================================================================
+
+SFX_IMPL_CHILDWINDOW( ScSpellDialogChildWindow, SID_SPELL_DIALOG )
+
+ScSpellDialogChildWindow::ScSpellDialogChildWindow( Window* pParentP, sal_uInt16 nId,
+ SfxBindings* pBindings, SfxChildWinInfo* pInfo ) :
+ ::svx::SpellDialogChildWindow( pParentP, nId, pBindings, pInfo ),
+ mpViewShell( 0 ),
+ mpViewData( 0 ),
+ mpDocShell( 0 ),
+ mpDoc( 0 ),
+ mbNeedNextObj( false ),
+ mbOldIdleDisabled( false )
+{
+ Init();
+}
+
+ScSpellDialogChildWindow::~ScSpellDialogChildWindow()
+{
+ Reset();
+}
+
+SfxChildWinInfo ScSpellDialogChildWindow::GetInfo() const
+{
+ return ::svx::SpellDialogChildWindow::GetInfo();
+}
+
+void ScSpellDialogChildWindow::InvalidateSpellDialog()
+{
+ ::svx::SpellDialogChildWindow::InvalidateSpellDialog();
+}
+
+// protected ------------------------------------------------------------------
+
+::svx::SpellPortions ScSpellDialogChildWindow::GetNextWrongSentence( bool /*bRecheck*/ )
+{
+ ::svx::SpellPortions aPortions;
+ if( mxEngine.get() && mpViewData )
+ {
+ if( EditView* pEditView = mpViewData->GetSpellingView() )
+ {
+ // edit engine handles cell iteration internally
+ do
+ {
+ if( mbNeedNextObj )
+ mxEngine->SpellNextDocument();
+ mbNeedNextObj = !mxEngine->IsFinished() && !mxEngine->SpellSentence( *pEditView, aPortions, false );
+ }
+ while( mbNeedNextObj );
+ }
+
+ // finished? - close the spelling dialog
+ if( mxEngine->IsFinished() )
+ GetBindings().GetDispatcher()->Execute( SID_SPELL_DIALOG, SFX_CALLMODE_ASYNCHRON );
+ }
+ return aPortions;
+}
+
+void ScSpellDialogChildWindow::ApplyChangedSentence( const ::svx::SpellPortions& rChanged, bool bRecheck )
+{
+ if( mxEngine.get() && mpViewData )
+ if( EditView* pEditView = mpViewData->GetSpellingView() )
+ mxEngine->ApplyChangedSentence( *pEditView, rChanged, bRecheck );
+}
+
+void ScSpellDialogChildWindow::GetFocus()
+{
+ if( IsSelectionChanged() )
+ {
+ Reset();
+ InvalidateSpellDialog();
+ Init();
+ }
+}
+
+void ScSpellDialogChildWindow::LoseFocus()
+{
+}
+
+// private --------------------------------------------------------------------
+
+void ScSpellDialogChildWindow::Reset()
+{
+ if( mpViewShell && (mpViewShell == PTR_CAST( ScTabViewShell, SfxViewShell::Current() )) )
+ {
+ if( mxEngine.get() && mxEngine->IsAnyModified() )
+ {
+ const ScAddress& rCursor = mxOldSel->GetCellCursor();
+ SCTAB nTab = rCursor.Tab();
+ SCCOL nOldCol = rCursor.Col();
+ SCROW nOldRow = rCursor.Row();
+ SCCOL nNewCol = mpViewData->GetCurX();
+ SCROW nNewRow = mpViewData->GetCurY();
+ mpDocShell->GetUndoManager()->AddUndoAction( new ScUndoConversion(
+ mpDocShell, mpViewData->GetMarkData(),
+ nOldCol, nOldRow, nTab, mxUndoDoc.release(),
+ nNewCol, nNewRow, nTab, mxRedoDoc.release(),
+ ScConversionParam( SC_CONVERSION_SPELLCHECK ) ) );
+ mpDoc->SetDirty();
+ mpDocShell->SetDocumentModified();
+ }
+
+ mpViewData->SetSpellingView( 0 );
+ mpViewShell->KillEditView( sal_True );
+ mpDocShell->PostPaintGridAll();
+ mpViewShell->UpdateInputHandler();
+ mpDoc->DisableIdle( mbOldIdleDisabled );
+ }
+ mxEngine.reset();
+ mxUndoDoc.reset();
+ mxRedoDoc.reset();
+ mxOldSel.reset();
+ mpViewShell = 0;
+ mpViewData = 0;
+ mpDocShell = 0;
+ mpDoc = 0;
+ mbNeedNextObj = false;
+ mbOldIdleDisabled = false;
+}
+
+void ScSpellDialogChildWindow::Init()
+{
+ if( mpViewShell )
+ return;
+ if( (mpViewShell = PTR_CAST( ScTabViewShell, SfxViewShell::Current() )) == 0 )
+ return;
+
+ mpViewData = mpViewShell->GetViewData();
+
+ // exit edit mode - TODO support spelling in edit mode
+ if( mpViewData->HasEditView( mpViewData->GetActivePart() ) )
+ SC_MOD()->InputEnterHandler();
+
+ mxOldSel.reset( new ScSelectionState( *mpViewData ) );
+
+ mpDocShell = mpViewData->GetDocShell();
+ mpDoc = mpDocShell->GetDocument();
+
+ const ScAddress& rCursor = mxOldSel->GetCellCursor();
+ SCCOL nCol = rCursor.Col();
+ SCROW nRow = rCursor.Row();
+ SCTAB nTab = rCursor.Tab();
+
+ ScMarkData& rMarkData = mpViewData->GetMarkData();
+ rMarkData.MarkToMulti();
+
+ switch( mxOldSel->GetSelectionType() )
+ {
+ case SC_SELECTTYPE_NONE:
+ case SC_SELECTTYPE_SHEET:
+ {
+ // test if there is something editable
+ ScEditableTester aTester( mpDoc, rMarkData );
+ if( !aTester.IsEditable() )
+ {
+ // #i85751# Don't show a ErrorMessage here, because the vcl
+ // parent of the InfoBox is not fully initialized yet.
+ // This leads to problems in the modality behaviour of the
+ // ScSpellDialogChildWindow.
+
+ //mpViewShell->ErrorMessage( aTester.GetMessageId() );
+ return;
+ }
+ }
+ break;
+
+ // edit mode exited, see TODO above
+// case SC_SELECTTYPE_EDITCELL:
+// break;
+
+ default:
+ DBG_ERRORFILE( "ScSpellDialogChildWindow::Init - unknown selection type" );
+ }
+
+ mbOldIdleDisabled = mpDoc->IsIdleDisabled();
+ mpDoc->DisableIdle( sal_True ); // #42726# stop online spelling
+
+ // *** create Undo/Redo documents *** -------------------------------------
+
+ mxUndoDoc.reset( new ScDocument( SCDOCMODE_UNDO ) );
+ mxUndoDoc->InitUndo( mpDoc, nTab, nTab );
+ mxRedoDoc.reset( new ScDocument( SCDOCMODE_UNDO ) );
+ mxRedoDoc->InitUndo( mpDoc, nTab, nTab );
+
+ if ( rMarkData.GetSelectCount() > 1 )
+ {
+ SCTAB nTabCount = mpDoc->GetTableCount();
+ for( SCTAB nOtherTab = 0; nOtherTab < nTabCount; ++nOtherTab )
+ {
+ if( rMarkData.GetTableSelect( nOtherTab ) && (nOtherTab != nTab) )
+ {
+ mxUndoDoc->AddUndoTab( nOtherTab, nOtherTab );
+ mxRedoDoc->AddUndoTab( nOtherTab, nOtherTab );
+ }
+ }
+ }
+
+ // *** create and init the edit engine *** --------------------------------
+
+ mxEngine.reset( new ScSpellingEngine(
+ mpDoc->GetEnginePool(), *mpViewData, mxUndoDoc.get(), mxRedoDoc.get(), LinguMgr::GetSpellChecker() ) );
+ mxEngine->SetRefDevice( mpViewData->GetActiveWin() );
+
+ mpViewShell->MakeEditView( mxEngine.get(), nCol, nRow );
+ EditView* pEditView = mpViewData->GetEditView( mpViewData->GetActivePart() );
+ mpViewData->SetSpellingView( pEditView );
+ Rectangle aRect( Point( 0, 0 ), Point( 0, 0 ) );
+ pEditView->SetOutputArea( aRect );
+ mxEngine->SetControlWord( EE_CNTRL_USECHARATTRIBS );
+ mxEngine->EnableUndo( sal_False );
+ mxEngine->SetPaperSize( aRect.GetSize() );
+ mxEngine->SetText( EMPTY_STRING );
+ mxEngine->ClearModifyFlag();
+
+ mbNeedNextObj = true;
+}
+
+bool ScSpellDialogChildWindow::IsSelectionChanged()
+{
+ if( !mxOldSel.get() || !mpViewShell || (mpViewShell != PTR_CAST( ScTabViewShell, SfxViewShell::Current() )) )
+ return true;
+
+ if( EditView* pEditView = mpViewData->GetSpellingView() )
+ if( pEditView->GetEditEngine() != mxEngine.get() )
+ return true;
+
+ ScSelectionState aNewSel( *mpViewData );
+ return mxOldSel->GetSheetSelection() != aNewSel.GetSheetSelection();
+}
+
+// ============================================================================
+
diff --git a/sc/source/ui/view/spelleng.cxx b/sc/source/ui/view/spelleng.cxx
new file mode 100644
index 000000000000..ab7b876d6417
--- /dev/null
+++ b/sc/source/ui/view/spelleng.cxx
@@ -0,0 +1,458 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include "spelleng.hxx"
+#include <com/sun/star/i18n/TextConversionOption.hpp>
+
+#include <memory>
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <editeng/langitem.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editview.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/svapp.hxx>
+
+#include "spelldialog.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "cell.hxx"
+#include "patattr.hxx"
+#include "waitoff.hxx"
+#include "globstr.hrc"
+
+
+using namespace ::com::sun::star;
+
+// ============================================================================
+
+namespace {
+
+bool lclHasString( ScDocument& rDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString )
+{
+ String aCompStr;
+ rDoc.GetString( nCol, nRow, nTab, aCompStr );
+ return aCompStr == rString; //! case-insensitive?
+}
+
+} // namespace
+
+// ----------------------------------------------------------------------------
+
+ScConversionEngineBase::ScConversionEngineBase(
+ SfxItemPool* pEnginePoolP, ScViewData& rViewData,
+ ScDocument* pUndoDoc, ScDocument* pRedoDoc ) :
+ ScEditEngineDefaulter( pEnginePoolP ),
+ mrViewData( rViewData ),
+ mrDocShell( *rViewData.GetDocShell() ),
+ mrDoc( *rViewData.GetDocShell()->GetDocument() ),
+ maSelState( rViewData ),
+ mpUndoDoc( pUndoDoc ),
+ mpRedoDoc( pRedoDoc ),
+ meCurrLang( LANGUAGE_ENGLISH_US ),
+ mbIsAnyModified( false ),
+ mbInitialState( true ),
+ mbWrappedInTable( false ),
+ mbFinished( false )
+{
+ maSelState.GetCellCursor().GetVars( mnStartCol, mnStartRow, mnStartTab );
+ // start with cell A1 in cell/range/multi-selection, will seek to first selected
+ if( maSelState.GetSelectionType() == SC_SELECTTYPE_SHEET )
+ {
+ mnStartCol = 0;
+ mnStartRow = 0;
+ }
+ mnCurrCol = mnStartCol;
+ mnCurrRow = mnStartRow;
+}
+
+ScConversionEngineBase::~ScConversionEngineBase()
+{
+}
+
+bool ScConversionEngineBase::FindNextConversionCell()
+{
+ ScMarkData& rMark = mrViewData.GetMarkData();
+ ScTabViewShell* pViewShell = mrViewData.GetViewShell();
+ ScBaseCell* pCell = NULL;
+ const ScPatternAttr* pPattern = NULL;
+ const ScPatternAttr* pLastPattern = NULL;
+ ::std::auto_ptr< SfxItemSet > pEditDefaults( new SfxItemSet( GetEmptyItemSet() ) );
+
+ if( IsModified() )
+ {
+ mbIsAnyModified = true;
+
+ String aNewStr = GetText();
+
+ sal_Bool bMultiTab = (rMark.GetSelectCount() > 1);
+ String aVisibleStr;
+ if( bMultiTab )
+ mrDoc.GetString( mnCurrCol, mnCurrRow, mnStartTab, aVisibleStr );
+
+ for( SCTAB nTab = 0, nTabCount = mrDoc.GetTableCount(); nTab < nTabCount; ++nTab )
+ {
+ // #69965# always change the cell on the visible tab,
+ // on the other selected tabs only if they contain the same text
+
+ if( (nTab == mnStartTab) ||
+ (bMultiTab && rMark.GetTableSelect( nTab ) &&
+ lclHasString( mrDoc, mnCurrCol, mnCurrRow, nTab, aVisibleStr )) )
+ {
+ ScAddress aPos( mnCurrCol, mnCurrRow, nTab );
+ CellType eCellType = mrDoc.GetCellType( aPos );
+ pCell = mrDoc.GetCell( aPos );
+
+ if( mpUndoDoc && pCell )
+ {
+ ScBaseCell* pUndoCell = pCell->CloneWithoutNote( *mpUndoDoc );
+ mpUndoDoc->PutCell( aPos, pUndoCell );
+ }
+
+ if( eCellType == CELLTYPE_EDIT )
+ {
+ if( pCell )
+ {
+ ScEditCell* pEditCell = static_cast< ScEditCell* >( pCell );
+ ::std::auto_ptr< EditTextObject > pEditObj( CreateTextObject() );
+ pEditCell->SetData( pEditObj.get(), GetEditTextObjectPool() );
+ }
+ }
+ else
+ {
+ mrDoc.SetString( mnCurrCol, mnCurrRow, nTab, aNewStr );
+ pCell = mrDoc.GetCell( aPos );
+ }
+
+ if( mpRedoDoc && pCell )
+ {
+ ScBaseCell* pRedoCell = pCell->CloneWithoutNote( *mpRedoDoc );
+ mpRedoDoc->PutCell( aPos, pRedoCell );
+ }
+
+ mrDocShell.PostPaintCell( mnCurrCol, mnCurrRow, nTab );
+ }
+ }
+ }
+ pCell = NULL;
+ SCCOL nNewCol = mnCurrCol;
+ SCROW nNewRow = mnCurrRow;
+
+ if( mbInitialState )
+ {
+ /* On very first call, decrement row to let GetNextSpellingCell() find
+ the first cell of current range. */
+ mbInitialState = false;
+ --nNewRow;
+ }
+
+ bool bSheetSel = maSelState.GetSelectionType() == SC_SELECTTYPE_SHEET;
+ bool bLoop = true;
+ bool bFound = false;
+ while( bLoop && !bFound )
+ {
+ bLoop = mrDoc.GetNextSpellingCell( nNewCol, nNewRow, mnStartTab, bSheetSel, rMark );
+ if( bLoop )
+ {
+ FillFromCell( mnCurrCol, mnCurrRow, mnStartTab );
+
+ if( mbWrappedInTable && ((nNewCol > mnStartCol) || ((nNewCol == mnStartCol) && (nNewRow >= mnStartRow))) )
+ {
+ ShowFinishDialog();
+ bLoop = false;
+ mbFinished = true;
+ }
+ else if( nNewCol > MAXCOL )
+ {
+ // no more cells in the sheet - try to restart at top of sheet
+
+ if( bSheetSel || ((mnStartCol == 0) && (mnStartRow == 0)) )
+ {
+ // conversion started at cell A1 or in selection, do not query to restart at top
+ ShowFinishDialog();
+ bLoop = false;
+ mbFinished = true;
+ }
+ else if( ShowTableWrapDialog() )
+ {
+ // conversion started anywhere but in cell A1, user wants to restart
+ nNewRow = MAXROW + 2;
+ mbWrappedInTable = true;
+ }
+ else
+ {
+ bLoop = false;
+ mbFinished = true;
+ }
+ }
+ else
+ {
+ pPattern = mrDoc.GetPattern( nNewCol, nNewRow, mnStartTab );
+ if( pPattern && (pPattern != pLastPattern) )
+ {
+ pPattern->FillEditItemSet( pEditDefaults.get() );
+ SetDefaults( *pEditDefaults );
+ pLastPattern = pPattern;
+ }
+
+ // language changed?
+ const SfxPoolItem* pItem = mrDoc.GetAttr( nNewCol, nNewRow, mnStartTab, ATTR_FONT_LANGUAGE );
+ if( const SvxLanguageItem* pLangItem = PTR_CAST( SvxLanguageItem, pItem ) )
+ {
+ LanguageType eLang = static_cast< LanguageType >( pLangItem->GetValue() );
+ if( eLang == LANGUAGE_SYSTEM )
+ eLang = Application::GetSettings().GetLanguage(); // never use SYSTEM for spelling
+ if( eLang != meCurrLang )
+ {
+ meCurrLang = eLang;
+ SetDefaultLanguage( eLang );
+ }
+ }
+
+ FillFromCell( nNewCol, nNewRow, mnStartTab );
+
+ bFound = bLoop && NeedsConversion();
+ }
+ }
+ }
+
+ if( bFound )
+ {
+ pViewShell->AlignToCursor( nNewCol, nNewRow, SC_FOLLOW_JUMP );
+ pViewShell->SetCursor( nNewCol, nNewRow, sal_True );
+ mrViewData.GetView()->MakeEditView( this, nNewCol, nNewRow );
+ EditView* pEditView = mrViewData.GetSpellingView();
+ // maSelState.GetEditSelection() returns (0,0) if not in edit mode -> ok
+ pEditView->SetSelection( maSelState.GetEditSelection() );
+
+ ClearModifyFlag();
+ mnCurrCol = nNewCol;
+ mnCurrRow = nNewRow;
+ }
+
+ return bFound;
+}
+
+void ScConversionEngineBase::RestoreCursorPos()
+{
+ const ScAddress& rPos = maSelState.GetCellCursor();
+ mrViewData.GetViewShell()->SetCursor( rPos.Col(), rPos.Row() );
+}
+
+bool ScConversionEngineBase::ShowTableWrapDialog()
+{
+ // default: no dialog, always restart at top
+ return true;
+}
+
+void ScConversionEngineBase::ShowFinishDialog()
+{
+ // default: no dialog
+}
+
+// private --------------------------------------------------------------------
+
+void ScConversionEngineBase::FillFromCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
+{
+ CellType eCellType;
+ mrDoc.GetCellType( nCol, nRow, nTab, eCellType );
+
+ switch( eCellType )
+ {
+ case CELLTYPE_STRING:
+ {
+ String aText;
+ mrDoc.GetString( nCol, nRow, nTab, aText );
+ SetText( aText );
+ }
+ break;
+ case CELLTYPE_EDIT:
+ {
+ ScBaseCell* pCell = NULL;
+ mrDoc.GetCell( nCol, nRow, nTab, pCell );
+ if( pCell )
+ {
+ const EditTextObject* pNewEditObj = NULL;
+ static_cast< ScEditCell* >( pCell )->GetData( pNewEditObj );
+ if( pNewEditObj )
+ SetText( *pNewEditObj );
+ }
+ }
+ break;
+ default:
+ SetText( EMPTY_STRING );
+ }
+}
+
+// ============================================================================
+
+ScSpellingEngine::ScSpellingEngine(
+ SfxItemPool* pEnginePoolP, ScViewData& rViewData,
+ ScDocument* pUndoDoc, ScDocument* pRedoDoc,
+ XSpellCheckerRef xSpeller ) :
+ ScConversionEngineBase( pEnginePoolP, rViewData, pUndoDoc, pRedoDoc )
+{
+ SetSpeller( xSpeller );
+}
+
+void ScSpellingEngine::ConvertAll( EditView& rEditView )
+{
+ EESpellState eState = EE_SPELL_OK;
+ if( FindNextConversionCell() )
+ eState = rEditView.StartSpeller( static_cast< sal_Bool >( sal_True ) );
+
+ DBG_ASSERT( eState != EE_SPELL_NOSPELLER, "ScSpellingEngine::Convert - no spell checker" );
+ if( eState == EE_SPELL_NOLANGUAGE )
+ {
+ Window* pParent = GetDialogParent();
+ ScWaitCursorOff aWaitOff( pParent );
+ InfoBox( pParent, ScGlobal::GetRscString( STR_NOLANGERR ) ).Execute();
+ }
+}
+
+sal_Bool ScSpellingEngine::SpellNextDocument()
+{
+ return FindNextConversionCell();
+}
+
+bool ScSpellingEngine::NeedsConversion()
+{
+ return HasSpellErrors() != EE_SPELL_OK;
+}
+
+bool ScSpellingEngine::ShowTableWrapDialog()
+{
+ Window* pParent = GetDialogParent();
+ ScWaitCursorOff aWaitOff( pParent );
+ MessBox aMsgBox( pParent, WinBits( WB_YES_NO | WB_DEF_YES ),
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),
+ ScGlobal::GetRscString( STR_SPELLING_BEGIN_TAB) );
+ return aMsgBox.Execute() == RET_YES;
+}
+
+void ScSpellingEngine::ShowFinishDialog()
+{
+ Window* pParent = GetDialogParent();
+ ScWaitCursorOff aWaitOff( pParent );
+ InfoBox( pParent, ScGlobal::GetRscString( STR_SPELLING_STOP_OK ) ).Execute();
+}
+
+Window* ScSpellingEngine::GetDialogParent()
+{
+ sal_uInt16 nWinId = ScSpellDialogChildWindow::GetChildWindowId();
+ SfxViewFrame* pViewFrm = mrViewData.GetViewShell()->GetViewFrame();
+ if( pViewFrm->HasChildWindow( nWinId ) )
+ if( SfxChildWindow* pChild = pViewFrm->GetChildWindow( nWinId ) )
+ if( Window* pWin = pChild->GetWindow() )
+ if( pWin->IsVisible() )
+ return pWin;
+
+ // fall back to standard dialog parent
+ return mrDocShell.GetActiveDialogParent();
+}
+
+// ============================================================================
+
+ScConversionParam::ScConversionParam( ScConversionType eConvType ) :
+ meConvType( eConvType ),
+ meSourceLang( LANGUAGE_NONE ),
+ meTargetLang( LANGUAGE_NONE ),
+ mnOptions( 0 ),
+ mbUseTargetFont( false ),
+ mbIsInteractive( false )
+{
+}
+
+ScConversionParam::ScConversionParam( ScConversionType eConvType,
+ LanguageType eLang, sal_Int32 nOptions, bool bIsInteractive ) :
+ meConvType( eConvType ),
+ meSourceLang( eLang ),
+ meTargetLang( eLang ),
+ mnOptions( nOptions ),
+ mbUseTargetFont( false ),
+ mbIsInteractive( bIsInteractive )
+{
+ if (LANGUAGE_KOREAN == eLang)
+ mnOptions = i18n::TextConversionOption::CHARACTER_BY_CHARACTER;
+}
+
+ScConversionParam::ScConversionParam( ScConversionType eConvType,
+ LanguageType eSourceLang, LanguageType eTargetLang, const Font& rTargetFont,
+ sal_Int32 nOptions, bool bIsInteractive ) :
+ meConvType( eConvType ),
+ meSourceLang( eSourceLang ),
+ meTargetLang( eTargetLang ),
+ maTargetFont( rTargetFont ),
+ mnOptions( nOptions ),
+ mbUseTargetFont( true ),
+ mbIsInteractive( bIsInteractive )
+{
+ if (LANGUAGE_KOREAN == meSourceLang && LANGUAGE_KOREAN == meTargetLang)
+ mnOptions = i18n::TextConversionOption::CHARACTER_BY_CHARACTER;
+}
+
+// ----------------------------------------------------------------------------
+
+ScTextConversionEngine::ScTextConversionEngine(
+ SfxItemPool* pEnginePoolP, ScViewData& rViewData,
+ const ScConversionParam& rConvParam,
+ ScDocument* pUndoDoc, ScDocument* pRedoDoc ) :
+ ScConversionEngineBase( pEnginePoolP, rViewData, pUndoDoc, pRedoDoc ),
+ maConvParam( rConvParam )
+{
+}
+
+void ScTextConversionEngine::ConvertAll( EditView& rEditView )
+{
+ if( FindNextConversionCell() )
+ {
+ rEditView.StartTextConversion(
+ maConvParam.GetSourceLang(), maConvParam.GetTargetLang(), maConvParam.GetTargetFont(),
+ maConvParam.GetOptions(), maConvParam.IsInteractive(), sal_True );
+ // #i34769# restore initial cursor position
+ RestoreCursorPos();
+ }
+}
+
+sal_Bool ScTextConversionEngine::ConvertNextDocument()
+{
+ return FindNextConversionCell();
+}
+
+bool ScTextConversionEngine::NeedsConversion()
+{
+ return HasConvertibleTextPortion( maConvParam.GetSourceLang() );
+}
+
+// ============================================================================
+
diff --git a/sc/source/ui/view/tabcont.cxx b/sc/source/ui/view/tabcont.cxx
new file mode 100644
index 000000000000..6e41548dc31f
--- /dev/null
+++ b/sc/source/ui/view/tabcont.cxx
@@ -0,0 +1,638 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/docfile.hxx>
+#include <vcl/sound.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include "tabcont.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "scmod.hxx"
+#include "scresid.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "transobj.hxx"
+#include "clipparam.hxx"
+
+
+// STATIC DATA -----------------------------------------------------------
+
+//==================================================================
+
+ScTabControl::ScTabControl( Window* pParent, ScViewData* pData ) :
+ TabBar( pParent, WinBits( WB_BORDER | WB_3DLOOK | WB_SCROLL |
+ WB_RANGESELECT | WB_MULTISELECT | WB_DRAG | WB_SIZEABLE ) ),
+ DropTargetHelper( this ),
+ DragSourceHelper( this ),
+ pViewData( pData ),
+ nMouseClickPageId( TabBar::PAGE_NOT_FOUND ),
+ nSelPageIdByMouse( TabBar::PAGE_NOT_FOUND ),
+ bErrorShown( sal_False )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ String aString;
+ Color aTabBgColor;
+ SCTAB nCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nCount; i++)
+ {
+ if (pDoc->IsVisible(i))
+ {
+ if (pDoc->GetName(i,aString))
+ {
+ if ( pDoc->IsScenario(i) )
+ 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 );
+ }
+ }
+ }
+ }
+
+ SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNo()) + 1 );
+
+ SetSizePixel( Size(SC_TABBAR_DEFWIDTH, 0) );
+
+ SetSplitHdl( LINK( pViewData->GetView(), ScTabView, TabBarResize ) );
+
+ EnableEditMode();
+}
+
+ScTabControl::~ScTabControl()
+{
+}
+
+sal_uInt16 ScTabControl::GetMaxId() const
+{
+ sal_uInt16 nVisCnt = GetPageCount();
+ if (nVisCnt)
+ return GetPageId(nVisCnt-1);
+
+ return 0;
+}
+
+SCTAB ScTabControl::GetPrivatDropPos(const Point& rPos )
+{
+ sal_uInt16 nPos = ShowDropPos(rPos);
+
+ SCTAB nRealPos = static_cast<SCTAB>(nPos);
+
+ if(nPos !=0 )
+ {
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ SCTAB nCount = pDoc->GetTableCount();
+
+ sal_uInt16 nViewPos=0;
+ nRealPos = nCount;
+ for (SCTAB i=0; i<nCount; i++)
+ {
+ if (pDoc->IsVisible(i))
+ {
+ nViewPos++;
+ if(nViewPos==nPos)
+ {
+ SCTAB j;
+ for (j=i+1; j<nCount; j++)
+ {
+ if (pDoc->IsVisible(j))
+ {
+ break;
+ }
+ }
+ nRealPos =j;
+ break;
+ }
+ }
+ }
+ }
+ return nRealPos ;
+}
+
+void ScTabControl::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ ScModule* pScMod = SC_MOD();
+ if ( !pScMod->IsModalMode() && !pScMod->IsFormulaMode() && !IsInEditMode() )
+ {
+ // View aktivieren
+ pViewData->GetViewShell()->SetActive(); // Appear und SetViewFrame
+ pViewData->GetView()->ActiveGrabFocus();
+ }
+
+ /* #47745# Click into free area -> insert new sheet (like in Draw).
+ Needing clean left click without modifiers (may be context menu).
+ #106948# Remember clicks to all pages, to be able to move mouse pointer later. */
+ if( rMEvt.IsLeft() && (rMEvt.GetModifier() == 0) )
+ nMouseClickPageId = GetPageId( rMEvt.GetPosPixel() );
+ else
+ nMouseClickPageId = TabBar::PAGE_NOT_FOUND;
+
+ TabBar::MouseButtonDown( rMEvt );
+}
+
+void ScTabControl::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ Point aPos = PixelToLogic( rMEvt.GetPosPixel() );
+
+ // mouse button down and up on same page?
+ if( nMouseClickPageId != GetPageId( aPos ) )
+ nMouseClickPageId = TabBar::PAGE_NOT_FOUND;
+
+ if ( rMEvt.GetClicks() == 2 && rMEvt.IsLeft() && nMouseClickPageId != 0 && nMouseClickPageId != TAB_PAGE_NOTFOUND )
+ {
+ SfxDispatcher* pDispatcher = pViewData->GetViewShell()->GetViewFrame()->GetDispatcher();
+ pDispatcher->Execute( FID_TAB_MENU_RENAME, SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD );
+ }
+
+ if( nMouseClickPageId == 0 )
+ {
+ // Click in the area next to the existing tabs:
+ // #i70320# if several sheets are selected, deselect all ecxept the current sheet,
+ // otherwise add new sheet
+ sal_uInt16 nSlot = ( GetSelectPageCount() > 1 ) ? FID_TAB_DESELECTALL : FID_INS_TABLE;
+ 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_NOT_FOUND;
+ }
+
+ TabBar::MouseButtonUp( rMEvt );
+}
+
+void ScTabControl::Select()
+{
+ /* Remember last clicked page ID. */
+ nSelPageIdByMouse = nMouseClickPageId;
+ /* Reset nMouseClickPageId, so that next Select() call may invalidate
+ nSelPageIdByMouse (i.e. if called from keyboard). */
+ nMouseClickPageId = TabBar::PAGE_NOT_FOUND;
+
+ ScModule* pScMod = SC_MOD();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScMarkData& rMark = pViewData->GetMarkData();
+ SCTAB nCount = pDoc->GetTableCount();
+ SCTAB i;
+
+ if ( pScMod->IsTableLocked() ) // darf jetzt nicht umgeschaltet werden ?
+ {
+ // den alten Zustand des TabControls wiederherstellen:
+
+ for (i=0; i<nCount; i++)
+ SelectPage( static_cast<sal_uInt16>(i)+1, rMark.GetTableSelect(i) );
+ SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNo()) + 1 );
+
+ Sound::Beep();
+ return;
+ }
+
+ sal_uInt16 nCurId = GetCurPageId();
+ if (!nCurId) return; // kann vorkommen, wenn bei Excel-Import alles versteckt ist
+ sal_uInt16 nPage = nCurId - 1;
+
+ // OLE-inplace deaktivieren
+ if ( nPage != static_cast<sal_uInt16>(pViewData->GetTabNo()) )
+ pViewData->GetView()->DrawMarkListHasChanged();
+
+ // InputEnterHandler nur wenn nicht Referenzeingabe
+
+ sal_Bool bRefMode = pScMod->IsFormulaMode();
+ if (!bRefMode)
+ pScMod->InputEnterHandler();
+
+ for (i=0; i<nCount; i++)
+ rMark.SelectTable( i, IsPageSelected(static_cast<sal_uInt16>(i)+1) );
+
+/* Markierungen werden per Default nicht pro Tabelle gehalten
+ sal_uInt16 nSelCnt = GetSelectPageCount();
+ if (nSelCnt>1)
+ pDoc->ExtendMarksFromTable( nPage );
+*/
+
+ SfxDispatcher& rDisp = pViewData->GetDispatcher();
+ if (rDisp.IsLocked())
+ pViewData->GetView()->SetTabNo( static_cast<SCTAB>(nPage) );
+ else
+ {
+ // Tabelle fuer Basic ist 1-basiert
+ SfxUInt16Item aItem( SID_CURRENTTAB, nPage + 1 );
+ rDisp.Execute( SID_CURRENTTAB, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
+ &aItem, (void*) NULL );
+ }
+
+ SfxBindings& rBind = pViewData->GetBindings();
+ rBind.Invalidate( FID_FILL_TAB );
+ rBind.Invalidate( FID_TAB_DESELECTALL );
+
+ rBind.Invalidate( FID_INS_TABLE );
+ rBind.Invalidate( FID_TAB_APPEND );
+ rBind.Invalidate( FID_TAB_MOVE );
+ rBind.Invalidate( FID_TAB_RENAME );
+ 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)
+ // bei anderen gibt das nur unnoetiges Gezappel
+
+ if ( bRefMode && pViewData->GetRefType() == SC_REFTYPE_REF )
+ if ( pViewData->GetViewShell()->GetViewFrame()->HasChildWindow(SID_OPENDLG_CONSOLIDATE) )
+ {
+ ScRange aRange(
+ pViewData->GetRefStartX(), pViewData->GetRefStartY(), pViewData->GetRefStartZ(),
+ pViewData->GetRefEndX(), pViewData->GetRefEndY(), pViewData->GetRefEndZ() );
+ pScMod->SetReference( aRange, pDoc, &rMark );
+ pScMod->EndReference(); // wegen Auto-Hide
+ }
+}
+
+void ScTabControl::UpdateStatus()
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScMarkData& rMark = pViewData->GetMarkData();
+ sal_Bool bActive = pViewData->IsActive();
+
+ SCTAB nCount = pDoc->GetTableCount();
+ SCTAB i;
+ String aString;
+ SCTAB nMaxCnt = Max( nCount, static_cast<SCTAB>(GetMaxId()) );
+ Color aTabBgColor;
+
+ sal_Bool bModified = sal_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) || (GetTabBgColor(static_cast<sal_uInt16>(i)+1) != aTabBgColor) )
+ bModified = sal_True;
+ }
+
+ if (bModified)
+ {
+ Clear();
+ for (i=0; i<nCount; i++)
+ {
+ if (pDoc->IsVisible(i))
+ {
+ if (pDoc->GetName(i,aString))
+ {
+ if ( pDoc->IsScenario(i) )
+ 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 );
+ }
+ }
+ }
+ }
+ }
+ SetCurPageId( static_cast<sal_uInt16>(pViewData->GetTabNo()) + 1 );
+
+ if (bActive)
+ {
+ bModified = sal_False; // Selektion
+ for (i=0; i<nMaxCnt && !bModified; i++)
+ if ( rMark.GetTableSelect(i) != IsPageSelected(static_cast<sal_uInt16>(i)+1) )
+ bModified = sal_True;
+
+ // #i99576# the following loop is mis-optimized on unxsoli4 and the reason
+ // why this file is in NOOPTFILES.
+ if ( bModified )
+ for (i=0; i<nCount; i++)
+ SelectPage( static_cast<sal_uInt16>(i)+1, rMark.GetTableSelect(i) );
+ }
+ else
+ {
+ }
+}
+
+void ScTabControl::ActivateView(sal_Bool bActivate)
+{
+// ScDocument* pDoc = pViewData->GetDocument();
+ ScMarkData& rMark = pViewData->GetMarkData();
+
+// ResetMark direkt in TabView
+// pDoc->ResetMark();
+
+ sal_uInt16 nCurId = GetCurPageId();
+ if (!nCurId) return; // kann vorkommen, wenn bei Excel-Import alles versteckt ist
+ sal_uInt16 nPage = nCurId - 1;
+// sal_uInt16 nCount = GetMaxId();
+
+ /*
+ sal_uInt16 i;
+ for (i=0; i<nCount; i++)
+ {
+ SelectPage( i+1, sal_False );
+ if (bActivate)
+ rMark.SelectTable( i, sal_False );
+ }
+ */
+ if (bActivate)
+ {
+ SelectPage( nPage+1, sal_True );
+ rMark.SelectTable( static_cast<SCTAB>(nPage), sal_True );
+ }
+ Invalidate();
+}
+
+void ScTabControl::SetSheetLayoutRTL( sal_Bool bSheetRTL )
+{
+ SetEffectiveRTL( bSheetRTL );
+ nSelPageIdByMouse = TabBar::PAGE_NOT_FOUND;
+}
+
+
+void ScTabControl::Command( const CommandEvent& rCEvt )
+{
+ ScModule* pScMod = SC_MOD();
+ ScTabViewShell* pViewSh = pViewData->GetViewShell();
+ sal_Bool bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode();
+
+ // ViewFrame erstmal aktivieren (Bug 19493):
+ pViewSh->SetActive();
+
+ sal_uInt16 nCmd = rCEvt.GetCommand();
+ if ( nCmd == COMMAND_CONTEXTMENU )
+ {
+ if (!bDisable)
+ {
+ // #i18735# select the page that is under the mouse cursor
+ // if multiple tables are selected and the one under the cursor
+ // is not part of them then unselect them
+ sal_uInt16 nId = GetPageId( rCEvt.GetMousePosPixel() );
+ if (nId)
+ {
+ sal_Bool bAlreadySelected = IsPageSelected( nId );
+ //make the clicked page the current one
+ SetCurPageId( nId );
+ //change the selection when the current one is not already
+ //selected or part of a multi selection
+ if(!bAlreadySelected)
+ {
+ sal_uInt16 nCount = GetMaxId();
+
+ for (sal_uInt16 i=1; i<=nCount; i++)
+ SelectPage( i, i==nId );
+ Select();
+ }
+ }
+
+ // #i52073# OLE inplace editing has to be stopped before showing the sheet tab context menu
+ pViewSh->DeactivateOle();
+
+ // Popup-Menu:
+ // get Dispatcher from ViewData (ViewFrame) instead of Shell (Frame), so it can't be null
+ pViewData->GetDispatcher().ExecutePopup( ScResId(RID_POPUP_TAB) );
+ }
+ }
+}
+
+void ScTabControl::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel )
+{
+ ScModule* pScMod = SC_MOD();
+ sal_Bool bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode();
+
+ if (!bDisable)
+ {
+ Region aRegion( Rectangle(0,0,0,0) );
+ CommandEvent aCEvt( rPosPixel, COMMAND_STARTDRAG, sal_True ); // needed for StartDrag
+ if (TabBar::StartDrag( aCEvt, aRegion ))
+ DoDrag( aRegion );
+ }
+}
+
+void ScTabControl::DoDrag( const Region& /* rRegion */ )
+{
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+
+ SCTAB nTab = pViewData->GetTabNo();
+ ScMarkData aTabMark = pViewData->GetMarkData();
+ aTabMark.ResetMark(); // doesn't change marked table information
+ aTabMark.SetMarkArea( ScRange(0,0,nTab,MAXCOL,MAXROW,nTab) );
+
+ ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
+ ScClipParam aClipParam(ScRange(0, 0, 0, MAXCOL, MAXROW, 0), false);
+ pDoc->CopyToClip(aClipParam, pClipDoc, &aTabMark, false);
+
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScTransferObj ctor
+
+ ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
+ com::sun::star::uno::Reference<com::sun::star::datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ pTransferObj->SetDragSourceFlags( SC_DROP_TABLE );
+
+ pTransferObj->SetDragSource( pDocSh, aTabMark );
+
+ Window* pWindow = pViewData->GetActiveWin();
+ SC_MOD()->SetDragObject( pTransferObj, NULL ); // for internal D&D
+ pTransferObj->StartDrag( pWindow, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
+}
+
+sal_uInt16 lcl_DocShellNr( ScDocument* pDoc )
+{
+ sal_uInt16 nShellCnt = 0;
+ SfxObjectShell* pShell = SfxObjectShell::GetFirst();
+ while ( pShell )
+ {
+ if ( pShell->Type() == TYPE(ScDocShell) )
+ {
+ if ( ((ScDocShell*)pShell)->GetDocument() == pDoc )
+ return nShellCnt;
+
+ ++nShellCnt;
+ }
+ pShell = SfxObjectShell::GetNext( *pShell );
+ }
+
+ DBG_ERROR("Dokument nicht gefunden");
+ return 0;
+}
+
+sal_Int8 ScTabControl::ExecuteDrop( const ExecuteDropEvent& rEvt )
+{
+ EndSwitchPage();
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ const ScDragData& rData = SC_MOD()->GetDragData();
+ if ( rData.pCellTransfer && ( rData.pCellTransfer->GetDragSourceFlags() & SC_DROP_TABLE ) &&
+ rData.pCellTransfer->GetSourceDocument() == pDoc )
+ {
+ // moving of tables within the document
+ SCTAB nPos = GetPrivatDropPos( rEvt.maPosPixel );
+ HideDropPos();
+
+ if ( nPos == rData.pCellTransfer->GetVisibleTab() && rEvt.mnAction == DND_ACTION_MOVE )
+ {
+ // #i83005# do nothing - don't move to the same position
+ // (too easily triggered unintentionally, and might take a long time in large documents)
+ }
+ else
+ {
+ if ( !pDoc->GetChangeTrack() && pDoc->IsDocEditable() )
+ {
+ //! use table selection from the tab control where dragging was started?
+ pViewData->GetView()->MoveTable( lcl_DocShellNr(pDoc), nPos, rEvt.mnAction != DND_ACTION_MOVE );
+
+ rData.pCellTransfer->SetDragWasInternal(); // don't delete
+ return sal_True;
+ }
+ else
+ Sound::Beep();
+ }
+ }
+
+ return 0;
+}
+
+sal_Int8 ScTabControl::AcceptDrop( const AcceptDropEvent& rEvt )
+{
+ if ( rEvt.mbLeaving )
+ {
+ EndSwitchPage();
+ HideDropPos();
+ return rEvt.mnAction;
+ }
+
+ const ScDocument* pDoc = pViewData->GetDocument();
+ const ScDragData& rData = SC_MOD()->GetDragData();
+ if ( rData.pCellTransfer && ( rData.pCellTransfer->GetDragSourceFlags() & SC_DROP_TABLE ) &&
+ rData.pCellTransfer->GetSourceDocument() == pDoc )
+ {
+ // moving of tables within the document
+ if ( !pDoc->GetChangeTrack() && pDoc->IsDocEditable() )
+ {
+ ShowDropPos( rEvt.maPosPixel );
+ return rEvt.mnAction;
+ }
+ }
+ else // switch sheets for all formats
+ {
+ SwitchPage( rEvt.maPosPixel ); // switch sheet after timeout
+ return 0; // nothing can be dropped here
+ }
+
+ return 0;
+}
+
+long ScTabControl::StartRenaming()
+{
+ if ( pViewData->GetDocument()->IsDocEditable() )
+ return TABBAR_RENAMING_YES;
+ else
+ return TABBAR_RENAMING_NO;
+}
+
+long ScTabControl::AllowRenaming()
+{
+ ScTabViewShell* pViewSh = pViewData->GetViewShell();
+ DBG_ASSERT( pViewSh, "pViewData->GetViewShell()" );
+
+ long nRet = TABBAR_RENAMING_CANCEL;
+ sal_uInt16 nId = GetEditPageId();
+ if ( nId )
+ {
+ SCTAB nTab = nId - 1;
+ String aNewName = GetEditText();
+ sal_Bool bDone = pViewSh->RenameTable( aNewName, nTab );
+ if ( bDone )
+ nRet = TABBAR_RENAMING_YES;
+ else if ( bErrorShown )
+ {
+ // if the error message from this TabControl is currently visible,
+ // don't end edit mode now, to avoid problems when returning to
+ // the other call (showing the error) - this should not happen
+ DBG_ERROR("ScTabControl::AllowRenaming: nested calls");
+ nRet = TABBAR_RENAMING_NO;
+ }
+ else if ( Application::IsInModalMode() )
+ {
+ // #73472# don't show error message above any modal dialog
+ // instead cancel renaming without error message
+ nRet = TABBAR_RENAMING_CANCEL;
+ }
+ else
+ {
+ bErrorShown = sal_True;
+ pViewSh->ErrorMessage( STR_INVALIDTABNAME );
+ bErrorShown = sal_False;
+ nRet = TABBAR_RENAMING_NO;
+ }
+ }
+ return nRet;
+}
+
+void ScTabControl::EndRenaming()
+{
+ if ( HasFocus() )
+ pViewData->GetView()->ActiveGrabFocus();
+}
+
+void ScTabControl::Mirror()
+{
+ TabBar::Mirror();
+ if( nSelPageIdByMouse != TabBar::PAGE_NOT_FOUND )
+ {
+ Rectangle aRect( GetPageRect( GetCurPageId() ) );
+ if( !aRect.IsEmpty() )
+ SetPointerPosPixel( aRect.Center() );
+ nSelPageIdByMouse = TabBar::PAGE_NOT_FOUND; // only once after a Select()
+ }
+}
+
+
+
diff --git a/sc/source/ui/view/tabpopsh.cxx b/sc/source/ui/view/tabpopsh.cxx
new file mode 100644
index 000000000000..f5033d5d0df5
--- /dev/null
+++ b/sc/source/ui/view/tabpopsh.cxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+#include "tabpopsh.hxx"
+#include "sc.hrc"
+
+#undef ShellClass
+#define ShellClass ScTabPopShell
+SFX_SLOTMAP(ScTabPopShell)
+{
+ SFX_SLOT( 0,0, DummyExec, DummyState, 0, SfxVoidItem )
+};
+
+
+TYPEINIT1(ScTabPopShell,SfxShell);
+
+//SFX_IMPL_IDL_INTERFACE(ScTabPopShell, SfxShell, 0)
+SFX_IMPL_INTERFACE(ScTabPopShell, SfxShell, ResId( 0, NULL))
+{
+ SFX_POPUPMENU_REGISTRATION( RID_POPUP_TAB );
+}
+
+
+
+
+ScTabPopShell::ScTabPopShell(SfxItemPool& rItemPool)
+{
+ SetPool( &rItemPool );
+}
+
+
+ScTabPopShell::~ScTabPopShell()
+{
+}
+
+
+void ScTabPopShell::DummyExec( SfxRequest& rReq )
+{
+}
+
+
+void ScTabPopShell::DummyState( SfxItemSet& rSet )
+{
+}
diff --git a/sc/source/ui/view/tabsplit.cxx b/sc/source/ui/view/tabsplit.cxx
new file mode 100644
index 000000000000..9007d627cda5
--- /dev/null
+++ b/sc/source/ui/view/tabsplit.cxx
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// System - Includes -----------------------------------------------------
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "tabsplit.hxx"
+#include "viewdata.hxx"
+#include "dbfunc.hxx"
+
+//==================================================================
+
+ScTabSplitter::ScTabSplitter( Window* pParent, WinBits nWinStyle, ScViewData* pData ) :
+ Splitter( pParent, nWinStyle ),
+ pViewData(pData)
+{
+ SetFixed(sal_False);
+ EnableRTL( sal_False );
+}
+
+
+ScTabSplitter::~ScTabSplitter()
+{
+}
+
+void __EXPORT ScTabSplitter::MouseMove( const MouseEvent& rMEvt )
+{
+ if (bFixed)
+ Window::MouseMove( rMEvt );
+ else
+ Splitter::MouseMove( rMEvt );
+}
+
+void __EXPORT ScTabSplitter::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if (bFixed)
+ Window::MouseButtonUp( rMEvt );
+ else
+ Splitter::MouseButtonUp( rMEvt );
+}
+
+void __EXPORT ScTabSplitter::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if (bFixed)
+ Window::MouseButtonDown( rMEvt );
+ else
+ Splitter::MouseButtonDown( rMEvt );
+}
+
+void __EXPORT ScTabSplitter::Splitting( Point& rSplitPos )
+{
+ Window* pParent = GetParent();
+ Point aScreenPos = pParent->OutputToNormalizedScreenPixel( rSplitPos );
+ pViewData->GetView()->SnapSplitPos( aScreenPos );
+ Point aNew = pParent->NormalizedScreenToOutputPixel( aScreenPos );
+ if ( IsHorizontal() )
+ rSplitPos.X() = aNew.X();
+ else
+ rSplitPos.Y() = aNew.Y();
+}
+
+
+void ScTabSplitter::SetFixed(sal_Bool bSet)
+{
+ bFixed = bSet;
+ if (bSet)
+ SetPointer(POINTER_ARROW);
+ else if (IsHorizontal())
+ SetPointer(POINTER_HSPLIT);
+ else
+ SetPointer(POINTER_VSPLIT);
+}
+
+
+
diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx
new file mode 100644
index 000000000000..83bf1a4c9c12
--- /dev/null
+++ b/sc/source/ui/view/tabview.cxx
@@ -0,0 +1,2535 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+//------------------------------------------------------------------
+
+#if 0
+#define _MACRODLG_HXX
+#define _BIGINT_HXX
+#define _SVCONTNR_HXX
+#define BASIC_NODIALOGS
+#define _SFXMNUITEM_HXX
+#define _SVDXOUT_HXX
+#define _SVDATTR_HXX
+#define _SFXMNUITEM_HXX
+#define _DLGCFG_HXX
+#define _SFXMNUMGR_HXX
+#define _SFXBASIC_HXX
+#define _MODALDLG_HXX
+#define _SFX_TEMPLDLG_HXX
+#define _SFXSTBMGR_HXX
+#define _SFXTBXMGR_HXX
+#define _BASE_DLGS_HXX
+#define _SFXIMGMGR_HXX
+#define _SFXMNUMGR_HXX
+#define _SFXSTBITEM_HXX
+#define _SFXTBXCTRL_HXX
+#define _PASSWD_HXX
+//#define _SFXFILEDLG_HXX
+//#define _SFXREQUEST_HXX
+#define _SFXOBJFACE_HXX
+
+#define _SDR_NOTRANSFORM
+#define _SVDXOUT_HXX
+#endif
+#include <vcl/svapp.hxx>
+
+///////////////////////////////////////////////////////////////////////////
+// NODRAW.HXX
+// Erweiterte Konstanten, um CLOKs mit SVDRAW.HXX zu vermeiden
+// Die u.a. Aenderungen nehmen vorgeschlagene Konstante vorweg
+///////////////////////////////////////////////////////////////////////////
+
+#if 0
+#define _SDR_NOTRANSFORM // Transformationen, selten verwendet
+#define _SDR_NOTOUCH // Hit-Tests, selten verwendet
+
+#define _SDR_NOUNDO // Undo-Objekte
+#define _SDR_NOPAGEOBJ // SdrPageObj
+#define _SDR_NOVIRTOBJ // SdrVirtObj
+#define _SDR_NOGROUPOBJ // SdrGroupObj
+#define _SDR_NOTEXTOBJ // SdrTextObj
+#define _SDR_NOPATHOBJ // SdrPathObj
+#define _SDR_NOEDGEOBJ // SdrEdgeObj
+#define _SDR_NORECTOBJ // SdrRectObj
+#define _SDR_NOCAPTIONOBJ // SdrCaptionObj
+#define _SDR_NOCIRCLEOBJ // SdrCircleObj
+#define _SDR_NOGRAFOBJ // SdrGrafObj
+#define _SDR_NOOLE2OBJ // SdrOle2Obj
+#endif
+
+// Dieses define entfernt die VCControls aus SI.HXX
+
+#define _SI_HXX // VCControls
+
+////////////////////// Umsetzen der Standard-Defines //////////////////////
+
+//#define _SVDDRAG_HXX // SdrDragStat
+#define _SVDPAGE_HXX // SdrPage
+
+#ifdef _SDR_NOSURROGATEOBJ
+ #undef _SDR_NOSURROGATEOBJ
+ #define _SVDSURO_HXX
+#endif
+
+#ifdef _SDR_NOPAGEOBJ
+ #undef _SDR_NOPAGEOBJ
+ #define _SVDOPAGE_HXX
+#endif
+
+#ifdef _SDR_NOVIRTOBJ
+ #undef _SDR_NOVIRTOBJ
+ #define _SVDOVIRT_HXX
+#endif
+
+#ifdef _SDR_NOGROUPOBJ
+ #undef _SDR_NOGROUPOBJ
+ #define _SVDOGRP_HXX
+#endif
+
+#ifdef _SDR_NOTEXTOBJ
+ #undef _SDR_NOTEXTOBJ
+ #define _SVDOTEXT_HXX
+#endif
+
+#ifdef _SDR_NOPATHOBJ
+ #undef _SDR_NOPATHOBJ
+ #define _SVDOPATH_HXX
+#endif
+
+#ifdef _SDR_NOEDGEOBJ
+ #undef _SDR_NOEDGEOBJ
+ #define _SVDOEDGE_HXX
+#endif
+
+#ifdef _SDR_NORECTOBJ
+ #undef _SDR_NORECTOBJ
+ #define _SVDORECT_HXX
+#else
+ #undef _SDVOTEXT_OBJ
+#endif
+
+#ifdef _SDR_NOCAPTIONOBJ
+ #undef _SDR_NOCAPTIONOBJ
+ #define _SVDCAPT_HXX
+#endif
+
+#ifdef _SDR_NOCIRCLEOBJ
+ #undef _SDR_NOCIRCLEOBJ
+ #define _SVDOCIRC_HXX
+#endif
+
+#ifdef _SDR_NOGRAFOBJ
+ #undef _SDR_NOGRAFOBJ
+ #define _SVDOGRAF_HXX
+#else
+ #undef _SVDOTEXT_HXX
+ #undef _SVDORECT_HXX
+#endif
+
+#ifdef _SDR_NOOLE2OBJ
+ #undef _SDR_NOOLE2OBJ
+ #define _SVDOOLE2_HXX
+#else
+ #undef _SVDOTEXT_HXX
+ #undef _SVDORECT_HXX
+#endif
+
+//#ifdef _SDR_NOVIEWS
+// #define _SVDDRAG_HXX
+//#endif
+
+////////////////////// Ende der SVDRAW-Modifikationen /////////////////////
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <vcl/help.hxx>
+#include <rtl/logfile.hxx>
+
+#include "tabview.hxx"
+#include "tabvwsh.hxx"
+#include "document.hxx"
+#include "gridwin.hxx"
+#include "olinewin.hxx"
+#include "olinetab.hxx"
+#include "tabsplit.hxx"
+#include "colrowba.hxx"
+#include "tabcont.hxx"
+#include "scmod.hxx"
+#include "sc.hrc"
+#include "viewutil.hxx"
+#include "globstr.hrc"
+#include "drawview.hxx"
+#include "docsh.hxx"
+#include "viewuno.hxx"
+#include "AccessibilityHints.hxx"
+#include "appoptio.hxx"
+
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+
+#include <string>
+#include <algorithm>
+
+#define SPLIT_MARGIN 30
+#define SC_ICONSIZE 36
+
+#define SC_SCROLLBAR_MIN 30
+#define SC_TABBAR_MIN 6
+
+// fuer Rad-Maus
+#define SC_DELTA_ZOOM 10
+
+using namespace ::com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+
+//==================================================================
+
+// Corner-Button
+
+ScCornerButton::ScCornerButton( Window* pParent, ScViewData* pData, sal_Bool bAdditional ) :
+ Window( pParent, WinBits( 0 ) ),
+ pViewData( pData ),
+ bAdd( bAdditional )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetBackground( rStyleSettings.GetFaceColor() );
+ EnableRTL( sal_False );
+}
+
+__EXPORT ScCornerButton::~ScCornerButton()
+{
+}
+
+void __EXPORT ScCornerButton::Paint( const Rectangle& rRect )
+{
+ Size aSize = GetOutputSizePixel();
+ long nPosX = aSize.Width()-1;
+ long nPosY = aSize.Height()-1;
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ Window::Paint(rRect);
+
+ sal_Bool bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
+ long nDarkX = bLayoutRTL ? 0 : nPosX;
+
+ if ( !bAdd && !rStyleSettings.GetHighContrastMode() )
+ {
+ // match the shaded look of column/row headers
+
+ Color aFace( rStyleSettings.GetFaceColor() );
+ Color aWhite( COL_WHITE );
+ Color aCenter( aFace );
+ aCenter.Merge( aWhite, 0xd0 ); // lighten up a bit
+ Color aOuter( aFace );
+ aOuter.Merge( aWhite, 0xa0 ); // lighten up more
+
+ long nCenterX = (aSize.Width() / 2) - 1;
+ long nCenterY = (aSize.Height() / 2) - 1;
+
+ SetLineColor();
+ SetFillColor(aCenter);
+ DrawRect( Rectangle( nCenterX, nCenterY, nCenterX, nPosY ) );
+ DrawRect( Rectangle( nCenterX, nCenterY, nDarkX, nCenterY ) );
+ SetFillColor(aOuter);
+ DrawRect( Rectangle( 0, 0, nPosX, nCenterY-1 ) );
+ if ( bLayoutRTL )
+ DrawRect( Rectangle( nCenterX+1, nCenterY, nPosX, nPosY ) );
+ else
+ DrawRect( Rectangle( 0, nCenterY, nCenterX-1, nPosY ) );
+ }
+
+ // both buttons have the same look now - only dark right/bottom lines
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ DrawLine( Point(0,nPosY), Point(nPosX,nPosY) );
+ DrawLine( Point(nDarkX,0), Point(nDarkX,nPosY) );
+}
+
+void ScCornerButton::StateChanged( StateChangedType nType )
+{
+ Window::StateChanged( nType );
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetBackground( rStyleSettings.GetFaceColor() );
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ScCornerButton::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetBackground( rStyleSettings.GetFaceColor() );
+ Invalidate();
+}
+
+
+void __EXPORT ScCornerButton::Resize()
+{
+ Invalidate();
+}
+
+void __EXPORT ScCornerButton::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ ScModule* pScMod = SC_MOD();
+ sal_Bool bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode();
+ if (!bDisable)
+ {
+ ScTabViewShell* pViewSh = pViewData->GetViewShell();
+ pViewSh->SetActive(); // Appear und SetViewFrame
+ pViewSh->ActiveGrabFocus();
+
+ sal_Bool bControl = rMEvt.IsMod1();
+ pViewSh->SelectAll( bControl );
+ }
+}
+
+//==================================================================
+
+sal_Bool lcl_HasColOutline( const ScViewData& rViewData )
+{
+ const ScOutlineTable* pTable = rViewData.GetDocument()->GetOutlineTable(rViewData.GetTabNo());
+ if (pTable)
+ {
+ const ScOutlineArray* pArray = pTable->GetColArray();
+ if ( pArray->GetDepth() > 0 )
+ return sal_True;
+ }
+ return sal_False;
+}
+
+sal_Bool lcl_HasRowOutline( const ScViewData& rViewData )
+{
+ const ScOutlineTable* pTable = rViewData.GetDocument()->GetOutlineTable(rViewData.GetTabNo());
+ if (pTable)
+ {
+ const ScOutlineArray* pArray = pTable->GetRowArray();
+ if ( pArray->GetDepth() > 0 )
+ return sal_True;
+ }
+ return sal_False;
+}
+
+//==================================================================
+
+// Init und Konstruktoren
+// ScTabView::Init() in tabview5.cxx wegen out of keys
+
+
+#define TABVIEW_INIT \
+ pSelEngine( NULL ), \
+ aFunctionSet( &aViewData ), \
+ pHdrSelEng( NULL ), \
+ aHdrFunc( &aViewData ), \
+ pDrawView( NULL ), \
+ bDrawSelMode( sal_False ), \
+ aVScrollTop( pFrameWin, WinBits( WB_VSCROLL | WB_DRAG ) ), \
+ aVScrollBottom( pFrameWin, WinBits( WB_VSCROLL | WB_DRAG ) ), \
+ aHScrollLeft( pFrameWin, WinBits( WB_HSCROLL | WB_DRAG ) ), \
+ aHScrollRight( pFrameWin, WinBits( WB_HSCROLL | WB_DRAG ) ), \
+ aCornerButton( pFrameWin, &aViewData, sal_False ), \
+ aTopButton( pFrameWin, &aViewData, sal_True ), \
+ aScrollBarBox( pFrameWin, WB_SIZEABLE ), \
+ pInputHintWindow( NULL ), \
+ pPageBreakData( NULL ), \
+ pHighlightRanges( NULL ), \
+ pBrushDocument( NULL ), \
+ pDrawBrushSet( NULL ), \
+ bLockPaintBrush( sal_False ), \
+ pTimerWindow( NULL ), \
+ nTipVisible( 0 ), \
+ bDragging( sal_False ), \
+ bIsBlockMode( sal_False ), \
+ bBlockNeg( sal_False ), \
+ bBlockCols( sal_False ), \
+ bBlockRows( sal_False ), \
+ mfPendingTabBarWidth( -1.0 ), \
+ bMinimized( sal_False ), \
+ bInUpdateHeader( sal_False ), \
+ bInActivatePart( sal_False ), \
+ bInZoomUpdate( sal_False ), \
+ bMoveIsShift( sal_False ), \
+ bNewStartIfMarking( sal_False )
+
+
+ScTabView::ScTabView( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
+ pFrameWin( pParent ),
+ aViewData( &rDocSh, pViewShell ),
+ TABVIEW_INIT
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScTabView::ScTabView" );
+
+ Init();
+}
+
+//UNUSED2009-05 ScTabView::ScTabView( Window* pParent, const ScTabView& rScTabView, ScTabViewShell* pViewShell ) :
+//UNUSED2009-05 pFrameWin( pParent ),
+//UNUSED2009-05 aViewData( rScTabView.aViewData ),
+//UNUSED2009-05 TABVIEW_INIT
+//UNUSED2009-05 {
+//UNUSED2009-05 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScTabView::ScTabView" );
+//UNUSED2009-05
+//UNUSED2009-05 aViewData.SetViewShell( pViewShell );
+//UNUSED2009-05 Init();
+//UNUSED2009-05
+//UNUSED2009-05 UpdateShow();
+//UNUSED2009-05 if ( aViewData.GetActivePart() != SC_SPLIT_BOTTOMLEFT )
+//UNUSED2009-05 pGridWin[SC_SPLIT_BOTTOMLEFT]->Show();
+//UNUSED2009-05
+//UNUSED2009-05 InvalidateSplit();
+//UNUSED2009-05 }
+
+void ScTabView::InitScrollBar( ScrollBar& rScrollBar, long nMaxVal )
+{
+ rScrollBar.SetRange( Range( 0, nMaxVal ) );
+ rScrollBar.SetLineSize( 1 );
+ rScrollBar.SetPageSize( 1 ); // wird getrennt abgefragt
+ rScrollBar.SetVisibleSize( 10 ); // wird bei Resize neu gesetzt
+
+ rScrollBar.SetScrollHdl( LINK(this, ScTabView, ScrollHdl) );
+ rScrollBar.SetEndScrollHdl( LINK(this, ScTabView, EndScrollHdl) );
+}
+
+// Scroll-Timer
+
+void ScTabView::SetTimer( ScGridWindow* pWin, const MouseEvent& rMEvt )
+{
+ pTimerWindow = pWin;
+ aTimerMEvt = rMEvt;
+ aScrollTimer.Start();
+}
+
+void ScTabView::ResetTimer()
+{
+ aScrollTimer.Stop();
+ pTimerWindow = NULL;
+}
+
+IMPL_LINK( ScTabView, TimerHdl, Timer*, EMPTYARG )
+{
+// aScrollTimer.Stop();
+ if (pTimerWindow)
+ pTimerWindow->MouseMove( aTimerMEvt );
+
+ return 0;
+}
+
+// --- Resize ---------------------------------------------------------------------
+
+void lcl_SetPosSize( Window& rWindow, const Point& rPos, const Size& rSize,
+ long nTotalWidth, sal_Bool bLayoutRTL )
+{
+ Point aNewPos = rPos;
+ if ( bLayoutRTL )
+ {
+ aNewPos.X() = nTotalWidth - rPos.X() - rSize.Width();
+ if ( aNewPos == rWindow.GetPosPixel() && rSize.Width() != rWindow.GetSizePixel().Width() )
+ {
+ // Document windows are manually painted right-to-left, so they need to
+ // be repainted if the size changes.
+ rWindow.Invalidate();
+ }
+ }
+ rWindow.SetPosSizePixel( aNewPos, rSize );
+}
+
+void ScTabView::DoResize( const Point& rOffset, const Size& rSize, sal_Bool bInner )
+{
+ HideListBox();
+
+ sal_Bool bHasHint = ( pInputHintWindow != NULL );
+ if (bHasHint)
+ RemoveHintWindow();
+
+ sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
+ long nTotalWidth = rSize.Width();
+ if ( bLayoutRTL )
+ nTotalWidth += 2*rOffset.X();
+
+ sal_Bool bVScroll = aViewData.IsVScrollMode();
+ sal_Bool bHScroll = aViewData.IsHScrollMode();
+ sal_Bool bTabControl = aViewData.IsTabMode();
+ sal_Bool bHeaders = aViewData.IsHeaderMode();
+ sal_Bool bOutlMode = aViewData.IsOutlineMode();
+ sal_Bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
+ sal_Bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
+
+ // Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden:
+ SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode();
+ if ( eMode == SCROLLING_NO )
+ bHScroll = bVScroll = sal_False;
+ else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO ) //! Auto ???
+ bHScroll = bVScroll = sal_True;
+
+ if ( aViewData.GetDocShell()->IsPreview() )
+ bHScroll = bVScroll = bTabControl = bHeaders = bOutlMode = bHOutline = bVOutline = sal_False;
+
+ long nBarX = 0;
+ long nBarY = 0;
+ long nOutlineX = 0;
+ long nOutlineY = 0;
+ long nOutPosX;
+ long nOutPosY;
+
+ long nPosX = rOffset.X();
+ long nPosY = rOffset.Y();
+ long nSizeX = rSize.Width();
+ long nSizeY = rSize.Height();
+ long nSize1;
+
+ bMinimized = ( nSizeX<=SC_ICONSIZE || nSizeY<=SC_ICONSIZE );
+ if ( bMinimized )
+ return;
+
+ long nSplitSizeX = SPLIT_HANDLE_SIZE;
+ if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
+ nSplitSizeX = 1;
+ long nSplitSizeY = SPLIT_HANDLE_SIZE;
+ if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
+ nSplitSizeY = 1;
+
+ const long nOverlap = 0; // ScrollBar::GetWindowOverlapPixel();
+
+ aBorderPos = rOffset;
+ aFrameSize = rSize;
+
+ if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
+ if ( aViewData.GetHSplitPos() > nSizeX - SPLIT_MARGIN )
+ {
+ aViewData.SetHSplitMode( SC_SPLIT_NONE );
+ if ( WhichH( aViewData.GetActivePart() ) == SC_SPLIT_RIGHT )
+ ActivatePart( SC_SPLIT_BOTTOMLEFT );
+ InvalidateSplit();
+// UpdateShow();
+ }
+ if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ if ( aViewData.GetVSplitPos() > nSizeY - SPLIT_MARGIN )
+ {
+ aViewData.SetVSplitMode( SC_SPLIT_NONE );
+ if ( WhichV( aViewData.GetActivePart() ) == SC_SPLIT_TOP )
+ ActivatePart( SC_SPLIT_BOTTOMLEFT );
+ InvalidateSplit();
+// UpdateShow();
+ }
+
+ UpdateShow();
+
+ if (bHScroll || bVScroll) // Scrollbars horizontal oder vertikal
+ {
+ long nScrollBarSize = pFrameWin->GetSettings().GetStyleSettings().GetScrollBarSize();
+ if (bVScroll)
+ {
+// nBarX = aVScrollBottom.GetSizePixel().Width();
+ nBarX = nScrollBarSize;
+ nSizeX -= nBarX - nOverlap;
+ }
+ if (bHScroll)
+ {
+// nBarY = aHScrollLeft.GetSizePixel().Height();
+ nBarY = nScrollBarSize;
+ nSizeY -= nBarY - nOverlap;
+ }
+
+ // window at the bottom right
+ lcl_SetPosSize( aScrollBarBox, Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ),
+ nTotalWidth, bLayoutRTL );
+
+ if (bHScroll) // Scrollbars horizontal
+ {
+ long nSizeLt = 0; // left scroll bar
+ long nSizeRt = 0; // right scroll bar
+ long nSizeSp = 0; // splitter
+
+ switch (aViewData.GetHSplitMode())
+ {
+ case SC_SPLIT_NONE:
+ nSizeSp = nSplitSizeX;
+ nSizeLt = nSizeX - nSizeSp + nOverlap; // Ecke ueberdecken
+ break;
+ case SC_SPLIT_NORMAL:
+ nSizeSp = nSplitSizeX;
+ nSizeLt = aViewData.GetHSplitPos();
+ break;
+ case SC_SPLIT_FIX:
+ nSizeSp = 0;
+ nSizeLt = 0;
+ break;
+ }
+ nSizeRt = nSizeX - nSizeLt - nSizeSp;
+
+ long nTabSize = 0;
+ if (bTabControl)
+ {
+ // pending relative tab bar width from extended document options
+ if( mfPendingTabBarWidth >= 0.0 )
+ {
+ SetRelTabBarWidth( mfPendingTabBarWidth );
+ mfPendingTabBarWidth = -1.0;
+ }
+
+ nTabSize = pTabControl->GetSizePixel().Width()-nOverlap;
+
+ if ( aViewData.GetHSplitMode() != SC_SPLIT_FIX ) // bei linkem Scrollbar
+ {
+ if (nTabSize > nSizeLt-SC_SCROLLBAR_MIN) nTabSize = nSizeLt-SC_SCROLLBAR_MIN;
+ if (nTabSize < SC_TABBAR_MIN) nTabSize = SC_TABBAR_MIN;
+ nSizeLt -= nTabSize;
+ }
+ else // bei rechtem Scrollbar
+ {
+ if (nTabSize > nSizeRt-SC_SCROLLBAR_MIN) nTabSize = nSizeRt-SC_SCROLLBAR_MIN;
+ if (nTabSize < SC_TABBAR_MIN) nTabSize = SC_TABBAR_MIN;
+ nSizeRt -= nTabSize;
+ }
+ }
+
+ lcl_SetPosSize( *pTabControl, Point(nPosX-nOverlap, nPosY+nSizeY),
+ Size(nTabSize+nOverlap, nBarY), nTotalWidth, bLayoutRTL );
+ pTabControl->SetSheetLayoutRTL( bLayoutRTL );
+
+ lcl_SetPosSize( aHScrollLeft, Point(nPosX+nTabSize-nOverlap, nPosY+nSizeY),
+ Size(nSizeLt+2*nOverlap, nBarY), nTotalWidth, bLayoutRTL );
+ lcl_SetPosSize( *pHSplitter, Point( nPosX+nTabSize+nSizeLt, nPosY+nSizeY ),
+ Size( nSizeSp, nBarY ), nTotalWidth, bLayoutRTL );
+ lcl_SetPosSize( aHScrollRight, Point(nPosX+nTabSize+nSizeLt+nSizeSp-nOverlap,
+ nPosY+nSizeY),
+ Size(nSizeRt+2*nOverlap, nBarY), nTotalWidth, bLayoutRTL );
+
+ // SetDragRectPixel is done below
+ }
+
+ if (bVScroll) // Scrollbars vertikal
+ {
+ long nSizeUp = 0; // upper scroll bar
+ long nSizeSp = 0; // splitter
+ long nSizeDn; // unterer Scrollbar
+
+ switch (aViewData.GetVSplitMode())
+ {
+ case SC_SPLIT_NONE:
+ nSizeUp = 0;
+ nSizeSp = nSplitSizeY;
+ break;
+ case SC_SPLIT_NORMAL:
+ nSizeUp = aViewData.GetVSplitPos();
+ nSizeSp = nSplitSizeY;
+ break;
+ case SC_SPLIT_FIX:
+ nSizeUp = 0;
+ nSizeSp = 0;
+ break;
+ }
+ nSizeDn = nSizeY - nSizeUp - nSizeSp;
+
+ lcl_SetPosSize( aVScrollTop, Point(nPosX+nSizeX, nPosY-nOverlap),
+ Size(nBarX,nSizeUp+2*nOverlap), nTotalWidth, bLayoutRTL );
+ lcl_SetPosSize( *pVSplitter, Point( nPosX+nSizeX, nPosY+nSizeUp ),
+ Size( nBarX, nSizeSp ), nTotalWidth, bLayoutRTL );
+ lcl_SetPosSize( aVScrollBottom, Point(nPosX+nSizeX,
+ nPosY+nSizeUp+nSizeSp-nOverlap),
+ Size(nBarX, nSizeDn+2*nOverlap), nTotalWidth, bLayoutRTL );
+
+ // SetDragRectPixel is done below
+ }
+ }
+
+ // SetDragRectPixel auch ohne Scrollbars etc., wenn schon gesplittet ist
+ if ( bHScroll || aViewData.GetHSplitMode() != SC_SPLIT_NONE )
+ pHSplitter->SetDragRectPixel(
+ Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin );
+ if ( bVScroll || aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ pVSplitter->SetDragRectPixel(
+ Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin );
+
+ if (bTabControl && ! bHScroll )
+ {
+ nBarY = aHScrollLeft.GetSizePixel().Height();
+ nBarX = aVScrollBottom.GetSizePixel().Width();
+
+ nSize1 = nSizeX + nOverlap;
+
+ long nTabSize = nSize1;
+ if (nTabSize < 0) nTabSize = 0;
+
+ lcl_SetPosSize( *pTabControl, Point(nPosX-nOverlap, nPosY+nSizeY-nBarY),
+ Size(nTabSize+nOverlap, nBarY), nTotalWidth, bLayoutRTL );
+ nSizeY -= nBarY - nOverlap;
+ lcl_SetPosSize( aScrollBarBox, Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ),
+ nTotalWidth, bLayoutRTL );
+
+ if( bVScroll )
+ {
+ Size aVScrSize = aVScrollBottom.GetSizePixel();
+ aVScrSize.Height() -= nBarY;
+ aVScrollBottom.SetSizePixel( aVScrSize );
+ }
+ }
+
+ nOutPosX = nPosX;
+ nOutPosY = nPosY;
+
+ // Outline-Controls
+ if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
+ {
+ nOutlineX = pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
+ nSizeX -= nOutlineX;
+ nPosX += nOutlineX;
+ }
+ if (bHOutline && pColOutline[SC_SPLIT_LEFT])
+ {
+ nOutlineY = pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
+ nSizeY -= nOutlineY;
+ nPosY += nOutlineY;
+ }
+
+ if (bHeaders) // Spalten/Zeilen-Header
+ {
+ nBarX = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
+ nBarY = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
+ nSizeX -= nBarX;
+ nSizeY -= nBarY;
+ nPosX += nBarX;
+ nPosY += nBarY;
+ }
+ else
+ nBarX = nBarY = 0;
+
+ //
+ // Splitter auswerten
+ //
+
+ long nLeftSize = nSizeX;
+ long nRightSize = 0;
+ long nTopSize = 0;
+ long nBottomSize = nSizeY;
+ long nSplitPosX = nPosX;
+ long nSplitPosY = nPosY;
+
+ if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
+ {
+ long nSplitHeight = rSize.Height();
+ if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
+ {
+ // Fixier-Splitter nicht mit Scrollbar/TabBar ueberlappen lassen
+ if ( bHScroll )
+ nSplitHeight -= aHScrollLeft.GetSizePixel().Height();
+ else if ( bTabControl && pTabControl )
+ nSplitHeight -= pTabControl->GetSizePixel().Height();
+ }
+ nSplitPosX = aViewData.GetHSplitPos();
+ lcl_SetPosSize( *pHSplitter,
+ Point( nSplitPosX, nOutPosY ), Size( nSplitSizeX, nSplitHeight ), nTotalWidth, bLayoutRTL );
+ nLeftSize = nSplitPosX - nPosX;
+ nSplitPosX += nSplitSizeX;
+ nRightSize = nSizeX - nLeftSize - nSplitSizeX;
+ }
+ if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ {
+ long nSplitWidth = rSize.Width();
+ if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && bVScroll )
+ nSplitWidth -= aVScrollBottom.GetSizePixel().Width();
+ nSplitPosY = aViewData.GetVSplitPos();
+ lcl_SetPosSize( *pVSplitter,
+ Point( nOutPosX, nSplitPosY ), Size( nSplitWidth, nSplitSizeY ), nTotalWidth, bLayoutRTL );
+ nTopSize = nSplitPosY - nPosY;
+ nSplitPosY += nSplitSizeY;
+ nBottomSize = nSizeY - nTopSize - nSplitSizeY;
+ }
+
+ // ShowHide fuer pColOutline / pRowOutline passiert in UpdateShow
+
+ if (bHOutline) // Outline-Controls
+ {
+ if (pColOutline[SC_SPLIT_LEFT])
+ {
+ pColOutline[SC_SPLIT_LEFT]->SetHeaderSize( nBarX );
+ lcl_SetPosSize( *pColOutline[SC_SPLIT_LEFT],
+ Point(nPosX-nBarX,nOutPosY), Size(nLeftSize+nBarX,nOutlineY), nTotalWidth, bLayoutRTL );
+ }
+ if (pColOutline[SC_SPLIT_RIGHT])
+ {
+ pColOutline[SC_SPLIT_RIGHT]->SetHeaderSize( 0 ); // always call to update RTL flag
+ lcl_SetPosSize( *pColOutline[SC_SPLIT_RIGHT],
+ Point(nSplitPosX,nOutPosY), Size(nRightSize,nOutlineY), nTotalWidth, bLayoutRTL );
+ }
+ }
+ if (bVOutline)
+ {
+ if (nTopSize)
+ {
+ if (pRowOutline[SC_SPLIT_TOP] && pRowOutline[SC_SPLIT_BOTTOM])
+ {
+ pRowOutline[SC_SPLIT_TOP]->SetHeaderSize( nBarY );
+ lcl_SetPosSize( *pRowOutline[SC_SPLIT_TOP],
+ Point(nOutPosX,nPosY-nBarY), Size(nOutlineX,nTopSize+nBarY), nTotalWidth, bLayoutRTL );
+ pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( 0 );
+ lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM],
+ Point(nOutPosX,nSplitPosY), Size(nOutlineX,nBottomSize), nTotalWidth, bLayoutRTL );
+ }
+ }
+ else if (pRowOutline[SC_SPLIT_BOTTOM])
+ {
+ pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( nBarY );
+ lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM],
+ Point(nOutPosX,nSplitPosY-nBarY), Size(nOutlineX,nBottomSize+nBarY), nTotalWidth, bLayoutRTL );
+ }
+ }
+ if (bHOutline && bVOutline)
+ {
+ lcl_SetPosSize( aTopButton, Point(nOutPosX,nOutPosY), Size(nOutlineX,nOutlineY), nTotalWidth, bLayoutRTL );
+ aTopButton.Show();
+ }
+ else
+ aTopButton.Hide();
+
+ if (bHeaders) // Spalten/Zeilen-Header
+ {
+ lcl_SetPosSize( *pColBar[SC_SPLIT_LEFT],
+ Point(nPosX,nPosY-nBarY), Size(nLeftSize,nBarY), nTotalWidth, bLayoutRTL );
+ if (pColBar[SC_SPLIT_RIGHT])
+ lcl_SetPosSize( *pColBar[SC_SPLIT_RIGHT],
+ Point(nSplitPosX,nPosY-nBarY), Size(nRightSize,nBarY), nTotalWidth, bLayoutRTL );
+
+ if (pRowBar[SC_SPLIT_TOP])
+ lcl_SetPosSize( *pRowBar[SC_SPLIT_TOP],
+ Point(nPosX-nBarX,nPosY), Size(nBarX,nTopSize), nTotalWidth, bLayoutRTL );
+ lcl_SetPosSize( *pRowBar[SC_SPLIT_BOTTOM],
+ Point(nPosX-nBarX,nSplitPosY), Size(nBarX,nBottomSize), nTotalWidth, bLayoutRTL );
+
+ lcl_SetPosSize( aCornerButton, Point(nPosX-nBarX,nPosY-nBarY), Size(nBarX,nBarY), nTotalWidth, bLayoutRTL );
+ aCornerButton.Show();
+ pColBar[SC_SPLIT_LEFT]->Show();
+ pRowBar[SC_SPLIT_BOTTOM]->Show();
+ }
+ else
+ {
+ aCornerButton.Hide();
+ pColBar[SC_SPLIT_LEFT]->Hide(); // immer da
+ pRowBar[SC_SPLIT_BOTTOM]->Hide();
+ }
+
+
+ // Grid-Windows
+
+ if (bInner)
+ {
+ long nInnerPosX = bLayoutRTL ? ( nTotalWidth - nPosX - nLeftSize ) : nPosX;
+ pGridWin[SC_SPLIT_BOTTOMLEFT]->SetPosPixel( Point(nInnerPosX,nSplitPosY) );
+ }
+ else
+ {
+ lcl_SetPosSize( *pGridWin[SC_SPLIT_BOTTOMLEFT],
+ Point(nPosX,nSplitPosY), Size(nLeftSize,nBottomSize), nTotalWidth, bLayoutRTL );
+ if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
+ lcl_SetPosSize( *pGridWin[SC_SPLIT_BOTTOMRIGHT],
+ Point(nSplitPosX,nSplitPosY), Size(nRightSize,nBottomSize), nTotalWidth, bLayoutRTL );
+ if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ lcl_SetPosSize( *pGridWin[SC_SPLIT_TOPLEFT],
+ Point(nPosX,nPosY), Size(nLeftSize,nTopSize), nTotalWidth, bLayoutRTL );
+ if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE && aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ lcl_SetPosSize( *pGridWin[SC_SPLIT_TOPRIGHT],
+ Point(nSplitPosX,nPosY), Size(nRightSize,nTopSize), nTotalWidth, bLayoutRTL );
+ }
+
+ //
+ // Scrollbars updaten
+ //
+
+ if (!bInUpdateHeader)
+ {
+ UpdateScrollBars(); // Scrollbars nicht beim Scrollen neu setzen
+ UpdateHeaderWidth();
+
+ InterpretVisible(); // #69343# have everything calculated before painting
+ }
+
+ if (bHasHint)
+ TestHintWindow(); // neu positionieren
+
+ UpdateVarZoom(); // update variable zoom types (after resizing GridWindows)
+
+ if (aViewData.GetViewShell()->HasAccessibilityObjects())
+ aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_WINDOWRESIZED));
+}
+
+void ScTabView::UpdateVarZoom()
+{
+ // update variable zoom types
+
+ SvxZoomType eZoomType = GetZoomType();
+ if ( eZoomType != SVX_ZOOM_PERCENT && !bInZoomUpdate )
+ {
+ bInZoomUpdate = sal_True;
+ const Fraction& rOldX = GetViewData()->GetZoomX();
+ const Fraction& rOldY = GetViewData()->GetZoomY();
+ long nOldPercent = ( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator();
+ sal_uInt16 nNewZoom = CalcZoom( eZoomType, (sal_uInt16)nOldPercent );
+ Fraction aNew( nNewZoom, 100 );
+
+ if ( aNew != rOldX || aNew != rOldY )
+ {
+ SetZoom( aNew, aNew, sal_False ); // always separately per sheet
+ PaintGrid();
+ PaintTop();
+ PaintLeft();
+ aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
+ aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
+ }
+ bInZoomUpdate = sal_False;
+ }
+}
+
+void ScTabView::UpdateFixPos()
+{
+ sal_Bool bResize = sal_False;
+ if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
+ if (aViewData.UpdateFixX())
+ bResize = sal_True;
+ if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
+ if (aViewData.UpdateFixY())
+ bResize = sal_True;
+ if (bResize)
+ RepeatResize(sal_False);
+}
+
+void ScTabView::RepeatResize( sal_Bool bUpdateFix )
+{
+ if ( bUpdateFix )
+ {
+ ScSplitMode eHSplit = aViewData.GetHSplitMode();
+ ScSplitMode eVSplit = aViewData.GetVSplitMode();
+
+ // #i46796# UpdateFixX / UpdateFixY uses GetGridOffset, which requires the
+ // outline windows to be available. So UpdateShow has to be called before
+ // (also called from DoResize).
+ if ( eHSplit == SC_SPLIT_FIX || eVSplit == SC_SPLIT_FIX )
+ UpdateShow();
+
+ if ( eHSplit == SC_SPLIT_FIX )
+ aViewData.UpdateFixX();
+ if ( eVSplit == SC_SPLIT_FIX )
+ aViewData.UpdateFixY();
+ }
+
+ DoResize( aBorderPos, aFrameSize );
+
+ //! Border muss neu gesetzt werden ???
+}
+
+void ScTabView::GetBorderSize( SvBorder& rBorder, const Size& /* rSize */ )
+{
+ sal_Bool bScrollBars = aViewData.IsVScrollMode();
+ sal_Bool bHeaders = aViewData.IsHeaderMode();
+ sal_Bool bOutlMode = aViewData.IsOutlineMode();
+ sal_Bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
+ sal_Bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
+ sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
+
+ rBorder = SvBorder();
+
+ if (bScrollBars) // Scrollbars horizontal oder vertikal
+ {
+ rBorder.Right() += aVScrollBottom.GetSizePixel().Width();
+ rBorder.Bottom() += aHScrollLeft.GetSizePixel().Height();
+ }
+
+ // Outline-Controls
+ if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
+ rBorder.Left() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
+ if (bHOutline && pColOutline[SC_SPLIT_LEFT])
+ rBorder.Top() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
+
+ if (bHeaders) // Spalten/Zeilen-Header
+ {
+ rBorder.Left() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
+ rBorder.Top() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
+ }
+
+ if ( bLayoutRTL )
+ ::std::swap( rBorder.Left(), rBorder.Right() );
+}
+
+IMPL_LINK( ScTabView, TabBarResize, void*, EMPTYARG )
+{
+ sal_Bool bHScrollMode = aViewData.IsHScrollMode();
+
+ // Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden:
+ SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode();
+ if ( eMode == SCROLLING_NO )
+ bHScrollMode = sal_False;
+ else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO ) //! Auto ???
+ bHScrollMode = sal_True;
+
+ if( bHScrollMode )
+ {
+ const long nOverlap = 0; // ScrollBar::GetWindowOverlapPixel();
+ long nSize = pTabControl->GetSplitSize();
+
+ if (aViewData.GetHSplitMode() != SC_SPLIT_FIX)
+ {
+ long nMax = pHSplitter->GetPosPixel().X();
+ if( pTabControl->IsEffectiveRTL() )
+ nMax = pFrameWin->GetSizePixel().Width() - nMax;
+ --nMax;
+ if (nSize>nMax) nSize = nMax;
+ }
+
+ if ( nSize != pTabControl->GetSizePixel().Width() )
+ {
+ pTabControl->SetSizePixel( Size( nSize+nOverlap,
+ pTabControl->GetSizePixel().Height() ) );
+ RepeatResize();
+ }
+ }
+
+ return 0;
+}
+
+void ScTabView::SetTabBarWidth( long nNewWidth )
+{
+ Size aSize = pTabControl->GetSizePixel();
+
+ if ( aSize.Width() != nNewWidth )
+ {
+ aSize.Width() = nNewWidth;
+ pTabControl->SetSizePixel( aSize );
+ }
+}
+
+void ScTabView::SetRelTabBarWidth( double fRelTabBarWidth )
+{
+ if( (0.0 <= fRelTabBarWidth) && (fRelTabBarWidth <= 1.0) )
+ if( long nFrameWidth = pFrameWin->GetSizePixel().Width() )
+ SetTabBarWidth( static_cast< long >( fRelTabBarWidth * nFrameWidth + 0.5 ) );
+}
+
+void ScTabView::SetPendingRelTabBarWidth( double fRelTabBarWidth )
+{
+ mfPendingTabBarWidth = fRelTabBarWidth;
+ SetRelTabBarWidth( fRelTabBarWidth );
+}
+
+long ScTabView::GetTabBarWidth() const
+{
+ return pTabControl->GetSizePixel().Width();
+}
+
+double ScTabView::GetRelTabBarWidth() const
+{
+ if( long nFrameWidth = pFrameWin->GetSizePixel().Width() )
+ return static_cast< double >( GetTabBarWidth() ) / nFrameWidth;
+ return 0.0;
+}
+
+double ScTabView::GetPendingRelTabBarWidth() const
+{
+ return mfPendingTabBarWidth;
+}
+
+Window* ScTabView::GetActiveWin()
+{
+ ScSplitPos ePos = aViewData.GetActivePart();
+ DBG_ASSERT(pGridWin[ePos],"kein aktives Fenster");
+ return pGridWin[ePos];
+}
+
+Window* ScTabView::GetWindowByPos( ScSplitPos ePos )
+{
+ return pGridWin[ePos];
+}
+
+void ScTabView::SetActivePointer( const Pointer& rPointer )
+{
+ for (sal_uInt16 i=0; i<4; i++)
+ if (pGridWin[i])
+ pGridWin[i]->SetPointer( rPointer );
+
+/* ScSplitPos ePos = aViewData.GetActivePart();
+ if (pGridWin[ePos])
+ pGridWin[ePos]->SetPointer( rPointer );
+*/
+}
+
+//UNUSED2008-05 void ScTabView::SetActivePointer( const ResId& )
+//UNUSED2008-05 {
+//UNUSED2008-05 DBG_ERRORFILE( "keine Pointer mit ResId!" );
+//UNUSED2008-05 }
+
+void ScTabView::ActiveGrabFocus()
+{
+ ScSplitPos ePos = aViewData.GetActivePart();
+ if (pGridWin[ePos])
+ pGridWin[ePos]->GrabFocus();
+}
+
+//UNUSED2008-05 void ScTabView::ActiveCaptureMouse()
+//UNUSED2008-05 {
+//UNUSED2008-05 ScSplitPos ePos = aViewData.GetActivePart();
+//UNUSED2008-05 if (pGridWin[ePos])
+//UNUSED2008-05 pGridWin[ePos]->CaptureMouse();
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void ScTabView::ActiveReleaseMouse()
+//UNUSED2008-05 {
+//UNUSED2008-05 ScSplitPos ePos = aViewData.GetActivePart();
+//UNUSED2008-05 if (pGridWin[ePos])
+//UNUSED2008-05 pGridWin[ePos]->ReleaseMouse();
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 Point ScTabView::ActivePixelToLogic( const Point& rDevicePoint )
+//UNUSED2008-05 {
+//UNUSED2008-05 ScSplitPos ePos = aViewData.GetActivePart();
+//UNUSED2008-05 if (pGridWin[ePos])
+//UNUSED2008-05 return pGridWin[ePos]->PixelToLogic(rDevicePoint);
+//UNUSED2008-05 else
+//UNUSED2008-05 return Point();
+//UNUSED2008-05 }
+
+ScSplitPos ScTabView::FindWindow( Window* pWindow ) const
+{
+ ScSplitPos eVal = SC_SPLIT_BOTTOMLEFT; // Default
+ for (sal_uInt16 i=0; i<4; i++)
+ if ( pGridWin[i] == pWindow )
+ eVal = (ScSplitPos) i;
+
+ return eVal;
+}
+
+Point ScTabView::GetGridOffset() const
+{
+ Point aPos;
+
+ // Groessen hier wie in DoResize
+
+ sal_Bool bHeaders = aViewData.IsHeaderMode();
+ sal_Bool bOutlMode = aViewData.IsOutlineMode();
+ sal_Bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
+ sal_Bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
+
+ // Outline-Controls
+ if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
+ aPos.X() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
+ if (bHOutline && pColOutline[SC_SPLIT_LEFT])
+ aPos.Y() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
+
+ if (bHeaders) // Spalten/Zeilen-Header
+ {
+ if (pRowBar[SC_SPLIT_BOTTOM])
+ aPos.X() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
+ if (pColBar[SC_SPLIT_LEFT])
+ aPos.Y() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
+ }
+
+ return aPos;
+}
+
+// --- Scroll-Bars --------------------------------------------------------
+
+sal_Bool ScTabView::ScrollCommand( const CommandEvent& rCEvt, ScSplitPos ePos )
+{
+ HideNoteMarker();
+
+ sal_Bool bDone = sal_False;
+ const CommandWheelData* pData = rCEvt.GetWheelData();
+ if ( pData && pData->GetMode() == COMMAND_WHEEL_ZOOM )
+ {
+ if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() )
+ {
+ // for ole inplace editing, the scale is defined by the visarea and client size
+ // and can't be changed directly
+
+ const Fraction& rOldY = aViewData.GetZoomY();
+ long nOld = (long)(( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator());
+ long nNew = nOld;
+ if ( pData->GetDelta() < 0 )
+ nNew = Max( (long) MINZOOM, (long)( nOld - SC_DELTA_ZOOM ) );
+ else
+ nNew = Min( (long) MAXZOOM, (long)( nOld + SC_DELTA_ZOOM ) );
+
+ if ( nNew != nOld )
+ {
+ // scroll wheel doesn't set the AppOptions default
+
+ sal_Bool bSyncZoom = SC_MOD()->GetAppOptions().GetSynchronizeZoom();
+ SetZoomType( SVX_ZOOM_PERCENT, bSyncZoom );
+ Fraction aFract( nNew, 100 );
+ SetZoom( aFract, aFract, bSyncZoom );
+ PaintGrid();
+ PaintTop();
+ PaintLeft();
+ aViewData.GetBindings().Invalidate( SID_ATTR_ZOOM );
+ aViewData.GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
+ }
+
+ bDone = sal_True;
+ }
+ }
+ else
+ {
+ ScHSplitPos eHPos = WhichH(ePos);
+ ScVSplitPos eVPos = WhichV(ePos);
+ ScrollBar* pHScroll = ( eHPos == SC_SPLIT_LEFT ) ? &aHScrollLeft : &aHScrollRight;
+ ScrollBar* pVScroll = ( eVPos == SC_SPLIT_TOP ) ? &aVScrollTop : &aVScrollBottom;
+ if ( pGridWin[ePos] )
+ bDone = pGridWin[ePos]->HandleScrollCommand( rCEvt, pHScroll, pVScroll );
+ }
+ return bDone;
+}
+
+IMPL_LINK( ScTabView, EndScrollHdl, ScrollBar*, pScroll )
+{
+ sal_Bool bOnlineScroll = sal_True; //! Optionen
+
+ if ( bDragging )
+ {
+ if ( bOnlineScroll ) // nur Ranges aktualisieren
+ UpdateScrollBars();
+ else
+ {
+ long nScrollMin = 0; // RangeMin simulieren
+ if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight )
+ nScrollMin = aViewData.GetFixPosX();
+ if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom )
+ nScrollMin = aViewData.GetFixPosY();
+
+ if ( pScroll == &aHScrollLeft || pScroll == &aHScrollRight )
+ {
+ sal_Bool bMirror = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ) != Application::GetSettings().GetLayoutRTL();
+ ScHSplitPos eWhich = (pScroll == &aHScrollLeft) ? SC_SPLIT_LEFT : SC_SPLIT_RIGHT;
+ long nDelta = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin - aViewData.GetPosX(eWhich);
+ if (nDelta) ScrollX( nDelta, eWhich );
+ }
+ else // VScroll...
+ {
+ ScVSplitPos eWhich = (pScroll == &aVScrollTop) ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM;
+ long nDelta = GetScrollBarPos( *pScroll, sal_False ) + nScrollMin - aViewData.GetPosY(eWhich);
+ if (nDelta) ScrollY( nDelta, eWhich );
+ }
+ }
+ bDragging = sal_False;
+ }
+ return 0;
+}
+
+IMPL_LINK( ScTabView, ScrollHdl, ScrollBar*, pScroll )
+{
+ sal_Bool bOnlineScroll = sal_True; //! Optionen
+
+ sal_Bool bHoriz = ( pScroll == &aHScrollLeft || pScroll == &aHScrollRight );
+ long nViewPos;
+ if ( bHoriz )
+ nViewPos = aViewData.GetPosX( (pScroll == &aHScrollLeft) ?
+ SC_SPLIT_LEFT : SC_SPLIT_RIGHT );
+ else
+ nViewPos = aViewData.GetPosY( (pScroll == &aVScrollTop) ?
+ SC_SPLIT_TOP : SC_SPLIT_BOTTOM );
+
+ sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
+ sal_Bool bMirror = bHoriz && (bLayoutRTL != Application::GetSettings().GetLayoutRTL());
+
+ ScrollType eType = pScroll->GetType();
+ if ( eType == SCROLL_DRAG )
+ {
+ if (!bDragging)
+ {
+ bDragging = sal_True;
+ nPrevDragPos = nViewPos;
+ }
+
+ // Scroll-Position anzeigen
+ // (nur QuickHelp, in der Statuszeile gibt es keinen Eintrag dafuer)
+
+ if (Help::IsQuickHelpEnabled())
+ {
+ Size aSize = pScroll->GetSizePixel();
+
+ /* Convert scrollbar mouse position to screen position. If RTL
+ mode of scrollbar differs from RTL mode of its parent, then the
+ direct call to Window::OutputToNormalizedScreenPixel() will
+ give unusable results, because calcualtion of screen position
+ is based on parent orientation and expects equal orientation of
+ the child position. Need to mirror mouse position before. */
+ Point aMousePos = pScroll->GetPointerPosPixel();
+ if( pScroll->IsRTLEnabled() != pScroll->GetParent()->IsRTLEnabled() )
+ aMousePos.X() = aSize.Width() - aMousePos.X() - 1;
+ aMousePos = pScroll->OutputToNormalizedScreenPixel( aMousePos );
+
+ // convert top-left position of scrollbar to screen position
+ Point aPos = pScroll->OutputToNormalizedScreenPixel( Point() );
+
+ // get scrollbar scroll position for help text (row number/column name)
+ long nScrollMin = 0; // RangeMin simulieren
+ if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight )
+ nScrollMin = aViewData.GetFixPosX();
+ if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom )
+ nScrollMin = aViewData.GetFixPosY();
+ long nScrollPos = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin;
+
+ String aHelpStr;
+ Rectangle aRect;
+ sal_uInt16 nAlign;
+ if (bHoriz)
+ {
+ aHelpStr = ScGlobal::GetRscString(STR_COLUMN);
+ aHelpStr += ' ';
+ aHelpStr += ScColToAlpha((SCCOL) nScrollPos);
+
+ aRect.Left() = aMousePos.X();
+ aRect.Top() = aPos.Y() - 4;
+ nAlign = QUICKHELP_BOTTOM|QUICKHELP_CENTER;
+ }
+ else
+ {
+ aHelpStr = ScGlobal::GetRscString(STR_ROW);
+ aHelpStr += ' ';
+ aHelpStr += String::CreateFromInt32(nScrollPos + 1);
+
+ // show quicktext always inside sheet area
+ aRect.Left() = bLayoutRTL ? (aPos.X() + aSize.Width() + 8) : (aPos.X() - 8);
+ aRect.Top() = aMousePos.Y();
+ nAlign = (bLayoutRTL ? QUICKHELP_LEFT : QUICKHELP_RIGHT) | QUICKHELP_VCENTER;
+ }
+ aRect.Right() = aRect.Left();
+ aRect.Bottom() = aRect.Top();
+
+ Help::ShowQuickHelp(pScroll->GetParent(), aRect, aHelpStr, nAlign);
+ }
+ }
+
+ if ( bOnlineScroll || eType != SCROLL_DRAG )
+ {
+ if ( bMirror )
+ {
+ // change scroll type so visible/previous cells calculation below remains the same
+ switch ( eType )
+ {
+ case SCROLL_LINEUP: eType = SCROLL_LINEDOWN; break;
+ case SCROLL_LINEDOWN: eType = SCROLL_LINEUP; break;
+ case SCROLL_PAGEUP: eType = SCROLL_PAGEDOWN; break;
+ case SCROLL_PAGEDOWN: eType = SCROLL_PAGEUP; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+ long nDelta = pScroll->GetDelta();
+ switch ( eType )
+ {
+ case SCROLL_LINEUP:
+ nDelta = -1;
+ break;
+ case SCROLL_LINEDOWN:
+ nDelta = 1;
+ break;
+ case SCROLL_PAGEUP:
+ if ( pScroll == &aHScrollLeft ) nDelta = -(long) aViewData.PrevCellsX( SC_SPLIT_LEFT );
+ if ( pScroll == &aHScrollRight ) nDelta = -(long) aViewData.PrevCellsX( SC_SPLIT_RIGHT );
+ if ( pScroll == &aVScrollTop ) nDelta = -(long) aViewData.PrevCellsY( SC_SPLIT_TOP );
+ if ( pScroll == &aVScrollBottom ) nDelta = -(long) aViewData.PrevCellsY( SC_SPLIT_BOTTOM );
+ if (nDelta==0) nDelta=-1;
+ break;
+ case SCROLL_PAGEDOWN:
+ if ( pScroll == &aHScrollLeft ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_LEFT );
+ if ( pScroll == &aHScrollRight ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_RIGHT );
+ if ( pScroll == &aVScrollTop ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_TOP );
+ if ( pScroll == &aVScrollBottom ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_BOTTOM );
+ if (nDelta==0) nDelta=1;
+ break;
+ case SCROLL_DRAG:
+ {
+ // nur in die richtige Richtung scrollen, nicht um ausgeblendete
+ // Bereiche herumzittern
+
+ long nScrollMin = 0; // RangeMin simulieren
+ if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight )
+ nScrollMin = aViewData.GetFixPosX();
+ if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom )
+ nScrollMin = aViewData.GetFixPosY();
+
+ long nScrollPos = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin;
+ nDelta = nScrollPos - nViewPos;
+ if ( nScrollPos > nPrevDragPos )
+ {
+ if (nDelta<0) nDelta=0;
+ }
+ else if ( nScrollPos < nPrevDragPos )
+ {
+ if (nDelta>0) nDelta=0;
+ }
+ else
+ nDelta = 0;
+ nPrevDragPos = nScrollPos;
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ if (nDelta)
+ {
+ sal_Bool bUpdate = ( eType != SCROLL_DRAG ); // bei Drag die Ranges nicht aendern
+ if ( bHoriz )
+ ScrollX( nDelta, (pScroll == &aHScrollLeft) ? SC_SPLIT_LEFT : SC_SPLIT_RIGHT, bUpdate );
+ else
+ ScrollY( nDelta, (pScroll == &aVScrollTop) ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM, bUpdate );
+ }
+ }
+
+ return 0;
+}
+
+void ScTabView::ScrollX( long nDeltaX, ScHSplitPos eWhich, sal_Bool bUpdBars )
+{
+ sal_Bool bHasHint = ( pInputHintWindow != NULL );
+ if (bHasHint)
+ RemoveHintWindow();
+
+ SCCOL nOldX = aViewData.GetPosX(eWhich);
+ SCsCOL nNewX = static_cast<SCsCOL>(nOldX) + static_cast<SCsCOL>(nDeltaX);
+ if ( nNewX < 0 )
+ {
+ nDeltaX -= nNewX;
+ nNewX = 0;
+ }
+ if ( nNewX > MAXCOL )
+ {
+ nDeltaX -= nNewX - MAXCOL;
+ nNewX = MAXCOL;
+ }
+
+ SCsCOL nDir = ( nDeltaX > 0 ) ? 1 : -1;
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ while ( pDoc->ColHidden(nNewX, nTab) &&
+ nNewX+nDir >= 0 && nNewX+nDir <= MAXCOL )
+ nNewX = sal::static_int_cast<SCsCOL>( nNewX + nDir );
+
+ // Fixierung
+
+ if (aViewData.GetHSplitMode() == SC_SPLIT_FIX)
+ {
+ if (eWhich == SC_SPLIT_LEFT)
+ nNewX = static_cast<SCsCOL>(nOldX); // links immer stehenlassen
+ else
+ {
+ SCsCOL nFixX = static_cast<SCsCOL>(aViewData.GetFixPosX());
+ if (nNewX < nFixX)
+ nNewX = nFixX;
+ }
+ }
+ if (nNewX == static_cast<SCsCOL>(nOldX))
+ return;
+
+ HideAllCursors();
+
+ if ( nNewX >= 0 && nNewX <= MAXCOL && nDeltaX )
+ {
+ SCCOL nTrackX = std::max( nOldX, static_cast<SCCOL>(nNewX) );
+
+ // Mit VCL wirkt Update() im Moment immer auf alle Fenster, beim Update
+ // nach dem Scrollen des GridWindow's wuerde darum der Col-/RowBar evtl.
+ // mit schon geaenderter Pos. gepainted werden -
+ // darum vorher einmal Update am Col-/RowBar
+
+ if (pColBar[eWhich])
+ pColBar[eWhich]->Update();
+
+ long nOldPos = aViewData.GetScrPos( nTrackX, 0, eWhich ).X();
+ aViewData.SetPosX( eWhich, static_cast<SCCOL>(nNewX) );
+ long nDiff = aViewData.GetScrPos( nTrackX, 0, eWhich ).X() - nOldPos;
+
+ if ( eWhich==SC_SPLIT_LEFT )
+ {
+ pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( nDiff, 0 );
+ if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( nDiff, 0 );
+ }
+ else
+ {
+ pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( nDiff, 0 );
+ if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( nDiff, 0 );
+ }
+ if (pColBar[eWhich]) { pColBar[eWhich]->Scroll( nDiff,0 ); pColBar[eWhich]->Update(); }
+ if (pColOutline[eWhich]) pColOutline[eWhich]->ScrollPixel( nDiff );
+ if (bUpdBars)
+ UpdateScrollBars();
+ }
+
+ if (nDeltaX==1 || nDeltaX==-1)
+ pGridWin[aViewData.GetActivePart()]->Update();
+
+ ShowAllCursors();
+
+ SetNewVisArea(); // MapMode muss schon gesetzt sein
+
+ if (bHasHint)
+ TestHintWindow(); // neu positionieren
+}
+
+void ScTabView::ScrollY( long nDeltaY, ScVSplitPos eWhich, sal_Bool bUpdBars )
+{
+ sal_Bool bHasHint = ( pInputHintWindow != NULL );
+ if (bHasHint)
+ RemoveHintWindow();
+
+ SCROW nOldY = aViewData.GetPosY(eWhich);
+ SCsROW nNewY = static_cast<SCsROW>(nOldY) + static_cast<SCsROW>(nDeltaY);
+ if ( nNewY < 0 )
+ {
+ nDeltaY -= nNewY;
+ nNewY = 0;
+ }
+ if ( nNewY > MAXROW )
+ {
+ nDeltaY -= nNewY - MAXROW;
+ nNewY = MAXROW;
+ }
+
+ SCsROW nDir = ( nDeltaY > 0 ) ? 1 : -1;
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ while ( pDoc->RowHidden(nNewY, nTab) &&
+ nNewY+nDir >= 0 && nNewY+nDir <= MAXROW )
+ nNewY += nDir;
+
+ // Fixierung
+
+ if (aViewData.GetVSplitMode() == SC_SPLIT_FIX)
+ {
+ if (eWhich == SC_SPLIT_TOP)
+ nNewY = static_cast<SCsROW>(nOldY); // oben immer stehenlassen
+ else
+ {
+ SCsROW nFixY = static_cast<SCsROW>(aViewData.GetFixPosY());
+ if (nNewY < nFixY)
+ nNewY = nFixY;
+ }
+ }
+ if (nNewY == static_cast<SCsROW>(nOldY))
+ return;
+
+ HideAllCursors();
+
+ if ( nNewY >= 0 && nNewY <= MAXROW && nDeltaY )
+ {
+ SCROW nTrackY = std::max( nOldY, static_cast<SCROW>(nNewY) );
+
+ // Zeilenkoepfe anpassen vor dem eigentlichen Scrolling, damit nicht
+ // doppelt gepainted werden muss
+ // PosY darf dann auch noch nicht umgesetzt sein, neuen Wert uebergeben
+ SCROW nUNew = static_cast<SCROW>(nNewY);
+ UpdateHeaderWidth( &eWhich, &nUNew ); // Zeilenkoepfe anpassen
+
+ if (pRowBar[eWhich])
+ pRowBar[eWhich]->Update();
+
+ long nOldPos = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y();
+ aViewData.SetPosY( eWhich, static_cast<SCROW>(nNewY) );
+ long nDiff = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y() - nOldPos;
+
+ if ( eWhich==SC_SPLIT_TOP )
+ {
+ pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( 0, nDiff );
+ if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
+ pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( 0, nDiff );
+ }
+ else
+ {
+ pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( 0, nDiff );
+ if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
+ pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( 0, nDiff );
+ }
+ if (pRowBar[eWhich]) { pRowBar[eWhich]->Scroll( 0,nDiff ); pRowBar[eWhich]->Update(); }
+ if (pRowOutline[eWhich]) pRowOutline[eWhich]->ScrollPixel( nDiff );
+ if (bUpdBars)
+ UpdateScrollBars();
+ }
+
+ if (nDeltaY==1 || nDeltaY==-1)
+ pGridWin[aViewData.GetActivePart()]->Update();
+
+ ShowAllCursors();
+
+ SetNewVisArea(); // MapMode muss schon gesetzt sein
+
+ if (bHasHint)
+ TestHintWindow(); // neu positionieren
+}
+
+void ScTabView::ScrollLines( long nDeltaX, long nDeltaY )
+{
+ ScSplitPos eWhich = aViewData.GetActivePart();
+ if (nDeltaX)
+ ScrollX(nDeltaX,WhichH(eWhich));
+ if (nDeltaY)
+ ScrollY(nDeltaY,WhichV(eWhich));
+}
+
+SCROW lcl_LastVisible( ScViewData& rViewData )
+{
+ // wenn am Dokumentende viele Zeilen ausgeblendet sind (welcher Trottel macht sowas?),
+ // soll dadurch nicht auf breite Zeilenkoepfe geschaltet werden
+ //! als Member ans Dokument ???
+
+ ScDocument* pDoc = rViewData.GetDocument();
+ SCTAB nTab = rViewData.GetTabNo();
+
+ SCROW nVis = MAXROW;
+ while ( nVis > 0 && pDoc->GetRowHeight( nVis, nTab ) == 0 )
+ --nVis;
+ return nVis;
+}
+
+void ScTabView::UpdateHeaderWidth( const ScVSplitPos* pWhich, const SCROW* pPosY )
+{
+ if ( !pRowBar[SC_SPLIT_BOTTOM] || MAXROW < 10000 )
+ return;
+
+ SCROW nEndPos = MAXROW;
+ if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() )
+ {
+ // fuer OLE Inplace immer MAXROW
+
+ if ( pWhich && *pWhich == SC_SPLIT_BOTTOM && pPosY )
+ nEndPos = *pPosY;
+ else
+ nEndPos = aViewData.GetPosY( SC_SPLIT_BOTTOM );
+ nEndPos += aViewData.CellsAtY( nEndPos, 1, SC_SPLIT_BOTTOM, SC_SIZE_NONE ); // VisibleCellsY
+ if (nEndPos > MAXROW)
+ nEndPos = lcl_LastVisible( aViewData );
+
+ if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ {
+ SCROW nTopEnd;
+ if ( pWhich && *pWhich == SC_SPLIT_TOP && pPosY )
+ nTopEnd = *pPosY;
+ else
+ nTopEnd = aViewData.GetPosY( SC_SPLIT_TOP );
+ nTopEnd += aViewData.CellsAtY( nTopEnd, 1, SC_SPLIT_TOP, SC_SIZE_NONE );// VisibleCellsY
+ if (nTopEnd > MAXROW)
+ nTopEnd = lcl_LastVisible( aViewData );
+
+ if ( nTopEnd > nEndPos )
+ nEndPos = nTopEnd;
+ }
+ }
+
+ long nSmall = pRowBar[SC_SPLIT_BOTTOM]->GetSmallWidth();
+ long nBig = pRowBar[SC_SPLIT_BOTTOM]->GetBigWidth();
+ long nDiff = nBig - nSmall;
+
+ if (nEndPos>10000)
+ nEndPos = 10000;
+ else if (nEndPos<1) // avoid extra step at 0 (when only one row is visible)
+ nEndPos = 1;
+ long nWidth = nBig - ( 10000 - nEndPos ) * nDiff / 10000;
+
+ if ( nWidth != pRowBar[SC_SPLIT_BOTTOM]->GetWidth() && !bInUpdateHeader )
+ {
+ bInUpdateHeader = sal_True;
+
+ pRowBar[SC_SPLIT_BOTTOM]->SetWidth( nWidth );
+ if (pRowBar[SC_SPLIT_TOP])
+ pRowBar[SC_SPLIT_TOP]->SetWidth( nWidth );
+
+ RepeatResize();
+
+ // auf VCL gibt's Update ohne Ende (jedes Update gilt fuer alle Fenster)
+ //aCornerButton.Update(); // der bekommt sonst nie ein Update
+
+ bInUpdateHeader = sal_False;
+ }
+}
+
+inline void ShowHide( Window* pWin, sal_Bool bShow )
+{
+ DBG_ASSERT(pWin || !bShow, "Fenster ist nicht da");
+ if (pWin)
+ pWin->Show(bShow);
+}
+
+void ScTabView::UpdateShow()
+{
+ sal_Bool bHScrollMode = aViewData.IsHScrollMode();
+ sal_Bool bVScrollMode = aViewData.IsVScrollMode();
+ sal_Bool bTabMode = aViewData.IsTabMode();
+ sal_Bool bOutlMode = aViewData.IsOutlineMode();
+ sal_Bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
+ sal_Bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
+ sal_Bool bHeader = aViewData.IsHeaderMode();
+
+ sal_Bool bShowH = ( aViewData.GetHSplitMode() != SC_SPLIT_NONE );
+ sal_Bool bShowV = ( aViewData.GetVSplitMode() != SC_SPLIT_NONE );
+
+ // Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden:
+ SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode();
+ if ( eMode == SCROLLING_NO )
+ bHScrollMode = bVScrollMode = sal_False;
+ else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO ) //! Auto ???
+ bHScrollMode = bVScrollMode = sal_True;
+
+ if ( aViewData.GetDocShell()->IsPreview() )
+ bHScrollMode = bVScrollMode = bTabMode = bHeader = bOutlMode = bHOutline = bVOutline = sal_False;
+
+ //
+ // Windows anlegen
+ //
+
+ if (bShowH && !pGridWin[SC_SPLIT_BOTTOMRIGHT])
+ {
+ pGridWin[SC_SPLIT_BOTTOMRIGHT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_BOTTOMRIGHT );
+ DoAddWin( pGridWin[SC_SPLIT_BOTTOMRIGHT] );
+ }
+ if (bShowV && !pGridWin[SC_SPLIT_TOPLEFT])
+ {
+ pGridWin[SC_SPLIT_TOPLEFT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_TOPLEFT );
+ DoAddWin( pGridWin[SC_SPLIT_TOPLEFT] );
+ }
+ if (bShowH && bShowV && !pGridWin[SC_SPLIT_TOPRIGHT])
+ {
+ pGridWin[SC_SPLIT_TOPRIGHT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_TOPRIGHT );
+ DoAddWin( pGridWin[SC_SPLIT_TOPRIGHT] );
+ }
+
+ if (bHOutline && !pColOutline[SC_SPLIT_LEFT])
+ pColOutline[SC_SPLIT_LEFT] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_HOR, &aViewData, SC_SPLIT_BOTTOMLEFT );
+ if (bShowH && bHOutline && !pColOutline[SC_SPLIT_RIGHT])
+ pColOutline[SC_SPLIT_RIGHT] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_HOR, &aViewData, SC_SPLIT_BOTTOMRIGHT );
+
+ if (bVOutline && !pRowOutline[SC_SPLIT_BOTTOM])
+ pRowOutline[SC_SPLIT_BOTTOM] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_VER, &aViewData, SC_SPLIT_BOTTOMLEFT );
+ if (bShowV && bVOutline && !pRowOutline[SC_SPLIT_TOP])
+ pRowOutline[SC_SPLIT_TOP] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_VER, &aViewData, SC_SPLIT_TOPLEFT );
+
+ if (bShowH && bHeader && !pColBar[SC_SPLIT_RIGHT])
+ pColBar[SC_SPLIT_RIGHT] = new ScColBar( pFrameWin, &aViewData, SC_SPLIT_RIGHT,
+ &aHdrFunc, pHdrSelEng );
+ if (bShowV && bHeader && !pRowBar[SC_SPLIT_TOP])
+ pRowBar[SC_SPLIT_TOP] = new ScRowBar( pFrameWin, &aViewData, SC_SPLIT_TOP,
+ &aHdrFunc, pHdrSelEng );
+
+ //
+ // Windows anzeigen
+ //
+
+ ShowHide( &aHScrollLeft, bHScrollMode );
+ ShowHide( &aHScrollRight, bShowH && bHScrollMode );
+ ShowHide( &aVScrollBottom, bVScrollMode );
+ ShowHide( &aVScrollTop, bShowV && bVScrollMode );
+ ShowHide( &aScrollBarBox, bVScrollMode || bHScrollMode );
+
+ ShowHide( pHSplitter, bHScrollMode || bShowH ); // immer angelegt
+ ShowHide( pVSplitter, bVScrollMode || bShowV );
+ ShowHide( pTabControl, bTabMode );
+
+ // ab hier dynamisch angelegte
+
+ ShowHide( pGridWin[SC_SPLIT_BOTTOMRIGHT], bShowH );
+ ShowHide( pGridWin[SC_SPLIT_TOPLEFT], bShowV );
+ ShowHide( pGridWin[SC_SPLIT_TOPRIGHT], bShowH && bShowV );
+
+ ShowHide( pColOutline[SC_SPLIT_LEFT], bHOutline );
+ ShowHide( pColOutline[SC_SPLIT_RIGHT], bShowH && bHOutline );
+
+ ShowHide( pRowOutline[SC_SPLIT_BOTTOM], bVOutline );
+ ShowHide( pRowOutline[SC_SPLIT_TOP], bShowV && bVOutline );
+
+ ShowHide( pColBar[SC_SPLIT_RIGHT], bShowH && bHeader );
+ ShowHide( pRowBar[SC_SPLIT_TOP], bShowV && bHeader );
+
+
+ //! neue Gridwindows eintragen
+}
+
+// --- Splitter --------------------------------------------------------
+
+IMPL_LINK( ScTabView, SplitHdl, Splitter*, pSplitter )
+{
+ if ( pSplitter == pHSplitter )
+ DoHSplit( pHSplitter->GetSplitPosPixel() );
+ else
+ DoVSplit( pVSplitter->GetSplitPosPixel() );
+
+ if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX || aViewData.GetVSplitMode() == SC_SPLIT_FIX )
+ FreezeSplitters( sal_True );
+
+ DoResize( aBorderPos, aFrameSize );
+
+ return 0;
+}
+
+void ScTabView::DoHSplit(long nSplitPos)
+{
+ // nSplitPos is the real pixel position on the frame window,
+ // mirroring for RTL has to be done here.
+
+ sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
+ if ( bLayoutRTL )
+ nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
+
+ long nMinPos;
+ long nMaxPos;
+ SCCOL nOldDelta;
+ SCCOL nNewDelta;
+
+ nMinPos = SPLIT_MARGIN;
+ if ( pRowBar[SC_SPLIT_BOTTOM] && pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() >= nMinPos )
+ nMinPos = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() + 1;
+ nMaxPos = aFrameSize.Width() - SPLIT_MARGIN;
+
+ ScSplitMode aOldMode = aViewData.GetHSplitMode();
+ ScSplitMode aNewMode = SC_SPLIT_NORMAL;
+
+ aViewData.SetHSplitPos( nSplitPos );
+ if ( nSplitPos < nMinPos || nSplitPos > nMaxPos )
+ aNewMode = SC_SPLIT_NONE;
+
+ aViewData.SetHSplitMode( aNewMode );
+
+ if ( aNewMode != aOldMode )
+ {
+ UpdateShow(); // vor ActivatePart !!
+
+ if ( aNewMode == SC_SPLIT_NONE )
+ {
+ if (aViewData.GetActivePart() == SC_SPLIT_TOPRIGHT)
+ ActivatePart( SC_SPLIT_TOPLEFT );
+ if (aViewData.GetActivePart() == SC_SPLIT_BOTTOMRIGHT)
+ ActivatePart( SC_SPLIT_BOTTOMLEFT );
+ }
+ else
+ {
+ nOldDelta = aViewData.GetPosX( SC_SPLIT_LEFT );
+// aViewData.SetPosX( SC_SPLIT_LEFT, nOldDelta );
+ long nLeftWidth = nSplitPos - pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
+ if ( nLeftWidth < 0 ) nLeftWidth = 0;
+ nNewDelta = nOldDelta + aViewData.CellsAtX( nOldDelta, 1, SC_SPLIT_LEFT,
+ (sal_uInt16) nLeftWidth );
+ if ( nNewDelta > MAXCOL )
+ nNewDelta = MAXCOL;
+ aViewData.SetPosX( SC_SPLIT_RIGHT, nNewDelta );
+ if ( nNewDelta > aViewData.GetCurX() )
+ ActivatePart( (WhichV(aViewData.GetActivePart()) == SC_SPLIT_BOTTOM) ?
+ SC_SPLIT_BOTTOMLEFT : SC_SPLIT_TOPLEFT );
+ else
+ ActivatePart( (WhichV(aViewData.GetActivePart()) == SC_SPLIT_BOTTOM) ?
+ SC_SPLIT_BOTTOMRIGHT : SC_SPLIT_TOPRIGHT );
+ }
+
+ // #61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen
+ // dafuer muss hier schon der MapMode stimmen
+ for (sal_uInt16 i=0; i<4; i++)
+ if (pGridWin[i])
+ pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
+ SetNewVisArea();
+
+ PaintGrid();
+ PaintTop();
+
+ InvalidateSplit();
+ }
+}
+
+void ScTabView::DoVSplit(long nSplitPos)
+{
+ long nMinPos;
+ long nMaxPos;
+ SCROW nOldDelta;
+ SCROW nNewDelta;
+
+ nMinPos = SPLIT_MARGIN;
+ if ( pColBar[SC_SPLIT_LEFT] && pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() >= nMinPos )
+ nMinPos = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() + 1;
+ nMaxPos = aFrameSize.Height() - SPLIT_MARGIN;
+
+ ScSplitMode aOldMode = aViewData.GetVSplitMode();
+ ScSplitMode aNewMode = SC_SPLIT_NORMAL;
+
+ aViewData.SetVSplitPos( nSplitPos );
+ if ( nSplitPos < nMinPos || nSplitPos > nMaxPos )
+ aNewMode = SC_SPLIT_NONE;
+
+ aViewData.SetVSplitMode( aNewMode );
+
+ if ( aNewMode != aOldMode )
+ {
+ UpdateShow(); // vor ActivatePart !!
+
+ if ( aNewMode == SC_SPLIT_NONE )
+ {
+ nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP );
+ aViewData.SetPosY( SC_SPLIT_BOTTOM, nOldDelta );
+
+ if (aViewData.GetActivePart() == SC_SPLIT_TOPLEFT)
+ ActivatePart( SC_SPLIT_BOTTOMLEFT );
+ if (aViewData.GetActivePart() == SC_SPLIT_TOPRIGHT)
+ ActivatePart( SC_SPLIT_BOTTOMRIGHT );
+ }
+ else
+ {
+ if ( aOldMode == SC_SPLIT_NONE )
+ nOldDelta = aViewData.GetPosY( SC_SPLIT_BOTTOM );
+ else
+ nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP );
+
+ aViewData.SetPosY( SC_SPLIT_TOP, nOldDelta );
+ long nTopHeight = nSplitPos - pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
+ if ( nTopHeight < 0 ) nTopHeight = 0;
+ nNewDelta = nOldDelta + aViewData.CellsAtY( nOldDelta, 1, SC_SPLIT_TOP,
+ (sal_uInt16) nTopHeight );
+ if ( nNewDelta > MAXROW )
+ nNewDelta = MAXROW;
+ aViewData.SetPosY( SC_SPLIT_BOTTOM, nNewDelta );
+ if ( nNewDelta > aViewData.GetCurY() )
+ ActivatePart( (WhichH(aViewData.GetActivePart()) == SC_SPLIT_LEFT) ?
+ SC_SPLIT_TOPLEFT : SC_SPLIT_TOPRIGHT );
+ else
+ ActivatePart( (WhichH(aViewData.GetActivePart()) == SC_SPLIT_LEFT) ?
+ SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT );
+ }
+
+ // #61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen
+ // dafuer muss hier schon der MapMode stimmen
+ for (sal_uInt16 i=0; i<4; i++)
+ if (pGridWin[i])
+ pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
+ SetNewVisArea();
+
+ PaintGrid();
+ PaintLeft();
+
+ InvalidateSplit();
+ }
+}
+
+Point ScTabView::GetInsertPos()
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCCOL nCol = aViewData.GetCurX();
+ SCROW nRow = aViewData.GetCurY();
+ SCTAB nTab = aViewData.GetTabNo();
+ long nPosX = 0;
+ for (SCCOL i=0; i<nCol; i++)
+ nPosX += pDoc->GetColWidth(i,nTab);
+ nPosX = (long)(nPosX * HMM_PER_TWIPS);
+ if ( pDoc->IsNegativePage( nTab ) )
+ nPosX = -nPosX;
+ long nPosY = (long) pDoc->GetRowHeight( 0, nRow-1, nTab);
+ nPosY = (long)(nPosY * HMM_PER_TWIPS);
+ return Point(nPosX,nPosY);
+}
+
+Point ScTabView::GetChartInsertPos( const Size& rSize, const ScRange& rCellRange )
+{
+ Point aInsertPos;
+ const long nBorder = 100; // leave 1mm for border
+ long nNeededWidth = rSize.Width() + 2 * nBorder;
+ long nNeededHeight = rSize.Height() + 2 * nBorder;
+
+ // use the active window, or lower/right if frozen (as in CalcZoom)
+ ScSplitPos eUsedPart = aViewData.GetActivePart();
+ if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
+ eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
+ if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
+ eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
+
+ ScGridWindow* pWin = pGridWin[eUsedPart];
+ DBG_ASSERT( pWin, "Window not found" );
+ if (pWin)
+ {
+ ActivatePart( eUsedPart );
+
+ // get the visible rectangle in logic units
+
+ MapMode aDrawMode = pWin->GetDrawMapMode();
+ Rectangle aVisible( pWin->PixelToLogic( Rectangle( Point(0,0), pWin->GetOutputSizePixel() ), aDrawMode ) );
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ long nDocX = (long)( (double) pDoc->GetColOffset( MAXCOL + 1, nTab ) * HMM_PER_TWIPS ) * nLayoutSign;
+ long nDocY = (long)( (double) pDoc->GetRowOffset( MAXROW + 1, nTab ) * HMM_PER_TWIPS );
+
+ if ( aVisible.Left() * nLayoutSign > nDocX * nLayoutSign )
+ aVisible.Left() = nDocX;
+ if ( aVisible.Right() * nLayoutSign > nDocX * nLayoutSign )
+ aVisible.Right() = nDocX;
+ if ( aVisible.Top() > nDocY )
+ aVisible.Top() = nDocY;
+ if ( aVisible.Bottom() > nDocY )
+ aVisible.Bottom() = nDocY;
+
+ // get the logic position of the selection
+
+ Rectangle aSelection = pDoc->GetMMRect( rCellRange.aStart.Col(), rCellRange.aStart.Row(),
+ rCellRange.aEnd.Col(), rCellRange.aEnd.Row(), nTab );
+
+ long nLeftSpace = aSelection.Left() - aVisible.Left();
+ long nRightSpace = aVisible.Right() - aSelection.Right();
+ long nTopSpace = aSelection.Top() - aVisible.Top();
+ long nBottomSpace = aVisible.Bottom() - aSelection.Bottom();
+
+ bool bFitLeft = ( nLeftSpace >= nNeededWidth );
+ bool bFitRight = ( nRightSpace >= nNeededWidth );
+
+ if ( bFitLeft || bFitRight )
+ {
+ // first preference: completely left or right of the selection
+
+ // if both fit, prefer left in RTL mode, right otherwise
+ bool bPutLeft = bFitLeft && ( bLayoutRTL || !bFitRight );
+
+ if ( bPutLeft )
+ aInsertPos.X() = aSelection.Left() - nNeededWidth;
+ else
+ aInsertPos.X() = aSelection.Right() + 1;
+
+ // align with top of selection (is moved again if it doesn't fit)
+ aInsertPos.Y() = std::max( aSelection.Top(), aVisible.Top() );
+ }
+ else if ( nTopSpace >= nNeededHeight || nBottomSpace >= nNeededHeight )
+ {
+ // second preference: completely above or below the selection
+
+ if ( nBottomSpace > nNeededHeight ) // bottom is preferred
+ aInsertPos.Y() = aSelection.Bottom() + 1;
+ else
+ aInsertPos.Y() = aSelection.Top() - nNeededHeight;
+
+ // align with (logic) left edge of selection (moved again if it doesn't fit)
+ if ( bLayoutRTL )
+ aInsertPos.X() = std::min( aSelection.Right(), aVisible.Right() ) - nNeededWidth + 1;
+ else
+ aInsertPos.X() = std::max( aSelection.Left(), aVisible.Left() );
+ }
+ else
+ {
+ // place to the (logic) right of the selection and move so it fits
+
+ if ( bLayoutRTL )
+ aInsertPos.X() = aSelection.Left() - nNeededWidth;
+ else
+ aInsertPos.X() = aSelection.Right() + 1;
+ aInsertPos.Y() = std::max( aSelection.Top(), aVisible.Top() );
+ }
+
+ // move the position if the object doesn't fit in the screen
+
+ Rectangle aCompareRect( aInsertPos, Size( nNeededWidth, nNeededHeight ) );
+ if ( aCompareRect.Right() > aVisible.Right() )
+ aInsertPos.X() -= aCompareRect.Right() - aVisible.Right();
+ if ( aCompareRect.Bottom() > aVisible.Bottom() )
+ aInsertPos.Y() -= aCompareRect.Bottom() - aVisible.Bottom();
+
+ if ( aInsertPos.X() < aVisible.Left() )
+ aInsertPos.X() = aVisible.Left();
+ if ( aInsertPos.Y() < aVisible.Top() )
+ aInsertPos.Y() = aVisible.Top();
+
+ // nNeededWidth / nNeededHeight includes all borders - move aInsertPos to the
+ // object position, inside the border
+
+ aInsertPos.X() += nBorder;
+ aInsertPos.Y() += nBorder;
+ }
+ return aInsertPos;
+}
+
+Point ScTabView::GetChartDialogPos( const Size& rDialogSize, const Rectangle& rLogicChart )
+{
+ // rDialogSize must be in pixels, rLogicChart in 1/100 mm. Return value is in pixels.
+
+ Point aRet;
+
+ // use the active window, or lower/right if frozen (as in CalcZoom)
+ ScSplitPos eUsedPart = aViewData.GetActivePart();
+ if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
+ eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
+ if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
+ eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
+
+ ScGridWindow* pWin = pGridWin[eUsedPart];
+ DBG_ASSERT( pWin, "Window not found" );
+ if (pWin)
+ {
+ MapMode aDrawMode = pWin->GetDrawMapMode();
+ Rectangle aObjPixel = pWin->LogicToPixel( rLogicChart, aDrawMode );
+ Rectangle aObjAbs( pWin->OutputToAbsoluteScreenPixel( aObjPixel.TopLeft() ),
+ pWin->OutputToAbsoluteScreenPixel( aObjPixel.BottomRight() ) );
+
+ Rectangle aDesktop = pWin->GetDesktopRectPixel();
+ Size aSpace = pWin->LogicToPixel( Size( 8, 12 ), MAP_APPFONT );
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+
+ bool bCenterHor = false;
+
+ if ( aDesktop.Bottom() - aObjAbs.Bottom() >= rDialogSize.Height() + aSpace.Height() )
+ {
+ // first preference: below the chart
+
+ aRet.Y() = aObjAbs.Bottom() + aSpace.Height();
+ bCenterHor = true;
+ }
+ else if ( aObjAbs.Top() - aDesktop.Top() >= rDialogSize.Height() + aSpace.Height() )
+ {
+ // second preference: above the chart
+
+ aRet.Y() = aObjAbs.Top() - rDialogSize.Height() - aSpace.Height();
+ bCenterHor = true;
+ }
+ else
+ {
+ bool bFitLeft = ( aObjAbs.Left() - aDesktop.Left() >= rDialogSize.Width() + aSpace.Width() );
+ bool bFitRight = ( aDesktop.Right() - aObjAbs.Right() >= rDialogSize.Width() + aSpace.Width() );
+
+ if ( bFitLeft || bFitRight )
+ {
+ // if both fit, prefer right in RTL mode, left otherwise
+ bool bPutRight = bFitRight && ( bLayoutRTL || !bFitLeft );
+ if ( bPutRight )
+ aRet.X() = aObjAbs.Right() + aSpace.Width();
+ else
+ aRet.X() = aObjAbs.Left() - rDialogSize.Width() - aSpace.Width();
+
+ // center vertically
+ aRet.Y() = aObjAbs.Top() + ( aObjAbs.GetHeight() - rDialogSize.Height() ) / 2;
+ }
+ else
+ {
+ // doesn't fit on any edge - put at the bottom of the screen
+ aRet.Y() = aDesktop.Bottom() - rDialogSize.Height();
+ bCenterHor = true;
+ }
+ }
+ if ( bCenterHor )
+ aRet.X() = aObjAbs.Left() + ( aObjAbs.GetWidth() - rDialogSize.Width() ) / 2;
+
+ // limit to screen (centering might lead to invalid positions)
+ if ( aRet.X() + rDialogSize.Width() - 1 > aDesktop.Right() )
+ aRet.X() = aDesktop.Right() - rDialogSize.Width() + 1;
+ if ( aRet.X() < aDesktop.Left() )
+ aRet.X() = aDesktop.Left();
+ if ( aRet.Y() + rDialogSize.Height() - 1 > aDesktop.Bottom() )
+ aRet.Y() = aDesktop.Bottom() - rDialogSize.Height() + 1;
+ if ( aRet.Y() < aDesktop.Top() )
+ aRet.Y() = aDesktop.Top();
+ }
+
+ return aRet;
+}
+
+void ScTabView::LockModifiers( sal_uInt16 nModifiers )
+{
+ pSelEngine->LockModifiers( nModifiers );
+ pHdrSelEng->LockModifiers( nModifiers );
+}
+
+sal_uInt16 ScTabView::GetLockedModifiers() const
+{
+ return pSelEngine->GetLockedModifiers();
+}
+
+Point ScTabView::GetMousePosPixel()
+{
+ Point aPos;
+ ScGridWindow* pWin = (ScGridWindow*)GetActiveWin();
+
+ if ( pWin )
+ aPos = pWin->GetMousePosPixel();
+
+ return aPos;
+}
+
+sal_Bool lcl_MouseIsOverWin( const Point& rScreenPosPixel, Window* pWin )
+{
+ if (pWin)
+ {
+ // SPLIT_HANDLE_SIZE draufaddieren, damit das Einrasten genau
+ // auf dem Splitter nicht aussetzt
+
+ Point aRel = pWin->NormalizedScreenToOutputPixel( rScreenPosPixel );
+ Size aWinSize = pWin->GetOutputSizePixel();
+ if ( aRel.X() >= 0 && aRel.X() < aWinSize.Width() + SPLIT_HANDLE_SIZE &&
+ aRel.Y() >= 0 && aRel.Y() < aWinSize.Height() + SPLIT_HANDLE_SIZE )
+ return sal_True;
+ }
+ return sal_False;
+}
+
+void ScTabView::SnapSplitPos( Point& rScreenPosPixel )
+{
+ sal_Bool bOverWin = sal_False;
+ sal_uInt16 i;
+ for (i=0; i<4; i++)
+ if (lcl_MouseIsOverWin(rScreenPosPixel,pGridWin[i]))
+ bOverWin = sal_True;
+
+ if (!bOverWin)
+ return;
+
+ // #74761# don't snap to cells if the scale will be modified afterwards
+ if ( GetZoomType() != SVX_ZOOM_PERCENT )
+ return;
+
+ ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
+ if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ ePos = SC_SPLIT_TOPLEFT;
+
+ Window* pWin = pGridWin[ePos];
+ if (!pWin)
+ {
+ DBG_ERROR("Window NULL");
+ return;
+ }
+
+ Point aMouse = pWin->NormalizedScreenToOutputPixel( rScreenPosPixel );
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ // #52949# bNextIfLarge=FALSE: nicht auf naechste Zelle, wenn ausserhalb des Fensters
+ aViewData.GetPosFromPixel( aMouse.X(), aMouse.Y(), ePos, nPosX, nPosY, sal_True, sal_False, sal_False );
+ sal_Bool bLeft;
+ sal_Bool bTop;
+ aViewData.GetMouseQuadrant( aMouse, ePos, nPosX, nPosY, bLeft, bTop );
+ if (!bLeft)
+ ++nPosX;
+ if (!bTop)
+ ++nPosY;
+ aMouse = aViewData.GetScrPos( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), ePos, sal_True );
+ rScreenPosPixel = pWin->OutputToNormalizedScreenPixel( aMouse );
+}
+
+void ScTabView::FreezeSplitters( sal_Bool bFreeze )
+{
+ ScSplitMode eOldH = aViewData.GetHSplitMode();
+ ScSplitMode eOldV = aViewData.GetVSplitMode();
+
+ ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
+ if ( eOldV != SC_SPLIT_NONE )
+ ePos = SC_SPLIT_TOPLEFT;
+ Window* pWin = pGridWin[ePos];
+
+ sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
+
+ if ( bFreeze )
+ {
+ Point aWinStart = pWin->GetPosPixel();
+
+ Point aSplit;
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ if (eOldH != SC_SPLIT_NONE || eOldV != SC_SPLIT_NONE)
+ {
+ if (eOldH != SC_SPLIT_NONE)
+ {
+ long nSplitPos = aViewData.GetHSplitPos();
+ if ( bLayoutRTL )
+ nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
+ aSplit.X() = nSplitPos - aWinStart.X();
+ }
+ if (eOldV != SC_SPLIT_NONE)
+ aSplit.Y() = aViewData.GetVSplitPos() - aWinStart.Y();
+
+ aViewData.GetPosFromPixel( aSplit.X(), aSplit.Y(), ePos, nPosX, nPosY );
+ sal_Bool bLeft;
+ sal_Bool bTop;
+ aViewData.GetMouseQuadrant( aSplit, ePos, nPosX, nPosY, bLeft, bTop );
+ if (!bLeft)
+ ++nPosX;
+ if (!bTop)
+ ++nPosY;
+ }
+ else
+ {
+ nPosX = static_cast<SCsCOL>( aViewData.GetCurX());
+ nPosY = static_cast<SCsROW>( aViewData.GetCurY());
+ }
+
+ SCCOL nLeftPos = aViewData.GetPosX(SC_SPLIT_LEFT);
+ SCROW nTopPos = aViewData.GetPosY(SC_SPLIT_BOTTOM);
+ SCCOL nRightPos = static_cast<SCCOL>(nPosX);
+ SCROW nBottomPos = static_cast<SCROW>(nPosY);
+ if (eOldH != SC_SPLIT_NONE)
+ if (aViewData.GetPosX(SC_SPLIT_RIGHT) > nRightPos)
+ nRightPos = aViewData.GetPosX(SC_SPLIT_RIGHT);
+ if (eOldV != SC_SPLIT_NONE)
+ {
+ nTopPos = aViewData.GetPosY(SC_SPLIT_TOP);
+ if (aViewData.GetPosY(SC_SPLIT_BOTTOM) > nBottomPos)
+ nBottomPos = aViewData.GetPosY(SC_SPLIT_BOTTOM);
+ }
+
+ aSplit = aViewData.GetScrPos( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), ePos, sal_True );
+ if (nPosX > aViewData.GetPosX(SC_SPLIT_LEFT)) // (aSplit.X() > 0) doesn't work for RTL
+ {
+ long nSplitPos = aSplit.X() + aWinStart.X();
+ if ( bLayoutRTL )
+ nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
+
+ aViewData.SetHSplitMode( SC_SPLIT_FIX );
+ aViewData.SetHSplitPos( nSplitPos );
+ aViewData.SetFixPosX( nPosX );
+
+ aViewData.SetPosX(SC_SPLIT_LEFT, nLeftPos);
+ aViewData.SetPosX(SC_SPLIT_RIGHT, nRightPos);
+ }
+ else
+ aViewData.SetHSplitMode( SC_SPLIT_NONE );
+ if (aSplit.Y() > 0)
+ {
+ aViewData.SetVSplitMode( SC_SPLIT_FIX );
+ aViewData.SetVSplitPos( aSplit.Y() + aWinStart.Y() );
+ aViewData.SetFixPosY( nPosY );
+
+ aViewData.SetPosY(SC_SPLIT_TOP, nTopPos);
+ aViewData.SetPosY(SC_SPLIT_BOTTOM, nBottomPos);
+ }
+ else
+ aViewData.SetVSplitMode( SC_SPLIT_NONE );
+ }
+ else // Fixierung aufheben
+ {
+ if ( eOldH == SC_SPLIT_FIX )
+ aViewData.SetHSplitMode( SC_SPLIT_NORMAL );
+ if ( eOldV == SC_SPLIT_FIX )
+ aViewData.SetVSplitMode( SC_SPLIT_NORMAL );
+ }
+
+ // #61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen
+ // dafuer muss hier schon der MapMode stimmen
+ for (sal_uInt16 i=0; i<4; i++)
+ if (pGridWin[i])
+ pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
+ SetNewVisArea();
+
+ RepeatResize(sal_False);
+
+ UpdateShow();
+ PaintLeft();
+ PaintTop();
+ PaintGrid();
+
+ // SC_FOLLOW_NONE: only update active part
+ AlignToCursor( aViewData.GetCurX(), aViewData.GetCurY(), SC_FOLLOW_NONE );
+ UpdateAutoFillMark();
+
+ InvalidateSplit();
+}
+
+void ScTabView::RemoveSplit()
+{
+ DoHSplit( 0 );
+ DoVSplit( 0 );
+ RepeatResize();
+}
+
+void ScTabView::SplitAtCursor()
+{
+ ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
+ if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ ePos = SC_SPLIT_TOPLEFT;
+ Window* pWin = pGridWin[ePos];
+ Point aWinStart = pWin->GetPosPixel();
+
+ SCCOL nPosX = aViewData.GetCurX();
+ SCROW nPosY = aViewData.GetCurY();
+ Point aSplit = aViewData.GetScrPos( nPosX, nPosY, ePos, sal_True );
+ if ( nPosX > 0 )
+ DoHSplit( aSplit.X() + aWinStart.X() );
+ else
+ DoHSplit( 0 );
+ if ( nPosY > 0 )
+ DoVSplit( aSplit.Y() + aWinStart.Y() );
+ else
+ DoVSplit( 0 );
+ RepeatResize();
+}
+
+void ScTabView::SplitAtPixel( const Point& rPixel, sal_Bool bHor, sal_Bool bVer ) // fuer API
+{
+ // Pixel ist auf die ganze View bezogen, nicht auf das erste GridWin
+
+ if (bHor)
+ {
+ if ( rPixel.X() > 0 )
+ DoHSplit( rPixel.X() );
+ else
+ DoHSplit( 0 );
+ }
+ if (bVer)
+ {
+ if ( rPixel.Y() > 0 )
+ DoVSplit( rPixel.Y() );
+ else
+ DoVSplit( 0 );
+ }
+ RepeatResize();
+}
+
+void ScTabView::InvalidateSplit()
+{
+ SfxBindings& rBindings = aViewData.GetBindings();
+ rBindings.Invalidate( SID_WINDOW_SPLIT );
+ rBindings.Invalidate( SID_WINDOW_FIX );
+
+ pHSplitter->SetFixed( aViewData.GetHSplitMode() == SC_SPLIT_FIX );
+ pVSplitter->SetFixed( aViewData.GetVSplitMode() == SC_SPLIT_FIX );
+}
+
+void ScTabView::SetNewVisArea()
+{
+ // #63854# fuer die Controls muss bei VisAreaChanged der Draw-MapMode eingestellt sein
+ // (auch wenn ansonsten der Edit-MapMode gesetzt ist)
+ MapMode aOldMode[4];
+ MapMode aDrawMode[4];
+ sal_uInt16 i;
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ {
+ aOldMode[i] = pGridWin[i]->GetMapMode();
+ aDrawMode[i] = pGridWin[i]->GetDrawMapMode();
+ if (aDrawMode[i] != aOldMode[i])
+ pGridWin[i]->SetMapMode(aDrawMode[i]);
+ }
+
+ Window* pActive = pGridWin[aViewData.GetActivePart()];
+ if (pActive)
+ aViewData.GetViewShell()->VisAreaChanged(
+ pActive->PixelToLogic(Rectangle(Point(),pActive->GetOutputSizePixel())) );
+ if (pDrawView)
+ pDrawView->VisAreaChanged(); // kein Window uebergeben -> alle Fenster
+
+ UpdateAllOverlays(); // #i79909# with drawing MapMode set
+
+ for (i=0; i<4; i++)
+ if (pGridWin[i] && aDrawMode[i] != aOldMode[i])
+ {
+ pGridWin[i]->flushOverlayManager(); // #i79909# flush overlays before switching to edit MapMode
+ pGridWin[i]->SetMapMode(aOldMode[i]);
+ }
+
+ SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
+ if (pViewFrame)
+ {
+ SfxFrame& rFrame = pViewFrame->GetFrame();
+ com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = rFrame.GetController();
+ if (xController.is())
+ {
+ ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
+ if (pImp)
+ pImp->VisAreaChanged();
+ }
+ }
+ if (aViewData.GetViewShell()->HasAccessibilityObjects())
+ aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_VISAREACHANGED));
+}
+
+sal_Bool ScTabView::HasPageFieldDataAtCursor() const
+{
+ ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
+ SCCOL nCol = aViewData.GetCurX();
+ SCROW nRow = aViewData.GetCurY();
+ if (pWin)
+ return pWin->GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE;
+
+ return sal_False;
+}
+
+void ScTabView::StartDataSelect()
+{
+ ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
+ SCCOL nCol = aViewData.GetCurX();
+ SCROW nRow = aViewData.GetCurY();
+
+ if (!pWin)
+ return;
+
+ switch (pWin->GetDPFieldOrientation(nCol, nRow))
+ {
+ case sheet::DataPilotFieldOrientation_PAGE:
+ // #i36598# If the cursor is on a page field's data cell,
+ // no meaningful input is possible anyway, so this function
+ // can be used to select a page field entry.
+ pWin->LaunchPageFieldMenu( nCol, nRow );
+ break;
+ case sheet::DataPilotFieldOrientation_COLUMN:
+ case sheet::DataPilotFieldOrientation_ROW:
+ pWin->LaunchDPFieldMenu( nCol, nRow );
+ break;
+ default:
+ pWin->DoAutoFilterMenue( nCol, nRow, sal_True );
+ }
+}
+
+void ScTabView::EnableRefInput(sal_Bool bFlag)
+{
+ aHScrollLeft.EnableInput(bFlag);
+ aHScrollRight.EnableInput(bFlag);
+ aVScrollBottom.EnableInput(bFlag);
+ aVScrollTop.EnableInput(bFlag);
+ aScrollBarBox.EnableInput(bFlag);
+
+ // ab hier dynamisch angelegte
+
+ if(pTabControl!=NULL) pTabControl->EnableInput(bFlag,sal_True);
+
+ if(pGridWin[SC_SPLIT_BOTTOMLEFT]!=NULL)
+ pGridWin[SC_SPLIT_BOTTOMLEFT]->EnableInput(bFlag,sal_False);
+ if(pGridWin[SC_SPLIT_BOTTOMRIGHT]!=NULL)
+ pGridWin[SC_SPLIT_BOTTOMRIGHT]->EnableInput(bFlag,sal_False);
+ if(pGridWin[SC_SPLIT_TOPLEFT]!=NULL)
+ pGridWin[SC_SPLIT_TOPLEFT]->EnableInput(bFlag,sal_False);
+ if(pGridWin[SC_SPLIT_TOPRIGHT]!=NULL)
+ pGridWin[SC_SPLIT_TOPRIGHT]->EnableInput(bFlag,sal_False);
+ if(pColBar[SC_SPLIT_RIGHT]!=NULL)
+ pColBar[SC_SPLIT_RIGHT]->EnableInput(bFlag,sal_False);
+ if(pRowBar[SC_SPLIT_TOP]!=NULL)
+ pRowBar[SC_SPLIT_TOP]->EnableInput(bFlag,sal_False);
+}
+
+
+
diff --git a/sc/source/ui/view/tabview2.cxx b/sc/source/ui/view/tabview2.cxx
new file mode 100644
index 000000000000..4fc575942feb
--- /dev/null
+++ b/sc/source/ui/view/tabview2.cxx
@@ -0,0 +1,982 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <vcl/timer.hxx>
+#include <vcl/msgbox.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/childwin.hxx>
+
+#include "attrib.hxx"
+#include "pagedata.hxx"
+#include "tabview.hxx"
+#include "tabvwsh.hxx"
+#include "printfun.hxx"
+#include "stlpool.hxx"
+#include "docsh.hxx"
+#include "gridwin.hxx"
+#include "olinewin.hxx"
+#include "uiitems.hxx"
+#include "sc.hrc"
+#include "viewutil.hxx"
+#include "colrowba.hxx"
+#include "waitoff.hxx"
+#include "globstr.hrc"
+#include "scmod.hxx"
+
+#define SC_BLOCKMODE_NONE 0
+#define SC_BLOCKMODE_NORMAL 1
+#define SC_BLOCKMODE_OWN 2
+
+
+
+//
+// Markier - Funktionen
+//
+
+void ScTabView::PaintMarks(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
+{
+ if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
+ if (!ValidRow(nStartRow)) nStartRow = MAXROW;
+ if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
+ if (!ValidRow(nEndRow)) nEndRow = MAXROW;
+
+ sal_Bool bLeft = (nStartCol==0 && nEndCol==MAXCOL);
+ sal_Bool bTop = (nStartRow==0 && nEndRow==MAXROW);
+
+ if (bLeft)
+ PaintLeftArea( nStartRow, nEndRow );
+ if (bTop)
+ PaintTopArea( nStartCol, nEndCol );
+
+ aViewData.GetDocument()->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow,
+ aViewData.GetTabNo() );
+ PaintArea( nStartCol, nStartRow, nEndCol, nEndRow, SC_UPDATE_MARKS );
+}
+
+sal_Bool ScTabView::IsMarking( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
+{
+ return bIsBlockMode
+ && nBlockStartX == nCol
+ && nBlockStartY == nRow
+ && nBlockStartZ == nTab;
+}
+
+void ScTabView::InitOwnBlockMode()
+{
+ if (!bIsBlockMode)
+ {
+ // Wenn keine (alte) Markierung mehr da ist, Anker in SelectionEngine loeschen:
+
+ ScMarkData& rMark = aViewData.GetMarkData();
+ if (!rMark.IsMarked() && !rMark.IsMultiMarked())
+ GetSelEngine()->CursorPosChanging( sal_False, sal_False );
+
+// bIsBlockMode = sal_True;
+ bIsBlockMode = SC_BLOCKMODE_OWN; //! Variable umbenennen!
+ nBlockStartX = 0;
+ nBlockStartY = 0;
+ nBlockStartZ = 0;
+ nBlockEndX = 0;
+ nBlockEndY = 0;
+ nBlockEndZ = 0;
+
+ SelectionChanged(); // Status wird mit gesetzer Markierung abgefragt
+ }
+}
+
+void ScTabView::InitBlockMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
+ sal_Bool bTestNeg, sal_Bool bCols, sal_Bool bRows )
+{
+ if (!bIsBlockMode)
+ {
+ if (!ValidCol(nCurX)) nCurX = MAXCOL;
+ if (!ValidRow(nCurY)) nCurY = MAXROW;
+
+ ScMarkData& rMark = aViewData.GetMarkData();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ // Teil von Markierung aufheben?
+ if (bTestNeg)
+ {
+ if ( bCols )
+ bBlockNeg = rMark.IsColumnMarked( nCurX );
+ else if ( bRows )
+ bBlockNeg = rMark.IsRowMarked( nCurY );
+ else
+ bBlockNeg = rMark.IsCellMarked( nCurX, nCurY );
+ }
+ else
+ bBlockNeg = sal_False;
+ rMark.SetMarkNegative(bBlockNeg);
+
+// bIsBlockMode = sal_True;
+ bIsBlockMode = SC_BLOCKMODE_NORMAL; //! Variable umbenennen!
+ bBlockCols = bCols;
+ bBlockRows = bRows;
+ nBlockStartX = nBlockStartXOrig = nCurX;
+ nBlockStartY = nBlockStartYOrig = nCurY;
+ nBlockStartZ = nCurZ;
+ nBlockEndX = nOldCurX = nBlockStartX;
+ nBlockEndY = nOldCurY = nBlockStartY;
+ nBlockEndZ = nBlockStartZ;
+
+ if (bBlockCols)
+ {
+ nBlockStartY = nBlockStartYOrig = 0;
+ nBlockEndY = MAXROW;
+ }
+
+ if (bBlockRows)
+ {
+ nBlockStartX = nBlockStartXOrig = 0;
+ nBlockEndX = MAXCOL;
+ }
+
+ rMark.SetMarkArea( ScRange( nBlockStartX,nBlockStartY, nTab, nBlockEndX,nBlockEndY, nTab ) );
+
+#ifdef OLD_SELECTION_PAINT
+ InvertBlockMark( nBlockStartX,nBlockStartY,nBlockEndX,nBlockEndY );
+#endif
+ UpdateSelectionOverlay();
+
+ bNewStartIfMarking = sal_False; // use only once
+ }
+}
+
+void ScTabView::SetNewStartIfMarking()
+{
+ bNewStartIfMarking = sal_True;
+}
+
+void ScTabView::DoneBlockMode( sal_Bool bContinue ) // Default FALSE
+{
+ // Wenn zwischen Tabellen- und Header SelectionEngine gewechselt wird,
+ // wird evtl. DeselectAll gerufen, weil die andere Engine keinen Anker hat.
+ // Mit bMoveIsShift wird verhindert, dass dann die Selektion aufgehoben wird.
+
+ if (bIsBlockMode && !bMoveIsShift)
+ {
+ ScMarkData& rMark = aViewData.GetMarkData();
+ sal_Bool bFlag = rMark.GetMarkingFlag();
+ rMark.SetMarking(sal_False);
+
+ if (bBlockNeg && !bContinue)
+ rMark.MarkToMulti();
+
+ if (bContinue)
+ rMark.MarkToMulti();
+ else
+ {
+ // Die Tabelle kann an dieser Stelle ungueltig sein, weil DoneBlockMode
+ // aus SetTabNo aufgerufen wird
+ // (z.B. wenn die aktuelle Tabelle von einer anderen View aus geloescht wird)
+
+ SCTAB nTab = aViewData.GetTabNo();
+ ScDocument* pDoc = aViewData.GetDocument();
+ if ( pDoc->HasTable(nTab) )
+ PaintBlock( sal_True ); // sal_True -> Block loeschen
+ else
+ rMark.ResetMark();
+ }
+// bIsBlockMode = sal_False;
+ bIsBlockMode = SC_BLOCKMODE_NONE; //! Variable umbenennen!
+
+ rMark.SetMarking(bFlag);
+ rMark.SetMarkNegative(sal_False);
+ }
+}
+
+void ScTabView::MarkCursor( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
+ sal_Bool bCols, sal_Bool bRows, sal_Bool bCellSelection )
+{
+ if (!ValidCol(nCurX)) nCurX = MAXCOL;
+ if (!ValidRow(nCurY)) nCurY = MAXROW;
+
+ if (!bIsBlockMode)
+ {
+ DBG_ERROR( "MarkCursor nicht im BlockMode" );
+ InitBlockMode( nCurX, nCurY, nCurZ, sal_False, bCols, bRows );
+ }
+
+ if (bCols)
+ nCurY = MAXROW;
+ if (bRows)
+ nCurX = MAXCOL;
+
+ ScMarkData& rMark = aViewData.GetMarkData();
+ DBG_ASSERT(rMark.IsMarked() || rMark.IsMultiMarked(), "MarkCursor, !IsMarked()");
+ ScRange aMarkRange;
+ rMark.GetMarkArea(aMarkRange);
+ if (( aMarkRange.aStart.Col() != nBlockStartX && aMarkRange.aEnd.Col() != nBlockStartX ) ||
+ ( aMarkRange.aStart.Row() != nBlockStartY && aMarkRange.aEnd.Row() != nBlockStartY ) ||
+ ( bIsBlockMode == SC_BLOCKMODE_OWN ))
+ {
+ // Markierung ist veraendert worden
+ // (z.B. MarkToSimple, wenn per negativ alles bis auf ein Rechteck geloescht wurde)
+ // oder nach InitOwnBlockMode wird mit Shift-Klick weitermarkiert...
+
+ sal_Bool bOldShift = bMoveIsShift;
+ bMoveIsShift = sal_False; // wirklich umsetzen
+ DoneBlockMode(sal_False); //! direkt Variablen setzen? (-> kein Geflacker)
+ bMoveIsShift = bOldShift;
+
+ InitBlockMode( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
+ nBlockStartZ, rMark.IsMarkNegative(), bCols, bRows );
+ }
+
+ SCCOL nOldBlockEndX = nBlockEndX;
+ SCROW nOldBlockEndY = nBlockEndY;
+
+ if ( nCurX != nOldCurX || nCurY != nOldCurY )
+ {
+ // Current cursor has moved
+
+ SCTAB nTab = nCurZ;
+
+#ifdef OLD_SELECTION_PAINT
+ SCCOL nDrawStartCol;
+ SCROW nDrawStartRow;
+ SCCOL nDrawEndCol;
+ SCROW nDrawEndRow;
+#endif
+
+ // Set old selection area
+ ScUpdateRect aRect( nBlockStartX, nBlockStartY, nOldBlockEndX, nOldBlockEndY );
+
+ if ( bCellSelection )
+ {
+ // Expand selection area accordingly when the current selection ends
+ // with a merged cell.
+ SCsCOL nCurXOffset = 0;
+ SCsCOL nBlockStartXOffset = 0;
+ SCsROW nCurYOffset = 0;
+ SCsROW nBlockStartYOffset = 0;
+ sal_Bool bBlockStartMerged = sal_False;
+ const ScMergeAttr* pMergeAttr = NULL;
+ ScDocument* pDocument = aViewData.GetDocument();
+
+ // The following block checks whether or not the "BlockStart" (anchor)
+ // cell is merged. If it's merged, it'll then move the position of the
+ // anchor cell to the corner that's diagonally opposite of the
+ // direction of a current selection area. For instance, if a current
+ // selection is moving in the upperleft direction, the anchor cell will
+ // move to the lower-right corner of the merged anchor cell, and so on.
+
+ pMergeAttr = static_cast<const ScMergeAttr*>(
+ pDocument->GetAttr( nBlockStartXOrig, nBlockStartYOrig, nTab, ATTR_MERGE ) );
+ if ( pMergeAttr->IsMerged() )
+ {
+ SCsCOL nColSpan = pMergeAttr->GetColMerge();
+ SCsROW nRowSpan = pMergeAttr->GetRowMerge();
+
+ if ( !( nCurX >= nBlockStartXOrig + nColSpan - 1 && nCurY >= nBlockStartYOrig + nRowSpan - 1 ) )
+ {
+ nBlockStartX = nCurX >= nBlockStartXOrig ? nBlockStartXOrig : nBlockStartXOrig + nColSpan - 1;
+ nBlockStartY = nCurY >= nBlockStartYOrig ? nBlockStartYOrig : nBlockStartYOrig + nRowSpan - 1;
+ nCurXOffset = nCurX >= nBlockStartXOrig && nCurX < nBlockStartXOrig + nColSpan - 1 ?
+ nBlockStartXOrig - nCurX + nColSpan - 1 : 0;
+ nCurYOffset = nCurY >= nBlockStartYOrig && nCurY < nBlockStartYOrig + nRowSpan - 1 ?
+ nBlockStartYOrig - nCurY + nRowSpan - 1 : 0;
+ bBlockStartMerged = sal_True;
+ }
+ }
+
+ // The following block checks whether or not the current cell is
+ // merged. If it is, it'll then set the appropriate X & Y offset
+ // values (nCurXOffset & nCurYOffset) such that the selection area will
+ // grow by those specified offset amounts. Note that the values of
+ // nCurXOffset/nCurYOffset may also be specified in the previous code
+ // block, in which case whichever value is greater will take on.
+
+ pMergeAttr = static_cast<const ScMergeAttr*>(
+ pDocument->GetAttr( nCurX, nCurY, nTab, ATTR_MERGE ) );
+ if ( pMergeAttr->IsMerged() )
+ {
+ SCsCOL nColSpan = pMergeAttr->GetColMerge();
+ SCsROW nRowSpan = pMergeAttr->GetRowMerge();
+
+ if ( !( nBlockStartX >= nCurX + nColSpan - 1 && nBlockStartY >= nCurY + nRowSpan - 1 ) )
+ {
+ if ( nBlockStartX <= nCurX + nColSpan - 1 )
+ {
+ SCsCOL nCurXOffsetTemp = nCurX < nCurX + nColSpan - 1 ? nColSpan - 1 : 0;
+ nCurXOffset = nCurXOffset > nCurXOffsetTemp ? nCurXOffset : nCurXOffsetTemp;
+ }
+ if ( nBlockStartY <= nCurY + nRowSpan - 1 )
+ {
+ SCsROW nCurYOffsetTemp = nCurY < nCurY + nRowSpan - 1 ? nRowSpan - 1 : 0;
+ nCurYOffset = nCurYOffset > nCurYOffsetTemp ? nCurYOffset : nCurYOffsetTemp;
+ }
+ if ( !( nBlockStartX <= nCurX && nBlockStartY <= nCurY ) &&
+ !( nBlockStartX > nCurX + nColSpan - 1 && nBlockStartY > nCurY + nRowSpan - 1 ) )
+ {
+ nBlockStartXOffset = nBlockStartX > nCurX && nBlockStartX <= nCurX + nColSpan - 1 ? nCurX - nBlockStartX : 0;
+ nBlockStartYOffset = nBlockStartY > nCurY && nBlockStartY <= nCurY + nRowSpan - 1 ? nCurY - nBlockStartY : 0;
+ }
+ }
+ }
+ else
+ {
+ // The current cell is not merged. Move the anchor cell to its
+ // original position.
+ if ( !bBlockStartMerged )
+ {
+ nBlockStartX = nBlockStartXOrig;
+ nBlockStartY = nBlockStartYOrig;
+ }
+ }
+
+ nBlockStartX = nBlockStartX + nBlockStartXOffset >= 0 ? nBlockStartX + nBlockStartXOffset : 0;
+ nBlockStartY = nBlockStartY + nBlockStartYOffset >= 0 ? nBlockStartY + nBlockStartYOffset : 0;
+ nBlockEndX = nCurX + nCurXOffset > MAXCOL ? MAXCOL : nCurX + nCurXOffset;
+ nBlockEndY = nCurY + nCurYOffset > MAXROW ? MAXROW : nCurY + nCurYOffset;
+ }
+ else
+ {
+ nBlockEndX = nCurX;
+ nBlockEndY = nCurY;
+ }
+ // end of "if ( bCellSelection )"
+
+ // Set new selection area
+ aRect.SetNew( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY );
+ rMark.SetMarkArea( ScRange( nBlockStartX, nBlockStartY, nTab, nBlockEndX, nBlockEndY, nTab ) );
+
+#ifdef OLD_SELECTION_PAINT
+ sal_Bool bCont;
+ sal_Bool bDraw = aRect.GetXorDiff( nDrawStartCol, nDrawStartRow,
+ nDrawEndCol, nDrawEndRow, bCont );
+ if ( bDraw )
+ {
+//? PutInOrder( nDrawStartCol, nDrawEndCol );
+//? PutInOrder( nDrawStartRow, nDrawEndRow );
+
+ HideAllCursors();
+ InvertBlockMark( nDrawStartCol, nDrawStartRow, nDrawEndCol, nDrawEndRow );
+ if (bCont)
+ {
+ aRect.GetContDiff( nDrawStartCol, nDrawStartRow, nDrawEndCol, nDrawEndRow );
+ InvertBlockMark( nDrawStartCol, nDrawStartRow, nDrawEndCol, nDrawEndRow );
+ }
+ ShowAllCursors();
+ }
+#endif
+ UpdateSelectionOverlay();
+
+ nOldCurX = nCurX;
+ nOldCurY = nCurY;
+
+ aViewData.GetViewShell()->UpdateInputHandler();
+// InvalidateAttribs();
+ }
+
+ if ( !bCols && !bRows )
+ aHdrFunc.SetAnchorFlag( sal_False );
+}
+
+void ScTabView::UpdateSelectionOverlay()
+{
+ for (sal_uInt16 i=0; i<4; i++)
+ if ( pGridWin[i] && pGridWin[i]->IsVisible() )
+ pGridWin[i]->UpdateSelectionOverlay();
+}
+
+void ScTabView::UpdateShrinkOverlay()
+{
+ for (sal_uInt16 i=0; i<4; i++)
+ if ( pGridWin[i] && pGridWin[i]->IsVisible() )
+ pGridWin[i]->UpdateShrinkOverlay();
+}
+
+void ScTabView::UpdateAllOverlays()
+{
+ for (sal_uInt16 i=0; i<4; i++)
+ if ( pGridWin[i] && pGridWin[i]->IsVisible() )
+ pGridWin[i]->UpdateAllOverlays();
+}
+
+//!
+//! PaintBlock in zwei Methoden aufteilen: RepaintBlock und RemoveBlock o.ae.
+//!
+
+void ScTabView::PaintBlock( sal_Bool bReset )
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ ScMarkData& rMark = aViewData.GetMarkData();
+ SCTAB nTab = aViewData.GetTabNo();
+ sal_Bool bMark = rMark.IsMarked();
+ sal_Bool bMulti = rMark.IsMultiMarked();
+ if (bMark || bMulti)
+ {
+ ScRange aMarkRange;
+ HideAllCursors();
+ if (bMulti)
+ {
+ sal_Bool bFlag = rMark.GetMarkingFlag();
+ rMark.SetMarking(sal_False);
+ rMark.MarkToMulti();
+ rMark.GetMultiMarkArea(aMarkRange);
+ rMark.MarkToSimple();
+ rMark.SetMarking(bFlag);
+
+ bMark = rMark.IsMarked();
+ bMulti = rMark.IsMultiMarked();
+ }
+ else
+ rMark.GetMarkArea(aMarkRange);
+
+ nBlockStartX = aMarkRange.aStart.Col();
+ nBlockStartY = aMarkRange.aStart.Row();
+ nBlockStartZ = aMarkRange.aStart.Tab();
+ nBlockEndX = aMarkRange.aEnd.Col();
+ nBlockEndY = aMarkRange.aEnd.Row();
+ nBlockEndZ = aMarkRange.aEnd.Tab();
+
+ sal_Bool bDidReset = sal_False;
+
+ if ( nTab>=nBlockStartZ && nTab<=nBlockEndZ )
+ {
+ if ( bReset )
+ {
+ // Invertieren beim Loeschen nur auf aktiver View
+ if ( aViewData.IsActive() )
+ {
+ sal_uInt16 i;
+ if ( bMulti )
+ {
+#ifdef OLD_SELECTION_PAINT
+ for (i=0; i<4; i++)
+ if (pGridWin[i] && pGridWin[i]->IsVisible())
+ pGridWin[i]->InvertSimple( nBlockStartX, nBlockStartY,
+ nBlockEndX, nBlockEndY,
+ sal_True, sal_True );
+#endif
+ rMark.ResetMark();
+ UpdateSelectionOverlay();
+ bDidReset = sal_True;
+ }
+ else
+ {
+#ifdef OLD_SELECTION_PAINT
+ // (mis)use InvertBlockMark to remove all of the selection
+ // -> set bBlockNeg (like when removing parts of a selection)
+ // and convert everything to Multi
+
+ rMark.MarkToMulti();
+ sal_Bool bOld = bBlockNeg;
+ bBlockNeg = sal_True;
+ // #73130# (negative) MarkArea must be set in case of repaint
+ rMark.SetMarkArea( ScRange( nBlockStartX,nBlockStartY, nTab,
+ nBlockEndX,nBlockEndY, nTab ) );
+
+ InvertBlockMark( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY );
+
+ bBlockNeg = bOld;
+#endif
+ rMark.ResetMark();
+ UpdateSelectionOverlay();
+ bDidReset = sal_True;
+ }
+
+ // repaint if controls are touched (#69680# in both cases)
+ // #i74768# Forms are rendered by DrawingLayer's EndDrawLayers()
+ static bool bSuppressControlExtraStuff(true);
+
+ if(!bSuppressControlExtraStuff)
+ {
+ Rectangle aMMRect = pDoc->GetMMRect(nBlockStartX,nBlockStartY,nBlockEndX,nBlockEndY, nTab);
+ if (pDoc->HasControl( nTab, aMMRect ))
+ {
+ for (i=0; i<4; i++)
+ {
+ if (pGridWin[i] && pGridWin[i]->IsVisible())
+ {
+ // MapMode muss logischer (1/100mm) sein !!!
+ pDoc->InvalidateControls( pGridWin[i], nTab, aMMRect );
+ pGridWin[i]->Update();
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ PaintMarks( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY );
+ }
+
+ if ( bReset && !bDidReset )
+ rMark.ResetMark();
+
+ ShowAllCursors();
+ }
+}
+
+void ScTabView::SelectAll( sal_Bool bContinue )
+{
+ ScMarkData& rMark = aViewData.GetMarkData();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ if (rMark.IsMarked())
+ {
+ ScRange aMarkRange;
+ rMark.GetMarkArea( aMarkRange );
+ if ( aMarkRange == ScRange( 0,0,nTab, MAXCOL,MAXROW,nTab ) )
+ return;
+ }
+
+ DoneBlockMode( bContinue );
+ InitBlockMode( 0,0,nTab );
+ MarkCursor( MAXCOL,MAXROW,nTab );
+
+ SelectionChanged();
+}
+
+void ScTabView::SelectAllTables()
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ ScMarkData& rMark = aViewData.GetMarkData();
+// SCTAB nTab = aViewData.GetTabNo();
+ SCTAB nCount = pDoc->GetTableCount();
+
+ if (nCount>1)
+ {
+ for (SCTAB i=0; i<nCount; i++)
+ rMark.SelectTable( i, sal_True );
+
+ // Markierungen werden per Default nicht pro Tabelle gehalten
+// pDoc->ExtendMarksFromTable( nTab );
+
+ aViewData.GetDocShell()->PostPaintExtras();
+ SfxBindings& rBind = aViewData.GetBindings();
+ rBind.Invalidate( FID_FILL_TAB );
+ rBind.Invalidate( FID_TAB_DESELECTALL );
+ }
+}
+
+void ScTabView::DeselectAllTables()
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ ScMarkData& rMark = aViewData.GetMarkData();
+ SCTAB nTab = aViewData.GetTabNo();
+ SCTAB nCount = pDoc->GetTableCount();
+
+ for (SCTAB i=0; i<nCount; i++)
+ rMark.SelectTable( i, ( i == nTab ) );
+
+ aViewData.GetDocShell()->PostPaintExtras();
+ SfxBindings& rBind = aViewData.GetBindings();
+ rBind.Invalidate( FID_FILL_TAB );
+ rBind.Invalidate( FID_TAB_DESELECTALL );
+}
+
+sal_Bool lcl_FitsInWindow( double fScaleX, double fScaleY, sal_uInt16 nZoom,
+ long nWindowX, long nWindowY, ScDocument* pDoc, SCTAB nTab,
+ SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ SCCOL nFixPosX, SCROW nFixPosY )
+{
+ double fZoomFactor = (double)Fraction(nZoom,100);
+ fScaleX *= fZoomFactor;
+ fScaleY *= fZoomFactor;
+
+ long nBlockX = 0;
+ SCCOL nCol;
+ for (nCol=0; nCol<nFixPosX; nCol++)
+ {
+ // for frozen panes, add both parts
+ sal_uInt16 nColTwips = pDoc->GetColWidth( nCol, nTab );
+ if (nColTwips)
+ {
+ nBlockX += (long)(nColTwips * fScaleX);
+ if (nBlockX > nWindowX)
+ return sal_False;
+ }
+ }
+ for (nCol=nStartCol; nCol<=nEndCol; nCol++)
+ {
+ sal_uInt16 nColTwips = pDoc->GetColWidth( nCol, nTab );
+ if (nColTwips)
+ {
+ nBlockX += (long)(nColTwips * fScaleX);
+ if (nBlockX > nWindowX)
+ return sal_False;
+ }
+ }
+
+ long nBlockY = 0;
+ for (SCROW nRow = 0; nRow <= nFixPosY-1; ++nRow)
+ {
+ if (pDoc->RowHidden(nRow, nTab))
+ continue;
+
+ // for frozen panes, add both parts
+ sal_uInt16 nRowTwips = pDoc->GetRowHeight(nRow, nTab);
+ if (nRowTwips)
+ {
+ nBlockY += (long)(nRowTwips * fScaleY);
+ if (nBlockY > nWindowY)
+ return sal_False;
+ }
+ }
+ for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
+ {
+ sal_uInt16 nRowTwips = pDoc->GetRowHeight(nRow, nTab);
+ if (nRowTwips)
+ {
+ nBlockY += (long)(nRowTwips * fScaleY);
+ if (nBlockY > nWindowY)
+ return sal_False;
+ }
+ }
+
+ return sal_True;
+}
+
+sal_uInt16 ScTabView::CalcZoom( SvxZoomType eType, sal_uInt16 nOldZoom )
+{
+ sal_uInt16 nZoom = 0; // Ergebnis
+
+ switch ( eType )
+ {
+ case SVX_ZOOM_PERCENT: // rZoom ist kein besonderer prozentualer Wert
+ nZoom = nOldZoom;
+ break;
+
+ case SVX_ZOOM_OPTIMAL: // nZoom entspricht der optimalen Gr"o\se
+ {
+ ScMarkData& rMark = aViewData.GetMarkData();
+ ScDocument* pDoc = aViewData.GetDocument();
+
+ if (!rMark.IsMarked() && !rMark.IsMultiMarked())
+ nZoom = 100; // nothing selected
+ else
+ {
+ SCTAB nTab = aViewData.GetTabNo();
+ ScRange aMarkRange;
+ if ( aViewData.GetSimpleArea( aMarkRange ) != SC_MARK_SIMPLE )
+ rMark.GetMultiMarkArea( aMarkRange );
+
+ SCCOL nStartCol = aMarkRange.aStart.Col();
+ SCROW nStartRow = aMarkRange.aStart.Row();
+ SCTAB nStartTab = aMarkRange.aStart.Tab();
+ SCCOL nEndCol = aMarkRange.aEnd.Col();
+ SCROW nEndRow = aMarkRange.aEnd.Row();
+ SCTAB nEndTab = aMarkRange.aEnd.Tab();
+
+ if ( nTab < nStartTab && nTab > nEndTab )
+ nTab = nStartTab;
+
+ ScSplitPos eUsedPart = aViewData.GetActivePart();
+
+ SCCOL nFixPosX = 0;
+ SCROW nFixPosY = 0;
+ if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
+ {
+ // use right part
+ eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
+ nFixPosX = aViewData.GetFixPosX();
+ if ( nStartCol < nFixPosX )
+ nStartCol = nFixPosX;
+ }
+ if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
+ {
+ // use bottom part
+ eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
+ nFixPosY = aViewData.GetFixPosY();
+ if ( nStartRow < nFixPosY )
+ nStartRow = nFixPosY;
+ }
+
+ if (pGridWin[eUsedPart])
+ {
+ // Because scale is rounded to pixels, the only reliable way to find
+ // the right scale is to check if a zoom fits
+
+ Size aWinSize = pGridWin[eUsedPart]->GetOutputSizePixel();
+
+ // for frozen panes, use sum of both parts for calculation
+
+ if ( nFixPosX != 0 )
+ aWinSize.Width() += GetGridWidth( SC_SPLIT_LEFT );
+ if ( nFixPosY != 0 )
+ aWinSize.Height() += GetGridHeight( SC_SPLIT_TOP );
+
+ ScDocShell* pDocSh = aViewData.GetDocShell();
+ double nPPTX = ScGlobal::nScreenPPTX / pDocSh->GetOutputFactor();
+ double nPPTY = ScGlobal::nScreenPPTY;
+
+ sal_uInt16 nMin = MINZOOM;
+ sal_uInt16 nMax = MAXZOOM;
+ while ( nMax > nMin )
+ {
+ sal_uInt16 nTest = (nMin+nMax+1)/2;
+ if ( lcl_FitsInWindow(
+ nPPTX, nPPTY, nTest, aWinSize.Width(), aWinSize.Height(),
+ pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow,
+ nFixPosX, nFixPosY ) )
+ nMin = nTest;
+ else
+ nMax = nTest-1;
+ }
+ DBG_ASSERT( nMin == nMax, "Schachtelung ist falsch" );
+ nZoom = nMin;
+
+ if ( nZoom != nOldZoom )
+ {
+ // scroll to block only in active split part
+ // (the part for which the size was calculated)
+
+ if ( nStartCol <= nEndCol )
+ aViewData.SetPosX( WhichH(eUsedPart), nStartCol );
+ if ( nStartRow <= nEndRow )
+ aViewData.SetPosY( WhichV(eUsedPart), nStartRow );
+ }
+ }
+ }
+ }
+ break;
+
+ case SVX_ZOOM_WHOLEPAGE: // nZoom entspricht der ganzen Seite oder
+ case SVX_ZOOM_PAGEWIDTH: // nZoom entspricht der Seitenbreite
+ {
+ SCTAB nCurTab = aViewData.GetTabNo();
+ ScDocument* pDoc = aViewData.GetDocument();
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet =
+ pStylePool->Find( pDoc->GetPageStyle( nCurTab ),
+ SFX_STYLE_FAMILY_PAGE );
+
+ DBG_ASSERT( pStyleSheet, "PageStyle not found :-/" );
+
+ if ( pStyleSheet )
+ {
+ ScPrintFunc aPrintFunc( aViewData.GetDocShell(),
+ aViewData.GetViewShell()->GetPrinter(sal_True),
+ nCurTab );
+
+ Size aPageSize = aPrintFunc.GetDataSize();
+
+ // use the size of the largest GridWin for normal split,
+ // or both combined for frozen panes, with the (document) size
+ // of the frozen part added to the page size
+ // (with frozen panes, the size of the individual parts
+ // depends on the scale that is to be calculated)
+
+ if ( !pGridWin[SC_SPLIT_BOTTOMLEFT] ) return 0;
+ Size aWinSize = pGridWin[SC_SPLIT_BOTTOMLEFT]->GetOutputSizePixel();
+ ScSplitMode eHMode = aViewData.GetHSplitMode();
+ if ( eHMode != SC_SPLIT_NONE && pGridWin[SC_SPLIT_BOTTOMRIGHT] )
+ {
+ long nOtherWidth = pGridWin[SC_SPLIT_BOTTOMRIGHT]->
+ GetOutputSizePixel().Width();
+ if ( eHMode == SC_SPLIT_FIX )
+ {
+ aWinSize.Width() += nOtherWidth;
+ for ( SCCOL nCol = aViewData.GetPosX(SC_SPLIT_LEFT);
+ nCol < aViewData.GetFixPosX(); nCol++ )
+ aPageSize.Width() += pDoc->GetColWidth( nCol, nCurTab );
+ }
+ else if ( nOtherWidth > aWinSize.Width() )
+ aWinSize.Width() = nOtherWidth;
+ }
+ ScSplitMode eVMode = aViewData.GetVSplitMode();
+ if ( eVMode != SC_SPLIT_NONE && pGridWin[SC_SPLIT_TOPLEFT] )
+ {
+ long nOtherHeight = pGridWin[SC_SPLIT_TOPLEFT]->
+ GetOutputSizePixel().Height();
+ if ( eVMode == SC_SPLIT_FIX )
+ {
+ aWinSize.Height() += nOtherHeight;
+ aPageSize.Height() += pDoc->GetRowHeight(
+ aViewData.GetPosY(SC_SPLIT_TOP),
+ aViewData.GetFixPosY()-1, nCurTab);
+ }
+ else if ( nOtherHeight > aWinSize.Height() )
+ aWinSize.Height() = nOtherHeight;
+ }
+
+ double nPPTX = ScGlobal::nScreenPPTX / aViewData.GetDocShell()->GetOutputFactor();
+ double nPPTY = ScGlobal::nScreenPPTY;
+
+ long nZoomX = (long) ( aWinSize.Width() * 100 /
+ ( aPageSize.Width() * nPPTX ) );
+ long nZoomY = (long) ( aWinSize.Height() * 100 /
+ ( aPageSize.Height() * nPPTY ) );
+ long nNew = nZoomX;
+
+ if (eType == SVX_ZOOM_WHOLEPAGE && nZoomY < nNew)
+ nNew = nZoomY;
+
+ nZoom = (sal_uInt16) nNew;
+ }
+ }
+ break;
+
+ default:
+ DBG_ERROR("Unknown Zoom-Revision");
+ nZoom = 0;
+ }
+
+ return nZoom;
+}
+
+// wird z.B. gerufen, wenn sich das View-Fenster verschiebt:
+
+void ScTabView::StopMarking()
+{
+ ScSplitPos eActive = aViewData.GetActivePart();
+ if (pGridWin[eActive])
+ pGridWin[eActive]->StopMarking();
+
+ ScHSplitPos eH = WhichH(eActive);
+ if (pColBar[eH])
+ pColBar[eH]->StopMarking();
+
+ ScVSplitPos eV = WhichV(eActive);
+ if (pRowBar[eV])
+ pRowBar[eV]->StopMarking();
+}
+
+void ScTabView::HideNoteMarker()
+{
+ for (sal_uInt16 i=0; i<4; i++)
+ if (pGridWin[i] && pGridWin[i]->IsVisible())
+ pGridWin[i]->HideNoteMarker();
+}
+
+void ScTabView::MakeDrawLayer()
+{
+ if (!pDrawView)
+ {
+ aViewData.GetDocShell()->MakeDrawLayer();
+
+ // pDrawView wird per Notify gesetzt
+ DBG_ASSERT(pDrawView,"ScTabView::MakeDrawLayer funktioniert nicht");
+
+ // #114409#
+ for(sal_uInt16 a(0); a < 4; a++)
+ {
+ if(pGridWin[a])
+ {
+ pGridWin[a]->DrawLayerCreated();
+ }
+ }
+ }
+}
+
+void ScTabView::ErrorMessage( sal_uInt16 nGlobStrId )
+{
+ if ( SC_MOD()->IsInExecuteDrop() )
+ {
+ // #i28468# don't show error message when called from Drag&Drop, silently abort instead
+ return;
+ }
+
+ StopMarking(); // falls per Focus aus MouseButtonDown aufgerufen
+
+ Window* pParent = aViewData.GetDialogParent();
+ ScWaitCursorOff aWaitOff( pParent );
+ sal_Bool bFocus = pParent && pParent->HasFocus();
+
+ if(nGlobStrId==STR_PROTECTIONERR)
+ {
+ if(aViewData.GetDocShell()->IsReadOnly())
+ {
+ nGlobStrId=STR_READONLYERR;
+ }
+ }
+
+ InfoBox aBox( pParent, ScGlobal::GetRscString( nGlobStrId ) );
+ aBox.Execute();
+ if (bFocus)
+ pParent->GrabFocus();
+}
+
+Window* ScTabView::GetParentOrChild( sal_uInt16 nChildId )
+{
+ SfxViewFrame* pViewFrm = aViewData.GetViewShell()->GetViewFrame();
+
+ if ( pViewFrm->HasChildWindow(nChildId) )
+ {
+ SfxChildWindow* pChild = pViewFrm->GetChildWindow(nChildId);
+ if (pChild)
+ {
+ Window* pWin = pChild->GetWindow();
+ if (pWin && pWin->IsVisible())
+ return pWin;
+ }
+ }
+
+ return aViewData.GetDialogParent();
+}
+
+void ScTabView::UpdatePageBreakData( sal_Bool bForcePaint )
+{
+ ScPageBreakData* pNewData = NULL;
+
+ if (aViewData.IsPagebreakMode())
+ {
+ ScDocShell* pDocSh = aViewData.GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ sal_uInt16 nCount = pDoc->GetPrintRangeCount(nTab);
+ if (!nCount)
+ nCount = 1;
+ pNewData = new ScPageBreakData(nCount);
+
+ ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab, 0,0,NULL, NULL, pNewData );
+ // ScPrintFunc fuellt im ctor die PageBreakData
+ if ( nCount > 1 )
+ {
+ aPrintFunc.ResetBreaks(nTab);
+ pNewData->AddPages();
+ }
+
+ // Druckbereiche veraendert?
+ if ( bForcePaint || ( pPageBreakData && !pPageBreakData->IsEqual( *pNewData ) ) )
+ PaintGrid();
+ }
+
+ delete pPageBreakData;
+ pPageBreakData = pNewData;
+}
+
+
+
diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx
new file mode 100644
index 000000000000..19289e4cf703
--- /dev/null
+++ b/sc/source/ui/view/tabview3.cxx
@@ -0,0 +1,2792 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// System - Includes -----------------------------------------------------
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include <rangelst.hxx>
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <editeng/brshitem.hxx>
+#include <editeng/editview.hxx>
+#include <svx/fmshell.hxx>
+#include <svx/svdoole2.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <vcl/cursor.hxx>
+
+#include "tabview.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "gridwin.hxx"
+#include "olinewin.hxx"
+#include "colrowba.hxx"
+#include "tabcont.hxx"
+#include "scmod.hxx"
+#include "uiitems.hxx"
+#include "sc.hrc"
+#include "viewutil.hxx"
+#include "editutil.hxx"
+#include "inputhdl.hxx"
+#include "inputwin.hxx"
+#include "validat.hxx"
+#include "hintwin.hxx"
+#include "inputopt.hxx"
+#include "rfindlst.hxx"
+#include "hiranges.hxx"
+#include "viewuno.hxx"
+#include "chartarr.hxx"
+#include "anyrefdg.hxx"
+#include "dpobject.hxx"
+#include "patattr.hxx"
+#include "dociter.hxx"
+#include "seltrans.hxx"
+#include "fillinfo.hxx"
+#include "AccessibilityHints.hxx"
+#include "rangeutl.hxx"
+#include "client.hxx"
+#include "tabprotection.hxx"
+
+#include <com/sun/star/chart2/data/HighlightedRange.hpp>
+
+namespace
+{
+
+ScRange lcl_getSubRangeByIndex( const ScRange& rRange, sal_Int32 nIndex )
+{
+ ScAddress aResult( rRange.aStart );
+
+ SCCOL nWidth = rRange.aEnd.Col() - rRange.aStart.Col() + 1;
+ SCROW nHeight = rRange.aEnd.Row() - rRange.aStart.Row() + 1;
+ SCTAB nDepth = rRange.aEnd.Tab() - rRange.aStart.Tab() + 1;
+ if( (nWidth > 0) && (nHeight > 0) && (nDepth > 0) )
+ {
+ // row by row from first to last sheet
+ sal_Int32 nArea = nWidth * nHeight;
+ aResult.IncCol( static_cast< SCsCOL >( nIndex % nWidth ) );
+ aResult.IncRow( static_cast< SCsROW >( (nIndex % nArea) / nWidth ) );
+ aResult.IncTab( static_cast< SCsTAB >( nIndex / nArea ) );
+ if( !rRange.In( aResult ) )
+ aResult = rRange.aStart;
+ }
+
+ return ScRange( aResult );
+}
+
+} // anonymous namespace
+
+using namespace com::sun::star;
+
+// -----------------------------------------------------------------------
+
+//
+// --- Public-Funktionen
+//
+
+void ScTabView::ClickCursor( SCCOL nPosX, SCROW nPosY, sal_Bool bControl )
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ while (pDoc->IsHorOverlapped( nPosX, nPosY, nTab )) //! ViewData !!!
+ --nPosX;
+ while (pDoc->IsVerOverlapped( nPosX, nPosY, nTab ))
+ --nPosY;
+
+ sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
+
+ if ( bRefMode )
+ {
+ DoneRefMode( sal_False );
+
+ if (bControl)
+ SC_MOD()->AddRefEntry();
+
+ InitRefMode( nPosX, nPosY, nTab, SC_REFTYPE_REF );
+ }
+ else
+ {
+ DoneBlockMode( bControl );
+ aViewData.ResetOldCursor();
+ SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
+ }
+}
+
+void ScTabView::UpdateAutoFillMark()
+{
+ // single selection or cursor
+ ScRange aMarkRange;
+ sal_Bool bMarked = (aViewData.GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE);
+
+ sal_uInt16 i;
+ for (i=0; i<4; i++)
+ if (pGridWin[i] && pGridWin[i]->IsVisible())
+ pGridWin[i]->UpdateAutoFillMark( bMarked, aMarkRange );
+
+ for (i=0; i<2; i++)
+ {
+ if (pColBar[i] && pColBar[i]->IsVisible())
+ pColBar[i]->SetMark( bMarked, aMarkRange.aStart.Col(), aMarkRange.aEnd.Col() );
+ if (pRowBar[i] && pRowBar[i]->IsVisible())
+ pRowBar[i]->SetMark( bMarked, aMarkRange.aStart.Row(), aMarkRange.aEnd.Row() );
+ }
+
+ // selection transfer object is checked together with AutoFill marks,
+ // because it has the same requirement of a single continuous block.
+ CheckSelectionTransfer(); // update selection transfer object
+}
+
+void ScTabView::FakeButtonUp( ScSplitPos eWhich )
+{
+ if (pGridWin[eWhich])
+ pGridWin[eWhich]->FakeButtonUp();
+}
+
+void ScTabView::HideAllCursors()
+{
+ for (sal_uInt16 i=0; i<4; i++)
+ if (pGridWin[i])
+ if (pGridWin[i]->IsVisible())
+ {
+ Cursor* pCur = pGridWin[i]->GetCursor();
+ if (pCur)
+ if (pCur->IsVisible())
+ pCur->Hide();
+ pGridWin[i]->HideCursor();
+ }
+}
+
+void ScTabView::ShowAllCursors()
+{
+ for (sal_uInt16 i=0; i<4; i++)
+ if (pGridWin[i])
+ if (pGridWin[i]->IsVisible())
+ {
+ pGridWin[i]->ShowCursor();
+
+ // #114409#
+ pGridWin[i]->CursorChanged();
+ }
+}
+
+void ScTabView::HideCursor()
+{
+ pGridWin[aViewData.GetActivePart()]->HideCursor();
+}
+
+void ScTabView::ShowCursor()
+{
+ pGridWin[aViewData.GetActivePart()]->ShowCursor();
+
+ // #114409#
+ pGridWin[aViewData.GetActivePart()]->CursorChanged();
+}
+
+void ScTabView::InvalidateAttribs()
+{
+ SfxBindings& rBindings = aViewData.GetBindings();
+
+ rBindings.Invalidate( SID_STYLE_APPLY );
+ rBindings.Invalidate( SID_STYLE_FAMILY2 );
+ // StarCalc kennt nur Absatz- bzw. Zellformat-Vorlagen
+
+ rBindings.Invalidate( SID_ATTR_CHAR_FONT );
+ rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
+ rBindings.Invalidate( SID_ATTR_CHAR_COLOR );
+
+ rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
+ rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
+ rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
+ rBindings.Invalidate( SID_ULINE_VAL_NONE );
+ rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
+ rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
+ rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
+
+ rBindings.Invalidate( SID_ATTR_CHAR_OVERLINE );
+
+ rBindings.Invalidate( SID_ALIGNLEFT );
+ rBindings.Invalidate( SID_ALIGNRIGHT );
+ rBindings.Invalidate( SID_ALIGNBLOCK );
+ rBindings.Invalidate( SID_ALIGNCENTERHOR );
+
+ rBindings.Invalidate( SID_ALIGNTOP );
+ rBindings.Invalidate( SID_ALIGNBOTTOM );
+ rBindings.Invalidate( SID_ALIGNCENTERVER );
+
+ rBindings.Invalidate( SID_BACKGROUND_COLOR );
+
+ rBindings.Invalidate( SID_ATTR_ALIGN_LINEBREAK );
+ rBindings.Invalidate( SID_NUMBER_FORMAT );
+
+ rBindings.Invalidate( SID_TEXTDIRECTION_LEFT_TO_RIGHT );
+ rBindings.Invalidate( SID_TEXTDIRECTION_TOP_TO_BOTTOM );
+ rBindings.Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
+ rBindings.Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
+
+ // pseudo slots for Format menu
+ rBindings.Invalidate( SID_ALIGN_ANY_HDEFAULT );
+ rBindings.Invalidate( SID_ALIGN_ANY_LEFT );
+ rBindings.Invalidate( SID_ALIGN_ANY_HCENTER );
+ rBindings.Invalidate( SID_ALIGN_ANY_RIGHT );
+ rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED );
+ rBindings.Invalidate( SID_ALIGN_ANY_VDEFAULT );
+ rBindings.Invalidate( SID_ALIGN_ANY_TOP );
+ rBindings.Invalidate( SID_ALIGN_ANY_VCENTER );
+ rBindings.Invalidate( SID_ALIGN_ANY_BOTTOM );
+
+// rBindings.Invalidate( SID_RANGE_VALUE );
+// rBindings.Invalidate( SID_RANGE_FORMULA );
+}
+
+// SetCursor - Cursor setzen, zeichnen, InputWin updaten
+// oder Referenz verschicken
+// ohne Optimierung wegen BugId 29307
+
+#ifdef _MSC_VER
+#pragma optimize ( "", off )
+#endif
+
+void ScTabView::SetCursor( SCCOL nPosX, SCROW nPosY, sal_Bool bNew )
+{
+ SCCOL nOldX = aViewData.GetCurX();
+ SCROW nOldY = aViewData.GetCurY();
+
+ // DeactivateIP nur noch bei MarkListHasChanged
+
+ if ( nPosX != nOldX || nPosY != nOldY || bNew )
+ {
+ ScTabViewShell* pViewShell = aViewData.GetViewShell();
+ bool bRefMode = ( pViewShell ? pViewShell->IsRefInputMode() : false );
+ if ( aViewData.HasEditView( aViewData.GetActivePart() ) && !bRefMode ) // 23259 oder so
+ {
+ UpdateInputLine();
+ }
+
+ HideAllCursors();
+
+ aViewData.SetCurX( nPosX );
+ aViewData.SetCurY( nPosY );
+
+ ShowAllCursors();
+
+ CursorPosChanged();
+ }
+}
+
+#ifdef _MSC_VER
+#pragma optimize ( "", on )
+#endif
+
+void ScTabView::CheckSelectionTransfer()
+{
+ if ( aViewData.IsActive() ) // only for active view
+ {
+ ScModule* pScMod = SC_MOD();
+ ScSelectionTransferObj* pOld = pScMod->GetSelectionTransfer();
+ if ( pOld && pOld->GetView() == this && pOld->StillValid() )
+ {
+ // selection not changed - nothing to do
+ }
+ else
+ {
+ ScSelectionTransferObj* pNew = ScSelectionTransferObj::CreateFromView( this );
+ if ( pNew )
+ {
+ // create new selection
+
+ if (pOld)
+ pOld->ForgetView();
+
+ uno::Reference<datatransfer::XTransferable> xRef( pNew );
+ pScMod->SetSelectionTransfer( pNew );
+ pNew->CopyToSelection( GetActiveWin() ); // may delete pOld
+ }
+ else if ( pOld && pOld->GetView() == this )
+ {
+ // remove own selection
+
+ pOld->ForgetView();
+ pScMod->SetSelectionTransfer( NULL );
+ TransferableHelper::ClearSelection( GetActiveWin() ); // may delete pOld
+ }
+ // else: selection from outside: leave unchanged
+ }
+ }
+}
+
+// Eingabezeile / Menues updaten
+// CursorPosChanged ruft SelectionChanged
+// SelectionChanged ruft CellContentChanged
+
+void ScTabView::CellContentChanged()
+{
+ SfxBindings& rBindings = aViewData.GetBindings();
+
+ rBindings.Invalidate( SID_ATTR_SIZE ); // -> Fehlermeldungen anzeigen
+ rBindings.Invalidate( SID_THESAURUS );
+ rBindings.Invalidate( SID_HYPERLINK_GETLINK );
+
+ InvalidateAttribs(); // Attribut-Updates
+ TestHintWindow(); // Eingabemeldung (Gueltigkeit)
+
+ aViewData.GetViewShell()->UpdateInputHandler();
+}
+
+void ScTabView::SelectionChanged()
+{
+ SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
+ if (pViewFrame)
+ {
+ uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController();
+ if (xController.is())
+ {
+ ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
+ if (pImp)
+ pImp->SelectionChanged();
+ }
+ }
+
+ UpdateAutoFillMark(); // also calls CheckSelectionTransfer
+
+ SfxBindings& rBindings = aViewData.GetBindings();
+
+ rBindings.Invalidate( SID_CURRENTCELL ); // -> Navigator
+ rBindings.Invalidate( SID_AUTO_FILTER ); // -> Menue
+ rBindings.Invalidate( FID_NOTE_VISIBLE );
+ rBindings.Invalidate( SID_DELETE_NOTE );
+
+ // Funktionen, die evtl disabled werden muessen
+
+ rBindings.Invalidate( FID_INS_ROWBRK );
+ rBindings.Invalidate( FID_INS_COLBRK );
+ rBindings.Invalidate( FID_DEL_ROWBRK );
+ rBindings.Invalidate( FID_DEL_COLBRK );
+ rBindings.Invalidate( FID_MERGE_ON );
+ rBindings.Invalidate( FID_MERGE_OFF );
+ rBindings.Invalidate( FID_MERGE_TOGGLE );
+ rBindings.Invalidate( SID_AUTOFILTER_HIDE );
+ rBindings.Invalidate( SID_UNFILTER );
+// rBindings.Invalidate( SID_IMPORT_DATA ); // jetzt wieder immer moeglich
+ rBindings.Invalidate( SID_REIMPORT_DATA );
+ rBindings.Invalidate( SID_REFRESH_DBAREA );
+ rBindings.Invalidate( SID_OUTLINE_SHOW );
+ rBindings.Invalidate( SID_OUTLINE_HIDE );
+ rBindings.Invalidate( SID_OUTLINE_REMOVE );
+ rBindings.Invalidate( FID_FILL_TO_BOTTOM );
+ rBindings.Invalidate( FID_FILL_TO_RIGHT );
+ rBindings.Invalidate( FID_FILL_TO_TOP );
+ rBindings.Invalidate( FID_FILL_TO_LEFT );
+ rBindings.Invalidate( FID_FILL_SERIES );
+ rBindings.Invalidate( SID_SCENARIOS );
+ rBindings.Invalidate( SID_AUTOFORMAT );
+ rBindings.Invalidate( SID_OPENDLG_TABOP );
+ rBindings.Invalidate( SID_DATA_SELECT );
+
+ rBindings.Invalidate( SID_CUT );
+ rBindings.Invalidate( SID_COPY );
+ rBindings.Invalidate( SID_PASTE );
+ rBindings.Invalidate( SID_PASTE_SPECIAL );
+
+ rBindings.Invalidate( FID_INS_ROW );
+ rBindings.Invalidate( FID_INS_COLUMN );
+ rBindings.Invalidate( FID_INS_CELL );
+ rBindings.Invalidate( FID_INS_CELLSDOWN );
+ rBindings.Invalidate( FID_INS_CELLSRIGHT );
+
+ rBindings.Invalidate( FID_CHG_COMMENT );
+
+ // nur wegen Zellschutz:
+
+ rBindings.Invalidate( SID_CELL_FORMAT_RESET );
+ rBindings.Invalidate( SID_DELETE );
+ rBindings.Invalidate( SID_DELETE_CONTENTS );
+ rBindings.Invalidate( FID_DELETE_CELL );
+ rBindings.Invalidate( FID_CELL_FORMAT );
+ rBindings.Invalidate( SID_ENABLE_HYPHENATION );
+ rBindings.Invalidate( SID_INSERT_POSTIT );
+ rBindings.Invalidate( SID_CHARMAP );
+ rBindings.Invalidate( SID_OPENDLG_FUNCTION );
+// rBindings.Invalidate( FID_CONDITIONAL_FORMAT );
+ rBindings.Invalidate( SID_OPENDLG_CONDFRMT );
+ rBindings.Invalidate( FID_VALIDATION );
+ rBindings.Invalidate( SID_EXTERNAL_SOURCE );
+ rBindings.Invalidate( SID_TEXT_TO_COLUMNS );
+ rBindings.Invalidate( SID_SORT_ASCENDING );
+ rBindings.Invalidate( SID_SORT_DESCENDING );
+
+ if (aViewData.GetViewShell()->HasAccessibilityObjects())
+ aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_CURSORCHANGED));
+
+ CellContentChanged();
+}
+
+void ScTabView::CursorPosChanged()
+{
+ sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
+ if ( !bRefMode ) // Abfrage, damit RefMode bei Tabellenwechsel funktioniert
+ aViewData.GetDocShell()->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );
+
+ // Broadcast, damit andere Views des Dokuments auch umschalten
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ bool bDP = NULL != pDoc->GetDPAtCursor(
+ aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
+ aViewData.GetViewShell()->SetPivotShell(bDP);
+
+ // UpdateInputHandler jetzt in CellContentChanged
+
+ SelectionChanged();
+
+ aViewData.SetTabStartCol( SC_TABSTART_NONE );
+}
+
+void ScTabView::TestHintWindow()
+{
+ // show input help window and list drop-down button for validity
+
+ sal_Bool bListValButton = sal_False;
+ ScAddress aListValPos;
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ const SfxUInt32Item* pItem = (const SfxUInt32Item*)
+ pDoc->GetAttr( aViewData.GetCurX(),
+ aViewData.GetCurY(),
+ aViewData.GetTabNo(),
+ ATTR_VALIDDATA );
+ if ( pItem->GetValue() )
+ {
+ const ScValidationData* pData = pDoc->GetValidationEntry( pItem->GetValue() );
+ DBG_ASSERT(pData,"ValidationData nicht gefunden");
+ String aTitle, aMessage;
+ if ( pData && pData->GetInput( aTitle, aMessage ) && aMessage.Len() > 0 )
+ {
+ //! Abfrage, ob an gleicher Stelle !!!!
+
+ DELETEZ(pInputHintWindow);
+
+ ScSplitPos eWhich = aViewData.GetActivePart();
+ Window* pWin = pGridWin[eWhich];
+ SCCOL nCol = aViewData.GetCurX();
+ SCROW nRow = aViewData.GetCurY();
+ Point aPos = aViewData.GetScrPos( nCol, nRow, eWhich );
+ Size aWinSize = pWin->GetOutputSizePixel();
+ // Cursor sichtbar?
+ if ( nCol >= aViewData.GetPosX(WhichH(eWhich)) &&
+ nRow >= aViewData.GetPosY(WhichV(eWhich)) &&
+ aPos.X() < aWinSize.Width() && aPos.Y() < aWinSize.Height() )
+ {
+ aPos += pWin->GetPosPixel(); // Position auf Frame
+ long nSizeXPix;
+ long nSizeYPix;
+ aViewData.GetMergeSizePixel( nCol, nRow, nSizeXPix, nSizeYPix );
+
+ // HintWindow anlegen, bestimmt seine Groesse selbst
+ pInputHintWindow = new ScHintWindow( pFrameWin, aTitle, aMessage );
+ Size aHintSize = pInputHintWindow->GetSizePixel();
+ Size aFrameWinSize = pFrameWin->GetOutputSizePixel();
+
+ // passende Position finden
+ // erster Versuch: unter dem Cursor
+ Point aHintPos( aPos.X() + nSizeXPix / 2, aPos.Y() + nSizeYPix + 3 );
+ if ( aHintPos.Y() + aHintSize.Height() > aFrameWinSize.Height() )
+ {
+ // zweiter Versuch: rechts vom Cursor
+ aHintPos = Point( aPos.X() + nSizeXPix + 3, aPos.Y() + nSizeYPix / 2 );
+ if ( aHintPos.X() + aHintSize.Width() > aFrameWinSize.Width() )
+ {
+ // dritter Versuch: ueber dem Cursor
+ aHintPos = Point( aPos.X() + nSizeXPix / 2,
+ aPos.Y() - aHintSize.Height() - 3 );
+ if ( aHintPos.Y() < 0 )
+ {
+ // oben und unten kein Platz - dann Default und abschneiden
+ aHintPos = Point( aPos.X() + nSizeXPix / 2, aPos.Y() + nSizeYPix + 3 );
+ aHintSize.Height() = aFrameWinSize.Height() - aHintPos.Y();
+ pInputHintWindow->SetSizePixel( aHintSize );
+ }
+ }
+ }
+
+ // X anpassen
+ if ( aHintPos.X() + aHintSize.Width() > aFrameWinSize.Width() )
+ aHintPos.X() = aFrameWinSize.Width() - aHintSize.Width();
+ // Y anpassen
+ if ( aHintPos.Y() + aHintSize.Height() > aFrameWinSize.Height() )
+ aHintPos.Y() = aFrameWinSize.Height() - aHintSize.Height();
+
+ pInputHintWindow->SetPosPixel( aHintPos );
+ pInputHintWindow->ToTop();
+ pInputHintWindow->Show();
+ }
+ }
+ else
+ DELETEZ(pInputHintWindow);
+
+ // list drop-down button
+ if ( pData && pData->HasSelectionList() )
+ {
+ aListValPos.Set( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
+ bListValButton = sal_True;
+ }
+ }
+ else
+ DELETEZ(pInputHintWindow);
+
+ for ( sal_uInt16 i=0; i<4; i++ )
+ if ( pGridWin[i] && pGridWin[i]->IsVisible() )
+ pGridWin[i]->UpdateListValPos( bListValButton, aListValPos );
+}
+
+void ScTabView::RemoveHintWindow()
+{
+ DELETEZ(pInputHintWindow);
+}
+
+
+// find window that should not be over the cursor
+Window* lcl_GetCareWin(SfxViewFrame* pViewFrm)
+{
+ //! auch Spelling ??? (dann beim Aufruf Membervariable setzen)
+
+ // Suchen & Ersetzen
+ if ( pViewFrm->HasChildWindow(SID_SEARCH_DLG) )
+ {
+ SfxChildWindow* pChild = pViewFrm->GetChildWindow(SID_SEARCH_DLG);
+ if (pChild)
+ {
+ Window* pWin = pChild->GetWindow();
+ if (pWin && pWin->IsVisible())
+ return pWin;
+ }
+ }
+
+ // Aenderungen uebernehmen
+ if ( pViewFrm->HasChildWindow(FID_CHG_ACCEPT) )
+ {
+ SfxChildWindow* pChild = pViewFrm->GetChildWindow(FID_CHG_ACCEPT);
+ if (pChild)
+ {
+ Window* pWin = pChild->GetWindow();
+ if (pWin && pWin->IsVisible())
+ return pWin;
+ }
+ }
+
+ return NULL;
+}
+
+ //
+ // Bildschirm an Cursorposition anpassen
+ //
+
+void ScTabView::AlignToCursor( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
+ const ScSplitPos* pWhich )
+{
+ //
+ // aktiven Teil umschalten jetzt hier
+ //
+
+ ScSplitPos eActive = aViewData.GetActivePart();
+ ScHSplitPos eActiveX = WhichH(eActive);
+ ScVSplitPos eActiveY = WhichV(eActive);
+ sal_Bool bHFix = (aViewData.GetHSplitMode() == SC_SPLIT_FIX);
+ sal_Bool bVFix = (aViewData.GetVSplitMode() == SC_SPLIT_FIX);
+ if (bHFix)
+ if (eActiveX == SC_SPLIT_LEFT && nCurX >= (SCsCOL)aViewData.GetFixPosX())
+ {
+ ActivatePart( (eActiveY==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT );
+ eActiveX = SC_SPLIT_RIGHT;
+ }
+ if (bVFix)
+ if (eActiveY == SC_SPLIT_TOP && nCurY >= (SCsROW)aViewData.GetFixPosY())
+ {
+ ActivatePart( (eActiveX==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT );
+ eActiveY = SC_SPLIT_BOTTOM;
+ }
+
+ //
+ // eigentliches Align
+ //
+
+ if ( eMode != SC_FOLLOW_NONE )
+ {
+ ScSplitPos eAlign;
+ if (pWhich)
+ eAlign = *pWhich;
+ else
+ eAlign = aViewData.GetActivePart();
+ ScHSplitPos eAlignX = WhichH(eAlign);
+ ScVSplitPos eAlignY = WhichV(eAlign);
+
+ SCsCOL nDeltaX = (SCsCOL) aViewData.GetPosX(eAlignX);
+ SCsROW nDeltaY = (SCsROW) aViewData.GetPosY(eAlignY);
+ SCsCOL nSizeX = (SCsCOL) aViewData.VisibleCellsX(eAlignX);
+ SCsROW nSizeY = (SCsROW) aViewData.VisibleCellsY(eAlignY);
+
+ long nCellSizeX;
+ long nCellSizeY;
+ if ( nCurX >= 0 && nCurY >= 0 )
+ aViewData.GetMergeSizePixel( (SCCOL)nCurX, (SCROW)nCurY, nCellSizeX, nCellSizeY );
+ else
+ nCellSizeX = nCellSizeY = 0;
+ Size aScrSize = aViewData.GetScrSize();
+ long nSpaceX = ( aScrSize.Width() - nCellSizeX ) / 2;
+ long nSpaceY = ( aScrSize.Height() - nCellSizeY ) / 2;
+ // nSpaceY: desired start position of cell for FOLLOW_JUMP, modified if dialog interferes
+
+ sal_Bool bForceNew = sal_False; // force new calculation of JUMP position (vertical only)
+
+ // VisibleCellsY == CellsAtY( GetPosY( eWhichY ), 1, eWhichY )
+
+ //-------------------------------------------------------------------------------
+ // falls z.B. Suchen-Dialog offen ist, Cursor nicht hinter den Dialog stellen
+ // wenn moeglich, die Zeile mit dem Cursor oberhalb oder unterhalb des Dialogs
+
+ //! nicht, wenn schon komplett sichtbar
+
+ if ( eMode == SC_FOLLOW_JUMP )
+ {
+ Window* pCare = lcl_GetCareWin( aViewData.GetViewShell()->GetViewFrame() );
+ if (pCare)
+ {
+ sal_Bool bLimit = sal_False;
+ Rectangle aDlgPixel;
+ Size aWinSize;
+ Window* pWin = GetActiveWin();
+ if (pWin)
+ {
+ aDlgPixel = pCare->GetWindowExtentsRelative( pWin );
+ aWinSize = pWin->GetOutputSizePixel();
+ // ueberdeckt der Dialog das GridWin?
+ if ( aDlgPixel.Right() >= 0 && aDlgPixel.Left() < aWinSize.Width() )
+ {
+ if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX ||
+ nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY )
+ bLimit = sal_True; // es wird sowieso gescrollt
+ else
+ {
+ // Cursor ist auf dem Bildschirm
+ Point aStart = aViewData.GetScrPos( nCurX, nCurY, eAlign );
+ long nCSX, nCSY;
+ aViewData.GetMergeSizePixel( nCurX, nCurY, nCSX, nCSY );
+ Rectangle aCursor( aStart, Size( nCSX, nCSY ) );
+ if ( aCursor.IsOver( aDlgPixel ) )
+ bLimit = sal_True; // Zelle vom Dialog ueberdeckt
+ }
+ }
+ }
+
+ if (bLimit)
+ {
+ sal_Bool bBottom = sal_False;
+ long nTopSpace = aDlgPixel.Top();
+ long nBotSpace = aWinSize.Height() - aDlgPixel.Bottom();
+ if ( nBotSpace > 0 && nBotSpace > nTopSpace )
+ {
+ long nDlgBot = aDlgPixel.Bottom();
+ SCsCOL nWPosX;
+ SCsROW nWPosY;
+ aViewData.GetPosFromPixel( 0,nDlgBot, eAlign, nWPosX, nWPosY );
+ ++nWPosY; // unter der letzten betroffenen Zelle
+
+ SCsROW nDiff = nWPosY - nDeltaY;
+ if ( nCurY >= nDiff ) // Pos. kann nicht negativ werden
+ {
+ nSpaceY = nDlgBot + ( nBotSpace - nCellSizeY ) / 2;
+ bBottom = sal_True;
+ bForceNew = sal_True;
+ }
+ }
+ if ( !bBottom && nTopSpace > 0 )
+ {
+ nSpaceY = ( nTopSpace - nCellSizeY ) / 2;
+ bForceNew = sal_True;
+ }
+ }
+ }
+ }
+ //-------------------------------------------------------------------------------
+
+ SCsCOL nNewDeltaX = nDeltaX;
+ SCsROW nNewDeltaY = nDeltaY;
+ sal_Bool bDoLine = sal_False;
+
+ switch (eMode)
+ {
+ case SC_FOLLOW_JUMP:
+ if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
+ {
+ nNewDeltaX = nCurX - static_cast<SCsCOL>(aViewData.CellsAtX( nCurX, -1, eAlignX, static_cast<sal_uInt16>(nSpaceX) ));
+ if (nNewDeltaX < 0) nNewDeltaX = 0;
+ nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
+ }
+ if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY || bForceNew )
+ {
+ nNewDeltaY = nCurY - static_cast<SCsROW>(aViewData.CellsAtY( nCurY, -1, eAlignY, static_cast<sal_uInt16>(nSpaceY) ));
+ if (nNewDeltaY < 0) nNewDeltaY = 0;
+ nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
+ }
+ bDoLine = sal_True;
+ break;
+
+ case SC_FOLLOW_LINE:
+ bDoLine = sal_True;
+ break;
+
+ case SC_FOLLOW_FIX:
+ if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
+ {
+ nNewDeltaX = nDeltaX + nCurX - aViewData.GetCurX();
+ if (nNewDeltaX < 0) nNewDeltaX = 0;
+ nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
+ }
+ if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY )
+ {
+ nNewDeltaY = nDeltaY + nCurY - aViewData.GetCurY();
+ if (nNewDeltaY < 0) nNewDeltaY = 0;
+ nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
+ }
+
+ // like old version of SC_FOLLOW_JUMP:
+
+ if ( nCurX < nNewDeltaX || nCurX >= nNewDeltaX+nSizeX )
+ {
+ nNewDeltaX = nCurX - (nSizeX / 2);
+ if (nNewDeltaX < 0) nNewDeltaX = 0;
+ nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
+ }
+ if ( nCurY < nNewDeltaY || nCurY >= nNewDeltaY+nSizeY )
+ {
+ nNewDeltaY = nCurY - (nSizeY / 2);
+ if (nNewDeltaY < 0) nNewDeltaY = 0;
+ nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
+ }
+
+ bDoLine = sal_True;
+ break;
+
+ case SC_FOLLOW_NONE:
+ break;
+ default:
+ DBG_ERROR("Falscher Cursormodus");
+ break;
+ }
+
+ if (bDoLine)
+ {
+ while ( nCurX >= nNewDeltaX+nSizeX )
+ {
+ nNewDeltaX = nCurX-nSizeX+1;
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ while ( nNewDeltaX < MAXCOL && !pDoc->GetColWidth( nNewDeltaX, nTab ) )
+ ++nNewDeltaX;
+ nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
+ }
+ while ( nCurY >= nNewDeltaY+nSizeY )
+ {
+ nNewDeltaY = nCurY-nSizeY+1;
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ while ( nNewDeltaY < MAXROW && !pDoc->GetRowHeight( nNewDeltaY, nTab ) )
+ ++nNewDeltaY;
+ nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
+ }
+ if ( nCurX < nNewDeltaX ) nNewDeltaX = nCurX;
+ if ( nCurY < nNewDeltaY ) nNewDeltaY = nCurY;
+ }
+
+ if ( nNewDeltaX != nDeltaX )
+ nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
+ if (nNewDeltaX+nSizeX-1 > MAXCOL) nNewDeltaX = MAXCOL-nSizeX+1;
+ if (nNewDeltaX < 0) nNewDeltaX = 0;
+
+ if ( nNewDeltaY != nDeltaY )
+ nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
+ if (nNewDeltaY+nSizeY-1 > MAXROW) nNewDeltaY = MAXROW-nSizeY+1;
+ if (nNewDeltaY < 0) nNewDeltaY = 0;
+
+ if ( nNewDeltaX != nDeltaX ) ScrollX( nNewDeltaX - nDeltaX, eAlignX );
+ if ( nNewDeltaY != nDeltaY ) ScrollY( nNewDeltaY - nDeltaY, eAlignY );
+ }
+
+ //
+ // nochmal aktiven Teil umschalten
+ //
+
+ if (bHFix)
+ if (eActiveX == SC_SPLIT_RIGHT && nCurX < (SCsCOL)aViewData.GetFixPosX())
+ {
+ ActivatePart( (eActiveY==SC_SPLIT_TOP) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT );
+ eActiveX = SC_SPLIT_LEFT;
+ }
+ if (bVFix)
+ if (eActiveY == SC_SPLIT_BOTTOM && nCurY < (SCsROW)aViewData.GetFixPosY())
+ {
+ ActivatePart( (eActiveX==SC_SPLIT_LEFT) ? SC_SPLIT_TOPLEFT : SC_SPLIT_TOPRIGHT );
+ eActiveY = SC_SPLIT_TOP;
+ }
+}
+
+sal_Bool ScTabView::SelMouseButtonDown( const MouseEvent& rMEvt )
+{
+ sal_Bool bRet = sal_False;
+
+ // #i3875# *Hack*
+ sal_Bool bMod1Locked = aViewData.GetViewShell()->GetLockedModifiers() & KEY_MOD1 ? sal_True : sal_False;
+ aViewData.SetSelCtrlMouseClick( rMEvt.IsMod1() || bMod1Locked );
+
+ if ( pSelEngine )
+ {
+ bMoveIsShift = rMEvt.IsShift();
+ bRet = pSelEngine->SelMouseButtonDown( rMEvt );
+ bMoveIsShift = sal_False;
+ }
+
+ aViewData.SetSelCtrlMouseClick( sal_False ); // #i3875# *Hack*
+
+ return bRet;
+}
+
+ //
+ // MoveCursor - mit Anpassung des Bildausschnitts
+ //
+
+void ScTabView::MoveCursorAbs( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
+ sal_Bool bShift, sal_Bool bControl, sal_Bool bKeepOld, sal_Bool bKeepSel )
+{
+ if (!bKeepOld)
+ aViewData.ResetOldCursor();
+
+ if (nCurX < 0) nCurX = 0;
+ if (nCurY < 0) nCurY = 0;
+ if (nCurX > MAXCOL) nCurX = MAXCOL;
+ if (nCurY > MAXROW) nCurY = MAXROW;
+
+ HideAllCursors();
+
+ if ( bShift && bNewStartIfMarking && IsBlockMode() )
+ {
+ // used for ADD selection mode: start a new block from the cursor position
+ DoneBlockMode( sal_True );
+ InitBlockMode( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo(), sal_True );
+ }
+
+ // aktiven Teil umschalten jetzt in AlignToCursor
+
+ AlignToCursor( nCurX, nCurY, eMode );
+ //! auf OS/2: SC_FOLLOW_JUMP statt SC_FOLLOW_LINE, um Nachlaufen zu verhindern ???
+
+ if (bKeepSel)
+ SetCursor( nCurX, nCurY ); // Markierung stehenlassen
+ else
+ {
+ sal_Bool bSame = ( nCurX == aViewData.GetCurX() && nCurY == aViewData.GetCurY() );
+ bMoveIsShift = bShift;
+ pSelEngine->CursorPosChanging( bShift, bControl );
+ bMoveIsShift = sal_False;
+ aFunctionSet.SetCursorAtCell( nCurX, nCurY, sal_False );
+
+ // Wenn der Cursor nicht bewegt wurde, muss das SelectionChanged fuer das
+ // Aufheben der Selektion hier einzeln passieren:
+ if (bSame)
+ SelectionChanged();
+ }
+
+ ShowAllCursors();
+}
+
+void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
+ sal_Bool bShift, sal_Bool bKeepSel )
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ bool bSkipProtected = false, bSkipUnprotected = false;
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ if ( pProtect && pProtect->isProtected() )
+ {
+ bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+ bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
+ }
+
+ if ( bSkipProtected && bSkipUnprotected )
+ return;
+
+ SCsCOL nOldX;
+ SCsROW nOldY;
+ SCsCOL nCurX;
+ SCsROW nCurY;
+ if ( aViewData.IsRefMode() )
+ {
+ nOldX = (SCsCOL) aViewData.GetRefEndX();
+ nOldY = (SCsROW) aViewData.GetRefEndY();
+ nCurX = nOldX + nMovX;
+ nCurY = nOldY + nMovY;
+ }
+ else
+ {
+ nOldX = (SCsCOL) aViewData.GetCurX();
+ nOldY = (SCsROW) aViewData.GetCurY();
+ nCurX = (nMovX != 0) ? nOldX+nMovX : (SCsCOL) aViewData.GetOldCurX();
+ nCurY = (nMovY != 0) ? nOldY+nMovY : (SCsROW) aViewData.GetOldCurY();
+ }
+
+ sal_Bool bSkipCell = sal_False;
+ aViewData.ResetOldCursor();
+
+ if (nMovX != 0 && VALIDCOLROW(nCurX,nCurY))
+ {
+ sal_Bool bHFlip = sal_False;
+ do
+ {
+ 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)
+ bSkipCell = !pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
+
+ if (bSkipCell)
+ {
+ if ( nCurX<=0 || nCurX>=MAXCOL )
+ {
+ if (bHFlip)
+ {
+ nCurX = nOldX;
+ bSkipCell = sal_False;
+ }
+ else
+ {
+ nMovX = -nMovX;
+ if (nMovX > 0) ++nCurX; else --nCurX; // zuruecknehmen
+ bHFlip = sal_True;
+ }
+ }
+ else
+ if (nMovX > 0) ++nCurX; else --nCurX;
+ }
+ }
+ while (bSkipCell);
+
+ if (pDoc->IsVerOverlapped( nCurX, nCurY, nTab ))
+ {
+ aViewData.SetOldCursor( nCurX,nCurY );
+ while (pDoc->IsVerOverlapped( nCurX, nCurY, nTab ))
+ --nCurY;
+ }
+ }
+
+ if (nMovY != 0 && VALIDCOLROW(nCurX,nCurY))
+ {
+ sal_Bool bVFlip = sal_False;
+ do
+ {
+ 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)
+ bSkipCell = !pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
+
+ if (bSkipCell)
+ {
+ if ( nCurY<=0 || nCurY>=MAXROW )
+ {
+ if (bVFlip)
+ {
+ nCurY = nOldY;
+ bSkipCell = sal_False;
+ }
+ else
+ {
+ nMovY = -nMovY;
+ if (nMovY > 0) ++nCurY; else --nCurY; // zuruecknehmen
+ bVFlip = sal_True;
+ }
+ }
+ else
+ if (nMovY > 0) ++nCurY; else --nCurY;
+ }
+ }
+ while (bSkipCell);
+
+ if (pDoc->IsHorOverlapped( nCurX, nCurY, nTab ))
+ {
+ aViewData.SetOldCursor( nCurX,nCurY );
+ while (pDoc->IsHorOverlapped( nCurX, nCurY, nTab ))
+ --nCurX;
+ }
+ }
+
+ MoveCursorAbs( nCurX, nCurY, eMode, bShift, sal_False, sal_True, bKeepSel );
+}
+
+void ScTabView::MoveCursorPage( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, sal_Bool bShift, sal_Bool bKeepSel )
+{
+ SCCOL nCurX;
+ SCROW nCurY;
+ aViewData.GetMoveCursor( nCurX,nCurY );
+
+ ScSplitPos eWhich = aViewData.GetActivePart();
+ ScHSplitPos eWhichX = WhichH( eWhich );
+ ScVSplitPos eWhichY = WhichV( eWhich );
+
+ SCsCOL nPageX;
+ SCsROW nPageY;
+ if (nMovX >= 0)
+ nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, 1, eWhichX )) * nMovX;
+ else
+ nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, -1, eWhichX )) * nMovX;
+
+ if (nMovY >= 0)
+ nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, 1, eWhichY )) * nMovY;
+ else
+ nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, -1, eWhichY )) * nMovY;
+
+ if (nMovX != 0 && nPageX == 0) nPageX = (nMovX>0) ? 1 : -1;
+ if (nMovY != 0 && nPageY == 0) nPageY = (nMovY>0) ? 1 : -1;
+
+ MoveCursorRel( nPageX, nPageY, eMode, bShift, bKeepSel );
+}
+
+void ScTabView::MoveCursorArea( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, sal_Bool bShift, sal_Bool bKeepSel )
+{
+ SCCOL nCurX;
+ SCROW nCurY;
+ aViewData.GetMoveCursor( nCurX,nCurY );
+ SCCOL nNewX = nCurX;
+ SCROW nNewY = nCurY;
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ // FindAreaPos kennt nur -1 oder 1 als Richtung
+
+ SCsCOLROW i;
+ if ( nMovX > 0 )
+ for ( i=0; i<nMovX; i++ )
+ pDoc->FindAreaPos( nNewX, nNewY, nTab, 1, 0 );
+ if ( nMovX < 0 )
+ for ( i=0; i<-nMovX; i++ )
+ pDoc->FindAreaPos( nNewX, nNewY, nTab, -1, 0 );
+ if ( nMovY > 0 )
+ for ( i=0; i<nMovY; i++ )
+ pDoc->FindAreaPos( nNewX, nNewY, nTab, 0, 1 );
+ if ( nMovY < 0 )
+ for ( i=0; i<-nMovY; i++ )
+ pDoc->FindAreaPos( nNewX, nNewY, nTab, 0, -1 );
+
+ if (eMode==SC_FOLLOW_JUMP) // unten/rechts nicht zuviel grau anzeigen
+ {
+ if (nMovX != 0 && nNewX == MAXCOL)
+ eMode = SC_FOLLOW_LINE;
+ if (nMovY != 0 && nNewY == MAXROW)
+ eMode = SC_FOLLOW_LINE;
+ }
+
+ MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY, eMode, bShift, bKeepSel );
+}
+
+void ScTabView::MoveCursorEnd( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, sal_Bool bShift, sal_Bool bKeepSel )
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ SCCOL nCurX;
+ SCROW nCurY;
+ aViewData.GetMoveCursor( nCurX,nCurY );
+ SCCOL nNewX = nCurX;
+ SCROW nNewY = nCurY;
+
+ SCCOL nUsedX = 0;
+ SCROW nUsedY = 0;
+ if ( nMovX > 0 || nMovY > 0 )
+ pDoc->GetPrintArea( nTab, nUsedX, nUsedY ); // Ende holen
+
+ if (nMovX<0)
+ nNewX=0;
+ else if (nMovX>0)
+ nNewX=nUsedX; // letzter benutzter Bereich
+
+ if (nMovY<0)
+ nNewY=0;
+ else if (nMovY>0)
+ nNewY=nUsedY;
+
+ aViewData.ResetOldCursor();
+ MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY, eMode, bShift, bKeepSel );
+}
+
+void ScTabView::MoveCursorScreen( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, sal_Bool bShift )
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ SCCOL nCurX;
+ SCROW nCurY;
+ aViewData.GetMoveCursor( nCurX,nCurY );
+ SCCOL nNewX = nCurX;
+ SCROW nNewY = nCurY;
+
+ ScSplitPos eWhich = aViewData.GetActivePart();
+ SCCOL nPosX = aViewData.GetPosX( WhichH(eWhich) );
+ SCROW nPosY = aViewData.GetPosY( WhichV(eWhich) );
+
+ SCCOL nAddX = aViewData.VisibleCellsX( WhichH(eWhich) );
+ if (nAddX != 0)
+ --nAddX;
+ SCROW nAddY = aViewData.VisibleCellsY( WhichV(eWhich) );
+ if (nAddY != 0)
+ --nAddY;
+
+ if (nMovX<0)
+ nNewX=nPosX;
+ else if (nMovX>0)
+ nNewX=nPosX+nAddX;
+
+ if (nMovY<0)
+ nNewY=nPosY;
+ else if (nMovY>0)
+ nNewY=nPosY+nAddY;
+
+// aViewData.ResetOldCursor();
+ aViewData.SetOldCursor( nNewX,nNewY );
+
+ while (pDoc->IsHorOverlapped( nNewX, nNewY, nTab ))
+ --nNewX;
+ while (pDoc->IsVerOverlapped( nNewX, nNewY, nTab ))
+ --nNewY;
+
+ MoveCursorAbs( nNewX, nNewY, eMode, bShift, sal_False, sal_True );
+}
+
+void ScTabView::MoveCursorEnter( sal_Bool bShift ) // bShift -> hoch/runter
+{
+ const ScInputOptions& rOpt = SC_MOD()->GetInputOptions();
+ if (!rOpt.GetMoveSelection())
+ {
+ aViewData.UpdateInputHandler(sal_True);
+ return;
+ }
+
+ SCsCOL nMoveX = 0;
+ SCsROW nMoveY = 0;
+ switch ((ScDirection)rOpt.GetMoveDir())
+ {
+ case DIR_BOTTOM:
+ nMoveY = bShift ? -1 : 1;
+ break;
+ case DIR_RIGHT:
+ nMoveX = bShift ? -1 : 1;
+ break;
+ case DIR_TOP:
+ nMoveY = bShift ? 1 : -1;
+ break;
+ case DIR_LEFT:
+ nMoveX = bShift ? 1 : -1;
+ break;
+ }
+
+ ScMarkData& rMark = aViewData.GetMarkData();
+ if (rMark.IsMarked() || rMark.IsMultiMarked())
+ {
+ SCCOL nCurX;
+ SCROW nCurY;
+ aViewData.GetMoveCursor( nCurX,nCurY );
+ SCCOL nNewX = nCurX;
+ SCROW nNewY = nCurY;
+ SCTAB nTab = aViewData.GetTabNo();
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ pDoc->GetNextPos( nNewX,nNewY, nTab, nMoveX,nMoveY, sal_True,sal_False, rMark );
+
+ MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY,
+ SC_FOLLOW_LINE, sal_False, sal_True );
+
+ // update input line even if cursor was not moved
+ if ( nNewX == nCurX && nNewY == nCurY )
+ aViewData.UpdateInputHandler(sal_True);
+ }
+ else
+ {
+ if ( nMoveY != 0 && !nMoveX )
+ {
+ // nach Tab und Enter wieder zur Ausgangsspalte
+ SCCOL nTabCol = aViewData.GetTabStartCol();
+ if (nTabCol != SC_TABSTART_NONE)
+ {
+ SCCOL nCurX;
+ SCROW nCurY;
+ aViewData.GetMoveCursor( nCurX,nCurY );
+ nMoveX = ((SCsCOL)nTabCol)-(SCsCOL)nCurX;
+ }
+ }
+
+ MoveCursorRel( nMoveX,nMoveY, SC_FOLLOW_LINE, sal_False );
+ }
+}
+
+
+sal_Bool ScTabView::MoveCursorKeyInput( const KeyEvent& rKeyEvent )
+{
+ const KeyCode& rKCode = rKeyEvent.GetKeyCode();
+
+ enum { MOD_NONE, MOD_CTRL, MOD_ALT, MOD_BOTH } eModifier =
+ rKCode.IsMod1() ?
+ (rKCode.IsMod2() ? MOD_BOTH : MOD_CTRL) :
+ (rKCode.IsMod2() ? MOD_ALT : MOD_NONE);
+
+ sal_Bool bSel = rKCode.IsShift();
+ sal_uInt16 nCode = rKCode.GetCode();
+
+ // CURSOR keys
+ SCsCOL nDX = 0;
+ SCsROW nDY = 0;
+ switch( nCode )
+ {
+ case KEY_LEFT: nDX = -1; break;
+ case KEY_RIGHT: nDX = 1; break;
+ case KEY_UP: nDY = -1; break;
+ case KEY_DOWN: nDY = 1; break;
+ }
+ if( nDX != 0 || nDY != 0 )
+ {
+ switch( eModifier )
+ {
+ case MOD_NONE: MoveCursorRel( nDX, nDY, SC_FOLLOW_LINE, bSel ); break;
+ case MOD_CTRL: MoveCursorArea( nDX, nDY, SC_FOLLOW_JUMP, bSel ); break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ // always sal_True to suppress changes of col/row size (ALT+CURSOR)
+ return sal_True;
+ }
+
+ // PAGEUP/PAGEDOWN
+ if( (nCode == KEY_PAGEUP) || (nCode == KEY_PAGEDOWN) )
+ {
+ nDX = (nCode == KEY_PAGEUP) ? -1 : 1;
+ switch( eModifier )
+ {
+ case MOD_NONE: MoveCursorPage( 0, static_cast<SCsCOLROW>(nDX), SC_FOLLOW_FIX, bSel ); break;
+ case MOD_ALT: MoveCursorPage( nDX, 0, SC_FOLLOW_FIX, bSel ); break;
+ case MOD_CTRL: SelectNextTab( nDX ); break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ return sal_True;
+ }
+
+ // HOME/END
+ if( (nCode == KEY_HOME) || (nCode == KEY_END) )
+ {
+ nDX = (nCode == KEY_HOME) ? -1 : 1;
+ ScFollowMode eMode = (nCode == KEY_HOME) ? SC_FOLLOW_LINE : SC_FOLLOW_JUMP;
+ switch( eModifier )
+ {
+ case MOD_NONE: MoveCursorEnd( nDX, 0, eMode, bSel ); break;
+ case MOD_CTRL: MoveCursorEnd( nDX, static_cast<SCsCOLROW>(nDX), eMode, bSel ); break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+
+ // naechste/vorherige nicht geschuetzte Zelle
+void ScTabView::FindNextUnprot( sal_Bool bShift, sal_Bool bInSelection )
+{
+ short nMove = bShift ? -1 : 1;
+
+ ScMarkData& rMark = aViewData.GetMarkData();
+ sal_Bool bMarked = bInSelection && (rMark.IsMarked() || rMark.IsMultiMarked());
+
+ SCCOL nCurX;
+ SCROW nCurY;
+ aViewData.GetMoveCursor( nCurX,nCurY );
+ SCCOL nNewX = nCurX;
+ SCROW nNewY = nCurY;
+ SCTAB nTab = aViewData.GetTabNo();
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ pDoc->GetNextPos( nNewX,nNewY, nTab, nMove,0, bMarked,sal_True, rMark );
+
+ SCCOL nTabCol = aViewData.GetTabStartCol();
+ if ( nTabCol == SC_TABSTART_NONE )
+ nTabCol = nCurX; // auf diese Spalte zurueck bei Enter
+
+ MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY,
+ SC_FOLLOW_LINE, sal_False, sal_True );
+
+ // in MoveCursorRel wird die TabCol zurueckgesetzt...
+ aViewData.SetTabStartCol( nTabCol );
+}
+
+void ScTabView::MarkColumns()
+{
+ SCCOL nStartCol;
+ SCCOL nEndCol;
+
+ ScMarkData& rMark = aViewData.GetMarkData();
+ if (rMark.IsMarked())
+ {
+ ScRange aMarkRange;
+ rMark.GetMarkArea( aMarkRange );
+ nStartCol = aMarkRange.aStart.Col();
+ nEndCol = aMarkRange.aEnd.Col();
+ }
+ else
+ {
+ SCROW nDummy;
+ aViewData.GetMoveCursor( nStartCol, nDummy );
+ nEndCol=nStartCol;
+ }
+
+ SCTAB nTab = aViewData.GetTabNo();
+ DoneBlockMode();
+ InitBlockMode( nStartCol,0, nTab );
+ MarkCursor( nEndCol,MAXROW, nTab );
+ SelectionChanged();
+}
+
+void ScTabView::MarkRows()
+{
+ SCROW nStartRow;
+ SCROW nEndRow;
+
+ ScMarkData& rMark = aViewData.GetMarkData();
+ if (rMark.IsMarked())
+ {
+ ScRange aMarkRange;
+ rMark.GetMarkArea( aMarkRange );
+ nStartRow = aMarkRange.aStart.Row();
+ nEndRow = aMarkRange.aEnd.Row();
+ }
+ else
+ {
+ SCCOL nDummy;
+ aViewData.GetMoveCursor( nDummy, nStartRow );
+ nEndRow=nStartRow;
+ }
+
+ SCTAB nTab = aViewData.GetTabNo();
+ DoneBlockMode();
+ InitBlockMode( 0,nStartRow, nTab );
+ MarkCursor( MAXCOL,nEndRow, nTab );
+ SelectionChanged();
+}
+
+void ScTabView::MarkDataArea( sal_Bool bIncludeCursor )
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ SCCOL nStartCol = aViewData.GetCurX();
+ SCROW nStartRow = aViewData.GetCurY();
+ SCCOL nEndCol = nStartCol;
+ SCROW nEndRow = nStartRow;
+
+ pDoc->GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, bIncludeCursor, false );
+
+ HideAllCursors();
+ DoneBlockMode();
+ InitBlockMode( nStartCol, nStartRow, nTab );
+ MarkCursor( nEndCol, nEndRow, nTab );
+ ShowAllCursors();
+
+ SelectionChanged();
+}
+
+void ScTabView::MarkMatrixFormula()
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ ScAddress aCursor( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
+ ScRange aMatrix;
+ if ( pDoc->GetMatrixFormulaRange( aCursor, aMatrix ) )
+ {
+ MarkRange( aMatrix, sal_False ); // cursor is already within the range
+ }
+}
+
+void ScTabView::MarkRange( const ScRange& rRange, sal_Bool bSetCursor, sal_Bool bContinue )
+{
+ SCTAB nTab = rRange.aStart.Tab();
+ SetTabNo( nTab );
+
+ HideAllCursors();
+ DoneBlockMode( bContinue ); // bContinue==sal_True -> clear old mark
+ if (bSetCursor) // Wenn Cursor gesetzt wird, immer auch alignen
+ {
+ SCCOL nAlignX = rRange.aStart.Col();
+ SCROW nAlignY = rRange.aStart.Row();
+ if ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == MAXCOL )
+ nAlignX = aViewData.GetPosX(WhichH(aViewData.GetActivePart()));
+ if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW )
+ nAlignY = aViewData.GetPosY(WhichV(aViewData.GetActivePart()));
+ AlignToCursor( nAlignX, nAlignY, SC_FOLLOW_JUMP );
+ }
+ InitBlockMode( rRange.aStart.Col(), rRange.aStart.Row(), nTab );
+ MarkCursor( rRange.aEnd.Col(), rRange.aEnd.Row(), nTab );
+ if (bSetCursor)
+ {
+ SCCOL nPosX = rRange.aStart.Col();
+ SCROW nPosY = rRange.aStart.Row();
+ ScDocument* pDoc = aViewData.GetDocument();
+
+ while (pDoc->IsHorOverlapped( nPosX, nPosY, nTab )) //! ViewData !!!
+ --nPosX;
+ while (pDoc->IsVerOverlapped( nPosX, nPosY, nTab ))
+ --nPosY;
+
+ aViewData.ResetOldCursor();
+ SetCursor( nPosX, nPosY );
+ }
+ ShowAllCursors();
+
+ SelectionChanged();
+}
+
+void ScTabView::Unmark()
+{
+ ScMarkData& rMark = aViewData.GetMarkData();
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ {
+ SCCOL nCurX;
+ SCROW nCurY;
+ aViewData.GetMoveCursor( nCurX,nCurY );
+ MoveCursorAbs( nCurX, nCurY, SC_FOLLOW_NONE, sal_False, sal_False );
+
+ SelectionChanged();
+ }
+}
+
+void ScTabView::SetMarkData( const ScMarkData& rNew )
+{
+ DoneBlockMode();
+ InitOwnBlockMode();
+ aViewData.GetMarkData() = rNew;
+
+ MarkDataChanged();
+}
+
+void ScTabView::MarkDataChanged()
+{
+ // has to be called after making direct changes to mark data (not via MarkCursor etc)
+
+ UpdateSelectionOverlay();
+}
+
+void ScTabView::SelectNextTab( short nDir, sal_Bool bExtendSelection )
+{
+ if (!nDir) return;
+ DBG_ASSERT( nDir==-1 || nDir==1, "SelectNextTab: falscher Wert");
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ if (nDir<0)
+ {
+ if (!nTab) return;
+ --nTab;
+ while (!pDoc->IsVisible(nTab))
+ {
+ if (!nTab) return;
+ --nTab;
+ }
+ }
+ else
+ {
+ SCTAB nCount = pDoc->GetTableCount();
+ ++nTab;
+ if (nTab >= nCount) return;
+ while (!pDoc->IsVisible(nTab))
+ {
+ ++nTab;
+ if (nTab >= nCount) return;
+ }
+ }
+
+ SetTabNo( nTab, sal_False, bExtendSelection );
+ PaintExtras();
+}
+
+
+// SetTabNo - angezeigte Tabelle
+
+void ScTabView::SetTabNo( SCTAB nTab, sal_Bool bNew, sal_Bool bExtendSelection, bool bSameTabButMoved )
+{
+ if ( !ValidTab(nTab) )
+ {
+ DBG_ERROR("SetTabNo: falsche Tabelle");
+ return;
+ }
+
+ if ( nTab != aViewData.GetTabNo() || bNew )
+ {
+ // #57724# Die FormShell moechte vor dem Umschalten benachrichtigt werden
+ FmFormShell* pFormSh = aViewData.GetViewShell()->GetFormShell();
+ if (pFormSh)
+ {
+ sal_Bool bAllowed = sal::static_int_cast<sal_Bool>( pFormSh->PrepareClose( sal_True ) );
+ if (!bAllowed)
+ {
+ //! Fehlermeldung? oder macht das die FormShell selber?
+ //! Fehler-Flag zurueckgeben und Aktionen abbrechen
+
+ return; // Die FormShell sagt, es kann nicht umgeschaltet werden
+ }
+ }
+
+ // nicht InputEnterHandler wegen Referenzeingabe !
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ pDoc->MakeTable( nTab );
+
+ // Update pending row heights before switching the sheet, so Reschedule from the progress bar
+ // doesn't paint the new sheet with old heights
+ aViewData.GetDocShell()->UpdatePendingRowHeights( nTab );
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nOldPos = nTab;
+ while (!pDoc->IsVisible(nTab)) // naechste sichtbare suchen
+ {
+ sal_Bool bUp = (nTab>=nOldPos);
+ if (bUp)
+ {
+ ++nTab;
+ if (nTab>=nTabCount)
+ {
+ nTab = nOldPos;
+ bUp = sal_False;
+ }
+ }
+
+ if (!bUp)
+ {
+ if (nTab != 0)
+ --nTab;
+ else
+ {
+ DBG_ERROR("keine sichtbare Tabelle");
+ pDoc->SetVisible( 0, sal_True );
+ }
+ }
+ }
+
+ // #i71490# Deselect drawing objects before changing the sheet number in view data,
+ // so the handling of notes still has the sheet selected on which the notes are.
+ DrawDeselectAll();
+
+ ScModule* pScMod = SC_MOD();
+ sal_Bool bRefMode = pScMod->IsFormulaMode();
+ if ( !bRefMode ) // Abfrage, damit RefMode bei Tabellenwechsel funktioniert
+ {
+ DoneBlockMode();
+ pSelEngine->Reset(); // reset all flags, including locked modifiers
+ aViewData.SetRefTabNo( nTab );
+ }
+
+ ScSplitPos eOldActive = aViewData.GetActivePart(); // before switching
+ sal_Bool bFocus = pGridWin[eOldActive]->HasFocus();
+
+ aViewData.SetTabNo( nTab );
+ // UpdateShow noch vor SetCursor, damit UpdateAutoFillMark die richtigen
+ // Fenster findet (wird aus SetCursor gerufen)
+ UpdateShow();
+ aViewData.ResetOldCursor();
+ SetCursor( aViewData.GetCurX(), aViewData.GetCurY(), sal_True );
+
+ SfxBindings& rBindings = aViewData.GetBindings();
+ ScMarkData& rMark = aViewData.GetMarkData();
+
+ bool bAllSelected = true;
+ for (SCTAB nSelTab = 0; nSelTab < nTabCount; ++nSelTab)
+ {
+ if (!pDoc->IsVisible(nSelTab) || rMark.GetTableSelect(nSelTab))
+ {
+ if (nTab == nSelTab)
+ // This tab is already in selection. Keep the current
+ // selection.
+ bExtendSelection = true;
+ }
+ else
+ {
+ bAllSelected = false;
+ if (bExtendSelection)
+ // We got what we need. No need to stay in the loop.
+ break;
+ }
+ }
+ if (bAllSelected && !bNew)
+ // #i6327# if all tables are selected, a selection event (#i6330#) will deselect all
+ // (not if called with bNew to update settings)
+ bExtendSelection = false;
+
+ if (bExtendSelection)
+ rMark.SelectTable( nTab, sal_True );
+ else
+ {
+ rMark.SelectOneTable( nTab );
+ rBindings.Invalidate( FID_FILL_TAB );
+ rBindings.Invalidate( FID_TAB_DESELECTALL );
+ }
+
+ bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF;
+
+ // recalc zoom-dependent values (before TabChanged, before UpdateEditViewPos)
+ RefreshZoom();
+ UpdateVarZoom();
+
+ if ( bRefMode ) // hide EditView if necessary (after aViewData.SetTabNo !)
+ {
+ for ( sal_uInt16 i=0; i<4; i++ )
+ if ( pGridWin[i] )
+ if ( pGridWin[i]->IsVisible() )
+ pGridWin[i]->UpdateEditViewPos();
+ }
+
+ TabChanged( bSameTabButMoved ); // DrawView
+
+ aViewData.GetViewShell()->WindowChanged(); // falls das aktive Fenster anders ist
+ if ( !bUnoRefDialog )
+ aViewData.GetViewShell()->DisconnectAllClients(); // important for floating frames
+ else
+ {
+ // hide / show inplace client
+
+ ScClient* pClient = static_cast<ScClient*>(aViewData.GetViewShell()->GetIPClient());
+ if ( pClient && pClient->IsObjectInPlaceActive() )
+ {
+ Rectangle aObjArea = pClient->GetObjArea();
+ if ( nTab == aViewData.GetRefTabNo() )
+ {
+ // move to its original position
+
+ SdrOle2Obj* pDrawObj = pClient->GetDrawObj();
+ if ( pDrawObj )
+ {
+ Rectangle aRect = pDrawObj->GetLogicRect();
+ MapMode aMapMode( MAP_100TH_MM );
+ Size aOleSize = pDrawObj->GetOrigObjSize( &aMapMode );
+ aRect.SetSize( aOleSize );
+ aObjArea = aRect;
+ }
+ }
+ else
+ {
+ // move to an invisible position
+
+ aObjArea.SetPos( Point( 0, -2*aObjArea.GetHeight() ) );
+ }
+ pClient->SetObjArea( aObjArea );
+ }
+ }
+
+ if ( bFocus && aViewData.GetActivePart() != eOldActive && !bRefMode )
+ ActiveGrabFocus(); // grab focus to the pane that's active now
+
+ // Fixierungen
+
+ sal_Bool bResize = sal_False;
+ if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
+ if (aViewData.UpdateFixX())
+ bResize = sal_True;
+ if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
+ if (aViewData.UpdateFixY())
+ bResize = sal_True;
+ if (bResize)
+ RepeatResize();
+ InvalidateSplit();
+
+ if ( aViewData.IsPagebreakMode() )
+ UpdatePageBreakData(); //! asynchron ??
+
+ // #53551# Form-Layer muss den sichtbaren Ausschnitt der neuen Tabelle kennen
+ // dafuer muss hier schon der MapMode stimmen
+ for (sal_uInt16 i=0; i<4; i++)
+ if (pGridWin[i])
+ pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
+ SetNewVisArea();
+
+ PaintGrid();
+ PaintTop();
+ PaintLeft();
+ PaintExtras();
+
+ DoResize( aBorderPos, aFrameSize );
+ rBindings.Invalidate( SID_DELETE_PRINTAREA ); // Menue
+ rBindings.Invalidate( FID_DEL_MANUALBREAKS );
+ rBindings.Invalidate( FID_RESET_PRINTZOOM );
+ rBindings.Invalidate( SID_STATUS_DOCPOS ); // Statusbar
+ rBindings.Invalidate( SID_STATUS_PAGESTYLE ); // Statusbar
+ rBindings.Invalidate( SID_CURRENTTAB ); // Navigator
+ rBindings.Invalidate( SID_STYLE_FAMILY2 ); // Gestalter
+ rBindings.Invalidate( SID_STYLE_FAMILY4 ); // Gestalter
+ rBindings.Invalidate( SID_TABLES_COUNT );
+
+ if(pScMod->IsRefDialogOpen())
+ {
+ sal_uInt16 nCurRefDlgId=pScMod->GetCurRefDlgId();
+ SfxViewFrame* pViewFrm = aViewData.GetViewShell()->GetViewFrame();
+ SfxChildWindow* pChildWnd = pViewFrm->GetChildWindow( nCurRefDlgId );
+ if ( pChildWnd )
+ {
+ IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
+ pRefDlg->ViewShellChanged(NULL);
+ }
+ }
+ }
+}
+
+//
+// Paint-Funktionen - nur fuer diese View
+//
+
+void ScTabView::MakeEditView( ScEditEngineDefaulter* pEngine, SCCOL nCol, SCROW nRow )
+{
+ DrawDeselectAll();
+
+ if (pDrawView)
+ DrawEnableAnim( sal_False );
+
+ EditView* pSpellingView = aViewData.GetSpellingView();
+
+ for (sal_uInt16 i=0; i<4; i++)
+ if (pGridWin[i])
+ if ( pGridWin[i]->IsVisible() && !aViewData.HasEditView((ScSplitPos)i) )
+ {
+ ScHSplitPos eHWhich = WhichH( (ScSplitPos) i );
+ ScVSplitPos eVWhich = WhichV( (ScSplitPos) i );
+ SCCOL nScrX = aViewData.GetPosX( eHWhich );
+ SCROW nScrY = aViewData.GetPosY( eVWhich );
+
+ sal_Bool bPosVisible =
+ ( nCol >= nScrX && nCol <= nScrX + aViewData.VisibleCellsX(eHWhich) + 1 &&
+ nRow >= nScrY && nRow <= nScrY + aViewData.VisibleCellsY(eVWhich) + 1 );
+
+ // #102421# for the active part, create edit view even if outside the visible area,
+ // so input isn't lost (and the edit view may be scrolled into the visible area)
+
+ // #i26433# during spelling, the spelling view must be active
+ if ( bPosVisible || aViewData.GetActivePart() == (ScSplitPos) i ||
+ ( pSpellingView && aViewData.GetEditView((ScSplitPos) i) == pSpellingView ) )
+ {
+ pGridWin[i]->HideCursor();
+
+ pGridWin[i]->DeleteCursorOverlay();
+ pGridWin[i]->DeleteAutoFillOverlay();
+
+ // flush OverlayManager before changing MapMode to text edit
+ pGridWin[i]->flushOverlayManager();
+
+ // MapMode must be set after HideCursor
+ pGridWin[i]->SetMapMode(aViewData.GetLogicMode());
+
+ aViewData.SetEditEngine( (ScSplitPos) i, pEngine, pGridWin[i], nCol, nRow );
+
+ if ( !bPosVisible )
+ {
+ // move the edit view area to the real (possibly negative) position,
+ // or hide if completely above or left of the window
+ pGridWin[i]->UpdateEditViewPos();
+ }
+ }
+ }
+
+ if (aViewData.GetViewShell()->HasAccessibilityObjects())
+ aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_ENTEREDITMODE));
+}
+
+void ScTabView::UpdateEditView()
+{
+ ScSplitPos eActive = aViewData.GetActivePart();
+ for (sal_uInt16 i=0; i<4; i++)
+ if (aViewData.HasEditView( (ScSplitPos) i ))
+ {
+ EditView* pEditView = aViewData.GetEditView( (ScSplitPos) i );
+ aViewData.SetEditEngine( (ScSplitPos) i,
+ static_cast<ScEditEngineDefaulter*>(pEditView->GetEditEngine()),
+ pGridWin[i], GetViewData()->GetCurX(), GetViewData()->GetCurY() );
+ if ( (ScSplitPos)i == eActive )
+ pEditView->ShowCursor( sal_False );
+ }
+}
+
+void ScTabView::KillEditView( sal_Bool bNoPaint )
+{
+ sal_uInt16 i;
+ SCCOL nCol1 = aViewData.GetEditStartCol();
+ SCROW nRow1 = aViewData.GetEditStartRow();
+ SCCOL nCol2 = aViewData.GetEditEndCol();
+ SCROW nRow2 = aViewData.GetEditEndRow();
+ sal_Bool bPaint[4];
+ sal_Bool bNotifyAcc(false);
+
+ sal_Bool bExtended = nRow1 != nRow2; // Col wird sowieso bis zum Ende gezeichnet
+ sal_Bool bAtCursor = nCol1 <= aViewData.GetCurX() &&
+ nCol2 >= aViewData.GetCurX() &&
+ nRow1 == aViewData.GetCurY();
+ for (i=0; i<4; i++)
+ {
+ bPaint[i] = aViewData.HasEditView( (ScSplitPos) i );
+ if (bPaint[i])
+ bNotifyAcc = true;
+ }
+
+ // #108931#; notify accessibility before all things happen
+ if ((bNotifyAcc) && (aViewData.GetViewShell()->HasAccessibilityObjects()))
+ aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_LEAVEEDITMODE));
+
+ aViewData.ResetEditView();
+ for (i=0; i<4; i++)
+ if (pGridWin[i] && bPaint[i])
+ if (pGridWin[i]->IsVisible())
+ {
+ pGridWin[i]->ShowCursor();
+
+ pGridWin[i]->SetMapMode(pGridWin[i]->GetDrawMapMode());
+
+ // #i73567# the cell still has to be repainted
+ if (bExtended || ( bAtCursor && !bNoPaint ))
+ {
+ pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2 );
+ pGridWin[i]->UpdateSelectionOverlay();
+ }
+ }
+
+ if (pDrawView)
+ DrawEnableAnim( sal_True );
+
+ // GrabFocus immer dann, wenn diese View aktiv ist und
+ // die Eingabezeile den Focus hat
+
+ sal_Bool bGrabFocus = sal_False;
+ if (aViewData.IsActive())
+ {
+ ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
+ if ( pInputHdl )
+ {
+ ScInputWindow* pInputWin = pInputHdl->GetInputWindow();
+ if (pInputWin && pInputWin->IsInputActive())
+ bGrabFocus = sal_True;
+ }
+ }
+
+ if (bGrabFocus)
+ {
+// So soll es gemacht werden, damit der Sfx es mitbekommt, klappt aber nicht:
+//! aViewData.GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
+// deshalb erstmal so:
+ GetActiveWin()->GrabFocus();
+ }
+
+ // Cursor-Abfrage erst nach GrabFocus
+
+ for (i=0; i<4; i++)
+ if (pGridWin[i] && pGridWin[i]->IsVisible())
+ {
+ Cursor* pCur = pGridWin[i]->GetCursor();
+ if (pCur && pCur->IsVisible())
+ pCur->Hide();
+
+ if(bPaint[i])
+ {
+ pGridWin[i]->UpdateCursorOverlay();
+ pGridWin[i]->UpdateAutoFillOverlay();
+ // pGridWin[i]->UpdateAllOverlays();
+ }
+ }
+}
+
+void ScTabView::UpdateFormulas()
+{
+ if ( aViewData.GetDocument()->IsAutoCalcShellDisabled() )
+ return ;
+
+ sal_uInt16 i;
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ if (pGridWin[i]->IsVisible())
+ pGridWin[i]->UpdateFormulas();
+
+ if ( aViewData.IsPagebreakMode() )
+ UpdatePageBreakData(); //! asynchron
+
+ UpdateHeaderWidth();
+
+ // if in edit mode, adjust edit view area because widths/heights may have changed
+ if ( aViewData.HasEditView( aViewData.GetActivePart() ) )
+ UpdateEditView();
+}
+
+// PaintArea -Block neu zeichnen
+
+void ScTabView::PaintArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ ScUpdateMode eMode )
+{
+ sal_uInt16 i;
+ SCCOL nCol1;
+ SCROW nRow1;
+ SCCOL nCol2;
+ SCROW nRow2;
+
+ PutInOrder( nStartCol, nEndCol );
+ PutInOrder( nStartRow, nEndRow );
+
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ if (pGridWin[i]->IsVisible())
+ {
+ ScHSplitPos eHWhich = WhichH( (ScSplitPos) i );
+ ScVSplitPos eVWhich = WhichV( (ScSplitPos) i );
+ sal_Bool bOut = sal_False;
+
+ nCol1 = nStartCol;
+ nRow1 = nStartRow;
+ nCol2 = nEndCol;
+ nRow2 = nEndRow;
+
+ SCCOL nScrX = aViewData.GetPosX( eHWhich );
+ SCROW nScrY = aViewData.GetPosY( eVWhich );
+ if (nCol1 < nScrX) nCol1 = nScrX;
+ if (nCol2 < nScrX)
+ {
+ if ( eMode == SC_UPDATE_ALL ) // #91240# for UPDATE_ALL, paint anyway
+ nCol2 = nScrX; // (because of extending strings to the right)
+ else
+ bOut = sal_True; // completely outside the window
+ }
+ if (nRow1 < nScrY) nRow1 = nScrY;
+ if (nRow2 < nScrY) bOut = sal_True;
+
+ SCCOL nLastX = nScrX + aViewData.VisibleCellsX( eHWhich ) + 1;
+ SCROW nLastY = nScrY + aViewData.VisibleCellsY( eVWhich ) + 1;
+ if (nCol1 > nLastX) bOut = sal_True;
+ if (nCol2 > nLastX) nCol2 = nLastX;
+ if (nRow1 > nLastY) bOut = sal_True;
+ if (nRow2 > nLastY) nRow2 = nLastY;
+
+ if (!bOut)
+ {
+ if ( eMode == SC_UPDATE_CHANGED )
+ pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2, eMode );
+ else // ALL oder MARKS
+ {
+ sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ Point aStart = aViewData.GetScrPos( nCol1, nRow1, (ScSplitPos) i );
+ Point aEnd = aViewData.GetScrPos( nCol2+1, nRow2+1, (ScSplitPos) i );
+ if ( eMode == SC_UPDATE_ALL )
+ aEnd.X() = bLayoutRTL ? 0 : (pGridWin[i]->GetOutputSizePixel().Width());
+ aEnd.X() -= nLayoutSign;
+ aEnd.Y() -= 1;
+
+ // #i85232# include area below cells (could be done in GetScrPos?)
+ if ( eMode == SC_UPDATE_ALL && nRow2 >= MAXROW )
+ aEnd.Y() = pGridWin[i]->GetOutputSizePixel().Height();
+
+ sal_Bool bShowChanges = sal_True; //! ...
+ if (bShowChanges)
+ {
+ aStart.X() -= nLayoutSign; // include change marks
+ aStart.Y() -= 1;
+ }
+
+ sal_Bool bMarkClipped = aViewData.GetOptions().GetOption( VOPT_CLIPMARKS );
+ if (bMarkClipped)
+ {
+ // dazu muesste ScColumn::IsEmptyBlock optimiert werden
+ // (auf Search() umstellen)
+ //!if ( nCol1 > 0 && !aViewData.GetDocument()->IsBlockEmpty(
+ //! aViewData.GetTabNo(),
+ //! 0, nRow1, nCol1-1, nRow2 ) )
+ {
+ long nMarkPixel = (long)( SC_CLIPMARK_SIZE * aViewData.GetPPTX() );
+ aStart.X() -= nMarkPixel * nLayoutSign;
+ if (!bShowChanges)
+ aStart.X() -= nLayoutSign; // cell grid
+ }
+ }
+
+ pGridWin[i]->Invalidate( pGridWin[i]->PixelToLogic( Rectangle( aStart,aEnd ) ) );
+ }
+ }
+ }
+
+ // #i79909# Calling UpdateAllOverlays here isn't necessary and would lead to overlay calls from a timer,
+ // with a wrong MapMode if editing in a cell (reference input).
+ // #i80499# Overlays need updates in a lot of cases, e.g. changing row/column size,
+ // or showing/hiding outlines. TODO: selections in inactive windows are vanishing.
+ // #i84689# With relative conditional formats, PaintArea may be called often (for each changed cell),
+ // so UpdateAllOverlays was moved to ScTabViewShell::Notify and is called only if PAINT_LEFT/PAINT_TOP
+ // is set (width or height changed).
+}
+
+void ScTabView::PaintRangeFinder( long nNumber )
+{
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl( aViewData.GetViewShell() );
+ if (pHdl)
+ {
+ ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
+ if ( pRangeFinder && pRangeFinder->GetDocName() == aViewData.GetDocShell()->GetTitle() )
+ {
+ SCTAB nTab = aViewData.GetTabNo();
+ sal_uInt16 nCount = (sal_uInt16)pRangeFinder->Count();
+ for (sal_uInt16 i=0; i<nCount; i++)
+ if ( nNumber < 0 || nNumber == i )
+ {
+ ScRangeFindData* pData = pRangeFinder->GetObject(i);
+ if (pData)
+ {
+ ScRange aRef = pData->aRef;
+ aRef.Justify(); // Justify fuer die Abfragen unten
+
+ if ( aRef.aStart == aRef.aEnd ) //! Tab ignorieren?
+ aViewData.GetDocument()->ExtendMerge(aRef);
+
+ if ( aRef.aStart.Tab() >= nTab && aRef.aEnd.Tab() <= nTab )
+ {
+ SCCOL nCol1 = aRef.aStart.Col();
+ SCROW nRow1 = aRef.aStart.Row();
+ SCCOL nCol2 = aRef.aEnd.Col();
+ SCROW nRow2 = aRef.aEnd.Row();
+
+ // wegnehmen -> Repaint
+ // SC_UPDATE_MARKS: Invalidate, nicht bis zum Zeilenende
+
+ sal_Bool bHiddenEdge = sal_False;
+ SCROW nTmp;
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCCOL nLastCol = -1;
+ while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab, nLastCol) )
+ {
+ --nCol1;
+ bHiddenEdge = sal_True;
+ }
+ while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab, nLastCol) )
+ {
+ ++nCol2;
+ bHiddenEdge = sal_True;
+ }
+ nTmp = pDoc->LastVisibleRow(0, nRow1, nTab);
+ if (!ValidRow(nTmp))
+ nTmp = 0;
+ if (nTmp < nRow1)
+ {
+ nRow1 = nTmp;
+ bHiddenEdge = sal_True;
+ }
+ nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab);
+ if (!ValidRow(nTmp))
+ nTmp = MAXROW;
+ if (nTmp > nRow2)
+ {
+ nRow2 = nTmp;
+ bHiddenEdge = sal_True;
+ }
+
+ if ( nCol2 - nCol1 > 1 && nRow2 - nRow1 > 1 && !bHiddenEdge )
+ {
+ // nur an den Raendern entlang
+ PaintArea( nCol1, nRow1, nCol2, nRow1, SC_UPDATE_MARKS );
+ PaintArea( nCol1, nRow1+1, nCol1, nRow2-1, SC_UPDATE_MARKS );
+ PaintArea( nCol2, nRow1+1, nCol2, nRow2-1, SC_UPDATE_MARKS );
+ PaintArea( nCol1, nRow2, nCol2, nRow2, SC_UPDATE_MARKS );
+ }
+ else // alles am Stueck
+ PaintArea( nCol1, nRow1, nCol2, nRow2, SC_UPDATE_MARKS );
+ }
+ }
+ }
+ }
+ }
+}
+
+// fuer Chart-Daten-Markierung
+
+void ScTabView::AddHighlightRange( const ScRange& rRange, const Color& rColor )
+{
+ if (!pHighlightRanges)
+ pHighlightRanges = new ScHighlightRanges;
+ pHighlightRanges->Insert( new ScHighlightEntry( rRange, rColor ) );
+
+ SCTAB nTab = aViewData.GetTabNo();
+ if ( nTab >= rRange.aStart.Tab() && nTab <= rRange.aEnd.Tab() )
+ PaintArea( rRange.aStart.Col(), rRange.aStart.Row(),
+ rRange.aEnd.Col(), rRange.aEnd.Row(), SC_UPDATE_MARKS );
+}
+
+void ScTabView::ClearHighlightRanges()
+{
+ if (pHighlightRanges)
+ {
+ ScHighlightRanges* pTemp = pHighlightRanges;
+ pHighlightRanges = NULL; // Repaint ohne Highlight
+
+ SCTAB nTab = aViewData.GetTabNo();
+ sal_uLong nCount = pTemp->Count();
+ for (sal_uLong i=0; i<nCount; i++)
+ {
+ ScHighlightEntry* pEntry = pTemp->GetObject( i );
+ if (pEntry)
+ {
+ ScRange aRange = pEntry->aRef;
+ if ( nTab >= aRange.aStart.Tab() && nTab <= aRange.aEnd.Tab() )
+ PaintArea( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(), SC_UPDATE_MARKS );
+ }
+ }
+ delete pTemp;
+ }
+}
+
+void ScTabView::DoChartSelection(
+ const uno::Sequence< chart2::data::HighlightedRange > & rHilightRanges )
+{
+ ClearHighlightRanges();
+
+ for( sal_Int32 i=0; i<rHilightRanges.getLength(); ++i )
+ {
+ Color aSelColor( rHilightRanges[i].PreferredColor );
+ ScRangeList aRangeList;
+ ScDocument* pDoc = aViewData.GetDocShell()->GetDocument();
+ if( ScRangeStringConverter::GetRangeListFromString(
+ aRangeList, rHilightRanges[i].RangeRepresentation, pDoc, pDoc->GetAddressConvention(), ';' ))
+ {
+ for ( ScRangePtr p = aRangeList.First(); p; p = aRangeList.Next())
+ {
+ if( rHilightRanges[i].Index == - 1 )
+ AddHighlightRange( *p, aSelColor );
+ else
+ AddHighlightRange( lcl_getSubRangeByIndex( *p, rHilightRanges[i].Index ), aSelColor );
+ }
+ }
+ }
+}
+
+// DrawDragRect - Drag&Drop-Rechteck zeichnen (XOR)
+
+//UNUSED2008-05 void ScTabView::DrawDragRect( SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY,
+//UNUSED2008-05 ScSplitPos ePos )
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX || aViewData.GetVSplitMode() == SC_SPLIT_FIX )
+//UNUSED2008-05 {
+//UNUSED2008-05 for (sal_uInt16 i=0; i<4; i++)
+//UNUSED2008-05 if (pGridWin[i])
+//UNUSED2008-05 if (pGridWin[i]->IsVisible())
+//UNUSED2008-05 pGridWin[i]->DrawDragRect( nStartX, nStartY, nEndX, nEndY );
+//UNUSED2008-05 }
+//UNUSED2008-05 else
+//UNUSED2008-05 pGridWin[ePos]->DrawDragRect( nStartX, nStartY, nEndX, nEndY );
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 // PaintCell - einzelne Zelle neu zeichnen
+//UNUSED2008-05
+//UNUSED2008-05 void ScTabView::PaintCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
+//UNUSED2008-05 {
+//UNUSED2008-05 if ( aViewData.GetTabNo() == nTab )
+//UNUSED2008-05 {
+//UNUSED2008-05 sal_uInt16 i;
+//UNUSED2008-05 for (i=0; i<4; i++)
+//UNUSED2008-05 if (pGridWin[i])
+//UNUSED2008-05 if (pGridWin[i]->IsVisible())
+//UNUSED2008-05 pGridWin[i]->Draw( nCol, nRow, nCol, nRow );
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void ScTabView::PaintLeftRow( SCROW nRow )
+//UNUSED2008-05 {
+//UNUSED2008-05 PaintLeftArea( nRow, nRow );
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void ScTabView::PaintTopCol( SCCOL nCol )
+//UNUSED2008-05 {
+//UNUSED2008-05 PaintTopArea( nCol, nCol );
+//UNUSED2008-05 }
+
+// PaintGrid - Datenbereiche neu zeichnen
+
+void ScTabView::PaintGrid()
+{
+ sal_uInt16 i;
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ if (pGridWin[i]->IsVisible())
+ pGridWin[i]->Invalidate();
+}
+
+// PaintTop - obere Kontrollelemente neu zeichnen
+
+void ScTabView::PaintTop()
+{
+ sal_uInt16 i;
+ for (i=0; i<2; i++)
+ {
+ if (pColBar[i])
+ pColBar[i]->Invalidate();
+ if (pColOutline[i])
+ pColOutline[i]->Invalidate();
+ }
+}
+
+void ScTabView::CreateAnchorHandles(SdrHdlList& rHdl, const ScAddress& rAddress)
+{
+ sal_uInt16 i;
+
+ for(i=0; i<4; i++)
+ {
+ if(pGridWin[i])
+ {
+ if(pGridWin[i]->IsVisible())
+ {
+ pGridWin[i]->CreateAnchorHandle(rHdl, rAddress);
+ }
+ }
+ }
+}
+
+void ScTabView::PaintTopArea( SCCOL nStartCol, SCCOL nEndCol )
+{
+ // Pixel-Position der linken Kante
+
+ if ( nStartCol < aViewData.GetPosX(SC_SPLIT_LEFT) ||
+ nStartCol < aViewData.GetPosX(SC_SPLIT_RIGHT) )
+ aViewData.RecalcPixPos();
+
+ // Fixierung anpassen (UpdateFixX setzt HSplitPos neu)
+
+ if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX && nStartCol < aViewData.GetFixPosX() )
+ if (aViewData.UpdateFixX())
+ RepeatResize();
+
+ // zeichnen
+
+ if (nStartCol>0)
+ --nStartCol; //! allgemeiner ?
+
+ sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ for (sal_uInt16 i=0; i<2; i++)
+ {
+ ScHSplitPos eWhich = (ScHSplitPos) i;
+ if (pColBar[eWhich])
+ {
+ Size aWinSize = pColBar[eWhich]->GetSizePixel();
+ long nStartX = aViewData.GetScrPos( nStartCol, 0, eWhich ).X();
+ long nEndX;
+ if (nEndCol >= MAXCOL)
+ nEndX = bLayoutRTL ? 0 : ( aWinSize.Width()-1 );
+ else
+ nEndX = aViewData.GetScrPos( nEndCol+1, 0, eWhich ).X() - nLayoutSign;
+ pColBar[eWhich]->Invalidate(
+ Rectangle( nStartX, 0, nEndX, aWinSize.Height()-1 ) );
+ }
+ if (pColOutline[eWhich])
+ pColOutline[eWhich]->Invalidate();
+ }
+}
+
+
+// PaintLeft - linke Kontrollelemente neu zeichnen
+
+void ScTabView::PaintLeft()
+{
+ sal_uInt16 i;
+ for (i=0; i<2; i++)
+ {
+ if (pRowBar[i])
+ pRowBar[i]->Invalidate();
+ if (pRowOutline[i])
+ pRowOutline[i]->Invalidate();
+ }
+}
+
+void ScTabView::PaintLeftArea( SCROW nStartRow, SCROW nEndRow )
+{
+ // Pixel-Position der oberen Kante
+
+ if ( nStartRow < aViewData.GetPosY(SC_SPLIT_TOP) ||
+ nStartRow < aViewData.GetPosY(SC_SPLIT_BOTTOM) )
+ aViewData.RecalcPixPos();
+
+ // Fixierung anpassen (UpdateFixY setzt VSplitPos neu)
+
+ if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && nStartRow < aViewData.GetFixPosY() )
+ if (aViewData.UpdateFixY())
+ RepeatResize();
+
+ // zeichnen
+
+ if (nStartRow>0)
+ --nStartRow;
+
+ for (sal_uInt16 i=0; i<2; i++)
+ {
+ ScVSplitPos eWhich = (ScVSplitPos) i;
+ if (pRowBar[eWhich])
+ {
+ Size aWinSize = pRowBar[eWhich]->GetSizePixel();
+ long nStartY = aViewData.GetScrPos( 0, nStartRow, eWhich ).Y();
+ long nEndY;
+ if (nEndRow >= MAXROW)
+ nEndY = aWinSize.Height()-1;
+ else
+ nEndY = aViewData.GetScrPos( 0, nEndRow+1, eWhich ).Y() - 1;
+ pRowBar[eWhich]->Invalidate(
+ Rectangle( 0, nStartY, aWinSize.Width()-1, nEndY ) );
+ }
+ if (pRowOutline[eWhich])
+ pRowOutline[eWhich]->Invalidate();
+ }
+}
+
+// InvertBlockMark - Block invertieren
+
+void ScTabView::InvertBlockMark(SCCOL nStartX, SCROW nStartY,
+ SCCOL nEndX, SCROW nEndY)
+{
+ if ( !aViewData.IsActive() )
+ return; // invertiert wird nur auf aktiver View
+
+ PutInOrder( nStartX, nEndX );
+ PutInOrder( nStartY, nEndY );
+
+ ScMarkData& rMark = aViewData.GetMarkData();
+ ScDocShell* pDocSh = aViewData.GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ if ( pDocSh->GetLockCount() )
+ {
+ // if paint is locked, avoid repeated inverting
+ // add repaint areas to paint lock data instead
+ pDocSh->PostPaint( nStartX,nStartY,nTab, nEndX,nEndY,nTab, PAINT_GRID );
+ return;
+ }
+
+ sal_Bool bSingle = rMark.IsMultiMarked();
+ sal_Bool bMerge = pDoc->HasAttrib( nStartX, nStartY, nTab, nEndX, nEndY, nTab,
+ HASATTR_MERGED | HASATTR_OVERLAPPED );
+
+ sal_uInt16 i;
+ if ( bMerge || bSingle )
+ {
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ if (pGridWin[i]->IsVisible())
+ pGridWin[i]->InvertSimple( nStartX, nStartY, nEndX, nEndY,
+ bMerge, bBlockNeg );
+ }
+ else
+ {
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ if (pGridWin[i]->IsVisible())
+ {
+ ScSplitPos ePos = (ScSplitPos) i;
+ Point aStartPoint = aViewData.GetScrPos( nStartX, nStartY, ePos );
+ Point aEndPoint = aViewData.GetScrPos( nEndX+1, nEndY+1, ePos );
+ if ( pDoc->IsLayoutRTL( nTab ) )
+ {
+ long nTemp = aStartPoint.X();
+ aStartPoint.X() = aEndPoint.X() + 1; // +1 - excluding start of nEndX+1
+ aEndPoint.X() = nTemp;
+ }
+ else
+ aEndPoint.X() -= 1;
+ aEndPoint.Y() -= 1;
+ if ( aEndPoint.X() >= aStartPoint.X() && aEndPoint.Y() >= aStartPoint.Y() )
+ {
+ MapMode aOld = pGridWin[ePos]->GetMapMode();
+ pGridWin[ePos]->SetMapMode(MAP_PIXEL);
+ pGridWin[ePos]->Invert( Rectangle(aStartPoint,aEndPoint), INVERT_HIGHLIGHT );
+ pGridWin[ePos]->SetMapMode(aOld);
+ pGridWin[ePos]->CheckInverted();
+ }
+ }
+ }
+
+ //
+ // wenn Controls betroffen, neu malen
+ //
+
+ sal_Bool bHide = sal_True; // wird Teil der Markierung aufgehoben ?
+ if (rMark.IsMarked())
+ {
+ ScRange aMarkRange;
+ rMark.GetMarkArea( aMarkRange );
+ if ( aMarkRange.aStart.Col() <= nStartX && aMarkRange.aEnd.Col() >= nEndX &&
+ aMarkRange.aStart.Row() <= nStartY && aMarkRange.aEnd.Row() >= nEndY )
+ {
+ bHide = sal_False; // der ganze Bereich ist markiert
+ }
+ }
+}
+
+sal_Bool ScTabView::PaintExtras()
+{
+ sal_Bool bRet = sal_False;
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ if (!pDoc->HasTable(nTab)) // Tabelle geloescht ?
+ {
+ SCTAB nCount = pDoc->GetTableCount();
+ aViewData.SetTabNo(nCount-1);
+ bRet = sal_True;
+ }
+ pTabControl->UpdateStatus(); // sal_True = active
+ return bRet;
+}
+
+void ScTabView::RecalcPPT()
+{
+ // called after changes that require the PPT values to be recalculated
+ // (currently from detective operations)
+
+ double nOldX = aViewData.GetPPTX();
+ double nOldY = aViewData.GetPPTY();
+
+ aViewData.RefreshZoom(); // pre-calculate new PPT values
+
+ sal_Bool bChangedX = ( aViewData.GetPPTX() != nOldX );
+ sal_Bool bChangedY = ( aViewData.GetPPTY() != nOldY );
+ if ( bChangedX || bChangedY )
+ {
+ // call view SetZoom (including draw scale, split update etc)
+ // and paint only if values changed
+
+ Fraction aZoomX = aViewData.GetZoomX();
+ Fraction aZoomY = aViewData.GetZoomY();
+ SetZoom( aZoomX, aZoomY, sal_False );
+
+ PaintGrid();
+ if (bChangedX)
+ PaintTop();
+ if (bChangedY)
+ PaintLeft();
+ }
+}
+
+void ScTabView::ActivateView( sal_Bool bActivate, sal_Bool bFirst )
+{
+ if ( bActivate == aViewData.IsActive() && !bFirst )
+ {
+ // keine Assertion mehr - kommt vor, wenn vorher im Drag&Drop
+ // auf ein anderes Dokument umgeschaltet wurde
+ return;
+ }
+
+ // wird nur bei MDI-(De)Activate gerufen
+ // aViewData.Activate hinten wegen Cursor-Show bei KillEditView
+ // Markierung nicht mehr loeschen - wenn an der ViewData Activate(sal_False) gesetzt ist,
+ // wird die Markierung nicht ausgegeben
+
+ if (!bActivate)
+ {
+ ScModule* pScMod = SC_MOD();
+ sal_Bool bRefMode = pScMod->IsFormulaMode();
+
+ // Referenzeingabe nicht abbrechen, um Referenzen auf
+ // andere Dokumente zuzulassen
+
+ if (!bRefMode)
+ {
+ //pScMod->InputEnterHandler();
+
+ // #80843# pass view to GetInputHdl, this view may not be current anymore
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
+ if (pHdl)
+ pHdl->EnterHandler();
+ }
+ }
+ pTabControl->ActivateView(bActivate);
+ PaintExtras();
+
+ aViewData.Activate(bActivate);
+
+ PaintBlock(sal_False); // Repaint, Markierung je nach Active-Status
+
+ if (!bActivate)
+ HideAllCursors(); // Cursor
+ else if (!bFirst)
+ ShowAllCursors();
+
+ //HMHif (pDrawView)
+ //HMH DrawShowMarkHdl(bActivate); // Drawing-Markierung
+
+ if (bActivate)
+ {
+ if ( bFirst )
+ {
+ ScSplitPos eWin = aViewData.GetActivePart();
+ DBG_ASSERT( pGridWin[eWin], "rottes Dokument, nicht alle SplitPos in GridWin" );
+ if ( !pGridWin[eWin] )
+ {
+ eWin = SC_SPLIT_BOTTOMLEFT;
+ if ( !pGridWin[eWin] )
+ {
+ short i;
+ for ( i=0; i<4; i++ )
+ {
+ if ( pGridWin[i] )
+ {
+ eWin = (ScSplitPos) i;
+ break; // for
+ }
+ }
+ DBG_ASSERT( i<4, "und BUMM" );
+ }
+ aViewData.SetActivePart( eWin );
+ }
+ }
+ // hier nicht mehr selber GrabFocus rufen!
+ // Wenn das Doc bearbeitet wird, ruft der Sfx selber GrabFocus am Fenster der Shell.
+ // Wenn es z.B. ein Mailbody ist, darf es den Focus nicht bekommen (Bug #43638#)
+
+ UpdateInputContext();
+ }
+ else
+ pGridWin[aViewData.GetActivePart()]->ClickExtern();
+}
+
+void ScTabView::ActivatePart( ScSplitPos eWhich )
+{
+ ScSplitPos eOld = aViewData.GetActivePart();
+ if ( eOld != eWhich )
+ {
+ bInActivatePart = sal_True;
+
+ sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
+
+ // #40565# the HasEditView call during SetCursor would fail otherwise
+ if ( aViewData.HasEditView(eOld) && !bRefMode )
+ UpdateInputLine();
+
+ ScHSplitPos eOldH = WhichH(eOld);
+ ScVSplitPos eOldV = WhichV(eOld);
+ ScHSplitPos eNewH = WhichH(eWhich);
+ ScVSplitPos eNewV = WhichV(eWhich);
+ sal_Bool bTopCap = pColBar[eOldH] && pColBar[eOldH]->IsMouseCaptured();
+ sal_Bool bLeftCap = pRowBar[eOldV] && pRowBar[eOldV]->IsMouseCaptured();
+
+ sal_Bool bFocus = pGridWin[eOld]->HasFocus();
+ sal_Bool bCapture = pGridWin[eOld]->IsMouseCaptured();
+ if (bCapture)
+ pGridWin[eOld]->ReleaseMouse();
+ pGridWin[eOld]->ClickExtern();
+ pGridWin[eOld]->HideCursor();
+ pGridWin[eWhich]->HideCursor();
+ aViewData.SetActivePart( eWhich );
+
+ ScTabViewShell* pShell = aViewData.GetViewShell();
+ pShell->WindowChanged();
+
+ pSelEngine->SetWindow(pGridWin[eWhich]);
+ pSelEngine->SetWhich(eWhich);
+ pSelEngine->SetVisibleArea( Rectangle(Point(), pGridWin[eWhich]->GetOutputSizePixel()) );
+
+ pGridWin[eOld]->MoveMouseStatus(*pGridWin[eWhich]);
+
+ if ( bCapture || pGridWin[eWhich]->IsMouseCaptured() )
+ {
+ // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
+ // (SelectionEngine ruft CaptureMouse beim SetWindow)
+ //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
+ pGridWin[eWhich]->ReleaseMouse();
+ pGridWin[eWhich]->StartTracking();
+ }
+
+ if ( bTopCap && pColBar[eNewH] )
+ {
+ pColBar[eOldH]->SetIgnoreMove(sal_True);
+ pColBar[eNewH]->SetIgnoreMove(sal_False);
+ pHdrSelEng->SetWindow( pColBar[eNewH] );
+ long nWidth = pColBar[eNewH]->GetOutputSizePixel().Width();
+ pHdrSelEng->SetVisibleArea( Rectangle( 0, LONG_MIN, nWidth-1, LONG_MAX ) );
+ pColBar[eNewH]->CaptureMouse();
+ }
+ if ( bLeftCap && pRowBar[eNewV] )
+ {
+ pRowBar[eOldV]->SetIgnoreMove(sal_True);
+ pRowBar[eNewV]->SetIgnoreMove(sal_False);
+ pHdrSelEng->SetWindow( pRowBar[eNewV] );
+ long nHeight = pRowBar[eNewV]->GetOutputSizePixel().Height();
+ pHdrSelEng->SetVisibleArea( Rectangle( LONG_MIN, 0, LONG_MAX, nHeight-1 ) );
+ pRowBar[eNewV]->CaptureMouse();
+ }
+ aHdrFunc.SetWhich(eWhich);
+
+ pGridWin[eOld]->ShowCursor();
+ pGridWin[eWhich]->ShowCursor();
+
+ SfxInPlaceClient* pClient = aViewData.GetViewShell()->GetIPClient();
+ sal_Bool bOleActive = ( pClient && pClient->IsObjectInPlaceActive() );
+
+ // #103823# don't switch ViewShell's active window during RefInput, because the focus
+ // might change, and subsequent SetReference calls wouldn't find the right EditView
+ if ( !bRefMode && !bOleActive )
+ aViewData.GetViewShell()->SetWindow( pGridWin[eWhich] );
+
+ if ( bFocus && !aViewData.IsAnyFillMode() && !bRefMode )
+ {
+ // GrabFocus nur, wenn vorher das andere GridWindow den Focus hatte
+ // (z.B. wegen Suchen & Ersetzen)
+//! aViewData.GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
+ pGridWin[eWhich]->GrabFocus();
+ }
+
+ bInActivatePart = sal_False;
+ }
+}
+
+void ScTabView::HideListBox()
+{
+ for (sal_uInt16 i=0; i<4; i++)
+ if (pGridWin[i])
+ pGridWin[i]->ClickExtern();
+}
+
+void ScTabView::UpdateInputContext()
+{
+ ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
+ if (pWin)
+ pWin->UpdateInputContext();
+}
+
+// GetGridWidth - Breite eines Ausgabebereichs (fuer ViewData)
+
+long ScTabView::GetGridWidth( ScHSplitPos eWhich )
+{
+ ScSplitPos eGridWhich = ( eWhich == SC_SPLIT_LEFT ) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
+ if (pGridWin[eGridWhich])
+ return pGridWin[eGridWhich]->GetSizePixel().Width();
+ else
+ return 0;
+}
+
+// GetGridHeight - Hoehe eines Ausgabebereichs (fuer ViewData)
+
+long ScTabView::GetGridHeight( ScVSplitPos eWhich )
+{
+ ScSplitPos eGridWhich = ( eWhich == SC_SPLIT_TOP ) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
+ if (pGridWin[eGridWhich])
+ return pGridWin[eGridWhich]->GetSizePixel().Height();
+ else
+ return 0;
+}
+
+void ScTabView::UpdateInputLine()
+{
+ SC_MOD()->InputEnterHandler();
+}
+
+void ScTabView::ZoomChanged()
+{
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
+ if (pHdl)
+ pHdl->SetRefScale( aViewData.GetZoomX(), aViewData.GetZoomY() );
+
+ UpdateFixPos();
+
+ UpdateScrollBars();
+
+ // VisArea...
+ // AW: Discussed with NN if there is a reason that new map mode was only set for one window,
+ // but is not. Setting only on one window causes the first repaint to have the old mapMode
+ // in three of four views, so the overlay will save the wrong content e.g. when zooming out.
+ // Changing to setting map mode at all windows.
+ sal_uInt32 a;
+
+ for(a = 0L; a < 4L; a++)
+ {
+ if(pGridWin[a])
+ {
+ pGridWin[a]->SetMapMode(pGridWin[a]->GetDrawMapMode());
+ }
+ }
+
+ SetNewVisArea();
+
+ /* the old code
+ ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
+ if (pWin)
+ {
+ pWin->SetMapMode( pWin->GetDrawMapMode() ); // mit neuem Zoom
+ SetNewVisArea(); // benutzt den gesetzten MapMode
+ } */
+
+ InterpretVisible(); // #69343# have everything calculated before painting
+
+ SfxBindings& rBindings = aViewData.GetBindings();
+ rBindings.Invalidate( SID_ATTR_ZOOM );
+ rBindings.Invalidate( SID_ATTR_ZOOMSLIDER );
+
+ HideNoteMarker();
+
+ // AW: To not change too much, use pWin here
+ ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
+
+ if ( pWin && aViewData.HasEditView( aViewData.GetActivePart() ) )
+ {
+ // flush OverlayManager before changing the MapMode
+ pWin->flushOverlayManager();
+
+ // #93650# make sure the EditView's position and size are updated
+ // with the right (logic, not drawing) MapMode
+ pWin->SetMapMode( aViewData.GetLogicMode() );
+ UpdateEditView();
+ }
+}
+
+void ScTabView::CheckNeedsRepaint()
+{
+ sal_uInt16 i;
+ for (i=0; i<4; i++)
+ if ( pGridWin[i] && pGridWin[i]->IsVisible() )
+ pGridWin[i]->CheckNeedsRepaint();
+}
+
+
+
+
+
diff --git a/sc/source/ui/view/tabview4.cxx b/sc/source/ui/view/tabview4.cxx
new file mode 100644
index 000000000000..b7fb4d717200
--- /dev/null
+++ b/sc/source/ui/view/tabview4.cxx
@@ -0,0 +1,573 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <vcl/help.hxx>
+#include <vcl/svapp.hxx>
+
+#include "tabview.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "scmod.hxx"
+#include "gridwin.hxx"
+#include "globstr.hrc"
+#include "cell.hxx"
+#include "dociter.hxx"
+
+extern sal_uInt16 nScFillModeMouseModifier; // global.cxx
+
+// STATIC DATA -----------------------------------------------------------
+
+//==================================================================
+
+//
+// --- Referenz-Eingabe / Fill-Cursor
+//
+
+void ScTabView::HideTip()
+{
+ if ( nTipVisible )
+ {
+ Help::HideTip( nTipVisible );
+ nTipVisible = 0;
+ }
+}
+
+void ScTabView::ShowRefTip()
+{
+ sal_Bool bDone = sal_False;
+ if ( aViewData.GetRefType() == SC_REFTYPE_REF && Help::IsQuickHelpEnabled() )
+ {
+ SCCOL nStartX = aViewData.GetRefStartX();
+ SCROW nStartY = aViewData.GetRefStartY();
+ SCCOL nEndX = aViewData.GetRefEndX();
+ SCROW nEndY = aViewData.GetRefEndY();
+ if ( nEndX != nStartX || nEndY != nStartY ) // nicht fuer einzelne Zelle
+ {
+ sal_Bool bLeft = ( nEndX < nStartX );
+ sal_Bool bTop = ( nEndY < nStartY );
+ PutInOrder( nStartX, nEndX );
+ PutInOrder( nStartY, nEndY );
+ SCCOL nCols = nEndX+1-nStartX;
+ SCROW nRows = nEndY+1-nStartY;
+
+ String aHelp = ScGlobal::GetRscString( STR_QUICKHELP_REF );
+ aHelp.SearchAndReplace( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("%1")),
+ String::CreateFromInt32(nRows) );
+ aHelp.SearchAndReplace( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("%2")),
+ String::CreateFromInt32(nCols) );
+
+ ScSplitPos eWhich = aViewData.GetActivePart();
+ Window* pWin = pGridWin[eWhich];
+ if ( pWin )
+ {
+ Point aStart = aViewData.GetScrPos( nStartX, nStartY, eWhich );
+ Point aEnd = aViewData.GetScrPos( nEndX+1, nEndY+1, eWhich );
+
+ Point aPos( bLeft ? aStart.X() : ( aEnd.X() + 3 ),
+ bTop ? aStart.Y() : ( aEnd.Y() + 3 ) );
+ sal_uInt16 nFlags = ( bLeft ? QUICKHELP_RIGHT : QUICKHELP_LEFT ) |
+ ( bTop ? QUICKHELP_BOTTOM : QUICKHELP_TOP );
+
+ // nicht ueber die editierte Formel
+ if ( !bTop && aViewData.HasEditView( eWhich ) &&
+ nEndY+1 == aViewData.GetEditViewRow() )
+ {
+ // dann an der oberen Kante der editierten Zelle ausrichten
+ aPos.Y() -= 2; // die 3 von oben
+ nFlags = ( nFlags & ~QUICKHELP_TOP ) | QUICKHELP_BOTTOM;
+ }
+
+ Rectangle aRect( pWin->OutputToScreenPixel( aPos ), Size(1,1) );
+
+ //! Test, ob geaendert ??
+
+ HideTip();
+ nTipVisible = Help::ShowTip( pWin, aRect, aHelp, nFlags );
+ bDone = sal_True;
+ }
+ }
+ }
+
+ if (!bDone)
+ HideTip();
+}
+
+void ScTabView::StopRefMode()
+{
+ if (aViewData.IsRefMode())
+ {
+ aViewData.SetRefMode( sal_False, SC_REFTYPE_NONE );
+
+ HideTip();
+ UpdateShrinkOverlay();
+
+ if ( aViewData.GetTabNo() >= aViewData.GetRefStartZ() &&
+ aViewData.GetTabNo() <= aViewData.GetRefEndZ() )
+ {
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCCOL nStartX = aViewData.GetRefStartX();
+ SCROW nStartY = aViewData.GetRefStartY();
+ SCCOL nEndX = aViewData.GetRefEndX();
+ SCROW nEndY = aViewData.GetRefEndY();
+ if ( nStartX == nEndX && nStartY == nEndY )
+ pDoc->ExtendMerge( nStartX, nStartY, nEndX, nEndY, aViewData.GetTabNo() );
+
+ PaintArea( nStartX,nStartY,nEndX,nEndY, SC_UPDATE_MARKS );
+ }
+
+ pSelEngine->Reset();
+ pSelEngine->SetAddMode( sal_False ); //! sollte das nicht bei Reset passieren?
+
+ ScSplitPos eOld = pSelEngine->GetWhich();
+ ScSplitPos eNew = aViewData.GetActivePart();
+ if ( eNew != eOld )
+ {
+ pSelEngine->SetWindow( pGridWin[ eNew ] );
+ pSelEngine->SetWhich( eNew );
+ pSelEngine->SetVisibleArea( Rectangle(Point(),
+ pGridWin[eNew]->GetOutputSizePixel()) );
+ pGridWin[eOld]->MoveMouseStatus(*pGridWin[eNew]);
+ }
+ }
+
+ // AlignToCursor(SC_FOLLOW_NONE): Only switch active part.
+ // This must also be done if no RefMode was active (for RangeFinder dragging),
+ // but if RefMode was set, AlignToCursor must be after SelectionEngine reset,
+ // so the SelectionEngine SetWindow call from AlignToCursor doesn't capture
+ // the mouse again when called from Tracking/MouseButtonUp (#94562#).
+ AlignToCursor( aViewData.GetCurX(), aViewData.GetCurY(), SC_FOLLOW_NONE );
+}
+
+void ScTabView::DoneRefMode( sal_Bool bContinue )
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ if ( aViewData.GetRefType() == SC_REFTYPE_REF && bContinue )
+ SC_MOD()->AddRefEntry();
+
+ sal_Bool bWasRef = aViewData.IsRefMode();
+ aViewData.SetRefMode( sal_False, SC_REFTYPE_NONE );
+
+ HideTip();
+ UpdateShrinkOverlay();
+
+ // Paint:
+ if ( bWasRef && aViewData.GetTabNo() >= aViewData.GetRefStartZ() &&
+ aViewData.GetTabNo() <= aViewData.GetRefEndZ() )
+ {
+ SCCOL nStartX = aViewData.GetRefStartX();
+ SCROW nStartY = aViewData.GetRefStartY();
+ SCCOL nEndX = aViewData.GetRefEndX();
+ SCROW nEndY = aViewData.GetRefEndY();
+ if ( nStartX == nEndX && nStartY == nEndY )
+ pDoc->ExtendMerge( nStartX, nStartY, nEndX, nEndY, aViewData.GetTabNo() );
+
+ PaintArea( nStartX,nStartY,nEndX,nEndY, SC_UPDATE_MARKS );
+ }
+}
+
+void ScTabView::UpdateRef( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ )
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+
+ if (!aViewData.IsRefMode())
+ {
+ // Das kommt vor, wenn bei einem Referenz-Dialog als erstes mit Control in die
+ // die Tabelle geklickt wird. Dann die neue Referenz an den alten Inhalt anhaengen:
+
+ ScModule* pScMod = SC_MOD();
+ if (pScMod->IsFormulaMode())
+ pScMod->AddRefEntry();
+
+ InitRefMode( nCurX, nCurY, nCurZ, SC_REFTYPE_REF );
+ }
+
+ if ( nCurX != aViewData.GetRefEndX() || nCurY != aViewData.GetRefEndY() ||
+ nCurZ != aViewData.GetRefEndZ() )
+ {
+ ScMarkData& rMark = aViewData.GetMarkData();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ SCCOL nStartX = aViewData.GetRefStartX();
+ SCROW nStartY = aViewData.GetRefStartY();
+ SCCOL nEndX = aViewData.GetRefEndX();
+ SCROW nEndY = aViewData.GetRefEndY();
+ if ( nStartX == nEndX && nStartY == nEndY )
+ pDoc->ExtendMerge( nStartX, nStartY, nEndX, nEndY, nTab );
+ ScUpdateRect aRect( nStartX, nStartY, nEndX, nEndY );
+
+ aViewData.SetRefEnd( nCurX, nCurY, nCurZ );
+
+ nStartX = aViewData.GetRefStartX();
+ nStartY = aViewData.GetRefStartY();
+ nEndX = aViewData.GetRefEndX();
+ nEndY = aViewData.GetRefEndY();
+ if ( nStartX == nEndX && nStartY == nEndY )
+ pDoc->ExtendMerge( nStartX, nStartY, nEndX, nEndY, nTab );
+ aRect.SetNew( nStartX, nStartY, nEndX, nEndY );
+
+ ScRefType eType = aViewData.GetRefType();
+ if ( eType == SC_REFTYPE_REF )
+ {
+ ScRange aRef(
+ aViewData.GetRefStartX(), aViewData.GetRefStartY(), aViewData.GetRefStartZ(),
+ aViewData.GetRefEndX(), aViewData.GetRefEndY(), aViewData.GetRefEndZ() );
+ SC_MOD()->SetReference( aRef, pDoc, &rMark );
+ ShowRefTip();
+ }
+ else if ( eType == SC_REFTYPE_EMBED_LT || eType == SC_REFTYPE_EMBED_RB )
+ {
+ PutInOrder(nStartX,nEndX);
+ PutInOrder(nStartY,nEndY);
+ pDoc->SetEmbedded( ScRange(nStartX,nStartY,nTab, nEndX,nEndY,nTab) );
+ ScDocShell* pDocSh = aViewData.GetDocShell();
+ pDocSh->UpdateOle( &aViewData, sal_True );
+ pDocSh->SetDocumentModified();
+ }
+
+ SCCOL nPaintStartX;
+ SCROW nPaintStartY;
+ SCCOL nPaintEndX;
+ SCROW nPaintEndY;
+ if (aRect.GetDiff( nPaintStartX, nPaintStartY, nPaintEndX, nPaintEndY ))
+ PaintArea( nPaintStartX, nPaintStartY, nPaintEndX, nPaintEndY, SC_UPDATE_MARKS );
+ }
+
+ // Tip-Hilfe fuer Auto-Fill
+
+ if ( aViewData.GetRefType() == SC_REFTYPE_FILL && Help::IsQuickHelpEnabled() )
+ {
+ String aHelpStr;
+ ScRange aMarkRange;
+ aViewData.GetSimpleArea( aMarkRange );
+ SCCOL nEndX = aViewData.GetRefEndX();
+ SCROW nEndY = aViewData.GetRefEndY();
+ ScRange aDelRange;
+ if ( aViewData.GetFillMode() == SC_FILL_MATRIX && !(nScFillModeMouseModifier & KEY_MOD1) )
+ {
+ aHelpStr = ScGlobal::GetRscString( STR_TIP_RESIZEMATRIX );
+ SCCOL nCols = nEndX + 1 - aViewData.GetRefStartX(); // Reihenfolge ist richtig
+ SCROW nRows = nEndY + 1 - aViewData.GetRefStartY();
+ aHelpStr.SearchAndReplace( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("%1")),
+ String::CreateFromInt32(nRows) );
+ aHelpStr.SearchAndReplace( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("%2")),
+ String::CreateFromInt32(nCols) );
+ }
+ else if ( aViewData.GetDelMark( aDelRange ) )
+ aHelpStr = ScGlobal::GetRscString( STR_QUICKHELP_DELETE );
+ else if ( nEndX != aMarkRange.aEnd.Col() || nEndY != aMarkRange.aEnd.Row() )
+ aHelpStr = pDoc->GetAutoFillPreview( aMarkRange, nEndX, nEndY );
+
+ // je nach Richtung die obere oder untere Ecke:
+ SCCOL nAddX = ( nEndX >= aMarkRange.aEnd.Col() ) ? 1 : 0;
+ SCROW nAddY = ( nEndY >= aMarkRange.aEnd.Row() ) ? 1 : 0;
+ Point aPos = aViewData.GetScrPos( nEndX+nAddX, nEndY+nAddY, aViewData.GetActivePart() );
+ aPos.X() += 8;
+ aPos.Y() += 4;
+ Window* pWin = GetActiveWin();
+ if ( pWin )
+ aPos = pWin->OutputToScreenPixel( aPos );
+ Rectangle aRect( aPos, aPos );
+ sal_uInt16 nAlign = QUICKHELP_LEFT|QUICKHELP_TOP;
+ Help::ShowQuickHelp(pWin, aRect, aHelpStr, nAlign);
+ }
+}
+
+void ScTabView::InitRefMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ, ScRefType eType, sal_Bool bPaint )
+{
+ ScDocument* pDoc = aViewData.GetDocument();
+ ScMarkData& rMark = aViewData.GetMarkData();
+ if (!aViewData.IsRefMode())
+ {
+ aViewData.SetRefMode( sal_True, eType );
+ aViewData.SetRefStart( nCurX, nCurY, nCurZ );
+ aViewData.SetRefEnd( nCurX, nCurY, nCurZ );
+
+ if (nCurZ == aViewData.GetTabNo() && bPaint)
+ {
+ SCCOL nStartX = nCurX;
+ SCROW nStartY = nCurY;
+ SCCOL nEndX = nCurX;
+ SCROW nEndY = nCurY;
+ pDoc->ExtendMerge( nStartX, nStartY, nEndX, nEndY, aViewData.GetTabNo() );
+
+ //! nur Markierung ueber Inhalte zeichnen!
+ PaintArea( nStartX,nStartY,nEndX,nEndY, SC_UPDATE_MARKS );
+
+ // SetReference ohne Merge-Anpassung
+ ScRange aRef( nCurX,nCurY,nCurZ, nCurX,nCurY,nCurZ );
+ SC_MOD()->SetReference( aRef, pDoc, &rMark );
+ }
+ }
+}
+
+//UNUSED2008-05 void ScTabView::EndSelection()
+//UNUSED2008-05 {
+//UNUSED2008-05 ScModule* pScMod = SC_MOD();
+//UNUSED2008-05 sal_Bool bRefMode = pScMod->IsFormulaMode();
+//UNUSED2008-05 if ( bRefMode )
+//UNUSED2008-05 pScMod->EndReference();
+//UNUSED2008-05 }
+
+// static
+void ScTabView::SetScrollBar( ScrollBar& rScroll, long nRangeMax, long nVisible, long nPos, sal_Bool bLayoutRTL )
+{
+ if ( nVisible == 0 )
+ nVisible = 1; // #i59893# don't use visible size 0
+
+ // RTL layout uses a negative range to simulate a mirrored scroll bar.
+ // SetScrollBar/GetScrollBarPos hide this so outside of these functions normal cell
+ // addresses can be used.
+
+ if ( bLayoutRTL )
+ {
+ rScroll.SetRange( Range( -nRangeMax, 0 ) );
+ rScroll.SetVisibleSize( nVisible );
+ rScroll.SetThumbPos( -nPos - nVisible );
+ }
+ else
+ {
+ rScroll.SetRange( Range( 0, nRangeMax ) );
+ rScroll.SetVisibleSize( nVisible );
+ rScroll.SetThumbPos( nPos );
+ }
+}
+
+// static
+long ScTabView::GetScrollBarPos( ScrollBar& rScroll, sal_Bool bLayoutRTL )
+{
+ if ( bLayoutRTL )
+ return -rScroll.GetThumbPos() - rScroll.GetVisibleSize();
+ else
+ return rScroll.GetThumbPos();
+}
+
+// UpdateScrollBars - sichtbaren Bereich und Scrollweite der Scrollbars einstellen
+
+long lcl_UpdateBar( ScrollBar& rScroll, SCCOLROW nSize ) // Size = (komplette) Zellen
+{
+ long nOldPos;
+ long nNewPos;
+
+ nOldPos = rScroll.GetThumbPos();
+ rScroll.SetPageSize( static_cast<long>(nSize) );
+ nNewPos = rScroll.GetThumbPos();
+#ifndef UNX
+ rScroll.SetPageSize( 1 ); // immer moeglich !
+#endif
+
+ return nNewPos - nOldPos;
+}
+
+long lcl_GetScrollRange( SCCOLROW nDocEnd, SCCOLROW nPos, SCCOLROW nVis, SCCOLROW nMax, SCCOLROW nStart )
+{
+ // get the end (positive) of a scroll bar range that always starts at 0
+
+ ++nVis;
+ ++nMax; // for partially visible cells
+ SCCOLROW nEnd = Max(nDocEnd, (SCCOLROW)(nPos+nVis)) + nVis;
+ if (nEnd > nMax)
+ nEnd = nMax;
+
+ return ( nEnd - nStart ); // for range starting at 0
+}
+
+void ScTabView::UpdateScrollBars()
+{
+ long nDiff;
+ sal_Bool bTop = ( aViewData.GetVSplitMode() != SC_SPLIT_NONE );
+ sal_Bool bRight = ( aViewData.GetHSplitMode() != SC_SPLIT_NONE );
+ ScDocument* pDoc = aViewData.GetDocument();
+ SCTAB nTab = aViewData.GetTabNo();
+ sal_Bool bMirror = pDoc->IsLayoutRTL( nTab ) != Application::GetSettings().GetLayoutRTL();
+ SCCOL nUsedX;
+ SCROW nUsedY;
+ pDoc->GetTableArea( nTab, nUsedX, nUsedY ); //! cachen !!!!!!!!!!!!!!!
+
+ SCCOL nVisXL = 0;
+ SCCOL nVisXR = 0;
+ SCROW nVisYB = 0;
+ SCROW nVisYT = 0;
+
+ SCCOL nStartX = 0;
+ SCROW nStartY = 0;
+ if (aViewData.GetHSplitMode()==SC_SPLIT_FIX)
+ nStartX = aViewData.GetFixPosX();
+ if (aViewData.GetVSplitMode()==SC_SPLIT_FIX)
+ nStartY = aViewData.GetFixPosY();
+
+ nVisXL = aViewData.VisibleCellsX( SC_SPLIT_LEFT );
+ long nMaxXL = lcl_GetScrollRange( nUsedX, aViewData.GetPosX(SC_SPLIT_LEFT), nVisXL, MAXCOL, 0 );
+ SetScrollBar( aHScrollLeft, nMaxXL, nVisXL, aViewData.GetPosX( SC_SPLIT_LEFT ), bMirror );
+
+ nVisYB = aViewData.VisibleCellsY( SC_SPLIT_BOTTOM );
+ long nMaxYB = lcl_GetScrollRange( nUsedY, aViewData.GetPosY(SC_SPLIT_BOTTOM), nVisYB, MAXROW, nStartY );
+ SetScrollBar( aVScrollBottom, nMaxYB, nVisYB, aViewData.GetPosY( SC_SPLIT_BOTTOM ) - nStartY, sal_False );
+
+ if (bRight)
+ {
+ nVisXR = aViewData.VisibleCellsX( SC_SPLIT_RIGHT );
+ long nMaxXR = lcl_GetScrollRange( nUsedX, aViewData.GetPosX(SC_SPLIT_RIGHT), nVisXR, MAXCOL, nStartX );
+ SetScrollBar( aHScrollRight, nMaxXR, nVisXR, aViewData.GetPosX( SC_SPLIT_RIGHT ) - nStartX, bMirror );
+ }
+
+ if (bTop)
+ {
+ nVisYT = aViewData.VisibleCellsY( SC_SPLIT_TOP );
+ long nMaxYT = lcl_GetScrollRange( nUsedY, aViewData.GetPosY(SC_SPLIT_TOP), nVisYT, MAXROW, 0 );
+ SetScrollBar( aVScrollTop, nMaxYT, nVisYT, aViewData.GetPosY( SC_SPLIT_TOP ), sal_False );
+ }
+
+ // Bereich testen
+
+ nDiff = lcl_UpdateBar( aHScrollLeft, nVisXL );
+ if (nDiff) ScrollX( nDiff, SC_SPLIT_LEFT );
+ if (bRight)
+ {
+ nDiff = lcl_UpdateBar( aHScrollRight, nVisXR );
+ if (nDiff) ScrollX( nDiff, SC_SPLIT_RIGHT );
+ }
+
+ nDiff = lcl_UpdateBar( aVScrollBottom, nVisYB );
+ if (nDiff) ScrollY( nDiff, SC_SPLIT_BOTTOM );
+ if (bTop)
+ {
+ nDiff = lcl_UpdateBar( aVScrollTop, nVisYT );
+ if (nDiff) ScrollY( nDiff, SC_SPLIT_TOP );
+ }
+
+ // set visible area for online spelling
+
+ if ( aViewData.IsActive() )
+ {
+ ScSplitPos eActive = aViewData.GetActivePart();
+ ScHSplitPos eHWhich = WhichH( eActive );
+ ScVSplitPos eVWhich = WhichV( eActive );
+ SCCOL nPosX = aViewData.GetPosX(eHWhich);
+ SCROW nPosY = aViewData.GetPosY(eVWhich);
+ SCCOL nEndX = nPosX + ( ( eHWhich == SC_SPLIT_LEFT ) ? nVisXL : nVisXR );
+ SCROW nEndY = nPosY + ( ( eVWhich == SC_SPLIT_TOP ) ? nVisYT : nVisYB );
+ if ( nEndX > MAXCOL ) nEndX = MAXCOL;
+ if ( nEndY > MAXROW ) nEndY = MAXROW;
+ ScRange aVisible( nPosX, nPosY, nTab, nEndX, nEndY, nTab );
+ if ( pDoc->SetVisibleSpellRange( aVisible ) )
+ SC_MOD()->AnythingChanged(); // if visible area has changed
+ }
+}
+
+#ifndef HDR_SLIDERSIZE
+#define HDR_SLIDERSIZE 2
+#endif
+
+void ScTabView::InvertHorizontal( ScVSplitPos eWhich, long nDragPos )
+{
+ for (sal_uInt16 i=0; i<4; i++)
+ if (WhichV((ScSplitPos)i)==eWhich)
+ {
+ ScGridWindow* pWin = pGridWin[i];
+ if (pWin)
+ {
+ Rectangle aRect( 0,nDragPos, pWin->GetOutputSizePixel().Width()-1,nDragPos+HDR_SLIDERSIZE-1 );
+ pWin->Update();
+ pWin->DoInvertRect( aRect ); // Pixel
+ }
+ }
+}
+
+void ScTabView::InvertVertical( ScHSplitPos eWhich, long nDragPos )
+{
+ for (sal_uInt16 i=0; i<4; i++)
+ if (WhichH((ScSplitPos)i)==eWhich)
+ {
+ ScGridWindow* pWin = pGridWin[i];
+ if (pWin)
+ {
+ Rectangle aRect( nDragPos,0, nDragPos+HDR_SLIDERSIZE-1,pWin->GetOutputSizePixel().Height()-1 );
+ pWin->Update();
+ pWin->DoInvertRect( aRect ); // Pixel
+ }
+ }
+}
+
+//==================================================================
+
+void ScTabView::InterpretVisible()
+{
+ // make sure all visible cells are interpreted,
+ // so the next paint will not execute a macro function
+
+ ScDocument* pDoc = aViewData.GetDocument();
+ if ( !pDoc->GetAutoCalc() )
+ return;
+
+ SCTAB nTab = aViewData.GetTabNo();
+ for (sal_uInt16 i=0; i<4; i++)
+ {
+ // rely on gridwin pointers to find used panes
+ // no IsVisible test in case the whole view is not yet shown
+
+ if (pGridWin[i])
+ {
+ ScHSplitPos eHWhich = WhichH( ScSplitPos(i) );
+ ScVSplitPos eVWhich = WhichV( ScSplitPos(i) );
+
+ SCCOL nX1 = aViewData.GetPosX( eHWhich );
+ SCROW nY1 = aViewData.GetPosY( eVWhich );
+ SCCOL nX2 = nX1 + aViewData.VisibleCellsX( eHWhich );
+ SCROW nY2 = nY1 + aViewData.VisibleCellsY( eVWhich );
+
+ if (nX2 > MAXCOL) nX2 = MAXCOL;
+ if (nY2 > MAXROW) nY2 = MAXROW;
+
+ ScCellIterator aIter( pDoc, nX1, nY1, nTab, nX2, nY2, nTab );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while ( pCell )
+ {
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA && ((ScFormulaCell*)pCell)->GetDirty() )
+ ((ScFormulaCell*)pCell)->Interpret();
+
+ pCell = aIter.GetNext();
+ }
+ }
+ }
+
+ // #i65047# repaint during the above loop may have set the bNeedsRepaint flag
+ CheckNeedsRepaint();
+}
+
+
+
+
+
diff --git a/sc/source/ui/view/tabview5.cxx b/sc/source/ui/view/tabview5.cxx
new file mode 100644
index 000000000000..a20c73d04adf
--- /dev/null
+++ b/sc/source/ui/view/tabview5.cxx
@@ -0,0 +1,722 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <svx/fmshell.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdoutl.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/objsh.hxx>
+#include <tools/ref.hxx>
+
+#include "tabview.hxx"
+#include "tabvwsh.hxx"
+#include "document.hxx"
+#include "gridwin.hxx"
+#include "olinewin.hxx"
+#include "tabsplit.hxx"
+#include "colrowba.hxx"
+#include "tabcont.hxx"
+#include "hintwin.hxx"
+#include "sc.hrc"
+#include "pagedata.hxx"
+#include "hiranges.hxx"
+#include "drawview.hxx"
+#include "drwlayer.hxx"
+#include "fusel.hxx" // Start-Function
+#include "seltrans.hxx"
+#include "scmod.hxx"
+#include "AccessibilityHints.hxx"
+#include "docsh.hxx"
+#include "viewuno.hxx"
+
+#include <vcl/svapp.hxx>
+
+using namespace com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+
+void __EXPORT ScTabView::Init()
+{
+ /* RTL layout of the view windows is done manually, because it depends on
+ the sheet orientation, not the UI setting. Note: controls that are
+ already constructed (e.g. scroll bars) have the RTL setting of the GUI.
+ Eventually this has to be disabled manually (see below). */
+ pFrameWin->EnableRTL( sal_False );
+
+ sal_uInt16 i;
+
+ aScrollTimer.SetTimeout(10);
+ aScrollTimer.SetTimeoutHdl( LINK( this, ScTabView, TimerHdl ) );
+
+ for (i=0; i<4; i++)
+ pGridWin[i] = NULL;
+ pGridWin[SC_SPLIT_BOTTOMLEFT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_BOTTOMLEFT );
+
+ pSelEngine = new ScViewSelectionEngine( pGridWin[SC_SPLIT_BOTTOMLEFT], this,
+ SC_SPLIT_BOTTOMLEFT );
+ aFunctionSet.SetSelectionEngine( pSelEngine );
+
+ pHdrSelEng = new ScHeaderSelectionEngine( pFrameWin, &aHdrFunc );
+
+ pColBar[SC_SPLIT_LEFT] = new ScColBar( pFrameWin, &aViewData, SC_SPLIT_LEFT,
+ &aHdrFunc, pHdrSelEng );
+ pColBar[SC_SPLIT_RIGHT] = NULL;
+ pRowBar[SC_SPLIT_BOTTOM] = new ScRowBar( pFrameWin, &aViewData, SC_SPLIT_BOTTOM,
+ &aHdrFunc, pHdrSelEng );
+ pRowBar[SC_SPLIT_TOP] = NULL;
+ for (i=0; i<2; i++)
+ pColOutline[i] = pRowOutline[i] = NULL;
+
+ pHSplitter = new ScTabSplitter( pFrameWin, WinBits( WB_HSCROLL ), &aViewData );
+ pVSplitter = new ScTabSplitter( pFrameWin, WinBits( WB_VSCROLL ), &aViewData );
+
+ // SSA: override default keyboard step size to allow snap to row/column
+ pHSplitter->SetKeyboardStepSize( 1 );
+ pVSplitter->SetKeyboardStepSize( 1 );
+
+ pTabControl = new ScTabControl( pFrameWin, &aViewData );
+ /* #i97900# The tab control has to remain in RTL mode if GUI is RTL, this
+ is needed to draw the 3D effect correctly. The base TabBar implementes
+ mirroring independent from the GUI direction. Have to set RTL mode
+ explicitly because the parent frame window is already RTL disabled. */
+ pTabControl->EnableRTL( Application::GetSettings().GetLayoutRTL() );
+
+ InitScrollBar( aHScrollLeft, MAXCOL+1 );
+ InitScrollBar( aHScrollRight, MAXCOL+1 );
+ InitScrollBar( aVScrollTop, MAXROW+1 );
+ InitScrollBar( aVScrollBottom, MAXROW+1 );
+ /* #i97900# scrollbars remain in correct RTL mode, needed mirroring etc.
+ is now handled correctly at the respective places. */
+
+ // Hier noch nichts anzeigen (Show), weil noch falsch angeordnet ist
+ // Show kommt dann aus UpdateShow beim ersten Resize
+ // pTabControl, pGridWin, aHScrollLeft, aVScrollBottom,
+ // aCornerButton, aScrollBarBox, pHSplitter, pVSplitter
+
+ // Splitter
+
+ pHSplitter->SetSplitHdl( LINK( this, ScTabView, SplitHdl ) );
+ pVSplitter->SetSplitHdl( LINK( this, ScTabView, SplitHdl ) );
+
+ // UpdateShow kommt beim Resize, oder bei Kopie einer bestehenden View aus dem ctor
+
+ pDrawActual = NULL;
+ pDrawOld = NULL;
+
+ // DrawView darf nicht im TabView - ctor angelegt werden,
+ // wenn die ViewShell noch nicht konstruiert ist...
+ // Das gilt auch fuer ViewOptionsHasChanged()
+
+ TestHintWindow();
+}
+
+__EXPORT ScTabView::~ScTabView()
+{
+ sal_uInt16 i;
+
+ // remove selection object
+ ScModule* pScMod = SC_MOD();
+ ScSelectionTransferObj* pOld = pScMod->GetSelectionTransfer();
+ if ( pOld && pOld->GetView() == this )
+ {
+ pOld->ForgetView();
+ pScMod->SetSelectionTransfer( NULL );
+ TransferableHelper::ClearSelection( GetActiveWin() ); // may delete pOld
+ }
+
+ DELETEZ(pBrushDocument);
+ DELETEZ(pDrawBrushSet);
+
+ DELETEZ(pPageBreakData);
+ DELETEZ(pHighlightRanges);
+
+ DELETEZ(pDrawOld);
+ DELETEZ(pDrawActual);
+
+ aViewData.KillEditView(); // solange GridWin's noch existieren
+
+ DELETEZ(pInputHintWindow);
+
+ if (pDrawView)
+ {
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ {
+ pDrawView->VCRemoveWin(pGridWin[i]);
+ pDrawView->DeleteWindowFromPaintView(pGridWin[i]);
+ }
+
+ pDrawView->HideSdrPage();
+ delete pDrawView;
+ }
+
+ delete pSelEngine;
+
+ for (i=0; i<4; i++)
+ delete pGridWin[i];
+
+ delete pHdrSelEng;
+
+ for (i=0; i<2; i++)
+ {
+ delete pColBar[i];
+ delete pRowBar[i];
+ delete pColOutline[i];
+ delete pRowOutline[i];
+ }
+
+ delete pHSplitter;
+ delete pVSplitter;
+
+ delete pTabControl;
+}
+
+void ScTabView::MakeDrawView( sal_uInt8 nForceDesignMode )
+{
+ if (!pDrawView)
+ {
+ ScDrawLayer* pLayer = aViewData.GetDocument()->GetDrawLayer();
+ DBG_ASSERT(pLayer, "wo ist der Draw Layer ??");
+
+ sal_uInt16 i;
+ pDrawView = new ScDrawView( pGridWin[SC_SPLIT_BOTTOMLEFT], &aViewData );
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ {
+ if ( SC_SPLIT_BOTTOMLEFT != (ScSplitPos)i )
+ pDrawView->AddWindowToPaintView(pGridWin[i]);
+ pDrawView->VCAddWin(pGridWin[i]);
+ }
+ pDrawView->RecalcScale();
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ {
+ pGridWin[i]->SetMapMode(pGridWin[i]->GetDrawMapMode());
+
+ pGridWin[i]->Update(); // wegen Invalidate im DrawView ctor (ShowPage),
+ // damit gleich gezeichnet werden kann
+ }
+ SfxRequest aSfxRequest(SID_OBJECT_SELECT, 0,aViewData.GetViewShell()->GetPool());
+ SetDrawFuncPtr(new FuSelection( aViewData.GetViewShell(), GetActiveWin(), pDrawView,
+ pLayer,aSfxRequest));
+
+ // #106334# used when switching back from page preview: restore saved design mode state
+ // (otherwise, keep the default from the draw view ctor)
+ if ( nForceDesignMode != SC_FORCEMODE_NONE )
+ pDrawView->SetDesignMode( (sal_Bool)nForceDesignMode );
+
+ // an der FormShell anmelden
+ FmFormShell* pFormSh = aViewData.GetViewShell()->GetFormShell();
+ if (pFormSh)
+ pFormSh->SetView(pDrawView);
+
+ if (aViewData.GetViewShell()->HasAccessibilityObjects())
+ aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_MAKEDRAWLAYER));
+
+ }
+}
+
+void ScTabView::DoAddWin( ScGridWindow* pWin )
+{
+ if (pDrawView)
+ {
+ pDrawView->AddWindowToPaintView(pWin);
+ pDrawView->VCAddWin(pWin);
+
+ // #114409#
+ pWin->DrawLayerCreated();
+ }
+}
+
+//==================================================================
+
+void ScTabView::TabChanged( bool bSameTabButMoved )
+{
+ if (pDrawView)
+ {
+ DrawDeselectAll(); // beendet auch Text-Edit-Modus
+
+ sal_uInt16 i;
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ pDrawView->VCRemoveWin(pGridWin[i]); // fuer alte Page
+
+ SCTAB nTab = aViewData.GetTabNo();
+ pDrawView->HideSdrPage();
+ pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
+
+ UpdateLayerLocks();
+
+ pDrawView->RecalcScale();
+ pDrawView->UpdateWorkArea(); // #54782# PageSize ist pro Page unterschiedlich
+
+ for (i=0; i<4; i++)
+ if (pGridWin[i])
+ pDrawView->VCAddWin(pGridWin[i]); // fuer neue Page
+ }
+
+ SfxBindings& rBindings = aViewData.GetBindings();
+
+ // Es gibt keine einfache Moeglichkeit, alle Slots der FormShell zu invalidieren
+ // (fuer disablete Slots auf geschuetzten Tabellen), darum hier einfach alles...
+ rBindings.InvalidateAll(sal_False);
+
+#if 0
+ rBindings.Invalidate( SID_SELECT_SCENARIO );
+ rBindings.Invalidate( FID_PROTECT_TABLE );
+ rBindings.Invalidate( FID_DELETE_TABLE );
+ rBindings.Invalidate( FID_TABLE_SHOW );
+ rBindings.Invalidate( FID_TABLE_HIDE );
+
+ // Auswirkungen von geschuetzten Tabellen.
+ rBindings.Invalidate( FID_TAB_RENAME );
+ rBindings.Invalidate( FID_TAB_MOVE );
+ rBindings.Invalidate( SID_DEL_ROWS );
+ rBindings.Invalidate( SID_DEL_COLS );
+ rBindings.Invalidate( FID_INS_ROW );
+ rBindings.Invalidate( FID_INS_COLUMN );
+ rBindings.Invalidate( FID_INS_CELL );
+ rBindings.Invalidate( FID_INS_CELLSDOWN );
+ rBindings.Invalidate( FID_INS_CELLSRIGHT );
+ rBindings.Invalidate( FID_DELETE_CELL );
+
+ rBindings.Invalidate( SID_OPENDLG_CHART );
+ rBindings.Invalidate( SID_INSERT_OBJECT );
+ rBindings.Invalidate( SID_INSERT_DIAGRAM );
+ rBindings.Invalidate( SID_INSERT_SMATH );
+ rBindings.Invalidate( SID_INSERT_GRAPHIC );
+#endif
+
+ if (aViewData.GetViewShell()->HasAccessibilityObjects())
+ {
+ SfxSimpleHint aAccHint(SC_HINT_ACC_TABLECHANGED);
+ aViewData.GetViewShell()->BroadcastAccessibility(aAccHint);
+ }
+
+ // notification for XActivationBroadcaster
+ SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
+ if (pViewFrame)
+ {
+ uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController();
+ if (xController.is())
+ {
+ ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
+ if (pImp)
+ pImp->SheetChanged( bSameTabButMoved );
+ }
+ }
+}
+
+void ScTabView::UpdateLayerLocks()
+{
+ if (pDrawView)
+ {
+ SCTAB nTab = aViewData.GetTabNo();
+ sal_Bool bEx = aViewData.GetViewShell()->IsDrawSelMode();
+ sal_Bool bProt = aViewData.GetDocument()->IsTabProtected( nTab ) ||
+ aViewData.GetSfxDocShell()->IsReadOnly();
+ sal_Bool bShared = aViewData.GetDocShell()->IsDocShared();
+
+ SdrLayer* pLayer;
+ SdrLayerAdmin& rAdmin = pDrawView->GetModel()->GetLayerAdmin();
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_BACK);
+ if (pLayer)
+ pDrawView->SetLayerLocked( pLayer->GetName(), bProt || !bEx || bShared );
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_INTERN);
+ if (pLayer)
+ pDrawView->SetLayerLocked( pLayer->GetName(), sal_True );
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_FRONT);
+ if (pLayer)
+ pDrawView->SetLayerLocked( pLayer->GetName(), bProt || bShared );
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_CONTROLS);
+ if (pLayer)
+ pDrawView->SetLayerLocked( pLayer->GetName(), bProt || bShared );
+ pLayer = rAdmin.GetLayerPerID(SC_LAYER_HIDDEN);
+ if (pLayer)
+ {
+ pDrawView->SetLayerLocked( pLayer->GetName(), bProt || bShared );
+ pDrawView->SetLayerVisible( pLayer->GetName(), sal_False);
+ }
+ }
+}
+
+void ScTabView::DrawDeselectAll()
+{
+ if (pDrawView)
+ {
+ ScTabViewShell* pViewSh = aViewData.GetViewShell();
+ if ( pDrawActual &&
+ ( pViewSh->IsDrawTextShell() || pDrawActual->GetSlotID() == SID_DRAW_NOTEEDIT ) )
+ {
+ // end text edit (as if escape pressed, in FuDraw)
+ aViewData.GetDispatcher().Execute( pDrawActual->GetSlotID(),
+ SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
+ }
+
+ pDrawView->ScEndTextEdit();
+ pDrawView->UnmarkAll();
+
+ if (!pViewSh->IsDrawSelMode())
+ pViewSh->SetDrawShell( sal_False );
+ }
+}
+
+sal_Bool ScTabView::IsDrawTextEdit() const
+{
+ if (pDrawView)
+ return pDrawView->IsTextEdit();
+ else
+ return sal_False;
+}
+
+//UNUSED2008-05 String ScTabView::GetSelectedChartName() const
+//UNUSED2008-05 {
+//UNUSED2008-05 if (pDrawView)
+//UNUSED2008-05 return pDrawView->GetSelectedChartName();
+//UNUSED2008-05 else
+//UNUSED2008-05 return EMPTY_STRING;
+//UNUSED2008-05 }
+
+SvxZoomType ScTabView::GetZoomType() const
+{
+ return aViewData.GetZoomType();
+}
+
+void ScTabView::SetZoomType( SvxZoomType eNew, sal_Bool bAll )
+{
+ aViewData.SetZoomType( eNew, bAll );
+}
+
+void ScTabView::SetZoom( const Fraction& rNewX, const Fraction& rNewY, sal_Bool bAll )
+{
+ aViewData.SetZoom( rNewX, rNewY, bAll );
+ if (pDrawView)
+ pDrawView->RecalcScale();
+ ZoomChanged(); // einzeln wegen CLOOKs
+}
+
+void ScTabView::RefreshZoom()
+{
+ aViewData.RefreshZoom();
+ if (pDrawView)
+ pDrawView->RecalcScale();
+ ZoomChanged();
+}
+
+void ScTabView::SetPagebreakMode( sal_Bool bSet )
+{
+ aViewData.SetPagebreakMode(bSet);
+ if (pDrawView)
+ pDrawView->RecalcScale();
+ ZoomChanged(); // einzeln wegen CLOOKs
+}
+
+void ScTabView::ResetDrawDragMode()
+{
+ if (pDrawView)
+ pDrawView->SetDragMode( SDRDRAG_MOVE );
+}
+
+void ScTabView::ViewOptionsHasChanged( sal_Bool bHScrollChanged, sal_Bool bGraphicsChanged )
+{
+ // DrawView erzeugen, wenn Gitter angezeigt werden soll
+ if ( !pDrawView && aViewData.GetOptions().GetGridOptions().GetGridVisible() )
+ MakeDrawLayer();
+
+ if (pDrawView)
+ pDrawView->UpdateUserViewOptions();
+
+ if (bGraphicsChanged)
+ DrawEnableAnim(sal_True); // DrawEnableAnim checks the options state
+
+ // if TabBar is set to visible, make sure its size is not 0
+ sal_Bool bGrow = ( aViewData.IsTabMode() && pTabControl->GetSizePixel().Width() <= 0 );
+
+ // if ScrollBar is set to visible, TabBar must make room
+ sal_Bool bShrink = ( bHScrollChanged && aViewData.IsTabMode() && aViewData.IsHScrollMode() &&
+ pTabControl->GetSizePixel().Width() > SC_TABBAR_DEFWIDTH );
+
+ if ( bGrow || bShrink )
+ {
+ Size aSize = pTabControl->GetSizePixel();
+ aSize.Width() = SC_TABBAR_DEFWIDTH; // initial size
+ pTabControl->SetSizePixel(aSize); // DoResize is called later...
+ }
+}
+
+// Helper-Funktion gegen das Include des Drawing Layers
+
+SdrView* ScTabView::GetSdrView()
+{
+ return pDrawView;
+}
+
+void ScTabView::DrawMarkListHasChanged()
+{
+ if ( pDrawView )
+ pDrawView->MarkListHasChanged();
+}
+
+void ScTabView::UpdateAnchorHandles()
+{
+ if ( pDrawView )
+ pDrawView->AdjustMarkHdl();
+}
+
+void ScTabView::UpdateIMap( SdrObject* pObj )
+{
+ if ( pDrawView )
+ pDrawView->UpdateIMap( pObj );
+}
+
+void ScTabView::DrawMarkRect( const Rectangle& rRect )
+{
+ //! store rectangle for repaint during drag
+
+ for (sal_uInt16 i=0; i<4; i++)
+ {
+ if ( pGridWin[i] && pGridWin[i]->IsVisible() )
+ {
+ RasterOp aROp = pGridWin[i]->GetRasterOp();
+ sal_Bool bHasLine = pGridWin[i]->IsLineColor();
+ Color aLine = pGridWin[i]->GetLineColor();
+ sal_Bool bHasFill = pGridWin[i]->IsFillColor();
+ Color aFill = pGridWin[i]->GetFillColor();
+
+ pGridWin[i]->SetRasterOp( ROP_INVERT );
+ pGridWin[i]->SetLineColor( COL_BLACK );
+ pGridWin[i]->SetFillColor();
+
+ pGridWin[i]->DrawRect(rRect);
+
+ pGridWin[i]->SetRasterOp(aROp);
+ if (bHasLine)
+ pGridWin[i]->SetLineColor(aLine);
+ else
+ pGridWin[i]->SetLineColor();
+ if (bHasFill)
+ pGridWin[i]->SetFillColor(aFill);
+ else
+ pGridWin[i]->SetFillColor();
+ }
+ }
+}
+
+void ScTabView::DrawEnableAnim(sal_Bool bSet)
+{
+ sal_uInt16 i;
+ if ( pDrawView )
+ {
+ // #71040# dont start animations if display of graphics is disabled
+ // graphics are controlled by VOBJ_TYPE_OLE
+ if ( bSet && aViewData.GetOptions().GetObjMode(VOBJ_TYPE_OLE) == VOBJ_MODE_SHOW )
+ {
+ if ( !pDrawView->IsAnimationEnabled() )
+ {
+ pDrawView->SetAnimationEnabled(sal_True);
+
+ // Animierte GIFs muessen wieder gestartet werden:
+ ScDocument* pDoc = aViewData.GetDocument();
+ for (i=0; i<4; i++)
+ if ( pGridWin[i] && pGridWin[i]->IsVisible() )
+ pDoc->StartAnimations( aViewData.GetTabNo(), pGridWin[i] );
+ }
+ }
+ else
+ {
+ pDrawView->SetAnimationEnabled(sal_False);
+ }
+ }
+}
+
+//HMHvoid ScTabView::DrawShowMarkHdl(sal_Bool bShow)
+//HMH{
+ //HMHif (!pDrawView)
+ //HMH return;
+
+ //HMHif (bShow)
+ //HMH{
+ //HMH if (!pDrawView->IsDisableHdl())
+ //HMH pDrawView->ShowMarkHdl();
+ //HMH}
+ //HMHelse
+ //HMH pDrawView->HideMarkHdl();
+//HMH}
+
+void ScTabView::UpdateDrawTextOutliner()
+{
+ if ( pDrawView )
+ {
+ Outliner* pOL = pDrawView->GetTextEditOutliner();
+ if (pOL)
+ aViewData.UpdateOutlinerFlags( *pOL );
+ }
+}
+
+void ScTabView::DigitLanguageChanged()
+{
+ LanguageType eNewLang = SC_MOD()->GetOptDigitLanguage();
+ for (sal_uInt16 i=0; i<4; i++)
+ if ( pGridWin[i] )
+ pGridWin[i]->SetDigitLanguage( eNewLang );
+}
+
+//---------------------------------------------------------------
+
+void ScTabView::ScrollToObject( SdrObject* pDrawObj )
+{
+ if ( pDrawObj )
+ MakeVisible( pDrawObj->GetLogicRect() );
+}
+
+void ScTabView::MakeVisible( const Rectangle& rHMMRect )
+{
+ Window* pWin = GetActiveWin();
+ Size aWinSize = pWin->GetOutputSizePixel();
+ SCTAB nTab = aViewData.GetTabNo();
+
+ Rectangle aRect = pWin->LogicToPixel( rHMMRect );
+
+ long nScrollX=0, nScrollY=0; // Pixel
+
+ if ( aRect.Right() >= aWinSize.Width() ) // rechts raus
+ {
+ nScrollX = aRect.Right() - aWinSize.Width() + 1; // rechter Rand sichtbar
+ if ( aRect.Left() < nScrollX )
+ nScrollX = aRect.Left(); // links sichtbar (falls zu gross)
+ }
+ if ( aRect.Bottom() >= aWinSize.Height() ) // unten raus
+ {
+ nScrollY = aRect.Bottom() - aWinSize.Height() + 1; // unterer Rand sichtbar
+ if ( aRect.Top() < nScrollY )
+ nScrollY = aRect.Top(); // oben sichtbar (falls zu gross)
+ }
+
+ if ( aRect.Left() < 0 ) // links raus
+ nScrollX = aRect.Left(); // linker Rand sichtbar
+ if ( aRect.Top() < 0 ) // oben raus
+ nScrollY = aRect.Top(); // oberer Rand sichtbar
+
+ if (nScrollX || nScrollY)
+ {
+ ScDocument* pDoc = aViewData.GetDocument();
+ if ( pDoc->IsNegativePage( nTab ) )
+ nScrollX = -nScrollX;
+
+ double nPPTX = aViewData.GetPPTX();
+ double nPPTY = aViewData.GetPPTY();
+ ScSplitPos eWhich = aViewData.GetActivePart();
+ SCCOL nPosX = aViewData.GetPosX(WhichH(eWhich));
+ SCROW nPosY = aViewData.GetPosY(WhichV(eWhich));
+
+ long nLinesX=0, nLinesY=0; // Spalten/Zeilen - um mindestens nScrollX/Y scrollen
+
+ if (nScrollX > 0)
+ while (nScrollX > 0 && nPosX < MAXCOL)
+ {
+ nScrollX -= (long) ( pDoc->GetColWidth(nPosX, nTab) * nPPTX );
+ ++nPosX;
+ ++nLinesX;
+ }
+ else if (nScrollX < 0)
+ while (nScrollX < 0 && nPosX > 0)
+ {
+ --nPosX;
+ nScrollX += (long) ( pDoc->GetColWidth(nPosX, nTab) * nPPTX );
+ --nLinesX;
+ }
+
+ if (nScrollY > 0)
+ while (nScrollY > 0 && nPosY < MAXROW)
+ {
+ nScrollY -= (long) ( pDoc->GetRowHeight(nPosY, nTab) * nPPTY );
+ ++nPosY;
+ ++nLinesY;
+ }
+ else if (nScrollY < 0)
+ while (nScrollY < 0 && nPosY > 0)
+ {
+ --nPosY;
+ nScrollY += (long) ( pDoc->GetRowHeight(nPosY, nTab) * nPPTY );
+ --nLinesY;
+ }
+
+ ScrollLines( nLinesX, nLinesY ); // ausfuehren
+ }
+}
+
+//---------------------------------------------------------------
+
+void ScTabView::SetBrushDocument( ScDocument* pNew, sal_Bool bLock )
+{
+ delete pBrushDocument;
+ delete pDrawBrushSet;
+
+ pBrushDocument = pNew;
+ pDrawBrushSet = NULL;
+
+ bLockPaintBrush = bLock;
+
+ aViewData.GetBindings().Invalidate(SID_FORMATPAINTBRUSH);
+}
+
+void ScTabView::SetDrawBrushSet( SfxItemSet* pNew, sal_Bool bLock )
+{
+ delete pBrushDocument;
+ delete pDrawBrushSet;
+
+ pBrushDocument = NULL;
+ pDrawBrushSet = pNew;
+
+ bLockPaintBrush = bLock;
+
+ aViewData.GetBindings().Invalidate(SID_FORMATPAINTBRUSH);
+}
+
+void ScTabView::ResetBrushDocument()
+{
+ if ( HasPaintBrush() )
+ {
+ SetBrushDocument( NULL, sal_False );
+ SetActivePointer( Pointer( POINTER_ARROW ) ); // switch pointers also when ended with escape key
+ }
+}
+
+
diff --git a/sc/source/ui/view/tabvwsh.cxx b/sc/source/ui/view/tabvwsh.cxx
new file mode 100644
index 000000000000..bdeb74a2d101
--- /dev/null
+++ b/sc/source/ui/view/tabvwsh.cxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svx/galbrws.hxx>
+#include <svx/imapdlg.hxx>
+#include <svl/srchitem.hxx>
+#include <sfx2/templdlg.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/app.hxx>
+#include <avmedia/mediaplayer.hxx>
+
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "reffact.hxx"
+#include "scresid.hxx"
+#include "dwfunctr.hxx"
+#include "sc.hrc" // -> SID_TOOL_xxx
+#include "drawattr.hxx" // -> SvxDrawToolItem
+#include "spelldialog.hxx"
+
+
+#define ScTabViewShell
+#include "scslots.hxx"
+
+TYPEINIT2(ScTabViewShell,SfxViewShell,SfxListener);
+
+SFX_IMPL_INTERFACE(ScTabViewShell,SfxViewShell,ScResId(SCSTR_TABVIEWSHELL))
+{
+ SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_TOOLS | SFX_VISIBILITY_STANDARD |
+ SFX_VISIBILITY_FULLSCREEN | SFX_VISIBILITY_SERVER,
+ ScResId(RID_OBJECTBAR_TOOLS) );
+
+ SFX_CHILDWINDOW_REGISTRATION(FID_INPUTLINE_STATUS);
+ SFX_CHILDWINDOW_REGISTRATION(SfxTemplateDialogWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_CONTEXT_REGISTRATION(SID_NAVIGATOR);
+ SFX_CHILDWINDOW_REGISTRATION(SID_TASKPANE);
+ SFX_CHILDWINDOW_REGISTRATION(ScNameDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScSolverDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScOptSolverDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScPivotLayoutWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScTabOpDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScFilterDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScSpecialFilterDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScDbNameDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScConsolidateDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScPrintAreasDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScCondFormatDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScColRowNameRangesDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScFormulaDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(SvxIMapDlgChildWindow::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScFunctionChildWindow::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScFormulaDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScAcceptChgDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScHighlightChgDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScSimpleRefDlgWrapper::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(SID_SEARCH_DLG);
+ SFX_CHILDWINDOW_REGISTRATION(SID_HYPERLINK_DIALOG);
+ SFX_CHILDWINDOW_REGISTRATION(GalleryChildWindow::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION(ScSpellDialogChildWindow::GetChildWindowId());
+ SFX_CHILDWINDOW_REGISTRATION( ::avmedia::MediaPlayer::GetChildWindowId() );
+ SFX_CHILDWINDOW_REGISTRATION(ScValidityRefChildWin::GetChildWindowId());
+}
+
+SFX_IMPL_NAMED_VIEWFACTORY( ScTabViewShell, "Default" )
+{
+ SFX_VIEW_REGISTRATION(ScDocShell);
+}
+
+//------------------------------------------------------------------
+
+IMPL_LINK( ScTabViewShell, HtmlOptionsHdl, void*, EMPTYARG )
+{
+ // Invalidierung, falls blinkender Text erlaubt/verboten wurde
+ GetViewFrame()->GetBindings().Invalidate(SID_DRAW_TEXT_MARQUEE);
+ return 0;
+}
diff --git a/sc/source/ui/view/tabvwsh2.cxx b/sc/source/ui/view/tabvwsh2.cxx
new file mode 100644
index 000000000000..64b60caf6f4e
--- /dev/null
+++ b/sc/source/ui/view/tabvwsh2.cxx
@@ -0,0 +1,481 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#ifdef _MSC_VER
+#pragma optimize ("", off)
+#endif
+
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/aeitem.hxx>
+#include <svl/whiter.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <svl/languageoptions.hxx>
+#include <sfx2/dispatch.hxx>
+
+#include "tabvwsh.hxx"
+#include "drawattr.hxx"
+#include "drawsh.hxx"
+#include "drawview.hxx"
+#include "fupoor.hxx"
+#include "fuconrec.hxx"
+#include "fuconpol.hxx"
+#include "fuconarc.hxx"
+#include "fuconuno.hxx"
+#include "fusel.hxx"
+#include "futext.hxx"
+#include "fumark.hxx"
+#include "fuinsert.hxx"
+#include "global.hxx"
+#include "sc.hrc"
+#include "scmod.hxx"
+#include "appoptio.hxx"
+
+// #98185# Create default drawing objects via keyboard
+#include <svx/svdpagv.hxx>
+#include <svl/stritem.hxx>
+#include <svx/svdpage.hxx>
+#include <fuconcustomshape.hxx>
+
+// -----------------------------------------------------------------------
+
+SdrView* __EXPORT ScTabViewShell::GetDrawView() const
+{
+ return ((ScTabViewShell*)this)->GetScDrawView(); // GetScDrawView ist nicht-const
+}
+
+void ScTabViewShell::WindowChanged()
+{
+ Window* pWin = GetActiveWin();
+
+ ScDrawView* pDrView = GetScDrawView();
+ if (pDrView)
+ pDrView->SetActualWin(pWin);
+
+ FuPoor* pFunc = GetDrawFuncPtr();
+ if (pFunc)
+ pFunc->SetWindow(pWin);
+
+ // when font from InputContext is used,
+ // this must be moved to change of cursor position:
+ UpdateInputContext();
+}
+
+void ScTabViewShell::ExecDraw(SfxRequest& rReq)
+{
+ SC_MOD()->InputEnterHandler();
+ UpdateInputHandler();
+
+ MakeDrawLayer();
+
+ ScTabView* pTabView = GetViewData()->GetView();
+ SfxBindings& rBindings = GetViewFrame()->GetBindings();
+
+ Window* pWin = pTabView->GetActiveWin();
+ ScDrawView* pView = pTabView->GetScDrawView();
+ SdrModel* pDoc = pView->GetModel();
+
+ const SfxItemSet *pArgs = rReq.GetArgs();
+ sal_uInt16 nNewId = rReq.GetSlot();
+
+ if ( nNewId == SID_DRAW_CHART )
+ {
+ // #i71254# directly insert a chart instead of drawing its output rectangle
+ FuInsertChart(this, pWin, pView, pDoc, rReq);
+ return;
+ }
+
+ //
+ // Pseudo-Slots von Draw-Toolbox auswerten
+ //! wird das ueberhaupt noch gebraucht ?????
+ //
+
+ if (nNewId == SID_INSERT_DRAW && pArgs)
+ {
+ const SfxPoolItem* pItem;
+ if ( pArgs->GetItemState( SID_INSERT_DRAW, sal_True, &pItem ) == SFX_ITEM_SET &&
+ pItem->ISA( SvxDrawToolItem ) )
+ {
+ SvxDrawToolEnum eSel = (SvxDrawToolEnum)((const SvxDrawToolItem*)pItem)->GetValue();
+ switch (eSel)
+ {
+ case SVX_SNAP_DRAW_SELECT: nNewId = SID_OBJECT_SELECT; break;
+ case SVX_SNAP_DRAW_LINE: nNewId = SID_DRAW_LINE; break;
+ case SVX_SNAP_DRAW_RECT: nNewId = SID_DRAW_RECT; break;
+ case SVX_SNAP_DRAW_ELLIPSE: nNewId = SID_DRAW_ELLIPSE; break;
+ case SVX_SNAP_DRAW_POLYGON_NOFILL: nNewId = SID_DRAW_POLYGON_NOFILL; break;
+ case SVX_SNAP_DRAW_BEZIER_NOFILL: nNewId = SID_DRAW_BEZIER_NOFILL; break;
+ case SVX_SNAP_DRAW_FREELINE_NOFILL: nNewId = SID_DRAW_FREELINE_NOFILL; break;
+ case SVX_SNAP_DRAW_ARC: nNewId = SID_DRAW_ARC; break;
+ case SVX_SNAP_DRAW_PIE: nNewId = SID_DRAW_PIE; break;
+ case SVX_SNAP_DRAW_CIRCLECUT: nNewId = SID_DRAW_CIRCLECUT; break;
+ case SVX_SNAP_DRAW_TEXT: nNewId = SID_DRAW_TEXT; break;
+ case SVX_SNAP_DRAW_TEXT_VERTICAL: nNewId = SID_DRAW_TEXT_VERTICAL; break;
+ case SVX_SNAP_DRAW_TEXT_MARQUEE: nNewId = SID_DRAW_TEXT_MARQUEE; break;
+ case SVX_SNAP_DRAW_CAPTION: nNewId = SID_DRAW_CAPTION; break;
+ case SVX_SNAP_DRAW_CAPTION_VERTICAL: nNewId = SID_DRAW_CAPTION_VERTICAL; break;
+ }
+ }
+ else // sal_uInt16-Item vom Controller
+ {
+ rReq.Done();
+ return;
+ }
+ }
+
+ if ( nNewId == SID_DRAW_SELECT )
+ nNewId = SID_OBJECT_SELECT;
+
+ sal_uInt16 nNewFormId = 0;
+ if ( nNewId == SID_FM_CREATE_CONTROL && pArgs )
+ {
+ const SfxPoolItem* pItem;
+ if ( pArgs->GetItemState( SID_FM_CONTROL_IDENTIFIER, sal_True, &pItem ) == SFX_ITEM_SET &&
+ pItem->ISA( SfxUInt16Item ) )
+ nNewFormId = ((const SfxUInt16Item*)pItem)->GetValue();
+ }
+
+ String sStringItemValue;
+ if ( pArgs )
+ {
+ const SfxPoolItem* pItem;
+ if ( pArgs->GetItemState( nNewId, sal_True, &pItem ) == SFX_ITEM_SET && pItem->ISA( SfxStringItem ) )
+ sStringItemValue = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ }
+ bool bSwitchCustom = ( sStringItemValue.Len() && sDrawCustom.Len() && sStringItemValue != sDrawCustom );
+
+ if (nNewId == SID_INSERT_FRAME) // vom Tbx-Button
+ nNewId = SID_DRAW_TEXT;
+
+ // #97016# CTRL-SID_OBJECT_SELECT is used to select the first object,
+ // but not if SID_OBJECT_SELECT is the result of clicking a create function again,
+ // so this must be tested before changing nNewId below.
+ sal_Bool bSelectFirst = ( nNewId == SID_OBJECT_SELECT && (rReq.GetModifier() & KEY_MOD1) );
+
+ sal_Bool bEx = IsDrawSelMode();
+ if ( rReq.GetModifier() & KEY_MOD1 )
+ {
+ // #97016# always allow keyboard selection also on background layer
+ // #98185# also allow creation of default objects if the same object type
+ // was already active
+ bEx = sal_True;
+ }
+ else if ( nNewId == nDrawSfxId && ( nNewId != SID_FM_CREATE_CONTROL ||
+ nNewFormId == nFormSfxId || nNewFormId == 0 ) && !bSwitchCustom )
+ {
+ // #i52871# if a different custom shape is selected, the slot id can be the same,
+ // so the custom shape type string has to be compared, too.
+
+ // SID_FM_CREATE_CONTROL mit nNewFormId==0 (ohne Parameter) kommt beim Deaktivieren
+ // aus FuConstruct::SimpleMouseButtonUp
+ // #59280# Execute fuer die Form-Shell, um im Controller zu deselektieren
+ if ( nNewId == SID_FM_CREATE_CONTROL )
+ {
+ GetViewData()->GetDispatcher().Execute(SID_FM_LEAVE_CREATE);
+ GetViewFrame()->GetBindings().InvalidateAll(sal_False);
+ //! was fuer einen Slot braucht der komische Controller wirklich, um das anzuzeigen????
+ }
+
+ bEx = !bEx;
+ nNewId = SID_OBJECT_SELECT;
+ }
+ else
+ bEx = sal_True;
+
+ if ( nDrawSfxId == SID_FM_CREATE_CONTROL && nNewId != nDrawSfxId )
+ {
+ // Wechsel von Control- zu Zeichenfunktion -> im Control-Controller deselektieren
+ GetViewData()->GetDispatcher().Execute(SID_FM_LEAVE_CREATE);
+ GetViewFrame()->GetBindings().InvalidateAll(sal_False);
+ //! was fuer einen Slot braucht der komische Controller wirklich, um das anzuzeigen????
+ }
+
+ SetDrawSelMode(bEx);
+
+ pView->LockBackgroundLayer( !bEx );
+
+ if ( bSelectFirst )
+ {
+ // #97016# select first draw object if none is selected yet
+ if(!pView->AreObjectsMarked())
+ {
+ // select first object
+ pView->UnmarkAllObj();
+ pView->MarkNextObj(sal_True);
+
+ // ...and make it visible
+ if(pView->AreObjectsMarked())
+ pView->MakeVisible(pView->GetAllMarkedRect(), *pWin);
+ }
+ }
+
+ nDrawSfxId = nNewId;
+ sDrawCustom.Erase(); // value is set below for custom shapes
+
+ if ( nNewId != SID_DRAW_CHART ) // Chart nicht mit DrawShell
+ {
+ if ( nNewId == SID_DRAW_TEXT || nNewId == SID_DRAW_TEXT_VERTICAL ||
+ nNewId == SID_DRAW_TEXT_MARQUEE || nNewId == SID_DRAW_NOTEEDIT )
+ SetDrawTextShell( sal_True );
+ else
+ {
+ if ( bEx || pView->GetMarkedObjectList().GetMarkCount() != 0 )
+ SetDrawShellOrSub();
+ else
+ SetDrawShell( sal_False );
+ }
+ }
+
+ if (pTabView->GetDrawFuncPtr())
+ {
+ if (pTabView->GetDrawFuncOldPtr() != pTabView->GetDrawFuncPtr())
+ delete pTabView->GetDrawFuncOldPtr();
+
+ pTabView->GetDrawFuncPtr()->Deactivate();
+ pTabView->SetDrawFuncOldPtr(pTabView->GetDrawFuncPtr());
+ pTabView->SetDrawFuncPtr(NULL);
+ }
+
+ SfxRequest aNewReq(rReq);
+ aNewReq.SetSlot(nDrawSfxId);
+
+ switch (nNewId)
+ {
+ case SID_OBJECT_SELECT:
+ //@#70206# Nicht immer zurueckschalten
+ if(pView->GetMarkedObjectList().GetMarkCount() == 0) SetDrawShell(bEx);
+ pTabView->SetDrawFuncPtr(new FuSelection(this, pWin, pView, pDoc, aNewReq));
+ break;
+
+ case SID_DRAW_LINE:
+ case SID_DRAW_RECT:
+ case SID_DRAW_ELLIPSE:
+ pTabView->SetDrawFuncPtr(new FuConstRectangle(this, pWin, pView, pDoc, aNewReq));
+ break;
+
+ case SID_DRAW_CAPTION:
+ case SID_DRAW_CAPTION_VERTICAL:
+ pTabView->SetDrawFuncPtr(new FuConstRectangle(this, pWin, pView, pDoc, aNewReq));
+ pView->SetFrameDragSingles( sal_False );
+ rBindings.Invalidate( SID_BEZIER_EDIT );
+ break;
+
+ case SID_DRAW_POLYGON:
+ case SID_DRAW_POLYGON_NOFILL:
+ case SID_DRAW_BEZIER_NOFILL:
+ case SID_DRAW_FREELINE_NOFILL:
+ pTabView->SetDrawFuncPtr(new FuConstPolygon(this, pWin, pView, pDoc, aNewReq));
+ break;
+
+ case SID_DRAW_ARC:
+ case SID_DRAW_PIE:
+ case SID_DRAW_CIRCLECUT:
+ pTabView->SetDrawFuncPtr(new FuConstArc(this, pWin, pView, pDoc, aNewReq));
+ break;
+
+ case SID_DRAW_TEXT:
+ case SID_DRAW_TEXT_VERTICAL:
+ case SID_DRAW_TEXT_MARQUEE:
+ case SID_DRAW_NOTEEDIT:
+ pTabView->SetDrawFuncPtr(new FuText(this, pWin, pView, pDoc, aNewReq));
+ break;
+
+ case SID_FM_CREATE_CONTROL:
+ SetDrawFormShell(sal_True);
+ pTabView->SetDrawFuncPtr(new FuConstUnoControl(this, pWin, pView, pDoc, aNewReq));
+ nFormSfxId = nNewFormId;
+ break;
+
+ case SID_DRAW_CHART:
+//UNUSED2008-05 bChartDlgIsEdit = sal_False;
+ pTabView->SetDrawFuncPtr(new FuMarkRect(this, pWin, pView, pDoc, aNewReq));
+ break;
+
+ case SID_DRAWTBX_CS_BASIC :
+ case SID_DRAWTBX_CS_SYMBOL :
+ case SID_DRAWTBX_CS_ARROW :
+ case SID_DRAWTBX_CS_FLOWCHART :
+ case SID_DRAWTBX_CS_CALLOUT :
+ case SID_DRAWTBX_CS_STAR :
+ case SID_DRAW_CS_ID :
+ {
+ pTabView->SetDrawFuncPtr( new FuConstCustomShape( this, pWin, pView, pDoc, aNewReq ));
+ if ( nNewId != SID_DRAW_CS_ID )
+ {
+ SFX_REQUEST_ARG( rReq, pEnumCommand, SfxStringItem, nNewId, sal_False );
+ if ( pEnumCommand )
+ {
+ aCurrShapeEnumCommand[ nNewId - SID_DRAWTBX_CS_BASIC ] = pEnumCommand->GetValue();
+ SfxBindings& rBind = GetViewFrame()->GetBindings();
+ rBind.Invalidate( nNewId );
+ rBind.Update( nNewId );
+
+ sDrawCustom = pEnumCommand->GetValue(); // to detect when a different shape type is selected
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (pTabView->GetDrawFuncPtr())
+ pTabView->GetDrawFuncPtr()->Activate();
+
+ rReq.Done();
+
+ rBindings.Invalidate( SID_INSERT_DRAW );
+ rBindings.Update( SID_INSERT_DRAW );
+
+ // #98185# Create default drawing objects via keyboard
+ // with qualifier construct directly
+ FuPoor* pFuActual = GetDrawFuncPtr();
+
+ if(pFuActual && (rReq.GetModifier() & KEY_MOD1))
+ {
+ // #98185# Create default drawing objects via keyboard
+ const ScAppOptions& rAppOpt = SC_MOD()->GetAppOptions();
+ sal_uInt32 nDefaultObjectSizeWidth = rAppOpt.GetDefaultObjectSizeWidth();
+ sal_uInt32 nDefaultObjectSizeHeight = rAppOpt.GetDefaultObjectSizeHeight();
+
+ // calc position and size
+ Rectangle aVisArea = pWin->PixelToLogic(Rectangle(Point(0,0), pWin->GetOutputSizePixel()));
+ Point aPagePos = aVisArea.Center();
+ aPagePos.X() -= nDefaultObjectSizeWidth / 2;
+ aPagePos.Y() -= nDefaultObjectSizeHeight / 2;
+ Rectangle aNewObjectRectangle(aPagePos, Size(nDefaultObjectSizeWidth, nDefaultObjectSizeHeight));
+
+ ScDrawView* pDrView = GetScDrawView();
+
+ if(pDrView)
+ {
+ SdrPageView* pPageView = pDrView->GetSdrPageView();
+
+ if(pPageView)
+ {
+ // create the default object
+ SdrObject* pObj = pFuActual->CreateDefaultObject(nNewId, aNewObjectRectangle);
+
+ if(pObj)
+ {
+ // insert into page
+ pView->InsertObjectAtView(pObj, *pPageView);
+
+ if ( nNewId == SID_DRAW_CAPTION || nNewId == SID_DRAW_CAPTION_VERTICAL )
+ {
+ // #105815# use KeyInput to start edit mode (FuText is created).
+ // For FuText objects, edit mode is handled within CreateDefaultObject.
+ // KEY_F2 is handled in FuDraw::KeyInput.
+
+ pFuActual->KeyInput( KeyEvent( 0, KeyCode( KEY_F2 ) ) );
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScTabViewShell::GetDrawState(SfxItemSet &rSet)
+{
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case SID_INSERT_DRAW:
+ {
+ // SID_OBJECT_SELECT nur, wenn "harter" Selektionsmodus
+ sal_uInt16 nPutId = nDrawSfxId;
+ if ( nPutId == SID_OBJECT_SELECT && !IsDrawSelMode() )
+ nPutId = USHRT_MAX;
+ // nur die Images, die auch auf dem Controller liegen
+ if ( nPutId != SID_OBJECT_SELECT &&
+ nPutId != SID_DRAW_LINE &&
+ nPutId != SID_DRAW_RECT &&
+ nPutId != SID_DRAW_ELLIPSE &&
+ nPutId != SID_DRAW_POLYGON_NOFILL &&
+ nPutId != SID_DRAW_BEZIER_NOFILL &&
+ nPutId != SID_DRAW_FREELINE_NOFILL &&
+ nPutId != SID_DRAW_ARC &&
+ nPutId != SID_DRAW_PIE &&
+ nPutId != SID_DRAW_CIRCLECUT &&
+ nPutId != SID_DRAW_TEXT &&
+ nPutId != SID_DRAW_TEXT_VERTICAL &&
+ nPutId != SID_DRAW_TEXT_MARQUEE &&
+ nPutId != SID_DRAW_CAPTION &&
+ nPutId != SID_DRAW_CAPTION_VERTICAL )
+ nPutId = USHRT_MAX;
+ SfxAllEnumItem aItem( nWhich, nPutId );
+ if ( !SvtLanguageOptions().IsVerticalTextEnabled() )
+ {
+ aItem.DisableValue( SID_DRAW_TEXT_VERTICAL );
+ aItem.DisableValue( SID_DRAW_CAPTION_VERTICAL );
+ }
+ rSet.Put( aItem );
+ }
+ break;
+
+ case SID_DRAW_CHART:
+ {
+ sal_Bool bOle = GetViewFrame()->GetFrame().IsInPlace();
+ if ( bOle || !SvtModuleOptions().IsChart() )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_OBJECT_SELECT: // wichtig fuer den ollen Control-Controller
+ rSet.Put( SfxBoolItem( nWhich, nDrawSfxId == SID_OBJECT_SELECT && IsDrawSelMode() ) );
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+sal_Bool ScTabViewShell::SelectObject( const String& rName )
+{
+ ScDrawView* pView = GetViewData()->GetScDrawView();
+ if (!pView)
+ return sal_False;
+
+ sal_Bool bFound = pView->SelectObject( rName );
+ // DrawShell etc. is handled in MarkListHasChanged
+
+ return bFound;
+}
+
+
+
diff --git a/sc/source/ui/view/tabvwsh3.cxx b/sc/source/ui/view/tabvwsh3.cxx
new file mode 100644
index 000000000000..79f63f873916
--- /dev/null
+++ b/sc/source/ui/view/tabvwsh3.cxx
@@ -0,0 +1,1234 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/app.hxx>
+//CHINA001 #include <svx/zoom.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/passwd.hxx>
+#include <sfx2/request.hxx>
+#include <svl/ptitem.hxx>
+#include <svl/stritem.hxx>
+#include <tools/urlobj.hxx>
+#include <sfx2/objface.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/vclenum.hxx>
+
+#include "globstr.hrc"
+#include "scmod.hxx"
+#include "appoptio.hxx"
+#include "tabvwsh.hxx"
+#include "document.hxx"
+#include "sc.hrc"
+#include "inputwin.hxx"
+#include "scresid.hxx"
+#include "printfun.hxx"
+#include "docsh.hxx"
+#include "rangelst.hxx"
+#include "prevwsh.hxx"
+#include "rangeutl.hxx"
+#include "reffact.hxx"
+#include "uiitems.hxx"
+#include "cell.hxx"
+#include "inputhdl.hxx"
+//CHINA001 #include "scendlg.hxx"
+//CHINA001 #include "mtrindlg.hxx"
+#include "autoform.hxx"
+#include "autofmt.hxx"
+#include "dwfunctr.hxx"
+#include "shtabdlg.hxx"
+#include "tabprotection.hxx"
+#include "protectiondlg.hxx"
+
+#include <svl/ilstitem.hxx>
+#define _SVSTDARR_ULONGS
+#include <svl/svstdarr.hxx>
+
+#include <svx/zoomslideritem.hxx>
+#include <svx/svxdlg.hxx> //CHINA001
+#include <svx/dialogs.hrc> //CHINA001
+#include "scabstdlg.hxx" //CHINA001
+
+#include <memory>
+
+using ::std::auto_ptr;
+
+#define IS_EDITMODE() GetViewData()->HasEditView( GetViewData()->GetActivePart() )
+#define IS_AVAILABLE(WhichId,ppItem) \
+ (pReqArgs->GetItemState((WhichId), sal_True, ppItem ) == SFX_ITEM_SET)
+#define GET_STRING(nid) ((const SfxStringItem&)pReqArgs->Get(nid)).GetValue()
+#define GET_UINT16(nid) ((const SfxUInt16Item&)pReqArgs->Get(nid)).GetValue()
+#define GET_BOOL(nid) ((const SfxBoolItem&)pReqArgs->Get(nid)).GetValue()
+#define RECALC_PAGE(pDocSh) ScPrintFunc( pDocSh, GetPrinter(), nCurTab ).UpdatePages()
+
+//------------------------------------------------------------------
+
+/** Try to parse the given range using Calc-style syntax first, then
+ Excel-style if that fails. */
+sal_uInt16 lcl_ParseRange(ScRange& rScRange, const String& aAddress, ScDocument* pDoc, sal_uInt16 /* nSlot */)
+{
+ sal_uInt16 nResult = rScRange.Parse(aAddress, pDoc);
+ if ( (nResult & SCA_VALID) )
+ return nResult;
+
+ return rScRange.Parse(aAddress, pDoc, ScAddress::Details(formula::FormulaGrammar::CONV_XL_A1, 0, 0));
+}
+
+/** Try to parse the given address using Calc-style syntax first, then
+ Excel-style if that fails. */
+sal_uInt16 lcl_ParseAddress(ScAddress& rScAddress, const String& aAddress, ScDocument* pDoc, sal_uInt16 /* nSlot */)
+{
+ sal_uInt16 nResult = rScAddress.Parse(aAddress, pDoc);
+ if ( (nResult & SCA_VALID) )
+ return nResult;
+
+ return rScAddress.Parse(aAddress, pDoc, ScAddress::Details(formula::FormulaGrammar::CONV_XL_A1, 0, 0));
+}
+
+void ScTabViewShell::Execute( SfxRequest& rReq )
+{
+ SfxViewFrame* pThisFrame = GetViewFrame();
+ SfxBindings& rBindings = pThisFrame->GetBindings();
+ ScModule* pScMod = SC_MOD();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ sal_uInt16 nSlot = rReq.GetSlot();
+
+ if (nSlot != SID_CURRENTCELL) // der kommt beim MouseButtonUp
+ HideListBox(); // Autofilter-DropDown-Listbox
+
+ switch ( nSlot )
+ {
+ case FID_INSERT_FILE:
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs &&
+ pReqArgs->GetItemState(FID_INSERT_FILE,sal_True,&pItem) == SFX_ITEM_SET )
+ {
+ String aFileName = ((const SfxStringItem*)pItem)->GetValue();
+
+ // Einfuege-Position
+
+ Point aInsertPos;
+ if ( pReqArgs->GetItemState(FN_PARAM_1,sal_True,&pItem) == SFX_ITEM_SET )
+ aInsertPos = ((const SfxPointItem*)pItem)->GetValue();
+ else
+ aInsertPos = GetInsertPos();
+
+ // als Link?
+
+ sal_Bool bAsLink = sal_False;
+ if ( pReqArgs->GetItemState(FN_PARAM_2,sal_True,&pItem) == SFX_ITEM_SET )
+ bAsLink = ((const SfxBoolItem*)pItem)->GetValue();
+
+ // ausfuehren
+
+ PasteFile( aInsertPos, aFileName, bAsLink );
+ }
+ }
+ break;
+
+ case SID_OPENDLG_EDIT_PRINTAREA:
+ {
+ sal_uInt16 nId = ScPrintAreasDlgWrapper::GetChildWindowId();
+ SfxChildWindow* pWnd = pThisFrame->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? sal_False : sal_True );
+ }
+ break;
+
+ case SID_CHANGE_PRINTAREA:
+ {
+ if ( pReqArgs ) // OK aus Dialog
+ {
+ String aPrintStr;
+ String aRowStr;
+ String aColStr;
+ sal_Bool bEntire = sal_False;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( SID_CHANGE_PRINTAREA, sal_True, &pItem ) == SFX_ITEM_SET )
+ aPrintStr = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ if ( pReqArgs->GetItemState( FN_PARAM_2, sal_True, &pItem ) == SFX_ITEM_SET )
+ aRowStr = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ if ( pReqArgs->GetItemState( FN_PARAM_3, sal_True, &pItem ) == SFX_ITEM_SET )
+ aColStr = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ if ( pReqArgs->GetItemState( FN_PARAM_4, sal_True, &pItem ) == SFX_ITEM_SET )
+ bEntire = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+
+ SetPrintRanges( bEntire, &aPrintStr, &aColStr, &aRowStr, sal_False );
+
+ rReq.Done();
+ }
+ }
+ break;
+
+ case SID_ADD_PRINTAREA:
+ case SID_DEFINE_PRINTAREA: // Menue oder Basic
+ {
+ sal_Bool bAdd = ( nSlot == SID_ADD_PRINTAREA );
+ if ( pReqArgs )
+ {
+ String aPrintStr;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( SID_DEFINE_PRINTAREA, sal_True, &pItem ) == SFX_ITEM_SET )
+ aPrintStr = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ SetPrintRanges( sal_False, &aPrintStr, NULL, NULL, bAdd );
+ }
+ else
+ {
+ SetPrintRanges( sal_False, NULL, NULL, NULL, bAdd ); // aus Selektion
+ rReq.Done();
+ }
+ }
+ break;
+
+ case SID_DELETE_PRINTAREA:
+ {
+ String aEmpty;
+ SetPrintRanges( sal_False, &aEmpty, NULL, NULL, sal_False ); // Druckbereich loeschen
+ rReq.Done();
+ }
+ break;
+
+ case FID_DEL_MANUALBREAKS:
+ RemoveManualBreaks();
+ rReq.Done();
+ break;
+
+ case FID_ADJUST_PRINTZOOM:
+ AdjustPrintZoom();
+ rReq.Done();
+ break;
+
+ case FID_RESET_PRINTZOOM:
+ SetPrintZoom( 100, 0 ); // 100%, nicht auf Seiten
+ rReq.Done();
+ break;
+
+ case SID_FORMATPAGE:
+ case SID_STATUS_PAGESTYLE:
+ case SID_HFEDIT:
+ GetViewData()->GetDocShell()->
+ ExecutePageStyle( *this, rReq, GetViewData()->GetTabNo() );
+ break;
+
+ case SID_JUMPTOMARK:
+ case SID_CURRENTCELL:
+ if ( pReqArgs )
+ {
+ String aAddress;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( nSlot, sal_True, &pItem ) == SFX_ITEM_SET )
+ aAddress = ((const SfxStringItem*)pItem)->GetValue();
+ else if ( nSlot == SID_JUMPTOMARK && pReqArgs->GetItemState(
+ SID_JUMPTOMARK, sal_True, &pItem ) == SFX_ITEM_SET )
+ aAddress = ((const SfxStringItem*)pItem)->GetValue();
+
+ // #i14927# SID_CURRENTCELL with a single cell must unmark if FN_PARAM_1
+ // isn't set (for recorded macros, because IsAPI is no longer available).
+ // ScGridWindow::MouseButtonUp no longer executes the slot for a single
+ // cell if there is a multi selection.
+ sal_Bool bUnmark = ( nSlot == SID_CURRENTCELL );
+ if ( pReqArgs->GetItemState( FN_PARAM_1, sal_True, &pItem ) == SFX_ITEM_SET )
+ bUnmark = ((const SfxBoolItem*)pItem)->GetValue();
+
+ if ( nSlot == SID_JUMPTOMARK )
+ {
+ // #106586# URL has to be decoded for escaped characters (%20)
+ aAddress = INetURLObject::decode( aAddress, INET_HEX_ESCAPE,
+ INetURLObject::DECODE_WITH_CHARSET,
+ RTL_TEXTENCODING_UTF8 );
+ }
+
+ sal_Bool bFound = sal_False;
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScMarkData& rMark = pViewData->GetMarkData();
+ ScRange aScRange;
+ ScAddress aScAddress;
+ sal_uInt16 nResult = lcl_ParseRange(aScRange, aAddress, pDoc, nSlot);
+ SCTAB nTab = pViewData->GetTabNo();
+ sal_Bool bMark = sal_True;
+
+ // Is this a range ?
+ if( nResult & SCA_VALID )
+ {
+ if ( nResult & SCA_TAB_3D )
+ {
+ if( aScRange.aStart.Tab() != nTab )
+ SetTabNo( nTab = aScRange.aStart.Tab() );
+ }
+ else
+ {
+ aScRange.aStart.SetTab( nTab );
+ aScRange.aEnd.SetTab( nTab );
+ }
+ }
+ // Is this a cell ?
+ else if ( (nResult = lcl_ParseAddress(aScAddress, aAddress, pDoc, nSlot)) & SCA_VALID )
+ {
+ if ( nResult & SCA_TAB_3D )
+ {
+ if( aScAddress.Tab() != nTab )
+ SetTabNo( nTab = aScAddress.Tab() );
+ }
+ else
+ aScAddress.SetTab( nTab );
+
+ aScRange = ScRange( aScAddress, aScAddress );
+ // Zellen sollen nicht markiert werden
+ bMark = sal_False;
+ }
+ // Ist es benahmster Bereich (erst Namen dann DBBereiche) ?
+ else
+ {
+ ScRangeUtil aRangeUtil;
+ formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
+ if( aRangeUtil.MakeRangeFromName( aAddress, pDoc, nTab, aScRange, RUTL_NAMES, eConv ) ||
+ aRangeUtil.MakeRangeFromName( aAddress, pDoc, nTab, aScRange, RUTL_DBASE, eConv ) )
+ {
+ nResult |= SCA_VALID;
+ if( aScRange.aStart.Tab() != nTab )
+ SetTabNo( nTab = aScRange.aStart.Tab() );
+ }
+ }
+
+ if ( !(nResult & SCA_VALID) &&
+ ByteString(aAddress, RTL_TEXTENCODING_ASCII_US).IsNumericAscii() )
+ {
+ sal_Int32 nNumeric = aAddress.ToInt32();
+ if ( nNumeric > 0 && nNumeric <= MAXROW+1 )
+ {
+ // 1-basierte Zeilennummer
+
+ aScAddress.SetRow( (SCROW)(nNumeric - 1) );
+ aScAddress.SetCol( pViewData->GetCurX() );
+ aScAddress.SetTab( nTab );
+ aScRange = ScRange( aScAddress, aScAddress );
+ bMark = sal_False;
+ nResult = SCA_VALID;
+ }
+ }
+
+ if ( !ValidRow(aScRange.aStart.Row()) || !ValidRow(aScRange.aEnd.Row()) )
+ nResult = 0;
+
+ // wir haben was gefunden
+ if( nResult & SCA_VALID )
+ {
+ bFound = sal_True;
+ SCCOL nCol = aScRange.aStart.Col();
+ SCROW nRow = aScRange.aStart.Row();
+ sal_Bool bNothing = ( pViewData->GetCurX()==nCol && pViewData->GetCurY()==nRow );
+
+ // markieren
+ if( bMark )
+ {
+ if (rMark.IsMarked()) // ist derselbe Bereich schon markiert?
+ {
+ ScRange aOldMark;
+ rMark.GetMarkArea( aOldMark );
+ aOldMark.Justify();
+ ScRange aCurrent = aScRange;
+ aCurrent.Justify();
+ bNothing = ( aCurrent == aOldMark );
+ }
+ else
+ bNothing = sal_False;
+
+ if (!bNothing)
+ MarkRange( aScRange, sal_False ); // Cursor kommt hinterher...
+ }
+ else
+ {
+ // remove old selection, unless bUnmark argument is sal_False (from navigator)
+ if( bUnmark )
+ {
+ MoveCursorAbs( nCol, nRow,
+ SC_FOLLOW_NONE, sal_False, sal_False );
+ }
+ }
+
+ // und Cursor setzen
+
+ // zusammengefasste Zellen beruecksichtigen:
+ while ( pDoc->IsHorOverlapped( nCol, nRow, nTab ) ) //! ViewData !!!
+ --nCol;
+ while ( pDoc->IsVerOverlapped( nCol, nRow, nTab ) )
+ --nRow;
+
+ // Navigator-Aufrufe sind nicht API!!!
+
+ if( bNothing )
+ {
+ if (rReq.IsAPI())
+ rReq.Ignore(); // wenn Makro, dann gar nix
+ else
+ rReq.Done(); // sonst wenigstens aufzeichnen
+ }
+ else
+ {
+ pViewData->ResetOldCursor();
+ SetCursor( nCol, nRow );
+ AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
+ rBindings.Invalidate( SID_CURRENTCELL );
+ rBindings.Update( nSlot );
+
+ if (!rReq.IsAPI())
+ rReq.Done();
+ }
+
+ rReq.SetReturnValue( SfxStringItem( SID_CURRENTCELL, aAddress ) );
+ }
+
+ if (!bFound) // kein gueltiger Bereich
+ {
+ // wenn es ein Tabellenname ist, umschalten (fuer Navigator/URL's)
+
+ SCTAB nNameTab;
+ if ( pDoc->GetTable( aAddress, nNameTab ) )
+ {
+ bFound = sal_True;
+ if ( nNameTab != nTab )
+ SetTabNo( nNameTab );
+ }
+ }
+
+ if ( !bFound && nSlot == SID_JUMPTOMARK )
+ {
+ // Grafik-Objekte probieren (nur bei URL's)
+
+ bFound = SelectObject( aAddress );
+ }
+
+ if (!bFound && !rReq.IsAPI())
+ ErrorMessage( STR_ERR_INVALID_AREA );
+ }
+ break;
+
+ case SID_CURRENTOBJECT:
+ if ( pReqArgs )
+ {
+ String aName = ((const SfxStringItem&)pReqArgs->Get(nSlot)).GetValue();
+ SelectObject( aName );
+ }
+ break;
+
+ case SID_CURRENTTAB:
+ if ( pReqArgs )
+ {
+ // Tabelle fuer Basic ist 1-basiert
+ SCTAB nTab = ((const SfxUInt16Item&)pReqArgs->Get(nSlot)).GetValue() - 1;
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if ( nTab < pDoc->GetTableCount() )
+ {
+ SetTabNo( nTab );
+ rBindings.Update( nSlot );
+
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ //! sonst Fehler ?
+ }
+ break;
+
+ case SID_CURRENTDOC:
+ if ( pReqArgs )
+ {
+ String aStrDocName( ((const SfxStringItem&)pReqArgs->
+ Get(nSlot)).GetValue() );
+
+ SfxViewFrame* pViewFrame = NULL;
+ ScDocShell* pDocSh = (ScDocShell*)SfxObjectShell::GetFirst();
+ sal_Bool bFound = sal_False;
+
+ // zu aktivierenden ViewFrame suchen
+
+ while ( pDocSh && !bFound )
+ {
+ if ( pDocSh->GetTitle() == aStrDocName )
+ {
+ pViewFrame = SfxViewFrame::GetFirst( pDocSh );
+ bFound = ( NULL != pViewFrame );
+ }
+
+ pDocSh = (ScDocShell*)SfxObjectShell::GetNext( *pDocSh );
+ }
+
+ if ( bFound )
+ pViewFrame->GetFrame().Appear();
+
+ rReq.Ignore();//XXX wird von SFX erledigt
+ }
+
+ case SID_ATTR_SIZE://XXX ???
+ break;
+
+
+ case SID_PRINTPREVIEW:
+ {
+ if ( !pThisFrame->GetFrame().IsInPlace() ) // nicht bei OLE
+ {
+ // print preview is now always in the same frame as the tab view
+ // -> always switch this frame back to normal view
+ // (ScPreviewShell ctor reads view data)
+
+ // #102785#; finish input
+ pScMod->InputEnterHandler();
+
+ pThisFrame->GetDispatcher()->Execute( SID_VIEWSHELL1, SFX_CALLMODE_ASYNCHRON );
+ }
+ // else Fehler (z.B. Ole)
+ }
+ break;
+
+ case SID_DETECTIVE_DEL_ALL:
+ DetectiveDelAll();
+ rReq.Done();
+ break;
+
+ // SID_TABLE_ACTIVATE und SID_MARKAREA werden von Basic aus an der versteckten
+ // View aufgerufen, um auf der sichtbaren View zu markieren/umzuschalten:
+
+ case SID_TABLE_ACTIVATE:
+ DBG_ERROR("old slot SID_TABLE_ACTIVATE");
+ break;
+
+ case SID_REPAINT:
+ PaintGrid();
+ PaintTop();
+ PaintLeft();
+ PaintExtras();
+ rReq.Done();
+ break;
+
+ case FID_NORMALVIEWMODE:
+ case FID_PAGEBREAKMODE:
+ {
+ sal_Bool bWantPageBreak = nSlot == FID_PAGEBREAKMODE;
+
+ // check whether there is an explicit argument, use it
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && pReqArgs->GetItemState(nSlot, sal_True, &pItem) == SFX_ITEM_SET )
+ {
+ sal_Bool bItemValue = ((const SfxBoolItem*)pItem)->GetValue();
+ bWantPageBreak = (nSlot == FID_PAGEBREAKMODE) == bItemValue;
+ }
+
+ if( GetViewData()->IsPagebreakMode() != bWantPageBreak )
+ {
+ SetPagebreakMode( bWantPageBreak );
+ UpdatePageBreakData();
+ SetCurSubShell( GetCurObjectSelectionType(), sal_True );
+ PaintGrid();
+ PaintTop();
+ PaintLeft();
+ rBindings.Invalidate( nSlot );
+ rReq.AppendItem( SfxBoolItem( nSlot, sal_True ) );
+ rReq.Done();
+ }
+ }
+ break;
+
+ case FID_FUNCTION_BOX:
+ {
+ sal_uInt16 nChildId = ScFunctionChildWindow::GetChildWindowId();
+ if ( rReq.GetArgs() )
+ pThisFrame->SetChildWindow( nChildId, ((const SfxBoolItem&) (rReq.GetArgs()->Get(FID_FUNCTION_BOX))).GetValue());
+ else
+ {
+ pThisFrame->ToggleChildWindow( nChildId );
+ rReq.AppendItem( SfxBoolItem( FID_FUNCTION_BOX , pThisFrame->HasChildWindow( nChildId ) ) );
+ }
+
+ GetViewFrame()->GetBindings().Invalidate(FID_FUNCTION_BOX);
+ rReq.Done ();
+ }
+ break;
+
+
+ case FID_TOGGLESYNTAX:
+ {
+ sal_Bool bSet = !GetViewData()->IsSyntaxMode();
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && pReqArgs->GetItemState(nSlot, sal_True, &pItem) == SFX_ITEM_SET )
+ bSet = ((const SfxBoolItem*)pItem)->GetValue();
+ GetViewData()->SetSyntaxMode( bSet );
+ PaintGrid();
+ rBindings.Invalidate( FID_TOGGLESYNTAX );
+ rReq.AppendItem( SfxBoolItem( nSlot, bSet ) );
+ rReq.Done();
+ }
+ break;
+ case FID_TOGGLEHEADERS:
+ {
+ sal_Bool bSet = !GetViewData()->IsHeaderMode();
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && pReqArgs->GetItemState(nSlot, sal_True, &pItem) == SFX_ITEM_SET )
+ bSet = ((const SfxBoolItem*)pItem)->GetValue();
+ GetViewData()->SetHeaderMode( bSet );
+ RepeatResize();
+ rBindings.Invalidate( FID_TOGGLEHEADERS );
+ rReq.AppendItem( SfxBoolItem( nSlot, bSet ) );
+ rReq.Done();
+ }
+ break;
+
+ case FID_TOGGLEFORMULA:
+ {
+ ScViewData* pViewData = GetViewData();
+ const ScViewOptions& rOpts = pViewData->GetOptions();
+ sal_Bool bFormulaMode = !rOpts.GetOption( VOPT_FORMULAS );
+ const SfxPoolItem *pItem;
+ if( pReqArgs && pReqArgs->GetItemState(nSlot, sal_True, &pItem) == SFX_ITEM_SET )
+ bFormulaMode = ((const SfxBoolItem *)pItem)->GetValue();
+
+ ScViewOptions rSetOpts = ScViewOptions( rOpts );
+ rSetOpts.SetOption( VOPT_FORMULAS, bFormulaMode );
+ pViewData->SetOptions( rSetOpts );
+
+ pViewData->GetDocShell()->PostPaintGridAll();
+
+ rBindings.Invalidate( FID_TOGGLEFORMULA );
+ rReq.AppendItem( SfxBoolItem( nSlot, bFormulaMode ) );
+ rReq.Done();
+ }
+ break;
+
+ case FID_TOGGLEINPUTLINE:
+ {
+ sal_uInt16 nId = ScInputWindowWrapper::GetChildWindowId();
+ SfxChildWindow* pWnd = pThisFrame->GetChildWindow( nId );
+ sal_Bool bSet = ( pWnd == NULL );
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && pReqArgs->GetItemState(nSlot, sal_True, &pItem) == SFX_ITEM_SET )
+ bSet = ((const SfxBoolItem*)pItem)->GetValue();
+
+ pThisFrame->SetChildWindow( nId, bSet );
+ rBindings.Invalidate( FID_TOGGLEINPUTLINE );
+ rReq.AppendItem( SfxBoolItem( nSlot, bSet ) );
+ rReq.Done();
+ }
+ break;
+
+ case SID_ATTR_ZOOM: // Statuszeile
+ case FID_SCALE:
+ {
+ sal_Bool bSyncZoom = SC_MOD()->GetAppOptions().GetSynchronizeZoom();
+ SvxZoomType eOldZoomType = GetZoomType();
+ SvxZoomType eNewZoomType = eOldZoomType;
+ const Fraction& rOldY = GetViewData()->GetZoomY(); // Y wird angezeigt
+ sal_uInt16 nOldZoom = (sal_uInt16)(( rOldY.GetNumerator() * 100 )
+ / rOldY.GetDenominator());
+ sal_uInt16 nZoom = nOldZoom;
+ sal_Bool bCancel = sal_False;
+
+ if ( pReqArgs )
+ {
+ const SvxZoomItem& rZoomItem = (const SvxZoomItem&)
+ pReqArgs->Get(SID_ATTR_ZOOM);
+
+ eNewZoomType = rZoomItem.GetType();
+ nZoom = rZoomItem.GetValue();
+ }
+ else
+ {
+ SfxItemSet aSet ( GetPool(), SID_ATTR_ZOOM, SID_ATTR_ZOOM );
+ SvxZoomItem aZoomItem( eOldZoomType, nOldZoom, SID_ATTR_ZOOM );
+ //CHINA001 SvxZoomDialog* pDlg = NULL;
+ AbstractSvxZoomDialog* pDlg = NULL;
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ sal_uInt16 nBtnFlags = SVX_ZOOM_ENABLE_50
+ | SVX_ZOOM_ENABLE_75
+ | SVX_ZOOM_ENABLE_100
+ | SVX_ZOOM_ENABLE_150
+ | SVX_ZOOM_ENABLE_200
+ | SVX_ZOOM_ENABLE_WHOLEPAGE
+ | SVX_ZOOM_ENABLE_PAGEWIDTH;
+
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ nBtnFlags = nBtnFlags | SVX_ZOOM_ENABLE_OPTIMAL;
+
+ aZoomItem.SetValueSet( nBtnFlags );
+ aSet.Put( aZoomItem );
+ //CHINA001 pDlg = new SvxZoomDialog( GetDialogParent(), aSet );
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ if(pFact)
+ {
+ pDlg = pFact->CreateSvxZoomDialog(GetDialogParent(), aSet );
+ DBG_ASSERT(pDlg, "Dialogdiet fail!");//CHINA001
+ }
+ pDlg->SetLimits( MINZOOM, MAXZOOM );
+
+ bCancel = ( RET_CANCEL == pDlg->Execute() );
+
+ if ( !bCancel )
+ {
+ const SvxZoomItem& rZoomItem = (const SvxZoomItem&)
+ pDlg->GetOutputItemSet()->
+ Get( SID_ATTR_ZOOM );
+
+ eNewZoomType = rZoomItem.GetType();
+ nZoom = rZoomItem.GetValue();
+ }
+
+ delete pDlg;
+ }
+
+ if ( !bCancel )
+ {
+ if ( eNewZoomType == SVX_ZOOM_PERCENT )
+ {
+ if ( nZoom < MINZOOM ) nZoom = MINZOOM;
+ if ( nZoom > MAXZOOM ) nZoom = MAXZOOM;
+ }
+ else
+ {
+ nZoom = CalcZoom( eNewZoomType, nOldZoom );
+ bCancel = nZoom == 0;
+ }
+
+ switch ( eNewZoomType )
+ {
+ case SVX_ZOOM_WHOLEPAGE:
+ case SVX_ZOOM_PAGEWIDTH:
+ SetZoomType( eNewZoomType, bSyncZoom );
+ break;
+
+ default:
+ SetZoomType( SVX_ZOOM_PERCENT, bSyncZoom );
+ }
+ }
+
+ if ( nZoom != nOldZoom && !bCancel )
+ {
+ if (!GetViewData()->IsPagebreakMode())
+ {
+ ScAppOptions aNewOpt = pScMod->GetAppOptions();
+ aNewOpt.SetZoom( nZoom );
+ aNewOpt.SetZoomType( GetZoomType() );
+ pScMod->SetAppOptions( aNewOpt );
+ }
+ Fraction aFract( nZoom, 100 );
+ SetZoom( aFract, aFract, bSyncZoom );
+ PaintGrid();
+ PaintTop();
+ PaintLeft();
+ rBindings.Invalidate( SID_ATTR_ZOOM );
+ rReq.AppendItem( SvxZoomItem( GetZoomType(), nZoom, nSlot ) );
+ rReq.Done();
+ }
+ }
+ break;
+
+ case SID_ATTR_ZOOMSLIDER:
+ {
+ const SfxPoolItem* pItem = NULL;
+ sal_Bool bSyncZoom = SC_MOD()->GetAppOptions().GetSynchronizeZoom();
+ if ( pReqArgs && pReqArgs->GetItemState(SID_ATTR_ZOOMSLIDER, sal_True, &pItem) == SFX_ITEM_SET )
+ {
+ const sal_uInt16 nCurrentZoom = ((const SvxZoomSliderItem *)pItem)->GetValue();
+ if( nCurrentZoom )
+ {
+ SetZoomType( SVX_ZOOM_PERCENT, bSyncZoom );
+ if (!GetViewData()->IsPagebreakMode())
+ {
+ ScAppOptions aNewOpt = pScMod->GetAppOptions();
+ aNewOpt.SetZoom( nCurrentZoom );
+ aNewOpt.SetZoomType( GetZoomType() );
+ pScMod->SetAppOptions( aNewOpt );
+ }
+ Fraction aFract( nCurrentZoom,100 );
+ SetZoom( aFract, aFract, bSyncZoom );
+ PaintGrid();
+ PaintTop();
+ PaintLeft();
+ rBindings.Invalidate( SID_ATTR_ZOOMSLIDER );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+
+ //----------------------------------------------------------------
+
+ case FID_TAB_SELECTALL:
+ SelectAllTables();
+ rReq.Done();
+ break;
+
+ case FID_TAB_DESELECTALL:
+ DeselectAllTables();
+ rReq.Done();
+ break;
+
+ case SID_SELECT_TABLES:
+ {
+ ScViewData& rViewData = *GetViewData();
+ ScDocument& rDoc = *rViewData.GetDocument();
+ ScMarkData& rMark = rViewData.GetMarkData();
+ SCTAB nTabCount = rDoc.GetTableCount();
+ SCTAB nTab;
+
+ SvULongs aIndexList( 4, 4 );
+ SFX_REQUEST_ARG( rReq, pItem, SfxIntegerListItem, SID_SELECT_TABLES, sal_False );
+ if ( pItem )
+ pItem->GetList( aIndexList );
+ else
+ {
+ //CHINA001 ScShowTabDlg* pDlg = new ScShowTabDlg( GetDialogParent() );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScShowTabDlg* pDlg = pFact->CreateScShowTabDlg( GetDialogParent(), RID_SCDLG_SHOW_TAB);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ pDlg->SetDescription(
+ String( ScResId( STR_DLG_SELECTTABLES_TITLE ) ),
+ String( ScResId( STR_DLG_SELECTTABLES_LBNAME ) ),
+ GetStaticInterface()->GetSlot(SID_SELECT_TABLES)->GetCommand(), HID_SELECTTABLES );
+
+ // fill all table names with selection state
+ String aTabName;
+ for( nTab = 0; nTab < nTabCount; ++nTab )
+ {
+ rDoc.GetName( nTab, aTabName );
+ pDlg->Insert( aTabName, rMark.GetTableSelect( nTab ) );
+ }
+
+ if( pDlg->Execute() == RET_OK )
+ {
+ sal_uInt16 nSelCount = pDlg->GetSelectEntryCount();
+ sal_uInt16 nSelIx;
+ for( nSelIx = 0; nSelIx < nSelCount; ++nSelIx )
+ aIndexList.Insert( pDlg->GetSelectEntryPos( nSelIx ), nSelIx );
+ delete pDlg;
+ rReq.AppendItem( SfxIntegerListItem( SID_SELECT_TABLES, aIndexList ) );
+ }
+ else
+ rReq.Ignore();
+ }
+
+ if ( aIndexList.Count() )
+ {
+ sal_uInt16 nSelCount = aIndexList.Count();
+ sal_uInt16 nSelIx;
+ SCTAB nFirstVisTab = 0;
+
+ // special case: only hidden tables selected -> do nothing
+ sal_Bool bVisSelected = sal_False;
+ for( nSelIx = 0; !bVisSelected && (nSelIx < nSelCount); ++nSelIx )
+ bVisSelected = rDoc.IsVisible( nFirstVisTab = static_cast<SCTAB>(aIndexList[nSelIx]) );
+ if( !bVisSelected )
+ nSelCount = 0;
+
+ // select the tables
+ if( nSelCount )
+ {
+ for( nTab = 0; nTab < nTabCount; ++nTab )
+ rMark.SelectTable( nTab, sal_False );
+
+ for( nSelIx = 0; nSelIx < nSelCount; ++nSelIx )
+ rMark.SelectTable( static_cast<SCTAB>(aIndexList[nSelIx]), sal_True );
+
+ // activate another table, if current is deselected
+ if( !rMark.GetTableSelect( rViewData.GetTabNo() ) )
+ {
+ rMark.SelectTable( nFirstVisTab, sal_True );
+ SetTabNo( nFirstVisTab );
+ }
+
+ rViewData.GetDocShell()->PostPaintExtras();
+ SfxBindings& rBind = rViewData.GetBindings();
+ rBind.Invalidate( FID_FILL_TAB );
+ rBind.Invalidate( FID_TAB_DESELECTALL );
+ }
+
+ rReq.Done();
+ }
+ }
+ break;
+
+
+ case SID_OUTLINE_DELETEALL:
+ RemoveAllOutlines();
+ rReq.Done();
+ break;
+
+ case SID_AUTO_OUTLINE:
+ AutoOutline();
+ rReq.Done();
+ break;
+
+
+ case SID_WINDOW_SPLIT:
+ {
+ ScSplitMode eHSplit = GetViewData()->GetHSplitMode();
+ ScSplitMode eVSplit = GetViewData()->GetVSplitMode();
+ if ( eHSplit == SC_SPLIT_NORMAL || eVSplit == SC_SPLIT_NORMAL ) // aufheben
+ RemoveSplit();
+ else if ( eHSplit == SC_SPLIT_FIX || eVSplit == SC_SPLIT_FIX ) // normal
+ FreezeSplitters( sal_False );
+ else // erzeugen
+ SplitAtCursor();
+ rReq.Done();
+
+ InvalidateSplit();
+ }
+ break;
+
+ case SID_WINDOW_FIX:
+ {
+ ScSplitMode eHSplit = GetViewData()->GetHSplitMode();
+ ScSplitMode eVSplit = GetViewData()->GetVSplitMode();
+ if ( eHSplit == SC_SPLIT_FIX || eVSplit == SC_SPLIT_FIX ) // aufheben
+ RemoveSplit();
+ else
+ FreezeSplitters( sal_True ); // erzeugen oder fixieren
+ rReq.Done();
+
+ InvalidateSplit();
+ }
+ break;
+
+ // ----------------------------------------------------------------
+
+ case FID_CHG_SHOW:
+ {
+ sal_uInt16 nId = ScHighlightChgDlgWrapper::GetChildWindowId();
+ SfxChildWindow* pWnd = pThisFrame->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? sal_False : sal_True );
+ }
+ break;
+
+ case FID_CHG_ACCEPT:
+ {
+ pThisFrame->ToggleChildWindow(ScAcceptChgDlgWrapper::GetChildWindowId());
+ GetViewFrame()->GetBindings().Invalidate(FID_CHG_ACCEPT);
+ rReq.Done ();
+
+ /*
+ sal_uInt16 nId = ScAcceptChgDlgWrapper::GetChildWindowId();
+ SfxChildWindow* pWnd = pThisFrame->GetChildWindow( nId );
+
+ pScMod->SetRefDialog( nId, pWnd ? sal_False : sal_True );
+ */
+ }
+ break;
+
+ case FID_CHG_COMMENT:
+ {
+ ScViewData* pData = GetViewData();
+ ScAddress aCursorPos( pData->GetCurX(), pData->GetCurY(), pData->GetTabNo() );
+ ScDocShell* pDocSh = pData->GetDocShell();
+
+ ScChangeAction* pAction = pDocSh->GetChangeAction( aCursorPos );
+ if ( pAction )
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs &&
+ pReqArgs->GetItemState( nSlot, sal_True, &pItem ) == SFX_ITEM_SET &&
+ pItem->ISA( SfxStringItem ) )
+ {
+ String aComment = ((const SfxStringItem*)pItem)->GetValue();
+ pDocSh->SetChangeComment( pAction, aComment );
+ rReq.Done();
+ }
+ else
+ {
+ pDocSh->ExecuteChangeCommentDialog( pAction, GetDialogParent() );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+
+ case SID_CREATE_SW_DRAWVIEW:
+ // wird von den Forms gerufen, wenn die DrawView mit allem Zubehoer
+ // angelegt werden muss
+ if (!GetScDrawView())
+ {
+ GetViewData()->GetDocShell()->MakeDrawLayer();
+ rBindings.InvalidateAll(sal_False);
+ }
+ break;
+
+ case FID_PROTECT_DOC:
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SfxPasswordDialog* pDlg;
+
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FID_PROTECT_DOC, &pItem ) &&
+ ((const SfxBoolItem*)pItem)->GetValue() == pDoc->IsDocProtected() )
+ {
+ rReq.Ignore();
+ break;
+ }
+ }
+
+ ScDocProtection* pProtect = pDoc->GetDocProtection();
+ if (pProtect && pProtect->isProtected())
+ {
+ sal_Bool bCancel = sal_False;
+ String aPassword;
+
+ if (pProtect->isProtectedWithPass())
+ {
+ String aText( ScResId(SCSTR_PASSWORD) );
+
+ pDlg = new SfxPasswordDialog( GetDialogParent(), &aText );
+ pDlg->SetText( ScResId(SCSTR_UNPROTECTDOC) );
+ pDlg->SetMinLen( 0 );
+ pDlg->SetHelpId( GetStaticInterface()->GetSlot(FID_PROTECT_DOC)->GetCommand() );
+ pDlg->SetEditHelpId( HID_PASSWD_DOC );
+
+ if (pDlg->Execute() == RET_OK)
+ aPassword = pDlg->GetPassword();
+ else
+ bCancel = sal_True;
+ delete pDlg;
+ }
+ if (!bCancel)
+ {
+ Unprotect( TABLEID_DOC, aPassword );
+ rReq.AppendItem( SfxBoolItem( FID_PROTECT_DOC, sal_False ) );
+ rReq.Done();
+ }
+ }
+ else
+ {
+ String aText( ScResId(SCSTR_PASSWORDOPT) );
+
+ pDlg = new SfxPasswordDialog( GetDialogParent(), &aText );
+ pDlg->SetText( ScResId(SCSTR_PROTECTDOC) );
+ pDlg->SetMinLen( 0 );
+ pDlg->SetHelpId( GetStaticInterface()->GetSlot(FID_PROTECT_DOC)->GetCommand() );
+ pDlg->SetEditHelpId( HID_PASSWD_DOC );
+ pDlg->ShowExtras( SHOWEXTRAS_CONFIRM );
+
+ if (pDlg->Execute() == RET_OK)
+ {
+ String aPassword = pDlg->GetPassword();
+ Protect( TABLEID_DOC, aPassword );
+ rReq.AppendItem( SfxBoolItem( FID_PROTECT_DOC, sal_True ) );
+ rReq.Done();
+ }
+
+ delete pDlg;
+ }
+ rBindings.Invalidate( FID_PROTECT_DOC );
+ }
+ break;
+
+
+ case FID_PROTECT_TABLE:
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ bool bOldProtection = pDoc->IsTabProtected(nTab);
+
+#if ENABLE_SHEET_PROTECTION
+
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ bool bNewProtection = !bOldProtection;
+ if( IS_AVAILABLE( FID_PROTECT_TABLE, &pItem ) )
+ bNewProtection = ((const SfxBoolItem*)pItem)->GetValue();
+ if( bNewProtection == bOldProtection )
+ {
+ rReq.Ignore();
+ break;
+ }
+ }
+
+ if (bOldProtection)
+ {
+ // Unprotect a protected sheet.
+
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ if (pProtect && pProtect->isProtectedWithPass())
+ {
+ String aText( ScResId(SCSTR_PASSWORDOPT) );
+ auto_ptr<SfxPasswordDialog> pDlg(new SfxPasswordDialog(GetDialogParent(), &aText));
+ pDlg->SetText( ScResId(SCSTR_UNPROTECTTAB) );
+ pDlg->SetMinLen( 0 );
+ pDlg->SetHelpId( GetStaticInterface()->GetSlot(FID_PROTECT_TABLE)->GetCommand() );
+ pDlg->SetEditHelpId( HID_PASSWD_TABLE );
+
+ if (pDlg->Execute() == RET_OK)
+ {
+ String aPassword = pDlg->GetPassword();
+ Unprotect(nTab, aPassword);
+ }
+ }
+ else
+ // this sheet is not password-protected.
+ Unprotect(nTab, String());
+
+ if (!pReqArgs)
+ {
+ rReq.AppendItem( SfxBoolItem(FID_PROTECT_TABLE, false) );
+ rReq.Done();
+ }
+ }
+ else
+ {
+ // Protect a current sheet.
+
+ auto_ptr<ScTableProtectionDlg> pDlg(new ScTableProtectionDlg(GetDialogParent()));
+
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ if (pProtect)
+ pDlg->SetDialogData(*pProtect);
+
+ if (pDlg->Execute() == RET_OK)
+ {
+ pScMod->InputEnterHandler();
+
+ ScTableProtection aNewProtect;
+ pDlg->WriteData(aNewProtect);
+ ProtectSheet(nTab, aNewProtect);
+ if (!pReqArgs)
+ {
+ rReq.AppendItem( SfxBoolItem(FID_PROTECT_TABLE, true) );
+ rReq.Done();
+ }
+ }
+ }
+#else
+ auto_ptr<SfxPasswordDialog> pDlg;
+ String aPassword;
+ sal_Bool bCancel = sal_False;
+ bool bNewProtection = ! bOldProtection;
+
+ if( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FID_PROTECT_TABLE, &pItem ) )
+ bNewProtection = ((const SfxBoolItem*)pItem)->GetValue();
+ if( bNewProtection == bOldProtection )
+ {
+ rReq.Ignore();
+ break;
+ }
+ }
+
+ if ( bOldProtection)
+ {
+ // Unprotect a protected sheet.
+
+ ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
+ if (pProtect && pProtect->isProtectedWithPass())
+ {
+ String aText( ScResId(SCSTR_PASSWORDOPT) );
+ pDlg.reset(new SfxPasswordDialog(GetDialogParent(), &aText));
+ pDlg->SetText( ScResId(SCSTR_UNPROTECTTAB) );
+ pDlg->SetMinLen( 0 );
+ pDlg->SetHelpId( GetStaticInterface()->GetSlot(FID_PROTECT_TABLE)->GetCommand() );
+ pDlg->SetEditHelpId( HID_PASSWD_TABLE );
+
+ if (pDlg->Execute() == RET_OK)
+ aPassword = pDlg->GetPassword();
+ else
+ bCancel = sal_True;
+ }
+
+ if (!pReqArgs)
+ {
+ rReq.AppendItem( SfxBoolItem(FID_PROTECT_TABLE, false) );
+ rReq.Done();
+ }
+ }
+ else
+ {
+ String aText( ScResId(SCSTR_PASSWORDOPT) );
+
+ pDlg.reset(new SfxPasswordDialog(GetDialogParent(), &aText));
+ pDlg->SetText( ScResId(SCSTR_PROTECTTAB) );
+ pDlg->SetMinLen( 0 );
+ pDlg->SetHelpId( GetStaticInterface()->GetSlot(FID_PROTECT_TABLE)->GetCommand() );
+ pDlg->SetEditHelpId( HID_PASSWD_TABLE );
+ pDlg->ShowExtras( SHOWEXTRAS_CONFIRM );
+
+ if (pDlg->Execute() == RET_OK)
+ aPassword = pDlg->GetPassword();
+ else
+ bCancel = sal_True;
+ }
+
+ if( !bCancel )
+ {
+ if ( bOldProtection )
+ Unprotect( nTab, aPassword );
+ else
+ {
+ pScMod->InputEnterHandler();
+
+ Protect( nTab, aPassword );
+ }
+
+ if( !pReqArgs )
+ {
+ rReq.AppendItem( SfxBoolItem( FID_PROTECT_TABLE, bNewProtection ) );
+ rReq.Done();
+ }
+ }
+#endif
+ TabChanged();
+ UpdateInputHandler(true); // damit sofort wieder eingegeben werden kann
+ SelectionChanged();
+ }
+ break;
+
+ case SID_OPT_LOCALE_CHANGED :
+ { // locale changed, SYSTEM number formats changed => repaint cell contents
+ PaintGrid();
+ rReq.Done();
+ }
+ break;
+
+ default:
+ DBG_ERROR("Unbekannter Slot bei ScTabViewShell::Execute");
+ break;
+ }
+}
+
+
+
diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx
new file mode 100644
index 000000000000..3710fca85e33
--- /dev/null
+++ b/sc/source/ui/view/tabvwsh4.cxx
@@ -0,0 +1,1990 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/app.hxx>
+#include <svx/extrusionbar.hxx>
+#include <svx/fontworkbar.hxx>
+#include <editeng/boxitem.hxx>
+#include <svx/fmshell.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <svx/prtqry.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svl/whiter.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <rtl/logfile.hxx>
+#include <tools/urlobj.hxx>
+#include <sfx2/docfile.hxx>
+
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "stlpool.hxx"
+#include "stlsheet.hxx"
+#include "docsh.hxx"
+#include "scmod.hxx"
+#include "appoptio.hxx"
+#include "rangeutl.hxx"
+#include "printfun.hxx"
+#include "drawsh.hxx"
+#include "drformsh.hxx"
+#include "editsh.hxx"
+#include "pivotsh.hxx"
+#include "auditsh.hxx"
+#include "drtxtob.hxx"
+#include "inputhdl.hxx"
+#include "editutil.hxx"
+#include "inputopt.hxx"
+#include "inputwin.hxx"
+#include "scresid.hxx"
+#include "dbcolect.hxx" // fuer ReImport
+#include "reffact.hxx"
+#include "viewuno.hxx"
+#include "dispuno.hxx"
+#include "anyrefdg.hxx"
+#include "chgtrack.hxx"
+#include "cellsh.hxx"
+#include "oleobjsh.hxx"
+#include "chartsh.hxx"
+#include "graphsh.hxx"
+#include "mediash.hxx"
+#include "pgbrksh.hxx"
+#include "dpobject.hxx"
+#include "prevwsh.hxx"
+#include "tpprint.hxx"
+#include "scextopt.hxx"
+#include "printopt.hxx"
+#include "drawview.hxx"
+#include "fupoor.hxx"
+#include "navsett.hxx"
+#include "sc.hrc" //CHINA001
+#include "scabstdlg.hxx" //CHINA001
+#include "externalrefmgr.hxx"
+
+void ActivateOlk( ScViewData* pViewData );
+void DeActivateOlk( ScViewData* pViewData );
+
+extern SfxViewShell* pScActiveViewShell; // global.cxx
+
+using namespace com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+sal_uInt16 ScTabViewShell::nInsertCtrlState = SID_INSERT_GRAPHIC;
+sal_uInt16 ScTabViewShell::nInsCellsCtrlState = 0;
+sal_uInt16 ScTabViewShell::nInsObjCtrlState = SID_INSERT_DIAGRAM;
+
+// -----------------------------------------------------------------------
+
+void __EXPORT ScTabViewShell::Activate(sal_Bool bMDI)
+{
+ SfxViewShell::Activate(bMDI);
+
+ // hier kein GrabFocus, sonst gibt's Probleme wenn etwas inplace editiert wird!
+
+ if ( bMDI )
+ {
+ // fuer Eingabezeile (ClearCache)
+ ScModule* pScMod = SC_MOD();
+ pScMod->ViewShellChanged();
+
+ ActivateView( sal_True, bFirstActivate );
+ ActivateOlk( GetViewData() );
+
+ // #56870# AutoCorrect umsetzen, falls der Writer seins neu angelegt hat
+ UpdateDrawTextOutliner();
+
+ // RegisterNewTargetNames gibts nicht mehr
+
+ SfxViewFrame* pThisFrame = GetViewFrame();
+ if ( pInputHandler && pThisFrame->HasChildWindow(FID_INPUTLINE_STATUS) )
+ {
+ // eigentlich nur beim Reload (letzte Version) noetig:
+ // Das InputWindow bleibt stehen, aber die View mitsamt InputHandler wird
+ // neu angelegt, darum muss der InputHandler am InputWindow gesetzt werden.
+ SfxChildWindow* pChild = pThisFrame->GetChildWindow(FID_INPUTLINE_STATUS);
+ if (pChild)
+ {
+ ScInputWindow* pWin = (ScInputWindow*)pChild->GetWindow();
+ if (pWin && pWin->IsVisible())
+ {
+
+ ScInputHandler* pOldHdl=pWin->GetInputHandler();
+
+ TypeId aScType = TYPE(ScTabViewShell);
+
+ SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
+ while ( pSh!=NULL && pOldHdl!=NULL)
+ {
+ if (((ScTabViewShell*)pSh)->GetInputHandler() == pOldHdl)
+ {
+ pOldHdl->ResetDelayTimer();
+ break;
+ }
+ pSh = SfxViewShell::GetNext( *pSh, &aScType );
+ }
+
+ pWin->SetInputHandler( pInputHandler );
+ }
+ }
+ }
+
+ UpdateInputHandler( sal_True );
+
+ if ( bFirstActivate )
+ {
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_NAVIGATOR_UPDATEALL ) );
+ bFirstActivate = sal_False;
+
+ // #116278# ReadExtOptions (view settings from Excel import) must also be done
+ // after the ctor, because of the potential calls to Window::Show.
+ // Even after the fix for #104887# (Window::Show no longer notifies the access
+ // bridge, it's done in ImplSetReallyVisible), there are problems if Window::Show
+ // is called during the ViewShell ctor and reschedules asynchronous calls
+ // (for example from the FmFormShell ctor).
+ ScExtDocOptions* pExtOpt = GetViewData()->GetDocument()->GetExtDocOptions();
+ if ( pExtOpt && pExtOpt->IsChanged() )
+ {
+ GetViewData()->ReadExtOptions(*pExtOpt); // Excel view settings
+ SetTabNo( GetViewData()->GetTabNo(), sal_True );
+ pExtOpt->SetChanged( false );
+ }
+ }
+
+ pScActiveViewShell = this;
+
+ ScInputHandler* pHdl = pScMod->GetInputHdl(this);
+ if (pHdl)
+ {
+ pHdl->SetRefScale( GetViewData()->GetZoomX(), GetViewData()->GetZoomY() );
+ }
+
+ // Aenderungs-Dialog aktualisieren
+
+ if ( pThisFrame->HasChildWindow(FID_CHG_ACCEPT) )
+ {
+ SfxChildWindow* pChild = pThisFrame->GetChildWindow(FID_CHG_ACCEPT);
+ if (pChild)
+ {
+ ((ScAcceptChgDlgWrapper*)pChild)->ReInitDlg();
+ }
+ }
+
+ if(pScMod->IsRefDialogOpen())
+ {
+ sal_uInt16 nModRefDlgId=pScMod->GetCurRefDlgId();
+ SfxChildWindow* pChildWnd = pThisFrame->GetChildWindow( nModRefDlgId );
+ if ( pChildWnd )
+ {
+ IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
+ pRefDlg->ViewShellChanged(this);
+ }
+ }
+ }
+
+ // don't call CheckSelectionTransfer here - activating a view should not change the
+ // primary selection (may be happening just because the mouse was moved over the window)
+
+ // Wenn Referenzeingabe-Tip-Hilfe hier wieder angezeigt werden soll (ShowRefTip),
+ // muss sie beim Verschieben der View angepasst werden (gibt sonst Probleme unter OS/2
+ // beim Umschalten zwischen Dokumenten)
+}
+
+void __EXPORT ScTabViewShell::Deactivate(sal_Bool bMDI)
+{
+ HideTip();
+
+ ScDocument* pDoc=GetViewData()->GetDocument();
+
+ ScChangeTrack* pChanges=pDoc->GetChangeTrack();
+
+ if(pChanges!=NULL)
+ {
+ Link aLink;
+ pChanges->SetModifiedLink(aLink);
+ }
+
+ SfxViewShell::Deactivate(bMDI);
+
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl(this);
+
+ if( bMDI )
+ {
+ // #85421# during shell deactivation, shells must not be switched, or the loop
+ // through the shell stack (in SfxDispatcher::DoDeactivate_Impl) will not work
+ sal_Bool bOldDontSwitch = bDontSwitch;
+ bDontSwitch = sal_True;
+
+ DeActivateOlk( GetViewData() );
+ ActivateView( sal_False, sal_False );
+
+ if ( GetViewFrame()->GetFrame().IsInPlace() ) // inplace
+ GetViewData()->GetDocShell()->UpdateOle(GetViewData(),sal_True);
+
+ if ( pHdl )
+ pHdl->NotifyChange( NULL, sal_True ); // Timer-verzoegert wg. Dokumentwechsel
+
+ if (pScActiveViewShell == this)
+ pScActiveViewShell = NULL;
+
+ bDontSwitch = bOldDontSwitch;
+ }
+ else
+ {
+ HideNoteMarker(); // Notiz-Anzeige
+
+ if ( pHdl )
+ pHdl->HideTip(); // Formel-AutoEingabe-Tip abschalten
+ }
+}
+
+void ScTabViewShell::SetActive()
+{
+ // Die Sfx-View moechte sich gerne selbst aktivieren, weil dabei noch
+ // magische Dinge geschehen (z.B. stuerzt sonst evtl. der Gestalter ab)
+ ActiveGrabFocus();
+
+#if 0
+ SfxViewFrame* pFrame = GetViewFrame();
+ pFrame->GetFrame().Appear();
+
+ SFX_APP()->SetViewFrame( pFrame ); // immer erst Appear, dann SetViewFrame (#29290#)
+#endif
+}
+
+sal_uInt16 __EXPORT ScTabViewShell::PrepareClose(sal_Bool bUI, sal_Bool bForBrowsing)
+{
+ // Call EnterHandler even in formula mode here,
+ // so a formula change in an embedded object isn't lost
+ // (ScDocShell::PrepareClose isn't called then).
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl( this );
+ if ( pHdl && pHdl->IsInputMode() )
+ pHdl->EnterHandler();
+
+ // #110797# draw text edit mode must be closed
+ FuPoor* pPoor = GetDrawFuncPtr();
+ if ( pPoor && ( IsDrawTextShell() || pPoor->GetSlotID() == SID_DRAW_NOTEEDIT ) )
+ {
+ // "clean" end of text edit, including note handling, subshells and draw func switching,
+ // as in FuDraw and ScTabView::DrawDeselectAll
+ GetViewData()->GetDispatcher().Execute( pPoor->GetSlotID(), SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
+ }
+ ScDrawView* pDrView = GetScDrawView();
+ if ( pDrView )
+ {
+ // force end of text edit, to be safe
+ // #128314# ScEndTextEdit must always be used, to ensure correct UndoManager
+ pDrView->ScEndTextEdit();
+ }
+
+ if ( pFormShell )
+ {
+ sal_uInt16 nRet = pFormShell->PrepareClose(bUI, bForBrowsing);
+ if (nRet!=sal_True)
+ return nRet;
+ }
+ return SfxViewShell::PrepareClose(bUI,bForBrowsing);
+}
+
+//------------------------------------------------------------------
+
+Size __EXPORT ScTabViewShell::GetOptimalSizePixel() const
+{
+ Size aOptSize;
+
+ SCTAB nCurTab = GetViewData()->GetTabNo();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find(
+ pDoc->GetPageStyle( nCurTab ),
+ SFX_STYLE_FAMILY_PAGE );
+
+ DBG_ASSERT( pStyleSheet, "PageStyle not found :-/" );
+
+ if ( pStyleSheet )
+ {
+ const SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ const SvxSizeItem& rItem = (const SvxSizeItem&)rSet.Get( ATTR_PAGE_SIZE );
+ const Size& rPageSize = rItem.GetSize();
+
+ aOptSize.Width() = (long) (rPageSize.Width() * GetViewData()->GetPPTX());
+ aOptSize.Height() = (long) (rPageSize.Height() * GetViewData()->GetPPTY());
+ }
+
+ return aOptSize;
+}
+
+//------------------------------------------------------------------
+
+// Zoom fuer In-Place berechnen
+// aus Verhaeltnis von VisArea und Fenstergroesse des GridWin
+
+void ScTabViewShell::UpdateOleZoom()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ if ( pDocSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
+ {
+ //TODO/LATER: is there a difference between the two GetVisArea methods?
+ Size aObjSize = ((const SfxObjectShell*)pDocSh)->GetVisArea().GetSize();
+ if ( aObjSize.Width() > 0 && aObjSize.Height() > 0 )
+ {
+ Window* pWin = GetActiveWin();
+ Size aWinHMM = pWin->PixelToLogic( pWin->GetOutputSizePixel(), MAP_100TH_MM );
+ SetZoomFactor( Fraction( aWinHMM.Width(),aObjSize.Width() ),
+ Fraction( aWinHMM.Height(),aObjSize.Height() ) );
+ }
+ }
+}
+
+void __EXPORT ScTabViewShell::AdjustPosSizePixel( const Point &rPos, const Size &rSize )
+{
+ OuterResizePixel( rPos, rSize );
+}
+
+void __EXPORT ScTabViewShell::InnerResizePixel( const Point &rOfs, const Size &rSize )
+{
+ Size aNewSize( rSize );
+ if ( GetViewFrame()->GetFrame().IsInPlace() )
+ {
+ SvBorder aBorder;
+ GetBorderSize( aBorder, rSize );
+ SetBorderPixel( aBorder );
+
+ Size aObjSize = GetObjectShell()->GetVisArea().GetSize();
+
+ Size aSize( rSize );
+ aSize.Width() -= (aBorder.Left() + aBorder.Right());
+ aSize.Height() -= (aBorder.Top() + aBorder.Bottom());
+
+ if ( aObjSize.Width() > 0 && aObjSize.Height() > 0 )
+ {
+ Size aLogicSize = GetWindow()->PixelToLogic( aSize, MAP_100TH_MM );
+ SfxViewShell::SetZoomFactor( Fraction( aLogicSize.Width(),aObjSize.Width() ),
+ Fraction( aLogicSize.Height(),aObjSize.Height() ) );
+ }
+
+ Point aPos( rOfs );
+ aPos.X() += aBorder.Left();
+ aPos.Y() += aBorder.Top();
+ GetWindow()->SetPosSizePixel( aPos, aSize );
+ }
+ else
+ {
+ SvBorder aBorder;
+ GetBorderSize( aBorder, rSize );
+ SetBorderPixel( aBorder );
+ aNewSize.Width() += aBorder.Left() + aBorder.Right();
+ aNewSize.Height() += aBorder.Top() + aBorder.Bottom();
+ }
+
+ DoResize( rOfs, aNewSize, sal_True ); // rSize = Groesse von gridwin
+
+ UpdateOleZoom(); // Zoom fuer In-Place berechnen
+
+// GetViewData()->GetDocShell()->UpdateOle( GetViewData() );
+ GetViewData()->GetDocShell()->SetDocumentModified();
+}
+
+void __EXPORT ScTabViewShell::OuterResizePixel( const Point &rOfs, const Size &rSize )
+{
+ SvBorder aBorder;
+ GetBorderSize( aBorder, rSize );
+ SetBorderPixel( aBorder );
+
+ DoResize( rOfs, rSize ); // Position und Groesse von tabview wie uebergeben
+
+ // ForceMove als Ersatz fuer den Sfx-Move-Mechanismus
+ // (aWinPos muss aktuell gehalten werden, damit ForceMove beim Ole-Deaktivieren klappt)
+
+ ForceMove();
+}
+
+void __EXPORT ScTabViewShell::SetZoomFactor( const Fraction &rZoomX, const Fraction &rZoomY )
+{
+ // fuer OLE...
+
+ Fraction aFrac20( 1,5 );
+ Fraction aFrac400( 4,1 );
+
+ Fraction aNewX( rZoomX );
+ if ( aNewX < aFrac20 )
+ aNewX = aFrac20;
+ if ( aNewX > aFrac400 )
+ aNewX = aFrac400;
+ Fraction aNewY( rZoomY );
+ if ( aNewY < aFrac20 )
+ aNewY = aFrac20;
+ if ( aNewY > aFrac400 )
+ aNewY = aFrac400;
+
+ GetViewData()->UpdateScreenZoom( aNewX, aNewY );
+ SetZoom( aNewX, aNewY, sal_True );
+
+ PaintGrid();
+ PaintTop();
+ PaintLeft();
+
+ SfxViewShell::SetZoomFactor( rZoomX, rZoomY );
+}
+
+void __EXPORT ScTabViewShell::QueryObjAreaPixel( Rectangle& rRect ) const
+{
+ // auf ganze Zellen anpassen (in 1/100 mm)
+
+ Size aPixelSize = rRect.GetSize();
+ Window* pWin = ((ScTabViewShell*)this)->GetActiveWin();
+ Size aLogicSize = pWin->PixelToLogic( aPixelSize );
+
+ const ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScSplitPos ePos = pViewData->GetActivePart();
+ SCCOL nCol = pViewData->GetPosX(WhichH(ePos));
+ SCROW nRow = pViewData->GetPosY(WhichV(ePos));
+ SCTAB nTab = pViewData->GetTabNo();
+ sal_Bool bNegativePage = pDoc->IsNegativePage( nTab );
+
+ Rectangle aLogicRect = pDoc->GetMMRect( nCol, nRow, nCol, nRow, nTab );
+ if ( bNegativePage )
+ {
+ // use right edge of aLogicRect, and aLogicSize
+ aLogicRect.Left() = aLogicRect.Right() - aLogicSize.Width() + 1; // Right() is set below
+ }
+ aLogicRect.SetSize( aLogicSize );
+
+ pDoc->SnapVisArea( aLogicRect );
+
+ rRect.SetSize( pWin->LogicToPixel( aLogicRect.GetSize() ) );
+
+#if 0
+ // auf ganze Zellen anpassen (in Pixeln)
+
+ ScViewData* pViewData = ((ScTabViewShell*)this)->GetViewData();
+ Size aSize = rRect.GetSize();
+
+ ScSplitPos ePos = pViewData->GetActivePart();
+ Window* pWin = ((ScTabViewShell*)this)->GetActiveWin();
+
+ Point aTest( aSize.Width(), aSize.Height() );
+ SCsCOL nPosX;
+ SCsROW nPosY;
+ pViewData->GetPosFromPixel( aTest.X(), aTest.Y(), ePos, nPosX, nPosY );
+ sal_Bool bLeft;
+ sal_Bool bTop;
+ pViewData->GetMouseQuadrant( aTest, ePos, nPosX, nPosY, bLeft, bTop );
+ if (!bLeft)
+ ++nPosX;
+ if (!bTop)
+ ++nPosY;
+ aTest = pViewData->GetScrPos( (SCCOL)nPosX, (SCROW)nPosY, ePos, sal_True );
+
+ rRect.SetSize(Size(aTest.X(),aTest.Y()));
+#endif
+}
+
+//------------------------------------------------------------------
+
+void __EXPORT ScTabViewShell::Move()
+{
+ Point aNewPos = GetViewFrame()->GetWindow().OutputToScreenPixel(Point());
+
+ if (aNewPos != aWinPos)
+ {
+ StopMarking();
+ aWinPos = aNewPos;
+ }
+}
+
+//------------------------------------------------------------------
+
+void __EXPORT ScTabViewShell::ShowCursor(FASTBOOL /* bOn */)
+{
+/*!!! ShowCursor wird nicht paarweise wie im gridwin gerufen.
+ Der CursorLockCount am Gridwin muss hier direkt auf 0 gesetzt werden
+
+ if (bOn)
+ ShowAllCursors();
+ else
+ HideAllCursors();
+*/
+}
+
+//------------------------------------------------------------------
+
+void __EXPORT ScTabViewShell::WriteUserData(String& rData, sal_Bool /* bBrowse */)
+{
+ GetViewData()->WriteUserData(rData);
+}
+
+void ScTabViewShell::WriteUserDataSequence (uno::Sequence < beans::PropertyValue >& rSettings, sal_Bool /* bBrowse */ )
+{
+ GetViewData()->WriteUserDataSequence (rSettings);
+}
+
+void __EXPORT ScTabViewShell::ReadUserData(const String& rData, sal_Bool /* bBrowse */)
+{
+ if ( !GetViewData()->GetDocShell()->IsPreview() )
+ DoReadUserData( rData );
+}
+
+void ScTabViewShell::ReadUserDataSequence (const uno::Sequence < beans::PropertyValue >& rSettings, sal_Bool /* bBrowse */ )
+{
+ if ( !GetViewData()->GetDocShell()->IsPreview() )
+ DoReadUserDataSequence( rSettings );
+}
+
+void ScTabViewShell::DoReadUserDataSequence( const uno::Sequence < beans::PropertyValue >& rSettings )
+{
+ Window* pOldWin = GetActiveWin();
+ sal_Bool bFocus = pOldWin && pOldWin->HasFocus();
+
+ GetViewData()->ReadUserDataSequence(rSettings);
+ SetTabNo( GetViewData()->GetTabNo(), sal_True );
+
+ if ( GetViewData()->IsPagebreakMode() )
+ SetCurSubShell( GetCurObjectSelectionType(), sal_True );
+
+ Window* pNewWin = GetActiveWin();
+ if (pNewWin && pNewWin != pOldWin)
+ {
+ SetWindow( pNewWin ); //! ist diese ViewShell immer aktiv???
+ if (bFocus)
+ pNewWin->GrabFocus();
+ WindowChanged(); // Drawing-Layer (z.B. #56771#)
+ }
+
+ if (GetViewData()->GetHSplitMode() == SC_SPLIT_FIX ||
+ GetViewData()->GetVSplitMode() == SC_SPLIT_FIX)
+ {
+ InvalidateSplit();
+ }
+
+ ZoomChanged();
+
+ TestHintWindow();
+
+ //! if ViewData has more tables than document, remove tables in ViewData
+}
+
+// DoReadUserData is also called from ctor when switching from print preview
+
+void ScTabViewShell::DoReadUserData( const String& rData )
+{
+ Window* pOldWin = GetActiveWin();
+ sal_Bool bFocus = pOldWin && pOldWin->HasFocus();
+
+ GetViewData()->ReadUserData(rData);
+ SetTabNo( GetViewData()->GetTabNo(), sal_True );
+
+ if ( GetViewData()->IsPagebreakMode() )
+ SetCurSubShell( GetCurObjectSelectionType(), sal_True );
+
+ Window* pNewWin = GetActiveWin();
+ if (pNewWin && pNewWin != pOldWin)
+ {
+ SetWindow( pNewWin ); //! ist diese ViewShell immer aktiv???
+ if (bFocus)
+ pNewWin->GrabFocus();
+ WindowChanged(); // Drawing-Layer (z.B. #56771#)
+ }
+
+ if (GetViewData()->GetHSplitMode() == SC_SPLIT_FIX ||
+ GetViewData()->GetVSplitMode() == SC_SPLIT_FIX)
+ {
+ InvalidateSplit();
+ }
+
+ ZoomChanged();
+
+ TestHintWindow();
+
+ //! if ViewData has more tables than document, remove tables in ViewData
+}
+
+//------------------------------------------------------------------
+
+//UNUSED2008-05 void ScTabViewShell::ExecuteShowNIY( SfxRequest& /* rReq */ )
+//UNUSED2008-05 {
+//UNUSED2008-05 ErrorMessage(STR_BOX_YNI);
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 //------------------------------------------------------------------
+//UNUSED2008-05
+//UNUSED2008-05 void ScTabViewShell::StateDisabled( SfxItemSet& rSet )
+//UNUSED2008-05 {
+//UNUSED2008-05 SfxWhichIter aIter( rSet );
+//UNUSED2008-05 sal_uInt16 nWhich = aIter.FirstWhich();
+//UNUSED2008-05
+//UNUSED2008-05 while ( nWhich )
+//UNUSED2008-05 {
+//UNUSED2008-05 rSet.DisableItem( nWhich );
+//UNUSED2008-05 nWhich = aIter.NextWhich();
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+
+void ScTabViewShell::SetDrawShellOrSub()
+{
+ bActiveDrawSh = sal_True;
+
+ if(bActiveDrawFormSh)
+ {
+ SetCurSubShell(OST_DrawForm);
+ }
+ else if(bActiveGraphicSh)
+ {
+ SetCurSubShell(OST_Graphic);
+ }
+ else if(bActiveMediaSh)
+ {
+ SetCurSubShell(OST_Media);
+ }
+ else if(bActiveChartSh)
+ {
+ SetCurSubShell(OST_Chart);
+ }
+ else if(bActiveOleObjectSh)
+ {
+ SetCurSubShell(OST_OleObject);
+ }
+ else
+ {
+ SetCurSubShell(OST_Drawing, true /* force: different toolbars are
+ visible concerning shape type
+ and shape state */);
+ }
+}
+
+void ScTabViewShell::SetDrawShell( sal_Bool bActive )
+{
+ if(bActive)
+ {
+ SetCurSubShell(OST_Drawing, true /* force: different toolbars are
+ visible concerning shape type
+ and shape state */);
+ }
+ else
+ {
+ if(bActiveDrawFormSh || bActiveDrawSh ||
+ bActiveGraphicSh || bActiveMediaSh || bActiveOleObjectSh||
+ bActiveChartSh || bActiveDrawTextSh)
+ {
+ SetCurSubShell(OST_Cell);
+ }
+ bActiveDrawFormSh=sal_False;
+ bActiveGraphicSh=sal_False;
+ bActiveMediaSh=sal_False;
+ bActiveOleObjectSh=sal_False;
+ bActiveChartSh=sal_False;
+ }
+
+ sal_Bool bWasDraw = bActiveDrawSh || bActiveDrawTextSh;
+
+ bActiveDrawSh = bActive;
+ bActiveDrawTextSh = sal_False;
+
+ if ( !bActive )
+ {
+ ResetDrawDragMode(); // Mirror / Rotate aus
+
+ if (bWasDraw && (GetViewData()->GetHSplitMode() == SC_SPLIT_FIX ||
+ GetViewData()->GetVSplitMode() == SC_SPLIT_FIX))
+ {
+ // Aktiven Teil an Cursor anpassen, etc.
+ MoveCursorAbs( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
+ SC_FOLLOW_NONE, sal_False, sal_False, sal_True );
+ }
+ }
+}
+
+void ScTabViewShell::SetDrawTextShell( sal_Bool bActive )
+{
+ bActiveDrawTextSh = bActive;
+ if ( bActive )
+ {
+ bActiveDrawFormSh=sal_False;
+ bActiveGraphicSh=sal_False;
+ bActiveMediaSh=sal_False;
+ bActiveOleObjectSh=sal_False;
+ bActiveChartSh=sal_False;
+ bActiveDrawSh = sal_False;
+ SetCurSubShell(OST_DrawText);
+ }
+ else
+ SetCurSubShell(OST_Cell);
+
+}
+
+void ScTabViewShell::SetPivotShell( sal_Bool bActive )
+{
+ bActivePivotSh = bActive;
+
+ // #68771# #76198# SetPivotShell is called from CursorPosChanged every time
+ // -> don't change anything except switching between cell and pivot shell
+
+ if ( eCurOST == OST_Pivot || eCurOST == OST_Cell )
+ {
+ if ( bActive )
+ {
+ bActiveDrawTextSh = bActiveDrawSh = sal_False;
+ bActiveDrawFormSh=sal_False;
+ bActiveGraphicSh=sal_False;
+ bActiveMediaSh=sal_False;
+ bActiveOleObjectSh=sal_False;
+ bActiveChartSh=sal_False;
+ SetCurSubShell(OST_Pivot);
+ }
+ else
+ SetCurSubShell(OST_Cell);
+ }
+}
+
+void ScTabViewShell::SetAuditShell( sal_Bool bActive )
+{
+ bActiveAuditingSh = bActive;
+ if ( bActive )
+ {
+ bActiveDrawTextSh = bActiveDrawSh = sal_False;
+ bActiveDrawFormSh=sal_False;
+ bActiveGraphicSh=sal_False;
+ bActiveMediaSh=sal_False;
+ bActiveOleObjectSh=sal_False;
+ bActiveChartSh=sal_False;
+ SetCurSubShell(OST_Auditing);
+ }
+ else
+ SetCurSubShell(OST_Cell);
+}
+
+void ScTabViewShell::SetDrawFormShell( sal_Bool bActive )
+{
+ bActiveDrawFormSh = bActive;
+
+ if(bActiveDrawFormSh)
+ SetCurSubShell(OST_DrawForm);
+}
+void ScTabViewShell::SetChartShell( sal_Bool bActive )
+{
+ bActiveChartSh = bActive;
+
+ if(bActiveChartSh)
+ SetCurSubShell(OST_Chart);
+}
+
+void ScTabViewShell::SetGraphicShell( sal_Bool bActive )
+{
+ bActiveGraphicSh = bActive;
+
+ if(bActiveGraphicSh)
+ SetCurSubShell(OST_Graphic);
+}
+
+void ScTabViewShell::SetMediaShell( sal_Bool bActive )
+{
+ bActiveMediaSh = bActive;
+
+ if(bActiveMediaSh)
+ SetCurSubShell(OST_Media);
+}
+
+void ScTabViewShell::SetOleObjectShell( sal_Bool bActive )
+{
+ bActiveOleObjectSh = bActive;
+
+ if(bActiveOleObjectSh)
+ SetCurSubShell(OST_OleObject);
+ else
+ SetCurSubShell(OST_Cell);
+}
+
+void ScTabViewShell::SetEditShell(EditView* pView, sal_Bool bActive )
+{
+ if(bActive)
+ {
+ if (pEditShell)
+ pEditShell->SetEditView( pView );
+ else
+ pEditShell = new ScEditShell( pView, GetViewData() );
+
+ SetCurSubShell(OST_Editing);
+ }
+ else if(bActiveEditSh)
+ {
+ SetCurSubShell(OST_Cell);
+ }
+ bActiveEditSh = bActive;
+}
+
+void ScTabViewShell::SetCurSubShell(ObjectSelectionType eOST, sal_Bool bForce)
+{
+ ScViewData* pViewData = GetViewData();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+
+ if(bDontSwitch) return;
+
+ if(!pCellShell) //Wird eh immer gebraucht.
+ {
+ pCellShell = new ScCellShell( GetViewData() );
+ pCellShell->SetRepeatTarget( &aTarget );
+ }
+
+ sal_Bool bPgBrk=pViewData->IsPagebreakMode();
+
+ if(bPgBrk && !pPageBreakShell)
+ {
+ pPageBreakShell = new ScPageBreakShell( this );
+ pPageBreakShell->SetRepeatTarget( &aTarget );
+ }
+
+
+ if ( eOST!=eCurOST || bForce )
+ {
+ sal_Bool bCellBrush = sal_False; // "format paint brush" allowed for cells
+ sal_Bool bDrawBrush = sal_False; // "format paint brush" allowed for drawing objects
+
+ if(eCurOST!=OST_NONE) RemoveSubShell();
+
+ if (pFormShell && !bFormShellAtTop)
+ AddSubShell(*pFormShell); // add below own subshells
+
+ switch(eOST)
+ {
+ case OST_Cell:
+ {
+ AddSubShell(*pCellShell);
+ if(bPgBrk) AddSubShell(*pPageBreakShell);
+ bCellBrush = sal_True;
+ }
+ break;
+ case OST_Editing:
+ {
+ AddSubShell(*pCellShell);
+ if(bPgBrk) AddSubShell(*pPageBreakShell);
+
+ if(pEditShell)
+ {
+ AddSubShell(*pEditShell);
+ }
+ }
+ break;
+ case OST_DrawText:
+ {
+ if ( !pDrawTextShell )
+ {
+ pDocSh->MakeDrawLayer();
+ pDrawTextShell = new ScDrawTextObjectBar( GetViewData() );
+ }
+ AddSubShell(*pDrawTextShell);
+ }
+ break;
+ case OST_Drawing:
+ {
+ if (svx::checkForSelectedCustomShapes(
+ GetScDrawView(), true /* bOnlyExtruded */ )) {
+ if (pExtrusionBarShell == 0)
+ pExtrusionBarShell = new svx::ExtrusionBar(this);
+ AddSubShell( *pExtrusionBarShell );
+ }
+ sal_uInt32 nCheckStatus = 0;
+ if (svx::checkForSelectedFontWork(
+ GetScDrawView(), nCheckStatus )) {
+ if (pFontworkBarShell == 0)
+ pFontworkBarShell = new svx::FontworkBar(this);
+ AddSubShell( *pFontworkBarShell );
+ }
+
+ if ( !pDrawShell )
+ {
+ pDocSh->MakeDrawLayer();
+ pDrawShell = new ScDrawShell( GetViewData() );
+ pDrawShell->SetRepeatTarget( &aTarget );
+ }
+ AddSubShell(*pDrawShell);
+ bDrawBrush = sal_True;
+ }
+ break;
+
+ case OST_DrawForm:
+ {
+ if ( !pDrawFormShell )
+ {
+ pDocSh->MakeDrawLayer();
+ pDrawFormShell = new ScDrawFormShell( GetViewData() );
+ pDrawFormShell->SetRepeatTarget( &aTarget );
+ }
+ AddSubShell(*pDrawFormShell);
+ bDrawBrush = sal_True;
+ }
+ break;
+
+ case OST_Chart:
+ {
+ if ( !pChartShell )
+ {
+ pDocSh->MakeDrawLayer();
+ pChartShell = new ScChartShell( GetViewData() );
+ pChartShell->SetRepeatTarget( &aTarget );
+ }
+ AddSubShell(*pChartShell);
+ bDrawBrush = sal_True;
+ }
+ break;
+
+ case OST_OleObject:
+ {
+ if ( !pOleObjectShell )
+ {
+ pDocSh->MakeDrawLayer();
+ pOleObjectShell = new ScOleObjectShell( GetViewData() );
+ pOleObjectShell->SetRepeatTarget( &aTarget );
+ }
+ AddSubShell(*pOleObjectShell);
+ bDrawBrush = sal_True;
+ }
+ break;
+
+ case OST_Graphic:
+ {
+ if ( !pGraphicShell)
+ {
+ pDocSh->MakeDrawLayer();
+ pGraphicShell = new ScGraphicShell( GetViewData() );
+ pGraphicShell->SetRepeatTarget( &aTarget );
+ }
+ AddSubShell(*pGraphicShell);
+ bDrawBrush = sal_True;
+ }
+ break;
+
+ case OST_Media:
+ {
+ if ( !pMediaShell)
+ {
+ pDocSh->MakeDrawLayer();
+ pMediaShell = new ScMediaShell( GetViewData() );
+ pMediaShell->SetRepeatTarget( &aTarget );
+ }
+ AddSubShell(*pMediaShell);
+ }
+ break;
+
+ case OST_Pivot:
+ {
+ AddSubShell(*pCellShell);
+ if(bPgBrk) AddSubShell(*pPageBreakShell);
+
+ if ( !pPivotShell )
+ {
+ pPivotShell = new ScPivotShell( this );
+ pPivotShell->SetRepeatTarget( &aTarget );
+ }
+ AddSubShell(*pPivotShell);
+ bCellBrush = sal_True;
+ }
+ break;
+ case OST_Auditing:
+ {
+ AddSubShell(*pCellShell);
+ if(bPgBrk) AddSubShell(*pPageBreakShell);
+
+ if ( !pAuditingShell )
+ {
+ pDocSh->MakeDrawLayer(); // die Wartezeit lieber jetzt als beim Klick
+
+ pAuditingShell = new ScAuditingShell( GetViewData() );
+ pAuditingShell->SetRepeatTarget( &aTarget );
+ }
+ AddSubShell(*pAuditingShell);
+ bCellBrush = sal_True;
+ }
+ break;
+ default:
+ DBG_ERROR("Falsche Shell angefordert");
+ break;
+ }
+
+ if (pFormShell && bFormShellAtTop)
+ AddSubShell(*pFormShell); // add on top of own subshells
+
+ eCurOST=eOST;
+
+ // abort "format paint brush" when switching to an incompatible shell
+ if ( ( GetBrushDocument() && !bCellBrush ) || ( GetDrawBrushSet() && !bDrawBrush ) )
+ ResetBrushDocument();
+ }
+}
+
+void ScTabViewShell::SetFormShellAtTop( sal_Bool bSet )
+{
+ if ( pFormShell && !bSet )
+ pFormShell->ForgetActiveControl(); // let the FormShell know it no longer has the focus
+
+ if ( bFormShellAtTop != bSet )
+ {
+ bFormShellAtTop = bSet;
+ SetCurSubShell( GetCurObjectSelectionType(), sal_True );
+ }
+}
+
+IMPL_LINK( ScTabViewShell, FormControlActivated, FmFormShell*, EMPTYARG )
+{
+ // a form control got the focus, so the form shell has to be on top
+ SetFormShellAtTop( sal_True );
+ return 0;
+}
+
+ObjectSelectionType ScTabViewShell::GetCurObjectSelectionType()
+{
+ return eCurOST;
+}
+
+// GetMySubShell / SetMySubShell: altes Verhalten simulieren,
+// dass es nur eine SubShell gibt (nur innerhalb der 5 eignenen SubShells)
+
+SfxShell* ScTabViewShell::GetMySubShell() const
+{
+ // GetSubShell() war frueher const, und GetSubShell(sal_uInt16) sollte es auch sein...
+
+ sal_uInt16 nPos = 0;
+ SfxShell* pSub = ((ScTabViewShell*)this)->GetSubShell(nPos);
+ while (pSub)
+ {
+ if ( pSub == pDrawShell || pSub == pDrawTextShell || pSub == pEditShell ||
+ pSub == pPivotShell || pSub == pAuditingShell || pSub == pDrawFormShell ||
+ pSub == pCellShell || pSub == pOleObjectShell|| pSub == pChartShell ||
+ pSub == pGraphicShell || pSub == pMediaShell || pSub == pPageBreakShell)
+ return pSub; // gefunden
+
+ pSub = ((ScTabViewShell*)this)->GetSubShell(++nPos);
+ }
+ return NULL; // keine von meinen dabei
+}
+
+//UNUSED2008-05 void ScTabViewShell::SetMySubShell( SfxShell* pShell )
+//UNUSED2008-05 {
+//UNUSED2008-05 SfxShell* pOld = GetMySubShell();
+//UNUSED2008-05 if ( pOld != pShell )
+//UNUSED2008-05 {
+//UNUSED2008-05 if (pOld)
+//UNUSED2008-05 RemoveSubShell(pOld); // alte SubShell entfernen
+//UNUSED2008-05 if (pShell)
+//UNUSED2008-05 AddSubShell(*pShell); // neue setzen
+//UNUSED2008-05 }
+//UNUSED2008-05 }
+
+sal_Bool ScTabViewShell::IsDrawTextShell() const
+{
+ return ( pDrawTextShell && ( GetMySubShell() == pDrawTextShell ) );
+}
+
+sal_Bool ScTabViewShell::IsAuditShell() const
+{
+ return ( pAuditingShell && ( GetMySubShell() == pAuditingShell ) );
+}
+
+void ScTabViewShell::SetDrawTextUndo( ::svl::IUndoManager* pNewUndoMgr )
+{
+ // Default: Undo-Manager der DocShell
+ if (!pNewUndoMgr)
+ pNewUndoMgr = GetViewData()->GetDocShell()->GetUndoManager();
+
+ if (pDrawTextShell)
+ {
+ pDrawTextShell->SetUndoManager(pNewUndoMgr);
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ if ( pNewUndoMgr == pDocSh->GetUndoManager() &&
+ !pDocSh->GetDocument()->IsUndoEnabled() )
+ {
+ pNewUndoMgr->SetMaxUndoActionCount( 0 );
+ }
+ }
+ else
+ {
+ DBG_ERROR("SetDrawTextUndo ohne DrawTextShell");
+ }
+}
+
+//------------------------------------------------------------------
+
+ScTabViewShell* ScTabViewShell::GetActiveViewShell()
+{
+ return PTR_CAST(ScTabViewShell,Current());
+}
+
+//------------------------------------------------------------------
+
+SfxPrinter* __EXPORT ScTabViewShell::GetPrinter( sal_Bool bCreate )
+{
+ // Drucker ist immer da (wird fuer die FontListe schon beim Starten angelegt)
+ return GetViewData()->GetDocShell()->GetPrinter(bCreate);
+}
+
+sal_uInt16 __EXPORT ScTabViewShell::SetPrinter( SfxPrinter *pNewPrinter, sal_uInt16 nDiffFlags, bool )
+{
+ return GetViewData()->GetDocShell()->SetPrinter( pNewPrinter, nDiffFlags );
+}
+
+SfxTabPage* ScTabViewShell::CreatePrintOptionsPage( Window *pParent, const SfxItemSet &rOptions )
+{
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+ //CHINA001 return ScTpPrintOptions::Create( pParent, rOptions );
+ ::CreateTabPage ScTpPrintOptionsCreate = pFact->GetTabPageCreatorFunc( RID_SCPAGE_PRINT );
+ if ( ScTpPrintOptionsCreate )
+ return (*ScTpPrintOptionsCreate)( pParent, rOptions);
+ return 0;
+}
+
+void ScTabViewShell::StopEditShell()
+{
+ if ( pEditShell != NULL && !bDontSwitch )
+ SetEditShell(NULL, sal_False );
+}
+
+//------------------------------------------------------------------
+
+// close handler to ensure function of dialog:
+
+IMPL_LINK( ScTabViewShell, SimpleRefClose, String*, EMPTYARG )
+{
+ SfxInPlaceClient* pClient = GetIPClient();
+ if ( pClient && pClient->IsObjectInPlaceActive() )
+ {
+ // If range selection was started with an active embedded object,
+ // switch back to original sheet (while the dialog is still open).
+
+ SetTabNo( GetViewData()->GetRefTabNo() );
+ }
+
+ ScSimpleRefDlgWrapper::SetAutoReOpen( sal_True );
+ return 0;
+}
+
+// handlers to call UNO listeners:
+
+ScTabViewObj* lcl_GetViewObj( ScTabViewShell& rShell )
+{
+ ScTabViewObj* pRet = NULL;
+ SfxViewFrame* pViewFrame = rShell.GetViewFrame();
+ if (pViewFrame)
+ {
+ SfxFrame& rFrame = pViewFrame->GetFrame();
+ uno::Reference<frame::XController> xController = rFrame.GetController();
+ if (xController.is())
+ pRet = ScTabViewObj::getImplementation( xController );
+ }
+ return pRet;
+}
+
+IMPL_LINK( ScTabViewShell, SimpleRefDone, String*, pResult )
+{
+ ScTabViewObj* pImpObj = lcl_GetViewObj( *this );
+ if ( pImpObj && pResult )
+ pImpObj->RangeSelDone( *pResult );
+ return 0;
+}
+
+IMPL_LINK( ScTabViewShell, SimpleRefAborted, String*, pResult )
+{
+ ScTabViewObj* pImpObj = lcl_GetViewObj( *this );
+ if ( pImpObj && pResult )
+ pImpObj->RangeSelAborted( *pResult );
+ return 0;
+}
+
+IMPL_LINK( ScTabViewShell, SimpleRefChange, String*, pResult )
+{
+ ScTabViewObj* pImpObj = lcl_GetViewObj( *this );
+ if ( pImpObj && pResult )
+ pImpObj->RangeSelChanged( *pResult );
+ return 0;
+}
+
+void ScTabViewShell::StartSimpleRefDialog(
+ const String& rTitle, const String& rInitVal,
+ sal_Bool bCloseOnButtonUp, sal_Bool bSingleCell, sal_Bool bMultiSelection )
+{
+ SfxViewFrame* pViewFrm = GetViewFrame();
+
+ if ( GetActiveViewShell() != this )
+ {
+ // #i18833# / #i34499# The API method can be called for a view that's not active.
+ // Then the view has to be activated first, the same way as in Execute for SID_CURRENTDOC.
+ // Can't use GrabFocus here, because it needs to take effect immediately.
+
+ pViewFrm->GetFrame().Appear();
+ }
+
+ sal_uInt16 nId = ScSimpleRefDlgWrapper::GetChildWindowId();
+
+ SC_MOD()->SetRefDialog( nId, sal_True, pViewFrm );
+
+ ScSimpleRefDlgWrapper* pWnd = (ScSimpleRefDlgWrapper*)pViewFrm->GetChildWindow( nId );
+ if (pWnd)
+ {
+ pWnd->SetCloseHdl( LINK( this, ScTabViewShell, SimpleRefClose ) );
+ pWnd->SetUnoLinks( LINK( this, ScTabViewShell, SimpleRefDone ),
+ LINK( this, ScTabViewShell, SimpleRefAborted ),
+ LINK( this, ScTabViewShell, SimpleRefChange ) );
+ pWnd->SetRefString( rInitVal );
+ pWnd->SetFlags( bCloseOnButtonUp, bSingleCell, bMultiSelection );
+ pWnd->SetAutoReOpen( sal_False );
+ Window* pWin = pWnd->GetWindow();
+ pWin->SetText( rTitle );
+ pWnd->StartRefInput();
+ }
+}
+
+void ScTabViewShell::StopSimpleRefDialog()
+{
+ SfxViewFrame* pViewFrm = GetViewFrame();
+ sal_uInt16 nId = ScSimpleRefDlgWrapper::GetChildWindowId();
+
+ ScSimpleRefDlgWrapper* pWnd = (ScSimpleRefDlgWrapper*)pViewFrm->GetChildWindow( nId );
+ if (pWnd)
+ {
+ Window* pWin = pWnd->GetWindow();
+ if (pWin && pWin->IsSystemWindow())
+ ((SystemWindow*)pWin)->Close(); // calls abort handler
+ }
+}
+
+//------------------------------------------------------------------
+
+sal_Bool ScTabViewShell::TabKeyInput(const KeyEvent& rKEvt)
+{
+ ScModule* pScMod = SC_MOD();
+
+ SfxViewFrame* pThisFrame = GetViewFrame();
+ if ( pThisFrame->GetChildWindow( SID_OPENDLG_FUNCTION ) )
+ return sal_False;
+
+ KeyCode aCode = rKEvt.GetKeyCode();
+ sal_Bool bShift = aCode.IsShift();
+ sal_Bool bControl = aCode.IsMod1();
+ sal_Bool bAlt = aCode.IsMod2();
+ sal_uInt16 nCode = aCode.GetCode();
+ sal_Bool bUsed = sal_False;
+ sal_Bool bInPlace = pScMod->IsEditMode(); // Editengine bekommt alles
+ sal_Bool bAnyEdit = pScMod->IsInputMode(); // nur Zeichen & Backspace
+ sal_Bool bDraw = IsDrawTextEdit();
+
+ HideNoteMarker(); // Notiz-Anzeige
+
+ // don't do extra HideCursor/ShowCursor calls if EnterHandler will switch to a different sheet
+ sal_Bool bOnRefSheet = ( GetViewData()->GetRefTabNo() == GetViewData()->GetTabNo() );
+ sal_Bool bHideCursor = ( ( nCode == KEY_RETURN && bInPlace ) || nCode == KEY_TAB ) && bOnRefSheet;
+
+ if (bHideCursor)
+ HideAllCursors();
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if ( pDoc )
+ pDoc->KeyInput( rKEvt ); // TimerDelays etc.
+
+ if( bInPlace )
+ {
+ bUsed = pScMod->InputKeyEvent( rKEvt ); // Eingabe
+ if( !bUsed )
+ bUsed = sal::static_int_cast<sal_Bool>(SfxViewShell::KeyInput( rKEvt )); // accelerators
+ }
+ else if( bAnyEdit )
+ {
+ sal_Bool bIsType = sal_False;
+ sal_uInt16 nModi = aCode.GetModifier();
+ sal_uInt16 nGroup = aCode.GetGroup();
+
+ if ( nGroup == KEYGROUP_NUM || nGroup == KEYGROUP_ALPHA || nGroup == 0 )
+ if ( !bControl && !bAlt )
+ bIsType = sal_True;
+
+ if ( nGroup == KEYGROUP_MISC )
+ switch ( nCode )
+ {
+ case KEY_RETURN:
+ bIsType = bControl && !bAlt; // Control, Shift-Control-Return
+ if ( !bIsType && nModi == 0 )
+ {
+ // Will der InputHandler auch ein einfaches Return?
+
+ ScInputHandler* pHdl = pScMod->GetInputHdl(this);
+ bIsType = pHdl && pHdl->TakesReturn();
+ }
+ break;
+ case KEY_SPACE:
+ bIsType = !bControl && !bAlt; // ohne Modifier oder Shift-Space
+ break;
+ case KEY_ESCAPE:
+ case KEY_BACKSPACE:
+ bIsType = (nModi == 0); // nur ohne Modifier
+ break;
+ default:
+ bIsType = sal_True;
+ }
+
+ if( bIsType )
+ bUsed = pScMod->InputKeyEvent( rKEvt ); // Eingabe
+
+ if( !bUsed )
+ bUsed = sal::static_int_cast<sal_Bool>(SfxViewShell::KeyInput( rKEvt )); // accelerators
+
+ if ( !bUsed && !bIsType && nCode != KEY_RETURN ) // Eingabe nochmal hinterher
+ bUsed = pScMod->InputKeyEvent( rKEvt );
+ }
+ else
+ {
+ // #51889# Spezialfall: Copy/Cut bei Mehrfachselektion -> Fehlermeldung
+ // (Slot ist disabled, SfxViewShell::KeyInput wuerde also kommentarlos verschluckt)
+ KeyFuncType eFunc = aCode.GetFunction();
+ if ( eFunc == KEYFUNC_CUT )
+ {
+ ScRange aDummy;
+ ScMarkType eMarkType = GetViewData()->GetSimpleArea( aDummy );
+ if ( eMarkType != SC_MARK_SIMPLE &&
+ !(eFunc == KEYFUNC_COPY && eMarkType == SC_MARK_SIMPLE_FILTERED) )
+ {
+ ErrorMessage(STR_NOMULTISELECT);
+ bUsed = sal_True;
+ }
+ }
+ if (!bUsed)
+ bUsed = sal::static_int_cast<sal_Bool>(SfxViewShell::KeyInput( rKEvt )); // accelerators
+
+ // #74696# during inplace editing, some slots are handled by the
+ // container app and are executed during Window::KeyInput.
+ // -> don't pass keys to input handler that would be used there
+ // but should call slots instead.
+ sal_Bool bParent = ( GetViewFrame()->GetFrame().IsInPlace() && eFunc != KEYFUNC_DONTKNOW );
+
+ if( !bUsed && !bDraw && nCode != KEY_RETURN && !bParent )
+ bUsed = pScMod->InputKeyEvent( rKEvt, sal_True ); // Eingabe
+ }
+
+ if (!bInPlace && !bUsed && !bDraw)
+ {
+ switch (nCode)
+ {
+ case KEY_RETURN:
+ {
+ sal_Bool bNormal = !bControl && !bAlt;
+ if ( !bAnyEdit && bNormal )
+ {
+ // je nach Optionen mit Enter in den Edit-Modus schalten
+
+ const ScInputOptions& rOpt = pScMod->GetInputOptions();
+ if ( rOpt.GetEnterEdit() )
+ {
+ pScMod->SetInputMode( SC_INPUT_TABLE );
+ bUsed = sal_True;
+ }
+ }
+
+ sal_Bool bEditReturn = bControl && !bShift; // An Edit-Engine weiter
+ if ( !bUsed && !bEditReturn )
+ {
+ if ( bOnRefSheet )
+ HideAllCursors();
+
+ sal_uInt8 nMode = SC_ENTER_NORMAL;
+ if ( bShift && bControl )
+ nMode = SC_ENTER_MATRIX;
+ else if ( bAlt )
+ nMode = SC_ENTER_BLOCK;
+ pScMod->InputEnterHandler(nMode);
+
+ if (nMode == SC_ENTER_NORMAL)
+ {
+ if( bShift )
+ GetViewData()->GetDispatcher().Execute( SID_CURSORENTERUP,
+ SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
+ else
+ GetViewData()->GetDispatcher().Execute( SID_CURSORENTERDOWN,
+ SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
+ }
+ else
+ UpdateInputHandler(sal_True);
+
+ if ( bOnRefSheet )
+ ShowAllCursors();
+
+ // hier kein UpdateInputHandler, weil bei Referenzeingabe auf ein
+ // anderes Dokument diese ViewShell nicht die ist, auf der eingegeben
+ // wird!
+
+ bUsed = sal_True;
+ }
+ }
+ break;
+ }
+ }
+
+ // Alt-Cursortasten hart codiert, weil Alt nicht konfigurierbar ist
+
+ if ( !bUsed && bAlt && !bControl )
+ {
+ sal_uInt16 nSlotId = 0;
+ switch (nCode)
+ {
+ case KEY_UP:
+ ModifyCellSize( DIR_TOP, bShift );
+ bUsed = sal_True;
+ break;
+ case KEY_DOWN:
+ ModifyCellSize( DIR_BOTTOM, bShift );
+ bUsed = sal_True;
+ break;
+ case KEY_LEFT:
+ ModifyCellSize( DIR_LEFT, bShift );
+ bUsed = sal_True;
+ break;
+ case KEY_RIGHT:
+ ModifyCellSize( DIR_RIGHT, bShift );
+ bUsed = sal_True;
+ break;
+ case KEY_PAGEUP:
+ nSlotId = bShift ? SID_CURSORPAGELEFT_SEL : SID_CURSORPAGELEFT_;
+ break;
+ case KEY_PAGEDOWN:
+ nSlotId = bShift ? SID_CURSORPAGERIGHT_SEL : SID_CURSORPAGERIGHT_;
+ break;
+ }
+ if ( nSlotId )
+ {
+ GetViewData()->GetDispatcher().Execute( nSlotId, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
+ bUsed = sal_True;
+ }
+ }
+
+ if (bHideCursor)
+ ShowAllCursors();
+
+ return bUsed;
+}
+
+sal_Bool ScTabViewShell::SfxKeyInput(const KeyEvent& rKeyEvent)
+{
+ return sal::static_int_cast<sal_Bool>(SfxViewShell::KeyInput( rKeyEvent ));
+}
+
+FASTBOOL __EXPORT ScTabViewShell::KeyInput( const KeyEvent &rKeyEvent )
+{
+// return SfxViewShell::KeyInput( rKeyEvent );
+ return TabKeyInput( rKeyEvent );
+}
+
+//------------------------------------------------------------------
+
+#define __INIT_ScTabViewShell \
+ eCurOST(OST_NONE), \
+ nDrawSfxId(0), \
+ nCtrlSfxId(USHRT_MAX), \
+ nFormSfxId(USHRT_MAX), \
+ pDrawShell(NULL), \
+ pDrawTextShell(NULL), \
+ pEditShell(NULL), \
+ pPivotShell(NULL), \
+ pAuditingShell(NULL), \
+ pDrawFormShell(NULL), \
+ pCellShell(NULL), \
+ pOleObjectShell(NULL), \
+ pChartShell(NULL), \
+ pGraphicShell(NULL), \
+ pMediaShell(NULL), \
+ pPageBreakShell(NULL), \
+ pExtrusionBarShell(NULL), \
+ pFontworkBarShell(NULL), \
+ pFormShell(NULL), \
+ pInputHandler(NULL), \
+ pCurFrameLine(NULL), \
+ aTarget( this ), \
+ pDialogDPObject(NULL), \
+ pNavSettings(NULL), \
+ bActiveDrawSh(sal_False), \
+ bActiveDrawTextSh(sal_False), \
+ bActivePivotSh(sal_False), \
+ bActiveAuditingSh(sal_False), \
+ bActiveDrawFormSh(sal_False), \
+ bActiveOleObjectSh(sal_False), \
+ bActiveChartSh(sal_False), \
+ bActiveGraphicSh(sal_False), \
+ bActiveMediaSh(sal_False), \
+ bActiveEditSh(sal_False), \
+ bFormShellAtTop(sal_False), \
+ bDontSwitch(sal_False), \
+ bInFormatDialog(sal_False), \
+ bPrintSelected(sal_False), \
+ bReadOnly(sal_False), \
+ pScSbxObject(NULL), \
+ /*bChartDlgIsEdit(sal_False),*/ \
+ bChartAreaValid(sal_False), \
+ nCurRefDlgId(0), \
+ pAccessibilityBroadcaster(NULL)
+
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::Construct( sal_uInt8 nForceDesignMode )
+{
+ SfxApplication* pSfxApp = SFX_APP();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+
+ bReadOnly = pDocSh->IsReadOnly();
+
+ SetName( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("View")) ); // fuer SBX
+ Color aColBlack( COL_BLACK );
+// SetPool( &pSfxApp->GetPool() );
+ SetPool( &SC_MOD()->GetPool() );
+ SetWindow( GetActiveWin() );
+
+ pCurFrameLine = new SvxBorderLine( &aColBlack, 20, 0, 0 );
+ pPivotSource = new ScArea;
+ StartListening(*GetViewData()->GetDocShell(),sal_True);
+ StartListening(*GetViewFrame(),sal_True);
+ StartListening(*pSfxApp,sal_True); // #i62045# #i62046# application is needed for Calc's own hints
+
+ SfxViewFrame* pFirst = SfxViewFrame::GetFirst(pDocSh);
+ sal_Bool bFirstView = !pFirst
+ || (pFirst == GetViewFrame() && !SfxViewFrame::GetNext(*pFirst,pDocSh));
+
+ if ( pDocSh->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
+ {
+ //TODO/LATER: is there a difference between the two GetVisArea methods?
+ Rectangle aVisArea = ((const SfxObjectShell*)pDocSh)->GetVisArea();
+
+ SCTAB nVisTab = pDoc->GetVisibleTab();
+ if (!pDoc->HasTable(nVisTab))
+ {
+ nVisTab = 0;
+ pDoc->SetVisibleTab(nVisTab);
+ }
+ SetTabNo( nVisTab );
+ sal_Bool bNegativePage = pDoc->IsNegativePage( nVisTab );
+ // show the right cells
+ GetViewData()->SetScreenPos( bNegativePage ? aVisArea.TopRight() : aVisArea.TopLeft() );
+
+ if ( GetViewFrame()->GetFrame().IsInPlace() ) // inplace
+ {
+ pDocSh->SetInplace( sal_True ); // schon so initialisiert
+ if (pDoc->IsEmbedded())
+ pDoc->ResetEmbedded(); // keine blaue Markierung
+ }
+ else if ( bFirstView )
+ {
+ pDocSh->SetInplace( sal_False );
+ GetViewData()->RefreshZoom(); // recalculate PPT
+ if (!pDoc->IsEmbedded())
+ pDoc->SetEmbedded( aVisArea ); // VisArea markieren
+ }
+ }
+
+ // ViewInputHandler
+ // #48721# jeder Task hat neuerdings sein eigenes InputWindow,
+ // darum muesste eigentlich entweder jeder Task seinen InputHandler bekommen,
+ // oder das InputWindow muesste sich beim App-InputHandler anmelden, wenn der
+ // Task aktiv wird, oder das InputWindow muesste sich den InputHandler selbst
+ // anlegen (dann immer ueber das InputWindow suchen, und nur wenn das nicht da
+ // ist, den InputHandler von der App nehmen).
+ // Als Sofortloesung bekommt erstmal jede View ihren Inputhandler, das gibt
+ // nur noch Probleme, wenn zwei Views in einem Task-Fenster sind.
+
+ pInputHandler = new ScInputHandler;
+
+ // Alte Version:
+ // if ( !GetViewFrame()->ISA(SfxTopViewFrame) ) // OLE oder Plug-In
+ // pInputHandler = new ScInputHandler;
+
+ // FormShell vor MakeDrawView anlegen, damit die DrawView auf jeden Fall
+ // an der FormShell angemeldet werden kann
+ // Gepusht wird die FormShell im ersten Activate
+ pFormShell = new FmFormShell(this);
+ pFormShell->SetControlActivationHandler( LINK( this, ScTabViewShell, FormControlActivated ) );
+
+ // DrawView darf nicht im TabView - ctor angelegt werden,
+ // wenn die ViewShell noch nicht kostruiert ist...
+ if (pDoc->GetDrawLayer())
+ MakeDrawView( nForceDesignMode );
+ ViewOptionsHasChanged(sal_False); // legt auch evtl. DrawView an
+
+ ::svl::IUndoManager* pMgr = pDocSh->GetUndoManager();
+ SetUndoManager( pMgr );
+ pFormShell->SetUndoManager( pMgr );
+ if ( !pDoc->IsUndoEnabled() )
+ {
+ pMgr->SetMaxUndoActionCount( 0 );
+ }
+ SetRepeatTarget( &aTarget );
+ pFormShell->SetRepeatTarget( &aTarget );
+ SetHelpId( HID_SCSHELL_TABVWSH );
+
+ if ( bFirstView ) // first view?
+ {
+ pDoc->SetDocVisible( sal_True ); // used when creating new sheets
+ if ( pDocSh->IsEmpty() )
+ {
+ // set first sheet's RTL flag (following will already be initialized because of SetDocVisible)
+ pDoc->SetLayoutRTL( 0, ScGlobal::IsSystemRTL() );
+
+ // append additional sheets (not for OLE object)
+ if ( pDocSh->GetCreateMode() != SFX_CREATE_MODE_EMBEDDED )
+ {
+ SCTAB nInitTabCount = 3; //! konfigurierbar !!!
+ for (SCTAB i=1; i<nInitTabCount; i++)
+ pDoc->MakeTable(i,false);
+ }
+
+ pDocSh->SetEmpty( sal_False ); // #i6232# make sure this is done only once
+ }
+
+ // ReadExtOptions is now in Activate
+
+ // Link-Update nicht verschachteln
+ if ( pDocSh->GetCreateMode() != SFX_CREATE_MODE_INTERNAL &&
+ pDocSh->IsUpdateEnabled() ) // #105575#; update only in the first creation of the ViewShell
+ {
+ // Check if there are any external data.
+ bool bLink = pDoc->GetExternalRefManager()->hasExternalData();
+ if (!bLink)
+ {
+ // #i100042# sheet links can still exist independently from external formula references
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount && !bLink; i++)
+ if (pDoc->IsLinked(i))
+ bLink = true;
+ }
+ if (!bLink)
+ if (pDoc->HasDdeLinks() || pDoc->HasAreaLinks())
+ bLink = sal_True;
+ if (bLink)
+ {
+ if ( !pFirst )
+ pFirst = GetViewFrame();
+
+ if(SC_MOD()->GetCurRefDlgId()==0)
+ {
+ pFirst->GetDispatcher()->Execute( SID_UPDATETABLINKS,
+ SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD );
+ }
+ }
+
+ sal_Bool bReImport = sal_False; // importierte Daten aktualisieren
+ ScDBCollection* pDBColl = pDoc->GetDBCollection();
+ if ( pDBColl )
+ {
+ sal_uInt16 nCount = pDBColl->GetCount();
+ for (sal_uInt16 i=0; i<nCount && !bReImport; i++)
+ {
+ ScDBData* pData = (*pDBColl)[i];
+ if ( pData->IsStripData() &&
+ pData->HasImportParam() && !pData->HasImportSelection() )
+ bReImport = sal_True;
+ }
+ }
+ if (bReImport)
+ {
+ if ( !pFirst )
+ pFirst = GetViewFrame();
+ if(SC_MOD()->GetCurRefDlgId()==0)
+ {
+ pFirst->GetDispatcher()->Execute( SID_REIMPORT_AFTER_LOAD,
+ SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD );
+ }
+ }
+ }
+ }
+
+ UpdateAutoFillMark();
+
+ // ScDispatchProviderInterceptor registers itself in ctor
+ xDisProvInterceptor = new ScDispatchProviderInterceptor( this );
+
+ bFirstActivate = sal_True; // NavigatorUpdate aufschieben bis Activate()
+
+ // #105575#; update only in the first creation of the ViewShell
+ pDocSh->SetUpdateEnabled(sal_False);
+
+ if ( GetViewFrame()->GetFrame().IsInPlace() )
+ UpdateHeaderWidth(); // The implace activation requires headers to be calculated
+
+ SvBorder aBorder;
+ GetBorderSize( aBorder, Size() );
+ SetBorderPixel( aBorder );
+}
+
+//------------------------------------------------------------------
+
+//UNUSED2008-05 ScTabViewShell::ScTabViewShell( SfxViewFrame* pViewFrame,
+//UNUSED2008-05 const ScTabViewShell& rWin ) :
+//UNUSED2008-05 SfxViewShell( pViewFrame, SFX_VIEW_MAXIMIZE_FIRST | SFX_VIEW_CAN_PRINT | SFX_VIEW_HAS_PRINTOPTIONS ),
+//UNUSED2008-05 ScDBFunc( &pViewFrame->GetWindow(), rWin, this ),
+//UNUSED2008-05 __INIT_ScTabViewShell
+//UNUSED2008-05 {
+//UNUSED2008-05 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScTabViewShell::ScTabViewShell" );
+//UNUSED2008-05
+//UNUSED2008-05 Construct();
+//UNUSED2008-05
+//UNUSED2008-05 UpdatePageBreakData();
+//UNUSED2008-05
+//UNUSED2008-05 /*uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface();
+//UNUSED2008-05 if (xFrame.is())
+//UNUSED2008-05 xFrame->setComponent( uno::Reference<awt::XWindow>(), new ScTabViewObj( this ) );*/
+//UNUSED2008-05 // make Controller known to SFX
+//UNUSED2008-05 new ScTabViewObj( this );
+//UNUSED2008-05
+//UNUSED2008-05 SetCurSubShell(OST_Cell);
+//UNUSED2008-05 SvBorder aBorder;
+//UNUSED2008-05 GetBorderSize( aBorder, Size() );
+//UNUSED2008-05 SetBorderPixel( aBorder );
+//UNUSED2008-05 }
+
+//------------------------------------------------------------------
+
+ScTabViewShell::ScTabViewShell( SfxViewFrame* pViewFrame,
+ SfxViewShell* pOldSh ) :
+ SfxViewShell( pViewFrame, SFX_VIEW_CAN_PRINT | SFX_VIEW_HAS_PRINTOPTIONS ),
+ ScDBFunc( &pViewFrame->GetWindow(), (ScDocShell&)*pViewFrame->GetObjectShell(), this ),
+ __INIT_ScTabViewShell
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScTabViewShell::ScTabViewShell" );
+
+ const ScAppOptions& rAppOpt = SC_MOD()->GetAppOptions();
+
+ // if switching back from print preview,
+ // restore the view settings that were active when creating the preview
+ // #89897# ReadUserData must not happen from ctor, because the view's edit window
+ // has to be shown by the sfx. ReadUserData is deferred until the first Activate call.
+ // #106334# old DesignMode state from form layer must be restored, too
+
+ sal_uInt8 nForceDesignMode = SC_FORCEMODE_NONE;
+ if ( pOldSh && pOldSh->ISA( ScPreviewShell ) )
+ {
+ ScPreviewShell* pPreviewShell = ((ScPreviewShell*)pOldSh);
+ nForceDesignMode = pPreviewShell->GetSourceDesignMode();
+ }
+
+ Construct( nForceDesignMode );
+
+ if ( GetViewData()->GetDocShell()->IsPreview() )
+ {
+ // preview for template dialog: always show whole page
+ SetZoomType( SVX_ZOOM_WHOLEPAGE, sal_True ); // zoom value is recalculated at next Resize
+ }
+ else
+ {
+ Fraction aFract( rAppOpt.GetZoom(), 100 );
+ SetZoom( aFract, aFract, sal_True );
+ SetZoomType( rAppOpt.GetZoomType(), sal_True );
+ }
+
+ /*uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface();
+ if (xFrame.is())
+ xFrame->setComponent( uno::Reference<awt::XWindow>(), new ScTabViewObj( this ) );*/
+ // make Controller known to SFX
+ new ScTabViewObj( this );
+
+ SetCurSubShell(OST_Cell);
+ SvBorder aBorder;
+ GetBorderSize( aBorder, Size() );
+ SetBorderPixel( aBorder );
+
+ // #114409#
+ MakeDrawLayer();
+}
+
+#undef __INIT_ScTabViewShell
+
+//------------------------------------------------------------------
+
+__EXPORT ScTabViewShell::~ScTabViewShell()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ EndListening(*pDocSh);
+ EndListening(*GetViewFrame());
+ EndListening(*SFX_APP()); // #i62045# #i62046# needed now - SfxViewShell no longer does it
+
+ SC_MOD()->ViewShellGone(this);
+
+ RemoveSubShell(); // alle
+ SetWindow(0);
+
+ // #54104# alles auf NULL, falls aus dem TabView-dtor noch darauf zugegriffen wird
+ //! (soll eigentlich nicht !??!?!)
+
+ DELETEZ(pFontworkBarShell);
+ DELETEZ(pExtrusionBarShell);
+ DELETEZ(pCellShell);
+ DELETEZ(pPageBreakShell);
+ DELETEZ(pDrawShell);
+ DELETEZ(pDrawFormShell);
+ DELETEZ(pOleObjectShell);
+ DELETEZ(pChartShell);
+ DELETEZ(pGraphicShell);
+ DELETEZ(pMediaShell);
+ DELETEZ(pDrawTextShell);
+ DELETEZ(pEditShell);
+ DELETEZ(pPivotShell);
+ DELETEZ(pAuditingShell);
+ DELETEZ(pCurFrameLine);
+ DELETEZ(pInputHandler);
+ DELETEZ(pPivotSource);
+ DELETEZ(pDialogDPObject);
+ DELETEZ(pNavSettings);
+
+ DELETEZ(pFormShell);
+ DELETEZ(pAccessibilityBroadcaster);
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::SetDialogDPObject( const ScDPObject* pObj )
+{
+ delete pDialogDPObject;
+ if (pObj)
+ pDialogDPObject = new ScDPObject( *pObj );
+ else
+ pDialogDPObject = NULL;
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::FillFieldData( ScHeaderFieldData& rData )
+{
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocShell->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ pDoc->GetName( nTab, rData.aTabName );
+
+ rData.aTitle = pDocShell->GetTitle();
+ const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject();
+ rData.aLongDocName = rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
+ if ( rData.aLongDocName.Len() )
+ rData.aShortDocName = rURLObj.GetName( INetURLObject::DECODE_UNAMBIGUOUS );
+ else
+ rData.aShortDocName = rData.aLongDocName = rData.aTitle;
+ rData.nPageNo = 1;
+ rData.nTotalPages = 99;
+
+ // eNumType kennt der Dialog selber
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::SetChartArea( const ScRangeListRef& rSource, const Rectangle& rDest )
+{
+ bChartAreaValid = sal_True;
+ aChartSource = rSource;
+ aChartPos = rDest;
+ nChartDestTab = GetViewData()->GetTabNo();
+}
+
+//UNUSED2008-05 void ScTabViewShell::ResetChartArea()
+//UNUSED2008-05 {
+//UNUSED2008-05 bChartAreaValid = sal_False;
+//UNUSED2008-05 }
+
+sal_Bool ScTabViewShell::GetChartArea( ScRangeListRef& rSource, Rectangle& rDest, SCTAB& rTab ) const
+{
+ rSource = aChartSource;
+ rDest = aChartPos;
+ rTab = nChartDestTab;
+ return bChartAreaValid;
+}
+
+//UNUSED2008-05 sal_Bool ScTabViewShell::IsChartDlgEdit() const
+//UNUSED2008-05 {
+//UNUSED2008-05 return bChartDlgIsEdit;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 const String& ScTabViewShell::GetEditChartName() const
+//UNUSED2008-05 {
+//UNUSED2008-05 return aEditChartName;
+//UNUSED2008-05 }
+
+ScNavigatorSettings* ScTabViewShell::GetNavigatorSettings()
+{
+ if( !pNavSettings )
+ pNavSettings = new ScNavigatorSettings;
+ return pNavSettings;
+}
+
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::ExecTbx( SfxRequest& rReq )
+{
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ sal_uInt16 nSlot = rReq.GetSlot();
+ const SfxPoolItem* pItem = NULL;
+ if ( pReqArgs )
+ pReqArgs->GetItemState( nSlot, sal_True, &pItem );
+
+ switch ( nSlot )
+ {
+ case SID_TBXCTL_INSERT:
+ if ( pItem )
+ nInsertCtrlState = ((const SfxUInt16Item*)pItem)->GetValue();
+ break;
+ case SID_TBXCTL_INSCELLS:
+ if ( pItem )
+ nInsCellsCtrlState = ((const SfxUInt16Item*)pItem)->GetValue();
+ break;
+ case SID_TBXCTL_INSOBJ:
+ if ( pItem )
+ nInsObjCtrlState = ((const SfxUInt16Item*)pItem)->GetValue();
+ break;
+ default:
+ DBG_ERROR("Slot im Wald");
+ }
+ GetViewFrame()->GetBindings().Invalidate( nSlot );
+}
+
+void ScTabViewShell::GetTbxState( SfxItemSet& rSet )
+{
+ rSet.Put( SfxUInt16Item( SID_TBXCTL_INSERT, nInsertCtrlState ) );
+ rSet.Put( SfxUInt16Item( SID_TBXCTL_INSCELLS, nInsCellsCtrlState ) );
+
+ // ohne installiertes Chart darf Chart nicht Default sein...
+ if ( nInsObjCtrlState == SID_DRAW_CHART && !SvtModuleOptions().IsChart() )
+ nInsObjCtrlState = SID_INSERT_OBJECT;
+
+ rSet.Put( SfxUInt16Item( SID_TBXCTL_INSOBJ, nInsObjCtrlState ) );
+}
+
+
+
+
+
diff --git a/sc/source/ui/view/tabvwsh5.cxx b/sc/source/ui/view/tabvwsh5.cxx
new file mode 100644
index 000000000000..406e608cff9b
--- /dev/null
+++ b/sc/source/ui/view/tabvwsh5.cxx
@@ -0,0 +1,429 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#define _ZFORLIST_DECLARE_TABLE
+#include "scitems.hxx"
+#include <svl/smplhint.hxx>
+#include <svl/zforlist.hxx>
+#include <svx/numfmtsh.hxx>
+#include <svx/numinf.hxx>
+#include <svx/svxids.hrc>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/objsh.hxx>
+
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "global.hxx"
+#include "docsh.hxx"
+#include "document.hxx"
+#include "cell.hxx"
+#include "globstr.hrc"
+#include "scmod.hxx"
+#include "uiitems.hxx"
+#include "editsh.hxx"
+#include "hints.hxx"
+
+
+//==================================================================
+
+void __EXPORT ScTabViewShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ if (rHint.ISA(SfxSimpleHint)) // ohne Parameter
+ {
+ sal_uLong nSlot = ((SfxSimpleHint&)rHint).GetId();
+ switch ( nSlot )
+ {
+ case FID_DATACHANGED:
+ UpdateFormulas();
+ break;
+
+ case FID_REFMODECHANGED:
+ {
+ sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
+ if (!bRefMode)
+ StopRefMode();
+ else
+ {
+ GetSelEngine()->Reset();
+ GetFunctionSet()->SetAnchorFlag(sal_True);
+ // AnchorFlag, damit gleich mit Control angehaengt werden kann
+ }
+ }
+ break;
+
+ case FID_KILLEDITVIEW:
+ case FID_KILLEDITVIEW_NOPAINT:
+ StopEditShell();
+ KillEditView( nSlot == FID_KILLEDITVIEW_NOPAINT );
+ break;
+
+ case SFX_HINT_DOCCHANGED:
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if (!pDoc->HasTable( GetViewData()->GetTabNo() ))
+ {
+ SetTabNo(0);
+ }
+ }
+ break;
+
+ case SC_HINT_DRWLAYER_NEW:
+ MakeDrawView();
+ break;
+
+ case SC_HINT_DOC_SAVED:
+ {
+ // beim "Save as" kann ein vorher schreibgeschuetztes Dokument
+ // bearbeitbar werden, deshalb die Layer-Locks neu (#39884#)
+ // (Invalidate etc. passiert schon vom Sfx her)
+ // #42091# bei SID_EDITDOC kommt kein SFX_HINT_TITLECHANGED, darum
+ // der eigene Hint aus DoSaveCompleted
+ //! was ist mit SFX_HINT_SAVECOMPLETED ?
+
+ UpdateLayerLocks();
+
+ // #54891# Design-Modus bei jedem Speichern anzupassen, waere zuviel
+ // (beim Speichern unter gleichem Namen soll er unveraendert bleiben)
+ // Darum nur bei SFX_HINT_MODECHANGED (vom ViewFrame)
+ }
+ break;
+
+ case SFX_HINT_MODECHANGED:
+ // #54891#/#58510# Da man sich nicht mehr darauf verlassen kann, woher
+ // dieser Hint kommt, den Design-Modus immer dann umschalten, wenn der
+ // ReadOnly-Status sich wirklich geaendert hat:
+
+ if ( GetViewData()->GetSfxDocShell()->IsReadOnly() != bReadOnly )
+ {
+ bReadOnly = GetViewData()->GetSfxDocShell()->IsReadOnly();
+
+ SfxBoolItem aItem( SID_FM_DESIGN_MODE, !bReadOnly);
+ GetViewData()->GetDispatcher().Execute( SID_FM_DESIGN_MODE, SFX_CALLMODE_ASYNCHRON,
+ &aItem, 0L );
+
+ UpdateInputContext();
+ }
+ break;
+
+ case SC_HINT_SHOWRANGEFINDER:
+ PaintRangeFinder();
+ break;
+
+ case SC_HINT_FORCESETTAB:
+ SetTabNo( GetViewData()->GetTabNo(), sal_True );
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (rHint.ISA(ScPaintHint)) // neu zeichnen
+ {
+ ScPaintHint* pHint = (ScPaintHint*) &rHint;
+ sal_uInt16 nParts = pHint->GetParts();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ if (pHint->GetStartTab() <= nTab && pHint->GetEndTab() >= nTab)
+ {
+ if (nParts & PAINT_EXTRAS) // zuerst, falls Tabelle weg ist !!!
+ if (PaintExtras())
+ nParts = PAINT_ALL;
+
+ // if the current sheet has pending row height updates (sheet links refreshed),
+ // execute them before invalidating the window
+ GetViewData()->GetDocShell()->UpdatePendingRowHeights( GetViewData()->GetTabNo() );
+
+ if (nParts & PAINT_SIZE)
+ RepeatResize(); //! InvalidateBorder ???
+ if (nParts & PAINT_GRID)
+ PaintArea( pHint->GetStartCol(), pHint->GetStartRow(),
+ pHint->GetEndCol(), pHint->GetEndRow() );
+ if (nParts & PAINT_MARKS)
+ PaintArea( pHint->GetStartCol(), pHint->GetStartRow(),
+ pHint->GetEndCol(), pHint->GetEndRow(), SC_UPDATE_MARKS );
+ if (nParts & PAINT_LEFT)
+ PaintLeftArea( pHint->GetStartRow(), pHint->GetEndRow() );
+ if (nParts & PAINT_TOP)
+ PaintTopArea( pHint->GetStartCol(), pHint->GetEndCol() );
+ if (nParts & PAINT_INVERT)
+ InvertBlockMark( pHint->GetStartCol(), pHint->GetStartRow(),
+ pHint->GetEndCol(), pHint->GetEndRow() );
+
+ // #i84689# call UpdateAllOverlays here instead of in ScTabView::PaintArea
+ if (nParts & ( PAINT_LEFT | PAINT_TOP )) // only if widths or heights changed
+ UpdateAllOverlays();
+
+ HideNoteMarker();
+ }
+ }
+ else if (rHint.ISA(ScEditViewHint)) // Edit-View anlegen
+ {
+ // ScEditViewHint kommt nur an aktiver View an
+
+ ScEditViewHint* pHint = (ScEditViewHint*) &rHint;
+ SCTAB nTab = GetViewData()->GetTabNo();
+ if ( pHint->GetTab() == nTab )
+ {
+ SCCOL nCol = pHint->GetCol();
+ SCROW nRow = pHint->GetRow();
+ {
+ HideNoteMarker();
+
+ MakeEditView( pHint->GetEngine(), nCol, nRow );
+
+ StopEditShell(); // sollte nicht gesetzt sein
+
+ ScSplitPos eActive = GetViewData()->GetActivePart();
+ if ( GetViewData()->HasEditView(eActive) )
+ {
+ // MakeEditView geht schief, wenn der Cursor ausserhalb des
+ // Bildschirms steht. GetEditView gibt dann eine nicht aktive
+ // View zurueck, darum die Abfrage HasEditView.
+
+ EditView* pView = GetViewData()->GetEditView(eActive); // ist nicht 0
+
+ SetEditShell(pView ,sal_True);
+ }
+ }
+ }
+ }
+ else if (rHint.ISA(ScTablesHint)) // Tabelle eingefuegt / geloescht
+ {
+ // aktuelle Tabelle zuerst holen (kann bei DeleteTab an ViewData geaendert werden)
+ SCTAB nActiveTab = GetViewData()->GetTabNo();
+
+ const ScTablesHint& rTabHint = (const ScTablesHint&)rHint;
+ SCTAB nTab1 = rTabHint.GetTab1();
+ SCTAB nTab2 = rTabHint.GetTab2();
+ sal_uInt16 nId = rTabHint.GetId();
+ switch (nId)
+ {
+ case SC_TAB_INSERTED:
+ GetViewData()->InsertTab( nTab1 );
+ break;
+ case SC_TAB_DELETED:
+ GetViewData()->DeleteTab( nTab1 );
+ break;
+ case SC_TAB_MOVED:
+ GetViewData()->MoveTab( nTab1, nTab2 );
+ break;
+ case SC_TAB_COPIED:
+ GetViewData()->CopyTab( nTab1, nTab2 );
+ break;
+ case SC_TAB_HIDDEN:
+ break;
+ default:
+ DBG_ERROR("unbekannter ScTablesHint");
+ }
+
+ // hier keine Abfrage auf IsActive() mehr, weil die Aktion von Basic ausgehen
+ // kann und dann auch die aktive View umgeschaltet werden muss.
+
+ SCTAB nNewTab = nActiveTab;
+ bool bStayOnActiveTab = true;
+ switch (nId)
+ {
+ case SC_TAB_INSERTED:
+ if ( nTab1 <= nNewTab ) // vorher eingefuegt
+ ++nNewTab;
+ break;
+ case SC_TAB_DELETED:
+ if ( nTab1 < nNewTab ) // vorher geloescht
+ --nNewTab;
+ else if ( nTab1 == nNewTab ) // aktuelle geloescht
+ bStayOnActiveTab = false;
+ break;
+ case SC_TAB_MOVED:
+ if ( nNewTab == nTab1 ) // verschobene Tabelle
+ nNewTab = nTab2;
+ else if ( nTab1 < nTab2 ) // nach hinten verschoben
+ {
+ if ( nNewTab > nTab1 && nNewTab <= nTab2 ) // nachrueckender Bereich
+ --nNewTab;
+ }
+ else // nach vorne verschoben
+ {
+ if ( nNewTab >= nTab2 && nNewTab < nTab1 ) // nachrueckender Bereich
+ ++nNewTab;
+ }
+ break;
+ case SC_TAB_COPIED:
+ if ( nNewTab >= nTab2 ) // vorher eingefuegt
+ ++nNewTab;
+ break;
+ case SC_TAB_HIDDEN:
+ if ( nTab1 == nNewTab ) // aktuelle ausgeblendet
+ bStayOnActiveTab = false;
+ break;
+ }
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if ( nNewTab >= pDoc->GetTableCount() )
+ nNewTab = pDoc->GetTableCount() - 1;
+
+ sal_Bool bForce = !bStayOnActiveTab;
+ SetTabNo( nNewTab, bForce, sal_False, bStayOnActiveTab );
+ }
+ else if (rHint.ISA(ScIndexHint))
+ {
+ const ScIndexHint& rIndexHint = (const ScIndexHint&)rHint;
+ sal_uInt16 nId = rIndexHint.GetId();
+ sal_uInt16 nIndex = rIndexHint.GetIndex();
+ switch (nId)
+ {
+ case SC_HINT_SHOWRANGEFINDER:
+ PaintRangeFinder( nIndex );
+ break;
+ }
+ }
+
+ SfxViewShell::Notify( rBC, rHint );
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::MakeNumberInfoItem( ScDocument* pDoc,
+ ScViewData* pViewData,
+ SvxNumberInfoItem** ppItem )
+{
+ //------------------------------
+ // NumberInfo-Item konstruieren:
+ //------------------------------
+ ScBaseCell* pCell = NULL;
+ SvxNumberValueType eValType = SVX_VALUE_TYPE_UNDEFINED;
+ double nCellValue = 0;
+ String aCellString;
+
+ pDoc->GetCell( pViewData->GetCurX(),
+ pViewData->GetCurY(),
+ pViewData->GetTabNo(),
+ pCell );
+
+ if ( pCell )
+ {
+ switch ( pCell->GetCellType() )
+ {
+ case CELLTYPE_VALUE:
+ {
+ nCellValue = ((ScValueCell*)pCell)->GetValue();
+ eValType = SVX_VALUE_TYPE_NUMBER;
+ aCellString.Erase();
+ }
+ break;
+
+ case CELLTYPE_STRING:
+ {
+ ((ScStringCell*)pCell)->GetString( aCellString );
+ eValType = SVX_VALUE_TYPE_STRING;
+ }
+ break;
+
+ case CELLTYPE_FORMULA:
+ {
+ if ( ((ScFormulaCell*)pCell)->IsValue() )
+ {
+ nCellValue = ((ScFormulaCell*)pCell)->GetValue();
+ eValType = SVX_VALUE_TYPE_NUMBER;
+ }
+ else
+ {
+ nCellValue = 0;
+ eValType = SVX_VALUE_TYPE_UNDEFINED;
+ }
+ aCellString.Erase();
+ }
+ break;
+
+ default:
+ nCellValue = 0;
+ eValType = SVX_VALUE_TYPE_UNDEFINED;
+ aCellString.Erase();
+ }
+ }
+ else // Zelle noch leer (== nicht erzeugt)
+ {
+ nCellValue = 0;
+ eValType = SVX_VALUE_TYPE_UNDEFINED;
+ aCellString.Erase();
+ }
+
+ switch ( eValType )
+ {
+ case SVX_VALUE_TYPE_STRING:
+ *ppItem = new SvxNumberInfoItem(
+ pDoc->GetFormatTable(),
+ aCellString,
+ SID_ATTR_NUMBERFORMAT_INFO );
+ break;
+
+ case SVX_VALUE_TYPE_NUMBER:
+ *ppItem = new SvxNumberInfoItem(
+ pDoc->GetFormatTable(),
+ nCellValue,
+ SID_ATTR_NUMBERFORMAT_INFO );
+ break;
+
+ case SVX_VALUE_TYPE_UNDEFINED:
+ default:
+ *ppItem = new SvxNumberInfoItem(
+ pDoc->GetFormatTable(),
+ (const sal_uInt16)
+ SID_ATTR_NUMBERFORMAT_INFO );
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::UpdateNumberFormatter(
+ ScDocument* pDoc,
+ const SvxNumberInfoItem& rInfoItem )
+{
+ const sal_uInt32 nDelCount = rInfoItem.GetDelCount();
+
+ if ( nDelCount > 0 )
+ {
+ const sal_uInt32* pDelArr = rInfoItem.GetDelArray();
+
+ for ( sal_uInt16 i=0; i<nDelCount; i++ )
+ rInfoItem.GetNumberFormatter()->DeleteEntry( pDelArr[i] );
+ }
+
+ // sollte besser UpdateNumberFormats() heissen ?
+ pDoc->DeleteNumberFormat( rInfoItem.GetDelArray(),
+ rInfoItem.GetDelCount() );
+}
+
+
+
+
+
+
diff --git a/sc/source/ui/view/tabvwsh8.cxx b/sc/source/ui/view/tabvwsh8.cxx
new file mode 100644
index 000000000000..298dbe787f0e
--- /dev/null
+++ b/sc/source/ui/view/tabvwsh8.cxx
@@ -0,0 +1,104 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/boxitem.hxx>
+
+#include "tabvwsh.hxx"
+#include "document.hxx"
+
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::SetDefaultFrameLine( const SvxBorderLine* pLine )
+{
+ if ( pLine )
+ {
+ delete pCurFrameLine;
+ pCurFrameLine = new SvxBorderLine( &pLine->GetColor(),
+ pLine->GetOutWidth(),
+ pLine->GetInWidth(),
+ pLine->GetDistance() );
+ }
+ else if ( pCurFrameLine )
+ {
+ delete pCurFrameLine;
+ pCurFrameLine = NULL;
+ }
+}
+
+//------------------------------------------------------------------
+
+sal_Bool __EXPORT ScTabViewShell::HasSelection( sal_Bool bText ) const
+{
+ sal_Bool bHas = sal_False;
+ ScViewData* pData = (ScViewData*)GetViewData(); // const weggecasted
+ if ( bText )
+ {
+ // Text enthalten: Anzahl2 >= 1
+ ScDocument* pDoc = pData->GetDocument();
+ ScMarkData& rMark = pData->GetMarkData();
+ ScAddress aCursor( pData->GetCurX(), pData->GetCurY(), pData->GetTabNo() );
+ double fVal = 0.0;
+ if ( pDoc->GetSelectionFunction( SUBTOTAL_FUNC_CNT2, aCursor, rMark, fVal ) )
+ bHas = ( fVal > 0.5 );
+ }
+ else
+ {
+ ScRange aRange;
+ ScMarkType eMarkType = pData->GetSimpleArea( aRange );
+ if ( eMarkType == SC_MARK_SIMPLE )
+ bHas = ( aRange.aStart != aRange.aEnd ); // more than 1 cell
+ else
+ bHas = sal_True; // multiple selection or filtered
+ }
+ return bHas;
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::UIDeactivated( SfxInPlaceClient* pClient )
+{
+ ClearHighlightRanges();
+
+ // Move an der ViewShell soll eigentlich vom Sfx gerufen werden, wenn sich
+ // das Frame-Window wegen unterschiedlicher Toolboxen o.ae. verschiebt
+ // (um nicht aus Versehen z.B. Zeichenobjekte zu verschieben, #56515#).
+ // Dieser Mechanismus funktioniert aber momentan nicht, darum hier der Aufruf
+ // per Hand (im Move wird verglichen, ob die Position wirklich geaendert ist).
+ ForceMove();
+ SfxViewShell::UIDeactivated( pClient );
+}
+
+
diff --git a/sc/source/ui/view/tabvwsh9.cxx b/sc/source/ui/view/tabvwsh9.cxx
new file mode 100644
index 000000000000..8ba9174a6b7a
--- /dev/null
+++ b/sc/source/ui/view/tabvwsh9.cxx
@@ -0,0 +1,295 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svx/svdmark.hxx>
+#include <svx/svdview.hxx>
+#include <svx/galbrws.hxx>
+#include <svx/gallery.hxx>
+#include <svx/hlnkitem.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svl/whiter.hxx>
+#include <avmedia/mediaplayer.hxx>
+
+#include "tabvwsh.hxx"
+#include "viewdata.hxx"
+#include "tabview.hxx"
+#include "drwlayer.hxx"
+#include "userdat.hxx"
+#include "docsh.hxx"
+
+// forwards -> galwrap.cxx (wg. CLOOKs)
+
+sal_uInt16 GallerySGA_FORMAT_GRAPHIC();
+Graphic GalleryGetGraphic ();
+sal_Bool GalleryIsLinkage ();
+String GalleryGetFullPath ();
+String GalleryGetFilterName ();
+
+// forwards -> imapwrap.cxx (wg. CLOOKs)
+
+class SvxIMapDlg;
+
+sal_uInt16 ScIMapChildWindowId();
+SvxIMapDlg* ScGetIMapDlg();
+const void* ScIMapDlgGetObj( SvxIMapDlg* pDlg );
+const ImageMap& ScIMapDlgGetMap( SvxIMapDlg* pDlg );
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::ExecChildWin(SfxRequest& rReq)
+{
+ sal_uInt16 nSlot = rReq.GetSlot();
+ switch(nSlot)
+ {
+ case SID_GALLERY:
+ {
+ SfxViewFrame* pThisFrame = GetViewFrame();
+ pThisFrame->ToggleChildWindow( GalleryChildWindow::GetChildWindowId() );
+ pThisFrame->GetBindings().Invalidate( SID_GALLERY );
+ rReq.Ignore();
+ }
+ break;
+
+ case SID_AVMEDIA_PLAYER:
+ {
+ SfxViewFrame* pThisFrame = GetViewFrame();
+ pThisFrame->ToggleChildWindow( ::avmedia::MediaPlayer::GetChildWindowId() );
+ pThisFrame->GetBindings().Invalidate( SID_AVMEDIA_PLAYER );
+ rReq.Ignore();
+ }
+ break;
+ }
+}
+
+void ScTabViewShell::GetChildWinState( SfxItemSet& rSet )
+{
+ if( SFX_ITEM_AVAILABLE == rSet.GetItemState( SID_GALLERY ) )
+ {
+ sal_uInt16 nId = GalleryChildWindow::GetChildWindowId();
+ rSet.Put( SfxBoolItem( SID_GALLERY, GetViewFrame()->HasChildWindow( nId ) ) );
+ }
+ else if( SFX_ITEM_AVAILABLE == rSet.GetItemState( SID_AVMEDIA_PLAYER ) )
+ {
+ sal_uInt16 nId = ::avmedia::MediaPlayer::GetChildWindowId();
+ rSet.Put( SfxBoolItem( SID_AVMEDIA_PLAYER, GetViewFrame()->HasChildWindow( nId ) ) );
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::ExecGallery( SfxRequest& rReq )
+{
+ const SfxItemSet* pArgs = rReq.GetArgs();
+
+ if ( pArgs )
+ {
+ const SfxPoolItem* pItem = NULL;
+ SfxItemState eState = pArgs->GetItemState(SID_GALLERY_FORMATS, sal_True, &pItem);
+ if ( eState == SFX_ITEM_SET )
+ {
+ sal_uInt32 nFormats = ((const SfxUInt32Item*)pItem)->GetValue();
+
+ /******************************************************************
+ * Graphik einfuegen
+ ******************************************************************/
+ if ( nFormats & GallerySGA_FORMAT_GRAPHIC() )
+ {
+ MakeDrawLayer();
+
+ Graphic aGraphic = GalleryGetGraphic();
+ Point aPos = GetInsertPos();
+
+ String aPath, aFilter;
+ if ( GalleryIsLinkage() ) // als Link einfuegen?
+ {
+ aPath = GalleryGetFullPath();
+ aFilter = GalleryGetFilterName();
+ }
+
+ PasteGraphic( aPos, aGraphic, aPath, aFilter );
+ }
+ else if ( nFormats & SGA_FORMAT_SOUND )
+ {
+ // #98115# for sounds (linked or not), insert a hyperlink button,
+ // like in Impress and Writer
+
+ GalleryExplorer* pGal = SVX_GALLERY();
+ if ( pGal )
+ {
+ const SfxStringItem aMediaURLItem( SID_INSERT_AVMEDIA, pGal->GetURL().GetMainURL( INetURLObject::NO_DECODE ) );
+ GetViewFrame()->GetDispatcher()->Execute( SID_INSERT_AVMEDIA, SFX_CALLMODE_SYNCHRON, &aMediaURLItem, 0L );
+ }
+ }
+ }
+ }
+}
+
+void ScTabViewShell::GetGalleryState( SfxItemSet& /* rSet */ )
+{
+}
+
+//------------------------------------------------------------------
+
+ScInputHandler* ScTabViewShell::GetInputHandler() const
+{
+ return pInputHandler;
+}
+
+//------------------------------------------------------------------
+
+String __EXPORT ScTabViewShell::GetDescription() const
+{
+ return String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(" ** Test ** "));
+}
+
+void ScTabViewShell::ExecImageMap( SfxRequest& rReq )
+{
+ sal_uInt16 nSlot = rReq.GetSlot();
+ switch(nSlot)
+ {
+ case SID_IMAP:
+ {
+ SfxViewFrame* pThisFrame = GetViewFrame();
+ sal_uInt16 nId = ScIMapChildWindowId();
+ pThisFrame->ToggleChildWindow( nId );
+ GetViewFrame()->GetBindings().Invalidate( SID_IMAP );
+
+ if ( pThisFrame->HasChildWindow( nId ) )
+ {
+ SvxIMapDlg* pDlg = ScGetIMapDlg();
+ if ( pDlg )
+ {
+ SdrView* pDrView = GetSdrView();
+ if ( pDrView )
+ {
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+ if ( rMarkList.GetMarkCount() == 1 )
+ UpdateIMap( rMarkList.GetMark( 0 )->GetMarkedSdrObj() );
+ }
+ }
+ }
+
+ rReq.Ignore();
+ }
+ break;
+
+ case SID_IMAP_EXEC:
+ {
+ SdrView* pDrView = GetSdrView();
+ SdrMark* pMark = pDrView ? pDrView->GetMarkedObjectList().GetMark(0) : 0;
+
+ if ( pMark )
+ {
+ SdrObject* pSdrObj = pMark->GetMarkedSdrObj();
+ SvxIMapDlg* pDlg = ScGetIMapDlg();
+
+ if ( ScIMapDlgGetObj(pDlg) == (void*) pSdrObj )
+ {
+ const ImageMap& rImageMap = ScIMapDlgGetMap(pDlg);
+ ScIMapInfo* pIMapInfo = ScDrawLayer::GetIMapInfo( pSdrObj );
+
+ if ( !pIMapInfo )
+ pSdrObj->InsertUserData( new ScIMapInfo( rImageMap ) );
+ else
+ pIMapInfo->SetImageMap( rImageMap );
+
+ GetViewData()->GetDocShell()->SetDrawModified();
+ }
+ }
+ }
+ break;
+ }
+}
+
+void ScTabViewShell::GetImageMapState( SfxItemSet& rSet )
+{
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case SID_IMAP:
+ {
+ // Disabled wird nicht mehr...
+
+ sal_Bool bThere = sal_False;
+ SfxViewFrame* pThisFrame = GetViewFrame();
+ sal_uInt16 nId = ScIMapChildWindowId();
+ if ( pThisFrame->KnowsChildWindow(nId) )
+ if ( pThisFrame->HasChildWindow(nId) )
+ bThere = sal_True;
+
+ ObjectSelectionType eType=GetCurObjectSelectionType();
+ sal_Bool bEnable=(eType==OST_OleObject) ||(eType==OST_Graphic);
+ if(!bThere && !bEnable)
+ {
+ rSet.DisableItem( nWhich );
+ }
+ else
+ {
+ rSet.Put( SfxBoolItem( nWhich, bThere ) );
+ }
+ }
+ break;
+
+ case SID_IMAP_EXEC:
+ {
+ sal_Bool bDisable = sal_True;
+
+ SdrView* pDrView = GetSdrView();
+ if ( pDrView )
+ {
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+ if ( rMarkList.GetMarkCount() == 1 )
+ if ( ScIMapDlgGetObj(ScGetIMapDlg()) ==
+ (void*) rMarkList.GetMark(0)->GetMarkedSdrObj() )
+ bDisable = sal_False;
+ }
+
+ rSet.Put( SfxBoolItem( SID_IMAP_EXEC, bDisable ) );
+ }
+ break;
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+
+
+
diff --git a/sc/source/ui/view/tabvwsha.cxx b/sc/source/ui/view/tabvwsha.cxx
new file mode 100644
index 000000000000..f8199100fc6d
--- /dev/null
+++ b/sc/source/ui/view/tabvwsha.cxx
@@ -0,0 +1,803 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#define _ZFORLIST_DECLARE_TABLE
+#include "scitems.hxx"
+#include <svl/stritem.hxx>
+#include <svl/whiter.hxx>
+#include <svl/zformat.hxx>
+#include <editeng/boxitem.hxx>
+#include <svx/numinf.hxx>
+#include <svl/srchitem.hxx>
+#include <svx/zoomslideritem.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/request.hxx>
+#include <vcl/msgbox.hxx>
+
+#include "global.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "document.hxx"
+#include "cell.hxx" // Input Status Edit-Zellen
+#include "globstr.hrc"
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+#include "inputwin.hxx"
+#include "docsh.hxx"
+#include "viewdata.hxx"
+//CHINA001 #include "attrdlg.hxx"
+#include "appoptio.hxx"
+#include "sc.hrc"
+#include "stlpool.hxx"
+#include "tabvwsh.hxx"
+#include "dwfunctr.hxx"
+#include "scabstdlg.hxx" //CHINA001
+#include "compiler.hxx"
+
+
+sal_Bool ScTabViewShell::GetFunction( String& rFuncStr, sal_uInt16 nErrCode )
+{
+ String aStr;
+
+ ScSubTotalFunc eFunc = (ScSubTotalFunc) SC_MOD()->GetAppOptions().GetStatusFunc();
+ ScViewData* pViewData = GetViewData();
+ ScMarkData& rMark = pViewData->GetMarkData();
+ bool bIgnoreError = (rMark.IsMarked() || rMark.IsMultiMarked());
+
+ if (bIgnoreError && (eFunc == SUBTOTAL_FUNC_CNT || eFunc == SUBTOTAL_FUNC_CNT2))
+ nErrCode = 0;
+
+ if (nErrCode)
+ {
+ rFuncStr = ScGlobal::GetLongErrorString(nErrCode);
+ return true;
+ }
+
+ sal_uInt16 nGlobStrId = 0;
+ switch (eFunc)
+ {
+ case SUBTOTAL_FUNC_AVE: nGlobStrId = STR_FUN_TEXT_AVG; break;
+ case SUBTOTAL_FUNC_CNT: nGlobStrId = STR_FUN_TEXT_COUNT; break;
+ case SUBTOTAL_FUNC_CNT2: nGlobStrId = STR_FUN_TEXT_COUNT2; break;
+ case SUBTOTAL_FUNC_MAX: nGlobStrId = STR_FUN_TEXT_MAX; break;
+ case SUBTOTAL_FUNC_MIN: nGlobStrId = STR_FUN_TEXT_MIN; break;
+ case SUBTOTAL_FUNC_SUM: nGlobStrId = STR_FUN_TEXT_SUM; break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ if (nGlobStrId)
+ {
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCCOL nPosX = pViewData->GetCurX();
+ SCROW nPosY = pViewData->GetCurY();
+ SCTAB nTab = pViewData->GetTabNo();
+
+ aStr = ScGlobal::GetRscString(nGlobStrId);
+ aStr += '=';
+
+ ScAddress aCursor( nPosX, nPosY, nTab );
+ double nVal;
+ if ( pDoc->GetSelectionFunction( eFunc, aCursor, rMark, nVal ) )
+ {
+ if ( nVal == 0.0 )
+ aStr += '0';
+ else
+ {
+ // Anzahl im Standardformat, die anderen nach Cursorposition
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ sal_uInt32 nNumFmt = 0;
+ if ( eFunc != SUBTOTAL_FUNC_CNT && eFunc != SUBTOTAL_FUNC_CNT2 )
+ {
+ // Zahlformat aus Attributen oder Formel
+ pDoc->GetNumberFormat( nPosX, nPosY, nTab, nNumFmt );
+ if ( (nNumFmt % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
+ {
+ ScBaseCell* pCell;
+ pDoc->GetCell( nPosX, nPosY, nTab, pCell );
+ if (pCell && pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+
+ nNumFmt = ((ScFormulaCell*)pCell)->GetStandardFormat(*pFormatter, nNumFmt );
+ }
+ }
+ }
+
+ String aValStr;
+ Color* pDummy;
+ pFormatter->GetOutputString( nVal, nNumFmt, aValStr, &pDummy );
+ aStr += aValStr;
+ }
+ }
+
+ rFuncStr = aStr;
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+
+
+// Funktionen, die je nach Selektion disabled sind
+// Default:
+// SID_DELETE,
+// SID_DELETE_CONTENTS,
+// FID_DELETE_CELL
+// FID_VALIDATION
+
+
+void __EXPORT ScTabViewShell::GetState( SfxItemSet& rSet )
+{
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScDocShell* pDocShell = pViewData->GetDocShell();
+ ScMarkData& rMark = pViewData->GetMarkData();
+ SCCOL nPosX = pViewData->GetCurX();
+ SCROW nPosY = pViewData->GetCurY();
+ SCTAB nTab = pViewData->GetTabNo();
+ sal_uInt16 nMyId = 0;
+
+ SfxViewFrame* pThisFrame = GetViewFrame();
+ sal_Bool bOle = GetViewFrame()->GetFrame().IsInPlace();
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case FID_CHG_COMMENT:
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScAddress aPos( nPosX, nPosY, nTab );
+ if ( pDocSh->IsReadOnly() || !pDocSh->GetChangeAction(aPos) || pDocSh->IsDocShared() )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_OPENDLG_EDIT_PRINTAREA:
+ case SID_ADD_PRINTAREA:
+ case SID_DEFINE_PRINTAREA:
+ {
+ if ( pDocShell && pDocShell->IsDocShared() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case SID_DELETE_PRINTAREA:
+ if ( nTabSelCount > 1 )
+ {
+ // #i22589# also take "Print Entire Sheet" into account here
+ sal_Bool bHas = sal_False;
+ for (SCTAB i=0; !bHas && i<nTabCount; i++)
+ bHas = rMark.GetTableSelect(i) && (pDoc->GetPrintRangeCount(i) || pDoc->IsPrintEntireSheet(i));
+ if (!bHas)
+ rSet.DisableItem( nWhich );
+ }
+ else if ( !pDoc->GetPrintRangeCount( nTab ) && !pDoc->IsPrintEntireSheet( nTab ) )
+ rSet.DisableItem( nWhich );
+ if ( pDocShell && pDocShell->IsDocShared() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_STATUS_PAGESTYLE:
+ case SID_HFEDIT:
+ GetViewData()->GetDocShell()->GetStatePageStyle( *this, rSet, nTab );
+ break;
+
+ case SID_SEARCH_ITEM:
+ rSet.Put( ScGlobal::GetSearchItem() );
+ break;
+
+ case SID_SEARCH_OPTIONS:
+ {
+ sal_uInt16 nOptions = 0xffff; // alles erlaubt
+ // wenn ReadOnly, kein Ersetzen:
+ if (GetViewData()->GetDocShell()->IsReadOnly())
+ nOptions &= ~( SEARCH_OPTIONS_REPLACE | SEARCH_OPTIONS_REPLACE_ALL );
+ rSet.Put( SfxUInt16Item( nWhich, nOptions ) );
+ }
+ break;
+
+ case SID_CURRENTCELL:
+ {
+ ScAddress aScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), 0 );
+ String aAddr;
+ aScAddress.Format( aAddr, SCA_ABS, NULL, pDoc->GetAddressConvention() );
+ SfxStringItem aPosItem( SID_CURRENTCELL, aAddr );
+
+ rSet.Put( aPosItem );
+ }
+ break;
+
+ case SID_CURRENTTAB:
+ // Tabelle fuer Basic ist 1-basiert
+ rSet.Put( SfxUInt16Item( nWhich, static_cast<sal_uInt16>(GetViewData()->GetTabNo()) + 1 ) );
+ break;
+
+ case SID_CURRENTDOC:
+ rSet.Put( SfxStringItem( nWhich, GetViewData()->GetDocShell()->GetTitle() ) );
+ break;
+
+ case FID_TOGGLEINPUTLINE:
+ {
+ sal_uInt16 nId = ScInputWindowWrapper::GetChildWindowId();
+
+ if ( pThisFrame->KnowsChildWindow( nId ) )
+ {
+ SfxChildWindow* pWnd = pThisFrame->GetChildWindow( nId );
+ rSet.Put( SfxBoolItem( nWhich, pWnd ? sal_True : sal_False ) );
+ }
+ else
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case FID_DEL_MANUALBREAKS:
+ if (!pDoc->HasManualBreaks(nTab))
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_RESET_PRINTZOOM:
+ {
+ // disablen, wenn schon Default eingestellt
+
+ String aStyleName = pDoc->GetPageStyle( nTab );
+ ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName,
+ SFX_STYLE_FAMILY_PAGE );
+ DBG_ASSERT( pStyleSheet, "PageStyle not found" );
+ if ( pStyleSheet )
+ {
+ SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
+ sal_uInt16 nScale = ((const SfxUInt16Item&)
+ rStyleSet.Get(ATTR_PAGE_SCALE)).GetValue();
+ sal_uInt16 nPages = ((const SfxUInt16Item&)
+ rStyleSet.Get(ATTR_PAGE_SCALETOPAGES)).GetValue();
+ if ( nScale == 100 && nPages == 0 )
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case FID_SCALE:
+ case SID_ATTR_ZOOM:
+ if ( bOle )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ const Fraction& rOldY = GetViewData()->GetZoomY();
+ sal_uInt16 nZoom = (sal_uInt16)(( rOldY.GetNumerator() * 100 )
+ / rOldY.GetDenominator());
+ rSet.Put( SvxZoomItem( SVX_ZOOM_PERCENT, nZoom, nWhich ) );
+ }
+ break;
+
+ case SID_ATTR_ZOOMSLIDER:
+ {
+ if ( bOle )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ const Fraction& rOldY = GetViewData()->GetZoomY();
+ sal_uInt16 nCurrentZoom = (sal_uInt16)(( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator());
+
+ if( nCurrentZoom )
+ {
+ SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM, MAXZOOM, SID_ATTR_ZOOMSLIDER );
+ aZoomSliderItem.AddSnappingPoint( 100 );
+ rSet.Put( aZoomSliderItem );
+ }
+ }
+ }
+ break;
+
+ case FID_TOGGLESYNTAX:
+ rSet.Put(SfxBoolItem(nWhich, GetViewData()->IsSyntaxMode()));
+ break;
+
+ case FID_TOGGLEHEADERS:
+ rSet.Put(SfxBoolItem(nWhich, GetViewData()->IsHeaderMode()));
+ break;
+
+ case FID_TOGGLEFORMULA:
+ {
+ const ScViewOptions& rOpts = pViewData->GetOptions();
+ sal_Bool bFormulaMode = rOpts.GetOption( VOPT_FORMULAS );
+ rSet.Put(SfxBoolItem(nWhich, bFormulaMode ));
+ }
+ break;
+
+ case FID_NORMALVIEWMODE:
+ case FID_PAGEBREAKMODE:
+ // always handle both slots - they exclude each other
+ if ( bOle )
+ {
+ rSet.DisableItem( FID_NORMALVIEWMODE );
+ rSet.DisableItem( FID_PAGEBREAKMODE );
+ }
+ else
+ {
+ rSet.Put(SfxBoolItem(FID_NORMALVIEWMODE, !GetViewData()->IsPagebreakMode()));
+ rSet.Put(SfxBoolItem(FID_PAGEBREAKMODE, GetViewData()->IsPagebreakMode()));
+ }
+ break;
+
+ case FID_FUNCTION_BOX:
+ nMyId = ScFunctionChildWindow::GetChildWindowId();
+ rSet.Put(SfxBoolItem(FID_FUNCTION_BOX, pThisFrame->HasChildWindow(nMyId)));
+ break;
+
+ case FID_PROTECT_DOC:
+ {
+ if ( pDocShell && pDocShell->IsDocShared() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ else
+ {
+ rSet.Put( SfxBoolItem( nWhich, pDoc->IsDocProtected() ) );
+ }
+ }
+ break;
+
+ case FID_PROTECT_TABLE:
+ {
+ if ( pDocShell && pDocShell->IsDocShared() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ else
+ {
+ rSet.Put( SfxBoolItem( nWhich, pDoc->IsTabProtected( nTab ) ) );
+ }
+ }
+ break;
+
+ case SID_AUTO_OUTLINE:
+ {
+ if (pDoc->GetChangeTrack()!=NULL || GetViewData()->IsMultiMarked())
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case SID_OUTLINE_DELETEALL:
+ {
+ SCTAB nOlTab = GetViewData()->GetTabNo();
+ ScOutlineTable* pOlTable = pDoc->GetOutlineTable( nOlTab );
+ if (pOlTable == NULL)
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_WINDOW_SPLIT:
+ rSet.Put(SfxBoolItem(nWhich,
+ pViewData->GetHSplitMode() == SC_SPLIT_NORMAL ||
+ pViewData->GetVSplitMode() == SC_SPLIT_NORMAL ));
+ break;
+
+ case SID_WINDOW_FIX:
+ rSet.Put(SfxBoolItem(nWhich,
+ pViewData->GetHSplitMode() == SC_SPLIT_FIX ||
+ pViewData->GetVSplitMode() == SC_SPLIT_FIX ));
+ break;
+
+ case FID_CHG_SHOW:
+ {
+ if ( pDoc->GetChangeTrack() == NULL || ( pDocShell && pDocShell->IsDocShared() ) )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+ case FID_CHG_ACCEPT:
+ {
+ rSet.Put(SfxBoolItem(FID_CHG_ACCEPT,
+ pThisFrame->HasChildWindow(FID_CHG_ACCEPT)));
+ if(pDoc->GetChangeTrack()==NULL)
+ {
+ if ( !pThisFrame->HasChildWindow(FID_CHG_ACCEPT) )
+ {
+ rSet.DisableItem( nWhich);
+ }
+ }
+ if ( pDocShell && pDocShell->IsDocShared() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case SID_FORMATPAGE:
+ //! bei geschuetzten Tabellen ???
+ if ( pDocShell && ( pDocShell->IsReadOnly() || pDocShell->IsDocShared() ) )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_PRINTPREVIEW:
+ // #58924# Toggle-Slot braucht einen State
+ rSet.Put( SfxBoolItem( nWhich, sal_False ) );
+ break;
+
+ case SID_READONLY_MODE:
+ rSet.Put( SfxBoolItem( nWhich, GetViewData()->GetDocShell()->IsReadOnly() ) );
+ break;
+
+ case FID_TAB_DESELECTALL:
+ if ( nTabSelCount == 1 )
+ rSet.DisableItem( nWhich ); // enabled only if several sheets are selected
+ break;
+
+ } // switch ( nWitch )
+ nWhich = aIter.NextWhich();
+ } // while ( nWitch )
+}
+
+//------------------------------------------------------------------
+void ScTabViewShell::ExecuteCellFormatDlg( SfxRequest& rReq, sal_uInt16 nTabPage )
+{
+ //CHINA001 ScAttrDlg* pDlg = NULL;
+ SfxAbstractTabDialog * pDlg = NULL; //CHINA001
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ SvxBoxItem aLineOuter( ATTR_BORDER );
+ SvxBoxInfoItem aLineInner( ATTR_BORDER_INNER );
+
+ SvxNumberInfoItem* pNumberInfoItem = NULL;
+ const ScPatternAttr* pOldAttrs = GetSelectionPattern();
+ SfxItemSet* pOldSet = new SfxItemSet(
+ pOldAttrs->GetItemSet() );
+
+
+ // Umrandungs-Items holen und in den Set packen:
+ GetSelectionFrame( aLineOuter, aLineInner );
+ pOldSet->Put( aLineOuter );
+ pOldSet->Put( aLineInner );
+
+ // NumberFormat Value aus Value und Language erzeugen und eintueten
+ pOldSet->Put( SfxUInt32Item( ATTR_VALUE_FORMAT,
+ pOldAttrs->GetNumberFormat( pDoc->GetFormatTable() ) ) );
+
+ MakeNumberInfoItem( pDoc, GetViewData(), &pNumberInfoItem );
+
+ pOldSet->MergeRange( SID_ATTR_NUMBERFORMAT_INFO, SID_ATTR_NUMBERFORMAT_INFO );
+ pOldSet->Put(*pNumberInfoItem );
+
+ bInFormatDialog = sal_True;
+ //CHINA001 pDlg = new ScAttrDlg( GetViewFrame(), GetDialogParent(), pOldSet );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ pDlg = pFact->CreateScAttrDlg( GetViewFrame(), GetDialogParent(), pOldSet, RID_SCDLG_ATTR);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( nTabPage != 0xffff )
+ pDlg->SetCurPageId( nTabPage );
+ short nResult = pDlg->Execute();
+ bInFormatDialog = sal_False;
+
+ if ( nResult == RET_OK )
+ {
+ const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
+
+ const SfxPoolItem* pItem=NULL;
+ if(pOutSet->GetItemState(SID_ATTR_NUMBERFORMAT_INFO,sal_True,&pItem)==SFX_ITEM_SET)
+ {
+
+ UpdateNumberFormatter( pDoc,(const SvxNumberInfoItem&)*pItem);
+ }
+
+ ApplyAttributes( pOutSet, pOldSet );
+
+ rReq.Done( *pOutSet );
+ }
+ delete pOldSet;
+ delete pNumberInfoItem;
+ delete pDlg;
+}
+
+//------------------------------------------------------------------
+
+bool ScTabViewShell::IsRefInputMode() const
+{
+ ScModule* pScMod = SC_MOD();
+ if ( pScMod )
+ {
+ if( pScMod->IsRefDialogOpen() )
+ return pScMod->IsFormulaMode();
+ if( pScMod->IsFormulaMode() )
+ {
+ ScInputHandler* pHdl = pScMod->GetInputHdl();
+ if ( pHdl )
+ {
+ String aString = pHdl->GetEditString();
+ if ( !pHdl->GetSelIsRef() && aString.Len() > 1 &&
+ ( aString.GetChar(0) == '+' || aString.GetChar(0) == '-' ) )
+ {
+ const ScViewData* pViewData = GetViewData();
+ if ( pViewData )
+ {
+ ScDocument* pDoc = pViewData->GetDocument();
+ if ( pDoc )
+ {
+ const ScAddress aPos( pViewData->GetCurPos() );
+ ScCompiler aComp( pDoc, aPos );
+ aComp.SetGrammar(pDoc->GetGrammar());
+ aComp.SetCloseBrackets( false );
+ ScTokenArray* pArr = aComp.CompileString( aString );
+ if ( pArr && pArr->MayReferenceFollow() )
+ {
+ return true;
+ }
+ }
+ }
+ }
+ else
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::ExecuteInputDirect()
+{
+ if ( !IsRefInputMode() )
+ {
+ ScModule* pScMod = SC_MOD();
+ if ( pScMod )
+ {
+ pScMod->InputEnterHandler();
+ }
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::UpdateInputHandler( sal_Bool bForce /* = sal_False */, sal_Bool bStopEditing /* = sal_True */ )
+{
+ ScInputHandler* pHdl = pInputHandler ? pInputHandler : SC_MOD()->GetInputHdl();
+
+ if ( pHdl )
+ {
+ String aString;
+ const EditTextObject* pObject = NULL;
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ CellType eType;
+ SCCOL nPosX = pViewData->GetCurX();
+ SCROW nPosY = pViewData->GetCurY();
+ SCTAB nTab = pViewData->GetTabNo();
+ SCTAB nStartTab = 0;
+ SCTAB nEndTab = 0;
+ SCCOL nStartCol = 0;
+ SCROW nStartRow = 0;
+ SCCOL nEndCol = 0;
+ SCROW nEndRow = 0;
+
+ pViewData->GetSimpleArea( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab );
+
+ PutInOrder( nStartCol, nEndCol );
+ PutInOrder( nStartRow, nEndRow );
+ PutInOrder( nStartTab, nEndTab );
+
+ sal_Bool bHideFormula = sal_False;
+ sal_Bool bHideAll = sal_False;
+
+ if (pDoc->IsTabProtected(nTab))
+ {
+ const ScProtectionAttr* pProt = (const ScProtectionAttr*)
+ pDoc->GetAttr( nPosX,nPosY,nTab,
+ ATTR_PROTECTION);
+ bHideFormula = pProt->GetHideFormula();
+ bHideAll = pProt->GetHideCell();
+ }
+
+ if (!bHideAll)
+ {
+ pDoc->GetCellType( nPosX, nPosY, nTab, eType );
+ if (eType == CELLTYPE_FORMULA)
+ {
+ if (!bHideFormula)
+ pDoc->GetFormula( nPosX, nPosY, nTab, aString );
+ }
+ else if (eType == CELLTYPE_EDIT)
+ {
+ ScBaseCell* pCell;
+ pDoc->GetCell( nPosX, nPosY, nTab, pCell );
+ ((ScEditCell*)pCell)->GetData( pObject );
+ }
+ else
+ {
+ pDoc->GetInputString( nPosX, nPosY, nTab, aString );
+ if (eType == CELLTYPE_STRING)
+ {
+ // Bei Bedarf ein ' vorneweg, damit der String nicht ungewollt
+ // als Zahl interpretiert wird, und um dem Benutzer zu zeigen,
+ // dass es ein String ist (#35060#).
+ //! Auch bei Zahlformat "Text"? -> dann beim Editieren wegnehmen
+
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ sal_uInt32 nNumFmt;
+ pDoc->GetNumberFormat( nPosX, nPosY, nTab, nNumFmt );
+ double fDummy;
+ if ( pFormatter->IsNumberFormat(aString, nNumFmt, fDummy) )
+ aString.Insert('\'',0);
+ }
+ }
+ }
+
+ ScInputHdlState aState( ScAddress( nPosX, nPosY, nTab ),
+ ScAddress( nStartCol, nStartRow, nTab ),
+ ScAddress( nEndCol, nEndRow, nTab ),
+ aString,
+ pObject );
+
+ // if using the view's local input handler, this view can always be set
+ // as current view inside NotifyChange.
+ ScTabViewShell* pSourceSh = pInputHandler ? this : NULL;
+
+ pHdl->NotifyChange( &aState, bForce, pSourceSh, bStopEditing );
+ }
+
+ SfxBindings& rBindings = GetViewFrame()->GetBindings();
+ rBindings.Invalidate( SID_STATUS_SUM ); // immer zusammen mit Eingabezeile
+ rBindings.Invalidate( SID_ATTR_SIZE );
+ rBindings.Invalidate( SID_TABLE_CELL );
+}
+
+void ScTabViewShell::UpdateInputHandlerCellAdjust( SvxCellHorJustify eJust )
+{
+ if( ScInputHandler* pHdl = pInputHandler ? pInputHandler : SC_MOD()->GetInputHdl() )
+ pHdl->UpdateCellAdjust( eJust );
+}
+
+//------------------------------------------------------------------
+
+void __EXPORT ScTabViewShell::ExecuteSave( SfxRequest& rReq )
+{
+ // nur SID_SAVEDOC / SID_SAVEASDOC
+
+ // Eingabe auf jeden Fall abschliessen, auch wenn eine Formel bearbeitet wird
+ SC_MOD()->InputEnterHandler();
+
+ if ( GetViewData()->GetDocShell()->IsDocShared() )
+ {
+ GetViewData()->GetDocShell()->SetDocumentModified();
+ }
+
+ // ansonsten normal weiter
+ GetViewData()->GetDocShell()->ExecuteSlot( rReq );
+}
+
+void __EXPORT ScTabViewShell::GetSaveState( SfxItemSet& rSet )
+{
+ SfxShell* pDocSh = GetViewData()->GetDocShell();
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while( nWhich )
+ {
+ if ( nWhich != SID_SAVEDOC || !GetViewData()->GetDocShell()->IsDocShared() )
+ {
+ // get state from DocShell
+ pDocSh->GetSlotState( nWhich, NULL, &rSet );
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::ExecDrawOpt( SfxRequest& rReq )
+{
+ ScViewOptions aViewOptions = GetViewData()->GetOptions();
+ ScGridOptions aGridOptions = aViewOptions.GetGridOptions();
+
+ SfxBindings& rBindings = GetViewFrame()->GetBindings();
+ const SfxItemSet* pArgs = rReq.GetArgs();
+ const SfxPoolItem* pItem;
+ sal_uInt16 nSlotId = rReq.GetSlot();
+ switch (nSlotId)
+ {
+ case SID_GRID_VISIBLE:
+ if ( pArgs && pArgs->GetItemState(nSlotId,sal_True,&pItem) == SFX_ITEM_SET )
+ {
+ aGridOptions.SetGridVisible( ((const SfxBoolItem*)pItem)->GetValue() );
+ aViewOptions.SetGridOptions(aGridOptions);
+ rBindings.Invalidate(SID_GRID_VISIBLE);
+ }
+ break;
+
+ case SID_GRID_USE:
+ if ( pArgs && pArgs->GetItemState(nSlotId,sal_True,&pItem) == SFX_ITEM_SET )
+ {
+ aGridOptions.SetUseGridSnap( ((const SfxBoolItem*)pItem)->GetValue() );
+ aViewOptions.SetGridOptions(aGridOptions);
+ rBindings.Invalidate(SID_GRID_USE);
+ }
+ break;
+
+ case SID_HELPLINES_MOVE:
+ if ( pArgs && pArgs->GetItemState(nSlotId,sal_True,&pItem) == SFX_ITEM_SET )
+ {
+ aViewOptions.SetOption( VOPT_HELPLINES, ((const SfxBoolItem*)pItem)->GetValue() );
+ rBindings.Invalidate(SID_HELPLINES_MOVE);
+ }
+ break;
+ }
+
+ GetViewData()->SetOptions(aViewOptions);
+}
+
+void ScTabViewShell::GetDrawOptState( SfxItemSet& rSet )
+{
+ SfxBoolItem aBool;
+
+ const ScViewOptions& rViewOptions = GetViewData()->GetOptions();
+ const ScGridOptions& rGridOptions = rViewOptions.GetGridOptions();
+
+ aBool.SetValue(rGridOptions.GetGridVisible());
+ aBool.SetWhich( SID_GRID_VISIBLE );
+ rSet.Put( aBool );
+
+ aBool.SetValue(rGridOptions.GetUseGridSnap());
+ aBool.SetWhich( SID_GRID_USE );
+ rSet.Put( aBool );
+
+ aBool.SetValue(rViewOptions.GetOption( VOPT_HELPLINES ));
+ aBool.SetWhich( SID_HELPLINES_MOVE );
+ rSet.Put( aBool );
+}
+
+
+
+
diff --git a/sc/source/ui/view/tabvwshb.cxx b/sc/source/ui/view/tabvwshb.cxx
new file mode 100644
index 000000000000..2001ba165531
--- /dev/null
+++ b/sc/source/ui/view/tabvwshb.cxx
@@ -0,0 +1,586 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
+#include <com/sun/star/chart2/data/XDataReceiver.hpp>
+
+
+
+//------------------------------------------------------------------
+
+#ifdef _MSC_VER
+#pragma optimize ("", off)
+#endif
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <com/sun/star/embed/EmbedMisc.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <sfx2/app.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <svx/svxdlg.hxx>
+#include <svx/dataaccessdescriptor.hxx>
+#include <svx/pfiledlg.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdmark.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdview.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <svx/fontworkbar.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svtools/soerr.hxx>
+#include <svl/rectitem.hxx>
+#include <svl/slstitm.hxx>
+#include <svl/whiter.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <sot/exchange.hxx>
+#include <tools/diagnose_ex.h>
+
+#include "tabvwsh.hxx"
+#include "globstr.hrc"
+#include "scmod.hxx"
+#include "document.hxx"
+#include "sc.hrc"
+#include "client.hxx"
+#include "fuinsert.hxx"
+#include "docsh.hxx"
+#include "chartarr.hxx"
+#include "drawview.hxx"
+#include "ChartRangeSelectionListener.hxx"
+
+using namespace com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+void ScTabViewShell::ConnectObject( SdrOle2Obj* pObj )
+{
+ // wird aus dem Paint gerufen
+
+ uno::Reference < embed::XEmbeddedObject > xObj = pObj->GetObjRef();
+ Window* pWin = GetActiveWin();
+
+ // #41412# wenn schon connected ist, nicht nochmal SetObjArea/SetSizeScale
+
+ SfxInPlaceClient* pClient = FindIPClient( xObj, pWin );
+ if ( !pClient )
+ {
+ pClient = new ScClient( this, pWin, GetSdrView()->GetModel(), pObj );
+ Rectangle aRect = pObj->GetLogicRect();
+ Size aDrawSize = aRect.GetSize();
+
+ Size aOleSize = pObj->GetOrigObjSize();
+
+ Fraction aScaleWidth (aDrawSize.Width(), aOleSize.Width() );
+ Fraction aScaleHeight(aDrawSize.Height(), aOleSize.Height() );
+ aScaleWidth.ReduceInaccurate(10); // kompatibel zum SdrOle2Obj
+ aScaleHeight.ReduceInaccurate(10);
+ pClient->SetSizeScale(aScaleWidth,aScaleHeight);
+
+ // sichtbarer Ausschnitt wird nur inplace veraendert!
+ // the object area must be set after the scaling since it triggers the resizing
+ aRect.SetSize( aOleSize );
+ pClient->SetObjArea( aRect );
+
+ ((ScClient*)pClient)->SetGrafEdit( NULL );
+ }
+}
+
+sal_Bool ScTabViewShell::ActivateObject( SdrOle2Obj* pObj, long nVerb )
+{
+ // #41081# Gueltigkeits-Hinweisfenster nicht ueber dem Objekt stehenlassen
+ RemoveHintWindow();
+
+ uno::Reference < embed::XEmbeddedObject > xObj = pObj->GetObjRef();
+ Window* pWin = GetActiveWin();
+ ErrCode nErr = ERRCODE_NONE;
+ sal_Bool bErrorShown = sal_False;
+
+ // linked objects aren't supported
+// if ( xIPObj->IsLink() )
+// nErr = xIPObj->DoVerb(nVerb); // gelinkt -> ohne Client etc.
+// else
+ {
+ SfxInPlaceClient* pClient = FindIPClient( xObj, pWin );
+ if ( !pClient )
+ pClient = new ScClient( this, pWin, GetSdrView()->GetModel(), pObj );
+
+ if ( !(nErr & ERRCODE_ERROR_MASK) && xObj.is() )
+ {
+ Rectangle aRect = pObj->GetLogicRect();
+ Size aDrawSize = aRect.GetSize();
+
+ MapMode aMapMode( MAP_100TH_MM );
+ Size aOleSize = pObj->GetOrigObjSize( &aMapMode );
+
+ if ( pClient->GetAspect() != embed::Aspects::MSOLE_ICON
+ && ( xObj->getStatus( pClient->GetAspect() ) & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE ) )
+ {
+ // scale must always be 1 - change VisArea if different from client size
+
+ if ( aDrawSize != aOleSize )
+ {
+ MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( pClient->GetAspect() ) );
+ aOleSize = OutputDevice::LogicToLogic( aDrawSize,
+ MAP_100TH_MM, aUnit );
+ awt::Size aSz( aOleSize.Width(), aOleSize.Height() );
+ xObj->setVisualAreaSize( pClient->GetAspect(), aSz );
+ }
+ Fraction aOne( 1, 1 );
+ pClient->SetSizeScale( aOne, aOne );
+ }
+ else
+ {
+ // calculate scale from client and VisArea size
+
+ Fraction aScaleWidth (aDrawSize.Width(), aOleSize.Width() );
+ Fraction aScaleHeight(aDrawSize.Height(), aOleSize.Height() );
+ aScaleWidth.ReduceInaccurate(10); // kompatibel zum SdrOle2Obj
+ aScaleHeight.ReduceInaccurate(10);
+ pClient->SetSizeScale(aScaleWidth,aScaleHeight);
+ }
+
+ // sichtbarer Ausschnitt wird nur inplace veraendert!
+ // the object area must be set after the scaling since it triggers the resizing
+ aRect.SetSize( aOleSize );
+ pClient->SetObjArea( aRect );
+
+ ((ScClient*)pClient)->SetGrafEdit( NULL );
+
+ nErr = pClient->DoVerb( nVerb );
+ bErrorShown = sal_True;
+ // SfxViewShell::DoVerb zeigt seine Fehlermeldungen selber an
+
+ // attach listener to selection changes in chart that affect cell
+ // ranges, so those can be highlighted
+ // note: do that after DoVerb, so that the chart controller exists
+ if ( SvtModuleOptions().IsChart() )
+ {
+ SvGlobalName aObjClsId ( xObj->getClassID() );
+ if (SotExchange::IsChart( aObjClsId ))
+ {
+ try
+ {
+ uno::Reference < embed::XComponentSupplier > xSup( xObj, uno::UNO_QUERY_THROW );
+ uno::Reference< chart2::data::XDataReceiver > xDataReceiver(
+ xSup->getComponent(), uno::UNO_QUERY_THROW );
+ uno::Reference< chart2::data::XRangeHighlighter > xRangeHightlighter(
+ xDataReceiver->getRangeHighlighter());
+ if( xRangeHightlighter.is())
+ {
+ uno::Reference< view::XSelectionChangeListener > xListener(
+ new ScChartRangeSelectionListener( this ));
+ xRangeHightlighter->addSelectionChangeListener( xListener );
+ }
+ }
+ catch( const uno::Exception & )
+ {
+ DBG_ERROR( "Exception caught while querying chart" );
+ }
+ }
+ }
+ }
+ }
+ if (nErr != ERRCODE_NONE && !bErrorShown)
+ ErrorHandler::HandleError(nErr);
+
+ //! SetDocumentName sollte schon im Sfx passieren ???
+ //TODO/LATER: how "SetDocumentName"?
+ //xIPObj->SetDocumentName( GetViewData()->GetDocShell()->GetTitle() );
+
+ return ( !(nErr & ERRCODE_ERROR_MASK) );
+}
+
+ErrCode __EXPORT ScTabViewShell::DoVerb(long nVerb)
+{
+ SdrView* pView = GetSdrView();
+ if (!pView)
+ return ERRCODE_SO_NOTIMPL; // soll nicht sein
+
+ SdrOle2Obj* pOle2Obj = NULL;
+ SdrGrafObj* pGrafObj = NULL;
+ SdrObject* pObj = NULL;
+ ErrCode nErr = ERRCODE_NONE;
+
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ if (pObj->GetObjIdentifier() == OBJ_OLE2)
+ pOle2Obj = (SdrOle2Obj*) pObj;
+ else if (pObj->GetObjIdentifier() == OBJ_GRAF)
+ {
+ pGrafObj = (SdrGrafObj*) pObj;
+ }
+ }
+
+ if (pOle2Obj)
+ {
+ ActivateObject( pOle2Obj, nVerb );
+ }
+ else
+ {
+ DBG_ERROR("kein Objekt fuer Verb gefunden");
+ }
+
+ return nErr;
+}
+
+void ScTabViewShell::DeactivateOle()
+{
+ // deactivate inplace editing if currently active
+
+ ScModule* pScMod = SC_MOD();
+ bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF;
+
+ ScClient* pClient = (ScClient*) GetIPClient();
+ if ( pClient && pClient->IsObjectInPlaceActive() && !bUnoRefDialog )
+ pClient->DeactivateObject();
+}
+
+void ScTabViewShell::ExecDrawIns(SfxRequest& rReq)
+{
+ sal_uInt16 nSlot = rReq.GetSlot();
+ if (nSlot != SID_OBJECTRESIZE )
+ {
+ SC_MOD()->InputEnterHandler();
+ UpdateInputHandler();
+ }
+
+ // Rahmen fuer Chart einfuegen wird abgebrochen:
+ FuPoor* pPoor = GetDrawFuncPtr();
+ if ( pPoor && pPoor->GetSlotID() == SID_DRAW_CHART )
+ GetViewData()->GetDispatcher().Execute(SID_DRAW_CHART, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
+
+ MakeDrawLayer();
+
+ SfxBindings& rBindings = GetViewFrame()->GetBindings();
+ ScTabView* pTabView = GetViewData()->GetView();
+ Window* pWin = pTabView->GetActiveWin();
+ ScDrawView* pView = pTabView->GetScDrawView();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+// SdrModel* pDrModel = pDocSh->MakeDrawLayer();
+ SdrModel* pDrModel = pView->GetModel();
+
+ switch ( nSlot )
+ {
+ case SID_INSERT_GRAPHIC:
+ FuInsertGraphic(this, pWin, pView, pDrModel, rReq);
+ // shell is set in MarkListHasChanged
+ break;
+
+ case SID_INSERT_AVMEDIA:
+ FuInsertMedia(this, pWin, pView, pDrModel, rReq);
+ // shell is set in MarkListHasChanged
+ break;
+
+ case SID_INSERT_DIAGRAM:
+ FuInsertChart(this, pWin, pView, pDrModel, rReq);
+//? SC_MOD()->SetFunctionDlg( NULL );//XXX
+ break;
+
+ case SID_INSERT_OBJECT:
+ case SID_INSERT_PLUGIN:
+ case SID_INSERT_SOUND:
+ case SID_INSERT_VIDEO:
+ case SID_INSERT_SMATH:
+ case SID_INSERT_FLOATINGFRAME:
+ FuInsertOLE(this, pWin, pView, pDrModel, rReq);
+ break;
+
+ case SID_OBJECTRESIZE:
+ {
+ // Der Server moechte die Clientgrosse verandern
+
+ SfxInPlaceClient* pClient = GetIPClient();
+
+ if ( pClient && pClient->IsObjectInPlaceActive() )
+ {
+ const SfxRectangleItem& rRect =
+ (SfxRectangleItem&)rReq.GetArgs()->Get(SID_OBJECTRESIZE);
+ Rectangle aRect( pWin->PixelToLogic( rRect.GetValue() ) );
+
+ if ( pView->AreObjectsMarked() )
+ {
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ SdrMark* pMark = rMarkList.GetMark(0);
+ SdrObject* pObj = pMark->GetMarkedSdrObj();
+
+ sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier();
+
+ if (nSdrObjKind == OBJ_OLE2)
+ {
+ if ( ( (SdrOle2Obj*) pObj)->GetObjRef().is() )
+ {
+ pObj->SetLogicRect(aRect);
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case SID_LINKS:
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ SfxAbstractLinksDialog* pDlg = pFact->CreateLinksDialog( pWin, pDoc->GetLinkManager() );
+ if ( pDlg )
+ {
+ pDlg->Execute();
+ rBindings.Invalidate( nSlot );
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); // Navigator
+ rReq.Done();
+ }
+ }
+ break;
+
+ // #98721#
+ case SID_FM_CREATE_FIELDCONTROL:
+ {
+ SFX_REQUEST_ARG( rReq, pDescriptorItem, SfxUnoAnyItem, SID_FM_DATACCESS_DESCRIPTOR, sal_False );
+ DBG_ASSERT( pDescriptorItem, "SID_FM_CREATE_FIELDCONTROL: invalid request args!" );
+
+ if(pDescriptorItem)
+ {
+ //! merge with ScViewFunc::PasteDataFormat (SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE)?
+
+ ScDrawView* pDrView = GetScDrawView();
+ SdrPageView* pPageView = pDrView ? pDrView->GetSdrPageView() : NULL;
+ if(pPageView)
+ {
+ ::svx::ODataAccessDescriptor aDescriptor(pDescriptorItem->GetValue());
+ SdrObject* pNewDBField = pDrView->CreateFieldControl(aDescriptor);
+
+ if(pNewDBField)
+ {
+ Rectangle aVisArea = pWin->PixelToLogic(Rectangle(Point(0,0), pWin->GetOutputSizePixel()));
+ Point aObjPos(aVisArea.Center());
+ Size aObjSize(pNewDBField->GetLogicRect().GetSize());
+ aObjPos.X() -= aObjSize.Width() / 2;
+ aObjPos.Y() -= aObjSize.Height() / 2;
+ Rectangle aNewObjectRectangle(aObjPos, aObjSize);
+
+ pNewDBField->SetLogicRect(aNewObjectRectangle);
+
+ // controls must be on control layer, groups on front layer
+ if ( pNewDBField->ISA(SdrUnoObj) )
+ pNewDBField->NbcSetLayer(SC_LAYER_CONTROLS);
+ else
+ pNewDBField->NbcSetLayer(SC_LAYER_FRONT);
+ if (pNewDBField->ISA(SdrObjGroup))
+ {
+ SdrObjListIter aIter( *pNewDBField, IM_DEEPWITHGROUPS );
+ SdrObject* pSubObj = aIter.Next();
+ while (pSubObj)
+ {
+ if ( pSubObj->ISA(SdrUnoObj) )
+ pSubObj->NbcSetLayer(SC_LAYER_CONTROLS);
+ else
+ pSubObj->NbcSetLayer(SC_LAYER_FRONT);
+ pSubObj = aIter.Next();
+ }
+ }
+
+ pView->InsertObjectAtView(pNewDBField, *pPageView);
+ }
+ }
+ }
+ rReq.Done();
+ }
+ break;
+
+ case SID_FONTWORK_GALLERY_FLOATER:
+ svx::FontworkBar::execute( pView, rReq, GetViewFrame()->GetBindings() );
+ rReq.Ignore();
+ break;
+ }
+}
+
+void ScTabViewShell::GetDrawInsState(SfxItemSet &rSet)
+{
+ sal_Bool bOle = GetViewFrame()->GetFrame().IsInPlace();
+ sal_Bool bTabProt = GetViewData()->GetDocument()->IsTabProtected(GetViewData()->GetTabNo());
+ ScDocShell* pDocShell = ( GetViewData() ? GetViewData()->GetDocShell() : NULL );
+ bool bShared = ( pDocShell ? pDocShell->IsDocShared() : false );
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+ case SID_INSERT_DIAGRAM:
+ if ( bOle || bTabProt || !SvtModuleOptions().IsChart() || bShared )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_INSERT_SMATH:
+ if ( bOle || bTabProt || !SvtModuleOptions().IsMath() || bShared )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_INSERT_OBJECT:
+ case SID_INSERT_PLUGIN:
+ case SID_INSERT_FLOATINGFRAME:
+ if ( bOle || bTabProt || bShared )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_INSERT_SOUND:
+ case SID_INSERT_VIDEO:
+ /* #i102735# discussed with NN: removed for performance reasons
+ || !SvxPluginFileDlg::IsAvailable(nWhich)
+ */
+ if ( bOle || bTabProt || bShared )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_INSERT_GRAPHIC:
+ case SID_INSERT_AVMEDIA:
+ case SID_FONTWORK_GALLERY_FLOATER:
+ if ( bTabProt || bShared )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case SID_LINKS:
+ {
+ if (GetViewData()->GetDocument()->GetLinkManager()->GetLinks().Count() == 0 )
+ rSet.DisableItem( SID_LINKS );
+ }
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::ExecuteUndo(SfxRequest& rReq)
+{
+ SfxShell* pSh = GetViewData()->GetDispatcher().GetShell(0);
+ ::svl::IUndoManager* pUndoManager = pSh->GetUndoManager();
+
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+
+ sal_uInt16 nSlot = rReq.GetSlot();
+ switch ( nSlot )
+ {
+ case SID_UNDO:
+ case SID_REDO:
+ if ( pUndoManager )
+ {
+ sal_Bool bIsUndo = ( nSlot == SID_UNDO );
+
+ sal_uInt16 nCount = 1;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && pReqArgs->GetItemState( nSlot, sal_True, &pItem ) == SFX_ITEM_SET )
+ nCount = ((const SfxUInt16Item*)pItem)->GetValue();
+
+ // lock paint for more than one cell undo action (not for editing within a cell)
+ sal_Bool bLockPaint = ( nCount > 1 && pUndoManager == GetUndoManager() );
+ if ( bLockPaint )
+ pDocSh->LockPaint();
+
+ try
+ {
+ for (sal_uInt16 i=0; i<nCount; i++)
+ {
+ if ( bIsUndo )
+ pUndoManager->Undo();
+ else
+ pUndoManager->Redo();
+ }
+ }
+ catch ( const uno::Exception& )
+ {
+ // no need to handle. By definition, the UndoManager handled this by clearing the
+ // Undo/Redo stacks
+ }
+
+ if ( bLockPaint )
+ pDocSh->UnlockPaint();
+
+ GetViewFrame()->GetBindings().InvalidateAll(sal_False);
+ }
+ break;
+// default:
+// GetViewFrame()->ExecuteSlot( rReq );
+ }
+}
+
+void ScTabViewShell::GetUndoState(SfxItemSet &rSet)
+{
+ SfxShell* pSh = GetViewData()->GetDispatcher().GetShell(0);
+ ::svl::IUndoManager* pUndoManager = pSh->GetUndoManager();
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch (nWhich)
+ {
+ case SID_GETUNDOSTRINGS:
+ case SID_GETREDOSTRINGS:
+ {
+ SfxStringListItem aStrLst( nWhich );
+ if ( pUndoManager )
+ {
+ List* pList = aStrLst.GetList();
+ sal_Bool bIsUndo = ( nWhich == SID_GETUNDOSTRINGS );
+ size_t nCount = bIsUndo ? pUndoManager->GetUndoActionCount() : pUndoManager->GetRedoActionCount();
+ for (size_t i=0; i<nCount; i++)
+ pList->Insert( new String( bIsUndo ? pUndoManager->GetUndoActionComment(i) :
+ pUndoManager->GetRedoActionComment(i) ),
+ LIST_APPEND );
+ }
+ rSet.Put( aStrLst );
+ }
+ break;
+ default:
+ // get state from sfx view frame
+ GetViewFrame()->GetSlotState( nWhich, NULL, &rSet );
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+
+
diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx
new file mode 100644
index 000000000000..2e829d83e07d
--- /dev/null
+++ b/sc/source/ui/view/tabvwshc.cxx
@@ -0,0 +1,327 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+// INCLUDE ---------------------------------------------------------------
+#include "scitems.hxx"
+#include <vcl/msgbox.hxx>
+#include <sfx2/childwin.hxx>
+#include <sfx2/dispatch.hxx>
+
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "scmod.hxx"
+#include "docsh.hxx"
+#include "document.hxx"
+#include "uiitems.hxx"
+#include "pivot.hxx"
+#include "namedlg.hxx"
+#include "solvrdlg.hxx"
+#include "optsolver.hxx"
+#include "tabopdlg.hxx"
+#include "autoform.hxx" // Core
+#include "autofmt.hxx" // Dialog
+#include "consdlg.hxx"
+//CHINA001 #include "sortdlg.hxx"
+#include "filtdlg.hxx"
+#include "dbnamdlg.hxx"
+#include "pvlaydlg.hxx"
+#include "areasdlg.hxx"
+#include "condfrmt.hxx"
+#include "rangeutl.hxx"
+#include "crnrdlg.hxx"
+#include "formula.hxx"
+#include "cell.hxx" // Input Status Edit-Zellen
+#include "acredlin.hxx"
+#include "highred.hxx"
+#include "simpref.hxx"
+#include "funcdesc.hxx"
+#include "dpobject.hxx"
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::SetCurRefDlgId( sal_uInt16 nNew )
+{
+ // CurRefDlgId is stored in ScModule to find if a ref dialog is open,
+ // and in the view to identify the view that has opened the dialog
+ nCurRefDlgId = nNew;
+}
+
+SfxModelessDialog* ScTabViewShell::CreateRefDialog(
+ SfxBindings* pB, SfxChildWindow* pCW, SfxChildWinInfo* pInfo,
+ Window* pParent, sal_uInt16 nSlotId )
+{
+ // Dialog nur aufmachen, wenn ueber ScModule::SetRefDialog gerufen, damit
+ // z.B. nach einem Absturz offene Ref-Dialoge nicht wiederkommen (#42341#).
+
+ if ( SC_MOD()->GetCurRefDlgId() != nSlotId )
+ return NULL;
+
+ if ( nCurRefDlgId != nSlotId )
+ {
+ // the dialog has been opened in a different view
+ // -> lock the dispatcher for this view (modal mode)
+
+ GetViewData()->GetDispatcher().Lock( sal_True ); // lock is reset when closing dialog
+ return NULL;
+ }
+
+ SfxModelessDialog* pResult = 0;
+
+ if(pCW)
+ pCW->SetHideNotDelete(sal_True);
+
+ switch( nSlotId )
+ {
+ case FID_DEFINE_NAME:
+ pResult = new ScNameDlg( pB, pCW, pParent, GetViewData(),
+ ScAddress( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(),
+ GetViewData()->GetTabNo() ) );
+ break;
+
+ case SID_DEFINE_COLROWNAMERANGES:
+ {
+ pResult = new ScColRowNameRangesDlg( pB, pCW, pParent, GetViewData() );
+ }
+ break;
+
+ case SID_OPENDLG_CONSOLIDATE:
+ {
+ SfxItemSet aArgSet( GetPool(),
+ SCITEM_CONSOLIDATEDATA,
+ SCITEM_CONSOLIDATEDATA );
+
+ const ScConsolidateParam* pDlgData =
+ GetViewData()->GetDocument()->GetConsolidateDlgData();
+
+ if ( !pDlgData )
+ {
+ ScConsolidateParam aConsParam;
+ SCCOL nStartCol, nEndCol;
+ SCROW nStartRow, nEndRow;
+ SCTAB nStartTab, nEndTab;
+
+ GetViewData()->GetSimpleArea( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab );
+
+ PutInOrder( nStartCol, nEndCol );
+ PutInOrder( nStartRow, nEndRow );
+ PutInOrder( nStartTab, nEndTab );
+
+ aConsParam.nCol = nStartCol;
+ aConsParam.nRow = nStartRow;
+ aConsParam.nTab = nStartTab;
+
+ aArgSet.Put( ScConsolidateItem( SCITEM_CONSOLIDATEDATA,
+ &aConsParam ) );
+ }
+ else
+ {
+ aArgSet.Put( ScConsolidateItem( SCITEM_CONSOLIDATEDATA, pDlgData ) );
+ }
+ pResult = new ScConsolidateDlg( pB, pCW, pParent, aArgSet );
+ }
+ break;
+
+ case SID_DEFINE_DBNAME:
+ {
+ // wenn auf einem bestehenden Bereich aufgerufen, den markieren
+ GetDBData( sal_True, SC_DB_OLD );
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
+ MarkDataArea( sal_False );
+
+ pResult = new ScDbNameDlg( pB, pCW, pParent, GetViewData() );
+ }
+ break;
+
+ case SID_SPECIAL_FILTER:
+ {
+ ScQueryParam aQueryParam;
+ SfxItemSet aArgSet( GetPool(),
+ SCITEM_QUERYDATA,
+ SCITEM_QUERYDATA );
+
+ ScDBData* pDBData = GetDBData( sal_True, SC_DB_MAKE, SC_DBSEL_ROW_DOWN);
+ pDBData->GetQueryParam( aQueryParam );
+
+ ScQueryItem aItem( SCITEM_QUERYDATA, GetViewData(), &aQueryParam );
+ ScRange aAdvSource;
+ if (pDBData->GetAdvancedQuerySource(aAdvSource))
+ aItem.SetAdvancedQuerySource( &aAdvSource );
+
+ aArgSet.Put( aItem );
+
+ // aktuelle Tabelle merken (wg. RefInput im Dialog)
+ GetViewData()->SetRefTabNo( GetViewData()->GetTabNo() );
+
+ pResult = new ScSpecialFilterDlg( pB, pCW, pParent, aArgSet );
+ }
+ break;
+
+ case SID_FILTER:
+ {
+
+ ScQueryParam aQueryParam;
+ SfxItemSet aArgSet( GetPool(),
+ SCITEM_QUERYDATA,
+ SCITEM_QUERYDATA );
+
+ ScDBData* pDBData = GetDBData( sal_True, SC_DB_MAKE, SC_DBSEL_ROW_DOWN);
+ pDBData->GetQueryParam( aQueryParam );
+
+ aArgSet.Put( ScQueryItem( SCITEM_QUERYDATA,
+ GetViewData(),
+ &aQueryParam ) );
+
+ // aktuelle Tabelle merken (wg. RefInput im Dialog)
+ GetViewData()->SetRefTabNo( GetViewData()->GetTabNo() );
+
+ pResult = new ScFilterDlg( pB, pCW, pParent, aArgSet );
+ }
+ break;
+
+ case SID_OPENDLG_TABOP:
+ {
+ ScViewData* pViewData = GetViewData();
+ ScRefAddress aCurPos ( pViewData->GetCurX(),
+ pViewData->GetCurY(),
+ pViewData->GetTabNo(),
+ sal_False, sal_False, sal_False );
+
+ pResult = new ScTabOpDlg( pB, pCW, pParent, pViewData->GetDocument(), aCurPos );
+ }
+ break;
+
+ case SID_OPENDLG_SOLVE:
+ {
+ ScViewData* pViewData = GetViewData();
+ ScAddress aCurPos( pViewData->GetCurX(),
+ pViewData->GetCurY(),
+ pViewData->GetTabNo());
+ pResult = new ScSolverDlg( pB, pCW, pParent, pViewData->GetDocument(), aCurPos );
+ }
+ break;
+
+ case SID_OPENDLG_OPTSOLVER:
+ {
+ ScViewData* pViewData = GetViewData();
+ ScAddress aCurPos( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo());
+ pResult = new ScOptSolverDlg( pB, pCW, pParent, pViewData->GetDocShell(), aCurPos );
+ }
+ break;
+
+ case SID_OPENDLG_PIVOTTABLE:
+ {
+ // all settings must be in pDialogDPObject
+
+ if( pDialogDPObject )
+ {
+ GetViewData()->SetRefTabNo( GetViewData()->GetTabNo() );
+ pResult = new ScDPLayoutDlg( pB, pCW, pParent, *pDialogDPObject );
+ }
+ }
+ break;
+
+ case SID_OPENDLG_EDIT_PRINTAREA:
+ {
+ pResult = new ScPrintAreasDlg( pB, pCW, pParent );
+ }
+ break;
+
+ case SID_OPENDLG_CONDFRMT:
+ {
+ ScViewData* pViewData = GetViewData();
+
+ ScDocument* pDoc = pViewData->GetDocument();
+ const ScConditionalFormat* pForm = pDoc->GetCondFormat(
+ pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() );
+
+ // aktuelle Tabelle merken (wg. RefInput im Dialog)
+ pViewData->SetRefTabNo( pViewData->GetTabNo() );
+
+ pResult = new ScConditionalFormatDlg( pB, pCW, pParent, pDoc, pForm );
+ }
+ break;
+
+ case SID_OPENDLG_FUNCTION:
+ {
+ // Dialog schaut selber, was in der Zelle steht
+
+ pResult = new ScFormulaDlg( pB, pCW, pParent, GetViewData(),ScGlobal::GetStarCalcFunctionMgr() );
+ }
+ break;
+
+ case FID_CHG_SHOW:
+ {
+ // Dialog schaut selber, was in der Zelle steht
+
+ pResult = new ScHighlightChgDlg( pB, pCW, pParent, GetViewData() );
+ }
+ break;
+
+ case WID_SIMPLE_REF:
+ {
+ // Dialog schaut selber, was in der Zelle steht
+
+ ScViewData* pViewData = GetViewData();
+ pViewData->SetRefTabNo( pViewData->GetTabNo() );
+ pResult = new ScSimpleRefDlg( pB, pCW, pParent, pViewData );
+ }
+ break;
+
+
+ default:
+ DBG_ERROR( "ScTabViewShell::CreateRefDialog: unbekannte ID" );
+ break;
+ }
+
+ if (pResult)
+ {
+ // Die Dialoge gehen immer mit eingeklapptem Zusaetze-Button auf,
+ // darum muss die Groesse ueber das Initialize gerettet werden
+ // (oder den Zusaetze-Status mit speichern !!!)
+
+ Size aSize = pResult->GetSizePixel();
+ pResult->Initialize( pInfo );
+ pResult->SetSizePixel(aSize);
+ }
+
+ return pResult;
+}
+
+
+
diff --git a/sc/source/ui/view/tabvwshd.cxx b/sc/source/ui/view/tabvwshd.cxx
new file mode 100644
index 000000000000..d0eeee22fbf7
--- /dev/null
+++ b/sc/source/ui/view/tabvwshd.cxx
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+#ifdef _MSC_VER
+#pragma optimize ("", off)
+#endif
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <sfx2/childwin.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+
+#include "tabvwsh.hxx"
+#include "global.hxx"
+#include "scmod.hxx"
+#include "docsh.hxx"
+#include "sc.hrc"
+
+
+// STATIC DATA -----------------------------------------------------------
+
+//------------------------------------------------------------------
+
+#define IS_AVAILABLE(WhichId,ppItem) \
+ (pReqArgs->GetItemState((WhichId), sal_True, ppItem ) == SFX_ITEM_SET)
+
+//! Parent-Window fuer Dialoge
+//! Problem: OLE Server!
+
+Window* ScTabViewShell::GetDialogParent()
+{
+ // #95513# if a ref-input dialog is open, use it as parent
+ // (necessary when a slot is executed from the dialog's OK handler)
+ if ( nCurRefDlgId && nCurRefDlgId == SC_MOD()->GetCurRefDlgId() )
+ {
+ SfxViewFrame* pViewFrm = GetViewFrame();
+ if ( pViewFrm->HasChildWindow(nCurRefDlgId) )
+ {
+ SfxChildWindow* pChild = pViewFrm->GetChildWindow(nCurRefDlgId);
+ if (pChild)
+ {
+ Window* pWin = pChild->GetWindow();
+ if (pWin && pWin->IsVisible())
+ return pWin;
+ }
+ }
+ }
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ if ( pDocSh->IsOle() )
+ {
+ //TODO/LATER: how to GetEditWindow in embedded document?!
+ //It should be OK to return the VieShell Window!
+ return GetWindow();
+ //SvInPlaceEnvironment* pEnv = pDocSh->GetIPEnv();
+ //if (pEnv)
+ // return pEnv->GetEditWin();
+ }
+
+ return GetActiveWin(); // for normal views, too
+}
+
+
+
+
+
diff --git a/sc/source/ui/view/tabvwshe.cxx b/sc/source/ui/view/tabvwshe.cxx
new file mode 100644
index 000000000000..0784d3143202
--- /dev/null
+++ b/sc/source/ui/view/tabvwshe.cxx
@@ -0,0 +1,343 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include <editeng/eeitem.hxx>
+
+#include "scitems.hxx"
+#include <editeng/editview.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/hlnkitem.hxx>
+#include <svl/srchitem.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/objface.hxx>
+#include <svl/stritem.hxx>
+#include <vcl/sound.hxx>
+
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "scmod.hxx"
+#include "impex.hxx"
+#include "editsh.hxx"
+#include "dociter.hxx"
+#include "inputhdl.hxx"
+#include "document.hxx"
+
+//==================================================================
+
+String __EXPORT ScTabViewShell::GetSelectionText( sal_Bool bWholeWord )
+{
+ String aStrSelection;
+
+ if ( pEditShell && pEditShell == GetMySubShell() )
+ {
+ aStrSelection = pEditShell->GetSelectionText( bWholeWord );
+ }
+ else
+ {
+ ScRange aRange;
+
+ if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if ( bInFormatDialog && aRange.aStart.Row() != aRange.aEnd.Row() )
+ {
+ // Range auf eine Datenzeile begrenzen
+ // (#48613# nur wenn der Aufruf aus einem Format-Dialog kommt)
+ ScHorizontalCellIterator aIter( pDoc, aRange.aStart.Tab(),
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row() );
+ SCCOL nCol;
+ SCROW nRow;
+ if ( aIter.GetNext( nCol, nRow ) )
+ {
+ aRange.aStart.SetCol( nCol );
+ aRange.aStart.SetRow( nRow );
+ aRange.aEnd.SetRow( nRow );
+ }
+ 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);
+ bool bShrunk;
+ pDoc->ShrinkToUsedDataArea( bShrunk, nTab1, nCol1, nRow1, nCol2, nRow2, false);
+ if (bShrunk)
+ {
+ 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 ) );
+ rtl::OUString aExportOUString;
+ aObj.ExportString( aExportOUString );
+ aStrSelection = aExportOUString;
+
+ aStrSelection.ConvertLineEnd( LINEEND_CR );
+
+ // Tab/CR durch Space ersetzen, wenn fuer Dialog oder per Basic/SelectionTextExt,
+ // oder wenn es eine einzelne Zeile ist.
+ // Sonst mehrzeilig mit Tabs beibehalten (z.B. Mail oder Basic/SelectionText).
+ // Fuer Mail werden die Tabs dann spaeter in (mehrere) Spaces gewandelt.
+
+ if ( bInFormatDialog || bWholeWord || aRange.aEnd.Row() == aRange.aStart.Row() )
+ {
+ xub_StrLen nAt;
+ while ( (nAt = aStrSelection.Search( CHAR_CR )) != STRING_NOTFOUND )
+ aStrSelection.SetChar( nAt, ' ' );
+ while ( (nAt = aStrSelection.Search( '\t' )) != STRING_NOTFOUND )
+ aStrSelection.SetChar( nAt, ' ' );
+
+ aStrSelection.EraseTrailingChars( ' ' );
+ }
+ }
+ }
+
+ return aStrSelection;
+}
+
+//------------------------------------------------------------------------
+
+void ScTabViewShell::InsertURL( const String& rName, const String& rURL, const String& rTarget,
+ sal_uInt16 nMode )
+{
+ SvxLinkInsertMode eMode = (SvxLinkInsertMode) nMode;
+ sal_Bool bAsText = ( eMode != HLINK_BUTTON ); // Default ist jetzt Text
+
+ if ( bAsText )
+ {
+ if ( GetViewData()->IsActive() )
+ {
+ // if the view is active, always use InsertURLField, which starts EditMode
+ // and selects the URL, so it can be changed from the URL bar / dialog
+
+ InsertURLField( rName, rURL, rTarget );
+ }
+ else
+ {
+ // #91216# if the view is not active, InsertURLField doesn't work
+ // -> use InsertBookmark to directly manipulate cell content
+ // bTryReplace=sal_True -> if cell contains only one URL, replace it
+
+ SCCOL nPosX = GetViewData()->GetCurX();
+ SCROW nPosY = GetViewData()->GetCurY();
+ InsertBookmark( rName, rURL, nPosX, nPosY, &rTarget, sal_True );
+ }
+ }
+ else
+ {
+ SC_MOD()->InputEnterHandler();
+ InsertURLButton( rName, rURL, rTarget );
+ }
+}
+
+//------------------------------------------------------------------------
+
+// wenn CLOOKs: -> mit <editview.hxx> <flditem.hxx>in neue tabvwsh
+
+void lcl_SelectFieldAfterInsert( EditView& rView )
+{
+ ESelection aSel = rView.GetSelection();
+ if ( aSel.nStartPos == aSel.nEndPos && aSel.nStartPos > 0 )
+ {
+ // Cursor is behind the inserted field -> extend selection to the left
+
+ --aSel.nStartPos;
+ rView.SetSelection( aSel );
+ }
+}
+
+void ScTabViewShell::InsertURLField( const String& rName, const String& rURL, const String& rTarget )
+{
+ SvxURLField aURLField( rURL, rName, SVXURLFORMAT_REPR );
+ aURLField.SetTargetFrame( rTarget );
+ SvxFieldItem aURLItem( aURLField, EE_FEATURE_FIELD );
+
+ ScViewData* pViewData = GetViewData();
+ ScModule* pScMod = SC_MOD();
+ ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
+
+ sal_Bool bSelectFirst = sal_False;
+ if ( !pScMod->IsEditMode() )
+ {
+ if ( !SelectionEditable() )
+ {
+ // no error message (may be called from drag&drop)
+ Sound::Beep();
+ return;
+ }
+
+ // single url in cell is shown in the dialog and replaced
+ bSelectFirst = HasBookmarkAtCursor( NULL );
+ pScMod->SetInputMode( SC_INPUT_TABLE );
+ }
+
+ EditView* pTopView = pHdl->GetTopView();
+ EditView* pTableView = pHdl->GetTableView();
+ DBG_ASSERT( pTopView || pTableView, "No EditView" );
+
+ if ( bSelectFirst )
+ {
+ if ( pTopView )
+ pTopView->SetSelection( ESelection(0,0,0,1) );
+ if ( pTableView )
+ pTableView->SetSelection( ESelection(0,0,0,1) );
+ }
+
+ pHdl->DataChanging();
+
+ if ( pTopView )
+ {
+ pTopView->InsertField( aURLItem );
+ lcl_SelectFieldAfterInsert( *pTopView );
+ }
+ if ( pTableView )
+ {
+ pTableView->InsertField( aURLItem );
+ lcl_SelectFieldAfterInsert( *pTableView );
+ }
+
+ pHdl->DataChanged();
+}
+
+void ScTabViewShell::ExecSearch( SfxRequest& rReq )
+{
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ sal_uInt16 nSlot = rReq.GetSlot();
+ const SfxPoolItem* pItem;
+
+ switch ( nSlot )
+ {
+ case FID_SEARCH_NOW:
+ {
+ if ( pReqArgs &&
+ SFX_ITEM_SET == pReqArgs->GetItemState(SID_SEARCH_ITEM, sal_False, &pItem) )
+ {
+ DBG_ASSERT( pItem->ISA(SvxSearchItem), "falsches Item" );
+ const SvxSearchItem* pSearchItem = (const SvxSearchItem*) pItem;
+
+ ScGlobal::SetSearchItem( *pSearchItem );
+ SearchAndReplace( pSearchItem, sal_True, rReq.IsAPI() );
+ rReq.Done();
+ }
+ }
+ break;
+
+ case SID_SEARCH_ITEM:
+ if (pReqArgs && SFX_ITEM_SET ==
+ pReqArgs->GetItemState(SID_SEARCH_ITEM, sal_False, &pItem))
+ {
+ // Search-Item merken
+ DBG_ASSERT( pItem->ISA(SvxSearchItem), "falsches Item" );
+ ScGlobal::SetSearchItem( *(const SvxSearchItem*) pItem );
+ }
+ else
+ {
+ DBG_ERROR("SID_SEARCH_ITEM ohne Parameter");
+ }
+ break;
+ case FID_SEARCH:
+ case FID_REPLACE:
+ case FID_REPLACE_ALL:
+ case FID_SEARCH_ALL:
+ {
+ if (pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState(nSlot, sal_False, &pItem))
+ {
+ // SearchItem holen
+
+ SvxSearchItem aSearchItem = ScGlobal::GetSearchItem();
+
+ // SearchItem fuellen
+
+ aSearchItem.SetSearchString(((SfxStringItem*)pItem)->GetValue());
+ if(SFX_ITEM_SET == pReqArgs->GetItemState(FN_PARAM_1, sal_False, &pItem))
+ aSearchItem.SetReplaceString(((SfxStringItem*)pItem)->GetValue());
+
+ if (nSlot == FID_SEARCH)
+ aSearchItem.SetCommand(SVX_SEARCHCMD_FIND);
+ else if(nSlot == FID_REPLACE)
+ aSearchItem.SetCommand(SVX_SEARCHCMD_REPLACE);
+ else if(nSlot == FID_REPLACE_ALL)
+ aSearchItem.SetCommand(SVX_SEARCHCMD_REPLACE_ALL);
+ else
+ aSearchItem.SetCommand(SVX_SEARCHCMD_FIND_ALL);
+
+ // Request ausfuehren (dabei wird das SearchItem gespeichert)
+
+ aSearchItem.SetWhich(SID_SEARCH_ITEM);
+ GetViewData()->GetDispatcher().Execute( FID_SEARCH_NOW,
+ rReq.IsAPI() ? SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON :
+ SFX_CALLMODE_STANDARD,
+ &aSearchItem, 0L );
+ }
+ else
+ {
+ GetViewData()->GetDispatcher().Execute(
+ SID_SEARCH_DLG, SFX_CALLMODE_ASYNCHRON|SFX_CALLMODE_RECORD );
+ }
+ }
+ break;
+ case FID_REPEAT_SEARCH:
+ {
+ // nochmal mit ScGlobal::GetSearchItem()
+
+ SvxSearchItem aSearchItem = ScGlobal::GetSearchItem();
+ aSearchItem.SetWhich(SID_SEARCH_ITEM);
+ GetViewData()->GetDispatcher().Execute( FID_SEARCH_NOW,
+ rReq.IsAPI() ? SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON :
+ SFX_CALLMODE_STANDARD,
+ &aSearchItem, 0L );
+ }
+ break;
+// case FID_SEARCH_COUNT:
+ }
+}
+
+//--------------------------------------------------------------------
+
+
+
+
+
+
diff --git a/sc/source/ui/view/tabvwshf.cxx b/sc/source/ui/view/tabvwshf.cxx
new file mode 100644
index 000000000000..10aea8a81dae
--- /dev/null
+++ b/sc/source/ui/view/tabvwshf.cxx
@@ -0,0 +1,964 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#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 <sfx2/objface.hxx>
+#include <svx/svxdlg.hxx>
+#include <editeng/colritem.hxx>
+
+#include "tabvwsh.hxx"
+#include "sc.hrc"
+#include "docsh.hxx"
+#include "document.hxx"
+#include "shtabdlg.hxx"
+#include "scresid.hxx"
+//CHINA001 #include "instbdlg.hxx"
+#include "globstr.hrc"
+//CHINA001 #include "strindlg.hxx"
+//CHINA001 #include "mvtabdlg.hxx"
+#include "docfunc.hxx"
+#include "eventuno.hxx"
+
+#include "scabstdlg.hxx" //CHINA001
+
+#include "tabbgcolor.hxx"
+#include "tabbgcolordlg.hxx"
+#include "sccommands.h"
+
+using ::boost::scoped_ptr;
+using namespace com::sun::star;
+
+#define IS_AVAILABLE(WhichId,ppItem) \
+ (pReqArgs->GetItemState((WhichId), sal_True, ppItem ) == SFX_ITEM_SET)
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::ExecuteTable( SfxRequest& rReq )
+{
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+
+ SCTAB nCurrentTab = pViewData->GetTabNo();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ sal_uInt16 nSlot = rReq.GetSlot();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+
+ HideListBox(); // Autofilter-DropDown-Listbox
+
+ switch ( nSlot )
+ {
+ case FID_TABLE_VISIBLE:
+ {
+ String aName;
+ pDoc->GetName( nCurrentTab, aName );
+
+ sal_Bool bVisible=sal_True;
+ if( pReqArgs != NULL )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FID_TABLE_VISIBLE, &pItem ) )
+ bVisible = ((const SfxBoolItem*)pItem)->GetValue();
+ }
+
+ if( ! bVisible ) // ausblenden
+ {
+ ScMarkData& rMark = pViewData->GetMarkData();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+ sal_uInt16 nVis = 0;
+ for ( SCTAB i=0; i < nTabCount && nVis<2; i++ )
+ if (pDoc->IsVisible(i))
+ ++nVis;
+ if ( nVis<2 || !pDoc->IsDocEditable() || nTabSelCount > 1 )
+ break;
+
+ SCTAB nHideTab;
+ if (pDoc->GetTable( aName, nHideTab ))
+ HideTable( nHideTab );
+ }
+ else // einblenden
+ {
+ ShowTable( aName );
+ }
+ }
+ break;
+
+ case FID_TABLE_HIDE:
+ {
+ ScMarkData& rMark = pViewData->GetMarkData();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+ sal_uInt16 nVis = 0;
+ for ( SCTAB i=0; i < nTabCount && nVis<2; i++ )
+ if (pDoc->IsVisible(i))
+ ++nVis;
+ if ( nVis<2 || !pDoc->IsDocEditable() || nTabSelCount > 1 )
+ break;
+
+
+ String aName;
+ if( pReqArgs != NULL )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FID_TABLE_HIDE, &pItem ) )
+ aName = ((const SfxStringItem*)pItem)->GetValue();
+ }
+
+ if (!aName.Len())
+ {
+ pDoc->GetName( nCurrentTab, aName ); // aktuelle Tabelle
+ rReq.AppendItem( SfxStringItem( FID_TABLE_HIDE, aName ) );
+ }
+
+ SCTAB nHideTab;
+ if (pDoc->GetTable( aName, nHideTab ))
+ HideTable( nHideTab );
+
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ break;
+
+ case FID_TABLE_SHOW:
+ {
+ String aName;
+ if ( pReqArgs )
+ {
+ const SfxPoolItem* pItem;
+ if( IS_AVAILABLE( FID_TABLE_SHOW, &pItem ) )
+ {
+ aName = ((const SfxStringItem*)pItem)->GetValue();
+
+ ShowTable( aName );
+
+ if( ! rReq.IsAPI() )
+ rReq.Done();
+ }
+ }
+ else
+ {
+ //CHINA001 ScShowTabDlg* pDlg = new ScShowTabDlg( GetDialogParent() );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScShowTabDlg* pDlg = pFact->CreateScShowTabDlg( GetDialogParent(), RID_SCDLG_SHOW_TAB);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ String aTabName;
+ sal_Bool bFirst = sal_True;
+ for ( SCTAB i=0; i != nTabCount; i++ )
+ {
+ if (!pDoc->IsVisible(i))
+ {
+ pDoc->GetName( i, aTabName );
+ pDlg->Insert( aTabName, bFirst );
+ bFirst = sal_False;
+ }
+ }
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ sal_uInt16 nCount = pDlg->GetSelectEntryCount();
+ for (sal_uInt16 nPos=0; nPos<nCount; nPos++)
+ {
+ aName = pDlg->GetSelectEntry(nPos);
+ ShowTable( aName );
+ }
+ rReq.AppendItem( SfxStringItem( FID_TABLE_SHOW, aName ) );
+ rReq.Done();
+ }
+ delete pDlg;
+ }
+ }
+ break;
+
+ case FID_INS_TABLE:
+ case FID_INS_TABLE_EXT:
+ {
+ ScMarkData& rMark = pViewData->GetMarkData();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+ SCTAB nTabNr = nCurrentTab;
+
+ if ( !pDoc->IsDocEditable() )
+ break; // gesperrt
+
+ if ( pReqArgs != NULL ) // von Basic
+ {
+ sal_Bool bOk = sal_False;
+ const SfxPoolItem* pTabItem;
+ const SfxPoolItem* pNameItem;
+ String aName;
+
+ if ( IS_AVAILABLE( FN_PARAM_1, &pTabItem ) &&
+ IS_AVAILABLE( nSlot, &pNameItem ) )
+ {
+ // Tabellennr. von Basic: 1-basiert
+
+ aName = ((const SfxStringItem*)pNameItem)->GetValue();
+ nTabNr = ((const SfxUInt16Item*)pTabItem)->GetValue() - 1;
+ if ( nTabNr < nTabCount )
+ bOk = InsertTable( aName, nTabNr );
+ }
+
+ if (bOk)
+ rReq.Done( *pReqArgs );
+ //! sonst Fehler setzen
+ }
+ else // Dialog
+ {
+//CHINA001 ScInsertTableDlg* pDlg = new ScInsertTableDlg(
+//CHINA001 GetDialogParent(),
+//CHINA001 *pViewData,nTabSelCount);
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScInsertTableDlg* pDlg = pFact->CreateScInsertTableDlg( GetDialogParent(), *pViewData,
+ nTabSelCount, nSlot == FID_INS_TABLE_EXT,
+ RID_SCDLG_INSERT_TABLE);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+ if ( RET_OK == pDlg->Execute() )
+ {
+ if (pDlg->GetTablesFromFile())
+ {
+ SCTAB nTabs[MAXTABCOUNT];
+ SCTAB nCount = 0;
+ sal_uInt16 n = 0;
+ const String* pStr = pDlg->GetFirstTable( &n );
+ while ( pStr )
+ {
+ nTabs[nCount++] = static_cast<SCTAB>(n);
+ pStr = pDlg->GetNextTable( &n );
+ }
+ sal_Bool bLink = pDlg->GetTablesAsLink();
+ if (nCount != 0)
+ {
+ if(pDlg->IsTableBefore())
+ {
+ ImportTables( pDlg->GetDocShellTables(), nCount, nTabs,
+ bLink,nTabNr );
+ }
+ else
+ {
+ SCTAB nTabAfter = nTabNr+1;
+
+ for(SCTAB j=nCurrentTab+1;j<nTabCount;j++)
+ {
+ if(!pDoc->IsScenario(j))
+ {
+ nTabAfter=j;
+ break;
+ }
+ }
+
+ ImportTables( pDlg->GetDocShellTables(), nCount, nTabs,
+ bLink,nTabAfter );
+ }
+ }
+ }
+ else
+ {
+ SCTAB nCount=pDlg->GetTableCount();
+ if(pDlg->IsTableBefore())
+ {
+ if(nCount==1 && pDlg->GetFirstTable()->Len()>0)
+ {
+ rReq.AppendItem( SfxStringItem( FID_INS_TABLE, *pDlg->GetFirstTable() ) );
+ rReq.AppendItem( SfxUInt16Item( FN_PARAM_1, static_cast<sal_uInt16>(nTabNr) + 1 ) ); // 1-based
+ rReq.Done();
+
+ InsertTable( *pDlg->GetFirstTable(), nTabNr );
+ }
+ else
+ InsertTables( NULL, nTabNr,nCount );
+ }
+ else
+ {
+ SCTAB nTabAfter = nTabNr+1;
+ SCTAB nSelHigh=0;
+
+ for(SCTAB i=0;i<nTabCount;i++)
+ {
+ if(rMark.GetTableSelect(i))
+ {
+ nSelHigh=i;
+ }
+ }
+
+ for(SCTAB j=nSelHigh+1;j<nTabCount;j++)
+ {
+ if(!pDoc->IsScenario(j))
+ {
+ nTabAfter=j;
+ break;
+ }
+ else // #101672#; increase nTabAfter, because it is possible that the scenario tables are the last
+ nTabAfter = j + 1;
+ }
+
+ if(nCount==1 && pDlg->GetFirstTable()->Len()>0)
+ {
+ rReq.AppendItem( SfxStringItem( FID_INS_TABLE, *pDlg->GetFirstTable() ) );
+ rReq.AppendItem( SfxUInt16Item( FN_PARAM_1, static_cast<sal_uInt16>(nTabAfter) + 1 ) ); // 1-based
+ rReq.Done();
+
+ InsertTable( *pDlg->GetFirstTable(), nTabAfter);
+ }
+ else
+ {
+ InsertTables( NULL, nTabAfter,nCount);
+ }
+ }
+ }
+ }
+
+ delete pDlg;
+ }
+ }
+ break;
+
+ case FID_TAB_APPEND:
+ case FID_TAB_RENAME:
+ case FID_TAB_MENU_RENAME:
+ {
+ // FID_TAB_MENU_RENAME - "umbenennen" im Menu
+ // FID_TAB_RENAME - "Name"-Property fuer Basic
+ // Execute ist gleich, aber im GetState wird MENU_RENAME evtl. disabled
+
+ if ( nSlot == FID_TAB_MENU_RENAME )
+ nSlot = FID_TAB_RENAME; // Execute ist gleich
+
+ SCTAB nTabNr = pViewData->GetTabNo();
+ ScMarkData& rMark = pViewData->GetMarkData();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+
+ if ( !pDoc->IsDocEditable() )
+ break; // alles gesperrt
+
+ if ( nSlot != FID_TAB_APPEND &&
+ ( pDoc->IsTabProtected( nTabNr ) || nTabSelCount > 1 ) )
+ break; // kein Rename
+
+#if 0
+ // ScSbxObject wird nicht mehr benutzt, stattdessen aus dem
+ // ScSbxTable::Notify die richtige Tabelle an der Basic-View eingestellt
+ if( rReq.IsAPI() )
+ {
+ SbxObject* pObj = GetScSbxObject();
+ ScSbxTable* pSbxTab = PTR_CAST( ScSbxTable, pObj );
+ DBG_ASSERT( pSbxTab, "pSbxTab???" );
+
+ if( pSbxTab )
+ nTabNr = pSbxTab->GetTableNr();
+ }
+#endif
+
+ if( pReqArgs != NULL )
+ {
+ sal_Bool bDone = sal_False;
+ const SfxPoolItem* pItem;
+ String aName;
+
+ if( IS_AVAILABLE( FN_PARAM_1, &pItem ) )
+ nTabNr = ((const SfxUInt16Item*)pItem)->GetValue();
+
+ if( IS_AVAILABLE( nSlot, &pItem ) )
+ aName = ((const SfxStringItem*)pItem)->GetValue();
+
+ switch ( nSlot )
+ {
+ case FID_TAB_APPEND:
+ bDone = AppendTable( aName );
+ break;
+ case FID_TAB_RENAME:
+ bDone = RenameTable( aName, nTabNr );
+ break;
+ }
+
+ if( bDone )
+ {
+ rReq.Done( *pReqArgs );
+ }
+ }
+ else
+ {
+ sal_uInt16 nRet = RET_OK;
+ sal_Bool bDone = sal_False;
+ String aErrMsg ( ScGlobal::GetRscString( STR_INVALIDTABNAME ) );
+ String aName;
+ String aDlgTitle;
+ const sal_Char* pHelpId = 0;
+
+ switch ( nSlot )
+ {
+ case FID_TAB_APPEND:
+ aDlgTitle = String(ScResId(SCSTR_APDTABLE));
+ pDoc->CreateValidTabName( aName );
+ pHelpId = HID_SC_APPEND_NAME;
+ break;
+
+ case FID_TAB_RENAME:
+ aDlgTitle = String(ScResId(SCSTR_RENAMETAB));
+ pDoc->GetName( pViewData->GetTabNo(), aName );
+ pHelpId = HID_SC_RENAME_NAME;
+ break;
+ }
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScStringInputDlg* pDlg = pFact->CreateScStringInputDlg( GetDialogParent(),
+ aDlgTitle,
+ String(ScResId(SCSTR_NAME)),
+ aName,
+ GetStaticInterface()->GetSlot(nSlot)->GetCommand(), pHelpId, RID_SCDLG_STRINPUT);
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ while ( !bDone && nRet == RET_OK )
+ {
+ nRet = pDlg->Execute();
+
+ if ( nRet == RET_OK )
+ {
+ pDlg->GetInputString( aName );
+
+
+ switch ( nSlot )
+ {
+ case FID_TAB_APPEND:
+ bDone = AppendTable( aName );
+ break;
+ case FID_TAB_RENAME:
+ bDone = RenameTable( aName, nTabNr );
+ break;
+ }
+
+ if ( bDone )
+ {
+ rReq.AppendItem( SfxStringItem( nSlot, aName ) );
+ rReq.Done();
+ }
+ else
+ {
+ if( rReq.IsAPI() )
+ {
+ StarBASIC::Error( SbERR_SETPROP_FAILED ); // XXX Fehlerbehandlung???
+ }
+ else
+ {
+ nRet = ErrorBox( GetDialogParent(),
+ WinBits( WB_OK | WB_DEF_OK ),
+ aErrMsg
+ ).Execute();
+ }
+ }
+ }
+ }
+ delete pDlg;
+ }
+ }
+ break;
+
+ case FID_TAB_MOVE:
+ {
+ if ( pDoc->GetChangeTrack() != NULL )
+ break; // bei aktiviertem ChangeTracking kein TabMove
+
+ sal_Bool bDoIt = sal_False;
+ sal_uInt16 nDoc = 0;
+ SCTAB nTab = pViewData->GetTabNo();
+ sal_Bool bCpy = sal_False;
+ String aDocName;
+
+ if( pReqArgs != NULL )
+ {
+ SCTAB nTableCount = pDoc->GetTableCount();
+ const SfxPoolItem* pItem;
+
+ if( IS_AVAILABLE( FID_TAB_MOVE, &pItem ) )
+ aDocName = ((const SfxStringItem*)pItem)->GetValue();
+ if( IS_AVAILABLE( FN_PARAM_1, &pItem ) )
+ {
+ // Tabelle ist 1-basiert
+ nTab = ((const SfxUInt16Item*)pItem)->GetValue() - 1;
+ if ( nTab >= nTableCount )
+ nTab = SC_TAB_APPEND;
+ }
+ if( IS_AVAILABLE( FN_PARAM_2, &pItem ) )
+ bCpy = ((const SfxBoolItem*)pItem)->GetValue();
+
+ if( aDocName.Len() )
+ {
+ SfxObjectShell* pSh = SfxObjectShell::GetFirst();
+ ScDocShell* pScSh = NULL;
+ sal_uInt16 i=0;
+
+ while ( pSh )
+ {
+ pScSh = PTR_CAST( ScDocShell, pSh );
+
+ if( pScSh )
+ {
+ pScSh->GetTitle();
+
+ if( pScSh->GetTitle() == aDocName )
+ {
+ nDoc = i;
+ ScDocument* pDestDoc = pScSh->GetDocument();
+ nTableCount = pDestDoc->GetTableCount();
+ bDoIt = pDestDoc->IsDocEditable();
+ break;
+ }
+
+ i++; // nur die ScDocShell's zaehlen
+ }
+ pSh = SfxObjectShell::GetNext( *pSh );
+ }
+ }
+ else // Kein Dokumentname -> neues Dokument
+ {
+ nDoc = SC_DOC_NEW;
+ bDoIt = sal_True;
+ }
+
+ if ( bDoIt && nTab >= nTableCount ) // ggf. anhaengen
+ nTab = SC_TAB_APPEND;
+ }
+ else
+ {
+ //CHINA001 ScMoveTableDlg* pDlg = new ScMoveTableDlg( GetDialogParent() );
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
+
+ AbstractScMoveTableDlg* pDlg = pFact->CreateScMoveTableDlg( GetDialogParent(), RID_SCDLG_MOVETAB );
+ DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
+
+ SCTAB nTableCount = pDoc->GetTableCount();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+
+
+ if(nTableCount==nTabSelCount)
+ {
+ pDlg->SetCopyTable();
+ pDlg->EnableCopyTable(sal_False);
+ }
+ if ( pDlg->Execute() == RET_OK )
+ {
+ nDoc = pDlg->GetSelectedDocument();
+ nTab = pDlg->GetSelectedTable();
+ bCpy = pDlg->GetCopyTable();
+ bDoIt = sal_True;
+
+ String aFoundDocName;
+ if ( nDoc != SC_DOC_NEW )
+ {
+ ScDocShell* pSh = ScDocShell::GetShellByNum( nDoc );
+ if (pSh)
+ {
+ aFoundDocName = pSh->GetTitle();
+ if ( !pSh->GetDocument()->IsDocEditable() )
+ {
+ ErrorMessage(STR_READONLYERR);
+ bDoIt = sal_False;
+ }
+ }
+ }
+ rReq.AppendItem( SfxStringItem( FID_TAB_MOVE, aFoundDocName ) );
+ // Tabelle ist 1-basiert, wenn nicht APPEND
+ SCTAB nBasicTab = ( nTab <= MAXTAB ) ? (nTab+1) : nTab;
+ rReq.AppendItem( SfxUInt16Item( FN_PARAM_1, static_cast<sal_uInt16>(nBasicTab) ) );
+ rReq.AppendItem( SfxBoolItem( FN_PARAM_2, bCpy ) );
+ }
+ delete pDlg;
+ }
+
+ if( bDoIt )
+ {
+ rReq.Done(); // aufzeichnen, solange das Dokument noch aktiv ist
+
+ MoveTable( nDoc, nTab, bCpy );
+ }
+ }
+ break;
+
+ case FID_DELETE_TABLE:
+ {
+ // Parameter war ueberfluessig, weil die Methode an der Table haengt
+
+ sal_Bool bDoIt = rReq.IsAPI();
+ if( !bDoIt )
+ {
+ // wenn's nicht von Basic kommt, nochmal nachfragen:
+
+#if ENABLE_LAYOUT
+// Using layout::QueryBox without client code modification is
+// deprecated, rather add HIG-complient buttons with verbs.
+#define QueryBox( parent, winbits, question ) layout::QueryBox (parent, question, ScGlobal::GetRscString (STR_UNDO_DELETE_TAB))
+#endif /* ENABLE_LAYOUT */
+
+ bDoIt = ( RET_YES ==
+ QueryBox( GetDialogParent(),
+ WinBits( WB_YES_NO | WB_DEF_YES ),
+ ScGlobal::GetRscString(STR_QUERY_DELTAB)
+ ).Execute() );
+ }
+ if( bDoIt )
+ {
+ SCTAB nNewTab = nCurrentTab;
+ SCTAB nFirstTab=0;
+ sal_Bool bTabFlag=sal_False;
+ ScMarkData& rMark = pViewData->GetMarkData();
+ SvShorts TheTabs;
+ for(SCTAB i=0;i<nTabCount;i++)
+ {
+ if(rMark.GetTableSelect(i) &&!pDoc->IsTabProtected(i))
+ {
+ TheTabs.push_back(i);
+ bTabFlag=sal_True;
+ if(nNewTab==i) nNewTab++;
+ }
+ if(!bTabFlag) nFirstTab=i;
+ }
+ if(nNewTab>=nTabCount) nNewTab=nFirstTab;
+
+ pViewData->SetTabNo(nNewTab);
+ DeleteTables(TheTabs);
+ TheTabs.clear();
+ rReq.Done();
+ }
+ }
+ break;
+
+ case FID_TAB_RTL:
+ {
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocFunc aFunc(*pDocSh);
+ sal_Bool bSet = !pDoc->IsLayoutRTL( nCurrentTab );
+
+ const ScMarkData& rMark = pViewData->GetMarkData();
+ if ( rMark.GetSelectCount() != 0 )
+ {
+ // handle several sheets
+
+ ::svl::IUndoManager* pUndoManager = pDocSh->GetUndoManager();
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_TAB_RTL );
+ pUndoManager->EnterListAction( aUndo, aUndo );
+
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if ( rMark.GetTableSelect(nTab) )
+ aFunc.SetLayoutRTL( nTab, bSet, sal_False );
+
+ pUndoManager->LeaveListAction();
+ }
+ else
+ aFunc.SetLayoutRTL( nCurrentTab, bSet, sal_False );
+ }
+ 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 )
+ {
+ sal_Bool bDone = sal_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
+ {
+ sal_uInt16 nRet = RET_OK; /// temp
+ sal_Bool bDone = sal_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,
+ CMD_FID_TAB_SET_TAB_BG_COLOR,
+ 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;
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::GetStateTable( SfxItemSet& rSet )
+{
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScDocShell* pDocShell = pViewData->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTab = pViewData->GetTabNo();
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ while ( nWhich )
+ {
+ switch ( nWhich )
+ {
+
+ case FID_TABLE_VISIBLE:
+ rSet.Put( SfxBoolItem( nWhich, pDoc->IsVisible(nTab) ));
+ break;
+
+ case FID_TABLE_HIDE:
+ {
+ sal_uInt16 nVis = 0;
+ for ( SCTAB i=0; i < nTabCount && nVis<2; i++ )
+ if (pDoc->IsVisible(i))
+ ++nVis;
+
+ if ( nVis<2 || !pDoc->IsDocEditable() || nTabSelCount > 1 )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case FID_TABLE_SHOW:
+ {
+ sal_Bool bHasHidden = sal_False;
+ for ( SCTAB i=0; i < nTabCount && !bHasHidden; i++ )
+ if (!pDoc->IsVisible(i))
+ bHasHidden = sal_True;
+ if ( !bHasHidden || pDoc->IsDocProtected() || nTabSelCount > 1 )
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case FID_DELETE_TABLE:
+ {
+ if ( pDoc->GetChangeTrack() )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ sal_uInt16 nVis = 0;
+ for ( SCTAB i=0; i < nTabCount && nVis<2; i++ )
+ if (pDoc->IsVisible(i))
+ ++nVis;
+ if ( pDoc->IsTabProtected(nTab)
+ || !pDoc->IsDocEditable()
+ || nVis < 2
+ || nTabSelCount == nTabCount)
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ case FID_INS_TABLE:
+ case FID_INS_TABLE_EXT:
+ case FID_TAB_APPEND:
+ if ( !pDoc->IsDocEditable() ||
+ nTabCount > MAXTAB ||
+ ( nWhich == FID_INS_TABLE_EXT && pDocShell && pDocShell->IsDocShared() ) )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_TAB_MOVE:
+ if ( !pDoc->IsDocEditable()
+ || pDoc->GetChangeTrack() != NULL
+ || nTabCount > MAXTAB)
+ rSet.DisableItem( nWhich );
+ break;
+
+ // FID_TAB_MENU_RENAME - "umbenennen" im Menu
+ // FID_TAB_RENAME - "Name"-Property fuer Basic
+
+ case FID_TAB_MENU_RENAME:
+ if ( !pDoc->IsDocEditable() ||
+ pDoc->IsTabProtected(nTab) ||nTabSelCount > 1 ||
+ ( pDocShell && pDocShell->IsDocShared() ) )
+ rSet.DisableItem( nWhich );
+ break;
+
+ case FID_TAB_RENAME:
+ {
+ String aTabName;
+ pDoc->GetName( nTab, aTabName );
+
+ rSet.Put( SfxStringItem( nWhich, aTabName ));
+
+ }
+ break;
+
+ case FID_TAB_RTL:
+ {
+ SvtLanguageOptions aLangOpt;
+ if ( !aLangOpt.IsCTLFontEnabled() )
+ rSet.DisableItem( nWhich );
+ else
+ 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/tabvwshg.cxx b/sc/source/ui/view/tabvwshg.cxx
new file mode 100644
index 000000000000..b30b07c43cb9
--- /dev/null
+++ b/sc/source/ui/view/tabvwshg.cxx
@@ -0,0 +1,140 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+//#define SI_VCDRAWOBJ
+
+#include <tools/urlobj.hxx>
+#include <svx/fmglob.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdpagv.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/docfile.hxx>
+
+#include <com/sun/star/form/FormButtonType.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/XControlModel.hpp>
+
+using namespace com::sun::star;
+
+#include "tabvwsh.hxx"
+#include "document.hxx"
+#include "drawview.hxx"
+#include "globstr.hrc"
+#include <avmedia/mediawindow.hxx>
+
+//------------------------------------------------------------------------
+
+void ScTabViewShell::InsertURLButton( const String& rName, const String& rURL,
+ const String& rTarget,
+ const Point* pInsPos )
+{
+ // Tabelle geschuetzt ?
+
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ if ( pDoc->IsTabProtected(nTab) )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ MakeDrawLayer();
+
+ ScTabView* pView = pViewData->GetView();
+// SdrView* pDrView = pView->GetSdrView();
+ ScDrawView* pDrView = pView->GetScDrawView();
+ SdrModel* pModel = pDrView->GetModel();
+
+ SdrObject* pObj = SdrObjFactory::MakeNewObject(FmFormInventor, OBJ_FM_BUTTON,
+ pDrView->GetSdrPageView()->GetPage(), pModel);
+ SdrUnoObj* pUnoCtrl = PTR_CAST(SdrUnoObj, pObj);
+
+ uno::Reference<awt::XControlModel> xControlModel = pUnoCtrl->GetUnoControlModel();
+ DBG_ASSERT( xControlModel.is(), "UNO-Control ohne Model" );
+ if( !xControlModel.is() )
+ return;
+
+ uno::Reference< beans::XPropertySet > xPropSet( xControlModel, uno::UNO_QUERY );
+ uno::Any aAny;
+
+ aAny <<= rtl::OUString(rName);
+ xPropSet->setPropertyValue( rtl::OUString::createFromAscii( "Label" ), aAny );
+
+ ::rtl::OUString aTmp = INetURLObject::GetAbsURL( pDoc->GetDocumentShell()->GetMedium()->GetBaseURL(), rURL );
+ aAny <<= aTmp;
+ xPropSet->setPropertyValue( rtl::OUString::createFromAscii( "TargetURL" ), aAny );
+
+ if( rTarget.Len() )
+ {
+ aAny <<= rtl::OUString(rTarget);
+ xPropSet->setPropertyValue( rtl::OUString::createFromAscii( "TargetFrame" ), aAny );
+ }
+
+ form::FormButtonType eButtonType = form::FormButtonType_URL;
+ aAny <<= eButtonType;
+ xPropSet->setPropertyValue( rtl::OUString::createFromAscii( "ButtonType" ), aAny );
+
+ if ( ::avmedia::MediaWindow::isMediaURL( rURL ) )
+ {
+ // #105638# OJ
+ aAny <<= sal_True;
+ xPropSet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DispatchURLInternal" )), aAny );
+ }
+
+ Point aPos;
+ if (pInsPos)
+ aPos = *pInsPos;
+ else
+ aPos = GetInsertPos();
+
+ // Groesse wie in 3.1:
+ Size aSize = GetActiveWin()->PixelToLogic(Size(140, 20));
+
+ if ( pDoc->IsNegativePage(nTab) )
+ aPos.X() -= aSize.Width();
+
+ pObj->SetLogicRect(Rectangle(aPos, aSize));
+// pObj->Resize(Point(), Fraction(1, 1), Fraction(1, 1));
+
+ // am alten VC-Button musste die Position/Groesse nochmal explizit
+ // gesetzt werden - das scheint mit UnoControls nicht noetig zu sein
+
+ // nicht markieren wenn Ole
+ pDrView->InsertObjectSafe( pObj, *pDrView->GetSdrPageView() );
+}
+
+
+
+
diff --git a/sc/source/ui/view/tabvwshh.cxx b/sc/source/ui/view/tabvwshh.cxx
new file mode 100644
index 000000000000..7622832f9094
--- /dev/null
+++ b/sc/source/ui/view/tabvwshh.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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svx/svdmark.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdview.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/request.hxx>
+#include <basic/sbxcore.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/msgbox.hxx>
+
+#include "tabvwsh.hxx"
+#include "client.hxx"
+#include "document.hxx"
+#include "docsh.hxx"
+#include "sc.hrc"
+#include "drwlayer.hxx" // GetVisibleName
+#include "retypepassdlg.hxx"
+#include "tabprotection.hxx"
+
+#include <memory>
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::ExecuteSbx( SfxRequest& /* rReq */ )
+{
+ // SID_RANGE_OFFSET (Offset),
+ // SID_PIVOT_CREATE (DataPilotCreate) - removed (old Basic)
+}
+
+void ScTabViewShell::GetSbxState( SfxItemSet& /* rSet */ )
+{
+ // SID_RANGE_REGION (CurrentRegion) - removed (old Basic)
+}
+
+//------------------------------------------------------------------
+
+void ScTabViewShell::ExecuteObject( SfxRequest& rReq )
+{
+ sal_uInt16 nSlotId = rReq.GetSlot();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+
+ // Objekte aktivieren/deaktivieren immer auf der sichtbaren View
+
+ ScTabViewShell* pVisibleSh = this;
+ if ( nSlotId == SID_OLE_SELECT || nSlotId == SID_OLE_ACTIVATE || nSlotId == SID_OLE_DEACTIVATE )
+ {
+ DBG_ERROR("old slot SID_OLE...");
+ }
+
+ switch (nSlotId)
+ {
+ case SID_OLE_SELECT:
+ case SID_OLE_ACTIVATE:
+ {
+ // in beiden Faellen erstmal auf der sichtbaren View selektieren
+
+ String aName;
+ SdrView* pDrView = GetSdrView();
+ if (pDrView)
+ {
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1)
+ aName = ScDrawLayer::GetVisibleName( rMarkList.GetMark(0)->GetMarkedSdrObj() );
+ }
+ pVisibleSh->SelectObject( aName );
+
+ // aktivieren
+
+ if ( nSlotId == SID_OLE_ACTIVATE )
+ pVisibleSh->DoVerb( 0 );
+ }
+ break;
+ case SID_OLE_DEACTIVATE:
+ pVisibleSh->DeactivateOle();
+ break;
+
+ case SID_OBJECT_LEFT:
+ case SID_OBJECT_TOP:
+ case SID_OBJECT_WIDTH:
+ case SID_OBJECT_HEIGHT:
+ {
+ sal_Bool bDone = sal_False;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && pReqArgs->GetItemState( nSlotId, sal_True, &pItem ) == SFX_ITEM_SET )
+ {
+ long nNewVal = ((const SfxInt32Item*)pItem)->GetValue();
+ if ( nNewVal < 0 )
+ nNewVal = 0;
+
+ //! von irgendwas in 1/100mm umrechnen ??????
+
+ SdrView* pDrView = GetSdrView();
+ if ( pDrView )
+ {
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ Rectangle aRect = pObj->GetLogicRect();
+
+ if ( nSlotId == SID_OBJECT_LEFT )
+ pDrView->MoveMarkedObj( Size( nNewVal - aRect.Left(), 0 ) );
+ else if ( nSlotId == SID_OBJECT_TOP )
+ pDrView->MoveMarkedObj( Size( 0, nNewVal - aRect.Top() ) );
+ else if ( nSlotId == SID_OBJECT_WIDTH )
+ pDrView->ResizeMarkedObj( aRect.TopLeft(),
+ Fraction( nNewVal, aRect.GetWidth() ),
+ Fraction( 1, 1 ) );
+ else // if ( nSlotId == SID_OBJECT_HEIGHT )
+ pDrView->ResizeMarkedObj( aRect.TopLeft(),
+ Fraction( 1, 1 ),
+ Fraction( nNewVal, aRect.GetHeight() ) );
+ bDone = sal_True;
+ }
+ }
+ }
+ if (!bDone)
+ SbxBase::SetError( SbxERR_BAD_PARAMETER ); // Basic-Fehler
+ }
+ break;
+
+ }
+}
+
+uno::Reference < embed::XEmbeddedObject > lcl_GetSelectedObj( SdrView* pDrView ) //! Member von ScDrawView?
+{
+ uno::Reference < embed::XEmbeddedObject > xRet;
+ if (pDrView)
+ {
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ if (pObj->GetObjIdentifier() == OBJ_OLE2)
+ {
+ SdrOle2Obj* pOle2Obj = (SdrOle2Obj*) pObj;
+ xRet = pOle2Obj->GetObjRef();
+ }
+ }
+ }
+
+ return xRet;
+}
+
+void ScTabViewShell::GetObjectState( SfxItemSet& rSet )
+{
+ // SID_OLE_OBJECT - removed (old Basic)
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch (nWhich)
+ {
+ case SID_ACTIVE_OBJ_NAME:
+ {
+ String aName;
+ uno::Reference < embed::XEmbeddedObject > xOLE = lcl_GetSelectedObj( GetSdrView() );
+ if (xOLE.is())
+ {
+ aName = GetViewData()->GetSfxDocShell()->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xOLE );
+ }
+ rSet.Put( SfxStringItem( nWhich, aName ) );
+ }
+ break;
+ case SID_OBJECT_LEFT:
+ case SID_OBJECT_TOP:
+ case SID_OBJECT_WIDTH:
+ case SID_OBJECT_HEIGHT:
+ {
+ SdrView* pDrView = GetSdrView();
+ if ( pDrView )
+ {
+ const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ Rectangle aRect = pObj->GetLogicRect();
+
+ long nVal;
+ if ( nWhich == SID_OBJECT_LEFT )
+ nVal = aRect.Left();
+ else if ( nWhich == SID_OBJECT_TOP )
+ nVal = aRect.Top();
+ else if ( nWhich == SID_OBJECT_WIDTH )
+ nVal = aRect.GetWidth();
+ else // if ( nWhich == SID_OBJECT_HEIGHT )
+ nVal = aRect.GetHeight();
+
+ //! von 1/100mm in irgendwas umrechnen ??????
+
+ rSet.Put( SfxInt32Item( nWhich, nVal ) );
+ }
+ }
+ }
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void ScTabViewShell::AddAccessibilityObject( SfxListener& rObject )
+{
+ if (!pAccessibilityBroadcaster)
+ pAccessibilityBroadcaster = new SfxBroadcaster;
+
+ rObject.StartListening( *pAccessibilityBroadcaster );
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if (pDoc)
+ pDoc->AddUnoObject(rObject);
+}
+
+void ScTabViewShell::RemoveAccessibilityObject( SfxListener& rObject )
+{
+ if (pAccessibilityBroadcaster)
+ {
+ rObject.EndListening( *pAccessibilityBroadcaster );
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if (pDoc)
+ pDoc->RemoveUnoObject(rObject);
+ }
+ else
+ {
+ DBG_ERROR("kein Accessibility-Broadcaster?");
+ }
+}
+
+void ScTabViewShell::BroadcastAccessibility( const SfxHint &rHint )
+{
+ if (pAccessibilityBroadcaster)
+ pAccessibilityBroadcaster->Broadcast( rHint );
+}
+
+sal_Bool ScTabViewShell::HasAccessibilityObjects()
+{
+ return pAccessibilityBroadcaster != NULL;
+}
+
+bool ScTabViewShell::ExecuteRetypePassDlg(ScPasswordHash eDesiredHash)
+{
+ using ::std::auto_ptr;
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ auto_ptr<ScRetypePassDlg> pDlg(new ScRetypePassDlg(GetDialogParent()));
+ pDlg->SetDataFromDocument(*pDoc);
+ pDlg->SetDesiredHash(eDesiredHash);
+ if (pDlg->Execute() != RET_OK)
+ return false;
+
+ pDlg->WriteNewDataToDocument(*pDoc);
+ return true;
+}
+
+
+
+
diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx
new file mode 100644
index 000000000000..088d3580bd67
--- /dev/null
+++ b/sc/source/ui/view/viewdata.cxx
@@ -0,0 +1,3179 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <sfx2/viewfrm.hxx>
+#include <editeng/adjitem.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <svtools/colorcfg.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/unolingu.hxx>
+
+#include <vcl/svapp.hxx>
+#include <rtl/math.hxx>
+
+#include "viewdata.hxx"
+#include "docoptio.hxx"
+#include "scmod.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "attrib.hxx"
+#include "tabview.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "sc.hrc"
+#include "patattr.hxx"
+#include "editutil.hxx"
+#include "scextopt.hxx"
+#include "miscuno.hxx"
+#include "unonames.hxx"
+#include "inputopt.hxx"
+#include "viewutil.hxx"
+#include <xmloff/xmluconv.hxx>
+#include "ViewSettingsSequenceDefines.hxx"
+#include <rtl/ustrbuf.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/container/XNameContainer.hpp>
+
+using namespace com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+#define SC_GROWY_SMALL_EXTRA 100
+#define SC_GROWY_BIG_EXTRA 200
+
+#define TAG_TABBARWIDTH "tw:"
+
+static sal_Bool bMoveArea = sal_False; //! Member?
+sal_uInt16 nEditAdjust = SVX_ADJUST_LEFT; //! Member !!!
+
+//==================================================================
+
+ScViewDataTable::ScViewDataTable() :
+ eZoomType( SVX_ZOOM_PERCENT ),
+ aZoomX( 1,1 ),
+ aZoomY( 1,1 ),
+ aPageZoomX( 3,5 ), // Page-Default: 60%
+ aPageZoomY( 3,5 ),
+ nHSplitPos( 0 ),
+ nVSplitPos( 0 ),
+ eHSplitMode( SC_SPLIT_NONE ),
+ eVSplitMode( SC_SPLIT_NONE ),
+ eWhichActive( SC_SPLIT_BOTTOMLEFT ),
+ nFixPosX( 0 ),
+ nFixPosY( 0 ),
+ nCurX( 0 ),
+ nCurY( 0 ),
+ bOldCurValid( sal_False )
+{
+ nPosX[0]=nPosX[1]=0;
+ nPosY[0]=nPosY[1]=0;
+ nTPosX[0]=nTPosX[1]=0;
+ nTPosY[0]=nTPosY[1]=0;
+ nMPosX[0]=nMPosX[1]=0;
+ nMPosY[0]=nMPosY[1]=0;
+ nPixPosX[0]=nPixPosX[1]=0;
+ nPixPosY[0]=nPixPosY[1]=0;
+}
+
+ScViewDataTable::~ScViewDataTable()
+{
+}
+
+void ScViewDataTable::WriteUserDataSequence(uno::Sequence <beans::PropertyValue>& rSettings, const ScViewData& /*rViewData*/, SCTAB /*nTab*/)
+{
+ rSettings.realloc(SC_TABLE_VIEWSETTINGS_COUNT);
+ beans::PropertyValue* pSettings = rSettings.getArray();
+ if (pSettings)
+ {
+ pSettings[SC_CURSOR_X].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_CURSORPOSITIONX));
+ pSettings[SC_CURSOR_X].Value <<= sal_Int32(nCurX);
+ pSettings[SC_CURSOR_Y].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_CURSORPOSITIONY));
+ pSettings[SC_CURSOR_Y].Value <<= sal_Int32(nCurY);
+ pSettings[SC_HORIZONTAL_SPLIT_MODE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_HORIZONTALSPLITMODE));
+ pSettings[SC_HORIZONTAL_SPLIT_MODE].Value <<= sal_Int16(eHSplitMode);
+ pSettings[SC_VERTICAL_SPLIT_MODE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_VERTICALSPLITMODE));
+ pSettings[SC_VERTICAL_SPLIT_MODE].Value <<= sal_Int16(eVSplitMode);
+ pSettings[SC_HORIZONTAL_SPLIT_POSITION].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_HORIZONTALSPLITPOSITION));
+ if (eHSplitMode == SC_SPLIT_FIX)
+ pSettings[SC_HORIZONTAL_SPLIT_POSITION].Value <<= sal_Int32(nFixPosX);
+ else
+ pSettings[SC_HORIZONTAL_SPLIT_POSITION].Value <<= sal_Int32(nHSplitPos);
+ pSettings[SC_VERTICAL_SPLIT_POSITION].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_VERTICALSPLITPOSITION));
+ if (eVSplitMode == SC_SPLIT_FIX)
+ pSettings[SC_VERTICAL_SPLIT_POSITION].Value <<= sal_Int32(nFixPosY);
+ else
+ pSettings[SC_VERTICAL_SPLIT_POSITION].Value <<= sal_Int32(nVSplitPos);
+ pSettings[SC_ACTIVE_SPLIT_RANGE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ACTIVESPLITRANGE));
+ pSettings[SC_ACTIVE_SPLIT_RANGE].Value <<= sal_Int16(eWhichActive);
+ pSettings[SC_POSITION_LEFT].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_POSITIONLEFT));
+ pSettings[SC_POSITION_LEFT].Value <<= sal_Int32(nPosX[SC_SPLIT_LEFT]);
+ pSettings[SC_POSITION_RIGHT].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_POSITIONRIGHT));
+ pSettings[SC_POSITION_RIGHT].Value <<= sal_Int32(nPosX[SC_SPLIT_RIGHT]);
+ pSettings[SC_POSITION_TOP].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_POSITIONTOP));
+ pSettings[SC_POSITION_TOP].Value <<= sal_Int32(nPosY[SC_SPLIT_TOP]);
+ pSettings[SC_POSITION_BOTTOM].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_POSITIONBOTTOM));
+ pSettings[SC_POSITION_BOTTOM].Value <<= sal_Int32(nPosY[SC_SPLIT_BOTTOM]);
+
+ sal_Int32 nZoomValue ((aZoomY.GetNumerator() * 100) / aZoomY.GetDenominator());
+ sal_Int32 nPageZoomValue ((aPageZoomY.GetNumerator() * 100) / aPageZoomY.GetDenominator());
+ pSettings[SC_TABLE_ZOOM_TYPE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ZOOMTYPE));
+ pSettings[SC_TABLE_ZOOM_TYPE].Value <<= sal_Int16(eZoomType);
+ pSettings[SC_TABLE_ZOOM_VALUE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ZOOMVALUE));
+ 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;
+ }
+}
+
+void ScViewDataTable::ReadUserDataSequence(const uno::Sequence <beans::PropertyValue>& aSettings, ScViewData& rViewData, SCTAB nTab, bool& rHasZoom )
+{
+ rHasZoom = false;
+
+ sal_Int32 nCount(aSettings.getLength());
+ sal_Int32 nTemp32(0);
+ sal_Int16 nTemp16(0);
+ sal_Int32 nTempPosV(0);
+ sal_Int32 nTempPosH(0);
+ sal_Int32 nTempPosVTw(0);
+ sal_Int32 nTempPosHTw(0);
+ bool bHasVSplitInTwips = false;
+ bool bHasHSplitInTwips = false;
+ for (sal_Int32 i = 0; i < nCount; i++)
+ {
+ rtl::OUString sName(aSettings[i].Name);
+ if (sName.compareToAscii(SC_CURSORPOSITIONX) == 0)
+ {
+ aSettings[i].Value >>= nTemp32;
+ nCurX = SanitizeCol( static_cast<SCCOL>(nTemp32));
+ }
+ else if (sName.compareToAscii(SC_CURSORPOSITIONY) == 0)
+ {
+ aSettings[i].Value >>= nTemp32;
+ nCurY = SanitizeRow( static_cast<SCROW>(nTemp32));
+ }
+ else if (sName.compareToAscii(SC_HORIZONTALSPLITMODE) == 0)
+ {
+ aSettings[i].Value >>= nTemp16;
+ eHSplitMode = static_cast<ScSplitMode>(nTemp16);
+ }
+ else if (sName.compareToAscii(SC_VERTICALSPLITMODE) == 0)
+ {
+ aSettings[i].Value >>= nTemp16;
+ eVSplitMode = static_cast<ScSplitMode>(nTemp16);
+ }
+ else if (sName.compareToAscii(SC_HORIZONTALSPLITPOSITION) == 0)
+ {
+ aSettings[i].Value >>= nTempPosH;
+ bHasHSplitInTwips = false;
+ }
+ else if (sName.compareToAscii(SC_VERTICALSPLITPOSITION) == 0)
+ {
+ aSettings[i].Value >>= nTempPosV;
+ bHasVSplitInTwips = false;
+ }
+ else if (sName.compareToAscii(SC_HORIZONTALSPLITPOSITION_TWIPS) == 0)
+ {
+ aSettings[i].Value >>= nTempPosHTw;
+ bHasHSplitInTwips = true;
+ }
+ else if (sName.compareToAscii(SC_VERTICALSPLITPOSITION_TWIPS) == 0)
+ {
+ aSettings[i].Value >>= nTempPosVTw;
+ bHasVSplitInTwips = true;
+ }
+ else if (sName.compareToAscii(SC_ACTIVESPLITRANGE) == 0)
+ {
+ aSettings[i].Value >>= nTemp16;
+ eWhichActive = static_cast<ScSplitPos>(nTemp16);
+ }
+ else if (sName.compareToAscii(SC_POSITIONLEFT) == 0)
+ {
+ aSettings[i].Value >>= nTemp32;
+ nPosX[SC_SPLIT_LEFT] = SanitizeCol( static_cast<SCCOL>(nTemp32));
+ }
+ else if (sName.compareToAscii(SC_POSITIONRIGHT) == 0)
+ {
+ aSettings[i].Value >>= nTemp32;
+ nPosX[SC_SPLIT_RIGHT] = SanitizeCol( static_cast<SCCOL>(nTemp32));
+ }
+ else if (sName.compareToAscii(SC_POSITIONTOP) == 0)
+ {
+ aSettings[i].Value >>= nTemp32;
+ nPosY[SC_SPLIT_TOP] = SanitizeRow( static_cast<SCROW>(nTemp32));
+ }
+ else if (sName.compareToAscii(SC_POSITIONBOTTOM) == 0)
+ {
+ aSettings[i].Value >>= nTemp32;
+ nPosY[SC_SPLIT_BOTTOM] = SanitizeRow( static_cast<SCROW>(nTemp32));
+ }
+ else if (sName.compareToAscii(SC_ZOOMTYPE) == 0)
+ {
+ aSettings[i].Value >>= nTemp16;
+ eZoomType = SvxZoomType(nTemp16);
+ rHasZoom = true; // set if there is any zoom information
+ }
+ else if (sName.compareToAscii(SC_ZOOMVALUE) == 0)
+ {
+ aSettings[i].Value >>= nTemp32;
+ Fraction aZoom(nTemp32, 100);
+ aZoomX = aZoomY = aZoom;
+ rHasZoom = true;
+ }
+ else if (sName.compareToAscii(SC_PAGEVIEWZOOMVALUE) == 0)
+ {
+ aSettings[i].Value >>= nTemp32;
+ Fraction aZoom(nTemp32, 100);
+ aPageZoomX = aPageZoomY = aZoom;
+ rHasZoom = true;
+ }
+ else if (sName.compareToAscii(SC_TABLESELECTED) == 0)
+ {
+ bool bSelected = false;
+ 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 ));
+ else
+ nHSplitPos = bHasHSplitInTwips ? static_cast< long >( nTempPosHTw * rViewData.GetPPTX() ) : nTempPosH;
+
+ if (eVSplitMode == SC_SPLIT_FIX)
+ nFixPosY = SanitizeRow( static_cast<SCROW>( bHasVSplitInTwips ? nTempPosVTw : nTempPosV ));
+ else
+ nVSplitPos = bHasVSplitInTwips ? static_cast< long >( nTempPosVTw * rViewData.GetPPTY() ) : nTempPosV;
+}
+
+//==================================================================
+
+ScViewData::ScViewData( ScDocShell* pDocSh, ScTabViewShell* pViewSh )
+ : pDocShell ( pDocSh ),
+ pDoc ( NULL ),
+ pView ( pViewSh ),
+ pViewShell ( pViewSh ),
+ pOptions ( new ScViewOptions ),
+ pSpellingView ( NULL ),
+ aLogicMode ( MAP_100TH_MM ),
+ eDefZoomType( SVX_ZOOM_PERCENT ),
+ aDefZoomX ( 1,1 ),
+ aDefZoomY ( 1,1 ),
+ aDefPageZoomX( 3,5 ),
+ aDefPageZoomY( 3,5 ),
+ eRefType ( SC_REFTYPE_NONE ),
+ nTabNo ( 0 ),
+ nRefTabNo ( 0 ),
+ eEditActivePart( SC_SPLIT_BOTTOMLEFT ),
+ bActive ( sal_True ), //! wie initialisieren?
+ bIsRefMode ( sal_False ),
+ bDelMarkValid( sal_False ),
+ nFillMode ( SC_FILL_NONE ),
+ bPagebreak ( sal_False ),
+ bSelCtrlMouseClick( sal_False )
+{
+
+ SetGridMode ( sal_True );
+ SetSyntaxMode ( sal_False );
+ SetHeaderMode ( sal_True );
+ SetTabMode ( sal_True );
+ SetVScrollMode ( sal_True );
+ SetHScrollMode ( sal_True );
+ SetOutlineMode ( sal_True );
+
+ aScrSize = Size( (long) ( STD_COL_WIDTH * PIXEL_PER_TWIPS * OLE_STD_CELLS_X ),
+ (long) ( ScGlobal::nStdRowHeight * PIXEL_PER_TWIPS * OLE_STD_CELLS_Y ) );
+ pTabData[0] = new ScViewDataTable;
+ for ( SCTAB i = 1; i <= MAXTAB; i++ )
+ pTabData[i] = NULL;
+ pThisTab = pTabData[nTabNo];
+ for (sal_uInt16 j=0; j<4; j++)
+ {
+ pEditView[j] = NULL;
+ bEditActive[j] = sal_False;
+ }
+
+ nEditEndCol = nEditStartCol = nEditCol = 0;
+ nEditEndRow = nEditRow = 0;
+ nTabStartCol = SC_TABSTART_NONE;
+
+ if (pDocShell)
+ {
+ pDoc = pDocShell->GetDocument();
+ *pOptions = pDoc->GetViewOptions();
+ }
+
+ // keine ausgeblendete Tabelle anzeigen:
+ if (pDoc && !pDoc->IsVisible(nTabNo))
+ {
+ while ( !pDoc->IsVisible(nTabNo) && pDoc->HasTable(nTabNo+1) )
+ ++nTabNo;
+
+ pTabData[nTabNo] = new ScViewDataTable;
+ pThisTab = pTabData[nTabNo];
+ }
+
+ CalcPPT();
+}
+
+ScViewData::ScViewData( const ScViewData& rViewData )
+ : pDocShell ( rViewData.pDocShell ),
+ pDoc ( rViewData.pDoc ),
+ pView ( rViewData.pView ),
+ pViewShell ( rViewData.pViewShell ),
+ pOptions ( new ScViewOptions( *(rViewData.pOptions) ) ),
+ pSpellingView ( rViewData.pSpellingView ),
+ aLogicMode ( rViewData.aLogicMode ),
+ eDefZoomType( rViewData.eDefZoomType ),
+ aDefZoomX ( rViewData.aDefZoomX ),
+ aDefZoomY ( rViewData.aDefZoomY ),
+ aDefPageZoomX( rViewData.aDefPageZoomX ),
+ aDefPageZoomY( rViewData.aDefPageZoomY ),
+ eRefType ( SC_REFTYPE_NONE ),
+ nTabNo ( rViewData.nTabNo ),
+ nRefTabNo ( rViewData.nTabNo ), // kein RefMode
+ eEditActivePart( rViewData.eEditActivePart ),
+ bActive ( sal_True ), //! wie initialisieren?
+ bIsRefMode ( sal_False ),
+ bDelMarkValid( sal_False ),
+ nFillMode ( SC_FILL_NONE ),
+ bPagebreak ( rViewData.bPagebreak ),
+ bSelCtrlMouseClick( rViewData.bSelCtrlMouseClick )
+{
+
+ SetGridMode ( rViewData.IsGridMode() );
+ SetSyntaxMode ( rViewData.IsSyntaxMode() );
+ SetHeaderMode ( rViewData.IsHeaderMode() );
+ SetTabMode ( rViewData.IsTabMode() );
+ SetVScrollMode ( rViewData.IsVScrollMode() );
+ SetHScrollMode ( rViewData.IsHScrollMode() );
+ SetOutlineMode ( rViewData.IsOutlineMode() );
+
+ aScrSize = rViewData.aScrSize;
+ for ( SCTAB i = 0; i <= MAXTAB; i++ )
+ if (rViewData.pTabData[i])
+ pTabData[i] = new ScViewDataTable( *rViewData.pTabData[i] );
+ else
+ pTabData[i] = NULL;
+ pThisTab = pTabData[nTabNo];
+ for (sal_uInt16 j=0; j<4; j++)
+ {
+ pEditView[j] = NULL;
+ bEditActive[j] = sal_False;
+ }
+
+ nEditEndCol = nEditStartCol = nEditCol = 0;
+ nEditEndRow = nEditRow = 0;
+ nTabStartCol = SC_TABSTART_NONE;
+ CalcPPT();
+}
+
+void ScViewData::InitData( ScDocument* pDocument )
+{
+ pDoc = pDocument;
+ *pOptions = pDoc->GetViewOptions();
+}
+
+//UNUSED2008-05 void ScViewData::InitFrom( const ScViewData* pRef )
+//UNUSED2008-05 {
+//UNUSED2008-05 if (pRef==NULL)
+//UNUSED2008-05 {
+//UNUSED2008-05 DBG_ERROR("ScViewData::InitFrom mit NULL");
+//UNUSED2008-05 return;
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 aScrSize = pRef->aScrSize;
+//UNUSED2008-05 nTabNo = pRef->nTabNo;
+//UNUSED2008-05 eDefZoomType = pRef->eDefZoomType;
+//UNUSED2008-05 aDefZoomX = pRef->aDefZoomX;
+//UNUSED2008-05 aDefZoomY = pRef->aDefZoomY;
+//UNUSED2008-05 aDefPageZoomX = pRef->aDefPageZoomX;
+//UNUSED2008-05 aDefPageZoomY = pRef->aDefPageZoomY;
+//UNUSED2008-05 bPagebreak = pRef->bPagebreak;
+//UNUSED2008-05 aLogicMode = pRef->aLogicMode;
+//UNUSED2008-05
+//UNUSED2008-05 SetGridMode ( pRef->IsGridMode() );
+//UNUSED2008-05 SetSyntaxMode ( pRef->IsSyntaxMode() );
+//UNUSED2008-05 SetHeaderMode ( pRef->IsHeaderMode() );
+//UNUSED2008-05 SetTabMode ( pRef->IsTabMode() );
+//UNUSED2008-05 SetVScrollMode ( pRef->IsVScrollMode() );
+//UNUSED2008-05 SetHScrollMode ( pRef->IsHScrollMode() );
+//UNUSED2008-05 SetOutlineMode ( pRef->IsOutlineMode() );
+//UNUSED2008-05
+//UNUSED2008-05 for (SCTAB i=0; i<=MAXTAB; i++)
+//UNUSED2008-05 {
+//UNUSED2008-05 delete pTabData[i];
+//UNUSED2008-05 if (pRef->pTabData[i])
+//UNUSED2008-05 pTabData[i] = new ScViewDataTable( *pRef->pTabData[i] );
+//UNUSED2008-05 else
+//UNUSED2008-05 pTabData[i] = NULL;
+//UNUSED2008-05 }
+//UNUSED2008-05 pThisTab = pTabData[nTabNo];
+//UNUSED2008-05 CalcPPT();
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 void ScViewData::SetDocShell( ScDocShell* pShell )
+//UNUSED2008-05 {
+//UNUSED2008-05 pDocShell = pShell;
+//UNUSED2008-05 pDoc = pDocShell->GetDocument();
+//UNUSED2008-05 *pOptions = pDoc->GetViewOptions();
+//UNUSED2008-05 CalcPPT();
+//UNUSED2008-05 }
+
+ScDocument* ScViewData::GetDocument() const
+{
+ if (pDoc)
+ return pDoc;
+ else if (pDocShell)
+ return pDocShell->GetDocument();
+
+ DBG_ERROR("kein Document an ViewData");
+ return NULL;
+}
+
+ScViewData::~ScViewData()
+{
+ for (SCTAB i=0; i<=MAXTAB; i++)
+ if (pTabData[i])
+ delete pTabData[i];
+
+ KillEditView();
+ delete pOptions;
+}
+
+void ScViewData::UpdateThis()
+{
+ do
+ {
+ pThisTab = pTabData[nTabNo];
+ if (!pThisTab)
+ {
+ if (nTabNo>0)
+ --nTabNo;
+ else
+ pThisTab = pTabData[0] = new ScViewDataTable;
+
+ // hier keine Assertion, weil sonst Paints kommen, bevor alles initialisiert ist!
+ }
+ }
+ while (!pThisTab);
+}
+
+void ScViewData::InsertTab( SCTAB nTab )
+{
+ delete pTabData[MAXTAB];
+
+ for (SCTAB i=MAXTAB; i>nTab; i--)
+ pTabData[i] = pTabData[i-1];
+
+ pTabData[nTab] = NULL; // force creating new
+ CreateTabData( nTab );
+
+ UpdateThis();
+ aMarkData.InsertTab( nTab );
+}
+
+void ScViewData::DeleteTab( SCTAB nTab )
+{
+ delete pTabData[nTab];
+
+ for (SCTAB i=nTab; i<MAXTAB; i++)
+ pTabData[i] = pTabData[i+1];
+
+ pTabData[MAXTAB] = NULL;
+
+ UpdateThis();
+ aMarkData.DeleteTab( nTab );
+}
+
+void ScViewData::CopyTab( SCTAB nSrcTab, SCTAB nDestTab )
+{
+ if (nDestTab==SC_TAB_APPEND)
+ nDestTab = pDoc->GetTableCount() - 1; // am Doc muss vorher kopiert worden sein
+
+ if (nDestTab > MAXTAB)
+ {
+ DBG_ERROR("Zuviele Tabellen");
+ return;
+ }
+
+ delete pTabData[MAXTAB];
+
+ for (SCTAB i=MAXTAB; i>nDestTab; i--)
+ pTabData[i] = pTabData[i-1];
+
+ if ( pTabData[nSrcTab] )
+ pTabData[nDestTab] = new ScViewDataTable( *pTabData[nSrcTab] );
+ else
+ pTabData[nDestTab] = NULL;
+
+ UpdateThis();
+ aMarkData.InsertTab( nDestTab );
+}
+
+void ScViewData::MoveTab( SCTAB nSrcTab, SCTAB nDestTab )
+{
+ if (nDestTab==SC_TAB_APPEND)
+ nDestTab = pDoc->GetTableCount() - 1;
+
+ SCTAB i;
+ ScViewDataTable* pTab = pTabData[nSrcTab];
+
+ SCTAB nInsTab = nDestTab;
+ if ( nSrcTab < nDestTab )
+ {
+ --nInsTab;
+ for (i=nSrcTab; i<nDestTab; i++)
+ pTabData[i] = pTabData[i+1];
+ }
+ else
+ for (i=nSrcTab; i>nDestTab; i--)
+ pTabData[i] = pTabData[i-1];
+
+ pTabData[nDestTab] = pTab;
+
+ UpdateThis();
+ aMarkData.DeleteTab( nSrcTab );
+ aMarkData.InsertTab( nInsTab ); // ggf. angepasst
+}
+
+//UNUSED2008-05 void ScViewData::UpdateOle( ScSplitPos /* eWhich */ )
+//UNUSED2008-05 {
+//UNUSED2008-05 GetDocShell()->UpdateOle(this);
+//UNUSED2008-05 }
+
+void ScViewData::SetViewShell( ScTabViewShell* pViewSh )
+{
+ if (pViewSh)
+ {
+ pViewShell = pViewSh;
+ pView = pViewSh;
+ }
+ else
+ {
+ pViewShell = NULL;
+ pView = NULL;
+ }
+}
+void ScViewData::CreateTabData( std::vector< SCTAB >& rvTabs )
+{
+ std::vector< SCTAB >::iterator it_end = rvTabs.end();
+ for ( std::vector< SCTAB >::iterator it = rvTabs.begin(); it != it_end; ++it )
+ if ( !pTabData[*it] )
+ CreateTabData( *it );
+}
+
+void ScViewData::SetZoomType( SvxZoomType eNew, std::vector< SCTAB >& tabs )
+{
+ sal_Bool bAll = ( tabs.size() == 0 );
+
+ if ( !bAll ) // create associated table data
+ CreateTabData( tabs );
+
+ if ( bAll )
+ {
+ for ( SCTAB i = 0; i <= MAXTAB; ++i )
+ {
+ if ( pTabData[i] )
+ pTabData[i]->eZoomType = eNew;
+ }
+ eDefZoomType = eNew;
+ }
+ else
+ {
+ std::vector< SCTAB >::iterator it_end = tabs.end();
+ std::vector< SCTAB >::iterator it = tabs.begin();
+ for ( ; it != it_end; ++it )
+ {
+ SCTAB i = *it;
+ if ( pTabData[i] )
+ pTabData[i]->eZoomType = eNew;
+ }
+ }
+}
+
+void ScViewData::SetZoomType( SvxZoomType eNew, sal_Bool bAll )
+{
+ std::vector< SCTAB > vTabs; // Empty for all tabs
+ if ( !bAll ) // get selected tabs
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ {
+ if ( aMarkData.GetTableSelect(i) )
+ vTabs.push_back( i );
+ }
+ }
+ SetZoomType( eNew, vTabs );
+}
+
+void ScViewData::SetZoom( const Fraction& rNewX, const Fraction& rNewY, std::vector< SCTAB >& tabs )
+{
+ sal_Bool bAll = ( tabs.size() == 0 );
+ if ( !bAll ) // create associated table data
+ CreateTabData( tabs );
+ Fraction aFrac20( 1,5 );
+ Fraction aFrac400( 4,1 );
+
+ Fraction aValidX = rNewX;
+ if (aValidX<aFrac20)
+ aValidX = aFrac20;
+ if (aValidX>aFrac400)
+ aValidX = aFrac400;
+
+ Fraction aValidY = rNewY;
+ if (aValidY<aFrac20)
+ aValidY = aFrac20;
+ if (aValidY>aFrac400)
+ aValidY = aFrac400;
+
+ if ( bAll )
+ {
+ for ( SCTAB i = 0; i <= MAXTAB; ++i )
+ {
+ if ( pTabData[i] )
+ {
+ if ( bPagebreak )
+ {
+ pTabData[i]->aPageZoomX = aValidX;
+ pTabData[i]->aPageZoomY = aValidY;
+ }
+ else
+ {
+ pTabData[i]->aZoomX = aValidX;
+ pTabData[i]->aZoomY = aValidY;
+ }
+ }
+ }
+ if ( bPagebreak )
+ {
+ aDefPageZoomX = aValidX;
+ aDefPageZoomY = aValidY;
+ }
+ else
+ {
+ aDefZoomX = aValidX;
+ aDefZoomY = aValidY;
+ }
+ }
+ else
+ {
+ std::vector< SCTAB >::iterator it_end = tabs.end();
+ std::vector< SCTAB >::iterator it = tabs.begin();
+ for ( ; it != it_end; ++it )
+ {
+ SCTAB i = *it;
+ if ( pTabData[i] )
+ {
+ if ( bPagebreak )
+ {
+ pTabData[i]->aPageZoomX = aValidX;
+ pTabData[i]->aPageZoomY = aValidY;
+ }
+ else
+ {
+ pTabData[i]->aZoomX = aValidX;
+ pTabData[i]->aZoomY = aValidY;
+ }
+ }
+ }
+ }
+ RefreshZoom();
+}
+
+void ScViewData::SetZoom( const Fraction& rNewX, const Fraction& rNewY, sal_Bool bAll )
+{
+ std::vector< SCTAB > vTabs;
+ if ( !bAll ) // get selected tabs
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ {
+ if ( aMarkData.GetTableSelect(i) )
+ vTabs.push_back( i );
+ }
+ }
+ SetZoom( rNewX, rNewY, vTabs );
+}
+
+void ScViewData::RefreshZoom()
+{
+ // recalculate zoom-dependent values (only for current sheet)
+
+ CalcPPT();
+ RecalcPixPos();
+ aScenButSize = Size(0,0);
+ aLogicMode.SetScaleX( GetZoomX() );
+ aLogicMode.SetScaleY( GetZoomY() );
+}
+
+void ScViewData::SetPagebreakMode( sal_Bool bSet )
+{
+ bPagebreak = bSet;
+
+ RefreshZoom();
+}
+
+
+ScMarkType ScViewData::GetSimpleArea( ScRange & rRange, ScMarkData & rNewMark ) const
+{
+ ScMarkType eMarkType = SC_MARK_NONE;
+
+ if ( rNewMark.IsMarked() || rNewMark.IsMultiMarked() )
+ {
+ if ( rNewMark.IsMultiMarked() )
+ rNewMark.MarkToSimple();
+
+ if ( rNewMark.IsMarked() && !rNewMark.IsMultiMarked() )
+ {
+ rNewMark.GetMarkArea( rRange );
+ if (ScViewUtil::HasFiltered( rRange, GetDocument()))
+ eMarkType = SC_MARK_SIMPLE_FILTERED;
+ else
+ eMarkType = SC_MARK_SIMPLE;
+ }
+ else
+ eMarkType = SC_MARK_MULTI;
+ }
+ if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
+ {
+ if (eMarkType == SC_MARK_NONE)
+ eMarkType = SC_MARK_SIMPLE;
+ rRange = ScRange( GetCurX(), GetCurY(), GetTabNo() );
+ }
+ return eMarkType;
+}
+
+
+ScMarkType ScViewData::GetSimpleArea( SCCOL& rStartCol, SCROW& rStartRow, SCTAB& rStartTab,
+ SCCOL& rEndCol, SCROW& rEndRow, SCTAB& rEndTab ) const
+{
+ // parameter bMergeMark is no longer needed: The view's selection is never modified
+ // (a local copy is used), and a multi selection that adds to a single range can always
+ // be treated like a single selection (#108266# - GetSimpleArea isn't used in selection
+ // handling itself)
+
+ ScRange aRange;
+ ScMarkData aNewMark( aMarkData ); // use a local copy for MarkToSimple
+ ScMarkType eMarkType = GetSimpleArea( aRange, aNewMark);
+ aRange.GetVars( rStartCol, rStartRow, rStartTab, rEndCol, rEndRow, rEndTab);
+ return eMarkType;
+}
+
+ScMarkType ScViewData::GetSimpleArea( ScRange& rRange ) const
+{
+ // parameter bMergeMark is no longer needed, see above
+
+ ScMarkData aNewMark( aMarkData ); // use a local copy for MarkToSimple
+ return GetSimpleArea( rRange, aNewMark);
+}
+
+void ScViewData::GetMultiArea( ScRangeListRef& rRange ) const
+{
+ // parameter bMergeMark is no longer needed, see GetSimpleArea
+
+ ScMarkData aNewMark( aMarkData ); // use a local copy for MarkToSimple
+
+ sal_Bool bMulti = aNewMark.IsMultiMarked();
+ if (bMulti)
+ {
+ aNewMark.MarkToSimple();
+ bMulti = aNewMark.IsMultiMarked();
+ }
+ if (bMulti)
+ {
+ rRange = new ScRangeList;
+ aNewMark.FillRangeListWithMarks( rRange, sal_False );
+ }
+ else
+ {
+ ScRange aSimple;
+ GetSimpleArea(aSimple);
+ rRange = new ScRangeList;
+ rRange->Append(aSimple);
+ }
+}
+
+sal_Bool ScViewData::SimpleColMarked()
+{
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+ if (GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
+ if (nStartRow==0 && nEndRow==MAXROW)
+ return sal_True;
+
+ return sal_False;
+}
+
+sal_Bool ScViewData::SimpleRowMarked()
+{
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+ if (GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
+ if (nStartCol==0 && nEndCol==MAXCOL)
+ return sal_True;
+
+ return sal_False;
+}
+
+sal_Bool ScViewData::IsMultiMarked()
+{
+ // Test for "real" multi selection, calling MarkToSimple on a local copy,
+ // and taking filtered in simple area marks into account.
+
+ ScRange aDummy;
+ ScMarkType eType = GetSimpleArea(aDummy);
+ return (eType & SC_MARK_SIMPLE) != SC_MARK_SIMPLE;
+}
+
+void ScViewData::SetFillMode( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
+{
+ nFillMode = SC_FILL_FILL;
+ nFillStartX = nStartCol;
+ nFillStartY = nStartRow;
+ nFillEndX = nEndCol;
+ nFillEndY = nEndRow;
+}
+
+void ScViewData::SetDragMode( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+ sal_uInt8 nMode )
+{
+ nFillMode = nMode;
+ nFillStartX = nStartCol;
+ nFillStartY = nStartRow;
+ nFillEndX = nEndCol;
+ nFillEndY = nEndRow;
+}
+
+void ScViewData::ResetFillMode()
+{
+ nFillMode = SC_FILL_NONE;
+}
+
+void ScViewData::GetFillData( SCCOL& rStartCol, SCROW& rStartRow,
+ SCCOL& rEndCol, SCROW& rEndRow )
+{
+ rStartCol = nFillStartX;
+ rStartRow = nFillStartY;
+ rEndCol = nFillEndX;
+ rEndRow = nFillEndY;
+}
+
+SCCOL ScViewData::GetOldCurX() const
+{
+ if (pThisTab->bOldCurValid)
+ return pThisTab->nOldCurX;
+ else
+ return pThisTab->nCurX;
+}
+
+SCROW ScViewData::GetOldCurY() const
+{
+ if (pThisTab->bOldCurValid)
+ return pThisTab->nOldCurY;
+ else
+ return pThisTab->nCurY;
+}
+
+void ScViewData::SetOldCursor( SCCOL nNewX, SCROW nNewY )
+{
+ pThisTab->nOldCurX = nNewX;
+ pThisTab->nOldCurY = nNewY;
+ pThisTab->bOldCurValid = sal_True;
+}
+
+void ScViewData::ResetOldCursor()
+{
+ pThisTab->bOldCurValid = sal_False;
+}
+
+Rectangle ScViewData::GetEditArea( ScSplitPos eWhich, SCCOL nPosX, SCROW nPosY,
+ Window* pWin, const ScPatternAttr* pPattern,
+ sal_Bool bForceToTop )
+{
+ return ScEditUtil( pDoc, nPosX, nPosY, nTabNo, GetScrPos(nPosX,nPosY,eWhich,sal_True),
+ pWin, nPPTX, nPPTY, GetZoomX(), GetZoomY() ).
+ GetEditArea( pPattern, bForceToTop );
+}
+
+void ScViewData::SetEditEngine( ScSplitPos eWhich,
+ ScEditEngineDefaulter* pNewEngine,
+ Window* pWin, SCCOL nNewX, SCROW nNewY )
+{
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTabNo );
+ ScHSplitPos eHWhich = WhichH(eWhich);
+
+ sal_Bool bWasThere = sal_False;
+ if (pEditView[eWhich])
+ {
+ // Wenn die View schon da ist, nichts aufrufen, was die Cursorposition aendert
+
+ if (bEditActive[eWhich])
+ bWasThere = sal_True;
+ else
+ pEditView[eWhich]->SetEditEngine(pNewEngine);
+
+ if (pEditView[eWhich]->GetWindow() != pWin)
+ {
+ pEditView[eWhich]->SetWindow(pWin);
+ DBG_ERROR("EditView Window geaendert");
+ }
+ }
+ else
+ {
+ pEditView[eWhich] = new EditView( pNewEngine, pWin );
+ }
+
+ // bei IdleFormat wird manchmal ein Cursor gemalt, wenn die View schon weg ist (23576)
+
+ sal_uLong nEC = pNewEngine->GetControlWord();
+ pNewEngine->SetControlWord(nEC & ~EE_CNTRL_DOIDLEFORMAT);
+
+ sal_uLong nVC = pEditView[eWhich]->GetControlWord();
+ pEditView[eWhich]->SetControlWord(nVC & ~EV_CNTRL_AUTOSCROLL);
+
+ bEditActive[eWhich] = sal_True;
+
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nNewX, nNewY, nTabNo );
+ SvxCellHorJustify eJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
+ pPattern->GetItem( ATTR_HOR_JUSTIFY )).GetValue();
+
+ sal_Bool bBreak = ( eJust == SVX_HOR_JUSTIFY_BLOCK ) ||
+ ((SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue();
+
+ sal_Bool bAsianVertical = pNewEngine->IsVertical(); // set by InputHandler
+
+ Rectangle aPixRect = ScEditUtil( pDoc, nNewX,nNewY,nTabNo, GetScrPos(nNewX,nNewY,eWhich),
+ pWin, nPPTX,nPPTY,GetZoomX(),GetZoomY() ).
+ GetEditArea( pPattern, sal_True );
+
+ // when right-aligned, leave space for the cursor
+ // in vertical mode, editing is always right-aligned
+ if ( nEditAdjust == SVX_ADJUST_RIGHT || bAsianVertical )
+ aPixRect.Right() += 1;
+
+ Rectangle aOutputArea = pWin->PixelToLogic( aPixRect, GetLogicMode() );
+ pEditView[eWhich]->SetOutputArea( aOutputArea );
+
+ if ( bActive && eWhich == GetActivePart() )
+ {
+ // keep the part that has the active edit view available after
+ // switching sheets or reference input on a different part
+ eEditActivePart = eWhich;
+
+ // modify members nEditCol etc. only if also extending for needed area
+ nEditCol = nNewX;
+ nEditRow = nNewY;
+ const ScMergeAttr* pMergeAttr = (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
+ nEditEndCol = nEditCol;
+ if (pMergeAttr->GetColMerge() > 1)
+ nEditEndCol += pMergeAttr->GetColMerge() - 1;
+ nEditEndRow = nEditRow;
+ if (pMergeAttr->GetRowMerge() > 1)
+ nEditEndRow += pMergeAttr->GetRowMerge() - 1;
+ nEditStartCol = nEditCol;
+
+ // For growing use only the alignment value from the attribute, numbers
+ // (existing or started) with default aligment extend to the right.
+ sal_Bool bGrowCentered = ( eJust == SVX_HOR_JUSTIFY_CENTER );
+ sal_Bool bGrowToLeft = ( eJust == SVX_HOR_JUSTIFY_RIGHT ); // visual left
+ sal_Bool bGrowBackwards = bGrowToLeft; // logical left
+ if ( bLayoutRTL )
+ bGrowBackwards = !bGrowBackwards; // invert on RTL sheet
+ if ( bAsianVertical )
+ bGrowCentered = bGrowToLeft = bGrowBackwards = sal_False; // keep old behavior for asian mode
+
+ long nSizeXPix;
+ if (bBreak && !bAsianVertical)
+ nSizeXPix = aPixRect.GetWidth(); // Papersize -> kein H-Scrolling
+ else
+ {
+ DBG_ASSERT(pView,"keine View fuer EditView");
+
+ if ( bGrowCentered )
+ {
+ // growing into both directions until one edge is reached
+ //! should be limited to whole cells in both directions
+ long nLeft = aPixRect.Left();
+ long nRight = pView->GetGridWidth(eHWhich) - aPixRect.Right();
+ nSizeXPix = aPixRect.GetWidth() + 2 * Min( nLeft, nRight );
+ }
+ else if ( bGrowToLeft )
+ nSizeXPix = aPixRect.Right(); // space that's available in the window when growing to the left
+ else
+ nSizeXPix = pView->GetGridWidth(eHWhich) - aPixRect.Left();
+
+ if ( nSizeXPix <= 0 )
+ nSizeXPix = aPixRect.GetWidth(); // editing outside to the right of the window -> keep cell width
+ }
+ DBG_ASSERT(pView,"keine View fuer EditView");
+ long nSizeYPix = pView->GetGridHeight(WhichV(eWhich)) - aPixRect.Top();
+ if ( nSizeYPix <= 0 )
+ nSizeYPix = aPixRect.GetHeight(); // editing outside below the window -> keep cell height
+
+ Size aPaperSize = pView->GetActiveWin()->PixelToLogic( Size( nSizeXPix, nSizeYPix ), GetLogicMode() );
+ if ( bBreak && !bAsianVertical && SC_MOD()->GetInputOptions().GetTextWysiwyg() )
+ {
+ // #95593# if text is formatted for printer, use the exact same paper width
+ // (and same line breaks) as for output.
+
+ Fraction aFract(1,1);
+ Rectangle aUtilRect = ScEditUtil( pDoc,nNewX,nNewY,nTabNo, Point(0,0), pWin,
+ HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( pPattern, sal_False );
+ aPaperSize.Width() = aUtilRect.GetWidth();
+ }
+ pNewEngine->SetPaperSize( aPaperSize );
+
+ // sichtbarer Ausschnitt
+ Size aPaper = pNewEngine->GetPaperSize();
+ Rectangle aVis = pEditView[eWhich]->GetVisArea();
+ long nDiff = aVis.Right() - aVis.Left();
+ if ( nEditAdjust == SVX_ADJUST_RIGHT )
+ {
+ aVis.Right() = aPaper.Width() - 1;
+ bMoveArea = !bLayoutRTL;
+ }
+ else if ( nEditAdjust == SVX_ADJUST_CENTER )
+ {
+ aVis.Right() = ( aPaper.Width() - 1 + nDiff ) / 2;
+ bMoveArea = sal_True; // always
+ }
+ else
+ {
+ aVis.Right() = nDiff;
+ bMoveArea = bLayoutRTL;
+ }
+ aVis.Left() = aVis.Right() - nDiff;
+ // --> OD 2005-12-22 #i49561#
+ // Important note:
+ // The set offset of the visible area of the EditView for centered and
+ // right alignment in horizontal layout is consider by instances of
+ // class <ScEditObjectViewForwarder> in its methods <LogicToPixel(..)>
+ // and <PixelToLogic(..)>. This is needed for the correct visibility
+ // of paragraphs in edit mode at the accessibility API.
+ // <--
+ pEditView[eWhich]->SetVisArea(aVis);
+ //
+
+ // UpdateMode has been disabled in ScInputHandler::StartTable
+ // must be enabled before EditGrowY (GetTextHeight)
+ pNewEngine->SetUpdateMode( sal_True );
+
+ pNewEngine->SetStatusEventHdl( LINK( this, ScViewData, EditEngineHdl ) );
+
+ EditGrowY( sal_True ); // adjust to existing text content
+ EditGrowX();
+
+ Point aDocPos = pEditView[eWhich]->GetWindowPosTopLeft(0);
+ if (aDocPos.Y() < aOutputArea.Top())
+ pEditView[eWhich]->Scroll( 0, aOutputArea.Top() - aDocPos.Y() );
+
+ //! Status (Event) zuruecksetzen
+ }
+
+ // hier muss bEditActive schon gesetzt sein
+ // (wegen Map-Mode bei Paint)
+ if (!bWasThere)
+ pNewEngine->InsertView(pEditView[eWhich]);
+
+ // Hintergrundfarbe der Zelle
+ Color aBackCol = ((const SvxBrushItem&)pPattern->GetItem(ATTR_BACKGROUND)).GetColor();
+
+ ScModule* pScMod = SC_MOD();
+ // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
+ if ( aBackCol.GetTransparency() > 0 ||
+ Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
+ {
+ aBackCol.SetColor( pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
+ }
+ pEditView[eWhich]->SetBackgroundColor( aBackCol );
+
+ pEditView[eWhich]->Invalidate(); // noetig ??
+ // noetig, wenn Position geaendert
+}
+
+IMPL_LINK_INLINE_START( ScViewData, EmptyEditHdl, EditStatus *, EMPTYARG )
+{
+ return 0;
+}
+IMPL_LINK_INLINE_END( ScViewData, EmptyEditHdl, EditStatus *, EMPTYARG )
+
+IMPL_LINK( ScViewData, EditEngineHdl, EditStatus *, pStatus )
+{
+ sal_uLong nStatus = pStatus->GetStatusWord();
+ if (nStatus & (EE_STAT_HSCROLL | EE_STAT_TEXTHEIGHTCHANGED | EE_STAT_TEXTWIDTHCHANGED | EE_STAT_CURSOROUT))
+ {
+ EditGrowY();
+ EditGrowX();
+
+ if (nStatus & EE_STAT_CURSOROUT)
+ {
+ ScSplitPos eWhich = GetActivePart();
+ if (pEditView[eWhich])
+ pEditView[eWhich]->ShowCursor(sal_False);
+ }
+ }
+ return 0;
+}
+
+void ScViewData::EditGrowX()
+{
+ ScDocument* pLocalDoc = GetDocument();
+
+ ScSplitPos eWhich = GetActivePart();
+ ScHSplitPos eHWhich = WhichH(eWhich);
+ EditView* pCurView = pEditView[eWhich];
+
+ if ( !pCurView || !bEditActive[eWhich])
+ return;
+
+ sal_Bool bLayoutRTL = pLocalDoc->IsLayoutRTL( nTabNo );
+
+ ScEditEngineDefaulter* pEngine =
+ (ScEditEngineDefaulter*) pCurView->GetEditEngine();
+ Window* pWin = pCurView->GetWindow();
+
+ SCCOL nLeft = GetPosX(eHWhich);
+ SCCOL nRight = nLeft + VisibleCellsX(eHWhich);
+
+ Size aSize = pEngine->GetPaperSize();
+ Rectangle aArea = pCurView->GetOutputArea();
+ long nOldRight = aArea.Right();
+
+ // Margin ist schon bei der urspruenglichen Breite beruecksichtigt
+ long nTextWidth = pEngine->CalcTextWidth();
+
+ sal_Bool bChanged = sal_False;
+ sal_Bool bAsianVertical = pEngine->IsVertical();
+
+ // get bGrow... variables the same way as in SetEditEngine
+ const ScPatternAttr* pPattern = pLocalDoc->GetPattern( nEditCol, nEditRow, nTabNo );
+ SvxCellHorJustify eJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
+ pPattern->GetItem( ATTR_HOR_JUSTIFY )).GetValue();
+ sal_Bool bGrowCentered = ( eJust == SVX_HOR_JUSTIFY_CENTER );
+ sal_Bool bGrowToLeft = ( eJust == SVX_HOR_JUSTIFY_RIGHT ); // visual left
+ sal_Bool bGrowBackwards = bGrowToLeft; // logical left
+ if ( bLayoutRTL )
+ bGrowBackwards = !bGrowBackwards; // invert on RTL sheet
+ if ( bAsianVertical )
+ bGrowCentered = bGrowToLeft = bGrowBackwards = sal_False; // keep old behavior for asian mode
+
+ sal_Bool bUnevenGrow = sal_False;
+ if ( bGrowCentered )
+ {
+ while (aArea.GetWidth() + 0 < nTextWidth && ( nEditStartCol > nLeft || nEditEndCol < nRight ) )
+ {
+ long nLogicLeft = 0;
+ if ( nEditStartCol > nLeft )
+ {
+ --nEditStartCol;
+ long nLeftPix = ToPixel( pLocalDoc->GetColWidth( nEditStartCol, nTabNo ), nPPTX );
+ nLogicLeft = pWin->PixelToLogic(Size(nLeftPix,0)).Width();
+ }
+ long nLogicRight = 0;
+ if ( nEditEndCol < nRight )
+ {
+ ++nEditEndCol;
+ long nRightPix = ToPixel( pLocalDoc->GetColWidth( nEditEndCol, nTabNo ), nPPTX );
+ nLogicRight = pWin->PixelToLogic(Size(nRightPix,0)).Width();
+ }
+
+ aArea.Left() -= bLayoutRTL ? nLogicRight : nLogicLeft;
+ aArea.Right() += bLayoutRTL ? nLogicLeft : nLogicRight;
+
+ if ( aArea.Right() > aArea.Left() + aSize.Width() - 1 )
+ {
+ long nCenter = ( aArea.Left() + aArea.Right() ) / 2;
+ long nHalf = aSize.Width() / 2;
+ aArea.Left() = nCenter - nHalf + 1;
+ aArea.Right() = nCenter + aSize.Width() - nHalf - 1;
+ }
+
+ bChanged = sal_True;
+ if ( nLogicLeft != nLogicRight )
+ bUnevenGrow = sal_True;
+ }
+ }
+ else if ( bGrowBackwards )
+ {
+ while (aArea.GetWidth() + 0 < nTextWidth && nEditStartCol > nLeft)
+ {
+ --nEditStartCol;
+ long nPix = ToPixel( pLocalDoc->GetColWidth( nEditStartCol, nTabNo ), nPPTX );
+ long nLogicWidth = pWin->PixelToLogic(Size(nPix,0)).Width();
+ if ( !bLayoutRTL )
+ aArea.Left() -= nLogicWidth;
+ else
+ aArea.Right() += nLogicWidth;
+
+ if ( aArea.Right() > aArea.Left() + aSize.Width() - 1 )
+ {
+ if ( !bLayoutRTL )
+ aArea.Left() = aArea.Right() - aSize.Width() + 1;
+ else
+ aArea.Right() = aArea.Left() + aSize.Width() - 1;
+ }
+
+ bChanged = sal_True;
+ }
+ }
+ else
+ {
+ while (aArea.GetWidth() + 0 < nTextWidth && nEditEndCol < nRight)
+ {
+ ++nEditEndCol;
+ long nPix = ToPixel( pLocalDoc->GetColWidth( nEditEndCol, nTabNo ), nPPTX );
+ long nLogicWidth = pWin->PixelToLogic(Size(nPix,0)).Width();
+ if ( bLayoutRTL )
+ aArea.Left() -= nLogicWidth;
+ else
+ aArea.Right() += nLogicWidth;
+
+ if ( aArea.Right() > aArea.Left() + aSize.Width() - 1 )
+ {
+ if ( bLayoutRTL )
+ aArea.Left() = aArea.Right() - aSize.Width() + 1;
+ else
+ aArea.Right() = aArea.Left() + aSize.Width() - 1;
+ }
+
+ bChanged = sal_True;
+ }
+ }
+
+ if (bChanged)
+ {
+ if ( bMoveArea || bGrowCentered || bGrowBackwards || bLayoutRTL )
+ {
+ Rectangle aVis = pCurView->GetVisArea();
+
+ if ( bGrowCentered )
+ {
+ // switch to center-aligned (undo?) and reset VisArea to center
+
+ pEngine->SetDefaultItem( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) );
+
+ long nCenter = aSize.Width() / 2;
+ long nVisSize = aArea.GetWidth();
+ aVis.Left() = nCenter - nVisSize / 2;
+ aVis.Right() = aVis.Left() + nVisSize - 1;
+ }
+ else if ( bGrowToLeft )
+ {
+ // switch to right-aligned (undo?) and reset VisArea to the right
+
+ pEngine->SetDefaultItem( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
+
+ aVis.Right() = aSize.Width() - 1;
+ aVis.Left() = aSize.Width() - aArea.GetWidth(); // with the new, increased area
+ }
+ else
+ {
+ // switch to left-aligned (undo?) and reset VisArea to the left
+
+ pEngine->SetDefaultItem( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
+
+ long nMove = aVis.Left();
+ aVis.Left() = 0;
+ aVis.Right() -= nMove;
+ }
+ pCurView->SetVisArea( aVis );
+ bMoveArea = sal_False;
+ }
+
+ pCurView->SetOutputArea(aArea);
+
+ // In vertical mode, the whole text is moved to the next cell (right-aligned),
+ // so everything must be repainted. Otherwise, paint only the new area.
+ // If growing in centered alignment, if the cells left and right have different sizes,
+ // the whole text will move, and may not even obscure all of the original display.
+ if ( bUnevenGrow )
+ {
+ aArea.Left() = pWin->PixelToLogic( Point(0,0) ).X();
+ aArea.Right() = pWin->PixelToLogic( aScrSize ).Width();
+ }
+ else if ( !bAsianVertical && !bGrowToLeft && !bGrowCentered )
+ aArea.Left() = nOldRight;
+ pWin->Invalidate(aArea);
+ }
+}
+
+void ScViewData::EditGrowY( sal_Bool bInitial )
+{
+ ScSplitPos eWhich = GetActivePart();
+ ScVSplitPos eVWhich = WhichV(eWhich);
+ EditView* pCurView = pEditView[eWhich];
+
+ if ( !pCurView || !bEditActive[eWhich])
+ return;
+
+ sal_uLong nControl = pEditView[eWhich]->GetControlWord();
+ if ( nControl & EV_CNTRL_AUTOSCROLL )
+ {
+ // if end of screen had already been reached and scrolling enabled,
+ // don't further try to grow the edit area
+
+ pCurView->SetOutputArea( pCurView->GetOutputArea() ); // re-align to pixels
+ return;
+ }
+
+ EditEngine* pEngine = pCurView->GetEditEngine();
+ Window* pWin = pCurView->GetWindow();
+
+ SCROW nBottom = GetPosY(eVWhich) + VisibleCellsY(eVWhich);
+
+ Size aSize = pEngine->GetPaperSize();
+ Rectangle aArea = pCurView->GetOutputArea();
+ long nOldBottom = aArea.Bottom();
+ long nTextHeight = pEngine->GetTextHeight();
+
+ // #106635# When editing a formula in a cell with optimal height, allow a larger portion
+ // to be clipped before extending to following rows, to avoid obscuring cells for
+ // reference input (next row is likely to be useful in formulas).
+ long nAllowedExtra = SC_GROWY_SMALL_EXTRA;
+ if ( nEditEndRow == nEditRow && !( pDoc->GetRowFlags( nEditRow, nTabNo ) & CR_MANUALSIZE ) &&
+ pEngine->GetParagraphCount() <= 1 )
+ {
+ // If the (only) paragraph starts with a '=', it's a formula.
+ // If this is the initial call and the text is empty, allow the larger value, too,
+ // because this occurs in the normal progress of editing a formula.
+ // Subsequent calls with empty text might involve changed attributes (including
+ // font height), so they are treated like normal text.
+ String aText = pEngine->GetText( (sal_uInt16) 0 );
+ if ( ( aText.Len() == 0 && bInitial ) || aText.GetChar(0) == (sal_Unicode)'=' )
+ nAllowedExtra = SC_GROWY_BIG_EXTRA;
+ }
+
+ sal_Bool bChanged = sal_False;
+ sal_Bool bMaxReached = sal_False;
+ while (aArea.GetHeight() + nAllowedExtra < nTextHeight && nEditEndRow < nBottom && !bMaxReached)
+ {
+ ++nEditEndRow;
+ ScDocument* pLocalDoc = GetDocument();
+ long nPix = ToPixel( pLocalDoc->GetRowHeight( nEditEndRow, nTabNo ), nPPTY );
+ aArea.Bottom() += pWin->PixelToLogic(Size(0,nPix)).Height();
+
+ if ( aArea.Bottom() > aArea.Top() + aSize.Height() - 1 )
+ {
+ aArea.Bottom() = aArea.Top() + aSize.Height() - 1;
+ bMaxReached = sal_True; // don't occupy more cells beyond paper size
+ }
+
+ bChanged = sal_True;
+ nAllowedExtra = SC_GROWY_SMALL_EXTRA; // larger value is only for first row
+ }
+
+ if (bChanged)
+ {
+ pCurView->SetOutputArea(aArea);
+
+ if (nEditEndRow >= nBottom || bMaxReached)
+ {
+ if ((nControl & EV_CNTRL_AUTOSCROLL) == 0)
+ pCurView->SetControlWord( nControl | EV_CNTRL_AUTOSCROLL );
+ }
+
+ aArea.Top() = nOldBottom;
+ pWin->Invalidate(aArea);
+ }
+}
+
+void ScViewData::ResetEditView()
+{
+ EditEngine* pEngine = NULL;
+ for (sal_uInt16 i=0; i<4; i++)
+ if (pEditView[i])
+ {
+ if (bEditActive[i])
+ {
+ pEngine = pEditView[i]->GetEditEngine();
+ pEngine->RemoveView(pEditView[i]);
+ pEditView[i]->SetOutputArea( Rectangle() );
+ }
+ bEditActive[i] = sal_False;
+ }
+
+ if (pEngine)
+ pEngine->SetStatusEventHdl( LINK( this, ScViewData, EmptyEditHdl ) );
+}
+
+void ScViewData::KillEditView()
+{
+ for (sal_uInt16 i=0; i<4; i++)
+ if (pEditView[i])
+ {
+ if (bEditActive[i])
+ pEditView[i]->GetEditEngine()->RemoveView(pEditView[i]);
+ delete pEditView[i];
+ pEditView[i] = NULL;
+ }
+}
+
+void ScViewData::GetEditView( ScSplitPos eWhich, EditView*& rViewPtr, SCCOL& rCol, SCROW& rRow )
+{
+ rViewPtr = pEditView[eWhich];
+ rCol = nEditCol;
+ rRow = nEditRow;
+}
+
+void ScViewData::CreateTabData( SCTAB nNewTab )
+{
+ if (!pTabData[nNewTab])
+ {
+ pTabData[nNewTab] = new ScViewDataTable;
+
+ pTabData[nNewTab]->eZoomType = eDefZoomType;
+ pTabData[nNewTab]->aZoomX = aDefZoomX;
+ pTabData[nNewTab]->aZoomY = aDefZoomY;
+ pTabData[nNewTab]->aPageZoomX = aDefPageZoomX;
+ pTabData[nNewTab]->aPageZoomY = aDefPageZoomY;
+ }
+}
+
+void ScViewData::CreateSelectedTabData()
+{
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ if ( aMarkData.GetTableSelect(i) && !pTabData[i] )
+ CreateTabData( i );
+}
+
+void ScViewData::SetTabNo( SCTAB nNewTab )
+{
+ if (!ValidTab(nNewTab))
+ {
+ DBG_ERROR("falsche Tabellennummer");
+ return;
+ }
+
+ nTabNo = nNewTab;
+ CreateTabData(nTabNo);
+ pThisTab = pTabData[nTabNo];
+
+ CalcPPT(); // for common column width correction
+ RecalcPixPos(); //! nicht immer noetig!
+}
+
+void ScViewData::SetActivePart( ScSplitPos eNewActive )
+{
+ pThisTab->eWhichActive = eNewActive;
+}
+
+Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScHSplitPos eWhich ) const
+{
+ DBG_ASSERT( eWhich==SC_SPLIT_LEFT || eWhich==SC_SPLIT_RIGHT, "Falsche Position" );
+ ScSplitPos ePos = ( eWhich == SC_SPLIT_LEFT ) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
+ return GetScrPos( nWhereX, nWhereY, ePos );
+}
+
+Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScVSplitPos eWhich ) const
+{
+ DBG_ASSERT( eWhich==SC_SPLIT_TOP || eWhich==SC_SPLIT_BOTTOM, "Falsche Position" );
+ ScSplitPos ePos = ( eWhich == SC_SPLIT_TOP ) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
+ return GetScrPos( nWhereX, nWhereY, ePos );
+}
+
+Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
+ sal_Bool bAllowNeg ) const
+{
+ ScHSplitPos eWhichX = SC_SPLIT_LEFT;
+ ScVSplitPos eWhichY = SC_SPLIT_BOTTOM;
+ switch( eWhich )
+ {
+ case SC_SPLIT_TOPLEFT:
+ eWhichX = SC_SPLIT_LEFT;
+ eWhichY = SC_SPLIT_TOP;
+ break;
+ case SC_SPLIT_TOPRIGHT:
+ eWhichX = SC_SPLIT_RIGHT;
+ eWhichY = SC_SPLIT_TOP;
+ break;
+ case SC_SPLIT_BOTTOMLEFT:
+ eWhichX = SC_SPLIT_LEFT;
+ eWhichY = SC_SPLIT_BOTTOM;
+ break;
+ case SC_SPLIT_BOTTOMRIGHT:
+ eWhichX = SC_SPLIT_RIGHT;
+ eWhichY = SC_SPLIT_BOTTOM;
+ break;
+ }
+
+ if (pView)
+ {
+ ((ScViewData*)this)->aScrSize.Width() = pView->GetGridWidth(eWhichX);
+ ((ScViewData*)this)->aScrSize.Height() = pView->GetGridHeight(eWhichY);
+ }
+
+ sal_uInt16 nTSize;
+
+ SCCOL nPosX = GetPosX(eWhichX);
+ SCCOL nX;
+
+ long nScrPosX=0;
+ if (nWhereX >= nPosX)
+ for (nX=nPosX; nX<nWhereX && (bAllowNeg || nScrPosX<=aScrSize.Width()); nX++)
+ {
+ if ( nX > MAXCOL )
+ nScrPosX = 65535;
+ else
+ {
+ nTSize = pDoc->GetColWidth( nX, nTabNo );
+ if (nTSize)
+ {
+ long nSizeXPix = ToPixel( nTSize, nPPTX );
+ nScrPosX += nSizeXPix;
+ }
+ }
+ }
+ else if (bAllowNeg)
+ for (nX=nPosX; nX>nWhereX;)
+ {
+ --nX;
+ nTSize = pDoc->GetColWidth( nX, nTabNo );
+ if (nTSize)
+ {
+ long nSizeXPix = ToPixel( nTSize, nPPTX );
+ nScrPosX -= nSizeXPix;
+ }
+ }
+
+ SCROW nPosY = GetPosY(eWhichY);
+ SCROW nY;
+
+ long nScrPosY=0;
+ if (nWhereY >= nPosY)
+ for (nY=nPosY; nY<nWhereY && (bAllowNeg || nScrPosY<=aScrSize.Height()); nY++)
+ {
+ if ( nY > MAXROW )
+ nScrPosY = 65535;
+ else
+ {
+ nTSize = pDoc->GetRowHeight( nY, nTabNo );
+ if (nTSize)
+ {
+ long nSizeYPix = ToPixel( nTSize, nPPTY );
+ nScrPosY += nSizeYPix;
+ }
+ else if ( nY < MAXROW )
+ {
+ // skip multiple hidden rows (forward only for now)
+ SCROW nNext = pDoc->FirstVisibleRow(nY + 1, MAXROW, nTabNo);
+ if ( nNext > MAXROW )
+ nY = MAXROW;
+ else
+ nY = nNext - 1; // +=nDir advances to next visible row
+ }
+ }
+ }
+ else if (bAllowNeg)
+ for (nY=nPosY; nY>nWhereY;)
+ {
+ --nY;
+ nTSize = pDoc->GetRowHeight( nY, nTabNo );
+ if (nTSize)
+ {
+ long nSizeYPix = ToPixel( nTSize, nPPTY );
+ nScrPosY -= nSizeYPix;
+ }
+ }
+
+ if ( pDoc->IsLayoutRTL( nTabNo ) )
+ {
+ // mirror horizontal position
+ nScrPosX = aScrSize.Width() - 1 - nScrPosX;
+ }
+
+ if (nScrPosX > 32767) nScrPosX=32767;
+ if (nScrPosY > 32767) nScrPosY=32767;
+ return Point( nScrPosX, nScrPosY );
+}
+
+//
+// Anzahl Zellen auf einem Bildschirm
+//
+
+SCCOL ScViewData::CellsAtX( SCsCOL nPosX, SCsCOL nDir, ScHSplitPos eWhichX, sal_uInt16 nScrSizeX ) const
+{
+ DBG_ASSERT( nDir==1 || nDir==-1, "falscher CellsAt Aufruf" );
+
+ if (pView)
+ ((ScViewData*)this)->aScrSize.Width() = pView->GetGridWidth(eWhichX);
+
+ SCsCOL nX;
+ sal_uInt16 nScrPosX = 0;
+ if (nScrSizeX == SC_SIZE_NONE) nScrSizeX = (sal_uInt16) aScrSize.Width();
+
+ if (nDir==1)
+ nX = nPosX; // vorwaerts
+ else
+ nX = nPosX-1; // rueckwaerts
+
+ sal_Bool bOut = sal_False;
+ for ( ; nScrPosX<=nScrSizeX && !bOut; nX = sal::static_int_cast<SCsCOL>(nX + nDir) )
+ {
+ SCsCOL nColNo = nX;
+ if ( nColNo < 0 || nColNo > MAXCOL )
+ bOut = sal_True;
+ else
+ {
+ sal_uInt16 nTSize = pDoc->GetColWidth( nColNo, nTabNo );
+ if (nTSize)
+ {
+ long nSizeXPix = ToPixel( nTSize, nPPTX );
+ nScrPosX = sal::static_int_cast<sal_uInt16>( nScrPosX + (sal_uInt16) nSizeXPix );
+ }
+ }
+ }
+
+ if (nDir==1)
+ nX = sal::static_int_cast<SCsCOL>( nX - nPosX );
+ else
+ nX = (nPosX-1)-nX;
+
+ if (nX>0) --nX;
+ return nX;
+}
+
+SCROW ScViewData::CellsAtY( SCsROW nPosY, SCsROW nDir, ScVSplitPos eWhichY, sal_uInt16 nScrSizeY ) const
+{
+ DBG_ASSERT( nDir==1 || nDir==-1, "falscher CellsAt Aufruf" );
+
+ if (pView)
+ ((ScViewData*)this)->aScrSize.Height() = pView->GetGridHeight(eWhichY);
+
+ if (nScrSizeY == SC_SIZE_NONE) nScrSizeY = (sal_uInt16) aScrSize.Height();
+
+ SCROW nY;
+
+ if (nDir==1)
+ {
+ // forward
+ nY = nPosY;
+ long nScrPosY = 0;
+ AddPixelsWhile( nScrPosY, nScrSizeY, nY, MAXROW, nPPTY, pDoc, nTabNo);
+ // Original loop ended on last evaluated +1 or if that was MAXROW even
+ // on MAXROW+2.
+ nY += (nY == MAXROW ? 2 : 1);
+ nY -= nPosY;
+ }
+ else
+ {
+ // backward
+ nY = nPosY-1;
+ long nScrPosY = 0;
+ AddPixelsWhileBackward( nScrPosY, nScrSizeY, nY, 0, nPPTY, pDoc, nTabNo);
+ // Original loop ended on last evaluated -1 or if that was 0 even on
+ // -2.
+ nY -= (nY == 0 ? 2 : 1);
+ nY = (nPosY-1)-nY;
+ }
+
+ if (nY>0) --nY;
+ return nY;
+}
+
+SCCOL ScViewData::VisibleCellsX( ScHSplitPos eWhichX ) const
+{
+ return CellsAtX( GetPosX( eWhichX ), 1, eWhichX, SC_SIZE_NONE );
+}
+
+SCROW ScViewData::VisibleCellsY( ScVSplitPos eWhichY ) const
+{
+ return CellsAtY( GetPosY( eWhichY ), 1, eWhichY, SC_SIZE_NONE );
+}
+
+SCCOL ScViewData::PrevCellsX( ScHSplitPos eWhichX ) const
+{
+ return CellsAtX( GetPosX( eWhichX ), -1, eWhichX, SC_SIZE_NONE );
+}
+
+SCROW ScViewData::PrevCellsY( ScVSplitPos eWhichY ) const
+{
+ return CellsAtY( GetPosY( eWhichY ), -1, eWhichY, SC_SIZE_NONE );
+}
+
+//UNUSED2008-05 SCCOL ScViewData::LastCellsX( ScHSplitPos eWhichX ) const
+//UNUSED2008-05 {
+//UNUSED2008-05 return CellsAtX( MAXCOL+1, -1, eWhichX, SC_SIZE_NONE );
+//UNUSED2008-05 }
+//UNUSED2008-05
+//UNUSED2008-05 SCROW ScViewData::LastCellsY( ScVSplitPos eWhichY ) const
+//UNUSED2008-05 {
+//UNUSED2008-05 return CellsAtY( MAXROW+1, -1, eWhichY, SC_SIZE_NONE );
+//UNUSED2008-05 }
+
+sal_Bool ScViewData::GetMergeSizePixel( SCCOL nX, SCROW nY, long& rSizeXPix, long& rSizeYPix )
+{
+ const ScMergeAttr* pMerge = (const ScMergeAttr*) pDoc->GetAttr( nX,nY,nTabNo, ATTR_MERGE );
+ if ( pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1 )
+ {
+ long nOutWidth = 0;
+ long nOutHeight = 0;
+ SCCOL nCountX = pMerge->GetColMerge();
+ for (SCCOL i=0; i<nCountX; i++)
+ nOutWidth += ToPixel( pDoc->GetColWidth(nX+i,nTabNo), nPPTX );
+ SCROW nCountY = pMerge->GetRowMerge();
+
+ for (SCROW nRow = nY; nRow <= nY+nCountY-1; ++nRow)
+ {
+ SCROW nLastRow = nRow;
+ if (pDoc->RowHidden(nRow, nTabNo, NULL, &nLastRow))
+ {
+ nRow = nLastRow;
+ continue;
+ }
+
+ sal_uInt16 nHeight = pDoc->GetRowHeight(nRow, nTabNo);
+ nOutHeight += ToPixel(nHeight, nPPTY);
+ }
+
+ rSizeXPix = nOutWidth;
+ rSizeYPix = nOutHeight;
+ return sal_True;
+ }
+ else
+ {
+ rSizeXPix = ToPixel( pDoc->GetColWidth( nX, nTabNo ), nPPTX );
+ rSizeYPix = ToPixel( pDoc->GetRowHeight( nY, nTabNo ), nPPTY );
+ return sal_False;
+ }
+}
+
+sal_Bool ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich,
+ SCsCOL& rPosX, SCsROW& rPosY,
+ sal_Bool bTestMerge, sal_Bool bRepair, sal_Bool bNextIfLarge )
+{
+ // special handling of 0 is now in ScViewFunctionSet::SetCursorAtPoint
+
+ ScHSplitPos eHWhich = WhichH(eWhich);
+ ScVSplitPos eVWhich = WhichV(eWhich);
+
+ if ( pDoc->IsLayoutRTL( nTabNo ) )
+ {
+ // mirror horizontal position
+ if (pView)
+ aScrSize.Width() = pView->GetGridWidth(eHWhich);
+ nClickX = aScrSize.Width() - 1 - nClickX;
+ }
+
+ SCsCOL nStartPosX = GetPosX(eHWhich);
+ SCsROW nStartPosY = GetPosY(eVWhich);
+ rPosX = nStartPosX;
+ rPosY = nStartPosY;
+ long nScrX = 0;
+ long nScrY = 0;
+
+ if (nClickX > 0)
+ {
+ while ( rPosX<=MAXCOL && nClickX >= nScrX )
+ {
+ nScrX += ToPixel( pDoc->GetColWidth( rPosX, nTabNo ), nPPTX );
+ ++rPosX;
+ }
+ --rPosX;
+ }
+ else
+ {
+ while ( rPosX>0 && nClickX < nScrX )
+ {
+ --rPosX;
+ nScrX -= ToPixel( pDoc->GetColWidth( rPosX, nTabNo ), nPPTX );
+ }
+ }
+
+ if (nClickY > 0)
+ AddPixelsWhile( nScrY, nClickY, rPosY, MAXROW, nPPTY, pDoc, nTabNo );
+ else
+ {
+ /* TODO: could need some "SubPixelsWhileBackward" method */
+ while ( rPosY>0 && nClickY < nScrY )
+ {
+ --rPosY;
+ nScrY -= ToPixel( pDoc->GetRowHeight( rPosY, nTabNo ), nPPTY );
+ }
+ }
+
+ if (bNextIfLarge) // zu grosse Zellen ?
+ {
+ if ( rPosX == nStartPosX && nClickX > 0 )
+ {
+ if (pView)
+ aScrSize.Width() = pView->GetGridWidth(eHWhich);
+ if ( nClickX > aScrSize.Width() )
+ ++rPosX;
+ }
+ if ( rPosY == nStartPosY && nClickY > 0 )
+ {
+ if (pView)
+ aScrSize.Height() = pView->GetGridHeight(eVWhich);
+ if ( nClickY > aScrSize.Height() )
+ ++rPosY;
+ }
+ }
+
+ if (rPosX<0) rPosX=0;
+ if (rPosX>MAXCOL) rPosX=MAXCOL;
+ if (rPosY<0) rPosY=0;
+ if (rPosY>MAXROW) rPosY=MAXROW;
+
+ if (bTestMerge)
+ {
+ //! public Methode um Position anzupassen
+
+ sal_Bool bHOver = sal_False;
+ while (pDoc->IsHorOverlapped( rPosX, rPosY, nTabNo ))
+ { --rPosX; bHOver=sal_True; }
+ sal_Bool bVOver = sal_False;
+ while (pDoc->IsVerOverlapped( rPosX, rPosY, nTabNo ))
+ { --rPosY; bVOver=sal_True; }
+
+ if ( bRepair && ( bHOver || bVOver ) )
+ {
+ const ScMergeAttr* pMerge = (const ScMergeAttr*)
+ pDoc->GetAttr( rPosX, rPosY, nTabNo, ATTR_MERGE );
+ if ( ( bHOver && pMerge->GetColMerge() <= 1 ) ||
+ ( bVOver && pMerge->GetRowMerge() <= 1 ) )
+ {
+ DBG_ERROR("Merge-Fehler gefunden");
+
+ pDoc->RemoveFlagsTab( 0,0, MAXCOL,MAXROW, nTabNo, SC_MF_HOR | SC_MF_VER );
+ SCCOL nEndCol = MAXCOL;
+ SCROW nEndRow = MAXROW;
+ pDoc->ExtendMerge( 0,0, nEndCol,nEndRow, nTabNo, sal_True, sal_False );
+ if (pDocShell)
+ pDocShell->PostPaint( ScRange(0,0,nTabNo,MAXCOL,MAXROW,nTabNo), PAINT_GRID );
+ }
+ }
+ }
+
+ return sal_False;
+}
+
+void ScViewData::GetMouseQuadrant( const Point& rClickPos, ScSplitPos eWhich,
+ SCsCOL nPosX, SCsROW nPosY, sal_Bool& rLeft, sal_Bool& rTop )
+{
+ sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTabNo );
+ long nLayoutSign = bLayoutRTL ? -1 : 1;
+
+ Point aCellStart = GetScrPos( nPosX, nPosY, eWhich, sal_True );
+ long nSizeX;
+ long nSizeY;
+ GetMergeSizePixel( nPosX, nPosY, nSizeX, nSizeY );
+ rLeft = ( rClickPos.X() - aCellStart.X() ) * nLayoutSign <= nSizeX / 2;
+ rTop = rClickPos.Y() - aCellStart.Y() <= nSizeY / 2;
+}
+
+void ScViewData::SetPosX( ScHSplitPos eWhich, SCCOL nNewPosX )
+{
+ if (nNewPosX != 0)
+ {
+ SCCOL nOldPosX = pThisTab->nPosX[eWhich];
+ long nTPosX = pThisTab->nTPosX[eWhich];
+ long nPixPosX = pThisTab->nPixPosX[eWhich];
+ SCCOL i;
+ if ( nNewPosX > nOldPosX )
+ for ( i=nOldPosX; i<nNewPosX; i++ )
+ {
+ long nThis = pDoc->GetColWidth( i,nTabNo );
+ nTPosX -= nThis;
+ nPixPosX -= ToPixel(sal::static_int_cast<sal_uInt16>(nThis), nPPTX);
+ }
+ else
+ for ( i=nNewPosX; i<nOldPosX; i++ )
+ {
+ long nThis = pDoc->GetColWidth( i,nTabNo );
+ nTPosX += nThis;
+ nPixPosX += ToPixel(sal::static_int_cast<sal_uInt16>(nThis), nPPTX);
+ }
+
+ pThisTab->nPosX[eWhich] = nNewPosX;
+ pThisTab->nTPosX[eWhich] = nTPosX;
+ pThisTab->nMPosX[eWhich] = (long) (nTPosX * HMM_PER_TWIPS);
+ pThisTab->nPixPosX[eWhich] = nPixPosX;
+ }
+ else
+ pThisTab->nPixPosX[eWhich] =
+ pThisTab->nTPosX[eWhich] =
+ pThisTab->nMPosX[eWhich] =
+ pThisTab->nPosX[eWhich] = 0;
+}
+
+void ScViewData::SetPosY( ScVSplitPos eWhich, SCROW nNewPosY )
+{
+ if (nNewPosY != 0)
+ {
+ SCROW nOldPosY = pThisTab->nPosY[eWhich];
+ long nTPosY = pThisTab->nTPosY[eWhich];
+ long nPixPosY = pThisTab->nPixPosY[eWhich];
+ SCROW i, nHeightEndRow;
+ if ( nNewPosY > nOldPosY )
+ for ( i=nOldPosY; i<nNewPosY; i++ )
+ {
+ long nThis = pDoc->GetRowHeight( i, nTabNo, NULL, &nHeightEndRow );
+ SCROW nRows = std::min( nNewPosY, nHeightEndRow + 1) - i;
+ i = nHeightEndRow;
+ nTPosY -= nThis * nRows;
+ nPixPosY -= ToPixel(sal::static_int_cast<sal_uInt16>(nThis), nPPTY) * nRows;
+ }
+ else
+ for ( i=nNewPosY; i<nOldPosY; i++ )
+ {
+ long nThis = pDoc->GetRowHeight( i, nTabNo, NULL, &nHeightEndRow );
+ SCROW nRows = std::min( nOldPosY, nHeightEndRow + 1) - i;
+ i = nHeightEndRow;
+ nTPosY += nThis * nRows;
+ nPixPosY += ToPixel(sal::static_int_cast<sal_uInt16>(nThis), nPPTY) * nRows;
+ }
+
+ pThisTab->nPosY[eWhich] = nNewPosY;
+ pThisTab->nTPosY[eWhich] = nTPosY;
+ pThisTab->nMPosY[eWhich] = (long) (nTPosY * HMM_PER_TWIPS);
+ pThisTab->nPixPosY[eWhich] = nPixPosY;
+ }
+ else
+ pThisTab->nPixPosY[eWhich] =
+ pThisTab->nTPosY[eWhich] =
+ pThisTab->nMPosY[eWhich] =
+ pThisTab->nPosY[eWhich] = 0;
+}
+
+void ScViewData::RecalcPixPos() // nach Zoom-Aenderungen
+{
+ for (sal_uInt16 eWhich=0; eWhich<2; eWhich++)
+ {
+ long nPixPosX = 0;
+ SCCOL nPosX = pThisTab->nPosX[eWhich];
+ for (SCCOL i=0; i<nPosX; i++)
+ nPixPosX -= ToPixel(pDoc->GetColWidth(i,nTabNo), nPPTX);
+ pThisTab->nPixPosX[eWhich] = nPixPosX;
+
+ long nPixPosY = 0;
+ SCROW nPosY = pThisTab->nPosY[eWhich];
+ for (SCROW j=0; j<nPosY; j++)
+ nPixPosY -= ToPixel(pDoc->GetRowHeight(j,nTabNo), nPPTY);
+ pThisTab->nPixPosY[eWhich] = nPixPosY;
+ }
+}
+
+const MapMode& ScViewData::GetLogicMode( ScSplitPos eWhich )
+{
+ aLogicMode.SetOrigin( Point( pThisTab->nMPosX[WhichH(eWhich)],
+ pThisTab->nMPosY[WhichV(eWhich)] ) );
+ return aLogicMode;
+}
+
+const MapMode& ScViewData::GetLogicMode()
+{
+ aLogicMode.SetOrigin( Point() );
+ return aLogicMode;
+}
+
+void ScViewData::SetScreen( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+ SCCOL nCol;
+ SCROW nRow;
+ sal_uInt16 nTSize;
+ long nSizePix;
+ long nScrPosX = 0;
+ long nScrPosY = 0;
+
+ SetActivePart( SC_SPLIT_BOTTOMLEFT );
+ SetPosX( SC_SPLIT_LEFT, nCol1 );
+ SetPosY( SC_SPLIT_BOTTOM, nRow1 );
+
+ for (nCol=nCol1; nCol<=nCol2; nCol++)
+ {
+ nTSize = pDoc->GetColWidth( nCol, nTabNo );
+ if (nTSize)
+ {
+ nSizePix = ToPixel( nTSize, nPPTX );
+ nScrPosX += (sal_uInt16) nSizePix;
+ }
+ }
+
+ for (nRow=nRow1; nRow<=nRow2; nRow++)
+ {
+ nTSize = pDoc->GetRowHeight( nRow, nTabNo );
+ if (nTSize)
+ {
+ nSizePix = ToPixel( nTSize, nPPTY );
+ nScrPosY += (sal_uInt16) nSizePix;
+ }
+ }
+
+ aScrSize = Size( nScrPosX, nScrPosY );
+}
+
+void ScViewData::SetScreenPos( const Point& rVisAreaStart )
+{
+ long nSize;
+ long nTwips;
+ long nAdd;
+ sal_Bool bEnd;
+
+ nSize = 0;
+ nTwips = (long) (rVisAreaStart.X() / HMM_PER_TWIPS);
+ if ( pDoc->IsLayoutRTL( nTabNo ) )
+ nTwips = -nTwips;
+ SCCOL nX1 = 0;
+ bEnd = sal_False;
+ while (!bEnd)
+ {
+ nAdd = (long) pDoc->GetColWidth(nX1,nTabNo);
+ if (nSize+nAdd <= nTwips+1 && nX1<MAXCOL)
+ {
+ nSize += nAdd;
+ ++nX1;
+ }
+ else
+ bEnd = sal_True;
+ }
+
+ nSize = 0;
+ nTwips = (long) (rVisAreaStart.Y() / HMM_PER_TWIPS);
+ SCROW nY1 = 0;
+ bEnd = sal_False;
+ while (!bEnd)
+ {
+ nAdd = (long) pDoc->GetRowHeight(nY1,nTabNo);
+ if (nSize+nAdd <= nTwips+1 && nY1<MAXROW)
+ {
+ nSize += nAdd;
+ ++nY1;
+ }
+ else
+ bEnd = sal_True;
+ }
+
+ SetActivePart( SC_SPLIT_BOTTOMLEFT );
+ SetPosX( SC_SPLIT_LEFT, nX1 );
+ SetPosY( SC_SPLIT_BOTTOM, nY1 );
+
+ SetCurX( nX1 );
+ SetCurY( nY1 );
+}
+
+void ScViewData::SetScreen( const Rectangle& rVisArea )
+{
+ SetScreenPos( rVisArea.TopLeft() );
+
+ // hier ohne GetOutputFactor(), weil fuer Ausgabe in Metafile
+
+ aScrSize = rVisArea.GetSize();
+ aScrSize.Width() = (long)
+ ( aScrSize.Width() * ScGlobal::nScreenPPTX / HMM_PER_TWIPS );
+ aScrSize.Height() = (long)
+ ( aScrSize.Height() * ScGlobal::nScreenPPTY / HMM_PER_TWIPS );
+}
+
+SfxObjectShell* ScViewData::GetSfxDocShell() const
+{
+ return pDocShell;
+}
+
+SfxBindings& ScViewData::GetBindings()
+{
+ DBG_ASSERT( pViewShell, "GetBindings() without ViewShell" );
+ return pViewShell->GetViewFrame()->GetBindings();
+}
+
+SfxDispatcher& ScViewData::GetDispatcher()
+{
+ DBG_ASSERT( pViewShell, "GetDispatcher() without ViewShell" );
+ return *pViewShell->GetViewFrame()->GetDispatcher();
+}
+
+Window* ScViewData::GetDialogParent()
+{
+ DBG_ASSERT( pViewShell, "GetDialogParent() ohne ViewShell" );
+ return pViewShell->GetDialogParent();
+}
+
+Window* ScViewData::GetActiveWin()
+{
+ DBG_ASSERT( pView, "GetActiveWin() ohne View" );
+ return pView->GetActiveWin();
+}
+
+ScDrawView* ScViewData::GetScDrawView()
+{
+ DBG_ASSERT( pView, "GetScDrawView() ohne View" );
+ return pView->GetScDrawView();
+}
+
+sal_Bool ScViewData::IsMinimized()
+{
+ DBG_ASSERT( pView, "IsMinimized() ohne View" );
+ return pView->IsMinimized();
+}
+
+void ScViewData::UpdateScreenZoom( const Fraction& rNewX, const Fraction& rNewY )
+{
+ Fraction aOldX = GetZoomX();
+ Fraction aOldY = GetZoomY();
+
+ SetZoom( rNewX, rNewY, sal_False );
+
+ Fraction aWidth = GetZoomX();
+ aWidth *= Fraction( aScrSize.Width(),1 );
+ aWidth /= aOldX;
+
+ Fraction aHeight = GetZoomY();
+ aHeight *= Fraction( aScrSize.Height(),1 );
+ aHeight /= aOldY;
+
+ aScrSize.Width() = (long) aWidth;
+ aScrSize.Height() = (long) aHeight;
+}
+
+void ScViewData::CalcPPT()
+{
+ nPPTX = ScGlobal::nScreenPPTX * (double) GetZoomX();
+ if (pDocShell)
+ nPPTX = nPPTX / pDocShell->GetOutputFactor(); // Faktor ist Drucker zu Bildschirm
+ nPPTY = ScGlobal::nScreenPPTY * (double) GetZoomY();
+
+ // #83616# if detective objects are present,
+ // try to adjust horizontal scale so the most common column width has minimal rounding errors,
+ // to avoid differences between cell and drawing layer output
+
+ if ( pDoc && pDoc->HasDetectiveObjects(nTabNo) )
+ {
+ SCCOL nEndCol = 0;
+ SCROW nDummy = 0;
+ pDoc->GetTableArea( nTabNo, nEndCol, nDummy );
+ if (nEndCol<20)
+ nEndCol = 20; // same end position as when determining draw scale
+
+ sal_uInt16 nTwips = pDoc->GetCommonWidth( nEndCol, nTabNo );
+ if ( nTwips )
+ {
+ double fOriginal = nTwips * nPPTX;
+ if ( fOriginal < static_cast<double>(nEndCol) )
+ {
+ // if one column is smaller than the column count,
+ // rounding errors are likely to add up to a whole column.
+
+ double fRounded = ::rtl::math::approxFloor( fOriginal + 0.5 );
+ if ( fRounded > 0.0 )
+ {
+ double fScale = fRounded / fOriginal + 1E-6;
+ if ( fScale >= 0.9 && fScale <= 1.1 )
+ nPPTX *= fScale;
+ }
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------
+
+#define SC_OLD_TABSEP '/'
+#define SC_NEW_TABSEP '+'
+
+void ScViewData::WriteUserData(String& rData)
+{
+ // nZoom (bis 364v) oder nZoom/nPageZoom/bPageMode (ab 364w)
+ // nTab
+ // Tab-ControlBreite
+ // pro Tabelle:
+ // CursorX/CursorY/HSplitMode/VSplitMode/HSplitPos/VSplitPos/SplitActive/
+ // PosX[links]/PosX[rechts]/PosY[oben]/PosY[unten]
+ // wenn Zeilen groesser 8192, "+" statt "/"
+
+ sal_uInt16 nZoom = (sal_uInt16)((pThisTab->aZoomY.GetNumerator() * 100) / pThisTab->aZoomY.GetDenominator());
+ rData = String::CreateFromInt32( nZoom );
+ rData += '/';
+ nZoom = (sal_uInt16)((pThisTab->aPageZoomY.GetNumerator() * 100) / pThisTab->aPageZoomY.GetDenominator());
+ rData += String::CreateFromInt32( nZoom );
+ rData += '/';
+ if (bPagebreak)
+ rData += '1';
+ else
+ rData += '0';
+
+ rData += ';';
+ rData += String::CreateFromInt32( nTabNo );
+ rData += ';';
+ rData.AppendAscii(RTL_CONSTASCII_STRINGPARAM( TAG_TABBARWIDTH ));
+ rData += String::CreateFromInt32( pView->GetTabBarWidth() );
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ {
+ rData += ';'; // Numerierung darf auf keinen Fall durcheinanderkommen
+ if (pTabData[i])
+ {
+ sal_Unicode cTabSep = SC_OLD_TABSEP; // wie 3.1
+ if ( pTabData[i]->nCurY > MAXROW_30 ||
+ pTabData[i]->nPosY[0] > MAXROW_30 || pTabData[i]->nPosY[1] > MAXROW_30 ||
+ ( pTabData[i]->eVSplitMode == SC_SPLIT_FIX &&
+ pTabData[i]->nFixPosY > MAXROW_30 ) )
+ {
+ cTabSep = SC_NEW_TABSEP; // um eine 3.1-Version nicht umzubringen
+ }
+
+
+ rData += String::CreateFromInt32( pTabData[i]->nCurX );
+ rData += cTabSep;
+ rData += String::CreateFromInt32( pTabData[i]->nCurY );
+ rData += cTabSep;
+ rData += String::CreateFromInt32( pTabData[i]->eHSplitMode );
+ rData += cTabSep;
+ rData += String::CreateFromInt32( pTabData[i]->eVSplitMode );
+ rData += cTabSep;
+ if ( pTabData[i]->eHSplitMode == SC_SPLIT_FIX )
+ rData += String::CreateFromInt32( pTabData[i]->nFixPosX );
+ else
+ rData += String::CreateFromInt32( pTabData[i]->nHSplitPos );
+ rData += cTabSep;
+ if ( pTabData[i]->eVSplitMode == SC_SPLIT_FIX )
+ rData += String::CreateFromInt32( pTabData[i]->nFixPosY );
+ else
+ rData += String::CreateFromInt32( pTabData[i]->nVSplitPos );
+ rData += cTabSep;
+ rData += String::CreateFromInt32( pTabData[i]->eWhichActive );
+ rData += cTabSep;
+ rData += String::CreateFromInt32( pTabData[i]->nPosX[0] );
+ rData += cTabSep;
+ rData += String::CreateFromInt32( pTabData[i]->nPosX[1] );
+ rData += cTabSep;
+ rData += String::CreateFromInt32( pTabData[i]->nPosY[0] );
+ rData += cTabSep;
+ rData += String::CreateFromInt32( pTabData[i]->nPosY[1] );
+ }
+ }
+}
+
+void ScViewData::ReadUserData(const String& rData)
+{
+ if (!rData.Len()) // Leerer String kommt bei "neu Laden"
+ return; // dann auch ohne Assertion beenden
+
+ xub_StrLen nCount = rData.GetTokenCount(';');
+ if ( nCount <= 2 )
+ {
+ // #45208# beim Reload in der Seitenansicht sind evtl. die Preview-UserData
+ // stehengelassen worden. Den Zoom von der Preview will man hier nicht...
+ DBG_ERROR("ReadUserData: das sind nicht meine Daten");
+ return;
+ }
+
+ String aTabOpt;
+ xub_StrLen nTagLen = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(TAG_TABBARWIDTH)).Len();
+
+ //-------------------
+ // nicht pro Tabelle:
+ //-------------------
+ SCTAB nTabStart = 2;
+
+ Fraction aZoomX, aZoomY, aPageZoomX, aPageZoomY; //! evaluate (all sheets?)
+
+ String aZoomStr = rData.GetToken(0); // Zoom/PageZoom/Modus
+ sal_uInt16 nNormZoom = sal::static_int_cast<sal_uInt16>(aZoomStr.GetToken(0,'/').ToInt32());
+ if ( nNormZoom >= MINZOOM && nNormZoom <= MAXZOOM )
+ aZoomX = aZoomY = Fraction( nNormZoom, 100 ); // "normaler" Zoom (immer)
+ sal_uInt16 nPageZoom = sal::static_int_cast<sal_uInt16>(aZoomStr.GetToken(1,'/').ToInt32());
+ if ( nPageZoom >= MINZOOM && nPageZoom <= MAXZOOM )
+ aPageZoomX = aPageZoomY = Fraction( nPageZoom, 100 ); // Pagebreak-Zoom, wenn gesetzt
+ sal_Unicode cMode = aZoomStr.GetToken(2,'/').GetChar(0); // 0 oder "0"/"1"
+ SetPagebreakMode( cMode == '1' );
+ // SetPagebreakMode muss immer gerufen werden wegen CalcPPT / RecalcPixPos()
+
+ //
+ // Tabelle kann ungueltig geworden sein (z.B. letzte Version):
+ //
+ SCTAB nNewTab = static_cast<SCTAB>(rData.GetToken(1).ToInt32());
+ if (pDoc->HasTable( nNewTab ))
+ SetTabNo(nNewTab);
+
+ //
+ // wenn vorhanden, TabBar-Breite holen:
+ //
+ aTabOpt = rData.GetToken(2);
+
+ if ( nTagLen && aTabOpt.Copy(0,nTagLen).EqualsAscii(TAG_TABBARWIDTH) )
+ {
+ pView->SetTabBarWidth( aTabOpt.Copy(nTagLen).ToInt32() );
+ nTabStart = 3;
+ }
+
+ //-------------
+ // pro Tabelle:
+ //-------------
+ SCTAB nPos = 0;
+ while ( nCount > nPos+nTabStart )
+ {
+ aTabOpt = rData.GetToken(static_cast<xub_StrLen>(nPos+nTabStart));
+ if (!pTabData[nPos])
+ pTabData[nPos] = new ScViewDataTable;
+
+ sal_Unicode cTabSep = 0;
+ if (aTabOpt.GetTokenCount(SC_OLD_TABSEP) >= 11)
+ cTabSep = SC_OLD_TABSEP;
+#ifndef SC_LIMIT_ROWS
+ else if (aTabOpt.GetTokenCount(SC_NEW_TABSEP) >= 11)
+ cTabSep = SC_NEW_TABSEP;
+ // '+' ist nur erlaubt, wenn wir mit Zeilen > 8192 umgehen koennen
+#endif
+
+ if (cTabSep)
+ {
+ pTabData[nPos]->nCurX = SanitizeCol( static_cast<SCCOL>(aTabOpt.GetToken(0,cTabSep).ToInt32()));
+ pTabData[nPos]->nCurY = SanitizeRow( aTabOpt.GetToken(1,cTabSep).ToInt32());
+ pTabData[nPos]->eHSplitMode = (ScSplitMode) aTabOpt.GetToken(2,cTabSep).ToInt32();
+ pTabData[nPos]->eVSplitMode = (ScSplitMode) aTabOpt.GetToken(3,cTabSep).ToInt32();
+
+ if ( pTabData[nPos]->eHSplitMode == SC_SPLIT_FIX )
+ {
+ pTabData[nPos]->nFixPosX = SanitizeCol( static_cast<SCCOL>(aTabOpt.GetToken(4,cTabSep).ToInt32()));
+ UpdateFixX(nPos);
+ }
+ else
+ pTabData[nPos]->nHSplitPos = aTabOpt.GetToken(4,cTabSep).ToInt32();
+
+ if ( pTabData[nPos]->eVSplitMode == SC_SPLIT_FIX )
+ {
+ pTabData[nPos]->nFixPosY = SanitizeRow( aTabOpt.GetToken(5,cTabSep).ToInt32());
+ UpdateFixY(nPos);
+ }
+ else
+ pTabData[nPos]->nVSplitPos = aTabOpt.GetToken(5,cTabSep).ToInt32();
+
+ pTabData[nPos]->eWhichActive = (ScSplitPos) aTabOpt.GetToken(6,cTabSep).ToInt32();
+ pTabData[nPos]->nPosX[0] = SanitizeCol( static_cast<SCCOL>(aTabOpt.GetToken(7,cTabSep).ToInt32()));
+ pTabData[nPos]->nPosX[1] = SanitizeCol( static_cast<SCCOL>(aTabOpt.GetToken(8,cTabSep).ToInt32()));
+ pTabData[nPos]->nPosY[0] = SanitizeRow( aTabOpt.GetToken(9,cTabSep).ToInt32());
+ pTabData[nPos]->nPosY[1] = SanitizeRow( aTabOpt.GetToken(10,cTabSep).ToInt32());
+
+ // Test, ob der aktive Teil laut SplitMode ueberhaupt existiert
+ // (Bug #44516#)
+ ScSplitPos eTest = pTabData[nPos]->eWhichActive;
+ if ( ( WhichH( eTest ) == SC_SPLIT_RIGHT &&
+ pTabData[nPos]->eHSplitMode == SC_SPLIT_NONE ) ||
+ ( WhichV( eTest ) == SC_SPLIT_TOP &&
+ pTabData[nPos]->eVSplitMode == SC_SPLIT_NONE ) )
+ {
+ // dann wieder auf Default (unten links)
+ pTabData[nPos]->eWhichActive = SC_SPLIT_BOTTOMLEFT;
+ DBG_ERROR("SplitPos musste korrigiert werden");
+ }
+ }
+ ++nPos;
+ }
+
+ RecalcPixPos();
+}
+
+void ScViewData::WriteExtOptions( ScExtDocOptions& rDocOpt ) const
+{
+ // *** Fill extended document data for export filters ***
+
+ // document settings
+ ScExtDocSettings& rDocSett = rDocOpt.GetDocSettings();
+
+ // displayed sheet
+ rDocSett.mnDisplTab = GetTabNo();
+
+ // width of the tabbar, relative to frame window width
+ rDocSett.mfTabBarWidth = pView->GetPendingRelTabBarWidth();
+ if( rDocSett.mfTabBarWidth < 0.0 )
+ rDocSett.mfTabBarWidth = pView->GetRelTabBarWidth();
+
+ // sheet settings
+ for( SCTAB nTab = 0, nTabCount = pDoc->GetTableCount(); nTab < nTabCount; ++nTab )
+ {
+ if( const ScViewDataTable* pViewTab = pTabData[ nTab ] )
+ {
+ ScExtTabSettings& rTabSett = rDocOpt.GetOrCreateTabSettings( nTab );
+
+ // split mode
+ ScSplitMode eHSplit = pViewTab->eHSplitMode;
+ ScSplitMode eVSplit = pViewTab->eVSplitMode;
+ bool bHSplit = eHSplit != SC_SPLIT_NONE;
+ bool bVSplit = eVSplit != SC_SPLIT_NONE;
+ bool bRealSplit = (eHSplit == SC_SPLIT_NORMAL) || (eVSplit == SC_SPLIT_NORMAL);
+ bool bFrozen = (eHSplit == SC_SPLIT_FIX) || (eVSplit == SC_SPLIT_FIX);
+ DBG_ASSERT( !bRealSplit || !bFrozen, "ScViewData::WriteExtOptions - split and freeze in same sheet" );
+ rTabSett.mbFrozenPanes = !bRealSplit && bFrozen;
+
+ // split and freeze position
+ rTabSett.maSplitPos = Point( 0, 0 );
+ rTabSett.maFreezePos.Set( 0, 0, nTab );
+ if( bRealSplit )
+ {
+ Point& rSplitPos = rTabSett.maSplitPos;
+ rSplitPos = Point( bHSplit ? pViewTab->nHSplitPos : 0, bVSplit ? pViewTab->nVSplitPos : 0 );
+ rSplitPos = Application::GetDefaultDevice()->PixelToLogic( rSplitPos, MapMode( MAP_TWIP ) );
+ if( pDocShell )
+ rSplitPos.X() = (long)((double)rSplitPos.X() / pDocShell->GetOutputFactor());
+ }
+ else if( bFrozen )
+ {
+ if( bHSplit ) rTabSett.maFreezePos.SetCol( pViewTab->nFixPosX );
+ if( bVSplit ) rTabSett.maFreezePos.SetRow( pViewTab->nFixPosY );
+ }
+
+ // first visible cell in top-left and additional panes
+ rTabSett.maFirstVis.Set( pViewTab->nPosX[ SC_SPLIT_LEFT ], pViewTab->nPosY[ bVSplit ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM ], nTab );
+ rTabSett.maSecondVis.Set( pViewTab->nPosX[ SC_SPLIT_RIGHT ], pViewTab->nPosY[ SC_SPLIT_BOTTOM ], nTab );
+
+ // active pane
+ switch( pViewTab->eWhichActive )
+ {
+ // no horizontal split -> always use left panes
+ // no vertical split -> always use top panes
+ case SC_SPLIT_TOPLEFT:
+ rTabSett.meActivePane = SCEXT_PANE_TOPLEFT;
+ break;
+ case SC_SPLIT_TOPRIGHT:
+ rTabSett.meActivePane = bHSplit ? SCEXT_PANE_TOPRIGHT : SCEXT_PANE_TOPLEFT;
+ break;
+ case SC_SPLIT_BOTTOMLEFT:
+ rTabSett.meActivePane = bVSplit ? SCEXT_PANE_BOTTOMLEFT : SCEXT_PANE_TOPLEFT;
+ break;
+ case SC_SPLIT_BOTTOMRIGHT:
+ rTabSett.meActivePane = bHSplit ?
+ (bVSplit ? SCEXT_PANE_BOTTOMRIGHT : SCEXT_PANE_TOPRIGHT) :
+ (bVSplit ? SCEXT_PANE_BOTTOMLEFT : SCEXT_PANE_TOPLEFT);
+ break;
+ }
+
+ // cursor position
+ rTabSett.maCursor.Set( pViewTab->nCurX, pViewTab->nCurY, nTab );
+
+ // sheet selection and selected ranges
+ const ScMarkData& rMarkData = GetMarkData();
+ rTabSett.mbSelected = rMarkData.GetTableSelect( nTab );
+ rMarkData.FillRangeListWithMarks( &rTabSett.maSelection, sal_True );
+
+ // grid color
+ rTabSett.maGridColor.SetColor( COL_AUTO );
+ if( pOptions )
+ {
+ const Color& rGridColor = pOptions->GetGridColor();
+ if( rGridColor.GetColor() != SC_STD_GRIDCOLOR )
+ rTabSett.maGridColor = rGridColor;
+ }
+
+ // view mode and zoom
+ rTabSett.mbPageMode = bPagebreak;
+ rTabSett.mnNormalZoom = static_cast< long >( pViewTab->aZoomY * Fraction( 100.0 ) );
+ rTabSett.mnPageZoom = static_cast< long >( pViewTab->aPageZoomY * Fraction( 100.0 ) );
+ }
+ }
+}
+
+void ScViewData::ReadExtOptions( const ScExtDocOptions& rDocOpt )
+{
+ // *** Get extended document data from import filters ***
+
+ if( !rDocOpt.IsChanged() ) return;
+
+ // document settings
+ const ScExtDocSettings& rDocSett = rDocOpt.GetDocSettings();
+
+ // displayed sheet
+ SetTabNo( rDocSett.mnDisplTab );
+
+ /* Width of the tabbar, relative to frame window width. We do not have the
+ correct width of the frame window here -> store in ScTabView, which sets
+ the size in the next resize. */
+ pView->SetPendingRelTabBarWidth( rDocSett.mfTabBarWidth );
+
+ // sheet settings
+ for( SCTAB nTab = 0, nTabCount = pDoc->GetTableCount(); nTab < nTabCount; ++nTab )
+ {
+ if( const ScExtTabSettings* pTabSett = rDocOpt.GetTabSettings( nTab ) )
+ {
+ if( !pTabData[ nTab ] )
+ pTabData[ nTab ] = new ScViewDataTable;
+
+ const ScExtTabSettings& rTabSett = *pTabSett;
+ ScViewDataTable& rViewTab = *pTabData[ nTab ];
+
+ // split mode initialization
+ bool bFrozen = rTabSett.mbFrozenPanes;
+ bool bHSplit = bFrozen ? (rTabSett.maFreezePos.Col() > 0) : (rTabSett.maSplitPos.X() > 0);
+ bool bVSplit = bFrozen ? (rTabSett.maFreezePos.Row() > 0) : (rTabSett.maSplitPos.Y() > 0);
+
+ // first visible cell of top-left pane and additional panes
+ rViewTab.nPosX[ SC_SPLIT_LEFT ] = rTabSett.maFirstVis.Col();
+ rViewTab.nPosY[ bVSplit ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM ] = rTabSett.maFirstVis.Row();
+ if( bHSplit ) rViewTab.nPosX[ SC_SPLIT_RIGHT ] = rTabSett.maSecondVis.Col();
+ if( bVSplit ) rViewTab.nPosY[ SC_SPLIT_BOTTOM ] = rTabSett.maSecondVis.Row();
+
+ // split mode, split and freeze position
+ rViewTab.eHSplitMode = rViewTab.eVSplitMode = SC_SPLIT_NONE;
+ rViewTab.nHSplitPos = rViewTab.nVSplitPos = 0;
+ rViewTab.nFixPosX = 0;
+ rViewTab.nFixPosY = 0;
+ if( bFrozen )
+ {
+ if( bHSplit )
+ {
+ rViewTab.eHSplitMode = SC_SPLIT_FIX;
+ rViewTab.nFixPosX = rTabSett.maFreezePos.Col();
+ UpdateFixX( nTab );
+ }
+ if( bVSplit )
+ {
+ rViewTab.eVSplitMode = SC_SPLIT_FIX;
+ rViewTab.nFixPosY = rTabSett.maFreezePos.Row();
+ UpdateFixY( nTab );
+ }
+ }
+ else
+ {
+ Point aPixel = Application::GetDefaultDevice()->LogicToPixel(
+ rTabSett.maSplitPos, MapMode( MAP_TWIP ) ); //! Zoom?
+ // #109648# - the test for use of printer metrics for text formatting here
+ // effectively results in the nFactor = 1.0 regardless of the Option setting.
+ if( pDocShell && SC_MOD()->GetInputOptions().GetTextWysiwyg())
+ {
+ double nFactor = pDocShell->GetOutputFactor();
+ aPixel.X() = (long)( aPixel.X() * nFactor + 0.5 );
+ }
+ if( bHSplit )
+ {
+ rViewTab.eHSplitMode = SC_SPLIT_NORMAL;
+ rViewTab.nHSplitPos = aPixel.X();
+ }
+ if( bVSplit )
+ {
+ rViewTab.eVSplitMode = SC_SPLIT_NORMAL;
+ rViewTab.nVSplitPos = aPixel.Y();
+ }
+ }
+
+ // active pane
+ ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
+ switch( rTabSett.meActivePane )
+ {
+ // no horizontal split -> always use left panes
+ // no vertical split -> always use *bottom* panes
+ case SCEXT_PANE_TOPLEFT:
+ ePos = bVSplit ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
+ break;
+ case SCEXT_PANE_TOPRIGHT:
+ ePos = bHSplit ?
+ (bVSplit ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT) :
+ (bVSplit ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT);
+ break;
+ case SCEXT_PANE_BOTTOMLEFT:
+ ePos = SC_SPLIT_BOTTOMLEFT;
+ break;
+ case SCEXT_PANE_BOTTOMRIGHT:
+ ePos = bHSplit ? SC_SPLIT_BOTTOMRIGHT : SC_SPLIT_BOTTOMLEFT;
+ break;
+ }
+ rViewTab.eWhichActive = ePos;
+
+ // cursor position
+ const ScAddress& rCursor = rTabSett.maCursor;
+ if( rCursor.IsValid() )
+ {
+ rViewTab.nCurX = rCursor.Col();
+ rViewTab.nCurY = rCursor.Row();
+ }
+
+ // sheet selection and selected ranges
+ ScMarkData& rMarkData = GetMarkData();
+ rMarkData.SelectTable( nTab, rTabSett.mbSelected );
+
+ // zoom for each sheet
+ if( rTabSett.mnNormalZoom )
+ rViewTab.aZoomX = rViewTab.aZoomY = Fraction( rTabSett.mnNormalZoom, 100L );
+ if( rTabSett.mnPageZoom )
+ rViewTab.aPageZoomX = rViewTab.aPageZoomY = Fraction( rTabSett.mnPageZoom, 100L );
+
+ // get some settings from displayed Excel sheet, set at Calc document
+ if( nTab == GetTabNo() )
+ {
+ // selection only for displayed sheet, do not select single cell
+// Disabled, does not work correctly. Anyway, our own XML filters do not import a selection at all.
+// const ScRangeList& rSel = rTabSett.maSelection;
+// if( (rSel.Count() >= 2) || ((rSel.Count() == 1) && (*rSel.GetObject( 0 ) != ScRange( rCursor ))) )
+// rMarkData.MarkFromRangeList( rTabSett.maSelection, sal_False );
+
+ // grid color -- #i47435# set automatic grid color explicitly
+ if( pOptions )
+ {
+ Color aGridColor( rTabSett.maGridColor );
+ if( aGridColor.GetColor() == COL_AUTO )
+ aGridColor.SetColor( SC_STD_GRIDCOLOR );
+ pOptions->SetGridColor( aGridColor, EMPTY_STRING );
+ }
+
+ // view mode and default zoom (for new sheets) from current sheet
+ if( rTabSett.mnNormalZoom )
+ aDefZoomX = aDefZoomY = Fraction( rTabSett.mnNormalZoom, 100L );
+ if( rTabSett.mnPageZoom )
+ aDefPageZoomX = aDefPageZoomY = Fraction( rTabSett.mnPageZoom, 100L );
+ /* #i46820# set pagebreak mode via SetPagebreakMode(), this will
+ update map modes that are needed to draw text correctly. */
+ SetPagebreakMode( rTabSett.mbPageMode );
+ }
+ }
+ }
+
+ // RecalcPixPos oder so - auch nMPos - auch bei ReadUserData ??!?!
+}
+
+void ScViewData::WriteUserDataSequence(uno::Sequence <beans::PropertyValue>& rSettings)
+{
+ rSettings.realloc(SC_VIEWSETTINGS_COUNT);
+ // + 1, because we have to put the view id in the sequence
+ beans::PropertyValue* pSettings = rSettings.getArray();
+ if (pSettings)
+ {
+ sal_uInt16 nViewID(pViewShell->GetViewFrame()->GetCurViewId());
+ pSettings[SC_VIEW_ID].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_VIEWID));
+ rtl::OUStringBuffer sBuffer(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_VIEW)));
+ SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(nViewID));
+ pSettings[SC_VIEW_ID].Value <<= sBuffer.makeStringAndClear();
+
+ SCTAB nTabCount (pDoc->GetTableCount());
+ uno::Reference<lang::XMultiServiceFactory> xServiceFactory =
+ comphelper::getProcessServiceFactory();
+ DBG_ASSERT( xServiceFactory.is(), "got no service manager" );
+ if( xServiceFactory.is() )
+ {
+ rtl::OUString sName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.NamedPropertyValues"));
+ uno::Reference<container::XNameContainer> xNameContainer = uno::Reference<container::XNameContainer>(xServiceFactory->createInstance(sName), uno::UNO_QUERY);
+ if (xNameContainer.is())
+ {
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ {
+ if (pTabData[nTab])
+ {
+ uno::Sequence <beans::PropertyValue> aTableViewSettings;
+ pTabData[nTab]->WriteUserDataSequence(aTableViewSettings, *this, nTab);
+ String sTabName;
+ GetDocument()->GetName( nTab, sTabName );
+ rtl::OUString sOUName(sTabName);
+ uno::Any aAny;
+ aAny <<= aTableViewSettings;
+ try
+ {
+ xNameContainer->insertByName(sTabName, aAny);
+ }
+ //#101739#; two tables with the same name are possible
+ catch ( container::ElementExistException& )
+ {
+ DBG_ERRORFILE("seems there are two tables with the same name");
+ }
+ catch ( uno::RuntimeException& )
+ {
+ DBG_ERRORFILE("something went wrong");
+ }
+ }
+ }
+ pSettings[SC_TABLE_VIEWSETTINGS].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_TABLES));
+ pSettings[SC_TABLE_VIEWSETTINGS].Value <<= xNameContainer;
+ }
+ }
+
+ String sName;
+ GetDocument()->GetName( nTabNo, sName );
+ rtl::OUString sOUName(sName);
+ pSettings[SC_ACTIVE_TABLE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ACTIVETABLE));
+ pSettings[SC_ACTIVE_TABLE].Value <<= sOUName;
+ pSettings[SC_HORIZONTAL_SCROLL_BAR_WIDTH].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_HORIZONTALSCROLLBARWIDTH));
+ pSettings[SC_HORIZONTAL_SCROLL_BAR_WIDTH].Value <<= sal_Int32(pView->GetTabBarWidth());
+ sal_Int32 nZoomValue ((pThisTab->aZoomY.GetNumerator() * 100) / pThisTab->aZoomY.GetDenominator());
+ sal_Int32 nPageZoomValue ((pThisTab->aPageZoomY.GetNumerator() * 100) / pThisTab->aPageZoomY.GetDenominator());
+ pSettings[SC_ZOOM_TYPE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ZOOMTYPE));
+ pSettings[SC_ZOOM_TYPE].Value <<= sal_Int16(pThisTab->eZoomType);
+ pSettings[SC_ZOOM_VALUE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ZOOMVALUE));
+ pSettings[SC_ZOOM_VALUE].Value <<= nZoomValue;
+ pSettings[SC_PAGE_VIEW_ZOOM_VALUE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_PAGEVIEWZOOMVALUE));
+ pSettings[SC_PAGE_VIEW_ZOOM_VALUE].Value <<= nPageZoomValue;
+ pSettings[SC_PAGE_BREAK_PREVIEW].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_SHOWPAGEBREAKPREVIEW));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_PAGE_BREAK_PREVIEW].Value, bPagebreak);
+
+ if (pOptions)
+ {
+ pSettings[SC_SHOWZERO].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHOWZERO));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHOWZERO].Value, pOptions->GetOption( VOPT_NULLVALS ) );
+ pSettings[SC_SHOWNOTES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHOWNOTES));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHOWNOTES].Value, pOptions->GetOption( VOPT_NOTES ) );
+ pSettings[SC_SHOWGRID].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHOWGRID));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHOWGRID].Value, pOptions->GetOption( VOPT_GRID ) );
+ pSettings[SC_GRIDCOLOR].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_GRIDCOLOR));
+ String aColorName;
+ Color aColor = pOptions->GetGridColor(&aColorName);
+ pSettings[SC_GRIDCOLOR].Value <<= static_cast<sal_Int64>(aColor.GetColor());
+ pSettings[SC_SHOWPAGEBR].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHOWPAGEBR));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHOWPAGEBR].Value, pOptions->GetOption( VOPT_PAGEBREAKS ) );
+ pSettings[SC_COLROWHDR].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_COLROWHDR));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_COLROWHDR].Value, pOptions->GetOption( VOPT_HEADER ) );
+ pSettings[SC_SHEETTABS].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHEETTABS));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHEETTABS].Value, pOptions->GetOption( VOPT_TABCONTROLS ) );
+ pSettings[SC_OUTLSYMB].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_OUTLSYMB));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_OUTLSYMB].Value, pOptions->GetOption( VOPT_OUTLINER ) );
+
+ const ScGridOptions& aGridOpt = pOptions->GetGridOptions();
+ pSettings[SC_SNAPTORASTER].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SNAPTORASTER));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SNAPTORASTER].Value, aGridOpt.GetUseGridSnap() );
+ pSettings[SC_RASTERVIS].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERVIS));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_RASTERVIS].Value, aGridOpt.GetGridVisible() );
+ pSettings[SC_RASTERRESX].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERRESX));
+ pSettings[SC_RASTERRESX].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDrawX() );
+ pSettings[SC_RASTERRESY].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERRESY));
+ pSettings[SC_RASTERRESY].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDrawY() );
+ pSettings[SC_RASTERSUBX].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERSUBX));
+ pSettings[SC_RASTERSUBX].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDivisionX() );
+ pSettings[SC_RASTERSUBY].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERSUBY));
+ pSettings[SC_RASTERSUBY].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDivisionY() );
+ pSettings[SC_RASTERSYNC].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERSYNC));
+ ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_RASTERSYNC].Value, aGridOpt.GetSynchronize() );
+ }
+ }
+}
+
+void ScViewData::ReadUserDataSequence(const uno::Sequence <beans::PropertyValue>& rSettings)
+{
+ Fraction aZoomX, aZoomY, aPageZoomX, aPageZoomY; //! evaluate (all sheets?)
+
+ std::vector<bool> aHasZoomVect( GetDocument()->GetTableCount(), false );
+
+ sal_Int32 nCount(rSettings.getLength());
+ sal_Int32 nTemp32(0);
+ sal_Int16 nTemp16(0);
+ sal_Bool bPageMode(sal_False);
+ for (sal_Int32 i = 0; i < nCount; i++)
+ {
+ // SC_VIEWID has to parse and use by mba
+ rtl::OUString sName(rSettings[i].Name);
+ if (sName.compareToAscii(SC_TABLES) == 0)
+ {
+ uno::Reference<container::XNameContainer> xNameContainer;
+ if ((rSettings[i].Value >>= xNameContainer) && xNameContainer->hasElements())
+ {
+ uno::Sequence< rtl::OUString > aNames(xNameContainer->getElementNames());
+ for (sal_Int32 nTabPos = 0; nTabPos < aNames.getLength(); nTabPos++)
+ {
+ String sTabName(aNames[nTabPos]);
+ SCTAB nTab(0);
+ if (GetDocument()->GetTable(sTabName, nTab))
+ {
+ uno::Any aAny = xNameContainer->getByName(aNames[nTabPos]);
+ uno::Sequence<beans::PropertyValue> aTabSettings;
+ if (aAny >>= aTabSettings)
+ {
+ pTabData[nTab] = new ScViewDataTable;
+ bool bHasZoom = false;
+ pTabData[nTab]->ReadUserDataSequence(aTabSettings, *this, nTab, bHasZoom);
+ aHasZoomVect[nTab] = bHasZoom;
+ }
+ }
+ }
+ }
+ }
+ else if (sName.compareToAscii(SC_ACTIVETABLE) == 0)
+ {
+ rtl::OUString sValue;
+ if(rSettings[i].Value >>= sValue)
+ {
+ String sTabName(sValue);
+ SCTAB nTab(0);
+ if (GetDocument()->GetTable(sTabName, nTab))
+ nTabNo = nTab;
+ }
+ }
+ else if (sName.compareToAscii(SC_HORIZONTALSCROLLBARWIDTH) == 0)
+ {
+ if (rSettings[i].Value >>= nTemp32)
+ pView->SetTabBarWidth(nTemp32);
+ }
+ else if (sName.compareToAscii(SC_RELHORIZONTALTABBARWIDTH) == 0)
+ {
+ double fWidth = 0.0;
+ if (rSettings[i].Value >>= fWidth)
+ pView->SetPendingRelTabBarWidth( fWidth );
+ }
+ else if (sName.compareToAscii(SC_ZOOMTYPE) == 0)
+ {
+ if (rSettings[i].Value >>= nTemp16)
+ eDefZoomType = SvxZoomType(nTemp16);
+ }
+ else if (sName.compareToAscii(SC_ZOOMVALUE) == 0)
+ {
+ if (rSettings[i].Value >>= nTemp32)
+ {
+ Fraction aZoom(nTemp32, 100);
+ aDefZoomX = aDefZoomY = aZoom;
+ }
+ }
+ else if (sName.compareToAscii(SC_PAGEVIEWZOOMVALUE) == 0)
+ {
+ if (rSettings[i].Value >>= nTemp32)
+ {
+ Fraction aZoom(nTemp32, 100);
+ aDefPageZoomX = aDefPageZoomY = aZoom;
+ }
+ }
+ else if (sName.compareToAscii(SC_SHOWPAGEBREAKPREVIEW) == 0)
+ bPageMode = ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value );
+ else if ( sName.compareToAscii( SC_UNO_SHOWZERO ) == 0 )
+ pOptions->SetOption(VOPT_NULLVALS, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ else if ( sName.compareToAscii( SC_UNO_SHOWNOTES ) == 0 )
+ pOptions->SetOption(VOPT_NOTES, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ else if ( sName.compareToAscii( SC_UNO_SHOWGRID ) == 0 )
+ pOptions->SetOption(VOPT_GRID, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ else if ( sName.compareToAscii( SC_UNO_GRIDCOLOR ) == 0 )
+ {
+ sal_Int64 nColor = 0;
+ if (rSettings[i].Value >>= nColor)
+ {
+ String aColorName;
+ Color aColor(static_cast<sal_uInt32>(nColor));
+ // #i47435# set automatic grid color explicitly
+ if( aColor.GetColor() == COL_AUTO )
+ aColor.SetColor( SC_STD_GRIDCOLOR );
+ pOptions->SetGridColor(aColor, aColorName);
+ }
+ }
+ else if ( sName.compareToAscii( SC_UNO_SHOWPAGEBR ) == 0 )
+ pOptions->SetOption(VOPT_PAGEBREAKS, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ else if ( sName.compareToAscii( SC_UNO_COLROWHDR ) == 0 )
+ pOptions->SetOption(VOPT_HEADER, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ else if ( sName.compareToAscii( SC_UNO_SHEETTABS ) == 0 )
+ pOptions->SetOption(VOPT_TABCONTROLS, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ else if ( sName.compareToAscii( SC_UNO_OUTLSYMB ) == 0 )
+ pOptions->SetOption(VOPT_OUTLINER, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ else if ( sName.compareToAscii( SC_UNO_SHOWOBJ ) == 0 )
+ {
+ // #i80528# placeholders not supported anymore
+ if ( rSettings[i].Value >>= nTemp16 )
+ pOptions->SetObjMode( VOBJ_TYPE_OLE, (nTemp16 == 1) ? VOBJ_MODE_HIDE : VOBJ_MODE_SHOW );
+ }
+ else if ( sName.compareToAscii( SC_UNO_SHOWCHARTS ) == 0 )
+ {
+ // #i80528# placeholders not supported anymore
+ if ( rSettings[i].Value >>= nTemp16 )
+ pOptions->SetObjMode( VOBJ_TYPE_CHART, (nTemp16 == 1) ? VOBJ_MODE_HIDE : VOBJ_MODE_SHOW );
+ }
+ else if ( sName.compareToAscii( SC_UNO_SHOWDRAW ) == 0 )
+ {
+ // #i80528# placeholders not supported anymore
+ if ( rSettings[i].Value >>= nTemp16 )
+ pOptions->SetObjMode( VOBJ_TYPE_DRAW, (nTemp16 == 1) ? VOBJ_MODE_HIDE : VOBJ_MODE_SHOW );
+ }
+ else
+ {
+ ScGridOptions aGridOpt(pOptions->GetGridOptions());
+ if ( sName.compareToAscii( SC_UNO_SNAPTORASTER ) == 0 )
+ aGridOpt.SetUseGridSnap( ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ else if ( sName.compareToAscii( SC_UNO_RASTERVIS ) == 0 )
+ aGridOpt.SetGridVisible( ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ else if ( sName.compareToAscii( SC_UNO_RASTERRESX ) == 0 )
+ aGridOpt.SetFldDrawX( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
+ else if ( sName.compareToAscii( SC_UNO_RASTERRESY ) == 0 )
+ aGridOpt.SetFldDrawY( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
+ else if ( sName.compareToAscii( SC_UNO_RASTERSUBX ) == 0 )
+ aGridOpt.SetFldDivisionX( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
+ else if ( sName.compareToAscii( SC_UNO_RASTERSUBY ) == 0 )
+ aGridOpt.SetFldDivisionY( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
+ else if ( sName.compareToAscii( SC_UNO_RASTERSYNC ) == 0 )
+ aGridOpt.SetSynchronize( ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
+ pOptions->SetGridOptions(aGridOpt);
+ }
+ }
+
+ // copy default zoom to sheets where a different one wasn't specified
+ for (SCTAB nZoomTab=0; nZoomTab<=MAXTAB; ++nZoomTab)
+ if (pTabData[nZoomTab] && ( nZoomTab >= static_cast<SCTAB>(aHasZoomVect.size()) || !aHasZoomVect[nZoomTab] ))
+ {
+ pTabData[nZoomTab]->eZoomType = eDefZoomType;
+ pTabData[nZoomTab]->aZoomX = aDefZoomX;
+ pTabData[nZoomTab]->aZoomY = aDefZoomY;
+ pTabData[nZoomTab]->aPageZoomX = aDefPageZoomX;
+ pTabData[nZoomTab]->aPageZoomY = aDefPageZoomY;
+ }
+
+ if (nCount)
+ SetPagebreakMode( bPageMode );
+
+ // #i47426# write view options to document, needed e.g. for Excel export
+ pDoc->SetViewOptions( *pOptions );
+}
+
+void ScViewData::SetOptions( const ScViewOptions& rOpt )
+{
+ // if visibility of horiz. ScrollBar is changed, TabBar may have to be resized...
+ sal_Bool bHScrollChanged = ( rOpt.GetOption(VOPT_HSCROLL) != pOptions->GetOption(VOPT_HSCROLL) );
+
+ // if graphics are turned on or off, animation has to be started or stopped
+ // graphics are controlled by VOBJ_TYPE_OLE
+ sal_Bool bGraphicsChanged = ( pOptions->GetObjMode(VOBJ_TYPE_OLE) !=
+ rOpt.GetObjMode(VOBJ_TYPE_OLE) );
+
+ *pOptions = rOpt;
+ DBG_ASSERT( pView, "No View" );
+
+ if( pView )
+ {
+ pView->ViewOptionsHasChanged( bHScrollChanged, bGraphicsChanged );
+ }
+}
+
+Point ScViewData::GetMousePosPixel()
+{
+ DBG_ASSERT( pView, "GetMousePosPixel() ohne View" );
+ return pView->GetMousePosPixel();
+}
+
+void ScViewData::UpdateInputHandler( sal_Bool bForce, sal_Bool bStopEditing )
+{
+ if (pViewShell)
+ pViewShell->UpdateInputHandler( bForce, bStopEditing );
+}
+
+sal_Bool ScViewData::IsOle()
+{
+ return pDocShell && pDocShell->IsOle();
+}
+
+sal_Bool ScViewData::UpdateFixX( SCTAB nTab ) // sal_True = Wert geaendert
+{
+ if (!ValidTab(nTab)) // Default
+ nTab=nTabNo; // akuelle Tabelle
+
+ if (!pView || pTabData[nTab]->eHSplitMode != SC_SPLIT_FIX)
+ return sal_False;
+
+ ScDocument* pLocalDoc = GetDocument();
+ if (!pLocalDoc->HasTable(nTab)) // #114007# if called from reload, the sheet may not exist
+ return sal_False;
+
+ SCCOL nFix = pTabData[nTab]->nFixPosX;
+ long nNewPos = 0;
+ for (SCCOL nX=pTabData[nTab]->nPosX[SC_SPLIT_LEFT]; nX<nFix; nX++)
+ {
+ sal_uInt16 nTSize = pLocalDoc->GetColWidth( nX, nTab );
+ if (nTSize)
+ {
+ long nPix = ToPixel( nTSize, nPPTX );
+ nNewPos += nPix;
+ }
+ }
+ nNewPos += pView->GetGridOffset().X();
+ if (nNewPos != pTabData[nTab]->nHSplitPos)
+ {
+ pTabData[nTab]->nHSplitPos = nNewPos;
+ if (nTab == nTabNo)
+ RecalcPixPos(); //! sollte nicht noetig sein !!!
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+sal_Bool ScViewData::UpdateFixY( SCTAB nTab ) // sal_True = Wert geaendert
+{
+ if (!ValidTab(nTab)) // Default
+ nTab=nTabNo; // akuelle Tabelle
+
+ if (!pView || pTabData[nTab]->eVSplitMode != SC_SPLIT_FIX)
+ return sal_False;
+
+ ScDocument* pLocalDoc = GetDocument();
+ if (!pLocalDoc->HasTable(nTab)) // #114007# if called from reload, the sheet may not exist
+ return sal_False;
+
+ SCROW nFix = pTabData[nTab]->nFixPosY;
+ long nNewPos = 0;
+ for (SCROW nY=pTabData[nTab]->nPosY[SC_SPLIT_TOP]; nY<nFix; nY++)
+ {
+ sal_uInt16 nTSize = pLocalDoc->GetRowHeight( nY, nTab );
+ if (nTSize)
+ {
+ long nPix = ToPixel( nTSize, nPPTY );
+ nNewPos += nPix;
+ }
+ }
+ nNewPos += pView->GetGridOffset().Y();
+ if (nNewPos != pTabData[nTab]->nVSplitPos)
+ {
+ pTabData[nTab]->nVSplitPos = nNewPos;
+ if (nTab == nTabNo)
+ RecalcPixPos(); //! sollte nicht noetig sein !!!
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+void ScViewData::UpdateOutlinerFlags( Outliner& rOutl ) const
+{
+ ScDocument* pLocalDoc = GetDocument();
+ sal_Bool bOnlineSpell = pLocalDoc->GetDocOptions().IsAutoSpell();
+
+ sal_uLong nCntrl = rOutl.GetControlWord();
+ nCntrl |= EE_CNTRL_URLSFXEXECUTE;
+ nCntrl |= EE_CNTRL_MARKFIELDS;
+ nCntrl |= EE_CNTRL_AUTOCORRECT;
+ if( bOnlineSpell )
+ nCntrl |= EE_CNTRL_ONLINESPELLING;
+ else
+ nCntrl &= ~EE_CNTRL_ONLINESPELLING;
+ rOutl.SetControlWord(nCntrl);
+
+ rOutl.SetCalcFieldValueHdl( LINK( SC_MOD(), ScModule, CalcFieldValueHdl ) );
+
+ // #97417# don't call GetSpellChecker if online spelling isn't enabled.
+ // The language for AutoCorrect etc. is taken from the pool defaults
+ // (set in ScDocument::UpdateDrawLanguages)
+
+ if ( bOnlineSpell )
+ {
+ com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellChecker1> xXSpellChecker1( LinguMgr::GetSpellChecker() );
+ rOutl.SetSpeller( xXSpellChecker1 );
+ }
+
+ rOutl.SetDefaultHorizontalTextDirection(
+ (EEHorizontalTextDirection)pLocalDoc->GetEditTextDirection( nTabNo ) );
+}
+
+ScAddress ScViewData::GetCurPos() const
+{
+ return ScAddress( GetCurX(), GetCurY(), GetTabNo() );
+}
+
+
+// static
+void ScViewData::AddPixelsWhile( long & rScrY, long nEndPixels, SCROW & rPosY,
+ SCROW nEndRow, double nPPTY, const ScDocument * pDoc, SCTAB nTabNo )
+{
+ SCROW nRow = rPosY;
+ while (rScrY <= nEndPixels && nRow <= nEndRow)
+ {
+ SCROW nHeightEndRow;
+ sal_uInt16 nHeight = pDoc->GetRowHeight( nRow, nTabNo, NULL, &nHeightEndRow);
+ if (nHeightEndRow > nEndRow)
+ nHeightEndRow = nEndRow;
+ if (!nHeight)
+ nRow = nHeightEndRow + 1;
+ else
+ {
+ SCROW nRows = nHeightEndRow - nRow + 1;
+ sal_Int64 nPixel = ToPixel( nHeight, nPPTY);
+ sal_Int64 nAdd = nPixel * nRows;
+ if (nAdd + rScrY > nEndPixels)
+ {
+ sal_Int64 nDiff = rScrY + nAdd - nEndPixels;
+ nRows -= static_cast<SCROW>(nDiff / nPixel);
+ nAdd = nPixel * nRows;
+ // We're looking for a value that satisfies loop condition.
+ if (nAdd + rScrY <= nEndPixels)
+ {
+ ++nRows;
+ nAdd += nPixel;
+ }
+ }
+ rScrY += static_cast<long>(nAdd);
+ nRow += nRows;
+ }
+ }
+ if (nRow > rPosY)
+ --nRow;
+ rPosY = nRow;
+}
+
+
+// static
+void ScViewData::AddPixelsWhileBackward( long & rScrY, long nEndPixels,
+ SCROW & rPosY, SCROW nStartRow, double nPPTY, const ScDocument * pDoc,
+ SCTAB nTabNo )
+{
+ SCROW nRow = rPosY;
+ while (rScrY <= nEndPixels && nRow >= nStartRow)
+ {
+ SCROW nHeightStartRow;
+ sal_uInt16 nHeight = pDoc->GetRowHeight( nRow, nTabNo, &nHeightStartRow, NULL);
+ if (nHeightStartRow < nStartRow)
+ nHeightStartRow = nStartRow;
+ if (!nHeight)
+ nRow = nHeightStartRow - 1;
+ else
+ {
+ SCROW nRows = nRow - nHeightStartRow + 1;
+ sal_Int64 nPixel = ToPixel( nHeight, nPPTY);
+ sal_Int64 nAdd = nPixel * nRows;
+ if (nAdd + rScrY > nEndPixels)
+ {
+ sal_Int64 nDiff = nAdd + rScrY - nEndPixels;
+ nRows -= static_cast<SCROW>(nDiff / nPixel);
+ nAdd = nPixel * nRows;
+ // We're looking for a value that satisfies loop condition.
+ if (nAdd + rScrY <= nEndPixels)
+ {
+ ++nRows;
+ nAdd += nPixel;
+ }
+ }
+ rScrY += static_cast<long>(nAdd);
+ nRow -= nRows;
+ }
+ }
+ if (nRow < rPosY)
+ ++nRow;
+ rPosY = nRow;
+}
diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx
new file mode 100644
index 000000000000..c8a02aa1ea2e
--- /dev/null
+++ b/sc/source/ui/view/viewfun2.cxx
@@ -0,0 +1,3144 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/app.hxx>
+#define _SVSTDARR_STRINGS
+#include <editeng/boxitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <svl/srchitem.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/objitem.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/stritem.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/svstdarr.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/sound.hxx>
+#include <vcl/waitobj.hxx>
+
+#include "viewfunc.hxx"
+
+#include "sc.hrc"
+#include "globstr.hrc"
+
+#include "attrib.hxx"
+#include "autoform.hxx"
+#include "cell.hxx" // EnterAutoSum
+#include "compiler.hxx"
+#include "docfunc.hxx"
+#include "docpool.hxx"
+#include "docsh.hxx"
+#include "global.hxx"
+#include "patattr.hxx"
+#include "printfun.hxx"
+#include "rangenam.hxx"
+#include "rangeutl.hxx"
+#include "refundo.hxx"
+#include "tablink.hxx"
+#include "tabvwsh.hxx"
+#include "uiitems.hxx"
+#include "undoblk.hxx"
+#include "undocell.hxx"
+#include "undotab.hxx"
+#include "sizedev.hxx"
+#include "editable.hxx"
+#include "scmod.hxx"
+#include "inputhdl.hxx"
+#include "inputwin.hxx"
+#include "funcdesc.hxx"
+#include "docuno.hxx"
+#include "charthelper.hxx"
+#include "tabbgcolor.hxx"
+
+#include <basic/sbstar.hxx>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/script/XLibraryContainer.hpp>
+using namespace com::sun::star;
+
+// helper func defined in docfunc.cxx
+void VBA_DeleteModule( ScDocShell& rDocSh, String& sModuleName );
+
+// STATIC DATA ---------------------------------------------------------------
+
+
+//----------------------------------------------------------------------------
+
+sal_Bool ScViewFunc::AdjustBlockHeight( sal_Bool bPaint, ScMarkData* pMarkData )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ if (!pMarkData)
+ pMarkData = &GetViewData()->GetMarkData();
+
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT];
+ SCCOLROW nRangeCnt = pMarkData->GetMarkRowRanges( pRanges );
+ if (nRangeCnt == 0)
+ {
+ pRanges[0] = pRanges[1] = GetViewData()->GetCurY();
+ nRangeCnt = 1;
+ }
+
+ double nPPTX = GetViewData()->GetPPTX();
+ double nPPTY = GetViewData()->GetPPTY();
+ Fraction aZoomX = GetViewData()->GetZoomX();
+ Fraction aZoomY = GetViewData()->GetZoomY();
+
+ ScSizeDeviceProvider aProv(pDocSh);
+ if (aProv.IsPrinter())
+ {
+ nPPTX = aProv.GetPPTX();
+ nPPTY = aProv.GetPPTY();
+ aZoomX = aZoomY = Fraction( 1, 1 );
+ }
+
+ sal_Bool bAnyChanged = sal_False;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ {
+ if (pMarkData->GetTableSelect(nTab))
+ {
+ SCCOLROW* pOneRange = pRanges;
+ sal_Bool bChanged = sal_False;
+ SCROW nPaintY = 0;
+ for (SCROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
+ {
+ SCROW nStartNo = *(pOneRange++);
+ SCROW nEndNo = *(pOneRange++);
+ if (pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, 0, aProv.GetDevice(),
+ nPPTX, nPPTY, aZoomX, aZoomY, sal_False ))
+ {
+ if (!bChanged)
+ nPaintY = nStartNo;
+ bAnyChanged = bChanged = sal_True;
+ }
+ }
+ if ( bPaint && bChanged )
+ pDocSh->PostPaint( 0, nPaintY, nTab, MAXCOL, MAXROW, nTab,
+ PAINT_GRID | PAINT_LEFT );
+ }
+ }
+ delete[] pRanges;
+
+ if ( bPaint && bAnyChanged )
+ pDocSh->UpdateOle(GetViewData());
+
+ return bAnyChanged;
+}
+
+
+//----------------------------------------------------------------------------
+
+sal_Bool ScViewFunc::AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, sal_Bool bPaint )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ double nPPTX = GetViewData()->GetPPTX();
+ double nPPTY = GetViewData()->GetPPTY();
+ Fraction aZoomX = GetViewData()->GetZoomX();
+ Fraction aZoomY = GetViewData()->GetZoomY();
+ sal_uInt16 nOldPixel = 0;
+ if (nStartRow == nEndRow)
+ nOldPixel = (sal_uInt16) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
+
+ ScSizeDeviceProvider aProv(pDocSh);
+ if (aProv.IsPrinter())
+ {
+ nPPTX = aProv.GetPPTX();
+ nPPTY = aProv.GetPPTY();
+ aZoomX = aZoomY = Fraction( 1, 1 );
+ }
+ sal_Bool bChanged = pDoc->SetOptimalHeight( nStartRow, nEndRow, nTab, 0, aProv.GetDevice(),
+ nPPTX, nPPTY, aZoomX, aZoomY, sal_False );
+
+ if (bChanged && ( nStartRow == nEndRow ))
+ {
+ sal_uInt16 nNewPixel = (sal_uInt16) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
+ if ( nNewPixel == nOldPixel )
+ bChanged = sal_False;
+ }
+
+ if ( bPaint && bChanged )
+ pDocSh->PostPaint( 0, nStartRow, nTab, MAXCOL, MAXROW, nTab,
+ PAINT_GRID | PAINT_LEFT );
+
+ return bChanged;
+}
+
+
+//----------------------------------------------------------------------------
+
+enum ScAutoSum
+{
+ ScAutoSumNone = 0,
+ ScAutoSumData,
+ ScAutoSumSum
+};
+
+
+ScAutoSum lcl_IsAutoSumData( ScDocument* pDoc, SCCOL nCol, SCROW nRow,
+ SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
+{
+ ScBaseCell* pCell;
+ pDoc->GetCell( nCol, nRow, nTab, pCell );
+ if ( pCell && pCell->HasValueData() )
+ {
+ if ( pCell->GetCellType() == CELLTYPE_FORMULA )
+ {
+ ScTokenArray* pCode = ((ScFormulaCell*)pCell)->GetCode();
+ if ( pCode && pCode->GetOuterFuncOpCode() == ocSum )
+ {
+ if ( pCode->GetAdjacentExtendOfOuterFuncRefs( nExtend,
+ ScAddress( nCol, nRow, nTab ), eDir ) )
+ return ScAutoSumSum;
+ }
+ }
+ return ScAutoSumData;
+ }
+ return ScAutoSumNone;
+}
+
+
+//----------------------------------------------------------------------------
+
+#define SC_AUTOSUM_MAXCOUNT 20
+
+ScAutoSum lcl_SeekAutoSumData( ScDocument* pDoc, SCCOL& nCol, SCROW& nRow,
+ SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
+{
+ sal_uInt16 nCount = 0;
+ while (nCount < SC_AUTOSUM_MAXCOUNT)
+ {
+ if ( eDir == DIR_TOP )
+ {
+ if (nRow > 0)
+ --nRow;
+ else
+ return ScAutoSumNone;
+ }
+ else
+ {
+ if (nCol > 0)
+ --nCol;
+ else
+ return ScAutoSumNone;
+ }
+ ScAutoSum eSum;
+ if ( (eSum = lcl_IsAutoSumData(
+ pDoc, nCol, nRow, nTab, eDir, nExtend )) != ScAutoSumNone )
+ return eSum;
+ ++nCount;
+ }
+ return ScAutoSumNone;
+}
+
+#undef SC_AUTOSUM_MAXCOUNT
+
+//----------------------------------------------------------------------------
+
+bool lcl_FindNextSumEntryInColumn( ScDocument* pDoc, SCCOL nCol, SCROW& nRow,
+ SCTAB nTab, SCCOLROW& nExtend, SCROW nMinRow )
+{
+ const SCROW nTmp = nRow;
+ ScAutoSum eSkip = ScAutoSumNone;
+ while ( ( eSkip = lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_TOP, nExtend ) ) == ScAutoSumData &&
+ nRow > nMinRow )
+ {
+ --nRow;
+ }
+ if ( eSkip == ScAutoSumSum && nRow < nTmp )
+ {
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+
+bool lcl_FindNextSumEntryInRow( ScDocument* pDoc, SCCOL& nCol, SCROW nRow,
+ SCTAB nTab, SCCOLROW& nExtend, SCROW nMinCol )
+{
+ const SCCOL nTmp = nCol;
+ ScAutoSum eSkip = ScAutoSumNone;
+ while ( ( eSkip = lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_LEFT, nExtend ) ) == ScAutoSumData &&
+ nCol > nMinCol )
+ {
+ --nCol;
+ }
+ if ( eSkip == ScAutoSumSum && nCol < nTmp )
+ {
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+
+bool lcl_GetAutoSumForColumnRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange )
+{
+ const ScAddress aStart = rRange.aStart;
+ const ScAddress aEnd = rRange.aEnd;
+ if ( aStart.Col() != aEnd.Col() )
+ {
+ return false;
+ }
+
+ const SCTAB nTab = aEnd.Tab();
+ const SCCOL nCol = aEnd.Col();
+ SCROW nEndRow = aEnd.Row();
+ SCROW nStartRow = nEndRow;
+ SCCOLROW nExtend = 0;
+ const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nCol, nEndRow, nTab, DIR_TOP, nExtend /*out*/ );
+
+ if ( eSum == ScAutoSumSum )
+ {
+ bool bContinue = false;
+ do
+ {
+ rRangeList.Append( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab ) );
+ nEndRow = static_cast< SCROW >( nExtend );
+ if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, aStart.Row() ) ) == true )
+ {
+ nStartRow = nEndRow;
+ }
+ } while ( bContinue );
+ }
+ else
+ {
+ while ( nStartRow > aStart.Row() &&
+ lcl_IsAutoSumData( pDoc, nCol, nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) != ScAutoSumSum )
+ {
+ --nStartRow;
+ }
+ rRangeList.Append( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab ) );
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+
+bool lcl_GetAutoSumForRowRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange )
+{
+ const ScAddress aStart = rRange.aStart;
+ const ScAddress aEnd = rRange.aEnd;
+ if ( aStart.Row() != aEnd.Row() )
+ {
+ return false;
+ }
+
+ const SCTAB nTab = aEnd.Tab();
+ const SCROW nRow = aEnd.Row();
+ SCCOL nEndCol = aEnd.Col();
+ SCCOL nStartCol = nEndCol;
+ SCCOLROW nExtend = 0;
+ const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nEndCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ );
+
+ if ( eSum == ScAutoSumSum )
+ {
+ bool bContinue = false;
+ do
+ {
+ rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) );
+ nEndCol = static_cast< SCCOL >( nExtend );
+ if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, aStart.Col() ) ) == true )
+ {
+ nStartCol = nEndCol;
+ }
+ } while ( bContinue );
+ }
+ else
+ {
+ while ( nStartCol > aStart.Col() &&
+ lcl_IsAutoSumData( pDoc, nStartCol-1, nRow, nTab, DIR_LEFT, nExtend /*out*/ ) != ScAutoSumSum )
+ {
+ --nStartCol;
+ }
+ rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) );
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+
+sal_Bool ScViewFunc::GetAutoSumArea( ScRangeList& rRangeList )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+
+ SCCOL nStartCol = nCol;
+ SCROW nStartRow = nRow;
+ SCCOL nEndCol = nCol;
+ SCROW nEndRow = nRow;
+ SCCOL nSeekCol = nCol;
+ SCROW nSeekRow = nRow;
+ SCCOLROW nExtend; // wird per Reference gueltig bei ScAutoSumSum
+
+ sal_Bool bCol = sal_False;
+ sal_Bool bRow = sal_False;
+
+ ScAutoSum eSum;
+ if ( nRow != 0
+ && ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
+ DIR_TOP, nExtend /*out*/ )) == ScAutoSumData )
+ && ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
+ DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
+ )
+ {
+ bRow = sal_True;
+ nSeekRow = nRow - 1;
+ }
+ else if ( nCol != 0 && (eSum = lcl_IsAutoSumData( pDoc, nCol-1, nRow, nTab,
+ DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
+ {
+ bCol = sal_True;
+ nSeekCol = nCol - 1;
+ }
+ else if ( (eSum = lcl_SeekAutoSumData( pDoc, nCol, nSeekRow, nTab, DIR_TOP, nExtend /*out*/ )) != ScAutoSumNone )
+ bRow = sal_True;
+ else if (( eSum = lcl_SeekAutoSumData( pDoc, nSeekCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ )) != ScAutoSumNone )
+ bCol = sal_True;
+
+ if ( bCol || bRow )
+ {
+ if ( bRow )
+ {
+ nStartRow = nSeekRow; // nSeekRow evtl. per Reference angepasst
+ if ( eSum == ScAutoSumSum )
+ nEndRow = nStartRow; // nur Summen summieren
+ else
+ nEndRow = nRow - 1; // Datenbereich evtl. nach unten erweitern
+ }
+ else
+ {
+ nStartCol = nSeekCol; // nSeekCol evtl. per Reference angepasst
+ if ( eSum == ScAutoSumSum )
+ nEndCol = nStartCol; // nur Summen summieren
+ else
+ nEndCol = nCol - 1; // Datenbereich evtl. nach rechts erweitern
+ }
+ sal_Bool bContinue = sal_False;
+ do
+ {
+ if ( eSum == ScAutoSumData )
+ {
+ if ( bRow )
+ {
+ while ( nStartRow != 0 && lcl_IsAutoSumData( pDoc, nCol,
+ nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) == eSum )
+ --nStartRow;
+ }
+ else
+ {
+ while ( nStartCol != 0 && lcl_IsAutoSumData( pDoc, nStartCol-1,
+ nRow, nTab, DIR_LEFT, nExtend /*out*/ ) == eSum )
+ --nStartCol;
+ }
+ }
+ rRangeList.Append(
+ ScRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ) );
+ if ( eSum == ScAutoSumSum )
+ {
+ if ( bRow )
+ {
+ nEndRow = static_cast< SCROW >( nExtend );
+ if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, 0 ) ) == true )
+ {
+ nStartRow = nEndRow;
+ }
+ }
+ else
+ {
+ nEndCol = static_cast< SCCOL >( nExtend );
+ if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, 0 ) ) == true )
+ {
+ nStartCol = nEndCol;
+ }
+ }
+ }
+ } while ( bContinue );
+ return sal_True;
+ }
+ return sal_False;
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::EnterAutoSum(const ScRangeList& rRangeList, sal_Bool bSubTotal) // Block mit Summen fuellen
+{
+ String aFormula = GetAutoSumFormula( rRangeList, bSubTotal );
+ EnterBlock( aFormula, NULL );
+}
+
+//----------------------------------------------------------------------------
+
+bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor, bool bContinue )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ const SCTAB nTab = rRange.aStart.Tab();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ const SCCOL nEndCol = rRange.aEnd.Col();
+ const SCROW nEndRow = rRange.aEnd.Row();
+ SCCOLROW nExtend = 0; // out parameter for lcl_IsAutoSumData
+
+ // ignore rows at the top of the given range which don't contain autosum data
+ bool bRowData = false;
+ for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
+ {
+ for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
+ {
+ if ( lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_TOP, nExtend ) != ScAutoSumNone )
+ {
+ bRowData = true;
+ break;
+ }
+ }
+ if ( bRowData )
+ {
+ nStartRow = nRow;
+ break;
+ }
+ }
+ if ( !bRowData )
+ {
+ return false;
+ }
+
+ // ignore columns at the left of the given range which don't contain autosum data
+ bool bColData = false;
+ for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
+ {
+ for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
+ {
+ if ( lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_LEFT, nExtend ) != ScAutoSumNone )
+ {
+ bColData = true;
+ break;
+ }
+ }
+ if ( bColData )
+ {
+ nStartCol = nCol;
+ break;
+ }
+ }
+ if ( !bColData )
+ {
+ return false;
+ }
+
+ const bool bEndRowEmpty = pDoc->IsBlockEmpty( nTab, nStartCol, nEndRow, nEndCol, nEndRow );
+ const bool bEndColEmpty = pDoc->IsBlockEmpty( nTab, nEndCol, nStartRow, nEndCol, nEndRow );
+ bool bRow = ( ( nStartRow != nEndRow ) && ( bEndRowEmpty || ( !bEndRowEmpty && !bEndColEmpty ) ) );
+ bool bCol = ( ( nStartCol != nEndCol ) && ( bEndColEmpty || nStartRow == nEndRow ) );
+
+ // find an empty row for entering the result
+ SCROW nInsRow = nEndRow;
+ if ( bRow && !bEndRowEmpty )
+ {
+ if ( nInsRow < MAXROW )
+ {
+ ++nInsRow;
+ while ( !pDoc->IsBlockEmpty( nTab, nStartCol, nInsRow, nEndCol, nInsRow ) )
+ {
+ if ( nInsRow < MAXROW )
+ {
+ ++nInsRow;
+ }
+ else
+ {
+ bRow = false;
+ break;
+ }
+ }
+ }
+ else
+ {
+ bRow = false;
+ }
+ }
+
+ // find an empty column for entering the result
+ SCCOL nInsCol = nEndCol;
+ if ( bCol && !bEndColEmpty )
+ {
+ if ( nInsCol < MAXCOL )
+ {
+ ++nInsCol;
+ while ( !pDoc->IsBlockEmpty( nTab, nInsCol, nStartRow, nInsCol, nEndRow ) )
+ {
+ if ( nInsCol < MAXCOL )
+ {
+ ++nInsCol;
+ }
+ else
+ {
+ bCol = false;
+ break;
+ }
+ }
+ }
+ else
+ {
+ bCol = false;
+ }
+ }
+
+ if ( !bRow && !bCol )
+ {
+ return false;
+ }
+
+ SCCOL nMarkEndCol = nEndCol;
+ SCROW nMarkEndRow = nEndRow;
+
+ if ( bRow )
+ {
+ // calculate the row sums for all columns of the given range
+
+ SCROW nSumEndRow = nEndRow;
+
+ if ( bEndRowEmpty )
+ {
+ // the last row of the given range is empty;
+ // don't take into account for calculating the autosum
+ --nSumEndRow;
+ }
+ else
+ {
+ // increase mark range
+ ++nMarkEndRow;
+ }
+
+ for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
+ {
+ if ( !pDoc->IsBlockEmpty( nTab, nCol, nStartRow, nCol, nSumEndRow ) )
+ {
+ ScRangeList aRangeList;
+ const ScRange aRange( nCol, nStartRow, nTab, nCol, nSumEndRow, nTab );
+ if ( lcl_GetAutoSumForColumnRange( pDoc, aRangeList, aRange ) )
+ {
+ const String aFormula = GetAutoSumFormula( aRangeList, bSubTotal );
+ EnterData( nCol, nInsRow, nTab, aFormula );
+ }
+ }
+ }
+ }
+
+ if ( bCol )
+ {
+ // calculate the column sums for all rows of the given range
+
+ SCCOL nSumEndCol = nEndCol;
+
+ if ( bEndColEmpty )
+ {
+ // the last column of the given range is empty;
+ // don't take into account for calculating the autosum
+ --nSumEndCol;
+ }
+ else
+ {
+ // increase mark range
+ ++nMarkEndCol;
+ }
+
+ for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
+ {
+ if ( !pDoc->IsBlockEmpty( nTab, nStartCol, nRow, nSumEndCol, nRow ) )
+ {
+ ScRangeList aRangeList;
+ const ScRange aRange( nStartCol, nRow, nTab, nSumEndCol, nRow, nTab );
+ if ( lcl_GetAutoSumForRowRange( pDoc, aRangeList, aRange ) )
+ {
+ const String aFormula = GetAutoSumFormula( aRangeList, bSubTotal );
+ EnterData( nInsCol, nRow, nTab, aFormula );
+ }
+ }
+ }
+ }
+
+ // set new mark range and cursor position
+ const ScRange aMarkRange( nStartCol, nStartRow, nTab, nMarkEndCol, nMarkEndRow, nTab );
+ MarkRange( aMarkRange, sal_False, bContinue );
+ if ( bSetCursor )
+ {
+ SetCursor( nMarkEndCol, nMarkEndRow );
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+
+String ScViewFunc::GetAutoSumFormula( const ScRangeList& rRangeList, bool bSubTotal )
+{
+ String aFormula = '=';
+ ScFunctionMgr* pFuncMgr = ScGlobal::GetStarCalcFunctionMgr();
+ const ScFuncDesc* pDesc = NULL;
+ if ( bSubTotal )
+ {
+ pDesc = pFuncMgr->Get( SC_OPCODE_SUB_TOTAL );
+ }
+ else
+ {
+ pDesc = pFuncMgr->Get( SC_OPCODE_SUM );
+ }
+ if ( pDesc && pDesc->pFuncName )
+ {
+ aFormula += *pDesc->pFuncName;
+ if ( bSubTotal )
+ {
+ aFormula.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "(9;" ) );
+ }
+ else
+ {
+ aFormula += '(';
+ }
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ String aRef;
+ rRangeList.Format( aRef, SCA_VALID, pDoc );
+ aFormula += aRef;
+ aFormula += ')';
+ }
+ return aFormula;
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::EnterBlock( const String& rString, const EditTextObject* pData )
+{
+ // Mehrfachselektion vorher abfragen...
+
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( rMark.IsMultiMarked() )
+ {
+ rMark.MarkToSimple();
+ if ( rMark.IsMultiMarked() )
+ { // "Einfuegen auf Mehrfachselektion nicht moeglich"
+ ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
+
+ // insert into single cell
+ if ( pData )
+ EnterData( nCol, nRow, nTab, pData );
+ else
+ EnterData( nCol, nRow, nTab, rString );
+ return;
+ }
+ }
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ String aNewStr = rString;
+ if ( pData )
+ {
+ const ScPatternAttr* pOldPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ ScTabEditEngine aEngine( *pOldPattern, pDoc->GetEnginePool() );
+ aEngine.SetText(*pData);
+
+ ScEditAttrTester aTester( &aEngine );
+ if (!aTester.NeedsObject())
+ {
+ aNewStr = aEngine.GetText();
+ pData = NULL;
+ }
+ }
+
+ // Einfuegen per PasteFromClip
+
+ WaitObject aWait( GetFrameWin() );
+
+ ScAddress aPos( nCol, nRow, nTab );
+
+ ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP );
+ pInsDoc->ResetClip( pDoc, nTab );
+
+ if (aNewStr.GetChar(0) == '=') // Formel ?
+ {
+ // SetString geht nicht, weil in Clipboard-Dokumenten nicht kompiliert wird!
+ ScFormulaCell* pFCell = new ScFormulaCell( pDoc, aPos, aNewStr );
+ pInsDoc->PutCell( nCol, nRow, nTab, pFCell );
+ }
+ else if ( pData )
+ pInsDoc->PutCell( nCol, nRow, nTab, new ScEditCell( pData, pDoc, NULL ) );
+ else
+ pInsDoc->SetString( nCol, nRow, nTab, aNewStr );
+
+ pInsDoc->SetClipArea( ScRange(aPos) );
+ // auf Block einfuegen, mit Undo etc.
+ if ( PasteFromClip( IDF_CONTENTS, pInsDoc, PASTE_NOFUNC, sal_False, sal_False,
+ sal_False, INS_NONE, IDF_ATTRIB ) )
+ {
+ const SfxUInt32Item* pItem = (SfxUInt32Item*) pInsDoc->GetAttr(
+ nCol, nRow, nTab, ATTR_VALUE_FORMAT );
+ if ( pItem )
+ { // Numberformat setzen wenn inkompatibel
+ // MarkData wurde bereits in PasteFromClip MarkToSimple'ed
+ ScRange aRange;
+ rMark.GetMarkArea( aRange );
+ ScPatternAttr* pPattern = new ScPatternAttr( pDoc->GetPool() );
+ pPattern->GetItemSet().Put( *pItem );
+ short nNewType = pDoc->GetFormatTable()->GetType( pItem->GetValue() );
+ pDoc->ApplyPatternIfNumberformatIncompatible( aRange, rMark,
+ *pPattern, nNewType );
+ delete pPattern;
+ }
+ }
+
+ delete pInsDoc;
+}
+
+
+//----------------------------------------------------------------------------
+
+//UNUSED2008-05 void ScViewFunc::PaintWidthHeight( sal_Bool bColumns, SCCOLROW nStart, SCCOLROW nEnd )
+//UNUSED2008-05 {
+//UNUSED2008-05 SCTAB nTab = GetViewData()->GetTabNo();
+//UNUSED2008-05 ScDocument* pDoc = GetViewData()->GetDocument();
+//UNUSED2008-05
+//UNUSED2008-05 sal_uInt16 nParts = PAINT_GRID;
+//UNUSED2008-05 SCCOL nStartCol = 0;
+//UNUSED2008-05 SCROW nStartRow = 0;
+//UNUSED2008-05 SCCOL nEndCol = MAXCOL; // fuer Test auf Merge
+//UNUSED2008-05 SCROW nEndRow = MAXROW;
+//UNUSED2008-05 if ( bColumns )
+//UNUSED2008-05 {
+//UNUSED2008-05 nParts |= PAINT_TOP;
+//UNUSED2008-05 nStartCol = static_cast<SCCOL>(nStart);
+//UNUSED2008-05 nEndCol = static_cast<SCCOL>(nEnd);
+//UNUSED2008-05 }
+//UNUSED2008-05 else
+//UNUSED2008-05 {
+//UNUSED2008-05 nParts |= PAINT_LEFT;
+//UNUSED2008-05 nStartRow = nStart;
+//UNUSED2008-05 nEndRow = nEnd;
+//UNUSED2008-05 }
+//UNUSED2008-05 if (pDoc->HasAttrib( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
+//UNUSED2008-05 HASATTR_MERGED | HASATTR_OVERLAPPED ))
+//UNUSED2008-05 {
+//UNUSED2008-05 nStartCol = 0;
+//UNUSED2008-05 nStartRow = 0;
+//UNUSED2008-05 }
+//UNUSED2008-05 GetViewData()->GetDocShell()->PostPaint( nStartCol,nStartRow,nTab, MAXCOL,MAXROW,nTab, nParts );
+//UNUSED2008-05 }
+
+
+//----------------------------------------------------------------------------
+// manueller Seitenumbruch
+
+void ScViewFunc::InsertPageBreak( sal_Bool bColumn, sal_Bool bRecord, const ScAddress* pPos,
+ sal_Bool bSetModified )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScAddress aCursor;
+ if (pPos)
+ aCursor = *pPos;
+ else
+ aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
+
+ sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ InsertPageBreak( bColumn, aCursor, bRecord, bSetModified, sal_False );
+
+ if ( bSuccess && bSetModified )
+ UpdatePageBreakData( sal_True ); // fuer PageBreak-Modus
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::DeletePageBreak( sal_Bool bColumn, sal_Bool bRecord, const ScAddress* pPos,
+ sal_Bool bSetModified )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScAddress aCursor;
+ if (pPos)
+ aCursor = *pPos;
+ else
+ aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
+
+ sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ RemovePageBreak( bColumn, aCursor, bRecord, bSetModified, sal_False );
+
+ if ( bSuccess && bSetModified )
+ UpdatePageBreakData( sal_True ); // fuer PageBreak-Modus
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::RemoveManualBreaks()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ sal_Bool bUndo(pDoc->IsUndoEnabled());
+
+ if (bUndo)
+ {
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
+ pDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, sal_False, pUndoDoc );
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoRemoveBreaks( pDocSh, nTab, pUndoDoc ) );
+ }
+
+ pDoc->RemoveManualBreaks(nTab);
+ pDoc->UpdatePageBreaks(nTab);
+
+ UpdatePageBreakData( sal_True );
+ pDocSh->SetDocumentModified();
+ pDocSh->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::SetPrintZoom(sal_uInt16 nScale, sal_uInt16 nPages)
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ pDocSh->SetPrintZoom( nTab, nScale, nPages );
+}
+
+void ScViewFunc::AdjustPrintZoom()
+{
+ ScRange aRange;
+ if ( GetViewData()->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
+ GetViewData()->GetMarkData().GetMultiMarkArea( aRange );
+ GetViewData()->GetDocShell()->AdjustPrintZoom( aRange );
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::SetPrintRanges( sal_Bool bEntireSheet, const String* pPrint,
+ const String* pRepCol, const String* pRepRow,
+ sal_Bool bAddPrint )
+{
+ // on all selected tables
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTab;
+ sal_Bool bUndo (pDoc->IsUndoEnabled());
+
+ ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
+
+ ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
+
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (rMark.GetTableSelect(nTab))
+ {
+ ScRange aRange( 0,0,nTab );
+
+ // print ranges
+
+ if( !bAddPrint )
+ pDoc->ClearPrintRanges( nTab );
+
+ if( bEntireSheet )
+ {
+ pDoc->SetPrintEntireSheet( nTab );
+ }
+ else if ( pPrint )
+ {
+ if ( pPrint->Len() )
+ {
+ const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
+ sal_uInt16 nTCount = pPrint->GetTokenCount(sep);
+ for (sal_uInt16 i=0; i<nTCount; i++)
+ {
+ String aToken = pPrint->GetToken(i, sep);
+ if ( aRange.ParseAny( aToken, pDoc, aDetails ) & SCA_VALID )
+ pDoc->AddPrintRange( nTab, aRange );
+ }
+ }
+ }
+ else // NULL = use selection (print range is always set), use empty string to delete all ranges
+ {
+ if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
+ {
+ pDoc->AddPrintRange( nTab, aRange );
+ }
+ else if ( rMark.IsMultiMarked() )
+ {
+ rMark.MarkToMulti();
+ ScRangeListRef aList( new ScRangeList );
+ rMark.FillRangeListWithMarks( aList, sal_False );
+ sal_uInt16 nCnt = (sal_uInt16) aList->Count();
+ if ( nCnt )
+ {
+ ScRangePtr pR;
+ sal_uInt16 i;
+ for ( pR = aList->First(), i=0; i < nCnt;
+ pR = aList->Next(), i++ )
+ {
+ pDoc->AddPrintRange( nTab, *pR );
+ }
+ }
+ }
+ }
+
+ // repeat columns
+
+ if ( pRepCol )
+ {
+ if ( !pRepCol->Len() )
+ pDoc->SetRepeatColRange( nTab, NULL );
+ else
+ if ( aRange.ParseAny( *pRepCol, pDoc, aDetails ) & SCA_VALID )
+ pDoc->SetRepeatColRange( nTab, &aRange );
+ }
+
+ // repeat rows
+
+ if ( pRepRow )
+ {
+ if ( !pRepRow->Len() )
+ pDoc->SetRepeatRowRange( nTab, NULL );
+ else
+ if ( aRange.ParseAny( *pRepRow, pDoc, aDetails ) & SCA_VALID )
+ pDoc->SetRepeatRowRange( nTab, &aRange );
+ }
+ }
+
+ // undo (for all tables)
+ if (bUndo)
+ {
+ SCTAB nCurTab = GetViewData()->GetTabNo();
+ ScPrintRangeSaver* pNewRanges = pDoc->CreatePrintRangeSaver();
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoPrintRange( pDocSh, nCurTab, pOldRanges, pNewRanges ) );
+ }
+
+ // update page breaks
+
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (rMark.GetTableSelect(nTab))
+ ScPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab ).UpdatePages();
+
+ SfxBindings& rBindings = GetViewData()->GetBindings();
+ rBindings.Invalidate( SID_DELETE_PRINTAREA );
+
+ pDocSh->SetDocumentModified();
+}
+
+//----------------------------------------------------------------------------
+// Zellen zusammenfassen
+
+sal_Bool ScViewFunc::TestMergeCells() // Vorab-Test (fuer Menue)
+{
+ // simple test: sal_True if there's a selection but no multi selection and not filtered
+
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ {
+ ScRange aDummy;
+ return GetViewData()->GetSimpleArea( aDummy) == SC_MARK_SIMPLE;
+ }
+ else
+ return sal_False;
+}
+
+
+//----------------------------------------------------------------------------
+
+sal_Bool ScViewFunc::MergeCells( sal_Bool bApi, sal_Bool& rDoContents, sal_Bool bRecord )
+{
+ // Editable- und Verschachtelungs-Abfrage muss vorneweg sein (auch in DocFunc),
+ // damit dann nicht die Inhalte-QueryBox kommt
+ ScEditableTester aTester( this );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return sal_False;
+ }
+
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ rMark.MarkToSimple();
+ if (!rMark.IsMarked())
+ {
+ ErrorMessage(STR_NOMULTISELECT);
+ return sal_False;
+ }
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+
+ ScRange aMarkRange;
+ rMark.GetMarkArea( aMarkRange );
+ SCCOL nStartCol = aMarkRange.aStart.Col();
+ SCROW nStartRow = aMarkRange.aStart.Row();
+ SCTAB nStartTab = aMarkRange.aStart.Tab();
+ SCCOL nEndCol = aMarkRange.aEnd.Col();
+ SCROW nEndRow = aMarkRange.aEnd.Row();
+ SCTAB nEndTab = aMarkRange.aEnd.Tab();
+ if ( nStartCol == nEndCol && nStartRow == nEndRow )
+ {
+ // nichts zu tun
+ return sal_True;
+ }
+
+ if ( pDoc->HasAttrib( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
+ HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+ { // "Zusammenfassen nicht verschachteln !"
+ ErrorMessage(STR_MSSG_MERGECELLS_0);
+ return sal_False;
+ }
+
+ sal_Bool bOk = sal_True;
+
+ if ( !pDoc->IsBlockEmpty( nStartTab, nStartCol,nStartRow+1, nStartCol,nEndRow, true ) ||
+ !pDoc->IsBlockEmpty( nStartTab, nStartCol+1,nStartRow, nEndCol,nEndRow, true ) )
+ {
+ if (!bApi)
+ {
+ MessBox aBox( GetViewData()->GetDialogParent(),
+ WinBits(WB_YES_NO_CANCEL | WB_DEF_NO),
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),
+ ScGlobal::GetRscString( STR_MERGE_NOTEMPTY ) );
+ sal_uInt16 nRetVal = aBox.Execute();
+
+ if ( nRetVal == RET_YES )
+ rDoContents = sal_True;
+ else if ( nRetVal == RET_CANCEL )
+ bOk = sal_False;
+ }
+ }
+
+ if (bOk)
+ {
+ HideCursor();
+ bOk = pDocSh->GetDocFunc().MergeCells( aMarkRange, rDoContents, bRecord, bApi );
+ ShowCursor();
+
+ if (bOk)
+ {
+ SetCursor( nStartCol, nStartRow );
+ //DoneBlockMode( sal_False);
+ Unmark();
+
+ pDocSh->UpdateOle(GetViewData());
+ UpdateInputLine();
+ }
+ }
+
+ return bOk;
+}
+
+
+//----------------------------------------------------------------------------
+
+sal_Bool ScViewFunc::TestRemoveMerge()
+{
+ sal_Bool bMerged = sal_False;
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if ( pDoc->HasAttrib( aRange, HASATTR_MERGED ) )
+ bMerged = sal_True;
+ }
+ return bMerged;
+}
+
+
+//----------------------------------------------------------------------------
+
+sal_Bool ScViewFunc::RemoveMerge( sal_Bool bRecord )
+{
+ ScRange aRange;
+ ScEditableTester aTester( this );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return sal_False;
+ }
+ else if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
+ {
+ ScRange aExtended( aRange );
+ GetViewData()->GetDocument()->ExtendMerge( aExtended );
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+
+ HideCursor();
+ sal_Bool bOk = pDocSh->GetDocFunc().UnmergeCells( aRange, bRecord, sal_False );
+ MarkRange( aExtended );
+ ShowCursor();
+
+ if (bOk)
+ pDocSh->UpdateOle(GetViewData());
+ }
+ return sal_True; //! bOk ??
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::FillSimple( FillDir eDir, sal_Bool bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ sal_Bool bSuccess = pDocSh->GetDocFunc().FillSimple( aRange, &rMark, eDir, bRecord, sal_False );
+ if (bSuccess)
+ {
+ pDocSh->UpdateOle(GetViewData());
+ UpdateScrollBars();
+ }
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::FillSeries( FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd,
+ double fStart, double fStep, double fMax, sal_Bool bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ sal_Bool bSuccess = pDocSh->GetDocFunc().
+ FillSeries( aRange, &rMark, eDir, eCmd, eDateCmd,
+ fStart, fStep, fMax, bRecord, sal_False );
+ if (bSuccess)
+ {
+ pDocSh->UpdateOle(GetViewData());
+ UpdateScrollBars();
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ aChangeRanges.Append( aRange );
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+ }
+ }
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::FillAuto( FillDir eDir, SCCOL nStartCol, SCROW nStartRow,
+ SCCOL nEndCol, SCROW nEndRow, sal_uLong nCount, sal_Bool bRecord )
+{
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScRange aRange( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab );
+ ScRange aSourceRange( aRange );
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ sal_Bool bSuccess = pDocSh->GetDocFunc().
+ FillAuto( aRange, &rMark, eDir, nCount, bRecord, sal_False );
+ if (bSuccess)
+ {
+ MarkRange( aRange, sal_False ); // aRange ist in FillAuto veraendert worden
+ pDocSh->UpdateOle(GetViewData());
+ UpdateScrollBars();
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ ScRange aChangeRange( aRange );
+ switch ( eDir )
+ {
+ case FILL_TO_BOTTOM:
+ {
+ aChangeRange.aStart.SetRow( aSourceRange.aEnd.Row() + 1 );
+ }
+ break;
+ case FILL_TO_TOP:
+ {
+ aChangeRange.aEnd.SetRow( aSourceRange.aStart.Row() - 1 );
+ }
+ break;
+ case FILL_TO_RIGHT:
+ {
+ aChangeRange.aStart.SetCol( aSourceRange.aEnd.Col() + 1 );
+ }
+ break;
+ case FILL_TO_LEFT:
+ {
+ aChangeRange.aEnd.SetCol( aSourceRange.aStart.Col() - 1 );
+ }
+ break;
+ default:
+ {
+
+ }
+ break;
+ }
+ aChangeRanges.Append( aChangeRange );
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::FillTab( sal_uInt16 nFlags, sal_uInt16 nFunction, sal_Bool bSkipEmpty, sal_Bool bAsLink )
+{
+ //! allow source sheet to be protected
+ ScEditableTester aTester( this );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return;
+ }
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ sal_Bool bUndo(pDoc->IsUndoEnabled());
+
+ ScRange aMarkRange;
+ rMark.MarkToSimple();
+ sal_Bool bMulti = rMark.IsMultiMarked();
+ if (bMulti)
+ rMark.GetMultiMarkArea( aMarkRange );
+ else if (rMark.IsMarked())
+ rMark.GetMarkArea( aMarkRange );
+ else
+ aMarkRange = ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
+
+ ScDocument* pUndoDoc = NULL;
+// if ( bRecord )
+ if (bUndo)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+// pUndoDoc->SelectTable( nTab, sal_True ); // nur fuer Markierung
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (i != nTab && rMark.GetTableSelect(i))
+ {
+ pUndoDoc->AddUndoTab( i, i );
+ aMarkRange.aStart.SetTab( i );
+ aMarkRange.aEnd.SetTab( i );
+ pDoc->CopyToDocument( aMarkRange, IDF_ALL, bMulti, pUndoDoc );
+// pUndoDoc->SelectTable( i, sal_True );
+ }
+ }
+
+ if (bMulti)
+ pDoc->FillTabMarked( nTab, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
+ else
+ {
+ aMarkRange.aStart.SetTab( nTab );
+ aMarkRange.aEnd.SetTab( nTab );
+ pDoc->FillTab( aMarkRange, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
+ }
+
+// if ( bRecord )
+ if (bUndo)
+ { //! fuer ChangeTrack erst zum Schluss
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoFillTable( pDocSh, rMark,
+ aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nTab,
+ aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), nTab,
+ pUndoDoc, bMulti, nTab, nFlags, nFunction, bSkipEmpty, bAsLink ) );
+ }
+
+ pDocSh->PostPaintGridAll();
+ pDocSh->PostDataChanged();
+}
+
+//----------------------------------------------------------------------------
+
+/** Downward fill of selected cell(s) by double-clicking cross-hair cursor
+
+ Extends a current selection down to the last non-empty cell of an adjacent
+ column when the lower-right corner of the selection is double-clicked. It
+ uses a left-adjoining non-empty column as a guide if such is available,
+ otherwise a right-adjoining non-empty column is used.
+
+ @author Kohei Yoshida (kohei@openoffice.org)
+
+ @return No return value
+
+ @see #i12313#
+*/
+void ScViewFunc::FillCrossDblClick()
+{
+ ScRange aRange;
+ GetViewData()->GetSimpleArea( aRange );
+ aRange.Justify();
+
+ SCTAB nTab = GetViewData()->GetCurPos().Tab();
+ SCCOL nStartX = aRange.aStart.Col();
+ SCROW nStartY = aRange.aStart.Row();
+ SCCOL nEndX = aRange.aEnd.Col();
+ SCROW nEndY = aRange.aEnd.Row();
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ // Make sure the selection is not empty
+ if ( pDoc->IsBlockEmpty( nTab, nStartX, nStartY, nEndX, nEndY ) )
+ return;
+
+ if ( nEndY < MAXROW )
+ {
+ if ( nStartX > 0 )
+ {
+ SCCOL nMovX = nStartX - 1;
+ SCROW nMovY = nStartY;
+
+ if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
+ pDoc->HasData( nMovX, nStartY + 1, nTab ) )
+ {
+ pDoc->FindAreaPos( nMovX, nMovY, nTab, 0, 1 );
+
+ if ( nMovY > nEndY )
+ {
+ FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
+ nMovY - nEndY );
+ return;
+ }
+ }
+ }
+
+ if ( nEndX < MAXCOL )
+ {
+ SCCOL nMovX = nEndX + 1;
+ SCROW nMovY = nStartY;
+
+ if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
+ pDoc->HasData( nMovX, nStartY + 1, nTab ) )
+ {
+ pDoc->FindAreaPos( nMovX, nMovY, nTab, 0, 1 );
+
+ if ( nMovY > nEndY )
+ {
+ FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
+ nMovY - nEndY );
+ return;
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::TransliterateText( sal_Int32 nType )
+{
+ ScMarkData aFuncMark = GetViewData()->GetMarkData();
+ if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() )
+ {
+ // no selection -> use cursor position
+
+ ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ aFuncMark.SetMarkArea( ScRange( aCursor ) );
+ }
+
+ sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ TransliterateText( aFuncMark, nType, sal_True, sal_False );
+ if (bSuccess)
+ {
+ GetViewData()->GetViewShell()->UpdateInputHandler();
+ }
+}
+
+//----------------------------------------------------------------------------
+// AutoFormat
+
+ScAutoFormatData* ScViewFunc::CreateAutoFormatData()
+{
+ ScAutoFormatData* pData = NULL;
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+ if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
+ {
+ if ( nEndCol-nStartCol >= 3 && nEndRow-nStartRow >= 3 )
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ pData = new ScAutoFormatData;
+ pDoc->GetAutoFormatData( nStartTab, nStartCol,nStartRow,nEndCol,nEndRow, *pData );
+ }
+ }
+ return pData;
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::AutoFormat( sal_uInt16 nFormatNo, sal_Bool bRecord )
+{
+#if 1
+
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+
+ sal_Bool bSuccess = pDocSh->GetDocFunc().AutoFormat( aRange, &rMark, nFormatNo, bRecord, sal_False );
+ if (bSuccess)
+ pDocSh->UpdateOle(GetViewData());
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+
+#else
+
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ sal_Bool bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+
+ if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ sal_Bool bSize = (*ScGlobal::GetAutoFormat())[nFormatNo]->GetIncludeWidthHeight();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = sal_False;
+
+ ScDocument* pUndoDoc = NULL;
+ if ( bRecord )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab, bSize, bSize );
+ pDoc->CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
+ IDF_ATTRIB, sal_False, pUndoDoc );
+ if (bSize)
+ {
+ pDoc->CopyToDocument( nStartCol,0,nStartTab, nEndCol,MAXROW,nEndTab,
+ IDF_NONE, sal_False, pUndoDoc );
+ pDoc->CopyToDocument( 0,nStartRow,nStartTab, MAXCOL,nEndRow,nEndTab,
+ IDF_NONE, sal_False, pUndoDoc );
+ }
+ pDoc->BeginDrawUndo();
+ }
+
+ GetFrameWin()->EnterWait();
+ pDoc->AutoFormat( nStartCol, nStartRow, nEndCol, nEndRow, nFormatNo, rMark );
+ GetFrameWin()->LeaveWait();
+
+ if (bSize)
+ {
+ SetMarkedWidthOrHeight( sal_True, SC_SIZE_VISOPT, STD_EXTRA_WIDTH, sal_False, sal_False );
+ SetMarkedWidthOrHeight( sal_False, SC_SIZE_VISOPT, 0, sal_False, sal_False );
+ pDocSh->PostPaint( 0,0,nStartTab, MAXCOL,MAXROW,nStartTab,
+ PAINT_GRID | PAINT_LEFT | PAINT_TOP );
+ }
+ else
+ {
+ sal_Bool bAdj = AdjustBlockHeight( sal_False );
+ if (bAdj)
+ pDocSh->PostPaint( 0,nStartRow,nStartTab, MAXCOL,MAXROW,nStartTab,
+ PAINT_GRID | PAINT_LEFT );
+ else
+ pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab, PAINT_GRID );
+ }
+
+ if ( bRecord ) // Draw-Undo erst jetzt verfuegbar
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoAutoFormat( pDocSh,
+ ScRange(nStartCol,nStartRow,nStartTab, nEndCol,nEndRow,nEndTab),
+ pUndoDoc, rMark, bSize, nFormatNo ) );
+ }
+
+ pDocSh->UpdateOle(GetViewData());
+ pDocSh->SetDocumentModified();
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+
+#endif
+}
+
+
+//----------------------------------------------------------------------------
+// Suchen & Ersetzen
+
+void ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem,
+ sal_Bool bAddUndo, sal_Bool bIsApi )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if (bAddUndo && !pDoc->IsUndoEnabled())
+ bAddUndo = sal_False;
+
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+// sal_Bool bAttrib = pSearchItem->GetPattern();
+ sal_uInt16 nCommand = pSearchItem->GetCommand();
+ sal_Bool bAllTables = pSearchItem->IsAllTables();
+ sal_Bool* pOldSelectedTables = NULL;
+ sal_uInt16 nOldSelectedCount = 0;
+ SCTAB nOldTab = nTab;
+ SCTAB nLastTab = pDoc->GetTableCount() - 1;
+ SCTAB nStartTab, nEndTab;
+ if ( bAllTables )
+ {
+ nStartTab = 0;
+ nEndTab = nLastTab;
+ pOldSelectedTables = new sal_Bool [ nEndTab + 1 ];
+ for ( SCTAB j = 0; j <= nEndTab; j++ )
+ {
+ pOldSelectedTables[j] = rMark.GetTableSelect( j );
+ if ( pOldSelectedTables[j] )
+ ++nOldSelectedCount;
+ }
+ }
+ else
+ { //! mindestens eine ist immer selektiert
+ nStartTab = nEndTab = rMark.GetFirstSelected();
+ for ( SCTAB j = nStartTab + 1; j <= nLastTab; j++ )
+ {
+ if ( rMark.GetTableSelect( j ) )
+ nEndTab = j;
+ }
+ }
+
+ if ( nCommand == SVX_SEARCHCMD_REPLACE
+ || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
+ {
+ for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
+ {
+ if ( (bAllTables || rMark.GetTableSelect( j )) &&
+ pDoc->IsTabProtected( j ) )
+ {
+ if ( pOldSelectedTables )
+ delete [] pOldSelectedTables;
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+ }
+ }
+
+ if ( nCommand == SVX_SEARCHCMD_FIND
+ || nCommand == SVX_SEARCHCMD_FIND_ALL)
+ bAddUndo = sal_False;
+
+ //! bAttrib bei Undo beruecksichtigen !!!
+
+ ScDocument* pUndoDoc = NULL;
+ ScMarkData* pUndoMark = NULL;
+ String aUndoStr;
+ if (bAddUndo)
+ {
+ pUndoMark = new ScMarkData( rMark ); // Markierung wird veraendert
+ if ( nCommand == SVX_SEARCHCMD_REPLACE_ALL )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
+ }
+ }
+
+ if ( bAllTables )
+ { //! alles selektieren, erst nachdem pUndoMark erzeugt wurde
+ for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
+ {
+ rMark.SelectTable( j, sal_True );
+ }
+ }
+
+ DoneBlockMode(sal_True); // Markierung nicht loeschen!
+ InitOwnBlockMode();
+
+ // wenn vom Anfang an gesucht wird, nicht nochmal fragen ob vom Anfang gesucht werden soll
+ sal_Bool bFirst = sal_True;
+ if ( nCol == 0 && nRow == 0 && nTab == nStartTab && !pSearchItem->GetBackward() )
+ bFirst = sal_False;
+
+ sal_Bool bFound = sal_False;
+ while (sal_True)
+ {
+ GetFrameWin()->EnterWait();
+ if (pDoc->SearchAndReplace( *pSearchItem, nCol, nRow, nTab, rMark, aUndoStr, pUndoDoc ) )
+ {
+ bFound = sal_True;
+ bFirst = sal_True;
+ if (bAddUndo)
+ {
+ GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
+ new ScUndoReplace( GetViewData()->GetDocShell(), *pUndoMark,
+ nCol, nRow, nTab,
+ aUndoStr, pUndoDoc, pSearchItem ) );
+ pUndoDoc = NULL;
+ }
+
+ break; // Abbruch while True
+ }
+ else if ( bFirst && (nCommand == SVX_SEARCHCMD_FIND ||
+ nCommand == SVX_SEARCHCMD_REPLACE) )
+ {
+ bFirst = sal_False;
+ sal_uInt16 nRetVal;
+ GetFrameWin()->LeaveWait();
+ if ( bIsApi )
+ nRetVal = RET_NO;
+ else
+ {
+ // Suchen-Dialog als Parent, wenn vorhanden
+ Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
+ sal_uInt16 nStrId;
+ if ( pSearchItem->GetBackward() )
+ {
+ if ( nStartTab == nEndTab )
+ nStrId = STR_MSSG_SEARCHANDREPLACE_1;
+ else
+ nStrId = STR_MSSG_SEARCHANDREPLACE_4;
+ }
+ else
+ {
+ if ( nStartTab == nEndTab )
+ nStrId = STR_MSSG_SEARCHANDREPLACE_2;
+ else
+ nStrId = STR_MSSG_SEARCHANDREPLACE_5;
+ }
+ MessBox aBox( pParent, WinBits(WB_YES_NO | WB_DEF_YES),
+ ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_3 ),
+ ScGlobal::GetRscString( nStrId ) );
+ nRetVal = aBox.Execute();
+ }
+
+ if ( nRetVal == RET_YES )
+ {
+ ScDocument::GetSearchAndReplaceStart( *pSearchItem, nCol, nRow );
+ if (pSearchItem->GetBackward())
+ nTab = nEndTab;
+ else
+ nTab = nStartTab;
+ }
+ else
+ {
+ break; // Abbruch while True
+ }
+ }
+ else // nichts gefunden
+ {
+ if ( nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
+ {
+ pDocSh->PostPaintGridAll(); // Markierung
+ }
+
+ GetFrameWin()->LeaveWait();
+ if (!bIsApi)
+ {
+ // Suchen-Dialog als Parent, wenn vorhanden
+ Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
+ // "nichts gefunden"
+ InfoBox aBox( pParent, ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_0 ) );
+ aBox.Execute();
+ }
+
+ break; // Abbruch while True
+ }
+ } // of while sal_True
+
+ if ( pOldSelectedTables )
+ { // urspruenglich selektierte Tabellen wiederherstellen
+ for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
+ {
+ rMark.SelectTable( j, pOldSelectedTables[j] );
+ }
+ if ( bFound )
+ { // durch Fundstelle neu selektierte Tabelle bleibt
+ rMark.SelectTable( nTab, sal_True );
+ // wenn vorher nur eine selektiert war, ist es ein Tausch
+ //! wenn nicht, ist jetzt evtl. eine mehr selektiert
+ if ( nOldSelectedCount == 1 && nTab != nOldTab )
+ rMark.SelectTable( nOldTab, sal_False );
+ }
+ delete [] pOldSelectedTables;
+ }
+
+ MarkDataChanged();
+
+ if ( bFound )
+ {
+ if ( nTab != GetViewData()->GetTabNo() )
+ SetTabNo( nTab );
+
+ // wenn nichts markiert ist, DoneBlockMode, damit von hier aus
+ // direkt per Shift-Cursor markiert werden kann:
+ if (!rMark.IsMarked() && !rMark.IsMultiMarked())
+ DoneBlockMode(sal_True);
+
+ AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
+ SetCursor( nCol, nRow, sal_True );
+
+ if ( nCommand == SVX_SEARCHCMD_REPLACE
+ || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
+ {
+ if ( nCommand == SVX_SEARCHCMD_REPLACE )
+ pDocSh->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID );
+ else
+ pDocSh->PostPaintGridAll();
+ pDocSh->SetDocumentModified();
+ }
+ else if ( nCommand == SVX_SEARCHCMD_FIND_ALL )
+ pDocSh->PostPaintGridAll(); // Markierung
+ GetFrameWin()->LeaveWait();
+ }
+
+ delete pUndoDoc; // loeschen wenn nicht benutzt
+ delete pUndoMark; // kann immer geloescht werden
+}
+
+
+//----------------------------------------------------------------------------
+// Zielwertsuche
+
+void ScViewFunc::Solve( const ScSolveParam& rParam )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+
+ SCCOL nDestCol = rParam.aRefVariableCell.Col();
+ SCROW nDestRow = rParam.aRefVariableCell.Row();
+ SCTAB nDestTab = rParam.aRefVariableCell.Tab();
+
+ ScEditableTester aTester( pDoc, nDestTab, nDestCol,nDestRow, nDestCol,nDestRow );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return;
+ }
+
+ if ( pDoc )
+ {
+ String aTargetValStr;
+ if ( rParam.pStrTargetVal != NULL )
+ aTargetValStr = *(rParam.pStrTargetVal);
+
+ String aMsgStr;
+ String aResStr;
+ double nSolveResult;
+
+ GetFrameWin()->EnterWait();
+
+ sal_Bool bExact =
+ pDoc->Solver(
+ rParam.aRefFormulaCell.Col(),
+ rParam.aRefFormulaCell.Row(),
+ rParam.aRefFormulaCell.Tab(),
+ nDestCol, nDestRow, nDestTab,
+ aTargetValStr,
+ nSolveResult );
+
+ GetFrameWin()->LeaveWait();
+
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ sal_uLong nFormat = 0;
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nDestCol, nDestRow, nDestTab );
+ if ( pPattern )
+ nFormat = pPattern->GetNumberFormat( pFormatter );
+ Color* p;
+ pFormatter->GetOutputString( nSolveResult, nFormat, aResStr, &p );
+
+ if ( bExact )
+ {
+ aMsgStr = ScGlobal::GetRscString( STR_MSSG_SOLVE_0 );
+ aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_1 );
+ aMsgStr += String( aResStr );
+ aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_2 );
+ }
+ else
+ {
+ aMsgStr = ScGlobal::GetRscString( STR_MSSG_SOLVE_3 );
+ aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_4 );
+ aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_5 );
+ aMsgStr += String( aResStr );
+ aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_6 );
+ }
+
+ MessBox aBox( GetViewData()->GetDialogParent(),
+ WinBits(WB_YES_NO | WB_DEF_NO),
+ ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), aMsgStr );
+ sal_uInt16 nRetVal = aBox.Execute();
+
+ if ( RET_YES == nRetVal )
+ EnterValue( nDestCol, nDestRow, nDestTab, nSolveResult );
+
+ GetViewData()->GetViewShell()->UpdateInputHandler( sal_True );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// Mehrfachoperation
+
+void ScViewFunc::TabOp( const ScTabOpParam& rParam, sal_Bool bRecord )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ pDocSh->GetDocFunc().TabOp( aRange, &rMark, rParam, bRecord, sal_False );
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::MakeScenario( const String& rName, const String& rComment,
+ const Color& rColor, sal_uInt16 nFlags )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ SCTAB nNewTab = pDocSh->MakeScenario( nTab, rName, rComment, rColor, nFlags, rMark );
+ if (nFlags & SC_SCENARIO_COPYALL)
+ SetTabNo( nNewTab, sal_True ); // SC_SCENARIO_COPYALL -> sichtbar
+ else
+ {
+ SfxBindings& rBindings = GetViewData()->GetBindings();
+ rBindings.Invalidate( SID_STATUS_DOCPOS ); // Statusbar
+ rBindings.Invalidate( SID_TABLES_COUNT );
+ rBindings.Invalidate( SID_SELECT_SCENARIO );
+ rBindings.Invalidate( FID_TABLE_SHOW );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::ExtendScenario()
+{
+ ScEditableTester aTester( this );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return;
+ }
+
+ // Undo: Attribute anwenden
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScPatternAttr aPattern( pDoc->GetPool() );
+ aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) );
+ aPattern.GetItemSet().Put( ScProtectionAttr( sal_True ) );
+ ApplySelectionPattern(aPattern);
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::UseScenario( const String& rName )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ DoneBlockMode();
+ InitOwnBlockMode();
+ pDocSh->UseScenario( nTab, rName );
+}
+
+
+//----------------------------------------------------------------------------
+// Tabelle einfuegen
+
+sal_Bool ScViewFunc::InsertTable( const String& rName, SCTAB nTab, sal_Bool bRecord )
+{
+ // Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt
+ sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ InsertTable( nTab, rName, bRecord, sal_False );
+ if (bSuccess)
+ SetTabNo( nTab, sal_True );
+
+ return bSuccess;
+}
+
+//----------------------------------------------------------------------------
+// Tabellen einfuegen
+
+sal_Bool ScViewFunc::InsertTables(SvStrings *pNames, SCTAB nTab,
+ SCTAB nCount, sal_Bool bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = sal_False;
+
+ SvStrings *pNameList= NULL;
+
+ WaitObject aWait( GetFrameWin() );
+
+ if (bRecord)
+ {
+ pNameList= new SvStrings;
+ pDoc->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage
+ }
+
+ sal_Bool bFlag=sal_False;
+
+ String aValTabName;
+ String *pStr;
+
+ for(SCTAB i=0;i<nCount;i++)
+ {
+ if(pNames!=NULL)
+ {
+ pStr=pNames->GetObject(static_cast<sal_uInt16>(i));
+ }
+ else
+ {
+ aValTabName.Erase();
+ pDoc->CreateValidTabName( aValTabName);
+ pStr=&aValTabName;
+ }
+
+ if(pDoc->InsertTab( nTab+i,*pStr))
+ {
+ bFlag=sal_True;
+ pDocSh->Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab+i ) );
+ }
+ else
+ {
+ break;
+ }
+
+ if(pNameList!=NULL)
+ pNameList->Insert(new String(*pStr),pNameList->Count());
+
+ }
+
+ if (bFlag)
+ {
+ if (bRecord)
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoInsertTables( pDocSh, nTab, sal_False, pNameList));
+
+ // Views updaten:
+
+ SetTabNo( nTab, sal_True );
+ pDocSh->PostPaintExtras();
+ pDocSh->SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ return sal_True;
+ }
+ else
+ {
+ return sal_False;
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+sal_Bool ScViewFunc::AppendTable( const String& rName, sal_Bool bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = sal_False;
+
+ WaitObject aWait( GetFrameWin() );
+
+ if (bRecord)
+ pDoc->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage
+
+ if (pDoc->InsertTab( SC_TAB_APPEND, rName ))
+ {
+ SCTAB nTab = pDoc->GetTableCount()-1;
+ if (bRecord)
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoInsertTab( pDocSh, nTab, sal_True, rName));
+ GetViewData()->InsertTab( nTab );
+ SetTabNo( nTab, sal_True );
+ pDocSh->PostPaintExtras();
+ pDocSh->SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ return sal_True;
+ }
+ else
+ {
+ return sal_False;
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+sal_Bool ScViewFunc::DeleteTable( SCTAB nTab, sal_Bool bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+
+ sal_Bool bSuccess = pDocSh->GetDocFunc().DeleteTable( nTab, bRecord, sal_False );
+ if (bSuccess)
+ {
+ SCTAB nNewTab = nTab;
+ if ( nNewTab >= pDoc->GetTableCount() )
+ --nNewTab;
+ SetTabNo( nNewTab, sal_True );
+ }
+ return bSuccess;
+}
+
+sal_Bool ScViewFunc::DeleteTables(const SvShorts &TheTabs, sal_Bool bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ sal_Bool bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : sal_False;
+ SCTAB nNewTab = TheTabs.front();
+ WaitObject aWait( GetFrameWin() );
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = sal_False;
+
+ while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) )
+ --nNewTab;
+
+ sal_Bool bWasLinked = sal_False;
+ ScDocument* pUndoDoc = NULL;
+ ScRefUndoData* pUndoData = NULL;
+ if (bRecord)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+// pUndoDoc->InitDrawLayer( pDocSh );
+ SCTAB nCount = pDoc->GetTableCount();
+
+// pUndoDoc->InitUndo( pDoc, 0, nCount-1 ); // incl. Ref.
+
+ String aOldName;
+ for (size_t i = 0; i < TheTabs.size(); i++)
+ {
+ SCTAB nTab = TheTabs[i];
+ if (i==0)
+ pUndoDoc->InitUndo( pDoc, nTab,nTab, sal_True,sal_True ); // incl. Spalten/Zeilenflags
+ else
+ pUndoDoc->AddUndoTab( nTab,nTab, sal_True,sal_True ); // incl. Spalten/Zeilenflags
+
+ pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,sal_False, pUndoDoc );
+ pDoc->GetName( nTab, aOldName );
+ pUndoDoc->RenameTab( nTab, aOldName, sal_False );
+ if (pDoc->IsLinked(nTab))
+ {
+ bWasLinked = sal_True;
+ pUndoDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), pDoc->GetLinkDoc(nTab),
+ pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
+ pDoc->GetLinkTab(nTab),
+ pDoc->GetLinkRefreshDelay(nTab) );
+ }
+ if ( pDoc->IsScenario(nTab) )
+ {
+ pUndoDoc->SetScenario( nTab, sal_True );
+ String aComment;
+ Color aColor;
+ sal_uInt16 nScenFlags;
+ pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags );
+ pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
+ sal_Bool bActive = pDoc->IsActiveScenario( nTab );
+ 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));
+
+ // Drawing-Layer muss sein Undo selbst in der Hand behalten !!!
+ // pUndoDoc->TransferDrawPage(pDoc, nTab,nTab);
+ }
+
+ pUndoDoc->AddUndoTab( 0, nCount-1 ); // alle Tabs fuer Referenzen
+
+ pDoc->BeginDrawUndo(); // DeleteTab erzeugt ein SdrUndoDelPage
+
+ pUndoData = new ScRefUndoData( pDoc );
+ }
+
+ sal_Bool bDelDone = sal_False;
+
+ for (size_t i = TheTabs.size(); i > 0; i--)
+ {
+ String sCodeName;
+ sal_Bool bHasCodeName = pDoc->GetCodeName( TheTabs[i-1], sCodeName );
+ if (pDoc->DeleteTab( TheTabs[i-1], pUndoDoc ))
+ {
+ bDelDone = sal_True;
+ if( bVbaEnabled )
+ {
+ if( bHasCodeName )
+ {
+ VBA_DeleteModule( *pDocSh, sCodeName );
+ }
+ }
+ pDocSh->Broadcast( ScTablesHint( SC_TAB_DELETED, TheTabs[i-1] ) );
+ }
+ }
+ if (bRecord)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoDeleteTab( GetViewData()->GetDocShell(), TheTabs,
+ pUndoDoc, pUndoData ));
+ }
+
+
+ if (bDelDone)
+ {
+ if ( nNewTab >= pDoc->GetTableCount() )
+ nNewTab = pDoc->GetTableCount() - 1;
+
+ SetTabNo( nNewTab, sal_True );
+
+ if (bWasLinked)
+ {
+ pDocSh->UpdateLinks(); // Link-Manager updaten
+ GetViewData()->GetBindings().Invalidate(SID_LINKS);
+ }
+
+ pDocSh->PostPaintExtras();
+ pDocSh->SetDocumentModified();
+
+ SfxApplication* pSfxApp = SFX_APP(); // Navigator
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+ }
+ else
+ {
+ delete pUndoDoc;
+ delete pUndoData;
+ }
+ return bDelDone;
+}
+
+
+//----------------------------------------------------------------------------
+
+sal_Bool ScViewFunc::RenameTable( const String& rName, SCTAB nTab )
+{
+ // Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt
+ sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
+ RenameTable( nTab, rName, sal_True, sal_False );
+ if (bSuccess)
+ {
+ // Der Tabellenname koennte in einer Formel vorkommen...
+ GetViewData()->GetViewShell()->UpdateInputHandler();
+ }
+ return bSuccess;
+}
+
+
+//----------------------------------------------------------------------------
+
+bool ScViewFunc::SetTabBgColor( const Color& rColor, SCTAB nTab )
+{
+ bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( nTab, rColor, sal_True, sal_False );
+ if (bSuccess)
+ {
+ GetViewData()->GetViewShell()->UpdateInputHandler();
+ }
+ return bSuccess;
+}
+
+bool ScViewFunc::SetTabBgColor( ScUndoTabColorInfo::List& rUndoSetTabBgColorInfoList )
+{
+ bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( rUndoSetTabBgColorInfoList, sal_True, sal_False );
+ if (bSuccess)
+ {
+ GetViewData()->GetViewShell()->UpdateInputHandler();
+ }
+ return bSuccess;
+}
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::InsertAreaLink( const String& rFile,
+ const String& rFilter, const String& rOptions,
+ const String& rSource, sal_uLong nRefresh )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ SCCOL nPosX = GetViewData()->GetCurX();
+ SCROW nPosY = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScAddress aPos( nPosX, nPosY, nTab );
+
+ pDocSh->GetDocFunc().InsertAreaLink( rFile, rFilter, rOptions, rSource, aPos, nRefresh, sal_False, sal_False );
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::InsertTableLink( const String& rFile,
+ const String& rFilter, const String& rOptions,
+ const String& rTabName )
+{
+ String aFilterName = rFilter;
+ String aOpt = rOptions;
+ ScDocumentLoader aLoader( rFile, aFilterName, aOpt );
+ if (!aLoader.IsError())
+ {
+ ScDocShell* pSrcSh = aLoader.GetDocShell();
+ ScDocument* pSrcDoc = pSrcSh->GetDocument();
+ SCTAB nTab = MAXTAB+1;
+ if (!rTabName.Len()) // kein Name angegeben -> erste Tabelle
+ nTab = 0;
+ else
+ {
+ String aTemp;
+ SCTAB nCount = pSrcDoc->GetTableCount();
+ for (SCTAB i=0; i<nCount; i++)
+ {
+ pSrcDoc->GetName( i, aTemp );
+ if ( aTemp == rTabName )
+ nTab = i;
+ }
+ }
+
+ if ( nTab <= MAXTAB )
+ ImportTables( pSrcSh, 1, &nTab, sal_True,
+ GetViewData()->GetTabNo() );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// Tabellen aus anderem Dokument kopieren / linken
+
+void ScViewFunc::ImportTables( ScDocShell* pSrcShell,
+ SCTAB nCount, const SCTAB* pSrcTabs, sal_Bool bLink,SCTAB nTab )
+{
+ ScDocument* pSrcDoc = pSrcShell->GetDocument();
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ sal_Bool bUndo(pDoc->IsUndoEnabled());
+ //SCTAB nTab = GetViewData()->GetTabNo();
+
+ sal_Bool bError = sal_False;
+ sal_Bool bRefs = sal_False;
+ sal_Bool bName = sal_False;
+
+ if (pSrcDoc->GetDrawLayer())
+ pDocSh->MakeDrawLayer();
+
+ if (bUndo)
+ pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
+
+ SCTAB nInsCount = 0;
+ SCTAB i;
+ for( i=0; i<nCount; i++ )
+ { // #63304# insert sheets first and update all references
+ String aName;
+ pSrcDoc->GetName( pSrcTabs[i], aName );
+ pDoc->CreateValidTabName( aName );
+ if ( !pDoc->InsertTab( nTab+i, aName ) )
+ {
+ bError = sal_True; // total error
+ break; // for
+ }
+ ++nInsCount;
+ }
+ for (i=0; i<nCount && !bError; i++)
+ {
+ SCTAB nSrcTab = pSrcTabs[i];
+ SCTAB nDestTab1=nTab+i;
+ sal_uLong nErrVal = pDoc->TransferTab( pSrcDoc, nSrcTab, nDestTab1,
+ sal_False ); // no insert
+
+ switch (nErrVal)
+ {
+ case 0: // interner Fehler oder voll Fehler
+ bError = sal_True;
+ break;
+ case 2:
+ bRefs = sal_True;
+ break;
+ case 3:
+ bName = sal_True;
+ break;
+ case 4:
+ bRefs = bName = sal_True;
+ break;
+ }
+
+ // TransferTab doesn't copy drawing objects with bInsertNew=FALSE
+ if ( !bError )
+ pDoc->TransferDrawPage( pSrcDoc, nSrcTab, nDestTab1 );
+
+ if(!bError &&pSrcDoc->IsScenario(nSrcTab))
+ {
+ String aComment;
+ Color aColor;
+ sal_uInt16 nFlags;
+
+ pSrcDoc->GetScenarioData(nSrcTab, aComment,aColor, nFlags);
+ pDoc->SetScenario( nDestTab1,sal_True);
+ pDoc->SetScenarioData( nTab+i,aComment,aColor,nFlags);
+ sal_Bool bActive = pSrcDoc->IsActiveScenario(nSrcTab );
+ pDoc->SetActiveScenario( nDestTab1, bActive );
+ sal_Bool bVisible=pSrcDoc->IsVisible(nSrcTab);
+ pDoc->SetVisible(nDestTab1,bVisible );
+
+ }
+ }
+
+ if (bLink)
+ {
+ sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
+
+ SfxMedium* pMed = pSrcShell->GetMedium();
+ String aFileName = pMed->GetName();
+ String aFilterName;
+ if (pMed->GetFilter())
+ aFilterName = pMed->GetFilter()->GetFilterName();
+ String aOptions = ScDocumentLoader::GetOptions(*pMed);
+
+ sal_Bool bWasThere = pDoc->HasLink( aFileName, aFilterName, aOptions );
+
+ sal_uLong nRefresh = 0;
+ String aTabStr;
+ for (i=0; i<nInsCount; i++)
+ {
+ pSrcDoc->GetName( pSrcTabs[i], aTabStr );
+ pDoc->SetLink( nTab+i, SC_LINK_NORMAL,
+ aFileName, aFilterName, aOptions, aTabStr, nRefresh );
+ }
+
+ if (!bWasThere) // Link pro Quelldokument nur einmal eintragen
+ {
+ ScTableLink* pLink = new ScTableLink( pDocSh, aFileName, aFilterName, aOptions, nRefresh );
+ pLink->SetInCreate( sal_True );
+ pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aFileName, &aFilterName );
+ pLink->Update();
+ pLink->SetInCreate( sal_False );
+
+ SfxBindings& rBindings = GetViewData()->GetBindings();
+ rBindings.Invalidate( SID_LINKS );
+ }
+ }
+
+
+ if (bUndo)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoImportTab( pDocSh, nTab, nCount, bLink ) );
+ }
+
+ for (i=0; i<nInsCount; i++)
+ GetViewData()->InsertTab(nTab);
+ SetTabNo(nTab,sal_True);
+ pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
+ PAINT_GRID | PAINT_TOP | PAINT_LEFT | PAINT_EXTRAS );
+
+ SfxApplication* pSfxApp = SFX_APP();
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
+
+ pDocSh->PostPaintExtras();
+ pDocSh->PostPaintGridAll();
+ pDocSh->SetDocumentModified();
+
+ if (bRefs)
+ ErrorMessage(STR_ABSREFLOST);
+ if (bName)
+ ErrorMessage(STR_NAMECONFLICT);
+}
+
+
+//----------------------------------------------------------------------------
+// Tabelle in anderes Dokument verschieben / kopieren
+
+void ScViewFunc::MoveTable( sal_uInt16 nDestDocNo, SCTAB nDestTab, sal_Bool bCopy )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ ScDocument* pDestDoc = NULL;
+ ScDocShell* pDestShell = NULL;
+ ScTabViewShell* pDestViewSh = NULL;
+ sal_Bool bUndo (pDoc->IsUndoEnabled());
+
+ sal_Bool bNewDoc = ( nDestDocNo == SC_DOC_NEW );
+ if ( bNewDoc )
+ {
+ nDestTab = 0; // als erstes einfuegen
+
+ // ohne SFX_CALLMODE_RECORD ausfuehren, weil schon im Move-Befehl enthalten:
+
+ String aUrl = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("private:factory/"));
+ aUrl.AppendAscii(RTL_CONSTASCII_STRINGPARAM( STRING_SCAPP )); // "scalc"
+ SfxStringItem aItem( SID_FILE_NAME, aUrl );
+ SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") );
+
+ const SfxPoolItem* pRetItem = GetViewData()->GetDispatcher().Execute(
+ SID_OPENDOC, SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON, &aItem, &aTarget, 0L );
+ if ( pRetItem )
+ {
+ if ( pRetItem->ISA( SfxObjectItem ) )
+ pDestShell = PTR_CAST( ScDocShell, ((const SfxObjectItem*)pRetItem)->GetShell() );
+ else if ( pRetItem->ISA( SfxViewFrameItem ) )
+ {
+ SfxViewFrame* pFrm = ((const SfxViewFrameItem*)pRetItem)->GetFrame();
+ if (pFrm)
+ pDestShell = PTR_CAST( ScDocShell, pFrm->GetObjectShell() );
+ }
+ if (pDestShell)
+ pDestViewSh = pDestShell->GetBestViewShell();
+ }
+ }
+ else
+ pDestShell = ScDocShell::GetShellByNum( nDestDocNo );
+
+ if (!pDestShell)
+ {
+ DBG_ERROR("Dest-Doc nicht gefunden !!!");
+ return;
+ }
+
+ pDestDoc = pDestShell->GetDocument();
+
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ if (pDestDoc != pDoc)
+ {
+ if (bNewDoc)
+ {
+ while (pDestDoc->GetTableCount() > 1)
+ pDestDoc->DeleteTab(0);
+ pDestDoc->RenameTab( 0,
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("______42_____")),
+ sal_False );
+ }
+
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nTabSelCount = rMark.GetSelectCount();
+
+ SvShorts TheTabs;
+
+ for(SCTAB i=0;i<nTabCount;i++)
+ {
+ if(rMark.GetTableSelect(i))
+ {
+ String aTabName;
+ pDoc->GetName( i, aTabName);
+ TheTabs.push_back(i);
+ for(SCTAB j=i+1;j<nTabCount;j++)
+ {
+ if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
+ {
+ pDoc->GetName( j, aTabName);
+ TheTabs.push_back(j);
+ i=j;
+ }
+ else break;
+ }
+ }
+ }
+
+ GetFrameWin()->EnterWait();
+
+ if (pDoc->GetDrawLayer())
+ pDestShell->MakeDrawLayer();
+
+ if (!bNewDoc && bUndo)
+ pDestDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
+
+ sal_uLong nErrVal =1;
+ if(nDestTab==SC_TAB_APPEND)
+ nDestTab=pDestDoc->GetTableCount();
+ SCTAB nDestTab1=nDestTab;
+ for( size_t j=0; j<TheTabs.size(); j++, nDestTab1++ )
+ { // #63304# insert sheets first and update all references
+ String aName;
+ pDoc->GetName( TheTabs[j], aName );
+ pDestDoc->CreateValidTabName( aName );
+ if ( !pDestDoc->InsertTab( nDestTab1, aName ) )
+ {
+ nErrVal = 0; // total error
+ break; // for
+ }
+ }
+ if ( nErrVal > 0 )
+ {
+ nDestTab1 = nDestTab;
+ for(size_t i=0;i<TheTabs.size();i++)
+ {
+ nErrVal = pDestDoc->TransferTab( pDoc, TheTabs[i], nDestTab1,
+ sal_False ); // no insert
+
+ // TransferTab doesn't copy drawing objects with bInsertNew=FALSE
+ if ( nErrVal > 0 )
+ pDestDoc->TransferDrawPage( pDoc, TheTabs[i], nDestTab1 );
+
+ if(nErrVal>0 && pDoc->IsScenario(TheTabs[i]))
+ {
+ String aComment;
+ Color aColor;
+ sal_uInt16 nFlags;
+
+ pDoc->GetScenarioData(TheTabs[i], aComment,aColor, nFlags);
+ pDestDoc->SetScenario(nDestTab1,sal_True);
+ pDestDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
+ sal_Bool bActive = pDoc->IsActiveScenario(TheTabs[i]);
+ pDestDoc->SetActiveScenario(nDestTab1, bActive );
+
+ sal_Bool bVisible=pDoc->IsVisible(TheTabs[i]);
+ pDestDoc->SetVisible(nDestTab1,bVisible );
+
+ }
+
+ if ( nErrVal > 0 && pDoc->IsTabProtected( TheTabs[i] ) )
+ pDestDoc->SetTabProtection(nDestTab1, pDoc->GetTabProtection(TheTabs[i]));
+
+ nDestTab1++;
+ }
+ }
+ String sName;
+ if (!bNewDoc && bUndo)
+ {
+ pDestDoc->GetName(nDestTab, sName);
+ pDestShell->GetUndoManager()->AddUndoAction(
+ new ScUndoImportTab( pDestShell, nDestTab,
+ static_cast<SCTAB>(TheTabs.size()), sal_False));
+
+ }
+ else
+ {
+ pDestShell->GetUndoManager()->Clear();
+ }
+
+ GetFrameWin()->LeaveWait();
+ switch (nErrVal)
+ {
+ case 0: // interner Fehler oder voll Fehler
+ {
+ ErrorMessage(STR_TABINSERT_ERROR);
+ return;
+ }
+ //break;
+ case 2:
+ ErrorMessage(STR_ABSREFLOST);
+ break;
+ case 3:
+ ErrorMessage(STR_NAMECONFLICT);
+ break;
+ case 4:
+ {
+ ErrorMessage(STR_ABSREFLOST);
+ ErrorMessage(STR_NAMECONFLICT);
+ }
+ break;
+ default:
+ break;
+ }
+ //pDestShell->GetUndoManager()->Clear(); //! Undo implementieren !!!
+/*
+ String sName;
+ pDestDoc->GetName(nDestTab, sName);
+ pDestShell->GetUndoManager()->AddUndoAction(
+ new ScUndoInsertTab( pDestShell, nDestTab, sal_True, sName ) );
+*/
+ if (!bCopy)
+ {
+ if(nTabCount!=nTabSelCount)
+ DeleteTables(TheTabs);// incl. Paint & Undo
+ else
+ ErrorMessage(STR_TABREMOVE_ERROR);
+ }
+
+ if (bNewDoc)
+ {
+ // ChartListenerCollection must be updated before DeleteTab
+ if ( pDestDoc->IsChartListenerCollectionNeedsUpdate() )
+ pDestDoc->UpdateChartListenerCollection();
+
+ pDestDoc->DeleteTab(static_cast<SCTAB>(TheTabs.size())); // first old table
+//? pDestDoc->SelectTable(0, sal_True); // neue erste Tabelle selektieren
+ if (pDestViewSh)
+ pDestViewSh->TabChanged(); // Pages auf dem Drawing-Layer
+ pDestShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
+ PAINT_GRID | PAINT_TOP | PAINT_LEFT |
+ PAINT_EXTRAS | PAINT_SIZE );
+ // PAINT_SIZE fuer Gliederung
+ }
+ else
+ {
+ pDestShell->Broadcast( ScTablesHint( SC_TAB_INSERTED, nDestTab ) );
+ pDestShell->PostPaintExtras();
+ pDestShell->PostPaintGridAll();
+ }
+
+ TheTabs.clear();
+
+ pDestShell->SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ }
+ else // within the documents
+ {
+
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTabCount = pDoc->GetTableCount();
+
+ SvShorts TheTabs;
+ SvShorts TheDestTabs;
+ SvStrings TheTabNames;
+ String aDestName;
+ String *pString;
+
+ for(SCTAB i=0;i<nTabCount;i++)
+ {
+ if(rMark.GetTableSelect(i))
+ {
+ String aTabName;
+ pDoc->GetName( i, aTabName);
+ TheTabNames.Insert(new String(aTabName),TheTabNames.Count());
+
+ for(SCTAB j=i+1;j<nTabCount;j++)
+ {
+ if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
+ {
+ pDoc->GetName( j, aTabName);
+ TheTabNames.Insert(new String(aTabName),TheTabNames.Count());
+ i=j;
+ }
+ else break;
+ }
+
+ }
+ }
+
+ if (bCopy && bUndo)
+ pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
+
+ pDoc->GetName( nDestTab, aDestName);
+ SCTAB nDestTab1=nDestTab;
+ SCTAB nMovTab=0;
+ for(int j=0;j<TheTabNames.Count();j++)
+ {
+ nTabCount = pDoc->GetTableCount();
+ pString=TheTabNames[sal::static_int_cast<sal_uInt16>(j)];
+ if(!pDoc->GetTable(*pString,nMovTab))
+ {
+ nMovTab=nTabCount;
+ }
+ if(!pDoc->GetTable(aDestName,nDestTab1))
+ {
+ nDestTab1=nTabCount;
+ }
+ pDocShell->MoveTable( nMovTab, nDestTab1, bCopy, sal_False ); // Undo ist hier
+
+ if(bCopy && pDoc->IsScenario(nMovTab))
+ {
+ String aComment;
+ Color aColor;
+ sal_uInt16 nFlags;
+
+ pDoc->GetScenarioData(nMovTab, aComment,aColor, nFlags);
+ pDoc->SetScenario(nDestTab1,sal_True);
+ pDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
+ sal_Bool bActive = pDoc->IsActiveScenario(nMovTab );
+ pDoc->SetActiveScenario( nDestTab1, bActive );
+ sal_Bool bVisible=pDoc->IsVisible(nMovTab);
+ pDoc->SetVisible(nDestTab1,bVisible );
+ }
+
+ TheTabs.push_back(nMovTab);
+
+ if(!bCopy)
+ {
+ if(!pDoc->GetTable(*pString,nDestTab1))
+ {
+ nDestTab1=nTabCount;
+ }
+ }
+
+ TheDestTabs.push_back(nDestTab1);
+ delete pString;
+ }
+
+ nTab = GetViewData()->GetTabNo();
+
+ if (bUndo)
+ {
+ if (bCopy)
+ {
+ pDocShell->GetUndoManager()->AddUndoAction(
+ new ScUndoCopyTab( pDocShell, TheTabs, TheDestTabs));
+ }
+ else
+ {
+ pDocShell->GetUndoManager()->AddUndoAction(
+ new ScUndoMoveTab( pDocShell, TheTabs, TheDestTabs));
+ }
+ }
+
+ SCTAB nNewTab = nDestTab;
+ if (nNewTab == SC_TAB_APPEND)
+ nNewTab = pDoc->GetTableCount()-1;
+ else if (!bCopy && nTab<nDestTab)
+ nNewTab--;
+
+ SetTabNo( nNewTab, sal_True );
+
+ //#i29848# adjust references to data on the copied sheet
+ if( bCopy )
+ ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pDoc, pDestDoc, nTab, nNewTab );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::ShowTable( const String& rName )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ sal_Bool bUndo(pDoc->IsUndoEnabled());
+ sal_Bool bFound = sal_False;
+ SCTAB nPos = 0;
+ String aTabName;
+ SCTAB nCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nCount; i++)
+ {
+ pDoc->GetName( i, aTabName );
+ if ( aTabName == rName )
+ {
+ nPos = i;
+ bFound = sal_True;
+ }
+ }
+
+ if (bFound)
+ {
+ pDoc->SetVisible( nPos, sal_True );
+ if (bUndo)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nPos, sal_True ) );
+ }
+ SetTabNo( nPos, sal_True );
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
+ pDocSh->SetDocumentModified();
+ }
+ else
+ Sound::Beep();
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::HideTable( SCTAB nTab )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ sal_Bool bUndo(pDoc->IsUndoEnabled());
+ SCTAB nVisible = 0;
+ SCTAB nCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nCount; i++)
+ {
+ if (pDoc->IsVisible(i))
+ ++nVisible;
+ }
+
+ if (nVisible > 1)
+ {
+ pDoc->SetVisible( nTab, sal_False );
+ if (bUndo)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nTab, sal_False ) );
+ }
+
+ // Views updaten:
+ pDocSh->Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );
+
+ SetTabNo( nTab, sal_True );
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
+ pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
+ pDocSh->SetDocumentModified();
+ }
+ else
+ Sound::Beep();
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::InsertSpecialChar( const String& rStr, const Font& rFont )
+{
+ ScEditableTester aTester( this );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return;
+ }
+
+ const sal_Unicode* pChar = rStr.GetBuffer();
+ ScTabViewShell* pViewShell = GetViewData()->GetViewShell();
+ SvxFontItem aFontItem( rFont.GetFamily(),
+ rFont.GetName(),
+ rFont.GetStyleName(),
+ rFont.GetPitch(),
+ rFont.GetCharSet(),
+ ATTR_FONT );
+
+ // if string contains WEAK characters, set all fonts
+ sal_uInt8 nScript;
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if ( pDoc->HasStringWeakCharacters( rStr ) )
+ nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
+ else
+ nScript = pDoc->GetStringScriptType( rStr );
+
+ SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, pViewShell->GetPool() );
+ aSetItem.PutItemForScriptType( nScript, aFontItem );
+ ApplyUserItemSet( aSetItem.GetItemSet() );
+
+ while ( *pChar )
+ pViewShell->TabKeyInput( KeyEvent( *(pChar++), KeyCode() ) );
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::UpdateLineAttrs( SvxBorderLine& rLine,
+ const SvxBorderLine* pDestLine,
+ const SvxBorderLine* pSrcLine,
+ sal_Bool bColor )
+{
+ if ( pSrcLine && pDestLine )
+ {
+ if ( bColor )
+ {
+ rLine.SetColor ( pSrcLine->GetColor() );
+ rLine.SetOutWidth ( pDestLine->GetOutWidth() );
+ rLine.SetInWidth ( pDestLine->GetInWidth() );
+ rLine.SetDistance ( pDestLine->GetDistance() );
+ }
+ else
+ {
+ rLine.SetColor ( pDestLine->GetColor() );
+ rLine.SetOutWidth ( pSrcLine->GetOutWidth() );
+ rLine.SetInWidth ( pSrcLine->GetInWidth() );
+ rLine.SetDistance ( pSrcLine->GetDistance() );
+ }
+ }
+}
+
+
+#define SET_LINE_ATTRIBUTES(LINE,BOXLINE) \
+ pBoxLine = aBoxItem.Get##LINE(); \
+ if ( pBoxLine ) \
+ { \
+ if ( pLine ) \
+ { \
+ UpdateLineAttrs( aLine, pBoxLine, pLine, bColorOnly ); \
+ aBoxItem.SetLine( &aLine, BOXLINE ); \
+ } \
+ else \
+ aBoxItem.SetLine( NULL, BOXLINE ); \
+ }
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::SetSelectionFrameLines( const SvxBorderLine* pLine,
+ sal_Bool bColorOnly )
+{
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ sal_Bool bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
+ ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScPatternAttr* pSelAttrs = GetSelectionPattern();
+ const SfxItemSet& rSelItemSet = pSelAttrs->GetItemSet();
+
+ const SfxPoolItem* pBorderAttr = NULL;
+ SfxItemState eItemState = rSelItemSet.GetItemState( ATTR_BORDER, sal_True, &pBorderAttr );
+
+ const SfxPoolItem* pTLBRItem = 0;
+ SfxItemState eTLBRState = rSelItemSet.GetItemState( ATTR_BORDER_TLBR, sal_True, &pTLBRItem );
+
+ const SfxPoolItem* pBLTRItem = 0;
+ SfxItemState eBLTRState = rSelItemSet.GetItemState( ATTR_BORDER_BLTR, sal_True, &pBLTRItem );
+
+ // any of the lines visible?
+ if( (eItemState != SFX_ITEM_DEFAULT) || (eTLBRState != SFX_ITEM_DEFAULT) || (eBLTRState != SFX_ITEM_DEFAULT) )
+ {
+ // none of the lines don't care?
+ if( (eItemState != SFX_ITEM_DONTCARE) && (eTLBRState != SFX_ITEM_DONTCARE) && (eBLTRState != SFX_ITEM_DONTCARE) )
+ {
+ SfxItemSet* pOldSet = new SfxItemSet(
+ *(pDoc->GetPool()),
+ ATTR_PATTERN_START,
+ ATTR_PATTERN_END );
+ SfxItemSet* pNewSet = new SfxItemSet(
+ *(pDoc->GetPool()),
+ ATTR_PATTERN_START,
+ ATTR_PATTERN_END );
+
+ //------------------------------------------------------------
+ const SvxBorderLine* pBoxLine = NULL;
+ SvxBorderLine aLine;
+
+ // hier wird die pBoxLine benutzt:
+
+ if( pBorderAttr )
+ {
+ SvxBoxItem aBoxItem( *(const SvxBoxItem*)pBorderAttr );
+ SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
+
+ SET_LINE_ATTRIBUTES(Top,BOX_LINE_TOP)
+ SET_LINE_ATTRIBUTES(Bottom,BOX_LINE_BOTTOM)
+ SET_LINE_ATTRIBUTES(Left,BOX_LINE_LEFT)
+ SET_LINE_ATTRIBUTES(Right,BOX_LINE_RIGHT)
+
+ aBoxInfoItem.SetLine( aBoxItem.GetTop(), BOXINFO_LINE_HORI );
+ aBoxInfoItem.SetLine( aBoxItem.GetLeft(), BOXINFO_LINE_VERT );
+ aBoxInfoItem.ResetFlags(); // Lines auf Valid setzen
+
+ pOldSet->Put( *pBorderAttr );
+ pNewSet->Put( aBoxItem );
+ pNewSet->Put( aBoxInfoItem );
+ }
+
+ if( pTLBRItem && ((const SvxLineItem*)pTLBRItem)->GetLine() )
+ {
+ SvxLineItem aTLBRItem( *(const SvxLineItem*)pTLBRItem );
+ UpdateLineAttrs( aLine, aTLBRItem.GetLine(), pLine, bColorOnly );
+ aTLBRItem.SetLine( &aLine );
+ pOldSet->Put( *pTLBRItem );
+ pNewSet->Put( aTLBRItem );
+ }
+
+ if( pBLTRItem && ((const SvxLineItem*)pBLTRItem)->GetLine() )
+ {
+ SvxLineItem aBLTRItem( *(const SvxLineItem*)pBLTRItem );
+ UpdateLineAttrs( aLine, aBLTRItem.GetLine(), pLine, bColorOnly );
+ aBLTRItem.SetLine( &aLine );
+ pOldSet->Put( *pBLTRItem );
+ pNewSet->Put( aBLTRItem );
+ }
+
+ ApplyAttributes( pNewSet, pOldSet );
+
+ delete pOldSet;
+ delete pNewSet;
+ }
+ else // if ( eItemState == SFX_ITEM_DONTCARE )
+ {
+ aFuncMark.MarkToMulti();
+ pDoc->ApplySelectionLineStyle( aFuncMark, pLine, bColorOnly );
+ }
+
+ ScRange aMarkRange;
+ aFuncMark.GetMultiMarkArea( aMarkRange );
+ SCCOL nStartCol = aMarkRange.aStart.Col();
+ SCROW nStartRow = aMarkRange.aStart.Row();
+ SCTAB nStartTab = aMarkRange.aStart.Tab();
+ SCCOL nEndCol = aMarkRange.aEnd.Col();
+ SCROW nEndRow = aMarkRange.aEnd.Row();
+ SCTAB nEndTab = aMarkRange.aEnd.Tab();
+ pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab,
+ PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
+
+ pDocSh->UpdateOle( GetViewData() );
+ pDocSh->SetDocumentModified();
+ }
+}
+
+#undef SET_LINE_ATTRIBUTES
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::SetConditionalFormat( const ScConditionalFormat& rNew )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ sal_uLong nIndex = pDoc->AddCondFormat(rNew); // dafuer gibt's kein Undo
+ SfxUInt32Item aItem( ATTR_CONDITIONAL, nIndex );
+
+ ApplyAttr( aItem ); // mit Paint und Undo...
+}
+
+
+//----------------------------------------------------------------------------
+
+void ScViewFunc::SetValidation( const ScValidationData& rNew )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ sal_uLong nIndex = pDoc->AddValidationEntry(rNew); // dafuer gibt's kein Undo
+ SfxUInt32Item aItem( ATTR_VALIDDATA, nIndex );
+
+ ApplyAttr( aItem ); // mit Paint und Undo...
+}
+
+
diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx
new file mode 100644
index 000000000000..0f4893cf3512
--- /dev/null
+++ b/sc/source/ui/view/viewfun3.cxx
@@ -0,0 +1,1837 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//----------------------------------------------------------------------------
+
+#define _SV_NOXSOUND
+
+#define _BASE_DLGS_HXX
+#define _BIGINT_HXX
+#define _CACHESTR_HXX
+#define _CONFIG_HXX
+#define _CURSOR_HXX
+#define _CTRLTOOL_HXX
+#define _DLGCFG_HXX
+#define _DYNARR_HXX
+#define _EXTATTR_HXX
+#define _FILDLG_HXX
+#define _FONTDLG_HXX
+#define _FRM3D_HXX
+#define _INTRO_HXX
+#define _ISETBWR_HXX
+#define _NO_SVRTF_PARSER_HXX
+#define _MACRODLG_HXX
+#define _MODALDLG_HXX
+#define _MOREBUTTON_HXX
+#define _OUTLINER_HXX
+//#define _PRNDLG_HXX
+//#define _POLY_HXX
+#define _PVRWIN_HXX
+//#define _QUEUE_HXX
+#define _RULER_HXX
+#define _SCRWIN_HXX
+#define _SETBRW_HXX
+//#define _STACK_HXX
+//#define _STATUS_HXX ***
+#define _STDCTRL_HXX
+#define _STDMENU_HXX
+//#define _TAB_HXX
+#define _TABBAR_HXX
+#define _TREELIST_HXX
+#define _VALUESET_HXX
+#define _VCATTR_HXX
+#define _VCBRW_HXX
+#define _VCTRLS_HXX
+#define _VCSBX_HXX
+#define _VCONT_HXX
+#define _VDRWOBJ_HXX
+
+//#define _SELENG_HXX
+//#define _SOUND_HXX
+//#define _SYSDLG_HXX
+
+
+
+
+#define _PASSWD_HXX
+
+#define _SFX_DOCFILE_HXX
+//#define _SFX_DOCFILT_HXX
+#define _SFX_DOCINF_HXX
+#define _SFX_DOCSH_HXX
+//#define _SFXDOCFILT_HXX
+//#define _SFXDOCINF_HXX
+//#define _SFXDOCSH_HXX
+#define _SFX_PRNMON_HXX
+#define _SFX_RESMGR_HXX
+#define _SFX_TEMPLDLG_HXX
+//#define _SFXAPPWIN_HXX
+#define _SFXBASIC_HXX
+#define _SFXCTRLITEM
+#define _SFXDLGCFG_HXX
+//#define _SFXDISPATCH_HXX
+#define _SFXFILEDLG_HXX
+//#define _SFXIMGMGR_HXX
+#define _SFXIPFRM_HXX
+#define _SFX_MACRO_HXX
+#define _SFXMNUITEM_HXX
+#define _SFXMNUMGR_HXX
+#define _SFXMULTISEL_HXX
+//#define _SFXMSG_HXX
+#define _SFXMSGDESCR_HXX
+#define _SFXMSGPOOL_HXX
+#define _SFX_MINFITEM_HXX
+#define _SFXOBJFACE_HXX
+#define _SFXOBJFAC_HXX
+#define _SFX_SAVEOPT_HXX
+#define _SFXSTBITEM_HXX
+#define _SFXSTBMGR_HXX
+#define _SFXTBXCTRL_HXX
+#define _SFXTBXMGR_HXX
+
+#define _SI_HXX
+//#define _SI_DLL_HXX
+//#define _SIDLL_HXX
+//#define _SI_NOITEMS
+//#define _SI_NOOTHERFORMS
+//#define _SI_NOSBXCONTROLS
+//#define _SINOSBXCONTROLS
+//#define _SI_NODRW
+//#define _SI_NOCONTROL
+
+#define _SVBOXITM_HXX
+#define _SVCONTNR_HXX //
+
+#define _SDR_NOTRANSFORM
+
+#define _SVDRAG_HXX
+#define _SVINCVW_HXX
+//#define _SV_MULTISEL_HXX
+#define _SVRTV_HXX
+#define _SVTABBX_HXX
+#define _SVTREEBOX_HXX
+#define _SVTREELIST_HXX
+
+#define _SVX_DAILDLL_HXX
+#define _SVX_HYPHEN_HXX
+#define _SVX_IMPGRF_HXX
+#define _SVX_LAYCTRL_HXX
+#define _SVX_OPTITEMS_HXX
+#define _SVX_OPTGERL_HXX
+#define _SVX_OPTSAVE_HXX
+#define _SVX_OPTSPELL_HXX
+#define _SVX_OPTPATH_HXX
+#define _SVX_OPTLINGU_HXX
+#define _SVX_RULER_HXX
+#define _SVX_RULRITEM_HXX
+#define _SVX_SELCTRL_HXX
+#define _SVX_SPLWRAP_HXX
+#define _SVX_SPLDLG_HXX
+#define _SVX_STDDLG_HXX
+#define _SVX_THESDLG_HXX
+
+// INCLUDE -------------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <svx/dbexch.hrc>
+#include <svx/svdetc.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdpage.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/docfile.hxx>
+#include <svl/stritem.hxx>
+#include <svl/ptitem.hxx>
+#include <svl/urlbmk.hxx>
+#include <sot/clsids.hxx>
+#include <sot/formats.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/msgbox.hxx>
+#include <tools/urlobj.hxx>
+#include <sot/exchange.hxx>
+#include <memory>
+
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "dociter.hxx"
+#include "viewfunc.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "docfunc.hxx"
+#include "undoblk.hxx"
+#include "refundo.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "transobj.hxx"
+#include "drwtrans.hxx"
+#include "rangenam.hxx"
+#include "dbcolect.hxx"
+#include "impex.hxx" // Sylk-ID fuer CB
+#include "chgtrack.hxx"
+#include "waitoff.hxx"
+#include "scmod.hxx"
+#include "sc.hrc"
+#include "inputopt.hxx"
+#include "warnbox.hxx"
+#include "drwlayer.hxx"
+#include "editable.hxx"
+#include "transobj.hxx"
+#include "drwtrans.hxx"
+#include "docuno.hxx"
+#include "clipparam.hxx"
+#include "drawview.hxx"
+#include "chartlis.hxx"
+#include "charthelper.hxx"
+
+
+using namespace com::sun::star;
+
+// STATIC DATA ---------------------------------------------------------------
+
+
+//============================================================================
+
+// GlobalName der Writer-DocShell kommt jetzt aus comphelper/classids.hxx
+
+//----------------------------------------------------------------------------
+// C U T
+
+void ScViewFunc::CutToClip( ScDocument* pClipDoc, sal_Bool bIncludeObjects )
+{
+ UpdateInputLine();
+
+ ScEditableTester aTester( this );
+ if (!aTester.IsEditable()) // selection editable?
+ {
+ ErrorMessage( aTester.GetMessageId() );
+ return;
+ }
+
+ ScRange aRange; // zu loeschender Bereich
+ if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ const sal_Bool bRecord(pDoc->IsUndoEnabled()); // Undo/Redo
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ if ( !rMark.IsMarked() && !rMark.IsMultiMarked() ) // mark the range if not marked yet
+ {
+ DoneBlockMode();
+ InitOwnBlockMode();
+ rMark.SetMarkArea( aRange );
+ MarkDataChanged();
+ }
+
+ CopyToClip( pClipDoc, sal_True, sal_False, bIncludeObjects ); // Ab ins Clipboard
+
+ ScAddress aOldEnd( aRange.aEnd ); // Zusammengefasste Zellen im Bereich?
+ pDoc->ExtendMerge( aRange, sal_True );
+
+ ScDocument* pUndoDoc = NULL;
+ if ( bRecord )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndoSelected( pDoc, rMark );
+ // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
+ ScRange aCopyRange = aRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(pDoc->GetTableCount()-1);
+ pDoc->CopyToDocument( aCopyRange, (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS, sal_False, pUndoDoc );
+ pDoc->BeginDrawUndo();
+ }
+
+ sal_uInt16 nExtFlags = 0;
+ pDocSh->UpdatePaintExt( nExtFlags, aRange );
+
+ HideCursor(); // Cursor aendert sich !
+
+ rMark.MarkToMulti();
+ pDoc->DeleteSelection( IDF_ALL, rMark );
+ if ( bIncludeObjects )
+ pDoc->DeleteObjectsInSelection( rMark );
+ rMark.MarkToSimple();
+
+ if ( !AdjustRowHeight( aRange.aStart.Row(), aRange.aEnd.Row() ) )
+ pDocSh->PostPaint( aRange, PAINT_GRID, nExtFlags );
+
+ if ( bRecord ) // erst jetzt ist Draw-Undo verfuegbar
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoCut( pDocSh, aRange, aOldEnd, rMark, pUndoDoc ) );
+
+ aModificator.SetDocumentModified();
+ ShowCursor(); // Cursor aendert sich !
+ pDocSh->UpdateOle(GetViewData());
+
+ CellContentChanged();
+ }
+ else
+ ErrorMessage( STR_NOMULTISELECT );
+}
+
+
+//----------------------------------------------------------------------------
+// C O P Y
+
+sal_Bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, sal_Bool bCut, sal_Bool bApi, sal_Bool bIncludeObjects, sal_Bool bStopEdit )
+{
+ sal_Bool bDone = sal_False;
+ if ( bStopEdit )
+ UpdateInputLine();
+
+ ScRange aRange;
+ ScMarkType eMarkType = GetViewData()->GetSimpleArea( aRange );
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED )
+ {
+ if ( !pDoc->HasSelectedBlockMatrixFragment(
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(),
+ rMark ) )
+ {
+ sal_Bool bSysClip = sal_False;
+ if ( !pClipDoc ) // no clip doc specified
+ {
+ pClipDoc = new ScDocument( SCDOCMODE_CLIP ); // create one (deleted by ScTransferObj)
+ bSysClip = sal_True; // and copy into system
+ }
+
+ if ( !bCut )
+ {
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->ResetLastCut(); // kein CutMode mehr
+ }
+
+ if ( bSysClip && bIncludeObjects )
+ {
+ sal_Bool bAnyOle = pDoc->HasOLEObjectsInArea( aRange, &rMark );
+ // update ScGlobal::pDrawClipDocShellRef
+ ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) );
+ }
+
+ ScClipParam aClipParam(aRange, bCut);
+ aClipParam.setSourceDocID( pDoc->GetDocumentID() );
+ pDoc->CopyToClip(aClipParam, pClipDoc, &rMark, false, false, bIncludeObjects);
+
+ if ( pDoc && pClipDoc )
+ {
+ ScDrawLayer* pDrawLayer = pClipDoc->GetDrawLayer();
+ if ( pDrawLayer )
+ {
+ ScClipParam& rClipParam = pClipDoc->GetClipParam();
+ ScRangeListVector& rRangesVector = rClipParam.maProtectedChartRangesVector;
+ SCTAB nTabCount = pClipDoc->GetTableCount();
+ for ( SCTAB nTab = 0; nTab < nTabCount; ++nTab )
+ {
+ SdrPage* pPage = pDrawLayer->GetPage( static_cast< sal_uInt16 >( nTab ) );
+ if ( pPage )
+ {
+ ScChartHelper::FillProtectedChartRangesVector( rRangesVector, pDoc, pPage );
+ }
+ }
+ }
+ }
+
+ if (bSysClip)
+ {
+ ScDrawLayer::SetGlobalDrawPersist(NULL);
+
+ ScGlobal::SetClipDocName( pDoc->GetDocumentShell()->GetTitle( SFX_TITLE_FULLNAME ) );
+ }
+ pClipDoc->ExtendMerge( aRange, sal_True );
+
+ if (bSysClip)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScTransferObj ctor
+
+ ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
+ uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ if ( ScGlobal::pDrawClipDocShellRef )
+ {
+ SfxObjectShellRef aPersistRef( &(*ScGlobal::pDrawClipDocShellRef) );
+ pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive
+ }
+
+ pTransferObj->CopyToClipboard( GetActiveWin() ); // system clipboard
+ SC_MOD()->SetClipObject( pTransferObj, NULL ); // internal clipboard
+ }
+
+ bDone = sal_True;
+ }
+ else
+ {
+ if (!bApi)
+ ErrorMessage(STR_MATRIXFRAGMENTERR);
+ }
+ }
+ else if (eMarkType == SC_MARK_MULTI)
+ {
+ bool bSuccess = false;
+ ScClipParam aClipParam;
+ aClipParam.mbCutMode = false;
+ rMark.MarkToSimple();
+ rMark.FillRangeListWithMarks(&aClipParam.maRanges, false);
+
+ do
+ {
+ if (bCut)
+ // We con't support cutting of multi-selections.
+ break;
+
+ if (pClipDoc)
+ // TODO: What's this for?
+ break;
+
+ ::std::auto_ptr<ScDocument> pDocClip(new ScDocument(SCDOCMODE_CLIP));
+
+ // Check for geometrical feasibility of the ranges.
+ bool bValidRanges = true;
+ ScRangePtr p = aClipParam.maRanges.First();
+ SCCOL nPrevColDelta = 0;
+ SCROW nPrevRowDelta = 0;
+ SCCOL nPrevCol = p->aStart.Col();
+ SCROW nPrevRow = p->aStart.Row();
+ SCCOL nPrevColSize = p->aEnd.Col() - p->aStart.Col() + 1;
+ SCROW nPrevRowSize = p->aEnd.Row() - p->aStart.Row() + 1;
+ for (p = aClipParam.maRanges.Next(); p; p = aClipParam.maRanges.Next())
+ {
+ if (pDoc->HasSelectedBlockMatrixFragment(
+ p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(), rMark))
+ {
+ if (!bApi)
+ ErrorMessage(STR_MATRIXFRAGMENTERR);
+ return false;
+ }
+
+ SCCOL nColDelta = p->aStart.Col() - nPrevCol;
+ SCROW nRowDelta = p->aStart.Row() - nPrevRow;
+
+ if ((nColDelta && nRowDelta) || (nPrevColDelta && nRowDelta) || (nPrevRowDelta && nColDelta))
+ {
+ bValidRanges = false;
+ break;
+ }
+
+ if (aClipParam.meDirection == ScClipParam::Unspecified)
+ {
+ if (nColDelta)
+ aClipParam.meDirection = ScClipParam::Column;
+ if (nRowDelta)
+ aClipParam.meDirection = ScClipParam::Row;
+ }
+
+ SCCOL nColSize = p->aEnd.Col() - p->aStart.Col() + 1;
+ SCROW nRowSize = p->aEnd.Row() - p->aStart.Row() + 1;
+
+ if (aClipParam.meDirection == ScClipParam::Column && nRowSize != nPrevRowSize)
+ {
+ // column-oriented ranges must have identical row size.
+ bValidRanges = false;
+ break;
+ }
+ if (aClipParam.meDirection == ScClipParam::Row && nColSize != nPrevColSize)
+ {
+ // likewise, row-oriented ranges must have identical
+ // column size.
+ bValidRanges = false;
+ break;
+ }
+
+ nPrevCol = p->aStart.Col();
+ nPrevRow = p->aStart.Row();
+ nPrevColDelta = nColDelta;
+ nPrevRowDelta = nRowDelta;
+ nPrevColSize = nColSize;
+ nPrevRowSize = nRowSize;
+ }
+ if (!bValidRanges)
+ break;
+
+ pDoc->CopyToClip(aClipParam, pDocClip.get(), &rMark, false, false, bIncludeObjects);
+
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->ResetLastCut(); // kein CutMode mehr
+
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScTransferObj ctor
+
+ ScTransferObj* pTransferObj = new ScTransferObj( pDocClip.release(), aObjDesc );
+ uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ if ( ScGlobal::pDrawClipDocShellRef )
+ {
+ SfxObjectShellRef aPersistRef( &(*ScGlobal::pDrawClipDocShellRef) );
+ pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive
+ }
+
+ pTransferObj->CopyToClipboard( GetActiveWin() ); // system clipboard
+ SC_MOD()->SetClipObject( pTransferObj, NULL ); // internal clipboard
+ }
+
+ bSuccess = true;
+ }
+ while (false);
+
+ if (!bSuccess && !bApi)
+ ErrorMessage(STR_NOMULTISELECT);
+
+ bDone = bSuccess;
+ }
+ else
+ {
+ if (!bApi)
+ ErrorMessage(STR_NOMULTISELECT);
+ }
+
+ return bDone;
+}
+
+ScTransferObj* ScViewFunc::CopyToTransferable()
+{
+ ScRange aRange;
+ if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( !pDoc->HasSelectedBlockMatrixFragment(
+ aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aEnd.Row(),
+ rMark ) )
+ {
+ ScDocument *pClipDoc = new ScDocument( SCDOCMODE_CLIP ); // create one (deleted by ScTransferObj)
+
+ sal_Bool bAnyOle = pDoc->HasOLEObjectsInArea( aRange, &rMark );
+ ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) );
+
+ ScClipParam aClipParam(aRange, false);
+ pDoc->CopyToClip(aClipParam, pClipDoc, &rMark, false, false, true);
+
+ ScDrawLayer::SetGlobalDrawPersist(NULL);
+ pClipDoc->ExtendMerge( aRange, sal_True );
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
+ return pTransferObj;
+ }
+ }
+
+ return NULL;
+}
+
+//----------------------------------------------------------------------------
+// P A S T E
+
+void ScViewFunc::PasteDraw()
+{
+ ScViewData* pViewData = GetViewData();
+ SCCOL nPosX = pViewData->GetCurX();
+ SCROW nPosY = pViewData->GetCurY();
+ Window* pWin = GetActiveWin();
+ Point aPos = pWin->PixelToLogic( pViewData->GetScrPos( nPosX, nPosY,
+ pViewData->GetActivePart() ) );
+ ScDrawTransferObj* pDrawClip = ScDrawTransferObj::GetOwnClipboard( pWin );
+ if (pDrawClip)
+ PasteDraw( aPos, pDrawClip->GetModel(), sal_False,
+ pDrawClip->GetSourceDocID() == pViewData->GetDocument()->GetDocumentID() );
+}
+
+void ScViewFunc::PasteFromSystem()
+{
+ UpdateInputLine();
+
+ Window* pWin = GetActiveWin();
+ ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin );
+ ScDrawTransferObj* pDrawClip = ScDrawTransferObj::GetOwnClipboard( pWin );
+
+ if (pOwnClip)
+ {
+ // #129384# keep a reference in case the clipboard is changed during PasteFromClip
+ uno::Reference<datatransfer::XTransferable> aOwnClipRef( pOwnClip );
+ PasteFromClip( IDF_ALL, pOwnClip->GetDocument(),
+ PASTE_NOFUNC, sal_False, sal_False, sal_False, INS_NONE, IDF_NONE,
+ sal_True ); // allow warning dialog
+ }
+ else if (pDrawClip)
+ PasteDraw();
+ else
+ {
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
+
+// if (pClipObj.Is())
+ {
+ sal_uLong nBiff8 = SotExchange::RegisterFormatName(
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Biff8")));
+ sal_uLong nBiff5 = SotExchange::RegisterFormatName(
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Biff5")));
+
+ // als erstes SvDraw-Model, dann Grafik
+ // (Grafik darf nur bei einzelner Grafik drinstehen)
+
+ if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ))
+ {
+ // special case for tables from drawing
+ if( aDataHelper.HasFormat( SOT_FORMAT_RTF ) )
+ {
+ PasteFromSystem( FORMAT_RTF );
+ }
+ else
+ {
+ PasteFromSystem( SOT_FORMATSTR_ID_DRAWING );
+ }
+ }
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ))
+ PasteFromSystem( SOT_FORMATSTR_ID_SVXB );
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ))
+ {
+ // If it's a Writer object, insert RTF instead of OLE
+
+ sal_Bool bDoRtf = sal_False;
+ TransferableObjectDescriptor aObjDesc;
+ if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) )
+ {
+ bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) ||
+ aObjDesc.maClassName == SvGlobalName( SO3_SWWEB_CLASSID ) )
+ && aDataHelper.HasFormat( SOT_FORMAT_RTF ) );
+ }
+ if ( bDoRtf )
+ PasteFromSystem( FORMAT_RTF );
+ else
+ PasteFromSystem( SOT_FORMATSTR_ID_EMBED_SOURCE );
+ }
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ))
+ PasteFromSystem( SOT_FORMATSTR_ID_LINK_SOURCE );
+ // the following format can not affect scenario from #89579#
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ))
+ PasteFromSystem( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE );
+ // FORMAT_PRIVATE no longer here (can't work if pOwnClip is NULL)
+ else if (aDataHelper.HasFormat(nBiff8)) // before xxx_OLE formats
+ PasteFromSystem(nBiff8);
+ else if (aDataHelper.HasFormat(nBiff5))
+ PasteFromSystem(nBiff5);
+ else if (aDataHelper.HasFormat(FORMAT_RTF))
+ PasteFromSystem(FORMAT_RTF);
+ else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_HTML))
+ PasteFromSystem(SOT_FORMATSTR_ID_HTML);
+ else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_HTML_SIMPLE))
+ PasteFromSystem(SOT_FORMATSTR_ID_HTML_SIMPLE);
+ else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_SYLK))
+ PasteFromSystem(SOT_FORMATSTR_ID_SYLK);
+ else if (aDataHelper.HasFormat(FORMAT_STRING))
+ PasteFromSystem(FORMAT_STRING);
+ else if (aDataHelper.HasFormat(FORMAT_GDIMETAFILE))
+ PasteFromSystem(FORMAT_GDIMETAFILE);
+ else if (aDataHelper.HasFormat(FORMAT_BITMAP))
+ PasteFromSystem(FORMAT_BITMAP);
+ // #89579# xxx_OLE formats come last, like in SotExchange tables
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ))
+ PasteFromSystem( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE );
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ))
+ PasteFromSystem( SOT_FORMATSTR_ID_LINK_SOURCE_OLE );
+// else
+// ErrorMessage(STR_PASTE_ERROR);
+ }
+// else
+// ErrorMessage(STR_PASTE_ERROR);
+ }
+
+ // keine Fehlermeldung, weil SID_PASTE in der idl das FastCall-Flag hat,
+ // also auch gerufen wird, wenn nichts im Clipboard steht (#42531#)
+}
+
+void ScViewFunc::PasteFromTransferable( const uno::Reference<datatransfer::XTransferable>& rxTransferable )
+{
+ ScTransferObj *pOwnClip=0;
+ ScDrawTransferObj *pDrawClip=0;
+ uno::Reference<lang::XUnoTunnel> xTunnel( rxTransferable, uno::UNO_QUERY );
+ if ( xTunnel.is() )
+ {
+ sal_Int64 nHandle = xTunnel->getSomething( ScTransferObj::getUnoTunnelId() );
+ if ( nHandle )
+ pOwnClip = (ScTransferObj*) (sal_IntPtr) nHandle;
+ else
+ {
+ nHandle = xTunnel->getSomething( ScDrawTransferObj::getUnoTunnelId() );
+ if ( nHandle )
+ pDrawClip = (ScDrawTransferObj*) (sal_IntPtr) nHandle;
+ }
+ }
+
+ if (pOwnClip)
+ {
+ PasteFromClip( IDF_ALL, pOwnClip->GetDocument(),
+ PASTE_NOFUNC, sal_False, sal_False, sal_False, INS_NONE, IDF_NONE,
+ sal_True ); // allow warning dialog
+ }
+ else if (pDrawClip)
+ {
+ ScViewData* pViewData = GetViewData();
+ SCCOL nPosX = pViewData->GetCurX();
+ SCROW nPosY = pViewData->GetCurY();
+ Window* pWin = GetActiveWin();
+ Point aPos = pWin->PixelToLogic( pViewData->GetScrPos( nPosX, nPosY, pViewData->GetActivePart() ) );
+ PasteDraw( aPos, pDrawClip->GetModel(), sal_False, pDrawClip->GetSourceDocID() == pViewData->GetDocument()->GetDocumentID() );
+ }
+ else
+ {
+ TransferableDataHelper aDataHelper( rxTransferable );
+ {
+ sal_uLong nBiff8 = SotExchange::RegisterFormatName(
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Biff8")));
+ sal_uLong nBiff5 = SotExchange::RegisterFormatName(
+ String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Biff5")));
+ sal_uLong nFormatId = 0;
+ // als erstes SvDraw-Model, dann Grafik
+ // (Grafik darf nur bei einzelner Grafik drinstehen)
+
+ if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ))
+ nFormatId = SOT_FORMATSTR_ID_DRAWING;
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ))
+ nFormatId = SOT_FORMATSTR_ID_SVXB;
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ))
+ {
+ // If it's a Writer object, insert RTF instead of OLE
+ sal_Bool bDoRtf = sal_False;
+ TransferableObjectDescriptor aObjDesc;
+ if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) )
+ {
+ bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) ||
+ aObjDesc.maClassName == SvGlobalName( SO3_SWWEB_CLASSID ) )
+ && aDataHelper.HasFormat( SOT_FORMAT_RTF ) );
+ }
+ if ( bDoRtf )
+ nFormatId = FORMAT_RTF;
+ else
+ nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE;
+ }
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ))
+ nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE;
+ // the following format can not affect scenario from #89579#
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ))
+ nFormatId = SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE;
+ // FORMAT_PRIVATE no longer here (can't work if pOwnClip is NULL)
+ else if (aDataHelper.HasFormat(nBiff8)) // before xxx_OLE formats
+ nFormatId = nBiff8;
+ else if (aDataHelper.HasFormat(nBiff5))
+ nFormatId = nBiff5;
+ else if (aDataHelper.HasFormat(FORMAT_RTF))
+ nFormatId = FORMAT_RTF;
+ else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_HTML))
+ nFormatId = SOT_FORMATSTR_ID_HTML;
+ else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_HTML_SIMPLE))
+ nFormatId = SOT_FORMATSTR_ID_HTML_SIMPLE;
+ else if (aDataHelper.HasFormat(SOT_FORMATSTR_ID_SYLK))
+ nFormatId = SOT_FORMATSTR_ID_SYLK;
+ else if (aDataHelper.HasFormat(FORMAT_STRING))
+ nFormatId = FORMAT_STRING;
+ else if (aDataHelper.HasFormat(FORMAT_GDIMETAFILE))
+ nFormatId = FORMAT_GDIMETAFILE;
+ else if (aDataHelper.HasFormat(FORMAT_BITMAP))
+ nFormatId = FORMAT_BITMAP;
+ // #89579# xxx_OLE formats come last, like in SotExchange tables
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ))
+ nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE_OLE;
+ else if (aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ))
+ nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE;
+ else
+ return;
+
+ PasteDataFormat( nFormatId, aDataHelper.GetTransferable(),
+ GetViewData()->GetCurX(), GetViewData()->GetCurY(),
+ NULL, sal_False, sal_False );
+ }
+ }
+}
+
+sal_Bool ScViewFunc::PasteFromSystem( sal_uLong nFormatId, sal_Bool bApi )
+{
+ UpdateInputLine();
+
+ sal_Bool bRet = sal_True;
+ Window* pWin = GetActiveWin();
+ ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin );
+ if ( nFormatId == 0 && pOwnClip )
+ {
+ // #129384# keep a reference in case the clipboard is changed during PasteFromClip
+ uno::Reference<datatransfer::XTransferable> aOwnClipRef( pOwnClip );
+ PasteFromClip( IDF_ALL, pOwnClip->GetDocument(),
+ PASTE_NOFUNC, sal_False, sal_False, sal_False, INS_NONE, IDF_NONE,
+ !bApi ); // allow warning dialog
+ }
+ else
+ {
+ TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) );
+ if ( !aDataHelper.GetTransferable().is() )
+ return sal_False;
+
+ bRet = PasteDataFormat( nFormatId, aDataHelper.GetTransferable(),
+ GetViewData()->GetCurX(), GetViewData()->GetCurY(),
+ NULL, sal_False, !bApi ); // allow warning dialog
+
+ if ( !bRet && !bApi )
+ ErrorMessage(STR_PASTE_ERROR);
+ }
+ return bRet;
+}
+
+
+//----------------------------------------------------------------------------
+// P A S T E
+
+sal_Bool ScViewFunc::PasteOnDrawObject( const uno::Reference<datatransfer::XTransferable>& rxTransferable,
+ SdrObject* pHitObj, sal_Bool bLink )
+{
+ sal_Bool bRet = sal_False;
+ if ( bLink )
+ {
+ TransferableDataHelper aDataHelper( rxTransferable );
+ if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ) )
+ {
+ SotStorageStreamRef xStm;
+ if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_SVXB, xStm ) )
+ {
+ Graphic aGraphic;
+ *xStm >> aGraphic;
+ bRet = ApplyGraphicToObject( pHitObj, aGraphic );
+ }
+ }
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_GDIMETAFILE ) )
+ {
+ GDIMetaFile aMtf;
+ if( aDataHelper.GetGDIMetaFile( FORMAT_GDIMETAFILE, aMtf ) )
+ bRet = ApplyGraphicToObject( pHitObj, Graphic(aMtf) );
+ }
+ else if ( aDataHelper.HasFormat( SOT_FORMAT_BITMAP ) )
+ {
+ Bitmap aBmp;
+ if( aDataHelper.GetBitmap( FORMAT_BITMAP, aBmp ) )
+ bRet = ApplyGraphicToObject( pHitObj, Graphic(aBmp) );
+ }
+ }
+ else
+ {
+ // ham' wa noch nich
+ }
+ return bRet;
+}
+
+sal_Bool lcl_SelHasAttrib( ScDocument* pDoc, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+ const ScMarkData& rTabSelection, sal_uInt16 nMask )
+{
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if ( rTabSelection.GetTableSelect(nTab) && pDoc->HasAttrib( nCol1, nRow1, nTab, nCol2, nRow2, nTab, nMask ) )
+ return sal_True;
+ return sal_False;
+}
+
+//
+// Einfuegen auf Tabelle:
+//
+
+// internes Paste
+
+namespace {
+
+class CursorSwitcher
+{
+public:
+ CursorSwitcher(ScViewFunc* pViewFunc) :
+ mpViewFunc(pViewFunc)
+ {
+ mpViewFunc->HideCursor();
+ }
+
+ ~CursorSwitcher()
+ {
+ mpViewFunc->ShowCursor();
+ }
+private:
+ ScViewFunc* mpViewFunc;
+};
+
+bool lcl_checkDestRangeForOverwrite(const ScRange& rDestRange, const ScDocument* pDoc, const ScMarkData& rMark, Window* pParentWnd)
+{
+ bool bIsEmpty = true;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab < nTabCount && bIsEmpty; ++nTab)
+ {
+ if (!rMark.GetTableSelect(nTab))
+ continue;
+
+ bIsEmpty = pDoc->IsBlockEmpty(nTab, rDestRange.aStart.Col(), rDestRange.aStart.Row(),
+ rDestRange.aEnd.Col(), rDestRange.aEnd.Row());
+ }
+
+ if (!bIsEmpty)
+ {
+ ScReplaceWarnBox aBox(pParentWnd);
+ if (aBox.Execute() != RET_YES)
+ {
+ // changing the configuration is within the ScReplaceWarnBox
+ return false;
+ }
+ }
+ return true;
+}
+
+}
+
+sal_Bool ScViewFunc::PasteFromClip( sal_uInt16 nFlags, ScDocument* pClipDoc,
+ sal_uInt16 nFunction, sal_Bool bSkipEmpty,
+ sal_Bool bTranspose, sal_Bool bAsLink,
+ InsCellCmd eMoveMode, sal_uInt16 nUndoExtraFlags,
+ sal_Bool bAllowDialogs )
+{
+ if (!pClipDoc)
+ {
+ DBG_ERROR("PasteFromClip: pClipDoc=0 not allowed");
+ return sal_False;
+ }
+
+ // fuer Undo etc. immer alle oder keine Inhalte sichern
+ sal_uInt16 nContFlags = IDF_NONE;
+ if (nFlags & IDF_CONTENTS)
+ nContFlags |= IDF_CONTENTS;
+ if (nFlags & IDF_ATTRIB)
+ nContFlags |= IDF_ATTRIB;
+ // evtl. Attribute ins Undo ohne sie vom Clip ins Doc zu kopieren
+ sal_uInt16 nUndoFlags = nContFlags;
+ if (nUndoExtraFlags & IDF_ATTRIB)
+ nUndoFlags |= IDF_ATTRIB;
+ // do not copy note captions into undo document
+ nUndoFlags |= IDF_NOCAPTIONS;
+
+ ScClipParam& rClipParam = pClipDoc->GetClipParam();
+ if (rClipParam.isMultiRange())
+ return PasteMultiRangesFromClip(
+ nFlags, pClipDoc, nFunction, bSkipEmpty, bTranspose, bAsLink, bAllowDialogs,
+ eMoveMode, nContFlags, nUndoFlags);
+
+ sal_Bool bCutMode = pClipDoc->IsCutMode(); // if transposing, take from original clipdoc
+ sal_Bool bIncludeFiltered = bCutMode;
+
+ // paste drawing: also if IDF_NOTE is set (to create drawing layer for note captions)
+ sal_Bool bPasteDraw = ( pClipDoc->GetDrawLayer() && ( nFlags & (IDF_OBJECTS|IDF_NOTE) ) );
+
+ ScDocShellRef aTransShellRef; // for objects in xTransClip - must remain valid as long as xTransClip
+ ScDocument* pOrigClipDoc = NULL;
+ ::std::auto_ptr< ScDocument > xTransClip;
+ if ( bTranspose )
+ {
+ SCCOL nX;
+ SCROW nY;
+ // include filtered rows until TransposeClip can skip them
+ bIncludeFiltered = sal_True;
+ pClipDoc->GetClipArea( nX, nY, sal_True );
+ if ( nY > static_cast<sal_Int32>(MAXCOL) ) // zuviele Zeilen zum Transponieren
+ {
+ ErrorMessage(STR_PASTE_FULL);
+ return sal_False;
+ }
+ pOrigClipDoc = pClipDoc; // fuer Referenzen
+
+ if ( bPasteDraw )
+ {
+ aTransShellRef = new ScDocShell; // DocShell needs a Ref immediately
+ aTransShellRef->DoInitNew(NULL);
+ }
+ ScDrawLayer::SetGlobalDrawPersist(aTransShellRef);
+
+ xTransClip.reset( new ScDocument( SCDOCMODE_CLIP ));
+ pClipDoc->TransposeClip( xTransClip.get(), nFlags, bAsLink );
+ pClipDoc = xTransClip.get();
+
+ ScDrawLayer::SetGlobalDrawPersist(NULL);
+ }
+
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ SCTAB nStartTab;
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ SCTAB nEndTab;
+ SCCOL nClipSizeX;
+ SCROW nClipSizeY;
+ pClipDoc->GetClipArea( nClipSizeX, nClipSizeY, sal_True ); // size in clipboard doc
+
+ // size in target doc: include filtered rows only if CutMode is set
+ SCCOL nDestSizeX;
+ SCROW nDestSizeY;
+ pClipDoc->GetClipArea( nDestSizeX, nDestSizeY, bIncludeFiltered );
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ ::svl::IUndoManager* pUndoMgr = pDocSh->GetUndoManager();
+ const sal_Bool bRecord(pDoc->IsUndoEnabled());
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ ScRange aMarkRange;
+ ScMarkData aFilteredMark( rMark); // local copy for all modifications
+ ScMarkType eMarkType = GetViewData()->GetSimpleArea( aMarkRange, aFilteredMark);
+ bool bMarkIsFiltered = (eMarkType == SC_MARK_SIMPLE_FILTERED);
+ bool bNoPaste = ((eMarkType != SC_MARK_SIMPLE && !bMarkIsFiltered) ||
+ (bMarkIsFiltered && (eMoveMode != INS_NONE || bAsLink)));
+ if (!bNoPaste && !rMark.IsMarked())
+ {
+ // Create a selection with clipboard row count and check that for
+ // filtered.
+ nStartCol = GetViewData()->GetCurX();
+ nStartRow = GetViewData()->GetCurY();
+ nStartTab = GetViewData()->GetTabNo();
+ nEndCol = nStartCol + nDestSizeX;
+ nEndRow = nStartRow + nDestSizeY;
+ nEndTab = nStartTab;
+ aMarkRange = ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
+ if (ScViewUtil::HasFiltered( aMarkRange, pDoc))
+ {
+ bMarkIsFiltered = true;
+ // Fit to clipboard's row count unfiltered rows. If there is no
+ // fit assume that pasting is not possible. Note that nDestSizeY is
+ // size-1 (difference).
+ if (!ScViewUtil::FitToUnfilteredRows( aMarkRange, pDoc, nDestSizeY+1))
+ bNoPaste = true;
+ }
+ aFilteredMark.SetMarkArea( aMarkRange);
+ }
+ if (bNoPaste)
+ {
+ ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
+ return sal_False;
+ }
+
+ SCROW nUnfilteredRows = aMarkRange.aEnd.Row() - aMarkRange.aStart.Row() + 1;
+ ScRangeList aRangeList;
+ if (bMarkIsFiltered)
+ {
+ ScViewUtil::UnmarkFiltered( aFilteredMark, pDoc);
+ aFilteredMark.FillRangeListWithMarks( &aRangeList, sal_False);
+ nUnfilteredRows = 0;
+ for (ScRange* p = aRangeList.First(); p; p = aRangeList.Next())
+ {
+ nUnfilteredRows += p->aEnd.Row() - p->aStart.Row() + 1;
+ }
+#if 0
+ /* This isn't needed but could be a desired restriction. */
+ // For filtered, destination rows have to be an exact multiple of
+ // source rows. Note that nDestSizeY is size-1 (difference), so
+ // nDestSizeY==0 fits always.
+ if ((nUnfilteredRows % (nDestSizeY+1)) != 0)
+ {
+ /* FIXME: this should be a more descriptive error message then. */
+ ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
+ return sal_False;
+ }
+#endif
+ }
+
+ SCCOL nMarkAddX = 0;
+ SCROW nMarkAddY = 0;
+
+ // Also for a filtered selection the area is used, for undo et al.
+ if ( aFilteredMark.IsMarked() || bMarkIsFiltered )
+ {
+ aMarkRange.GetVars( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
+ SCCOL nBlockAddX = nEndCol-nStartCol;
+ SCROW nBlockAddY = nEndRow-nStartRow;
+
+ // #58422# Nachfrage, wenn die Selektion groesser als 1 Zeile/Spalte, aber kleiner
+ // als das Clipboard ist (dann wird ueber die Selektion hinaus eingefuegt)
+
+ // ClipSize is not size, but difference
+ if ( ( nBlockAddX != 0 && nBlockAddX < nDestSizeX ) ||
+ ( nBlockAddY != 0 && nBlockAddY < nDestSizeY ) ||
+ ( bMarkIsFiltered && nUnfilteredRows < nDestSizeY+1 ) )
+ {
+ ScWaitCursorOff aWaitOff( GetFrameWin() );
+ String aMessage = ScGlobal::GetRscString( STR_PASTE_BIGGER );
+ QueryBox aBox( GetViewData()->GetDialogParent(),
+ WinBits(WB_YES_NO | WB_DEF_NO), aMessage );
+ if ( aBox.Execute() != RET_YES )
+ {
+ return sal_False;
+ }
+ }
+
+ if (nBlockAddX > nDestSizeX)
+ nMarkAddX = nBlockAddX - nDestSizeX; // fuer Merge-Test
+ else
+ nEndCol = nStartCol + nDestSizeX;
+
+ if (nBlockAddY > nDestSizeY)
+ nMarkAddY = nBlockAddY - nDestSizeY; // fuer Merge-Test
+ else
+ {
+ nEndRow = nStartRow + nDestSizeY;
+ if (bMarkIsFiltered || nEndRow > aMarkRange.aEnd.Row())
+ {
+ // Same as above if nothing was marked: re-fit selection to
+ // unfiltered rows. Extending the selection actually may
+ // introduce filtered rows where there weren't any before, so
+ // we also need to test for that.
+ aMarkRange = ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
+ if (bMarkIsFiltered || ScViewUtil::HasFiltered( aMarkRange, pDoc))
+ {
+ bMarkIsFiltered = true;
+ // Worst case: all rows up to the end of the sheet are filtered.
+ if (!ScViewUtil::FitToUnfilteredRows( aMarkRange, pDoc, nDestSizeY+1))
+ {
+ ErrorMessage(STR_PASTE_FULL);
+ return sal_False;
+ }
+ }
+ aMarkRange.GetVars( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab);
+ aFilteredMark.SetMarkArea( aMarkRange);
+ if (bMarkIsFiltered)
+ {
+ ScViewUtil::UnmarkFiltered( aFilteredMark, pDoc);
+ aFilteredMark.FillRangeListWithMarks( &aRangeList, sal_True);
+ }
+ }
+ }
+ }
+ else
+ {
+ nStartCol = GetViewData()->GetCurX();
+ nStartRow = GetViewData()->GetCurY();
+ nStartTab = GetViewData()->GetTabNo();
+ nEndCol = nStartCol + nDestSizeX;
+ nEndRow = nStartRow + nDestSizeY;
+ nEndTab = nStartTab;
+ }
+
+ bool bOffLimits = !ValidCol(nEndCol) || !ValidRow(nEndRow);
+
+ // Zielbereich, wie er angezeigt wird:
+ ScRange aUserRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab );
+
+ // Sollen Zellen eingefuegt werden?
+ // (zu grosse nEndCol/nEndRow werden weiter unten erkannt)
+ sal_Bool bInsertCells = ( eMoveMode != INS_NONE && !bOffLimits );
+ if ( bInsertCells )
+ {
+ // #94115# Instead of EnterListAction, the paste undo action is merged into the
+ // insert action, so Repeat can insert the right cells
+
+ MarkRange( aUserRange ); // wird vor CopyFromClip sowieso gesetzt
+
+ // #72930# CutMode is reset on insertion of cols/rows but needed again on cell move
+ sal_Bool bCut = pClipDoc->IsCutMode();
+ if (!InsertCells( eMoveMode, bRecord, sal_True )) // is inserting possible?
+ {
+ return sal_False;
+ // #i21036# EnterListAction isn't used, and InsertCells doesn't insert
+ // its undo action on failure, so no undo handling is needed here
+ }
+ if ( bCut )
+ pClipDoc->SetCutMode( bCut );
+ }
+ else if (!bOffLimits)
+ {
+ sal_Bool bAskIfNotEmpty = bAllowDialogs &&
+ ( nFlags & IDF_CONTENTS ) &&
+ nFunction == PASTE_NOFUNC &&
+ SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
+ if ( bAskIfNotEmpty )
+ {
+ if (!lcl_checkDestRangeForOverwrite(aUserRange, pDoc, aFilteredMark, GetViewData()->GetDialogParent()))
+ return false;
+ }
+ }
+
+ SCCOL nClipStartX; // Clipboard-Bereich erweitern
+ SCROW nClipStartY;
+ pClipDoc->GetClipStart( nClipStartX, nClipStartY );
+ SCCOL nUndoEndCol = nClipStartX + nClipSizeX;
+ SCROW nUndoEndRow = nClipStartY + nClipSizeY; // end of source area in clipboard document
+ sal_Bool bClipOver = sal_False;
+ // #i68690# ExtendMerge for the clip doc must be called with the clipboard's sheet numbers.
+ // The same end column/row can be used for all calls because the clip doc doesn't contain
+ // content outside the clip area.
+ for (SCTAB nClipTab=0; nClipTab<=MAXTAB; nClipTab++)
+ if ( pClipDoc->HasTable(nClipTab) )
+ if ( pClipDoc->ExtendMerge( nClipStartX,nClipStartY, nUndoEndCol,nUndoEndRow, nClipTab, sal_False ) )
+ bClipOver = sal_True;
+ nUndoEndCol -= nClipStartX + nClipSizeX;
+ nUndoEndRow -= nClipStartY + nClipSizeY; // now contains only the difference added by ExtendMerge
+ nUndoEndCol = sal::static_int_cast<SCCOL>( nUndoEndCol + nEndCol );
+ nUndoEndRow = sal::static_int_cast<SCROW>( nUndoEndRow + nEndRow ); // destination area, expanded for merged cells
+
+// if (nUndoEndCol < nEndCol) nUndoEndCol = nEndCol;
+// if (nUndoEndRow < nEndRow) nUndoEndRow = nEndRow;
+
+// nUndoEndCol += nMarkAddX;
+// nUndoEndRow += nMarkAddY;
+
+ if (nUndoEndCol>MAXCOL || nUndoEndRow>MAXROW)
+ {
+ ErrorMessage(STR_PASTE_FULL);
+ return sal_False;
+ }
+
+ pDoc->ExtendMergeSel( nStartCol,nStartRow, nUndoEndCol,nUndoEndRow, aFilteredMark, sal_False );
+
+ // Test auf Zellschutz
+
+ ScEditableTester aTester( pDoc, nStartTab, nStartCol,nStartRow, nUndoEndCol,nUndoEndRow );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return sal_False;
+ }
+
+ //! Test auf Ueberlappung
+ //! nur wirkliche Schnittmenge testen !!!!!!!
+
+ // pDoc->HasCommonAttr( StartCol,nStartRow, nUndoEndCol,nUndoEndRow, nStartTab,
+ // pClipDoc, nClipStartX, nClipStartY );
+
+ ScDocFunc& rDocFunc = pDocSh->GetDocFunc();
+ if ( bRecord )
+ {
+ String aUndo = ScGlobal::GetRscString( pClipDoc->IsCutMode() ? STR_UNDO_MOVE : STR_UNDO_COPY );
+ pUndoMgr->EnterListAction( aUndo, aUndo );
+ }
+
+ if (bClipOver)
+ if (lcl_SelHasAttrib( pDoc, nStartCol,nStartRow, nUndoEndCol,nUndoEndRow, aFilteredMark, HASATTR_OVERLAPPED ))
+ { // "Cell merge not possible if cells already merged"
+ ScDocAttrIterator aIter( pDoc, nStartTab, nStartCol, nStartRow, nUndoEndCol, nUndoEndRow );
+ const ScPatternAttr* pPattern = NULL;
+ const ScMergeAttr* pMergeFlag = NULL;
+ const ScMergeFlagAttr* pMergeFlagAttr = NULL;
+ SCCOL nCol = -1;
+ SCROW nRow1 = -1;
+ SCROW nRow2 = -1;
+ while ( ( pPattern = aIter.GetNext( nCol, nRow1, nRow2 ) ) != NULL )
+ {
+ pMergeFlag = (const ScMergeAttr*) &pPattern->GetItem(ATTR_MERGE);
+ pMergeFlagAttr = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
+ if( ( pMergeFlag && pMergeFlag->IsMerged() ) || ( pMergeFlagAttr && pMergeFlagAttr->IsOverlapped() ) )
+ {
+ ScRange aRange(nCol, nRow1, nStartTab);
+ pDoc->ExtendOverlapped(aRange);
+ pDoc->ExtendMerge(aRange, sal_True, sal_True);
+ rDocFunc.UnmergeCells(aRange, bRecord, sal_True);
+ }
+ }
+ }
+
+ if ( !bCutMode )
+ {
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->ResetLastCut(); // kein CutMode mehr
+ }
+
+ sal_Bool bColInfo = ( nStartRow==0 && nEndRow==MAXROW );
+ sal_Bool bRowInfo = ( nStartCol==0 && nEndCol==MAXCOL );
+
+ ScDocument* pUndoDoc = NULL;
+ ScDocument* pRefUndoDoc = NULL;
+ ScDocument* pRedoDoc = NULL;
+ ScRefUndoData* pUndoData = NULL;
+
+ if ( bRecord )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndoSelected( pDoc, aFilteredMark, bColInfo, bRowInfo );
+
+ // all sheets - CopyToDocument skips those that don't exist in pUndoDoc
+ SCTAB nTabCount = pDoc->GetTableCount();
+ pDoc->CopyToDocument( nStartCol, nStartRow, 0, nUndoEndCol, nUndoEndRow, nTabCount-1,
+ nUndoFlags, sal_False, pUndoDoc );
+
+ if ( bCutMode )
+ {
+ pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, sal_False, sal_False );
+
+ pUndoData = new ScRefUndoData( pDoc );
+ }
+ }
+
+ sal_uInt16 nExtFlags = 0;
+ pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab ); // content before the change
+
+ if (GetViewData()->IsActive())
+ {
+ DoneBlockMode();
+ InitOwnBlockMode();
+ }
+ rMark.SetMarkArea( aUserRange );
+ MarkDataChanged();
+
+ HideCursor(); // Cursor aendert sich !
+
+ //
+ // Aus Clipboard kopieren,
+ // wenn gerechnet werden soll, Originaldaten merken
+ //
+
+ ScDocument* pMixDoc = NULL;
+ if ( bSkipEmpty || nFunction )
+ {
+ if ( nFlags & IDF_CONTENTS )
+ {
+ pMixDoc = new ScDocument( SCDOCMODE_UNDO );
+ pMixDoc->InitUndo( pDoc, nStartTab, nEndTab );
+ pDoc->CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
+ IDF_CONTENTS, sal_False, pMixDoc );
+ }
+ }
+
+ /* Make draw layer and start drawing undo.
+ - Needed before AdjustBlockHeight to track moved drawing objects.
+ - Needed before pDoc->CopyFromClip to track inserted note caption objects.
+ */
+ if ( bPasteDraw )
+ pDocSh->MakeDrawLayer();
+ if ( bRecord )
+ pDoc->BeginDrawUndo();
+
+ sal_uInt16 nNoObjFlags = nFlags & ~IDF_OBJECTS;
+ if (!bAsLink)
+ {
+ // copy normally (original range)
+ pDoc->CopyFromClip( aUserRange, aFilteredMark, nNoObjFlags,
+ pRefUndoDoc, pClipDoc, sal_True, sal_False, bIncludeFiltered,
+ bSkipEmpty, (bMarkIsFiltered ? &aRangeList : NULL) );
+
+ // bei Transpose Referenzen per Hand anpassen
+ if ( bTranspose && bCutMode && (nFlags & IDF_CONTENTS) )
+ pDoc->UpdateTranspose( aUserRange.aStart, pOrigClipDoc, aFilteredMark, pRefUndoDoc );
+ }
+ else if (!bTranspose)
+ {
+ // copy with bAsLink=TRUE
+ pDoc->CopyFromClip( aUserRange, aFilteredMark, nNoObjFlags, pRefUndoDoc, pClipDoc,
+ sal_True, sal_True, bIncludeFiltered, bSkipEmpty );
+ }
+ else
+ {
+ // alle Inhalte kopieren (im TransClipDoc stehen nur Formeln)
+ pDoc->CopyFromClip( aUserRange, aFilteredMark, nContFlags, pRefUndoDoc, pClipDoc );
+ }
+
+ // skipped rows and merged cells don't mix
+ if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() )
+ rDocFunc.UnmergeCells( aUserRange, sal_False, sal_True );
+
+ pDoc->ExtendMergeSel( nStartCol, nStartRow, nEndCol, nEndRow, aFilteredMark, sal_True ); // Refresh
+ // und Bereich neu
+
+ if ( pMixDoc ) // Rechenfunktionen mit Original-Daten auszufuehren ?
+ {
+ pDoc->MixDocument( aUserRange, nFunction, bSkipEmpty, pMixDoc );
+ }
+ delete pMixDoc;
+
+ AdjustBlockHeight(); // update row heights before pasting objects
+
+ ::std::vector< ::rtl::OUString > aExcludedChartNames;
+ SdrPage* pPage = NULL;
+
+ if ( nFlags & IDF_OBJECTS )
+ {
+ ScDrawView* pScDrawView = GetScDrawView();
+ SdrModel* pModel = ( pScDrawView ? pScDrawView->GetModel() : NULL );
+ pPage = ( pModel ? pModel->GetPage( static_cast< sal_uInt16 >( nStartTab ) ) : NULL );
+ if ( pPage )
+ {
+ ScChartHelper::GetChartNames( aExcludedChartNames, pPage );
+ }
+
+ // Paste the drawing objects after the row heights have been updated.
+
+ pDoc->CopyFromClip( aUserRange, aFilteredMark, IDF_OBJECTS, pRefUndoDoc, pClipDoc,
+ sal_True, sal_False, bIncludeFiltered );
+ }
+
+ //
+ //
+ //
+
+ pDocSh->UpdatePaintExt( nExtFlags, nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab ); // content after the change
+
+
+ // ggf. Autofilter-Koepfe loeschen
+ if (bCutMode)
+ if (pDoc->RefreshAutoFilter( nClipStartX,nClipStartY, nClipStartX+nClipSizeX,
+ nClipStartY+nClipSizeY, nStartTab ))
+ pDocSh->PostPaint( nClipStartX,nClipStartY,nStartTab,
+ nClipStartX+nClipSizeX,nClipStartY,nStartTab,
+ PAINT_GRID );
+
+ ShowCursor(); // Cursor aendert sich !
+
+ //! Block-Bereich bei RefUndoDoc weglassen !!!
+
+ if ( bRecord )
+ {
+ // Redo-Daten werden erst beim ersten Undo kopiert
+ // ohne RefUndoDoc muss das Redo-Doc noch nicht angelegt werden
+
+ if (pRefUndoDoc)
+ {
+ pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pRedoDoc->InitUndo( pDoc, nStartTab, nEndTab, bColInfo, bRowInfo );
+
+ // angepasste Referenzen ins Redo-Doc
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ pRedoDoc->AddUndoTab( 0, nTabCount-1 );
+ pDoc->CopyUpdated( pRefUndoDoc, pRedoDoc );
+
+ // alte Referenzen ins Undo-Doc
+
+ //! Tabellen selektieren ?
+ pUndoDoc->AddUndoTab( 0, nTabCount-1 );
+ pRefUndoDoc->DeleteArea( nStartCol, nStartRow, nEndCol, nEndRow, aFilteredMark, IDF_ALL );
+ pRefUndoDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTabCount-1,
+ IDF_FORMULA, sal_False, pUndoDoc );
+ delete pRefUndoDoc;
+ }
+
+ // DeleteUnchanged for pUndoData is in ScUndoPaste ctor,
+ // UndoData for redo is made during first undo
+
+ ScUndoPasteOptions aOptions; // store options for repeat
+ aOptions.nFunction = nFunction;
+ aOptions.bSkipEmpty = bSkipEmpty;
+ aOptions.bTranspose = bTranspose;
+ aOptions.bAsLink = bAsLink;
+ aOptions.eMoveMode = eMoveMode;
+
+ SfxUndoAction* pUndo = new ScUndoPaste( pDocSh,
+ nStartCol, nStartRow, nStartTab,
+ nUndoEndCol, nUndoEndRow, nEndTab, aFilteredMark,
+ pUndoDoc, pRedoDoc, nFlags | nUndoFlags,
+ pUndoData, NULL, NULL, NULL,
+ sal_False, &aOptions ); // sal_False = Redo data not yet copied
+
+ if ( bInsertCells )
+ {
+ // Merge the paste undo action into the insert action.
+ // Use ScUndoWrapper so the ScUndoPaste pointer can be stored in the insert action.
+
+ pUndoMgr->AddUndoAction( new ScUndoWrapper( pUndo ), sal_True );
+ }
+ else
+ pUndoMgr->AddUndoAction( pUndo );
+ pUndoMgr->LeaveListAction();
+ }
+
+ sal_uInt16 nPaint = PAINT_GRID;
+ if (bColInfo)
+ {
+ nPaint |= PAINT_TOP;
+ nUndoEndCol = MAXCOL; // nur zum Zeichnen !
+ }
+ if (bRowInfo)
+ {
+ nPaint |= PAINT_LEFT;
+ nUndoEndRow = MAXROW; // nur zum Zeichnen !
+ }
+ pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
+ nUndoEndCol, nUndoEndRow, nEndTab, nPaint, nExtFlags );
+ // AdjustBlockHeight has already been called above
+
+ aModificator.SetDocumentModified();
+ PostPasteFromClip(aUserRange, rMark);
+
+ if ( nFlags & IDF_OBJECTS )
+ {
+ ScModelObj* pModelObj = ( pDocSh ? ScModelObj::getImplementation( pDocSh->GetModel() ) : NULL );
+ if ( pDoc && pPage && pModelObj )
+ {
+ bool bSameDoc = ( rClipParam.getSourceDocID() == pDoc->GetDocumentID() );
+ const ScRangeListVector& rProtectedChartRangesVector( rClipParam.maProtectedChartRangesVector );
+ ScChartHelper::CreateProtectedChartListenersAndNotify( pDoc, pPage, pModelObj, nStartTab,
+ rProtectedChartRangesVector, aExcludedChartNames, bSameDoc );
+ }
+ }
+
+ return sal_True;
+}
+
+bool ScViewFunc::PasteMultiRangesFromClip(
+ sal_uInt16 nFlags, ScDocument* pClipDoc, sal_uInt16 nFunction,
+ bool bSkipEmpty, bool bTranspose, bool bAsLink, bool bAllowDialogs,
+ InsCellCmd eMoveMode, sal_uInt16 /*nContFlags*/, sal_uInt16 nUndoFlags)
+{
+ ScViewData& rViewData = *GetViewData();
+ ScDocument* pDoc = rViewData.GetDocument();
+ ScDocShell* pDocSh = rViewData.GetDocShell();
+ ScMarkData aMark(rViewData.GetMarkData());
+ const ScAddress& rCurPos = rViewData.GetCurPos();
+ ScClipParam& rClipParam = pClipDoc->GetClipParam();
+ SCCOL nColSize = rClipParam.getPasteColSize();
+ SCROW nRowSize = rClipParam.getPasteRowSize();
+
+ if (bTranspose)
+ {
+ if (static_cast<SCROW>(rCurPos.Col()) + nRowSize-1 > static_cast<SCROW>(MAXCOL))
+ {
+ ErrorMessage(STR_PASTE_FULL);
+ return false;
+ }
+
+ ::std::auto_ptr<ScDocument> pTransClip(new ScDocument(SCDOCMODE_CLIP));
+ pClipDoc->TransposeClip(pTransClip.get(), nFlags, bAsLink);
+ pClipDoc = pTransClip.release();
+ SCCOL nTempColSize = nColSize;
+ nColSize = static_cast<SCCOL>(nRowSize);
+ nRowSize = static_cast<SCROW>(nTempColSize);
+ }
+
+ if (!ValidCol(rCurPos.Col()+nColSize-1) || !ValidRow(rCurPos.Row()+nRowSize-1))
+ {
+ ErrorMessage(STR_PASTE_FULL);
+ return false;
+ }
+
+ // Determine the first and last selected sheet numbers.
+ SCTAB nTab1 = aMark.GetFirstSelected();
+ SCTAB nTab2 = nTab1;
+ for (SCTAB i = nTab1+1; i <= MAXTAB; ++i)
+ if (aMark.GetTableSelect(i))
+ nTab2 = i;
+
+ ScDocShellModificator aModificator(*pDocSh);
+
+ // For multi-selection paste, we don't support cell duplication for larger
+ // destination range. In case the destination is marked, we reset it to
+ // the clip size.
+ ScRange aMarkedRange(rCurPos.Col(), rCurPos.Row(), nTab1,
+ rCurPos.Col()+nColSize-1, rCurPos.Row()+nRowSize-1, nTab2);
+
+ // Extend the marked range to account for filtered rows in the destination
+ // area.
+ if (ScViewUtil::HasFiltered(aMarkedRange, pDoc))
+ {
+ if (!ScViewUtil::FitToUnfilteredRows(aMarkedRange, pDoc, nRowSize))
+ return false;
+ }
+
+ bool bAskIfNotEmpty =
+ bAllowDialogs && (nFlags & IDF_CONTENTS) &&
+ nFunction == PASTE_NOFUNC && SC_MOD()->GetInputOptions().GetReplaceCellsWarn();
+
+ if (bAskIfNotEmpty)
+ {
+ if (!lcl_checkDestRangeForOverwrite(aMarkedRange, pDoc, aMark, rViewData.GetDialogParent()))
+ return false;
+ }
+
+ aMark.SetMarkArea(aMarkedRange);
+ MarkRange(aMarkedRange);
+
+ bool bInsertCells = (eMoveMode != INS_NONE);
+ if (bInsertCells)
+ {
+ if (!InsertCells(eMoveMode, pDoc->IsUndoEnabled(), true))
+ return false;
+ }
+
+ ::std::auto_ptr<ScDocument> pUndoDoc;
+ if (pDoc->IsUndoEnabled())
+ {
+ pUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
+ pUndoDoc->InitUndoSelected(pDoc, aMark, false, false);
+ pDoc->CopyToDocument(aMarkedRange, nUndoFlags, false, pUndoDoc.get(), &aMark, true);
+ }
+
+ ::std::auto_ptr<ScDocument> pMixDoc;
+ if ( bSkipEmpty || nFunction )
+ {
+ if ( nFlags & IDF_CONTENTS )
+ {
+ pMixDoc.reset(new ScDocument(SCDOCMODE_UNDO));
+ pMixDoc->InitUndoSelected(pDoc, aMark, false, false);
+ pDoc->CopyToDocument(aMarkedRange, IDF_CONTENTS, false, pMixDoc.get(), &aMark, true);
+ }
+ }
+
+ /* Make draw layer and start drawing undo.
+ - Needed before AdjustBlockHeight to track moved drawing objects.
+ - Needed before pDoc->CopyFromClip to track inserted note caption objects.
+ */
+ if (nFlags & IDF_OBJECTS)
+ pDocSh->MakeDrawLayer();
+ if (pDoc->IsUndoEnabled())
+ pDoc->BeginDrawUndo();
+
+ CursorSwitcher aCursorSwitch(this);
+ sal_uInt16 nNoObjFlags = nFlags & ~IDF_OBJECTS;
+ pDoc->CopyMultiRangeFromClip(rCurPos, aMark, nNoObjFlags, pClipDoc,
+ true, bAsLink, false, bSkipEmpty);
+
+ if (pMixDoc.get())
+ pDoc->MixDocument(aMarkedRange, nFunction, bSkipEmpty, pMixDoc.get());
+
+ AdjustBlockHeight(); // update row heights before pasting objects
+
+ if (nFlags & IDF_OBJECTS)
+ {
+ // Paste the drawing objects after the row heights have been updated.
+ pDoc->CopyMultiRangeFromClip(rCurPos, aMark, IDF_OBJECTS, pClipDoc,
+ true, false, false, true);
+ }
+
+ pDocSh->PostPaint(
+ aMarkedRange.aStart.Col(), aMarkedRange.aStart.Row(), nTab1,
+ aMarkedRange.aEnd.Col(), aMarkedRange.aEnd.Row(), nTab1, PAINT_GRID);
+
+ if (pDoc->IsUndoEnabled())
+ {
+ ::svl::IUndoManager* pUndoMgr = pDocSh->GetUndoManager();
+ String aUndo = ScGlobal::GetRscString(
+ pClipDoc->IsCutMode() ? STR_UNDO_CUT : STR_UNDO_COPY);
+ pUndoMgr->EnterListAction(aUndo, aUndo);
+
+ ScUndoPasteOptions aOptions; // store options for repeat
+ aOptions.nFunction = nFunction;
+ aOptions.bSkipEmpty = bSkipEmpty;
+ aOptions.bTranspose = bTranspose;
+ aOptions.bAsLink = bAsLink;
+ aOptions.eMoveMode = eMoveMode;
+
+ ScUndoPaste* pUndo = new ScUndoPaste(pDocSh,
+ aMarkedRange.aStart.Col(),
+ aMarkedRange.aStart.Row(),
+ aMarkedRange.aStart.Tab(),
+ aMarkedRange.aEnd.Col(),
+ aMarkedRange.aEnd.Row(),
+ aMarkedRange.aEnd.Tab(),
+ aMark, pUndoDoc.release(), NULL, nFlags|nUndoFlags, NULL, NULL, NULL, NULL, false, &aOptions);
+
+ if (bInsertCells)
+ pUndoMgr->AddUndoAction(new ScUndoWrapper(pUndo), true);
+ else
+ pUndoMgr->AddUndoAction(pUndo, false);
+
+ pUndoMgr->LeaveListAction();
+ }
+ aModificator.SetDocumentModified();
+ PostPasteFromClip(aMarkedRange, aMark);
+ return true;
+}
+
+void ScViewFunc::PostPasteFromClip(const ScRange& rPasteRange, const ScMarkData& rMark)
+{
+ ScViewData* pViewData = GetViewData();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pDoc = pViewData->GetDocument();
+ pDocSh->UpdateOle(pViewData);
+
+ SelectionChanged();
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for ( SCTAB i = 0; i < nTabCount; ++i )
+ {
+ if ( rMark.GetTableSelect( i ) )
+ {
+ ScRange aChangeRange(rPasteRange);
+ aChangeRange.aStart.SetTab( i );
+ aChangeRange.aEnd.SetTab( i );
+ aChangeRanges.Append( aChangeRange );
+ }
+ }
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// D R A G A N D D R O P
+//
+// innerhalb des Dokuments
+
+sal_Bool ScViewFunc::MoveBlockTo( const ScRange& rSource, const ScAddress& rDestPos,
+ sal_Bool bCut, sal_Bool bRecord, sal_Bool bPaint, sal_Bool bApi )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ HideAllCursors(); // wegen zusammengefassten
+
+ sal_Bool bSuccess = sal_True;
+ SCTAB nDestTab = rDestPos.Tab();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( rSource.aStart.Tab() == nDestTab && rSource.aEnd.Tab() == nDestTab && rMark.GetSelectCount() > 1 )
+ {
+ // moving within one table and several tables selected -> apply to all selected tables
+
+ if ( bRecord )
+ {
+ String aUndo = ScGlobal::GetRscString( bCut ? STR_UNDO_MOVE : STR_UNDO_COPY );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+ }
+
+ // collect ranges of consecutive selected tables
+
+ ScRange aLocalSource = rSource;
+ ScAddress aLocalDest = rDestPos;
+ SCTAB nTabCount = pDocSh->GetDocument()->GetTableCount();
+ SCTAB nStartTab = 0;
+ while ( nStartTab < nTabCount && bSuccess )
+ {
+ while ( nStartTab < nTabCount && !rMark.GetTableSelect(nStartTab) )
+ ++nStartTab;
+ if ( nStartTab < nTabCount )
+ {
+ SCTAB nEndTab = nStartTab;
+ while ( nEndTab+1 < nTabCount && rMark.GetTableSelect(nEndTab+1) )
+ ++nEndTab;
+
+ aLocalSource.aStart.SetTab( nStartTab );
+ aLocalSource.aEnd.SetTab( nEndTab );
+ aLocalDest.SetTab( nStartTab );
+
+ bSuccess = pDocSh->GetDocFunc().MoveBlock(
+ aLocalSource, aLocalDest, bCut, bRecord, bPaint, bApi );
+
+ nStartTab = nEndTab + 1;
+ }
+ }
+
+ if ( bRecord )
+ pDocSh->GetUndoManager()->LeaveListAction();
+ }
+ else
+ {
+ // move the block as specified
+ bSuccess = pDocSh->GetDocFunc().MoveBlock(
+ rSource, rDestPos, bCut, bRecord, bPaint, bApi );
+ }
+
+ ShowAllCursors();
+ if (bSuccess)
+ {
+ // Zielbereich markieren
+ ScAddress aDestEnd(
+ rDestPos.Col() + rSource.aEnd.Col() - rSource.aStart.Col(),
+ rDestPos.Row() + rSource.aEnd.Row() - rSource.aStart.Row(),
+ nDestTab );
+
+ sal_Bool bIncludeFiltered = bCut;
+ if ( !bIncludeFiltered )
+ {
+ // 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 );
+ }
+
+ MarkRange( ScRange( rDestPos, aDestEnd ), sal_False ); //! sal_False ???
+
+ pDocSh->UpdateOle(GetViewData());
+ SelectionChanged();
+ }
+ return bSuccess;
+}
+
+// Link innerhalb des Dokuments
+
+sal_Bool ScViewFunc::LinkBlock( const ScRange& rSource, const ScAddress& rDestPos, sal_Bool bApi )
+{
+ // Test auf Ueberlappung
+
+ if ( rSource.aStart.Tab() == rDestPos.Tab() )
+ {
+ SCCOL nDestEndCol = rDestPos.Col() + ( rSource.aEnd.Col() - rSource.aStart.Col() );
+ SCROW nDestEndRow = rDestPos.Row() + ( rSource.aEnd.Row() - rSource.aStart.Row() );
+
+ if ( rSource.aStart.Col() <= nDestEndCol && rDestPos.Col() <= rSource.aEnd.Col() &&
+ rSource.aStart.Row() <= nDestEndRow && rDestPos.Row() <= rSource.aEnd.Row() )
+ {
+ if (!bApi)
+ ErrorMessage( STR_ERR_LINKOVERLAP );
+ return sal_False;
+ }
+ }
+
+ // Ausfuehren per Paste
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
+ pDoc->CopyTabToClip( rSource.aStart.Col(), rSource.aStart.Row(),
+ rSource.aEnd.Col(), rSource.aEnd.Row(),
+ rSource.aStart.Tab(), pClipDoc );
+
+ // Zielbereich markieren (Cursor setzen, keine Markierung)
+
+ if ( GetViewData()->GetTabNo() != rDestPos.Tab() )
+ SetTabNo( rDestPos.Tab() );
+
+ MoveCursorAbs( rDestPos.Col(), rDestPos.Row(), SC_FOLLOW_NONE, sal_False, sal_False );
+
+ // Paste
+
+ PasteFromClip( IDF_ALL, pClipDoc, PASTE_NOFUNC, sal_False, sal_False, sal_True ); // als Link
+
+ delete pClipDoc;
+
+ return sal_True;
+}
+
+
+
+
diff --git a/sc/source/ui/view/viewfun4.cxx b/sc/source/ui/view/viewfun4.cxx
new file mode 100644
index 000000000000..c3f58e7d9b74
--- /dev/null
+++ b/sc/source/ui/view/viewfun4.cxx
@@ -0,0 +1,848 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <editeng/editobj.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/hlnkitem.hxx>
+#include <editeng/langitem.hxx>
+#include <svx/svxerr.hxx>
+#include <editeng/unolingu.hxx>
+
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <svtools/langtab.hxx>
+#include <svtools/filter.hxx>
+#include <svl/stritem.hxx>
+#include <svtools/transfer.hxx>
+#include <svl/urlbmk.hxx>
+#include <vcl/msgbox.hxx>
+#include <avmedia/mediawindow.hxx>
+
+#include <comphelper/storagehelper.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include "viewfunc.hxx"
+#include "docsh.hxx"
+#include "docsh.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "undoblk.hxx"
+#include "undocell.hxx"
+#include "cell.hxx"
+#include "scmod.hxx"
+#include "spelleng.hxx"
+#include "patattr.hxx"
+#include "sc.hrc"
+#include "tabvwsh.hxx"
+#include "impex.hxx"
+#include "editutil.hxx"
+#include "editable.hxx"
+#include "dociter.hxx"
+#include "reffind.hxx"
+#include "compiler.hxx"
+
+using namespace com::sun::star;
+
+// STATIC DATA -----------------------------------------------------------
+
+sal_Bool bPasteIsDrop = sal_False;
+
+//==================================================================
+
+void ScViewFunc::PasteRTF( SCCOL nStartCol, SCROW nStartRow,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::datatransfer::XTransferable >& rxTransferable )
+{
+ TransferableDataHelper aDataHelper( rxTransferable );
+ if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EDITENGINE ) )
+ {
+ HideAllCursors();
+
+ ScDocument* pUndoDoc = NULL;
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ const sal_Bool bRecord (pDoc->IsUndoEnabled());
+
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nStartCol, nStartRow, nTab );
+ ScTabEditEngine* pEngine = new ScTabEditEngine( *pPattern, pDoc->GetEnginePool() );
+ pEngine->EnableUndo( sal_False );
+
+ Window* pActWin = GetActiveWin();
+ if (pActWin)
+ {
+ pEngine->SetPaperSize(Size(100000,100000));
+ Window aWin( pActWin );
+ EditView aEditView( pEngine, &aWin );
+ aEditView.SetOutputArea(Rectangle(0,0,100000,100000));
+
+ // same method now for clipboard or drag&drop
+ // mba: clipboard always must contain absolute URLs (could be from alien source)
+ aEditView.InsertText( rxTransferable, String(), sal_True );
+ }
+
+ sal_uLong nParCnt = pEngine->GetParagraphCount();
+ if (nParCnt)
+ {
+ SCROW nEndRow = nStartRow + static_cast<SCROW>(nParCnt) - 1;
+ if (nEndRow > MAXROW)
+ nEndRow = MAXROW;
+
+ if (bRecord)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+ pDoc->CopyToDocument( nStartCol,nStartRow,nTab, nStartCol,nEndRow,nTab, IDF_ALL, sal_False, pUndoDoc );
+ }
+
+ SCROW nRow = nStartRow;
+ for( sal_uInt16 n = 0; n < nParCnt; n++ )
+ {
+ EditTextObject* pObject = pEngine->CreateTextObject( n );
+ EnterData( nStartCol, nRow, nTab, pObject, sal_False, sal_True );
+ // kein Undo, auf einfache Strings testen
+ delete pObject;
+ if( ++nRow > MAXROW )
+ break;
+ }
+
+ if (bRecord)
+ {
+ ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pRedoDoc->InitUndo( pDoc, nTab, nTab );
+ pDoc->CopyToDocument( nStartCol,nStartRow,nTab, nStartCol,nEndRow,nTab, IDF_ALL|IDF_NOCAPTIONS, sal_False, pRedoDoc );
+
+ ScMarkData aDestMark;
+ aDestMark.SelectOneTable( nTab );
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoPaste( pDocSh, nStartCol,nStartRow,nTab, nStartCol,nEndRow,nTab,
+ aDestMark,
+ pUndoDoc, pRedoDoc, IDF_ALL, NULL,NULL,NULL,NULL ) );
+ }
+ }
+
+ delete pEngine;
+
+ ShowAllCursors();
+ }
+ else
+ {
+ HideAllCursors();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScImportExport aImpEx( pDocSh->GetDocument(),
+ ScAddress( nStartCol, nStartRow, GetViewData()->GetTabNo() ) );
+
+ ::rtl::OUString aStr;
+ SotStorageStreamRef xStream;
+ if ( aDataHelper.GetSotStorageStream( SOT_FORMAT_RTF, xStream ) && xStream.Is() )
+ // mba: clipboard always must contain absolute URLs (could be from alien source)
+ aImpEx.ImportStream( *xStream, String(), SOT_FORMAT_RTF );
+ else if ( aDataHelper.GetString( SOT_FORMAT_RTF, aStr ) )
+ aImpEx.ImportString( aStr, SOT_FORMAT_RTF );
+
+ AdjustRowHeight( nStartRow, aImpEx.GetRange().aEnd.Row() );
+ pDocSh->UpdateOle(GetViewData());
+ ShowAllCursors();
+ }
+}
+void ScViewFunc::DoRefConversion( sal_Bool bRecord )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = sal_False;
+
+ ScRange aMarkRange;
+ rMark.MarkToSimple();
+ sal_Bool bMulti = rMark.IsMultiMarked();
+ if (bMulti)
+ rMark.GetMultiMarkArea( aMarkRange );
+ else if (rMark.IsMarked())
+ rMark.GetMarkArea( aMarkRange );
+ else
+ {
+ aMarkRange = ScRange( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ }
+ ScEditableTester aTester( pDoc, aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
+ aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(),rMark );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ return;
+ }
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ sal_Bool bOk = sal_False;
+
+ ScDocument* pUndoDoc = NULL;
+ if (bRecord)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ SCTAB nTab = aMarkRange.aStart.Tab();
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+
+ if ( rMark.GetSelectCount() > 1 )
+ {
+ for (SCTAB i=0; i<nTabCount; i++)
+ if ( rMark.GetTableSelect(i) && i != nTab )
+ pUndoDoc->AddUndoTab( i, i );
+ }
+ ScRange aCopyRange = aMarkRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pDoc->CopyToDocument( aCopyRange, IDF_ALL, bMulti, pUndoDoc, &rMark );
+ }
+
+ ScRangeListRef xRanges;
+ GetViewData()->GetMultiArea( xRanges );
+ sal_uLong nCount = xRanges->Count();
+
+ for (SCTAB i=0; i<nTabCount; i++)
+ {
+ if (rMark.GetTableSelect(i))
+ {
+ for (sal_uLong j=0; j<nCount; j++)
+ {
+ ScRange aRange = *xRanges->GetObject(j);
+ aRange.aStart.SetTab(i);
+ aRange.aEnd.SetTab(i);
+ ScCellIterator aIter( pDoc, aRange );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while ( pCell )
+ {
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ {
+ String aOld;
+ ((ScFormulaCell*)pCell)->GetFormula(aOld);
+ xub_StrLen nLen = aOld.Len();
+ ScRefFinder aFinder( aOld, pDoc );
+ aFinder.ToggleRel( 0, nLen );
+ if (aFinder.GetFound())
+ {
+ ScAddress aPos = ((ScFormulaCell*)pCell)->aPos;
+ String aNew = aFinder.GetText();
+ ScCompiler aComp( pDoc, aPos);
+ aComp.SetGrammar(pDoc->GetGrammar());
+ ScTokenArray* pArr = aComp.CompileString( aNew );
+ ScFormulaCell* pNewCell = new ScFormulaCell( pDoc, aPos,
+ pArr,formula::FormulaGrammar::GRAM_DEFAULT, MM_NONE );
+ pDoc->PutCell( aPos, pNewCell );
+ bOk = sal_True;
+ }
+ }
+ pCell = aIter.GetNext();
+ }
+ }
+ }
+ }
+ if (bRecord)
+ {
+ ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
+ SCTAB nTab = aMarkRange.aStart.Tab();
+ pRedoDoc->InitUndo( pDoc, nTab, nTab );
+
+ if ( rMark.GetSelectCount() > 1 )
+ {
+ for (SCTAB i=0; i<nTabCount; i++)
+ if ( rMark.GetTableSelect(i) && i != nTab )
+ pRedoDoc->AddUndoTab( i, i );
+ }
+ ScRange aCopyRange = aMarkRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pDoc->CopyToDocument( aCopyRange, IDF_ALL, bMulti, pRedoDoc, &rMark );
+
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoRefConversion( pDocSh,
+ aMarkRange, rMark, pUndoDoc, pRedoDoc, bMulti, IDF_ALL) );
+ }
+
+ pDocSh->PostPaint( aMarkRange, PAINT_GRID );
+ pDocSh->UpdateOle(GetViewData());
+ pDocSh->SetDocumentModified();
+ CellContentChanged();
+
+ if (!bOk)
+ ErrorMessage(STR_ERR_NOREF);
+}
+// Thesaurus - Undo ok
+void ScViewFunc::DoThesaurus( sal_Bool bRecord )
+{
+ SCCOL nCol;
+ SCROW nRow;
+ SCTAB nTab;
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ ScSplitPos eWhich = GetViewData()->GetActivePart();
+ CellType eCellType;
+ EESpellState eState;
+ String sOldText, sNewString;
+ EditTextObject* pOldTObj = NULL;
+ const EditTextObject* pTObject = NULL;
+ ScBaseCell* pCell = NULL;
+ EditView* pEditView = NULL;
+ ESelection* pEditSel = NULL;
+ ScEditEngineDefaulter* pThesaurusEngine;
+ sal_Bool bIsEditMode = GetViewData()->HasEditView(eWhich);
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = sal_False;
+ if (bIsEditMode) // Edit-Mode aktiv
+ {
+ GetViewData()->GetEditView(eWhich, pEditView, nCol, nRow);
+ pEditSel = new ESelection(pEditView->GetSelection());
+ SC_MOD()->InputEnterHandler();
+ GetViewData()->GetBindings().Update(); // sonst kommt der Sfx durcheinander...
+ }
+ else
+ {
+ nCol = GetViewData()->GetCurX();
+ nRow = GetViewData()->GetCurY();
+ }
+ nTab = GetViewData()->GetTabNo();
+
+ ScEditableTester aTester( pDoc, nCol, nRow, nCol, nRow, rMark );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ delete pEditSel;
+ return;
+ }
+ pDoc->GetCellType(nCol, nRow, nTab, eCellType);
+ if (eCellType != CELLTYPE_STRING && eCellType != CELLTYPE_EDIT)
+ {
+ ErrorMessage(STR_THESAURUS_NO_STRING);
+ return;
+ }
+
+ com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellChecker1>
+ xSpeller = LinguMgr::GetSpellChecker();
+ //! if (...) // thesaurus not available
+ //! {
+ //! ErrorMessage(STR_EXPORT_ASCII_WARNING);
+ //! delete pEditSel;
+ //! return;
+ //! }
+
+ pThesaurusEngine = new ScEditEngineDefaulter( pDoc->GetEnginePool() );
+ pThesaurusEngine->SetEditTextObjectPool( pDoc->GetEditPool() );
+ pThesaurusEngine->SetRefDevice(GetViewData()->GetActiveWin());
+ pThesaurusEngine->SetSpeller(xSpeller);
+ MakeEditView(pThesaurusEngine, nCol, nRow );
+ const ScPatternAttr* pPattern = NULL;
+ SfxItemSet* pEditDefaults = new SfxItemSet(pThesaurusEngine->GetEmptyItemSet());
+ pPattern = pDoc->GetPattern(nCol, nRow, nTab);
+ if (pPattern )
+ {
+ pPattern->FillEditItemSet( pEditDefaults );
+ pThesaurusEngine->SetDefaults( *pEditDefaults );
+ }
+
+ if (eCellType == CELLTYPE_STRING)
+ {
+ pDoc->GetString(nCol, nRow, nTab, sOldText);
+ pThesaurusEngine->SetText(sOldText);
+ }
+ else if (eCellType == CELLTYPE_EDIT)
+ {
+ pDoc->GetCell(nCol, nRow, nTab, pCell);
+ if (pCell)
+ {
+ ((ScEditCell*) pCell)->GetData(pTObject);
+ if (pTObject)
+ {
+ pOldTObj = pTObject->Clone();
+ pThesaurusEngine->SetText(*pTObject);
+ }
+ }
+ }
+ else
+ {
+ DBG_ERROR("DoThesaurus: Keine String oder Editzelle");
+ }
+ pEditView = GetViewData()->GetEditView(GetViewData()->GetActivePart());;
+ if (pEditSel)
+ pEditView->SetSelection(*pEditSel);
+ else
+ pEditView->SetSelection(ESelection(0,0,0,0));
+
+ pThesaurusEngine->ClearModifyFlag();
+
+ // language is now in EditEngine attributes -> no longer passed to StartThesaurus
+
+ eState = pEditView->StartThesaurus();
+ DBG_ASSERT(eState != EE_SPELL_NOSPELLER, "No SpellChecker");
+
+ if (eState == EE_SPELL_ERRORFOUND) // sollte spaeter durch Wrapper geschehen!
+ {
+ LanguageType eLnge = ScViewUtil::GetEffLanguage( pDoc, ScAddress( nCol, nRow, nTab ) );
+ SvtLanguageTable aLangTab;
+ String aErr = aLangTab.GetString(eLnge);
+ aErr += ScGlobal::GetRscString( STR_SPELLING_NO_LANG );
+ InfoBox aBox( GetViewData()->GetDialogParent(), aErr );
+ aBox.Execute();
+ }
+ if (pThesaurusEngine->IsModified())
+ {
+ EditTextObject* pNewTObj = NULL;
+ if (pCell && pTObject)
+ {
+ pNewTObj = pThesaurusEngine->CreateTextObject();
+ pCell = new ScEditCell( pNewTObj, pDoc,
+ pThesaurusEngine->GetEditTextObjectPool() );
+ pDoc->PutCell( nCol, nRow, nTab, pCell );
+ }
+ else
+ {
+ sNewString = pThesaurusEngine->GetText();
+ pDoc->SetString(nCol, nRow, nTab, sNewString);
+ }
+// erack! it's broadcasted
+// pDoc->SetDirty();
+ pDocSh->SetDocumentModified();
+ if (bRecord)
+ {
+ GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
+ new ScUndoThesaurus( GetViewData()->GetDocShell(),
+ nCol, nRow, nTab,
+ sOldText, pOldTObj, sNewString, pNewTObj));
+ }
+ delete pNewTObj;
+ }
+ KillEditView(sal_True);
+ delete pEditDefaults;
+ delete pThesaurusEngine;
+ delete pOldTObj;
+ delete pEditSel;
+ pDocSh->PostPaintGridAll();
+}
+
+//UNUSED2008-05 // Spelling Checker - Undo ok
+//UNUSED2008-05 void ScViewFunc::DoSpellingChecker( sal_Bool bRecord )
+//UNUSED2008-05 {
+//UNUSED2008-05 DoSheetConversion( ScConversionParam( SC_CONVERSION_SPELLCHECK ), bRecord );
+//UNUSED2008-05 }
+
+void ScViewFunc::DoHangulHanjaConversion( sal_Bool bRecord )
+{
+ ScConversionParam aConvParam( SC_CONVERSION_HANGULHANJA, LANGUAGE_KOREAN, 0, true );
+ DoSheetConversion( aConvParam, bRecord );
+}
+
+void ScViewFunc::DoSheetConversion( const ScConversionParam& rConvParam, sal_Bool bRecord )
+{
+ SCCOL nCol;
+ SCROW nRow;
+ SCTAB nTab;
+ ScViewData& rViewData = *GetViewData();
+ ScDocShell* pDocSh = rViewData.GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = rViewData.GetMarkData();
+ ScSplitPos eWhich = rViewData.GetActivePart();
+ EditView* pEditView = NULL;
+ ESelection* pEditSel = NULL;
+ sal_Bool bIsEditMode = rViewData.HasEditView(eWhich);
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = sal_False;
+ if (bIsEditMode) // Edit-Mode aktiv
+ {
+ rViewData.GetEditView(eWhich, pEditView, nCol, nRow);
+ pEditSel = new ESelection(pEditView->GetSelection());
+ SC_MOD()->InputEnterHandler();
+ }
+ else
+ {
+ nCol = rViewData.GetCurX();
+ nRow = rViewData.GetCurY();
+
+ AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP);
+ }
+ nTab = rViewData.GetTabNo();
+
+ rMark.MarkToMulti();
+ sal_Bool bMarked = rMark.IsMultiMarked();
+ if (bMarked)
+ {
+ ScEditableTester aTester( pDoc, rMark );
+ if (!aTester.IsEditable())
+ {
+ ErrorMessage(aTester.GetMessageId());
+ delete pEditSel;
+ return;
+ }
+ }
+
+ ScDocument* pUndoDoc = NULL;
+ ScDocument* pRedoDoc = NULL;
+ if (bRecord)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+ pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pRedoDoc->InitUndo( pDoc, nTab, nTab );
+
+ if ( rMark.GetSelectCount() > 1 )
+ {
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ if ( rMark.GetTableSelect(i) && i != nTab )
+ {
+ pUndoDoc->AddUndoTab( i, i );
+ pRedoDoc->AddUndoTab( i, i );
+ }
+ }
+ }
+
+ // ab hier kein return mehr
+
+ sal_Bool bOldDis = pDoc->IsIdleDisabled();
+ pDoc->DisableIdle( sal_True ); // #42726# stop online spelling
+
+ // *** create and init the edit engine *** --------------------------------
+
+ ScConversionEngineBase* pEngine = NULL;
+ switch( rConvParam.GetType() )
+ {
+ case SC_CONVERSION_SPELLCHECK:
+ pEngine = new ScSpellingEngine(
+ pDoc->GetEnginePool(), rViewData, pUndoDoc, pRedoDoc, LinguMgr::GetSpellChecker() );
+ break;
+ case SC_CONVERSION_HANGULHANJA:
+ case SC_CONVERSION_CHINESE_TRANSL:
+ pEngine = new ScTextConversionEngine(
+ pDoc->GetEnginePool(), rViewData, rConvParam, pUndoDoc, pRedoDoc );
+ break;
+ default:
+ DBG_ERRORFILE( "ScViewFunc::DoSheetConversion - unknown conversion type" );
+ }
+
+ MakeEditView( pEngine, nCol, nRow );
+ pEngine->SetRefDevice( rViewData.GetActiveWin() );
+ // dummy Zelle simulieren:
+ pEditView = rViewData.GetEditView( rViewData.GetActivePart() );
+ rViewData.SetSpellingView( pEditView );
+ Rectangle aRect( Point( 0, 0 ), Point( 0, 0 ) );
+ pEditView->SetOutputArea( aRect );
+ pEngine->SetControlWord( EE_CNTRL_USECHARATTRIBS );
+ pEngine->EnableUndo( sal_False );
+ pEngine->SetPaperSize( aRect.GetSize() );
+ pEngine->SetText( EMPTY_STRING );
+
+ // *** do the conversion *** ----------------------------------------------
+
+ pEngine->ClearModifyFlag();
+ pEngine->ConvertAll( *pEditView );
+
+ // *** undo/redo *** ------------------------------------------------------
+
+ if( pEngine->IsAnyModified() )
+ {
+ if (bRecord)
+ {
+ SCCOL nNewCol = rViewData.GetCurX();
+ SCROW nNewRow = rViewData.GetCurY();
+ rViewData.GetDocShell()->GetUndoManager()->AddUndoAction(
+ new ScUndoConversion(
+ pDocSh, rMark,
+ nCol, nRow, nTab, pUndoDoc,
+ nNewCol, nNewRow, nTab, pRedoDoc, rConvParam ) );
+ }
+ pDoc->SetDirty();
+ pDocSh->SetDocumentModified();
+ }
+ else
+ {
+ delete pUndoDoc;
+ delete pRedoDoc;
+ }
+
+ // *** final cleanup *** --------------------------------------------------
+
+ rViewData.SetSpellingView( NULL );
+ KillEditView(sal_True);
+ delete pEngine;
+ delete pEditSel;
+ pDocSh->PostPaintGridAll();
+ rViewData.GetViewShell()->UpdateInputHandler();
+ pDoc->DisableIdle(bOldDis);
+}
+
+
+//UNUSED2008-05 IMPL_LINK_INLINE_START( ScViewFunc, SpellError, void *, nLang )
+//UNUSED2008-05 {
+//UNUSED2008-05 SvtLanguageTable aLangTab;
+//UNUSED2008-05 String aErr = aLangTab.GetString((LanguageType) (sal_uLong) nLang);
+//UNUSED2008-05 ErrorHandler::HandleError(*new StringErrorInfo(
+//UNUSED2008-05 ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aErr) );
+//UNUSED2008-05
+//UNUSED2008-05 return 0;
+//UNUSED2008-05 }
+//UNUSED2008-05 IMPL_LINK_INLINE_END( ScViewFunc, SpellError, void *, nLang )
+
+// Pasten von FORMAT_FILE-Items
+// wird nicht direkt aus Drop aufgerufen, sondern asynchron -> Dialoge sind erlaubt
+
+sal_Bool ScViewFunc::PasteFile( const Point& rPos, const String& rFile, sal_Bool bLink )
+{
+ INetURLObject aURL;
+ aURL.SetSmartURL( rFile );
+ String aStrURL = aURL.GetMainURL( INetURLObject::NO_DECODE );
+
+ // is it a media URL?
+ if( ::avmedia::MediaWindow::isMediaURL( aStrURL ) )
+ {
+ const SfxStringItem aMediaURLItem( SID_INSERT_AVMEDIA, aStrURL );
+ return sal_Bool( 0 != GetViewData()->GetDispatcher().Execute(
+ SID_INSERT_AVMEDIA, SFX_CALLMODE_SYNCHRON,
+ &aMediaURLItem, 0L ) );
+ }
+
+ if (!bLink) // bei bLink nur Grafik oder URL
+ {
+ // 1. Kann ich die Datei oeffnen?
+ const SfxFilter* pFlt = NULL;
+
+ // nur nach eigenen Filtern suchen, ohne Auswahlbox (wie in ScDocumentLoader)
+ SfxFilterMatcher aMatcher( ScDocShell::Factory().GetFilterContainer()->GetName() );
+ SfxMedium aSfxMedium( aStrURL, (STREAM_READ | STREAM_SHARE_DENYNONE), sal_False );
+ // #i73992# GuessFilter no longer calls UseInteractionHandler.
+ // This is UI, so it can be called here.
+ aSfxMedium.UseInteractionHandler(sal_True);
+ ErrCode nErr = aMatcher.GuessFilter( aSfxMedium, &pFlt );
+
+ if ( pFlt && !nErr )
+ {
+ // Code aus dem SFX geklaut!
+ SfxDispatcher &rDispatcher = GetViewData()->GetDispatcher();
+ SfxStringItem aFileNameItem( SID_FILE_NAME, aStrURL );
+ SfxStringItem aFilterItem( SID_FILTER_NAME, pFlt->GetName() );
+ // #i69524# add target, as in SfxApplication when the Open dialog is used
+ SfxStringItem aTargetItem( SID_TARGETNAME, String::CreateFromAscii("_default") );
+
+ // Asynchron oeffnen, kann naemlich auch aus D&D heraus passieren
+ // und das bekommt dem MAC nicht so gut ...
+ return sal_Bool( 0 != rDispatcher.Execute( SID_OPENDOC,
+ SFX_CALLMODE_ASYNCHRON, &aFileNameItem, &aFilterItem, &aTargetItem, 0L) );
+ }
+ }
+
+ // 2. Kann die Datei ueber die Grafik-Filter eingefuegt werden?
+ // (als Link, weil Gallery das so anbietet)
+
+ sal_uInt16 nFilterFormat;
+ Graphic aGraphic;
+ GraphicFilter* pGraphicFilter = GraphicFilter::GetGraphicFilter();
+
+// GraphicProgress aGraphicProgress(&aGraphicFilter);
+
+ if (!pGraphicFilter->ImportGraphic(aGraphic, aURL,
+ GRFILTER_FORMAT_DONTKNOW, &nFilterFormat ))
+ {
+ if ( bLink )
+ {
+ String aFltName = pGraphicFilter->GetImportFormatName(nFilterFormat);
+ return PasteGraphic( rPos, aGraphic, aStrURL, aFltName );
+ }
+ else
+ {
+ // #i76709# if bLink isn't set, pass empty URL/filter, so a non-linked image is inserted
+ return PasteGraphic( rPos, aGraphic, EMPTY_STRING, EMPTY_STRING );
+ }
+ }
+
+ if (bLink) // bei bLink alles, was nicht Grafik ist, als URL
+ {
+ Rectangle aRect( rPos, Size(0,0) );
+ ScRange aRange = GetViewData()->GetDocument()->
+ GetRange( GetViewData()->GetTabNo(), aRect );
+ SCCOL nPosX = aRange.aStart.Col();
+ SCROW nPosY = aRange.aStart.Row();
+
+ InsertBookmark( aStrURL, aStrURL, nPosX, nPosY );
+ return sal_True;
+ }
+ else
+ {
+ // 3. Kann die Datei als OLE eingefuegt werden?
+ // auch nicht-Storages, z.B. Sounds (#38282#)
+ uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
+
+ //TODO/LATER: what about "bLink"?
+
+ uno::Sequence < beans::PropertyValue > aMedium(1);
+ aMedium[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
+ aMedium[0].Value <<= ::rtl::OUString( aStrURL );
+
+ comphelper::EmbeddedObjectContainer aCnt( xStorage );
+ ::rtl::OUString aName;
+ uno::Reference < embed::XEmbeddedObject > xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
+ if( xObj.is() )
+ return PasteObject( rPos, xObj );
+
+ // #105851# If an OLE object can't be created, insert a URL button
+
+ GetViewData()->GetViewShell()->InsertURLButton( aStrURL, aStrURL, EMPTY_STRING, &rPos );
+ return sal_True;
+ }
+}
+
+sal_Bool ScViewFunc::PasteBookmark( sal_uLong nFormatId,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::datatransfer::XTransferable >& rxTransferable,
+ SCCOL nPosX, SCROW nPosY )
+{
+ INetBookmark aBookmark;
+ TransferableDataHelper aDataHelper( rxTransferable );
+ if ( !aDataHelper.GetINetBookmark( nFormatId, aBookmark ) )
+ return sal_False;
+
+ InsertBookmark( aBookmark.GetDescription(), aBookmark.GetURL(), nPosX, nPosY );
+ return sal_True;
+}
+
+void ScViewFunc::InsertBookmark( const String& rDescription, const String& rURL,
+ SCCOL nPosX, SCROW nPosY, const String* pTarget,
+ sal_Bool bTryReplace )
+{
+ ScViewData* pViewData = GetViewData();
+ if ( pViewData->HasEditView( pViewData->GetActivePart() ) &&
+ nPosX >= pViewData->GetEditStartCol() && nPosX <= pViewData->GetEditEndCol() &&
+ nPosY >= pViewData->GetEditStartRow() && nPosY <= pViewData->GetEditEndRow() )
+ {
+ // in die gerade editierte Zelle einfuegen
+
+ String aTargetFrame;
+ if (pTarget)
+ aTargetFrame = *pTarget;
+ pViewData->GetViewShell()->InsertURLField( rDescription, rURL, aTargetFrame );
+ return;
+ }
+
+ // in nicht editierte Zelle einfuegen
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScAddress aCellPos( nPosX, nPosY, nTab );
+ ScBaseCell* pCell = pDoc->GetCell( aCellPos );
+ EditEngine aEngine( pDoc->GetEnginePool() );
+ if (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_EDIT)
+ {
+ const EditTextObject* pOld = ((ScEditCell*)pCell)->GetData();
+ if (pOld)
+ aEngine.SetText(*pOld);
+ }
+ else
+ {
+ String aOld;
+ pDoc->GetInputString( nPosX, nPosY, nTab, aOld );
+ if (aOld.Len())
+ aEngine.SetText(aOld);
+ }
+ }
+
+ sal_uInt16 nPara = aEngine.GetParagraphCount();
+ if (nPara)
+ --nPara;
+ xub_StrLen nTxtLen = aEngine.GetTextLen(nPara);
+ ESelection aInsSel( nPara, nTxtLen, nPara, nTxtLen );
+
+ if ( bTryReplace && HasBookmarkAtCursor( NULL ) )
+ {
+ // if called from hyperlink slot and cell contains only a URL,
+ // replace old URL with new one
+
+ aInsSel = ESelection( 0, 0, 0, 1 ); // replace first character (field)
+ }
+
+ SvxURLField aField( rURL, rDescription, SVXURLFORMAT_APPDEFAULT );
+ if (pTarget)
+ aField.SetTargetFrame(*pTarget);
+ aEngine.QuickInsertField( SvxFieldItem( aField, EE_FEATURE_FIELD ), aInsSel );
+
+ EditTextObject* pData = aEngine.CreateTextObject();
+ EnterData( nPosX, nPosY, nTab, pData );
+ delete pData;
+}
+
+sal_Bool ScViewFunc::HasBookmarkAtCursor( SvxHyperlinkItem* pContent )
+{
+ ScAddress aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ ScDocument* pDoc = GetViewData()->GetDocShell()->GetDocument();
+
+ ScBaseCell* pCell = pDoc->GetCell( aPos );
+ if ( pCell && pCell->GetCellType() == CELLTYPE_EDIT )
+ {
+ const EditTextObject* pData = ((ScEditCell*)pCell)->GetData();
+ if (pData)
+ {
+ sal_Bool bField = pData->IsFieldObject();
+ if (bField)
+ {
+ const SvxFieldItem* pFieldItem = pData->GetField();
+ if (pFieldItem)
+ {
+ const SvxFieldData* pField = pFieldItem->GetField();
+ if ( pField && pField->ISA(SvxURLField) )
+ {
+ if (pContent)
+ {
+ const SvxURLField* pURLField = (const SvxURLField*)pField;
+ pContent->SetName( pURLField->GetRepresentation() );
+ pContent->SetURL( pURLField->GetURL() );
+ pContent->SetTargetFrame( pURLField->GetTargetFrame() );
+ }
+ return sal_True;
+ }
+ }
+ }
+ }
+ }
+ return sal_False;
+}
+
+
diff --git a/sc/source/ui/view/viewfun5.cxx b/sc/source/ui/view/viewfun5.cxx
new file mode 100644
index 000000000000..205a0532eb3a
--- /dev/null
+++ b/sc/source/ui/view/viewfun5.cxx
@@ -0,0 +1,749 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include <com/sun/star/embed/XEmbedObjectClipboardCreator.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+
+
+#include <svx/unomodel.hxx>
+#include <unotools/streamwrap.hxx>
+
+//------------------------------------------------------------------
+
+#include <svx/dbexch.hrc>
+#include <svx/fmmodel.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdpage.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/docfile.hxx>
+#include <sot/clsids.hxx>
+#include <sot/formats.hxx>
+#include <sot/filelist.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svl/ptitem.hxx>
+#include <svl/stritem.hxx>
+#include <svtools/transfer.hxx>
+#include <vcl/graph.hxx>
+
+#include <comphelper/storagehelper.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <sot/formats.hxx>
+#define SOT_FORMATSTR_ID_STARCALC_CURRENT SOT_FORMATSTR_ID_STARCALC_50
+
+#include "viewfunc.hxx"
+#include "docsh.hxx"
+#include "drawview.hxx"
+#include "impex.hxx"
+#include "dbfunc.hxx"
+#include "dbcolect.hxx"
+#include "sc.hrc"
+#include "filter.hxx"
+#include "scextopt.hxx"
+#include "tabvwsh.hxx" // wegen GetViewFrame
+#include "compiler.hxx"
+
+#include "asciiopt.hxx"
+#include "scabstdlg.hxx"
+#include "clipparam.hxx"
+#include <vcl/msgbox.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svx/dbaexchange.hxx>
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------
+
+sal_Bool ScViewFunc::PasteDataFormat( sal_uLong nFormatId,
+ const uno::Reference<datatransfer::XTransferable>& rxTransferable,
+ SCCOL nPosX, SCROW nPosY, Point* pLogicPos, sal_Bool bLink, sal_Bool bAllowDialogs )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ pDoc->SetPastingDrawFromOtherDoc( sal_True );
+
+ Point aPos; // inserting position (1/100 mm)
+ if (pLogicPos)
+ aPos = *pLogicPos;
+ else
+ {
+ // inserting position isn't needed for text formats
+ sal_Bool bIsTextFormat = ( ScImportExport::IsFormatSupported( nFormatId ) ||
+ nFormatId == FORMAT_RTF );
+ if ( !bIsTextFormat )
+ {
+ // Window MapMode isn't drawing MapMode if DrawingLayer hasn't been created yet
+
+ SCTAB nTab = GetViewData()->GetTabNo();
+ long nXT = 0;
+ for (SCCOL i=0; i<nPosX; i++)
+ nXT += pDoc->GetColWidth(i,nTab);
+ if (pDoc->IsNegativePage(nTab))
+ nXT = -nXT;
+ sal_uLong nYT = pDoc->GetRowHeight( 0, nPosY-1, nTab);
+ aPos = Point( (long)(nXT * HMM_PER_TWIPS), (long)(nYT * HMM_PER_TWIPS) );
+ }
+ }
+
+ TransferableDataHelper aDataHelper( rxTransferable );
+ sal_Bool bRet = sal_False;
+
+ //
+ // handle individual formats
+ //
+
+ if ( nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE ||
+ nFormatId == SOT_FORMATSTR_ID_LINK_SOURCE ||
+ nFormatId == SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ||
+ nFormatId == SOT_FORMATSTR_ID_LINK_SOURCE_OLE ||
+ nFormatId == SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE )
+ {
+ uno::Reference < io::XInputStream > xStm;
+ TransferableObjectDescriptor aObjDesc;
+
+ if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) &&
+ aDataHelper.GetInputStream( nFormatId, xStm ) )
+ {
+ if ( aObjDesc.maClassName == SvGlobalName( SO3_SC_CLASSID_60 ) )
+ {
+ uno::Reference < embed::XStorage > xStore = ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm );
+
+ // mba: BaseURL doesn't make sense for clipboard
+ // #i43716# Medium must be allocated with "new".
+ // DoLoad stores the pointer and deletes it with the SfxObjectShell.
+ SfxMedium* pMedium = new SfxMedium( xStore, String() );
+
+ // TODO/LATER: is it a problem that we don't support binary formats here?
+ ScDocShellRef xDocShRef = new ScDocShell(SFX_CREATE_MODE_EMBEDDED);
+ if (xDocShRef->DoLoad(pMedium))
+ {
+ ScDocument* pSrcDoc = xDocShRef->GetDocument();
+ SCTAB nSrcTab = pSrcDoc->GetVisibleTab();
+ if (!pSrcDoc->HasTable(nSrcTab))
+ nSrcTab = 0;
+
+ ScMarkData aSrcMark;
+ aSrcMark.SelectOneTable( nSrcTab ); // for CopyToClip
+ ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
+
+ SCCOL nFirstCol, nLastCol;
+ SCROW nFirstRow, nLastRow;
+ if ( pSrcDoc->GetDataStart( nSrcTab, nFirstCol, nFirstRow ) )
+ pSrcDoc->GetCellArea( nSrcTab, nLastCol, nLastRow );
+ else
+ {
+ nFirstCol = nLastCol = 0;
+ nFirstRow = nLastRow = 0;
+ }
+ ScClipParam aClipParam(ScRange(nFirstCol, nFirstRow, 0, nLastCol, nLastRow, 0), false);
+ pSrcDoc->CopyToClip(aClipParam, pClipDoc, &aSrcMark);
+ ScGlobal::SetClipDocName( xDocShRef->GetTitle( SFX_TITLE_FULLNAME ) );
+
+ SetCursor( nPosX, nPosY );
+ Unmark();
+ PasteFromClip( IDF_ALL, pClipDoc,
+ PASTE_NOFUNC, sal_False, sal_False, sal_False, INS_NONE, IDF_NONE,
+ bAllowDialogs );
+ delete pClipDoc;
+ bRet = sal_True;
+ }
+
+ xDocShRef->DoClose();
+ xDocShRef.Clear();
+ }
+ else
+ {
+ ::rtl::OUString aName;
+ uno::Reference < embed::XEmbeddedObject > xObj = GetViewData()->GetViewShell()->GetObjectShell()->
+ GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
+ if ( xObj.is() )
+ {
+ // try to get the replacement image from the clipboard
+ Graphic aGraphic;
+ sal_uLong nGrFormat = 0;
+// (wg. Selection Manager bei Trustet Solaris)
+#ifndef SOLARIS
+/*
+ if( aDataHelper.GetGraphic( SOT_FORMATSTR_ID_SVXB, aGraphic ) )
+ nGrFormat = SOT_FORMATSTR_ID_SVXB;
+ else if( aDataHelper.GetGraphic( FORMAT_GDIMETAFILE, aGraphic ) )
+ nGrFormat = SOT_FORMAT_GDIMETAFILE;
+ else if( aDataHelper.GetGraphic( FORMAT_BITMAP, aGraphic ) )
+ nGrFormat = SOT_FORMAT_BITMAP;
+*/
+#endif
+
+ // insert replacement image ( if there is one ) into the object helper
+ if ( nGrFormat )
+ {
+ datatransfer::DataFlavor aDataFlavor;
+ SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
+ PasteObject( aPos, xObj, &aObjDesc.maSize, &aGraphic, aDataFlavor.MimeType, aObjDesc.mnViewAspect );
+ }
+ else
+ PasteObject( aPos, xObj, &aObjDesc.maSize );
+
+ bRet = sal_True;
+ }
+ else
+ {
+ DBG_ERROR("Error in CreateAndLoad");
+ }
+ }
+ }
+ else
+ {
+// uno::Reference < io::XInputStream > xStm;
+// TransferableObjectDescriptor aObjDesc;
+
+ if ( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR_OLE, aObjDesc ) )
+ {
+ ::rtl::OUString aName;
+ uno::Reference < embed::XEmbeddedObject > xObj;
+
+ if ( aDataHelper.GetInputStream( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE, xStm )
+ || aDataHelper.GetInputStream( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE, xStm ) )
+ {
+ xObj = GetViewData()->GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xStm, aName );
+ }
+ else
+ {
+ try
+ {
+ uno::Reference< embed::XStorage > xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage();
+ uno::Reference < embed::XEmbedObjectClipboardCreator > xClipboardCreator(
+ ::comphelper::getProcessServiceFactory()->createInstance( ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.MSOLEObjectSystemCreator") ) ),
+ uno::UNO_QUERY_THROW );
+
+ embed::InsertedObjectInfo aInfo = xClipboardCreator->createInstanceInitFromClipboard(
+ xTmpStor,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "DummyName" ) ),
+ uno::Sequence< beans::PropertyValue >() );
+
+ // TODO/LATER: in future InsertedObjectInfo will be used to get container related information
+ // for example whether the object should be an iconified one
+ xObj = aInfo.Object;
+ if ( xObj.is() )
+ GetViewData()->GetDocShell()->GetEmbeddedObjectContainer().InsertEmbeddedObject( xObj, aName );
+ }
+ catch( uno::Exception& )
+ {}
+ }
+
+ if ( xObj.is() )
+ {
+ // try to get the replacement image from the clipboard
+ Graphic aGraphic;
+ sal_uLong nGrFormat = 0;
+
+// (wg. Selection Manager bei Trustet Solaris)
+#ifndef SOLARIS
+ if( aDataHelper.GetGraphic( SOT_FORMATSTR_ID_SVXB, aGraphic ) )
+ nGrFormat = SOT_FORMATSTR_ID_SVXB;
+ else if( aDataHelper.GetGraphic( FORMAT_GDIMETAFILE, aGraphic ) )
+ nGrFormat = SOT_FORMAT_GDIMETAFILE;
+ else if( aDataHelper.GetGraphic( FORMAT_BITMAP, aGraphic ) )
+ nGrFormat = SOT_FORMAT_BITMAP;
+#endif
+
+ // insert replacement image ( if there is one ) into the object helper
+ if ( nGrFormat )
+ {
+ datatransfer::DataFlavor aDataFlavor;
+ SotExchange::GetFormatDataFlavor( nGrFormat, aDataFlavor );
+ PasteObject( aPos, xObj, &aObjDesc.maSize, &aGraphic, aDataFlavor.MimeType, aObjDesc.mnViewAspect );
+ }
+ else
+ PasteObject( aPos, xObj, &aObjDesc.maSize );
+
+ // let object stay in loaded state after insertion
+ SdrOle2Obj::Unload( xObj, embed::Aspects::MSOLE_CONTENT );
+ bRet = sal_True;
+ }
+ else
+ {
+ DBG_ERROR("Error creating external OLE object");
+ }
+ }
+ //TODO/LATER: if format is not available, create picture
+ }
+ }
+ else if ( nFormatId == SOT_FORMATSTR_ID_LINK ) // LINK is also in ScImportExport
+ {
+ bRet = PasteDDE( rxTransferable );
+ }
+ else if ( ScImportExport::IsFormatSupported( nFormatId ) || nFormatId == SOT_FORMAT_RTF )
+ {
+ if ( nFormatId == SOT_FORMAT_RTF && aDataHelper.HasFormat( SOT_FORMATSTR_ID_EDITENGINE ) )
+ {
+ // use EditView's PasteSpecial / Drop
+ PasteRTF( nPosX, nPosY, rxTransferable );
+ bRet = sal_True;
+ }
+ else
+ {
+ ScAddress aCellPos( nPosX, nPosY, GetViewData()->GetTabNo() );
+ ScImportExport aObj( GetViewData()->GetDocument(), aCellPos );
+
+ ::rtl::OUString aStr;
+ SotStorageStreamRef xStream;
+ if ( aDataHelper.GetSotStorageStream( nFormatId, xStream ) && xStream.Is() )
+ // mba: clipboard always must contain absolute URLs (could be from alien source)
+ bRet = aObj.ImportStream( *xStream, String(), nFormatId );
+ else if (nFormatId == FORMAT_STRING && aDataHelper.GetString( nFormatId, aStr ))
+ {
+ // Do CSV dialog if more than one line.
+ sal_Int32 nDelim = aStr.indexOf('\n');
+#if 0
+ ::rtl::OString tmpStr = OUStringToOString( aStr,
+ RTL_TEXTENCODING_UTF8 );
+ fprintf( stderr, "String is '%s' (%d) [%d]\n", tmpStr.getStr(),
+ tmpStr.getLength(), nDelim);
+#endif
+ if (nDelim >= 0 && nDelim != aStr.getLength () - 1)
+ {
+ ScImportStringStream aStrm( aStr);
+ ScAbstractDialogFactory* pFact =
+ ScAbstractDialogFactory::Create();
+ AbstractScImportAsciiDlg *pDlg =
+ pFact->CreateScImportAsciiDlg( NULL, String(), &aStrm,
+ RID_SCDLG_ASCII);
+
+ if (pDlg->Execute() == RET_OK)
+ {
+ ScAsciiOptions aOptions;
+ pDlg->GetOptions( aOptions );
+ aObj.SetExtOptions( aOptions );
+
+ bRet = aObj.ImportString( aStr, nFormatId );
+
+ // TODO: what if (aObj.IsOverflow())
+ // Content was partially pasted, which can be undone by
+ // the user though.
+ if (aObj.IsOverflow())
+ bRet = sal_False;
+ }
+ else
+ bRet = sal_True;
+ // Yes, no failure, don't raise a "couldn't paste"
+ // dialog if user cancelled.
+ delete pDlg;
+ }
+ else
+ bRet = aObj.ImportString( aStr, nFormatId );
+ }
+ else if (nFormatId != FORMAT_STRING && aDataHelper.GetString( nFormatId, aStr ))
+ bRet = aObj.ImportString( aStr, nFormatId );
+
+ InvalidateAttribs();
+ GetViewData()->UpdateInputHandler();
+ }
+ }
+ else if (nFormatId == SOT_FORMATSTR_ID_SBA_DATAEXCHANGE)
+ {
+ // import of database data into table
+
+ String sDataDesc;
+ if ( aDataHelper.GetString( nFormatId, sDataDesc ) )
+ {
+ SfxStringItem aDataDesc(SID_SBA_IMPORT, sDataDesc);
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ ClickCursor(nPosX, nPosY, sal_False); // set cursor position
+
+ // Creation of database area "Import1" isn't here, but in the DocShell
+ // slot execute, so it can be added to the undo action
+
+ ScDBData* pDBData = pDocSh->GetDBData( ScRange(nPosX,nPosY,nTab), SC_DB_OLD, SC_DBSEL_KEEP );
+ String sTarget;
+ if (pDBData)
+ sTarget = pDBData->GetName();
+ else
+ {
+ ScAddress aCellPos( nPosX,nPosY,nTab );
+ aCellPos.Format( sTarget, SCA_ABS_3D, pDoc, pDoc->GetAddressConvention() );
+ }
+ SfxStringItem aTarget(FN_PARAM_1, sTarget);
+
+ sal_Bool bAreaIsNew = !pDBData;
+ SfxBoolItem aAreaNew(FN_PARAM_2, bAreaIsNew);
+
+ ::svx::ODataAccessDescriptor aDesc;
+ DataFlavorExVector& rVector = aDataHelper.GetDataFlavorExVector();
+ ::std::auto_ptr<SfxUsrAnyItem> pCursorItem;
+ if ( ::svx::ODataAccessObjectTransferable::canExtractObjectDescriptor(rVector) )
+ {
+ aDesc = ::svx::ODataAccessObjectTransferable::extractObjectDescriptor(aDataHelper);
+ if ( aDesc.has(::svx::daCursor) )
+ pCursorItem.reset(new SfxUsrAnyItem(FN_PARAM_3, aDesc[::svx::daCursor]));
+ }
+
+ // asynchronous, to avoid doing the whole import in drop handler
+ SfxDispatcher& rDisp = GetViewData()->GetDispatcher();
+ rDisp.Execute(SID_SBA_IMPORT, SFX_CALLMODE_ASYNCHRON,
+ &aDataDesc, &aTarget, &aAreaNew, pCursorItem.get(), (void*)0 );
+
+ bRet = sal_True;
+ }
+ }
+ else if (nFormatId == SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE)
+ {
+ // insert database field control
+
+ if ( ::svx::OColumnTransferable::canExtractColumnDescriptor( aDataHelper.GetDataFlavorExVector(), CTF_COLUMN_DESCRIPTOR | CTF_CONTROL_EXCHANGE ) )
+ {
+ MakeDrawLayer();
+ ScDrawView* pScDrawView = GetScDrawView();
+ SdrObject* pObj = pScDrawView->CreateFieldControl( ::svx::OColumnTransferable::extractColumnDescriptor( aDataHelper ) );
+ if (pObj)
+ {
+ Point aInsPos = aPos;
+ Rectangle aRect(pObj->GetLogicRect());
+ aInsPos.X() -= aRect.GetSize().Width() / 2;
+ aInsPos.Y() -= aRect.GetSize().Height() / 2;
+ if ( aInsPos.X() < 0 ) aInsPos.X() = 0;
+ if ( aInsPos.Y() < 0 ) aInsPos.Y() = 0;
+ aRect.SetPos(aInsPos);
+ pObj->SetLogicRect(aRect);
+
+ if ( pObj->ISA(SdrUnoObj) )
+ pObj->NbcSetLayer(SC_LAYER_CONTROLS);
+ else
+ pObj->NbcSetLayer(SC_LAYER_FRONT);
+ if (pObj->ISA(SdrObjGroup))
+ {
+ SdrObjListIter aIter( *pObj, IM_DEEPWITHGROUPS );
+ SdrObject* pSubObj = aIter.Next();
+ while (pSubObj)
+ {
+ if ( pSubObj->ISA(SdrUnoObj) )
+ pSubObj->NbcSetLayer(SC_LAYER_CONTROLS);
+ else
+ pSubObj->NbcSetLayer(SC_LAYER_FRONT);
+ pSubObj = aIter.Next();
+ }
+ }
+
+ pScDrawView->InsertObjectSafe(pObj, *pScDrawView->GetSdrPageView());
+
+ GetViewData()->GetViewShell()->SetDrawShell( sal_True );
+ bRet = sal_True;
+ }
+ }
+ }
+ else if (nFormatId == SOT_FORMAT_BITMAP)
+ {
+ Bitmap aBmp;
+ if( aDataHelper.GetBitmap( FORMAT_BITMAP, aBmp ) )
+ bRet = PasteBitmap( aPos, aBmp );
+ }
+ else if (nFormatId == SOT_FORMAT_GDIMETAFILE)
+ {
+ GDIMetaFile aMtf;
+ if( aDataHelper.GetGDIMetaFile( FORMAT_GDIMETAFILE, aMtf ) )
+ bRet = PasteMetaFile( aPos, aMtf );
+ }
+ else if (nFormatId == SOT_FORMATSTR_ID_SVXB)
+ {
+ SotStorageStreamRef xStm;
+ if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_SVXB, xStm ) )
+ {
+ Graphic aGraphic;
+ *xStm >> aGraphic;
+ bRet = PasteGraphic( aPos, aGraphic, EMPTY_STRING, EMPTY_STRING );
+ }
+ }
+ else if ( nFormatId == SOT_FORMATSTR_ID_DRAWING )
+ {
+ SotStorageStreamRef xStm;
+ if( aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_DRAWING, xStm ) )
+ {
+ MakeDrawLayer(); // before loading model, so 3D factory has been created
+
+ SvtPathOptions aPathOpt;
+ String aPath = aPathOpt.GetPalettePath();
+
+ ScDocShellRef aDragShellRef( new ScDocShell );
+ aDragShellRef->DoInitNew(NULL);
+ FmFormModel* pModel = new FmFormModel( aPath, NULL, aDragShellRef );
+
+ pModel->GetItemPool().FreezeIdRanges();
+ xStm->Seek(0);
+
+ com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream( new utl::OInputStreamWrapper( *xStm ) );
+ SvxDrawingLayerImport( pModel, xInputStream );
+
+ // set everything to right layer:
+ sal_uLong nObjCount = 0;
+ sal_uInt16 nPages = pModel->GetPageCount();
+ for (sal_uInt16 i=0; i<nPages; i++)
+ {
+ SdrPage* pPage = pModel->GetPage(i);
+ SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->ISA(SdrUnoObj) )
+ pObject->NbcSetLayer(SC_LAYER_CONTROLS);
+ else
+ pObject->NbcSetLayer(SC_LAYER_FRONT);
+ pObject = aIter.Next();
+ }
+
+ nObjCount += pPage->GetObjCount(); // #105888# count group object only once
+ }
+
+ PasteDraw( aPos, pModel, (nObjCount > 1) ); // grouped if more than 1 object
+ delete pModel;
+ aDragShellRef->DoClose();
+ bRet = sal_True;
+ }
+ }
+ else if ( (nFormatId == SOT_FORMATSTR_ID_BIFF_5) || (nFormatId == SOT_FORMATSTR_ID_BIFF_8) )
+ {
+ // do excel import into a clipboard document
+ //TODO/MBA: testing
+ uno::Reference < io::XInputStream > xStm;
+ if( aDataHelper.GetInputStream( nFormatId, xStm ) )
+ {
+#if 0
+ SotStorage aDest( "d:\\test.xls" ); // to see the file
+ pStor->CopyTo( &aDest );
+#endif
+ ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP );
+ SCTAB nSrcTab = 0; // Biff5 in clipboard: always sheet 0
+ pInsDoc->ResetClip( pDoc, nSrcTab );
+
+ SfxMedium aMed;
+ aMed.GetItemSet()->Put( SfxUsrAnyItem( SID_INPUTSTREAM, uno::makeAny( xStm ) ) );
+ FltError eErr = ScFormatFilter::Get().ScImportExcel( aMed, pInsDoc, EIF_AUTO );
+ if ( eErr == eERR_OK )
+ {
+ ScRange aSource;
+ const ScExtDocOptions* pExtOpt = pInsDoc->GetExtDocOptions();
+ const ScExtTabSettings* pTabSett = pExtOpt ? pExtOpt->GetTabSettings( nSrcTab ) : 0;
+ if( pTabSett && pTabSett->maUsedArea.IsValid() )
+ {
+ aSource = pTabSett->maUsedArea;
+ // ensure correct sheet indexes
+ aSource.aStart.SetTab( nSrcTab );
+ aSource.aEnd.SetTab( nSrcTab );
+// #92240# don't use selection area: if cursor is moved in Excel after Copy, selection
+// represents the new cursor position and not the copied area
+ }
+ else
+ {
+ DBG_ERROR("no dimension"); //! possible?
+ SCCOL nFirstCol, nLastCol;
+ SCROW nFirstRow, nLastRow;
+ if ( pInsDoc->GetDataStart( nSrcTab, nFirstCol, nFirstRow ) )
+ pInsDoc->GetCellArea( nSrcTab, nLastCol, nLastRow );
+ else
+ {
+ nFirstCol = nLastCol = 0;
+ nFirstRow = nLastRow = 0;
+ }
+ aSource = ScRange( nFirstCol, nFirstRow, nSrcTab,
+ nLastCol, nLastRow, nSrcTab );
+ }
+
+ if ( pLogicPos )
+ {
+ // position specified (Drag&Drop) - change selection
+ MoveCursorAbs( nPosX, nPosY, SC_FOLLOW_NONE, sal_False, sal_False );
+ Unmark();
+ }
+
+ pInsDoc->SetClipArea( aSource );
+ PasteFromClip( IDF_ALL, pInsDoc,
+ PASTE_NOFUNC, sal_False, sal_False, sal_False, INS_NONE, IDF_NONE,
+ bAllowDialogs );
+ delete pInsDoc;
+
+ bRet = sal_True;
+ }
+ }
+ }
+ else if ( nFormatId == SOT_FORMAT_FILE )
+ {
+ String aFile;
+ if ( aDataHelper.GetString( nFormatId, aFile ) )
+ bRet = PasteFile( aPos, aFile, bLink );
+ }
+ else if ( nFormatId == SOT_FORMAT_FILE_LIST )
+ {
+ FileList aFileList;
+ if ( aDataHelper.GetFileList( nFormatId, aFileList ) )
+ {
+ sal_uLong nCount = aFileList.Count();
+ for( sal_uLong i = 0; i < nCount ; i++ )
+ {
+ String aFile = aFileList.GetFile( i );
+
+ PasteFile( aPos, aFile, bLink );
+#if 0
+ SfxStringItem aNameItem( FID_INSERT_FILE, aFile );
+ SfxPointItem aPosItem( FN_PARAM_1, aPos );
+ SfxDispatcher* pDisp =
+ GetViewData()->GetViewShell()->GetViewFrame()->GetDispatcher();
+ if (pDisp)
+ pDisp->Execute( FID_INSERT_FILE, SFX_CALLMODE_ASYNCHRON,
+ &aNameItem, &aPosItem, (void*)0 );
+#endif
+
+ aPos.X() += 400;
+ aPos.Y() += 400;
+ }
+ bRet = sal_True;
+ }
+ }
+ else if ( nFormatId == SOT_FORMATSTR_ID_SOLK ||
+ nFormatId == SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ||
+ nFormatId == SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ||
+ nFormatId == SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR )
+ {
+ bRet = PasteBookmark( nFormatId, rxTransferable, nPosX, nPosY );
+ }
+
+ pDoc->SetPastingDrawFromOtherDoc( sal_False );
+
+ return bRet;
+}
+
+ByteString lcl_GetSubString( sal_Char* pData, long nStart, long nDataSize )
+{
+ if ( nDataSize <= nStart /* || pData[nDataSize] != 0 */ )
+ {
+ DBG_ERROR("DDE Data: invalid data");
+ return ByteString();
+ }
+ return ByteString( pData + nStart );
+}
+
+sal_Bool ScViewFunc::PasteDDE( const uno::Reference<datatransfer::XTransferable>& rxTransferable )
+{
+ TransferableDataHelper aDataHelper( rxTransferable );
+
+ // get link data from transferable before string data,
+ // so the source knows it will be used for a link
+
+ uno::Sequence<sal_Int8> aSequence;
+ if ( !aDataHelper.GetSequence( SOT_FORMATSTR_ID_LINK, aSequence ) )
+ {
+ DBG_ERROR("DDE Data not found.");
+ return sal_False;
+ }
+
+ // check size (only if string is available in transferable)
+
+ sal_uInt16 nCols = 1;
+ sal_uInt16 nRows = 1;
+ if ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) )
+ {
+ String aDataStr;
+ if ( aDataHelper.GetString( SOT_FORMAT_STRING, aDataStr ) )
+ {
+ // get size from string the same way as in ScDdeLink::DataChanged
+
+ aDataStr.ConvertLineEnd(LINEEND_LF);
+ xub_StrLen nLen = aDataStr.Len();
+ if (nLen && aDataStr.GetChar(nLen-1) == '\n')
+ aDataStr.Erase(nLen-1);
+
+ if (aDataStr.Len())
+ {
+ nRows = aDataStr.GetTokenCount( '\n' );
+ String aLine = aDataStr.GetToken( 0, '\n' );
+ if (aLine.Len())
+ nCols = aLine.GetTokenCount( '\t' );
+ }
+ }
+ }
+
+ // create formula
+
+ long nSeqLen = aSequence.getLength();
+ sal_Char* pData = (sal_Char*)aSequence.getConstArray();
+
+ rtl_TextEncoding eSysEnc = gsl_getSystemTextEncoding();
+
+ ByteString aByteApp = lcl_GetSubString( pData, 0, nSeqLen );
+ ByteString aByteTopic = lcl_GetSubString( pData, aByteApp.Len() + 1, nSeqLen );
+ ByteString aByteItem = lcl_GetSubString( pData, aByteApp.Len() + aByteTopic.Len() + 2, nSeqLen );
+
+ String aApp( aByteApp, eSysEnc );
+ String aTopic( aByteTopic, eSysEnc );
+ String aItem( aByteItem, eSysEnc );
+
+ // TODO: we could define ocQuote for "
+ const String aQuote( '"' );
+ const String& sSep = ScCompiler::GetNativeSymbol( ocSep);
+ String aFormula( '=' );
+ aFormula += ScCompiler::GetNativeSymbol( ocDde);
+ aFormula += ScCompiler::GetNativeSymbol( ocOpen);
+ aFormula += aQuote;
+ aFormula += aApp;
+ aFormula += aQuote;
+ aFormula += sSep;
+ aFormula += aQuote;
+ aFormula += aTopic;
+ aFormula += aQuote;
+ aFormula += sSep;
+ aFormula += aQuote;
+ aFormula += aItem;
+ aFormula += aQuote;
+ aFormula += ScCompiler::GetNativeSymbol( ocClose);
+
+ // mark range
+
+ SCTAB nTab = GetViewData()->GetTabNo();
+ SCCOL nCurX = GetViewData()->GetCurX();
+ SCROW nCurY = GetViewData()->GetCurY();
+ HideAllCursors();
+ DoneBlockMode();
+ InitBlockMode( nCurX, nCurY, nTab );
+ MarkCursor( nCurX+static_cast<SCCOL>(nCols)-1, nCurY+static_cast<SCROW>(nRows)-1, nTab );
+ ShowAllCursors();
+
+ // enter formula
+
+ EnterMatrix( aFormula );
+ CursorPosChanged();
+
+ return sal_True;
+}
+
+
diff --git a/sc/source/ui/view/viewfun6.cxx b/sc/source/ui/view/viewfun6.cxx
new file mode 100644
index 000000000000..ded17fb9ccf4
--- /dev/null
+++ b/sc/source/ui/view/viewfun6.cxx
@@ -0,0 +1,197 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+#include <svx/svdundo.hxx>
+#include <svx/svdocapt.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/sound.hxx>
+
+#include "viewfunc.hxx"
+#include "detfunc.hxx"
+#include "detdata.hxx"
+#include "viewdata.hxx"
+#include "drwlayer.hxx"
+#include "docsh.hxx"
+#include "undocell.hxx"
+#include "futext.hxx"
+#include "docfunc.hxx"
+#include "globstr.hrc"
+#include "sc.hrc"
+#include "fusel.hxx"
+
+//==================================================================
+
+void ScViewFunc::DetectiveAddPred()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ sal_Bool bDone = pDocSh->GetDocFunc().
+ DetectiveAddPred( GetViewData()->GetCurPos() );
+ if (!bDone)
+ Sound::Beep();
+
+ RecalcPPT(); //! use broadcast in DocFunc instead?
+}
+
+void ScViewFunc::DetectiveDelPred()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ sal_Bool bDone = pDocSh->GetDocFunc().
+ DetectiveDelPred( GetViewData()->GetCurPos() );
+ if (!bDone)
+ Sound::Beep();
+
+ RecalcPPT();
+}
+
+void ScViewFunc::DetectiveAddSucc()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ sal_Bool bDone = pDocSh->GetDocFunc().
+ DetectiveAddSucc( GetViewData()->GetCurPos() );
+ if (!bDone)
+ Sound::Beep();
+
+ RecalcPPT();
+}
+
+void ScViewFunc::DetectiveDelSucc()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ sal_Bool bDone = pDocSh->GetDocFunc().
+ DetectiveDelSucc( GetViewData()->GetCurPos() );
+ if (!bDone)
+ Sound::Beep();
+
+ RecalcPPT();
+}
+
+void ScViewFunc::DetectiveAddError()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ sal_Bool bDone = pDocSh->GetDocFunc().
+ DetectiveAddError( GetViewData()->GetCurPos() );
+ if (!bDone)
+ Sound::Beep();
+
+ RecalcPPT();
+}
+
+void ScViewFunc::DetectiveDelAll()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ sal_Bool bDone = pDocSh->GetDocFunc().
+ DetectiveDelAll( GetViewData()->GetTabNo() );
+ if (!bDone)
+ Sound::Beep();
+
+ RecalcPPT();
+}
+
+void ScViewFunc::DetectiveMarkInvalid()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ sal_Bool bDone = pDocSh->GetDocFunc().
+ DetectiveMarkInvalid( GetViewData()->GetTabNo() );
+ if (!bDone)
+ Sound::Beep();
+
+ RecalcPPT();
+}
+
+void ScViewFunc::DetectiveRefresh()
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ sal_Bool bDone = pDocSh->GetDocFunc().DetectiveRefresh();
+ if (!bDone)
+ Sound::Beep();
+
+ RecalcPPT();
+}
+
+//---------------------------------------------------------------------------
+
+void ScViewFunc::ShowNote( bool bShow )
+{
+ if( bShow )
+ HideNoteMarker();
+ const ScViewData& rViewData = *GetViewData();
+ ScAddress aPos( rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo() );
+ // show note moved to ScDocFunc, to be able to use it in notesuno.cxx
+ rViewData.GetDocShell()->GetDocFunc().ShowNote( aPos, bShow );
+}
+
+void ScViewFunc::EditNote()
+{
+ // zum Editieren einblenden und aktivieren
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScAddress aPos( nCol, nRow, nTab );
+
+ // start drawing undo to catch undo action for insertion of the caption object
+ pDocSh->MakeDrawLayer();
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ pDrawLayer->BeginCalcUndo();
+ // generated undo action is processed in FuText::StopEditMode
+
+ // get existing note or create a new note (including caption drawing object)
+ if( ScPostIt* pNote = pDoc->GetOrCreateNote( aPos ) )
+ {
+ // hide temporary note caption
+ HideNoteMarker();
+ // show caption object without changing internal visibility state
+ pNote->ShowCaptionTemp( aPos );
+
+ /* Drawing object has been created in ScDocument::GetOrCreateNote() or
+ in ScPostIt::ShowCaptionTemp(), so ScPostIt::GetCaption() should
+ return a caption object. */
+ if( SdrCaptionObj* pCaption = pNote->GetCaption() )
+ {
+ // #i33764# enable the resize handles before starting edit mode
+ if( FuPoor* pDraw = GetDrawFuncPtr() )
+ static_cast< FuSelection* >( pDraw )->ActivateNoteHandles( pCaption );
+
+ // activate object (as in FuSelection::TestComment)
+ GetViewData()->GetDispatcher().Execute( SID_DRAW_NOTEEDIT, SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD );
+ // jetzt den erzeugten FuText holen und in den EditModus setzen
+ FuPoor* pPoor = GetDrawFuncPtr();
+ if ( pPoor && (pPoor->GetSlotID() == SID_DRAW_NOTEEDIT) ) // hat keine RTTI
+ {
+ ScrollToObject( pCaption ); // Objekt komplett sichtbar machen
+ static_cast< FuText* >( pPoor )->SetInEditMode( pCaption );
+ }
+ }
+ }
+}
diff --git a/sc/source/ui/view/viewfun7.cxx b/sc/source/ui/view/viewfun7.cxx
new file mode 100644
index 000000000000..5ee4893a0a9a
--- /dev/null
+++ b/sc/source/ui/view/viewfun7.cxx
@@ -0,0 +1,492 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <svx/svditer.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/xbitmap.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xoutbmp.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <com/sun/star/embed/Aspects.hpp>
+
+#include "document.hxx" // fuer MapMode Initialisierung in PasteDraw
+#include "viewfunc.hxx"
+#include "tabvwsh.hxx"
+#include "drawview.hxx"
+#include "scmod.hxx"
+#include "drwlayer.hxx"
+#include "drwtrans.hxx"
+#include "globstr.hrc"
+#include "chartlis.hxx"
+#include "docuno.hxx"
+#include "docsh.hxx"
+#include "convuno.hxx"
+
+extern Point aDragStartDiff;
+
+// STATIC DATA -----------------------------------------------------------
+
+sal_Bool bPasteIsMove = sal_False;
+
+using namespace com::sun::star;
+
+//==================================================================
+
+void lcl_AdjustInsertPos( ScViewData* pData, Point& rPos, Size& rSize )
+{
+// SdrPage* pPage = pData->GetDocument()->GetDrawLayer()->GetPage( pData->GetTabNo() );
+ SdrPage* pPage = pData->GetScDrawView()->GetModel()->GetPage( static_cast<sal_uInt16>(pData->GetTabNo()) );
+ DBG_ASSERT(pPage,"pPage ???");
+ Size aPgSize( pPage->GetSize() );
+ if (aPgSize.Width() < 0)
+ aPgSize.Width() = -aPgSize.Width();
+ long x = aPgSize.Width() - rPos.X() - rSize.Width();
+ long y = aPgSize.Height() - rPos.Y() - rSize.Height();
+ // ggf. Ajustments (80/200) fuer Pixel-Rundungsfehler
+ if( x < 0 )
+ rPos.X() += x + 80;
+ if( y < 0 )
+ rPos.Y() += y + 200;
+ rPos.X() += rSize.Width() / 2; // Position bei Paste gibt Mittelpunkt an
+ rPos.Y() += rSize.Height() / 2;
+}
+
+void ScViewFunc::PasteDraw( const Point& rLogicPos, SdrModel* pModel,
+ sal_Bool bGroup, sal_Bool bSameDocClipboard )
+{
+ MakeDrawLayer();
+ Point aPos( rLogicPos );
+
+ // #64184# MapMode am Outliner-RefDevice muss stimmen (wie in FuText::MakeOutliner)
+ //! mit FuText::MakeOutliner zusammenfassen?
+ MapMode aOldMapMode;
+ OutputDevice* pRef = GetViewData()->GetDocument()->GetDrawLayer()->GetRefDevice();
+ if (pRef)
+ {
+ aOldMapMode = pRef->GetMapMode();
+ pRef->SetMapMode( MapMode(MAP_100TH_MM) );
+ }
+
+ sal_Bool bNegativePage = GetViewData()->GetDocument()->IsNegativePage( GetViewData()->GetTabNo() );
+
+ SdrView* pDragEditView = NULL;
+ ScModule* pScMod = SC_MOD();
+ const ScDragData& rData = pScMod->GetDragData();
+ ScDrawTransferObj* pDrawTrans = rData.pDrawTransfer;
+ if (pDrawTrans)
+ {
+ pDragEditView = pDrawTrans->GetDragSourceView();
+
+ aPos -= aDragStartDiff;
+ if ( bNegativePage )
+ {
+ if (aPos.X() > 0) aPos.X() = 0;
+ }
+ else
+ {
+ if (aPos.X() < 0) aPos.X() = 0;
+ }
+ if (aPos.Y() < 0) aPos.Y() = 0;
+ }
+
+ ScDrawView* pScDrawView = GetScDrawView();
+ if (bGroup)
+ pScDrawView->BegUndo( ScGlobal::GetRscString( STR_UNDO_PASTE ) );
+
+ sal_Bool bSameDoc = ( pDragEditView && pDragEditView->GetModel() == pScDrawView->GetModel() );
+ if (bSameDoc)
+ {
+ // lokal kopieren - incl. Charts
+
+ Point aSourceStart = pDragEditView->GetAllMarkedRect().TopLeft();
+ long nDiffX = aPos.X() - aSourceStart.X();
+ long nDiffY = aPos.Y() - aSourceStart.Y();
+
+ // innerhalb einer Page verschieben?
+
+ if ( bPasteIsMove &&
+ pScDrawView->GetSdrPageView()->GetPage() ==
+ pDragEditView->GetSdrPageView()->GetPage() )
+ {
+ if ( nDiffX != 0 || nDiffY != 0 )
+ pDragEditView->MoveAllMarked(Size(nDiffX,nDiffY), sal_False);
+ }
+ else
+ {
+ SdrModel* pDrawModel = pDragEditView->GetModel();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ SdrPage* pDestPage = pDrawModel->GetPage( static_cast< sal_uInt16 >( nTab ) );
+ DBG_ASSERT(pDestPage,"nanu, Page?");
+
+ ::std::vector< ::rtl::OUString > aExcludedChartNames;
+ if ( pDestPage )
+ {
+ ScChartHelper::GetChartNames( aExcludedChartNames, pDestPage );
+ }
+
+ SdrMarkList aMark = pDragEditView->GetMarkedObjectList();
+ aMark.ForceSort();
+ sal_uLong nMarkAnz=aMark.GetMarkCount();
+ for (sal_uLong nm=0; nm<nMarkAnz; nm++) {
+ const SdrMark* pM=aMark.GetMark(nm);
+ const SdrObject* pObj=pM->GetMarkedSdrObj();
+
+ // #116235#
+ SdrObject* pNeuObj=pObj->Clone();
+ //SdrObject* pNeuObj=pObj->Clone(pDestPage,pDrawModel);
+
+ if (pNeuObj!=NULL)
+ {
+ pNeuObj->SetModel(pDrawModel);
+ pNeuObj->SetPage(pDestPage);
+
+ // #68787# copy graphics within the same model - always needs new name
+ if ( pNeuObj->ISA(SdrGrafObj) && !bPasteIsMove )
+ pNeuObj->SetName(((ScDrawLayer*)pDrawModel)->GetNewGraphicName());
+
+ if (nDiffX!=0 || nDiffY!=0)
+ pNeuObj->NbcMove(Size(nDiffX,nDiffY));
+ pDestPage->InsertObject( pNeuObj );
+ pScDrawView->AddUndo(new SdrUndoInsertObj( *pNeuObj ));
+
+ // Chart braucht nicht mehr getrennt behandelt zu werden,
+ // weil es seine Daten jetzt selber hat
+ }
+ }
+
+ if (bPasteIsMove)
+ pDragEditView->DeleteMarked();
+
+ ScDocument* pDocument = GetViewData()->GetDocument();
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ ScModelObj* pModelObj = ( pDocShell ? ScModelObj::getImplementation( pDocShell->GetModel() ) : NULL );
+ if ( pDocument && pDestPage && pModelObj && pDrawTrans )
+ {
+ const ScRangeListVector& rProtectedChartRangesVector( pDrawTrans->GetProtectedChartRangesVector() );
+ ScChartHelper::CreateProtectedChartListenersAndNotify( pDocument, pDestPage, pModelObj, nTab,
+ rProtectedChartRangesVector, aExcludedChartNames, bSameDoc );
+ }
+ }
+ }
+ else
+ {
+ bPasteIsMove = sal_False; // kein internes Verschieben passiert
+
+ SdrView aView(pModel); // #i71529# never create a base class of SdrView directly!
+ SdrPageView* pPv = aView.ShowSdrPage(aView.GetModel()->GetPage(0));
+ aView.MarkAllObj(pPv);
+ Size aSize = aView.GetAllMarkedRect().GetSize();
+ lcl_AdjustInsertPos( GetViewData(), aPos, aSize );
+
+ // #41333# Markierung nicht aendern, wenn Ole-Objekt aktiv
+ // (bei Drop aus Ole-Objekt wuerde sonst mitten im ExecuteDrag deaktiviert!)
+
+ sal_uLong nOptions = 0;
+ SfxInPlaceClient* pClient = GetViewData()->GetViewShell()->GetIPClient();
+ if ( pClient && pClient->IsObjectInPlaceActive() )
+ nOptions |= SDRINSERT_DONTMARK;
+
+ ::std::vector< ::rtl::OUString > aExcludedChartNames;
+ SCTAB nTab = GetViewData()->GetTabNo();
+ SdrPage* pPage = pScDrawView->GetModel()->GetPage( static_cast< sal_uInt16 >( nTab ) );
+ DBG_ASSERT( pPage, "Page?" );
+ if ( pPage )
+ {
+ ScChartHelper::GetChartNames( aExcludedChartNames, pPage );
+ }
+
+ // #89247# Set flag for ScDocument::UpdateChartListeners() which is
+ // called during paste.
+ if ( !bSameDocClipboard )
+ GetViewData()->GetDocument()->SetPastingDrawFromOtherDoc( sal_True );
+
+ pScDrawView->Paste( *pModel, aPos, NULL, nOptions );
+
+ if ( !bSameDocClipboard )
+ GetViewData()->GetDocument()->SetPastingDrawFromOtherDoc( sal_False );
+
+ // #68991# Paste puts all objects on the active (front) layer
+ // controls must be on SC_LAYER_CONTROLS
+ if (pPage)
+ {
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject)
+ {
+ if ( pObject->ISA(SdrUnoObj) && pObject->GetLayer() != SC_LAYER_CONTROLS )
+ pObject->NbcSetLayer(SC_LAYER_CONTROLS);
+ pObject = aIter.Next();
+ }
+ }
+
+ // #75299# all graphics objects must have names
+ GetViewData()->GetDocument()->EnsureGraphicNames();
+
+ ScDocument* pDocument = GetViewData()->GetDocument();
+ ScDocShell* pDocShell = GetViewData()->GetDocShell();
+ ScModelObj* pModelObj = ( pDocShell ? ScModelObj::getImplementation( pDocShell->GetModel() ) : NULL );
+ ScDrawTransferObj* pTransferObj = ScDrawTransferObj::GetOwnClipboard( NULL );
+ if ( pDocument && pPage && pModelObj && ( pTransferObj || pDrawTrans ) )
+ {
+ const ScRangeListVector& rProtectedChartRangesVector(
+ pTransferObj ? pTransferObj->GetProtectedChartRangesVector() : pDrawTrans->GetProtectedChartRangesVector() );
+ ScChartHelper::CreateProtectedChartListenersAndNotify( pDocument, pPage, pModelObj, nTab,
+ rProtectedChartRangesVector, aExcludedChartNames, bSameDocClipboard );
+ }
+ }
+
+ if (bGroup)
+ {
+ pScDrawView->GroupMarked();
+ pScDrawView->EndUndo();
+ }
+
+ if (pRef)
+ pRef->SetMapMode( aOldMapMode );
+
+ // GetViewData()->GetViewShell()->SetDrawShell( sal_True );
+ // #99759# It is not sufficient to just set the DrawShell if we pasted, for
+ // example, a chart. SetDrawShellOrSub() would only work for D&D in the
+ // same document but not if inserting from the clipboard, therefore
+ // MarkListHasChanged() is what we need.
+ pScDrawView->MarkListHasChanged();
+
+}
+
+sal_Bool ScViewFunc::PasteObject( const Point& rPos, const uno::Reference < embed::XEmbeddedObject >& xObj,
+ const Size* pDescSize, const Graphic* pReplGraph, const ::rtl::OUString& aMediaType, sal_Int64 nAspect )
+{
+ MakeDrawLayer();
+ if ( xObj.is() )
+ {
+ ::rtl::OUString aName;
+ //TODO/MBA: is that OK?
+ comphelper::EmbeddedObjectContainer& aCnt = GetViewData()->GetViewShell()->GetObjectShell()->GetEmbeddedObjectContainer();
+ if ( !aCnt.HasEmbeddedObject( xObj ) )
+ aCnt.InsertEmbeddedObject( xObj, aName );
+ else
+ aName = aCnt.GetEmbeddedObjectName( xObj );
+
+ svt::EmbeddedObjectRef aObjRef( xObj, nAspect );
+ if ( pReplGraph )
+ aObjRef.SetGraphic( *pReplGraph, aMediaType );
+
+ Size aSize;
+ if ( nAspect == embed::Aspects::MSOLE_ICON )
+ {
+ MapMode aMapMode( MAP_100TH_MM );
+ aSize = aObjRef.GetSize( &aMapMode );
+ }
+ else
+ {
+ // working with visual area can switch object to running state
+ MapUnit aMapObj = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
+ MapUnit aMap100 = MAP_100TH_MM;
+
+ if ( pDescSize && pDescSize->Width() && pDescSize->Height() )
+ {
+ // use size from object descriptor if given
+ aSize = OutputDevice::LogicToLogic( *pDescSize, aMap100, aMapObj );
+ awt::Size aSz;
+ aSz.Width = aSize.Width();
+ aSz.Height = aSize.Height();
+ xObj->setVisualAreaSize( nAspect, aSz );
+ }
+
+ awt::Size aSz;
+ try
+ {
+ aSz = xObj->getVisualAreaSize( nAspect );
+ }
+ catch ( embed::NoVisualAreaSizeException& )
+ {
+ // the default size will be set later
+ }
+
+ aSize = Size( aSz.Width, aSz.Height );
+ aSize = OutputDevice::LogicToLogic( aSize, aMapObj, aMap100 ); // fuer SdrOle2Obj
+
+ if( aSize.Height() == 0 || aSize.Width() == 0 )
+ {
+ DBG_ERROR("SvObjectDescriptor::GetSize == 0");
+ aSize.Width() = 5000;
+ aSize.Height() = 5000;
+ aSize = OutputDevice::LogicToLogic( aSize, aMap100, aMapObj );
+ aSz.Width = aSize.Width();
+ aSz.Height = aSize.Height();
+ xObj->setVisualAreaSize( nAspect, aSz );
+ }
+ }
+
+ // don't call AdjustInsertPos
+ Point aInsPos = rPos;
+ if ( GetViewData()->GetDocument()->IsNegativePage( GetViewData()->GetTabNo() ) )
+ aInsPos.X() -= aSize.Width();
+ Rectangle aRect( aInsPos, aSize );
+
+ ScDrawView* pDrView = GetScDrawView();
+ SdrOle2Obj* pSdrObj = new SdrOle2Obj( aObjRef, aName, aRect );
+
+ SdrPageView* pPV = pDrView->GetSdrPageView();
+ pDrView->InsertObjectSafe( pSdrObj, *pPV ); // nicht markieren wenn Ole
+ GetViewData()->GetViewShell()->SetDrawShell( sal_True );
+ return sal_True;
+ }
+ else
+ return sal_False;
+}
+
+sal_Bool ScViewFunc::PasteBitmap( const Point& rPos, const Bitmap& rBmp )
+{
+ String aEmpty;
+ Graphic aGraphic(rBmp);
+ return PasteGraphic( rPos, aGraphic, aEmpty, aEmpty );
+}
+
+sal_Bool ScViewFunc::PasteMetaFile( const Point& rPos, const GDIMetaFile& rMtf )
+{
+ String aEmpty;
+ Graphic aGraphic(rMtf);
+ return PasteGraphic( rPos, aGraphic, aEmpty, aEmpty );
+}
+
+sal_Bool ScViewFunc::PasteGraphic( const Point& rPos, const Graphic& rGraphic,
+ const String& rFile, const String& rFilter )
+{
+ MakeDrawLayer();
+ ScDrawView* pScDrawView = GetScDrawView();
+
+ Point aPos( rPos );
+ Window* pWin = GetActiveWin();
+ MapMode aSourceMap = rGraphic.GetPrefMapMode();
+ MapMode aDestMap( MAP_100TH_MM );
+
+ if (aSourceMap.GetMapUnit() == MAP_PIXEL)
+ {
+ // Pixel-Korrektur beruecksichtigen, damit Bitmap auf dem Bildschirm stimmt
+
+ Fraction aScaleX, aScaleY;
+ pScDrawView->CalcNormScale( aScaleX, aScaleY );
+ aDestMap.SetScaleX(aScaleX);
+ aDestMap.SetScaleY(aScaleY);
+ }
+
+ Size aSize = pWin->LogicToLogic( rGraphic.GetPrefSize(), &aSourceMap, &aDestMap );
+// lcl_AdjustInsertPos( GetViewData(), aPos, aSize );
+ if ( GetViewData()->GetDocument()->IsNegativePage( GetViewData()->GetTabNo() ) )
+ aPos.X() -= aSize.Width();
+
+ GetViewData()->GetViewShell()->SetDrawShell( sal_True );
+
+ Rectangle aRect(aPos, aSize);
+ SdrGrafObj* pGrafObj = new SdrGrafObj(rGraphic, aRect);
+
+ // #118522# calling SetGraphicLink here doesn't work
+
+ // #49961# Pfad wird nicht mehr als Name der Grafik gesetzt
+
+ ScDrawLayer* pLayer = (ScDrawLayer*) pScDrawView->GetModel();
+ String aName = pLayer->GetNewGraphicName(); // "Grafik x"
+ pGrafObj->SetName(aName);
+
+ // nicht markieren wenn Ole
+ pScDrawView->InsertObjectSafe(pGrafObj, *pScDrawView->GetSdrPageView());
+
+ // #118522# SetGraphicLink has to be used after inserting the object,
+ // otherwise an empty graphic is swapped in and the contact stuff crashes.
+ // See #i37444#.
+ if (rFile.Len())
+ pGrafObj->SetGraphicLink( rFile, rFilter );
+
+ return sal_True;
+}
+
+sal_Bool ScViewFunc::ApplyGraphicToObject( SdrObject* pPickObj, const Graphic& rGraphic )
+{
+ sal_Bool bRet = sal_False;
+ SdrGrafObj* pNewGrafObj = NULL;
+
+ ScDrawView* pScDrawView = GetScDrawView();
+ if ( pScDrawView && pPickObj )
+ {
+ /**********************************************************************
+ * Objekt neu attributieren
+ **********************************************************************/
+ SdrPageView* pPV = pScDrawView->GetSdrPageView();
+ if (pPickObj->ISA(SdrGrafObj))
+ {
+ /******************************************************************
+ * Das Graphik-Objekt bekommt eine neue Graphik
+ ******************************************************************/
+ pNewGrafObj = (SdrGrafObj*) pPickObj->Clone();
+ pNewGrafObj->SetGraphic(rGraphic);
+
+ pScDrawView->BegUndo(ScGlobal::GetRscString(STR_UNDO_DRAGDROP));
+ pScDrawView->ReplaceObjectAtView(pPickObj, *pPV, pNewGrafObj);
+ pScDrawView->EndUndo();
+
+ bRet = sal_True;
+ }
+ else if (pPickObj->IsClosedObj() && !pPickObj->ISA(SdrOle2Obj))
+ {
+ /******************************************************************
+ * Das Objekt wird mit der Graphik gefuellt
+ ******************************************************************/
+ //pScDrawView->BegUndo(ScGlobal::GetRscString(STR_UNDO_DRAGDROP));
+ pScDrawView->AddUndo(new SdrUndoAttrObj(*pPickObj));
+ //pScDrawView->EndUndo();
+
+ XOBitmap aXOBitmap( rGraphic.GetBitmap() );
+ SfxItemSet aSet( pScDrawView->GetModel()->GetItemPool(),
+ XATTR_FILLSTYLE, XATTR_FILLBITMAP );
+ aSet.Put(XFillStyleItem(XFILL_BITMAP));
+ aSet.Put(XFillBitmapItem(String(), aXOBitmap));
+
+ pPickObj->SetMergedItemSetAndBroadcast(aSet);
+
+ bRet = sal_True;
+ }
+ }
+ return bRet;
+}
+
+
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
new file mode 100644
index 000000000000..8c309b3cc6a1
--- /dev/null
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -0,0 +1,3018 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/app.hxx>
+#include <svx/algitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/editview.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <sfx2/bindings.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/sound.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/waitobj.hxx>
+#include <vcl/wrkwin.hxx>
+#include <stdlib.h> // qsort
+
+#include "viewfunc.hxx"
+#include "tabvwsh.hxx"
+#include "docsh.hxx"
+#include "attrib.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "uiitems.hxx"
+#include "sc.hrc"
+#include "undocell.hxx"
+#include "undoblk.hxx"
+#include "undotab.hxx"
+#include "refundo.hxx"
+#include "dbcolect.hxx"
+#include "olinetab.hxx"
+#include "rangeutl.hxx"
+#include "rangenam.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "stlsheet.hxx"
+#include "editutil.hxx"
+//CHINA001 #include "namecrea.hxx" // wegen Flags
+#include "cell.hxx"
+#include "scresid.hxx"
+#include "inputhdl.hxx"
+#include "scmod.hxx"
+#include "inputopt.hxx"
+#include "compiler.hxx"
+#include "docfunc.hxx"
+#include "appoptio.hxx"
+#include "dociter.hxx"
+#include "sizedev.hxx"
+#include "editable.hxx"
+#include "scui_def.hxx" //CHINA001
+#include "funcdesc.hxx"
+#include "docuno.hxx"
+#include "cellsuno.hxx"
+//==================================================================
+
+ScViewFunc::ScViewFunc( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
+ ScTabView( pParent, rDocSh, pViewShell ),
+ bFormatValid( sal_False )
+{
+}
+
+//UNUSED2008-05 ScViewFunc::ScViewFunc( Window* pParent, const ScViewFunc& rViewFunc, ScTabViewShell* pViewShell ) :
+//UNUSED2008-05 ScTabView( pParent, rViewFunc, pViewShell ),
+//UNUSED2008-05 bFormatValid( sal_False )
+//UNUSED2008-05 {
+//UNUSED2008-05 }
+
+ScViewFunc::~ScViewFunc()
+{
+}
+
+//------------------------------------------------------------------------------------
+
+void ScViewFunc::StartFormatArea()
+{
+ // ueberhaupt aktiviert?
+ if ( !SC_MOD()->GetInputOptions().GetExtendFormat() )
+ return;
+
+ // start only with single cell (marked or cursor position)
+ ScRange aMarkRange;
+ sal_Bool bOk = (GetViewData()->GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE);
+ if ( bOk && aMarkRange.aStart != aMarkRange.aEnd )
+ bOk = sal_False;
+
+ if (bOk)
+ {
+ bFormatValid = sal_True;
+ aFormatSource = aMarkRange.aStart;
+ aFormatArea = ScRange( aFormatSource );
+ }
+ else
+ bFormatValid = sal_False; // keinen alten Bereich behalten
+}
+
+sal_Bool ScViewFunc::TestFormatArea( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Bool bAttrChanged )
+{
+ // ueberhaupt aktiviert?
+ if ( !SC_MOD()->GetInputOptions().GetExtendFormat() )
+ return sal_False;
+
+ // Test: Eingabe mit Zahlformat (bAttrChanged) immer als neue Attributierung behandeln
+ // (alte Area verwerfen). Wenn das nicht gewollt ist, den if-Teil weglassen:
+ if ( bAttrChanged )
+ {
+ StartFormatArea();
+ return sal_False;
+ }
+
+ //! Abfrage, ob Zelle leer war ???
+
+ sal_Bool bFound = sal_False;
+ ScRange aNewRange = aFormatArea;
+ if ( bFormatValid && nTab == aFormatSource.Tab() )
+ {
+ if ( nRow >= aFormatArea.aStart.Row() && nRow <= aFormatArea.aEnd.Row() )
+ {
+ // innerhalb ?
+ if ( nCol >= aFormatArea.aStart.Col() && nCol <= aFormatArea.aEnd.Col() )
+ {
+ bFound = sal_True; // Bereich nicht aendern
+ }
+ // links ?
+ if ( nCol+1 == aFormatArea.aStart.Col() )
+ {
+ bFound = sal_True;
+ aNewRange.aStart.SetCol( nCol );
+ }
+ // rechts ?
+ if ( nCol == aFormatArea.aEnd.Col()+1 )
+ {
+ bFound = sal_True;
+ aNewRange.aEnd.SetCol( nCol );
+ }
+ }
+ if ( nCol >= aFormatArea.aStart.Col() && nCol <= aFormatArea.aEnd.Col() )
+ {
+ // oben ?
+ if ( nRow+1 == aFormatArea.aStart.Row() )
+ {
+ bFound = sal_True;
+ aNewRange.aStart.SetRow( nRow );
+ }
+ // unten ?
+ if ( nRow == aFormatArea.aEnd.Row()+1 )
+ {
+ bFound = sal_True;
+ aNewRange.aEnd.SetRow( nRow );
+ }
+ }
+ }
+
+ if (bFound)
+ aFormatArea = aNewRange; // erweitern
+ else
+ {
+ bFormatValid = sal_False; // ausserhalb -> abbrechen
+ if ( bAttrChanged ) // Wert mit Zahlformat eingegeben?
+ StartFormatArea(); // dann ggf. neu starten
+ }
+
+ return bFound;
+}
+
+void ScViewFunc::DoAutoAttributes( SCCOL nCol, SCROW nRow, SCTAB nTab,
+ sal_Bool bAttrChanged, sal_Bool bAddUndo )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ if (bAddUndo && !pDoc->IsUndoEnabled())
+ bAddUndo = sal_False;
+
+ const ScPatternAttr* pSource = pDoc->GetPattern(
+ aFormatSource.Col(), aFormatSource.Row(), nTab );
+ if ( !((const ScMergeAttr&)pSource->GetItem(ATTR_MERGE)).IsMerged() )
+ {
+ const ScPatternAttr* pDocOld = pDoc->GetPattern( nCol, nRow, nTab );
+ // pDocOld ist nur bis zum Apply... gueltig!
+
+ ScPatternAttr* pOldPattern = NULL;
+ if ( bAddUndo )
+ pOldPattern = new ScPatternAttr( *pDocOld );
+
+ const ScStyleSheet* pSrcStyle = pSource->GetStyleSheet();
+ if ( pSrcStyle && pSrcStyle != pDocOld->GetStyleSheet() )
+ pDoc->ApplyStyle( nCol, nRow, nTab, *pSrcStyle );
+ pDoc->ApplyPattern( nCol, nRow, nTab, *pSource );
+ AdjustRowHeight( nRow, nRow, sal_True ); //! nicht doppelt ?
+
+ if ( bAddUndo )
+ {
+ const ScPatternAttr* pNewPattern = pDoc->GetPattern( nCol, nRow, nTab );
+
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoCursorAttr( pDocSh, nCol, nRow, nTab,
+ pOldPattern, pNewPattern, pSource,
+ sal_True ) );
+
+ delete pOldPattern; // wird im Undo kopiert (Pool)
+ }
+ }
+
+ if ( bAttrChanged ) // Wert mit Zahlformat eingegeben?
+ aFormatSource.Set( nCol, nRow, nTab ); // dann als neue Quelle
+}
+
+//------------------------------------------------------------------------------------
+
+// Hilfsroutinen
+
+sal_uInt16 ScViewFunc::GetOptimalColWidth( SCCOL nCol, SCTAB nTab, sal_Bool bFormula )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+
+ double nPPTX = GetViewData()->GetPPTX();
+ double nPPTY = GetViewData()->GetPPTY();
+ Fraction aZoomX = GetViewData()->GetZoomX();
+ Fraction aZoomY = GetViewData()->GetZoomY();
+
+ ScSizeDeviceProvider aProv(pDocSh);
+ if (aProv.IsPrinter())
+ {
+ nPPTX = aProv.GetPPTX();
+ nPPTY = aProv.GetPPTY();
+ aZoomX = aZoomY = Fraction( 1, 1 );
+ }
+
+ sal_uInt16 nTwips = pDoc->GetOptimalColWidth( nCol, nTab, aProv.GetDevice(),
+ nPPTX, nPPTY, aZoomX, aZoomY, bFormula, &rMark );
+ return nTwips;
+}
+
+sal_Bool ScViewFunc::SelectionEditable( sal_Bool* pOnlyNotBecauseOfMatrix /* = NULL */ )
+{
+ sal_Bool bRet;
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ if (rMark.IsMarked() || rMark.IsMultiMarked())
+ bRet = pDoc->IsSelectionEditable( rMark, pOnlyNotBecauseOfMatrix );
+ else
+ {
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ bRet = pDoc->IsBlockEditable( nTab, nCol, nRow, nCol, nRow,
+ pOnlyNotBecauseOfMatrix );
+ }
+ return bRet;
+}
+
+#ifndef LRU_MAX
+#define LRU_MAX 10
+#endif
+
+sal_Bool lcl_FunctionKnown( sal_uInt16 nOpCode )
+{
+ const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
+ if ( pFuncList )
+ {
+ sal_uLong nCount = pFuncList->GetCount();
+ for (sal_uLong i=0; i<nCount; i++)
+ if ( pFuncList->GetFunction(i)->nFIndex == nOpCode )
+ return sal_True;
+ }
+ return sal_False;
+}
+
+sal_Bool lcl_AddFunction( ScAppOptions& rAppOpt, sal_uInt16 nOpCode )
+{
+ sal_uInt16 nOldCount = rAppOpt.GetLRUFuncListCount();
+ sal_uInt16* pOldList = rAppOpt.GetLRUFuncList();
+ sal_uInt16 nPos;
+ for (nPos=0; nPos<nOldCount; nPos++)
+ if (pOldList[nPos] == nOpCode) // is the function already in the list?
+ {
+ if ( nPos == 0 )
+ return sal_False; // already at the top -> no change
+
+ // count doesn't change, so the original array is modified
+
+ for (sal_uInt16 nCopy=nPos; nCopy>0; nCopy--)
+ pOldList[nCopy] = pOldList[nCopy-1];
+ pOldList[0] = nOpCode;
+
+ return sal_True; // list has changed
+ }
+
+ if ( !lcl_FunctionKnown( nOpCode ) )
+ return sal_False; // not in function list -> no change
+
+ sal_uInt16 nNewCount = Min( (sal_uInt16)(nOldCount + 1), (sal_uInt16)LRU_MAX );
+ sal_uInt16 nNewList[LRU_MAX];
+ nNewList[0] = nOpCode;
+ for (nPos=1; nPos<nNewCount; nPos++)
+ nNewList[nPos] = pOldList[nPos-1];
+ rAppOpt.SetLRUFuncList( nNewList, nNewCount );
+
+ return sal_True; // list has changed
+}
+
+// eigentliche Funktionen
+
+// Eingabe - Undo OK
+
+void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString,
+ sal_Bool bRecord, const EditTextObject* pData )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nSelCount = rMark.GetSelectCount();
+ SCTAB i;
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = sal_False;
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocShellModificator aModificator( *pDocSh );
+
+ ScEditableTester aTester( pDoc, nCol,nRow, nCol,nRow, rMark );
+ if (aTester.IsEditable())
+ {
+ sal_Bool bEditDeleted = sal_False;
+ sal_uInt8 nOldScript = 0;
+
+ ScBaseCell** ppOldCells = NULL;
+ sal_Bool* pHasFormat = NULL;
+ sal_uLong* pOldFormats = NULL;
+ SCTAB* pTabs = NULL;
+ SCTAB nUndoPos = 0;
+ EditTextObject* pUndoData = NULL;
+ if ( bRecord )
+ {
+ ppOldCells = new ScBaseCell*[nSelCount];
+ pHasFormat = new sal_Bool[nSelCount];
+ pOldFormats = new sal_uLong[nSelCount];
+ pTabs = new SCTAB[nSelCount];
+ nUndoPos = 0;
+
+ for (i=0; i<nTabCount; i++)
+ if (rMark.GetTableSelect(i))
+ {
+ pTabs[nUndoPos] = i;
+ ScBaseCell* pDocCell;
+ pDoc->GetCell( nCol, nRow, i, pDocCell );
+ if ( pDocCell )
+ {
+ ppOldCells[nUndoPos] = pDocCell->CloneWithoutNote( *pDoc );
+ if ( pDocCell->GetCellType() == CELLTYPE_EDIT )
+ bEditDeleted = sal_True;
+
+ sal_uInt8 nDocScript = pDoc->GetScriptType( nCol, nRow, i, pDocCell );
+ if ( nOldScript == 0 )
+ nOldScript = nDocScript;
+ else if ( nDocScript != nOldScript )
+ bEditDeleted = sal_True;
+ }
+ else
+ {
+ ppOldCells[nUndoPos] = NULL;
+ }
+
+ const SfxPoolItem* pItem;
+ const ScPatternAttr* pPattern = pDoc->GetPattern(nCol, nRow, i);
+ if ( SFX_ITEM_SET == pPattern->GetItemSet().GetItemState(
+ ATTR_VALUE_FORMAT,sal_False,&pItem) )
+ {
+ pHasFormat[nUndoPos] = sal_True;
+ pOldFormats[nUndoPos] = ((const SfxUInt32Item*)pItem)->GetValue();
+ }
+ else
+ pHasFormat[nUndoPos] = sal_False;
+
+ ++nUndoPos;
+ }
+
+ DBG_ASSERT( nUndoPos==nSelCount, "nUndoPos!=nSelCount" );
+
+ pUndoData = ( pData ? pData->Clone() : NULL );
+ }
+
+ bool bFormula = false;
+
+ // a single '=' character is handled as string (needed for special filters)
+ if ( rString.Len() > 1 )
+ {
+ if ( rString.GetChar(0) == '=' )
+ {
+ // handle as formula
+ bFormula = true;
+ }
+ else if ( rString.GetChar(0) == '+' || rString.GetChar(0) == '-' )
+ {
+ // if there is more than one leading '+' or '-' character, remove the additional ones
+ String aString( rString );
+ xub_StrLen nIndex = 1;
+ xub_StrLen nLen = aString.Len();
+ while ( nIndex < nLen && ( aString.GetChar( nIndex ) == '+' || aString.GetChar( nIndex ) == '-' ) )
+ {
+ ++nIndex;
+ }
+ aString.Erase( 1, nIndex - 1 );
+
+ // if the remaining part without the leading '+' or '-' character
+ // is non-empty and not a number, handle as formula
+ if ( aString.Len() > 1 )
+ {
+ sal_uInt32 nFormat = 0;
+ pDoc->GetNumberFormat( nCol, nRow, nTab, nFormat );
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ double fNumber = 0;
+ if ( !pFormatter->IsNumberFormat( aString, nFormat, fNumber ) )
+ {
+ bFormula = true;
+ }
+ }
+ }
+ }
+
+ sal_Bool bNumFmtChanged = sal_False;
+ if ( bFormula )
+ { // Formel, compile mit AutoCorrection
+ for (i=0; i<nTabCount; i++)
+ if (rMark.GetTableSelect(i))
+ break;
+ ScAddress aPos( nCol, nRow, i );
+ ScCompiler aComp( pDoc, aPos);
+ aComp.SetGrammar(pDoc->GetGrammar());
+//2do: AutoCorrection via CalcOptions abschaltbar machen
+ aComp.SetAutoCorrection( sal_True );
+ if ( rString.GetChar(0) == '+' || rString.GetChar(0) == '-' )
+ {
+ aComp.SetExtendedErrorDetection( true );
+ }
+ String aFormula( rString );
+ ScTokenArray* pArr;
+ sal_Bool bAgain;
+ do
+ {
+ bAgain = sal_False;
+ sal_Bool bAddEqual = sal_False;
+ ScTokenArray* pArrFirst = pArr = aComp.CompileString( aFormula );
+ sal_Bool bCorrected = aComp.IsCorrected();
+ if ( bCorrected )
+ { // probieren, mit erster Parser-Korrektur neu zu parsen
+ pArr = aComp.CompileString( aComp.GetCorrectedFormula() );
+ }
+ if ( !pArr->GetCodeError() )
+ {
+ bAddEqual = sal_True;
+ aComp.CompileTokenArray();
+ bCorrected |= aComp.IsCorrected();
+ }
+ if ( bCorrected )
+ {
+ String aCorrectedFormula;
+ if ( bAddEqual )
+ {
+ aCorrectedFormula = '=';
+ aCorrectedFormula += aComp.GetCorrectedFormula();
+ }
+ else
+ aCorrectedFormula = aComp.GetCorrectedFormula();
+ short nResult;
+ if ( aCorrectedFormula.Len() == 1 )
+ nResult = RET_NO; // leere Formel, nur '='
+ else
+ {
+ String aMessage( ScResId( SCSTR_FORMULA_AUTOCORRECTION ) );
+ aMessage += aCorrectedFormula;
+ nResult = QueryBox( GetViewData()->GetDialogParent(),
+ WinBits(WB_YES_NO | WB_DEF_YES),
+ aMessage ).Execute();
+ }
+ if ( nResult == RET_YES )
+ {
+ aFormula = aCorrectedFormula;
+ if ( pArr != pArrFirst )
+ delete pArrFirst;
+ bAgain = sal_True;
+ }
+ else
+ {
+ if ( pArr != pArrFirst )
+ {
+ delete pArr;
+ pArr = pArrFirst;
+ }
+ }
+ }
+ } while ( bAgain );
+ // um in mehreren Tabellen eingesetzt zu werden, muss die Formel
+ // via ScFormulaCell copy-ctor evtl. wegen RangeNames neu kompiliert
+ // werden, gleiches Code-Array fuer alle Zellen geht nicht.
+ // Wenn das Array einen Fehler enthaelt, muss in den neu erzeugten
+ // Zellen RPN geloescht und der Fehler explizit gesetzt werden, da
+ // via FormulaCell copy-ctor und Interpreter das, wenn moeglich,
+ // wieder glattgebuegelt wird, zu intelligent.. z.B.: =1))
+ sal_uInt16 nError = pArr->GetCodeError();
+ if ( !nError )
+ {
+ // #68693# update list of recent functions with all functions that
+ // are not within parentheses
+
+ ScModule* pScMod = SC_MOD();
+ ScAppOptions aAppOpt = pScMod->GetAppOptions();
+ sal_Bool bOptChanged = sal_False;
+
+ formula::FormulaToken** ppToken = pArr->GetArray();
+ sal_uInt16 nTokens = pArr->GetLen();
+ sal_uInt16 nLevel = 0;
+ for (sal_uInt16 nTP=0; nTP<nTokens; nTP++)
+ {
+ formula::FormulaToken* pTok = ppToken[nTP];
+ OpCode eOp = pTok->GetOpCode();
+ if ( eOp == ocOpen )
+ ++nLevel;
+ else if ( eOp == ocClose && nLevel )
+ --nLevel;
+ if ( nLevel == 0 && pTok->IsFunction() &&
+ lcl_AddFunction( aAppOpt, sal::static_int_cast<sal_uInt16>( eOp ) ) )
+ bOptChanged = sal_True;
+ }
+
+ if ( bOptChanged )
+ {
+ pScMod->SetAppOptions(aAppOpt);
+ pScMod->RecentFunctionsChanged();
+ }
+ }
+
+ ScFormulaCell aCell( pDoc, aPos, pArr,formula::FormulaGrammar::GRAM_DEFAULT, MM_NONE );
+ delete pArr;
+ sal_Bool bAutoCalc = pDoc->GetAutoCalc();
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ for ( ; i<nTabCount; i++)
+ {
+ if (rMark.GetTableSelect(i))
+ {
+ aPos.SetTab( i );
+ sal_uLong nIndex = (sal_uLong) ((SfxUInt32Item*) pDoc->GetAttr(
+ nCol, nRow, i, ATTR_VALUE_FORMAT ))->GetValue();
+ if ( pFormatter->GetType( nIndex ) == NUMBERFORMAT_TEXT ||
+ ( ( rString.GetChar(0) == '+' || rString.GetChar(0) == '-' ) && nError && rString.Equals( aFormula ) ) )
+ {
+ if ( pData )
+ {
+ ScEditCell* pCell = new ScEditCell( pData, pDoc, NULL );
+ pDoc->PutCell( aPos, pCell );
+ }
+ else
+ {
+ ScStringCell* pCell = new ScStringCell( aFormula );
+ pDoc->PutCell( aPos, pCell );
+ }
+ }
+ else
+ {
+ DELETEZ(pUndoData);
+ ScFormulaCell* pCell = new ScFormulaCell( aCell, *pDoc, aPos );
+ if ( nError )
+ {
+ pCell->GetCode()->DelRPN();
+ pCell->SetErrCode( nError );
+ if(pCell->GetCode()->IsHyperLink())
+ pCell->GetCode()->SetHyperLink(sal_False);
+ }
+ pDoc->PutCell( aPos, pCell );
+ if ( !bAutoCalc )
+ { // einmal nur die Zelle berechnen und wieder dirty setzen
+ pCell->Interpret();
+ pCell->SetDirtyVar();
+ pDoc->PutInFormulaTree( pCell );
+ }
+ }
+
+ }
+ }
+ }
+ else
+ {
+ for (i=0; i<nTabCount; i++)
+ if (rMark.GetTableSelect(i))
+ if (pDoc->SetString( nCol, nRow, i, rString ))
+ bNumFmtChanged = sal_True;
+ }
+
+ // row height must be changed if new text has a different script type
+ for (i=0; i<nTabCount && !bEditDeleted; i++)
+ if (rMark.GetTableSelect(i))
+ if ( pDoc->GetScriptType( nCol, nRow, i ) != nOldScript )
+ bEditDeleted = sal_True;
+
+ HideAllCursors();
+
+ if (bEditDeleted || pDoc->HasAttrib( nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_NEEDHEIGHT ))
+ AdjustRowHeight(nRow,nRow);
+
+ sal_Bool bAutoFormat = TestFormatArea(nCol, nRow, nTab, bNumFmtChanged);
+ if (bAutoFormat)
+ DoAutoAttributes(nCol, nRow, nTab, bNumFmtChanged, bRecord);
+
+ if ( bRecord )
+ { // wg. ChangeTrack erst jetzt
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoEnterData( pDocSh, nCol, nRow, nTab, nUndoPos, pTabs,
+ ppOldCells, pHasFormat, pOldFormats,
+ rString, pUndoData ) );
+ }
+
+ for (i=0; i<nTabCount; i++)
+ if (rMark.GetTableSelect(i))
+ pDocSh->PostPaintCell( nCol, nRow, i );
+
+ ShowAllCursors();
+
+ pDocSh->UpdateOle(GetViewData());
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ for ( i = 0; i < nTabCount; ++i )
+ {
+ if ( rMark.GetTableSelect( i ) )
+ {
+ aChangeRanges.Append( ScRange( nCol, nRow, i ) );
+ }
+ }
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+ }
+
+ aModificator.SetDocumentModified();
+ }
+ else
+ {
+ ErrorMessage(aTester.GetMessageId());
+ PaintArea( nCol, nRow, nCol, nRow ); // da steht evtl. noch die Edit-Engine
+ }
+}
+
+// Wert in einzele Zelle eintragen (nur auf nTab)
+
+void ScViewFunc::EnterValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rValue )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ sal_Bool bUndo (pDoc->IsUndoEnabled());
+
+ if ( pDoc && pDocSh )
+ {
+ ScDocShellModificator aModificator( *pDocSh );
+
+ ScEditableTester aTester( pDoc, nTab, nCol,nRow, nCol,nRow );
+ if (aTester.IsEditable())
+ {
+ ScAddress aPos( nCol, nRow, nTab );
+ ScBaseCell* pOldCell = pDoc->GetCell( aPos );
+ sal_Bool bNeedHeight = ( pOldCell && pOldCell->GetCellType() == CELLTYPE_EDIT )
+ || pDoc->HasAttrib(
+ nCol,nRow,nTab, nCol,nRow,nTab, HASATTR_NEEDHEIGHT );
+
+ // Undo
+ ScBaseCell* pUndoCell = (bUndo && pOldCell) ? pOldCell->CloneWithoutNote( *pDoc ) : 0;
+
+ pDoc->SetValue( nCol, nRow, nTab, rValue );
+
+ // wg. ChangeTrack nach Aenderung im Dokument
+ if (bUndo)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoEnterValue( pDocSh, aPos, pUndoCell, rValue, bNeedHeight ) );
+ }
+
+/*! Zeilenhoehe anpassen? Dann auch bei Undo...
+ if (bNeedHeight)
+ AdjustRowHeight(nRow,nRow);
+*/
+
+ pDocSh->PostPaintCell( aPos );
+ pDocSh->UpdateOle(GetViewData());
+ aModificator.SetDocumentModified();
+ }
+ else
+ ErrorMessage(aTester.GetMessageId());
+ }
+}
+
+void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, const EditTextObject* pData,
+ sal_Bool bRecord, sal_Bool bTestSimple )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = sal_False;
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ ScEditableTester aTester( pDoc, nTab, nCol,nRow, nCol,nRow );
+ if (aTester.IsEditable())
+ {
+ //
+ // Test auf Attribute
+ //
+ sal_Bool bSimple = sal_False;
+ sal_Bool bCommon = sal_False;
+ ScPatternAttr* pCellAttrs = NULL;
+ EditTextObject* pNewData = NULL;
+ String aString;
+
+ const ScPatternAttr* pOldPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ ScTabEditEngine aEngine( *pOldPattern, pDoc->GetEnginePool() );
+ aEngine.SetText(*pData);
+
+ if (bTestSimple) // Testen, ob einfacher String ohne Attribute
+ {
+ ScEditAttrTester aAttrTester( &aEngine );
+ bSimple = !aAttrTester.NeedsObject();
+ bCommon = aAttrTester.NeedsCellAttr();
+
+ // formulas have to be recognized even if they're formatted
+ // (but commmon attributes are still collected)
+
+ if ( !bSimple && aEngine.GetParagraphCount() == 1 )
+ {
+ String aParStr = aEngine.GetText( (sal_uInt16) 0 );
+ if ( aParStr.GetChar(0) == '=' )
+ bSimple = sal_True;
+ }
+
+ if (bCommon) // Attribute fuer Tabelle
+ {
+ pCellAttrs = new ScPatternAttr( *pOldPattern );
+ pCellAttrs->GetFromEditItemSet( &aAttrTester.GetAttribs() );
+ //! remove common attributes from EditEngine?
+ }
+ }
+
+ // #i97726# always get text for "repeat" of undo action
+ aString = ScEditUtil::GetSpaceDelimitedString(aEngine);
+
+ //
+ // Undo
+ //
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nSelCount = rMark.GetSelectCount();
+ SCTAB i;
+ ScBaseCell** ppOldCells = NULL;
+ SCTAB* pTabs = NULL;
+ SCTAB nPos = 0;
+ EditTextObject* pUndoData = NULL;
+ if (bRecord && !bSimple)
+ {
+ ppOldCells = new ScBaseCell*[nSelCount];
+ pTabs = new SCTAB[nSelCount];
+ nPos = 0;
+
+ for (i=0; i<nTabCount; i++)
+ if (rMark.GetTableSelect(i))
+ {
+ pTabs[nPos] = i;
+ ScBaseCell* pDocCell;
+ pDoc->GetCell( nCol, nRow, i, pDocCell );
+ ppOldCells[nPos] = pDocCell ? pDocCell->CloneWithoutNote( *pDoc ) : 0;
+ ++nPos;
+ }
+
+ DBG_ASSERT( nPos==nSelCount, "nPos!=nSelCount" );
+
+ pUndoData = pData->Clone();
+ }
+
+ //
+ // Daten eintragen
+ //
+
+ if (bCommon)
+ pDoc->ApplyPattern(nCol,nRow,nTab,*pCellAttrs); //! Undo
+
+ if (bSimple)
+ {
+ if (bCommon)
+ AdjustRowHeight(nRow,nRow);
+
+ EnterData(nCol,nRow,nTab,aString,bRecord);
+ }
+ else
+ {
+ for (i=0; i<nTabCount; i++)
+ if (rMark.GetTableSelect(i))
+ pDoc->PutCell( nCol, nRow, i, new ScEditCell( pData, pDoc, NULL ) );
+
+ if ( bRecord )
+ { // wg. ChangeTrack erst jetzt
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoEnterData( pDocSh, nCol, nRow, nTab, nPos, pTabs,
+ ppOldCells, NULL, NULL, aString,
+ pUndoData ) );
+ }
+
+ HideAllCursors();
+
+ AdjustRowHeight(nRow,nRow);
+
+ for (i=0; i<nTabCount; i++)
+ if (rMark.GetTableSelect(i))
+ pDocSh->PostPaintCell( nCol, nRow, i );
+
+ ShowAllCursors();
+
+ pDocSh->UpdateOle(GetViewData());
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ for ( i = 0; i < nTabCount; ++i )
+ {
+ if ( rMark.GetTableSelect( i ) )
+ {
+ aChangeRanges.Append( ScRange( nCol, nRow, i ) );
+ }
+ }
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+ }
+
+ aModificator.SetDocumentModified();
+ }
+
+ delete pCellAttrs;
+ delete pNewData;
+ }
+ else
+ {
+ ErrorMessage(aTester.GetMessageId());
+ PaintArea( nCol, nRow, nCol, nRow ); // da steht evtl. noch die Edit-Engine
+ }
+}
+
+void ScViewFunc::EnterDataAtCursor( const String& rString )
+{
+ SCCOL nPosX = GetViewData()->GetCurX();
+ SCROW nPosY = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ EnterData( nPosX, nPosY, nTab, rString );
+}
+
+void ScViewFunc::EnterMatrix( const String& rString )
+{
+ ScViewData* pData = GetViewData();
+ const ScMarkData& rMark = pData->GetMarkData();
+ if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
+ {
+ // nichts markiert -> automatisch Block mit Groesse des Ergebnisses
+ // Formel temporaer berechnen, um an die Groesse heranzukommen
+
+ ScDocument* pDoc = pData->GetDocument();
+ SCCOL nCol = pData->GetCurX();
+ SCROW nRow = pData->GetCurY();
+ SCTAB nTab = pData->GetTabNo();
+ ScFormulaCell aFormCell( pDoc, ScAddress(nCol,nRow,nTab), rString,formula::FormulaGrammar::GRAM_DEFAULT, MM_FORMULA );
+
+ SCSIZE nSizeX;
+ SCSIZE nSizeY;
+ aFormCell.GetResultDimensions( nSizeX, nSizeY );
+ if ( nSizeX != 0 && nSizeY != 0 &&
+ nCol+nSizeX-1 <= sal::static_int_cast<SCSIZE>(MAXCOL) &&
+ nRow+nSizeY-1 <= sal::static_int_cast<SCSIZE>(MAXROW) )
+ {
+ ScRange aResult( nCol, nRow, nTab,
+ sal::static_int_cast<SCCOL>(nCol+nSizeX-1),
+ sal::static_int_cast<SCROW>(nRow+nSizeY-1), nTab );
+ MarkRange( aResult, sal_False );
+ }
+ }
+
+ ScRange aRange;
+ if (pData->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = pData->GetDocShell();
+ sal_Bool bSuccess = pDocSh->GetDocFunc().EnterMatrix( aRange, &rMark, NULL, rString, sal_False, sal_False, EMPTY_STRING, formula::FormulaGrammar::GRAM_DEFAULT );
+ if (bSuccess)
+ pDocSh->UpdateOle(GetViewData());
+ }
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+}
+
+sal_uInt8 ScViewFunc::GetSelectionScriptType()
+{
+ sal_uInt8 nScript = 0;
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
+ {
+ // no selection -> cursor
+
+ nScript = pDoc->GetScriptType( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ }
+ else
+ {
+ ScRangeList aRanges;
+ rMark.FillRangeListWithMarks( &aRanges, sal_False );
+ sal_uLong nCount = aRanges.Count();
+ for (sal_uLong i=0; i<nCount; i++)
+ {
+ ScRange aRange = *aRanges.GetObject(i);
+ ScCellIterator aIter( pDoc, aRange );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while ( pCell )
+ {
+ nScript |= pDoc->GetScriptType( aIter.GetCol(), aIter.GetRow(), aIter.GetTab(), pCell );
+ pCell = aIter.GetNext();
+ }
+ }
+ }
+
+ if (nScript == 0)
+ nScript = ScGlobal::GetDefaultScriptType();
+
+ return nScript;
+}
+
+const ScPatternAttr* ScViewFunc::GetSelectionPattern()
+{
+ // Don't use UnmarkFiltered in slot state functions, for performance reasons.
+ // The displayed state is always that of the whole selection including filtered rows.
+
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ {
+ // MarkToMulti is no longer necessary for pDoc->GetSelectionPattern
+ const ScPatternAttr* pAttr = pDoc->GetSelectionPattern( rMark );
+ return pAttr;
+ }
+ else
+ {
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ ScMarkData aTempMark( rMark ); // copy sheet selection
+ aTempMark.SetMarkArea( ScRange( nCol, nRow, nTab ) );
+ const ScPatternAttr* pAttr = pDoc->GetSelectionPattern( aTempMark );
+ return pAttr;
+ }
+}
+
+void ScViewFunc::GetSelectionFrame( SvxBoxItem& rLineOuter,
+ SvxBoxInfoItem& rLineInner )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ {
+ if ( rMark.IsMultiMarked() )
+ {
+ ScMarkData aNewMark( rMark ); // use local copy for MarkToSimple
+ aNewMark.MarkToSimple(); // simple block is needed for GetSelectionFrame
+ pDoc->GetSelectionFrame( aNewMark, rLineOuter, rLineInner );
+ }
+ else
+ pDoc->GetSelectionFrame( rMark, rLineOuter, rLineInner );
+ }
+ else
+ {
+ const ScPatternAttr* pAttrs =
+ pDoc->GetPattern( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(),
+ GetViewData()->GetTabNo() );
+
+ rLineOuter = (const SvxBoxItem&) (pAttrs->GetItem( ATTR_BORDER ));
+ rLineInner = (const SvxBoxInfoItem&)(pAttrs->GetItem( ATTR_BORDER_INNER ));
+ rLineInner.SetTable(sal_False);
+ rLineInner.SetDist(sal_True);
+ rLineInner.SetMinDist(sal_False);
+ }
+}
+
+//
+// Attribute anwenden - Undo OK
+//
+// kompletter Set ( ATTR_STARTINDEX, ATTR_ENDINDEX )
+//
+
+void ScViewFunc::ApplyAttributes( const SfxItemSet* pDialogSet,
+ const SfxItemSet* pOldSet,
+ sal_Bool bRecord )
+{
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ sal_Bool bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ ScPatternAttr aOldAttrs( new SfxItemSet(*pOldSet) );
+ ScPatternAttr aNewAttrs( new SfxItemSet(*pDialogSet) );
+ aNewAttrs.DeleteUnchanged( &aOldAttrs );
+
+ if ( pDialogSet->GetItemState( ATTR_VALUE_FORMAT ) == SFX_ITEM_SET )
+ { // #82521# don't reset to default SYSTEM GENERAL if not intended
+ sal_uInt32 nOldFormat =
+ ((const SfxUInt32Item&)pOldSet->Get( ATTR_VALUE_FORMAT )).GetValue();
+ sal_uInt32 nNewFormat =
+ ((const SfxUInt32Item&)pDialogSet->Get( ATTR_VALUE_FORMAT )).GetValue();
+ if ( nNewFormat != nOldFormat )
+ {
+ SvNumberFormatter* pFormatter =
+ GetViewData()->GetDocument()->GetFormatTable();
+ const SvNumberformat* pOldEntry = pFormatter->GetEntry( nOldFormat );
+ LanguageType eOldLang =
+ pOldEntry ? pOldEntry->GetLanguage() : LANGUAGE_DONTKNOW;
+ const SvNumberformat* pNewEntry = pFormatter->GetEntry( nNewFormat );
+ LanguageType eNewLang =
+ pNewEntry ? pNewEntry->GetLanguage() : LANGUAGE_DONTKNOW;
+ if ( eNewLang != eOldLang )
+ {
+ aNewAttrs.GetItemSet().Put(
+ SvxLanguageItem( eNewLang, ATTR_LANGUAGE_FORMAT ) );
+
+ // #40606# nur die Sprache geaendert -> Zahlformat-Attribut nicht anfassen
+ sal_uInt32 nNewMod = nNewFormat % SV_COUNTRY_LANGUAGE_OFFSET;
+ if ( nNewMod == ( nOldFormat % SV_COUNTRY_LANGUAGE_OFFSET ) &&
+ nNewMod <= SV_MAX_ANZ_STANDARD_FORMATE )
+ aNewAttrs.GetItemSet().ClearItem( ATTR_VALUE_FORMAT );
+ }
+ }
+ }
+
+ const SvxBoxItem* pOldOuter = (const SvxBoxItem*) &pOldSet->Get( ATTR_BORDER );
+ const SvxBoxItem* pNewOuter = (const SvxBoxItem*) &pDialogSet->Get( ATTR_BORDER );
+ const SvxBoxInfoItem* pOldInner = (const SvxBoxInfoItem*) &pOldSet->Get( ATTR_BORDER_INNER );
+ const SvxBoxInfoItem* pNewInner = (const SvxBoxInfoItem*) &pDialogSet->Get( ATTR_BORDER_INNER );
+ SfxItemSet& rNewSet = aNewAttrs.GetItemSet();
+ SfxItemPool* pNewPool = rNewSet.GetPool();
+
+ pNewPool->Put( *pNewOuter ); // noch nicht loeschen
+ pNewPool->Put( *pNewInner );
+ rNewSet.ClearItem( ATTR_BORDER );
+ rNewSet.ClearItem( ATTR_BORDER_INNER );
+
+ /*
+ * Feststellen, ob Rahmenattribute zu setzen sind:
+ * 1. Neu != Alt
+ * 2. Ist eine der Linien nicht-DontCare (seit 238.f: IsxxValid())
+ *
+ */
+
+ sal_Bool bFrame = (pDialogSet->GetItemState( ATTR_BORDER ) != SFX_ITEM_DEFAULT)
+ || (pDialogSet->GetItemState( ATTR_BORDER_INNER ) != SFX_ITEM_DEFAULT);
+
+ if ( pNewOuter==pOldOuter && pNewInner==pOldInner )
+ bFrame = sal_False;
+
+ // das sollte doch der Pool abfangen: ?!??!??
+
+ if ( bFrame && pNewOuter && pNewInner )
+ if ( *pNewOuter == *pOldOuter && *pNewInner == *pOldInner )
+ bFrame = sal_False;
+
+ if ( pNewInner )
+ {
+ bFrame = bFrame
+ && ( pNewInner->IsValid(VALID_LEFT)
+ || pNewInner->IsValid(VALID_RIGHT)
+ || pNewInner->IsValid(VALID_TOP)
+ || pNewInner->IsValid(VALID_BOTTOM)
+ || pNewInner->IsValid(VALID_HORI)
+ || pNewInner->IsValid(VALID_VERT) );
+ }
+ else
+ bFrame = sal_False;
+
+ if (!bFrame)
+ ApplySelectionPattern( aNewAttrs, bRecord ); // nur normale
+ else
+ {
+ // wenn neue Items Default-Items sind, so muessen die
+ // alten Items geputtet werden:
+
+ sal_Bool bDefNewOuter = ( SFX_ITEMS_STATICDEFAULT == pNewOuter->GetKind() );
+ sal_Bool bDefNewInner = ( SFX_ITEMS_STATICDEFAULT == pNewInner->GetKind() );
+
+ ApplyPatternLines( aNewAttrs,
+ bDefNewOuter ? pOldOuter : pNewOuter,
+ bDefNewInner ? pOldInner : pNewInner,
+ bRecord );
+ }
+
+ pNewPool->Remove( *pNewOuter ); // freigeben
+ pNewPool->Remove( *pNewInner );
+
+ // Hoehen anpassen
+ AdjustBlockHeight();
+
+ // CellContentChanged wird von ApplySelectionPattern / ApplyPatternLines gerufen
+}
+
+void ScViewFunc::ApplyAttr( const SfxPoolItem& rAttrItem )
+{
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ sal_Bool bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ ScPatternAttr aNewAttrs( new SfxItemSet( *GetViewData()->GetDocument()->GetPool(),
+ ATTR_PATTERN_START, ATTR_PATTERN_END ) );
+
+ aNewAttrs.GetItemSet().Put( rAttrItem );
+ // Wenn Ausrichtung eingestellt wird (ueber Buttons), immer Einzug 0
+ if ( rAttrItem.Which() == ATTR_HOR_JUSTIFY )
+ aNewAttrs.GetItemSet().Put( SfxUInt16Item( ATTR_INDENT, 0 ) );
+ ApplySelectionPattern( aNewAttrs );
+
+ AdjustBlockHeight();
+
+ // CellContentChanged wird von ApplySelectionPattern gerufen
+}
+
+
+// Pattern und Rahmen
+
+void ScViewFunc::ApplyPatternLines( const ScPatternAttr& rAttr, const SvxBoxItem* pNewOuter,
+ const SvxBoxInfoItem* pNewInner, sal_Bool bRecord )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
+ ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = sal_False;
+
+ ScRange aMarkRange;
+ aFuncMark.MarkToSimple();
+ sal_Bool bMulti = aFuncMark.IsMultiMarked();
+ if (bMulti)
+ aFuncMark.GetMultiMarkArea( aMarkRange );
+ else if (aFuncMark.IsMarked())
+ aFuncMark.GetMarkArea( aMarkRange );
+ else
+ {
+ aMarkRange = ScRange( GetViewData()->GetCurX(),
+ GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ DoneBlockMode();
+ InitOwnBlockMode();
+ aFuncMark.SetMarkArea(aMarkRange);
+ MarkDataChanged();
+ }
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ if (bRecord)
+ {
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ SCTAB nStartTab = aMarkRange.aStart.Tab();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab );
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (i != nStartTab && aFuncMark.GetTableSelect(i))
+ pUndoDoc->AddUndoTab( i, i );
+
+ ScRange aCopyRange = aMarkRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, bMulti, pUndoDoc, &aFuncMark );
+
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoSelectionAttr(
+ pDocSh, aFuncMark,
+ aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), aMarkRange.aStart.Tab(),
+ aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), aMarkRange.aEnd.Tab(),
+ pUndoDoc, bMulti, &rAttr, pNewOuter, pNewInner ) );
+ }
+
+ sal_uInt16 nExt = SC_PF_TESTMERGE;
+ pDocSh->UpdatePaintExt( nExt, aMarkRange ); // content before the change
+
+ pDoc->ApplySelectionFrame( aFuncMark, pNewOuter, pNewInner );
+
+ pDocSh->UpdatePaintExt( nExt, aMarkRange ); // content after the change
+
+ aFuncMark.MarkToMulti();
+ pDoc->ApplySelectionPattern( rAttr, aFuncMark );
+
+ pDocSh->PostPaint( aMarkRange, PAINT_GRID, nExt );
+ pDocSh->UpdateOle(GetViewData());
+ aModificator.SetDocumentModified();
+ CellContentChanged();
+
+ StartFormatArea();
+}
+
+// nur Pattern
+
+void ScViewFunc::ApplySelectionPattern( const ScPatternAttr& rAttr,
+ sal_Bool bRecord, sal_Bool bCursorOnly )
+{
+ ScViewData* pViewData = GetViewData();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData aFuncMark( pViewData->GetMarkData() ); // local copy for UnmarkFiltered
+ ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = sal_False;
+
+ // State from old ItemSet doesn't matter for paint flags, as any change will be
+ // from SFX_ITEM_SET in the new ItemSet (default is ignored in ApplyPattern).
+ // New alignment is checked (check in PostPaint isn't enough) in case a right
+ // alignment is changed to left.
+ const SfxItemSet& rNewSet = rAttr.GetItemSet();
+ sal_Bool bSetLines = rNewSet.GetItemState( ATTR_BORDER, sal_True ) == SFX_ITEM_SET ||
+ rNewSet.GetItemState( ATTR_SHADOW, sal_True ) == SFX_ITEM_SET;
+ sal_Bool bSetAlign = rNewSet.GetItemState( ATTR_HOR_JUSTIFY, sal_True ) == SFX_ITEM_SET;
+
+ sal_uInt16 nExtFlags = 0;
+ if ( bSetLines )
+ nExtFlags |= SC_PF_LINES;
+ if ( bSetAlign )
+ nExtFlags |= SC_PF_WHOLEROWS;
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ sal_Bool bMulti = aFuncMark.IsMultiMarked();
+ aFuncMark.MarkToMulti();
+ sal_Bool bOnlyTab = (!aFuncMark.IsMultiMarked() && !bCursorOnly && aFuncMark.GetSelectCount() > 1);
+ if (bOnlyTab)
+ {
+ SCCOL nCol = pViewData->GetCurX();
+ SCROW nRow = pViewData->GetCurY();
+ SCTAB nTab = pViewData->GetTabNo();
+ aFuncMark.SetMarkArea(ScRange(nCol,nRow,nTab));
+ aFuncMark.MarkToMulti();
+ }
+
+ ScRangeList aChangeRanges;
+
+ if (aFuncMark.IsMultiMarked() && !bCursorOnly)
+ {
+ ScRange aMarkRange;
+ aFuncMark.GetMultiMarkArea( aMarkRange );
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for ( SCTAB i = 0; i < nTabCount; ++i )
+ {
+ if ( aFuncMark.GetTableSelect( i ) )
+ {
+ ScRange aChangeRange( aMarkRange );
+ aChangeRange.aStart.SetTab( i );
+ aChangeRange.aEnd.SetTab( i );
+ aChangeRanges.Append( aChangeRange );
+ }
+ }
+
+ SCCOL nStartCol = aMarkRange.aStart.Col();
+ SCROW nStartRow = aMarkRange.aStart.Row();
+ SCTAB nStartTab = aMarkRange.aStart.Tab();
+ SCCOL nEndCol = aMarkRange.aEnd.Col();
+ SCROW nEndRow = aMarkRange.aEnd.Row();
+ SCTAB nEndTab = aMarkRange.aEnd.Tab();
+
+ if (bRecord)
+ {
+ ScRange aCopyRange = aMarkRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab );
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (i != nStartTab && aFuncMark.GetTableSelect(i))
+ pUndoDoc->AddUndoTab( i, i );
+ pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, bMulti, pUndoDoc, &aFuncMark );
+
+ aFuncMark.MarkToMulti();
+
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoSelectionAttr(
+ pDocSh, aFuncMark,
+ nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab,
+ pUndoDoc, bMulti, &rAttr ) );
+ }
+
+ pDoc->ApplySelectionPattern( rAttr, aFuncMark );
+
+ pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
+ nEndCol, nEndRow, nEndTab,
+ PAINT_GRID, nExtFlags | SC_PF_TESTMERGE );
+ pDocSh->UpdateOle(GetViewData());
+ aModificator.SetDocumentModified();
+ CellContentChanged();
+ }
+ else // einzelne Zelle - Undo einfacher
+ {
+ SCCOL nCol = pViewData->GetCurX();
+ SCROW nRow = pViewData->GetCurY();
+ SCTAB nTab = pViewData->GetTabNo();
+ aChangeRanges.Append( ScRange( nCol, nRow, nTab ) );
+ ScPatternAttr* pOldPat = new ScPatternAttr(*pDoc->GetPattern( nCol, nRow, nTab ));
+
+ pDoc->ApplyPattern( nCol, nRow, nTab, rAttr );
+
+ const ScPatternAttr* pNewPat = pDoc->GetPattern( nCol, nRow, nTab );
+
+ if (bRecord)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoCursorAttr( pDocSh,
+ nCol, nRow, nTab,
+ pOldPat, pNewPat, &rAttr,
+ sal_False ) ); // sal_False = nicht automatisch
+ }
+ delete pOldPat; // wird im Undo kopiert (Pool)
+
+ pDocSh->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID, nExtFlags | SC_PF_TESTMERGE );
+ pDocSh->UpdateOle(GetViewData());
+ aModificator.SetDocumentModified();
+ CellContentChanged();
+ }
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aProperties;
+ sal_Int32 nCount = 0;
+ const SfxItemPropertyMap* pMap = ScCellObj::GetCellPropertyMap();
+ PropertyEntryVector_t aPropVector = pMap->getPropertyEntries();
+ for ( sal_uInt16 nWhich = ATTR_PATTERN_START; nWhich <= ATTR_PATTERN_END; ++nWhich )
+ {
+ const SfxPoolItem* pItem = 0;
+ if ( rNewSet.GetItemState( nWhich, sal_True, &pItem ) == SFX_ITEM_SET && pItem )
+ {
+ PropertyEntryVector_t::const_iterator aIt = aPropVector.begin();
+ while ( aIt != aPropVector.end())
+ {
+ if ( aIt->nWID == nWhich )
+ {
+ ::com::sun::star::uno::Any aVal;
+ pItem->QueryValue( aVal, aIt->nMemberId );
+ aProperties.realloc( nCount + 1 );
+ aProperties[ nCount ].Name = aIt->sName;
+ aProperties[ nCount ].Value <<= aVal;
+ ++nCount;
+ }
+ ++aIt;
+ }
+ }
+ }
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "attribute" ) ), aChangeRanges, aProperties );
+ }
+
+ StartFormatArea();
+}
+
+void ScViewFunc::ApplyUserItemSet( const SfxItemSet& rItemSet )
+{
+ // ItemSet from UI, may have different pool
+
+ sal_Bool bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ ScPatternAttr aNewAttrs( GetViewData()->GetDocument()->GetPool() );
+ SfxItemSet& rNewSet = aNewAttrs.GetItemSet();
+ rNewSet.Put( rItemSet, sal_False );
+ ApplySelectionPattern( aNewAttrs );
+
+ AdjustBlockHeight();
+}
+
+const SfxStyleSheet* ScViewFunc::GetStyleSheetFromMarked()
+{
+ // Don't use UnmarkFiltered in slot state functions, for performance reasons.
+ // The displayed state is always that of the whole selection including filtered rows.
+
+ const ScStyleSheet* pSheet = NULL;
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScMarkData& rMark = pViewData->GetMarkData();
+
+ if ( rMark.IsMarked() || rMark.IsMultiMarked() )
+ pSheet = pDoc->GetSelectionStyle( rMark ); // MarkToMulti isn't necessary
+ else
+ pSheet = pDoc->GetStyle( pViewData->GetCurX(),
+ pViewData->GetCurY(),
+ pViewData->GetTabNo() );
+
+ return pSheet;
+}
+
+void ScViewFunc::SetStyleSheetToMarked( SfxStyleSheet* pStyleSheet, sal_Bool bRecord )
+{
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ sal_Bool bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ if ( !pStyleSheet) return;
+ // -------------------------------------------------------------------
+
+ ScViewData* pViewData = GetViewData();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData aFuncMark( pViewData->GetMarkData() ); // local copy for UnmarkFiltered
+ ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
+ SCTAB nTabCount = pDoc->GetTableCount();
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = sal_False;
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ if ( aFuncMark.IsMarked() || aFuncMark.IsMultiMarked() )
+ {
+ ScRange aMarkRange;
+ aFuncMark.MarkToMulti();
+ aFuncMark.GetMultiMarkArea( aMarkRange );
+
+ if ( bRecord )
+ {
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (i != nTab && aFuncMark.GetTableSelect(i))
+ pUndoDoc->AddUndoTab( i, i );
+
+ ScRange aCopyRange = aMarkRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+ pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, sal_True, pUndoDoc, &aFuncMark );
+ aFuncMark.MarkToMulti();
+
+ String aName = pStyleSheet->GetName();
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoSelectionStyle( pDocSh, aFuncMark, aMarkRange, aName, pUndoDoc ) );
+ }
+
+ pDoc->ApplySelectionStyle( (ScStyleSheet&)*pStyleSheet, aFuncMark );
+
+ if (!AdjustBlockHeight())
+ pViewData->GetDocShell()->PostPaint( aMarkRange, PAINT_GRID );
+
+ aFuncMark.MarkToSimple();
+ }
+ else
+ {
+ SCCOL nCol = pViewData->GetCurX();
+ SCROW nRow = pViewData->GetCurY();
+ SCTAB nTab = pViewData->GetTabNo();
+
+ if ( bRecord )
+ {
+ ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (i != nTab && aFuncMark.GetTableSelect(i))
+ pUndoDoc->AddUndoTab( i, i );
+
+ ScRange aCopyRange( nCol, nRow, 0, nCol, nRow, nTabCount-1 );
+ pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, sal_False, pUndoDoc );
+
+ ScRange aMarkRange ( nCol, nRow, nTab );
+ ScMarkData aUndoMark = aFuncMark;
+ aUndoMark.SetMultiMarkArea( aMarkRange );
+
+ String aName = pStyleSheet->GetName();
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoSelectionStyle( pDocSh, aUndoMark, aMarkRange, aName, pUndoDoc ) );
+ }
+
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (aFuncMark.GetTableSelect(i))
+ pDoc->ApplyStyle( nCol, nRow, i, (ScStyleSheet&)*pStyleSheet );
+
+ if (!AdjustBlockHeight())
+ pViewData->GetDocShell()->PostPaintCell( nCol, nRow, nTab );
+
+ }
+
+ aModificator.SetDocumentModified();
+
+ StartFormatArea();
+}
+
+
+void ScViewFunc::RemoveStyleSheetInUse( const SfxStyleSheetBase* pStyleSheet )
+{
+ if ( !pStyleSheet) return;
+ // -------------------------------------------------------------------
+
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ VirtualDevice aVirtDev;
+ aVirtDev.SetMapMode(MAP_PIXEL);
+ pDoc->StyleSheetChanged( pStyleSheet, sal_True, &aVirtDev,
+ pViewData->GetPPTX(),
+ pViewData->GetPPTY(),
+ pViewData->GetZoomX(),
+ pViewData->GetZoomY() );
+
+ pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID|PAINT_LEFT );
+ aModificator.SetDocumentModified();
+
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
+ if (pHdl)
+ pHdl->ForgetLastPattern();
+}
+
+void ScViewFunc::UpdateStyleSheetInUse( const SfxStyleSheetBase* pStyleSheet )
+{
+ if ( !pStyleSheet) return;
+ // -------------------------------------------------------------------
+
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ VirtualDevice aVirtDev;
+ aVirtDev.SetMapMode(MAP_PIXEL);
+ pDoc->StyleSheetChanged( pStyleSheet, sal_False, &aVirtDev,
+ pViewData->GetPPTX(),
+ pViewData->GetPPTY(),
+ pViewData->GetZoomX(),
+ pViewData->GetZoomY() );
+
+ pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID|PAINT_LEFT );
+ aModificator.SetDocumentModified();
+
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
+ if (pHdl)
+ pHdl->ForgetLastPattern();
+}
+
+// Zellen einfuegen - Undo OK
+
+sal_Bool ScViewFunc::InsertCells( InsCellCmd eCmd, sal_Bool bRecord, sal_Bool bPartOfPaste )
+{
+ ScRange aRange;
+ if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+ sal_Bool bSuccess = pDocSh->GetDocFunc().InsertCells( aRange, &rMark, eCmd, bRecord, sal_False, bPartOfPaste );
+ if (bSuccess)
+ {
+ pDocSh->UpdateOle(GetViewData());
+ CellContentChanged();
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ if ( eCmd == INS_INSROWS || eCmd == INS_INSCOLS )
+ {
+ ScRangeList aChangeRanges;
+ aChangeRanges.Append( aRange );
+ ::rtl::OUString aOperation = ( eCmd == INS_INSROWS ?
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert-rows" ) ) :
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert-columns" ) ) );
+ pModelObj->NotifyChanges( aOperation, aChangeRanges );
+ }
+ }
+ }
+ return bSuccess;
+ }
+ else
+ {
+ ErrorMessage(STR_NOMULTISELECT);
+ return sal_False;
+ }
+}
+
+// Zellen loeschen - Undo OK
+
+void ScViewFunc::DeleteCells( DelCellCmd eCmd, sal_Bool bRecord )
+{
+ ScRange aRange;
+ if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ const ScMarkData& rMark = GetViewData()->GetMarkData();
+
+ // #i94841# [Collaboration] When deleting rows is rejected, the content is sometimes wrong
+ if ( pDocSh->IsDocShared() && ( eCmd == DEL_DELROWS || eCmd == DEL_DELCOLS ) )
+ {
+ ScRange aDelRange( aRange.aStart );
+ SCCOLROW nCount = 0;
+ if ( eCmd == DEL_DELROWS )
+ {
+ nCount = sal::static_int_cast< SCCOLROW >( aRange.aEnd.Row() - aRange.aStart.Row() + 1 );
+ }
+ else
+ {
+ nCount = sal::static_int_cast< SCCOLROW >( aRange.aEnd.Col() - aRange.aStart.Col() + 1 );
+ }
+ while ( nCount > 0 )
+ {
+ pDocSh->GetDocFunc().DeleteCells( aDelRange, &rMark, eCmd, bRecord, sal_False );
+ --nCount;
+ }
+ }
+ else
+ {
+ pDocSh->GetDocFunc().DeleteCells( aRange, &rMark, eCmd, bRecord, sal_False );
+ }
+
+ pDocSh->UpdateOle(GetViewData());
+ CellContentChanged();
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ if ( eCmd == DEL_DELROWS || eCmd == DEL_DELCOLS )
+ {
+ ScRangeList aChangeRanges;
+ aChangeRanges.Append( aRange );
+ ::rtl::OUString aOperation = ( eCmd == DEL_DELROWS ?
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete-rows" ) ) :
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete-columns" ) ) );
+ pModelObj->NotifyChanges( aOperation, aChangeRanges );
+ }
+ }
+
+ // #58106# Cursor direkt hinter den geloeschten Bereich setzen
+ SCCOL nCurX = GetViewData()->GetCurX();
+ SCROW nCurY = GetViewData()->GetCurY();
+ if ( eCmd==DEL_CELLSLEFT || eCmd==DEL_DELCOLS )
+ nCurX = aRange.aStart.Col();
+ else
+ nCurY = aRange.aStart.Row();
+ SetCursor( nCurX, nCurY );
+ }
+ else
+ {
+ if (eCmd == DEL_DELCOLS)
+ DeleteMulti( sal_False, bRecord );
+ else if (eCmd == DEL_DELROWS)
+ DeleteMulti( sal_True, bRecord );
+ else
+ ErrorMessage(STR_NOMULTISELECT);
+ }
+
+ Unmark();
+}
+
+void ScViewFunc::DeleteMulti( sal_Bool bRows, sal_Bool bRecord )
+{
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocShellModificator aModificator( *pDocSh );
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
+ ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = sal_False;
+ SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT];
+ SCCOLROW nRangeCnt = bRows ? aFuncMark.GetMarkRowRanges( pRanges ) :
+ aFuncMark.GetMarkColumnRanges( pRanges );
+ if (nRangeCnt == 0)
+ {
+ pRanges[0] = pRanges[1] = bRows ? static_cast<SCCOLROW>(GetViewData()->GetCurY()) : static_cast<SCCOLROW>(GetViewData()->GetCurX());
+ nRangeCnt = 1;
+ }
+
+ // Test ob erlaubt
+
+ SCCOLROW* pOneRange = pRanges;
+ sal_uInt16 nErrorId = 0;
+ sal_Bool bNeedRefresh = sal_False;
+ SCCOLROW nRangeNo;
+ for (nRangeNo=0; nRangeNo<nRangeCnt && !nErrorId; nRangeNo++)
+ {
+ SCCOLROW nStart = *(pOneRange++);
+ SCCOLROW nEnd = *(pOneRange++);
+
+ SCCOL nStartCol, nEndCol;
+ SCROW nStartRow, nEndRow;
+ if ( bRows )
+ {
+ nStartCol = 0;
+ nEndCol = MAXCOL;
+ nStartRow = static_cast<SCROW>(nStart);
+ nEndRow = static_cast<SCROW>(nEnd);
+ }
+ else
+ {
+ nStartCol = static_cast<SCCOL>(nStart);
+ nEndCol = static_cast<SCCOL>(nEnd);
+ nStartRow = 0;
+ nEndRow = MAXROW;
+ }
+
+ // cell protection (only needed for first range, as all following cells are moved)
+ if ( nRangeNo == 0 )
+ {
+ // test to the end of the sheet
+ ScEditableTester aTester( pDoc, nTab, nStartCol, nStartRow, MAXCOL, MAXROW );
+ if (!aTester.IsEditable())
+ nErrorId = aTester.GetMessageId();
+ }
+
+ // merged cells
+ SCCOL nMergeStartX = nStartCol;
+ SCROW nMergeStartY = nStartRow;
+ SCCOL nMergeEndX = nEndCol;
+ SCROW nMergeEndY = nEndRow;
+ pDoc->ExtendMerge( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, nTab );
+ pDoc->ExtendOverlapped( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, nTab );
+
+ if ( nMergeStartX != nStartCol || nMergeStartY != nStartRow )
+ {
+ // Disallow deleting parts of a merged cell.
+ // Deleting the start is allowed (merge is removed), so the end doesn't have to be checked.
+
+ nErrorId = STR_MSSG_DELETECELLS_0;
+ }
+ if ( nMergeEndX != nEndCol || nMergeEndY != nEndRow )
+ {
+ // detect if the start of a merged cell is deleted, so the merge flags can be refreshed
+
+ bNeedRefresh = sal_True;
+ }
+ }
+
+ if ( nErrorId )
+ {
+ ErrorMessage( nErrorId );
+ delete[] pRanges;
+ return;
+ }
+
+ // ausfuehren
+
+ WaitObject aWait( GetFrameWin() ); // wichtig wegen TrackFormulas bei UpdateReference
+
+ ScDocument* pUndoDoc = NULL;
+ ScRefUndoData* pUndoData = NULL;
+ if (bRecord)
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, !bRows, bRows ); // Zeilenhoehen
+
+ pOneRange = pRanges;
+ for (nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
+ {
+ SCCOLROW nStart = *(pOneRange++);
+ SCCOLROW nEnd = *(pOneRange++);
+ if (bRows)
+ pDoc->CopyToDocument( 0,nStart,nTab, MAXCOL,nEnd,nTab, IDF_ALL,sal_False,pUndoDoc );
+ else
+ pDoc->CopyToDocument( static_cast<SCCOL>(nStart),0,nTab,
+ static_cast<SCCOL>(nEnd),MAXROW,nTab,
+ IDF_ALL,sal_False,pUndoDoc );
+ }
+
+ // alle Formeln wegen Referenzen
+ SCTAB nTabCount = pDoc->GetTableCount();
+ pUndoDoc->AddUndoTab( 0, nTabCount-1, sal_False, sal_False );
+ pDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,MAXTAB, IDF_FORMULA,sal_False,pUndoDoc );
+
+ pUndoData = new ScRefUndoData( pDoc );
+
+ pDoc->BeginDrawUndo();
+ }
+
+ pOneRange = &pRanges[2*nRangeCnt]; // rueckwaerts
+ for (nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
+ {
+ SCCOLROW nEnd = *(--pOneRange);
+ SCCOLROW nStart = *(--pOneRange);
+
+ if (bRows)
+ pDoc->DeleteRow( 0,nTab, MAXCOL,nTab, nStart, static_cast<SCSIZE>(nEnd-nStart+1) );
+ else
+ pDoc->DeleteCol( 0,nTab, MAXROW,nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd-nStart+1) );
+ }
+
+ if (bNeedRefresh)
+ {
+ SCCOLROW nFirstStart = pRanges[0];
+ SCCOL nStartCol = bRows ? 0 : static_cast<SCCOL>(nFirstStart);
+ SCROW nStartRow = bRows ? static_cast<SCROW>(nFirstStart) : 0;
+ SCCOL nEndCol = MAXCOL;
+ SCROW nEndRow = MAXROW;
+
+ pDoc->RemoveFlagsTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, SC_MF_HOR | SC_MF_VER );
+ pDoc->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab, sal_True );
+ }
+
+ if (bRecord)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoDeleteMulti( pDocSh, bRows, bNeedRefresh, nTab, pRanges, nRangeCnt,
+ pUndoDoc, pUndoData ) );
+ }
+
+ if (!AdjustRowHeight(0, MAXROW))
+ {
+ if (bRows)
+ pDocSh->PostPaint( 0,pRanges[0],nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_LEFT );
+ else
+ pDocSh->PostPaint( static_cast<SCCOL>(pRanges[0]),0,nTab,
+ MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_TOP );
+ }
+ aModificator.SetDocumentModified();
+
+ CellContentChanged();
+
+ // #58106# Cursor direkt hinter den ersten geloeschten Bereich setzen
+ SCCOL nCurX = GetViewData()->GetCurX();
+ SCROW nCurY = GetViewData()->GetCurY();
+ if ( bRows )
+ nCurY = pRanges[0];
+ else
+ nCurX = static_cast<SCCOL>(pRanges[0]);
+ SetCursor( nCurX, nCurY );
+
+ delete[] pRanges;
+
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
+}
+
+// Inhalte loeschen
+
+void ScViewFunc::DeleteContents( sal_uInt16 nFlags, sal_Bool bRecord )
+{
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ sal_Bool bOnlyNotBecauseOfMatrix;
+ sal_Bool bEditable = SelectionEditable( &bOnlyNotBecauseOfMatrix );
+ if ( !bEditable )
+ {
+ if ( !(bOnlyNotBecauseOfMatrix &&
+ ((nFlags & (IDF_ATTRIB | IDF_EDITATTR)) == nFlags)) )
+ {
+ ErrorMessage(bOnlyNotBecauseOfMatrix ? STR_MATRIXFRAGMENTERR : STR_PROTECTIONERR);
+ return;
+ }
+ }
+
+ ScRange aMarkRange;
+ sal_Bool bSimple = sal_False;
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
+ ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
+
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = sal_False;
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() )
+ {
+ aMarkRange.aStart.SetCol(GetViewData()->GetCurX());
+ aMarkRange.aStart.SetRow(GetViewData()->GetCurY());
+ aMarkRange.aStart.SetTab(GetViewData()->GetTabNo());
+ aMarkRange.aEnd = aMarkRange.aStart;
+ if ( pDoc->HasAttrib( aMarkRange, HASATTR_MERGED ) )
+ {
+// InitOwnBlockMode();
+ aFuncMark.SetMarkArea( aMarkRange );
+ }
+ else
+ bSimple = sal_True;
+ }
+
+ aFuncMark.SetMarking(sal_False); // for MarkToMulti
+ aFuncMark.MarkToSimple(); // before bMulti test below
+
+ DBG_ASSERT( aFuncMark.IsMarked() || aFuncMark.IsMultiMarked() || bSimple, "delete what?" );
+
+ ScDocument* pUndoDoc = NULL;
+ sal_Bool bMulti = !bSimple && aFuncMark.IsMultiMarked();
+ if (!bSimple)
+ {
+ aFuncMark.MarkToMulti();
+ aFuncMark.GetMultiMarkArea( aMarkRange );
+ }
+ ScRange aExtendedRange(aMarkRange);
+ if (!bSimple)
+ {
+ if ( pDoc->ExtendMerge( aExtendedRange, sal_True ) )
+ bMulti = sal_False;
+ }
+
+ // keine Objekte auf geschuetzten Tabellen
+ sal_Bool bObjects = sal_False;
+ if ( nFlags & IDF_OBJECTS )
+ {
+ bObjects = sal_True;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (aFuncMark.GetTableSelect(nTab) && pDoc->IsTabProtected(nTab))
+ bObjects = sal_False;
+ }
+
+ sal_uInt16 nExtFlags = 0; // extra flags are needed only if attributes are deleted
+ if ( nFlags & IDF_ATTRIB )
+ pDocSh->UpdatePaintExt( nExtFlags, aMarkRange );
+
+ // Reihenfolge:
+ // 1) BeginDrawUndo
+ // 2) Objekte loeschen (DrawUndo wird gefuellt)
+ // 3) Inhalte fuer Undo kopieren
+ // 4) Inhalte loeschen
+ // 5) Undo-Aktion anlegen
+
+ sal_Bool bDrawUndo = bObjects || ( nFlags & IDF_NOTE ); // needed for shown notes
+ if ( bDrawUndo && bRecord )
+ pDoc->BeginDrawUndo();
+
+ if (bObjects)
+ {
+ if (bMulti)
+ pDoc->DeleteObjectsInSelection( aFuncMark );
+ else
+ pDoc->DeleteObjectsInArea( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
+/*!*/ aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(),
+ aFuncMark );
+ }
+
+ if ( bRecord )
+ {
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ SCTAB nTab = aMarkRange.aStart.Tab();
+ pUndoDoc->InitUndo( pDoc, nTab, nTab );
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB i=0; i<nTabCount; i++)
+ if (i != nTab && aFuncMark.GetTableSelect(i))
+ pUndoDoc->AddUndoTab( i, i );
+ ScRange aCopyRange = aExtendedRange;
+ aCopyRange.aStart.SetTab(0);
+ aCopyRange.aEnd.SetTab(nTabCount-1);
+
+ // bei "Format/Standard" alle Attribute kopieren, weil CopyToDocument
+ // nur mit IDF_HARDATTR zu langsam ist:
+ sal_uInt16 nUndoDocFlags = nFlags;
+ if (nFlags & IDF_ATTRIB)
+ nUndoDocFlags |= IDF_ATTRIB;
+ if (nFlags & IDF_EDITATTR) // Edit-Engine-Attribute
+ nUndoDocFlags |= IDF_STRING; // -> Zellen werden geaendert
+ if (nFlags & IDF_NOTE)
+ nUndoDocFlags |= IDF_CONTENTS; // #68795# copy all cells with their notes
+ // do not copy note captions to undo document
+ nUndoDocFlags |= IDF_NOCAPTIONS;
+ pDoc->CopyToDocument( aCopyRange, nUndoDocFlags, bMulti, pUndoDoc, &aFuncMark );
+ }
+
+ HideAllCursors(); // falls Zusammenfassung aufgehoben wird
+ if (bSimple)
+ pDoc->DeleteArea( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
+ aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(),
+ aFuncMark, nFlags );
+ else
+ {
+ pDoc->DeleteSelection( nFlags, aFuncMark );
+// aFuncMark.MarkToSimple();
+ }
+
+ if ( bRecord )
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoDeleteContents( pDocSh, aFuncMark, aExtendedRange,
+ pUndoDoc, bMulti, nFlags, bDrawUndo ) );
+ }
+
+ if (!AdjustRowHeight( aExtendedRange.aStart.Row(), aExtendedRange.aEnd.Row() ))
+ pDocSh->PostPaint( aExtendedRange, PAINT_GRID, nExtFlags );
+
+ pDocSh->UpdateOle(GetViewData());
+
+ // #i97876# Spreadsheet data changes are not notified
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ if ( bSimple )
+ {
+ aChangeRanges.Append( aMarkRange );
+ }
+ else
+ {
+ aFuncMark.FillRangeListWithMarks( &aChangeRanges, sal_False );
+ }
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+ }
+
+ aModificator.SetDocumentModified();
+ CellContentChanged();
+ ShowAllCursors();
+
+ if ( nFlags & IDF_ATTRIB )
+ {
+ if ( nFlags & IDF_CONTENTS )
+ ForgetFormatArea();
+ else
+ StartFormatArea(); // Attribute loeschen ist auch Attributierung
+ }
+}
+
+// Spaltenbreiten/Zeilenhoehen (ueber Header) - Undo OK
+
+void ScViewFunc::SetWidthOrHeight( sal_Bool bWidth, SCCOLROW nRangeCnt, SCCOLROW* pRanges,
+ ScSizeMode eMode, sal_uInt16 nSizeTwips,
+ sal_Bool bRecord, sal_Bool bPaint, ScMarkData* pMarkData )
+{
+ if (nRangeCnt == 0)
+ return;
+
+ // use view's mark if none specified
+ if ( !pMarkData )
+ pMarkData = &GetViewData()->GetMarkData();
+
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ SCTAB nFirstTab = pMarkData->GetFirstSelected();
+ SCTAB nCurTab = GetViewData()->GetTabNo();
+ SCTAB nTab;
+ if (bRecord && !pDoc->IsUndoEnabled())
+ bRecord = sal_False;
+
+ ScDocShellModificator aModificator( *pDocSh );
+
+ sal_Bool bAllowed = sal_True;
+ for (nTab=0; nTab<nTabCount && bAllowed; nTab++)
+ if (pMarkData->GetTableSelect(nTab))
+ {
+ for ( SCCOLROW i=0; i<nRangeCnt && bAllowed; i++ )
+ {
+ sal_Bool bOnlyMatrix;
+ if (bWidth)
+ bAllowed = pDoc->IsBlockEditable( nTab,
+ static_cast<SCCOL>(pRanges[2*i]),0,
+ static_cast<SCCOL>(pRanges[2*i+1]),MAXROW,
+ &bOnlyMatrix ) || bOnlyMatrix;
+ else
+ bAllowed = pDoc->IsBlockEditable( nTab, 0,pRanges[2*i],
+ MAXCOL,pRanges[2*i+1], &bOnlyMatrix ) ||
+ bOnlyMatrix;
+ }
+ }
+ if ( !bAllowed )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ SCCOLROW nStart = pRanges[0];
+ SCCOLROW nEnd = pRanges[2*nRangeCnt-1];
+
+ sal_Bool bFormula = sal_False;
+ if ( eMode == SC_SIZE_OPTIMAL )
+ {
+ const ScViewOptions& rOpts = GetViewData()->GetOptions();
+ bFormula = rOpts.GetOption( VOPT_FORMULAS );
+ }
+
+ ScDocument* pUndoDoc = NULL;
+ ScOutlineTable* pUndoTab = NULL;
+ SCCOLROW* pUndoRanges = NULL;
+
+ if ( bRecord )
+ {
+ pDoc->BeginDrawUndo(); // Drawing Updates
+
+ pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (pMarkData->GetTableSelect(nTab))
+ {
+ if (bWidth)
+ {
+ if ( nTab == nFirstTab )
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_False );
+ else
+ pUndoDoc->AddUndoTab( nTab, nTab, sal_True, sal_False );
+ pDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab,
+ static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE,
+ sal_False, pUndoDoc );
+ }
+ else
+ {
+ if ( nTab == nFirstTab )
+ pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_False, sal_True );
+ else
+ pUndoDoc->AddUndoTab( nTab, nTab, sal_False, sal_True );
+ pDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, sal_False, pUndoDoc );
+ }
+ }
+
+ pUndoRanges = new SCCOLROW[ 2*nRangeCnt ];
+ memmove( pUndoRanges, pRanges, 2*nRangeCnt*sizeof(SCCOLROW) );
+
+ //! outlines from all tables?
+ ScOutlineTable* pTable = pDoc->GetOutlineTable( nCurTab );
+ if (pTable)
+ pUndoTab = new ScOutlineTable( *pTable );
+ }
+
+ if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
+ pMarkData->MarkToMulti();
+
+ sal_Bool bShow = nSizeTwips > 0 || eMode != SC_SIZE_DIRECT;
+ sal_Bool bOutline = sal_False;
+
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (pMarkData->GetTableSelect(nTab))
+ {
+ const SCCOLROW* pTabRanges = pRanges;
+
+ pDoc->IncSizeRecalcLevel( nTab ); // nicht fuer jede Spalte einzeln
+ pDoc->InitializeNoteCaptions( nTab );
+ for (SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
+ {
+ SCCOLROW nStartNo = *(pTabRanges++);
+ SCCOLROW nEndNo = *(pTabRanges++);
+
+ if ( !bWidth ) // Hoehen immer blockweise
+ {
+ if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
+ {
+ sal_Bool bAll = ( eMode==SC_SIZE_OPTIMAL );
+ if (!bAll)
+ {
+ // fuer alle eingeblendeten CR_MANUALSIZE loeschen,
+ // dann SetOptimalHeight mit bShrink = FALSE
+ for (SCROW nRow = nStartNo; nRow <= nEndNo; ++nRow)
+ {
+ SCROW nLastRow = nRow;
+ if (pDoc->RowHidden(nRow, nTab, NULL, &nLastRow))
+ {
+ nRow = nLastRow;
+ continue;
+ }
+
+ sal_uInt8 nOld = pDoc->GetRowFlags(nRow, nTab);
+ if (nOld & CR_MANUALSIZE)
+ pDoc->SetRowFlags(nRow, nTab, nOld & ~CR_MANUALSIZE);
+ }
+ }
+
+ double nPPTX = GetViewData()->GetPPTX();
+ double nPPTY = GetViewData()->GetPPTY();
+ Fraction aZoomX = GetViewData()->GetZoomX();
+ Fraction aZoomY = GetViewData()->GetZoomY();
+
+ ScSizeDeviceProvider aProv(pDocSh);
+ if (aProv.IsPrinter())
+ {
+ nPPTX = aProv.GetPPTX();
+ nPPTY = aProv.GetPPTY();
+ aZoomX = aZoomY = Fraction( 1, 1 );
+ }
+
+ pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, nSizeTwips, aProv.GetDevice(),
+ nPPTX, nPPTY, aZoomX, aZoomY, bAll );
+ if (bAll)
+ pDoc->ShowRows( nStartNo, nEndNo, nTab, sal_True );
+
+ // Manual-Flag wird bei bAll=sal_True schon in SetOptimalHeight gesetzt
+ // (an bei Extra-Height, sonst aus).
+ }
+ else if ( eMode==SC_SIZE_DIRECT )
+ {
+ if (nSizeTwips)
+ {
+ pDoc->SetRowHeightRange( nStartNo, nEndNo, nTab, nSizeTwips );
+ pDoc->SetManualHeight( nStartNo, nEndNo, nTab, sal_True ); // height was set manually
+ }
+ pDoc->ShowRows( nStartNo, nEndNo, nTab, nSizeTwips != 0 );
+ }
+ else if ( eMode==SC_SIZE_SHOW )
+ {
+ pDoc->ShowRows( nStartNo, nEndNo, nTab, sal_True );
+ }
+ }
+ else // Spaltenbreiten
+ {
+ for (SCCOL nCol=static_cast<SCCOL>(nStartNo); nCol<=static_cast<SCCOL>(nEndNo); nCol++)
+ {
+ if ( eMode != SC_SIZE_VISOPT || !pDoc->ColHidden(nCol, nTab) )
+ {
+ sal_uInt16 nThisSize = nSizeTwips;
+
+ if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
+ nThisSize = nSizeTwips + GetOptimalColWidth( nCol, nTab, bFormula );
+ if ( nThisSize )
+ pDoc->SetColWidth( nCol, nTab, nThisSize );
+
+ pDoc->ShowCol( nCol, nTab, bShow );
+ }
+ }
+ }
+
+ // Outline anpassen
+
+ if (bWidth)
+ {
+ if ( pDoc->UpdateOutlineCol( static_cast<SCCOL>(nStartNo),
+ static_cast<SCCOL>(nEndNo), nTab, bShow ) )
+ bOutline = sal_True;
+ }
+ else
+ {
+ if ( pDoc->UpdateOutlineRow( nStartNo, nEndNo, nTab, bShow ) )
+ bOutline = sal_True;
+ }
+ }
+ pDoc->DecSizeRecalcLevel( nTab ); // nicht fuer jede Spalte einzeln
+ }
+
+
+ if (!bOutline)
+ DELETEZ(pUndoTab);
+
+ if (bRecord)
+ {
+ pDocSh->GetUndoManager()->AddUndoAction(
+ new ScUndoWidthOrHeight( pDocSh, *pMarkData,
+ nStart, nCurTab, nEnd, nCurTab,
+ pUndoDoc, nRangeCnt, pUndoRanges,
+ pUndoTab, eMode, nSizeTwips, bWidth ) );
+ }
+
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (pMarkData->GetTableSelect(nTab))
+ pDoc->UpdatePageBreaks( nTab );
+
+ GetViewData()->GetView()->UpdateScrollBars();
+
+ if (bPaint)
+ {
+ HideCursor();
+
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (pMarkData->GetTableSelect(nTab))
+ {
+ if (bWidth)
+ {
+ if (pDoc->HasAttrib( static_cast<SCCOL>(nStart),0,nTab,
+ static_cast<SCCOL>(nEnd),MAXROW,nTab,
+ HASATTR_MERGED | HASATTR_OVERLAPPED ))
+ nStart = 0;
+ if (nStart > 0) // weiter oben anfangen wegen Linien und Cursor
+ --nStart;
+ pDocSh->PostPaint( static_cast<SCCOL>(nStart), 0, nTab,
+ MAXCOL, MAXROW, nTab, PAINT_GRID | PAINT_TOP );
+ }
+ else
+ {
+ if (pDoc->HasAttrib( 0,nStart,nTab, MAXCOL,nEnd,nTab, HASATTR_MERGED | HASATTR_OVERLAPPED ))
+ nStart = 0;
+ if (nStart != 0)
+ --nStart;
+ pDocSh->PostPaint( 0, nStart, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID | PAINT_LEFT );
+ }
+ }
+
+ pDocSh->UpdateOle(GetViewData());
+ aModificator.SetDocumentModified();
+
+ ShowCursor();
+ }
+
+ // #i97876# Spreadsheet data changes are not notified
+ if ( bWidth )
+ {
+ ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
+ if ( pModelObj && pModelObj->HasChangesListeners() )
+ {
+ ScRangeList aChangeRanges;
+ for ( nTab = 0; nTab < nTabCount; ++nTab )
+ {
+ if ( pMarkData->GetTableSelect( nTab ) )
+ {
+ const SCCOLROW* pTabRanges = pRanges;
+ for ( SCCOLROW nRange = 0; nRange < nRangeCnt; ++nRange )
+ {
+ SCCOL nStartCol = static_cast< SCCOL >( *(pTabRanges++) );
+ SCCOL nEndCol = static_cast< SCCOL >( *(pTabRanges++) );
+ for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
+ {
+ aChangeRanges.Append( ScRange( nCol, 0, nTab ) );
+ }
+ }
+ }
+ }
+ pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "column-resize" ) ), aChangeRanges );
+ }
+ }
+}
+
+// Spaltenbreiten/Zeilenhoehen (ueber Blockmarken)
+
+void ScViewFunc::SetMarkedWidthOrHeight( sal_Bool bWidth, ScSizeMode eMode, sal_uInt16 nSizeTwips,
+ sal_Bool bRecord, sal_Bool bPaint )
+{
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+
+ rMark.MarkToMulti();
+ if (!rMark.IsMultiMarked())
+ {
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ DoneBlockMode();
+ InitOwnBlockMode();
+ rMark.SetMultiMarkArea( ScRange( nCol,nRow,nTab ), sal_True );
+ MarkDataChanged();
+ }
+
+ SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT];
+ SCCOLROW nRangeCnt = 0;
+
+ if ( bWidth )
+ nRangeCnt = rMark.GetMarkColumnRanges( pRanges );
+ else
+ nRangeCnt = rMark.GetMarkRowRanges( pRanges );
+
+ SetWidthOrHeight( bWidth, nRangeCnt, pRanges, eMode, nSizeTwips, bRecord, bPaint );
+
+ delete[] pRanges;
+ rMark.MarkToSimple();
+}
+
+void ScViewFunc::ModifyCellSize( ScDirection eDir, sal_Bool bOptimal )
+{
+ //! Schrittweiten einstellbar
+ // Schrittweite ist auch Minimum
+ sal_uInt16 nStepX = STD_COL_WIDTH / 5;
+ sal_uInt16 nStepY = ScGlobal::nStdRowHeight;
+
+ ScModule* pScMod = SC_MOD();
+ sal_Bool bAnyEdit = pScMod->IsInputMode();
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+
+ sal_Bool bAllowed, bOnlyMatrix;
+ if ( eDir == DIR_LEFT || eDir == DIR_RIGHT )
+ bAllowed = pDoc->IsBlockEditable( nTab, nCol,0, nCol,MAXROW, &bOnlyMatrix );
+ else
+ bAllowed = pDoc->IsBlockEditable( nTab, 0,nRow, MAXCOL,nRow, &bOnlyMatrix );
+ if ( !bAllowed && !bOnlyMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ HideAllCursors();
+
+ sal_uInt16 nWidth = pDoc->GetColWidth( nCol, nTab );
+ sal_uInt16 nHeight = pDoc->GetRowHeight( nRow, nTab );
+ SCCOLROW nRange[2];
+ if ( eDir == DIR_LEFT || eDir == DIR_RIGHT )
+ {
+ if (bOptimal) // Breite dieser einen Zelle
+ {
+ if ( bAnyEdit )
+ {
+ // beim Editieren die aktuelle Breite der Eingabe
+ ScInputHandler* pHdl = pScMod->GetInputHdl( GetViewData()->GetViewShell() );
+ if (pHdl)
+ {
+ long nEdit = pHdl->GetTextSize().Width(); // in 1/100mm
+
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ const SvxMarginItem& rMItem =
+ (const SvxMarginItem&)pPattern->GetItem(ATTR_MARGIN);
+ sal_uInt16 nMargin = rMItem.GetLeftMargin() + rMItem.GetRightMargin();
+ if ( ((const SvxHorJustifyItem&) pPattern->
+ GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_LEFT )
+ nMargin = sal::static_int_cast<sal_uInt16>(
+ nMargin + ((const SfxUInt16Item&)pPattern->GetItem(ATTR_INDENT)).GetValue() );
+
+ nWidth = (sal_uInt16)(nEdit * pDocSh->GetOutputFactor() / HMM_PER_TWIPS)
+ + nMargin + STD_EXTRA_WIDTH;
+ }
+ }
+ else
+ {
+ double nPPTX = GetViewData()->GetPPTX();
+ double nPPTY = GetViewData()->GetPPTY();
+ Fraction aZoomX = GetViewData()->GetZoomX();
+ Fraction aZoomY = GetViewData()->GetZoomY();
+
+ ScSizeDeviceProvider aProv(pDocSh);
+ if (aProv.IsPrinter())
+ {
+ nPPTX = aProv.GetPPTX();
+ nPPTY = aProv.GetPPTY();
+ aZoomX = aZoomY = Fraction( 1, 1 );
+ }
+
+ long nPixel = pDoc->GetNeededSize( nCol, nRow, nTab, aProv.GetDevice(),
+ nPPTX, nPPTY, aZoomX, aZoomY, sal_True );
+ sal_uInt16 nTwips = (sal_uInt16)( nPixel / nPPTX );
+ if (nTwips != 0)
+ nWidth = nTwips + STD_EXTRA_WIDTH;
+ else
+ nWidth = STD_COL_WIDTH;
+ }
+ }
+ else // vergroessern / verkleinern
+ {
+ if ( eDir == DIR_RIGHT )
+ nWidth = sal::static_int_cast<sal_uInt16>( nWidth + nStepX );
+ else if ( nWidth > nStepX )
+ nWidth = sal::static_int_cast<sal_uInt16>( nWidth - nStepX );
+ if ( nWidth < nStepX ) nWidth = nStepX;
+ if ( nWidth > MAX_COL_WIDTH ) nWidth = MAX_COL_WIDTH;
+ }
+ nRange[0] = nRange[1] = nCol;
+ SetWidthOrHeight( sal_True, 1, nRange, SC_SIZE_DIRECT, nWidth );
+
+ // hier bei Breite auch Hoehe anpassen (nur die eine Zeile)
+
+ if (!bAnyEdit)
+ {
+ const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
+ sal_Bool bNeedHeight =
+ ((const SfxBoolItem&)pPattern->GetItem( ATTR_LINEBREAK )).GetValue() ||
+ ((const SvxHorJustifyItem&)pPattern->
+ GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_BLOCK;
+ if (bNeedHeight)
+ AdjustRowHeight( nRow, nRow );
+ }
+ }
+ else
+ {
+ ScSizeMode eMode;
+ if (bOptimal)
+ {
+ eMode = SC_SIZE_OPTIMAL;
+ nHeight = 0;
+ }
+ else
+ {
+ eMode = SC_SIZE_DIRECT;
+ if ( eDir == DIR_BOTTOM )
+ nHeight = sal::static_int_cast<sal_uInt16>( nHeight + nStepY );
+ else if ( nHeight > nStepY )
+ nHeight = sal::static_int_cast<sal_uInt16>( nHeight - nStepY );
+ if ( nHeight < nStepY ) nHeight = nStepY;
+ if ( nHeight > MAX_COL_HEIGHT ) nHeight = MAX_COL_HEIGHT;
+ //! MAX_COL_HEIGHT umbenennen in MAX_ROW_HEIGHT in global.hxx !!!!!!
+ }
+ nRange[0] = nRange[1] = nRow;
+ SetWidthOrHeight( sal_False, 1, nRange, eMode, nHeight );
+ }
+
+ if ( bAnyEdit )
+ {
+ UpdateEditView();
+ if ( pDoc->HasAttrib( nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_NEEDHEIGHT ) )
+ {
+ ScInputHandler* pHdl = pScMod->GetInputHdl( GetViewData()->GetViewShell() );
+ if (pHdl)
+ pHdl->SetModified(); // damit bei Enter die Hoehe angepasst wird
+ }
+ }
+
+ ShowAllCursors();
+}
+
+void ScViewFunc::ProtectSheet( SCTAB nTab, const ScTableProtection& rProtect )
+{
+ if (nTab == TABLEID_DOC)
+ return;
+
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScDocFunc aFunc(*pDocSh);
+ bool bUndo(pDoc->IsUndoEnabled());
+
+ // modifying several tables is handled here
+
+ if (bUndo)
+ {
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_PROTECT_TAB );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+ }
+
+ SCTAB nCount = pDocSh->GetDocument()->GetTableCount();
+ for ( SCTAB i=0; i<nCount; i++ )
+ if ( rMark.GetTableSelect(i) )
+ aFunc.ProtectSheet(i, rProtect);
+
+ if (bUndo)
+ pDocSh->GetUndoManager()->LeaveListAction();
+
+ UpdateLayerLocks(); //! broadcast to all views
+}
+
+void ScViewFunc::Protect( SCTAB nTab, const String& rPassword )
+{
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScDocFunc aFunc(*pDocSh);
+ sal_Bool bUndo(pDoc->IsUndoEnabled());
+
+ if ( nTab == TABLEID_DOC || rMark.GetSelectCount() <= 1 )
+ aFunc.Protect( nTab, rPassword, sal_False );
+ else
+ {
+ // modifying several tables is handled here
+
+ if (bUndo)
+ {
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_PROTECT_TAB );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+ }
+
+ SCTAB nCount = pDocSh->GetDocument()->GetTableCount();
+ for ( SCTAB i=0; i<nCount; i++ )
+ if ( rMark.GetTableSelect(i) )
+ aFunc.Protect( i, rPassword, sal_False );
+
+ if (bUndo)
+ pDocSh->GetUndoManager()->LeaveListAction();
+ }
+
+ UpdateLayerLocks(); //! broadcast to all views
+}
+
+sal_Bool ScViewFunc::Unprotect( SCTAB nTab, const String& rPassword )
+{
+ ScMarkData& rMark = GetViewData()->GetMarkData();
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ ScDocFunc aFunc(*pDocSh);
+ sal_Bool bChanged = sal_False;
+ sal_Bool bUndo (pDoc->IsUndoEnabled());
+
+ if ( nTab == TABLEID_DOC || rMark.GetSelectCount() <= 1 )
+ bChanged = aFunc.Unprotect( nTab, rPassword, sal_False );
+ else
+ {
+ // modifying several tables is handled here
+
+ if (bUndo)
+ {
+ String aUndo = ScGlobal::GetRscString( STR_UNDO_UNPROTECT_TAB );
+ pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
+ }
+
+ SCTAB nCount = pDocSh->GetDocument()->GetTableCount();
+ for ( SCTAB i=0; i<nCount; i++ )
+ if ( rMark.GetTableSelect(i) )
+ if ( aFunc.Unprotect( i, rPassword, sal_False ) )
+ bChanged = sal_True;
+
+ if (bUndo)
+ pDocSh->GetUndoManager()->LeaveListAction();
+ }
+
+ if (bChanged)
+ UpdateLayerLocks(); //! broadcast to all views
+
+ return bChanged;
+}
+
+void ScViewFunc::SetNoteText( const ScAddress& rPos, const String& rNoteText )
+{
+ GetViewData()->GetDocShell()->GetDocFunc().SetNoteText( rPos, rNoteText, sal_False );
+}
+
+void ScViewFunc::ReplaceNote( const ScAddress& rPos, const String& rNoteText, const String* pAuthor, const String* pDate )
+{
+ GetViewData()->GetDocShell()->GetDocFunc().ReplaceNote( rPos, rNoteText, pAuthor, pDate, sal_False );
+}
+
+void ScViewFunc::SetNumberFormat( short nFormatType, sal_uLong nAdd )
+{
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ sal_Bool bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ sal_uInt32 nNumberFormat = 0;
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ SvNumberFormatter* pNumberFormatter = pDoc->GetFormatTable();
+ LanguageType eLanguage = ScGlobal::eLnge;
+ ScPatternAttr aNewAttrs( pDoc->GetPool() );
+
+ // #67936# always take language from cursor position, even if there is a selection
+
+ sal_uInt32 nCurrentNumberFormat;
+ pDoc->GetNumberFormat( pViewData->GetCurX(),
+ pViewData->GetCurY(),
+ pViewData->GetTabNo(),
+ nCurrentNumberFormat );
+ const SvNumberformat* pEntry = pNumberFormatter->GetEntry( nCurrentNumberFormat );
+ if (pEntry)
+ eLanguage = pEntry->GetLanguage(); // sonst ScGlobal::eLnge behalten
+
+ nNumberFormat = pNumberFormatter->GetStandardFormat( nFormatType, eLanguage ) + nAdd;
+
+ SfxItemSet& rSet = aNewAttrs.GetItemSet();
+ rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNumberFormat ) );
+ // ATTR_LANGUAGE_FORMAT nicht
+ ApplySelectionPattern( aNewAttrs, sal_True );
+}
+
+void ScViewFunc::SetNumFmtByStr( const String& rCode )
+{
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ sal_Bool bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ ScViewData* pViewData = GetViewData();
+ ScDocument* pDoc = pViewData->GetDocument();
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+
+ // Sprache immer von Cursorposition
+
+ sal_uInt32 nCurrentNumberFormat;
+ pDoc->GetNumberFormat( pViewData->GetCurX(), pViewData->GetCurY(),
+ pViewData->GetTabNo(), nCurrentNumberFormat );
+ const SvNumberformat* pEntry = pFormatter->GetEntry( nCurrentNumberFormat );
+ LanguageType eLanguage = pEntry ? pEntry->GetLanguage() : ScGlobal::eLnge;
+
+ // Index fuer String bestimmen
+
+ sal_Bool bOk = sal_True;
+ sal_uInt32 nNumberFormat = pFormatter->GetEntryKey( rCode, eLanguage );
+ if ( nNumberFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
+ {
+ // neu eintragen
+
+ String aFormat = rCode; // wird veraendert
+ xub_StrLen nErrPos = 0;
+ short nType = 0; //! ???
+ bOk = pFormatter->PutEntry( aFormat, nErrPos, nType, nNumberFormat, eLanguage );
+ }
+
+ if ( bOk ) // gueltiges Format?
+ {
+ ScPatternAttr aNewAttrs( pDoc->GetPool() );
+ SfxItemSet& rSet = aNewAttrs.GetItemSet();
+ rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNumberFormat ) );
+ rSet.Put( SvxLanguageItem( eLanguage, ATTR_LANGUAGE_FORMAT ) );
+ ApplySelectionPattern( aNewAttrs, sal_True );
+ }
+
+ //! sonst Fehler zuerueckgeben / Meldung ausgeben ???
+}
+
+void ScViewFunc::ChangeNumFmtDecimals( sal_Bool bIncrement )
+{
+ // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
+ sal_Bool bOnlyNotBecauseOfMatrix;
+ if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
+ {
+ ErrorMessage(STR_PROTECTIONERR);
+ return;
+ }
+
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+
+ SCCOL nCol = GetViewData()->GetCurX();
+ SCROW nRow = GetViewData()->GetCurY();
+ SCTAB nTab = GetViewData()->GetTabNo();
+
+ sal_uInt32 nOldFormat;
+ pDoc->GetNumberFormat( nCol, nRow, nTab, nOldFormat );
+ const SvNumberformat* pOldEntry = pFormatter->GetEntry( nOldFormat );
+ if (!pOldEntry)
+ {
+ DBG_ERROR("Zahlformat nicht gefunden !!!");
+ return;
+ }
+
+ // was haben wir denn da?
+
+ sal_uInt32 nNewFormat = nOldFormat;
+ sal_Bool bError = sal_False;
+
+ LanguageType eLanguage = pOldEntry->GetLanguage();
+ sal_Bool bThousand, bNegRed;
+ sal_uInt16 nPrecision, nLeading;
+ pOldEntry->GetFormatSpecialInfo( bThousand, bNegRed, nPrecision, nLeading );
+
+ short nOldType = pOldEntry->GetType();
+ if ( 0 == ( nOldType & (
+ NUMBERFORMAT_NUMBER | NUMBERFORMAT_CURRENCY | NUMBERFORMAT_PERCENT ) ) )
+ {
+ // Datum, Zeit, Bruch, logisch, Text kann nicht angepasst werden
+ //! bei Wisssenschaftlich kann es der Numberformatter auch nicht
+ bError = sal_True;
+ }
+
+ //! Das SvNumberformat hat einen Member bStandard, verraet ihn aber nicht
+ sal_Bool bWasStandard = ( nOldFormat == pFormatter->GetStandardIndex( eLanguage ) );
+ if (bWasStandard)
+ {
+ // bei "Standard" die Nachkommastellen abhaengig vom Zellinhalt
+ // 0 bei leer oder Text -> keine Nachkommastellen
+ double nVal = pDoc->GetValue( ScAddress( nCol, nRow, nTab ) );
+
+ // Die Wege des Numberformatters sind unergruendlich, darum ausprobieren:
+ String aOut;
+ Color* pCol;
+ ((SvNumberformat*)pOldEntry)->GetOutputString( nVal, aOut, &pCol );
+
+ nPrecision = 0;
+ // 'E' fuer Exponential ist fest im Numberformatter
+ if ( aOut.Search('E') != STRING_NOTFOUND )
+ bError = sal_True; // Exponential nicht veraendern
+ else
+ {
+ String aDecSep( pFormatter->GetFormatDecimalSep( nOldFormat ) );
+ xub_StrLen nPos = aOut.Search( aDecSep );
+ if ( nPos != STRING_NOTFOUND )
+ nPrecision = aOut.Len() - nPos - aDecSep.Len();
+ // sonst 0 behalten
+ }
+ }
+
+ if (!bError)
+ {
+ if (bIncrement)
+ {
+ if (nPrecision<20)
+ ++nPrecision; // erhoehen
+ else
+ bError = sal_True; // 20 ist Maximum
+ }
+ else
+ {
+ if (nPrecision)
+ --nPrecision; // vermindern
+ else
+ bError = sal_True; // weniger als 0 geht nicht
+ }
+ }
+
+ if (!bError)
+ {
+ String aNewPicture;
+ pFormatter->GenerateFormat( aNewPicture, nOldFormat, eLanguage,
+ bThousand, bNegRed, nPrecision, nLeading );
+
+ nNewFormat = pFormatter->GetEntryKey( aNewPicture, eLanguage );
+ if ( nNewFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
+ {
+ xub_StrLen nErrPos = 0;
+ short nNewType = 0;
+ sal_Bool bOk = pFormatter->PutEntry( aNewPicture, nErrPos,
+ nNewType, nNewFormat, eLanguage );
+ DBG_ASSERT( bOk, "falsches Zahlformat generiert" );
+ if (!bOk)
+ bError = sal_True;
+ }
+ }
+
+ if (!bError)
+ {
+ ScPatternAttr aNewAttrs( pDoc->GetPool() );
+ SfxItemSet& rSet = aNewAttrs.GetItemSet();
+ rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) );
+ // ATTR_LANGUAGE_FORMAT nicht
+ ApplySelectionPattern( aNewAttrs, sal_True );
+ }
+ else
+ Sound::Beep(); // war nix
+}
+
+void ScViewFunc::ChangeIndent( sal_Bool bIncrement )
+{
+ ScViewData* pViewData = GetViewData();
+ ScDocShell* pDocSh = pViewData->GetDocShell();
+ ScMarkData& rMark = pViewData->GetMarkData();
+
+ ScMarkData aWorkMark = rMark;
+ ScViewUtil::UnmarkFiltered( aWorkMark, pDocSh->GetDocument() );
+ aWorkMark.MarkToMulti();
+ if (!aWorkMark.IsMultiMarked())
+ {
+ SCCOL nCol = pViewData->GetCurX();
+ SCROW nRow = pViewData->GetCurY();
+ SCTAB nTab = pViewData->GetTabNo();
+ aWorkMark.SetMultiMarkArea( ScRange(nCol,nRow,nTab) );
+ }
+
+ sal_Bool bSuccess = pDocSh->GetDocFunc().ChangeIndent( aWorkMark, bIncrement, sal_False );
+ if (bSuccess)
+ {
+ pDocSh->UpdateOle(pViewData);
+ StartFormatArea();
+ }
+}
+
+sal_Bool ScViewFunc::InsertName( const String& rName, const String& rSymbol,
+ const String& rType )
+{
+ // Type = P,R,C,F (und Kombinationen)
+ //! Undo...
+
+ sal_Bool bOk = sal_False;
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ ScRangeName* pList = pDoc->GetRangeName();
+
+ RangeType nType = RT_NAME;
+ ScRangeData* pNewEntry = new ScRangeData( pDoc, rName, rSymbol,
+ ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
+ nTab), nType );
+ String aUpType = rType;
+ aUpType.ToUpperAscii();
+ if ( aUpType.Search( 'P' ) != STRING_NOTFOUND )
+ nType |= RT_PRINTAREA;
+ if ( aUpType.Search( 'R' ) != STRING_NOTFOUND )
+ nType |= RT_ROWHEADER;
+ if ( aUpType.Search( 'C' ) != STRING_NOTFOUND )
+ nType |= RT_COLHEADER;
+ if ( aUpType.Search( 'F' ) != STRING_NOTFOUND )
+ nType |= RT_CRITERIA;
+ pNewEntry->AddType(nType);
+
+ if ( !pNewEntry->GetErrCode() ) // Text gueltig?
+ {
+ ScDocShellModificator aModificator( *pDocSh );
+
+ pDoc->CompileNameFormula( sal_True ); // CreateFormulaString
+
+ // Eintrag bereits vorhanden? Dann vorher entfernen (=Aendern)
+ sal_uInt16 nFoundAt;
+ if ( pList->SearchName( rName, nFoundAt ) )
+ { // alten Index uebernehmen
+ pNewEntry->SetIndex( ((ScRangeData*)pList->At(nFoundAt))->GetIndex() );
+ pList->AtFree( nFoundAt );
+ }
+
+ if ( pList->Insert( pNewEntry ) )
+ {
+ pNewEntry = NULL; // nicht loeschen
+ bOk = sal_True;
+ }
+
+ pDoc->CompileNameFormula( sal_False ); // CompileFormulaString
+ aModificator.SetDocumentModified();
+ SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
+ }
+
+ delete pNewEntry; // wenn er nicht eingefuegt wurde
+ return bOk;
+}
+
+void ScViewFunc::CreateNames( sal_uInt16 nFlags )
+{
+ sal_Bool bDone = sal_False;
+ ScRange aRange;
+ if ( GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE )
+ bDone = GetViewData()->GetDocShell()->GetDocFunc().CreateNames( aRange, nFlags, sal_False );
+
+ if (!bDone)
+ ErrorMessage(STR_CREATENAME_MARKERR);
+}
+
+sal_uInt16 ScViewFunc::GetCreateNameFlags()
+{
+ sal_uInt16 nFlags = 0;
+
+ SCCOL nStartCol, nEndCol;
+ SCROW nStartRow, nEndRow;
+ SCTAB nDummy;
+ if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nDummy,nEndCol,nEndRow,nDummy) == SC_MARK_SIMPLE)
+ {
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ SCTAB nTab = GetViewData()->GetTabNo();
+ sal_Bool bOk;
+ SCCOL i;
+ SCROW j;
+
+ bOk = sal_True;
+ SCCOL nFirstCol = nStartCol;
+ SCCOL nLastCol = nEndCol;
+ if (nStartCol+1 < nEndCol) { ++nFirstCol; --nLastCol; }
+ for (i=nFirstCol; i<=nLastCol && bOk; i++)
+ if (!pDoc->HasStringData( i,nStartRow,nTab ))
+ bOk = sal_False;
+ if (bOk)
+ nFlags |= NAME_TOP;
+ else // Bottom nur wenn nicht Top
+ {
+ bOk = sal_True;
+ for (i=nFirstCol; i<=nLastCol && bOk; i++)
+ if (!pDoc->HasStringData( i,nEndRow,nTab ))
+ bOk = sal_False;
+ if (bOk)
+ nFlags |= NAME_BOTTOM;
+ }
+
+ bOk = sal_True;
+ SCROW nFirstRow = nStartRow;
+ SCROW nLastRow = nEndRow;
+ if (nStartRow+1 < nEndRow) { ++nFirstRow; --nLastRow; }
+ for (j=nFirstRow; j<=nLastRow && bOk; j++)
+ if (!pDoc->HasStringData( nStartCol,j,nTab ))
+ bOk = sal_False;
+ if (bOk)
+ nFlags |= NAME_LEFT;
+ else // Right nur wenn nicht Left
+ {
+ bOk = sal_True;
+ for (j=nFirstRow; j<=nLastRow && bOk; j++)
+ if (!pDoc->HasStringData( nEndCol,j,nTab ))
+ bOk = sal_False;
+ if (bOk)
+ nFlags |= NAME_RIGHT;
+ }
+ }
+
+ if (nStartCol == nEndCol)
+ nFlags &= ~( NAME_LEFT | NAME_RIGHT );
+ if (nStartRow == nEndRow)
+ nFlags &= ~( NAME_TOP | NAME_BOTTOM );
+
+ return nFlags;
+}
+
+void ScViewFunc::InsertNameList()
+{
+ ScAddress aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ if ( pDocSh->GetDocFunc().InsertNameList( aPos, sal_False ) )
+ pDocSh->UpdateOle(GetViewData());
+}
+
+
+
+
diff --git a/sc/source/ui/view/viewutil.cxx b/sc/source/ui/view/viewutil.cxx
new file mode 100644
index 000000000000..1c2691d8a33f
--- /dev/null
+++ b/sc/source/ui/view/viewutil.cxx
@@ -0,0 +1,640 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include <tools/list.hxx>
+#include "scitems.hxx"
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/dispatch.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include <svl/itempool.hxx>
+#include <svl/itemset.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/wrkwin.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/objsh.hxx>
+#include <svl/stritem.hxx>
+#include <svl/eitem.hxx>
+
+#include <com/sun/star/i18n/TransliterationModules.hpp>
+#include <com/sun/star/i18n/TransliterationModulesExtra.hpp>
+
+
+#include "viewutil.hxx"
+#include "global.hxx"
+#include "chgtrack.hxx"
+#include "chgviset.hxx"
+#include "markdata.hxx"
+
+#include <svx/svxdlg.hxx> //CHINA001
+#include <svx/dialogs.hrc> //CHINA001
+// STATIC DATA -----------------------------------------------------------
+
+//==================================================================
+
+// static
+void ScViewUtil::PutItemScript( SfxItemSet& rShellSet, const SfxItemSet& rCoreSet,
+ sal_uInt16 nWhichId, sal_uInt16 nScript )
+{
+ // take the effective item from rCoreSet according to nScript
+ // and put in rShellSet under the (base) nWhichId
+
+ SfxItemPool& rPool = *rShellSet.GetPool();
+ SvxScriptSetItem aSetItem( rPool.GetSlotId(nWhichId), rPool );
+ // use PutExtended with eDefaultAs = SFX_ITEM_SET, so defaults from rCoreSet
+ // (document pool) are read and put into rShellSet (MessagePool)
+ aSetItem.GetItemSet().PutExtended( rCoreSet, SFX_ITEM_DONTCARE, SFX_ITEM_SET );
+ const SfxPoolItem* pI = aSetItem.GetItemOfScript( nScript );
+ if (pI)
+ rShellSet.Put( *pI, nWhichId );
+ else
+ rShellSet.InvalidateItem( nWhichId );
+}
+
+// static
+sal_uInt16 ScViewUtil::GetEffLanguage( ScDocument* pDoc, const ScAddress& rPos )
+{
+ // used for thesaurus
+
+ sal_uInt8 nScript = pDoc->GetScriptType( rPos.Col(), rPos.Row(), rPos.Tab() );
+ sal_uInt16 nWhich = ( nScript == SCRIPTTYPE_ASIAN ) ? ATTR_CJK_FONT_LANGUAGE :
+ ( ( nScript == SCRIPTTYPE_COMPLEX ) ? ATTR_CTL_FONT_LANGUAGE : ATTR_FONT_LANGUAGE );
+ const SfxPoolItem* pItem = pDoc->GetAttr( rPos.Col(), rPos.Row(), rPos.Tab(), nWhich);
+ SvxLanguageItem* pLangIt = PTR_CAST( SvxLanguageItem, pItem );
+ LanguageType eLnge;
+ if (pLangIt)
+ {
+ eLnge = (LanguageType) pLangIt->GetValue();
+ if (eLnge == LANGUAGE_DONTKNOW) //! can this happen?
+ {
+ LanguageType eLatin, eCjk, eCtl;
+ pDoc->GetLanguage( eLatin, eCjk, eCtl );
+ eLnge = ( nScript == SCRIPTTYPE_ASIAN ) ? eCjk :
+ ( ( nScript == SCRIPTTYPE_COMPLEX ) ? eCtl : eLatin );
+ }
+ }
+ else
+ eLnge = LANGUAGE_ENGLISH_US;
+ if ( eLnge == LANGUAGE_SYSTEM )
+ eLnge = Application::GetSettings().GetLanguage(); // never use SYSTEM for spelling
+
+ return eLnge;
+}
+
+// static
+sal_Int32 ScViewUtil::GetTransliterationType( sal_uInt16 nSlotID )
+{
+ sal_Int32 nType = 0;
+ switch ( nSlotID )
+ {
+ case SID_TRANSLITERATE_SENTENCE_CASE:
+ nType = com::sun::star::i18n::TransliterationModulesExtra::SENTENCE_CASE;
+ break;
+ case SID_TRANSLITERATE_TITLE_CASE:
+ nType = com::sun::star::i18n::TransliterationModulesExtra::TITLE_CASE;
+ break;
+ case SID_TRANSLITERATE_TOGGLE_CASE:
+ nType = com::sun::star::i18n::TransliterationModulesExtra::TOGGLE_CASE;
+ break;
+ case SID_TRANSLITERATE_UPPER:
+ nType = com::sun::star::i18n::TransliterationModules_LOWERCASE_UPPERCASE;
+ break;
+ case SID_TRANSLITERATE_LOWER:
+ nType = com::sun::star::i18n::TransliterationModules_UPPERCASE_LOWERCASE;
+ break;
+ case SID_TRANSLITERATE_HALFWIDTH:
+ nType = com::sun::star::i18n::TransliterationModules_FULLWIDTH_HALFWIDTH;
+ break;
+ case SID_TRANSLITERATE_FULLWIDTH:
+ nType = com::sun::star::i18n::TransliterationModules_HALFWIDTH_FULLWIDTH;
+ break;
+ case SID_TRANSLITERATE_HIRAGANA:
+ nType = com::sun::star::i18n::TransliterationModules_KATAKANA_HIRAGANA;
+ break;
+ case SID_TRANSLITERATE_KATAGANA:
+ nType = com::sun::star::i18n::TransliterationModules_HIRAGANA_KATAKANA;
+ break;
+ }
+ return nType;
+}
+
+// static
+sal_Bool ScViewUtil::IsActionShown( const ScChangeAction& rAction,
+ const ScChangeViewSettings& rSettings,
+ ScDocument& rDocument )
+{
+ // abgelehnte werden durch eine invertierende akzeptierte Action dargestellt,
+ // die Reihenfolge von ShowRejected/ShowAccepted ist deswegen wichtig
+
+ if ( !rSettings.IsShowRejected() && rAction.IsRejecting() )
+ return sal_False;
+
+ if ( !rSettings.IsShowAccepted() && rAction.IsAccepted() && !rAction.IsRejecting() )
+ return sal_False;
+
+ if ( rSettings.HasAuthor() )
+ {
+ if ( rSettings.IsEveryoneButMe() )
+ {
+ // GetUser() am ChangeTrack ist der aktuelle Benutzer
+ ScChangeTrack* pTrack = rDocument.GetChangeTrack();
+ if ( !pTrack || rAction.GetUser() == pTrack->GetUser() )
+ return sal_False;
+ }
+ else if ( rAction.GetUser() != rSettings.GetTheAuthorToShow() )
+ return sal_False;
+ }
+
+ if ( rSettings.HasComment() )
+ {
+ String aComStr=rAction.GetComment();
+ aComStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " (" ));
+ rAction.GetDescription( aComStr, &rDocument );
+ aComStr+=')';
+
+ if(!rSettings.IsValidComment(&aComStr))
+ return sal_False;
+ }
+
+ if ( rSettings.HasRange() )
+ if ( !rSettings.GetTheRangeList().Intersects( rAction.GetBigRange().MakeRange() ) )
+ return sal_False;
+
+ if ( rSettings.HasDate() && rSettings.GetTheDateMode() != SCDM_NO_DATEMODE )
+ {
+ DateTime aDateTime = rAction.GetDateTime();
+ const DateTime& rFirst = rSettings.GetTheFirstDateTime();
+ const DateTime& rLast = rSettings.GetTheLastDateTime();
+ switch ( rSettings.GetTheDateMode() )
+ { // korrespondiert mit ScHighlightChgDlg::OKBtnHdl
+ case SCDM_DATE_BEFORE:
+ if ( aDateTime > rFirst )
+ return sal_False;
+ break;
+
+ case SCDM_DATE_SINCE:
+ if ( aDateTime < rFirst )
+ return sal_False;
+ break;
+
+ case SCDM_DATE_EQUAL:
+ case SCDM_DATE_BETWEEN:
+ if ( aDateTime < rFirst || aDateTime > rLast )
+ return sal_False;
+ break;
+
+ case SCDM_DATE_NOTEQUAL:
+ if ( aDateTime >= rFirst && aDateTime <= rLast )
+ return sal_False;
+ break;
+
+ case SCDM_DATE_SAVE:
+ {
+ ScChangeTrack* pTrack = rDocument.GetChangeTrack();
+ if ( !pTrack || pTrack->GetLastSavedActionNumber() >=
+ rAction.GetActionNumber() )
+ return sal_False;
+ }
+ break;
+
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+
+ if ( rSettings.HasActionRange() )
+ {
+ sal_uLong nAction = rAction.GetActionNumber();
+ sal_uLong nFirstAction;
+ sal_uLong nLastAction;
+ rSettings.GetTheActionRange( nFirstAction, nLastAction );
+ if ( nAction < nFirstAction || nAction > nLastAction )
+ {
+ return sal_False;
+ }
+ }
+
+ return sal_True;
+}
+
+// static
+void ScViewUtil::UnmarkFiltered( ScMarkData& rMark, ScDocument* pDoc )
+{
+ rMark.MarkToMulti();
+
+ ScRange aMultiArea;
+ rMark.GetMultiMarkArea( aMultiArea );
+ SCCOL nStartCol = aMultiArea.aStart.Col();
+ SCROW nStartRow = aMultiArea.aStart.Row();
+ SCCOL nEndCol = aMultiArea.aEnd.Col();
+ SCROW nEndRow = aMultiArea.aEnd.Row();
+
+ bool bChanged = false;
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if ( rMark.GetTableSelect(nTab ) )
+ {
+ for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
+ {
+ 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, nRow, nTab, nEndCol, nLastRow, nTab), false);
+ bChanged = true;
+ nRow = nLastRow;
+ }
+ }
+ }
+
+ if ( bChanged && !rMark.HasAnyMultiMarks() )
+ rMark.ResetMark();
+
+ rMark.MarkToSimple();
+}
+
+
+// static
+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();
+ 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, 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->HasFilteredRows(nStartRow, nEndRow, nTab))
+ return true;
+ }
+
+ return false;
+}
+
+// static
+void ScViewUtil::HideDisabledSlot( SfxItemSet& rSet, SfxBindings& rBindings, sal_uInt16 nSlotId )
+{
+ SvtCJKOptions aCJKOptions;
+ SvtCTLOptions aCTLOptions;
+ bool bEnabled = true;
+
+ switch( nSlotId )
+ {
+ case SID_CHINESE_CONVERSION:
+ case SID_HANGUL_HANJA_CONVERSION:
+ bEnabled = aCJKOptions.IsAnyEnabled();
+ break;
+
+ case SID_TRANSLITERATE_HALFWIDTH:
+ case SID_TRANSLITERATE_FULLWIDTH:
+ case SID_TRANSLITERATE_HIRAGANA:
+ case SID_TRANSLITERATE_KATAGANA:
+ bEnabled = aCJKOptions.IsChangeCaseMapEnabled();
+ break;
+
+ case SID_INSERT_RLM:
+ case SID_INSERT_LRM:
+ case SID_INSERT_ZWNBSP:
+ case SID_INSERT_ZWSP:
+ bEnabled = aCTLOptions.IsCTLFontEnabled();
+ break;
+
+ default:
+ DBG_ERRORFILE( "ScViewUtil::HideDisabledSlot - unknown slot ID" );
+ return;
+ }
+
+ rBindings.SetVisibleState( nSlotId, bEnabled );
+ if( !bEnabled )
+ rSet.DisableItem( nSlotId );
+}
+
+//==================================================================
+
+sal_Bool ScViewUtil::ExecuteCharMap( const SvxFontItem& rOldFont,
+ SfxViewFrame& rFrame,
+ SvxFontItem& rNewFont,
+ String& rString )
+{
+ sal_Bool bRet = sal_False;
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ if(pFact)
+ {
+ SfxAllItemSet aSet( rFrame.GetObjectShell()->GetPool() );
+ aSet.Put( SfxBoolItem( FN_PARAM_1, sal_False ) );
+ aSet.Put( SvxFontItem( rOldFont.GetFamily(), rOldFont.GetFamilyName(), rOldFont.GetStyleName(), rOldFont.GetPitch(), rOldFont.GetCharSet(), aSet.GetPool()->GetWhich( SID_ATTR_CHAR_FONT ) ) );
+ SfxAbstractDialog* pDlg = pFact->CreateSfxDialog( &rFrame.GetWindow(), aSet, rFrame.GetFrame().GetFrameInterface(), RID_SVXDLG_CHARMAP );
+ if ( pDlg->Execute() == RET_OK )
+ {
+ SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pItem, SfxStringItem, SID_CHARMAP, sal_False );
+ SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pFontItem, SvxFontItem, SID_ATTR_CHAR_FONT, sal_False );
+ if ( pItem )
+ rString = pItem->GetValue();
+ if ( pFontItem )
+ rNewFont = SvxFontItem( pFontItem->GetFamily(), pFontItem->GetFamilyName(), pFontItem->GetStyleName(), pFontItem->GetPitch(), pFontItem->GetCharSet(), rNewFont.Which() );
+ bRet = sal_True;
+ }
+ delete pDlg;
+ }
+ return bRet;
+}
+
+bool ScViewUtil::IsFullScreen( SfxViewShell& rViewShell )
+{
+ SfxBindings& rBindings = rViewShell.GetViewFrame()->GetBindings();
+ SfxPoolItem* pItem = 0;
+ bool bIsFullScreen = false;
+
+ if (rBindings.QueryState( SID_WIN_FULLSCREEN, pItem ) >= SFX_ITEM_DEFAULT)
+ bIsFullScreen = static_cast< SfxBoolItem* >( pItem )->GetValue();
+ return bIsFullScreen;
+}
+
+void ScViewUtil::SetFullScreen( SfxViewShell& rViewShell, bool bSet )
+{
+ if( IsFullScreen( rViewShell ) != bSet )
+ {
+ SfxBoolItem aItem( SID_WIN_FULLSCREEN, bSet );
+ rViewShell.GetDispatcher()->Execute( SID_WIN_FULLSCREEN, SFX_CALLMODE_RECORD, &aItem, 0L );
+ }
+}
+
+//------------------------------------------------------------------
+
+ScUpdateRect::ScUpdateRect( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
+{
+ PutInOrder( nX1, nX2 );
+ PutInOrder( nY1, nY2 );
+
+ nOldStartX = nX1;
+ nOldStartY = nY1;
+ nOldEndX = nX2;
+ nOldEndY = nY2;
+}
+
+void ScUpdateRect::SetNew( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
+{
+ PutInOrder( nX1, nX2 );
+ PutInOrder( nY1, nY2 );
+
+ nNewStartX = nX1;
+ nNewStartY = nY1;
+ nNewEndX = nX2;
+ nNewEndY = nY2;
+}
+
+sal_Bool ScUpdateRect::GetDiff( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
+{
+ if ( nNewStartX == nOldStartX && nNewEndX == nOldEndX &&
+ nNewStartY == nOldStartY && nNewEndY == nOldEndY )
+ {
+ rX1 = nNewStartX;
+ rY1 = nNewStartY;
+ rX2 = nNewStartX;
+ rY2 = nNewStartY;
+ return sal_False;
+ }
+
+ rX1 = Min(nNewStartX,nOldStartX);
+ rY1 = Min(nNewStartY,nOldStartY);
+ rX2 = Max(nNewEndX,nOldEndX);
+ rY2 = Max(nNewEndY,nOldEndY);
+
+ if ( nNewStartX == nOldStartX && nNewEndX == nOldEndX )
+ {
+ if ( nNewStartY == nOldStartY )
+ {
+ rY1 = Min( nNewEndY, nOldEndY );
+ rY2 = Max( nNewEndY, nOldEndY );
+ }
+ else if ( nNewEndY == nOldEndY )
+ {
+ rY1 = Min( nNewStartY, nOldStartY );
+ rY2 = Max( nNewStartY, nOldStartY );
+ }
+ }
+ else if ( nNewStartY == nOldStartY && nNewEndY == nOldEndY )
+ {
+ if ( nNewStartX == nOldStartX )
+ {
+ rX1 = Min( nNewEndX, nOldEndX );
+ rX2 = Max( nNewEndX, nOldEndX );
+ }
+ else if ( nNewEndX == nOldEndX )
+ {
+ rX1 = Min( nNewStartX, nOldStartX );
+ rX2 = Max( nNewStartX, nOldStartX );
+ }
+ }
+
+ return sal_True;
+}
+
+#ifdef OLD_SELECTION_PAINT
+sal_Bool ScUpdateRect::GetXorDiff( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2, sal_Bool& rCont )
+{
+ rCont = sal_False;
+
+ if (nNewStartX == nOldStartX && nNewEndX == nOldEndX &&
+ nNewStartY == nOldStartY && nNewEndY == nOldEndY)
+ {
+ rX1 = nNewStartX;
+ rY1 = nNewStartY;
+ rX2 = nNewStartX;
+ rY2 = nNewStartY;
+ return sal_False;
+ }
+
+ rX1 = Min(nNewStartX,nOldStartX);
+ rY1 = Min(nNewStartY,nOldStartY);
+ rX2 = Max(nNewEndX,nOldEndX);
+ rY2 = Max(nNewEndY,nOldEndY);
+
+ if (nNewStartX == nOldStartX && nNewEndX == nOldEndX) // nur vertikal
+ {
+ if (nNewStartY == nOldStartY)
+ {
+ rY1 = Min( nNewEndY, nOldEndY ) + 1;
+ rY2 = Max( nNewEndY, nOldEndY );
+ }
+ else if (nNewEndY == nOldEndY)
+ {
+ rY1 = Min( nNewStartY, nOldStartY );
+ rY2 = Max( nNewStartY, nOldStartY ) - 1;
+ }
+ else
+ {
+ rY1 = Min( nNewStartY, nOldStartY );
+ rY2 = Max( nNewStartY, nOldStartY ) - 1;
+ rCont = sal_True;
+ nContY1 = Min( nNewEndY, nOldEndY ) + 1;
+ nContY2 = Max( nNewEndY, nOldEndY );
+ nContX1 = rX1;
+ nContX2 = rX2;
+ }
+ }
+ else if (nNewStartY == nOldStartY && nNewEndY == nOldEndY) // nur horizontal
+ {
+ if (nNewStartX == nOldStartX)
+ {
+ rX1 = Min( nNewEndX, nOldEndX ) + 1;
+ rX2 = Max( nNewEndX, nOldEndX );
+ }
+ else if (nNewEndX == nOldEndX)
+ {
+ rX1 = Min( nNewStartX, nOldStartX );
+ rX2 = Max( nNewStartX, nOldStartX ) - 1;
+ }
+ else
+ {
+ rX1 = Min( nNewStartX, nOldStartX );
+ rX2 = Max( nNewStartX, nOldStartX ) - 1;
+ rCont = sal_True;
+ nContX1 = Min( nNewEndX, nOldEndX ) + 1;
+ nContX2 = Max( nNewEndX, nOldEndX );
+ nContY1 = rY1;
+ nContY2 = rY2;
+ }
+ }
+ else if (nNewEndX == nOldEndX && nNewEndY == nOldEndY) // links oben
+ {
+ if ((nNewStartX<nOldStartX) == (nNewStartY<nOldStartY))
+ rX1 = Min( nNewStartX, nOldStartX );
+ else
+ rX1 = Max( nNewStartX, nOldStartX ); // Ecke weglassen
+ rX2 = nOldEndX;
+ rY1 = Min( nNewStartY, nOldStartY ); // oben
+ rY2 = Max( nNewStartY, nOldStartY ) - 1;
+ rCont = sal_True;
+ nContY1 = rY2+1;
+ nContY2 = nOldEndY;
+ nContX1 = Min( nNewStartX, nOldStartX ); // links
+ nContX2 = Max( nNewStartX, nOldStartX ) - 1;
+ }
+ else if (nNewStartX == nOldStartX && nNewEndY == nOldEndY) // rechts oben
+ {
+ if ((nNewEndX<nOldEndX) != (nNewStartY<nOldStartY))
+ rX2 = Max( nNewEndX, nOldEndX );
+ else
+ rX2 = Min( nNewEndX, nOldEndX ); // Ecke weglassen
+ rX1 = nOldStartX;
+ rY1 = Min( nNewStartY, nOldStartY ); // oben
+ rY2 = Max( nNewStartY, nOldStartY ) - 1;
+ rCont = sal_True;
+ nContY1 = rY2+1;
+ nContY2 = nOldEndY;
+ nContX1 = Min( nNewEndX, nOldEndX ) + 1; // rechts
+ nContX2 = Max( nNewEndX, nOldEndX );
+ }
+ else if (nNewEndX == nOldEndX && nNewStartY == nOldStartY) // links unten
+ {
+ if ((nNewStartX<nOldStartX) != (nNewEndY<nOldEndY))
+ rX1 = Min( nNewStartX, nOldStartX );
+ else
+ rX1 = Max( nNewStartX, nOldStartX ); // Ecke weglassen
+ rX2 = nOldEndX;
+ rY1 = Min( nNewEndY, nOldEndY ) + 1; // unten
+ rY2 = Max( nNewEndY, nOldEndY );
+ rCont = sal_True;
+ nContY1 = nOldStartY;
+ nContY2 = rY1-1;
+ nContX1 = Min( nNewStartX, nOldStartX ); // links
+ nContX2 = Max( nNewStartX, nOldStartX ) - 1;
+ }
+ else if (nNewStartX == nOldStartX && nNewStartY == nOldStartY) // rechts unten
+ {
+ if ((nNewEndX<nOldEndX) == (nNewEndY<nOldEndY))
+ rX2 = Max( nNewEndX, nOldEndX );
+ else
+ rX2 = Min( nNewEndX, nOldEndX ); // Ecke weglassen
+ rX1 = nOldStartX;
+ rY1 = Min( nNewEndY, nOldEndY ) + 1; // unten
+ rY2 = Max( nNewEndY, nOldEndY );
+ rCont = sal_True;
+ nContY1 = nOldStartY;
+ nContY2 = rY1-1;
+ nContX1 = Min( nNewEndX, nOldEndX ) + 1; // rechts
+ nContX2 = Max( nNewEndX, nOldEndX );
+ }
+ else // Ueberschlag
+ {
+ rX1 = nOldStartX;
+ rY1 = nOldStartY;
+ rX2 = nOldEndX;
+ rY2 = nOldEndY;
+ rCont = sal_True;
+ nContX1 = nNewStartX;
+ nContY1 = nNewStartY;
+ nContX2 = nNewEndX;
+ nContY2 = nNewEndY;
+ }
+
+ return sal_True;
+}
+
+void ScUpdateRect::GetContDiff( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
+{
+ rX1 = nContX1;
+ rY1 = nContY1;
+ rX2 = nContX2;
+ rY2 = nContY2;
+}
+#endif
+
+
+
+
+
+
diff --git a/sc/source/ui/view/waitoff.cxx b/sc/source/ui/view/waitoff.cxx
new file mode 100644
index 000000000000..2e3c3e8476af
--- /dev/null
+++ b/sc/source/ui/view/waitoff.cxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+//------------------------------------------------------------------------
+
+#include <vcl/window.hxx>
+
+#include "waitoff.hxx"
+
+//------------------------------------------------------------------------
+
+ScWaitCursorOff::ScWaitCursorOff( Window* pWinP )
+ :
+ pWin( pWinP ),
+ nWaiters(0)
+{
+ if ( pWin )
+ {
+ while ( pWin->IsWait() )
+ {
+ nWaiters++;
+ pWin->LeaveWait();
+ }
+ }
+}
+
+ScWaitCursorOff::~ScWaitCursorOff()
+{
+ if ( pWin )
+ {
+ while ( nWaiters )
+ {
+ nWaiters--;
+ pWin->EnterWait();
+ }
+ }
+}
+
+
+
+