/* -*- 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 <svl/stritem.hxx>
#include <sfx2/fcontnr.hxx>
#include <sfx2/linkmgr.hxx>
#include <sfx2/dispatch.hxx>
#include <svl/urihelper.hxx>
#include <sfx2/docfile.hxx>
#include <vcl/help.hxx>
#include <sot/filelist.hxx>
#include <svl/eitem.hxx>
#include <svl/urlbmk.hxx>
#include <vcl/graphicfilter.hxx>
#include <vcl/settings.hxx>
#include <svtools/treelistentry.hxx>
#include <sfx2/docinsert.hxx>
#include <sfx2/filedlghelper.hxx>
#include <sfx2/app.hxx>
#include <swmodule.hxx>
#include <wrtsh.hxx>
#include <view.hxx>
#include <docsh.hxx>
#include <content.hxx>
#include <edglbldc.hxx>
#include <section.hxx>
#include <tox.hxx>
#include <cnttab.hxx>
#include <navipi.hxx>
#include <navicont.hxx>
#include <edtwin.hxx>
#include <uitool.hxx>
#include <o3tl/make_unique.hxx>
#include <cmdid.h>
#include <helpids.h>
#include <strings.hrc>
#include <globals.hrc>
#include <bitmaps.hlst>
#include <swabstdlg.hxx>
#include <memory>
using namespace ::com::sun::star::uno;
// Context menu for GlobalTree
#define CTX_INSERT_ANY_INDEX 10
#define CTX_INSERT_FILE 11
#define CTX_INSERT_NEW_FILE 12
#define CTX_INSERT_TEXT 13
#define CTX_UPDATE_SEL 20
#define CTX_UPDATE_INDEX 21
#define CTX_UPDATE_LINK 22
#define CTX_UPDATE_ALL 23
#define CTX_UPDATE 1
#define CTX_INSERT 2
#define CTX_EDIT 3
#define CTX_DELETE 4
#define CTX_EDIT_LINK 5
#define GLOBAL_UPDATE_TIMEOUT 2000
// TabPos: push to left
#define GLBL_TABPOS_SUB 5
const SfxObjectShell* SwGlobalTree::pShowShell = nullptr;
static const char* aHelpForMenu[] =
{
nullptr,
HID_GLBLTREE_UPDATE, //CTX_UPDATE
HID_GLBLTREE_INSERT, //CTX_INSERT
HID_GLBLTREE_EDIT, //CTX_EDIT
HID_GLBLTREE_DEL, //CTX_DELETE
HID_GLBLTREE_EDIT_LINK, //CTX_EDIT_LINK
nullptr,
nullptr,
nullptr,
nullptr,
HID_GLBLTREE_INS_IDX, //CTX_INSERT_ANY_INDEX
HID_GLBLTREE_INS_FILE, //CTX_INSERT_FILE
HID_GLBLTREE_INS_NEW_FILE, //CTX_INSERT_NEW_FILE
HID_GLBLTREE_INS_TEXT, //CTX_INSERT_TEXT
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
HID_GLBLTREE_UPD_SEL, //CTX_UPDATE_SEL
HID_GLBLTREE_UPD_IDX, //CTX_UPDATE_INDEX
HID_GLBLTREE_UPD_LINK, //CTX_UPDATE_LINK
HID_GLBLTREEUPD_ALL //CTX_UPDATE_ALL
};
class SwGlobalFrameListener_Impl : public SfxListener
{
bool bValid;
public:
explicit SwGlobalFrameListener_Impl(SfxViewFrame& rFrame)
: bValid(true)
{
StartListening(rFrame);
}
virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
bool IsValid() const {return bValid;}
};
void SwGlobalFrameListener_Impl::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
{
if( rHint.GetId() == SfxHintId::Dying)
bValid = false;
}
enum GLOBAL_CONTEXT_IDX
{
IDX_STR_UPDATE = 0,
IDX_STR_EDIT_CONTENT = 1,
IDX_STR_EDIT_INSERT = 2,
IDX_STR_INDEX = 3,
IDX_STR_FILE = 4,
IDX_STR_NEW_FILE = 5,
IDX_STR_INSERT_TEXT = 6,
IDX_STR_DELETE = 7,
IDX_STR_UPDATE_SEL = 8,
IDX_STR_UPDATE_INDEX = 9,
IDX_STR_UPDATE_LINK = 10,
IDX_STR_UPDATE_ALL = 11,
IDX_STR_BROKEN_LINK = 12,
IDX_STR_EDIT_LINK = 13
};
static const char* GLOBAL_CONTEXT_ARY[] =
{
STR_UPDATE,
STR_EDIT_CONTENT,
STR_EDIT_INSERT,
STR_INDEX,
STR_FILE,
STR_NEW_FILE,
STR_INSERT_TEXT,
STR_DELETE,
STR_UPDATE_SEL,
STR_UPDATE_INDEX,
STR_UPDATE_LINK,
STR_UPDATE_ALL,
STR_BROKEN_LINK,
STR_EDIT_LINK
};
SwGlobalTree::SwGlobalTree(vcl::Window* pParent, SwNavigationPI* pDialog)
: SvTreeListBox(pParent)
, m_xDialog(pDialog)
, m_pActiveShell(nullptr)
, m_pEmphasisEntry(nullptr)
, m_pDDSource(nullptr)
, m_pDocContent(nullptr)
, m_bIsInternalDrag(false)
, m_bLastEntryEmphasis(false)
{
SetDragDropMode(DragDropMode::APP_COPY |
DragDropMode::CTRL_MOVE |
DragDropMode::ENABLE_TOP );
m_aUpdateTimer.SetTimeout(GLOBAL_UPDATE_TIMEOUT);
m_aUpdateTimer.SetInvokeHandler(LINK(this, SwGlobalTree, Timeout));
m_aUpdateTimer.Start();
for (sal_uInt16 i = 0; i < GLOBAL_CONTEXT_COUNT; i++)
{
m_aContextStrings[i] = SwResId(GLOBAL_CONTEXT_ARY[i]);
}
SetHelpId(HID_NAVIGATOR_GLOB_TREELIST);
SelectHdl();
SetDoubleClickHdl(LINK(this, SwGlobalTree, DoubleClickHdl));
EnableContextMenuHandling();
}
SwGlobalTree::~SwGlobalTree()
{
disposeOnce();
}
void SwGlobalTree::dispose()
{
m_pSwGlblDocContents.reset();
m_pDocInserter.reset();
m_aUpdateTimer.Stop();
m_xDialog.clear();
SvTreeListBox::dispose();
}
Size SwGlobalTree::GetOptimalSize() const
{
return LogicToPixel(Size(110, 112), MapMode(MapUnit::MapAppFont));
}
sal_Int8 SwGlobalTree::ExecuteDrop( const ExecuteDropEvent& rEvt )
{
sal_Int8 nRet = DND_ACTION_NONE;
SvTreeListEntry* pLast = LastVisible();
if(m_pEmphasisEntry)
{
ImplShowTargetEmphasis( Prev(m_pEmphasisEntry), false );
m_pEmphasisEntry = nullptr;
}
else if(m_bLastEntryEmphasis && pLast)
{
ImplShowTargetEmphasis( pLast, false);
}
SvTreeListEntry* pDropEntry = m_bLastEntryEmphasis ? nullptr : GetEntry(rEvt.maPosPixel);
if( m_bIsInternalDrag )
{
SvTreeListEntry* pDummy = nullptr;
sal_uLong nInsertionPos = TREELIST_APPEND;
NotifyMoving( pDropEntry, m_pDDSource, pDummy, nInsertionPos );
}
else
{
TransferableDataHelper aData( rEvt.maDropEvent.Transferable );
OUString sFileName;
const SwGlblDocContent* pCnt = pDropEntry ?
static_cast<const SwGlblDocContent*>(pDropEntry->GetUserData()) :
nullptr;
if( aData.HasFormat( SotClipboardFormatId::FILE_LIST ))
{
nRet = rEvt.mnAction;
std::unique_ptr<SwGlblDocContents> pTempContents(new SwGlblDocContents);
int nAbsContPos = pDropEntry ?
static_cast<int>(GetModel()->GetAbsPos(pDropEntry)):
- 1;
sal_uLong nEntryCount = GetEntryCount();
// Get data
FileList aFileList;
aData.GetFileList( SotClipboardFormatId::FILE_LIST, aFileList );
for ( size_t n = aFileList.Count(); n--; )
{
sFileName = aFileList.GetFile(n);
InsertRegion(pCnt, &sFileName);
// The list of contents must be newly fetched after inserting,
// to not work on an old content.
if(n)
{
m_pActiveShell->GetGlobalDocContent(*pTempContents);
// If the file was successfully inserted,
// then the next content must also be fetched.
if(nEntryCount < pTempContents->size())
{
nEntryCount++;
nAbsContPos++;
pCnt = (*pTempContents)[ nAbsContPos ];
}
}
}
}
else if( !(sFileName =
SwNavigationPI::CreateDropFileName( aData )).isEmpty())
{
INetURLObject aTemp(sFileName);
GraphicDescriptor aDesc(aTemp);
if( !aDesc.Detect() ) // accept no graphics
{
nRet = rEvt.mnAction;
InsertRegion(pCnt, &sFileName);
}
}
}
m_bLastEntryEmphasis = false;
return nRet;
}
sal_Int8 SwGlobalTree::AcceptDrop( const AcceptDropEvent& rEvt )
{
sal_Int8 nRet = rEvt.mnAction;
//initiate scrolling
GetDropTarget( rEvt.maPosPixel );
SvTreeListEntry* pLast = LastVisible();
if( rEvt.mbLeaving )
{
if( m_pEmphasisEntry )
{
ImplShowTargetEmphasis( Prev(m_pEmphasisEntry), false );
m_pEmphasisEntry = nullptr;
}
else if(m_bLastEntryEmphasis && pLast)
{
ImplShowTargetEmphasis( pLast, false);
}
m_bLastEntryEmphasis = false;
}
else
{
SvTreeListEntry* pDropEntry = GetEntry( rEvt.maPosPixel );
if(m_bIsInternalDrag)
{
if( m_pDDSource != pDropEntry )
nRet = rEvt.mnAction;
}
else if( IsDropFormatSupported( SotClipboardFormatId::SIMPLE_FILE ) ||
IsDropFormatSupported( SotClipboardFormatId::STRING ) ||
IsDropFormatSupported( SotClipboardFormatId::FILE_LIST ) ||
IsDropFormatSupported( SotClipboardFormatId::SOLK ) ||
IsDropFormatSupported( SotClipboardFormatId::NETSCAPE_BOOKMARK )||
IsDropFormatSupported( SotClipboardFormatId::FILECONTENT ) ||
IsDropFormatSupported( SotClipboardFormatId::FILEGRPDESCRIPTOR ) ||
IsDropFormatSupported( SotClipboardFormatId::UNIFORMRESOURCELOCATOR ) ||
IsDropFormatSupported( SotClipboardFormatId::FILENAME ))
nRet = DND_ACTION_LINK;
if(m_pEmphasisEntry && m_pEmphasisEntry != pDropEntry)
ImplShowTargetEmphasis( Prev(m_pEmphasisEntry), false );
else if(pLast && m_bLastEntryEmphasis && pDropEntry)
{
ImplShowTargetEmphasis( pLast, false);
m_bLastEntryEmphasis = false;
}
if(pDropEntry)
ImplShowTargetEmphasis( Prev(pDropEntry), DND_ACTION_NONE != nRet );
else if(pLast)
{
ImplShowTargetEmphasis( pLast, DND_ACTION_NONE != nRet );
m_bLastEntryEmphasis = true;
}
m_pEmphasisEntry = pDropEntry;
}
return nRet;
}
VclPtr<PopupMenu> SwGlobalTree::CreateContextMenu()
{
VclPtr<PopupMenu> pPop;
if(m_pActiveShell &&
!m_pActiveShell->GetView().GetDocShell()->IsReadOnly())
{
const MenuEnableFlags nEnableFlags = GetEnableFlags();
pPop = VclPtr<PopupMenu>::Create();
VclPtrInstance<PopupMenu> pSubPop1;
VclPtrInstance<PopupMenu> pSubPop2;
for (sal_uInt16 i = CTX_UPDATE_SEL; i <= CTX_UPDATE_ALL; i++)
{
pSubPop2->InsertItem( i, m_aContextStrings[IDX_STR_UPDATE_SEL + i - CTX_UPDATE_SEL] );
pSubPop2->SetHelpId(i, aHelpForMenu[i]);
}
pSubPop2->EnableItem(CTX_UPDATE_SEL, bool(nEnableFlags & MenuEnableFlags::UpdateSel));
pSubPop1->InsertItem(CTX_INSERT_ANY_INDEX, m_aContextStrings[IDX_STR_INDEX]);
pSubPop1->SetHelpId(CTX_INSERT_ANY_INDEX, aHelpForMenu[CTX_INSERT_ANY_INDEX]);
pSubPop1->InsertItem(CTX_INSERT_FILE, m_aContextStrings[IDX_STR_FILE]);
pSubPop1->SetHelpId(CTX_INSERT_FILE, aHelpForMenu[CTX_INSERT_FILE]);
pSubPop1->InsertItem(CTX_INSERT_NEW_FILE, m_aContextStrings[IDX_STR_NEW_FILE]);
pSubPop1->SetHelpId(CTX_INSERT_NEW_FILE, aHelpForMenu[CTX_INSERT_NEW_FILE]);
pSubPop1->InsertItem(CTX_INSERT_TEXT, m_aContextStrings[IDX_STR_INSERT_TEXT]);
pSubPop1->SetHelpId(CTX_INSERT_TEXT, aHelpForMenu[CTX_INSERT_TEXT]);
pPop->InsertItem(CTX_UPDATE, m_aContextStrings[IDX_STR_UPDATE]);
pPop->SetHelpId(CTX_UPDATE, aHelpForMenu[CTX_UPDATE]);
pPop->InsertItem(CTX_EDIT, m_aContextStrings[IDX_STR_EDIT_CONTENT]);
pPop->SetHelpId(CTX_EDIT, aHelpForMenu[CTX_EDIT]);
if(nEnableFlags&MenuEnableFlags::EditLink)
{
pPop->InsertItem(CTX_EDIT_LINK, m_aContextStrings[IDX_STR_EDIT_LINK]);
pPop->SetHelpId(CTX_EDIT_LINK, aHelpForMenu[CTX_EDIT_LINK]);
}
pPop->InsertItem(CTX_INSERT, m_aContextStrings[IDX_STR_EDIT_INSERT]);
pPop->SetHelpId(CTX_INSERT, aHelpForMenu[CTX_INSERT]);
pPop->InsertSeparator() ;
pPop->InsertItem(CTX_DELETE, m_aContextStrings[IDX_STR_DELETE]);
pPop->SetHelpId(CTX_DELETE, aHelpForMenu[CTX_DELETE]);
//disabling if applicable
pSubPop1->EnableItem(CTX_INSERT_ANY_INDEX, bool(nEnableFlags & MenuEnableFlags::InsertIdx ));
pSubPop1->EnableItem(CTX_INSERT_TEXT, bool(nEnableFlags & MenuEnableFlags::InsertText));
pSubPop1->EnableItem(CTX_INSERT_FILE, bool(nEnableFlags & MenuEnableFlags::InsertFile));
pSubPop1->EnableItem(CTX_INSERT_NEW_FILE, bool(nEnableFlags & MenuEnableFlags::InsertFile));
pPop->EnableItem(CTX_UPDATE, bool(nEnableFlags & MenuEnableFlags::Update));
pPop->EnableItem(CTX_INSERT, bool(nEnableFlags & MenuEnableFlags::InsertIdx));
pPop->EnableItem(CTX_EDIT, bool(nEnableFlags & MenuEnableFlags::Edit));
pPop->EnableItem(CTX_DELETE, bool(nEnableFlags & MenuEnableFlags::Delete));
pPop->SetPopupMenu( CTX_INSERT, pSubPop1 );
pPop->SetPopupMenu( CTX_UPDATE, pSubPop2 );
}
return pPop;
}
void SwGlobalTree::TbxMenuHdl(sal_uInt16 nTbxId, ToolBox* pBox)
{
const MenuEnableFlags nEnableFlags = GetEnableFlags();
const OUString sCommand(pBox->GetItemCommand(nTbxId));
if (sCommand == "insert")
{
ScopedVclPtrInstance<PopupMenu> pMenu;
for (sal_uInt16 i = CTX_INSERT_ANY_INDEX; i <= CTX_INSERT_TEXT; ++i)
{
pMenu->InsertItem( i, m_aContextStrings[IDX_STR_INDEX + i - CTX_INSERT_ANY_INDEX] );
pMenu->SetHelpId(i, aHelpForMenu[i] );
}
pMenu->EnableItem(CTX_INSERT_ANY_INDEX, bool(nEnableFlags & MenuEnableFlags::InsertIdx ));
pMenu->EnableItem(CTX_INSERT_TEXT, bool(nEnableFlags & MenuEnableFlags::InsertText));
pMenu->EnableItem(CTX_INSERT_FILE, bool(nEnableFlags & MenuEnableFlags::InsertFile));
pMenu->EnableItem(CTX_INSERT_NEW_FILE, bool(nEnableFlags & MenuEnableFlags::InsertFile));
pMenu->SetSelectHdl(LINK(this, SwGlobalTree, PopupHdl));
pMenu->Execute(pBox, pBox->GetItemRect(nTbxId));
pMenu.disposeAndClear();
pBox->EndSelection();
pBox->Invalidate();
}
else if (sCommand == "update")
{
ScopedVclPtrInstance<PopupMenu> pMenu;
for (sal_uInt16 i = CTX_UPDATE_SEL; i <= CTX_UPDATE_ALL; i++)
{
pMenu->InsertItem( i, m_aContextStrings[IDX_STR_UPDATE_SEL + i - CTX_UPDATE_SEL] );
pMenu->SetHelpId(i, aHelpForMenu[i] );
}
pMenu->EnableItem(CTX_UPDATE_SEL, bool(nEnableFlags & MenuEnableFlags::UpdateSel));
pMenu->SetSelectHdl(LINK(this, SwGlobalTree, PopupHdl));
pMenu->Execute(pBox, pBox->GetItemRect(nTbxId));
pMenu.disposeAndClear();
pBox->EndSelection();
pBox->Invalidate();
}
}
MenuEnableFlags SwGlobalTree::GetEnableFlags() const
{
SvTreeListEntry* pEntry = FirstSelected();
sal_uLong nSelCount = GetSelectionCount();
sal_uLong nEntryCount = GetEntryCount();
SvTreeListEntry* pPrevEntry = pEntry ? Prev(pEntry) : nullptr;
MenuEnableFlags nRet = MenuEnableFlags::NONE;
if(nSelCount == 1 || !nEntryCount)
nRet |= MenuEnableFlags::InsertIdx|MenuEnableFlags::InsertFile;
if(nSelCount == 1)
{
nRet |= MenuEnableFlags::Edit;
if (pEntry && static_cast<SwGlblDocContent*>(pEntry->GetUserData())->GetType() != GLBLDOC_UNKNOWN &&
(!pPrevEntry || static_cast<SwGlblDocContent*>(pPrevEntry->GetUserData())->GetType() != GLBLDOC_UNKNOWN))
nRet |= MenuEnableFlags::InsertText;
if (pEntry && GLBLDOC_SECTION == static_cast<SwGlblDocContent*>(pEntry->GetUserData())->GetType())
nRet |= MenuEnableFlags::EditLink;
}
else if(!nEntryCount)
{
nRet |= MenuEnableFlags::InsertText;
}
if(nEntryCount)
nRet |= MenuEnableFlags::Update|MenuEnableFlags::Delete;
if(nSelCount)
nRet |= MenuEnableFlags::UpdateSel;
return nRet;
}
void SwGlobalTree::RequestHelp( const HelpEvent& rHEvt )
{
bool bParent = true;
Update(true);
Display(true);
if( rHEvt.GetMode() & HelpEventMode::QUICK )
{
Point aPos( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ));
SvTreeListEntry* pEntry = GetEntry( aPos );
const SwGlblDocContent* pCont = pEntry ?
static_cast<const SwGlblDocContent*>(pEntry->GetUserData()) : nullptr;
if( pCont && GLBLDOC_SECTION == pCont->GetType())
{
bParent = false;
SvLBoxTab* pTab;
SvLBoxItem* pItem = GetItem( pEntry, aPos.X(), &pTab );
if (pItem && SvLBoxItemType::String == pItem->GetType())
{
const SwSection* pSect = pCont->GetSection();
OUString sEntry = pSect->GetLinkFileName().getToken(0, sfx2::cTokenSeparator);
if(!pSect->IsConnectFlag())
sEntry = m_aContextStrings[IDX_STR_BROKEN_LINK] + sEntry;
Point aEntryPos = GetEntryPosition( pEntry );
aEntryPos.setX( GetTabPos( pEntry, pTab ) );
Size aSize( pItem->GetSize( this, pEntry ) );
if((aEntryPos.X() + aSize.Width()) > GetSizePixel().Width())
aSize.setWidth( GetSizePixel().Width() - aEntryPos.X() );
aEntryPos = OutputToScreenPixel(aEntryPos);
tools::Rectangle aItemRect( aEntryPos, aSize );
if(Help::IsBalloonHelpEnabled())
{
aEntryPos.AdjustX(aSize.Width() );
Help::ShowBalloon( this, aEntryPos, aItemRect, sEntry );
}
else
Help::ShowQuickHelp( this, aItemRect, sEntry,
QuickHelpFlags::Left|QuickHelpFlags::VCenter );
}
}
}
if(bParent)
SvTreeListBox::RequestHelp(rHEvt);
}
void SwGlobalTree::SelectHdl()
{
sal_uLong nSelCount = GetSelectionCount();
SvTreeListEntry* pSel = FirstSelected();
sal_uLong nAbsPos = pSel ? GetModel()->GetAbsPos(pSel) : 0;
SwNavigationPI* pNavi = GetParentWindow();
bool bReadonly = !m_pActiveShell ||
m_pActiveShell->GetView().GetDocShell()->IsReadOnly();
pNavi->m_aGlobalToolBox->EnableItem(pNavi->m_aGlobalToolBox->GetItemId("edit"), nSelCount == 1 && !bReadonly);
pNavi->m_aGlobalToolBox->EnableItem(pNavi->m_aGlobalToolBox->GetItemId("insert"), nSelCount <= 1 && !bReadonly);
pNavi->m_aGlobalToolBox->EnableItem(pNavi->m_aGlobalToolBox->GetItemId("update"), GetEntryCount() > 0 && !bReadonly);
pNavi->m_aGlobalToolBox->EnableItem(pNavi->m_aGlobalToolBox->GetItemId("up"),
nSelCount == 1 && nAbsPos && !bReadonly);
pNavi->m_aGlobalToolBox->EnableItem(pNavi->m_aGlobalToolBox->GetItemId("down"),
nSelCount == 1 && nAbsPos < GetEntryCount() - 1 && !bReadonly);
}
void SwGlobalTree::DeselectHdl()
{
SelectHdl();
}
DragDropMode SwGlobalTree::NotifyStartDrag( TransferDataContainer& ,
SvTreeListEntry* pEntry )
{
m_bIsInternalDrag = true;
m_pDDSource = pEntry;
return DragDropMode::CTRL_MOVE;
}
sal_IntPtr SwGlobalTree::GetTabPos( SvTreeListEntry*, SvLBoxTab* pTab)
{
return pTab->GetPos() - GLBL_TABPOS_SUB;
}
TriState SwGlobalTree::NotifyMoving( SvTreeListEntry* pTarget,
SvTreeListEntry* pSource,
SvTreeListEntry*&,
sal_uLong&
)
{
SvTreeList* _pModel = GetModel();
sal_uLong nSource = _pModel->GetAbsPos(pSource);
sal_uLong nDest = pTarget ? _pModel->GetAbsPos(pTarget) : m_pSwGlblDocContents->size();
if( m_pActiveShell->MoveGlobalDocContent(
*m_pSwGlblDocContents, nSource, nSource + 1, nDest ) &&
Update( false ))
Display();
return TRISTATE_FALSE;
}
TriState SwGlobalTree::NotifyCopying( SvTreeListEntry* /*pTarget*/,
SvTreeListEntry* /*pEntry*/,
SvTreeListEntry*& /*rpNewParent*/,
sal_uLong& /*rNewChildPos*/
)
{
return TRISTATE_FALSE;
}
bool SwGlobalTree::NotifyAcceptDrop( SvTreeListEntry* pEntry)
{
return pEntry != nullptr;
}
void SwGlobalTree::StartDrag( sal_Int8 nAction, const Point& rPt )
{
if( 1 == GetSelectionCount() )
SvTreeListBox::StartDrag( nAction, rPt );
}
void SwGlobalTree::DragFinished( sal_Int8 nAction )
{
SvTreeListBox::DragFinished( nAction );
m_bIsInternalDrag = false;
}
// If a Ctrl+DoubleClick is executed in an empty area,
// then the base function of the control should be called.
void SwGlobalTree::MouseButtonDown( const MouseEvent& rMEvt )
{
Point aPos( rMEvt.GetPosPixel());
SvTreeListEntry* pEntry = GetEntry( aPos, true );
if( !pEntry && rMEvt.IsLeft() && rMEvt.IsMod1() && (rMEvt.GetClicks() % 2) == 0)
Control::MouseButtonDown( rMEvt );
else
SvTreeListBox::MouseButtonDown( rMEvt );
}
void SwGlobalTree::GetFocus()
{
if(Update( false ))
Display();
SvTreeListBox::GetFocus();
}
void SwGlobalTree::KeyInput(const KeyEvent& rKEvt)
{
const vcl::KeyCode aCode = rKEvt.GetKeyCode();
if(aCode.GetCode() == KEY_RETURN)
{
switch(aCode.GetModifier())
{
case KEY_MOD2:
// Switch boxes
GetParentWindow()->ToggleTree();
break;
}
}
else
SvTreeListBox::KeyInput(rKEvt);
}
void SwGlobalTree::Clear()
{
m_pEmphasisEntry = nullptr;
SvTreeListBox::Clear();
}
void SwGlobalTree::Display(bool bOnlyUpdateUserData)
{
size_t nCount = m_pSwGlblDocContents->size();
if(bOnlyUpdateUserData && GetEntryCount() == m_pSwGlblDocContents->size())
{
SvTreeListEntry* pEntry = First();
for (size_t i = 0; i < nCount && pEntry; i++)
{
SwGlblDocContent* pCont = (*m_pSwGlblDocContents)[i];
pEntry->SetUserData(pCont);
pEntry = Next(pEntry);
assert(pEntry || i == nCount - 1);
}
}
else
{
SetUpdateMode( false );
SvTreeListEntry* pOldSelEntry = FirstSelected();
OUString sEntryName; // Name of the entry
sal_uLong nSelPos = TREELIST_ENTRY_NOTFOUND;
if(pOldSelEntry)
{
sEntryName = GetEntryText(pOldSelEntry);
nSelPos = GetModel()->GetAbsPos(pOldSelEntry);
}
Clear();
if(!m_pSwGlblDocContents)
Update( false );
SvTreeListEntry* pSelEntry = nullptr;
for( size_t i = 0; i < nCount; i++)
{
SwGlblDocContent* pCont = (*m_pSwGlblDocContents)[i];
OUString sEntry;
Image aImage;
switch( pCont->GetType() )
{
case GLBLDOC_UNKNOWN:
{
sEntry = m_aContextStrings[IDX_STR_INSERT_TEXT];
}
break;
case GLBLDOC_TOXBASE:
{
const SwTOXBase* pBase = pCont->GetTOX();
sEntry = pBase->GetTitle();
aImage = Image(BitmapEx(RID_BMP_NAVI_INDEX));
}
break;
case GLBLDOC_SECTION:
{
const SwSection* pSect = pCont->GetSection();
sEntry = pSect->GetSectionName();
aImage = Image(BitmapEx(RID_BMP_DROP_REGION));
}
break;
}
SvTreeListEntry* pEntry = InsertEntry(sEntry, aImage, aImage,
nullptr, false, TREELIST_APPEND, pCont);
if(sEntry == sEntryName)
{
pSelEntry = pEntry;
}
}
if(pSelEntry)
{
Select(pSelEntry);
}
else if(nSelPos != TREELIST_ENTRY_NOTFOUND && nSelPos < nCount)
{
Select(GetEntry(nSelPos));
}
else if(nCount)
Select(First());
else
SelectHdl();
SetUpdateMode( true );
}
}
void SwGlobalTree::InsertRegion( const SwGlblDocContent* pCont, const OUString* pFileName )
{
Sequence< OUString > aFileNames;
if ( !pFileName )
{
m_pDocInserter.reset(new ::sfx2::DocumentInserter(GetFrameWeld(), "swriter", sfx2::DocumentInserter::Mode::InsertMulti));
m_pDocInserter->StartExecuteModal( LINK( this, SwGlobalTree, DialogClosedHdl ) );
}
else if ( !pFileName->isEmpty() )
{
aFileNames.realloc(1);
INetURLObject aFileName;
aFileName.SetSmartURL( *pFileName );
aFileNames.getArray()[0] = aFileName.GetMainURL( INetURLObject::DecodeMechanism::NONE );
InsertRegion( pCont, aFileNames );
}
}
void SwGlobalTree::EditContent(const SwGlblDocContent* pCont )
{
sal_uInt16 nSlot = 0;
switch( pCont->GetType() )
{
case GLBLDOC_UNKNOWN:
m_pActiveShell->GetView().GetEditWin().GrabFocus();
break;
case GLBLDOC_TOXBASE:
{
const SwTOXBase* pBase = pCont->GetTOX();
if(pBase)
nSlot = FN_INSERT_MULTI_TOX;
}
break;
case GLBLDOC_SECTION:
{
OpenDoc(pCont);
nSlot = 0;
pCont = nullptr;
}
break;
}
if(pCont)
GotoContent(pCont);
if(nSlot)
{
m_pActiveShell->GetView().GetViewFrame()->GetDispatcher()->Execute(nSlot);
if(Update( false ))
Display();
}
}
IMPL_LINK( SwGlobalTree, PopupHdl, Menu* , pMenu, bool)
{
ExecuteContextMenuAction( pMenu->GetCurItemId());
return true;
}
void SwGlobalTree::ExecuteContextMenuAction( sal_uInt16 nSelectedPopupEntry )
{
SvTreeListEntry* pEntry = FirstSelected();
SwGlblDocContent* pCont = pEntry ? static_cast<SwGlblDocContent*>(pEntry->GetUserData()) : nullptr;
// If a RequestHelp is called during the dialogue,
// then the content gets lost. Because of that a copy
// is created in which only the DocPos is set correctly.
SwGlblDocContent* pContCopy = nullptr;
if(pCont)
pContCopy = new SwGlblDocContent(pCont->GetDocPos());
SfxDispatcher& rDispatch = *m_pActiveShell->GetView().GetViewFrame()->GetDispatcher();
sal_uInt16 nSlot = 0;
bool bDeleteContentCopy = true;
switch( nSelectedPopupEntry )
{
case CTX_UPDATE_SEL:
{
// Two passes: first update the areas, then the directories.
SvTreeListEntry* pSelEntry = FirstSelected();
while( pSelEntry )
{
SwGlblDocContent* pContent = static_cast<SwGlblDocContent*>(pSelEntry->GetUserData());
if(GLBLDOC_SECTION == pContent->GetType() &&
pContent->GetSection()->IsConnected())
{
const_cast<SwSection*>(pContent->GetSection())->UpdateNow();
}
pSelEntry = NextSelected(pSelEntry);
}
pSelEntry = FirstSelected();
while( pSelEntry )
{
SwGlblDocContent* pContent = static_cast<SwGlblDocContent*>(pSelEntry->GetUserData());
if(GLBLDOC_TOXBASE == pContent->GetType())
m_pActiveShell->UpdateTableOf(*pContent->GetTOX());
pSelEntry = NextSelected(pSelEntry);
}
}
break;
case CTX_UPDATE_INDEX:
{
nSlot = FN_UPDATE_TOX;
}
break;
case CTX_UPDATE_LINK:
case CTX_UPDATE_ALL:
{
m_pActiveShell->GetLinkManager().UpdateAllLinks(true, false, nullptr);
if(CTX_UPDATE_ALL == nSelectedPopupEntry)
nSlot = FN_UPDATE_TOX;
pCont = nullptr;
}
break;
case CTX_EDIT:
{
OSL_ENSURE(pCont, "edit without entry ? " );
if (pCont)
{
EditContent(pCont);
}
}
break;
case CTX_EDIT_LINK:
{
OSL_ENSURE(pCont, "edit without entry ? " );
if (pCont)
{
SfxStringItem aName(FN_EDIT_REGION,
pCont->GetSection()->GetSectionName());
rDispatch.ExecuteList(FN_EDIT_REGION, SfxCallMode::ASYNCHRON,
{ &aName });
}
}
break;
case CTX_DELETE:
{
// If several entries selected, then after each delete the array
// must be refilled. So you do not have to remember anything,
// deleting begins at the end.
SvTreeListEntry* pSelEntry = LastSelected();
std::unique_ptr<SwGlblDocContents> pTempContents;
m_pActiveShell->StartAction();
while(pSelEntry)
{
m_pActiveShell->DeleteGlobalDocContent(
pTempContents ? *pTempContents : *m_pSwGlblDocContents,
GetModel()->GetAbsPos(pSelEntry));
pSelEntry = PrevSelected(pSelEntry);
if(pSelEntry)
{
pTempContents.reset(new SwGlblDocContents);
m_pActiveShell->GetGlobalDocContent(*pTempContents);
}
}
pTempContents.reset();
m_pActiveShell->EndAction();
pCont = nullptr;
}
break;
case CTX_INSERT_ANY_INDEX:
{
if(pContCopy)
{
SfxItemSet aSet(
m_pActiveShell->GetView().GetPool(),
svl::Items<
RES_FRM_SIZE, RES_FRM_SIZE,
RES_LR_SPACE, RES_LR_SPACE,
RES_BACKGROUND, RES_BACKGROUND,
RES_COL, RES_COL,
SID_ATTR_PAGE_SIZE, SID_ATTR_PAGE_SIZE,
FN_PARAM_TOX_TYPE, FN_PARAM_TOX_TYPE>{});
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
ScopedVclPtr<AbstractMultiTOXTabDialog> pDlg(pFact->CreateMultiTOXTabDialog(
this, aSet,
*m_pActiveShell,
nullptr,
true));
if(RET_OK == pDlg->Execute())
{
SwTOXDescription& rDesc = pDlg->GetTOXDescription(
pDlg->GetCurrentTOXType());
SwTOXMgr aMgr(m_pActiveShell);
SwTOXBase* pToInsert = nullptr;
if(aMgr.UpdateOrInsertTOX(rDesc, &pToInsert, pDlg->GetOutputItemSet()))
m_pActiveShell->InsertGlobalDocContent( *pContCopy, *pToInsert );
}
pCont = nullptr;
}
}
break;
case CTX_INSERT_FILE:
{
bDeleteContentCopy = false;
m_pDocContent = pContCopy;
InsertRegion( pContCopy );
pCont = nullptr;
}
break;
case CTX_INSERT_NEW_FILE:
{
SfxViewFrame* pGlobFrame = m_pActiveShell->GetView().GetViewFrame();
SwGlobalFrameListener_Impl aFrameListener(*pGlobFrame);
sal_uLong nEntryPos = pEntry ? GetModel()->GetAbsPos(pEntry) : sal_uLong(-1);
// Creating a new doc
SfxStringItem aFactory(SID_NEWDOCDIRECT,
SwDocShell::Factory().GetFilterContainer()->GetName());
const SfxFrameItem* pItem = static_cast<const SfxFrameItem*>(
rDispatch.ExecuteList(SID_NEWDOCDIRECT,
SfxCallMode::SYNCHRON, { &aFactory }));
// save at
SfxFrame* pFrame = pItem ? pItem->GetFrame() : nullptr;
SfxViewFrame* pViewFrame = pFrame ? pFrame->GetCurrentViewFrame() : nullptr;
if (pViewFrame)
{
const SfxBoolItem* pBool = static_cast<const SfxBoolItem*>(
pViewFrame->GetDispatcher()->Execute(
SID_SAVEASDOC, SfxCallMode::SYNCHRON ));
SfxObjectShell& rObj = *pViewFrame->GetObjectShell();
const SfxMedium* pMedium = rObj.GetMedium();
OUString sNewFile(pMedium->GetURLObject().GetMainURL(INetURLObject::DecodeMechanism::ToIUri));
// Insert the area with the Doc-Name
// Bring the own Doc in the foreground
if(aFrameListener.IsValid() && !sNewFile.isEmpty())
{
pGlobFrame->ToTop();
// Due to the update the entries are invalid
if(nEntryPos != sal_uLong(-1))
{
Update( false );
Display();
Select(GetModel()->GetEntryAtAbsPos(nEntryPos));
pEntry = FirstSelected();
pCont = pEntry ? static_cast<SwGlblDocContent*>(pEntry->GetUserData()) : nullptr;
}
else
{
pEntry = nullptr;
pCont = nullptr;
}
if(pBool->GetValue())
{
InsertRegion(pCont, &sNewFile);
pViewFrame->ToTop();
}
else
pViewFrame->GetDispatcher()->Execute(SID_CLOSEWIN,
SfxCallMode::SYNCHRON);
}
else
{
pViewFrame->ToTop();
return;
}
}
}
break;
case CTX_INSERT_TEXT:
{
if(pCont)
m_pActiveShell->InsertGlobalDocContent(*pCont);
else
{
m_pActiveShell->SplitNode(); // Empty document
m_pActiveShell->Up( false );
}
m_pActiveShell->GetView().GetEditWin().GrabFocus();
}
break;
case CTX_UPDATE:
pCont = nullptr;
break;
default:;
// here nothing happens
}
if(pCont)
GotoContent(pCont);
if(nSlot)
rDispatch.Execute(nSlot);
if(Update( false ))
Display();
if ( bDeleteContentCopy )
delete pContCopy;
}
IMPL_LINK_NOARG(SwGlobalTree, Timeout, Timer *, void)
{
if(!IsDisposed() && !HasFocus() && Update( false ))
Display();
}
void SwGlobalTree::GotoContent(const SwGlblDocContent* pCont)
{
m_pActiveShell->EnterStdMode();
switch( pCont->GetType() )
{
case GLBLDOC_UNKNOWN:
m_pActiveShell->GotoGlobalDocContent(*pCont);
break;
case GLBLDOC_TOXBASE:
{
const OUString sName = pCont->GetTOX()->GetTOXName();
if (!m_pActiveShell->GotoNextTOXBase(&sName))
m_pActiveShell->GotoPrevTOXBase(&sName);
}
break;
case GLBLDOC_SECTION:
break;
}
}
void SwGlobalTree::ShowTree()
{
m_aUpdateTimer.Start();
SvTreeListBox::Show();
}
void SwGlobalTree::HideTree()
{
m_aUpdateTimer.Stop();
SvTreeListBox::Hide();
}
void SwGlobalTree::ExecCommand(const OUString &rCmd)
{
SvTreeListEntry* pEntry = FirstSelected();
OSL_ENSURE(pEntry, "It explodes in the next moment");
if (rCmd == "edit")
{
const SwGlblDocContent* pCont = static_cast<const SwGlblDocContent*>(
pEntry->GetUserData());
EditContent(pCont);
}
else
{
if(GetSelectionCount() == 1)
{
bool bMove = false;
sal_uLong nSource = GetModel()->GetAbsPos(pEntry);
sal_uLong nDest = nSource;
if (rCmd == "down")
{
sal_uLong nEntryCount = GetEntryCount();
bMove = nEntryCount > nSource + 1;
nDest+= 2;
}
else if (rCmd == "up")
{
if(nSource)
bMove = 0 != nSource;
nDest--;
}
if( bMove && m_pActiveShell->MoveGlobalDocContent(
*m_pSwGlblDocContents, nSource, nSource + 1, nDest ) &&
Update( false ))
Display();
}
}
}
bool SwGlobalTree::Update(bool bHard)
{
SwView* pActView = GetParentWindow()->GetCreateView();
bool bRet = false;
if(pActView && pActView->GetWrtShellPtr())
{
const SwWrtShell* pOldShell = m_pActiveShell;
m_pActiveShell = pActView->GetWrtShellPtr();
if(m_pActiveShell != pOldShell)
{
m_pSwGlblDocContents.reset();
}
if(!m_pSwGlblDocContents)
{
m_pSwGlblDocContents.reset(new SwGlblDocContents);
bRet = true;
m_pActiveShell->GetGlobalDocContent(*m_pSwGlblDocContents);
}
else
{
bool bCopy = false;
std::unique_ptr<SwGlblDocContents> pTempContents(new SwGlblDocContents);
m_pActiveShell->GetGlobalDocContent(*pTempContents);
if(pTempContents->size() != m_pSwGlblDocContents->size() ||
pTempContents->size() != GetEntryCount())
{
bRet = true;
bCopy = true;
}
else
{
for(size_t i = 0; i < pTempContents->size() && !bCopy; i++)
{
SwGlblDocContent* pLeft = (*pTempContents)[i];
SwGlblDocContent* pRight = (*m_pSwGlblDocContents)[i];
GlobalDocContentType eType = pLeft->GetType();
SvTreeListEntry* pEntry = GetEntry(i);
OUString sTemp = GetEntryText(pEntry);
if (
eType != pRight->GetType() ||
(
eType == GLBLDOC_SECTION &&
pLeft->GetSection()->GetSectionName() != sTemp
) ||
(
eType == GLBLDOC_TOXBASE &&
pLeft->GetTOX()->GetTitle() != sTemp
)
)
{
bCopy = bRet = true;
}
}
}
if(bCopy || bHard)
{
m_pSwGlblDocContents->DeleteAndDestroyAll();
m_pSwGlblDocContents->insert( *pTempContents );
pTempContents->clear();
}
}
}
else
{
Clear();
if(m_pSwGlblDocContents)
m_pSwGlblDocContents->DeleteAndDestroyAll();
}
// FIXME: Implement a test for changes!
return bRet;
}
void SwGlobalTree::OpenDoc(const SwGlblDocContent* pCont)
{
const OUString sFileName(pCont->GetSection()->GetLinkFileName().getToken(0,
sfx2::cTokenSeparator));
bool bFound = false;
const SfxObjectShell* pCurr = SfxObjectShell::GetFirst();
while( !bFound && pCurr )
{
if(pCurr->GetMedium() &&
pCurr->GetMedium()->GetURLObject().GetMainURL(INetURLObject::DecodeMechanism::ToIUri) == sFileName)
{
bFound = true;
SwGlobalTree::SetShowShell(pCurr);
Application::PostUserEvent( LINK( this, SwGlobalTree, ShowFrameHdl ), nullptr, true );
pCurr = nullptr;
}
else
pCurr = SfxObjectShell::GetNext(*pCurr);
}
if(!bFound)
{
SfxStringItem aURL(SID_FILE_NAME, sFileName);
SfxBoolItem aReadOnly(SID_DOC_READONLY, false);
SfxStringItem aTargetFrameName( SID_TARGETNAME, "_blank" );
SfxStringItem aReferer(SID_REFERER, m_pActiveShell->GetView().GetDocShell()->GetTitle());
m_pActiveShell->GetView().GetViewFrame()->GetDispatcher()->
ExecuteList(SID_OPENDOC, SfxCallMode::ASYNCHRON,
{ &aURL, &aReadOnly, &aReferer, &aTargetFrameName });
}
}
IMPL_LINK_NOARG( SwGlobalTree, DoubleClickHdl, SvTreeListBox*, bool)
{
SvTreeListEntry* pEntry = GetCurEntry();
SwGlblDocContent* pCont = static_cast<SwGlblDocContent*>(pEntry->GetUserData());
if(pCont->GetType() == GLBLDOC_SECTION)
OpenDoc(pCont);
else
{
GotoContent(pCont);
m_pActiveShell->GetView().GetEditWin().GrabFocus();
}
return false;
}
SwNavigationPI* SwGlobalTree::GetParentWindow()
{
return m_xDialog;
}
IMPL_STATIC_LINK_NOARG(SwGlobalTree, ShowFrameHdl, void*, void)
{
SfxViewFrame* pFirst = pShowShell ? SfxViewFrame::GetFirst(pShowShell) : nullptr;
if (pFirst)
pFirst->ToTop();
SwGlobalTree::SetShowShell(nullptr);
}
void SwGlobalTree::InitEntry(SvTreeListEntry* pEntry,
const OUString& rStr ,const Image& rImg1,const Image& rImg2,
SvLBoxButtonKind eButtonKind)
{
const size_t nColToHilite = 1; //0==Bitmap;1=="Column1";2=="Column2"
SvTreeListBox::InitEntry( pEntry, rStr, rImg1, rImg2, eButtonKind );
SvLBoxString& rCol = static_cast<SvLBoxString&>(pEntry->GetItem( nColToHilite ));
pEntry->ReplaceItem(o3tl::make_unique<SwLBoxString>(rCol.GetText()), nColToHilite);
}
void SwLBoxString::Paint(const Point& rPos, SvTreeListBox& rDev, vcl::RenderContext& rRenderContext,
const SvViewDataEntry* pView, const SvTreeListEntry& rEntry)
{
SwGlblDocContent* pCont = static_cast<SwGlblDocContent*>(rEntry.GetUserData());
if (pCont->GetType() == GLBLDOC_SECTION &&
!pCont->GetSection()->IsConnectFlag())
{
rRenderContext.Push(PushFlags::FONT);
vcl::Font aOldFont(rRenderContext.GetFont());
vcl::Font aFont(rRenderContext.GetFont());
aFont.SetColor(COL_LIGHTRED);
rRenderContext.SetFont(aFont);
rRenderContext.DrawText(rPos, GetText());
rRenderContext.Pop();
}
else
SvLBoxString::Paint(rPos, rDev, rRenderContext, pView, rEntry);
}
void SwGlobalTree::DataChanged( const DataChangedEvent& rDCEvt )
{
if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
(rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
{
Update(true);
}
SvTreeListBox::DataChanged( rDCEvt );
}
void SwGlobalTree::InsertRegion( const SwGlblDocContent* _pContent, const Sequence< OUString >& _rFiles )
{
sal_Int32 nFiles = _rFiles.getLength();
if ( !nFiles )
return;
bool bMove = false;
if ( !_pContent )
{
SvTreeListEntry* pLast = LastVisible();
_pContent = static_cast<SwGlblDocContent*>(pLast->GetUserData());
bMove = true;
}
sal_uLong nEntryCount = GetEntryCount();
const OUString* pFileNames = _rFiles.getConstArray();
SwWrtShell& rSh = GetParentWindow()->GetCreateView()->GetWrtShell();
rSh.StartAction();
// after insertion of the first new content the 'pCont' parameter becomes invalid
// find the index of the 'anchor' content to always use a current anchor content
size_t nAnchorContent = m_pSwGlblDocContents->size() - 1;
if ( !bMove )
{
for (size_t nContent = 0; nContent < m_pSwGlblDocContents->size();
++nContent)
{
if( *_pContent == *(*m_pSwGlblDocContents)[ nContent ] )
{
nAnchorContent = nContent;
break;
}
}
}
SwGlblDocContents aTempContents;
for ( sal_Int32 nFile = 0; nFile < nFiles; ++nFile )
{
//update the global document content after each inserted document
rSh.GetGlobalDocContent(aTempContents);
SwGlblDocContent* pAnchorContent = nullptr;
OSL_ENSURE(aTempContents.size() > (nAnchorContent + nFile), "invalid anchor content -> last insertion failed");
if ( aTempContents.size() > (nAnchorContent + nFile) )
pAnchorContent = aTempContents[nAnchorContent + nFile];
else
pAnchorContent = aTempContents.back();
OUString sFileName(pFileNames[nFile]);
INetURLObject aFileUrl;
aFileUrl.SetSmartURL( sFileName );
OUString sSectionName(aFileUrl.GetLastName(
INetURLObject::DecodeMechanism::Unambiguous).getToken(0, sfx2::cTokenSeparator));
sal_uInt16 nSectCount = rSh.GetSectionFormatCount();
OUString sTempSectionName(sSectionName);
sal_uInt16 nAddNumber = 0;
sal_uInt16 nCount = 0;
// if applicable: add index if the range name is already in use.
while ( nCount < nSectCount )
{
const SwSectionFormat& rFormat = rSh.GetSectionFormat(nCount);
if ((rFormat.GetSection()->GetSectionName() == sTempSectionName)
&& rFormat.IsInNodesArr())
{
nCount = 0;
nAddNumber++;
sTempSectionName = sSectionName + ":" + OUString::number( nAddNumber );
}
else
nCount++;
}
if ( nAddNumber )
sSectionName = sTempSectionName;
SwSectionData aSectionData(CONTENT_SECTION, sSectionName);
aSectionData.SetProtectFlag(true);
aSectionData.SetHidden(false);
aSectionData.SetLinkFileName(sFileName);
aSectionData.SetType(FILE_LINK_SECTION);
aSectionData.SetLinkFilePassword( OUString() );
rSh.InsertGlobalDocContent( *pAnchorContent, aSectionData );
}
if ( bMove )
{
Update( false );
rSh.MoveGlobalDocContent(
*m_pSwGlblDocContents, nEntryCount, nEntryCount + nFiles, nEntryCount - nFiles );
}
rSh.EndAction();
Update( false );
Display();
}
IMPL_LINK( SwGlobalTree, DialogClosedHdl, sfx2::FileDialogHelper*, _pFileDlg, void )
{
if ( ERRCODE_NONE != _pFileDlg->GetError() )
return;
std::unique_ptr<SfxMediumList> pMedList(m_pDocInserter->CreateMediumList());
if ( pMedList )
{
Sequence< OUString >aFileNames( pMedList->size() );
OUString* pFileNames = aFileNames.getArray();
sal_Int32 nPos = 0;
for (SfxMedium* pMed : *pMedList)
{
OUString sFileName = pMed->GetURLObject().GetMainURL( INetURLObject::DecodeMechanism::NONE )
+ OUStringLiteral1(sfx2::cTokenSeparator)
+ pMed->GetFilter()->GetFilterName()
+ OUStringLiteral1(sfx2::cTokenSeparator);
pFileNames[nPos++] = sFileName;
}
pMedList.reset();
InsertRegion( m_pDocContent, aFileNames );
DELETEZ( m_pDocContent );
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V547 Expression '0 != nSource' is always true.