diff options
Diffstat (limited to 'sc/source/ui/navipi/content.cxx')
-rw-r--r-- | sc/source/ui/navipi/content.cxx | 1490 |
1 files changed, 1490 insertions, 0 deletions
diff --git a/sc/source/ui/navipi/content.cxx b/sc/source/ui/navipi/content.cxx new file mode 100644 index 000000000000..ad957181e12f --- /dev/null +++ b/sc/source/ui/navipi/content.cxx @@ -0,0 +1,1490 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + +#include <svx/svditer.hxx> +#include <svx/svdobj.hxx> +#include <svx/svdpage.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdview.hxx> +#include <svx/svdxcgv.hxx> +#include <sfx2/linkmgr.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/viewfrm.hxx> +#include <vcl/help.hxx> +#include <vcl/sound.hxx> +#include <vcl/svapp.hxx> +#include <tools/urlobj.hxx> +#include <svl/urlbmk.hxx> +#include <stdlib.h> + +#include "content.hxx" +#include "navipi.hxx" +#include "global.hxx" +#include "docsh.hxx" +#include "scmod.hxx" +#include "rangenam.hxx" +#include "dbcolect.hxx" +#include "tablink.hxx" // fuer Loader +#include "popmenu.hxx" +#include "drwlayer.hxx" +#include "transobj.hxx" +#include "drwtrans.hxx" +#include "lnktrans.hxx" +#include "cell.hxx" +#include "dociter.hxx" +#include "scresid.hxx" +#include "globstr.hrc" +#include "navipi.hrc" +#include "arealink.hxx" +#include "navicfg.hxx" +#include "navsett.hxx" +#include "postit.hxx" +#include "clipparam.hxx" + +using namespace com::sun::star; + +// Reihenfolge der Kategorien im Navigator ------------------------------------- + +static sal_uInt16 pTypeList[SC_CONTENT_COUNT] = +{ + SC_CONTENT_ROOT, // ROOT (0) muss vorne stehen + SC_CONTENT_TABLE, + SC_CONTENT_RANGENAME, + SC_CONTENT_DBAREA, + SC_CONTENT_AREALINK, + SC_CONTENT_GRAPHIC, + SC_CONTENT_OLEOBJECT, + SC_CONTENT_NOTE, + SC_CONTENT_DRAWING +}; + +sal_Bool ScContentTree::bIsInDrag = false; + + +ScDocShell* ScContentTree::GetManualOrCurrent() +{ + ScDocShell* pSh = NULL; + if ( aManualDoc.Len() ) + { + TypeId aScType = TYPE(ScDocShell); + SfxObjectShell* pObjSh = SfxObjectShell::GetFirst( &aScType ); + while ( pObjSh && !pSh ) + { + if ( pObjSh->GetTitle() == aManualDoc ) + pSh = PTR_CAST( ScDocShell, pObjSh ); + pObjSh = SfxObjectShell::GetNext( *pObjSh, &aScType ); + } + } + else + { + // Current nur, wenn keine manuell eingestellt ist + // (damit erkannt wird, wenn das Dokument nicht mehr existiert) + + SfxViewShell* pViewSh = SfxViewShell::Current(); + if ( pViewSh ) + { + SfxObjectShell* pObjSh = pViewSh->GetViewFrame()->GetObjectShell(); + pSh = PTR_CAST( ScDocShell, pObjSh ); + } + } + + return pSh; +} + +// +// ScContentTree +// + +ScContentTree::ScContentTree( Window* pParent, const ResId& rResId ) : + SvTreeListBox ( pParent, rResId ), + aEntryImages ( ScResId( RID_IMAGELIST_NAVCONT ) ), + nRootType ( SC_CONTENT_ROOT ), + bHiddenDoc ( false ), + pHiddenDocument ( NULL ) +{ + sal_uInt16 i; + for (i=0; i<SC_CONTENT_COUNT; i++) + pPosList[pTypeList[i]] = i; // invers zum suchen + + pParentWindow = (ScNavigatorDlg*)pParent; + + pRootNodes[0] = NULL; + for (i=1; i<SC_CONTENT_COUNT; i++) + InitRoot(i); + + SetNodeDefaultImages(); + + SetDoubleClickHdl( LINK( this, ScContentTree, ContentDoubleClickHdl ) ); + + SetStyle( GetStyle() | WB_QUICK_SEARCH ); +} + +ScContentTree::~ScContentTree() +{ +} + +void ScContentTree::InitRoot( sal_uInt16 nType ) +{ + if ( !nType ) + return; + + if ( nRootType && nRootType != nType ) // ausgeblendet ? + { + pRootNodes[nType] = NULL; + return; + } + + const Image& rImage = aEntryImages.GetImage( nType ); + String aName( ScResId( SCSTR_CONTENT_ROOT + nType ) ); + // wieder an die richtige Position: + sal_uInt16 nPos = nRootType ? 0 : pPosList[nType]-1; + SvLBoxEntry* pNew = InsertEntry( aName, rImage, rImage, NULL, false, nPos ); + + pRootNodes[nType] = pNew; +} + +void ScContentTree::ClearAll() +{ + Clear(); + for (sal_uInt16 i=1; i<SC_CONTENT_COUNT; i++) + InitRoot(i); +} + +void ScContentTree::ClearType(sal_uInt16 nType) +{ + if (!nType) + ClearAll(); + else + { + SvLBoxEntry* pParent = pRootNodes[nType]; + if ( !pParent || GetChildCount(pParent) ) // nicht, wenn ohne Children schon da + { + if (pParent) + GetModel()->Remove( pParent ); // mit allen Children + InitRoot( nType ); // ggf. neu eintragen + } + } +} + +void ScContentTree::InsertContent( sal_uInt16 nType, const String& rValue ) +{ + if (nType >= SC_CONTENT_COUNT) + { + OSL_FAIL("ScContentTree::InsertContent mit falschem Typ"); + return; + } + + SvLBoxEntry* pParent = pRootNodes[nType]; + if (pParent) + InsertEntry( rValue, pParent ); + else + { + OSL_FAIL("InsertContent ohne Parent"); + } +} + +void ScContentTree::GetEntryIndexes( sal_uInt16& rnRootIndex, sal_uLong& rnChildIndex, SvLBoxEntry* pEntry ) const +{ + rnRootIndex = SC_CONTENT_ROOT; + rnChildIndex = SC_CONTENT_NOCHILD; + + if( !pEntry ) + return; + + SvLBoxEntry* pParent = GetParent( pEntry ); + bool bFound = false; + for( sal_uInt16 nRoot = 1; !bFound && (nRoot < SC_CONTENT_COUNT); ++nRoot ) + { + if( pEntry == pRootNodes[ nRoot ] ) + { + rnRootIndex = nRoot; + rnChildIndex = ~0UL; + bFound = true; + } + else if( pParent && (pParent == pRootNodes[ nRoot ]) ) + { + rnRootIndex = nRoot; + + // search the entry in all child entries of the parent + sal_uLong nEntry = 0; + SvLBoxEntry* pIterEntry = FirstChild( pParent ); + while( !bFound && pIterEntry ) + { + if ( pEntry == pIterEntry ) + { + rnChildIndex = nEntry; + bFound = true; // exit the while loop + } + pIterEntry = NextSibling( pIterEntry ); + ++nEntry; + } + + bFound = true; // exit the for loop + } + } +} + +sal_uLong ScContentTree::GetChildIndex( SvLBoxEntry* pEntry ) const +{ + sal_uInt16 nRoot; + sal_uLong nChild; + GetEntryIndexes( nRoot, nChild, pEntry ); + return nChild; +} + +String lcl_GetDBAreaRange( ScDocument* pDoc, const String& rDBName ) +{ + String aRet; + if (pDoc) + { + ScDBCollection* pDbNames = pDoc->GetDBCollection(); + sal_uInt16 nCount = pDbNames->GetCount(); + for ( sal_uInt16 i=0; i<nCount; i++ ) + { + ScDBData* pData = (*pDbNames)[i]; + if ( pData->GetName() == rDBName ) + { + ScRange aRange; + pData->GetArea(aRange); + aRange.Format( aRet, SCR_ABS_3D, pDoc ); + break; + } + } + } + return aRet; +} + +IMPL_LINK( ScContentTree, ContentDoubleClickHdl, ScContentTree *, EMPTYARG ) +{ + sal_uInt16 nType; + sal_uLong nChild; + SvLBoxEntry* pEntry = GetCurEntry(); + GetEntryIndexes( nType, nChild, pEntry ); + + if( pEntry && (nType != SC_CONTENT_ROOT) && (nChild != SC_CONTENT_NOCHILD) ) + { + if ( bHiddenDoc ) + return 0; //! spaeter... + + String aText( GetEntryText( pEntry ) ); + + if ( aManualDoc.Len() ) + pParentWindow->SetCurrentDoc( aManualDoc ); + + switch( nType ) + { + case SC_CONTENT_TABLE: + pParentWindow->SetCurrentTableStr( aText ); + break; + + case SC_CONTENT_RANGENAME: + pParentWindow->SetCurrentCellStr( aText ); + break; + + case SC_CONTENT_DBAREA: + { + // Wenn gleiche Bereichs- und DB-Namen existieren, wird + // bei SID_CURRENTCELL der Bereichsname genommen. + // DB-Bereiche darum direkt ueber die Adresse anspringen. + + String aRangeStr = lcl_GetDBAreaRange( GetSourceDocument(), aText ); + if (aRangeStr.Len()) + pParentWindow->SetCurrentCellStr( aRangeStr ); + } + break; + + case SC_CONTENT_OLEOBJECT: + case SC_CONTENT_GRAPHIC: + case SC_CONTENT_DRAWING: + pParentWindow->SetCurrentObject( aText ); + break; + + case SC_CONTENT_NOTE: + { + ScAddress aPos = GetNotePos( nChild ); + pParentWindow->SetCurrentTable( aPos.Tab() ); + pParentWindow->SetCurrentCell( aPos.Col(), aPos.Row() ); + } + break; + + case SC_CONTENT_AREALINK: + { + const ScAreaLink* pLink = GetLink( nChild ); + if( pLink ) + { + ScRange aRange = pLink->GetDestArea(); + String aRangeStr; + ScDocument* pSrcDoc = GetSourceDocument(); + aRange.Format( aRangeStr, SCR_ABS_3D, pSrcDoc, pSrcDoc->GetAddressConvention() ); + pParentWindow->SetCurrentCellStr( aRangeStr ); + } + } + break; + } + + ScNavigatorDlg::ReleaseFocus(); // set focus into document + } + + return 0; +} + +void ScContentTree::MouseButtonDown( const MouseEvent& rMEvt ) +{ + SvTreeListBox::MouseButtonDown( rMEvt ); + StoreSettings(); +} + +void ScContentTree::KeyInput( const KeyEvent& rKEvt ) +{ + sal_Bool bUsed = false; + + const KeyCode aCode = rKEvt.GetKeyCode(); + if (aCode.GetCode() == KEY_RETURN) + { + switch (aCode.GetModifier()) + { + case KEY_MOD1: + ToggleRoot(); // toggle root mode (as in Writer) + bUsed = sal_True; + break; + case 0: + { + SvLBoxEntry* pEntry = GetCurEntry(); + if( pEntry ) + { + sal_uInt16 nType; + sal_uLong nChild; + GetEntryIndexes( nType, nChild, pEntry ); + + if( (nType != SC_CONTENT_ROOT) && (nChild == SC_CONTENT_NOCHILD) ) + { + String aText( GetEntryText( pEntry ) ); + if ( IsExpanded( pEntry ) ) + Collapse( pEntry ); + else + Expand( pEntry ); + } + else + ContentDoubleClickHdl(0); // select content as if double clicked + } + + bUsed = sal_True; + } + break; + } + } + StoreSettings(); + + if( !bUsed ) + SvTreeListBox::KeyInput(rKEvt); +} + +sal_Int8 ScContentTree::AcceptDrop( const AcceptDropEvent& /* rEvt */ ) +{ + return DND_ACTION_NONE; +} + +sal_Int8 ScContentTree::ExecuteDrop( const ExecuteDropEvent& /* rEvt */ ) +{ + return DND_ACTION_NONE; +} + +void ScContentTree::StartDrag( sal_Int8 /* nAction */, const Point& /* rPosPixel */ ) +{ + DoDrag(); +} + +void ScContentTree::DragFinished( sal_Int8 /* nAction */ ) +{ +} + +void ScContentTree::Command( const CommandEvent& rCEvt ) +{ + sal_Bool bDone = false; + + switch ( rCEvt.GetCommand() ) + { + case COMMAND_STARTDRAG: + // Aus dem ExecuteDrag heraus kann der Navigator geloescht werden + // (beim Umschalten auf einen anderen Dokument-Typ), das wuerde aber + // den StarView MouseMove-Handler, der Command() aufruft, umbringen. + // Deshalb Drag&Drop asynchron: + + Application::PostUserEvent( STATIC_LINK( this, ScContentTree, ExecDragHdl ) ); + + bDone = sal_True; + break; + + case COMMAND_CONTEXTMENU: + { + // Drag-Drop Modus + + PopupMenu aPop; + ScPopupMenu aDropMenu( ScResId( RID_POPUP_DROPMODE ) ); + aDropMenu.CheckItem( RID_DROPMODE_URL + pParentWindow->GetDropMode() ); + aPop.InsertItem( 1, pParentWindow->GetStrDragMode() ); + aPop.SetPopupMenu( 1, &aDropMenu ); + + // angezeigtes Dokument + + ScPopupMenu aDocMenu; + aDocMenu.SetMenuFlags( aDocMenu.GetMenuFlags() | MENU_FLAG_NOAUTOMNEMONICS ); + sal_uInt16 i=0; + sal_uInt16 nPos=0; + // geladene Dokumente + ScDocShell* pCurrentSh = PTR_CAST( ScDocShell, SfxObjectShell::Current() ); + SfxObjectShell* pSh = SfxObjectShell::GetFirst(); + while ( pSh ) + { + if ( pSh->ISA(ScDocShell) ) + { + String aName = pSh->GetTitle(); + String aEntry = aName; + if ( pSh == pCurrentSh ) + aEntry += pParentWindow->aStrActive; + else + aEntry += pParentWindow->aStrNotActive; + aDocMenu.InsertItem( ++i, aEntry ); + if ( !bHiddenDoc && aName == aManualDoc ) + nPos = i; + } + pSh = SfxObjectShell::GetNext( *pSh ); + } + // "aktives Fenster" + aDocMenu.InsertItem( ++i, pParentWindow->aStrActiveWin ); + if (!bHiddenDoc && !aManualDoc.Len()) + nPos = i; + // verstecktes Dokument + if ( aHiddenTitle.Len() ) + { + String aEntry = aHiddenTitle; + aEntry += pParentWindow->aStrHidden; + aDocMenu.InsertItem( ++i, aEntry ); + if (bHiddenDoc) + nPos = i; + } + aDocMenu.CheckItem( nPos ); + aPop.InsertItem( 2, pParentWindow->GetStrDisplay() ); + aPop.SetPopupMenu( 2, &aDocMenu ); + + // ausfuehren + + aPop.Execute( this, rCEvt.GetMousePosPixel() ); + + if ( aDropMenu.WasHit() ) // Drag-Drop Modus + { + sal_uInt16 nId = aDropMenu.GetSelected(); + if ( nId >= RID_DROPMODE_URL && nId <= RID_DROPMODE_COPY ) + pParentWindow->SetDropMode( nId - RID_DROPMODE_URL ); + } + else if ( aDocMenu.WasHit() ) // angezeigtes Dokument + { + sal_uInt16 nId = aDocMenu.GetSelected(); + String aName = aDocMenu.GetItemText(nId); + SelectDoc( aName ); + } + } + break; + } + + if (!bDone) + SvTreeListBox::Command(rCEvt); +} + +void ScContentTree::RequestHelp( const HelpEvent& rHEvt ) +{ + sal_Bool bDone = false; + if( rHEvt.GetMode() & HELPMODE_QUICK ) + { + Point aPos( ScreenToOutputPixel( rHEvt.GetMousePosPixel() )); + SvLBoxEntry* pEntry = GetEntry( aPos ); + if ( pEntry ) + { + sal_Bool bRet = false; + String aHelpText; + SvLBoxEntry* pParent = GetParent(pEntry); + if ( !pParent ) // Top-Level ? + { + aHelpText = String::CreateFromInt32( GetChildCount(pEntry) ); + aHelpText += ' '; + aHelpText += GetEntryText(pEntry); + bRet = sal_True; + } + else if ( pParent == pRootNodes[SC_CONTENT_NOTE] ) + { + aHelpText = GetEntryText(pEntry); // Notizen als Help-Text + bRet = sal_True; + } + else if ( pParent == pRootNodes[SC_CONTENT_AREALINK] ) + { + sal_uLong nIndex = GetChildIndex(pEntry); + if( nIndex != SC_CONTENT_NOCHILD ) + { + const ScAreaLink* pLink = GetLink(nIndex); + if (pLink) + { + aHelpText = pLink->GetFile(); // Source-Datei als Help-Text + bRet = sal_True; + } + } + } + + if (bRet) + { + SvLBoxTab* pTab; + SvLBoxString* pItem = (SvLBoxString*)(GetItem( pEntry, aPos.X(), &pTab )); + if( pItem ) + { + aPos = GetEntryPosition( pEntry ); + aPos.X() = GetTabPos( pEntry, pTab ); + aPos = OutputToScreenPixel(aPos); + Size aSize( pItem->GetSize( this, pEntry ) ); + + Rectangle aItemRect( aPos, aSize ); + Help::ShowQuickHelp( this, aItemRect, aHelpText ); + bDone = sal_True; + } + } + } + } + if (!bDone) + Window::RequestHelp( rHEvt ); +} + +ScDocument* ScContentTree::GetSourceDocument() +{ + if (bHiddenDoc) + return pHiddenDocument; + else + { + ScDocShell* pSh = GetManualOrCurrent(); + if (pSh) + return pSh->GetDocument(); + + } + return NULL; +} + +void ScContentTree::Refresh( sal_uInt16 nType ) +{ + if ( bHiddenDoc && !pHiddenDocument ) + return; // anderes Dokument angezeigt + + // wenn sich nichts geaendert hat, gleich abbrechen (gegen Geflacker) + + if ( nType == SC_CONTENT_NOTE ) + if (!NoteStringsChanged()) + return; + if ( nType == SC_CONTENT_GRAPHIC ) + if (!DrawNamesChanged(SC_CONTENT_GRAPHIC)) + return; + if ( nType == SC_CONTENT_OLEOBJECT ) + if (!DrawNamesChanged(SC_CONTENT_OLEOBJECT)) + return; + if ( nType == SC_CONTENT_DRAWING ) + if (!DrawNamesChanged(SC_CONTENT_DRAWING)) + return; + + SetUpdateMode(false); + + ClearType( nType ); + + if ( !nType || nType == SC_CONTENT_TABLE ) + GetTableNames(); + if ( !nType || nType == SC_CONTENT_RANGENAME ) + GetAreaNames(); + if ( !nType || nType == SC_CONTENT_DBAREA ) + GetDbNames(); + if ( !nType || nType == SC_CONTENT_GRAPHIC ) + GetGraphicNames(); + if ( !nType || nType == SC_CONTENT_OLEOBJECT ) + GetOleNames(); + if ( !nType || nType == SC_CONTENT_DRAWING ) + GetDrawingNames(); + if ( !nType || nType == SC_CONTENT_NOTE ) + GetNoteStrings(); + if ( !nType || nType == SC_CONTENT_AREALINK ) + GetLinkNames(); + + ApplySettings(); + SetUpdateMode(sal_True); +} + +void ScContentTree::GetTableNames() +{ + if ( nRootType && nRootType != SC_CONTENT_TABLE ) // ausgeblendet ? + return; + + ScDocument* pDoc = GetSourceDocument(); + if (!pDoc) + return; + + String aName; + SCTAB nCount = pDoc->GetTableCount(); + for ( SCTAB i=0; i<nCount; i++ ) + { + pDoc->GetName( i, aName ); + InsertContent( SC_CONTENT_TABLE, aName ); + } +} + +void ScContentTree::GetAreaNames() +{ + if ( nRootType && nRootType != SC_CONTENT_RANGENAME ) // ausgeblendet ? + return; + + ScDocument* pDoc = GetSourceDocument(); + if (!pDoc) + return; + + ScRangeName* pRangeNames = pDoc->GetRangeName(); + if (!pRangeNames->empty()) + { + ScRange aDummy; + ScRangeName::const_iterator itrBeg = pRangeNames->begin(), itrEnd = pRangeNames->end(); + std::vector<const ScRangeData*> aSortArray; + for (ScRangeName::const_iterator itr = itrBeg; itr != itrEnd; ++itr) + { + if (itr->IsValidReference(aDummy)) + aSortArray.push_back(&(*itr)); + } + + if (!aSortArray.empty()) + { +#ifndef ICC + size_t n = aSortArray.size(); + qsort( (void*)&aSortArray[0], n, sizeof(ScRangeData*), + &ScRangeData_QsortNameCompare ); +#else + qsort( (void*)&aSortArray[0], n, sizeof(ScRangeData*), + ICCQsortNameCompare ); +#endif + for (size_t i = 0; i < n; ++i) + InsertContent(SC_CONTENT_RANGENAME, aSortArray[i]->GetName()); + } + } +} + +void ScContentTree::GetDbNames() +{ + if ( nRootType && nRootType != SC_CONTENT_DBAREA ) // ausgeblendet ? + return; + + ScDocument* pDoc = GetSourceDocument(); + if (!pDoc) + return; + + ScDBCollection* pDbNames = pDoc->GetDBCollection(); + sal_uInt16 nCount = pDbNames->GetCount(); + if ( nCount > 0 ) + { + for ( sal_uInt16 i=0; i<nCount; i++ ) + { + ScDBData* pData = (*pDbNames)[i]; + String aStrName = pData->GetName(); + InsertContent( SC_CONTENT_DBAREA, aStrName ); + } + } +} + +bool ScContentTree::IsPartOfType( sal_uInt16 nContentType, sal_uInt16 nObjIdentifier ) +{ + bool bRet = false; + switch ( nContentType ) + { + case SC_CONTENT_GRAPHIC: + bRet = ( nObjIdentifier == OBJ_GRAF ); + break; + case SC_CONTENT_OLEOBJECT: + bRet = ( nObjIdentifier == OBJ_OLE2 ); + break; + case SC_CONTENT_DRAWING: + bRet = ( nObjIdentifier != OBJ_GRAF && nObjIdentifier != OBJ_OLE2 ); // everything else + break; + default: + OSL_FAIL("unknown content type"); + } + return bRet; +} + +void ScContentTree::GetDrawNames( sal_uInt16 nType ) +{ + if ( nRootType && nRootType != nType ) // ausgeblendet ? + return; + + ScDocument* pDoc = GetSourceDocument(); + if (!pDoc) + return; + + // iterate in flat mode for groups + SdrIterMode eIter = ( nType == SC_CONTENT_DRAWING ) ? IM_FLAT : IM_DEEPNOGROUPS; + + ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); + SfxObjectShell* pShell = pDoc->GetDocumentShell(); + if (pDrawLayer && pShell) + { + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; nTab++) + { + SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); + DBG_ASSERT(pPage,"Page ?"); + if (pPage) + { + SdrObjListIter aIter( *pPage, eIter ); + SdrObject* pObject = aIter.Next(); + while (pObject) + { + if ( IsPartOfType( nType, pObject->GetObjIdentifier() ) ) + { + String aName = ScDrawLayer::GetVisibleName( pObject ); + if (aName.Len()) + InsertContent( nType, aName ); + } + + pObject = aIter.Next(); + } + } + } + } +} + +void ScContentTree::GetGraphicNames() +{ + GetDrawNames( SC_CONTENT_GRAPHIC ); +} + +void ScContentTree::GetOleNames() +{ + GetDrawNames( SC_CONTENT_OLEOBJECT ); +} + +void ScContentTree::GetDrawingNames() +{ + GetDrawNames( SC_CONTENT_DRAWING ); +} + +void ScContentTree::GetLinkNames() +{ + if ( nRootType && nRootType != SC_CONTENT_AREALINK ) // ausgeblendet ? + return; + + ScDocument* pDoc = GetSourceDocument(); + if (!pDoc) + return; + + sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager(); + DBG_ASSERT(pLinkManager, "kein LinkManager am Dokument?"); + const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks(); + sal_uInt16 nCount = rLinks.Count(); + for (sal_uInt16 i=0; i<nCount; i++) + { + ::sfx2::SvBaseLink* pBase = *rLinks[i]; + if (pBase->ISA(ScAreaLink)) + InsertContent( SC_CONTENT_AREALINK, ((ScAreaLink*)pBase)->GetSource() ); + + // in der Liste die Namen der Quellbereiche + } +} + +const ScAreaLink* ScContentTree::GetLink( sal_uLong nIndex ) +{ + ScDocument* pDoc = GetSourceDocument(); + if (!pDoc) + return NULL; + + sal_uLong nFound = 0; + sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager(); + DBG_ASSERT(pLinkManager, "kein LinkManager am Dokument?"); + const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks(); + sal_uInt16 nCount = rLinks.Count(); + for (sal_uInt16 i=0; i<nCount; i++) + { + ::sfx2::SvBaseLink* pBase = *rLinks[i]; + if (pBase->ISA(ScAreaLink)) + { + if (nFound == nIndex) + return (const ScAreaLink*) pBase; + ++nFound; + } + } + + OSL_FAIL("Link nicht gefunden"); + return NULL; +} + +String lcl_NoteString( const ScPostIt& rNote ) +{ + String aText = rNote.GetText(); + xub_StrLen nAt; + while ( (nAt = aText.Search( '\n' )) != STRING_NOTFOUND ) + aText.SetChar( nAt, ' ' ); + return aText; +} + +void ScContentTree::GetNoteStrings() +{ + if ( nRootType && nRootType != SC_CONTENT_NOTE ) // ausgeblendet ? + return; + + ScDocument* pDoc = GetSourceDocument(); + if (!pDoc) + return; + + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; nTab++) + { + ScCellIterator aIter( pDoc, 0,0,nTab, MAXCOL,MAXROW,nTab ); + for( ScBaseCell* pCell = aIter.GetFirst(); pCell; pCell = aIter.GetNext() ) + if( const ScPostIt* pNote = pCell->GetNote() ) + InsertContent( SC_CONTENT_NOTE, lcl_NoteString( *pNote ) ); + } +} + +ScAddress ScContentTree::GetNotePos( sal_uLong nIndex ) +{ + ScDocument* pDoc = GetSourceDocument(); + if (!pDoc) + return ScAddress(); + + sal_uLong nFound = 0; + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; nTab++) + { + ScCellIterator aIter( pDoc, 0,0,nTab, MAXCOL,MAXROW,nTab ); + ScBaseCell* pCell = aIter.GetFirst(); + while (pCell) + { + if( pCell->HasNote() ) + { + if (nFound == nIndex) + return ScAddress( aIter.GetCol(), aIter.GetRow(), nTab ); // gefunden + ++nFound; + } + pCell = aIter.GetNext(); + } + } + + OSL_FAIL("Notiz nicht gefunden"); + return ScAddress(); +} + +sal_Bool ScContentTree::NoteStringsChanged() +{ + ScDocument* pDoc = GetSourceDocument(); + if (!pDoc) + return false; + + SvLBoxEntry* pParent = pRootNodes[SC_CONTENT_NOTE]; + if (!pParent) + return false; + + SvLBoxEntry* pEntry = FirstChild( pParent ); + + sal_Bool bEqual = sal_True; + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount && bEqual; nTab++) + { + ScCellIterator aIter( pDoc, 0,0,nTab, MAXCOL,MAXROW,nTab ); + ScBaseCell* pCell = aIter.GetFirst(); + while (pCell && bEqual) + { + if( const ScPostIt* pNote = pCell->GetNote() ) + { + if ( !pEntry ) + bEqual = false; + else + { + if ( lcl_NoteString( *pNote ) != GetEntryText(pEntry) ) + bEqual = false; + + pEntry = NextSibling( pEntry ); + } + } + pCell = aIter.GetNext(); + } + } + + if ( pEntry ) + bEqual = false; // kommt noch was + + return !bEqual; +} + +sal_Bool ScContentTree::DrawNamesChanged( sal_uInt16 nType ) +{ + ScDocument* pDoc = GetSourceDocument(); + if (!pDoc) + return false; + + SvLBoxEntry* pParent = pRootNodes[nType]; + if (!pParent) + return false; + + SvLBoxEntry* pEntry = FirstChild( pParent ); + + // iterate in flat mode for groups + SdrIterMode eIter = ( nType == SC_CONTENT_DRAWING ) ? IM_FLAT : IM_DEEPNOGROUPS; + + sal_Bool bEqual = sal_True; + ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); + SfxObjectShell* pShell = pDoc->GetDocumentShell(); + if (pDrawLayer && pShell) + { + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount && bEqual; nTab++) + { + SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); + DBG_ASSERT(pPage,"Page ?"); + if (pPage) + { + SdrObjListIter aIter( *pPage, eIter ); + SdrObject* pObject = aIter.Next(); + while (pObject && bEqual) + { + if ( IsPartOfType( nType, pObject->GetObjIdentifier() ) ) + { + if ( !pEntry ) + bEqual = false; + else + { + if ( ScDrawLayer::GetVisibleName( pObject ) != GetEntryText(pEntry) ) + bEqual = false; + + pEntry = NextSibling( pEntry ); + } + } + pObject = aIter.Next(); + } + } + } + } + + if ( pEntry ) + bEqual = false; // kommt noch was + + return !bEqual; +} + +sal_Bool lcl_GetRange( ScDocument* pDoc, sal_uInt16 nType, const String& rName, ScRange& rRange ) +{ + sal_Bool bFound = false; + sal_uInt16 nPos; + + if ( nType == SC_CONTENT_RANGENAME ) + { + ScRangeName* pList = pDoc->GetRangeName(); + if (pList) + { + const ScRangeData* p = pList->findByName(rName); + if (p && p->IsValidReference(rRange)) + bFound = true; + } + } + else if ( nType == SC_CONTENT_DBAREA ) + { + ScDBCollection* pList = pDoc->GetDBCollection(); + if (pList) + if (pList->SearchName( rName, nPos )) + { + SCTAB nTab; + SCCOL nCol1, nCol2; + SCROW nRow1, nRow2; + (*pList)[nPos]->GetArea(nTab,nCol1,nRow1,nCol2,nRow2); + rRange = ScRange( nCol1,nRow1,nTab, nCol2,nRow2,nTab ); + bFound = sal_True; + } + } + + return bFound; +} + +void lcl_DoDragObject( ScDocShell* pSrcShell, const String& rName, sal_uInt16 nType, Window* pWin ) +{ + ScDocument* pSrcDoc = pSrcShell->GetDocument(); + ScDrawLayer* pModel = pSrcDoc->GetDrawLayer(); + if (pModel) + { + sal_Bool bOle = ( nType == SC_CONTENT_OLEOBJECT ); + sal_Bool bGraf = ( nType == SC_CONTENT_GRAPHIC ); + sal_uInt16 nDrawId = sal::static_int_cast<sal_uInt16>( bOle ? OBJ_OLE2 : ( bGraf ? OBJ_GRAF : OBJ_GRUP ) ); + SCTAB nTab = 0; + SdrObject* pObject = pModel->GetNamedObject( rName, nDrawId, nTab ); + if (pObject) + { + SdrView aEditView( pModel ); + aEditView.ShowSdrPage(aEditView.GetModel()->GetPage(nTab)); + SdrPageView* pPV = aEditView.GetSdrPageView(); + aEditView.MarkObj(pObject, pPV); + + SdrModel* pDragModel = aEditView.GetAllMarkedModel(); + + TransferableObjectDescriptor aObjDesc; + pSrcShell->FillTransferableObjectDescriptor( aObjDesc ); + aObjDesc.maDisplayName = pSrcShell->GetMedium()->GetURLObject().GetURLNoPass(); + // maSize is set in ScDrawTransferObj ctor + + ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pDragModel, pSrcShell, aObjDesc ); + uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj ); + + pTransferObj->SetDragSourceObj( pObject, nTab ); + pTransferObj->SetDragSourceFlags( SC_DROP_NAVIGATOR ); + + SC_MOD()->SetDragObject( NULL, pTransferObj ); + pWin->ReleaseMouse(); + pTransferObj->StartDrag( pWin, DND_ACTION_COPYMOVE | DND_ACTION_LINK ); + } + } +} + +void lcl_DoDragCells( ScDocShell* pSrcShell, const ScRange& rRange, sal_uInt16 nFlags, Window* pWin ) +{ + ScMarkData aMark; + aMark.SelectTable( rRange.aStart.Tab(), sal_True ); + aMark.SetMarkArea( rRange ); + + ScDocument* pSrcDoc = pSrcShell->GetDocument(); + if ( !pSrcDoc->HasSelectedBlockMatrixFragment( rRange.aStart.Col(), rRange.aStart.Row(), + rRange.aEnd.Col(), rRange.aEnd.Row(), + aMark ) ) + { + ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP ); + ScClipParam aClipParam(rRange, false); + pSrcDoc->CopyToClip(aClipParam, pClipDoc, &aMark); + // pClipDoc->ExtendMerge( rRange, sal_True ); + + TransferableObjectDescriptor aObjDesc; + pSrcShell->FillTransferableObjectDescriptor( aObjDesc ); + aObjDesc.maDisplayName = pSrcShell->GetMedium()->GetURLObject().GetURLNoPass(); + // maSize is set in ScTransferObj ctor + + ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc ); + uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj ); + + pTransferObj->SetDragSource( pSrcShell, aMark ); + pTransferObj->SetDragSourceFlags( nFlags ); + + SC_MOD()->SetDragObject( pTransferObj, NULL ); // for internal D&D + pWin->ReleaseMouse(); + pTransferObj->StartDrag( pWin, DND_ACTION_COPYMOVE | DND_ACTION_LINK ); + } +} + +void ScContentTree::DoDrag() +{ + ScDocumentLoader* pDocLoader = NULL; + bIsInDrag = sal_True; + + ScModule* pScMod = SC_MOD(); + + sal_uInt16 nType; + sal_uLong nChild; + SvLBoxEntry* pEntry = GetCurEntry(); + GetEntryIndexes( nType, nChild, pEntry ); + + if( pEntry && + (nChild != SC_CONTENT_NOCHILD) && + (nType != SC_CONTENT_ROOT) && + (nType != SC_CONTENT_NOTE) && + (nType != SC_CONTENT_AREALINK) ) + { + String aText( GetEntryText( pEntry ) ); + + ScDocument* pLocalDoc = NULL; // fuer URL-Drop + String aDocName; + if (bHiddenDoc) + aDocName = aHiddenName; + else + { + ScDocShell* pDocSh = GetManualOrCurrent(); + if (pDocSh) + { + if (pDocSh->HasName()) + aDocName = pDocSh->GetMedium()->GetName(); + else + pLocalDoc = pDocSh->GetDocument(); // Drop nur in dieses Dokument + } + } + + sal_Bool bDoLinkTrans = false; // use ScLinkTransferObj + String aLinkURL; // for ScLinkTransferObj + String aLinkText; + + sal_uInt16 nDropMode = pParentWindow->GetDropMode(); + switch ( nDropMode ) + { + case SC_DROPMODE_URL: + { + String aUrl = aDocName; + aUrl += '#'; + aUrl += aText; + + pScMod->SetDragJump( pLocalDoc, aUrl, aText ); + + if (aDocName.Len()) + { + // provide URL to outside only if the document has a name + // (without name, only internal D&D via SetDragJump) + + aLinkURL = aUrl; + aLinkText = aText; + } + bDoLinkTrans = sal_True; + } + break; + case SC_DROPMODE_LINK: + { + if ( aDocName.Len() ) // link only to named documents + { + // for internal D&D, set flag to insert a link + + switch ( nType ) + { + case SC_CONTENT_TABLE: + pScMod->SetDragLink( aDocName, aText, EMPTY_STRING ); + bDoLinkTrans = sal_True; + break; + case SC_CONTENT_RANGENAME: + case SC_CONTENT_DBAREA: + pScMod->SetDragLink( aDocName, EMPTY_STRING, aText ); + bDoLinkTrans = sal_True; + break; + + // other types cannot be linked + } + } + } + break; + case SC_DROPMODE_COPY: + { + ScDocShell* pSrcShell = NULL; + if ( bHiddenDoc ) + { + String aFilter, aOptions; + pDocLoader = new ScDocumentLoader( aHiddenName, aFilter, aOptions ); + if (!pDocLoader->IsError()) + pSrcShell = pDocLoader->GetDocShell(); + } + else + pSrcShell = GetManualOrCurrent(); + + if ( pSrcShell ) + { + ScDocument* pSrcDoc = pSrcShell->GetDocument(); + if ( nType == SC_CONTENT_RANGENAME || nType == SC_CONTENT_DBAREA ) + { + ScRange aRange; + if ( lcl_GetRange( pSrcDoc, nType, aText, aRange ) ) + { + lcl_DoDragCells( pSrcShell, aRange, SC_DROP_NAVIGATOR, this ); + } + } + else if ( nType == SC_CONTENT_TABLE ) + { + SCTAB nTab; + if ( pSrcDoc->GetTable( aText, nTab ) ) + { + ScRange aRange( 0,0,nTab, MAXCOL,MAXROW,nTab ); + lcl_DoDragCells( pSrcShell, aRange, SC_DROP_NAVIGATOR | SC_DROP_TABLE, this ); + } + } + else if ( nType == SC_CONTENT_GRAPHIC || nType == SC_CONTENT_OLEOBJECT || + nType == SC_CONTENT_DRAWING ) + { + lcl_DoDragObject( pSrcShell, aText, nType, this ); + + // in ExecuteDrag kann der Navigator geloescht worden sein + // -> nicht mehr auf Member zugreifen !!! + } + } + } + break; + } + + if (bDoLinkTrans) + { + ScLinkTransferObj* pTransferObj = new ScLinkTransferObj; + uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj ); + + if ( aLinkURL.Len() ) + pTransferObj->SetLinkURL( aLinkURL, aLinkText ); + + // SetDragJump / SetDragLink has been done above + + ReleaseMouse(); + pTransferObj->StartDrag( this, DND_ACTION_COPYMOVE | DND_ACTION_LINK ); + } + } + + bIsInDrag = false; // static Member + + delete pDocLoader; // falls Dokument zum Draggen geladen wurde +} + +IMPL_STATIC_LINK(ScContentTree, ExecDragHdl, void*, EMPTYARG) +{ + // als Link, damit asynchron ohne ImpMouseMoveMsg auf dem Stack auch der + // Navigator geloescht werden darf + + pThis->DoDrag(); + return 0; +} + +sal_Bool ScContentTree::LoadFile( const String& rUrl ) +{ + String aDocName = rUrl; + xub_StrLen nPos = aDocName.Search('#'); + if ( nPos != STRING_NOTFOUND ) + aDocName.Erase(nPos); // nur der Name, ohne #... + + sal_Bool bReturn = false; + String aFilter, aOptions; + ScDocumentLoader aLoader( aDocName, aFilter, aOptions ); + if ( !aLoader.IsError() ) + { + bHiddenDoc = sal_True; + aHiddenName = aDocName; + aHiddenTitle = aLoader.GetTitle(); + pHiddenDocument = aLoader.GetDocument(); + + Refresh(); // Inhalte aus geladenem Dokument holen + + pHiddenDocument = NULL; + + pParentWindow->GetDocNames( &aHiddenTitle ); // Liste fuellen + } + else + Sound::Beep(); // Fehler beim Laden + + // Dokument wird im dtor von ScDocumentLoader wieder geschlossen + + return bReturn; +} + +void ScContentTree::InitWindowBits( sal_Bool bButtons ) +{ + WinBits nFlags = GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL; + if (bButtons) + nFlags |= WB_HASBUTTONS|WB_HASBUTTONSATROOT; + + SetStyle( nFlags ); +} + +void ScContentTree::SetRootType( sal_uInt16 nNew ) +{ + if ( nNew != nRootType ) + { + nRootType = nNew; + InitWindowBits( nNew == 0 ); + Refresh(); + + ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg(); + rCfg.SetRootType( nRootType ); + } +} + +void ScContentTree::ToggleRoot() // nach Selektion +{ + sal_uInt16 nNew = SC_CONTENT_ROOT; + if ( nRootType == SC_CONTENT_ROOT ) + { + SvLBoxEntry* pEntry = GetCurEntry(); + if (pEntry) + { + SvLBoxEntry* pParent = GetParent(pEntry); + for (sal_uInt16 i=1; i<SC_CONTENT_COUNT; i++) + if ( pEntry == pRootNodes[i] || pParent == pRootNodes[i] ) + nNew = i; + } + } + + SetRootType( nNew ); +} + +void ScContentTree::ResetManualDoc() +{ + aManualDoc.Erase(); + bHiddenDoc = false; + + ActiveDocChanged(); +} + +void ScContentTree::ActiveDocChanged() +{ + if ( !bHiddenDoc && !aManualDoc.Len() ) + Refresh(); // Inhalte nur wenn automatisch + + // Listbox muss immer geupdated werden, wegen aktiv-Flag + + String aCurrent; + if ( bHiddenDoc ) + aCurrent = aHiddenTitle; + else + { + ScDocShell* pSh = GetManualOrCurrent(); + if (pSh) + aCurrent = pSh->GetTitle(); + else + { + // eingestelltes Dokument existiert nicht mehr + + aManualDoc.Erase(); // wieder automatisch + Refresh(); + pSh = GetManualOrCurrent(); // sollte jetzt aktives sein + if (pSh) + aCurrent = pSh->GetTitle(); + } + } + pParentWindow->GetDocNames( &aCurrent ); // selektieren +} + +void ScContentTree::SetManualDoc(const String& rName) +{ + aManualDoc = rName; + if (!bHiddenDoc) + { + Refresh(); + pParentWindow->GetDocNames( &aManualDoc ); // selektieren + } +} + +void ScContentTree::SelectDoc(const String& rName) // rName wie im Menue/Listbox angezeigt +{ + if ( rName == pParentWindow->aStrActiveWin ) + { + ResetManualDoc(); + return; + } + + // "aktiv" oder "inaktiv" weglassen + + String aRealName = rName; + xub_StrLen nLen = rName.Len(); + xub_StrLen nActiveStart = nLen - pParentWindow->aStrActive.Len(); + if ( rName.Copy( nActiveStart ) == pParentWindow->aStrActive ) + aRealName = rName.Copy( 0, nActiveStart ); + xub_StrLen nNotActiveStart = nLen - pParentWindow->aStrNotActive.Len(); + if ( rName.Copy( nNotActiveStart ) == pParentWindow->aStrNotActive ) + aRealName = rName.Copy( 0, nNotActiveStart ); + + sal_Bool bLoaded = false; + + // ist es ein normal geladenes Doc ? + + SfxObjectShell* pSh = SfxObjectShell::GetFirst(); + while ( pSh && !bLoaded ) + { + if ( pSh->ISA(ScDocShell) ) + if ( pSh->GetTitle() == aRealName ) + bLoaded = sal_True; + pSh = SfxObjectShell::GetNext( *pSh ); + } + + if (bLoaded) + { + bHiddenDoc = false; + SetManualDoc(aRealName); + } + else if (aHiddenTitle.Len()) // verstecktes ausgewaehlt + { + if (!bHiddenDoc) + LoadFile(aHiddenName); + } + else + { + OSL_FAIL("SelectDoc: nicht gefunden"); + } +} + +void ScContentTree::ApplySettings() +{ + const ScNavigatorSettings* pSettings = pParentWindow->GetNavigatorSettings(); + if( pSettings ) + { + sal_uInt16 nRootSel = pSettings->GetRootSelected(); + sal_uLong nChildSel = pSettings->GetChildSelected(); + + for( sal_uInt16 nEntry = 1; nEntry < SC_CONTENT_COUNT; ++nEntry ) + { + if( pRootNodes[ nEntry ] ) + { + // expand + sal_Bool bExp = pSettings->IsExpanded( nEntry ); + if( bExp != IsExpanded( pRootNodes[ nEntry ] ) ) + { + if( bExp ) + Expand( pRootNodes[ nEntry ] ); + else + Collapse( pRootNodes[ nEntry ] ); + } + + // select + if( nRootSel == nEntry ) + { + SvLBoxEntry* pEntry = NULL; + if( bExp && (nChildSel != SC_CONTENT_NOCHILD) ) + pEntry = GetEntry( pRootNodes[ nEntry ], nChildSel ); + Select( pEntry ? pEntry : pRootNodes[ nEntry ] ); + } + } + } + } +} + +void ScContentTree::StoreSettings() const +{ + ScNavigatorSettings* pSettings = pParentWindow->GetNavigatorSettings(); + if( pSettings ) + { + for( sal_uInt16 nEntry = 1; nEntry < SC_CONTENT_COUNT; ++nEntry ) + { + sal_Bool bExp = pRootNodes[ nEntry ] && IsExpanded( pRootNodes[ nEntry ] ); + pSettings->SetExpanded( nEntry, bExp ); + } + sal_uInt16 nRoot; + sal_uLong nChild; + GetEntryIndexes( nRoot, nChild, GetCurEntry() ); + pSettings->SetRootSelected( nRoot ); + pSettings->SetChildSelected( nChild ); + } +} + + +// +//------------------------------------------------------------------------ +// + + + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |