diff options
Diffstat (limited to 'src-qt5/core')
59 files changed, 845 insertions, 378 deletions
diff --git a/src-qt5/core/libLumina/ExternalProcess.h b/src-qt5/core/libLumina/ExternalProcess.h index 2a6f4949..e75d6108 100644 --- a/src-qt5/core/libLumina/ExternalProcess.h +++ b/src-qt5/core/libLumina/ExternalProcess.h @@ -21,6 +21,7 @@ class ExternalProcess : public QProcess{ Q_OBJECT private: bool cursorRestored; + QString logoutput; private slots: void resetCursor(){ @@ -46,6 +47,9 @@ private slots: //Clean up this object this->deleteLater(); } + void updateLog(){ + logoutput.append( QString(this->readAllStandardOutput()) ); + } public: ExternalProcess(QString logfile = "", bool manageCursors = false) : QProcess(){ @@ -53,6 +57,8 @@ public: cursorRestored = !manageCursors; if(logfile.isEmpty()){ this->setStandardOutputFile(QProcess::nullDevice()); + }else if(logfile=="stdout"){ + connect(this, SIGNAL(readyReadStandardOutput()), this, SLOT(updateLog()) ); }else{ this->setStandardOutputFile(logfile); } @@ -67,6 +73,11 @@ public: }*/ } + QString log(){ + //NOTE: This will only contain output if the "stdout" argument is used as the logfile + return logoutput; + } + static void launch(QString program, QStringList args = QStringList(), bool manageCursors = true){ //Quick launch of a process with logging disabled and automatic cleanup ExternalProcess *tmp = new ExternalProcess("", manageCursors); diff --git a/src-qt5/core/libLumina/LDesktopUtils.cpp b/src-qt5/core/libLumina/LDesktopUtils.cpp index 69d4ba52..5595532a 100644 --- a/src-qt5/core/libLumina/LDesktopUtils.cpp +++ b/src-qt5/core/libLumina/LDesktopUtils.cpp @@ -13,10 +13,8 @@ #include "LuminaThemes.h" -static QStringList fav; - QString LDesktopUtils::LuminaDesktopVersion(){ - QString ver = "1.4.0"; + QString ver = "1.4.1"; #ifdef GIT_VERSION ver.append( QString(" (Git Revision: %1)").arg(GIT_VERSION) ); #endif @@ -80,22 +78,23 @@ QStringList LDesktopUtils::infoQuickPlugin(QString ID){ //Returns: [Name, Descri } QStringList LDesktopUtils::listFavorites(){ - static QDateTime lastRead; - QDateTime cur = QDateTime::currentDateTime(); - if(lastRead.isNull() || lastRead<QFileInfo( QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/favorites.list").lastModified()){ + //static QDateTime lastRead; + QStringList fav; + //QDateTime cur = QDateTime::currentDateTime(); + //if(lastRead.isNull() || fav.isEmpty() || lastRead<QFileInfo( QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/favorites.list").lastModified()){ fav = LUtils::readFile(QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/favorites.list"); fav.removeAll(""); //remove any empty lines fav.removeDuplicates(); - lastRead = cur; - } - + //lastRead = cur; + //} return fav; } bool LDesktopUtils::saveFavorites(QStringList list){ list.removeDuplicates(); + //qDebug() << "Save Favorites:" << list; bool ok = LUtils::writeFile(QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/favorites.list", list, true); - if(ok){ fav = list; } //also save internally in case of rapid write/read of the file + //if(ok){ fav = list; } //also save internally in case of rapid write/read of the file return ok; } @@ -116,11 +115,13 @@ bool LDesktopUtils::addFavorite(QString path, QString name){ else{ type = LXDG::findAppMimeForFile(path); } //Assign a name if none given if(name.isEmpty()){ name = info.fileName(); } + //qDebug() << "Add Favorite:" << path << type << name; //Now add it to the list QStringList favs = LDesktopUtils::listFavorites(); + //qDebug() << "Current Favorites:" << favs; bool found = false; for(int i=0; i<favs.length(); i++){ - if(favs[i].endsWith("::::"+path)){ favs[i] = name+"::::"+type+"::::"+path; } + if(favs[i].endsWith("::::"+path)){ favs[i] = name+"::::"+type+"::::"+path; found = true; } } if(!found){ favs << name+"::::"+type+"::::"+path; } return LDesktopUtils::saveFavorites(favs); @@ -143,8 +144,15 @@ void LDesktopUtils::upgradeFavorites(int){ //fromoldversionnumber void LDesktopUtils::LoadSystemDefaults(bool skipOS){ //Will create the Lumina configuration files based on the current system template (if any) qDebug() << "Loading System Defaults"; + //Ensure that the settings directory exists + QString setdir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop"; + if(!QFile::exists(setdir)){ + QDir dir; + dir.mkpath(setdir); + } + bool skipmime = QFile::exists( QString(getenv("XDG_CONFIG_HOME"))+"/lumina-mimapps.list" ); - qDebug() << " - Skipping mimetype default apps" << skipmime; + //qDebug() << " - Skipping mimetype default apps" << skipmime; QStringList sysDefaults; if(!skipOS){ sysDefaults = LUtils::readFile(LOS::AppPrefix()+"etc/luminaDesktop.conf"); } if(sysDefaults.isEmpty() && !skipOS){ sysDefaults = LUtils::readFile(LOS::AppPrefix()+"etc/luminaDesktop.conf.dist"); } @@ -187,6 +195,8 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ if(var.endsWith("_ifexists") ){ var = var.remove("_ifexists"); //remove this flag from the variable //Check if the value exists (absolute path only) + val = LUtils::AppToAbsolute(val); + //qDebug() << "Checking if favorite app exists:" << val; if(!QFile::exists(val)){ continue; } //skip this line - value/file does not exist } @@ -231,20 +241,23 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ if(tmp[i].startsWith("#") || !tmp[i].contains("=") ){ continue; } QString var = tmp[i].section("=",0,0).toLower().simplified(); QString val = tmp[i].section("=",1,1).section("#",0,0).simplified(); + qDebug() << "Mime entry:" << var << val; if(val.isEmpty()){ continue; } QString istrue = (val.toLower()=="true") ? "true": "false"; //Change in 0.8.5 - use "_" instead of "." within variables names - need backwards compat for a little while if(var.contains(".")){ var.replace(".","_"); } //Now parse the variable and put the value in the proper file - val = LUtils::AppToAbsolute(val); //Special handling for values which need to exist first if(var.endsWith("_ifexists") ){ var = var.remove("_ifexists"); //remove this flag from the variable + val = LUtils::AppToAbsolute(val); + //qDebug() << "Checking if Mime app exists:" << val; //Check if the value exists (absolute path only) if(!QFile::exists(val)){ continue; } //skip this line - value/file does not exist } //Now turn this variable into the mimetype only var = var.section("_default_",1,-1); + //qDebug() << " - Set Default Mime:" << var << val; LXDG::setDefaultAppForMime(var, val); } @@ -326,6 +339,7 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ tmp = sysDefaults.filter("favorites_"); if(tmp.isEmpty()){ tmp = sysDefaults.filter("favorites."); } for(int i=0; i<tmp.length(); i++){ + //qDebug() << "Found Favorite Entry:" << tmp[i]; if(tmp[i].startsWith("#") || !tmp[i].contains("=") ){ continue; } QString var = tmp[i].section("=",0,0).toLower().simplified(); QString val = tmp[i].section("=",1,1).section("#",0,0).simplified(); @@ -334,7 +348,7 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ //Now parse the variable and put the value in the proper file qDebug() << "Favorite entry:" << var << val; val = LUtils::AppToAbsolute(val); //turn any relative files into absolute - if(var=="favorites_add_ifexists" && QFile::exists(val)){ qDebug() << " - Exists/Adding:"; LDesktopUtils::addFavorite(val); } + if(var=="favorites_add_ifexists" && QFile::exists(val)){ qDebug() << " - Exists/Adding:" << val; LDesktopUtils::addFavorite(val); } else if(var=="favorites_add"){ qDebug() << " - Adding:"; LDesktopUtils::addFavorite(val); } else if(var=="favorites_remove"){ qDebug() << " - Removing:"; LDesktopUtils::removeFavorite(val); } } @@ -385,6 +399,7 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ if(var.contains(".")){ var.replace(".","_"); } //Now parse the variable and put the value in the proper file if(var=="theme_themefile"){ themesettings[0] = val; } + else if(var=="theme_styles"){ LTHEME::setCurrentStyles( val.split(",",QString::SkipEmptyParts) ); } else if(var=="theme_colorfile"){ themesettings[1] = val; } else if(var=="theme_iconset"){ themesettings[2] = val; } else if(var=="theme_font"){ themesettings[3] = val; } @@ -425,12 +440,6 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ } //qDebug() << " - Final Theme Color:" << themesettings[1]; - //Ensure that the settings directory exists - QString setdir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop"; - if(!QFile::exists(setdir)){ - QDir dir; - dir.mkpath(setdir); - } //Now save the settings files if(setTheme){ LTHEME::setCurrentSettings( themesettings[0], themesettings[1], themesettings[2], themesettings[3], themesettings[4]); @@ -538,7 +547,7 @@ bool LDesktopUtils::checkUserFiles(QString lastversion, QString currentversion){ newtheme.setValue("Interface/desktop_stylesheets", QStringList() << enginedir+"desktop_qss/Glass.qss"); } newtheme.setValue("Appearance/style", "Fusion"); - newtheme.setValue("Interface/stylesheets", QStringList() << enginedir+"qss/tooltip-simple.qss" << enginedir+"qss/scrollbar-simple.qss" << enginedir+"qss/sliders-simple.qss"); + newtheme.setValue("Interface/stylesheets", QStringList() << enginedir+"qss/tooltip-simple.qss" << enginedir+"qss/scrollbar-simple.qss" << enginedir+"qss/sliders-simple.qss" << enginedir+"qss/traynotification-simple.qss"); newtheme.sync(); //flush this to file right now } //end check for theme file existance } @@ -569,7 +578,7 @@ bool LDesktopUtils::checkUserFiles(QString lastversion, QString currentversion){ } int LDesktopUtils::VersionStringToNumber(QString version){ - version = version.section("-",0,0); //trim any extra labels off the end + version = version.section("_",0,0).section("-",0,0); //trim any extra labels off the end int maj, mid, min; //major/middle/minor version numbers (<Major>.<Middle>.<Minor>) maj = mid = min = 0; bool ok = true; diff --git a/src-qt5/core/libLumina/LUtils.pri b/src-qt5/core/libLumina/LUtils.pri index 6ce0839c..da5a78d5 100644 --- a/src-qt5/core/libLumina/LUtils.pri +++ b/src-qt5/core/libLumina/LUtils.pri @@ -15,8 +15,7 @@ GIT_VERSION=$$system(git describe --always) #DEFINES += BUILD_DATE='"\\\"$$system(date)\\\""' #LuminaOS files -HEADERS *= $${PWD}/LuminaOS.h \ - $${PWD}/OSInterface.h +HEADERS *= $${PWD}/LuminaOS.h # LuminaOS support functions (or fall back to generic one) exists($${PWD}/LuminaOS-$${LINUX_DISTRO}.cpp){ @@ -26,13 +25,6 @@ exists($${PWD}/LuminaOS-$${LINUX_DISTRO}.cpp){ }else{ SOURCES *= $${PWD}/LuminaOS-template.cpp } -exists($${PWD}/OSInterface-$${LINUX_DISTRO}.cpp){ - SOURCES *= $${PWD}/OSInterface-$${LINUX_DISTRO}.cpp -}else:exists($${PWD}/OSInterface-$${OS}.cpp){ - SOURCES *= $${PWD}/OSInterface-$${OS}.cpp -}else{ - SOURCES *= $${PWD}/OSInterface-template.cpp -} #LUtils Files SOURCES *= $${PWD}/LUtils.cpp diff --git a/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp b/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp index dc7de37f..1ee8fb8a 100644 --- a/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp +++ b/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp @@ -30,7 +30,7 @@ QString LOS::AppStoreShortcut(){ return "/usr/local/share/applications/appcafe.d QStringList LOS::RSSFeeds(){ QStringList feeds; feeds << "FreeBSD News Feed::::https://www.freebsd.org/news/rss.xml"; - feeds << "TrueOS News Feed::::http://www.trueos.org/?feed=rss2"; + feeds << "TrueOS News Feed::::http://www.trueos.org/feed/"; return feeds; } diff --git a/src-qt5/core/libLumina/LuminaSingleApplication.cpp b/src-qt5/core/libLumina/LuminaSingleApplication.cpp index 5d276805..6107aff8 100644 --- a/src-qt5/core/libLumina/LuminaSingleApplication.cpp +++ b/src-qt5/core/libLumina/LuminaSingleApplication.cpp @@ -11,7 +11,7 @@ #include <QDebug> #include <QX11Info> -#include <unistd.h> //for getlogin() +#include <unistd.h> //for getuid() LSingleApplication::LSingleApplication(int &argc, char **argv, QString appname) : QApplication(argc, argv){ //Load the proper translation systems @@ -19,7 +19,7 @@ LSingleApplication::LSingleApplication(int &argc, char **argv, QString appname) if(appname!="lumina-desktop"){ cTrans = LUtils::LoadTranslation(this, appname); }//save the translator for later //Initialize a couple convenience internal variables cfile = QDir::tempPath()+"/.LSingleApp-%1-%2-%3"; - QString username = QString(getuid()); + QString username = QString::number(getuid()); //For locking the process use the official process name - not the user input (no masking) appname = this->applicationName(); cfile = cfile.arg( username, appname, QString::number(QX11Info::appScreen()) ); diff --git a/src-qt5/core/libLumina/LuminaThemes.cpp b/src-qt5/core/libLumina/LuminaThemes.cpp index 857e604b..03524941 100644 --- a/src-qt5/core/libLumina/LuminaThemes.cpp +++ b/src-qt5/core/libLumina/LuminaThemes.cpp @@ -34,6 +34,17 @@ QStringList LTHEME::availableSystemThemes(){ return list; } +QStringList LTHEME::availableSystemStyles(){ + //returns: [name::::path] for each item + QDir dir(LOS::LuminaShare()+"../lthemeengine/qss"); + QStringList list = dir.entryList(QStringList() <<"*.qss", QDir::Files, QDir::Name); + for(int i=0; i<list.length(); i++){ + //Format the output entry [<name>::::<fullpath>] + list[i] = list[i].section(".qss",0,0)+"::::"+dir.absoluteFilePath(list[i]); + } + return list; +} + QStringList LTHEME::availableLocalThemes(){ //returns: [name::::path] for each item QDir dir( QString(getenv("XDG_CONFIG_HOME"))+"/lthemeengine/desktop_qss"); QStringList list = dir.entryList(QStringList() <<"*.qss", QDir::Files, QDir::Name); @@ -44,6 +55,16 @@ QStringList LTHEME::availableLocalThemes(){ //returns: [name::::path] for each i return list; } +QStringList LTHEME::availableLocalStyles(){ //returns: [name::::path] for each item + QDir dir( QString(getenv("XDG_CONFIG_HOME"))+"/lthemeengine/qss"); + QStringList list = dir.entryList(QStringList() <<"*.qss", QDir::Files, QDir::Name); + for(int i=0; i<list.length(); i++){ + //Format the output entry [<name>::::<fullpath>] + list[i] = list[i].section(".qss",0,0)+"::::"+dir.absoluteFilePath(list[i]); + } + return list; +} + QStringList LTHEME::availableSystemColors(){ //returns: [name::::path] for each item //returns: [name::::path] for each item QDir dir(LOS::LuminaShare()+"../lthemeengine/colors"); @@ -244,6 +265,23 @@ bool LTHEME::setCursorTheme(QString cursorname){ return LUtils::writeFile(QDir::homePath()+"/.icons/default/index.theme", info, true); } +bool LTHEME::setCurrentStyles(QStringList paths){ + //Verify that the paths are all absolute paths, otherwise scan/replace with absolute paths + QStringList avail = LTHEME::availableSystemStyles(); + for(int i=0; i<paths.length(); i++){ + paths[i] = paths[i].simplified(); + if(paths[i].startsWith("/")){ continue; } //already an absolute path + for(int j=0; j<avail.length(); j++){ + if(avail[j].startsWith(paths[i].section("/",-1).section(".qss",0,0)+"::::") ){ paths[i] = avail[j].section("::::",1,-1); break; } + } + } + //ordered by priority: lowest -> highest + QSettings engineset("lthemeengine","lthemeengine"); + engineset.setValue("Interface/stylesheets",paths); + engineset.sync(); + return true; +} + //Return the complete stylesheet for a given theme/colors QString LTHEME::assembleStyleSheet(QString themepath, QString colorpath, QString font, QString fontsize){ QString stylesheet = LUtils::readFile(themepath).join("\n"); @@ -340,10 +378,10 @@ void LTHEME::LoadCustomEnvSettings(){ setenv(info[i].section("=",0,0).toLocal8Bit(), info[i].section("=",1,100).simplified().toLocal8Bit(), 1); } } - + } -bool LTHEME::setCustomEnvSetting(QString var, QString val){ +bool LTHEME::setCustomEnvSetting(QString var, QString val){ //variable/value pair (use an empty val to clear it) QStringList info = LTHEME::CustomEnvSettings(true); //user only bool changed = false; diff --git a/src-qt5/core/libLumina/LuminaThemes.h b/src-qt5/core/libLumina/LuminaThemes.h index ca79e0bd..133bd04d 100644 --- a/src-qt5/core/libLumina/LuminaThemes.h +++ b/src-qt5/core/libLumina/LuminaThemes.h @@ -25,7 +25,9 @@ class LTHEME{ public: //Read the Themes/Colors/Icons that are available on the system static QStringList availableSystemThemes();//returns: [name::::path] for each item + static QStringList availableSystemStyles();//returns: [name::::path] for each item static QStringList availableLocalThemes(); //returns: [name::::path] for each item + static QStringList availableLocalStyles(); //returns: [name::::path] for each item static QStringList availableSystemColors(); //returns: [name::::path] for each item static QStringList availableLocalColors(); //returns: [name::::path] for each item static QStringList availableSystemIcons(); //returns: [name] for each item @@ -42,6 +44,7 @@ public: //Change the current Theme/Colors/Icons static bool setCurrentSettings(QString themepath, QString colorpath, QString iconname, QString font, QString fontsize); static bool setCursorTheme(QString cursorname); + static bool setCurrentStyles(QStringList paths); //ordered by priority: lowest -> highest //Return the complete stylesheet for a given theme/colors static QString assembleStyleSheet(QString themepath, QString colorpath, QString font, QString fontsize); diff --git a/src-qt5/core/libLumina/LuminaXDG.cpp b/src-qt5/core/libLumina/LuminaXDG.cpp index 1933ba93..e1c582d9 100644 --- a/src-qt5/core/libLumina/LuminaXDG.cpp +++ b/src-qt5/core/libLumina/LuminaXDG.cpp @@ -1294,6 +1294,7 @@ QStringList LXDG::findAvailableAppsForMime(QString mime){ } void LXDG::setDefaultAppForMime(QString mime, QString app){ + //qDebug() << "Set Default App For Mime:" << mime << app; QString filepath = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-mimeapps.list"; QStringList cinfo = LUtils::readFile(filepath); //If this is a new file, make sure to add the header appropriately diff --git a/src-qt5/core/libLumina/OSInterface-template.cpp b/src-qt5/core/libLumina/OSInterface-template.cpp deleted file mode 100644 index 96b01e60..00000000 --- a/src-qt5/core/libLumina/OSInterface-template.cpp +++ /dev/null @@ -1,100 +0,0 @@ -//=========================================== -// Lumina desktop source code -// Copyright (c) 2017, Ken Moore -// Available under the 3-clause BSD license -// See the LICENSE file for full details -//=========================================== -#include <OSInterface.h> - -//=========== -// PUBLIC -//=========== - -//Simple functions used to determine if the current OS supports using this class, and what levels of support -QList<OSInterface::Interface> OSInterface::supportedNotifications(){ - //Which interfaces provide change notifications - return QList< OSInterface::Interface >(); -} - -QList<OSInterface::Interface> OSInterface::supportedStatus(){ - //Which interfaces are available for "status" requests - return QList< OSInterface::Interface >(); -} - -QList<OSInterface::Interface> OSInterface::supportedModify(){ - //Which interfaces are available for "modify" requests - return QList< OSInterface::Interface >(); -} - -//Start/stop interface watchers/notifications (each only called once per session) -void OSInterface::start(){ - //nothing to do -} - -void OSInterface::stop(){ - //nothing to do -} - -//Generic status update -QList<QVariant> OSInterface::status(OSInterface::Interface){ - // ==== Interface status output lists ==== - // Battery: [ float (percent charge), bool (is Charging), double (seconds remaining) ]; - // Volume: [int (percent volume) ] - // Devices: [ QStringList[ name, mountpoint, type (optional)] ] (List length depends on number of devices) - // Network: [bool (network access available)] - // PowerOff: [bool (can power off system)] - // Reboot: [bool (can reboot system)] - // Suspend: [bool (can suspend system)] - // Updates: [bool (is updating), bool (reboot required)] - // ========== - return QList<QVariant>(); -} - -//Individual Interface interactions -bool OSInterface::modify(OSInterface::Interface, QList<QVariant>){ //returns: success/failure - // ==== Interface modification argument lists ==== - // Battery: <NO MODIFICATION> - // Volume: [int (set percent volume) ] - // Devices: <NO MODIFICATION> - // Network: <NO MODIFICATION> - // PowerOff: [bool (skip updates - optional)] - // Reboot: [bool (skip updates - optional)] - // Suspend: [] (No input arguments) - // Updates: <NO MODIFICATION> - // ========== - return false; -} - -//================= -// PRIVATE SLOTS -//================= -//FileSystemWatcher slots -void OSInterface::watcherFileChanged(QString){ - -} - -void OSInterface::watcherDirChanged(QString){ - -} - -//IO Device slots -void OSInterface::iodeviceReadyRead(){ - -} - -void OSInterface::iodeviceAboutToClose(){ - -} - -//NetworkAccessManager slots -void OSInterface::netAccessChanged(QNetworkAccessManager::NetworkAccessibility){ - -} - -void OSInterface::netRequestFinished(QNetworkReply*){ - -} - -void OSInterface::netSslErrors(QNetworkReply*, const QList<QSslError>&){ - -} diff --git a/src-qt5/core/libLumina/OSInterface.h b/src-qt5/core/libLumina/OSInterface.h deleted file mode 100644 index acbd5c38..00000000 --- a/src-qt5/core/libLumina/OSInterface.h +++ /dev/null @@ -1,136 +0,0 @@ -//=========================================== -// Lumina desktop source code -// Copyright (c) 2017, Ken Moore -// Available under the 3-clause BSD license -// See the LICENSE file for full details -//=========================================== -// This is the main interface for any OS-specific system calls -// To port Lumina to a different operating system, just create a file -// called "OSInterface-<Operating System>.cpp" -//=========================================== -#ifndef _LUMINA_LIBRARY_OS_INTERFACE_H -#define _LUMINA_LIBRARY_OS_INTERFACE_H - -#include <QString> -#include <QStringList> -#include <QList> -#include <QObject> -#include <QVariant> -#include <QHash> - -#include <QIODevice> -#include <QFileSystemWatcher> -#include <QNetworkAccessManager> -#include <QNetworkReply> -#include <QSslError> - -class OSInterface : public QObject{ - Q_OBJECT - -public: - enum Interface{ Battery, Volume, Devices, Network, PowerOff, Reboot, Suspend, Updates }; - -private slots: - //FileSystemWatcher slots - void watcherFileChanged(QString); - void watcherDirChanged(QString); - //IO Device slots - void iodeviceReadyRead(); - void iodeviceAboutToClose(); - //NetworkAccessManager slots - void netAccessChanged(QNetworkAccessManager::NetworkAccessibility); - void netRequestFinished(QNetworkReply*); - void netSslErrors(QNetworkReply*, const QList<QSslError>&); - -private: - //Internal persistant data storage, OS-specific usage implementation - QHash< OSInterface::Interface, QList<QVariant> > INFO; - - // ============ - // Internal possibilities for watching the system (OS-Specific usage/implementation) - // ============ - //File System Watcher - QFileSystemWatcher *watcher; - //IO Device (QLocalSocket, QTcpConnection, QFile, etc) - QIODevice *iodevice; - //Network Access Manager (check network connectivity, etc) - QNetworkAccessManager *netman; - - //Simplifications for connecting the various watcher objects to their respective slots - void connectWatcher(){ - if(watcher==0){ return; } - connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(watcherFileChanged(QString)) ); - connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(watcherDirChanged(QString)) ); - } - void connectIodevice(){ - if(iodevice==0){ return; } - connect(iodevice, SIGNAL(readyRead()), this, SLOT(iodeviceReadyRead()) ); - } - void connectNetman(){ - if(netman==0){ return; } - connect(netman, SIGNAL(networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility)), this, SLOT(netAccessChanged(QNetworkAccessManager::NetworkAccessibility)) ); - connect(netman, SIGNAL(requestFinished(QNetworkReply*)), this, SLOT(netRequestFinished(QNetworkReply*)) ); - connect(netman, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>&)), this, SLOT(netSslErrors(QNetworkReply*, const QList<QSslError>&)) ); - } - -public: - OSInterface(QObject *parent = 0) : QObject(parent){ - watcher = 0; - iodevice = 0; - netman = 0; - } - ~OSInterface(){ - if(watcher!=0){ - QStringList paths; paths << watcher->files() << watcher->directories(); - if(!paths.isEmpty()){ watcher->removePaths(paths); } - watcher->deleteLater(); - } - if(iodevice!=0){ - if(iodevice->isOpen()){ iodevice->close(); } - iodevice->deleteLater(); - } - if(netman!=0){ - netman->deleteLater(); - } - } - - //Simple functions used to determine if the current OS supports using this class, and what levels of support - QList<OSInterface::Interface> supportedNotifications(); //Which interfaces provide change notifications - QList<OSInterface::Interface> supportedStatus(); //Which interfaces are available for "status" requests - QList<OSInterface::Interface> supportedModify(); //Which interfaces are available for "modify" requests - - //Start/stop interface watchers/notifications (each only called once per session) - void start(); - void stop(); - - //Generic status update - QList<QVariant> status(OSInterface::Interface); - // ==== Interface status output lists ==== - // Battery: [ float (percent charge), bool (is Charging), double (seconds remaining) ]; - // Volume: [int (percent volume) ] - // Devices: [ QStringList[ name, mountpoint, type (optional)] ] (List length depends on number of devices) - // Network: [bool (network access available)] - // PowerOff: [bool (can power off system)] - // Reboot: [bool (can reboot system)] - // Suspend: [bool (can suspend system)] - // Updates: [bool (is updating), bool (reboot required)] - // ========== - - //Individual Interface interactions - bool modify(OSInterface::Interface, QList<QVariant> args); //returns: success/failure - // ==== Interface modification argument lists ==== - // Battery: <NO MODIFICATION> - // Volume: [int (set percent volume) ] - // Devices: <NO MODIFICATION> - // Network: <NO MODIFICATION> - // PowerOff: [bool (skip updates - optional)] - // Reboot: [bool (skip updates - optional)] - // Suspend: [] (No input arguments) - // Updates: <NO MODIFICATION> - // ========== - -signals: - void interfaceChanged(OSInterface::Interface); - -}; -#endif diff --git a/src-qt5/core/lumina-desktop-unified/LSession.cpp b/src-qt5/core/lumina-desktop-unified/LSession.cpp index e1251c01..ed4d644b 100644 --- a/src-qt5/core/lumina-desktop-unified/LSession.cpp +++ b/src-qt5/core/lumina-desktop-unified/LSession.cpp @@ -22,6 +22,7 @@ QThread* Lumina::EVThread = 0; RootWindow* Lumina::ROOTWIN = 0; XDGDesktopList* Lumina::APPLIST = 0; LShortcutEvents* Lumina::SHORTCUTS = 0; +DesktopManager* Lumina::DESKMAN = 0; LSession::LSession(int &argc, char ** argv) : LSingleApplication(argc, argv, "lumina-desktop-unified"){ //Initialize the global objects to null pointers @@ -49,10 +50,11 @@ LSession::LSession(int &argc, char ** argv) : LSingleApplication(argc, argv, "lu Lumina::NEF = new NativeEventFilter(); Lumina::NWS = new NativeWindowSystem(); Lumina::SS = new LScreenSaver(); + Lumina::DESKMAN = new DesktopManager(); //Now put the Native Window System into it's own thread to keep things snappy Lumina::EVThread = new QThread(); - //Lumina::NWS->moveToThread(Lumina::EVThread); - //Lumina::EVThread->start(); + Lumina::DESKMAN->moveToThread(Lumina::EVThread); + Lumina::EVThread->start(); Lumina::APPLIST = XDGDesktopList::instance(); Lumina::ROOTWIN = new RootWindow(); Lumina::SHORTCUTS = new LShortcutEvents(); //this can be moved to it's own thread eventually as well @@ -73,6 +75,7 @@ LSession::~LSession(){ if(DesktopSettings::instance()!=0){ DesktopSettings::instance()->deleteLater(); } if(Lumina::ROOTWIN!=0){ Lumina::ROOTWIN->deleteLater(); } if(Lumina::APPLIST!=0){ Lumina::APPLIST->deleteLater(); } + if(Lumina::DESKMAN!=0){ Lumina::DESKMAN->deleteLater(); } } void LSession::setupSession(){ @@ -104,6 +107,10 @@ void LSession::setupSession(){ splash.showScreen("user"); if(DEBUG){ qDebug() << " - Init User Files:" << timer->elapsed();} //checkUserFiles(); //adds these files to the watcher as well + Lumina::NWS->setRoot_numberOfWorkspaces(QStringList() << "one" << "two"); + Lumina::NWS->setRoot_currentWorkspace(0); + + Lumina::DESKMAN->start(); Lumina::ROOTWIN->start(); //Initialize the internal variables //DESKTOPS.clear(); @@ -124,14 +131,12 @@ void LSession::setupSession(){ //Initialize the desktops splash.showScreen("desktop"); - if(DEBUG){ qDebug() << " - Init Desktops:" << timer->elapsed(); } + /*if(DEBUG){ qDebug() << " - Init Desktops:" << timer->elapsed(); } QList<QScreen*> scrns= QApplication::screens(); for(int i=0; i<scrns.length(); i++){ qDebug() << " --- Load Wallpaper for Screen:" << scrns[i]->name(); RootDesktopObject::instance()->ChangeWallpaper(scrns[i]->name(),QUrl::fromLocalFile(LOS::LuminaShare()+"desktop-background.jpg").toString() ); - } - Lumina::NWS->setRoot_numberOfWorkspaces(QStringList() << "one" << "two"); - Lumina::NWS->setRoot_currentWorkspace(0); + }*/ if(DEBUG){ qDebug() << " - Create Desktop Context Menu"; } diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Grav.json b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Grav.json new file mode 100644 index 00000000..8d75d399 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Grav.json @@ -0,0 +1,25 @@ +{ + "name" : { + "default" : "Grav" + }, + "description" : { + "default" : "Simulates a solar system, with a single star and planets erratically orbiting that star" + }, + "author" : { + "name" : "Zackary Welch", + "email" : "zwelch@ixsystems.com", + "website" : "https://github.com/ZackaryWelch", + "company" : "iXsystems", + "company_website" : "http://ixsystems.com" + }, + "meta" : { + "license" : "3-clause BSD", + "license_url" : "https://github.com/trueos/lumina/blob/master/LICENSE", + "copyright" : "Copyright (c) 2017, Ken Moore (ken@ixsystems.com)", + "date_created" : "20171101", + "version" : "1.0" + }, + "qml" : { + "exec" : "qml_scripts/Grav.qml" + } +} diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Grav.qml b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Grav.qml index 7a3c33cd..d1e5d3c9 100644 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Grav.qml +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Grav.qml @@ -4,11 +4,13 @@ import QtGraphicalEffects 1.0 Rectangle { id : canvas anchors.fill: parent - width: 800 - height: 600 + width: Screen.width + height: Screen.height color: "black" //TODO Add orbital trails option + //TODO Fix jitteryness and start position + //TODO Make orbits more extreme //Between 5 and 15 planets, read from settings property int planets: Math.round(( Math.random() * 10 ) + 5 ) @@ -30,6 +32,7 @@ Rectangle { property double a: Math.sqrt(b*b+c*c) //Random angle of rotation property double th: Math.random() * Math.PI + property var path: [] //Calculates starting position x: Math.round(cx + a * Math.cos(th)) @@ -45,34 +48,40 @@ Rectangle { //Give each planet a random color, semi-transparent color: Qt.rgba(Math.random(), Math.random(), Math.random(), 0.5) - Timer { + /*Timer { //Each planet updates between 1ms and 51ms (smaller times=faster) interval: Math.round(Math.random() * 50 ) + 1 repeat: true running: true - property bool starting: true property int time: 0 onTriggered: { - //Move a planet 80 pixels away from the sun if the planet is too close - if(starting) { - if(x > cx && Math.abs(cx-x) < 80) { - x+=80 - }else if(x < cx && Math.abs(cx-x) < 80) { - x-=80 - } - - if(y > cy && Math.abs(cy-y) < 80) { - y+=80 - }else if(y < cy && Math.abs(cy-y) < 80) { - y-=80 - } - starting = false; - } //Parametric equation that calculates the position of the general ellipse. Completes a loop ever 314 cycles. Credit to x = cx+a*Math.cos(2*Math.PI*(time/314.0))*Math.cos(th) - b*Math.sin(2*Math.PI*(time/314.0))*Math.sin(th) y = cy+a*Math.cos(2*Math.PI*(time/314.0))*Math.sin(th) + b*Math.sin(2*Math.PI*(time/314.0))*Math.cos(th) time++; + + //Move a planet 80 pixels away from the sun if the planet is too close + if(x > cx && Math.abs(cx-x) < 80) { + x+=80 + }else if(x < cx && Math.abs(cx-x) < 80) { + x-=80 + } + + if(y > cy && Math.abs(cy-y) < 80) { + y+=80 + }else if(y < cy && Math.abs(cy-y) < 80) { + y-=80 + } + } + }*/ + + Component.onCompleted: { + pahtX[0] = x + pahtY[0] = y + for(int i = 1; i <= 200; i++) { + pathX[i] = cx+a*Math.cos(2*Math.PI*(i/200.0)*Math.cos(th) - b*Math.sin(2*Math.PI*(i/200.0)*Math.sin(th) + pathY[i] = cy+a*Math.cos(2*Math.PI*(i/200.0)*Math.sin(th) + b*Math.sin(2*Math.PI*(i/200.0)*Math.cos(th) } } } diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Video.qml b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Video.qml index e7d0626d..9948537b 100644 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Video.qml +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Video.qml @@ -4,10 +4,8 @@ import QtQuick.Window 2.2 import Qt.labs.folderlistmodel 2.1 Rectangle { - //width: Screen.width - //height: Screen.height - width: 800 - height: 600 + width: Screen.width + height: Screen.height color: "black" FolderListModel { diff --git a/src-qt5/core/lumina-desktop-unified/global-includes.h b/src-qt5/core/lumina-desktop-unified/global-includes.h index 40987ad4..fbc3c4f7 100644 --- a/src-qt5/core/lumina-desktop-unified/global-includes.h +++ b/src-qt5/core/lumina-desktop-unified/global-includes.h @@ -59,10 +59,6 @@ #include <QQmlEngine> #include <QQuickImageProvider> -// C++ Backend classes for QML interface -#include <RootDesktopObject.h> -#include <ScreenObject.h> - // libLumina includes #include <LuminaX11.h> #include <LuminaXDG.h> @@ -80,6 +76,9 @@ #include <LIconCache.h> #include <LFileInfo.h> +// C++ Backend classes for QML interface +#include <RootDesktopObject.h> +#include <ScreenObject.h> //Setup any global defines (no classes or global objects: use "global-objects.h" for that) diff --git a/src-qt5/core/lumina-desktop-unified/global-objects.h b/src-qt5/core/lumina-desktop-unified/global-objects.h index c204587f..4cea60c2 100644 --- a/src-qt5/core/lumina-desktop-unified/global-objects.h +++ b/src-qt5/core/lumina-desktop-unified/global-objects.h @@ -22,9 +22,10 @@ //#include "src-events/LXcbEventFilter.h" //#endif #include "src-events/LShortcutEvents.h" - +#include "src-desktop/DesktopManager.h" #include "src-screensaver/LScreenSaver.h" //#include "src-WM/LWindowManager.h" + #include <RootWindow.h> #include "LSession.h" @@ -43,13 +44,13 @@ namespace Lumina{ //extern EventFilter *EFILTER; //Native Event Watcher extern LShortcutEvents *SHORTCUTS; //Keyboard/mouse shortcut events - //extern DesktopSettings *SETTINGS; //All Settings files + //ScreenSaver extern LScreenSaver *SS; //Root Window extern RootWindow *ROOTWIN; - //Window Manager - //LWindowManager *WM; + //Desktop Manager + extern DesktopManager *DESKMAN; //Application List extern XDGDesktopList *APPLIST; diff --git a/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro b/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro index 21e46b22..bb987e25 100644 --- a/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro +++ b/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro @@ -24,7 +24,7 @@ include(../libLumina/ExternalProcess.pri) include(../../src-cpp/NativeWindow.pri) include(../libLumina/XDGMime.pri) -include(../../src-cpp/plugins-screensaver.pri) +include(../../src-cpp/plugins-base.pri) #include all the main individual source groups include(src-screensaver/screensaver.pri) @@ -124,7 +124,7 @@ TRANSLATIONS = i18n/lumina-desktop_af.ts \ i18n/lumina-desktop_zu.ts dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/ -dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/ +dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/ INSTALLS += target desktop defaults extrafiles diff --git a/src-qt5/core/lumina-desktop-unified/main.cpp b/src-qt5/core/lumina-desktop-unified/main.cpp index ed2b9b4c..3cf35e50 100644 --- a/src-qt5/core/lumina-desktop-unified/main.cpp +++ b/src-qt5/core/lumina-desktop-unified/main.cpp @@ -39,11 +39,11 @@ int main(int argc, char ** argv) QTime *timer=0; if(DEBUG){ timer = new QTime(); timer->start(); } if(DEBUG){ qDebug() << "Theme Init:" << timer->elapsed(); } - LuminaThemeEngine theme(&a); - QObject::connect(&theme, SIGNAL(updateIcons()), &a, SLOT(reloadIconTheme()) ); + /*LuminaThemeEngine theme(&a); + QObject::connect(&theme, SIGNAL(updateIcons()), &a, SLOT(reloadIconTheme()) );*/ if(DEBUG){ qDebug() << "Session Setup:" << timer->elapsed(); } QTimer::singleShot(0, &a, SLOT(setupSession()) ); - theme.refresh(); + //theme.refresh(); if(DEBUG){ qDebug() << "Exec Time:" << timer->elapsed(); delete timer;} int retCode = a.exec(); qDebug() << "Finished Closing Down Unified Lumina"; diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp new file mode 100644 index 00000000..d6d06be9 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp @@ -0,0 +1,139 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017-2018, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "DesktopManager.h" + +#include "global-objects.h" + +// === PUBLIC === +DesktopManager::DesktopManager(){ + +} + +DesktopManager::~DesktopManager(){ + +} + +void DesktopManager::start(){ + connect(DesktopSettings::instance(), SIGNAL(FileModified(DesktopSettings::File)), this, SLOT(settingsChanged(DesktopSettings::File)) ); + //Perform the initial load of the settings files + QTimer::singleShot(0, this, SLOT(updateDesktopSettings()) ); + QTimer::singleShot(0, this, SLOT(updatePanelSettings()) ); + QTimer::singleShot(0, this, SLOT(updatePluginSettings()) ); + QTimer::singleShot(0, this, SLOT(updateMenuSettings()) ); + QTimer::singleShot(0, this, SLOT(updateAnimationSettings()) ); +} + +void DesktopManager::stop(){ + disconnect(DesktopSettings::instance(), SIGNAL(FileModified(DesktopSettings::File)), this, SLOT(settingsChanged(DesktopSettings::File)) ); +} + +// === PRIVATE === +void DesktopManager::updateWallpaper(QString screen_id, int wkspace){ + QString current = RootDesktopObject::instance()->CurrentWallpaper(screen_id); + if(!current.isEmpty()){ current = QUrl(current).toLocalFile(); } //convert it back to the normal file syntax + //First find the list of options from the settings + //First look for a list that matches this exact screen/workspace combo + QStringList wpaperList = DesktopSettings::instance()->value(DesktopSettings::Desktop, "wallpapers/"+screen_id+"_wk_"+QString::number(wkspace), QStringList()).toStringList(); + //Next look for a list that matches this exact workspace + if(wpaperList.isEmpty()){ wpaperList= DesktopSettings::instance()->value(DesktopSettings::Desktop, "wallpapers/default_wk_"+QString::number(wkspace), QStringList()).toStringList(); } + //Next look for a list that matches this exact screen + if(wpaperList.isEmpty()){ wpaperList= DesktopSettings::instance()->value(DesktopSettings::Desktop, "wallpapers/"+screen_id, QStringList()).toStringList(); } + //Now look for a list that matches any screen/workspace + if(wpaperList.isEmpty()){ wpaperList= DesktopSettings::instance()->value(DesktopSettings::Desktop, "wallpapers/default", QStringList()).toStringList(); } + //Now use the failover wallpaper directory + if(wpaperList.isEmpty()){ wpaperList << LOS::LuminaShare()+"../wallpapers/lumina-nature"; } + //Wallpaper selection/randomization + if(wpaperList.count()==1 && wpaperList.first()==current){ return; } //nothing to do - just the same image + QString wpaper; + QStringList bgL = wpaperList; //need a copy at the moment - could change the entire list in a second (opening a dir for instance) + while(wpaper.isEmpty() || QFileInfo(wpaper).isDir()){ + QString prefix; + if(!wpaper.isEmpty()){ + //Got a directory - update the list of files and re-randomize the selection + QStringList imgs = LUtils::imageExtensions(true); + QDir tdir(wpaper); + prefix=wpaper+"/"; + bgL = tdir.entryList(imgs, QDir::Files | QDir::NoDotAndDotDot, QDir::Name); + //If directory no longer has any valid images - remove it from list and try again + if(bgL.isEmpty()){ + wpaperList.removeAll(wpaper); //invalid directory - remove it from the list for the moment + bgL = wpaperList; //reset the list back to the original list (not within a directory) + } + } + //Verify that there are files in the list - otherwise use the default + if(bgL.isEmpty()){ wpaper="default"; break; } + int index = ( qrand() % bgL.length() ); + if(index== bgL.indexOf(current)){ //if the current wallpaper was selected by the randomization again + //Go to the next in the list + if(index < 0 || index >= bgL.length()-1){ index = 0; } //if invalid or last item in the list - go to first + else{ index++; } //go to next + } + wpaper = prefix+bgL[index]; + } + //Now go ahead and set the wallpaper in the screen object + if(wpaper.isEmpty() || wpaper=="default"){ wpaper = LOS::LuminaShare()+"desktop-background.jpg"; } //failover image + qDebug() << "Updating Wallpaper:" << screen_id << wpaper; + RootDesktopObject::instance()->ChangeWallpaper(screen_id,QUrl::fromLocalFile(wpaper).toString() ); +} + +void DesktopManager::updatePanels(QString panel_id){ + +} + +void DesktopManager::updatePlugins(QString plugin_id){ + +} + +// === PUBLIC SLOTS === +void DesktopManager::workspaceChanged(int wknum){ + qDebug() << "Got Workspace Changed:" << wknum; + +} + +void DesktopManager::settingsChanged(DesktopSettings::File type){ + switch(type){ + case DesktopSettings::Desktop: + QTimer::singleShot(0, this, SLOT(updateDesktopSettings()) ); + case DesktopSettings::Panels: + QTimer::singleShot(0, this, SLOT(updatePanelSettings()) ); + case DesktopSettings::Plugins: + QTimer::singleShot(0, this, SLOT(updatePluginSettings()) ); + case DesktopSettings::ContextMenu: + QTimer::singleShot(0, this, SLOT(updateMenuSettings()) ); + case DesktopSettings::Animation: + QTimer::singleShot(0, this, SLOT(updateAnimationSettings()) ); + default: + break; + //Do nothing - not a settings change we care about here + } +} + +// === PRIVATE SLOTS === +void DesktopManager::updateDesktopSettings(){ + qDebug() << "Update Desktop Settings..."; + QList<QScreen*> scrns= QApplication::screens(); + int wkspace = Lumina::NWS->currentWorkspace(); + for(int i=0; i<scrns.length(); i++){ updateWallpaper(scrns[i]->name(), wkspace); } + +} + +void DesktopManager::updatePanelSettings(){ + +} + +void DesktopManager::updatePluginSettings(){ + +} + +void DesktopManager::updateMenuSettings(){ + +} + +void DesktopManager::updateAnimationSettings(){ + +} + diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h new file mode 100644 index 00000000..df681afa --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h @@ -0,0 +1,44 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017-2018, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +// This is the main class that updates the interface objects +// on-demand as settings files and other stuff changes +//=========================================== +#ifndef _LUMINA_DESKTOP_OBJECT_MANAGER_H +#define _LUMINA_DESKTOP_OBJECT_MANAGER_H + +#include <global-includes.h> + +class DesktopManager : public QObject { + Q_OBJECT +public: + DesktopManager(); + ~DesktopManager(); + + void start(); + void stop(); + +private: + void updateWallpaper(QString screen_id, int wkspace); + void updatePanels(QString panel_id); + void updatePlugins(QString plugin_id); + +public slots: + void workspaceChanged(int); + void settingsChanged(DesktopSettings::File); + +private slots: + void updateDesktopSettings(); + void updatePanelSettings(); + void updatePluginSettings(); + void updateMenuSettings(); + void updateAnimationSettings(); + +signals: + void PanelLocationsChanged(); //reserved screen space changed +}; + +#endif diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri b/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri index e4c4faeb..f4a6882d 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri @@ -1,8 +1,10 @@ QT *= gui widgets qml quick -SOURCES *= $${PWD}/RootWindow.cpp +SOURCES *= $${PWD}/RootWindow.cpp \ + $${PWD}/Desktopmanager.cpp -HEADERS *= $${PWD}/RootWindow.h +HEADERS *= $${PWD}/RootWindow.h \ + $${PWD}/DesktopManager.h #update the includepath so we can just #include as needed without paths INCLUDEPATH *= $${PWD} diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.cpp new file mode 100644 index 00000000..471da58f --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.cpp @@ -0,0 +1,44 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "PanelObject.h" +#include <QQmlEngine> +#include <QDebug> + +PanelObject::PanelObject(QString id, QObject *parent) : QObject(parent){ + panel_id = id; +} + +void PanelObject::RegisterType(){ + static bool done = false; + if(done){ return; } + done=true; + qmlRegisterType<PanelObject>("Lumina.Backend.PanelObject",2,0, "PanelObject"); +} + +QString PanelObject::name(){ return panel_id; } +QString PanelObject::background(){ + if(bg.isEmpty()){ return "transparent"; } + return bg; +} +int PanelObject::x(){ return geom.x(); } +int PanelObject::y(){ return geom.y(); } +int PanelObject::width(){ return geom.width(); } +int PanelObject::height(){ return geom.height(); } + +void PanelObject::setBackground(QString fileOrColor){ + if(bg!=fileOrColor){ + bg = fileOrColor; + emit backgroundChanged(); + } +} + +void PanelObject::setGeometry( QRect newgeom ){ + if(geom!=newgeom){ + geom = newgeom; + emit geomChanged(); + } +} diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.h new file mode 100644 index 00000000..a788fa07 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.h @@ -0,0 +1,49 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +// This is the base C++ object that is used to pass Panel info to the QML classes +//=========================================== +#ifndef _LUMINA_DESKTOP_PANEL_OBJECT_H +#define _LUMINA_DESKTOP_PANEL_OBJECT_H +#include <QObject> +#include <QString> +#include <QScreen> + +class PanelObject : public QObject { + Q_OBJECT + Q_PROPERTY( QString name READ name ) + Q_PROPERTY( QString background READ background NOTIFY backgroundChanged) + Q_PROPERTY( int x READ x NOTIFY geomChanged) + Q_PROPERTY( int y READ y NOTIFY geomChanged) + Q_PROPERTY( int width READ width NOTIFY geomChanged) + Q_PROPERTY( int height READ height NOTIFY geomChanged) + +private: + QString panel_id, bg; + QRect geom; + +public: + PanelObject(QString id = "", QObject *parent = 0); + + static void RegisterType(); + + Q_INVOKABLE QString name(); + Q_INVOKABLE QString background(); + Q_INVOKABLE int x(); + Q_INVOKABLE int y(); + Q_INVOKABLE int width(); + Q_INVOKABLE int height(); + +public slots: + void setBackground(QString fileOrColor); + void setGeometry(QRect newgeom); + +signals: + void backgroundChanged(); + void geomChanged(); +}; + +#endif diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp index 60cf56c3..4b01fa0d 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp @@ -21,6 +21,9 @@ RootDesktopObject::~RootDesktopObject(){ } void RootDesktopObject::RegisterType(){ + static bool done = false; + if(done){ return; } + done=true; qmlRegisterType<RootDesktopObject>("Lumina.Backend.RootDesktopObject", 2, 0, "RootDesktopObject"); //Also register any types that are needed by this class ScreenObject::RegisterType(); @@ -47,6 +50,47 @@ ScreenObject* RootDesktopObject::screen(QString id){ return 0; } +QStringList RootDesktopObject::panels(){ + //qDebug() << "Request Panels:" << panel_objects.length(); + QStringList names; + for(int i=0; i<panel_objects.length(); i++){ names << panel_objects[i]->name(); } + return names; +} + +PanelObject* RootDesktopObject::panel(QString id){ + //qDebug() << "Got Panel Request:" << id; + for(int i=0; i<panel_objects.length(); i++){ + if(panel_objects[i]->name()==id){ return panel_objects[i]; } + } + return 0; +} + +QStringList RootDesktopObject::windows(){ + //qDebug() << "Request Panels:" << panel_objects.length(); + QStringList names; + for(int i=0; i<window_objects.length(); i++){ names << QString::number(window_objects[i]->id()); } + return names; +} + +NativeWindow* RootDesktopObject::window(QString id){ + //qDebug() << "Got Panel Request:" << id; + WId chk = id.toInt(); //numerical ID's in this case + for(int i=0; i<window_objects.length(); i++){ + if(window_objects[i]->id()==chk){ return window_objects[i]; } + } + return 0; +} + +void RootDesktopObject::setPanels(QList<PanelObject*> list){ + panel_objects = list; + emit panelsChanged(); +} + +void RootDesktopObject::setWindows(QList<NativeWindow*> list){ + window_objects = list; + emit windowsChanged(); +} + void RootDesktopObject::logout(){ emit startLogout(); } @@ -85,4 +129,13 @@ void RootDesktopObject::ChangeWallpaper(QString screen, QString value){ } } +QString RootDesktopObject::CurrentWallpaper(QString screen){ + for(int i=0; i<s_objects.length(); i++){ + if(s_objects[i]->name()==screen){ return s_objects[i]->background();} + } + return ""; //unknown +} + + + // === PRIVATE === diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h index ba586701..7d5182c4 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h @@ -10,6 +10,7 @@ #define _LUMINA_DESKTOP_QML_BACKEND_ROOT_DESKTOP_OBJECT_H #include <QObject> #include <QList> +#include <global-includes.h> #include "ScreenObject.h" @@ -17,6 +18,8 @@ class RootDesktopObject : public QObject{ Q_OBJECT //Define all the QML Properties here (interface between QML and the C++ methods below) Q_PROPERTY( QStringList screens READ screens NOTIFY screensChanged) + Q_PROPERTY( QStringList panels READ panels NOTIFY panelsChanged) + Q_PROPERTY( QStringList windows READ windows NOTIFY windowsChanged); public: //main contructor/destructor @@ -29,24 +32,38 @@ public: static RootDesktopObject* instance(); //QML Read Functions - QStringList screens(); + Q_INVOKABLE QStringList screens(); Q_INVOKABLE ScreenObject* screen(QString id); + Q_INVOKABLE QStringList panels(); + Q_INVOKABLE PanelObject* panel(QString id); + Q_INVOKABLE QStringList windows(); + Q_INVOKABLE NativeWindow* window(QString id); + + void setPanels(QList<PanelObject*> list); + void setWindows(QList<NativeWindow*> list); //QML Access Functions Q_INVOKABLE void logout(); Q_INVOKABLE void lockscreen(); Q_INVOKABLE void mousePositionChanged(); + private: QList<ScreenObject*> s_objects; + QList<PanelObject*> panel_objects; + QList<NativeWindow*> window_objects; public slots: void updateScreens(); //rescan/update screen objects void ChangeWallpaper(QString screen, QString); + QString CurrentWallpaper(QString screen); private slots: signals: void screensChanged(); + void panelsChanged(); + void windowsChanged(); + void startLogout(); void mouseMoved(); void lockScreen(); diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp index 4c1d6189..82622403 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp @@ -13,7 +13,12 @@ ScreenObject::ScreenObject(QScreen *scrn, QObject *parent) : QObject(parent){ } void ScreenObject::RegisterType(){ + static bool done = false; + if(done){ return; } + done=true; qmlRegisterType<ScreenObject>("Lumina.Backend.ScreenObject",2,0, "ScreenObject"); + //Also register any types that are needed by this class + PanelObject::RegisterType(); } QString ScreenObject::name(){ return bg_screen->name(); } @@ -29,3 +34,24 @@ void ScreenObject::setBackground(QString fileOrColor){ emit backgroundChanged(); } } + +void ScreenObject::setPanels(QList<PanelObject*> list){ + panel_objects = list; + emit panelsChanged(); +} + +//QML Read Functions +QStringList ScreenObject::panels(){ + //qDebug() << "Request Panels:" << panel_objects.length(); + QStringList names; + for(int i=0; i<panel_objects.length(); i++){ names << panel_objects[i]->name(); } + return names; +} + +PanelObject* ScreenObject::panel(QString id){ + //qDebug() << "Got Panel Request:" << id; + for(int i=0; i<panel_objects.length(); i++){ + if(panel_objects[i]->name()==id){ return panel_objects[i]; } + } + return 0; +} diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.h index 8076f1ae..1afff6d2 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.h @@ -12,6 +12,8 @@ #include <QString> #include <QScreen> +#include "PanelObject.h" + class ScreenObject : public QObject { Q_OBJECT Q_PROPERTY( QString name READ name ) @@ -20,10 +22,12 @@ class ScreenObject : public QObject { Q_PROPERTY( int y READ y NOTIFY geomChanged) Q_PROPERTY( int width READ width NOTIFY geomChanged) Q_PROPERTY( int height READ height NOTIFY geomChanged) + Q_PROPERTY( QStringList panels READ panels NOTIFY panelsChanged) private: QScreen *bg_screen; QString bg; + QList<PanelObject*> panel_objects; public: ScreenObject(QScreen *scrn = 0, QObject *parent = 0); @@ -36,6 +40,10 @@ public: Q_INVOKABLE int y(); Q_INVOKABLE int width(); Q_INVOKABLE int height(); + Q_INVOKABLE QStringList panels(); + Q_INVOKABLE PanelObject* panel(QString id); + + void setPanels(QList<PanelObject*> list); public slots: void setBackground(QString fileOrColor); @@ -43,6 +51,7 @@ public slots: signals: void backgroundChanged(); void geomChanged(); + void panelsChanged(); }; #endif diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/src-cpp.pri b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/src-cpp.pri index 33b699da..899f4968 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/src-cpp.pri +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/src-cpp.pri @@ -1,8 +1,9 @@ SOURCES *= $${PWD}/RootDesktopObject.cpp \ - $${PWD}/ScreenObject.cpp + $${PWD}/ScreenObject.cpp \ + $${PWD}/PanelObject.cpp HEADERS *= $${PWD}/RootDesktopObject.h \ - $${PWD}/ScreenObject.h + $${PWD}/ScreenObject.h \ + $${PWD}/PanelObject.h INCLUDEPATH *= $${PWD} - diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/Panel.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/Panel.qml new file mode 100644 index 00000000..846b5b55 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/Panel.qml @@ -0,0 +1,26 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +import QtQuick 2.2 +import QtQuick.Window 2.2 +import QtQuick.Controls 1 + +import Lumina.Backend.PanelObject 2.0 + +AnimatedImage { + //C++ backend object + property string screen_id + property PanelObject object + + //Normal geometries/placements + asynchronous: true + clip: true + source: object.background + x: object.x + y: object.y + width: object.width + height: object.height + } diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml index e0381e23..c564ee42 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml @@ -46,11 +46,12 @@ Rectangle { //Create the context menu itself QML.ContextMenu { id: contextMenu } - //Setup the wallpapers + //Setup the screens/wallpapers Repeater{ model: RootObject.screens - QML.WallpaperImage{ + QML.Screen{ screen_id: modelData + object: RootObject.screen(modelData) z: 0+index } } diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/WallpaperImage.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/Screen.qml index 1b44963f..3b83653a 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/WallpaperImage.qml +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/Screen.qml @@ -13,7 +13,7 @@ import Lumina.Backend.ScreenObject 2.0 AnimatedImage { //C++ backend object property string screen_id - property ScreenObject object: RootObject.screen(screen_id) + property ScreenObject object //Normal geometries/placements asynchronous: true diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri index fed18e02..ad07902a 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri @@ -2,7 +2,8 @@ lupdate_only{ SOURCES *= $${PWD}/RootDesktop.qml \ $${PWD}/ContextMenu.qml \ - $${PWD}/WallpaperImage.qml + $${PWD}/Screen.qml \ + $${PWD}/Panel.qml } RESOURCES *= $${PWD}/src-qml.qrc diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc index ebdcc606..b0c66e20 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc @@ -2,6 +2,7 @@ <qresource prefix="qml"> <file>RootDesktop.qml</file> <file>ContextMenu.qml</file> - <file>WallpaperImage.qml</file> + <file>Screen.qml</file> + <file>Panel.qml</file> </qresource> </RCC> diff --git a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp index 7c098887..aa3214a2 100644 --- a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp @@ -7,6 +7,9 @@ #include "SSBaseWidget.h" +//Relative directory to search along the XDG paths for screensavers +#define REL_DIR QString("/lumina-desktop/screensavers") + #define DEBUG 0 // ======== @@ -39,10 +42,10 @@ void SSBaseWidget::startPainting(){ stopPainting(); //If a random plugin - grab one of the known plugins if(plugType=="random"){ - QList<SSPlugin> valid = SSPluginSystem::findAllPlugins(); + QList<SSPlugin> valid = PluginSystem::findAllPlugins<SSPlugin>(REL_DIR); if(!valid.isEmpty()){ cplug = valid[ qrand()%valid.length() ]; } //grab a random plugin }else if(plugType!="none"){ - cplug = SSPluginSystem::findPlugin(plugType); + cplug = PluginSystem::findPlugin<SSPlugin>(plugType, REL_DIR); } if(DEBUG){ qDebug() << " - Screen Saver:" << plugType << cplug.scriptURL() << cplug.isValid(); } if(cplug.isValid()){ diff --git a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h index 72e02702..e0a03d17 100644 --- a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h +++ b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h @@ -10,6 +10,7 @@ #define _LUMINA_DESKTOP_SCREEN_SAVER_BASE_WIDGET_H #include "global-includes.h" +#include <plugins-base.h> #include <plugins-screensaver.h> class SSBaseWidget : public QQuickView{ @@ -25,8 +26,8 @@ public slots: void stopPainting(); private: - QString plugType; - SSPlugin cplug; + QString plugType; + SSPlugin cplug; QTimer *restartTimer; private slots: diff --git a/src-qt5/core/lumina-desktop/defaults/desktop-background-TrueOS.jpg b/src-qt5/core/lumina-desktop/defaults/desktop-background-TrueOS.jpg Binary files differindex de11074e..3fd8cc49 100644 --- a/src-qt5/core/lumina-desktop/defaults/desktop-background-TrueOS.jpg +++ b/src-qt5/core/lumina-desktop/defaults/desktop-background-TrueOS.jpg diff --git a/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf b/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf index e9520a3c..543f9eaa 100644 --- a/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf +++ b/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf @@ -53,6 +53,7 @@ mime_default_application/x-tar_ifexists=lumina-archiver.desktop #THEME SETTINGS theme_themefile=DarkGlass #Name of the theme to use (disable for Lumina-Default) +theme_styles=scrollbar-simple, tooltip-simple, sliders-simple, traynotification-simple theme_colorfile=darker #Name of the color spec file to use for theming theme_iconset=material-design-dark #Name of the icon theme to use theme_font=Noto Sans #Name of the font family to use @@ -60,14 +61,14 @@ theme_fontsize=10pt #Default size of the fonts to use on the desktop (can also u #DESKTOP SETTINGS (used for the primary screen in multi-screen setups) desktop_visiblepanels=1 #[0 - 12] The number of panels visible by default -desktop_backgroundfiles=/usr/local/share/wallpapers/TrueOS/trueos-1-4k.png #list of absolute file paths for image files (disable for Lumina default) +desktop_backgroundfiles=/usr/local/share/lumina-desktop/desktop-background.jpg #list of absolute file paths for image files (disable for Lumina default) desktop_backgroundrotateminutes=5 #[positive integer] number of minutes between background rotations (if multiple files) #desktop_plugins= #list of plugins to be shown on the desktop by default desktop_generate_icons=true #[true/false] Auto-generate launchers for ~/Desktop items #PANEL SETTINGS (preface with panel1.<setting> or panel2.<setting>, depending on the number of panels you have visible by default) panel1_location=bottom #[top/bottom/left/right] Screen edge the panel should be on -panel1_pixelsize=3.5%H #number of pixels wide/high the panel should be (or <number>%[W/H] for a percentage of the screen width/height) +panel1_pixelsize=5%H #number of pixels wide/high the panel should be (or <number>%[W/H] for a percentage of the screen width/height) panel1_autohide=false #[true/false] Have the panel become visible on mouse-over panel1_plugins=systemstart, taskmanager-nogroups, spacer, systemtray, clock, battery #list of plugins for the panel panel1_pinlocation=center #[left/center/right] Note:[left/right] corresponds to [top/bottom] for vertical panels diff --git a/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf b/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf index e4229038..0e6101c1 100644 --- a/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf +++ b/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf @@ -50,7 +50,8 @@ mime_default_unknown/*=lumina-textedit.desktop mime_default_application/x-shellscript=lumina-textedit.desktop #THEME SETTINGS -theme_themefile=DarkGlass #Name of the theme to use (disable for Lumina-Default) +theme_themefile=DarkGlass #Name of the theme to use +theme_styles=scrollbar-simple, tooltip-simple, sliders-simple, traynotification-simple theme_colorfile=darker #Name of the color spec file to use for theming theme_iconset=material-design-dark #Name of the icon theme to use theme_font=Arial #Name of the font family to use diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSFeedPlugin.cpp b/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSFeedPlugin.cpp index c330d6c0..e8e5adb4 100644 --- a/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSFeedPlugin.cpp +++ b/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSFeedPlugin.cpp @@ -119,11 +119,13 @@ void RSSFeedPlugin::updateFeed(QString ID){ if(!data.items[i].author_email.isEmpty()){ html.append("<a href=\"mailto:"+data.items[i].author_email+"\" style=\"color: "+color+";\">"+data.items[i].author+"</a>"); } else{ html.append(data.items[i].author); } } - html.append(")</i><br>"); + html.append(")</i>"); + if(data.rss) + html.append("<br>"); } html.append(data.items[i].description); //html.append("</li>\n"); - if(i+1 < data.items.length()){ html.append("<br>"); } + if(i+1 < data.items.length() && data.rss){ html.append("<br>"); } } //html.append("</ul>\n"); // - load that html into the viewer diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSObjects.cpp b/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSObjects.cpp index cd29d5f0..5f62f99f 100644 --- a/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSObjects.cpp +++ b/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSObjects.cpp @@ -10,6 +10,8 @@ #include "LSession.h" +#define DEBUG 0 + //============ // PUBLIC //============ @@ -116,18 +118,51 @@ RSSchannel RSSReader::readRSS(QByteArray bytes){ RSSchannel rssinfo; //qDebug() << "Can Read XML Stream:" << !xml.hasError(); if(xml.readNextStartElement()){ - //qDebug() << " - RSS Element:" << xml.name(); - if(xml.name() == "rss" && (xml.attributes().value("version") =="2.0" || xml.attributes().value("version") =="0.91") ){ + if(DEBUG) qDebug() << " - RSS Element:" << xml.name(); + if(xml.name() == "rss" && (xml.attributes().value("version") =="2.0" || xml.attributes().value("version") =="0.91")) { + rssinfo.rss = true; while(xml.readNextStartElement()){ //qDebug() << " - RSS Element:" << xml.name(); if(xml.name()=="channel"){ rssinfo = readRSSChannel(&xml); } else{ xml.skipCurrentElement(); } } + }else if(xml.name() == "feed") { + rssinfo.timetolive = -1; + rssinfo.rss = false; + while(xml.readNextStartElement()){ + if(DEBUG) qDebug() << " - ATOM Element (channel):" << xml.name(); + if(xml.name()=="entry") { + rssinfo.items << readRSSItemAtom(&xml); + }else if(xml.name()=="title"){ + rssinfo.title = xml.readElementText(); + if(DEBUG) qDebug() << "title" << rssinfo.link; + }else if(xml.name()=="link"){ + QXmlStreamAttributes att = xml.attributes(); + for(int i = 0; i < att.size(); i++) { + if(att[i].name() == "href") { + rssinfo.link = att[i].value().toString(); + } + } + xml.readElementText(); + if(DEBUG) qDebug() << "link" << rssinfo.link; + }else if(xml.name()=="subtitle"){ + rssinfo.description = xml.readElementText(); + }else if(xml.name()=="updated"){ + rssinfo.lastBuildDate = ATOMDateTime(xml.readElementText()); + }else if(xml.name()=="icon"){ + rssinfo.icon_url = xml.readElementText(); + if(DEBUG) qDebug() << "icon" << rssinfo.icon_url; + requestRSS(rssinfo.icon_url); + }else{ + xml.skipCurrentElement(); + } + } } } - if(xml.hasError()){ qDebug() << " - XML Read Error:" << xml.errorString() << "\n" << bytes; } + //if(xml.hasError()){ qDebug() << " - XML Read Error:" << xml.errorString() << "\n" << bytes; } return rssinfo; } + RSSchannel RSSReader::readRSSChannel(QXmlStreamReader *rss){ RSSchannel info; info.timetolive = -1; @@ -151,6 +186,40 @@ RSSchannel RSSReader::readRSSChannel(QXmlStreamReader *rss){ return info; } +RSSitem RSSReader::readRSSItemAtom(QXmlStreamReader *rss){ + RSSitem item; + while(rss->readNextStartElement()){ + if(rss->name()=="title"){ + item.title = rss->readElementText(); + if(DEBUG) qDebug() << rss->name() << item.title; + }else if(rss->name()=="link"){ + QXmlStreamAttributes att = rss->attributes(); + for(int i = 0; i < att.size(); i++) { + if(att[i].name() == "href") { + item.link = att[i].value().toString(); + } + } + rss->readElementText(); + if(DEBUG) qDebug() << rss->name() << item.link; + }else if(rss->name()=="summary"){ + item.description = rss->readElementText(); + if(DEBUG) qDebug() << rss->name() << item.description; + } else if(rss->name()=="comments"){ + item.comments_url = rss->readElementText(); + if(DEBUG) qDebug() << rss->name() << item.comments_url; + } else if(rss->name()=="author"){ + rss->readNextStartElement(); + item.author = rss->readElementText(); + if(DEBUG) qDebug() << "author" << item.author; + rss->skipCurrentElement(); + }else if(rss->name()=="updated"){ + item.pubdate = ATOMDateTime(rss->readElementText()); + if(DEBUG) qDebug() << rss->name() << item.pubdate; + } else{ rss->skipCurrentElement(); } + } + return item; +} + RSSitem RSSReader::readRSSItem(QXmlStreamReader *rss){ RSSitem item; while(rss->readNextStartElement()){ @@ -192,17 +261,21 @@ QDateTime RSSReader::RSSDateTime(QString datetime){ return QDateTime::fromString(datetime, Qt::RFC2822Date); } +QDateTime RSSReader::ATOMDateTime(QString datetime){ + return QDateTime::fromString(datetime, Qt::ISODate); +} + //================= // PRIVATE SLOTS //================= void RSSReader::replyFinished(QNetworkReply *reply){ QString url = reply->request().url().toString(); - //qDebug() << "Got Reply:" << url; + qDebug() << "Got Reply:" << url; QString key = keyForUrl(url); //current hash key for this URL QByteArray data = reply->readAll(); outstandingURLS.removeAll(url); if(data.isEmpty()){ - //qDebug() << "No data returned:" << url; + qDebug() << "No data returned:" << url; //see if the URL can be adjusted for known issues bool handled = false; QUrl redirecturl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); @@ -229,13 +302,13 @@ void RSSReader::replyFinished(QNetworkReply *reply){ //Could also be an icon fetch response QStringList keys = hash.keys(); for(int i=0; i<keys.length(); i++){ - //qDebug() << " - Check for icon URL:" << hash[keys[i]].icon_url; + qDebug() << " - Check for icon URL:" << hash[keys[i]].icon_url; if(hash[keys[i]].icon_url.toLower() == url.toLower()){ //needs to be case-insensitive //Icon fetch response RSSchannel info = hash[keys[i]]; QImage img = QImage::fromData(data); info.icon = QIcon( QPixmap::fromImage(img) ); - //qDebug() << "Got Icon response:" << url << info.icon; + qDebug() << "Got Icon response:" << url << info.icon; hash.insert(keys[i], info); //insert back into the hash emit rssChanged( hash[keys[i]].originalURL ); break; diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSObjects.h b/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSObjects.h index 3069bf8d..9d65ee57 100644 --- a/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSObjects.h +++ b/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSObjects.h @@ -51,6 +51,7 @@ struct RSSchannel{ //Internal data for bookkeeping QDateTime lastsync, nextsync; QString originalURL; //in case it was redirected to some "fixed" url later + bool rss; }; class RSSReader : public QObject{ @@ -88,9 +89,12 @@ private: //RSS parsing functions RSSchannel readRSS(QByteArray bytes); RSSchannel readRSSChannel(QXmlStreamReader *rss); + RSSchannel readRSSChannelAtom(QXmlStreamReader *rss); RSSitem readRSSItem(QXmlStreamReader *rss); - void readRSSImage(RSSchannel *item, QXmlStreamReader *rss); + RSSitem readRSSItemAtom(QXmlStreamReader *rss); + void readRSSImage(RSSchannel *item, QXmlStreamReader *rss); QDateTime RSSDateTime(QString datetime); + QDateTime ATOMDateTime(QString datetime); private slots: void replyFinished(QNetworkReply *reply); diff --git a/src-qt5/core/lumina-desktop/lumina-desktop.pro b/src-qt5/core/lumina-desktop/lumina-desktop.pro index 9c8272c8..e36d11a2 100644 --- a/src-qt5/core/lumina-desktop/lumina-desktop.pro +++ b/src-qt5/core/lumina-desktop/lumina-desktop.pro @@ -170,10 +170,10 @@ TRANSLATIONS = i18n/lumina-desktop_af.ts \ i18n/lumina-desktop_zu.ts dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/ -dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/ +dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/ manpage.path=$${L_MANDIR}/man1/ -manpage.extra="$${MAN_ZIP} lumina-desktop.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-desktop.1.gz" +manpage.extra="$${MAN_ZIP} $$PWD/lumina-desktop.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-desktop.1.gz" INSTALLS += target desktop icons defaults conf fluxconf manpage diff --git a/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp b/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp index 7a6b0e7c..69ea5faa 100644 --- a/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp +++ b/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp @@ -77,6 +77,7 @@ void LBattery::updateBattery(bool force){ label->setPixmap( LXDG::findIcon("battery-unknown", "battery-missing").pixmap(label->size()) ); break; } + } if(icon<iconOld && icon==0){ //Play some audio warning chime when bool playaudio = sessionsettings->value("PlayBatteryLowAudio",true).toBool(); @@ -97,7 +98,6 @@ void LBattery::updateBattery(bool force){ else{ tt = QString( tr("%1 % (%2 Remaining)") ).arg(QString::number(charge), getRemainingTime() ); } label->setToolTip(tt); } -} QString LBattery::getRemainingTime(){ int secs = LOS::batterySecondsLeft(); diff --git a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/ItemWidget.cpp b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/ItemWidget.cpp index f4382ffc..545000f4 100644 --- a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/ItemWidget.cpp +++ b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/ItemWidget.cpp @@ -70,12 +70,12 @@ ItemWidget::ItemWidget(QWidget *parent, QString itemPath, QString type, bool gob iconPath = itemPath; //icon->setPixmap( QIcon(itemPath).pixmap(64,64) ); }else{ - if( LUtils::isValidBinary(itemPath) ){ + if( LUtils::isValidBinary(itemPath) ){ if(ICONS->exists(type)){ iconPath = type; } else{ iconPath = "application-x-executable"; } }else{ iconPath = LXDG::findAppMimeForFile(itemPath.section("/",-1)).replace("/","-"); } } - name->setText( itemPath.section("/",-1) ); //this->fontMetrics().elidedText(itemPath.section("/",-1), Qt::ElideRight, TEXTCUTOFF) ); + name->setText( itemPath.section("/",-1) ); //this->fontMetrics().elidedText(itemPath.section("/",-1), Qt::ElideRight, TEXTCUTOFF) ); text = itemPath.section("/",-1) ; } ICONS->loadIcon(icon, iconPath); @@ -133,11 +133,11 @@ ItemWidget::~ItemWidget(){ //actButton->deleteLater(); contextMenu->clear(); //contextMenu->deleteLater(); - if(actButton->menu()!=0){ + if(actButton->menu()!=0){ for(int i=0; i<actButton->menu()->actions().length(); i++){ actButton->menu()->actions().at(i)->deleteLater(); } - actButton->menu()->deleteLater(); + actButton->menu()->deleteLater(); } //actButton->deleteLater(); //icon->deleteLater(); @@ -156,7 +156,7 @@ void ItemWidget::createWidget(){ menuopen = false; menureset = new QTimer(this); menureset->setSingleShot(true); - menureset->setInterval(1000); //1 second + menureset->setInterval(1000); //1 second this->setContentsMargins(0,0,0,0); contextMenu = new QMenu(this); connect(contextMenu, SIGNAL(aboutToShow()), this, SLOT(actionMenuOpen()) ); @@ -220,7 +220,7 @@ void ItemWidget::setupActions(XDGDesktop *app){ else{ ICONS->loadIcon(act, app->icon); } act->setToolTip(app->actions[i].ID); act->setWhatsThis(app->actions[i].ID); - actButton->menu()->addAction(act); + actButton->menu()->addAction(act); } connect(actButton->menu(), SIGNAL(triggered(QAction*)), this, SLOT(actionClicked(QAction*)) ); connect(actButton->menu(), SIGNAL(aboutToShow()), this, SLOT(actionMenuOpen()) ); @@ -230,9 +230,11 @@ void ItemWidget::setupActions(XDGDesktop *app){ void ItemWidget::updateItems(){ //update the text/icon to match sizes - int H = (2.5*name->fontMetrics().height() ) -4; //make sure the height is large enough for two lines + int H = (2.2*name->fontMetrics().height() ) -4; //make sure the height is large enough for two lines icon->setFixedSize(QSize(H, H)); + icon->setAlignment(Qt::AlignCenter); actButton->setFixedSize( QSize( H/2, H) ); + H = (1.8*name->fontMetrics().height() ) -4; QStringList newname = text.split("<br>"); for(int i=0; i<newname.length(); i++){ newname[i] = name->fontMetrics().elidedText(newname[i], Qt::ElideRight, name->width()); } name->setText( newname.join("<br>") ); @@ -271,9 +273,9 @@ void ItemWidget::RemoveFavorite(){ void ItemWidget::AddFavorite(){ if( LDesktopUtils::addFavorite(icon->whatsThis()) ){ linkPath = icon->whatsThis(); - emit NewShortcut(); + emit NewShortcut(); } - + } void ItemWidget::RemoveQL(){ qDebug() << "Remove QuickLaunch Button:" << icon->whatsThis(); @@ -282,7 +284,7 @@ void ItemWidget::RemoveQL(){ void ItemWidget::AddQL(){ qDebug() << "Add QuickLaunch Button:" << icon->whatsThis(); - emit toggleQuickLaunch(icon->whatsThis(), true); + emit toggleQuickLaunch(icon->whatsThis(), true); } diff --git a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp index 562122ae..d8014f4c 100644 --- a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp +++ b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp @@ -25,9 +25,11 @@ LStartButtonPlugin::LStartButtonPlugin(QWidget *parent, QString id, bool horizon startmenu = new StartMenu(this); connect(startmenu, SIGNAL(CloseMenu()), this, SLOT(closeMenu()) ); connect(startmenu, SIGNAL(UpdateQuickLaunch(QStringList)), this, SLOT(updateQuickLaunch(QStringList))); - //QRect screenSize = QApplication::desktop()->availableGeometry(this); - QSize saved = LSession::handle()->DesktopPluginSettings()->value("panelPlugs/"+this->type()+"/MenuSize", QSize(0, 0)).toSize(); - if(!saved.isNull()){ startmenu->setFixedSize(saved); } //re-load the previously saved value + + QRect screenSize = QApplication::desktop()->availableGeometry(this); + QSize saved = LSession::handle()->DesktopPluginSettings()->value("panelPlugs/"+this->type()+"/MenuSize",QSize(this->fontMetrics().width("x")*30 ,screenSize.height()/1.8)).toSize(); + //qDebug() << "Got Start Menu Saved Size:" << saved; + if(!saved.isNull() && saved.isValid()){ startmenu->setFixedSize(saved); } //re-load the previously saved value menu->setContents(startmenu); button->setMenu(menu); @@ -122,6 +124,7 @@ void LStartButtonPlugin::openMenu(){ menu->setContents(startmenu); if(old!=0){ old->deleteLater(); }*/ //-------- + //qDebug() << "Menu Size:" << startmenu->size(); startmenu->UpdateMenu(); button->showMenu(); } diff --git a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp index 272bf0fa..ee3e0f80 100644 --- a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp +++ b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp @@ -597,7 +597,7 @@ void StartMenu::on_tool_restart_clicked(){ LSession::handle()->StartReboot(true); } -void StartMenu::on_tool_restart_update_clicked(){ +void StartMenu::on_tool_restart_updates_clicked(){ emit CloseMenu(); QCoreApplication::processEvents(); //bool skipupdates = false; diff --git a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h index 41bc3ec4..0a90311d 100644 --- a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h +++ b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h @@ -73,7 +73,7 @@ private slots: void on_tool_lock_clicked(); void on_tool_logout_clicked(); void on_tool_restart_clicked(); - void on_tool_restart_update_clicked(); + void on_tool_restart_updates_clicked(); void on_tool_shutdown_clicked(); void on_tool_suspend_clicked(); diff --git a/src-qt5/core/lumina-info/lumina-info.pro b/src-qt5/core/lumina-info/lumina-info.pro index 0c8693a0..dc07c08e 100644 --- a/src-qt5/core/lumina-info/lumina-info.pro +++ b/src-qt5/core/lumina-info/lumina-info.pro @@ -92,13 +92,13 @@ TRANSLATIONS = i18n/lumina-info_af.ts \ i18n/lumina-info_zu.ts dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/ -dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/ +dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/ desktop.files=lumina-info.desktop lumina-support.desktop desktop.path=$${L_SHAREDIR}/applications/ manpage.path=$${L_MANDIR}/man1/ -manpage.extra="$${MAN_ZIP} lumina-info.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-info.1.gz" +manpage.extra="$${MAN_ZIP} $$PWD/lumina-info.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-info.1.gz" INSTALLS += target desktop manpage diff --git a/src-qt5/core/lumina-open/lumina-open.pro b/src-qt5/core/lumina-open/lumina-open.pro index b31c7a0e..3bc7e9bf 100644 --- a/src-qt5/core/lumina-open/lumina-open.pro +++ b/src-qt5/core/lumina-open/lumina-open.pro @@ -87,10 +87,10 @@ TRANSLATIONS = i18n/lumina-open_af.ts \ i18n/lumina-open_zu.ts dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/ -dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/ +dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/ manpage.path=$${L_MANDIR}/man1/ -manpage.extra="$${MAN_ZIP} lumina-open.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-open.1.gz" +manpage.extra="$${MAN_ZIP} $$PWD/lumina-open.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-open.1.gz" INSTALLS += target manpage diff --git a/src-qt5/core/lumina-session/lumina-session.pro b/src-qt5/core/lumina-session/lumina-session.pro index 797547db..9d8e8f87 100644 --- a/src-qt5/core/lumina-session/lumina-session.pro +++ b/src-qt5/core/lumina-session/lumina-session.pro @@ -16,6 +16,6 @@ SOURCES += main.cpp \ HEADERS += session.h manpage.path=$${L_MANDIR}/man8/ -manpage.extra="$${MAN_ZIP} start-lumina-desktop.8 > $(INSTALL_ROOT)$${L_MANDIR}/man8/start-lumina-desktop.8.gz" +manpage.extra="$${MAN_ZIP} $$PWD/start-lumina-desktop.8 > $(INSTALL_ROOT)$${L_MANDIR}/man8/start-lumina-desktop.8.gz" INSTALLS += target manpage diff --git a/src-qt5/core/lumina-theme-engine/lumina-theme-engine.pro b/src-qt5/core/lumina-theme-engine/lumina-theme-engine.pro index e1023752..1e8b2ca4 100644 --- a/src-qt5/core/lumina-theme-engine/lumina-theme-engine.pro +++ b/src-qt5/core/lumina-theme-engine/lumina-theme-engine.pro @@ -3,7 +3,8 @@ include(../../OS-detect.pri) TEMPLATE = subdirs SUBDIRS += src/lthemeengine-qtplugin \ src/lthemeengine-style \ - src/lthemeengine + src/lthemeengine \ + src/lthemeengine-sstest colors.files = colors/*.conf colors.path = $${L_SHAREDIR}/lthemeengine/colors diff --git a/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss b/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss index e8311e92..a9b165a6 100644 --- a/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss +++ b/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss @@ -1,26 +1,26 @@ /* SLIDERS */ QSlider::groove:horizontal { -border: 1px solid transparent; +border: 1px solid palette(mid); background: palette(alternate-window); height: 10px; border-radius: 3px; } QSlider::groove:vertical { -border: 1px solid transparent; +border: 1px solid palette(mid); background: palette(alternate-window); width: 10px; border-radius: 3px; } QSlider::sub-page:horizontal { background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, - stop: 0 palette(highlight), stop: 1 palette(window)); + stop: 0 transparent, stop: 1 palette(highlight) ); border: 1px solid transparent; height: 10px; border-radius: 3px; } -QSlider::sub-page:vertical { +QSlider::add-page:vertical { background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, - stop: 0 palette(highlight), stop: 1 palette(window)); + stop: 0 transparent, stop: 1 palette(highlight) ); border: 1px solid transparent; width: 10px; border-radius: 3px; @@ -31,7 +31,7 @@ border: 1px solid transparent; height: 10px; border-radius: 3px; } -QSlider::add-page:vertical{ +QSlider::sub-page:vertical{ background: palette(alternate-window); border: 1px solid transparent; width: 10px; @@ -40,13 +40,13 @@ border-radius: 3px; QSlider::handle:horizontal{ background: palette(mid); border: 1px solid palette(mid); -width: 1em; +width: 1ex; border-radius: 1px; } QSlider::handle:vertical{ background: palette(mid); border: 1px solid palette(mid); -height: 1em; +height: 1ex; border-radius: 1px; } QSlider::handle:horizontal:hover, QSlider::handle:vertical:hover{ diff --git a/src-qt5/core/lumina-theme-engine/qss/traynotification-simple.qss b/src-qt5/core/lumina-theme-engine/qss/traynotification-simple.qss new file mode 100644 index 00000000..43aff087 --- /dev/null +++ b/src-qt5/core/lumina-theme-engine/qss/traynotification-simple.qss @@ -0,0 +1,4 @@ +QBalloonTip{ +background-color: palette(base); +color: palette(text); +} diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine-qtplugin/lthemeengineplatformtheme.cpp b/src-qt5/core/lumina-theme-engine/src/lthemeengine-qtplugin/lthemeengineplatformtheme.cpp index 670e1c9c..e581b016 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine-qtplugin/lthemeengineplatformtheme.cpp +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine-qtplugin/lthemeengineplatformtheme.cpp @@ -43,7 +43,7 @@ lthemeenginePlatformTheme::lthemeenginePlatformTheme(){ #endif QGuiApplication::setFont(m_generalFont); } - qCDebug(llthemeengine) << "using lthemeengine plugin"; + //qCDebug(llthemeengine) << "using lthemeengine plugin"; #ifdef QT_WIDGETS_LIB if(!QStyleFactory::keys().contains("lthemeengine-style")) qCCritical(llthemeengine) << "unable to find lthemeengine proxy style"; @@ -60,7 +60,7 @@ QPlatformMenuBar *lthemeenginePlatformTheme::createPlatformMenuBar() const{ if(m_checkDBusGlobalMenu){ QDBusConnection conn = QDBusConnection::sessionBus(); m_dbusGlobalMenuAvailable = conn.interface()->isServiceRegistered("com.canonical.AppMenu.Registrar"); - qCDebug(llthemeengine) << "D-Bus global menu:" << (m_dbusGlobalMenuAvailable ? "yes" : "no"); + //qCDebug(llthemeengine) << "D-Bus global menu:" << (m_dbusGlobalMenuAvailable ? "yes" : "no"); } return (m_dbusGlobalMenuAvailable ? new QDBusMenuBar() : nullptr); } diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine-sstest/lthemeengine-sstest.pro b/src-qt5/core/lumina-theme-engine/src/lthemeengine-sstest/lthemeengine-sstest.pro new file mode 100644 index 00000000..fadc6fcb --- /dev/null +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine-sstest/lthemeengine-sstest.pro @@ -0,0 +1,11 @@ +include(../../lthemeengine.pri) +TEMPLATE = app +QT *= widgets + +SOURCES += \ + main.cpp + +TARGET = lthemeengine-sstest +target.path = $${L_BINDIR} + +INSTALLS += target diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine-sstest/main.cpp b/src-qt5/core/lumina-theme-engine/src/lthemeengine-sstest/main.cpp new file mode 100644 index 00000000..bdab0a30 --- /dev/null +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine-sstest/main.cpp @@ -0,0 +1,18 @@ +#include <QApplication> +//#include <QDebug> +#include <QWidget> + +#include <LUtils.h> + +int main(int argc, char **argv){ + if(argc<2){ return 1; } //error + unsetenv("QT_QPA_PLATFORMTHEME"); //Make sure we are not testing anything related to the current theme engine + QString stylesheet = LUtils::readFile(argv[1]).join("\n"); + //qDebug() << "Found Stylesheet:" << stylesheet; + QApplication app(argc, argv); + app.setStyleSheet(stylesheet); + //qDebug() << " Using Stylesheet:" << app.styleSheet(); + QWidget tmp(0,Qt::SplashScreen | Qt::BypassWindowManagerHint); + tmp.show(); //needed to actually run the parser on the stylesheet (unused/unchecked otherwise) + return 0; +} diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.cpp b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.cpp index ac891a80..56289931 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.cpp +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.cpp @@ -4,6 +4,12 @@ #include "qsseditordialog.h" #include "ui_qsseditordialog.h" +#include <QTemporaryFile> +#include <QTextStream> + +#include <LuminaXDG.h> +#include <LUtils.h> + QSSEditorDialog::QSSEditorDialog(const QString &filePath, QWidget *parent) : QDialog(parent), m_ui(new Ui::QSSEditorDialog){ m_ui->setupUi(this); m_filePath = filePath; @@ -37,6 +43,11 @@ QSSEditorDialog::QSSEditorDialog(const QString &filePath, QWidget *parent) : QDi for(int i=0; i<colors.length(); i++){ colorMenu->addAction( colors[i].section("::::",0,0) )->setWhatsThis(colors[i].section("::::",1,1) ); } m_ui->tool_color->setMenu(colorMenu); connect(colorMenu, SIGNAL(triggered(QAction*)), this, SLOT(colorPicked(QAction*)) ); + validateTimer = new QTimer(this); + validateTimer->setInterval(500); //1/2 second after finish typing + validateTimer->setSingleShot(true); + connect(validateTimer, SIGNAL(timeout()), this, SLOT(validateStyleSheet()) ); + connect(m_ui->textEdit, SIGNAL(textChanged()), validateTimer, SLOT(start()) ); } QSSEditorDialog::~QSSEditorDialog(){ @@ -69,3 +80,31 @@ void QSSEditorDialog::colorPicked(QAction* act){ if(id.isEmpty()){ return; } m_ui->textEdit->insertPlainText( QString("palette(%1)").arg(id) ); } + +bool QSSEditorDialog::isStyleSheetValid(const QString &styleSheet){ + QTemporaryFile tempfile; + if(tempfile.open()){ + QTextStream out(&tempfile); + out << styleSheet; + out.flush(); + tempfile.close(); + } + QStringList log = LUtils::getCmdOutput("lthemeengine-sstest", QStringList() << tempfile.fileName()); + qDebug() << "Got Validation Log:" << log; + return log.join("").simplified().isEmpty(); +} + +void QSSEditorDialog::validateStyleSheet(){ + qDebug() << "Validating StyleSheet:"; + bool ok = isStyleSheetValid(m_ui->textEdit->toPlainText()); + + //Now update the button/label as needed + int sz = this->fontMetrics().height(); + if(ok){ + m_ui->label_status_icon->setPixmap(LXDG::findIcon("dialog-ok","").pixmap(sz,sz) ); + m_ui->label_status_icon->setToolTip(tr("Valid StyleSheet")); + }else{ + m_ui->label_status_icon->setPixmap(LXDG::findIcon("dialog-cancel","").pixmap(sz,sz) ); + m_ui->label_status_icon->setToolTip(tr("Invalid StyleSheet")); + } +} diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.h b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.h index 114611fe..f51434e9 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.h +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.h @@ -5,6 +5,7 @@ #include <QString> #include <QMenu> #include <QAction> +#include <QTimer> namespace Ui { class QSSEditorDialog; @@ -23,6 +24,8 @@ public: private slots: void on_buttonBox_clicked(QAbstractButton *button); void colorPicked(QAction*); + bool isStyleSheetValid(const QString&); + void validateStyleSheet(); private: void save(); @@ -30,6 +33,7 @@ private: Ui::QSSEditorDialog *m_ui; QString m_filePath; QMenu *colorMenu; + QTimer *validateTimer; }; diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.ui b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.ui index f75a21c6..68a14fb1 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.ui +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>643</width> - <height>499</height> + <width>808</width> + <height>512</height> </rect> </property> <property name="windowTitle"> @@ -53,6 +53,38 @@ </widget> </item> <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_status_icon"> + <property name="minimumSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="text"> + <string notr="true"/> + </property> + <property name="scaledContents"> + <bool>false</bool> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> <widget class="QDialogButtonBox" name="buttonBox"> <property name="orientation"> <enum>Qt::Horizontal</enum> |