1 /* BEGIN_COMMON_COPYRIGHT_HEADER
2  * (c)LGPL2+
3  *
4  * LXQt - a lightweight, Qt based, desktop toolset
5  * https://lxqt.org
6  *
7  * Copyright: 2010-2011 Razor team
8  * Authors:
9  *   Alexander Sokoloff <sokoloff.a@gmail.com>
10  *
11  * This program or library is free software; you can redistribute it
12  * and/or modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20 
21  * You should have received a copy of the GNU Lesser General
22  * Public License along with this library; if not, write to the
23  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24  * Boston, MA 02110-1301 USA
25  *
26  * END_COMMON_COPYRIGHT_HEADER */
27 
28 
29 #ifndef LXQTPANEL_H
30 #define LXQTPANEL_H
31 
32 #include <QFrame>
33 #include <QString>
34 #include <QTimer>
35 #include <QPropertyAnimation>
36 #include <QPointer>
37 #include <LXQt/Settings>
38 #include "ilxqtpanel.h"
39 #include "lxqtpanelglobals.h"
40 
41 class QMenu;
42 class Plugin;
43 class QAbstractItemModel;
44 
45 namespace LXQt {
46 class Settings;
47 class PluginInfo;
48 }
49 class LXQtPanelLayout;
50 class ConfigPanelDialog;
51 class PanelPluginsModel;
52 class WindowNotifier;
53 
54 /*! \brief The LXQtPanel class provides a single lxqt-panel. All LXQtPanel
55  * instances should be created and handled by LXQtPanelApplication. In turn,
56  * all Plugins should be created and handled by LXQtPanels.
57  *
58  * LXQtPanel is just the panel, it does not incorporate any functionality.
59  * Each function of the panel is implemented by Plugins, even the mainmenu
60  * (plugin-mainmenu) and the taskbar (plugin-taskbar). So the LXQtPanel is
61  * just the container for several Plugins while the different Plugins
62  * incorporate the functions of the panel. Without the Plugins, the panel
63  * is quite useless because it is just a box occupying space on the screen.
64  *
65  * LXQtPanel itself is a window (QFrame/QWidget) and this class is mainly
66  * responsible for handling the size and position of this window on the
67  * screen(s) as well as the different settings. The handling of the plugins
68  * is outsourced in PanelPluginsModel and LXQtPanelLayout. PanelPluginsModel
69  * is responsible for loading/creating and handling the plugins.
70  * LXQtPanelLayout is inherited from QLayout and set as layout to the
71  * background of LXQtPanel, so LXQtPanelLayout is responsible for the
72  * layout of all the Plugins.
73  *
74  * \sa LXQtPanelApplication, Plugin, PanelPluginsModel, LXQtPanelLayout.
75  */
76 class LXQT_PANEL_API LXQtPanel : public QFrame, public ILXQtPanel
77 {
78     Q_OBJECT
79 
80     Q_PROPERTY(QString position READ qssPosition)
81 
82     // for configuration dialog
83     friend class ConfigPanelWidget;
84     friend class ConfigPluginsWidget;
85     friend class ConfigPanelDialog;
86     friend class PanelPluginsModel;
87 
88 public:
89     /**
90      * @brief Stores how the panel should be aligned. Obviously, this applies
91      * only if the panel does not occupy 100 % of the available space. If the
92      * panel is vertical, AlignmentLeft means align to the top border of the
93      * screen, AlignmentRight means align to the bottom.
94      */
95     enum Alignment {
96         AlignmentLeft   = -1, //!< Align the panel to the left or top
97         AlignmentCenter =  0, //!< Center the panel
98         AlignmentRight  =  1 //!< Align the panel to the right or bottom
99     };
100 
101     /**
102      * @brief Creates and initializes the LXQtPanel. Performs the following
103      * steps:
104      * 1. Sets Qt window title, flags, attributes.
105      * 2. Creates the panel layout.
106      * 3. Prepares the timers.
107      * 4. Connects signals and slots.
108      * 5. Reads the settings for this panel.
109      * 6. Optionally moves the panel to a valid screen (position-dependent).
110      * 7. Loads the Plugins.
111      * 8. Shows the panel, even if it is hidable (but then, starts the timer).
112      * @param configGroup The name of the panel which is used as identifier
113      * in the config file.
114      * @param settings The settings instance of this lxqt panel application.
115      * @param parent Parent QWidget, can be omitted.
116      */
117     LXQtPanel(const QString &configGroup, LXQt::Settings *settings, QWidget *parent = nullptr);
118     virtual ~LXQtPanel();
119 
120     /**
121      * @brief Returns the name of this panel which is also used as identifier
122      * in the config file.
123      */
name()124     QString name() { return mConfigGroup; }
125 
126     /**
127      * @brief Reads all the necessary settings from mSettings and stores them
128      * in local variables. Additionally, calls necessary methods like realign()
129      * or updateStyleSheet() which need to get called after changing settings.
130      */
131     void readSettings();
132 
133     /**
134      * @brief Creates and shows the popup menu (right click menu). If a plugin
135      * is given as parameter, the menu will be divided in two groups:
136      * plugin-specific options and panel-related options. As these two are
137      * shown together, this menu has to be created by LXQtPanel.
138      * @param plugin The plugin whose menu options will be included in the
139      * context menu.
140      */
141     void showPopupMenu(Plugin *plugin = 0);
142 
143     // ILXQtPanel overrides ........
position()144     ILXQtPanel::Position position() const override { return mPosition; }
145     QRect globalGeometry() const override;
146     QRect calculatePopupWindowPos(QPoint const & absolutePos, QSize const & windowSize) const override;
147     QRect calculatePopupWindowPos(const ILXQtPanelPlugin *plugin, const QSize &windowSize) const override;
148     void willShowWindow(QWidget * w) override;
149     void pluginFlagsChanged(const ILXQtPanelPlugin * plugin) override;
isLocked()150     bool isLocked() const override { return mLockPanel; }
151     // ........ end of ILXQtPanel overrides
152 
153     /**
154      * @brief Searches for a Plugin in the Plugins-list of this panel. Takes
155      * an ILXQtPanelPlugin as parameter and returns the corresponding Plugin.
156      * @param iPlugin ILXQtPanelPlugin that we are looking for.
157      * @return The corresponding Plugin if it is loaded in this panel, nullptr
158      * otherwise.
159      */
160     Plugin *findPlugin(const ILXQtPanelPlugin *iPlugin) const;
161 
162     // For QSS properties ..................
163     /**
164      * @brief Returns the position as string
165      *
166      * \sa positionToStr().
167      */
168     QString qssPosition() const;
169 
170     /**
171      * @brief Checks if this LXQtPanel can be placed at a given position
172      * on the screen with the given screenNum. The condition for doing so
173      * is that the panel is not located between two screens.
174      *
175      * For example, if position is PositionRight, there should be no screen to
176      * the right of the given screen. That means that there should be no
177      * screen whose left border has a higher x-coordinate than the x-coordinate
178      * of the right border of the given screen. This method iterates over all
179      * screens and checks these conditions.
180      * @param screenNum screen index as it is used by QDesktopWidget methods
181      * @param position position where the panel should be placed
182      * @return true if this panel can be placed at the given position on the
183      * given screen.
184      *
185      * \sa findAvailableScreen(), mScreenNum, mActualScreenNum.
186      */
187     static bool canPlacedOn(int screenNum, LXQtPanel::Position position);
188     /**
189      * @brief Returns a string representation of the given position. This
190      * string is human-readable and can be used in config files.
191      * @param position position that should be converted to a string.
192      * @return the string representation of the given position, i.e.
193      * "Top", "Left", "Right" or "Bottom".
194      *
195      * \sa strToPosition()
196      */
197     static QString positionToStr(ILXQtPanel::Position position);
198     /**
199      * @brief Returns an ILXQtPanel::Position from the given string. This can
200      * be used to retrieve ILXQtPanel::Position values from the config files.
201      * @param str string that should be converted to ILXQtPanel::Position
202      * @param defaultValue value that will be returned if the string can not
203      * be converted to an ILXQtPanel::Position.
204      * @return ILXQtPanel::Position that was determined from str or
205      * defaultValue if str could not be converted.
206      *
207      * \sa positionToStr()
208      */
209     static ILXQtPanel::Position strToPosition(const QString &str, ILXQtPanel::Position defaultValue);
210 
211     // Settings
iconSize()212     int iconSize() const override { return mIconSize; } //!< Implement ILXQtPanel::iconSize().
lineCount()213     int lineCount() const override { return mLineCount; } //!< Implement ILXQtPanel::lineCount().
panelSize()214     int panelSize() const { return mPanelSize; }
length()215     int length() const { return mLength; }
lengthInPercents()216     bool lengthInPercents() const { return mLengthInPercents; }
alignment()217     LXQtPanel::Alignment alignment() const { return mAlignment; }
screenNum()218     int screenNum() const { return mScreenNum; }
fontColor()219     QColor fontColor() const { return mFontColor; }
backgroundColor()220     QColor backgroundColor() const { return mBackgroundColor; }
backgroundImage()221     QString backgroundImage() const { return mBackgroundImage; }
opacity()222     int opacity() const { return mOpacity; }
reserveSpace()223     int reserveSpace() const { return mReserveSpace; }
hidable()224     bool hidable() const { return mHidable; }
visibleMargin()225     bool visibleMargin() const { return mVisibleMargin; }
hideOnOverlap()226     bool hideOnOverlap() const { return mHideOnOverlap; }
animationTime()227     int animationTime() const { return mAnimationTime; }
showDelay()228     int showDelay() const { return mShowDelayTimer.interval(); }
229     QString iconTheme() const;
230 
231     /*!
232      * \brief Checks if a given Plugin is running and has the
233      * ILXQtPanelPlugin::SingleInstance flag set.
234      * \param pluginId Plugin Identifier which is the basename of the
235      * .desktop file that specifies the plugin.
236      * \return true if the Plugin is running and has the
237      * ILXQtPanelPlugin::SingleInstance flag set, false otherwise.
238      */
239     bool isPluginSingletonAndRunnig(QString const & pluginId) const;
240     /*!
241      * \brief Updates the config dialog. Used for updating its icons
242      * when the panel-specific icon theme changes.
243      */
244     void updateConfigDialog() const;
245 
246 public slots:
247     /**
248      * @brief Shows the QWidget and makes it visible on all desktops. This
249      * method is NOT related to showPanel(), hidePanel() and hidePanelWork()
250      * which handle the LXQt hiding by resizing the panel.
251      */
252     void show();
253     /**
254      * @brief Shows the panel (immediately) after it had been hidden before.
255      * Stops the QTimer mHideTimer. This it NOT the same as QWidget::show()
256      * because hiding the panel in LXQt is done by making it very thin. So
257      * this method in fact restores the original size of the panel.
258      * \param animate flag for the panel show-up animation disabling (\sa mAnimationTime).
259      *
260      * \sa mHidable, mHidden, mHideTimer, hidePanel(), hidePanelWork()
261      */
262     void showPanel(bool animate);
263     /**
264      * @brief Hides the panel (delayed) by starting the QTimer mHideTimer.
265      * When this timer times out, hidePanelWork() will be called. So this
266      * method is called when the cursor leaves the panel area but the panel
267      * will be hidden later.
268      *
269      * \sa mHidable, mHidden, mHideTimer, showPanel(), hidePanelWork()
270      */
271     void hidePanel();
272     /**
273      * @brief Actually hides the panel. Will be invoked when the QTimer
274      * mHideTimer times out. That timer will be started by showPanel(). This
275      * is NOT the same as QWidget::hide() because hiding the panel in LXQt is
276      * done by making the panel very thin. So this method in fact makes the
277      * panel very thin while the QWidget stays visible.
278      *
279      * \sa mHidable, mHidden, mHideTimer, showPanel(), hidePanel()
280      */
281     void hidePanelWork();
282 
283     // Settings
284     /**
285      * @brief All the setter methods are  designed similar:
286      * 1. Check if the given value is different from the current value. If not,
287      * do not do anything and return.
288      * 2. Set the value.
289      * 3. If parameter save is true, call saveSettings(true) to store the
290      * new settings on the disk.
291      * 4. If necessary, propagate the new value to child objects, e.g. to
292      * mLayout.
293      * 5. If necessary, call update methods like realign() or
294      * updateStyleSheet().
295      * @param value The value that should be set.
296      * @param save If true, saveSettings(true) will be called.
297      */
298     void setPanelSize(int value, bool save);
299     void setIconSize(int value, bool save); //!< \sa setPanelSize()
300     void setLineCount(int value, bool save); //!< \sa setPanelSize()
301     void setLength(int length, bool inPercents, bool save); //!< \sa setPanelSize()
302     void setPosition(int screen, ILXQtPanel::Position position, bool save); //!< \sa setPanelSize()
303     void setAlignment(LXQtPanel::Alignment value, bool save); //!< \sa setPanelSize()
304     void setFontColor(QColor color, bool save); //!< \sa setPanelSize()
305     void setBackgroundColor(QColor color, bool save); //!< \sa setPanelSize()
306     void setBackgroundImage(QString path, bool save); //!< \sa setPanelSize()
307     void setOpacity(int opacity, bool save); //!< \sa setPanelSize()
308     void setReserveSpace(bool reserveSpace, bool save); //!< \sa setPanelSize()
309     void setHidable(bool hidable, bool save); //!< \sa setPanelSize()
310     void setVisibleMargin(bool visibleMargin, bool save); //!< \sa setPanelSize()
311     void setHideOnOverlap(bool hideOnOverlap, bool save);
312     void setAnimationTime(int animationTime, bool save); //!< \sa setPanelSize()
313     void setShowDelay(int showDelay, bool save); //!< \sa setPanelSize()
314     void setIconTheme(const QString& iconTheme);
315 
316     /**
317      * @brief Saves the current configuration, i.e. writes the current
318      * configuration varibles to mSettings.
319      * @param later Determines if the settings are written immediately or
320      * after a short delay. If later==true, the QTimer mDelaySave is started.
321      * As soon as this timer times out, saveSettings(false) will be called. If
322      * later==false, settings will be written.
323      */
324     void saveSettings(bool later=false);
325     /**
326      * @brief Checks if the panel can be placed on the current screen at the
327      * current position. If it can not, it will be moved on another screen
328      * where the desired position is possible.
329      */
330     void ensureVisible();
331 
332 signals:
333     /**
334      * @brief This signal gets emitted whenever this panel receives a
335      * QEvent::LayoutRequest, i.e. "Widget layout needs to be redone.".
336      * The PanelPluginsModel will connect this signal to the individual
337      * plugins so they can realign, too.
338      */
339     void realigned();
340     /**
341      * @brief This signal gets emitted at the end of
342      * userRequestForDeletion() which in turn gets called when the user
343      * decides to remove a panel. This signal is used by
344      * LXQtPanelApplication to get notified whenever an LXQtPanel should
345      * be removed.
346      * @param self This LXQtPanel. LXQtPanelApplication will use this
347      * parameter to identify the LXQtPanel that should be removed.
348      */
349     void deletedByUser(LXQtPanel *self);
350     /**
351      * @brief This signal is just a relay signal. The pluginAdded signal
352      * of the PanelPluginsModel (mPlugins) will be connected to this
353      * signal. Thereby, we can make this signal of a private member
354      * available as a public signal.
355      * Currently, this signal is used by LXQtPanelApplication which
356      * will further re-emit this signal.
357      */
358     void pluginAdded();
359     /**
360      * @brief This signal is just a relay signal. The pluginRemoved signal
361      * of the PanelPluginsModel (mPlugins) will be connected to this
362      * signal. Thereby, we can make this signal of a private member
363      * available as a public signal.
364      * Currently, this signal is used by LXQtPanelApplication which
365      * will further re-emit this signal.
366      */
367     void pluginRemoved();
368 
369 protected:
370     /**
371      * @brief Overrides QObject::event(QEvent * e). Some functions of
372      * the panel will be triggered by these events, e.g. showing/hiding
373      * the panel or showing the context menu.
374      * @param event The event that was received.
375      * @return "QObject::event(QEvent *e) should return true if the event e
376      * was recognized and processed." This is done by passing the event to
377      * QFrame::event(QEvent *e) at the end.
378      */
379     bool event(QEvent *event) override;
380     /**
381      * @brief Overrides QWidget::showEvent(QShowEvent * event). This
382      * method is called when a widget (in this case: the LXQtPanel) is
383      * shown. The call could happen before and after the widget is shown.
384      * This method is just overridden to get notified when the LXQtPanel
385      * will be shown. Then, LXQtPanel will call realign().
386      * @param event The QShowEvent sent by Qt.
387      */
388     void showEvent(QShowEvent *event) override;
389 
390 public slots:
391     /**
392      * @brief Shows the ConfigPanelDialog and shows the "Config Panel"
393      * page, i.e. calls showConfigPanelPage(). If the dialog does not
394      * exist yet, it will be created before.
395      *
396      * The "Configure Panel" button in the context menu of the panel will
397      * be connected to this slot so this method gets called whenever the
398      * user clicks that button.
399      *
400      * Furthermore, this method will be called by LXQtPanelApplication
401      * when a new plugin gets added (the LXQtPanel instances are handled
402      * by LXQtPanelApplication). That is why this method/slot has to be
403      * public.
404      */
405     void showConfigDialog();
406 
407 private slots:
408     /**
409      * @brief Shows the ConfigPanelDialog and shows the "Config Plugins"
410      * page, i.e. calls showConfigPluginsPage(). If the dialog does not
411      * exist yet, it will be created before.
412      *
413      * The "Manage Widgets" button in the context menu of the panel will
414      * be connected to this slot so this method gets called whenever the
415      * user clicks that button.
416      */
417     void showAddPluginDialog();
418     /**
419      * @brief Recalculates the geometry of the panel and reserves the
420      * window manager strut, i.e. it calls setPanelGeometry() and
421      * updateWmStrut().
422      * Two signals will be connected to this slot:
423      * 1. QDesktopWidget::workAreaResized(int screen) which will be emitted
424      * when the work area available (on screen) changes.
425      * 2. LXQt::Application::themeChanged(), i.e. when the user changes
426      * the theme.
427      */
428     void realign();
429     /**
430      * @brief Moves a plugin in PanelPluginsModel, i.e. calls
431      * PanelPluginsModel::movePlugin(Plugin * plugin, QString const & nameAfter).
432      * LXQtPanelLayout::pluginMoved() will be connected to this slot so
433      * it gets called whenever a plugin was moved in the layout by the user.
434      * @param plug
435      */
436     void pluginMoved(Plugin * plug);
437     /**
438      * @brief Removes this panel's entries from the config file and emits
439      * the deletedByUser signal.
440      * The "Remove Panel" button in the panel's contex menu will
441      * be connected to this slot, so this method will be called whenever
442      * the user clicks "Remove Panel".
443      */
444     void userRequestForDeletion();
445 
446 private:
447     /**
448      * @brief The LXQtPanelLayout of this panel. All the Plugins will be added
449      * to the UI via this layout.
450      */
451     LXQtPanelLayout* mLayout;
452     /**
453      * @brief The LXQt::Settings instance as retrieved from
454      * LXQtPanelApplication.
455      */
456     LXQt::Settings *mSettings;
457     /**
458      * @brief The background widget for the panel. This background widget will
459      * have the background color or the background image if any of these is
460      * set. This background widget will have the LXQtPanelLayout mLayout which
461      * will in turn contain all the Plugins.
462      */
463     QFrame *LXQtPanelWidget;
464     /**
465      * @brief The name of the panel which will also be used as an identifier
466      * for config files.
467      */
468     QString mConfigGroup;
469     /**
470      * @brief Pointer to the PanelPluginsModel which will store all the Plugins
471      * that are loaded.
472      */
473     QScopedPointer<PanelPluginsModel> mPlugins;
474     /**
475      * @brief object for storing info if some standalone window is shown
476      * (for preventing hide)
477      */
478     QScopedPointer<WindowNotifier> mStandaloneWindows;
479 
480     /**
481      * @brief Returns the screen index of a screen on which this panel could
482      * be placed at the given position. If possible, the current screen index
483      * is preserved. So, if the panel can be placed on the current screen, the
484      * index of that screen will be returned.
485      * @param position position at which the panel should be placed.
486      * @return The current screen index if the panel can be placed on the
487      * current screen or the screen index of a screen that it can be placed on.
488      *
489      * \sa canPlacedOn(), mScreenNum, mActualScreenNum.
490      */
491     int findAvailableScreen(LXQtPanel::Position position);
492     /**
493      * @brief Update the window manager struts _NET_WM_PARTIAL_STRUT and
494      * _NET_WM_STRUT for this widget. "The purpose of struts is to reserve
495      * space at the borders of the desktop. This is very useful for a
496      * docking area, a taskbar or a panel, for instance. The Window Manager
497      * should take this reserved area into account when constraining window
498      * positions - maximized windows, for example, should not cover that
499      * area."
500      * \sa http://standards.freedesktop.org/wm-spec/wm-spec-latest.html#NETWMSTRUT
501      */
502     void updateWmStrut();
503 
504     /**
505      * @brief Loads the plugins, i.e. creates a new PanelPluginsModel.
506      * Connects the signals and slots and adds all the plugins to the
507      * layout.
508      */
509     void loadPlugins();
510 
511     /**
512      * @brief Calculates and sets the geometry (i.e. the position and the size
513      * on the screen) of the panel. Considers alignment, position, if the panel
514      * is hidden and if its geometry should be set with animation.
515      * \param animate flag if showing/hiding the panel should be animated.
516      */
517     void setPanelGeometry(bool animate = false);
518     /**
519      * @brief Sets the contents margins of the panel according to its position
520      * and hiddenness. All margins are zero for visible panels.
521      */
522     void setMargins();
523     /**
524      * @brief Calculates the height of the panel if it is horizontal or the
525      * width if the panel is vertical. Considers if the panel is hidden and
526      * ensures that the result is at least PANEL_MINIMUM_SIZE.
527      * @return The height/width of the panel.
528      */
529     int getReserveDimension();
530     /**
531      * @brief Stores the geometry of the non-hidden panel, for use in
532      * calculatePopupWindowPos()
533      */
534     QRect mGeometry;
535     /**
536      * @brief Stores the size of the panel, i.e. the height of a horizontal
537      * panel or the width of a vertical panel in pixels. If the panel is
538      * hidden (which is achieved by making the panel very thin), this value
539      * is unchanged. So this value stores the size of the non-hidden panel.
540      *
541      * \sa panelSize(), setPanelSize().
542      */
543     int mPanelSize;
544     /**
545      * @brief Stores the edge length of the panel icons in pixels.
546      *
547      * \sa ILXQtPanel::iconSize(), setIconSize().
548      */
549     int mIconSize;
550     /**
551      * @brief Stores the number of lines/rows of the panel.
552      *
553      * \sa ILXQtPanel::lineCount(), setLineCount().
554      */
555     int mLineCount;
556 
557     /**
558      * @brief Stores the length of the panel, i.e. the width of a horizontal
559      * panel or the height of a vertical panel. The unit of this value is
560      * determined by mLengthInPercents.
561      *
562      * \sa mLengthInPercents
563      */
564     int mLength;
565     /**
566      * @brief Stores if mLength is stored in pixels or relative to the
567      * screen size in percents. If true, the length is stored in percents,
568      * otherwise in pixels.
569      *
570      * \sa mLength
571      */
572     bool mLengthInPercents;
573 
574     /**
575      * @brief Stores how this panel is aligned. The meaning of this value
576      * differs for horizontal and vertical panels.
577      *
578      * \sa Alignment.
579      */
580     Alignment mAlignment;
581 
582     /**
583      * @brief Stores the position where the panel is shown
584      */
585     ILXQtPanel::Position mPosition;
586     /**
587      * @brief Returns the index of the screen on which this panel should be
588      * shown. This is the user configured value which can differ from the
589      * screen that the panel is actually shown on. If the panel can not be
590      * shown on the configured screen, LXQtPanel will determine another
591      * screen. The screen that the panel is actually shown on is stored in
592      * mActualScreenNum.
593      *
594      * @return The index of the screen on which this panel should be shown.
595      *
596      * \sa mActualScreenNum, canPlacedOn(), findAvailableScreen().
597      */
598     int mScreenNum;
599     /**
600      * @brief screen that the panel is currently shown at (this could
601      * differ from mScreenNum).
602      *
603      * \sa mScreenNum, canPlacedOn(), findAvailableScreen().
604      */
605     int mActualScreenNum;
606     /**
607      * @brief QTimer for delayed saving of changed settings. In many cases,
608      * instead of storing changes to disk immediately we start this timer.
609      * If this timer times out, we store the changes to disk. This has the
610      * advantage that we can store a couple of changes with only one write to
611      * disk.
612      *
613      * \sa saveSettings()
614      */
615     QTimer mDelaySave;
616     /**
617      * @brief Stores if the panel is hidable, i.e. if the panel will be
618      * hidden after the cursor has left the panel area.
619      *
620      * \sa mVisibleMargin, mHidden, mHideTimer, showPanel(), hidePanel(), hidePanelWork()
621      */
622     bool mHidable;
623     /**
624      * @brief Stores if the hidable panel should have a visible margin.
625      *
626      * \sa mHidable, mHidden, mHideTimer, showPanel(), hidePanel(), hidePanelWork()
627      */
628     bool mVisibleMargin;
629     /**
630      * @brief Stores if the panel should hide on overlapping a window.
631      *
632      * \sa mHidable, mHidden, mHideTimer, showPanel(), hidePanel(), hidePanelWork()
633      */
634     bool mHideOnOverlap;
635     /**
636      * @brief Stores if the panel is currently hidden.
637      *
638      * \sa mHidable, mVisibleMargin, mHideTimer, showPanel(), hidePanel(), hidePanelWork()
639      */
640     bool mHidden;
641     /**
642      * @brief QTimer for hiding the panel. When the cursor leaves the panel
643      * area, this timer will be started. After this timer has timed out, the
644      * panel will actually be hidden.
645      *
646      * \sa mHidable, mVisibleMargin, mHidden, showPanel(), hidePanel(), hidePanelWork()
647      */
648     QTimer mHideTimer;
649     /**
650      * @brief Stores the duration of auto-hide animation.
651      *
652      * \sa mHidden, mHideTimer, showPanel(), hidePanel(), hidePanelWork()
653      */
654     int mAnimationTime;
655     /**
656      * @brief The timer used for showing an auto-hiding panel wih delay.
657      *
658      * \sa showPanel()
659      */
660     QTimer mShowDelayTimer;
661 
662     QColor mFontColor; //!< Font color that is used in the style sheet.
663     QColor mBackgroundColor; //!< Background color that is used in the style sheet.
664     QString mBackgroundImage; //!< Background image that is used in the style sheet.
665     /**
666      * @brief Determines the opacity of the background color. The value
667      * should be in the range from 0 to 100. This will not affect the opacity
668      * of a background image.
669      */
670     int mOpacity;
671     /*!
672      * \brief Flag if the panel should reserve the space under it as not usable
673      * for "normal" windows. Usable for not 100% wide/hight or hiddable panels,
674      * if user wants maximized windows go under the panel.
675      *
676      * \sa updateWmStrut()
677      */
678     bool mReserveSpace;
679 
680     /**
681      * @brief Pointer to the current ConfigPanelDialog if there is any. Make
682      * sure to test this pointer for validity because it is lazily loaded.
683      */
684     QPointer<ConfigPanelDialog> mConfigDialog;
685 
686     /**
687      * @brief The animation used for showing/hiding an auto-hiding panel.
688      */
689     QPropertyAnimation *mAnimation;
690 
691     /**
692      * @brief Flag for providing the configuration options in panel's context menu
693      */
694     bool mLockPanel;
695 
696     /**
697      * @brief Updates the style sheet for the panel. First, the stylesheet is
698      * created from the preferences. Then, it is set via
699      * QWidget::setStyleSheet().
700      */
701     void updateStyleSheet();
702 
703     /**
704      * @brief Checks if the panel overlaps a window.
705      */
706     bool isPanelOverlapped() const;
707 
708     // settings should be kept private for security
settings()709     LXQt::Settings *settings() const { return mSettings; }
710 };
711 
712 
713 #endif // LXQTPANEL_H
714