1 /*
2     SPDX-FileCopyrightText: 2019 Michail Vourlakos <mvourlakos@gmail.com>
3     SPDX-License-Identifier: GPL-2.0-or-later
4 */
5 
6 #ifndef GENERICLAYOUT_H
7 #define GENERICLAYOUT_H
8 
9 // local
10 #include <coretypes.h>
11 #include "abstractlayout.h"
12 #include "../data/errordata.h"
13 #include "../data/viewdata.h"
14 #include "../data/viewstable.h"
15 
16 // Qt
17 #include <QObject>
18 #include <QQuickView>
19 #include <QPointer>
20 #include <QScreen>
21 
22 // Plasma
23 #include <Plasma>
24 
25 namespace Plasma {
26 class Applet;
27 class Containment;
28 class Types;
29 }
30 
31 namespace Latte {
32 class Corona;
33 class ScreenPool;
34 class View;
35 }
36 
37 namespace Latte {
38 namespace Layout {
39 
40 //! This is  views map in the following structure:
41 //! SCREEN_NAME -> EDGE -> VIEWID
42 typedef QHash<QString, QHash<Plasma::Types::Location, QList<uint>>> ViewsMap;
43 
44 class GenericLayout : public AbstractLayout
45 {
46     Q_OBJECT
47     Q_PROPERTY(int viewsCount READ viewsCount NOTIFY viewsCountChanged)
48 
49 public:
50     GenericLayout(QObject *parent, QString layoutFile, QString assignedName = QString());
51     ~GenericLayout() override;
52 
53     QString background() const override;
54     QString textColor() const override;
55 
56     virtual const QStringList appliedActivities() = 0; // to move at an interface
57 
58     void importToCorona();
59     bool initToCorona(Latte::Corona *corona);
60 
61     bool isActive() const; //! is loaded and running
62     virtual bool isCurrent();
63     bool isWritable() const;
64 
65     virtual int viewsCount(int screen) const;
66     virtual int viewsCount(QScreen *screen) const;
67     virtual int viewsCount() const;
68 
69     Type type() const override;
70 
71     Latte::Corona *corona() const;
72 
73     QStringList unloadedContainmentsIds();
74 
75     virtual Types::ViewType latteViewType(uint containmentId) const;
76     const QList<Plasma::Containment *> *containments() const;
77 
78     bool contains(Plasma::Containment *containment) const;
79     bool containsView(const int &containmentId) const;
80     int screenForContainment(Plasma::Containment *containment);
81 
82     Latte::View *highestPriorityView();
83     Latte::View *viewForContainment(uint id) const;
84     Latte::View *viewForContainment(Plasma::Containment *containment) const;
85     Plasma::Containment *containmentForId(uint id) const;
86     QList<Plasma::Containment *> subContainmentsOf(uint id) const;
87 
88     static bool viewAtLowerScreenPriority(Latte::View *test, Latte::View *base);
89     static bool viewAtLowerEdgePriority(Latte::View *test, Latte::View *base);
90     static QList<Latte::View *> sortedLatteViews(QList<Latte::View *> views);
91 
92     QList<Latte::View *> sortedLatteViews();
93     virtual QList<Latte::View *> viewsWithPlasmaShortcuts();
94     virtual QList<Latte::View *> latteViews();
95     ViewsMap validViewsMap(ViewsMap *occupiedMap = nullptr);
96     virtual void syncLatteViewsToScreens(Layout::ViewsMap *occupiedMap = nullptr);
97 
98     void syncToLayoutFile(bool removeLayoutId = false);
99 
100     void lock(); //! make it only read-only
101     void renameLayout(QString newName);
102     virtual void unloadContainments();
103     void unloadLatteViews();
104     void unlock(); //! make it writable which it should be the default
105 
106     virtual void setLastConfigViewFor(Latte::View *view);
107     virtual Latte::View *lastConfigViewFor();
108 
109     //! this function needs the layout to have first set the corona through initToCorona() function
110     virtual void addView(Plasma::Containment *containment, bool forceOnPrimary = false, int explicitScreen = -1, Layout::ViewsMap *occupied = nullptr);
111     void recreateView(Plasma::Containment *containment, bool delayed = true);
112     bool latteViewExists(Plasma::Containment *containment);
113 
114     bool newView(const QString &templateName);
115     Data::View newView(const Latte::Data::View &nextViewData);
116     void removeView(const Latte::Data::View &viewData);
117     void updateView(const Latte::Data::View &viewData);
118     QString storedView(const int &containmentId); //returns temp filepath containing all view data
119     void removeOrphanedSubContainment(const int &containmentId);
120 
121     //! Available edges for specific view in that screen
122     virtual QList<Plasma::Types::Location> availableEdgesForView(QScreen *scr, Latte::View *forView) const;
123     //! All free edges in that screen
124     virtual QList<Plasma::Types::Location> freeEdges(QScreen *scr) const;
125     virtual QList<Plasma::Types::Location> freeEdges(int screen) const;
126 
127     //! Bind this latteView and its relevant containments(including subcontainments)
128     //! to this layout. It is used for moving a Latte::View from layout to layout)
129     void assignToLayout(Latte::View *latteView, QList<Plasma::Containment *> containments);
130     //! Unassign that latteView from this layout (this is used for moving a latteView
131     //! from layout to layout) and returns all the containments relevant to
132     //! that latteView
133     QList<Plasma::Containment *> unassignFromLayout(Plasma::Containment *latteContainment);
134 
135     QList<int> viewsExplicitScreens();
136 
137     Latte::Data::ViewsTable viewsTable() const;
138 
139     //! errors/warnings
140     Data::ErrorsList errors() const;
141     Data::WarningsList warnings() const;
142 
143 public slots:
144     Q_INVOKABLE int viewsWithTasks() const;
145     virtual Q_INVOKABLE QList<int> qmlFreeEdges(int screen) const;  //change <Plasma::Types::Location> to <int> types
146 
147     void toggleHiddenState(QString viewName, QString screenName, Plasma::Types::Location edge);
148 
149 signals:
150     void activitiesChanged(); // to move at an interface
151     void viewsCountChanged();
152     void viewEdgeChanged();
153 
154     //! used from ConfigView(s) in order to be informed which is one should be shown
155     void lastConfigViewForChanged(Latte::View *view);
156 
157     //! used from LatteView(s) in order to exist only one each time that has the highest priority
158     //! to use the global shortcuts activations
159     void preferredViewForShortcutsChanged(Latte::View *view);
160 
161 protected:
162     void updateLastUsedActivity();
163 
164 protected:
165     Latte::Corona *m_corona{nullptr};
166 
167     QList<Plasma::Containment *> m_containments;
168 
169     QHash<const Plasma::Containment *, Latte::View *> m_latteViews;
170     QHash<const Plasma::Containment *, Latte::View *> m_waitingLatteViews;
171 
172 private slots:
173     void addContainment(Plasma::Containment *containment);
174     void appletCreated(Plasma::Applet *applet);
175     void destroyedChanged(bool destroyed);
176     void containmentDestroyed(QObject *cont);
177     void onLastConfigViewChangedFrom(Latte::View *view);
178 
179 private:
180     //! It can be used in order for LatteViews to not be created automatically when
181     //! their corresponding containments are created e.g. copyView functionality
182     bool blockAutomaticLatteViewCreation() const;
183     void setBlockAutomaticLatteViewCreation(bool block);
184 
185     bool explicitDockOccupyEdge(int screen, Plasma::Types::Location location) const;
186     bool primaryDockOccupyEdge(Plasma::Types::Location location) const;
187 
188     bool viewDataAtLowerEdgePriority(const Latte::Data::View &test, const Latte::Data::View &base) const;
189     bool viewDataAtLowerScreenPriority(const Latte::Data::View &test, const Latte::Data::View &base) const;
190     bool viewDataAtLowerStatePriority(const Latte::Data::View &test, const Latte::Data::View &base) const;
191 
192     bool mapContainsId(const ViewsMap *map, uint viewId) const;
193 
194     QList<int> subContainmentsOf(Plasma::Containment *containment) const;
195 
196     QList<Latte::Data::View> sortedViewsData(const QList<Latte::Data::View> &viewsData);
197 
198     void destroyContainment(Plasma::Containment *containment);
199 
200 private:
201     bool m_blockAutomaticLatteViewCreation{false};
202 
203     QPointer<Latte::View> m_lastConfigViewFor;
204 
205     QStringList m_unloadedContainmentsIds;
206 
207     //! try to avoid crashes from recreating the same views all the time
208     QList<const Plasma::Containment *> m_viewsToRecreate;
209 
210     //! Containments that are pending screen/state updates
211     Latte::Data::ViewsTable m_pendingContainmentUpdates;
212 
213     friend class Latte::View;
214 };
215 
216 }
217 }
218 
219 #endif
220