1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svx/svditer.hxx>
21 #include <svx/svdobj.hxx>
22 #include <svx/svdpage.hxx>
23 #include <svx/svdpagv.hxx>
24 #include <svx/svdview.hxx>
25 #include <svx/svdxcgv.hxx>
26 #include <sfx2/linkmgr.hxx>
27 #include <sfx2/docfile.hxx>
28 #include <sfx2/viewfrm.hxx>
29 #include <vcl/help.hxx>
30 #include <vcl/svapp.hxx>
31 #include <tools/urlobj.hxx>
32 #include <svl/urlbmk.hxx>
33 #include "svtools/svlbitm.hxx"
36 #include "content.hxx"
41 #include "rangenam.hxx"
43 #include "tablink.hxx"
44 #include "popmenu.hxx"
45 #include "drwlayer.hxx"
46 #include "transobj.hxx"
47 #include "drwtrans.hxx"
48 #include "lnktrans.hxx"
49 #include "formulacell.hxx"
50 #include "dociter.hxx"
51 #include "scresid.hxx"
52 #include "globstr.hrc"
54 #include "arealink.hxx"
55 #include "navicfg.hxx"
56 #include "navsett.hxx"
58 #include "clipparam.hxx"
59 #include "markdata.hxx"
61 using namespace com::sun::star
;
63 // Reihenfolge der Kategorien im Navigator -------------------------------------
65 static const sal_uInt16 pTypeList
[SC_CONTENT_COUNT
] =
67 SC_CONTENT_ROOT
, // ROOT (0) muss vorne stehen
78 sal_Bool
ScContentTree::bIsInDrag
= false;
81 ScDocShell
* ScContentTree::GetManualOrCurrent()
83 ScDocShell
* pSh
= NULL
;
84 if ( !aManualDoc
.isEmpty() )
86 TypeId aScType
= TYPE(ScDocShell
);
87 SfxObjectShell
* pObjSh
= SfxObjectShell::GetFirst( &aScType
);
88 while ( pObjSh
&& !pSh
)
90 if ( pObjSh
->GetTitle() == aManualDoc
)
91 pSh
= PTR_CAST( ScDocShell
, pObjSh
);
92 pObjSh
= SfxObjectShell::GetNext( *pObjSh
, &aScType
);
97 // Current nur, wenn keine manuell eingestellt ist
98 // (damit erkannt wird, wenn das Dokument nicht mehr existiert)
100 SfxViewShell
* pViewSh
= SfxViewShell::Current();
103 SfxObjectShell
* pObjSh
= pViewSh
->GetViewFrame()->GetObjectShell();
104 pSh
= PTR_CAST( ScDocShell
, pObjSh
);
115 ScContentTree::ScContentTree( Window
* pParent
, const ResId
& rResId
) :
116 SvTreeListBox ( pParent
, rResId
),
117 aEntryImages ( ScResId( RID_IMAGELIST_NAVCONT
) ),
118 nRootType ( SC_CONTENT_ROOT
),
119 bHiddenDoc ( false ),
120 pHiddenDocument ( NULL
)
123 for (i
=0; i
<SC_CONTENT_COUNT
; i
++)
124 pPosList
[pTypeList
[i
]] = i
; // invers zum suchen
126 pParentWindow
= (ScNavigatorDlg
*)pParent
;
128 pRootNodes
[0] = NULL
;
129 for (i
=1; i
<SC_CONTENT_COUNT
; i
++)
132 SetNodeDefaultImages();
134 SetDoubleClickHdl( LINK( this, ScContentTree
, ContentDoubleClickHdl
) );
136 SetStyle( GetStyle() | WB_QUICK_SEARCH
);
139 ScContentTree::~ScContentTree()
143 void ScContentTree::InitRoot( sal_uInt16 nType
)
148 if ( nRootType
&& nRootType
!= nType
) // ausgeblendet ?
150 pRootNodes
[nType
] = NULL
;
154 const Image
& rImage
= aEntryImages
.GetImage( nType
);
155 OUString
aName( ScResId( SCSTR_CONTENT_ROOT
+ nType
) );
156 // wieder an die richtige Position:
157 sal_uInt16 nPos
= nRootType
? 0 : pPosList
[nType
]-1;
158 SvTreeListEntry
* pNew
= InsertEntry( aName
, rImage
, rImage
, NULL
, false, nPos
);
160 pRootNodes
[nType
] = pNew
;
163 void ScContentTree::ClearAll()
166 for (sal_uInt16 i
=1; i
<SC_CONTENT_COUNT
; i
++)
170 void ScContentTree::ClearType(sal_uInt16 nType
)
176 SvTreeListEntry
* pParent
= pRootNodes
[nType
];
177 if ( !pParent
|| GetChildCount(pParent
) ) // nicht, wenn ohne Children schon da
180 GetModel()->Remove( pParent
); // mit allen Children
181 InitRoot( nType
); // ggf. neu eintragen
186 void ScContentTree::InsertContent( sal_uInt16 nType
, const OUString
& rValue
)
188 if (nType
>= SC_CONTENT_COUNT
)
190 OSL_FAIL("ScContentTree::InsertContent mit falschem Typ");
194 SvTreeListEntry
* pParent
= pRootNodes
[nType
];
196 InsertEntry( rValue
, pParent
);
199 OSL_FAIL("InsertContent ohne Parent");
203 void ScContentTree::GetEntryIndexes( sal_uInt16
& rnRootIndex
, sal_uLong
& rnChildIndex
, SvTreeListEntry
* pEntry
) const
205 rnRootIndex
= SC_CONTENT_ROOT
;
206 rnChildIndex
= SC_CONTENT_NOCHILD
;
211 SvTreeListEntry
* pParent
= GetParent( pEntry
);
213 for( sal_uInt16 nRoot
= 1; !bFound
&& (nRoot
< SC_CONTENT_COUNT
); ++nRoot
)
215 if( pEntry
== pRootNodes
[ nRoot
] )
221 else if( pParent
&& (pParent
== pRootNodes
[ nRoot
]) )
225 // search the entry in all child entries of the parent
226 sal_uLong nEntry
= 0;
227 SvTreeListEntry
* pIterEntry
= FirstChild( pParent
);
228 while( !bFound
&& pIterEntry
)
230 if ( pEntry
== pIterEntry
)
232 rnChildIndex
= nEntry
;
233 bFound
= true; // exit the while loop
235 pIterEntry
= NextSibling( pIterEntry
);
239 bFound
= true; // exit the for loop
244 sal_uLong
ScContentTree::GetChildIndex( SvTreeListEntry
* pEntry
) const
248 GetEntryIndexes( nRoot
, nChild
, pEntry
);
252 static OUString
lcl_GetDBAreaRange( ScDocument
* pDoc
, const OUString
& rDBName
)
257 ScDBCollection
* pDbNames
= pDoc
->GetDBCollection();
258 const ScDBData
* pData
= pDbNames
->getNamedDBs().findByUpperName(ScGlobal::pCharClass
->uppercase(rDBName
));
262 pData
->GetArea(aRange
);
263 aRet
= aRange
.Format(SCR_ABS_3D
, pDoc
);
269 IMPL_LINK_NOARG(ScContentTree
, ContentDoubleClickHdl
)
273 SvTreeListEntry
* pEntry
= GetCurEntry();
274 GetEntryIndexes( nType
, nChild
, pEntry
);
276 if( pEntry
&& (nType
!= SC_CONTENT_ROOT
) && (nChild
!= SC_CONTENT_NOCHILD
) )
279 return 0; //! spaeter...
281 OUString
aText( GetEntryText( pEntry
) );
283 if ( !aManualDoc
.isEmpty() )
284 pParentWindow
->SetCurrentDoc( aManualDoc
);
288 case SC_CONTENT_TABLE
:
289 pParentWindow
->SetCurrentTableStr( aText
);
292 case SC_CONTENT_RANGENAME
:
293 pParentWindow
->SetCurrentCellStr( aText
);
296 case SC_CONTENT_DBAREA
:
298 // Wenn gleiche Bereichs- und DB-Namen existieren, wird
299 // bei SID_CURRENTCELL der Bereichsname genommen.
300 // DB-Bereiche darum direkt ueber die Adresse anspringen.
302 OUString aRangeStr
= lcl_GetDBAreaRange( GetSourceDocument(), aText
);
303 if (!aRangeStr
.isEmpty())
304 pParentWindow
->SetCurrentCellStr( aRangeStr
);
308 case SC_CONTENT_OLEOBJECT
:
309 case SC_CONTENT_GRAPHIC
:
310 case SC_CONTENT_DRAWING
:
311 pParentWindow
->SetCurrentObject( aText
);
314 case SC_CONTENT_NOTE
:
316 ScAddress aPos
= GetNotePos( nChild
);
317 pParentWindow
->SetCurrentTable( aPos
.Tab() );
318 pParentWindow
->SetCurrentCell( aPos
.Col(), aPos
.Row() );
322 case SC_CONTENT_AREALINK
:
324 const ScAreaLink
* pLink
= GetLink( nChild
);
327 ScRange aRange
= pLink
->GetDestArea();
328 ScDocument
* pSrcDoc
= GetSourceDocument();
329 OUString
aRangeStr(aRange
.Format(SCR_ABS_3D
, pSrcDoc
, pSrcDoc
->GetAddressConvention()));
330 pParentWindow
->SetCurrentCellStr( aRangeStr
);
336 ScNavigatorDlg::ReleaseFocus(); // set focus into document
342 void ScContentTree::MouseButtonDown( const MouseEvent
& rMEvt
)
344 SvTreeListBox::MouseButtonDown( rMEvt
);
348 void ScContentTree::KeyInput( const KeyEvent
& rKEvt
)
352 const KeyCode aCode
= rKEvt
.GetKeyCode();
353 if (aCode
.GetCode() == KEY_RETURN
)
355 switch (aCode
.GetModifier())
358 ToggleRoot(); // toggle root mode (as in Writer)
363 SvTreeListEntry
* pEntry
= GetCurEntry();
368 GetEntryIndexes( nType
, nChild
, pEntry
);
370 if( (nType
!= SC_CONTENT_ROOT
) && (nChild
== SC_CONTENT_NOCHILD
) )
372 if ( IsExpanded( pEntry
) )
378 ContentDoubleClickHdl(0); // select content as if double clicked
389 SvTreeListBox::KeyInput(rKEvt
);
392 sal_Int8
ScContentTree::AcceptDrop( const AcceptDropEvent
& /* rEvt */ )
394 return DND_ACTION_NONE
;
397 sal_Int8
ScContentTree::ExecuteDrop( const ExecuteDropEvent
& /* rEvt */ )
399 return DND_ACTION_NONE
;
402 void ScContentTree::StartDrag( sal_Int8
/* nAction */, const Point
& /* rPosPixel */ )
407 void ScContentTree::DragFinished( sal_Int8
/* nAction */ )
411 void ScContentTree::Command( const CommandEvent
& rCEvt
)
415 switch ( rCEvt
.GetCommand() )
417 case COMMAND_STARTDRAG
:
418 // Aus dem ExecuteDrag heraus kann der Navigator geloescht werden
419 // (beim Umschalten auf einen anderen Dokument-Typ), das wuerde aber
420 // den StarView MouseMove-Handler, der Command() aufruft, umbringen.
421 // Deshalb Drag&Drop asynchron:
423 Application::PostUserEvent( STATIC_LINK( this, ScContentTree
, ExecDragHdl
) );
428 case COMMAND_CONTEXTMENU
:
433 ScPopupMenu
aDropMenu( ScResId( RID_POPUP_DROPMODE
) );
434 aDropMenu
.CheckItem( RID_DROPMODE_URL
+ pParentWindow
->GetDropMode() );
435 aPop
.InsertItem( 1, pParentWindow
->GetStrDragMode() );
436 aPop
.SetPopupMenu( 1, &aDropMenu
);
438 // angezeigtes Dokument
440 ScPopupMenu aDocMenu
;
441 aDocMenu
.SetMenuFlags( aDocMenu
.GetMenuFlags() | MENU_FLAG_NOAUTOMNEMONICS
);
444 // geladene Dokumente
445 ScDocShell
* pCurrentSh
= PTR_CAST( ScDocShell
, SfxObjectShell::Current() );
446 SfxObjectShell
* pSh
= SfxObjectShell::GetFirst();
449 if ( pSh
->ISA(ScDocShell
) )
451 OUString aName
= pSh
->GetTitle();
452 OUString aEntry
= aName
;
453 if ( pSh
== pCurrentSh
)
454 aEntry
+= pParentWindow
->aStrActive
;
456 aEntry
+= pParentWindow
->aStrNotActive
;
457 aDocMenu
.InsertItem( ++i
, aEntry
);
458 if ( !bHiddenDoc
&& aName
== aManualDoc
)
461 pSh
= SfxObjectShell::GetNext( *pSh
);
464 aDocMenu
.InsertItem( ++i
, pParentWindow
->aStrActiveWin
);
465 if (!bHiddenDoc
&& aManualDoc
.isEmpty())
467 // verstecktes Dokument
468 if ( !aHiddenTitle
.isEmpty() )
470 OUString aEntry
= aHiddenTitle
;
471 aEntry
+= pParentWindow
->aStrHidden
;
472 aDocMenu
.InsertItem( ++i
, aEntry
);
476 aDocMenu
.CheckItem( nPos
);
477 aPop
.InsertItem( 2, pParentWindow
->GetStrDisplay() );
478 aPop
.SetPopupMenu( 2, &aDocMenu
);
482 aPop
.Execute( this, rCEvt
.GetMousePosPixel() );
484 if ( aDropMenu
.WasHit() ) // Drag-Drop Modus
486 sal_uInt16 nId
= aDropMenu
.GetSelected();
487 if ( nId
>= RID_DROPMODE_URL
&& nId
<= RID_DROPMODE_COPY
)
488 pParentWindow
->SetDropMode( nId
- RID_DROPMODE_URL
);
490 else if ( aDocMenu
.WasHit() ) // angezeigtes Dokument
492 sal_uInt16 nId
= aDocMenu
.GetSelected();
493 OUString aName
= aDocMenu
.GetItemText(nId
);
501 SvTreeListBox::Command(rCEvt
);
504 void ScContentTree::RequestHelp( const HelpEvent
& rHEvt
)
507 if( rHEvt
.GetMode() & HELPMODE_QUICK
)
509 Point
aPos( ScreenToOutputPixel( rHEvt
.GetMousePosPixel() ));
510 SvTreeListEntry
* pEntry
= GetEntry( aPos
);
515 SvTreeListEntry
* pParent
= GetParent(pEntry
);
516 if ( !pParent
) // Top-Level ?
518 aHelpText
= OUString::number( GetChildCount(pEntry
) ) +
519 " " + GetEntryText(pEntry
);
522 else if ( pParent
== pRootNodes
[SC_CONTENT_NOTE
] )
524 aHelpText
= GetEntryText(pEntry
); // Notizen als Help-Text
527 else if ( pParent
== pRootNodes
[SC_CONTENT_AREALINK
] )
529 sal_uLong nIndex
= GetChildIndex(pEntry
);
530 if( nIndex
!= SC_CONTENT_NOCHILD
)
532 const ScAreaLink
* pLink
= GetLink(nIndex
);
535 aHelpText
= pLink
->GetFile(); // Source-Datei als Help-Text
544 SvLBoxString
* pItem
= (SvLBoxString
*)(GetItem( pEntry
, aPos
.X(), &pTab
));
547 aPos
= GetEntryPosition( pEntry
);
548 aPos
.X() = GetTabPos( pEntry
, pTab
);
549 aPos
= OutputToScreenPixel(aPos
);
550 Size
aSize( pItem
->GetSize( this, pEntry
) );
552 Rectangle
aItemRect( aPos
, aSize
);
553 Help::ShowQuickHelp( this, aItemRect
, aHelpText
);
560 Window::RequestHelp( rHEvt
);
563 ScDocument
* ScContentTree::GetSourceDocument()
566 return pHiddenDocument
;
569 ScDocShell
* pSh
= GetManualOrCurrent();
571 return pSh
->GetDocument();
577 void ScContentTree::Refresh( sal_uInt16 nType
)
579 if ( bHiddenDoc
&& !pHiddenDocument
)
580 return; // anderes Dokument angezeigt
582 // wenn sich nichts geaendert hat, gleich abbrechen (gegen Geflacker)
584 if ( nType
== SC_CONTENT_NOTE
)
585 if (!NoteStringsChanged())
587 if ( nType
== SC_CONTENT_GRAPHIC
)
588 if (!DrawNamesChanged(SC_CONTENT_GRAPHIC
))
590 if ( nType
== SC_CONTENT_OLEOBJECT
)
591 if (!DrawNamesChanged(SC_CONTENT_OLEOBJECT
))
593 if ( nType
== SC_CONTENT_DRAWING
)
594 if (!DrawNamesChanged(SC_CONTENT_DRAWING
))
597 SetUpdateMode(false);
601 if ( !nType
|| nType
== SC_CONTENT_TABLE
)
603 if ( !nType
|| nType
== SC_CONTENT_RANGENAME
)
605 if ( !nType
|| nType
== SC_CONTENT_DBAREA
)
607 if ( !nType
|| nType
== SC_CONTENT_GRAPHIC
)
609 if ( !nType
|| nType
== SC_CONTENT_OLEOBJECT
)
611 if ( !nType
|| nType
== SC_CONTENT_DRAWING
)
613 if ( !nType
|| nType
== SC_CONTENT_NOTE
)
615 if ( !nType
|| nType
== SC_CONTENT_AREALINK
)
619 SetUpdateMode(sal_True
);
622 void ScContentTree::GetTableNames()
624 if ( nRootType
&& nRootType
!= SC_CONTENT_TABLE
) // ausgeblendet ?
627 ScDocument
* pDoc
= GetSourceDocument();
632 SCTAB nCount
= pDoc
->GetTableCount();
633 for ( SCTAB i
=0; i
<nCount
; i
++ )
635 pDoc
->GetName( i
, aName
);
636 InsertContent( SC_CONTENT_TABLE
, aName
);
642 OUString
createLocalRangeName(const OUString
& rName
, const OUString
& rTableName
)
644 OUStringBuffer
aString (rName
);
645 aString
.append(OUString(" ("));
646 aString
.append(rTableName
);
647 aString
.append(OUString(")"));
648 return aString
.makeStringAndClear();
652 void ScContentTree::GetAreaNames()
654 if ( nRootType
&& nRootType
!= SC_CONTENT_RANGENAME
) // ausgeblendet ?
657 ScDocument
* pDoc
= GetSourceDocument();
662 std::set
<OUString
> aSet
;
663 ScRangeName
* pRangeNames
= pDoc
->GetRangeName();
664 if (!pRangeNames
->empty())
666 ScRangeName::const_iterator itrBeg
= pRangeNames
->begin(), itrEnd
= pRangeNames
->end();
667 for (ScRangeName::const_iterator itr
= itrBeg
; itr
!= itrEnd
; ++itr
)
669 if (itr
->second
->IsValidReference(aDummy
))
670 aSet
.insert(itr
->second
->GetName());
673 for (SCTAB i
= 0; i
< pDoc
->GetTableCount(); ++i
)
675 ScRangeName
* pLocalRangeName
= pDoc
->GetRangeName(i
);
676 if (pLocalRangeName
&& !pLocalRangeName
->empty())
679 pDoc
->GetName(i
, aTableName
);
680 for (ScRangeName::const_iterator itr
= pLocalRangeName
->begin(); itr
!= pLocalRangeName
->end(); ++itr
)
682 if (itr
->second
->IsValidReference(aDummy
))
683 aSet
.insert(createLocalRangeName(itr
->second
->GetName(), aTableName
));
690 for (std::set
<OUString
>::iterator itr
= aSet
.begin();
691 itr
!= aSet
.end(); ++itr
)
693 InsertContent(SC_CONTENT_RANGENAME
, *itr
);
698 void ScContentTree::GetDbNames()
700 if ( nRootType
&& nRootType
!= SC_CONTENT_DBAREA
) // ausgeblendet ?
703 ScDocument
* pDoc
= GetSourceDocument();
707 ScDBCollection
* pDbNames
= pDoc
->GetDBCollection();
708 const ScDBCollection::NamedDBs
& rDBs
= pDbNames
->getNamedDBs();
709 ScDBCollection::NamedDBs::const_iterator itr
= rDBs
.begin(), itrEnd
= rDBs
.end();
710 for (; itr
!= itrEnd
; ++itr
)
712 const OUString
& aStrName
= itr
->GetName();
713 InsertContent(SC_CONTENT_DBAREA
, aStrName
);
717 bool ScContentTree::IsPartOfType( sal_uInt16 nContentType
, sal_uInt16 nObjIdentifier
)
720 switch ( nContentType
)
722 case SC_CONTENT_GRAPHIC
:
723 bRet
= ( nObjIdentifier
== OBJ_GRAF
);
725 case SC_CONTENT_OLEOBJECT
:
726 bRet
= ( nObjIdentifier
== OBJ_OLE2
);
728 case SC_CONTENT_DRAWING
:
729 bRet
= ( nObjIdentifier
!= OBJ_GRAF
&& nObjIdentifier
!= OBJ_OLE2
); // everything else
732 OSL_FAIL("unknown content type");
737 void ScContentTree::GetDrawNames( sal_uInt16 nType
)
739 if ( nRootType
&& nRootType
!= nType
) // ausgeblendet ?
742 ScDocument
* pDoc
= GetSourceDocument();
746 // iterate in flat mode for groups
747 SdrIterMode eIter
= ( nType
== SC_CONTENT_DRAWING
) ? IM_FLAT
: IM_DEEPNOGROUPS
;
749 ScDrawLayer
* pDrawLayer
= pDoc
->GetDrawLayer();
750 SfxObjectShell
* pShell
= pDoc
->GetDocumentShell();
751 if (pDrawLayer
&& pShell
)
753 SCTAB nTabCount
= pDoc
->GetTableCount();
754 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
756 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
757 OSL_ENSURE(pPage
,"Page ?");
760 SdrObjListIter
aIter( *pPage
, eIter
);
761 SdrObject
* pObject
= aIter
.Next();
764 if ( IsPartOfType( nType
, pObject
->GetObjIdentifier() ) )
766 OUString aName
= ScDrawLayer::GetVisibleName( pObject
);
767 if (!aName
.isEmpty())
768 InsertContent( nType
, aName
);
771 pObject
= aIter
.Next();
778 void ScContentTree::GetGraphicNames()
780 GetDrawNames( SC_CONTENT_GRAPHIC
);
783 void ScContentTree::GetOleNames()
785 GetDrawNames( SC_CONTENT_OLEOBJECT
);
788 void ScContentTree::GetDrawingNames()
790 GetDrawNames( SC_CONTENT_DRAWING
);
793 void ScContentTree::GetLinkNames()
795 if ( nRootType
&& nRootType
!= SC_CONTENT_AREALINK
) // ausgeblendet ?
798 ScDocument
* pDoc
= GetSourceDocument();
802 sfx2::LinkManager
* pLinkManager
= pDoc
->GetLinkManager();
803 OSL_ENSURE(pLinkManager
, "kein LinkManager am Dokument?");
804 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
805 sal_uInt16 nCount
= rLinks
.size();
806 for (sal_uInt16 i
=0; i
<nCount
; i
++)
808 ::sfx2::SvBaseLink
* pBase
= *rLinks
[i
];
809 if (pBase
->ISA(ScAreaLink
))
810 InsertContent( SC_CONTENT_AREALINK
, ((ScAreaLink
*)pBase
)->GetSource() );
812 // in der Liste die Namen der Quellbereiche
816 const ScAreaLink
* ScContentTree::GetLink( sal_uLong nIndex
)
818 ScDocument
* pDoc
= GetSourceDocument();
822 sal_uLong nFound
= 0;
823 sfx2::LinkManager
* pLinkManager
= pDoc
->GetLinkManager();
824 OSL_ENSURE(pLinkManager
, "kein LinkManager am Dokument?");
825 const ::sfx2::SvBaseLinks
& rLinks
= pLinkManager
->GetLinks();
826 sal_uInt16 nCount
= rLinks
.size();
827 for (sal_uInt16 i
=0; i
<nCount
; i
++)
829 ::sfx2::SvBaseLink
* pBase
= *rLinks
[i
];
830 if (pBase
->ISA(ScAreaLink
))
832 if (nFound
== nIndex
)
833 return (const ScAreaLink
*) pBase
;
838 OSL_FAIL("link not found");
842 static OUString
lcl_NoteString( const ScPostIt
& rNote
)
844 OUString aText
= rNote
.GetText();
846 while ( (nAt
= aText
.indexOf( '\n' )) != -1 )
847 aText
= aText
.replaceAt( nAt
, 1, " " );
851 void ScContentTree::GetNoteStrings()
853 if ( nRootType
&& nRootType
!= SC_CONTENT_NOTE
) // ausgeblendet ?
856 ScDocument
* pDoc
= GetSourceDocument();
860 // loop over cell notes
861 std::vector
<sc::NoteEntry
> aEntries
;
862 pDoc
->GetAllNoteEntries(aEntries
);
863 std::vector
<sc::NoteEntry
>::const_iterator it
= aEntries
.begin(), itEnd
= aEntries
.end();
864 for (; it
!= itEnd
; ++it
)
865 InsertContent(SC_CONTENT_NOTE
, lcl_NoteString(*it
->mpNote
));
868 ScAddress
ScContentTree::GetNotePos( sal_uLong nIndex
)
870 ScDocument
* pDoc
= GetSourceDocument();
874 return pDoc
->GetNotePosition(nIndex
);
877 sal_Bool
ScContentTree::NoteStringsChanged()
879 ScDocument
* pDoc
= GetSourceDocument();
883 SvTreeListEntry
* pParent
= pRootNodes
[SC_CONTENT_NOTE
];
887 SvTreeListEntry
* pEntry
= FirstChild( pParent
);
889 std::vector
<sc::NoteEntry
> aEntries
;
890 pDoc
->GetAllNoteEntries(aEntries
);
891 std::vector
<sc::NoteEntry
>::const_iterator it
= aEntries
.begin(), itEnd
= aEntries
.end();
892 for (; it
!= itEnd
; ++it
)
894 const ScPostIt
* pNote
= it
->mpNote
;
898 if (lcl_NoteString(*pNote
) != GetEntryText(pEntry
))
901 pEntry
= NextSibling(pEntry
);
910 sal_Bool
ScContentTree::DrawNamesChanged( sal_uInt16 nType
)
912 ScDocument
* pDoc
= GetSourceDocument();
916 SvTreeListEntry
* pParent
= pRootNodes
[nType
];
920 SvTreeListEntry
* pEntry
= FirstChild( pParent
);
922 // iterate in flat mode for groups
923 SdrIterMode eIter
= ( nType
== SC_CONTENT_DRAWING
) ? IM_FLAT
: IM_DEEPNOGROUPS
;
925 sal_Bool bEqual
= sal_True
;
926 ScDrawLayer
* pDrawLayer
= pDoc
->GetDrawLayer();
927 SfxObjectShell
* pShell
= pDoc
->GetDocumentShell();
928 if (pDrawLayer
&& pShell
)
930 SCTAB nTabCount
= pDoc
->GetTableCount();
931 for (SCTAB nTab
=0; nTab
<nTabCount
&& bEqual
; nTab
++)
933 SdrPage
* pPage
= pDrawLayer
->GetPage(static_cast<sal_uInt16
>(nTab
));
934 OSL_ENSURE(pPage
,"Page ?");
937 SdrObjListIter
aIter( *pPage
, eIter
);
938 SdrObject
* pObject
= aIter
.Next();
939 while (pObject
&& bEqual
)
941 if ( IsPartOfType( nType
, pObject
->GetObjIdentifier() ) )
947 if ( ScDrawLayer::GetVisibleName( pObject
) != GetEntryText(pEntry
) )
950 pEntry
= NextSibling( pEntry
);
953 pObject
= aIter
.Next();
960 bEqual
= false; // kommt noch was
965 static bool lcl_GetRange( ScDocument
* pDoc
, sal_uInt16 nType
, const OUString
& rName
, ScRange
& rRange
)
969 if ( nType
== SC_CONTENT_RANGENAME
)
971 ScRangeName
* pList
= pDoc
->GetRangeName();
974 const ScRangeData
* p
= pList
->findByUpperName(ScGlobal::pCharClass
->uppercase(rName
));
975 if (p
&& p
->IsValidReference(rRange
))
979 else if ( nType
== SC_CONTENT_DBAREA
)
981 ScDBCollection
* pList
= pDoc
->GetDBCollection();
984 const ScDBData
* p
= pList
->getNamedDBs().findByUpperName(ScGlobal::pCharClass
->uppercase(rName
));
990 p
->GetArea(nTab
, nCol1
, nRow1
, nCol2
, nRow2
);
991 rRange
= ScRange(nCol1
, nRow1
, nTab
, nCol2
, nRow2
, nTab
);
1000 static void lcl_DoDragObject( ScDocShell
* pSrcShell
, const OUString
& rName
, sal_uInt16 nType
, Window
* pWin
)
1002 ScDocument
* pSrcDoc
= pSrcShell
->GetDocument();
1003 ScDrawLayer
* pModel
= pSrcDoc
->GetDrawLayer();
1006 bool bOle
= ( nType
== SC_CONTENT_OLEOBJECT
);
1007 bool bGraf
= ( nType
== SC_CONTENT_GRAPHIC
);
1008 sal_uInt16 nDrawId
= sal::static_int_cast
<sal_uInt16
>( bOle
? OBJ_OLE2
: ( bGraf
? OBJ_GRAF
: OBJ_GRUP
) );
1010 SdrObject
* pObject
= pModel
->GetNamedObject( rName
, nDrawId
, nTab
);
1013 SdrView
aEditView( pModel
);
1014 aEditView
.ShowSdrPage(aEditView
.GetModel()->GetPage(nTab
));
1015 SdrPageView
* pPV
= aEditView
.GetSdrPageView();
1016 aEditView
.MarkObj(pObject
, pPV
);
1018 SdrModel
* pDragModel
= aEditView
.GetMarkedObjModel();
1020 TransferableObjectDescriptor aObjDesc
;
1021 pSrcShell
->FillTransferableObjectDescriptor( aObjDesc
);
1022 aObjDesc
.maDisplayName
= pSrcShell
->GetMedium()->GetURLObject().GetURLNoPass();
1023 // maSize is set in ScDrawTransferObj ctor
1025 ScDrawTransferObj
* pTransferObj
= new ScDrawTransferObj( pDragModel
, pSrcShell
, aObjDesc
);
1026 uno::Reference
<datatransfer::XTransferable
> xTransferable( pTransferObj
);
1028 pTransferObj
->SetDragSourceObj( pObject
, nTab
);
1029 pTransferObj
->SetDragSourceFlags( SC_DROP_NAVIGATOR
);
1031 SC_MOD()->SetDragObject( NULL
, pTransferObj
);
1032 pWin
->ReleaseMouse();
1033 pTransferObj
->StartDrag( pWin
, DND_ACTION_COPYMOVE
| DND_ACTION_LINK
);
1038 static void lcl_DoDragCells( ScDocShell
* pSrcShell
, const ScRange
& rRange
, sal_uInt16 nFlags
, Window
* pWin
)
1041 aMark
.SelectTable( rRange
.aStart
.Tab(), sal_True
);
1042 aMark
.SetMarkArea( rRange
);
1044 ScDocument
* pSrcDoc
= pSrcShell
->GetDocument();
1045 if ( !pSrcDoc
->HasSelectedBlockMatrixFragment( rRange
.aStart
.Col(), rRange
.aStart
.Row(),
1046 rRange
.aEnd
.Col(), rRange
.aEnd
.Row(),
1049 ScDocument
* pClipDoc
= new ScDocument( SCDOCMODE_CLIP
);
1050 ScClipParam
aClipParam(rRange
, false);
1051 pSrcDoc
->CopyToClip(aClipParam
, pClipDoc
, &aMark
);
1052 // pClipDoc->ExtendMerge( rRange, sal_True );
1054 TransferableObjectDescriptor aObjDesc
;
1055 pSrcShell
->FillTransferableObjectDescriptor( aObjDesc
);
1056 aObjDesc
.maDisplayName
= pSrcShell
->GetMedium()->GetURLObject().GetURLNoPass();
1057 // maSize is set in ScTransferObj ctor
1059 ScTransferObj
* pTransferObj
= new ScTransferObj( pClipDoc
, aObjDesc
);
1060 uno::Reference
<datatransfer::XTransferable
> xTransferable( pTransferObj
);
1062 pTransferObj
->SetDragSource( pSrcShell
, aMark
);
1063 pTransferObj
->SetDragSourceFlags( nFlags
);
1065 SC_MOD()->SetDragObject( pTransferObj
, NULL
); // for internal D&D
1066 pWin
->ReleaseMouse();
1067 pTransferObj
->StartDrag( pWin
, DND_ACTION_COPYMOVE
| DND_ACTION_LINK
);
1071 void ScContentTree::DoDrag()
1073 ScDocumentLoader
* pDocLoader
= NULL
;
1074 bIsInDrag
= sal_True
;
1076 ScModule
* pScMod
= SC_MOD();
1080 SvTreeListEntry
* pEntry
= GetCurEntry();
1081 GetEntryIndexes( nType
, nChild
, pEntry
);
1084 (nChild
!= SC_CONTENT_NOCHILD
) &&
1085 (nType
!= SC_CONTENT_ROOT
) &&
1086 (nType
!= SC_CONTENT_NOTE
) &&
1087 (nType
!= SC_CONTENT_AREALINK
) )
1089 OUString
aText( GetEntryText( pEntry
) );
1091 ScDocument
* pLocalDoc
= NULL
; // fuer URL-Drop
1094 aDocName
= aHiddenName
;
1097 ScDocShell
* pDocSh
= GetManualOrCurrent();
1100 if (pDocSh
->HasName())
1101 aDocName
= pDocSh
->GetMedium()->GetName();
1103 pLocalDoc
= pDocSh
->GetDocument(); // Drop nur in dieses Dokument
1107 bool bDoLinkTrans
= false; // use ScLinkTransferObj
1108 OUString aLinkURL
; // for ScLinkTransferObj
1111 sal_uInt16 nDropMode
= pParentWindow
->GetDropMode();
1112 switch ( nDropMode
)
1114 case SC_DROPMODE_URL
:
1116 OUString aUrl
= aDocName
+ "#" + aText
;
1118 pScMod
->SetDragJump( pLocalDoc
, aUrl
, aText
);
1120 if (!aDocName
.isEmpty())
1122 // provide URL to outside only if the document has a name
1123 // (without name, only internal D&D via SetDragJump)
1128 bDoLinkTrans
= true;
1131 case SC_DROPMODE_LINK
:
1133 if ( !aDocName
.isEmpty() ) // link only to named documents
1135 // for internal D&D, set flag to insert a link
1139 case SC_CONTENT_TABLE
:
1140 pScMod
->SetDragLink( aDocName
, aText
, EMPTY_OUSTRING
);
1141 bDoLinkTrans
= true;
1143 case SC_CONTENT_RANGENAME
:
1144 case SC_CONTENT_DBAREA
:
1145 pScMod
->SetDragLink( aDocName
, EMPTY_OUSTRING
, aText
);
1146 bDoLinkTrans
= true;
1149 // other types cannot be linked
1154 case SC_DROPMODE_COPY
:
1156 ScDocShell
* pSrcShell
= NULL
;
1159 OUString aFilter
, aOptions
;
1160 OUString aURL
= aHiddenName
;
1161 pDocLoader
= new ScDocumentLoader( aURL
, aFilter
, aOptions
);
1162 if (!pDocLoader
->IsError())
1163 pSrcShell
= pDocLoader
->GetDocShell();
1166 pSrcShell
= GetManualOrCurrent();
1170 ScDocument
* pSrcDoc
= pSrcShell
->GetDocument();
1171 if ( nType
== SC_CONTENT_RANGENAME
|| nType
== SC_CONTENT_DBAREA
)
1174 if ( lcl_GetRange( pSrcDoc
, nType
, aText
, aRange
) )
1176 lcl_DoDragCells( pSrcShell
, aRange
, SC_DROP_NAVIGATOR
, this );
1179 else if ( nType
== SC_CONTENT_TABLE
)
1182 if ( pSrcDoc
->GetTable( aText
, nTab
) )
1184 ScRange
aRange( 0,0,nTab
, MAXCOL
,MAXROW
,nTab
);
1185 lcl_DoDragCells( pSrcShell
, aRange
, SC_DROP_NAVIGATOR
| SC_DROP_TABLE
, this );
1188 else if ( nType
== SC_CONTENT_GRAPHIC
|| nType
== SC_CONTENT_OLEOBJECT
||
1189 nType
== SC_CONTENT_DRAWING
)
1191 lcl_DoDragObject( pSrcShell
, aText
, nType
, this );
1193 // in ExecuteDrag kann der Navigator geloescht worden sein
1194 // -> nicht mehr auf Member zugreifen !!!
1203 ScLinkTransferObj
* pTransferObj
= new ScLinkTransferObj
;
1204 uno::Reference
<datatransfer::XTransferable
> xTransferable( pTransferObj
);
1206 if ( !aLinkURL
.isEmpty() )
1207 pTransferObj
->SetLinkURL( aLinkURL
, aLinkText
);
1209 // SetDragJump / SetDragLink has been done above
1212 pTransferObj
->StartDrag( this, DND_ACTION_COPYMOVE
| DND_ACTION_LINK
);
1216 bIsInDrag
= false; // static Member
1218 delete pDocLoader
; // falls Dokument zum Draggen geladen wurde
1221 IMPL_STATIC_LINK(ScContentTree
, ExecDragHdl
, void*, EMPTYARG
)
1223 // als Link, damit asynchron ohne ImpMouseMoveMsg auf dem Stack auch der
1224 // Navigator geloescht werden darf
1230 sal_Bool
ScContentTree::LoadFile( const OUString
& rUrl
)
1232 OUString aDocName
= rUrl
;
1233 sal_Int32 nPos
= aDocName
.indexOf('#');
1235 aDocName
= aDocName
.copy(0, nPos
); // nur der Name, ohne #...
1237 sal_Bool bReturn
= false;
1238 OUString aURL
= aDocName
;
1239 OUString aFilter
, aOptions
;
1240 ScDocumentLoader
aLoader( aURL
, aFilter
, aOptions
);
1241 if ( !aLoader
.IsError() )
1243 bHiddenDoc
= sal_True
;
1244 aHiddenName
= aDocName
;
1245 aHiddenTitle
= aLoader
.GetTitle();
1246 pHiddenDocument
= aLoader
.GetDocument();
1248 Refresh(); // Inhalte aus geladenem Dokument holen
1250 pHiddenDocument
= NULL
;
1252 pParentWindow
->GetDocNames( &aHiddenTitle
); // Liste fuellen
1255 // Dokument wird im dtor von ScDocumentLoader wieder geschlossen
1260 void ScContentTree::InitWindowBits( sal_Bool bButtons
)
1262 WinBits nFlags
= GetStyle()|WB_CLIPCHILDREN
|WB_HSCROLL
;
1264 nFlags
|= WB_HASBUTTONS
|WB_HASBUTTONSATROOT
;
1269 void ScContentTree::SetRootType( sal_uInt16 nNew
)
1271 if ( nNew
!= nRootType
)
1274 InitWindowBits( nNew
== 0 );
1277 ScNavipiCfg
& rCfg
= SC_MOD()->GetNavipiCfg();
1278 rCfg
.SetRootType( nRootType
);
1282 void ScContentTree::ToggleRoot() // nach Selektion
1284 sal_uInt16 nNew
= SC_CONTENT_ROOT
;
1285 if ( nRootType
== SC_CONTENT_ROOT
)
1287 SvTreeListEntry
* pEntry
= GetCurEntry();
1290 SvTreeListEntry
* pParent
= GetParent(pEntry
);
1291 for (sal_uInt16 i
=1; i
<SC_CONTENT_COUNT
; i
++)
1292 if ( pEntry
== pRootNodes
[i
] || pParent
== pRootNodes
[i
] )
1297 SetRootType( nNew
);
1300 void ScContentTree::ResetManualDoc()
1308 void ScContentTree::ActiveDocChanged()
1310 if ( !bHiddenDoc
&& aManualDoc
.isEmpty() )
1311 Refresh(); // Inhalte nur wenn automatisch
1313 // Listbox muss immer geupdated werden, wegen aktiv-Flag
1317 aCurrent
= aHiddenTitle
;
1320 ScDocShell
* pSh
= GetManualOrCurrent();
1322 aCurrent
= pSh
->GetTitle();
1325 // eingestelltes Dokument existiert nicht mehr
1327 aManualDoc
= ""; // wieder automatisch
1329 pSh
= GetManualOrCurrent(); // sollte jetzt aktives sein
1331 aCurrent
= pSh
->GetTitle();
1334 pParentWindow
->GetDocNames( &aCurrent
); // selektieren
1337 void ScContentTree::SetManualDoc(const OUString
& rName
)
1343 pParentWindow
->GetDocNames( &aManualDoc
); // selektieren
1347 void ScContentTree::SelectDoc(const OUString
& rName
) // rName wie im Menue/Listbox angezeigt
1349 if ( rName
== pParentWindow
->aStrActiveWin
)
1355 // "aktiv" oder "inaktiv" weglassen
1357 OUString aRealName
= rName
;
1358 sal_Int32 nLen
= rName
.getLength();
1359 sal_Int32 nActiveStart
= nLen
- pParentWindow
->aStrActive
.getLength();
1360 if ( rName
.copy( nActiveStart
) == pParentWindow
->aStrActive
)
1361 aRealName
= rName
.copy( 0, nActiveStart
);
1362 sal_Int32 nNotActiveStart
= nLen
- pParentWindow
->aStrNotActive
.getLength();
1363 if ( rName
.copy( nNotActiveStart
) == pParentWindow
->aStrNotActive
)
1364 aRealName
= rName
.copy( 0, nNotActiveStart
);
1366 bool bLoaded
= false;
1368 // ist es ein normal geladenes Doc ?
1370 SfxObjectShell
* pSh
= SfxObjectShell::GetFirst();
1371 while ( pSh
&& !bLoaded
)
1373 if ( pSh
->ISA(ScDocShell
) )
1374 if ( pSh
->GetTitle() == aRealName
)
1376 pSh
= SfxObjectShell::GetNext( *pSh
);
1382 SetManualDoc(aRealName
);
1384 else if (!aHiddenTitle
.isEmpty()) // verstecktes ausgewaehlt
1387 LoadFile(aHiddenName
);
1391 OSL_FAIL("SelectDoc: nicht gefunden");
1395 void ScContentTree::ApplySettings()
1397 const ScNavigatorSettings
* pSettings
= pParentWindow
->GetNavigatorSettings();
1400 sal_uInt16 nRootSel
= pSettings
->GetRootSelected();
1401 sal_uLong nChildSel
= pSettings
->GetChildSelected();
1403 for( sal_uInt16 nEntry
= 1; nEntry
< SC_CONTENT_COUNT
; ++nEntry
)
1405 if( pRootNodes
[ nEntry
] )
1408 sal_Bool bExp
= pSettings
->IsExpanded( nEntry
);
1409 if( bExp
!= IsExpanded( pRootNodes
[ nEntry
] ) )
1412 Expand( pRootNodes
[ nEntry
] );
1414 Collapse( pRootNodes
[ nEntry
] );
1418 if( nRootSel
== nEntry
)
1420 SvTreeListEntry
* pEntry
= NULL
;
1421 if( bExp
&& (nChildSel
!= SC_CONTENT_NOCHILD
) )
1422 pEntry
= GetEntry( pRootNodes
[ nEntry
], nChildSel
);
1423 Select( pEntry
? pEntry
: pRootNodes
[ nEntry
] );
1430 void ScContentTree::StoreSettings() const
1432 ScNavigatorSettings
* pSettings
= pParentWindow
->GetNavigatorSettings();
1435 for( sal_uInt16 nEntry
= 1; nEntry
< SC_CONTENT_COUNT
; ++nEntry
)
1437 sal_Bool bExp
= pRootNodes
[ nEntry
] && IsExpanded( pRootNodes
[ nEntry
] );
1438 pSettings
->SetExpanded( nEntry
, bExp
);
1442 GetEntryIndexes( nRoot
, nChild
, GetCurEntry() );
1443 pSettings
->SetRootSelected( nRoot
);
1444 pSettings
->SetChildSelected( nChild
);
1450 //------------------------------------------------------------------------
1457 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */