weld calc navigator

note: non-standard dnd via parent so the treeview triggers the dnd but doesn't
itself strictly speaking drive the dnd, see copying a range from the navigator
where the calc main edit window shows the outline where the copy of the range
from the calc main window will go

Change-Id: Ideecbe779e3d9bb5b392357a93ec25f625180ba8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89597
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/extras/source/glade/libreoffice-catalog.xml.in b/extras/source/glade/libreoffice-catalog.xml.in
index 4d09187..a1572d3 100644
--- a/extras/source/glade/libreoffice-catalog.xml.in
+++ b/extras/source/glade/libreoffice-catalog.xml.in
@@ -56,13 +56,6 @@
                        generic-name="Page List Control" parent="GtkTreeView"
                        icon-name="widget-gtk-treeview"/>

    <glade-widget-class title="Calc Row SpinButton" name="sclo-RowEdit"
                        generic-name="Calc Row SpinButton" parent="GtkSpinButton"
                        icon-name="widget-gtk-spinbutton"/>
    <glade-widget-class title="Calc Column SpinButton" name="sclo-ColumnEdit"
                        generic-name="Calc Column SpinButton" parent="GtkSpinButton"
                        icon-name="widget-gtk-spinbutton"/>

    <glade-widget-class title="PropertyControl" name="sdlo-PropertyControl"
                        generic-name="PropertyControl" parent="GtkComboBoxText"
                        icon-name="widget-gtk-comboboxtext"/>
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index fa65940..7a45730e 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -722,8 +722,9 @@ protected:
    Link<TreeView&, void> m_aModelChangedHdl;
    // if handler returns true, then menu has been show and event is consumed
    Link<const CommandEvent&, bool> m_aPopupMenuHdl;
    // if handler returns true, drag is disallowed
    Link<TreeView&, bool> m_aDragBeginHdl;
    // if handler returns true, drag is disallowed, consumer can change bool
    // arg to false to disable the treeview default dnd icon
    Link<bool&, bool> m_aDragBeginHdl;
    std::function<int(const weld::TreeIter&, const weld::TreeIter&)> m_aCustomSort;

    std::vector<int> m_aRadioIndexes;
@@ -991,7 +992,7 @@ public:
                                    sal_uInt8 eDNDConstants)
        = 0;

    void connect_drag_begin(const Link<TreeView&, bool>& rLink) { m_aDragBeginHdl = rLink; }
    void connect_drag_begin(const Link<bool&, bool>& rLink) { m_aDragBeginHdl = rLink; }

    //all of them
    void select_all() { unselect(-1); }
@@ -1215,23 +1216,28 @@ public:
    void connect_selected(const Link<const OString&, void>& rLink) { m_aSelectHdl = rLink; }

    virtual void insert_item(int pos, const OUString& rId, const OUString& rStr,
                             const OUString* pIconName, VirtualDevice* pImageSufface, bool bCheck)
                             const OUString* pIconName, VirtualDevice* pImageSufface,
                             TriState eCheckRadioFalse)
        = 0;
    void append_item(const OUString& rId, const OUString& rStr)
    {
        insert_item(-1, rId, rStr, nullptr, nullptr, false);
        insert_item(-1, rId, rStr, nullptr, nullptr, TRISTATE_INDET);
    }
    void append_item_check(const OUString& rId, const OUString& rStr)
    {
        insert_item(-1, rId, rStr, nullptr, nullptr, true);
        insert_item(-1, rId, rStr, nullptr, nullptr, TRISTATE_TRUE);
    }
    void append_item_radio(const OUString& rId, const OUString& rStr)
    {
        insert_item(-1, rId, rStr, nullptr, nullptr, TRISTATE_FALSE);
    }
    void append_item(const OUString& rId, const OUString& rStr, const OUString& rImage)
    {
        insert_item(-1, rId, rStr, &rImage, nullptr, false);
        insert_item(-1, rId, rStr, &rImage, nullptr, TRISTATE_INDET);
    }
    void append_item(const OUString& rId, const OUString& rStr, VirtualDevice& rImage)
    {
        insert_item(-1, rId, rStr, nullptr, &rImage, false);
        insert_item(-1, rId, rStr, nullptr, &rImage, TRISTATE_INDET);
    }
    virtual void insert_separator(int pos, const OUString& rId) = 0;
    void append_separator(const OUString& rId) { insert_separator(-1, rId); }
@@ -1957,12 +1963,14 @@ public:

    virtual void set_sensitive(const OString& rIdent, bool bSensitive) = 0;
    virtual void set_label(const OString& rIdent, const OUString& rLabel) = 0;
    virtual OUString get_label(const OString& rIdent) const = 0;
    virtual void set_active(const OString& rIdent, bool bActive) = 0;
    virtual bool get_active(const OString& rIdent) const = 0;
    virtual void set_visible(const OString& rIdent, bool bVisible) = 0;

    virtual void insert(int pos, const OUString& rId, const OUString& rStr,
                        const OUString* pIconName, VirtualDevice* pImageSufface, bool bCheck)
                        const OUString* pIconName, VirtualDevice* pImageSufface,
                        TriState eCheckRadioFalse)
        = 0;

    virtual void clear() = 0;
@@ -1972,19 +1980,23 @@ public:

    void append(const OUString& rId, const OUString& rStr)
    {
        insert(-1, rId, rStr, nullptr, nullptr, false);
        insert(-1, rId, rStr, nullptr, nullptr, TRISTATE_INDET);
    }
    void append_check(const OUString& rId, const OUString& rStr)
    {
        insert(-1, rId, rStr, nullptr, nullptr, true);
        insert(-1, rId, rStr, nullptr, nullptr, TRISTATE_TRUE);
    }
    void append_radio(const OUString& rId, const OUString& rStr)
    {
        insert(-1, rId, rStr, nullptr, nullptr, TRISTATE_FALSE);
    }
    void append(const OUString& rId, const OUString& rStr, const OUString& rImage)
    {
        insert(-1, rId, rStr, &rImage, nullptr, false);
        insert(-1, rId, rStr, &rImage, nullptr, TRISTATE_FALSE);
    }
    void append(const OUString& rId, const OUString& rStr, VirtualDevice& rImage)
    {
        insert(-1, rId, rStr, nullptr, &rImage, false);
        insert(-1, rId, rStr, nullptr, &rImage, TRISTATE_FALSE);
    }

    // return the number of toplevel nodes
diff --git a/reportdesign/source/ui/dlg/AddField.cxx b/reportdesign/source/ui/dlg/AddField.cxx
index 341430c..895ea2b 100644
--- a/reportdesign/source/ui/dlg/AddField.cxx
+++ b/reportdesign/source/ui/dlg/AddField.cxx
@@ -55,8 +55,9 @@ using namespace lang;
using namespace container;
using namespace ::svx;

IMPL_LINK_NOARG(OAddFieldWindow, DragBeginHdl, weld::TreeView&, bool)
IMPL_LINK(OAddFieldWindow, DragBeginHdl, bool&, rUnsetDragIcon, bool)
{
    rUnsetDragIcon = false;
    if (m_xListBox->get_selected_index() == -1)
    {
        // no drag without a field
diff --git a/reportdesign/source/ui/inc/AddField.hxx b/reportdesign/source/ui/inc/AddField.hxx
index a15c809..b348fcd 100644
--- a/reportdesign/source/ui/inc/AddField.hxx
+++ b/reportdesign/source/ui/inc/AddField.hxx
@@ -68,7 +68,7 @@ class  OAddFieldWindow : public weld::GenericDialogController

    DECL_LINK( OnDoubleClickHdl, weld::TreeView&, bool );
    DECL_LINK( OnSelectHdl, weld::TreeView&, void );
    DECL_LINK( DragBeginHdl, weld::TreeView&, bool );
    DECL_LINK( DragBeginHdl, bool&, bool );
    DECL_LINK( OnSortAction, const OString&, void );
    DECL_LINK( FocusChangeHdl, weld::Widget&, void );

diff --git a/sc/inc/pch/precompiled_sc.hxx b/sc/inc/pch/precompiled_sc.hxx
index 0fd221f..ff3ca6d 100644
--- a/sc/inc/pch/precompiled_sc.hxx
+++ b/sc/inc/pch/precompiled_sc.hxx
@@ -13,7 +13,7 @@
 manual changes will be rewritten by the next run of update_pch.sh (which presumably
 also fixes all possible problems, so it's usually better to use it).

 Generated on 2020-02-17 11:23:21 using:
 Generated on 2020-02-26 17:29:13 using:
 ./bin/update_pch sc sc --cutoff=12 --exclude:system --include:module --include:local

 If after updating build fails, use the following command to locate conflicting headers:
@@ -40,6 +40,7 @@
#include <math.h>
#include <memory>
#include <new>
#include <optional>
#include <ostream>
#include <set>
#include <sstream>
@@ -121,9 +122,7 @@
#include <vcl/ctrl.hxx>
#include <vcl/customweld.hxx>
#include <vcl/dllapi.h>
#include <vcl/dndhelp.hxx>
#include <vcl/dockwin.hxx>
#include <vcl/edit.hxx>
#include <vcl/errcode.hxx>
#include <vcl/event.hxx>
#include <vcl/floatwin.hxx>
@@ -144,7 +143,6 @@
#include <vcl/svapp.hxx>
#include <vcl/syswin.hxx>
#include <vcl/task.hxx>
#include <vcl/textfilter.hxx>
#include <vcl/timer.hxx>
#include <vcl/transfer.hxx>
#include <vcl/uitest/factory.hxx>
@@ -329,7 +327,6 @@
#include <o3tl/cow_wrapper.hxx>
#include <o3tl/deleter.hxx>
#include <o3tl/enumarray.hxx>
#include <optional>
#include <o3tl/safeint.hxx>
#include <o3tl/sorted_vector.hxx>
#include <o3tl/strong_int.hxx>
@@ -438,7 +435,6 @@
#include <tools/gen.hxx>
#include <tools/globname.hxx>
#include <tools/helpers.hxx>
#include <tools/lineend.hxx>
#include <tools/link.hxx>
#include <tools/mapunit.hxx>
#include <tools/poly.hxx>
diff --git a/sc/inc/pch/precompiled_scfilt.hxx b/sc/inc/pch/precompiled_scfilt.hxx
index c22daa4..aaa986c 100644
--- a/sc/inc/pch/precompiled_scfilt.hxx
+++ b/sc/inc/pch/precompiled_scfilt.hxx
@@ -13,7 +13,7 @@
 manual changes will be rewritten by the next run of update_pch.sh (which presumably
 also fixes all possible problems, so it's usually better to use it).

 Generated on 2020-02-01 10:57:51 using:
 Generated on 2020-02-26 17:28:59 using:
 ./bin/update_pch sc scfilt --cutoff=4 --exclude:system --exclude:module --include:local

 If after updating build fails, use the following command to locate conflicting headers:
@@ -33,6 +33,7 @@
#include <math.h>
#include <memory>
#include <new>
#include <optional>
#include <ostream>
#include <set>
#include <stack>
@@ -179,7 +180,6 @@
#include <filter/msfilter/msocximex.hxx>
#include <i18nlangtag/lang.h>
#include <o3tl/cow_wrapper.hxx>
#include <optional>
#include <o3tl/safeint.hxx>
#include <o3tl/sorted_vector.hxx>
#include <o3tl/strong_int.hxx>
diff --git a/sc/inc/strings.hrc b/sc/inc/strings.hrc
index 9a44676..a685c1e 100644
--- a/sc/inc/strings.hrc
+++ b/sc/inc/strings.hrc
@@ -154,8 +154,6 @@
#define SCSTR_CONTENT_NOTE                          NC_("SCSTR_CONTENT_NOTE", "Comments" )
#define SCSTR_CONTENT_AREALINK                      NC_("SCSTR_CONTENT_AREALINK", "Linked areas" )
#define SCSTR_CONTENT_DRAWING                       NC_("SCSTR_CONTENT_DRAWING", "Drawing objects")
#define SCSTR_DRAGMODE                              NC_("SCSTR_DRAGMODE", "Drag Mode" )
#define SCSTR_DISPLAY                               NC_("SCSTR_DISPLAY", "Display" )
#define SCSTR_ACTIVE                                NC_("SCSTR_ACTIVE", "active" )
#define SCSTR_NOTACTIVE                             NC_("SCSTR_NOTACTIVE", "inactive" )
#define SCSTR_HIDDEN                                NC_("SCSTR_HIDDEN", "hidden" )
diff --git a/sc/source/ui/inc/content.hxx b/sc/source/ui/inc/content.hxx
index ce290d8..3411d94 100644
--- a/sc/source/ui/inc/content.hxx
+++ b/sc/source/ui/inc/content.hxx
@@ -20,15 +20,16 @@
#ifndef INCLUDED_SC_SOURCE_UI_INC_CONTENT_HXX
#define INCLUDED_SC_SOURCE_UI_INC_CONTENT_HXX

#include <vcl/treelistbox.hxx>
#include <vcl/weld.hxx>
#include <address.hxx>
#include <tools/solar.h>
#include <o3tl/enumarray.hxx>

class ScNavigatorDlg;
class ScAreaLink;
class ScLinkTransferObj;
class ScDocument;
class ScDocShell;
class ScAreaLink;
class ScNavigatorDlg;

enum class ScContentId {
    ROOT, TABLE, RANGENAME, DBAREA,
@@ -38,10 +39,13 @@ enum class ScContentId {

const sal_uLong SC_CONTENT_NOCHILD  = ~0UL;

class ScContentTree : public SvTreeListBox
class ScContentTree
{
    std::unique_ptr<weld::TreeView> m_xTreeView;
    std::unique_ptr<weld::TreeIter> m_xScratchIter;
    rtl::Reference<ScLinkTransferObj> m_xTransferObj;
    VclPtr<ScNavigatorDlg>  pParentWindow;
    o3tl::enumarray<ScContentId, SvTreeListEntry*> pRootNodes;
    o3tl::enumarray<ScContentId, std::unique_ptr<weld::TreeIter>> m_aRootNodes;
    ScContentId             nRootType;          // set as Root
    OUString                aManualDoc;         // Switched in Navigator (Title)
    bool                    bHiddenDoc;         // Hidden active?
@@ -49,7 +53,9 @@ class ScContentTree : public SvTreeListBox
    OUString                aHiddenTitle;       // for display
    ScDocument*             pHiddenDocument;    // temporary
    bool                    bisInNavigatoeDlg;
    bool                    m_bFreeze;
    OUString                sKeyString;
    ImplSVEvent*            m_nAsyncMouseReleaseId;

    o3tl::enumarray<ScContentId, sal_uInt16> pPosList;     // for the sequence

@@ -84,49 +90,62 @@ class ScContentTree : public SvTreeListBox
        @param rnRootIndex  Root index of specified entry is returned.
        @param rnChildIndex  Index of the entry inside its root is returned (or SC_CONTENT_NOCHILD if entry is root).
        @param pEntry  The entry to examine. */
    void    GetEntryIndexes( ScContentId& rnRootIndex, sal_uLong& rnChildIndex, SvTreeListEntry* pEntry ) const;
    void    GetEntryIndexes(ScContentId& rnRootIndex, sal_uLong& rnChildIndex, weld::TreeIter* pEntry) const;

    /** Returns the child index of the specified listbox entry.
        @param pEntry  The entry to examine or NULL for the selected entry.
        @return  Index of the entry inside its root or SC_CONTENT_NOCHILD if entry is root. */
    sal_uLong   GetChildIndex( SvTreeListEntry* pEntry ) const;

    void    DoDrag();
    sal_uLong   GetChildIndex(weld::TreeIter* pEntry) const;

    ScDocument* GetSourceDocument();

    DECL_LINK( ContentDoubleClickHdl, SvTreeListBox*, bool );
    DECL_LINK( ExecDragHdl, void*, void );
    void freeze()
    {
        m_xTreeView->freeze();
        m_bFreeze = true;
    }

protected:
    void thaw()
    {
        m_xTreeView->thaw();
        m_bFreeze = false;
    }

    using SvTreeListBox::ExecuteDrop;
    void LaunchAsyncStoreNavigatorSettings();

    virtual sal_Int8    AcceptDrop( const AcceptDropEvent& rEvt ) override;
    virtual sal_Int8    ExecuteDrop( const ExecuteDropEvent& rEvt ) override;
    virtual void        StartDrag( sal_Int8 nAction, const Point& rPosPixel ) override;
    virtual void        DragFinished( sal_Int8 nAction ) override;

    virtual void        Command( const CommandEvent& rCEvt ) override;
    virtual void        RequestHelp( const HelpEvent& rHEvt ) override;
    virtual void        InitEntry(SvTreeListEntry*,const OUString&,const Image&,const Image&) override;
    DECL_LINK(ContentDoubleClickHdl, weld::TreeView&, bool);
    DECL_LINK(MouseReleaseHdl, const MouseEvent&, bool);
    DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
    DECL_LINK(AsyncStoreNavigatorSettings, void*, void);
    DECL_LINK(CommandHdl, const CommandEvent&, bool);
    DECL_LINK(DragBeginHdl, bool&, bool);

public:
    ScContentTree(vcl::Window* pParent, ScNavigatorDlg* pNavigatorDlg);
    virtual ~ScContentTree() override;
    virtual void dispose() override;
    ScContentTree(std::unique_ptr<weld::TreeView> xTreeView, ScNavigatorDlg* pNavigatorDlg);
    ~ScContentTree();

    OUString getAltLongDescText(SvTreeListEntry* pEntry, bool isAltText) const;
    OUString GetEntryAltText( SvTreeListEntry* pEntry ) const override;
    OUString GetEntryLongDescription( SvTreeListEntry* pEntry ) const override;

    void     ObjectFresh( ScContentId nType, const SvTreeListEntry* pEntry = nullptr);
    void     ObjectFresh(ScContentId nType, const weld::TreeIter* pEntry = nullptr);
    void     SetNavigatorDlgFlag(bool isInNavigateDlg){ bisInNavigatoeDlg=isInNavigateDlg;};
    virtual void    MouseButtonDown( const MouseEvent& rMEvt ) override;
    virtual void    KeyInput( const KeyEvent& rKEvt ) override;
    virtual Size    GetOptimalSize() const override;

    void    InitWindowBits( bool bButtons );
    void    set_selection_mode(SelectionMode eMode)
    {
        m_xTreeView->set_selection_mode(eMode);
    }

    void set_size_request(int nWidth, int nHeight)
    {
        m_xTreeView->set_size_request(nWidth, nHeight);
    }

    void    hide()
    {
        m_xTreeView->hide();
    }

    void    show()
    {
        m_xTreeView->show();
    }

    void    Refresh( ScContentId nType = ScContentId::ROOT );

diff --git a/sc/source/ui/inc/navipi.hxx b/sc/source/ui/inc/navipi.hxx
index 6db896f..4a6c3ea 100644
--- a/sc/source/ui/inc/navipi.hxx
+++ b/sc/source/ui/inc/navipi.hxx
@@ -21,15 +21,11 @@
#define INCLUDED_SC_SOURCE_UI_INC_NAVIPI_HXX

#include <vector>
#include <vcl/toolbox.hxx>
#include <vcl/field.hxx>
#include <vcl/lstbox.hxx>
#include <vcl/idle.hxx>
#include <svl/lstner.hxx>
#include <sfx2/childwin.hxx>
#include <svx/sidebar/PanelLayout.hxx>
#include "content.hxx"
#include <vcl/vclmedit.hxx>

class SfxPoolItem;
class ScTabViewShell;
@@ -48,20 +44,21 @@ enum NavListMode { NAV_LMODE_NONE       = 0x4000,
                   NAV_LMODE_AREAS      = 0x2000,
                   NAV_LMODE_SCENARIOS  = 0x400 };

class ScScenarioListBox : public ListBox
class ScScenarioWindow
{
public:
    explicit            ScScenarioListBox( ScScenarioWindow& rParent );
    virtual             ~ScScenarioListBox() override;

    void                UpdateEntries( const std::vector<OUString> &aNewEntryList );

protected:
    virtual void        Select() override;
    virtual void        DoubleClick() override;
    virtual bool        EventNotify( NotifyEvent& rNEvt ) override;
    ScScenarioWindow(weld::Builder& rBuilder, const OUString& rQH_List, const OUString& rQH_Comment);
    ~ScScenarioWindow();
    void NotifyState(const SfxPoolItem* pState);
    void SetComment(const OUString& rComment)
    {
        m_xEdComment->set_text(rComment);
    }

private:
    std::unique_ptr<weld::TreeView> m_xLbScenario;
    std::unique_ptr<weld::TextView> m_xEdComment;

    struct ScenarioEntry
    {
        OUString            maName;
@@ -72,102 +69,25 @@ private:
    };
    typedef ::std::vector< ScenarioEntry > ScenarioList;

private:
    ScenarioList m_aEntries;

    void UpdateEntries(const std::vector<OUString> &rNewEntryList);
    void SelectScenario();
    void ExecuteScenarioSlot(sal_uInt16 nSlotId);
    void EditScenario();
    void DeleteScenario();
    const ScenarioEntry* GetSelectedScenarioEntry() const;

    void                ExecuteScenarioSlot( sal_uInt16 nSlotId );
    void                SelectScenario();
    void                EditScenario();
    void                DeleteScenario();

private:
    ScScenarioWindow&   mrParent;
    ScenarioList        maEntries;
};

class ScScenarioWindow : public vcl::Window
{
public:
    ScScenarioWindow(vcl::Window* pParent, const OUString& rQH_List, const OUString& rQH_Comment);
    virtual ~ScScenarioWindow() override;
    virtual void dispose() override;
    void NotifyState(const SfxPoolItem* pState);
    void SetComment(const OUString& rComment)
    {
        aEdComment->SetText(rComment);
    }

protected:
    virtual void    Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
    virtual void    Resize() override;

private:
    VclPtr<ScScenarioListBox>   aLbScenario;
    VclPtr<VclMultiLineEdit>    aEdComment;
};

class ColumnEdit : public SpinField
{
public:
    ColumnEdit(Window* pParent, WinBits nWinBits);
    ~ColumnEdit() override;
    void SetNavigatorDlg(ScNavigatorDlg *pNaviDlg)
    {
        xDlg = pNaviDlg;
    }
    SCCOL   GetCol() const { return nCol; }
    void    SetCol( SCCOL nColNo );

protected:
    virtual bool    EventNotify( NotifyEvent& rNEvt ) override;
    virtual void    LoseFocus() override;
    virtual void    Up() override;
    virtual void    Down() override;
    virtual void    First() override;
    virtual void    Last() override;
    virtual void    dispose() override;

private:
    VclPtr<ScNavigatorDlg> xDlg;
    SCCOL           nCol;

    void EvalText();
    void ExecuteCol();
    static SCCOL AlphaToNum    ( const ScDocument& rDoc, OUString& rStr );
    static SCCOL NumStrToAlpha ( OUString& rStr );
    static SCCOL NumToAlpha    ( SCCOL nColNo, OUString& rStr );
};

class RowEdit : public NumericField
{
public:
    RowEdit(Window* pParent, WinBits nWinBits);
    ~RowEdit() override;
    void SetNavigatorDlg(ScNavigatorDlg *pNaviDlg)
    {
        xDlg = pNaviDlg;
    }
    SCROW   GetRow() const { return static_cast<SCROW>(GetValue()); }
    void    SetRow(SCROW nRow) { SetValue(nRow); }

protected:
    virtual bool    EventNotify( NotifyEvent& rNEvt ) override;
    virtual Size    GetOptimalSize() const override;
    virtual void    LoseFocus() override;
    virtual void    dispose() override;

private:
    VclPtr<ScNavigatorDlg> xDlg;

    void    ExecuteRow();
    DECL_LINK(SelectHdl, weld::TreeView&, void);
    DECL_LINK(DoubleClickHdl, weld::TreeView&, bool);
    DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
    DECL_LINK(ContextMenuHdl, const CommandEvent&, bool);
};

class ScNavigatorDlg : public PanelLayout, public SfxListener
{
friend class ScNavigatorControllerItem;
friend class ScNavigatorDialogWrapper;
friend class ColumnEdit;
friend class RowEdit;
friend class ScContentTree;

private:
@@ -175,32 +95,24 @@ private:

    SfxBindings&        rBindings;      // must be first member

    VclPtr<ColumnEdit> aEdCol;
    VclPtr<RowEdit> aEdRow;
    VclPtr<ToolBox> aTbxCmd;
    VclPtr<vcl::Window> aContentBox;
    VclPtr<ScContentTree> aLbEntries;
    VclPtr<vcl::Window> aScenarioBox;
    VclPtr<ScScenarioWindow> aWndScenarios;
    VclPtr<ListBox> aLbDocuments;
    std::unique_ptr<weld::SpinButton> m_xEdCol;
    std::unique_ptr<weld::SpinButton> m_xEdRow;
    std::unique_ptr<weld::Toolbar> m_xTbxCmd1;
    std::unique_ptr<weld::Toolbar> m_xTbxCmd2;
    std::unique_ptr<ScContentTree> m_xLbEntries;
    std::unique_ptr<weld::Widget> m_xScenarioBox;
    std::unique_ptr<ScScenarioWindow> m_xWndScenarios;
    std::unique_ptr<weld::ComboBox> m_xLbDocuments;
    std::unique_ptr<weld::Menu> m_xDragModeMenu;

    Size            aExpandedSize;
    Idle            aContentIdle;

    OUString const  aStrDragMode;
    OUString const  aStrDisplay;
    OUString        aStrActive;
    OUString        aStrNotActive;
    OUString        aStrHidden;
    OUString const  aStrActiveWin;

    sal_uInt16      nZoomId;
    sal_uInt16      nChangeRootId;
    sal_uInt16      nDragModeId;
    sal_uInt16      nScenarioId;
    sal_uInt16      nDownId;
    sal_uInt16      nUpId;
    sal_uInt16      nDataId;
    std::unique_ptr<ScArea> pMarkArea;
    ScViewData*     pViewData;

@@ -213,9 +125,14 @@ private:
    std::array<std::unique_ptr<ScNavigatorControllerItem>,CTRL_ITEMS> mvBoundItems;

    DECL_LINK(TimeHdl, Timer*, void);
    DECL_LINK(DocumentSelectHdl, ListBox&, void);
    DECL_LINK(ToolBoxSelectHdl, ToolBox*, void);
    DECL_LINK(ToolBoxDropdownClickHdl, ToolBox*, void);
    DECL_LINK(DocumentSelectHdl, weld::ComboBox&, void);
    DECL_LINK(ExecuteRowHdl, weld::Entry&, bool);
    DECL_LINK(ExecuteColHdl, weld::Entry&, bool);
    DECL_LINK(ToolBoxSelectHdl, const OString&, void);
    DECL_LINK(ToolBoxDropdownClickHdl, const OString&, void);
    DECL_LINK(MenuSelectHdl, const OString&, void);
    DECL_LINK(FormatRowOutputHdl, weld::SpinButton&, void);
    DECL_LINK(ParseRowInputHdl, int*, bool);

    void    UpdateButtons();
    void    SetCurrentCell( SCCOL nCol, SCROW Row );
@@ -245,9 +162,6 @@ private:
    void    SetDropMode(sal_uInt16 nNew);
    sal_uInt16  GetDropMode() const         { return nDropMode; }

    const OUString& GetStrDragMode() const    { return aStrDragMode; }
    const OUString& GetStrDisplay() const     { return aStrDisplay; }

    void    MarkDataArea    ();
    void    UnmarkDataArea  ();
    void    StartOfDataArea ();
diff --git a/sc/source/ui/navipi/content.cxx b/sc/source/ui/navipi/content.cxx
index 1fbeddf..ff6fa69 100644
--- a/sc/source/ui/navipi/content.cxx
+++ b/sc/source/ui/navipi/content.cxx
@@ -27,7 +27,6 @@
#include <vcl/help.hxx>
#include <vcl/svapp.hxx>
#include <tools/urlobj.hxx>
#include <vcl/treelistentry.hxx>
#include <sal/log.hxx>
#include <unotools/charclass.hxx>

@@ -117,106 +116,44 @@ ScDocShell* ScContentTree::GetManualOrCurrent()

//          ScContentTree

ScContentTree::ScContentTree(vcl::Window* pParent, ScNavigatorDlg* pNavigatorDlg)
    : SvTreeListBox(pParent, WB_BORDER | WB_TABSTOP)
ScContentTree::ScContentTree(std::unique_ptr<weld::TreeView> xTreeView, ScNavigatorDlg* pNavigatorDlg)
    : m_xTreeView(std::move(xTreeView))
    , m_xScratchIter(m_xTreeView->make_iterator())
    , m_xTransferObj(new ScLinkTransferObj)
    , pParentWindow(pNavigatorDlg)
    , nRootType(ScContentId::ROOT)
    , bHiddenDoc(false)
    , pHiddenDocument(nullptr)
    , bisInNavigatoeDlg(false)
    , m_bFreeze(false)
    , m_nAsyncMouseReleaseId(nullptr)
{
    SetQuickSearch(true);
    for (sal_uInt16 i = 0; i <= int(ScContentId::LAST); ++i)
        pPosList[pTypeList[i]] = i;         // inverse for searching

    pRootNodes[ScContentId::ROOT] = nullptr;
    m_aRootNodes[ScContentId::ROOT] = nullptr;
    for (sal_uInt16 i = 1; i < int(ScContentId::LAST); ++i)
        InitRoot(static_cast<ScContentId>(i));

    SetNodeDefaultImages();
    m_xTreeView->connect_row_activated(LINK(this, ScContentTree, ContentDoubleClickHdl));
    m_xTreeView->connect_mouse_release(LINK(this, ScContentTree, MouseReleaseHdl));
    m_xTreeView->connect_key_press(LINK(this, ScContentTree, KeyInputHdl));
    m_xTreeView->connect_popup_menu(LINK(this, ScContentTree, CommandHdl));

    SetDoubleClickHdl( LINK( this, ScContentTree, ContentDoubleClickHdl ) );
}
    rtl::Reference<TransferDataContainer> xHelper(m_xTransferObj.get());
    m_xTreeView->enable_drag_source(xHelper, DND_ACTION_COPYMOVE | DND_ACTION_LINK);

Size ScContentTree::GetOptimalSize() const
{
    return LogicToPixel(Size(110, 100), MapMode(MapUnit::MapAppFont));
    m_xTreeView->connect_drag_begin(LINK(this, ScContentTree, DragBeginHdl));
}

ScContentTree::~ScContentTree()
{
    disposeOnce();
}

void ScContentTree::dispose()
{
    pParentWindow.clear();
    SvTreeListBox::dispose();
}

// helper function for  GetEntryAltText and GetEntryLongDescription
OUString ScContentTree::getAltLongDescText( SvTreeListEntry* pEntry, bool isAltText) const
{

    ScContentId nType;
    sal_uLong nChild;
    GetEntryIndexes( nType, nChild, pEntry );
    switch( nType )
    if (m_nAsyncMouseReleaseId)
    {
    case ScContentId::OLEOBJECT:
    case ScContentId::GRAPHIC:
    case ScContentId::DRAWING:
        {
            SdrObject* pFound = nullptr;
            ScDocument* pDoc =  const_cast< ScContentTree* >(this)->GetSourceDocument();
            SdrIterMode eIter = ( nType == ScContentId::DRAWING ) ? SdrIterMode::Flat : SdrIterMode::DeepNoGroups;
            ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
            SfxObjectShell* pShell = pDoc->GetDocumentShell();
            if (pDrawLayer && pShell)
            {
                sal_uInt16 nTabCount = pDoc->GetTableCount();
                for (sal_uInt16 nTab=0; nTab<nTabCount; nTab++)
                {
                    SdrPage* pPage = pDrawLayer->GetPage(nTab);
                    DBG_ASSERT(pPage,"Page ?");
                    if (pPage)
                    {
                        SdrObjListIter aIter( pPage, eIter );
                        SdrObject* pObject = aIter.Next();
                        while (pObject)
                        {
                            if( ScDrawLayer::GetVisibleName( pObject ) == GetEntryText( pEntry ) )
                            {
                                pFound = pObject;
                                break;
                            }
                            pObject = aIter.Next();
                        }
                    }
                }
            }
            if( pFound )
            {
                if( isAltText )
                    return pFound->GetTitle();
                else
                    return pFound->GetDescription();
            }
        }
        break;
        default: break;
        Application::RemoveUserEvent(m_nAsyncMouseReleaseId);
        m_nAsyncMouseReleaseId = nullptr;
    }
    return OUString();
}

OUString  ScContentTree::GetEntryAltText( SvTreeListEntry* pEntry ) const
{
    return getAltLongDescText( pEntry, true );
}

OUString ScContentTree::GetEntryLongDescription( SvTreeListEntry* pEntry ) const
{
    return getAltLongDescText( pEntry, false );
    pParentWindow.clear();
}

static const char* SCSTR_CONTENT_ARY[] =
@@ -239,30 +176,31 @@ void ScContentTree::InitRoot( ScContentId nType )

    if ( nRootType != ScContentId::ROOT && nRootType != nType )              // hidden ?
    {
        pRootNodes[nType] = nullptr;
        m_aRootNodes[nType] = nullptr;
        return;
    }

    Image aImage(StockImage::Yes, aContentBmps[static_cast<int>(nType) - 1]);
    OUString aImage(aContentBmps[static_cast<int>(nType) - 1]);
    OUString aName(ScResId(SCSTR_CONTENT_ARY[static_cast<int>(nType)]));
    // back to the correct position:
    sal_uInt16 nPos = nRootType != ScContentId::ROOT ? 0 : pPosList[nType]-1;
    SvTreeListEntry* pNew = InsertEntry( aName, aImage, aImage, nullptr, false, nPos );

    pRootNodes[nType] = pNew;
    m_aRootNodes[nType] = m_xTreeView->make_iterator();
    m_xTreeView->insert(nullptr, nPos, &aName, nullptr, nullptr, nullptr, &aImage, false, m_aRootNodes[nType].get());
}

void ScContentTree::ClearAll()
{
    //There are one method in Control::SetUpdateMode(), and one override method SvTreeListBox::SetUpdateMode(). Here although
    //SvTreeListBox::SetUpdateMode() is called in refresh method, it only call SvTreeListBox::SetUpdateMode(), not Control::SetUpdateMode().
    //In SvTreeList::Clear(), Broadcast( LISTACTION_CLEARED ) will be called and finally, it will be trapped into the event yield() loop. And
    //In m_xTreeView->clear(), Broadcast( LISTACTION_CLEARED ) will be called and finally, it will be trapped into the event yield() loop. And
    //the InitRoot() method won't be called. Then if a user click or press key to update the navigator tree, crash happens.
    //So the solution is to disable the UpdateMode of Control, then call Clear(), then recover the update mode
    bool bOldUpdate = Control::IsUpdateMode();
    Control::SetUpdateMode(false);
    Clear();
    Control::SetUpdateMode(bOldUpdate);
    bool bWasFrozen = m_bFreeze;
    if (!bWasFrozen)
        freeze();
    m_xTreeView->clear();
    if (!bWasFrozen)
        thaw();
    for (sal_uInt16 i=1; i<=int(ScContentId::LAST); i++)
        InitRoot(static_cast<ScContentId>(i));
}
@@ -273,11 +211,11 @@ void ScContentTree::ClearType(ScContentId nType)
        ClearAll();
    else
    {
        SvTreeListEntry* pParent = pRootNodes[nType];
        if ( !pParent || GetChildCount(pParent) )       // not if no children existing
        weld::TreeIter* pParent = m_aRootNodes[nType].get();
        if (!pParent || m_xTreeView->iter_has_child(*pParent)) // not if no children existing
        {
            if (pParent)
                GetModel()->Remove( pParent );          // with all children
                m_xTreeView->remove(*pParent);          // with all children
            InitRoot( nType );                          // if needed insert anew
        }
    }
@@ -285,16 +223,19 @@ void ScContentTree::ClearType(ScContentId nType)

void ScContentTree::InsertContent( ScContentId nType, const OUString& rValue )
{
    SvTreeListEntry* pParent = pRootNodes[nType];
    weld::TreeIter* pParent = m_aRootNodes[nType].get();
    if (pParent)
        InsertEntry( rValue, pParent );
    {
        m_xTreeView->insert(pParent, -1, &rValue, nullptr, nullptr, nullptr, nullptr, false, m_xScratchIter.get());
        m_xTreeView->set_sensitive(*m_xScratchIter, true);
    }
    else
    {
        OSL_FAIL("InsertContent without parent");
    }
}

void ScContentTree::GetEntryIndexes( ScContentId& rnRootIndex, sal_uLong& rnChildIndex, SvTreeListEntry* pEntry ) const
void ScContentTree::GetEntryIndexes(ScContentId& rnRootIndex, sal_uLong& rnChildIndex, weld::TreeIter* pEntry) const
{
    rnRootIndex = ScContentId::ROOT;
    rnChildIndex = SC_CONTENT_NOCHILD;
@@ -302,32 +243,37 @@ void ScContentTree::GetEntryIndexes( ScContentId& rnRootIndex, sal_uLong& rnChil
    if( !pEntry )
        return;

    SvTreeListEntry* pParent = GetParent( pEntry );
    std::unique_ptr<weld::TreeIter> xParent(m_xTreeView->make_iterator(pEntry));
    if (!m_xTreeView->iter_parent(*xParent))
        xParent.reset();
    bool bFound = false;
    for( int i = 1; !bFound && (i <= int(ScContentId::LAST)); ++i )
    {
        ScContentId nRoot = static_cast<ScContentId>(i);
        if( pEntry == pRootNodes[ nRoot ] )
        if (!m_aRootNodes[nRoot])
            continue;
        if (m_xTreeView->iter_compare(*pEntry, *m_aRootNodes[nRoot]) == 0)
        {
            rnRootIndex = nRoot;
            rnChildIndex = ~0UL;
            bFound = true;
        }
        else if( pParent && (pParent == pRootNodes[ nRoot ]) )
        else if (xParent && m_xTreeView->iter_compare(*xParent, *m_aRootNodes[nRoot]) == 0)
        {
            rnRootIndex = nRoot;

            // search the entry in all child entries of the parent
            sal_uLong nEntry = 0;
            SvTreeListEntry* pIterEntry = FirstChild( pParent );
            while( !bFound && pIterEntry )
            std::unique_ptr<weld::TreeIter> xIterEntry(m_xTreeView->make_iterator(xParent.get()));
            bool bIterEntry = m_xTreeView->iter_children(*xIterEntry);
            while (!bFound && bIterEntry)
            {
                if ( pEntry == pIterEntry )
                if (m_xTreeView->iter_compare(*pEntry, *xIterEntry) == 0)
                {
                    rnChildIndex = nEntry;
                    bFound = true;  // exit the while loop
                }
                pIterEntry = pIterEntry->NextSibling();
                bIterEntry = m_xTreeView->iter_next_sibling(*xIterEntry);
                ++nEntry;
            }

@@ -336,7 +282,7 @@ void ScContentTree::GetEntryIndexes( ScContentId& rnRootIndex, sal_uLong& rnChil
    }
}

sal_uLong ScContentTree::GetChildIndex( SvTreeListEntry* pEntry ) const
sal_uLong ScContentTree::GetChildIndex(weld::TreeIter* pEntry) const
{
    ScContentId nRoot;
    sal_uLong nChild;
@@ -361,19 +307,21 @@ static OUString lcl_GetDBAreaRange( const ScDocument* pDoc, const OUString& rDBN
    return aRet;
}

IMPL_LINK_NOARG(ScContentTree, ContentDoubleClickHdl, SvTreeListBox*, bool)
IMPL_LINK_NOARG(ScContentTree, ContentDoubleClickHdl, weld::TreeView&, bool)
{
    ScContentId nType;
    sal_uLong nChild;
    SvTreeListEntry* pEntry = GetCurEntry();
    GetEntryIndexes( nType, nChild, pEntry );
    std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
    if (!m_xTreeView->get_cursor(xEntry.get()))
        xEntry.reset();
    GetEntryIndexes(nType, nChild, xEntry.get());

    if( pEntry && (nType != ScContentId::ROOT) && (nChild != SC_CONTENT_NOCHILD) )
    if (xEntry && (nType != ScContentId::ROOT) && (nChild != SC_CONTENT_NOCHILD))
    {
        if ( bHiddenDoc )
            return false;               //! later...

        OUString aText( GetEntryText( pEntry ) );
        OUString aText(m_xTreeView->get_text(*xEntry));

        if ( !aManualDoc.isEmpty() )
            pParentWindow->SetCurrentDoc( aManualDoc );
@@ -432,16 +380,28 @@ IMPL_LINK_NOARG(ScContentTree, ContentDoubleClickHdl, SvTreeListBox*, bool)
        ScNavigatorDlg::ReleaseFocus();     // set focus into document
    }

    return true;
    return false;
}

void ScContentTree::MouseButtonDown( const MouseEvent& rMEvt )
void ScContentTree::LaunchAsyncStoreNavigatorSettings()
{
    SvTreeListBox::MouseButtonDown( rMEvt );
    if (!m_nAsyncMouseReleaseId)
        m_nAsyncMouseReleaseId = Application::PostUserEvent(LINK(this, ScContentTree, AsyncStoreNavigatorSettings));
}

IMPL_LINK_NOARG(ScContentTree, MouseReleaseHdl, const MouseEvent&, bool)
{
    LaunchAsyncStoreNavigatorSettings();
    return false;
}

IMPL_LINK_NOARG(ScContentTree, AsyncStoreNavigatorSettings, void*, void)
{
    m_nAsyncMouseReleaseId = nullptr;
    StoreNavigatorSettings();
}

void ScContentTree::KeyInput( const KeyEvent& rKEvt )
IMPL_LINK(ScContentTree, KeyInputHdl, const KeyEvent&, rKEvt, bool)
{
    bool bUsed = false;

@@ -456,22 +416,24 @@ void ScContentTree::KeyInput( const KeyEvent& rKEvt )
                break;
            case 0:
            {
                SvTreeListEntry* pEntry = GetCurEntry();
                if( pEntry )
                std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
                if (!m_xTreeView->get_cursor(xEntry.get()))
                    xEntry.reset();
                if (xEntry)
                {
                    ScContentId nType;
                    sal_uLong nChild;
                    GetEntryIndexes( nType, nChild, pEntry );
                    GetEntryIndexes(nType, nChild, xEntry.get());

                    if( (nType != ScContentId::ROOT) && (nChild == SC_CONTENT_NOCHILD) )
                    if (nType != ScContentId::ROOT && nChild == SC_CONTENT_NOCHILD)
                    {
                        if ( IsExpanded( pEntry ) )
                            Collapse( pEntry );
                        if (m_xTreeView->get_row_expanded(*xEntry))
                            m_xTreeView->collapse_row(*xEntry);
                        else
                            Expand( pEntry );
                            m_xTreeView->expand_row(*xEntry);
                    }
                    else
                        ContentDoubleClickHdl(nullptr);      // select content as if double clicked
                        ContentDoubleClickHdl(*m_xTreeView);      // select content as if double clicked
                }

                bUsed = true;
@@ -487,141 +449,104 @@ void ScContentTree::KeyInput( const KeyEvent& rKEvt )
            bUsed = true;
            ScContentId nType;
            sal_uLong nChild;
            SvTreeListEntry* pEntry = GetCurEntry();
            GetEntryIndexes( nType, nChild, pEntry );
            if( pEntry && (nType != ScContentId::ROOT) && (nChild != SC_CONTENT_NOCHILD) )
            std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
            if (!m_xTreeView->get_cursor(xEntry.get()))
                xEntry.reset();
            GetEntryIndexes(nType, nChild, xEntry.get());

            if (xEntry && (nType != ScContentId::ROOT) && (nChild != SC_CONTENT_NOCHILD))
            {
                if ( bHiddenDoc )
                    return ;                //! later...
                OUString aText( GetEntryText( pEntry ) );
                    return true;                //! later...
                OUString aText(m_xTreeView->get_text(*xEntry));
                sKeyString = aText;
                if (!aManualDoc.isEmpty())
                    pParentWindow->SetCurrentDoc( aManualDoc );
                switch( nType )
                switch (nType)
                {
                    case ScContentId::OLEOBJECT:
                    case ScContentId::GRAPHIC:
                    case ScContentId::DRAWING:
                    {
                        vcl::Window* pWindow=reinterpret_cast<vcl::Window*>(GetParent(pEntry));
                        ScNavigatorDlg* pScNavigatorDlg = static_cast<ScNavigatorDlg*>(pWindow);
                        ScTabViewShell* pScTabViewShell = nullptr;
                        ScDrawView* pScDrawView = nullptr;
                        if (pScNavigatorDlg!=nullptr)
                              pScTabViewShell = ScNavigatorDlg::GetTabViewShell();
                        if(pScTabViewShell !=nullptr)
                              pScDrawView =pScTabViewShell->GetViewData().GetScDrawView();
                        if(pScDrawView!=nullptr)
                         {
                            pScDrawView->SelectCurrentViewObject(aText );
                        ScTabViewShell* pScTabViewShell = ScNavigatorDlg::GetTabViewShell();
                        if (pScTabViewShell)
                            pScDrawView = pScTabViewShell->GetViewData().GetScDrawView();
                        if (pScDrawView)
                        {
                            pScDrawView->SelectCurrentViewObject(aText);
                            bool bHasMakredObject = false;
                            SvTreeListEntry* pParent = pRootNodes[nType];
                            SvTreeListEntry* pBeginEntry = nullptr;
                            if( pParent )
                                pBeginEntry = FirstChild(pParent);
                            while( pBeginEntry )
                            weld::TreeIter* pParent = m_aRootNodes[nType].get();
                            std::unique_ptr<weld::TreeIter> xBeginEntry(m_xTreeView->make_iterator(pParent));
                            bool bBeginEntry = false;
                            if (pParent)
                                bBeginEntry = m_xTreeView->iter_children(*xBeginEntry);
                            while (bBeginEntry)
                            {
                                OUString aTempText( GetEntryText( pBeginEntry ) );
                                OUString aTempText(m_xTreeView->get_text(*xBeginEntry));
                                if( pScDrawView->GetObjectIsMarked( pScDrawView->GetObjectByName( aTempText ) ) )
                                {
                                    bHasMakredObject = true;
                                    break;
                                }
                                pBeginEntry =  Next( pBeginEntry );
                                bBeginEntry = m_xTreeView->iter_next(*xBeginEntry);
                            }
                            if(  !bHasMakredObject && pScTabViewShell)
                            if (!bHasMakredObject && pScTabViewShell)
                                pScTabViewShell->SetDrawShell(false);
                            ObjectFresh( nType,pEntry );
                            ObjectFresh(nType, xEntry.get());
                        }
                        break;
                    }
                    break;
                    default: break;
                 }
                    default:
                        break;
                }
            }
           }
       }

    if( !bUsed )
    {
        if(aCode.GetCode() == KEY_F5 )
        {
            StoreNavigatorSettings();
            SvTreeListBox::KeyInput(rKEvt);
        }
        else
        {
            SvTreeListBox::KeyInput(rKEvt);
            StoreNavigatorSettings();
        }
    }

    if (!bUsed)
    {
        if (aCode.GetCode() == KEY_F5)
            StoreNavigatorSettings();
        else
            LaunchAsyncStoreNavigatorSettings();
    }

    return bUsed;
}

sal_Int8 ScContentTree::AcceptDrop( const AcceptDropEvent& /* rEvt */ )
{
    return DND_ACTION_NONE;
}

sal_Int8 ScContentTree::ExecuteDrop( const ExecuteDropEvent& /* rEvt */ )
{
    return DND_ACTION_NONE;
}

void ScContentTree::StartDrag( sal_Int8 /* nAction */, const Point& /* rPosPixel */ )
{
    DoDrag();
}

void ScContentTree::DragFinished( sal_Int8 /* nAction */ )
{
}

void ScContentTree::Command( const CommandEvent& rCEvt )
IMPL_LINK(ScContentTree, CommandHdl, const CommandEvent&, rCEvt, bool)
{
    bool bDone = false;

    switch ( rCEvt.GetCommand() )
    {
        case CommandEventId::StartDrag:
            //  From within ExecuteDrag you can delete the navigator
            //  (during switch over to another document type), but this would
            //  kill the StarView MouseMove handler, who calls Command().
            //  Therefore async Drag&Drop:

            Application::PostUserEvent( LINK( this, ScContentTree, ExecDragHdl ), nullptr, true );

            bDone = true;
            break;

        case CommandEventId::ContextMenu:
            {
                //  drag-and-drop mode

                ScopedVclPtrInstance<PopupMenu> aPop;
                VclBuilder aBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "modules/scalc/ui/dropmenu.ui", "");
                VclPtr<PopupMenu> aDropMenu(aBuilder.get_menu("menu"));
                std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xTreeView.get(), "modules/scalc/ui/dropmenu.ui"));
                std::unique_ptr<weld::Menu> xPop(xBuilder->weld_menu("contextmenu"));
                std::unique_ptr<weld::Menu> xDropMenu(xBuilder->weld_menu("dragmodesubmenu"));

                switch (pParentWindow->GetDropMode())
                {
                    case 0:
                        aDropMenu->CheckItem("hyperlink");
                        xDropMenu->set_active("hyperlink", true);
                        break;
                    case 1:
                        aDropMenu->CheckItem("link");
                        xDropMenu->set_active("link", true);
                        break;
                    case 2:
                        aDropMenu->CheckItem("copy");
                        xDropMenu->set_active("copy", true);
                        break;
                }

                aPop->InsertItem( 1, pParentWindow->GetStrDragMode() );
                aPop->SetPopupMenu( 1, aDropMenu.get() );

                //  displayed document

                VclPtrInstance<PopupMenu> aDocMenu;
                aDocMenu->SetMenuFlags( aDocMenu->GetMenuFlags() | MenuFlags::NoAutoMnemonics );
                std::unique_ptr<weld::Menu> xDocMenu(xBuilder->weld_menu("displaymenu"));
//TODO                aDocMenu->SetMenuFlags( aDocMenu->GetMenuFlags() | MenuFlags::NoAutoMnemonics );
                sal_uInt16 i=0;
                sal_uInt16 nPos=0;
                OUString sActive;
                OUString sId;
                //  loaded documents
                ScDocShell* pCurrentSh = dynamic_cast<ScDocShell*>( SfxObjectShell::Current()  );
                SfxObjectShell* pSh = SfxObjectShell::GetFirst();
@@ -636,110 +561,49 @@ void ScContentTree::Command( const CommandEvent& rCEvt )
                        else
                            aEntry += pParentWindow->aStrNotActive;
                        ++i;
                        aDocMenu->InsertItem(i, aEntry, MenuItemBits::AUTOCHECK | MenuItemBits::RADIOCHECK, "document" + OString::number(i));
                        sId = "document" + OUString::number(i);
                        xDocMenu->append_radio(sId, aEntry);
                        if ( !bHiddenDoc && aName == aManualDoc )
                            nPos = i;
                            sActive = sId;
                    }
                    pSh = SfxObjectShell::GetNext( *pSh );
                }
                //  "active window"
                ++i;
                aDocMenu->InsertItem(i, pParentWindow->aStrActiveWin, MenuItemBits::AUTOCHECK | MenuItemBits::RADIOCHECK, "document" + OString::number(i));
                sId = "document" + OUString::number(i);
                xDocMenu->append_radio(sId, pParentWindow->aStrActiveWin);
                if (!bHiddenDoc && aManualDoc.isEmpty())
                    nPos = i;
                    sActive = sId;
                //  hidden document
                if ( !aHiddenTitle.isEmpty() )
                {
                    OUString aEntry = aHiddenTitle + pParentWindow->aStrHidden;
                    ++i;
                    aDocMenu->InsertItem(i, aEntry, MenuItemBits::AUTOCHECK | MenuItemBits::RADIOCHECK, "document" + OString::number(i));
                    sId = "document" + OUString::number(i);
                    xDocMenu->append_radio(sId, aEntry);
                    if (bHiddenDoc)
                        nPos = i;
                        sActive = sId;
                }
                aDocMenu->CheckItem( nPos );
                aPop->InsertItem( 2, pParentWindow->GetStrDisplay() );
                aPop->SetPopupMenu( 2, aDocMenu.get() );
                xDocMenu->set_active(sActive.toUtf8(), true);

                aPop->Execute(this, rCEvt.GetMousePosPixel());
                OString sIdent = aPop->GetCurItemIdent();

                if (sIdent.startsWith("document"))
                {
                    OUString aName = aDocMenu->GetItemText(aDocMenu->GetItemId(sIdent));
                    SelectDoc(aName);
                }
                else if (sIdent == "hyperlink")
                OString sIdent = xPop->popup_at_rect(m_xTreeView.get(), tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1, 1)));
                if (sIdent == "hyperlink")
                    pParentWindow->SetDropMode(0);
                else if (sIdent == "link")
                    pParentWindow->SetDropMode(1);
                else if (sIdent == "copy")
                    pParentWindow->SetDropMode(2);
                else if (sIdent.startsWith("document"))
                {
                    OUString aName = xDocMenu->get_label(sIdent);
                    SelectDoc(aName);
                }
            }
            break;
            default: break;
    }

    if (!bDone)
        SvTreeListBox::Command(rCEvt);
}

void ScContentTree::RequestHelp( const HelpEvent& rHEvt )
{
    bool bDone = false;
    if( rHEvt.GetMode() & HelpEventMode::QUICK )
    {
        Point aPos( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ));
        SvTreeListEntry* pEntry = GetEntry( aPos );
        if ( pEntry )
        {
            bool bRet = false;
            OUString aHelpText;
            SvTreeListEntry* pParent = GetParent(pEntry);
            if ( !pParent )                                 // Top-Level ?
            {
                aHelpText = OUString::number( GetChildCount(pEntry) ) +
                            " " + GetEntryText(pEntry);
                bRet = true;
            }
            else if ( pParent == pRootNodes[ScContentId::NOTE] )
            {
                aHelpText = GetEntryText(pEntry);           // notes as help text
                bRet = true;
            }
            else if ( pParent == pRootNodes[ScContentId::AREALINK] )
            {
                sal_uLong nIndex = GetChildIndex(pEntry);
                if( nIndex != SC_CONTENT_NOCHILD )
                {
                    const ScAreaLink* pLink = GetLink(nIndex);
                    if (pLink)
                    {
                        aHelpText = pLink->GetFile();           // source file as help text
                        bRet = true;
                    }
                }
            }

            if (bRet)
            {
                SvLBoxTab* pTab;
                SvLBoxItem* pItem = GetItem( pEntry, aPos.X(), &pTab );
                if( pItem )
                {
                    aPos = GetEntryPosition( pEntry );
                    aPos.setX( GetTabPos( pEntry, pTab ) );
                    aPos = OutputToScreenPixel(aPos);
                    Size aSize(pItem->GetWidth(this, pEntry), pItem->GetHeight(this, pEntry));

                    tools::Rectangle aItemRect( aPos, aSize );
                    Help::ShowQuickHelp( this, aItemRect, aHelpText );
                    bDone = true;
                }
            }
        }
    }
    if (!bDone)
        Window::RequestHelp( rHEvt );
    return bDone;
}

ScDocument* ScContentTree::GetSourceDocument()
@@ -757,39 +621,42 @@ ScDocument* ScContentTree::GetSourceDocument()
}

//Move along and draw "*" sign .
void ScContentTree::ObjectFresh( ScContentId nType, const SvTreeListEntry* pEntry )
void ScContentTree::ObjectFresh(ScContentId nType, const weld::TreeIter* pEntry)
{
    if ( bHiddenDoc && !pHiddenDocument )
    if (bHiddenDoc && !pHiddenDocument)
        return;     // other document displayed
    if(nType ==ScContentId::GRAPHIC||nType ==ScContentId::OLEOBJECT||nType ==ScContentId::DRAWING)
    if (nType == ScContentId::GRAPHIC || nType == ScContentId::OLEOBJECT || nType == ScContentId::DRAWING)
    {
        SetUpdateMode(false);
        freeze();
        ClearType( nType );
        GetDrawNames( nType/*, nId*/ );
        if( !pEntry )
        thaw();
        if (!pEntry)
            ApplyNavigatorSettings();
        SetUpdateMode(true);
        if( pEntry )
        if (pEntry)
        {
            SvTreeListEntry* pParent = pRootNodes[nType];
            SvTreeListEntry* pBeginEntry = nullptr;
            SvTreeListEntry* pOldEntry = nullptr;
            weld::TreeIter* pParent = m_aRootNodes[nType].get();
            std::unique_ptr<weld::TreeIter> xOldEntry;
            std::unique_ptr<weld::TreeIter> xBeginEntry(m_xTreeView->make_iterator(pParent));
            bool bBeginEntry = false;
            if( pParent )
                pBeginEntry = FirstChild(pParent);
            while( pBeginEntry )
                bBeginEntry = m_xTreeView->iter_children(*xBeginEntry);
            while (bBeginEntry)
            {
                OUString aTempText( GetEntryText( pBeginEntry ) );
                if( aTempText ==  sKeyString )
                OUString aTempText(m_xTreeView->get_text(*xBeginEntry));
                if (aTempText == sKeyString)
                {
                    pOldEntry = pBeginEntry;
                    xOldEntry = m_xTreeView->make_iterator(xBeginEntry.get());
                    break;
                }
                pBeginEntry =  Next( pBeginEntry );
                bBeginEntry = m_xTreeView->iter_next(*xBeginEntry);
            }
            if( pOldEntry )
            if (xOldEntry)
            {
                Expand(pParent);
                Select( pOldEntry );
                m_xTreeView->expand_row(*pParent);
                m_xTreeView->select(*xOldEntry);
                m_xTreeView->set_cursor(*xOldEntry);
                StoreNavigatorSettings();
            }
        }
    }
@@ -815,7 +682,7 @@ void ScContentTree::Refresh( ScContentId nType )
        if (!DrawNamesChanged(ScContentId::DRAWING))
            return;

    SetUpdateMode(false);
    freeze();

    ClearType( nType );

@@ -836,8 +703,9 @@ void ScContentTree::Refresh( ScContentId nType )
    if ( nType == ScContentId::ROOT || nType == ScContentId::AREALINK )
        GetLinkNames();

    thaw();

    ApplyNavigatorSettings();
    SetUpdateMode(true);
}

void ScContentTree::GetTableNames()
@@ -976,10 +844,11 @@ void ScContentTree::GetDrawNames( ScContentId nType )
                        {
                            if( bisInNavigatoeDlg )
                            {
                                SvTreeListEntry* pParent = pRootNodes[nType];
                                weld::TreeIter* pParent = m_aRootNodes[nType].get();
                                if (pParent)
                                {
                                    InsertEntry( aName, pParent );
                                    m_xTreeView->insert(pParent, -1, &aName, nullptr, nullptr, nullptr, nullptr, false, m_xScratchIter.get());
                                    m_xTreeView->set_sensitive(*m_xScratchIter, true);
                                }//end if parent
                                else
                                    SAL_WARN("sc", "InsertContent without parent");
@@ -1099,27 +968,28 @@ bool ScContentTree::NoteStringsChanged()
    if (!pDoc)
        return false;

    SvTreeListEntry* pParent = pRootNodes[ScContentId::NOTE];
    weld::TreeIter* pParent = m_aRootNodes[ScContentId::NOTE].get();
    if (!pParent)
        return false;

    SvTreeListEntry* pEntry = FirstChild( pParent );
    std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator(pParent));
    bool bEntry = m_xTreeView->iter_children(*xEntry);

    std::vector<sc::NoteEntry> aEntries;
    pDoc->GetAllNoteEntries(aEntries);
    for (const auto& rEntry : aEntries)
    {
        const ScPostIt* pNote = rEntry.mpNote;
        if (!pEntry)
        if (!bEntry)
            return true;

        if (lcl_NoteString(*pNote) != GetEntryText(pEntry))
        if (lcl_NoteString(*pNote) != m_xTreeView->get_text(*xEntry))
            return true;

        pEntry = pEntry->NextSibling();
        bEntry = m_xTreeView->iter_next_sibling(*xEntry);
    }

    return pEntry != nullptr;
    return bEntry;
}

bool ScContentTree::DrawNamesChanged( ScContentId nType )
@@ -1128,11 +998,12 @@ bool ScContentTree::DrawNamesChanged( ScContentId nType )
    if (!pDoc)
        return false;

    SvTreeListEntry* pParent = pRootNodes[nType];
    weld::TreeIter* pParent = m_aRootNodes[nType].get();
    if (!pParent)
        return false;

    SvTreeListEntry* pEntry = FirstChild( pParent );
    std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator(pParent));
    bool bEntry = m_xTreeView->iter_children(*xEntry);

    // iterate in flat mode for groups
    SdrIterMode eIter = ( nType == ScContentId::DRAWING ) ? SdrIterMode::Flat : SdrIterMode::DeepNoGroups;
