summaryrefslogtreecommitdiff
path: root/sc/source/ui/docshell/docsh4.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/docshell/docsh4.cxx')
-rw-r--r--sc/source/ui/docshell/docsh4.cxx2718
1 files changed, 2718 insertions, 0 deletions
diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx
new file mode 100644
index 000000000000..353fff9043d4
--- /dev/null
+++ b/sc/source/ui/docshell/docsh4.cxx
@@ -0,0 +1,2718 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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/XEmbeddedObject.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+
+
+using namespace ::com::sun::star;
+
+// INCLUDE ---------------------------------------------------------------
+#if STLPORT_VERSION>=321
+#include <math.h> // prevent conflict between exception and std::exception
+#endif
+
+#include "scitems.hxx"
+#include <sfx2/fcontnr.hxx>
+#include <editeng/eeitem.hxx>
+
+#include <sfx2/app.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <svtools/ehdl.hxx>
+#include <basic/sbxcore.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/request.hxx>
+#include <svtools/sfxecode.hxx>
+#include <svx/ofaitem.hxx>
+#include <sot/formats.hxx>
+#include <svtools/printdlg.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/waitobj.hxx>
+#include <tools/multisel.hxx>
+#include <svx/drawitem.hxx>
+#include <svx/fmview.hxx>
+#include <svx/pageitem.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/fmshell.hxx>
+#include <svtools/xwindowitem.hxx>
+#include <sfx2/passwd.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/docinsert.hxx>
+#include <svl/PasswordHelper.hxx>
+#include <svl/documentlockfile.hxx>
+#include <svl/sharecontrolfile.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include "docuno.hxx"
+
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include "docsh.hxx"
+#include "docshimp.hxx"
+#include "docfunc.hxx"
+#include "sc.hrc"
+#include "stlsheet.hxx"
+#include "stlpool.hxx"
+#include "appoptio.hxx"
+#include "globstr.hrc"
+#include "global.hxx"
+#include "dbdocfun.hxx"
+#include "printfun.hxx" // DrawToDev
+#include "viewdata.hxx"
+#include "tabvwsh.hxx"
+#include "impex.hxx"
+#include "attrib.hxx"
+#include "undodat.hxx"
+#include "autostyl.hxx"
+#include "undocell.hxx"
+#include "undotab.hxx"
+#include "inputhdl.hxx"
+#include "dbcolect.hxx"
+#include "servobj.hxx"
+#include "rangenam.hxx"
+#include "scmod.hxx"
+#include "chgviset.hxx"
+#include "reffact.hxx"
+#include "chartlis.hxx"
+#include "waitoff.hxx"
+#include "tablink.hxx" // ScDocumentLoader statics
+#include "drwlayer.hxx"
+#include "docoptio.hxx"
+#include "undostyl.hxx"
+#include "rangeseq.hxx"
+#include "chgtrack.hxx"
+#include "printopt.hxx"
+#include <com/sun/star/document/UpdateDocMode.hpp>
+#include "scresid.hxx"
+#include "scabstdlg.hxx"
+#include "externalrefmgr.hxx"
+#include "sharedocdlg.hxx"
+#include "conditio.hxx"
+#include "sheetevents.hxx"
+
+//------------------------------------------------------------------
+
+#define IS_SHARE_HEADER(set) \
+ ((SfxBoolItem&) \
+ ((SvxSetItem&)(set).Get(ATTR_PAGE_HEADERSET)).GetItemSet(). \
+ Get(ATTR_PAGE_SHARED)).GetValue()
+
+#define IS_SHARE_FOOTER(set) \
+ ((SfxBoolItem&) \
+ ((SvxSetItem&)(set).Get(ATTR_PAGE_FOOTERSET)).GetItemSet(). \
+ Get(ATTR_PAGE_SHARED)).GetValue()
+
+#define IS_AVAILABLE(WhichId,ppItem) \
+ (pReqArgs->GetItemState((WhichId), TRUE, ppItem ) == SFX_ITEM_SET)
+
+#define SC_PREVIEW_SIZE_X 10000
+#define SC_PREVIEW_SIZE_Y 12400
+
+
+//------------------------------------------------------------------
+
+void ScDocShell::Execute( SfxRequest& rReq )
+{
+ // SID_SC_RANGE (Range),
+ // SID_SC_CELLTEXT (CellText),
+ // SID_SC_CELLS (Cells) - removed (old Basic)
+
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+ SfxBindings* pBindings = GetViewBindings();
+ BOOL bUndo (aDocument.IsUndoEnabled());
+
+ USHORT nSlot = rReq.GetSlot();
+ switch ( nSlot )
+ {
+ case SID_SC_SETTEXT:
+ {
+ const SfxPoolItem* pColItem;
+ const SfxPoolItem* pRowItem;
+ const SfxPoolItem* pTabItem;
+ const SfxPoolItem* pTextItem;
+ if( pReqArgs && IS_AVAILABLE( FN_PARAM_1, &pColItem ) &&
+ IS_AVAILABLE( FN_PARAM_2, &pRowItem ) &&
+ IS_AVAILABLE( FN_PARAM_3, &pTabItem ) &&
+ IS_AVAILABLE( SID_SC_SETTEXT, &pTextItem ) )
+ {
+ // Parameter sind 1-based !!!
+ SCCOL nCol = ((SfxInt16Item*)pColItem)->GetValue() - 1;
+ SCROW nRow = ((SfxInt32Item*)pRowItem)->GetValue() - 1;
+ SCTAB nTab = ((SfxInt16Item*)pTabItem)->GetValue() - 1;
+
+ SCTAB nTabCount = aDocument.GetTableCount();
+ if ( ValidCol(nCol) && ValidRow(nRow) && ValidTab(nTab,nTabCount) )
+ {
+ if ( aDocument.IsBlockEditable( nTab, nCol,nRow, nCol, nRow ) )
+ {
+ String aVal = ((const SfxStringItem*)pTextItem)->GetValue();
+ aDocument.SetString( nCol, nRow, nTab, aVal );
+
+ PostPaintCell( nCol, nRow, nTab );
+ SetDocumentModified();
+
+ rReq.Done();
+ break;
+ }
+ else // geschuetzte Zelle
+ {
+ SbxBase::SetError( SbxERR_BAD_PARAMETER ); //! welchen Fehler ?
+ break;
+ }
+ }
+ }
+ SbxBase::SetError( SbxERR_NO_OBJECT );
+ }
+ break;
+
+
+ // SID_SBA_QRY_CHANGETARGET gibts nicht mehr - auch in idl raus
+
+ case SID_SBA_IMPORT:
+ {
+ if (pReqArgs)
+ {
+ const sal_Unicode cSbaSep = 11; // Trennzeichen
+
+ const SfxPoolItem* pItem;
+ String sSbaData, sTarget;
+ if ( pReqArgs->GetItemState( nSlot, TRUE, &pItem ) == SFX_ITEM_SET )
+ sSbaData = ((const SfxStringItem*)pItem)->GetValue();
+ if ( pReqArgs->GetItemState( FN_PARAM_1, TRUE, &pItem ) == SFX_ITEM_SET )
+ sTarget = ((const SfxStringItem*)pItem)->GetValue();
+
+ BOOL bIsNewArea = TRUE; // Default TRUE (keine Nachfrage)
+ if ( pReqArgs->GetItemState( FN_PARAM_2, TRUE, &pItem ) == SFX_ITEM_SET )
+ bIsNewArea = ((const SfxBoolItem*)pItem)->GetValue();
+
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::sdbc::XResultSet > xResultSet;
+ if ( pReqArgs->GetItemState( FN_PARAM_3, FALSE, &pItem ) == SFX_ITEM_SET && pItem )
+ xResultSet.set(((const SfxUsrAnyItem*)pItem)->GetValue(),::com::sun::star::uno::UNO_QUERY);
+
+ String sDBName = sSbaData.GetToken(0,cSbaSep); // Datenbankname
+ String sDBTable = sSbaData.GetToken(1,cSbaSep); // Tabellen- oder Query-Name
+ String sTabFlag = sSbaData.GetToken(2,cSbaSep);
+ String sDBSql = sSbaData.GetToken(3,cSbaSep); // SQL im Klartext
+
+ BYTE nType = ScDbTable; // "0" oder "1"
+ if ( sTabFlag.EqualsAscii("0") ) // "0" = Query, "1" = Table (Default)
+ nType = ScDbQuery;
+
+ SbaSelectionListRef pSelectionList = new SbaSelectionList;
+ xub_StrLen nCount = sSbaData.GetTokenCount(cSbaSep);
+
+ for (xub_StrLen i = 4; i < nCount; i++)
+ {
+ String aSelItem = sSbaData.GetToken(i,cSbaSep);
+ if (aSelItem.Len())
+ {
+ void *pPtr = (void*)aSelItem.ToInt32();
+ pSelectionList->Insert( pPtr, LIST_APPEND );
+ }
+ }
+
+ // bei Bedarf neuen Datenbankbereich anlegen
+ BOOL bMakeArea = FALSE;
+ if (bIsNewArea)
+ {
+ ScDBCollection* pDBColl = aDocument.GetDBCollection();
+ USHORT nDummy;
+ if ( !pDBColl || !pDBColl->SearchName( sTarget, nDummy ) )
+ {
+ ScAddress aPos;
+ if ( aPos.Parse( sTarget, &aDocument, aDocument.GetAddressConvention() ) & SCA_VALID )
+ {
+ bMakeArea = TRUE;
+ if (bUndo)
+ {
+ String aStrImport = ScGlobal::GetRscString( STR_UNDO_IMPORTDATA );
+ GetUndoManager()->EnterListAction( aStrImport, aStrImport );
+ }
+
+ ScDBData* pDBData = GetDBData( ScRange(aPos), SC_DB_IMPORT, SC_DBSEL_KEEP );
+ DBG_ASSERT(pDBData, "kann DB-Daten nicht anlegen");
+ sTarget = pDBData->GetName();
+ }
+ }
+ }
+
+ // nachfragen, bevor alter DB-Bereich ueberschrieben wird
+ BOOL bDo = TRUE;
+ if (!bIsNewArea)
+ {
+ String aTemplate = ScGlobal::GetRscString( STR_IMPORT_REPLACE );
+ String aMessage = aTemplate.GetToken( 0, '#' );
+ aMessage += sTarget;
+ aMessage += aTemplate.GetToken( 1, '#' );
+
+ QueryBox aBox( 0, WinBits(WB_YES_NO | WB_DEF_YES), aMessage );
+ bDo = ( aBox.Execute() == RET_YES );
+ }
+
+ if (bDo)
+ {
+ ScDBDocFunc(*this).UpdateImport( sTarget, sDBName,
+ sDBTable, sDBSql, TRUE, nType, xResultSet,
+ pSelectionList );
+ rReq.Done();
+
+ // UpdateImport aktualisiert auch die internen Operationen
+ }
+ else
+ rReq.Ignore();
+
+ if ( bMakeArea && bUndo)
+ GetUndoManager()->LeaveListAction();
+ }
+ else
+ {
+ DBG_ERROR( "arguments expected" );
+ }
+ }
+ break;
+
+ case SID_CHART_SOURCE:
+ case SID_CHART_ADDSOURCE:
+ if (pReqArgs)
+ {
+ ScDocument* pDoc = GetDocument();
+// BOOL bUndo (pDoc->IsUndoEnabled());
+ const SfxPoolItem* pItem;
+ String aChartName, aRangeName;
+
+ ScRange aSingleRange;
+ ScRangeListRef aRangeListRef;
+ BOOL bMultiRange = FALSE;
+
+ BOOL bColHeaders = TRUE;
+ BOOL bRowHeaders = TRUE;
+ BOOL bColInit = FALSE;
+ BOOL bRowInit = FALSE;
+ BOOL bAddRange = (nSlot == SID_CHART_ADDSOURCE);
+
+ if( IS_AVAILABLE( SID_CHART_NAME, &pItem ) )
+ aChartName = ((const SfxStringItem*)pItem)->GetValue();
+
+ if( IS_AVAILABLE( SID_CHART_SOURCE, &pItem ) )
+ aRangeName = ((const SfxStringItem*)pItem)->GetValue();
+
+ if( IS_AVAILABLE( FN_PARAM_1, &pItem ) )
+ {
+ bColHeaders = ((const SfxBoolItem*)pItem)->GetValue();
+ bColInit = TRUE;
+ }
+ if( IS_AVAILABLE( FN_PARAM_2, &pItem ) )
+ {
+ bRowHeaders = ((const SfxBoolItem*)pItem)->GetValue();
+ bRowInit = TRUE;
+ }
+
+ ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
+ BOOL bValid = ( aSingleRange.ParseAny( aRangeName, pDoc, aDetails ) & SCA_VALID ) != 0;
+ if (!bValid)
+ {
+ aRangeListRef = new ScRangeList;
+ aRangeListRef->Parse( aRangeName, pDoc );
+ if ( aRangeListRef->Count() )
+ {
+ bMultiRange = TRUE;
+ aSingleRange = *aRangeListRef->GetObject(0); // fuer Header
+ bValid = TRUE;
+ }
+ else
+ aRangeListRef.Clear();
+ }
+
+ ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
+ if (pViewSh && bValid && aChartName.Len() != 0 )
+ {
+ Window* pParent = pViewSh->GetDialogParent();
+
+ SCCOL nCol1 = aSingleRange.aStart.Col();
+ SCROW nRow1 = aSingleRange.aStart.Row();
+ SCCOL nCol2 = aSingleRange.aEnd.Col();
+ SCROW nRow2 = aSingleRange.aEnd.Row();
+ SCTAB nTab = aSingleRange.aStart.Tab();
+
+ //! immer oder gar nicht begrenzen ???
+ if (!bMultiRange)
+ aDocument.LimitChartArea( nTab, nCol1,nRow1, nCol2,nRow2 );
+
+ // Dialog fuer Spalten/Zeilenkoepfe
+ BOOL bOk = TRUE;
+ if ( !bAddRange && ( !bColInit || !bRowInit ) )
+ {
+ // Spalten/Zeilenkoepfe testen wie in chartarr
+ if (!bColInit)
+ {
+ for (SCCOL i=nCol1; i<=nCol2 && bColHeaders; i++)
+ if (aDocument.HasValueData( i, nRow1, nTab ))
+ bColHeaders = FALSE;
+ }
+ if (!bRowInit)
+ {
+ for (SCROW i=nRow1; i<=nRow2 && bRowHeaders; i++)
+ if (aDocument.HasValueData( nCol1, i, nTab ))
+ bRowHeaders = FALSE;
+ }
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");
+
+ AbstractScColRowLabelDlg* pDlg = pFact->CreateScColRowLabelDlg( pParent, RID_SCDLG_CHARTCOLROW, bRowHeaders, bColHeaders);
+ DBG_ASSERT(pDlg, "Dialog create fail!");
+ if ( pDlg->Execute() == RET_OK )
+ {
+ bColHeaders = pDlg->IsRow();
+ bRowHeaders = pDlg->IsCol();
+
+ rReq.AppendItem(SfxBoolItem(FN_PARAM_1, bColHeaders));
+ rReq.AppendItem(SfxBoolItem(FN_PARAM_2, bRowHeaders));
+ }
+ else
+ bOk = FALSE;
+ delete pDlg;
+ }
+
+ if (bOk) // ausfuehren
+ {
+ if (bMultiRange)
+ {
+ if (bUndo)
+ {
+ GetUndoManager()->AddUndoAction(
+ new ScUndoChartData( this, aChartName, aRangeListRef,
+ bColHeaders, bRowHeaders, bAddRange ) );
+ }
+ aDocument.UpdateChartArea( aChartName, aRangeListRef,
+ bColHeaders, bRowHeaders, bAddRange );
+ }
+ else
+ {
+ ScRange aNewRange( nCol1,nRow1,nTab, nCol2,nRow2,nTab );
+ if (bUndo)
+ {
+ GetUndoManager()->AddUndoAction(
+ new ScUndoChartData( this, aChartName, aNewRange,
+ bColHeaders, bRowHeaders, bAddRange ) );
+ }
+ aDocument.UpdateChartArea( aChartName, aNewRange,
+ bColHeaders, bRowHeaders, bAddRange );
+ }
+ }
+ }
+ else
+ {
+ DBG_ERROR("UpdateChartArea: keine ViewShell oder falsche Daten");
+ }
+ rReq.Done();
+ }
+ else
+ {
+ DBG_ERROR("SID_CHART_SOURCE ohne Argumente");
+ }
+ break;
+
+ case FID_AUTO_CALC:
+ {
+ BOOL bNewVal;
+ const SfxPoolItem* pItem;
+ if ( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( nSlot, TRUE, &pItem ) )
+ bNewVal = ((const SfxBoolItem*)pItem)->GetValue();
+ else
+ bNewVal = !aDocument.GetAutoCalc(); // Toggle fuer Menue
+ aDocument.SetAutoCalc( bNewVal );
+ SetDocumentModified();
+ if (pBindings)
+ {
+ pBindings->Invalidate( FID_AUTO_CALC );
+// pBindings->Invalidate( FID_RECALC ); // jetzt immer enabled
+ }
+ rReq.AppendItem( SfxBoolItem( FID_AUTO_CALC, bNewVal ) );
+ rReq.Done();
+ }
+ break;
+ case FID_RECALC:
+ DoRecalc( rReq.IsAPI() );
+ rReq.Done();
+ break;
+ case FID_HARD_RECALC:
+ DoHardRecalc( rReq.IsAPI() );
+ rReq.Done();
+ break;
+ case SID_UPDATETABLINKS:
+ {
+ ScDocument* pDoc = GetDocument();
+
+ ScLkUpdMode nSet=pDoc->GetLinkMode();
+
+ USHORT nDlgRet=RET_NO;
+ if(nSet==LM_UNKNOWN)
+ {
+ ScAppOptions aAppOptions=SC_MOD()->GetAppOptions();
+ nSet=aAppOptions.GetLinkMode();
+ }
+
+ if (nCanUpdate == com::sun::star::document::UpdateDocMode::NO_UPDATE)
+ nSet = LM_NEVER;
+ else if (nCanUpdate == com::sun::star::document::UpdateDocMode::QUIET_UPDATE &&
+ nSet == LM_ON_DEMAND)
+ nSet = LM_NEVER;
+ else if (nCanUpdate == com::sun::star::document::UpdateDocMode::FULL_UPDATE)
+ nSet = LM_ALWAYS;
+
+ if(nSet==LM_ON_DEMAND)
+ {
+ QueryBox aBox( GetActiveDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
+ ScGlobal::GetRscString(STR_RELOAD_TABLES) );
+
+ nDlgRet=aBox.Execute();
+ }
+
+ if (nDlgRet == RET_YES || nSet==LM_ALWAYS)
+ {
+ ReloadTabLinks();
+ aDocument.UpdateExternalRefLinks();
+ aDocument.UpdateDdeLinks();
+ aDocument.UpdateAreaLinks();
+
+ //! Test, ob Fehler
+ rReq.Done();
+ }
+ else
+ rReq.Ignore();
+ }
+ break;
+
+ case SID_REIMPORT_AFTER_LOAD:
+ {
+ // wird nach dem Laden aufgerufen, wenn DB-Bereiche mit
+ // weggelassenen Daten enthalten sind
+
+ BOOL bDone = FALSE;
+ ScDBCollection* pDBColl = aDocument.GetDBCollection();
+
+ if ((nCanUpdate != com::sun::star::document::UpdateDocMode::NO_UPDATE) &&
+ (nCanUpdate != com::sun::star::document::UpdateDocMode::QUIET_UPDATE))
+ {
+ ScRange aRange;
+ ScTabViewShell* pViewSh = GetBestViewShell();
+ DBG_ASSERT(pViewSh,"SID_REIMPORT_AFTER_LOAD: keine View");
+ if (pViewSh && pDBColl)
+ {
+ QueryBox aBox( GetActiveDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
+ ScGlobal::GetRscString(STR_REIMPORT_AFTER_LOAD) );
+ if (aBox.Execute() == RET_YES)
+ {
+ for (USHORT i=0; i<pDBColl->GetCount(); i++)
+ {
+ ScDBData* pDBData = (*pDBColl)[i];
+ if ( pDBData->IsStripData() &&
+ pDBData->HasImportParam() && !pDBData->HasImportSelection() )
+ {
+ pDBData->GetArea(aRange);
+ pViewSh->MarkRange(aRange);
+
+ // Import und interne Operationen wie SID_REFRESH_DBAREA
+ // (Abfrage auf Import hier nicht noetig)
+
+ ScImportParam aImportParam;
+ pDBData->GetImportParam( aImportParam );
+ BOOL bContinue = pViewSh->ImportData( aImportParam );
+ pDBData->SetImportParam( aImportParam );
+
+ // markieren (Groesse kann sich geaendert haben)
+ pDBData->GetArea(aRange);
+ pViewSh->MarkRange(aRange);
+
+ if ( bContinue ) // #41905# Fehler beim Import -> Abbruch
+ {
+ // interne Operationen, wenn welche gespeichert
+
+ if ( pDBData->HasQueryParam() || pDBData->HasSortParam() ||
+ pDBData->HasSubTotalParam() )
+ pViewSh->RepeatDB();
+
+ // Pivottabellen die den Bereich als Quelldaten haben
+
+ RefreshPivotTables(aRange);
+ }
+ }
+ }
+ bDone = TRUE;
+ }
+ }
+ }
+
+ if ( !bDone && pDBColl )
+ {
+ // wenn nicht, dann aber die abhaengigen Formeln updaten
+ //! auch fuer einzelne Bereiche, die nicht aktualisiert werden koennen
+
+ aDocument.CalcAll(); //! nur die abhaengigen
+ PostDataChanged();
+ }
+
+ if (bDone)
+ rReq.Done();
+ else
+ rReq.Ignore();
+ }
+ break;
+
+
+ case SID_AUTO_STYLE:
+ DBG_ERROR("use ScAutoStyleHint instead of SID_AUTO_STYLE");
+ break;
+
+ case SID_GET_COLORTABLE:
+ {
+ // passende ColorTable ist per PutItem gesetzt worden
+ SvxColorTableItem* pColItem = (SvxColorTableItem*)GetItem(SID_COLOR_TABLE);
+ XColorTable* pTable = pColItem->GetColorTable();
+ rReq.SetReturnValue(OfaPtrItem(SID_GET_COLORTABLE, pTable));
+ }
+ break;
+
+ case FID_CHG_RECORD:
+ {
+ ScDocument* pDoc = GetDocument();
+ if(pDoc!=NULL)
+ {
+ // get argument (recorded macro)
+ SFX_REQUEST_ARG( rReq, pItem, SfxBoolItem, FID_CHG_RECORD, sal_False );
+ BOOL bDo = TRUE;
+
+ // xmlsec05/06:
+ // getting real parent window when called from Security-Options TP
+ Window* pParent = NULL;
+ const SfxPoolItem* pParentItem;
+ if( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( SID_ATTR_XWINDOW, FALSE, &pParentItem ) )
+ pParent = ( ( const XWindowItem* ) pParentItem )->GetWindowPtr();
+
+ // desired state
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ BOOL bActivateTracking = (pChangeTrack == 0); // toggle
+ if ( pItem )
+ bActivateTracking = pItem->GetValue(); // from argument
+
+ if ( !bActivateTracking )
+ {
+ if ( !pItem )
+ {
+ // no dialog on playing the macro
+ WarningBox aBox( pParent ? pParent : GetActiveDialogParent(),
+ WinBits(WB_YES_NO | WB_DEF_NO),
+ ScGlobal::GetRscString( STR_END_REDLINING ) );
+ bDo = ( aBox.Execute() == RET_YES );
+ }
+
+ if ( bDo )
+ {
+ if ( pChangeTrack->IsProtected() )
+ bDo = ExecuteChangeProtectionDialog( NULL );
+ if ( bDo )
+ {
+ pDoc->EndChangeTracking();
+ PostPaintGridAll();
+ }
+ }
+ }
+ else
+ {
+ pDoc->StartChangeTracking();
+ ScChangeViewSettings aChangeViewSet;
+ aChangeViewSet.SetShowChanges(TRUE);
+ pDoc->SetChangeViewSettings(aChangeViewSet);
+ }
+
+ if ( bDo )
+ {
+ UpdateAcceptChangesDialog();
+
+ // Slots invalidieren
+ if (pBindings)
+ pBindings->InvalidateAll(FALSE);
+ if ( !pItem )
+ rReq.AppendItem( SfxBoolItem( FID_CHG_RECORD, bActivateTracking ) );
+ rReq.Done();
+ }
+ else
+ rReq.Ignore();
+ }
+ }
+ break;
+
+ case SID_CHG_PROTECT :
+ {
+ Window* pParent = NULL;
+ const SfxPoolItem* pParentItem;
+ if( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( SID_ATTR_XWINDOW, FALSE, &pParentItem ) )
+ pParent = ( ( const XWindowItem* ) pParentItem )->GetWindowPtr();
+ if ( ExecuteChangeProtectionDialog( pParent ) )
+ {
+ rReq.Done();
+ SetDocumentModified();
+ }
+ else
+ rReq.Ignore();
+ }
+ break;
+
+ case SID_DOCUMENT_MERGE:
+ case SID_DOCUMENT_COMPARE:
+ {
+ BOOL bDo = TRUE;
+ ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
+ if ( pChangeTrack && !pImpl->bIgnoreLostRedliningWarning )
+ {
+ if ( nSlot == SID_DOCUMENT_COMPARE )
+ { //! old changes trace will be lost
+ WarningBox aBox( GetActiveDialogParent(),
+ WinBits(WB_YES_NO | WB_DEF_NO),
+ ScGlobal::GetRscString( STR_END_REDLINING ) );
+ if( aBox.Execute() == RET_YES )
+ bDo = ExecuteChangeProtectionDialog( NULL, TRUE );
+ else
+ bDo = FALSE;
+ }
+ else // merge might reject some actions
+ bDo = ExecuteChangeProtectionDialog( NULL, TRUE );
+ }
+ if ( !bDo )
+ {
+ rReq.Ignore();
+ break;
+ }
+ SfxApplication* pApp = SFX_APP();
+ const SfxPoolItem* pItem;
+ SfxMedium* pMed = NULL;
+ if ( pReqArgs &&
+ pReqArgs->GetItemState( SID_FILE_NAME, TRUE, &pItem ) == SFX_ITEM_SET &&
+ pItem->ISA(SfxStringItem) )
+ {
+ String aFileName = ((const SfxStringItem*)pItem)->GetValue();
+
+ String aFilterName;
+ if ( pReqArgs->GetItemState( SID_FILTER_NAME, TRUE, &pItem ) == SFX_ITEM_SET &&
+ pItem->ISA(SfxStringItem) )
+ {
+ aFilterName = ((const SfxStringItem*)pItem)->GetValue();
+ }
+ String aOptions;
+ if ( pReqArgs->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) == SFX_ITEM_SET &&
+ pItem->ISA(SfxStringItem) )
+ {
+ aOptions = ((const SfxStringItem*)pItem)->GetValue();
+ }
+ short nVersion = 0;
+ if ( pReqArgs->GetItemState( SID_VERSION, TRUE, &pItem ) == SFX_ITEM_SET &&
+ pItem->ISA(SfxInt16Item) )
+ {
+ nVersion = ((const SfxInt16Item*)pItem)->GetValue();
+ }
+
+ // kein Filter angegeben -> Detection
+ if ( !aFilterName.Len() )
+ ScDocumentLoader::GetFilterName( aFileName, aFilterName, aOptions, TRUE, FALSE );
+
+ // filter name from dialog contains application prefix,
+ // GetFilter needs name without the prefix.
+ ScDocumentLoader::RemoveAppPrefix( aFilterName );
+
+ const SfxFilter* pFilter = ScDocShell::Factory().GetFilterContainer()->GetFilter4FilterName( aFilterName );
+ SfxItemSet* pSet = new SfxAllItemSet( pApp->GetPool() );
+ if ( aOptions.Len() )
+ pSet->Put( SfxStringItem( SID_FILE_FILTEROPTIONS, aOptions ) );
+ if ( nVersion != 0 )
+ pSet->Put( SfxInt16Item( SID_VERSION, nVersion ) );
+ pMed = new SfxMedium( aFileName, STREAM_STD_READ, FALSE, pFilter, pSet );
+ }
+ else
+ {
+ // start file dialog asynchronous
+ pImpl->bIgnoreLostRedliningWarning = true;
+ delete pImpl->pRequest;
+ pImpl->pRequest = new SfxRequest( rReq );
+ delete pImpl->pDocInserter;
+ pImpl->pDocInserter = new ::sfx2::DocumentInserter(
+ 0, String::CreateFromAscii( ScDocShell::Factory().GetShortName() ), 0 );
+ pImpl->pDocInserter->StartExecuteModal( LINK( this, ScDocShell, DialogClosedHdl ) );
+ return ;
+ }
+
+ if ( pMed ) // nun wirklich ausfuehren...
+ {
+ SfxErrorContext aEc( ERRCTX_SFX_OPENDOC, pMed->GetName() );
+
+ ScDocShell* pOtherDocSh = new ScDocShell;
+ SfxObjectShellRef aDocShTablesRef = pOtherDocSh;
+ pOtherDocSh->DoLoad( pMed );
+ ULONG nErr = pOtherDocSh->GetErrorCode();
+ if (nErr)
+ ErrorHandler::HandleError( nErr ); // auch Warnings
+
+ if ( !pOtherDocSh->GetError() ) // nur Errors
+ {
+ BOOL bHadTrack = ( aDocument.GetChangeTrack() != NULL );
+ ULONG nStart = 0;
+ if ( nSlot == SID_DOCUMENT_MERGE && pChangeTrack )
+ {
+ nStart = pChangeTrack->GetActionMax() + 1;
+ }
+
+ if ( nSlot == SID_DOCUMENT_COMPARE )
+ CompareDocument( *pOtherDocSh->GetDocument() );
+ else
+ MergeDocument( *pOtherDocSh->GetDocument() );
+
+ // show "accept changes" dialog
+ //! get view for this document!
+ if ( !IsDocShared() )
+ {
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if ( pViewFrm )
+ {
+ pViewFrm->ShowChildWindow( ScAcceptChgDlgWrapper::GetChildWindowId(), TRUE ); //@51669
+ }
+ if ( pBindings )
+ {
+ pBindings->Invalidate( FID_CHG_ACCEPT );
+ }
+ }
+
+ rReq.SetReturnValue( SfxInt32Item( nSlot, 0 ) ); //! ???????
+ rReq.Done();
+
+ if (!bHadTrack) // neu eingeschaltet -> auch anzeigen
+ {
+ ScChangeViewSettings* pOldSet = aDocument.GetChangeViewSettings();
+ if ( !pOldSet || !pOldSet->ShowChanges() )
+ {
+ ScChangeViewSettings aChangeViewSet;
+ aChangeViewSet.SetShowChanges(TRUE);
+ aDocument.SetChangeViewSettings(aChangeViewSet);
+ }
+ }
+ else if ( nSlot == SID_DOCUMENT_MERGE && IsDocShared() && pChangeTrack )
+ {
+ ULONG nEnd = pChangeTrack->GetActionMax();
+ if ( nEnd >= nStart )
+ {
+ // only show changes from merged document
+ ScChangeViewSettings aChangeViewSet;
+ aChangeViewSet.SetShowChanges( TRUE );
+ aChangeViewSet.SetShowAccepted( TRUE );
+ aChangeViewSet.SetHasActionRange( true );
+ aChangeViewSet.SetTheActionRange( nStart, nEnd );
+ aDocument.SetChangeViewSettings( aChangeViewSet );
+
+ // update view
+ PostPaintExtras();
+ PostPaintGridAll();
+ }
+ }
+ }
+ pOtherDocSh->DoClose(); // delete passiert mit der Ref
+ }
+ }
+ break;
+
+ case SID_DELETE_SCENARIO:
+ if (pReqArgs)
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( nSlot, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ if ( pItem->ISA(SfxStringItem) )
+ {
+ String aName = ((const SfxStringItem*)pItem)->GetValue();
+ SCTAB nTab;
+ if (aDocument.GetTable( aName, nTab ))
+ {
+ // DeleteTable von viewfunc nach docfunc verschieben!
+
+ ScTabViewShell* pSh = GetBestViewShell();
+ if ( pSh )
+ {
+ //! SetTabNo in DeleteTable weglassen?
+ SCTAB nDispTab = pSh->GetViewData()->GetTabNo();
+ pSh->DeleteTable( nTab );
+ pSh->SetTabNo(nDispTab);
+ rReq.Done();
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case SID_EDIT_SCENARIO:
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( nSlot, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ if ( pItem->ISA(SfxStringItem) )
+ {
+ String aName = ((const SfxStringItem*)pItem)->GetValue();
+ SCTAB nTab;
+ if (aDocument.GetTable( aName, nTab ))
+ {
+ if (aDocument.IsScenario(nTab))
+ {
+ String aComment;
+ Color aColor;
+ USHORT nFlags;
+ aDocument.GetScenarioData( nTab, aComment, aColor, nFlags );
+
+ // Determine if the Sheet that the Scenario was created on
+ // is protected. But first we need to find that Sheet.
+ // Rewind back to the actual sheet.
+ SCTAB nActualTab = nTab;
+ do
+ {
+ nActualTab--;
+ }
+ while(aDocument.IsScenario(nActualTab));
+ BOOL bSheetProtected = aDocument.IsTabProtected(nActualTab);
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");
+
+ AbstractScNewScenarioDlg* pNewDlg = pFact->CreateScNewScenarioDlg( GetActiveDialogParent(), aName, RID_SCDLG_NEWSCENARIO, TRUE,bSheetProtected);
+ DBG_ASSERT(pNewDlg, "Dialog create fail!");
+ pNewDlg->SetScenarioData( aName, aComment, aColor, nFlags );
+ if ( pNewDlg->Execute() == RET_OK )
+ {
+ pNewDlg->GetScenarioData( aName, aComment, aColor, nFlags );
+ ModifyScenario( nTab, aName, aComment, aColor, nFlags );
+ rReq.Done();
+ }
+ delete pNewDlg;
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case SID_ATTR_YEAR2000 :
+ {
+ const SfxPoolItem* pItem;
+ if ( pReqArgs->GetItemState( nSlot, TRUE, &pItem ) == SFX_ITEM_SET )
+ {
+ if ( pItem->ISA(SfxUInt16Item) )
+ {
+ UINT16 nY2k = ((SfxUInt16Item*)pItem)->GetValue();
+ // immer an den DocOptions setzen, damit das auch fuer SO50
+ // gespeichert wird (und alle Abfragen bisher auch darauf laufen).
+ // SetDocOptions propagiert das an den NumberFormatter
+ ScDocOptions aDocOpt( aDocument.GetDocOptions() );
+ aDocOpt.SetYear2000( nY2k );
+ aDocument.SetDocOptions( aDocOpt );
+ // die FormShell soll es mitbekommen
+ ScTabViewShell* pSh = GetBestViewShell();
+ if ( pSh )
+ {
+ FmFormShell* pFSh = pSh->GetFormShell();
+ if ( pFSh )
+ pFSh->SetY2KState( nY2k );
+ }
+ }
+ }
+ }
+ break;
+
+ case SID_SHARE_DOC:
+ {
+ ScViewData* pViewData = GetViewData();
+ if ( !pViewData )
+ {
+ rReq.Ignore();
+ break;
+ }
+
+ ScShareDocumentDlg aDlg( GetActiveDialogParent(), pViewData );
+ if ( aDlg.Execute() == RET_OK )
+ {
+ bool bSetShared = aDlg.IsShareDocumentChecked();
+ if ( bSetShared != static_cast< bool >( IsDocShared() ) )
+ {
+ if ( bSetShared )
+ {
+ bool bContinue = true;
+ if ( HasName() )
+ {
+ QueryBox aBox( GetActiveDialogParent(), WinBits( WB_YES_NO | WB_DEF_YES ),
+ ScGlobal::GetRscString( STR_DOC_WILLBESAVED ) );
+ if ( aBox.Execute() == RET_NO )
+ {
+ bContinue = false;
+ }
+ }
+ if ( bContinue )
+ {
+ EnableSharedSettings( true );
+
+ SC_MOD()->SetInSharedDocSaving( true );
+ if ( !SwitchToShared( sal_True, sal_True ) )
+ {
+ // TODO/LATER: what should be done in case the switch has failed?
+ // for example in case the user has cancelled the saveAs operation
+ }
+
+ SC_MOD()->SetInSharedDocSaving( false );
+
+ InvalidateName();
+ GetUndoManager()->Clear();
+
+ ScTabView* pTabView = dynamic_cast< ScTabView* >( pViewData->GetView() );
+ if ( pTabView )
+ {
+ pTabView->UpdateLayerLocks();
+ }
+ }
+ }
+ else
+ {
+ uno::Reference< frame::XModel > xModel;
+ try
+ {
+ // load shared file
+ xModel.set( LoadSharedDocument(), uno::UNO_QUERY_THROW );
+ uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY_THROW );
+
+ // check if shared flag is set in shared file
+ bool bShared = false;
+ ScModelObj* pDocObj = ScModelObj::getImplementation( xModel );
+ if ( pDocObj )
+ {
+ ScDocShell* pDocShell = dynamic_cast< ScDocShell* >( pDocObj->GetEmbeddedObject() );
+ if ( pDocShell )
+ {
+ bShared = pDocShell->HasSharedXMLFlagSet();
+ }
+ }
+
+ // #i87870# check if shared status was disabled and enabled again
+ bool bOwnEntry = false;
+ try
+ {
+ ::svt::ShareControlFile aControlFile( GetSharedFileURL() );
+ bOwnEntry = aControlFile.HasOwnEntry();
+ }
+ catch ( uno::Exception& )
+ {
+ }
+
+ if ( bShared && bOwnEntry )
+ {
+ uno::Reference< frame::XStorable > xStorable( xModel, uno::UNO_QUERY_THROW );
+ if ( xStorable->isReadonly() )
+ {
+ xCloseable->close( sal_True );
+
+ String aUserName( ScGlobal::GetRscString( STR_UNKNOWN_USER ) );
+ try
+ {
+ ::svt::DocumentLockFile aLockFile( GetSharedFileURL() );
+ uno::Sequence< ::rtl::OUString > aData = aLockFile.GetLockData();
+ if ( aData.getLength() > LOCKFILE_SYSUSERNAME_ID )
+ {
+ if ( aData[LOCKFILE_OOOUSERNAME_ID].getLength() > 0 )
+ {
+ aUserName = aData[LOCKFILE_OOOUSERNAME_ID];
+ }
+ else if ( aData[LOCKFILE_SYSUSERNAME_ID].getLength() > 0 )
+ {
+ aUserName = aData[LOCKFILE_SYSUSERNAME_ID];
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ String aMessage( ScGlobal::GetRscString( STR_FILE_LOCKED_TRY_LATER ) );
+ aMessage.SearchAndReplaceAscii( "%1", aUserName );
+
+ WarningBox aBox( GetActiveDialogParent(), WinBits( WB_OK ), aMessage );
+ aBox.Execute();
+ }
+ else
+ {
+ WarningBox aBox( GetActiveDialogParent(), WinBits( WB_YES_NO | WB_DEF_YES ),
+ ScGlobal::GetRscString( STR_DOC_DISABLESHARED ) );
+ if ( aBox.Execute() == RET_YES )
+ {
+ xCloseable->close( sal_True );
+
+ if ( !SwitchToShared( sal_False, sal_True ) )
+ {
+ // TODO/LATER: what should be done in case the switch has failed?
+ // for example in case the user has cancelled the saveAs operation
+ }
+
+ EnableSharedSettings( false );
+
+ if ( pBindings )
+ {
+ pBindings->ExecuteSynchron( SID_SAVEDOC );
+ }
+
+ ScTabView* pTabView = dynamic_cast< ScTabView* >( pViewData->GetView() );
+ if ( pTabView )
+ {
+ pTabView->UpdateLayerLocks();
+ }
+ }
+ else
+ {
+ xCloseable->close( sal_True );
+ }
+ }
+ }
+ else
+ {
+ xCloseable->close( sal_True );
+ WarningBox aBox( GetActiveDialogParent(), WinBits( WB_OK ),
+ ScGlobal::GetRscString( STR_DOC_NOLONGERSHARED ) );
+ aBox.Execute();
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERROR( "SID_SHARE_DOC: caught exception\n" );
+ SC_MOD()->SetInSharedDocSaving( false );
+
+ try
+ {
+ uno::Reference< util::XCloseable > xClose( xModel, uno::UNO_QUERY_THROW );
+ xClose->close( sal_True );
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+ }
+ }
+ }
+ rReq.Done();
+ }
+ break;
+
+ default:
+ {
+ // kleiner (?) Hack -> forward der Slots an TabViewShell
+ ScTabViewShell* pSh = GetBestViewShell();
+ if ( pSh )
+ pSh->Execute( rReq );
+ else
+ SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
+ }
+ }
+}
+
+
+//------------------------------------------------------------------
+
+void UpdateAcceptChangesDialog()
+{
+ // update "accept changes" dialog
+ //! notify all views
+ SfxViewFrame* pViewFrm = SfxViewFrame::Current();
+ if ( pViewFrm && pViewFrm->HasChildWindow( FID_CHG_ACCEPT ) )
+ {
+ SfxChildWindow* pChild = pViewFrm->GetChildWindow( FID_CHG_ACCEPT );
+ if ( pChild )
+ ((ScAcceptChgDlgWrapper*)pChild)->ReInitDlg();
+ }
+}
+
+//------------------------------------------------------------------
+
+BOOL ScDocShell::ExecuteChangeProtectionDialog( Window* _pParent, BOOL bJustQueryIfProtected )
+{
+ BOOL bDone = FALSE;
+ ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
+ if ( pChangeTrack )
+ {
+ BOOL bProtected = pChangeTrack->IsProtected();
+ if ( bJustQueryIfProtected && !bProtected )
+ return TRUE;
+
+ String aTitle( ScResId( bProtected ? SCSTR_CHG_UNPROTECT : SCSTR_CHG_PROTECT ) );
+ String aText( ScResId( SCSTR_PASSWORD ) );
+ String aPassword;
+
+ SfxPasswordDialog* pDlg = new SfxPasswordDialog(
+ _pParent ? _pParent : GetActiveDialogParent(), &aText );
+ pDlg->SetText( aTitle );
+ pDlg->SetMinLen( 1 );
+ pDlg->SetHelpId( SID_CHG_PROTECT );
+ pDlg->SetEditHelpId( HID_CHG_PROTECT );
+ if ( !bProtected )
+ pDlg->ShowExtras( SHOWEXTRAS_CONFIRM );
+ if ( pDlg->Execute() == RET_OK )
+ aPassword = pDlg->GetPassword();
+ delete pDlg;
+
+ if ( aPassword.Len() )
+ {
+ if ( bProtected )
+ {
+ if ( SvPasswordHelper::CompareHashPassword(pChangeTrack->GetProtection(), aPassword) )
+ {
+ if ( bJustQueryIfProtected )
+ bDone = TRUE;
+ else
+ pChangeTrack->SetProtection(
+ com::sun::star::uno::Sequence< sal_Int8 > (0) );
+ }
+ else
+ {
+ InfoBox aBox( GetActiveDialogParent(),
+ String( ScResId( SCSTR_WRONGPASSWORD ) ) );
+ aBox.Execute();
+ }
+ }
+ else
+ {
+ com::sun::star::uno::Sequence< sal_Int8 > aPass;
+ SvPasswordHelper::GetHashPassword( aPass, aPassword );
+ pChangeTrack->SetProtection( aPass );
+ }
+ if ( bProtected != pChangeTrack->IsProtected() )
+ {
+ UpdateAcceptChangesDialog();
+ bDone = TRUE;
+ }
+ }
+ }
+ else if ( bJustQueryIfProtected )
+ bDone = TRUE;
+ return bDone;
+}
+
+
+//------------------------------------------------------------------
+
+void ScDocShell::DoRecalc( BOOL bApi )
+{
+ BOOL bDone = FALSE;
+ ScTabViewShell* pSh = GetBestViewShell();
+ if ( pSh )
+ {
+ ScInputHandler* pHdl = SC_MOD()->GetInputHdl(pSh);
+ if ( pHdl && pHdl->IsInputMode() && pHdl->IsFormulaMode() && !bApi )
+ {
+ pHdl->FormulaPreview(); // Teilergebnis als QuickHelp
+ bDone = TRUE;
+ }
+ else
+ {
+ pSh->UpdateInputLine(); // InputEnterHandler
+ pSh->UpdateInputHandler();
+ }
+ }
+ if (!bDone) // sonst Dokument neu berechnen
+ {
+ WaitObject aWaitObj( GetActiveDialogParent() );
+ aDocument.CalcFormulaTree();
+ if ( pSh )
+ pSh->UpdateCharts(TRUE);
+
+ aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
+
+ // #47939# Wenn es Charts gibt, dann alles painten, damit nicht
+ // PostDataChanged und die Charts nacheinander kommen und Teile
+ // doppelt gepainted werden.
+
+ ScChartListenerCollection* pCharts = aDocument.GetChartListenerCollection();
+ if ( pCharts && pCharts->GetCount() )
+ PostPaintGridAll();
+ else
+ PostDataChanged();
+ }
+}
+
+void ScDocShell::DoHardRecalc( BOOL /* bApi */ )
+{
+ WaitObject aWaitObj( GetActiveDialogParent() );
+ ScTabViewShell* pSh = GetBestViewShell();
+ if ( pSh )
+ {
+ pSh->UpdateInputLine(); // InputEnterHandler
+ pSh->UpdateInputHandler();
+ }
+ aDocument.CalcAll();
+ GetDocFunc().DetectiveRefresh(); // erzeugt eigenes Undo
+ if ( pSh )
+ pSh->UpdateCharts(TRUE);
+
+ // set notification flags for "calculate" event (used in SFX_HINT_DATACHANGED broadcast)
+ // (might check for the presence of any formulas on each sheet)
+ SCTAB nTabCount = aDocument.GetTableCount();
+ SCTAB nTab;
+ if (aDocument.HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE, true )) // search also for VBA hendler
+ for (nTab=0; nTab<nTabCount; nTab++)
+ aDocument.SetCalcNotification(nTab);
+
+ // CalcAll doesn't broadcast value changes, so SC_HINT_CALCALL is broadcasted globally
+ // in addition to SFX_HINT_DATACHANGED.
+ aDocument.BroadcastUno( SfxSimpleHint( SC_HINT_CALCALL ) );
+ aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
+
+ // use hard recalc also to disable stream-copying of all sheets
+ // (somewhat consistent with charts)
+ for (nTab=0; nTab<nTabCount; nTab++)
+ if (aDocument.IsStreamValid(nTab))
+ aDocument.SetStreamValid(nTab, FALSE);
+
+ PostPaintGridAll();
+}
+
+//------------------------------------------------------------------
+
+void ScDocShell::DoAutoStyle( const ScRange& rRange, const String& rStyle )
+{
+ ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
+ ScStyleSheet* pStyleSheet =
+ pStylePool->FindCaseIns( rStyle, SFX_STYLE_FAMILY_PARA );
+ if (!pStyleSheet)
+ pStyleSheet = (ScStyleSheet*)
+ pStylePool->Find( ScGlobal::GetRscString(STR_STYLENAME_STANDARD), SFX_STYLE_FAMILY_PARA );
+ if (pStyleSheet)
+ {
+ DBG_ASSERT(rRange.aStart.Tab() == rRange.aEnd.Tab(),
+ "DoAutoStyle mit mehreren Tabellen");
+ SCTAB nTab = rRange.aStart.Tab();
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCROW nStartRow = rRange.aStart.Row();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ SCROW nEndRow = rRange.aEnd.Row();
+ aDocument.ApplyStyleAreaTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, *pStyleSheet );
+ aDocument.ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab );
+ PostPaint( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab, PAINT_GRID );
+ }
+}
+
+//------------------------------------------------------------------
+
+void ScDocShell::NotifyStyle( const SfxStyleSheetHint& rHint )
+{
+ USHORT nId = rHint.GetHint();
+ const SfxStyleSheetBase* pStyle = rHint.GetStyleSheet();
+ if (!pStyle)
+ return;
+
+ if ( pStyle->GetFamily() == SFX_STYLE_FAMILY_PAGE )
+ {
+ if ( nId == SFX_STYLESHEET_MODIFIED )
+ {
+ ScDocShellModificator aModificator( *this );
+
+ String aNewName = pStyle->GetName();
+ String aOldName = aNewName;
+ BOOL bExtended = rHint.ISA(SfxStyleSheetHintExtended); // Name geaendert?
+ if (bExtended)
+ aOldName = ((SfxStyleSheetHintExtended&)rHint).GetOldName();
+
+ if ( aNewName != aOldName )
+ aDocument.RenamePageStyleInUse( aOldName, aNewName );
+
+ SCTAB nTabCount = aDocument.GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (aDocument.GetPageStyle(nTab) == aNewName) // schon auf neu angepasst
+ {
+ aDocument.PageStyleModified( nTab, aNewName );
+ ScPrintFunc aPrintFunc( this, GetPrinter(), nTab );
+ aPrintFunc.UpdatePages();
+ }
+
+ aModificator.SetDocumentModified();
+
+ if (bExtended)
+ {
+ SfxBindings* pBindings = GetViewBindings();
+ if (pBindings)
+ {
+ pBindings->Invalidate( SID_STATUS_PAGESTYLE );
+ pBindings->Invalidate( SID_STYLE_FAMILY4 );
+ pBindings->Invalidate( FID_RESET_PRINTZOOM );
+ pBindings->Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
+ pBindings->Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
+ }
+ }
+ }
+ }
+ else if ( pStyle->GetFamily() == SFX_STYLE_FAMILY_PARA )
+ {
+ if ( nId == SFX_STYLESHEET_MODIFIED)
+ {
+ String aNewName = pStyle->GetName();
+ String aOldName = aNewName;
+ BOOL bExtended = rHint.ISA(SfxStyleSheetHintExtended);
+ if (bExtended)
+ aOldName = ((SfxStyleSheetHintExtended&)rHint).GetOldName();
+ if ( aNewName != aOldName )
+ {
+ ScConditionalFormatList* pList = aDocument.GetCondFormList();
+ if (pList)
+ pList->RenameCellStyle( aOldName,aNewName );
+ }
+ }
+ }
+
+ // alles andere geht ueber Slots...
+}
+
+// wie in printfun.cxx
+#define ZOOM_MIN 10
+
+void ScDocShell::SetPrintZoom( SCTAB nTab, USHORT nScale, USHORT nPages )
+{
+ BOOL bUndo(aDocument.IsUndoEnabled());
+ String aStyleName = aDocument.GetPageStyle( nTab );
+ ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PAGE );
+ DBG_ASSERT( pStyleSheet, "PageStyle not found" );
+ if ( pStyleSheet )
+ {
+ ScDocShellModificator aModificator( *this );
+
+ SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ if (bUndo)
+ {
+ USHORT nOldScale = ((const SfxUInt16Item&)rSet.Get(ATTR_PAGE_SCALE)).GetValue();
+ USHORT nOldPages = ((const SfxUInt16Item&)rSet.Get(ATTR_PAGE_SCALETOPAGES)).GetValue();
+ GetUndoManager()->AddUndoAction( new ScUndoPrintZoom(
+ this, nTab, nOldScale, nOldPages, nScale, nPages ) );
+ }
+
+ rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, nScale ) );
+ rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALETOPAGES, nPages ) );
+
+ ScPrintFunc aPrintFunc( this, GetPrinter(), nTab );
+ aPrintFunc.UpdatePages();
+ aModificator.SetDocumentModified();
+
+ SfxBindings* pBindings = GetViewBindings();
+ if (pBindings)
+ pBindings->Invalidate( FID_RESET_PRINTZOOM );
+ }
+}
+
+BOOL ScDocShell::AdjustPrintZoom( const ScRange& rRange )
+{
+ BOOL bChange = FALSE;
+ SCTAB nTab = rRange.aStart.Tab();
+
+ String aStyleName = aDocument.GetPageStyle( nTab );
+ ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PAGE );
+ DBG_ASSERT( pStyleSheet, "PageStyle not found" );
+ if ( pStyleSheet )
+ {
+ SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ BOOL bHeaders = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_HEADERS)).GetValue();
+ USHORT nOldScale = ((const SfxUInt16Item&)rSet.Get(ATTR_PAGE_SCALE)).GetValue();
+ USHORT nOldPages = ((const SfxUInt16Item&)rSet.Get(ATTR_PAGE_SCALETOPAGES)).GetValue();
+ const ScRange* pRepeatCol = aDocument.GetRepeatColRange( nTab );
+ const ScRange* pRepeatRow = aDocument.GetRepeatRowRange( nTab );
+
+ // benoetigte Skalierung fuer Selektion ausrechnen
+
+ USHORT nNewScale = nOldScale;
+
+ long nBlkTwipsX = 0;
+ if (bHeaders)
+ nBlkTwipsX += (long) PRINT_HEADER_WIDTH;
+ SCCOL nStartCol = rRange.aStart.Col();
+ SCCOL nEndCol = rRange.aEnd.Col();
+ if ( pRepeatCol && nStartCol >= pRepeatCol->aStart.Col() )
+ {
+ for (SCCOL i=pRepeatCol->aStart.Col(); i<=pRepeatCol->aEnd.Col(); i++ )
+ nBlkTwipsX += aDocument.GetColWidth( i, nTab );
+ if ( nStartCol <= pRepeatCol->aEnd.Col() )
+ nStartCol = pRepeatCol->aEnd.Col() + 1;
+ }
+ // legacy compilers' own scope for i
+ {
+ for ( SCCOL i=nStartCol; i<=nEndCol; i++ )
+ nBlkTwipsX += aDocument.GetColWidth( i, nTab );
+ }
+
+ long nBlkTwipsY = 0;
+ if (bHeaders)
+ nBlkTwipsY += (long) PRINT_HEADER_HEIGHT;
+ SCROW nStartRow = rRange.aStart.Row();
+ SCROW nEndRow = rRange.aEnd.Row();
+ if ( pRepeatRow && nStartRow >= pRepeatRow->aStart.Row() )
+ {
+ nBlkTwipsY += aDocument.GetRowHeight( pRepeatRow->aStart.Row(),
+ pRepeatRow->aEnd.Row(), nTab );
+ if ( nStartRow <= pRepeatRow->aEnd.Row() )
+ nStartRow = pRepeatRow->aEnd.Row() + 1;
+ }
+ nBlkTwipsY += aDocument.GetRowHeight( nStartRow, nEndRow, nTab );
+
+ Size aPhysPage;
+ long nHdr, nFtr;
+ ScPrintFunc aOldPrFunc( this, GetPrinter(), nTab );
+ aOldPrFunc.GetScaleData( aPhysPage, nHdr, nFtr );
+ nBlkTwipsY += nHdr + nFtr;
+
+ if ( nBlkTwipsX == 0 ) // #100639# hidden columns/rows may lead to 0
+ nBlkTwipsX = 1;
+ if ( nBlkTwipsY == 0 )
+ nBlkTwipsY = 1;
+
+ long nNeeded = Min( aPhysPage.Width() * 100 / nBlkTwipsX,
+ aPhysPage.Height() * 100 / nBlkTwipsY );
+ if ( nNeeded < ZOOM_MIN )
+ nNeeded = ZOOM_MIN; // Begrenzung
+ if ( nNeeded < (long) nNewScale )
+ nNewScale = (USHORT) nNeeded;
+
+ bChange = ( nNewScale != nOldScale || nOldPages != 0 );
+ if ( bChange )
+ SetPrintZoom( nTab, nNewScale, 0 );
+ }
+ return bChange;
+}
+
+void ScDocShell::PageStyleModified( const String& rStyleName, BOOL bApi )
+{
+ ScDocShellModificator aModificator( *this );
+
+ BOOL bWarn = FALSE;
+
+ SCTAB nTabCount = aDocument.GetTableCount();
+ SCTAB nUseTab = MAXTAB+1;
+ for (SCTAB nTab=0; nTab<nTabCount && nUseTab>MAXTAB; nTab++)
+ if ( aDocument.GetPageStyle(nTab) == rStyleName &&
+ ( !bApi || aDocument.GetPageSize(nTab).Width() ) )
+ nUseTab = nTab;
+ // bei bApi nur, wenn Umbrueche schon angezeigt
+
+ if (ValidTab(nUseTab)) // nicht verwendet -> nichts zu tun
+ {
+ ScPrintFunc aPrintFunc( this, GetPrinter(), nUseTab ); //! ohne CountPages auskommen
+ if (!aPrintFunc.UpdatePages()) // setzt Umbrueche auf allen Tabs
+ bWarn = TRUE;
+
+ if (bWarn && !bApi)
+ {
+ ScWaitCursorOff aWaitOff( GetActiveDialogParent() );
+ InfoBox aInfoBox(GetActiveDialogParent(),
+ ScGlobal::GetRscString(STR_PRINT_INVALID_AREA));
+ aInfoBox.Execute();
+ }
+ }
+
+ aModificator.SetDocumentModified();
+
+ SfxBindings* pBindings = GetViewBindings();
+ if (pBindings)
+ {
+ pBindings->Invalidate( FID_RESET_PRINTZOOM );
+ pBindings->Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
+ pBindings->Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
+ }
+}
+
+void ScDocShell::ExecutePageStyle( SfxViewShell& rCaller,
+ SfxRequest& rReq,
+ SCTAB nCurTab )
+{
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+
+ switch ( rReq.GetSlot() )
+ {
+ case SID_STATUS_PAGESTYLE: // Click auf StatusBar-Control
+ case SID_FORMATPAGE:
+ {
+ if ( pReqArgs != NULL )
+ {
+ }
+ else if ( pReqArgs == NULL )
+ {
+ BOOL bUndo(aDocument.IsUndoEnabled());
+ String aOldName = aDocument.GetPageStyle( nCurTab );
+ ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet
+ = pStylePool->Find( aOldName, SFX_STYLE_FAMILY_PAGE );
+
+ DBG_ASSERT( pStyleSheet, "PageStyle not found! :-/" );
+
+ if ( pStyleSheet )
+ {
+ ScStyleSaveData aOldData;
+ if (bUndo)
+ aOldData.InitFromStyle( pStyleSheet );
+
+ SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");
+
+ SfxAbstractTabDialog* pDlg = pFact->CreateScStyleDlg( GetActiveDialogParent(), *pStyleSheet, RID_SCDLG_STYLES_PAGE, RID_SCDLG_STYLES_PAGE );
+ DBG_ASSERT(pDlg, "Dialog create fail!");
+
+ if ( pDlg->Execute() == RET_OK )
+ {
+ const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
+
+ WaitObject aWait( GetActiveDialogParent() );
+
+ String aNewName = pStyleSheet->GetName();
+ if ( aNewName != aOldName &&
+ aDocument.RenamePageStyleInUse( aOldName, aNewName ) )
+ {
+ SfxBindings* pBindings = GetViewBindings();
+ if (pBindings)
+ {
+ pBindings->Invalidate( SID_STATUS_PAGESTYLE );
+ pBindings->Invalidate( FID_RESET_PRINTZOOM );
+ }
+ }
+
+ if ( pOutSet )
+ aDocument.ModifyStyleSheet( *pStyleSheet, *pOutSet );
+
+ // merken fuer GetState():
+ GetPageOnFromPageStyleSet( &rStyleSet, nCurTab, bHeaderOn, bFooterOn );
+ rCaller.GetViewFrame()->GetBindings().Invalidate( SID_HFEDIT );
+
+ ScStyleSaveData aNewData;
+ aNewData.InitFromStyle( pStyleSheet );
+ if (bUndo)
+ {
+ GetUndoManager()->AddUndoAction(
+ new ScUndoModifyStyle( this, SFX_STYLE_FAMILY_PAGE,
+ aOldData, aNewData ) );
+ }
+
+ PageStyleModified( aNewName, FALSE );
+ rReq.Done();
+ }
+ delete pDlg;
+
+ rStyleSet.ClearItem( ATTR_PAGE_PAPERTRAY );
+ }
+ }
+ }
+ break;
+
+ case SID_HFEDIT:
+ {
+ if ( pReqArgs != NULL )
+ {
+ }
+ else if ( pReqArgs == NULL )
+ {
+ String aStr( aDocument.GetPageStyle( nCurTab ) );
+
+ ScStyleSheetPool* pStylePool
+ = aDocument.GetStyleSheetPool();
+
+ SfxStyleSheetBase* pStyleSheet
+ = pStylePool->Find( aStr, SFX_STYLE_FAMILY_PAGE );
+
+ DBG_ASSERT( pStyleSheet, "PageStyle not found! :-/" );
+
+ if ( pStyleSheet )
+ {
+ SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
+
+ SvxPageUsage eUsage =
+ SvxPageUsage( ((const SvxPageItem&)
+ rStyleSet.Get( ATTR_PAGE )).
+ GetPageUsage() );
+ BOOL bShareHeader = IS_SHARE_HEADER(rStyleSet);
+ BOOL bShareFooter = IS_SHARE_FOOTER(rStyleSet);
+ USHORT nResId = 0;
+
+ switch ( eUsage )
+ {
+ case SVX_PAGE_LEFT:
+ case SVX_PAGE_RIGHT:
+ {
+ if ( bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT;
+ else if ( SVX_PAGE_RIGHT == eUsage )
+ {
+ if ( !bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_RIGHTFOOTER;
+ else if ( bHeaderOn && !bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_RIGHTHEADER;
+ }
+ else
+ {
+ // #69193a# respect "shared" setting
+ if ( !bHeaderOn && bFooterOn )
+ nResId = bShareFooter ?
+ RID_SCDLG_HFEDIT_RIGHTFOOTER :
+ RID_SCDLG_HFEDIT_LEFTFOOTER;
+ else if ( bHeaderOn && !bFooterOn )
+ nResId = bShareHeader ?
+ RID_SCDLG_HFEDIT_RIGHTHEADER :
+ RID_SCDLG_HFEDIT_LEFTHEADER;
+ }
+ }
+ break;
+
+ case SVX_PAGE_MIRROR:
+ case SVX_PAGE_ALL:
+ default:
+ {
+ if ( !bShareHeader && !bShareFooter )
+ {
+ if ( bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_ALL;
+ else if ( !bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_FOOTER;
+ else if ( bHeaderOn && !bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_HEADER;
+ }
+ else if ( bShareHeader && bShareFooter )
+ {
+ if ( bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT;
+ else
+ {
+ if ( !bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_RIGHTFOOTER;
+ else if ( bHeaderOn && !bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_RIGHTHEADER;
+ }
+ }
+ else if ( !bShareHeader && bShareFooter )
+ {
+ if ( bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_SFTR;
+ else if ( !bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_RIGHTFOOTER;
+ else if ( bHeaderOn && !bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_HEADER;
+ }
+ else if ( bShareHeader && !bShareFooter )
+ {
+ if ( bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_SHDR;
+ else if ( !bHeaderOn && bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_FOOTER;
+ else if ( bHeaderOn && !bFooterOn )
+ nResId = RID_SCDLG_HFEDIT_RIGHTHEADER;
+ }
+ }
+ }
+
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ DBG_ASSERT(pFact, "ScAbstractFactory create fail!");
+
+ SfxAbstractTabDialog* pDlg = pFact->CreateScHFEditDlg( SfxViewFrame::Current(),
+ GetActiveDialogParent(),
+ rStyleSet,
+ aStr,
+ RID_SCDLG_HFEDIT, nResId);
+ DBG_ASSERT(pDlg, "Dialog create fail!");
+ if ( pDlg->Execute() == RET_OK )
+ {
+ const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
+
+ if ( pOutSet )
+ aDocument.ModifyStyleSheet( *pStyleSheet, *pOutSet );
+
+ SetDocumentModified();
+ rReq.Done();
+ }
+ delete pDlg;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void ScDocShell::GetStatePageStyle( SfxViewShell& /* rCaller */,
+ SfxItemSet& rSet,
+ SCTAB nCurTab )
+{
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch (nWhich)
+ {
+ case SID_STATUS_PAGESTYLE:
+ rSet.Put( SfxStringItem( nWhich, aDocument.GetPageStyle( nCurTab ) ) );
+ break;
+
+ case SID_HFEDIT:
+ {
+ String aStr = aDocument.GetPageStyle( nCurTab );
+ ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStr, SFX_STYLE_FAMILY_PAGE );
+
+ DBG_ASSERT( pStyleSheet, "PageStyle not found! :-/" );
+
+ if ( pStyleSheet )
+ {
+ SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
+
+ GetPageOnFromPageStyleSet( &rStyleSet, nCurTab, bHeaderOn, bFooterOn );
+
+ if ( !bHeaderOn && !bFooterOn )
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void lcl_GetPrintData( ScDocShell* pDocShell /*in*/,
+ ScDocument* pDocument /*in*/, SfxPrinter* pPrinter /*in*/,
+ PrintDialog* pPrintDialog /*in*/, bool bForceSelected /*in*/,
+ ScMarkData* pMarkData /*inout*/, bool& rbHasOptions /*out*/,
+ ScPrintOptions& rOptions /*out*/, bool& rbAllTabs /*out*/,
+ long& rnTotalPages /*out*/, long aPageArr[] /*out*/,
+ MultiSelection& rPageRanges /*out*/, ScRange** ppMarkedRange /*out*/ )
+{
+ // get settings from print options sub-dialog
+ const SfxItemSet& rOptionSet = pPrinter->GetOptions();
+ const SfxPoolItem* pItem;
+ rbHasOptions = ( rOptionSet.GetItemState( SID_SCPRINTOPTIONS, FALSE, &pItem ) == SFX_ITEM_SET );
+ if ( rbHasOptions )
+ {
+ rOptions = ((const ScTpPrintItem*)pItem)->GetPrintOptions();
+ }
+ else
+ {
+ // use configuration
+ rOptions = SC_MOD()->GetPrintOptions();
+ }
+
+ // update all pending row heights with a single progress bar,
+ // instead of a separate progress for each sheet from ScPrintFunc
+ pDocShell->UpdatePendingRowHeights( MAXTAB, true );
+
+ // get number of total pages
+ rnTotalPages = 0;
+ SCTAB nTabCount = pDocument->GetTableCount();
+ for ( SCTAB nTab = 0; nTab < nTabCount; ++nTab )
+ {
+ ScPrintFunc aPrintFunc( pDocShell, pPrinter, nTab, 0, 0, NULL, &rOptions );
+ long nThisTab = aPrintFunc.GetTotalPages();
+ aPageArr[nTab] = nThisTab;
+ rnTotalPages += nThisTab;
+ }
+
+ rPageRanges.SetTotalRange( Range( 0, RANGE_MAX ) );
+ rPageRanges.Select( Range( 1, rnTotalPages ) );
+
+ rbAllTabs = ( pPrintDialog ? ( pPrintDialog->GetCheckedSheetRange() == PRINTSHEETS_ALL ) : SC_MOD()->GetPrintOptions().GetAllSheets() );
+ if ( bForceSelected )
+ {
+ rbAllTabs = false;
+ }
+
+ if ( ( pPrintDialog && pPrintDialog->GetCheckedSheetRange() == PRINTSHEETS_SELECTED_CELLS ) || bForceSelected )
+ {
+ if ( pMarkData && ( pMarkData->IsMarked() || pMarkData->IsMultiMarked() ) )
+ {
+ pMarkData->MarkToMulti();
+ *ppMarkedRange = new ScRange;
+ pMarkData->GetMultiMarkArea( **ppMarkedRange );
+ pMarkData->MarkToSimple();
+ }
+ }
+
+ PrintDialogRange eDlgOption = pPrintDialog ? pPrintDialog->GetCheckedRange() : PRINTDIALOG_ALL;
+ if ( eDlgOption == PRINTDIALOG_RANGE )
+ {
+ rPageRanges = MultiSelection( pPrintDialog->GetRangeText() );
+ }
+
+ // get number of total pages if selection
+ if ( !rbAllTabs )
+ {
+ rnTotalPages = 0;
+ for ( SCTAB nTab = 0; nTab < nTabCount; ++nTab )
+ {
+ if ( *ppMarkedRange ) // selected range is used instead of print ranges -> page count is different
+ {
+ ScPrintFunc aPrintFunc( pDocShell, pPrinter, nTab, 0, 0, *ppMarkedRange, &rOptions );
+ aPageArr[nTab] = aPrintFunc.GetTotalPages();
+ }
+ if ( !pMarkData || pMarkData->GetTableSelect( nTab ) )
+ {
+ rnTotalPages += aPageArr[nTab];
+ }
+ }
+ if ( eDlgOption == PRINTDIALOG_ALL || bForceSelected )
+ {
+ rPageRanges.Select( Range( 1, rnTotalPages ) );
+ }
+ }
+}
+
+bool ScDocShell::CheckPrint( PrintDialog* pPrintDialog, ScMarkData* pMarkData, bool bForceSelected, bool bIsAPI )
+{
+ SfxPrinter* pPrinter = GetPrinter();
+ if ( !pPrinter )
+ {
+ return false;
+ }
+
+ bool bHasOptions = false;
+ ScPrintOptions aOptions;
+ bool bAllTabs = true;
+ long nTotalPages = 0;
+ long aPageArr[MAXTABCOUNT]; // pages per sheet
+ MultiSelection aPageRanges; // pages to print
+ ScRange* pMarkedRange = NULL;
+
+ lcl_GetPrintData( this, &aDocument, pPrinter, pPrintDialog, bForceSelected,
+ pMarkData, bHasOptions, aOptions, bAllTabs, nTotalPages,
+ aPageArr, aPageRanges, &pMarkedRange );
+
+ delete pMarkedRange;
+
+ if ( nTotalPages == 0 )
+ {
+ if ( !bIsAPI )
+ {
+ WarningBox aWarningBox( GetActiveDialogParent(), WinBits( WB_OK ),
+ String( ScResId( STR_PRINT_NOTHING ) ) );
+ aWarningBox.Execute();
+ }
+ return false;
+ }
+
+ return true;
+}
+
+void ScDocShell::PreparePrint( PrintDialog* pPrintDialog, ScMarkData* pMarkData )
+{
+ SfxPrinter* pPrinter = GetPrinter();
+ if ( !pPrinter )
+ {
+ return;
+ }
+
+ delete pOldJobSetup; // gesetzt nur bei Fehler in StartJob()
+ pOldJobSetup = new ScJobSetup( pPrinter ); // Einstellungen merken
+
+ // Einstellungen fuer die erste gedruckte Seite muessen hier (vor StartJob) gesetzt werden
+ //! Selection etc. mit Print() zusammenfassen !!!
+ //! Seiten nur einmal zaehlen
+
+ bool bHasOptions = false;
+ ScPrintOptions aOptions;
+ bool bAllTabs = true;
+ long nTotalPages = 0;
+ long aPageArr[MAXTABCOUNT]; // pages per sheet
+ MultiSelection aPageRanges; // pages to print
+ ScRange* pMarkedRange = NULL;
+
+ lcl_GetPrintData( this, &aDocument, pPrinter, pPrintDialog, false,
+ pMarkData, bHasOptions, aOptions, bAllTabs, nTotalPages,
+ aPageArr, aPageRanges, &pMarkedRange );
+
+ BOOL bFound = FALSE; // erste Seite gefunden
+ long nTabStart = 0;
+ SCTAB nTabCount = aDocument.GetTableCount();
+ for ( SCTAB nTab=0; nTab<nTabCount && !bFound; nTab++ )
+ {
+ if ( bAllTabs || !pMarkData || pMarkData->GetTableSelect( nTab ) )
+ {
+ long nNext = nTabStart + aPageArr[nTab];
+ BOOL bSelected = FALSE;
+ for (long nP=nTabStart+1; nP<=nNext; nP++) // 1-basiert
+ if (aPageRanges.IsSelected( nP )) // eine Seite von dieser Tabelle selektiert?
+ bSelected = TRUE;
+
+ if (bSelected)
+ {
+ ScPrintFunc aPrintFunc( this, pPrinter, nTab );
+
+ aPrintFunc.ApplyPrintSettings(); // dann Settings fuer diese Tabelle
+ bFound = TRUE;
+ }
+ nTabStart = nNext;
+ }
+ }
+
+ delete pMarkedRange;
+}
+
+BOOL lcl_HasTransparent( ScDocument* pDoc, SCTAB nTab, const ScRange* pRange )
+{
+ BOOL bFound = FALSE;
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ if (pDrawLayer)
+ {
+ SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+ DBG_ASSERT(pPage,"Page ?");
+ if (pPage)
+ {
+ Rectangle aMMRect;
+ if ( pRange )
+ aMMRect = pDoc->GetMMRect( pRange->aStart.Col(), pRange->aStart.Row(),
+ pRange->aEnd.Col(), pRange->aEnd.Row(), nTab );
+
+ SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
+ SdrObject* pObject = aIter.Next();
+ while (pObject && !bFound)
+ {
+ if (pObject->IsTransparent())
+ {
+ if ( pRange )
+ {
+ Rectangle aObjRect = pObject->GetLogicRect();
+ if ( aObjRect.IsOver( aMMRect ) )
+ bFound = TRUE;
+ }
+ else
+ bFound = TRUE;
+ }
+
+ pObject = aIter.Next();
+ }
+ }
+ }
+
+ return bFound;
+}
+
+void ScDocShell::Print( SfxProgress& rProgress, PrintDialog* pPrintDialog,
+ ScMarkData* pMarkData, Window* pDialogParent, BOOL bForceSelected, BOOL bIsAPI )
+{
+ SfxPrinter* pPrinter = GetPrinter();
+ if ( !pPrinter )
+ {
+ return;
+ }
+
+ bool bHasOptions = false;
+ ScPrintOptions aOptions;
+ bool bAllTabs = true;
+ long nTotalPages = 0;
+ long aPageArr[MAXTABCOUNT]; // pages per sheet
+ MultiSelection aPageRanges; // pages to print
+ ScRange* pMarkedRange = NULL;
+
+ lcl_GetPrintData( this, &aDocument, pPrinter, pPrintDialog, bForceSelected,
+ pMarkData, bHasOptions, aOptions, bAllTabs, nTotalPages,
+ aPageArr, aPageRanges, &pMarkedRange );
+
+ USHORT nCollateCopies = 1;
+ if ( pPrintDialog && pPrintDialog->IsCollateEnabled() && pPrintDialog->IsCollateChecked() )
+ nCollateCopies = pPrintDialog->GetCopyCount();
+
+ // test if printed range contains transparent objects
+
+ BOOL bHasTransp = FALSE;
+ BOOL bAnyPrintRanges = aDocument.HasPrintRange();
+ ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
+ SCTAB nTabCount = aDocument.GetTableCount();
+ for ( SCTAB nTab=0; nTab<nTabCount && !bHasTransp; nTab++ )
+ {
+ if ( bAllTabs || !pMarkData || pMarkData->GetTableSelect( nTab ) )
+ {
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find(
+ aDocument.GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
+ if ( pStyleSheet )
+ {
+ const SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ if ( ((const ScViewObjectModeItem&)rSet.Get(ATTR_PAGE_CHARTS)).GetValue() == VOBJ_MODE_SHOW ||
+ ((const ScViewObjectModeItem&)rSet.Get(ATTR_PAGE_OBJECTS)).GetValue() == VOBJ_MODE_SHOW ||
+ ((const ScViewObjectModeItem&)rSet.Get(ATTR_PAGE_DRAWINGS)).GetValue() == VOBJ_MODE_SHOW )
+ {
+ if ( pMarkedRange )
+ bHasTransp = bHasTransp || lcl_HasTransparent( &aDocument, nTab, pMarkedRange );
+ else if ( aDocument.GetPrintRangeCount(nTab) )
+ {
+ USHORT nRangeCount = aDocument.GetPrintRangeCount(nTab);
+ for (USHORT i=0; i<nRangeCount; i++)
+ bHasTransp = bHasTransp ||
+ lcl_HasTransparent( &aDocument, nTab, aDocument.GetPrintRange( nTab, i ) );
+ }
+ else if (!bAnyPrintRanges || aDocument.IsPrintEntireSheet(nTab))
+ bHasTransp = bHasTransp || lcl_HasTransparent( &aDocument, nTab, NULL );
+ }
+ }
+ }
+ }
+
+ BOOL bContinue = pPrinter->InitJob( pDialogParent, !bIsAPI && bHasTransp );
+
+ if ( bContinue )
+ {
+ for ( USHORT n=0; n<nCollateCopies; n++ )
+ {
+ long nTabStart = 0;
+ long nDisplayStart = 0;
+ long nAttrPage = 1;
+ long nPrinted = 0;
+
+ for ( SCTAB nTab=0; nTab<nTabCount; nTab++ )
+ {
+ if ( bAllTabs || !pMarkData || pMarkData->GetTableSelect( nTab ) )
+ {
+ FmFormView* pDrawView = NULL;
+ Rectangle aFull( 0, 0, LONG_MAX, LONG_MAX );
+
+ // #114135#
+ ScDrawLayer* pModel = aDocument.GetDrawLayer(); // ist nicht NULL
+
+ if(pModel)
+ {
+ pDrawView = new FmFormView( pModel, pPrinter );
+ pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
+ pDrawView->SetPrintPreview( TRUE );
+ }
+
+ ScPrintFunc aPrintFunc( this, pPrinter, nTab, nAttrPage, nTotalPages, pMarkedRange, &aOptions );
+ aPrintFunc.SetDrawView( pDrawView );
+ nPrinted += aPrintFunc.DoPrint( aPageRanges, nTabStart, nDisplayStart, TRUE, &rProgress, NULL );
+
+ nTabStart += aPageArr[nTab];
+ if ( aDocument.NeedPageResetAfterTab(nTab) )
+ nDisplayStart = 0;
+ else
+ nDisplayStart += aPageArr[nTab];
+ nAttrPage = aPrintFunc.GetFirstPageNo(); // behalten oder aus Vorlage
+
+ delete pDrawView;
+ }
+ }
+
+#if 0
+ if ( n+1 < nCollateCopies &&
+ (pPrinter->GetDuplexMode() == DUPLEX_SHORTEDGE || pPrinter->GetDuplexMode() == DUPLEX_LONGEDGE) &&
+ ( nPrinted % 2 ) == 1 )
+ {
+ // #105584# when several collated copies are printed in duplex mode, and there is
+ // an odd number of pages, print an empty page between copies, so the first page of
+ // the second copy isn't printed on the back of the last page of the first copy.
+ // (same as in Writer ViewShell::Prt)
+
+ // FIXME: needs to be adapted to XRenderable interface
+ pPrinter->StartPage();
+ pPrinter->EndPage();
+ }
+#endif
+ }
+ }
+
+ delete pMarkedRange;
+
+ if (pOldJobSetup)
+ {
+ pPrinter->SetOrientation( pOldJobSetup->eOrientation );
+ pPrinter->SetPaperBin ( pOldJobSetup->nPaperBin );
+ pPrinter->SetPaper ( pOldJobSetup->ePaper );
+
+ if ( PAPER_USER == pOldJobSetup->ePaper )
+ {
+ pPrinter->SetMapMode( pOldJobSetup->aUserMapMode );
+ pPrinter->SetPaperSizeUser( pOldJobSetup->aUserSize );
+ }
+
+ delete pOldJobSetup;
+ pOldJobSetup = NULL;
+ }
+
+ if ( bHasOptions )
+ {
+ // remove PrintOptions from printer ItemSet,
+ // so next time the options from the configuration are used
+
+ SfxItemSet aSet( pPrinter->GetOptions() );
+ aSet.ClearItem( SID_SCPRINTOPTIONS );
+ pPrinter->SetOptions( aSet );
+ }
+
+ PostPaintGridAll(); //! nur wenn geaendert
+}
+
+void ScDocShell::GetState( SfxItemSet &rSet )
+{
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch (nWhich)
+ {
+ case FID_AUTO_CALC:
+ if ( (BOOL) aDocument.GetHardRecalcState() )
+ rSet.DisableItem( nWhich );
+ else
+ rSet.Put( SfxBoolItem( nWhich, aDocument.GetAutoCalc() ) );
+ break;
+
+ case FID_CHG_RECORD:
+ if ( IsDocShared() )
+ rSet.DisableItem( nWhich );
+ else
+ rSet.Put( SfxBoolItem( nWhich,
+ aDocument.GetChangeTrack() != NULL ) );
+ break;
+
+ case SID_CHG_PROTECT:
+ {
+ ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
+ if ( pChangeTrack && !IsDocShared() )
+ rSet.Put( SfxBoolItem( nWhich,
+ pChangeTrack->IsProtected() ) );
+ else
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
+ case SID_DOCUMENT_COMPARE:
+ {
+ if ( IsDocShared() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ // Wenn eine Formel editiert wird, muss FID_RECALC auf jeden Fall enabled sein.
+ // Recalc fuer das Doc war mal wegen #29898# disabled, wenn AutoCalc an war,
+ // ist jetzt wegen #41540# aber auch immer enabled.
+// case FID_RECALC:
+// if ( aDocument.GetAutoCalc() )
+// rSet.DisableItem( nWhich );
+// break;
+
+ case SID_TABLES_COUNT:
+ rSet.Put( SfxInt16Item( nWhich, aDocument.GetTableCount() ) );
+ break;
+
+ case SID_ATTR_YEAR2000 :
+ rSet.Put( SfxUInt16Item( nWhich,
+ aDocument.GetDocOptions().GetYear2000() ) );
+ break;
+
+ case SID_SHARE_DOC:
+ {
+ if ( IsReadOnly() )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ }
+ break;
+
+ default:
+ {
+ }
+ break;
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+}
+
+void ScDocShell::GetSbxState( SfxItemSet &rSet )
+{
+ // SID_SC_SELECTION (Selection),
+ // SID_SC_ACTIVECELL (ActiveCell),
+ // SID_SC_ACTIVETAB (ActiveTable),
+ // SID_TABLES_GET (Tables),
+ // SID_PIVOT_GET (DataPilotTables) - removed (old Basic)
+
+ //
+ // Wenn hier Slots von der View-Shell executed werden, muss auch der
+ // GetState weitergeleitet werden!
+ //
+
+ ScTabViewShell* pVisibleSh = GetBestViewShell(); // sichtbare View
+ if ( pVisibleSh )
+ pVisibleSh->GetState( rSet );
+}
+
+void __EXPORT ScDocShell::Draw( OutputDevice* pDev, const JobSetup & /* rSetup */, USHORT nAspect )
+{
+// bIsOle = TRUE; // jetzt ueber den CreateMode
+
+ SCTAB nVisTab = aDocument.GetVisibleTab();
+ if (!aDocument.HasTable(nVisTab))
+ return;
+
+ ULONG nOldLayoutMode = pDev->GetLayoutMode();
+ pDev->SetLayoutMode( TEXT_LAYOUT_DEFAULT ); // even if it's the same, to get the metafile action
+
+ if ( nAspect == ASPECT_THUMBNAIL )
+ {
+ Rectangle aBoundRect = GetVisArea( ASPECT_THUMBNAIL );
+ ScViewData aTmpData( this, NULL );
+ aTmpData.SetTabNo(nVisTab);
+ aDocument.SnapVisArea( aBoundRect );
+ aTmpData.SetScreen( aBoundRect );
+ ScPrintFunc::DrawToDev( &aDocument, pDev, 1.0, aBoundRect, &aTmpData, TRUE );
+ }
+ else
+ {
+ Rectangle aBoundRect = SfxObjectShell::GetVisArea();
+ ScViewData aTmpData( this, NULL );
+ aTmpData.SetTabNo(nVisTab);
+ aDocument.SnapVisArea( aBoundRect );
+ aTmpData.SetScreen( aBoundRect );
+ ScPrintFunc::DrawToDev( &aDocument, pDev, 1.0, aBoundRect, &aTmpData, TRUE );
+ }
+
+ pDev->SetLayoutMode( nOldLayoutMode );
+}
+
+Rectangle __EXPORT ScDocShell::GetVisArea( USHORT nAspect ) const
+{
+ SfxObjectCreateMode eShellMode = GetCreateMode();
+ if ( eShellMode == SFX_CREATE_MODE_ORGANIZER )
+ {
+ // ohne Inhalte wissen wir auch nicht, wie gross die Inhalte sind
+ // leeres Rechteck zurueckgeben, das wird dann nach dem Laden berechnet
+ return Rectangle();
+ }
+
+ if( nAspect == ASPECT_THUMBNAIL )
+ {
+// Rectangle aArea( 0,0, 3175,3175 ); // 120x120 Pixel in 1:1
+ Rectangle aArea( 0,0, SC_PREVIEW_SIZE_X,SC_PREVIEW_SIZE_Y );
+ BOOL bNegativePage = aDocument.IsNegativePage( aDocument.GetVisibleTab() );
+ if ( bNegativePage )
+ ScDrawLayer::MirrorRectRTL( aArea );
+ aDocument.SnapVisArea( aArea );
+ return aArea;
+ }
+ else if( nAspect == ASPECT_CONTENT && eShellMode != SFX_CREATE_MODE_EMBEDDED )
+ {
+ // Visarea holen wie nach Load
+
+ SCTAB nVisTab = aDocument.GetVisibleTab();
+ if (!aDocument.HasTable(nVisTab))
+ {
+ nVisTab = 0;
+ ((ScDocShell*)this)->aDocument.SetVisibleTab(nVisTab);
+ }
+ SCCOL nStartCol;
+ SCROW nStartRow;
+ aDocument.GetDataStart( nVisTab, nStartCol, nStartRow );
+ SCCOL nEndCol;
+ SCROW nEndRow;
+ aDocument.GetPrintArea( nVisTab, nEndCol, nEndRow );
+ if (nStartCol>nEndCol)
+ nStartCol = nEndCol;
+ if (nStartRow>nEndRow)
+ nStartRow = nEndRow;
+ Rectangle aNewArea = ((ScDocument&)aDocument)
+ .GetMMRect( nStartCol,nStartRow, nEndCol,nEndRow, nVisTab );
+ //TODO/LATER: different methods for setting VisArea?!
+ ((ScDocShell*)this)->SfxObjectShell::SetVisArea( aNewArea );
+ return aNewArea;
+ }
+ else
+ return SfxObjectShell::GetVisArea( nAspect );
+}
+
+void ScDocShell::GetPageOnFromPageStyleSet( const SfxItemSet* pStyleSet,
+ SCTAB nCurTab,
+ BOOL& rbHeader,
+ BOOL& rbFooter )
+{
+ if ( !pStyleSet )
+ {
+ ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->
+ Find( aDocument.GetPageStyle( nCurTab ),
+ SFX_STYLE_FAMILY_PAGE );
+
+ DBG_ASSERT( pStyleSheet, "PageStyle not found! :-/" );
+
+ if ( pStyleSheet )
+ pStyleSet = &pStyleSheet->GetItemSet();
+ else
+ rbHeader = rbFooter = FALSE;
+ }
+
+ DBG_ASSERT( pStyleSet, "PageStyle-Set not found! :-(" );
+
+ //--------------------------------------------------------------------
+
+ const SvxSetItem* pSetItem = NULL;
+ const SfxItemSet* pSet = NULL;
+
+ pSetItem = (const SvxSetItem*) &pStyleSet->Get( ATTR_PAGE_HEADERSET );
+ pSet = &pSetItem->GetItemSet();
+ rbHeader = ((const SfxBoolItem&)pSet->Get(ATTR_PAGE_ON)).GetValue();
+
+ pSetItem = (const SvxSetItem*) &pStyleSet->Get( ATTR_PAGE_FOOTERSET );
+ pSet = &pSetItem->GetItemSet();
+ rbFooter = ((const SfxBoolItem&)pSet->Get(ATTR_PAGE_ON)).GetValue();
+}
+
+long __EXPORT ScDocShell::DdeGetData( const String& rItem,
+ const String& rMimeType,
+ ::com::sun::star::uno::Any & rValue )
+{
+ if( FORMAT_STRING == SotExchange::GetFormatIdFromMimeType( rMimeType ) )
+ {
+ if( rItem.EqualsIgnoreCaseAscii( "Format" ) )
+ {
+ ByteString aFmtByte( aDdeTextFmt, gsl_getSystemTextEncoding() );
+ rValue <<= ::com::sun::star::uno::Sequence< sal_Int8 >(
+ (sal_Int8*)aFmtByte.GetBuffer(),
+ aFmtByte.Len() + 1 );
+ return 1;
+ }
+ ScImportExport aObj( &aDocument, rItem );
+ if ( !aObj.IsRef() )
+ return 0; // ungueltiger Bereich
+
+ if( aDdeTextFmt.GetChar(0) == 'F' )
+ aObj.SetFormulas( TRUE );
+ if( aDdeTextFmt.EqualsAscii( "SYLK" ) ||
+ aDdeTextFmt.EqualsAscii( "FSYLK" ) )
+ {
+ ByteString aData;
+ if( aObj.ExportByteString( aData, gsl_getSystemTextEncoding(),
+ SOT_FORMATSTR_ID_SYLK ) )
+ {
+ rValue <<= ::com::sun::star::uno::Sequence< sal_Int8 >(
+ (sal_Int8*)aData.GetBuffer(),
+ aData.Len() + 1 );
+ return 1;
+ }
+ else
+ return 0;
+ }
+ if( aDdeTextFmt.EqualsAscii( "CSV" ) ||
+ aDdeTextFmt.EqualsAscii( "FCSV" ) )
+ aObj.SetSeparator( ',' );
+ aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, 0, false ) );
+ return aObj.ExportData( rMimeType, rValue ) ? 1 : 0;
+ }
+
+ ScImportExport aObj( &aDocument, rItem );
+ aObj.SetExportTextOptions( ScExportTextOptions( ScExportTextOptions::ToSpace, 0, false ) );
+ if( aObj.IsRef() )
+ return aObj.ExportData( rMimeType, rValue ) ? 1 : 0;
+ return 0;
+}
+
+long __EXPORT ScDocShell::DdeSetData( const String& rItem,
+ const String& rMimeType,
+ const ::com::sun::star::uno::Any & rValue )
+{
+ if( FORMAT_STRING == SotExchange::GetFormatIdFromMimeType( rMimeType ))
+ {
+ if( rItem.EqualsIgnoreCaseAscii( "Format" ) )
+ {
+ if ( ScByteSequenceToString::GetString( aDdeTextFmt, rValue, gsl_getSystemTextEncoding() ) )
+ {
+ aDdeTextFmt.ToUpperAscii();
+ return 1;
+ }
+ return 0;
+ }
+ ScImportExport aObj( &aDocument, rItem );
+ if( aDdeTextFmt.GetChar(0) == 'F' )
+ aObj.SetFormulas( TRUE );
+ if( aDdeTextFmt.EqualsAscii( "SYLK" ) ||
+ aDdeTextFmt.EqualsAscii( "FSYLK" ) )
+ {
+ String aData;
+ if ( ScByteSequenceToString::GetString( aData, rValue, gsl_getSystemTextEncoding() ) )
+ {
+ return aObj.ImportString( aData, SOT_FORMATSTR_ID_SYLK ) ? 1 : 0;
+ }
+ return 0;
+ }
+ if( aDdeTextFmt.EqualsAscii( "CSV" ) ||
+ aDdeTextFmt.EqualsAscii( "FCSV" ) )
+ aObj.SetSeparator( ',' );
+ return aObj.ImportData( rMimeType, rValue ) ? 1 : 0;
+ }
+ ScImportExport aObj( &aDocument, rItem );
+ if( aObj.IsRef() )
+ return aObj.ImportData( rMimeType, rValue ) ? 1 : 0;
+ return 0;
+}
+
+::sfx2::SvLinkSource* __EXPORT ScDocShell::DdeCreateLinkSource( const String& rItem )
+{
+ // only check for valid item string - range is parsed again in ScServerObject ctor
+
+ // named range?
+ String aPos = rItem;
+ ScRangeName* pRange = aDocument.GetRangeName();
+ if( pRange )
+ {
+ USHORT nPos;
+ if( pRange->SearchName( aPos, nPos ) )
+ {
+ ScRangeData* pData = (*pRange)[ nPos ];
+ if( pData->HasType( RT_REFAREA )
+ || pData->HasType( RT_ABSAREA )
+ || pData->HasType( RT_ABSPOS ) )
+ pData->GetSymbol( aPos ); // continue with the name's contents
+ }
+ }
+
+ // Address in DDE function must be always parsed as CONV_OOO so that it
+ // would always work regardless of current address convension. We do this
+ // because the address item in a DDE entry is *not* normalized when saved
+ // into ODF.
+ ScRange aRange;
+ bool bValid = ( (aRange.Parse(aPos, &aDocument, formula::FormulaGrammar::CONV_OOO ) & SCA_VALID) ||
+ (aRange.aStart.Parse(aPos, &aDocument, formula::FormulaGrammar::CONV_OOO) & SCA_VALID) );
+
+ ScServerObject* pObj = NULL; // NULL = error
+ if ( bValid )
+ pObj = new ScServerObject( this, rItem );
+
+ // GetLinkManager()->InsertServer() is in the ScServerObject ctor
+
+ return pObj;
+}
+
+//------------------------------------------------------------------
+
+ScViewData* ScDocShell::GetViewData()
+{
+ SfxViewShell* pCur = SfxViewShell::Current();
+ ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,pCur);
+ return pViewSh ? pViewSh->GetViewData() : NULL;
+}
+
+//------------------------------------------------------------------
+
+SCTAB ScDocShell::GetCurTab()
+{
+ //! this must be made non-static and use a ViewShell from this document!
+
+ ScViewData* pViewData = GetViewData();
+
+ return pViewData ? pViewData->GetTabNo() : static_cast<SCTAB>(0);
+}
+
+ScTabViewShell* ScDocShell::GetBestViewShell( BOOL bOnlyVisible )
+{
+ ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
+ // falsches Doc?
+ if( pViewSh && pViewSh->GetViewData()->GetDocShell() != this )
+ pViewSh = NULL;
+ if( !pViewSh )
+ {
+ // 1. ViewShell suchen
+ SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this, bOnlyVisible );
+ if( pFrame )
+ {
+ SfxViewShell* p = pFrame->GetViewShell();
+ pViewSh = PTR_CAST(ScTabViewShell,p);
+ }
+ }
+ return pViewSh;
+}
+
+SfxBindings* ScDocShell::GetViewBindings()
+{
+ // used to invalidate slots after changes to this document
+
+ SfxViewShell* pViewSh = GetBestViewShell();
+ if (pViewSh)
+ return &pViewSh->GetViewFrame()->GetBindings();
+ else
+ return NULL;
+}
+
+//------------------------------------------------------------------
+
+ScDocShell* ScDocShell::GetShellByNum( USHORT nDocNo ) // static
+{
+ ScDocShell* pFound = NULL;
+ SfxObjectShell* pShell = SfxObjectShell::GetFirst();
+ USHORT nShellCnt = 0;
+
+ while ( pShell && !pFound )
+ {
+ if ( pShell->Type() == TYPE(ScDocShell) )
+ {
+ if ( nShellCnt == nDocNo )
+ pFound = (ScDocShell*) pShell;
+ else
+ ++nShellCnt;
+ }
+ pShell = SfxObjectShell::GetNext( *pShell );
+ }
+
+ return pFound;
+}
+
+//------------------------------------------------------------------
+
+IMPL_LINK( ScDocShell, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg )
+{
+ DBG_ASSERT( _pFileDlg, "ScDocShell::DialogClosedHdl(): no file dialog" );
+ DBG_ASSERT( pImpl->pDocInserter, "ScDocShell::DialogClosedHdl(): no document inserter" );
+
+ if ( ERRCODE_NONE == _pFileDlg->GetError() )
+ {
+ USHORT nSlot = pImpl->pRequest->GetSlot();
+ SfxMedium* pMed = pImpl->pDocInserter->CreateMedium();
+ // #i87094# If a .odt was selected pMed is NULL.
+ if (pMed)
+ {
+ pImpl->pRequest->AppendItem( SfxStringItem( SID_FILE_NAME, pMed->GetName() ) );
+ if ( SID_DOCUMENT_COMPARE == nSlot )
+ {
+ if ( pMed->GetFilter() )
+ pImpl->pRequest->AppendItem(
+ SfxStringItem( SID_FILTER_NAME, pMed->GetFilter()->GetFilterName() ) );
+ String sOptions = ScDocumentLoader::GetOptions( *pMed );
+ if ( sOptions.Len() > 0 )
+ pImpl->pRequest->AppendItem( SfxStringItem( SID_FILE_FILTEROPTIONS, sOptions ) );
+ }
+ const SfxPoolItem* pItem = NULL;
+ SfxItemSet* pSet = pMed->GetItemSet();
+ if ( pSet &&
+ pSet->GetItemState( SID_VERSION, TRUE, &pItem ) == SFX_ITEM_SET &&
+ pItem->ISA( SfxInt16Item ) )
+ {
+ pImpl->pRequest->AppendItem( *pItem );
+ }
+
+ Execute( *(pImpl->pRequest) );
+ }
+ }
+
+ pImpl->bIgnoreLostRedliningWarning = false;
+ return 0;
+}
+
+//------------------------------------------------------------------
+
+void ScDocShell::EnableSharedSettings( bool bEnable )
+{
+ SetDocumentModified();
+
+ if ( bEnable )
+ {
+ aDocument.EndChangeTracking();
+ aDocument.StartChangeTracking();
+
+ // hide accept or reject changes dialog
+ USHORT nId = ScAcceptChgDlgWrapper::GetChildWindowId();
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if ( pViewFrame && pViewFrame->HasChildWindow( nId ) )
+ {
+ pViewFrame->ToggleChildWindow( nId );
+ SfxBindings* pBindings = GetViewBindings();
+ if ( pBindings )
+ {
+ pBindings->Invalidate( FID_CHG_ACCEPT );
+ }
+ }
+ }
+ else
+ {
+ aDocument.EndChangeTracking();
+ }
+
+ ScChangeViewSettings aChangeViewSet;
+ aChangeViewSet.SetShowChanges( FALSE );
+ aDocument.SetChangeViewSettings( aChangeViewSet );
+}
+
+uno::Reference< frame::XModel > ScDocShell::LoadSharedDocument()
+{
+ uno::Reference< frame::XModel > xModel;
+ try
+ {
+ SC_MOD()->SetInSharedDocLoading( true );
+ uno::Reference< lang::XMultiServiceFactory > xFactory(
+ ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
+ uno::Reference< frame::XComponentLoader > xLoader(
+ xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ) ),
+ uno::UNO_QUERY_THROW );
+ uno::Sequence < beans::PropertyValue > aArgs( 1 );
+ aArgs[0].Name = ::rtl::OUString::createFromAscii( "Hidden" );
+ aArgs[0].Value <<= sal_True;
+
+ if ( GetMedium() )
+ {
+ SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False);
+ if ( pPasswordItem && pPasswordItem->GetValue().Len() )
+ {
+ aArgs.realloc( 2 );
+ aArgs[1].Name = ::rtl::OUString::createFromAscii( "Password" );
+ aArgs[1].Value <<= ::rtl::OUString( pPasswordItem->GetValue() );
+ }
+ }
+
+ xModel.set(
+ xLoader->loadComponentFromURL( GetSharedFileURL(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" ) ), 0, aArgs ),
+ uno::UNO_QUERY_THROW );
+ SC_MOD()->SetInSharedDocLoading( false );
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERROR( "ScDocShell::LoadSharedDocument(): caught exception\n" );
+ SC_MOD()->SetInSharedDocLoading( false );
+ try
+ {
+ uno::Reference< util::XCloseable > xClose( xModel, uno::UNO_QUERY_THROW );
+ xClose->close( sal_True );
+ return uno::Reference< frame::XModel >();
+ }
+ catch ( uno::Exception& )
+ {
+ return uno::Reference< frame::XModel >();
+ }
+ }
+ return xModel;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */