| 1 | /* |
| 2 | This file is part of the KDE project |
| 3 | SPDX-FileCopyrightText: 1999 Simon Hausmann <hausmann@kde.org> |
| 4 | SPDX-FileCopyrightText: 1999 David Faure <faure@kde.org> |
| 5 | |
| 6 | SPDX-License-Identifier: LGPL-2.0-or-later |
| 7 | */ |
| 8 | |
| 9 | #ifndef __kpartmanager_h__ |
| 10 | #define __kpartmanager_h__ |
| 11 | |
| 12 | #include <kparts/kparts_export.h> |
| 13 | |
| 14 | #include <QWidget> |
| 15 | #include <memory> |
| 16 | |
| 17 | namespace KParts |
| 18 | { |
| 19 | class Part; |
| 20 | |
| 21 | class PartManagerPrivate; |
| 22 | |
| 23 | /*! |
| 24 | * \class KParts::PartManager |
| 25 | * \inheaderfile KParts/PartManager |
| 26 | * \inmodule KParts |
| 27 | * |
| 28 | * \brief The part manager is an object which knows about a collection of parts |
| 29 | * (even nested ones) and handles activation/deactivation. |
| 30 | * |
| 31 | * Applications that want to embed parts without merging GUIs |
| 32 | * only use a KParts::PartManager. Those who want to merge GUIs use a |
| 33 | * KParts::MainWindow for example, in addition to a part manager. |
| 34 | * |
| 35 | * Parts know about the part manager to add nested parts to it. |
| 36 | * See also KParts::Part::manager() and KParts::Part::setManager(). |
| 37 | */ |
| 38 | class KPARTS_EXPORT PartManager : public QObject |
| 39 | { |
| 40 | Q_OBJECT |
| 41 | |
| 42 | /*! |
| 43 | * \property KParts::PartManager::selectionPolicy |
| 44 | */ |
| 45 | Q_PROPERTY(SelectionPolicy selectionPolicy READ selectionPolicy WRITE setSelectionPolicy) |
| 46 | |
| 47 | /*! |
| 48 | * \property KParts::PartManager::allowNestedParts |
| 49 | */ |
| 50 | Q_PROPERTY(bool allowNestedParts READ allowNestedParts WRITE setAllowNestedParts) |
| 51 | |
| 52 | /*! |
| 53 | * \property KParts::PartManager::ignoreScrollBars |
| 54 | */ |
| 55 | Q_PROPERTY(bool ignoreScrollBars READ ignoreScrollBars WRITE setIgnoreScrollBars) |
| 56 | public: |
| 57 | /*! |
| 58 | * Selection policy. The default policy of a PartManager is Direct. |
| 59 | * |
| 60 | * \value Direct |
| 61 | * \value TriState |
| 62 | */ |
| 63 | enum SelectionPolicy { Direct, TriState }; |
| 64 | Q_ENUM(SelectionPolicy) |
| 65 | |
| 66 | /*! |
| 67 | * This extends QFocusEvent::Reason with the non-focus-event reasons for partmanager to activate a part. |
| 68 | * To test for "any focusin reason", use < ReasonLeftClick |
| 69 | * NoReason usually means: explicit activation with setActivePart. |
| 70 | * |
| 71 | * \value ReasonLeftClick |
| 72 | * \value ReasonMidClick |
| 73 | * \value ReasonRightClick |
| 74 | * \value NoReason |
| 75 | */ |
| 76 | enum Reason { ReasonLeftClick = 100, ReasonMidClick, ReasonRightClick, NoReason }; |
| 77 | |
| 78 | /*! |
| 79 | * Constructs a part manager. |
| 80 | * |
| 81 | * \a parent The toplevel widget (window / dialog) the |
| 82 | * partmanager should monitor for activation/selection |
| 83 | * events |
| 84 | */ |
| 85 | PartManager(QWidget *parent); |
| 86 | /*! |
| 87 | * Constructs a part manager. |
| 88 | * |
| 89 | * \a topLevel The toplevel widget (window / dialog ) the |
| 90 | * partmanager should monitor for activation/selection |
| 91 | * events |
| 92 | * \a parent The parent QObject. |
| 93 | */ |
| 94 | PartManager(QWidget *topLevel, QObject *parent); |
| 95 | ~PartManager() override; |
| 96 | |
| 97 | /*! |
| 98 | * Sets the selection policy of the partmanager. |
| 99 | */ |
| 100 | void setSelectionPolicy(SelectionPolicy policy); |
| 101 | /*! |
| 102 | * Returns the current selection policy. |
| 103 | */ |
| 104 | SelectionPolicy selectionPolicy() const; |
| 105 | |
| 106 | /*! |
| 107 | * Specifies whether the partmanager should handle/allow nested parts |
| 108 | * or not. |
| 109 | * |
| 110 | * This is a property the shell has to set/specify. Per |
| 111 | * default we assume that the shell cannot handle nested |
| 112 | * parts. However in case of a KOffice shell for example we allow |
| 113 | * nested parts. A Part is nested (a child part) if its parent |
| 114 | * object inherits KParts::Part. If a child part is activated and |
| 115 | * nested parts are not allowed/handled, then the top parent part in |
| 116 | * the tree is activated. |
| 117 | */ |
| 118 | void setAllowNestedParts(bool allow); |
| 119 | /*! |
| 120 | * \sa setAllowNestedParts |
| 121 | */ |
| 122 | bool allowNestedParts() const; |
| 123 | |
| 124 | /*! |
| 125 | * Specifies whether the partmanager should ignore mouse click events for |
| 126 | * scrollbars or not. If the partmanager ignores them, then clicking on the |
| 127 | * scrollbars of a non-active/non-selected part will not change the selection |
| 128 | * or activation state. |
| 129 | * |
| 130 | * The default value is false (read: scrollbars are NOT ignored). |
| 131 | */ |
| 132 | void setIgnoreScrollBars(bool ignore); |
| 133 | /*! |
| 134 | * \sa setIgnoreScrollBars |
| 135 | */ |
| 136 | bool ignoreScrollBars() const; |
| 137 | |
| 138 | /*! |
| 139 | * Specifies which mouse buttons the partmanager should react upon. |
| 140 | * |
| 141 | * By default it reacts on all mouse buttons (LMB/MMB/RMB). |
| 142 | * |
| 143 | * \a buttonMask a combination of Qt::ButtonState values e.g. Qt::LeftButton | Qt::MiddleButton |
| 144 | */ |
| 145 | void setActivationButtonMask(short int buttonMask); |
| 146 | /*! |
| 147 | * \sa setActivationButtonMask |
| 148 | */ |
| 149 | short int activationButtonMask() const; |
| 150 | |
| 151 | bool eventFilter(QObject *obj, QEvent *ev) override; |
| 152 | |
| 153 | /*! |
| 154 | * Adds a part to the manager. |
| 155 | * |
| 156 | * Sets it to the active part automatically if \a setActive is true (default). |
| 157 | */ |
| 158 | virtual void addPart(Part *part, bool setActive = true); |
| 159 | |
| 160 | /*! |
| 161 | * Removes a part from the manager (this does not delete the object) . |
| 162 | * |
| 163 | * Sets the active part to 0 if \a part is the activePart() . |
| 164 | */ |
| 165 | virtual void removePart(Part *part); |
| 166 | |
| 167 | /*! |
| 168 | * Replaces \a oldPart with \a newPart, and sets \a newPart as active if |
| 169 | * \a setActive is true. |
| 170 | * This is an optimised version of removePart + addPart |
| 171 | */ |
| 172 | virtual void replacePart(Part *oldPart, Part *newPart, bool setActive = true); |
| 173 | |
| 174 | /*! |
| 175 | * Sets the active part. |
| 176 | * |
| 177 | * The active part receives activation events. |
| 178 | * |
| 179 | * \a widget can be used to specify which widget was responsible for the activation. |
| 180 | * This is important if you have multiple views for a document/part , like in KOffice . |
| 181 | */ |
| 182 | virtual void setActivePart(Part *part, QWidget *widget = nullptr); |
| 183 | |
| 184 | /*! |
| 185 | * Returns the active part. |
| 186 | **/ |
| 187 | virtual Part *activePart() const; |
| 188 | |
| 189 | /*! |
| 190 | * Returns the active widget of the current active part (see activePart ). |
| 191 | */ |
| 192 | virtual QWidget *activeWidget() const; |
| 193 | |
| 194 | /*! |
| 195 | * Returns the list of parts being managed by the partmanager. |
| 196 | */ |
| 197 | const QList<Part *> parts() const; |
| 198 | |
| 199 | /*! |
| 200 | * Adds the \a topLevel widget to the list of managed toplevel widgets. |
| 201 | * |
| 202 | * Usually a PartManager only listens for events (for activation/selection) |
| 203 | * for one toplevel widget (and its children) , the one specified in the |
| 204 | * constructor. Sometimes however (like for example when using the KDE dockwidget |
| 205 | * library) , it is necessary to extend this. |
| 206 | */ |
| 207 | void addManagedTopLevelWidget(const QWidget *topLevel); |
| 208 | /*! |
| 209 | * Removes the \a topLevel widget from the list of managed toplevel widgets. |
| 210 | * \sa addManagedTopLevelWidget |
| 211 | */ |
| 212 | void removeManagedTopLevelWidget(const QWidget *topLevel); |
| 213 | |
| 214 | /*! |
| 215 | * Returns the reason for the last activePartChanged signal emitted. |
| 216 | * \sa Reason |
| 217 | */ |
| 218 | int reason() const; |
| 219 | |
| 220 | Q_SIGNALS: |
| 221 | /*! |
| 222 | * Emitted when a new part has been added. |
| 223 | * \sa addPart() |
| 224 | **/ |
| 225 | void partAdded(KParts::Part *part); |
| 226 | /*! |
| 227 | * Emitted when a part has been removed. |
| 228 | * \sa removePart() |
| 229 | **/ |
| 230 | void partRemoved(KParts::Part *part); |
| 231 | /*! |
| 232 | * Emitted when the active part has changed. |
| 233 | * \sa setActivePart() |
| 234 | **/ |
| 235 | void activePartChanged(KParts::Part *newPart); |
| 236 | |
| 237 | protected: |
| 238 | /*! |
| 239 | * Sets whether the PartManager ignores explicit set focus requests |
| 240 | * from the part. |
| 241 | * |
| 242 | * By default this option is set to false. Set it to true to prevent |
| 243 | * the part from sending explicit set focus requests to the client |
| 244 | * application. |
| 245 | * |
| 246 | * \since 4.10 |
| 247 | */ |
| 248 | void setIgnoreExplictFocusRequests(bool); |
| 249 | |
| 250 | protected Q_SLOTS: |
| 251 | /*! |
| 252 | * Removes a part when it is destroyed. |
| 253 | **/ |
| 254 | void slotObjectDestroyed(); |
| 255 | |
| 256 | void slotWidgetDestroyed(); |
| 257 | |
| 258 | void slotManagedTopLevelWidgetDestroyed(); |
| 259 | |
| 260 | private: |
| 261 | KPARTS_NO_EXPORT Part *findPartFromWidget(QWidget *widget, const QPoint &pos); |
| 262 | KPARTS_NO_EXPORT Part *findPartFromWidget(QWidget *widget); |
| 263 | |
| 264 | private: |
| 265 | std::unique_ptr<PartManagerPrivate> const d; |
| 266 | }; |
| 267 | |
| 268 | } |
| 269 | |
| 270 | #endif |
| 271 | |