1 /* SPDX-License-Identifier: LGPL-2.0-or-later 2 3 SPDX-FileCopyrightText: 2005 Christoph Cullmann <cullmann@kde.org> 4 SPDX-FileCopyrightText: 2002, 2003 Joseph Wenninger <jowenn@kde.org> 5 6 SPDX-License-Identifier: LGPL-2.0-or-later 7 */ 8 9 #ifndef __KATE_MDI_H__ 10 #define __KATE_MDI_H__ 11 12 #include <KTextEditor/Plugin> 13 14 #include <KParts/MainWindow> 15 16 #include <KMultiTabBar> 17 #include <KToggleAction> 18 #include <KXMLGUIClient> 19 20 #include <QChildEvent> 21 #include <QEvent> 22 #include <QFrame> 23 #include <QPointer> 24 #include <QSplitter> 25 26 #include <map> 27 #include <unordered_map> 28 #include <vector> 29 30 class KActionMenu; 31 class QAction; 32 class QLabel; 33 class QPixmap; 34 class KConfigBase; 35 36 namespace KTextEditor 37 { 38 class ConfigPageInterface; 39 } 40 41 namespace KateMDI 42 { 43 class ToolView; 44 45 class ToggleToolViewAction : public KToggleAction 46 { 47 Q_OBJECT 48 49 public: 50 ToggleToolViewAction(const QString &text, ToolView *tv, QObject *parent); 51 52 protected Q_SLOTS: 53 void slotToggled(bool) override; 54 void toolVisibleChanged(bool); 55 56 private: 57 ToolView *m_tv; 58 }; 59 60 class GUIClient : public QObject, public KXMLGUIClient 61 { 62 Q_OBJECT 63 64 public: 65 GUIClient(class MainWindow *mw); 66 67 void registerToolView(ToolView *tv); 68 void unregisterToolView(ToolView *tv); 69 void updateSidebarsVisibleAction(); 70 71 private Q_SLOTS: 72 void clientAdded(KXMLGUIClient *client); 73 void updateActions(); 74 75 private: 76 MainWindow *m_mw; 77 KToggleAction *m_showSidebarsAction; 78 std::vector<QAction *> m_toolViewActions; 79 std::unordered_map<ToolView *, QAction *> m_toolToAction; 80 KActionMenu *m_toolMenu; 81 }; 82 83 class ToolView : public QFrame 84 { 85 Q_OBJECT 86 87 friend class Sidebar; 88 friend class MainWindow; 89 friend class GUIClient; 90 friend class ToggleToolViewAction; 91 92 protected: 93 /** 94 * ToolView 95 * Objects of this clas represent a toolview in the mainwindow 96 * you should only add one widget as child to this toolview, it will 97 * be automatically set to be the focus proxy of the toolview 98 * @param mainwin main window for this toolview 99 * @param sidebar sidebar of this toolview 100 * @param parent parent widget, e.g. the splitter of one of the sidebars 101 */ 102 ToolView(class MainWindow *mainwin, class Sidebar *sidebar, QWidget *parent); 103 104 public: 105 /** 106 * destruct me, this is allowed for all, will care itself that the toolview is removed 107 * from the mainwindow and sidebar 108 */ 109 ~ToolView() override; 110 111 Q_SIGNALS: 112 /** 113 * toolview hidden or shown 114 * @param visible is this toolview made visible? 115 */ 116 void toolVisibleChanged(bool visible); 117 118 /** 119 * some internal methodes needed by the main window and the sidebars 120 */ 121 protected: mainWindow()122 MainWindow *mainWindow() 123 { 124 return m_mainWin; 125 } 126 sidebar()127 Sidebar *sidebar() 128 { 129 return m_sidebar; 130 } 131 132 void setToolVisible(bool vis); 133 134 public: 135 bool toolVisible() const; 136 QSize sizeHint() const override; 137 QSize minimumSizeHint() const override; 138 139 protected: 140 void childEvent(QChildEvent *ev) override; 141 void actionEvent(QActionEvent *event) override; 142 143 private: 144 MainWindow *m_mainWin; 145 Sidebar *m_sidebar; 146 KToolBar *m_toolbar; 147 148 /// plugin this view belongs to, may be 0 149 QPointer<KTextEditor::Plugin> plugin; 150 151 /** 152 * unique id 153 */ 154 QString id; 155 156 /** 157 * is visible in sidebar 158 */ 159 bool m_toolVisible; 160 161 /** 162 * is this view persistent? 163 */ 164 bool persistent; 165 166 QIcon icon; 167 QString text; 168 }; 169 170 class Sidebar : public KMultiTabBar 171 { 172 Q_OBJECT 173 174 public: 175 Sidebar(KMultiTabBar::KMultiTabBarPosition pos, class MainWindow *mainwin, QWidget *parent); 176 177 void setSplitter(QSplitter *sp); 178 179 /** 180 * Monitor resizes using the mouse and update the last size accordingly. 181 * Only call this when the sidebar has siblings in the splitter (i.e. m_splitter->count() >= 2) to guarantee that resize handles exist 182 */ 183 void updateLastSizeOnResize(); 184 185 public: 186 ToolView *addWidget(const QIcon &icon, const QString &text, ToolView *widget); 187 bool removeWidget(ToolView *widget); 188 189 bool showWidget(ToolView *widget); 190 bool hideWidget(ToolView *widget); 191 192 bool isCollapsed(); 193 void handleCollapse(int pos, int index); 194 void expandSidebar(ToolView *widget); 195 setLastSize(int s)196 void setLastSize(int s) 197 { 198 m_lastSize = s; 199 } lastSize()200 int lastSize() const 201 { 202 return m_lastSize; 203 } 204 void updateLastSize(); 205 splitterVisible()206 bool splitterVisible() const 207 { 208 return m_ownSplit->isVisible(); 209 } 210 211 void restoreSession(); 212 213 /** 214 * restore the current session config from given object, use current group 215 * @param config config object to use 216 */ 217 void restoreSession(KConfigGroup &config); 218 219 /** 220 * save the current session config to given object, use current group 221 * @param config config object to use 222 */ 223 void saveSession(KConfigGroup &config); 224 225 public Q_SLOTS: 226 // reimplemented, to block a show() call if all sidebars are forced hidden 227 void setVisible(bool visible) override; 228 private Q_SLOTS: 229 void tabClicked(int); 230 231 protected: 232 bool eventFilter(QObject *obj, QEvent *ev) override; 233 234 private Q_SLOTS: 235 void buttonPopupActivate(QAction *); 236 237 private: 238 MainWindow *m_mainWin; 239 240 KMultiTabBar::KMultiTabBarPosition m_pos{}; 241 QSplitter *m_splitter; 242 KMultiTabBar *m_tabBar = nullptr; 243 QSplitter *m_ownSplit; 244 245 std::map<int, ToolView *> m_idToWidget; 246 std::map<ToolView *, int> m_widgetToId; 247 std::map<ToolView *, QSize> m_widgetToSize; 248 249 /** 250 * list of all toolviews around in this sidebar 251 */ 252 std::vector<ToolView *> m_toolviews; 253 254 int m_lastSize; 255 256 QSize m_preHideSize; 257 258 int m_popupButton = 0; 259 260 QLabel *m_resizePlaceholder; 261 bool m_isPreviouslyCollapsed = false; 262 263 Q_SIGNALS: 264 void sigShowPluginConfigPage(KTextEditor::Plugin *configpageinterface, int id); 265 }; 266 267 class MainWindow : public KParts::MainWindow 268 { 269 Q_OBJECT 270 271 friend class ToolView; 272 273 // 274 // Constructor area 275 // 276 public: 277 /** 278 * Constructor 279 */ 280 MainWindow(QWidget *parentWidget = nullptr); 281 282 /** 283 * Destructor 284 */ 285 ~MainWindow() override; 286 287 // 288 // public interfaces 289 // 290 291 /** 292 * add a given widget to the given sidebar if possible, name is very important 293 * @param plugin pointer to the plugin 294 * @param identifier unique identifier for this toolview 295 * @param pos position for the toolview, if we are in session restore, this is only a preference 296 * @param icon icon to use for the toolview 297 * @param text text to use in addition to icon 298 * @return created toolview on success or 0 299 */ 300 ToolView * 301 createToolView(KTextEditor::Plugin *plugin, const QString &identifier, KMultiTabBar::KMultiTabBarPosition pos, const QIcon &icon, const QString &text); 302 303 /** 304 * give you handle to toolview for the given name, 0 if no toolview around 305 * @param identifier toolview name 306 * @return toolview if existing, else 0 307 */ 308 ToolView *toolView(const QString &identifier) const; 309 310 /** 311 * set the toolview's tabbar style. 312 * @param style the tabbar style. 313 */ 314 void setToolViewStyle(KMultiTabBar::KMultiTabBarStyle style); 315 316 /** 317 * get the toolview's tabbar style. Call this before @p startRestore(), 318 * otherwise you overwrite the usersettings. 319 * @return toolview's tabbar style 320 */ 321 KMultiTabBar::KMultiTabBarStyle toolViewStyle() const; 322 323 /** 324 * get the sidebars' visibility. 325 * @return false, if the sidebars' visibility is forced hidden, otherwise true 326 */ 327 bool sidebarsVisible() const; 328 329 public Q_SLOTS: 330 /** 331 * set the sidebars' visibility to @p visible. If false, the sidebars 332 * are @e always hidden. Usually you do not have to call this because 333 * the user can set this in the menu. 334 * @param visible sidebars visibility 335 */ 336 void setSidebarsVisible(bool visible); 337 338 protected: 339 /** 340 * called by toolview destructor 341 * @param widget toolview which is destroyed 342 */ 343 void toolViewDeleted(ToolView *widget); 344 345 /** 346 * central widget ;) 347 * use this as parent for your content 348 * this widget will get focus if a toolview is hidden 349 * @return central widget 350 */ 351 QWidget *centralWidget() const; 352 353 /** 354 * modifiers for existing toolviews 355 */ 356 public: 357 /** 358 * move a toolview around 359 * @param widget toolview to move 360 * @param pos position to move too, during session restore, only preference 361 * @return success 362 */ 363 bool moveToolView(ToolView *widget, KMultiTabBar::KMultiTabBarPosition pos); 364 365 /** 366 * show given toolview, discarded while session restore 367 * @param widget toolview to show 368 * @return success 369 */ 370 bool showToolView(ToolView *widget); 371 372 /** 373 * hide given toolview, discarded while session restore 374 * @param widget toolview to hide 375 * @return success 376 */ 377 bool hideToolView(ToolView *widget); 378 379 /** 380 * session saving and restore stuff 381 */ 382 public: 383 /** 384 * start the restore 385 * @param config config object to use 386 * @param group config group to use 387 */ 388 void startRestore(KConfigBase *config, const QString &group); 389 390 /** 391 * finish the restore 392 */ 393 void finishRestore(); 394 395 /** 396 * save the current session config to given object and group 397 * @param group config group to use 398 */ 399 void saveSession(KConfigGroup &group); 400 401 /** 402 * internal data ;) 403 */ 404 private: 405 /** 406 * map identifiers to widgets 407 */ 408 std::map<QString, ToolView *> m_idToWidget; 409 410 /** 411 * list of all toolviews around 412 */ 413 std::vector<ToolView *> m_toolviews; 414 415 /** 416 * widget, which is the central part of the 417 * main window ;) 418 */ 419 QWidget *m_centralWidget; 420 421 /** 422 * horizontal splitter 423 */ 424 QSplitter *m_hSplitter; 425 426 /** 427 * vertical splitter 428 */ 429 QSplitter *m_vSplitter; 430 431 /** 432 * sidebars for the four sides 433 */ 434 std::unique_ptr<Sidebar> m_sidebars[4]; 435 436 /** 437 * sidebars state. 438 */ 439 bool m_sidebarsVisible = true; 440 441 /** 442 * config object for session restore, only valid between 443 * start and finish restore calls 444 */ 445 KConfigBase *m_restoreConfig = nullptr; 446 447 /** 448 * restore group 449 */ 450 QString m_restoreGroup; 451 452 /** 453 * out guiclient 454 */ 455 GUIClient *m_guiClient; 456 457 Q_SIGNALS: 458 void sigShowPluginConfigPage(KTextEditor::Plugin *configpageinterface, int id); 459 }; 460 461 } 462 463 #endif 464