@@ -1155,14 +1026,14 @@ bool ScContentTree::DrawNamesChanged( ScContentId nType )
                {
                    if ( IsPartOfType( nType, pObject->GetObjIdentifier() ) )
                    {
                        if ( !pEntry )
                        if ( !bEntry )
                            bEqual = false;
                        else
                        {
                            if ( ScDrawLayer::GetVisibleName( pObject ) != GetEntryText(pEntry) )
                            if (ScDrawLayer::GetVisibleName(pObject) != m_xTreeView->get_text(*xEntry))
                                bEqual = false;

                            pEntry = pEntry->NextSibling();
                            bEntry = m_xTreeView->iter_next_sibling(*xEntry);
                        }
                    }
                    pObject = aIter.Next();
@@ -1171,7 +1042,7 @@ bool ScContentTree::DrawNamesChanged( ScContentId nType )
        }
    }

    if ( pEntry )
    if ( bEntry )
        bEqual = false;             // anything else

    return !bEqual;
@@ -1212,8 +1083,10 @@ static bool lcl_GetRange( const ScDocument* pDoc, ScContentId nType, const OUStr
    return bFound;
}

static void lcl_DoDragObject( ScDocShell* pSrcShell, const OUString& rName, ScContentId nType, vcl::Window* pWin )
static bool lcl_DoDragObject( ScDocShell* pSrcShell, const OUString& rName, ScContentId nType, vcl::Window* pWin )
{
    bool bDisallow = true;

    ScDocument& rSrcDoc = pSrcShell->GetDocument();
    ScDrawLayer* pModel = rSrcDoc.GetDrawLayer();
    if (pModel)
@@ -1243,14 +1116,19 @@ static void lcl_DoDragObject( ScDocShell* pSrcShell, const OUString& rName, ScCo
            pTransferObj->SetDragSourceFlags(ScDragSrc::Navigator);

            SC_MOD()->SetDragObject( nullptr, pTransferObj.get() );
            pWin->ReleaseMouse();
            pTransferObj->StartDrag( pWin, DND_ACTION_COPYMOVE | DND_ACTION_LINK );

            bDisallow = false;
        }
    }

    return bDisallow;
}

