/* This file is part of KDDockWidgets. SPDX-FileCopyrightText: 2020 Klarälvdalens Datakonsult AB, a KDAB Group company Author: Sérgio Martins SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only Contact KDAB at for commercial licensing options. */ /** * @file Helper class so dockwidgets can be restored to their previous position. * * @author Sérgio Martins \ */ #ifndef KDDOCKWIDGETS_POSITION_P_H #define KDDOCKWIDGETS_POSITION_P_H #include "kddockwidgets/docks_export.h" #include "kddockwidgets/LayoutSaver.h" #include "ObjectGuard_p.h" #include #include #include namespace KDDockWidgets { namespace Core { class Item; class DockWidget; class Group; class Layout; class LayoutingHost; } /** * @internal * @brief Represents the DockWidget's last positions. * * DockWidgets know where they were in the main window even after they're closed, so that * showing them again puts them in their previous place. * * This class is called Positions since the window might also have a floating position memorized. * * This class is not directly related to LayoutSaver which saves/restores in bulk. It's more * for redocking back when you double-click a floating dock widget title-bar for example. */ class DOCKS_EXPORT_FOR_UNIT_TESTS Positions { KDDW_DELETE_COPY_CTOR(Positions) public: typedef std::shared_ptr Ptr; Positions() = default; ~Positions(); void deserialize(const LayoutSaver::Position &); LayoutSaver::Position serialize() const; ///@brief The tab index in case the dock widget was in a TabWidget, -1 otherwise. int m_tabIndex = -1; ///@brief true if the DockWidget was floating when it was closed bool m_wasFloating = false; ///@brief Adds the last layout item where the dock widget was (or is) /// This is called at the moment the dock widget is added into any layout void addPlaceholderItem(Core::Item *placeholder); bool containsPlaceholder(Core::Item *) const; void removePlaceholders(); ///@brief Removes the placeholders that belong to this multisplitter void removePlaceholders(const Core::LayoutingHost *); ///@brief Removes the placeholders that reference a FloatingWindow void removeNonMainWindowPlaceholders(); ///@brief Removes the placeholders that reference a MainWindow void removeMainWindowPlaceholders(); ///@brief removes the Item @p placeholder void removePlaceholder(Core::Item *placeholder); /// The amount of placeholders we know about /// this will be either: /// 0 - if dock widget hasn't been docked /// 1 - if it has been docked /// 2 - if it has been docked to main window and to a floating window /// We don't support memorizing more than 1 main window or more than 1 floating window int placeholderCount() const; void saveTabIndex(int tabIndex, bool isFloating) { m_tabIndex = tabIndex; m_wasFloating = isFloating; } void setLastFloatingGeometry(Rect geo) { m_lastFloatingGeometry = geo; } bool wasFloating() const { return m_wasFloating; } Rect lastFloatingGeometry() const { return m_lastFloatingGeometry; } /// Returns the placeholder Item where the dock widget *was* /// Pass current to exclude the current layout Item where it's living Core::Item *lastItem(Core::Item *current = nullptr) const; /// convenience overload Core::Item *lastItem(const Core::DockWidget *current) const; int lastTabIndex() const { return m_tabIndex; } Rect lastOverlayedGeometry(SideBarLocation loc) const { auto it = m_lastOverlayedGeometries.find(loc); return it == m_lastOverlayedGeometries.cend() ? Rect() : it->second; } void setLastOverlayedGeometry(SideBarLocation loc, Rect rect) { m_lastOverlayedGeometries[loc] = rect; } private: /// A RAII class so we don't forget to unref struct ItemRef { explicit ItemRef(KDBindings::ConnectionHandle conn, Core::Item *); ~ItemRef(); bool isInMainWindow() const; Core::ObjectGuard item; KDBindings::ConnectionHandle connection; private: KDDW_DELETE_COPY_CTOR(ItemRef) }; bool itemIsBeingDestroyed(Core::Item *) const; // The last places where this dock widget was (or is), so it can be restored when // setFloating(false) or show() is called. std::vector> m_placeholders; Rect m_lastFloatingGeometry; std::unordered_map m_lastOverlayedGeometries; bool m_clearing = false; // to prevent re-entrancy }; } #endif