diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2000-09-18 16:07:07 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2000-09-18 16:07:07 +0000 |
commit | 9ae5a91f7955e44d3b24a3f7741f9bca02ac7f24 (patch) | |
tree | 13c111a6380728f470fa177e679b80089a01efc4 /sc/source/ui/docshell |
initial import
Diffstat (limited to 'sc/source/ui/docshell')
24 files changed, 18257 insertions, 0 deletions
diff --git a/sc/source/ui/docshell/arealink.cxx b/sc/source/ui/docshell/arealink.cxx new file mode 100644 index 000000000000..bb0b47ec4354 --- /dev/null +++ b/sc/source/ui/docshell/arealink.cxx @@ -0,0 +1,442 @@ +/************************************************************************* + * + * $RCSfile: arealink.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#pragma hdrstop + +// INCLUDE --------------------------------------------------------- + +#include <sfx2/app.hxx> +#include <sfx2/docfile.hxx> +#include <svx/linkmgr.hxx> +#include <svtools/stritem.hxx> +#include <vcl/msgbox.hxx> + +#include "arealink.hxx" + +#include "tablink.hxx" +#include "document.hxx" +#include "docsh.hxx" +#include "rangenam.hxx" +#include "dbcolect.hxx" +#include "undoblk.hxx" +#include "globstr.hrc" +#include "markdata.hxx" +#include "hints.hxx" + +#include "attrib.hxx" // raus, wenn ResetAttrib am Dokument +#include "patattr.hxx" // raus, wenn ResetAttrib am Dokument +#include "docpool.hxx" // raus, wenn ResetAttrib am Dokument + +TYPEINIT1(ScAreaLink,SvBaseLink); + +//------------------------------------------------------------------------ + +ScAreaLink::ScAreaLink( SfxObjectShell* pShell, const String& rFile, + const String& rFilter, const String& rOpt, + const String& rArea, const ScRange& rDest ) : + SvBaseLink (LINKUPDATE_ONCALL,FORMAT_FILE), + pDocShell ((ScDocShell*)pShell), + aFileName (rFile), + aFilterName (rFilter), + aOptions (rOpt), + aSourceArea (rArea), + aDestArea (rDest), + bAddUndo (TRUE), + bInCreate (FALSE), + bDoInsert (TRUE) +{ + DBG_ASSERT(pShell->ISA(ScDocShell), "ScAreaLink mit falscher ObjectShell"); +} + +__EXPORT ScAreaLink::~ScAreaLink() +{ + // Verbindung aufheben +} + +BOOL __EXPORT ScAreaLink::Edit(Window* pParent) +{ + // DefModalDialogParent setzen, weil evtl. aus der DocShell beim ConvertFrom + // ein Optionen-Dialog kommt... + + Window* pOldParent = Application::GetDefDialogParent(); + if (pParent) + Application::SetDefDialogParent(pParent); + + BOOL bRet = SvBaseLink::Edit(pParent); + + Application::SetDefDialogParent(pOldParent); + + return bRet; +} + +void __EXPORT ScAreaLink::DataChanged(SvData& rData) +{ + // bei bInCreate nichts tun, damit Update gerufen werden kann, um den Status im + // LinkManager zu setzen, ohne die Daten im Dokument zu aendern + + if (bInCreate) + return; + + SvxLinkManager* pLinkManager=pDocShell->GetDocument()->GetLinkManager(); + if (pLinkManager!=NULL) + { + String aFile; + String aFilter; + String aArea; + pLinkManager->GetDisplayNames(*this,0,&aFile,&aArea,&aFilter); + + // aus dem Dialog kommt der Filtername mit Applikation davor + //! soll das so sein ??!?! + String aAppPrefix = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( STRING_SCAPP )); + aAppPrefix.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " )); + xub_StrLen nPreLen = aAppPrefix.Len(); + if ( aFilter.Copy(0,nPreLen) == aAppPrefix ) + aFilter.Erase(0,nPreLen); + + Refresh(aFile,aFilter,aArea); + } +} + +void __EXPORT ScAreaLink::Closed() +{ + // Verknuepfung loeschen: Undo + + if (bAddUndo) + { + pDocShell->GetUndoManager()->AddUndoAction( new ScUndoRemoveAreaLink( pDocShell, + aFileName, aFilterName, aOptions, + aSourceArea, aDestArea ) ); + + bAddUndo = FALSE; // nur einmal + } + + SvBaseLink::Closed(); +} + +void ScAreaLink::SetDestArea(const ScRange& rNew) +{ + aDestArea = rNew; // fuer Undo +} + +void ScAreaLink::SetSource(const String& rDoc, const String& rFlt, const String& rOpt, + const String& rArea) +{ + aFileName = rDoc; + aFilterName = rFlt; + aOptions = rOpt; + aSourceArea = rArea; +} + +BOOL ScAreaLink::IsEqual( const String& rFile, const String& rFilter, const String& rOpt, + const String& rSource, const ScRange& rDest ) const +{ + return aFileName == rFile && aFilterName == rFilter && aOptions == rOpt && + aSourceArea == rSource && aDestArea == rDest; +} + +// ausfuehren: + +BOOL ScAreaLink::Refresh( const String& rNewFile, const String& rNewFilter, + const String& rNewArea ) +{ + // Dokument laden - wie TabLink + + if (!rNewFile.Len() || !rNewFilter.Len()) + return FALSE; + + String aNewUrl( ScGlobal::GetAbsDocName( rNewFile, pDocShell ) ); + BOOL bNewUrlName = (aNewUrl != aFileName); + + const SfxFilter* pFilter = SFX_APP()->GetFilter( pDocShell->GetFactory(), rNewFilter ); + if (!pFilter) + return FALSE; + + ScDocument* pDoc = pDocShell->GetDocument(); + pDoc->SetInLinkUpdate( TRUE ); + + // wenn neuer Filter ausgewaehlt wurde, Optionen vergessen + if ( rNewFilter != aFilterName ) + aOptions.Erase(); + + // ItemSet immer anlegen, damit die DocShell die Optionen setzen kann + SfxItemSet* pSet = new SfxAllItemSet( SFX_APP()->GetPool() ); + if ( aOptions.Len() ) + pSet->Put( SfxStringItem( SID_FILE_FILTEROPTIONS, aOptions ) ); + + SfxMedium* pMed = new SfxMedium(aNewUrl, STREAM_STD_READ, FALSE, TRUE, pFilter); + + ScDocShell* pSrcShell = new ScDocShell(SFX_CREATE_MODE_INTERNAL); + SvEmbeddedObjectRef aRef = pSrcShell; + pSrcShell->DoLoad(pMed); + + // Optionen koennten gesetzt worden sein + String aNewOpt = ScDocumentLoader::GetOptions(*pMed); + if (!aNewOpt.Len()) + aNewOpt = aOptions; + + // Bereich suchen + + BOOL bFound = FALSE; + ScRange aSourceRange; + ScDocument* pSrcDoc = pSrcShell->GetDocument(); + ScRangeName* pNames = pSrcDoc->GetRangeName(); + USHORT nPos; + if (pNames) // benannte Bereiche + { + if (pNames->SearchName( rNewArea, nPos )) + if ( (*pNames)[nPos]->IsReference( aSourceRange ) ) + bFound = TRUE; + } + if (!bFound) // Datenbankbereiche + { + ScDBCollection* pDBColl = pSrcDoc->GetDBCollection(); + if (pDBColl) + if (pDBColl->SearchName( rNewArea, nPos )) + { + USHORT nTab,nCol1,nRow1,nCol2,nRow2; + (*pDBColl)[nPos]->GetArea(nTab,nCol1,nRow1,nCol2,nRow2); + aSourceRange = ScRange( nCol1,nRow1,nTab, nCol2,nRow2,nTab ); + bFound = TRUE; + } + } + if (!bFound) // direct reference (range or cell) + { + if ( aSourceRange.ParseAny( rNewArea, pSrcDoc ) & SCA_VALID ) + bFound = TRUE; + } + + // alte Daten loeschen / neue kopieren + + ScAddress aDestPos = aDestArea.aStart; + USHORT nDestTab = aDestPos.Tab(); + ScRange aOldRange = aDestArea; + ScRange aNewRange = aDestArea; // alter Bereich, wenn Datei nicht gefunden o.ae. + if (bFound) + aNewRange.aEnd = ScAddress( + aSourceRange.aEnd.Col() - aSourceRange.aStart.Col() + aDestPos.Col(), + aSourceRange.aEnd.Row() - aSourceRange.aStart.Row() + aDestPos.Row(), + nDestTab ); + + + BOOL bCanDo = pDoc->CanFitBlock( aOldRange, aNewRange ); //! nach bDoInsert unterscheiden + if (bCanDo) + { + ScDocShellModificator aModificator( *pDocShell ); + + USHORT nStartX = aDestPos.Col(); + USHORT nStartY = aDestPos.Row(); + USHORT nOldEndX = aOldRange.aEnd.Col(); + USHORT nOldEndY = aOldRange.aEnd.Row(); + USHORT nNewEndX = aNewRange.aEnd.Col(); + USHORT nNewEndY = aNewRange.aEnd.Row(); + ScRange aMaxRange( aDestPos, + ScAddress(Max(nOldEndX,nNewEndX), Max(nOldEndY,nNewEndY), nDestTab) ); + + // Undo initialisieren + + ScDocument* pUndoDoc = NULL; + ScDocument* pRedoDoc = NULL; + if ( bAddUndo ) + { + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + if ( bDoInsert ) + { + if ( nNewEndX != nOldEndX || nNewEndY != nOldEndY ) // Bereich veraendert? + { + pUndoDoc->InitUndo( pDoc, 0, pDoc->GetTableCount()-1 ); + pDoc->CopyToDocument( 0,0,0,MAXCOL,MAXROW,MAXTAB, + IDF_FORMULA, FALSE, pUndoDoc ); // alle Formeln + } + else + pUndoDoc->InitUndo( pDoc, nDestTab, nDestTab ); // nur Zieltabelle + pDoc->CopyToDocument( aOldRange, IDF_ALL, FALSE, pUndoDoc ); + } + else // ohne Einfuegen + { + pUndoDoc->InitUndo( pDoc, nDestTab, nDestTab ); // nur Zieltabelle + pDoc->CopyToDocument( aMaxRange, IDF_ALL, FALSE, pUndoDoc ); + } + } + + // Zellen einfuegen / loeschen + // DeleteAreaTab loescht auch MERGE_FLAG Attribute + + if (bDoInsert) + pDoc->FitBlock( aOldRange, aNewRange ); // incl. loeschen + else + pDoc->DeleteAreaTab( aMaxRange, IDF_ALL ); + + // Daten kopieren + + if (bFound) + { + USHORT nSrcTab = aSourceRange.aStart.Tab(); + ScMarkData aSourceMark; + aSourceMark.SelectOneTable( nSrcTab ); // selektieren fuer CopyToClip + aSourceMark.SetMarkArea( aSourceRange ); + + ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP ); + pSrcDoc->CopyToClip( aSourceRange.aStart.Col(),aSourceRange.aStart.Row(), + aSourceRange.aEnd.Col(),aSourceRange.aEnd.Row(), + FALSE, pClipDoc, FALSE, &aSourceMark ); + + if ( pClipDoc->HasAttrib( 0,0,nSrcTab, MAXCOL,MAXROW,nSrcTab, + HASATTR_MERGED | HASATTR_OVERLAPPED ) ) + { + //! ResetAttrib am Dokument !!! + + ScPatternAttr aPattern( pSrcDoc->GetPool() ); + aPattern.GetItemSet().Put( ScMergeAttr() ); // Defaults + aPattern.GetItemSet().Put( ScMergeFlagAttr() ); + pClipDoc->ApplyPatternAreaTab( 0,0, MAXCOL,MAXROW, nSrcTab, aPattern ); + } + + ScMarkData aDestMark; + aDestMark.SelectOneTable( nDestTab ); + aDestMark.SetMarkArea( aNewRange ); + pDoc->CopyFromClip( aNewRange, aDestMark, IDF_ALL, NULL, pClipDoc, FALSE ); + } + else + { + String aErr = ScGlobal::GetRscString(STR_LINKERROR); + pDoc->SetString( aDestPos.Col(), aDestPos.Row(), aDestPos.Tab(), aErr ); + } + + // Undo eintragen + + if ( bAddUndo ) + { + pRedoDoc = new ScDocument( SCDOCMODE_UNDO ); + pRedoDoc->InitUndo( pDoc, nDestTab, nDestTab ); + pDoc->CopyToDocument( aNewRange, IDF_ALL, FALSE, pRedoDoc ); + + pDocShell->GetUndoManager()->AddUndoAction( + new ScUndoUpdateAreaLink( pDocShell, + aFileName, aFilterName, aOptions, + aSourceArea, aOldRange, + aNewUrl, rNewFilter, aNewOpt, + rNewArea, aNewRange, + pUndoDoc, pRedoDoc, bDoInsert ) ); + } + + // neue Einstellungen merken + + if ( bNewUrlName ) + aFileName = aNewUrl; + if ( rNewFilter != aFilterName ) + aFilterName = rNewFilter; + if ( rNewArea != aSourceArea ) + aSourceArea = rNewArea; + if ( aNewOpt != aOptions ) + aOptions = aNewOpt; + + if ( aNewRange != aDestArea ) + aDestArea = aNewRange; + + USHORT nPaintEndX = Max( aOldRange.aEnd.Col(), aNewRange.aEnd.Col() ); + USHORT nPaintEndY = Max( aOldRange.aEnd.Row(), aNewRange.aEnd.Row() ); + + if ( aOldRange.aEnd.Col() != aNewRange.aEnd.Col() ) + nPaintEndX = MAXCOL; + if ( aOldRange.aEnd.Row() != aNewRange.aEnd.Row() ) + nPaintEndY = MAXROW; + + pDocShell->PostPaint( aDestPos.Col(),aDestPos.Row(),nDestTab, + nPaintEndX,nPaintEndY,nDestTab, PAINT_GRID ); + aModificator.SetDocumentModified(); + } + else + { + // CanFitBlock FALSE -> Probleme mit zusammengefassten Zellen + // oder Tabellengrenze erreicht! + //! Zellschutz ??? + + //! Link-Dialog muss Default-Parent setzen + // "kann keine Zeilen einfuegen" + InfoBox aBox( Application::GetDefDialogParent(), + ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_2 ) ); + aBox.Execute(); + } + + // aufraeumen + + aRef->DoClose(); + + pDoc->SetInLinkUpdate( FALSE ); + + if (bCanDo) + { + // notify Uno objects (for XRefreshListener) + //! also notify Uno objects if file name was changed! + ScLinkRefreshedHint aHint; + aHint.SetAreaLink( aDestPos ); + pDoc->BroadcastUno( aHint ); + } + + return bCanDo; +} + + + diff --git a/sc/source/ui/docshell/autostyl.cxx b/sc/source/ui/docshell/autostyl.cxx new file mode 100644 index 000000000000..29fab8619ebd --- /dev/null +++ b/sc/source/ui/docshell/autostyl.cxx @@ -0,0 +1,284 @@ +/************************************************************************* + * + * $RCSfile: autostyl.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#pragma hdrstop + +// INCLUDE --------------------------------------------------------------- + +#include <time.h> +#include "autostyl.hxx" + +#include "docsh.hxx" +#include "attrib.hxx" +#include "sc.hrc" + +//================================================================== + +struct ScAutoStyleInitData +{ + ScRange aRange; + String aStyle1; + ULONG nTimeout; + String aStyle2; + + ScAutoStyleInitData( const ScRange& rR, const String& rSt1, ULONG nT, const String& rSt2 ) : + aRange(rR), aStyle1(rSt1), nTimeout(nT), aStyle2(rSt2) {} +}; + +struct ScAutoStyleData +{ + ULONG nTimeout; + ScRange aRange; + String aStyle; + + ScAutoStyleData( ULONG nT, const ScRange& rR, const String& rT ) : + nTimeout(nT), aRange(rR), aStyle(rT) {} +}; + +//================================================================== + +inline ULONG TimeNow() // Sekunden +{ + return (ULONG) time(0); +} + +//================================================================== + +ScAutoStyleList::ScAutoStyleList(ScDocShell* pShell) : + pDocSh( pShell ) +{ + aTimer.SetTimeoutHdl( LINK( this, ScAutoStyleList, TimerHdl ) ); + aInitTimer.SetTimeoutHdl( LINK( this, ScAutoStyleList, InitHdl ) ); + aInitTimer.SetTimeout( 0 ); +} + +ScAutoStyleList::~ScAutoStyleList() +{ + ULONG i; + ULONG nCount = aEntries.Count(); + for (i=0; i<nCount; i++) + delete (ScAutoStyleData*) aEntries.GetObject(i); + nCount = aInitials.Count(); + for (i=0; i<nCount; i++) + delete (ScAutoStyleInitData*) aInitials.GetObject(i); +} + +//================================================================== + +// initial short delay (asynchronous call) + +void ScAutoStyleList::AddInitial( const ScRange& rRange, const String& rStyle1, + ULONG nTimeout, const String& rStyle2 ) +{ + ScAutoStyleInitData* pNew = + new ScAutoStyleInitData( rRange, rStyle1, nTimeout, rStyle2 ); + aInitials.Insert( pNew, aInitials.Count() ); + aInitTimer.Start(); +} + +IMPL_LINK( ScAutoStyleList, InitHdl, Timer*, pTimer ) +{ + DBG_ASSERT( pTimer == &aInitTimer, "wrong timer" ); + + ULONG nCount = aInitials.Count(); + for (ULONG i=0; i<nCount; i++) + { + ScAutoStyleInitData* pData = (ScAutoStyleInitData*) aInitials.GetObject(i); + + // apply first style immediately + pDocSh->DoAutoStyle( pData->aRange, pData->aStyle1 ); + + // add second style to list + if ( pData->nTimeout ) + AddEntry( pData->nTimeout, pData->aRange, pData->aStyle2 ); + + delete pData; + } + aInitials.Clear(); + + return 0; +} + +//================================================================== + +void ScAutoStyleList::AddEntry( ULONG nTimeout, const ScRange& rRange, const String& rStyle ) +{ + aTimer.Stop(); + ULONG nNow = TimeNow(); + + // alten Eintrag loeschen + + ULONG nCount = aEntries.Count(); + ULONG i; + for (i=0; i<nCount; i++) + { + ScAutoStyleData* pData = (ScAutoStyleData*) aEntries.GetObject(i); + if (pData->aRange == rRange) + { + delete pData; + aEntries.Remove(i); + --nCount; + break; // nicht weitersuchen - es kann nur einen geben + } + } + + // Timeouts von allen Eintraegen anpassen + + if (nCount && nNow != nTimerStart) + { + DBG_ASSERT(nNow>nTimerStart, "Zeit laeuft rueckwaerts?"); + AdjustEntries((nNow-nTimerStart)*1000); + } + + // Einfuege-Position suchen + + ULONG nPos = LIST_APPEND; + BOOL bFound = FALSE; + for (i=0; i<nCount && nPos == LIST_APPEND; i++) + if (nTimeout <= ((ScAutoStyleData*) aEntries.GetObject(i))->nTimeout) + nPos = i; + + ScAutoStyleData* pNew = new ScAutoStyleData( nTimeout, rRange, rStyle ); + aEntries.Insert( pNew, nPos ); + + // abgelaufene ausfuehren, Timer neu starten + + ExecuteEntries(); + StartTimer(nNow); +} + +void ScAutoStyleList::AdjustEntries( ULONG nDiff ) // Millisekunden +{ + ULONG nCount = aEntries.Count(); + for (ULONG i=0; i<nCount; i++) + { + ScAutoStyleData* pData = (ScAutoStyleData*) aEntries.GetObject(i); + if ( pData->nTimeout <= nDiff ) + pData->nTimeout = 0; // abgelaufen + else + pData->nTimeout -= nDiff; // weiterzaehlen + } +} + +void ScAutoStyleList::ExecuteEntries() +{ + ScAutoStyleData* pData; + while ((pData = (ScAutoStyleData*) aEntries.GetObject(0)) && pData->nTimeout == 0) + { + pDocSh->DoAutoStyle( pData->aRange, pData->aStyle ); //! oder Request ??? + + delete pData; + aEntries.Remove((ULONG)0); + } +} + +void ScAutoStyleList::ExecuteAllNow() +{ + aTimer.Stop(); + + ULONG nCount = aEntries.Count(); + for (ULONG i=0; i<nCount; i++) + { + ScAutoStyleData* pData = (ScAutoStyleData*) aEntries.GetObject(i); + + pDocSh->DoAutoStyle( pData->aRange, pData->aStyle ); //! oder Request ??? + + delete pData; + } + aEntries.Clear(); +} + +void ScAutoStyleList::StartTimer( ULONG nNow ) // Sekunden +{ + // ersten Eintrag mit Timeout != 0 suchen + + ULONG nPos = 0; + ScAutoStyleData* pData; + while ( (pData = (ScAutoStyleData*) aEntries.GetObject(nPos)) && pData->nTimeout == 0 ) + ++nPos; + + if (pData) + { + aTimer.SetTimeout( pData->nTimeout ); + aTimer.Start(); + } + nTimerStart = nNow; +} + +IMPL_LINK( ScAutoStyleList, TimerHdl, Timer*, pTimer ) +{ + DBG_ASSERT( pTimer == &aTimer, "falscher Timer" ); + + ULONG nNow = TimeNow(); + AdjustEntries(aTimer.GetTimeout()); // eingestellte Wartezeit + ExecuteEntries(); + StartTimer(nNow); + + return 0; +} + + + + diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx new file mode 100644 index 000000000000..0d2cf0bcc7ae --- /dev/null +++ b/sc/source/ui/docshell/dbdocfun.cxx @@ -0,0 +1,1342 @@ +/************************************************************************* + * + * $RCSfile: dbdocfun.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#pragma hdrstop + +// INCLUDE --------------------------------------------------------------- + +#include <sfx2/app.hxx> +#include <vcl/msgbox.hxx> +#include <vcl/waitobj.hxx> + +#include "dbdocfun.hxx" +#include "sc.hrc" +#include "dbcolect.hxx" +#include "undodat.hxx" +#include "docsh.hxx" +#include "docfunc.hxx" +#include "globstr.hrc" +#include "tabvwsh.hxx" +#include "patattr.hxx" +#include "rangenam.hxx" +#include "olinetab.hxx" +#include "dpobject.hxx" + +// ----------------------------------------------------------------- + +BOOL ScDBDocFunc::AddDBRange( const String& rName, const ScRange& rRange, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + ScDocument* pDoc = rDocShell.GetDocument(); + ScDBCollection* pDocColl = pDoc->GetDBCollection(); + + ScDBCollection* pUndoColl = new ScDBCollection( *pDocColl ); + + ScDBData* pNew = new ScDBData( rName, rRange.aStart.Tab(), + rRange.aStart.Col(), rRange.aStart.Row(), + rRange.aEnd.Col(), rRange.aEnd.Row() ); + + pDoc->CompileDBFormula( TRUE ); // CreateFormulaString + BOOL bOk = pDocColl->Insert( pNew ); + pDoc->CompileDBFormula( FALSE ); // CompileFormulaString + if (!bOk) + { + delete pNew; + delete pUndoColl; + return FALSE; + } + + ScDBCollection* pRedoColl = new ScDBCollection( *pDocColl ); + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoDBData( &rDocShell, pUndoColl, pRedoColl ) ); + + aModificator.SetDocumentModified(); + SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) ); + return TRUE; +} + +BOOL ScDBDocFunc::DeleteDBRange( const String& rName, BOOL bApi ) +{ + BOOL bDone = FALSE; + ScDocument* pDoc = rDocShell.GetDocument(); + ScDBCollection* pDocColl = pDoc->GetDBCollection(); + + USHORT nPos = 0; + if (pDocColl->SearchName( rName, nPos )) + { + ScDocShellModificator aModificator( rDocShell ); + + ScDBCollection* pUndoColl = new ScDBCollection( *pDocColl ); + + pDoc->CompileDBFormula( TRUE ); // CreateFormulaString + pDocColl->AtFree( nPos ); + pDoc->CompileDBFormula( FALSE ); // CompileFormulaString + + ScDBCollection* pRedoColl = new ScDBCollection( *pDocColl ); + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoDBData( &rDocShell, pUndoColl, pRedoColl ) ); + + aModificator.SetDocumentModified(); + SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) ); + bDone = TRUE; + } + + return bDone; +} + +BOOL ScDBDocFunc::RenameDBRange( const String& rOld, const String& rNew, BOOL bApi ) +{ + BOOL bDone = FALSE; + ScDocument* pDoc = rDocShell.GetDocument(); + ScDBCollection* pDocColl = pDoc->GetDBCollection(); + + USHORT nPos = 0; + USHORT nDummy = 0; + if ( pDocColl->SearchName( rOld, nPos ) && + !pDocColl->SearchName( rNew, nDummy ) ) + { + ScDocShellModificator aModificator( rDocShell ); + + ScDBData* pData = (*pDocColl)[nPos]; + ScDBData* pNewData = new ScDBData(*pData); + pNewData->SetName(rNew); + + ScDBCollection* pUndoColl = new ScDBCollection( *pDocColl ); + + pDoc->CompileDBFormula( TRUE ); // CreateFormulaString + pDocColl->AtFree( nPos ); + BOOL bInserted = pDocColl->Insert( pNewData ); + if (!bInserted) // Fehler -> alten Zustand wiederherstellen + { + delete pNewData; + pDoc->SetDBCollection( pUndoColl ); // gehoert dann dem Dokument + } + pDoc->CompileDBFormula( FALSE ); // CompileFormulaString + + if (bInserted) // Einfuegen hat geklappt + { + ScDBCollection* pRedoColl = new ScDBCollection( *pDocColl ); + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoDBData( &rDocShell, pUndoColl, pRedoColl ) ); + + aModificator.SetDocumentModified(); + SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) ); + bDone = TRUE; + } + } + + return bDone; +} + +BOOL ScDBDocFunc::ModifyDBData( const ScDBData& rNewData, BOOL bApi ) +{ + BOOL bDone = FALSE; + ScDocument* pDoc = rDocShell.GetDocument(); + ScDBCollection* pDocColl = pDoc->GetDBCollection(); + + USHORT nPos = 0; + if (pDocColl->SearchName( rNewData.GetName(), nPos )) + { + ScDocShellModificator aModificator( rDocShell ); + + ScDBData* pData = (*pDocColl)[nPos]; + + ScRange aOldRange, aNewRange; + pData->GetArea(aOldRange); + rNewData.GetArea(aNewRange); + BOOL bAreaChanged = ( aOldRange != aNewRange ); // dann muss neu compiliert werden + + ScDBCollection* pUndoColl = new ScDBCollection( *pDocColl ); + + *pData = rNewData; + if (bAreaChanged) + pDoc->CompileDBFormula(); + + ScDBCollection* pRedoColl = new ScDBCollection( *pDocColl ); + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoDBData( &rDocShell, pUndoColl, pRedoColl ) ); + + aModificator.SetDocumentModified(); + bDone = TRUE; + } + + return bDone; +} + +// ----------------------------------------------------------------- + +BOOL ScDBDocFunc::RepeatDB( const String& rDBName, BOOL bRecord, BOOL bApi ) +{ + //! auch fuer ScDBFunc::RepeatDB benutzen! + + BOOL bDone = FALSE; + ScDocument* pDoc = rDocShell.GetDocument(); + ScDBCollection* pColl = pDoc->GetDBCollection(); + USHORT nIndex; + if ( pColl && pColl->SearchName( rDBName, nIndex ) ) + { + ScDBData* pDBData = (*pColl)[nIndex]; + + ScQueryParam aQueryParam; + pDBData->GetQueryParam( aQueryParam ); + BOOL bQuery = aQueryParam.GetEntry(0).bDoQuery; + + ScSortParam aSortParam; + pDBData->GetSortParam( aSortParam ); + BOOL bSort = aSortParam.bDoSort[0]; + + ScSubTotalParam aSubTotalParam; + pDBData->GetSubTotalParam( aSubTotalParam ); + BOOL bSubTotal = aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly; + + if ( bQuery || bSort || bSubTotal ) + { + BOOL bQuerySize = FALSE; + ScRange aOldQuery; + ScRange aNewQuery; + if (bQuery && !aQueryParam.bInplace) + { + ScDBData* pDest = pDoc->GetDBAtCursor( aQueryParam.nDestCol, aQueryParam.nDestRow, + aQueryParam.nDestTab, TRUE ); + if (pDest && pDest->IsDoSize()) + { + pDest->GetArea( aOldQuery ); + bQuerySize = TRUE; + } + } + + USHORT nTab; + USHORT nStartCol; + USHORT nStartRow; + USHORT nEndCol; + USHORT nEndRow; + pDBData->GetArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow ); + + //! Undo nur benoetigte Daten ? + + ScDocument* pUndoDoc = NULL; + ScOutlineTable* pUndoTab = NULL; + ScRangeName* pUndoRange = NULL; + ScDBCollection* pUndoDB = NULL; + + if (bRecord) + { + USHORT nTabCount = pDoc->GetTableCount(); + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab ); + if (pTable) + { + pUndoTab = new ScOutlineTable( *pTable ); + + USHORT nOutStartCol; // Zeilen/Spaltenstatus + USHORT nOutStartRow; + USHORT nOutEndCol; + USHORT nOutEndRow; + pTable->GetColArray()->GetRange( nOutStartCol, nOutEndCol ); + pTable->GetRowArray()->GetRange( nOutStartRow, nOutEndRow ); + + pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE ); + pDoc->CopyToDocument( nOutStartCol, 0, nTab, nOutEndCol, MAXROW, nTab, IDF_NONE, FALSE, pUndoDoc ); + pDoc->CopyToDocument( 0, nOutStartRow, nTab, MAXCOL, nOutEndRow, nTab, IDF_NONE, FALSE, pUndoDoc ); + } + else + pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, TRUE ); + + // Datenbereich sichern - incl. Filter-Ergebnis + pDoc->CopyToDocument( 0,nStartRow,nTab, MAXCOL,nEndRow,nTab, IDF_ALL, FALSE, pUndoDoc ); + + // alle Formeln wegen Referenzen + pDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTabCount-1, IDF_FORMULA, 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 = TRUE; // wird unten wieder zurueckgesetzt + DoSubTotals( nTab, aSubTotalParam, NULL, FALSE, bApi ); + } + + if (bSort) + { + pDBData->GetSortParam( aSortParam ); // Bereich kann sich geaendert haben + Sort( nTab, aSortParam, FALSE, FALSE, bApi ); + } + if (bQuery) + { + pDBData->GetQueryParam( aQueryParam ); // Bereich kann sich geaendert haben + ScRange aAdvSource; + if (pDBData->GetAdvancedQuerySource(aAdvSource)) + Query( nTab, aQueryParam, &aAdvSource, FALSE, bApi ); + else + Query( nTab, aQueryParam, NULL, FALSE, bApi ); + + // 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 = FALSE; + DoSubTotals( nTab, aSubTotalParam, NULL, FALSE, bApi ); + } + + if (bRecord) + { + USHORT nDummy; + USHORT nNewEndRow; + pDBData->GetArea( nDummy, nDummy,nDummy, nDummy,nNewEndRow ); + + const ScRange* pOld = NULL; + const ScRange* pNew = NULL; + if (bQuerySize) + { + ScDBData* pDest = pDoc->GetDBAtCursor( aQueryParam.nDestCol, aQueryParam.nDestRow, + aQueryParam.nDestTab, TRUE ); + if (pDest) + { + pDest->GetArea( aNewQuery ); + pOld = &aOldQuery; + pNew = &aNewQuery; + } + } + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoRepeatDB( &rDocShell, nTab, + nStartCol, nStartRow, nEndCol, nEndRow, + nNewEndRow, + //nCurX, nCurY, + nStartCol, nStartRow, + pUndoDoc, pUndoTab, + pUndoRange, pUndoDB, + pOld, pNew ) ); + } + + rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, + PAINT_GRID | PAINT_LEFT | PAINT_TOP | PAINT_SIZE ); + bDone = TRUE; + } + else if (!bApi) // "Keine Operationen auszufuehren" + rDocShell.ErrorMessage(STR_MSSG_REPEATDB_0); + } + + return bDone; +} + +// ----------------------------------------------------------------- + +BOOL ScDBDocFunc::Sort( USHORT nTab, const ScSortParam& rSortParam, + BOOL bRecord, BOOL bPaint, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + ScDocument* pDoc = rDocShell.GetDocument(); + USHORT nSrcTab = nTab; + + ScDBData* pDBData = pDoc->GetDBAtArea( nTab, rSortParam.nCol1, rSortParam.nRow1, + rSortParam.nCol2, rSortParam.nRow2 ); + if (!pDBData) + { + DBG_ERROR( "Sort: keine DBData" ); + return FALSE; + } + + ScDBData* pDestData = NULL; + ScRange aOldDest; + BOOL bCopy = !rSortParam.bInplace; + if ( bCopy && rSortParam.nDestCol == rSortParam.nCol1 && + rSortParam.nDestRow == rSortParam.nRow1 && rSortParam.nDestTab == nTab ) + bCopy = FALSE; + ScSortParam aLocalParam( rSortParam ); + if ( bCopy ) + { + aLocalParam.MoveToDest(); + nTab = rSortParam.nDestTab; + pDestData = pDoc->GetDBAtCursor( rSortParam.nDestCol, rSortParam.nDestRow, + rSortParam.nDestTab, TRUE ); + if (pDestData) + pDestData->GetArea(aOldDest); + } + + if (!pDoc->IsBlockEditable(nTab, aLocalParam.nCol1,aLocalParam.nRow1, + aLocalParam.nCol2,aLocalParam.nRow2)) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + return FALSE; + } + + if ( aLocalParam.bIncludePattern && pDoc->HasAttrib( + aLocalParam.nCol1, aLocalParam.nRow1, nTab, + aLocalParam.nCol2, aLocalParam.nRow2, nTab, + HASATTR_MERGED | HASATTR_OVERLAPPED ) ) + { + // Merge-Attribute wuerden beim Sortieren durcheinanderkommen + if (!bApi) + rDocShell.ErrorMessage(STR_SORT_ERR_MERGED); + return FALSE; + } + + + // ausfuehren + + WaitObject aWait( rDocShell.GetDialogParent() ); + + BOOL bRepeatQuery = FALSE; // bestehenden Filter wiederholen? + ScQueryParam aQueryParam; + pDBData->GetQueryParam( aQueryParam ); + if ( aQueryParam.GetEntry(0).bDoQuery ) + bRepeatQuery = TRUE; + + if (bRepeatQuery && bCopy) + { + if ( aQueryParam.bInplace || + aQueryParam.nDestCol != rSortParam.nDestCol || + aQueryParam.nDestRow != rSortParam.nDestRow || + aQueryParam.nDestTab != rSortParam.nDestTab ) // Query auf selben Zielbereich? + bRepeatQuery = FALSE; + } + + if ( bRecord ) + { + // Referenzen ausserhalb des Bereichs werden nicht veraendert ! + + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + // Zeilenhoehen immer (wegen automatischer Anpassung) + //! auf ScBlockUndo umstellen + pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, TRUE ); + pDoc->CopyToDocument( aLocalParam.nCol1, aLocalParam.nRow1, nTab, + aLocalParam.nCol2, aLocalParam.nRow2, nTab, + IDF_ALL, FALSE, pUndoDoc ); + + const ScRange* pR = 0; + if (pDestData) + { + pDoc->CopyToDocument( aOldDest, IDF_ALL, FALSE, pUndoDoc ); + pR = &aOldDest; + } + + // Zeilenhoehen immer (wegen automatischer Anpassung) + //! auf ScBlockUndo umstellen +// if (bRepeatQuery) + pDoc->CopyToDocument( 0, aLocalParam.nRow1, nTab, MAXCOL, aLocalParam.nRow2, nTab, + IDF_NONE, FALSE, pUndoDoc ); + + ScDBCollection* pUndoDB = NULL; + ScDBCollection* pDocDB = pDoc->GetDBCollection(); + if (pDocDB->GetCount()) + pUndoDB = new ScDBCollection( *pDocDB ); + + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoSort( &rDocShell, nTab, + rSortParam, bRepeatQuery, pUndoDoc, pUndoDB, pR ) ); + } + + if ( bCopy ) + { + if (pDestData) + pDoc->DeleteAreaTab(aOldDest, IDF_CONTENTS); // Zielbereich vorher loeschen + + ScRange aSource( rSortParam.nCol1,rSortParam.nRow1,nSrcTab, + rSortParam.nCol2,rSortParam.nRow2,nSrcTab ); + ScAddress aDest( rSortParam.nDestCol, rSortParam.nDestRow, rSortParam.nDestTab ); + + rDocShell.GetDocFunc().MoveBlock( aSource, aDest, FALSE, FALSE, FALSE, TRUE ); + } + pDoc->Sort( nTab, aLocalParam, bRepeatQuery ); + + BOOL bSave = TRUE; + if (bCopy) + { + ScSortParam aOldSortParam; + pDBData->GetSortParam( aOldSortParam ); + if ( aOldSortParam.bDoSort[0] && aOldSortParam.bInplace ) // Inplace-Sortierung gemerkt? + { + bSave = FALSE; + aOldSortParam.nDestCol = rSortParam.nDestCol; + aOldSortParam.nDestRow = rSortParam.nDestRow; + aOldSortParam.nDestTab = rSortParam.nDestTab; + pDBData->SetSortParam( aOldSortParam ); // dann nur DestPos merken + } + } + if (bSave) // Parameter merken + { + pDBData->SetSortParam( rSortParam ); + pDBData->SetHeader( rSortParam.bHasHeader ); //! ??? + pDBData->SetByRow( rSortParam.bByRow ); //! ??? + } + + if (bCopy) // neuen DB-Bereich merken + { + // Tabelle umschalten von aussen (View) + //! SetCursor ??!?! + + ScRange aDestPos( aLocalParam.nCol1, aLocalParam.nRow1, nTab, + aLocalParam.nCol2, aLocalParam.nRow2, nTab ); + ScDBData* pNewData; + if (pDestData) + pNewData = pDestData; // Bereich vorhanden -> anpassen + else // Bereich ab Cursor/Markierung wird angelegt + pNewData = rDocShell.GetDBData(aDestPos, SC_DB_MAKE, TRUE ); + if (pNewData) + { + pNewData->SetArea( nTab, + aLocalParam.nCol1,aLocalParam.nRow1, + aLocalParam.nCol2,aLocalParam.nRow2 ); + pNewData->SetSortParam( aLocalParam ); + pNewData->SetHeader( aLocalParam.bHasHeader ); //! ??? + pNewData->SetByRow( aLocalParam.bByRow ); + } + else + DBG_ERROR("Zielbereich nicht da"); + } + + ScRange aDirtyRange( aLocalParam.nCol1, aLocalParam.nRow1, nTab, + aLocalParam.nCol2, aLocalParam.nRow2, nTab ); + pDoc->SetDirty( aDirtyRange ); + + if (bPaint) + { + USHORT nPaint = PAINT_GRID; + USHORT nStartX = aLocalParam.nCol1; + USHORT nStartY = aLocalParam.nRow1; + USHORT nEndX = aLocalParam.nCol2; + USHORT nEndY = aLocalParam.nRow2; + if ( bRepeatQuery ) + { + nPaint |= PAINT_LEFT; + nStartX = 0; + nEndX = MAXCOL; + } + if (pDestData) + { + if ( nEndX < aOldDest.aEnd.Col() ) + nEndX = aOldDest.aEnd.Col(); + if ( nEndY < aOldDest.aEnd.Row() ) + nEndY = aOldDest.aEnd.Row(); + } + rDocShell.PostPaint( nStartX, nStartY, nTab, nEndX, nEndY, nTab, nPaint ); + } + +// AdjustRowHeight( aLocalParam.nRow1, aLocalParam.nRow2, bPaint ); + rDocShell.AdjustRowHeight( aLocalParam.nRow1, aLocalParam.nRow2, nTab ); + + aModificator.SetDocumentModified(); + + return TRUE; +} + +// ----------------------------------------------------------------- + +BOOL ScDBDocFunc::Query( USHORT nTab, const ScQueryParam& rQueryParam, + const ScRange* pAdvSource, BOOL bRecord, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + ScDocument* pDoc = rDocShell.GetDocument(); + ScDBData* pDBData = pDoc->GetDBAtArea( nTab, rQueryParam.nCol1, rQueryParam.nRow1, + rQueryParam.nCol2, rQueryParam.nRow2 ); + if (!pDBData) + { + DBG_ERROR( "Query: keine DBData" ); + return FALSE; + } + + // Wechsel von Inplace auf nicht-Inplace, dann erst Inplace aufheben: + // (nur, wenn im Dialog "Persistent" ausgewaehlt ist) + + if ( !rQueryParam.bInplace && pDBData->HasQueryParam() && rQueryParam.bDestPers ) + { + ScQueryParam aOldQuery; + pDBData->GetQueryParam(aOldQuery); + if (aOldQuery.bInplace) + { + // alte Filterung aufheben + + USHORT nEC = aOldQuery.GetEntryCount(); + for (USHORT i=0; i<nEC; i++) + aOldQuery.GetEntry(i).bDoQuery = FALSE; + aOldQuery.bDuplicate = TRUE; + Query( nTab, aOldQuery, NULL, bRecord, bApi ); + } + } + + ScQueryParam aLocalParam( rQueryParam ); // fuer Paint / Zielbereich + BOOL bCopy = !rQueryParam.bInplace; // kopiert wird in Table::Query + ScDBData* pDestData = NULL; // Bereich, in den kopiert wird + BOOL bDoSize = FALSE; // Zielgroesse anpassen (einf./loeschen) + USHORT nFormulaCols = 0; // nur bei bDoSize + BOOL bKeepFmt = FALSE; + ScRange aOldDest; + ScRange aDestTotal; + if ( bCopy && rQueryParam.nDestCol == rQueryParam.nCol1 && + rQueryParam.nDestRow == rQueryParam.nRow1 && rQueryParam.nDestTab == nTab ) + bCopy = FALSE; + USHORT nDestTab = nTab; + if ( bCopy ) + { + aLocalParam.MoveToDest(); + nDestTab = rQueryParam.nDestTab; + + if (!pDoc->IsBlockEditable(nDestTab, aLocalParam.nCol1,aLocalParam.nRow1, + aLocalParam.nCol2,aLocalParam.nRow2)) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + return FALSE; + } + + pDestData = pDoc->GetDBAtCursor( rQueryParam.nDestCol, rQueryParam.nDestRow, + rQueryParam.nDestTab, TRUE ); + if (pDestData) + { + pDestData->GetArea( aOldDest ); + aDestTotal=ScRange( rQueryParam.nDestCol, + rQueryParam.nDestRow, + nDestTab, + rQueryParam.nDestCol + rQueryParam.nCol2 - rQueryParam.nCol1, + rQueryParam.nDestRow + rQueryParam.nRow2 - rQueryParam.nRow1, + nDestTab ); + + bDoSize = pDestData->IsDoSize(); + // Test, ob Formeln aufgefuellt werden muessen (nFormulaCols): + if ( bDoSize && aOldDest.aEnd.Col() == aDestTotal.aEnd.Col() ) + { + USHORT nTestCol = aOldDest.aEnd.Col() + 1; // neben dem Bereich + USHORT nTestRow = rQueryParam.nDestRow + + ( aLocalParam.bHasHeader ? 1 : 0 ); + while ( nTestCol <= MAXCOL && + pDoc->GetCellType(ScAddress( nTestCol, nTestRow, nTab )) == CELLTYPE_FORMULA ) + ++nTestCol, ++nFormulaCols; + } + + bKeepFmt = pDestData->IsKeepFmt(); + if ( bDoSize && !pDoc->CanFitBlock( aOldDest, aDestTotal ) ) + { + if (!bApi) + rDocShell.ErrorMessage(STR_MSSG_DOSUBTOTALS_2); // kann keine Zeilen einfuegen + return FALSE; + } + } + } + + // ausfuehren + + WaitObject aWait( rDocShell.GetDialogParent() ); + + BOOL bKeepSub = FALSE; // bestehende Teilergebnisse wiederholen? + ScSubTotalParam aSubTotalParam; + if (rQueryParam.GetEntry(0).bDoQuery) // nicht beim Aufheben + { + pDBData->GetSubTotalParam( aSubTotalParam ); // Teilergebnisse vorhanden? + + if ( aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly ) + bKeepSub = TRUE; + } + + if ( bRecord ) + { + const ScRange* pOld = 0; + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + if (bCopy) + { + pUndoDoc->InitUndo( pDoc, nDestTab, nDestTab, FALSE, TRUE ); + pDoc->CopyToDocument( aLocalParam.nCol1, aLocalParam.nRow1, nDestTab, + aLocalParam.nCol2, aLocalParam.nRow2, nDestTab, + IDF_ALL, FALSE, pUndoDoc ); + // Attribute sichern, falls beim Filtern mitkopiert + + if (pDestData) + { + pDoc->CopyToDocument( aOldDest, IDF_ALL, FALSE, pUndoDoc ); + pOld = &aOldDest; + } + } + else + { + pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, TRUE ); + pDoc->CopyToDocument( 0, rQueryParam.nRow1, nTab, MAXCOL, rQueryParam.nRow2, nTab, + IDF_NONE, FALSE, pUndoDoc ); + } + + ScDBCollection* pUndoDB = NULL; + ScDBCollection* pDocDB = pDoc->GetDBCollection(); + if (pDocDB->GetCount()) + pUndoDB = new ScDBCollection( *pDocDB ); + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoQuery( &rDocShell, nTab, rQueryParam, pUndoDoc, pUndoDB, + pOld, bDoSize, pAdvSource ) ); + } + + ScDocument* pAttribDoc = NULL; + ScRange aAttribRange; + if (pDestData) // Zielbereich loeschen + { + if ( bKeepFmt ) + { + // kleinere der End-Spalten, Header+1 Zeile + aAttribRange = aOldDest; + if ( aAttribRange.aEnd.Col() > aDestTotal.aEnd.Col() ) + aAttribRange.aEnd.SetCol( aDestTotal.aEnd.Col() ); + aAttribRange.aEnd.SetRow( aAttribRange.aStart.Row() + + ( aLocalParam.bHasHeader ? 1 : 0 ) ); + + // auch fuer aufgefuellte Formeln + aAttribRange.aEnd.SetCol( aAttribRange.aEnd.Col() + nFormulaCols ); + + pAttribDoc = new ScDocument( SCDOCMODE_UNDO ); + pAttribDoc->InitUndo( pDoc, nDestTab, nDestTab, FALSE, TRUE ); + pDoc->CopyToDocument( aAttribRange, IDF_ATTRIB, FALSE, pAttribDoc ); + } + + if ( bDoSize ) + pDoc->FitBlock( aOldDest, aDestTotal ); + else + pDoc->DeleteAreaTab(aOldDest, IDF_ALL); // einfach loeschen + } + + // Filtern am Dokument ausfuehren + USHORT nCount = pDoc->Query( nTab, rQueryParam, bKeepSub ); + if (bCopy) + { + aLocalParam.nRow2 = aLocalParam.nRow1 + nCount; + if (!aLocalParam.bHasHeader && nCount) + --aLocalParam.nRow2; + + if ( bDoSize ) + { + // auf wirklichen Ergebnis-Bereich anpassen + // (das hier ist immer eine Verkleinerung) + + ScRange aNewDest( aLocalParam.nCol1, aLocalParam.nRow1, nDestTab, + aLocalParam.nCol2, aLocalParam.nRow2, nDestTab ); + pDoc->FitBlock( aDestTotal, aNewDest, FALSE ); // FALSE - nicht loeschen + + if ( nFormulaCols ) + { + // Formeln ausfuellen + //! Undo (Query und Repeat) !!! + + ScRange aNewForm( aLocalParam.nCol2+1, aLocalParam.nRow1, nDestTab, + aLocalParam.nCol2+nFormulaCols, aLocalParam.nRow2, nDestTab ); + ScRange aOldForm = aNewForm; + aOldForm.aEnd.SetRow( aOldDest.aEnd.Row() ); + pDoc->FitBlock( aOldForm, aNewForm, FALSE ); + + ScMarkData aMark; + aMark.SelectOneTable(nDestTab); + USHORT nFStartY = aLocalParam.nRow1 + ( aLocalParam.bHasHeader ? 1 : 0 ); + pDoc->Fill( aLocalParam.nCol2+1, nFStartY, + aLocalParam.nCol2+nFormulaCols, nFStartY, aMark, + aLocalParam.nRow2 - nFStartY, + FILL_TO_BOTTOM, FILL_SIMPLE ); + } + } + + if ( pAttribDoc ) // gemerkte Attribute zurueckkopieren + { + // Header + if (aLocalParam.bHasHeader) + { + ScRange aHdrRange = aAttribRange; + aHdrRange.aEnd.SetRow( aHdrRange.aStart.Row() ); + pAttribDoc->CopyToDocument( aHdrRange, IDF_ATTRIB, FALSE, pDoc ); + } + + // Daten + USHORT nAttrEndCol = aAttribRange.aEnd.Col(); + USHORT nAttrRow = aAttribRange.aStart.Row() + ( aLocalParam.bHasHeader ? 1 : 0 ); + for (USHORT nCol = aAttribRange.aStart.Col(); nCol<=nAttrEndCol; nCol++) + { + const ScPatternAttr* pSrcPattern = pAttribDoc->GetPattern( + nCol, nAttrRow, nDestTab ); + DBG_ASSERT(pSrcPattern,"Pattern ist 0"); + if (pSrcPattern) + pDoc->ApplyPatternAreaTab( nCol, nAttrRow, nCol, aLocalParam.nRow2, + nDestTab, *pSrcPattern ); + const ScStyleSheet* pStyle = pSrcPattern->GetStyleSheet(); + if (pStyle) + pDoc->ApplyStyleAreaTab( nCol, nAttrRow, nCol, aLocalParam.nRow2, + nDestTab, *pStyle ); + } + + delete pAttribDoc; + } + } + + // speichern: Inplace immer, sonst je nach Einstellung + // alter Inplace-Filter ist ggf. schon aufgehoben + + BOOL bSave = rQueryParam.bInplace || rQueryParam.bDestPers; + if (bSave) // merken + { + pDBData->SetQueryParam( rQueryParam ); + pDBData->SetHeader( rQueryParam.bHasHeader ); //! ??? + pDBData->SetAdvancedQuerySource( pAdvSource ); // after SetQueryParam + } + + if (bCopy) // neuen DB-Bereich merken + { + // selektieren wird hinterher von aussen (dbfunc) + // momentan ueber DB-Bereich an der Zielposition, darum muss dort + // auf jeden Fall ein Bereich angelegt werden. + + ScDBData* pNewData; + if (pDestData) + pNewData = pDestData; // Bereich vorhanden -> anpassen (immer!) + else // Bereich anlegen + pNewData = rDocShell.GetDBData( + ScRange( aLocalParam.nCol1, aLocalParam.nRow1, nDestTab, + aLocalParam.nCol2, aLocalParam.nRow2, nDestTab ), + SC_DB_MAKE, TRUE ); + + if (pNewData) + { + pNewData->SetArea( nDestTab, aLocalParam.nCol1, aLocalParam.nRow1, + aLocalParam.nCol2, aLocalParam.nRow2 ); + + // Query-Param wird am Ziel nicht mehr eingestellt, fuehrt nur zu Verwirrung + // und Verwechslung mit dem Query-Param am Quellbereich (#37187#) + } + else + DBG_ERROR("Zielbereich nicht da"); + } + + if (!bCopy) + pDoc->UpdatePageBreaks( nTab ); + + ScRange aDirtyRange( aLocalParam.nCol1, aLocalParam.nRow1, nDestTab, + aLocalParam.nCol2, aLocalParam.nRow2, nDestTab ); + pDoc->SetDirty( aDirtyRange ); + + if (bCopy) + { + USHORT nEndX = aLocalParam.nCol2; + USHORT nEndY = aLocalParam.nRow2; + if (pDestData) + { + if ( aOldDest.aEnd.Col() > nEndX ) + nEndX = aOldDest.aEnd.Col(); + if ( aOldDest.aEnd.Row() > nEndY ) + nEndY = aOldDest.aEnd.Row(); + } + if (bDoSize) + nEndY = MAXROW; + rDocShell.PostPaint( aLocalParam.nCol1, aLocalParam.nRow1, nDestTab, + nEndX, nEndY, nDestTab, PAINT_GRID ); + } + else + rDocShell.PostPaint( 0, rQueryParam.nRow1, nTab, MAXCOL, MAXROW, nTab, + PAINT_GRID | PAINT_LEFT ); + aModificator.SetDocumentModified(); + + return TRUE; +} + +// ----------------------------------------------------------------- + +BOOL ScDBDocFunc::DoSubTotals( USHORT nTab, const ScSubTotalParam& rParam, + const ScSortParam* pForceNewSort, BOOL bRecord, BOOL bApi ) +{ + //! auch fuer ScDBFunc::DoSubTotals benutzen! + // dann bleibt aussen: + // - neuen Bereich (aus DBData) markieren + // - SelectionChanged (?) + + BOOL bDo = !rParam.bRemoveOnly; // FALSE = nur loeschen + BOOL bRet = FALSE; + + ScDocument* pDoc = rDocShell.GetDocument(); + ScDBData* pDBData = pDoc->GetDBAtArea( nTab, rParam.nCol1, rParam.nRow1, + rParam.nCol2, rParam.nRow2 ); + if (!pDBData) + { + DBG_ERROR( "SubTotals: keine DBData" ); + return FALSE; + } + + if (!pDoc->IsBlockEditable( nTab, 0,rParam.nRow1+1, MAXCOL,MAXROW )) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + return FALSE; + } + + if (pDoc->HasAttrib( rParam.nCol1, rParam.nRow1+1, nTab, + rParam.nCol2, rParam.nRow2, nTab, HASATTR_MERGED | HASATTR_OVERLAPPED )) + { + if (!bApi) + rDocShell.ErrorMessage(STR_MSSG_INSERTCELLS_0); // nicht in zusammengefasste einfuegen + return FALSE; + } + + BOOL bOk = TRUE; + BOOL bDelete = FALSE; + if (rParam.bReplace) + if (pDoc->TestRemoveSubTotals( nTab, rParam )) + { + bDelete = TRUE; + bOk = ( MessBox( rDocShell.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) + { + WaitObject aWait( rDocShell.GetDialogParent() ); + ScDocShellModificator aModificator( rDocShell ); + + ScSubTotalParam aNewParam( rParam ); // Bereichsende wird veraendert + ScDocument* pUndoDoc = NULL; + ScOutlineTable* pUndoTab = NULL; + ScRangeName* pUndoRange = NULL; + ScDBCollection* pUndoDB = NULL; + USHORT nTabCount = 0; // fuer Referenz-Undo + + if (bRecord) // alte Daten sichern + { + BOOL bOldFilter = bDo && rParam.bDoSort; + + nTabCount = pDoc->GetTableCount(); + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab ); + if (pTable) + { + pUndoTab = new ScOutlineTable( *pTable ); + + USHORT nOutStartCol; // Zeilen/Spaltenstatus + USHORT nOutStartRow; + USHORT nOutEndCol; + USHORT nOutEndRow; + pTable->GetColArray()->GetRange( nOutStartCol, nOutEndCol ); + pTable->GetRowArray()->GetRange( nOutStartRow, nOutEndRow ); + + pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE ); + pDoc->CopyToDocument( nOutStartCol, 0, nTab, nOutEndCol, MAXROW, nTab, IDF_NONE, FALSE, pUndoDoc ); + pDoc->CopyToDocument( 0, nOutStartRow, nTab, MAXCOL, nOutEndRow, nTab, IDF_NONE, FALSE, pUndoDoc ); + } + else + pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, bOldFilter ); + + // Datenbereich sichern - incl. Filter-Ergebnis + pDoc->CopyToDocument( 0,rParam.nRow1+1,nTab, MAXCOL,rParam.nRow2,nTab, + IDF_ALL, FALSE, pUndoDoc ); + + // alle Formeln wegen Referenzen + pDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTabCount-1, + IDF_FORMULA, 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 ); + BOOL bSuccess = 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( nTab, aSortParam, FALSE, FALSE, bApi ); + } + + 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; + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoSubTotals( &rDocShell, nTab, + rParam, aNewParam.nRow2, + pUndoDoc, pUndoTab, // pUndoDBData, + pUndoRange, pUndoDB ) ); + } + + if (!bSuccess) + { + // "Kann keine Zeilen einfuegen" + if (!bApi) + rDocShell.ErrorMessage(STR_MSSG_DOSUBTOTALS_2); + } + + // merken + pDBData->SetSubTotalParam( aNewParam ); + pDBData->SetArea( nTab, aNewParam.nCol1,aNewParam.nRow1, aNewParam.nCol2,aNewParam.nRow2 ); + pDoc->CompileDBFormula(); + + rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, + PAINT_GRID | PAINT_LEFT | PAINT_TOP | PAINT_SIZE ); + aModificator.SetDocumentModified(); + + bRet = bSuccess; + } + return bRet; +} + +//================================================================== + +BOOL lcl_BlockEditable( ScDocument* pDoc, const ScRange& rRange ) +{ + return pDoc->IsBlockEditable( rRange.aStart.Tab(), + rRange.aStart.Col(), rRange.aStart.Row(), + rRange.aEnd.Col(), rRange.aEnd.Row() ); +} + +BOOL ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewObj, + BOOL bRecord, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + WaitObject aWait( rDocShell.GetDialogParent() ); + + BOOL bDone = FALSE; + BOOL bUndoSelf = FALSE; + USHORT nErrId = 0; + + ScDocument* pOldUndoDoc = NULL; + ScDocument* pNewUndoDoc = NULL; + ScDPObject* pUndoDPObj = NULL; + if ( bRecord && pOldObj ) + pUndoDPObj = new ScDPObject( *pOldObj ); // copy old settings for undo + + ScDocument* pDoc = rDocShell.GetDocument(); + if ( rDocShell.IsReadOnly() || pDoc->GetChangeTrack() ) + { + // not recorded -> disallow + //! different error messages? + + nErrId = STR_PROTECTIONERR; + } + if ( pOldObj && !nErrId ) + { + ScRange aOldOut = pOldObj->GetOutRange(); + if ( !lcl_BlockEditable( pDoc, aOldOut ) ) + nErrId = STR_PROTECTIONERR; + } + if ( pNewObj && !nErrId ) + { + // at least one cell at the output position must be editable + // -> check in advance + // (start of output range in pNewObj is valid) + + ScRange aNewStart( pNewObj->GetOutRange().aStart ); + if ( !lcl_BlockEditable( pDoc, aNewStart ) ) + nErrId = STR_PROTECTIONERR; + } + + ScDPObject* pDestObj = NULL; + if ( !nErrId ) + { + if ( pOldObj && !pNewObj ) + { + // delete table + + ScRange aRange = pOldObj->GetOutRange(); + USHORT nTab = aRange.aStart.Tab(); + + if ( bRecord ) + { + pOldUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pOldUndoDoc->InitUndo( pDoc, nTab, nTab ); + pDoc->CopyToDocument( aRange, IDF_ALL, FALSE, pOldUndoDoc ); + } + + pDoc->DeleteAreaTab( aRange.aStart.Col(), aRange.aStart.Row(), + aRange.aEnd.Col(), aRange.aEnd.Row(), + nTab, IDF_ALL ); + + pDoc->GetDPCollection()->Free( pOldObj ); // object is deleted here + + rDocShell.PostPaintGridAll(); //! only necessary parts + rDocShell.PostPaint( aRange.aStart.Col(), aRange.aStart.Row(), nTab, + aRange.aEnd.Col(), aRange.aEnd.Row(), nTab, + PAINT_GRID ); + bDone = TRUE; + } + else if ( pNewObj ) + { + if ( pOldObj ) + { + if ( bRecord ) + { + ScRange aRange = pOldObj->GetOutRange(); + USHORT nTab = aRange.aStart.Tab(); + pOldUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pOldUndoDoc->InitUndo( pDoc, nTab, nTab ); + pDoc->CopyToDocument( aRange, IDF_ALL, FALSE, pOldUndoDoc ); + } + + if ( pNewObj == pOldObj ) + { + // refresh only - no settings modified + } + else + { + pNewObj->WriteSourceDataTo( *pOldObj ); // copy source data + + ScDPSaveData* pData = pNewObj->GetSaveData(); + DBG_ASSERT( pData, "no SaveData from living DPObject" ); + if ( pData ) + pOldObj->SetSaveData( *pData ); // copy SaveData + } + + pDestObj = pOldObj; + } + else + { + // output range must be set at pNewObj + + pDestObj = new ScDPObject( *pNewObj ); + pDestObj->SetAlive(TRUE); + if ( !pDoc->GetDPCollection()->Insert(pDestObj) ) + { + DBG_ERROR("cannot insert DPObject"); + DELETEZ( pDestObj ); + } + } + if ( pDestObj ) + { + pDestObj->InvalidateData(); // before getting the new output area + + // make sure the table has a name (not set by dialog) + if ( !pDestObj->GetName().Len() ) + pDestObj->SetName( pDoc->GetDPCollection()->CreateNewName() ); + + ScRange aNewOut = pDestObj->GetNewOutputRange(); + if ( !lcl_BlockEditable( pDoc, aNewOut ) ) + { + // destination area isn't editable + //! reverse everything done so far, don't proceed + + // quick solution: proceed to end, use undo action + // to reverse everything: + DBG_ASSERT( bRecord, "DataPilotUpdate: can't undo" ); + bUndoSelf = TRUE; + nErrId = STR_PROTECTIONERR; + } + + if ( bRecord ) + { + USHORT nTab = aNewOut.aStart.Tab(); + pNewUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pNewUndoDoc->InitUndo( pDoc, nTab, nTab ); + pDoc->CopyToDocument( aNewOut, IDF_ALL, FALSE, pNewUndoDoc ); + } + + //! test for overlap with other data pilot tables + + //! test if output area is empty and query before overwriting + + pDestObj->Output(); + + rDocShell.PostPaintGridAll(); //! only necessary parts + bDone = TRUE; + } + } + // else nothing (no old, no new) + } + + if ( bRecord && bDone ) + { + SfxUndoAction* pAction = new ScUndoDataPilot( &rDocShell, + pOldUndoDoc, pNewUndoDoc, pUndoDPObj, pDestObj ); + pOldUndoDoc = NULL; + pNewUndoDoc = NULL; // pointers are used in undo action + // pUndoDPObj is copied + + if (bUndoSelf) + { + // use undo action to restore original state + //! prevent setting the document modified? (ScDocShellModificator) + + pAction->Undo(); + delete pAction; + bDone = FALSE; + } + else + rDocShell.GetUndoManager()->AddUndoAction( pAction ); + } + + delete pOldUndoDoc; // if not used for undo + delete pNewUndoDoc; + delete pUndoDPObj; + + if (bDone) + aModificator.SetDocumentModified(); + + if ( nErrId && !bApi ) + rDocShell.ErrorMessage( nErrId ); + + return bDone; +} + +//================================================================== +// +// Datenbank-Import... + +void ScDBDocFunc::UpdateImport( const String& rTarget, const String& rDBName, + const String& rTableName, const String& rStatement, + BOOL bNative, BYTE nType, + const SbaSelectionList* pSelection ) +{ + // Target ist jetzt einfach der Bereichsname + + ScDocument* pDoc = rDocShell.GetDocument(); + ScDBCollection& rDBColl = *pDoc->GetDBCollection(); + ScDBData* pData; + ScImportParam aImportParam; + BOOL bFound = FALSE; + USHORT nCount = rDBColl.GetCount(); + for (USHORT i=0; i<nCount && !bFound; i++) + { + pData = rDBColl[i]; + if (pData->GetName() == rTarget) + bFound = TRUE; + } + if (!bFound) + { + InfoBox aInfoBox(rDocShell.GetDialogParent(), + ScGlobal::GetRscString( STR_TARGETNOTFOUND ) ); + aInfoBox.Execute(); + return; + } + + USHORT nTab; + USHORT nDummy; + pData->GetArea( nTab, nDummy,nDummy,nDummy,nDummy ); + pData->GetImportParam( aImportParam ); + + BOOL bSql = ( rStatement.Len() != 0 ); + + aImportParam.aDBName = rDBName; + aImportParam.bSql = bSql; + aImportParam.aStatement = bSql ? rStatement : rTableName; + aImportParam.bNative = bNative; + aImportParam.nType = nType; + aImportParam.bImport = TRUE; + BOOL bContinue = DoImport( nTab, aImportParam, pSelection, TRUE ); + + // DB-Operationen wiederholen + + ScTabViewShell* pViewSh = rDocShell.GetBestViewShell(); + if (pViewSh) + { + ScRange aRange; + pData->GetArea(aRange); + pViewSh->MarkRange(aRange); // selektieren + + if ( bContinue ) // #41905# Fehler beim Import -> Abbruch + { + // interne Operationen, wenn welche gespeichert + + if ( pData->HasQueryParam() || pData->HasSortParam() || pData->HasSubTotalParam() ) + pViewSh->RepeatDB(); + + // Pivottabellen die den Bereich als Quelldaten haben + + rDocShell.RefreshPivotTables(aRange); + } + } +} + + + + diff --git a/sc/source/ui/docshell/dbdocimp.cxx b/sc/source/ui/docshell/dbdocimp.cxx new file mode 100644 index 000000000000..ae6ea5ec48f1 --- /dev/null +++ b/sc/source/ui/docshell/dbdocimp.cxx @@ -0,0 +1,716 @@ +/************************************************************************* + * + * $RCSfile: dbdocimp.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#pragma hdrstop + +// INCLUDE --------------------------------------------------------- + +#include <unotools/processfactory.hxx> +#include <vcl/msgbox.hxx> +#include <sdb/sdbstat.hxx> // DBObject enum values +#include <tools/debug.hxx> +#include <svtools/zforlist.hxx> +#include <offmgr/sbaitems.hxx> // SbaSelectionList + +#include <com/sun/star/sdb/CommandType.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XRowSet.hpp> +#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp> +#include <com/sun/star/sdbc/DataType.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +#include "dbdocfun.hxx" +#include "docsh.hxx" +#include "globstr.hrc" +#include "scerrors.hxx" +#include "cell.hxx" +#include "compiler.hxx" +#include "dbcolect.hxx" +#include "markdata.hxx" +#include "undodat.hxx" +#include "progress.hxx" +#include "patattr.hxx" +#include "docpool.hxx" +#include "attrib.hxx" + +using namespace com::sun::star; + +#define SC_SERVICE_ROWSET "com.sun.star.sdb.RowSet" + +//! move to a header file? +#define SC_DBPROP_DATASOURCENAME "DataSourceName" +#define SC_DBPROP_COMMAND "Command" +#define SC_DBPROP_COMMANDTYPE "CommandType" + +#define D_TIMEFACTOR 86400.0 + +// ----------------------------------------------------------------- + +void lcl_PutData( ScDocument* pDoc, USHORT nCol, USHORT nRow, USHORT nTab, + const uno::Reference<sdbc::XRow>& xRow, long nRowPos, + long nType, BOOL bCurrency ) +{ + String aString; + double nVal = 0.0; + BOOL bValue = FALSE; + BOOL bEmptyFlag = FALSE; + BOOL bError = FALSE; + ULONG nFormatIndex = 0; + + //! wasNull calls only if null value was found? + + try + { + switch ( nType ) + { + case sdbc::DataType::BIT: + //! use language from doc (here, date/time and currency)? + nFormatIndex = pDoc->GetFormatTable()->GetStandardFormat( + NUMBERFORMAT_LOGICAL, ScGlobal::eLnge ); + nVal = (xRow->getBoolean(nRowPos) ? 1 : 0); + bEmptyFlag = ( nVal == 0.0 ) && xRow->wasNull(); + bValue = TRUE; + break; + + case sdbc::DataType::TINYINT: + case sdbc::DataType::SMALLINT: + case sdbc::DataType::INTEGER: + case sdbc::DataType::BIGINT: + case sdbc::DataType::FLOAT: + case sdbc::DataType::REAL: + case sdbc::DataType::DOUBLE: + case sdbc::DataType::NUMERIC: + case sdbc::DataType::DECIMAL: + //! do the conversion here? + nVal = xRow->getDouble(nRowPos); + bEmptyFlag = ( nVal == 0.0 ) && xRow->wasNull(); + bValue = TRUE; + break; + + case sdbc::DataType::CHAR: + case sdbc::DataType::VARCHAR: + case sdbc::DataType::LONGVARCHAR: + aString = xRow->getString(nRowPos); + bEmptyFlag = ( aString.Len() == 0 ) && xRow->wasNull(); + break; + + case sdbc::DataType::DATE: + { + SvNumberFormatter* pFormTable = pDoc->GetFormatTable(); + nFormatIndex = pFormTable->GetStandardFormat( + NUMBERFORMAT_DATE, ScGlobal::eLnge ); + + util::Date aDate = xRow->getDate(nRowPos); + nVal = Date( aDate.Day, aDate.Month, aDate.Year ) - + *pFormTable->GetNullDate(); + bEmptyFlag = xRow->wasNull(); + bValue = TRUE; + } + break; + + case sdbc::DataType::TIME: + { + SvNumberFormatter* pFormTable = pDoc->GetFormatTable(); + nFormatIndex = pFormTable->GetStandardFormat( + NUMBERFORMAT_TIME, ScGlobal::eLnge ); + + util::Time aTime = xRow->getTime(nRowPos); + nVal = ( aTime.Hours * 3600 + aTime.Minutes * 60 + + aTime.Seconds + aTime.HundredthSeconds / 100.0 ) / D_TIMEFACTOR; + bEmptyFlag = xRow->wasNull(); + bValue = TRUE; + } + break; + + case sdbc::DataType::TIMESTAMP: + { + SvNumberFormatter* pFormTable = pDoc->GetFormatTable(); + nFormatIndex = pFormTable->GetStandardFormat( + NUMBERFORMAT_DATETIME, ScGlobal::eLnge ); + + util::DateTime aStamp = xRow->getTimestamp(nRowPos); + nVal = ( Date( aStamp.Day, aStamp.Month, aStamp.Year ) - + *pFormTable->GetNullDate() ) + + ( aStamp.Hours * 3600 + aStamp.Minutes * 60 + + aStamp.Seconds + aStamp.HundredthSeconds / 100.0 ) / D_TIMEFACTOR; + bEmptyFlag = xRow->wasNull(); + bValue = TRUE; + } + break; + + case sdbc::DataType::SQLNULL: + bEmptyFlag = TRUE; + break; + + case sdbc::DataType::BINARY: + case sdbc::DataType::VARBINARY: + case sdbc::DataType::LONGVARBINARY: + default: + bError = TRUE; // unknown type + } + } + catch ( uno::Exception& ) + { + bError = TRUE; + } + + if ( bValue && bCurrency ) + nFormatIndex = pDoc->GetFormatTable()->GetStandardFormat( + NUMBERFORMAT_CURRENCY, ScGlobal::eLnge ); + + ScBaseCell* pCell; + if (bEmptyFlag) + { + pCell = NULL; + pDoc->PutCell( nCol, nRow, nTab, pCell ); + } + else if (bError) + { + pDoc->SetError( nCol, nRow, nTab, NOVALUE ); + } + else if (bValue) + { + pCell = new ScValueCell( nVal ); + if (nFormatIndex == 0) + pDoc->PutCell( nCol, nRow, nTab, pCell ); + else + pDoc->PutCell( nCol, nRow, nTab, pCell, nFormatIndex ); + } + else + { + pCell = ScBaseCell::CreateTextCell( aString, pDoc ); +// if ( pSimpleFlag && pCell->GetCellType() == CELLTYPE_EDIT ) +// *pSimpleFlag = FALSE; + pDoc->PutCell( nCol, nRow, nTab, pCell ); + } +} + +// ----------------------------------------------------------------- + +BOOL ScDBDocFunc::DoImport( USHORT nTab, const ScImportParam& rParam, + const SbaSelectionList* pSelection, + BOOL bRecord, BOOL bAddrInsert ) +{ + ScDocument* pDoc = rDocShell.GetDocument(); + ScDBData* pDBData = 0; + if ( !bAddrInsert ) + { + pDBData = pDoc->GetDBAtArea( nTab, rParam.nCol1, rParam.nRow1, + rParam.nCol2, rParam.nRow2 ); + if (!pDBData) + { + DBG_ERROR( "DoImport: no DBData" ); + return FALSE; + } + } + + Window* pWaitWin = rDocShell.GetDialogParent(); + if (pWaitWin) + pWaitWin->EnterWait(); + ScDocShellModificator aModificator( rDocShell ); + + BOOL bSuccess = FALSE; + BOOL bApi = FALSE; //! pass as argument + BOOL bTruncated = FALSE; // for warning + USHORT nErrStringId = 0; + String aErrorMessage; + + USHORT nCol = rParam.nCol1; + USHORT nRow = rParam.nRow1; + USHORT nEndCol = nCol; // end of resulting database area + USHORT nEndRow = nRow; + long i; + + BOOL bDoSelection = FALSE; + BOOL bRealSelection = FALSE; // TRUE if not everything is selected + ULONG nListPos = 0; + ULONG nRowsRead = 0; + ULONG nListCount = 0; + + // -1 is special + if ( pSelection && pSelection->Count() && (long)pSelection->GetObject(0) != -1L ) + { + bDoSelection = TRUE; + nListCount = pSelection->Count(); + } + + // ImportDoc - also used for Redo + ScDocument* pImportDoc = new ScDocument( SCDOCMODE_UNDO ); + pImportDoc->InitUndo( pDoc, nTab, nTab ); + ScColumn::bDoubleAlloc = TRUE; + + // + // get data from database into import document + // + + try + { + // progress bar + // only text (title is still needed, for the cancel button) + ScProgress aProgress( &rDocShell, ScGlobal::GetRscString(STR_UNDO_IMPORTDATA), 0 ); + USHORT nInserted = 0; + + uno::Reference<sdbc::XRowSet> xRowSet( + utl::getProcessServiceFactory()->createInstance( + rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ), + uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY ); + DBG_ASSERT( xRowProp.is(), "can't get RowSet" ); + if ( xRowProp.is() ) + { + // + // set source parameters + // + + sal_Int32 nType = rParam.bSql ? sdb::CommandType::COMMAND : + ( (rParam.nType == dbQuery) ? sdb::CommandType::QUERY : + sdb::CommandType::TABLE ); + uno::Any aAny; + + aAny <<= rtl::OUString( rParam.aDBName ); + xRowProp->setPropertyValue( + rtl::OUString::createFromAscii(SC_DBPROP_DATASOURCENAME), aAny ); + + aAny <<= rtl::OUString( rParam.aStatement ); + xRowProp->setPropertyValue( + rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny ); + + aAny <<= nType; + xRowProp->setPropertyValue( + rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny ); + + xRowSet->execute(); + + // + // get column descriptions + // + + long nColCount = 0; + uno::Reference<sdbc::XResultSetMetaData> xMeta; + uno::Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp( xRowSet, uno::UNO_QUERY ); + if ( xMetaSupp.is() ) + xMeta = xMetaSupp->getMetaData(); + if ( xMeta.is() ) + nColCount = xMeta->getColumnCount(); // this is the number of real columns + + if ( rParam.nCol1 + nColCount - 1 > MAXCOL ) + { + nColCount = 0; + //! error message + } + + uno::Reference<sdbc::XRow> xRow( xRowSet, uno::UNO_QUERY ); + if ( nColCount > 0 && xRow.is() ) + { + nEndCol = (USHORT)( rParam.nCol1 + nColCount - 1 ); + + uno::Sequence<sal_Int32> aColTypes( nColCount ); // column types + uno::Sequence<sal_Bool> aColCurr( nColCount ); // currency flag is not in types + sal_Int32* pTypeArr = aColTypes.getArray(); + sal_Bool* pCurrArr = aColCurr.getArray(); + for (i=0; i<nColCount; i++) + { + pTypeArr[i] = xMeta->getColumnType( i+1 ); + pCurrArr[i] = xMeta->isCurrency( i+1 ); + } + + if ( !bAddrInsert ) // read column names + { + nCol = rParam.nCol1; + for (i=0; i<nColCount; i++) + { + pImportDoc->SetString( nCol, nRow, nTab, + xMeta->getColumnLabel( i+1 ) ); + ++nCol; + } + ++nRow; + } + + BOOL bEnd = FALSE; + while ( !bEnd && xRowSet->next() ) + { + // skip rows that are not selected + + if (bDoSelection) + { + if (nListPos < nListCount) + { + ULONG nNextRow = (ULONG) pSelection->GetObject(nListPos); + while (nRowsRead+1 < nNextRow && !bEnd) + { + bRealSelection = TRUE; + if ( !xRowSet->next() ) + bEnd = TRUE; + ++nRowsRead; + } + ++nListPos; + } + else + { + bRealSelection = TRUE; // more data available but not used + bEnd = TRUE; + } + } + + if ( nRow <= MAXROW ) + { + nCol = rParam.nCol1; + for (i=0; i<nColCount; i++) + { + lcl_PutData( pImportDoc, nCol, nRow, nTab, + xRow, i+1, pTypeArr[i], pCurrArr[i] ); + ++nCol; + } + nEndRow = nRow; + ++nRow; + + // progress bar + + ++nInserted; + if (!(nInserted & 15)) + { + String aPict = ScGlobal::GetRscString( STR_PROGRESS_IMPORT ); + String aText = aPict.GetToken(0,'#'); + aText += String::CreateFromInt32( nInserted ); + aText += aPict.GetToken(1,'#'); + + if (!aProgress.SetStateText( 0, aText )) // stopped by user? + { + bEnd = TRUE; + bSuccess = FALSE; + nErrStringId = STR_DATABASE_ABORTED; + } + } + } + else // past the end of the spreadsheet + { + bEnd = TRUE; // don't continue + bTruncated = TRUE; // warning flag + } + } + + bSuccess = TRUE; + } + + } + } + catch ( sdbc::SQLException& rError ) + { + aErrorMessage = rError.Message; + } + catch ( uno::Exception& ) + { + DBG_ERROR("Unexpected exception in database"); + } + + ScColumn::bDoubleAlloc = FALSE; + pImportDoc->DoColResize( nTab, rParam.nCol1,nEndCol, 0 ); + + // + // test for cell protection + // + + BOOL bKeepFormat = !bAddrInsert && pDBData->IsKeepFmt(); + BOOL bMoveCells = !bAddrInsert && pDBData->IsDoSize(); + USHORT nFormulaCols = 0; // columns to be filled with formulas + if (bMoveCells && nEndCol == rParam.nCol2) + { + // if column count changes, formulas would become invalid anyway + // -> only set nFormulaCols for unchanged column count + + USHORT nTestCol = rParam.nCol2 + 1; // right of the data + USHORT nTestRow = rParam.nRow1 + 1; // below the title row + while ( nTestCol <= MAXCOL && + pDoc->GetCellType(ScAddress( nTestCol, nTestRow, nTab )) == CELLTYPE_FORMULA ) + ++nTestCol, ++nFormulaCols; + } + + if (bSuccess) + { + // old and new range editable? + if ( !pDoc->IsBlockEditable(nTab, rParam.nCol1,rParam.nRow1,rParam.nCol2,rParam.nRow2) || + !pDoc->IsBlockEditable(nTab, rParam.nCol1,rParam.nRow1,nEndCol,nEndRow) ) + { + nErrStringId = STR_PROTECTIONERR; + bSuccess = FALSE; + } + } + + if ( bSuccess && bMoveCells ) + { + ScRange aOld( rParam.nCol1, rParam.nRow1, nTab, + rParam.nCol2+nFormulaCols, rParam.nRow2, nTab ); + ScRange aNew( rParam.nCol1, rParam.nRow1, nTab, + nEndCol+nFormulaCols, nEndRow, nTab ); + if (!pDoc->CanFitBlock( aOld, aNew )) + { + nErrStringId = STR_MSSG_DOSUBTOTALS_2; // can't insert cells + bSuccess = FALSE; + } + } + + // + // copy data from import doc into real document + // + + if ( bSuccess ) + { + if (bKeepFormat) + { + // keep formatting of title and first data row from the document + // CopyToDocument also copies styles, Apply... needs separate calls + + USHORT nMinEndCol = Min( rParam.nCol2, nEndCol ); // not too much + nMinEndCol += nFormulaCols; // only if column count unchanged + pImportDoc->DeleteAreaTab( 0,0, MAXCOL,MAXROW, nTab, IDF_ATTRIB ); + pDoc->CopyToDocument( rParam.nCol1, rParam.nRow1, nTab, + nMinEndCol, rParam.nRow1, nTab, + IDF_ATTRIB, FALSE, pImportDoc ); + + USHORT nDataStartRow = rParam.nRow1+1; + for (USHORT nCopyCol=rParam.nCol1; nCopyCol<=nMinEndCol; nCopyCol++) + { + const ScPatternAttr* pSrcPattern = pDoc->GetPattern( + nCopyCol, nDataStartRow, nTab ); + pImportDoc->ApplyPatternAreaTab( nCopyCol, nDataStartRow, nCopyCol, nEndRow, + nTab, *pSrcPattern ); + const ScStyleSheet* pStyle = pSrcPattern->GetStyleSheet(); + if (pStyle) + pImportDoc->ApplyStyleAreaTab( nCopyCol, nDataStartRow, nCopyCol, nEndRow, + nTab, *pStyle ); + } + } + + // don't set cell protection attribute if table is protected + if (pDoc->IsTabProtected(nTab)) + { + ScPatternAttr aPattern(pImportDoc->GetPool()); + aPattern.GetItemSet().Put( ScProtectionAttr( FALSE,FALSE,FALSE,FALSE ) ); + pImportDoc->ApplyPatternAreaTab( 0,0,MAXCOL,MAXROW, nTab, aPattern ); + } + + // + // copy old data for undo + // + + USHORT nUndoEndCol = Max( nEndCol, rParam.nCol2 ); // rParam = old end + USHORT nUndoEndRow = Max( nEndRow, rParam.nRow2 ); + + ScDocument* pUndoDoc = NULL; + ScDBData* pUndoDBData = NULL; + if ( bRecord ) + { + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, nTab, nTab ); + + if ( !bAddrInsert ) + pUndoDBData = new ScDBData( *pDBData ); + } + + ScMarkData aNewMark; + aNewMark.SelectOneTable( nTab ); + + if (bRecord) + { + // nFormulaCols is set only if column count is unchanged + pDoc->CopyToDocument( rParam.nCol1, rParam.nRow1, nTab, + nEndCol+nFormulaCols, nEndRow, nTab, + IDF_ALL, FALSE, pUndoDoc ); + if ( rParam.nCol2 > nEndCol ) + pDoc->CopyToDocument( nEndCol+1, rParam.nRow1, nTab, + nUndoEndCol, nUndoEndRow, nTab, + IDF_ALL, FALSE, pUndoDoc ); + if ( rParam.nRow2 > nEndRow ) + pDoc->CopyToDocument( rParam.nCol1, nEndRow+1, nTab, + nUndoEndCol+nFormulaCols, nUndoEndRow, nTab, + IDF_ALL, FALSE, pUndoDoc ); + } + + // + // move new data + // + + if (bMoveCells) + { + // clear only the range without the formulas, + // so the formula title and first row are preserved + + ScRange aDelRange( rParam.nCol1, rParam.nRow1, nTab, + rParam.nCol2, rParam.nRow2, nTab ); + pDoc->DeleteAreaTab( aDelRange, IDF_ALL ); // ohne die Formeln + + ScRange aOld( rParam.nCol1, rParam.nRow1, nTab, + rParam.nCol2+nFormulaCols, rParam.nRow2, nTab ); + ScRange aNew( rParam.nCol1, rParam.nRow1, nTab, + nEndCol+nFormulaCols, nEndRow, nTab ); + pDoc->FitBlock( aOld, aNew, FALSE ); // Formeln nicht loeschen + } + else if ( nEndCol < rParam.nCol2 ) // DeleteArea calls PutInOrder + pDoc->DeleteArea( nEndCol+1, rParam.nRow1, rParam.nCol2, rParam.nRow2, + aNewMark, IDF_CONTENTS ); + + // CopyToDocument doesn't remove contents + pDoc->DeleteAreaTab( rParam.nCol1, rParam.nRow1, nEndCol, nEndRow, nTab, IDF_CONTENTS ); + + // #41216# remove each column from ImportDoc after copying to reduce memory usage + BOOL bOldAutoCalc = pDoc->GetAutoCalc(); + pDoc->SetAutoCalc( FALSE ); // outside of the loop + for (USHORT nCopyCol = rParam.nCol1; nCopyCol <= nEndCol; nCopyCol++) + { + pImportDoc->CopyToDocument( nCopyCol, rParam.nRow1, nTab, nCopyCol, nEndRow, nTab, + IDF_ALL, FALSE, pDoc ); + pImportDoc->DeleteAreaTab( nCopyCol, rParam.nRow1, nCopyCol, nEndRow, nTab, IDF_CONTENTS ); + pImportDoc->DoColResize( nTab, nCopyCol, nCopyCol, 0 ); + } + pDoc->SetAutoCalc( bOldAutoCalc ); + + if (nFormulaCols) // copy formulas + { + if (bKeepFormat) // formats for formulas + pImportDoc->CopyToDocument( nEndCol+1, rParam.nRow1, nTab, + nEndCol+nFormulaCols, nEndRow, nTab, + IDF_ATTRIB, FALSE, pDoc ); + // fill formulas + ScMarkData aMark; + aMark.SelectOneTable(nTab); + pDoc->Fill( nEndCol+1, rParam.nRow1+1, nEndCol+nFormulaCols, rParam.nRow1+1, + aMark, nEndRow-rParam.nRow1-1, FILL_TO_BOTTOM, FILL_SIMPLE ); + } + + // if new range is smaller, clear old contents + + if (!bMoveCells) // move has happened above + { + if ( rParam.nCol2 > nEndCol ) + pDoc->DeleteArea( nEndCol+1, rParam.nRow1, rParam.nCol2, rParam.nRow2, + aNewMark, IDF_CONTENTS ); + if ( rParam.nRow2 > nEndRow ) + pDoc->DeleteArea( rParam.nCol1, nEndRow+1, rParam.nCol2, rParam.nRow2, + aNewMark, IDF_CONTENTS ); + } + + if( !bAddrInsert ) // update database range + { + pDBData->SetImportParam( rParam ); + pDBData->SetHeader( TRUE ); + pDBData->SetByRow( TRUE ); + pDBData->SetArea( nTab, rParam.nCol1,rParam.nRow1, nEndCol,nEndRow ); + pDBData->SetImportSelection( bRealSelection ); + pDoc->CompileDBFormula(); + } + + if (bRecord) + { + ScDocument* pRedoDoc = pImportDoc; + pImportDoc = NULL; + + if (nFormulaCols) // include filled formulas for redo + pDoc->CopyToDocument( rParam.nCol1, rParam.nRow1, nTab, + nEndCol+nFormulaCols, nEndRow, nTab, + IDF_ALL, FALSE, pRedoDoc ); + + ScDBData* pRedoDBData = pDBData ? new ScDBData( *pDBData ) : NULL; + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoImportData( &rDocShell, nTab, + rParam, nUndoEndCol, nUndoEndRow, + nFormulaCols, + pUndoDoc, pRedoDoc, pUndoDBData, pRedoDBData ) ); + } + + pDoc->SetDirty(); + rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID ); + aModificator.SetDocumentModified(); + + if (pWaitWin) + pWaitWin->LeaveWait(); + + if ( bTruncated && !bApi ) // show warning + ErrorHandler::HandleError(SCWARN_IMPORT_RANGE_OVERFLOW); + } + else if ( !bApi ) + { + if (pWaitWin) + pWaitWin->LeaveWait(); + + if (!aErrorMessage.Len()) + { + if (!nErrStringId) + nErrStringId = STR_MSSG_IMPORTDATA_0; + aErrorMessage = ScGlobal::GetRscString( nErrStringId ); + } + InfoBox aInfoBox( rDocShell.GetDialogParent(), aErrorMessage ); + aInfoBox.Execute(); + } + + delete pImportDoc; + + return bSuccess; +} + + + + diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx new file mode 100644 index 000000000000..e90dcd17588c --- /dev/null +++ b/sc/source/ui/docshell/docfunc.cxx @@ -0,0 +1,3499 @@ +/************************************************************************* + * + * $RCSfile: docfunc.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#pragma hdrstop + +// INCLUDE --------------------------------------------------------------- + +#include "scitems.hxx" +#include <svx/editobj.hxx> +#include <svx/eeitem.hxx> +#include <svx/linkmgr.hxx> +#include <svx/svdundo.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/printer.hxx> +#include <vcl/msgbox.hxx> +#include <vcl/sound.hxx> +#include <vcl/virdev.hxx> +#include <vcl/waitobj.hxx> +#include <svtools/zforlist.hxx> + +#include "docfunc.hxx" + +#include "sc.hrc" + +#include "arealink.hxx" +#include "attrib.hxx" +#include "autoform.hxx" +#include "cell.hxx" +#include "detdata.hxx" +#include "detfunc.hxx" +#include "docpool.hxx" +#include "docsh.hxx" +#include "drwlayer.hxx" +#include "editutil.hxx" +#include "globstr.hrc" +#include "namecrea.hxx" // NAME_TOP etc. +#include "olinetab.hxx" +#include "patattr.hxx" +#include "rangenam.hxx" +#include "rangeutl.hxx" +#include "refundo.hxx" +#include "scresid.hxx" +#include "stlpool.hxx" +#include "stlsheet.hxx" +#include "tablink.hxx" +#include "tabvwsh.hxx" +#include "uiitems.hxx" +#include "undoblk.hxx" +#include "undocell.hxx" +#include "undodraw.hxx" +#include "undotab.hxx" +#include "waitoff.hxx" + +// STATIC DATA ----------------------------------------------------------- + +//======================================================================== + +IMPL_LINK( ScDocFunc, NotifyDrawUndo, SfxUndoAction*, pUndoAction ) +{ + rDocShell.GetUndoManager()->AddUndoAction( new ScUndoDraw( pUndoAction, &rDocShell ) ); + rDocShell.SetDrawModified(); + return 0; +} + +//------------------------------------------------------------------------ + +// Zeile ueber dem Range painten (fuer Linien nach AdjustRowHeight) + +void lcl_PaintAbove( ScDocShell& rDocShell, const ScRange& rRange ) +{ + USHORT nRow = rRange.aStart.Row(); + if ( nRow > 0 ) + { + USHORT nTab = rRange.aStart.Tab(); //! alle? + --nRow; + rDocShell.PostPaint( ScRange(0,nRow,nTab, MAXCOL,nRow,nTab), PAINT_GRID ); + } +} + +//------------------------------------------------------------------------ + +BOOL ScDocFunc::AdjustRowHeight( const ScRange& rRange, BOOL bPaint ) +{ + ScDocument* pDoc = rDocShell.GetDocument(); + if ( pDoc->IsImportingXML() ) + { + // for XML import, all row heights are updated together after importing + return FALSE; + } + +//! OutputDevice* pDev = rDocShell.GetPrinter(); + VirtualDevice aVDev; + OutputDevice* pDev = &aVDev; // aus Kompatibilitaetsgruenden... + + if (!pDev) + { + DBG_ERROR("kein Printer !??!?"); + return FALSE; + } + + USHORT nTab = rRange.aStart.Tab(); + USHORT nStartRow = rRange.aStart.Row(); + USHORT nEndRow = rRange.aEnd.Row(); + + Fraction aOne(1,1); + + MapMode aOldMap = pDev->GetMapMode(); + pDev->SetMapMode( MAP_PIXEL ); // wichtig fuer GetNeededSize + Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP ); + double nPPTX = aPix1000.X() / 1000.0; + double nPPTY = aPix1000.Y() / 1000.0; + + nPPTX /= rDocShell.GetOutputFactor(); // noetig fuer Bildschirm/VDev + + BOOL bChanged = pDoc->SetOptimalHeight( nStartRow, nEndRow, nTab, 0, pDev, + nPPTX, nPPTY, aOne, aOne, FALSE ); + + pDev->SetMapMode( aOldMap ); //! noetig ??? + + if ( bPaint && bChanged ) + rDocShell.PostPaint( 0, nStartRow, nTab, MAXCOL, MAXROW, nTab, + PAINT_GRID | PAINT_LEFT ); + + return bChanged; +} + + +//------------------------------------------------------------------------ + +BOOL ScDocFunc::DetectiveAddPred(const ScAddress& rPos) +{ + ScDocShellModificator aModificator( rDocShell ); + + rDocShell.MakeDrawLayer(); + ScDocument* pDoc = rDocShell.GetDocument(); + ScDrawLayer* pModel = pDoc->GetDrawLayer(); + USHORT nCol = rPos.Col(); + USHORT nRow = rPos.Row(); + USHORT nTab = rPos.Tab(); + + pModel->BeginCalcUndo(); + BOOL bDone = ScDetectiveFunc( pDoc,nTab ).ShowPred( nCol, nRow ); + SdrUndoGroup* pUndo = pModel->GetCalcUndo(); + if (bDone) + { + ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDPRED ); + pDoc->AddDetectiveOperation( aOperation ); + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoDetective( &rDocShell, pUndo, &aOperation ) ); + aModificator.SetDocumentModified(); + SFX_BINDINGS().Invalidate( SID_DETECTIVE_REFRESH ); + } + else + delete pUndo; + + return bDone; +} + +BOOL ScDocFunc::DetectiveDelPred(const ScAddress& rPos) +{ + ScDocument* pDoc = rDocShell.GetDocument(); + ScDrawLayer* pModel = pDoc->GetDrawLayer(); + if (!pModel) + return FALSE; + + ScDocShellModificator aModificator( rDocShell ); + + USHORT nCol = rPos.Col(); + USHORT nRow = rPos.Row(); + USHORT nTab = rPos.Tab(); + + pModel->BeginCalcUndo(); + BOOL bDone = ScDetectiveFunc( pDoc,nTab ).DeletePred( nCol, nRow ); + SdrUndoGroup* pUndo = pModel->GetCalcUndo(); + if (bDone) + { + ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_DELPRED ); + pDoc->AddDetectiveOperation( aOperation ); + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoDetective( &rDocShell, pUndo, &aOperation ) ); + aModificator.SetDocumentModified(); + SFX_BINDINGS().Invalidate( SID_DETECTIVE_REFRESH ); + } + else + delete pUndo; + + return bDone; +} + +BOOL ScDocFunc::DetectiveAddSucc(const ScAddress& rPos) +{ + ScDocShellModificator aModificator( rDocShell ); + + rDocShell.MakeDrawLayer(); + ScDocument* pDoc = rDocShell.GetDocument(); + ScDrawLayer* pModel = pDoc->GetDrawLayer(); + USHORT nCol = rPos.Col(); + USHORT nRow = rPos.Row(); + USHORT nTab = rPos.Tab(); + + pModel->BeginCalcUndo(); + BOOL bDone = ScDetectiveFunc( pDoc,nTab ).ShowSucc( nCol, nRow ); + SdrUndoGroup* pUndo = pModel->GetCalcUndo(); + if (bDone) + { + ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDSUCC ); + pDoc->AddDetectiveOperation( aOperation ); + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoDetective( &rDocShell, pUndo, &aOperation ) ); + aModificator.SetDocumentModified(); + SFX_BINDINGS().Invalidate( SID_DETECTIVE_REFRESH ); + } + else + delete pUndo; + + return bDone; +} + +BOOL ScDocFunc::DetectiveDelSucc(const ScAddress& rPos) +{ + ScDocument* pDoc = rDocShell.GetDocument(); + ScDrawLayer* pModel = pDoc->GetDrawLayer(); + if (!pModel) + return FALSE; + + ScDocShellModificator aModificator( rDocShell ); + + USHORT nCol = rPos.Col(); + USHORT nRow = rPos.Row(); + USHORT nTab = rPos.Tab(); + + pModel->BeginCalcUndo(); + BOOL bDone = ScDetectiveFunc( pDoc,nTab ).DeleteSucc( nCol, nRow ); + SdrUndoGroup* pUndo = pModel->GetCalcUndo(); + if (bDone) + { + ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_DELSUCC ); + pDoc->AddDetectiveOperation( aOperation ); + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoDetective( &rDocShell, pUndo, &aOperation ) ); + aModificator.SetDocumentModified(); + SFX_BINDINGS().Invalidate( SID_DETECTIVE_REFRESH ); + } + else + delete pUndo; + + return bDone; +} + +BOOL ScDocFunc::DetectiveAddError(const ScAddress& rPos) +{ + ScDocShellModificator aModificator( rDocShell ); + + rDocShell.MakeDrawLayer(); + ScDocument* pDoc = rDocShell.GetDocument(); + ScDrawLayer* pModel = pDoc->GetDrawLayer(); + USHORT nCol = rPos.Col(); + USHORT nRow = rPos.Row(); + USHORT nTab = rPos.Tab(); + + pModel->BeginCalcUndo(); + BOOL bDone = ScDetectiveFunc( pDoc,nTab ).ShowError( nCol, nRow ); + SdrUndoGroup* pUndo = pModel->GetCalcUndo(); + if (bDone) + { + ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDERROR ); + pDoc->AddDetectiveOperation( aOperation ); + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoDetective( &rDocShell, pUndo, &aOperation ) ); + aModificator.SetDocumentModified(); + SFX_BINDINGS().Invalidate( SID_DETECTIVE_REFRESH ); + } + else + delete pUndo; + + return bDone; +} + +BOOL ScDocFunc::DetectiveMarkInvalid(USHORT nTab) +{ + ScDocShellModificator aModificator( rDocShell ); + + rDocShell.MakeDrawLayer(); + ScDocument* pDoc = rDocShell.GetDocument(); + ScDrawLayer* pModel = pDoc->GetDrawLayer(); + + Window* pWaitWin = rDocShell.GetDialogParent(); + if (pWaitWin) + pWaitWin->EnterWait(); + pModel->BeginCalcUndo(); + BOOL bOverflow; + BOOL bDone = ScDetectiveFunc( pDoc,nTab ).MarkInvalid( bOverflow ); + SdrUndoGroup* pUndo = pModel->GetCalcUndo(); + if (pWaitWin) + pWaitWin->LeaveWait(); + if (bDone) + { + if (pUndo) + { + pUndo->SetComment( ScGlobal::GetRscString( STR_UNDO_DETINVALID ) ); + rDocShell.GetUndoManager()->AddUndoAction( pUndo ); + } + aModificator.SetDocumentModified(); + if ( bOverflow ) + { + InfoBox( NULL, + ScGlobal::GetRscString( STR_DETINVALID_OVERFLOW ) ).Execute(); + } + } + else + delete pUndo; + + return bDone; +} + +BOOL ScDocFunc::DetectiveDelAll(USHORT nTab) +{ + ScDocument* pDoc = rDocShell.GetDocument(); + ScDrawLayer* pModel = pDoc->GetDrawLayer(); + if (!pModel) + return FALSE; + + ScDocShellModificator aModificator( rDocShell ); + + pModel->BeginCalcUndo(); + BOOL bDone = ScDetectiveFunc( pDoc,nTab ).DeleteAll( SC_DET_DETECTIVE ); + SdrUndoGroup* pUndo = pModel->GetCalcUndo(); + if (bDone) + { + ScDetOpList* pOldList = pDoc->GetDetOpList(); + ScDetOpList* pUndoList = pOldList ? new ScDetOpList(*pOldList) : NULL; + + pDoc->ClearDetectiveOperations(); + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoDetective( &rDocShell, pUndo, NULL, pUndoList ) ); + aModificator.SetDocumentModified(); + SFX_BINDINGS().Invalidate( SID_DETECTIVE_REFRESH ); + } + else + delete pUndo; + + return bDone; +} + +BOOL ScDocFunc::DetectiveRefresh( BOOL bAutomatic ) +{ + BOOL bDone = FALSE; + ScDocument* pDoc = rDocShell.GetDocument(); + ScDetOpList* pList = pDoc->GetDetOpList(); + if ( pList && pList->Count() ) + { + rDocShell.MakeDrawLayer(); + ScDrawLayer* pModel = pDoc->GetDrawLayer(); + pModel->BeginCalcUndo(); + + // Loeschen auf allen Tabellen + + USHORT nTabCount = pDoc->GetTableCount(); + for (USHORT nTab=0; nTab<nTabCount; nTab++) + ScDetectiveFunc( pDoc,nTab ).DeleteAll( SC_DET_DETECTIVE ); + + // Wiederholen + + USHORT nCount = pList->Count(); + for (USHORT i=0; i<nCount; i++) + { + ScDetOpData* pData = (*pList)[i]; + if (pData) + { + ScAddress aPos = pData->GetPos(); + ScDetectiveFunc aFunc( pDoc, aPos.Tab() ); + USHORT nCol = aPos.Col(); + USHORT nRow = aPos.Row(); + switch (pData->GetOperation()) + { + case SCDETOP_ADDSUCC: + aFunc.ShowSucc( nCol, nRow ); + break; + case SCDETOP_DELSUCC: + aFunc.DeleteSucc( nCol, nRow ); + break; + case SCDETOP_ADDPRED: + aFunc.ShowPred( nCol, nRow ); + break; + case SCDETOP_DELPRED: + aFunc.DeletePred( nCol, nRow ); + break; + case SCDETOP_ADDERROR: + aFunc.ShowError( nCol, nRow ); + break; + default: + DBG_ERROR("falsche Op bei DetectiveRefresh"); + } + } + } + + SdrUndoGroup* pUndo = pModel->GetCalcUndo(); + if (pUndo) + { + pUndo->SetComment( ScGlobal::GetRscString( STR_UNDO_DETREFRESH ) ); + // wenn automatisch, an letzte Aktion anhaengen + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoDraw( pUndo, &rDocShell ), + bAutomatic ); + } + rDocShell.SetDrawModified(); + bDone = TRUE; + } + return bDone; +} + +//------------------------------------------------------------------------ + +BOOL ScDocFunc::DeleteContents( const ScMarkData& rMark, USHORT nFlags, + BOOL bRecord, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + if ( !rMark.IsMarked() && !rMark.IsMultiMarked() ) + { + DBG_ERROR("ScDocFunc::DeleteContents ohne Markierung"); + return FALSE; + } + + ScDocument* pDoc = rDocShell.GetDocument(); + if (!pDoc->IsSelectionEditable(rMark)) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + return FALSE; + } + + ScRange aMarkRange; + BOOL bSimple = FALSE; + + ScMarkData aMultiMark = rMark; + aMultiMark.SetMarking(FALSE); // fuer MarkToMulti + + ScDocument* pUndoDoc = NULL; + BOOL bMulti = !bSimple && aMultiMark.IsMultiMarked(); + if (!bSimple) + { + aMultiMark.MarkToMulti(); + aMultiMark.GetMultiMarkArea( aMarkRange ); + } + ScRange aExtendedRange(aMarkRange); + if (!bSimple) + { + if ( pDoc->ExtendMerge( aExtendedRange, TRUE ) ) + bMulti = FALSE; + } + + // keine Objekte auf geschuetzten Tabellen + BOOL bObjects = FALSE; + if ( nFlags & IDF_OBJECTS ) + { + bObjects = TRUE; + USHORT nTabCount = pDoc->GetTableCount(); + for (USHORT nTab=0; nTab<nTabCount; nTab++) + if (aMultiMark.GetTableSelect(nTab) && pDoc->IsTabProtected(nTab)) + bObjects = FALSE; + } + + USHORT nExtFlags = 0; // Linien interessieren nur, wenn Attribute + if ( nFlags & IDF_ATTRIB ) // geloescht werden + if (pDoc->HasAttrib( aMarkRange, HASATTR_PAINTEXT )) + nExtFlags |= SC_PF_LINES; + + // Reihenfolge: + // 1) BeginDrawUndo + // 2) Objekte loeschen (DrawUndo wird gefuellt) + // 3) Inhalte fuer Undo kopieren und Undo-Aktion anlegen + // 4) Inhalte loeschen + + if (bObjects) + { + if (bRecord) + pDoc->BeginDrawUndo(); + + if (bMulti) + pDoc->DeleteObjectsInSelection( aMultiMark ); + else + pDoc->DeleteObjectsInArea( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), + aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), + aMultiMark ); + } + + if ( bRecord ) + { + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, aMarkRange.aStart.Tab(), aMarkRange.aEnd.Tab() ); + + // bei "Format/Standard" alle Attribute kopieren, weil CopyToDocument + // nur mit IDF_HARDATTR zu langsam ist: + USHORT 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 + pDoc->CopyToDocument( aExtendedRange, nUndoDocFlags, bMulti, pUndoDoc, &aMultiMark ); + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoDeleteContents( &rDocShell, aMultiMark, aExtendedRange, + pUndoDoc, bMulti, nFlags, bObjects ) ); + } + +//! HideAllCursors(); // falls Zusammenfassung aufgehoben wird + if (bSimple) + pDoc->DeleteArea( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), + aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), + aMultiMark, nFlags ); + else + { + pDoc->DeleteSelection( nFlags, aMultiMark ); + aMultiMark.MarkToSimple(); + } + + if (!AdjustRowHeight( aExtendedRange )) + rDocShell.PostPaint( aExtendedRange, PAINT_GRID, nExtFlags ); + else if (nExtFlags & SC_PF_LINES) + lcl_PaintAbove( rDocShell, aExtendedRange ); // fuer Linien ueber dem Bereich + +// rDocShell.UpdateOle(GetViewData()); //! an der View? + aModificator.SetDocumentModified(); +//! CellContentChanged(); +//! ShowAllCursors(); + +#if 0 + //! muss an der View bleiben !!!! + if ( nFlags & IDF_ATTRIB ) + { + if ( nFlags & IDF_CONTENTS ) + ForgetFormatArea(); + else + StartFormatArea(); // Attribute loeschen ist auch Attributierung + } +#endif + + return TRUE; +} + +//------------------------------------------------------------------------ + +BOOL ScDocFunc::SetNormalString( const ScAddress& rPos, const String& rText, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + ScDocument* pDoc = rDocShell.GetDocument(); + if (!pDoc->IsBlockEditable( rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() )) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + return FALSE; + } + + USHORT* pTabs = new USHORT[1]; + pTabs[0] = rPos.Tab(); + ScBaseCell** ppOldCells = new ScBaseCell*[1]; + ScBaseCell* pDocCell = pDoc->GetCell( rPos ); + BOOL bEditDeleted = (pDocCell && pDocCell->GetCellType() == CELLTYPE_EDIT); + ppOldCells[0] = pDocCell ? pDocCell->Clone(pDoc) : NULL; + + BOOL* pHasFormat = new BOOL[1]; + ULONG* pOldFormats = new ULONG[1]; + const SfxPoolItem* pItem; + const ScPatternAttr* pPattern = pDoc->GetPattern( rPos.Col(),rPos.Row(),rPos.Tab() ); + if ( SFX_ITEM_SET == pPattern->GetItemSet().GetItemState( + ATTR_VALUE_FORMAT,FALSE,&pItem) ) + { + pHasFormat[0] = TRUE; + pOldFormats[0] = ((const SfxUInt32Item*)pItem)->GetValue(); + } + else + pHasFormat[0] = FALSE; + + pDoc->SetString( rPos.Col(), rPos.Row(), rPos.Tab(), rText ); + + // wegen ChangeTracking darf UndoAction erst nach SetString angelegt werden + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoEnterData( &rDocShell, rPos.Col(),rPos.Row(),rPos.Tab(), 1,pTabs, + ppOldCells, pHasFormat, pOldFormats, rText, NULL ) ); + + if ( bEditDeleted || pDoc->HasAttrib( ScRange(rPos), HASATTR_NEEDHEIGHT ) ) + AdjustRowHeight( ScRange(rPos) ); + + rDocShell.PostPaintCell( rPos.Col(), rPos.Row(), rPos.Tab() ); + aModificator.SetDocumentModified(); + + return TRUE; +} + +BOOL ScDocFunc::PutCell( const ScAddress& rPos, ScBaseCell* pNewCell, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + ScDocument* pDoc = rDocShell.GetDocument(); + if (!pDoc->IsBlockEditable( rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() )) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + pNewCell->Delete(); + return FALSE; + } + + BOOL bEditCell = ( pNewCell->GetCellType() == CELLTYPE_EDIT ); + ScBaseCell* pDocCell = pDoc->GetCell( rPos ); + BOOL bEditDeleted = (pDocCell && pDocCell->GetCellType() == CELLTYPE_EDIT); + BOOL bHeight = ( bEditDeleted || bEditCell || + pDoc->HasAttrib( ScRange(rPos), HASATTR_NEEDHEIGHT ) ); + ScBaseCell* pUndoCell = pDocCell ? pDocCell->Clone(pDoc) : NULL; + ScBaseCell* pRedoCell = pNewCell ? pNewCell->Clone(pDoc) : NULL; + + pDoc->PutCell( rPos, pNewCell ); + + // wegen ChangeTracking darf UndoAction erst nach PutCell angelegt werden + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoPutCell( &rDocShell, rPos, pUndoCell, pRedoCell, bHeight ) ); + + if (bHeight) + AdjustRowHeight( ScRange(rPos) ); + + rDocShell.PostPaintCell( rPos.Col(), rPos.Row(), rPos.Tab() ); + aModificator.SetDocumentModified(); + + return TRUE; +} + +BOOL ScDocFunc::PutData( const ScAddress& rPos, EditEngine& rEngine, BOOL bInterpret, BOOL bApi ) +{ + // PutData ruft PutCell oder SetNormalString + + // harte Ausrichtungs-Attribute aus der EditEngine loeschen + USHORT nCount = rEngine.GetParagraphCount(); + for (USHORT i=0; i<nCount; i++) + { + const SfxItemSet& rOld = rEngine.GetParaAttribs( i ); + if ( rOld.GetItemState( EE_PARA_JUST ) == SFX_ITEM_SET ) + { + SfxItemSet aNew( rOld ); + aNew.ClearItem( EE_PARA_JUST ); + rEngine.SetParaAttribs( i, aNew ); + } + } + + BOOL bRet = FALSE; + ScDocument* pDoc = rDocShell.GetDocument(); + ScEditAttrTester aTester( &rEngine ); + BOOL bEditCell = aTester.NeedsObject(); + if ( bEditCell ) + { + EditTextObject* pData = rEngine.CreateTextObject(); + bRet = PutCell( rPos, + new ScEditCell( pData, pDoc, rEngine.GetEditTextObjectPool() ), + bApi ); + delete pData; + } + else + { + String aText = rEngine.GetText(); + if (bInterpret) + bRet = SetNormalString( rPos, aText, bApi ); + else + bRet = PutCell( rPos, new ScStringCell( aText ), bApi ); + } + + if ( bRet && aTester.NeedsCellAttr() ) + { + const SfxItemSet& rEditAttr = aTester.GetAttribs(); + ScPatternAttr aPattern( pDoc->GetPool() ); + aPattern.GetFromEditItemSet( &rEditAttr ); + aPattern.DeleteUnchanged( pDoc->GetPattern( rPos.Col(), rPos.Row(), rPos.Tab() ) ); + if ( aPattern.GetItemSet().Count() > 0 ) + { + ScMarkData aMark; + aMark.SelectTable( rPos.Tab(), TRUE ); + aMark.SetMarkArea( ScRange( rPos ) ); + ApplyAttributes( aMark, aPattern, TRUE, bApi ); + } + } + + return bRet; +} + + +ScTokenArray* lcl_ScDocFunc_CreateTokenArrayXML( const String& rText ) +{ + ScTokenArray* pCode = new ScTokenArray; + xub_StrLen nPos = 0; + while ( nPos < rText.Len() ) + { + xub_StrLen nChars = Min( rText.Len() - nPos, MAXSTRLEN-1 ); + String aTmpStr( rText.Copy( nPos, nChars ) ); + pCode->AddString( aTmpStr.GetBuffer() ); + nPos += nChars; + } + return pCode; +} + + +BOOL ScDocFunc::SetCellText( const ScAddress& rPos, const String& rText, + BOOL bInterpret, BOOL bEnglish, BOOL bApi ) +{ + // SetCellText ruft PutCell oder SetNormalString + + ScDocument* pDoc = rDocShell.GetDocument(); + ScBaseCell* pNewCell = NULL; + if ( bInterpret ) + { + if ( bEnglish ) + { + if ( rText.Len() > 1 && rText.GetChar(0) == '=' ) + { + ScTokenArray* pCode; + if ( pDoc->IsImportingXML() ) + { // temporary formula string as string tokens + pCode = lcl_ScDocFunc_CreateTokenArrayXML( rText ); + } + else + { + ScCompiler aComp( pDoc, rPos ); + aComp.SetCompileEnglish( TRUE ); + pCode = aComp.CompileString( rText ); + } + pNewCell = new ScFormulaCell( pDoc, rPos, pCode, 0 ); + delete pCode; // Zell-ctor hat das TokenArray kopiert + } + else // (nur) auf englisches Zahlformat testen + { + SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); + ULONG nEnglish = pFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US); + double fVal; + if ( pFormatter->IsNumberFormat( rText, nEnglish, fVal ) ) + pNewCell = new ScValueCell( fVal ); + else + pNewCell = ScBaseCell::CreateTextCell( rText, pDoc ); + + // das (englische) Zahlformat wird nicht gesetzt + //! passendes lokales Format suchen und setzen??? + } + } + // sonst Null behalten -> SetString mit lokalen Formeln/Zahlformat + } + else if ( rText.Len() ) + pNewCell = ScBaseCell::CreateTextCell( rText, pDoc ); // immer Text + + if (pNewCell) + return PutCell( rPos, pNewCell, bApi ); + else + return SetNormalString( rPos, rText, bApi ); +} + +//------------------------------------------------------------------------ + +BOOL ScDocFunc::SetNoteText( const ScAddress& rPos, const String& rText, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + ScDocument* pDoc = rDocShell.GetDocument(); + if (!pDoc->IsBlockEditable( rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() )) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + return FALSE; + } + + String aNewText = rText; + aNewText.ConvertLineEnd(); //! ist das noetig ??? + + ScPostIt aNote; + pDoc->GetNote( rPos.Col(), rPos.Row(), rPos.Tab(), aNote ); + aNote.AutoSetText( aNewText ); // setzt auch Author und Date + pDoc->SetNote( rPos.Col(), rPos.Row(), rPos.Tab(), aNote ); + + if ( aNote.IsShown() ) + { + // Zeichenobjekt updaten + //! bei gelocktem Paint auch erst spaeter !!! + + ScDetectiveFunc aDetFunc( pDoc, rPos.Tab() ); + aDetFunc.HideComment( rPos.Col(), rPos.Row() ); + aDetFunc.ShowComment( rPos.Col(), rPos.Row(), FALSE ); // FALSE: nur wenn gefunden + } + + //! Undo !!! + + rDocShell.PostPaintCell( rPos.Col(), rPos.Row(), rPos.Tab() ); + aModificator.SetDocumentModified(); + + return TRUE; +} + +//------------------------------------------------------------------------ + +BOOL ScDocFunc::ApplyAttributes( const ScMarkData& rMark, const ScPatternAttr& rPattern, + BOOL bRecord, BOOL bApi ) +{ + ScDocument* pDoc = rDocShell.GetDocument(); + if ( bRecord && pDoc->IsImportingXML() ) + bRecord = FALSE; + + // nur wegen Matrix nicht editierbar? Attribute trotzdem ok + BOOL bOnlyNotBecauseOfMatrix; + if ( !pDoc->IsSelectionEditable( rMark, &bOnlyNotBecauseOfMatrix ) + && !bOnlyNotBecauseOfMatrix ) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + return FALSE; + } + + ScDocShellModificator aModificator( rDocShell ); + + //! Umrandung + + ScRange aMultiRange; + BOOL bMulti = rMark.IsMultiMarked(); + if ( bMulti ) + rMark.GetMultiMarkArea( aMultiRange ); + else + rMark.GetMarkArea( aMultiRange ); + + if ( bRecord ) + { + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, aMultiRange.aStart.Tab(), aMultiRange.aEnd.Tab() ); + pDoc->CopyToDocument( aMultiRange, IDF_ATTRIB, bMulti, pUndoDoc, &rMark ); + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoSelectionAttr( + &rDocShell, rMark, + aMultiRange.aStart.Col(), aMultiRange.aStart.Row(), aMultiRange.aStart.Tab(), + aMultiRange.aEnd.Col(), aMultiRange.aEnd.Row(), aMultiRange.aEnd.Tab(), + pUndoDoc, bMulti, &rPattern ) ); + } + + BOOL bPaintExt = pDoc->HasAttrib( aMultiRange, HASATTR_PAINTEXT ); + pDoc->ApplySelectionPattern( rPattern, rMark ); + + if (!bPaintExt) + bPaintExt = pDoc->HasAttrib( aMultiRange, HASATTR_PAINTEXT ); + USHORT nExtFlags = bPaintExt ? SC_PF_LINES : 0; + if (!AdjustRowHeight( aMultiRange )) + rDocShell.PostPaint( aMultiRange, PAINT_GRID, nExtFlags ); + else if (nExtFlags & SC_PF_LINES) + lcl_PaintAbove( rDocShell, aMultiRange ); // fuer Linien ueber dem Bereich + + aModificator.SetDocumentModified(); + + return TRUE; +} + + +BOOL ScDocFunc::ApplyStyle( const ScMarkData& rMark, const String& rStyleName, + BOOL bRecord, BOOL bApi ) +{ + ScDocument* pDoc = rDocShell.GetDocument(); + if ( bRecord && pDoc->IsImportingXML() ) + bRecord = FALSE; + + // nur wegen Matrix nicht editierbar? Attribute trotzdem ok + BOOL bOnlyNotBecauseOfMatrix; + if ( !pDoc->IsSelectionEditable( rMark, &bOnlyNotBecauseOfMatrix ) + && !bOnlyNotBecauseOfMatrix ) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + return FALSE; + } + + ScStyleSheet* pStyleSheet = (ScStyleSheet*) pDoc->GetStyleSheetPool()->Find( + rStyleName, SFX_STYLE_FAMILY_PARA ); + if (!pStyleSheet) + return FALSE; + + ScDocShellModificator aModificator( rDocShell ); + + ScRange aMultiRange; + BOOL bMulti = rMark.IsMultiMarked(); + if ( bMulti ) + rMark.GetMultiMarkArea( aMultiRange ); + else + rMark.GetMarkArea( aMultiRange ); + + if ( bRecord ) + { + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + USHORT nStartTab = aMultiRange.aStart.Tab(); + USHORT nTabCount = pDoc->GetTableCount(); + pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab ); + for (USHORT i=0; i<nTabCount; i++) + if (i != nStartTab && rMark.GetTableSelect(i)) + pUndoDoc->AddUndoTab( i, i ); + + ScRange aCopyRange = aMultiRange; + aCopyRange.aStart.SetTab(0); + aCopyRange.aEnd.SetTab(nTabCount-1); + pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, bMulti, pUndoDoc, &rMark ); + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoSelectionStyle( + &rDocShell, rMark, aMultiRange, rStyleName, pUndoDoc ) ); + + } + +// BOOL bPaintExt = pDoc->HasAttrib( aMultiRange, HASATTR_PAINTEXT ); +// pDoc->ApplySelectionPattern( rPattern, rMark ); + + pDoc->ApplySelectionStyle( (ScStyleSheet&)*pStyleSheet, rMark ); + +// if (!bPaintExt) +// bPaintExt = pDoc->HasAttrib( aMultiRange, HASATTR_PAINTEXT ); +// USHORT nExtFlags = bPaintExt ? SC_PF_LINES : 0; + USHORT nExtFlags = 0; + if (!AdjustRowHeight( aMultiRange )) + rDocShell.PostPaint( aMultiRange, PAINT_GRID, nExtFlags ); + else if (nExtFlags & SC_PF_LINES) + lcl_PaintAbove( rDocShell, aMultiRange ); // fuer Linien ueber dem Bereich + + aModificator.SetDocumentModified(); + + return TRUE; +} + +//------------------------------------------------------------------------ + +BOOL ScDocFunc::InsertCells( const ScRange& rRange, InsCellCmd eCmd, + BOOL bRecord, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + USHORT nStartCol = rRange.aStart.Col(); + USHORT nStartRow = rRange.aStart.Row(); + USHORT nStartTab = rRange.aStart.Tab(); + USHORT nEndCol = rRange.aEnd.Col(); + USHORT nEndRow = rRange.aEnd.Row(); + USHORT nEndTab = rRange.aEnd.Tab(); + + if ( nStartRow > MAXROW || nEndRow > MAXROW ) + { + DBG_ERROR("invalid row in InsertCells"); + return FALSE; + } + + USHORT nTab = nStartTab; + ScDocument* pDoc = rDocShell.GetDocument(); + USHORT nTabCount = pDoc->GetTableCount(); + USHORT nPaintStartX = nStartCol; + USHORT nPaintStartY = nStartRow; + USHORT nPaintEndX = nEndCol; + USHORT nPaintEndY = nEndRow; + USHORT nPaintFlags = PAINT_GRID; + BOOL bSuccess; + + // zugehoerige Szenarien auch anpassen + if ( !pDoc->IsScenario(nEndTab) ) + while ( nEndTab+1 < nTabCount && pDoc->IsScenario(nEndTab+1) ) + ++nEndTab; + + // Test zusammengefasste + + USHORT nMergeTestStartX = nStartCol; + USHORT nMergeTestStartY = nStartRow; + USHORT nMergeTestEndX = nEndCol; + USHORT nMergeTestEndY = nEndRow; + + if (eCmd==INS_INSROWS) + { + nMergeTestStartX = 0; + nMergeTestEndX = MAXCOL; + } + if (eCmd==INS_INSCOLS) + { + nMergeTestStartY = 0; + nMergeTestEndY = MAXROW; + } + if (eCmd==INS_CELLSDOWN) + nMergeTestEndY = MAXROW; + if (eCmd==INS_CELLSRIGHT) + nMergeTestEndX = MAXCOL; + + BOOL bCanDo = TRUE; + BOOL bNeedRefresh = FALSE; + + USHORT nEditTestEndX = (eCmd==INS_INSCOLS) ? MAXCOL : nMergeTestEndX; + USHORT nEditTestEndY = (eCmd==INS_INSROWS) ? MAXROW : nMergeTestEndY; + if (!pDoc->IsBlockEditable( nTab, nMergeTestStartX,nMergeTestStartY, + nEditTestEndX,nEditTestEndY )) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + return FALSE; + } + + if (pDoc->HasAttrib( nMergeTestStartX,nMergeTestStartY,nTab, + nMergeTestEndX,nMergeTestEndY,nTab, + HASATTR_MERGED | HASATTR_OVERLAPPED )) + { + if (eCmd==INS_CELLSRIGHT) + bNeedRefresh = TRUE; + + USHORT nMergeStartX = nMergeTestStartX; + USHORT nMergeStartY = nMergeTestStartY; + USHORT nMergeEndX = nMergeTestEndX; + USHORT nMergeEndY = nMergeTestEndY; + + pDoc->ExtendMerge( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, nTab ); + pDoc->ExtendOverlapped( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, nTab ); + if ( nMergeStartX != nMergeTestStartX || nMergeStartY != nMergeTestStartY || + nMergeEndX != nMergeTestEndX || nMergeEndY != nMergeTestEndY ) + bCanDo = FALSE; + + //! ? nur Start testen ? + + if (!bCanDo) + if ( eCmd==INS_INSCOLS || eCmd==INS_INSROWS ) + if ( nMergeStartX == nMergeTestStartX && nMergeStartY == nMergeTestStartY ) + { + bCanDo = TRUE; +// bNeedRefresh = TRUE; + } + } + + if (!bCanDo) + { + //! auf Verschieben (Drag&Drop) zurueckfuehren !!! + // "Kann nicht in zusammengefasste Bereiche einfuegen" + if (!bApi) + rDocShell.ErrorMessage(STR_MSSG_INSERTCELLS_0); + return FALSE; + } + + // + // ausfuehren + // + + WaitObject aWait( rDocShell.GetDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference + + ScDocument* pRefUndoDoc = NULL; + ScRefUndoData* pUndoData = NULL; + if ( bRecord ) + { + pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, FALSE, FALSE ); + + // alle Formeln wegen Referenzen + //! stattdessen bei InsertRow uebergeben + pDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,MAXTAB, IDF_FORMULA,FALSE,pRefUndoDoc ); + + pUndoData = new ScRefUndoData( pDoc ); + + pDoc->BeginDrawUndo(); + } + + switch (eCmd) + { + case INS_CELLSDOWN: + bSuccess = pDoc->InsertRow( nStartCol,nStartTab, nEndCol,nEndTab, + nStartRow, nEndRow-nStartRow+1 ); + nPaintEndY = MAXROW; + break; + case INS_INSROWS: + bSuccess = pDoc->InsertRow( 0,nStartTab, MAXCOL,nEndTab, + nStartRow, nEndRow-nStartRow+1 ); + nPaintStartX = 0; + nPaintEndX = MAXCOL; + nPaintEndY = MAXROW; + nPaintFlags |= PAINT_LEFT; + break; + case INS_CELLSRIGHT: + bSuccess = pDoc->InsertCol( nStartRow,nStartTab, nEndRow,nEndTab, + nStartCol, nEndCol-nStartCol+1 ); + nPaintEndX = MAXCOL; + break; + case INS_INSCOLS: + bSuccess = pDoc->InsertCol( 0,nStartTab, MAXROW,nEndTab, + nStartCol, nEndCol-nStartCol+1 ); + nPaintStartY = 0; + nPaintEndY = MAXROW; + nPaintEndX = MAXCOL; + nPaintFlags |= PAINT_TOP; + break; + default: + DBG_ERROR("Falscher Code beim Einfuegen"); + bSuccess = FALSE; + break; + } + + if ( bSuccess ) + { + if ( bRecord ) + { + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoInsertCells( &rDocShell, ScRange( + nStartCol,nStartRow,nStartTab, + nEndCol,nEndRow,nEndTab ), + eCmd, pRefUndoDoc, pUndoData ) ); + } + + if (bNeedRefresh) + pDoc->ExtendMerge( nMergeTestStartX,nMergeTestStartY, + nMergeTestEndX,nMergeTestEndY, nTab, TRUE ); + else + pDoc->RefreshAutoFilter( nMergeTestStartX,nMergeTestStartY, + nMergeTestEndX,nMergeTestEndY, nTab); + + if ( eCmd == INS_INSROWS || eCmd == INS_INSCOLS ) + pDoc->UpdatePageBreaks( nTab ); + + USHORT nExtFlags = 0; + if (pDoc->HasAttrib( nPaintStartX,nPaintStartY,nTab, + nPaintEndX,nPaintEndY,nTab, HASATTR_PAINTEXT )) + nExtFlags |= SC_PF_LINES; + + // ganze Zeilen einfuegen: nur neue Zeilen anpassen + BOOL bAdjusted = ( eCmd == INS_INSROWS ) ? + AdjustRowHeight(ScRange(0,nStartRow,nStartTab, MAXCOL,nEndRow,nEndTab)) : + AdjustRowHeight(ScRange(0,nPaintStartY,nStartTab, MAXCOL,nPaintEndY,nEndTab)); + if (bAdjusted) + { + // paint only what is not done by AdjustRowHeight + if (nPaintFlags & PAINT_TOP) + rDocShell.PostPaint( nPaintStartX, nPaintStartY, nStartTab, + nPaintEndX, nPaintEndY, nEndTab, PAINT_TOP ); + } + else + rDocShell.PostPaint( nPaintStartX, nPaintStartY, nStartTab, + nPaintEndX, nPaintEndY, nEndTab, + nPaintFlags, nExtFlags); + aModificator.SetDocumentModified(); + +//! pDocSh->UpdateOle(GetViewData()); // muss an der View bleiben +//! CellContentChanged(); // muss an der View bleiben + } + else + { + delete pRefUndoDoc; + delete pUndoData; + if (!bApi) + rDocShell.ErrorMessage(STR_INSERT_FULL); // Spalte/Zeile voll + } + return bSuccess; +} + +BOOL ScDocFunc::DeleteCells( const ScRange& rRange, DelCellCmd eCmd, BOOL bRecord, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + USHORT nStartCol = rRange.aStart.Col(); + USHORT nStartRow = rRange.aStart.Row(); + USHORT nStartTab = rRange.aStart.Tab(); + USHORT nEndCol = rRange.aEnd.Col(); + USHORT nEndRow = rRange.aEnd.Row(); + USHORT nEndTab = rRange.aEnd.Tab(); + + if ( nStartRow > MAXROW || nEndRow > MAXROW ) + { + DBG_ERROR("invalid row in DeleteCells"); + return FALSE; + } + + USHORT nTab = nStartTab; + ScDocument* pDoc = rDocShell.GetDocument(); + USHORT nTabCount = pDoc->GetTableCount(); + USHORT nPaintStartX = nStartCol; + USHORT nPaintStartY = nStartRow; + USHORT nPaintEndX = nEndCol; + USHORT nPaintEndY = nEndRow; + USHORT nPaintFlags = PAINT_GRID; + + // zugehoerige Szenarien auch anpassen + if ( !pDoc->IsScenario(nEndTab) ) + while ( nEndTab+1 < nTabCount && pDoc->IsScenario(nEndTab+1) ) + ++nEndTab; + + USHORT nUndoStartX = nStartCol; + USHORT nUndoStartY = nStartRow; + USHORT nUndoEndX = nEndCol; + USHORT nUndoEndY = nEndRow; + + if (eCmd==DEL_DELROWS) + { + nUndoStartX = 0; + nUndoEndX = MAXCOL; + } + if (eCmd==DEL_DELCOLS) + { + nUndoStartY = 0; + nUndoEndY = MAXROW; + } + + USHORT nDelEndX = nUndoEndX; + if (eCmd==DEL_CELLSLEFT||eCmd==DEL_DELCOLS) nDelEndX = MAXCOL; + USHORT nDelEndY = nUndoEndY; + if (eCmd==DEL_CELLSUP||eCmd==DEL_DELROWS) nDelEndY = MAXROW; + + // Test Zellschutz + + USHORT nEditTestEndX = nUndoEndX; + if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT ) nEditTestEndX = MAXCOL; + USHORT nEditTestEndY = nUndoEndX; + if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP ) nEditTestEndY = MAXROW; + if (!pDoc->IsBlockEditable( nTab, nUndoStartX,nUndoStartY,nEditTestEndX,nEditTestEndY )) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + return FALSE; + } + + // Test zusammengefasste + + USHORT nMergeTestEndX = (eCmd==DEL_CELLSLEFT) ? MAXCOL : nUndoEndX; + USHORT nMergeTestEndY = (eCmd==DEL_CELLSUP) ? MAXROW : nUndoEndY; + BOOL bCanDo = TRUE; + BOOL bNeedRefresh = FALSE; + + if (pDoc->HasAttrib( nUndoStartX,nUndoStartY,nTab, nMergeTestEndX,nMergeTestEndY,nTab, + HASATTR_MERGED | HASATTR_OVERLAPPED )) + { + if (eCmd==DEL_CELLSLEFT) + bNeedRefresh = TRUE; + + USHORT nMergeStartX = nUndoStartX; + USHORT nMergeStartY = nUndoStartY; + USHORT nMergeEndX = nMergeTestEndX; + USHORT nMergeEndY = nMergeTestEndY; + + pDoc->ExtendMerge( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, nTab ); + pDoc->ExtendOverlapped( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, nTab ); + if ( nMergeStartX != nUndoStartX || nMergeStartY != nUndoStartY || + nMergeEndX != nMergeTestEndX || nMergeEndY != nMergeTestEndY ) + bCanDo = FALSE; + + // ganze Zeilen/Spalten: Testen, ob Merge komplett geloescht werden kann + + if (!bCanDo) + if ( eCmd==DEL_DELCOLS || eCmd==DEL_DELROWS ) + if ( nMergeStartX == nUndoStartX && nMergeStartY == nUndoStartY ) + { + bCanDo = TRUE; + bNeedRefresh = TRUE; + } + } + + if (!bCanDo) + { + //! auf Verschieben (Drag&Drop) zurueckfuehren !!! + // "Kann nicht aus zusammengefassten Bereichen loeschen" + if (!bApi) + rDocShell.ErrorMessage(STR_MSSG_DELETECELLS_0); + return FALSE; + } + + // + // ausfuehren + // + + WaitObject aWait( rDocShell.GetDialogParent() ); // wichtig wegen TrackFormulas bei UpdateReference + + ScDocument* pUndoDoc = NULL; + ScDocument* pRefUndoDoc = NULL; + ScRefUndoData* pUndoData = NULL; + if ( bRecord ) + { + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab, + (eCmd==DEL_DELCOLS), (eCmd==DEL_DELROWS) ); + pDoc->CopyToDocument( nUndoStartX, nUndoStartY, nStartTab, nDelEndX, nDelEndY, nEndTab, + IDF_ALL, FALSE, pUndoDoc ); + pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, FALSE, FALSE ); + + pUndoData = new ScRefUndoData( pDoc ); + + pDoc->BeginDrawUndo(); + } + + USHORT nExtFlags = 0; + if (pDoc->HasAttrib( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab, HASATTR_PAINTEXT )) + nExtFlags |= SC_PF_LINES; + + BOOL bUndoOutline = FALSE; + switch (eCmd) + { + case DEL_CELLSUP: + pDoc->DeleteRow( nStartCol, nStartTab, nEndCol, nEndTab, + nStartRow, nEndRow-nStartRow+1, pRefUndoDoc ); + nPaintEndY = MAXROW; + break; + case DEL_DELROWS: + pDoc->DeleteRow( 0, nStartTab, MAXCOL, nEndTab, + nStartRow, nEndRow-nStartRow+1, pRefUndoDoc, &bUndoOutline ); + nPaintStartX = 0; + nPaintEndX = MAXCOL; + nPaintEndY = MAXROW; + nPaintFlags |= PAINT_LEFT; + break; + case DEL_CELLSLEFT: + pDoc->DeleteCol( nStartRow, nStartTab, nEndRow, nEndTab, + nStartCol, nEndCol-nStartCol+1, pRefUndoDoc ); + nPaintEndX = MAXCOL; + break; + case DEL_DELCOLS: + pDoc->DeleteCol( 0, nStartTab, MAXROW, nEndTab, + nStartCol, nEndCol-nStartCol+1, pRefUndoDoc, &bUndoOutline ); + nPaintStartY = 0; + nPaintEndY = MAXROW; + nPaintEndX = MAXCOL; + nPaintFlags |= PAINT_TOP; + break; + default: + DBG_ERROR("Falscher Code beim Loeschen"); + break; + } + + //! Test, ob Outline in Groesse geaendert + + if ( bRecord ) + { + for (USHORT i=nStartTab; i<=nEndTab; i++) + pRefUndoDoc->DeleteAreaTab(nUndoStartX,nUndoStartY,nDelEndX,nDelEndY,i, + IDF_ALL); + + // alle Tabellen anlegen, damit Formeln kopiert werden koennen: + pUndoDoc->AddUndoTab( 0, nTabCount-1, FALSE, FALSE ); + + // kopieren mit bColRowFlags=FALSE (#54194#) + pRefUndoDoc->CopyToDocument(0,0,0,MAXCOL,MAXROW,MAXTAB,IDF_FORMULA,FALSE,pUndoDoc,NULL,FALSE); + delete pRefUndoDoc; + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoDeleteCells( &rDocShell, ScRange( + nStartCol,nStartRow,nStartTab, + nEndCol,nEndRow,nEndTab ), + eCmd, pUndoDoc, pUndoData ) ); + } + + if (bNeedRefresh) + { + if ( eCmd==DEL_DELCOLS || eCmd==DEL_DELROWS ) + { + if (eCmd==DEL_DELCOLS) nMergeTestEndX = MAXCOL; + if (eCmd==DEL_DELROWS) nMergeTestEndY = MAXROW; + ScPatternAttr aPattern( pDoc->GetPool() ); + aPattern.GetItemSet().Put( ScMergeFlagAttr() ); + + ScMarkData aMark; // nur fuer Tabellen + for (USHORT i=nStartTab; i<=nEndTab; i++) + aMark.SelectTable( i, TRUE ); + pDoc->ApplyPatternArea( nUndoStartX, nUndoStartY, nMergeTestEndX, nMergeTestEndY, + aMark, aPattern ); + } + pDoc->ExtendMerge( nUndoStartX, nUndoStartY, nMergeTestEndX, nMergeTestEndY, nTab, TRUE ); + } + + if ( eCmd == DEL_DELCOLS || eCmd == DEL_DELROWS ) + pDoc->UpdatePageBreaks( nTab ); + + if (pDoc->HasAttrib( nPaintStartX,nPaintStartY,nTab, + nPaintEndX,nPaintEndY,nTab, HASATTR_PAINTEXT )) + nExtFlags |= SC_PF_LINES; + + // ganze Zeilen loeschen: nichts anpassen + if ( eCmd == DEL_DELROWS || + !AdjustRowHeight(ScRange(0,nPaintStartY,nStartTab, MAXCOL,nPaintEndY,nEndTab)) ) + rDocShell.PostPaint( nPaintStartX, nPaintStartY, nStartTab, + nPaintEndX, nPaintEndY, nEndTab, + nPaintFlags, nExtFlags ); + else + { + // paint only what is not done by AdjustRowHeight + if (nExtFlags & SC_PF_LINES) + lcl_PaintAbove( rDocShell, ScRange( nPaintStartX, nPaintStartY, nStartTab, + nPaintEndX, nPaintEndY, nEndTab) ); + if (nPaintFlags & PAINT_TOP) + rDocShell.PostPaint( nPaintStartX, nPaintStartY, nStartTab, + nPaintEndX, nPaintEndY, nEndTab, PAINT_TOP ); + } + aModificator.SetDocumentModified(); + +//! pDocSh->UpdateOle(GetViewData()); // muss an der View bleiben +//! CellContentChanged(); // muss an der View bleiben + + return TRUE; +} + +BOOL ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos, + BOOL bCut, BOOL bRecord, BOOL bPaint, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + USHORT nStartCol = rSource.aStart.Col(); + USHORT nStartRow = rSource.aStart.Row(); + USHORT nStartTab = rSource.aStart.Tab(); + USHORT nEndCol = rSource.aEnd.Col(); + USHORT nEndRow = rSource.aEnd.Row(); + USHORT nEndTab = rSource.aEnd.Tab(); + USHORT nDestCol = rDestPos.Col(); + USHORT nDestRow = rDestPos.Row(); + USHORT nDestTab = rDestPos.Tab(); + + if ( nStartRow > MAXROW || nEndRow > MAXROW || nDestRow > MAXROW ) + { + DBG_ERROR("invalid row in MoveBlock"); + return FALSE; + } + + // zugehoerige Szenarien auch anpassen - nur wenn innerhalb einer Tabelle verschoben wird! + BOOL bScenariosAdded = FALSE; + ScDocument* pDoc = rDocShell.GetDocument(); + USHORT nTabCount = pDoc->GetTableCount(); + if ( nDestTab == nStartTab && !pDoc->IsScenario(nEndTab) ) + while ( nEndTab+1 < nTabCount && pDoc->IsScenario(nEndTab+1) ) + { + ++nEndTab; + bScenariosAdded = TRUE; + } + + USHORT nSrcTabCount = nEndTab-nStartTab+1; + USHORT nDestEndTab = nDestTab+nSrcTabCount-1; + USHORT nTab; + + ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP ); + + ScMarkData aSourceMark; + for (nTab=nStartTab; nTab<=nEndTab; nTab++) + aSourceMark.SelectTable( nTab, TRUE ); // Source selektieren + aSourceMark.SetMarkArea( rSource ); + + pDoc->CopyToClip( nStartCol, nStartRow, nEndCol, nEndRow, bCut, pClipDoc, + FALSE, &aSourceMark, bScenariosAdded ); + + USHORT nOldEndCol = nEndCol; + USHORT nOldEndRow = nEndRow; + BOOL bClipOver = FALSE; + for (nTab=nStartTab; nTab<=nEndTab; nTab++) + { + USHORT nTmpEndCol = nOldEndCol; + USHORT nTmpEndRow = nOldEndRow; + if (pDoc->ExtendMerge( nStartCol, nStartRow, nTmpEndCol, nTmpEndRow, nTab )) + bClipOver = TRUE; + if ( nTmpEndCol > nEndCol ) nEndCol = nTmpEndCol; + if ( nTmpEndRow > nEndRow ) nEndRow = nTmpEndRow; + } + + USHORT nDestEndCol = nDestCol + ( nOldEndCol-nStartCol ); + USHORT nDestEndRow = nDestRow + ( nOldEndRow-nStartRow ); + + USHORT nUndoEndCol = nDestCol + ( nEndCol-nStartCol ); // erweitert im Zielblock + USHORT nUndoEndRow = nDestRow + ( nEndRow-nStartRow ); + + if (nUndoEndCol>MAXCOL || nUndoEndRow>MAXROW) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PASTE_FULL); + delete pClipDoc; + return FALSE; + } + + // Test auf Zellschutz + + BOOL bOk = TRUE; + for (nTab=nDestTab; nTab<=nDestEndTab && bOk; nTab++) + bOk = pDoc->IsBlockEditable( nTab, nDestCol,nDestRow, nUndoEndCol,nUndoEndRow ); + if (bCut) + for (nTab=nStartTab; nTab<=nEndTab && bOk; nTab++) + bOk = pDoc->IsBlockEditable( nTab, nStartCol,nStartRow, nEndCol,nEndRow ); + + if (!bOk) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + delete pClipDoc; + return FALSE; + } + + // Test auf zusammengefasste - beim Verschieben erst nach dem Loeschen + + if (bClipOver && !bCut) + if (pDoc->HasAttrib( nDestCol,nDestRow,nDestTab, nUndoEndCol,nUndoEndRow,nDestEndTab, + HASATTR_MERGED | HASATTR_OVERLAPPED )) + { // "Zusammenfassen nicht verschachteln !" + if (!bApi) + rDocShell.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0); + delete pClipDoc; + return FALSE; + } + + // Linien drin? (fuer Paint) + + BOOL bSourceLines = pDoc->HasAttrib( nStartCol,nStartRow,nStartTab, + nEndCol,nEndRow,nEndTab, HASATTR_PAINTEXT ); + BOOL bDestLines = pDoc->HasAttrib( nDestCol,nDestRow,nDestTab, + nDestEndCol,nDestEndRow,nDestEndTab, HASATTR_PAINTEXT ); + + // + // ausfuehren + // + + ScDocument* pUndoDoc = NULL; + ScDocument* pRefUndoDoc = NULL; + ScRefUndoData* pUndoData = NULL; + if (bRecord) + { + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab, FALSE, FALSE ); + + if (bCut) + { + pDoc->CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab, + IDF_ALL, FALSE, pUndoDoc ); + pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, FALSE, FALSE ); + } + + if ( nDestTab != nStartTab ) + pUndoDoc->AddUndoTab( nDestTab, nDestEndTab, FALSE, FALSE ); + pDoc->CopyToDocument( nDestCol, nDestRow, nDestTab, + nDestEndCol, nDestEndRow, nDestEndTab, + IDF_ALL, FALSE, pUndoDoc ); + + pUndoData = new ScRefUndoData( pDoc ); + + pDoc->BeginDrawUndo(); + } + + BOOL bSourceHeight = FALSE; // Hoehen angepasst? + if (bCut) + { + for (nTab=nStartTab; nTab<=nEndTab; nTab++) + pDoc->DeleteAreaTab( nStartCol,nStartRow, nOldEndCol,nOldEndRow, nTab, IDF_ALL ); +//!!! pDoc->DeleteAreaTab( nStartCol,nStartRow, nEndCol,nEndRow, nStartTab, IDF_ALL ); + + // Test auf zusammengefasste + + if (bClipOver) + if (pDoc->HasAttrib( nDestCol,nDestRow,nDestTab, + nUndoEndCol,nUndoEndRow,nDestEndTab, + HASATTR_MERGED | HASATTR_OVERLAPPED )) + { + pDoc->CopyFromClip( rSource, aSourceMark, IDF_ALL, pRefUndoDoc, pClipDoc ); + for (nTab=nStartTab; nTab<=nEndTab; nTab++) + { + USHORT nTmpEndCol = nEndCol; + USHORT nTmpEndRow = nEndRow; + pDoc->ExtendMerge( nStartCol, nStartRow, nTmpEndCol, nTmpEndRow, nTab, TRUE ); + } + + // Fehlermeldung erst nach dem Wiederherstellen des Inhalts + if (!bApi) // "Zusammenfassen nicht verschachteln !" + rDocShell.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0); + + delete pUndoDoc; + delete pRefUndoDoc; + delete pUndoData; + delete pClipDoc; + return FALSE; + } + + bSourceHeight = AdjustRowHeight( rSource, FALSE ); + } + + ScRange aPasteDest( nDestCol, nDestRow, nDestTab, nDestEndCol, nDestEndRow, nDestEndTab ); + + ScMarkData aDestMark; + for (nTab=nDestTab; nTab<=nDestEndTab; nTab++) + aDestMark.SelectTable( nTab, TRUE ); // Destination selektieren + aDestMark.SetMarkArea( aPasteDest ); + + //! markierte Tabellen bei CopyFromClip uebergeben !!!!! + pDoc->CopyFromClip( aPasteDest, aDestMark, IDF_ALL, pRefUndoDoc, pClipDoc ); + + VirtualDevice aVirtDev; + BOOL bDestHeight = AdjustRowHeight( + ScRange( 0,nDestRow,nDestTab, MAXCOL,nDestEndRow,nDestEndTab ), + FALSE ); + + if (bRecord) + { + if (pRefUndoDoc) + { + // alle Tabellen anlegen, damit Formeln kopiert werden koennen: + pUndoDoc->AddUndoTab( 0, nTabCount-1, FALSE, FALSE ); + + pRefUndoDoc->DeleteArea( nDestCol, nDestRow, nDestEndCol, nDestEndRow, aSourceMark, IDF_ALL ); + // kopieren mit bColRowFlags=FALSE (#54194#) + pRefUndoDoc->CopyToDocument( 0, 0, 0, MAXCOL, MAXROW, MAXTAB, + IDF_FORMULA, FALSE, pUndoDoc, NULL, FALSE ); + delete pRefUndoDoc; + } + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoDragDrop( &rDocShell, ScRange( + nStartCol, nStartRow, nStartTab, + nOldEndCol, nOldEndRow, nEndTab ), + ScAddress( nDestCol, nDestRow, nDestTab ), + bCut, pUndoDoc, pUndoData, bScenariosAdded ) ); + } + + USHORT nDestPaintEndCol = nDestEndCol; + USHORT nDestPaintEndRow = nDestEndRow; + for (nTab=nDestTab; nTab<=nDestEndTab; nTab++) + { + USHORT nTmpEndCol = nDestEndCol; + USHORT nTmpEndRow = nDestEndRow; + pDoc->ExtendMerge( nDestCol, nDestRow, nTmpEndCol, nTmpEndRow, nTab, TRUE ); + if (nTmpEndCol > nDestPaintEndCol) nDestPaintEndCol = nTmpEndCol; + if (nTmpEndRow > nDestPaintEndRow) nDestPaintEndRow = nTmpEndRow; + } + + if (bCut) + for (nTab=nStartTab; nTab<=nEndTab; nTab++) + pDoc->RefreshAutoFilter( nStartCol, nStartRow, nEndCol, nEndRow, nTab ); + + if (bPaint) + { + // Zielbereich: + + USHORT nPaintStartX = nDestCol; + USHORT nPaintStartY = nDestRow; + USHORT nPaintEndX = nDestPaintEndCol; + USHORT nPaintEndY = nDestPaintEndRow; + USHORT nFlags = PAINT_GRID; + USHORT nExt = 0; + if ( bSourceLines || bDestLines ) + nExt |= SC_PF_LINES; + + if ( nStartRow==0 && nEndRow==MAXROW ) // Breiten mitkopiert? + { + nPaintEndX = MAXCOL; + nPaintStartY = 0; + nPaintEndY = MAXROW; + nFlags |= PAINT_TOP; + } + if ( bDestHeight ) + { + nPaintEndY = MAXROW; + nPaintStartX = 0; + nPaintEndX = MAXCOL; + nFlags |= PAINT_LEFT; + } + if ( bScenariosAdded ) + { + nPaintStartX = nPaintStartY = 0; + nPaintEndX = MAXCOL; + nPaintEndY = MAXROW; + } + + rDocShell.PostPaint( nPaintStartX,nPaintStartY,nDestTab, + nPaintEndX,nPaintEndY,nDestEndTab, nFlags, nExt ); + + if ( bCut ) + { + // Quellbereich: + + nPaintStartX = nStartCol; + nPaintStartY = nStartRow; + nPaintEndX = nEndCol; + nPaintEndY = nEndRow; + nFlags = PAINT_GRID; + nExt = 0; + if ( bSourceLines ) + nExt |= SC_PF_LINES; + + if ( bSourceHeight ) + { + nPaintEndY = MAXROW; + nPaintStartX = 0; + nPaintEndX = MAXCOL; + nFlags |= PAINT_LEFT; + } + if ( bScenariosAdded ) + { + nPaintStartX = nPaintStartY = 0; + nPaintEndX = MAXCOL; + nPaintEndY = MAXROW; + } + + rDocShell.PostPaint( nPaintStartX,nPaintStartY,nStartTab, + nPaintEndX,nPaintEndY,nEndTab, nFlags, nExt ); + } + } + + aModificator.SetDocumentModified(); + + delete pClipDoc; + return TRUE; +} + +//------------------------------------------------------------------------ + +BOOL ScDocFunc::InsertTable( USHORT nTab, const String& rName, BOOL bRecord, BOOL bApi ) +{ + BOOL bSuccess = FALSE; + WaitObject aWait( rDocShell.GetDialogParent() ); + + ScDocShellModificator aModificator( rDocShell ); + + ScDocument* pDoc = rDocShell.GetDocument(); + if (bRecord) + pDoc->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage + + USHORT nTabCount = pDoc->GetTableCount(); + BOOL bAppend = ( nTab >= nTabCount ); + if ( bAppend ) + nTab = nTabCount; // wichtig fuer Undo + + if (pDoc->InsertTab( nTab, rName )) + { + if (bRecord) + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoInsertTab( &rDocShell, nTab, bAppend, rName)); + // Views updaten: + rDocShell.Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab ) ); + + rDocShell.PostPaintExtras(); + aModificator.SetDocumentModified(); + SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); + bSuccess = TRUE; + } + else if (!bApi) + rDocShell.ErrorMessage(STR_TABINSERT_ERROR); + + return bSuccess; +} + +BOOL ScDocFunc::DeleteTable( USHORT nTab, BOOL bRecord, BOOL bApi ) +{ + WaitObject aWait( rDocShell.GetDialogParent() ); + + ScDocShellModificator aModificator( rDocShell ); + + BOOL bSuccess = FALSE; + ScDocument* pDoc = rDocShell.GetDocument(); + BOOL bWasLinked = pDoc->IsLinked(nTab); + ScDocument* pUndoDoc = NULL; + ScRefUndoData* pUndoData = NULL; + if (bRecord) + { + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + USHORT nCount = pDoc->GetTableCount(); + + pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE ); // nur nTab mit Flags + pUndoDoc->AddUndoTab( 0, nCount-1 ); // alle Tabs fuer Referenzen + + pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,FALSE, pUndoDoc ); + String aOldName; + pDoc->GetName( nTab, aOldName ); + pUndoDoc->RenameTab( nTab, aOldName, FALSE ); + if (bWasLinked) + pUndoDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), pDoc->GetLinkDoc(nTab), + pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab), + pDoc->GetLinkTab(nTab) ); + + if ( pDoc->IsScenario(nTab) ) + { + pUndoDoc->SetScenario( nTab, TRUE ); + String aComment; + Color aColor; + USHORT nScenFlags; + pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags ); + pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags ); + BOOL bActive = pDoc->IsActiveScenario( nTab ); + pUndoDoc->SetActiveScenario( nTab, bActive ); + } + + // Drawing-Layer muss sein Undo selbst in der Hand behalten !!! + pDoc->BeginDrawUndo(); // DeleteTab erzeugt ein SdrUndoDelPage + + pUndoData = new ScRefUndoData( pDoc ); + } + + if (pDoc->DeleteTab( nTab, pUndoDoc )) + { + if (bRecord) + { + SvUShorts theTabs; + theTabs.Insert(nTab,theTabs.Count()); + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoDeleteTab( &rDocShell, theTabs, pUndoDoc, pUndoData )); + } + // Views updaten: + rDocShell.Broadcast( ScTablesHint( SC_TAB_DELETED, nTab ) ); + + if (bWasLinked) + { + rDocShell.UpdateLinks(); // Link-Manager updaten + SFX_BINDINGS().Invalidate(SID_LINKS); + } + + rDocShell.PostPaintExtras(); + aModificator.SetDocumentModified(); + SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); + bSuccess = TRUE; + } + else + { + delete pUndoDoc; + delete pUndoData; + } + return bSuccess; +} + +BOOL ScDocFunc::SetTableVisible( USHORT nTab, BOOL bVisible, BOOL bApi ) +{ + ScDocument* pDoc = rDocShell.GetDocument(); + if ( pDoc->IsVisible( nTab ) == bVisible ) + return TRUE; // nichts zu tun - ok + + if ( !pDoc->IsDocEditable() ) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + return FALSE; + } + + ScDocShellModificator aModificator( rDocShell ); + + if ( !bVisible ) + { + // nicht alle Tabellen ausblenden + + USHORT nVisCount = 0; + USHORT nCount = pDoc->GetTableCount(); + for (USHORT i=0; i<nCount; i++) + if (pDoc->IsVisible(i)) + ++nVisCount; + + if (nVisCount <= 1) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); //! eigene Meldung? + return FALSE; + } + } + + pDoc->SetVisible( nTab, bVisible ); + rDocShell.GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( &rDocShell, nTab, bVisible ) ); + + // Views updaten: + if (!bVisible) + rDocShell.Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) ); + + SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); + rDocShell.PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS); + aModificator.SetDocumentModified(); + + return TRUE; +} + +BOOL ScDocFunc::RenameTable( USHORT nTab, const String& rName, BOOL bRecord, BOOL bApi ) +{ + ScDocument* pDoc = rDocShell.GetDocument(); + if ( !pDoc->IsDocEditable() ) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + return FALSE; + } + + ScDocShellModificator aModificator( rDocShell ); + + BOOL bSuccess = FALSE; + String sOldName; + pDoc->GetName(nTab, sOldName); + if (pDoc->RenameTab( nTab, rName )) + { + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoRenameTab( &rDocShell, nTab, sOldName, rName)); + rDocShell.PostPaintExtras(); + aModificator.SetDocumentModified(); + SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); + + bSuccess = TRUE; + } + return bSuccess; +} + +//------------------------------------------------------------------------ + +//! SetWidthOrHeight - noch doppelt zu ViewFunc !!!!!! +//! Probleme: +//! - Optimale Hoehe fuer Edit-Zellen ist unterschiedlich zwischen Drucker und Bildschirm +//! - Optimale Breite braucht Selektion, um evtl. nur selektierte Zellen zu beruecksichtigen + +USHORT lcl_GetOptimalColWidth( ScDocShell& rDocShell, USHORT nCol, USHORT nTab, BOOL bFormula ) +{ + USHORT nTwips = 0; + +//! OutputDevice* pDev = rDocShell.GetPrinter(); + VirtualDevice aVDev; + OutputDevice* pDev = &aVDev; // aus Kompatibilitaetsgruenden... + + if (pDev) + { + ScDocument* pDoc = rDocShell.GetDocument(); + Fraction aOne(1,1); + MapMode aOldMap = pDev->GetMapMode(); + pDev->SetMapMode( MAP_PIXEL ); // wichtig fuer GetNeededSize + Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP ); + double nPPTX = aPix1000.X() / 1000.0; + double nPPTY = aPix1000.Y() / 1000.0; + nTwips = pDoc->GetOptimalColWidth( nCol, nTab, pDev, nPPTX, nPPTY, aOne, aOne, + bFormula, NULL ); + pDev->SetMapMode( aOldMap ); //! noetig ??? + } + return nTwips; +} + +BOOL ScDocFunc::SetWidthOrHeight( BOOL bWidth, USHORT nRangeCnt, USHORT* pRanges, USHORT nTab, + ScSizeMode eMode, USHORT nSizeTwips, + BOOL bRecord, BOOL bApi ) +{ + if (!nRangeCnt) + return TRUE; + + if ( rDocShell.IsReadOnly() ) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); //! eigene Meldung? + return FALSE; + } + + BOOL bSuccess = FALSE; + ScDocument* pDoc = rDocShell.GetDocument(); + USHORT nStart = pRanges[0]; + USHORT nEnd = pRanges[2*nRangeCnt-1]; + + BOOL bFormula = FALSE; + if ( eMode == SC_SIZE_OPTIMAL ) + { + //! Option "Formeln anzeigen" - woher nehmen? + } + + ScDocument* pUndoDoc = NULL; + ScOutlineTable* pUndoTab = NULL; + USHORT* pUndoRanges = NULL; + + if ( bRecord ) + { + pDoc->BeginDrawUndo(); // Drawing Updates + + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + if (bWidth) + { + pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, FALSE ); + pDoc->CopyToDocument( nStart, 0, nTab, nEnd, MAXROW, nTab, IDF_NONE, FALSE, pUndoDoc ); + } + else + { + pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, TRUE ); + pDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, FALSE, pUndoDoc ); + } + + pUndoRanges = new USHORT[ 2*nRangeCnt ]; + memmove( pUndoRanges, pRanges, 2*nRangeCnt*sizeof(USHORT) ); + + ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab ); + if (pTable) + pUndoTab = new ScOutlineTable( *pTable ); + } + + BOOL bShow = nSizeTwips > 0 || eMode != SC_SIZE_DIRECT; + BOOL bOutline = FALSE; + + pDoc->IncSizeRecalcLevel( nTab ); // nicht fuer jede Spalte einzeln + for (USHORT nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++) + { + USHORT nStartNo = *(pRanges++); + USHORT nEndNo = *(pRanges++); + + if ( !bWidth ) // Hoehen immer blockweise + { + if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT ) + { + BOOL bAll = ( eMode==SC_SIZE_OPTIMAL ); + if (!bAll) + { + // fuer alle eingeblendeten CR_MANUALSIZE loeschen, + // dann SetOptimalHeight mit bShrink = FALSE + for (USHORT nRow=nStartNo; nRow<=nEndNo; nRow++) + { + BYTE nOld = pDoc->GetRowFlags(nRow,nTab); + if ( (nOld & CR_HIDDEN) == 0 && ( nOld & CR_MANUALSIZE ) ) + pDoc->SetRowFlags( nRow, nTab, nOld & ~CR_MANUALSIZE ); + } + } + +//! OutputDevice* pDev = rDocShell.GetPrinter(); + VirtualDevice aVDev; + OutputDevice* pDev = &aVDev; // aus Kompatibilitaetsgruenden... + + if (pDev) + { + Fraction aOne(1,1); + MapMode aOldMap = pDev->GetMapMode(); + pDev->SetMapMode( MAP_PIXEL ); // wichtig fuer GetNeededSize + Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP ); + double nPPTX = aPix1000.X() / 1000.0; + double nPPTY = aPix1000.Y() / 1000.0; + pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, 0, pDev, + nPPTX, nPPTY, aOne, aOne, bAll ); + pDev->SetMapMode( aOldMap ); //! noetig ??? + } + + if (bAll) + pDoc->ShowRows( nStartNo, nEndNo, nTab, TRUE ); + + // Manual-Flag wird bei bAll=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->ShowRows( nStartNo, nEndNo, nTab, nSizeTwips != 0 ); + pDoc->SetManualHeight( nStartNo, nEndNo, nTab, TRUE ); // Manual-Flag + } + else if ( eMode==SC_SIZE_SHOW ) + { + pDoc->ShowRows( nStartNo, nEndNo, nTab, TRUE ); + } + } + else // Spaltenbreiten + { + for (USHORT nCol=nStartNo; nCol<=nEndNo; nCol++) + { + if ( eMode != SC_SIZE_VISOPT || + (pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN) == 0 ) + { + USHORT nThisSize = nSizeTwips; + + if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT ) + nThisSize = nSizeTwips + + lcl_GetOptimalColWidth( rDocShell, nCol, nTab, bFormula ); + if ( nThisSize ) + pDoc->SetColWidth( nCol, nTab, nThisSize ); + + pDoc->ShowCol( nCol, nTab, bShow ); + } + } + } + + // Outline anpassen + + if (bWidth) + bOutline = bOutline || pDoc->UpdateOutlineCol( nStartNo, nEndNo, nTab, bShow ); + else + bOutline = bOutline || pDoc->UpdateOutlineRow( nStartNo, nEndNo, nTab, bShow ); + } + pDoc->DecSizeRecalcLevel( nTab ); // nicht fuer jede Spalte einzeln + + if (!bOutline) + DELETEZ(pUndoTab); + + if (bRecord) + { + ScMarkData aMark; + aMark.SelectOneTable( nTab ); + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoWidthOrHeight( &rDocShell, aMark, + nStart, nTab, nEnd, nTab, + pUndoDoc, nRangeCnt, pUndoRanges, + pUndoTab, eMode, nSizeTwips, bWidth ) ); + } + + pDoc->UpdatePageBreaks( nTab ); + + + //! Test !!!!!!! + rDocShell.PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_ALL); + //! Test !!!!!!! + + return bSuccess; +} + + +BOOL ScDocFunc::InsertPageBreak( BOOL bColumn, const ScAddress& rPos, + BOOL bRecord, BOOL bSetModified, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + ScDocument* pDoc = rDocShell.GetDocument(); + USHORT nTab = rPos.Tab(); + SfxBindings& rBindings = SFX_BINDINGS(); + + USHORT nPos = bColumn ? rPos.Col() : rPos.Row(); + if (nPos == 0) + return FALSE; // erste Spalte / Zeile + + BYTE nFlags = bColumn ? pDoc->GetColFlags( nPos, nTab ) : pDoc->GetRowFlags( nPos, nTab ); + if (nFlags & CR_MANUALBREAK) + return TRUE; // Umbruch schon gesetzt + + if (bRecord) + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoPageBreak( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, TRUE ) ); + + nFlags |= CR_MANUALBREAK; + if (bColumn) + pDoc->SetColFlags( nPos, nTab, nFlags ); + else + pDoc->SetRowFlags( nPos, nTab, nFlags ); + pDoc->UpdatePageBreaks( nTab ); + + if (bColumn) + { + rDocShell.PostPaint( nPos-1, 0, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID ); + rBindings.Invalidate( FID_INS_COLBRK ); + rBindings.Invalidate( FID_DEL_COLBRK ); + } + else + { + rDocShell.PostPaint( 0, nPos-1, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID ); + rBindings.Invalidate( FID_INS_ROWBRK ); + rBindings.Invalidate( FID_DEL_ROWBRK ); + } + rBindings.Invalidate( FID_DEL_MANUALBREAKS ); + + if (bSetModified) + aModificator.SetDocumentModified(); + + return TRUE; +} + +BOOL ScDocFunc::RemovePageBreak( BOOL bColumn, const ScAddress& rPos, + BOOL bRecord, BOOL bSetModified, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + ScDocument* pDoc = rDocShell.GetDocument(); + USHORT nTab = rPos.Tab(); + SfxBindings& rBindings = SFX_BINDINGS(); + + USHORT nPos = bColumn ? rPos.Col() : rPos.Row(); + BYTE nFlags = bColumn ? pDoc->GetColFlags( nPos, nTab ) : pDoc->GetRowFlags( nPos, nTab ); + if ((nFlags & CR_MANUALBREAK)==0) + return FALSE; // kein Umbruch gesetzt + + if (bRecord) + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoPageBreak( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, FALSE ) ); + + nFlags &= ~CR_MANUALBREAK; + if (bColumn) + pDoc->SetColFlags( nPos, nTab, nFlags ); + else + pDoc->SetRowFlags( nPos, nTab, nFlags ); + pDoc->UpdatePageBreaks( nTab ); + + if (bColumn) + { + rDocShell.PostPaint( nPos-1, 0, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID ); + rBindings.Invalidate( FID_INS_COLBRK ); + rBindings.Invalidate( FID_DEL_COLBRK ); + } + else + { + rDocShell.PostPaint( 0, nPos-1, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID ); + rBindings.Invalidate( FID_INS_ROWBRK ); + rBindings.Invalidate( FID_DEL_ROWBRK ); + } + rBindings.Invalidate( FID_DEL_MANUALBREAKS ); + + if (bSetModified) + aModificator.SetDocumentModified(); + + return TRUE; +} + +//------------------------------------------------------------------------ + +BOOL lcl_ValidPassword( ScDocument* pDoc, USHORT nTab, + const String& rPassword, String* pReturnOld = NULL ) +{ + String aOldPassword; + if ( nTab == TABLEID_DOC ) + { + if (pDoc->IsDocProtected()) + aOldPassword = pDoc->GetDocPassword(); + } + else + { + if (pDoc->IsTabProtected(nTab)) + aOldPassword = pDoc->GetTabPassword(nTab); + } + + if (pReturnOld) + *pReturnOld = aOldPassword; + + return ( aOldPassword.Len() == 0 || aOldPassword == rPassword ); +} + +BOOL ScDocFunc::Protect( USHORT nTab, const String& rPassword, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + ScDocument* pDoc = rDocShell.GetDocument(); + BOOL bOk = lcl_ValidPassword( pDoc, nTab, rPassword ); + + if ( bOk ) + { + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoProtect( &rDocShell, nTab, TRUE, rPassword ) ); + + if ( nTab == TABLEID_DOC ) + pDoc->SetDocProtection( TRUE, rPassword ); + else + pDoc->SetTabProtection( nTab, TRUE, rPassword ); + + rDocShell.PostPaintGridAll(); + aModificator.SetDocumentModified(); + } + else if (!bApi) + { + // different password was set before + +//! rDocShell.ErrorMessage(...); + + InfoBox aBox( rDocShell.GetDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD ) ) ); + aBox.Execute(); + } + + return bOk; +} + +BOOL ScDocFunc::Unprotect( USHORT nTab, const String& rPassword, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + ScDocument* pDoc = rDocShell.GetDocument(); + String aOldPassword; + BOOL bOk = lcl_ValidPassword( pDoc, nTab, rPassword, &aOldPassword ); + + if ( bOk ) + { + if ( nTab == TABLEID_DOC ) + pDoc->SetDocProtection( FALSE, String() ); + else + pDoc->SetTabProtection( nTab, FALSE, String() ); + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoProtect( &rDocShell, nTab, FALSE, aOldPassword ) ); + + rDocShell.PostPaintGridAll(); + aModificator.SetDocumentModified(); + } + else if (!bApi) + { +//! rDocShell.ErrorMessage(...); + + InfoBox aBox( rDocShell.GetDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD ) ) ); + aBox.Execute(); + } + + return bOk; +} + +//------------------------------------------------------------------------ + +BOOL ScDocFunc::ClearItems( const ScMarkData& rMark, const USHORT* pWhich, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + ScDocument* pDoc = rDocShell.GetDocument(); + if (!pDoc->IsSelectionEditable(rMark)) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + return FALSE; + } + + ScRange aMarkRange; + rMark.GetMultiMarkArea( aMarkRange ); + +// if (bRecord) + { + USHORT nStartTab = aMarkRange.aStart.Tab(); + USHORT nEndTab = aMarkRange.aEnd.Tab(); + + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab ); + pDoc->CopyToDocument( aMarkRange, IDF_ATTRIB, TRUE, pUndoDoc, (ScMarkData*)&rMark ); + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoClearItems( &rDocShell, rMark, pUndoDoc, pWhich ) ); + } + + pDoc->ClearSelectionItems( pWhich, rMark ); + + rDocShell.PostPaint( aMarkRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE ); + aModificator.SetDocumentModified(); + + //! Bindings-Invalidate etc.? + + return TRUE; +} + +BOOL ScDocFunc::ChangeIndent( const ScMarkData& rMark, BOOL bIncrement, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + ScDocument* pDoc = rDocShell.GetDocument(); + if (!pDoc->IsSelectionEditable(rMark)) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + return FALSE; + } + + ScRange aMarkRange; + rMark.GetMultiMarkArea( aMarkRange ); + +// if (bRecord) + { + USHORT nStartTab = aMarkRange.aStart.Tab(); + USHORT nTabCount = pDoc->GetTableCount(); + + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab ); + for (USHORT i=0; i<nTabCount; i++) + if (i != nStartTab && rMark.GetTableSelect(i)) + pUndoDoc->AddUndoTab( i, i ); + + ScRange aCopyRange = aMarkRange; + aCopyRange.aStart.SetTab(0); + aCopyRange.aEnd.SetTab(nTabCount-1); + pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, TRUE, pUndoDoc, (ScMarkData*)&rMark ); + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoIndent( &rDocShell, rMark, pUndoDoc, bIncrement ) ); + } + + pDoc->ChangeSelectionIndent( bIncrement, rMark ); + + rDocShell.PostPaint( aMarkRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE ); + aModificator.SetDocumentModified(); + + SfxBindings& rBindings = SFX_BINDINGS(); + rBindings.Invalidate( SID_ALIGNLEFT ); // ChangeIndent setzt auf links + rBindings.Invalidate( SID_ALIGNRIGHT ); + rBindings.Invalidate( SID_ALIGNBLOCK ); + rBindings.Invalidate( SID_ALIGNCENTERHOR ); + + return TRUE; +} + +BOOL ScDocFunc::AutoFormat( const ScRange& rRange, const ScMarkData* pTabMark, + USHORT nFormatNo, BOOL bRecord, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + BOOL bSuccess = FALSE; + ScDocument* pDoc = rDocShell.GetDocument(); + USHORT nStartCol = rRange.aStart.Col(); + USHORT nStartRow = rRange.aStart.Row(); + USHORT nStartTab = rRange.aStart.Tab(); + USHORT nEndCol = rRange.aEnd.Col(); + USHORT nEndRow = rRange.aEnd.Row(); + USHORT nEndTab = rRange.aEnd.Tab(); + + ScMarkData aMark; + if (pTabMark) + aMark = *pTabMark; + else + { + for (USHORT nTab=nStartTab; nTab<=nEndTab; nTab++) + aMark.SelectTable( nTab, TRUE ); + } + + ScAutoFormat* pAutoFormat = ScGlobal::GetAutoFormat(); + if ( pAutoFormat && nFormatNo < pAutoFormat->GetCount() && + pDoc->IsSelectedBlockEditable( nStartCol,nStartRow, nEndCol,nEndRow, aMark ) ) + { + WaitObject aWait( rDocShell.GetDialogParent() ); + + BOOL bSize = (*pAutoFormat)[nFormatNo]->GetIncludeWidthHeight(); + + USHORT nTabCount = pDoc->GetTableCount(); + ScDocument* pUndoDoc = NULL; + if ( bRecord ) + { + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab, bSize, bSize ); + for (USHORT i=0; i<nTabCount; i++) + if (i != nStartTab && aMark.GetTableSelect(i)) + pUndoDoc->AddUndoTab( i, i, bSize, bSize ); + + ScRange aCopyRange = rRange; + aCopyRange.aStart.SetTab(0); + aCopyRange.aStart.SetTab(nTabCount-1); + pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, FALSE, pUndoDoc, &aMark ); + if (bSize) + { + pDoc->CopyToDocument( nStartCol,0,0, nEndCol,MAXROW,nTabCount-1, + IDF_NONE, FALSE, pUndoDoc, &aMark ); + pDoc->CopyToDocument( 0,nStartRow,0, MAXCOL,nEndRow,nTabCount-1, + IDF_NONE, FALSE, pUndoDoc, &aMark ); + } + pDoc->BeginDrawUndo(); + } + + pDoc->AutoFormat( nStartCol, nStartRow, nEndCol, nEndRow, nFormatNo, aMark ); + + if (bSize) + { +/* USHORT nCols[2]; + nCols[0] = nStartCol; + nCols[1] = nEndCol; + USHORT nRows[2]; + nRows[0] = nStartRow; + nRows[1] = nEndRow; +*/ + USHORT nCols[2] = { nStartCol, nEndCol }; + USHORT nRows[2] = { nStartRow, nEndRow }; + + for (USHORT nTab=0; nTab<nTabCount; nTab++) + if (aMark.GetTableSelect(nTab)) + { + SetWidthOrHeight( TRUE, 1,nCols, nTab, SC_SIZE_VISOPT, STD_EXTRA_WIDTH, FALSE, TRUE ); + SetWidthOrHeight( FALSE,1,nRows, nTab, SC_SIZE_VISOPT, 0, FALSE, FALSE ); + rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, + PAINT_GRID | PAINT_LEFT | PAINT_TOP ); + } + } + else + { + for (USHORT nTab=0; nTab<nTabCount; nTab++) + if (aMark.GetTableSelect(nTab)) + { + BOOL bAdj = AdjustRowHeight( ScRange(nStartCol, nStartRow, nTab, + nEndCol, nEndRow, nTab), FALSE ); + if (bAdj) + rDocShell.PostPaint( 0,nStartRow,nTab, MAXCOL,MAXROW,nTab, + PAINT_GRID | PAINT_LEFT ); + else + rDocShell.PostPaint( nStartCol, nStartRow, nTab, + nEndCol, nEndRow, nTab, PAINT_GRID ); + } + } + + if ( bRecord ) // Draw-Undo erst jetzt verfuegbar + { + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoAutoFormat( &rDocShell, rRange, pUndoDoc, aMark, bSize, nFormatNo ) ); + } + + aModificator.SetDocumentModified(); + } + else if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + + return bSuccess; +} + +//------------------------------------------------------------------------ + +BOOL ScDocFunc::EnterMatrix( const ScRange& rRange, const ScMarkData* pTabMark, + const String& rString, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + BOOL bSuccess = FALSE; + ScDocument* pDoc = rDocShell.GetDocument(); + USHORT nStartCol = rRange.aStart.Col(); + USHORT nStartRow = rRange.aStart.Row(); + USHORT nStartTab = rRange.aStart.Tab(); + USHORT nEndCol = rRange.aEnd.Col(); + USHORT nEndRow = rRange.aEnd.Row(); + USHORT nEndTab = rRange.aEnd.Tab(); + + ScMarkData aMark; + if (pTabMark) + aMark = *pTabMark; + else + { + for (USHORT nTab=nStartTab; nTab<=nEndTab; nTab++) + aMark.SelectTable( nTab, TRUE ); + } + + if ( pDoc->IsSelectedBlockEditable( nStartCol,nStartRow, nEndCol,nEndRow, aMark ) ) + { + WaitObject aWait( rDocShell.GetDialogParent() ); + + ScDocument* pUndoDoc; +// if (bRecord) // immer + { + //! auch bei Undo selektierte Tabellen beruecksichtigen + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab ); + pDoc->CopyToDocument( rRange, IDF_ALL, FALSE, pUndoDoc ); + } + + if ( pDoc->IsImportingXML() ) + { + ScTokenArray* pCode = lcl_ScDocFunc_CreateTokenArrayXML( rString ); + pDoc->InsertMatrixFormula(nStartCol,nStartRow,nEndCol,nEndRow,aMark,EMPTY_STRING,pCode); + delete pCode; + } + else + pDoc->InsertMatrixFormula(nStartCol,nStartRow,nEndCol,nEndRow,aMark,rString); + +// if (bRecord) // immer + { + //! auch bei Undo selektierte Tabellen beruecksichtigen + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoEnterMatrix( &rDocShell, rRange, pUndoDoc, rString ) ); + } + + // Err522 beim Paint von DDE-Formeln werden jetzt beim Interpretieren abgefangen + rDocShell.PostPaint( nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab, PAINT_GRID ); + aModificator.SetDocumentModified(); + + bSuccess = TRUE; + } + else if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + + return bSuccess; +} + +//------------------------------------------------------------------------ + +BOOL ScDocFunc::TabOp( const ScRange& rRange, const ScMarkData* pTabMark, + const ScTabOpParam& rParam, BOOL bRecord, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + BOOL bSuccess = FALSE; + ScDocument* pDoc = rDocShell.GetDocument(); + USHORT nStartCol = rRange.aStart.Col(); + USHORT nStartRow = rRange.aStart.Row(); + USHORT nStartTab = rRange.aStart.Tab(); + USHORT nEndCol = rRange.aEnd.Col(); + USHORT nEndRow = rRange.aEnd.Row(); + USHORT nEndTab = rRange.aEnd.Tab(); + + ScMarkData aMark; + if (pTabMark) + aMark = *pTabMark; + else + { + for (USHORT nTab=nStartTab; nTab<=nEndTab; nTab++) + aMark.SelectTable( nTab, TRUE ); + } + + if ( pDoc->IsSelectedBlockEditable( nStartCol,nStartRow, nEndCol,nEndRow, aMark ) ) + { + WaitObject aWait( rDocShell.GetDialogParent() ); + pDoc->SetDirty( rRange ); + if ( bRecord ) + { + //! auch bei Undo selektierte Tabellen beruecksichtigen + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab ); + pDoc->CopyToDocument( rRange, IDF_ALL, FALSE, pUndoDoc ); + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoTabOp( &rDocShell, + nStartCol, nStartRow, nStartTab, + nEndCol, nEndRow, nEndTab, pUndoDoc, + rParam.aRefFormulaCell, + rParam.aRefFormulaEnd, + rParam.aRefRowCell, + rParam.aRefColCell, + rParam.nMode) ); + } + pDoc->InsertTableOp(rParam, nStartCol, nStartRow, nEndCol, nEndRow, aMark); + rDocShell.PostPaintGridAll(); + aModificator.SetDocumentModified(); + bSuccess = TRUE; + } + else if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + + return bSuccess; +} + +//------------------------------------------------------------------------ + +inline ScDirection DirFromFillDir( FillDir eDir ) +{ + if (eDir==FILL_TO_BOTTOM) + return DIR_BOTTOM; + else if (eDir==FILL_TO_RIGHT) + return DIR_RIGHT; + else if (eDir==FILL_TO_TOP) + return DIR_TOP; + else // if (eDir==FILL_TO_LEFT) + return DIR_LEFT; +} + +BOOL ScDocFunc::FillSimple( const ScRange& rRange, const ScMarkData* pTabMark, + FillDir eDir, BOOL bRecord, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + BOOL bSuccess = FALSE; + ScDocument* pDoc = rDocShell.GetDocument(); + USHORT nStartCol = rRange.aStart.Col(); + USHORT nStartRow = rRange.aStart.Row(); + USHORT nStartTab = rRange.aStart.Tab(); + USHORT nEndCol = rRange.aEnd.Col(); + USHORT nEndRow = rRange.aEnd.Row(); + USHORT nEndTab = rRange.aEnd.Tab(); + + ScMarkData aMark; + if (pTabMark) + aMark = *pTabMark; + else + { + for (USHORT nTab=nStartTab; nTab<=nEndTab; nTab++) + aMark.SelectTable( nTab, TRUE ); + } + + if ( pDoc->IsSelectedBlockEditable( nStartCol,nStartRow, nEndCol,nEndRow, aMark ) ) + { + WaitObject aWait( rDocShell.GetDialogParent() ); + + ScRange aSourceArea = rRange; + ScRange aDestArea = rRange; + + USHORT nCount; + switch (eDir) + { + case FILL_TO_BOTTOM: + nCount = aSourceArea.aEnd.Row()-aSourceArea.aStart.Row(); + aSourceArea.aEnd.SetRow( aSourceArea.aStart.Row() ); + break; + case FILL_TO_RIGHT: + nCount = aSourceArea.aEnd.Col()-aSourceArea.aStart.Col(); + aSourceArea.aEnd.SetCol( aSourceArea.aStart.Col() ); + break; + case FILL_TO_TOP: + nCount = aSourceArea.aEnd.Row()-aSourceArea.aStart.Row(); + aSourceArea.aStart.SetRow( aSourceArea.aEnd.Row() ); + break; + case FILL_TO_LEFT: + nCount = aSourceArea.aEnd.Col()-aSourceArea.aStart.Col(); + aSourceArea.aStart.SetCol( aSourceArea.aEnd.Col() ); + break; + } + + ScDocument* pUndoDoc = NULL; + if ( bRecord ) + { + USHORT nTabCount = pDoc->GetTableCount(); + USHORT nStartTab = aDestArea.aStart.Tab(); + + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab ); + for (USHORT i=0; i<nTabCount; i++) + if (i != nStartTab && aMark.GetTableSelect(i)) + pUndoDoc->AddUndoTab( i, i ); + + ScRange aCopyRange = aDestArea; + aCopyRange.aStart.SetTab(0); + aCopyRange.aEnd.SetTab(nTabCount-1); + pDoc->CopyToDocument( aCopyRange, IDF_ALL, FALSE, pUndoDoc, &aMark ); + pDoc->BeginDrawUndo(); + } + + pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(), + aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark, + nCount, eDir, FILL_SIMPLE ); + AdjustRowHeight(rRange); + + if ( bRecord ) // Draw-Undo erst jetzt verfuegbar + { + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark, + eDir, FILL_SIMPLE, FILL_DAY, MAXDOUBLE, 1.0, 1e307, + pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) ); + } + + rDocShell.PostPaintGridAll(); +// rDocShell.PostPaintDataChanged(); + aModificator.SetDocumentModified(); + + bSuccess = TRUE; + } + else if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + + return bSuccess; +} + +BOOL ScDocFunc::FillSeries( const ScRange& rRange, const ScMarkData* pTabMark, + FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd, + double fStart, double fStep, double fMax, + BOOL bRecord, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + BOOL bSuccess = FALSE; + ScDocument* pDoc = rDocShell.GetDocument(); + USHORT nStartCol = rRange.aStart.Col(); + USHORT nStartRow = rRange.aStart.Row(); + USHORT nStartTab = rRange.aStart.Tab(); + USHORT nEndCol = rRange.aEnd.Col(); + USHORT nEndRow = rRange.aEnd.Row(); + USHORT nEndTab = rRange.aEnd.Tab(); + + ScMarkData aMark; + if (pTabMark) + aMark = *pTabMark; + else + { + for (USHORT nTab=nStartTab; nTab<=nEndTab; nTab++) + aMark.SelectTable( nTab, TRUE ); + } + + if ( pDoc->IsSelectedBlockEditable( nStartCol,nStartRow, nEndCol,nEndRow, aMark ) ) + { + WaitObject aWait( rDocShell.GetDialogParent() ); + + ScRange aSourceArea = rRange; + ScRange aDestArea = rRange; + + USHORT nCount = pDoc->GetEmptyLinesInBlock( + aSourceArea.aStart.Col(), aSourceArea.aStart.Row(), aSourceArea.aStart.Tab(), + aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aSourceArea.aEnd.Tab(), + DirFromFillDir(eDir) ); + + // #27665# mindestens eine Zeile/Spalte als Quellbereich behalten: + USHORT nTotLines = ( eDir == FILL_TO_BOTTOM || eDir == FILL_TO_TOP ) ? + ( aSourceArea.aEnd.Row() - aSourceArea.aStart.Row() + 1 ) : + ( aSourceArea.aEnd.Col() - aSourceArea.aStart.Col() + 1 ); + if ( nCount >= nTotLines ) + nCount = nTotLines - 1; + + switch (eDir) + { + case FILL_TO_BOTTOM: + aSourceArea.aEnd.SetRow( aSourceArea.aEnd.Row() - nCount ); + break; + case FILL_TO_RIGHT: + aSourceArea.aEnd.SetCol( aSourceArea.aEnd.Col() - nCount ); + break; + case FILL_TO_TOP: + aSourceArea.aStart.SetRow( aSourceArea.aStart.Row() + nCount ); + break; + case FILL_TO_LEFT: + aSourceArea.aStart.SetCol( aSourceArea.aStart.Col() + nCount ); + break; + } + + ScDocument* pUndoDoc = NULL; + if ( bRecord ) + { + USHORT nTabCount = pDoc->GetTableCount(); + USHORT nStartTab = aDestArea.aStart.Tab(); + + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab ); + for (USHORT i=0; i<nTabCount; i++) + if (i != nStartTab && aMark.GetTableSelect(i)) + pUndoDoc->AddUndoTab( i, i ); + + pDoc->CopyToDocument( + aDestArea.aStart.Col(), aDestArea.aStart.Row(), 0, + aDestArea.aEnd.Col(), aDestArea.aEnd.Row(), nTabCount-1, + IDF_ALL, FALSE, pUndoDoc, &aMark ); + pDoc->BeginDrawUndo(); + } + + if (aDestArea.aStart.Col() <= aDestArea.aEnd.Col() && + aDestArea.aStart.Row() <= aDestArea.aEnd.Row()) + { + if ( fStart != MAXDOUBLE ) + { + USHORT nValX = (eDir == FILL_TO_LEFT) ? aDestArea.aEnd.Col() : aDestArea.aStart.Col(); + USHORT nValY = (eDir == FILL_TO_TOP ) ? aDestArea.aEnd.Row() : aDestArea.aStart.Row(); + USHORT nTab = aDestArea.aStart.Tab(); + pDoc->SetValue( nValX, nValY, nTab, fStart ); + } + pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(), + aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark, + nCount, eDir, eCmd, eDateCmd, fStep, fMax ); + AdjustRowHeight(rRange); + + rDocShell.PostPaintGridAll(); +// rDocShell.PostPaintDataChanged(); + aModificator.SetDocumentModified(); + } + + if ( bRecord ) // Draw-Undo erst jetzt verfuegbar + { + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark, + eDir, eCmd, eDateCmd, fStart, fStep, fMax, + pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) ); + } + + bSuccess = TRUE; + } + else if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + + return bSuccess; +} + +BOOL ScDocFunc::FillAuto( ScRange& rRange, const ScMarkData* pTabMark, + FillDir eDir, USHORT nCount, BOOL bRecord, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + ScDocument* pDoc = rDocShell.GetDocument(); + USHORT nStartCol = rRange.aStart.Col(); + USHORT nStartRow = rRange.aStart.Row(); + USHORT nStartTab = rRange.aStart.Tab(); + USHORT nEndCol = rRange.aEnd.Col(); + USHORT nEndRow = rRange.aEnd.Row(); + USHORT nEndTab = rRange.aEnd.Tab(); + + ScMarkData aMark; + if (pTabMark) + aMark = *pTabMark; + else + { + for (USHORT nTab=nStartTab; nTab<=nEndTab; nTab++) + aMark.SelectTable( nTab, TRUE ); + } + + ScRange aSourceArea = rRange; + ScRange aDestArea = rRange; + + FillCmd eCmd = FILL_AUTO; + FillDateCmd eDateCmd = FILL_DAY; + double fStep = 1.0; + double fMax = MAXDOUBLE; + + switch (eDir) + { + case FILL_TO_BOTTOM: + aDestArea.aEnd.SetRow( aSourceArea.aEnd.Row() + nCount ); + break; + case FILL_TO_TOP: + if (nCount > aSourceArea.aStart.Row()) + { + DBG_ERROR("FillAuto: Row < 0"); + nCount = aSourceArea.aStart.Row(); + } + aDestArea.aStart.SetRow( aSourceArea.aStart.Row() - nCount ); + break; + case FILL_TO_RIGHT: + aDestArea.aEnd.SetCol( aSourceArea.aEnd.Col() + nCount ); + break; + case FILL_TO_LEFT: + if (nCount > aSourceArea.aStart.Col()) + { + DBG_ERROR("FillAuto: Col < 0"); + nCount = aSourceArea.aStart.Col(); + } + aDestArea.aStart.SetCol( aSourceArea.aStart.Col() - nCount ); + break; + default: + DBG_ERROR("Falsche Richtung bei FillAuto"); + break; + } + + // Zellschutz testen + //! Quellbereich darf geschuetzt sein !!! + //! aber kein Matrixfragment enthalten !!! + + if ( !pDoc->IsBlockEditable(aDestArea.aStart.Tab(), + aDestArea.aStart.Col(), aDestArea.aStart.Row(), + aDestArea.aEnd.Col(), aDestArea.aEnd.Row()) + || pDoc->HasSelectedBlockMatrixFragment( nStartCol, nStartRow, + nEndCol, nEndRow, aMark ) ) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + return FALSE; + } + + WaitObject aWait( rDocShell.GetDialogParent() ); + + ScDocument* pUndoDoc = NULL; + if ( bRecord ) + { + USHORT nTabCount = pDoc->GetTableCount(); + USHORT nStartTab = aDestArea.aStart.Tab(); + + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab ); + for (USHORT i=0; i<nTabCount; i++) + if (i != nStartTab && aMark.GetTableSelect(i)) + pUndoDoc->AddUndoTab( i, i ); + + pDoc->CopyToDocument( + aDestArea.aStart.Col(), aDestArea.aStart.Row(), 0, + aDestArea.aEnd.Col(), aDestArea.aEnd.Row(), nTabCount-1, + IDF_ALL, FALSE, pUndoDoc, &aMark ); + pDoc->BeginDrawUndo(); + } + + pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(), + aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark, + nCount, eDir, eCmd, eDateCmd, fStep, fMax ); + + AdjustRowHeight(aDestArea); + + if ( bRecord ) // Draw-Undo erst jetzt verfuegbar + { + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark, + eDir, eCmd, eDateCmd, MAXDOUBLE, fStep, fMax, + pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) ); + } + + rDocShell.PostPaintGridAll(); +// rDocShell.PostPaintDataChanged(); + aModificator.SetDocumentModified(); + + rRange = aDestArea; // Zielbereich zurueckgeben (zum Markieren) + return TRUE; +} + +//------------------------------------------------------------------------ + +BOOL ScDocFunc::MergeCells( const ScRange& rRange, BOOL bContents, BOOL bRecord, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + ScDocument* pDoc = rDocShell.GetDocument(); + USHORT nStartCol = rRange.aStart.Col(); + USHORT nStartRow = rRange.aStart.Row(); + USHORT nEndCol = rRange.aEnd.Col(); + USHORT nEndRow = rRange.aEnd.Row(); + USHORT nTab = rRange.aStart.Tab(); + + if (!pDoc->IsBlockEditable( nTab, nStartCol, nStartRow, nEndCol, nEndRow )) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + return FALSE; + } + + if ( nStartCol == nEndCol && nStartRow == nEndRow ) + { + // nichts zu tun + return TRUE; + } + + if ( pDoc->HasAttrib( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab, + HASATTR_MERGED | HASATTR_OVERLAPPED ) ) + { + // "Zusammenfassen nicht verschachteln !" + if (!bApi) + rDocShell.ErrorMessage(STR_MSSG_MERGECELLS_0); + return FALSE; + } + + BOOL bNeedContents = bContents && + ( !pDoc->IsBlockEmpty( nTab, nStartCol,nStartRow+1, nStartCol,nEndRow ) || + !pDoc->IsBlockEmpty( nTab, nStartCol+1,nStartRow, nEndCol,nEndRow ) ); + + if (bRecord) + { + ScDocument* pUndoDoc = NULL; + if (bNeedContents && bContents) + { + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, nTab, nTab ); + pDoc->CopyToDocument( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab, + IDF_ALL, FALSE, pUndoDoc ); + } + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoMerge( &rDocShell, + nStartCol, nStartRow, nTab, + nEndCol, nEndRow, nTab, TRUE, pUndoDoc ) ); + } + + if (bNeedContents && bContents) + pDoc->DoMergeContents( nTab, nStartCol,nStartRow, nEndCol,nEndRow ); + pDoc->DoMerge( nTab, nStartCol,nStartRow, nEndCol,nEndRow ); + + if ( !AdjustRowHeight( ScRange( 0,nStartRow,nTab, MAXCOL,nEndRow,nTab ) ) ) + rDocShell.PostPaint( nStartCol, nStartRow, nTab, + nEndCol, nEndRow, nTab, PAINT_GRID ); + if (bNeedContents && bContents) + pDoc->SetDirty( rRange ); + aModificator.SetDocumentModified(); + + SfxBindings& rBindings = SFX_BINDINGS(); + rBindings.Invalidate( FID_MERGE_ON ); + rBindings.Invalidate( FID_MERGE_OFF ); + + return TRUE; +} + +BOOL ScDocFunc::UnmergeCells( const ScRange& rRange, BOOL bRecord, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + ScDocument* pDoc = rDocShell.GetDocument(); + USHORT nTab = rRange.aStart.Tab(); + + if ( pDoc->HasAttrib( rRange, HASATTR_MERGED ) ) + { + ScRange aExtended = rRange; + pDoc->ExtendMerge( aExtended ); + ScRange aRefresh = aExtended; + pDoc->ExtendOverlapped( aRefresh ); + + if (bRecord) + { + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, nTab, nTab ); + pDoc->CopyToDocument( aExtended, IDF_ATTRIB, FALSE, pUndoDoc ); + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoRemoveMerge( &rDocShell, rRange, pUndoDoc ) ); + } + + const SfxPoolItem& rDefAttr = pDoc->GetPool()->GetDefaultItem( ATTR_MERGE ); + ScPatternAttr aPattern( pDoc->GetPool() ); + aPattern.GetItemSet().Put( rDefAttr ); + pDoc->ApplyPatternAreaTab( rRange.aStart.Col(), rRange.aStart.Row(), + rRange.aEnd.Col(), rRange.aEnd.Row(), nTab, + aPattern ); + + pDoc->RemoveFlagsTab( aExtended.aStart.Col(), aExtended.aStart.Row(), + aExtended.aEnd.Col(), aExtended.aEnd.Row(), nTab, + SC_MF_HOR | SC_MF_VER ); + + pDoc->ExtendMerge( aRefresh, TRUE, FALSE ); + + if ( !AdjustRowHeight( aExtended ) ) + rDocShell.PostPaint( aExtended, PAINT_GRID ); + aModificator.SetDocumentModified(); + } + else if (!bApi) + Sound::Beep(); //! FALSE zurueck??? + + return TRUE; +} + +//------------------------------------------------------------------------ + +BOOL ScDocFunc::SetNote( const ScAddress& rPos, const ScPostIt& rNote, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + BOOL bDone = FALSE; + USHORT nCol = rPos.Col(); + USHORT nRow = rPos.Row(); + USHORT nTab = rPos.Tab(); + + ScDocument* pDoc = rDocShell.GetDocument(); + if (pDoc->IsBlockEditable( nTab, nCol,nRow, nCol,nRow )) + { + ScPostIt aOld; + pDoc->GetNote( nCol, nRow, nTab, aOld ); + pDoc->SetNote( nCol, nRow, nTab, rNote ); + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoEditNote( &rDocShell, rPos, aOld, rNote ) ); + + rDocShell.PostPaintCell( nCol, nRow, nTab ); + aModificator.SetDocumentModified(); + bDone = TRUE; + } + else if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + + return bDone; +} + +//------------------------------------------------------------------------ + +BOOL ScDocFunc::ModifyRangeNames( const ScRangeName& rNewRanges, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + ScDocument* pDoc = rDocShell.GetDocument(); + + ScRangeName* pOld = pDoc->GetRangeName(); + ScRangeName* pUndoRanges = new ScRangeName(*pOld); + ScRangeName* pRedoRanges = new ScRangeName(rNewRanges); + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoRangeNames( &rDocShell, pUndoRanges, pRedoRanges ) ); + + pDoc->CompileNameFormula( TRUE ); // CreateFormulaString + pDoc->SetRangeName( new ScRangeName( rNewRanges ) ); + pDoc->CompileNameFormula( FALSE ); // CompileFormulaString + + aModificator.SetDocumentModified(); + SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) ); + + return TRUE; +} + +//------------------------------------------------------------------------ + +void ScDocFunc::CreateOneName( ScRangeName& rList, + USHORT nPosX, USHORT nPosY, USHORT nTab, + USHORT nX1, USHORT nY1, USHORT nX2, USHORT nY2, + BOOL& rCancel, BOOL bApi ) +{ + if (rCancel) + return; + + ScDocument* pDoc = rDocShell.GetDocument(); + if (!pDoc->HasValueData( nPosX, nPosY, nTab )) + { + String aName; + pDoc->GetString( nPosX, nPosY, nTab, aName ); + ScRangeData::MakeValidName(aName); + if (aName.Len()) + { + String aContent; + ScRangeUtil().MakeAreaString( ScArea( nTab,nX1,nY1,nX2,nY2 ), + aContent, pDoc, FALSE ); + + ScRangeName* pList = pDoc->GetRangeName(); + + BOOL bInsert = FALSE; + USHORT nOldPos; + if (rList.SearchName( aName, nOldPos )) // vorhanden ? + { + ScRangeData* pOld = rList[nOldPos]; + String aOldStr; + pOld->GetSymbol( aOldStr ); + if (aOldStr != aContent) + { + if (bApi) + bInsert = TRUE; // per API nicht nachfragen + else + { + String aTemplate = ScGlobal::GetRscString( STR_CREATENAME_REPLACE ); + + String aMessage = aTemplate.GetToken( 0, '#' ); + aMessage += aName; + aMessage += aTemplate.GetToken( 1, '#' ); + + short nResult = QueryBox( rDocShell.GetDialogParent(), + WinBits(WB_YES_NO_CANCEL | WB_DEF_YES), + aMessage ).Execute(); + if ( nResult == RET_YES ) + { + rList.AtFree(nOldPos); + bInsert = TRUE; + } + else if ( nResult == RET_CANCEL ) + rCancel = TRUE; + } + } + } + else + bInsert = TRUE; + + if (bInsert) + { + ScRangeData* pData = new ScRangeData( pDoc, aName, aContent, nPosX, nPosY, nTab ); + if (!rList.Insert(pData)) + { + DBG_ERROR("nanu?"); + delete pData; + } + } + } + } +} + +BOOL ScDocFunc::CreateNames( const ScRange& rRange, USHORT nFlags, BOOL bApi ) +{ + if (!nFlags) + return FALSE; // war nix + + ScDocShellModificator aModificator( rDocShell ); + + BOOL bDone = FALSE; + USHORT nStartCol = rRange.aStart.Col(); + USHORT nStartRow = rRange.aStart.Row(); + USHORT nEndCol = rRange.aEnd.Col(); + USHORT nEndRow = rRange.aEnd.Row(); + USHORT nTab = rRange.aStart.Tab(); + DBG_ASSERT(rRange.aEnd.Tab() == nTab, "CreateNames: mehrere Tabellen geht nicht"); + + BOOL bValid = TRUE; + if ( nFlags & ( NAME_TOP | NAME_BOTTOM ) ) + if ( nStartRow == nEndRow ) + bValid = FALSE; + if ( nFlags & ( NAME_LEFT | NAME_RIGHT ) ) + if ( nStartCol == nEndCol ) + bValid = FALSE; + + if (bValid) + { + ScDocument* pDoc = rDocShell.GetDocument(); + ScRangeName* pNames = pDoc->GetRangeName(); + if (!pNames) + return FALSE; // soll nicht sein + ScRangeName aNewRanges( *pNames ); + + BOOL bTop = ( ( nFlags & NAME_TOP ) != 0 ); + BOOL bLeft = ( ( nFlags & NAME_LEFT ) != 0 ); + BOOL bBottom = ( ( nFlags & NAME_BOTTOM ) != 0 ); + BOOL bRight = ( ( nFlags & NAME_RIGHT ) != 0 ); + + USHORT nContX1 = nStartCol; + USHORT nContY1 = nStartRow; + USHORT nContX2 = nEndCol; + USHORT nContY2 = nEndRow; + + if ( bTop ) + ++nContY1; + if ( bLeft ) + ++nContX1; + if ( bBottom ) + --nContY2; + if ( bRight ) + --nContX2; + + BOOL bCancel = FALSE; + USHORT i; + + if ( bTop ) + for (i=nContX1; i<=nContX2; i++) + CreateOneName( aNewRanges, i,nStartRow,nTab, i,nContY1,i,nContY2, bCancel, bApi ); + if ( bLeft ) + for (i=nContY1; i<=nContY2; i++) + CreateOneName( aNewRanges, nStartCol,i,nTab, nContX1,i,nContX2,i, bCancel, bApi ); + if ( bBottom ) + for (i=nContX1; i<=nContX2; i++) + CreateOneName( aNewRanges, i,nEndRow,nTab, i,nContY1,i,nContY2, bCancel, bApi ); + if ( bRight ) + for (i=nContY1; i<=nContY2; i++) + CreateOneName( aNewRanges, nEndCol,i,nTab, nContX1,i,nContX2,i, bCancel, bApi ); + + if ( bTop && bLeft ) + CreateOneName( aNewRanges, nStartCol,nStartRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi ); + if ( bTop && bRight ) + CreateOneName( aNewRanges, nEndCol,nStartRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi ); + if ( bBottom && bLeft ) + CreateOneName( aNewRanges, nStartCol,nEndRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi ); + if ( bBottom && bRight ) + CreateOneName( aNewRanges, nEndCol,nEndRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi ); + + bDone = ModifyRangeNames( aNewRanges, bApi ); + + aModificator.SetDocumentModified(); + SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) ); + } + + return bDone; +} + +//------------------------------------------------------------------------ + +BOOL ScDocFunc::InsertNameList( const ScAddress& rStartPos, BOOL bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); + + const BOOL bRecord=TRUE; + + BOOL bDone = FALSE; + ScDocument* pDoc = rDocShell.GetDocument(); + USHORT nTab = rStartPos.Tab(); + ScDocument* pUndoDoc = NULL; + + ScRangeName* pList = pDoc->GetRangeName(); + USHORT nCount = pList->GetCount(); + USHORT nValidCount = 0; + USHORT i; + for (i=0; i<nCount; i++) + { + ScRangeData* pData = (*pList)[i]; + if ( !pData->HasType( RT_DATABASE ) && !pData->HasType( RT_SHARED ) ) + ++nValidCount; + } + + if (nValidCount) + { + USHORT nStartCol = rStartPos.Col(); + USHORT nStartRow = rStartPos.Row(); + USHORT nEndCol = nStartCol + 1; + USHORT nEndRow = nStartRow + nValidCount - 1; + + if (pDoc->IsBlockEditable( nTab, nStartCol,nStartRow, nEndCol,nEndRow )) + { + if (bRecord) + { + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, nTab, nTab ); + pDoc->CopyToDocument( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab, + IDF_ALL, FALSE, pUndoDoc ); + + pDoc->BeginDrawUndo(); // wegen Hoehenanpassung + } + + ScRangeData** ppSortArray = new ScRangeData* [ nValidCount ]; + USHORT j = 0; + for (i=0; i<nCount; i++) + { + ScRangeData* pData = (*pList)[i]; + if ( !pData->HasType( RT_DATABASE ) && !pData->HasType( RT_SHARED ) ) + ppSortArray[j++] = pData; + } +#ifndef ICC + qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*), + &ScRangeData::QsortNameCompare ); +#else + qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*), + ICCQsortNameCompare ); +#endif + String aName; + String aContent; + String aFormula; + USHORT nOutRow = nStartRow; + for (j=0; j<nValidCount; j++) + { + ScRangeData* pData = ppSortArray[j]; + pData->GetName(aName); + // relative Referenzen Excel-konform auf die linke Spalte anpassen: + pData->UpdateSymbol(aContent, ScAddress( nStartCol, nOutRow, nTab )); + aFormula = '='; + aFormula += aContent; + pDoc->PutCell( nStartCol,nOutRow,nTab, new ScStringCell( aName ) ); + pDoc->PutCell( nEndCol ,nOutRow,nTab, new ScStringCell( aFormula ) ); + ++nOutRow; + } + + delete [] ppSortArray; + + if (bRecord) + { + ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO ); + pRedoDoc->InitUndo( pDoc, nTab, nTab ); + pDoc->CopyToDocument( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab, + IDF_ALL, FALSE, pRedoDoc ); + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoListNames( &rDocShell, + ScRange( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab ), + pUndoDoc, pRedoDoc ) ); + } + + if (!AdjustRowHeight(ScRange(0,nStartRow,nTab,MAXCOL,nEndRow,nTab))) + rDocShell.PostPaint( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab, PAINT_GRID ); +//! rDocShell.UpdateOle(GetViewData()); + aModificator.SetDocumentModified(); + bDone = TRUE; + } + else if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); + } + return bDone; +} + +//------------------------------------------------------------------------ + +BOOL ScDocFunc::ResizeMatrix( const ScRange& rOldRange, const ScAddress& rNewEnd, BOOL bApi ) +{ + ScDocument* pDoc = rDocShell.GetDocument(); + USHORT nStartCol = rOldRange.aStart.Col(); + USHORT nStartRow = rOldRange.aStart.Row(); + USHORT nNewEndCol = rNewEnd.Col(); + USHORT nNewEndRow = rNewEnd.Row(); + USHORT nTab = rOldRange.aStart.Tab(); + + BOOL bRet = FALSE; + + String aFormula; + pDoc->GetFormula( nStartCol, nStartRow, nTab, aFormula ); + if ( aFormula.GetChar(0) == '{' && aFormula.GetChar(aFormula.Len()-1) == '}' ) + { + String aUndo = ScGlobal::GetRscString( STR_UNDO_RESIZEMATRIX ); + rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo ); + + aFormula.Erase(0,1); + aFormula.Erase(aFormula.Len()-1,1); + + ScMarkData aMark; + aMark.SetMarkArea( rOldRange ); + aMark.SelectTable( nTab, TRUE ); + ScRange aNewRange( rOldRange.aStart, rNewEnd ); + + if ( DeleteContents( aMark, IDF_CONTENTS, TRUE, bApi ) ) + { + bRet = EnterMatrix( aNewRange, &aMark, aFormula, bApi ); + if (!bRet) + { + // versuchen, alten Zustand wiederherzustellen + EnterMatrix( rOldRange, &aMark, aFormula, bApi ); + } + } + + rDocShell.GetUndoManager()->LeaveListAction(); + } + + return bRet; +} + +//------------------------------------------------------------------------ + +BOOL ScDocFunc::InsertAreaLink( const String& rFile, const String& rFilter, + const String& rOptions, const String& rSource, + const ScRange& rDestRange, BOOL bFitBlock, BOOL bApi ) +{ + //! auch fuer ScViewFunc::InsertAreaLink benutzen! + + ScDocument* pDoc = rDocShell.GetDocument(); + + String aFilterName = rFilter; + String aNewOptions = rOptions; + if (!aFilterName.Len()) + ScDocumentLoader::GetFilterName( rFile, aFilterName, aNewOptions ); + + SvxLinkManager* pLinkManager = pDoc->GetLinkManager(); + + ScAreaLink* pLink = new ScAreaLink( &rDocShell, rFile, aFilterName, + aNewOptions, rSource, rDestRange ); + pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, rFile, &aFilterName, &rSource ); + + // Undo fuer den leeren Link + + rDocShell.GetUndoManager()->AddUndoAction( new ScUndoInsertAreaLink( &rDocShell, + rFile, aFilterName, aNewOptions, + rSource, rDestRange ) ); + + // Update hat sein eigenes Undo + + pLink->SetDoInsert(bFitBlock); // beim ersten Update ggf. nichts einfuegen + pLink->Update(); // kein SetInCreate -> Update ausfuehren + pLink->SetDoInsert(TRUE); // Default = TRUE + + SfxBindings& rBindings = SFX_BINDINGS(); + rBindings.Invalidate( SID_LINKS ); + + SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); // Navigator + + return TRUE; +} + + + + diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx new file mode 100644 index 000000000000..fd109b57162c --- /dev/null +++ b/sc/source/ui/docshell/docsh.cxx @@ -0,0 +1,2748 @@ +/************************************************************************* + * + * $RCSfile: docsh.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +// System - Includes ----------------------------------------------------- + +#ifdef PCH +#include "ui_pch.hxx" +#endif + + +#include "scitems.hxx" + +#include <sdb/sdbcol.hxx> +#include <sdb/sdbconn.hxx> +#include <sdb/sdbtab.hxx> + +#include <sfx2/sfx.hrc> +#include <sfx2/app.hxx> +#include <sfx2/topfrm.hxx> +#include <vcl/exchange.hxx> +#include <offmgr/app.hxx> +#include <svx/srchitem.hxx> +#include <svtools/zforlist.hxx> +#include <svtools/sfxecode.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/docfilt.hxx> +#include <sfx2/evntconf.hxx> +#include <svtools/stritem.hxx> +#include <vcl/msgbox.hxx> +#include <tools/stream.hxx> +#include <tools/string.hxx> +#include <vcl/virdev.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/dinfdlg.hxx> +#include <svtools/ctrltool.hxx> +#include <so3/clsids.hxx> +#include <svtools/converter.hxx> +#include <offmgr/fltrcfg.hxx> +#include <svx/svxmsbas.hxx> +#include <vcl/waitobj.hxx> +#include <unotools/charclass.hxx> + +#include <sot/formats.hxx> +#define SOT_FORMATSTR_ID_STARCALC_30 SOT_FORMATSTR_ID_STARCALC + +#include <offmgr/sbaobj.hxx> + +#ifndef SO2_DECL_SVSTORAGESTREAM_DEFINED +#define SO2_DECL_SVSTORAGESTREAM_DEFINED +SO2_DECL_REF(SvStorageStream) +#endif + +// INCLUDE --------------------------------------------------------------- + +#include "docoptio.hxx" // fuer SbaSdbExport +#include "cell.hxx" // fuer SbaSdbExport + +#include "global.hxx" +#include "filter.hxx" +#include "scmod.hxx" +#include "dbdocfun.hxx" +#include "tabvwsh.hxx" +#include "docfunc.hxx" +#include "imoptdlg.hxx" +#include "impex.hxx" +#include "scresid.hxx" +#include "sc.hrc" +#include "globstr.hrc" +#include "printfun.hxx" +#include "tpstat.hxx" +#include "scerrors.hxx" +#include "brdcst.hxx" +#include "stlpool.hxx" +#include "autostyl.hxx" +#include "attrib.hxx" +#include "asciiopt.hxx" +#include "waitoff.hxx" +#include "docpool.hxx" // LoadCompleted +#include "progress.hxx" +#include "pntlock.hxx" +#include "collect.hxx" +#include "docuno.hxx" +#include "appoptio.hxx" +#include "detdata.hxx" +#include "printfun.hxx" // ScJobSetup +#include "dociter.hxx" +#include "cellform.hxx" +#include "chartlis.hxx" +#include "hints.hxx" +#include "xmlwrap.hxx" + +#include "docsh.hxx" + +// STATIC DATA ----------------------------------------------------------- + +// Stream-Namen im Storage + +const sal_Char __FAR_DATA ScDocShell::pStarCalcDoc[] = STRING_SCSTREAM; // "StarCalcDocument" +const sal_Char __FAR_DATA ScDocShell::pStyleName[] = "SfxStyleSheets"; + +// Filter-Namen (wie in sclib.cxx) + +static const sal_Char __FAR_DATA pFilterSc50[] = "StarCalc 5.0"; +//static const sal_Char __FAR_DATA pFilterSc50Temp[] = "StarCalc 5.0 Vorlage/Template"; +static const sal_Char __FAR_DATA pFilterSc40[] = "StarCalc 4.0"; +//static const sal_Char __FAR_DATA pFilterSc40Temp[] = "StarCalc 4.0 Vorlage/Template"; +static const sal_Char __FAR_DATA pFilterSc30[] = "StarCalc 3.0"; +//static const sal_Char __FAR_DATA pFilterSc30Temp[] = "StarCalc 3.0 Vorlage/Template"; +static const sal_Char __FAR_DATA pFilterSc10[] = "StarCalc 1.0"; +static const sal_Char __FAR_DATA pFilterXML[] = "StarOffice XML (Calc)"; +static const sal_Char __FAR_DATA pFilterAscii[] = "Text - txt - csv (StarCalc)"; +static const sal_Char __FAR_DATA pFilterLotus[] = "Lotus"; +static const sal_Char __FAR_DATA pFilterExcel4[] = "MS Excel 4.0"; +static const sal_Char __FAR_DATA pFilterEx4Temp[] = "MS Excel 4.0 Vorlage/Template"; +static const sal_Char __FAR_DATA pFilterExcel5[] = "MS Excel 5.0/95"; +static const sal_Char __FAR_DATA pFilterEx5Temp[] = "MS Excel 5.0/95 Vorlage/Template"; +static const sal_Char __FAR_DATA pFilterExcel95[] = "MS Excel 95"; +static const sal_Char __FAR_DATA pFilterEx95Temp[] = "MS Excel 95 Vorlage/Template"; +static const sal_Char __FAR_DATA pFilterExcel97[] = "MS Excel 97"; +static const sal_Char __FAR_DATA pFilterEx97Temp[] = "MS Excel 97 Vorlage/Template"; +static const sal_Char __FAR_DATA pFilterDBase[] = "dBase"; +static const sal_Char __FAR_DATA pFilterDif[] = "DIF"; +static const sal_Char __FAR_DATA pFilterSylk[] = "SYLK"; +static const sal_Char __FAR_DATA pFilterHtml[] = "HTML (StarCalc)"; +static const sal_Char __FAR_DATA pFilterRtf[] = "Rich Text Format (StarCalc)"; + +//---------------------------------------------------------------------- + +#define ScDocShell +#include "scslots.hxx" + + +SFX_IMPL_INTERFACE(ScDocShell,SfxObjectShell, ScResId(SCSTR_DOCSHELL)) +{} + +// GlobalName der aktuellen Version: +SFX_IMPL_OBJECTFACTORY_DLL(ScDocShell, SFXOBJECTSHELL_STD_NORMAL, + SvGlobalName(SO3_SC_CLASSID), Sc) + +TYPEINIT1( ScDocShell, SfxObjectShell ); // SfxInPlaceObject: kein Type-Info ? + +//------------------------------------------------------------------ + +void __EXPORT ScDocShell::FillClass( SvGlobalName* pClassName, + ULONG* pFormat, + String* pAppName, + String* pFullTypeName, + String* pShortTypeName, + long nFileFormat ) const +{ + SfxInPlaceObject::FillClass( pClassName, pFormat, pAppName, + pFullTypeName, pShortTypeName, nFileFormat ); + + if ( nFileFormat == SOFFICE_FILEFORMAT_31 ) + { + *pClassName = SvGlobalName( SO3_SC_CLASSID_30 ); + *pFormat = SOT_FORMATSTR_ID_STARCALC_30; + *pAppName = String( ScResId( SCSTR_30_APPLICATION ) ); + *pFullTypeName = String( ScResId( SCSTR_30_LONG_DOCNAME ) ); + *pShortTypeName = String( ScResId( SCSTR_SHORT_SCDOC_NAME ) ); + } + else if ( nFileFormat == SOFFICE_FILEFORMAT_40 ) + { + *pClassName = SvGlobalName( SO3_SC_CLASSID_40 ); + *pFormat = SOT_FORMATSTR_ID_STARCALC_40; + *pAppName = String( ScResId( SCSTR_40_APPLICATION ) ); + *pFullTypeName = String( ScResId( SCSTR_40_LONG_DOCNAME ) ); + *pShortTypeName = String( ScResId( SCSTR_SHORT_SCDOC_NAME ) ); + } + else if ( nFileFormat == SOFFICE_FILEFORMAT_NOW ) + { + *pFullTypeName = String( ScResId( SCSTR_LONG_SCDOC_NAME ) ); + *pShortTypeName = String( ScResId( SCSTR_SHORT_SCDOC_NAME ) ); + } + else + DBG_ERROR("wat fuer ne Version?"); +} + +//------------------------------------------------------------------ + +void __EXPORT ScDocShell::FillRegInfo( SvEmbeddedRegistryInfo* pInfo ) +{ + SfxInPlaceObject::FillRegInfo( pInfo ); + + pInfo->aObjName = String::CreateFromAscii(pStarCalcDoc); + pInfo->nMajorVers = 5; + pInfo->nMinorVers = 0; + pInfo->aHumanShortTypeName = String( ScResId( SCSTR_HUMAN_SCDOC_NAME ) ); + + //! nIconResId nur, wenn Desktop? + + pInfo->nIconResId = REG_ICON_RESID_CALC; + + // nShell und aExt sind schon gefuellt +} + +//------------------------------------------------------------------ + +void ScDocShell::DoEnterHandler() +{ + ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); + if (pViewSh) + if (pViewSh->GetViewData()->GetDocShell() == this) + SC_MOD()->InputEnterHandler(); +} + +//------------------------------------------------------------------ + +USHORT ScDocShell::GetSaveTab() +{ + USHORT nTab = 0; + ScTabViewShell* pSh = GetBestViewShell(); + if (pSh) + { + const ScMarkData& rMark = pSh->GetViewData()->GetMarkData(); + for ( nTab = 0; nTab <= MAXTAB; nTab++ ) // erste markierte Tabelle + if ( rMark.GetTableSelect( nTab ) ) + break; + } + return nTab; +} + +//------------------------------------------------------------------ + +inline IsAsciiDigit( sal_Unicode c ) +{ + return 0x31 <= c && c <= 0x39; +} + +inline IsAsciiAlpha( sal_Unicode c ) +{ + return (0x41 <= c && c <= 0x5a) || (0x61 <= c && c <= 0x7a); +} + + +ULONG ScDocShell::SbaSdbExport( BOOL& bHasMemo, const String& rParStr, + const String& aFileName ) +{ + + ULONG nErr = eERR_OK; + bHasMemo = FALSE; + SbaObject* pSbaObject = ((OfficeApplication*)SFX_APP())->GetSbaObject(); + DBG_ASSERT( pSbaObject, "pSbaObject==NULL" ); + SdbConnectionRef xConnect = pSbaObject->OpenConnection( rParStr ); + + if ( !xConnect.Is() || !xConnect->Status().IsSuccessful() ) + return SCERR_EXPORT_CONNECT; + + SdbTableRef xTable = xConnect->CreateTable( aFileName ); // Erzeugen der Tabellenstruktur + if ( !xTable.Is() ) + return SCERR_EXPORT_CURSOR; + + SdbColumnsRef xTblCol = xTable->Columns(); // leere Struktur holen + + USHORT nFirstCol, nFirstRow, nLastCol, nLastRow, nCol, nRow; + + USHORT nTab = GetSaveTab(); + aDocument.GetDataStart( nTab, nFirstCol, nFirstRow ); + aDocument.GetCellArea( nTab, nLastCol, nLastRow ); + ScProgress aProgress( this, ScGlobal::GetRscString( STR_SAVE_DOC ), + nLastRow - nFirstRow ); + SvNumberFormatter* pNumFmt = aDocument.GetFormatTable(); + String aFieldName, aString, aOutString; + SdbDatabaseType eDbType; + xub_StrLen nFieldLen; + USHORT nPrecision; + BOOL bTypeDefined, bPrecDefined; + StrCollection aFieldNamesCollection; + BOOL bHasFieldNames = TRUE; + for ( nCol = nFirstCol; nCol <= nLastCol && bHasFieldNames; nCol++ ) + { // nur Strings in erster Zeile => sind Feldnamen + if ( !aDocument.HasStringData( nCol, nFirstRow, nTab ) ) + bHasFieldNames = FALSE; + } + USHORT nFirstDataRow = ( bHasFieldNames ? nFirstRow + 1 : nFirstRow ); + for ( nCol = nFirstCol; nCol <= nLastCol; nCol++ ) + { + bTypeDefined = FALSE; + bPrecDefined = FALSE; + nFieldLen = 0; + nPrecision = 0; + // Feldname[,Type[,Width[,Prec]]] + // Typ etc.: L; D; C[,W]; N[,W[,P]] + if ( bHasFieldNames ) + { + aDocument.GetString( nCol, nFirstRow, nTab, aString ); + aString.ToUpperAscii(); + xub_StrLen nToken = aString.GetTokenCount( ',' ); + if ( nToken > 1 ) + { + aFieldName = aString.GetToken( 0, ',' ); + aString.EraseAllChars( ' ' ); + switch ( aString.GetToken( 1, ',' ).GetChar(0) ) + { + case 'L' : + eDbType = SDB_DBTYPE_BOOLEAN; + nFieldLen = 1; + bTypeDefined = TRUE; + bPrecDefined = TRUE; + break; + case 'D' : + eDbType = SDB_DBTYPE_DATE; + nFieldLen = 8; + bTypeDefined = TRUE; + bPrecDefined = TRUE; + break; + case 'M' : + eDbType = SDB_DBTYPE_LONGVARCHAR; + nFieldLen = 10; + bTypeDefined = TRUE; + bPrecDefined = TRUE; + bHasMemo = TRUE; + break; + case 'C' : + eDbType = SDB_DBTYPE_VARCHAR; + bTypeDefined = TRUE; + bPrecDefined = TRUE; + break; + case 'N' : + eDbType = SDB_DBTYPE_DECIMAL; + bTypeDefined = TRUE; + break; + } + if ( bTypeDefined && !nFieldLen && nToken > 2 ) + { + nFieldLen = aString.GetToken( 2, ',' ).ToInt32(); + if ( !bPrecDefined && nToken > 3 ) + { + String aTmp( aString.GetToken( 3, ',' ) ); + if ( CharClass::isAsciiNumeric(aTmp) ) + { + nPrecision = aTmp.ToInt32(); + bPrecDefined = TRUE; + } + } + } + } + else + aFieldName = aString; + + // Feldnamen pruefen und ggbf. gueltigen Feldnamen erzeugen. + // Erstes Zeichen muss Buchstabe sein, + // weitere nur alphanumerisch und Unterstrich erlaubt, + // "_DBASELOCK" ist reserviert (obsolet weil erstes Zeichen kein Buchstabe), + // keine doppelten Namen. + if ( !IsAsciiAlpha( aFieldName.GetChar(0) ) ) + aFieldName.Insert( 'N', 0 ); + String aTmpStr; + sal_Unicode c; + for ( const sal_Unicode* p = aFieldName.GetBuffer(); c = *p; p++ ) + { + if ( IsAsciiAlpha( c ) || IsAsciiDigit( c ) || c == '_' ) + aTmpStr += c; + else + aTmpStr += '_'; + } + aFieldName = aTmpStr; + if ( aFieldName.Len() > 10 ) + aFieldName.Erase( 10 ); + StrData* pStrData = new StrData( aFieldName ); + if ( !aFieldNamesCollection.Insert( pStrData ) ) + { // doppelter Feldname, numerisch erweitern + USHORT nSub = 1; + String aFixPart( aFieldName ); + do + { + ++nSub; + String aVarPart = String::CreateFromInt32( nSub ); + if ( aFixPart.Len() + aVarPart.Len() > 10 ) + aFixPart.Erase( 10 - aVarPart.Len() ); + aFieldName = aFixPart; + aFieldName += aVarPart; + pStrData->SetString( aFieldName ); + } while ( !aFieldNamesCollection.Insert( pStrData ) ); + } + } + else + { + aFieldName = 'N'; + aFieldName += String::CreateFromInt32(nCol+1); + } + + if ( !bTypeDefined ) + { // Feldtyp + ScBaseCell* pCell; + aDocument.GetCell( nCol, nFirstDataRow, nTab, pCell ); + if ( !pCell || pCell->HasStringData() ) + eDbType = SDB_DBTYPE_VARCHAR; + else + { + ULONG nFormat; + aDocument.GetNumberFormat( nCol, nFirstDataRow, nTab, nFormat ); + if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA + && ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0) ) + { + nFormat = ScGlobal::GetStandardFormat( + ((ScFormulaCell*)pCell)->GetValue(), *pNumFmt, nFormat, + ((ScFormulaCell*)pCell)->GetFormatType() ); + } + switch ( pNumFmt->GetType( nFormat ) ) + { + case NUMBERFORMAT_LOGICAL : + eDbType = SDB_DBTYPE_BOOLEAN; + nFieldLen = 1; + break; + case NUMBERFORMAT_DATE : + eDbType = SDB_DBTYPE_DATE; + nFieldLen = 8; + break; + case NUMBERFORMAT_TIME : + case NUMBERFORMAT_DATETIME : + eDbType = SDB_DBTYPE_VARCHAR; + break; + default: + eDbType = SDB_DBTYPE_DECIMAL; + } + } + } + BOOL bSdbLenAdjusted = FALSE; + BOOL bSdbLenBad = FALSE; + // Feldlaenge + if ( eDbType == SDB_DBTYPE_VARCHAR && !nFieldLen ) + { // maximale Feldbreite bestimmen + nFieldLen = aDocument.GetMaxStringLen( nTab, nCol, nFirstDataRow, + nLastRow ); + if ( nFieldLen == 0 ) + nFieldLen = 1; + } + else if ( eDbType == SDB_DBTYPE_DECIMAL ) + { // maximale Feldbreite und Nachkommastellen bestimmen + xub_StrLen nLen; + USHORT nPrec; + nLen = aDocument.GetMaxNumberStringLen( nPrec, nTab, nCol, + nFirstDataRow, nLastRow ); + // dBaseIII Limit Nachkommastellen: 15 + if ( nPrecision > 15 ) + nPrecision = 15; + if ( nPrec > 15 ) + nPrec = 15; + if ( bPrecDefined && nPrecision != nPrec ) + { // Laenge auf vorgegebene Nachkommastellen anpassen + if ( nPrecision ) + nLen += nPrecision - nPrec; + else + nLen -= nPrec+1; // auch den . mit raus + } + if ( nLen > nFieldLen ) + nFieldLen = nLen; + if ( !bPrecDefined ) + nPrecision = nPrec; + if ( nFieldLen == 0 ) + nFieldLen = 1; + else if ( nFieldLen > 19 ) + nFieldLen = 19; // dBaseIII Limit Feldlaenge numerisch: 19 + if ( nPrecision && nFieldLen < nPrecision + 2 ) + nFieldLen = nPrecision + 2; // 0. muss mit reinpassen + // 538 MUST: Sdb internal representation adds 2 to the field length! + // To give the user what he wants we must substract it here. + //! CAVEAT! There is no way to define a numeric field with a length + //! of 1 and no decimals! + if ( nFieldLen == 1 && nPrecision == 0 ) + bSdbLenBad = TRUE; + nFieldLen = SvDbaseConverter::ConvertPrecisionToOdbc( nFieldLen, nPrecision ); + bSdbLenAdjusted = TRUE; + } + if ( nFieldLen > 254 ) + { + if ( eDbType == SDB_DBTYPE_VARCHAR ) + { // zu lang fuer normales Textfeld => Memofeld + eDbType = SDB_DBTYPE_LONGVARCHAR; + nFieldLen = 10; + bHasMemo = TRUE; + } + else + nFieldLen = 254; // dumm gelaufen.. + } + xTblCol->AddColumn( xConnect->CreateColumn( + aFieldName, // feld name (max 10 Zeichen) + eDbType, // typ + nFieldLen, // feldlaenge + nPrecision)); // Nachkommastellen + // undo change to field length, reflect reality + if ( bSdbLenAdjusted ) + { + nFieldLen = SvDbaseConverter::ConvertPrecisionToDbase( nFieldLen, nPrecision ); + if ( bSdbLenBad && nFieldLen == 1 ) + nFieldLen = 2; // THIS is reality + } + if ( bTypeDefined ) + { // Angabe anpassen und ausgeben + aOutString = aFieldName; + switch ( eDbType ) + { + case SDB_DBTYPE_BOOLEAN : + aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",L" )); + break; + case SDB_DBTYPE_DATE : + aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",D" )); + break; + case SDB_DBTYPE_LONGVARCHAR : + aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",M" )); + break; + case SDB_DBTYPE_VARCHAR : + aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",C," )); + aOutString += String::CreateFromInt32( nFieldLen ); + break; + case SDB_DBTYPE_DECIMAL : + aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",N," )); + aOutString += String::CreateFromInt32( nFieldLen ); + aOutString += ','; + aOutString += String::CreateFromInt32( nPrecision ); + break; + } + if ( !aOutString.EqualsIgnoreCaseAscii( aString ) ) + { + aDocument.SetString( nCol, nFirstRow, nTab, aOutString ); + PostPaint( nCol, nFirstRow, nTab, nCol, nFirstRow, nTab, PAINT_GRID ); + } + } + } + xTable->Update(); + + if ( xTable->Status().IsError() ) + nErr = SCERR_EXPORT_CURSOR; + else + { + SdbCursorRef xCur = xConnect->CreateCursor( SDB_KEYSET, SDB_APPENDONLY ); + SdbCursor* pCur = &xCur; + DBG_ASSERT( pCur, "Cursor" ); + pCur->Open( aFileName, TRUE ); + + if ( !pCur->Status().IsError() ) + { + USHORT nIdx; + double fVal; + Date aDate; + SvNumberFormatter& rFormatter = *aDocument.GetFormatTable(); + ScFieldEditEngine aEditEngine( aDocument.GetEditPool() ); + for ( nRow = nFirstDataRow; nRow <= nLastRow; nRow++ ) + { + pCur->AppendRow(); + for ( nCol = nFirstCol, nIdx = 1; nCol <= nLastCol; nCol++, nIdx++ ) + { + ODbVariantRef xVar = (*pCur->GetRow())[nIdx]; + const SdbColumn* pCol = xTblCol->Column( nIdx ); + SdbDatabaseType eType = pCol->GetType(); + switch ( eType ) + { + case SDB_DBTYPE_LONGVARCHAR : + { + ScBaseCell* pCell; + aDocument.GetCell( nCol, nRow, nTab, pCell ); + if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE ) + { + if ( pCell->GetCellType() == CELLTYPE_EDIT ) + { // #60761# Paragraphs erhalten + aEditEngine.SetText( *((ScEditCell*)pCell)->GetData() ); + aString = aEditEngine.GetText( LINEEND_CRLF ); + } + else + { + ULONG nFormat; + Color* pColor; + aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat ); + ScCellFormat::GetString( pCell, nFormat, aString, &pColor, rFormatter ); + } + xVar->setString( aString ); + } + else + xVar->setVoid(); + } + break; + case SDB_DBTYPE_VARCHAR : + aDocument.GetString( nCol, nRow, nTab, aString ); + xVar->setString( aString ); + if ( nErr == eERR_OK && pCol->GetLength() < aString.Len() ) + nErr = SCWARN_EXPORT_DATALOST; + break; + case SDB_DBTYPE_DATE : + { + aDocument.GetValue( nCol, nRow, nTab, fVal ); + // #39274# zwischen 0 Wert und 0 kein Wert unterscheiden + BOOL bIsNull = (fVal == 0.0); + if ( bIsNull ) + bIsNull = !aDocument.HasValueData( nCol, nRow, nTab ); + if ( bIsNull ) + { + xVar->setVoid(); // sonst Basic-NullDate + if ( nErr == eERR_OK && + aDocument.HasStringData( nCol, nRow, nTab ) ) + nErr = SCWARN_EXPORT_DATALOST; + } + else + { + // unser NullDate: 30.12.1899 / 1.1.1900 / 1.1.1904 + aDate = *(pNumFmt->GetNullDate()); + aDate += (long)fVal; + // Basic NullDate: 30.12.1899 + //pVar->PutDate( (double)( aDate - Date(30,12,1899) ) ); + xVar->setDate( aDate ); + } + } + break; + case SDB_DBTYPE_BOOLEAN : + case SDB_DBTYPE_DECIMAL : + { + aDocument.GetValue( nCol, nRow, nTab, fVal ); + if ( fVal == 0.0 && nErr == eERR_OK && + aDocument.HasStringData( nCol, nRow, nTab ) ) + nErr = SCWARN_EXPORT_DATALOST; + xVar->setDouble( fVal ); + } + break; + default: + DBG_ERROR( "ScDocShell::SbaSdbExport: unknown FieldType" ); + if ( nErr == eERR_OK ) + nErr = SCWARN_EXPORT_DATALOST; + aDocument.GetValue( nCol, nRow, nTab, fVal ); + xVar->setDouble( fVal ); + } + } + pCur->UpdateRow(); + if ( pCur->Status().IsError() ) + { // #63824# aussagekraeftige Fehlermeldung + //! 2do: was ist bei Call aus Basic? generelles Problem.. + String aMsg; + ScRange aRange( nFirstCol, nRow, nTab, nLastCol, nRow, nTab ); + aRange.Format( aMsg, (SCA_VALID | SCA_TAB_3D), &aDocument ); + aMsg += '\n'; + const SdbStatus& rStat = pCur->Status(); + aMsg += rStat.ErrorMessage(); + aMsg.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "\n\n" )); + aMsg += rStat.ErrorInfo(); + // STR_MSSG_DOSUBTOTALS_0 == "StarCalc" + BOOL bOk = MessBox( GetDialogParent(), + WinBits( WB_OK_CANCEL | WB_DEF_OK ), + ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), + aMsg ).Execute(); + if ( bOk ) + { + nErr = SCWARN_EXPORT_DATALOST; + // Wenigstens schreiben, was geht, + // SdbCursor UpdateRow schreibt bei Ueberlaeufen nichts. + // Leider laesst sich nicht feststellen, welche Spalte + // den Fehler ausgeloest hat. + //! 2do: Sdb sollte hier einen Spaltenwert liefern + USHORT nCol, nIdx; + for ( nCol = nFirstCol, nIdx = 1; nCol <= nLastCol; nCol++, nIdx++ ) + { + switch ( xTblCol->Column( nIdx )->GetType() ) + { + case SDB_DBTYPE_DECIMAL : + //pCur->Variable( nIdx )->PutNull(); + (*pCur->GetRow())[nIdx]->setVoid(); + break; + } + } + pCur->UpdateRow(); + if ( pCur->Status().IsError() ) + { // Letzter Versuch: eine leere Zeile + for ( nCol = nFirstCol, nIdx = 1; nCol <= nLastCol; nCol++, nIdx++ ) + { + //pCur->Variable( nIdx )->PutNull(); + (*pCur->GetRow())[nIdx]->setVoid(); + } + pCur->UpdateRow(); + if ( pCur->Status().IsError() ) + { // da geht anscheinend gar nichts mehr + nErr = SCERR_EXPORT_DATA; + break; // for ( nRow ... ) + } + } + } + else + { + nErr = SCERR_EXPORT_DATA; + break; + } + } + if ( !aProgress.SetStateOnPercent( nRow - nFirstRow ) ) + { // UserBreak + nErr = SCERR_EXPORT_DATA; + break; + } + } + } + else + nErr = SCERR_EXPORT_CURSOR; + pCur->Close(); + } + + return nErr; +} + + +BOOL ScDocShell::LoadCalc( SvStorage* pStor ) // StarCalc 3 oder 4 Datei +{ + SfxEventConfiguration* pConf = SFX_APP()->GetEventConfig(); + BOOL bWarningEnabled = pConf && pConf->IsWarningForced(); + if (bWarningEnabled) + aDocument.SetMacroCallMode(SC_MACROCALL_ASK); // ask before executing + + BOOL bRet = TRUE; + + SvStorageStreamRef aPoolStm = pStor->OpenStream( String::CreateFromAscii(pStyleName), STREAM_STD_READ ); + SvStorageStreamRef aDocStm = pStor->OpenStream( String::CreateFromAscii(pStarCalcDoc), STREAM_STD_READ ); + ULONG nPoolErr = aPoolStm->GetError(); + ULONG nDocErr = aDocStm->GetError(); + + ScProgress* pProgress = NULL; + if ( eShellMode == SFX_CREATE_MODE_STANDARD && !nDocErr ) + { + ULONG nCurPos = aDocStm->Tell(); + ULONG nEndPos = aDocStm->Seek( STREAM_SEEK_TO_END ); + aDocStm->Seek( nCurPos ); + ULONG nRange = nEndPos - nCurPos; + pProgress = new ScProgress( this, ScGlobal::GetRscString(STR_LOAD_DOC), nRange ); + } + + if ( nPoolErr == ERRCODE_IO_NOTEXISTS && nDocErr == ERRCODE_IO_NOTEXISTS ) + { + // leerer Storage = leeres Dokument -> wie InitNew + + aDocument.MakeTable(0); + Size aSize( (long) ( STD_COL_WIDTH * HMM_PER_TWIPS * OLE_STD_CELLS_X ), + (long) ( ScGlobal::nStdRowHeight * HMM_PER_TWIPS * OLE_STD_CELLS_Y ) ); + // hier muss auch der Start angepasst werden + SetVisAreaOrSize( Rectangle( Point(), aSize ), TRUE ); + aDocument.GetStyleSheetPool()->CreateStandardStyles(); + aDocument.UpdStlShtPtrsFrmNms(); + } + else if ( !nPoolErr && !nDocErr ) + { + aPoolStm->SetVersion(pStor->GetVersion()); + aDocStm->SetVersion(pStor->GetVersion()); + + aDocument.Clear(); // keine Referenzen auf Pool behalten! + + RemoveItem( SID_ATTR_CHAR_FONTLIST ); + RemoveItem( ITEMID_COLOR_TABLE ); + RemoveItem( ITEMID_GRADIENT_LIST ); + RemoveItem( ITEMID_HATCH_LIST ); + RemoveItem( ITEMID_BITMAP_LIST ); + RemoveItem( ITEMID_DASH_LIST ); + RemoveItem( ITEMID_LINEEND_LIST ); + + aDocument.LoadPool( *aPoolStm, FALSE ); // FALSE: RefCounts nicht laden + bRet = (aPoolStm->GetError() == 0); + + if ( !bRet ) + { + pStor->SetError( aPoolStm->GetError() ); + DBG_ERROR( "Fehler im Pool-Stream" ); + } + else if (eShellMode != SFX_CREATE_MODE_ORGANIZER) + { + // ViewOptions are not completely stored (to avoid warnings), + // so must be initialized from global settings. + //! This can be removed if a new file format loads all ViewOptions !!! + + aDocument.SetViewOptions( SC_MOD()->GetViewOptions() ); + + ULONG nErrCode = aPoolStm->GetErrorCode(); + const ByteString aStrKey = pStor->GetKey(); + const BOOL bKeySet = (aStrKey.Len() > 0); + + if ( bKeySet ) + aDocStm->SetKey( aStrKey ); // Passwort setzen + + bRet = aDocument.Load( *aDocStm, pProgress ); + + if ( !bRet && bKeySet ) // Passwort falsch + { + SetError( ERRCODE_SFX_WRONGPASSWORD ); + pStor->SetError( ERRCODE_SFX_WRONGPASSWORD ); + } + + if ( aDocStm->GetError() ) + { + // Zeile-8192-Meldung braucht nur zu kommen, wenn die Zeilen + // beschraenkt sind, sonst ist "falsches Format" besser +#ifdef SC_LIMIT_ROWS + if ( aDocument.HasLostData() ) // zuviele Zeilen? + pStor->SetError( SCERR_IMPORT_8K_LIMIT ); + else +#endif + pStor->SetError( aDocStm->GetError() ); + bRet = FALSE; + DBG_ERROR( "Fehler im Document-Stream" ); + } + else + { + if ( !(nErrCode & ERRCODE_WARNING_MASK) ) + nErrCode = aDocStm->GetErrorCode(); + if ( nErrCode & ERRCODE_WARNING_MASK ) + SetError( nErrCode ); + } + + if (bRet) + { + aDocument.UpdateFontCharSet(); + + UpdateLinks(); // verknuepfte Tabellen in Link-Manager + RemoveUnknownObjects(); // unbekannte Ole-Objekte loeschen + } + } + else // SFX_CREATE_MODE_ORGANIZER + { + // UpdateStdNames is called from ScDocument::Load, but is also needed + // if only the styles are loaded! + ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool(); + if (pStylePool) + pStylePool->UpdateStdNames(); // correct style names for different languages + } + + if (bRet) + aDocument.GetPool()->MyLoadCompleted(); + } + else + { + DBG_ERROR( "Stream-Fehler"); + bRet = FALSE; + } + + if (!aDocument.HasTable(0)) + aDocument.MakeTable(0); + + if (eShellMode == SFX_CREATE_MODE_EMBEDDED) + { + USHORT nVisTab = aDocument.GetVisibleTab(); + BOOL bHasVis = aDocument.HasTable(nVisTab); + if ( SfxInPlaceObject::GetVisArea().IsEmpty() || !bHasVis ) + { + if (!bHasVis) + { + nVisTab = 0; + aDocument.SetVisibleTab(nVisTab); + } + USHORT nStartCol,nStartRow; + aDocument.GetDataStart( nVisTab, nStartCol, nStartRow ); + USHORT nEndCol,nEndRow; + aDocument.GetPrintArea( nVisTab, nEndCol, nEndRow ); + if (nStartCol>nEndCol) + nStartCol = nEndCol; + if (nStartRow>nEndRow) + nStartRow = nEndRow; + // hier muss auch der Start angepasst werden + SetVisAreaOrSize( aDocument.GetMMRect( nStartCol,nStartRow, nEndCol,nEndRow, nVisTab ), + TRUE ); + } + } + + delete pProgress; + + if ( eShellMode == SFX_CREATE_MODE_STANDARD && bRet ) + { + if ( bWarningEnabled ) + { + // If the document contains macro calls, ask now + // otherwise set to ALLOWED (for entering new formulas). + // (If document is loaded invisibly, ASK state is kept) + + if ( aDocument.HasMacroCallsAfterLoad() ) + aDocument.CheckMacroWarn(); + else + aDocument.SetMacroCallMode(SC_MACROCALL_ALLOWED); + } + } + + return bRet; +} + + +BOOL ScDocShell::SaveCalc( SvStorage* pStor ) // Calc 3 oder 4 Datei +{ + BOOL bRet = TRUE; + + ScProgress* pProgress = NULL; + if ( eShellMode == SFX_CREATE_MODE_STANDARD ) + { + ULONG nRange = aDocument.GetWeightedCount() + 1; + pProgress = new ScProgress( this, ScGlobal::GetRscString(STR_SAVE_DOC), nRange ); + } + + SvStorageStreamRef aPoolStm = pStor->OpenStream( String::CreateFromAscii(pStyleName) ); + if( !aPoolStm->GetError() ) + { + aPoolStm->SetVersion(pStor->GetVersion()); + aPoolStm->SetSize(0); + bRet = aDocument.SavePool( *aPoolStm ); + } + else + { + DBG_ERROR( "Stream Error" ); + bRet = FALSE; + } + + if ( bRet && eShellMode != SFX_CREATE_MODE_ORGANIZER ) + { + SvStorageStreamRef aDocStm = pStor->OpenStream( String::CreateFromAscii(pStarCalcDoc) ); + if( !aDocStm->GetError() ) + { + aDocStm->SetVersion(pStor->GetVersion()); + aDocStm->SetKey(pStor->GetKey()); // Passwort setzen + aDocStm->SetSize(0); + bRet = aDocument.Save( *aDocStm, pProgress ); + if ( !bRet ) + DBG_ERROR( "Fehler beim Speichern" ); + + if ( aDocument.HasLostData() ) + { + // Warnung, dass nicht alles gespeichert wurde + + if (!pStor->GetError()) + pStor->SetError(SCWARN_EXPORT_MAXROW); + } + else if ( aDocStm->GetErrorCode() && !pStor->GetErrorCode() ) + pStor->SetError(aDocStm->GetErrorCode()); + else if ( OFF_APP()->GetFilterOptions()->IsLoadExcelBasicStorage() ) + { + // #75497# warning if MS VBA macros are lost + // GetSaveWarningOfMSVBAStorage checks if sub-storage with VBA macros is present + // (only possible when editing Excel documents -- storage is not copied to + // StarCalc files) + ULONG nVBAWarn = SvxImportMSVBasic::GetSaveWarningOfMSVBAStorage( *this ); + if ( nVBAWarn && !pStor->GetErrorCode() ) + pStor->SetError( nVBAWarn ); + } + } + else + { + DBG_ERROR( "Stream Error" ); + bRet = FALSE; + } + } + + delete pProgress; + + return bRet; +} + + +BOOL __EXPORT ScDocShell::Load( SvStorage* pStor ) +{ + DBG_ASSERT( pStor, "Nanu... Load ohne Storage?" ); + // wait cursor is handled with progress bar + + GetUndoManager()->Clear(); + + BOOL bRet = SfxInPlaceObject::Load( pStor ); + if( bRet ) + bRet = LoadCalc( pStor ); + + if (!bRet && !pStor->GetError()) + pStor->SetError( SVSTREAM_FILEFORMAT_ERROR ); + + InitItems(); + CalcOutputFactor(); + + // #73762# invalidate eventually temporary table areas + if ( bRet ) + aDocument.InvalidateTableArea(); + + bIsEmpty = FALSE; + FinishedLoading( SFX_LOADED_MAINDOCUMENT | SFX_LOADED_IMAGES ); + return bRet; +} + + +void __EXPORT ScDocShell::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType, + const SfxHint& rHint, const TypeId& rHintType ) +{ + if (rHint.ISA(SfxSimpleHint)) // ohne Parameter + { + ULONG nSlot = ((const SfxSimpleHint&)rHint).GetId(); + switch ( nSlot ) + { + case SFX_HINT_TITLECHANGED: + aDocument.SetName( SfxShell::GetName() ); + // RegisterNewTargetNames gibts nicht mehr + SFX_APP()->Broadcast(SfxSimpleHint( SC_HINT_DOCNAME_CHANGED )); // Navigator + break; + } + } + else if (rHint.ISA(SfxStyleSheetHint)) // Vorlagen geaendert + NotifyStyle((const SfxStyleSheetHint&) rHint); + else if (rHint.ISA(ScAutoStyleHint)) + { + //! direct call for AutoStyles + + // this is called synchronously from ScInterpreter::ScStyle, + // modifying the document must be asynchronous + // (handled by AddInitial) + + ScAutoStyleHint& rStlHint = (ScAutoStyleHint&)rHint; + ScRange aRange = rStlHint.GetRange(); + String aName1 = rStlHint.GetStyle1(); + String aName2 = rStlHint.GetStyle2(); + UINT32 nTimeout = rStlHint.GetTimeout(); + + if (!pAutoStyleList) + pAutoStyleList = new ScAutoStyleList(this); + pAutoStyleList->AddInitial( aRange, aName1, nTimeout, aName2 ); + } +} + + // Inhalte fuer Organizer laden + + +BOOL __EXPORT ScDocShell::LoadFrom( SvStorage* pStor ) +{ + DBG_ASSERT( pStor, "Nanu... LoadFrom ohne Storage?" ); + + WaitObject aWait( GetDialogParent() ); + + BOOL bRet = FALSE; + SvStorageStreamRef aPoolStm = pStor->OpenStream( String::CreateFromAscii(pStyleName), STREAM_STD_READ ); + if ( !aPoolStm->GetError() ) + { + aPoolStm->SetVersion(pStor->GetVersion()); + + aDocument.Clear(); // keine Referenzen auf Pool behalten! + RemoveItem( SID_ATTR_CHAR_FONTLIST ); + RemoveItem( ITEMID_COLOR_TABLE ); + RemoveItem( ITEMID_GRADIENT_LIST ); + RemoveItem( ITEMID_HATCH_LIST ); + RemoveItem( ITEMID_BITMAP_LIST ); + RemoveItem( ITEMID_DASH_LIST ); + RemoveItem( ITEMID_LINEEND_LIST ); + + aDocument.LoadPool( *aPoolStm, TRUE ); // TRUE: RefCounts aus Datei laden + bRet = (aPoolStm->GetError() == 0); + if ( !bRet ) + DBG_ERROR( "Fehler im Pool-Stream" ); + + // UpdateStdNames is called from ScDocument::Load, but is also needed + // if only the styles are loaded! + ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool(); + if (pStylePool) + pStylePool->UpdateStdNames(); // correct style names for different languages + + // Hier auf keinen Fall LoadCompleted, weil ohne Laden der Tabellen die RefCounts + // nicht hochgezaehlt wurden. + // Die Items wuerden dann geloescht, und beim Speichern wuerde Muell herauskommen. + // Darum die Ref-Counts aus der Datei laden (TRUE bei LoadPool). + // (Bug #37635#) + + InitItems(); + // CalcOutputFactor interessiert hier nicht + } + + SfxObjectShell::LoadFrom( pStor ); + + return bRet; +} + + +BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium ) +{ + BOOL bRet = FALSE; // FALSE heisst Benutzerabbruch !! + // bei Fehler: Fehler am Stream setzen!! + + GetUndoManager()->Clear(); + + // ob nach dem Import optimale Spaltenbreiten gesetzt werden sollen + BOOL bSetColWidths = FALSE; + BOOL bSetSimpleTextColWidths = FALSE; + BOOL bSimpleColWidth[MAXCOL+1]; + memset( bSimpleColWidth, 1, (MAXCOL+1) * sizeof(BOOL) ); + ScRange aColWidthRange; + // ob nach dem Import optimale Zeilenhoehen gesetzt werden sollen + BOOL bSetRowHeights = FALSE; + + aConvFilterName.Erase(); //@ #BugId 54198 + + // Alle Filter brauchen die komplette Datei am Stueck (nicht asynchron), + // darum vorher per CreateFileStream dafuer sorgen, dass die komplette + // Datei uebertragen wird. + rMedium.GetPhysicalName(); //! CreateFileStream direkt rufen, wenn verfuegbar + + const SfxFilter* pFilter = rMedium.GetFilter(); + if (pFilter) + { + String aFltName = pFilter->GetFilterName(); + + aConvFilterName=aFltName; //@ #BugId 54198 + + BOOL bCalc3 = ( aFltName.EqualsAscii(pFilterSc30) ); + BOOL bCalc4 = ( aFltName.EqualsAscii(pFilterSc40) ); + if (!bCalc3 && !bCalc4) + aDocument.SetInsertingFromOtherDoc( TRUE ); + + if (bCalc3 || bCalc4) // Calc3/4 - "Import" + { + // wait cursor is handled with progress bar + SvStorage* pStor = rMedium.GetStorage(); + if ( pStor ) + { + bRet = SfxInPlaceObject::Load( pStor ); + if( bRet ) + bRet = LoadCalc( pStor ); + if (!bRet && !pStor->GetError()) + pStor->SetError( SVSTREAM_FILEFORMAT_ERROR ); + } + else + DBG_ERROR("Calc3/4: kein Storage"); + } + else if (aFltName.EqualsAscii(pFilterXML)) + { + // prevent unnecessary broadcasts and updates + ScDocShellModificator aModificator( *this ); + + aDocument.SetImportingXML( TRUE ); + SvStream* pInStream = rMedium.GetInStream(); + if (pInStream) + pInStream->Seek( 0 ); + + ScXMLImportWrapper aImport( aDocument, rMedium ); + bRet = aImport.Import(); + if ( bRet ) + { + // don't prevent establishing of listeners anymore + aDocument.SetInsertingFromOtherDoc( FALSE ); + aDocument.CompileXML(); + } + aDocument.SetImportingXML( FALSE ); + + bSetRowHeights = TRUE; // row height update is disabled during XML import + } + else if (aFltName.EqualsAscii(pFilterSc10)) + { + SvStream* pStream = rMedium.GetInStream(); + if (pStream) + { + FltError eError = ScImportStarCalc10( *pStream, &aDocument ); + if (eError != eERR_OK) + { + if (!GetError()) + SetError(eError); + } + else + bRet = TRUE; + } + } + else if (aFltName.EqualsAscii(pFilterLotus)) + { +// SvStream* pStream = rMedium.GetInStream(); +// if (pStream) + { + FltError eError; + String sCharSet; + String sItStr; + SfxItemSet* pSet = rMedium.GetItemSet(); + const SfxPoolItem* pItem; + if ( pSet && SFX_ITEM_SET == + pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) ) + { + sItStr = ((const SfxStringItem*)pItem)->GetValue(); + } + + if (sItStr.Len() == 0) + { + String aTitle = ScGlobal::GetRscString( STR_IMPORT_LOTUS ); + sCharSet = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "IBMPC (437)" )); + ScImportOptions aOptions(59, 34, sCharSet); + ScImportOptionsDlg* pDlg = + new ScImportOptionsDlg( NULL, FALSE, &aOptions, &aTitle ); + int nDlgRet; + { // WarteCursor aus und wieder einschalten + ScWaitCursorOff aWait( GetDialogParent() ); + nDlgRet = pDlg->Execute(); + } + if ( RET_OK == nDlgRet ) + { + pDlg->GetImportOptions( aOptions ); + sCharSet = aOptions.aStrFont; + SfxItemSet* pItemSet = rMedium.GetItemSet(); + if (pItemSet) + pItemSet->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, sCharSet)); +// eError = ScImportLotus123( *pStream, &aDocument, +// GetCharsetValue(sCharSet)); + ScColumn::bDoubleAlloc = TRUE; + eError = ScImportLotus123( rMedium, &aDocument, + GetCharsetValue(sCharSet)); + ScColumn::bDoubleAlloc = FALSE; + if (eError != eERR_OK) + { + if (!GetError()) + SetError(eError); + + if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK ) + bRet = TRUE; + } + else + bRet = TRUE; + } + else + { + // ConvertFrom lautlos abbrechen + SetError( ERRCODE_IO_ABORT ); + bRet = FALSE; + } + + delete pDlg; + } + else + { + sCharSet = sItStr; +// eError = ScImportLotus123( *pStream, &aDocument, +// GetCharsetValue(sCharSet)); + ScColumn::bDoubleAlloc = TRUE; + eError = ScImportLotus123( rMedium, &aDocument, + GetCharsetValue(sCharSet)); + ScColumn::bDoubleAlloc = FALSE; + if (eError != eERR_OK) + { + if (!GetError()) + SetError(eError); + + if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK ) + bRet = TRUE; + } + else + bRet = TRUE; + } +// rMedium.CloseInStream(); + } + } + else if ( aFltName.EqualsAscii(pFilterExcel4) || aFltName.EqualsAscii(pFilterExcel5) || + aFltName.EqualsAscii(pFilterExcel95) || aFltName.EqualsAscii(pFilterExcel97) || + aFltName.EqualsAscii(pFilterEx4Temp) || aFltName.EqualsAscii(pFilterEx5Temp) || + aFltName.EqualsAscii(pFilterEx95Temp) || aFltName.EqualsAscii(pFilterEx97Temp) ) + { + EXCIMPFORMAT eFormat = EIF_AUTO; + if ( aFltName.EqualsAscii(pFilterExcel4) || aFltName.EqualsAscii(pFilterEx4Temp) ) + eFormat = EIF_BIFF_LE4; + else if ( aFltName.EqualsAscii(pFilterExcel5) || aFltName.EqualsAscii(pFilterExcel95) || + aFltName.EqualsAscii(pFilterEx5Temp) || aFltName.EqualsAscii(pFilterEx95Temp) ) + eFormat = EIF_BIFF5; + else if ( aFltName.EqualsAscii(pFilterExcel97) || aFltName.EqualsAscii(pFilterEx97Temp) ) + eFormat = EIF_BIFF8; + + MakeDrawLayer(); //! im Filter + ScColumn::bDoubleAlloc = TRUE; + FltError eError = ScImportExcel( rMedium, &aDocument, eFormat ); + ScColumn::bDoubleAlloc = FALSE; + aDocument.UpdateFontCharSet(); + if ( aDocument.IsChartListenerCollectionNeedsUpdate() ) + aDocument.UpdateChartListenerCollection(); //! fuer alle Importe? + + // #75299# all graphics objects must have names + aDocument.EnsureGraphicNames(); + + if (eError == SCWARN_IMPORT_RANGE_OVERFLOW) + { + if (!GetError()) + SetError(eError); + bRet = TRUE; + } + else if (eError != eERR_OK) + { + if (!GetError()) + SetError(eError); + } + else + bRet = TRUE; + + bSetRowHeights = TRUE; // #75357# optimal row heights must be updated + } + else if (aFltName.EqualsAscii(pFilterAscii)) + { + SfxItemSet* pSet = rMedium.GetItemSet(); + const SfxPoolItem* pItem; + ScAsciiOptions aOptions; + BOOL bOptInit = FALSE; + + if ( pSet && SFX_ITEM_SET == + pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) ) + { + aOptions.ReadFromString( ((const SfxStringItem*)pItem)->GetValue() ); + bOptInit = TRUE; + } + + if ( !bOptInit ) + { + String aExt = rMedium.GetURLObject().getExtension(); + String aPrivDatName = rMedium.GetURLObject().getName(); + sal_Unicode cAsciiDel; + if (aExt.EqualsIgnoreCaseAscii("CSV")) + cAsciiDel = ','; + else + cAsciiDel = '\t'; + + SvStream* pInStream = rMedium.GetInStream(); + if (pInStream) + { + ScImportAsciiDlg* pDlg = new ScImportAsciiDlg( + NULL,aPrivDatName, + pInStream, cAsciiDel ); + int nDlgRet; + { // WarteCursor aus und wieder einschalten + ScWaitCursorOff aWait( GetDialogParent() ); + nDlgRet = pDlg->Execute(); + } + if ( nDlgRet == RET_OK ) + { + pDlg->GetOptions( aOptions ); + + SfxItemSet* pItemSet = rMedium.GetItemSet(); + if (pItemSet) + pItemSet->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, aOptions.WriteToString() )); + + bOptInit = TRUE; + } + else + { + // ConvertFrom lautlos abbrechen + SetError( ERRCODE_IO_ABORT ); + bRet = FALSE; + } + + delete pDlg; + } + else + DBG_ERROR( "No Stream" ); + } + + if( bOptInit ) // Jetzt gesetzt ? + { + FltError eError = eERR_OK; + BOOL bOverflow = FALSE; + + if( ! rMedium.IsStorage() ) + { + ScImportExport aImpEx( &aDocument ); + aImpEx.SetExtOptions( aOptions ); + + SvStream* pInStream = rMedium.GetInStream(); + if (pInStream) + { + pInStream->SetStreamCharSet( aOptions.GetCharSet() ); + pInStream->Seek( 0 ); + bRet = aImpEx.ImportStream( *pInStream ); + eError = bRet ? eERR_OK : SCERR_IMPORT_CONNECT; + aDocument.StartAllListeners(); + aDocument.SetDirty(); + bOverflow = aImpEx.IsOverflow(); + } + else + DBG_ERROR( "No Stream" ); + } + + if (eError != eERR_OK) + { + if (!GetError()) + SetError(eError); + } + else if ( bOverflow ) + { + if (!GetError()) + SetError(SCWARN_IMPORT_RANGE_OVERFLOW); + } + bSetColWidths = TRUE; + bSetSimpleTextColWidths = TRUE; + } + } + else if (aFltName.EqualsAscii(pFilterDBase)) + { + String sCharSet; + String sItStr; + SfxItemSet* pSet = rMedium.GetItemSet(); + const SfxPoolItem* pItem; + if ( pSet && SFX_ITEM_SET == + pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) ) + { + sItStr = ((const SfxStringItem*)pItem)->GetValue(); + } + if (sItStr.Len() == 0) + { + String aTitle = ScGlobal::GetRscString(STR_IMPORT_DBF); + sCharSet = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "IBMPC" )); + ScImportOptions aOptions; + aOptions.aStrFont = sCharSet; + aOptions.eCharSet = GetCharsetValue( sCharSet ); + ScImportOptionsDlg* pDlg = + new ScImportOptionsDlg( NULL, FALSE, &aOptions, &aTitle ); + int nDlgRet; + { // WarteCursor aus und wieder einschalten + ScWaitCursorOff aWait( GetDialogParent() ); + nDlgRet = pDlg->Execute(); + } + if ( nDlgRet == RET_OK ) + { + pDlg->GetImportOptions( aOptions ); + sCharSet = aOptions.aStrFont; + SfxItemSet* pItemSet = rMedium.GetItemSet(); + if (pItemSet) + pItemSet->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, sCharSet)); + String aBaseName = rMedium.GetURLObject().getBase(); + String aParString = String::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM( "Typ=DBF;Dsn=" )); + aParString += rMedium.GetPhysicalName(); // Sdb kann keine URLs !!! + aParString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";Charset=" )); + aParString += sCharSet; + aParString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";deleted;HDR;" )); + ULONG eError = SbaSdbImport( aBaseName, aParString, TRUE, bSimpleColWidth ); + if (eError != eERR_OK) + { + if (!GetError()) + SetError(eError); + bRet = ( eError == SCWARN_IMPORT_RANGE_OVERFLOW ); + } + else + bRet = TRUE; + } + else + { + // ConvertFrom lautlos abbrechen + SetError( ERRCODE_IO_ABORT ); + bRet = FALSE; + } + + delete pDlg; + } + else + { + sCharSet = sItStr; + String aBaseName = rMedium.GetURLObject().getBase(); + String aParString = String::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM( "Typ=DBF;Dsn=" )); + aParString += rMedium.GetPhysicalName(); // Sdb kann keine URLs !!! + aParString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";Charset=" )); + aParString += sCharSet; + aParString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";deleted;HDR" )); + ULONG eError = SbaSdbImport( aBaseName, aParString, TRUE, bSimpleColWidth ); + if (eError != eERR_OK) + { + if (!GetError()) + SetError(eError); + bRet = ( eError == SCWARN_IMPORT_RANGE_OVERFLOW ); + } + else + bRet = TRUE; + } + aColWidthRange.aStart.SetRow( 1 ); // Spaltenheader nicht + bSetColWidths = TRUE; + bSetSimpleTextColWidths = TRUE; + // Memo-Felder fuehren zu einem bSimpleColWidth[nCol]==FALSE + for ( USHORT nCol=0; nCol <= MAXCOL && !bSetRowHeights; nCol++ ) + { + if ( !bSimpleColWidth[nCol] ) + bSetRowHeights = TRUE; + } + } + else if (aFltName.EqualsAscii(pFilterDif)) + { + SvStream* pStream = rMedium.GetInStream(); + if (pStream) + { + FltError eError; + String sCharSet; + String sItStr; + SfxItemSet* pSet = rMedium.GetItemSet(); + const SfxPoolItem* pItem; + if ( pSet && SFX_ITEM_SET == + pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) ) + { + sItStr = ((const SfxStringItem*)pItem)->GetValue(); + } + + if (sItStr.Len() == 0) + { + String aTitle = ScGlobal::GetRscString( STR_IMPORT_DIF ); + sCharSet = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "ANSI" )); + ScImportOptions aOptions(59, 34, sCharSet); + ScImportOptionsDlg* pDlg = + new ScImportOptionsDlg( NULL, FALSE, &aOptions, &aTitle ); + int nDlgRet; + { // WarteCursor aus und wieder einschalten + ScWaitCursorOff aWait( GetDialogParent() ); + nDlgRet = pDlg->Execute(); + } + if ( RET_OK == nDlgRet ) + { + pDlg->GetImportOptions( aOptions ); + sCharSet = aOptions.aStrFont; + SfxItemSet* pItemSet = rMedium.GetItemSet(); + if (pItemSet) + pItemSet->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, sCharSet)); + eError = ScImportDif( *pStream, &aDocument, ScAddress(0,0,0), + GetCharsetValue(sCharSet)); + if (eError != eERR_OK) + { + if (!GetError()) + SetError(eError); + + if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK ) + bRet = TRUE; + } + else + bRet = TRUE; + } + else + { + // ConvertFrom lautlos abbrechen + SetError( ERRCODE_IO_ABORT ); + bRet = FALSE; + } + + delete pDlg; + } + else + { + sCharSet = sItStr; + eError = ScImportDif( *pStream, &aDocument, ScAddress(0,0,0), + GetCharsetValue(sCharSet)); + if (eError != eERR_OK) + { + if (!GetError()) + SetError(eError); + + if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK ) + bRet = TRUE; + } + else + bRet = TRUE; + } + rMedium.CloseInStream(); + } + bSetColWidths = TRUE; + bSetSimpleTextColWidths = TRUE; + } + else if (aFltName.EqualsAscii(pFilterSylk)) + { + FltError eError = SCERR_IMPORT_UNKNOWN; + if( !rMedium.IsStorage() ) + { + ScImportExport aImpEx( &aDocument ); + + SvStream* pInStream = rMedium.GetInStream(); + if (pInStream) + { + pInStream->Seek( 0 ); + bRet = aImpEx.ImportStream( *pInStream, SOT_FORMATSTR_ID_SYLK ); + eError = bRet ? eERR_OK : SCERR_IMPORT_UNKNOWN; + aDocument.StartAllListeners(); + aDocument.SetDirty(); + } + else + DBG_ERROR( "No Stream" ); + } + + if ( eError != eERR_OK && !GetError() ) + SetError(eError); + bSetColWidths = TRUE; + bSetSimpleTextColWidths = TRUE; + } + else if (aFltName.EqualsAscii(pFilterRtf)) + { + FltError eError = SCERR_IMPORT_UNKNOWN; + if( !rMedium.IsStorage() ) + { + SvStream* pInStream = rMedium.GetInStream(); + if (pInStream) + { + pInStream->Seek( 0 ); + ScRange aRange; + eError = ScImportRTF( *pInStream, &aDocument, aRange ); + if (eError != eERR_OK) + { + if (!GetError()) + SetError(eError); + + if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK ) + bRet = TRUE; + } + else + bRet = TRUE; + aDocument.StartAllListeners(); + aDocument.SetDirty(); + bSetColWidths = TRUE; + bSetRowHeights = TRUE; + } + else + DBG_ERROR( "No Stream" ); + } + + if ( eError != eERR_OK && !GetError() ) + SetError(eError); + } + else if (aFltName.EqualsAscii(pFilterHtml)) + { + FltError eError = SCERR_IMPORT_UNKNOWN; + if( !rMedium.IsStorage() ) + { + SvStream* pInStream = rMedium.GetInStream(); + if (pInStream) + { + pInStream->Seek( 0 ); + ScRange aRange; + // HTML macht eigenes ColWidth/RowHeight + CalcOutputFactor(); + eError = ScImportHTML( *pInStream, &aDocument, aRange, + GetOutputFactor() ); + if (eError != eERR_OK) + { + if (!GetError()) + SetError(eError); + + if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK ) + bRet = TRUE; + } + else + bRet = TRUE; + aDocument.StartAllListeners(); + aDocument.SetDirty(); + } + else + DBG_ERROR( "No Stream" ); + } + + if ( eError != eERR_OK && !GetError() ) + SetError(eError); + } + else + { + if (!GetError()) + SetError(SCERR_IMPORT_NI); + } + + if (!bCalc3) + aDocument.SetInsertingFromOtherDoc( FALSE ); + } + else + DBG_ERROR("Kein Filter bei ConvertFrom"); + + InitItems(); + CalcOutputFactor(); + if ( bRet && (bSetColWidths || bSetRowHeights) ) + { // Spaltenbreiten/Zeilenhoehen anpassen, Basis 100% Zoom + Fraction aZoom( 1, 1 ); + double nPPTX = ScGlobal::nScreenPPTX * (double) aZoom + / GetOutputFactor(); // Faktor ist Drucker zu Bildschirm + double nPPTY = ScGlobal::nScreenPPTY * (double) aZoom; + VirtualDevice aVirtDev; + // all sheets (for Excel import) + USHORT nTabCount = aDocument.GetTableCount(); + for (USHORT nTab=0; nTab<nTabCount; nTab++) + { + USHORT nEndCol, nEndRow; + aDocument.GetCellArea( nTab, nEndCol, nEndRow ); + aColWidthRange.aEnd.SetCol( nEndCol ); + aColWidthRange.aEnd.SetRow( nEndRow ); + ScMarkData aMark; + aMark.SetMarkArea( aColWidthRange ); + aMark.MarkToMulti(); + // Reihenfolge erst Breite dann Hoehe ist wichtig (vergl. hund.rtf) + if ( bSetColWidths ) + { + for ( USHORT nCol=0; nCol <= nEndCol; nCol++ ) + { + USHORT nWidth = aDocument.GetOptimalColWidth( + nCol, nTab, &aVirtDev, nPPTX, nPPTY, aZoom, aZoom, FALSE, &aMark, + (bSetSimpleTextColWidths && bSimpleColWidth[nCol]) ); + aDocument.SetColWidth( nCol, nTab, + nWidth + (USHORT)ScGlobal::nLastColWidthExtra ); + } + } + if ( bSetRowHeights ) + { + // nExtra must be 0 + aDocument.SetOptimalHeight( 0, nEndRow, nTab, 0, &aVirtDev, + nPPTX, nPPTY, aZoom, aZoom, FALSE ); + } + } + } + FinishedLoading( SFX_LOADED_MAINDOCUMENT | SFX_LOADED_IMAGES ); + + // #73762# invalidate eventually temporary table areas + if ( bRet ) + aDocument.InvalidateTableArea(); + + bIsEmpty = FALSE; + + return bRet; +} + + +void __EXPORT ScDocShell::HandsOff() +{ + SfxInPlaceObject::HandsOff(); +} + + +BOOL __EXPORT ScDocShell::Save() +{ + // DoEnterHandler hier nicht (wegen AutoSave), ist im ExecuteSave + + ScChartListenerCollection* pCharts = aDocument.GetChartListenerCollection(); + if (pCharts) + pCharts->UpdateDirtyCharts(); // Charts, die noch upgedated werden muessen + if (pAutoStyleList) + pAutoStyleList->ExecuteAllNow(); // Vorlagen-Timeouts jetzt ausfuehren + if (eShellMode == SFX_CREATE_MODE_STANDARD) + SvInPlaceObject::SetVisArea( Rectangle() ); // normal bearbeitet -> keine VisArea + + // #77577# save additionally XML in storage + if ( GetCreateMode() != SFX_CREATE_MODE_EMBEDDED ) + AddXMLAsZipToTheStorage( *GetStorage() ); + + // wait cursor is handled with progress bar + BOOL bRet = SfxInPlaceObject::Save(); + if( bRet ) + bRet = SaveCalc( GetStorage() ); + return bRet; +} + + +BOOL __EXPORT ScDocShell::SaveAs( SvStorage* pStor ) +{ + // DoEnterHandler hier nicht (wegen AutoSave), ist im ExecuteSave + + ScChartListenerCollection* pCharts = aDocument.GetChartListenerCollection(); + if (pCharts) + pCharts->UpdateDirtyCharts(); // Charts, die noch upgedated werden muessen + if (pAutoStyleList) + pAutoStyleList->ExecuteAllNow(); // Vorlagen-Timeouts jetzt ausfuehren + if (eShellMode == SFX_CREATE_MODE_STANDARD) + SvInPlaceObject::SetVisArea( Rectangle() ); // normal bearbeitet -> keine VisArea + + DBG_ASSERT( pStor, "Nanu... SaveAs ohne Storage?" ); + + // #77577# save additionally XML in storage + if ( GetCreateMode() != SFX_CREATE_MODE_EMBEDDED ) + AddXMLAsZipToTheStorage( *pStor ); + + // wait cursor is handled with progress bar + BOOL bRet = SfxInPlaceObject::SaveAs( pStor ); + if( bRet ) + bRet = SaveCalc( pStor ); + + return bRet; +} + + +BOOL __EXPORT ScDocShell::IsInformationLost() +{ +/* + const SfxFilter *pFilt = GetMedium()->GetFilter(); + BOOL bRet = pFilt && pFilt->IsAlienFormat() && bNoInformLost; + if (bNoInformLost) // nur einmal!! + bNoInformLost = FALSE; + return bRet; +*/ + //!!! bei Gelegenheit ein korrekte eigene Behandlung einbauen + + return SfxObjectShell::IsInformationLost(); +} + + +void ScDocShell::AsciiSave( SvStream& rStream, sal_Unicode cDelim, sal_Unicode cStrDelim, + CharSet eCharSet) +{ + // could be UTF8 => ByteString, not sal_Char + ByteString aDelim( cDelim, eCharSet ); + + USHORT nStartCol = 0; + USHORT nStartRow = 0; + USHORT nTab = GetSaveTab(); + USHORT nEndCol, nEndRow; + aDocument.GetCellArea( nTab, nEndCol, nEndRow ); + + ScProgress aProgress( this, ScGlobal::GetRscString( STR_SAVE_DOC ), nEndRow ); + + String aString; + ByteString aEmptyLine; // fuer WriteLine mit ConvertEndl + + ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell, SfxViewShell::Current()); + const ScViewOptions& rOpt = (pViewSh) + ? pViewSh->GetViewData()->GetOptions() + : aDocument.GetViewOptions(); + BOOL bShowFormulas = rOpt.GetOption( VOPT_FORMULAS ); + BOOL bTabProtect = aDocument.IsTabProtected( nTab ); + + USHORT nCol; + USHORT nRow; + USHORT nNextCol = nStartCol; + USHORT nNextRow = nStartRow; + USHORT nEmptyCol, nEmptyRow; + SvNumberFormatter& rFormatter = *aDocument.GetFormatTable(); + + ScHorizontalCellIterator aIter( &aDocument, nTab, nStartCol, nStartRow, + nEndCol, nEndRow ); + ScBaseCell* pCell; + while ( pCell = aIter.GetNext( nCol, nRow ) ) + { + BOOL bProgress = FALSE; // nur bei Zeilenwechsel + if ( nNextRow < nRow ) + { // leere Zeilen oder/und leere Spalten bis zum Ende der Zeile + bProgress = TRUE; + if(cDelim!=0) //@ BugId 55355 + for ( nEmptyCol = nNextCol; nEmptyCol < nEndCol; nEmptyCol++ ) + { // restliche Spalten der letzten Zeile + rStream.Write( aDelim.GetBuffer(), aDelim.Len() ); + } + + rStream.WriteLine( aEmptyLine ); // ConvertEndl + nNextRow++; + for ( nEmptyRow = nNextRow; nEmptyRow < nRow; nEmptyRow++ ) + { // ganze leere Zeilen + if(cDelim!=0) //@ BugId 55355 + for ( nEmptyCol = nStartCol; nEmptyCol < nEndCol; nEmptyCol++ ) + { + rStream.Write( aDelim.GetBuffer(), aDelim.Len() ); + } + rStream.WriteLine( aEmptyLine ); // ConvertEndl + } + if(cDelim!=0) //@ BugId 55355 + for ( nEmptyCol = nStartCol; nEmptyCol < nCol; nEmptyCol++ ) + { // leere Spalten am Anfang der Zeile + rStream.Write( aDelim.GetBuffer(), aDelim.Len() ); + } + nNextRow = nRow; + } + else if ( nNextCol < nCol ) + { // leere Spalten in gleicher Zeile + if(cDelim!=0) //@ BugId 55355 + for ( nEmptyCol = nNextCol; nEmptyCol < nCol; nEmptyCol++ ) + { // dazwischen liegende Spalten + rStream.Write( aDelim.GetBuffer(), aDelim.Len() ); + } + } + if ( nCol == nEndCol ) + { + bProgress = TRUE; + nNextCol = nStartCol; + nNextRow = nRow + 1; + } + else + nNextCol = nCol + 1; + + CellType eType = pCell->GetCellType(); + if ( bTabProtect ) + { + const ScProtectionAttr* pProtAttr = + (const ScProtectionAttr*) aDocument.GetAttr( + nCol, nRow, nTab, ATTR_PROTECTION ); + if ( pProtAttr->GetHideCell() || + ( eType == CELLTYPE_FORMULA && bShowFormulas && + pProtAttr->GetHideFormula() ) ) + eType = CELLTYPE_NONE; // ausblenden + } + BOOL bString; + switch ( eType ) + { + case CELLTYPE_NOTE: + case CELLTYPE_NONE: + aString.Erase(); + bString = FALSE; + break; + case CELLTYPE_FORMULA : + { + USHORT nErrCode; + if ( bShowFormulas ) + { + ((ScFormulaCell*)pCell)->GetFormula( aString ); + bString = TRUE; + } + else if ( nErrCode = ((ScFormulaCell*)pCell)->GetErrCode() ) + { + aString = ScGlobal::GetErrorString( nErrCode ); + bString = TRUE; + } + else if ( ((ScFormulaCell*)pCell)->IsValue() ) + { + ULONG nFormat; + aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat ); + ScCellFormat::GetInputString( pCell, nFormat, aString, rFormatter ); + bString = FALSE; + } + else + { + ((ScFormulaCell*)pCell)->GetString( aString ); + bString = TRUE; + } + } + break; + case CELLTYPE_STRING : + ((ScStringCell*)pCell)->GetString( aString ); + bString = TRUE; + break; + case CELLTYPE_EDIT : + ((ScEditCell*)pCell)->GetString( aString ); + bString = TRUE; + break; + case CELLTYPE_VALUE : + { + ULONG nFormat; + aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat ); + ScCellFormat::GetInputString( pCell, nFormat, aString, rFormatter ); + bString = FALSE; + } + break; + default: + DBG_ERROR( "ScDocShell::AsciiSave: unknown CellType" ); + aString.Erase(); + bString = FALSE; + } + + if ( bString ) + { + if(cStrDelim!=0) //@ BugId 55355 + { + xub_StrLen nPos = aString.Search( cStrDelim ); + while (nPos != STRING_NOTFOUND) + { + aString.Insert(cStrDelim, nPos); + nPos = aString.Search(cStrDelim, nPos+2); + } + } + if(cStrDelim!=0) //@ BugId 55355 + { + aString.Insert( cStrDelim, 0 ); + aString += cStrDelim; + } + ByteString aByteStr( aString, eCharSet ); + rStream.Write( aByteStr.GetBuffer(), aByteStr.Len() ); + } + else + { + ByteString aByteStr( aString, eCharSet ); + rStream.Write( aByteStr.GetBuffer(), aByteStr.Len() ); + } + + if( nCol < nEndCol ) + { + if(cDelim!=0) //@ BugId 55355 + rStream.Write( aDelim.GetBuffer(), aDelim.Len() ); + } + else + rStream.WriteLine( aEmptyLine ); // ConvertEndl + + if ( bProgress ) + aProgress.SetStateOnPercent( nRow ); + } + + // was noch gewuenscht ist leer rausschreiben + if ( nNextRow <= nEndRow ) + { + if(cDelim!=0) //@ BugId 55355 + for ( nEmptyCol = nNextCol; nEmptyCol < nEndCol; nEmptyCol++ ) + { // restliche Spalten der letzten Zeile + rStream.Write( aDelim.GetBuffer(), aDelim.Len() ); + } + rStream.WriteLine( aEmptyLine ); // ConvertEndl + nNextRow++; + } + for ( nEmptyRow = nNextRow; nEmptyRow <= nEndRow; nEmptyRow++ ) + { // ganze leere Zeilen + if(cDelim!=0) //@ BugId 55355 + for ( nEmptyCol = nStartCol; nEmptyCol < nEndCol; nEmptyCol++ ) + { + rStream.Write( aDelim.GetBuffer(), aDelim.Len() ); + } + rStream.WriteLine( aEmptyLine ); // ConvertEndl + } +} + + +BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed ) +{ + DoEnterHandler(); // nicht abgeschlossene Zelle beenden + if (pAutoStyleList) + pAutoStyleList->ExecuteAllNow(); // Vorlagen-Timeouts jetzt ausfuehren + if (eShellMode == SFX_CREATE_MODE_STANDARD) + SvInPlaceObject::SetVisArea( Rectangle() ); // normal bearbeitet -> keine VisArea + + + DBG_ASSERT( rMed.GetFilter(), "Filter == 0" ); + + BOOL bRet = FALSE; + String aFltName = rMed.GetFilter()->GetFilterName(); + +/* + if (aFltName.EqualsAscii(pFilterLotus)) + { + SvStream* pStream = rMed.GetOutStream(); + if (pStream) + { + FltError eError = ScExportLotus123( *pStream, &aDocument, ExpWK1, + CHARSET_IBMPC_437 ); + bRet = eError == eERR_OK; + } + } + else +*/ + if ( aFltName.EqualsAscii(pFilterSc30) || aFltName.EqualsAscii(pFilterSc40) ) + { + // Calc3/4 - "Export" + //! wird nicht gerufen (geht ueber Save/SaveAs) - wird das noch gebraucht ??????? + + DBG_ERROR("ConvertTo fuer altes Calc gibt's noch..."); + SvStorage* pStor = rMed.GetStorage(); + if ( pStor ) + { + // wait cursor is handled with progress bar + bRet = SfxInPlaceObject::SaveAs( pStor ); + if( bRet ) + bRet = SaveCalc( pStor ); + + String aShortTypeName = String( ScResId(SCSTR_SHORT_SCDOC_NAME) ); // "Dokument" + if ( aFltName.EqualsAscii(pFilterSc30) ) + { + // Ole-Geraffel auf 3.0-Werte setzen: + SvGlobalName aName( SO3_SC_CLASSID_30 ); + UINT32 nClip = SOT_FORMATSTR_ID_STARCALC_30; + pStor->SetClass( aName, nClip, aShortTypeName ); + } + else + { + // Ole-Geraffel auf 4.0-Werte setzen: + SvGlobalName aName( SO3_SC_CLASSID_40 ); + UINT32 nClip = SOT_FORMATSTR_ID_STARCALC_40; + pStor->SetClass( aName, nClip, aShortTypeName ); + } + } + } + else if (aFltName.EqualsAscii(pFilterXML)) + { + ScXMLImportWrapper aImport( aDocument, rMed ); + bRet = aImport.Export(); + } + else if (aFltName.EqualsAscii(pFilterExcel5) || aFltName.EqualsAscii(pFilterExcel95) || + aFltName.EqualsAscii(pFilterExcel97) || aFltName.EqualsAscii(pFilterEx5Temp) || + aFltName.EqualsAscii(pFilterEx95Temp) || aFltName.EqualsAscii(pFilterEx97Temp)) + { + WaitObject aWait( GetDialogParent() ); + BOOL bFake97 = ( aFltName.EqualsAscii(pFilterExcel97) || aFltName.EqualsAscii(pFilterEx97Temp) ); + FltError eError = ScExportExcel5( rMed, &aDocument, bFake97, RTL_TEXTENCODING_MS_1252 ); + + if (eError && !GetError()) + SetError(eError); + + if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK ) + bRet = TRUE; + else + bRet = eError == eERR_OK; + } + else if (aFltName.EqualsAscii(pFilterAscii)) + { + SvStream* pStream = rMed.GetOutStream(); + if (pStream) + { + String sCharSet; + sal_Unicode cAsciiDel; + sal_Unicode cStrDel; + String sItStr; + SfxItemSet* pSet = rMed.GetItemSet(); + + BOOL bShowDlg=FALSE; + BOOL bCancel=FALSE; + + const SfxPoolItem* pDlgItem; + if (pSet&& SFX_ITEM_SET == + pSet->GetItemState( SID_USE_FILTEROPTIONS, TRUE, &pDlgItem ) ) + { + bShowDlg=((const SfxBoolItem*)pDlgItem)->GetValue(); + } + + const SfxPoolItem* pItem; + if ( pSet && SFX_ITEM_SET == + pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) ) + { + sItStr = ((const SfxStringItem*)pItem)->GetValue(); + } + if (sItStr.Len() == 0 || bShowDlg) + { + if (aDocument.GetTableCount() > 1) + if (!rMed.GetError()) + rMed.SetError(SCWARN_EXPORT_ASCII); + sCharSet = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "SYSTEM" )); + cStrDel = '"'; + String aExt = rMed.GetName().Copy(rMed.GetName().Len()-3, 3); + if (aExt.EqualsIgnoreCaseAscii("CSV")) + cAsciiDel = ','; + else + cAsciiDel = '\t'; + ScImportOptions aOptions((USHORT)cAsciiDel, (USHORT)cStrDel, sCharSet); + String aTitle = ScGlobal::GetRscString( STR_EXPORT_ASCII ); + ScImportOptionsDlg* pDlg = + new ScImportOptionsDlg( NULL, TRUE, &aOptions, &aTitle ); + if ( pDlg->Execute() == RET_OK ) + { + WaitObject aWait( GetDialogParent() ); + pDlg->GetImportOptions( aOptions ); + cAsciiDel = (sal_Unicode) aOptions.nFieldSepCode; + cStrDel = (sal_Unicode) aOptions.nTextSepCode; + sCharSet = aOptions.aStrFont; + sItStr = aOptions.BuildString(); + SfxItemSet* pItemSet = rMed.GetItemSet(); + if (pItemSet) + pItemSet->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, sItStr)); + AsciiSave( *pStream, cAsciiDel, cStrDel, + GetCharsetValue(sCharSet)); + } + else + { + bCancel = TRUE; + SetError( ERRCODE_IO_ABORT ); + } + delete pDlg; + } + else + { + WaitObject aWait( GetDialogParent() ); + ScImportOptions aOptions( sItStr ); + cAsciiDel = (sal_Unicode)aOptions.nFieldSepCode; + cStrDel = (sal_Unicode)aOptions.nTextSepCode; + sCharSet = aOptions.aStrFont; + AsciiSave( *pStream, cAsciiDel, cStrDel, GetCharsetValue(sCharSet)); + } + bRet = !bCancel; + } + } + else if (aFltName.EqualsAscii(pFilterDBase)) + { + BOOL bCancel = FALSE; + String sCharSet; + SfxItemSet* pSet = rMed.GetItemSet(); + const SfxPoolItem* pItem; + if ( pSet && SFX_ITEM_SET == + pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) ) + { + sCharSet = ((const SfxStringItem*)pItem)->GetValue(); + + if ( pSet->GetItemState( SID_USE_FILTEROPTIONS, TRUE, &pItem ) == SFX_ITEM_SET && + ((const SfxBoolItem*)pItem)->GetValue() ) + { + sCharSet.Erase(); // "edit options" - forget old + } + } + if (sCharSet.Len() == 0) + { + sCharSet = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "IBMPC" )); + ScImportOptions aOptions(59, 34, sCharSet); + String aTitle = ScGlobal::GetRscString( STR_EXPORT_DBF ); + ScImportOptionsDlg* pDlg = + new ScImportOptionsDlg( NULL, FALSE, &aOptions, &aTitle ); + if ( pDlg->Execute() == RET_OK ) + { + pDlg->GetImportOptions( aOptions ); + sCharSet = aOptions.aStrFont; + SfxItemSet* pItemSet = rMed.GetItemSet(); + if (pItemSet) + pItemSet->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, sCharSet)); + } + else + bCancel = TRUE; + delete pDlg; + } + + if ( bCancel ) + { + SetError( ERRCODE_IO_ABORT ); + } + else + { + WaitObject aWait( GetDialogParent() ); + String aParString = String::CreateFromAscii( + RTL_CONSTASCII_STRINGPARAM( "Typ=DBF;Dsn=" )); + DirEntry aTmpFile( rMed.GetPhysicalName() ); + // Sdb kann keine URLs !!! + // nur Pfad fuer OpenPrivateConnection! + aParString += aTmpFile.GetPath().GetFull(); + // die Extension braucht's auch noch.. + aParString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";Ext=" )); + aParString += aTmpFile.GetExtension(); + // Dateiname mit vollem Pfad ist laenger als 8 Zeichen... + aParString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";NOFILENAMELIMIT=1" )); + aParString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";Charset=" )); + aParString += sCharSet; +// HACK damit Sba geoffnetes TempFile ueberschreiben kann + rMed.CloseOutStream(); + BOOL bHasMemo = FALSE; + ULONG eError = SbaSdbExport( bHasMemo, aParString, aTmpFile.GetBase() ); + if ( eError != eERR_OK && (eError & ERRCODE_WARNING_MASK) ) + { + if ( !rMed.GetError() ) + rMed.SetError( eError ); + eError = eERR_OK; + } + else if ( aDocument.GetTableCount() > 1 && !rMed.GetError() ) + rMed.SetError( SCWARN_EXPORT_ASCII ); + if ( bHasMemo ) + aTmpFile.SetExtension( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("dbt")) ); + if ( eError != eERR_OK ) + { + if (!GetError()) + SetError(eError); + if ( bHasMemo && aTmpFile.Exists() ) + aTmpFile.Kill(); + } + else + { + bRet = TRUE; + if ( bHasMemo ) + { + SfxStringItem* pNameItem = + (SfxStringItem*) rMed.GetItemSet()->GetItem( SID_FILE_NAME ); + DirEntry aDbtFile( pNameItem->GetValue() ); + aDbtFile.SetExtension( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("dbt")) ); + if ( aDbtFile.Exists() && aDbtFile.Kill() ) + bRet = FALSE; + if ( bRet && aTmpFile.MoveTo( aDbtFile ) ) + bRet = FALSE; + if ( !bRet ) + { + if ( aTmpFile.Exists() ) + aTmpFile.Kill(); + if ( !GetError() ) + SetError( SCERR_EXPORT_DATA ); + } + } + } + } + } + else if (aFltName.EqualsAscii(pFilterDif)) + { + SvStream* pStream = rMed.GetOutStream(); + if (pStream) + { + BOOL bCancel = FALSE; + String sCharSet; + String sItStr; + SfxItemSet* pSet = rMed.GetItemSet(); + const SfxPoolItem* pItem; + if ( pSet && SFX_ITEM_SET == + pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) ) + { + sItStr = ((const SfxStringItem*)pItem)->GetValue(); + } + if (sItStr.Len() == 0) + { + if (aDocument.GetTableCount() > 1) + if (!rMed.GetError()) + rMed.SetError(SCWARN_EXPORT_ASCII); + + sCharSet = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "ANSI" )); + ScImportOptions aOptions(59, 34, sCharSet); + String aTitle = ScGlobal::GetRscString( STR_EXPORT_DIF ); + ScImportOptionsDlg* pDlg = + new ScImportOptionsDlg( NULL, FALSE, &aOptions, &aTitle ); + if ( pDlg->Execute() == RET_OK ) + { + WaitObject aWait( GetDialogParent() ); + pDlg->GetImportOptions( aOptions ); + sCharSet = aOptions.aStrFont; + SfxItemSet* pItemSet = rMed.GetItemSet(); + if (pItemSet) + pItemSet->Put(SfxStringItem(SID_FILE_FILTEROPTIONS, sCharSet)); + USHORT nTab = GetSaveTab(); + ScExportDif( *pStream, &aDocument, ScAddress(0,0,nTab), GetCharsetValue(sCharSet) ); + } + else + { + bCancel = TRUE; + SetError( ERRCODE_IO_ABORT ); + } + delete pDlg; + } + else + { + WaitObject aWait( GetDialogParent() ); + sCharSet = sItStr; + ScExportDif( *pStream, &aDocument, ScAddress(0,0,0), GetCharsetValue(sCharSet) ); + } + bRet = !bCancel; + } + } + else if (aFltName.EqualsAscii(pFilterSylk)) + { + SvStream* pStream = rMed.GetOutStream(); + if ( pStream ) + { + WaitObject aWait( GetDialogParent() ); + + // Formeln mit exportieren? + + ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell, SfxViewShell::Current()); + const ScViewOptions& rOpt = (pViewSh) + ? pViewSh->GetViewData()->GetOptions() + : aDocument.GetViewOptions(); + BOOL bShowFormulas = rOpt.GetOption( VOPT_FORMULAS ); + + USHORT nEndCol, nEndRow; + aDocument.GetCellArea( 0, nEndCol, nEndRow ); + ScRange aRange( 0,0,0, nEndCol,nEndRow,0 ); + + ScImportExport aImExport( &aDocument, aRange ); + aImExport.SetFormulas(bShowFormulas); + bRet = aImExport.ExportStream( *pStream, SOT_FORMATSTR_ID_SYLK ); + } + } + else if (aFltName.EqualsAscii(pFilterHtml)) + { + SvStream* pStream = rMed.GetOutStream(); + if ( pStream ) + { + WaitObject aWait( GetDialogParent() ); + ScImportExport aImExport( &aDocument ); + aImExport.SetStreamPath( rMed.GetName() ); + bRet = aImExport.ExportStream( *pStream, SOT_FORMATSTR_ID_HTML ); + } + } + else + { + if (GetError()) + SetError(SCERR_IMPORT_NI); + } + return bRet; +} + + +BOOL __EXPORT ScDocShell::SaveCompleted( SvStorage * pStor ) +{ + return SfxInPlaceObject::SaveCompleted( pStor ); +} + + +BOOL __EXPORT ScDocShell::DoSaveCompleted( SfxMedium * pNewStor ) +{ + BOOL bRet = SfxObjectShell::DoSaveCompleted( pNewStor ); + + // SC_HINT_DOC_SAVED fuer Wechsel ReadOnly -> Read/Write + Broadcast( SfxSimpleHint( SC_HINT_DOC_SAVED ) ); + return bRet; +} + + +USHORT __EXPORT ScDocShell::PrepareClose( BOOL bUI, BOOL bForBrowsing ) +{ + if(SC_MOD()->GetCurRefDlgId()>0) + { + SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this, TYPE(SfxTopViewFrame) ); + if( pFrame ) + { + SfxViewShell* p = pFrame->GetViewShell(); + ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p); + if(pViewSh!=NULL) + { + Window *pWin=pViewSh->GetWindow(); + if(pWin!=NULL) pWin->GrabFocus(); + } + } + + return FALSE; + } + if ( aDocument.IsInLinkUpdate() || aDocument.IsInInterpreter() ) + { + ErrorMessage(STR_CLOSE_ERROR_LINK); + return FALSE; + } + + DoEnterHandler(); + + USHORT nRet = SfxObjectShell::PrepareClose( bUI, bForBrowsing ); + if (nRet == TRUE) // TRUE = schliessen + aDocument.DisableIdle(TRUE); // nicht mehr drin rumpfuschen !!! + + return nRet; +} + +void ScDocShell::PrepareReload() +{ + SfxObjectShell::PrepareReload(); // tut nichts? + + // Das Disconnect von DDE-Links kann Reschedule ausloesen. + // Wenn die DDE-Links erst im Dokument-dtor geloescht werden, kann beim Reload + // aus diesem Reschedule das DDE-Link-Update fuer das neue Dokument ausgeloest + // werden. Dabei verklemmt sicht dann irgendwas. + // -> Beim Reload die DDE-Links des alten Dokuments vorher disconnecten + + aDocument.DisconnectDdeLinks(); +} + + +String ScDocShell::GetOwnFilterName() // static +{ + return String::CreateFromAscii(pFilterSc50); +} + +BOOL ScDocShell::HasAutomaticTableName( const String& rFilter ) // static +{ + // TRUE for those filters that keep the default table name + // (which is language specific) + + return rFilter.EqualsAscii( pFilterAscii ) + || rFilter.EqualsAscii( pFilterLotus ) + || rFilter.EqualsAscii( pFilterExcel4 ) + || rFilter.EqualsAscii( pFilterEx4Temp ) + || rFilter.EqualsAscii( pFilterDBase ) + || rFilter.EqualsAscii( pFilterDif ) + || rFilter.EqualsAscii( pFilterSylk ) + || rFilter.EqualsAscii( pFilterHtml ) + || rFilter.EqualsAscii( pFilterRtf ); +} + +//================================================================== + +#define __SCDOCSHELL_INIT \ + aDocument ( SCDOCMODE_DOCUMENT, this ), \ + pUndoManager ( NULL ), \ + pFontList ( NULL ), \ + bHeaderOn ( TRUE ), \ + bFooterOn ( TRUE ), \ + pDocHelper ( NULL ), \ + pAutoStyleList ( NULL ), \ + pOldJobSetup ( NULL ), \ + pPaintLockData ( NULL ), \ + nPrtToScreenFactor( 1.0 ), \ + bIsEmpty ( TRUE ), \ + bIsInUndo ( FALSE ), \ + bDocumentModifiedPending( FALSE ) + +//------------------------------------------------------------------ + +ScDocShell::ScDocShell( const ScDocShell& rShell ) + : SfxObjectShell( rShell.GetCreateMode() ), + aDdeTextFmt(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("TEXT"))), + bNoInformLost( TRUE ), + __SCDOCSHELL_INIT +{ + SetPool( &SC_MOD()->GetPool() ); + + SetShell(this); + eShellMode = rShell.eShellMode; + bIsInplace = rShell.bIsInplace; + + pDocFunc = new ScDocFunc(*this); + + // SetBaseModel needs exception handling + ScModelObj::CreateAndSet( this ); + + StartListening(*this); + SfxStyleSheetPool* pStlPool = aDocument.GetStyleSheetPool(); + if (pStlPool) + StartListening(*pStlPool); + + GetPageOnFromPageStyleSet( NULL, 0, bHeaderOn, bFooterOn ); + SetHelpId( HID_SCSHELL_DOCSH ); + + // InitItems und CalcOutputFactor werden jetzt nach bei Load/ConvertFrom/InitNew gerufen +} + +//------------------------------------------------------------------ + +ScDocShell::ScDocShell( SfxObjectCreateMode eMode ) + : SfxObjectShell( eMode ), + aDdeTextFmt(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("TEXT"))), + bNoInformLost( TRUE ), + __SCDOCSHELL_INIT +{ + SetPool( &SC_MOD()->GetPool() ); + + SetShell(this); + eShellMode = eMode; + bIsInplace = (eShellMode == SFX_CREATE_MODE_EMBEDDED); + // wird zurueckgesetzt, wenn nicht inplace + + pDocFunc = new ScDocFunc(*this); + + // SetBaseModel needs exception handling + ScModelObj::CreateAndSet( this ); + + StartListening(*this); + SfxStyleSheetPool* pStlPool = aDocument.GetStyleSheetPool(); + if (pStlPool) + StartListening(*pStlPool); + SetHelpId( HID_SCSHELL_DOCSH ); + + // InitItems und CalcOutputFactor werden jetzt nach bei Load/ConvertFrom/InitNew gerufen +} + +//------------------------------------------------------------------ + +__EXPORT ScDocShell::~ScDocShell() +{ + ResetDrawObjectShell(); // #55570# falls der Drawing-Layer noch versucht, darauf zuzugreifen + + SfxStyleSheetPool* pStlPool = aDocument.GetStyleSheetPool(); + if (pStlPool) + EndListening(*pStlPool); + EndListening(*this); + + delete pAutoStyleList; + + SfxApplication *pSfxApp = SFX_APP(); + if ( pSfxApp->GetDdeService() ) // DDE vor Dokument loeschen + pSfxApp->RemoveDdeTopic( this ); + + delete pDocFunc; + delete pUndoManager; + delete pFontList; + + delete pPaintLockData; + + delete pOldJobSetup; // gesetzt nur bei Fehler in StartJob() +} + +//------------------------------------------------------------------ + +SfxUndoManager* __EXPORT ScDocShell::GetUndoManager() +{ + if (!pUndoManager) + pUndoManager = new SfxUndoManager; + return pUndoManager; +} + +void ScDocShell::SetModified( BOOL bModified ) +{ + SfxInPlaceObject::SetModified( bModified ); + Broadcast( SfxSimpleHint( SFX_HINT_DOCCHANGED ) ); +} + + +void ScDocShell::SetDocumentModified( BOOL bIsModified /* = TRUE */ ) +{ + // BroadcastUno muss auch mit pPaintLockData sofort passieren + //! auch bei SetDrawModified, wenn Drawing angebunden ist + //! dann eigener Hint??? + + if (bIsModified) + aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) ); + + if ( pPaintLockData && bIsModified ) + { + pPaintLockData->SetModified(); // spaeter... + return; + } + + SetDrawModified( bIsModified ); + + if ( bIsModified ) + { + if ( aDocument.IsAutoCalcShellDisabled() ) + SetDocumentModifiedPending( TRUE ); + else + { + SetDocumentModifiedPending( FALSE ); + aDocument.InvalidateTableArea(); + aDocument.Broadcast( SC_HINT_DATACHANGED, BCA_BRDCST_ALWAYS, NULL ); + if ( aDocument.IsForcedFormulaPending() && aDocument.GetAutoCalc() ) + aDocument.CalcFormulaTree( TRUE ); + PostDataChanged(); + + // automatisches Detektiv-Update + + if ( aDocument.IsDetectiveDirty() ) + { + aDocument.SetDetectiveDirty(FALSE); // bei jedem Modified + + ScDetOpList* pList = aDocument.GetDetOpList(); + if ( pList && pList->Count() && !IsInUndo() && + SC_MOD()->GetAppOptions().GetDetectiveAuto() ) + { + GetDocFunc().DetectiveRefresh(TRUE); // TRUE = automatisch erzeugt + } + } + } + } +} + +// SetDrawModified - ohne Formel-Update +// (Drawing muss auch beim normalen SetDocumentModified upgedated werden, +// z.B. bei Tabelle loeschen etc.) + +void ScDocShell::SetDrawModified( BOOL bIsModified /* = TRUE */ ) +{ + BOOL bUpdate = ( bIsModified != IsModified() ); + + SetModified( bIsModified ); + + if (bUpdate) + { + SFX_BINDINGS().Invalidate( SID_SAVEDOC ); + SFX_BINDINGS().Invalidate( SID_DOC_MODIFIED ); + } + + if (bIsModified) + { + if ( aDocument.IsChartListenerCollectionNeedsUpdate() ) + { + aDocument.UpdateChartListenerCollection(); + SFX_APP()->Broadcast(SfxSimpleHint( SC_HINT_DRAW_CHANGED )); // Navigator + } + SC_MOD()->AnythingChanged(); + } +} + +void ScDocShell::SetInUndo(BOOL bSet) +{ + bIsInUndo = bSet; +} + + +void ScDocShell::GetDocStat( ScDocStat& rDocStat ) +{ + SfxPrinter* pPrinter = GetPrinter(); + + aDocument.GetDocStat( rDocStat ); + rDocStat.nPageCount = 0; + + if ( pPrinter ) + for ( USHORT i=0; i<rDocStat.nTableCount; i++ ) + rDocStat.nPageCount += + (USHORT) ScPrintFunc( this, pPrinter, i ).GetTotalPages(); +} + + +SfxDocumentInfoDialog* __EXPORT ScDocShell::CreateDocumentInfoDialog( + Window *pParent, const SfxItemSet &rSet ) +{ + SfxDocumentInfoDialog* pDlg = new SfxDocumentInfoDialog( pParent, rSet ); + ScDocShell* pDocSh = PTR_CAST(ScDocShell,SfxObjectShell::Current()); + + //nur mit Statistik, wenn dieses Doc auch angezeigt wird, nicht + //aus dem Doc-Manager + + if( pDocSh == this ) + pDlg->AddTabPage( 42, + ScGlobal::GetRscString( STR_DOC_STAT ), + ScDocStatPage::Create, + NULL ); + + return pDlg; +} + +Window* ScDocShell::GetDialogParent() +{ + ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); + if ( pViewSh ) + return pViewSh->GetDialogParent(); + else + return Application::GetDefDialogParent(); +} + + +// --- ScDocShellModificator ------------------------------------------ + +ScDocShellModificator::ScDocShellModificator( ScDocShell& rDS ) : + rDocShell( rDS ) +{ + ScDocument* pDoc = rDocShell.GetDocument(); + bAutoCalcShellDisabled = pDoc->IsAutoCalcShellDisabled(); + bIdleDisabled = pDoc->IsIdleDisabled(); + pDoc->SetAutoCalcShellDisabled( TRUE ); + pDoc->DisableIdle( TRUE ); +} + + +ScDocShellModificator::~ScDocShellModificator() +{ + ScDocument* pDoc = rDocShell.GetDocument(); + pDoc->SetAutoCalcShellDisabled( bAutoCalcShellDisabled ); + if ( !bAutoCalcShellDisabled && rDocShell.IsDocumentModifiedPending() ) + rDocShell.SetDocumentModified(); // der letzte macht das Licht aus + pDoc->DisableIdle( bIdleDisabled ); +} + + +void ScDocShellModificator::SetDocumentModified() +{ + ScDocument* pDoc = rDocShell.GetDocument(); + if ( !pDoc->IsImportingXML() ) + { + // AutoCalcShellDisabled temporaer restaurieren + BOOL bDisabled = pDoc->IsAutoCalcShellDisabled(); + pDoc->SetAutoCalcShellDisabled( bAutoCalcShellDisabled ); + rDocShell.SetDocumentModified(); + pDoc->SetAutoCalcShellDisabled( bDisabled ); + } + else + { + // uno broadcast is necessary for api to work + // -> must also be done during xml import + pDoc->BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) ); + } +} + + diff --git a/sc/source/ui/docshell/docsh2.cxx b/sc/source/ui/docshell/docsh2.cxx new file mode 100644 index 000000000000..717e413a0f74 --- /dev/null +++ b/sc/source/ui/docshell/docsh2.cxx @@ -0,0 +1,516 @@ +/************************************************************************* + * + * $RCSfile: docsh2.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +// System - Includes ----------------------------------------------------- + +// 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 _DYNARY_HXX +#define _SVMEMPOOL_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 _FILDLG_HXX +//#define _PRNDLG_HXX +#define _COLDLG_HXX +//#define _TABDLG_HXX +#ifdef WIN +#define _MENU_HXX +#endif +//#define _GDIMTF_HXX +//#define _POLY_HXX +//#define _ACCEL_HXX +//#define _GRAPH_HXX +#define _SOUND_HXX + +#if defined WIN +#define _MENUBTN_HXX +#endif + +//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 _SFX_BINDINGS_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 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 + + + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#ifndef _SVDPAGE_HXX //autogen +#include <svx/svdpage.hxx> +#endif + +#pragma hdrstop + + +#include "scitems.hxx" +#include <tools/gen.hxx> +#include <sfx2/interno.hxx> +#include <so3/svstor.hxx> +#include <svtools/ctrltool.hxx> +#include <svx/flstitem.hxx> +#include <svx/drawitem.hxx> +#include <sfx2/printer.hxx> +#include <svtools/smplhint.hxx> +#include <svx/svditer.hxx> +#include <svx/svdobj.hxx> +#include <svx/svdoole2.hxx> +#include <vcl/svapp.hxx> + + + +// INCLUDE --------------------------------------------------------------- +/* +#include <svdrwetc.hxx> +#include <svdrwobx.hxx> +#include <sostor.hxx> +*/ +#include "drwlayer.hxx" +#include "stlpool.hxx" +#include "docsh.hxx" +#include "docfunc.hxx" +#include "sc.hrc" + +//------------------------------------------------------------------ + +BOOL __EXPORT ScDocShell::InitNew( SvStorage * pStor ) +{ + BOOL bRet = SfxInPlaceObject::InitNew( pStor ); + + aDocument.MakeTable(0); + // zusaetzliche Tabellen werden von der ersten View angelegt, + // wenn bIsEmpty dann noch TRUE ist + + if ( !pStor ) + pStor = GetStorage(); + + if( bRet ) + { + Size aSize( (long) ( STD_COL_WIDTH * HMM_PER_TWIPS * OLE_STD_CELLS_X ), + (long) ( ScGlobal::nStdRowHeight * HMM_PER_TWIPS * OLE_STD_CELLS_Y ) ); + // hier muss auch der Start angepasst werden + SetVisAreaOrSize( Rectangle( Point(), aSize ), TRUE ); + } + + aDocument.GetStyleSheetPool()->CreateStandardStyles(); + aDocument.UpdStlShtPtrsFrmNms(); + InitOptions(); // CLOOK + + // SetDocumentModified ist in Load/InitNew nicht mehr erlaubt! + + InitItems(); + CalcOutputFactor(); + + return bRet; +} + +//------------------------------------------------------------------ + +BOOL ScDocShell::IsEmpty() const +{ + return bIsEmpty; +} + + +void ScDocShell::ResetEmpty() +{ + bIsEmpty = FALSE; +} + +//------------------------------------------------------------------ + +void ScDocShell::InitItems() +{ + // AllItemSet fuer Controller mit benoetigten Items fuellen: + + if ( pFontList ) + delete pFontList; + + // Druck-Optionen werden beim Drucken und evtl. in GetPrinter gesetzt + + pFontList = new FontList( GetPrinter(), Application::GetDefaultDevice() ); + PutItem( SvxFontListItem( pFontList, SID_ATTR_CHAR_FONTLIST ) ); + + ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer(); + if (pDrawLayer) + { + PutItem( SvxColorTableItem ( pDrawLayer->GetColorTable() ) ); + PutItem( SvxGradientListItem( pDrawLayer->GetGradientList() ) ); + PutItem( SvxHatchListItem ( pDrawLayer->GetHatchList() ) ); + PutItem( SvxBitmapListItem ( pDrawLayer->GetBitmapList() ) ); + PutItem( SvxDashListItem ( pDrawLayer->GetDashList() ) ); + PutItem( SvxLineEndListItem ( pDrawLayer->GetLineEndList() ) ); + + // andere Anpassungen nach dem Anlegen des DrawLayers + + pDrawLayer->SetNotifyUndoActionHdl( LINK( pDocFunc, ScDocFunc, NotifyDrawUndo ) ); + + //if (SfxObjectShell::HasSbxObject()) + pDrawLayer->UpdateBasic(); // DocShell-Basic in DrawPages setzen + } + else + { + // ColorTable wegen Farben fuer Tabelle + + PutItem( SvxColorTableItem( aDocument.GetColorTable() ) ); + } +} + +//------------------------------------------------------------------ + +void ScDocShell::ResetDrawObjectShell() +{ + ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer(); + if (pDrawLayer) + pDrawLayer->SetObjectShell( NULL ); +} + +//------------------------------------------------------------------ + +void __EXPORT ScDocShell::Activate() +{ +} + + +void __EXPORT ScDocShell::Deactivate() +{ +} + +//------------------------------------------------------------------ + + +ScDrawLayer* ScDocShell::MakeDrawLayer() +{ + ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer(); + if (!pDrawLayer) + { + aDocument.InitDrawLayer(this); + pDrawLayer = aDocument.GetDrawLayer(); + InitItems(); // incl. Undo und Basic + Broadcast( SfxSimpleHint( SC_HINT_DRWLAYER_NEW ) ); + } + return pDrawLayer; +} + +//------------------------------------------------------------------ + + +void ScDocShell::RemoveUnknownObjects() +{ + // OLE-Objekte loeschen, wenn kein Drawing-Objekt dazu existiert + // Loeschen wie in SvPersist::CleanUp + + ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer(); + const SvInfoObjectMemberList* pChildList = GetObjectList(); + + if( pChildList && pChildList->Count() ) + { + for( ULONG i=0; i<pChildList->Count(); ) + { + SvInfoObjectRef pEle = pChildList->GetObject(i); + String aObjName = pEle->GetObjName(); + BOOL bFound = FALSE; + if ( pDrawLayer ) + { + USHORT nTabCount = pDrawLayer->GetPageCount(); + for (USHORT nTab=0; nTab<nTabCount && !bFound; nTab++) + { + SdrPage* pPage = pDrawLayer->GetPage(nTab); + DBG_ASSERT(pPage,"Page ?"); + if (pPage) + { + SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); + SdrObject* pObject = aIter.Next(); + while (pObject && !bFound) + { + if ( pObject->ISA(SdrOle2Obj) && pObject->GetName() == aObjName ) + bFound = TRUE; + pObject = aIter.Next(); + } + } + } + } + + if (!bFound) + { + DBG_ASSERT(pEle->GetRefCount()==2, "Loeschen von referenziertem Storage"); + String aStorName(pEle->GetStorageName()); + SvPersist::Remove(pEle); + GetStorage()->Remove(aStorName); + } + else + i++; + } + } +} + + diff --git a/sc/source/ui/docshell/docsh3.cxx b/sc/source/ui/docshell/docsh3.cxx new file mode 100644 index 000000000000..6594b0e063ca --- /dev/null +++ b/sc/source/ui/docshell/docsh3.cxx @@ -0,0 +1,902 @@ +/************************************************************************* + * + * $RCSfile: docsh3.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#pragma hdrstop + +// INCLUDE --------------------------------------------------------------- + +#include "scitems.hxx" +#include "rangelst.hxx" +#include <svx/flstitem.hxx> +#include <svx/pageitem.hxx> +#include <svx/paperinf.hxx> +#include <svx/postattr.hxx> +//#include <svx/postdlg.hxx> +#include <svx/sizeitem.hxx> +#include <offmgr/app.hxx> + +#ifdef ONE_LINGU +#else +#include <offmgr/osplcfg.hxx> +#endif + +#include <sfx2/misccfg.hxx> +#include <sfx2/printer.hxx> +#include <svtools/ctrltool.hxx> +#include <vcl/virdev.hxx> +#include <vcl/svapp.hxx> +#include <vcl/msgbox.hxx> + +#include "docsh.hxx" +#include "scmod.hxx" +#include "tabvwsh.hxx" +#include "viewdata.hxx" +#include "docpool.hxx" +#include "stlpool.hxx" +#include "patattr.hxx" +#include "uiitems.hxx" +#include "hints.hxx" +#include "docoptio.hxx" +#include "viewopti.hxx" +#include "pntlock.hxx" +#include "chgtrack.hxx" +#include "docfunc.hxx" +#include "cell.hxx" +#include "chgviset.hxx" +#include "progress.hxx" +#include "redcom.hxx" +#include "sc.hrc" + +//------------------------------------------------------------------ + +// +// Redraw - Benachrichtigungen +// + + +void ScDocShell::PostEditView( ScEditEngineDefaulter* pEditEngine, const ScAddress& rCursorPos ) +{ +// Broadcast( ScEditViewHint( pEditEngine, rCursorPos ) ); + + // Test: nur aktive ViewShell + + ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); + if (pViewSh && pViewSh->GetViewData()->GetDocShell() == this) + { + ScEditViewHint aHint( pEditEngine, rCursorPos ); + pViewSh->Notify( *this, aHint ); + } +} + +void ScDocShell::PostDataChanged() +{ + Broadcast( SfxSimpleHint( FID_DATACHANGED ) ); + aDocument.ResetChanged( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB) ); + + SFX_APP()->Broadcast(SfxSimpleHint( FID_ANYDATACHANGED )); // Navigator + //! Navigator direkt benachrichtigen! +} + +void ScDocShell::PostPaint( USHORT nStartCol, USHORT nStartRow, USHORT nStartTab, + USHORT nEndCol, USHORT nEndRow, USHORT nEndTab, USHORT nPart, + USHORT nExtFlags ) +{ + if (nStartCol > MAXCOL) nStartCol = MAXCOL; + if (nStartRow > MAXROW) nStartRow = MAXROW; + if (nEndCol > MAXCOL) nEndCol = MAXCOL; + if (nEndRow > MAXROW) nEndRow = MAXROW; + + if ( pPaintLockData ) + { + //! nExtFlags ??? + pPaintLockData->AddRange( ScRange( nStartCol, nStartRow, nStartTab, + nEndCol, nEndRow, nEndTab ), nPart ); + return; + } + + + if (nExtFlags & SC_PF_LINES) // Platz fuer Linien bercksichtigen + { + //! Abfrage auf versteckte Spalten/Zeilen! + if (nStartCol>0) --nStartCol; + if (nEndCol<MAXCOL) ++nEndCol; + if (nStartRow>0) --nStartRow; + if (nEndRow<MAXROW) ++nEndRow; + } + + // um zusammengefasste erweitern + if (nExtFlags & SC_PF_TESTMERGE) + aDocument.ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nStartTab ); + + if ( nStartCol != 0 || nEndCol != MAXCOL ) // gedreht -> ganze Zeilen + { + if ( aDocument.HasAttrib( 0,nStartRow,nStartTab, + MAXCOL,nEndRow,nEndTab, HASATTR_ROTATE ) ) + { + nStartCol = 0; + nEndCol = MAXCOL; + } + } + + Broadcast( ScPaintHint( ScRange( nStartCol, nStartRow, nStartTab, + nEndCol, nEndRow, nEndTab ), nPart ) ); + + if ( nPart & PAINT_GRID ) + aDocument.ResetChanged( ScRange(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) ); +} + +void ScDocShell::PostPaint( const ScRange& rRange, USHORT nPart, USHORT nExtFlags ) +{ + PostPaint( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(), + rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(), + nPart, nExtFlags ); +} + +void ScDocShell::PostPaintGridAll() +{ + PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID ); +} + +void ScDocShell::PostPaintCell( USHORT nCol, USHORT nRow, USHORT nTab ) +{ + PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID, SC_PF_TESTMERGE ); +} + +void ScDocShell::PostPaintExtras() +{ + PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS ); +} + +//------------------------------------------------------------------ + +USHORT ScDocShell::GetLockCount() const +{ + if (pPaintLockData) + return pPaintLockData->GetLevel() + 1; // erster Lock setzt Level auf 0 + else + return 0; +} + +void ScDocShell::SetLockCount(USHORT nNew) +{ + if (nNew) // setzen + { + if ( !pPaintLockData ) + pPaintLockData = new ScPaintLockData(0); //! Modus... + pPaintLockData->SetLevel(nNew-1); + } + else if (pPaintLockData) // loeschen + { + pPaintLockData->SetLevel(0); // bei Unlock sofort ausfuehren + UnlockPaint(); // jetzt + } +} + +void ScDocShell::LockPaint() +{ + if ( pPaintLockData ) + pPaintLockData->IncLevel(); + else + pPaintLockData = new ScPaintLockData(0); //! Modus... +} + +void ScDocShell::UnlockPaint() +{ + if ( pPaintLockData ) + { + if ( pPaintLockData->GetLevel() ) + pPaintLockData->DecLevel(); + else + { + // Paint jetzt ausfuehren + + ScPaintLockData* pPaint = pPaintLockData; + pPaintLockData = NULL; // nicht weitersammeln + + ScRangeListRef xRangeList = pPaint->GetRangeList(); + if (xRangeList) + { + USHORT nParts = pPaint->GetParts(); + ULONG nCount = xRangeList->Count(); + for ( ULONG i=0; i<nCount; i++ ) + { + //! nExtFlags ??? + ScRange aRange = *xRangeList->GetObject(i); + PostPaint( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab(), + aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Tab(), + nParts ); + } + } + + if ( pPaint->GetModified() ) + SetDocumentModified(); + + delete pPaint; + } + } + else + DBG_ERROR("UnlockPaint ohne LockPaint"); +} + +//------------------------------------------------------------------ + +void ScDocShell::SetInplace( BOOL bInplace ) +{ + if (bIsInplace != bInplace) + { + bIsInplace = bInplace; + CalcOutputFactor(); + } +} + +void ScDocShell::CalcOutputFactor() +{ + if (bIsInplace) + { + nPrtToScreenFactor = 1.0; // passt sonst nicht zur inaktiven Darstellung + return; + } + + String aTestString = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789" )); + long nPrinterWidth = 0; + long nWindowWidth = 0; + const ScPatternAttr* pPattern = (const ScPatternAttr*)&aDocument.GetPool()-> + GetDefaultItem(ATTR_PATTERN); + + Font aDefFont; + Printer* pPrinter = GetPrinter(); + if (pPrinter) + { + MapMode aOldMode = pPrinter->GetMapMode(); + Font aOldFont = pPrinter->GetFont(); + + pPrinter->SetMapMode(MAP_PIXEL); + pPattern->GetFont(aDefFont, pPrinter); + pPrinter->SetFont(aDefFont); + nPrinterWidth = pPrinter->PixelToLogic( Size( pPrinter->GetTextWidth(aTestString), 0 ), + MAP_100TH_MM ).Width(); + pPrinter->SetFont(aOldFont); + pPrinter->SetMapMode(aOldMode); + } + else + DBG_ERROR("kein Drucker ?!?!?"); + + VirtualDevice aVirtWindow( *Application::GetDefaultDevice() ); + aVirtWindow.SetMapMode(MAP_PIXEL); + pPattern->GetFont(aDefFont, &aVirtWindow); + aVirtWindow.SetFont(aDefFont); + nWindowWidth = aVirtWindow.GetTextWidth(aTestString); + nWindowWidth = (long) ( nWindowWidth / ScGlobal::nScreenPPTX * HMM_PER_TWIPS ); + + if (nPrinterWidth && nWindowWidth) + nPrtToScreenFactor = nPrinterWidth / (double) nWindowWidth; + else + { + DBG_ERROR("GetTextSize gibt 0 ??"); + nPrtToScreenFactor = 1.0; + } +} + +double ScDocShell::GetOutputFactor() const +{ + return nPrtToScreenFactor; +} + +//--------------------------------------------------------------------- + +void ScDocShell::InitOptions() // Fortsetzung von InitNew (CLOOKs) +{ + // Einstellungen aus dem SpellCheckCfg kommen in Doc- und ViewOptions + +#ifdef ONE_LINGU + USHORT nDefLang; + BOOL bAutoSpell, bHideAuto; + ScModule::GetSpellSettings( nDefLang, bAutoSpell, bHideAuto ); +#else + OfaCfgSpellCheck* pSpellCheckCfg = OFF_APP()->GetSpellChecker(); +#endif + ScModule* pScMod = SC_MOD(); + + ScDocOptions aDocOpt = pScMod->GetDocOptions(); + ScViewOptions aViewOpt = pScMod->GetViewOptions(); +#ifdef ONE_LINGU + aDocOpt.SetAutoSpell( bAutoSpell ); + aViewOpt.SetHideAutoSpell( bHideAuto ); +#else + aDocOpt.SetAutoSpell( pSpellCheckCfg->IsAutoSpell() ); + aViewOpt.SetHideAutoSpell( pSpellCheckCfg->IsHideSpell() ); +#endif + + // zweistellige Jahreszahleneingabe aus Extras->Optionen->Allgemein->Sonstiges + aDocOpt.SetYear2000( SFX_APP()->GetMiscConfig()->GetYear2000() ); + + aDocument.SetDocOptions( aDocOpt ); + aDocument.SetViewOptions( aViewOpt ); + + // Druck-Optionen werden jetzt direkt vor dem Drucken gesetzt + +#ifdef ONE_LINGU + aDocument.SetLanguage( (LanguageType) nDefLang ); +#else + aDocument.SetLanguage( (LanguageType) pSpellCheckCfg->GetDefaultLanguage() ); +#endif +} + +//--------------------------------------------------------------------- + +Printer* ScDocShell::GetDocumentPrinter() // fuer OLE +{ + return aDocument.GetPrinter(); +} + +SfxPrinter* ScDocShell::GetPrinter() +{ + return aDocument.GetPrinter(); +} + +void ScDocShell::UpdateFontList() +{ + delete pFontList; + pFontList = new FontList( GetPrinter(), Application::GetDefaultDevice() ); + SvxFontListItem aFontListItem( pFontList, SID_ATTR_CHAR_FONTLIST ); + PutItem( aFontListItem ); + + CalcOutputFactor(); +} + +USHORT ScDocShell::SetPrinter( SfxPrinter* pNewPrinter, USHORT nDiffFlags ) +{ + if (nDiffFlags & SFX_PRINTER_PRINTER) + { + if ( aDocument.GetPrinter() != pNewPrinter ) + { + aDocument.SetPrinter( pNewPrinter ); + aDocument.SetPrintOptions(); + + delete pFontList; + pFontList = new FontList( pNewPrinter, Application::GetDefaultDevice() ); + SvxFontListItem aFontListItem( pFontList, SID_ATTR_CHAR_FONTLIST ); + PutItem( aFontListItem ); + + CalcOutputFactor(); + } + } + else if (nDiffFlags & SFX_PRINTER_JOBSETUP) + { + SfxPrinter* pOldPrinter = aDocument.GetPrinter(); + if (pOldPrinter) + pOldPrinter->SetJobSetup( pNewPrinter->GetJobSetup() ); + } + + if (nDiffFlags & SFX_PRINTER_OPTIONS) + { + aDocument.SetPrintOptions(); //! aus neuem Printer ??? + } + + if (nDiffFlags & (SFX_PRINTER_CHG_ORIENTATION | SFX_PRINTER_CHG_SIZE)) + { + String aStyle = aDocument.GetPageStyle( GetCurTab() ); + ScStyleSheetPool* pStPl = aDocument.GetStyleSheetPool(); + SfxStyleSheet* pStyleSheet = (SfxStyleSheet*)pStPl->Find(aStyle, SFX_STYLE_FAMILY_PAGE); + if (pStyleSheet) + { + SfxItemSet& rSet = pStyleSheet->GetItemSet(); + + if (nDiffFlags & SFX_PRINTER_CHG_ORIENTATION) + { + const SvxPageItem& rOldItem = (const SvxPageItem&)rSet.Get(ATTR_PAGE); + BOOL bWasLand = rOldItem.IsLandscape(); + BOOL bNewLand = ( pNewPrinter->GetOrientation() == ORIENTATION_LANDSCAPE ); + if (bNewLand != bWasLand) + { + SvxPageItem aNewItem( rOldItem ); + aNewItem.SetLandscape( bNewLand ); + rSet.Put( aNewItem ); + + // Groesse umdrehen + Size aOldSize = ((const SvxSizeItem&)rSet.Get(ATTR_PAGE_SIZE)).GetSize(); + Size aNewSize(aOldSize.Height(),aOldSize.Width()); + SvxSizeItem aNewSItem(ATTR_PAGE_SIZE,aNewSize); + rSet.Put( aNewSItem ); + } + } + if (nDiffFlags & SFX_PRINTER_CHG_SIZE) + { + SvxSizeItem aPaperSizeItem( ATTR_PAGE_SIZE, SvxPaperInfo::GetPaperSize(pNewPrinter) ); + rSet.Put( aPaperSizeItem ); + } + } + } + + PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB,PAINT_ALL); + + return 0; +} + +//--------------------------------------------------------------------- + +ScChangeAction* ScDocShell::GetChangeAction( const ScAddress& rPos ) +{ + ScChangeTrack* pTrack = GetDocument()->GetChangeTrack(); + if (!pTrack) + return NULL; + + USHORT nTab = rPos.Tab(); + + const ScChangeAction* pFound = NULL; + const ScChangeAction* pFoundContent = NULL; + const ScChangeAction* pFoundMove = NULL; + long nModified = 0; + const ScChangeAction* pAction = pTrack->GetFirst(); + while (pAction) + { + ScChangeActionType eType = pAction->GetType(); + //! ScViewUtil::IsActionShown( *pAction, *pSettings, *pDoc )... + if ( pAction->IsVisible() && eType != SC_CAT_DELETE_TABS ) + { + 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( rPos ) ) + { + pFound = pAction; // der letzte gewinnt + switch ( pAction->GetType() ) + { + case SC_CAT_CONTENT : + pFoundContent = pAction; + break; + case SC_CAT_MOVE : + pFoundMove = pAction; + break; + } + ++nModified; + } + } + if ( pAction->GetType() == SC_CAT_MOVE ) + { + ScRange aRange = + ((const ScChangeActionMove*)pAction)-> + GetFromRange().MakeRange(); + if ( aRange.In( rPos ) ) + { + pFound = pAction; + ++nModified; + } + } + } + pAction = pAction->GetNext(); + } + + return (ScChangeAction*)pFound; +} + +void ScDocShell::SetChangeComment( ScChangeAction* pAction, const String& rComment ) +{ + if (pAction) + { + pAction->SetComment( rComment ); + //! Undo ??? + SetDocumentModified(); + + // Dialog-Notify + ScChangeTrack* pTrack = GetDocument()->GetChangeTrack(); + if (pTrack) + { + ULONG nNumber = pAction->GetActionNumber(); + pTrack->NotifyModified( SC_CTM_CHANGE, nNumber, nNumber ); + } + } +} + +void ScDocShell::ExecuteChangeCommentDialog( ScChangeAction* pAction, Window* pParent,BOOL bPrevNext) +{ + if (!pAction) return; // ohne Aktion ist nichts.. + + String aComment = pAction->GetComment(); + String aAuthor = pAction->GetUser(); + + International* pIntl = ScGlobal::pScInternational; + DateTime aDT = pAction->GetDateTime(); + String aDate = pIntl->GetDate( aDT ); + aDate += ' '; + aDate += pIntl->GetTime( aDT, FALSE, FALSE ); + + SfxItemSet aSet( GetPool(), + SID_ATTR_POSTIT_AUTHOR, SID_ATTR_POSTIT_AUTHOR, + SID_ATTR_POSTIT_DATE, SID_ATTR_POSTIT_DATE, + SID_ATTR_POSTIT_TEXT, SID_ATTR_POSTIT_TEXT, + 0 ); + + aSet.Put( SvxPostItTextItem ( aComment, SID_ATTR_POSTIT_TEXT ) ); + aSet.Put( SvxPostItAuthorItem( aAuthor, SID_ATTR_POSTIT_AUTHOR ) ); + aSet.Put( SvxPostItDateItem ( aDate, SID_ATTR_POSTIT_DATE ) ); + + ScRedComDialog* pDlg = new ScRedComDialog( pParent, aSet,this,pAction,bPrevNext); + + pDlg->Execute(); + + delete pDlg; +} + +//--------------------------------------------------------------------- + +void ScDocShell::CompareDocument( ScDocument& rOtherDoc ) +{ + ScChangeTrack* pTrack = aDocument.GetChangeTrack(); + if ( pTrack && pTrack->GetFirst() ) + { + //! Changes vorhanden -> Nachfrage ob geloescht werden soll + } + + aDocument.EndChangeTracking(); + aDocument.StartChangeTracking(); + + aDocument.CompareDocument( rOtherDoc ); + + PostPaintGridAll(); + SetDocumentModified(); +} + +//--------------------------------------------------------------------- +// +// Merge (Aenderungen zusammenfuehren) +// +//--------------------------------------------------------------------- + +BOOL lcl_Equal( const ScChangeAction* pA, const ScChangeAction* pB ) +{ + return pA && pB && + pA->GetUser() == pB->GetUser() && + pA->GetType() == pB->GetType() && + pA->GetActionNumber() == pB->GetActionNumber() && + pA->GetDateTimeUTC() == pB->GetDateTimeUTC(); + // State nicht vergleichen, falls eine alte Aenderung akzeptiert wurde +} + +void ScDocShell::MergeDocument( ScDocument& rOtherDoc ) +{ + ScTabViewShell* pViewSh = GetBestViewShell(); //! Funktionen an die DocShell + if (!pViewSh) + return; + + ScChangeTrack* pSourceTrack = rOtherDoc.GetChangeTrack(); + if (!pSourceTrack) + return; //! nichts zu tun - Fehlermeldung? + + ScChangeTrack* pThisTrack = aDocument.GetChangeTrack(); + if ( !pThisTrack ) + { // anschalten + aDocument.StartChangeTracking(); + pThisTrack = aDocument.GetChangeTrack(); + DBG_ASSERT(pThisTrack,"ChangeTracking nicht angeschaltet?"); + // #51138# visuelles RedLining einschalten + ScChangeViewSettings aChangeViewSet; + aChangeViewSet.SetShowChanges(TRUE); + aDocument.SetChangeViewSettings(aChangeViewSet); + } + + + // gemeinsame Ausgangsposition suchen + ULONG nFirstNewNumber = 0; + const ScChangeAction* pSourceAction = pSourceTrack->GetFirst(); + const ScChangeAction* pThisAction = pThisTrack->GetFirst(); + while ( lcl_Equal( pSourceAction, pThisAction ) ) // gleiche Aktionen ueberspringen + { + nFirstNewNumber = pSourceAction->GetActionNumber() + 1; + pSourceAction = pSourceAction->GetNext(); + pThisAction = pThisAction->GetNext(); + } + // pSourceAction und pThisAction zeigen jetzt auf die ersten "eigenen" Aktionen + // Die gemeinsamen Aktionen davor interessieren ueberhaupt nicht + + //! Abfrage, ob die Dokumente vor dem Change-Tracking gleich waren !!! + + + const ScChangeAction* pFirstMergeAction = pSourceAction; + // MergeChangeData aus den folgenden Aktionen erzeugen + ULONG nNewActionCount = 0; + const ScChangeAction* pCount = pSourceAction; + while ( pCount ) + { + if ( !ScChangeTrack::MergeIgnore( *pCount, nFirstNewNumber ) ) + ++nNewActionCount; + pCount = pCount->GetNext(); + } + if (!nNewActionCount) + return; //! nichts zu tun - Fehlermeldung? + // ab hier kein return mehr + + ScProgress aProgress( this, + String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("...")), + nNewActionCount ); + + ULONG nLastMergeAction = pSourceTrack->GetLast()->GetActionNumber(); + // UpdateReference-Undo, gueltige Referenzen fuer den letzten gemeinsamen Zustand + pSourceTrack->MergePrepare( (ScChangeAction*) pFirstMergeAction ); + + // MergeChangeData an alle noch folgenden Aktionen in diesem Dokument anpassen + // -> Referenzen gueltig fuer dieses Dokument + while ( pThisAction ) + { + ScChangeActionType eType = pThisAction->GetType(); + switch ( eType ) + { + case SC_CAT_INSERT_COLS : + case SC_CAT_INSERT_ROWS : + case SC_CAT_INSERT_TABS : + pSourceTrack->AppendInsert( pThisAction->GetBigRange().MakeRange() ); + break; + case SC_CAT_DELETE_COLS : + case SC_CAT_DELETE_ROWS : + case SC_CAT_DELETE_TABS : + { + const ScChangeActionDel* pDel = (const ScChangeActionDel*) pThisAction; + if ( pDel->IsTopDelete() && !pDel->IsTabDeleteCol() ) + { // deleted Table enthaelt deleted Cols, die nicht + ULONG nStart, nEnd; + pSourceTrack->AppendDeleteRange( + pDel->GetOverAllRange().MakeRange(), NULL, nStart, nEnd ); + } + } + break; + case SC_CAT_MOVE : + { + const ScChangeActionMove* pMove = (const ScChangeActionMove*) pThisAction; + pSourceTrack->AppendMove( pMove->GetFromRange().MakeRange(), + pMove->GetBigRange().MakeRange(), NULL ); + } + break; + } + pThisAction = pThisAction->GetNext(); + } + + + // MergeChangeData in das aktuelle Dokument uebernehmen + BOOL bHasRejected = FALSE; + String aOldUser = pThisTrack->GetUser(); + pThisTrack->SetUseFixDateTime( TRUE ); + ScMarkData& rMarkData = pViewSh->GetViewData()->GetMarkData(); + ScMarkData aOldMarkData( rMarkData ); + pSourceAction = pFirstMergeAction; + while ( pSourceAction && pSourceAction->GetActionNumber() <= nLastMergeAction ) + { + if ( !ScChangeTrack::MergeIgnore( *pSourceAction, nFirstNewNumber ) ) + { + ScChangeActionType eSourceType = pSourceAction->GetType(); + if ( pSourceAction->IsDeletedIn() ) + { + //! muss hier noch festgestellt werden, ob wirklich in + //! _diesem_ Dokument geloescht? + + // liegt in einem Bereich, der in diesem Dokument geloescht wurde + // -> wird weggelassen + //! ??? Loesch-Aktion rueckgaengig machen ??? + //! ??? Aktion irgendwo anders speichern ??? +#ifndef PRODUCT + String aValue; + if ( eSourceType == SC_CAT_CONTENT ) + ((const ScChangeActionContent*)pSourceAction)->GetNewString( aValue ); + ByteString aError( aValue, gsl_getSystemTextEncoding() ); + aError += " weggelassen"; + DBG_ERROR( aError.GetBuffer() ); +#endif + } + else + { + //! Datum/Autor/Kommentar der Source-Aktion uebernehmen! + + pThisTrack->SetUser( pSourceAction->GetUser() ); + pThisTrack->SetFixDateTimeUTC( pSourceAction->GetDateTimeUTC() ); + ULONG nNextAction = pThisTrack->GetActionMax() + 1; + + ULONG nReject = pSourceAction->GetRejectAction(); + if (nReject) + { + // alte Aktion (aus den gemeinsamen) ablehnen + ScChangeAction* pOldAction = pThisTrack->GetAction( nReject ); + if (pOldAction && pOldAction->GetState() == SC_CAS_VIRGIN) + { + //! was passiert bei Aktionen, die in diesem Dokument accepted worden sind??? + //! Fehlermeldung oder was??? + //! oder Reject-Aenderung normal ausfuehren + + pThisTrack->Reject(pOldAction); + bHasRejected = TRUE; // fuer Paint + } + } + else + { + // normal ausfuehren + ScRange aSourceRange = pSourceAction->GetBigRange().MakeRange(); + rMarkData.SelectOneTable( aSourceRange.aStart.Tab() ); + switch ( eSourceType ) + { + case SC_CAT_CONTENT: + { + //! Test, ob es ganz unten im Dokument war, dann automatisches + //! Zeilen-Einfuegen ??? + + DBG_ASSERT( aSourceRange.aStart == aSourceRange.aEnd, "huch?" ); + ScAddress aPos = aSourceRange.aStart; + String aValue; + ((const ScChangeActionContent*)pSourceAction)->GetNewString( aValue ); + BYTE eMatrix = MM_NONE; + const ScBaseCell* pCell = ((const ScChangeActionContent*)pSourceAction)->GetNewCell(); + if ( pCell->GetCellType() == CELLTYPE_FORMULA ) + eMatrix = ((const ScFormulaCell*)pCell)->GetMatrixFlag(); + switch ( eMatrix ) + { + case MM_NONE : + pViewSh->EnterData( aPos.Col(), aPos.Row(), aPos.Tab(), aValue ); + break; + case MM_FORMULA : + { + USHORT nCols, nRows; + ((const ScFormulaCell*)pCell)->GetMatColsRows( nCols, nRows ); + aSourceRange.aEnd.SetCol( aPos.Col() + nCols - 1 ); + aSourceRange.aEnd.SetRow( aPos.Row() + nRows - 1 ); + aValue.Erase( 0, 1 ); + aValue.Erase( aValue.Len()-1, 1 ); + GetDocFunc().EnterMatrix( aSourceRange, NULL, aValue, FALSE ); + } + break; + case MM_REFERENCE : // do nothing + break; + case MM_FAKE : + DBG_WARNING( "MergeDocument: MatrixFlag MM_FAKE" ); + pViewSh->EnterData( aPos.Col(), aPos.Row(), aPos.Tab(), aValue ); + break; + default: + DBG_ERROR( "MergeDocument: unknown MatrixFlag" ); + } + } + break; + case SC_CAT_INSERT_TABS : + { + String aName; + aDocument.CreateValidTabName( aName ); + GetDocFunc().InsertTable( aSourceRange.aStart.Tab(), aName, TRUE, FALSE ); + } + break; + case SC_CAT_INSERT_ROWS: + GetDocFunc().InsertCells( aSourceRange, INS_INSROWS, TRUE, FALSE ); + break; + case SC_CAT_INSERT_COLS: + GetDocFunc().InsertCells( aSourceRange, INS_INSCOLS, TRUE, FALSE ); + break; + case SC_CAT_DELETE_TABS : + GetDocFunc().DeleteTable( aSourceRange.aStart.Tab(), TRUE, FALSE ); + break; + case SC_CAT_DELETE_ROWS: + { + const ScChangeActionDel* pDel = (const ScChangeActionDel*) pSourceAction; + if ( pDel->IsTopDelete() ) + { + aSourceRange = pDel->GetOverAllRange().MakeRange(); + GetDocFunc().DeleteCells( aSourceRange, DEL_DELROWS, TRUE, FALSE ); + } + } + break; + case SC_CAT_DELETE_COLS: + { + const ScChangeActionDel* pDel = (const ScChangeActionDel*) pSourceAction; + if ( pDel->IsTopDelete() && !pDel->IsTabDeleteCol() ) + { // deleted Table enthaelt deleted Cols, die nicht + aSourceRange = pDel->GetOverAllRange().MakeRange(); + GetDocFunc().DeleteCells( aSourceRange, DEL_DELCOLS, TRUE, FALSE ); + } + } + break; + case SC_CAT_MOVE : + { + const ScChangeActionMove* pMove = (const ScChangeActionMove*) pSourceAction; + ScRange aFromRange( pMove->GetFromRange().MakeRange() ); + GetDocFunc().MoveBlock( aFromRange, + aSourceRange.aStart, TRUE, TRUE, FALSE, FALSE ); + } + break; + } + } + const String& rComment = pSourceAction->GetComment(); + if ( rComment.Len() ) + { + ScChangeAction* pAct = pThisTrack->GetLast(); + if ( pAct && pAct->GetActionNumber() >= nNextAction ) + pAct->SetComment( rComment ); +#ifndef PRODUCT + else + DBG_ERROR( "MergeDocument: wohin mit dem Kommentar?!?" ); +#endif + } + + // Referenzen anpassen + pSourceTrack->MergeOwn( (ScChangeAction*) pSourceAction, nFirstNewNumber ); + } + aProgress.SetStateCountDown( --nNewActionCount ); + } + pSourceAction = pSourceAction->GetNext(); + } + rMarkData = aOldMarkData; + pThisTrack->SetUser(aOldUser); + pThisTrack->SetUseFixDateTime( FALSE ); + + pSourceTrack->Clear(); //! der ist jetzt verhunzt + + if (bHasRejected) + PostPaintGridAll(); // Reject() paintet nicht selber +} + + + + + diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx new file mode 100644 index 000000000000..0e06c13ebea1 --- /dev/null +++ b/sc/source/ui/docshell/docsh4.cxx @@ -0,0 +1,2004 @@ +/************************************************************************* + * + * $RCSfile: docsh4.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#pragma hdrstop + + +// INCLUDE --------------------------------------------------------------- +#if STLPORT_VERSION>=321 +#include <math.h> // prevent conflict between exception and std::exception +#endif + +#include <sdb/sdbenv.hxx> +#include "scitems.hxx" +#include <sfx2/bindings.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/docfilt.hxx> +#include <svtools/ehdl.hxx> +#include <svtools/sbxcore.hxx> +#include <sfx2/printer.hxx> +#include <sfx2/request.hxx> +#include <svtools/sfxecode.hxx> +#include <sfx2/topfrm.hxx> +#include <offmgr/ofaitem.hxx> +#include <offmgr/sbaitems.hxx> +#include <sot/formats.hxx> +#include <sdb/sdbstat.hxx> +#include <svtools/printdlg.hxx> +#include <svtools/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 <sch/schdll.hxx> +#ifndef _SVX_FMSHELL_HXX //autogen +#include <svx/fmshell.hxx> +#endif + + +#include "docsh.hxx" +#include "docfunc.hxx" +#include "sc.hrc" +#include "stlsheet.hxx" +#include "stlpool.hxx" +#include "appoptio.hxx" +#include "globstr.hrc" +#include "global.hxx" +#include "styledlg.hxx" +#include "hfedtdlg.hxx" +#include "dbdocfun.hxx" +#include "printfun.hxx" // DrawToDev +#include "viewdata.hxx" +#include "tabvwsh.hxx" +#include "dataobj.hxx" +#include "impex.hxx" +#include "attrib.hxx" +#include "corodlg.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 "scendlg.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" + +//------------------------------------------------------------------ + +#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 + + +//------------------------------------------------------------------ + +Window* lcl_GetDialogParent() +{ + ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); + return pViewSh ? pViewSh->GetDialogParent() : Application::GetDefDialogParent(); +} + +//------------------------------------------------------------------ + +BOOL ScDocShell::GetTabParam( const SfxItemSet* pArgs, USHORT nId, USHORT& rTab ) +{ + BOOL bOk = TRUE; + rTab = 0; // zur Sicherheit... + + const SfxPoolItem* pTabItem; + if ( pArgs && pArgs->GetItemState( nId, TRUE, &pTabItem ) == SFX_ITEM_SET ) + { + // Parameter sind 1-based !!! + USHORT nItemTab = ((const SfxUInt16Item*)pTabItem)->GetValue(); + USHORT nTabCount = aDocument.GetTableCount(); + if (nItemTab>0 && nItemTab<=nTabCount) + rTab = nItemTab-1; + else + bOk = FALSE; + } + else // nichts angegeben -> sichtbare + { + ScTabViewShell* pVisibleSh = GetBestViewShell(); + if ( pVisibleSh ) + rTab = pVisibleSh->GetViewData()->GetTabNo(); + else + bOk = FALSE; + } + + return bOk; +} + +//------------------------------------------------------------------ + +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& rBindings = SFX_BINDINGS(); + + 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 !!! + USHORT nCol = ((SfxUInt16Item*)pColItem)->GetValue() - 1; + USHORT nRow = ((SfxUInt16Item*)pRowItem)->GetValue() - 1; + USHORT nTab = ((SfxUInt16Item*)pTabItem)->GetValue() - 1; + + USHORT nTabCount = aDocument.GetTableCount(); + if ( nCol <= MAXCOL && nRow <= MAXROW && 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(); + + 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 = dbTable; // "0" oder "1" + if ( sTabFlag.EqualsAscii("0") ) // "0" = Query, "1" = Table (Default) + nType = dbQuery; + + 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 ) & SCA_VALID ) + { + bMakeArea = TRUE; + String aStrImport = ScGlobal::GetRscString( STR_UNDO_IMPORTDATA ); + GetUndoManager()->EnterListAction( aStrImport, aStrImport ); + + ScDBData* pDBData = GetDBData( ScRange(aPos), SC_DB_IMPORT, FALSE ); + 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, pSelectionList ); + rReq.Done(); + + // UpdateImport aktualisiert auch die internen Operationen + } + else + rReq.Ignore(); + + if ( bMakeArea ) + GetUndoManager()->LeaveListAction(); + } + else + DBG_ERROR( "arguments expected" ); + } + break; + + case SID_CHART_SOURCE: + case SID_CHART_ADDSOURCE: + if (pReqArgs) + { + ScDocument* pDoc = GetDocument(); + 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; + } + + BOOL bValid = ( aSingleRange.ParseAny( aRangeName, pDoc ) & 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(); + Window* pDataWin = pViewSh->GetActiveWin(); + + USHORT nCol1 = aSingleRange.aStart.Col(); + USHORT nRow1 = aSingleRange.aStart.Row(); + USHORT nCol2 = aSingleRange.aEnd.Col(); + USHORT nRow2 = aSingleRange.aEnd.Row(); + USHORT 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 + USHORT i; + if (!bColInit) + for (i=nCol1; i<=nCol2 && bColHeaders; i++) + if (aDocument.HasValueData( i, nRow1, nTab )) + bColHeaders = FALSE; + if (!bRowInit) + for (i=nRow1; i<=nRow2 && bRowHeaders; i++) + if (aDocument.HasValueData( nCol1, i, nTab )) + bRowHeaders = FALSE; + + ScColRowLabelDlg aDlg( pParent, bRowHeaders, bColHeaders ); + if ( aDlg.Execute() == RET_OK ) + { + bColHeaders = aDlg.IsRow(); // Spaltenkoepfe = 1. Zeile + bRowHeaders = aDlg.IsCol(); + + rReq.AppendItem(SfxBoolItem(FN_PARAM_1, bColHeaders)); + rReq.AppendItem(SfxBoolItem(FN_PARAM_2, bRowHeaders)); + } + else + bOk = FALSE; + } + + if (bOk) // ausfuehren + { + if (bMultiRange) + { + GetUndoManager()->AddUndoAction( + new ScUndoChartData( this, aChartName, aRangeListRef, + bColHeaders, bRowHeaders, bAddRange ) ); + aDocument.UpdateChartArea( aChartName, aRangeListRef, + bColHeaders, bRowHeaders, bAddRange, + pDataWin ); + } + else + { + ScRange aNewRange( nCol1,nRow1,nTab, nCol2,nRow2,nTab ); + GetUndoManager()->AddUndoAction( + new ScUndoChartData( this, aChartName, aNewRange, + bColHeaders, bRowHeaders, bAddRange ) ); + aDocument.UpdateChartArea( aChartName, aNewRange, + bColHeaders, bRowHeaders, bAddRange, + pDataWin ); + } + } + } + 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(); + rBindings.Invalidate( FID_AUTO_CALC ); +// rBindings.Invalidate( FID_RECALC ); // jetzt immer enabled + 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(nSet==LM_ON_DEMAND) + { + QueryBox aBox( lcl_GetDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES), + ScGlobal::GetRscString(STR_RELOAD_TABLES) ); + + nDlgRet=aBox.Execute(); + } + + if (nDlgRet == RET_YES || nSet==LM_ALWAYS) + { + ReloadTabLinks(); + 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; + ScRange aRange; + ScDBCollection* pDBColl = aDocument.GetDBCollection(); + ScTabViewShell* pViewSh = GetBestViewShell(); + DBG_ASSERT(pViewSh,"SID_REIMPORT_AFTER_LOAD: keine View"); + if (pViewSh && pDBColl) + { + QueryBox aBox( lcl_GetDialogParent(), 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) + { + if(pDoc->GetChangeTrack()!=NULL) + { + WarningBox aBox( lcl_GetDialogParent(), WinBits(WB_YES_NO | WB_DEF_NO), + ScGlobal::GetRscString( STR_END_REDLINING ) ); + + if(aBox.Execute()==RET_YES) + { + pDoc->EndChangeTracking(); + PostPaintGridAll(); + } + } + else + { + pDoc->StartChangeTracking(); + ScChangeViewSettings aChangeViewSet; + aChangeViewSet.SetShowChanges(TRUE); + pDoc->SetChangeViewSettings(aChangeViewSet); + } + + // 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(); + } + } + // Slots invalidieren + rBindings.InvalidateAll(FALSE); + } + } + break; + + case SID_DOCUMENT_MERGE: + case SID_DOCUMENT_COMPARE: + { + //! bei COMPARE eine Warnung, dass alte Changes verlorengehen ??!?!? + + 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 ); + + const SfxFilter* pFilter = pApp->GetFilter( ScDocShell::Factory(), 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, TRUE, pFilter, pSet ); + } + else + { + pMed = pApp->InsertDocumentDialog( 0, ScDocShell::Factory() ); + if ( pMed ) + { + // kompletten Request zum Aufzeichnen zusammenbasteln + rReq.AppendItem( SfxStringItem( SID_FILE_NAME, pMed->GetName() ) ); + if ( nSlot == SID_DOCUMENT_COMPARE ) + { + // Filter und Options nur bei Compare + if (pMed->GetFilter()) + rReq.AppendItem( SfxStringItem( SID_FILTER_NAME, + pMed->GetFilter()->GetFilterName() ) ); + String aOptions = ScDocumentLoader::GetOptions(*pMed); + if (aOptions.Len()) + rReq.AppendItem( SfxStringItem( SID_FILE_FILTEROPTIONS, aOptions ) ); + } + SfxItemSet* pSet = pMed->GetItemSet(); + if ( pSet && + pSet->GetItemState( SID_VERSION, TRUE, &pItem ) == SFX_ITEM_SET && + pItem->ISA(SfxInt16Item) ) + { + rReq.AppendItem( *pItem ); + } + } + } + + if ( pMed ) // nun wirklich ausfuehren... + { + SfxErrorContext aEc( ERRCTX_SFX_OPENDOC, pMed->GetName() ); + + ScDocShell* pOtherDocSh = new ScDocShell; + SvEmbeddedObjectRef 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 ); + + if ( nSlot == SID_DOCUMENT_COMPARE ) + CompareDocument( *pOtherDocSh->GetDocument() ); + else + MergeDocument( *pOtherDocSh->GetDocument() ); + + // show "accept changes" dialog + //! get view for this document! + + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); + if (pViewFrm) + pViewFrm->ShowChildWindow(ScAcceptChgDlgWrapper::GetChildWindowId(),TRUE); //@51669 + SFX_BINDINGS().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); + } + } + } + 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(); + USHORT nTab; + if (aDocument.GetTable( aName, nTab )) + { + // DeleteTable von viewfunc nach docfunc verschieben! + + ScTabViewShell* pSh = GetBestViewShell(); + if ( pSh ) + { + //! SetTabNo in DeleteTable weglassen? + USHORT 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(); + USHORT nTab; + if (aDocument.GetTable( aName, nTab )) + { + if (aDocument.IsScenario(nTab)) + { + String aComment; + Color aColor; + USHORT nFlags; + aDocument.GetScenarioData( nTab, aComment, aColor, nFlags ); + + //! anderen Titel am Dialog setzen + ScNewScenarioDlg* pNewDlg = + new ScNewScenarioDlg( lcl_GetDialogParent(), aName, TRUE ); + 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; + + default: + { + // kleiner (?) Hack -> forward der Slots an TabViewShell + ScTabViewShell* pSh = GetBestViewShell(); + if ( pSh ) + pSh->Execute( rReq ); + else + SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT ); + } + } +} + +//------------------------------------------------------------------ + +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( GetDialogParent() ); + aDocument.CalcFormulaTree(); + if ( pSh ) + pSh->UpdateCharts(TRUE); + + // #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( GetDialogParent() ); + ScTabViewShell* pSh = GetBestViewShell(); + if ( pSh ) + { + pSh->UpdateInputLine(); // InputEnterHandler + pSh->UpdateInputHandler(); + } + aDocument.CalcAll(); + GetDocFunc().DetectiveRefresh(); // erzeugt eigenes Undo + if ( pSh ) + pSh->UpdateCharts(TRUE); + 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"); + USHORT nTab = rRange.aStart.Tab(); + USHORT nStartCol = rRange.aStart.Col(); + USHORT nStartRow = rRange.aStart.Row(); + USHORT nEndCol = rRange.aEnd.Col(); + USHORT 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 ); + + USHORT nTabCount = aDocument.GetTableCount(); + for (USHORT 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& rBindings = SFX_BINDINGS(); + rBindings.Invalidate( SID_STATUS_PAGESTYLE ); + rBindings.Invalidate( SID_STYLE_FAMILY4 ); + rBindings.Invalidate( FID_RESET_PRINTZOOM ); + } + } + } + + // alles andere geht ueber Slots... +} + +// wie in printfun.cxx +#define ZOOM_MIN 10 + +void ScDocShell::SetPrintZoom( USHORT nTab, USHORT nScale, USHORT nPages ) +{ + 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(); + 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& rBindings = SFX_BINDINGS(); + rBindings.Invalidate( FID_RESET_PRINTZOOM ); + } +} + +BOOL ScDocShell::AdjustPrintZoom( const ScRange& rRange ) +{ + BOOL bChange = FALSE; + USHORT 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; + USHORT i; + + long nBlkTwipsX = 0; + if (bHeaders) + nBlkTwipsX += PRINT_HEADER_WIDTH; + USHORT nStartCol = rRange.aStart.Col(); + USHORT nEndCol = rRange.aEnd.Col(); + if ( pRepeatCol && nStartCol >= pRepeatCol->aStart.Col() ) + { + for ( i=pRepeatCol->aStart.Col(); i<=pRepeatCol->aEnd.Col(); i++ ) + nBlkTwipsX += aDocument.GetColWidth( i, nTab ); + if ( nStartCol <= pRepeatCol->aEnd.Col() ) + nStartCol = pRepeatCol->aEnd.Col() + 1; + } + for ( i=nStartCol; i<=nEndCol; i++ ) + nBlkTwipsX += aDocument.GetColWidth( i, nTab ); + + long nBlkTwipsY = 0; + if (bHeaders) + nBlkTwipsY += PRINT_HEADER_HEIGHT; + USHORT nStartRow = rRange.aStart.Row(); + USHORT nEndRow = rRange.aEnd.Row(); + if ( pRepeatRow && nStartRow >= pRepeatRow->aStart.Row() ) + { + for ( i=pRepeatRow->aStart.Row(); i<=pRepeatRow->aEnd.Row(); i++ ) + nBlkTwipsY += aDocument.FastGetRowHeight( i, nTab ); + if ( nStartRow <= pRepeatRow->aEnd.Row() ) + nStartRow = pRepeatRow->aEnd.Row() + 1; + } + for ( i=nStartRow; i<=nEndRow; i++ ) + nBlkTwipsY += aDocument.FastGetRowHeight( i, nTab ); + + Size aPhysPage; + long nHdr, nFtr; + ScPrintFunc aOldPrFunc( this, GetPrinter(), nTab ); + aOldPrFunc.GetScaleData( aPhysPage, nHdr, nFtr ); + nBlkTwipsY += nHdr + nFtr; + + 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; + + USHORT nTabCount = aDocument.GetTableCount(); + USHORT nUseTab = MAXTAB+1; + for (USHORT 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 (nUseTab<=MAXTAB) // 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( GetDialogParent() ); + InfoBox aInfoBox(GetDialogParent(), + ScGlobal::GetRscString(STR_PRINT_INVALID_AREA)); + aInfoBox.Execute(); + } + } + + aModificator.SetDocumentModified(); + + SFX_BINDINGS().Invalidate( FID_RESET_PRINTZOOM ); +} + +void ScDocShell::ExecutePageStyle( SfxViewShell& rCaller, + SfxRequest& rReq, + USHORT 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 ) + { + 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; + aOldData.InitFromStyle( pStyleSheet ); + + SfxItemSet& rStyleSet = pStyleSheet->GetItemSet(); + + ScStyleDlg* pDlg = new ScStyleDlg( lcl_GetDialogParent(), + *pStyleSheet, + RID_SCDLG_STYLES_PAGE ); + + if ( pDlg->Execute() == RET_OK ) + { + const SfxItemSet* pOutSet = pDlg->GetOutputItemSet(); + + WaitObject aWait( GetDialogParent() ); + + String aNewName = pStyleSheet->GetName(); + if ( aNewName != aOldName && + aDocument.RenamePageStyleInUse( aOldName, aNewName ) ) + { + SfxBindings& rBindings = SFX_BINDINGS(); + rBindings.Invalidate( SID_STATUS_PAGESTYLE ); + rBindings.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 ); + 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; + } + } + } + + ScHFEditDlg* pDlg + = new ScHFEditDlg( SFX_APP()->GetViewFrame(), + lcl_GetDialogParent(), + rStyleSet, + aStr, + nResId ); + + 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, + USHORT 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 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 bAllTabs = TRUE; + USHORT nTabCount = aDocument.GetTableCount(); + USHORT nTab; + long nTotalPages = 0; // alle Seiten + long aPageArr[MAXTAB+1]; // Seiten pro Tabelle + for ( nTab=0; nTab<nTabCount; nTab++ ) // nPages und nTotalPages ermitteln + { + ScPrintFunc aPrintFunc( this, pPrinter, nTab ); + long nThisTab = aPrintFunc.GetTotalPages(); + aPageArr[nTab] = nThisTab; + nTotalPages += nThisTab; + } + + MultiSelection aPageRanges; // zu druckende Seiten + aPageRanges.SetTotalRange( Range( 0, RANGE_MAX ) ); + aPageRanges.Select( Range(1,nTotalPages) ); + PrintDialogRange eDlgOption = pPrintDialog ? pPrintDialog->GetCheckedRange() : PRINTDIALOG_ALL; + switch ( eDlgOption ) + { + case PRINTDIALOG_RANGE: + aPageRanges = MultiSelection( pPrintDialog->GetRangeText() ); + break; + + case PRINTDIALOG_SELECTION: + // pMarkedRange interessiert hier nicht + bAllTabs = FALSE; + break; + } + + if (!bAllTabs) // Gesamt-Seitenzahl bei Selektion + { + nTotalPages = 0; + for (nTab=0; nTab<nTabCount; nTab++) + if ( !pMarkData || pMarkData->GetTableSelect(nTab) ) + nTotalPages += aPageArr[nTab]; + aPageRanges.Select( Range(1,nTotalPages) ); + } + + BOOL bFound = FALSE; // erste Seite gefunden + long nTabStart = 0; + for ( nTab=0; nTab<nTabCount && !bFound; nTab++ ) + { + if ( bAllTabs || !pMarkData || pMarkData->GetTableSelect( nTab ) ) + { + ScPrintFunc aPrintFunc( this, pPrinter, 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) + { + aPrintFunc.ApplyPrintSettings(); // dann Settings fuer diese Tabelle + bFound = TRUE; + } + nTabStart = nNext; + } + } +} + +void ScDocShell::Print( SfxProgress& rProgress, PrintDialog* pPrintDialog, + ScMarkData* pMarkData, BOOL bForceSelected ) +{ + SfxPrinter* pPrinter = GetPrinter(); + if ( !pPrinter ) return; + + PrintDialogRange eDlgOption = PRINTDIALOG_ALL; + if ( bForceSelected ) + eDlgOption = PRINTDIALOG_SELECTION; + + ScRange* pMarkedRange = NULL; + + BOOL bAllTabs = TRUE; + USHORT nTabCount = aDocument.GetTableCount(); + USHORT nTab; + long nTotalPages = 0; // alle Seiten + long aPageArr[MAXTAB+1]; // Seiten pro Tabelle + for ( nTab=0; nTab<nTabCount; nTab++ ) // nPages und nTotalPages ermitteln + { + ScPrintFunc aPrintFunc( this, pPrinter, nTab ); + long nThisTab = aPrintFunc.GetTotalPages(); + aPageArr[nTab] = nThisTab; + nTotalPages += nThisTab; + } + + MultiSelection aPageRanges; // zu druckende Seiten + aPageRanges.SetTotalRange( Range( 0, RANGE_MAX ) ); + aPageRanges.Select( Range(1,nTotalPages) ); + if ( pPrintDialog ) + eDlgOption = pPrintDialog->GetCheckedRange(); + switch ( eDlgOption ) + { + case PRINTDIALOG_RANGE: + aPageRanges = MultiSelection( pPrintDialog->GetRangeText() ); + break; + + case PRINTDIALOG_SELECTION: + if ( pMarkData && ( pMarkData->IsMarked() || pMarkData->IsMultiMarked() ) ) + { + pMarkData->MarkToMulti(); + pMarkedRange = new ScRange; + pMarkData->GetMultiMarkArea( *pMarkedRange ); + pMarkData->MarkToSimple(); + } + bAllTabs = FALSE; + break; + + //case PRINTDIALOG_ALL: + //default: + } + + if (!bAllTabs) // Gesamt-Seitenzahl bei Selektion + { + nTotalPages = 0; + for (nTab=0; nTab<nTabCount; nTab++) + if ( !pMarkData || pMarkData->GetTableSelect(nTab) ) + nTotalPages += aPageArr[nTab]; + aPageRanges.Select( Range(1,nTotalPages) ); + } + + USHORT nCollateCopies = 1; + if ( pPrintDialog && pPrintDialog->IsCollateEnabled() && pPrintDialog->IsCollateChecked() ) + nCollateCopies = pPrintDialog->GetCopyCount(); + + for ( USHORT n=0; n<nCollateCopies; n++ ) + { + long nTabStart = 0; + long nDisplayStart = 0; + long nAttrPage = 1; + + for ( nTab=0; nTab<nTabCount; nTab++ ) + { + if ( bAllTabs || !pMarkData || pMarkData->GetTableSelect( nTab ) ) + { + FmFormView* pDrawView = NULL; + Rectangle aFull( 0, 0, LONG_MAX, LONG_MAX ); + if ( aDocument.HasControl( nTab, aFull ) ) + { + ScDrawLayer* pModel = aDocument.GetDrawLayer(); // ist nicht NULL + pDrawView = new FmFormView( pModel, pPrinter ); + pDrawView->ShowPagePgNum( nTab, Point() ); + pDrawView->SetPrintPreview( TRUE ); + } + + ScPrintFunc aPrintFunc( this, pPrinter, nTab, nAttrPage, nTotalPages, pMarkedRange ); + aPrintFunc.SetDrawView( pDrawView ); + aPrintFunc.DoPrint( aPageRanges, nTabStart, nDisplayStart, &rProgress ); + + nTabStart += aPageArr[nTab]; + if ( aDocument.NeedPageResetAfterTab(nTab) ) + nDisplayStart = 0; + else + nDisplayStart += aPageArr[nTab]; + nAttrPage = aPrintFunc.GetFirstPageNo(); // behalten oder aus Vorlage + + delete pDrawView; + } + } + } + + 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; + } + + 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: + { + ScDocument* pDoc = GetDocument(); + if(pDoc->GetChangeTrack()!=NULL) + rSet.Put( SfxBoolItem( nWhich, TRUE)); + else + rSet.Put( SfxBoolItem( nWhich, FALSE)); + } + 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( SfxUInt16Item( nWhich, aDocument.GetTableCount() ) ); + break; + + case SID_ATTR_YEAR2000 : + rSet.Put( SfxUInt16Item( nWhich, + aDocument.GetDocOptions().GetYear2000() ) ); + 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 + + USHORT nVisTab = aDocument.GetVisibleTab(); + if (!aDocument.HasTable(nVisTab)) + return; + + 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 = SfxInPlaceObject::GetVisArea(); + ScViewData aTmpData( this, NULL ); + aTmpData.SetTabNo(nVisTab); + aDocument.SnapVisArea( aBoundRect ); + aTmpData.SetScreen( aBoundRect ); + ScPrintFunc::DrawToDev( &aDocument, pDev, 1.0, aBoundRect, &aTmpData, TRUE ); + } +} + +Rectangle __EXPORT ScDocShell::GetVisArea( USHORT nAspect ) const +{ + 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 ); + aDocument.SnapVisArea( aArea ); + return aArea; + } + else if( nAspect == ASPECT_CONTENT && eShellMode != SFX_CREATE_MODE_EMBEDDED ) + { + // Visarea holen wie nach Load + + USHORT nVisTab = aDocument.GetVisibleTab(); + if (!aDocument.HasTable(nVisTab)) + { + nVisTab = 0; + ((ScDocShell*)this)->aDocument.SetVisibleTab(nVisTab); + } + USHORT nStartCol,nStartRow; + aDocument.GetDataStart( nVisTab, nStartCol, nStartRow ); + USHORT nEndCol,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 ); + ((ScDocShell*)this)->SvEmbeddedObject::SetVisArea( aNewArea ); + return aNewArea; + } + else + return SfxInPlaceObject::GetVisArea( nAspect ); +} + +SvDataMemberObjectRef __EXPORT ScDocShell::CreateSnapshot() +{ + ScDocShell* pNewSh = new ScDocShell; + SvEmbeddedObjectRef aDocShellRef = pNewSh; + pNewSh->DoInitNew(NULL); + pNewSh->ResetEmpty(); + ScDocument* pDestDoc = pNewSh->GetDocument(); + pDestDoc->RenameTab( 0, + String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("______42_____")), + FALSE ); + + // Kopieren (wie in ScDataObject::GetCalcData): + // - Tabellen + // - Seitenvorlage + + if (aDocument.GetDrawLayer()) + pNewSh->MakeDrawLayer(); + + ScStyleSheetPool* pStylePool = aDocument.GetStyleSheetPool(); + ScStyleSheetPool* pDestPool = pDestDoc->GetStyleSheetPool(); + + USHORT nCount = aDocument.GetTableCount(); + for (USHORT nTab=0; nTab<nCount; nTab++) + { + pDestDoc->MakeTable( nTab ); + pDestDoc->TransferTab( &aDocument, nTab, nTab ); // nicht einfuegen + String aStyleName = aDocument.GetPageStyle( nTab ); + // CopyStyleFrom kopiert SetItems mit richtigem Pool + pDestPool->CopyStyleFrom( pStylePool, aStyleName, SFX_STYLE_FAMILY_PAGE ); + } + + pDestDoc->DeleteTab( nCount ); // vorher kann die einzige Tab nicht geloescht werden + + aDocument.CopyDdeLinks( pDestDoc ); // Werte von DDE-Links kopieren + + pDestDoc->SetViewOptions( aDocument.GetViewOptions() ); + + pDestDoc->SetVisibleTab( aDocument.GetVisibleTab() ); + // hier muss auch der Start angepasst werden + pNewSh->SetVisAreaOrSize( SfxInPlaceObject::GetVisArea(), TRUE ); + + return new ScDataObject( pNewSh ); +} + +void ScDocShell::GetPageOnFromPageStyleSet( const SfxItemSet* pStyleSet, + USHORT 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, SvData& rData ) +{ + if( rData.GetFormat() == FORMAT_STRING ) + { + if( rItem.EqualsIgnoreCaseAscii( "Format" ) ) + { + ByteString aFmtByte( aDdeTextFmt, gsl_getSystemTextEncoding() ); + rData.SetData( (void*) 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 ) ) + { + rData.SetData( (void*) aData.GetBuffer(), aData.Len() + 1 ); + return 1; + } + else + return 0; + } + if( aDdeTextFmt.EqualsAscii( "CSV" ) || aDdeTextFmt.EqualsAscii( "FCSV" ) ) + aObj.SetSeparator( ',' ); + return aObj.ExportData( rData ) ? 1 : 0; + } + + ScImportExport aObj( &aDocument, rItem ); + if( aObj.IsRef() ) + return aObj.ExportData( rData ) ? 1 : 0; + else + return 0; +} + +long __EXPORT ScDocShell::DdeSetData( const String& rItem, const SvData& rData ) +{ + SvData* p = (SvData*) &rData; + + if( rData.GetFormat() == FORMAT_STRING ) + { + if( rItem.EqualsIgnoreCaseAscii( "Format" ) ) + { + p->GetData( aDdeTextFmt ); + aDdeTextFmt.ToUpperAscii(); + return 1; + } + ScImportExport aObj( &aDocument, rItem ); + if( aDdeTextFmt.GetChar(0) == 'F' ) + aObj.SetFormulas( TRUE ); + if( aDdeTextFmt.EqualsAscii( "SYLK" ) || aDdeTextFmt.EqualsAscii( "FSYLK" ) ) + { + String aData; + p->GetData( aData ); + return aObj.ImportString( aData, SOT_FORMATSTR_ID_SYLK ) ? 1 : 0; + } + if( aDdeTextFmt.EqualsAscii( "CSV" ) || aDdeTextFmt.EqualsAscii( "FCSV" ) ) + aObj.SetSeparator( ',' ); + return aObj.ImportData( *p ) ? 1 : 0; + } + ScImportExport aObj( &aDocument, rItem ); + if( aObj.IsRef() ) + return aObj.ImportData( *p ) ? 1 : 0; + else + return 0; +} + +SvPseudoObject* __EXPORT ScDocShell::DdeCreateHotLink( 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 + } + } + ScRange aRange; + BOOL bValid = ( ( aRange.Parse( aPos, &aDocument ) & SCA_VALID ) || + ( aRange.aStart.Parse( aPos, &aDocument ) & 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; +} + +//------------------------------------------------------------------ + +USHORT ScDocShell::GetCurTab() +{ + //! this must be made non-static and use a ViewShell from this document! + + ScViewData* pViewData = GetViewData(); + + return pViewData ? pViewData->GetTabNo() : 0; +} + +ScTabViewShell* ScDocShell::GetBestViewShell() +{ + ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); + // falsches Doc? + if( pViewSh && pViewSh->GetViewData()->GetDocShell() != this ) + pViewSh = NULL; + if( !pViewSh ) + { + // 1. ViewShell suchen + SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this, TYPE(SfxTopViewFrame) ); + if( pFrame ) + { + SfxViewShell* p = pFrame->GetViewShell(); + pViewSh = PTR_CAST(ScTabViewShell,p); + } + } + return pViewSh; +} + + +//------------------------------------------------------------------ + +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, ChartSelectionHdl, ChartSelectionInfo*, pInfo ) +{ + if (!pInfo) + return 0; + + // die View suchen, auf der das Objekt aktiv ist + + SfxViewFrame *pFrame = SfxViewFrame::GetFirst( this ); + while (pFrame) + { + SfxViewShell* pSh = pFrame->GetViewShell(); + if (pSh && pSh->ISA(ScTabViewShell)) + { + ScTabViewShell* pViewSh = (ScTabViewShell*)pSh; + SfxInPlaceClient* pClient = pViewSh->GetIPClient(); + if ( pClient && pClient->IsInPlaceActive() ) + { + SvInPlaceObjectRef xIPObj = pClient->GetIPObj(); + if (xIPObj.Is()) + { + SchMemChart* pMemChart = SchDLL::GetChartData(xIPObj); + if (pMemChart) + return pViewSh->DoChartSelection( *pInfo, *pMemChart ); + } + } + } + pFrame = SfxViewFrame::GetNext( *pFrame, this ); + } + + return 0; +} + + + diff --git a/sc/source/ui/docshell/docsh5.cxx b/sc/source/ui/docshell/docsh5.cxx new file mode 100644 index 000000000000..739f3553e8bc --- /dev/null +++ b/sc/source/ui/docshell/docsh5.cxx @@ -0,0 +1,941 @@ +/************************************************************************* + * + * $RCSfile: docsh5.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +// System - Includes ----------------------------------------------------- + +#define _BASEDLGS_HXX +#define _BIGINT_HXX +#define _CACHESTR_HXX +//#define _CLIP_HXX +#define _CONFIG_HXX +#define _CURSOR_HXX +//#define _COLOR_HXX +//#define _CTRLBOX_HXX +//#define _CTRLTOOL_HXX +#define _DIALOGS_HXX +#define _DLGCFG_HXX +#define _DYNARR_HXX +#define _EXTATTR_HXX +//#define _FIELD_HXX +#define _FILDLG_HXX +//#define _FILTER_HXX +#define _FONTDLG_HXX +#define _FRM3D_HXX +//#define _GRAPH_HXX +//#define _GDIMTF_HXX +#define _INTRO_HXX +#define _ISETBWR_HXX +#define _NO_SVRTF_PARSER_HXX +//#define _MDIFRM_HXX +#define _MACRODLG_HXX +#define _MODALDLG_HXX +#define _MOREBUTTON_HXX +//#define _MAPMOD_HXX +#define _OUTLINER_HXX +//#define _PAL_HXX +#define _PASSWD_HXX +//#define _PRNDLG_HXX // +#define _POLY_HXX +#define _PVRWIN_HXX +#define _QUEUE_HXX +#define _RULER_HXX +#define _SCRWIN_HXX +//#define _SELENG_HXX +#define _SETBRW_HXX +//#define _SOUND_HXX +#define _STACK_HXX +//#define _STATUS_HXX *** +#define _STDMENU_HXX +//#define _STDCTRL_HXX +//#define _SYSDLG_HXX +//#define _TAB_HXX +#define _TABBAR_HXX +//#define _TREELIST_HXX +//#define _VALUESET_HXX +#define _VCBRW_HXX +#define _VCTRLS_HXX +//#define _VCATTR_HXX +#define _VCSBX_HXX +#define _VCONT_HXX +#define _VDRWOBJ_HXX +//#define _VIEWFAC_HXX + + +#define _SFX_PRNMON_HXX +#define _SFX_RESMGR_HXX +//#define _SFX_SAVEOPT_HXX +#define _SFX_TEMPLDLG_HXX +//#define _SFXAPP_HXX +#define _SFXBASIC_HXX +//#define _SFXCTRLITEM_HXX +//#define _SFXDISPATCH_HXX +#define _SFXFILEDLG_HXX +#define _SFXIMGMGR_HXX +#define _SFXMNUMGR_HXX +//#define _SFXMSG_HXX +#define _SFXMSGDESCR_HXX +#define _SFXMSGPOOL_HXX +//#define _SFXOBJFACE_HXX +//#define _SFXREQUEST_HXX +#define _SFXSTBITEM_HXX +#define _SFXSTBMGR_HXX +#define _SFXTBXCTRL_HXX +#define _SFXTBXMGR_HXX +#define _SFX_TEMPLDLG_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 _SV_NOXSOUND +#define _SVDATTR_HXX +#define _SVDETC_HXX +#define _SVDIO_HXX +#define _SVDRAG_HXX +#define _SVDLAYER_HXX +#define _SVDXOUT_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 + + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#pragma hdrstop + + +#include "scitems.hxx" +#include <vcl/svapp.hxx> +#include <vcl/msgbox.hxx> +#include <vcl/virdev.hxx> +#include <vcl/waitobj.hxx> +#include <sfx2/app.hxx> +#include <sfx2/bindings.hxx> +#include <svtools/smplhint.hxx> + + +// INCLUDE --------------------------------------------------------------- + +#include "docsh.hxx" +#include "global.hxx" +#include "globstr.hrc" +#include "undodat.hxx" +#include "undotab.hxx" +#include "undoblk.hxx" +//#include "pivot.hxx" +#include "dpobject.hxx" +#include "dpshttab.hxx" +#include "dbdocfun.hxx" +#include "consoli.hxx" +#include "dbcolect.hxx" +#include "olinetab.hxx" +#include "patattr.hxx" +#include "attrib.hxx" +#include "docpool.hxx" +#include "uiitems.hxx" +#include "sc.hrc" +#include "waitoff.hxx" + +// --------------------------------------------------------------------------- + +// +// ehemalige viewfunc/dbfunc Methoden +// + +void ScDocShell::ErrorMessage( USHORT nGlobStrId ) +{ + //! StopMarking an der (aktiven) View? + + Window* pParent = GetDialogParent(); + ScWaitCursorOff aWaitOff( pParent ); + BOOL bFocus = pParent && pParent->HasFocus(); + + if(nGlobStrId==STR_PROTECTIONERR) + { + if(IsReadOnly()) + { + nGlobStrId=STR_READONLYERR; + } + } + + InfoBox aBox( pParent, ScGlobal::GetRscString( nGlobStrId ) ); + aBox.Execute(); + if (bFocus) + pParent->GrabFocus(); +} + +void ScDocShell::DBAreaDeleted( USHORT nTab, USHORT nX1, USHORT nY1, USHORT nX2, USHORT nY2 ) +{ + ScDocShellModificator aModificator( *this ); + aDocument.RemoveFlagsTab( nX1, nY1, nX2, nY1, nTab, SC_MF_AUTO ); + PostPaint( nX1, nY1, nTab, nX2, nY1, nTab, PAINT_GRID ); + aModificator.SetDocumentModified(); +} + +ScDBData* lcl_GetDBNearCursor( ScDBCollection* pColl, USHORT nCol, USHORT nRow, USHORT nTab ) +{ + //! nach document/dbcolect verschieben + + if (!pColl) + return NULL; + + ScDBData* pNoNameData = NULL; + ScDBData* pNearData = NULL; + USHORT nCount = pColl->GetCount(); + String aNoName = ScGlobal::GetRscString( STR_DB_NONAME ); + USHORT nAreaTab, nStartCol, nStartRow, nEndCol, nEndRow; + for (USHORT i = 0; i < nCount; i++) + { + ScDBData* pDB = (*pColl)[i]; + pDB->GetArea( nAreaTab, nStartCol, nStartRow, nEndCol, nEndRow ); + if ( nTab == nAreaTab && nCol+1 >= nStartCol && nCol <= nEndCol+1 && + nRow+1 >= nStartRow && nRow <= nEndRow+1 ) + { + if ( pDB->GetName() == aNoName ) + pNoNameData = pDB; + else if ( nCol < nStartCol || nCol > nEndCol || nRow < nStartRow || nRow > nEndRow ) + { + if (!pNearData) + pNearData = pDB; // ersten angrenzenden Bereich merken + } + else + return pDB; // nicht "unbenannt" und Cursor steht wirklich drin + } + } + if (pNearData) + return pNearData; // angrenzender, wenn nichts direkt getroffen + return pNoNameData; // "unbenannt" nur zurueck, wenn sonst nichts gefunden +} + +ScDBData* ScDocShell::GetDBData( const ScRange& rMarked, ScGetDBMode eMode, BOOL bForceMark ) +{ + USHORT nCol = rMarked.aStart.Col(); + USHORT nRow = rMarked.aStart.Row(); + USHORT nTab = rMarked.aStart.Tab(); + + USHORT nStartCol = nCol; + USHORT nStartRow = nRow; + USHORT nStartTab = nTab; + USHORT nEndCol = rMarked.aEnd.Col(); + USHORT nEndRow = rMarked.aEnd.Row(); + USHORT nEndTab = rMarked.aEnd.Tab(); + + // Wegen #49655# nicht einfach GetDBAtCursor: Der zusammenhaengende Datenbereich + // fuer "unbenannt" (GetDataArea) kann neben dem Cursor legen, also muss auch ein + // benannter DB-Bereich dort gesucht werden. + + ScDBData* pData = aDocument.GetDBAtArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow ); + if (!pData) + pData = lcl_GetDBNearCursor( aDocument.GetDBCollection(), nCol, nRow, nTab ); + + BOOL bSelected = ( bForceMark || rMarked.aStart != rMarked.aEnd ); + + BOOL bUseThis = FALSE; + if (pData) + { + // Bereich nehmen, wenn nichts anderes markiert + + USHORT nDummy; + USHORT nOldCol1; + USHORT nOldRow1; + USHORT nOldCol2; + USHORT nOldRow2; + pData->GetArea( nDummy, nOldCol1,nOldRow1, nOldCol2,nOldRow2 ); + BOOL bIsNoName = ( pData->GetName() == ScGlobal::GetRscString( STR_DB_NONAME ) ); + + if (!bSelected) + { + bUseThis = TRUE; + if ( bIsNoName && eMode == SC_DB_MAKE ) + { + // wenn nichts markiert, "unbenannt" auf zusammenhaengenden Bereich anpassen + nStartCol = nCol; + nStartRow = nRow; + nEndCol = nStartCol; + nEndRow = nStartRow; + aDocument.GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, FALSE ); + if ( nOldCol1 != nStartCol || nOldCol2 != nEndCol || nOldRow1 != nStartRow ) + bUseThis = FALSE; // passt gar nicht + else if ( nOldRow2 != nEndRow ) + { + // Bereich auf neue End-Zeile erweitern + pData->SetArea( nTab, nOldCol1,nOldRow1, nOldCol2,nEndRow ); + } + } + } + else + { + if ( nOldCol1 == nStartCol && nOldRow1 == nStartRow && + nOldCol2 == nEndCol && nOldRow2 == nEndRow ) // genau markiert? + bUseThis = TRUE; + else + bUseThis = FALSE; // immer Markierung nehmen (Bug 11964) + } + + // fuer Import nie "unbenannt" nehmen + + if ( bUseThis && eMode == SC_DB_IMPORT && bIsNoName ) + bUseThis = FALSE; + } + + if ( bUseThis ) + { + pData->GetArea( nStartTab, nStartCol,nStartRow, nEndCol,nEndRow ); + nEndTab = nStartTab; + } + else if ( eMode == SC_DB_OLD ) + { + pData = NULL; // nichts gefunden + nStartCol = nEndCol = nCol; + nStartRow = nEndRow = nRow; + nStartTab = nEndTab = nTab; +// bMark = FALSE; // nichts zu markieren + } + else + { + if ( bSelected ) + { +// bMark = FALSE; + } + else + { // zusammenhaengender Bereich + nStartCol = nCol; + nStartRow = nRow; + nEndCol = nStartCol; + nEndRow = nStartRow; + aDocument.GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, FALSE ); + } + + BOOL bHasHeader = aDocument.HasColHeader( nStartCol,nStartRow, nEndCol,nEndRow, nTab ); + + ScDBData* pNoNameData; + USHORT nNoNameIndex; + ScDBCollection* pColl = aDocument.GetDBCollection(); + if ( eMode != SC_DB_IMPORT && + pColl->SearchName( ScGlobal::GetRscString( STR_DB_NONAME ), nNoNameIndex ) ) + { + pNoNameData = (*pColl)[nNoNameIndex]; + + USHORT nOldX1; // alten Bereich sauber wegnehmen + USHORT nOldY1; //! (UNDO ???) + USHORT nOldX2; + USHORT nOldY2; + USHORT nOldTab; + pNoNameData->GetArea( nOldTab, nOldX1, nOldY1, nOldX2, nOldY2 ); + DBAreaDeleted( nOldTab, nOldX1, nOldY1, nOldX2, nOldY2 ); + + pNoNameData->SetSortParam( ScSortParam() ); // Parameter zuruecksetzen + pNoNameData->SetQueryParam( ScQueryParam() ); + pNoNameData->SetSubTotalParam( ScSubTotalParam() ); + + pNoNameData->SetArea( nTab, nStartCol,nStartRow, nEndCol,nEndRow ); // neu setzen + pNoNameData->SetByRow( TRUE ); + pNoNameData->SetHeader( bHasHeader ); + pNoNameData->SetAutoFilter( FALSE ); + } + else + { + ScDBCollection* pUndoColl = NULL; + + String aNewName; + if (eMode==SC_DB_IMPORT) + { + aDocument.CompileDBFormula( TRUE ); // CreateFormulaString + pUndoColl = new ScDBCollection( *pColl ); // Undo fuer Import1-Bereich + + String aImport = ScGlobal::GetRscString( STR_DBNAME_IMPORT ); + long nCount = 0; + USHORT nDummy; + do + { + ++nCount; + aNewName = aImport; + aNewName += String::CreateFromInt32( nCount ); + } + while (pColl->SearchName( aNewName, nDummy )); + } + else + aNewName = ScGlobal::GetRscString( STR_DB_NONAME ); + pNoNameData = new ScDBData( aNewName, nTab, + nStartCol,nStartRow, nEndCol,nEndRow, + TRUE, bHasHeader ); + pColl->Insert( pNoNameData ); + + if ( pUndoColl ) + { + aDocument.CompileDBFormula( FALSE ); // CompileFormulaString + + ScDBCollection* pRedoColl = new ScDBCollection( *pColl ); + GetUndoManager()->AddUndoAction( new ScUndoDBData( this, pUndoColl, pRedoColl ) ); + } + + // neuen Bereich am Sba anmelden nicht mehr noetig + + // "Import1" etc am Navigator bekanntmachen + if (eMode==SC_DB_IMPORT) + SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) ); + } + pData = pNoNameData; + } + +// if (bMark) +// MarkRange( ScRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ), FALSE ); + + return pData; +} + + + // Hoehen anpassen + //! mit docfunc zusammenfassen + +BOOL ScDocShell::AdjustRowHeight( USHORT nStartRow, USHORT nEndRow, USHORT nTab ) +{ + VirtualDevice aVDev; + Point aLogic = aVDev.LogicToPixel( Point(1000,1000), MAP_TWIP ); + double nPPTX = aLogic.X() / 1000.0; + double nPPTY = aLogic.Y() / 1000.0; + nPPTX /= GetOutputFactor(); // noetig fuer Bildschirm/VDev + Fraction aZoom(1,1); + BOOL bChange = aDocument.SetOptimalHeight( nStartRow,nEndRow, nTab, 0, &aVDev, + nPPTX,nPPTY, aZoom,aZoom, FALSE ); + if (bChange) + PostPaint( 0,nStartRow,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID|PAINT_LEFT ); + + return bChange; +} + +void ScDocShell::PivotUpdate( ScPivot* pOldPivot, ScPivot* pNewPivot, BOOL bRecord, BOOL bApi ) +{ + DBG_ERRORFILE("PivotUpdate is obsolete!"); +} + +void ScDocShell::RefreshPivotTables( const ScRange& rSource ) +{ + //! rename to RefreshDataPilotTables? + + ScDPCollection* pColl = aDocument.GetDPCollection(); + if ( pColl ) + { + // DataPilotUpdate doesn't modify the collection order like PivotUpdate did, + // so a simple loop can be used. + + USHORT nCount = pColl->GetCount(); + for ( USHORT i=0; i<nCount; i++ ) + { + ScDPObject* pOld = (*pColl)[i]; + if ( pOld ) + { + const ScSheetSourceDesc* pSheetDesc = pOld->GetSheetDesc(); + if ( pSheetDesc && pSheetDesc->aSourceRange.Intersects( rSource ) ) + { + ScDPObject* pNew = new ScDPObject( *pOld ); + ScDBDocFunc aFunc( *this ); + aFunc.DataPilotUpdate( pOld, pNew, TRUE, FALSE ); + delete pNew; // DataPilotUpdate copies settings from "new" object + } + } + } + } +} + +String lcl_GetAreaName( ScDocument* pDoc, ScArea* pArea ) +{ + String aName; + BOOL bOk = FALSE; + ScDBData* pData = pDoc->GetDBAtArea( pArea->nTab, pArea->nColStart, pArea->nRowStart, + pArea->nColEnd, pArea->nRowEnd ); + if (pData) + { + pData->GetName( aName ); + if ( aName != ScGlobal::GetRscString( STR_DB_NONAME ) ) + bOk = TRUE; + } + + if (!bOk) + pDoc->GetName( pArea->nTab, aName ); + + return aName; +} + +void ScDocShell::DoConsolidate( const ScConsolidateParam& rParam, BOOL bRecord ) +{ + ScConsData aData; + + USHORT nPos; + USHORT nColSize = 0; + USHORT nRowSize = 0; + BOOL bErr = FALSE; + for (nPos=0; nPos<rParam.nDataAreaCount; nPos++) + { + ScArea* pArea = rParam.ppDataAreas[nPos]; + nColSize = Max( nColSize, USHORT( pArea->nColEnd - pArea->nColStart + 1 ) ); + nRowSize = Max( nRowSize, USHORT( pArea->nRowEnd - pArea->nRowStart + 1 ) ); + + // Test, ob Quelldaten verschoben wuerden + if (rParam.bReferenceData) + if (pArea->nTab == rParam.nTab && pArea->nRowEnd >= rParam.nRow) + bErr = TRUE; + } + + if (bErr) + { + InfoBox aBox( GetDialogParent(), + ScGlobal::GetRscString( STR_CONSOLIDATE_ERR1 ) ); + aBox.Execute(); + return; + } + + // ausfuehren + + WaitObject aWait( GetDialogParent() ); + ScDocShellModificator aModificator( *this ); + + ScRange aOldDest; + ScDBData* pDestData = aDocument.GetDBAtCursor( rParam.nCol, rParam.nRow, rParam.nTab, TRUE ); + if (pDestData) + pDestData->GetArea(aOldDest); + + aData.SetSize( nColSize, nRowSize ); + aData.SetFlags( rParam.eFunction, rParam.bByCol, rParam.bByRow, rParam.bReferenceData ); + if ( rParam.bByCol || rParam.bByRow ) + for (nPos=0; nPos<rParam.nDataAreaCount; nPos++) + { + ScArea* pArea = rParam.ppDataAreas[nPos]; + aData.AddFields( &aDocument, pArea->nTab, pArea->nColStart, pArea->nRowStart, + pArea->nColEnd, pArea->nRowEnd ); + } + aData.DoneFields(); + for (nPos=0; nPos<rParam.nDataAreaCount; nPos++) + { + ScArea* pArea = rParam.ppDataAreas[nPos]; + aData.AddData( &aDocument, pArea->nTab, pArea->nColStart, pArea->nRowStart, + pArea->nColEnd, pArea->nRowEnd ); + aData.AddName( lcl_GetAreaName(&aDocument,pArea) ); + } + + aData.GetSize( nColSize, nRowSize ); + if (bRecord && nColSize && nRowSize) + { + ScDBData* pUndoData = pDestData ? new ScDBData(*pDestData) : NULL; + + USHORT nDestTab = rParam.nTab; + ScArea aDestArea( rParam.nTab, rParam.nCol, rParam.nRow, + rParam.nCol+nColSize-1, rParam.nRow+nRowSize-1 ); + if (rParam.bByCol) ++aDestArea.nColEnd; + if (rParam.bByRow) ++aDestArea.nRowEnd; + + if (rParam.bReferenceData) + { + USHORT nTabCount = aDocument.GetTableCount(); + USHORT nInsertCount = aData.GetInsertCount(); + + // alte Outlines + ScOutlineTable* pTable = aDocument.GetOutlineTable( nDestTab ); + ScOutlineTable* pUndoTab = pTable ? new ScOutlineTable( *pTable ) : NULL; + + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( &aDocument, 0, nTabCount-1, FALSE, TRUE ); + + // Zeilenstatus + aDocument.CopyToDocument( 0,0,nDestTab, MAXCOL,MAXROW,nDestTab, + IDF_NONE, FALSE, pUndoDoc ); + + // alle Formeln + aDocument.CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTabCount-1, + IDF_FORMULA, FALSE, pUndoDoc ); + + // komplette Ausgangszeilen + aDocument.CopyToDocument( 0,aDestArea.nRowStart,nDestTab, + MAXCOL,aDestArea.nRowEnd,nDestTab, + IDF_ALL, FALSE, pUndoDoc ); + + // alten Ausgabebereich + if (pDestData) + aDocument.CopyToDocument( aOldDest, IDF_ALL, FALSE, pUndoDoc ); + + GetUndoManager()->AddUndoAction( + new ScUndoConsolidate( this, aDestArea, rParam, pUndoDoc, + TRUE, nInsertCount, pUndoTab, pUndoData ) ); + } + else + { + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( &aDocument, aDestArea.nTab, aDestArea.nTab ); + + aDocument.CopyToDocument( aDestArea.nColStart, aDestArea.nRowStart, aDestArea.nTab, + aDestArea.nColEnd, aDestArea.nRowEnd, aDestArea.nTab, + IDF_ALL, FALSE, pUndoDoc ); + + // alten Ausgabebereich + if (pDestData) + aDocument.CopyToDocument( aOldDest, IDF_ALL, FALSE, pUndoDoc ); + + GetUndoManager()->AddUndoAction( + new ScUndoConsolidate( this, aDestArea, rParam, pUndoDoc, + FALSE, 0, NULL, pUndoData ) ); + } + } + + if (pDestData) // Zielbereich loeschen / anpassen + { + aDocument.DeleteAreaTab(aOldDest, IDF_CONTENTS); + pDestData->SetArea( rParam.nTab, rParam.nCol, rParam.nRow, + rParam.nCol + nColSize - 1, rParam.nRow + nRowSize - 1 ); + pDestData->SetHeader( rParam.bByRow ); + } + + aData.OutputToDocument( &aDocument, rParam.nCol, rParam.nRow, rParam.nTab ); + + USHORT nPaintStartCol = rParam.nCol; + USHORT nPaintStartRow = rParam.nRow; + USHORT nPaintEndCol = nPaintStartCol + nColSize - 1; + USHORT nPaintEndRow = nPaintStartRow + nRowSize - 1; + USHORT nPaintFlags = PAINT_GRID; + if (rParam.bByCol) + ++nPaintEndRow; + if (rParam.bByRow) + ++nPaintEndCol; + if (rParam.bReferenceData) + { + nPaintStartCol = 0; + nPaintEndCol = MAXCOL; + nPaintEndRow = MAXROW; + nPaintFlags |= PAINT_LEFT | PAINT_SIZE; + } + if (pDestData) + { + if ( aOldDest.aEnd.Col() > nPaintEndCol ) + nPaintEndCol = aOldDest.aEnd.Col(); + if ( aOldDest.aEnd.Row() > nPaintEndRow ) + nPaintEndRow = aOldDest.aEnd.Row(); + } + PostPaint( nPaintStartCol, nPaintStartRow, rParam.nTab, + nPaintEndCol, nPaintEndRow, rParam.nTab, nPaintFlags ); + aModificator.SetDocumentModified(); +} + +void ScDocShell::UseScenario( USHORT nTab, const String& rName, BOOL bRecord ) +{ + if (!aDocument.IsScenario(nTab)) + { + USHORT nTabCount = aDocument.GetTableCount(); + USHORT nSrcTab = USHRT_MAX; + USHORT nEndTab = nTab; + String aCompare; + while ( nEndTab+1 < nTabCount && aDocument.IsScenario(nEndTab+1) ) + { + ++nEndTab; + if (nSrcTab > MAXTAB) // noch auf der Suche nach dem Szenario? + { + aDocument.GetName( nEndTab, aCompare ); + if (aCompare == rName) + nSrcTab = nEndTab; // gefunden + } + } + if (nSrcTab <= MAXTAB) + { + if ( aDocument.TestCopyScenario( nSrcTab, nTab ) ) // Zellschutz testen + { + ScDocShellModificator aModificator( *this ); + ScMarkData aScenMark; + aDocument.MarkScenario( nSrcTab, nTab, aScenMark ); + ScRange aMultiRange; + aScenMark.GetMultiMarkArea( aMultiRange ); + USHORT nStartCol = aMultiRange.aStart.Col(); + USHORT nStartRow = aMultiRange.aStart.Row(); + USHORT nEndCol = aMultiRange.aEnd.Col(); + USHORT nEndRow = aMultiRange.aEnd.Row(); + + if (bRecord) + { + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( &aDocument, nTab,nEndTab ); // auch alle Szenarien + // angezeigte Tabelle: + aDocument.CopyToDocument( nStartCol,nStartRow,nTab, + nEndCol,nEndRow,nTab, IDF_ALL,TRUE, pUndoDoc, &aScenMark ); + // Szenarien + for (USHORT i=nTab+1; i<=nEndTab; i++) + { + pUndoDoc->SetScenario( i, TRUE ); + String aComment; + Color aColor; + USHORT nScenFlags; + aDocument.GetScenarioData( i, aComment, aColor, nScenFlags ); + pUndoDoc->SetScenarioData( i, aComment, aColor, nScenFlags ); + BOOL bActive = aDocument.IsActiveScenario( i ); + pUndoDoc->SetActiveScenario( i, bActive ); + // Bei Zurueckkopier-Szenarios auch Inhalte + if ( nScenFlags & SC_SCENARIO_TWOWAY ) + aDocument.CopyToDocument( 0,0,i, MAXCOL,MAXROW,i, + IDF_ALL,FALSE, pUndoDoc ); + } + + GetUndoManager()->AddUndoAction( + new ScUndoUseScenario( this, aScenMark, + ScArea( nTab,nStartCol,nStartRow,nEndCol,nEndRow ), + pUndoDoc, rName ) ); + } + + aDocument.CopyScenario( nSrcTab, nTab ); + aDocument.SetDirty(); + + // alles painten, weil in anderen Bereichen das aktive Szenario + // geaendert sein kann + //! nur, wenn sichtbare Rahmen vorhanden? + PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID ); + aModificator.SetDocumentModified(); + } + else + { + InfoBox aBox(GetDialogParent(), + ScGlobal::GetRscString( STR_PROTECTIONERR ) ); + aBox.Execute(); + } + } + else + { + InfoBox aBox(GetDialogParent(), + ScGlobal::GetRscString( STR_SCENARIO_NOTFOUND ) ); + aBox.Execute(); + } + } + else + DBG_ERROR( "UseScenario auf Szenario-Blatt" ); +} + +void ScDocShell::ModifyScenario( USHORT nTab, const String& rName, const String& rComment, + const Color& rColor, USHORT nFlags ) +{ + // Undo + String aOldName; + aDocument.GetName( nTab, aOldName ); + String aOldComment; + Color aOldColor; + USHORT nOldFlags; + aDocument.GetScenarioData( nTab, aOldComment, aOldColor, nOldFlags ); + GetUndoManager()->AddUndoAction( + new ScUndoScenarioFlags( this, nTab, + aOldName, rName, aOldComment, rComment, + aOldColor, rColor, nOldFlags, nFlags ) ); + + // ausfuehren + ScDocShellModificator aModificator( *this ); + aDocument.RenameTab( nTab, rName ); + aDocument.SetScenarioData( nTab, rComment, rColor, nFlags ); + PostPaintGridAll(); + aModificator.SetDocumentModified(); + + if ( rName != aOldName ) + SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); + + SFX_BINDINGS().Invalidate( SID_SELECT_SCENARIO ); +} + +USHORT ScDocShell::MakeScenario( USHORT nTab, const String& rName, const String& rComment, + const Color& rColor, USHORT nFlags, + ScMarkData& rMark, BOOL bRecord ) +{ + rMark.MarkToMulti(); + if (rMark.IsMultiMarked()) + { + USHORT nNewTab = nTab + 1; + while (aDocument.IsScenario(nNewTab)) + ++nNewTab; + + BOOL bCopyAll = ( (nFlags & SC_SCENARIO_COPYALL) != 0 ); + const ScMarkData* pCopyMark = NULL; + if (!bCopyAll) + pCopyMark = &rMark; + + ScDocShellModificator aModificator( *this ); + + if (aDocument.CopyTab( nTab, nNewTab, pCopyMark )) + { + if (bRecord) + { + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( &aDocument, nTab,nTab ); + GetUndoManager()->AddUndoAction( + new ScUndoMakeScenario( this, nTab, nNewTab, pUndoDoc, + rName, rComment, rColor, nFlags, rMark )); + } + + aDocument.RenameTab( nNewTab, rName, FALSE ); // ohne Formel-Update + aDocument.SetScenario( nNewTab, TRUE ); + aDocument.SetScenarioData( nNewTab, rComment, rColor, nFlags ); + + ScMarkData aDestMark = rMark; + aDestMark.SelectOneTable( nNewTab ); + + //! auf Filter / Buttons / Merging testen ! + + ScPatternAttr aProtPattern( aDocument.GetPool() ); + aProtPattern.GetItemSet().Put( ScProtectionAttr( TRUE ) ); + aDocument.ApplyPatternAreaTab( 0,0, MAXCOL,MAXROW, nNewTab, aProtPattern ); + + ScPatternAttr aPattern( aDocument.GetPool() ); + aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) ); + aPattern.GetItemSet().Put( ScProtectionAttr( TRUE ) ); + aDocument.ApplySelectionPattern( aPattern, aDestMark ); + + if (!bCopyAll) + aDocument.SetVisible( nNewTab, FALSE ); + + // dies ist dann das aktive Szenario + aDocument.CopyScenario( nNewTab, nTab, TRUE ); // TRUE - nicht aus Szenario kopieren + + if (nFlags & SC_SCENARIO_SHOWFRAME) + PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID ); // Rahmen painten + PostPaintExtras(); // Tabellenreiter + aModificator.SetDocumentModified(); + + SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); + + return nNewTab; + } + } + return nTab; +} + +BOOL ScDocShell::MoveTable( USHORT nSrcTab, USHORT nDestTab, BOOL bCopy, BOOL bRecord ) +{ + ScDocShellModificator aModificator( *this ); + + if (bCopy) + { + if (bRecord) + aDocument.BeginDrawUndo(); // drawing layer must do its own undo actions + + if (!aDocument.CopyTab( nSrcTab, nDestTab )) + { + //! EndDrawUndo? + return FALSE; + } + else if (bRecord) + { + SvUShorts aSrcList; + SvUShorts aDestList; + aSrcList.Insert(nSrcTab,0); + aDestList.Insert(nDestTab,0); + GetUndoManager()->AddUndoAction( + new ScUndoCopyTab( this, aSrcList, aDestList ) ); + } + + Broadcast( ScTablesHint( SC_TAB_COPIED, nSrcTab, nDestTab ) ); + } + else + { + if ( aDocument.GetChangeTrack() ) + return FALSE; + + if ( nSrcTab<nDestTab && nDestTab!=SC_TAB_APPEND ) + nDestTab--; + + if ( nSrcTab == nDestTab ) + { + //! allow only for api calls? + return TRUE; // nothing to do, but valid + } + + if (!aDocument.MoveTab( nSrcTab, nDestTab )) + return FALSE; + else if (bRecord) + { + SvUShorts aSrcList; + SvUShorts aDestList; + aSrcList.Insert(nSrcTab,0); + aDestList.Insert(nDestTab,0); + GetUndoManager()->AddUndoAction( + new ScUndoMoveTab( this, aSrcList, aDestList ) ); + } + + Broadcast( ScTablesHint( SC_TAB_MOVED, nSrcTab, nDestTab ) ); + } + + PostPaintGridAll(); + PostPaintExtras(); + aModificator.SetDocumentModified(); + SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); + + return TRUE; +} + + + diff --git a/sc/source/ui/docshell/docsh6.cxx b/sc/source/ui/docshell/docsh6.cxx new file mode 100644 index 000000000000..24103630c66c --- /dev/null +++ b/sc/source/ui/docshell/docsh6.cxx @@ -0,0 +1,622 @@ +/************************************************************************* + * + * $RCSfile: docsh6.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +// System - Includes ----------------------------------------------------- + +//#define _BASEDLGS_HXX *** +#define _BIGINT_HXX +#define _CACHESTR_HXX +//#define _CLIP_HXX +#define _CONFIG_HXX +#define _CURSOR_HXX +//#define _COLOR_HXX +//#define _CTRLBOX_HXX +//#define _CTRLTOOL_HXX +#define _DIALOGS_HXX +#define _DLGCFG_HXX +#define _DYNARR_HXX +#define _EXTATTR_HXX +//#define _FIELD_HXX +#define _FILDLG_HXX +//#define _FILTER_HXX +#define _FONTDLG_HXX +#define _FRM3D_HXX +//#define _GRAPH_HXX +//#define _GDIMTF_HXX +#define _INTRO_HXX +#define _ISETBWR_HXX +#define _NO_SVRTF_PARSER_HXX +//#define _MDIFRM_HXX +#define _MACRODLG_HXX +#define _MODALDLG_HXX +#define _MOREBUTTON_HXX +//#define _MAPMOD_HXX +#define _OUTLINER_HXX +//#define _PAL_HXX +#define _PASSWD_HXX +//#define _PRNDLG_HXX // +#define _POLY_HXX +#define _PVRWIN_HXX +#define _QUEUE_HXX +#define _RULER_HXX +#define _SCRWIN_HXX +//#define _SELENG_HXX +#define _SETBRW_HXX +//#define _SOUND_HXX +#define _STACK_HXX +//#define _STATUS_HXX *** +#define _STDMENU_HXX +//#define _STDCTRL_HXX +//#define _SYSDLG_HXX +//#define _TAB_HXX +#define _TABBAR_HXX +//#define _TREELIST_HXX +//#define _VALUESET_HXX +#define _VCBRW_HXX +#define _VCTRLS_HXX +//#define _VCATTR_HXX +#define _VCSBX_HXX +#define _VCONT_HXX +#define _VDRWOBJ_HXX +//#define _VIEWFAC_HXX + + +#define _SFX_PRNMON_HXX +#define _SFX_RESMGR_HXX +//#define _SFX_SAVEOPT_HXX +#define _SFX_TEMPLDLG_HXX +//#define _SFXAPP_HXX +#define _SFXBASIC_HXX +//#define _SFXCTRLITEM_HXX +#define _SFXDISPATCH_HXX +#define _SFXFILEDLG_HXX +#define _SFXIMGMGR_HXX +#define _SFXMNUMGR_HXX +//#define _SFXMSG_HXX +#define _SFXMSGDESCR_HXX +#define _SFXMSGPOOL_HXX +//#define _SFXOBJFACE_HXX +//#define _SFXREQUEST_HXX +#define _SFXSTBITEM_HXX +#define _SFXSTBMGR_HXX +#define _SFXTBXCTRL_HXX +#define _SFXTBXMGR_HXX +#define _SFX_TEMPLDLG_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 _SV_NOXSOUND +#define _SVDATTR_HXX +#define _SVDETC_HXX +#define _SVDIO_HXX +#define _SVDRAG_HXX +#define _SVDLAYER_HXX +#define _SVDXOUT_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 + + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef PCH +#include <so3/ipenv.hxx> +#include "scitems.hxx" + +#include <so3/ipenv.hxx> +#include <svx/pageitem.hxx> +#include <vcl/virdev.hxx> +#include <svx/linkmgr.hxx> + +#include <segmentc.hxx> +#endif + +// INCLUDE --------------------------------------------------------------- + +//#include <svxlink.hxx> + +#include "docsh.hxx" + +#include "stlsheet.hxx" +#include "stlpool.hxx" +#include "global.hxx" +#include "viewdata.hxx" +#include "tabvwsh.hxx" +#include "tablink.hxx" +#include "collect.hxx" + +// STATIC DATA ----------------------------------------------------------- + +//---------------------------------------------------------------------- + +SEG_EOFGLOBALS() + +// +// Ole +// + +#pragma SEG_FUNCDEF(docsh6_01) + +String ScDocShell::CreateObjectName( const String& rPrefix ) +{ + String aStr( rPrefix ); + USHORT i = 1; + aStr += String::CreateFromInt32( i ); + while( Find( aStr ) ) + { + i++; + aStr = rPrefix; + aStr += String::CreateFromInt32( i ); + } + return aStr; +} + +#pragma SEG_FUNCDEF(docsh6_02) + +void __EXPORT ScDocShell::SetVisArea( const Rectangle & rVisArea ) +{ + // wenn von aussen gerufen, nur Groesse anpassen + // (linke obere Ecke bleibt unveraendert), + // weil sonst beim Verschieben des Objekts durch Pixel-Rundungsfehler + // manchmal ungewollt der Ausschnitt verschoben wird + + SetVisAreaOrSize( rVisArea, FALSE ); +} + +void ScDocShell::SetVisAreaOrSize( const Rectangle& rVisArea, BOOL bModifyStart ) +{ + Rectangle aArea = rVisArea; + if (!bModifyStart) + aArea.SetPos( SfxInPlaceObject::GetVisArea().TopLeft() ); + + // hier Position anpassen! + + aDocument.SnapVisArea( aArea ); + + SvInPlaceEnvironment* pEnv = GetIPEnv(); + if (pEnv) + { + Window* pWin = pEnv->GetEditWin(); + pEnv->MakeScale( aArea.GetSize(), MAP_100TH_MM, + pWin->LogicToPixel( aArea.GetSize() ) ); + } + + SvInPlaceObject::SetVisArea( aArea ); + + if (bIsInplace) // Zoom in der InPlace View einstellen + { + ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); + if (pViewSh) + { + if (pViewSh->GetViewData()->GetDocShell() == this) + pViewSh->UpdateOleZoom(); + } + else + DataChanged( SvDataType() ); // fuer Zuppeln wenn nicht IP-aktiv + } + + if (aDocument.IsEmbedded()) + { + ScTripel aOldStart,aOldEnd; + aDocument.GetEmbedded(aOldStart,aOldEnd); + aDocument.SetEmbedded( aArea ); + ScTripel aNewStart,aNewEnd; + aDocument.GetEmbedded(aNewStart,aNewEnd); + if (aNewStart!=aOldStart || aNewEnd!=aOldEnd) + PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB,PAINT_GRID); + + ViewChanged( ASPECT_CONTENT ); // auch im Container anzeigen + } +} + +#pragma SEG_FUNCDEF(docsh6_03) + +BOOL ScDocShell::IsOle() +{ + return (eShellMode == SFX_CREATE_MODE_EMBEDDED); +} + +#pragma SEG_FUNCDEF(docsh6_04) + +void ScDocShell::UpdateOle( const ScViewData* pViewData, BOOL bSnapSize ) +{ + // wenn's gar nicht Ole ist, kann man sich die Berechnungen sparen + // (VisArea wird dann beim Save wieder zurueckgesetzt) + + if (eShellMode == SFX_CREATE_MODE_STANDARD) + return; + + DBG_ASSERT(pViewData,"pViewData==0 bei ScDocShell::UpdateOle"); + + Rectangle aOldArea = SfxInPlaceObject::GetVisArea(); + Rectangle aNewArea = aOldArea; + + BOOL bChange = FALSE; + BOOL bEmbedded = aDocument.IsEmbedded(); + if (bEmbedded) + aNewArea = aDocument.GetEmbeddedRect(); + else + { + USHORT nX = pViewData->GetPosX(SC_SPLIT_LEFT); + USHORT nY = pViewData->GetPosY(SC_SPLIT_BOTTOM); + Point aStart = aDocument.GetMMRect( nX,nY, nX,nY, 0 ).TopLeft(); + aNewArea.SetPos(aStart); + if (bSnapSize) + aDocument.SnapVisArea(aNewArea); + + if ( pViewData->GetTabNo() != aDocument.GetVisibleTab() ) + { + aDocument.SetVisibleTab( pViewData->GetTabNo() ); + bChange = TRUE; + } + } + + if (aNewArea != aOldArea) + { + SetVisAreaOrSize( aNewArea, TRUE ); // hier muss auch der Start angepasst werden + bChange = TRUE; + } + + if (bChange) + DataChanged( SvDataType() ); //! passiert auch bei SetModified +} + +// +// Style-Krempel fuer Organizer etc. +// + +#pragma SEG_FUNCDEF(docsh6_05) + +SfxStyleSheetBasePool* __EXPORT ScDocShell::GetStyleSheetPool() +{ + return (SfxStyleSheetBasePool*)aDocument.GetStyleSheetPool(); +} + + +#pragma SEG_FUNCDEF(docsh6_07) + +// nach dem Laden von Vorlagen aus einem anderen Dokment (LoadStyles, Insert) +// muessen die SetItems (ATTR_PAGE_HEADERSET, ATTR_PAGE_FOOTERSET) auf den richtigen +// Pool umgesetzt werden, bevor der Quell-Pool geloescht wird. + +void lcl_AdjustPool( SfxStyleSheetBasePool* pStylePool ) +{ + pStylePool->SetSearchMask(SFX_STYLE_FAMILY_PAGE, 0xffff); + SfxStyleSheetBase *pStyle = pStylePool->First(); + while ( pStyle ) + { + SfxItemSet& rStyleSet = pStyle->GetItemSet(); + + const SfxPoolItem* pItem; + if (rStyleSet.GetItemState(ATTR_PAGE_HEADERSET,FALSE,&pItem) == SFX_ITEM_SET) + { + SfxItemSet& rSrcSet = ((SvxSetItem*)pItem)->GetItemSet(); + SfxItemSet* pDestSet = new SfxItemSet(*rStyleSet.GetPool(),rSrcSet.GetRanges()); + pDestSet->Put(rSrcSet); + rStyleSet.Put(SvxSetItem(ATTR_PAGE_HEADERSET,pDestSet)); + } + if (rStyleSet.GetItemState(ATTR_PAGE_FOOTERSET,FALSE,&pItem) == SFX_ITEM_SET) + { + SfxItemSet& rSrcSet = ((SvxSetItem*)pItem)->GetItemSet(); + SfxItemSet* pDestSet = new SfxItemSet(*rStyleSet.GetPool(),rSrcSet.GetRanges()); + pDestSet->Put(rSrcSet); + rStyleSet.Put(SvxSetItem(ATTR_PAGE_FOOTERSET,pDestSet)); + } + + pStyle = pStylePool->Next(); + } +} + +#pragma SEG_FUNCDEF(docsh6_08) + +void __EXPORT ScDocShell::LoadStyles( SfxObjectShell &rSource ) +{ + aDocument.StylesToNames(); + + SfxObjectShell::LoadStyles(rSource); + lcl_AdjustPool( GetStyleSheetPool() ); // SetItems anpassen + + aDocument.UpdStlShtPtrsFrmNms(); + + // Hoehen anpassen + + VirtualDevice aVDev; + Point aLogic = aVDev.LogicToPixel( Point(1000,1000), MAP_TWIP ); + double nPPTX = aLogic.X() / 1000.0; + double nPPTY = aLogic.Y() / 1000.0; + Fraction aZoom(1,1); + USHORT nTabCnt = aDocument.GetTableCount(); + for (USHORT nTab=0; nTab<nTabCnt; nTab++) + aDocument.SetOptimalHeight( 0,MAXROW, nTab,0, &aVDev, nPPTX,nPPTY, aZoom,aZoom, FALSE ); + + // Paint + + PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, PAINT_GRID | PAINT_LEFT ); +} + +#pragma SEG_FUNCDEF(docsh6_0b) + +BOOL __EXPORT ScDocShell::Insert( SfxObjectShell &rSource, + USHORT nSourceIdx1, USHORT nSourceIdx2, USHORT nSourceIdx3, + USHORT &nIdx1, USHORT &nIdx2, USHORT &nIdx3, USHORT &rIdxDeleted ) +{ + BOOL bRet = SfxObjectShell::Insert( rSource, nSourceIdx1, nSourceIdx2, nSourceIdx3, + nIdx1, nIdx2, nIdx3, rIdxDeleted ); + if (bRet) + lcl_AdjustPool( GetStyleSheetPool() ); // SetItems anpassen + + return bRet; +} + +#pragma SEG_FUNCDEF(docsh6_09) + +void ScDocShell::UpdateLinks() +{ + SvxLinkManager* pLinkManager = aDocument.GetLinkManager(); + USHORT nCount; + USHORT i; + StrCollection aNames; + + // nicht mehr benutzte Links raus + + nCount = pLinkManager->GetLinks().Count(); + for (i=nCount; i>0; ) + { + --i; + SvBaseLink* pBase = *pLinkManager->GetLinks()[i]; + if (pBase->ISA(ScTableLink)) + { + ScTableLink* pTabLink = (ScTableLink*)pBase; + if (pTabLink->IsUsed()) + { + StrData* pData = new StrData(pTabLink->GetFileName()); + if (!aNames.Insert(pData)) + delete pData; + } + else // nicht mehr benutzt -> loeschen + { + pTabLink->SetAddUndo(TRUE); + pLinkManager->Remove(i); + } + } + } + + + // neue Links eintragen + + nCount = aDocument.GetTableCount(); + for (i=0; i<nCount; i++) + if (aDocument.IsLinked(i)) + { + String aDocName = aDocument.GetLinkDoc(i); + String aFltName = aDocument.GetLinkFlt(i); + String aOptions = aDocument.GetLinkOpt(i); + BOOL bThere = FALSE; + for (USHORT j=0; j<i && !bThere; j++) // im Dokument mehrfach? + if (aDocument.IsLinked(j) + && aDocument.GetLinkDoc(j) == aDocName + && aDocument.GetLinkFlt(j) == aFltName + && aDocument.GetLinkOpt(j) == aOptions) + bThere = TRUE; + + if (!bThere) // schon als Filter eingetragen? + { + StrData* pData = new StrData(aDocName); + if (!aNames.Insert(pData)) + { + delete pData; + bThere = TRUE; + } + } + if (!bThere) + { + ScTableLink* pLink = new ScTableLink( this, aDocName, aFltName, aOptions ); + pLink->SetInCreate( TRUE ); + pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aDocName, &aFltName ); + pLink->Update(); + pLink->SetInCreate( FALSE ); + } + } +} + +#pragma SEG_FUNCDEF(docsh6_0a) + +BOOL ScDocShell::ReloadTabLinks() +{ + SvxLinkManager* pLinkManager = aDocument.GetLinkManager(); + + BOOL bAny = FALSE; + USHORT nCount = pLinkManager->GetLinks().Count(); + for (USHORT i=0; i<nCount; i++ ) + { + SvBaseLink* pBase = *pLinkManager->GetLinks()[i]; + if (pBase->ISA(ScTableLink)) + { + ScTableLink* pTabLink = (ScTableLink*)pBase; +// pTabLink->SetAddUndo(FALSE); //! Undo's zusammenfassen + pTabLink->SetPaint(FALSE); // Paint nur einmal am Ende + pTabLink->Update(); + pTabLink->SetPaint(TRUE); +// pTabLink->SetAddUndo(TRUE); + bAny = TRUE; + } + } + + if ( bAny ) + { + // Paint nur einmal + PostPaint( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB), + PAINT_GRID | PAINT_TOP | PAINT_LEFT ); + + SetDocumentModified(); + } + + return TRUE; //! Fehler erkennen +} + +/*------------------------------------------------------------------------ + + $Log: not supported by cvs2svn $ + Revision 1.25 2000/09/17 14:09:00 willem.vandorp + OpenOffice header added. + + Revision 1.24 2000/08/31 16:38:22 willem.vandorp + Header and footer replaced + + Revision 1.23 2000/04/20 16:51:18 nn + unicode changes + + Revision 1.22 2000/02/11 12:25:25 hr + #70473# changes for unicode ( patched by automated patchtool ) + + Revision 1.21 1998/08/06 08:37:38 TJ + include + + + Rev 1.20 06 Aug 1998 10:37:38 TJ + include + + Rev 1.19 11 Jun 1998 11:24:18 NN + wenn VisArea von aussen gesetzt, Position beibehalten + + Rev 1.18 27 Jan 1998 12:42:26 TJ + include + + Rev 1.17 05 Dec 1997 19:51:28 ANK + Includes geaendert + + Rev 1.16 22 Sep 1997 18:08:40 NN + #44070# ReloadTabLinks: nur 1x Paint + + Rev 1.15 10 Sep 1997 21:16:32 NN + IsOle: Abfrage per CreateMode + + Rev 1.14 17 Sep 1996 16:10:38 NN + Bei Link auch Filter-Options speichern + + Rev 1.13 09 Aug 1996 20:36:06 NN + Svx-Includes aus scitems.hxx raus + + Rev 1.12 08 Aug 1996 11:03:30 NF + includes... + + Rev 1.11 22 Apr 1996 14:57:30 NN + UpdateOle: SetVisArea immer wenn geaendert + + Rev 1.10 20 Mar 1996 14:24:50 NN + Zoom fuer X und Y getrennt (wegen OLE) + + Rev 1.9 09 Mar 1996 18:18:56 NN + bei Insert und LoadStyles hinterher die Pools anpassen + + Rev 1.8 06 Mar 1996 19:17:22 NN + ReloadTabLinks + + Rev 1.7 05 Mar 1996 19:52:32 NN + UpdateOle: auch SetVisibleTab + + Rev 1.6 01 Mar 1996 17:04:54 NN + UpdateLinks: unbenutzte Links loeschen + + Rev 1.5 27 Feb 1996 15:01:46 NN + UpdateLinks + + Rev 1.4 09 Jan 1996 19:25:54 NN + bei SetVisArea das Embedded-Rechteck (tuerkiser Rahmen) updaten + + Rev 1.3 10 Dec 1995 15:20:50 TRI + define entfernt + + Rev 1.2 23 Nov 1995 16:11:02 NN + DataChanged bei SetVisArea + + Rev 1.1 21 Nov 1995 15:49:14 TLX + Insert wandert in den SFX + + Rev 1.0 17 Nov 1995 15:45:44 NN + Initial revision. + +------------------------------------------------------------------------*/ + +#pragma SEG_EOFMODULE diff --git a/sc/source/ui/docshell/docsh7.cxx b/sc/source/ui/docshell/docsh7.cxx new file mode 100644 index 000000000000..fc0837c981e5 --- /dev/null +++ b/sc/source/ui/docshell/docsh7.cxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * $RCSfile: docsh7.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#pragma hdrstop + +// INCLUDE --------------------------------------------------------- + +#include "docsh.hxx" + +//------------------------------------------------------------------ + +void ScDocShell::GetDrawObjState( SfxItemSet &rSet ) +{ + // SID_SC_ACTIVEOBJECT (SelectedObject) - removed (old Basic) +} + + + diff --git a/sc/source/ui/docshell/docsh8.cxx b/sc/source/ui/docshell/docsh8.cxx new file mode 100644 index 000000000000..044f9ca8e945 --- /dev/null +++ b/sc/source/ui/docshell/docsh8.cxx @@ -0,0 +1,245 @@ +/************************************************************************* + * + * $RCSfile: docsh8.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#if defined(OS2) && defined(BLC) +// ohne -vi- verhaspelt sich der Dummbatz bei SdbCursor::Variable() inlining +#pragma option -vi- +#endif + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#pragma hdrstop + +// INCLUDE --------------------------------------------------------------- + +#include <sdb/sdbcol.hxx> +#include <sdb/sdbconn.hxx> +#include <sdb/sdbcurs.hxx> +#include <tools/list.hxx> +#include "scitems.hxx" +#include <offmgr/sba.hrc> +#include <offmgr/sbaobj.hxx> +#include <offmgr/app.hxx> +#include <svtools/zforlist.hxx> +#include <vcl/virdev.hxx> +#include <svtools/converter.hxx> + +#include "scerrors.hxx" +#include "docsh.hxx" +#include "filter.hxx" +#include "cell.hxx" +#include "progress.hxx" +#include "globstr.hrc" + +// STATIC DATA ----------------------------------------------------------- + +ULONG ScDocShell::SbaSdbImport(const String& rName, const String& rParStr, + BOOL bHeader, BOOL bSimpleColWidth[MAXCOL+1] ) +{ + ULONG nErr = eERR_OK; + SbaObject* pSbaObject = ((OfficeApplication*)SFX_APP())->GetSbaObject(); + DBG_ASSERT( pSbaObject, "pSbaObject==NULL" ); + SdbConnectionRef xConnect = pSbaObject->OpenConnection(rParStr); + + if( !xConnect.Is() ) + nErr = SCERR_IMPORT_CONNECT; + else + { + USHORT nCol = 0; + USHORT nRow = 0; + UINT16 nCount; + UINT16 i; + //! fuer den RowCount einen extra Cursor anlegen + SdbCursorRef xCount = xConnect->CreateCursor( SDB_SNAPSHOT, SDB_READONLY | SDB_FORWARDONLY ); + // laut Ocke soll das per SQL am schnellsten sein + String aSel = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( + "SELECT COUNT ( * ) FROM \"" )); + aSel += rName; + aSel += '"'; + xCount->Open( aSel, FALSE ); + +// ULONG nRowCount = ( xCount->Status().IsError() ? 1 : +// xCount->Variable(1)->GetLong() ); + + ULONG nRowCount = ( xCount->Status().IsError() ? 1 : + (*xCount->GetRow())[1]->toINT32() ); + + xCount->Close(); + SdbCursorRef xCur = xConnect->CreateCursor( SDB_SNAPSHOT, SDB_READONLY | SDB_FORWARDONLY ); + SdbCursor* pCursor = &xCur; + DBG_ASSERT( pCursor, "Cursor" ); + pCursor->Open( rName, TRUE ); + + if ( !pCursor->Status().IsError() ) + { + if ( nRowCount > MAXROW + 1 ) + nRowCount = MAXROW + 1; + ScProgress aProgress( this, ScGlobal::GetRscString( STR_LOAD_DOC ), + nRowCount ); + + const SdbColumnsRef pColumns = pCursor->GetColumns(); + nCount = pColumns->Count(); + if ( nCount > (bHeader ? 1 : 0) ) + aDocument.DoColResize( 0, 0, nCount - (bHeader ? 2 : 1), + (bHeader ? nRowCount + 1 : nRowCount) ); + + // Spaltenkoepfe + SdbDatabaseType* pType = new SdbDatabaseType[nCount+1]; + if (nCount < 2) + { + DBG_ERROR( "ScDocShell::dBaseImport: Keine Spalten!" ); + } + else if ( nCount > MAXCOL+1 ) + nErr = SCWARN_IMPORT_RANGE_OVERFLOW; // Warnung ausgeben + + String aStr; + for (i=1; i<nCount; i++) // 0 = Bookmark + { + const SdbColumn* pCol = pColumns->Column(i); + aStr = pCol->GetName(); + switch ( pType[i] = pCol->GetType() ) + { + case SDB_DBTYPE_BOOLEAN : + aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",L" )); + break; + case SDB_DBTYPE_DATE : + aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",D" )); + break; + case SDB_DBTYPE_LONGVARCHAR : + aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",M" )); + break; + case SDB_DBTYPE_VARCHAR : + aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",C," )); + aStr += String::CreateFromInt32( pCol->GetLength() ); + break; + case SDB_DBTYPE_DECIMAL : + aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",N," )); + aStr += String::CreateFromInt32( + SvDbaseConverter::ConvertPrecisionToDbase( + pCol->GetLength(), pCol->GetScale() ) ); + aStr += ','; + aStr += String::CreateFromInt32( pCol->GetScale() ); + break; + } + if ( bHeader ) + { + aDocument.SetString( nCol, nRow, 0, aStr ); + ++nCol; + } + } + if ( bHeader ) + ++nRow; // Daten + + //! pass standard format keys to PutVariable? +#if 0 + SvNumberFormatter* pFormatter = aDocument.GetFormatTable(); + ULONG nFormatBool = pFormatter-> + GetStandardFormat( NUMBERFORMAT_LOGICAL, ScGlobal::eLnge ); + ULONG nFormatDate = pFormatter-> + GetStandardFormat( NUMBERFORMAT_DATE, ScGlobal::eLnge ); + + Date* pScDate = pFormatter->GetNullDate(); + Date aRefDate(30,12,1899); +// Date aRefDate(3,1,1900); + double nDateDiff; + if ( pScDate && ! (*pScDate == aRefDate) ) + nDateDiff = (double)(aRefDate - *pScDate); + else + nDateDiff = 0; +#endif + + pCursor->First(); + while (pCursor->IsInRange()) + { + if ( nRow > MAXROW ) + { + nErr = SCWARN_IMPORT_RANGE_OVERFLOW; // Warnung ausgeben + break; + } + + nCol = 0; + for (i=1; i<nCount; i++) // 0 = Bookmark + { + // All data is in ODbVariant objects and handled in PutVariable + // (including bSimpleColWidth) + + BOOL* pSimple = (i <= MAXCOL+1) ? (&bSimpleColWidth[i-1]) : NULL; + ODbVariantRef xVar = (*pCursor->GetRow())[i]; + aDocument.PutVariable( nCol, nRow, 0, xVar.getBodyPtr(), pType[i], pSimple ); + + ++nCol; + } + ++nRow; + pCursor->Next(); + aProgress.SetStateOnPercent( nRow ); + } + delete [] pType; + } + else + nErr = SCERR_IMPORT_CURSOR; + pCursor->Close(); + } + return nErr; +} + + diff --git a/sc/source/ui/docshell/hiranges.cxx b/sc/source/ui/docshell/hiranges.cxx new file mode 100644 index 000000000000..86405885a303 --- /dev/null +++ b/sc/source/ui/docshell/hiranges.cxx @@ -0,0 +1,88 @@ +/************************************************************************* + * + * $RCSfile: hiranges.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#pragma hdrstop + +#include "hiranges.hxx" + +//================================================================== + +ScHighlightRanges::ScHighlightRanges() +{ +} + +ScHighlightRanges::~ScHighlightRanges() +{ + void* pEntry = aEntries.First(); + while ( pEntry ) + { + delete (ScHighlightEntry*) aEntries.Remove( pEntry ); + pEntry = aEntries.Next(); + } +} + + + + diff --git a/sc/source/ui/docshell/impex.cxx b/sc/source/ui/docshell/impex.cxx new file mode 100644 index 000000000000..f14d481848a5 --- /dev/null +++ b/sc/source/ui/docshell/impex.cxx @@ -0,0 +1,1460 @@ +/************************************************************************* + * + * $RCSfile: impex.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +// System - Includes ----------------------------------------------------- + +class StarBASIC; + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#pragma hdrstop + +#ifndef PCH +#include "sc.hrc" +#define GLOBALOVERFLOW +#endif + +// INCLUDE --------------------------------------------------------------- + +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> + +#include <tools/list.hxx> +#include <tools/string.hxx> +#include <tools/solmath.hxx> +#include <svtools/htmlout.hxx> +#include <svtools/zforlist.hxx> +#include <sot/formats.hxx> +#include <sfx2/mieclip.hxx> +#include <unotools/charclass.hxx> + +#include "global.hxx" +#include "docsh.hxx" +#include "undoblk.hxx" +#include "rangenam.hxx" +#include "viewdata.hxx" +#include "tabvwsh.hxx" +#include "filter.hxx" +#include "asciiopt.hxx" +#include "cell.hxx" +#include "rtfimp.hxx" +#include "htmlimp.hxx" +#include "docoptio.hxx" +#include "progress.hxx" + +#include "impex.hxx" + +#include "globstr.hrc" + +#ifndef _SV_MSGBOX_HXX //autogen +#include <vcl/msgbox.hxx> +#endif + +#ifndef _SV_EXCHANGE_HXX //autogen +#include <vcl/exchange.hxx> +#endif + +#ifndef _SV_SVAPP_HXX //autogen +#include <vcl/svapp.hxx> +#endif + +//======================================================================== + + +// Gesamtdokument ohne Undo + + +ScImportExport::ScImportExport( ScDocument* p ) + : pDoc( p ), pDocSh( PTR_CAST(ScDocShell,p->GetDocumentShell()) ), + nSizeLimit( 0 ), bSingle( TRUE ), bAll( TRUE ), bUndo( FALSE ), + cSep( '\t' ), cStr( '"' ), bFormulas( FALSE ), bOverflow( FALSE ) +{ + pUndoDoc = NULL; + pExtOptions = NULL; +} + +// Insert am Punkt ohne Bereichschecks + + +ScImportExport::ScImportExport( ScDocument* p, const ScAddress& rPt ) + : pDoc( p ), pDocSh( PTR_CAST(ScDocShell,p->GetDocumentShell()) ), + aRange( rPt ), + nSizeLimit( 0 ), bSingle( TRUE ), bAll( FALSE ), bUndo( BOOL( pDocSh != NULL ) ), + cSep( '\t' ), cStr( '"' ), bFormulas( FALSE ), bOverflow( FALSE ) +{ + pUndoDoc = NULL; + pExtOptions = NULL; +} + + +// ctor with a range is only used for export +//! ctor with a string (and bSingle=TRUE) is also used for DdeSetData + +ScImportExport::ScImportExport( ScDocument* p, const ScRange& r ) + : pDoc( p ), pDocSh( PTR_CAST(ScDocShell,p->GetDocumentShell()) ), + aRange( r ), + nSizeLimit( 0 ), bSingle( FALSE ), bAll( FALSE ), bUndo( BOOL( pDocSh != NULL ) ), + cSep( '\t' ), cStr( '"' ), bFormulas( FALSE ), bOverflow( FALSE ) +{ + pUndoDoc = NULL; + pExtOptions = NULL; + // Zur Zeit nur in einer Tabelle! + aRange.aEnd.SetTab( aRange.aStart.Tab() ); +} + +// String auswerten: Entweder Bereich, Punkt oder Gesamtdoc (bei Fehler) +// Falls eine View existiert, wird die TabNo der View entnommen! + + +ScImportExport::ScImportExport( ScDocument* p, const String& rPos ) + : pDoc( p ), pDocSh( PTR_CAST(ScDocShell,p->GetDocumentShell()) ), + nSizeLimit( 0 ), bSingle( TRUE ), bAll( FALSE ), bUndo( BOOL( pDocSh != NULL ) ), + cSep( '\t' ), cStr( '"' ), bFormulas( FALSE ), bOverflow( FALSE ) +{ + pUndoDoc = NULL; + pExtOptions = NULL; + + USHORT nTab = ScDocShell::GetCurTab(); + aRange.aStart.SetTab( nTab ); + String aPos( rPos ); + // Benannter Bereich? + ScRangeName* pRange = pDoc->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 ); // mit dem Inhalt weitertesten + } + } + // Bereich? + if( aRange.Parse( aPos, pDoc ) & SCA_VALID ) + bSingle = FALSE; + // Zelle? + else if( aRange.aStart.Parse( aPos, pDoc ) & SCA_VALID ) + aRange.aEnd = aRange.aStart; + else + bAll = TRUE; +} + + +ScImportExport::~ScImportExport() +{ + delete pUndoDoc; + delete pExtOptions; +} + + +void ScImportExport::SetExtOptions( const ScAsciiOptions& rOpt ) +{ + if ( pExtOptions ) + *pExtOptions = rOpt; + else + pExtOptions = new ScAsciiOptions( rOpt ); + + // "normale" Optionen uebernehmen + + cSep = rOpt.GetFieldSeps().GetChar(0); + cStr = rOpt.GetTextSep(); +} + + +BOOL ScImportExport::IsFormatSupported( SvDataObject* pObj ) +{ + return BOOL( pObj->HasFormat( FORMAT_STRING ) + || pObj->HasFormat( SOT_FORMATSTR_ID_SYLK ) + || pObj->HasFormat( SOT_FORMATSTR_ID_LINK ) + || pObj->HasFormat( SOT_FORMATSTR_ID_HTML ) + || pObj->HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) + || pObj->HasFormat( SOT_FORMATSTR_ID_DIF ) ); +} + + +BOOL ScImportExport::IsFormatSupported( ULONG nFormat ) +{ + return BOOL( nFormat == FORMAT_STRING + || nFormat == SOT_FORMATSTR_ID_SYLK + || nFormat == SOT_FORMATSTR_ID_LINK + || nFormat == SOT_FORMATSTR_ID_HTML + || nFormat == SOT_FORMATSTR_ID_HTML_SIMPLE + || nFormat == SOT_FORMATSTR_ID_DIF ); +} + + +void ScImportExport::AddFormats( SvDataTypeList* pList ) +{ + pList->Insert( SvDataType( SOT_FORMATSTR_ID_HTML, MEDIUM_MEMORY ), LIST_APPEND ); + pList->Insert( SvDataType( SOT_FORMATSTR_ID_SYLK, MEDIUM_MEMORY ), LIST_APPEND ); + pList->Insert( SvDataType( SOT_FORMATSTR_ID_LINK, MEDIUM_MEMORY ), LIST_APPEND ); + pList->Insert( SvDataType( SOT_FORMATSTR_ID_DIF, MEDIUM_MEMORY ), LIST_APPEND ); + pList->Insert( SvDataType( FORMAT_STRING, MEDIUM_MEMORY ), LIST_APPEND ); +} + +////////////////////////////////////////////////////////////////////////////// + +// Vorbereitung fuer Undo: Undo-Dokument erzeugen + + +BOOL ScImportExport::StartPaste() +{ + if ( !bAll && !pDoc->IsBlockEditable + ( aRange.aStart.Tab(), aRange.aStart.Col(),aRange.aStart.Row(), + aRange.aEnd.Col(),aRange.aEnd.Row() ) ) + { + InfoBox aInfoBox(Application::GetDefDialogParent(), + ScGlobal::GetRscString( STR_PROTECTIONERR ) ); + aInfoBox.Execute(); + return FALSE; + } + if( bUndo && pDocSh ) + { + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, aRange.aStart.Tab(), aRange.aEnd.Tab() ); + pDoc->CopyToDocument( aRange, IDF_ALL, FALSE, pUndoDoc ); + } + return TRUE; +} + +// Nachbereitung Insert: Undo/Redo-Aktionen erzeugen, Invalidate/Repaint + + +void ScImportExport::EndPaste() +{ + BOOL bHeight = pDocSh && pDocSh->AdjustRowHeight( + aRange.aStart.Row(), aRange.aEnd.Row(), aRange.aStart.Tab() ); + + if( pUndoDoc ) + { + ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO ); + pRedoDoc->InitUndo( pDoc, aRange.aStart.Tab(), aRange.aEnd.Tab() ); + pDoc->CopyToDocument( aRange, IDF_ALL, FALSE, pRedoDoc ); + ScMarkData aDestMark; + aDestMark.SelectOneTable( aRange.aStart.Tab() ); + pDocSh->GetUndoManager()->AddUndoAction( + new ScUndoPaste( pDocSh, + aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab(), + aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Tab(), aDestMark, + pUndoDoc, pRedoDoc, IDF_ALL, NULL,NULL,NULL,NULL ) ); + } + pUndoDoc = NULL; + if( pDocSh ) + { + if (!bHeight) + pDocSh->PostPaint( aRange, PAINT_GRID ); // AdjustRowHeight paintet evtl. selber + pDocSh->SetDocumentModified(); + } + ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); + if ( pViewSh ) + pViewSh->UpdateInputHandler(); + +} + +///////////////////////////////////////////////////////////////////////////// + + +BOOL ScImportExport::ImportData( SvData& rData ) +{ + ULONG nFmt = rData.GetFormat(); + if ( nFmt == SOT_FORMATSTR_ID_HTML_SIMPLE ) + { + MSE40HTMLClipFormatObj aMSE40ClpObj; + if ( aMSE40ClpObj.GetData( rData ) ) + { + SvStream* pStream = aMSE40ClpObj.GetStream(); + return ImportStream( *pStream, nFmt ); + } + return FALSE; + } + else + { + void* pMem; + ULONG nSize = rData.GetMinMemorySize(); + rData.GetData( &pMem, TRANSFER_REFERENCE ); + if( nFmt == FORMAT_STRING + || nFmt == FORMAT_RTF + || nFmt == SOT_FORMATSTR_ID_SYLK + || nFmt == SOT_FORMATSTR_ID_HTML + || nFmt == SOT_FORMATSTR_ID_DIF ) + { + //! String? Unicode?? + + // Stringende ermitteln! + sal_Char* pBegin = (sal_Char*) pMem; + sal_Char* pEnd = (sal_Char*) pMem + nSize; + + nSize = 0; + while( pBegin != pEnd && *pBegin != '\0' ) + pBegin++, nSize++; + // #72909# MT says only STRING has to be zero-terminated + DBG_ASSERT( pBegin != pEnd || nFmt != FORMAT_STRING, "non zero-terminated String" ) + } + SvMemoryStream aStrm( pMem, nSize, STREAM_READ ); + return ImportStream( aStrm, nFmt ); + } +} + + +BOOL ScImportExport::ExportData( SvData& rData ) +{ + SvMemoryStream aStrm; + if( ExportStream( aStrm, rData.GetFormat() ) ) + { + aStrm << (BYTE) 0; + rData.SetData( (void*)aStrm.GetData(), aStrm.Tell() ); + return TRUE; + } + return FALSE; +} + + +// static +inline void ScImportExport::SetNoEndianSwap( SvStream& rStrm ) +{ +#ifdef __BIGENDIAN + rStrm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN ); +#else + rStrm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); +#endif +} + + +BOOL ScImportExport::ImportString( const String& rText, ULONG nFmt ) +{ + switch ( nFmt ) + { + // formats supporting unicode + case FORMAT_STRING : + { + SvMemoryStream aStrm( (void*)rText.GetBuffer(), rText.Len() * sizeof(sal_Unicode), STREAM_READ ); + aStrm.SetStreamCharSet( RTL_TEXTENCODING_UNICODE ); + SetNoEndianSwap( aStrm ); //! no swapping in memory + return ImportStream( aStrm, nFmt ); + // ImportStream must handle RTL_TEXTENCODING_UNICODE + } + break; + default: + { + rtl_TextEncoding eEnc = gsl_getSystemTextEncoding(); + ByteString aTmp( rText, eEnc ); + SvMemoryStream aStrm( (void*)aTmp.GetBuffer(), aTmp.Len() * sizeof(sal_Char), STREAM_READ ); + aStrm.SetStreamCharSet( eEnc ); + SetNoEndianSwap( aStrm ); //! no swapping in memory + return ImportStream( aStrm, nFmt ); + } + } +} + + +BOOL ScImportExport::ExportString( String& rText, ULONG nFmt ) +{ + DBG_ASSERT( nFmt == FORMAT_STRING, "ScImportExport::ExportString: Unicode not supported for other formats than FORMAT_STRING" ); + if ( nFmt != FORMAT_STRING ) + { + rtl_TextEncoding eEnc = gsl_getSystemTextEncoding(); + ByteString aTmp; + BOOL bOk = ExportByteString( aTmp, eEnc, nFmt ); + rText = UniString( aTmp, eEnc ); + return bOk; + } + if (!nSizeLimit) + nSizeLimit = STRING_MAXLEN; + + SvMemoryStream aStrm; + aStrm.SetStreamCharSet( RTL_TEXTENCODING_UNICODE ); + SetNoEndianSwap( aStrm ); //! no swapping in memory + if( ExportStream( aStrm, nFmt ) ) + { + aStrm << (sal_Unicode) 0; + aStrm.Seek( STREAM_SEEK_TO_END ); + // Sicherheits-Check: + if( aStrm.Tell() <= (ULONG) STRING_MAXLEN ) + { + rText = (const sal_Unicode*) aStrm.GetData(); + return TRUE; + } + } + rText.Erase(); + return FALSE; + + // ExportStream must handle RTL_TEXTENCODING_UNICODE +} + + +BOOL ScImportExport::ExportByteString( ByteString& rText, rtl_TextEncoding eEnc, ULONG nFmt ) +{ + DBG_ASSERT( eEnc != RTL_TEXTENCODING_UNICODE, "ScImportExport::ExportByteString: Unicode not supported" ); + if ( eEnc == RTL_TEXTENCODING_UNICODE ) + eEnc = gsl_getSystemTextEncoding(); + + if (!nSizeLimit) + nSizeLimit = STRING_MAXLEN; + + SvMemoryStream aStrm; + aStrm.SetStreamCharSet( eEnc ); + SetNoEndianSwap( aStrm ); //! no swapping in memory + if( ExportStream( aStrm, nFmt ) ) + { + aStrm << (sal_Char) 0; + aStrm.Seek( STREAM_SEEK_TO_END ); + // Sicherheits-Check: + if( aStrm.Tell() <= (ULONG) STRING_MAXLEN ) + { + rText = (const sal_Char*) aStrm.GetData(); + return TRUE; + } + } + rText.Erase(); + return FALSE; +} + + +BOOL ScImportExport::ImportStream( SvStream& rStrm, ULONG nFmt ) +{ + if( nFmt == FORMAT_STRING ) + { + if( ExtText2Doc( rStrm ) ) // pExtOptions auswerten + return TRUE; + } + if( nFmt == SOT_FORMATSTR_ID_SYLK ) + { + if( Sylk2Doc( rStrm ) ) + return TRUE; + } + if( nFmt == SOT_FORMATSTR_ID_DIF ) + { + if( Dif2Doc( rStrm ) ) + return TRUE; + } + if( nFmt == FORMAT_RTF ) + { + if( RTF2Doc( rStrm ) ) + return TRUE; + } + if( nFmt == SOT_FORMATSTR_ID_LINK ) + return TRUE; // Link-Import? + if ( nFmt == SOT_FORMATSTR_ID_HTML ) + { + if( HTML2Doc( rStrm ) ) + return TRUE; + } + if ( nFmt == SOT_FORMATSTR_ID_HTML_SIMPLE ) + { + if( HTML2Doc( rStrm ) ) + return TRUE; + } + + return FALSE; +} + + +BOOL ScImportExport::ExportStream( SvStream& rStrm, ULONG nFmt ) +{ + if( nFmt == FORMAT_STRING ) + { + if( Doc2Text( rStrm ) ) + return TRUE; + } + if( nFmt == SOT_FORMATSTR_ID_SYLK ) + { + if( Doc2Sylk( rStrm ) ) + return TRUE; + } + if( nFmt == SOT_FORMATSTR_ID_DIF ) + { + if( Doc2Dif( rStrm ) ) + return TRUE; + } + if( nFmt == SOT_FORMATSTR_ID_LINK && !bAll ) + { + String aDocName; + if ( pDoc->IsClipboard() ) + aDocName = ScGlobal::GetClipDocName(); + else + { + SfxObjectShell* pShell = pDoc->GetDocumentShell(); + if (pShell) + aDocName = pShell->GetTitle( SFX_TITLE_FULLNAME ); + } + + DBG_ASSERT( aDocName.Len(), "ClipBoard document has no name! :-/" ); + if( aDocName.Len() ) + { + String aRefName; + USHORT nFlags = SCA_VALID | SCA_TAB_3D; + if( bSingle ) + aRange.aStart.Format( aRefName, nFlags, pDoc ); + else + { + if( aRange.aStart.Tab() != aRange.aEnd.Tab() ) + nFlags |= SCA_TAB2_3D; + aRange.Format( aRefName, nFlags, pDoc ); + } + String aAppName = Application::GetAppName(); + + WriteUnicodeOrByteString( rStrm, aAppName, TRUE ); + WriteUnicodeOrByteString( rStrm, aDocName, TRUE ); + WriteUnicodeOrByteString( rStrm, aRefName, TRUE ); + if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE ) + rStrm << sal_Unicode(0); + else + rStrm << sal_Char(0); + return BOOL( rStrm.GetError() == SVSTREAM_OK ); + } + } + if( nFmt == SOT_FORMATSTR_ID_HTML ) + { + if( Doc2HTML( rStrm ) ) + return TRUE; + } + if( nFmt == FORMAT_RTF ) + { + if( Doc2RTF( rStrm ) ) + return TRUE; + } + + return FALSE; +} + + +//static +void ScImportExport::WriteUnicodeOrByteString( SvStream& rStrm, const String& rString, BOOL bZero ) +{ + rtl_TextEncoding eEnc = rStrm.GetStreamCharSet(); + if ( eEnc == RTL_TEXTENCODING_UNICODE ) + { + if ( !IsEndianSwap( rStrm ) ) + rStrm.Write( rString.GetBuffer(), rString.Len() * sizeof(sal_Unicode) ); + else + { + const sal_Unicode* p = rString.GetBuffer(); + const sal_Unicode* const pStop = p + rString.Len(); + while ( p < pStop ) + { + rStrm << *p; + } + } + if ( bZero ) + rStrm << sal_Unicode(0); + } + else + { + ByteString aByteStr( rString, eEnc ); + rStrm << aByteStr.GetBuffer(); + if ( bZero ) + rStrm << sal_Char(0); + } +} + + +// static +void ScImportExport::WriteUnicodeOrByteEndl( SvStream& rStrm ) +{ + if ( rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE ) + { // same as endl() but unicode + switch ( rStrm.GetLineDelimiter() ) + { + case LINEEND_CR : + rStrm << sal_Unicode(_CR); + break; + case LINEEND_LF : + rStrm << sal_Unicode(_LF); + break; + default: + rStrm << sal_Unicode(_CR) << sal_Unicode(_LF); + } + } + else + endl( rStrm ); +} + + +enum DoubledQuoteMode +{ + DQM_KEEP, // both are taken + DQM_ESCAPE, // escaped quote, one is taken, one ignored + DQM_CONCAT, // first is end, next is start, both ignored => strings combined + DQM_SEPARATE // end one string and begin next +}; + +const sal_Unicode* lcl_ScanString( const sal_Unicode* p, String& rString, + sal_Unicode cStr, DoubledQuoteMode eMode ) +{ + p++; //! jump over opening quote + BOOL bCont; + do + { + bCont = FALSE; + const sal_Unicode* p0 = p; + for( ;; ) + { + if( !*p ) + break; + if( *p == cStr ) + { + if ( *++p != cStr ) + break; + // doubled quote char + switch ( eMode ) + { + case DQM_KEEP : + p++; // both for us (not breaking for-loop) + break; + case DQM_ESCAPE : + p++; // one for us (breaking for-loop) + bCont = TRUE; // and more + break; + case DQM_CONCAT : + if ( p0+1 < p ) + rString.Append( p0, (p-1) - p0 ); // first part + p0 = ++p; // text of next part starts here + break; + case DQM_SEPARATE : + // positioned on next opening quote + break; + } + if ( eMode == DQM_ESCAPE || eMode == DQM_SEPARATE ) + break; + } + else + p++; + } + if ( p0 < p ) + rString.Append( p0, ((*p || *(p-1) == cStr) ? p-1 : p) - p0 ); + } while ( bCont ); + return p; +} + + +void lcl_WriteString( SvStream& rStrm, String& rString, sal_Unicode cStr ) +{ + xub_StrLen n = 0; + while( ( n = rString.Search( cStr, n ) ) != STRING_NOTFOUND ) + { + rString.Insert( cStr, n ); + n += 2; + } + + rString.Insert( cStr, 0 ); + rString.Append( cStr ); + + ScImportExport::WriteUnicodeOrByteString( rStrm, rString ); +} + +inline void lcl_WriteSimpleString( SvStream& rStrm, const String& rString ) +{ + ScImportExport::WriteUnicodeOrByteString( rStrm, rString ); +} + +////////////////////////////////////////////////////////////////////////////// + + +BOOL ScImportExport::Text2Doc( SvStream& rStrm ) +{ + BOOL bOk = TRUE; + + USHORT nStartCol = aRange.aStart.Col(); + USHORT nStartRow = aRange.aStart.Row(); + USHORT nEndCol = aRange.aEnd.Col(); + USHORT nEndRow = aRange.aEnd.Row(); + ULONG nOldPos = rStrm.Tell(); + BOOL bData = BOOL( !bSingle ); + if( !bSingle) + bOk = StartPaste(); + + while( bOk ) + { + ByteString aByteLine; + String aLine, aCell; + USHORT nRow = nStartRow; + rStrm.Seek( nOldPos ); + for( ;; ) + { + //! allow unicode + rStrm.ReadLine( aByteLine ); + aLine = String( aByteLine, rStrm.GetStreamCharSet() ); + if( rStrm.IsEof() ) + break; + USHORT nCol = nStartCol; + const sal_Unicode* p = aLine.GetBuffer(); + while( *p ) + { + aCell.Erase(); + if( *p == cStr ) + { + p = lcl_ScanString( p, aCell, cStr, DQM_KEEP ); + while( *p && *p != cSep ) + p++; + if( *p ) + p++; + } + else + { + const sal_Unicode* q = p; + while( *p && *p != cSep ) + p++; + aCell.Assign( q, p - q ); + if( *p ) + p++; + } + if (nCol<=MAXCOL && nRow<=MAXROW ) + { + if( bSingle ) + { + if (nCol>nEndCol) nEndCol = nCol; + if (nRow>nEndRow) nEndRow = nRow; + } + if( bData && nCol <= nEndCol && nRow <= nEndRow ) + pDoc->SetString( nCol, nRow, aRange.aStart.Tab(), aCell ); + } + else // zuviele Spalten/Zeilen + bOverflow = TRUE; // beim Import Warnung ausgeben + ++nCol; + } + ++nRow; + } + + if( !bData ) + { + aRange.aEnd.SetCol( nEndCol ); + aRange.aEnd.SetRow( nEndRow ); + bOk = StartPaste(); + bData = TRUE; + } + else + break; + } + + EndPaste(); + return bOk; +} + + // + // erweiterter Ascii-Import + // + + +void lcl_PutString( ScDocument* pDoc, USHORT nCol, USHORT nRow, USHORT nTab, + const String& rStr, BYTE nColFormat, const International& rInter, + const International* pSecondInt ) +{ + if ( nColFormat == SC_COL_SKIP || !rStr.Len() || nCol > MAXCOL || nRow > MAXROW ) + return; + + if ( nColFormat == SC_COL_TEXT ) + { + pDoc->PutCell( nCol, nRow, nTab, new ScStringCell( rStr ) ); + return; + } + + if ( nColFormat == SC_COL_ENGLISH ) + { + //! SetString mit Extra-Flag ??? + + SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); + ULONG nEnglish = pFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US); + double fVal; + if ( pFormatter->IsNumberFormat( rStr, nEnglish, fVal ) ) + { + // Zahlformat wird nicht auf englisch gesetzt + pDoc->SetValue( nCol, nRow, nTab, fVal ); + return; + } + // sonst weiter mit SetString + } + else if ( nColFormat != SC_COL_STANDARD ) // Datumsformate + { + // nach genau drei Teilen suchen + + xub_StrLen nLen = rStr.Len(); + xub_StrLen nStart[3]; + xub_StrLen nEnd[3]; + USHORT nFound = 0; + BOOL bInNum = FALSE; + for ( xub_StrLen nPos=0; nPos<nLen; nPos++ ) + { + if ( ScGlobal::pCharClass->isLetterNumeric( rStr, nPos ) ) + { + if (!bInNum) + { + if ( nFound >= 3 ) + break; // zuviele Teile + bInNum = TRUE; + nStart[nFound] = nPos; + ++nFound; + } + nEnd[nFound-1] = nPos; + } + else + bInNum = FALSE; + } + if ( nFound == 3 ) // genau 3 Teile ? + { + USHORT nDP, nMP, nYP; + switch ( nColFormat ) + { + case SC_COL_YMD: nDP = 2; nMP = 1; nYP = 0; break; + case SC_COL_MDY: nDP = 1; nMP = 0; nYP = 2; break; + case SC_COL_DMY: + default: nDP = 0; nMP = 1; nYP = 2; break; + } + USHORT nDay = (USHORT) rStr.Copy( nStart[nDP], nEnd[nDP]+1-nStart[nDP] ).ToInt32(); + USHORT nYear = (USHORT) rStr.Copy( nStart[nYP], nEnd[nYP]+1-nStart[nYP] ).ToInt32(); + String aMStr = rStr.Copy( nStart[nMP], nEnd[nMP]+1-nStart[nMP] ); + USHORT nMonth = (USHORT) aMStr.ToInt32(); + if (!nMonth) + { + USHORT i; + // first test all month names from local international + for (i=1; i<=12 && !nMonth; i++) + if ( rInter.CompareEqual( aMStr, rInter.GetMonthText(i), INTN_COMPARE_IGNORECASE ) || + rInter.CompareEqual( aMStr, rInter.GetAbbrevMonthText(i), INTN_COMPARE_IGNORECASE ) ) + nMonth = i; + // if none found, then test english month names + if ( !nMonth && pSecondInt ) + for (i=1; i<=12 && !nMonth; i++) + if ( pSecondInt->CompareEqual( aMStr, pSecondInt->GetMonthText(i), INTN_COMPARE_IGNORECASE ) || + pSecondInt->CompareEqual( aMStr, pSecondInt->GetAbbrevMonthText(i), INTN_COMPARE_IGNORECASE ) ) + nMonth = i; + } + + SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); + if ( nYear < 100 ) + nYear = pFormatter->ExpandTwoDigitYear( nYear ); + + if ( nDay && nMonth && nDay<=31 && nMonth<=12 ) + { + Date aDate( nDay, nMonth, nYear ); + Date aNullDate = *pFormatter->GetNullDate(); + double nValue = aDate - aNullDate; + long nFormat = pFormatter->GetStandardFormat( NUMBERFORMAT_DATE, pDoc->GetLanguage() ); + + pDoc->PutCell( nCol, nRow, nTab, new ScValueCell(nValue), nFormat, FALSE ); + + return; // Erfolg + } + } + } + + // Standard oder Datum nicht erkannt -> SetString + + pDoc->SetString( nCol, nRow, nTab, rStr ); +} + + +String lcl_GetFixed( const String& rLine, xub_StrLen nStart, xub_StrLen nNext ) +{ + xub_StrLen nLen = rLine.Len(); + if (nNext > nLen) + nNext = nLen; + if ( nNext <= nStart ) + return EMPTY_STRING; + + const sal_Unicode* pStr = rLine.GetBuffer(); + + xub_StrLen nSpace = nNext; + while ( nSpace > nStart && pStr[nSpace-1] == ' ' ) + --nSpace; + + return rLine.Copy( nStart, nSpace-nStart ); +} + + +BOOL ScImportExport::ExtText2Doc( SvStream& rStrm ) +{ + if (!pExtOptions) + return Text2Doc( rStrm ); + + ULONG nOldPos = rStrm.Tell(); + rStrm.Seek( STREAM_SEEK_TO_END ); + ScProgress aProgress( pDocSh, ScGlobal::GetRscString( STR_LOAD_DOC ), rStrm.Tell() - nOldPos ); + rStrm.Seek( nOldPos ); + + BOOL bOld = ScColumn::bDoubleAlloc; + ScColumn::bDoubleAlloc = TRUE; + + DBG_ASSERT( !bUndo, "ExtText2Doc mit Undo noch nicht implementiert!" ); + USHORT nStartCol = aRange.aStart.Col(); + USHORT nStartRow = aRange.aStart.Row(); + USHORT nTab = aRange.aStart.Tab(); + + BOOL bFixed = pExtOptions->IsFixedLen(); + const sal_Unicode* pSeps = pExtOptions->GetFieldSeps().GetBuffer(); + BOOL bMerge = pExtOptions->IsMergeSeps(); + USHORT nInfoCount = pExtOptions->GetInfoCount(); + const xub_StrLen* pColStart = pExtOptions->GetColStart(); + const BYTE* pColFormat = pExtOptions->GetColFormat(); + long nSkipLines = pExtOptions->GetStartRow(); + + LanguageType eDocLang = pDoc->GetLanguage(); + International aInter( eDocLang ); // fuer Datums-Erkennung + International* pEnglish = NULL; + if ( eDocLang != LANGUAGE_ENGLISH_US ) + pEnglish = new International( LANGUAGE_ENGLISH_US ); // for English month names + + ByteString aByteLine; + String aLine, aCell; + USHORT i; + USHORT nRow = nStartRow; + + while(--nSkipLines>0) + { + //! allow unicode + rStrm.ReadLine( aByteLine ); // content is ignored + if ( rStrm.IsEof() ) + break; + } + for( ;; ) + { + //! allow unicode + rStrm.ReadLine( aByteLine ); + aLine = String( aByteLine, rStrm.GetStreamCharSet() ); + if ( rStrm.IsEof() ) + break; + + xub_StrLen nLineLen = aLine.Len(); + USHORT nCol = nStartCol; + if ( bFixed ) // Feste Satzlaenge + { + for ( i=0; i<nInfoCount; i++ ) + { + if ( pColFormat[i] != SC_COL_SKIP ) // sonst auch nCol nicht hochzaehlen + { + xub_StrLen nStart = pColStart[i]; + xub_StrLen nNext = ( i+1 < nInfoCount ) ? pColStart[i+1] : nLineLen; + aCell = lcl_GetFixed( aLine, nStart, nNext ); + lcl_PutString( pDoc, nCol, nRow, nTab, aCell, pColFormat[i], aInter, pEnglish ); + ++nCol; + } + } + } + else // Nach Trennzeichen suchen + { + USHORT nSourceCol = 0; + USHORT nInfoStart = 0; + const sal_Unicode* p = aLine.GetBuffer(); + while (*p) + { + p = ScImportExport::ScanNextFieldFromString( p, aCell, cStr, pSeps, bMerge ); + + BYTE nFmt = SC_COL_STANDARD; + for ( i=nInfoStart; i<nInfoCount; i++ ) + { + if ( pColStart[i] == nSourceCol + 1 ) // pColStart ist 1-basiert + { + nFmt = pColFormat[i]; + nInfoStart = i + 1; // ColInfos sind in Reihenfolge + break; // for + } + } + if ( nFmt != SC_COL_SKIP ) + { + lcl_PutString( pDoc, nCol, nRow, nTab, aCell, nFmt, aInter, pEnglish ); + ++nCol; + } + + ++nSourceCol; + } + } + + aProgress.SetStateOnPercent( rStrm.Tell() - nOldPos ); + ++nRow; + if ( nRow > MAXROW ) + { + bOverflow = TRUE; // beim Import Warnung ausgeben + break; + } + } + + ScColumn::bDoubleAlloc = bOld; + pDoc->DoColResize( nTab, 0, MAXCOL, 0 ); + + delete pEnglish; + + return TRUE; +} + + +// static +const sal_Unicode* ScImportExport::ScanNextFieldFromString( const sal_Unicode* p, + String& rField, sal_Unicode cStr, const sal_Unicode* pSeps, BOOL bMergeSeps ) +{ + rField.Erase(); + if ( *p == cStr ) // String in Anfuehrungszeichen + { + p = lcl_ScanString( p, rField, cStr, DQM_ESCAPE ); + while ( *p && !ScGlobal::UnicodeStrChr( pSeps, *p ) ) + p++; + if( *p ) + p++; + } + else // bis zum Trennzeichen + { + const sal_Unicode* p0 = p; + while ( *p && !ScGlobal::UnicodeStrChr( pSeps, *p ) ) + p++; + rField.Append( p0, p - p0 ); + if( *p ) + p++; + } + if ( bMergeSeps ) // folgende Trennzeichen ueberspringen + { + while ( *p && ScGlobal::UnicodeStrChr( pSeps, *p ) ) + p++; + } + return p; +} + + // + // + // + + +BOOL ScImportExport::Doc2Text( SvStream& rStrm ) +{ + USHORT nCol; + USHORT nRow; + USHORT nStartCol = aRange.aStart.Col(); + USHORT nStartRow = aRange.aStart.Row(); + USHORT nEndCol = aRange.aEnd.Col(); + USHORT nEndRow = aRange.aEnd.Row(); + String aCell; + + for (nRow = nStartRow; nRow <= nEndRow; nRow++) + { + for (nCol = nStartCol; nCol <= nEndCol; nCol++) + { + CellType eType; + pDoc->GetCellType( nCol, nRow, aRange.aStart.Tab(), eType ); + switch (eType) + { + case CELLTYPE_FORMULA: + { + if (bFormulas) + { + pDoc->GetFormula( nCol, nRow, aRange.aStart.Tab(), aCell, TRUE ); + if( aCell.Search( cSep ) != STRING_NOTFOUND ) + lcl_WriteString( rStrm, aCell, cStr ); + else + lcl_WriteSimpleString( rStrm, aCell ); + } + else + { + pDoc->GetString( nCol, nRow, aRange.aStart.Tab(), aCell ); + if( aCell.Search( cSep ) != STRING_NOTFOUND ) + lcl_WriteString( rStrm, aCell, cStr ); + else + lcl_WriteSimpleString( rStrm, aCell ); + } + } + break; + case CELLTYPE_VALUE: + { + pDoc->GetString( nCol, nRow, aRange.aStart.Tab(), aCell ); + lcl_WriteSimpleString( rStrm, aCell ); + } + break; + case CELLTYPE_NOTE: + case CELLTYPE_NONE: + break; + default: + { + pDoc->GetString( nCol, nRow, aRange.aStart.Tab(), aCell ); + if( aCell.Search( cSep ) != STRING_NOTFOUND ) + lcl_WriteString( rStrm, aCell, cStr ); + else + lcl_WriteSimpleString( rStrm, aCell ); + } + } + if( nCol < nEndCol ) + lcl_WriteSimpleString( rStrm, String(cSep) ); + } +// if( nRow < nEndRow ) + WriteUnicodeOrByteEndl( rStrm ); + if( rStrm.GetError() != SVSTREAM_OK ) + break; + if( nSizeLimit && rStrm.Tell() > nSizeLimit ) + break; + } + + return BOOL( rStrm.GetError() == SVSTREAM_OK ); +} + + +BOOL ScImportExport::Sylk2Doc( SvStream& rStrm ) +{ + BOOL bOk = TRUE; + BOOL bMyDoc = FALSE; + + International aEnglishInt( LANGUAGE_ENGLISH_US ); // for StringToDouble + + USHORT nStartCol = aRange.aStart.Col(); + USHORT nStartRow = aRange.aStart.Row(); + USHORT nEndCol = aRange.aEnd.Col(); + USHORT nEndRow = aRange.aEnd.Row(); + ULONG nOldPos = rStrm.Tell(); + BOOL bData = BOOL( !bSingle ); + + if( !bSingle) + bOk = StartPaste(); + + while( bOk ) + { + String aLine; + String aCell; + ByteString aByteLine; + USHORT nCol = nStartCol; + USHORT nRow = nStartRow; + rStrm.Seek( nOldPos ); + for( ;; ) + { + //! allow unicode + rStrm.ReadLine( aByteLine ); + aLine = String( aByteLine, rStrm.GetStreamCharSet() ); + if( rStrm.IsEof() ) + break; + const sal_Unicode* p = aLine.GetBuffer(); + sal_Unicode cTag = *p++; + if( cTag == 'I' && *p == 'D' ) + { + aLine.Erase( 0, 4 ); + bMyDoc = aLine.EqualsAscii( "SCALC3" ); + } + else if( cTag == 'E' ) // Ende + break; + else if( cTag == 'C' || cTag == 'F' ) // in F kann die Position gesetzt werden + { + if( *p++ != ';' ) + return FALSE; + while( *p ) + { + sal_Unicode ch = *p++; + ch = ScGlobal::ToUpperAlpha( ch ); + switch( ch ) + { + case 'X': + nCol = String( p ).ToInt32() + nStartCol - 1; + break; + case 'Y': + nRow = String( p ).ToInt32() + nStartRow - 1; + break; + case 'K': + if( cTag != 'C' ) // nur bei 'C' + break; + if( !bSingle && + ( nCol < nStartCol || nCol > nEndCol + || nRow < nStartRow || nRow > nEndRow + || nCol > MAXCOL || nRow > MAXROW ) ) + break; + if( !bData ) + { + if( nRow > nEndRow ) + nEndRow = nRow; + if( nCol > nEndCol ) + nEndCol = nCol; + break; + } + if( *p == '"' ) + { + String aText; + p = lcl_ScanString( p, aText, '"', DQM_KEEP ); + pDoc->SetString( nCol, nRow, aRange.aStart.Tab(), aText ); + } + else + { + int nErr; + double fVal = SolarMath::StringToDouble( p, aEnglishInt, nErr ); + pDoc->SetValue( nCol, nRow, aRange.aStart.Tab(), fVal ); + } + break; + case 'E': + if( !bMyDoc || !bData ) + break; + if( *p == '"' ) + { + String aText; + p = lcl_ScanString( p, aText, '"', DQM_KEEP ); + aText.Insert( '=', 0 ); + pDoc->SetString( nCol, nRow, aRange.aStart.Tab(), aText ); + } + else + { + sal_Unicode* q = (sal_Unicode*) p; + while( *q && *q != ';' ) + q++; + *q = 0; + String aText( '=' ); + aText += p; + *q = ';'; p = q; + pDoc->SetString( nCol, nRow, aRange.aStart.Tab(), aText ); + } + break; + } + while( *p && *p != ';' ) + p++; + if( *p ) + p++; + } + } + } + if( !bData ) + { + aRange.aEnd.SetCol( nEndCol ); + aRange.aEnd.SetRow( nEndRow ); + bOk = StartPaste(); + bData = TRUE; + } + else + break; + } + + EndPaste(); + return bOk; +} + + +BOOL ScImportExport::Doc2Sylk( SvStream& rStrm ) +{ + USHORT nCol; + USHORT nRow; + USHORT nStartCol = aRange.aStart.Col(); + USHORT nStartRow = aRange.aStart.Row(); + USHORT nEndCol = aRange.aEnd.Col(); + USHORT nEndRow = aRange.aEnd.Row(); + String aCellStr; + String aValStr; + lcl_WriteSimpleString( rStrm, + String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "ID;PSCALC3" )) ); + WriteUnicodeOrByteEndl( rStrm ); + + for (nRow = nStartRow; nRow <= nEndRow; nRow++) + { + for (nCol = nStartCol; nCol <= nEndCol; nCol++) + { + String aBufStr; + CellType eType; + double nVal; + BOOL bForm = FALSE; + USHORT r = nRow - nStartRow + 1; + USHORT c = nCol - nStartCol + 1; + pDoc->GetCellType( nCol, nRow, aRange.aStart.Tab(), eType ); + switch( eType ) + { + case CELLTYPE_FORMULA: + bForm = bFormulas; + if( pDoc->HasValueData( nCol, nRow, aRange.aStart.Tab()) ) + goto hasvalue; + else + goto hasstring; + + case CELLTYPE_VALUE: + hasvalue: + pDoc->GetValue( nCol, nRow, aRange.aStart.Tab(), nVal ); + //sprintf( cBuf, "C;X%d;Y%d;K%lg", c, r, nVal ); + + aValStr.Erase(); + SolarMath::DoubleToString( aValStr, nVal, 'A', INT_MAX, '.', TRUE ); + + aBufStr.AssignAscii(RTL_CONSTASCII_STRINGPARAM( "C;X" )); + aBufStr += String::CreateFromInt32( c ); + aBufStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";Y" )); + aBufStr += String::CreateFromInt32( r ); + aBufStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";K" )); + aBufStr += aValStr; + lcl_WriteSimpleString( rStrm, aBufStr ); + goto checkformula; + + case CELLTYPE_STRING: + case CELLTYPE_EDIT: + hasstring: + pDoc->GetString( nCol, nRow, aRange.aStart.Tab(), aCellStr ); + //sprintf( cBuf, "C;X%d;Y%d;K", c, r ); + + aBufStr.AssignAscii(RTL_CONSTASCII_STRINGPARAM( "C;X" )); + aBufStr += String::CreateFromInt32( c ); + aBufStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";Y" )); + aBufStr += String::CreateFromInt32( r ); + aBufStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ";K" )); + lcl_WriteSimpleString( rStrm, aBufStr ); + lcl_WriteString( rStrm, aCellStr, '"' ); + + checkformula: + if( bForm ) + { + pDoc->GetFormula( nCol, nRow, aRange.aStart.Tab(), aCellStr, TRUE ); + if (aCellStr.GetChar(0) == '=') + aCellStr.Erase(0,1); + lcl_WriteSimpleString( rStrm, + String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( ";E" )) ); + if( aCellStr.Search( ';' ) != STRING_NOTFOUND ) + lcl_WriteString( rStrm, aCellStr, '"' ); + else + lcl_WriteSimpleString( rStrm, aCellStr ); + } + WriteUnicodeOrByteEndl( rStrm ); + break; + } + } + } + lcl_WriteSimpleString( rStrm, String( 'E' ) ); + WriteUnicodeOrByteEndl( rStrm ); + return BOOL( rStrm.GetError() == SVSTREAM_OK ); +} + + +BOOL ScImportExport::Doc2HTML( SvStream& rStrm ) +{ + // CharSet is ignored in ScExportHTML + ScExportHTML( rStrm, pDoc, aRange, RTL_TEXTENCODING_DONTKNOW, bAll, aStreamPath ); + return BOOL( rStrm.GetError() == SVSTREAM_OK ); +} + +BOOL ScImportExport::Doc2RTF( SvStream& rStrm ) +{ + // CharSet is ignored in ScExportRTF + ScExportRTF( rStrm, pDoc, aRange, RTL_TEXTENCODING_DONTKNOW ); + return BOOL( rStrm.GetError() == SVSTREAM_OK ); +} + + +BOOL ScImportExport::Doc2Dif( SvStream& rStrm ) +{ + ScExportDif( rStrm, pDoc, aRange, gsl_getSystemTextEncoding() ); + return TRUE; +} + + +BOOL ScImportExport::Dif2Doc( SvStream& rStrm ) +{ + USHORT nTab = aRange.aStart.Tab(); + ScDocument* pImportDoc = new ScDocument( SCDOCMODE_UNDO ); + pImportDoc->InitUndo( pDoc, nTab, nTab ); + + ScImportDif( rStrm, pImportDoc, aRange.aStart, gsl_getSystemTextEncoding() ); + + USHORT nEndCol, nEndRow; + pImportDoc->GetCellArea( nTab, nEndCol, nEndRow ); + aRange.aEnd = ScAddress( nEndCol, nEndRow, nTab ); + + BOOL bOk = StartPaste(); + if (bOk) + { + USHORT nFlags = IDF_ALL & ~IDF_STYLES; + pDoc->DeleteAreaTab( aRange, nFlags ); + pImportDoc->CopyToDocument( aRange, nFlags, FALSE, pDoc ); + EndPaste(); + } + + delete pImportDoc; + + return bOk; +} + + +BOOL ScImportExport::RTF2Doc( SvStream& rStrm ) +{ + ScRTFImport aImp( pDoc, aRange ); + aImp.Read( rStrm ); + aRange = aImp.GetRange(); + + BOOL bOk = StartPaste(); + if (bOk) + { + USHORT nFlags = IDF_ALL & ~IDF_STYLES; + pDoc->DeleteAreaTab( aRange, nFlags ); + aImp.WriteToDocument(); + EndPaste(); + } + + return bOk; +} + + +BOOL ScImportExport::HTML2Doc( SvStream& rStrm ) +{ + ScHTMLImport aImp( pDoc, aRange ); + aImp.Read( rStrm ); + aRange = aImp.GetRange(); + + BOOL bOk = StartPaste(); + if (bOk) + { + // ScHTMLImport may call ScDocument::InitDrawLayer, resulting in + // a DrawLayer but no DrawView -> create DrawLayer and View here + if (pDocSh) + pDocSh->MakeDrawLayer(); + + USHORT nFlags = IDF_ALL & ~IDF_STYLES; + pDoc->DeleteAreaTab( aRange, nFlags ); + aImp.WriteToDocument(); + EndPaste(); + } + + return bOk; +} + + diff --git a/sc/source/ui/docshell/makefile.mk b/sc/source/ui/docshell/makefile.mk new file mode 100644 index 000000000000..0ec3b23dfbfa --- /dev/null +++ b/sc/source/ui/docshell/makefile.mk @@ -0,0 +1,141 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (the "License"); You may not use this file +# except in compliance with the License. You may obtain a copy of the +# License at http://www.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=sc +TARGET=docshell + +PROJECTPCH4DLL=TRUE +PROJECTPCH=ui_pch +PDBTARGET=ui_pch +PROJECTPCHSOURCE=..\pch\ui_pch + +AUTOSEG=true + +# --- Settings ----------------------------------------------------- + +.INCLUDE : scpre.mk +.INCLUDE : settings.mk +.INCLUDE : sc.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +CXXFILES = \ + docsh.cxx \ + docsh2.cxx \ + docsh3.cxx \ + docsh4.cxx \ + docsh5.cxx \ + docsh6.cxx \ + docsh7.cxx \ + docsh8.cxx \ + tablink.cxx \ + arealink.cxx \ + dbdocfun.cxx \ + dbdocimp.cxx \ + impex.cxx \ + docfunc.cxx \ + olinefun.cxx \ + servobj.cxx \ + tpstat.cxx \ + autostyl.cxx \ + pagedata.cxx \ + hiranges.cxx \ + pntlock.cxx + + +SLOFILES = \ + $(SLO)$/docsh.obj \ + $(SLO)$/docsh2.obj \ + $(SLO)$/docsh3.obj \ + $(SLO)$/docsh4.obj \ + $(SLO)$/docsh5.obj \ + $(SLO)$/docsh6.obj \ + $(SLO)$/docsh7.obj \ + $(SLO)$/docsh8.obj \ + $(SLO)$/tablink.obj \ + $(SLO)$/arealink.obj \ + $(SLO)$/dbdocfun.obj \ + $(SLO)$/dbdocimp.obj \ + $(SLO)$/impex.obj \ + $(SLO)$/docfunc.obj \ + $(SLO)$/olinefun.obj \ + $(SLO)$/servobj.obj \ + $(SLO)$/tpstat.obj \ + $(SLO)$/autostyl.obj \ + $(SLO)$/pagedata.obj \ + $(SLO)$/hiranges.obj \ + $(SLO)$/pntlock.obj + + +EXCEPTIONSFILES= \ + $(SLO)$/dbdocimp.obj + + +SRCFILES = tpstat.src + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/sc/source/ui/docshell/olinefun.cxx b/sc/source/ui/docshell/olinefun.cxx new file mode 100644 index 000000000000..4a76585bc605 --- /dev/null +++ b/sc/source/ui/docshell/olinefun.cxx @@ -0,0 +1,764 @@ +/************************************************************************* + * + * $RCSfile: olinefun.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#pragma hdrstop + +// INCLUDE --------------------------------------------------------------- + +#include <vcl/sound.hxx> + +#include "olinefun.hxx" + +#include "docsh.hxx" +#include "olinetab.hxx" +#include "undodat.hxx" +#include "globstr.hrc" + + +//======================================================================== + +void lcl_InvalidateOutliner(); //! in dbfunc3 - hierher verschieben!!! + +//------------------------------------------------------------------------ + +//! PaintWidthHeight zur DocShell verschieben? + +void lcl_PaintWidthHeight( ScDocShell& rDocShell, USHORT nTab, + BOOL bColumns, USHORT nStart, USHORT nEnd ) +{ + ScDocument* pDoc = rDocShell.GetDocument(); + + USHORT nParts = PAINT_GRID; + USHORT nStartCol = 0; + USHORT nStartRow = 0; + USHORT nEndCol = MAXCOL; // fuer Test auf Merge + USHORT nEndRow = MAXROW; + if ( bColumns ) + { + nParts |= PAINT_TOP; + nStartCol = nStart; + nEndCol = nEnd; + } + else + { + nParts |= PAINT_LEFT; + nStartRow = nStart; + nEndRow = nEnd; + } + if (pDoc->HasAttrib( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab, + HASATTR_MERGED | HASATTR_OVERLAPPED )) + { + nStartCol = 0; + nStartRow = 0; + } + rDocShell.PostPaint( nStartCol,nStartRow,nTab, MAXCOL,MAXROW,nTab, nParts ); +} + +//------------------------------------------------------------------------ + +BOOL ScOutlineDocFunc::MakeOutline( const ScRange& rRange, BOOL bColumns, BOOL bRecord, BOOL bApi ) +{ + BOOL bSuccess = FALSE; + USHORT nStartCol = rRange.aStart.Col(); + USHORT nStartRow = rRange.aStart.Row(); + USHORT nEndCol = rRange.aEnd.Col(); + USHORT nEndRow = rRange.aEnd.Row(); + USHORT nTab = rRange.aStart.Tab(); + + ScDocument* pDoc = rDocShell.GetDocument(); + ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab, TRUE ); + ScOutlineTable* pUndoTab = NULL; + + if (bRecord) + pUndoTab = new ScOutlineTable( *pTable ); + + ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray(); + + BOOL bRes; + BOOL bSize = FALSE; + if ( bColumns ) + bRes = pArray->Insert( nStartCol, nEndCol, bSize ); + else + bRes = pArray->Insert( nStartRow, nEndRow, bSize ); + + if ( bRes ) + { + if (bRecord) + { + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoMakeOutline( &rDocShell, + nStartCol,nStartRow,nTab,nEndCol,nEndRow,nTab, + pUndoTab, bColumns, TRUE ) ); + } + + USHORT nParts = 0; // Datenbereich nicht geaendert + if ( bColumns ) + nParts |= PAINT_TOP; + else + nParts |= PAINT_LEFT; + if ( bSize ) + nParts |= PAINT_SIZE; + + rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, nParts ); + rDocShell.SetDocumentModified(); + lcl_InvalidateOutliner(); + bSuccess = TRUE; + } + else + { + if (!bApi) + rDocShell.ErrorMessage(STR_MSSG_MAKEOUTLINE_0); // "Gruppierung nicht moeglich" + delete pUndoTab; + } + + return bSuccess; +} + +BOOL ScOutlineDocFunc::RemoveOutline( const ScRange& rRange, BOOL bColumns, BOOL bRecord, BOOL bApi ) +{ + BOOL bDone = FALSE; + + USHORT nStartCol = rRange.aStart.Col(); + USHORT nStartRow = rRange.aStart.Row(); + USHORT nEndCol = rRange.aEnd.Col(); + USHORT nEndRow = rRange.aEnd.Row(); + USHORT nTab = rRange.aStart.Tab(); + + ScDocument* pDoc = rDocShell.GetDocument(); + ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab ); + if (pTable) + { + ScOutlineTable* pUndoTab = NULL; + if (bRecord) + pUndoTab = new ScOutlineTable( *pTable ); + + ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray(); + + BOOL bRes; + BOOL bSize = FALSE; + if ( bColumns ) + bRes = pArray->Remove( nStartCol, nEndCol, bSize ); + else + bRes = pArray->Remove( nStartRow, nEndRow, bSize ); + + if ( bRes ) + { + if (bRecord) + { + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoMakeOutline( &rDocShell, + nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab, + pUndoTab, bColumns, FALSE ) ); + } + + USHORT nParts = 0; // Datenbereich nicht geaendert + if ( bColumns ) + nParts |= PAINT_TOP; + else + nParts |= PAINT_LEFT; + if ( bSize ) + nParts |= PAINT_SIZE; + + rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, nParts ); + rDocShell.SetDocumentModified(); + bDone = TRUE; + lcl_InvalidateOutliner(); + + // es wird nicht wieder eingeblendet -> kein UpdatePageBreaks + } + else + delete pUndoTab; + } + + if (!bDone && !bApi) + rDocShell.ErrorMessage(STR_MSSG_REMOVEOUTLINE_0); // "Aufheben nicht moeglich" + + return bDone; +} + +BOOL ScOutlineDocFunc::RemoveAllOutlines( USHORT nTab, BOOL bRecord, BOOL bApi ) +{ + BOOL bSuccess = FALSE; + ScDocument* pDoc = rDocShell.GetDocument(); + ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab ); + if (pTable) + { + USHORT nStartCol; + USHORT nStartRow; + USHORT nEndCol; + USHORT nEndRow; + pTable->GetColArray()->GetRange( nStartCol, nEndCol ); + pTable->GetRowArray()->GetRange( nStartRow, nEndRow ); + + if (bRecord) + { + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE ); + pDoc->CopyToDocument( nStartCol, 0, nTab, nEndCol, MAXROW, nTab, IDF_NONE, FALSE, pUndoDoc ); + pDoc->CopyToDocument( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab, IDF_NONE, FALSE, pUndoDoc ); + + ScOutlineTable* pUndoTab = new ScOutlineTable( *pTable ); + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoRemoveAllOutlines( &rDocShell, + nStartCol, nStartRow, nTab, + nEndCol, nEndRow, nTab, + pUndoDoc, pUndoTab ) ); + } + + SelectLevel( nTab, TRUE, pTable->GetColArray()->GetDepth(), FALSE, FALSE, bApi ); + SelectLevel( nTab, FALSE, pTable->GetRowArray()->GetDepth(), FALSE, FALSE, bApi ); + pDoc->SetOutlineTable( nTab, NULL ); + + pDoc->UpdatePageBreaks( nTab ); + + rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, + PAINT_GRID | PAINT_LEFT | PAINT_TOP | PAINT_SIZE ); + rDocShell.SetDocumentModified(); + lcl_InvalidateOutliner(); + bSuccess = TRUE; + } + else if (!bApi) + Sound::Beep(); + + return bSuccess; +} + +//------------------------------------------------------------------------ + +BOOL ScOutlineDocFunc::AutoOutline( const ScRange& rRange, BOOL bRecord, BOOL bApi ) +{ + USHORT nStartCol = rRange.aStart.Col(); + USHORT nStartRow = rRange.aStart.Row(); + USHORT nEndCol = rRange.aEnd.Col(); + USHORT nEndRow = rRange.aEnd.Row(); + USHORT nTab = rRange.aStart.Tab(); + + ScDocument* pDoc = rDocShell.GetDocument(); + ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab ); + + ScDocument* pUndoDoc = NULL; + ScOutlineTable* pUndoTab = NULL; + + if ( pTable ) + { + if ( bRecord ) + { + pUndoTab = new ScOutlineTable( *pTable ); + + USHORT nOutStartCol; + USHORT nOutStartRow; + USHORT nOutEndCol; + USHORT nOutEndRow; + pTable->GetColArray()->GetRange( nOutStartCol, nOutEndCol ); + pTable->GetRowArray()->GetRange( nOutStartRow, nOutEndRow ); + + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE ); + pDoc->CopyToDocument( nOutStartCol, 0, nTab, nOutEndCol, MAXROW, nTab, IDF_NONE, FALSE, pUndoDoc ); + pDoc->CopyToDocument( 0, nOutStartRow, nTab, MAXCOL, nOutEndRow, nTab, IDF_NONE, FALSE, pUndoDoc ); + } + + // einblenden + SelectLevel( nTab, TRUE, pTable->GetColArray()->GetDepth(), FALSE, FALSE, bApi ); + SelectLevel( nTab, FALSE, pTable->GetRowArray()->GetDepth(), FALSE, FALSE, bApi ); + pDoc->SetOutlineTable( nTab, NULL ); + } + + pDoc->DoAutoOutline( nStartCol,nStartRow, nEndCol,nEndRow, nTab ); + + if (bRecord) + { + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoAutoOutline( &rDocShell, + nStartCol, nStartRow, nTab, + nEndCol, nEndRow, nTab, + pUndoDoc, pUndoTab ) ); + } + + rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_LEFT | PAINT_TOP | PAINT_SIZE ); + rDocShell.SetDocumentModified(); + lcl_InvalidateOutliner(); + + return TRUE; +} + +//------------------------------------------------------------------------ + +BOOL ScOutlineDocFunc::SelectLevel( USHORT nTab, BOOL bColumns, USHORT nLevel, + BOOL bRecord, BOOL bPaint, BOOL bApi ) +{ + ScDocument* pDoc = rDocShell.GetDocument(); + ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab ); // ist schon da + if (!pTable) + return FALSE; + ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray(); + if (!pArray) + return FALSE; + + USHORT nStart; + USHORT nEnd; + pArray->GetRange( nStart, nEnd ); + + if ( bRecord ) + { + ScOutlineTable* pUndoTab = new ScOutlineTable( *pTable ); + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + if (bColumns) + { + pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, FALSE ); + pDoc->CopyToDocument( nStart, 0, nTab, nEnd, MAXROW, nTab, IDF_NONE, FALSE, pUndoDoc ); + } + else + { + pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, TRUE ); + pDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, FALSE, pUndoDoc ); + } + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoOutlineLevel( &rDocShell, + nStart, nEnd, nTab, //! start und end berechnen + pUndoDoc, pUndoTab, + bColumns, nLevel ) ); + } + + ScSubOutlineIterator aIter( pArray ); // alle Eintraege + ScOutlineEntry* pEntry; + while ((pEntry=aIter.GetNext()) != NULL) + { + USHORT nThisLevel = aIter.LastLevel(); + BOOL bShow = (nThisLevel < nLevel); + if (bShow) // einblenden + { + pEntry->SetHidden( FALSE ); + pEntry->SetVisible( TRUE ); + } + else if ( nThisLevel == nLevel ) // ausblenden + { + pEntry->SetHidden( TRUE ); + pEntry->SetVisible( TRUE ); + } + else // verdeckt + { + pEntry->SetVisible( FALSE ); + } + + USHORT nThisStart = pEntry->GetStart(); + USHORT nThisEnd = pEntry->GetEnd(); + for (USHORT i=nThisStart; i<=nThisEnd; i++) + { + if ( bColumns ) + pDoc->ShowCol( i, nTab, bShow ); + else + if ( !bShow || !pDoc->IsFiltered( i,nTab ) ) + pDoc->ShowRow( i, nTab, bShow ); + } + } + + pDoc->UpdatePageBreaks( nTab ); + + if (bPaint) + lcl_PaintWidthHeight( rDocShell, nTab, bColumns, nStart, nEnd ); + + rDocShell.SetDocumentModified(); + lcl_InvalidateOutliner(); + + return TRUE; +} + +//------------------------------------------------------------------------ + +BOOL ScOutlineDocFunc::ShowMarkedOutlines( const ScRange& rRange, BOOL bRecord, BOOL bApi ) +{ + BOOL bDone = FALSE; + + USHORT nStartCol = rRange.aStart.Col(); + USHORT nStartRow = rRange.aStart.Row(); + USHORT nEndCol = rRange.aEnd.Col(); + USHORT nEndRow = rRange.aEnd.Row(); + USHORT nTab = rRange.aStart.Tab(); + + ScDocument* pDoc = rDocShell.GetDocument(); + ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab ); + + if (pTable) + { + ScOutlineArray* pArray; + ScOutlineEntry* pEntry; + USHORT nStart; + USHORT nEnd; + USHORT nMin; + USHORT nMax; + USHORT i; + + if ( bRecord ) + { + ScOutlineTable* pUndoTab = new ScOutlineTable( *pTable ); + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE ); + pDoc->CopyToDocument( nStartCol, 0, nTab, nEndCol, MAXROW, nTab, IDF_NONE, FALSE, pUndoDoc ); + pDoc->CopyToDocument( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab, IDF_NONE, FALSE, pUndoDoc ); + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoOutlineBlock( &rDocShell, + nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab, + pUndoDoc, pUndoTab, TRUE ) ); + } + + // Spalten + + nMin=MAXCOL; + nMax=0; + pArray = pTable->GetColArray(); + ScSubOutlineIterator aColIter( pArray ); + while ((pEntry=aColIter.GetNext()) != NULL) + { + nStart = pEntry->GetStart(); + nEnd = pEntry->GetEnd(); + if ( nStart>=nStartCol && nEnd<=nEndCol ) + { + pEntry->SetHidden( FALSE ); + pEntry->SetVisible( TRUE ); + if (nStart<nMin) nMin=nStart; + if (nEnd>nMax) nMax=nEnd; + } + } + for ( i=nMin; i<=nMax; i++ ) + pDoc->ShowCol( i, nTab, TRUE ); + + // Zeilen + + nMin=MAXROW; + nMax=0; + pArray = pTable->GetRowArray(); + ScSubOutlineIterator aRowIter( pArray ); + while ((pEntry=aRowIter.GetNext()) != NULL) + { + nStart = pEntry->GetStart(); + nEnd = pEntry->GetEnd(); + if ( nStart>=nStartRow && nEnd<=nEndRow ) + { + pEntry->SetHidden( FALSE ); + pEntry->SetVisible( TRUE ); + if (nStart<nMin) nMin=nStart; + if (nEnd>nMax) nMax=nEnd; + } + } + for ( i=nMin; i<=nMax; i++ ) + if ( !pDoc->IsFiltered( i,nTab ) ) // weggefilterte nicht einblenden + pDoc->ShowRow( i, nTab, TRUE ); + + pDoc->UpdatePageBreaks( nTab ); + + rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_LEFT | PAINT_TOP ); + + rDocShell.SetDocumentModified(); + bDone = TRUE; + + lcl_InvalidateOutliner(); + } + + if (!bDone && !bApi) + Sound::Beep(); + + return bDone; +} + +BOOL ScOutlineDocFunc::HideMarkedOutlines( const ScRange& rRange, BOOL bRecord, BOOL bApi ) +{ + BOOL bDone = FALSE; + + USHORT nStartCol = rRange.aStart.Col(); + USHORT nStartRow = rRange.aStart.Row(); + USHORT nEndCol = rRange.aEnd.Col(); + USHORT nEndRow = rRange.aEnd.Row(); + USHORT nTab = rRange.aStart.Tab(); + + ScDocument* pDoc = rDocShell.GetDocument(); + ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab ); + + if (pTable) + { + ScOutlineEntry* pEntry; + USHORT nColLevel; + USHORT nRowLevel; + USHORT nCount; + USHORT nStart; + USHORT nEnd; + USHORT i; + + USHORT nEffStartCol = nStartCol; + USHORT nEffEndCol = nEndCol; + ScOutlineArray* pColArray = pTable->GetColArray(); + pColArray->FindTouchedLevel( nStartCol, nEndCol, nColLevel ); + pColArray->ExtendBlock( nColLevel, nEffStartCol, nEffEndCol ); + USHORT nEffStartRow = nStartRow; + USHORT nEffEndRow = nEndRow; + ScOutlineArray* pRowArray = pTable->GetRowArray(); + pRowArray->FindTouchedLevel( nStartRow, nEndRow, nRowLevel ); + pRowArray->ExtendBlock( nRowLevel, nEffStartRow, nEffEndRow ); + + if ( bRecord ) + { + ScOutlineTable* pUndoTab = new ScOutlineTable( *pTable ); + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE ); + pDoc->CopyToDocument( nEffStartCol, 0, nTab, nEffEndCol, MAXROW, nTab, IDF_NONE, FALSE, pUndoDoc ); + pDoc->CopyToDocument( 0, nEffStartRow, nTab, MAXCOL, nEffEndRow, nTab, IDF_NONE, FALSE, pUndoDoc ); + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoOutlineBlock( &rDocShell, + nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab, + pUndoDoc, pUndoTab, FALSE ) ); + } + + // Spalten + + nCount = pColArray->GetCount(nColLevel); + for ( i=0; i<nCount; i++ ) + { + pEntry = pColArray->GetEntry(nColLevel,i); + nStart = pEntry->GetStart(); + nEnd = pEntry->GetEnd(); + + if ( nStartCol<=nEnd && nEndCol>=nStart ) + HideOutline( nTab, TRUE, nColLevel, i, FALSE, FALSE, bApi ); + } + + // Zeilen + + nCount = pRowArray->GetCount(nRowLevel); + for ( i=0; i<nCount; i++ ) + { + pEntry = pRowArray->GetEntry(nRowLevel,i); + nStart = pEntry->GetStart(); + nEnd = pEntry->GetEnd(); + + if ( nStartRow<=nEnd && nEndRow>=nStart ) + HideOutline( nTab, FALSE, nRowLevel, i, FALSE, FALSE, bApi ); + } + + pDoc->UpdatePageBreaks( nTab ); + + rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_LEFT | PAINT_TOP ); + + rDocShell.SetDocumentModified(); + bDone = TRUE; + + lcl_InvalidateOutliner(); + } + + if (!bDone && !bApi) + Sound::Beep(); + + return bDone; +} + +//------------------------------------------------------------------------ + +BOOL ScOutlineDocFunc::ShowOutline( USHORT nTab, BOOL bColumns, USHORT nLevel, USHORT nEntry, + BOOL bRecord, BOOL bPaint, BOOL bApi ) +{ + ScDocument* pDoc = rDocShell.GetDocument(); + + ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab ); + ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray(); + ScOutlineEntry* pEntry = pArray->GetEntry( nLevel, nEntry ); + USHORT nStart = pEntry->GetStart(); + USHORT nEnd = pEntry->GetEnd(); + + if ( bRecord ) + { + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + if (bColumns) + { + pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, FALSE ); + pDoc->CopyToDocument( nStart, 0, nTab, nEnd, MAXROW, nTab, IDF_NONE, FALSE, pUndoDoc ); + } + else + { + pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, TRUE ); + pDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, FALSE, pUndoDoc ); + } + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoDoOutline( &rDocShell, + nStart, nEnd, nTab, pUndoDoc, //! start und end berechnen + bColumns, nLevel, nEntry, TRUE ) ); + } + +//! HideCursor(); + + pEntry->SetHidden(FALSE); + USHORT i; + for ( i = nStart; i <= nEnd; i++ ) + { + if ( bColumns ) + pDoc->ShowCol( i, nTab, TRUE ); + else + if ( !pDoc->IsFiltered( i,nTab ) ) // weggefilterte nicht einblenden + pDoc->ShowRow( i, nTab, TRUE ); + } + + ScSubOutlineIterator aIter( pArray, nLevel, nEntry ); + while ((pEntry=aIter.GetNext()) != NULL) + { + if ( pEntry->IsHidden() ) + { + USHORT nSubStart = pEntry->GetStart(); + USHORT nSubEnd = pEntry->GetEnd(); + for ( i = nSubStart; i <= nSubEnd; i++ ) + { + if ( bColumns ) + pDoc->ShowCol( i, nTab, FALSE ); + else + pDoc->ShowRow( i, nTab, FALSE ); + } + } + } + + pArray->SetVisibleBelow( nLevel, nEntry, TRUE, TRUE ); + + pDoc->UpdatePageBreaks( nTab ); + + if (bPaint) + lcl_PaintWidthHeight( rDocShell, nTab, bColumns, nStart, nEnd ); + +//! ShowCursor(); + rDocShell.SetDocumentModified(); + +//! if (bPaint) +//! UpdateScrollBars(); + + lcl_InvalidateOutliner(); + + return TRUE; //! immer ??? +} + +BOOL ScOutlineDocFunc::HideOutline( USHORT nTab, BOOL bColumns, USHORT nLevel, USHORT nEntry, + BOOL bRecord, BOOL bPaint, BOOL bApi ) +{ + ScDocument* pDoc = rDocShell.GetDocument(); + + ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab ); + ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray(); + ScOutlineEntry* pEntry = pArray->GetEntry( nLevel, nEntry ); + USHORT nStart = pEntry->GetStart(); + USHORT nEnd = pEntry->GetEnd(); + + if ( bRecord ) + { + ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + if (bColumns) + { + pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, FALSE ); + pDoc->CopyToDocument( nStart, 0, nTab, nEnd, MAXROW, nTab, IDF_NONE, FALSE, pUndoDoc ); + } + else + { + pUndoDoc->InitUndo( pDoc, nTab, nTab, FALSE, TRUE ); + pDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, FALSE, pUndoDoc ); + } + + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoDoOutline( &rDocShell, + nStart, nEnd, nTab, pUndoDoc, + bColumns, nLevel, nEntry, FALSE ) ); + } + +//! HideCursor(); + + pEntry->SetHidden(TRUE); + USHORT i; + for ( i = nStart; i <= nEnd; i++ ) + { + if ( bColumns ) + pDoc->ShowCol( i, nTab, FALSE ); + else + pDoc->ShowRow( i, nTab, FALSE ); + } + + pArray->SetVisibleBelow( nLevel, nEntry, FALSE ); + + pDoc->UpdatePageBreaks( nTab ); + + if (bPaint) + lcl_PaintWidthHeight( rDocShell, nTab, bColumns, nStart, nEnd ); + +//! ShowCursor(); + rDocShell.SetDocumentModified(); + +//! if (bPaint) +//! UpdateScrollBars(); + + lcl_InvalidateOutliner(); + + return TRUE; //! immer ??? +} + + + + + diff --git a/sc/source/ui/docshell/pagedata.cxx b/sc/source/ui/docshell/pagedata.cxx new file mode 100644 index 000000000000..c0a3b6e99101 --- /dev/null +++ b/sc/source/ui/docshell/pagedata.cxx @@ -0,0 +1,180 @@ +/************************************************************************* + * + * $RCSfile: pagedata.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#include <string.h> + +#ifndef _DEBUG_HXX //autogen +#include <tools/debug.hxx> +#endif + +#pragma hdrstop + +#ifndef PCH +#include "segmentc.hxx" +#endif + +#include "pagedata.hxx" + +//============================================================================ + +ScPrintRangeData::ScPrintRangeData() +{ + nPagesX = nPagesY = 0; + pPageEndX = pPageEndY = NULL; + bTopDown = bAutomatic = TRUE; + nFirstPage = 1; +} + +ScPrintRangeData::~ScPrintRangeData() +{ + delete[] pPageEndX; + delete[] pPageEndY; +} + +void ScPrintRangeData::SetPagesX( USHORT nCount, const USHORT* pData ) +{ + delete[] pPageEndX; + if ( nCount ) + { + pPageEndX = new USHORT[nCount]; + memcpy( pPageEndX, pData, nCount * sizeof(USHORT) ); + } + else + pPageEndX = NULL; + nPagesX = nCount; +} + +void ScPrintRangeData::SetPagesY( USHORT nCount, const USHORT* pData ) +{ + delete[] pPageEndY; + if ( nCount ) + { + pPageEndY = new USHORT[nCount]; + memcpy( pPageEndY, pData, nCount * sizeof(USHORT) ); + } + else + pPageEndY = NULL; + nPagesY = nCount; +} + +//============================================================================ + +ScPageBreakData::ScPageBreakData(USHORT nMax) +{ + nUsed = 0; + if (nMax) + pData = new ScPrintRangeData[nMax]; + else + pData = NULL; + nAlloc = nMax; +} + +ScPageBreakData::~ScPageBreakData() +{ + delete[] pData; +} + +ScPrintRangeData& ScPageBreakData::GetData(USHORT nPos) +{ + DBG_ASSERT(nPos < nAlloc, "ScPageBreakData::GetData bumm"); + + if ( nPos >= nUsed ) + { + DBG_ASSERT(nPos == nUsed, "ScPageBreakData::GetData falsche Reihenfolge"); + nUsed = nPos+1; + } + + return pData[nPos]; +} + +BOOL ScPageBreakData::IsEqual( const ScPageBreakData& rOther ) const +{ + if ( nUsed != rOther.nUsed ) + return FALSE; + + for (USHORT i=0; i<nUsed; i++) + if ( pData[i].GetPrintRange() != rOther.pData[i].GetPrintRange() ) + return FALSE; + + //! ScPrintRangeData komplett vergleichen ?? + + return TRUE; +} + +void ScPageBreakData::AddPages() +{ + if ( nUsed > 1 ) + { + long nPage = pData[0].GetFirstPage(); + for (USHORT i=0; i+1<nUsed; i++) + { + nPage += ((long)pData[i].GetPagesX())*pData[i].GetPagesY(); + pData[i+1].SetFirstPage( nPage ); + } + } +} + + + diff --git a/sc/source/ui/docshell/pntlock.cxx b/sc/source/ui/docshell/pntlock.cxx new file mode 100644 index 000000000000..c8e9262e4a17 --- /dev/null +++ b/sc/source/ui/docshell/pntlock.cxx @@ -0,0 +1,95 @@ +/************************************************************************* + * + * $RCSfile: pntlock.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#pragma hdrstop + +#include "pntlock.hxx" + +//------------------------------------------------------------------------ + +ScPaintLockData::ScPaintLockData(USHORT nNewMode) : + nMode( nNewMode ), + nParts( 0 ), + nLevel( 0 ), + bModified( FALSE ) +{ +} + +ScPaintLockData::~ScPaintLockData() +{ +} + +void ScPaintLockData::AddRange( const ScRange& rRange, USHORT nP ) +{ + if (!xRangeList.Is()) + xRangeList = new ScRangeList; + + xRangeList->Join( rRange ); + nParts |= nP; +} + + + + diff --git a/sc/source/ui/docshell/servobj.cxx b/sc/source/ui/docshell/servobj.cxx new file mode 100644 index 000000000000..f2a8912caaba --- /dev/null +++ b/sc/source/ui/docshell/servobj.cxx @@ -0,0 +1,285 @@ +/************************************************************************* + * + * $RCSfile: servobj.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +// System - Includes ----------------------------------------------------- + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#pragma hdrstop + +#include <sot/formats.hxx> +#include <sfx2/app.hxx> +#include <svx/linkmgr.hxx> +#include "servobj.hxx" +#include "docsh.hxx" +#include "impex.hxx" +#include "brdcst.hxx" +#include "rangenam.hxx" +#include "sc.hrc" // SC_HINT_AREAS_CHANGED + +// ----------------------------------------------------------------------- + +BOOL lcl_FillRangeFromName( ScRange& rRange, ScDocShell* pDocSh, const String& rName ) +{ + if (pDocSh) + { + ScDocument* pDoc = pDocSh->GetDocument(); + ScRangeName* pNames = pDoc->GetRangeName(); + if (pNames) + { + USHORT nPos; + if( pNames->SearchName( rName, nPos ) ) + { + ScRangeData* pData = (*pNames)[ nPos ]; + if ( pData->IsReference( rRange ) ) + return TRUE; + } + } + } + return FALSE; +} + +ScServerObject::ScServerObject( ScDocShell* pShell, const String& rItem ) : + pDocSh( pShell ), + bRefreshListener( FALSE ) +{ + // parse item string + + if ( lcl_FillRangeFromName( aRange, pDocSh, rItem ) ) + { + aItemStr = rItem; // must be parsed again on ref update + } + else + { + // parse ref + ScDocument* pDoc = pDocSh->GetDocument(); + USHORT nTab = pDocSh->GetCurTab(); + aRange.aStart.SetTab( nTab ); + + if ( aRange.Parse( rItem, pDoc ) & SCA_VALID ) + { + // area reference + } + else if ( aRange.aStart.Parse( rItem, pDoc ) & SCA_VALID ) + { + // cell reference + aRange.aEnd = aRange.aStart; + } + else + { + DBG_ERROR("ScServerObject: invalid item"); + } + } + + pDocSh->GetDocument()->GetLinkManager()->InsertServer( this ); + pDocSh->GetDocument()->StartListeningArea( aRange, this ); + + StartListening(*pDocSh); // um mitzubekommen, wenn die DocShell geloescht wird + StartListening(*SFX_APP()); // for SC_HINT_AREAS_CHANGED +} + +__EXPORT ScServerObject::~ScServerObject() +{ + Clear(); +} + +void ScServerObject::Clear() +{ + if (pDocSh) + { + ScDocShell* pTemp = pDocSh; + pDocSh = NULL; + + pTemp->GetDocument()->EndListeningArea( aRange, this ); + pTemp->GetDocument()->GetLinkManager()->RemoveServer( this ); + EndListening(*pTemp); + EndListening(*SFX_APP()); + } +} + +BOOL __EXPORT ScServerObject::GetData( SvData* pData ) // wie ScDocShell::DdeGetData +{ + if (!pDocSh) + return FALSE; + + // named ranges may have changed -> update aRange + if ( aItemStr.Len() ) + { + ScRange aNew; + if ( lcl_FillRangeFromName( aNew, pDocSh, aItemStr ) && aNew != aRange ) + { + aRange = aNew; + bRefreshListener = TRUE; + } + } + + if ( bRefreshListener ) + { + // refresh the listeners now (this is called from a timer) + + EndListeningAll(); + pDocSh->GetDocument()->StartListeningArea( aRange, this ); + StartListening(*pDocSh); + StartListening(*SFX_APP()); + bRefreshListener = FALSE; + } + + String aDdeTextFmt = pDocSh->GetDdeTextFmt(); + ScDocument* pDoc = pDocSh->GetDocument(); + + if( pData->GetFormat() == FORMAT_STRING ) + { + ScImportExport aObj( pDoc, aRange ); + if( aDdeTextFmt.GetChar(0) == 'F' ) + aObj.SetFormulas( TRUE ); + if( aDdeTextFmt.EqualsAscii( "SYLK" ) || aDdeTextFmt.EqualsAscii( "FSYLK" ) ) + { + String aData; + if( aObj.ExportString( aData, SOT_FORMATSTR_ID_SYLK ) ) + { + ByteString aByteData( aData, gsl_getSystemTextEncoding() ); + pData->SetData( (void*) aByteData.GetBuffer(), aByteData.Len() + 1 ); + return 1; + } + else + return 0; + } + if( aDdeTextFmt.EqualsAscii( "CSV" ) || aDdeTextFmt.EqualsAscii( "FCSV" ) ) + aObj.SetSeparator( ',' ); + return aObj.ExportData( *pData ) ? 1 : 0; + } + ScImportExport aObj( pDoc, aRange ); + if( aObj.IsRef() ) + return aObj.ExportData( *pData ) ? 1 : 0; + else + return 0; +} + +BOOL __EXPORT ScServerObject::SetData( SvData& ) +{ + // erstmal nicht + return FALSE; +} + +void __EXPORT ScServerObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType, + const SfxHint& rHint, const TypeId& rHintType ) +{ + BOOL bDataChanged = FALSE; + + if (rBC.ISA(ScDocShell)) + { + // from DocShell, only SFX_HINT_DYING is interesting + if ( rHint.ISA(SfxSimpleHint) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) + Clear(); + } + else if (rBC.ISA(SfxApplication)) + { + if ( aItemStr.Len() && rHint.ISA(SfxSimpleHint) && + ((const SfxSimpleHint&)rHint).GetId() == SC_HINT_AREAS_CHANGED ) + { + // check if named range was modified + ScRange aNew; + if ( lcl_FillRangeFromName( aNew, pDocSh, aItemStr ) && aNew != aRange ) + bDataChanged = TRUE; + } + } + else + { + // must be from Area broadcasters + + const ScHint* pScHint = PTR_CAST( ScHint, &rHint ); + if( pScHint && (pScHint->GetId() & (SC_HINT_DATACHANGED | SC_HINT_DYING)) ) + bDataChanged = TRUE; + else if (rHint.ISA(ScAreaChangedHint)) // position of broadcaster changed + { + ScRange aNewRange = ((const ScAreaChangedHint&)rHint).GetRange(); + if ( aRange != aNewRange ) + { + bRefreshListener = TRUE; + bDataChanged = TRUE; + } + } + else if (rHint.ISA(SfxSimpleHint)) + { + USHORT nId = ((const SfxSimpleHint&)rHint).GetId(); + if (nId == SFX_HINT_DYING) + { + // If the range is being deleted, listening must be restarted + // after the deletion is complete (done in GetData) + bRefreshListener = TRUE; + bDataChanged = TRUE; + } + } + } + + if ( bDataChanged && GetSelectorCount() ) + { + SvData aSvData; + DataChanged( aSvData ); + } +} + + + + + diff --git a/sc/source/ui/docshell/tablink.cxx b/sc/source/ui/docshell/tablink.cxx new file mode 100644 index 000000000000..bbf806d9e745 --- /dev/null +++ b/sc/source/ui/docshell/tablink.cxx @@ -0,0 +1,496 @@ +/************************************************************************* + * + * $RCSfile: tablink.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef WNT +#pragma optimize("",off) +#endif + +//------------------------------------------------------------------ + +#ifdef PCH +#include "core_pch.hxx" +#endif + +#pragma hdrstop + +// INCLUDE --------------------------------------------------------- + +#include <sfx2/app.hxx> +#include <svtools/itemset.hxx> +#include <svtools/stritem.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/docfilt.hxx> +#include <sfx2/fcontnr.hxx> +#include <svx/linkmgr.hxx> +#include <tools/urlobj.hxx> + +#include "tablink.hxx" + +#include "scextopt.hxx" +#include "table.hxx" +#include "document.hxx" +#include "docsh.hxx" +#include "globstr.hrc" +#include "undoblk.hxx" +#include "undotab.hxx" +#include "global.hxx" +#include "hints.hxx" + +TYPEINIT1(ScTableLink,SvBaseLink); + +//------------------------------------------------------------------------ + +ScTableLink::ScTableLink(ScDocShell* pDocSh, const String& rFile, + const String& rFilter, const String& rOpt): + SvBaseLink(LINKUPDATE_ONCALL,FORMAT_FILE), + pDocShell(pDocSh), + aFileName(rFile), + aFilterName(rFilter), + aOptions(rOpt), + bInCreate( FALSE ), + bAddUndo( TRUE ), + bDoPaint( TRUE ) +{ +} + +ScTableLink::ScTableLink(SfxObjectShell* pShell, const String& rFile, + const String& rFilter, const String& rOpt): + SvBaseLink(LINKUPDATE_ONCALL,FORMAT_FILE), + pDocShell((ScDocShell*)pShell), + aFileName(rFile), + aFilterName(rFilter), + aOptions(rOpt), + bInCreate( FALSE ), + bAddUndo( TRUE ), + bDoPaint( TRUE ) +{ +} + +__EXPORT ScTableLink::~ScTableLink() +{ + // Verbindung aufheben + + String aEmpty; + ScDocument* pDoc = pDocShell->GetDocument(); + USHORT nCount = pDoc->GetTableCount(); + for (USHORT nTab=0; nTab<nCount; nTab++) + if (pDoc->IsLinked(nTab) && pDoc->GetLinkDoc(nTab)==aFileName) + pDoc->SetLink( nTab, SC_LINK_NONE, aEmpty, aEmpty, aEmpty, aEmpty ); +} + +BOOL __EXPORT ScTableLink::Edit(Window* pParent) +{ + // DefModalDialogParent setzen, weil evtl. aus der DocShell beim ConvertFrom + // ein Optionen-Dialog kommt... + + Window* pOldParent = Application::GetDefDialogParent(); + if (pParent) + Application::SetDefDialogParent(pParent); + + BOOL bRet = SvBaseLink::Edit(pParent); + + Application::SetDefDialogParent(pOldParent); + + return bRet; +} + +void __EXPORT ScTableLink::DataChanged(SvData& rData) +{ + SvxLinkManager* pLinkManager=pDocShell->GetDocument()->GetLinkManager(); + if (pLinkManager!=NULL) + { + String aFile; + String aFilter; + pLinkManager->GetDisplayNames(*this,0,&aFile,NULL,&aFilter); + + // aus dem Dialog kommt der Filtername mit Applikation davor + //! soll das so sein ??!?! + String aAppPrefix = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( STRING_SCAPP )); + aAppPrefix.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ": " )); + xub_StrLen nPreLen = aAppPrefix.Len(); + if ( aFilter.Copy(0,nPreLen) == aAppPrefix ) + aFilter.Erase(0,nPreLen); + + if (!bInCreate) + Refresh(aFile,aFilter); // nicht doppelt laden! + } +} + +void __EXPORT ScTableLink::Closed() +{ + // Verknuepfung loeschen: Undo + + if (bAddUndo) + { + pDocShell->GetUndoManager()->AddUndoAction( + new ScUndoRemoveLink( pDocShell, aFileName ) ); + + bAddUndo = FALSE; // nur einmal + } + + // Verbindung wird im dtor aufgehoben + + SvBaseLink::Closed(); +} + +BOOL ScTableLink::IsUsed() const +{ + return pDocShell->GetDocument()->HasLink( aFileName, aFilterName, aOptions ); +} + +BOOL ScTableLink::Refresh(const String& rNewFile, const String& rNewFilter, + const String* pNewOptions) +{ + // Dokument laden + + if (!rNewFile.Len() || !rNewFilter.Len()) + return FALSE; + + String aNewUrl( ScGlobal::GetAbsDocName( rNewFile, pDocShell ) ); + BOOL bNewUrlName = (aNewUrl != aFileName); + + const SfxFilter* pFilter = SFX_APP()->GetFilter( pDocShell->GetFactory(), rNewFilter ); + if (!pFilter) + return FALSE; + + ScDocument* pDoc = pDocShell->GetDocument(); + pDoc->SetInLinkUpdate( TRUE ); + + // wenn neuer Filter ausgewaehlt wurde, Optionen vergessen + if ( rNewFilter != aFilterName ) + aOptions.Erase(); + if ( pNewOptions ) // Optionen hart angegeben? + aOptions = *pNewOptions; + + // ItemSet immer anlegen, damit die DocShell die Optionen setzen kann + SfxItemSet* pSet = new SfxAllItemSet( SFX_APP()->GetPool() ); + if ( aOptions.Len() ) + pSet->Put( SfxStringItem( SID_FILE_FILTEROPTIONS, aOptions ) ); + + SfxMedium* pMed = new SfxMedium(aNewUrl, STREAM_STD_READ, FALSE, TRUE, pFilter, pSet); + + ScDocShell* pSrcShell = new ScDocShell(SFX_CREATE_MODE_INTERNAL); + SvEmbeddedObjectRef aRef = pSrcShell; + pSrcShell->DoLoad(pMed); + + // Optionen koennten gesetzt worden sein + String aNewOpt = ScDocumentLoader::GetOptions(*pMed); + if (!aNewOpt.Len()) + aNewOpt = aOptions; + + // Undo... + + ScDocument* pUndoDoc = NULL; + BOOL bFirst = TRUE; + if (bAddUndo) + pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); + + // Tabellen kopieren + + ScDocShellModificator aModificator( *pDocShell ); + + BOOL bNotFound = FALSE; + ScDocument* pSrcDoc = pSrcShell->GetDocument(); + + // #74835# from text filters that don't set the table name, + // use the one table regardless of link table name + BOOL bAutoTab = (pSrcDoc->GetTableCount() == 1) && + ScDocShell::HasAutomaticTableName( rNewFilter ); + + USHORT nCount = pDoc->GetTableCount(); + for (USHORT nTab=0; nTab<nCount; nTab++) + { + BYTE nMode = pDoc->GetLinkMode(nTab); + if (nMode && pDoc->GetLinkDoc(nTab)==aFileName) + { + String aTabName = pDoc->GetLinkTab(nTab); + + // Undo + + if (bAddUndo) + { + if (bFirst) + pUndoDoc->InitUndo( pDoc, nTab, nTab, TRUE, TRUE ); + else + pUndoDoc->AddUndoTab( nTab, nTab, TRUE, TRUE ); + bFirst = FALSE; + ScRange aRange(0,0,nTab,MAXCOL,MAXROW,nTab); + pDoc->CopyToDocument(aRange, IDF_ALL, FALSE, pUndoDoc); + pUndoDoc->TransferDrawPage( pDoc, nTab, nTab ); + pUndoDoc->SetLink( nTab, nMode, aFileName, aFilterName, aOptions, aTabName ); + } + + // Tabellenname einer ExtDocRef anpassen + + if ( bNewUrlName && nMode == SC_LINK_VALUE ) + { + String aName; + pDoc->GetName( nTab, aName ); + if ( ScGlobal::pScInternational->CompareEqual( + ScGlobal::GetDocTabName( aFileName, aTabName ), aName, + INTN_COMPARE_IGNORECASE ) ) + { + pDoc->RenameTab( nTab, + ScGlobal::GetDocTabName( aNewUrl, aTabName ), + FALSE, TRUE ); // kein RefUpdate, kein ValidTabName + } + } + + // kopieren + + USHORT nSrcTab = 0; + BOOL bFound = TRUE; // kein Tab-Name angegeben: immer die erste + if ( aTabName.Len() && !bAutoTab ) + bFound = pSrcDoc->GetTable( aTabName, nSrcTab ); + if (bFound) + pDoc->TransferTab( pSrcDoc, nSrcTab, nTab, FALSE, // nicht neu einfuegen + (nMode == SC_LINK_VALUE) ); // nur Werte? + else + { + pDoc->DeleteAreaTab( 0,0,MAXCOL,MAXROW, nTab, IDF_ALL ); +// pDoc->ClearDrawPage(nTab); + // Fehler eintragen + pDoc->SetString( 0,0,nTab, ScGlobal::GetRscString(STR_LINKERROR) ); + pDoc->SetString( 0,1,nTab, ScGlobal::GetRscString(STR_LINKERRORFILE) ); + pDoc->SetString( 1,1,nTab, aNewUrl ); + pDoc->SetString( 0,2,nTab, ScGlobal::GetRscString(STR_LINKERRORTAB) ); + pDoc->SetString( 1,2,nTab, aTabName ); + + bNotFound = TRUE; + } + + if ( bNewUrlName || rNewFilter != aFilterName || aNewOpt != aOptions || pNewOptions ) + pDoc->SetLink( nTab, nMode, aNewUrl, rNewFilter, aNewOpt, aTabName ); + } + } + + // neue Einstellungen merken + + if ( bNewUrlName ) + aFileName = aNewUrl; + if ( rNewFilter != aFilterName ) + aFilterName = rNewFilter; + if ( aNewOpt != aOptions ) + aOptions = aNewOpt; + + // aufraeumen + +// pSrcShell->DoClose(); + aRef->DoClose(); + + // Undo + + if (bAddUndo) + pDocShell->GetUndoManager()->AddUndoAction( + new ScUndoRefreshLink( pDocShell, pUndoDoc ) ); + + // Paint (koennen mehrere Tabellen sein) + + if (bDoPaint) + { + pDocShell->PostPaint( ScRange(0,0,0,MAXCOL,MAXROW,MAXTAB), + PAINT_GRID | PAINT_TOP | PAINT_LEFT ); + aModificator.SetDocumentModified(); + } + + if (bNotFound) + { + //! Fehler ausgeben ? + } + + pDoc->SetInLinkUpdate( FALSE ); + + // notify Uno objects (for XRefreshListener) + //! also notify Uno objects if file name was changed! + ScLinkRefreshedHint aHint; + aHint.SetSheetLink( aFileName ); + pDoc->BroadcastUno( aHint ); + + return TRUE; +} + +// === ScDocumentLoader ================================================== + +String ScDocumentLoader::GetOptions( SfxMedium& rMedium ) // static +{ + SfxItemSet* pSet = rMedium.GetItemSet(); + const SfxPoolItem* pItem; + if ( pSet && SFX_ITEM_SET == pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) ) + return ((const SfxStringItem*)pItem)->GetValue(); + + return EMPTY_STRING; +} + +void ScDocumentLoader::GetFilterName( const String& rFileName, + String& rFilter, String& rOptions ) // static +{ + TypeId aScType = TYPE(ScDocShell); + SfxObjectShell* pDocSh = SfxObjectShell::GetFirst( &aScType ); + while ( pDocSh ) + { + if ( pDocSh->HasName() ) + { + SfxMedium* pMed = pDocSh->GetMedium(); + if ( rFileName == pMed->GetName() ) + { + rFilter = pMed->GetFilter()->GetFilterName(); + rOptions = GetOptions(*pMed); + return; + } + } + pDocSh = SfxObjectShell::GetNext( *pDocSh, &aScType ); + } + + // Filter-Detection + + const SfxFilter* pSfxFilter = NULL; + SfxMedium* pMedium = new SfxMedium( rFileName, STREAM_STD_READ, FALSE, TRUE ); + if ( pMedium->GetError() == ERRCODE_NONE ) + { + SfxFilterMatcher aMatcher( ScDocShell::Factory().GetFilterContainer() ); + aMatcher.GuessFilter( *pMedium, &pSfxFilter ); + } + + if ( pSfxFilter ) + rFilter = pSfxFilter->GetFilterName(); + else + rFilter = ScDocShell::GetOwnFilterName(); // sonst Calc-Datei + + delete pMedium; +} + +ScDocumentLoader::ScDocumentLoader( const String& rFileName, + String& rFilterName, String& rOptions, + UINT32 nRekCnt ) : + pDocShell(0), + pMedium(0) +{ + if ( !rFilterName.Len() ) + GetFilterName( rFileName, rFilterName, rOptions ); + + const SfxFilter* pFilter = SFX_APP()->GetFilter( + ScDocShell::Factory(), rFilterName ); + + // ItemSet immer anlegen, damit die DocShell die Optionen setzen kann + SfxItemSet* pSet = new SfxAllItemSet( SFX_APP()->GetPool() ); + if ( rOptions.Len() ) + pSet->Put( SfxStringItem( SID_FILE_FILTEROPTIONS, rOptions ) ); + + pMedium = new SfxMedium( rFileName, STREAM_STD_READ, FALSE, TRUE, pFilter, pSet ); + if ( pMedium->GetError() != ERRCODE_NONE ) + return ; + + pDocShell = new ScDocShell( SFX_CREATE_MODE_INTERNAL ); + aRef = pDocShell; + + ScDocument* pDoc = pDocShell->GetDocument(); + if( pDoc ) + { + ScExtDocOptions* pExtDocOpt = pDoc->GetExtDocOptions(); + if( !pExtDocOpt ) + { + pExtDocOpt = new ScExtDocOptions; + pDoc->SetExtDocOptions( pExtDocOpt ); + } + pExtDocOpt->nLinkCnt = nRekCnt; + } + + pDocShell->DoLoad( pMedium ); + + String aNew = GetOptions(*pMedium); // Optionen werden beim Laden per Dialog gesetzt + if (aNew.Len() && aNew != rOptions) + rOptions = aNew; +} + +ScDocumentLoader::~ScDocumentLoader() +{ +/* if ( pDocShell ) + pDocShell->DoClose(); +*/ + if ( aRef.Is() ) + aRef->DoClose(); + else if ( pMedium ) + delete pMedium; +} + +ScDocument* ScDocumentLoader::GetDocument() +{ + return pDocShell ? pDocShell->GetDocument() : 0; +} + +BOOL ScDocumentLoader::IsError() const +{ + if ( pDocShell && pMedium ) + return pMedium->GetError() != ERRCODE_NONE; + else + return TRUE; +} + +String ScDocumentLoader::GetTitle() const +{ + if ( pDocShell ) + return pDocShell->GetTitle(); + else + return EMPTY_STRING; +} + + + diff --git a/sc/source/ui/docshell/tpstat.cxx b/sc/source/ui/docshell/tpstat.cxx new file mode 100644 index 000000000000..d6d08eca934d --- /dev/null +++ b/sc/source/ui/docshell/tpstat.cxx @@ -0,0 +1,134 @@ +/************************************************************************* + * + * $RCSfile: tpstat.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef PCH +#include "ui_pch.hxx" +#endif + +#pragma hdrstop + +#include "document.hxx" +#include "docsh.hxx" +#include "scresid.hxx" +#include "tpstat.hrc" + +#include "tpstat.hxx" + + +//======================================================================== +// Dokumentinfo-Tabpage: +//======================================================================== + +SfxTabPage* __EXPORT ScDocStatPage::Create( Window *pParent, const SfxItemSet& rSet ) +{ + return new ScDocStatPage( pParent, rSet ); +} + +//------------------------------------------------------------------------ + +ScDocStatPage::ScDocStatPage( Window *pParent, const SfxItemSet& rSet ) + : SfxTabPage( pParent, ScResId(RID_SCPAGE_STAT), rSet ), + aFtTablesLbl ( this, ScResId( FT_TABLES_LBL ) ), + aFtTables ( this, ScResId( FT_TABLES ) ), + aFtCellsLbl ( this, ScResId( FT_CELLS_LBL ) ), + aFtCells ( this, ScResId( FT_CELLS ) ), + aFtPagesLbl ( this, ScResId( FT_PAGES_LBL ) ), + aFtPages ( this, ScResId( FT_PAGES ) ), + aGbInfo ( this, ScResId( GB_INFO ) ) +{ + ScDocShell* pDocSh = PTR_CAST( ScDocShell, SfxObjectShell::Current() ); + ScDocStat aDocStat; + + if ( pDocSh ) + pDocSh->GetDocStat( aDocStat ); + + String aInfo = aGbInfo.GetText(); + aInfo += aDocStat.aDocName; + aGbInfo .SetText( aInfo ); + aFtTables .SetText( String::CreateFromInt32( aDocStat.nTableCount ) ); + aFtCells .SetText( String::CreateFromInt32( aDocStat.nCellCount ) ); + aFtPages .SetText( String::CreateFromInt32( aDocStat.nPageCount ) ); + + FreeResource(); +} + +//------------------------------------------------------------------------ + +__EXPORT ScDocStatPage::~ScDocStatPage() +{ +} + +//------------------------------------------------------------------------ + +BOOL __EXPORT ScDocStatPage::FillItemSet( SfxItemSet& rSet ) +{ + return FALSE; +} + +//------------------------------------------------------------------------ + +void __EXPORT ScDocStatPage::Reset( const SfxItemSet& rSet ) +{ +} + + + + diff --git a/sc/source/ui/docshell/tpstat.hrc b/sc/source/ui/docshell/tpstat.hrc new file mode 100644 index 000000000000..c0a7b1ce6b37 --- /dev/null +++ b/sc/source/ui/docshell/tpstat.hrc @@ -0,0 +1,70 @@ +/************************************************************************* + * + * $RCSfile: tpstat.hrc,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include "sc.hrc" + +#define FT_TABLES 1 +#define FT_TABLES_LBL 2 +#define FT_CELLS 3 +#define FT_CELLS_LBL 4 +#define FT_PAGES 5 +#define FT_PAGES_LBL 6 + +#define GB_INFO 1 diff --git a/sc/source/ui/docshell/tpstat.src b/sc/source/ui/docshell/tpstat.src new file mode 100644 index 000000000000..825d84b33f0e --- /dev/null +++ b/sc/source/ui/docshell/tpstat.src @@ -0,0 +1,203 @@ +/************************************************************************* + * + * $RCSfile: tpstat.src,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:44:55 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include "tpstat.hrc" +TabPage RID_SCPAGE_STAT +{ + // HelpID = HID_DOC_STAT; + Hide = TRUE ; + Size = MAP_APPFONT ( 260 , 135 ) ; + FixedText FT_TABLES_LBL + { + Pos = MAP_APPFONT ( 18 , 26 ) ; + Size = MAP_APPFONT ( 90 , 10 ) ; + Text = "Anzahl Tabellen:" ; + Text [ ENGLISH ] = "Number of tables:" ; + Text [ norwegian ] = "Number of tables:" ; + Text [ italian ] = "Numero di tabelle:" ; + Text [ portuguese_brazilian ] = "Nmero de tabelas:" ; + Text [ portuguese ] = "Nmero de tabelas:" ; + Text [ finnish ] = "Taulukoita:" ; + Text [ danish ] = "Antal tabeller:" ; + Text [ french ] = "Nombre de feuilles :" ; + Text [ swedish ] = "Antal tabeller:" ; + Text [ dutch ] = "Aantal werkbladen:" ; + Text [ spanish ] = "Nm. de hojas:" ; + Text [ english_us ] = "Number of sheets:" ; + Left = TRUE ; + Text[ chinese_simplified ] = "Ŀ:"; + Text[ russian ] = " :"; + Text[ polish ] = "Liczba tabel:"; + Text[ japanese ] = "\\̐:"; + Text[ chinese_traditional ] = "u@ƥءG"; + Text[ arabic ] = " :"; + Text[ dutch ] = "Aantal werkbladen:"; + Text[ chinese_simplified ] = "Ŀ:"; + Text[ greek ] = " :"; + Text[ korean ] = "Ʈ :"; + Text[ turkish ] = "Tablo says:"; + Text[ language_user1 ] = " "; + }; + FixedText FT_TABLES + { + Pos = MAP_APPFONT ( 114 , 26 ) ; + Size = MAP_APPFONT ( 27 , 10 ) ; + Left = TRUE ; + }; + FixedText FT_CELLS_LBL + { + Pos = MAP_APPFONT ( 18 , 38 ) ; + Size = MAP_APPFONT ( 90 , 10 ) ; + Text = "Anzahl Zellen:" ; + Text [ ENGLISH ] = "Number of cells:" ; + Text [ english_us ] = "Number of cells:" ; + Left = TRUE ; + Text [ italian ] = "Numero di celle:" ; + Text [ spanish ] = "Cantidad de celdas:" ; + Text [ french ] = "Nombre de cellules :" ; + Text [ dutch ] = "Aantal cellen:" ; + Text [ swedish ] = "Antal celler:" ; + Text [ danish ] = "Antal celler:" ; + Text [ portuguese ] = "Nmero de clulas:" ; + Text [ portuguese_brazilian ] = "Anzahl Zellen:" ; + Text[ chinese_simplified ] = "ԪĿ"; + Text[ russian ] = " :"; + Text[ polish ] = "Liczba komrek:"; + Text[ japanese ] = "ق̐F"; + Text[ chinese_traditional ] = "xs檺ƥءG"; + Text[ arabic ] = " :"; + Text[ dutch ] = "Aantal cellen:"; + Text[ chinese_simplified ] = "ԪĿ"; + Text[ greek ] = " :"; + Text[ korean ] = " :"; + Text[ turkish ] = "Hcre says:"; + Text[ language_user1 ] = " "; + }; + FixedText FT_CELLS + { + Pos = MAP_APPFONT ( 114 , 38 ) ; + Size = MAP_APPFONT ( 27 , 10 ) ; + Left = TRUE ; + }; + FixedText FT_PAGES_LBL + { + Pos = MAP_APPFONT ( 18 , 50 ) ; + Size = MAP_APPFONT ( 90 , 10 ) ; + Text = "Anzahl Seiten:" ; + Text [ ENGLISH ] = "Number of pages:" ; + Text [ english_us ] = "Number of pages:" ; + Left = TRUE ; + Text [ italian ] = "Numero di pagine:" ; + Text [ spanish ] = "Cantidad de pginas:" ; + Text [ french ] = "Nombre de pages :" ; + Text [ dutch ] = "Aantal paginas:" ; + Text [ swedish ] = "Antal sidor:" ; + Text [ danish ] = "Antal sider:" ; + Text [ portuguese_brazilian ] = "Anzahl Seiten:" ; + Text [ portuguese ] = "Nmero de pginas:" ; + Text[ chinese_simplified ] = "ҳ"; + Text[ russian ] = " :"; + Text[ polish ] = "Liczba stron:"; + Text[ japanese ] = "߰ޑ:"; + Text[ chinese_traditional ] = "ơG"; + Text[ arabic ] = " :"; + Text[ dutch ] = "Aantal paginas:"; + Text[ chinese_simplified ] = "ҳ"; + Text[ greek ] = " :"; + Text[ korean ] = " :"; + Text[ turkish ] = "Sayfa says:"; + Text[ language_user1 ] = " "; + }; + FixedText FT_PAGES + { + Pos = MAP_APPFONT ( 114 , 50 ) ; + Size = MAP_APPFONT ( 27 , 10 ) ; + Left = TRUE ; + }; + GroupBox GB_INFO + { + Pos = MAP_APPFONT ( 6 , 4 ) ; + Size = MAP_APPFONT ( 246 , 124 ) ; + Text = "Dokument: " ; + Text [ ENGLISH ] = "Document: " ; + Text [ english_us ] = "Document: " ; + Text [ dutch ] = "Document: " ; + Text [ italian ] = "Documento: " ; + Text [ spanish ] = "Documento: " ; + Text [ french ] = "Document : " ; + Text [ swedish ] = "Dokument: " ; + Text [ danish ] = "Dokument: " ; + Text [ portuguese_brazilian ] = "Dokument: " ; + Text [ portuguese ] = "Documento: " ; + Text[ chinese_simplified ] = "ĵ "; + Text[ russian ] = ": "; + Text[ polish ] = "Dokument: "; + Text[ japanese ] = ": "; + Text[ chinese_traditional ] = "G "; + Text[ arabic ] = ": "; + Text[ dutch ] = "Document: "; + Text[ chinese_simplified ] = "ĵ "; + Text[ greek ] = ": "; + Text[ korean ] = ": "; + Text[ turkish ] = "Belge: "; + Text[ language_user1 ] = " "; + }; +}; |