static void lcl_DoDragCells( ScDocShell* pSrcShell, const ScRange& rRange, ScDragSrc nFlags, vcl::Window* pWin )
static bool lcl_DoDragCells( ScDocShell* pSrcShell, const ScRange& rRange, ScDragSrc nFlags, vcl::Window* pWin )
{
    bool bDisallow = true;

    ScDocument& rSrcDoc = pSrcShell->GetDocument();
    ScMarkData aMark(rSrcDoc.MaxRow(), rSrcDoc.MaxCol());
    aMark.SelectTable( rRange.aStart.Tab(), true );
@@ -1276,13 +1154,22 @@ static void lcl_DoDragCells( ScDocShell* pSrcShell, const ScRange& rRange, ScDra
        pTransferObj->SetDragSourceFlags( nFlags );

        SC_MOD()->SetDragObject( pTransferObj.get(), nullptr );      // for internal D&D
        pWin->ReleaseMouse();
        pTransferObj->StartDrag( pWin, DND_ACTION_COPYMOVE | DND_ACTION_LINK );

        bDisallow = false;
    }

    return bDisallow;
}

void ScContentTree::DoDrag()
IMPL_LINK(ScContentTree, DragBeginHdl, bool&, rUnsetDragIcon, bool)
{
    rUnsetDragIcon = true;

    StoreNavigatorSettings();

    bool bDisallow = true;

    std::unique_ptr<ScDocumentLoader> pDocLoader;
    bIsInDrag = true;

@@ -1290,16 +1177,20 @@ void ScContentTree::DoDrag()

    ScContentId nType;
    sal_uLong nChild;
    SvTreeListEntry* pEntry = GetCurEntry();
    GetEntryIndexes( nType, nChild, pEntry );

    if( pEntry &&
    std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
    if (!m_xTreeView->get_cursor(xEntry.get()))
        xEntry.reset();

    GetEntryIndexes(nType, nChild, xEntry.get());

    if( xEntry &&
        (nChild != SC_CONTENT_NOCHILD) &&
        (nType != ScContentId::ROOT) &&
        (nType != ScContentId::NOTE) &&
        (nType != ScContentId::AREALINK) )
    {
        OUString aText( GetEntryText( pEntry ) );
        OUString aText(m_xTreeView->get_text(*xEntry));

        ScDocument* pLocalDoc = nullptr;                   // for URL drop
        OUString aDocName;
@@ -1387,7 +1278,7 @@ void ScContentTree::DoDrag()
                            ScRange aRange;
                            if ( lcl_GetRange( &rSrcDoc, nType, aText, aRange ) )
                            {
                                lcl_DoDragCells( pSrcShell, aRange, ScDragSrc::Navigator, this );
                                bDisallow = lcl_DoDragCells( pSrcShell, aRange, ScDragSrc::Navigator, pParentWindow );
                            }
                        }
                        else if ( nType == ScContentId::TABLE )
@@ -1396,13 +1287,13 @@ void ScContentTree::DoDrag()
                            if ( rSrcDoc.GetTable( aText, nTab ) )
                            {
                                ScRange aRange(0, 0, nTab, rSrcDoc.MaxCol(), rSrcDoc.MaxRow(), nTab);
                                lcl_DoDragCells( pSrcShell, aRange, (ScDragSrc::Navigator | ScDragSrc::Table), this );
                                bDisallow = lcl_DoDragCells( pSrcShell, aRange, (ScDragSrc::Navigator | ScDragSrc::Table), pParentWindow );
                            }
                        }
                        else if ( nType == ScContentId::GRAPHIC || nType == ScContentId::OLEOBJECT ||
                                    nType == ScContentId::DRAWING )
                        {
                            lcl_DoDragObject( pSrcShell, aText, nType, this );
                            bDisallow = lcl_DoDragObject( pSrcShell, aText, nType, pParentWindow );

                            //  during ExecuteDrag the navigator can be deleted
                            //  -> don't access member anymore !!!
@@ -1414,27 +1305,18 @@ void ScContentTree::DoDrag()

        if (bDoLinkTrans)
        {
            rtl::Reference<ScLinkTransferObj> pTransferObj = new ScLinkTransferObj;
            if (!aLinkURL.isEmpty())
                m_xTransferObj->SetLinkURL(aLinkURL, aLinkText);

            if ( !aLinkURL.isEmpty() )
                pTransferObj->SetLinkURL( aLinkURL, aLinkText );
            m_xTransferObj->StartDrag(pParentWindow, DND_ACTION_COPYMOVE | DND_ACTION_LINK);

            //  SetDragJump / SetDragLink has been done above

            ReleaseMouse();
            pTransferObj->StartDrag( this, DND_ACTION_COPYMOVE | DND_ACTION_LINK );
            bDisallow = false;
        }
    }

    bIsInDrag = false;              // static member
}

IMPL_LINK_NOARG(ScContentTree, ExecDragHdl, void*, void)
{
    //  as link, so that async without ImpMouseMoveMsg on the stack also
    //  the navigator can be deleted

    DoDrag();
    return bDisallow;
}

void ScContentTree::LoadFile( const OUString& rUrl )
@@ -1464,21 +1346,11 @@ void ScContentTree::LoadFile( const OUString& rUrl )
    //  document is closed again by ScDocumentLoader in dtor
}

void ScContentTree::InitWindowBits( bool bButtons )
{
    WinBits nFlags = GetStyle() | WB_CLIPCHILDREN | WB_HSCROLL;
    if (bButtons)
        nFlags |= WB_HASBUTTONS | WB_HASBUTTONSATROOT;

    SetStyle( nFlags );
}

void ScContentTree::SetRootType( ScContentId nNew )
{
    if ( nNew != nRootType )
    {
        nRootType = nNew;
        InitWindowBits( nNew == ScContentId::ROOT );
        Refresh();

        ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
@@ -1491,13 +1363,23 @@ void ScContentTree::ToggleRoot()        // after selection
    ScContentId nNew = ScContentId::ROOT;
    if ( nRootType == ScContentId::ROOT )
    {
        SvTreeListEntry* pEntry = GetCurEntry();
        if (pEntry)
        std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
        if (m_xTreeView->get_cursor(xEntry.get()))
        {
            SvTreeListEntry* pParent = GetParent(pEntry);
            std::unique_ptr<weld::TreeIter> xParent(m_xTreeView->make_iterator(xEntry.get()));
            if (!m_xTreeView->iter_parent(*xParent))
                xParent.reset();

            for (sal_uInt16 i=1; i<=int(ScContentId::LAST); i++)
                if ( pEntry == pRootNodes[static_cast<ScContentId>(i)] || pParent == pRootNodes[static_cast<ScContentId>(i)] )
            {
                if (!m_aRootNodes[static_cast<ScContentId>(i)])
                    continue;
                if ((m_xTreeView->iter_compare(*xEntry, *m_aRootNodes[static_cast<ScContentId>(i)]) == 0) ||
                    (xParent && m_xTreeView->iter_compare(*xParent, *m_aRootNodes[static_cast<ScContentId>(i)]) == 0))
                {
                    nNew = static_cast<ScContentId>(i);
                }
            }
        }
    }

@@ -1601,36 +1483,29 @@ void ScContentTree::SelectDoc(const OUString& rName)      // rName like shown in

void ScContentTree::SelectEntryByName(const ScContentId nRoot, const OUString& rName)
{
    SvTreeListEntry* pParent = pRootNodes[ nRoot ];
    weld::TreeIter* pParent = m_aRootNodes[nRoot].get();

    if( !pParent->HasChildren() )
    if (pParent || !m_xTreeView->iter_has_child(*pParent))
        return;

    SvTreeListEntry* pEntry = FirstChild( pParent );
    while( pEntry )
    std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator(pParent));
    bool bEntry = m_xTreeView->iter_children(*xEntry);

    while (bEntry)
    {
        if( GetEntryText( pEntry ) == rName )
        if (m_xTreeView->get_text(*xEntry) == rName)
        {
            SvTreeListBox::Select( pEntry );
            m_xTreeView->select(*xEntry);
            m_xTreeView->set_cursor(*xEntry);

            // Scroll to the selected item
            if( SvTreeListBox::GetVScroll()->IsVisible() )
            {
                long nBeforeCount = 0;
                SvTreeList* pList = GetModel();
                SvTreeListEntry* pRoot = pList->First();
                while( pRoot != pParent )
                {
                    ++nBeforeCount;
                    pRoot = pList->Next( pRoot );
                }
                SvTreeListBox::ScrollToAbsPos( pEntry->GetChildListPos()
                            + nBeforeCount );
            }
            m_xTreeView->scroll_to_row(*xEntry);

            StoreNavigatorSettings();

            return;
        }
        pEntry = Next( pEntry );
        bEntry = m_xTreeView->iter_next(*xEntry);
    }
}

@@ -1645,37 +1520,36 @@ void ScContentTree::ApplyNavigatorSettings()
        for( int i = 1; i <= int(ScContentId::LAST); ++i )
        {
            ScContentId nEntry = static_cast<ScContentId>(i);
            if( pRootNodes[ nEntry ] )
            if( m_aRootNodes[ nEntry ] )
            {
                // gray or ungray
                if( GetChildCount( pRootNodes[ nEntry ] ) == 0 )
                {
                    pRootNodes[ nEntry ]->SetFlags( pRootNodes[ nEntry ]->GetFlags() | SvTLEntryFlags::SEMITRANSPARENT );
                    pRootNodes[ nEntry ]->SetTextColor( COL_GRAY );
                }
                if (!m_xTreeView->iter_has_child(*m_aRootNodes[nEntry]))
                    m_xTreeView->set_sensitive(*m_aRootNodes[nEntry], false);
                else
                {
                   pRootNodes[ nEntry ]->SetFlags( pRootNodes[ nEntry ]->GetFlags() & ~SvTLEntryFlags::SEMITRANSPARENT );
                   pRootNodes[ nEntry ]->SetTextColor( GetTextColor() );
                }
                    m_xTreeView->set_sensitive(*m_aRootNodes[nEntry], true);

                // expand
                bool bExp = pSettings->IsExpanded( nEntry );
                if( bExp != IsExpanded( pRootNodes[ nEntry ] ) )
                if (bExp != m_xTreeView->get_row_expanded(*m_aRootNodes[nEntry]))
                {
                    if( bExp )
                        Expand( pRootNodes[ nEntry ] );
                        m_xTreeView->expand_row(*m_aRootNodes[nEntry]);
                    else
                        Collapse( pRootNodes[ nEntry ] );
                        m_xTreeView->collapse_row(*m_aRootNodes[nEntry]);
                }

                // select
                if( nRootSel == nEntry )
                {
                    SvTreeListEntry* pEntry = nullptr;
                    if( bExp && (nChildSel != SC_CONTENT_NOCHILD) )
                        pEntry = GetEntry( pRootNodes[ nEntry ], nChildSel );
                    Select( pEntry ? pEntry : pRootNodes[ nEntry ] );
                    std::unique_ptr<weld::TreeIter> xEntry;
                    if (bExp && (nChildSel != SC_CONTENT_NOCHILD))
                    {
                        xEntry = m_xTreeView->make_iterator(m_aRootNodes[nEntry].get());
                        if (!m_xTreeView->iter_children(*xEntry) || !m_xTreeView->iter_nth_sibling(*xEntry, nChildSel))
                            xEntry.reset();
                    }
                    m_xTreeView->select(xEntry ? *xEntry : *m_aRootNodes[nEntry]);
                    m_xTreeView->set_cursor(xEntry ? *xEntry : *m_aRootNodes[nEntry]);
                }
            }
        }
@@ -1690,24 +1564,21 @@ void ScContentTree::StoreNavigatorSettings() const
        for( int i = 1; i <= int(ScContentId::LAST); ++i )
        {
            ScContentId nEntry = static_cast<ScContentId>(i);
            bool bExp = pRootNodes[ nEntry ] && IsExpanded( pRootNodes[ nEntry ] );
            bool bExp = m_aRootNodes[nEntry] && m_xTreeView->get_row_expanded(*m_aRootNodes[nEntry]);
            pSettings->SetExpanded( nEntry, bExp );
        }

        std::unique_ptr<weld::TreeIter> xCurEntry(m_xTreeView->make_iterator());
        if (!m_xTreeView->get_cursor(xCurEntry.get()))
            xCurEntry.reset();

        ScContentId nRoot;
        sal_uLong nChild;
        GetEntryIndexes( nRoot, nChild, GetCurEntry() );
        GetEntryIndexes(nRoot, nChild, xCurEntry.get());

        pSettings->SetRootSelected( nRoot );
        pSettings->SetChildSelected( nChild );
    }
}

void ScContentTree::InitEntry(SvTreeListEntry* pEntry,
    const OUString& rStr, const Image& rImg1, const Image& rImg2)
{
    sal_uInt16 nColToHilite = 1; //0==Bitmap;1=="Spalte1";2=="Spalte2"
    SvTreeListBox::InitEntry( pEntry, rStr, rImg1, rImg2 );
    SvLBoxString& rCol = static_cast<SvLBoxString&>(pEntry->GetItem( nColToHilite ));
    pEntry->ReplaceItem(std::make_unique<SvLBoxString>(rCol.GetText()), nColToHilite);
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/navipi/navcitem.cxx b/sc/source/ui/navipi/navcitem.cxx
index 8a31369..a3ba855 100644
--- a/sc/source/ui/navipi/navcitem.cxx
+++ b/sc/source/ui/navipi/navcitem.cxx
@@ -88,7 +88,7 @@ void ScNavigatorControllerItem::StateChanged( sal_uInt16 /* nSID */, SfxItemStat
            break;

        case SID_SELECT_SCENARIO:
            rNavigatorDlg.aWndScenarios->NotifyState( pItem );
            rNavigatorDlg.m_xWndScenarios->NotifyState(pItem);
            break;

        default:
diff --git a/sc/source/ui/navipi/navipi.cxx b/sc/source/ui/navipi/navipi.cxx
index bae7c6b..8ac1a91 100644
--- a/sc/source/ui/navipi/navipi.cxx
+++ b/sc/source/ui/navipi/navipi.cxx
@@ -23,7 +23,6 @@
#include <sfx2/event.hxx>
#include <sfx2/navigat.hxx>
#include <svl/stritem.hxx>
#include <vcl/builderfactory.hxx>
#include <unotools/charclass.hxx>

#include <viewdata.hxx>
@@ -67,93 +66,61 @@ void ScNavigatorDlg::ReleaseFocus()
    }
}

ColumnEdit::ColumnEdit(Window* pParent, WinBits nWinBits)
    : SpinField(pParent, nWinBits)
    , nCol(0)
namespace
{
    SetMaxTextLen(SCNAV_COLDIGITS);   // 1...256...18278 or A...IV...ZZZ
}

ColumnEdit::~ColumnEdit()
{
    disposeOnce();
}

VCL_BUILDER_FACTORY_ARGS(ColumnEdit, WB_BORDER | WB_SPIN | WB_REPEAT | WB_RIGHT)

bool ColumnEdit::EventNotify( NotifyEvent& rNEvt )
{
    bool bHandled = SpinField::EventNotify(rNEvt);

    MouseNotifyEvent nType = rNEvt.GetType();
    if ( nType == MouseNotifyEvent::KEYINPUT )
    SCCOL NumToAlpha(SCCOL nColNo, OUString& rStr)
    {
        const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
        vcl::KeyCode aCode = pKEvt->GetKeyCode();
        if ( nColNo > SCNAV_MAXCOL )
            nColNo = SCNAV_MAXCOL;
        else if ( nColNo < 1 )
            nColNo = 1;

        if ( !aCode.IsMod1() && !aCode.IsMod2() )
        ::ScColToAlpha( rStr, nColNo - 1);

        return nColNo;
    }

    SCCOL AlphaToNum(const ScDocument& rDoc, OUString& rStr)
    {
        SCCOL  nColumn = 0;

        if ( CharClass::isAsciiAlpha( rStr) )
        {
            //! Input Validation (only alphanumerics, max 2-3 digits)
            //! was before VCL not forwarded keyinput
            //! rethink this!!!
            rStr = rStr.toAsciiUpperCase();

            if ( aCode.GetCode() == KEY_RETURN )
            if (::AlphaToCol( rDoc, nColumn, rStr))
                ++nColumn;

            if ( (rStr.getLength() > SCNAV_COLLETTERS) || (nColumn > SCNAV_MAXCOL) )
            {
                ScNavigatorDlg::ReleaseFocus();
                ExecuteCol();
                bHandled = true;
                nColumn = SCNAV_MAXCOL;
                NumToAlpha( nColumn, rStr );
            }
        }
        else
            rStr.clear();

        return nColumn;
    }
    else if ( nType == MouseNotifyEvent::LOSEFOCUS )    // LoseFocus not called at VCL
        EvalText();                         // nCol set

    return bHandled;
    SCCOL NumStrToAlpha(OUString& rStr)
    {
        SCCOL  nColumn = 0;

        if ( CharClass::isAsciiNumeric(rStr) )
            nColumn = NumToAlpha( static_cast<SCCOL>(rStr.toInt32()), rStr );
        else
            rStr.clear();

        return nColumn;
    }
}

void ColumnEdit::LoseFocus()
IMPL_LINK(ScNavigatorDlg, ParseRowInputHdl, int*, result, bool)
{
    EvalText();
}
    SCCOL nCol;

void ColumnEdit::dispose()
{
    xDlg.clear();
    SpinField::dispose();
}

void ColumnEdit::Up()
{
    nCol++;

    if ( nCol <= SCNAV_MAXCOL )
        SetCol( nCol );
    else
        nCol--;
}

void ColumnEdit::Down()
{
    if ( nCol>1 )
        SetCol( nCol-1 );
}

void ColumnEdit::First()
{
    nCol = 1;
    SetText(OUString('A'));
}

void ColumnEdit::Last()
{
    OUString aStr;
    nCol = NumToAlpha( SCNAV_MAXCOL, aStr );
    SetText( aStr );
}

void ColumnEdit::EvalText()
{
    OUString aStrCol = GetText();
    OUString aStrCol = m_xEdCol->get_text();

    if (!aStrCol.isEmpty())
    {
@@ -170,159 +137,60 @@ void ColumnEdit::EvalText()
    else
        nCol = 0;

    SetText( aStrCol );
    *result = nCol;
    return true;
}

void ColumnEdit::ExecuteCol()
IMPL_LINK_NOARG(ScNavigatorDlg, ExecuteColHdl, weld::Entry&, bool)
{
    SCROW nRow = xDlg->aEdRow->GetRow();
    ReleaseFocus();

    EvalText(); // sets nCol
    SCROW nRow = m_xEdRow->get_value();
    SCCOL nCol = m_xEdCol->get_value();

    if ( (nCol > 0) && (nRow > 0) )
        xDlg->SetCurrentCell(nCol - 1, nRow - 1);
        SetCurrentCell(nCol - 1, nRow - 1);

    return true;
}

void ColumnEdit::SetCol( SCCOL nColNo )
IMPL_LINK_NOARG(ScNavigatorDlg, FormatRowOutputHdl, weld::SpinButton&, void)
{
    OUString aStr;

    if ( nColNo == 0 )
    {
        nCol = 0;
        SetText( aStr );
    }
    else
    {
        nColNo = NumToAlpha( nColNo, aStr );
        nCol = nColNo;
        SetText( aStr );
    }
    ::ScColToAlpha(aStr, m_xEdCol->get_value() - 1);
    m_xEdCol->set_text(aStr);
}

SCCOL ColumnEdit::AlphaToNum( const ScDocument& rDoc, OUString& rStr )
IMPL_LINK_NOARG(ScNavigatorDlg, ExecuteRowHdl, weld::Entry&, bool)
{
    SCCOL  nColumn = 0;
    ReleaseFocus();

    if ( CharClass::isAsciiAlpha( rStr) )
    {
        rStr = rStr.toAsciiUpperCase();

        if (::AlphaToCol( rDoc, nColumn, rStr))
            ++nColumn;

        if ( (rStr.getLength() > SCNAV_COLLETTERS) || (nColumn > SCNAV_MAXCOL) )
        {
            nColumn = SCNAV_MAXCOL;
            NumToAlpha( nColumn, rStr );
        }
    }
    else
        rStr.clear();

    return nColumn;
}

SCCOL ColumnEdit::NumStrToAlpha( OUString& rStr )
{
    SCCOL  nColumn = 0;

    if ( CharClass::isAsciiNumeric(rStr) )
        nColumn = NumToAlpha( static_cast<SCCOL>(rStr.toInt32()), rStr );
    else
        rStr.clear();

    return nColumn;
}

SCCOL ColumnEdit::NumToAlpha( SCCOL nColNo, OUString& rStr )
{
    if ( nColNo > SCNAV_MAXCOL )
        nColNo = SCNAV_MAXCOL;
    else if ( nColNo < 1 )
        nColNo = 1;

    ::ScColToAlpha( rStr, nColNo - 1);

    return nColNo;
}

RowEdit::RowEdit(Window* pParent, WinBits nWinBits)
    : NumericField(pParent, nWinBits)
{
    SetMax(SCNAV_MAXROW);
    SetLast(SCNAV_MAXROW);
}

RowEdit::~RowEdit()
{
    disposeOnce();
}

VCL_BUILDER_FACTORY_ARGS(RowEdit, WB_BORDER | WB_SPIN | WB_REPEAT | WB_RIGHT)

bool RowEdit::EventNotify( NotifyEvent& rNEvt )
{
    bool bHandled = NumericField::EventNotify(rNEvt);

    if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
    {
        const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
        vcl::KeyCode aCode = pKEvt->GetKeyCode();
        if ( aCode.GetCode() == KEY_RETURN && !aCode.IsMod1() && !aCode.IsMod2() )
        {
            ScNavigatorDlg::ReleaseFocus();
            ExecuteRow();
            bHandled = true;
        }
    }

    return bHandled;
}

void RowEdit::LoseFocus()
{
}

void RowEdit::dispose()
{
    xDlg.clear();
    NumericField::dispose();
}

Size RowEdit::GetOptimalSize() const
{
    //max rows is 1,000,000, which is too long for typical use
    return CalcMinimumSizeForText("1,000");
}

void RowEdit::ExecuteRow()
{
    SCCOL nCol = xDlg->aEdCol->GetCol();
    SCROW nRow = static_cast<SCROW>(GetValue());
    SCCOL nCol = m_xEdCol->get_value();
    SCROW nRow = m_xEdRow->get_value();

    if ( (nCol > 0) && (nRow > 0) )
        xDlg->SetCurrentCell(nCol - 1, nRow - 1);
        SetCurrentCell(nCol - 1, nRow - 1);

    return true;
}

IMPL_LINK(ScNavigatorDlg, DocumentSelectHdl, ListBox&, rListBox, void)
IMPL_LINK(ScNavigatorDlg, DocumentSelectHdl, weld::ComboBox&, rListBox, void)
{
    ScNavigatorDlg::ReleaseFocus();

    OUString aDocName = rListBox.GetSelectedEntry();
    aLbEntries->SelectDoc(aDocName);
    OUString aDocName = rListBox.get_active_text();
    m_xLbEntries->SelectDoc(aDocName);
}

IMPL_LINK(ScNavigatorDlg, ToolBoxSelectHdl, ToolBox*, pToolBox, void)
IMPL_LINK(ScNavigatorDlg, ToolBoxSelectHdl, const OString&, rSelId, void)
{
    sal_uInt16 nSelId = pToolBox->GetCurItemId();
    //  Switch the mode?
    if (nSelId == nZoomId || nSelId == nScenarioId)
    if (rSelId == "contents" || rSelId == "scenarios")
    {
        NavListMode eOldMode = eListMode;
        NavListMode eNewMode;

        if (nSelId == nScenarioId)
        if (rSelId == "scenarios")
        {
            if (eOldMode == NAV_LMODE_SCENARIOS)
                eNewMode = NAV_LMODE_AREAS;
@@ -339,75 +207,75 @@ IMPL_LINK(ScNavigatorDlg, ToolBoxSelectHdl, ToolBox*, pToolBox, void)
        SetListMode(eNewMode);
        UpdateButtons();
    }
    else if (rSelId == "dragmode")
        m_xTbxCmd2->set_menu_item_active("dragmode", !m_xTbxCmd2->get_menu_item_active("dragmode"));
    else
    {
        if (nSelId == nDataId)
        if (rSelId == "datarange")
            MarkDataArea();
        else if (nSelId == nUpId)
        else if (rSelId == "start")
            StartOfDataArea();
        else if (nSelId == nDownId)
        else if (rSelId == "end")
            EndOfDataArea();
        else if (nSelId == nChangeRootId)
        else if (rSelId == "toggle")
        {
            aLbEntries->ToggleRoot();
            m_xLbEntries->ToggleRoot();
            UpdateButtons();
        }
    }
}

IMPL_LINK(ScNavigatorDlg, ToolBoxDropdownClickHdl, ToolBox *, pToolBox, void)
IMPL_LINK(ScNavigatorDlg, ToolBoxDropdownClickHdl, const OString&, rCommand, void)
{
    if (!m_xTbxCmd2->get_menu_item_active(rCommand))
        return;

    // the popup menu of the drop mode has to be called in the
    // click (button down) and not in the select (button up)
    if (pToolBox->GetCurItemId() == nDragModeId)
    if (rCommand == "dragmode")
    {
        VclBuilder aBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "modules/scalc/ui/dropmenu.ui", "");
        VclPtr<PopupMenu> aPop(aBuilder.get_menu("menu"));

        switch (GetDropMode())
        {
            case 0:
                aPop->CheckItem("hyperlink");
                m_xDragModeMenu->set_active("hyperlink", true);
                break;
            case 1:
                aPop->CheckItem("link");
                m_xDragModeMenu->set_active("link", true);
                break;
            case 2:
                aPop->CheckItem("copy");
                m_xDragModeMenu->set_active("copy", true);
                break;
        }

        sal_uInt16 nId = aPop->Execute(pToolBox, pToolBox->GetItemRect(nDragModeId), PopupMenuFlags::ExecuteDown);
        OString sIdent = aPop->GetItemIdent(nId);

        if (sIdent == "hyperlink")
            SetDropMode(0);
        else if (sIdent == "link")
            SetDropMode(1);
        else if (sIdent == "copy")
            SetDropMode(2);

        pToolBox->EndSelection();     // before SetDropMode (SetDropMode calls SetItemImage)
    }
}

IMPL_LINK(ScNavigatorDlg, MenuSelectHdl, const OString&, rIdent, void)
{
    if (rIdent == "hyperlink")
        SetDropMode(0);
    else if (rIdent == "link")
        SetDropMode(1);
    else if (rIdent == "copy")
        SetDropMode(2);
}

void ScNavigatorDlg::UpdateButtons()
{
    NavListMode eMode = eListMode;
    aTbxCmd->CheckItem(nScenarioId, eMode == NAV_LMODE_SCENARIOS);
    aTbxCmd->CheckItem(nZoomId, eMode != NAV_LMODE_NONE);
    m_xTbxCmd2->set_item_active("scenarios", eMode == NAV_LMODE_SCENARIOS);
    m_xTbxCmd1->set_item_active("contents", eMode != NAV_LMODE_NONE);

    // the toggle button:
    if (eMode == NAV_LMODE_SCENARIOS || eMode == NAV_LMODE_NONE)
    {
        aTbxCmd->EnableItem(nChangeRootId, false);
        aTbxCmd->CheckItem(nChangeRootId, false);
        m_xTbxCmd2->set_item_sensitive("toggle", false);
        m_xTbxCmd2->set_item_active("toggle", false);
    }
    else
    {
        aTbxCmd->EnableItem(nChangeRootId);
        bool bRootSet = aLbEntries->GetRootType() != ScContentId::ROOT;
        aTbxCmd->CheckItem(nChangeRootId, bRootSet);
        m_xTbxCmd2->set_item_sensitive("toggle", true);
        bool bRootSet = m_xLbEntries->GetRootType() != ScContentId::ROOT;
        m_xTbxCmd2->set_item_active("toggle", bRootSet);
    }

    OUString sImageId;
@@ -423,7 +291,7 @@ void ScNavigatorDlg::UpdateButtons()
            sImageId = RID_BMP_DROP_COPY;
            break;
    }
    aTbxCmd->SetItemImage(nDragModeId, Image(StockImage::Yes, sImageId));
    m_xTbxCmd2->set_item_icon_name("dragmode", sImageId);
}

ScNavigatorSettings::ScNavigatorSettings()
@@ -448,10 +316,18 @@ ScNavigatorDialogWrapper::ScNavigatorDialogWrapper(vcl::Window* pParent,
}

ScNavigatorDlg::ScNavigatorDlg(SfxBindings* pB, vcl::Window* pParent)
    : PanelLayout(pParent, "NavigatorPanel", "modules/scalc/ui/navigatorpanel.ui", nullptr)
    : PanelLayout(pParent, "NavigatorPanel", "modules/scalc/ui/navigatorpanel.ui", nullptr, true)
    , rBindings(*pB)
    , aStrDragMode(ScResId(SCSTR_DRAGMODE))
    , aStrDisplay(ScResId(SCSTR_DISPLAY))
    , m_xEdCol(m_xBuilder->weld_spin_button("column"))
    , m_xEdRow(m_xBuilder->weld_spin_button("row"))
    , m_xTbxCmd1(m_xBuilder->weld_toolbar("toolbox1"))
    , m_xTbxCmd2(m_xBuilder->weld_toolbar("toolbox2"))
    , m_xLbEntries(new ScContentTree(m_xBuilder->weld_tree_view("contentbox"), this))
    , m_xScenarioBox(m_xBuilder->weld_widget("scenariobox"))
    , m_xWndScenarios(new ScScenarioWindow(*m_xBuilder,
        ScResId(SCSTR_QHLP_SCEN_LISTBOX), ScResId(SCSTR_QHLP_SCEN_COMMENT)))
    , m_xLbDocuments(m_xBuilder->weld_combo_box("documents"))
    , m_xDragModeMenu(m_xBuilder->weld_menu("dragmodemenu"))
    , aStrActiveWin(ScResId(SCSTR_ACTIVEWIN))
    , pViewData(nullptr )
    , eListMode(NAV_LMODE_NONE)
@@ -460,42 +336,29 @@ ScNavigatorDlg::ScNavigatorDlg(SfxBindings* pB, vcl::Window* pParent)
    , nCurRow(0)
    , nCurTab(0)
{
    get(aLbDocuments, "documents");
    get(aEdCol, "column");
    aEdCol->SetNavigatorDlg(this);
    get(aEdRow, "row");
    aEdRow->SetNavigatorDlg(this);
    get(aTbxCmd, "toolbox");
    aTbxCmd->SetSelectHdl(LINK(this, ScNavigatorDlg, ToolBoxSelectHdl));
    aTbxCmd->SetDropdownClickHdl(LINK(this, ScNavigatorDlg, ToolBoxDropdownClickHdl));
    nZoomId = aTbxCmd->GetItemId("contents");
    nChangeRootId = aTbxCmd->GetItemId("toggle");
    nDragModeId = aTbxCmd->GetItemId("dragmode");
    aTbxCmd->SetItemBits(nDragModeId, aTbxCmd->GetItemBits(nDragModeId) | ToolBoxItemBits::DROPDOWNONLY);
    nScenarioId = aTbxCmd->GetItemId("scenarios");
    nDownId = aTbxCmd->GetItemId("end");
    nUpId = aTbxCmd->GetItemId("start");
    nDataId = aTbxCmd->GetItemId("datarange");
    get(aContentBox, "contentbox");
    aLbEntries = VclPtr<ScContentTree>::Create(aContentBox, this);
    aLbEntries->set_hexpand(true);
    aLbEntries->set_vexpand(true);
    aLbEntries->Show();
    get(aScenarioBox, "scenariobox");
    aWndScenarios = VclPtr<ScScenarioWindow>::Create(aScenarioBox,
        ScResId(SCSTR_QHLP_SCEN_LISTBOX), ScResId(SCSTR_QHLP_SCEN_COMMENT));
    aWndScenarios->set_hexpand(true);
    aWndScenarios->set_vexpand(true);
    aWndScenarios->Show();
    m_xEdRow->set_range(1, SCNAV_MAXROW);
    m_xEdRow->set_width_chars(5);
    //max rows is 1,000,000, which is too long for typical use
    m_xEdRow->connect_activate(LINK(this, ScNavigatorDlg, ExecuteRowHdl));

    m_xEdCol->set_range(1, SCNAV_MAXCOL);
    m_xEdCol->set_width_chars(SCNAV_COLDIGITS);   // 1...256...18278 or A...IV...ZZZ
    m_xEdCol->connect_activate(LINK(this, ScNavigatorDlg, ExecuteColHdl));
    m_xEdCol->connect_output(LINK(this, ScNavigatorDlg, FormatRowOutputHdl));
    m_xEdCol->connect_input(LINK(this, ScNavigatorDlg, ParseRowInputHdl));

    m_xTbxCmd1->connect_clicked(LINK(this, ScNavigatorDlg, ToolBoxSelectHdl));
    m_xTbxCmd2->connect_clicked(LINK(this, ScNavigatorDlg, ToolBoxSelectHdl));

    m_xTbxCmd2->set_item_menu("dragmode", m_xDragModeMenu.get());
    m_xDragModeMenu->connect_activate(LINK(this, ScNavigatorDlg, MenuSelectHdl));
    m_xTbxCmd2->connect_menu_toggled(LINK(this, ScNavigatorDlg, ToolBoxDropdownClickHdl));

    ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
    nDropMode = rCfg.GetDragMode();

    aTbxCmd->InsertBreak(3);
    aTbxCmd->SetLineCount(2);
    aLbDocuments->SetDropDownLineCount(9);
    aLbDocuments->setMaxWidthChars(20);
    aLbDocuments->SetSelectHdl(LINK(this, ScNavigatorDlg, DocumentSelectHdl));
    m_xLbDocuments->set_size_request(42, -1); // set a nominal width so it takes width of surroundings
    m_xLbDocuments->connect_changed(LINK(this, ScNavigatorDlg, DocumentSelectHdl));
    aStrActive    = " (" + ScResId(SCSTR_ACTIVE) + ")";     // " (active)"
    aStrNotActive = " (" + ScResId(SCSTR_NOTACTIVE) + ")";  // " (not active)"
    aStrHidden    = " (" + ScResId(SCSTR_HIDDEN) + ")";     // " (hidden)"
@@ -512,20 +375,16 @@ ScNavigatorDlg::ScNavigatorDlg(SfxBindings* pB, vcl::Window* pParent)
    StartListening( *(SfxGetpApp()) );
    StartListening( rBindings );

    aLbEntries->InitWindowBits(true);

    aLbEntries->SetSpaceBetweenEntries(0);
    aLbEntries->SetSelectionMode( SelectionMode::Single );
    aLbEntries->SetDragDropMode( DragDropMode::CTRL_MOVE |
                                 DragDropMode::CTRL_COPY |
                                 DragDropMode::ENABLE_TOP );
    m_xLbEntries->set_selection_mode( SelectionMode::Single );
    Size aSize(LogicToPixel(Size(110, 100), MapMode(MapUnit::MapAppFont)));
    m_xLbEntries->set_size_request(aSize.Width(), aSize.Height());

    //  was a category chosen as root?
    ScContentId nLastRoot = rCfg.GetRootType();
    if ( nLastRoot != ScContentId::ROOT )
        aLbEntries->SetRootType( nLastRoot );
        m_xLbEntries->SetRootType( nLastRoot );

    aLbEntries->Refresh();
    m_xLbEntries->Refresh();
    GetDocNames(nullptr);

    UpdateButtons();
@@ -533,18 +392,18 @@ ScNavigatorDlg::ScNavigatorDlg(SfxBindings* pB, vcl::Window* pParent)
    UpdateColumn();
    UpdateRow();
    UpdateTable(nullptr);
    aContentBox->Hide();
    aScenarioBox->Hide();
    m_xLbEntries->hide();
    m_xScenarioBox->hide();

    aContentIdle.SetInvokeHandler( LINK( this, ScNavigatorDlg, TimeHdl ) );
    aContentIdle.SetPriority( TaskPriority::LOWEST );

    aLbEntries->SetNavigatorDlgFlag(true);
    m_xLbEntries->SetNavigatorDlgFlag(true);

    // if scenario was active, switch on
    NavListMode eNavMode = static_cast<NavListMode>(rCfg.GetListMode());
    if (eNavMode == NAV_LMODE_SCENARIOS)
        aTbxCmd->CheckItem(nScenarioId);
        m_xTbxCmd2->set_item_active("scenarios", true);
    else
        eNavMode = NAV_LMODE_AREAS;
    SetListMode(eNavMode);
@@ -560,7 +419,7 @@ void ScNavigatorDlg::StateChanged(StateChangedType nStateChange)
        // When the navigator is displayed in the sidebar, or is otherwise
        // docked, it has the whole deck to fill. Therefore hide the button that
        // hides all controls below the top two rows of buttons.
        aTbxCmd->ShowItem(nZoomId, SfxChildWindowContext::GetFloatingWindow(GetParent()) != nullptr);
        m_xTbxCmd1->set_item_visible("contents", SfxChildWindowContext::GetFloatingWindow(GetParent()) != nullptr);
    }
}

@@ -580,14 +439,15 @@ void ScNavigatorDlg::dispose()
    EndListening( *(SfxGetpApp()) );
    EndListening( rBindings );

    aEdCol.clear();
    aEdRow.clear();
    aTbxCmd.clear();
    aLbEntries.disposeAndClear();
    aContentBox.clear();
    aWndScenarios.disposeAndClear();
    aScenarioBox.clear();
    aLbDocuments.clear();
    m_xEdCol.reset();
    m_xEdRow.reset();
    m_xTbxCmd1.reset();
    m_xTbxCmd2.reset();
    m_xDragModeMenu.reset();
    m_xLbEntries.reset();
    m_xWndScenarios.reset();
    m_xScenarioBox.reset();
    m_xLbDocuments.reset();
    PanelLayout::dispose();
}

@@ -597,7 +457,7 @@ void ScNavigatorDlg::Notify( SfxBroadcaster&, const SfxHint& rHint )
    {
        if (pHint->GetEventId() == SfxEventHintId::ActivateDoc)
        {
            aLbEntries->ActiveDocChanged();
            m_xLbEntries->ActiveDocChanged();
            UpdateAll();
        }
    }
@@ -607,7 +467,7 @@ void ScNavigatorDlg::Notify( SfxBroadcaster&, const SfxHint& rHint )

        if (nHintId == SfxHintId::ScDocNameChanged)
        {
            aLbEntries->ActiveDocChanged();
            m_xLbEntries->ActiveDocChanged();
        }
        else if (NAV_LMODE_NONE == eListMode)
        {
@@ -618,25 +478,25 @@ void ScNavigatorDlg::Notify( SfxBroadcaster&, const SfxHint& rHint )
            switch ( nHintId )
            {
                case SfxHintId::ScTablesChanged:
                    aLbEntries->Refresh( ScContentId::TABLE );
                    m_xLbEntries->Refresh( ScContentId::TABLE );
                    break;

                case SfxHintId::ScDbAreasChanged:
                    aLbEntries->Refresh( ScContentId::DBAREA );
                    m_xLbEntries->Refresh( ScContentId::DBAREA );
                    break;

                case SfxHintId::ScAreasChanged:
                    aLbEntries->Refresh( ScContentId::RANGENAME );
                    m_xLbEntries->Refresh( ScContentId::RANGENAME );
                    break;

                case SfxHintId::ScDrawChanged:
                    aLbEntries->Refresh( ScContentId::GRAPHIC );
                    aLbEntries->Refresh( ScContentId::OLEOBJECT );
                    aLbEntries->Refresh( ScContentId::DRAWING );
                    m_xLbEntries->Refresh( ScContentId::GRAPHIC );
                    m_xLbEntries->Refresh( ScContentId::OLEOBJECT );
                    m_xLbEntries->Refresh( ScContentId::DRAWING );
                    break;

                case SfxHintId::ScAreaLinksChanged:
                    aLbEntries->Refresh( ScContentId::AREALINK );
                    m_xLbEntries->Refresh( ScContentId::AREALINK );
                    break;

                //  SfxHintId::DocChanged not only at document change
@@ -650,9 +510,9 @@ void ScNavigatorDlg::Notify( SfxBroadcaster&, const SfxHint& rHint )
                    aContentIdle.Start();      // Do not search notes immediately
                    break;
                case SfxHintId::ScKillEditView:
                    aLbEntries->ObjectFresh( ScContentId::OLEOBJECT );
                    aLbEntries->ObjectFresh( ScContentId::DRAWING );
                    aLbEntries->ObjectFresh( ScContentId::GRAPHIC );
                    m_xLbEntries->ObjectFresh( ScContentId::OLEOBJECT );
                    m_xLbEntries->ObjectFresh( ScContentId::DRAWING );
                    m_xLbEntries->ObjectFresh( ScContentId::GRAPHIC );
                    break;
                case SfxHintId::ScSelectionChanged:
                    UpdateSelection();
@@ -669,7 +529,7 @@ IMPL_LINK( ScNavigatorDlg, TimeHdl, Timer*, pIdle, void )
    if ( pIdle != &aContentIdle )
        return;

    aLbEntries->Refresh( ScContentId::NOTE );
    m_xLbEntries->Refresh( ScContentId::NOTE );
}

void ScNavigatorDlg::SetDropMode(sal_uInt16 nNew)
@@ -797,7 +657,7 @@ void ScNavigatorDlg::UpdateSelection()
            OUString sName = xNamed->getName();
            if (!sName.isEmpty())
            {
                aLbEntries->SelectEntryByName( ScContentId::DRAWING, sName );
                m_xLbEntries->SelectEntryByName( ScContentId::DRAWING, sName );
            }
        }
    }
@@ -833,7 +693,7 @@ void ScNavigatorDlg::UpdateColumn( const SCCOL* pCol )
    else if ( GetViewData() )
        nCurCol = pViewData->GetCurX() + 1;

    aEdCol->SetCol( nCurCol );
    m_xEdCol->set_value(nCurCol);
}

void ScNavigatorDlg::UpdateRow( const SCROW* pRow )
@@ -843,7 +703,7 @@ void ScNavigatorDlg::UpdateRow( const SCROW* pRow )
    else if ( GetViewData() )
        nCurRow = pViewData->GetCurY() + 1;

    aEdRow->SetRow( nCurRow );
    m_xEdRow->set_value(nCurRow);
}

void ScNavigatorDlg::UpdateTable( const SCTAB* pTab )
@@ -859,7 +719,7 @@ void ScNavigatorDlg::UpdateAll()
    switch (eListMode)
    {
        case NAV_LMODE_AREAS:
            aLbEntries->Refresh();
            m_xLbEntries->Refresh();
            break;
        case NAV_LMODE_NONE:
            //! ???
@@ -889,7 +749,7 @@ void ScNavigatorDlg::SetListMode(NavListMode eMode)
                ShowList(false);
                break;
            case NAV_LMODE_AREAS:
                aLbEntries->Refresh();
                m_xLbEntries->Refresh();
                ShowList(true);
                break;
            case NAV_LMODE_SCENARIOS:
@@ -923,15 +783,15 @@ void ScNavigatorDlg::ShowList(bool bShow)
{
    if (bShow)
    {
        aContentBox->Show();
        aLbDocuments->Show();
        m_xLbEntries->show();
        m_xLbDocuments->show();
    }
    else
    {
        aContentBox->Hide();
        aLbDocuments->Hide();
        m_xLbEntries->hide();
        m_xLbDocuments->hide();
    }
    aScenarioBox->Hide();
    m_xScenarioBox->hide();
}

void ScNavigatorDlg::ShowScenarios()
@@ -939,17 +799,16 @@ void ScNavigatorDlg::ShowScenarios()
    rBindings.Invalidate( SID_SELECT_SCENARIO );
    rBindings.Update( SID_SELECT_SCENARIO );

    aScenarioBox->Show();
    aLbDocuments->Show();
    aContentBox->Hide();
    m_xScenarioBox->show();
    m_xLbDocuments->show();
    m_xLbEntries->hide();
}

//      documents for Dropdown-Listbox

void ScNavigatorDlg::GetDocNames( const OUString* pManualSel )
{
    aLbDocuments->Clear();
    aLbDocuments->SetUpdateMode( false );
    m_xLbDocuments->clear();
    m_xLbDocuments->freeze();

    ScDocShell* pCurrentSh = dynamic_cast<ScDocShell*>( SfxObjectShell::Current()  );

@@ -965,7 +824,7 @@ void ScNavigatorDlg::GetDocNames( const OUString* pManualSel )
                aEntry += aStrActive;
            else
                aEntry += aStrNotActive;
            aLbDocuments->InsertEntry( aEntry );
            m_xLbDocuments->append_text(aEntry);

            if ( pManualSel ? ( aName == *pManualSel )
                            : ( pSh == pCurrentSh ) )
@@ -975,21 +834,21 @@ void ScNavigatorDlg::GetDocNames( const OUString* pManualSel )
        pSh = SfxObjectShell::GetNext( *pSh );
    }

    aLbDocuments->InsertEntry( aStrActiveWin );
    m_xLbDocuments->append_text(aStrActiveWin);

    OUString aHidden =  aLbEntries->GetHiddenTitle();
    OUString aHidden =  m_xLbEntries->GetHiddenTitle();
    if (!aHidden.isEmpty())
    {
        OUString aEntry = aHidden + aStrHidden;
        aLbDocuments->InsertEntry( aEntry );
        m_xLbDocuments->append_text(aEntry);

        if ( pManualSel && aHidden == *pManualSel )
            aSelEntry = aEntry;
    }

    aLbDocuments->SetUpdateMode( true );
    m_xLbDocuments->thaw();

    aLbDocuments->SelectEntry( aSelEntry );
    m_xLbDocuments->set_active_text(aSelEntry);
}

void ScNavigatorDlg::MarkDataArea()
@@ -1036,7 +895,7 @@ void ScNavigatorDlg::StartOfDataArea()
        SCCOL nCol = aMarkRange.aStart.Col();
        SCROW nRow = aMarkRange.aStart.Row();

        if ( (nCol+1 != aEdCol->GetCol()) || (nRow+1 != aEdRow->GetRow()) )
        if ( (nCol+1 != m_xEdCol->get_value()) || (nRow+1 != m_xEdRow->get_value()) )
            SetCurrentCell( nCol, nRow );
    }
}
@@ -1054,7 +913,7 @@ void ScNavigatorDlg::EndOfDataArea()
        SCCOL nCol = aMarkRange.aEnd.Col();
        SCROW nRow = aMarkRange.aEnd.Row();

        if ( (nCol+1 != aEdCol->GetCol()) || (nRow+1 != aEdRow->GetRow()) )
        if ( (nCol+1 != m_xEdCol->get_value()) || (nRow+1 != m_xEdRow->get_value()) )
            SetCurrentCell( nCol, nRow );
    }
}
diff --git a/sc/source/ui/navipi/scenwnd.cxx b/sc/source/ui/navipi/scenwnd.cxx
index 74ac7b0..f9ad4067 100644
--- a/sc/source/ui/navipi/scenwnd.cxx
+++ b/sc/source/ui/navipi/scenwnd.cxx
@@ -36,45 +36,31 @@

// class ScScenarioWindow ------------------------------------------------

ScScenarioListBox::ScScenarioListBox( ScScenarioWindow& rParent ) :
    ListBox( &rParent, WB_BORDER | WB_TABSTOP ),
    mrParent( rParent )
void ScScenarioWindow::UpdateEntries( const std::vector<OUString> &rNewEntryList )
{
    vcl::Font aFont( GetFont() );
    aFont.SetTransparent( true );
    aFont.SetWeight( WEIGHT_LIGHT );
    SetFont( aFont );
}
    m_xLbScenario->clear();
    m_aEntries.clear();

ScScenarioListBox::~ScScenarioListBox()
{
}

void ScScenarioListBox::UpdateEntries( const std::vector<OUString> &aNewEntryList )
{
    Clear();
    maEntries.clear();

    switch( aNewEntryList.size() )
    switch( rNewEntryList.size() )
    {
        case 0:
            // no scenarios in current sheet
            mrParent.SetComment( EMPTY_OUSTRING );
            SetComment( EMPTY_OUSTRING );
        break;

        case 1:
            // sheet is a scenario container, comment only
            mrParent.SetComment( aNewEntryList[0] );
            SetComment( rNewEntryList[0] );
        break;

        default:
        {
            // sheet contains scenarios
            assert(aNewEntryList.size() % 3 == 0 && "ScScenarioListBox::UpdateEntries - wrong list size");
            SetUpdateMode( false );
            assert(rNewEntryList.size() % 3 == 0 && "ScScenarioListBox::UpdateEntries - wrong list size");
            m_xLbScenario->freeze();

            std::vector<OUString>::const_iterator iter;
            for (iter = aNewEntryList.begin(); iter != aNewEntryList.end(); ++iter)
            for (iter = rNewEntryList.begin(); iter != rNewEntryList.end(); ++iter)
            {
                ScenarioEntry aEntry;

@@ -89,135 +75,131 @@ void ScScenarioListBox::UpdateEntries( const std::vector<OUString> &aNewEntryLis
                ++iter;
                aEntry.mbProtected = !(*iter).isEmpty() && (*iter)[0] != '0';

                maEntries.push_back( aEntry );
                InsertEntry( aEntry.maName );
                m_aEntries.push_back( aEntry );
                m_xLbScenario->append_text(aEntry.maName);
            }
            SetUpdateMode( true );
            SetNoSelection();
            mrParent.SetComment( EMPTY_OUSTRING );
            m_xLbScenario->thaw();
            m_xLbScenario->unselect_all();
            SetComment(EMPTY_OUSTRING);
        }
    }
}

void ScScenarioListBox::Select()
IMPL_LINK_NOARG(ScScenarioWindow, SelectHdl, weld::TreeView&, void)
{
    if( const ScenarioEntry* pEntry = GetSelectedScenarioEntry() )
        mrParent.SetComment( pEntry->maComment );
    if (const ScenarioEntry* pEntry = GetSelectedScenarioEntry())
        SetComment(pEntry->maComment);
}

void ScScenarioListBox::DoubleClick()
IMPL_LINK_NOARG(ScScenarioWindow, DoubleClickHdl, weld::TreeView&, bool)
{
    SelectScenario();
    return true;
}

bool ScScenarioListBox::EventNotify( NotifyEvent& rNEvt )
IMPL_LINK(ScScenarioWindow, KeyInputHdl, const KeyEvent&, rKEvt, bool)
{
    bool bHandled = false;

    if( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
    vcl::KeyCode aCode = rKEvt.GetKeyCode();
    switch( aCode.GetCode() )
    {
        vcl::KeyCode aCode = rNEvt.GetKeyEvent()->GetKeyCode();
        switch( aCode.GetCode() )
        {
            case KEY_RETURN:
                SelectScenario();
                bHandled = true;
            break;
            case KEY_DELETE:
                DeleteScenario();
                bHandled = true;
            break;
        }
    }
    else if ( rNEvt.GetType() == MouseNotifyEvent::COMMAND && GetSelectedEntryCount() )
    {
        const CommandEvent* pCEvt = rNEvt.GetCommandEvent();
        if ( pCEvt && pCEvt->GetCommand() == CommandEventId::ContextMenu )
        {
            if( const ScenarioEntry* pEntry = GetSelectedScenarioEntry() )
            {
                if( !pEntry->mbProtected )
                {
                    VclBuilder aBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "modules/scalc/ui/scenariomenu.ui", "");
                    VclPtr<PopupMenu> aPopup(aBuilder.get_menu("menu"));
                    sal_uInt16 nId = aPopup->Execute(this, pCEvt->GetMousePosPixel());
                    OString sIdent(aPopup->GetItemIdent(nId));
                    if (sIdent == "delete")
                        DeleteScenario();
                    else if (sIdent == "edit")
                        EditScenario();
                }
            }
        case KEY_RETURN:
            SelectScenario();
            bHandled = true;
        }
        break;
        case KEY_DELETE:
            DeleteScenario();
            bHandled = true;
        break;
    }

    return bHandled || ListBox::EventNotify(rNEvt);
    return bHandled;
}

const ScScenarioListBox::ScenarioEntry* ScScenarioListBox::GetSelectedScenarioEntry() const
IMPL_LINK(ScScenarioWindow, ContextMenuHdl, const CommandEvent&, rCEvt, bool)
{
    size_t nPos = GetSelectedEntryPos();
    return (nPos < maEntries.size()) ? &maEntries[ nPos ] : nullptr;
    bool bHandled = false;

    if (rCEvt.GetCommand() == CommandEventId::ContextMenu)
    {
        if (const ScenarioEntry* pEntry = GetSelectedScenarioEntry())
        {
            if (!pEntry->mbProtected)
            {
                std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xLbScenario.get(), "modules/scalc/ui/scenariomenu.ui"));
                std::unique_ptr<weld::Menu> xPopup(xBuilder->weld_menu("menu"));
                OString sIdent(xPopup->popup_at_rect(m_xLbScenario.get(), tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1))));
                if (sIdent == "delete")
                    DeleteScenario();
                else if (sIdent == "edit")
                    EditScenario();
            }
        }
        bHandled = true;
    }

    return bHandled;
}

void ScScenarioListBox::ExecuteScenarioSlot( sal_uInt16 nSlotId )
const ScScenarioWindow::ScenarioEntry* ScScenarioWindow::GetSelectedScenarioEntry() const
{
    size_t nPos = m_xLbScenario->get_selected_index();
    return (nPos < m_aEntries.size()) ? &m_aEntries[ nPos ] : nullptr;
}

void ScScenarioWindow::ExecuteScenarioSlot(sal_uInt16 nSlotId)
{
    if( SfxViewFrame* pViewFrm = SfxViewFrame::Current() )
    {
        SfxStringItem aStringItem( nSlotId, GetSelectedEntry() );
        SfxStringItem aStringItem(nSlotId, m_xLbScenario->get_selected_text());
        pViewFrm->GetDispatcher()->ExecuteList(nSlotId,
                SfxCallMode::SLOT | SfxCallMode::RECORD, { &aStringItem } );
    }
}

void ScScenarioListBox::SelectScenario()
void ScScenarioWindow::SelectScenario()
{
    if( GetSelectedEntryCount() > 0 )
        ExecuteScenarioSlot( SID_SELECT_SCENARIO );
    if (m_xLbScenario->get_selected_index() != -1)
        ExecuteScenarioSlot(SID_SELECT_SCENARIO);
}

void ScScenarioListBox::EditScenario()
void ScScenarioWindow::EditScenario()
{
    if( GetSelectedEntryCount() > 0 )
        ExecuteScenarioSlot( SID_EDIT_SCENARIO );
    if (m_xLbScenario->get_selected_index() != -1)
        ExecuteScenarioSlot(SID_EDIT_SCENARIO);
}

void ScScenarioListBox::DeleteScenario()
void ScScenarioWindow::DeleteScenario()
{
    if( GetSelectedEntryCount() > 0 )
    if (m_xLbScenario->get_selected_index() != -1)
    {
        std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(nullptr,
        std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_xLbScenario.get(),
                                                       VclMessageType::Question, VclButtonsType::YesNo,
                                                       ScResId(STR_QUERY_DELSCENARIO)));
        xQueryBox->set_default_response(RET_YES);
        if (xQueryBox->run() == RET_YES)
            ExecuteScenarioSlot( SID_DELETE_SCENARIO );
            ExecuteScenarioSlot(SID_DELETE_SCENARIO);
    }
}

// class ScScenarioWindow ------------------------------------------------

ScScenarioWindow::ScScenarioWindow( vcl::Window* pParent, const OUString& aQH_List,
                                    const OUString& aQH_Comment)
    :   Window      ( pParent, WB_TABSTOP | WB_DIALOGCONTROL ),
        aLbScenario ( VclPtr<ScScenarioListBox>::Create(*this) ),
        aEdComment  ( VclPtr<VclMultiLineEdit>::Create(this,  WB_BORDER | WB_LEFT | WB_READONLY | WB_VSCROLL | WB_TABSTOP) )
ScScenarioWindow::ScScenarioWindow(weld::Builder& rBuilder, const OUString& aQH_List,
                                   const OUString& aQH_Comment)
    : m_xLbScenario(rBuilder.weld_tree_view("scenariolist"))
    , m_xEdComment(rBuilder.weld_text_view("scenariotext"))
{
    vcl::Font aFont( GetFont() );
    aFont.SetTransparent( true );
    aFont.SetWeight( WEIGHT_LIGHT );
    aEdComment->SetFont( aFont );
    aEdComment->SetMaxTextLen( 512 );
    aLbScenario->SetPosPixel( Point(0,0) );
    aLbScenario->SetHelpId(HID_SC_SCENWIN_TOP);
    aEdComment->SetHelpId(HID_SC_SCENWIN_BOTTOM);
    aLbScenario->Show();
    aEdComment->Show();
    m_xLbScenario->set_help_id(HID_SC_SCENWIN_TOP);
    m_xEdComment->set_help_id(HID_SC_SCENWIN_BOTTOM);

    aLbScenario->SetQuickHelpText(aQH_List);
    aEdComment->SetQuickHelpText(aQH_Comment);
    aEdComment->SetBackground( COL_LIGHTGRAY );
    m_xLbScenario->set_tooltip_text(aQH_List);
    m_xEdComment->set_tooltip_text(aQH_Comment);

    m_xLbScenario->connect_changed(LINK(this, ScScenarioWindow, SelectHdl));
    m_xLbScenario->connect_row_activated(LINK(this, ScScenarioWindow, DoubleClickHdl));
    m_xLbScenario->connect_key_press(LINK(this, ScScenarioWindow, KeyInputHdl));
    m_xLbScenario->connect_popup_menu(LINK(this, ScScenarioWindow, ContextMenuHdl));

    SfxViewFrame* pViewFrm = SfxViewFrame::Current();
    if (pViewFrm)
@@ -230,65 +212,33 @@ ScScenarioWindow::ScScenarioWindow( vcl::Window* pParent, const OUString& aQH_Li

ScScenarioWindow::~ScScenarioWindow()
{
    disposeOnce();
}

void ScScenarioWindow::dispose()
{
    aLbScenario.disposeAndClear();
    aEdComment.disposeAndClear();
    vcl::Window::dispose();
}

void ScScenarioWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
{
    const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
    Color aBgColor = rStyleSettings.GetFaceColor();

    SetBackground( aBgColor );

    Window::Paint(rRenderContext, rRect);
}

void ScScenarioWindow::NotifyState( const SfxPoolItem* pState )
{
    if( pState )
    {
        aLbScenario->Enable();
        m_xLbScenario->set_sensitive(true);

        if ( auto pStringItem = dynamic_cast<const SfxStringItem*>( pState) )
        {
            const OUString& aNewEntry( pStringItem->GetValue() );

            if ( !aNewEntry.isEmpty() )
                aLbScenario->SelectEntry( aNewEntry );
            if (!aNewEntry.isEmpty())
                m_xLbScenario->select_text(aNewEntry);
            else
                aLbScenario->SetNoSelection();
                m_xLbScenario->unselect_all();
        }
        else if ( auto pStringListItem = dynamic_cast<const SfxStringListItem*>( pState) )
        {
            aLbScenario->UpdateEntries( pStringListItem->GetList() );
            UpdateEntries(pStringListItem->GetList());
        }
    }
    else
    {
        aLbScenario->Disable();
        aLbScenario->SetNoSelection();
        m_xLbScenario->set_sensitive(false);
        m_xLbScenario->unselect_all();
    }
}

void ScScenarioWindow::Resize()
{
    Window::Resize();

    Size aSize(GetSizePixel());
    long nHeight = aSize.Height() / 2;

    aSize.setHeight( nHeight );
    aLbScenario->SetSizePixel(aSize);

    aSize.AdjustHeight( -4 );
    aEdComment->SetPosSizePixel(Point(0, nHeight + 4), aSize);
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/sidebar/CellAppearancePropertyPanel.hxx b/sc/source/ui/sidebar/CellAppearancePropertyPanel.hxx
index f23565a..3c2e1cd9 100644
--- a/sc/source/ui/sidebar/CellAppearancePropertyPanel.hxx
+++ b/sc/source/ui/sidebar/CellAppearancePropertyPanel.hxx
@@ -22,8 +22,6 @@
#include <sfx2/sidebar/ControllerItem.hxx>
#include <sfx2/sidebar/IContextChangeReceiver.hxx>
#include <svx/sidebar/PanelLayout.hxx>
#include <vcl/image.hxx>
#include <vcl/toolbox.hxx>
#include "CellBorderStyleControl.hxx"
#include "CellLineStyleControl.hxx"

diff --git a/sc/uiconfig/scalc/ui/dropmenu.ui b/sc/uiconfig/scalc/ui/dropmenu.ui
index c8d026a..1da41c0 100644
--- a/sc/uiconfig/scalc/ui/dropmenu.ui
+++ b/sc/uiconfig/scalc/ui/dropmenu.ui
@@ -1,32 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<!-- Generated with glade 3.22.1 -->
<interface domain="sc">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkMenu" id="menu">
  <object class="GtkMenu" id="contextmenu">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <child>
      <object class="GtkRadioMenuItem" id="hyperlink">
      <object class="GtkMenuItem" id="dragmodeitem">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes" context="dropmenu|hyperlink">Insert as Hyperlink</property>
        <property name="label" translatable="yes" context="dropmenu|SCSTR_DRAGMODE">Drag Mode</property>
        <property name="use_underline">True</property>
        <child type="submenu">
          <object class="GtkMenu" id="dragmodesubmenu">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <object class="GtkRadioMenuItem" id="hyperlink">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="label" translatable="yes" context="dropmenu|hyperlink">Insert as Hyperlink</property>
                <property name="use_underline">True</property>
                <property name="active">True</property>
                <property name="draw_as_radio">True</property>
              </object>
            </child>
            <child>
              <object class="GtkRadioMenuItem" id="link">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="label" translatable="yes" context="dropmenu|link">Insert as Link</property>
                <property name="use_underline">True</property>
                <property name="draw_as_radio">True</property>
                <property name="group">hyperlink</property>
              </object>
            </child>
            <child>
              <object class="GtkRadioMenuItem" id="copy">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="label" translatable="yes" context="dropmenu|copy">Insert as Copy</property>
                <property name="use_underline">True</property>
                <property name="draw_as_radio">True</property>
                <property name="group">hyperlink</property>
              </object>
            </child>
          </object>
        </child>
      </object>
    </child>
    <child>
      <object class="GtkRadioMenuItem" id="link">
      <object class="GtkMenuItem" id="displayitem">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes" context="dropmenu|link">Insert as Link</property>
        <property name="label" translatable="yes" context="dropmenu|SCSTR_DISPLAY">Display</property>
        <property name="use_underline">True</property>
      </object>
    </child>
    <child>
      <object class="GtkRadioMenuItem" id="copy">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes" context="dropmenu|copy">Insert as Copy</property>
        <property name="use_underline">True</property>
        <child type="submenu">
          <object class="GtkMenu" id="displaymenu">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
          </object>
        </child>
      </object>
    </child>
  </object>
diff --git a/sc/uiconfig/scalc/ui/navigatorpanel.ui b/sc/uiconfig/scalc/ui/navigatorpanel.ui
index c8cb347..48fa789 100644
--- a/sc/uiconfig/scalc/ui/navigatorpanel.ui
+++ b/sc/uiconfig/scalc/ui/navigatorpanel.ui
@@ -1,10 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<!-- Generated with glade 3.22.1 -->
<interface domain="sc">
  <requires lib="gtk+" version="3.18"/>
  <object class="GtkAdjustment" id="adjustment1">
    <property name="upper">100</property>
    <property name="step_increment">1</property>
    <property name="page_increment">10</property>
  </object>
  <object class="GtkAdjustment" id="adjustment2">
    <property name="upper">100</property>
    <property name="step_increment">1</property>
    <property name="page_increment">10</property>
  </object>
  <object class="GtkMenu" id="dragmodemenu">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <child>
      <object class="GtkRadioMenuItem" id="hyperlink">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes" context="navigatorpanel|hyperlink">Insert as Hyperlink</property>
        <property name="use_underline">True</property>
        <property name="active">True</property>
        <property name="draw_as_radio">True</property>
      </object>
    </child>
    <child>
      <object class="GtkRadioMenuItem" id="link">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes" context="navigatorpanel|link">Insert as Link</property>
        <property name="use_underline">True</property>
        <property name="draw_as_radio">True</property>
        <property name="group">hyperlink</property>
      </object>
    </child>
    <child>
      <object class="GtkRadioMenuItem" id="copy">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes" context="navigatorpanel|copy">Insert as Copy</property>
        <property name="use_underline">True</property>
        <property name="draw_as_radio">True</property>
        <property name="group">hyperlink</property>
      </object>
    </child>
  </object>
  <object class="GtkTreeStore" id="liststore1">
    <columns>
      <!-- column-name expander -->
      <column type="GdkPixbuf"/>
      <!-- column-name text -->
      <column type="gchararray"/>
      <!-- column-name id -->
      <column type="gchararray"/>
      <!-- column-name weight -->
      <column type="gint"/>
      <!-- column-name sensitive -->
      <column type="gboolean"/>
    </columns>
  </object>
  <object class="GtkTreeStore" id="liststore2">
    <columns>
      <!-- column-name text -->
      <column type="gchararray"/>
      <!-- column-name id -->
      <column type="gchararray"/>
    </columns>
  </object>
  <object class="GtkGrid" id="NavigatorPanel">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="hexpand">True</property>
    <property name="vexpand">True</property>
    <property name="border_width">6</property>
    <child>
      <object class="GtkGrid">
@@ -19,9 +87,9 @@
          <object class="GtkGrid">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="hexpand">True</property>
            <property name="row_spacing">6</property>
            <property name="column_spacing">12</property>
            <property name="hexpand">True</property>
            <child>
              <object class="GtkLabel" id="label1">
                <property name="visible">True</property>
@@ -51,11 +119,12 @@
              </packing>
            </child>
            <child>
              <object class="sclo-ColumnEdit" id="column">
              <object class="GtkSpinButton" id="column">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="tooltip_text" translatable="yes" context="navigatorpanel|column|tooltip_text">Column</property>
                <property name="hexpand">True</property>
                <property name="adjustment">adjustment1</property>
              </object>
              <packing>
                <property name="left_attach">1</property>
@@ -63,11 +132,12 @@
              </packing>
            </child>
            <child>
              <object class="sclo-RowEdit" id="row">
              <object class="GtkSpinButton" id="row">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="tooltip_text" translatable="yes" context="navigatorpanel|row|tooltip_text">Row</property>
                <property name="hexpand">True</property>
                <property name="adjustment">adjustment2</property>
              </object>
              <packing>
                <property name="left_attach">1</property>
@@ -75,21 +145,21 @@
              </packing>
            </child>
            <child>
              <object class="GtkToolbar" id="toolbox">
              <object class="GtkToolbar" id="toolbox1">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="toolbar_style">icons</property>
                <property name="show_arrow">False</property>
                <child>
                  <object class="GtkToolButton" id="datarange">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="tooltip_text" translatable="yes" context="navigatorpanel|datarange|tooltip_text">Data Range</property>
                    <property name="action_name">datarange</property>
                    <property name="icon_name">sc/res/na03.png</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="homogeneous">True</property>
                    <property name="homogeneous">False</property>
                  </packing>
                </child>
                <child>
@@ -97,12 +167,11 @@
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="tooltip_text" translatable="yes" context="navigatorpanel|start|tooltip_text">Start</property>
                    <property name="action_name">start</property>
                    <property name="icon_name">sc/res/na05.png</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="homogeneous">True</property>
                    <property name="homogeneous">False</property>
                  </packing>
                </child>
                <child>
@@ -110,51 +179,59 @@
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="tooltip_text" translatable="yes" context="navigatorpanel|end|tooltip_text">End</property>
                    <property name="action_name">end</property>
                    <property name="icon_name">sc/res/na06.png</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="homogeneous">True</property>
                    <property name="homogeneous">False</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkToolButton" id="contents">
                  <object class="GtkToggleToolButton" id="contents">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="tooltip_text" translatable="yes" context="navigatorpanel|contents|tooltip_text">Contents</property>
                    <property name="action_name">contents</property>
                    <property name="icon_name">sc/res/na011.png</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="homogeneous">True</property>
                    <property name="homogeneous">False</property>
                  </packing>
                </child>
              </object>
              <packing>
                <property name="left_attach">2</property>
                <property name="top_attach">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkToolbar" id="toolbox2">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="toolbar_style">icons</property>
                <property name="show_arrow">False</property>
                <child>
                  <object class="GtkToolButton" id="toggle">
                  <object class="GtkToggleToolButton" id="toggle">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="tooltip_text" translatable="yes" context="navigatorpanel|toggle|tooltip_text">Toggle</property>
                    <property name="action_name">toggle</property>
                    <property name="icon_name">sc/res/na010.png</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="homogeneous">True</property>
                    <property name="homogeneous">False</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkToolButton" id="scenarios">
                  <object class="GtkToggleToolButton" id="scenarios">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="tooltip_text" translatable="yes" context="navigatorpanel|scenarios|tooltip_text">Scenarios</property>
                    <property name="action_name">scenarios</property>
                    <property name="icon_name">sc/res/na07.png</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="homogeneous">True</property>
                    <property name="homogeneous">False</property>
                  </packing>
                </child>
                <child>
@@ -162,19 +239,17 @@
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="tooltip_text" translatable="yes" context="navigatorpanel|dragmode|tooltip_text">Drag Mode</property>
                    <property name="action_name">dragmode</property>
                    <property name="icon_name">sc/res/na09.png</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="homogeneous">True</property>
                    <property name="homogeneous">False</property>
                  </packing>
                </child>
              </object>
              <packing>
                <property name="left_attach">2</property>
                <property name="top_attach">0</property>
                <property name="height">2</property>
                <property name="top_attach">1</property>
              </packing>
            </child>
          </object>
@@ -184,7 +259,7 @@
          </packing>
        </child>
        <child>
          <object class="GtkComboBox" id="documents">
          <object class="GtkComboBoxText" id="documents">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="tooltip_text" translatable="yes" context="navigatorpanel|documents|tooltip_text">Document</property>
@@ -200,14 +275,46 @@
          </packing>
        </child>
        <child>
          <object class="GtkBox" id="contentbox">
          <object class="GtkScrolledWindow">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="can_focus">True</property>
            <property name="hexpand">True</property>
            <property name="vexpand">True</property>
            <property name="orientation">vertical</property>
            <property name="shadow_type">in</property>
            <child>
              <placeholder/>
              <object class="GtkTreeView" id="contentbox">
                <property name="width_request">-1</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <property name="model">liststore1</property>
                <property name="headers_visible">False</property>
                <property name="search_column">1</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="Macro Library List-selection1"/>
                </child>
                <child>
                  <object class="GtkTreeViewColumn" id="treeviewcolumn2">
                    <property name="spacing">6</property>
                    <child>
                      <object class="GtkCellRendererPixbuf" id="cellrenderertext4"/>
                      <attributes>
                        <attribute name="sensitive">4</attribute>
                        <attribute name="pixbuf">0</attribute>
                      </attributes>
                    </child>
                    <child>
                      <object class="GtkCellRendererText" id="cellrenderertext2"/>
                      <attributes>
                        <attribute name="sensitive">4</attribute>
                        <attribute name="text">1</attribute>
                      </attributes>
                    </child>
                  </object>
                </child>
              </object>
            </child>
          </object>
          <packing>
@@ -217,13 +324,76 @@
        </child>
        <child>
          <object class="GtkBox" id="scenariobox">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="no_show_all">True</property>
            <property name="hexpand">True</property>
            <property name="vexpand">True</property>
            <property name="orientation">vertical</property>
            <property name="spacing">6</property>
            <property name="homogeneous">True</property>
            <child>
              <placeholder/>
              <object class="GtkScrolledWindow">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="hexpand">True</property>
                <property name="vexpand">True</property>
                <property name="shadow_type">in</property>
                <child>
                  <object class="GtkTreeView" id="scenariolist">
                    <property name="width_request">-1</property>
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="receives_default">True</property>
                    <property name="hexpand">True</property>
                    <property name="vexpand">True</property>
                    <property name="model">liststore2</property>
                    <property name="headers_visible">False</property>
                    <property name="search_column">0</property>
                    <property name="show_expanders">False</property>
                    <child internal-child="selection">
                      <object class="GtkTreeSelection"/>
                    </child>
                    <child>
                      <object class="GtkTreeViewColumn" id="treeviewcolumn1">
                        <property name="spacing">6</property>
                        <child>
                          <object class="GtkCellRendererText" id="cellrenderertext3"/>
                          <attributes>
                            <attribute name="text">0</attribute>
                          </attributes>
                        </child>
                      </object>
                    </child>
                  </object>
                </child>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkScrolledWindow">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="shadow_type">in</property>
                <child>
                  <object class="GtkTextView" id="scenariotext">
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="editable">False</property>
                    <property name="wrap_mode">word</property>
                    <property name="cursor_visible">False</property>
                    <property name="accepts_tab">False</property>
                  </object>
                </child>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">1</property>
              </packing>
            </child>
          </object>
          <packing>
diff --git a/sd/source/ui/dlg/sdtreelb.cxx b/sd/source/ui/dlg/sdtreelb.cxx
index b27f880..300fef7 100644
--- a/sd/source/ui/dlg/sdtreelb.cxx
+++ b/sd/source/ui/dlg/sdtreelb.cxx
@@ -340,8 +340,9 @@ IMPL_LINK_NOARG(SdPageObjsTLV, MouseReleaseHdl, const MouseEvent&, bool)
    return false;
}

IMPL_LINK_NOARG(SdPageObjsTLV, DragBeginHdl, weld::TreeView&, bool)
IMPL_LINK(SdPageObjsTLV, DragBeginHdl, bool&, rUnsetDragIcon, bool)
{
    rUnsetDragIcon = false;
    return StartDrag();
}

diff --git a/sd/source/ui/inc/sdtreelb.hxx b/sd/source/ui/inc/sdtreelb.hxx
index c2b3e96..c9fce34 100644
--- a/sd/source/ui/inc/sdtreelb.hxx
+++ b/sd/source/ui/inc/sdtreelb.hxx
@@ -129,7 +129,7 @@ private:
    DECL_LINK(AsyncSelectHdl, void*, void);
    DECL_LINK(RowActivatedHdl, weld::TreeView&, bool);
    DECL_LINK(AsyncRowActivatedHdl, void*, void);
    DECL_LINK(DragBeginHdl, weld::TreeView&, bool);
    DECL_LINK(DragBeginHdl, bool&, bool);
    DECL_LINK(KeyInputHdl, const KeyEvent&, bool);

    /** Determine whether the specified page belongs to the current show
diff --git a/sfx2/source/doc/templatedlg.cxx b/sfx2/source/doc/templatedlg.cxx
index 2fc118bfb..592fcd1 100644
--- a/sfx2/source/doc/templatedlg.cxx
+++ b/sfx2/source/doc/templatedlg.cxx
@@ -175,11 +175,11 @@ SfxTemplateManagerDlg::SfxTemplateManagerDlg(weld::Window *pParent)
{
    // Create popup menus
    OUString sBmp(BMP_ACTION_REFRESH);
    mxActionBar->insert_item(0, MNI_ACTION_NEW_FOLDER, SfxResId(STR_CATEGORY_NEW), &sBmp, nullptr, false);
    mxActionBar->insert_item(1, MNI_ACTION_RENAME_FOLDER, SfxResId(STR_CATEGORY_RENAME), nullptr, nullptr, false);
    mxActionBar->insert_item(2, MNI_ACTION_DELETE_FOLDER, SfxResId(STR_CATEGORY_DELETE), nullptr, nullptr, false);
    mxActionBar->insert_item(0, MNI_ACTION_NEW_FOLDER, SfxResId(STR_CATEGORY_NEW), &sBmp, nullptr, TRISTATE_INDET);
    mxActionBar->insert_item(1, MNI_ACTION_RENAME_FOLDER, SfxResId(STR_CATEGORY_RENAME), nullptr, nullptr, TRISTATE_INDET);
    mxActionBar->insert_item(2, MNI_ACTION_DELETE_FOLDER, SfxResId(STR_CATEGORY_DELETE), nullptr, nullptr, TRISTATE_INDET);
    mxActionBar->insert_separator(3, "separator");
    mxActionBar->insert_item(4, MNI_ACTION_REFRESH, SfxResId(STR_ACTION_REFRESH), &sBmp, nullptr, false);
    mxActionBar->insert_item(4, MNI_ACTION_REFRESH, SfxResId(STR_ACTION_REFRESH), &sBmp, nullptr, TRISTATE_INDET);
    mxActionBar->connect_selected(LINK(this,SfxTemplateManagerDlg,MenuSelectHdl));

    mxLocalView->setItemMaxTextLength(TEMPLATE_ITEM_MAX_TEXT_LENGTH);
diff --git a/solenv/bin/native-code.py b/solenv/bin/native-code.py
index e09962d..aca0aac 100755
--- a/solenv/bin/native-code.py
+++ b/solenv/bin/native-code.py
@@ -498,7 +498,6 @@ constructor_map = {
custom_widgets = [
    'BookmarksBox',
    'CategoryListBox',
    'ColumnEdit',
    'ContentListBox',
    'ContextVBox',
    'CustomAnimationList',
@@ -511,7 +510,6 @@ custom_widgets = [
    'PriorityMergedHBox',
    'PropertyControl',
    'RecentDocsView',
    'RowEdit',
    'SearchBox',
    'SearchResultsBox',
    'SidebarToolBox',
diff --git a/svx/inc/galbrws2.hxx b/svx/inc/galbrws2.hxx
index 2f904dc..7d72594 100644
--- a/svx/inc/galbrws2.hxx
+++ b/svx/inc/galbrws2.hxx
@@ -111,7 +111,7 @@ private:
                        DECL_LINK( PopupMenuHdl, const CommandEvent&, bool );
                        DECL_LINK( KeyInputHdl, const KeyEvent&, bool );
                        DECL_LINK( RowActivatedHdl, weld::TreeView&, bool );
                        DECL_LINK( DragBeginHdl, weld::TreeView&, bool );
                        DECL_LINK( DragBeginHdl, bool&, bool );
                        DECL_LINK( VisRowsScrolledHdl, weld::TreeView&, void );
                        DECL_LINK( SizeAllocHdl, const Size&, void );

diff --git a/svx/source/form/tabwin.cxx b/svx/source/form/tabwin.cxx
index 063f00a..4c9dec9 100644
--- a/svx/source/form/tabwin.cxx
+++ b/svx/source/form/tabwin.cxx
@@ -85,8 +85,10 @@ void FmFieldWin::addToList(const uno::Reference< container::XNameAccess>& i_xCol
    }
}

IMPL_LINK_NOARG(FmFieldWin, DragBeginHdl, weld::TreeView&, bool)
IMPL_LINK(FmFieldWin, DragBeginHdl, bool&, rUnsetDragIcon, bool)
{
    rUnsetDragIcon = false;

    ColumnInfo* pSelected = reinterpret_cast<ColumnInfo*>(m_xListBox->get_selected_id().toInt64());
    if (!pSelected)
    {
diff --git a/svx/source/gallery2/galbrws2.cxx b/svx/source/gallery2/galbrws2.cxx
index 325d8e5..42856a8 100644
--- a/svx/source/gallery2/galbrws2.cxx
+++ b/svx/source/gallery2/galbrws2.cxx
@@ -476,8 +476,9 @@ bool GalleryBrowser2::StartDrag()
    return m_xHelper->StartDrag();
}

IMPL_LINK_NOARG(GalleryBrowser2, DragBeginHdl, weld::TreeView&, bool)
IMPL_LINK(GalleryBrowser2, DragBeginHdl, bool&, rUnsetDragIcon, bool)
{
    rUnsetDragIcon = false;
    return StartDrag();
}

diff --git a/svx/source/inc/tabwin.hxx b/svx/source/inc/tabwin.hxx
index bffb4c9..68cef73 100644
--- a/svx/source/inc/tabwin.hxx
+++ b/svx/source/inc/tabwin.hxx
@@ -50,7 +50,7 @@ class FmFieldWin : public SfxModelessDialogController
    void addToList(const css::uno::Reference<css::container::XNameAccess>& i_xColumns);

    DECL_LINK(RowActivatedHdl, weld::TreeView&, bool);
    DECL_LINK(DragBeginHdl, weld::TreeView&, bool);
    DECL_LINK(DragBeginHdl, bool&, bool);
public:
    FmFieldWin(SfxBindings *pBindings, SfxChildWindow *pMgr, weld::Window* pParent);

diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index cd076d5..14da859 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -643,10 +643,19 @@ Image createImage(const VirtualDevice& rDevice)

sal_uInt16 insert_to_menu(sal_uInt16 nLastId, PopupMenu* pMenu, int pos, const OUString& rId,
                          const OUString& rStr, const OUString* pIconName,
                          const VirtualDevice* pImageSurface, bool bCheck)
                          const VirtualDevice* pImageSurface, TriState eCheckRadioFalse)
{
    const sal_uInt16 nNewid = nLastId + 1;
    pMenu->InsertItem(nNewid, rStr, bCheck ? MenuItemBits::CHECKABLE : MenuItemBits::NONE,

    MenuItemBits nBits;
    if (eCheckRadioFalse == TRISTATE_TRUE)
        nBits = MenuItemBits::CHECKABLE;
    else if (eCheckRadioFalse == TRISTATE_FALSE)
        nBits = MenuItemBits::CHECKABLE | MenuItemBits::RADIOCHECK;
    else
        nBits = MenuItemBits::NONE;

    pMenu->InsertItem(nNewid, rStr, nBits,
                      OUStringToOString(rId, RTL_TEXTENCODING_UTF8), pos == -1 ? MENU_APPEND : pos);
    if (pIconName)
    {
@@ -705,6 +714,10 @@ public:
    {
        m_xMenu->SetItemText(m_xMenu->GetItemId(rIdent), rLabel);
    }
    virtual OUString get_label(const OString& rIdent) const override
    {
        return m_xMenu->GetItemText(m_xMenu->GetItemId(rIdent));
    }
    virtual void set_visible(const OString& rIdent, bool bShow) override
    {
        m_xMenu->ShowItem(m_xMenu->GetItemId(rIdent), bShow);
@@ -712,10 +725,10 @@ public:
    virtual void clear() override { m_xMenu->Clear(); }
    virtual void insert(int pos, const OUString& rId, const OUString& rStr,
                        const OUString* pIconName, VirtualDevice* pImageSurface,
                        bool bCheck) override
                        TriState eCheckRadioFalse) override
    {
        m_nLastId
            = insert_to_menu(m_nLastId, m_xMenu, pos, rId, rStr, pIconName, pImageSurface, bCheck);
            = insert_to_menu(m_nLastId, m_xMenu, pos, rId, rStr, pIconName, pImageSurface, eCheckRadioFalse);
    }
    virtual void insert_separator(int pos, const OUString& rId) override
    {
@@ -2508,10 +2521,10 @@ public:

    virtual void insert_item(int pos, const OUString& rId, const OUString& rStr,
                             const OUString* pIconName, VirtualDevice* pImageSurface,
                             bool bCheck) override
                             TriState eCheckRadioFalse) override
    {
        m_nLastId = insert_to_menu(m_nLastId, m_xMenuButton->GetPopupMenu(), pos, rId, rStr,
                                   pIconName, pImageSurface, bCheck);
                                   pIconName, pImageSurface, eCheckRadioFalse);
    }

    virtual void insert_separator(int pos, const OUString& rId) override
@@ -3744,6 +3757,10 @@ public:
    {
        if (col == -1)
        {
            auto nFlags = pEntry->GetFlags() & ~SvTLEntryFlags::SEMITRANSPARENT;
            if (!bSensitive)
                nFlags = nFlags | SvTLEntryFlags::SEMITRANSPARENT;
            pEntry->SetFlags(nFlags);
            const sal_uInt16 nCount = pEntry->ItemCount();
            for (sal_uInt16 nCur = 0; nCur < nCount; ++nCur)
            {
@@ -4573,7 +4590,8 @@ IMPL_LINK_NOARG(SalInstanceTreeView, ModelChangedHdl, SvTreeListBox*, void)

IMPL_LINK_NOARG(SalInstanceTreeView, StartDragHdl, SvTreeListBox*, bool)
{
    if (m_aDragBeginHdl.Call(*this))
    bool bUnsetDragIcon(false); // ignored for vcl
    if (m_aDragBeginHdl.Call(bUnsetDragIcon))
        return true;
    g_DragSource = this;
    return false;
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index a1f5c28..6901202 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -1952,7 +1952,10 @@ protected:
    void ensure_drag_begin_end()
    {
        if (!m_nDragBeginSignalId)
            m_nDragBeginSignalId = g_signal_connect(m_pWidget, "drag-begin", G_CALLBACK(signalDragBegin), this);
        {
            // using "after" due to https://gitlab.gnome.org/GNOME/pygobject/issues/251
            m_nDragBeginSignalId = g_signal_connect_after(m_pWidget, "drag-begin", G_CALLBACK(signalDragBegin), this);
        }
        if (!m_nDragEndSignalId)
            m_nDragEndSignalId = g_signal_connect(m_pWidget, "drag-end", G_CALLBACK(signalDragEnd), this);
    }
@@ -2129,14 +2132,22 @@ private:
    bool signal_motion(const GdkEventMotion* pEvent)
    {
        GtkTargetList* pDragData = (m_eDragAction != 0 && m_nPressedButton != -1 && m_xDragSource.is()) ? gtk_drag_source_get_target_list(m_pWidget) : nullptr;
        if (pDragData && gtk_drag_check_threshold(m_pWidget, m_nPressStartX, m_nPressStartY, pEvent->x, pEvent->y) && !do_signal_drag_begin())
        bool bUnsetDragIcon(false);
        if (pDragData && gtk_drag_check_threshold(m_pWidget, m_nPressStartX, m_nPressStartY, pEvent->x, pEvent->y) && !do_signal_drag_begin(bUnsetDragIcon))
        {
            gtk_drag_begin_with_coordinates(m_pWidget,
                                            pDragData,
                                            m_eDragAction,
                                            m_nPressedButton,
                                            const_cast<GdkEvent*>(reinterpret_cast<const GdkEvent*>(pEvent)),
                                            m_nPressStartX, m_nPressStartY);
            GdkDragContext* pContext = gtk_drag_begin_with_coordinates(m_pWidget,
                                                                       pDragData,
                                                                       m_eDragAction,
                                                                       m_nPressedButton,
                                                                       const_cast<GdkEvent*>(reinterpret_cast<const GdkEvent*>(pEvent)),
                                                                       m_nPressStartX, m_nPressStartY);

            if (pContext && bUnsetDragIcon)
            {
                cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0);
                gtk_drag_set_icon_surface(pContext, surface);
            }

            m_nPressedButton = -1;
            return false;
        }
@@ -2240,18 +2251,25 @@ private:
        }
    }

    virtual bool do_signal_drag_begin()
    virtual bool do_signal_drag_begin(bool& rUnsetDragIcon)
    {
        rUnsetDragIcon = false;
        return false;
    }

    void signal_drag_begin(GdkDragContext* context)
    {
        if (do_signal_drag_begin())
        bool bUnsetDragIcon(false);
        if (do_signal_drag_begin(bUnsetDragIcon))
        {
            launch_drag_cancel(context);
            return;
        }
        if (bUnsetDragIcon)
        {
            cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0);
            gtk_drag_set_icon_surface(context, surface);
        }
        if (!m_xDragSource)
            return;
        m_xDragSource->setActiveDragSource();
@@ -3314,7 +3332,7 @@ public:

    void insert_item(int pos, const OUString& rId, const OUString& rStr,
                     const OUString* pIconName, const VirtualDevice* pImageSurface,
                     bool bCheck)
                     TriState eCheckRadioFalse)
    {
        GtkWidget* pImage = nullptr;
        if (pIconName && !pIconName->isEmpty())
@@ -3334,7 +3352,7 @@ public:
        {
            GtkWidget *pBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
            GtkWidget *pLabel = gtk_label_new(MapToGtkAccelerator(rStr).getStr());
            pItem = bCheck ? gtk_check_menu_item_new() : gtk_menu_item_new();
            pItem = eCheckRadioFalse != TRISTATE_INDET ? gtk_check_menu_item_new() : gtk_menu_item_new();
            gtk_container_add(GTK_CONTAINER(pBox), pImage);
            gtk_container_add(GTK_CONTAINER(pBox), pLabel);
            gtk_container_add(GTK_CONTAINER(pItem), pBox);
@@ -3342,9 +3360,13 @@ public:
        }
        else
        {
            pItem = bCheck ? gtk_check_menu_item_new_with_mnemonic(MapToGtkAccelerator(rStr).getStr())
                           : gtk_menu_item_new_with_mnemonic(MapToGtkAccelerator(rStr).getStr());
            pItem = eCheckRadioFalse != TRISTATE_INDET ? gtk_check_menu_item_new_with_mnemonic(MapToGtkAccelerator(rStr).getStr())
                                                       : gtk_menu_item_new_with_mnemonic(MapToGtkAccelerator(rStr).getStr());
        }

        if (eCheckRadioFalse == TRISTATE_FALSE)
            gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(pItem), true);

        gtk_buildable_set_name(GTK_BUILDABLE(pItem), OUStringToOString(rId, RTL_TEXTENCODING_UTF8).getStr());
        gtk_menu_shell_append(GTK_MENU_SHELL(m_pMenu), pItem);
        gtk_widget_show(pItem);
@@ -6982,9 +7004,9 @@ public:
    }

    virtual void insert_item(int pos, const OUString& rId, const OUString& rStr,
                        const OUString* pIconName, VirtualDevice* pImageSurface, bool bCheck) override
                        const OUString* pIconName, VirtualDevice* pImageSurface, TriState eCheckRadioFalse) override
    {
        MenuHelper::insert_item(pos, rId, rStr, pIconName, pImageSurface, bCheck);
        MenuHelper::insert_item(pos, rId, rStr, pIconName, pImageSurface, eCheckRadioFalse);
    }

    virtual void insert_separator(int pos, const OUString& rId) override
@@ -7256,6 +7278,11 @@ public:
        set_item_label(rIdent, rLabel);
    }

    virtual OUString get_label(const OString& rIdent) const override
    {
        return get_item_label(rIdent);
    }

    virtual void insert_separator(int pos, const OUString& rId) override
    {
        MenuHelper::insert_separator(pos, rId);
@@ -7269,7 +7296,7 @@ public:

    virtual void insert(int pos, const OUString& rId, const OUString& rStr,
                        const OUString* pIconName, VirtualDevice* pImageSurface,
                        bool bCheck) override
                        TriState eCheckRadioFalse) override
    {
        GtkWidget* pImage = nullptr;
        if (pIconName)
@@ -7290,7 +7317,7 @@ public:
        {
            GtkWidget *pBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
            GtkWidget *pLabel = gtk_label_new(MapToGtkAccelerator(rStr).getStr());
            pItem = bCheck ? gtk_check_menu_item_new() : gtk_menu_item_new();
            pItem = eCheckRadioFalse != TRISTATE_INDET ? gtk_check_menu_item_new() : gtk_menu_item_new();
            gtk_container_add(GTK_CONTAINER(pBox), pImage);
            gtk_container_add(GTK_CONTAINER(pBox), pLabel);
            gtk_container_add(GTK_CONTAINER(pItem), pBox);
@@ -7298,9 +7325,13 @@ public:
        }
        else
        {
            pItem = bCheck ? gtk_check_menu_item_new_with_mnemonic(MapToGtkAccelerator(rStr).getStr())
                           : gtk_menu_item_new_with_mnemonic(MapToGtkAccelerator(rStr).getStr());
            pItem = eCheckRadioFalse != TRISTATE_INDET ? gtk_check_menu_item_new_with_mnemonic(MapToGtkAccelerator(rStr).getStr())
                                                       : gtk_menu_item_new_with_mnemonic(MapToGtkAccelerator(rStr).getStr());
        }

        if (eCheckRadioFalse == TRISTATE_FALSE)
            gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(pItem), true);

        gtk_buildable_set_name(GTK_BUILDABLE(pItem), OUStringToOString(rId, RTL_TEXTENCODING_UTF8).getStr());
        gtk_menu_shell_append(GTK_MENU_SHELL(m_pMenu), pItem);
        gtk_widget_show(pItem);
@@ -10549,9 +10580,9 @@ public:
        return g_DragSource;
    }

    virtual bool do_signal_drag_begin() override
    virtual bool do_signal_drag_begin(bool& rUnsetDragIcon) override
    {
        if (m_aDragBeginHdl.Call(*this))
        if (m_aDragBeginHdl.Call(rUnsetDragIcon))
            return true;
        g_DragSource = this;
        return false;
@@ -11857,8 +11888,9 @@ public:
        do_enable_drag_source(rHelper, eDNDConstants);
    }

    virtual bool do_signal_drag_begin() override
    virtual bool do_signal_drag_begin(bool& rUnsetDragIcon) override
    {
        rUnsetDragIcon = false;
        if (m_aDragBeginHdl.Call(*this))
            return true;
        return false;