Change-Id: I50b864ffc4ed13ba801af46815988bf568b83d2e Reviewed-on: https://gerrit.libreoffice.org/66832 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
1428 lines
43 KiB
C++
1428 lines
43 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <sal/types.h>
|
|
#include <sal/log.hxx>
|
|
#include <sot/formats.hxx>
|
|
#include <sot/storage.hxx>
|
|
#include <vcl/weld.hxx>
|
|
#include <svl/urihelper.hxx>
|
|
#include <svx/svditer.hxx>
|
|
#include <sfx2/docfile.hxx>
|
|
#include <svx/svdoole2.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
#include <vcl/builderfactory.hxx>
|
|
#include <cusshow.hxx>
|
|
#include <sfx2/childwin.hxx>
|
|
|
|
#include <sfx2/viewfrm.hxx>
|
|
|
|
#include <strmname.h>
|
|
#include <sdtreelb.hxx>
|
|
#include <DrawDocShell.hxx>
|
|
#include <drawdoc.hxx>
|
|
#include <sdpage.hxx>
|
|
#include <sdmod.hxx>
|
|
#include <sdresid.hxx>
|
|
#include <navigatr.hxx>
|
|
#include <strings.hrc>
|
|
|
|
#include <bitmaps.hlst>
|
|
#include <customshowlist.hxx>
|
|
#include <ViewShell.hxx>
|
|
#include <DrawController.hxx>
|
|
#include <ViewShellBase.hxx>
|
|
|
|
#include <com/sun/star/embed/XEmbedPersist.hpp>
|
|
#include <com/sun/star/frame/Desktop.hpp>
|
|
#include <com/sun/star/frame/XFramesSupplier.hpp>
|
|
#include <svtools/acceleratorexecute.hxx>
|
|
#include <svtools/embedtransfer.hxx>
|
|
#include <vcl/svlbitm.hxx>
|
|
#include <vcl/treelistentry.hxx>
|
|
#include <comphelper/servicehelper.hxx>
|
|
#include <comphelper/processfactory.hxx>
|
|
#include <tools/diagnose_ex.h>
|
|
#include <o3tl/make_unique.hxx>
|
|
#include <comphelper/scopeguard.hxx>
|
|
|
|
|
|
using namespace com::sun::star;
|
|
|
|
class SdPageObjsTLB::IconProvider
|
|
{
|
|
public:
|
|
IconProvider();
|
|
|
|
// Regular icons.
|
|
Image const maImgPage;
|
|
Image const maImgPageExcl;
|
|
Image const maImgPageObjsExcl;
|
|
Image const maImgPageObjs;
|
|
Image const maImgObjects;
|
|
Image const maImgGroup;
|
|
};
|
|
|
|
bool SdPageObjsTLB::bIsInDrag = false;
|
|
|
|
bool SdPageObjsTLB::IsInDrag()
|
|
{
|
|
return bIsInDrag;
|
|
}
|
|
|
|
SotClipboardFormatId SdPageObjsTLB::SdPageObjsTransferable::mnListBoxDropFormatId = static_cast<SotClipboardFormatId>(SAL_MAX_UINT32);
|
|
|
|
|
|
SdPageObjsTLB::SdPageObjsTransferable::SdPageObjsTransferable(
|
|
SdPageObjsTLB& rParent,
|
|
const INetBookmark& rBookmark,
|
|
::sd::DrawDocShell& rDocShell,
|
|
NavigatorDragType eDragType)
|
|
: SdTransferable(rDocShell.GetDoc(), nullptr, true),
|
|
mrParent( rParent ),
|
|
maBookmark( rBookmark ),
|
|
mrDocShell( rDocShell ),
|
|
meDragType( eDragType )
|
|
{
|
|
rParent.SetupDragOrigin();
|
|
}
|
|
|
|
VCL_BUILDER_FACTORY_CONSTRUCTOR(SdPageObjsTLB, WB_TABSTOP)
|
|
|
|
SdPageObjsTLB::SdPageObjsTransferable::~SdPageObjsTransferable()
|
|
{
|
|
}
|
|
|
|
void SdPageObjsTLB::SdPageObjsTransferable::AddSupportedFormats()
|
|
{
|
|
AddFormat(SotClipboardFormatId::NETSCAPE_BOOKMARK);
|
|
AddFormat(SotClipboardFormatId::TREELISTBOX);
|
|
AddFormat(GetListBoxDropFormatId());
|
|
}
|
|
|
|
bool SdPageObjsTLB::SdPageObjsTransferable::GetData( const css::datatransfer::DataFlavor& rFlavor, const OUString& /*rDestDoc*/ )
|
|
{
|
|
SotClipboardFormatId nFormatId = SotExchange::GetFormat( rFlavor );
|
|
switch (nFormatId)
|
|
{
|
|
case SotClipboardFormatId::NETSCAPE_BOOKMARK:
|
|
SetINetBookmark( maBookmark, rFlavor );
|
|
return true;
|
|
|
|
case SotClipboardFormatId::TREELISTBOX:
|
|
{
|
|
css::uno::Any aTreeListBoxData; // empty for now
|
|
SetAny(aTreeListBoxData);
|
|
return true;
|
|
}
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void SdPageObjsTLB::SdPageObjsTransferable::DragFinished( sal_Int8 nDropAction )
|
|
{
|
|
mrParent.OnDragFinished();
|
|
SdTransferable::DragFinished(nDropAction);
|
|
}
|
|
|
|
sal_Int64 SAL_CALL SdPageObjsTLB::SdPageObjsTransferable::getSomething( const css::uno::Sequence< sal_Int8 >& rId )
|
|
{
|
|
sal_Int64 nRet;
|
|
|
|
if( ( rId.getLength() == 16 ) &&
|
|
( 0 == memcmp( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
|
|
{
|
|
nRet = static_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
|
|
}
|
|
else
|
|
nRet = SdTransferable::getSomething(rId);
|
|
|
|
return nRet;
|
|
}
|
|
|
|
namespace
|
|
{
|
|
class theSdPageObjsTLBUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSdPageObjsTLBUnoTunnelId > {};
|
|
}
|
|
|
|
const css::uno::Sequence< sal_Int8 >& SdPageObjsTLB::SdPageObjsTransferable::getUnoTunnelId()
|
|
{
|
|
return theSdPageObjsTLBUnoTunnelId::get().getSeq();
|
|
}
|
|
|
|
SdPageObjsTLB::SdPageObjsTransferable* SdPageObjsTLB::SdPageObjsTransferable::getImplementation( const css::uno::Reference< css::uno::XInterface >& rxData )
|
|
throw()
|
|
{
|
|
try
|
|
{
|
|
css::uno::Reference< css::lang::XUnoTunnel > xUnoTunnel( rxData, css::uno::UNO_QUERY_THROW );
|
|
|
|
return reinterpret_cast<SdPageObjsTLB::SdPageObjsTransferable*>(
|
|
sal::static_int_cast<sal_uIntPtr>(
|
|
xUnoTunnel->getSomething( SdPageObjsTLB::SdPageObjsTransferable::getUnoTunnelId()) ) );
|
|
}
|
|
catch( const css::uno::Exception& )
|
|
{
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
SotClipboardFormatId SdPageObjsTLB::SdPageObjsTransferable::GetListBoxDropFormatId()
|
|
{
|
|
if (mnListBoxDropFormatId == static_cast<SotClipboardFormatId>(SAL_MAX_UINT32))
|
|
mnListBoxDropFormatId = SotExchange::RegisterFormatMimeType("application/x-openoffice-treelistbox-moveonly;windows_formatname=\"SV_LBOX_DD_FORMAT_MOVE\"");
|
|
return mnListBoxDropFormatId;
|
|
}
|
|
|
|
SdPageObjsTLB::SdPageObjsTLB( vcl::Window* pParentWin, WinBits nStyle )
|
|
: SvTreeListBox ( pParentWin, nStyle )
|
|
, mpDoc ( nullptr )
|
|
, mpBookmarkDoc ( nullptr )
|
|
, mpMedium ( nullptr )
|
|
, mpOwnMedium ( nullptr )
|
|
, maImgOle ( StockImage::Yes, BMP_OLE )
|
|
, maImgGraphic ( StockImage::Yes, BMP_GRAPHIC )
|
|
, mbLinkableSelected ( false )
|
|
, mbSaveTreeItemState ( false )
|
|
, mbShowAllShapes ( false )
|
|
, mbShowAllPages ( false )
|
|
, mbSelectionHandlerNavigates(false)
|
|
, mbNavigationGrabsFocus(true)
|
|
{
|
|
// add lines to Tree-ListBox
|
|
SetStyle( GetStyle() | WB_TABSTOP | WB_BORDER | WB_HASLINES |
|
|
WB_HASBUTTONS | // WB_HASLINESATROOT |
|
|
WB_HSCROLL |
|
|
WB_HASBUTTONSATROOT );
|
|
SetQuickSearch(true); /* i31275 */;
|
|
SetNodeBitmaps(Image(StockImage::Yes, BMP_EXPAND), Image(StockImage::Yes, BMP_COLLAPSE));
|
|
|
|
SetDragDropMode(
|
|
DragDropMode::CTRL_MOVE | DragDropMode::CTRL_COPY |
|
|
DragDropMode::APP_MOVE | DragDropMode::APP_COPY | DragDropMode::APP_DROP );
|
|
|
|
m_pAccel = ::svt::AcceleratorExecute::createAcceleratorHelper();
|
|
}
|
|
|
|
void SdPageObjsTLB::SetSdNavigator(SdNavigatorWin* pNavigator)
|
|
{
|
|
mpNavigator = pNavigator;
|
|
}
|
|
|
|
void SdPageObjsTLB::SetViewFrame( const SfxViewFrame* pViewFrame )
|
|
{
|
|
sd::ViewShellBase* pBase = sd::ViewShellBase::GetViewShellBase(pViewFrame);
|
|
const css::uno::Reference< css::frame::XFrame > xFrame = pBase->GetMainViewShell()->GetViewFrame()->GetFrame().GetFrameInterface();
|
|
m_pAccel->init(::comphelper::getProcessComponentContext(), xFrame);
|
|
}
|
|
|
|
|
|
SdPageObjsTLB::~SdPageObjsTLB()
|
|
{
|
|
disposeOnce();
|
|
}
|
|
|
|
void SdPageObjsTLB::dispose()
|
|
{
|
|
if ( mpBookmarkDoc )
|
|
CloseBookmarkDoc();
|
|
else
|
|
// no document was created from mpMedium, so this object is still the owner of it
|
|
delete mpMedium;
|
|
mpNavigator.clear();
|
|
m_pAccel.reset();
|
|
SvTreeListBox::dispose();
|
|
}
|
|
|
|
// helper function for GetEntryAltText and GetEntryLongDescription
|
|
OUString SdPageObjsTLB::getAltLongDescText(SvTreeListEntry* pEntry , bool isAltText) const
|
|
{
|
|
sal_uInt16 maxPages = mpDoc->GetPageCount();
|
|
sal_uInt16 pageNo;
|
|
SdrObject* pObj = nullptr;
|
|
|
|
OUString ParentName = GetEntryText( GetRootLevelParent( pEntry ) );
|
|
|
|
for( pageNo = 0; pageNo < maxPages; pageNo++ )
|
|
{
|
|
const SdPage* pPage = static_cast<const SdPage*>( mpDoc->GetPage( pageNo ) );
|
|
if( pPage->GetPageKind() != PageKind::Standard ) continue;
|
|
if( pPage->GetName() != ParentName ) continue;
|
|
SdrObjListIter aIter( pPage, SdrIterMode::Flat );
|
|
while( aIter.IsMore() )
|
|
{
|
|
pObj = aIter.Next();
|
|
if( GetEntryText(pEntry) == GetObjectName( pObj ) )
|
|
{
|
|
if( isAltText )
|
|
return pObj->GetTitle();
|
|
else
|
|
return pObj->GetDescription();
|
|
}
|
|
}
|
|
}
|
|
return OUString();
|
|
|
|
}
|
|
|
|
OUString SdPageObjsTLB::GetEntryAltText( SvTreeListEntry* pEntry ) const
|
|
{
|
|
return getAltLongDescText( pEntry, true );
|
|
}
|
|
|
|
OUString SdPageObjsTLB::GetEntryLongDescription( SvTreeListEntry* pEntry ) const
|
|
{
|
|
return getAltLongDescText( pEntry, false);
|
|
}
|
|
|
|
void SdPageObjsTLB::InitEntry(SvTreeListEntry* pEntry,
|
|
const OUString& rStr, const Image& rImg1, const Image& rImg2, SvLBoxButtonKind eButtonKind)
|
|
{
|
|
sal_uInt16 nColToHilite = 1; //0==Bitmap;1=="Spalte1";2=="Spalte2"
|
|
SvTreeListBox::InitEntry( pEntry, rStr, rImg1, rImg2, eButtonKind );
|
|
SvLBoxString& rCol = static_cast<SvLBoxString&>(pEntry->GetItem( nColToHilite ));
|
|
pEntry->ReplaceItem(o3tl::make_unique<SvLBoxString>(rCol.GetText()), nColToHilite );
|
|
}
|
|
|
|
void SdPageObjsTLB::SaveExpandedTreeItemState(SvTreeListEntry* pEntry, std::vector<OUString>& vectTreeItem)
|
|
{
|
|
if (pEntry)
|
|
{
|
|
SvTreeListEntry* pListEntry = pEntry;
|
|
while (pListEntry)
|
|
{
|
|
if (pListEntry->HasChildren())
|
|
{
|
|
if (IsExpanded(pListEntry))
|
|
vectTreeItem.push_back(GetEntryText(pListEntry));
|
|
SvTreeListEntry* pChildEntry = FirstChild(pListEntry);
|
|
SaveExpandedTreeItemState(pChildEntry, vectTreeItem);
|
|
}
|
|
pListEntry = pListEntry->NextSibling();
|
|
}
|
|
}
|
|
}
|
|
void SdPageObjsTLB::Clear()
|
|
{
|
|
//Save the expanded tree item
|
|
if (mbSaveTreeItemState)
|
|
{
|
|
maSelectionEntryText.clear();
|
|
maTreeItem.clear();
|
|
if (GetCurEntry())
|
|
maSelectionEntryText = GetSelectedEntry();
|
|
SvTreeListEntry* pEntry = FirstChild(nullptr);
|
|
SaveExpandedTreeItemState(pEntry, maTreeItem);
|
|
}
|
|
return SvTreeListBox::Clear();
|
|
}
|
|
|
|
OUString SdPageObjsTLB::GetObjectName(
|
|
const SdrObject* pObject,
|
|
const bool bCreate) const
|
|
{
|
|
OUString aRet;
|
|
|
|
if ( pObject )
|
|
{
|
|
aRet = pObject->GetName();
|
|
|
|
if (aRet.isEmpty() && dynamic_cast<const SdrOle2Obj* >(pObject) != nullptr)
|
|
aRet = static_cast< const SdrOle2Obj* >( pObject )->GetPersistName();
|
|
}
|
|
|
|
if (bCreate
|
|
&& mbShowAllShapes
|
|
&& aRet.isEmpty()
|
|
&& pObject!=nullptr)
|
|
{
|
|
aRet = SdResId(STR_NAVIGATOR_SHAPE_BASE_NAME);
|
|
aRet = aRet.replaceFirst("%1", OUString::number(pObject->GetOrdNum() + 1));
|
|
}
|
|
|
|
return aRet;
|
|
}
|
|
|
|
/**
|
|
* select a entry in TreeLB
|
|
*/
|
|
bool SdPageObjsTLB::SelectEntry( const OUString& rName )
|
|
{
|
|
bool bFound = false;
|
|
|
|
if( !rName.isEmpty() )
|
|
{
|
|
SvTreeListEntry* pEntry = nullptr;
|
|
OUString aTmp;
|
|
|
|
for( pEntry = First(); pEntry && !bFound; pEntry = Next( pEntry ) )
|
|
{
|
|
aTmp = GetEntryText( pEntry );
|
|
if( aTmp == rName )
|
|
{
|
|
bFound = true;
|
|
SetCurEntry( pEntry );
|
|
}
|
|
}
|
|
}
|
|
return bFound;
|
|
}
|
|
|
|
/**
|
|
* @return true if children of the specified string are selected
|
|
*/
|
|
bool SdPageObjsTLB::HasSelectedChildren( const OUString& rName )
|
|
{
|
|
bool bChildren = false;
|
|
|
|
if( !rName.isEmpty() )
|
|
{
|
|
bool bFound = false;
|
|
SvTreeListEntry* pEntry = nullptr;
|
|
OUString aTmp;
|
|
|
|
for( pEntry = First(); pEntry && !bFound; pEntry = Next( pEntry ) )
|
|
{
|
|
aTmp = GetEntryText( pEntry );
|
|
if( aTmp == rName )
|
|
{
|
|
bFound = true;
|
|
bool bExpanded = IsExpanded( pEntry );
|
|
long nCount = GetChildSelectionCount( pEntry );
|
|
if( bExpanded && nCount > 0 )
|
|
bChildren = true;
|
|
}
|
|
}
|
|
}
|
|
return bChildren;
|
|
}
|
|
|
|
/**
|
|
* Fill TreeLB with pages and objects
|
|
*/
|
|
void SdPageObjsTLB::Fill( const SdDrawDocument* pInDoc, bool bAllPages,
|
|
const OUString& rDocName)
|
|
{
|
|
OUString aSelection;
|
|
if( GetSelectionCount() > 0 )
|
|
{
|
|
aSelection = GetSelectedEntry();
|
|
Clear();
|
|
}
|
|
|
|
mpDoc = pInDoc;
|
|
maDocName = rDocName;
|
|
mbShowAllPages = bAllPages;
|
|
mpMedium = nullptr;
|
|
|
|
IconProvider aIconProvider;
|
|
|
|
// first insert all pages including objects
|
|
sal_uInt16 nPage = 0;
|
|
const sal_uInt16 nMaxPages = mpDoc->GetPageCount();
|
|
|
|
while( nPage < nMaxPages )
|
|
{
|
|
const SdPage* pPage = static_cast<const SdPage*>( mpDoc->GetPage( nPage ) );
|
|
if( (mbShowAllPages || pPage->GetPageKind() == PageKind::Standard)
|
|
&& (pPage->GetPageKind() != PageKind::Handout) ) //#94954# never list the normal handout page ( handout-masterpage is used instead )
|
|
{
|
|
bool bPageExluded = pPage->IsExcluded();
|
|
|
|
bool bPageBelongsToShow = PageBelongsToCurrentShow (pPage);
|
|
bPageExluded |= !bPageBelongsToShow;
|
|
|
|
AddShapeList(*pPage, nullptr, pPage->GetName(), bPageExluded, nullptr, aIconProvider);
|
|
}
|
|
nPage++;
|
|
}
|
|
|
|
// then insert all master pages including objects
|
|
if( mbShowAllPages )
|
|
{
|
|
nPage = 0;
|
|
const sal_uInt16 nMaxMasterPages = mpDoc->GetMasterPageCount();
|
|
|
|
while( nPage < nMaxMasterPages )
|
|
{
|
|
const SdPage* pPage = static_cast<const SdPage*>( mpDoc->GetMasterPage( nPage ) );
|
|
AddShapeList(*pPage, nullptr, pPage->GetName(), false, nullptr, aIconProvider);
|
|
nPage++;
|
|
}
|
|
}
|
|
if( !aSelection.isEmpty() )
|
|
SelectEntry( aSelection );
|
|
else if (mbSaveTreeItemState && !maSelectionEntryText.isEmpty())
|
|
{
|
|
SelectEntry(maSelectionEntryText);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* We insert only the first entry. Children are created on demand.
|
|
*/
|
|
void SdPageObjsTLB::Fill( const SdDrawDocument* pInDoc, SfxMedium* pInMedium,
|
|
const OUString& rDocName )
|
|
{
|
|
mpDoc = pInDoc;
|
|
|
|
// this object now owns the Medium
|
|
mpMedium = pInMedium;
|
|
maDocName = rDocName;
|
|
|
|
Image aImgDocOpen(StockImage::Yes, BMP_DOC_OPEN);
|
|
Image aImgDocClosed(StockImage::Yes, BMP_DOC_CLOSED);
|
|
|
|
// insert document name
|
|
InsertEntry( maDocName, aImgDocOpen, aImgDocClosed, nullptr, true, TREELIST_APPEND,
|
|
reinterpret_cast< void* >( 1 )
|
|
);
|
|
}
|
|
|
|
void SdPageObjsTLB::AddShapeList (
|
|
const SdrObjList& rList,
|
|
SdrObject* pShape,
|
|
const OUString& rsName,
|
|
const bool bIsExcluded,
|
|
SvTreeListEntry* pParentEntry,
|
|
const IconProvider& rIconProvider)
|
|
{
|
|
Image aIcon (rIconProvider.maImgPage);
|
|
if (bIsExcluded)
|
|
aIcon = rIconProvider.maImgPageExcl;
|
|
else if (pShape != nullptr)
|
|
aIcon = rIconProvider.maImgGroup;
|
|
|
|
void* pUserData (reinterpret_cast<void*>(1));
|
|
if (pShape != nullptr)
|
|
pUserData = pShape;
|
|
|
|
SvTreeListEntry* pEntry = InsertEntry(
|
|
rsName,
|
|
aIcon,
|
|
aIcon,
|
|
pParentEntry,
|
|
false,
|
|
TREELIST_APPEND,
|
|
pUserData);
|
|
|
|
SdrObjListIter aIter(
|
|
&rList,
|
|
!rList.HasObjectNavigationOrder() /* use navigation order, if available */,
|
|
SdrIterMode::Flat);
|
|
|
|
while( aIter.IsMore() )
|
|
{
|
|
SdrObject* pObj = aIter.Next();
|
|
OSL_ASSERT(pObj!=nullptr);
|
|
|
|
// Get the shape name.
|
|
OUString aStr (GetObjectName( pObj ) );
|
|
|
|
if( !aStr.isEmpty() )
|
|
{
|
|
if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == OBJ_OLE2 )
|
|
{
|
|
InsertEntry(
|
|
aStr,
|
|
maImgOle,
|
|
maImgOle,
|
|
pEntry,
|
|
false,
|
|
TREELIST_APPEND,
|
|
pObj
|
|
);
|
|
}
|
|
else if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == OBJ_GRAF )
|
|
{
|
|
InsertEntry(
|
|
aStr,
|
|
maImgGraphic,
|
|
maImgGraphic,
|
|
pEntry,
|
|
false,
|
|
TREELIST_APPEND,
|
|
pObj
|
|
);
|
|
}
|
|
else if (pObj->IsGroupObject())
|
|
{
|
|
AddShapeList(
|
|
*pObj->GetSubList(),
|
|
pObj,
|
|
aStr,
|
|
false,
|
|
pEntry,
|
|
rIconProvider
|
|
);
|
|
}
|
|
else
|
|
{
|
|
InsertEntry(
|
|
aStr,
|
|
rIconProvider.maImgObjects,
|
|
rIconProvider.maImgObjects,
|
|
pEntry,
|
|
false,
|
|
TREELIST_APPEND,
|
|
pObj
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
if( pEntry->HasChildren() )
|
|
{
|
|
SetExpandedEntryBmp(
|
|
pEntry,
|
|
bIsExcluded ? rIconProvider.maImgPageObjsExcl : rIconProvider.maImgPageObjs);
|
|
SetCollapsedEntryBmp(
|
|
pEntry,
|
|
bIsExcluded ? rIconProvider.maImgPageObjsExcl : rIconProvider.maImgPageObjs);
|
|
if (mbSaveTreeItemState)
|
|
{
|
|
OUString strEntry = GetEntryText(pEntry);
|
|
auto it = std::find(maTreeItem.begin(), maTreeItem.end(), strEntry);
|
|
if (it != maTreeItem.end())
|
|
Expand( pEntry );
|
|
}
|
|
else
|
|
Expand( pEntry );
|
|
}
|
|
}
|
|
|
|
void SdPageObjsTLB::SetShowAllShapes (
|
|
const bool bShowAllShapes,
|
|
const bool bFillList)
|
|
{
|
|
mbShowAllShapes = bShowAllShapes;
|
|
if (bFillList)
|
|
{
|
|
if (mpMedium == nullptr)
|
|
Fill(mpDoc, mbShowAllPages, maDocName);
|
|
else
|
|
Fill(mpDoc, mpMedium, maDocName);
|
|
}
|
|
}
|
|
|
|
bool SdPageObjsTLB::IsEqualToShapeList(SvTreeListEntry*& pEntry, const SdrObjList& rList,
|
|
const OUString& rListName)
|
|
{
|
|
if (!pEntry)
|
|
return false;
|
|
OUString aName = GetEntryText(pEntry);
|
|
|
|
if (rListName != aName)
|
|
return false;
|
|
|
|
pEntry = Next(pEntry);
|
|
|
|
SdrObjListIter aIter(&rList,
|
|
!rList.HasObjectNavigationOrder() /* use navigation order, if available */,
|
|
SdrIterMode::Flat);
|
|
|
|
while (aIter.IsMore())
|
|
{
|
|
SdrObject* pObj = aIter.Next();
|
|
|
|
const OUString aObjectName(GetObjectName(pObj));
|
|
|
|
if (!aObjectName.isEmpty())
|
|
{
|
|
if (!pEntry)
|
|
return false;
|
|
|
|
aName = GetEntryText(pEntry);
|
|
|
|
if (aObjectName != aName)
|
|
return false;
|
|
|
|
if (pObj->IsGroupObject())
|
|
{
|
|
bool bRet = IsEqualToShapeList(pEntry, *pObj->GetSubList(), aObjectName);
|
|
if (!bRet)
|
|
return false;
|
|
}
|
|
else
|
|
pEntry = Next(pEntry);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Checks if the pages (PageKind::Standard) of a doc and the objects on the pages
|
|
* are identical to the TreeLB.
|
|
* If a doc is provided, this will be the used doc (important by more than
|
|
* one document).
|
|
*/
|
|
bool SdPageObjsTLB::IsEqualToDoc( const SdDrawDocument* pInDoc )
|
|
{
|
|
if( pInDoc )
|
|
mpDoc = pInDoc;
|
|
|
|
if( !mpDoc )
|
|
return false;
|
|
|
|
SvTreeListEntry* pEntry = First();
|
|
|
|
// compare all pages including the objects
|
|
sal_uInt16 nPage = 0;
|
|
const sal_uInt16 nMaxPages = mpDoc->GetPageCount();
|
|
|
|
while( nPage < nMaxPages )
|
|
{
|
|
const SdPage* pPage = static_cast<const SdPage*>( mpDoc->GetPage( nPage ) );
|
|
if( pPage->GetPageKind() == PageKind::Standard )
|
|
{
|
|
bool bRet = IsEqualToShapeList(pEntry, *pPage, pPage->GetName());
|
|
if (!bRet)
|
|
return false;
|
|
}
|
|
nPage++;
|
|
}
|
|
// If there are still entries in the listbox,
|
|
// then objects (with names) or pages were deleted
|
|
return !pEntry;
|
|
}
|
|
|
|
/**
|
|
* @return selected string
|
|
*/
|
|
OUString SdPageObjsTLB::GetSelectedEntry()
|
|
{
|
|
return GetEntryText( GetCurEntry() );
|
|
}
|
|
|
|
std::vector<OUString> SdPageObjsTLB::GetSelectEntryList( const sal_uInt16 nDepth ) const
|
|
{
|
|
std::vector<OUString> aEntries;
|
|
SvTreeListEntry* pEntry = FirstSelected();
|
|
|
|
while( pEntry )
|
|
{
|
|
sal_uInt16 nListDepth = GetModel()->GetDepth( pEntry );
|
|
|
|
if( nListDepth == nDepth )
|
|
aEntries.push_back(GetEntryText(pEntry));
|
|
|
|
pEntry = NextSelected( pEntry );
|
|
}
|
|
|
|
return aEntries;
|
|
}
|
|
|
|
/**
|
|
* Entries are inserted only by request (double click)
|
|
*/
|
|
void SdPageObjsTLB::RequestingChildren( SvTreeListEntry* pFileEntry )
|
|
{
|
|
if( !pFileEntry->HasChildren() )
|
|
{
|
|
if( GetBookmarkDoc() )
|
|
{
|
|
SdrObject* pObj = nullptr;
|
|
SvTreeListEntry* pPageEntry = nullptr;
|
|
|
|
Image aImgPage(StockImage::Yes, BMP_PAGE);
|
|
Image aImgPageObjs(StockImage::Yes, BMP_PAGEOBJS);
|
|
Image aImgObjects(StockImage::Yes, BMP_OBJECTS);
|
|
|
|
// document name already inserted
|
|
|
|
// only insert all "normal" ? slides with objects
|
|
sal_uInt16 nPage = 0;
|
|
const sal_uInt16 nMaxPages = mpBookmarkDoc->GetPageCount();
|
|
|
|
while( nPage < nMaxPages )
|
|
{
|
|
SdPage* pPage = static_cast<SdPage*>( mpBookmarkDoc->GetPage( nPage ) );
|
|
if( pPage->GetPageKind() == PageKind::Standard )
|
|
{
|
|
pPageEntry = InsertEntry( pPage->GetName(),
|
|
aImgPage,
|
|
aImgPage,
|
|
pFileEntry,
|
|
false,
|
|
TREELIST_APPEND,
|
|
reinterpret_cast< void* >( 1 ) );
|
|
|
|
SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups );
|
|
|
|
while( aIter.IsMore() )
|
|
{
|
|
pObj = aIter.Next();
|
|
OUString aStr( GetObjectName( pObj ) );
|
|
if( !aStr.isEmpty() )
|
|
{
|
|
if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == OBJ_OLE2 )
|
|
{
|
|
InsertEntry(aStr, maImgOle, maImgOle, pPageEntry);
|
|
}
|
|
else if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == OBJ_GRAF )
|
|
{
|
|
InsertEntry(aStr, maImgGraphic, maImgGraphic, pPageEntry);
|
|
}
|
|
else
|
|
{
|
|
InsertEntry(aStr, aImgObjects, aImgObjects, pPageEntry);
|
|
}
|
|
}
|
|
}
|
|
if( pPageEntry->HasChildren() )
|
|
{
|
|
SetExpandedEntryBmp( pPageEntry, aImgPageObjs );
|
|
SetCollapsedEntryBmp( pPageEntry, aImgPageObjs );
|
|
}
|
|
}
|
|
nPage++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
SvTreeListBox::RequestingChildren( pFileEntry );
|
|
}
|
|
|
|
/**
|
|
* Checks if it is a draw file and opens the BookmarkDoc depending of
|
|
* the provided Docs
|
|
*/
|
|
SdDrawDocument* SdPageObjsTLB::GetBookmarkDoc(SfxMedium* pMed)
|
|
{
|
|
if (
|
|
!mpBookmarkDoc ||
|
|
(pMed && (!mpOwnMedium || mpOwnMedium->GetName() != pMed->GetName()))
|
|
)
|
|
{
|
|
// create a new BookmarkDoc if now one exists or if a new Medium is provided
|
|
if (mpOwnMedium != pMed)
|
|
{
|
|
CloseBookmarkDoc();
|
|
}
|
|
|
|
if (pMed)
|
|
{
|
|
// it looks that it is undefined if a Medium was set by Fill() already
|
|
DBG_ASSERT( !mpMedium, "SfxMedium confusion!" );
|
|
delete mpMedium;
|
|
mpMedium = nullptr;
|
|
|
|
// take over this Medium (currently used only be Navigator)
|
|
mpOwnMedium = pMed;
|
|
}
|
|
|
|
DBG_ASSERT( mpMedium || pMed, "No SfxMedium provided!" );
|
|
|
|
if( pMed )
|
|
{
|
|
// in this mode the document is also owned and controlled by this instance
|
|
mxBookmarkDocShRef = new ::sd::DrawDocShell(SfxObjectCreateMode::STANDARD, true, DocumentType::Impress);
|
|
if (mxBookmarkDocShRef->DoLoad(pMed))
|
|
mpBookmarkDoc = mxBookmarkDocShRef->GetDoc();
|
|
else
|
|
mpBookmarkDoc = nullptr;
|
|
}
|
|
else if ( mpMedium )
|
|
// in this mode the document is owned and controlled by the SdDrawDocument
|
|
// it can be released by calling the corresponding CloseBookmarkDoc method
|
|
// successful creation of a document makes this the owner of the medium
|
|
mpBookmarkDoc = const_cast<SdDrawDocument*>(mpDoc)->OpenBookmarkDoc(mpMedium);
|
|
|
|
if ( !mpBookmarkDoc )
|
|
{
|
|
std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
|
|
VclMessageType::Warning, VclButtonsType::Ok, SdResId(STR_READ_DATA_ERROR)));
|
|
xErrorBox->run();
|
|
mpMedium = nullptr; //On failure the SfxMedium is invalid
|
|
}
|
|
}
|
|
|
|
return mpBookmarkDoc;
|
|
}
|
|
|
|
/**
|
|
* Close and delete bookmark document
|
|
*/
|
|
void SdPageObjsTLB::CloseBookmarkDoc()
|
|
{
|
|
if (mxBookmarkDocShRef.is())
|
|
{
|
|
mxBookmarkDocShRef->DoClose();
|
|
mxBookmarkDocShRef.clear();
|
|
|
|
// Medium is owned by document, so it's destroyed already
|
|
mpOwnMedium = nullptr;
|
|
}
|
|
else if ( mpBookmarkDoc )
|
|
{
|
|
DBG_ASSERT( !mpOwnMedium, "SfxMedium confusion!" );
|
|
if ( mpDoc )
|
|
{
|
|
// The document owns the Medium, so the Medium will be invalid after closing the document
|
|
const_cast<SdDrawDocument*>(mpDoc)->CloseBookmarkDoc();
|
|
mpMedium = nullptr;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// perhaps mpOwnMedium provided, but no successful creation of BookmarkDoc
|
|
delete mpOwnMedium;
|
|
mpOwnMedium = nullptr;
|
|
}
|
|
|
|
mpBookmarkDoc = nullptr;
|
|
}
|
|
|
|
void SdPageObjsTLB::SelectHdl()
|
|
{
|
|
SvTreeListEntry* pEntry = FirstSelected();
|
|
|
|
mbLinkableSelected = true;
|
|
|
|
while( pEntry && mbLinkableSelected )
|
|
{
|
|
if( nullptr == pEntry->GetUserData() )
|
|
mbLinkableSelected = false;
|
|
|
|
pEntry = NextSelected( pEntry );
|
|
}
|
|
|
|
SvTreeListBox::SelectHdl();
|
|
|
|
if (mbSelectionHandlerNavigates)
|
|
DoubleClickHdl();
|
|
}
|
|
|
|
/**
|
|
* Overloads RETURN with the functionality of DoubleClick
|
|
*/
|
|
void SdPageObjsTLB::KeyInput( const KeyEvent& rKEvt )
|
|
{
|
|
const vcl::KeyCode& aKeyCode = rKEvt.GetKeyCode();
|
|
if ( m_pAccel->execute( aKeyCode ) )
|
|
// the accelerator consumed the event
|
|
return;
|
|
if( rKEvt.GetKeyCode().GetCode() == KEY_RETURN )
|
|
{
|
|
// commented code from svtools/source/contnr/svimpbox.cxx
|
|
SvTreeListEntry* pCursor = GetCurEntry();
|
|
if (!pCursor)
|
|
return;
|
|
if( pCursor->HasChildren() || pCursor->HasChildrenOnDemand() )
|
|
{
|
|
if( IsExpanded( pCursor ) )
|
|
Collapse( pCursor );
|
|
else
|
|
Expand( pCursor );
|
|
}
|
|
|
|
DoubleClickHdl();
|
|
}
|
|
else if (rKEvt.GetKeyCode().GetCode() == KEY_SPACE)
|
|
{
|
|
if (mpNavigator)
|
|
{
|
|
SvTreeListEntry* pNewEntry = GetCurEntry();
|
|
if (!pNewEntry)
|
|
return;
|
|
SvTreeListEntry* pParentEntry = GetParent(pNewEntry);
|
|
if (!pParentEntry)
|
|
return;
|
|
Invalidate();
|
|
}
|
|
}
|
|
else
|
|
SvTreeListBox::KeyInput( rKEvt );
|
|
}
|
|
|
|
void SdPageObjsTLB::MouseButtonDown(const MouseEvent& rMEvt)
|
|
{
|
|
mbSelectionHandlerNavigates = rMEvt.GetClicks() == 1;
|
|
comphelper::ScopeGuard aNavigationGuard([this]() { this->mbSelectionHandlerNavigates = false; });
|
|
mbNavigationGrabsFocus = rMEvt.GetClicks() != 1;
|
|
comphelper::ScopeGuard aGrabGuard([this]() { this->mbNavigationGrabsFocus = true; });
|
|
|
|
SvTreeListBox::MouseButtonDown(rMEvt);
|
|
}
|
|
|
|
/**
|
|
* StartDrag-Request
|
|
*/
|
|
void SdPageObjsTLB::StartDrag( sal_Int8, const Point& rPosPixel)
|
|
{
|
|
SvTreeListEntry* pEntry = GetEntry(rPosPixel);
|
|
|
|
if (pEntry && mpNavigator && mpNavigator->GetNavigatorDragType() != NAVIGATOR_DRAGTYPE_NONE)
|
|
{
|
|
// Mark only the children of the page under the mouse as drop
|
|
// targets. This prevents moving shapes from one page to another.
|
|
|
|
// Select all entries and disable them as drop targets.
|
|
SetSelectionMode(SelectionMode::Multiple);
|
|
SetCursor(static_cast<SvTreeListEntry*>(nullptr));
|
|
SelectAll(true, false);
|
|
EnableSelectionAsDropTarget(false);
|
|
|
|
// Enable only the entries as drop targets that are children of the
|
|
// page under the mouse.
|
|
SvTreeListEntry* pParent = GetRootLevelParent(pEntry);
|
|
if (pParent != nullptr)
|
|
{
|
|
SelectAll(false, false);
|
|
Select(pParent);
|
|
// for (SvTreeListEntry*pChild=FirstChild(pParent); pChild!=NULL; pChild=NextSibling(pChild))
|
|
// Select(pChild, sal_True);
|
|
EnableSelectionAsDropTarget();//sal_False);
|
|
}
|
|
|
|
// Set selection back to the entry under the mouse.
|
|
SelectAll(false, false);
|
|
SetSelectionMode(SelectionMode::Single);
|
|
Select(pEntry);
|
|
|
|
// We can delete the Navigator from ExecuteDrag (when switching to
|
|
// another document type), but that would kill the StarView MouseMove
|
|
// Handler which is calling Command().
|
|
// For this reason, Drag&Drop is asynchronous.
|
|
Application::PostUserEvent( LINK( this, SdPageObjsTLB, ExecDragHdl ), nullptr, true );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Begin drag
|
|
*/
|
|
void SdPageObjsTLB::DoDrag()
|
|
{
|
|
if (mpNavigator)
|
|
{
|
|
::sd::DrawDocShell* pDocShell = mpDoc->GetDocSh();
|
|
OUString aURL = INetURLObject( pDocShell->GetMedium()->GetPhysicalName(), INetProtocol::File ).GetMainURL( INetURLObject::DecodeMechanism::NONE );
|
|
NavigatorDragType eDragType = mpNavigator->GetNavigatorDragType();
|
|
|
|
aURL += "#" + GetSelectedEntry();
|
|
|
|
INetBookmark aBookmark( aURL, GetSelectedEntry() );
|
|
sal_Int8 nDNDActions = DND_ACTION_COPYMOVE;
|
|
|
|
if( eDragType == NAVIGATOR_DRAGTYPE_LINK )
|
|
nDNDActions = DND_ACTION_LINK; // Either COPY *or* LINK, never both!
|
|
else if (mpDoc->GetSdPageCount(PageKind::Standard) == 1)
|
|
{
|
|
// Can not move away the last slide in a document.
|
|
nDNDActions = DND_ACTION_COPY;
|
|
}
|
|
|
|
SvTreeListBox::ReleaseMouse();
|
|
|
|
bIsInDrag = true;
|
|
|
|
// Get the view.
|
|
::sd::ViewShell* pViewShell = GetViewShellForDocShell(*pDocShell);
|
|
if (pViewShell == nullptr)
|
|
{
|
|
OSL_ASSERT(pViewShell!=nullptr);
|
|
return;
|
|
}
|
|
sd::View* pView = pViewShell->GetView();
|
|
if (pView == nullptr)
|
|
{
|
|
OSL_ASSERT(pView!=nullptr);
|
|
return;
|
|
}
|
|
|
|
// object is destroyed by internal reference mechanism
|
|
SdTransferable* pTransferable =
|
|
new SdPageObjsTLB::SdPageObjsTransferable(
|
|
*this, aBookmark, *pDocShell, eDragType);
|
|
|
|
SdrObject* pObject = nullptr;
|
|
void* pUserData = GetCurEntry()->GetUserData();
|
|
if (pUserData != nullptr && pUserData != reinterpret_cast<void*>(1))
|
|
pObject = static_cast<SdrObject*>(pUserData);
|
|
if (pObject != nullptr)
|
|
{
|
|
// For shapes without a user supplied name (the automatically
|
|
// created name does not count), a different drag and drop technique
|
|
// is used.
|
|
if (GetObjectName(pObject, false).isEmpty())
|
|
{
|
|
AddShapeToTransferable(*pTransferable, *pObject);
|
|
pTransferable->SetView(pView);
|
|
SD_MOD()->pTransferDrag = pTransferable;
|
|
}
|
|
|
|
// Unnamed shapes have to be selected to be recognized by the
|
|
// current drop implementation. In order to have a consistent
|
|
// behaviour for all shapes, every shape that is to be dragged is
|
|
// selected first.
|
|
SdrPageView* pPageView = pView->GetSdrPageView();
|
|
pView->UnmarkAllObj(pPageView);
|
|
pView->MarkObj(pObject, pPageView);
|
|
}
|
|
else
|
|
{
|
|
pTransferable->SetView(pView);
|
|
SD_MOD()->pTransferDrag = pTransferable;
|
|
}
|
|
|
|
pTransferable->StartDrag( this, nDNDActions );
|
|
}
|
|
}
|
|
|
|
void SdPageObjsTLB::OnDragFinished()
|
|
{
|
|
if (mpNavigator)
|
|
{
|
|
MouseEvent aMEvt(mpNavigator->GetPointerPosPixel());
|
|
SvTreeListBox::MouseButtonUp(aMEvt);
|
|
}
|
|
|
|
bIsInDrag = false;
|
|
}
|
|
|
|
/**
|
|
* AcceptDrop-Event
|
|
*/
|
|
sal_Int8 SdPageObjsTLB::AcceptDrop (const AcceptDropEvent& rEvent)
|
|
{
|
|
sal_Int8 nResult (DND_ACTION_NONE);
|
|
|
|
if ( !bIsInDrag && IsDropFormatSupported( SotClipboardFormatId::SIMPLE_FILE ) )
|
|
{
|
|
nResult = rEvent.mnAction;
|
|
}
|
|
else
|
|
{
|
|
SvTreeListEntry* pEntry = GetDropTarget(rEvent.maPosPixel);
|
|
if (rEvent.mbLeaving || !CheckDragAndDropMode( this, rEvent.mnAction ))
|
|
{
|
|
ImplShowTargetEmphasis( pTargetEntry, false );
|
|
}
|
|
else if( GetDragDropMode() == DragDropMode::NONE )
|
|
{
|
|
SAL_WARN( "sc.ui", "SdPageObjsTLB::AcceptDrop(): no target" );
|
|
}
|
|
else if (IsDropAllowed(pEntry))
|
|
{
|
|
nResult = DND_ACTION_MOVE;
|
|
|
|
// Draw emphasis.
|
|
if (pEntry != pTargetEntry || !(nImpFlags & SvTreeListBoxFlags::TARGEMPH_VIS))
|
|
{
|
|
ImplShowTargetEmphasis( pTargetEntry, false );
|
|
pTargetEntry = pEntry;
|
|
ImplShowTargetEmphasis( pTargetEntry, true );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Hide emphasis when there is no valid drop action.
|
|
if (nResult == DND_ACTION_NONE)
|
|
ImplShowTargetEmphasis(pTargetEntry, false);
|
|
|
|
return nResult;
|
|
}
|
|
|
|
/**
|
|
* ExecuteDrop-Event
|
|
*/
|
|
sal_Int8 SdPageObjsTLB::ExecuteDrop( const ExecuteDropEvent& rEvt )
|
|
{
|
|
sal_Int8 nRet = DND_ACTION_NONE;
|
|
|
|
try
|
|
{
|
|
if( !bIsInDrag )
|
|
{
|
|
if (mpNavigator)
|
|
{
|
|
TransferableDataHelper aDataHelper( rEvt.maDropEvent.Transferable );
|
|
OUString aFile;
|
|
|
|
if( aDataHelper.GetString( SotClipboardFormatId::SIMPLE_FILE, aFile ) &&
|
|
mpNavigator->InsertFile( aFile ) )
|
|
{
|
|
nRet = rEvt.mnAction;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (css::uno::Exception&)
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("sd");
|
|
}
|
|
|
|
if (nRet == DND_ACTION_NONE)
|
|
SvTreeListBox::ExecuteDrop(rEvt, this);
|
|
|
|
return nRet;
|
|
}
|
|
|
|
/**
|
|
* Handler for Dragging
|
|
*/
|
|
IMPL_LINK_NOARG(SdPageObjsTLB, ExecDragHdl, void*, void)
|
|
{
|
|
// as link, then it is allowed to asynchronous, without ImpMouseMoveMsg on
|
|
// the stack, delete the Navigator
|
|
DoDrag();
|
|
}
|
|
|
|
bool SdPageObjsTLB::PageBelongsToCurrentShow (const SdPage* pPage) const
|
|
{
|
|
// Return <TRUE/> as default when there is no custom show or when none
|
|
// is used. The page does then belong to the standard show.
|
|
bool bBelongsToShow = true;
|
|
|
|
if (mpDoc->getPresentationSettings().mbCustomShow)
|
|
{
|
|
// Get the current custom show.
|
|
SdCustomShow* pCustomShow = nullptr;
|
|
SdCustomShowList* pShowList = const_cast<SdDrawDocument*>(mpDoc)->GetCustomShowList();
|
|
if (pShowList != nullptr)
|
|
{
|
|
sal_uLong nCurrentShowIndex = pShowList->GetCurPos();
|
|
pCustomShow = (*pShowList)[nCurrentShowIndex].get();
|
|
}
|
|
|
|
// Check whether the given page is part of that custom show.
|
|
if (pCustomShow != nullptr)
|
|
{
|
|
bBelongsToShow = false;
|
|
size_t nPageCount = pCustomShow->PagesVector().size();
|
|
for (size_t i=0; i<nPageCount && !bBelongsToShow; i++)
|
|
if (pPage == pCustomShow->PagesVector()[i])
|
|
bBelongsToShow = true;
|
|
}
|
|
}
|
|
|
|
return bBelongsToShow;
|
|
}
|
|
|
|
TriState SdPageObjsTLB::NotifyMoving(
|
|
SvTreeListEntry* pTarget,
|
|
SvTreeListEntry* pEntry,
|
|
SvTreeListEntry*& rpNewParent,
|
|
sal_uLong& rNewChildPos)
|
|
{
|
|
SvTreeListEntry* pDestination = pTarget;
|
|
while (GetParent(pDestination) != nullptr && GetParent(GetParent(pDestination)) != nullptr)
|
|
pDestination = GetParent(pDestination);
|
|
|
|
SdrObject* pTargetObject = static_cast<SdrObject*>(pDestination->GetUserData());
|
|
SdrObject* pSourceObject = static_cast<SdrObject*>(pEntry->GetUserData());
|
|
if (pSourceObject == reinterpret_cast<SdrObject*>(1))
|
|
pSourceObject = nullptr;
|
|
|
|
if (pTargetObject != nullptr && pSourceObject != nullptr)
|
|
{
|
|
SdrPage* pObjectList = pSourceObject->getSdrPageFromSdrObject();
|
|
if (pObjectList != nullptr)
|
|
{
|
|
sal_uInt32 nNewPosition;
|
|
if (pTargetObject == reinterpret_cast<SdrObject*>(1))
|
|
nNewPosition = 0;
|
|
else
|
|
nNewPosition = pTargetObject->GetNavigationPosition() + 1;
|
|
pObjectList->SetObjectNavigationPosition(*pSourceObject, nNewPosition);
|
|
}
|
|
|
|
// Update the tree list.
|
|
if (GetParent(pDestination) == nullptr)
|
|
{
|
|
rpNewParent = pDestination;
|
|
rNewChildPos = 0;
|
|
}
|
|
else
|
|
{
|
|
rpNewParent = GetParent(pDestination);
|
|
rNewChildPos = SvTreeList::GetRelPos(pDestination) + 1;
|
|
rNewChildPos += nCurEntrySelPos;
|
|
nCurEntrySelPos++;
|
|
}
|
|
return TRISTATE_TRUE;
|
|
}
|
|
else
|
|
return TRISTATE_FALSE;
|
|
}
|
|
|
|
SvTreeListEntry* SdPageObjsTLB::GetDropTarget (const Point& rLocation)
|
|
{
|
|
SvTreeListEntry* pEntry = SvTreeListBox::GetDropTarget(rLocation);
|
|
if (pEntry == nullptr)
|
|
return nullptr;
|
|
|
|
if (GetParent(pEntry) == nullptr)
|
|
{
|
|
// Use page entry as insertion position.
|
|
}
|
|
else
|
|
{
|
|
// Go to second hierarchy level, i.e. top level shapes,
|
|
// i.e. children of pages.
|
|
while (GetParent(pEntry) != nullptr && GetParent(GetParent(pEntry)) != nullptr)
|
|
pEntry = GetParent(pEntry);
|
|
|
|
// Advance to next sibling.
|
|
SvTreeListEntry* pNext;
|
|
sal_uInt16 nDepth (0);
|
|
do
|
|
{
|
|
pNext = NextVisible(pEntry, &nDepth);
|
|
if (pNext != nullptr && nDepth > 0 && nDepth!=0xffff)
|
|
pEntry = pNext;
|
|
else
|
|
break;
|
|
}
|
|
while (pEntry != nullptr);
|
|
}
|
|
|
|
return pEntry;
|
|
}
|
|
|
|
bool SdPageObjsTLB::IsDropAllowed (SvTreeListEntry const * pEntry)
|
|
{
|
|
if (pEntry == nullptr)
|
|
return false;
|
|
|
|
if ( ! IsDropFormatSupported(SdPageObjsTransferable::GetListBoxDropFormatId()))
|
|
return false;
|
|
|
|
if (pEntry->GetFlags() & SvTLEntryFlags::DISABLE_DROP)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void SdPageObjsTLB::AddShapeToTransferable (
|
|
SdTransferable& rTransferable,
|
|
SdrObject& rObject) const
|
|
{
|
|
std::unique_ptr<TransferableObjectDescriptor> pObjectDescriptor(new TransferableObjectDescriptor);
|
|
bool bIsDescriptorFillingPending (true);
|
|
|
|
const SdrOle2Obj* pOleObject = dynamic_cast<const SdrOle2Obj*>(&rObject);
|
|
if (pOleObject != nullptr && pOleObject->GetObjRef().is())
|
|
{
|
|
// If object has no persistence it must be copied as part of the document
|
|
try
|
|
{
|
|
uno::Reference< embed::XEmbedPersist > xPersObj (pOleObject->GetObjRef(), uno::UNO_QUERY );
|
|
if (xPersObj.is() && xPersObj->hasEntry())
|
|
{
|
|
SvEmbedTransferHelper::FillTransferableObjectDescriptor(
|
|
*pObjectDescriptor,
|
|
pOleObject->GetObjRef(),
|
|
pOleObject->GetGraphic(),
|
|
pOleObject->GetAspect());
|
|
bIsDescriptorFillingPending = false;
|
|
}
|
|
}
|
|
catch( uno::Exception& )
|
|
{
|
|
}
|
|
}
|
|
|
|
::sd::DrawDocShell* pDocShell = mpDoc->GetDocSh();
|
|
if (bIsDescriptorFillingPending && pDocShell!=nullptr)
|
|
{
|
|
pDocShell->FillTransferableObjectDescriptor(*pObjectDescriptor);
|
|
}
|
|
|
|
Point aDragPos (rObject.GetCurrentBoundRect().Center());
|
|
//Point aDragPos (0,0);
|
|
pObjectDescriptor->maDragStartPos = aDragPos;
|
|
// aObjectDescriptor.maSize = GetAllMarkedRect().GetSize();
|
|
if (pDocShell != nullptr)
|
|
pObjectDescriptor->maDisplayName = pDocShell->GetMedium()->GetURLObject().GetURLNoPass();
|
|
else
|
|
pObjectDescriptor->maDisplayName.clear();
|
|
|
|
rTransferable.SetStartPos(aDragPos);
|
|
rTransferable.SetObjectDescriptor( std::move(pObjectDescriptor) );
|
|
}
|
|
|
|
::sd::ViewShell* SdPageObjsTLB::GetViewShellForDocShell (::sd::DrawDocShell& rDocShell)
|
|
{
|
|
{
|
|
::sd::ViewShell* pViewShell = rDocShell.GetViewShell();
|
|
if (pViewShell != nullptr)
|
|
return pViewShell;
|
|
}
|
|
|
|
try
|
|
{
|
|
// Get a component enumeration from the desktop and search it for documents.
|
|
uno::Reference<uno::XComponentContext> xContext( ::comphelper::getProcessComponentContext());
|
|
|
|
uno::Reference<frame::XDesktop2> xDesktop = frame::Desktop::create(xContext);
|
|
|
|
uno::Reference<frame::XFramesSupplier> xFrameSupplier (xDesktop, uno::UNO_QUERY);
|
|
if ( ! xFrameSupplier.is())
|
|
return nullptr;
|
|
|
|
uno::Reference<container::XIndexAccess> xFrameAccess (xFrameSupplier->getFrames(), uno::UNO_QUERY);
|
|
if ( ! xFrameAccess.is())
|
|
return nullptr;
|
|
|
|
for (sal_Int32 nIndex=0,nCount=xFrameAccess->getCount(); nIndex<nCount; ++nIndex)
|
|
{
|
|
uno::Reference<frame::XFrame> xFrame;
|
|
if ( ! (xFrameAccess->getByIndex(nIndex) >>= xFrame))
|
|
continue;
|
|
|
|
::sd::DrawController* pController = dynamic_cast<sd::DrawController*>(xFrame->getController().get());
|
|
if (pController == nullptr)
|
|
continue;
|
|
::sd::ViewShellBase* pBase = pController->GetViewShellBase();
|
|
if (pBase == nullptr)
|
|
continue;
|
|
if (pBase->GetDocShell() != &rDocShell)
|
|
continue;
|
|
|
|
const std::shared_ptr<sd::ViewShell> pViewShell (pBase->GetMainViewShell());
|
|
if (pViewShell)
|
|
return pViewShell.get();
|
|
}
|
|
}
|
|
catch (uno::Exception &)
|
|
{
|
|
// When there is an exception then simply use the default value of
|
|
// bIsEnabled and disable the controls.
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
//===== IconProvider ==========================================================
|
|
|
|
SdPageObjsTLB::IconProvider::IconProvider()
|
|
: maImgPage(StockImage::Yes, BMP_PAGE),
|
|
maImgPageExcl(StockImage::Yes, BMP_PAGE_EXCLUDED),
|
|
maImgPageObjsExcl(StockImage::Yes, BMP_PAGEOBJS_EXCLUDED),
|
|
maImgPageObjs(StockImage::Yes, BMP_PAGEOBJS),
|
|
maImgObjects(StockImage::Yes, BMP_OBJECTS),
|
|
maImgGroup(StockImage::Yes, BMP_GROUP)
|
|
{
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|