bump product version to 6.3.0.0.beta1
[LibreOffice.git] / sd / source / ui / dlg / sdtreelb.cxx
blobcfac921eeda0b93ff61666b0ae6a35f4d9f57340
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 <sal/types.h>
21 #include <sal/log.hxx>
22 #include <sot/formats.hxx>
23 #include <vcl/weld.hxx>
24 #include <svx/svditer.hxx>
25 #include <sfx2/docfile.hxx>
26 #include <svx/svdoole2.hxx>
27 #include <vcl/svapp.hxx>
28 #include <vcl/builderfactory.hxx>
29 #include <cusshow.hxx>
31 #include <sfx2/viewfrm.hxx>
33 #include <sdtreelb.hxx>
34 #include <DrawDocShell.hxx>
35 #include <drawdoc.hxx>
36 #include <sdpage.hxx>
37 #include <sdmod.hxx>
38 #include <sdresid.hxx>
39 #include <navigatr.hxx>
40 #include <strings.hrc>
42 #include <bitmaps.hlst>
43 #include <customshowlist.hxx>
44 #include <ViewShell.hxx>
45 #include <DrawController.hxx>
46 #include <ViewShellBase.hxx>
48 #include <com/sun/star/embed/XEmbedPersist.hpp>
49 #include <com/sun/star/frame/Desktop.hpp>
50 #include <com/sun/star/frame/XFramesSupplier.hpp>
51 #include <svtools/acceleratorexecute.hxx>
52 #include <svtools/embedtransfer.hxx>
53 #include <vcl/svlbitm.hxx>
54 #include <vcl/treelistentry.hxx>
55 #include <comphelper/servicehelper.hxx>
56 #include <comphelper/processfactory.hxx>
57 #include <tools/diagnose_ex.h>
58 #include <comphelper/scopeguard.hxx>
61 using namespace com::sun::star;
63 class SdPageObjsTLB::IconProvider
65 public:
66 IconProvider();
68 // Regular icons.
69 Image const maImgPage;
70 Image const maImgPageExcl;
71 Image const maImgPageObjsExcl;
72 Image const maImgPageObjs;
73 Image const maImgObjects;
74 Image const maImgGroup;
77 bool SdPageObjsTLB::bIsInDrag = false;
79 bool SdPageObjsTLB::IsInDrag()
81 return bIsInDrag;
84 SotClipboardFormatId SdPageObjsTLB::SdPageObjsTransferable::mnListBoxDropFormatId = static_cast<SotClipboardFormatId>(SAL_MAX_UINT32);
87 SdPageObjsTLB::SdPageObjsTransferable::SdPageObjsTransferable(
88 SdPageObjsTLB& rParent,
89 const INetBookmark& rBookmark,
90 ::sd::DrawDocShell& rDocShell,
91 NavigatorDragType eDragType)
92 : SdTransferable(rDocShell.GetDoc(), nullptr, true),
93 mrParent( rParent ),
94 maBookmark( rBookmark ),
95 mrDocShell( rDocShell ),
96 meDragType( eDragType )
98 rParent.SetupDragOrigin();
101 VCL_BUILDER_FACTORY_CONSTRUCTOR(SdPageObjsTLB, WB_TABSTOP)
103 SdPageObjsTLB::SdPageObjsTransferable::~SdPageObjsTransferable()
107 void SdPageObjsTLB::SdPageObjsTransferable::AddSupportedFormats()
109 AddFormat(SotClipboardFormatId::NETSCAPE_BOOKMARK);
110 AddFormat(SotClipboardFormatId::TREELISTBOX);
111 AddFormat(GetListBoxDropFormatId());
114 bool SdPageObjsTLB::SdPageObjsTransferable::GetData( const css::datatransfer::DataFlavor& rFlavor, const OUString& /*rDestDoc*/ )
116 SotClipboardFormatId nFormatId = SotExchange::GetFormat( rFlavor );
117 switch (nFormatId)
119 case SotClipboardFormatId::NETSCAPE_BOOKMARK:
120 SetINetBookmark( maBookmark, rFlavor );
121 return true;
123 case SotClipboardFormatId::TREELISTBOX:
125 css::uno::Any aTreeListBoxData; // empty for now
126 SetAny(aTreeListBoxData);
127 return true;
130 default:
131 return false;
135 void SdPageObjsTLB::SdPageObjsTransferable::DragFinished( sal_Int8 nDropAction )
137 mrParent.OnDragFinished();
138 SdTransferable::DragFinished(nDropAction);
141 sal_Int64 SAL_CALL SdPageObjsTLB::SdPageObjsTransferable::getSomething( const css::uno::Sequence< sal_Int8 >& rId )
143 sal_Int64 nRet;
145 if( ( rId.getLength() == 16 ) &&
146 ( 0 == memcmp( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
148 nRet = static_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
150 else
151 nRet = SdTransferable::getSomething(rId);
153 return nRet;
156 namespace
158 class theSdPageObjsTLBUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSdPageObjsTLBUnoTunnelId > {};
161 const css::uno::Sequence< sal_Int8 >& SdPageObjsTLB::SdPageObjsTransferable::getUnoTunnelId()
163 return theSdPageObjsTLBUnoTunnelId::get().getSeq();
166 SdPageObjsTLB::SdPageObjsTransferable* SdPageObjsTLB::SdPageObjsTransferable::getImplementation( const css::uno::Reference< css::uno::XInterface >& rxData )
167 throw()
171 css::uno::Reference< css::lang::XUnoTunnel > xUnoTunnel( rxData, css::uno::UNO_QUERY_THROW );
173 return reinterpret_cast<SdPageObjsTLB::SdPageObjsTransferable*>(
174 sal::static_int_cast<sal_uIntPtr>(
175 xUnoTunnel->getSomething( SdPageObjsTLB::SdPageObjsTransferable::getUnoTunnelId()) ) );
177 catch( const css::uno::Exception& )
180 return nullptr;
183 SotClipboardFormatId SdPageObjsTLB::SdPageObjsTransferable::GetListBoxDropFormatId()
185 if (mnListBoxDropFormatId == static_cast<SotClipboardFormatId>(SAL_MAX_UINT32))
186 mnListBoxDropFormatId = SotExchange::RegisterFormatMimeType("application/x-openoffice-treelistbox-moveonly;windows_formatname=\"SV_LBOX_DD_FORMAT_MOVE\"");
187 return mnListBoxDropFormatId;
190 SdPageObjsTLB::SdPageObjsTLB( vcl::Window* pParentWin, WinBits nStyle )
191 : SvTreeListBox ( pParentWin, nStyle )
192 , mpDoc ( nullptr )
193 , mpBookmarkDoc ( nullptr )
194 , mpMedium ( nullptr )
195 , mpOwnMedium ( nullptr )
196 , maImgOle ( StockImage::Yes, BMP_OLE )
197 , maImgGraphic ( StockImage::Yes, BMP_GRAPHIC )
198 , mbLinkableSelected ( false )
199 , mbSaveTreeItemState ( false )
200 , mbShowAllShapes ( false )
201 , mbShowAllPages ( false )
202 , mbSelectionHandlerNavigates(false)
203 , mbNavigationGrabsFocus(true)
205 // add lines to Tree-ListBox
206 SetStyle( GetStyle() | WB_TABSTOP | WB_BORDER | WB_HASLINES |
207 WB_HASBUTTONS | // WB_HASLINESATROOT |
208 WB_HSCROLL |
209 WB_HASBUTTONSATROOT );
210 SetQuickSearch(true); /* i31275 */;
211 SetNodeBitmaps(Image(StockImage::Yes, BMP_EXPAND), Image(StockImage::Yes, BMP_COLLAPSE));
213 SetDragDropMode(
214 DragDropMode::CTRL_MOVE | DragDropMode::CTRL_COPY |
215 DragDropMode::APP_MOVE | DragDropMode::APP_COPY | DragDropMode::APP_DROP );
217 m_pAccel = ::svt::AcceleratorExecute::createAcceleratorHelper();
220 void SdPageObjsTLB::SetSdNavigator(SdNavigatorWin* pNavigator)
222 mpNavigator = pNavigator;
225 void SdPageObjsTLB::SetViewFrame( const SfxViewFrame* pViewFrame )
227 sd::ViewShellBase* pBase = sd::ViewShellBase::GetViewShellBase(pViewFrame);
228 const css::uno::Reference< css::frame::XFrame > xFrame = pBase->GetMainViewShell()->GetViewFrame()->GetFrame().GetFrameInterface();
229 m_pAccel->init(::comphelper::getProcessComponentContext(), xFrame);
233 SdPageObjsTLB::~SdPageObjsTLB()
235 disposeOnce();
238 void SdPageObjsTLB::dispose()
240 if ( mpBookmarkDoc )
241 CloseBookmarkDoc();
242 else
243 // no document was created from mpMedium, so this object is still the owner of it
244 delete mpMedium;
245 mpNavigator.clear();
246 m_pAccel.reset();
247 SvTreeListBox::dispose();
250 // helper function for GetEntryAltText and GetEntryLongDescription
251 OUString SdPageObjsTLB::getAltLongDescText(SvTreeListEntry* pEntry , bool isAltText) const
253 sal_uInt16 maxPages = mpDoc->GetPageCount();
254 sal_uInt16 pageNo;
255 SdrObject* pObj = nullptr;
257 OUString ParentName = GetEntryText( GetRootLevelParent( pEntry ) );
259 for( pageNo = 0; pageNo < maxPages; pageNo++ )
261 const SdPage* pPage = static_cast<const SdPage*>( mpDoc->GetPage( pageNo ) );
262 if( pPage->GetPageKind() != PageKind::Standard ) continue;
263 if( pPage->GetName() != ParentName ) continue;
264 SdrObjListIter aIter( pPage, SdrIterMode::Flat );
265 while( aIter.IsMore() )
267 pObj = aIter.Next();
268 if( GetEntryText(pEntry) == GetObjectName( pObj ) )
270 if( isAltText )
271 return pObj->GetTitle();
272 else
273 return pObj->GetDescription();
277 return OUString();
281 OUString SdPageObjsTLB::GetEntryAltText( SvTreeListEntry* pEntry ) const
283 return getAltLongDescText( pEntry, true );
286 OUString SdPageObjsTLB::GetEntryLongDescription( SvTreeListEntry* pEntry ) const
288 return getAltLongDescText( pEntry, false);
291 void SdPageObjsTLB::InitEntry(SvTreeListEntry* pEntry,
292 const OUString& rStr, const Image& rImg1, const Image& rImg2, SvLBoxButtonKind eButtonKind)
294 sal_uInt16 nColToHilite = 1; //0==Bitmap;1=="Spalte1";2=="Spalte2"
295 SvTreeListBox::InitEntry( pEntry, rStr, rImg1, rImg2, eButtonKind );
296 SvLBoxString& rCol = static_cast<SvLBoxString&>(pEntry->GetItem( nColToHilite ));
297 pEntry->ReplaceItem(std::make_unique<SvLBoxString>(rCol.GetText()), nColToHilite );
300 void SdPageObjsTLB::SaveExpandedTreeItemState(SvTreeListEntry* pEntry, std::vector<OUString>& vectTreeItem)
302 if (!pEntry)
303 return;
305 SvTreeListEntry* pListEntry = pEntry;
306 while (pListEntry)
308 if (pListEntry->HasChildren())
310 if (IsExpanded(pListEntry))
311 vectTreeItem.push_back(GetEntryText(pListEntry));
312 SvTreeListEntry* pChildEntry = FirstChild(pListEntry);
313 SaveExpandedTreeItemState(pChildEntry, vectTreeItem);
315 pListEntry = pListEntry->NextSibling();
318 void SdPageObjsTLB::Clear()
320 //Save the expanded tree item
321 if (mbSaveTreeItemState)
323 maSelectionEntryText.clear();
324 maTreeItem.clear();
325 if (GetCurEntry())
326 maSelectionEntryText = GetSelectedEntry();
327 SvTreeListEntry* pEntry = FirstChild(nullptr);
328 SaveExpandedTreeItemState(pEntry, maTreeItem);
330 return SvTreeListBox::Clear();
333 OUString SdPageObjsTLB::GetObjectName(
334 const SdrObject* pObject,
335 const bool bCreate) const
337 OUString aRet;
339 if ( pObject )
341 aRet = pObject->GetName();
343 if (aRet.isEmpty() && dynamic_cast<const SdrOle2Obj* >(pObject) != nullptr)
344 aRet = static_cast< const SdrOle2Obj* >( pObject )->GetPersistName();
347 if (bCreate
348 && mbShowAllShapes
349 && aRet.isEmpty()
350 && pObject!=nullptr)
352 aRet = SdResId(STR_NAVIGATOR_SHAPE_BASE_NAME);
353 aRet = aRet.replaceFirst("%1", OUString::number(pObject->GetOrdNum() + 1));
356 return aRet;
360 * select a entry in TreeLB
362 bool SdPageObjsTLB::SelectEntry( const OUString& rName )
364 bool bFound = false;
366 if( !rName.isEmpty() )
368 SvTreeListEntry* pEntry = nullptr;
369 OUString aTmp;
371 for( pEntry = First(); pEntry && !bFound; pEntry = Next( pEntry ) )
373 aTmp = GetEntryText( pEntry );
374 if( aTmp == rName )
376 bFound = true;
377 SetCurEntry( pEntry );
381 return bFound;
385 * @return true if children of the specified string are selected
387 bool SdPageObjsTLB::HasSelectedChildren( const OUString& rName )
389 bool bChildren = false;
391 if( !rName.isEmpty() )
393 bool bFound = false;
394 SvTreeListEntry* pEntry = nullptr;
395 OUString aTmp;
397 for( pEntry = First(); pEntry && !bFound; pEntry = Next( pEntry ) )
399 aTmp = GetEntryText( pEntry );
400 if( aTmp == rName )
402 bFound = true;
403 bool bExpanded = IsExpanded( pEntry );
404 long nCount = GetChildSelectionCount( pEntry );
405 if( bExpanded && nCount > 0 )
406 bChildren = true;
410 return bChildren;
414 * Fill TreeLB with pages and objects
416 void SdPageObjsTLB::Fill( const SdDrawDocument* pInDoc, bool bAllPages,
417 const OUString& rDocName)
419 OUString aSelection;
420 if( GetSelectionCount() > 0 )
422 aSelection = GetSelectedEntry();
423 Clear();
426 mpDoc = pInDoc;
427 maDocName = rDocName;
428 mbShowAllPages = bAllPages;
429 mpMedium = nullptr;
431 IconProvider aIconProvider;
433 // first insert all pages including objects
434 sal_uInt16 nPage = 0;
435 const sal_uInt16 nMaxPages = mpDoc->GetPageCount();
437 while( nPage < nMaxPages )
439 const SdPage* pPage = static_cast<const SdPage*>( mpDoc->GetPage( nPage ) );
440 if( (mbShowAllPages || pPage->GetPageKind() == PageKind::Standard)
441 && (pPage->GetPageKind() != PageKind::Handout) ) //#94954# never list the normal handout page ( handout-masterpage is used instead )
443 bool bPageExluded = pPage->IsExcluded();
445 bool bPageBelongsToShow = PageBelongsToCurrentShow (pPage);
446 bPageExluded |= !bPageBelongsToShow;
448 AddShapeList(*pPage, nullptr, pPage->GetName(), bPageExluded, nullptr, aIconProvider);
450 nPage++;
453 // then insert all master pages including objects
454 if( mbShowAllPages )
456 nPage = 0;
457 const sal_uInt16 nMaxMasterPages = mpDoc->GetMasterPageCount();
459 while( nPage < nMaxMasterPages )
461 const SdPage* pPage = static_cast<const SdPage*>( mpDoc->GetMasterPage( nPage ) );
462 AddShapeList(*pPage, nullptr, pPage->GetName(), false, nullptr, aIconProvider);
463 nPage++;
466 if( !aSelection.isEmpty() )
467 SelectEntry( aSelection );
468 else if (mbSaveTreeItemState && !maSelectionEntryText.isEmpty())
470 SelectEntry(maSelectionEntryText);
475 * We insert only the first entry. Children are created on demand.
477 void SdPageObjsTLB::Fill( const SdDrawDocument* pInDoc, SfxMedium* pInMedium,
478 const OUString& rDocName )
480 mpDoc = pInDoc;
482 // this object now owns the Medium
483 mpMedium = pInMedium;
484 maDocName = rDocName;
486 Image aImgDocOpen(StockImage::Yes, BMP_DOC_OPEN);
487 Image aImgDocClosed(StockImage::Yes, BMP_DOC_CLOSED);
489 // insert document name
490 InsertEntry( maDocName, aImgDocOpen, aImgDocClosed, nullptr, true, TREELIST_APPEND,
491 reinterpret_cast< void* >( 1 )
495 void SdPageObjsTLB::AddShapeList (
496 const SdrObjList& rList,
497 SdrObject* pShape,
498 const OUString& rsName,
499 const bool bIsExcluded,
500 SvTreeListEntry* pParentEntry,
501 const IconProvider& rIconProvider)
503 Image aIcon (rIconProvider.maImgPage);
504 if (bIsExcluded)
505 aIcon = rIconProvider.maImgPageExcl;
506 else if (pShape != nullptr)
507 aIcon = rIconProvider.maImgGroup;
509 void* pUserData (reinterpret_cast<void*>(1));
510 if (pShape != nullptr)
511 pUserData = pShape;
513 SvTreeListEntry* pEntry = InsertEntry(
514 rsName,
515 aIcon,
516 aIcon,
517 pParentEntry,
518 false,
519 TREELIST_APPEND,
520 pUserData);
522 SdrObjListIter aIter(
523 &rList,
524 !rList.HasObjectNavigationOrder() /* use navigation order, if available */,
525 SdrIterMode::Flat);
527 while( aIter.IsMore() )
529 SdrObject* pObj = aIter.Next();
530 OSL_ASSERT(pObj!=nullptr);
532 // Get the shape name.
533 OUString aStr (GetObjectName( pObj ) );
535 if( !aStr.isEmpty() )
537 if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == OBJ_OLE2 )
539 InsertEntry(
540 aStr,
541 maImgOle,
542 maImgOle,
543 pEntry,
544 false,
545 TREELIST_APPEND,
546 pObj
549 else if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == OBJ_GRAF )
551 InsertEntry(
552 aStr,
553 maImgGraphic,
554 maImgGraphic,
555 pEntry,
556 false,
557 TREELIST_APPEND,
558 pObj
561 else if (pObj->IsGroupObject())
563 AddShapeList(
564 *pObj->GetSubList(),
565 pObj,
566 aStr,
567 false,
568 pEntry,
569 rIconProvider
572 else
574 InsertEntry(
575 aStr,
576 rIconProvider.maImgObjects,
577 rIconProvider.maImgObjects,
578 pEntry,
579 false,
580 TREELIST_APPEND,
581 pObj
587 if( !pEntry->HasChildren() )
588 return;
590 SetExpandedEntryBmp(
591 pEntry,
592 bIsExcluded ? rIconProvider.maImgPageObjsExcl : rIconProvider.maImgPageObjs);
593 SetCollapsedEntryBmp(
594 pEntry,
595 bIsExcluded ? rIconProvider.maImgPageObjsExcl : rIconProvider.maImgPageObjs);
596 if (mbSaveTreeItemState)
598 OUString strEntry = GetEntryText(pEntry);
599 auto it = std::find(maTreeItem.begin(), maTreeItem.end(), strEntry);
600 if (it != maTreeItem.end())
601 Expand( pEntry );
603 else
604 Expand( pEntry );
607 void SdPageObjsTLB::SetShowAllShapes (
608 const bool bShowAllShapes,
609 const bool bFillList)
611 mbShowAllShapes = bShowAllShapes;
612 if (bFillList)
614 if (mpMedium == nullptr)
615 Fill(mpDoc, mbShowAllPages, maDocName);
616 else
617 Fill(mpDoc, mpMedium, maDocName);
621 bool SdPageObjsTLB::IsEqualToShapeList(SvTreeListEntry*& pEntry, const SdrObjList& rList,
622 const OUString& rListName)
624 if (!pEntry)
625 return false;
626 OUString aName = GetEntryText(pEntry);
628 if (rListName != aName)
629 return false;
631 pEntry = Next(pEntry);
633 SdrObjListIter aIter(&rList,
634 !rList.HasObjectNavigationOrder() /* use navigation order, if available */,
635 SdrIterMode::Flat);
637 while (aIter.IsMore())
639 SdrObject* pObj = aIter.Next();
641 const OUString aObjectName(GetObjectName(pObj));
643 if (!aObjectName.isEmpty())
645 if (!pEntry)
646 return false;
648 aName = GetEntryText(pEntry);
650 if (aObjectName != aName)
651 return false;
653 if (pObj->IsGroupObject())
655 bool bRet = IsEqualToShapeList(pEntry, *pObj->GetSubList(), aObjectName);
656 if (!bRet)
657 return false;
659 else
660 pEntry = Next(pEntry);
664 return true;
668 * Checks if the pages (PageKind::Standard) of a doc and the objects on the pages
669 * are identical to the TreeLB.
670 * If a doc is provided, this will be the used doc (important by more than
671 * one document).
673 bool SdPageObjsTLB::IsEqualToDoc( const SdDrawDocument* pInDoc )
675 if( pInDoc )
676 mpDoc = pInDoc;
678 if( !mpDoc )
679 return false;
681 SvTreeListEntry* pEntry = First();
683 // compare all pages including the objects
684 sal_uInt16 nPage = 0;
685 const sal_uInt16 nMaxPages = mpDoc->GetPageCount();
687 while( nPage < nMaxPages )
689 const SdPage* pPage = static_cast<const SdPage*>( mpDoc->GetPage( nPage ) );
690 if( pPage->GetPageKind() == PageKind::Standard )
692 bool bRet = IsEqualToShapeList(pEntry, *pPage, pPage->GetName());
693 if (!bRet)
694 return false;
696 nPage++;
698 // If there are still entries in the listbox,
699 // then objects (with names) or pages were deleted
700 return !pEntry;
704 * @return selected string
706 OUString SdPageObjsTLB::GetSelectedEntry()
708 return GetEntryText( GetCurEntry() );
712 * Entries are inserted only by request (double click)
714 void SdPageObjsTLB::RequestingChildren( SvTreeListEntry* pFileEntry )
716 if( !pFileEntry->HasChildren() )
718 if( GetBookmarkDoc() )
720 SdrObject* pObj = nullptr;
721 SvTreeListEntry* pPageEntry = nullptr;
723 Image aImgPage(StockImage::Yes, BMP_PAGE);
724 Image aImgPageObjs(StockImage::Yes, BMP_PAGEOBJS);
725 Image aImgObjects(StockImage::Yes, BMP_OBJECTS);
727 // document name already inserted
729 // only insert all "normal" ? slides with objects
730 sal_uInt16 nPage = 0;
731 const sal_uInt16 nMaxPages = mpBookmarkDoc->GetPageCount();
733 while( nPage < nMaxPages )
735 SdPage* pPage = static_cast<SdPage*>( mpBookmarkDoc->GetPage( nPage ) );
736 if( pPage->GetPageKind() == PageKind::Standard )
738 pPageEntry = InsertEntry( pPage->GetName(),
739 aImgPage,
740 aImgPage,
741 pFileEntry,
742 false,
743 TREELIST_APPEND,
744 reinterpret_cast< void* >( 1 ) );
746 SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups );
748 while( aIter.IsMore() )
750 pObj = aIter.Next();
751 OUString aStr( GetObjectName( pObj ) );
752 if( !aStr.isEmpty() )
754 if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == OBJ_OLE2 )
756 InsertEntry(aStr, maImgOle, maImgOle, pPageEntry);
758 else if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == OBJ_GRAF )
760 InsertEntry(aStr, maImgGraphic, maImgGraphic, pPageEntry);
762 else
764 InsertEntry(aStr, aImgObjects, aImgObjects, pPageEntry);
768 if( pPageEntry->HasChildren() )
770 SetExpandedEntryBmp( pPageEntry, aImgPageObjs );
771 SetCollapsedEntryBmp( pPageEntry, aImgPageObjs );
774 nPage++;
778 else
779 SvTreeListBox::RequestingChildren( pFileEntry );
783 * Checks if it is a draw file and opens the BookmarkDoc depending of
784 * the provided Docs
786 SdDrawDocument* SdPageObjsTLB::GetBookmarkDoc(SfxMedium* pMed)
788 if (
789 !mpBookmarkDoc ||
790 (pMed && (!mpOwnMedium || mpOwnMedium->GetName() != pMed->GetName()))
793 // create a new BookmarkDoc if now one exists or if a new Medium is provided
794 if (mpOwnMedium != pMed)
796 CloseBookmarkDoc();
799 if (pMed)
801 // it looks that it is undefined if a Medium was set by Fill() already
802 DBG_ASSERT( !mpMedium, "SfxMedium confusion!" );
803 delete mpMedium;
804 mpMedium = nullptr;
806 // take over this Medium (currently used only be Navigator)
807 mpOwnMedium = pMed;
810 DBG_ASSERT( mpMedium || pMed, "No SfxMedium provided!" );
812 if( pMed )
814 // in this mode the document is also owned and controlled by this instance
815 mxBookmarkDocShRef = new ::sd::DrawDocShell(SfxObjectCreateMode::STANDARD, true, DocumentType::Impress);
816 if (mxBookmarkDocShRef->DoLoad(pMed))
817 mpBookmarkDoc = mxBookmarkDocShRef->GetDoc();
818 else
819 mpBookmarkDoc = nullptr;
821 else if ( mpMedium )
822 // in this mode the document is owned and controlled by the SdDrawDocument
823 // it can be released by calling the corresponding CloseBookmarkDoc method
824 // successful creation of a document makes this the owner of the medium
825 mpBookmarkDoc = const_cast<SdDrawDocument*>(mpDoc)->OpenBookmarkDoc(mpMedium);
827 if ( !mpBookmarkDoc )
829 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
830 VclMessageType::Warning, VclButtonsType::Ok, SdResId(STR_READ_DATA_ERROR)));
831 xErrorBox->run();
832 mpMedium = nullptr; //On failure the SfxMedium is invalid
836 return mpBookmarkDoc;
840 * Close and delete bookmark document
842 void SdPageObjsTLB::CloseBookmarkDoc()
844 if (mxBookmarkDocShRef.is())
846 mxBookmarkDocShRef->DoClose();
847 mxBookmarkDocShRef.clear();
849 // Medium is owned by document, so it's destroyed already
850 mpOwnMedium = nullptr;
852 else if ( mpBookmarkDoc )
854 DBG_ASSERT( !mpOwnMedium, "SfxMedium confusion!" );
855 if ( mpDoc )
857 // The document owns the Medium, so the Medium will be invalid after closing the document
858 const_cast<SdDrawDocument*>(mpDoc)->CloseBookmarkDoc();
859 mpMedium = nullptr;
862 else
864 // perhaps mpOwnMedium provided, but no successful creation of BookmarkDoc
865 delete mpOwnMedium;
866 mpOwnMedium = nullptr;
869 mpBookmarkDoc = nullptr;
872 void SdPageObjsTLB::SelectHdl()
874 SvTreeListEntry* pEntry = FirstSelected();
876 mbLinkableSelected = true;
878 while( pEntry && mbLinkableSelected )
880 if( nullptr == pEntry->GetUserData() )
881 mbLinkableSelected = false;
883 pEntry = NextSelected( pEntry );
886 SvTreeListBox::SelectHdl();
888 if (mbSelectionHandlerNavigates)
889 DoubleClickHdl();
893 * Overloads RETURN with the functionality of DoubleClick
895 void SdPageObjsTLB::KeyInput( const KeyEvent& rKEvt )
897 const vcl::KeyCode& aKeyCode = rKEvt.GetKeyCode();
898 if ( m_pAccel->execute( aKeyCode ) )
899 // the accelerator consumed the event
900 return;
901 if( rKEvt.GetKeyCode().GetCode() == KEY_RETURN )
903 // commented code from svtools/source/contnr/svimpbox.cxx
904 SvTreeListEntry* pCursor = GetCurEntry();
905 if (!pCursor)
906 return;
907 if( pCursor->HasChildren() || pCursor->HasChildrenOnDemand() )
909 if( IsExpanded( pCursor ) )
910 Collapse( pCursor );
911 else
912 Expand( pCursor );
915 DoubleClickHdl();
917 else if (rKEvt.GetKeyCode().GetCode() == KEY_SPACE)
919 if (mpNavigator)
921 SvTreeListEntry* pNewEntry = GetCurEntry();
922 if (!pNewEntry)
923 return;
924 SvTreeListEntry* pParentEntry = GetParent(pNewEntry);
925 if (!pParentEntry)
926 return;
927 Invalidate();
930 else
931 SvTreeListBox::KeyInput( rKEvt );
934 void SdPageObjsTLB::MouseButtonDown(const MouseEvent& rMEvt)
936 mbSelectionHandlerNavigates = rMEvt.GetClicks() == 1;
937 comphelper::ScopeGuard aNavigationGuard([this]() { this->mbSelectionHandlerNavigates = false; });
938 mbNavigationGrabsFocus = rMEvt.GetClicks() != 1;
939 comphelper::ScopeGuard aGrabGuard([this]() { this->mbNavigationGrabsFocus = true; });
941 SvTreeListBox::MouseButtonDown(rMEvt);
945 * StartDrag-Request
947 void SdPageObjsTLB::StartDrag( sal_Int8, const Point& rPosPixel)
949 SvTreeListEntry* pEntry = GetEntry(rPosPixel);
951 if (!(pEntry && mpNavigator && mpNavigator->GetNavigatorDragType() != NAVIGATOR_DRAGTYPE_NONE))
952 return;
954 // Mark only the children of the page under the mouse as drop
955 // targets. This prevents moving shapes from one page to another.
957 // Select all entries and disable them as drop targets.
958 SetSelectionMode(SelectionMode::Multiple);
959 SetCursor(static_cast<SvTreeListEntry*>(nullptr));
960 SelectAll(true, false);
961 EnableSelectionAsDropTarget(false);
963 // Enable only the entries as drop targets that are children of the
964 // page under the mouse.
965 SvTreeListEntry* pParent = GetRootLevelParent(pEntry);
966 if (pParent != nullptr)
968 SelectAll(false, false);
969 Select(pParent);
970 // for (SvTreeListEntry*pChild=FirstChild(pParent); pChild!=NULL; pChild=NextSibling(pChild))
971 // Select(pChild, sal_True);
972 EnableSelectionAsDropTarget();//sal_False);
975 // Set selection back to the entry under the mouse.
976 SelectAll(false, false);
977 SetSelectionMode(SelectionMode::Single);
978 Select(pEntry);
980 // We can delete the Navigator from ExecuteDrag (when switching to
981 // another document type), but that would kill the StarView MouseMove
982 // Handler which is calling Command().
983 // For this reason, Drag&Drop is asynchronous.
984 Application::PostUserEvent( LINK( this, SdPageObjsTLB, ExecDragHdl ), nullptr, true );
988 * Begin drag
990 void SdPageObjsTLB::DoDrag()
992 if (!mpNavigator)
993 return;
995 ::sd::DrawDocShell* pDocShell = mpDoc->GetDocSh();
996 OUString aURL = INetURLObject( pDocShell->GetMedium()->GetPhysicalName(), INetProtocol::File ).GetMainURL( INetURLObject::DecodeMechanism::NONE );
997 NavigatorDragType eDragType = mpNavigator->GetNavigatorDragType();
999 aURL += "#" + GetSelectedEntry();
1001 INetBookmark aBookmark( aURL, GetSelectedEntry() );
1002 sal_Int8 nDNDActions = DND_ACTION_COPYMOVE;
1004 if( eDragType == NAVIGATOR_DRAGTYPE_LINK )
1005 nDNDActions = DND_ACTION_LINK; // Either COPY *or* LINK, never both!
1006 else if (mpDoc->GetSdPageCount(PageKind::Standard) == 1)
1008 // Can not move away the last slide in a document.
1009 nDNDActions = DND_ACTION_COPY;
1012 SvTreeListBox::ReleaseMouse();
1014 bIsInDrag = true;
1016 // Get the view.
1017 ::sd::ViewShell* pViewShell = GetViewShellForDocShell(*pDocShell);
1018 if (pViewShell == nullptr)
1020 OSL_ASSERT(pViewShell!=nullptr);
1021 return;
1023 sd::View* pView = pViewShell->GetView();
1024 if (pView == nullptr)
1026 OSL_ASSERT(pView!=nullptr);
1027 return;
1030 // object is destroyed by internal reference mechanism
1031 SdTransferable* pTransferable =
1032 new SdPageObjsTLB::SdPageObjsTransferable(
1033 *this, aBookmark, *pDocShell, eDragType);
1035 SdrObject* pObject = nullptr;
1036 void* pUserData = GetCurEntry()->GetUserData();
1037 if (pUserData != nullptr && pUserData != reinterpret_cast<void*>(1))
1038 pObject = static_cast<SdrObject*>(pUserData);
1039 if (pObject != nullptr)
1041 // For shapes without a user supplied name (the automatically
1042 // created name does not count), a different drag and drop technique
1043 // is used.
1044 if (GetObjectName(pObject, false).isEmpty())
1046 AddShapeToTransferable(*pTransferable, *pObject);
1047 pTransferable->SetView(pView);
1048 SD_MOD()->pTransferDrag = pTransferable;
1051 // Unnamed shapes have to be selected to be recognized by the
1052 // current drop implementation. In order to have a consistent
1053 // behaviour for all shapes, every shape that is to be dragged is
1054 // selected first.
1055 SdrPageView* pPageView = pView->GetSdrPageView();
1056 pView->UnmarkAllObj(pPageView);
1057 pView->MarkObj(pObject, pPageView);
1059 else
1061 pTransferable->SetView(pView);
1062 SD_MOD()->pTransferDrag = pTransferable;
1065 pTransferable->StartDrag( this, nDNDActions );
1068 void SdPageObjsTLB::OnDragFinished()
1070 if (mpNavigator)
1072 MouseEvent aMEvt(mpNavigator->GetPointerPosPixel());
1073 SvTreeListBox::MouseButtonUp(aMEvt);
1076 bIsInDrag = false;
1080 * AcceptDrop-Event
1082 sal_Int8 SdPageObjsTLB::AcceptDrop (const AcceptDropEvent& rEvent)
1084 sal_Int8 nResult (DND_ACTION_NONE);
1086 if ( !bIsInDrag && IsDropFormatSupported( SotClipboardFormatId::SIMPLE_FILE ) )
1088 nResult = rEvent.mnAction;
1090 else
1092 SvTreeListEntry* pEntry = GetDropTarget(rEvent.maPosPixel);
1093 if (rEvent.mbLeaving || !CheckDragAndDropMode( this, rEvent.mnAction ))
1095 ImplShowTargetEmphasis( pTargetEntry, false );
1097 else if( GetDragDropMode() == DragDropMode::NONE )
1099 SAL_WARN( "sc.ui", "SdPageObjsTLB::AcceptDrop(): no target" );
1101 else if (IsDropAllowed(pEntry))
1103 nResult = DND_ACTION_MOVE;
1105 // Draw emphasis.
1106 if (pEntry != pTargetEntry || !(nImpFlags & SvTreeListBoxFlags::TARGEMPH_VIS))
1108 ImplShowTargetEmphasis( pTargetEntry, false );
1109 pTargetEntry = pEntry;
1110 ImplShowTargetEmphasis( pTargetEntry, true );
1115 // Hide emphasis when there is no valid drop action.
1116 if (nResult == DND_ACTION_NONE)
1117 ImplShowTargetEmphasis(pTargetEntry, false);
1119 return nResult;
1123 * ExecuteDrop-Event
1125 sal_Int8 SdPageObjsTLB::ExecuteDrop( const ExecuteDropEvent& rEvt )
1127 sal_Int8 nRet = DND_ACTION_NONE;
1131 if( !bIsInDrag )
1133 if (mpNavigator)
1135 TransferableDataHelper aDataHelper( rEvt.maDropEvent.Transferable );
1136 OUString aFile;
1138 if( aDataHelper.GetString( SotClipboardFormatId::SIMPLE_FILE, aFile ) &&
1139 mpNavigator->InsertFile( aFile ) )
1141 nRet = rEvt.mnAction;
1146 catch (css::uno::Exception&)
1148 DBG_UNHANDLED_EXCEPTION("sd");
1151 if (nRet == DND_ACTION_NONE)
1152 SvTreeListBox::ExecuteDrop(rEvt, this);
1154 return nRet;
1158 * Handler for Dragging
1160 IMPL_LINK_NOARG(SdPageObjsTLB, ExecDragHdl, void*, void)
1162 // as link, then it is allowed to asynchronous, without ImpMouseMoveMsg on
1163 // the stack, delete the Navigator
1164 DoDrag();
1167 bool SdPageObjsTLB::PageBelongsToCurrentShow (const SdPage* pPage) const
1169 // Return <TRUE/> as default when there is no custom show or when none
1170 // is used. The page does then belong to the standard show.
1171 bool bBelongsToShow = true;
1173 if (mpDoc->getPresentationSettings().mbCustomShow)
1175 // Get the current custom show.
1176 SdCustomShow* pCustomShow = nullptr;
1177 SdCustomShowList* pShowList = const_cast<SdDrawDocument*>(mpDoc)->GetCustomShowList();
1178 if (pShowList != nullptr)
1180 sal_uLong nCurrentShowIndex = pShowList->GetCurPos();
1181 pCustomShow = (*pShowList)[nCurrentShowIndex].get();
1184 // Check whether the given page is part of that custom show.
1185 if (pCustomShow != nullptr)
1187 bBelongsToShow = false;
1188 size_t nPageCount = pCustomShow->PagesVector().size();
1189 for (size_t i=0; i<nPageCount && !bBelongsToShow; i++)
1190 if (pPage == pCustomShow->PagesVector()[i])
1191 bBelongsToShow = true;
1195 return bBelongsToShow;
1198 TriState SdPageObjsTLB::NotifyMoving(
1199 SvTreeListEntry* pTarget,
1200 SvTreeListEntry* pEntry,
1201 SvTreeListEntry*& rpNewParent,
1202 sal_uLong& rNewChildPos)
1204 SvTreeListEntry* pDestination = pTarget;
1205 while (GetParent(pDestination) != nullptr && GetParent(GetParent(pDestination)) != nullptr)
1206 pDestination = GetParent(pDestination);
1208 SdrObject* pTargetObject = static_cast<SdrObject*>(pDestination->GetUserData());
1209 SdrObject* pSourceObject = static_cast<SdrObject*>(pEntry->GetUserData());
1210 if (pSourceObject == reinterpret_cast<SdrObject*>(1))
1211 pSourceObject = nullptr;
1213 if (pTargetObject != nullptr && pSourceObject != nullptr)
1215 SdrPage* pObjectList = pSourceObject->getSdrPageFromSdrObject();
1216 if (pObjectList != nullptr)
1218 sal_uInt32 nNewPosition;
1219 if (pTargetObject == reinterpret_cast<SdrObject*>(1))
1220 nNewPosition = 0;
1221 else
1222 nNewPosition = pTargetObject->GetNavigationPosition() + 1;
1223 pObjectList->SetObjectNavigationPosition(*pSourceObject, nNewPosition);
1226 // Update the tree list.
1227 if (GetParent(pDestination) == nullptr)
1229 rpNewParent = pDestination;
1230 rNewChildPos = 0;
1232 else
1234 rpNewParent = GetParent(pDestination);
1235 rNewChildPos = SvTreeList::GetRelPos(pDestination) + 1;
1236 rNewChildPos += nCurEntrySelPos;
1237 nCurEntrySelPos++;
1239 return TRISTATE_TRUE;
1241 else
1242 return TRISTATE_FALSE;
1245 SvTreeListEntry* SdPageObjsTLB::GetDropTarget (const Point& rLocation)
1247 SvTreeListEntry* pEntry = SvTreeListBox::GetDropTarget(rLocation);
1248 if (pEntry == nullptr)
1249 return nullptr;
1251 if (GetParent(pEntry) == nullptr)
1253 // Use page entry as insertion position.
1255 else
1257 // Go to second hierarchy level, i.e. top level shapes,
1258 // i.e. children of pages.
1259 while (GetParent(pEntry) != nullptr && GetParent(GetParent(pEntry)) != nullptr)
1260 pEntry = GetParent(pEntry);
1262 // Advance to next sibling.
1263 SvTreeListEntry* pNext;
1264 sal_uInt16 nDepth (0);
1267 pNext = NextVisible(pEntry, &nDepth);
1268 if (pNext != nullptr && nDepth > 0 && nDepth!=0xffff)
1269 pEntry = pNext;
1270 else
1271 break;
1273 while (pEntry != nullptr);
1276 return pEntry;
1279 bool SdPageObjsTLB::IsDropAllowed (SvTreeListEntry const * pEntry)
1281 if (pEntry == nullptr)
1282 return false;
1284 if ( ! IsDropFormatSupported(SdPageObjsTransferable::GetListBoxDropFormatId()))
1285 return false;
1287 if (pEntry->GetFlags() & SvTLEntryFlags::DISABLE_DROP)
1288 return false;
1290 return true;
1293 void SdPageObjsTLB::AddShapeToTransferable (
1294 SdTransferable& rTransferable,
1295 SdrObject& rObject) const
1297 std::unique_ptr<TransferableObjectDescriptor> pObjectDescriptor(new TransferableObjectDescriptor);
1298 bool bIsDescriptorFillingPending (true);
1300 const SdrOle2Obj* pOleObject = dynamic_cast<const SdrOle2Obj*>(&rObject);
1301 if (pOleObject != nullptr && pOleObject->GetObjRef().is())
1303 // If object has no persistence it must be copied as part of the document
1306 uno::Reference< embed::XEmbedPersist > xPersObj (pOleObject->GetObjRef(), uno::UNO_QUERY );
1307 if (xPersObj.is() && xPersObj->hasEntry())
1309 SvEmbedTransferHelper::FillTransferableObjectDescriptor(
1310 *pObjectDescriptor,
1311 pOleObject->GetObjRef(),
1312 pOleObject->GetGraphic(),
1313 pOleObject->GetAspect());
1314 bIsDescriptorFillingPending = false;
1317 catch( uno::Exception& )
1322 ::sd::DrawDocShell* pDocShell = mpDoc->GetDocSh();
1323 if (bIsDescriptorFillingPending && pDocShell!=nullptr)
1325 pDocShell->FillTransferableObjectDescriptor(*pObjectDescriptor);
1328 Point aDragPos (rObject.GetCurrentBoundRect().Center());
1329 //Point aDragPos (0,0);
1330 pObjectDescriptor->maDragStartPos = aDragPos;
1331 // aObjectDescriptor.maSize = GetAllMarkedRect().GetSize();
1332 if (pDocShell != nullptr)
1333 pObjectDescriptor->maDisplayName = pDocShell->GetMedium()->GetURLObject().GetURLNoPass();
1334 else
1335 pObjectDescriptor->maDisplayName.clear();
1337 rTransferable.SetStartPos(aDragPos);
1338 rTransferable.SetObjectDescriptor( std::move(pObjectDescriptor) );
1341 ::sd::ViewShell* SdPageObjsTLB::GetViewShellForDocShell (::sd::DrawDocShell& rDocShell)
1344 ::sd::ViewShell* pViewShell = rDocShell.GetViewShell();
1345 if (pViewShell != nullptr)
1346 return pViewShell;
1351 // Get a component enumeration from the desktop and search it for documents.
1352 uno::Reference<uno::XComponentContext> xContext( ::comphelper::getProcessComponentContext());
1354 uno::Reference<frame::XDesktop2> xDesktop = frame::Desktop::create(xContext);
1356 uno::Reference<frame::XFramesSupplier> xFrameSupplier (xDesktop, uno::UNO_QUERY);
1357 if ( ! xFrameSupplier.is())
1358 return nullptr;
1360 uno::Reference<container::XIndexAccess> xFrameAccess (xFrameSupplier->getFrames(), uno::UNO_QUERY);
1361 if ( ! xFrameAccess.is())
1362 return nullptr;
1364 for (sal_Int32 nIndex=0,nCount=xFrameAccess->getCount(); nIndex<nCount; ++nIndex)
1366 uno::Reference<frame::XFrame> xFrame;
1367 if ( ! (xFrameAccess->getByIndex(nIndex) >>= xFrame))
1368 continue;
1370 ::sd::DrawController* pController = dynamic_cast<sd::DrawController*>(xFrame->getController().get());
1371 if (pController == nullptr)
1372 continue;
1373 ::sd::ViewShellBase* pBase = pController->GetViewShellBase();
1374 if (pBase == nullptr)
1375 continue;
1376 if (pBase->GetDocShell() != &rDocShell)
1377 continue;
1379 const std::shared_ptr<sd::ViewShell> pViewShell (pBase->GetMainViewShell());
1380 if (pViewShell)
1381 return pViewShell.get();
1384 catch (uno::Exception &)
1386 // When there is an exception then simply use the default value of
1387 // bIsEnabled and disable the controls.
1389 return nullptr;
1392 //===== IconProvider ==========================================================
1394 SdPageObjsTLB::IconProvider::IconProvider()
1395 : maImgPage(StockImage::Yes, BMP_PAGE),
1396 maImgPageExcl(StockImage::Yes, BMP_PAGE_EXCLUDED),
1397 maImgPageObjsExcl(StockImage::Yes, BMP_PAGEOBJS_EXCLUDED),
1398 maImgPageObjs(StockImage::Yes, BMP_PAGEOBJS),
1399 maImgObjects(StockImage::Yes, BMP_OBJECTS),
1400 maImgGroup(StockImage::Yes, BMP_GROUP)
1404 SdPageObjsTLV::SdPageObjsTLV(std::unique_ptr<weld::TreeView> xTreeView)
1405 : m_xTreeView(std::move(xTreeView))
1406 , m_xAccel(::svt::AcceleratorExecute::createAcceleratorHelper())
1407 , m_pDoc(nullptr)
1408 , m_pBookmarkDoc(nullptr)
1409 , m_pMedium(nullptr)
1410 , m_bLinkableSelected(false)
1411 , m_bShowAllPages(false)
1413 m_xTreeView->connect_expanding(LINK(this, SdPageObjsTLV, RequestingChildrenHdl));
1414 m_xTreeView->connect_changed(LINK(this, SdPageObjsTLV, SelectHdl));
1417 IMPL_LINK_NOARG(SdPageObjsTLV, SelectHdl, weld::TreeView&, void)
1419 m_bLinkableSelected = true;
1421 m_xTreeView->selected_foreach([this](weld::TreeIter& rEntry){
1422 if (m_xTreeView->get_id(rEntry).toInt64() == 0)
1423 m_bLinkableSelected = false;
1424 return false;
1427 m_aChangeHdl.Call(*m_xTreeView);
1430 OUString SdPageObjsTLV::GetObjectName(const SdrObject* pObject)
1432 if ( !pObject )
1433 return OUString();
1435 OUString aRet = pObject->GetName();
1436 if (!aRet.isEmpty())
1437 return aRet;
1439 if (auto pOle = dynamic_cast<const SdrOle2Obj* >(pObject))
1440 aRet = pOle->GetPersistName();
1442 return aRet;
1445 std::vector<OUString> SdPageObjsTLV::GetSelectEntryList(const int nDepth) const
1447 std::vector<OUString> aEntries;
1449 m_xTreeView->selected_foreach([this, nDepth, &aEntries](weld::TreeIter& rEntry){
1450 int nListDepth = m_xTreeView->get_iter_depth(rEntry);
1451 if (nListDepth == nDepth)
1452 aEntries.push_back(m_xTreeView->get_text(rEntry));
1453 return false;
1456 return aEntries;
1460 * Checks if it is a draw file and opens the BookmarkDoc depending of
1461 * the provided Docs
1463 SdDrawDocument* SdPageObjsTLV::GetBookmarkDoc()
1465 if (!m_pBookmarkDoc)
1467 DBG_ASSERT( m_pMedium, "No SfxMedium provided!" );
1469 if ( m_pMedium )
1470 // in this mode the document is owned and controlled by the SdDrawDocument
1471 // it can be released by calling the corresponding CloseBookmarkDoc method
1472 // successful creation of a document makes this the owner of the medium
1473 m_pBookmarkDoc = const_cast<SdDrawDocument*>(m_pDoc)->OpenBookmarkDoc(m_pMedium);
1475 if ( !m_pBookmarkDoc )
1477 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xTreeView.get(),
1478 VclMessageType::Warning, VclButtonsType::Ok, SdResId(STR_READ_DATA_ERROR)));
1479 xErrorBox->run();
1480 m_pMedium = nullptr; //On failure the SfxMedium is invalid
1484 return m_pBookmarkDoc;
1488 * Entries are inserted only by request (double click)
1490 IMPL_LINK(SdPageObjsTLV, RequestingChildrenHdl, const weld::TreeIter&, rFileEntry, bool)
1492 if (!m_xTreeView->iter_has_child(rFileEntry))
1494 if (GetBookmarkDoc())
1496 SdrObject* pObj = nullptr;
1498 OUString sImgPage(BMP_PAGE);
1499 OUString sImgPageObjs(BMP_PAGEOBJS);
1500 OUString sImgObjects(BMP_OBJECTS);
1501 OUString sImgOle(BMP_OLE);
1502 OUString sImgGraphic(BMP_GRAPHIC);
1504 // document name already inserted
1506 // only insert all "normal" ? slides with objects
1507 sal_uInt16 nPage = 0;
1508 const sal_uInt16 nMaxPages = m_pBookmarkDoc->GetPageCount();
1510 std::unique_ptr<weld::TreeIter> xPageEntry;
1511 while (nPage < nMaxPages)
1513 SdPage* pPage = static_cast<SdPage*>(m_pBookmarkDoc->GetPage(nPage));
1514 if (pPage->GetPageKind() == PageKind::Standard)
1516 OUString sId(OUString::number(1));
1517 m_xTreeView->insert(&rFileEntry, -1, &pPage->GetName(), &sId,
1518 nullptr, nullptr, &sImgPage, false, nullptr);
1520 if (!xPageEntry)
1522 xPageEntry = m_xTreeView->make_iterator(&rFileEntry);
1523 m_xTreeView->iter_children(*xPageEntry);
1525 else
1526 m_xTreeView->iter_next_sibling(*xPageEntry);
1528 SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups );
1530 while( aIter.IsMore() )
1532 pObj = aIter.Next();
1533 OUString aStr( GetObjectName( pObj ) );
1534 if( !aStr.isEmpty() )
1536 if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == OBJ_OLE2 )
1538 m_xTreeView->insert(xPageEntry.get(), -1, &aStr, nullptr,
1539 nullptr, nullptr, &sImgOle, false, nullptr);
1541 else if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == OBJ_GRAF )
1543 m_xTreeView->insert(xPageEntry.get(), -1, &aStr, nullptr,
1544 nullptr, nullptr, &sImgGraphic, false, nullptr);
1546 else
1548 m_xTreeView->insert(xPageEntry.get(), -1, &aStr, nullptr,
1549 nullptr, nullptr, &sImgObjects, false, nullptr);
1553 if (m_xTreeView->iter_has_child(*xPageEntry))
1555 m_xTreeView->set_image(*xPageEntry, sImgPageObjs);
1558 nPage++;
1562 return true;
1565 void SdPageObjsTLV::SetViewFrame(const SfxViewFrame* pViewFrame)
1567 sd::ViewShellBase* pBase = sd::ViewShellBase::GetViewShellBase(pViewFrame);
1568 const css::uno::Reference< css::frame::XFrame > xFrame = pBase->GetMainViewShell()->GetViewFrame()->GetFrame().GetFrameInterface();
1569 m_xAccel->init(::comphelper::getProcessComponentContext(), xFrame);
1573 * Close and delete bookmark document
1575 void SdPageObjsTLV::CloseBookmarkDoc()
1577 if (m_xBookmarkDocShRef.is())
1579 m_xBookmarkDocShRef->DoClose();
1580 m_xBookmarkDocShRef.clear();
1582 else if (m_pBookmarkDoc)
1584 if (m_pDoc)
1586 // The document owns the Medium, so the Medium will be invalid after closing the document
1587 const_cast<SdDrawDocument*>(m_pDoc)->CloseBookmarkDoc();
1588 m_pMedium = nullptr;
1592 m_pBookmarkDoc = nullptr;
1595 bool SdPageObjsTLV::PageBelongsToCurrentShow(const SdPage* pPage) const
1597 // Return <TRUE/> as default when there is no custom show or when none
1598 // is used. The page does then belong to the standard show.
1599 bool bBelongsToShow = true;
1601 if (m_pDoc->getPresentationSettings().mbCustomShow)
1603 // Get the current custom show.
1604 SdCustomShow* pCustomShow = nullptr;
1605 SdCustomShowList* pShowList = const_cast<SdDrawDocument*>(m_pDoc)->GetCustomShowList();
1606 if (pShowList != nullptr)
1608 sal_uLong nCurrentShowIndex = pShowList->GetCurPos();
1609 pCustomShow = (*pShowList)[nCurrentShowIndex].get();
1612 // Check whether the given page is part of that custom show.
1613 if (pCustomShow != nullptr)
1615 bBelongsToShow = false;
1616 size_t nPageCount = pCustomShow->PagesVector().size();
1617 for (size_t i=0; i<nPageCount && !bBelongsToShow; i++)
1618 if (pPage == pCustomShow->PagesVector()[i])
1619 bBelongsToShow = true;
1623 return bBelongsToShow;
1626 void SdPageObjsTLV::AddShapeList (
1627 const SdrObjList& rList,
1628 SdrObject* pShape,
1629 const OUString& rsName,
1630 const bool bIsExcluded,
1631 weld::TreeIter* pParentEntry)
1633 OUString aIcon(BMP_PAGE);
1634 if (bIsExcluded)
1635 aIcon = BMP_PAGE_EXCLUDED;
1636 else if (pShape != nullptr)
1637 aIcon = BMP_GROUP;
1639 OUString aUserData("1");
1640 if (pShape != nullptr)
1641 aUserData = OUString::number(reinterpret_cast<sal_Int64>(pShape));
1643 std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
1644 InsertEntry(pParentEntry, aUserData, rsName, aIcon, xEntry.get());
1646 SdrObjListIter aIter(
1647 &rList,
1648 !rList.HasObjectNavigationOrder() /* use navigation order, if available */,
1649 SdrIterMode::Flat);
1651 while( aIter.IsMore() )
1653 SdrObject* pObj = aIter.Next();
1654 OSL_ASSERT(pObj!=nullptr);
1656 // Get the shape name.
1657 OUString aStr (GetObjectName( pObj ) );
1658 OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pObj)));
1660 if( !aStr.isEmpty() )
1662 if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == OBJ_OLE2 )
1664 InsertEntry(xEntry.get(), sId, aStr, BMP_OLE);
1666 else if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == OBJ_GRAF )
1668 InsertEntry(xEntry.get(), sId, aStr, BMP_GRAPHIC);
1670 else if (pObj->IsGroupObject())
1672 AddShapeList(
1673 *pObj->GetSubList(),
1674 pObj,
1675 aStr,
1676 false,
1677 xEntry.get());
1679 else
1681 InsertEntry(xEntry.get(), sId, aStr, BMP_OBJECTS);
1686 if (!m_xTreeView->iter_has_child(*xEntry))
1687 return;
1689 if (bIsExcluded)
1690 m_xTreeView->set_image(*xEntry, BMP_PAGEOBJS_EXCLUDED);
1691 else
1692 m_xTreeView->set_image(*xEntry, BMP_PAGEOBJS);
1693 m_xTreeView->expand_row(*xEntry);
1697 * Fill TreeLB with pages and objects
1699 void SdPageObjsTLV::Fill(const SdDrawDocument* pInDoc, bool bAllPages, const OUString& rDocName)
1701 OUString aSelection = m_xTreeView->get_selected_text();
1702 clear();
1704 m_pDoc = pInDoc;
1705 m_aDocName = rDocName;
1706 m_bShowAllPages = bAllPages;
1707 m_pMedium = nullptr;
1709 // first insert all pages including objects
1710 sal_uInt16 nPage = 0;
1711 const sal_uInt16 nMaxPages = m_pDoc->GetPageCount();
1713 while( nPage < nMaxPages )
1715 const SdPage* pPage = static_cast<const SdPage*>( m_pDoc->GetPage( nPage ) );
1716 if( (m_bShowAllPages || pPage->GetPageKind() == PageKind::Standard)
1717 && (pPage->GetPageKind() != PageKind::Handout) ) //#94954# never list the normal handout page ( handout-masterpage is used instead )
1719 bool bPageExluded = pPage->IsExcluded();
1721 bool bPageBelongsToShow = PageBelongsToCurrentShow (pPage);
1722 bPageExluded |= !bPageBelongsToShow;
1724 AddShapeList(*pPage, nullptr, pPage->GetName(), bPageExluded, nullptr);
1726 nPage++;
1729 // then insert all master pages including objects
1730 if( m_bShowAllPages )
1732 nPage = 0;
1733 const sal_uInt16 nMaxMasterPages = m_pDoc->GetMasterPageCount();
1735 while( nPage < nMaxMasterPages )
1737 const SdPage* pPage = static_cast<const SdPage*>( m_pDoc->GetMasterPage( nPage ) );
1738 AddShapeList(*pPage, nullptr, pPage->GetName(), false, nullptr);
1739 nPage++;
1742 if (!aSelection.isEmpty())
1743 m_xTreeView->select_text(aSelection);
1747 * We insert only the first entry. Children are created on demand.
1749 void SdPageObjsTLV::Fill( const SdDrawDocument* pInDoc, SfxMedium* pInMedium,
1750 const OUString& rDocName )
1752 m_pDoc = pInDoc;
1754 // this object now owns the Medium
1755 m_pMedium = pInMedium;
1756 m_aDocName = rDocName;
1758 OUString sImgDoc(BMP_DOC_OPEN);
1760 OUString sId(OUString::number(1));
1761 // insert document name
1762 m_xTreeView->insert(nullptr, -1, &m_aDocName, &sId, nullptr, nullptr, &sImgDoc, true, nullptr);
1766 * select a entry in TreeLB
1768 bool SdPageObjsTLV::SelectEntry( const OUString& rName )
1770 bool bFound = false;
1772 if (!rName.isEmpty())
1774 std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
1775 OUString aTmp;
1777 if (m_xTreeView->get_iter_first(*xEntry))
1781 aTmp = m_xTreeView->get_text(*xEntry);
1782 if (aTmp == rName)
1784 m_xTreeView->set_cursor(*xEntry);
1785 m_xTreeView->select(*xEntry);
1786 bFound = true;
1787 break;
1790 while (m_xTreeView->iter_next(*xEntry));
1794 return bFound;
1797 SdPageObjsTLV::~SdPageObjsTLV()
1799 if (m_pBookmarkDoc)
1800 CloseBookmarkDoc();
1801 else
1803 // no document was created from m_pMedium, so this object is still the owner of it
1804 delete m_pMedium;
1806 m_xAccel.reset();
1809 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */