Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / ui / navipi / content.cxx
blob7e7a04380575fed0d1f8dea61f43ebd7f5228eba
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
34 #include <svtools/treelistentry.hxx>
35 #include <stdlib.h>
37 #include "content.hxx"
38 #include "navipi.hxx"
39 #include "global.hxx"
40 #include "docsh.hxx"
41 #include "scmod.hxx"
42 #include "rangenam.hxx"
43 #include "dbdata.hxx"
44 #include "tablink.hxx"
45 #include "popmenu.hxx"
46 #include "drwlayer.hxx"
47 #include "transobj.hxx"
48 #include "drwtrans.hxx"
49 #include "lnktrans.hxx"
50 #include "formulacell.hxx"
51 #include "dociter.hxx"
52 #include "scresid.hxx"
53 #include "globstr.hrc"
54 #include "navipi.hrc"
55 #include "arealink.hxx"
56 #include "navicfg.hxx"
57 #include "navsett.hxx"
58 #include "postit.hxx"
59 #include "tabvwsh.hxx"
60 #include "drawview.hxx"
61 #include "clipparam.hxx"
62 #include "markdata.hxx"
63 #include <o3tl/make_unique.hxx>
64 using namespace com::sun::star;
66 // Reihenfolge der Kategorien im Navigator -------------------------------------
68 static const ScContentId pTypeList[(int)ScContentId::LAST + 1] =
70 ScContentId::ROOT, // ROOT (0) muss vorne stehen
71 ScContentId::TABLE,
72 ScContentId::RANGENAME,
73 ScContentId::DBAREA,
74 ScContentId::AREALINK,
75 ScContentId::GRAPHIC,
76 ScContentId::OLEOBJECT,
77 ScContentId::NOTE,
78 ScContentId::DRAWING
81 bool ScContentTree::bIsInDrag = false;
83 ScDocShell* ScContentTree::GetManualOrCurrent()
85 ScDocShell* pSh = nullptr;
86 if ( !aManualDoc.isEmpty() )
88 SfxObjectShell* pObjSh = SfxObjectShell::GetFirst( checkSfxObjectShell<ScDocShell> );
89 while ( pObjSh && !pSh )
91 if ( pObjSh->GetTitle() == aManualDoc )
92 pSh = dynamic_cast<ScDocShell*>( pObjSh );
93 pObjSh = SfxObjectShell::GetNext( *pObjSh, checkSfxObjectShell<ScDocShell> );
96 else
98 // Current nur, wenn keine manuell eingestellt ist
99 // (damit erkannt wird, wenn das Dokument nicht mehr existiert)
101 SfxViewShell* pViewSh = SfxViewShell::Current();
102 if ( pViewSh )
104 SfxObjectShell* pObjSh = pViewSh->GetViewFrame()->GetObjectShell();
105 pSh = dynamic_cast<ScDocShell*>( pObjSh );
109 return pSh;
112 // ScContentTree
114 ScContentTree::ScContentTree( vcl::Window* pParent, const ResId& rResId ) :
115 SvTreeListBox ( pParent, rResId ),
116 aEntryImages ( ScResId( RID_IMAGELIST_NAVCONT ) ),
117 nRootType ( ScContentId::ROOT ),
118 bHiddenDoc ( false ),
119 pHiddenDocument ( nullptr ),
120 bisInNavigatoeDlg ( false )
122 sal_uInt16 i;
123 for (i=0; i<=(int)ScContentId::LAST; i++)
124 pPosList[pTypeList[i]] = i; // invers zum suchen
126 pParentWindow = static_cast<ScNavigatorDlg*>(pParent);
128 pRootNodes[ScContentId::ROOT] = nullptr;
129 for (i=1; i<(int)ScContentId::LAST; i++)
130 InitRoot((ScContentId)i);
132 SetNodeDefaultImages();
134 SetDoubleClickHdl( LINK( this, ScContentTree, ContentDoubleClickHdl ) );
136 pTmpEntry= nullptr;
137 m_bFirstPaint=true;
139 SetStyle( GetStyle() | WB_QUICK_SEARCH );
142 ScContentTree::~ScContentTree()
144 disposeOnce();
147 void ScContentTree::dispose()
149 pParentWindow.clear();
150 SvTreeListBox::dispose();
153 // helper function for GetEntryAltText and GetEntryLongDescription
154 OUString ScContentTree::getAltLongDescText( SvTreeListEntry* pEntry, bool isAltText) const
157 ScContentId nType;
158 sal_uLong nChild;
159 GetEntryIndexes( nType, nChild, pEntry );
160 switch( nType )
162 case ScContentId::OLEOBJECT:
163 case ScContentId::GRAPHIC:
164 case ScContentId::DRAWING:
166 SdrObject* pFound = nullptr;
167 ScDocument* pDoc = ( const_cast< ScContentTree* >(this) )->GetSourceDocument();
168 SdrIterMode eIter = ( nType == ScContentId::DRAWING ) ? IM_FLAT : IM_DEEPNOGROUPS;
169 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
170 SfxObjectShell* pShell = pDoc->GetDocumentShell();
171 if (pDrawLayer && pShell)
173 sal_uInt16 nTabCount = pDoc->GetTableCount();
174 for (sal_uInt16 nTab=0; nTab<nTabCount; nTab++)
176 SdrPage* pPage = pDrawLayer->GetPage(nTab);
177 DBG_ASSERT(pPage,"Page ?");
178 if (pPage)
180 SdrObjListIter aIter( *pPage, eIter );
181 SdrObject* pObject = aIter.Next();
182 while (pObject)
184 if( ScDrawLayer::GetVisibleName( pObject ) == GetEntryText( pEntry ) )
186 pFound = pObject;
187 break;
189 pObject = aIter.Next();
194 if( pFound )
196 if( isAltText )
197 return pFound->GetTitle();
198 else
199 return pFound->GetDescription();
202 break;
203 default: break;
205 return OUString();
208 OUString ScContentTree::GetEntryAltText( SvTreeListEntry* pEntry ) const
210 return getAltLongDescText( pEntry, true );
213 OUString ScContentTree::GetEntryLongDescription( SvTreeListEntry* pEntry ) const
215 return getAltLongDescText( pEntry, false );
218 void ScContentTree::InitRoot( ScContentId nType )
220 if ( nType == ScContentId::ROOT )
221 return;
223 if ( nRootType != ScContentId::ROOT && nRootType != nType ) // ausgeblendet ?
225 pRootNodes[nType] = nullptr;
226 return;
229 const Image& rImage = aEntryImages.GetImage( (int) nType );
230 OUString aName( ScResId( SCSTR_CONTENT_ROOT + (int)nType ) );
231 // wieder an die richtige Position:
232 sal_uInt16 nPos = nRootType != ScContentId::ROOT ? 0 : pPosList[nType]-1;
233 SvTreeListEntry* pNew = InsertEntry( aName, rImage, rImage, nullptr, false, nPos );
235 pRootNodes[nType] = pNew;
238 void ScContentTree::ClearAll()
240 //There are one method in Control::SetUpdateMode(), and one override method SvTreeListBox::SetUpdateMode(). Here although
241 //SvTreeListBox::SetUpdateMode() is called in refresh method, it only call SvTreeListBox::SetUpdateMode(), not Control::SetUpdateMode().
242 //In SvTreeList::Clear(), Broadcast( LISTACTION_CLEARED ) will be called and finally, it will be trapped into the event yield() loop. And
243 //the InitRoot() method won't be called. Then if a user click or press key to update the navigator tree, crash happens.
244 //So the solution is to disable the UpdateMode of Control, then call Clear(), then recover the update mode
245 bool bOldUpdate = Control::IsUpdateMode();
246 Control::SetUpdateMode(false);
247 Clear();
248 Control::SetUpdateMode(bOldUpdate);
249 for (sal_uInt16 i=1; i<=(int)ScContentId::LAST; i++)
250 InitRoot((ScContentId)i);
253 void ScContentTree::ClearType(ScContentId nType)
255 if (nType == ScContentId::ROOT)
256 ClearAll();
257 else
259 SvTreeListEntry* pParent = pRootNodes[nType];
260 if ( !pParent || GetChildCount(pParent) ) // nicht, wenn ohne Children schon da
262 if (pParent)
263 GetModel()->Remove( pParent ); // mit allen Children
264 InitRoot( nType ); // ggf. neu eintragen
269 void ScContentTree::InsertContent( ScContentId nType, const OUString& rValue )
271 SvTreeListEntry* pParent = pRootNodes[nType];
272 if (pParent)
273 InsertEntry( rValue, pParent );
274 else
276 OSL_FAIL("InsertContent ohne Parent");
280 void ScContentTree::GetEntryIndexes( ScContentId& rnRootIndex, sal_uLong& rnChildIndex, SvTreeListEntry* pEntry ) const
282 rnRootIndex = ScContentId::ROOT;
283 rnChildIndex = SC_CONTENT_NOCHILD;
285 if( !pEntry )
286 return;
288 SvTreeListEntry* pParent = GetParent( pEntry );
289 bool bFound = false;
290 for( int i = 1; !bFound && (i <= (int)ScContentId::LAST); ++i )
292 ScContentId nRoot = (ScContentId)i;
293 if( pEntry == pRootNodes[ nRoot ] )
295 rnRootIndex = nRoot;
296 rnChildIndex = ~0UL;
297 bFound = true;
299 else if( pParent && (pParent == pRootNodes[ nRoot ]) )
301 rnRootIndex = nRoot;
303 // search the entry in all child entries of the parent
304 sal_uLong nEntry = 0;
305 SvTreeListEntry* pIterEntry = FirstChild( pParent );
306 while( !bFound && pIterEntry )
308 if ( pEntry == pIterEntry )
310 rnChildIndex = nEntry;
311 bFound = true; // exit the while loop
313 pIterEntry = NextSibling( pIterEntry );
314 ++nEntry;
317 bFound = true; // exit the for loop
322 sal_uLong ScContentTree::GetChildIndex( SvTreeListEntry* pEntry ) const
324 ScContentId nRoot;
325 sal_uLong nChild;
326 GetEntryIndexes( nRoot, nChild, pEntry );
327 return nChild;
330 static OUString lcl_GetDBAreaRange( ScDocument* pDoc, const OUString& rDBName )
332 OUString aRet;
333 if (pDoc)
335 ScDBCollection* pDbNames = pDoc->GetDBCollection();
336 const ScDBData* pData = pDbNames->getNamedDBs().findByUpperName(ScGlobal::pCharClass->uppercase(rDBName));
337 if (pData)
339 ScRange aRange;
340 pData->GetArea(aRange);
341 aRet = aRange.Format(ScRefFlags::RANGE_ABS_3D, pDoc);
344 return aRet;
347 IMPL_LINK_NOARG_TYPED(ScContentTree, ContentDoubleClickHdl, SvTreeListBox*, bool)
349 ScContentId nType;
350 sal_uLong nChild;
351 SvTreeListEntry* pEntry = GetCurEntry();
352 GetEntryIndexes( nType, nChild, pEntry );
354 if( pEntry && (nType != ScContentId::ROOT) && (nChild != SC_CONTENT_NOCHILD) )
356 if ( bHiddenDoc )
357 return false; //! spaeter...
359 OUString aText( GetEntryText( pEntry ) );
361 if ( !aManualDoc.isEmpty() )
362 pParentWindow->SetCurrentDoc( aManualDoc );
364 switch( nType )
366 case ScContentId::TABLE:
367 pParentWindow->SetCurrentTableStr( aText );
368 break;
370 case ScContentId::RANGENAME:
371 pParentWindow->SetCurrentCellStr( aText );
372 break;
374 case ScContentId::DBAREA:
376 // Wenn gleiche Bereichs- und DB-Namen existieren, wird
377 // bei SID_CURRENTCELL der Bereichsname genommen.
378 // DB-Bereiche darum direkt ueber die Adresse anspringen.
380 OUString aRangeStr = lcl_GetDBAreaRange( GetSourceDocument(), aText );
381 if (!aRangeStr.isEmpty())
382 pParentWindow->SetCurrentCellStr( aRangeStr );
384 break;
386 case ScContentId::OLEOBJECT:
387 case ScContentId::GRAPHIC:
388 case ScContentId::DRAWING:
389 pParentWindow->SetCurrentObject( aText );
390 break;
392 case ScContentId::NOTE:
394 ScAddress aPos = GetNotePos( nChild );
395 pParentWindow->SetCurrentTable( aPos.Tab() );
396 pParentWindow->SetCurrentCell( aPos.Col(), aPos.Row() );
398 break;
400 case ScContentId::AREALINK:
402 const ScAreaLink* pLink = GetLink( nChild );
403 if( pLink )
405 ScRange aRange = pLink->GetDestArea();
406 ScDocument* pSrcDoc = GetSourceDocument();
407 OUString aRangeStr(aRange.Format(ScRefFlags::RANGE_ABS_3D, pSrcDoc, pSrcDoc->GetAddressConvention()));
408 pParentWindow->SetCurrentCellStr( aRangeStr );
411 break;
412 default: break;
415 ScNavigatorDlg::ReleaseFocus(); // set focus into document
418 return false;
421 void ScContentTree::MouseButtonDown( const MouseEvent& rMEvt )
423 SvTreeListBox::MouseButtonDown( rMEvt );
424 StoreNavigatorSettings();
427 void ScContentTree::KeyInput( const KeyEvent& rKEvt )
429 bool bUsed = false;
431 const vcl::KeyCode aCode = rKEvt.GetKeyCode();
432 if (aCode.GetCode() == KEY_RETURN)
434 switch (aCode.GetModifier())
436 case KEY_MOD1:
437 ToggleRoot(); // toggle root mode (as in Writer)
438 bUsed = true;
439 break;
440 case 0:
442 SvTreeListEntry* pEntry = GetCurEntry();
443 if( pEntry )
445 ScContentId nType;
446 sal_uLong nChild;
447 GetEntryIndexes( nType, nChild, pEntry );
449 if( (nType != ScContentId::ROOT) && (nChild == SC_CONTENT_NOCHILD) )
451 if ( IsExpanded( pEntry ) )
452 Collapse( pEntry );
453 else
454 Expand( pEntry );
456 else
457 ContentDoubleClickHdl(nullptr); // select content as if double clicked
460 bUsed = true;
462 break;
465 //Make KEY_SPACE has same function as DoubleClick
466 if ( bisInNavigatoeDlg )
468 if(aCode.GetCode() == KEY_SPACE )
470 bUsed = true;
471 ScContentId nType;
472 sal_uLong nChild;
473 SvTreeListEntry* pEntry = GetCurEntry();
474 GetEntryIndexes( nType, nChild, pEntry );
475 if( pEntry && (nType != ScContentId::ROOT) && (nChild != SC_CONTENT_NOCHILD) )
477 if ( bHiddenDoc )
478 return ; //! spaeter...
479 OUString aText( GetEntryText( pEntry ) );
480 sKeyString = aText;
481 if (!aManualDoc.isEmpty())
482 pParentWindow->SetCurrentDoc( aManualDoc );
483 switch( nType )
485 case ScContentId::OLEOBJECT:
486 case ScContentId::GRAPHIC:
487 case ScContentId::DRAWING:
489 vcl::Window* pWindow=reinterpret_cast<vcl::Window*>(GetParent(pEntry));
490 ScNavigatorDlg* pScNavigatorDlg = static_cast<ScNavigatorDlg*>(pWindow);
491 ScTabViewShell* pScTabViewShell = nullptr;
492 ScDrawView* pScDrawView = nullptr;
493 if (pScNavigatorDlg!=nullptr)
494 pScTabViewShell = ScNavigatorDlg::GetTabViewShell();
495 if(pScTabViewShell !=nullptr)
496 pScDrawView =pScTabViewShell->GetViewData().GetScDrawView();
497 if(pScDrawView!=nullptr)
499 pScDrawView->SelectCurrentViewObject(aText );
500 bool bHasMakredObject = false;
501 SvTreeListEntry* pParent = pRootNodes[nType];
502 SvTreeListEntry* pBeginEntry = nullptr;
503 if( pParent )
504 pBeginEntry = FirstChild(pParent);
505 while( pBeginEntry )
507 OUString aTempText( GetEntryText( pBeginEntry ) );
508 if( pScDrawView->GetObjectIsMarked( pScDrawView->GetObjectByName( aTempText ) ) )
510 bHasMakredObject = true;
511 break;
513 pBeginEntry = Next( pBeginEntry );
515 if( !bHasMakredObject && pScTabViewShell)
516 pScTabViewShell->SetDrawShell(false);
517 ObjectFresh( nType,pEntry );
520 break;
521 default: break;
527 if( !bUsed )
529 if(aCode.GetCode() == KEY_F5 )
531 StoreNavigatorSettings();
532 SvTreeListBox::KeyInput(rKEvt);
534 else
536 SvTreeListBox::KeyInput(rKEvt);
537 StoreNavigatorSettings();
542 sal_Int8 ScContentTree::AcceptDrop( const AcceptDropEvent& /* rEvt */ )
544 return DND_ACTION_NONE;
547 sal_Int8 ScContentTree::ExecuteDrop( const ExecuteDropEvent& /* rEvt */ )
549 return DND_ACTION_NONE;
552 void ScContentTree::StartDrag( sal_Int8 /* nAction */, const Point& /* rPosPixel */ )
554 DoDrag();
557 void ScContentTree::DragFinished( sal_Int8 /* nAction */ )
561 void ScContentTree::Command( const CommandEvent& rCEvt )
563 bool bDone = false;
565 switch ( rCEvt.GetCommand() )
567 case CommandEventId::StartDrag:
568 // Aus dem ExecuteDrag heraus kann der Navigator geloescht werden
569 // (beim Umschalten auf einen anderen Dokument-Typ), das wuerde aber
570 // den StarView MouseMove-Handler, der Command() aufruft, umbringen.
571 // Deshalb Drag&Drop asynchron:
573 Application::PostUserEvent( LINK( this, ScContentTree, ExecDragHdl ), nullptr, true );
575 bDone = true;
576 break;
578 case CommandEventId::ContextMenu:
580 // Drag-Drop Modus
582 PopupMenu aPop;
583 ScPopupMenu aDropMenu( ScResId( RID_POPUP_DROPMODE ) );
584 aDropMenu.CheckItem( RID_DROPMODE_URL + pParentWindow->GetDropMode() );
585 aPop.InsertItem( 1, pParentWindow->GetStrDragMode() );
586 aPop.SetPopupMenu( 1, &aDropMenu );
588 // angezeigtes Dokument
590 ScPopupMenu aDocMenu;
591 aDocMenu.SetMenuFlags( aDocMenu.GetMenuFlags() | MenuFlags::NoAutoMnemonics );
592 sal_uInt16 i=0;
593 sal_uInt16 nPos=0;
594 // geladene Dokumente
595 ScDocShell* pCurrentSh = dynamic_cast<ScDocShell*>( SfxObjectShell::Current() );
596 SfxObjectShell* pSh = SfxObjectShell::GetFirst();
597 while ( pSh )
599 if ( dynamic_cast<const ScDocShell*>( pSh) != nullptr )
601 OUString aName = pSh->GetTitle();
602 OUString aEntry = aName;
603 if ( pSh == pCurrentSh )
604 aEntry += pParentWindow->aStrActive;
605 else
606 aEntry += pParentWindow->aStrNotActive;
607 aDocMenu.InsertItem( ++i, aEntry );
608 if ( !bHiddenDoc && aName == aManualDoc )
609 nPos = i;
611 pSh = SfxObjectShell::GetNext( *pSh );
613 // "aktives Fenster"
614 aDocMenu.InsertItem( ++i, pParentWindow->aStrActiveWin );
615 if (!bHiddenDoc && aManualDoc.isEmpty())
616 nPos = i;
617 // verstecktes Dokument
618 if ( !aHiddenTitle.isEmpty() )
620 OUString aEntry = aHiddenTitle;
621 aEntry += pParentWindow->aStrHidden;
622 aDocMenu.InsertItem( ++i, aEntry );
623 if (bHiddenDoc)
624 nPos = i;
626 aDocMenu.CheckItem( nPos );
627 aPop.InsertItem( 2, pParentWindow->GetStrDisplay() );
628 aPop.SetPopupMenu( 2, &aDocMenu );
630 // ausfuehren
632 aPop.Execute( this, rCEvt.GetMousePosPixel() );
634 if ( aDropMenu.WasHit() ) // Drag-Drop Modus
636 sal_uInt16 nId = aDropMenu.GetSelected();
637 if ( nId >= RID_DROPMODE_URL && nId <= RID_DROPMODE_COPY )
638 pParentWindow->SetDropMode( nId - RID_DROPMODE_URL );
640 else if ( aDocMenu.WasHit() ) // angezeigtes Dokument
642 sal_uInt16 nId = aDocMenu.GetSelected();
643 OUString aName = aDocMenu.GetItemText(nId);
644 SelectDoc( aName );
647 break;
648 default: break;
651 if (!bDone)
652 SvTreeListBox::Command(rCEvt);
655 void ScContentTree::RequestHelp( const HelpEvent& rHEvt )
657 bool bDone = false;
658 if( rHEvt.GetMode() & HelpEventMode::QUICK )
660 Point aPos( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ));
661 SvTreeListEntry* pEntry = GetEntry( aPos );
662 if ( pEntry )
664 bool bRet = false;
665 OUString aHelpText;
666 SvTreeListEntry* pParent = GetParent(pEntry);
667 if ( !pParent ) // Top-Level ?
669 aHelpText = OUString::number( GetChildCount(pEntry) ) +
670 " " + GetEntryText(pEntry);
671 bRet = true;
673 else if ( pParent == pRootNodes[ScContentId::NOTE] )
675 aHelpText = GetEntryText(pEntry); // Notizen als Help-Text
676 bRet = true;
678 else if ( pParent == pRootNodes[ScContentId::AREALINK] )
680 sal_uLong nIndex = GetChildIndex(pEntry);
681 if( nIndex != SC_CONTENT_NOCHILD )
683 const ScAreaLink* pLink = GetLink(nIndex);
684 if (pLink)
686 aHelpText = pLink->GetFile(); // Source-Datei als Help-Text
687 bRet = true;
692 if (bRet)
694 SvLBoxTab* pTab;
695 SvLBoxString* pItem = static_cast<SvLBoxString*>(GetItem( pEntry, aPos.X(), &pTab ));
696 if( pItem )
698 aPos = GetEntryPosition( pEntry );
699 aPos.X() = GetTabPos( pEntry, pTab );
700 aPos = OutputToScreenPixel(aPos);
701 Size aSize( pItem->GetSize( this, pEntry ) );
703 Rectangle aItemRect( aPos, aSize );
704 Help::ShowQuickHelp( this, aItemRect, aHelpText );
705 bDone = true;
710 if (!bDone)
711 Window::RequestHelp( rHEvt );
714 ScDocument* ScContentTree::GetSourceDocument()
716 if (bHiddenDoc)
717 return pHiddenDocument;
718 else
720 ScDocShell* pSh = GetManualOrCurrent();
721 if (pSh)
722 return &pSh->GetDocument();
725 return nullptr;
728 //Move along and draw "*" sign .
729 void ScContentTree::ObjectFresh( ScContentId nType, SvTreeListEntry* pEntry )
731 if ( bHiddenDoc && !pHiddenDocument )
732 return; // anderes Dokument angezeigt
733 if(nType ==ScContentId::GRAPHIC||nType ==ScContentId::OLEOBJECT||nType ==ScContentId::DRAWING)
735 SetUpdateMode(false);
736 ClearType( nType );
737 GetDrawNames( nType/*, nId*/ );
738 if( !pEntry )
739 ApplyNavigatorSettings();
740 SetUpdateMode(true);
741 if( pEntry )
743 SvTreeListEntry* pParent = pRootNodes[nType];
744 SvTreeListEntry* pBeginEntry = nullptr;
745 SvTreeListEntry* pOldEntry = nullptr;
746 if( pParent )
747 pBeginEntry = FirstChild(pParent);
748 while( pBeginEntry )
750 OUString aTempText( GetEntryText( pBeginEntry ) );
751 if( aTempText == sKeyString )
753 pOldEntry = pBeginEntry;
754 break;
756 pBeginEntry = Next( pBeginEntry );
758 if( pOldEntry )
760 Expand(pParent);
761 Select( pOldEntry );
767 void ScContentTree::Refresh( ScContentId nType )
769 if ( bHiddenDoc && !pHiddenDocument )
770 return; // anderes Dokument angezeigt
772 // wenn sich nichts geaendert hat, gleich abbrechen (gegen Geflacker)
774 if ( nType == ScContentId::NOTE )
775 if (!NoteStringsChanged())
776 return;
777 if ( nType == ScContentId::GRAPHIC )
778 if (!DrawNamesChanged(ScContentId::GRAPHIC))
779 return;
780 if ( nType == ScContentId::OLEOBJECT )
781 if (!DrawNamesChanged(ScContentId::OLEOBJECT))
782 return;
783 if ( nType == ScContentId::DRAWING )
784 if (!DrawNamesChanged(ScContentId::DRAWING))
785 return;
787 SetUpdateMode(false);
789 ClearType( nType );
791 if ( nType == ScContentId::ROOT || nType == ScContentId::TABLE )
792 GetTableNames();
793 if ( nType == ScContentId::ROOT || nType == ScContentId::RANGENAME )
794 GetAreaNames();
795 if ( nType == ScContentId::ROOT || nType == ScContentId::DBAREA )
796 GetDbNames();
797 if ( nType == ScContentId::ROOT || nType == ScContentId::GRAPHIC )
798 GetGraphicNames();
799 if ( nType == ScContentId::ROOT || nType == ScContentId::OLEOBJECT )
800 GetOleNames();
801 if ( nType == ScContentId::ROOT || nType == ScContentId::DRAWING )
802 GetDrawingNames();
803 if ( nType == ScContentId::ROOT || nType == ScContentId::NOTE )
804 GetNoteStrings();
805 if ( nType == ScContentId::ROOT || nType == ScContentId::AREALINK )
806 GetLinkNames();
808 ApplyNavigatorSettings();
809 SetUpdateMode(true);
812 void ScContentTree::GetTableNames()
814 if ( nRootType != ScContentId::ROOT && nRootType != ScContentId::TABLE ) // ausgeblendet ?
815 return;
817 ScDocument* pDoc = GetSourceDocument();
818 if (!pDoc)
819 return;
821 OUString aName;
822 SCTAB nCount = pDoc->GetTableCount();
823 for ( SCTAB i=0; i<nCount; i++ )
825 pDoc->GetName( i, aName );
826 InsertContent( ScContentId::TABLE, aName );
830 namespace {
832 OUString createLocalRangeName(const OUString& rName, const OUString& rTableName)
834 OUStringBuffer aString (rName);
835 aString.append(" (");
836 aString.append(rTableName);
837 aString.append(")");
838 return aString.makeStringAndClear();
842 void ScContentTree::GetAreaNames()
844 if ( nRootType != ScContentId::ROOT && nRootType != ScContentId::RANGENAME ) // ausgeblendet ?
845 return;
847 ScDocument* pDoc = GetSourceDocument();
848 if (!pDoc)
849 return;
851 ScRange aDummy;
852 std::set<OUString> aSet;
853 ScRangeName* pRangeNames = pDoc->GetRangeName();
854 if (!pRangeNames->empty())
856 ScRangeName::const_iterator itrBeg = pRangeNames->begin(), itrEnd = pRangeNames->end();
857 for (ScRangeName::const_iterator itr = itrBeg; itr != itrEnd; ++itr)
859 if (itr->second->IsValidReference(aDummy))
860 aSet.insert(itr->second->GetName());
863 for (SCTAB i = 0; i < pDoc->GetTableCount(); ++i)
865 ScRangeName* pLocalRangeName = pDoc->GetRangeName(i);
866 if (pLocalRangeName && !pLocalRangeName->empty())
868 OUString aTableName;
869 pDoc->GetName(i, aTableName);
870 for (ScRangeName::const_iterator itr = pLocalRangeName->begin(); itr != pLocalRangeName->end(); ++itr)
872 if (itr->second->IsValidReference(aDummy))
873 aSet.insert(createLocalRangeName(itr->second->GetName(), aTableName));
878 if (!aSet.empty())
880 for (std::set<OUString>::iterator itr = aSet.begin();
881 itr != aSet.end(); ++itr)
883 InsertContent(ScContentId::RANGENAME, *itr);
888 void ScContentTree::GetDbNames()
890 if ( nRootType != ScContentId::ROOT && nRootType != ScContentId::DBAREA ) // ausgeblendet ?
891 return;
893 ScDocument* pDoc = GetSourceDocument();
894 if (!pDoc)
895 return;
897 ScDBCollection* pDbNames = pDoc->GetDBCollection();
898 const ScDBCollection::NamedDBs& rDBs = pDbNames->getNamedDBs();
899 ScDBCollection::NamedDBs::const_iterator itr = rDBs.begin(), itrEnd = rDBs.end();
900 for (; itr != itrEnd; ++itr)
902 const OUString& aStrName = (*itr)->GetName();
903 InsertContent(ScContentId::DBAREA, aStrName);
907 bool ScContentTree::IsPartOfType( ScContentId nContentType, sal_uInt16 nObjIdentifier )
909 bool bRet = false;
910 switch ( nContentType )
912 case ScContentId::GRAPHIC:
913 bRet = ( nObjIdentifier == OBJ_GRAF );
914 break;
915 case ScContentId::OLEOBJECT:
916 bRet = ( nObjIdentifier == OBJ_OLE2 );
917 break;
918 case ScContentId::DRAWING:
919 bRet = ( nObjIdentifier != OBJ_GRAF && nObjIdentifier != OBJ_OLE2 ); // everything else
920 break;
921 default:
922 OSL_FAIL("unknown content type");
924 return bRet;
927 void ScContentTree::GetDrawNames( ScContentId nType )
929 if ( nRootType != ScContentId::ROOT && nRootType != nType ) // ausgeblendet ?
930 return;
932 ScDocument* pDoc = GetSourceDocument();
933 if (!pDoc)
934 return;
936 // iterate in flat mode for groups
937 SdrIterMode eIter = ( nType == ScContentId::DRAWING ) ? IM_FLAT : IM_DEEPNOGROUPS;
939 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
940 SfxObjectShell* pShell = pDoc->GetDocumentShell();
941 if (pDrawLayer && pShell)
943 SCTAB nTabCount = pDoc->GetTableCount();
944 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
946 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
947 OSL_ENSURE(pPage,"Page ?");
948 if (pPage)
950 SdrObjListIter aIter( *pPage, eIter );
951 SdrObject* pObject = aIter.Next();
952 while (pObject)
954 if ( IsPartOfType( nType, pObject->GetObjIdentifier() ) )
956 OUString aName = ScDrawLayer::GetVisibleName( pObject );
957 if (!aName.isEmpty())
959 if( bisInNavigatoeDlg )
961 SvTreeListEntry* pParent = pRootNodes[nType];
962 if (pParent)
964 SvTreeListEntry* pChild=InsertEntry( aName, pParent );
965 if(pChild)
966 pChild->SetMarked(false);
967 vcl::Window* pWindow=nullptr;
968 ScTabViewShell* pScTabViewShell=nullptr;
969 ScDrawView* pScDrawView=nullptr;
970 ScNavigatorDlg* pScNavigatorDlg=nullptr;
971 if(pChild)
972 pWindow=reinterpret_cast<vcl::Window*>(GetParent(pChild));
973 if(pWindow)
974 pScNavigatorDlg = static_cast<ScNavigatorDlg*>(pWindow);
975 if (pScNavigatorDlg!=nullptr)
976 pScTabViewShell = ScNavigatorDlg::GetTabViewShell();
977 if(pScTabViewShell !=nullptr)
978 pScDrawView =pScTabViewShell->GetViewData().GetScDrawView();
979 if(pScDrawView!=nullptr)
981 bool bMarked =pScDrawView->GetObjectIsMarked(pObject);
982 pChild->SetMarked( bMarked );
984 }//end if parent
985 else
986 SAL_WARN("sc", "InsertContent ohne Parent");
992 pObject = aIter.Next();
999 void ScContentTree::GetGraphicNames()
1001 GetDrawNames( ScContentId::GRAPHIC );
1004 void ScContentTree::GetOleNames()
1006 GetDrawNames( ScContentId::OLEOBJECT );
1009 void ScContentTree::GetDrawingNames()
1011 GetDrawNames( ScContentId::DRAWING );
1014 void ScContentTree::GetLinkNames()
1016 if ( nRootType != ScContentId::ROOT && nRootType != ScContentId::AREALINK ) // ausgeblendet ?
1017 return;
1019 ScDocument* pDoc = GetSourceDocument();
1020 if (!pDoc)
1021 return;
1023 sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
1024 OSL_ENSURE(pLinkManager, "kein LinkManager am Dokument?");
1025 const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
1026 sal_uInt16 nCount = rLinks.size();
1027 for (sal_uInt16 i=0; i<nCount; i++)
1029 ::sfx2::SvBaseLink* pBase = rLinks[i].get();
1030 if (dynamic_cast<const ScAreaLink*>( pBase) != nullptr)
1031 InsertContent( ScContentId::AREALINK, static_cast<ScAreaLink*>(pBase)->GetSource() );
1033 // in der Liste die Namen der Quellbereiche
1037 const ScAreaLink* ScContentTree::GetLink( sal_uLong nIndex )
1039 ScDocument* pDoc = GetSourceDocument();
1040 if (!pDoc)
1041 return nullptr;
1043 sal_uLong nFound = 0;
1044 sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
1045 OSL_ENSURE(pLinkManager, "kein LinkManager am Dokument?");
1046 const ::sfx2::SvBaseLinks& rLinks = pLinkManager->GetLinks();
1047 sal_uInt16 nCount = rLinks.size();
1048 for (sal_uInt16 i=0; i<nCount; i++)
1050 ::sfx2::SvBaseLink* pBase = rLinks[i].get();
1051 if (dynamic_cast<const ScAreaLink*>( pBase) != nullptr)
1053 if (nFound == nIndex)
1054 return static_cast<const ScAreaLink*>(pBase);
1055 ++nFound;
1059 OSL_FAIL("link not found");
1060 return nullptr;
1063 static OUString lcl_NoteString( const ScPostIt& rNote )
1065 OUString aText = rNote.GetText();
1066 sal_Int32 nAt;
1067 while ( (nAt = aText.indexOf( '\n' )) != -1 )
1068 aText = aText.replaceAt( nAt, 1, " " );
1069 return aText;
1072 void ScContentTree::GetNoteStrings()
1074 if ( nRootType != ScContentId::ROOT && nRootType != ScContentId::NOTE ) // ausgeblendet ?
1075 return;
1077 ScDocument* pDoc = GetSourceDocument();
1078 if (!pDoc)
1079 return;
1081 // loop over cell notes
1082 std::vector<sc::NoteEntry> aEntries;
1083 pDoc->GetAllNoteEntries(aEntries);
1084 std::vector<sc::NoteEntry>::const_iterator it = aEntries.begin(), itEnd = aEntries.end();
1085 for (; it != itEnd; ++it)
1086 InsertContent(ScContentId::NOTE, lcl_NoteString(*it->mpNote));
1089 ScAddress ScContentTree::GetNotePos( sal_uLong nIndex )
1091 ScDocument* pDoc = GetSourceDocument();
1092 if (!pDoc)
1093 return ScAddress();
1095 return pDoc->GetNotePosition(nIndex);
1098 bool ScContentTree::NoteStringsChanged()
1100 ScDocument* pDoc = GetSourceDocument();
1101 if (!pDoc)
1102 return false;
1104 SvTreeListEntry* pParent = pRootNodes[ScContentId::NOTE];
1105 if (!pParent)
1106 return false;
1108 SvTreeListEntry* pEntry = FirstChild( pParent );
1110 std::vector<sc::NoteEntry> aEntries;
1111 pDoc->GetAllNoteEntries(aEntries);
1112 std::vector<sc::NoteEntry>::const_iterator it = aEntries.begin(), itEnd = aEntries.end();
1113 for (; it != itEnd; ++it)
1115 const ScPostIt* pNote = it->mpNote;
1116 if (!pEntry)
1117 return true;
1119 if (lcl_NoteString(*pNote) != GetEntryText(pEntry))
1120 return true;
1122 pEntry = NextSibling(pEntry);
1125 if ( pEntry )
1126 return true;
1128 return false;
1131 bool ScContentTree::DrawNamesChanged( ScContentId nType )
1133 ScDocument* pDoc = GetSourceDocument();
1134 if (!pDoc)
1135 return false;
1137 SvTreeListEntry* pParent = pRootNodes[nType];
1138 if (!pParent)
1139 return false;
1141 SvTreeListEntry* pEntry = FirstChild( pParent );
1143 // iterate in flat mode for groups
1144 SdrIterMode eIter = ( nType == ScContentId::DRAWING ) ? IM_FLAT : IM_DEEPNOGROUPS;
1146 bool bEqual = true;
1147 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
1148 SfxObjectShell* pShell = pDoc->GetDocumentShell();
1149 if (pDrawLayer && pShell)
1151 SCTAB nTabCount = pDoc->GetTableCount();
1152 for (SCTAB nTab=0; nTab<nTabCount && bEqual; nTab++)
1154 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
1155 OSL_ENSURE(pPage,"Page ?");
1156 if (pPage)
1158 SdrObjListIter aIter( *pPage, eIter );
1159 SdrObject* pObject = aIter.Next();
1160 while (pObject && bEqual)
1162 if ( IsPartOfType( nType, pObject->GetObjIdentifier() ) )
1164 if ( !pEntry )
1165 bEqual = false;
1166 else
1168 if ( ScDrawLayer::GetVisibleName( pObject ) != GetEntryText(pEntry) )
1169 bEqual = false;
1171 pEntry = NextSibling( pEntry );
1174 pObject = aIter.Next();
1180 if ( pEntry )
1181 bEqual = false; // kommt noch was
1183 return !bEqual;
1186 static bool lcl_GetRange( ScDocument* pDoc, ScContentId nType, const OUString& rName, ScRange& rRange )
1188 bool bFound = false;
1190 if ( nType == ScContentId::RANGENAME )
1192 ScRangeName* pList = pDoc->GetRangeName();
1193 if (pList)
1195 const ScRangeData* p = pList->findByUpperName(ScGlobal::pCharClass->uppercase(rName));
1196 if (p && p->IsValidReference(rRange))
1197 bFound = true;
1200 else if ( nType == ScContentId::DBAREA )
1202 ScDBCollection* pList = pDoc->GetDBCollection();
1203 if (pList)
1205 const ScDBData* p = pList->getNamedDBs().findByUpperName(ScGlobal::pCharClass->uppercase(rName));
1206 if (p)
1208 SCTAB nTab;
1209 SCCOL nCol1, nCol2;
1210 SCROW nRow1, nRow2;
1211 p->GetArea(nTab, nCol1, nRow1, nCol2, nRow2);
1212 rRange = ScRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab);
1213 bFound = true;
1218 return bFound;
1221 static void lcl_DoDragObject( ScDocShell* pSrcShell, const OUString& rName, ScContentId nType, vcl::Window* pWin )
1223 ScDocument& rSrcDoc = pSrcShell->GetDocument();
1224 ScDrawLayer* pModel = rSrcDoc.GetDrawLayer();
1225 if (pModel)
1227 bool bOle = ( nType == ScContentId::OLEOBJECT );
1228 bool bGraf = ( nType == ScContentId::GRAPHIC );
1229 sal_uInt16 nDrawId = sal::static_int_cast<sal_uInt16>( bOle ? OBJ_OLE2 : ( bGraf ? OBJ_GRAF : OBJ_GRUP ) );
1230 SCTAB nTab = 0;
1231 SdrObject* pObject = pModel->GetNamedObject( rName, nDrawId, nTab );
1232 if (pObject)
1234 SdrView aEditView( pModel );
1235 aEditView.ShowSdrPage(aEditView.GetModel()->GetPage(nTab));
1236 SdrPageView* pPV = aEditView.GetSdrPageView();
1237 aEditView.MarkObj(pObject, pPV);
1239 SdrModel* pDragModel = aEditView.GetMarkedObjModel();
1241 TransferableObjectDescriptor aObjDesc;
1242 pSrcShell->FillTransferableObjectDescriptor( aObjDesc );
1243 aObjDesc.maDisplayName = pSrcShell->GetMedium()->GetURLObject().GetURLNoPass();
1244 // maSize is set in ScDrawTransferObj ctor
1246 ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pDragModel, pSrcShell, aObjDesc );
1247 uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
1249 pTransferObj->SetDragSourceObj( pObject, nTab );
1250 pTransferObj->SetDragSourceFlags( SC_DROP_NAVIGATOR );
1252 SC_MOD()->SetDragObject( nullptr, pTransferObj );
1253 pWin->ReleaseMouse();
1254 pTransferObj->StartDrag( pWin, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
1259 static void lcl_DoDragCells( ScDocShell* pSrcShell, const ScRange& rRange, sal_uInt16 nFlags, vcl::Window* pWin )
1261 ScMarkData aMark;
1262 aMark.SelectTable( rRange.aStart.Tab(), true );
1263 aMark.SetMarkArea( rRange );
1265 ScDocument& rSrcDoc = pSrcShell->GetDocument();
1266 if ( !rSrcDoc.HasSelectedBlockMatrixFragment( rRange.aStart.Col(), rRange.aStart.Row(),
1267 rRange.aEnd.Col(), rRange.aEnd.Row(),
1268 aMark ) )
1270 ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
1271 ScClipParam aClipParam(rRange, false);
1272 rSrcDoc.CopyToClip(aClipParam, pClipDoc, &aMark, false, false);
1273 // pClipDoc->ExtendMerge( rRange, sal_True );
1275 TransferableObjectDescriptor aObjDesc;
1276 pSrcShell->FillTransferableObjectDescriptor( aObjDesc );
1277 aObjDesc.maDisplayName = pSrcShell->GetMedium()->GetURLObject().GetURLNoPass();
1278 // maSize is set in ScTransferObj ctor
1280 ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
1281 uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
1283 pTransferObj->SetDragSource( pSrcShell, aMark );
1284 pTransferObj->SetDragSourceFlags( nFlags );
1286 SC_MOD()->SetDragObject( pTransferObj, nullptr ); // for internal D&D
1287 pWin->ReleaseMouse();
1288 pTransferObj->StartDrag( pWin, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
1292 void ScContentTree::DoDrag()
1294 ScDocumentLoader* pDocLoader = nullptr;
1295 bIsInDrag = true;
1297 ScModule* pScMod = SC_MOD();
1299 ScContentId nType;
1300 sal_uLong nChild;
1301 SvTreeListEntry* pEntry = GetCurEntry();
1302 GetEntryIndexes( nType, nChild, pEntry );
1304 if( pEntry &&
1305 (nChild != SC_CONTENT_NOCHILD) &&
1306 (nType != ScContentId::ROOT) &&
1307 (nType != ScContentId::NOTE) &&
1308 (nType != ScContentId::AREALINK) )
1310 OUString aText( GetEntryText( pEntry ) );
1312 ScDocument* pLocalDoc = nullptr; // fuer URL-Drop
1313 OUString aDocName;
1314 if (bHiddenDoc)
1315 aDocName = aHiddenName;
1316 else
1318 ScDocShell* pDocSh = GetManualOrCurrent();
1319 if (pDocSh)
1321 if (pDocSh->HasName())
1322 aDocName = pDocSh->GetMedium()->GetName();
1323 else
1324 pLocalDoc = &pDocSh->GetDocument(); // Drop nur in dieses Dokument
1328 bool bDoLinkTrans = false; // use ScLinkTransferObj
1329 OUString aLinkURL; // for ScLinkTransferObj
1330 OUString aLinkText;
1332 sal_uInt16 nDropMode = pParentWindow->GetDropMode();
1333 switch ( nDropMode )
1335 case SC_DROPMODE_URL:
1337 OUString aUrl = aDocName + "#" + aText;
1339 pScMod->SetDragJump( pLocalDoc, aUrl, aText );
1341 if (!aDocName.isEmpty())
1343 // provide URL to outside only if the document has a name
1344 // (without name, only internal D&D via SetDragJump)
1346 aLinkURL = aUrl;
1347 aLinkText = aText;
1349 bDoLinkTrans = true;
1351 break;
1352 case SC_DROPMODE_LINK:
1354 if ( !aDocName.isEmpty() ) // link only to named documents
1356 // for internal D&D, set flag to insert a link
1358 switch ( nType )
1360 case ScContentId::TABLE:
1361 pScMod->SetDragLink( aDocName, aText, EMPTY_OUSTRING );
1362 bDoLinkTrans = true;
1363 break;
1364 case ScContentId::RANGENAME:
1365 case ScContentId::DBAREA:
1366 pScMod->SetDragLink( aDocName, EMPTY_OUSTRING, aText );
1367 bDoLinkTrans = true;
1368 break;
1370 // other types cannot be linked
1371 default: break;
1375 break;
1376 case SC_DROPMODE_COPY:
1378 ScDocShell* pSrcShell = nullptr;
1379 if ( bHiddenDoc )
1381 OUString aFilter, aOptions;
1382 OUString aURL = aHiddenName;
1383 pDocLoader = new ScDocumentLoader( aURL, aFilter, aOptions );
1384 if (!pDocLoader->IsError())
1385 pSrcShell = pDocLoader->GetDocShell();
1387 else
1388 pSrcShell = GetManualOrCurrent();
1390 if ( pSrcShell )
1392 ScDocument& rSrcDoc = pSrcShell->GetDocument();
1393 if ( nType == ScContentId::RANGENAME || nType == ScContentId::DBAREA )
1395 ScRange aRange;
1396 if ( lcl_GetRange( &rSrcDoc, nType, aText, aRange ) )
1398 lcl_DoDragCells( pSrcShell, aRange, SC_DROP_NAVIGATOR, this );
1401 else if ( nType == ScContentId::TABLE )
1403 SCTAB nTab;
1404 if ( rSrcDoc.GetTable( aText, nTab ) )
1406 ScRange aRange( 0,0,nTab, MAXCOL,MAXROW,nTab );
1407 lcl_DoDragCells( pSrcShell, aRange, SC_DROP_NAVIGATOR | SC_DROP_TABLE, this );
1410 else if ( nType == ScContentId::GRAPHIC || nType == ScContentId::OLEOBJECT ||
1411 nType == ScContentId::DRAWING )
1413 lcl_DoDragObject( pSrcShell, aText, nType, this );
1415 // in ExecuteDrag kann der Navigator geloescht worden sein
1416 // -> nicht mehr auf Member zugreifen !!!
1420 break;
1423 if (bDoLinkTrans)
1425 ScLinkTransferObj* pTransferObj = new ScLinkTransferObj;
1426 uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
1428 if ( !aLinkURL.isEmpty() )
1429 pTransferObj->SetLinkURL( aLinkURL, aLinkText );
1431 // SetDragJump / SetDragLink has been done above
1433 ReleaseMouse();
1434 pTransferObj->StartDrag( this, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
1438 bIsInDrag = false; // static Member
1440 delete pDocLoader; // falls Dokument zum Draggen geladen wurde
1443 IMPL_LINK_NOARG_TYPED(ScContentTree, ExecDragHdl, void*, void)
1445 // als Link, damit asynchron ohne ImpMouseMoveMsg auf dem Stack auch der
1446 // Navigator geloescht werden darf
1448 DoDrag();
1451 bool ScContentTree::LoadFile( const OUString& rUrl )
1453 OUString aDocName = rUrl;
1454 sal_Int32 nPos = aDocName.indexOf('#');
1455 if ( nPos != -1 )
1456 aDocName = aDocName.copy(0, nPos); // nur der Name, ohne #...
1458 bool bReturn = false;
1459 OUString aURL = aDocName;
1460 OUString aFilter, aOptions;
1461 ScDocumentLoader aLoader( aURL, aFilter, aOptions );
1462 if ( !aLoader.IsError() )
1464 bHiddenDoc = true;
1465 aHiddenName = aDocName;
1466 aHiddenTitle = aLoader.GetTitle();
1467 pHiddenDocument = aLoader.GetDocument();
1469 Refresh(); // Inhalte aus geladenem Dokument holen
1471 pHiddenDocument = nullptr;
1473 pParentWindow->GetDocNames( &aHiddenTitle ); // Liste fuellen
1476 // Dokument wird im dtor von ScDocumentLoader wieder geschlossen
1478 return bReturn;
1481 void ScContentTree::InitWindowBits( bool bButtons )
1483 WinBits nFlags = GetStyle() | WB_CLIPCHILDREN | WB_HSCROLL;
1484 if (bButtons)
1485 nFlags |= WB_HASBUTTONS | WB_HASBUTTONSATROOT;
1487 SetStyle( nFlags );
1490 void ScContentTree::SetRootType( ScContentId nNew )
1492 if ( nNew != nRootType )
1494 nRootType = nNew;
1495 InitWindowBits( nNew == ScContentId::ROOT );
1496 Refresh();
1498 ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
1499 rCfg.SetRootType( nRootType );
1503 void ScContentTree::ToggleRoot() // nach Selektion
1505 ScContentId nNew = ScContentId::ROOT;
1506 if ( nRootType == ScContentId::ROOT )
1508 SvTreeListEntry* pEntry = GetCurEntry();
1509 if (pEntry)
1511 SvTreeListEntry* pParent = GetParent(pEntry);
1512 for (sal_uInt16 i=1; i<=(int)ScContentId::LAST; i++)
1513 if ( pEntry == pRootNodes[(ScContentId)i] || pParent == pRootNodes[(ScContentId)i] )
1514 nNew = (ScContentId)i;
1518 SetRootType( nNew );
1521 void ScContentTree::ResetManualDoc()
1523 aManualDoc.clear();
1524 bHiddenDoc = false;
1526 ActiveDocChanged();
1529 void ScContentTree::ActiveDocChanged()
1531 if ( !bHiddenDoc && aManualDoc.isEmpty() )
1532 Refresh(); // Inhalte nur wenn automatisch
1534 // Listbox muss immer geupdated werden, wegen aktiv-Flag
1536 OUString aCurrent;
1537 if ( bHiddenDoc )
1538 aCurrent = aHiddenTitle;
1539 else
1541 ScDocShell* pSh = GetManualOrCurrent();
1542 if (pSh)
1543 aCurrent = pSh->GetTitle();
1544 else
1546 // eingestelltes Dokument existiert nicht mehr
1548 aManualDoc.clear(); // wieder automatisch
1549 Refresh();
1550 pSh = GetManualOrCurrent(); // sollte jetzt aktives sein
1551 if (pSh)
1552 aCurrent = pSh->GetTitle();
1555 pParentWindow->GetDocNames( &aCurrent ); // selektieren
1558 void ScContentTree::SetManualDoc(const OUString& rName)
1560 aManualDoc = rName;
1561 if (!bHiddenDoc)
1563 Refresh();
1564 pParentWindow->GetDocNames( &aManualDoc ); // selektieren
1568 void ScContentTree::SelectDoc(const OUString& rName) // rName wie im Menue/Listbox angezeigt
1570 if ( rName == pParentWindow->aStrActiveWin )
1572 ResetManualDoc();
1573 return;
1576 // "aktiv" oder "inaktiv" weglassen
1578 OUString aRealName = rName;
1579 sal_Int32 nLen = rName.getLength();
1580 sal_Int32 nActiveStart = nLen - pParentWindow->aStrActive.getLength();
1581 if ( rName.copy( nActiveStart ) == pParentWindow->aStrActive )
1582 aRealName = rName.copy( 0, nActiveStart );
1583 sal_Int32 nNotActiveStart = nLen - pParentWindow->aStrNotActive.getLength();
1584 if ( rName.copy( nNotActiveStart ) == pParentWindow->aStrNotActive )
1585 aRealName = rName.copy( 0, nNotActiveStart );
1587 bool bLoaded = false;
1589 // ist es ein normal geladenes Doc ?
1591 SfxObjectShell* pSh = SfxObjectShell::GetFirst();
1592 while ( pSh && !bLoaded )
1594 if ( dynamic_cast<const ScDocShell*>( pSh) != nullptr )
1595 if ( pSh->GetTitle() == aRealName )
1596 bLoaded = true;
1597 pSh = SfxObjectShell::GetNext( *pSh );
1600 if (bLoaded)
1602 bHiddenDoc = false;
1603 SetManualDoc(aRealName);
1605 else if (!aHiddenTitle.isEmpty()) // verstecktes ausgewaehlt
1607 if (!bHiddenDoc)
1608 LoadFile(aHiddenName);
1610 else
1612 OSL_FAIL("SelectDoc: nicht gefunden");
1616 void ScContentTree::ApplyNavigatorSettings()
1618 const ScNavigatorSettings* pSettings = ScNavigatorDlg::GetNavigatorSettings();
1619 if( pSettings )
1621 ScContentId nRootSel = pSettings->GetRootSelected();
1622 sal_uLong nChildSel = pSettings->GetChildSelected();
1624 for( int i = 1; i <= (int)ScContentId::LAST; ++i )
1626 ScContentId nEntry = (ScContentId)i;
1627 if( pRootNodes[ nEntry ] )
1629 // expand
1630 bool bExp = pSettings->IsExpanded( nEntry );
1631 if( bExp != IsExpanded( pRootNodes[ nEntry ] ) )
1633 if( bExp )
1634 Expand( pRootNodes[ nEntry ] );
1635 else
1636 Collapse( pRootNodes[ nEntry ] );
1639 // select
1640 if( nRootSel == nEntry )
1642 SvTreeListEntry* pEntry = nullptr;
1643 if( bExp && (nChildSel != SC_CONTENT_NOCHILD) )
1644 pEntry = GetEntry( pRootNodes[ nEntry ], nChildSel );
1645 Select( pEntry ? pEntry : pRootNodes[ nEntry ] );
1652 void ScContentTree::StoreNavigatorSettings() const
1654 ScNavigatorSettings* pSettings = ScNavigatorDlg::GetNavigatorSettings();
1655 if( pSettings )
1657 for( int i = 1; i <= (int)ScContentId::LAST; ++i )
1659 ScContentId nEntry = (ScContentId)i;
1660 bool bExp = pRootNodes[ nEntry ] && IsExpanded( pRootNodes[ nEntry ] );
1661 pSettings->SetExpanded( nEntry, bExp );
1663 ScContentId nRoot;
1664 sal_uLong nChild;
1665 GetEntryIndexes( nRoot, nChild, GetCurEntry() );
1666 pSettings->SetRootSelected( nRoot );
1667 pSettings->SetChildSelected( nChild );
1671 void ScContentTree::InitEntry(SvTreeListEntry* pEntry,
1672 const OUString& rStr, const Image& rImg1, const Image& rImg2, SvLBoxButtonKind eButtonKind)
1674 sal_uInt16 nColToHilite = 1; //0==Bitmap;1=="Spalte1";2=="Spalte2"
1675 SvTreeListBox::InitEntry( pEntry, rStr, rImg1, rImg2, eButtonKind );
1676 SvLBoxString& rCol = static_cast<SvLBoxString&>(pEntry->GetItem( nColToHilite ));
1677 pEntry->ReplaceItem(o3tl::make_unique<SvLBoxString>(rCol.GetText()), nColToHilite);
1680 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */