File indexing completed on 2024-05-12 05:38:24

0001 /*
0002     SPDX-FileCopyrightText: 2009 Aaron Seigo <aseigo@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "panel.h"
0008 
0009 #include <QAction>
0010 #include <QQuickItem>
0011 
0012 #include <Plasma/Containment>
0013 #include <Plasma/Corona>
0014 #include <QScreen>
0015 
0016 #include "panelview.h"
0017 #include "scriptengine.h"
0018 #include "shellcorona.h"
0019 #include "widget.h"
0020 
0021 namespace WorkspaceScripting
0022 {
0023 Panel::Panel(Plasma::Containment *containment, ScriptEngine *engine)
0024     : Containment(containment, engine)
0025 {
0026 }
0027 
0028 Panel::~Panel()
0029 {
0030 }
0031 
0032 QString Panel::location() const
0033 {
0034     Plasma::Containment *c = containment();
0035     if (!c) {
0036         return "floating";
0037     }
0038 
0039     switch (c->location()) {
0040     case Plasma::Types::Floating:
0041         return "floating";
0042     case Plasma::Types::Desktop:
0043         return "desktop";
0044     case Plasma::Types::FullScreen:
0045         return "fullscreen";
0046     case Plasma::Types::TopEdge:
0047         return "top";
0048     case Plasma::Types::BottomEdge:
0049         return "bottom";
0050     case Plasma::Types::LeftEdge:
0051         return "left";
0052     case Plasma::Types::RightEdge:
0053         return "right";
0054     }
0055 
0056     return "floating";
0057 }
0058 
0059 void Panel::setLocation(const QString &locationString)
0060 {
0061     Plasma::Containment *c = containment();
0062     if (!c) {
0063         return;
0064     }
0065 
0066     const QString lower = locationString.toLower();
0067     Plasma::Types::Location loc = Plasma::Types::Floating;
0068     Plasma::Types::FormFactor ff = Plasma::Types::Planar;
0069     if (lower == "desktop") {
0070         loc = Plasma::Types::Desktop;
0071     } else if (lower == "fullscreen") {
0072         loc = Plasma::Types::FullScreen;
0073     } else if (lower == "top") {
0074         loc = Plasma::Types::TopEdge;
0075         ff = Plasma::Types::Horizontal;
0076     } else if (lower == "bottom") {
0077         loc = Plasma::Types::BottomEdge;
0078         ff = Plasma::Types::Horizontal;
0079     } else if (lower == "left") {
0080         loc = Plasma::Types::LeftEdge;
0081         ff = Plasma::Types::Vertical;
0082     } else if (lower == "right") {
0083         loc = Plasma::Types::RightEdge;
0084         ff = Plasma::Types::Vertical;
0085     }
0086 
0087     c->setLocation(loc);
0088     c->setFormFactor(ff);
0089 
0090     /*
0091      * After location is set, one layout script will usually start adding widgets.
0092      * It's required to emit formFactorChanged() to update plasmoid.formFactor bindings
0093      * in QML side to avoid Layout issues.
0094      *
0095      * @see isHorizontal in plasma-desktop/containments/panel/contents/ui/main.qml
0096      */
0097     c->flushPendingConstraintsEvents();
0098 }
0099 
0100 PanelView *Panel::panel() const
0101 {
0102     Plasma::Containment *c = containment();
0103     if (!c || !corona()) {
0104         return nullptr;
0105     }
0106 
0107     return corona()->panelView(c);
0108 }
0109 
0110 // NOTE: this is used *only* for alignment and visibility
0111 KConfigGroup Panel::panelConfig() const
0112 {
0113     int screenNum = qMax(screen(), 0); // if we don't have a screen (-1) we'll be put on screen 0
0114 
0115     if (QGuiApplication::screens().size() < screenNum) {
0116         return KConfigGroup();
0117     }
0118     QScreen *s = QGuiApplication::screens().at(screenNum);
0119     return PanelView::panelConfig(corona(), containment(), s);
0120 }
0121 
0122 // NOTE: when we don't have a view we should write only to the defaults group as we don't know yet during startup if we are on the "final" screen resolution yet
0123 KConfigGroup Panel::panelConfigDefaults() const
0124 {
0125     int screenNum = qMax(screen(), 0); // if we don't have a screen (-1) we'll be put on screen 0
0126 
0127     if (QGuiApplication::screens().size() < screenNum) {
0128         return KConfigGroup();
0129     }
0130     QScreen *s = QGuiApplication::screens().at(screenNum);
0131     return PanelView::panelConfigDefaults(corona(), containment(), s);
0132 }
0133 
0134 // NOTE: Alignment is the only one that reads and writes directly from panelconfig()
0135 QString Panel::alignment() const
0136 {
0137     int alignment;
0138     if (panel()) {
0139         alignment = panel()->alignment();
0140     } else {
0141         alignment = panelConfig().readEntry("alignment", 0);
0142     }
0143 
0144     switch (alignment) {
0145     case Qt::AlignRight:
0146         return "right";
0147     case Qt::AlignCenter:
0148         return "center";
0149     default:
0150         return "left";
0151     }
0152 
0153     return "left";
0154 }
0155 
0156 // NOTE: Alignment is the only one that reads and writes directly from panelconfig()
0157 void Panel::setAlignment(const QString &alignment)
0158 {
0159     int a = Qt::AlignCenter;
0160     if (alignment.compare("left", Qt::CaseInsensitive) == 0) {
0161         a = Qt::AlignLeft;
0162     } else if (alignment.compare("right", Qt::CaseInsensitive) == 0) {
0163         a = Qt::AlignRight;
0164     }
0165 
0166     // Always prefer the view, if available
0167     if (panel()) {
0168         panel()->setAlignment(Qt::Alignment(a));
0169     } else {
0170         panelConfig().writeEntry("alignment", a);
0171     }
0172 }
0173 
0174 // NOTE: lengthMode also reads and writes directly from panelConfig() because it
0175 // is resolution independent
0176 QString Panel::lengthMode() const
0177 {
0178     int lengthMode;
0179     if (panel()) {
0180         lengthMode = panel()->lengthMode();
0181     } else {
0182         lengthMode = panelConfig().readEntry("panelLengthMode", 0);
0183     }
0184 
0185     switch (lengthMode) {
0186     case PanelView::LengthMode::FillAvailable:
0187         return "fill";
0188     case PanelView::LengthMode::FitContent:
0189         return "fit";
0190     case PanelView::LengthMode::Custom:
0191         return "custom";
0192     }
0193 
0194     return "fill";
0195 }
0196 
0197 void Panel::setLengthMode(const QString &mode)
0198 {
0199     PanelView::LengthMode lengthMode = PanelView::LengthMode::FillAvailable;
0200     if (mode.compare("fit", Qt::CaseInsensitive) == 0) {
0201         lengthMode = PanelView::LengthMode::FitContent;
0202     } else if (mode.compare("custom", Qt::CaseInsensitive) == 0) {
0203         lengthMode = PanelView::LengthMode::Custom;
0204     }
0205 
0206     if (panel()) {
0207         panel()->setLengthMode(lengthMode);
0208     } else {
0209         panelConfig().writeEntry("panelLengthMode", (int)lengthMode);
0210     }
0211 }
0212 
0213 // From now on only panelConfigDefaults should be used
0214 int Panel::offset() const
0215 {
0216     if (panel()) {
0217         return panel()->offset();
0218     } else {
0219         return panelConfigDefaults().readEntry("offset", 0);
0220     }
0221 }
0222 
0223 void Panel::setOffset(int pixels)
0224 {
0225     panelConfigDefaults().writeEntry("offset", pixels);
0226     if (panel()) {
0227         panel()->setOffset(pixels);
0228     } else {
0229         panelConfigDefaults().readEntry("offset", pixels);
0230     }
0231 }
0232 
0233 int Panel::length() const
0234 {
0235     if (panel()) {
0236         return panel()->length();
0237     } else {
0238         return panelConfigDefaults().readEntry("length", 0);
0239     }
0240 }
0241 
0242 void Panel::setLength(int pixels)
0243 {
0244     if (panel()) {
0245         panel()->setLength(pixels);
0246     } else {
0247         panelConfigDefaults().writeEntry("length", pixels);
0248     }
0249 }
0250 
0251 int Panel::minimumLength() const
0252 {
0253     if (panel()) {
0254         return panel()->minimumLength();
0255     } else {
0256         return panelConfigDefaults().readEntry("minLength", 0);
0257     }
0258 }
0259 
0260 void Panel::setMinimumLength(int pixels)
0261 {
0262     if (panel()) {
0263         panel()->setMinimumLength(pixels);
0264     } else {
0265         panelConfigDefaults().writeEntry("minLength", pixels);
0266     }
0267 }
0268 
0269 int Panel::maximumLength() const
0270 {
0271     if (panel()) {
0272         return panel()->maximumLength();
0273     } else {
0274         return panelConfigDefaults().readEntry("maxLength", 0);
0275     }
0276 }
0277 
0278 void Panel::setMaximumLength(int pixels)
0279 {
0280     if (panel()) {
0281         panel()->setMaximumLength(pixels);
0282     } else {
0283         panelConfigDefaults().writeEntry("maxLength", pixels);
0284     }
0285 }
0286 
0287 int Panel::height() const
0288 {
0289     if (panel()) {
0290         return panel()->thickness();
0291     } else {
0292         return panelConfigDefaults().readEntry("thickness", 0);
0293     }
0294 }
0295 
0296 void Panel::setHeight(int height)
0297 {
0298     if (panel()) {
0299         panel()->setThickness(height);
0300     } else {
0301         panelConfigDefaults().writeEntry("thickness", height);
0302     }
0303 }
0304 
0305 QString Panel::hiding() const
0306 {
0307     int visibility;
0308     if (panel()) {
0309         visibility = panel()->visibilityMode();
0310     } else {
0311         visibility = panelConfig().readEntry("panelVisibility", 0);
0312     }
0313 
0314     switch (visibility) {
0315     case PanelView::NormalPanel:
0316         return "none";
0317     case PanelView::AutoHide:
0318         return "autohide";
0319     case PanelView::DodgeWindows:
0320         return "dodgewindows";
0321     }
0322     return "none";
0323 }
0324 
0325 void Panel::setHiding(const QString &mode)
0326 {
0327     PanelView::VisibilityMode visibilityMode = PanelView::NormalPanel;
0328     if (mode.compare("autohide", Qt::CaseInsensitive) == 0) {
0329         visibilityMode = PanelView::AutoHide;
0330     }
0331     if (mode.compare("dodgewindows", Qt::CaseInsensitive) == 0) {
0332         visibilityMode = PanelView::DodgeWindows;
0333     }
0334     if (mode.compare("windowsgobelow", Qt::CaseInsensitive) == 0) {
0335         visibilityMode = PanelView::WindowsGoBelow;
0336     }
0337 
0338     if (panel()) {
0339         panel()->setVisibilityMode(visibilityMode);
0340     } else {
0341         panelConfig().writeEntry("panelVisibility", (int)visibilityMode);
0342     }
0343 }
0344 
0345 bool Panel::floating() const
0346 {
0347     if (panel()) {
0348         return panel()->floating();
0349     } else {
0350         return panelConfig().readEntry("floating", true);
0351     }
0352 }
0353 
0354 void Panel::setFloating(bool floating)
0355 {
0356     if (panel()) {
0357         panel()->setFloating(floating);
0358     } else {
0359         panelConfig().writeEntry("floating", (int)floating);
0360     }
0361 }
0362 }