diff options
author | Caolán McNamara <caolanm@redhat.com> | 2018-10-08 09:02:25 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2018-11-07 22:01:02 +0100 |
commit | 6311f7ffce8f64b0773d2ad3ea7be3be683924c0 (patch) | |
tree | 67a59c93ca968838e86b63da214c75e98f8d0626 /svtools | |
parent | 128bec2c4bf57c2d82ce61319cbd1778bcabfeb1 (diff) |
move SvTreeListBox to vcl
Change-Id: I04a146d3d8a428ac1678827dc883525c40240a44
Reviewed-on: https://gerrit.libreoffice.org/62787
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'svtools')
33 files changed, 77 insertions, 14654 deletions
diff --git a/svtools/Library_svt.mk b/svtools/Library_svt.mk index 66cdda687dc6..5bbfb0925363 100644 --- a/svtools/Library_svt.mk +++ b/svtools/Library_svt.mk @@ -97,14 +97,8 @@ $(eval $(call gb_Library_add_exception_objects,svt,\ svtools/source/contnr/imivctl2 \ svtools/source/contnr/ivctrl \ svtools/source/contnr/simptabl \ - svtools/source/contnr/svimpbox \ - svtools/source/contnr/svlbitm \ svtools/source/contnr/svtabbx \ svtools/source/contnr/templwin \ - svtools/source/contnr/treelist \ - svtools/source/contnr/treelistbox \ - svtools/source/contnr/treelistentry \ - svtools/source/contnr/viewdataentry \ svtools/source/control/accessibleruler \ svtools/source/control/asynclink \ svtools/source/control/autocmpledit \ @@ -169,9 +163,6 @@ $(eval $(call gb_Library_add_exception_objects,svt,\ svtools/source/misc/filechangedchecker \ svtools/source/misc/imagemgr \ svtools/source/misc/imageresourceaccess \ - svtools/source/misc/imap \ - svtools/source/misc/imap2 \ - svtools/source/misc/imap3 \ svtools/source/misc/langtab \ svtools/source/misc/langhelp \ svtools/source/misc/openfiledroptargetlistener \ @@ -180,8 +171,6 @@ $(eval $(call gb_Library_add_exception_objects,svt,\ svtools/source/misc/svtaccessiblefactory \ svtools/source/misc/svtresid \ svtools/source/misc/templatefoldercache \ - svtools/source/misc/transfer \ - svtools/source/misc/transfer2 \ svtools/source/misc/unitconv \ svtools/source/svhtml/htmlkywd \ svtools/source/svhtml/htmlout \ @@ -221,7 +210,6 @@ $(eval $(call gb_Library_add_exception_objects,svt,\ svtools/source/uno/wizard/unowizard \ svtools/source/uno/wizard/wizardpagecontroller \ svtools/source/uno/wizard/wizardshell \ - svtools/source/urlobj/inetimg \ )) ifeq ($(OS),WNT) diff --git a/svtools/inc/bitmaps.hlst b/svtools/inc/bitmaps.hlst index 1f31a7f22a62..27c5f85a9858 100644 --- a/svtools/inc/bitmaps.hlst +++ b/svtools/inc/bitmaps.hlst @@ -104,8 +104,6 @@ #define BMP_PLUGIN "res/plugin.png" #define RID_BMP_FOLDER "svtools/res/folder.png" #define RID_BMP_FOLDER_OPEN "res/folderop.png" -#define RID_BMP_TREENODE_COLLAPSED "res/plus.png" -#define RID_BMP_TREENODE_EXPANDED "res/minus.png" #define BMP_CURRENT "svtools/res/ed01.png" #define BMP_MODIFIED "svtools/res/ed02.png" #define BMP_NEW "svtools/res/ed03.png" diff --git a/svtools/inc/pch/precompiled_svt.hxx b/svtools/inc/pch/precompiled_svt.hxx index d3ed09986710..3d7c3869a9d8 100644 --- a/svtools/inc/pch/precompiled_svt.hxx +++ b/svtools/inc/pch/precompiled_svt.hxx @@ -421,21 +421,21 @@ #include <svtools/htmltokn.h> #include <svtools/iconview.hxx> #include <svtools/imagemgr.hxx> -#include <svtools/imap.hxx> -#include <svtools/imapcirc.hxx> -#include <svtools/imappoly.hxx> -#include <svtools/imaprect.hxx> #include <svtools/imgdef.hxx> #include <svtools/inettbc.hxx> #include <svtools/miscopt.hxx> -#include <svtools/svlbitm.hxx> #include <svtools/svmedit.hxx> #include <svtools/svtdllapi.h> #include <svtools/svtresid.hxx> #include <svtools/table/tabletypes.hxx> -#include <svtools/transfer.hxx> -#include <svtools/treelistbox.hxx> -#include <svtools/treelistentry.hxx> -#include <svtools/viewdataentry.hxx> +#include <vcl/transfer.hxx> +#include <vcl/svlbitm.hxx> +#include <vcl/imap.hxx> +#include <vcl/imapcirc.hxx> +#include <vcl/imappoly.hxx> +#include <vcl/imaprect.hxx> +#include <vcl/treelistbox.hxx> +#include <vcl/treelistentry.hxx> +#include <vcl/viewdataentry.hxx> /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/inc/uitest/uiobject.hxx b/svtools/inc/uitest/uiobject.hxx index ff169749bf1a..16a137da7c7c 100644 --- a/svtools/inc/uitest/uiobject.hxx +++ b/svtools/inc/uitest/uiobject.hxx @@ -10,59 +10,8 @@ #include <memory> #include <vcl/uitest/uiobject.hxx> -class SvTreeListBox; -class SvTreeListEntry; class SvSimpleTable; -class TreeListUIObject : public WindowUIObject -{ -public: - TreeListUIObject(const VclPtr<SvTreeListBox>& xTreeList); - - virtual StringMap get_state() override; - - static std::unique_ptr<UIObject> create(vcl::Window* pWindow); - - virtual void execute(const OUString& rAction, - const StringMap& rParameters) override; - - virtual std::unique_ptr<UIObject> get_child(const OUString& rID) override; - - virtual std::set<OUString> get_children() const override; - -protected: - - virtual OUString get_name() const override; - -private: - - VclPtr<SvTreeListBox> mxTreeList; -}; - -class TreeListEntryUIObject : public UIObject -{ -public: - - TreeListEntryUIObject(const VclPtr<SvTreeListBox>& xTreeList, SvTreeListEntry* pEntry); - - virtual StringMap get_state() override; - - virtual void execute(const OUString& rAction, - const StringMap& rParameters) override; - - virtual std::unique_ptr<UIObject> get_child(const OUString& rID) override; - - virtual std::set<OUString> get_children() const override; - - virtual OUString get_type() const override; - -private: - - VclPtr<SvTreeListBox> mxTreeList; - - SvTreeListEntry* const mpEntry; -}; - class SimpleTableUIObject : public TreeListUIObject { public: diff --git a/svtools/source/brwbox/datwin.hxx b/svtools/source/brwbox/datwin.hxx index 5c30c0955e18..ef9a9ec5ab01 100644 --- a/svtools/source/brwbox/datwin.hxx +++ b/svtools/source/brwbox/datwin.hxx @@ -24,7 +24,7 @@ #include <svtools/brwhead.hxx> #include <vcl/timer.hxx> #include <vcl/image.hxx> -#include <svtools/transfer.hxx> +#include <vcl/transfer.hxx> #include <memory> #include <vector> diff --git a/svtools/source/contnr/DocumentInfoPreview.cxx b/svtools/source/contnr/DocumentInfoPreview.cxx index 42e0f6698da3..f4e7c89b0671 100644 --- a/svtools/source/contnr/DocumentInfoPreview.cxx +++ b/svtools/source/contnr/DocumentInfoPreview.cxx @@ -40,7 +40,6 @@ #include <tools/urlobj.hxx> #include <unotools/ucbhelper.hxx> -#include "fileview.hxx" #include <templwin.hrc> #include "templwin.hxx" diff --git a/svtools/source/contnr/fileview.cxx b/svtools/source/contnr/fileview.cxx index be2282ee9710..8cc3fef8c864 100644 --- a/svtools/source/contnr/fileview.cxx +++ b/svtools/source/contnr/fileview.cxx @@ -17,12 +17,11 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#include <svtools/treelistbox.hxx> +#include <vcl/treelistbox.hxx> #include <svtools/iconview.hxx> -#include "fileview.hxx" #include <sal/config.h> #include <sal/log.hxx> -#include <svtools/treelistentry.hxx> +#include <vcl/treelistentry.hxx> #include <svtools/fileview.hxx> #include <svtools/svtresid.hxx> #include <svtools/imagemgr.hxx> @@ -30,7 +29,7 @@ #include <svtools/svtabbx.hxx> #include <svtools/strings.hrc> #include <bitmaps.hlst> -#include <svtools/viewdataentry.hxx> +#include <vcl/viewdataentry.hxx> #include <toolkit/helper/vclunohelper.hxx> #include "contentenumeration.hxx" #include <svtools/AccessibleBrowseBoxObjType.hxx> @@ -419,50 +418,52 @@ inline void SvtFileView_Impl::EndEditing() mpCurView->EndEditing(); } -// functions ------------------------------------------------------------- - -OUString CreateExactSizeText( sal_Int64 nSize ) +namespace { - double fSize( static_cast<double>(nSize) ); - int nDec; + // functions ------------------------------------------------------------- - long nMega = 1024 * 1024; - long nGiga = nMega * 1024; + OUString CreateExactSizeText( sal_Int64 nSize ) + { + double fSize( static_cast<double>(nSize) ); + int nDec; - OUString aUnitStr(' '); + long nMega = 1024 * 1024; + long nGiga = nMega * 1024; - if ( nSize < 10000 ) - { - aUnitStr += SvtResId(STR_SVT_BYTES ); - nDec = 0; - } - else if ( nSize < nMega ) - { - fSize /= 1024; - aUnitStr += SvtResId(STR_SVT_KB); - nDec = 1; - } - else if ( nSize < nGiga ) - { - fSize /= nMega; - aUnitStr += SvtResId(STR_SVT_MB); - nDec = 2; - } - else - { - fSize /= nGiga; - aUnitStr += SvtResId(STR_SVT_GB); - nDec = 3; - } + OUString aUnitStr(' '); - OUString aSizeStr( ::rtl::math::doubleToUString( fSize, - rtl_math_StringFormat_F, nDec, - SvtSysLocale().GetLocaleData().getNumDecimalSep()[0]) ); - aSizeStr += aUnitStr; + if ( nSize < 10000 ) + { + aUnitStr += SvtResId(STR_SVT_BYTES ); + nDec = 0; + } + else if ( nSize < nMega ) + { + fSize /= 1024; + aUnitStr += SvtResId(STR_SVT_KB); + nDec = 1; + } + else if ( nSize < nGiga ) + { + fSize /= nMega; + aUnitStr += SvtResId(STR_SVT_MB); + nDec = 2; + } + else + { + fSize /= nGiga; + aUnitStr += SvtResId(STR_SVT_GB); + nDec = 3; + } - return aSizeStr; -} + OUString aSizeStr( ::rtl::math::doubleToUString( fSize, + rtl_math_StringFormat_F, nDec, + SvtSysLocale().GetLocaleData().getNumDecimalSep()[0]) ); + aSizeStr += aUnitStr; + return aSizeStr; + } +} ViewTabListBox_Impl::ViewTabListBox_Impl( vcl::Window* pParentWin, SvtFileView_Impl* pParent, diff --git a/svtools/source/contnr/fileview.hxx b/svtools/source/contnr/fileview.hxx deleted file mode 100644 index c1dad51e3da4..000000000000 --- a/svtools/source/contnr/fileview.hxx +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- 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 . - */ - -#ifndef INCLUDED_SVTOOLS_SOURCE_CONTNR_FILEVIEW_HXX -#define INCLUDED_SVTOOLS_SOURCE_CONTNR_FILEVIEW_HXX - -#include <sal/config.h> - -#include <sal/types.h> -#include <rtl/ustring.hxx> - -OUString CreateExactSizeText(sal_Int64 nSize); - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/contnr/iconview.cxx b/svtools/source/contnr/iconview.cxx index 9af84362f45f..f00e10b77b5e 100644 --- a/svtools/source/contnr/iconview.cxx +++ b/svtools/source/contnr/iconview.cxx @@ -18,7 +18,7 @@ */ #include <svtools/iconview.hxx> -#include <svtools/treelistentry.hxx> +#include <vcl/treelistentry.hxx> #include <svtools/fileview.hxx> #include <iconviewimpl.hxx> diff --git a/svtools/source/contnr/simptabl.cxx b/svtools/source/contnr/simptabl.cxx index 66860faba759..cea94c5eba7e 100644 --- a/svtools/source/contnr/simptabl.cxx +++ b/svtools/source/contnr/simptabl.cxx @@ -18,8 +18,8 @@ */ #include <svtools/simptabl.hxx> -#include <svtools/svlbitm.hxx> -#include <svtools/treelistentry.hxx> +#include <vcl/svlbitm.hxx> +#include <vcl/treelistentry.hxx> #include <vcl/builderfactory.hxx> #include <vcl/svapp.hxx> #include <vcl/settings.hxx> diff --git a/svtools/source/contnr/svimpbox.cxx b/svtools/source/contnr/svimpbox.cxx deleted file mode 100644 index 11a1f6e6890a..000000000000 --- a/svtools/source/contnr/svimpbox.cxx +++ /dev/null @@ -1,3389 +0,0 @@ -/* -*- 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 <vcl/svapp.hxx> -#include <vcl/salnativewidgets.hxx> -#include <vcl/help.hxx> -#include <vcl/settings.hxx> - -#include <cstdlib> -#include <memory> -#include <stack> - -#include <svtools/treelistbox.hxx> -#include <svtools/iconview.hxx> -#include <svtools/svlbitm.hxx> -#include <svimpbox.hxx> -#include <iconviewimpl.hxx> -#include <rtl/instance.hxx> -#include <tools/wintypes.hxx> -#include <bitmaps.hlst> -#include <comphelper/processfactory.hxx> -#include <comphelper/string.hxx> - -#include <svtools/treelistentry.hxx> -#include <svtools/viewdataentry.hxx> - -// #i27063# (pl), #i32300# (pb) never access VCL after DeInitVCL - also no destructors -Image* SvImpLBox::s_pDefCollapsed = nullptr; -Image* SvImpLBox::s_pDefExpanded = nullptr; -oslInterlockedCount SvImpLBox::s_nImageRefCount = 0; - -SvImpLBox::SvImpLBox( SvTreeListBox* pLBView, SvTreeList* pLBTree, WinBits nWinStyle) - : aHorSBar(VclPtr<ScrollBar>::Create(pLBView, WB_DRAG | WB_HSCROLL)) - , aScrBarBox(VclPtr<ScrollBarBox>::Create(pLBView)) - , aFctSet(this, pLBView) - , bAreChildrenTransient(true) - , mbForceMakeVisible (false) - , aVerSBar(VclPtr<ScrollBar>::Create(pLBView, WB_DRAG | WB_VSCROLL)) - , aOutputSize(0, 0) - , mbNoAutoCurEntry(false) - , aSelEng(pLBView, nullptr) - , nNextVerVisSize(0) -{ - osl_atomic_increment(&s_nImageRefCount); - pView = pLBView; - pTree = pLBTree; - aSelEng.SetFunctionSet( static_cast<FunctionSet*>(&aFctSet) ); - aSelEng.ExpandSelectionOnMouseMove( false ); - SetStyle( nWinStyle ); - SetSelectionMode( SelectionMode::Single ); - SetDragDropMode( DragDropMode::NONE ); - - aVerSBar->SetScrollHdl( LINK( this, SvImpLBox, ScrollUpDownHdl ) ); - aHorSBar->SetScrollHdl( LINK( this, SvImpLBox, ScrollLeftRightHdl ) ); - aHorSBar->SetEndScrollHdl( LINK( this, SvImpLBox, EndScrollHdl ) ); - aVerSBar->SetEndScrollHdl( LINK( this, SvImpLBox, EndScrollHdl ) ); - aVerSBar->SetRange( Range(0,0) ); - aVerSBar->Hide(); - aHorSBar->SetRange( Range(0,0) ); - aHorSBar->SetPageSize( 24 ); // pixels - aHorSBar->SetLineSize( 8 ); // pixels - - nHorSBarHeight = static_cast<short>(aHorSBar->GetSizePixel().Height()); - nVerSBarWidth = static_cast<short>(aVerSBar->GetSizePixel().Width()); - - pStartEntry = nullptr; - pCursor = nullptr; - pAnchor = nullptr; - nVisibleCount = 0; // number of rows of data in control - nNodeBmpTabDistance = NODE_BMP_TABDIST_NOTVALID; - nNodeBmpWidth = 0; - - bAsyncBeginDrag = false; - aAsyncBeginDragIdle.SetPriority( TaskPriority::HIGHEST ); - aAsyncBeginDragIdle.SetInvokeHandler( LINK(this,SvImpLBox,BeginDragHdl)); - // button animation in listbox - pActiveButton = nullptr; - pActiveEntry = nullptr; - pActiveTab = nullptr; - - nFlags = LBoxFlags::NONE; - nCurTabPos = FIRST_ENTRY_TAB; - - aEditIdle.SetPriority( TaskPriority::LOWEST ); - aEditIdle.SetInvokeHandler( LINK(this,SvImpLBox,EditTimerCall) ); - - nMostRight = -1; - pMostRightEntry = nullptr; - nCurUserEvent = nullptr; - - bUpdateMode = true; - bInVScrollHdl = false; - nFlags |= LBoxFlags::Filling; - - bSubLstOpRet = bSubLstOpLR = bContextMenuHandling = bIsCellFocusEnabled = false; - bSubLstOpDblClick = true; -} - -SvImpLBox::~SvImpLBox() -{ - aEditIdle.Stop(); - StopUserEvent(); - - if ( osl_atomic_decrement(&s_nImageRefCount) == 0 ) - { - DELETEZ(s_pDefCollapsed); - DELETEZ(s_pDefExpanded); - } - aVerSBar.disposeAndClear(); - aHorSBar.disposeAndClear(); - aScrBarBox.disposeAndClear(); -} - -void SvImpLBox::UpdateStringSorter() -{ - const css::lang::Locale& rNewLocale = Application::GetSettings().GetLanguageTag().getLocale(); - - if( m_pStringSorter ) - { - // different Locale from the older one, drop it and force recreate - const css::lang::Locale &aLocale = m_pStringSorter->getLocale(); - if( aLocale.Language != rNewLocale.Language || - aLocale.Country != rNewLocale.Country || - aLocale.Variant != rNewLocale.Variant ) - m_pStringSorter.reset(); - } - - if( !m_pStringSorter ) - { - m_pStringSorter.reset(new comphelper::string::NaturalStringSorter( - ::comphelper::getProcessComponentContext(), - rNewLocale)); - } -} - -short SvImpLBox::UpdateContextBmpWidthVector( SvTreeListEntry const * pEntry, short nWidth ) -{ - DBG_ASSERT( pView->pModel, "View and Model aren't valid!" ); - - sal_uInt16 nDepth = pView->pModel->GetDepth( pEntry ); - // initialize vector if necessary - std::vector< short >::size_type nSize = aContextBmpWidthVector.size(); - while ( nDepth > nSize ) - { - aContextBmpWidthVector.resize( nSize + 1 ); - aContextBmpWidthVector.at( nSize ) = nWidth; - ++nSize; - } - if( aContextBmpWidthVector.size() == nDepth ) - { - aContextBmpWidthVector.resize( nDepth + 1 ); - aContextBmpWidthVector.at( nDepth ) = 0; - } - short nContextBmpWidth = aContextBmpWidthVector[ nDepth ]; - if( nContextBmpWidth < nWidth ) - { - aContextBmpWidthVector.at( nDepth ) = nWidth; - return nWidth; - } - else - return nContextBmpWidth; -} - -void SvImpLBox::UpdateContextBmpWidthVectorFromMovedEntry( SvTreeListEntry* pEntry ) -{ - DBG_ASSERT( pEntry, "Moved Entry is invalid!" ); - - SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem(SvLBoxItemType::ContextBmp) ); - short nExpWidth = static_cast<short>(pBmpItem->GetBitmap1().GetSizePixel().Width()); - short nColWidth = static_cast<short>(pBmpItem->GetBitmap2().GetSizePixel().Width()); - short nMax = std::max(nExpWidth, nColWidth); - UpdateContextBmpWidthVector( pEntry, nMax ); - - if( pEntry->HasChildren() ) // recursive call, whether expanded or not - { - SvTreeListEntry* pChild = pView->FirstChild( pEntry ); - DBG_ASSERT( pChild, "The first child is invalid!" ); - do - { - UpdateContextBmpWidthVectorFromMovedEntry( pChild ); - pChild = pView->Next( pChild ); - } while ( pChild ); - } -} - -void SvImpLBox::UpdateContextBmpWidthMax( SvTreeListEntry const * pEntry ) -{ - sal_uInt16 nDepth = pView->pModel->GetDepth( pEntry ); - if( aContextBmpWidthVector.empty() ) - return; - short nWidth = aContextBmpWidthVector[ nDepth ]; - if( nWidth != pView->nContextBmpWidthMax ) { - pView->nContextBmpWidthMax = nWidth; - nFlags |= LBoxFlags::IgnoreChangedTabs; - pView->SetTabs(); - nFlags &= ~LBoxFlags::IgnoreChangedTabs; - } -} - -void SvImpLBox::CalcCellFocusRect( SvTreeListEntry const * pEntry, tools::Rectangle& rRect ) -{ - if ( !(pEntry && bIsCellFocusEnabled) ) - return; - - if ( nCurTabPos > FIRST_ENTRY_TAB ) - { - SvLBoxItem& rItem = pCursor->GetItem( nCurTabPos ); - rRect.SetLeft( pView->GetTab( pCursor, &rItem )->GetPos() ); - } - if (pCursor->ItemCount() > static_cast<size_t>(nCurTabPos+1)) - { - SvLBoxItem& rNextItem = pCursor->GetItem( nCurTabPos + 1 ); - long nRight = pView->GetTab( pCursor, &rNextItem )->GetPos() - 1; - if ( nRight < rRect.Right() ) - rRect.SetRight( nRight ); - } -} - -void SvImpLBox::SetStyle( WinBits i_nWinStyle ) -{ - m_nStyle = i_nWinStyle; - if ( ( m_nStyle & WB_SIMPLEMODE) && ( aSelEng.GetSelectionMode() == SelectionMode::Multiple ) ) - aSelEng.AddAlways( true ); -} - -void SvImpLBox::SetNoAutoCurEntry( bool b ) -{ - mbNoAutoCurEntry = b; -} - -// don't touch the model any more -void SvImpLBox::Clear() -{ - StopUserEvent(); - pStartEntry = nullptr; - pAnchor = nullptr; - - pActiveButton = nullptr; - pActiveEntry = nullptr; - pActiveTab = nullptr; - - nMostRight = -1; - pMostRightEntry = nullptr; - - // don't touch the cursor any more - if( pCursor ) - { - if( pView->HasFocus() ) - pView->HideFocus(); - pCursor = nullptr; - } - aVerSBar->Hide(); - aVerSBar->SetThumbPos( 0 ); - Range aRange( 0, 0 ); - aVerSBar->SetRange( aRange ); - aOutputSize = pView->Control::GetOutputSizePixel(); - aHorSBar->Hide(); - aHorSBar->SetThumbPos( 0 ); - MapMode aMapMode( pView->GetMapMode()); - aMapMode.SetOrigin( Point(0,0) ); - pView->Control::SetMapMode( aMapMode ); - aHorSBar->SetRange( aRange ); - aHorSBar->SetSizePixel(Size(aOutputSize.Width(),nHorSBarHeight)); - pView->SetClipRegion(); - if( GetUpdateMode() ) - pView->Invalidate( GetVisibleArea() ); - nFlags |= LBoxFlags::Filling; - if( !aHorSBar->IsVisible() && !aVerSBar->IsVisible() ) - aScrBarBox->Hide(); - - aContextBmpWidthVector.clear(); - - CallEventListeners( VclEventId::ListboxItemRemoved ); -} - -// ********************************************************************* -// Paint, navigate, scroll -// ********************************************************************* - -IMPL_LINK_NOARG(SvImpLBox, EndScrollHdl, ScrollBar*, void) -{ - if( nFlags & LBoxFlags::EndScrollSetVisSize ) - { - aVerSBar->SetVisibleSize( nNextVerVisSize ); - nFlags &= ~LBoxFlags::EndScrollSetVisSize; - } - EndScroll(); -} - -// handler for vertical scrollbar - -IMPL_LINK( SvImpLBox, ScrollUpDownHdl, ScrollBar *, pScrollBar, void ) -{ - DBG_ASSERT(!bInVScrollHdl,"Scroll handler out-paces itself!"); - long nDelta = pScrollBar->GetDelta(); - if( !nDelta ) - return; - - nFlags &= (~LBoxFlags::Filling); - - bInVScrollHdl = true; - - if( pView->IsEditingActive() ) - { - pView->EndEditing( true ); // Cancel - pView->Update(); - } - BeginScroll(); - - if( nDelta > 0 ) - { - if( nDelta == 1 ) - CursorDown(); - else - PageDown( static_cast<sal_uInt16>(nDelta) ); - } - else - { - nDelta *= -1; - if( nDelta == 1 ) - CursorUp(); - else - PageUp( static_cast<sal_uInt16>(nDelta) ); - } - bInVScrollHdl = false; -} - - -void SvImpLBox::CursorDown() -{ - if (!pStartEntry) - return; - - SvTreeListEntry* pNextFirstToDraw = pView->NextVisible(pStartEntry); - if( pNextFirstToDraw ) - { - nFlags &= (~LBoxFlags::Filling); - ShowCursor( false ); - pView->Update(); - pStartEntry = pNextFirstToDraw; - tools::Rectangle aArea( GetVisibleArea() ); - pView->Scroll( 0, -(pView->GetEntryHeight()), aArea, ScrollFlags::NoChildren ); - pView->Update(); - ShowCursor( true ); - pView->NotifyScrolled(); - } -} - -void SvImpLBox::CursorUp() -{ - if (!pStartEntry) - return; - - SvTreeListEntry* pPrevFirstToDraw = pView->PrevVisible(pStartEntry); - if( !pPrevFirstToDraw ) - return; - - nFlags &= (~LBoxFlags::Filling); - long nEntryHeight = pView->GetEntryHeight(); - ShowCursor( false ); - pView->Update(); - pStartEntry = pPrevFirstToDraw; - tools::Rectangle aArea( GetVisibleArea() ); - aArea.AdjustBottom( -nEntryHeight ); - pView->Scroll( 0, nEntryHeight, aArea, ScrollFlags::NoChildren ); - pView->Update(); - ShowCursor( true ); - pView->NotifyScrolled(); -} - -void SvImpLBox::PageDown( sal_uInt16 nDelta ) -{ - sal_uInt16 nRealDelta = nDelta; - - if( !nDelta ) - return; - - if (!pStartEntry) - return; - - SvTreeListEntry* pNext = pView->NextVisible(pStartEntry, nRealDelta); - if( pNext == pStartEntry ) - return; - - ShowCursor( false ); - - nFlags &= (~LBoxFlags::Filling); - pView->Update(); - pStartEntry = pNext; - - if( nRealDelta >= nVisibleCount ) - { - pView->Invalidate( GetVisibleArea() ); - pView->Update(); - } - else - { - tools::Rectangle aArea( GetVisibleArea() ); - long nScroll = pView->GetEntryHeight() * static_cast<long>(nRealDelta); - nScroll = -nScroll; - pView->Update(); - pView->Scroll( 0, nScroll, aArea, ScrollFlags::NoChildren ); - pView->Update(); - pView->NotifyScrolled(); - } - - ShowCursor( true ); -} - -void SvImpLBox::PageUp( sal_uInt16 nDelta ) -{ - sal_uInt16 nRealDelta = nDelta; - if( !nDelta ) - return; - - if (!pStartEntry) - return; - - SvTreeListEntry* pPrev = pView->PrevVisible(pStartEntry, nRealDelta); - if( pPrev == pStartEntry ) - return; - - nFlags &= (~LBoxFlags::Filling); - ShowCursor( false ); - - pView->Update(); - pStartEntry = pPrev; - if( nRealDelta >= nVisibleCount ) - { - pView->Invalidate( GetVisibleArea() ); - pView->Update(); - } - else - { - long nEntryHeight = pView->GetEntryHeight(); - tools::Rectangle aArea( GetVisibleArea() ); - pView->Update(); - pView->Scroll( 0, nEntryHeight*nRealDelta, aArea, ScrollFlags::NoChildren ); - pView->Update(); - pView->NotifyScrolled(); - } - - ShowCursor( true ); -} - -void SvImpLBox::KeyUp( bool bPageUp ) -{ - if( !aVerSBar->IsVisible() ) - return; - - long nDelta; - if( bPageUp ) - nDelta = aVerSBar->GetPageSize(); - else - nDelta = 1; - - long nThumbPos = aVerSBar->GetThumbPos(); - - if( nThumbPos < nDelta ) - nDelta = nThumbPos; - - if( nDelta <= 0 ) - return; - - nFlags &= (~LBoxFlags::Filling); - BeginScroll(); - - aVerSBar->SetThumbPos( nThumbPos - nDelta ); - if( bPageUp ) - PageUp( static_cast<short>(nDelta) ); - else - CursorUp(); - - EndScroll(); -} - - -void SvImpLBox::KeyDown( bool bPageDown ) -{ - if( !aVerSBar->IsVisible() ) - return; - - long nDelta; - if( bPageDown ) - nDelta = aVerSBar->GetPageSize(); - else - nDelta = 1; - - long nThumbPos = aVerSBar->GetThumbPos(); - long nVisibleSize = aVerSBar->GetVisibleSize(); - long nRange = aVerSBar->GetRange().Len(); - - long nTmp = nThumbPos+nVisibleSize; - while( (nDelta > 0) && (nTmp+nDelta) >= nRange ) - nDelta--; - - if( nDelta <= 0 ) - return; - - nFlags &= (~LBoxFlags::Filling); - BeginScroll(); - - aVerSBar->SetThumbPos( nThumbPos+nDelta ); - if( bPageDown ) - PageDown( static_cast<short>(nDelta) ); - else - CursorDown(); - - EndScroll(); -} - - -void SvImpLBox::InvalidateEntriesFrom( long nY ) const -{ - if( !(nFlags & LBoxFlags::InPaint )) - { - tools::Rectangle aRect( GetVisibleArea() ); - aRect.SetTop( nY ); - pView->Invalidate( aRect ); - } -} - -void SvImpLBox::InvalidateEntry( long nY ) const -{ - if( !(nFlags & LBoxFlags::InPaint )) - { - tools::Rectangle aRect( GetVisibleArea() ); - long nMaxBottom = aRect.Bottom(); - aRect.SetTop( nY ); - aRect.SetBottom( nY ); aRect.AdjustBottom(pView->GetEntryHeight() ); - if( aRect.Top() > nMaxBottom ) - return; - if( aRect.Bottom() > nMaxBottom ) - aRect.SetBottom( nMaxBottom ); - pView->Invalidate( aRect ); - } -} - -void SvImpLBox::InvalidateEntry( SvTreeListEntry* pEntry ) -{ - if( GetUpdateMode() ) - { - long nPrev = nMostRight; - SetMostRight( pEntry ); - if( nPrev < nMostRight ) - ShowVerSBar(); - } - if( !(nFlags & LBoxFlags::InPaint )) - { - bool bHasFocusRect = false; - if( pEntry==pCursor && pView->HasFocus() ) - { - bHasFocusRect = true; - ShowCursor( false ); - } - InvalidateEntry( GetEntryLine( pEntry ) ); - if( bHasFocusRect ) - ShowCursor( true ); - } -} - - -void SvImpLBox::RecalcFocusRect() -{ - if( pView->HasFocus() && pCursor ) - { - pView->HideFocus(); - long nY = GetEntryLine( pCursor ); - tools::Rectangle aRect = pView->GetFocusRect( pCursor, nY ); - CalcCellFocusRect( pCursor, aRect ); - vcl::Region aOldClip( pView->GetClipRegion()); - vcl::Region aClipRegion( GetClipRegionRect() ); - pView->SetClipRegion( aClipRegion ); - pView->ShowFocus( aRect ); - pView->SetClipRegion( aOldClip ); - } -} - - -// Sets cursor. When using SingleSelection, the selection is adjusted. - - -void SvImpLBox::SetCursor( SvTreeListEntry* pEntry, bool bForceNoSelect ) -{ - SvViewDataEntry* pViewDataNewCur = nullptr; - if( pEntry ) - pViewDataNewCur= pView->GetViewDataEntry(pEntry); - if( pEntry && - pEntry == pCursor && - pViewDataNewCur && - pViewDataNewCur->HasFocus() && - pViewDataNewCur->IsSelected()) - { - return; - } - - // if this cursor is not selectable, find first visible that is and use it - while( pEntry && pViewDataNewCur && !pViewDataNewCur->IsSelectable() ) - { - pEntry = pView->NextVisible(pEntry); - pViewDataNewCur = pEntry ? pView->GetViewDataEntry(pEntry) : nullptr; - } - - SvTreeListEntry* pOldCursor = pCursor; - if( pCursor && pEntry != pCursor ) - { - pView->SetEntryFocus( pCursor, false ); - if( bSimpleTravel ) - pView->Select( pCursor, false ); - pView->HideFocus(); - } - pCursor = pEntry; - if( pCursor ) - { - if (pViewDataNewCur) - pViewDataNewCur->SetFocus( true ); - if(!bForceNoSelect && bSimpleTravel && !(nFlags & LBoxFlags::DeselectAll) && GetUpdateMode()) - { - pView->Select( pCursor ); - CallEventListeners( VclEventId::ListboxTreeFocus, pCursor ); - } - // multiple selection: select in cursor move if we're not in - // Add mode (Ctrl-F8) - else if( GetUpdateMode() && - pView->GetSelectionMode() == SelectionMode::Multiple && - !(nFlags & LBoxFlags::DeselectAll) && !aSelEng.IsAddMode() && - !bForceNoSelect ) - { - pView->Select( pCursor ); - CallEventListeners( VclEventId::ListboxTreeFocus, pCursor ); - } - else - { - ShowCursor( true ); - if (bForceNoSelect && GetUpdateMode()) - { - CallEventListeners( VclEventId::ListboxTreeFocus, pCursor); - } - } - - if( pAnchor ) - { - DBG_ASSERT(aSelEng.GetSelectionMode() != SelectionMode::Single,"Mode?"); - SetAnchorSelection( pOldCursor, pCursor ); - } - } - nFlags &= (~LBoxFlags::DeselectAll); - - pView->OnCurrentEntryChanged(); -} - -void SvImpLBox::ShowCursor( bool bShow ) -{ - if( !bShow || !pCursor || !pView->HasFocus() ) - { - vcl::Region aOldClip( pView->GetClipRegion()); - vcl::Region aClipRegion( GetClipRegionRect() ); - pView->SetClipRegion( aClipRegion ); - pView->HideFocus(); - pView->SetClipRegion( aOldClip ); - } - else - { - long nY = GetEntryLine( pCursor ); - tools::Rectangle aRect = pView->GetFocusRect( pCursor, nY ); - CalcCellFocusRect( pCursor, aRect ); - vcl::Region aOldClip( pView->GetClipRegion()); - vcl::Region aClipRegion( GetClipRegionRect() ); - pView->SetClipRegion( aClipRegion ); - pView->ShowFocus( aRect ); - pView->SetClipRegion( aOldClip ); - } -} - - -void SvImpLBox::UpdateAll( bool bInvalidateCompleteView ) -{ - FindMostRight(nullptr); - aVerSBar->SetRange( Range(0, pView->GetVisibleCount()-1 ) ); - SyncVerThumb(); - FillView(); - ShowVerSBar(); - if( bSimpleTravel && pCursor && pView->HasFocus() ) - pView->Select( pCursor ); - ShowCursor( true ); - if( bInvalidateCompleteView ) - pView->Invalidate(); - else - pView->Invalidate( GetVisibleArea() ); -} - -IMPL_LINK( SvImpLBox, ScrollLeftRightHdl, ScrollBar *, pScrollBar, void ) -{ - long nDelta = pScrollBar->GetDelta(); - if( nDelta ) - { - if( pView->IsEditingActive() ) - { - pView->EndEditing( true ); // Cancel - pView->Update(); - } - pView->nFocusWidth = -1; - KeyLeftRight( nDelta ); - } -} - -void SvImpLBox::KeyLeftRight( long nDelta ) -{ - if( !(nFlags & LBoxFlags::InResize) ) - pView->Update(); - BeginScroll(); - nFlags &= (~LBoxFlags::Filling); - ShowCursor( false ); - - // calculate new origin - long nPos = aHorSBar->GetThumbPos(); - Point aOrigin( -nPos, 0 ); - - MapMode aMapMode( pView->GetMapMode() ); - aMapMode.SetOrigin( aOrigin ); - pView->SetMapMode( aMapMode ); - - if( !(nFlags & LBoxFlags::InResize) ) - { - tools::Rectangle aRect( GetVisibleArea() ); - pView->Scroll( -nDelta, 0, aRect, ScrollFlags::NoChildren ); - } - else - pView->Invalidate(); - RecalcFocusRect(); - ShowCursor( true ); - pView->NotifyScrolled(); -} - - -// returns the last entry if position is just past the last entry -SvTreeListEntry* SvImpLBox::GetClickedEntry( const Point& rPoint ) const -{ - DBG_ASSERT( pView->GetModel(), "SvImpLBox::GetClickedEntry: how can this ever happen? Please tell me (frank.schoenheit@sun.com) how to reproduce!" ); - if ( !pView->GetModel() ) - // this is quite impossible. Nevertheless, stack traces from the crash reporter - // suggest it isn't. Okay, make it safe, and wait for somebody to reproduce it - // reliably :-\ .... - // #122359# / 2005-05-23 / frank.schoenheit@sun.com - return nullptr; - if( pView->GetEntryCount() == 0 || !pStartEntry || !pView->GetEntryHeight()) - return nullptr; - - sal_uInt16 nClickedEntry = static_cast<sal_uInt16>(rPoint.Y() / pView->GetEntryHeight() ); - sal_uInt16 nTemp = nClickedEntry; - SvTreeListEntry* pEntry = pView->NextVisible(pStartEntry, nTemp); - return pEntry; -} - - -// checks if the entry was hit "the right way" -// (Focusrect+ ContextBitmap at TreeListBox) - -bool SvImpLBox::EntryReallyHit(SvTreeListEntry* pEntry, const Point& rPosPixel, long nLine) -{ - bool bRet; - // we are not too exact when it comes to "special" entries - // (with CheckButtons etc.) - if( pEntry->ItemCount() >= 3 ) - return true; - - tools::Rectangle aRect( pView->GetFocusRect( pEntry, nLine )); - aRect.SetRight( GetOutputSize().Width() - pView->GetMapMode().GetOrigin().X() ); - - SvLBoxContextBmp* pBmp = static_cast<SvLBoxContextBmp*>(pEntry->GetFirstItem(SvLBoxItemType::ContextBmp)); - aRect.AdjustLeft( -(pBmp->GetSize(pView,pEntry).Width()) ); - aRect.AdjustLeft( -4 ); // a little tolerance - - Point aPos( rPosPixel ); - aPos -= pView->GetMapMode().GetOrigin(); - bRet = aRect.IsInside( aPos ); - return bRet; -} - - -// returns 0 if position is just past the last entry -SvTreeListEntry* SvImpLBox::GetEntry( const Point& rPoint ) const -{ - if( (pView->GetEntryCount() == 0) || !pStartEntry || - (rPoint.Y() > aOutputSize.Height()) - || !pView->GetEntryHeight()) - return nullptr; - - sal_uInt16 nClickedEntry = static_cast<sal_uInt16>(rPoint.Y() / pView->GetEntryHeight() ); - sal_uInt16 nTemp = nClickedEntry; - SvTreeListEntry* pEntry = pView->NextVisible(pStartEntry, nTemp); - if( nTemp != nClickedEntry ) - pEntry = nullptr; - return pEntry; -} - - -SvTreeListEntry* SvImpLBox::MakePointVisible(const Point& rPoint) -{ - if( !pCursor ) - return nullptr; - long nY = rPoint.Y(); - SvTreeListEntry* pEntry = nullptr; - long nMax = aOutputSize.Height(); - if( nY < 0 || nY >= nMax ) // aOutputSize.Height() ) - { - if( nY < 0 ) - pEntry = pView->PrevVisible(pCursor); - else - pEntry = pView->NextVisible(pCursor); - - if( pEntry && pEntry != pCursor ) - pView->SetEntryFocus( pCursor, false ); - - if( nY < 0 ) - KeyUp( false ); - else - KeyDown( false ); - } - else - { - pEntry = GetClickedEntry( rPoint ); - if( !pEntry ) - { - sal_uInt16 nSteps = 0xFFFF; - // TODO: LastVisible is not yet implemented! - pEntry = pView->NextVisible(pStartEntry, nSteps); - } - if( pEntry ) - { - if( pEntry != pCursor && - aSelEng.GetSelectionMode() == SelectionMode::Single - ) - pView->Select( pCursor, false ); - } - } - return pEntry; -} - -tools::Rectangle SvImpLBox::GetClipRegionRect() const -{ - Point aOrigin( pView->GetMapMode().GetOrigin() ); - aOrigin.setX( aOrigin.X() * -1 ); // conversion document coordinates - tools::Rectangle aClipRect( aOrigin, aOutputSize ); - aClipRect.AdjustBottom( 1 ); - return aClipRect; -} - - -void SvImpLBox::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) -{ - if (!pView->GetVisibleCount()) - return; - - nFlags |= LBoxFlags::InPaint; - - if (nFlags & LBoxFlags::Filling) - { - SvTreeListEntry* pFirst = pView->First(); - if (pFirst != pStartEntry) - { - ShowCursor(false); - pStartEntry = pView->First(); - aVerSBar->SetThumbPos( 0 ); - StopUserEvent(); - ShowCursor(true); - nCurUserEvent = Application::PostUserEvent(LINK(this, SvImpLBox, MyUserEvent), - reinterpret_cast<void*>(1)); - return; - } - } - - if (!pStartEntry) - { - pStartEntry = pView->First(); - } - - if (nNodeBmpTabDistance == NODE_BMP_TABDIST_NOTVALID) - SetNodeBmpTabDistance(); - - long nRectHeight = rRect.GetHeight(); - long nEntryHeight = pView->GetEntryHeight(); - - // calculate area for the entries we want to draw - sal_uInt16 nStartLine = static_cast<sal_uInt16>(rRect.Top() / nEntryHeight); - sal_uInt16 nCount = static_cast<sal_uInt16>(nRectHeight / nEntryHeight); - nCount += 2; // don't miss a row - - long nY = nStartLine * nEntryHeight; - SvTreeListEntry* pEntry = pStartEntry; - while (nStartLine && pEntry) - { - pEntry = pView->NextVisible(pEntry); - nStartLine--; - } - - vcl::Region aClipRegion(GetClipRegionRect()); - - // first draw the lines, then clip them! - rRenderContext.SetClipRegion(); - if (m_nStyle & (WB_HASLINES | WB_HASLINESATROOT)) - DrawNet(rRenderContext); - - rRenderContext.SetClipRegion(aClipRegion); - - if (!pCursor && !mbNoAutoCurEntry) - { - // do not select if multiselection or explicit set - bool bNotSelect = (aSelEng.GetSelectionMode() == SelectionMode::Multiple ) || ((m_nStyle & WB_NOINITIALSELECTION) == WB_NOINITIALSELECTION); - SetCursor(pStartEntry, bNotSelect); - } - - for(sal_uInt16 n=0; n< nCount && pEntry; n++) - { - /*long nMaxRight=*/ - pView->PaintEntry1(*pEntry, nY, rRenderContext ); - nY += nEntryHeight; - pEntry = pView->NextVisible(pEntry); - } - - nFlags &= (~LBoxFlags::DeselectAll); - rRenderContext.SetClipRegion(); - nFlags &= (~LBoxFlags::InPaint); -} - -void SvImpLBox::MakeVisible( SvTreeListEntry* pEntry, bool bMoveToTop ) -{ - if( !pEntry ) - return; - - bool bInView = IsEntryInView( pEntry ); - - if( bInView && (!bMoveToTop || pStartEntry == pEntry) ) - return; // is already visible - - if( pStartEntry || mbForceMakeVisible ) - nFlags &= (~LBoxFlags::Filling); - if( !bInView ) - { - if( !pView->IsEntryVisible(pEntry) ) // Parent(s) collapsed? - { - SvTreeListEntry* pParent = pView->GetParent( pEntry ); - while( pParent ) - { - if( !pView->IsExpanded( pParent ) ) - { - bool bRet = pView->Expand( pParent ); - DBG_ASSERT(bRet,"Not expanded!"); - } - pParent = pView->GetParent( pParent ); - } - // do the parent's children fit into the view or do we have to scroll? - if( IsEntryInView( pEntry ) && !bMoveToTop ) - return; // no need to scroll - } - } - - pStartEntry = pEntry; - ShowCursor( false ); - FillView(); - aVerSBar->SetThumbPos( static_cast<long>(pView->GetVisiblePos( pStartEntry )) ); - ShowCursor( true ); - pView->Invalidate(); -} - -void SvImpLBox::ScrollToAbsPos( long nPos ) -{ - if( pView->GetVisibleCount() == 0 ) - return; - long nLastEntryPos = pView->GetAbsPos( pView->Last() ); - - if( nPos < 0 ) - nPos = 0; - else if( nPos > nLastEntryPos ) - nPos = nLastEntryPos; - - SvTreeListEntry* pEntry = pView->GetEntryAtAbsPos( nPos ); - if( !pEntry || pEntry == pStartEntry ) - return; - - if( pStartEntry || mbForceMakeVisible ) - nFlags &= (~LBoxFlags::Filling); - - if( pView->IsEntryVisible(pEntry) ) - { - pStartEntry = pEntry; - ShowCursor( false ); - aVerSBar->SetThumbPos( nPos ); - ShowCursor( true ); - if (GetUpdateMode()) - pView->Invalidate(); - } -} - -void SvImpLBox::DrawNet(vcl::RenderContext& rRenderContext) -{ - if (pView->GetVisibleCount() < 2 && !pStartEntry->HasChildrenOnDemand() && - !pStartEntry->HasChildren()) - { - return; - } - - // for platforms that don't have nets, DrawNativeControl does nothing and returns true - // so that SvImpLBox::DrawNet() doesn't draw anything either - if (rRenderContext.IsNativeControlSupported(ControlType::ListNet, ControlPart::Entire)) - { - ImplControlValue aControlValue; - if (rRenderContext.DrawNativeControl(ControlType::ListNet, ControlPart::Entire, - tools::Rectangle(), ControlState::ENABLED, aControlValue, OUString())) - { - return; - } - } - - long nEntryHeight = pView->GetEntryHeight(); - long nEntryHeightDIV2 = nEntryHeight / 2; - if( nEntryHeightDIV2 && !(nEntryHeight & 0x0001)) - nEntryHeightDIV2--; - - SvTreeListEntry* pChild; - SvTreeListEntry* pEntry = pStartEntry; - - SvLBoxTab* pFirstDynamicTab = pView->GetFirstDynamicTab(); - while (pTree->GetDepth( pEntry ) > 0) - { - pEntry = pView->GetParent(pEntry); - } - sal_uInt16 nOffs = static_cast<sal_uInt16>(pView->GetVisiblePos(pStartEntry) - pView->GetVisiblePos(pEntry)); - long nY = 0; - nY -= (nOffs * nEntryHeight); - - DBG_ASSERT(pFirstDynamicTab,"No Tree!"); - - rRenderContext.Push(PushFlags::LINECOLOR); - - const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings(); - Color aCol = rStyleSettings.GetFaceColor(); - - if (aCol.IsRGBEqual(rRenderContext.GetBackground().GetColor())) - aCol = rStyleSettings.GetShadowColor(); - rRenderContext.SetLineColor(aCol); - Point aPos1, aPos2; - sal_uInt16 nDistance; - sal_uLong nMax = nVisibleCount + nOffs + 1; - - const Image& rExpandedNodeBitmap = GetExpandedNodeBmp(); - - for (sal_uLong n=0; n< nMax && pEntry; n++) - { - if (pView->IsExpanded(pEntry)) - { - aPos1.setX( pView->GetTabPos(pEntry, pFirstDynamicTab) ); - // if it is not a context bitmap, go a little to the right below the - // first text (node bitmap, too) - if (!pView->nContextBmpWidthMax) - aPos1.AdjustX(rExpandedNodeBitmap.GetSizePixel().Width() / 2 ); - - aPos1.setY( nY ); - aPos1.AdjustY(nEntryHeightDIV2 ); - - pChild = pView->FirstChild( pEntry ); - assert(pChild && "Child?"); - pChild = pChild->LastSibling(); - nDistance = static_cast<sal_uInt16>(pView->GetVisiblePos(pChild) - pView->GetVisiblePos(pEntry)); - aPos2 = aPos1; - aPos2.AdjustY(nDistance * nEntryHeight ); - rRenderContext.DrawLine(aPos1, aPos2); - } - // visible in control? - if (n >= nOffs && ((m_nStyle & WB_HASLINESATROOT) || !pTree->IsAtRootDepth(pEntry))) - { - // can we recycle aPos1? - if (!pView->IsExpanded(pEntry)) - { - // nope - aPos1.setX( pView->GetTabPos(pEntry, pFirstDynamicTab) ); - // if it is not a context bitmap, go a little to the right below - // the first text (node bitmap, too) - if (!pView->nContextBmpWidthMax) - aPos1.AdjustX(rExpandedNodeBitmap.GetSizePixel().Width() / 2 ); - aPos1.setY( nY ); - aPos1.AdjustY(nEntryHeightDIV2 ); - aPos2.setX( aPos1.X() ); - } - aPos2.setY( aPos1.Y() ); - aPos2.AdjustX( -(pView->GetIndent()) ); - rRenderContext.DrawLine(aPos1, aPos2); - } - nY += nEntryHeight; - pEntry = pView->NextVisible(pEntry); - } - if (m_nStyle & WB_HASLINESATROOT) - { - pEntry = pView->First(); - aPos1.setX( pView->GetTabPos(pEntry, pFirstDynamicTab) ); - // if it is not a context bitmap, go a little to the right below the - // first text (node bitmap, too) - if (!pView->nContextBmpWidthMax) - aPos1.AdjustX(rExpandedNodeBitmap.GetSizePixel().Width() / 2 ); - aPos1.AdjustX( -(pView->GetIndent()) ); - aPos1.setY( GetEntryLine( pEntry ) ); - aPos1.AdjustY(nEntryHeightDIV2 ); - pChild = pEntry->LastSibling(); - aPos2.setX( aPos1.X() ); - aPos2.setY( GetEntryLine( pChild ) ); - aPos2.AdjustY(nEntryHeightDIV2 ); - rRenderContext.DrawLine(aPos1, aPos2); - } - rRenderContext.Pop(); -} - -void SvImpLBox::PositionScrollBars( Size& rSize, sal_uInt16 nMask ) -{ - long nOverlap = 0; - - Size aVerSize( nVerSBarWidth, rSize.Height() ); - Size aHorSize( rSize.Width(), nHorSBarHeight ); - - if( nMask & 0x0001 ) - aHorSize.AdjustWidth( -(nVerSBarWidth) ); - if( nMask & 0x0002 ) - aVerSize.AdjustHeight( -(nHorSBarHeight) ); - - aVerSize.AdjustHeight(2 * nOverlap ); - Point aVerPos( rSize.Width() - aVerSize.Width() + nOverlap, -nOverlap ); - aVerSBar->SetPosSizePixel( aVerPos, aVerSize ); - - aHorSize.AdjustWidth(2 * nOverlap ); - Point aHorPos( -nOverlap, rSize.Height() - aHorSize.Height() + nOverlap ); - - aHorSBar->SetPosSizePixel( aHorPos, aHorSize ); - - if( nMask & 0x0001 ) - rSize.setWidth( aVerPos.X() ); - if( nMask & 0x0002 ) - rSize.setHeight( aHorPos.Y() ); - - if( (nMask & (0x0001|0x0002)) == (0x0001|0x0002) ) - aScrBarBox->Show(); - else - aScrBarBox->Hide(); -} - -void SvImpLBox::AdjustScrollBars( Size& rSize ) -{ - long nEntryHeight = pView->GetEntryHeight(); - if( !nEntryHeight ) - return; - - sal_uInt16 nResult = 0; - - Size aOSize( pView->Control::GetOutputSizePixel() ); - - const WinBits nWindowStyle = pView->GetStyle(); - bool bVerSBar = ( nWindowStyle & WB_VSCROLL ) != 0; - bool bHorBar = false; - long nMaxRight = aOSize.Width(); //GetOutputSize().Width(); - Point aOrigin( pView->GetMapMode().GetOrigin() ); - aOrigin.setX( aOrigin.X() * -1 ); - nMaxRight += aOrigin.X() - 1; - long nVis = nMostRight - aOrigin.X(); - if( (nWindowStyle & WB_HSCROLL) && - (nVis < nMostRight || nMaxRight < nMostRight) ) - { - bHorBar = true; - } - - // number of entries that are not collapsed - sal_uLong nTotalCount = pView->GetVisibleCount(); - - // number of entries visible within the view - nVisibleCount = aOSize.Height() / nEntryHeight; - - // do we need a vertical scrollbar? - if( bVerSBar || nTotalCount > nVisibleCount ) - { - nResult = 1; - nMaxRight -= nVerSBarWidth; - if( !bHorBar ) - { - if( (nWindowStyle & WB_HSCROLL) && - (nVis < nMostRight || nMaxRight < nMostRight) ) - bHorBar = true; - } - } - - // do we need a horizontal scrollbar? - if( bHorBar ) - { - nResult |= 0x0002; - // the number of entries visible within the view has to be recalculated - // because the horizontal scrollbar is now visible. - nVisibleCount = (aOSize.Height() - nHorSBarHeight) / nEntryHeight; - // we might actually need a vertical scrollbar now - if( !(nResult & 0x0001) && - ((nTotalCount > nVisibleCount) || bVerSBar) ) - { - nResult = 3; - } - } - - PositionScrollBars( aOSize, nResult ); - - // adapt Range, VisibleRange etc. - - // refresh output size, in case we have to scroll - tools::Rectangle aRect; - aRect.SetSize( aOSize ); - aSelEng.SetVisibleArea( aRect ); - - // vertical scrollbar - long nTemp = static_cast<long>(nVisibleCount); - nTemp--; - if( nTemp != aVerSBar->GetVisibleSize() ) - { - if( !bInVScrollHdl ) - { - aVerSBar->SetPageSize( nTemp - 1 ); - aVerSBar->SetVisibleSize( nTemp ); - } - else - { - nFlags |= LBoxFlags::EndScrollSetVisSize; - nNextVerVisSize = nTemp; - } - } - - // horizontal scrollbar - nTemp = aHorSBar->GetThumbPos(); - aHorSBar->SetVisibleSize( aOSize.Width() ); - long nNewThumbPos = aHorSBar->GetThumbPos(); - Range aRange( aHorSBar->GetRange() ); - if( aRange.Max() < nMostRight+25 ) - { - aRange.Max() = nMostRight+25; - aHorSBar->SetRange( aRange ); - } - - if( nTemp != nNewThumbPos ) - { - nTemp = nNewThumbPos - nTemp; - if( pView->IsEditingActive() ) - { - pView->EndEditing( true ); // Cancel - pView->Update(); - } - pView->nFocusWidth = -1; - KeyLeftRight( nTemp ); - } - - if( nResult & 0x0001 ) - aVerSBar->Show(); - else - aVerSBar->Hide(); - - if( nResult & 0x0002 ) - aHorSBar->Show(); - else - { - aHorSBar->Hide(); - } - rSize = aOSize; -} - -void SvImpLBox::InitScrollBarBox() -{ - aScrBarBox->SetSizePixel( Size(nVerSBarWidth, nHorSBarHeight) ); - Size aSize( pView->Control::GetOutputSizePixel() ); - aScrBarBox->SetPosPixel( Point(aSize.Width()-nVerSBarWidth, aSize.Height()-nHorSBarHeight)); -} - -void SvImpLBox::Resize() -{ - aOutputSize = pView->Control::GetOutputSizePixel(); - if( aOutputSize.Width() <= 0 || aOutputSize.Height() <= 0 ) - return; - nFlags |= LBoxFlags::InResize; - InitScrollBarBox(); - - if( pView->GetEntryHeight()) - { - AdjustScrollBars( aOutputSize ); - UpdateAll(false); - } - // HACK, as in floating and docked windows the scrollbars might not be drawn - // correctly/not be drawn at all after resizing! - if( aHorSBar->IsVisible()) - aHorSBar->Invalidate(); - if( aVerSBar->IsVisible()) - aVerSBar->Invalidate(); - nFlags &= ~LBoxFlags::InResize; -} - -void SvImpLBox::FillView() -{ - if( !pStartEntry ) - { - sal_uLong nVisibleViewCount = pView->GetVisibleCount(); - long nTempThumb = aVerSBar->GetThumbPos(); - if( nTempThumb < 0 ) - nTempThumb = 0; - else if( static_cast<unsigned long>(nTempThumb) >= nVisibleViewCount ) - nTempThumb = nVisibleViewCount == 0 ? 0 : nVisibleViewCount - 1; - pStartEntry = pView->GetEntryAtVisPos(nTempThumb); - } - if( !pStartEntry ) - return; - - sal_uInt16 nLast = static_cast<sal_uInt16>(pView->GetVisiblePos(pView->LastVisible())); - sal_uInt16 nThumb = static_cast<sal_uInt16>(pView->GetVisiblePos( pStartEntry )); - sal_uLong nCurDispEntries = nLast-nThumb+1; - if( nCurDispEntries >= nVisibleCount ) - return; - - ShowCursor( false ); - // fill window by moving the thumb up incrementally - bool bFound = false; - SvTreeListEntry* pTemp = pStartEntry; - while( nCurDispEntries < nVisibleCount && pTemp ) - { - pTemp = pView->PrevVisible(pStartEntry); - if( pTemp ) - { - nThumb--; - pStartEntry = pTemp; - nCurDispEntries++; - bFound = true; - } - } - if( bFound ) - { - aVerSBar->SetThumbPos( nThumb ); - ShowCursor( true ); // recalculate focus rectangle - pView->Invalidate(); - } -} - - -void SvImpLBox::ShowVerSBar() -{ - bool bVerBar = ( pView->GetStyle() & WB_VSCROLL ) != 0; - sal_uLong nVis = 0; - if( !bVerBar ) - nVis = pView->GetVisibleCount(); - if( bVerBar || (nVisibleCount && nVis > static_cast<sal_uLong>(nVisibleCount-1)) ) - { - if( !aVerSBar->IsVisible() ) - { - pView->nFocusWidth = -1; - AdjustScrollBars( aOutputSize ); - if( GetUpdateMode() ) - aVerSBar->Update(); - } - } - else - { - if( aVerSBar->IsVisible() ) - { - pView->nFocusWidth = -1; - AdjustScrollBars( aOutputSize ); - } - } - - long nMaxRight = GetOutputSize().Width(); - Point aPos( pView->GetMapMode().GetOrigin() ); - aPos.setX( aPos.X() * -1 ); // convert document coordinates - nMaxRight = nMaxRight + aPos.X() - 1; - if( nMaxRight < nMostRight ) - { - if( !aHorSBar->IsVisible() ) - { - pView->nFocusWidth = -1; - AdjustScrollBars( aOutputSize ); - if( GetUpdateMode() ) - aHorSBar->Update(); - } - else - { - Range aRange( aHorSBar->GetRange() ); - if( aRange.Max() < nMostRight+25 ) - { - aRange.Max() = nMostRight+25; - aHorSBar->SetRange( aRange ); - } - else - { - pView->nFocusWidth = -1; - AdjustScrollBars( aOutputSize ); - } - } - } - else - { - if( aHorSBar->IsVisible() ) - { - pView->nFocusWidth = -1; - AdjustScrollBars( aOutputSize ); - } - } -} - - -void SvImpLBox::SyncVerThumb() -{ - if( pStartEntry ) - { - long nEntryPos = pView->GetVisiblePos( pStartEntry ); - aVerSBar->SetThumbPos( nEntryPos ); - } - else - aVerSBar->SetThumbPos( 0 ); -} - -bool SvImpLBox::IsEntryInView( SvTreeListEntry* pEntry ) const -{ - // parent collapsed - if( !pView->IsEntryVisible(pEntry) ) - return false; - long nY = GetEntryLine( pEntry ); - if( nY < 0 ) - return false; - long nMax = nVisibleCount * pView->GetEntryHeight(); - return nY < nMax; -} - - -long SvImpLBox::GetEntryLine( SvTreeListEntry* pEntry ) const -{ - if(!pStartEntry ) - return -1; // invisible position - - long nFirstVisPos = pView->GetVisiblePos( pStartEntry ); - long nEntryVisPos = pView->GetVisiblePos( pEntry ); - nFirstVisPos = nEntryVisPos - nFirstVisPos; - nFirstVisPos *= pView->GetEntryHeight(); - return nFirstVisPos; -} - -void SvImpLBox::SetEntryHeight() -{ - SetNodeBmpWidth( GetExpandedNodeBmp() ); - SetNodeBmpWidth( GetCollapsedNodeBmp() ); - if(!pView->HasViewData()) // are we within the Clear? - { - Size aSize = pView->Control::GetOutputSizePixel(); - AdjustScrollBars( aSize ); - } - else - { - Resize(); - if( GetUpdateMode() ) - pView->Invalidate(); - } -} - - -// *********************************************************************** -// Callback Functions -// *********************************************************************** - -void SvImpLBox::EntryExpanded( SvTreeListEntry* pEntry ) -{ - // SelAllDestrAnch( false, true ); //DeselectAll(); - if( !GetUpdateMode() ) - return; - - ShowCursor( false ); - long nY = GetEntryLine( pEntry ); - if( IsLineVisible(nY) ) - { - InvalidateEntriesFrom( nY ); - FindMostRight( pEntry, nullptr ); - } - aVerSBar->SetRange( Range(0, pView->GetVisibleCount()-1 ) ); - // if we expanded before the thumb, the thumb's position has to be - // corrected - SyncVerThumb(); - ShowVerSBar(); - ShowCursor( true ); -} - -void SvImpLBox::EntryCollapsed( SvTreeListEntry* pEntry ) -{ - if( !pView->IsEntryVisible( pEntry ) ) - return; - - ShowCursor( false ); - - if( !pMostRightEntry || pTree->IsChild( pEntry,pMostRightEntry ) ) - { - FindMostRight(nullptr); - } - - if( pStartEntry ) - { - long nOldThumbPos = aVerSBar->GetThumbPos(); - sal_uLong nVisList = pView->GetVisibleCount(); - aVerSBar->SetRange( Range(0, nVisList-1) ); - long nNewThumbPos = aVerSBar->GetThumbPos(); - if( nNewThumbPos != nOldThumbPos ) - { - pStartEntry = pView->First(); - sal_uInt16 nDistance = static_cast<sal_uInt16>(nNewThumbPos); - if( nDistance ) - pStartEntry = pView->NextVisible(pStartEntry, nDistance); - if( GetUpdateMode() ) - pView->Invalidate(); - } - else - SyncVerThumb(); - ShowVerSBar(); - } - // has the cursor been collapsed? - if( pTree->IsChild( pEntry, pCursor ) ) - SetCursor( pEntry ); - if( GetUpdateMode() ) - ShowVerSBar(); - ShowCursor( true ); - if( GetUpdateMode() && pCursor ) - pView->Select( pCursor ); -} - -void SvImpLBox::CollapsingEntry( SvTreeListEntry* pEntry ) -{ - if( !pView->IsEntryVisible( pEntry ) || !pStartEntry ) - return; - - SelAllDestrAnch( false ); // deselect all - - // is the collapsed cursor visible? - long nY = GetEntryLine( pEntry ); - if( IsLineVisible(nY) ) - { - if( GetUpdateMode() ) - InvalidateEntriesFrom( nY ); - } - else - { - if( pTree->IsChild(pEntry, pStartEntry) ) - { - pStartEntry = pEntry; - if( GetUpdateMode() ) - pView->Invalidate(); - } - } -} - - -void SvImpLBox::SetNodeBmpWidth( const Image& rBmp ) -{ - const Size aSize( rBmp.GetSizePixel() ); - nNodeBmpWidth = aSize.Width(); -} - -void SvImpLBox::SetNodeBmpTabDistance() -{ - nNodeBmpTabDistance = -pView->GetIndent(); - if( pView->nContextBmpWidthMax ) - { - // only if the first dynamic tab is centered (we currently assume that) - Size aSize = GetExpandedNodeBmp().GetSizePixel(); - nNodeBmpTabDistance -= aSize.Width() / 2; - } -} - - -// corrects the cursor when using SingleSelection - -void SvImpLBox::EntrySelected( SvTreeListEntry* pEntry, bool bSelect ) -{ - if( nFlags & LBoxFlags::IgnoreSelect ) - return; - - nFlags &= (~LBoxFlags::DeselectAll); - if( bSelect && - aSelEng.GetSelectionMode() == SelectionMode::Single && - pEntry != pCursor ) - { - SetCursor( pEntry ); - DBG_ASSERT(pView->GetSelectionCount()==1,"selection count?"); - } - - if( GetUpdateMode() && pView->IsEntryVisible(pEntry) ) - { - long nY = GetEntryLine( pEntry ); - if( IsLineVisible( nY ) ) - { - ShowCursor(false); - InvalidateEntry(pEntry); - ShowCursor(true); - } - } -} - - -void SvImpLBox::RemovingEntry( SvTreeListEntry* pEntry ) -{ - CallEventListeners( VclEventId::ListboxItemRemoved , pEntry ); - - DestroyAnchor(); - - if( !pView->IsEntryVisible( pEntry ) ) - { - // if parent is collapsed => bye! - nFlags |= LBoxFlags::RemovedEntryInvisible; - return; - } - - if( pEntry == pMostRightEntry || ( - pEntry->HasChildren() && pView->IsExpanded(pEntry) && - pTree->IsChild(pEntry, pMostRightEntry))) - { - nFlags |= LBoxFlags::RemovedRecalcMostRight; - } - - SvTreeListEntry* pOldStartEntry = pStartEntry; - - SvTreeListEntry* pParent = pView->GetModel()->GetParent(pEntry); - - if (pParent && pView->GetModel()->GetChildList(pParent).size() == 1) - { - DBG_ASSERT( pView->IsExpanded( pParent ), "Parent not expanded"); - pParent->SetFlags( pParent->GetFlags() | SvTLEntryFlags::NO_NODEBMP); - InvalidateEntry( pParent ); - } - - if( pCursor && pTree->IsChild( pEntry, pCursor) ) - pCursor = pEntry; - if( pStartEntry && pTree->IsChild(pEntry,pStartEntry) ) - pStartEntry = pEntry; - - SvTreeListEntry* pTemp; - if( pCursor && pCursor == pEntry ) - { - if( bSimpleTravel ) - pView->Select( pCursor, false ); - ShowCursor( false ); // focus rectangle gone - // NextSibling, because we also delete the children of the cursor - pTemp = pCursor->NextSibling(); - if( !pTemp ) - pTemp = pView->PrevVisible(pCursor); - - SetCursor( pTemp, true ); - } - if( pStartEntry && pStartEntry == pEntry ) - { - pTemp = pStartEntry->NextSibling(); - if( !pTemp ) - pTemp = pView->PrevVisible(pStartEntry); - pStartEntry = pTemp; - } - if( GetUpdateMode()) - { - // if it is the last one, we have to invalidate it, so the lines are - // drawn correctly (in this case they're deleted) - if( pStartEntry && (pStartEntry != pOldStartEntry || pEntry == pView->GetModel()->Last()) ) - { - aVerSBar->SetThumbPos( pView->GetVisiblePos( pStartEntry )); - pView->Invalidate( GetVisibleArea() ); - } - else - InvalidateEntriesFrom( GetEntryLine( pEntry ) ); - } -} - -void SvImpLBox::EntryRemoved() -{ - if( nFlags & LBoxFlags::RemovedEntryInvisible ) - { - nFlags &= (~LBoxFlags::RemovedEntryInvisible); - return; - } - if( !pStartEntry ) - pStartEntry = pTree->First(); - if( !pCursor ) - SetCursor( pStartEntry, true ); - - if( pCursor && (bSimpleTravel || !pView->GetSelectionCount() )) - pView->Select( pCursor ); - - if( GetUpdateMode()) - { - if( nFlags & LBoxFlags::RemovedRecalcMostRight ) - FindMostRight(nullptr); - aVerSBar->SetRange( Range(0, pView->GetVisibleCount()-1 ) ); - FillView(); - if( pStartEntry ) - // if something above the thumb was deleted - aVerSBar->SetThumbPos( pView->GetVisiblePos( pStartEntry) ); - - ShowVerSBar(); - if( pCursor && pView->HasFocus() && !pView->IsSelected(pCursor) ) - { - if( pView->GetSelectionCount() ) - { - // is a neighboring entry selected? - SvTreeListEntry* pNextCursor = pView->PrevVisible( pCursor ); - if( !pNextCursor || !pView->IsSelected( pNextCursor )) - pNextCursor = pView->NextVisible( pCursor ); - if( !pNextCursor || !pView->IsSelected( pNextCursor )) - // no neighbor selected: use first selected - pNextCursor = pView->FirstSelected(); - SetCursor( pNextCursor ); - MakeVisible( pCursor ); - } - else - pView->Select( pCursor ); - } - ShowCursor( true ); - } - nFlags &= (~LBoxFlags::RemovedRecalcMostRight); -} - - -void SvImpLBox::MovingEntry( SvTreeListEntry* pEntry ) -{ - bool bDeselAll(nFlags & LBoxFlags::DeselectAll); - SelAllDestrAnch( false ); // DeselectAll(); - if( !bDeselAll ) - nFlags &= (~LBoxFlags::DeselectAll); - - if( pEntry == pCursor ) - ShowCursor( false ); - if( IsEntryInView( pEntry ) ) - pView->Invalidate(); - if( pEntry != pStartEntry ) - return; - - SvTreeListEntry* pNew = nullptr; - if( !pEntry->HasChildren() ) - { - pNew = pView->NextVisible(pStartEntry); - if( !pNew ) - pNew = pView->PrevVisible(pStartEntry); - } - else - { - pNew = pEntry->NextSibling(); - if( !pNew ) - pNew = pEntry->PrevSibling(); - } - pStartEntry = pNew; -} - -void SvImpLBox::EntryMoved( SvTreeListEntry* pEntry ) -{ - UpdateContextBmpWidthVectorFromMovedEntry( pEntry ); - - if ( !pStartEntry ) - // this might happen if the only entry in the view is moved to its very same position - // #i97346# - pStartEntry = pView->First(); - - aVerSBar->SetRange( Range(0, pView->GetVisibleCount()-1)); - sal_uInt16 nFirstPos = static_cast<sal_uInt16>(pTree->GetAbsPos( pStartEntry )); - sal_uInt16 nNewPos = static_cast<sal_uInt16>(pTree->GetAbsPos( pEntry )); - FindMostRight(nullptr); - if( nNewPos < nFirstPos ) // HACK! - pStartEntry = pEntry; - SyncVerThumb(); - if( pEntry == pCursor ) - { - if( pView->IsEntryVisible( pCursor ) ) - ShowCursor( true ); - else - { - SvTreeListEntry* pParent = pEntry; - do { - pParent = pTree->GetParent( pParent ); - } - while( !pView->IsEntryVisible( pParent ) ); - SetCursor( pParent ); - } - } - if( IsEntryInView( pEntry ) ) - pView->Invalidate(); -} - - -void SvImpLBox::EntryInserted( SvTreeListEntry* pEntry ) -{ - if( !GetUpdateMode() ) - return; - - SvTreeListEntry* pParent = pTree->GetParent(pEntry); - if (pParent && pTree->GetChildList(pParent).size() == 1) - // draw plus sign - pTree->InvalidateEntry( pParent ); - - if( !pView->IsEntryVisible( pEntry ) ) - return; - bool bDeselAll(nFlags & LBoxFlags::DeselectAll); - if( bDeselAll ) - SelAllDestrAnch( false ); - else - DestroyAnchor(); - // nFlags &= (~LBoxFlags::DeselectAll); -// ShowCursor( false ); // if cursor is moved lower - long nY = GetEntryLine( pEntry ); - bool bEntryVisible = IsLineVisible( nY ); - if( bEntryVisible ) - { - ShowCursor( false ); // if cursor is moved lower - nY -= pView->GetEntryHeight(); // because of lines - InvalidateEntriesFrom( nY ); - } - else if( pStartEntry && nY < GetEntryLine(pStartEntry) ) - { - // Check if the view is filled completely. If not, then adjust - // pStartEntry and the Cursor (automatic scrolling). - sal_uInt16 nLast = static_cast<sal_uInt16>(pView->GetVisiblePos(pView->LastVisible())); - sal_uInt16 nThumb = static_cast<sal_uInt16>(pView->GetVisiblePos( pStartEntry )); - sal_uInt16 nCurDispEntries = nLast-nThumb+1; - if( nCurDispEntries < nVisibleCount ) - { - // set at the next paint event - pStartEntry = nullptr; - SetCursor( nullptr ); - pView->Invalidate(); - } - } - else if( !pStartEntry ) - pView->Invalidate(); - - SetMostRight( pEntry ); - aVerSBar->SetRange( Range(0, pView->GetVisibleCount()-1)); - SyncVerThumb(); // if something was inserted before the thumb - ShowVerSBar(); - ShowCursor( true ); - if( pStartEntry != pView->First() && (nFlags & LBoxFlags::Filling) ) - pView->Update(); -} - - -// ******************************************************************** -// Event handler -// ******************************************************************** - - -// ****** Control the control animation - -bool SvImpLBox::ButtonDownCheckCtrl(const MouseEvent& rMEvt, SvTreeListEntry* pEntry) -{ - SvLBoxItem* pItem = pView->GetItem(pEntry,rMEvt.GetPosPixel().X(),&pActiveTab); - if (pItem && pItem->GetType() == SvLBoxItemType::Button) - { - pActiveButton = static_cast<SvLBoxButton*>(pItem); - pActiveEntry = pEntry; - if( pCursor == pActiveEntry ) - pView->HideFocus(); - pView->CaptureMouse(); - pActiveButton->SetStateHilighted( true ); - InvalidateEntry(pActiveEntry); - return true; - } - else - pActiveButton = nullptr; - return false; -} - -bool SvImpLBox::MouseMoveCheckCtrl(const MouseEvent& rMEvt, SvTreeListEntry const * pEntry) -{ - if( pActiveButton ) - { - long nMouseX = rMEvt.GetPosPixel().X(); - if( pEntry == pActiveEntry && - pView->GetItem(pActiveEntry, nMouseX) == pActiveButton ) - { - if( !pActiveButton->IsStateHilighted() ) - { - pActiveButton->SetStateHilighted(true ); - InvalidateEntry(pActiveEntry); - } - } - else - { - if( pActiveButton->IsStateHilighted() ) - { - pActiveButton->SetStateHilighted(false ); - InvalidateEntry(pActiveEntry); - } - } - return true; - } - return false; -} - -bool SvImpLBox::ButtonUpCheckCtrl( const MouseEvent& rMEvt ) -{ - if( pActiveButton ) - { - pView->ReleaseMouse(); - SvTreeListEntry* pEntry = GetClickedEntry( rMEvt.GetPosPixel() ); - pActiveButton->SetStateHilighted( false ); - long nMouseX = rMEvt.GetPosPixel().X(); - if (pEntry == pActiveEntry && pView->GetItem(pActiveEntry, nMouseX) == pActiveButton) - pActiveButton->ClickHdl(pActiveEntry); - InvalidateEntry(pActiveEntry); - if (pCursor == pActiveEntry) - ShowCursor(true); - pActiveButton = nullptr; - pActiveEntry = nullptr; - pActiveTab = nullptr; - return true; - } - return false; -} - -// ******* Control plus/minus button for expanding/collapsing - -// false == no expand/collapse button hit -bool SvImpLBox::IsNodeButton( const Point& rPosPixel, SvTreeListEntry* pEntry ) const -{ - if( !pEntry->HasChildren() && !pEntry->HasChildrenOnDemand() ) - return false; - - SvLBoxTab* pFirstDynamicTab = pView->GetFirstDynamicTab(); - if( !pFirstDynamicTab ) - return false; - - long nMouseX = rPosPixel.X(); - // convert to document coordinates - Point aOrigin( pView->GetMapMode().GetOrigin() ); - nMouseX -= aOrigin.X(); - - long nX = pView->GetTabPos( pEntry, pFirstDynamicTab); - nX += nNodeBmpTabDistance; - if( nMouseX < nX ) - return false; - nX += nNodeBmpWidth; - return nMouseX <= nX; -} - -// false == hit no node button -bool SvImpLBox::ButtonDownCheckExpand( const MouseEvent& rMEvt, SvTreeListEntry* pEntry ) -{ - bool bRet = false; - - if ( pView->IsEditingActive() && pEntry == pView->pEdEntry ) - // inplace editing -> nothing to do - bRet = true; - else if ( IsNodeButton( rMEvt.GetPosPixel(), pEntry ) ) - { - if ( pView->IsExpanded( pEntry ) ) - { - pView->EndEditing( true ); - pView->Collapse( pEntry ); - } - else - { - // you can expand an entry, which is in editing - pView->Expand( pEntry ); - } - bRet = true; - } - - return bRet; -} - -void SvImpLBox::MouseButtonDown( const MouseEvent& rMEvt ) -{ - if ( !rMEvt.IsLeft() && !rMEvt.IsRight()) - return; - - aEditIdle.Stop(); - Point aPos( rMEvt.GetPosPixel()); - - if( aPos.X() > aOutputSize.Width() || aPos.Y() > aOutputSize.Height() ) - return; - - SvTreeListEntry* pEntry = GetEntry( aPos ); - if ( pEntry != pCursor ) - // new entry selected -> reset current tab position to first tab - nCurTabPos = FIRST_ENTRY_TAB; - nFlags &= (~LBoxFlags::Filling); - pView->GrabFocus(); - //fdo#82270 Grabbing focus can invalidate the entries, re-fetch - pEntry = GetEntry(aPos); - // the entry can still be invalid! - if( !pEntry || !pView->GetViewData( pEntry )) - return; - - long nY = GetEntryLine( pEntry ); - // Node-Button? - if( ButtonDownCheckExpand( rMEvt, pEntry ) ) - return; - - if( !EntryReallyHit(pEntry,aPos,nY)) - return; - - SvLBoxItem* pXItem = pView->GetItem( pEntry, aPos.X() ); - if( pXItem ) - { - SvLBoxTab* pXTab = pView->GetTab( pEntry, pXItem ); - if ( !rMEvt.IsMod1() && !rMEvt.IsMod2() && rMEvt.IsLeft() && pXTab->IsEditable() - && pEntry == pView->FirstSelected() && nullptr == pView->NextSelected( pEntry ) ) - // #i8234# FirstSelected() and NextSelected() ensures, that inplace editing is only triggered, when only one entry is selected - nFlags |= LBoxFlags::StartEditTimer; - if ( !pView->IsSelected( pEntry ) ) - nFlags &= ~LBoxFlags::StartEditTimer; - } - - - if( (rMEvt.GetClicks() % 2) == 0 ) - { - nFlags &= (~LBoxFlags::StartEditTimer); - pView->pHdlEntry = pEntry; - if( !pView->DoubleClickHdl() ) - { - // Handler signals nothing to be done anymore, bail out, 'this' may - // even be dead and destroyed. - return; - } - else - { - // if the entry was deleted within the handler - pEntry = GetClickedEntry( aPos ); - if( !pEntry ) - return; - if( pEntry != pView->pHdlEntry ) - { - // select anew & bye - if( !bSimpleTravel && !aSelEng.IsAlwaysAdding()) - SelAllDestrAnch( false ); // DeselectAll(); - SetCursor( pEntry ); - - return; - } - if( pEntry->HasChildren() || pEntry->HasChildrenOnDemand() ) - { - if( bSubLstOpDblClick ) - { - if( pView->IsExpanded(pEntry) ) - pView->Collapse( pEntry ); - else - pView->Expand( pEntry ); - } - if( pEntry == pCursor ) // only if Entryitem was clicked - // (Nodebutton is not an Entryitem!) - pView->Select( pCursor ); - return; - } - } - } - else - { - // CheckButton? (TreeListBox: Check + Info) - if( ButtonDownCheckCtrl(rMEvt, pEntry) ) - return; - // Inplace-Editing? - } - if ( aSelEng.GetSelectionMode() != SelectionMode::NONE ) - aSelEng.SelMouseButtonDown( rMEvt ); -} - -void SvImpLBox::MouseButtonUp( const MouseEvent& rMEvt) -{ - if ( !ButtonUpCheckCtrl( rMEvt ) && ( aSelEng.GetSelectionMode() != SelectionMode::NONE ) ) - aSelEng.SelMouseButtonUp( rMEvt ); - EndScroll(); - if( nFlags & LBoxFlags::StartEditTimer ) - { - nFlags &= (~LBoxFlags::StartEditTimer); - aEditClickPos = rMEvt.GetPosPixel(); - aEditIdle.Start(); - } -} - -void SvImpLBox::MouseMove( const MouseEvent& rMEvt) -{ - SvTreeListEntry* pEntry = GetClickedEntry( rMEvt.GetPosPixel() ); - if ( !MouseMoveCheckCtrl( rMEvt, pEntry ) && ( aSelEng.GetSelectionMode() != SelectionMode::NONE ) ) - aSelEng.SelMouseMove( rMEvt ); -} - -bool SvImpLBox::KeyInput( const KeyEvent& rKEvt) -{ - aEditIdle.Stop(); - const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode(); - - if( rKeyCode.IsMod2() ) - return false; // don't evaluate Alt key - - nFlags &= (~LBoxFlags::Filling); - - if( !pCursor ) - pCursor = pStartEntry; - if( !pCursor ) - return false; - - bool bKeyUsed = true; - - sal_uInt16 nDelta = static_cast<sal_uInt16>(aVerSBar->GetPageSize()); - sal_uInt16 aCode = rKeyCode.GetCode(); - - bool bShift = rKeyCode.IsShift(); - bool bMod1 = rKeyCode.IsMod1(); - - SvTreeListEntry* pNewCursor; - - const WinBits nWindowStyle = pView->GetStyle(); - switch( aCode ) - { - case KEY_UP: - if( !IsEntryInView( pCursor ) ) - MakeVisible( pCursor ); - - pNewCursor = pCursor; - do - { - pNewCursor = pView->PrevVisible(pNewCursor); - } while( pNewCursor && !IsSelectable(pNewCursor) ); - - if ( pNewCursor ) - // new entry selected -> reset current tab position to first tab - nCurTabPos = FIRST_ENTRY_TAB; - // if there is no next entry, take the current one - // this ensures that in case of _one_ entry in the list, this entry is selected when pressing - // the cursor key - if (!pNewCursor) - pNewCursor = pCursor; - - aSelEng.CursorPosChanging( bShift, bMod1 ); - SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on - if( !IsEntryInView( pNewCursor ) ) - KeyUp( false ); - break; - - case KEY_DOWN: - if( !IsEntryInView( pCursor ) ) - MakeVisible( pCursor ); - - pNewCursor = pCursor; - do - { - pNewCursor = pView->NextVisible(pNewCursor); - } while( pNewCursor && !IsSelectable(pNewCursor) ); - - if ( pNewCursor ) - // new entry selected -> reset current tab position to first tab - nCurTabPos = FIRST_ENTRY_TAB; - - // if there is no next entry, take the current one - // this ensures that in case of _one_ entry in the list, this entry is selected when pressing - // the cursor key - // 06.09.20001 - 83416 - frank.schoenheit@sun.com - if ( !pNewCursor && pCursor ) - pNewCursor = pCursor; - - if( pNewCursor ) - { - aSelEng.CursorPosChanging( bShift, bMod1 ); - if( IsEntryInView( pNewCursor ) ) - SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on - else - { - if( pCursor ) - pView->Select( pCursor, false ); - KeyDown( false ); - SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on - } - } - else - KeyDown( false ); // because scrollbar range might still - // allow scrolling - break; - - case KEY_RIGHT: - { - if( bSubLstOpLR ) - { - // only try to expand if sublist is expandable, - // otherwise ignore the key press - if( IsExpandable() && !pView->IsExpanded( pCursor ) ) - pView->Expand( pCursor ); - } - else if ( bIsCellFocusEnabled && pCursor ) - { - if ( nCurTabPos < ( pView->TabCount() - 1 /*!2*/ ) ) - { - ++nCurTabPos; - ShowCursor( true ); - CallEventListeners( VclEventId::ListboxSelect, pCursor ); - } - } - else if( nWindowStyle & WB_HSCROLL ) - { - long nThumb = aHorSBar->GetThumbPos(); - nThumb += aHorSBar->GetLineSize(); - long nOldThumb = aHorSBar->GetThumbPos(); - aHorSBar->SetThumbPos( nThumb ); - nThumb = nOldThumb; - nThumb -= aHorSBar->GetThumbPos(); - nThumb *= -1; - if( nThumb ) - { - KeyLeftRight( nThumb ); - EndScroll(); - } - } - else - bKeyUsed = false; - break; - } - - case KEY_LEFT: - { - if ( bIsCellFocusEnabled && pCursor ) - { - if ( nCurTabPos > FIRST_ENTRY_TAB ) - { - --nCurTabPos; - ShowCursor( true ); - CallEventListeners( VclEventId::ListboxSelect, pCursor ); - } - } - else if ( nWindowStyle & WB_HSCROLL ) - { - long nThumb = aHorSBar->GetThumbPos(); - nThumb -= aHorSBar->GetLineSize(); - long nOldThumb = aHorSBar->GetThumbPos(); - aHorSBar->SetThumbPos( nThumb ); - nThumb = nOldThumb; - nThumb -= aHorSBar->GetThumbPos(); - if( nThumb ) - { - KeyLeftRight( -nThumb ); - EndScroll(); - } - else if( bSubLstOpLR ) - { - if( IsExpandable() && pView->IsExpanded( pCursor ) ) - pView->Collapse( pCursor ); - else - { - pNewCursor = pView->GetParent( pCursor ); - if( pNewCursor ) - SetCursor( pNewCursor ); - } - } - } - else if( bSubLstOpLR ) - { - if( IsExpandable() && pView->IsExpanded( pCursor ) ) - pView->Collapse( pCursor ); - else - { - pNewCursor = pView->GetParent( pCursor ); - if( pNewCursor ) - SetCursor( pNewCursor ); - } - } - else - bKeyUsed = false; - break; - } - - case KEY_PAGEUP: - if( !bMod1 ) - { - pNewCursor = pView->PrevVisible(pCursor, nDelta); - - while( nDelta && pNewCursor && !IsSelectable(pNewCursor) ) - { - pNewCursor = pView->NextVisible(pNewCursor); - nDelta--; - } - - if( nDelta ) - { - DBG_ASSERT(pNewCursor && pNewCursor!=pCursor, "Cursor?"); - aSelEng.CursorPosChanging( bShift, bMod1 ); - if( IsEntryInView( pNewCursor ) ) - SetCursor( pNewCursor ); - else - { - SetCursor( pNewCursor ); - KeyUp( true ); - } - } - } - else - bKeyUsed = false; - break; - - case KEY_PAGEDOWN: - if( !bMod1 ) - { - pNewCursor= pView->NextVisible(pCursor, nDelta); - - while( nDelta && pNewCursor && !IsSelectable(pNewCursor) ) - { - pNewCursor = pView->PrevVisible(pNewCursor); - nDelta--; - } - - if( nDelta && pNewCursor ) - { - DBG_ASSERT(pNewCursor && pNewCursor!=pCursor, "Cursor?"); - aSelEng.CursorPosChanging( bShift, bMod1 ); - if( IsEntryInView( pNewCursor ) ) - SetCursor( pNewCursor ); - else - { - SetCursor( pNewCursor ); - KeyDown( true ); - } - } - else - KeyDown( false ); // see also: KEY_DOWN - } - else - bKeyUsed = false; - break; - - case KEY_SPACE: - if ( pView->GetSelectionMode() != SelectionMode::NONE ) - { - if ( bMod1 ) - { - if ( pView->GetSelectionMode() == SelectionMode::Multiple && !bShift ) - // toggle selection - pView->Select( pCursor, !pView->IsSelected( pCursor ) ); - } - else if ( !bShift /*&& !bMod1*/ ) - { - if ( aSelEng.IsAddMode() ) - { - // toggle selection - pView->Select( pCursor, !pView->IsSelected( pCursor ) ); - } - else if ( !pView->IsSelected( pCursor ) ) - { - SelAllDestrAnch( false ); - pView->Select( pCursor ); - } - else - bKeyUsed = false; - } - else - bKeyUsed = false; - } - else - bKeyUsed = false; - break; - - case KEY_RETURN: - if( bSubLstOpRet && IsExpandable() ) - { - if( pView->IsExpanded( pCursor ) ) - pView->Collapse( pCursor ); - else - pView->Expand( pCursor ); - } - else - bKeyUsed = false; - break; - - case KEY_F2: - if( !bShift && !bMod1 ) - { - aEditClickPos = Point( -1, -1 ); - EditTimerCall( nullptr ); - } - else - bKeyUsed = false; - break; - - case KEY_F8: - if( bShift && pView->GetSelectionMode()==SelectionMode::Multiple && - !(m_nStyle & WB_SIMPLEMODE)) - { - if( aSelEng.IsAlwaysAdding() ) - aSelEng.AddAlways( false ); - else - aSelEng.AddAlways( true ); - } - else - bKeyUsed = false; - break; - - case KEY_ADD: - if( pCursor ) - { - if( !pView->IsExpanded(pCursor)) - pView->Expand( pCursor ); - if( bMod1 ) - { - sal_uInt16 nRefDepth = pTree->GetDepth( pCursor ); - SvTreeListEntry* pCur = pTree->Next( pCursor ); - while( pCur && pTree->GetDepth(pCur) > nRefDepth ) - { - if( pCur->HasChildren() && !pView->IsExpanded(pCur)) - pView->Expand( pCur ); - pCur = pTree->Next( pCur ); - } - } - } - else - bKeyUsed = false; - break; - - case KEY_A: - if( bMod1 ) - SelAllDestrAnch( true ); - else - bKeyUsed = false; - break; - - case KEY_SUBTRACT: - if( pCursor ) - { - if( pView->IsExpanded(pCursor)) - pView->Collapse( pCursor ); - if( bMod1 ) - { - // collapse all parents until we get to the root - SvTreeListEntry* pParentToCollapse = pTree->GetRootLevelParent(pCursor); - if( pParentToCollapse ) - { - sal_uInt16 nRefDepth; - // special case explorer: if the root only has a single - // entry, don't collapse the root entry - if (pTree->GetChildList(nullptr).size() < 2) - { - nRefDepth = 1; - pParentToCollapse = pCursor; - while( pTree->GetParent(pParentToCollapse) && - pTree->GetDepth( pTree->GetParent(pParentToCollapse)) > 0) - { - pParentToCollapse = pTree->GetParent(pParentToCollapse); - } - } - else - nRefDepth = 0; - - if( pView->IsExpanded(pParentToCollapse) ) - pView->Collapse( pParentToCollapse ); - SvTreeListEntry* pCur = pTree->Next( pParentToCollapse ); - while( pCur && pTree->GetDepth(pCur) > nRefDepth ) - { - if( pCur->HasChildren() && pView->IsExpanded(pCur) ) - pView->Collapse( pCur ); - pCur = pTree->Next( pCur ); - } - } - } - } - else - bKeyUsed = false; - break; - - case KEY_DIVIDE : - if( bMod1 ) - SelAllDestrAnch( true ); - else - bKeyUsed = false; - break; - - case KEY_COMMA : - if( bMod1 ) - SelAllDestrAnch( false ); - else - bKeyUsed = false; - break; - - case KEY_HOME : - pNewCursor = pView->GetModel()->First(); - - while( pNewCursor && !IsSelectable(pNewCursor) ) - { - pNewCursor = pView->NextVisible(pNewCursor); - } - - if( pNewCursor && pNewCursor != pCursor ) - { -// SelAllDestrAnch( false ); - aSelEng.CursorPosChanging( bShift, bMod1 ); - SetCursor( pNewCursor ); - if( !IsEntryInView( pNewCursor ) ) - MakeVisible( pNewCursor ); - } - else - bKeyUsed = false; - break; - - case KEY_END : - pNewCursor = pView->GetModel()->Last(); - - while( pNewCursor && !IsSelectable(pNewCursor) ) - { - pNewCursor = pView->PrevVisible(pNewCursor); - } - - if( pNewCursor && pNewCursor != pCursor) - { -// SelAllDestrAnch( false ); - aSelEng.CursorPosChanging( bShift, bMod1 ); - SetCursor( pNewCursor ); - if( !IsEntryInView( pNewCursor ) ) - MakeVisible( pNewCursor ); - } - else - bKeyUsed = false; - break; - - case KEY_ESCAPE: - case KEY_TAB: - case KEY_DELETE: - case KEY_BACKSPACE: - // must not be handled because this quits dialogs and does other magic things... - // if there are other single keys which should not be handled, they can be added here - bKeyUsed = false; - break; - - default: - // is there any reason why we should eat the events here? The only place where this is called - // is from SvTreeListBox::KeyInput. If we set bKeyUsed to true here, then the key input - // is just silenced. However, we want SvLBox::KeyInput to get a chance, to do the QuickSelection - // handling. - // (The old code here which intentionally set bKeyUsed to sal_True said this was because of "quick search" - // handling, but actually there was no quick search handling anymore. We just re-implemented it.) - // #i31275# / 2009-06-16 / frank.schoenheit@sun.com - bKeyUsed = false; - break; - } - return bKeyUsed; -} - -void SvImpLBox::GetFocus() -{ - if( pCursor ) - { - pView->SetEntryFocus( pCursor, true ); - ShowCursor( true ); -// auskommentiert wg. deselectall -// if( bSimpleTravel && !pView->IsSelected(pCursor) ) -// pView->Select( pCursor, true ); - } - if( m_nStyle & WB_HIDESELECTION ) - { - SvTreeListEntry* pEntry = pView->FirstSelected(); - while( pEntry ) - { - InvalidateEntry( pEntry ); - pEntry = pView->NextSelected( pEntry ); - } - } -} - -void SvImpLBox::LoseFocus() -{ - aEditIdle.Stop(); - if( pCursor ) - pView->SetEntryFocus( pCursor,false ); - ShowCursor( false ); - - if( m_nStyle & WB_HIDESELECTION ) - { - SvTreeListEntry* pEntry = pView ? pView->FirstSelected() : nullptr; - while( pEntry ) - { - InvalidateEntry( pEntry ); - pEntry = pView->NextSelected( pEntry ); - } - } -} - - -// ******************************************************************** -// SelectionEngine -// ******************************************************************** - -void SvImpLBox::SelectEntry( SvTreeListEntry* pEntry, bool bSelect ) -{ - pView->Select( pEntry, bSelect ); -} - -ImpLBSelEng::ImpLBSelEng( SvImpLBox* pImpl, SvTreeListBox* pV ) -{ - pImp = pImpl; - pView = pV; -} - -ImpLBSelEng::~ImpLBSelEng() -{ -} - -void ImpLBSelEng::BeginDrag() -{ - pImp->BeginDrag(); -} - -void ImpLBSelEng::CreateAnchor() -{ - pImp->pAnchor = pImp->pCursor; -} - -void ImpLBSelEng::DestroyAnchor() -{ - pImp->pAnchor = nullptr; -} - -void ImpLBSelEng::SetCursorAtPoint(const Point& rPoint, bool bDontSelectAtCursor) -{ - SvTreeListEntry* pNewCursor = pImp->MakePointVisible( rPoint ); - if( pNewCursor != pImp->pCursor ) - pImp->BeginScroll(); - - if( pNewCursor ) - { - // at SimpleTravel, the SetCursor is selected and the select handler is - // called - //if( !bDontSelectAtCursor && !pImp->bSimpleTravel ) - // pImp->SelectEntry( pNewCursor, true ); - pImp->SetCursor( pNewCursor, bDontSelectAtCursor ); - } -} - -bool ImpLBSelEng::IsSelectionAtPoint( const Point& rPoint ) -{ - SvTreeListEntry* pEntry = pImp->MakePointVisible( rPoint ); - if( pEntry ) - return pView->IsSelected(pEntry); - return false; -} - -void ImpLBSelEng::DeselectAtPoint( const Point& rPoint ) -{ - SvTreeListEntry* pEntry = pImp->MakePointVisible( rPoint ); - if( !pEntry ) - return; - pImp->SelectEntry( pEntry, false ); -} - -void ImpLBSelEng::DeselectAll() -{ - pImp->SelAllDestrAnch( false, false ); // don't reset SelectionEngine! - pImp->nFlags &= (~LBoxFlags::DeselectAll); -} - -// *********************************************************************** -// Selection -// *********************************************************************** - -void SvImpLBox::SetAnchorSelection(SvTreeListEntry* pOldCursor,SvTreeListEntry* pNewCursor) -{ - SvTreeListEntry* pEntry; - sal_uLong nAnchorVisPos = pView->GetVisiblePos( pAnchor ); - sal_uLong nOldVisPos = pView->GetVisiblePos( pOldCursor ); - sal_uLong nNewVisPos = pView->GetVisiblePos( pNewCursor ); - - if( nOldVisPos > nAnchorVisPos || - ( nAnchorVisPos==nOldVisPos && nNewVisPos > nAnchorVisPos) ) - { - if( nNewVisPos > nOldVisPos ) - { - pEntry = pOldCursor; - while( pEntry && pEntry != pNewCursor ) - { - pView->Select( pEntry ); - pEntry = pView->NextVisible(pEntry); - } - if( pEntry ) - pView->Select( pEntry ); - return; - } - - if( nNewVisPos < nAnchorVisPos ) - { - pEntry = pAnchor; - while( pEntry && pEntry != pOldCursor ) - { - pView->Select( pEntry, false ); - pEntry = pView->NextVisible(pEntry); - } - if( pEntry ) - pView->Select( pEntry, false ); - - pEntry = pNewCursor; - while( pEntry && pEntry != pAnchor ) - { - pView->Select( pEntry ); - pEntry = pView->NextVisible(pEntry); - } - if( pEntry ) - pView->Select( pEntry ); - return; - } - - if( nNewVisPos < nOldVisPos ) - { - pEntry = pNewCursor; - pEntry = pView->NextVisible(pEntry); - while( pEntry && pEntry != pOldCursor ) - { - pView->Select( pEntry, false ); - pEntry = pView->NextVisible(pEntry); - } - if( pEntry ) - pView->Select( pEntry, false ); - return; - } - } - else - { - if( nNewVisPos < nOldVisPos ) // enlarge selection - { - pEntry = pNewCursor; - while( pEntry && pEntry != pOldCursor ) - { - pView->Select( pEntry ); - pEntry = pView->NextVisible(pEntry); - } - if( pEntry ) - pView->Select( pEntry ); - return; - } - - if( nNewVisPos > nAnchorVisPos ) - { - pEntry = pOldCursor; - while( pEntry && pEntry != pAnchor ) - { - pView->Select( pEntry, false ); - pEntry = pView->NextVisible(pEntry); - } - if( pEntry ) - pView->Select( pEntry, false ); - pEntry = pAnchor; - while( pEntry && pEntry != pNewCursor ) - { - pView->Select( pEntry ); - pEntry = pView->NextVisible(pEntry); - } - if( pEntry ) - pView->Select( pEntry ); - return; - } - - if( nNewVisPos > nOldVisPos ) - { - pEntry = pOldCursor; - while( pEntry && pEntry != pNewCursor ) - { - pView->Select( pEntry, false ); - pEntry = pView->NextVisible(pEntry); - } - return; - } - } -} - -void SvImpLBox::SelAllDestrAnch( - bool bSelect, bool bDestroyAnchor, bool bSingleSelToo ) -{ - SvTreeListEntry* pEntry; - nFlags &= (~LBoxFlags::DeselectAll); - if( bSelect && bSimpleTravel ) - { - if( pCursor && !pView->IsSelected( pCursor )) - { - pView->Select( pCursor ); - } - return; - } - if( !bSelect && pView->GetSelectionCount() == 0 ) - { - if( bSimpleTravel && ( !GetUpdateMode() || !pCursor) ) - nFlags |= LBoxFlags::DeselectAll; - return; - } - if( bSelect && pView->GetSelectionCount() == pView->GetEntryCount()) - return; - if( !bSingleSelToo && bSimpleTravel ) - return; - - if( !bSelect && pView->GetSelectionCount()==1 && pCursor && - pView->IsSelected( pCursor )) - { - pView->Select( pCursor, false ); - if( bDestroyAnchor ) - DestroyAnchor(); // delete anchor & reset SelectionEngine - else - pAnchor = nullptr; // always delete internal anchor - return; - } - - if( bSimpleTravel && !pCursor && !GetUpdateMode() ) - nFlags |= LBoxFlags::DeselectAll; - - ShowCursor( false ); - bool bUpdate = GetUpdateMode(); - - nFlags |= LBoxFlags::IgnoreSelect; // EntryInserted should not do anything - pEntry = pTree->First(); - while( pEntry ) - { - if( pView->Select( pEntry, bSelect ) ) - { - if( bUpdate && pView->IsEntryVisible(pEntry) ) - { - long nY = GetEntryLine( pEntry ); - if( IsLineVisible( nY ) ) - InvalidateEntry(pEntry); - } - } - pEntry = pTree->Next( pEntry ); - } - nFlags &= ~LBoxFlags::IgnoreSelect; - - if( bDestroyAnchor ) - DestroyAnchor(); // delete anchor & reset SelectionEngine - else - pAnchor = nullptr; // always delete internal anchor - ShowCursor( true ); -} - -void SvImpLBox::SetSelectionMode( SelectionMode eSelMode ) -{ - aSelEng.SetSelectionMode( eSelMode); - if( eSelMode == SelectionMode::Single ) - bSimpleTravel = true; - else - bSimpleTravel = false; - if( (m_nStyle & WB_SIMPLEMODE) && (eSelMode == SelectionMode::Multiple) ) - aSelEng.AddAlways( true ); -} - -// *********************************************************************** -// Drag & Drop -// *********************************************************************** - -void SvImpLBox::SetDragDropMode( DragDropMode eDDMode ) -{ - if( eDDMode != DragDropMode::NONE && eDDMode != DragDropMode::APP_DROP ) - { - aSelEng.ExpandSelectionOnMouseMove( false ); - aSelEng.EnableDrag( true ); - } - else - { - aSelEng.ExpandSelectionOnMouseMove(); - aSelEng.EnableDrag( false ); - } -} - -void SvImpLBox::BeginDrag() -{ - nFlags &= (~LBoxFlags::Filling); - if( !bAsyncBeginDrag ) - { - BeginScroll(); - pView->StartDrag( 0, aSelEng.GetMousePosPixel() ); - EndScroll(); - } - else - { - aAsyncBeginDragPos = aSelEng.GetMousePosPixel(); - aAsyncBeginDragIdle.Start(); - } -} - -IMPL_LINK_NOARG(SvImpLBox, BeginDragHdl, Timer *, void) -{ - pView->StartDrag( 0, aAsyncBeginDragPos ); -} - -void SvImpLBox::PaintDDCursor( SvTreeListEntry* pInsertionPos ) -{ - long nY; - if( pInsertionPos ) - { - nY = GetEntryLine( pInsertionPos ); - nY += pView->GetEntryHeight(); - } - else - nY = 1; - RasterOp eOldOp = pView->GetRasterOp(); - pView->SetRasterOp( RasterOp::Invert ); - Color aOldLineColor = pView->GetLineColor(); - pView->SetLineColor( COL_BLACK ); - pView->DrawLine( Point( 0, nY ), Point( aOutputSize.Width(), nY ) ); - pView->SetLineColor( aOldLineColor ); - pView->SetRasterOp( eOldOp ); -} - -void SvImpLBox::Command( const CommandEvent& rCEvt ) -{ - CommandEventId nCommand = rCEvt.GetCommand(); - - if( nCommand == CommandEventId::ContextMenu ) - aEditIdle.Stop(); - - // scroll mouse event? - if( ( ( nCommand == CommandEventId::Wheel ) || ( nCommand == CommandEventId::StartAutoScroll ) || ( nCommand == CommandEventId::AutoScroll ) ) - && pView->HandleScrollCommand( rCEvt, aHorSBar.get(), aVerSBar.get() ) ) - return; - - if( bContextMenuHandling && nCommand == CommandEventId::ContextMenu ) - { - Point aPopupPos; - bool bClickedIsFreePlace = false; - std::stack<SvTreeListEntry*> aSelRestore; - - if( rCEvt.IsMouseEvent() ) - { // change selection, if mouse position doesn't fit to selection - - aPopupPos = rCEvt.GetMousePosPixel(); - - SvTreeListEntry* pClickedEntry = GetEntry( aPopupPos ); - if( pClickedEntry ) - { // mouse in non empty area - bool bClickedIsSelected = false; - - // collect the currently selected entries - SvTreeListEntry* pSelected = pView->FirstSelected(); - while( pSelected ) - { - bClickedIsSelected |= ( pClickedEntry == pSelected ); - pSelected = pView->NextSelected( pSelected ); - } - - // if the entry which the user clicked at is not selected - if( !bClickedIsSelected ) - { // deselect all other and select the clicked one - pView->SelectAll( false ); - pView->SetCursor( pClickedEntry ); - } - } - else if( aSelEng.GetSelectionMode() == SelectionMode::Single ) - { - bClickedIsFreePlace = true; - sal_Int32 nSelectedEntries = pView->GetSelectionCount(); - SvTreeListEntry* pSelected = pView->FirstSelected(); - for(sal_Int32 nSel = 0; nSel < nSelectedEntries; nSel++ ) - { - aSelRestore.push(pSelected); - pSelected = pView->NextSelected( pSelected ); - } - pView->SelectAll( false ); - } - else - { // deselect all - pView->SelectAll( false ); - } - - - } - else - { // key event (or at least no mouse event) - sal_Int32 nSelectionCount = pView->GetSelectionCount(); - - if( nSelectionCount ) - { // now always take first visible as base for positioning the menu - SvTreeListEntry* pSelected = pView->FirstSelected(); - while( pSelected ) - { - if( IsEntryInView( pSelected ) ) - break; - - pSelected = pView->NextSelected( pSelected ); - } - - if( !pSelected ) - { - // no one was visible - pSelected = pView->FirstSelected(); - pView->MakeVisible( pSelected ); - } - - aPopupPos = pView->GetFocusRect( pSelected, pView->GetEntryPosition( pSelected ).Y() ).Center(); - } - else - aPopupPos = Point( 0, 0 ); - } - - { - VclPtr<PopupMenu> pPopup = pView->CreateContextMenu(); - if (pPopup) - { - // do action for selected entry in popup menu - sal_uInt16 nMenuAction = pPopup->Execute( pView, aPopupPos ); - if ( nMenuAction ) - pView->ExecuteContextMenuAction( nMenuAction ); - pPopup.disposeAndClear(); - } - } - - if( bClickedIsFreePlace ) - { - while(!aSelRestore.empty()) - { - SvTreeListEntry* pEntry = aSelRestore.top(); - //#i19717# the entry is maybe already deleted - bool bFound = false; - for(sal_uLong nEntry = 0; nEntry < pView->GetEntryCount(); nEntry++) - if(pEntry == pView->GetEntry(nEntry)) - { - bFound = true; - break; - } - if(bFound) - SetCurEntry( pEntry ); - aSelRestore.pop(); - } - } - } - else - { - const Point& rPos = rCEvt.GetMousePosPixel(); - if( rPos.X() < aOutputSize.Width() && rPos.Y() < aOutputSize.Height() ) - aSelEng.Command( rCEvt ); - } -} - -void SvImpLBox::BeginScroll() -{ - if( !(nFlags & LBoxFlags::InScrolling)) - { - nFlags |= LBoxFlags::InScrolling; - } -} - -void SvImpLBox::EndScroll() -{ - if( nFlags & LBoxFlags::InScrolling) - { - pView->NotifyEndScroll(); - nFlags &= (~LBoxFlags::InScrolling); - } -} - - -tools::Rectangle SvImpLBox::GetVisibleArea() const -{ - Point aPos( pView->GetMapMode().GetOrigin() ); - aPos.setX( aPos.X() * -1 ); - tools::Rectangle aRect( aPos, aOutputSize ); - return aRect; -} - -void SvImpLBox::Invalidate() -{ - pView->SetClipRegion(); -} - -void SvImpLBox::SetCurEntry( SvTreeListEntry* pEntry ) -{ - if ( ( aSelEng.GetSelectionMode() != SelectionMode::Single ) - && ( aSelEng.GetSelectionMode() != SelectionMode::NONE ) - ) - SelAllDestrAnch( false ); - if ( pEntry ) - MakeVisible( pEntry ); - SetCursor( pEntry ); - if ( pEntry && ( aSelEng.GetSelectionMode() != SelectionMode::NONE ) ) - pView->Select( pEntry ); -} - -IMPL_LINK_NOARG(SvImpLBox, EditTimerCall, Timer *, void) -{ - if( !pView->IsInplaceEditingEnabled() ) - return; - - bool bIsMouseTriggered = aEditClickPos.X() >= 0; - if ( bIsMouseTriggered ) - { - Point aCurrentMousePos = pView->GetPointerPosPixel(); - if ( ( std::abs( aCurrentMousePos.X() - aEditClickPos.X() ) > 5 ) - || ( std::abs( aCurrentMousePos.Y() - aEditClickPos.Y() ) > 5 ) - ) - { - return; - } - } - - SvTreeListEntry* pEntry = GetCurEntry(); - if( pEntry ) - { - ShowCursor( false ); - pView->ImplEditEntry( pEntry ); - ShowCursor( true ); - } -} - -bool SvImpLBox::RequestHelp( const HelpEvent& rHEvt ) -{ - if( rHEvt.GetMode() & HelpEventMode::QUICK ) - { - Point aPos( pView->ScreenToOutputPixel( rHEvt.GetMousePosPixel() )); - if( !GetVisibleArea().IsInside( aPos )) - return false; - - SvTreeListEntry* pEntry = GetEntry( aPos ); - if( pEntry ) - { - // recalculate text rectangle - SvLBoxTab* pTab; - SvLBoxItem* pItem = pView->GetItem( pEntry, aPos.X(), &pTab ); - if (!pItem || pItem->GetType() != SvLBoxItemType::String) - return false; - - aPos = GetEntryPosition( pEntry ); - aPos.setX( pView->GetTabPos( pEntry, pTab ) ); //pTab->GetPos(); - Size aSize( pItem->GetSize( pView, pEntry ) ); - SvLBoxTab* pNextTab = NextTab( pTab ); - bool bItemClipped = false; - // is the item cut off by its right neighbor? - if( pNextTab && pView->GetTabPos(pEntry,pNextTab) < aPos.X()+aSize.Width() ) - { - aSize.setWidth( pNextTab->GetPos() - pTab->GetPos() ); - bItemClipped = true; - } - tools::Rectangle aItemRect( aPos, aSize ); - - tools::Rectangle aViewRect( GetVisibleArea() ); - - if( bItemClipped || !aViewRect.IsInside( aItemRect ) ) - { - // clip the right edge of the item at the edge of the view - //if( aItemRect.Right() > aViewRect.Right() ) - // aItemRect.Right() = aViewRect.Right(); - - Point aPt = pView->OutputToScreenPixel( aItemRect.TopLeft() ); - aItemRect.SetLeft( aPt.X() ); - aItemRect.SetTop( aPt.Y() ); - aPt = pView->OutputToScreenPixel( aItemRect.BottomRight() ); - aItemRect.SetRight( aPt.X() ); - aItemRect.SetBottom( aPt.Y() ); - - Help::ShowQuickHelp( pView, aItemRect, - static_cast<SvLBoxString*>(pItem)->GetText(), QuickHelpFlags::Left | QuickHelpFlags::VCenter ); - return true; - } - } - } - return false; -} - -SvLBoxTab* SvImpLBox::NextTab( SvLBoxTab const * pTab ) -{ - sal_uInt16 nTabCount = pView->TabCount(); - if( nTabCount <= 1 ) - return nullptr; - for( int nTab=0; nTab < (nTabCount-1); nTab++) - { - if( pView->aTabs[nTab].get() == pTab ) - return pView->aTabs[nTab+1].get(); - } - return nullptr; -} - -void SvImpLBox::EndSelection() -{ - DestroyAnchor(); - nFlags &= ~LBoxFlags::StartEditTimer; -} - -void SvImpLBox::SetUpdateMode( bool bMode ) -{ - if( bUpdateMode != bMode ) - { - bUpdateMode = bMode; - if( bUpdateMode ) - UpdateAll( false ); - } -} - -bool SvImpLBox::SetMostRight( SvTreeListEntry* pEntry ) -{ - if( pView->nTreeFlags & SvTreeFlags::RECALCTABS ) - { - nFlags |= LBoxFlags::IgnoreChangedTabs; - pView->SetTabs(); - nFlags &= ~LBoxFlags::IgnoreChangedTabs; - } - - sal_uInt16 nLastTab = pView->aTabs.size() - 1; - sal_uInt16 nLastItem = pEntry->ItemCount() - 1; - if( !pView->aTabs.empty() && nLastItem != USHRT_MAX ) - { - if( nLastItem < nLastTab ) - nLastTab = nLastItem; - - SvLBoxTab* pTab = pView->aTabs[ nLastTab ].get(); - SvLBoxItem& rItem = pEntry->GetItem( nLastTab ); - - long nTabPos = pView->GetTabPos( pEntry, pTab ); - - long nMaxRight = GetOutputSize().Width(); - Point aPos( pView->GetMapMode().GetOrigin() ); - aPos.setX( aPos.X() * -1 ); // conversion document coordinates - nMaxRight = nMaxRight + aPos.X() - 1; - - long nNextTab = nTabPos < nMaxRight ? nMaxRight : nMaxRight + 50; - long nTabWidth = nNextTab - nTabPos + 1; - long nItemSize = rItem.GetSize(pView,pEntry).Width(); - long nOffset = pTab->CalcOffset( nItemSize, nTabWidth ); - - long nRight = nTabPos + nOffset + nItemSize; - if( nRight > nMostRight ) - { - nMostRight = nRight; - pMostRightEntry = pEntry; - return true; - } - } - return false; -} - -void SvImpLBox::FindMostRight( SvTreeListEntry const * pEntryToIgnore ) -{ - nMostRight = -1; - pMostRightEntry = nullptr; - if( !pView->GetModel() ) - return; - - SvTreeListEntry* pEntry = pView->FirstVisible(); - while( pEntry ) - { - if( pEntry != pEntryToIgnore ) - SetMostRight( pEntry ); - pEntry = pView->NextVisible( pEntry ); - } -} - -void SvImpLBox::FindMostRight( SvTreeListEntry* pParent, SvTreeListEntry* pEntryToIgnore ) -{ - if( !pParent ) - FindMostRight( pEntryToIgnore ); - else - FindMostRight_Impl( pParent, pEntryToIgnore ); -} - -void SvImpLBox::FindMostRight_Impl( SvTreeListEntry* pParent, SvTreeListEntry* pEntryToIgnore ) -{ - SvTreeListEntries& rList = pTree->GetChildList( pParent ); - - size_t nCount = rList.size(); - for( size_t nCur = 0; nCur < nCount; nCur++ ) - { - SvTreeListEntry* pChild = rList[nCur].get(); - if( pChild != pEntryToIgnore ) - { - SetMostRight( pChild ); - if( pChild->HasChildren() && pView->IsExpanded( pChild )) - FindMostRight_Impl( pChild, pEntryToIgnore ); - } - } -} - -void SvImpLBox::NotifyTabsChanged() -{ - if( GetUpdateMode() && !(nFlags & LBoxFlags::IgnoreChangedTabs ) && - nCurUserEvent == nullptr ) - { - nCurUserEvent = Application::PostUserEvent(LINK(this,SvImpLBox,MyUserEvent)); - } -} - -bool SvImpLBox::IsExpandable() const -{ - return pCursor->HasChildren() || pCursor->HasChildrenOnDemand(); -} - -IMPL_LINK(SvImpLBox, MyUserEvent, void*, pArg, void ) -{ - nCurUserEvent = nullptr; - if( !pArg ) - { - pView->Invalidate(); - pView->Update(); - } - else - { - FindMostRight( nullptr ); - ShowVerSBar(); - pView->Invalidate( GetVisibleArea() ); - } -} - - -void SvImpLBox::StopUserEvent() -{ - if( nCurUserEvent != nullptr ) - { - Application::RemoveUserEvent( nCurUserEvent ); - nCurUserEvent = nullptr; - } -} - -void SvImpLBox::ShowFocusRect( const SvTreeListEntry* pEntry ) -{ - if( pEntry ) - { - long nY = GetEntryLine( const_cast<SvTreeListEntry*>(pEntry) ); - tools::Rectangle aRect = pView->GetFocusRect( const_cast<SvTreeListEntry*>(pEntry), nY ); - vcl::Region aOldClip( pView->GetClipRegion()); - vcl::Region aClipRegion( GetClipRegionRect() ); - pView->SetClipRegion( aClipRegion ); - pView->ShowFocus( aRect ); - pView->SetClipRegion( aOldClip ); - - } - else - { - pView->HideFocus(); - } -} - - -void SvImpLBox::implInitDefaultNodeImages() -{ - if ( s_pDefCollapsed ) - // assume that all or nothing is initialized - return; - - s_pDefCollapsed = new Image(BitmapEx(RID_BMP_TREENODE_COLLAPSED)); - s_pDefExpanded = new Image(BitmapEx(RID_BMP_TREENODE_EXPANDED)); -} - - -const Image& SvImpLBox::GetDefaultExpandedNodeImage( ) -{ - implInitDefaultNodeImages(); - return *s_pDefExpanded; -} - - -const Image& SvImpLBox::GetDefaultCollapsedNodeImage( ) -{ - implInitDefaultNodeImages(); - return *s_pDefCollapsed; -} - - -void SvImpLBox::CallEventListeners( VclEventId nEvent, void* pData ) -{ - if ( pView ) - pView->CallImplEventListeners( nEvent, pData); -} - - -bool SvImpLBox::SetCurrentTabPos( sal_uInt16 _nNewPos ) -{ - bool bRet = false; - - if ( pView && _nNewPos < ( pView->TabCount() - 2 ) ) - { - nCurTabPos = _nNewPos; - ShowCursor( true ); - bRet = true; - } - - return bRet; -} - - -bool SvImpLBox::IsSelectable( const SvTreeListEntry* pEntry ) -{ - if( pEntry ) - { - SvViewDataEntry* pViewDataNewCur = pView->GetViewDataEntry(pEntry); - return (pViewDataNewCur == nullptr) || pViewDataNewCur->IsSelectable(); - } - else - { - return false; - } -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/contnr/svlbitm.cxx b/svtools/source/contnr/svlbitm.cxx deleted file mode 100644 index 11eeb0165f5e..000000000000 --- a/svtools/source/contnr/svlbitm.cxx +++ /dev/null @@ -1,461 +0,0 @@ -/* -*- 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 <svtools/treelistbox.hxx> -#include <svtools/svlbitm.hxx> -#include <svtools/treelistentry.hxx> -#include <svtools/viewdataentry.hxx> -#include <vcl/svapp.hxx> -#include <vcl/button.hxx> -#include <vcl/decoview.hxx> -#include <vcl/salnativewidgets.hxx> - -struct SvLBoxButtonData_Impl -{ - SvTreeListEntry* pEntry; - bool bDefaultImages; - bool bShowRadioButton; - - SvLBoxButtonData_Impl() : pEntry( nullptr ), bDefaultImages( false ), bShowRadioButton( false ) {} -}; - -void SvLBoxButtonData::InitData( bool _bRadioBtn, const Control* pCtrl ) -{ - nWidth = nHeight = 0; - - aBmps.resize(int(SvBmp::STATICIMAGE)+1); - - bDataOk = false; - pImpl->bDefaultImages = true; - pImpl->bShowRadioButton = _bRadioBtn; - - SetDefaultImages( pCtrl ); -} - -SvLBoxButtonData::SvLBoxButtonData( const Control* pControlForSettings ) - : pImpl( new SvLBoxButtonData_Impl ) -{ - InitData( false, pControlForSettings ); -} - -SvLBoxButtonData::SvLBoxButtonData( const Control* pControlForSettings, bool _bRadioBtn ) - : pImpl( new SvLBoxButtonData_Impl ) -{ - InitData( _bRadioBtn, pControlForSettings ); -} - -SvLBoxButtonData::~SvLBoxButtonData() -{ -} - -void SvLBoxButtonData::CallLink() -{ - aLink.Call( this ); -} - -SvBmp SvLBoxButtonData::GetIndex( SvItemStateFlags nItemState ) -{ - SvBmp nIdx; - if (nItemState == SvItemStateFlags::UNCHECKED) - nIdx = SvBmp::UNCHECKED; - else if (nItemState == SvItemStateFlags::CHECKED) - nIdx = SvBmp::CHECKED; - else if (nItemState == SvItemStateFlags::TRISTATE) - nIdx = SvBmp::TRISTATE; - else if (nItemState == (SvItemStateFlags::UNCHECKED | SvItemStateFlags::HILIGHTED)) - nIdx = SvBmp::HIUNCHECKED; - else if (nItemState == (SvItemStateFlags::CHECKED | SvItemStateFlags::HILIGHTED)) - nIdx = SvBmp::HICHECKED; - else if (nItemState == (SvItemStateFlags::TRISTATE | SvItemStateFlags::HILIGHTED)) - nIdx = SvBmp::HITRISTATE; - else - nIdx = SvBmp::UNCHECKED; - return nIdx; -} - -void SvLBoxButtonData::SetWidthAndHeight() -{ - Size aSize = aBmps[int(SvBmp::UNCHECKED)].GetSizePixel(); - nWidth = aSize.Width(); - nHeight = aSize.Height(); - bDataOk = true; -} - - -void SvLBoxButtonData::StoreButtonState( SvTreeListEntry* pActEntry ) -{ - pImpl->pEntry = pActEntry; -} - -SvButtonState SvLBoxButtonData::ConvertToButtonState( SvItemStateFlags nItemFlags ) -{ - nItemFlags &= (SvItemStateFlags::UNCHECKED | - SvItemStateFlags::CHECKED | - SvItemStateFlags::TRISTATE); - switch( nItemFlags ) - { - case SvItemStateFlags::UNCHECKED: - return SvButtonState::Unchecked; - case SvItemStateFlags::CHECKED: - return SvButtonState::Checked; - case SvItemStateFlags::TRISTATE: - return SvButtonState::Tristate; - default: - return SvButtonState::Unchecked; - } -} - -SvTreeListEntry* SvLBoxButtonData::GetActEntry() const -{ - assert(pImpl && "-SvLBoxButtonData::GetActEntry(): don't use me that way!"); - return pImpl->pEntry; -} - -void SvLBoxButtonData::SetDefaultImages( const Control* pCtrl ) -{ - const AllSettings& rSettings = pCtrl? pCtrl->GetSettings() : Application::GetSettings(); - - if ( pImpl->bShowRadioButton ) - { - SetImage(SvBmp::UNCHECKED, RadioButton::GetRadioImage( rSettings, DrawButtonFlags::Default ) ); - SetImage(SvBmp::CHECKED, RadioButton::GetRadioImage( rSettings, DrawButtonFlags::Checked ) ); - SetImage(SvBmp::HICHECKED, RadioButton::GetRadioImage( rSettings, DrawButtonFlags::Checked | DrawButtonFlags::Pressed ) ); - SetImage(SvBmp::HIUNCHECKED, RadioButton::GetRadioImage( rSettings, DrawButtonFlags::Default | DrawButtonFlags::Pressed ) ); - SetImage(SvBmp::TRISTATE, RadioButton::GetRadioImage( rSettings, DrawButtonFlags::DontKnow ) ); - SetImage(SvBmp::HITRISTATE, RadioButton::GetRadioImage( rSettings, DrawButtonFlags::DontKnow | DrawButtonFlags::Pressed ) ); - } - else - { - SetImage(SvBmp::UNCHECKED, CheckBox::GetCheckImage( rSettings, DrawButtonFlags::Default ) ); - SetImage(SvBmp::CHECKED, CheckBox::GetCheckImage( rSettings, DrawButtonFlags::Checked ) ); - SetImage(SvBmp::HICHECKED, CheckBox::GetCheckImage( rSettings, DrawButtonFlags::Checked | DrawButtonFlags::Pressed ) ); - SetImage(SvBmp::HIUNCHECKED, CheckBox::GetCheckImage( rSettings, DrawButtonFlags::Default | DrawButtonFlags::Pressed ) ); - SetImage(SvBmp::TRISTATE, CheckBox::GetCheckImage( rSettings, DrawButtonFlags::DontKnow ) ); - SetImage(SvBmp::HITRISTATE, CheckBox::GetCheckImage( rSettings, DrawButtonFlags::DontKnow | DrawButtonFlags::Pressed ) ); - } -} - -bool SvLBoxButtonData::HasDefaultImages() const -{ - return pImpl->bDefaultImages; -} - -bool SvLBoxButtonData::IsRadio() { - return pImpl->bShowRadioButton; -} - -// *************************************************************** -// class SvLBoxString -// *************************************************************** - - -SvLBoxString::SvLBoxString(const OUString& rStr) -{ - SetText(rStr); -} - -SvLBoxString::SvLBoxString() : SvLBoxItem() -{ -} - -SvLBoxString::~SvLBoxString() -{ -} - -SvLBoxItemType SvLBoxString::GetType() const -{ - return SvLBoxItemType::String; -} - -void SvLBoxString::Paint( - const Point& rPos, SvTreeListBox& rDev, vcl::RenderContext& rRenderContext, - const SvViewDataEntry* /*pView*/, const SvTreeListEntry& rEntry) -{ - Size aSize = GetSize(&rDev, &rEntry); - DrawTextFlags nStyle = rDev.IsEnabled() ? DrawTextFlags::NONE : DrawTextFlags::Disable; - if (rDev.IsEntryMnemonicsEnabled()) - nStyle |= DrawTextFlags::Mnemonic; - if (rDev.TextCenterAndClipEnabled()) - { - nStyle |= DrawTextFlags::PathEllipsis | DrawTextFlags::Center; - aSize.setWidth( rDev.GetEntryWidth() ); - } - rRenderContext.DrawText(tools::Rectangle(rPos, aSize), maText, nStyle); -} - -std::unique_ptr<SvLBoxItem> SvLBoxString::Clone(SvLBoxItem const * pSource) const -{ - std::unique_ptr<SvLBoxString> pNew(new SvLBoxString); - pNew->maText = static_cast<SvLBoxString const *>(pSource)->maText; - return std::unique_ptr<SvLBoxItem>(pNew.release()); -} - -void SvLBoxString::InitViewData( - SvTreeListBox* pView, SvTreeListEntry* pEntry, SvViewDataItem* pViewData) -{ - if( !pViewData ) - pViewData = pView->GetViewDataItem( pEntry, this ); - pViewData->maSize = Size(pView->GetTextWidth(maText), pView->GetTextHeight()); -} - -// *************************************************************** -// class SvLBoxButton -// *************************************************************** - - -SvLBoxButton::SvLBoxButton( SvLBoxButtonKind eTheKind, - SvLBoxButtonData* pBData ) - : isVis(true) - , pData(pBData) - , eKind(eTheKind) - , nItemFlags(SvItemStateFlags::NONE) -{ - SetStateUnchecked(); -} - -SvLBoxButton::SvLBoxButton() - : SvLBoxItem() - , isVis(false) - , pData(nullptr) - , eKind(SvLBoxButtonKind::EnabledCheckbox) - , nItemFlags(SvItemStateFlags::NONE) -{ - SetStateUnchecked(); -} - -SvLBoxButton::~SvLBoxButton() -{ -} - -SvLBoxItemType SvLBoxButton::GetType() const -{ - return SvLBoxItemType::Button; -} - -void SvLBoxButton::ClickHdl( SvTreeListEntry* pEntry ) -{ - if ( CheckModification() ) - { - if ( IsStateChecked() ) - SetStateUnchecked(); - else - SetStateChecked(); - pData->StoreButtonState( pEntry ); - pData->CallLink(); - } -} - -void SvLBoxButton::Paint( - const Point& rPos, SvTreeListBox& rDev, vcl::RenderContext& rRenderContext, - const SvViewDataEntry* /*pView*/, const SvTreeListEntry& /*rEntry*/) -{ - SvBmp nIndex = eKind == SvLBoxButtonKind::StaticImage ? SvBmp::STATICIMAGE : SvLBoxButtonData::GetIndex(nItemFlags); - DrawImageFlags nStyle = eKind != SvLBoxButtonKind::DisabledCheckbox && rDev.IsEnabled() ? DrawImageFlags::NONE : DrawImageFlags::Disable; - - //Native drawing - bool bNativeOK = false; - ControlType eCtrlType = (pData->IsRadio())? ControlType::Radiobutton : ControlType::Checkbox; - if ( nIndex != SvBmp::STATICIMAGE && rRenderContext.IsNativeControlSupported( eCtrlType, ControlPart::Entire) ) - - { - Size aSize(pData->Width(), pData->Height()); - ImplAdjustBoxSize(aSize, eCtrlType, rRenderContext); - ImplControlValue aControlValue; - tools::Rectangle aCtrlRegion( rPos, aSize ); - ControlState nState = ControlState::NONE; - - //states ControlState::DEFAULT, ControlState::PRESSED and ControlState::ROLLOVER are not implemented - if (IsStateHilighted()) - nState |= ControlState::FOCUSED; - if (nStyle != DrawImageFlags::Disable) - nState |= ControlState::ENABLED; - if (IsStateChecked()) - aControlValue.setTristateVal(ButtonValue::On); - else if (IsStateUnchecked()) - aControlValue.setTristateVal(ButtonValue::Off); - else if (IsStateTristate()) - aControlValue.setTristateVal( ButtonValue::Mixed ); - - if (isVis) - bNativeOK = rRenderContext.DrawNativeControl(eCtrlType, ControlPart::Entire, - aCtrlRegion, nState, aControlValue, OUString()); - } - - if (!bNativeOK && isVis) - rRenderContext.DrawImage(rPos, pData->GetImage(nIndex), nStyle); -} - -std::unique_ptr<SvLBoxItem> SvLBoxButton::Clone(SvLBoxItem const * pSource) const -{ - std::unique_ptr<SvLBoxButton> pNew(new SvLBoxButton); - pNew->pData = static_cast<SvLBoxButton const *>(pSource)->pData; - return std::unique_ptr<SvLBoxItem>(pNew.release()); -} - -void SvLBoxButton::ImplAdjustBoxSize(Size& io_rSize, ControlType i_eType, vcl::RenderContext const & rRenderContext) -{ - if (!rRenderContext.IsNativeControlSupported( i_eType, ControlPart::Entire) ) - return; - - ImplControlValue aControlValue; - tools::Rectangle aCtrlRegion( Point( 0, 0 ), io_rSize ); - - aControlValue.setTristateVal( ButtonValue::On ); - - tools::Rectangle aNativeBounds, aNativeContent; - bool bNativeOK = rRenderContext.GetNativeControlRegion( i_eType, - ControlPart::Entire, - aCtrlRegion, - ControlState::ENABLED, - aControlValue, - aNativeBounds, - aNativeContent ); - if( bNativeOK ) - { - Size aContentSize( aNativeContent.GetSize() ); - // leave a little space around the box image (looks better) - if( aContentSize.Height() + 2 > io_rSize.Height() ) - io_rSize.setHeight( aContentSize.Height() + 2 ); - if( aContentSize.Width() + 2 > io_rSize.Width() ) - io_rSize.setWidth( aContentSize.Width() + 2 ); - } -} - -void SvLBoxButton::InitViewData(SvTreeListBox* pView,SvTreeListEntry* pEntry, SvViewDataItem* pViewData) -{ - if( !pViewData ) - pViewData = pView->GetViewDataItem( pEntry, this ); - Size aSize( pData->Width(), pData->Height() ); - - ControlType eCtrlType = (pData->IsRadio())? ControlType::Radiobutton : ControlType::Checkbox; - if ( eKind != SvLBoxButtonKind::StaticImage && pView ) - ImplAdjustBoxSize(aSize, eCtrlType, *pView); - pViewData->maSize = aSize; -} - -bool SvLBoxButton::CheckModification() const -{ - return eKind == SvLBoxButtonKind::EnabledCheckbox; -} - -void SvLBoxButton::SetStateInvisible() -{ - isVis = false; -} - -// *************************************************************** -// class SvLBoxContextBmp -// *************************************************************** - -struct SvLBoxContextBmp_Impl -{ - Image m_aImage1; - Image m_aImage2; - - bool m_bExpanded; -}; - -// *************************************************************** - -SvLBoxContextBmp::SvLBoxContextBmp(const Image& aBmp1, const Image& aBmp2, - bool bExpanded) - :m_pImpl( new SvLBoxContextBmp_Impl ) -{ - - m_pImpl->m_bExpanded = bExpanded; - SetModeImages( aBmp1, aBmp2 ); -} - -SvLBoxContextBmp::SvLBoxContextBmp() - :SvLBoxItem( ) - ,m_pImpl( new SvLBoxContextBmp_Impl ) -{ - m_pImpl->m_bExpanded = false; -} - -SvLBoxContextBmp::~SvLBoxContextBmp() -{ -} - -SvLBoxItemType SvLBoxContextBmp::GetType() const -{ - return SvLBoxItemType::ContextBmp; -} - -void SvLBoxContextBmp::SetModeImages( const Image& _rBitmap1, const Image& _rBitmap2 ) -{ - m_pImpl->m_aImage1 = _rBitmap1; - m_pImpl->m_aImage2 = _rBitmap2; -} - -Image& SvLBoxContextBmp::implGetImageStore( bool _bFirst ) -{ - - // OJ: #i27071# wrong mode so we just return the normal images - return _bFirst ? m_pImpl->m_aImage1 : m_pImpl->m_aImage2; -} - -void SvLBoxContextBmp::InitViewData( SvTreeListBox* pView,SvTreeListEntry* pEntry, - SvViewDataItem* pViewData) -{ - if( !pViewData ) - pViewData = pView->GetViewDataItem( pEntry, this ); - pViewData->maSize = m_pImpl->m_aImage1.GetSizePixel(); -} - -void SvLBoxContextBmp::Paint( - const Point& _rPos, SvTreeListBox& _rDev, vcl::RenderContext& rRenderContext, - const SvViewDataEntry* pView, const SvTreeListEntry& rEntry) -{ - - // get the image. - const Image& rImage = implGetImageStore(pView->IsExpanded() != m_pImpl->m_bExpanded); - - bool _bSemiTransparent = bool( SvTLEntryFlags::SEMITRANSPARENT & rEntry.GetFlags( ) ); - // draw - DrawImageFlags nStyle = _rDev.IsEnabled() ? DrawImageFlags::NONE : DrawImageFlags::Disable; - if (_bSemiTransparent) - nStyle |= DrawImageFlags::SemiTransparent; - rRenderContext.DrawImage(_rPos, rImage, nStyle); -} - -std::unique_ptr<SvLBoxItem> SvLBoxContextBmp::Clone(SvLBoxItem const * pSource) const -{ - std::unique_ptr<SvLBoxContextBmp> pNew(new SvLBoxContextBmp); - pNew->m_pImpl->m_aImage1 = static_cast< SvLBoxContextBmp const * >( pSource )->m_pImpl->m_aImage1; - pNew->m_pImpl->m_aImage2 = static_cast< SvLBoxContextBmp const * >( pSource )->m_pImpl->m_aImage2; - pNew->m_pImpl->m_bExpanded = static_cast<SvLBoxContextBmp const *>(pSource)->m_pImpl->m_bExpanded; - return std::unique_ptr<SvLBoxItem>(pNew.release()); -} - -long SvLBoxButtonData::Width() -{ - if ( !bDataOk ) - SetWidthAndHeight(); - return nWidth; -} - -long SvLBoxButtonData::Height() -{ - if ( !bDataOk ) - SetWidthAndHeight(); - return nHeight; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/contnr/svtabbx.cxx b/svtools/source/contnr/svtabbx.cxx index 8fb4aef8d84a..12bcc3dfc6d3 100644 --- a/svtools/source/contnr/svtabbx.cxx +++ b/svtools/source/contnr/svtabbx.cxx @@ -21,9 +21,9 @@ #include <svtools/svtabbx.hxx> #include <svtools/headbar.hxx> #include <svtools/svtresid.hxx> -#include <svtools/svlbitm.hxx> +#include <vcl/svlbitm.hxx> #include <svtools/strings.hrc> -#include <svtools/treelistentry.hxx> +#include <vcl/treelistentry.hxx> #include <vcl/builderfactory.hxx> #include <com/sun/star/accessibility/AccessibleStateType.hpp> #include <com/sun/star/accessibility/AccessibleEventId.hpp> diff --git a/svtools/source/contnr/treelist.cxx b/svtools/source/contnr/treelist.cxx deleted file mode 100644 index e20e571f2d4a..000000000000 --- a/svtools/source/contnr/treelist.cxx +++ /dev/null @@ -1,1630 +0,0 @@ -/* -*- 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 <svtools/treelist.hxx> -#include <svtools/treelistentry.hxx> -#include <svtools/viewdataentry.hxx> -#include <osl/diagnose.h> -#include <o3tl/make_unique.hxx> - -#include <memory> -#include <map> - - -typedef std::map<SvTreeListEntry*, std::unique_ptr<SvViewDataEntry>> SvDataTable; - -struct SvListView::Impl -{ - SvListView & m_rThis; - - SvDataTable m_DataTable; // Mapping SvTreeListEntry -> ViewData - - sal_uLong m_nVisibleCount; - sal_uLong m_nSelectionCount; - bool m_bVisPositionsValid; - - explicit Impl(SvListView & rThis) - : m_rThis(rThis) - , m_nVisibleCount(0) - , m_nSelectionCount(0) - , m_bVisPositionsValid(false) - {} - - void InitTable(); - void RemoveViewData( SvTreeListEntry* pParent ); - - void ActionMoving(SvTreeListEntry* pEntry); - void ActionMoved(); - void ActionInserted(SvTreeListEntry* pEntry); - void ActionInsertedTree(SvTreeListEntry* pEntry); - void ActionRemoving(SvTreeListEntry* pEntry); - void ActionClear(); -}; - - -SvTreeList::SvTreeList() : - mbEnableInvalidate(true) -{ - nEntryCount = 0; - bAbsPositionsValid = false; - nRefCount = 1; - pRootItem.reset(new SvTreeListEntry); - eSortMode = SortNone; -} - -SvTreeList::~SvTreeList() -{ - Clear(); -} - -void SvTreeList::Broadcast( - SvListAction nActionId, - SvTreeListEntry* pEntry1, - SvTreeListEntry* pEntry2, - sal_uLong nPos -) { - for (auto const& view : aViewList) - { - if(view) - view->ModelNotification(nActionId, pEntry1, pEntry2, nPos); - } -} - -void SvTreeList::InsertView( SvListView* pView ) -{ - if (std::find(aViewList.begin(), aViewList.end(), pView) != aViewList.end()) - return; - - aViewList.push_back( pView ); - nRefCount++; -} - -void SvTreeList::RemoveView( SvListView const * pView ) -{ - auto viewFound = std::find(aViewList.begin(), aViewList.end(), pView); - if (viewFound != aViewList.end()) - { - aViewList.erase( viewFound ); - --nRefCount; - } -} - - -// an entry is visible if all parents are expanded -bool SvTreeList::IsEntryVisible( const SvListView* pView, SvTreeListEntry* pEntry ) const -{ - DBG_ASSERT(pView&&pEntry,"IsVisible:Invalid Params"); - bool bRetVal = false; - do - { - if ( pEntry == pRootItem.get() ) - { - bRetVal = true; - break; - } - pEntry = pEntry->pParent; - } while( pView->IsExpanded( pEntry ) ); - return bRetVal; -} - -sal_uInt16 SvTreeList::GetDepth( const SvTreeListEntry* pEntry ) const -{ - DBG_ASSERT(pEntry && pEntry!=pRootItem.get(),"GetDepth:Bad Entry"); - sal_uInt16 nDepth = 0; - while( pEntry->pParent != pRootItem.get() ) - { - nDepth++; - pEntry = pEntry->pParent; - } - return nDepth; -} - -bool SvTreeList::IsAtRootDepth( const SvTreeListEntry* pEntry ) const -{ - return pEntry->pParent == pRootItem.get(); -} - -void SvTreeList::Clear() -{ - Broadcast( SvListAction::CLEARING ); - pRootItem->ClearChildren(); - nEntryCount = 0; - Broadcast( SvListAction::CLEARED ); -} - -bool SvTreeList::IsChild(const SvTreeListEntry* pParent, const SvTreeListEntry* pChild) const -{ - if ( !pParent ) - pParent = pRootItem.get(); - - if (pParent->m_Children.empty()) - return false; - - for (auto const& it : pParent->m_Children) - { - const SvTreeListEntry* pThis = it.get(); - if (pThis == pChild) - return true; - else - { - bool bIsChild = IsChild(pThis, pChild); - if (bIsChild) - return true; - } - } - return false; -} - -namespace { - -class FindByPointer -{ - const SvTreeListEntry* mpEntry; -public: - explicit FindByPointer(const SvTreeListEntry* p) : mpEntry(p) {} - - bool operator() (std::unique_ptr<SvTreeListEntry> const& rpEntry) const - { - return mpEntry == rpEntry.get(); - } -}; - -sal_uLong findEntryPosition(const SvTreeListEntries& rDst, const SvTreeListEntry* pEntry) -{ - SvTreeListEntries::const_iterator itPos = std::find_if(rDst.begin(), rDst.end(), FindByPointer(pEntry)); - if (itPos == rDst.end()) - return static_cast<sal_uLong>(~0); - - return static_cast<sal_uLong>(std::distance(rDst.begin(), itPos)); -} - -} - -sal_uLong SvTreeList::Move(SvTreeListEntry* pSrcEntry,SvTreeListEntry* pTargetParent,sal_uLong nListPos) -{ - // pDest may be 0! - DBG_ASSERT(pSrcEntry,"Entry?"); - if ( !pTargetParent ) - pTargetParent = pRootItem.get(); - DBG_ASSERT(pSrcEntry!=pTargetParent,"Move:Source=Target"); - - Broadcast( SvListAction::MOVING, pSrcEntry, pTargetParent, nListPos ); - - if ( pSrcEntry == pTargetParent ) - // You can't move an entry onto itself as the parent. Just return its - // position and bail out. - return pSrcEntry->GetChildListPos(); - - bAbsPositionsValid = false; - - SvTreeListEntries& rDst = pTargetParent->m_Children; - SvTreeListEntries& rSrc = pSrcEntry->pParent->m_Children; - - bool bSameParent = pTargetParent == pSrcEntry->pParent; - - // Find the position of the entry being moved in the source container. - SvTreeListEntries::iterator itSrcPos = rSrc.begin(), itEnd = rSrc.end(); - for (; itSrcPos != itEnd; ++itSrcPos) - { - const SvTreeListEntry* p = (*itSrcPos).get(); - if (p == pSrcEntry) - // Found - break; - } - - if (itSrcPos == itEnd) - { - OSL_FAIL("Source entry not found! This should never happen."); - return pSrcEntry->GetChildListPos(); - } - - if (bSameParent) - { - // Moving within the same parent. - - size_t nSrcPos = std::distance(rSrc.begin(), itSrcPos); - if (nSrcPos == nListPos) - // Nothing to move here. - return pSrcEntry->GetChildListPos(); - - if (nSrcPos < nListPos) - // Destination position shifts left after removing the original. - --nListPos; - - // Release the original. - std::unique_ptr<SvTreeListEntry> pOriginal(std::move(*itSrcPos)); - assert(pOriginal.get()); - rSrc.erase(itSrcPos); - - // Determine the insertion position. - SvTreeListEntries::iterator itDstPos = rSrc.end(); - if (nListPos < rSrc.size()) - { - itDstPos = rSrc.begin(); - std::advance(itDstPos, nListPos); - } - rSrc.insert(itDstPos, std::move(pOriginal)); - } - else - { - // Moving from one parent to another. - SvTreeListEntries::iterator itDstPos = rDst.end(); - if (nListPos < rDst.size()) - { - itDstPos = rDst.begin(); - std::advance(itDstPos, nListPos); - } - std::unique_ptr<SvTreeListEntry> pOriginal(std::move(*itSrcPos)); - assert(pOriginal.get()); - rSrc.erase(itSrcPos); - rDst.insert(itDstPos, std::move(pOriginal)); - } - - // move parent (do this only now, because we need the parent for - // deleting the old child list!) - pSrcEntry->pParent = pTargetParent; - - // correct list position in target list - SetListPositions(rDst); - if (!bSameParent) - SetListPositions(rSrc); - - sal_uLong nRetVal = findEntryPosition(rDst, pSrcEntry); - OSL_ENSURE(nRetVal == pSrcEntry->GetChildListPos(), "ListPos not valid"); - Broadcast( SvListAction::MOVED,pSrcEntry,pTargetParent,nRetVal); - return nRetVal; -} - -sal_uLong SvTreeList::Copy(SvTreeListEntry* pSrcEntry,SvTreeListEntry* pTargetParent,sal_uLong nListPos) -{ - // pDest may be 0! - DBG_ASSERT(pSrcEntry,"Entry?"); - if ( !pTargetParent ) - pTargetParent = pRootItem.get(); - - bAbsPositionsValid = false; - - sal_uLong nCloneCount = 0; - SvTreeListEntry* pClonedEntry = Clone( pSrcEntry, nCloneCount ); - nEntryCount += nCloneCount; - - SvTreeListEntries& rDst = pTargetParent->m_Children; - - pClonedEntry->pParent = pTargetParent; // move parent - - if (nListPos < rDst.size()) - { - SvTreeListEntries::iterator itPos = rDst.begin(); // insertion position. - std::advance(itPos, nListPos); - rDst.insert(itPos, std::unique_ptr<SvTreeListEntry>(pClonedEntry)); - } - else - rDst.push_back(std::unique_ptr<SvTreeListEntry>(pClonedEntry)); - - SetListPositions(rDst); // correct list position in target list - - Broadcast( SvListAction::INSERTED_TREE, pClonedEntry ); - sal_uLong nRetVal = findEntryPosition(rDst, pClonedEntry); - return nRetVal; -} - -void SvTreeList::Move( SvTreeListEntry* pSrcEntry, SvTreeListEntry* pDstEntry ) -{ - SvTreeListEntry* pParent; - sal_uLong nPos; - - if ( !pDstEntry ) - { - pParent = pRootItem.get(); - nPos = 0; - } - else - { - pParent = pDstEntry->pParent; - nPos = pDstEntry->GetChildListPos(); - nPos++; // (On screen:) insert _below_ pDstEntry - } - Move( pSrcEntry, pParent, nPos ); -} - -void SvTreeList::InsertTree(SvTreeListEntry* pSrcEntry, - SvTreeListEntry* pTargetParent,sal_uLong nListPos) -{ - DBG_ASSERT(pSrcEntry,"InsertTree:Entry?"); - if ( !pSrcEntry ) - return; - - if ( !pTargetParent ) - pTargetParent = pRootItem.get(); - - // take sorting into account - GetInsertionPos( pSrcEntry, pTargetParent, nListPos ); - - bAbsPositionsValid = false; - - pSrcEntry->pParent = pTargetParent; // move parent - SvTreeListEntries& rDst = pTargetParent->m_Children; - - if (nListPos < rDst.size()) - { - SvTreeListEntries::iterator itPos = rDst.begin(); - std::advance(itPos, nListPos); - rDst.insert(itPos, std::unique_ptr<SvTreeListEntry>(pSrcEntry)); - } - else - rDst.push_back(std::unique_ptr<SvTreeListEntry>(pSrcEntry)); - - SetListPositions(rDst); // correct list position in target list - nEntryCount += GetChildCount( pSrcEntry ); - nEntryCount++; // the parent is new, too - - Broadcast(SvListAction::INSERTED_TREE, pSrcEntry ); -} - -SvTreeListEntry* SvTreeList::CloneEntry( SvTreeListEntry* pSource ) const -{ - if( aCloneLink.IsSet() ) - return aCloneLink.Call( pSource ); - SvTreeListEntry* pEntry = new SvTreeListEntry; - pEntry->Clone(pSource); - return pEntry; -} - -SvTreeListEntry* SvTreeList::Clone( SvTreeListEntry* pEntry, sal_uLong& nCloneCount ) const -{ - SvTreeListEntry* pClonedEntry = CloneEntry( pEntry ); - nCloneCount = 1; - if (!pEntry->m_Children.empty()) - // Clone the child entries. - CloneChildren(pClonedEntry->m_Children, nCloneCount, pEntry->m_Children, *pClonedEntry); - - return pClonedEntry; -} - -void SvTreeList::CloneChildren( - SvTreeListEntries& rDst, sal_uLong& rCloneCount, SvTreeListEntries& rSrc, SvTreeListEntry& rNewParent) const -{ - SvTreeListEntries aClone; - for (auto const& elem : rSrc) - { - SvTreeListEntry& rEntry = *elem; - std::unique_ptr<SvTreeListEntry> pNewEntry(CloneEntry(&rEntry)); - ++rCloneCount; - pNewEntry->pParent = &rNewParent; - if (!rEntry.m_Children.empty()) - // Clone entries recursively. - CloneChildren(pNewEntry->m_Children, rCloneCount, rEntry.m_Children, *pNewEntry); - - aClone.push_back(std::move(pNewEntry)); - } - - rDst.swap(aClone); -} - -sal_uLong SvTreeList::GetChildCount( const SvTreeListEntry* pParent ) const -{ - if ( !pParent ) - return GetEntryCount(); - - if (pParent->m_Children.empty()) - return 0; - - sal_uLong nCount = 0; - sal_uInt16 nRefDepth = GetDepth( pParent ); - sal_uInt16 nActDepth = nRefDepth; - do - { - pParent = Next(const_cast<SvTreeListEntry*>(pParent), &nActDepth); - nCount++; - } while( pParent && nRefDepth < nActDepth ); - nCount--; - return nCount; -} - -sal_uLong SvTreeList::GetVisibleChildCount(const SvListView* pView, SvTreeListEntry* pParent) const -{ - DBG_ASSERT(pView,"GetVisChildCount:No View"); - if ( !pParent ) - pParent = pRootItem.get(); - - if (!pParent || !pView->IsExpanded(pParent) || pParent->m_Children.empty()) - return 0; - - sal_uLong nCount = 0; - sal_uInt16 nRefDepth = GetDepth( pParent ); - sal_uInt16 nActDepth = nRefDepth; - do - { - pParent = NextVisible( pView, pParent, &nActDepth ); - nCount++; - } while( pParent && nRefDepth < nActDepth ); - nCount--; - return nCount; -} - -sal_uLong SvTreeList::GetChildSelectionCount(const SvListView* pView,SvTreeListEntry* pParent) const -{ - DBG_ASSERT(pView,"GetChildSelCount:No View"); - if ( !pParent ) - pParent = pRootItem.get(); - - if (!pParent || pParent->m_Children.empty()) - return 0; - - sal_uLong nCount = 0; - sal_uInt16 nRefDepth = GetDepth( pParent ); - sal_uInt16 nActDepth = nRefDepth; - do - { - pParent = Next( pParent, &nActDepth ); - if( pParent && pView->IsSelected( pParent ) && nRefDepth < nActDepth) - nCount++; - } while( pParent && nRefDepth < nActDepth ); -// nCount--; - return nCount; -} - -SvTreeListEntry* SvTreeList::First() const -{ - if ( nEntryCount ) - return pRootItem->m_Children[0].get(); - else - return nullptr; -} - -SvTreeListEntry* SvTreeList::Next( SvTreeListEntry* pActEntry, sal_uInt16* pDepth ) const -{ - DBG_ASSERT( pActEntry && pActEntry->pParent, "SvTreeList::Next: invalid entry/parent!" ); - if ( !pActEntry || !pActEntry->pParent ) - return nullptr; - - sal_uInt16 nDepth = 0; - bool bWithDepth = false; - if ( pDepth ) - { - nDepth = *pDepth; - bWithDepth = true; - } - - // Get the list where the current entry belongs to (from its parent). - SvTreeListEntries* pActualList = &pActEntry->pParent->m_Children; - sal_uLong nActualPos = pActEntry->GetChildListPos(); - - if (!pActEntry->m_Children.empty()) - { - // The current entry has children. Get its first child entry. - nDepth++; - pActEntry = pActEntry->m_Children[0].get(); - if ( bWithDepth ) - *pDepth = nDepth; - return pActEntry; - } - - if (pActualList->size() > (nActualPos+1)) - { - // Get the next sibling of the current entry. - pActEntry = (*pActualList)[nActualPos+1].get(); - if ( bWithDepth ) - *pDepth = nDepth; - return pActEntry; - } - - // Move up level(s) until we find the level where the next sibling exists. - SvTreeListEntry* pParent = pActEntry->pParent; - nDepth--; - while( pParent != pRootItem.get() && pParent != nullptr ) - { - DBG_ASSERT(pParent!=nullptr,"TreeData corrupt!"); - pActualList = &pParent->pParent->m_Children; - nActualPos = pParent->GetChildListPos(); - if (pActualList->size() > (nActualPos+1)) - { - pActEntry = (*pActualList)[nActualPos+1].get(); - if ( bWithDepth ) - *pDepth = nDepth; - return pActEntry; - } - pParent = pParent->pParent; - nDepth--; - } - return nullptr; -} - -SvTreeListEntry* SvTreeList::Prev( SvTreeListEntry* pActEntry ) const -{ - DBG_ASSERT(pActEntry!=nullptr,"Entry?"); - - sal_uInt16 nDepth = 0; - - SvTreeListEntries* pActualList = &pActEntry->pParent->m_Children; - sal_uLong nActualPos = pActEntry->GetChildListPos(); - - if ( nActualPos > 0 ) - { - pActEntry = (*pActualList)[nActualPos-1].get(); - while (!pActEntry->m_Children.empty()) - { - pActualList = &pActEntry->m_Children; - nDepth++; - pActEntry = pActualList->back().get(); - } - return pActEntry; - } - if ( pActEntry->pParent == pRootItem.get() ) - return nullptr; - - pActEntry = pActEntry->pParent; - - if ( pActEntry ) - { - nDepth--; - return pActEntry; - } - return nullptr; -} - -SvTreeListEntry* SvTreeList::Last() const -{ - SvTreeListEntries* pActList = &pRootItem->m_Children; - SvTreeListEntry* pEntry = nullptr; - while (!pActList->empty()) - { - pEntry = pActList->back().get(); - pActList = &pEntry->m_Children; - } - return pEntry; -} - -sal_uLong SvTreeList::GetVisiblePos( const SvListView* pView, SvTreeListEntry const * pEntry ) const -{ - DBG_ASSERT(pView&&pEntry,"View/Entry?"); - - if (!pView->m_pImpl->m_bVisPositionsValid) - { - // to make GetVisibleCount refresh the positions - const_cast<SvListView*>(pView)->m_pImpl->m_nVisibleCount = 0; - GetVisibleCount( const_cast<SvListView*>(pView) ); - } - const SvViewDataEntry* pViewData = pView->GetViewData( pEntry ); - return pViewData->nVisPos; -} - -sal_uLong SvTreeList::GetVisibleCount( SvListView* pView ) const -{ - assert(pView && "GetVisCount:No View"); - if( !pView->HasViewData() ) - return 0; - if (pView->m_pImpl->m_nVisibleCount) - return pView->m_pImpl->m_nVisibleCount; - - sal_uLong nPos = 0; - SvTreeListEntry* pEntry = First(); // first entry is always visible - while ( pEntry ) - { - SvViewDataEntry* pViewData = pView->GetViewData( pEntry ); - pViewData->nVisPos = nPos; - nPos++; - pEntry = NextVisible( pView, pEntry ); - } -#ifdef DBG_UTIL - if( nPos > 10000000 ) - { - OSL_FAIL("nVisibleCount bad"); - } -#endif - pView->m_pImpl->m_nVisibleCount = nPos; - pView->m_pImpl->m_bVisPositionsValid = true; - return nPos; -} - - -// For performance reasons, this function assumes that the passed entry is -// already visible. -SvTreeListEntry* SvTreeList::NextVisible(const SvListView* pView,SvTreeListEntry* pActEntry,sal_uInt16* pActDepth) const -{ - DBG_ASSERT(pView,"NextVisible:No View"); - if ( !pActEntry ) - return nullptr; - - sal_uInt16 nDepth = 0; - bool bWithDepth = false; - if ( pActDepth ) - { - nDepth = *pActDepth; - bWithDepth = true; - } - - SvTreeListEntries* pActualList = &pActEntry->pParent->m_Children; - sal_uLong nActualPos = pActEntry->GetChildListPos(); - - if ( pView->IsExpanded(pActEntry) ) - { - OSL_ENSURE(!pActEntry->m_Children.empty(), "Pass entry is supposed to have child entries."); - - nDepth++; - pActEntry = pActEntry->m_Children[0].get(); - if ( bWithDepth ) - *pActDepth = nDepth; - return pActEntry; - } - - nActualPos++; - if ( pActualList->size() > nActualPos ) - { - pActEntry = (*pActualList)[nActualPos].get(); - if ( bWithDepth ) - *pActDepth = nDepth; - return pActEntry; - } - - SvTreeListEntry* pParent = pActEntry->pParent; - nDepth--; - while( pParent != pRootItem.get() ) - { - pActualList = &pParent->pParent->m_Children; - nActualPos = pParent->GetChildListPos(); - nActualPos++; - if ( pActualList->size() > nActualPos ) - { - pActEntry = (*pActualList)[nActualPos].get(); - if ( bWithDepth ) - *pActDepth = nDepth; - return pActEntry; - } - pParent = pParent->pParent; - nDepth--; - } - return nullptr; -} - - -// For performance reasons, this function assumes that the passed entry is -// already visible. - -SvTreeListEntry* SvTreeList::PrevVisible(const SvListView* pView, SvTreeListEntry* pActEntry) const -{ - DBG_ASSERT(pView&&pActEntry,"PrevVis:View/Entry?"); - - sal_uInt16 nDepth = 0; - - SvTreeListEntries* pActualList = &pActEntry->pParent->m_Children; - sal_uLong nActualPos = pActEntry->GetChildListPos(); - - if ( nActualPos > 0 ) - { - pActEntry = (*pActualList)[nActualPos-1].get(); - while( pView->IsExpanded(pActEntry) ) - { - pActualList = &pActEntry->m_Children; - nDepth++; - pActEntry = pActualList->back().get(); - } - return pActEntry; - } - - if ( pActEntry->pParent == pRootItem.get() ) - return nullptr; - - pActEntry = pActEntry->pParent; - if ( pActEntry ) - { - nDepth--; - return pActEntry; - } - return nullptr; -} - -SvTreeListEntry* SvTreeList::LastVisible( const SvListView* pView) const -{ - DBG_ASSERT(pView,"LastVis:No View"); - SvTreeListEntry* pEntry = Last(); - while( pEntry && !IsEntryVisible( pView, pEntry ) ) - pEntry = PrevVisible( pView, pEntry ); - return pEntry; -} - -SvTreeListEntry* SvTreeList::NextVisible(const SvListView* pView,SvTreeListEntry* pEntry,sal_uInt16& nDelta) const -{ - DBG_ASSERT(pView&&pEntry&&IsEntryVisible(pView,pEntry),"NextVis:Wrong Prms/!Vis"); - - sal_uLong nVisPos = GetVisiblePos( pView, pEntry ); - // nDelta entries existent? - // example: 0,1,2,3,4,5,6,7,8,9 nVisPos=5 nDelta=7 - // nNewDelta = 10-nVisPos-1 == 4 - if (nVisPos+nDelta >= pView->m_pImpl->m_nVisibleCount) - { - nDelta = static_cast<sal_uInt16>(pView->m_pImpl->m_nVisibleCount-nVisPos); - nDelta--; - } - sal_uInt16 nDeltaTmp = nDelta; - while( nDeltaTmp ) - { - pEntry = NextVisible( pView, pEntry ); - nDeltaTmp--; - DBG_ASSERT(pEntry,"Entry?"); - } - return pEntry; -} - -SvTreeListEntry* SvTreeList::PrevVisible( const SvListView* pView, SvTreeListEntry* pEntry, sal_uInt16& nDelta ) const -{ - DBG_ASSERT(pView&&pEntry&&IsEntryVisible(pView,pEntry),"PrevVis:Parms/!Vis"); - - sal_uLong nVisPos = GetVisiblePos( pView, pEntry ); - // nDelta entries existent? - // example: 0,1,2,3,4,5,6,7,8,9 nVisPos=8 nDelta=20 - // nNewDelta = nNewVisPos - if ( nDelta > nVisPos ) - nDelta = static_cast<sal_uInt16>(nVisPos); - sal_uInt16 nDeltaTmp = nDelta; - while( nDeltaTmp ) - { - pEntry = PrevVisible( pView, pEntry ); - nDeltaTmp--; - DBG_ASSERT(pEntry,"Entry?"); - } - return pEntry; -} - -SvTreeListEntry* SvTreeList::FirstSelected( const SvListView* pView) const -{ - DBG_ASSERT(pView,"FirstSel:No View"); - if( !pView ) - return nullptr; - SvTreeListEntry* pActSelEntry = First(); - while( pActSelEntry && !pView->IsSelected(pActSelEntry) ) - pActSelEntry = NextVisible( pView, pActSelEntry ); - return pActSelEntry; -} - - -SvTreeListEntry* SvTreeList::FirstChild( SvTreeListEntry* pParent ) const -{ - if ( !pParent ) - pParent = pRootItem.get(); - SvTreeListEntry* pResult; - if (!pParent->m_Children.empty()) - pResult = pParent->m_Children[0].get(); - else - pResult = nullptr; - return pResult; -} - -SvTreeListEntry* SvTreeList::NextSelected( const SvListView* pView, SvTreeListEntry* pEntry ) const -{ - DBG_ASSERT(pView&&pEntry,"NextSel:View/Entry?"); - pEntry = Next( pEntry ); - while( pEntry && !pView->IsSelected(pEntry) ) - pEntry = Next( pEntry ); - return pEntry; -} - -SvTreeListEntry* SvTreeList::PrevSelected( const SvListView* pView, SvTreeListEntry* pEntry) const -{ - DBG_ASSERT(pView&&pEntry,"PrevSel:View/Entry?"); - pEntry = Prev( pEntry ); - while( pEntry && !pView->IsSelected(pEntry) ) - pEntry = Prev( pEntry ); - - return pEntry; -} - -SvTreeListEntry* SvTreeList::LastSelected( const SvListView* pView ) const -{ - DBG_ASSERT(pView,"LastSel:No View"); - SvTreeListEntry* pEntry = Last(); - while( pEntry && !pView->IsSelected(pEntry) ) - pEntry = Prev( pEntry ); - return pEntry; -} - -sal_uLong SvTreeList::Insert( SvTreeListEntry* pEntry,SvTreeListEntry* pParent,sal_uLong nPos ) -{ - DBG_ASSERT( pEntry,"Entry?"); - - if ( !pParent ) - pParent = pRootItem.get(); - - SvTreeListEntries& rList = pParent->m_Children; - - // take sorting into account - GetInsertionPos( pEntry, pParent, nPos ); - - bAbsPositionsValid = false; - pEntry->pParent = pParent; - - if (nPos < rList.size()) - { - SvTreeListEntries::iterator itPos = rList.begin(); - std::advance(itPos, nPos); - rList.insert(itPos, std::unique_ptr<SvTreeListEntry>(pEntry)); - } - else - rList.push_back(std::unique_ptr<SvTreeListEntry>(pEntry)); - - nEntryCount++; - if (nPos != TREELIST_APPEND && (nPos != (rList.size()-1))) - SetListPositions(rList); - else - pEntry->nListPos = rList.size()-1; - - Broadcast( SvListAction::INSERTED, pEntry ); - return nPos; // pEntry->nListPos; -} - -sal_uLong SvTreeList::GetAbsPos( const SvTreeListEntry* pEntry) const -{ - if ( !bAbsPositionsValid ) - const_cast<SvTreeList*>(this)->SetAbsolutePositions(); - return pEntry->nAbsPos; -} - -sal_uLong SvTreeList::GetRelPos( const SvTreeListEntry* pChild ) -{ - return pChild->GetChildListPos(); -} - -void SvTreeList::SetAbsolutePositions() -{ - sal_uLong nPos = 0; - SvTreeListEntry* pEntry = First(); - while ( pEntry ) - { - pEntry->nAbsPos = nPos; - nPos++; - pEntry = Next( pEntry ); - } - bAbsPositionsValid = true; -} - -void SvTreeList::Expand( SvListView* pView, SvTreeListEntry* pEntry ) -{ - DBG_ASSERT(pEntry&&pView,"Expand:View/Entry?"); - if ( pView->IsExpanded(pEntry) ) - return; - - DBG_ASSERT(!pEntry->m_Children.empty(), "SvTreeList::Expand: We expected to have child entries."); - - SvViewDataEntry* pViewData = pView->GetViewData(pEntry); - pViewData->SetExpanded(true); - SvTreeListEntry* pParent = pEntry->pParent; - // if parent is visible, invalidate status data - if ( pView->IsExpanded( pParent ) ) - { - pView->m_pImpl->m_bVisPositionsValid = false; - pView->m_pImpl->m_nVisibleCount = 0; - } -} - -void SvTreeList::Collapse( SvListView* pView, SvTreeListEntry* pEntry ) -{ - DBG_ASSERT(pView&&pEntry,"Collapse:View/Entry?"); - if ( !pView->IsExpanded(pEntry) ) - return; - - DBG_ASSERT(!pEntry->m_Children.empty(), "SvTreeList::Collapse: We expected to have child entries."); - - SvViewDataEntry* pViewData = pView->GetViewData( pEntry ); - pViewData->SetExpanded(false); - - SvTreeListEntry* pParent = pEntry->pParent; - if ( pView->IsExpanded(pParent) ) - { - pView->m_pImpl->m_nVisibleCount = 0; - pView->m_pImpl->m_bVisPositionsValid = false; - } -} - -bool SvTreeList::Select( SvListView* pView, SvTreeListEntry* pEntry, bool bSelect ) -{ - DBG_ASSERT(pView&&pEntry,"Select:View/Entry?"); - SvViewDataEntry* pViewData = pView->GetViewData( pEntry ); - if ( bSelect ) - { - if ( pViewData->IsSelected() || !pViewData->IsSelectable() ) - return false; - else - { - pViewData->SetSelected(true); - pView->m_pImpl->m_nSelectionCount++; - } - } - else - { - if ( !pViewData->IsSelected() ) - return false; - else - { - pViewData->SetSelected(false); - pView->m_pImpl->m_nSelectionCount--; - } - } - return true; -} - -bool SvTreeList::Remove( const SvTreeListEntry* pEntry ) -{ - DBG_ASSERT(pEntry,"Cannot remove root, use clear"); - - if( !pEntry->pParent ) - { - OSL_FAIL("Removing entry not in model!"); - // Under certain circumstances (which?), the explorer deletes entries - // from the view that it hasn't inserted into the view. We don't want - // to crash, so we catch this case here. - return false; - } - - Broadcast(SvListAction::REMOVING, const_cast<SvTreeListEntry*>(pEntry)); - sal_uLong nRemoved = 1 + GetChildCount(pEntry); - bAbsPositionsValid = false; - - SvTreeListEntry* pParent = pEntry->pParent; - SvTreeListEntries& rList = pParent->m_Children; - bool bLastEntry = false; - - // Since we need the live instance of SvTreeListEntry for broadcasting, - // we first need to pop it from the container, broadcast it, then delete - // the instance manually at the end. - - std::unique_ptr<SvTreeListEntry> pEntryDeleter; - if ( pEntry->HasChildListPos() ) - { - size_t nListPos = pEntry->GetChildListPos(); - bLastEntry = (nListPos == (rList.size()-1)); - SvTreeListEntries::iterator it = rList.begin(); - std::advance(it, nListPos); - pEntryDeleter = std::move(*it); - rList.erase(it); - } - else - { - SvTreeListEntries::iterator it = - std::find_if(rList.begin(), rList.end(), FindByPointer(pEntry)); - if (it != rList.end()) - { - pEntryDeleter = std::move(*it); - rList.erase(it); - } - } - - if (!rList.empty() && !bLastEntry) - SetListPositions(rList); - - nEntryCount -= nRemoved; - Broadcast(SvListAction::REMOVED, const_cast<SvTreeListEntry*>(pEntry)); - - return true; -} - -SvTreeListEntry* SvTreeList::GetEntryAtAbsPos( sal_uLong nAbsPos ) const -{ - SvTreeListEntry* pEntry = First(); - while ( nAbsPos && pEntry ) - { - pEntry = Next( pEntry ); - nAbsPos--; - } - return pEntry; -} - -SvTreeListEntry* SvTreeList::GetEntryAtVisPos( const SvListView* pView, sal_uLong nVisPos ) const -{ - DBG_ASSERT(pView,"GetEntryAtVisPos:No View"); - SvTreeListEntry* pEntry = First(); - while ( nVisPos && pEntry ) - { - pEntry = NextVisible( pView, pEntry ); - nVisPos--; - } - return pEntry; -} - -void SvTreeList::SetListPositions( SvTreeListEntries& rEntries ) -{ - if (rEntries.empty()) - return; - - SvTreeListEntry& rFirst = *rEntries.front(); - if (rFirst.pParent) - rFirst.pParent->InvalidateChildrensListPositions(); -} - -void SvTreeList::EnableInvalidate( bool bEnable ) -{ - mbEnableInvalidate = bEnable; -} - -void SvTreeList::InvalidateEntry( SvTreeListEntry* pEntry ) -{ - if (!mbEnableInvalidate) - return; - - Broadcast( SvListAction::INVALIDATE_ENTRY, pEntry ); -} - -SvTreeListEntry* SvTreeList::GetRootLevelParent( SvTreeListEntry* pEntry ) const -{ - DBG_ASSERT(pEntry,"GetRootLevelParent:No Entry"); - SvTreeListEntry* pCurParent = nullptr; - if ( pEntry ) - { - pCurParent = pEntry->pParent; - if ( pCurParent == pRootItem.get() ) - return pEntry; // is its own parent - while( pCurParent && pCurParent->pParent != pRootItem.get() ) - pCurParent = pCurParent->pParent; - } - return pCurParent; -} - -std::pair<SvTreeListEntries::iterator, SvTreeListEntries::iterator> - SvTreeList::GetChildIterators(SvTreeListEntry* pParent) -{ - typedef std::pair<SvTreeListEntries::iterator, SvTreeListEntries::iterator> IteratorPair; - - static SvTreeListEntries dummy; // prevent singular iterator asserts - IteratorPair aRet(dummy.begin(), dummy.end()); - - if (!pParent) - pParent = pRootItem.get(); - - if (pParent->m_Children.empty()) - // This entry has no children. - return aRet; - - aRet.first = pParent->m_Children.begin(); - aRet.second = pParent->m_Children.end(); - - return aRet; -} - - -SvListView::SvListView() - : m_pImpl(new Impl(*this)) - , pModel(nullptr) -{ -} - -SvListView::~SvListView() -{ - m_pImpl->m_DataTable.clear(); -} - -sal_uLong SvListView::GetSelectionCount() const -{ return m_pImpl->m_nSelectionCount; } - -bool SvListView::HasViewData() const -{ return m_pImpl->m_DataTable.size() > 1; } // There's always a ROOT - - -void SvListView::Impl::InitTable() -{ - DBG_ASSERT(m_rThis.pModel,"InitTable:No Model"); - DBG_ASSERT(!m_nSelectionCount && !m_nVisibleCount && !m_bVisPositionsValid, - "InitTable: Not cleared!"); - - if (!m_DataTable.empty()) - { - DBG_ASSERT(m_DataTable.size() == 1, "InitTable: TableCount != 1"); - // Delete the view data allocated to the Clear in the root. - // Attention: The model belonging to the root entry (and thus the entry - // itself) might already be deleted. - m_DataTable.clear(); - } - - SvTreeListEntry* pEntry; - - // insert root entry - pEntry = m_rThis.pModel->pRootItem.get(); - std::unique_ptr<SvViewDataEntry> pViewData(new SvViewDataEntry); - pViewData->SetExpanded(true); - m_DataTable.insert(std::make_pair(pEntry, std::move(pViewData))); - // now all the other entries - pEntry = m_rThis.pModel->First(); - while( pEntry ) - { - pViewData = m_rThis.CreateViewData( pEntry ); - DBG_ASSERT(pViewData,"InitTable:No ViewData"); - m_rThis.InitViewData( pViewData.get(), pEntry ); - m_DataTable.insert(std::make_pair(pEntry, std::move(pViewData))); - pEntry = m_rThis.pModel->Next( pEntry ); - } -} - -std::unique_ptr<SvViewDataEntry> SvListView::CreateViewData( SvTreeListEntry* ) -{ - return o3tl::make_unique<SvViewDataEntry>(); -} - -void SvListView::Clear() -{ - m_pImpl->m_DataTable.clear(); - m_pImpl->m_nSelectionCount = 0; - m_pImpl->m_nVisibleCount = 0; - m_pImpl->m_bVisPositionsValid = false; - if( pModel ) - { - // insert root entry - SvTreeListEntry* pEntry = pModel->pRootItem.get(); - std::unique_ptr<SvViewDataEntry> pViewData(new SvViewDataEntry); - pViewData->SetExpanded(true); - m_pImpl->m_DataTable.insert(std::make_pair(pEntry, std::move(pViewData))); - } -} - -void SvListView::SetModel( SvTreeList* pNewModel ) -{ - bool bBroadcastCleared = false; - if ( pModel ) - { - pModel->RemoveView( this ); - bBroadcastCleared = true; - ModelNotification( SvListAction::CLEARING,nullptr,nullptr,0 ); - if ( pModel->GetRefCount() == 0 ) - delete pModel; - } - pModel = pNewModel; - m_pImpl->InitTable(); - pNewModel->InsertView( this ); - if( bBroadcastCleared ) - ModelNotification( SvListAction::CLEARED,nullptr,nullptr,0 ); -} - - -void SvListView::ModelHasCleared() -{ -} - -void SvListView::ModelHasInserted( SvTreeListEntry* ) -{ -} - -void SvListView::ModelHasInsertedTree( SvTreeListEntry* ) -{ -} - -void SvListView::ModelIsMoving( SvTreeListEntry* /* pSource */ , - SvTreeListEntry* /* pTargetParent */ , sal_uLong /* nPos */ ) -{ -} - - -void SvListView::ModelHasMoved( SvTreeListEntry* ) -{ -} - -void SvListView::ModelIsRemoving( SvTreeListEntry* ) -{ -} - -void SvListView::ModelHasRemoved( SvTreeListEntry* ) -{ - //WARNING WARNING WARNING - //The supplied pointer should have been deleted - //before this call. Be careful not to use it!!! -} - -void SvListView::ModelHasEntryInvalidated( SvTreeListEntry*) -{ -} - -void SvListView::Impl::ActionMoving( SvTreeListEntry* pEntry ) -{ - SvTreeListEntry* pParent = pEntry->pParent; - DBG_ASSERT(pParent,"Model not consistent"); - if (pParent != m_rThis.pModel->pRootItem.get() && pParent->m_Children.size() == 1) - { - SvViewDataEntry* pViewData = m_DataTable.find( pParent )->second.get(); - pViewData->SetExpanded(false); - } - // preliminary - m_nVisibleCount = 0; - m_bVisPositionsValid = false; -} - -void SvListView::Impl::ActionMoved() -{ - m_nVisibleCount = 0; - m_bVisPositionsValid = false; -} - -void SvListView::Impl::ActionInserted( SvTreeListEntry* pEntry ) -{ - DBG_ASSERT(pEntry,"Insert:No Entry"); - std::unique_ptr<SvViewDataEntry> pData(m_rThis.CreateViewData( pEntry )); - m_rThis.InitViewData( pData.get(), pEntry ); - std::pair<SvDataTable::iterator, bool> aSuccess = - m_DataTable.insert(std::make_pair(pEntry, std::move(pData))); - DBG_ASSERT(aSuccess.second,"Entry already in View"); - if (m_nVisibleCount && m_rThis.pModel->IsEntryVisible(&m_rThis, pEntry)) - { - m_nVisibleCount = 0; - m_bVisPositionsValid = false; - } -} - -void SvListView::Impl::ActionInsertedTree( SvTreeListEntry* pEntry ) -{ - if (m_rThis.pModel->IsEntryVisible(&m_rThis, pEntry)) - { - m_nVisibleCount = 0; - m_bVisPositionsValid = false; - } - // iterate over entry and its children - SvTreeListEntry* pCurEntry = pEntry; - sal_uInt16 nRefDepth = m_rThis.pModel->GetDepth( pCurEntry ); - while( pCurEntry ) - { - DBG_ASSERT(m_DataTable.find(pCurEntry) != m_DataTable.end(),"Entry already in Table"); - std::unique_ptr<SvViewDataEntry> pViewData(m_rThis.CreateViewData(pCurEntry)); - DBG_ASSERT(pViewData,"No ViewData"); - m_rThis.InitViewData( pViewData.get(), pEntry ); - m_DataTable.insert(std::make_pair(pCurEntry, std::move(pViewData))); - pCurEntry = m_rThis.pModel->Next( pCurEntry ); - if ( pCurEntry && m_rThis.pModel->GetDepth(pCurEntry) <= nRefDepth) - pCurEntry = nullptr; - } -} - -void SvListView::Impl::RemoveViewData( SvTreeListEntry* pParent ) -{ - for (auto const& it : pParent->m_Children) - { - SvTreeListEntry& rEntry = *it; - m_DataTable.erase(&rEntry); - if (rEntry.HasChildren()) - RemoveViewData(&rEntry); - } -} - - -void SvListView::Impl::ActionRemoving( SvTreeListEntry* pEntry ) -{ - DBG_ASSERT(pEntry,"Remove:No Entry"); - - SvViewDataEntry* pViewData = m_DataTable.find( pEntry )->second.get(); - sal_uLong nSelRemoved = 0; - if ( pViewData->IsSelected() ) - nSelRemoved = 1 + m_rThis.pModel->GetChildSelectionCount(&m_rThis, pEntry); - m_nSelectionCount -= nSelRemoved; - sal_uLong nVisibleRemoved = 0; - if (m_rThis.pModel->IsEntryVisible(&m_rThis, pEntry)) - nVisibleRemoved = 1 + m_rThis.pModel->GetVisibleChildCount(&m_rThis, pEntry); - if( m_nVisibleCount ) - { -#ifdef DBG_UTIL - if (m_nVisibleCount < nVisibleRemoved) - { - OSL_FAIL("nVisibleRemoved bad"); - } -#endif - m_nVisibleCount -= nVisibleRemoved; - } - m_bVisPositionsValid = false; - - m_DataTable.erase(pEntry); - RemoveViewData( pEntry ); - - SvTreeListEntry* pCurEntry = pEntry->pParent; - if (pCurEntry && pCurEntry != m_rThis.pModel->pRootItem.get() && pCurEntry->m_Children.size() == 1) - { - pViewData = m_DataTable.find(pCurEntry)->second.get(); - pViewData->SetExpanded(false); - } -} - -void SvListView::Impl::ActionClear() -{ - m_rThis.Clear(); -} - -void SvListView::ModelNotification( SvListAction nActionId, SvTreeListEntry* pEntry1, - SvTreeListEntry* pEntry2, sal_uLong nPos ) -{ - switch( nActionId ) - { - case SvListAction::INSERTED: - m_pImpl->ActionInserted( pEntry1 ); - ModelHasInserted( pEntry1 ); - break; - case SvListAction::INSERTED_TREE: - m_pImpl->ActionInsertedTree( pEntry1 ); - ModelHasInsertedTree( pEntry1 ); - break; - case SvListAction::REMOVING: - ModelIsRemoving( pEntry1 ); - m_pImpl->ActionRemoving( pEntry1 ); - break; - case SvListAction::REMOVED: - ModelHasRemoved( pEntry1 ); - break; - case SvListAction::MOVING: - ModelIsMoving( pEntry1, pEntry2, nPos ); - m_pImpl->ActionMoving( pEntry1 ); - break; - case SvListAction::MOVED: - m_pImpl->ActionMoved(); - ModelHasMoved( pEntry1 ); - break; - case SvListAction::CLEARING: - m_pImpl->ActionClear(); - ModelHasCleared(); // sic! for compatibility reasons! - break; - case SvListAction::CLEARED: - break; - case SvListAction::INVALIDATE_ENTRY: - // no action for the base class - ModelHasEntryInvalidated( pEntry1 ); - break; - case SvListAction::RESORTED: - m_pImpl->m_bVisPositionsValid = false; - break; - case SvListAction::RESORTING: - break; - case SvListAction::REVERSING: - break; - case SvListAction::REVERSED: - m_pImpl->m_bVisPositionsValid = false; - break; - default: - OSL_FAIL("unknown ActionId"); - } -} - -void SvListView::InitViewData( SvViewDataEntry*, SvTreeListEntry* ) -{ -} - -bool SvListView::IsExpanded( SvTreeListEntry* pEntry ) const -{ - DBG_ASSERT(pEntry,"IsExpanded:No Entry"); - SvDataTable::const_iterator itr = m_pImpl->m_DataTable.find(pEntry); - DBG_ASSERT(itr != m_pImpl->m_DataTable.end(),"Entry not in Table"); - if (itr == m_pImpl->m_DataTable.end()) - return false; - return itr->second->IsExpanded(); -} - -bool SvListView::IsSelected( SvTreeListEntry* pEntry ) const -{ - DBG_ASSERT(pEntry,"IsExpanded:No Entry"); - SvDataTable::const_iterator itr = m_pImpl->m_DataTable.find(pEntry); - if (itr == m_pImpl->m_DataTable.end()) - return false; - return itr->second->IsSelected(); -} - -void SvListView::SetEntryFocus( SvTreeListEntry* pEntry, bool bFocus ) -{ - DBG_ASSERT(pEntry,"SetEntryFocus:No Entry"); - SvDataTable::iterator itr = m_pImpl->m_DataTable.find(pEntry); - DBG_ASSERT(itr != m_pImpl->m_DataTable.end(),"Entry not in Table"); - itr->second->SetFocus(bFocus); -} - -const SvViewDataEntry* SvListView::GetViewData( const SvTreeListEntry* pEntry ) const -{ - SvDataTable::const_iterator itr = - m_pImpl->m_DataTable.find(const_cast<SvTreeListEntry*>(pEntry)); - if (itr == m_pImpl->m_DataTable.end()) - return nullptr; - return itr->second.get(); -} - -SvViewDataEntry* SvListView::GetViewData( SvTreeListEntry* pEntry ) -{ - SvDataTable::iterator itr = m_pImpl->m_DataTable.find( pEntry ); - DBG_ASSERT(itr != m_pImpl->m_DataTable.end(),"Entry not in model or wrong view"); - return itr->second.get(); -} - -sal_Int32 SvTreeList::Compare(const SvTreeListEntry* pLeft, const SvTreeListEntry* pRight) const -{ - if( aCompareLink.IsSet()) - { - SvSortData aSortData; - aSortData.pLeft = pLeft; - aSortData.pRight = pRight; - return aCompareLink.Call( aSortData ); - } - return 0; -} - -void SvTreeList::Resort() -{ - Broadcast( SvListAction::RESORTING ); - bAbsPositionsValid = false; - ResortChildren( pRootItem.get() ); - Broadcast( SvListAction::RESORTED ); -} - -namespace { - -class SortComparator -{ - SvTreeList& mrList; -public: - - explicit SortComparator( SvTreeList& rList ) : mrList(rList) {} - - bool operator() (std::unique_ptr<SvTreeListEntry> const& rpLeft, - std::unique_ptr<SvTreeListEntry> const& rpRight) const - { - return mrList.Compare(rpLeft.get(), rpRight.get()) < 0; - } -}; - -} - -void SvTreeList::ResortChildren( SvTreeListEntry* pParent ) -{ - DBG_ASSERT(pParent,"Parent not set"); - - if (pParent->m_Children.empty()) - return; - - SortComparator aComp(*this); - std::sort(pParent->m_Children.begin(), pParent->m_Children.end(), aComp); - - // Recursively sort child entries. - for (auto const& it : pParent->m_Children) - { - SvTreeListEntry& r = *it; - ResortChildren(&r); - } - - SetListPositions(pParent->m_Children); // correct list position in target list -} - -void SvTreeList::Reverse() -{ - Broadcast(SvListAction::REVERSING); - bAbsPositionsValid = false; - ReverseChildren(pRootItem.get()); - Broadcast(SvListAction::REVERSED); -} - -void SvTreeList::ReverseChildren( SvTreeListEntry* pParent ) -{ - DBG_ASSERT(pParent,"Parent not set"); - - if (pParent->m_Children.empty()) - return; - - std::reverse(pParent->m_Children.begin(), pParent->m_Children.end()); - // Recursively sort child entries. - for (auto const& it : pParent->m_Children) - { - SvTreeListEntry& r = *it; - ReverseChildren(&r); - } - - SetListPositions(pParent->m_Children); // correct list position in target list -} - -void SvTreeList::GetInsertionPos( SvTreeListEntry const * pEntry, SvTreeListEntry* pParent, - sal_uLong& rPos ) -{ - DBG_ASSERT(pEntry,"No Entry"); - - if( eSortMode == SortNone ) - return; - - rPos = TREELIST_ENTRY_NOTFOUND; - const SvTreeListEntries& rChildList = GetChildList(pParent); - - if (rChildList.empty()) - return; - - long i = 0; - long j = rChildList.size()-1; - long k; - sal_Int32 nCompare = 1; - - do - { - k = (i+j)/2; - const SvTreeListEntry* pTempEntry = rChildList[k].get(); - nCompare = Compare( pEntry, pTempEntry ); - if( eSortMode == SortDescending && nCompare != 0 ) - { - if( nCompare < 0 ) - nCompare = 1; - else - nCompare = -1; - } - if( nCompare > 0 ) - i = k + 1; - else - j = k - 1; - } while( (nCompare != 0) && (i <= j) ); - - if( nCompare != 0 ) - { - if (i > static_cast<long>(rChildList.size()-1)) // not found, end of list - rPos = TREELIST_ENTRY_NOTFOUND; - else - rPos = i; // not found, middle of list - } - else - rPos = k; -} - -bool SvTreeList::HasChildren( const SvTreeListEntry* pEntry ) const -{ - if ( !pEntry ) - pEntry = pRootItem.get(); - - return !pEntry->m_Children.empty(); -} - -bool SvTreeList::HasParent( const SvTreeListEntry* pEntry ) const -{ - return pEntry->pParent != pRootItem.get(); -} - -SvTreeListEntry* SvTreeList::GetEntry( SvTreeListEntry* pParent, sal_uLong nPos ) const -{ if ( !pParent ) - pParent = pRootItem.get(); - SvTreeListEntry* pRet = nullptr; - if (nPos < pParent->m_Children.size()) - pRet = pParent->m_Children[nPos].get(); - return pRet; -} - -SvTreeListEntry* SvTreeList::GetEntry( sal_uLong nRootPos ) const -{ - SvTreeListEntry* pRet = nullptr; - if (nEntryCount && nRootPos < pRootItem->m_Children.size()) - pRet = pRootItem->m_Children[nRootPos].get(); - return pRet; -} - -const SvTreeListEntries& SvTreeList::GetChildList( SvTreeListEntry* pParent ) const -{ - if ( !pParent ) - pParent = pRootItem.get(); - return pParent->m_Children; -} - -SvTreeListEntries& SvTreeList::GetChildList( SvTreeListEntry* pParent ) -{ - if ( !pParent ) - pParent = pRootItem.get(); - return pParent->m_Children; -} - -const SvTreeListEntry* SvTreeList::GetParent( const SvTreeListEntry* pEntry ) const -{ - const SvTreeListEntry* pParent = pEntry->pParent; - if (pParent == pRootItem.get()) - pParent = nullptr; - return pParent; -} - -SvTreeListEntry* SvTreeList::GetParent( SvTreeListEntry* pEntry ) -{ - SvTreeListEntry* pParent = pEntry->pParent; - if (pParent == pRootItem.get()) - pParent = nullptr; - return pParent; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/contnr/treelistbox.cxx b/svtools/source/contnr/treelistbox.cxx deleted file mode 100644 index 190af932b858..000000000000 --- a/svtools/source/contnr/treelistbox.cxx +++ /dev/null @@ -1,3686 +0,0 @@ -/* -*- 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 . - */ - -/* - TODO: - - delete anchor in SelectionEngine when selecting manually - - SelectAll( false ) => only repaint the deselected entries -*/ - -#include <svtools/treelistbox.hxx> -#include <com/sun/star/accessibility/AccessibleStateType.hpp> -#include <vcl/svapp.hxx> -#include <vcl/accel.hxx> -#include <vcl/i18nhelp.hxx> -#include <vcl/builderfactory.hxx> -#include <vcl/settings.hxx> -#include <sot/formats.hxx> -#include <unotools/accessiblestatesethelper.hxx> -#include <rtl/instance.hxx> -#include <comphelper/string.hxx> -#include <sal/log.hxx> - -#include <svtools/svmedit.hxx> -#include <svtools/svlbitm.hxx> -#include <svtools/treelistentry.hxx> -#include <svtools/viewdataentry.hxx> -#include <svimpbox.hxx> -#include <uitest/uiobject.hxx> - -#include <set> -#include <string.h> -#include <vector> -#include <o3tl/make_unique.hxx> -using namespace css::accessibility; - -// Drag&Drop -static VclPtr<SvTreeListBox> g_pDDSource; -static VclPtr<SvTreeListBox> g_pDDTarget; - -#define SVLBOX_ACC_RETURN 1 -#define SVLBOX_ACC_ESCAPE 2 - -// *************************************************************** - -class MyEdit_Impl : public Edit -{ - SvInplaceEdit2* pOwner; -public: - MyEdit_Impl( vcl::Window* pParent, SvInplaceEdit2* pOwner ); - virtual ~MyEdit_Impl() override { disposeOnce(); } - virtual void dispose() override { pOwner = nullptr; Edit::dispose(); } - virtual void KeyInput( const KeyEvent& rKEvt ) override; - virtual void LoseFocus() override; -}; - -MyEdit_Impl::MyEdit_Impl( vcl::Window* pParent, SvInplaceEdit2* _pOwner ) : - - Edit( pParent, WB_LEFT ), - - pOwner( _pOwner ) - -{ -} - -void MyEdit_Impl::KeyInput( const KeyEvent& rKEvt ) -{ - if( !pOwner->KeyInput( rKEvt )) - Edit::KeyInput( rKEvt ); -} - -void MyEdit_Impl::LoseFocus() -{ - if (pOwner) - pOwner->LoseFocus(); -} - -SvInplaceEdit2::SvInplaceEdit2 -( - vcl::Window* pParent, const Point& rPos, - const Size& rSize, - const OUString& rData, - const Link<SvInplaceEdit2&,void>& rNotifyEditEnd, - const Selection& rSelection -) : - - aCallBackHdl ( rNotifyEditEnd ), - bCanceled ( false ), - bAlreadyInCallBack ( false ) - -{ - - pEdit = VclPtr<MyEdit_Impl>::Create( pParent, this ); - - vcl::Font aFont( pParent->GetFont() ); - aFont.SetTransparent( false ); - Color aColor( pParent->GetBackground().GetColor() ); - aFont.SetFillColor(aColor ); - pEdit->SetFont( aFont ); - pEdit->SetBackground( pParent->GetBackground() ); - pEdit->SetPosPixel( rPos ); - pEdit->SetSizePixel( rSize ); - pEdit->SetText( rData ); - pEdit->SetSelection( rSelection ); - pEdit->SaveValue(); - - aAccReturn.InsertItem( SVLBOX_ACC_RETURN, vcl::KeyCode(KEY_RETURN) ); - aAccEscape.InsertItem( SVLBOX_ACC_ESCAPE, vcl::KeyCode(KEY_ESCAPE) ); - - aAccReturn.SetActivateHdl( LINK( this, SvInplaceEdit2, ReturnHdl_Impl) ); - aAccEscape.SetActivateHdl( LINK( this, SvInplaceEdit2, EscapeHdl_Impl) ); - Application::InsertAccel( &aAccReturn ); - Application::InsertAccel( &aAccEscape ); - - pEdit->Show(); - pEdit->GrabFocus(); -} - -SvInplaceEdit2::~SvInplaceEdit2() -{ - if( !bAlreadyInCallBack ) - { - Application::RemoveAccel( &aAccReturn ); - Application::RemoveAccel( &aAccEscape ); - } - pEdit.disposeAndClear(); -} - -OUString const & SvInplaceEdit2::GetSavedValue() const -{ - return pEdit->GetSavedValue(); -} - -void SvInplaceEdit2::Hide() -{ - pEdit->Hide(); -} - - -IMPL_LINK_NOARG(SvInplaceEdit2, ReturnHdl_Impl, Accelerator&, void) -{ - bCanceled = false; - CallCallBackHdl_Impl(); -} - -IMPL_LINK_NOARG(SvInplaceEdit2, EscapeHdl_Impl, Accelerator&, void) -{ - bCanceled = true; - CallCallBackHdl_Impl(); -} - -bool SvInplaceEdit2::KeyInput( const KeyEvent& rKEvt ) -{ - vcl::KeyCode aCode = rKEvt.GetKeyCode(); - sal_uInt16 nCode = aCode.GetCode(); - - switch ( nCode ) - { - case KEY_ESCAPE: - bCanceled = true; - CallCallBackHdl_Impl(); - return true; - - case KEY_RETURN: - bCanceled = false; - CallCallBackHdl_Impl(); - return true; - } - return false; -} - -void SvInplaceEdit2::StopEditing( bool bCancel ) -{ - if ( !bAlreadyInCallBack ) - { - bCanceled = bCancel; - CallCallBackHdl_Impl(); - } -} - -void SvInplaceEdit2::LoseFocus() -{ - if ( !bAlreadyInCallBack - && ((!Application::GetFocusWindow()) || !pEdit->IsChild( Application::GetFocusWindow()) ) - ) - { - bCanceled = false; - aIdle.SetPriority(TaskPriority::REPAINT); - aIdle.SetInvokeHandler(LINK(this,SvInplaceEdit2,Timeout_Impl)); - aIdle.SetDebugName( "svtools::SvInplaceEdit2 aIdle" ); - aIdle.Start(); - } -} - -IMPL_LINK_NOARG(SvInplaceEdit2, Timeout_Impl, Timer *, void) -{ - CallCallBackHdl_Impl(); -} - -void SvInplaceEdit2::CallCallBackHdl_Impl() -{ - aIdle.Stop(); - if ( !bAlreadyInCallBack ) - { - bAlreadyInCallBack = true; - Application::RemoveAccel( &aAccReturn ); - Application::RemoveAccel( &aAccEscape ); - pEdit->Hide(); - aCallBackHdl.Call( *this ); - } -} - -OUString SvInplaceEdit2::GetText() const -{ - return pEdit->GetText(); -} - -// *************************************************************** -// class SvLBoxTab -// *************************************************************** - - -SvLBoxTab::SvLBoxTab() -{ - nPos = 0; - nFlags = SvLBoxTabFlags::NONE; -} - -SvLBoxTab::SvLBoxTab( long nPosition, SvLBoxTabFlags nTabFlags ) -{ - nPos = nPosition; - nFlags = nTabFlags; -} - -SvLBoxTab::SvLBoxTab( const SvLBoxTab& rTab ) -{ - nPos = rTab.nPos; - nFlags = rTab.nFlags; -} - -SvLBoxTab::~SvLBoxTab() -{ -} - - -long SvLBoxTab::CalcOffset( long nItemWidth, long nTabWidth ) -{ - long nOffset = 0; - if ( nFlags & SvLBoxTabFlags::ADJUST_RIGHT ) - { - nOffset = nTabWidth - nItemWidth; - if( nOffset < 0 ) - nOffset = 0; - } - else if ( nFlags & SvLBoxTabFlags::ADJUST_CENTER ) - { - if( nFlags & SvLBoxTabFlags::FORCE ) - { - // correct implementation of centering - nOffset = ( nTabWidth - nItemWidth ) / 2; - if( nOffset < 0 ) - nOffset = 0; - } - else - { - // historically grown, wrong calculation of tabs which is needed by - // Abo-Tabbox, Tools/Options/Customize etc. - nItemWidth++; - nOffset = -( nItemWidth / 2 ); - } - } - return nOffset; -} - -// *************************************************************** -// class SvLBoxItem -// *************************************************************** - - -SvLBoxItem::SvLBoxItem() -{ -} - -SvLBoxItem::~SvLBoxItem() -{ -} - -const Size& SvLBoxItem::GetSize(const SvTreeListBox* pView, const SvTreeListEntry* pEntry) const -{ - const SvViewDataItem* pViewData = pView->GetViewDataItem( pEntry, this ); - return pViewData->maSize; -} - -const Size& SvLBoxItem::GetSize(const SvViewDataEntry* pData, sal_uInt16 nItemPos) -{ - const SvViewDataItem& rIData = pData->GetItem(nItemPos); - return rIData.maSize; -} - -struct SvTreeListBoxImpl -{ - bool m_bIsEmptyTextAllowed:1; - bool m_bEntryMnemonicsEnabled:1; - bool m_bDoingQuickSelection:1; - - vcl::MnemonicEngine m_aMnemonicEngine; - vcl::QuickSelectionEngine m_aQuickSelectionEngine; - - explicit SvTreeListBoxImpl(SvTreeListBox& _rBox) : - m_bIsEmptyTextAllowed(true), - m_bEntryMnemonicsEnabled(false), - m_bDoingQuickSelection(false), - m_aMnemonicEngine(_rBox), - m_aQuickSelectionEngine(_rBox) {} -}; - - -SvTreeListBox::SvTreeListBox(vcl::Window* pParent, WinBits nWinStyle) : - Control(pParent, nWinStyle | WB_CLIPCHILDREN), - DropTargetHelper(this), - DragSourceHelper(this), - mpImpl(new SvTreeListBoxImpl(*this)), - mbContextBmpExpanded(false), - mbAlternatingRowColors(false), - mbUpdateAlternatingRows(false), - mbQuickSearch(false), - eSelMode(SelectionMode::NONE), - nMinWidthInChars(0), - mbCenterAndClipText(false) -{ - nDragOptions = DND_ACTION_COPYMOVE | DND_ACTION_LINK; - nImpFlags = SvTreeListBoxFlags::NONE; - pTargetEntry = nullptr; - nDragDropMode = DragDropMode::NONE; - SvTreeList* pTempModel = new SvTreeList; - pTempModel->SetRefCount( 0 ); - SetBaseModel(pTempModel); - pModel->SetCloneLink( LINK(this, SvTreeListBox, CloneHdl_Impl )); - pModel->InsertView( this ); - pHdlEntry = nullptr; - eSelMode = SelectionMode::Single; - nDragDropMode = DragDropMode::NONE; - SetType(WindowType::TREELISTBOX); - - InitTreeView(); - - SetSublistOpenWithLeftRight(); -} - -VCL_BUILDER_FACTORY_CONSTRUCTOR(SvTreeListBox, WB_TABSTOP) - -void SvTreeListBox::Clear() -{ - if (pModel) - pModel->Clear(); // Model calls SvTreeListBox::ModelHasCleared() -} - -void SvTreeListBox::EnableEntryMnemonics() -{ - if ( IsEntryMnemonicsEnabled() ) - return; - - mpImpl->m_bEntryMnemonicsEnabled = true; - Invalidate(); -} - -bool SvTreeListBox::IsEntryMnemonicsEnabled() const -{ - return mpImpl->m_bEntryMnemonicsEnabled; -} - -IMPL_LINK( SvTreeListBox, CloneHdl_Impl, SvTreeListEntry*, pEntry, SvTreeListEntry* ) -{ - return CloneEntry(pEntry); -} - -sal_uLong SvTreeListBox::Insert( SvTreeListEntry* pEntry, SvTreeListEntry* pParent, sal_uLong nPos ) -{ - sal_uLong nInsPos = pModel->Insert( pEntry, pParent, nPos ); - pEntry->SetBackColor( GetBackground().GetColor() ); - SetAlternatingRowColors( mbAlternatingRowColors ); - return nInsPos; -} - -sal_uLong SvTreeListBox::Insert( SvTreeListEntry* pEntry,sal_uLong nRootPos ) -{ - sal_uLong nInsPos = pModel->Insert( pEntry, nRootPos ); - pEntry->SetBackColor( GetBackground().GetColor() ); - SetAlternatingRowColors( mbAlternatingRowColors ); - return nInsPos; -} - -bool SvTreeListBox::ExpandingHdl() -{ - return !aExpandingHdl.IsSet() || aExpandingHdl.Call( this ); -} - -void SvTreeListBox::ExpandedHdl() -{ - aExpandedHdl.Call( this ); -} - -void SvTreeListBox::SelectHdl() -{ - aSelectHdl.Call( this ); -} - -void SvTreeListBox::DeselectHdl() -{ - aDeselectHdl.Call( this ); -} - -bool SvTreeListBox::DoubleClickHdl() -{ - return !aDoubleClickHdl.IsSet() || aDoubleClickHdl.Call(this); -} - - -bool SvTreeListBox::CheckDragAndDropMode( SvTreeListBox const * pSource, sal_Int8 nAction ) -{ - if ( pSource == this ) - { - if ( !(nDragDropMode & (DragDropMode::CTRL_MOVE | DragDropMode::CTRL_COPY) ) ) - return false; // D&D locked within list - if( DND_ACTION_MOVE == nAction ) - { - if ( !(nDragDropMode & DragDropMode::CTRL_MOVE) ) - return false; // no local move - } - else - { - if ( !(nDragDropMode & DragDropMode::CTRL_COPY)) - return false; // no local copy - } - } - else - { - if ( !(nDragDropMode & DragDropMode::APP_DROP ) ) - return false; // no drop - if ( DND_ACTION_MOVE == nAction ) - { - if ( !(nDragDropMode & DragDropMode::APP_MOVE) ) - return false; // no global move - } - else - { - if ( !(nDragDropMode & DragDropMode::APP_COPY)) - return false; // no global copy - } - } - return true; -} - - -/* - NotifyMoving/Copying - ==================== - - default behavior: - - 1. target doesn't have children - - entry becomes sibling of target. entry comes after target - (->Window: below the target) - 2. target is an expanded parent - - entry inserted at the beginning of the target childlist - 3. target is a collapsed parent - - entry is inserted at the end of the target childlist -*/ -TriState SvTreeListBox::NotifyMoving( - SvTreeListEntry* pTarget, // D&D dropping position in GetModel() - SvTreeListEntry* pEntry, // entry that we want to move, from - // GetSourceListBox()->GetModel() - SvTreeListEntry*& rpNewParent, // new target parent - sal_uLong& rNewChildPos) // position in childlist of target parent -{ - DBG_ASSERT(pEntry,"NotifyMoving:SourceEntry?"); - if( !pTarget ) - { - rpNewParent = nullptr; - rNewChildPos = 0; - return TRISTATE_TRUE; - } - if ( !pTarget->HasChildren() && !pTarget->HasChildrenOnDemand() ) - { - // case 1 - rpNewParent = GetParent( pTarget ); - rNewChildPos = SvTreeList::GetRelPos( pTarget ) + 1; - rNewChildPos += nCurEntrySelPos; - nCurEntrySelPos++; - } - else - { - // cases 2 & 3 - rpNewParent = pTarget; - if( IsExpanded(pTarget)) - rNewChildPos = 0; - else - rNewChildPos = TREELIST_APPEND; - } - return TRISTATE_TRUE; -} - -TriState SvTreeListBox::NotifyCopying( - SvTreeListEntry* pTarget, // D&D dropping position in GetModel() - SvTreeListEntry* pEntry, // entry that we want to move, from - // GetSourceListBox()->GetModel() - SvTreeListEntry*& rpNewParent, // new target parent - sal_uLong& rNewChildPos) // position in childlist of target parent -{ - return NotifyMoving(pTarget,pEntry,rpNewParent,rNewChildPos); -} - -SvTreeListEntry* SvTreeListBox::FirstChild( SvTreeListEntry* pParent ) const -{ - return pModel->FirstChild(pParent); -} - -// return: all entries copied -bool SvTreeListBox::CopySelection( SvTreeListBox* pSource, SvTreeListEntry* pTarget ) -{ - nCurEntrySelPos = 0; // selection counter for NotifyMoving/Copying - bool bSuccess = true; - std::vector<SvTreeListEntry*> aList; - bool bClone = ( pSource->GetModel() != GetModel() ); - Link<SvTreeListEntry*,SvTreeListEntry*> aCloneLink( pModel->GetCloneLink() ); - pModel->SetCloneLink( LINK(this, SvTreeListBox, CloneHdl_Impl )); - - // cache selection to simplify iterating over the selection when doing a D&D - // exchange within the same listbox - SvTreeListEntry* pSourceEntry = pSource->FirstSelected(); - while ( pSourceEntry ) - { - // children are copied automatically - pSource->SelectChildren( pSourceEntry, false ); - aList.push_back( pSourceEntry ); - pSourceEntry = pSource->NextSelected( pSourceEntry ); - } - - for (auto const& elem : aList) - { - pSourceEntry = elem; - SvTreeListEntry* pNewParent = nullptr; - sal_uLong nInsertionPos = TREELIST_APPEND; - TriState nOk = NotifyCopying(pTarget,pSourceEntry,pNewParent,nInsertionPos); - if ( nOk ) - { - if ( bClone ) - { - sal_uLong nCloneCount = 0; - pSourceEntry = pModel->Clone(pSourceEntry, nCloneCount); - pModel->InsertTree(pSourceEntry, pNewParent, nInsertionPos); - } - else - { - sal_uLong nListPos = pModel->Copy(pSourceEntry, pNewParent, nInsertionPos); - pSourceEntry = GetEntry( pNewParent, nListPos ); - } - } - else - bSuccess = false; - - if (nOk == TRISTATE_INDET) // HACK: make visible moved entry - MakeVisible( pSourceEntry ); - } - pModel->SetCloneLink( aCloneLink ); - return bSuccess; -} - -// return: all entries were moved -bool SvTreeListBox::MoveSelectionCopyFallbackPossible( SvTreeListBox* pSource, SvTreeListEntry* pTarget, bool bAllowCopyFallback ) -{ - nCurEntrySelPos = 0; // selection counter for NotifyMoving/Copying - bool bSuccess = true; - std::vector<SvTreeListEntry*> aList; - bool bClone = ( pSource->GetModel() != GetModel() ); - Link<SvTreeListEntry*,SvTreeListEntry*> aCloneLink( pModel->GetCloneLink() ); - if ( bClone ) - pModel->SetCloneLink( LINK(this, SvTreeListBox, CloneHdl_Impl )); - - SvTreeListEntry* pSourceEntry = pSource->FirstSelected(); - while ( pSourceEntry ) - { - // children are automatically moved - pSource->SelectChildren( pSourceEntry, false ); - aList.push_back( pSourceEntry ); - pSourceEntry = pSource->NextSelected( pSourceEntry ); - } - - for (auto const& elem : aList) - { - pSourceEntry = elem; - SvTreeListEntry* pNewParent = nullptr; - sal_uLong nInsertionPos = TREELIST_APPEND; - TriState nOk = NotifyMoving(pTarget,pSourceEntry,pNewParent,nInsertionPos); - TriState nCopyOk = nOk; - if ( !nOk && bAllowCopyFallback ) - { - nInsertionPos = TREELIST_APPEND; - nCopyOk = NotifyCopying(pTarget,pSourceEntry,pNewParent,nInsertionPos); - } - - if ( nOk || nCopyOk ) - { - if ( bClone ) - { - sal_uLong nCloneCount = 0; - pSourceEntry = pModel->Clone(pSourceEntry, nCloneCount); - pModel->InsertTree(pSourceEntry, pNewParent, nInsertionPos); - } - else - { - if ( nOk ) - pModel->Move(pSourceEntry, pNewParent, nInsertionPos); - else - pModel->Copy(pSourceEntry, pNewParent, nInsertionPos); - } - } - else - bSuccess = false; - - if (nOk == TRISTATE_INDET) // HACK: make moved entry visible - MakeVisible( pSourceEntry ); - } - pModel->SetCloneLink( aCloneLink ); - return bSuccess; -} - -void SvTreeListBox::RemoveSelection() -{ - std::vector<const SvTreeListEntry*> aList; - // cache selection, as the implementation deselects everything on the first - // remove - SvTreeListEntry* pEntry = FirstSelected(); - while ( pEntry ) - { - aList.push_back( pEntry ); - if ( pEntry->HasChildren() ) - // remove deletes all children automatically - SelectChildren(pEntry, false); - pEntry = NextSelected( pEntry ); - } - - for (auto const& elem : aList) - pModel->Remove(elem); -} - -void SvTreeListBox::RemoveEntry(SvTreeListEntry const * pEntry) -{ - pModel->Remove(pEntry); -} - -void SvTreeListBox::RecalcViewData() -{ - SvTreeListEntry* pEntry = First(); - while( pEntry ) - { - sal_uInt16 nCount = pEntry->ItemCount(); - sal_uInt16 nCurPos = 0; - while ( nCurPos < nCount ) - { - SvLBoxItem& rItem = pEntry->GetItem( nCurPos ); - rItem.InitViewData( this, pEntry ); - nCurPos++; - } - pEntry = Next( pEntry ); - } -} - -void SvTreeListBox::ImplShowTargetEmphasis( SvTreeListEntry* pEntry, bool bShow) -{ - if ( bShow && (nImpFlags & SvTreeListBoxFlags::TARGEMPH_VIS) ) - return; - if ( !bShow && !(nImpFlags & SvTreeListBoxFlags::TARGEMPH_VIS) ) - return; - pImpl->PaintDDCursor( pEntry ); - if( bShow ) - nImpFlags |= SvTreeListBoxFlags::TARGEMPH_VIS; - else - nImpFlags &= ~SvTreeListBoxFlags::TARGEMPH_VIS; -} - -void SvTreeListBox::OnCurrentEntryChanged() -{ - if ( !mpImpl->m_bDoingQuickSelection ) - mpImpl->m_aQuickSelectionEngine.Reset(); -} - -SvTreeListEntry* SvTreeListBox::GetEntry( SvTreeListEntry* pParent, sal_uLong nPos ) const -{ - return pModel->GetEntry(pParent, nPos); -} - -SvTreeListEntry* SvTreeListBox::GetEntry( sal_uLong nRootPos ) const -{ - return pModel->GetEntry(nRootPos); -} - -SvTreeListEntry* SvTreeListBox::GetEntryFromPath( const ::std::deque< sal_Int32 >& _rPath ) const -{ - - SvTreeListEntry* pEntry = nullptr; - SvTreeListEntry* pParent = nullptr; - for (auto const& elem : _rPath) - { - pEntry = GetEntry( pParent, elem ); - if ( !pEntry ) - break; - pParent = pEntry; - } - - return pEntry; -} - -void SvTreeListBox::FillEntryPath( SvTreeListEntry* pEntry, ::std::deque< sal_Int32 >& _rPath ) const -{ - - if ( !pEntry ) - return; - - SvTreeListEntry* pParentEntry = GetParent( pEntry ); - while ( true ) - { - sal_uLong i, nCount = GetLevelChildCount( pParentEntry ); - for ( i = 0; i < nCount; ++i ) - { - SvTreeListEntry* pTemp = GetEntry( pParentEntry, i ); - DBG_ASSERT( pEntry, "invalid entry" ); - if ( pEntry == pTemp ) - { - _rPath.push_front( static_cast<sal_Int32>(i) ); - break; - } - } - - if ( pParentEntry ) - { - pEntry = pParentEntry; - pParentEntry = GetParent( pParentEntry ); - } - else - break; - } -} - -const SvTreeListEntry* SvTreeListBox::GetParent( const SvTreeListEntry* pEntry ) const -{ - return pModel->GetParent(pEntry); -} - -SvTreeListEntry* SvTreeListBox::GetParent( SvTreeListEntry* pEntry ) const -{ - return pModel->GetParent(pEntry); -} - -SvTreeListEntry* SvTreeListBox::GetRootLevelParent( SvTreeListEntry* pEntry ) const -{ - return pModel->GetRootLevelParent(pEntry); -} - -sal_uLong SvTreeListBox::GetChildCount( SvTreeListEntry const * pParent ) const -{ - return pModel->GetChildCount(pParent); -} - -sal_uLong SvTreeListBox::GetLevelChildCount( SvTreeListEntry* _pParent ) const -{ - - //if _pParent is 0, then pEntry is the first child of the root. - SvTreeListEntry* pEntry = FirstChild( _pParent ); - - if( !pEntry )//there is only root, root don't have children - return 0; - - if( !_pParent )//root and children of root - return pEntry->pParent->m_Children.size(); - - return _pParent->m_Children.size(); -} - -SvViewDataEntry* SvTreeListBox::GetViewDataEntry( SvTreeListEntry const * pEntry ) const -{ - return const_cast<SvViewDataEntry*>(SvListView::GetViewData(pEntry)); -} - -SvViewDataItem* SvTreeListBox::GetViewDataItem(SvTreeListEntry const * pEntry, SvLBoxItem const * pItem) -{ - return const_cast<SvViewDataItem*>(static_cast<const SvTreeListBox*>(this)->GetViewDataItem(pEntry, pItem)); -} - -const SvViewDataItem* SvTreeListBox::GetViewDataItem(const SvTreeListEntry* pEntry, const SvLBoxItem* pItem) const -{ - const SvViewDataEntry* pEntryData = SvListView::GetViewData(pEntry); - assert(pEntryData && "Entry not in View"); - sal_uInt16 nItemPos = pEntry->GetPos(pItem); - return &pEntryData->GetItem(nItemPos); -} - -std::unique_ptr<SvViewDataEntry> SvTreeListBox::CreateViewData( SvTreeListEntry* ) -{ - return o3tl::make_unique<SvViewDataEntry>(); -} - -void SvTreeListBox::InitViewData( SvViewDataEntry* pData, SvTreeListEntry* pEntry ) -{ - SvTreeListEntry* pInhEntry = pEntry; - SvViewDataEntry* pEntryData = pData; - - pEntryData->Init(pInhEntry->ItemCount()); - sal_uInt16 nCount = pInhEntry->ItemCount(); - sal_uInt16 nCurPos = 0; - while( nCurPos < nCount ) - { - SvLBoxItem& rItem = pInhEntry->GetItem( nCurPos ); - SvViewDataItem& rItemData = pEntryData->GetItem(nCurPos); - rItem.InitViewData( this, pInhEntry, &rItemData ); - nCurPos++; - } -} - -void SvTreeListBox::EnableSelectionAsDropTarget( bool bEnable ) -{ - sal_uInt16 nRefDepth; - SvTreeListEntry* pTemp; - - SvTreeListEntry* pSelEntry = FirstSelected(); - while( pSelEntry ) - { - if ( !bEnable ) - { - pSelEntry->nEntryFlags |= SvTLEntryFlags::DISABLE_DROP; - nRefDepth = pModel->GetDepth( pSelEntry ); - pTemp = Next( pSelEntry ); - while( pTemp && pModel->GetDepth( pTemp ) > nRefDepth ) - { - pTemp->nEntryFlags |= SvTLEntryFlags::DISABLE_DROP; - pTemp = Next( pTemp ); - } - } - else - { - pSelEntry->nEntryFlags &= (~SvTLEntryFlags::DISABLE_DROP); - nRefDepth = pModel->GetDepth( pSelEntry ); - pTemp = Next( pSelEntry ); - while( pTemp && pModel->GetDepth( pTemp ) > nRefDepth ) - { - pTemp->nEntryFlags &= (~SvTLEntryFlags::DISABLE_DROP); - pTemp = Next( pTemp ); - } - } - pSelEntry = NextSelected( pSelEntry ); - } -} - -// ****************************************************************** -// InplaceEditing -// ****************************************************************** - -void SvTreeListBox::EditText( const OUString& rStr, const tools::Rectangle& rRect, - const Selection& rSel ) -{ - pEdCtrl.reset(); - nImpFlags |= SvTreeListBoxFlags::IN_EDT; - nImpFlags &= ~SvTreeListBoxFlags::EDTEND_CALLED; - HideFocus(); - pEdCtrl.reset( new SvInplaceEdit2( - this, rRect.TopLeft(), rRect.GetSize(), rStr, - LINK( this, SvTreeListBox, TextEditEndedHdl_Impl ), - rSel ) ); -} - -IMPL_LINK_NOARG(SvTreeListBox, TextEditEndedHdl_Impl, SvInplaceEdit2&, void) -{ - if ( nImpFlags & SvTreeListBoxFlags::EDTEND_CALLED ) // avoid nesting - return; - nImpFlags |= SvTreeListBoxFlags::EDTEND_CALLED; - OUString aStr; - if ( !pEdCtrl->EditingCanceled() ) - aStr = pEdCtrl->GetText(); - else - aStr = pEdCtrl->GetSavedValue(); - if ( mpImpl->m_bIsEmptyTextAllowed || !aStr.isEmpty() ) - EditedText( aStr ); - // Hide may only be called after the new text was put into the entry, so - // that we don't call the selection handler in the GetFocus of the listbox - // with the old entry text. - pEdCtrl->Hide(); - nImpFlags &= (~SvTreeListBoxFlags::IN_EDT); - GrabFocus(); -} - -void SvTreeListBox::CancelTextEditing() -{ - if ( pEdCtrl ) - pEdCtrl->StopEditing( true ); - nImpFlags &= (~SvTreeListBoxFlags::IN_EDT); -} - -void SvTreeListBox::EndEditing( bool bCancel ) -{ - if( pEdCtrl ) - pEdCtrl->StopEditing( bCancel ); - nImpFlags &= (~SvTreeListBoxFlags::IN_EDT); -} - - -void SvTreeListBox::ForbidEmptyText() -{ - mpImpl->m_bIsEmptyTextAllowed = false; -} - -SvTreeListEntry* SvTreeListBox::CreateEntry() const -{ - return new SvTreeListEntry; -} - -const void* SvTreeListBox::FirstSearchEntry( OUString& _rEntryText ) const -{ - SvTreeListEntry* pEntry = GetCurEntry(); - if ( pEntry ) - pEntry = const_cast< SvTreeListEntry* >( static_cast< const SvTreeListEntry* >( NextSearchEntry( pEntry, _rEntryText ) ) ); - else - { - pEntry = FirstSelected(); - if ( !pEntry ) - pEntry = First(); - } - - if ( pEntry ) - _rEntryText = GetEntryText( pEntry ); - - return pEntry; -} - -const void* SvTreeListBox::NextSearchEntry( const void* _pCurrentSearchEntry, OUString& _rEntryText ) const -{ - SvTreeListEntry* pEntry = const_cast< SvTreeListEntry* >( static_cast< const SvTreeListEntry* >( _pCurrentSearchEntry ) ); - - if ( ( ( GetChildCount( pEntry ) > 0 ) - || ( pEntry->HasChildrenOnDemand() ) - ) - && !IsExpanded( pEntry ) - ) - { - pEntry = pEntry->NextSibling(); - } - else - { - pEntry = Next( pEntry ); - } - - if ( !pEntry ) - pEntry = First(); - - if ( pEntry ) - _rEntryText = GetEntryText( pEntry ); - - return pEntry; -} - -void SvTreeListBox::SelectSearchEntry( const void* _pEntry ) -{ - SvTreeListEntry* pEntry = const_cast< SvTreeListEntry* >( static_cast< const SvTreeListEntry* >( _pEntry ) ); - DBG_ASSERT( pEntry, "SvTreeListBox::SelectSearchEntry: invalid entry!" ); - if ( !pEntry ) - return; - - SelectAll( false ); - SetCurEntry( pEntry ); - Select( pEntry ); -} - -void SvTreeListBox::ExecuteSearchEntry( const void* /*_pEntry*/ ) const -{ - // nothing to do here, we have no "execution" -} - -vcl::StringEntryIdentifier SvTreeListBox::CurrentEntry( OUString& _out_entryText ) const -{ - // always accept the current entry if there is one - SvTreeListEntry* pCurrentEntry( GetCurEntry() ); - if ( pCurrentEntry ) - { - _out_entryText = GetEntryText( pCurrentEntry ); - return pCurrentEntry; - } - return FirstSearchEntry( _out_entryText ); -} - -vcl::StringEntryIdentifier SvTreeListBox::NextEntry( vcl::StringEntryIdentifier _currentEntry, OUString& _out_entryText ) const -{ - return NextSearchEntry( _currentEntry, _out_entryText ); -} - -void SvTreeListBox::SelectEntry( vcl::StringEntryIdentifier _entry ) -{ - SelectSearchEntry( _entry ); -} - -bool SvTreeListBox::HandleKeyInput( const KeyEvent& _rKEvt ) -{ - if ( IsEntryMnemonicsEnabled() - && mpImpl->m_aMnemonicEngine.HandleKeyEvent( _rKEvt ) - ) - return true; - - if (mbQuickSearch) - { - mpImpl->m_bDoingQuickSelection = true; - const bool bHandled = mpImpl->m_aQuickSelectionEngine.HandleKeyEvent( _rKEvt ); - mpImpl->m_bDoingQuickSelection = false; - if ( bHandled ) - return true; - } - - return false; -} - -bool SvTreeListBox::EditingCanceled() const -{ - return pEdCtrl && pEdCtrl->EditingCanceled(); -} - - -//JP 28.3.2001: new Drag & Drop API -sal_Int8 SvTreeListBox::AcceptDrop( const AcceptDropEvent& rEvt ) -{ - sal_Int8 nRet = DND_ACTION_NONE; - - if (rEvt.mbLeaving || !CheckDragAndDropMode(g_pDDSource, rEvt.mnAction)) - { - ImplShowTargetEmphasis( pTargetEntry, false ); - } - else if( nDragDropMode == DragDropMode::NONE ) - { - SAL_WARN( "svtools.contnr", "SvTreeListBox::QueryDrop(): no target" ); - } - else - { - SvTreeListEntry* pEntry = GetDropTarget( rEvt.maPosPixel ); - if( !IsDropFormatSupported( SotClipboardFormatId::TREELISTBOX ) ) - { - SAL_WARN( "svtools.contnr", "SvTreeListBox::QueryDrop(): no format" ); - } - else - { - DBG_ASSERT(g_pDDSource, "SvTreeListBox::QueryDrop(): SourceBox == 0"); - if (!( pEntry && g_pDDSource->GetModel() == GetModel() - && DND_ACTION_MOVE == rEvt.mnAction - && (pEntry->nEntryFlags & SvTLEntryFlags::DISABLE_DROP))) - { - if( NotifyAcceptDrop( pEntry )) - nRet = rEvt.mnAction; - } - } - - // **** draw emphasis **** - if( DND_ACTION_NONE == nRet ) - ImplShowTargetEmphasis( pTargetEntry, false ); - else if( pEntry != pTargetEntry || !(nImpFlags & SvTreeListBoxFlags::TARGEMPH_VIS) ) - { - ImplShowTargetEmphasis( pTargetEntry, false ); - pTargetEntry = pEntry; - ImplShowTargetEmphasis( pTargetEntry, true ); - } - } - return nRet; -} - -sal_Int8 SvTreeListBox::ExecuteDrop( const ExecuteDropEvent& rEvt, SvTreeListBox* pSourceView ) -{ - assert(pSourceView); - pSourceView->EnableSelectionAsDropTarget(); - - ImplShowTargetEmphasis( pTargetEntry, false ); - g_pDDTarget = this; - - TransferableDataHelper aData( rEvt.maDropEvent.Transferable ); - - sal_Int8 nRet; - if( aData.HasFormat( SotClipboardFormatId::TREELISTBOX )) - nRet = rEvt.mnAction; - else - nRet = DND_ACTION_NONE; - - if( DND_ACTION_NONE != nRet ) - { - nRet = DND_ACTION_NONE; - - SvTreeListEntry* pTarget = pTargetEntry; // may be 0! - - if( DND_ACTION_COPY == rEvt.mnAction ) - { - if (CopySelection(g_pDDSource, pTarget)) - nRet = rEvt.mnAction; - } - else if( DND_ACTION_MOVE == rEvt.mnAction ) - { - if (MoveSelectionCopyFallbackPossible( g_pDDSource, pTarget, false )) - nRet = rEvt.mnAction; - } - else if( DND_ACTION_COPYMOVE == rEvt.mnAction ) - { - if (MoveSelectionCopyFallbackPossible(g_pDDSource, pTarget, true)) - nRet = rEvt.mnAction; - } - } - return nRet; -} - -sal_Int8 SvTreeListBox::ExecuteDrop( const ExecuteDropEvent& rEvt ) -{ - return ExecuteDrop( rEvt, g_pDDSource ); -} - -/** - * This sets the global variables used to determine the - * in-process drag source. - */ -void SvTreeListBox::SetupDragOrigin() -{ - g_pDDSource = this; - g_pDDTarget = nullptr; -} - -void SvTreeListBox::StartDrag( sal_Int8, const Point& rPosPixel ) -{ - - Point aEventPos( rPosPixel ); - MouseEvent aMouseEvt( aEventPos, 1, MouseEventModifiers::SELECT, MOUSE_LEFT ); - MouseButtonUp( aMouseEvt ); - - nOldDragMode = GetDragDropMode(); - if ( nOldDragMode == DragDropMode::NONE ) - return; - - ReleaseMouse(); - - SvTreeListEntry* pEntry = GetEntry( rPosPixel ); // GetDropTarget( rPos ); - if( !pEntry ) - { - DragFinished( DND_ACTION_NONE ); - return; - } - - rtl::Reference<TransferDataContainer> pContainer = new TransferDataContainer; - nDragDropMode = NotifyStartDrag( *pContainer, pEntry ); - if( nDragDropMode == DragDropMode::NONE || 0 == GetSelectionCount() ) - { - nDragDropMode = nOldDragMode; - DragFinished( DND_ACTION_NONE ); - return; - } - - SetupDragOrigin(); - - // apparently some (unused) content is needed - pContainer->CopyAnyData( SotClipboardFormatId::TREELISTBOX, - "unused", SAL_N_ELEMENTS("unused") ); - - bool bOldUpdateMode = Control::IsUpdateMode(); - Control::SetUpdateMode( true ); - Update(); - Control::SetUpdateMode( bOldUpdateMode ); - - // Disallow using the selection and its children as drop targets. - // Important: If the selection of the SourceListBox is changed in the - // DropHandler, the entries have to be allowed as drop targets again: - // (GetSourceListBox()->EnableSelectionAsDropTarget( true, true );) - EnableSelectionAsDropTarget( false ); - - pContainer->StartDrag( this, nDragOptions, GetDragFinishedHdl() ); -} - -void SvTreeListBox::DragFinished( sal_Int8 -#ifndef UNX -nAction -#endif -) -{ - EnableSelectionAsDropTarget(); - -#ifndef UNX - if ( (nAction == DND_ACTION_MOVE) - && ( (g_pDDTarget && (g_pDDTarget->GetModel() != GetModel())) - || !g_pDDTarget)) - { - RemoveSelection(); - } -#endif - - ImplShowTargetEmphasis( pTargetEntry, false ); - g_pDDSource = nullptr; - g_pDDTarget = nullptr; - pTargetEntry = nullptr; - nDragDropMode = nOldDragMode; -} - -DragDropMode SvTreeListBox::NotifyStartDrag( TransferDataContainer&, SvTreeListEntry* ) -{ - return DragDropMode(0xffff); -} - -bool SvTreeListBox::NotifyAcceptDrop( SvTreeListEntry* ) -{ - return true; -} - -// Handler and methods for Drag - finished handler. -// The with get GetDragFinishedHdl() get link can set on the -// TransferDataContainer. This link is a callback for the DragFinished -// call. AddBox method is called from the GetDragFinishedHdl() and the -// remove is called in link callback and in the destructor. So it can't -// called to a deleted object. - -namespace -{ - struct SortLBoxes : public rtl::Static<std::set<sal_uLong>, SortLBoxes> {}; -} - -void SvTreeListBox::AddBoxToDDList_Impl( const SvTreeListBox& rB ) -{ - sal_uLong nVal = reinterpret_cast<sal_uLong>(&rB); - SortLBoxes::get().insert( nVal ); -} - -void SvTreeListBox::RemoveBoxFromDDList_Impl( const SvTreeListBox& rB ) -{ - sal_uLong nVal = reinterpret_cast<sal_uLong>(&rB); - SortLBoxes::get().erase( nVal ); -} - -IMPL_LINK( SvTreeListBox, DragFinishHdl_Impl, sal_Int8, nAction, void ) -{ - sal_uLong nVal = reinterpret_cast<sal_uLong>(this); - std::set<sal_uLong> &rSortLBoxes = SortLBoxes::get(); - std::set<sal_uLong>::const_iterator it = rSortLBoxes.find(nVal); - if( it != rSortLBoxes.end() ) - { - DragFinished( nAction ); - rSortLBoxes.erase( it ); - } -} - -Link<sal_Int8,void> SvTreeListBox::GetDragFinishedHdl() const -{ - AddBoxToDDList_Impl( *this ); - return LINK( const_cast<SvTreeListBox*>(this), SvTreeListBox, DragFinishHdl_Impl ); -} - -/* - Bugs/TODO - - - calculate rectangle when editing in-place (bug with some fonts) - - SetSpaceBetweenEntries: offset is not taken into account in SetEntryHeight -*/ - -#define SV_LBOX_DEFAULT_INDENT_PIXEL 20 - -void SvTreeListBox::InitTreeView() -{ - pCheckButtonData = nullptr; - pEdEntry = nullptr; - pEdItem = nullptr; - nEntryHeight = 0; - pEdCtrl = nullptr; - nFirstSelTab = 0; - nLastSelTab = 0; - nFocusWidth = -1; - nAllItemAccRoleType = SvTreeAccRoleType::NONE; - mnCheckboxItemWidth = 0; - - nTreeFlags = SvTreeFlags::RECALCTABS; - nIndent = SV_LBOX_DEFAULT_INDENT_PIXEL; - nEntryHeightOffs = SV_ENTRYHEIGHTOFFS_PIXEL; - pImpl.reset( new SvImpLBox( this, GetModel(), GetStyle() ) ); - - mbContextBmpExpanded = true; - nContextBmpWidthMax = 0; - - SetFont( GetFont() ); - AdjustEntryHeightAndRecalc(); - - SetSpaceBetweenEntries( 0 ); - SetLineColor(); - InitSettings(); - ImplInitStyle(); - SetTabs(); -} - -OUString SvTreeListBox::GetEntryAltText( SvTreeListEntry* ) const -{ - return OUString(); -} - -OUString SvTreeListBox::GetEntryLongDescription( SvTreeListEntry* ) const -{ - return OUString(); -} - -OUString SvTreeListBox::SearchEntryTextWithHeadTitle( SvTreeListEntry* pEntry ) -{ - assert(pEntry); - OUStringBuffer sRet; - - sal_uInt16 nCount = pEntry->ItemCount(); - sal_uInt16 nCur = 0; - while( nCur < nCount ) - { - SvLBoxItem& rItem = pEntry->GetItem( nCur ); - if ( (rItem.GetType() == SvLBoxItemType::String) && - !static_cast<SvLBoxString&>( rItem ).GetText().isEmpty() ) - { - sRet.append(static_cast<SvLBoxString&>( rItem ).GetText()).append(","); - } - nCur++; - } - - if (!sRet.isEmpty()) - sRet = sRet.copy(0, sRet.getLength() - 1); - return sRet.makeStringAndClear(); -} - -SvTreeListBox::~SvTreeListBox() -{ - disposeOnce(); -} - -void SvTreeListBox::dispose() -{ - if( pImpl ) - { - pImpl->CallEventListeners( VclEventId::ObjectDying ); - pImpl.reset(); - } - if( mpImpl ) - { - ClearTabList(); - - pEdCtrl.reset(); - - if( pModel ) - { - pModel->RemoveView( this ); - if ( pModel->GetRefCount() == 0 ) - { - pModel->Clear(); - delete pModel; - pModel = nullptr; - } - } - - SvTreeListBox::RemoveBoxFromDDList_Impl( *this ); - - if (this == g_pDDSource) - g_pDDSource = nullptr; - if (this == g_pDDTarget) - g_pDDTarget = nullptr; - mpImpl.reset(); - } - - DropTargetHelper::dispose(); - DragSourceHelper::dispose(); - Control::dispose(); -} - -void SvTreeListBox::SetNoAutoCurEntry( bool b ) -{ - pImpl->SetNoAutoCurEntry( b ); -} - -void SvTreeListBox::SetModel( SvTreeList* pNewModel ) -{ - pImpl->SetModel( pNewModel ); - SetBaseModel(pNewModel); -} - -void SvTreeListBox::SetBaseModel( SvTreeList* pNewModel ) -{ - // does the CleanUp - SvListView::SetModel( pNewModel ); - pModel->SetCloneLink( LINK(this, SvTreeListBox, CloneHdl_Impl )); - SvTreeListEntry* pEntry = First(); - while( pEntry ) - { - ModelHasInserted( pEntry ); - pEntry = Next( pEntry ); - } -} - -void SvTreeListBox::SetSublistOpenWithReturn() -{ - pImpl->bSubLstOpRet = true; -} - -void SvTreeListBox::SetSublistOpenWithLeftRight() -{ - pImpl->bSubLstOpLR = true; -} - -void SvTreeListBox::SetSublistDontOpenWithDoubleClick(bool bDontOpen) -{ - pImpl->bSubLstOpDblClick = !bDontOpen; -} - -void SvTreeListBox::Resize() -{ - if( IsEditingActive() ) - EndEditing( true ); - - Control::Resize(); - - pImpl->Resize(); - nFocusWidth = -1; - pImpl->ShowCursor( false ); - pImpl->ShowCursor( true ); -} - -/* Cases: - - A) entries have bitmaps - 0. no buttons - 1. node buttons (can optionally also be on root items) - 2. node buttons (can optionally also be on root items) + CheckButton - 3. CheckButton - B) entries don't have bitmaps (=>via WindowBits because of D&D!) - 0. no buttons - 1. node buttons (can optionally also be on root items) - 2. node buttons (can optionally also be on root items) + CheckButton - 3. CheckButton -*/ - -#define NO_BUTTONS 0 -#define NODE_BUTTONS 1 -#define NODE_AND_CHECK_BUTTONS 2 -#define CHECK_BUTTONS 3 - -#define TABFLAGS_TEXT (SvLBoxTabFlags::DYNAMIC | \ - SvLBoxTabFlags::ADJUST_LEFT | \ - SvLBoxTabFlags::EDITABLE | \ - SvLBoxTabFlags::SHOW_SELECTION) - -#define TABFLAGS_CONTEXTBMP (SvLBoxTabFlags::DYNAMIC | SvLBoxTabFlags::ADJUST_CENTER) - -#define TABFLAGS_CHECKBTN (SvLBoxTabFlags::DYNAMIC | \ - SvLBoxTabFlags::ADJUST_CENTER | \ - SvLBoxTabFlags::PUSHABLE) - -#define TAB_STARTPOS 2 - -// take care of GetTextOffset when doing changes -void SvTreeListBox::SetTabs() -{ - if( IsEditingActive() ) - EndEditing( true ); - nTreeFlags &= (~SvTreeFlags::RECALCTABS); - nFocusWidth = -1; - const WinBits nStyle( GetStyle() ); - bool bHasButtons = (nStyle & WB_HASBUTTONS)!=0; - bool bHasButtonsAtRoot = (nStyle & (WB_HASLINESATROOT | - WB_HASBUTTONSATROOT))!=0; - long nStartPos = TAB_STARTPOS; - long nNodeWidthPixel = GetExpandedNodeBmp().GetSizePixel().Width(); - - // pCheckButtonData->Width() knows nothing about the native checkbox width, - // so we have mnCheckboxItemWidth which becomes valid when something is added. - long nCheckWidth = 0; - if( nTreeFlags & SvTreeFlags::CHKBTN ) - nCheckWidth = mnCheckboxItemWidth; - long nCheckWidthDIV2 = nCheckWidth / 2; - - long nContextWidth = nContextBmpWidthMax; - long nContextWidthDIV2 = nContextWidth / 2; - - ClearTabList(); - - int nCase = NO_BUTTONS; - if( !(nTreeFlags & SvTreeFlags::CHKBTN) ) - { - if( bHasButtons ) - nCase = NODE_BUTTONS; - } - else - { - if( bHasButtons ) - nCase = NODE_AND_CHECK_BUTTONS; - else - nCase = CHECK_BUTTONS; - } - - switch( nCase ) - { - case NO_BUTTONS : - nStartPos += nContextWidthDIV2; // because of centering - AddTab( nStartPos, TABFLAGS_CONTEXTBMP ); - nStartPos += nContextWidthDIV2; // right edge of context bitmap - // only set a distance if there are bitmaps - if( nContextBmpWidthMax ) - nStartPos += 5; // distance context bitmap to text - AddTab( nStartPos, TABFLAGS_TEXT ); - break; - - case NODE_BUTTONS : - if( bHasButtonsAtRoot ) - nStartPos += ( nIndent + (nNodeWidthPixel/2) ); - else - nStartPos += nContextWidthDIV2; - AddTab( nStartPos, TABFLAGS_CONTEXTBMP ); - nStartPos += nContextWidthDIV2; // right edge of context bitmap - // only set a distance if there are bitmaps - if( nContextBmpWidthMax ) - nStartPos += 5; // distance context bitmap to text - AddTab( nStartPos, TABFLAGS_TEXT ); - break; - - case NODE_AND_CHECK_BUTTONS : - if( bHasButtonsAtRoot ) - nStartPos += ( nIndent + nNodeWidthPixel ); - else - nStartPos += nCheckWidthDIV2; - AddTab( nStartPos, TABFLAGS_CHECKBTN ); - nStartPos += nCheckWidthDIV2; // right edge of CheckButton - nStartPos += 3; // distance CheckButton to context bitmap - nStartPos += nContextWidthDIV2; // center of context bitmap - AddTab( nStartPos, TABFLAGS_CONTEXTBMP ); - nStartPos += nContextWidthDIV2; // right edge of context bitmap - // only set a distance if there are bitmaps - if( nContextBmpWidthMax ) - nStartPos += 5; // distance context bitmap to text - AddTab( nStartPos, TABFLAGS_TEXT ); - break; - - case CHECK_BUTTONS : - nStartPos += nCheckWidthDIV2; - AddTab( nStartPos, TABFLAGS_CHECKBTN ); - nStartPos += nCheckWidthDIV2; // right edge of CheckButton - nStartPos += 3; // distance CheckButton to context bitmap - nStartPos += nContextWidthDIV2; // center of context bitmap - AddTab( nStartPos, TABFLAGS_CONTEXTBMP ); - nStartPos += nContextWidthDIV2; // right edge of context bitmap - // only set a distance if there are bitmaps - if( nContextBmpWidthMax ) - nStartPos += 5; // distance context bitmap to text - AddTab( nStartPos, TABFLAGS_TEXT ); - break; - } - pImpl->NotifyTabsChanged(); -} - -void SvTreeListBox::InitEntry(SvTreeListEntry* pEntry, - const OUString& aStr, const Image& aCollEntryBmp, const Image& aExpEntryBmp, - SvLBoxButtonKind eButtonKind) -{ - if( nTreeFlags & SvTreeFlags::CHKBTN ) - { - pEntry->AddItem(o3tl::make_unique<SvLBoxButton>(eButtonKind, pCheckButtonData)); - } - - pEntry->AddItem(o3tl::make_unique<SvLBoxContextBmp>( aCollEntryBmp,aExpEntryBmp, mbContextBmpExpanded)); - - pEntry->AddItem(o3tl::make_unique<SvLBoxString>(aStr)); -} - -OUString SvTreeListBox::GetEntryText(SvTreeListEntry* pEntry) const -{ - assert(pEntry); - SvLBoxString* pItem = static_cast<SvLBoxString*>(pEntry->GetFirstItem(SvLBoxItemType::String)); - assert(pItem); - return pItem->GetText(); -} - -const Image& SvTreeListBox::GetExpandedEntryBmp(const SvTreeListEntry* pEntry) -{ - assert(pEntry); - const SvLBoxContextBmp* pItem = static_cast<const SvLBoxContextBmp*>(pEntry->GetFirstItem(SvLBoxItemType::ContextBmp)); - assert(pItem); - return pItem->GetBitmap2( ); -} - -const Image& SvTreeListBox::GetCollapsedEntryBmp( const SvTreeListEntry* pEntry ) -{ - assert(pEntry); - const SvLBoxContextBmp* pItem = static_cast<const SvLBoxContextBmp*>(pEntry->GetFirstItem(SvLBoxItemType::ContextBmp)); - assert(pItem); - return pItem->GetBitmap1( ); -} - -IMPL_LINK( SvTreeListBox, CheckButtonClick, SvLBoxButtonData *, pData, void ) -{ - pHdlEntry = pData->GetActEntry(); - CheckButtonHdl(); -} - -SvTreeListEntry* SvTreeListBox::InsertEntry( - const OUString& rText, - SvTreeListEntry* pParent, - bool bChildrenOnDemand, sal_uLong nPos, - void* pUser, - SvLBoxButtonKind eButtonKind -) -{ - nTreeFlags |= SvTreeFlags::MANINS; - - const Image& rDefExpBmp = pImpl->GetDefaultEntryExpBmp( ); - const Image& rDefColBmp = pImpl->GetDefaultEntryColBmp( ); - - aCurInsertedExpBmp = rDefExpBmp; - aCurInsertedColBmp = rDefColBmp; - - SvTreeListEntry* pEntry = CreateEntry(); - pEntry->SetUserData( pUser ); - InitEntry( pEntry, rText, rDefColBmp, rDefExpBmp, eButtonKind ); - pEntry->EnableChildrenOnDemand( bChildrenOnDemand ); - - if( !pParent ) - Insert( pEntry, nPos ); - else - Insert( pEntry, pParent, nPos ); - - aPrevInsertedExpBmp = rDefExpBmp; - aPrevInsertedColBmp = rDefColBmp; - - nTreeFlags &= (~SvTreeFlags::MANINS); - - return pEntry; -} - -SvTreeListEntry* SvTreeListBox::InsertEntry( const OUString& rText, - const Image& aExpEntryBmp, const Image& aCollEntryBmp, - SvTreeListEntry* pParent, bool bChildrenOnDemand, sal_uLong nPos, void* pUser, - SvLBoxButtonKind eButtonKind ) -{ - nTreeFlags |= SvTreeFlags::MANINS; - - aCurInsertedExpBmp = aExpEntryBmp; - aCurInsertedColBmp = aCollEntryBmp; - - SvTreeListEntry* pEntry = CreateEntry(); - pEntry->SetUserData( pUser ); - InitEntry( pEntry, rText, aCollEntryBmp, aExpEntryBmp, eButtonKind ); - - pEntry->EnableChildrenOnDemand( bChildrenOnDemand ); - - if( !pParent ) - Insert( pEntry, nPos ); - else - Insert( pEntry, pParent, nPos ); - - aPrevInsertedExpBmp = aExpEntryBmp; - aPrevInsertedColBmp = aCollEntryBmp; - - nTreeFlags &= (~SvTreeFlags::MANINS); - - return pEntry; -} - -void SvTreeListBox::SetEntryText(SvTreeListEntry* pEntry, const OUString& rStr) -{ - SvLBoxString* pItem = static_cast<SvLBoxString*>(pEntry->GetFirstItem(SvLBoxItemType::String)); - assert(pItem); - pItem->SetText(rStr); - pItem->InitViewData( this, pEntry ); - GetModel()->InvalidateEntry( pEntry ); -} - -void SvTreeListBox::SetExpandedEntryBmp( SvTreeListEntry* pEntry, const Image& aBmp ) -{ - SvLBoxContextBmp* pItem = static_cast<SvLBoxContextBmp*>(pEntry->GetFirstItem(SvLBoxItemType::ContextBmp)); - - assert(pItem); - pItem->SetBitmap2( aBmp ); - - GetModel()->InvalidateEntry( pEntry ); - SetEntryHeight( pEntry ); - Size aSize = aBmp.GetSizePixel(); - short nWidth = pImpl->UpdateContextBmpWidthVector( pEntry, static_cast<short>(aSize.Width()) ); - if( nWidth > nContextBmpWidthMax ) - { - nContextBmpWidthMax = nWidth; - SetTabs(); - } -} - -void SvTreeListBox::SetCollapsedEntryBmp(SvTreeListEntry* pEntry,const Image& aBmp ) -{ - SvLBoxContextBmp* pItem = static_cast<SvLBoxContextBmp*>(pEntry->GetFirstItem(SvLBoxItemType::ContextBmp)); - - assert(pItem); - pItem->SetBitmap1( aBmp ); - - GetModel()->InvalidateEntry( pEntry ); - SetEntryHeight( pEntry ); - Size aSize = aBmp.GetSizePixel(); - short nWidth = pImpl->UpdateContextBmpWidthVector( pEntry, static_cast<short>(aSize.Width()) ); - if( nWidth > nContextBmpWidthMax ) - { - nContextBmpWidthMax = nWidth; - SetTabs(); - } -} - -void SvTreeListBox::ImpEntryInserted( SvTreeListEntry* pEntry ) -{ - - SvTreeListEntry* pParent = pModel->GetParent( pEntry ); - if( pParent ) - { - SvTLEntryFlags nFlags = pParent->GetFlags(); - nFlags &= ~SvTLEntryFlags::NO_NODEBMP; - pParent->SetFlags( nFlags ); - } - - if(!((nTreeFlags & SvTreeFlags::MANINS) && - (aPrevInsertedExpBmp == aCurInsertedExpBmp) && - (aPrevInsertedColBmp == aCurInsertedColBmp) )) - { - Size aSize = GetCollapsedEntryBmp( pEntry ).GetSizePixel(); - if( aSize.Width() > nContextBmpWidthMax ) - { - nContextBmpWidthMax = static_cast<short>(aSize.Width()); - nTreeFlags |= SvTreeFlags::RECALCTABS; - } - aSize = GetExpandedEntryBmp( pEntry ).GetSizePixel(); - if( aSize.Width() > nContextBmpWidthMax ) - { - nContextBmpWidthMax = static_cast<short>(aSize.Width()); - nTreeFlags |= SvTreeFlags::RECALCTABS; - } - } - SetEntryHeight( pEntry ); - - if( !(nTreeFlags & SvTreeFlags::CHKBTN) ) - return; - - SvLBoxButton* pItem = static_cast<SvLBoxButton*>(pEntry->GetFirstItem(SvLBoxItemType::Button)); - if( pItem ) - { - long nWidth = pItem->GetSize(this, pEntry).Width(); - if( mnCheckboxItemWidth < nWidth ) - { - mnCheckboxItemWidth = nWidth; - nTreeFlags |= SvTreeFlags::RECALCTABS; - } - } -} - - -void SvTreeListBox::SetCheckButtonState( SvTreeListEntry* pEntry, SvButtonState eState) -{ - if( !(nTreeFlags & SvTreeFlags::CHKBTN) ) - return; - - SvLBoxButton* pItem = static_cast<SvLBoxButton*>(pEntry->GetFirstItem(SvLBoxItemType::Button)); - if(!(pItem && pItem->CheckModification())) - return ; - switch( eState ) - { - case SvButtonState::Checked: - pItem->SetStateChecked(); - break; - - case SvButtonState::Unchecked: - pItem->SetStateUnchecked(); - break; - - case SvButtonState::Tristate: - pItem->SetStateTristate(); - break; - } - InvalidateEntry( pEntry ); -} - -void SvTreeListBox::SetCheckButtonInvisible( SvTreeListEntry* pEntry) -{ - SvLBoxButton* pItem = (nTreeFlags & SvTreeFlags::CHKBTN) ? - static_cast<SvLBoxButton*>(pEntry->GetFirstItem(SvLBoxItemType::Button)) : - nullptr; - - if (!pItem) - return; - - pItem->SetStateInvisible(); - InvalidateEntry(pEntry); -} - -SvButtonState SvTreeListBox::GetCheckButtonState( SvTreeListEntry* pEntry ) const -{ - SvButtonState eState = SvButtonState::Unchecked; - if( pEntry && ( nTreeFlags & SvTreeFlags::CHKBTN ) ) - { - SvLBoxButton* pItem = static_cast<SvLBoxButton*>(pEntry->GetFirstItem(SvLBoxItemType::Button)); - if(!pItem) - return SvButtonState::Tristate; - SvItemStateFlags nButtonFlags = pItem->GetButtonFlags(); - eState = SvLBoxButtonData::ConvertToButtonState( nButtonFlags ); - } - return eState; -} - -void SvTreeListBox::CheckButtonHdl() -{ - aCheckButtonHdl.Call( this ); - if ( pCheckButtonData ) - pImpl->CallEventListeners( VclEventId::CheckboxToggle, static_cast<void*>(pCheckButtonData->GetActEntry()) ); -} - - -// TODO: Currently all data is cloned so that they conform to the default tree -// view format. Actually, the model should be used as a reference here. This -// leads to us _not_ calling SvTreeListEntry::Clone, but only its base class -// SvTreeListEntry. - - -SvTreeListEntry* SvTreeListBox::CloneEntry( SvTreeListEntry* pSource ) -{ - OUString aStr; - Image aCollEntryBmp; - Image aExpEntryBmp; - SvLBoxButtonKind eButtonKind = SvLBoxButtonKind::EnabledCheckbox; - - SvLBoxString* pStringItem = static_cast<SvLBoxString*>(pSource->GetFirstItem(SvLBoxItemType::String)); - if( pStringItem ) - aStr = pStringItem->GetText(); - SvLBoxContextBmp* pBmpItem = static_cast<SvLBoxContextBmp*>(pSource->GetFirstItem(SvLBoxItemType::ContextBmp)); - if( pBmpItem ) - { - aCollEntryBmp = pBmpItem->GetBitmap1( ); - aExpEntryBmp = pBmpItem->GetBitmap2( ); - } - SvLBoxButton* pButtonItem = static_cast<SvLBoxButton*>(pSource->GetFirstItem(SvLBoxItemType::Button)); - if( pButtonItem ) - eButtonKind = pButtonItem->GetKind(); - SvTreeListEntry* pClone = CreateEntry(); - InitEntry( pClone, aStr, aCollEntryBmp, aExpEntryBmp, eButtonKind ); - pClone->SvTreeListEntry::Clone( pSource ); - pClone->EnableChildrenOnDemand( pSource->HasChildrenOnDemand() ); - pClone->SetUserData( pSource->GetUserData() ); - - return pClone; -} - -void SvTreeListBox::SetIndent( short nNewIndent ) -{ - nIndent = nNewIndent; - SetTabs(); - if( IsUpdateMode() ) - Invalidate(); -} - -const Image& SvTreeListBox::GetDefaultExpandedEntryBmp( ) const -{ - return pImpl->GetDefaultEntryExpBmp( ); -} - -const Image& SvTreeListBox::GetDefaultCollapsedEntryBmp( ) const -{ - return pImpl->GetDefaultEntryColBmp( ); -} - -void SvTreeListBox::SetDefaultExpandedEntryBmp( const Image& aBmp ) -{ - Size aSize = aBmp.GetSizePixel(); - if( aSize.Width() > nContextBmpWidthMax ) - nContextBmpWidthMax = static_cast<short>(aSize.Width()); - SetTabs(); - - pImpl->SetDefaultEntryExpBmp( aBmp ); -} - -void SvTreeListBox::SetDefaultCollapsedEntryBmp( const Image& aBmp ) -{ - Size aSize = aBmp.GetSizePixel(); - if( aSize.Width() > nContextBmpWidthMax ) - nContextBmpWidthMax = static_cast<short>(aSize.Width()); - SetTabs(); - - pImpl->SetDefaultEntryColBmp( aBmp ); -} - -void SvTreeListBox::EnableCheckButton( SvLBoxButtonData* pData ) -{ - DBG_ASSERT(!GetEntryCount(),"EnableCheckButton: Entry count != 0"); - if( !pData ) - nTreeFlags &= (~SvTreeFlags::CHKBTN); - else - { - SetCheckButtonData( pData ); - nTreeFlags |= SvTreeFlags::CHKBTN; - pData->SetLink( LINK(this, SvTreeListBox, CheckButtonClick)); - } - - SetTabs(); - if( IsUpdateMode() ) - Invalidate(); -} - -void SvTreeListBox::SetCheckButtonData( SvLBoxButtonData* pData ) -{ - if ( pData ) - pCheckButtonData = pData; -} - -const Image& SvTreeListBox::GetDefaultExpandedNodeImage( ) -{ - return SvImpLBox::GetDefaultExpandedNodeImage( ); -} - -const Image& SvTreeListBox::GetDefaultCollapsedNodeImage( ) -{ - return SvImpLBox::GetDefaultCollapsedNodeImage( ); -} - -void SvTreeListBox::SetNodeBitmaps( const Image& rCollapsedNodeBmp, const Image& rExpandedNodeBmp ) -{ - SetExpandedNodeBmp( rExpandedNodeBmp ); - SetCollapsedNodeBmp( rCollapsedNodeBmp ); - SetTabs(); -} - -bool SvTreeListBox::EditingEntry( SvTreeListEntry*, Selection& ) -{ - return true; -} - -bool SvTreeListBox::EditedEntry( SvTreeListEntry* /*pEntry*/,const OUString& /*rNewText*/) -{ - return true; -} - -void SvTreeListBox::EnableInplaceEditing( bool bOn ) -{ - if (bOn) - nImpFlags |= SvTreeListBoxFlags::EDT_ENABLED; - else - nImpFlags &= ~SvTreeListBoxFlags::EDT_ENABLED; -} - -void SvTreeListBox::KeyInput( const KeyEvent& rKEvt ) -{ - // under OS/2, we get key up/down even while editing - if( IsEditingActive() ) - return; - - nImpFlags |= SvTreeListBoxFlags::IS_TRAVELSELECT; - - if( !pImpl->KeyInput( rKEvt ) ) - { - bool bHandled = HandleKeyInput( rKEvt ); - if ( !bHandled ) - Control::KeyInput( rKEvt ); - } - - nImpFlags &= ~SvTreeListBoxFlags::IS_TRAVELSELECT; -} - -void SvTreeListBox::RequestingChildren( SvTreeListEntry* pParent ) -{ - if( !pParent->HasChildren() ) - InsertEntry( OUString("<dummy>"), pParent ); -} - -void SvTreeListBox::GetFocus() -{ - //If there is no item in the tree, draw focus. - if( !First()) - { - Invalidate(); - } - pImpl->GetFocus(); - Control::GetFocus(); - - SvTreeListEntry* pEntry = FirstSelected(); - if ( !pEntry ) - { - pEntry = pImpl->GetCurrentEntry(); - } - if (pImpl->pCursor) - { - if (pEntry != pImpl->pCursor) - pEntry = pImpl->pCursor; - } - if ( pEntry ) - pImpl->CallEventListeners( VclEventId::ListboxTreeFocus, pEntry ); - -} - -void SvTreeListBox::LoseFocus() -{ - // If there is no item in the tree, delete visual focus. - if ( !First() ) - Invalidate(); - if ( pImpl ) - pImpl->LoseFocus(); - Control::LoseFocus(); -} - -void SvTreeListBox::ModelHasCleared() -{ - pImpl->pCursor = nullptr; // else we crash in GetFocus when editing in-place - pEdCtrl.reset(); - pImpl->Clear(); - nFocusWidth = -1; - - nContextBmpWidthMax = 0; - SetDefaultExpandedEntryBmp( GetDefaultExpandedEntryBmp() ); - SetDefaultCollapsedEntryBmp( GetDefaultCollapsedEntryBmp() ); - - if( !(nTreeFlags & SvTreeFlags::FIXEDHEIGHT )) - nEntryHeight = 0; - AdjustEntryHeight(); - AdjustEntryHeight( GetDefaultExpandedEntryBmp() ); - AdjustEntryHeight( GetDefaultCollapsedEntryBmp() ); - - SvListView::ModelHasCleared(); -} - -void SvTreeListBox::ScrollOutputArea( short nDeltaEntries ) -{ - if( !nDeltaEntries || !pImpl->aVerSBar->IsVisible() ) - return; - - long nThumb = pImpl->aVerSBar->GetThumbPos(); - long nMax = pImpl->aVerSBar->GetRange().Max(); - - if( nDeltaEntries < 0 ) - { - // move window up - nDeltaEntries *= -1; - long nVis = pImpl->aVerSBar->GetVisibleSize(); - long nTemp = nThumb + nVis; - if( nDeltaEntries > (nMax - nTemp) ) - nDeltaEntries = static_cast<short>(nMax - nTemp); - pImpl->PageDown( static_cast<sal_uInt16>(nDeltaEntries) ); - } - else - { - if( nDeltaEntries > nThumb ) - nDeltaEntries = static_cast<short>(nThumb); - pImpl->PageUp( static_cast<sal_uInt16>(nDeltaEntries) ); - } - pImpl->SyncVerThumb(); - NotifyEndScroll(); -} - -void SvTreeListBox::ScrollToAbsPos( long nPos ) -{ - pImpl->ScrollToAbsPos( nPos ); -} - -void SvTreeListBox::SetSelectionMode( SelectionMode eSelectMode ) -{ - eSelMode = eSelectMode; - pImpl->SetSelectionMode( eSelectMode ); -} - -void SvTreeListBox::SetDragDropMode( DragDropMode nDDMode ) -{ - nDragDropMode = nDDMode; - pImpl->SetDragDropMode( nDDMode ); -} - -void SvTreeListBox::SetEntryHeight( SvTreeListEntry const * pEntry ) -{ - short nHeightMax=0; - sal_uInt16 nCount = pEntry->ItemCount(); - sal_uInt16 nCur = 0; - SvViewDataEntry* pViewData = GetViewDataEntry( pEntry ); - while( nCur < nCount ) - { - short nHeight = static_cast<short>(SvLBoxItem::GetSize( pViewData, nCur ).Height()); - if( nHeight > nHeightMax ) - nHeightMax = nHeight; - nCur++; - } - - if( nHeightMax > nEntryHeight ) - { - nEntryHeight = nHeightMax; - Control::SetFont( GetFont() ); - pImpl->SetEntryHeight(); - } -} - -void SvTreeListBox::SetEntryHeight( short nHeight, bool bForce ) -{ - if( nHeight > nEntryHeight || bForce ) - { - nEntryHeight = nHeight; - if( nEntryHeight ) - nTreeFlags |= SvTreeFlags::FIXEDHEIGHT; - else - nTreeFlags &= ~SvTreeFlags::FIXEDHEIGHT; - Control::SetFont( GetFont() ); - pImpl->SetEntryHeight(); - } -} - -void SvTreeListBox::SetEntryWidth( short nWidth ) -{ - nEntryWidth = nWidth; -} - -void SvTreeListBox::AdjustEntryHeight( const Image& rBmp ) -{ - const Size aSize( rBmp.GetSizePixel() ); - if( aSize.Height() > nEntryHeight ) - { - nEntryHeight = static_cast<short>(aSize.Height()) + nEntryHeightOffs; - pImpl->SetEntryHeight(); - } -} - -void SvTreeListBox::AdjustEntryHeight() -{ - Size aSize( GetTextWidth(OUString('X')), GetTextHeight() ); - if( aSize.Height() > nEntryHeight ) - { - nEntryHeight = static_cast<short>(aSize.Height()) + nEntryHeightOffs; - pImpl->SetEntryHeight(); - } -} - -bool SvTreeListBox::Expand( SvTreeListEntry* pParent ) -{ - pHdlEntry = pParent; - bool bExpanded = false; - SvTLEntryFlags nFlags; - - if( pParent->HasChildrenOnDemand() ) - RequestingChildren( pParent ); - if( pParent->HasChildren() ) - { - nImpFlags |= SvTreeListBoxFlags::IS_EXPANDING; - if( ExpandingHdl() ) - { - bExpanded = true; - ExpandListEntry( pParent ); - pImpl->EntryExpanded( pParent ); - pHdlEntry = pParent; - ExpandedHdl(); - SetAlternatingRowColors( mbAlternatingRowColors ); - } - nFlags = pParent->GetFlags(); - nFlags &= ~SvTLEntryFlags::NO_NODEBMP; - nFlags |= SvTLEntryFlags::HAD_CHILDREN; - pParent->SetFlags( nFlags ); - } - else - { - nFlags = pParent->GetFlags(); - nFlags |= SvTLEntryFlags::NO_NODEBMP; - pParent->SetFlags( nFlags ); - GetModel()->InvalidateEntry( pParent ); // repaint - } - - // #i92103# - if ( bExpanded ) - { - pImpl->CallEventListeners( VclEventId::ItemExpanded, pParent ); - } - - return bExpanded; -} - -bool SvTreeListBox::Collapse( SvTreeListEntry* pParent ) -{ - nImpFlags &= ~SvTreeListBoxFlags::IS_EXPANDING; - pHdlEntry = pParent; - bool bCollapsed = false; - - if( ExpandingHdl() ) - { - bCollapsed = true; - pImpl->CollapsingEntry( pParent ); - CollapseListEntry( pParent ); - pImpl->EntryCollapsed( pParent ); - pHdlEntry = pParent; - ExpandedHdl(); - SetAlternatingRowColors( mbAlternatingRowColors ); - } - - // #i92103# - if ( bCollapsed ) - { - pImpl->CallEventListeners( VclEventId::ItemCollapsed, pParent ); - } - - return bCollapsed; -} - -bool SvTreeListBox::Select( SvTreeListEntry* pEntry, bool bSelect ) -{ - DBG_ASSERT(pEntry,"Select: Null-Ptr"); - bool bRetVal = SelectListEntry( pEntry, bSelect ); - DBG_ASSERT(IsSelected(pEntry)==bSelect,"Select failed"); - if( bRetVal ) - { - pImpl->EntrySelected( pEntry, bSelect ); - pHdlEntry = pEntry; - if( bSelect ) - { - SelectHdl(); - CallEventListeners( VclEventId::ListboxTreeSelect, pEntry); - } - else - DeselectHdl(); - } - return bRetVal; -} - -sal_uLong SvTreeListBox::SelectChildren( SvTreeListEntry* pParent, bool bSelect ) -{ - pImpl->DestroyAnchor(); - sal_uLong nRet = 0; - if( !pParent->HasChildren() ) - return 0; - sal_uInt16 nRefDepth = pModel->GetDepth( pParent ); - SvTreeListEntry* pChild = FirstChild( pParent ); - do { - nRet++; - Select( pChild, bSelect ); - pChild = Next( pChild ); - } while( pChild && pModel->GetDepth( pChild ) > nRefDepth ); - return nRet; -} - -void SvTreeListBox::SelectAll( bool bSelect, bool ) -{ - pImpl->SelAllDestrAnch( - bSelect, - true, // delete anchor, - true ); // even when using SelectionMode::Single, deselect the cursor -} - -void SvTreeListBox::ModelHasInsertedTree( SvTreeListEntry* pEntry ) -{ - sal_uInt16 nRefDepth = pModel->GetDepth( pEntry ); - SvTreeListEntry* pTmp = pEntry; - do - { - ImpEntryInserted( pTmp ); - pTmp = Next( pTmp ); - } while( pTmp && nRefDepth < pModel->GetDepth( pTmp ) ); - pImpl->TreeInserted( pEntry ); -} - -void SvTreeListBox::ModelHasInserted( SvTreeListEntry* pEntry ) -{ - ImpEntryInserted( pEntry ); - pImpl->EntryInserted( pEntry ); -} - -void SvTreeListBox::ModelIsMoving(SvTreeListEntry* pSource, - SvTreeListEntry* /* pTargetParent */, - sal_uLong /* nChildPos */ ) -{ - pImpl->MovingEntry( pSource ); -} - -void SvTreeListBox::ModelHasMoved( SvTreeListEntry* pSource ) -{ - pImpl->EntryMoved( pSource ); -} - -void SvTreeListBox::ModelIsRemoving( SvTreeListEntry* pEntry ) -{ - if(pEdEntry == pEntry) - pEdEntry = nullptr; - - pImpl->RemovingEntry( pEntry ); -} - -void SvTreeListBox::ModelHasRemoved( SvTreeListEntry* pEntry ) -{ - if ( pEntry == pHdlEntry) - pHdlEntry = nullptr; - pImpl->EntryRemoved(); -} - -void SvTreeListBox::SetCollapsedNodeBmp( const Image& rBmp) -{ - AdjustEntryHeight( rBmp ); - pImpl->SetCollapsedNodeBmp( rBmp ); -} - -void SvTreeListBox::SetExpandedNodeBmp( const Image& rBmp ) -{ - AdjustEntryHeight( rBmp ); - pImpl->SetExpandedNodeBmp( rBmp ); -} - - -void SvTreeListBox::SetFont( const vcl::Font& rFont ) -{ - vcl::Font aTempFont( rFont ); - vcl::Font aOrigFont( GetFont() ); - aTempFont.SetTransparent( true ); - if (aTempFont == aOrigFont) - return; - Control::SetFont( aTempFont ); - - aTempFont.SetColor(aOrigFont.GetColor()); - aTempFont.SetFillColor(aOrigFont.GetFillColor()); - aTempFont.SetTransparent(aOrigFont.IsTransparent()); - - if (aTempFont == aOrigFont) - return; - - AdjustEntryHeightAndRecalc(); -} - -void SvTreeListBox::AdjustEntryHeightAndRecalc() -{ - AdjustEntryHeight(); - // always invalidate, else things go wrong in SetEntryHeight - RecalcViewData(); -} - -void SvTreeListBox::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) -{ - Control::Paint(rRenderContext, rRect); - if (nTreeFlags & SvTreeFlags::RECALCTABS) - SetTabs(); - pImpl->Paint(rRenderContext, rRect); - - //Add visual focus draw - if (First()) - return; - - if (HasFocus()) - { - long nHeight = rRenderContext.GetTextHeight(); - tools::Rectangle aRect(Point(0, 0), Size(GetSizePixel().Width(), nHeight)); - ShowFocus(aRect); - } - else - { - HideFocus(); - } -} - -void SvTreeListBox::MouseButtonDown( const MouseEvent& rMEvt ) -{ - pImpl->MouseButtonDown( rMEvt ); -} - -void SvTreeListBox::MouseButtonUp( const MouseEvent& rMEvt ) -{ - pImpl->MouseButtonUp( rMEvt ); -} - -void SvTreeListBox::MouseMove( const MouseEvent& rMEvt ) -{ - pImpl->MouseMove( rMEvt ); -} - - -void SvTreeListBox::SetUpdateMode( bool bUpdate ) -{ - pImpl->SetUpdateMode( bUpdate ); - mbUpdateAlternatingRows = bUpdate; - SetAlternatingRowColors( mbAlternatingRowColors ); -} - -void SvTreeListBox::SetSpaceBetweenEntries( short nOffsLogic ) -{ - if( nOffsLogic != nEntryHeightOffs ) - { - nEntryHeight = nEntryHeight - nEntryHeightOffs; - nEntryHeightOffs = nOffsLogic; - nEntryHeight = nEntryHeight + nOffsLogic; - AdjustEntryHeightAndRecalc(); - pImpl->SetEntryHeight(); - } -} - -void SvTreeListBox::SetCursor( SvTreeListEntry* pEntry, bool bForceNoSelect ) -{ - pImpl->SetCursor(pEntry, bForceNoSelect); -} - -void SvTreeListBox::SetCurEntry( SvTreeListEntry* pEntry ) -{ - pImpl->SetCurEntry( pEntry ); -} - -Image const & SvTreeListBox::GetExpandedNodeBmp( ) const -{ - return pImpl->GetExpandedNodeBmp( ); -} - -Point SvTreeListBox::GetEntryPosition( SvTreeListEntry* pEntry ) const -{ - return pImpl->GetEntryPosition( pEntry ); -} - -void SvTreeListBox::MakeVisible( SvTreeListEntry* pEntry ) -{ - pImpl->MakeVisible(pEntry); -} - -void SvTreeListBox::MakeVisible( SvTreeListEntry* pEntry, bool bMoveToTop ) -{ - pImpl->MakeVisible( pEntry, bMoveToTop ); -} - -void SvTreeListBox::ModelHasEntryInvalidated( SvTreeListEntry* pEntry ) -{ - - // reinitialize the separate items of the entries - sal_uInt16 nCount = pEntry->ItemCount(); - for( sal_uInt16 nIdx = 0; nIdx < nCount; nIdx++ ) - { - SvLBoxItem& rItem = pEntry->GetItem( nIdx ); - rItem.InitViewData( this, pEntry ); - } - - // repaint - pImpl->InvalidateEntry( pEntry ); -} - -void SvTreeListBox::EditItemText(SvTreeListEntry* pEntry, SvLBoxString* pItem, const Selection& rSelection) -{ - assert(pEntry && pItem); - if( IsSelected( pEntry )) - { - pImpl->ShowCursor( false ); - SelectListEntry( pEntry, false ); - pImpl->InvalidateEntry(pEntry); - SelectListEntry( pEntry, true ); - pImpl->ShowCursor( true ); - } - pEdEntry = pEntry; - pEdItem = pItem; - SvLBoxTab* pTab = GetTab( pEntry, pItem ); - DBG_ASSERT(pTab,"EditItemText:Tab not found"); - - Size aItemSize( pItem->GetSize(this, pEntry) ); - Point aPos = GetEntryPosition( pEntry ); - aPos.AdjustY(( nEntryHeight - aItemSize.Height() ) / 2 ); - aPos.setX( GetTabPos( pEntry, pTab ) ); - long nOutputWidth = pImpl->GetOutputSize().Width(); - Size aSize( nOutputWidth - aPos.X(), aItemSize.Height() ); - sal_uInt16 nPos = std::find_if( aTabs.begin(), aTabs.end(), - [pTab](const std::unique_ptr<SvLBoxTab>& p) { return p.get() == pTab; }) - - aTabs.begin(); - if( nPos+1 < static_cast<sal_uInt16>(aTabs.size()) ) - { - SvLBoxTab* pRightTab = aTabs[ nPos + 1 ].get(); - long nRight = GetTabPos( pEntry, pRightTab ); - if( nRight <= nOutputWidth ) - aSize.setWidth( nRight - aPos.X() ); - } - Point aOrigin( GetMapMode().GetOrigin() ); - aPos += aOrigin; // convert to win coordinates - aSize.AdjustWidth( -(aOrigin.X()) ); - tools::Rectangle aRect( aPos, aSize ); - EditText( pItem->GetText(), aRect, rSelection ); -} - -void SvTreeListBox::EditEntry( SvTreeListEntry* pEntry ) -{ - pImpl->aEditClickPos = Point( -1, -1 ); - ImplEditEntry( pEntry ); -} - -void SvTreeListBox::ImplEditEntry( SvTreeListEntry* pEntry ) -{ - if( IsEditingActive() ) - EndEditing(); - if( !pEntry ) - pEntry = GetCurEntry(); - if( !pEntry ) - return; - - long nClickX = pImpl->aEditClickPos.X(); - bool bIsMouseTriggered = nClickX >= 0; - - SvLBoxString* pItem = nullptr; - sal_uInt16 nCount = pEntry->ItemCount(); - long nTabPos, nNextTabPos = 0; - for( sal_uInt16 i = 0 ; i < nCount ; i++ ) - { - SvLBoxItem& rTmpItem = pEntry->GetItem( i ); - if (rTmpItem.GetType() != SvLBoxItemType::String) - continue; - - SvLBoxTab* pTab = GetTab( pEntry, &rTmpItem ); - nNextTabPos = -1; - if( i < nCount - 1 ) - { - SvLBoxItem& rNextItem = pEntry->GetItem( i + 1 ); - SvLBoxTab* pNextTab = GetTab( pEntry, &rNextItem ); - nNextTabPos = pNextTab->GetPos(); - } - - if( pTab && pTab->IsEditable() ) - { - nTabPos = pTab->GetPos(); - if( !bIsMouseTriggered || (nClickX > nTabPos && (nNextTabPos == -1 || nClickX < nNextTabPos ) ) ) - { - pItem = static_cast<SvLBoxString*>( &rTmpItem ); - break; - } - } - } - - Selection aSel( SELECTION_MIN, SELECTION_MAX ); - if( pItem && EditingEntry( pEntry, aSel ) ) - { - SelectAll( false ); - MakeVisible( pEntry ); - EditItemText( pEntry, pItem, aSel ); - } -} - -bool SvTreeListBox::AreChildrenTransient() const -{ - return pImpl->AreChildrenTransient(); -} - -void SvTreeListBox::SetChildrenNotTransient() -{ - pImpl->SetChildrenNotTransient(); -} - -void SvTreeListBox::EditedText( const OUString& rStr ) - -{ - if(pEdEntry) // we have to check if this entry is null that means that it is removed while editing - { - if( EditedEntry( pEdEntry, rStr ) ) - { - static_cast<SvLBoxString*>(pEdItem)->SetText( rStr ); - pModel->InvalidateEntry( pEdEntry ); - } - if( GetSelectionCount() == 0 ) - Select( pEdEntry ); - if( GetSelectionMode() == SelectionMode::Multiple && !GetCurEntry() ) - SetCurEntry( pEdEntry ); - } -} - -SvTreeListEntry* SvTreeListBox::GetDropTarget( const Point& rPos ) -{ - // scroll - if( rPos.Y() < 12 ) - { - ImplShowTargetEmphasis(pTargetEntry, false); - ScrollOutputArea( +1 ); - } - else - { - Size aSize( pImpl->GetOutputSize() ); - if( rPos.Y() > aSize.Height() - 12 ) - { - ImplShowTargetEmphasis(pTargetEntry, false); - ScrollOutputArea( -1 ); - } - } - - SvTreeListEntry* pTarget = pImpl->GetEntry( rPos ); - // when dropping in a vacant space, use the last entry - if( !pTarget ) - return LastVisible(); - else if( (GetDragDropMode() & DragDropMode::ENABLE_TOP) && - pTarget == First() && rPos.Y() < 6 ) - return nullptr; - - return pTarget; -} - - -SvTreeListEntry* SvTreeListBox::GetEntry( const Point& rPos, bool bHit ) const -{ - SvTreeListEntry* pEntry = pImpl->GetEntry( rPos ); - if( pEntry && bHit ) - { - long nLine = pImpl->GetEntryLine( pEntry ); - if( !(pImpl->EntryReallyHit( pEntry, rPos, nLine)) ) - return nullptr; - } - return pEntry; -} - -SvTreeListEntry* SvTreeListBox::GetCurEntry() const -{ - return pImpl ? pImpl->GetCurEntry() : nullptr; -} - -void SvTreeListBox::ImplInitStyle() -{ - const WinBits nWindowStyle = GetStyle(); - - nTreeFlags |= SvTreeFlags::RECALCTABS; - if (nWindowStyle & WB_SORT) - { - GetModel()->SetSortMode(SortAscending); - GetModel()->SetCompareHdl(LINK(this, SvTreeListBox, DefaultCompare)); - } - else - { - GetModel()->SetSortMode(SortNone); - GetModel()->SetCompareHdl(Link<const SvSortData&,sal_Int32>()); - } - pImpl->SetStyle(nWindowStyle); - pImpl->Resize(); - Invalidate(); -} - -void SvTreeListBox::InvalidateEntry(SvTreeListEntry* pEntry) -{ - DBG_ASSERT(pEntry,"InvalidateEntry:No Entry"); - if (pEntry) - { - GetModel()->InvalidateEntry(pEntry); - } -} - -void SvTreeListBox::PaintEntry1(SvTreeListEntry& rEntry, long nLine, vcl::RenderContext& rRenderContext) -{ - - tools::Rectangle aRect; // multi purpose - - bool bHorSBar = pImpl->HasHorScrollBar(); - PreparePaint(rRenderContext, rEntry); - - pImpl->UpdateContextBmpWidthMax(&rEntry); - - if (nTreeFlags & SvTreeFlags::RECALCTABS) - SetTabs(); - - short nTempEntryHeight = GetEntryHeight(); - long nWidth = pImpl->GetOutputSize().Width(); - - // Did we turn on the scrollbar within PreparePaints? If yes, we have to set - // the ClipRegion anew. - if (!bHorSBar && pImpl->HasHorScrollBar()) - rRenderContext.SetClipRegion(vcl::Region(pImpl->GetClipRegionRect())); - - Point aEntryPos(rRenderContext.GetMapMode().GetOrigin()); - aEntryPos.setX( aEntryPos.X() * -1 ); // conversion document coordinates - long nMaxRight = nWidth + aEntryPos.X() - 1; - - Color aBackupTextColor(rRenderContext.GetTextColor()); - vcl::Font aBackupFont(rRenderContext.GetFont()); - Color aBackupColor = rRenderContext.GetFillColor(); - - bool bCurFontIsSel = false; - bool bInUse = rEntry.HasInUseEmphasis(); - // if a ClipRegion was set from outside, we don't have to reset it - const WinBits nWindowStyle = GetStyle(); - const bool bHideSelection = (nWindowStyle & WB_HIDESELECTION) !=0 && !HasFocus(); - const StyleSettings& rSettings = rRenderContext.GetSettings().GetStyleSettings(); - - vcl::Font aHighlightFont(rRenderContext.GetFont()); - const Color aHighlightTextColor(rSettings.GetHighlightTextColor()); - aHighlightFont.SetColor(aHighlightTextColor); - - Size aRectSize(0, nTempEntryHeight); - - SvViewDataEntry* pViewDataEntry = GetViewDataEntry( &rEntry ); - - sal_uInt16 nTabCount = aTabs.size(); - sal_uInt16 nItemCount = rEntry.ItemCount(); - sal_uInt16 nCurTab = 0; - sal_uInt16 nCurItem = 0; - - while (nCurTab < nTabCount && nCurItem < nItemCount) - { - SvLBoxTab* pTab = aTabs[nCurTab].get(); - sal_uInt16 nNextTab = nCurTab + 1; - SvLBoxTab* pNextTab = nNextTab < nTabCount ? aTabs[nNextTab].get() : nullptr; - SvLBoxItem* pItem = nCurItem < nItemCount ? &rEntry.GetItem(nCurItem) : nullptr; - - SvLBoxTabFlags nFlags = pTab->nFlags; - Size aSize(SvLBoxItem::GetSize(pViewDataEntry, nCurItem)); - long nTabPos = GetTabPos(&rEntry, pTab); - - long nNextTabPos; - if (pNextTab) - nNextTabPos = GetTabPos(&rEntry, pNextTab); - else - { - nNextTabPos = nMaxRight; - if (nTabPos > nMaxRight) - nNextTabPos += 50; - } - - long nX; - if( pTab->nFlags & SvLBoxTabFlags::ADJUST_RIGHT ) - // avoid cutting the right edge off the tab separation - nX = nTabPos + pTab->CalcOffset(aSize.Width(), (nNextTabPos - SV_TAB_BORDER - 1) - nTabPos); - else - nX = nTabPos + pTab->CalcOffset(aSize.Width(), nNextTabPos - nTabPos); - - aEntryPos.setX( nX ); - aEntryPos.setY( nLine ); - - // set background pattern/color - - Wallpaper aWallpaper = rRenderContext.GetBackground(); - - bool bSelTab = bool(nFlags & SvLBoxTabFlags::SHOW_SELECTION); - SvLBoxItemType nItemType = pItem->GetType(); - - if (pViewDataEntry->IsHighlighted() && bSelTab) - { - Color aNewWallColor = rSettings.GetHighlightColor(); - if (!bInUse || nItemType != SvLBoxItemType::ContextBmp) - { - // if the face color is bright then the deactive color is also bright - // -> so you can't see any deactive selection - if (bHideSelection && !rSettings.GetFaceColor().IsBright() - && aWallpaper.GetColor().IsBright() != rSettings.GetDeactiveColor().IsBright()) - { - aNewWallColor = rSettings.GetDeactiveColor(); - } - // set font color to highlight - if (!bCurFontIsSel) - { - rRenderContext.SetTextColor(aHighlightTextColor); - rRenderContext.SetFont(aHighlightFont); - bCurFontIsSel = true; - } - } - aWallpaper.SetColor(aNewWallColor); - } - else // no selection - { - if (bInUse && nItemType == SvLBoxItemType::ContextBmp) - { - aWallpaper.SetColor(rSettings.GetFieldColor()); - } - else if (bCurFontIsSel) - { - bCurFontIsSel = false; - rRenderContext.SetTextColor(aBackupTextColor); - rRenderContext.SetFont(aBackupFont); - } - else - { - aWallpaper.SetColor(rEntry.GetBackColor()); - } - } - - // draw background - if (!(nTreeFlags & SvTreeFlags::USESEL)) - { - // only draw the area that is used by the item - aRectSize.setWidth( aSize.Width() ); - aRect.SetPos(aEntryPos); - aRect.SetSize(aRectSize); - } - else - { - // draw from the current to the next tab - if (nCurTab != 0) - aRect.SetLeft( nTabPos ); - else - // if we're in the 0th tab, always draw from column 0 -- - // else we get problems with centered tabs - aRect.SetLeft( 0 ); - aRect.SetTop( nLine ); - aRect.SetBottom( nLine + nTempEntryHeight - 1 ); - if (pNextTab) - { - long nRight; - nRight = GetTabPos(&rEntry, pNextTab) - 1; - if (nRight > nMaxRight) - nRight = nMaxRight; - aRect.SetRight( nRight ); - } - else - { - aRect.SetRight( nMaxRight ); - } - } - // A custom selection that starts at a tab position > 0, do not fill - // the background of the 0th item, else e.g. we might not be able to - // realize tab listboxes with lines. - if (!(nCurTab == 0 && (nTreeFlags & SvTreeFlags::USESEL) && nFirstSelTab)) - { - Color aBackgroundColor = aWallpaper.GetColor(); - if (aBackgroundColor != COL_TRANSPARENT) - { - rRenderContext.SetFillColor(aBackgroundColor); - // this case may occur for smaller horizontal resizes - if (aRect.Left() < aRect.Right()) - rRenderContext.DrawRect(aRect); - } - } - // draw item - // center vertically - aEntryPos.AdjustY((nTempEntryHeight - aSize.Height()) / 2 ); - pViewDataEntry->SetPaintRectangle(aRect); - - pItem->Paint(aEntryPos, *this, rRenderContext, pViewDataEntry, rEntry); - - // division line between tabs - if (pNextTab && pItem->GetType() == SvLBoxItemType::String && - // not at the right edge of the window! - aRect.Right() < nMaxRight) - { - aRect.SetLeft( aRect.Right() - SV_TAB_BORDER ); - rRenderContext.DrawRect(aRect); - } - - rRenderContext.SetFillColor(aBackupColor); - - nCurItem++; - nCurTab++; - } - - if (bCurFontIsSel) - { - rRenderContext.SetTextColor(aBackupTextColor); - rRenderContext.SetFont(aBackupFont); - } - - sal_uInt16 nFirstDynTabPos(0); - SvLBoxTab* pFirstDynamicTab = GetFirstDynamicTab(nFirstDynTabPos); - long nDynTabPos = GetTabPos(&rEntry, pFirstDynamicTab); - nDynTabPos += pImpl->nNodeBmpTabDistance; - nDynTabPos += pImpl->nNodeBmpWidth / 2; - nDynTabPos += 4; // 4 pixels of buffer, so the node bitmap is not too close - // to the next tab - - if( !((!(rEntry.GetFlags() & SvTLEntryFlags::NO_NODEBMP)) && - (nWindowStyle & WB_HASBUTTONS) && pFirstDynamicTab && - (rEntry.HasChildren() || rEntry.HasChildrenOnDemand()))) - return; - - // find first tab and check if the node bitmap extends into it - sal_uInt16 nNextTab = nFirstDynTabPos; - SvLBoxTab* pNextTab; - do - { - nNextTab++; - pNextTab = nNextTab < nTabCount ? aTabs[nNextTab].get() : nullptr; - } while (pNextTab && pNextTab->IsDynamic()); - - if (!(!pNextTab || (GetTabPos( &rEntry, pNextTab ) > nDynTabPos))) - return; - - if (!((nWindowStyle & WB_HASBUTTONSATROOT) || pModel->GetDepth(&rEntry) > 0)) - return; - - Point aPos(GetTabPos(&rEntry, pFirstDynamicTab), nLine); - aPos.AdjustX(pImpl->nNodeBmpTabDistance ); - - const Image* pImg = nullptr; - - if (IsExpanded(&rEntry)) - pImg = &pImpl->GetExpandedNodeBmp(); - else - { - if ((!rEntry.HasChildren()) && rEntry.HasChildrenOnDemand() && - (!(rEntry.GetFlags() & SvTLEntryFlags::HAD_CHILDREN)) && - pImpl->GetDontKnowNodeBmp().GetSizePixel().Width()) - { - pImg = &pImpl->GetDontKnowNodeBmp( ); - } - else - { - pImg = &pImpl->GetCollapsedNodeBmp( ); - } - } - aPos.AdjustY((nTempEntryHeight - pImg->GetSizePixel().Height()) / 2 ); - - DrawImageFlags nStyle = DrawImageFlags::NONE; - if (!IsEnabled()) - nStyle |= DrawImageFlags::Disable; - - //native - bool bNativeOK = false; - if (rRenderContext.IsNativeControlSupported(ControlType::ListNode, ControlPart::Entire)) - { - ImplControlValue aControlValue; - tools::Rectangle aCtrlRegion(aPos, pImg->GetSizePixel()); - ControlState nState = ControlState::NONE; - - if (IsEnabled()) - nState |= ControlState::ENABLED; - - if (IsExpanded(&rEntry)) - aControlValue.setTristateVal(ButtonValue::On); //expanded node - else - { - if ((!rEntry.HasChildren()) && rEntry.HasChildrenOnDemand() && - (!(rEntry.GetFlags() & SvTLEntryFlags::HAD_CHILDREN)) && - pImpl->GetDontKnowNodeBmp().GetSizePixel().Width()) - { - aControlValue.setTristateVal( ButtonValue::DontKnow ); //don't know - } - else - { - aControlValue.setTristateVal( ButtonValue::Off ); //collapsed node - } - } - - bNativeOK = rRenderContext.DrawNativeControl(ControlType::ListNode, ControlPart::Entire, aCtrlRegion, nState, aControlValue, OUString()); - } - - if (!bNativeOK) - { - rRenderContext.DrawImage(aPos, *pImg ,nStyle); - } -} - -void SvTreeListBox::PreparePaint(vcl::RenderContext& /*rRenderContext*/, SvTreeListEntry& /*rEntry*/) -{ -} - -tools::Rectangle SvTreeListBox::GetFocusRect( SvTreeListEntry* pEntry, long nLine ) -{ - pImpl->UpdateContextBmpWidthMax( pEntry ); - - Size aSize; - tools::Rectangle aRect; - aRect.SetTop( nLine ); - aSize.setHeight( GetEntryHeight() ); - - long nRealWidth = pImpl->GetOutputSize().Width(); - nRealWidth -= GetMapMode().GetOrigin().X(); - - sal_uInt16 nCurTab; - SvLBoxTab* pTab = GetFirstTab( SvLBoxTabFlags::SHOW_SELECTION, nCurTab ); - long nTabPos = 0; - if( pTab ) - nTabPos = GetTabPos( pEntry, pTab ); - long nNextTabPos; - if( pTab && nCurTab < aTabs.size() - 1 ) - { - SvLBoxTab* pNextTab = aTabs[ nCurTab + 1 ].get(); - nNextTabPos = GetTabPos( pEntry, pNextTab ); - } - else - { - nNextTabPos = nRealWidth; - if( nTabPos > nRealWidth ) - nNextTabPos += 50; - } - - bool bUserSelection = bool( nTreeFlags & SvTreeFlags::USESEL ); - if( !bUserSelection ) - { - if( pTab && nCurTab < pEntry->ItemCount() ) - { - SvLBoxItem& rItem = pEntry->GetItem( nCurTab ); - aSize.setWidth( rItem.GetSize( this, pEntry ).Width() ); - if( !aSize.Width() ) - aSize.setWidth( 15 ); - long nX = nTabPos; //GetTabPos( pEntry, pTab ); - // alignment - nX += pTab->CalcOffset( aSize.Width(), nNextTabPos - nTabPos ); - aRect.SetLeft( nX ); - // make sure that first and last letter aren't cut off slightly - aRect.SetSize( aSize ); - if( aRect.Left() > 0 ) - aRect.AdjustLeft( -1 ); - aRect.AdjustRight( 1 ); - } - } - else - { - // if SelTab != 0, we have to calculate also - if( nFocusWidth == -1 || nFirstSelTab ) - { - SvLBoxTab* pLastTab = nullptr; // default to select whole width - - sal_uInt16 nLastTab; - GetLastTab(SvLBoxTabFlags::SHOW_SELECTION,nLastTab); - nLastTab++; - if( nLastTab < aTabs.size() ) // is there another one? - pLastTab = aTabs[ nLastTab ].get(); - - aSize.setWidth( pLastTab ? pLastTab->GetPos() : 0x0fffffff ); - nFocusWidth = static_cast<short>(aSize.Width()); - if( pTab ) - nFocusWidth = nFocusWidth - static_cast<short>(nTabPos); //pTab->GetPos(); - } - else - { - aSize.setWidth( nFocusWidth ); - if( pTab ) - { - if( nCurTab ) - aSize.AdjustWidth(nTabPos ); - else - aSize.AdjustWidth(pTab->GetPos() ); // Tab0 always from the leftmost position - } - } - // if selection starts with 0th tab, draw from column 0 on - if( nCurTab != 0 ) - { - aRect.SetLeft( nTabPos ); - aSize.AdjustWidth( -nTabPos ); - } - aRect.SetSize( aSize ); - } - // adjust right edge because of clipping - if( aRect.Right() >= nRealWidth ) - { - aRect.SetRight( nRealWidth-1 ); - nFocusWidth = static_cast<short>(aRect.GetWidth()); - } - return aRect; -} - - -sal_IntPtr SvTreeListBox::GetTabPos( SvTreeListEntry* pEntry, SvLBoxTab* pTab) -{ - assert(pTab); - sal_IntPtr nPos = pTab->GetPos(); - if( pTab->IsDynamic() ) - { - sal_uInt16 nDepth = pModel->GetDepth( pEntry ); - nDepth = nDepth * static_cast<sal_uInt16>(nIndent); - nPos += static_cast<sal_IntPtr>(nDepth); - } - return nPos; -} - -SvLBoxItem* SvTreeListBox::GetItem_Impl( SvTreeListEntry* pEntry, long nX, - SvLBoxTab** ppTab ) -{ - SvLBoxItem* pItemClicked = nullptr; - sal_uInt16 nTabCount = aTabs.size(); - sal_uInt16 nItemCount = pEntry->ItemCount(); - SvLBoxTab* pTab = aTabs.front().get(); - SvLBoxItem* pItem = &pEntry->GetItem(0); - sal_uInt16 nNextItem = 1; - nX -= GetMapMode().GetOrigin().X(); - long nRealWidth = pImpl->GetOutputSize().Width(); - nRealWidth -= GetMapMode().GetOrigin().X(); - - while( true ) - { - SvLBoxTab* pNextTab=nNextItem<nTabCount ? aTabs[nNextItem].get() : nullptr; - long nStart = GetTabPos( pEntry, pTab ); - - long nNextTabPos; - if( pNextTab ) - nNextTabPos = GetTabPos( pEntry, pNextTab ); - else - { - nNextTabPos = nRealWidth; - if( nStart > nRealWidth ) - nNextTabPos += 50; - } - - Size aItemSize( pItem->GetSize(this, pEntry)); - nStart += pTab->CalcOffset( aItemSize.Width(), nNextTabPos - nStart ); - long nLen = aItemSize.Width(); - if( pNextTab ) - { - long nTabWidth = GetTabPos( pEntry, pNextTab ) - nStart; - if( nTabWidth < nLen ) - nLen = nTabWidth; - } - - if( nX >= nStart && nX < (nStart+nLen ) ) - { - pItemClicked = pItem; - if( ppTab ) - { - *ppTab = pTab; - break; - } - } - if( nNextItem >= nItemCount || nNextItem >= nTabCount) - break; - pTab = aTabs[ nNextItem ].get(); - pItem = &pEntry->GetItem( nNextItem ); - nNextItem++; - } - return pItemClicked; -} - -long SvTreeListBox::getPreferredDimensions(std::vector<long> &rWidths) const -{ - long nHeight = 0; - rWidths.clear(); - SvTreeListEntry* pEntry = First(); - while (pEntry) - { - sal_uInt16 nCount = pEntry->ItemCount(); - sal_uInt16 nCurPos = 0; - if (nCount > rWidths.size()) - rWidths.resize(nCount); - while (nCurPos < nCount) - { - SvLBoxItem& rItem = pEntry->GetItem( nCurPos ); - long nWidth = rItem.GetSize(this, pEntry).Width(); - if (nWidth) - { - nWidth += SV_TAB_BORDER * 2; - if (nWidth > rWidths[nCurPos]) - rWidths[nCurPos] = nWidth; - } - ++nCurPos; - } - pEntry = Next( pEntry ); - nHeight += GetEntryHeight(); - } - return nHeight; -} - -Size SvTreeListBox::GetOptimalSize() const -{ - std::vector<long> aWidths; - Size aRet(0, getPreferredDimensions(aWidths)); - for (long aWidth : aWidths) - aRet.AdjustWidth(aWidth ); - if (GetStyle() & WB_BORDER) - { - const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); - aRet.AdjustWidth(rStyleSettings.GetBorderSize() * 2 ); - aRet.AdjustHeight(rStyleSettings.GetBorderSize() * 2 ); - } - long nMinWidth = nMinWidthInChars * approximate_char_width(); - aRet.setWidth( std::max(aRet.Width(), nMinWidth) ); - return aRet; -} - -void SvTreeListBox::SetAlternatingRowColors( bool bEnable ) -{ - if( !mbUpdateAlternatingRows ) - { - mbAlternatingRowColors = bEnable; - return; - } - - if( bEnable ) - { - SvTreeListEntry* pEntry = pModel->First(); - for(size_t i = 0; pEntry; ++i) - { - pEntry->SetBackColor( i % 2 == 0 ? GetBackground().GetColor() : GetSettings().GetStyleSettings().GetAlternatingRowColor()); - SvTreeListEntry *pNextEntry = nullptr; - if( IsExpanded( pEntry ) ) - pNextEntry = pModel->FirstChild( pEntry ); - else - pNextEntry = pEntry->NextSibling(); - - if( !pNextEntry ) - pEntry = pModel->Next( pEntry ); - else - pEntry = pNextEntry; - } - } - else if( mbAlternatingRowColors ) - for(SvTreeListEntry* pEntry = pModel->First(); pEntry; pEntry = pModel->Next(pEntry)) - pEntry->SetBackColor( GetBackground().GetColor() ); - - mbAlternatingRowColors = bEnable; - pImpl->UpdateAll(true); -} - -void SvTreeListBox::SetForceMakeVisible( bool bEnable ) -{ - pImpl->SetForceMakeVisible(bEnable); -} - -SvLBoxItem* SvTreeListBox::GetItem(SvTreeListEntry* pEntry,long nX,SvLBoxTab** ppTab) -{ - return GetItem_Impl( pEntry, nX, ppTab ); -} - -SvLBoxItem* SvTreeListBox::GetItem(SvTreeListEntry* pEntry,long nX ) -{ - SvLBoxTab* pDummyTab; - return GetItem_Impl( pEntry, nX, &pDummyTab ); -} - -void SvTreeListBox::AddTab(long nTabPos, SvLBoxTabFlags nFlags ) -{ - nFocusWidth = -1; - SvLBoxTab* pTab = new SvLBoxTab( nTabPos, nFlags ); - aTabs.emplace_back( pTab ); - if( nTreeFlags & SvTreeFlags::USESEL ) - { - sal_uInt16 nPos = aTabs.size() - 1; - if( nPos >= nFirstSelTab && nPos <= nLastSelTab ) - pTab->nFlags |= SvLBoxTabFlags::SHOW_SELECTION; - else - // string items usually have to be selected -- turn this off - // explicitly - pTab->nFlags &= ~SvLBoxTabFlags::SHOW_SELECTION; - } -} - - -SvLBoxTab* SvTreeListBox::GetFirstDynamicTab( sal_uInt16& rPos ) const -{ - sal_uInt16 nCurTab = 0; - sal_uInt16 nTabCount = aTabs.size(); - while( nCurTab < nTabCount ) - { - SvLBoxTab* pTab = aTabs[nCurTab].get(); - if( pTab->nFlags & SvLBoxTabFlags::DYNAMIC ) - { - rPos = nCurTab; - return pTab; - } - nCurTab++; - } - return nullptr; -} - -SvLBoxTab* SvTreeListBox::GetFirstDynamicTab() const -{ - sal_uInt16 nDummy; - return GetFirstDynamicTab( nDummy ); -} - -SvLBoxTab* SvTreeListBox::GetTab( SvTreeListEntry const * pEntry, SvLBoxItem const * pItem) const -{ - sal_uInt16 nPos = pEntry->GetPos( pItem ); - return aTabs[ nPos ].get(); -} - -void SvTreeListBox::ClearTabList() -{ - aTabs.clear(); -} - - -Size SvTreeListBox::GetOutputSizePixel() const -{ - Size aSize = pImpl->GetOutputSize(); - return aSize; -} - -void SvTreeListBox::NotifyEndScroll() -{ -} - -void SvTreeListBox::NotifyScrolled() -{ - aScrolledHdl.Call( this ); -} - -void SvTreeListBox::Invalidate( InvalidateFlags nInvalidateFlags ) -{ - if (!pImpl) - return; - if( nFocusWidth == -1 ) - // to make sure that the control doesn't show the wrong focus rectangle - // after painting - pImpl->RecalcFocusRect(); - Control::Invalidate( nInvalidateFlags ); - pImpl->Invalidate(); -} - -void SvTreeListBox::Invalidate( const tools::Rectangle& rRect, InvalidateFlags nInvalidateFlags ) -{ - if( nFocusWidth == -1 ) - // to make sure that the control doesn't show the wrong focus rectangle - // after painting - pImpl->RecalcFocusRect(); - Control::Invalidate( rRect, nInvalidateFlags ); -} - - -void SvTreeListBox::SetHighlightRange( sal_uInt16 nStart, sal_uInt16 nEnd) -{ - - sal_uInt16 nTemp; - nTreeFlags |= SvTreeFlags::USESEL; - if( nStart > nEnd ) - { - nTemp = nStart; - nStart = nEnd; - nEnd = nTemp; - } - // select all tabs that lie within the area - nTreeFlags |= SvTreeFlags::RECALCTABS; - nFirstSelTab = nStart; - nLastSelTab = nEnd; - pImpl->RecalcFocusRect(); -} - -void SvTreeListBox::Command(const CommandEvent& rCEvt) -{ - pImpl->Command(rCEvt); - //pass at least alt press/release to parent impl - if (rCEvt.GetCommand() == CommandEventId::ModKeyChange) - Control::Command(rCEvt); -} - -void SvTreeListBox::RemoveParentKeepChildren( SvTreeListEntry* pParent ) -{ - assert(pParent); - SvTreeListEntry* pNewParent = GetParent( pParent ); - if( pParent->HasChildren()) - { - SvTreeListEntry* pChild = FirstChild( pParent ); - while( pChild ) - { - pModel->Move( pChild, pNewParent, TREELIST_APPEND ); - pChild = FirstChild( pParent ); - } - } - pModel->Remove( pParent ); -} - -SvLBoxTab* SvTreeListBox::GetFirstTab( SvLBoxTabFlags nFlagMask, sal_uInt16& rPos ) -{ - sal_uInt16 nTabCount = aTabs.size(); - for( sal_uInt16 nPos = 0; nPos < nTabCount; nPos++ ) - { - SvLBoxTab* pTab = aTabs[ nPos ].get(); - if( pTab->nFlags & nFlagMask ) - { - rPos = nPos; - return pTab; - } - } - rPos = 0xffff; - return nullptr; -} - -void SvTreeListBox::GetLastTab( SvLBoxTabFlags nFlagMask, sal_uInt16& rTabPos ) -{ - sal_uInt16 nPos = static_cast<sal_uInt16>(aTabs.size()); - while( nPos ) - { - --nPos; - SvLBoxTab* pTab = aTabs[ nPos ].get(); - if( pTab->nFlags & nFlagMask ) - { - rTabPos = nPos; - return; - } - } - rTabPos = 0xffff; -} - -void SvTreeListBox::RequestHelp( const HelpEvent& rHEvt ) -{ - if( !pImpl->RequestHelp( rHEvt ) ) - Control::RequestHelp( rHEvt ); -} - -IMPL_LINK( SvTreeListBox, DefaultCompare, const SvSortData&, rData, sal_Int32 ) -{ - const SvTreeListEntry* pLeft = rData.pLeft; - const SvTreeListEntry* pRight = rData.pRight; - OUString aLeft( static_cast<const SvLBoxString*>(pLeft->GetFirstItem(SvLBoxItemType::String))->GetText()); - OUString aRight( static_cast<const SvLBoxString*>(pRight->GetFirstItem(SvLBoxItemType::String))->GetText()); - pImpl->UpdateStringSorter(); - return pImpl->m_pStringSorter->compare(aLeft, aRight); -} - -void SvTreeListBox::ModelNotification( SvListAction nActionId, SvTreeListEntry* pEntry1, - SvTreeListEntry* pEntry2, sal_uLong nPos ) -{ - SolarMutexGuard aSolarGuard; - - if( nActionId == SvListAction::CLEARING ) - CancelTextEditing(); - - SvListView::ModelNotification( nActionId, pEntry1, pEntry2, nPos ); - switch( nActionId ) - { - case SvListAction::INSERTED: - { - SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry1->GetFirstItem( SvLBoxItemType::ContextBmp ) ); - if ( !pBmpItem ) - break; - const Image& rBitmap1( pBmpItem->GetBitmap1() ); - const Image& rBitmap2( pBmpItem->GetBitmap2() ); - short nMaxWidth = short( std::max( rBitmap1.GetSizePixel().Width(), rBitmap2.GetSizePixel().Width() ) ); - nMaxWidth = pImpl->UpdateContextBmpWidthVector( pEntry1, nMaxWidth ); - if( nMaxWidth > nContextBmpWidthMax ) - { - nContextBmpWidthMax = nMaxWidth; - SetTabs(); - } - if (get_width_request() == -1) - queue_resize(); - } - break; - - case SvListAction::RESORTING: - SetUpdateMode( false ); - break; - - case SvListAction::RESORTED: - // after a selection: show first entry and also keep the selection - MakeVisible( pModel->First(), true ); - SetUpdateMode( true ); - break; - - case SvListAction::CLEARED: - if( IsUpdateMode() ) - Update(); - break; - - default: break; - } -} - -void SvTreeListBox::EndSelection() -{ - pImpl->EndSelection(); -} - -ScrollBar *SvTreeListBox::GetVScroll() -{ - return pImpl->aVerSBar.get(); -} - -ScrollBar *SvTreeListBox::GetHScroll() -{ - return pImpl->aHorSBar.get(); -} - -void SvTreeListBox::EnableAsyncDrag( bool b ) -{ - pImpl->EnableAsyncDrag( b ); -} - -SvTreeListEntry* SvTreeListBox::GetFirstEntryInView() const -{ - return GetEntry( Point() ); -} - -SvTreeListEntry* SvTreeListBox::GetNextEntryInView(SvTreeListEntry* pEntry ) const -{ - SvTreeListEntry* pNext = NextVisible( pEntry ); - if( pNext ) - { - Point aPos( GetEntryPosition(pNext) ); - const Size& rSize = pImpl->GetOutputSize(); - if( aPos.Y() < 0 || aPos.Y() >= rSize.Height() ) - return nullptr; - } - return pNext; -} - -SvTreeListEntry* SvTreeListBox::GetPrevEntryInView(SvTreeListEntry* pEntry ) const -{ - SvTreeListEntry* pPrev = PrevVisible( pEntry ); - if( pPrev ) - { - Point aPos( GetEntryPosition(pPrev) ); - const Size& rSize = pImpl->GetOutputSize(); - if( aPos.Y() < 0 || aPos.Y() >= rSize.Height() ) - return nullptr; - } - return pPrev; -} - -SvTreeListEntry* SvTreeListBox::GetLastEntryInView() const -{ - SvTreeListEntry* pEntry = GetFirstEntryInView(); - SvTreeListEntry* pNext = nullptr; - while( pEntry ) - { - pNext = NextVisible( pEntry ); - if( pNext ) - { - Point aPos( GetEntryPosition(pNext) ); - const Size& rSize = pImpl->GetOutputSize(); - if( aPos.Y() < 0 || aPos.Y() + GetEntryHeight() >= rSize.Height() ) - break; - else - pEntry = pNext; - } - else - break; - } - return pEntry; -} - -void SvTreeListBox::ShowFocusRect( const SvTreeListEntry* pEntry ) -{ - pImpl->ShowFocusRect( pEntry ); -} - -void SvTreeListBox::DataChanged( const DataChangedEvent& rDCEvt ) -{ - if( (rDCEvt.GetType()==DataChangedEventType::SETTINGS) && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) ) - { - nEntryHeight = 0; // _together_ with true of 1. par (bFont) of InitSettings() a zero-height - // forces complete recalc of heights! - InitSettings(); - Invalidate(); - } - else - Control::DataChanged( rDCEvt ); -} - -void SvTreeListBox::StateChanged( StateChangedType eType ) -{ - if( eType == StateChangedType::Enable ) - Invalidate( InvalidateFlags::Children ); - - Control::StateChanged( eType ); - - if ( eType == StateChangedType::Style ) - ImplInitStyle(); -} - -void SvTreeListBox::ApplySettings(vcl::RenderContext& rRenderContext) -{ - SetPointFont(rRenderContext, GetPointFont(*this)); - - const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings(); - rRenderContext.SetTextColor(rStyleSettings.GetFieldTextColor()); - rRenderContext.SetTextFillColor(); - rRenderContext.SetBackground(rStyleSettings.GetFieldColor()); - - // always try to re-create default-SvLBoxButtonData - if (pCheckButtonData && pCheckButtonData->HasDefaultImages()) - pCheckButtonData->SetDefaultImages(this); -} - -void SvTreeListBox::InitSettings() -{ - const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); - vcl::Font aFont; - aFont = rStyleSettings.GetFieldFont(); - aFont.SetColor(rStyleSettings.GetWindowTextColor()); - SetPointFont(*this, aFont); - AdjustEntryHeightAndRecalc(); - - SetTextColor(rStyleSettings.GetFieldTextColor()); - SetTextFillColor(); - - SetBackground(rStyleSettings.GetFieldColor()); - - // always try to re-create default-SvLBoxButtonData - if( pCheckButtonData && pCheckButtonData->HasDefaultImages() ) - pCheckButtonData->SetDefaultImages(this); -} - -bool SvTreeListBox::IsCellFocusEnabled() const -{ - return pImpl->IsCellFocusEnabled(); -} - -bool SvTreeListBox::SetCurrentTabPos( sal_uInt16 _nNewPos ) -{ - return pImpl->SetCurrentTabPos( _nNewPos ); -} - -sal_uInt16 SvTreeListBox::GetCurrentTabPos() const -{ - return pImpl->GetCurrentTabPos(); -} - -void SvTreeListBox::InitStartEntry() -{ - if( !pImpl->pStartEntry ) - pImpl->pStartEntry = GetModel()->First(); -} - -VclPtr<PopupMenu> SvTreeListBox::CreateContextMenu() -{ - return nullptr; -} - -void SvTreeListBox::ExecuteContextMenuAction( sal_uInt16 ) -{ - SAL_INFO( "svtools.contnr", "SvTreeListBox::ExecuteContextMenuAction(): now there's happening nothing!" ); -} - -void SvTreeListBox::EnableContextMenuHandling() -{ - assert(pImpl && "-SvTreeListBox::EnableContextMenuHandling(): No implementation!"); - pImpl->bContextMenuHandling = true; -} - -void SvTreeListBox::EnableList( bool _bEnable ) -{ - // call base class method - Window::Enable(_bEnable); - // then invalidate - Invalidate(tools::Rectangle(Point(), GetSizePixel())); -} - -css::uno::Reference< XAccessible > SvTreeListBox::CreateAccessible() -{ - vcl::Window* pParent = GetAccessibleParentWindow(); - DBG_ASSERT( pParent, "SvTreeListBox::CreateAccessible - accessible parent not found" ); - - css::uno::Reference< XAccessible > xAccessible; - if ( pParent ) - { - css::uno::Reference< XAccessible > xAccParent = pParent->GetAccessible(); - if ( xAccParent.is() ) - { - // need to be done here to get the vclxwindow later on in the accessible - css::uno::Reference< css::awt::XWindowPeer > xTemp(GetComponentInterface()); - xAccessible = pImpl->m_aFactoryAccess.getFactory().createAccessibleTreeListBox( *this, xAccParent ); - } - } - return xAccessible; -} - -void SvTreeListBox::FillAccessibleEntryStateSet( SvTreeListEntry* pEntry, ::utl::AccessibleStateSetHelper& rStateSet ) const -{ - assert(pEntry && "SvTreeListBox::FillAccessibleEntryStateSet: invalid entry"); - - if ( pEntry->HasChildrenOnDemand() || pEntry->HasChildren() ) - { - rStateSet.AddState( AccessibleStateType::EXPANDABLE ); - if ( IsExpanded( pEntry ) ) - rStateSet.AddState( sal_Int16(AccessibleStateType::EXPANDED) ); - } - - if ( GetCheckButtonState( pEntry ) == SvButtonState::Checked ) - rStateSet.AddState( AccessibleStateType::CHECKED ); - if ( IsEntryVisible( pEntry ) ) - rStateSet.AddState( AccessibleStateType::VISIBLE ); - if ( IsSelected( pEntry ) ) - rStateSet.AddState( AccessibleStateType::SELECTED ); - if ( IsEnabled() ) - { - rStateSet.AddState( AccessibleStateType::ENABLED ); - rStateSet.AddState( AccessibleStateType::FOCUSABLE ); - rStateSet.AddState( AccessibleStateType::SELECTABLE ); - SvViewDataEntry* pViewDataNewCur = GetViewDataEntry(pEntry); - if (pViewDataNewCur && pViewDataNewCur->HasFocus()) - rStateSet.AddState( AccessibleStateType::FOCUSED ); - } -} - -tools::Rectangle SvTreeListBox::GetBoundingRect( SvTreeListEntry* pEntry ) -{ - Point aPos = GetEntryPosition( pEntry ); - tools::Rectangle aRect = GetFocusRect( pEntry, aPos.Y() ); - return aRect; -} - -void SvTreeListBox::EnableCellFocus() -{ - pImpl->EnableCellFocus(); -} - -void SvTreeListBox::CallImplEventListeners(VclEventId nEvent, void* pData) -{ - CallEventListeners(nEvent, pData); -} - -void SvTreeListBox::set_min_width_in_chars(sal_Int32 nChars) -{ - nMinWidthInChars = nChars; - queue_resize(); -} - -bool SvTreeListBox::set_property(const OString &rKey, const OUString &rValue) -{ - if (rKey == "min-width-chars") - { - set_min_width_in_chars(rValue.toInt32()); - } - else - return Control::set_property(rKey, rValue); - return true; -} - -FactoryFunction SvTreeListBox::GetUITestFactory() const -{ - return TreeListUIObject::create; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/contnr/treelistentry.cxx b/svtools/source/contnr/treelistentry.cxx deleted file mode 100644 index 35c342f4a80f..000000000000 --- a/svtools/source/contnr/treelistentry.cxx +++ /dev/null @@ -1,241 +0,0 @@ -/* -*- 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 <memory> -#include <svtools/treelistentry.hxx> -#include <svtools/treelist.hxx> -#include <vcl/svapp.hxx> -#include <vcl/settings.hxx> - -#include <limits> - -void SvTreeListEntry::ClearChildren() -{ - m_Children.clear(); -} - -void SvTreeListEntry::SetListPositions() -{ - sal_uLong nCur = 0; - for (auto const& pEntry : m_Children) - { - SvTreeListEntry& rEntry = *pEntry; - rEntry.nListPos &= 0x80000000; - rEntry.nListPos |= nCur; - ++nCur; - } - - nListPos &= (~0x80000000); // remove the invalid bit. -} - -void SvTreeListEntry::InvalidateChildrensListPositions() -{ - nListPos |= 0x80000000; -} - -SvTreeListEntry::SvTreeListEntry() - : pParent(nullptr) - , nAbsPos(0) - , nListPos(0) - , pUserData(nullptr) - , nEntryFlags(SvTLEntryFlags::NONE) - , maBackColor(Application::GetSettings().GetStyleSettings().GetWindowColor()) -{ -} - -SvTreeListEntry::~SvTreeListEntry() -{ -#ifdef DBG_UTIL - pParent = nullptr; -#endif - - m_Children.clear(); - m_Items.clear(); -} - -bool SvTreeListEntry::HasChildren() const -{ - return !m_Children.empty(); -} - -bool SvTreeListEntry::HasChildListPos() const -{ - return pParent && !(pParent->nListPos & 0x80000000); -} - -sal_uLong SvTreeListEntry::GetChildListPos() const -{ - if( pParent && (pParent->nListPos & 0x80000000) ) - pParent->SetListPositions(); - return ( nListPos & 0x7fffffff ); -} - - -void SvTreeListEntry::Clone(SvTreeListEntry* pSource) -{ - nListPos &= 0x80000000; - nListPos |= ( pSource->nListPos & 0x7fffffff); - nAbsPos = pSource->nAbsPos; - - m_Items.clear(); - for (auto const& it : pSource->m_Items) - { - SvLBoxItem* pItem = &(*it); - std::unique_ptr<SvLBoxItem> pNewItem(pItem->Clone(pItem)); - m_Items.push_back(std::move(pNewItem)); - } - - pUserData = pSource->GetUserData(); - nEntryFlags = pSource->nEntryFlags; -} - -size_t SvTreeListEntry::ItemCount() const -{ - return m_Items.size(); -} - -void SvTreeListEntry::AddItem(std::unique_ptr<SvLBoxItem> pItem) -{ - m_Items.push_back(std::move(pItem)); -} - -void SvTreeListEntry::EnableChildrenOnDemand( bool bEnable ) -{ - if ( bEnable ) - nEntryFlags |= SvTLEntryFlags::CHILDREN_ON_DEMAND; - else - nEntryFlags &= (~SvTLEntryFlags::CHILDREN_ON_DEMAND); -} - -void SvTreeListEntry::ReplaceItem(std::unique_ptr<SvLBoxItem> pNewItem, size_t const nPos) -{ - DBG_ASSERT(pNewItem,"ReplaceItem:No Item"); - if (nPos >= m_Items.size()) - { - // Out of bound. Bail out. - pNewItem.reset(); - return; - } - - m_Items.erase(m_Items.begin()+nPos); - m_Items.insert(m_Items.begin()+nPos, std::move(pNewItem)); -} - -const SvLBoxItem& SvTreeListEntry::GetItem( size_t nPos ) const -{ - return *m_Items[nPos]; -} - -SvLBoxItem& SvTreeListEntry::GetItem( size_t nPos ) -{ - return *m_Items[nPos]; -} - -namespace { - -class FindByType -{ - SvLBoxItemType const meType; -public: - explicit FindByType(SvLBoxItemType eType) : meType(eType) {} - bool operator() (const std::unique_ptr<SvLBoxItem>& rpItem) const - { - return rpItem->GetType() == meType; - } -}; - -class FindByPointer -{ - const SvLBoxItem* mpItem; -public: - explicit FindByPointer(const SvLBoxItem* p) : mpItem(p) {} - bool operator() (const std::unique_ptr<SvLBoxItem>& rpItem) const - { - return rpItem.get() == mpItem; - } -}; - -} - -const SvLBoxItem* SvTreeListEntry::GetFirstItem(SvLBoxItemType eType) const -{ - ItemsType::const_iterator it = std::find_if(m_Items.begin(), m_Items.end(), FindByType(eType)); - return (it == m_Items.end()) ? nullptr : (*it).get(); -} - -SvLBoxItem* SvTreeListEntry::GetFirstItem(SvLBoxItemType eType) -{ - ItemsType::iterator it = std::find_if(m_Items.begin(), m_Items.end(), FindByType(eType)); - return (it == m_Items.end()) ? nullptr : (*it).get(); -} - -size_t SvTreeListEntry::GetPos( const SvLBoxItem* pItem ) const -{ - ItemsType::const_iterator it = std::find_if(m_Items.begin(), m_Items.end(), FindByPointer(pItem)); - return it == m_Items.end() ? ITEM_NOT_FOUND : std::distance(m_Items.begin(), it); -} - - -void SvTreeListEntry::SetUserData( void* pPtr ) -{ - pUserData = pPtr; -} - -bool SvTreeListEntry::HasChildrenOnDemand() const -{ - return static_cast<bool>(nEntryFlags & SvTLEntryFlags::CHILDREN_ON_DEMAND); -} - -bool SvTreeListEntry::HasInUseEmphasis() const -{ - return static_cast<bool>(nEntryFlags & SvTLEntryFlags::IN_USE); -} - - -void SvTreeListEntry::SetFlags( SvTLEntryFlags nFlags ) -{ - nEntryFlags = nFlags; -} - -SvTreeListEntry* SvTreeListEntry::NextSibling() const -{ - SvTreeListEntries& rList = pParent->m_Children; - sal_uLong nPos = GetChildListPos(); - nPos++; - return (nPos < rList.size()) ? rList[nPos].get() : nullptr; -} - -SvTreeListEntry* SvTreeListEntry::PrevSibling() const -{ - SvTreeListEntries& rList = pParent->m_Children; - sal_uLong nPos = GetChildListPos(); - if ( nPos == 0 ) - return nullptr; - nPos--; - return rList[nPos].get(); -} - - -SvTreeListEntry* SvTreeListEntry::LastSibling() const -{ - SvTreeListEntries& rChildren = pParent->m_Children; - return (rChildren.empty()) ? nullptr : rChildren.back().get(); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/contnr/viewdataentry.cxx b/svtools/source/contnr/viewdataentry.cxx deleted file mode 100644 index 53795b414db2..000000000000 --- a/svtools/source/contnr/viewdataentry.cxx +++ /dev/null @@ -1,102 +0,0 @@ -/* -*- 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 <svtools/viewdataentry.hxx> - -SvViewDataEntry::SvViewDataEntry() : - nVisPos(0), - mbSelected(false), - mbHighlighted(false), - mbExpanded(false), - mbFocused(false), - mbSelectable(true), - maPaintRectangle() -{ -} - -SvViewDataEntry::SvViewDataEntry( const SvViewDataEntry& rData ) : - nVisPos(rData.nVisPos), - mbSelected(false), - mbHighlighted(false), - mbExpanded(rData.mbExpanded), - mbFocused(false), - mbSelectable(rData.mbSelectable), - maPaintRectangle(rData.maPaintRectangle) -{ -} - -SvViewDataEntry::~SvViewDataEntry() -{ -#ifdef DBG_UTIL - nVisPos = 0x12345678; -#endif -} - -void SvViewDataEntry::SetFocus( bool bFocus ) -{ - mbFocused = bFocus; -} - -void SvViewDataEntry::SetSelected( bool bSelected ) -{ - mbSelected = bSelected; - mbHighlighted = bSelected; -} - -void SvViewDataEntry::SetHighlighted( bool bHighlighted ) -{ - mbHighlighted = bHighlighted; -} - -void SvViewDataEntry::SetExpanded( bool bExpanded ) -{ - mbExpanded = bExpanded; -} - -void SvViewDataEntry::SetSelectable( bool bSelectable ) -{ - mbSelectable = bSelectable; -} - -void SvViewDataEntry::Init(size_t nSize) -{ - maItems.resize(nSize); -} - -const SvViewDataItem& SvViewDataEntry::GetItem(size_t nPos) const -{ - return maItems[nPos]; -} - -SvViewDataItem& SvViewDataEntry::GetItem(size_t nPos) -{ - return maItems[nPos]; -} - -void SvViewDataEntry::SetPaintRectangle(tools::Rectangle aRectangle) -{ - maPaintRectangle = aRectangle; -} - -const tools::Rectangle& SvViewDataEntry::GetPaintRectangle() const -{ - return maPaintRectangle; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/inc/iconviewimpl.hxx b/svtools/source/inc/iconviewimpl.hxx index 516923f3f40c..df11f5952426 100644 --- a/svtools/source/inc/iconviewimpl.hxx +++ b/svtools/source/inc/iconviewimpl.hxx @@ -17,10 +17,10 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#ifndef INCLUDED_SVTOOLS_SOURCE_INC_ICONVIEWIMPL_HXX -#define INCLUDED_SVTOOLS_SOURCE_INC_ICONVIEWIMPL_HXX +#ifndef INCLUDED_VCL_SOURCE_INC_ICONVIEWIMPL_HXX +#define INCLUDED_VCL_SOURCE_INC_ICONVIEWIMPL_HXX -#include "svimpbox.hxx" +#include <vcl/svimpbox.hxx> class SvTreeListBox; class Point; @@ -63,6 +63,6 @@ protected: void AdjustScrollBars( Size& rSize ) override; }; -#endif // INCLUDED_SVTOOLS_SOURCE_INC_ICONVIEWIMPL_HXX +#endif // INCLUDED_VCL_SOURCE_INC_ICONVIEWIMPL_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/inc/svimpbox.hxx b/svtools/source/inc/svimpbox.hxx deleted file mode 100644 index 28fa2ed4b427..000000000000 --- a/svtools/source/inc/svimpbox.hxx +++ /dev/null @@ -1,416 +0,0 @@ -/* -*- 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 . - */ - -#ifndef INCLUDED_SVTOOLS_SOURCE_INC_SVIMPBOX_HXX -#define INCLUDED_SVTOOLS_SOURCE_INC_SVIMPBOX_HXX - -#include <vcl/seleng.hxx> -#include <vcl/scrbar.hxx> -#include <vcl/vclevent.hxx> -#include <unotools/intlwrapper.hxx> -#include <o3tl/enumarray.hxx> -#include <memory> -#include <vector> -#include "svtaccessiblefactory.hxx" - -class SvTreeListBox; -class Point; -class SvTreeList; -class SvImpLBox; -class SvTreeListEntry; -class SvLBoxTab; -namespace comphelper -{ - namespace string - { - class NaturalStringSorter; - } -} - -class ImpLBSelEng : public FunctionSet -{ - SvImpLBox* pImp; - VclPtr<SvTreeListBox> pView; - -public: - ImpLBSelEng( SvImpLBox* pImp, SvTreeListBox* pView ); - virtual ~ImpLBSelEng() override; - void BeginDrag() override; - void CreateAnchor() override; - void DestroyAnchor() override; - void SetCursorAtPoint( const Point& rPoint, - bool bDontSelectAtCursor=false ) override; - bool IsSelectionAtPoint( const Point& rPoint ) override; - void DeselectAtPoint( const Point& rPoint ) override; - void DeselectAll() override; -}; - -// Flags for nFlag -enum class LBoxFlags { - NONE = 0x0000, - InScrolling = 0x0001, - DeselectAll = 0x0002, - StartEditTimer = 0x0004, // MAC only - IgnoreSelect = 0x0008, - InResize = 0x0010, - RemovedEntryInvisible = 0x0020, - RemovedRecalcMostRight = 0x0040, - IgnoreChangedTabs = 0x0080, - InPaint = 0x0100, - EndScrollSetVisSize = 0x0200, - Filling = 0x0400, -}; -namespace o3tl -{ - template<> struct typed_flags<LBoxFlags> : is_typed_flags<LBoxFlags, 0x07ff> {}; -} - -#define NODE_BMP_TABDIST_NOTVALID -2000000 -#define FIRST_ENTRY_TAB 1 - -class SvImpLBox -{ -friend class ImpLBSelEng; -friend class SvTreeListBox; -friend class IconView; -private: - SvTreeList* pTree; - SvTreeListEntry* pAnchor; - SvTreeListEntry* pMostRightEntry; - SvLBoxButton* pActiveButton; - SvTreeListEntry* pActiveEntry; - SvLBoxTab* pActiveTab; - - VclPtr<ScrollBar> aHorSBar; - VclPtr<ScrollBarBox> aScrBarBox; - - ::svt::AccessibleFactoryAccess - m_aFactoryAccess; - - static Image* s_pDefCollapsed; - static Image* s_pDefExpanded; - static oslInterlockedCount s_nImageRefCount; /// When 0 all static images will be destroyed - - // Node Bitmaps - enum class ImageType - { - NodeExpanded = 0, // node is expanded ( usually a bitmap showing a minus ) - NodeCollapsed, // node is collapsed ( usually a bitmap showing a plus ) - NodeDontKnow, // don't know the node state - EntryDefExpanded, // default for expanded entries - EntryDefCollapsed, // default for collapsed entries - LAST = EntryDefCollapsed - }; - - // all our images - o3tl::enumarray<ImageType, Image> - m_aNodeAndEntryImages; - - ImpLBSelEng aFctSet; - Idle aAsyncBeginDragIdle; - Point aAsyncBeginDragPos; - - long nNodeBmpWidth; - long nMostRight; - short nHorSBarHeight, nVerSBarWidth; - sal_uInt16 nCurTabPos; - - bool bUpdateMode : 1; - bool bAsyncBeginDrag : 1; - bool bSubLstOpRet : 1; // open/close sublist with return/enter, defaulted with false - bool bSubLstOpLR : 1; // open/close sublist with cursor left/right, defaulted with false - bool bSubLstOpDblClick : 1; // open/close sublist with mouse double click, defaulted with true - bool bContextMenuHandling : 1; - bool bIsCellFocusEnabled : 1; - bool bAreChildrenTransient; - bool mbForceMakeVisible; - - Point aEditClickPos; - Idle aEditIdle; - - std::unique_ptr<comphelper::string::NaturalStringSorter> m_pStringSorter; - - std::vector< short > aContextBmpWidthVector; - - DECL_LINK(EditTimerCall, Timer *, void); - - DECL_LINK( BeginDragHdl, Timer*, void ); - - void InvalidateEntriesFrom( long nY ) const; - bool IsLineVisible( long nY ) const; - void KeyLeftRight( long nDiff ); - - void DrawNet(vcl::RenderContext& rRenderContext); - - // ScrollBar-Handler - DECL_LINK( ScrollUpDownHdl, ScrollBar*, void ); - DECL_LINK( ScrollLeftRightHdl, ScrollBar*, void ); - DECL_LINK( EndScrollHdl, ScrollBar*, void ); - - void SetNodeBmpWidth( const Image& ); - void SetNodeBmpTabDistance(); - - // Selection-Engine - SvTreeListEntry* MakePointVisible( const Point& rPoint ); - - void SetAnchorSelection( SvTreeListEntry* pOld, - SvTreeListEntry* pNewCursor ); - void BeginDrag(); - bool ButtonDownCheckCtrl( const MouseEvent& rMEvt, SvTreeListEntry* pEntry ); - bool MouseMoveCheckCtrl( const MouseEvent& rMEvt, SvTreeListEntry const * pEntry ); - bool ButtonUpCheckCtrl( const MouseEvent& rMEvt ); - bool ButtonDownCheckExpand( const MouseEvent&, SvTreeListEntry* ); - - bool EntryReallyHit(SvTreeListEntry* pEntry, const Point& rPos, long nLine); - void InitScrollBarBox(); - SvLBoxTab* NextTab( SvLBoxTab const * ); - - bool SetMostRight( SvTreeListEntry* pEntry ); - void FindMostRight( SvTreeListEntry* pParent, SvTreeListEntry* EntryToIgnore ); - void FindMostRight_Impl( SvTreeListEntry* pParent,SvTreeListEntry* EntryToIgnore ); - void NotifyTabsChanged(); - - // if element at cursor can be expanded in general - bool IsExpandable() const; - - static void implInitDefaultNodeImages(); - - void UpdateStringSorter(); - - short UpdateContextBmpWidthVector( SvTreeListEntry const * pEntry, short nWidth ); - void UpdateContextBmpWidthMax( SvTreeListEntry const * pEntry ); - void UpdateContextBmpWidthVectorFromMovedEntry( SvTreeListEntry* pEntry ); - - void CalcCellFocusRect( SvTreeListEntry const * pEntry, tools::Rectangle& rRect ); - - bool AreChildrenTransient() const { return bAreChildrenTransient; } - void SetChildrenNotTransient() { bAreChildrenTransient = false; } - -protected: - VclPtr<SvTreeListBox> pView; - VclPtr<ScrollBar> aVerSBar; - SvTreeListEntry* pCursor; - SvTreeListEntry* pStartEntry; - ImplSVEvent* nCurUserEvent; - Size aOutputSize; - LBoxFlags nFlags; - WinBits m_nStyle; - bool mbNoAutoCurEntry; // disable the behavior of automatically selecting a "CurEntry" upon painting the control - SelectionEngine aSelEng; - sal_uLong nVisibleCount; // Number of lines in control - bool bInVScrollHdl : 1; - bool bSimpleTravel : 1; // is true if SelectionMode::Single - long nNextVerVisSize; - long nNodeBmpTabDistance; // typical smaller than 0 - - virtual long GetEntryLine( SvTreeListEntry* pEntry ) const; - virtual void CursorDown(); - virtual void CursorUp(); - virtual void PageDown( sal_uInt16 nDelta ); - virtual void PageUp( sal_uInt16 nDelta ); - // set Thumb to FirstEntryToDraw - virtual void SyncVerThumb(); - virtual void AdjustScrollBars( Size& rSize ); - virtual void InvalidateEntry( long nY ) const; - - tools::Rectangle GetVisibleArea() const; - void SetCursor( SvTreeListEntry* pEntry, bool bForceNoSelect = false ); - void BeginScroll(); - void EndScroll(); - void PositionScrollBars( Size& rOSize, sal_uInt16 nMask ); - void FindMostRight( SvTreeListEntry const * EntryToIgnore ); - void FillView(); - void ShowVerSBar(); - void StopUserEvent(); - - DECL_LINK( MyUserEvent, void*, void); - -public: - SvImpLBox( SvTreeListBox* pView, SvTreeList*, WinBits nWinStyle ); - virtual ~SvImpLBox(); - - void Clear(); - void SetStyle( WinBits i_nWinStyle ); - void SetNoAutoCurEntry( bool b ); - void SetModel( SvTreeList* pModel ) { pTree = pModel;} - - void EntryInserted( SvTreeListEntry*); - void RemovingEntry( SvTreeListEntry* pEntry ); - void EntryRemoved(); - void MovingEntry( SvTreeListEntry* pEntry ); - void EntryMoved( SvTreeListEntry* pEntry ); - void TreeInserted( SvTreeListEntry* pEntry ); - - void EntryExpanded( SvTreeListEntry* pEntry ); - void EntryCollapsed( SvTreeListEntry* pEntry ); - void CollapsingEntry( SvTreeListEntry* pEntry ); - void EntrySelected( SvTreeListEntry* pEntry, bool bSelect ); - - virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect); - void MouseButtonDown( const MouseEvent& ); - void MouseButtonUp( const MouseEvent& ); - void MouseMove( const MouseEvent&); - virtual bool KeyInput( const KeyEvent& ); - void Resize(); - void GetFocus(); - void LoseFocus(); - virtual void UpdateAll( bool bInvalidateCompleteView ); - void SetEntryHeight(); - void InvalidateEntry( SvTreeListEntry* ); - void RecalcFocusRect(); - - void SelectEntry( SvTreeListEntry* pEntry, bool bSelect ); - void SetDragDropMode( DragDropMode eDDMode ); - void SetSelectionMode( SelectionMode eSelMode ); - - SvTreeListEntry* GetCurrentEntry() const { return pCursor; } - virtual bool IsEntryInView( SvTreeListEntry* pEntry ) const; - virtual SvTreeListEntry* GetEntry( const Point& rPos ) const; - // returns last entry, if Pos below last entry - virtual SvTreeListEntry* GetClickedEntry( const Point& ) const; - SvTreeListEntry* GetCurEntry() const { return pCursor; } - void SetCurEntry( SvTreeListEntry* ); - virtual Point GetEntryPosition( SvTreeListEntry* ) const; - void MakeVisible( SvTreeListEntry* pEntry, bool bMoveToTop = false ); - void ScrollToAbsPos( long nPos ); - - void PaintDDCursor( SvTreeListEntry* ); - - // Images - inline Image& implGetImageLocation( const ImageType _eType ); - - inline void SetExpandedNodeBmp( const Image& _rImg ); - inline void SetCollapsedNodeBmp( const Image& _rImg ); - - inline const Image& GetExpandedNodeBmp( ); - inline const Image& GetCollapsedNodeBmp( ); - inline const Image& GetDontKnowNodeBmp( ); - - inline void SetDefaultEntryExpBmp( const Image& _rImg ); - inline void SetDefaultEntryColBmp( const Image& _rImg ); - inline const Image& GetDefaultEntryExpBmp( ); - inline const Image& GetDefaultEntryColBmp( ); - - static const Image& GetDefaultExpandedNodeImage( ); - static const Image& GetDefaultCollapsedNodeImage( ); - - const Size& GetOutputSize() const { return aOutputSize;} - virtual void KeyUp( bool bPageUp ); - virtual void KeyDown( bool bPageDown ); - void Command( const CommandEvent& rCEvt ); - - void Invalidate(); - void DestroyAnchor() { pAnchor=nullptr; aSelEng.Reset(); } - void SelAllDestrAnch( bool bSelect, bool bDestroyAnchor = true, bool bSingleSelToo = false ); - void ShowCursor( bool bShow ); - - bool RequestHelp( const HelpEvent& rHEvt ); - void EndSelection(); - bool IsNodeButton( const Point& rPosPixel, SvTreeListEntry* pEntry ) const; - void EnableAsyncDrag( bool b ) { bAsyncBeginDrag = b; } - void SetUpdateMode( bool bMode ); - bool GetUpdateMode() const { return bUpdateMode; } - tools::Rectangle GetClipRegionRect() const; - bool HasHorScrollBar() const { return aHorSBar->IsVisible(); } - void ShowFocusRect( const SvTreeListEntry* pEntry ); - void CallEventListeners( VclEventId nEvent, void* pData = nullptr ); - - /** Enables, that one cell of a tablistbox entry can be focused */ - bool IsCellFocusEnabled() const { return bIsCellFocusEnabled; } - void EnableCellFocus() { bIsCellFocusEnabled = true; } - bool SetCurrentTabPos( sal_uInt16 _nNewPos ); - sal_uInt16 GetCurrentTabPos() const { return nCurTabPos; } - - bool IsSelectable( const SvTreeListEntry* pEntry ); - void SetForceMakeVisible(bool bEnable) { mbForceMakeVisible = bEnable; } -}; - -inline Image& SvImpLBox::implGetImageLocation( const ImageType _eType ) -{ - return m_aNodeAndEntryImages[_eType]; -} - -inline void SvImpLBox::SetExpandedNodeBmp( const Image& rImg ) -{ - implGetImageLocation( ImageType::NodeExpanded ) = rImg; - SetNodeBmpWidth( rImg ); -} - -inline void SvImpLBox::SetCollapsedNodeBmp( const Image& rImg ) -{ - implGetImageLocation( ImageType::NodeCollapsed ) = rImg; - SetNodeBmpWidth( rImg ); -} - -inline const Image& SvImpLBox::GetDontKnowNodeBmp( ) -{ - return implGetImageLocation( ImageType::NodeDontKnow ); -} - -inline const Image& SvImpLBox::GetExpandedNodeBmp( ) -{ - return implGetImageLocation( ImageType::NodeExpanded ); -} - -inline const Image& SvImpLBox::GetCollapsedNodeBmp( ) -{ - return implGetImageLocation( ImageType::NodeCollapsed ); -} - -inline void SvImpLBox::SetDefaultEntryExpBmp( const Image& _rImg ) -{ - implGetImageLocation( ImageType::EntryDefExpanded ) = _rImg; -} - -inline void SvImpLBox::SetDefaultEntryColBmp( const Image& _rImg ) -{ - implGetImageLocation( ImageType::EntryDefCollapsed ) = _rImg; -} - -inline const Image& SvImpLBox::GetDefaultEntryExpBmp( ) -{ - return implGetImageLocation( ImageType::EntryDefExpanded ); -} - -inline const Image& SvImpLBox::GetDefaultEntryColBmp( ) -{ - return implGetImageLocation( ImageType::EntryDefCollapsed ); -} - -inline Point SvImpLBox::GetEntryPosition( SvTreeListEntry* pEntry ) const -{ - return Point( 0, GetEntryLine( pEntry ) ); -} - -inline bool SvImpLBox::IsLineVisible( long nY ) const -{ - bool bRet = true; - if ( nY < 0 || nY >= aOutputSize.Height() ) - bRet = false; - return bRet; -} - -inline void SvImpLBox::TreeInserted( SvTreeListEntry* pInsTree ) -{ - EntryInserted( pInsTree ); -} - -#endif // INCLUDED_SVTOOLS_SOURCE_INC_SVIMPBOX_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/misc/cliplistener.cxx b/svtools/source/misc/cliplistener.cxx index c2d21d4a47c1..992d9efb9370 100644 --- a/svtools/source/misc/cliplistener.cxx +++ b/svtools/source/misc/cliplistener.cxx @@ -24,7 +24,7 @@ #include <vcl/window.hxx> #include <svtools/cliplistener.hxx> -#include <svtools/transfer.hxx> +#include <vcl/transfer.hxx> using namespace ::com::sun::star; diff --git a/svtools/source/misc/imap.cxx b/svtools/source/misc/imap.cxx deleted file mode 100644 index 0a2739f7eb4c..000000000000 --- a/svtools/source/misc/imap.cxx +++ /dev/null @@ -1,991 +0,0 @@ -/* -*- 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 <tools/urlobj.hxx> -#include <tools/fract.hxx> -#include <vcl/svapp.hxx> -#include <vcl/mapmod.hxx> -#include <vcl/window.hxx> -#include <o3tl/numeric.hxx> -#include <svl/urihelper.hxx> -#include <svtools/imap.hxx> -#include <svtools/imapobj.hxx> -#include <svtools/imapcirc.hxx> -#include <svtools/imaprect.hxx> -#include <svtools/imappoly.hxx> - -#include <string.h> -#include <math.h> -#include <memory> -#include <sal/log.hxx> - - -#define SCALEPOINT(aPT,aFracX,aFracY) (aPT).setX(long((aPT).X()*aFracX)); \ - (aPT).setY(long((aPT).Y()*aFracY)); - - -/******************************************************************************/ - -sal_uInt16 IMapObject::nActualTextEncoding = sal_uInt16(RTL_TEXTENCODING_DONTKNOW); - -/******************************************************************************/ - - -IMapObject::IMapObject() - : bActive( false ) - , nReadVersion( 0 ) -{ -} - -IMapObject::IMapObject( const OUString& rURL, const OUString& rAltText, const OUString& rDesc, - const OUString& rTarget, const OUString& rName, bool bURLActive ) -: aURL( rURL ) -, aAltText( rAltText ) -, aDesc( rDesc ) -, aTarget( rTarget ) -, aName( rName ) -, bActive( bURLActive ) -, nReadVersion( 0 ) -{ -} - - -void IMapObject::Write( SvStream& rOStm ) const -{ - const rtl_TextEncoding eEncoding = osl_getThreadTextEncoding(); - - rOStm.WriteUInt16( GetType() ); - rOStm.WriteUInt16( IMAP_OBJ_VERSION ); - rOStm.WriteUInt16( eEncoding ); - - const OString aRelURL = OUStringToOString( - URIHelper::simpleNormalizedMakeRelative("", aURL), eEncoding); - write_uInt16_lenPrefixed_uInt8s_FromOString(rOStm, aRelURL); - write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aAltText, eEncoding); - rOStm.WriteBool( bActive ); - write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aTarget, eEncoding); - - std::unique_ptr<IMapCompat> pCompat(new IMapCompat( rOStm, StreamMode::WRITE )); - - WriteIMapObject( rOStm ); - aEventList.Write( rOStm ); // V4 - write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aName, eEncoding); // V5 -} - - -/****************************************************************************** -|* -|* Binary import -|* -\******************************************************************************/ - -void IMapObject::Read( SvStream& rIStm ) -{ - rtl_TextEncoding nTextEncoding; - - // read on type and version - rIStm.SeekRel( 2 ); - rIStm.ReadUInt16( nReadVersion ); - rIStm.ReadUInt16( nTextEncoding ); - aURL = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStm, nTextEncoding); - aAltText = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStm, nTextEncoding); - rIStm.ReadCharAsBool( bActive ); - aTarget = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStm, nTextEncoding); - - // make URL absolute - aURL = URIHelper::SmartRel2Abs( INetURLObject(""), aURL, URIHelper::GetMaybeFileHdl(), true, false, INetURLObject::EncodeMechanism::WasEncoded, INetURLObject::DecodeMechanism::Unambiguous ); - std::unique_ptr<IMapCompat> pCompat(new IMapCompat( rIStm, StreamMode::READ )); - - ReadIMapObject( rIStm ); - - // from version 4 onwards we read a eventlist - if ( nReadVersion >= 0x0004 ) - { - aEventList.Read(rIStm); - - // from version 5 onwards an objectname could be available - if ( nReadVersion >= 0x0005 ) - aName = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStm, nTextEncoding); - } -} - -bool IMapObject::IsEqual( const IMapObject& rEqObj ) -{ - return ( ( aURL == rEqObj.aURL ) && - ( aAltText == rEqObj.aAltText ) && - ( aDesc == rEqObj.aDesc ) && - ( aTarget == rEqObj.aTarget ) && - ( aName == rEqObj.aName ) && - ( bActive == rEqObj.bActive ) ); -} - -IMapRectangleObject::IMapRectangleObject( const tools::Rectangle& rRect, - const OUString& rURL, - const OUString& rAltText, - const OUString& rDesc, - const OUString& rTarget, - const OUString& rName, - bool bURLActive, - bool bPixelCoords ) : - IMapObject ( rURL, rAltText, rDesc, rTarget, rName, bURLActive ) -{ - ImpConstruct( rRect, bPixelCoords ); -} - -void IMapRectangleObject::ImpConstruct( const tools::Rectangle& rRect, bool bPixel ) -{ - if ( bPixel ) - aRect = Application::GetDefaultDevice()->PixelToLogic( rRect, MapMode( MapUnit::Map100thMM ) ); - else - aRect = rRect; -} - - -/****************************************************************************** -|* -|* Binary export -|* -\******************************************************************************/ - -void IMapRectangleObject::WriteIMapObject( SvStream& rOStm ) const -{ - WriteRectangle( rOStm, aRect ); -} - - -/****************************************************************************** -|* -|* Binary import -|* -\******************************************************************************/ - -void IMapRectangleObject::ReadIMapObject( SvStream& rIStm ) -{ - ReadRectangle( rIStm, aRect ); -} - - -/****************************************************************************** -|* -|* return type -|* -\******************************************************************************/ - -sal_uInt16 IMapRectangleObject::GetType() const -{ - return IMAP_OBJ_RECTANGLE; -} - - -/****************************************************************************** -|* -|* Hit test -|* -\******************************************************************************/ - -bool IMapRectangleObject::IsHit( const Point& rPoint ) const -{ - return aRect.IsInside( rPoint ); -} - -tools::Rectangle IMapRectangleObject::GetRectangle( bool bPixelCoords ) const -{ - tools::Rectangle aNewRect; - - if ( bPixelCoords ) - aNewRect = Application::GetDefaultDevice()->LogicToPixel( aRect, MapMode( MapUnit::Map100thMM ) ); - else - aNewRect = aRect; - - return aNewRect; -} - -void IMapRectangleObject::Scale( const Fraction& rFracX, const Fraction& rFracY ) -{ - Point aTL( aRect.TopLeft() ); - Point aBR( aRect.BottomRight() ); - - if ( rFracX.GetDenominator() && rFracY.GetDenominator() ) - { - SCALEPOINT( aTL, rFracX, rFracY ); - SCALEPOINT( aBR, rFracX, rFracY ); - } - - aRect = tools::Rectangle( aTL, aBR ); -} - -bool IMapRectangleObject::IsEqual( const IMapRectangleObject& rEqObj ) -{ - return ( IMapObject::IsEqual( rEqObj ) && ( aRect == rEqObj.aRect ) ); -} - -IMapCircleObject::IMapCircleObject( const Point& rCenter, sal_uLong nCircleRadius, - const OUString& rURL, - const OUString& rAltText, - const OUString& rDesc, - const OUString& rTarget, - const OUString& rName, - bool bURLActive, - bool bPixelCoords ) : - IMapObject ( rURL, rAltText, rDesc, rTarget, rName, bURLActive ) -{ - ImpConstruct( rCenter, nCircleRadius, bPixelCoords ); -} - -void IMapCircleObject::ImpConstruct( const Point& rCenter, sal_uLong nRad, bool bPixel ) -{ - if ( bPixel ) - { - MapMode aMap100( MapUnit::Map100thMM ); - - aCenter = Application::GetDefaultDevice()->PixelToLogic( rCenter, aMap100 ); - nRadius = Application::GetDefaultDevice()->PixelToLogic( Size( nRad, 0 ), aMap100 ).Width(); - } - else - { - aCenter = rCenter; - nRadius = nRad; - } -} - - -/****************************************************************************** -|* -|* Binary export -|* -\******************************************************************************/ - -void IMapCircleObject::WriteIMapObject( SvStream& rOStm ) const -{ - sal_uInt32 nTmp = nRadius; - - WritePair( rOStm, aCenter ); - rOStm.WriteUInt32( nTmp ); -} - - -/****************************************************************************** -|* -|* Binary import -|* -\******************************************************************************/ - -void IMapCircleObject::ReadIMapObject( SvStream& rIStm ) -{ - sal_uInt32 nTmp; - - ReadPair( rIStm, aCenter ); - rIStm.ReadUInt32( nTmp ); - - nRadius = nTmp; -} - - -/****************************************************************************** -|* -|* return type -|* -\******************************************************************************/ - -sal_uInt16 IMapCircleObject::GetType() const -{ - return IMAP_OBJ_CIRCLE; -} - - -/****************************************************************************** -|* -|* Hit-Test -|* -\******************************************************************************/ - -bool IMapCircleObject::IsHit( const Point& rPoint ) const -{ - const Point aPoint( aCenter - rPoint ); - bool bRet = false; - - if ( static_cast<sal_Int32>(sqrt( static_cast<double>(aPoint.X()) * aPoint.X() + - aPoint.Y() * aPoint.Y() )) <= nRadius ) - { - bRet = true; - } - - return bRet; -} - -Point IMapCircleObject::GetCenter( bool bPixelCoords ) const -{ - Point aNewPoint; - - if ( bPixelCoords ) - aNewPoint = Application::GetDefaultDevice()->LogicToPixel( aCenter, MapMode( MapUnit::Map100thMM ) ); - else - aNewPoint = aCenter; - - return aNewPoint; -} - -sal_uLong IMapCircleObject::GetRadius( bool bPixelCoords ) const -{ - sal_uLong nNewRadius; - - if ( bPixelCoords ) - nNewRadius = Application::GetDefaultDevice()->LogicToPixel( Size( nRadius, 0 ), MapMode( MapUnit::Map100thMM ) ).Width(); - else - nNewRadius = nRadius; - - return nNewRadius; -} - -void IMapCircleObject::Scale( const Fraction& rFracX, const Fraction& rFracY ) -{ - Fraction aAverage( rFracX ); - - aAverage += rFracY; - aAverage *= Fraction( 1, 2 ); - - if ( rFracX.GetDenominator() && rFracY.GetDenominator() ) - { - SCALEPOINT( aCenter, rFracX, rFracY ); - } - - if (!aAverage.GetDenominator()) - throw o3tl::divide_by_zero(); - - nRadius = double(nRadius * aAverage); -} - -bool IMapCircleObject::IsEqual( const IMapCircleObject& rEqObj ) -{ - return ( IMapObject::IsEqual( rEqObj ) && - ( aCenter == rEqObj.aCenter ) && - ( nRadius == rEqObj.nRadius ) ); -} - -IMapPolygonObject::IMapPolygonObject( const tools::Polygon& rPoly, - const OUString& rURL, - const OUString& rAltText, - const OUString& rDesc, - const OUString& rTarget, - const OUString& rName, - bool bURLActive, - bool bPixelCoords ) : - IMapObject ( rURL, rAltText, rDesc, rTarget, rName, bURLActive ), - bEllipse ( false ) -{ - ImpConstruct( rPoly, bPixelCoords ); -} - -void IMapPolygonObject::ImpConstruct( const tools::Polygon& rPoly, bool bPixel ) -{ - if ( bPixel ) - aPoly = Application::GetDefaultDevice()->PixelToLogic( rPoly, MapMode( MapUnit::Map100thMM ) ); - else - aPoly = rPoly; -} - - -/****************************************************************************** -|* -|* Binary export -|* -\******************************************************************************/ - -void IMapPolygonObject::WriteIMapObject( SvStream& rOStm ) const -{ - WritePolygon( rOStm, aPoly ); - rOStm.WriteBool( bEllipse ); // >= Version 2 - WriteRectangle( rOStm, aEllipse ); // >= Version 2 -} - - -/****************************************************************************** -|* -|* Binary import -|* -\******************************************************************************/ - -void IMapPolygonObject::ReadIMapObject( SvStream& rIStm ) -{ - ReadPolygon( rIStm, aPoly ); - - // Version >= 2 has additional ellipses information - if ( nReadVersion >= 2 ) - { - rIStm.ReadCharAsBool( bEllipse ); - ReadRectangle( rIStm, aEllipse ); - } -} - - -/****************************************************************************** -|* -|* return type -|* -\******************************************************************************/ - -sal_uInt16 IMapPolygonObject::GetType() const -{ - return IMAP_OBJ_POLYGON; -} - - -/****************************************************************************** -|* -|* hit test -|* -\******************************************************************************/ - -bool IMapPolygonObject::IsHit( const Point& rPoint ) const -{ - return aPoly.IsInside( rPoint ); -} - -tools::Polygon IMapPolygonObject::GetPolygon( bool bPixelCoords ) const -{ - tools::Polygon aNewPoly; - - if ( bPixelCoords ) - aNewPoly = Application::GetDefaultDevice()->LogicToPixel( aPoly, MapMode( MapUnit::Map100thMM ) ); - else - aNewPoly = aPoly; - - return aNewPoly; -} - -void IMapPolygonObject::SetExtraEllipse( const tools::Rectangle& rEllipse ) -{ - if ( aPoly.GetSize() ) - { - bEllipse = true; - aEllipse = rEllipse; - } -} - -void IMapPolygonObject::Scale( const Fraction& rFracX, const Fraction& rFracY ) -{ - sal_uInt16 nCount = aPoly.GetSize(); - - for ( sal_uInt16 i = 0; i < nCount; i++ ) - { - Point aScaledPt( aPoly[ i ] ); - - if ( rFracX.GetDenominator() && rFracY.GetDenominator() ) - { - SCALEPOINT( aScaledPt, rFracX, rFracY ); - } - - aPoly[ i ] = aScaledPt; - } - - if ( !bEllipse ) - return; - - Point aTL( aEllipse.TopLeft() ); - Point aBR( aEllipse.BottomRight() ); - - if ( rFracX.GetDenominator() && rFracY.GetDenominator() ) - { - SCALEPOINT( aTL, rFracX, rFracY ); - SCALEPOINT( aBR, rFracX, rFracY ); - } - - aEllipse = tools::Rectangle( aTL, aBR ); -} - -bool IMapPolygonObject::IsEqual( const IMapPolygonObject& rEqObj ) -{ - bool bRet = false; - - if ( IMapObject::IsEqual( rEqObj ) ) - { - const tools::Polygon& rEqPoly = rEqObj.aPoly; - const sal_uInt16 nCount = aPoly.GetSize(); - const sal_uInt16 nEqCount = rEqPoly.GetSize(); - - if ( nCount == nEqCount ) - { - bool bDifferent = false; - - for ( sal_uInt16 i = 0; i < nCount; i++ ) - { - if ( aPoly[ i ] != rEqPoly[ i ] ) - { - bDifferent = true; - break; - } - } - - if ( !bDifferent ) - bRet = true; - } - } - - return bRet; -} - -/****************************************************************************** -|* -|* Ctor -|* -\******************************************************************************/ - -ImageMap::ImageMap( const OUString& rName ) -: aName( rName ) -{ -} - - -/****************************************************************************** -|* -|* Copy-Ctor -|* -\******************************************************************************/ - -ImageMap::ImageMap( const ImageMap& rImageMap ) -{ - - size_t nCount = rImageMap.GetIMapObjectCount(); - - for ( size_t i = 0; i < nCount; i++ ) - { - IMapObject* pCopyObj = rImageMap.GetIMapObject( i ); - - switch( pCopyObj->GetType() ) - { - case IMAP_OBJ_RECTANGLE: - maList.emplace_back( new IMapRectangleObject( *static_cast<IMapRectangleObject*>( pCopyObj ) ) ); - break; - - case IMAP_OBJ_CIRCLE: - maList.emplace_back( new IMapCircleObject( *static_cast<IMapCircleObject*>( pCopyObj ) ) ); - break; - - case IMAP_OBJ_POLYGON: - maList.emplace_back( new IMapPolygonObject( *static_cast<IMapPolygonObject*>( pCopyObj ) ) ); - break; - - default: - break; - } - } - - aName = rImageMap.aName; -} - - -/****************************************************************************** -|* -|* Dtor -|* -\******************************************************************************/ - -ImageMap::~ImageMap() -{ -} - - -/****************************************************************************** -|* -|* release internal memory -|* -\******************************************************************************/ - -void ImageMap::ClearImageMap() -{ - maList.clear(); - - aName.clear(); -} - - -/****************************************************************************** -|* -|* assignment operator -|* -\******************************************************************************/ - -ImageMap& ImageMap::operator=( const ImageMap& rImageMap ) -{ - if (this != &rImageMap) - { - size_t nCount = rImageMap.GetIMapObjectCount(); - - ClearImageMap(); - - for ( size_t i = 0; i < nCount; i++ ) - { - IMapObject* pCopyObj = rImageMap.GetIMapObject( i ); - - switch( pCopyObj->GetType() ) - { - case IMAP_OBJ_RECTANGLE: - maList.emplace_back( new IMapRectangleObject( *static_cast<IMapRectangleObject*>(pCopyObj) ) ); - break; - - case IMAP_OBJ_CIRCLE: - maList.emplace_back( new IMapCircleObject( *static_cast<IMapCircleObject*>(pCopyObj) ) ); - break; - - case IMAP_OBJ_POLYGON: - maList.emplace_back( new IMapPolygonObject( *static_cast<IMapPolygonObject*>(pCopyObj) ) ); - break; - - default: - break; - } - } - - aName = rImageMap.aName; - } - return *this; -} - - -/****************************************************************************** -|* -|* compare operator I -|* -\******************************************************************************/ - -bool ImageMap::operator==( const ImageMap& rImageMap ) -{ - const size_t nCount = maList.size(); - const size_t nEqCount = rImageMap.GetIMapObjectCount(); - bool bRet = false; - - if ( nCount == nEqCount ) - { - bool bDifferent = ( aName != rImageMap.aName ); - - for ( size_t i = 0; ( i < nCount ) && !bDifferent; i++ ) - { - IMapObject* pObj = maList[ i ].get(); - IMapObject* pEqObj = rImageMap.GetIMapObject( i ); - - if ( pObj->GetType() == pEqObj->GetType() ) - { - switch( pObj->GetType() ) - { - case IMAP_OBJ_RECTANGLE: - { - if ( ! static_cast<IMapRectangleObject*>(pObj)->IsEqual( *static_cast<IMapRectangleObject*>(pEqObj) ) ) - bDifferent = true; - } - break; - - case IMAP_OBJ_CIRCLE: - { - if ( ! static_cast<IMapCircleObject*>(pObj)->IsEqual( *static_cast<IMapCircleObject*>(pEqObj) ) ) - bDifferent = true; - } - break; - - case IMAP_OBJ_POLYGON: - { - if ( ! static_cast<IMapPolygonObject*>(pObj)->IsEqual( *static_cast<IMapPolygonObject*>(pEqObj) ) ) - bDifferent = true; - } - break; - - default: - break; - } - } - else - bDifferent = true; - } - - if ( !bDifferent ) - bRet = true; - } - - return bRet; -} - - -/****************************************************************************** -|* -|* compare operator II -|* -\******************************************************************************/ - -bool ImageMap::operator!=( const ImageMap& rImageMap ) -{ - return !( *this == rImageMap ); -} - - -/****************************************************************************** -|* -|* insert new object -|* -\******************************************************************************/ - -void ImageMap::InsertIMapObject( const IMapObject& rIMapObject ) -{ - switch( rIMapObject.GetType() ) - { - case IMAP_OBJ_RECTANGLE: - maList.emplace_back( new IMapRectangleObject( static_cast<const IMapRectangleObject&>( rIMapObject ) ) ); - break; - - case IMAP_OBJ_CIRCLE: - maList.emplace_back( new IMapCircleObject( static_cast<const IMapCircleObject&>( rIMapObject ) ) ); - break; - - case IMAP_OBJ_POLYGON: - maList.emplace_back( new IMapPolygonObject( static_cast<const IMapPolygonObject&>( rIMapObject ) ) ); - break; - - default: - break; - } -} - -void ImageMap::InsertIMapObject( std::unique_ptr<IMapObject> pNewObject ) -{ - maList.emplace_back( std::move(pNewObject) ); -} - -/****************************************************************************** -|* -|* hit test -|* -\******************************************************************************/ - -IMapObject* ImageMap::GetHitIMapObject( const Size& rTotalSize, - const Size& rDisplaySize, - const Point& rRelHitPoint, - sal_uLong nFlags ) -{ - Point aRelPoint( rTotalSize.Width() * rRelHitPoint.X() / rDisplaySize.Width(), - rTotalSize.Height() * rRelHitPoint.Y() / rDisplaySize.Height() ); - - // transform point to check before checking if flags to mirror etc. are set, - if ( nFlags ) - { - if ( nFlags & IMAP_MIRROR_HORZ ) - aRelPoint.setX( rTotalSize.Width() - aRelPoint.X() ); - - if ( nFlags & IMAP_MIRROR_VERT ) - aRelPoint.setY( rTotalSize.Height() - aRelPoint.Y() ); - } - - // walk over all objects and execute HitTest - IMapObject* pObj = nullptr; - for(auto& i : maList) { - if ( i->IsHit( aRelPoint ) ) { - pObj = i.get(); - break; - } - } - - return( pObj ? ( pObj->IsActive() ? pObj : nullptr ) : nullptr ); -} - -void ImageMap::Scale( const Fraction& rFracX, const Fraction& rFracY ) -{ - size_t nCount = maList.size(); - - for ( size_t i = 0; i < nCount; i++ ) - { - IMapObject* pObj = maList[ i ].get(); - - switch( pObj->GetType() ) - { - case IMAP_OBJ_RECTANGLE: - static_cast<IMapRectangleObject*>( pObj )->Scale( rFracX, rFracY ); - break; - - case IMAP_OBJ_CIRCLE: - static_cast<IMapCircleObject*>( pObj )->Scale( rFracX, rFracY ); - break; - - case IMAP_OBJ_POLYGON: - static_cast<IMapPolygonObject*>( pObj )->Scale( rFracX, rFracY ); - break; - - default: - break; - } - } -} - - -/****************************************************************************** -|* -|* sequentially write objects -|* -\******************************************************************************/ - -void ImageMap::ImpWriteImageMap( SvStream& rOStm ) const -{ - size_t nCount = maList.size(); - - for ( size_t i = 0; i < nCount; i++ ) - { - auto& pObj = maList[ i ]; - pObj->Write( rOStm ); - } -} - - -/****************************************************************************** -|* -|* sequentially read objects -|* -\******************************************************************************/ - -void ImageMap::ImpReadImageMap( SvStream& rIStm, size_t nCount ) -{ - const size_t nMinRecordSize = 12; //circle, three 32bit numbers - const size_t nMaxRecords = rIStm.remainingSize() / nMinRecordSize; - - if (nCount > nMaxRecords) - { - SAL_WARN("svtools.misc", "Parsing error: " << nMaxRecords << " max possible entries, but " << - nCount << " claimed, truncating"); - nCount = nMaxRecords; - } - - // read new objects - for (size_t i = 0; i < nCount; ++i) - { - sal_uInt16 nType; - - rIStm.ReadUInt16( nType ); - rIStm.SeekRel( -2 ); - - switch( nType ) - { - case IMAP_OBJ_RECTANGLE: - { - IMapRectangleObject* pObj = new IMapRectangleObject; - pObj->Read( rIStm ); - maList.emplace_back( pObj ); - } - break; - - case IMAP_OBJ_CIRCLE: - { - IMapCircleObject* pObj = new IMapCircleObject; - pObj->Read( rIStm ); - maList.emplace_back( pObj ); - } - break; - - case IMAP_OBJ_POLYGON: - { - IMapPolygonObject* pObj = new IMapPolygonObject; - pObj->Read( rIStm ); - maList.emplace_back( pObj ); - } - break; - - default: - break; - } - } -} - - -/****************************************************************************** -|* -|* store binary -|* -\******************************************************************************/ - -void ImageMap::Write( SvStream& rOStm ) const -{ - IMapCompat* pCompat; - OUString aImageName( GetName() ); - SvStreamEndian nOldFormat = rOStm.GetEndian(); - sal_uInt16 nCount = static_cast<sal_uInt16>(GetIMapObjectCount()); - const rtl_TextEncoding eEncoding = osl_getThreadTextEncoding(); //vomit! - - rOStm.SetEndian( SvStreamEndian::LITTLE ); - - // write MagicCode - rOStm.WriteCharPtr( IMAPMAGIC ); - rOStm.WriteUInt16( IMAGE_MAP_VERSION ); - write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aImageName, eEncoding); - write_uInt16_lenPrefixed_uInt8s_FromOString(rOStm, OString()); //dummy - rOStm.WriteUInt16( nCount ); - write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aImageName, eEncoding); - - pCompat = new IMapCompat( rOStm, StreamMode::WRITE ); - - // here one can insert in newer versions - - delete pCompat; - - ImpWriteImageMap( rOStm ); - - rOStm.SetEndian( nOldFormat ); -} - - -/****************************************************************************** -|* -|* load binary -|* -\******************************************************************************/ - -void ImageMap::Read( SvStream& rIStm ) -{ - char cMagic[6]; - SvStreamEndian nOldFormat = rIStm.GetEndian(); - sal_uInt16 nCount; - - rIStm.SetEndian( SvStreamEndian::LITTLE ); - rIStm.ReadBytes(cMagic, sizeof(cMagic)); - - if ( !memcmp( cMagic, IMAPMAGIC, sizeof( cMagic ) ) ) - { - IMapCompat* pCompat; - - // delete old content - ClearImageMap(); - - // read on version - rIStm.SeekRel( 2 ); - - aName = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStm, osl_getThreadTextEncoding()); - read_uInt16_lenPrefixed_uInt8s_ToOString(rIStm); // Dummy - rIStm.ReadUInt16( nCount ); - read_uInt16_lenPrefixed_uInt8s_ToOString(rIStm); // Dummy - - pCompat = new IMapCompat( rIStm, StreamMode::READ ); - - // here one can read in newer versions - - delete pCompat; - ImpReadImageMap( rIStm, nCount ); - - } - else - rIStm.SetError( SVSTREAM_GENERALERROR ); - - rIStm.SetEndian( nOldFormat ); -} - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/misc/imap2.cxx b/svtools/source/misc/imap2.cxx deleted file mode 100644 index da99028254fa..000000000000 --- a/svtools/source/misc/imap2.cxx +++ /dev/null @@ -1,532 +0,0 @@ -/* -*- 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 <comphelper/string.hxx> -#include <string.h> -#include <rtl/strbuf.hxx> -#include <vcl/svapp.hxx> -#include <tools/urlobj.hxx> -#include <vcl/wrkwin.hxx> -#include <sot/formats.hxx> - -#include <svl/urihelper.hxx> -#include <svtools/imap.hxx> -#include <svtools/imapobj.hxx> -#include <svtools/imaprect.hxx> -#include <svtools/imapcirc.hxx> -#include <svtools/imappoly.hxx> - -#include <math.h> - -#define NOTEOL(c) ((c)!='\0') - -void IMapObject::AppendCERNCoords(OStringBuffer& rBuf, const Point& rPoint100) -{ - const Point aPixPt( Application::GetDefaultDevice()->LogicToPixel( rPoint100, MapMode( MapUnit::Map100thMM ) ) ); - - rBuf.append('('); - rBuf.append(static_cast<sal_Int32>(aPixPt.X())); - rBuf.append(','); - rBuf.append(static_cast<sal_Int32>(aPixPt.Y())); - rBuf.append(") "); -} - -void IMapObject::AppendNCSACoords(OStringBuffer& rBuf, const Point& rPoint100) -{ - const Point aPixPt( Application::GetDefaultDevice()->LogicToPixel( rPoint100, MapMode( MapUnit::Map100thMM ) ) ); - - rBuf.append(static_cast<sal_Int32>(aPixPt.X())); - rBuf.append(','); - rBuf.append(static_cast<sal_Int32>(aPixPt.Y())); - rBuf.append(' '); -} - -void IMapObject::AppendCERNURL(OStringBuffer& rBuf) const -{ - rBuf.append(OUStringToOString(URIHelper::simpleNormalizedMakeRelative("", aURL), osl_getThreadTextEncoding())); -} - -void IMapObject::AppendNCSAURL(OStringBuffer& rBuf) const -{ - rBuf.append(OUStringToOString(URIHelper::simpleNormalizedMakeRelative("", aURL), osl_getThreadTextEncoding())); - rBuf.append(' '); -} - -void IMapRectangleObject::WriteCERN( SvStream& rOStm ) const -{ - OStringBuffer aStrBuf("rectangle "); - - AppendCERNCoords(aStrBuf, aRect.TopLeft()); - AppendCERNCoords(aStrBuf, aRect.BottomRight()); - AppendCERNURL(aStrBuf); - - rOStm.WriteLine(aStrBuf.makeStringAndClear()); -} - -void IMapRectangleObject::WriteNCSA( SvStream& rOStm ) const -{ - OStringBuffer aStrBuf("rect "); - - AppendNCSAURL(aStrBuf); - AppendNCSACoords(aStrBuf, aRect.TopLeft()); - AppendNCSACoords(aStrBuf, aRect.BottomRight()); - - rOStm.WriteLine(aStrBuf.makeStringAndClear()); -} - -void IMapCircleObject::WriteCERN( SvStream& rOStm ) const -{ - OStringBuffer aStrBuf("circle "); - - AppendCERNCoords(aStrBuf, aCenter); - aStrBuf.append(nRadius); - aStrBuf.append(' '); - AppendCERNURL(aStrBuf); - - rOStm.WriteLine(aStrBuf.makeStringAndClear()); -} - -void IMapCircleObject::WriteNCSA( SvStream& rOStm ) const -{ - OStringBuffer aStrBuf("circle "); - - AppendNCSAURL(aStrBuf); - AppendNCSACoords(aStrBuf, aCenter); - AppendNCSACoords(aStrBuf, aCenter + Point(nRadius, 0)); - - rOStm.WriteLine(aStrBuf.makeStringAndClear()); -} - -void IMapPolygonObject::WriteCERN( SvStream& rOStm ) const -{ - OStringBuffer aStrBuf("polygon "); - const sal_uInt16 nCount = aPoly.GetSize(); - - for (sal_uInt16 i = 0; i < nCount; ++i) - AppendCERNCoords(aStrBuf, aPoly[i]); - - AppendCERNURL(aStrBuf); - - rOStm.WriteLine(aStrBuf.makeStringAndClear()); -} - -void IMapPolygonObject::WriteNCSA( SvStream& rOStm ) const -{ - OStringBuffer aStrBuf("poly "); - const sal_uInt16 nCount = std::min( aPoly.GetSize(), sal_uInt16(100) ); - - AppendNCSAURL(aStrBuf); - - for (sal_uInt16 i = 0; i < nCount; ++i) - AppendNCSACoords(aStrBuf, aPoly[i]); - - rOStm.WriteLine(aStrBuf.makeStringAndClear()); -} - -void ImageMap::Write( SvStream& rOStm, sal_uLong nFormat ) const -{ - switch( nFormat ) - { - case IMAP_FORMAT_BIN : Write( rOStm ); break; - case IMAP_FORMAT_CERN : ImpWriteCERN( rOStm ); break; - case IMAP_FORMAT_NCSA : ImpWriteNCSA( rOStm ); break; - - default: - break; - } -} - -void ImageMap::ImpWriteCERN( SvStream& rOStm ) const -{ - size_t nCount = maList.size(); - - for ( size_t i = 0; i < nCount; i++ ) - { - IMapObject* pObj = maList[ i ].get(); - - switch( pObj->GetType() ) - { - case IMAP_OBJ_RECTANGLE: - static_cast<IMapRectangleObject*>( pObj )->WriteCERN( rOStm ); - break; - - case IMAP_OBJ_CIRCLE: - static_cast<IMapCircleObject*>( pObj )->WriteCERN( rOStm ); - break; - - case IMAP_OBJ_POLYGON: - static_cast<IMapPolygonObject*>( pObj )->WriteCERN( rOStm ); - break; - - default: - break; - } - } -} - -void ImageMap::ImpWriteNCSA( SvStream& rOStm ) const -{ - size_t nCount = maList.size(); - - for ( size_t i = 0; i < nCount; i++ ) - { - IMapObject* pObj = maList[ i ].get(); - - switch( pObj->GetType() ) - { - case IMAP_OBJ_RECTANGLE: - static_cast<IMapRectangleObject*>( pObj )->WriteNCSA( rOStm ); - break; - - case IMAP_OBJ_CIRCLE: - static_cast<IMapCircleObject*>( pObj )->WriteNCSA( rOStm ); - break; - - case IMAP_OBJ_POLYGON: - static_cast<IMapPolygonObject*>( pObj )->WriteNCSA( rOStm ); - break; - - default: - break; - } - } -} - -sal_uLong ImageMap::Read( SvStream& rIStm, sal_uLong nFormat ) -{ - sal_uLong nRet = IMAP_ERR_FORMAT; - - if ( nFormat == IMAP_FORMAT_DETECT ) - nFormat = ImpDetectFormat( rIStm ); - - switch ( nFormat ) - { - case IMAP_FORMAT_BIN : Read( rIStm ); break; - case IMAP_FORMAT_CERN : ImpReadCERN( rIStm ); break; - case IMAP_FORMAT_NCSA : ImpReadNCSA( rIStm ); break; - - default: - break; - } - - if ( !rIStm.GetError() ) - nRet = IMAP_ERR_OK; - - return nRet; -} - -void ImageMap::ImpReadCERN( SvStream& rIStm ) -{ - // delete old content - ClearImageMap(); - - OString aStr; - while ( rIStm.ReadLine( aStr ) ) - ImpReadCERNLine( aStr ); -} - -void ImageMap::ImpReadCERNLine( const OString& rLine ) -{ - OString aStr = comphelper::string::stripStart(rLine, ' '); - aStr = comphelper::string::stripStart(aStr, '\t'); - aStr = aStr.replaceAll(";", ""); - aStr = aStr.toAsciiLowerCase(); - - const char* pStr = aStr.getStr(); - char cChar = *pStr++; - - // find instruction - OStringBuffer aBuf; - while( ( cChar >= 'a' ) && ( cChar <= 'z' ) && NOTEOL( cChar ) ) - { - aBuf.append(cChar); - cChar = *pStr++; - } - OString aToken = aBuf.makeStringAndClear(); - - if ( !(NOTEOL( cChar )) ) - return; - - if ( ( aToken == "rectangle" ) || ( aToken == "rect" ) ) - { - const Point aTopLeft( ImpReadCERNCoords( &pStr ) ); - const Point aBottomRight( ImpReadCERNCoords( &pStr ) ); - const OUString aURL( ImpReadCERNURL( &pStr ) ); - const tools::Rectangle aRect( aTopLeft, aBottomRight ); - - maList.emplace_back( new IMapRectangleObject( aRect, aURL, OUString(), OUString(), OUString(), OUString() ) ); - } - else if ( ( aToken == "circle" ) || ( aToken == "circ" ) ) - { - const Point aCenter( ImpReadCERNCoords( &pStr ) ); - const long nRadius = ImpReadCERNRadius( &pStr ); - const OUString aURL( ImpReadCERNURL( &pStr ) ); - - maList.emplace_back( new IMapCircleObject( aCenter, nRadius, aURL, OUString(), OUString(), OUString(), OUString() ) ); - } - else if ( ( aToken == "polygon" ) || ( aToken == "poly" ) ) - { - const sal_uInt16 nCount = comphelper::string::getTokenCount(aStr, '(') - 1; - tools::Polygon aPoly( nCount ); - - for ( sal_uInt16 i = 0; i < nCount; i++ ) - aPoly[ i ] = ImpReadCERNCoords( &pStr ); - - const OUString aURL = ImpReadCERNURL( &pStr ); - - maList.emplace_back( new IMapPolygonObject( aPoly, aURL, OUString(), OUString(), OUString(), OUString() ) ); - } -} - -Point ImageMap::ImpReadCERNCoords( const char** ppStr ) -{ - OUStringBuffer aStrX; - OUStringBuffer aStrY; - Point aPt; - char cChar = *(*ppStr)++; - - while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) ) - cChar = *(*ppStr)++; - - if ( NOTEOL( cChar ) ) - { - while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) ) - { - aStrX.append( cChar ); - cChar = *(*ppStr)++; - } - - if ( NOTEOL( cChar ) ) - { - while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) ) - cChar = *(*ppStr)++; - - while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) ) - { - aStrY.append( cChar ); - cChar = *(*ppStr)++; - } - - if ( NOTEOL( cChar ) ) - while( NOTEOL( cChar ) && ( cChar != ')' ) ) - cChar = *(*ppStr)++; - - aPt = Point( aStrX.makeStringAndClear().toInt32(), aStrY.makeStringAndClear().toInt32() ); - } - } - - return aPt; -} - -long ImageMap::ImpReadCERNRadius( const char** ppStr ) -{ - OUStringBuffer aStr; - char cChar = *(*ppStr)++; - - while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) ) - cChar = *(*ppStr)++; - - if ( NOTEOL( cChar ) ) - { - while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) ) - { - aStr.append( cChar ); - cChar = *(*ppStr)++; - } - } - - return aStr.makeStringAndClear().toInt32(); -} - -OUString ImageMap::ImpReadCERNURL( const char** ppStr ) -{ - OUString aStr(OUString::createFromAscii(*ppStr)); - - aStr = comphelper::string::stripStart(aStr, ' '); - aStr = comphelper::string::stripStart(aStr, '\t'); - aStr = comphelper::string::stripEnd(aStr, ' '); - aStr = comphelper::string::stripEnd(aStr, '\t'); - - return INetURLObject::GetAbsURL( "", aStr ); -} - -void ImageMap::ImpReadNCSA( SvStream& rIStm ) -{ - // delete old content - ClearImageMap(); - - OString aStr; - while ( rIStm.ReadLine( aStr ) ) - ImpReadNCSALine( aStr ); -} - -void ImageMap::ImpReadNCSALine( const OString& rLine ) -{ - OString aStr = comphelper::string::stripStart(rLine, ' '); - aStr = comphelper::string::stripStart(aStr, '\t'); - aStr = aStr.replaceAll(";", ""); - aStr = aStr.toAsciiLowerCase(); - - const char* pStr = aStr.getStr(); - char cChar = *pStr++; - - // find instruction - OStringBuffer aBuf; - while( ( cChar >= 'a' ) && ( cChar <= 'z' ) && NOTEOL( cChar ) ) - { - aBuf.append(cChar); - cChar = *pStr++; - } - OString aToken = aBuf.makeStringAndClear(); - - if ( !(NOTEOL( cChar )) ) - return; - - if ( aToken == "rect" ) - { - const OUString aURL( ImpReadNCSAURL( &pStr ) ); - const Point aTopLeft( ImpReadNCSACoords( &pStr ) ); - const Point aBottomRight( ImpReadNCSACoords( &pStr ) ); - const tools::Rectangle aRect( aTopLeft, aBottomRight ); - - maList.emplace_back( new IMapRectangleObject( aRect, aURL, OUString(), OUString(), OUString(), OUString() ) ); - } - else if ( aToken == "circle" ) - { - const OUString aURL( ImpReadNCSAURL( &pStr ) ); - const Point aCenter( ImpReadNCSACoords( &pStr ) ); - const Point aDX( aCenter - ImpReadNCSACoords( &pStr ) ); - long nRadius = static_cast<long>(sqrt( static_cast<double>(aDX.X()) * aDX.X() + - static_cast<double>(aDX.Y()) * aDX.Y() )); - - maList.emplace_back( new IMapCircleObject( aCenter, nRadius, aURL, OUString(), OUString(), OUString(), OUString() ) ); - } - else if ( aToken == "poly" ) - { - const sal_uInt16 nCount = comphelper::string::getTokenCount(aStr, ',') - 1; - const OUString aURL( ImpReadNCSAURL( &pStr ) ); - tools::Polygon aPoly( nCount ); - - for ( sal_uInt16 i = 0; i < nCount; i++ ) - aPoly[ i ] = ImpReadNCSACoords( &pStr ); - - maList.emplace_back( new IMapPolygonObject( aPoly, aURL, OUString(), OUString(), OUString(), OUString() ) ); - } -} - -OUString ImageMap::ImpReadNCSAURL( const char** ppStr ) -{ - OUStringBuffer aStr; - char cChar = *(*ppStr)++; - - while( NOTEOL( cChar ) && ( ( cChar == ' ' ) || ( cChar == '\t' ) ) ) - cChar = *(*ppStr)++; - - if ( NOTEOL( cChar ) ) - { - while( NOTEOL( cChar ) && ( cChar != ' ' ) && ( cChar != '\t' ) ) - { - aStr.append( cChar ); - cChar = *(*ppStr)++; - } - } - - return INetURLObject::GetAbsURL( "", aStr.makeStringAndClear() ); -} - -Point ImageMap::ImpReadNCSACoords( const char** ppStr ) -{ - OUStringBuffer aStrX; - OUStringBuffer aStrY; - Point aPt; - char cChar = *(*ppStr)++; - - while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) ) - cChar = *(*ppStr)++; - - if ( NOTEOL( cChar ) ) - { - while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) ) - { - aStrX.append( cChar ); - cChar = *(*ppStr)++; - } - - if ( NOTEOL( cChar ) ) - { - while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) ) - cChar = *(*ppStr)++; - - while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) ) - { - aStrY.append( cChar ); - cChar = *(*ppStr)++; - } - - aPt = Point( aStrX.makeStringAndClear().toInt32(), aStrY.makeStringAndClear().toInt32() ); - } - } - - return aPt; -} - -sal_uLong ImageMap::ImpDetectFormat( SvStream& rIStm ) -{ - sal_uInt64 nPos = rIStm.Tell(); - sal_uLong nRet = IMAP_FORMAT_BIN; - char cMagic[6]; - - rIStm.ReadBytes(cMagic, sizeof(cMagic)); - - // if we do not have an internal formats - // we check the format - if ( memcmp( cMagic, IMAPMAGIC, sizeof( cMagic ) ) ) - { - long nCount = 128; - - rIStm.Seek( nPos ); - OString aStr; - while ( rIStm.ReadLine( aStr ) && nCount-- ) - { - aStr = aStr.toAsciiLowerCase(); - - if ( (aStr.indexOf("rect") != -1) || - (aStr.indexOf("circ") != -1) || - (aStr.indexOf("poly") != -1) ) - { - if ( ( aStr.indexOf('(') != -1 ) && - ( aStr.indexOf(')') != -1 ) ) - { - nRet = IMAP_FORMAT_CERN; - } - else - nRet = IMAP_FORMAT_NCSA; - - break; - } - } - } - - rIStm.Seek( nPos ); - - return nRet; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/misc/imap3.cxx b/svtools/source/misc/imap3.cxx deleted file mode 100644 index eed27dd2a729..000000000000 --- a/svtools/source/misc/imap3.cxx +++ /dev/null @@ -1,87 +0,0 @@ -/* -*- 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 <svtools/imap.hxx> - -#include <tools/debug.hxx> - - -/****************************************************************************** -|* -|* Ctor -|* -\******************************************************************************/ - -IMapCompat::IMapCompat( SvStream& rStm, const StreamMode nStreamMode ) - : pRWStm(&rStm) - , nCompatPos(0) - , nTotalSize(0) - , nStmMode(nStreamMode) -{ - DBG_ASSERT( nStreamMode == StreamMode::READ || nStreamMode == StreamMode::WRITE, "Wrong Mode!" ); - - if ( pRWStm->GetError() ) - return; - - if ( nStmMode == StreamMode::WRITE ) - { - nCompatPos = pRWStm->Tell(); - pRWStm->SeekRel( 4 ); - nTotalSize = nCompatPos + 4; - } - else - { - sal_uInt32 nTotalSizeTmp; - pRWStm->ReadUInt32( nTotalSizeTmp ); - nTotalSize = nTotalSizeTmp; - nCompatPos = pRWStm->Tell(); - } -} - - -/****************************************************************************** -|* -|* Dtor -|* -\******************************************************************************/ - -IMapCompat::~IMapCompat() -{ - if ( pRWStm->GetError() ) - return; - - if ( nStmMode == StreamMode::WRITE ) - { - const sal_uInt64 nEndPos = pRWStm->Tell(); - - pRWStm->Seek( nCompatPos ); - pRWStm->WriteUInt32( nEndPos - nTotalSize ); - pRWStm->Seek( nEndPos ); - } - else - { - const sal_uInt64 nReadSize = pRWStm->Tell() - nCompatPos; - - if ( nTotalSize > nReadSize ) - pRWStm->SeekRel( nTotalSize - nReadSize ); - } -} - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/misc/openfiledroptargetlistener.cxx b/svtools/source/misc/openfiledroptargetlistener.cxx index 06e92db659ae..4baed7364fd7 100644 --- a/svtools/source/misc/openfiledroptargetlistener.cxx +++ b/svtools/source/misc/openfiledroptargetlistener.cxx @@ -26,7 +26,7 @@ #include <com/sun/star/util/URLTransformer.hpp> #include <com/sun/star/util/XURLTransformer.hpp> -#include <svtools/transfer.hxx> +#include <vcl/transfer.hxx> #include <sot/filelist.hxx> #include <osl/file.hxx> diff --git a/svtools/source/misc/svtaccessiblefactory.cxx b/svtools/source/misc/svtaccessiblefactory.cxx index 08bb8710a555..8d0bbcc04e3c 100644 --- a/svtools/source/misc/svtaccessiblefactory.cxx +++ b/svtools/source/misc/svtaccessiblefactory.cxx @@ -110,15 +110,6 @@ namespace svt } virtual css::uno::Reference< css::accessibility::XAccessible > - createAccessibleTreeListBox( - SvTreeListBox& /*_rListBox*/, - const css::uno::Reference< css::accessibility::XAccessible >& /*_xParent*/ - ) const override - { - return nullptr; - } - - virtual css::uno::Reference< css::accessibility::XAccessible > createAccessibleBrowseBoxHeaderBar( const css::uno::Reference< css::accessibility::XAccessible >& /*rxParent*/, IAccessibleTableProvider& /*_rOwningTable*/, diff --git a/svtools/source/misc/transfer.cxx b/svtools/source/misc/transfer.cxx deleted file mode 100644 index 44c01059684d..000000000000 --- a/svtools/source/misc/transfer.cxx +++ /dev/null @@ -1,2177 +0,0 @@ -/* -*- 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 . - */ - -#ifdef _WIN32 -#include <prewin.h> -#include <postwin.h> -#include <shlobj.h> -#endif -#include <osl/mutex.hxx> -#include <rtl/uri.hxx> -#include <sal/log.hxx> -#include <tools/debug.hxx> -#include <tools/urlobj.hxx> -#include <unotools/ucbstreamhelper.hxx> -#include <sot/exchange.hxx> -#include <sot/storage.hxx> -#include <vcl/bitmap.hxx> -#include <vcl/gdimtf.hxx> -#include <vcl/graph.hxx> -#include <vcl/cvtgrf.hxx> -#include <vcl/svapp.hxx> -#include <vcl/window.hxx> -#include <comphelper/fileformat.h> -#include <comphelper/processfactory.hxx> -#include <comphelper/servicehelper.hxx> -#include <comphelper/sequence.hxx> -#include <sot/filelist.hxx> -#include <cppuhelper/implbase.hxx> - -#include <comphelper/seqstream.hxx> -#include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp> -#include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp> -#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp> -#include <com/sun/star/datatransfer/MimeContentTypeFactory.hpp> -#include <com/sun/star/datatransfer/XMimeContentType.hpp> -#include <com/sun/star/datatransfer/XTransferable2.hpp> -#include <com/sun/star/frame/Desktop.hpp> -#include <com/sun/star/lang/XInitialization.hpp> - -#include <svl/urlbmk.hxx> -#include <svtools/inetimg.hxx> -#include <vcl/wmf.hxx> -#include <svtools/imap.hxx> -#include <svtools/transfer.hxx> -#include <rtl/strbuf.hxx> -#include <cstdio> -#include <vcl/dibtools.hxx> -#include <vcl/pngread.hxx> -#include <vcl/pngwrite.hxx> -#include <vcl/graphicfilter.hxx> -#include <memory> - - -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::lang; -using namespace ::com::sun::star::frame; -using namespace ::com::sun::star::io; -using namespace ::com::sun::star::datatransfer; -using namespace ::com::sun::star::datatransfer::clipboard; -using namespace ::com::sun::star::datatransfer::dnd; - - -#define TOD_SIG1 0x01234567 -#define TOD_SIG2 0x89abcdef - -SvStream& WriteTransferableObjectDescriptor( SvStream& rOStm, const TransferableObjectDescriptor& rObjDesc ) -{ - const sal_uInt32 nFirstPos = rOStm.Tell(), nViewAspect = rObjDesc.mnViewAspect; - const sal_uInt32 nSig1 = TOD_SIG1, nSig2 = TOD_SIG2; - - rOStm.SeekRel( 4 ); - WriteSvGlobalName( rOStm, rObjDesc.maClassName ); - rOStm.WriteUInt32( nViewAspect ); - rOStm.WriteInt32( rObjDesc.maSize.Width() ); - rOStm.WriteInt32( rObjDesc.maSize.Height() ); - rOStm.WriteInt32( rObjDesc.maDragStartPos.X() ); - rOStm.WriteInt32( rObjDesc.maDragStartPos.Y() ); - rOStm.WriteUniOrByteString( rObjDesc.maTypeName, osl_getThreadTextEncoding() ); - rOStm.WriteUniOrByteString( rObjDesc.maDisplayName, osl_getThreadTextEncoding() ); - rOStm.WriteUInt32( nSig1 ).WriteUInt32( nSig2 ); - - const sal_uInt32 nLastPos = rOStm.Tell(); - - rOStm.Seek( nFirstPos ); - rOStm.WriteUInt32( nLastPos - nFirstPos ); - rOStm.Seek( nLastPos ); - - return rOStm; -} - - -// the reading of the parameter is done using the special service css::datatransfer::MimeContentType, -// a similar approach should be implemented for creation of the mimetype string; -// for now the set of acceptable characters has to be hardcoded, in future it should be part of the service that creates the mimetype - -static OUString ImplGetParameterString( const TransferableObjectDescriptor& rObjDesc ) -{ - const OUString aClassName( rObjDesc.maClassName.GetHexName() ); - OUString aParams; - - if( !aClassName.isEmpty() ) - { - aParams += ";classname=\"" + aClassName + "\""; - } - - if( !rObjDesc.maTypeName.isEmpty() ) - { - aParams += ";typename=\"" + rObjDesc.maTypeName + "\""; - } - - if( !rObjDesc.maDisplayName.isEmpty() ) - { - // the display name might contain unacceptable characters, encode all of them - // this seems to be the only parameter currently that might contain such characters - sal_Bool pToAccept[128]; - for (sal_Bool & rb : pToAccept) - rb = false; - - const char aQuotedParamChars[] = - "()<>@,;:/[]?=!#$&'*+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~. "; - - for ( sal_Int32 nInd = 0; nInd < RTL_CONSTASCII_LENGTH(aQuotedParamChars); ++nInd ) - { - sal_Unicode nChar = aQuotedParamChars[nInd]; - if ( nChar < 128 ) - pToAccept[nChar] = true; - } - - aParams += ";displayname=\"" - + rtl::Uri::encode( - rObjDesc.maDisplayName, pToAccept, rtl_UriEncodeIgnoreEscapes, - RTL_TEXTENCODING_UTF8) - + "\""; - } - - aParams += ";viewaspect=\"" + OUString::number(rObjDesc.mnViewAspect) - + "\";width=\"" + OUString::number(rObjDesc.maSize.Width()) - + "\";height=\"" + OUString::number(rObjDesc.maSize.Height()) - + "\";posx=\"" + OUString::number(rObjDesc.maDragStartPos.X()) - + "\";posy=\"" + OUString::number(rObjDesc.maDragStartPos.X()) + "\""; - - return aParams; -} - - -static void ImplSetParameterString( TransferableObjectDescriptor& rObjDesc, const DataFlavorEx& rFlavorEx ) -{ - Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() ); - - try - { - Reference< XMimeContentTypeFactory > xMimeFact = MimeContentTypeFactory::create( xContext ); - - Reference< XMimeContentType > xMimeType( xMimeFact->createMimeContentType( rFlavorEx.MimeType ) ); - - if( xMimeType.is() ) - { - const OUString aClassNameString( "classname" ); - const OUString aTypeNameString( "typename" ); - const OUString aDisplayNameString( "displayname" ); - const OUString aViewAspectString( "viewaspect" ); - const OUString aWidthString( "width" ); - const OUString aHeightString( "height" ); - const OUString aPosXString( "posx" ); - const OUString aPosYString( "posy" ); - - if( xMimeType->hasParameter( aClassNameString ) ) - { - rObjDesc.maClassName.MakeId( xMimeType->getParameterValue( aClassNameString ) ); - } - - if( xMimeType->hasParameter( aTypeNameString ) ) - { - rObjDesc.maTypeName = xMimeType->getParameterValue( aTypeNameString ); - } - - if( xMimeType->hasParameter( aDisplayNameString ) ) - { - // the display name might contain unacceptable characters, in this case they should be encoded - // this seems to be the only parameter currently that might contain such characters - rObjDesc.maDisplayName = ::rtl::Uri::decode( xMimeType->getParameterValue( aDisplayNameString ), rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 ); - } - - if( xMimeType->hasParameter( aViewAspectString ) ) - { - rObjDesc.mnViewAspect = static_cast< sal_uInt16 >( xMimeType->getParameterValue( aViewAspectString ).toInt32() ); - } - - if( xMimeType->hasParameter( aWidthString ) ) - { - rObjDesc.maSize.setWidth( xMimeType->getParameterValue( aWidthString ).toInt32() ); - } - - if( xMimeType->hasParameter( aHeightString ) ) - { - rObjDesc.maSize.setHeight( xMimeType->getParameterValue( aHeightString ).toInt32() ); - } - - if( xMimeType->hasParameter( aPosXString ) ) - { - rObjDesc.maDragStartPos.setX( xMimeType->getParameterValue( aPosXString ).toInt32() ); - } - - if( xMimeType->hasParameter( aPosYString ) ) - { - rObjDesc.maDragStartPos.setY( xMimeType->getParameterValue( aPosYString ).toInt32() ); - } - } - } - catch( const css::uno::Exception& ) - { - } -} - - -TransferableHelper::TerminateListener::TerminateListener( TransferableHelper& rTransferableHelper ) : - mrParent( rTransferableHelper ) -{ -} - - -TransferableHelper::TerminateListener::~TerminateListener() -{ -} - - -void SAL_CALL TransferableHelper::TerminateListener::disposing( const EventObject& ) -{ -} - - -void SAL_CALL TransferableHelper::TerminateListener::queryTermination( const EventObject& ) -{ -} - - -void SAL_CALL TransferableHelper::TerminateListener::notifyTermination( const EventObject& ) -{ - mrParent.ImplFlush(); -} - -OUString SAL_CALL TransferableHelper::TerminateListener::getImplementationName() -{ - return OUString("com.sun.star.comp.svt.TransferableHelperTerminateListener"); -} - -sal_Bool SAL_CALL TransferableHelper::TerminateListener::supportsService(const OUString& /*rServiceName*/) -{ - return false; -} - -css::uno::Sequence<OUString> TransferableHelper::TerminateListener::getSupportedServiceNames() -{ - return css::uno::Sequence<OUString>(); -} - - -Any SAL_CALL TransferableHelper::getTransferData( const DataFlavor& rFlavor ) -{ - return getTransferData2(rFlavor, OUString()); -} - -Any SAL_CALL TransferableHelper::getTransferData2( const DataFlavor& rFlavor, const OUString& rDestDoc ) -{ - if( !maAny.hasValue() || maFormats.empty() || ( maLastFormat != rFlavor.MimeType ) ) - { - const SolarMutexGuard aGuard; - - maLastFormat = rFlavor.MimeType; - maAny = Any(); - - try - { - DataFlavor aSubstFlavor; - bool bDone = false; - - // add formats if not already done - if (maFormats.empty()) - AddSupportedFormats(); - - // check alien formats first and try to get a substitution format - if( SotExchange::GetFormatDataFlavor( SotClipboardFormatId::STRING, aSubstFlavor ) && - TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) ) - { - GetData(aSubstFlavor, rDestDoc); - bDone = maAny.hasValue(); - } - else if(SotExchange::GetFormatDataFlavor(SotClipboardFormatId::BMP, aSubstFlavor ) - && TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) - && SotExchange::GetFormatDataFlavor(SotClipboardFormatId::BITMAP, aSubstFlavor)) - { - GetData(aSubstFlavor, rDestDoc); - bDone = true; - } - else if( SotExchange::GetFormatDataFlavor( SotClipboardFormatId::EMF, aSubstFlavor ) && - TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) && - SotExchange::GetFormatDataFlavor( SotClipboardFormatId::GDIMETAFILE, aSubstFlavor ) ) - { - GetData(aSubstFlavor, rDestDoc); - - if( maAny.hasValue() ) - { - Sequence< sal_Int8 > aSeq; - - if( maAny >>= aSeq ) - { - std::unique_ptr<SvMemoryStream> pSrcStm(new SvMemoryStream( aSeq.getArray(), aSeq.getLength(), StreamMode::WRITE | StreamMode::TRUNC )); - GDIMetaFile aMtf; - - ReadGDIMetaFile( *pSrcStm, aMtf ); - pSrcStm.reset(); - - Graphic aGraphic( aMtf ); - SvMemoryStream aDstStm( 65535, 65535 ); - - if( GraphicConverter::Export( aDstStm, aGraphic, ConvertDataFormat::EMF ) == ERRCODE_NONE ) - { - maAny <<= ( aSeq = Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aDstStm.GetData() ), - aDstStm.TellEnd() ) ); - bDone = true; - } - } - } - } - else if( SotExchange::GetFormatDataFlavor( SotClipboardFormatId::WMF, aSubstFlavor ) && - TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) && - SotExchange::GetFormatDataFlavor( SotClipboardFormatId::GDIMETAFILE, aSubstFlavor ) ) - { - GetData(aSubstFlavor, rDestDoc); - - if( maAny.hasValue() ) - { - Sequence< sal_Int8 > aSeq; - - if( maAny >>= aSeq ) - { - std::unique_ptr<SvMemoryStream> pSrcStm(new SvMemoryStream( aSeq.getArray(), aSeq.getLength(), StreamMode::WRITE | StreamMode::TRUNC )); - GDIMetaFile aMtf; - - ReadGDIMetaFile( *pSrcStm, aMtf ); - pSrcStm.reset(); - - SvMemoryStream aDstStm( 65535, 65535 ); - - // taking wmf without file header - if ( ConvertGDIMetaFileToWMF( aMtf, aDstStm, nullptr, false ) ) - { - maAny <<= ( aSeq = Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aDstStm.GetData() ), - aDstStm.TellEnd() ) ); - bDone = true; - } - } - } - } - - // reset Any if substitute doesn't work - if( !bDone && maAny.hasValue() ) - maAny = Any(); - - // if any is not yet filled, use standard format - if( !maAny.hasValue() ) - GetData(rFlavor, rDestDoc); - } - catch( const css::uno::Exception& ) - { - } - - if( !maAny.hasValue() ) - throw UnsupportedFlavorException(); - } - - return maAny; -} - - -Sequence< DataFlavor > SAL_CALL TransferableHelper::getTransferDataFlavors() -{ - const SolarMutexGuard aGuard; - - try - { - if(maFormats.empty()) - AddSupportedFormats(); - } - catch( const css::uno::Exception& ) - { - } - - return comphelper::containerToSequence<DataFlavor>(maFormats); -} - - -sal_Bool SAL_CALL TransferableHelper::isDataFlavorSupported( const DataFlavor& rFlavor ) -{ - const SolarMutexGuard aGuard; - - try - { - if (maFormats.empty()) - AddSupportedFormats(); - } - catch( const css::uno::Exception& ) - { - } - - for (auto const& format : maFormats) - { - if( TransferableDataHelper::IsEqual( format, rFlavor ) ) - { - return true; - } - } - - return false; -} - - -void SAL_CALL TransferableHelper::lostOwnership( const Reference< XClipboard >&, const Reference< XTransferable >& ) -{ - const SolarMutexGuard aGuard; - - try - { - if( mxTerminateListener.is() ) - { - Reference< XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() ); - xDesktop->removeTerminateListener( mxTerminateListener ); - - mxTerminateListener.clear(); - } - - ObjectReleased(); - } - catch( const css::uno::Exception& ) - { - } -} - - -void SAL_CALL TransferableHelper::disposing( const EventObject& ) -{ -} - - -void SAL_CALL TransferableHelper::dragDropEnd( const DragSourceDropEvent& rDSDE ) -{ - const SolarMutexGuard aGuard; - - try - { - DragFinished( rDSDE.DropSuccess ? ( rDSDE.DropAction & ~DNDConstants::ACTION_DEFAULT ) : DNDConstants::ACTION_NONE ); - ObjectReleased(); - } - catch( const css::uno::Exception& ) - { - } -} - - -void SAL_CALL TransferableHelper::dragEnter( const DragSourceDragEvent& ) -{ -} - - -void SAL_CALL TransferableHelper::dragExit( const DragSourceEvent& ) -{ -} - - -void SAL_CALL TransferableHelper::dragOver( const DragSourceDragEvent& ) -{ -} - - -void SAL_CALL TransferableHelper::dropActionChanged( const DragSourceDragEvent& ) -{ -} - - -sal_Int64 SAL_CALL TransferableHelper::getSomething( const Sequence< sal_Int8 >& rId ) -{ - sal_Int64 nRet; - - if( ( rId.getLength() == 16 ) && - ( 0 == memcmp( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) ) - { - nRet = sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this)); - } - else - nRet = 0; - - return nRet; -} - - -void TransferableHelper::ImplFlush() -{ - if( !mxClipboard.is() ) - return; - - Reference< XFlushableClipboard > xFlushableClipboard( mxClipboard, UNO_QUERY ); - SolarMutexReleaser aReleaser; - - try - { - if( xFlushableClipboard.is() ) - xFlushableClipboard->flushClipboard(); - } - catch( const css::uno::Exception& ) - { - OSL_FAIL( "Could not flush clipboard" ); - } -} - - -void TransferableHelper::AddFormat( SotClipboardFormatId nFormat ) -{ - DataFlavor aFlavor; - - if( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) ) - AddFormat( aFlavor ); -} - - -void TransferableHelper::AddFormat( const DataFlavor& rFlavor ) -{ - bool bAdd = true; - - for (auto & format : maFormats) - { - if( TransferableDataHelper::IsEqual( format, rFlavor ) ) - { - // update MimeType for SotClipboardFormatId::OBJECTDESCRIPTOR in every case - if ((SotClipboardFormatId::OBJECTDESCRIPTOR == format.mnSotId) && mxObjDesc) - { - DataFlavor aObjDescFlavor; - - SotExchange::GetFormatDataFlavor( SotClipboardFormatId::OBJECTDESCRIPTOR, aObjDescFlavor ); - format.MimeType = aObjDescFlavor.MimeType; - format.MimeType += ::ImplGetParameterString(*mxObjDesc); - } - - bAdd = false; - break; - } - } - - if( !bAdd ) - return; - - DataFlavorEx aFlavorEx; - - aFlavorEx.MimeType = rFlavor.MimeType; - aFlavorEx.HumanPresentableName = rFlavor.HumanPresentableName; - aFlavorEx.DataType = rFlavor.DataType; - aFlavorEx.mnSotId = SotExchange::RegisterFormat( rFlavor ); - - if ((SotClipboardFormatId::OBJECTDESCRIPTOR == aFlavorEx.mnSotId) && mxObjDesc) - aFlavorEx.MimeType += ::ImplGetParameterString(*mxObjDesc); - - maFormats.push_back(aFlavorEx); - - if( SotClipboardFormatId::BITMAP == aFlavorEx.mnSotId ) - { - AddFormat( SotClipboardFormatId::PNG ); - AddFormat( SotClipboardFormatId::BMP ); - } - else if( SotClipboardFormatId::GDIMETAFILE == aFlavorEx.mnSotId ) - { - AddFormat( SotClipboardFormatId::EMF ); - AddFormat( SotClipboardFormatId::WMF ); - } -} - - -void TransferableHelper::RemoveFormat( SotClipboardFormatId nFormat ) -{ - DataFlavor aFlavor; - - if( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) ) - RemoveFormat( aFlavor ); -} - - -void TransferableHelper::RemoveFormat( const DataFlavor& rFlavor ) -{ - DataFlavorExVector::iterator aIter(maFormats.begin()); - - while (aIter != maFormats.end()) - { - if( TransferableDataHelper::IsEqual( *aIter, rFlavor ) ) - aIter = maFormats.erase(aIter); - else - ++aIter; - } -} - - -bool TransferableHelper::HasFormat( SotClipboardFormatId nFormat ) -{ - return std::any_of(maFormats.begin(), maFormats.end(), - [&](const DataFlavorEx& data) { return data.mnSotId == nFormat; }); -} - - -void TransferableHelper::ClearFormats() -{ - maFormats.clear(); - maAny.clear(); -} - - -bool TransferableHelper::SetAny( const Any& rAny ) -{ - maAny = rAny; - return maAny.hasValue(); -} - - -bool TransferableHelper::SetString( const OUString& rString, const DataFlavor& rFlavor ) -{ - DataFlavor aFileFlavor; - - if( !rString.isEmpty() && - SotExchange::GetFormatDataFlavor( SotClipboardFormatId::SIMPLE_FILE, aFileFlavor ) && - TransferableDataHelper::IsEqual( aFileFlavor, rFlavor ) ) - { - const OString aByteStr(OUStringToOString(rString, osl_getThreadTextEncoding())); - Sequence< sal_Int8 > aSeq( aByteStr.getLength() + 1 ); - - memcpy( aSeq.getArray(), aByteStr.getStr(), aByteStr.getLength() ); - aSeq[ aByteStr.getLength() ] = 0; - maAny <<= aSeq; - } - else - maAny <<= rString; - - return maAny.hasValue(); -} - - -bool TransferableHelper::SetBitmapEx( const BitmapEx& rBitmapEx, const DataFlavor& rFlavor ) -{ - if( !rBitmapEx.IsEmpty() ) - { - SvMemoryStream aMemStm( 65535, 65535 ); - - if(rFlavor.MimeType.equalsIgnoreAsciiCase("image/png")) - { - // write a PNG - vcl::PNGWriter aPNGWriter(rBitmapEx); - - aPNGWriter.Write(aMemStm); - } - else - { - const Bitmap aBitmap(rBitmapEx.GetBitmap()); - - // explicitly use Bitmap::Write with bCompressed = sal_False and bFileHeader = sal_True - WriteDIB(aBitmap, aMemStm, false, true); - } - - maAny <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.TellEnd() ); - } - - return maAny.hasValue(); -} - - -bool TransferableHelper::SetGDIMetaFile( const GDIMetaFile& rMtf ) -{ - if( rMtf.GetActionSize() ) - { - SvMemoryStream aMemStm( 65535, 65535 ); - - const_cast<GDIMetaFile&>(rMtf).Write( aMemStm ); - maAny <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.TellEnd() ); - } - - return maAny.hasValue(); -} - - -bool TransferableHelper::SetGraphic( const Graphic& rGraphic ) -{ - if( rGraphic.GetType() != GraphicType::NONE ) - { - SvMemoryStream aMemStm( 65535, 65535 ); - - aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 ); - aMemStm.SetCompressMode( SvStreamCompressFlags::NATIVE ); - WriteGraphic( aMemStm, rGraphic ); - maAny <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) ); - } - - return maAny.hasValue(); -} - - -bool TransferableHelper::SetImageMap( const ImageMap& rIMap ) -{ - SvMemoryStream aMemStm( 8192, 8192 ); - - aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 ); - rIMap.Write( aMemStm ); - maAny <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) ); - - return maAny.hasValue(); -} - - -bool TransferableHelper::SetTransferableObjectDescriptor( const TransferableObjectDescriptor& rDesc ) -{ - PrepareOLE( rDesc ); - - SvMemoryStream aMemStm( 1024, 1024 ); - - WriteTransferableObjectDescriptor( aMemStm, rDesc ); - maAny <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Tell() ); - - return maAny.hasValue(); - } - - -bool TransferableHelper::SetINetBookmark( const INetBookmark& rBmk, - const css::datatransfer::DataFlavor& rFlavor ) -{ - rtl_TextEncoding eSysCSet = osl_getThreadTextEncoding(); - - switch( SotExchange::GetFormat( rFlavor ) ) - { - case SotClipboardFormatId::SOLK: - { - OString sURL(OUStringToOString(rBmk.GetURL(), eSysCSet)); - OString sDesc(OUStringToOString(rBmk.GetDescription(), eSysCSet)); - OStringBuffer sOut; - sOut.append(sURL.getLength()); - sOut.append('@').append(sURL); - sOut.append(sDesc.getLength()); - sOut.append('@').append(sDesc); - - Sequence< sal_Int8 > aSeq(sOut.getLength()); - memcpy(aSeq.getArray(), sOut.getStr(), sOut.getLength()); - maAny <<= aSeq; - } - break; - - case SotClipboardFormatId::STRING: - maAny <<= rBmk.GetURL(); - break; - - case SotClipboardFormatId::UNIFORMRESOURCELOCATOR: - { - OString sURL(OUStringToOString(rBmk.GetURL(), eSysCSet)); - Sequence< sal_Int8 > aSeq( sURL.getLength() ); - memcpy( aSeq.getArray(), sURL.getStr(), sURL.getLength() ); - maAny <<= aSeq; - } - break; - - case SotClipboardFormatId::NETSCAPE_BOOKMARK: - { - Sequence< sal_Int8 > aSeq( 2048 ); - - memset( aSeq.getArray(), 0, 2048 ); - strcpy( reinterpret_cast< char* >( aSeq.getArray() ), OUStringToOString(rBmk.GetURL(), eSysCSet).getStr() ); - strcpy( reinterpret_cast< char* >( aSeq.getArray() ) + 1024, OUStringToOString(rBmk.GetDescription(), eSysCSet).getStr() ); - - maAny <<= aSeq; - } - break; - -#ifdef _WIN32 - case SotClipboardFormatId::FILEGRPDESCRIPTOR: - { - Sequence< sal_Int8 > aSeq( sizeof( FILEGROUPDESCRIPTOR ) ); - FILEGROUPDESCRIPTOR* pFDesc = reinterpret_cast<FILEGROUPDESCRIPTOR*>(aSeq.getArray()); - FILEDESCRIPTOR& rFDesc1 = pFDesc->fgd[ 0 ]; - - pFDesc->cItems = 1; - memset( &rFDesc1, 0, sizeof( FILEDESCRIPTOR ) ); - rFDesc1.dwFlags = FD_LINKUI; - - OStringBuffer aStr(OUStringToOString( - rBmk.GetDescription(), eSysCSet)); - for( sal_Int32 nChar = 0; nChar < aStr.getLength(); ++nChar ) - if( strchr( "\\/:*?\"<>|", aStr[nChar] ) ) - aStr.remove(nChar--, 1); - - aStr.insert(0, "Shortcut to "); - aStr.append(".URL"); - strcpy( rFDesc1.cFileName, aStr.getStr() ); - - maAny <<= aSeq; - } - break; - - case SotClipboardFormatId::FILECONTENT: - { - OUString aStr( "[InternetShortcut]\x0aURL=" ); - maAny <<= ( aStr += rBmk.GetURL() ); - } - break; -#endif - - default: - break; - } - - return maAny.hasValue(); -} - - -bool TransferableHelper::SetINetImage( const INetImage& rINtImg, - const css::datatransfer::DataFlavor& rFlavor ) -{ - SvMemoryStream aMemStm( 1024, 1024 ); - - aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 ); - rINtImg.Write( aMemStm, SotExchange::GetFormat( rFlavor ) ); - - maAny <<= Sequence< sal_Int8 >( static_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) ); - - return maAny.hasValue(); -} - - -bool TransferableHelper::SetObject( void* pUserObject, sal_uInt32 nUserObjectId, const DataFlavor& rFlavor ) -{ - tools::SvRef<SotStorageStream> xStm( new SotStorageStream( OUString() ) ); - - xStm->SetVersion( SOFFICE_FILEFORMAT_50 ); - - if( pUserObject && WriteObject( xStm, pUserObject, nUserObjectId, rFlavor ) ) - { - const sal_uInt32 nLen = xStm->TellEnd(); - Sequence< sal_Int8 > aSeq( nLen ); - - xStm->Seek( STREAM_SEEK_TO_BEGIN ); - xStm->ReadBytes(aSeq.getArray(), nLen); - - if( nLen && ( SotExchange::GetFormat( rFlavor ) == SotClipboardFormatId::STRING ) ) - { - //JP 24.7.2001: as I know was this only for the writer application and this - // writes now UTF16 format into the stream - //JP 6.8.2001: and now it writes UTF8 because then exist no problem with - // little / big endians! - Bug 88121 - maAny <<= OUString( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ), nLen - 1, RTL_TEXTENCODING_UTF8 ); - } - else - maAny <<= aSeq; - } - - return maAny.hasValue(); -} - - -bool TransferableHelper::WriteObject( tools::SvRef<SotStorageStream>&, void*, sal_uInt32, const DataFlavor& ) -{ - OSL_FAIL( "TransferableHelper::WriteObject( ... ) not implemented" ); - return false; -} - - -void TransferableHelper::DragFinished( sal_Int8 ) -{ -} - - -void TransferableHelper::ObjectReleased() -{ -} - - -void TransferableHelper::PrepareOLE( const TransferableObjectDescriptor& rObjDesc ) -{ - mxObjDesc.reset(new TransferableObjectDescriptor(rObjDesc)); - - if( HasFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ) ) - AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR ); -} - - -void TransferableHelper::CopyToClipboard( vcl::Window *pWindow ) const -{ - DBG_ASSERT( pWindow, "Window pointer is NULL" ); - Reference< XClipboard > xClipboard; - - if( pWindow ) - xClipboard = pWindow->GetClipboard(); - - if( xClipboard.is() ) - mxClipboard = xClipboard; - - if( !(mxClipboard.is() && !mxTerminateListener.is()) ) - return; - - try - { - TransferableHelper* pThis = const_cast< TransferableHelper* >( this ); - Reference< XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() ); - xDesktop->addTerminateListener( pThis->mxTerminateListener = new TerminateListener( *pThis ) ); - - mxClipboard->setContents( pThis, pThis ); - } - catch( const css::uno::Exception& ) - { - } -} - - -void TransferableHelper::CopyToSelection( vcl::Window *pWindow ) const -{ - DBG_ASSERT( pWindow, "Window pointer is NULL" ); - Reference< XClipboard > xSelection; - - if( pWindow ) - xSelection = pWindow->GetPrimarySelection(); - - if( !(xSelection.is() && !mxTerminateListener.is()) ) - return; - - try - { - TransferableHelper* pThis = const_cast< TransferableHelper* >( this ); - Reference< XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() ); - xDesktop->addTerminateListener( pThis->mxTerminateListener = new TerminateListener( *pThis ) ); - - xSelection->setContents( pThis, pThis ); - } - catch( const css::uno::Exception& ) - { - } -} - - -void TransferableHelper::StartDrag( vcl::Window* pWindow, sal_Int8 nDnDSourceActions, - sal_Int32 nDnDPointer ) - -{ - DBG_ASSERT( pWindow, "Window pointer is NULL" ); - Reference< XDragSource > xDragSource( pWindow->GetDragSource() ); - - if( !xDragSource.is() ) - return; - - /* - * #96792# release mouse before actually starting DnD. - * This is necessary for the X11 DnD implementation to work. - */ - if( pWindow->IsMouseCaptured() ) - pWindow->ReleaseMouse(); - - const Point aPt( pWindow->GetPointerPosPixel() ); - - // On Mac OS X we are forced to execute 'startDrag' synchronously - // contrary to the XDragSource interface specification because - // we can receive drag events from the system only in the main - // thread -#if !defined(MACOSX) - SolarMutexReleaser aReleaser; -#endif - - try - { - DragGestureEvent aEvt; - aEvt.DragAction = DNDConstants::ACTION_COPY; - aEvt.DragOriginX = aPt.X(); - aEvt.DragOriginY = aPt.Y(); - aEvt.DragSource = xDragSource; - - xDragSource->startDrag( aEvt, nDnDSourceActions, nDnDPointer, DND_IMAGE_NONE, this, this ); - } - catch( const css::uno::Exception& ) - { - } -} - -void TransferableHelper::ClearSelection( vcl::Window *pWindow ) -{ - DBG_ASSERT( pWindow, "Window pointer is NULL" ); - Reference< XClipboard > xSelection( pWindow->GetPrimarySelection() ); - - if( xSelection.is() ) - xSelection->setContents( nullptr, nullptr ); -} - -namespace -{ - class theTransferableHelperUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theTransferableHelperUnoTunnelId > {}; -} - -const Sequence< sal_Int8 >& TransferableHelper::getUnoTunnelId() -{ - return theTransferableHelperUnoTunnelId::get().getSeq(); -} - -class TransferableClipboardNotifier : public ::cppu::WeakImplHelper< XClipboardListener > -{ -private: - ::osl::Mutex& mrMutex; - Reference< XClipboardNotifier > mxNotifier; - TransferableDataHelper* mpListener; - -protected: - // XClipboardListener - virtual void SAL_CALL changedContents( const clipboard::ClipboardEvent& event ) override; - - // XEventListener - virtual void SAL_CALL disposing( const EventObject& Source ) override; - -public: - TransferableClipboardNotifier( const Reference< XClipboard >& _rxClipboard, TransferableDataHelper& _rListener, ::osl::Mutex& _rMutex ); - - /// determines whether we're currently listening - bool isListening() const { return mpListener != nullptr; } - - /// makes the instance non-functional - void dispose(); -}; - - -TransferableClipboardNotifier::TransferableClipboardNotifier( const Reference< XClipboard >& _rxClipboard, TransferableDataHelper& _rListener, ::osl::Mutex& _rMutex ) - :mrMutex( _rMutex ) - ,mxNotifier( _rxClipboard, UNO_QUERY ) - ,mpListener( &_rListener ) -{ - osl_atomic_increment( &m_refCount ); - { - if ( mxNotifier.is() ) - mxNotifier->addClipboardListener( this ); - else - // born dead - mpListener = nullptr; - } - osl_atomic_decrement( &m_refCount ); -} - - -void SAL_CALL TransferableClipboardNotifier::changedContents( const clipboard::ClipboardEvent& event ) -{ - SolarMutexGuard aSolarGuard; - // the SolarMutex here is necessary, since - // - we cannot call mpListener without our own mutex locked - // - Rebind respectively InitFormats (called by Rebind) will - // try to lock the SolarMutex, too - ::osl::MutexGuard aGuard( mrMutex ); - if( mpListener ) - mpListener->Rebind( event.Contents ); -} - - -void SAL_CALL TransferableClipboardNotifier::disposing( const EventObject& ) -{ - // clipboard is being disposed. Hmm. Okay, become disfunctional myself. - dispose(); -} - - -void TransferableClipboardNotifier::dispose() -{ - ::osl::MutexGuard aGuard( mrMutex ); - - Reference< XClipboardListener > xKeepMeAlive( this ); - - if ( mxNotifier.is() ) - mxNotifier->removeClipboardListener( this ); - mxNotifier.clear(); - - mpListener = nullptr; -} - -struct TransferableDataHelper_Impl -{ - ::osl::Mutex maMutex; - rtl::Reference<TransferableClipboardNotifier> mxClipboardListener; - - TransferableDataHelper_Impl() - { - } -}; - -TransferableDataHelper::TransferableDataHelper() - : mxObjDesc(new TransferableObjectDescriptor) - , mxImpl(new TransferableDataHelper_Impl) -{ -} - -TransferableDataHelper::TransferableDataHelper(const Reference< css::datatransfer::XTransferable >& rxTransferable) - : mxTransfer(rxTransferable) - , mxObjDesc(new TransferableObjectDescriptor) - , mxImpl(new TransferableDataHelper_Impl) -{ - InitFormats(); -} - -TransferableDataHelper::TransferableDataHelper(const TransferableDataHelper& rDataHelper) - : mxTransfer(rDataHelper.mxTransfer) - , mxClipboard(rDataHelper.mxClipboard) - , maFormats(rDataHelper.maFormats) - , mxObjDesc(new TransferableObjectDescriptor(*rDataHelper.mxObjDesc)) - , mxImpl(new TransferableDataHelper_Impl) -{ -} - -TransferableDataHelper::TransferableDataHelper(TransferableDataHelper&& rDataHelper) - : mxTransfer(std::move(rDataHelper.mxTransfer)) - , mxClipboard(std::move(rDataHelper.mxClipboard)) - , maFormats(std::move(rDataHelper.maFormats)) - , mxObjDesc(std::move(rDataHelper.mxObjDesc)) - , mxImpl(new TransferableDataHelper_Impl) -{ -} - -TransferableDataHelper& TransferableDataHelper::operator=( const TransferableDataHelper& rDataHelper ) -{ - if ( this != &rDataHelper ) - { - ::osl::MutexGuard aGuard(mxImpl->maMutex); - - const bool bWasClipboardListening = mxImpl->mxClipboardListener.is(); - - if (bWasClipboardListening) - StopClipboardListening(); - - mxTransfer = rDataHelper.mxTransfer; - maFormats = rDataHelper.maFormats; - mxObjDesc.reset(new TransferableObjectDescriptor(*rDataHelper.mxObjDesc)); - mxClipboard = rDataHelper.mxClipboard; - - if (bWasClipboardListening) - StartClipboardListening(); - } - - return *this; -} - -TransferableDataHelper& TransferableDataHelper::operator=(TransferableDataHelper&& rDataHelper) -{ - ::osl::MutexGuard aGuard(mxImpl->maMutex); - - const bool bWasClipboardListening = mxImpl->mxClipboardListener.is(); - - if (bWasClipboardListening) - StopClipboardListening(); - - mxTransfer = std::move(rDataHelper.mxTransfer); - maFormats = std::move(rDataHelper.maFormats); - mxObjDesc = std::move(rDataHelper.mxObjDesc); - mxClipboard = std::move(rDataHelper.mxClipboard); - - if (bWasClipboardListening) - StartClipboardListening(); - - return *this; -} - -TransferableDataHelper::~TransferableDataHelper() -{ - StopClipboardListening( ); - { - ::osl::MutexGuard aGuard(mxImpl->maMutex); - maFormats.clear(); - mxObjDesc.reset(); - } -} - -void TransferableDataHelper::FillDataFlavorExVector( const Sequence< DataFlavor >& rDataFlavorSeq, - DataFlavorExVector& rDataFlavorExVector ) -{ - try - { - Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() ); - Reference< XMimeContentTypeFactory > xMimeFact = MimeContentTypeFactory::create( xContext ); - DataFlavorEx aFlavorEx; - const OUString aCharsetStr( "charset" ); - - - for (auto const& rFlavor : rDataFlavorSeq) - { - Reference< XMimeContentType > xMimeType; - - try - { - if( !rFlavor.MimeType.isEmpty() ) - xMimeType = xMimeFact->createMimeContentType( rFlavor.MimeType ); - } - catch( const css::uno::Exception& ) - { - } - - aFlavorEx.MimeType = rFlavor.MimeType; - aFlavorEx.HumanPresentableName = rFlavor.HumanPresentableName; - aFlavorEx.DataType = rFlavor.DataType; - aFlavorEx.mnSotId = SotExchange::RegisterFormat( rFlavor ); - - rDataFlavorExVector.push_back( aFlavorEx ); - - // add additional formats for special mime types - if(SotClipboardFormatId::BMP == aFlavorEx.mnSotId || SotClipboardFormatId::PNG == aFlavorEx.mnSotId) - { - if( SotExchange::GetFormatDataFlavor( SotClipboardFormatId::BITMAP, aFlavorEx ) ) - { - aFlavorEx.mnSotId = SotClipboardFormatId::BITMAP; - rDataFlavorExVector.push_back( aFlavorEx ); - } - } - else if( SotClipboardFormatId::WMF == aFlavorEx.mnSotId || SotClipboardFormatId::EMF == aFlavorEx.mnSotId ) - { - if( SotExchange::GetFormatDataFlavor( SotClipboardFormatId::GDIMETAFILE, aFlavorEx ) ) - { - aFlavorEx.mnSotId = SotClipboardFormatId::GDIMETAFILE; - rDataFlavorExVector.push_back( aFlavorEx ); - } - } - else if ( SotClipboardFormatId::HTML_SIMPLE == aFlavorEx.mnSotId ) - { - // #104735# HTML_SIMPLE may also be inserted without comments - aFlavorEx.mnSotId = SotClipboardFormatId::HTML_NO_COMMENT; - rDataFlavorExVector.push_back( aFlavorEx ); - } - else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( "text/plain" ) ) - { - // add, if it is a UTF-8 byte buffer - if( xMimeType->hasParameter( aCharsetStr ) ) - { - if( xMimeType->getParameterValue( aCharsetStr ).equalsIgnoreAsciiCase( "unicode" ) || - xMimeType->getParameterValue( aCharsetStr ).equalsIgnoreAsciiCase( "utf-16" ) ) - { - rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SotClipboardFormatId::STRING; - - } - } - } - else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( "text/rtf" ) ) - { - rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SotClipboardFormatId::RTF; - } - else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( "text/richtext" ) ) - { - rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SotClipboardFormatId::RICHTEXT; - } - else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( "text/html" ) ) - - { - rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SotClipboardFormatId::HTML; - } - else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( "text/uri-list" ) ) - { - rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SotClipboardFormatId::FILE_LIST; - } - else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( "application/x-openoffice-objectdescriptor-xml" ) ) - { - rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SotClipboardFormatId::OBJECTDESCRIPTOR; - } - } - } - catch( const css::uno::Exception& ) - { - } -} - -void TransferableDataHelper::InitFormats() -{ - SolarMutexGuard aSolarGuard; - ::osl::MutexGuard aGuard(mxImpl->maMutex); - - maFormats.clear(); - mxObjDesc.reset(new TransferableObjectDescriptor); - - if( !mxTransfer.is() ) - return; - - TransferableDataHelper::FillDataFlavorExVector(mxTransfer->getTransferDataFlavors(), maFormats); - - for (auto const& format : maFormats) - { - if( SotClipboardFormatId::OBJECTDESCRIPTOR == format.mnSotId ) - { - ImplSetParameterString(*mxObjDesc, format); - break; - } - } -} - - -bool TransferableDataHelper::HasFormat( SotClipboardFormatId nFormat ) const -{ - ::osl::MutexGuard aGuard(mxImpl->maMutex); - return std::any_of(maFormats.begin(), maFormats.end(), - [&](const DataFlavorEx& data) { return data.mnSotId == nFormat; }); -} - -bool TransferableDataHelper::HasFormat( const DataFlavor& rFlavor ) const -{ - ::osl::MutexGuard aGuard(mxImpl->maMutex); - for (auto const& format : maFormats) - { - if( TransferableDataHelper::IsEqual( rFlavor, format ) ) - return true; - } - - return false; -} - -sal_uInt32 TransferableDataHelper::GetFormatCount() const -{ - ::osl::MutexGuard aGuard(mxImpl->maMutex); - return maFormats.size(); -} - -SotClipboardFormatId TransferableDataHelper::GetFormat( sal_uInt32 nFormat ) const -{ - ::osl::MutexGuard aGuard(mxImpl->maMutex); - DBG_ASSERT(nFormat < maFormats.size(), "TransferableDataHelper::GetFormat: invalid format index"); - return( ( nFormat < maFormats.size() ) ? (maFormats)[ nFormat ].mnSotId : SotClipboardFormatId::NONE ); -} - -DataFlavor TransferableDataHelper::GetFormatDataFlavor( sal_uInt32 nFormat ) const -{ - ::osl::MutexGuard aGuard(mxImpl->maMutex); - DBG_ASSERT(nFormat < maFormats.size(), "TransferableDataHelper::GetFormat: invalid format index"); - - DataFlavor aRet; - - if (nFormat < maFormats.size()) - aRet = maFormats[nFormat]; - - return aRet; -} - - -Reference< XTransferable > TransferableDataHelper::GetXTransferable() const -{ - Reference< XTransferable > xRet; - - if( mxTransfer.is() ) - { - try - { - xRet = mxTransfer; - - // do a dummy call to check, if this interface is valid (nasty) - xRet->getTransferDataFlavors(); - - } - catch( const css::uno::Exception& ) - { - xRet.clear(); - } - } - - return xRet; -} - - -Any TransferableDataHelper::GetAny( SotClipboardFormatId nFormat, const OUString& rDestDoc ) const -{ - Any aReturn; - - DataFlavor aFlavor; - if ( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) ) - aReturn = GetAny(aFlavor, rDestDoc); - - return aReturn; -} - -Any TransferableDataHelper::GetAny( const DataFlavor& rFlavor, const OUString& rDestDoc ) const -{ - ::osl::MutexGuard aGuard(mxImpl->maMutex); - Any aRet; - - try - { - if( mxTransfer.is() ) - { - const SotClipboardFormatId nRequestFormat = SotExchange::GetFormat( rFlavor ); - - Reference<css::datatransfer::XTransferable2> xTransfer2(mxTransfer, UNO_QUERY); - - if( nRequestFormat != SotClipboardFormatId::NONE ) - { - // try to get alien format first - for (auto const& format : maFormats) - { - if( ( nRequestFormat == format.mnSotId ) && !rFlavor.MimeType.equalsIgnoreAsciiCase( format.MimeType ) ) - { - if (xTransfer2.is()) - aRet = xTransfer2->getTransferData2(format, rDestDoc); - else - aRet = mxTransfer->getTransferData(format); - } - - if( aRet.hasValue() ) - break; - } - } - - if( !aRet.hasValue() ) - { - if (xTransfer2.is()) - aRet = xTransfer2->getTransferData2(rFlavor, rDestDoc); - else - aRet = mxTransfer->getTransferData(rFlavor); - } - } - } - catch( const css::uno::Exception& ) - { - } - - return aRet; -} - - -bool TransferableDataHelper::GetString( SotClipboardFormatId nFormat, OUString& rStr ) -{ - DataFlavor aFlavor; - return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetString( aFlavor, rStr ) ); -} - - -bool TransferableDataHelper::GetString( const DataFlavor& rFlavor, OUString& rStr ) -{ - Any aAny = GetAny(rFlavor, OUString()); - bool bRet = false; - - if( aAny.hasValue() ) - { - OUString aOUString; - Sequence< sal_Int8 > aSeq; - - if( aAny >>= aOUString ) - { - rStr = aOUString; - bRet = true; - } - else if( aAny >>= aSeq ) - { - - const sal_Char* pChars = reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ); - sal_Int32 nLen = aSeq.getLength(); - - //JP 10.10.2001: 92930 - don't copy the last zero character into the string. - //DVO 2002-05-27: strip _all_ trailing zeros - while( nLen && ( 0 == *( pChars + nLen - 1 ) ) ) - --nLen; - - rStr = OUString( pChars, nLen, osl_getThreadTextEncoding() ); - bRet = true; - } - } - - return bRet; -} - - -bool TransferableDataHelper::GetBitmapEx( SotClipboardFormatId nFormat, BitmapEx& rBmpEx ) -{ - if(SotClipboardFormatId::BITMAP == nFormat) - { - // try to get PNG first - DataFlavor aFlavor; - - if(SotExchange::GetFormatDataFlavor(SotClipboardFormatId::PNG, aFlavor)) - { - if(GetBitmapEx(aFlavor, rBmpEx)) - { - return true; - } - } - } - - DataFlavor aFlavor; - return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetBitmapEx( aFlavor, rBmpEx ) ); -} - - -bool TransferableDataHelper::GetBitmapEx( const DataFlavor& rFlavor, BitmapEx& rBmpEx ) -{ - tools::SvRef<SotStorageStream> xStm; - DataFlavor aSubstFlavor; - bool bRet(GetSotStorageStream(rFlavor, xStm)); - bool bSuppressPNG(false); // #122982# If PNG stream not accessed, but BMP one, suppress trying to load PNG - bool bSuppressJPEG(false); - - if(!bRet && HasFormat(SotClipboardFormatId::PNG) && SotExchange::GetFormatDataFlavor(SotClipboardFormatId::PNG, aSubstFlavor)) - { - // when no direct success, try if PNG is available - bRet = GetSotStorageStream(aSubstFlavor, xStm); - bSuppressJPEG = bRet; - } - - if(!bRet && HasFormat(SotClipboardFormatId::JPEG) && SotExchange::GetFormatDataFlavor(SotClipboardFormatId::JPEG, aSubstFlavor)) - { - bRet = GetSotStorageStream(aSubstFlavor, xStm); - bSuppressPNG = bRet; - } - - if(!bRet && HasFormat(SotClipboardFormatId::BMP) && SotExchange::GetFormatDataFlavor(SotClipboardFormatId::BMP, aSubstFlavor)) - { - // when no direct success, try if BMP is available - bRet = GetSotStorageStream(aSubstFlavor, xStm); - bSuppressPNG = bRet; - bSuppressJPEG = bRet; - } - - if(bRet) - { - if(!bSuppressPNG && rFlavor.MimeType.equalsIgnoreAsciiCase("image/png")) - { - // it's a PNG, import to BitmapEx - vcl::PNGReader aPNGReader(*xStm); - - rBmpEx = aPNGReader.Read(); - } - else if(!bSuppressJPEG && rFlavor.MimeType.equalsIgnoreAsciiCase("image/jpeg")) - { - // it's a JPEG, import to BitmapEx - GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter(); - Graphic aGraphic; - if (rFilter.ImportGraphic(aGraphic, "", *xStm) == ERRCODE_NONE) - rBmpEx = aGraphic.GetBitmapEx(); - } - - if(rBmpEx.IsEmpty()) - { - Bitmap aBitmap; - AlphaMask aMask; - - // explicitly use Bitmap::Read with bFileHeader = sal_True - // #i124085# keep DIBV5 for read from clipboard, but should not happen - ReadDIBV5(aBitmap, aMask, *xStm); - - if(aMask.GetBitmap().IsEmpty()) - { - rBmpEx = aBitmap; - } - else - { - rBmpEx = BitmapEx(aBitmap, aMask); - } - } - - bRet = (ERRCODE_NONE == xStm->GetError() && !rBmpEx.IsEmpty()); - - /* SJ: #110748# At the moment we are having problems with DDB inserted as DIB. The - problem is, that some graphics are inserted much too big because the nXPelsPerMeter - and nYPelsPerMeter of the bitmap fileheader isn't including the correct value. - Due to this reason the following code assumes that bitmaps with a logical size - greater than 50 cm aren't having the correct mapmode set. - - The following code should be removed if DDBs and DIBs are supported via clipboard - properly. - */ - if(bRet) - { - const MapMode aMapMode(rBmpEx.GetPrefMapMode()); - - if(MapUnit::MapPixel != aMapMode.GetMapUnit()) - { - const Size aSize(OutputDevice::LogicToLogic(rBmpEx.GetPrefSize(), aMapMode, MapMode(MapUnit::Map100thMM))); - - // #i122388# This wrongly corrects in the given case; changing from 5000 100th mm to - // the described 50 cm (which is 50000 100th mm) - if((aSize.Width() > 50000) || (aSize.Height() > 50000)) - { - rBmpEx.SetPrefMapMode(MapMode(MapUnit::MapPixel)); - - // #i122388# also adapt size by applying the mew MapMode - const Size aNewSize(OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(MapUnit::MapPixel))); - rBmpEx.SetPrefSize(aNewSize); - } - } - } - } - - return bRet; -} - - -bool TransferableDataHelper::GetGDIMetaFile(SotClipboardFormatId nFormat, GDIMetaFile& rMtf, size_t nMaxActions) -{ - DataFlavor aFlavor; - return SotExchange::GetFormatDataFlavor(nFormat, aFlavor) && - GetGDIMetaFile(aFlavor, rMtf) && - (nMaxActions == 0 || rMtf.GetActionSize() < nMaxActions); -} - - -bool TransferableDataHelper::GetGDIMetaFile( const DataFlavor& rFlavor, GDIMetaFile& rMtf ) -{ - tools::SvRef<SotStorageStream> xStm; - DataFlavor aSubstFlavor; - bool bRet = false; - - if( GetSotStorageStream( rFlavor, xStm ) ) - { - ReadGDIMetaFile( *xStm, rMtf ); - bRet = ( xStm->GetError() == ERRCODE_NONE ); - } - - if( !bRet && - HasFormat( SotClipboardFormatId::EMF ) && - SotExchange::GetFormatDataFlavor( SotClipboardFormatId::EMF, aSubstFlavor ) && - GetSotStorageStream( aSubstFlavor, xStm ) ) - { - Graphic aGraphic; - - if( GraphicConverter::Import( *xStm, aGraphic ) == ERRCODE_NONE ) - { - rMtf = aGraphic.GetGDIMetaFile(); - bRet = true; - } - } - - if( !bRet && - HasFormat( SotClipboardFormatId::WMF ) && - SotExchange::GetFormatDataFlavor( SotClipboardFormatId::WMF, aSubstFlavor ) && - GetSotStorageStream( aSubstFlavor, xStm ) ) - { - Graphic aGraphic; - - if( GraphicConverter::Import( *xStm, aGraphic ) == ERRCODE_NONE ) - { - rMtf = aGraphic.GetGDIMetaFile(); - bRet = true; - } - } - - return bRet; -} - - -bool TransferableDataHelper::GetGraphic( SotClipboardFormatId nFormat, Graphic& rGraphic ) -{ - if(SotClipboardFormatId::BITMAP == nFormat) - { - // try to get PNG first - DataFlavor aFlavor; - - if(SotExchange::GetFormatDataFlavor(SotClipboardFormatId::PNG, aFlavor)) - { - if(GetGraphic(aFlavor, rGraphic)) - { - return true; - } - } - } - - DataFlavor aFlavor; - return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetGraphic( aFlavor, rGraphic ) ); -} - - -bool TransferableDataHelper::GetGraphic( const css::datatransfer::DataFlavor& rFlavor, Graphic& rGraphic ) -{ - DataFlavor aFlavor; - bool bRet = false; - - if(SotExchange::GetFormatDataFlavor(SotClipboardFormatId::PNG, aFlavor) && - TransferableDataHelper::IsEqual(aFlavor, rFlavor)) - { - // try to get PNG first - BitmapEx aBmpEx; - - bRet = GetBitmapEx( aFlavor, aBmpEx ); - if( bRet ) - rGraphic = aBmpEx; - } - else if (SotExchange::GetFormatDataFlavor(SotClipboardFormatId::JPEG, aFlavor) && TransferableDataHelper::IsEqual(aFlavor, rFlavor)) - { - BitmapEx aBitmapEx; - - bRet = GetBitmapEx(aFlavor, aBitmapEx); - if (bRet) - rGraphic = aBitmapEx; - } - else if(SotExchange::GetFormatDataFlavor( SotClipboardFormatId::BITMAP, aFlavor ) && - TransferableDataHelper::IsEqual( aFlavor, rFlavor ) ) - { - BitmapEx aBmpEx; - - bRet = GetBitmapEx( aFlavor, aBmpEx ); - if( bRet ) - rGraphic = aBmpEx; - } - else if( SotExchange::GetFormatDataFlavor( SotClipboardFormatId::GDIMETAFILE, aFlavor ) && - TransferableDataHelper::IsEqual( aFlavor, rFlavor ) ) - { - GDIMetaFile aMtf; - - bRet = GetGDIMetaFile( aFlavor, aMtf ); - if( bRet ) - rGraphic = aMtf; - } - else - { - tools::SvRef<SotStorageStream> xStm; - - if( GetSotStorageStream( rFlavor, xStm ) ) - { - ReadGraphic( *xStm, rGraphic ); - bRet = ( xStm->GetError() == ERRCODE_NONE ); - } - } - - return bRet; -} - - -bool TransferableDataHelper::GetImageMap( SotClipboardFormatId nFormat, ImageMap& rIMap ) -{ - DataFlavor aFlavor; - return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetImageMap( aFlavor, rIMap ) ); -} - - -bool TransferableDataHelper::GetImageMap( const css::datatransfer::DataFlavor& rFlavor, ImageMap& rIMap ) -{ - tools::SvRef<SotStorageStream> xStm; - bool bRet = GetSotStorageStream( rFlavor, xStm ); - - if( bRet ) - { - rIMap.Read( *xStm ); - bRet = ( xStm->GetError() == ERRCODE_NONE ); - } - - return bRet; -} - - -bool TransferableDataHelper::GetTransferableObjectDescriptor( SotClipboardFormatId nFormat, TransferableObjectDescriptor& rDesc ) -{ - DataFlavor aFlavor; - return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetTransferableObjectDescriptor( rDesc ) ); -} - - -bool TransferableDataHelper::GetTransferableObjectDescriptor( TransferableObjectDescriptor& rDesc ) -{ - rDesc = *mxObjDesc; - return true; -} - - -bool TransferableDataHelper::GetINetBookmark( SotClipboardFormatId nFormat, INetBookmark& rBmk ) -{ - DataFlavor aFlavor; - return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetINetBookmark( aFlavor, rBmk ) ); -} - - -bool TransferableDataHelper::GetINetBookmark( const css::datatransfer::DataFlavor& rFlavor, INetBookmark& rBmk ) -{ - bool bRet = false; - if( HasFormat( rFlavor )) - { - const SotClipboardFormatId nFormat = SotExchange::GetFormat( rFlavor ); - switch( nFormat ) - { - case SotClipboardFormatId::SOLK: - case SotClipboardFormatId::UNIFORMRESOURCELOCATOR: - { - OUString aString; - if( GetString( rFlavor, aString ) ) - { - if( SotClipboardFormatId::UNIFORMRESOURCELOCATOR == nFormat ) - { - rBmk = INetBookmark( aString, aString ); - bRet = true; - } - else - { - OUString aURL, aDesc; - sal_Int32 nStart = aString.indexOf( '@' ), nLen = aString.toInt32(); - - if( !nLen && aString[ 0 ] != '0' ) - { - SAL_INFO( "svtools", "SOLK: 1. len=0" ); - } - if( nStart == -1 || nLen > aString.getLength() - nStart - 3 ) - { - SAL_INFO( "svtools", "SOLK: 1. illegal start or wrong len" ); - } - aURL = aString.copy( nStart + 1, nLen ); - - aString = aString.replaceAt( 0, nStart + 1 + nLen, "" ); - nStart = aString.indexOf( '@' ); - nLen = aString.toInt32(); - - if( !nLen && aString[ 0 ] != '0' ) - { - SAL_INFO( "svtools", "SOLK: 2. len=0" ); - } - if( nStart == -1 || nLen > aString.getLength() - nStart - 1 ) - { - SAL_INFO( "svtools", "SOLK: 2. illegal start or wrong len" ); - } - aDesc = aString.copy( nStart+1, nLen ); - - rBmk = INetBookmark( aURL, aDesc ); - bRet = true; - } - } - } - break; - - case SotClipboardFormatId::NETSCAPE_BOOKMARK: - { - Sequence<sal_Int8> aSeq = GetSequence(rFlavor, OUString()); - - if (2048 == aSeq.getLength()) - { - const sal_Char* p1 = reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ); - const sal_Char* p2 = reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ) + 1024; - rBmk = INetBookmark( OUString( p1, strlen(p1), osl_getThreadTextEncoding() ), - OUString( p2, strlen(p2), osl_getThreadTextEncoding() ) ); - bRet = true; - } - } - break; - -#ifdef _WIN32 - case SotClipboardFormatId::FILEGRPDESCRIPTOR: - { - Sequence<sal_Int8> aSeq = GetSequence(rFlavor, OUString()); - - if (aSeq.getLength()) - { - FILEGROUPDESCRIPTOR const * pFDesc = reinterpret_cast<FILEGROUPDESCRIPTOR const *>(aSeq.getConstArray()); - - if( pFDesc->cItems ) - { - OString aDesc( pFDesc->fgd[ 0 ].cFileName ); - rtl_TextEncoding eTextEncoding = osl_getThreadTextEncoding(); - - if( ( aDesc.getLength() > 4 ) && aDesc.copy(aDesc.getLength() - 4).equalsIgnoreAsciiCase(".URL") ) - { - std::unique_ptr<SvStream> pStream(::utl::UcbStreamHelper::CreateStream( INetURLObject( OStringToOUString(aDesc, eTextEncoding) ).GetMainURL( INetURLObject::DecodeMechanism::NONE ), - StreamMode::STD_READ )); - - if( !pStream || pStream->GetError() ) - { - DataFlavor aFileContentFlavor; - - aSeq.realloc( 0 ); - pStream.reset(); - - if (SotExchange::GetFormatDataFlavor(SotClipboardFormatId::FILECONTENT, aFileContentFlavor)) - { - aSeq = GetSequence(aFileContentFlavor, OUString()); - if (aSeq.getLength()) - pStream.reset(new SvMemoryStream( const_cast<sal_Int8 *>(aSeq.getConstArray()), aSeq.getLength(), StreamMode::STD_READ )); - } - } - - if( pStream ) - { - OString aLine; - bool bSttFnd = false; - - while( pStream->ReadLine( aLine ) ) - { - if (aLine.equalsIgnoreAsciiCase("[InternetShortcut]")) - bSttFnd = true; - else if (bSttFnd && aLine.copy(0, 4).equalsIgnoreAsciiCase("URL=")) - { - rBmk = INetBookmark( OStringToOUString(aLine.copy(4), eTextEncoding), - OStringToOUString(aDesc.copy(0, aDesc.getLength() - 4), eTextEncoding) ); - bRet = true; - break; - } - } - } - } - } - } - } - break; -#endif - default: break; - } - } - return bRet; -} - - -bool TransferableDataHelper::GetINetImage( SotClipboardFormatId nFormat, - INetImage& rINtImg ) -{ - DataFlavor aFlavor; - return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetINetImage( aFlavor, rINtImg ) ); -} - - -bool TransferableDataHelper::GetINetImage( - const css::datatransfer::DataFlavor& rFlavor, - INetImage& rINtImg ) -{ - tools::SvRef<SotStorageStream> xStm; - bool bRet = GetSotStorageStream( rFlavor, xStm ); - - if( bRet ) - bRet = rINtImg.Read( *xStm, SotExchange::GetFormat( rFlavor ) ); - return bRet; -} - - -bool TransferableDataHelper::GetFileList( SotClipboardFormatId nFormat, - FileList& rFileList ) -{ - DataFlavor aFlavor; - return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetFileList( rFileList ) ); -} - - -bool TransferableDataHelper::GetFileList( FileList& rFileList ) -{ - tools::SvRef<SotStorageStream> xStm; - bool bRet = false; - - for( sal_uInt32 i = 0, nFormatCount = GetFormatCount(); ( i < nFormatCount ) && !bRet; ++i ) - { - if( SotClipboardFormatId::FILE_LIST == GetFormat( i ) ) - { - const DataFlavor aFlavor( GetFormatDataFlavor( i ) ); - - if( GetSotStorageStream( aFlavor, xStm ) ) - { - if( aFlavor.MimeType.indexOf( "text/uri-list" ) > -1 ) - { - OString aDiskString; - - while( xStm->ReadLine( aDiskString ) ) - if( !aDiskString.isEmpty() && aDiskString[0] != '#' ) - rFileList.AppendFile( OStringToOUString(aDiskString, RTL_TEXTENCODING_UTF8) ); - - bRet = true; - } - else - bRet = ( ReadFileList( *xStm, rFileList ).GetError() == ERRCODE_NONE ); - } - } - } - - return bRet; -} - - -Sequence<sal_Int8> TransferableDataHelper::GetSequence( SotClipboardFormatId nFormat, const OUString& rDestDoc ) -{ - DataFlavor aFlavor; - if (!SotExchange::GetFormatDataFlavor(nFormat, aFlavor)) - return Sequence<sal_Int8>(); - - return GetSequence(aFlavor, rDestDoc); -} - -Sequence<sal_Int8> TransferableDataHelper::GetSequence( const DataFlavor& rFlavor, const OUString& rDestDoc ) -{ - const Any aAny = GetAny(rFlavor, rDestDoc); - Sequence<sal_Int8> aSeq; - if (aAny.hasValue()) - aAny >>= aSeq; - - return aSeq; -} - - -bool TransferableDataHelper::GetSotStorageStream( SotClipboardFormatId nFormat, tools::SvRef<SotStorageStream>& rxStream ) -{ - DataFlavor aFlavor; - return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetSotStorageStream( aFlavor, rxStream ) ); -} - - -bool TransferableDataHelper::GetSotStorageStream( const DataFlavor& rFlavor, tools::SvRef<SotStorageStream>& rxStream ) -{ - Sequence<sal_Int8> aSeq = GetSequence(rFlavor, OUString()); - - if (aSeq.getLength()) - { - rxStream = new SotStorageStream( "" ); - rxStream->WriteBytes( aSeq.getConstArray(), aSeq.getLength() ); - rxStream->Seek( 0 ); - } - - return aSeq.getLength(); -} - -Reference<XInputStream> TransferableDataHelper::GetInputStream( SotClipboardFormatId nFormat, const OUString& rDestDoc ) -{ - DataFlavor aFlavor; - if (!SotExchange::GetFormatDataFlavor(nFormat, aFlavor)) - return Reference<XInputStream>(); - - return GetInputStream(aFlavor, rDestDoc); -} - -Reference<XInputStream> TransferableDataHelper::GetInputStream( const DataFlavor& rFlavor, const OUString& rDestDoc ) -{ - Sequence<sal_Int8> aSeq = GetSequence(rFlavor, rDestDoc); - - if (!aSeq.getLength()) - return Reference<XInputStream>(); - - Reference<XInputStream> xStream(new comphelper::SequenceInputStream(aSeq)); - return xStream; -} - -void TransferableDataHelper::Rebind( const Reference< XTransferable >& _rxNewContent ) -{ - mxTransfer = _rxNewContent; - InitFormats(); -} - -bool TransferableDataHelper::StartClipboardListening( ) -{ - ::osl::MutexGuard aGuard(mxImpl->maMutex); - - StopClipboardListening( ); - - mxImpl->mxClipboardListener = new TransferableClipboardNotifier(mxClipboard, *this, mxImpl->maMutex); - - return mxImpl->mxClipboardListener->isListening(); -} - -void TransferableDataHelper::StopClipboardListening( ) -{ - ::osl::MutexGuard aGuard(mxImpl->maMutex); - - if (mxImpl->mxClipboardListener.is()) - { - mxImpl->mxClipboardListener->dispose(); - mxImpl->mxClipboardListener.clear(); - } -} - - -TransferableDataHelper TransferableDataHelper::CreateFromSystemClipboard( vcl::Window * pWindow ) -{ - DBG_ASSERT( pWindow, "Window pointer is NULL" ); - - Reference< XClipboard > xClipboard; - TransferableDataHelper aRet; - - if( pWindow ) - xClipboard = pWindow->GetClipboard(); - - if( xClipboard.is() ) - { - try - { - Reference< XTransferable > xTransferable( xClipboard->getContents() ); - - if( xTransferable.is() ) - { - aRet = TransferableDataHelper( xTransferable ); - // also copy the clipboard - aRet.mxClipboard = xClipboard; - } - } - catch( const css::uno::Exception& ) - { - } - } - - return aRet; -} - - -TransferableDataHelper TransferableDataHelper::CreateFromSelection( vcl::Window* pWindow ) -{ - DBG_ASSERT( pWindow, "Window pointer is NULL" ); - - Reference< XClipboard > xSelection; - TransferableDataHelper aRet; - - if( pWindow ) - xSelection = pWindow->GetPrimarySelection(); - - if( xSelection.is() ) - { - SolarMutexReleaser aReleaser; - - try - { - Reference< XTransferable > xTransferable( xSelection->getContents() ); - - if( xTransferable.is() ) - { - aRet = TransferableDataHelper( xTransferable ); - aRet.mxClipboard = xSelection; - } - } - catch( const css::uno::Exception& ) - { - } - } - - return aRet; -} - - -bool TransferableDataHelper::IsEqual( const css::datatransfer::DataFlavor& rInternalFlavor, - const css::datatransfer::DataFlavor& rRequestFlavor ) -{ - Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() ); - bool bRet = false; - - try - { - Reference< XMimeContentTypeFactory > xMimeFact = MimeContentTypeFactory::create( xContext ); - - Reference< XMimeContentType > xRequestType1( xMimeFact->createMimeContentType( rInternalFlavor.MimeType ) ); - Reference< XMimeContentType > xRequestType2( xMimeFact->createMimeContentType( rRequestFlavor.MimeType ) ); - - if( xRequestType1.is() && xRequestType2.is() ) - { - if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( xRequestType2->getFullMediaType() ) ) - { - if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( "text/plain" ) ) - { - // special handling for text/plain media types - const OUString aCharsetString( "charset" ); - - if( !xRequestType2->hasParameter( aCharsetString ) || - xRequestType2->getParameterValue( aCharsetString ).equalsIgnoreAsciiCase( "utf-16" ) || - xRequestType2->getParameterValue( aCharsetString ).equalsIgnoreAsciiCase( "unicode" ) ) - { - bRet = true; - } - } - else if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( "application/x-openoffice" ) ) - { - // special handling for application/x-openoffice media types - const OUString aFormatString( "windows_formatname" ); - - if( xRequestType1->hasParameter( aFormatString ) && - xRequestType2->hasParameter( aFormatString ) && - xRequestType1->getParameterValue( aFormatString ).equalsIgnoreAsciiCase( xRequestType2->getParameterValue( aFormatString ) ) ) - { - bRet = true; - } - } - else - bRet = true; - } - } - } - catch( const css::uno::Exception& ) - { - bRet = rInternalFlavor.MimeType.equalsIgnoreAsciiCase( rRequestFlavor.MimeType ); - } - - return bRet; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/misc/transfer2.cxx b/svtools/source/misc/transfer2.cxx deleted file mode 100644 index 5405ce9683a2..000000000000 --- a/svtools/source/misc/transfer2.cxx +++ /dev/null @@ -1,472 +0,0 @@ -/* -*- 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 <osl/mutex.hxx> -#include <sot/exchange.hxx> -#include <sot/storage.hxx> -#include <vcl/bitmap.hxx> -#include <vcl/gdimtf.hxx> -#include <vcl/graph.hxx> -#include <vcl/svapp.hxx> -#include <vcl/window.hxx> -#include <comphelper/fileformat.h> -#include <com/sun/star/datatransfer/dnd/XDropTargetDragContext.hpp> -#include <svl/urlbmk.hxx> -#include <svtools/inetimg.hxx> -#include <svtools/imap.hxx> -#include <svtools/transfer.hxx> - - -using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::lang; -using namespace ::com::sun::star::io; -using namespace ::com::sun::star::datatransfer; -using namespace ::com::sun::star::datatransfer::clipboard; -using namespace ::com::sun::star::datatransfer::dnd; - - -DragSourceHelper::DragGestureListener::DragGestureListener( DragSourceHelper& rDragSourceHelper ) : - mrParent( rDragSourceHelper ) -{ -} - - -DragSourceHelper::DragGestureListener::~DragGestureListener() -{ -} - - -void SAL_CALL DragSourceHelper::DragGestureListener::disposing( const EventObject& ) -{ -} - - -void SAL_CALL DragSourceHelper::DragGestureListener::dragGestureRecognized( const DragGestureEvent& rDGE ) -{ - const SolarMutexGuard aGuard; - - const Point aPtPixel( rDGE.DragOriginX, rDGE.DragOriginY ); - mrParent.StartDrag( rDGE.DragAction, aPtPixel ); -} - - -DragSourceHelper::DragSourceHelper( vcl::Window* pWindow ) : - mxDragGestureRecognizer( pWindow->GetDragGestureRecognizer() ) -{ - if( mxDragGestureRecognizer.is() ) - { - mxDragGestureListener = new DragSourceHelper::DragGestureListener( *this ); - mxDragGestureRecognizer->addDragGestureListener( mxDragGestureListener ); - } -} - - -void DragSourceHelper::dispose() -{ - Reference<XDragGestureRecognizer> xTmp; - { - osl::MutexGuard aGuard( maMutex ); - xTmp = mxDragGestureRecognizer; - mxDragGestureRecognizer.clear(); - } - if( xTmp.is() ) - xTmp->removeDragGestureListener( mxDragGestureListener ); -} - -DragSourceHelper::~DragSourceHelper() -{ - dispose(); -} - - -void DragSourceHelper::StartDrag( sal_Int8, const Point& ) -{ -} - - -DropTargetHelper::DropTargetListener::DropTargetListener( DropTargetHelper& rDropTargetHelper ) : - mrParent( rDropTargetHelper ) -{ -} - - -DropTargetHelper::DropTargetListener::~DropTargetListener() -{ -} - - -void SAL_CALL DropTargetHelper::DropTargetListener::disposing( const EventObject& ) -{ -} - - -void SAL_CALL DropTargetHelper::DropTargetListener::drop( const DropTargetDropEvent& rDTDE ) -{ - const SolarMutexGuard aGuard; - - try - { - AcceptDropEvent aAcceptEvent; - ExecuteDropEvent aExecuteEvt( rDTDE.DropAction & ~DNDConstants::ACTION_DEFAULT, Point( rDTDE.LocationX, rDTDE.LocationY ), rDTDE ); - - aExecuteEvt.mbDefault = ( ( rDTDE.DropAction & DNDConstants::ACTION_DEFAULT ) != 0 ); - - // in case of a default action, call ::AcceptDrop first and use the returned - // accepted action as the execute action in the call to ::ExecuteDrop - aAcceptEvent.mnAction = aExecuteEvt.mnAction; - aAcceptEvent.maPosPixel = aExecuteEvt.maPosPixel; - static_cast<DropTargetEvent&>(const_cast<DropTargetDragEvent&>( aAcceptEvent.maDragEvent )) = rDTDE; - const_cast<DropTargetDragEvent&>( aAcceptEvent.maDragEvent ).DropAction = rDTDE.DropAction; - const_cast<DropTargetDragEvent&>( aAcceptEvent.maDragEvent ).LocationX = rDTDE.LocationX; - const_cast<DropTargetDragEvent&>( aAcceptEvent.maDragEvent ).LocationY = rDTDE.LocationY; - const_cast<DropTargetDragEvent&>( aAcceptEvent.maDragEvent ).SourceActions = rDTDE.SourceActions; - aAcceptEvent.mbLeaving = false; - aAcceptEvent.mbDefault = aExecuteEvt.mbDefault; - - sal_Int8 nRet = mrParent.AcceptDrop( aAcceptEvent ); - - if( DNDConstants::ACTION_NONE != nRet ) - { - rDTDE.Context->acceptDrop( nRet ); - - if( aExecuteEvt.mbDefault ) - aExecuteEvt.mnAction = nRet; - - nRet = mrParent.ExecuteDrop( aExecuteEvt ); - } - - rDTDE.Context->dropComplete( DNDConstants::ACTION_NONE != nRet ); - - mpLastDragOverEvent.reset(); - } - catch( const css::uno::Exception& ) - { - } -} - - -void SAL_CALL DropTargetHelper::DropTargetListener::dragEnter( const DropTargetDragEnterEvent& rDTDEE ) -{ - const SolarMutexGuard aGuard; - - try - { - mrParent.ImplBeginDrag( rDTDEE.SupportedDataFlavors ); - } - catch( const css::uno::Exception& ) - { - } - - dragOver( rDTDEE ); -} - - -void SAL_CALL DropTargetHelper::DropTargetListener::dragOver( const DropTargetDragEvent& rDTDE ) -{ - const SolarMutexGuard aGuard; - - try - { - mpLastDragOverEvent.reset( new AcceptDropEvent( rDTDE.DropAction & ~DNDConstants::ACTION_DEFAULT, Point( rDTDE.LocationX, rDTDE.LocationY ), rDTDE ) ); - mpLastDragOverEvent->mbDefault = ( ( rDTDE.DropAction & DNDConstants::ACTION_DEFAULT ) != 0 ); - - const sal_Int8 nRet = mrParent.AcceptDrop( *mpLastDragOverEvent ); - - if( DNDConstants::ACTION_NONE == nRet ) - rDTDE.Context->rejectDrag(); - else - rDTDE.Context->acceptDrag( nRet ); - } - catch( const css::uno::Exception& ) - { - } -} - - -void SAL_CALL DropTargetHelper::DropTargetListener::dragExit( const DropTargetEvent& ) -{ - const SolarMutexGuard aGuard; - - try - { - if( mpLastDragOverEvent ) - { - mpLastDragOverEvent->mbLeaving = true; - mrParent.AcceptDrop( *mpLastDragOverEvent ); - mpLastDragOverEvent.reset(); - } - - mrParent.ImplEndDrag(); - } - catch( const css::uno::Exception& ) - { - } -} - - -void SAL_CALL DropTargetHelper::DropTargetListener::dropActionChanged( const DropTargetDragEvent& ) -{ -} - - -DropTargetHelper::DropTargetHelper( vcl::Window* pWindow ) : - mxDropTarget( pWindow->GetDropTarget() ) -{ - ImplConstruct(); -} - - -DropTargetHelper::DropTargetHelper( const Reference< XDropTarget >& rxDropTarget ) : - mxDropTarget( rxDropTarget ) -{ - ImplConstruct(); -} - - -void DropTargetHelper::dispose() -{ - Reference< XDropTarget > xTmp; - { - osl::MutexGuard aGuard( maMutex ); - xTmp = mxDropTarget; - mxDropTarget.clear(); - } - if( xTmp.is() ) - xTmp->removeDropTargetListener( mxDropTargetListener ); -} - -DropTargetHelper::~DropTargetHelper() -{ - dispose(); -} - - -void DropTargetHelper::ImplConstruct() -{ - if( mxDropTarget.is() ) - { - mxDropTargetListener = new DropTargetHelper::DropTargetListener( *this ); - mxDropTarget->addDropTargetListener( mxDropTargetListener ); - mxDropTarget->setActive( true ); - } -} - - -void DropTargetHelper::ImplBeginDrag( const Sequence< DataFlavor >& rSupportedDataFlavors ) -{ - maFormats.clear(); - TransferableDataHelper::FillDataFlavorExVector( rSupportedDataFlavors, maFormats ); -} - - -void DropTargetHelper::ImplEndDrag() -{ - maFormats.clear(); -} - - -sal_Int8 DropTargetHelper::AcceptDrop( const AcceptDropEvent& ) -{ - return DNDConstants::ACTION_NONE; -} - - -sal_Int8 DropTargetHelper::ExecuteDrop( const ExecuteDropEvent& ) -{ - return DNDConstants::ACTION_NONE; -} - - -bool DropTargetHelper::IsDropFormatSupported( SotClipboardFormatId nFormat ) -{ - return std::any_of(maFormats.begin(), maFormats.end(), - [&](const DataFlavorEx& data) { return data.mnSotId == nFormat; }); -} - - -// TransferDataContainer - - -struct TDataCntnrEntry_Impl -{ - css::uno::Any aAny; - SotClipboardFormatId nId; -}; - - -typedef ::std::vector< TDataCntnrEntry_Impl > TDataCntnrEntryList; - - -struct TransferDataContainer_Impl -{ - TDataCntnrEntryList aFmtList; - Link<sal_Int8,void> aFinshedLnk; - std::unique_ptr<INetBookmark> pBookmk; - - TransferDataContainer_Impl() - { - } -}; - - -TransferDataContainer::TransferDataContainer() - : pImpl( new TransferDataContainer_Impl ) -{ -} - - -TransferDataContainer::~TransferDataContainer() -{ -} - - -void TransferDataContainer::AddSupportedFormats() -{ -} - - -bool TransferDataContainer::GetData( - const css::datatransfer::DataFlavor& rFlavor, const OUString& /*rDestDoc*/ ) -{ - bool bFnd = false; - SotClipboardFormatId nFmtId = SotExchange::GetFormat( rFlavor ); - - // test first the list - for (auto const& format : pImpl->aFmtList) - { - if( nFmtId == format.nId ) - { - bFnd = SetAny( format.aAny ); - break; - } - } - - // test second the bookmark pointer - if( !bFnd ) - switch( nFmtId ) - { - case SotClipboardFormatId::STRING: - case SotClipboardFormatId::SOLK: - case SotClipboardFormatId::NETSCAPE_BOOKMARK: - case SotClipboardFormatId::FILECONTENT: - case SotClipboardFormatId::FILEGRPDESCRIPTOR: - case SotClipboardFormatId::UNIFORMRESOURCELOCATOR: - if( pImpl->pBookmk ) - bFnd = SetINetBookmark( *pImpl->pBookmk, rFlavor ); - break; - - default: break; - } - - return bFnd; -} - - -void TransferDataContainer::CopyINetBookmark( const INetBookmark& rBkmk ) -{ - if( !pImpl->pBookmk ) - pImpl->pBookmk.reset( new INetBookmark( rBkmk ) ); - else - *pImpl->pBookmk = rBkmk; - - AddFormat( SotClipboardFormatId::STRING ); - AddFormat( SotClipboardFormatId::SOLK ); - AddFormat( SotClipboardFormatId::NETSCAPE_BOOKMARK ); - AddFormat( SotClipboardFormatId::FILECONTENT ); - AddFormat( SotClipboardFormatId::FILEGRPDESCRIPTOR ); - AddFormat( SotClipboardFormatId::UNIFORMRESOURCELOCATOR ); -} - - -void TransferDataContainer::CopyAnyData( SotClipboardFormatId nFormatId, - const sal_Char* pData, sal_uLong nLen ) -{ - if( nLen ) - { - TDataCntnrEntry_Impl aEntry; - aEntry.nId = nFormatId; - - Sequence< sal_Int8 > aSeq( nLen ); - memcpy( aSeq.getArray(), pData, nLen ); - aEntry.aAny <<= aSeq; - pImpl->aFmtList.push_back( aEntry ); - AddFormat( nFormatId ); - } -} - - -void TransferDataContainer::CopyByteString( SotClipboardFormatId nFormatId, - const OString& rStr ) -{ - CopyAnyData( nFormatId, rStr.getStr(), rStr.getLength() ); -} - - -void TransferDataContainer::CopyString( SotClipboardFormatId nFmt, const OUString& rStr ) -{ - if( !rStr.isEmpty() ) - { - TDataCntnrEntry_Impl aEntry; - aEntry.nId = nFmt; - aEntry.aAny <<= rStr; - pImpl->aFmtList.push_back( aEntry ); - AddFormat( aEntry.nId ); - } -} - - -void TransferDataContainer::CopyString( const OUString& rStr ) -{ - CopyString( SotClipboardFormatId::STRING, rStr ); -} - - -void TransferDataContainer::CopyAny( SotClipboardFormatId nFmt, - const css::uno::Any& rAny ) -{ - TDataCntnrEntry_Impl aEntry; - aEntry.nId = nFmt; - aEntry.aAny = rAny; - pImpl->aFmtList.push_back( aEntry ); - AddFormat( aEntry.nId ); -} - - -bool TransferDataContainer::HasAnyData() const -{ - return !pImpl->aFmtList.empty() || - nullptr != pImpl->pBookmk; -} - - -void TransferDataContainer::StartDrag( - vcl::Window* pWindow, sal_Int8 nDragSourceActions, - const Link<sal_Int8,void>& rLnk ) -{ - pImpl->aFinshedLnk = rLnk; - TransferableHelper::StartDrag( pWindow, nDragSourceActions ); -} - - -void TransferDataContainer::DragFinished( sal_Int8 nDropAction ) -{ - pImpl->aFinshedLnk.Call( nDropAction ); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/svhtml/htmlout.cxx b/svtools/source/svhtml/htmlout.cxx index dd94023011de..65b7da3e7317 100644 --- a/svtools/source/svhtml/htmlout.cxx +++ b/svtools/source/svhtml/htmlout.cxx @@ -26,10 +26,10 @@ #include <svtools/htmlout.hxx> #include <svtools/htmlkywd.hxx> -#include <svtools/imap.hxx> -#include <svtools/imaprect.hxx> -#include <svtools/imapcirc.hxx> -#include <svtools/imappoly.hxx> +#include <vcl/imap.hxx> +#include <vcl/imaprect.hxx> +#include <vcl/imapcirc.hxx> +#include <vcl/imappoly.hxx> #include <svl/urihelper.hxx> #include <rtl/character.hxx> diff --git a/svtools/source/uitest/uiobject.cxx b/svtools/source/uitest/uiobject.cxx index 99eac13cabc5..3c0a34b26a8d 100644 --- a/svtools/source/uitest/uiobject.cxx +++ b/svtools/source/uitest/uiobject.cxx @@ -10,163 +10,11 @@ #include <memory> #include <uitest/uiobject.hxx> -#include <svtools/treelistbox.hxx> +#include <vcl/treelistbox.hxx> #include <svtools/simptabl.hxx> -TreeListUIObject::TreeListUIObject(const VclPtr<SvTreeListBox>& xTreeList): - WindowUIObject(xTreeList), - mxTreeList(xTreeList) -{ -} - namespace { -bool isCheckBoxList(const VclPtr<SvTreeListBox>& xTreeList) -{ - return (xTreeList->GetTreeFlags() & SvTreeFlags::CHKBTN) == SvTreeFlags::CHKBTN; -} - -} - -StringMap TreeListUIObject::get_state() -{ - StringMap aMap = WindowUIObject::get_state(); - - aMap["SelectionCount"] = OUString::number(mxTreeList->GetSelectionCount()); - aMap["VisibleCount"] = OUString::number(mxTreeList->GetVisibleCount()); - aMap["Children"] = OUString::number(mxTreeList->GetChildCount(nullptr)); - aMap["LevelChildren"] = OUString::number(mxTreeList->GetLevelChildCount(nullptr)); - aMap["CheckBoxList"] = OUString::boolean(isCheckBoxList(mxTreeList)); - return aMap; -} - -void TreeListUIObject::execute(const OUString& rAction, - const StringMap& rParameters) -{ - if (rAction.isEmpty()) - { - } - else - WindowUIObject::execute(rAction, rParameters); -} - -std::unique_ptr<UIObject> TreeListUIObject::get_child(const OUString& rID) -{ - sal_Int32 nID = rID.toInt32(); - if (nID >= 0) - { - SvTreeListEntry* pEntry = mxTreeList->GetEntry(nullptr, nID); - if (!pEntry) - return nullptr; - - return std::unique_ptr<UIObject>(new TreeListEntryUIObject(mxTreeList, pEntry)); - } - - return nullptr; -} - -std::set<OUString> TreeListUIObject::get_children() const -{ - std::set<OUString> aChildren; - - size_t nChildren = mxTreeList->GetLevelChildCount(nullptr); - for (size_t i = 0; i < nChildren; ++i) - { - aChildren.insert(OUString::number(i)); - } - - return aChildren; -} - -OUString TreeListUIObject::get_name() const -{ - return OUString("TreeListUIObject"); -} - -std::unique_ptr<UIObject> TreeListUIObject::create(vcl::Window* pWindow) -{ - SvTreeListBox* pTreeList = dynamic_cast<SvTreeListBox*>(pWindow); - assert(pTreeList); - return std::unique_ptr<UIObject>(new TreeListUIObject(pTreeList)); -} - -TreeListEntryUIObject::TreeListEntryUIObject(const VclPtr<SvTreeListBox>& xTreeList, SvTreeListEntry* pEntry): - mxTreeList(xTreeList), - mpEntry(pEntry) -{ -} - -StringMap TreeListEntryUIObject::get_state() -{ - StringMap aMap; - - aMap["Text"] = mxTreeList->GetEntryText(mpEntry); - aMap["Children"] = OUString::number(mxTreeList->GetLevelChildCount(mpEntry)); - aMap["VisibleChildCount"] = OUString::number(mxTreeList->GetVisibleChildCount(mpEntry)); - - return aMap; -} - -void TreeListEntryUIObject::execute(const OUString& rAction, const StringMap& /*rParameters*/) -{ - if (rAction == "COLLAPSE") - { - mxTreeList->Collapse(mpEntry); - } - else if (rAction == "EXPAND") - { - mxTreeList->Expand(mpEntry); - } - else if (rAction == "SELECT") - { - mxTreeList->Select(mpEntry); - } - else if (rAction == "DESELECT") - { - mxTreeList->Select(mpEntry, false); - } - else if (rAction == "CLICK") - { - if (!isCheckBoxList(mxTreeList)) - return; - SvButtonState eState = mxTreeList->GetCheckButtonState(mpEntry); - eState = eState == SvButtonState::Checked ? SvButtonState::Unchecked : SvButtonState::Checked; - mxTreeList->SetCheckButtonState(mpEntry, eState); - mxTreeList->CheckButtonHdl(); - } -} - -std::unique_ptr<UIObject> TreeListEntryUIObject::get_child(const OUString& rID) -{ - sal_Int32 nID = rID.toInt32(); - if (nID >= 0) - { - SvTreeListEntry* pEntry = mxTreeList->GetEntry(mpEntry, nID); - if (!pEntry) - return nullptr; - - return std::unique_ptr<UIObject>(new TreeListEntryUIObject(mxTreeList, pEntry)); - } - - return nullptr; -} - -std::set<OUString> TreeListEntryUIObject::get_children() const -{ - std::set<OUString> aChildren; - - size_t nChildren = mxTreeList->GetLevelChildCount(mpEntry); - for (size_t i = 0; i < nChildren; ++i) - { - aChildren.insert(OUString::number(i)); - } - - return aChildren; -} - -OUString TreeListEntryUIObject::get_type() const -{ - return OUString("TreeListEntry"); } SimpleTableUIObject::SimpleTableUIObject(const VclPtr<SvSimpleTable>& xTable): diff --git a/svtools/source/uno/treecontrolpeer.cxx b/svtools/source/uno/treecontrolpeer.cxx index d11d57e377fb..f38861d4442b 100644 --- a/svtools/source/uno/treecontrolpeer.cxx +++ b/svtools/source/uno/treecontrolpeer.cxx @@ -35,10 +35,10 @@ #include <rtl/ref.hxx> #include <vcl/graph.hxx> #include <vcl/svapp.hxx> -#include <svtools/treelistbox.hxx> -#include <svtools/treelistentry.hxx> -#include <svtools/viewdataentry.hxx> -#include <svtools/svlbitm.hxx> +#include <vcl/treelistbox.hxx> +#include <vcl/treelistentry.hxx> +#include <vcl/viewdataentry.hxx> +#include <vcl/svlbitm.hxx> #include <map> #include <o3tl/make_unique.hxx> diff --git a/svtools/source/uno/unoiface.cxx b/svtools/source/uno/unoiface.cxx index a14848fd3de7..e5f3cade1ec4 100644 --- a/svtools/source/uno/unoiface.cxx +++ b/svtools/source/uno/unoiface.cxx @@ -35,7 +35,7 @@ #include <svtools/fmtfield.hxx> #include <svl/numuno.hxx> #include <svtools/calendar.hxx> -#include <svtools/treelistbox.hxx> +#include <vcl/treelistbox.hxx> #include "treecontrolpeer.hxx" #include "svtxgridcontrol.hxx" #include <table/tablecontrol.hxx> diff --git a/svtools/source/uno/unoimap.cxx b/svtools/source/uno/unoimap.cxx index e863a2ed5389..cbfe92690b66 100644 --- a/svtools/source/uno/unoimap.cxx +++ b/svtools/source/uno/unoimap.cxx @@ -39,10 +39,10 @@ #include <vcl/svapp.hxx> #include <svtools/unoevent.hxx> #include <svtools/unoimap.hxx> -#include <svtools/imap.hxx> -#include <svtools/imapcirc.hxx> -#include <svtools/imaprect.hxx> -#include <svtools/imappoly.hxx> +#include <vcl/imap.hxx> +#include <vcl/imapcirc.hxx> +#include <vcl/imaprect.hxx> +#include <vcl/imappoly.hxx> using namespace comphelper; using namespace cppu; diff --git a/svtools/source/urlobj/inetimg.cxx b/svtools/source/urlobj/inetimg.cxx deleted file mode 100644 index f3b92c69b305..000000000000 --- a/svtools/source/urlobj/inetimg.cxx +++ /dev/null @@ -1,135 +0,0 @@ -/* -*- 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 <osl/thread.h> -#include <sot/formats.hxx> -#include <tools/stream.hxx> - -#include <svtools/inetimg.hxx> - -static const sal_Unicode TOKEN_SEPARATOR = '\001'; - -void INetImage::Write( SvStream& rOStm, SotClipboardFormatId nFormat ) const -{ - switch( nFormat ) - { - case SotClipboardFormatId::INET_IMAGE: - { - OUString sString( - aImageURL + OUStringLiteral1(TOKEN_SEPARATOR) + aTargetURL - + OUStringLiteral1(TOKEN_SEPARATOR) + aTargetFrame - + OUStringLiteral1(TOKEN_SEPARATOR) /* + aAlternateText */ - + OUStringLiteral1(TOKEN_SEPARATOR) - + OUString::number(aSizePixel.Width()) - + OUStringLiteral1(TOKEN_SEPARATOR) - + OUString::number(aSizePixel.Height())); - - OString sOut(OUStringToOString(sString, - RTL_TEXTENCODING_UTF8)); - - rOStm.WriteBytes(sOut.getStr(), sOut.getLength()); - static const sal_Char aEndChar[2] = { 0 }; - rOStm.WriteBytes(aEndChar, sizeof(aEndChar)); - } - break; - - case SotClipboardFormatId::NETSCAPE_IMAGE: - break; - default: break; - } -} - -bool INetImage::Read( SvStream& rIStm, SotClipboardFormatId nFormat ) -{ - bool bRet = false; - switch( nFormat ) - { - case SotClipboardFormatId::INET_IMAGE: - { - OUString sINetImg = read_zeroTerminated_uInt8s_ToOUString(rIStm, RTL_TEXTENCODING_UTF8); - sal_Int32 nStart = 0; - aImageURL = sINetImg.getToken( 0, TOKEN_SEPARATOR, nStart ); - aTargetURL = sINetImg.getToken( 0, TOKEN_SEPARATOR, nStart ); - aTargetFrame = sINetImg.getToken( 0, TOKEN_SEPARATOR, nStart ); - /*aAlternateText =*/ sINetImg.getToken( 0, TOKEN_SEPARATOR, nStart ); - aSizePixel.setWidth( sINetImg.getToken( 0, TOKEN_SEPARATOR, - nStart ).toInt32() ); - aSizePixel.setHeight( sINetImg.getToken( 0, TOKEN_SEPARATOR, - nStart ).toInt32() ); - bRet = !sINetImg.isEmpty(); - } - break; - - case SotClipboardFormatId::NETSCAPE_IMAGE: - { -/* - --> structure size MUST - alignment of 4! - int iSize; // size of all data, including variable length strings - sal_Bool bIsMap; // For server side maps - sal_Int32 iWidth; // Fixed size data correspond to fields in LO_ImageDataStruct - sal_Int32 iHeight; // and EDT_ImageData - sal_Int32 iHSpace; - sal_Int32 iVSpace; - sal_Int32 iBorder; - int iLowResOffset; // Offsets into string_data. If 0, string is NULL (not used) - int iAltOffset; // (alternate text?) - int iAnchorOffset; // HREF in image - int iExtraHTML_Offset; // Extra HTML (stored in CImageElement) - sal_Char pImageURL[1]; // Append all variable-length strings starting here -*/ - rtl_TextEncoding eSysCSet = osl_getThreadTextEncoding(); - sal_Int32 nVal, nAnchorOffset, nAltOffset; - sal_uInt64 nFilePos; - - nFilePos = rIStm.Tell(); - // skip over iSize (int), bIsMao ( sal_Bool ) alignment of 4 !!!! - rIStm.SeekRel( 8 ); - rIStm.ReadInt32( nVal ); aSizePixel.setWidth( nVal ); - rIStm.ReadInt32( nVal ); aSizePixel.setHeight( nVal ); - // skip over iHSpace, iVSpace, iBorder, iLowResOffset - rIStm.SeekRel( 3 * sizeof( sal_Int32 ) + sizeof( int ) ); - rIStm.ReadInt32( nAltOffset ); - rIStm.ReadInt32( nAnchorOffset ); - // skip over iExtraHTML_Offset - rIStm.SeekRel( sizeof( int ) ); - - aImageURL = read_zeroTerminated_uInt8s_ToOUString(rIStm, eSysCSet); - if( nAltOffset ) - { - rIStm.Seek( nFilePos + nAltOffset ); - /*aAlternateText =*/ read_zeroTerminated_uInt8s_ToOUString(rIStm, eSysCSet); - } - - if( nAnchorOffset ) - { - rIStm.Seek( nFilePos + nAnchorOffset ); - aTargetURL = read_zeroTerminated_uInt8s_ToOUString(rIStm, eSysCSet); - } - else if( !aTargetURL.isEmpty() ) - aTargetURL.clear(); - - bRet = ERRCODE_NONE == rIStm.GetError(); - } - break; - default: break; - } - return bRet; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |