File indexing completed on 2024-04-28 04:37:31

0001 /*
0002     SPDX-FileCopyrightText: 2006-2007 Alexander Dymo <adymo@kdevelop.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef KDEVPLATFORM_SUBLIMECONTROLLER_H
0008 #define KDEVPLATFORM_SUBLIMECONTROLLER_H
0009 
0010 #include <QObject>
0011 
0012 #include "sublimedefs.h"
0013 #include "sublimeexport.h"
0014 
0015 #include "mainwindowoperator.h"
0016 
0017 
0018 namespace Sublime {
0019 
0020 class Area;
0021 class AreaIndex;
0022 class Document;
0023 class MainWindow;
0024 class ControllerPrivate;
0025 
0026 /**
0027 @short Handles association of areas to main windows.
0028 
0029 Whereas the MainWindow class can be told to show arbitrary Area
0030 instance, this class establishes more high-level rules based
0031 on the following assumptions:
0032 
0033 1. It's desirable to have a list of "area types" -- basically string,
0034 and be able to switch each main window between those "area types". For
0035 example, to switch main window between "Code" and "Debug"
0036 
0037 2. It's also desirable to save the state of area -- like the set of tool views,
0038 position of tool views, etc. This need to be done per-main window, so that
0039 "code" area of one window is allowed to be different from "code" area
0040 of another window.
0041 
0042 3. Is it desirable to be able to reset an area of given type in a given
0043 main window to a default state.
0044 
0045 The current implementation achieves those goals as follows.
0046 
0047 1. Controller keeps a list of default areas. Those areas are not shown by any
0048 main window, and never modified as result of user actions. They are directly 
0049 constructed by kdevelop core. Those areas are returned by the defaultAreas
0050 method. Each Area instance in the list provides area type id, and human name
0051 of the area -- via Area::objectName and Area::title methods respectively.
0052 All methods in this class accept area id, and human name of the area is only
0053 used to present the area type to the user, for selection.
0054 
0055 2. Controller also keeps a list of MainWindow instances that it manages. For
0056 each instance, it keeps a list of areas private to the MainWindow instance.
0057 There's one area for each area in defaultAreas. That is, for each area type,
0058 there's one area in defaultAreas, and one area per each main window
0059 
0060 3. It's possible to switch a given main window to display an area of the
0061 given type -- which finds the area with the given id in the list of area
0062 private to that main window, and switches the main window to the found area.
0063 
0064 When we create a new main window, we create fresh set of private areas by
0065 cloning the default areas. An alternative approach would be to create a clone
0066 only when we try to show a specific area type in a main window. However, 
0067 I think that knowing that each main window has its Area instance for each 
0068 area type simplifies the code. For example, most of the time, during 
0069 restoring areas we'd need per-window area instances anyway. Of course, we 
0070 can introduce a method demand_area_type(MainWindow*, QString) that
0071 clones the default area of the necessary type, but I don't see what that will
0072 buy us.
0073 
0074 Controller has to exist before any area, document or mainwindow can be created.
0075 There's no point in having two controllers for one application unless they
0076 need to show completely different sets of areas.
0077 */
0078 class KDEVPLATFORMSUBLIME_EXPORT Controller: public QObject, public MainWindowOperator {
0079     Q_OBJECT
0080 public:
0081     explicit Controller(QObject *parent = nullptr);
0082     ~Controller() override;
0083 
0084     /** Add the area to the set of default areas in this controller. */
0085     void addDefaultArea(Area *area);
0086 
0087     /** Return the list of default areas.  */
0088     const QList<Area*> &defaultAreas() const;
0089 
0090     /** Return the default area with given @p id.*/
0091     Area *defaultArea(const QString &id) const;
0092 
0093     /** Add a main window to the set of windows managed by this
0094         controller.  The ownership of the window is passed to the
0095         controller.  The window will be associated with a set of
0096         areas created by cloning the current defaultAreas.  */
0097     void addMainWindow(MainWindow* mainWindow);
0098 
0099     /** Return the set of MainWindow instances managed by
0100         *this. */
0101     const QList<MainWindow*> &mainWindows() const;
0102 
0103     /** Return all areas associated with the main window with the specified
0104         index. */
0105    const QList<Area*> &areas(int mainWindow) const;
0106 
0107    /** Return all areas associated with the main window with the specified
0108         index. */
0109    const QList<Area*> &areas(MainWindow* mainWindow) const;
0110 
0111     /** Return the area with the given in main window specified
0112         by its index, @p mainWindow.  */
0113     Area *area(int mainWindow, const QString& id) const;
0114 
0115     /** Returns the area that contains the given view.
0116      * */
0117     Area* areaForView(View* view) const;
0118 
0119     /**Shows an @p area in @p mainWindow. @todo Remove this method */
0120     void showArea(Area *area, MainWindow *mainWindow);
0121 
0122     /** Show area with the id of @p areaTypeId in @p mainWindow. */
0123     void showArea(const QString& areaTypeId, MainWindow *mainWindow);
0124 
0125     /** Make the tool configuration of the area currently shown
0126         in @p mainWindow match those of default area with the same
0127         area type. */
0128     void resetCurrentArea(MainWindow *mainWindow);
0129     
0130     /** Return the list of all areas, including default area and
0131         area private to each main window.  */
0132     const QList<Area*> &allAreas() const;
0133 
0134     /**@return the list of documents created in this controller.*/
0135     const QList<Document*> &documents() const;
0136 
0137     bool openAfterCurrent() const;
0138     bool arrangeBuddies() const;
0139 
0140     void loadSettings();
0141 public Q_SLOTS:
0142     //@todo adymo: this should not be a part of public API
0143     /**Area can connect to this slot to release itself from its mainwindow.*/
0144     void areaReleased();
0145     /**Releases @p area from its mainwindow.*/
0146     void areaReleased(Sublime::Area *area);
0147 
0148 protected:
0149     bool eventFilter(QObject *obj, QEvent *ev) override;
0150     void showAreaInternal(Area* area, MainWindow *mainWindow);
0151 
0152 private Q_SLOTS:
0153     void notifyToolViewRemoved(Sublime::View *view, Sublime::Position);
0154     void notifyToolViewAdded(Sublime::View *view, Sublime::Position);
0155     void notifyViewRemoved(Sublime::AreaIndex*, Sublime::View *view);
0156     void notifyViewAdded(Sublime::AreaIndex*, Sublime::View *view);
0157 
0158 Q_SIGNALS:
0159     void aboutToRemoveToolView(Sublime::View*);
0160     void toolViewAdded(Sublime::View*);
0161     void aboutToRemoveView(Sublime::View*);
0162     void viewAdded(Sublime::View*);
0163     void toolViewMoved(Sublime::View*);
0164     void mainWindowAdded(Sublime::MainWindow*);
0165     void areaCreated(Sublime::Area* area);
0166 
0167 private:
0168     void init();
0169 
0170     void removeArea(Sublime::Area*); // called by Sublime::Area
0171     void removeDocument(Sublime::Document*); // called by Sublime::Document
0172 
0173     /**Adds the document to the controller, used by Document class.
0174     @todo adymo: refactor*/
0175     void addDocument(Document *document);
0176 
0177 private:
0178     const QScopedPointer<class ControllerPrivate> d_ptr;
0179     Q_DECLARE_PRIVATE(Controller)
0180 
0181     friend class Area;
0182     friend class Document;
0183 };
0184 
0185 }
0186 
0187 #endif
0188