aboutsummaryrefslogtreecommitdiff
path: root/src-qt5/core/libLumina
diff options
context:
space:
mode:
Diffstat (limited to 'src-qt5/core/libLumina')
-rw-r--r--src-qt5/core/libLumina/LDesktopUtils.cpp (renamed from src-qt5/core/libLumina/LuminaUtils.cpp)665
-rw-r--r--src-qt5/core/libLumina/LDesktopUtils.h49
-rw-r--r--src-qt5/core/libLumina/LDesktopUtils.pri7
-rw-r--r--src-qt5/core/libLumina/LInputDevice.cpp275
-rw-r--r--src-qt5/core/libLumina/LInputDevice.h67
-rw-r--r--src-qt5/core/libLumina/LInputDevice.pri13
-rw-r--r--src-qt5/core/libLumina/LUtils.cpp436
-rw-r--r--src-qt5/core/libLumina/LUtils.h (renamed from src-qt5/core/libLumina/LuminaUtils.h)75
-rw-r--r--src-qt5/core/libLumina/LUtils.pri34
-rw-r--r--src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp83
-rw-r--r--src-qt5/core/libLumina/LuminaOS.h4
-rw-r--r--src-qt5/core/libLumina/LuminaRandR.cpp1
-rw-r--r--src-qt5/core/libLumina/LuminaRandR.h35
-rw-r--r--src-qt5/core/libLumina/LuminaSingleApplication.h2
-rw-r--r--src-qt5/core/libLumina/LuminaSingleApplication.pri12
-rw-r--r--src-qt5/core/libLumina/LuminaThemes.cpp6
-rw-r--r--src-qt5/core/libLumina/LuminaThemes.pri10
-rw-r--r--src-qt5/core/libLumina/LuminaX11.cpp46
-rw-r--r--src-qt5/core/libLumina/LuminaX11.h4
-rw-r--r--src-qt5/core/libLumina/LuminaX11.pri13
-rw-r--r--src-qt5/core/libLumina/LuminaXDG.cpp896
-rw-r--r--src-qt5/core/libLumina/LuminaXDG.h60
-rw-r--r--src-qt5/core/libLumina/LuminaXDG.pri10
-rw-r--r--src-qt5/core/libLumina/ResizeMenu.cpp106
-rw-r--r--src-qt5/core/libLumina/ResizeMenu.h51
-rw-r--r--src-qt5/core/libLumina/ResizeMenu.pri6
-rw-r--r--src-qt5/core/libLumina/colors/Black.qss.colors13
-rw-r--r--src-qt5/core/libLumina/colors/Blue-Light.qss.colors13
-rw-r--r--src-qt5/core/libLumina/colors/Grey-Dark.qss.colors13
-rw-r--r--src-qt5/core/libLumina/colors/Lumina-Glass.qss.colors13
-rw-r--r--src-qt5/core/libLumina/colors/Lumina-Gold.qss.colors13
-rw-r--r--src-qt5/core/libLumina/colors/Lumina-Green.qss.colors13
-rw-r--r--src-qt5/core/libLumina/colors/Lumina-Purple.qss.colors13
-rw-r--r--src-qt5/core/libLumina/colors/Lumina-Red.qss.colors13
-rw-r--r--src-qt5/core/libLumina/colors/PCBSD10-Default.qss.colors13
-rw-r--r--src-qt5/core/libLumina/colors/Solarized-Dark.qss.colors16
-rw-r--r--src-qt5/core/libLumina/colors/Solarized-Light.qss.colors16
-rw-r--r--src-qt5/core/libLumina/libLumina.pro65
-rw-r--r--src-qt5/core/libLumina/quickplugins/quick-sample.qml12
-rw-r--r--src-qt5/core/libLumina/themes/Glass.qss.template539
-rw-r--r--src-qt5/core/libLumina/themes/Lumina-default.qss.template494
-rw-r--r--src-qt5/core/libLumina/themes/None.qss.template118
42 files changed, 1829 insertions, 2514 deletions
diff --git a/src-qt5/core/libLumina/LuminaUtils.cpp b/src-qt5/core/libLumina/LDesktopUtils.cpp
index 1ab3faac..978ce70b 100644
--- a/src-qt5/core/libLumina/LuminaUtils.cpp
+++ b/src-qt5/core/libLumina/LDesktopUtils.cpp
@@ -1,452 +1,40 @@
//===========================================
// Lumina-DE source code
-// Copyright (c) 2013-2015, Ken Moore
+// Copyright (c) 2012-2016, Ken Moore
// Available under the 3-clause BSD license
// See the LICENSE file for full details
//===========================================
-#include "LuminaUtils.h"
+#include "LDesktopUtils.h"
-#include <QString>
-#include <QFile>
-#include <QStringList>
-#include <QObject>
-#include <QTextCodec>
-#include <QDebug>
#include <QDesktopWidget>
-#include <QImageReader>
-#include <QRegExp>
-#include <QFuture>
-#include <QtConcurrent>
+#include <QApplication>
+#include <QScreen>
-#include <LuminaOS.h>
-#include <LuminaThemes.h>
-#include <LuminaXDG.h>
+#include "LuminaThemes.h"
static QStringList fav;
-inline QStringList ProcessRun(QString cmd, QStringList args){
- //Assemble outputs
- QStringList out; out << "1" << ""; //error code, string output
- QProcess proc;
- QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
- env.insert("LANG", "C");
- env.insert("LC_MESSAGES", "C");
- proc.setProcessEnvironment(env);
- proc.setProcessChannelMode(QProcess::MergedChannels);
- if(args.isEmpty()){
- proc.start(cmd, QIODevice::ReadOnly);
- }else{
- proc.start(cmd,args ,QIODevice::ReadOnly);
- }
- QString info;
- while(!proc.waitForFinished(1000)){
- if(proc.state() == QProcess::NotRunning){ break; } //somehow missed the finished signal
- QString tmp = proc.readAllStandardOutput();
- if(tmp.isEmpty()){ proc.terminate(); }
- else{ info.append(tmp); }
- }
- out[0] = QString::number(proc.exitCode());
- out[1] = info+QString(proc.readAllStandardOutput());
- return out;
-}
-//=============
-// LUtils Functions
-//=============
-QString LUtils::LuminaDesktopVersion(){
- QString ver = "1.0.1";
+QString LDesktopUtils::LuminaDesktopVersion(){
+ QString ver = "1.1.2";
#ifdef GIT_VERSION
ver.append( QString(" (Git Revision: %1)").arg(GIT_VERSION) );
#endif
return ver;
}
-QString LUtils::LuminaDesktopBuildDate(){
+QString LDesktopUtils::LuminaDesktopBuildDate(){
#ifdef BUILD_DATE
return BUILD_DATE;
#endif
return "";
}
-int LUtils::runCmd(QString cmd, QStringList args){
- /*QProcess proc;
- proc.setProcessChannelMode(QProcess::MergedChannels);
- if(args.isEmpty()){
- proc.start(cmd);
- }else{
- proc.start(cmd, args);
- }
- //if(!proc.waitForStarted(30000)){ return 1; } //process never started - max wait of 30 seconds
- while(!proc.waitForFinished(300)){
- if(proc.state() == QProcess::NotRunning){ break; } //somehow missed the finished signal
- QCoreApplication::processEvents();
- }
- int ret = proc.exitCode();
- return ret;*/
- QFuture<QStringList> future = QtConcurrent::run(ProcessRun, cmd, args);
- return future.result()[0].toInt(); //turn it back into an integer return code
-
-}
-
-QStringList LUtils::getCmdOutput(QString cmd, QStringList args){
- /*QProcess proc;
- QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
- env.insert("LANG", "C");
- env.insert("LC_MESSAGES", "C");
- proc.setProcessEnvironment(env);
- proc.setProcessChannelMode(QProcess::MergedChannels);
- if(args.isEmpty()){
- proc.start(cmd);
- }else{
- proc.start(cmd,args);
- }
- //if(!proc.waitForStarted(30000)){ return QStringList(); } //process never started - max wait of 30 seconds
- while(!proc.waitForFinished(300)){
- if(proc.state() == QProcess::NotRunning){ break; } //somehow missed the finished signal
- QCoreApplication::processEvents();
- }
- QStringList out = QString(proc.readAllStandardOutput()).split("\n");
- return out;*/
- QFuture<QStringList> future = QtConcurrent::run(ProcessRun, cmd, args);
- return future.result()[1].split("\n"); //Split the return message into lines
-}
-
-QStringList LUtils::readFile(QString filepath){
- QStringList out;
- QFile file(filepath);
- if(file.open(QIODevice::Text | QIODevice::ReadOnly)){
- QTextStream in(&file);
- while(!in.atEnd()){
- out << in.readLine();
- }
- file.close();
- }
- return out;
-}
-
-bool LUtils::writeFile(QString filepath, QStringList contents, bool overwrite){
- QFile file(filepath);
- if(file.exists() && !overwrite){ return false; }
- bool ok = false;
- if(contents.isEmpty()){ contents << "\n"; }
- if( file.open(QIODevice::WriteOnly | QIODevice::Truncate) ){
- QTextStream out(&file);
- out << contents.join("\n");
- if(!contents.last().isEmpty()){ out << "\n"; } //always end with a new line
- file.close();
- ok = true;
- }
- return ok;
-}
-
-bool LUtils::isValidBinary(QString& bin){
- if(!bin.startsWith("/")){
- //Relative path: search for it on the current "PATH" settings
- QStringList paths = QString(qgetenv("PATH")).split(":");
- for(int i=0; i<paths.length(); i++){
- if(QFile::exists(paths[i]+"/"+bin)){ bin = paths[i]+"/"+bin; break;}
- }
- }
- //bin should be the full path by now
- if(!bin.startsWith("/")){ return false; }
- QFileInfo info(bin);
- bool good = (info.exists() && info.isExecutable());
- if(good){ bin = info.absoluteFilePath(); }
- return good;
-}
-
-QString LUtils::GenerateOpenTerminalExec(QString term, QString dirpath){
- //Check the input terminal application (default/fallback - determined by calling application)
- //if(!LUtils::isValidBinary(term)){
- if(term.endsWith(".desktop")){
- //Pull the binary name out of the shortcut
- bool ok = false;
- XDGDesktop DF = LXDG::loadDesktopFile(term,ok);
- if(!ok){ term = "xterm"; }
- else{ term= DF.exec.section(" ",0,0); } //only take the binary name - not any other flags
- }else{
- term = "xterm"; //fallback
- }
- //}
- //Now create the calling command for the designated terminal
- // NOTE: While the "-e" routine is supposed to be universal, many terminals do not properly use it
- // so add some special/known terminals here as necessary
- QString exec;
- qWarning() << " - Reached terminal initialization" << term;
- if(term=="mate-terminal" || term=="lxterminal" || term=="gnome-terminal"){
- exec = term+" --working-directory=\""+dirpath+"\"";
- }else if(term=="xfce4-terminal"){
- exec = term+" --default-working-directory=\""+dirpath+"\"";
- }else if(term=="konsole" || term == "qterminal"){
- exec = term+" --workdir \""+dirpath+"\"";
- }else{
- //-e is the parameter for most of the terminal appliction to execute an external command.
- //In this case we start a shell in the selected directory
- //Need the user's shell first
- QString shell = QString(getenv("SHELL"));
- if(!LUtils::isValidBinary(shell)){ shell = "/bin/sh"; } //universal fallback for a shell
- exec = term + " -e \"cd " + dirpath + " && " + shell + " \" ";
- }
- qDebug() << exec;
- return exec;
-}
-
-QStringList LUtils::listSubDirectories(QString dir, bool recursive){
- //This is a recursive method for returning the full paths of all subdirectories (if recursive flag is enabled)
- QDir maindir(dir);
- QStringList out;
- QStringList subs = maindir.entryList(QDir::NoDotAndDotDot | QDir::Dirs, QDir::Name);
- for(int i=0; i<subs.length(); i++){
- out << maindir.absoluteFilePath(subs[i]);
- if(recursive){
- out << LUtils::listSubDirectories(maindir.absoluteFilePath(subs[i]), recursive);
- }
- }
- return out;
-}
-
-QString LUtils::PathToAbsolute(QString path){
- //Convert an input path to an absolute path (this does not check existance ot anything)
- if(path.startsWith("/")){ return path; } //already an absolute path
- if(path.startsWith("~")){ path.replace(0,1,QDir::homePath()); }
- if(!path.startsWith("/")){
- //Must be a relative path
- if(path.startsWith("./")){ path = path.remove(2); }
- path.prepend( QDir::currentPath()+"/");
- }
- return path;
-}
-QString LUtils::AppToAbsolute(QString path){
- if(path.startsWith("~/")){ path = path.replace("~/", QDir::homePath()+"/" ); }
- if(path.startsWith("/") || QFile::exists(path)){ return path; }
- if(path.endsWith(".desktop")){
- //Look in the XDG dirs
- QStringList dirs = LXDG::systemApplicationDirs();
- for(int i=0; i<dirs.length(); i++){
- if(QFile::exists(dirs[i]+"/"+path)){ return (dirs[i]+"/"+path); }
- }
- }else{
- //Look on $PATH for the binary
- QStringList paths = QString(getenv("PATH")).split(":");
- for(int i=0; i<paths.length(); i++){
- if(QFile::exists(paths[i]+"/"+path)){ return (paths[i]+"/"+path); }
- }
- }
- return path;
-}
-
-QStringList LUtils::imageExtensions(bool wildcards){
- //Note that all the image extensions are lowercase!!
- static QStringList imgExtensions;
- if(imgExtensions.isEmpty()){
- QList<QByteArray> fmt = QImageReader::supportedImageFormats();
- for(int i=0; i<fmt.length(); i++){
- if(wildcards){ imgExtensions << "*."+QString::fromLocal8Bit(fmt[i]); }
- else{ imgExtensions << QString::fromLocal8Bit(fmt[i]); }
- }
- }
- return imgExtensions;
-}
-
- QTranslator* LUtils::LoadTranslation(QApplication *app, QString appname, QString locale, QTranslator *cTrans){
- //Get the current localization
- QString langEnc = "UTF-8"; //default value
- QString langCode = locale; //provided locale
- if(langCode.isEmpty()){ langCode = getenv("LC_ALL"); }
- if(langCode.isEmpty()){ langCode = getenv("LANG"); }
- if(langCode.isEmpty()){ langCode = "en_US.UTF-8"; } //default to US english
- //See if the encoding is included and strip it out as necessary
- if(langCode.contains(".")){
- langEnc = langCode.section(".",-1);
- langCode = langCode.section(".",0,0);
- }
- //Now verify the encoding for the locale
- if(langCode =="C" || langCode=="POSIX" || langCode.isEmpty()){
- langEnc = "System"; //use the Qt system encoding
- }
- if(app !=0){
- qDebug() << "Loading Locale:" << appname << langCode << langEnc;
- //If an existing translator was provided, remove it first (will be replaced)
- if(cTrans!=0){ app->removeTranslator(cTrans); }
- //Setup the translator
- cTrans = new QTranslator();
- //Use the shortened locale code if specific code does not have a corresponding file
- if(!QFile::exists(LOS::LuminaShare()+"i18n/"+appname+"_" + langCode + ".qm") && langCode!="en_US" ){
- langCode.truncate( langCode.indexOf("_") );
- }
- QString filename = appname+"_"+langCode+".qm";
- //qDebug() << "FileName:" << filename << "Dir:" << LOS::LuminaShare()+"i18n/";
- if( cTrans->load( filename, LOS::LuminaShare()+"i18n/" ) ){
- app->installTranslator( cTrans );
- }else{
- //Translator could not be loaded for some reason
- cTrans = 0;
- if(langCode!="en_US"){
- qWarning() << " - Could not load Locale:" << langCode;
- }
- }
- }else{
- //Only going to set the encoding since no application given
- qDebug() << "Loading System Encoding:" << langEnc;
- }
- //Load current encoding for this locale
- QTextCodec::setCodecForLocale( QTextCodec::codecForName(langEnc.toUtf8()) );
- return cTrans;
-}
-
-QStringList LUtils::knownLocales(){
- QDir i18n = QDir(LOS::LuminaShare()+"i18n");
- if( !i18n.exists() ){ return QStringList(); }
- QStringList files = i18n.entryList(QStringList() << "lumina-desktop_*.qm", QDir::Files, QDir::Name);
- if(files.isEmpty()){ return QStringList(); }
- //Now strip off the filename and just leave the locale tag
- for(int i=0; i<files.length(); i++){
- files[i].chop(3); //remove the ".qm" on the end
- files[i] = files[i].section("_",1,50).simplified();
- }
- files << "en_US"; //default locale
- files.sort();
- return files;
-}
-
-void LUtils::setLocaleEnv(QString lang, QString msg, QString time, QString num,QString money,QString collate, QString ctype){
- //Adjust the current locale environment variables
- bool all = false;
- if(msg.isEmpty() && time.isEmpty() && num.isEmpty() && money.isEmpty() && collate.isEmpty() && ctype.isEmpty() ){
- if(lang.isEmpty()){ return; } //nothing to do - no changes requested
- all = true; //set everything to the "lang" value
- }
- //If no lang given, but others are given, then use the current setting
- if(lang.isEmpty()){ lang = getenv("LC_ALL"); }
- if(lang.isEmpty()){ lang = getenv("LANG"); }
- if(lang.isEmpty()){ lang = "en_US"; }
- //Now go through and set/unset the environment variables
- // - LANG & LC_ALL
- if(!lang.contains(".")){ lang.append(".UTF-8"); }
- setenv("LANG",lang.toUtf8() ,1); //overwrite setting (this is always required as the fallback)
- if(all){ setenv("LC_ALL",lang.toUtf8() ,1); }
- else{ unsetenv("LC_ALL"); } //make sure the custom settings are used
- // - LC_MESSAGES
- if(msg.isEmpty()){ unsetenv("LC_MESSAGES"); }
- else{
- if(!msg.contains(".")){ msg.append(".UTF-8"); }
- setenv("LC_MESSAGES",msg.toUtf8(),1);
- }
- // - LC_TIME
- if(time.isEmpty()){ unsetenv("LC_TIME"); }
- else{
- if(!time.contains(".")){ time.append(".UTF-8"); }
- setenv("LC_TIME",time.toUtf8(),1);
- }
- // - LC_NUMERIC
- if(num.isEmpty()){ unsetenv("LC_NUMERIC"); }
- else{
- if(!num.contains(".")){ num.append(".UTF-8"); }
- setenv("LC_NUMERIC",num.toUtf8(),1);
- }
- // - LC_MONETARY
- if(money.isEmpty()){ unsetenv("LC_MONETARY"); }
- else{
- if(!money.contains(".")){ money.append(".UTF-8"); }
- setenv("LC_MONETARY",money.toUtf8(),1);
- }
- // - LC_COLLATE
- if(collate.isEmpty()){ unsetenv("LC_COLLATE"); }
- else{
- if(!collate.contains(".")){ collate.append(".UTF-8"); }
- setenv("LC_COLLATE",collate.toUtf8(),1);
- }
- // - LC_CTYPE
- if(ctype.isEmpty()){ unsetenv("LC_CTYPE"); }
- else{
- if(!ctype.contains(".")){ ctype.append(".UTF-8"); }
- setenv("LC_CTYPE",ctype.toUtf8(),1);
- }
-}
-
-QString LUtils::currentLocale(){
- QString curr = getenv("LC_ALL");// = QLocale::system();
- if(curr.isEmpty()){ curr = getenv("LANG"); }
- if(curr.isEmpty()){ curr = "en_US"; }
- curr = curr.section(".",0,0); //remove any encodings off the end
- return curr;
-}
-
-double LUtils::DisplaySizeToBytes(QString num){
- //qDebug() << "Convert Num to Bytes:" << num;
- num = num.toLower().simplified();
- num = num.remove(" ");
- if(num.isEmpty()){ return 0.0; }
- if(num.endsWith("b")){ num.chop(1); } //remove the "bytes" marker (if there is one)
- QString lab = "b";
- if(!num[num.size()-1].isNumber()){
- lab = num.right(1); num.chop(1);
- }
- double N = num.toDouble();
- QStringList labs; labs <<"b"<<"k"<<"m"<<"g"<<"t"<<"p"; //go up to petabytes for now
- for(int i=0; i<labs.length(); i++){
- if(lab==labs[i]){ break; }//already at the right units - break out
- N = N*1024.0; //Move to the next unit of measurement
- }
- //qDebug() << " - Done:" << QString::number(N) << lab << num;
- return N;
-}
-
-QString LUtils::BytesToDisplaySize(qint64 ibytes){
- static QStringList labs = QStringList();
- if(labs.isEmpty()){ labs << "B" << "K" << "M" << "G" << "T" << "P"; }
- //Now get the dominant unit
- int c=0;
- double bytes = ibytes; //need to keep decimel places for calculations
- while(bytes>=1000 && c<labs.length() ){
- bytes = bytes/1024;
- c++;
- } //labs[c] is the unit
- //Bytes are now
- //Now format the number (up to 3 digits, not including decimel places)
- QString num;
- if(bytes>=100){
- //No decimel places
- num = QString::number(qRound(bytes));
- }else if(bytes>=10){
- //need 1 decimel place
- num = QString::number( (qRound(bytes*10)/10.0) );
- }else if(bytes>1){
- //need 2 decimel places
- num = QString::number( (qRound(bytes*100)/100.0) );
- }else{
- //Fully decimel (3 places)
- num = "0."+QString::number(qRound(bytes*1000));
- }
- return (num+labs[c]);
-}
-
-QString LUtils::SecondsToDisplay(int secs){
- if(secs < 0){ return "??"; }
- QString rem; //remaining
- if(secs > 3600){
- int hours = secs/3600;
- rem.append( QString::number(hours)+"h ");
- secs = secs - (hours*3600);
- }
- if(secs > 60){
- int min = secs/60;
- rem.append( QString::number(min)+"m ");
- secs = secs - (min*60);
- }
- if(secs > 0){
- rem.append( QString::number(secs)+"s");
- }else{
- rem.append( "0s" );
- }
- return rem;
-}
-
//Various function for finding valid QtQuick plugins on the system
-bool LUtils::validQuickPlugin(QString ID){
- return ( !LUtils::findQuickPluginFile(ID).isEmpty() );
+bool LDesktopUtils::validQuickPlugin(QString ID){
+ return ( !LDesktopUtils::findQuickPluginFile(ID).isEmpty() );
}
-QString LUtils::findQuickPluginFile(QString ID){
+QString LDesktopUtils::findQuickPluginFile(QString ID){
if(ID.startsWith("quick-")){ ID = ID.section("-",1,50); } //just in case
//Give preference to any user-supplied plugins (overwrites for system plugins)
QString path = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/quickplugins/quick-"+ID+".qml";
@@ -456,7 +44,7 @@ QString LUtils::findQuickPluginFile(QString ID){
return ""; //could not be found
}
-QStringList LUtils::listQuickPlugins(){
+QStringList LDesktopUtils::listQuickPlugins(){
QDir dir(QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/quickplugins");
QStringList files = dir.entryList(QStringList() << "quick-*.qml", QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
dir.cd(LOS::LuminaShare()+"quickplugins");
@@ -469,7 +57,7 @@ QStringList LUtils::listQuickPlugins(){
return files;
}
-QStringList LUtils::infoQuickPlugin(QString ID){ //Returns: [Name, Description, Icon]
+QStringList LDesktopUtils::infoQuickPlugin(QString ID){ //Returns: [Name, Description, Icon]
//qDebug() << "Find Quick Info:" << ID;
QString path = findQuickPluginFile(ID);
//qDebug() << " - path:" << path;
@@ -490,7 +78,7 @@ QStringList LUtils::infoQuickPlugin(QString ID){ //Returns: [Name, Description,
return info;
}
-QStringList LUtils::listFavorites(){
+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()){
@@ -503,22 +91,22 @@ QStringList LUtils::listFavorites(){
return fav;
}
-bool LUtils::saveFavorites(QStringList list){
+bool LDesktopUtils::saveFavorites(QStringList list){
list.removeDuplicates();
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
return ok;
}
-bool LUtils::isFavorite(QString path){
- QStringList fav = LUtils::listFavorites();
+bool LDesktopUtils::isFavorite(QString path){
+ QStringList fav = LDesktopUtils::listFavorites();
for(int i=0; i<fav.length(); i++){
if(fav[i].endsWith("::::"+path)){ return true; }
}
return false;
}
-bool LUtils::addFavorite(QString path, QString name){
+bool LDesktopUtils::addFavorite(QString path, QString name){
//Generate the type of favorite this is
QFileInfo info(path);
QString type;
@@ -528,30 +116,30 @@ bool LUtils::addFavorite(QString path, QString name){
//Assign a name if none given
if(name.isEmpty()){ name = info.fileName(); }
//Now add it to the list
- QStringList favs = LUtils::listFavorites();
+ QStringList favs = LDesktopUtils::listFavorites();
bool found = false;
for(int i=0; i<favs.length(); i++){
if(favs[i].endsWith("::::"+path)){ favs[i] = name+"::::"+type+"::::"+path; }
}
if(!found){ favs << name+"::::"+type+"::::"+path; }
- return LUtils::saveFavorites(favs);
+ return LDesktopUtils::saveFavorites(favs);
}
-void LUtils::removeFavorite(QString path){
- QStringList fav = LUtils::listFavorites();
+void LDesktopUtils::removeFavorite(QString path){
+ QStringList fav = LDesktopUtils::listFavorites();
bool changed = false;
for(int i=0; i<fav.length(); i++){
if(fav[i].endsWith("::::"+path)){ fav.removeAt(i); i--; changed=true;}
}
- if(changed){ LUtils::saveFavorites(fav); }
+ if(changed){ LDesktopUtils::saveFavorites(fav); }
}
-void LUtils::upgradeFavorites(int fromoldversionnumber){
+void LDesktopUtils::upgradeFavorites(int fromoldversionnumber){
/*if(fromoldversionnumber <= 8004){ // < pre-0.8.4>, sym-links in the ~/.lumina/favorites dir}
//Include 0.8.4-devel versions in this upgrade (need to distinguish b/w devel and release versions later somehow)
QDir favdir(QDir::homePath()+"/.lumina/favorites");
QFileInfoList symlinks = favdir.entryInfoList(QDir::Files | QDir::Dirs | QDir::System | QDir::NoDotAndDotDot);
- QStringList favfile = LUtils::listFavorites(); //just in case some already exist
+ QStringList favfile = LDesktopUtils::listFavorites(); //just in case some already exist
bool newentry = false;
for(int i=0; i<symlinks.length(); i++){
if(!symlinks[i].isSymLink()){ continue; } //not a symlink
@@ -568,13 +156,13 @@ void LUtils::upgradeFavorites(int fromoldversionnumber){
newentry = true;
}
if(newentry){
- LUtils::saveFavorites(favfile);
+ LDesktopUtils::saveFavorites(favfile);
}
}*/ //end check for version <= 0.8.4
}
-void LUtils::LoadSystemDefaults(bool skipOS){
+void LDesktopUtils::LoadSystemDefaults(bool skipOS){
//Will create the Lumina configuration files based on the current system template (if any)
qDebug() << "Loading System Defaults";
QStringList sysDefaults;
@@ -603,7 +191,7 @@ void LUtils::LoadSystemDefaults(bool skipOS){
QStringList tmp = sysDefaults.filter("session_");
if(tmp.isEmpty()){ tmp = sysDefaults.filter("session."); }//for backwards compat
sesset << "[General]"; //everything is in this section
- sesset << "DesktopVersion="+LUtils::LuminaDesktopVersion();
+ sesset << "DesktopVersion="+LDesktopUtils::LuminaDesktopVersion();
for(int i=0; i<tmp.length(); i++){
if(tmp[i].startsWith("#") || !tmp[i].contains("=") ){ continue; }
QString var = tmp[i].section("=",0,0).toLower().simplified();
@@ -614,7 +202,7 @@ void LUtils::LoadSystemDefaults(bool skipOS){
if(var.contains(".")){ var.replace(".","_"); }
//Now parse the variable and put the value in the proper file
- if(var.contains("_default_")){ val = AppToAbsolute(val); } //got an application/binary
+ if(var.contains("_default_")){ val = LUtils::AppToAbsolute(val); } //got an application/binary
//Special handling for values which need to exist first
if(var.endsWith("_ifexists") ){
var = var.remove("_ifexists"); //remove this flag from the variable
@@ -668,7 +256,7 @@ void LUtils::LoadSystemDefaults(bool skipOS){
//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 = AppToAbsolute(val);
+ 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
@@ -681,10 +269,11 @@ void LUtils::LoadSystemDefaults(bool skipOS){
}
// -- DESKTOP SETTINGS --
+ QString deskID = QApplication::primaryScreen()->name();
//(only works for the primary desktop at the moment)
tmp = sysDefaults.filter("desktop_");
if(tmp.isEmpty()){ tmp = sysDefaults.filter("desktop."); }//for backwards compat
- if(!tmp.isEmpty()){deskset << "[desktop-"+screen+"]"; }
+ if(!tmp.isEmpty()){deskset << "[desktop-"+deskID+"]"; }
for(int i=0; i<tmp.length(); i++){
if(tmp[i].startsWith("#") || !tmp[i].contains("=") ){ continue; }
QString var = tmp[i].section("=",0,0).toLower().simplified();
@@ -707,7 +296,7 @@ void LUtils::LoadSystemDefaults(bool skipOS){
for(int i=1; i<11; i++){
QString panvar = "panel"+QString::number(i);
tmp = sysDefaults.filter(panvar);
- if(!tmp.isEmpty()){deskset << "[panel"+screen+"."+QString::number(i-1)+"]"; }
+ if(!tmp.isEmpty()){deskset << "[panel_"+deskID+"."+QString::number(i-1)+"]"; }
for(int i=0; i<tmp.length(); i++){
if(tmp[i].startsWith("#") || !tmp[i].contains("=") ){ continue; }
QString var = tmp[i].section("=",0,0).toLower().simplified();
@@ -764,10 +353,10 @@ void LUtils::LoadSystemDefaults(bool skipOS){
if(var.contains(".")){ var.replace(".","_"); }
//Now parse the variable and put the value in the proper file
qDebug() << "Favorite entry:" << var << val;
- val = AppToAbsolute(val); //turn any relative files into absolute
- if(var=="favorites_add_ifexists" && QFile::exists(val)){ qDebug() << " - Exists/Adding:"; LUtils::addFavorite(val); }
- else if(var=="favorites_add"){ qDebug() << " - Adding:"; LUtils::addFavorite(val); }
- else if(var=="favorites_remove"){ qDebug() << " - Removing:"; LUtils::removeFavorite(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); }
+ else if(var=="favorites_add"){ qDebug() << " - Adding:"; LDesktopUtils::addFavorite(val); }
+ else if(var=="favorites_remove"){ qDebug() << " - Removing:"; LDesktopUtils::removeFavorite(val); }
}
// -- QUICKLAUNCH --
@@ -781,7 +370,7 @@ void LUtils::LoadSystemDefaults(bool skipOS){
//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 = AppToAbsolute(val); //turn any relative files into absolute
+ val = LUtils::AppToAbsolute(val); //turn any relative files into absolute
if(var=="quicklaunch_add_ifexists" && QFile::exists(val)){ quickL << val; }
else if(var=="quicklaunch_add"){ quickL << val; }
}
@@ -874,12 +463,12 @@ void LUtils::LoadSystemDefaults(bool skipOS){
}
-bool LUtils::checkUserFiles(QString lastversion){
+bool LDesktopUtils::checkUserFiles(QString lastversion){
//internal version conversion examples:
// [1.0.0 -> 1000000], [1.2.3 -> 1002003], [0.6.1 -> 6001]
//returns true if something changed
- int oldversion = LUtils::VersionStringToNumber(lastversion);
- int nversion = LUtils::VersionStringToNumber(QApplication::applicationVersion());
+ int oldversion = LDesktopUtils::VersionStringToNumber(lastversion);
+ int nversion = LDesktopUtils::VersionStringToNumber(QApplication::applicationVersion());
bool newversion = ( oldversion < nversion ); //increasing version number
bool newrelease = ( lastversion.contains("-devel", Qt::CaseInsensitive) && QApplication::applicationVersion().contains("-release", Qt::CaseInsensitive) ); //Moving from devel to release
@@ -890,56 +479,37 @@ bool LUtils::checkUserFiles(QString lastversion){
if(!QFile::exists(dset) || oldversion < 5000){
if( oldversion < 100000 && nversion>=100000 ){ system("rm -rf ~/.lumina"); qDebug() << "Current desktop settings obsolete: Re-implementing defaults"; }
else{ firstrun = true; }
- LUtils::LoadSystemDefaults();
+ LDesktopUtils::LoadSystemDefaults();
}
//Convert the favorites framework as necessary (change occured with 0.8.4)
if(newversion || newrelease){
- LUtils::upgradeFavorites(oldversion);
- }
- //Convert any "userbutton" and "appmenu" panel plugins to the new "systemstart" plugin (0.8.7)
- /*if(oldversion <= 8007 && (newversion || newrelease) && nversion < 8008){
- QSettings dset(QSettings::UserScope, "LuminaDE","desktopsettings");
- QStringList plugKeys = dset.allKeys().filter("panel").filter("/pluginlist");
- for(int i=0; i<plugKeys.length(); i++){
- QStringList plugs = dset.value(plugKeys[i],QStringList()).toStringList();
- //Do the appmenu/userbutton -> systemstart conversion
- plugs = plugs.join(";;;;").replace("userbutton","systemstart").replace("appmenu","systemstart").split(";;;;");
- //Remove any system dashboard plugins
- plugs.removeAll("systemdashboard");
- //Now save that back to the file
- dset.setValue(plugKeys[i], plugs);
- }
- //Also remove any "desktopview" desktop plugin and enable the automatic desktop icons instead
- plugKeys = dset.allKeys().filter("desktop-").filter("/pluginlist");
- for(int i=0; i<plugKeys.length(); i++){
- QStringList plugs = dset.value(plugKeys[i], QStringList()).toStringList();
- QStringList old = plugs.filter("desktopview");
- bool found = !old.isEmpty();
- for(int j=0; j<old.length(); j++){ plugs.removeAll(old[j]); }
- if(found){
- dset.setValue(plugKeys[i],plugs); //save the modified plugin list
- //Also set the auto-generate flag on this desktop
- dset.setValue(plugKeys[i].section("/",0,0)+"/generateDesktopIcons", true);
+ LDesktopUtils::upgradeFavorites(oldversion);
+ }
+ //Convert from the old desktop numbering system to the new one (change occured with 1.0.1)
+ if(oldversion<=1000001){
+ QStringList DS = LUtils::readFile(dset);
+ QList<QScreen*> screens = QApplication::screens();
+ for(int i=0; i<DS.length(); i++){
+ if(!DS[i].startsWith("[")){ continue; }
+ if(DS[i].startsWith("[desktop-")){
+ bool ok = false;
+ int num = DS[i].section("desktop-",-1).section("]",0,0).toInt(&ok);
+ if(num>=0 && ok && num< screens.length()){
+ //This one needs to be converted
+ DS[i] = "[desktop-"+screens[num]->name()+"]";
+ }
+ }else if(DS[i].startsWith("[panel")){
+ bool ok = false;
+ int num = DS[i].section("panel",-1).section(".",0,0).toInt(&ok);
+ if(num>=0 && ok && num< screens.length()){
+ //This one needs to be converted
+ QString rest = DS[i].section(".",1,-1); //everything after the desktop number in the current setting
+ DS[i] = "[panel_"+screens[num]->name()+"."+rest;
+ }
}
}
- dset.sync();
- //Due to the grid size change for desktop plugins, need to remove any old plugin geometries
- if(QFile::exists(QDir::homePath()+"/.lumina/pluginsettings/desktopsettings.conf")){
- QFile::remove(QDir::homePath()+"/.lumina/pluginsettings/desktopsettings.conf");
- }
- }*/
-
- //Convert to the XDG autostart spec as necessary (Change occured with 0.8.5)
- /*if(QFile::exists(QDir::homePath()+"/.lumina/startapps") ){
- QStringList cmds = LUtils::readFile(QDir::homePath()+"/.lumina/startapps");
- for(int i=0; i<cmds.length(); i++){
- cmds[i] = cmds[i].remove("lumina-open").simplified(); //remove the file opener
- if(cmds[i].startsWith("#") || cmds[i].isEmpty()){ continue; } //invalid line
-
- LXDG::setAutoStarted(true, cmds[i]);
- }
- QFile::remove(QDir::homePath()+"/.lumina/startapps"); //delete the old file
- }*/
+ LUtils::writeFile(dset, DS, true);
+ }
//Check the fluxbox configuration files
dset = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/";
@@ -966,7 +536,7 @@ bool LUtils::checkUserFiles(QString lastversion){
return (firstrun || newversion || newrelease);
}
-int LUtils::VersionStringToNumber(QString version){
+int LDesktopUtils::VersionStringToNumber(QString version){
version = version.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;
@@ -979,102 +549,3 @@ int LUtils::VersionStringToNumber(QString version){
//NOTE: This format allows numbers to be anywhere from 0->999 without conflict
return (maj*1000000 + mid*1000 + min);
}
-
-// =======================
-// RESIZEMENU CLASS
-// =======================
-ResizeMenu::ResizeMenu(QWidget *parent) : QMenu(parent){
- this->setContentsMargins(1,1,1,1);
- this->setMouseTracking(true);
- resizeSide = NONE;
- cAct = new QWidgetAction(this);
- contents = 0;
- connect(this, SIGNAL(aboutToShow()), this, SLOT(clearFlags()) );
- connect(this, SIGNAL(aboutToHide()), this, SLOT(clearFlags()) );
- connect(cAct, SIGNAL(hovered()), this, SLOT(clearFlags()) );
-}
-
-ResizeMenu::~ResizeMenu(){
-
-}
-
-void ResizeMenu::setContents(QWidget *con){
- this->clear();
- cAct->setDefaultWidget(con);
- this->addAction(cAct);
- contents = con; //save for later
- contents->setCursor(Qt::ArrowCursor);
-}
-
-void ResizeMenu::mouseMoveEvent(QMouseEvent *ev){
- QRect geom = this->geometry();
- //Note: The exact position does not matter as much as the size
- // since the window will be moved again the next time it is shown
- // The "-2" in the sizing below accounts for the menu margins
- QPoint gpos = this->mapToGlobal(ev->pos());
- bool handled = false;
- switch(resizeSide){
- case TOP:
- if(gpos.y() >= geom.bottom()-1){ break; }
- geom.setTop(gpos.y());
- this->setGeometry(geom);
- if(contents!=0){ contents->setFixedSize(QSize(geom.width()-2, geom.height()-2));}
- handled = true;
- break;
- case BOTTOM:
- if(gpos.y() <= geom.top()+1){ break; }
- geom.setBottom( gpos.y());
- this->setGeometry(geom);
- if(contents!=0){ contents->setFixedSize(QSize(geom.width()-2, geom.height()-2));}
- handled = true;
- break;
- case LEFT:
- if(gpos.x() >= geom.right()-1){ break; }
- geom.setLeft(gpos.x());
- this->setGeometry(geom);
- if(contents!=0){ contents->setFixedSize(QSize(geom.width()-2, geom.height()-2));}
- handled = true;
- break;
- case RIGHT:
- if(gpos.x() <= geom.left()+1){ break; }
- geom.setRight(gpos.x());
- this->setGeometry(geom);
- if(contents!=0){ contents->setFixedSize(QSize(geom.width()-2, geom.height()-2));}
- handled = true;
- break;
- default: //NONE
- //qDebug() << " - Mouse At:" << ev->pos();
- //Just adjust the mouse cursor which is shown
- if(ev->pos().x()<=1 && ev->pos().x() >= -1){ this->setCursor(Qt::SizeHorCursor); }
- else if(ev->pos().x() >= this->width()-1 && ev->pos().x() <= this->width()+1){ this->setCursor(Qt::SizeHorCursor); }
- else if(ev->pos().y()<=1 && ev->pos().y() >= -1){ this->setCursor(Qt::SizeVerCursor); }
- else if(ev->pos().y() >= this->height()-1 && ev->pos().y() <= this->height()+1){ this->setCursor(Qt::SizeVerCursor); }
- else{ this->setCursor(Qt::ArrowCursor); }
- }
- if(!handled){ QMenu::mouseMoveEvent(ev); } //do normal processing as well
-}
-
-void ResizeMenu::mousePressEvent(QMouseEvent *ev){
- bool used = false;
- if(ev->buttons().testFlag(Qt::LeftButton) && resizeSide==NONE){
- //qDebug() << "Mouse Press Event:" << ev->pos() << resizeSide;
- if(ev->pos().x()<=1 && ev->pos().x() >= -1){resizeSide = LEFT; used = true;}
- else if(ev->pos().x() >= this->width()-1 && ev->pos().x() <= this->width()+1){ resizeSide = RIGHT; used = true;}
- else if(ev->pos().y()<=1 && ev->pos().y() >= -1){ resizeSide = TOP; used = true; }
- else if(ev->pos().y() >= this->height()-1 && ev->pos().y() <= this->height()+1){ resizeSide = BOTTOM; used = true; }
- }
- if(used){ ev->accept(); this->grabMouse(); }
- else{ QMenu::mousePressEvent(ev); } //do normal processing
-}
-
-void ResizeMenu::mouseReleaseEvent(QMouseEvent *ev){
- this->releaseMouse();
- if(ev->button() == Qt::LeftButton && resizeSide!=NONE ){
- //qDebug() << "Mouse Release Event:" << ev->pos() << resizeSide;
- resizeSide = NONE;
- emit MenuResized(contents->size());
- ev->accept();
- }else{
- QMenu::mouseReleaseEvent(ev); //do normal processing
- }
-}
diff --git a/src-qt5/core/libLumina/LDesktopUtils.h b/src-qt5/core/libLumina/LDesktopUtils.h
new file mode 100644
index 00000000..dbad8757
--- /dev/null
+++ b/src-qt5/core/libLumina/LDesktopUtils.h
@@ -0,0 +1,49 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2012-2016, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#ifndef _LUMINA_LIBRARY_DESKTOP_UTILS_H
+#define _LUMINA_LIBRARY_DESKTOP_UTILS_H
+
+#include <QString>
+#include <QStringList>
+#include <QFile>
+#include <QDir>
+#include <QDateTime>
+
+//Other classes needed
+#include <LUtils.h>
+#include <LuminaXDG.h>
+#include <LuminaOS.h>
+
+class LDesktopUtils{
+public:
+ //Get the current version/build of the Lumina desktop
+ static QString LuminaDesktopVersion();
+ static QString LuminaDesktopBuildDate();
+
+ //Various function for finding valid QtQuick plugins on the system
+ static bool validQuickPlugin(QString ID);
+ static QString findQuickPluginFile(QString ID);
+ static QStringList listQuickPlugins(); //List of valid ID's
+ static QStringList infoQuickPlugin(QString ID); //Returns: [Name, Description, Icon]
+
+ //Various functions for the favorites sub-system
+ // Formatting Note: "<name>::::[dir/app/<mimetype>]::::<path>"
+ // the <name> field might not be used for "app" flagged entries
+ static QStringList listFavorites();
+ static bool saveFavorites(QStringList);
+ static bool isFavorite(QString path);
+ static bool addFavorite(QString path, QString name = "");
+ static void removeFavorite(QString path);
+ static void upgradeFavorites(int fromoldversionnumber);
+
+ //Load the default setup for the system
+ static void LoadSystemDefaults(bool skipOS = false);
+ static bool checkUserFiles(QString lastversion); //returns true if something changed
+ static int VersionStringToNumber(QString version); //convert the lumina version string to a number for comparisons
+};
+
+#endif
diff --git a/src-qt5/core/libLumina/LDesktopUtils.pri b/src-qt5/core/libLumina/LDesktopUtils.pri
new file mode 100644
index 00000000..80bbcfa8
--- /dev/null
+++ b/src-qt5/core/libLumina/LDesktopUtils.pri
@@ -0,0 +1,7 @@
+SOURCES *= $${PWD}/LDesktopUtils.cpp
+HEADERS *= $${PWD}/LDesktopUtils.h
+
+INCLUDEPATH *= ${PWD}
+
+#Now the other dependendies of it
+include(LUtils.pri)
diff --git a/src-qt5/core/libLumina/LInputDevice.cpp b/src-qt5/core/libLumina/LInputDevice.cpp
new file mode 100644
index 00000000..a04dd607
--- /dev/null
+++ b/src-qt5/core/libLumina/LInputDevice.cpp
@@ -0,0 +1,275 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2016, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "LInputDevice.h"
+
+//Qt Library includes
+#include <QString>
+#include <QX11Info>
+#include <QDebug>
+
+//XCB Library includes
+#include <xcb/xcb.h>
+#include <xcb/xcb_atom.h>
+#include <xcb/xinput.h>
+#include <xcb/xproto.h>
+
+#include <LUtils.h>
+
+//===================
+// LInputDevice Class
+//===================
+// === PUBLIC ===
+LInputDevice::LInputDevice(unsigned int id, unsigned int type){
+ devID = id;
+ devType = type;
+ //ATOM_FLOAT = 0; //init this when needed later
+ //devName = name;
+ getProperties(); //need to populate the name/atom correlations for properties
+ readProperties(); //populate the hash with the current values of the properties
+}
+
+LInputDevice::~LInputDevice(){
+
+}
+
+unsigned int LInputDevice::devNumber(){
+ return devID;
+}
+
+bool LInputDevice::isPointer(){
+ return (devType==XCB_INPUT_DEVICE_USE_IS_X_POINTER \
+ || devType==XCB_INPUT_DEVICE_USE_IS_X_EXTENSION_POINTER);
+}
+
+bool LInputDevice::isKeyboard(){
+ return (devType==XCB_INPUT_DEVICE_USE_IS_X_KEYBOARD \
+ || devType==XCB_INPUT_DEVICE_USE_IS_X_EXTENSION_KEYBOARD);
+}
+
+bool LInputDevice::isExtension(){
+ return (devType==XCB_INPUT_DEVICE_USE_IS_X_EXTENSION_DEVICE \
+ || devType==XCB_INPUT_DEVICE_USE_IS_X_EXTENSION_KEYBOARD \
+ || devType==XCB_INPUT_DEVICE_USE_IS_X_EXTENSION_POINTER);
+}
+
+// Property Management
+QList<int> LInputDevice::listProperties(){
+ return devProps.keys();
+}
+
+QString LInputDevice::propertyName(int prop){
+ if(devProps.contains(prop)){ return devProps[prop].name; }
+ else{ return ""; }
+}
+
+QVariant LInputDevice::getPropertyValue(int prop){
+ if(devProps.contains(prop)){ return devProps[prop].value; }
+ else{ return QVariant(); }
+}
+
+bool LInputDevice::setPropertyValue(int prop, QVariant value){
+ if(!devProps.contains(prop)){ return false; }
+ //Need the float atom for some properties - make sure we have that first
+ /*if(ATOM_FLOAT==0){
+ xcb_intern_atom_reply_t *ar = xcb_intern_atom_reply(QX11Info::connection(), \
+ xcb_intern_atom(QX11Info::connection(), 0, 1, "FLOAT"), NULL);
+ if(ar!=0){
+ ATOM_FLOAT = ar->atom;
+ free(ar);
+ }
+ }*/
+ //Now setup the argument
+ bool ok = false;
+ QStringList args;
+ args << "--set-prop";
+ args << QString::number(devID);
+ args << QString::number(prop); //prop ID
+ args << variantToString(value);
+ ok = (0 == LUtils::runCmd("xinput", args) );
+ if(ok){
+ //Need to update the value in the hash as well
+ propData dat = devProps[prop];
+ dat.value = value;
+ devProps.insert(prop, dat);
+ }
+ return ok;
+}
+
+// === PRIVATE ===
+void LInputDevice::getProperties(){
+ devProps.clear();
+ xcb_input_list_device_properties_cookie_t cookie = xcb_input_list_device_properties_unchecked(QX11Info::connection(), devID);
+ xcb_input_list_device_properties_reply_t *reply = xcb_input_list_device_properties_reply(QX11Info::connection(), cookie, NULL);
+ //Get the atoms
+ xcb_atom_t *atoms = xcb_input_list_device_properties_atoms(reply);
+ //qDebug() << "Property Response Type:" << reply->response_type; //Always seems to be "1"
+ QList<xcb_get_atom_name_cookie_t> cookies;
+ for(int i=0; i<reply->num_atoms; i++){ cookies << xcb_get_atom_name(QX11Info::connection(), atoms[i]); }
+ for(int i=0; i<reply->num_atoms; i++){
+ xcb_get_atom_name_reply_t *nr = xcb_get_atom_name_reply(QX11Info::connection(), cookies[i], NULL);
+ propData DATA;
+ DATA.name = QString::fromUtf8( xcb_get_atom_name_name(nr), xcb_get_atom_name_name_length(nr) );
+ DATA.atom = atoms[i];
+ DATA.id = (int)(atoms[i]);
+ devProps.insert(DATA.id,DATA);
+ ::free(nr);
+ }
+ //Done with data structure
+ ::free(reply);
+}
+
+void LInputDevice::readProperties(){
+ QList<int> props = devProps.keys();
+ //XINPUT UTILITY USAGE (alternative to XCB which actually works right now)
+ QStringList info = LUtils::getCmdOutput("xinput list-props "+QString::number(devID));
+ for(int i=0; i<props.length(); i++){
+ propData PROP = devProps[props[i]];
+ QStringList filter = info.filter(" ("+QString::number(PROP.id)+"):");
+ if(filter.length()==1){
+ QString val = filter.first().section("):",1,-1).simplified();
+ //Now figure out what type of value this is and save it into the QVariant
+ QVariant variant;
+ if(val.split(", ").length()>1){
+ //some kind of array
+ QList<QVariant> list;
+ QStringList valList = val.split(", ");
+ for(int j=0; j<valList.length(); j++){ list << valueToVariant(valList[j]); }
+ variant = QVariant(list);
+ }else{
+ variant = valueToVariant(val);
+ }
+ PROP.value = variant;
+ }
+ devProps.insert(props[i], PROP);
+ }
+
+//XCB Code (non-functional - issue with library itself? 12/6/16 - Ken Moore)
+ /*QVariant result;
+ if(!devProps.contains(prop)){qDebug() << "Invalid Property"; return result; }
+ //Now generate the property request
+ xcb_input_get_device_property_cookie_t cookie = xcb_input_get_device_property_unchecked( QX11Info::connection(), devProps.value(prop).atom, \
+ XCB_ATOM_ATOM, 0, 1000, devID, 0);
+ xcb_input_get_device_property_reply_t *reply = xcb_input_get_device_property_reply(QX11Info::connection(), cookie, NULL);
+ if(reply==0){ qDebug() << "Could not get reply!"; return result; }
+ //Now read off the value of the property
+ if(ATOM_FLOAT==0){
+ xcb_intern_atom_reply_t *ar = xcb_intern_atom_reply(QX11Info::connection(), \
+ xcb_intern_atom(QX11Info::connection(), 0, 1, "FLOAT"), NULL);
+ if(ar!=0){
+ ATOM_FLOAT = ar->atom;
+ free(ar);
+ }
+ }
+ //Turn the reply into the proper items array (depends on format of the return data)
+ xcb_input_get_device_property_items_t items;
+ qDebug() <<QByteArray::fromRawData( (char*)(xcb_input_get_device_property_items(reply) ) , reply->num_items);
+ void *buffer = xcb_input_get_device_property_items(reply);
+ xcb_input_get_device_property_items_serialize( &buffer, reply->num_items, reply->format, &items);
+
+ //if(reply->num_items > 0){
+ //qDebug() << "Format:" << reply->format << "Length:" << length;
+ //qDebug() << "Response Type:" << reply->response_type << "Pads:" << reply->pad0 << reply->pad1;
+ switch(reply->type){
+ case XCB_ATOM_INTEGER:
+ //qDebug() << "Got Integer";
+
+ break;
+ case XCB_ATOM_CARDINAL:
+ //qDebug() << "Got Cardinal";
+
+ break;
+ case XCB_ATOM_STRING:
+ qDebug() << "Got String:";
+ if(reply->format==8){
+ result.setValue( QByteArray::fromRawData( (char*) xcb_input_get_device_property_items_data_8(&items), sizeof(xcb_input_get_device_property_items_data_8(&items))/sizeof(char)) );
+ }
+ break;
+ case XCB_ATOM_ATOM:
+ //qDebug() << "Got Atom";
+
+ break;
+ default:
+ qDebug() << "Other Type:" << reply->type;
+ }
+ //}
+ free(reply); //done with this structure
+ return result;*/
+}
+
+QVariant LInputDevice::valueToVariant(QString value){
+ //Read through the string and see what type of value it is
+ if(value.count("\"")==2){
+ //String value or atom
+ if(value.endsWith(")")){
+ //ATOM (name string +(atomID))
+ return QVariant(value); //don't strip off the atom number -- keep that within the parenthesis
+ }else{
+ //String
+ value = value.section("\"",1,-2); //everything between the quotes
+ return QVariant(value);
+ }
+ }else if(value.contains(".")){
+ //float/double number
+ return QVariant( value.toDouble() );
+ }else{
+ //integer or boolian (no way to tell right now - assume all int)
+ bool ok = false;
+ int intval = value.toInt(&ok);
+ if(ok){ return QVariant(intval); }
+ }
+ return QVariant();
+}
+
+QString LInputDevice::variantToString(QVariant value){
+ if( value.canConvert< QList<QVariant> >() ){
+ //List of variants
+ QStringList out;
+ QList<QVariant> list = value.toList();
+ for(int i=0; i<list.length(); i++){ out << variantToString(list[i]); }
+ return out.join(", ");
+ }else{
+ //Single value
+ if(value.canConvert<double>() ){
+ return QString::number(value.toDouble());
+ }else if(value.canConvert<int>() ){
+ return QString::number(value.toInt());
+ }else if( value.canConvert<QString>() ){
+ //See if this is an atom first
+ QString val = value.toString();
+ if(val.contains("(")){ val = val.section("(",1,-1).section(")",0,0); }
+ return val;
+ }
+ }
+ return ""; //nothing to return
+}
+
+//======================
+// LInput Static Functions
+//======================
+QList<LInputDevice*> LInput::listDevices(){
+ QList<LInputDevice*> devices;
+ xcb_input_list_input_devices_cookie_t cookie = xcb_input_list_input_devices_unchecked(QX11Info::connection());
+ xcb_input_list_input_devices_reply_t *reply = xcb_input_list_input_devices_reply(QX11Info::connection(), cookie, NULL);
+ if(reply==0){ return devices; } //error - nothing returned
+ //Use the iterator for going through the reply
+ //qDebug() << "Create iterator";
+ xcb_input_device_info_iterator_t iter = xcb_input_list_input_devices_devices_iterator(reply);
+ //xcb_str_iterator_t nameiter = xcb_input_list_input_devices_names_iterator(reply);
+
+ //Now step through the reply
+ while(iter.data != 0 ){
+ devices << new LInputDevice(iter.data->device_id, iter.data->device_use);
+ //qDebug() << "Found Input Device:" << iter.data->device_id;
+ //qDebug() << " - num_class_info:" << iter.data->num_class_info;
+ if(iter.rem>0){ xcb_input_device_info_next(&iter); }
+ else{ break; }
+ }
+ //Free the reply (done with it)
+ ::free(reply);
+ //return the information
+ return devices;
+}
diff --git a/src-qt5/core/libLumina/LInputDevice.h b/src-qt5/core/libLumina/LInputDevice.h
new file mode 100644
index 00000000..82dee4fd
--- /dev/null
+++ b/src-qt5/core/libLumina/LInputDevice.h
@@ -0,0 +1,67 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2016, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+// This class governs all the XCB input device interactions
+// and provides simpler Qt-based functions for use elsewhere
+//===========================================
+#ifndef _LUMINA_XCB_INPUT_DEVICES_H
+#define _LUMINA_XCB_INPUT_DEVICES_H
+
+#include <QList>
+#include <QString>
+#include <QStringList>
+#include <QHash>
+#include <QVariant>
+
+#include <xcb/xproto.h>
+
+//Internal data structure for storing the property information
+struct propData{
+ int id;
+ QString name;
+ QVariant value;
+ xcb_atom_t atom;
+};
+
+class LInputDevice{
+public:
+ LInputDevice(unsigned int id, unsigned int type); //don't use this directly - use the "listDevices()" function instead
+ ~LInputDevice();
+
+ //Device Information
+ //QString name(); //Return the name of this device
+ unsigned int devNumber();
+ bool isPointer();
+ bool isKeyboard();
+ bool isExtension();
+
+ //Property Management
+ QList<int> listProperties();
+ QString propertyName(int prop);
+ QVariant getPropertyValue(int prop);
+ bool setPropertyValue(int prop, QVariant value);
+
+private:
+ unsigned int devID; //device ID number - assigned at class creation
+ unsigned int devType; //device "use" identifier - assigned at class creation
+ QHash<int, propData> devProps; //Known device properties <id#, properties struct>
+
+ void getProperties();
+ void readProperties();
+ QVariant valueToVariant(QString value); //xinput output to QVariant
+ QString variantToString(QVariant value); //QVariant to xinput input string
+
+ //QString devName; //device name - use this for cross-session management (id #'s can get changed every session)
+};
+
+//Static functions for overall management
+class LInput{
+ public:
+ static QList<LInputDevice*> listDevices(); //NOTE: Make sure you "free()" all the LInputDevice objects when finished
+
+};
+
+#endif
diff --git a/src-qt5/core/libLumina/LInputDevice.pri b/src-qt5/core/libLumina/LInputDevice.pri
new file mode 100644
index 00000000..a5f88a05
--- /dev/null
+++ b/src-qt5/core/libLumina/LInputDevice.pri
@@ -0,0 +1,13 @@
+
+QT *= x11extras
+
+LIBS *= -lc -lxcb -lxcb-xinput
+
+#LUtils Files
+SOURCES *= $${PWD}/LInputDevice.cpp
+HEADERS *= $${PWD}/LInputDevice.h
+
+INCLUDEPATH *= ${PWD}
+
+#include LUtils and LuminaOS
+include(LUtils.pri)
diff --git a/src-qt5/core/libLumina/LUtils.cpp b/src-qt5/core/libLumina/LUtils.cpp
new file mode 100644
index 00000000..78831231
--- /dev/null
+++ b/src-qt5/core/libLumina/LUtils.cpp
@@ -0,0 +1,436 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2013-2016, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "LUtils.h"
+
+#include "LuminaOS.h"
+#include "LuminaXDG.h"
+
+#include <QApplication>
+#include <QtConcurrent>
+
+inline QStringList ProcessRun(QString cmd, QStringList args){
+ //Assemble outputs
+ QStringList out; out << "1" << ""; //error code, string output
+ QProcess proc;
+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+ env.insert("LANG", "C");
+ env.insert("LC_MESSAGES", "C");
+ proc.setProcessEnvironment(env);
+ proc.setProcessChannelMode(QProcess::MergedChannels);
+ if(args.isEmpty()){
+ proc.start(cmd, QIODevice::ReadOnly);
+ }else{
+ proc.start(cmd,args ,QIODevice::ReadOnly);
+ }
+ QString info;
+ while(!proc.waitForFinished(1000)){
+ if(proc.state() == QProcess::NotRunning){ break; } //somehow missed the finished signal
+ QString tmp = proc.readAllStandardOutput();
+ if(tmp.isEmpty()){ proc.terminate(); }
+ else{ info.append(tmp); }
+ }
+ out[0] = QString::number(proc.exitCode());
+ out[1] = info+QString(proc.readAllStandardOutput());
+ return out;
+}
+//=============
+// LUtils Functions
+//=============
+int LUtils::runCmd(QString cmd, QStringList args){
+ /*QProcess proc;
+ proc.setProcessChannelMode(QProcess::MergedChannels);
+ if(args.isEmpty()){
+ proc.start(cmd);
+ }else{
+ proc.start(cmd, args);
+ }
+ //if(!proc.waitForStarted(30000)){ return 1; } //process never started - max wait of 30 seconds
+ while(!proc.waitForFinished(300)){
+ if(proc.state() == QProcess::NotRunning){ break; } //somehow missed the finished signal
+ QCoreApplication::processEvents();
+ }
+ int ret = proc.exitCode();
+ return ret;*/
+ QFuture<QStringList> future = QtConcurrent::run(ProcessRun, cmd, args);
+ return future.result()[0].toInt(); //turn it back into an integer return code
+
+}
+
+QStringList LUtils::getCmdOutput(QString cmd, QStringList args){
+ /*QProcess proc;
+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+ env.insert("LANG", "C");
+ env.insert("LC_MESSAGES", "C");
+ proc.setProcessEnvironment(env);
+ proc.setProcessChannelMode(QProcess::MergedChannels);
+ if(args.isEmpty()){
+ proc.start(cmd);
+ }else{
+ proc.start(cmd,args);
+ }
+ //if(!proc.waitForStarted(30000)){ return QStringList(); } //process never started - max wait of 30 seconds
+ while(!proc.waitForFinished(300)){
+ if(proc.state() == QProcess::NotRunning){ break; } //somehow missed the finished signal
+ QCoreApplication::processEvents();
+ }
+ QStringList out = QString(proc.readAllStandardOutput()).split("\n");
+ return out;*/
+ QFuture<QStringList> future = QtConcurrent::run(ProcessRun, cmd, args);
+ return future.result()[1].split("\n"); //Split the return message into lines
+}
+
+QStringList LUtils::readFile(QString filepath){
+ QStringList out;
+ QFile file(filepath);
+ if(file.open(QIODevice::Text | QIODevice::ReadOnly)){
+ QTextStream in(&file);
+ while(!in.atEnd()){
+ out << in.readLine();
+ }
+ file.close();
+ }
+ return out;
+}
+
+bool LUtils::writeFile(QString filepath, QStringList contents, bool overwrite){
+ QFile file(filepath);
+ if(file.exists() && !overwrite){ return false; }
+ bool ok = false;
+ if(contents.isEmpty()){ contents << "\n"; }
+ if( file.open(QIODevice::WriteOnly | QIODevice::Truncate) ){
+ QTextStream out(&file);
+ out << contents.join("\n");
+ if(!contents.last().isEmpty()){ out << "\n"; } //always end with a new line
+ file.close();
+ ok = true;
+ }
+ return ok;
+}
+
+bool LUtils::isValidBinary(QString& bin){
+ if(!bin.startsWith("/")){
+ //Relative path: search for it on the current "PATH" settings
+ QStringList paths = QString(qgetenv("PATH")).split(":");
+ for(int i=0; i<paths.length(); i++){
+ if(QFile::exists(paths[i]+"/"+bin)){ bin = paths[i]+"/"+bin; break;}
+ }
+ }
+ //bin should be the full path by now
+ if(!bin.startsWith("/")){ return false; }
+ QFileInfo info(bin);
+ bool good = (info.exists() && info.isExecutable());
+ if(good){ bin = info.absoluteFilePath(); }
+ return good;
+}
+
+QStringList LUtils::systemApplicationDirs(){
+ //Returns a list of all the directories where *.desktop files can be found
+ QStringList appDirs = QString(getenv("XDG_DATA_HOME")).split(":");
+ appDirs << QString(getenv("XDG_DATA_DIRS")).split(":");
+ if(appDirs.isEmpty()){ appDirs << "/usr/local/share" << "/usr/share" << LOS::AppPrefix()+"/share" << LOS::SysPrefix()+"/share" << L_SHAREDIR; }
+ appDirs.removeDuplicates();
+ //Now create a valid list
+ QStringList out;
+ for(int i=0; i<appDirs.length(); i++){
+ if( QFile::exists(appDirs[i]+"/applications") ){
+ out << appDirs[i]+"/applications";
+ //Also check any subdirs within this directory
+ // (looking at you KDE - stick to the standards!!)
+ out << LUtils::listSubDirectories(appDirs[i]+"/applications");
+ }
+ }
+ //qDebug() << "System Application Dirs:" << out;
+ return out;
+}
+
+QString LUtils::GenerateOpenTerminalExec(QString term, QString dirpath){
+ //Check the input terminal application (default/fallback - determined by calling application)
+ //if(!LUtils::isValidBinary(term)){
+ if(term.endsWith(".desktop")){
+ //Pull the binary name out of the shortcut
+ XDGDesktop DF(term);
+ if(DF.type == XDGDesktop::BAD){ term = "xterm"; }
+ else{ term= DF.exec.section(" ",0,0); } //only take the binary name - not any other flags
+ }else{
+ term = "xterm"; //fallback
+ }
+ //}
+ //Now create the calling command for the designated terminal
+ // NOTE: While the "-e" routine is supposed to be universal, many terminals do not properly use it
+ // so add some special/known terminals here as necessary
+ QString exec;
+ qWarning() << " - Reached terminal initialization" << term;
+ if(term=="mate-terminal" || term=="lxterminal" || term=="gnome-terminal"){
+ exec = term+" --working-directory=\""+dirpath+"\"";
+ }else if(term=="xfce4-terminal"){
+ exec = term+" --default-working-directory=\""+dirpath+"\"";
+ }else if(term=="konsole" || term == "qterminal"){
+ exec = term+" --workdir \""+dirpath+"\"";
+ }else{
+ //-e is the parameter for most of the terminal appliction to execute an external command.
+ //In this case we start a shell in the selected directory
+ //Need the user's shell first
+ QString shell = QString(getenv("SHELL"));
+ if(!LUtils::isValidBinary(shell)){ shell = "/bin/sh"; } //universal fallback for a shell
+ exec = term + " -e \"cd " + dirpath + " && " + shell + " \" ";
+ }
+ qDebug() << exec;
+ return exec;
+}
+
+QStringList LUtils::listSubDirectories(QString dir, bool recursive){
+ //This is a recursive method for returning the full paths of all subdirectories (if recursive flag is enabled)
+ QDir maindir(dir);
+ QStringList out;
+ QStringList subs = maindir.entryList(QDir::NoDotAndDotDot | QDir::Dirs, QDir::Name);
+ for(int i=0; i<subs.length(); i++){
+ out << maindir.absoluteFilePath(subs[i]);
+ if(recursive){
+ out << LUtils::listSubDirectories(maindir.absoluteFilePath(subs[i]), recursive);
+ }
+ }
+ return out;
+}
+
+QString LUtils::PathToAbsolute(QString path){
+ //Convert an input path to an absolute path (this does not check existance ot anything)
+ if(path.startsWith("/")){ return path; } //already an absolute path
+ if(path.startsWith("~")){ path.replace(0,1,QDir::homePath()); }
+ if(!path.startsWith("/")){
+ //Must be a relative path
+ if(path.startsWith("./")){ path = path.remove(2); }
+ path.prepend( QDir::currentPath()+"/");
+ }
+ return path;
+}
+
+QString LUtils::AppToAbsolute(QString path){
+ if(path.startsWith("~/")){ path = path.replace("~/", QDir::homePath()+"/" ); }
+ if(path.startsWith("/") || QFile::exists(path)){ return path; }
+ if(path.endsWith(".desktop")){
+ //Look in the XDG dirs
+ QStringList dirs = systemApplicationDirs();
+ for(int i=0; i<dirs.length(); i++){
+ if(QFile::exists(dirs[i]+"/"+path)){ return (dirs[i]+"/"+path); }
+ }
+ }else{
+ //Look on $PATH for the binary
+ QStringList paths = QString(getenv("PATH")).split(":");
+ for(int i=0; i<paths.length(); i++){
+ if(QFile::exists(paths[i]+"/"+path)){ return (paths[i]+"/"+path); }
+ }
+ }
+ return path;
+}
+
+QStringList LUtils::imageExtensions(bool wildcards){
+ //Note that all the image extensions are lowercase!!
+ static QStringList imgExtensions;
+ if(imgExtensions.isEmpty()){
+ QList<QByteArray> fmt = QImageReader::supportedImageFormats();
+ for(int i=0; i<fmt.length(); i++){
+ if(wildcards){ imgExtensions << "*."+QString::fromLocal8Bit(fmt[i]); }
+ else{ imgExtensions << QString::fromLocal8Bit(fmt[i]); }
+ }
+ }
+ return imgExtensions;
+}
+
+ QTranslator* LUtils::LoadTranslation(QApplication *app, QString appname, QString locale, QTranslator *cTrans){
+ //Get the current localization
+ QString langEnc = "UTF-8"; //default value
+ QString langCode = locale; //provided locale
+ if(langCode.isEmpty()){ langCode = getenv("LC_ALL"); }
+ if(langCode.isEmpty()){ langCode = getenv("LANG"); }
+ if(langCode.isEmpty()){ langCode = "en_US.UTF-8"; } //default to US english
+ //See if the encoding is included and strip it out as necessary
+ if(langCode.contains(".")){
+ langEnc = langCode.section(".",-1);
+ langCode = langCode.section(".",0,0);
+ }
+ //Now verify the encoding for the locale
+ if(langCode =="C" || langCode=="POSIX" || langCode.isEmpty()){
+ langEnc = "System"; //use the Qt system encoding
+ }
+ if(app !=0){
+ qDebug() << "Loading Locale:" << appname << langCode << langEnc;
+ //If an existing translator was provided, remove it first (will be replaced)
+ if(cTrans!=0){ app->removeTranslator(cTrans); }
+ //Setup the translator
+ cTrans = new QTranslator();
+ //Use the shortened locale code if specific code does not have a corresponding file
+ if(!QFile::exists(LOS::LuminaShare()+"i18n/"+appname+"_" + langCode + ".qm") && langCode!="en_US" ){
+ langCode.truncate( langCode.indexOf("_") );
+ }
+ QString filename = appname+"_"+langCode+".qm";
+ //qDebug() << "FileName:" << filename << "Dir:" << LOS::LuminaShare()+"i18n/";
+ if( cTrans->load( filename, LOS::LuminaShare()+"i18n/" ) ){
+ app->installTranslator( cTrans );
+ }else{
+ //Translator could not be loaded for some reason
+ cTrans = 0;
+ if(langCode!="en_US"){
+ qWarning() << " - Could not load Locale:" << langCode;
+ }
+ }
+ }else{
+ //Only going to set the encoding since no application given
+ qDebug() << "Loading System Encoding:" << langEnc;
+ }
+ //Load current encoding for this locale
+ QTextCodec::setCodecForLocale( QTextCodec::codecForName(langEnc.toUtf8()) );
+ return cTrans;
+}
+
+QStringList LUtils::knownLocales(){
+ QDir i18n = QDir(LOS::LuminaShare()+"i18n");
+ if( !i18n.exists() ){ return QStringList(); }
+ QStringList files = i18n.entryList(QStringList() << "lumina-desktop_*.qm", QDir::Files, QDir::Name);
+ if(files.isEmpty()){ return QStringList(); }
+ //Now strip off the filename and just leave the locale tag
+ for(int i=0; i<files.length(); i++){
+ files[i].chop(3); //remove the ".qm" on the end
+ files[i] = files[i].section("_",1,50).simplified();
+ }
+ files << "en_US"; //default locale
+ files.sort();
+ return files;
+}
+
+void LUtils::setLocaleEnv(QString lang, QString msg, QString time, QString num,QString money,QString collate, QString ctype){
+ //Adjust the current locale environment variables
+ bool all = false;
+ if(msg.isEmpty() && time.isEmpty() && num.isEmpty() && money.isEmpty() && collate.isEmpty() && ctype.isEmpty() ){
+ if(lang.isEmpty()){ return; } //nothing to do - no changes requested
+ all = true; //set everything to the "lang" value
+ }
+ //If no lang given, but others are given, then use the current setting
+ if(lang.isEmpty()){ lang = getenv("LC_ALL"); }
+ if(lang.isEmpty()){ lang = getenv("LANG"); }
+ if(lang.isEmpty()){ lang = "en_US"; }
+ //Now go through and set/unset the environment variables
+ // - LANG & LC_ALL
+ if(!lang.contains(".")){ lang.append(".UTF-8"); }
+ setenv("LANG",lang.toUtf8() ,1); //overwrite setting (this is always required as the fallback)
+ if(all){ setenv("LC_ALL",lang.toUtf8() ,1); }
+ else{ unsetenv("LC_ALL"); } //make sure the custom settings are used
+ // - LC_MESSAGES
+ if(msg.isEmpty()){ unsetenv("LC_MESSAGES"); }
+ else{
+ if(!msg.contains(".")){ msg.append(".UTF-8"); }
+ setenv("LC_MESSAGES",msg.toUtf8(),1);
+ }
+ // - LC_TIME
+ if(time.isEmpty()){ unsetenv("LC_TIME"); }
+ else{
+ if(!time.contains(".")){ time.append(".UTF-8"); }
+ setenv("LC_TIME",time.toUtf8(),1);
+ }
+ // - LC_NUMERIC
+ if(num.isEmpty()){ unsetenv("LC_NUMERIC"); }
+ else{
+ if(!num.contains(".")){ num.append(".UTF-8"); }
+ setenv("LC_NUMERIC",num.toUtf8(),1);
+ }
+ // - LC_MONETARY
+ if(money.isEmpty()){ unsetenv("LC_MONETARY"); }
+ else{
+ if(!money.contains(".")){ money.append(".UTF-8"); }
+ setenv("LC_MONETARY",money.toUtf8(),1);
+ }
+ // - LC_COLLATE
+ if(collate.isEmpty()){ unsetenv("LC_COLLATE"); }
+ else{
+ if(!collate.contains(".")){ collate.append(".UTF-8"); }
+ setenv("LC_COLLATE",collate.toUtf8(),1);
+ }
+ // - LC_CTYPE
+ if(ctype.isEmpty()){ unsetenv("LC_CTYPE"); }
+ else{
+ if(!ctype.contains(".")){ ctype.append(".UTF-8"); }
+ setenv("LC_CTYPE",ctype.toUtf8(),1);
+ }
+}
+
+QString LUtils::currentLocale(){
+ QString curr = getenv("LC_ALL");// = QLocale::system();
+ if(curr.isEmpty()){ curr = getenv("LANG"); }
+ if(curr.isEmpty()){ curr = "en_US"; }
+ curr = curr.section(".",0,0); //remove any encodings off the end
+ return curr;
+}
+
+double LUtils::DisplaySizeToBytes(QString num){
+ //qDebug() << "Convert Num to Bytes:" << num;
+ num = num.toLower().simplified();
+ num = num.remove(" ");
+ if(num.isEmpty()){ return 0.0; }
+ if(num.endsWith("b")){ num.chop(1); } //remove the "bytes" marker (if there is one)
+ QString lab = "b";
+ if(!num[num.size()-1].isNumber()){
+ lab = num.right(1); num.chop(1);
+ }
+ double N = num.toDouble();
+ QStringList labs; labs <<"b"<<"k"<<"m"<<"g"<<"t"<<"p"; //go up to petabytes for now
+ for(int i=0; i<labs.length(); i++){
+ if(lab==labs[i]){ break; }//already at the right units - break out
+ N = N*1024.0; //Move to the next unit of measurement
+ }
+ //qDebug() << " - Done:" << QString::number(N) << lab << num;
+ return N;
+}
+
+QString LUtils::BytesToDisplaySize(qint64 ibytes){
+ static QStringList labs = QStringList();
+ if(labs.isEmpty()){ labs << "B" << "K" << "M" << "G" << "T" << "P"; }
+ //Now get the dominant unit
+ int c=0;
+ double bytes = ibytes; //need to keep decimel places for calculations
+ while(bytes>=1000 && c<labs.length() ){
+ bytes = bytes/1024;
+ c++;
+ } //labs[c] is the unit
+ //Bytes are now
+ //Now format the number (up to 3 digits, not including decimel places)
+ QString num;
+ if(bytes>=100){
+ //No decimel places
+ num = QString::number(qRound(bytes));
+ }else if(bytes>=10){
+ //need 1 decimel place
+ num = QString::number( (qRound(bytes*10)/10.0) );
+ }else if(bytes>=1){
+ //need 2 decimel places
+ num = QString::number( (qRound(bytes*100)/100.0) );
+ }else{
+ //Fully decimel (3 places)
+ num = "0."+QString::number(qRound(bytes*1000));
+ }
+ //qDebug() << "Bytes to Human-readable:" << bytes << c << num << labs[c];
+ return (num+labs[c]);
+}
+
+QString LUtils::SecondsToDisplay(int secs){
+ if(secs < 0){ return "??"; }
+ QString rem; //remaining
+ if(secs > 3600){
+ int hours = secs/3600;
+ rem.append( QString::number(hours)+"h ");
+ secs = secs - (hours*3600);
+ }
+ if(secs > 60){
+ int min = secs/60;
+ rem.append( QString::number(min)+"m ");
+ secs = secs - (min*60);
+ }
+ if(secs > 0){
+ rem.append( QString::number(secs)+"s");
+ }else{
+ rem.append( "0s" );
+ }
+ return rem;
+}
diff --git a/src-qt5/core/libLumina/LuminaUtils.h b/src-qt5/core/libLumina/LUtils.h
index e07363ca..459fca60 100644
--- a/src-qt5/core/libLumina/LuminaUtils.h
+++ b/src-qt5/core/libLumina/LUtils.h
@@ -1,6 +1,6 @@
//===========================================
// Lumina-DE source code
-// Copyright (c) 2012-2015, Ken Moore
+// Copyright (c) 2012-2016, Ken Moore
// Available under the 3-clause BSD license
// See the LICENSE file for full details
//===========================================
@@ -10,6 +10,7 @@
#include <QCoreApplication>
#include <QProcess>
#include <QTextStream>
+#include <QTextCodec>
#include <QFile>
#include <QDir>
#include <QString>
@@ -18,17 +19,15 @@
#include <QFileInfo>
#include <QObject>
#include <QTranslator>
-//#include <QApplication>
-#include <QMenu>
-#include <QMouseEvent>
-#include <QSize>
-#include <QWidgetAction>
+#include <QDebug>
+#include <QDesktopWidget>
+#include <QImageReader>
+#include <QRegExp>
+#include <QFuture>
+#include <QScreen>
class LUtils{
public:
- //Get the current version/build of the Lumina desktop
- static QString LuminaDesktopVersion();
- static QString LuminaDesktopBuildDate();
//Run an external command and return the exit code
static int runCmd(QString cmd, QStringList args = QStringList());
@@ -47,6 +46,9 @@ public:
return isValidBinary(bins); //overload for a "junk" binary variable input
}
+ //Return all the dirs on the system which contain .desktop files
+ static QStringList systemApplicationDirs();
+
//Create the exec string to open a terminal in a particular directory
static QString GenerateOpenTerminalExec(QString term, QString dirpath);
@@ -72,60 +74,5 @@ public:
static QString BytesToDisplaySize(qint64 bytes); //convert into a readable size (like 50M or 50KB)
static QString SecondsToDisplay(int secs); //convert into a readable time
-
- //Various function for finding valid QtQuick plugins on the system
- static bool validQuickPlugin(QString ID);
- static QString findQuickPluginFile(QString ID);
- static QStringList listQuickPlugins(); //List of valid ID's
- static QStringList infoQuickPlugin(QString ID); //Returns: [Name, Description, Icon]
-
- //Various functions for the favorites sub-system
- // Formatting Note: "<name>::::[dir/app/<mimetype>]::::<path>"
- // the <name> field might not be used for "app" flagged entries
- static QStringList listFavorites();
- static bool saveFavorites(QStringList);
- static bool isFavorite(QString path);
- static bool addFavorite(QString path, QString name = "");
- static void removeFavorite(QString path);
- static void upgradeFavorites(int fromoldversionnumber);
-
- //Load the default setup for the system
- static void LoadSystemDefaults(bool skipOS = false);
- static bool checkUserFiles(QString lastversion); //returns true if something changed
- static int VersionStringToNumber(QString version); //convert the lumina version string to a number for comparisons
-
-};
-
-//Special subclass for a menu which the user can grab the edges and resize as necessary
-// Note: Make sure that you don't set 0pixel contents margins on this menu
-// - it needs at least 1 pixel margins for the user to be able to grab it
-class ResizeMenu : public QMenu{
- Q_OBJECT
-public:
- ResizeMenu(QWidget *parent = 0);
- virtual ~ResizeMenu();
-
- void setContents(QWidget *con);
-
-private:
- enum SideFlag{NONE, TOP, BOTTOM, LEFT, RIGHT};
- SideFlag resizeSide;
- QWidget *contents;
- QWidgetAction *cAct;
-
-private slots:
- void clearFlags(){
- resizeSide=NONE;
- }
-
-protected:
- virtual void mouseMoveEvent(QMouseEvent *ev);
- virtual void mousePressEvent(QMouseEvent *ev);
- virtual void mouseReleaseEvent(QMouseEvent *ev);
-
-signals:
- void MenuResized(QSize); //Emitted when the menu is manually resized by the user
-
};
-
#endif
diff --git a/src-qt5/core/libLumina/LUtils.pri b/src-qt5/core/libLumina/LUtils.pri
new file mode 100644
index 00000000..d5941a41
--- /dev/null
+++ b/src-qt5/core/libLumina/LUtils.pri
@@ -0,0 +1,34 @@
+#since this is the most common of the include files - make sure it only gets added once
+!contains( HEADERS, $${PWD}/LUtils.h ){
+
+include("$${PWD}/../../OS-detect.pri")
+
+QT *= concurrent
+
+#Setup any special defines (qmake -> C++)
+GIT_VERSION=$$system(git describe --always)
+!isEmpty(GIT_VERSION){
+ DEFINES += GIT_VERSION='"\\\"$${GIT_VERSION}\\\""'
+}
+#Note: Saving the build date will break reproducible builds (time stamp always different)
+# Disable this by default, but leave it possible to re-enable this as needed by user
+#DEFINES += BUILD_DATE='"\\\"$$system(date)\\\""'
+
+#LuminaOS files
+HEADERS *= $${PWD}/LuminaOS.h
+# LuminaOS support functions (or fall back to generic one)
+exists($${PWD}/LuminaOS-$${LINUX_DISTRO}.cpp){
+ SOURCES *= $${PWD}/LuminaOS-$${LINUX_DISTRO}.cpp
+}else:exists($${PWD}/LuminaOS-$${OS}.cpp){
+ SOURCES *= $${PWD}/LuminaOS-$${OS}.cpp
+}else{
+ SOURCES *= $${PWD}/LuminaOS-template.cpp
+}
+
+#LUtils Files
+SOURCES *= $${PWD}/LUtils.cpp
+HEADERS *= $${PWD}/LUtils.h
+
+INCLUDEPATH *= ${PWD}
+
+}
diff --git a/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp b/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp
index 5cdf18bc..b9346565 100644
--- a/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp
+++ b/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp
@@ -97,13 +97,14 @@ void LOS::setScreenBrightness(int percent){
//Run the command(s)
bool success = false;
// - try hardware setting first (TrueOS || or intel_backlight)
- if( LUtils::isValidBinary("pc-sysconfig") ){
+ bool remoteSession = !QString(getenv("PICO_CLIENT_LOGIN")).isEmpty();
+ if( LUtils::isValidBinary("pc-sysconfig") && !remoteSession){
//Use TrueOS tool (direct sysctl control)
QString ret = LUtils::getCmdOutput("pc-sysconfig", QStringList() <<"setscreenbrightness "+QString::number(percent)).join("");
success = ret.toLower().contains("success");
qDebug() << "Set hardware brightness:" << percent << success;
}
- if( !success && LUtils::isValidBinary("intel_backlight")){
+ if( !success && LUtils::isValidBinary("intel_backlight") && !remoteSession){
//Use the intel_backlight utility (only for Intel mobo/hardware?)
if(0== LUtils::runCmd("intel_backlight", QStringList() <<QString::number(percent)) ){
//This utility does not report success/failure - run it again to get the current value and ensure it was set properly
@@ -131,11 +132,17 @@ int LOS::audioVolume(){ //Returns: audio volume as a percentage (0-100, with -1
QString info = LUtils::readFile(QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/.currentvolume").join("");
if(!info.isEmpty()){
out = info.simplified().toInt();
- audiovolume = out; //unset this internal flag
+ audiovolume = out; //reset this internal flag
return out;
}
}
-
+ bool remoteSession = !QString(getenv("PICO_CLIENT_LOGIN")).isEmpty();
+ if(remoteSession){
+ QStringList info = LUtils::getCmdOutput("pactl list short sinks");
+ qDebug() << "Got PA sinks:" << info;
+ out = 50; //TEMPORARY - still need to write up the info parsing
+ audiovolume = out;
+ }else{
//probe the system for the current volume (other utils could be changing it)
QString info = LUtils::getCmdOutput("mixer -S vol").join(":").simplified(); //ignores any other lines
if(!info.isEmpty()){
@@ -149,7 +156,7 @@ int LOS::audioVolume(){ //Returns: audio volume as a percentage (0-100, with -1
}
audiovolume = out;
}
-
+ }
return out;
}
@@ -157,35 +164,45 @@ int LOS::audioVolume(){ //Returns: audio volume as a percentage (0-100, with -1
void LOS::setAudioVolume(int percent){
if(percent<0){percent=0;}
else if(percent>100){percent=100;}
- QString info = LUtils::getCmdOutput("mixer -S vol").join(":").simplified(); //ignores any other lines
- if(!info.isEmpty()){
- int L = info.section(":",1,1).toInt();
- int R = info.section(":",2,2).toInt();
- int diff = L-R;
- if((percent == L) && (L==R)){ return; } //already set to that volume
- if(diff<0){ R=percent; L=percent+diff; } //R Greater
- else{ L=percent; R=percent-diff; } //L Greater or equal
- //Check bounds
- if(L<0){L=0;}else if(L>100){L=100;}
- if(R<0){R=0;}else if(R>100){R=100;}
- //Run Command
- audiovolume = percent; //save for checking later
- LUtils::runCmd("mixer vol "+QString::number(L)+":"+QString::number(R));
- LUtils::writeFile(QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/.currentvolume", QStringList() << QString::number(percent), true);
- }
+ bool remoteSession = !QString(getenv("PICO_CLIENT_LOGIN")).isEmpty();
+ if(remoteSession){
+ LUtils::runCmd(QString("pactl set-sink-volume @DEFAULT_SINK@ ")+QString::number(percent)+"%");
+ }else{
+ QString info = LUtils::getCmdOutput("mixer -S vol").join(":").simplified(); //ignores any other lines
+ if(!info.isEmpty()){
+ int L = info.section(":",1,1).toInt();
+ int R = info.section(":",2,2).toInt();
+ int diff = L-R;
+ if((percent == L) && (L==R)){ return; } //already set to that volume
+ if(diff<0){ R=percent; L=percent+diff; } //R Greater
+ else{ L=percent; R=percent-diff; } //L Greater or equal
+ //Check bounds
+ if(L<0){L=0;}else if(L>100){L=100;}
+ if(R<0){R=0;}else if(R>100){R=100;}
+ //Run Command
+ LUtils::runCmd("mixer vol "+QString::number(L)+":"+QString::number(R));
+ }
+ }
+ audiovolume = percent; //save for checking later
+ LUtils::writeFile(QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/.currentvolume", QStringList() << QString::number(percent), true);
}
//Change the current volume a set amount (+ or -)
void LOS::changeAudioVolume(int percentdiff){
- QString info = LUtils::getCmdOutput("mixer -S vol").join(":").simplified(); //ignores any other lines
- if(!info.isEmpty()){
- int L = info.section(":",1,1).toInt() + percentdiff;
- int R = info.section(":",2,2).toInt() + percentdiff;
- //Check bounds
- if(L<0){L=0;}else if(L>100){L=100;}
- if(R<0){R=0;}else if(R>100){R=100;}
- //Run Command
- LUtils::runCmd("mixer vol "+QString::number(L)+":"+QString::number(R));
+ bool remoteSession = !QString(getenv("PICO_CLIENT_LOGIN")).isEmpty();
+ if(remoteSession){
+ LUtils::runCmd(QString("pactl set-sink-volume @DEFAULT_SINK@ ")+((percentdiff>0)?"+" : "") + QString::number(percentdiff)+"%");
+ }else{
+ QString info = LUtils::getCmdOutput("mixer -S vol").join(":").simplified(); //ignores any other lines
+ if(!info.isEmpty()){
+ int L = info.section(":",1,1).toInt() + percentdiff;
+ int R = info.section(":",2,2).toInt() + percentdiff;
+ //Check bounds
+ if(L<0){L=0;}else if(L>100){L=100;}
+ if(R<0){R=0;}else if(R>100){R=100;}
+ //Run Command
+ LUtils::runCmd("mixer vol "+QString::number(L)+":"+QString::number(R));
+ }
}
}
@@ -292,8 +309,10 @@ QString LOS::FileSystemCapacity(QString dir) { //Return: percentage capacity as
QStringList LOS::CPUTemperatures(){ //Returns: List containing the temperature of any CPU's ("50C" for example)
static QStringList vars = QStringList();
QStringList temps;
- if(vars.isEmpty()){ temps = LUtils::getCmdOutput("sysctl -i hw.").filter(".temperature:"); }
- else{ temps = LUtils::getCmdOutput("sysctl "+vars.join(" ")); vars.clear(); }
+ if(vars.isEmpty()){
+ temps = LUtils::getCmdOutput("sysctl -i dev.cpu").filter(".temperature:"); //try direct readings first
+ if(temps.isEmpty()){ temps = LUtils::getCmdOutput("sysctl -i hw.acpi").filter(".temperature:"); } // then try acpi values
+ }else{ temps = LUtils::getCmdOutput("sysctl "+vars.join(" ")); vars.clear(); }
temps.sort();
for(int i=0; i<temps.length(); i++){
diff --git a/src-qt5/core/libLumina/LuminaOS.h b/src-qt5/core/libLumina/LuminaOS.h
index 50d6baec..96a587a8 100644
--- a/src-qt5/core/libLumina/LuminaOS.h
+++ b/src-qt5/core/libLumina/LuminaOS.h
@@ -1,6 +1,6 @@
//===========================================
// Lumina-DE source code
-// Copyright (c) 2014-15, Ken Moore
+// Copyright (c) 2014-16, Ken Moore
// Available under the 3-clause BSD license
// See the LICENSE file for full details
//===========================================
@@ -18,7 +18,7 @@
#include <QDir>
#include <QObject>
-#include "LuminaUtils.h"
+#include "LUtils.h"
class LOS{
public:
diff --git a/src-qt5/core/libLumina/LuminaRandR.cpp b/src-qt5/core/libLumina/LuminaRandR.cpp
new file mode 100644
index 00000000..eefc5aa8
--- /dev/null
+++ b/src-qt5/core/libLumina/LuminaRandR.cpp
@@ -0,0 +1 @@
+#include "LuminaRandR.h"
diff --git a/src-qt5/core/libLumina/LuminaRandR.h b/src-qt5/core/libLumina/LuminaRandR.h
new file mode 100644
index 00000000..3cdff651
--- /dev/null
+++ b/src-qt5/core/libLumina/LuminaRandR.h
@@ -0,0 +1,35 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2016, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+// This class governs all the xcb/randr interactions
+// and provides simpler Qt-based functions for use elsewhere
+//===========================================
+
+//Qt includes
+#include <QSize>
+
+#include "xcb/randr.h"
+
+class outputDevice{
+public:
+ QString id; //output ID
+ bool enabled;
+ //Monitor Geometry
+ QPoint geom; //geometry of monitor within session
+ //Monitor Resolution
+ QSize cRes; //current resolution of the monitor (could be different from geom.size() if panning is enabled)
+ QList<QSize> availRes; //available resolutions supported by the monitor
+ //Refresh Rate
+ int cHz; //current refresh rate
+ QList<int> availHz; //available refresh rates
+ //Expand this later to include:
+ // panning (current/possible)
+ // rotation (current/possible)
+
+ //FUNCTIONS
+
+ //Modification
+};
diff --git a/src-qt5/core/libLumina/LuminaSingleApplication.h b/src-qt5/core/libLumina/LuminaSingleApplication.h
index 725d8e40..bacf5640 100644
--- a/src-qt5/core/libLumina/LuminaSingleApplication.h
+++ b/src-qt5/core/libLumina/LuminaSingleApplication.h
@@ -25,7 +25,7 @@
#include <QLockFile>
#include <QApplication>
-#include <LuminaUtils.h>
+#include <LUtils.h>
//NOTE: This application type will automatically load the proper translation file(s)
// if the application name is set properly
diff --git a/src-qt5/core/libLumina/LuminaSingleApplication.pri b/src-qt5/core/libLumina/LuminaSingleApplication.pri
new file mode 100644
index 00000000..88ab7726
--- /dev/null
+++ b/src-qt5/core/libLumina/LuminaSingleApplication.pri
@@ -0,0 +1,12 @@
+include("$${PWD}/../../OS-detect.pri")
+
+QT *= network x11extras
+
+#LUtils Files
+SOURCES *= $${PWD}/LuminaSingleApplication.cpp
+HEADERS *= $${PWD}/LuminaSingleApplication.h
+
+INCLUDEPATH *= ${PWD}
+
+#include LUtils and LuminaOS
+include(LUtils.pri)
diff --git a/src-qt5/core/libLumina/LuminaThemes.cpp b/src-qt5/core/libLumina/LuminaThemes.cpp
index b6c18cf0..70cd221d 100644
--- a/src-qt5/core/libLumina/LuminaThemes.cpp
+++ b/src-qt5/core/libLumina/LuminaThemes.cpp
@@ -6,7 +6,7 @@
//===========================================
#include "LuminaThemes.h"
-#include "LuminaUtils.h"
+#include "LUtils.h"
#include "LuminaOS.h"
#include <QIcon>
#include <QFont>
@@ -15,6 +15,8 @@
#include <QPainter>
#include <QPen>
+#include "LuminaXDG.h"
+
#include <unistd.h>
//Stuff necesary for Qt Cursor Reloads
@@ -292,6 +294,8 @@ QStringList LTHEME::CustomEnvSettings(bool useronly){ //view all the key=value s
}
void LTHEME::LoadCustomEnvSettings(){
+ //Also ensure that the normal XDG_* environment variables are setup (will not overwrite them if already there)
+ LXDG::setEnvironmentVars();
//will push the custom settings into the environment (recommended before loading the initial QApplication)
QStringList info = LTHEME::CustomEnvSettings(false); //all settings
if(info.isEmpty()){
diff --git a/src-qt5/core/libLumina/LuminaThemes.pri b/src-qt5/core/libLumina/LuminaThemes.pri
new file mode 100644
index 00000000..0fe35b79
--- /dev/null
+++ b/src-qt5/core/libLumina/LuminaThemes.pri
@@ -0,0 +1,10 @@
+include("$${PWD}/../../OS-detect.pri")
+
+#LUtils Files
+SOURCES *= $${PWD}/LuminaThemes.cpp
+HEADERS *= $${PWD}/LuminaThemes.h
+
+INCLUDEPATH *= ${PWD}
+
+#include LUtils and LuminaOS
+include(LUtils.pri)
diff --git a/src-qt5/core/libLumina/LuminaX11.cpp b/src-qt5/core/libLumina/LuminaX11.cpp
index ecaa83d2..a8016460 100644
--- a/src-qt5/core/libLumina/LuminaX11.cpp
+++ b/src-qt5/core/libLumina/LuminaX11.cpp
@@ -1,6 +1,6 @@
//===========================================
// Lumina-DE source code
-// Copyright (c) 2014-2015, Ken Moore
+// Copyright (c) 2014-2016, Ken Moore
// Available under the 3-clause BSD license
// See the LICENSE file for full details
//===========================================
@@ -531,6 +531,49 @@ uint LXCB::GenerateDamageID(WId win){
return ( (uint) dmgID );
}
+// === paintRoot() ===
+void LXCB::paintRoot(QRect area, const QPixmap *pix){
+ //Generate a graphics context for this paint
+ xcb_gcontext_t gc = xcb_generate_id(QX11Info::connection());
+ xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(QX11Info::connection())).data;
+ uint32_t values[1];
+ values[0] = screen->black_pixel;
+
+ xcb_create_gc(QX11Info::connection(),
+ gc,
+ screen->root,
+ XCB_GC_BACKGROUND,
+ values );
+ //Convert the QPixmap to a xcb_drawable_t
+ QImage qimage = pix->toImage().convertToFormat(QImage::Format_ARGB32);
+ xcb_image_t *image = xcb_image_create(pix->width(), pix->height(), XCB_IMAGE_FORMAT_XY_PIXMAP,
+ 32, qimage.depth(), 32, 32, XCB_IMAGE_ORDER_LSB_FIRST, XCB_IMAGE_ORDER_LSB_FIRST,
+ 0, qimage.byteCount(), qimage.bits());
+
+
+ //Now paint on the root window
+ xcb_image_put(QX11Info::connection(),
+ screen->root, //where to put it
+ gc,
+ image,
+ area.x(),
+ area.y(),
+ 0);
+ /*xcb_copy_area(QX11Info::connection(),
+ //static_cast<xcb_drawable_t>( pix.handle() ) , //image to copy
+ *image,
+ screen->root, //where to put it
+ gc, //graphics context for destination
+ 0, //x origin of picture
+ 0, // y origin of picture
+ area.x(), //x origin of where to place it
+ area.y(), //y origin of where to place it
+ area.width(),
+ area.height() );*/
+ //Apply the change right now
+ xcb_flush(QX11Info::connection());
+ xcb_image_destroy(image);
+}
// === SetAsSticky() ===
void LXCB::SetAsSticky(WId win){
@@ -1081,6 +1124,7 @@ void LXCB::closeSystemTray(WId trayID){
xcb_destroy_window(QX11Info::connection(), trayID);
}
+
// === SetScreenWorkArea() ===
/*void LXCB::SetScreenWorkArea(unsigned int screen, QRect rect){
//This is only useful because Fluxbox does not set the _NET_WORKAREA root atom
diff --git a/src-qt5/core/libLumina/LuminaX11.h b/src-qt5/core/libLumina/LuminaX11.h
index b7310abd..2c741111 100644
--- a/src-qt5/core/libLumina/LuminaX11.h
+++ b/src-qt5/core/libLumina/LuminaX11.h
@@ -1,6 +1,6 @@
//===========================================
// Lumina-DE source code
-// Copyright (c) 2014-2015, Ken Moore
+// Copyright (c) 2014-2016, Ken Moore
// Available under the 3-clause BSD license
// See the LICENSE file for full details
//===========================================
@@ -133,6 +133,7 @@ public:
// - SubStructure simplifications (not commonly used)
void SelectInput(WId win, bool isEmbed = false); //XSelectInput replacement (to see window events)
uint GenerateDamageID(WId);
+ void paintRoot(QRect area, const QPixmap *pix);
// - General Window Modifications
void SetAsSticky(WId); //Stick to all workspaces
@@ -160,7 +161,6 @@ public:
WId startSystemTray(int screen = 0); //Startup the system tray (returns window ID for tray)
void closeSystemTray(WId); //Close the system tray
-
//============
// WM Functions (directly changing/reading properties)
// - Using these directly may prevent the WM from seeing the change
diff --git a/src-qt5/core/libLumina/LuminaX11.pri b/src-qt5/core/libLumina/LuminaX11.pri
new file mode 100644
index 00000000..0e472dd4
--- /dev/null
+++ b/src-qt5/core/libLumina/LuminaX11.pri
@@ -0,0 +1,13 @@
+
+QT *= x11extras
+
+LIBS *= -lc -lxcb -lxcb-ewmh -lxcb-icccm -lxcb-image -lxcb-composite -lxcb-damage -lxcb-util -lXdamage
+
+#LUtils Files
+SOURCES *= $${PWD}/LuminaX11.cpp
+HEADERS *= $${PWD}/LuminaX11.h
+
+INCLUDEPATH *= ${PWD}
+
+#include LUtils and LuminaOS
+include(LUtils.pri)
diff --git a/src-qt5/core/libLumina/LuminaXDG.cpp b/src-qt5/core/libLumina/LuminaXDG.cpp
index 48185a38..d6342269 100644
--- a/src-qt5/core/libLumina/LuminaXDG.cpp
+++ b/src-qt5/core/libLumina/LuminaXDG.cpp
@@ -6,7 +6,7 @@
//===========================================
#include "LuminaXDG.h"
#include "LuminaOS.h"
-#include "LuminaUtils.h"
+#include "LUtils.h"
#include <QObject>
#include <QTimer>
#include <QMediaPlayer>
@@ -15,11 +15,399 @@
static QStringList mimeglobs;
static qint64 mimechecktime;
+//=============================
+// XDGDesktop CLASS
+//=============================
+XDGDesktop::XDGDesktop(QString file, QObject *parent) : QObject(parent){
+ isHidden=false;
+ useTerminal=false;
+ startupNotify=false;
+ useVGL = false;
+ type = XDGDesktop::BAD;
+ filePath = file;
+ exec = tryexec = ""; // just to make sure this is initialized
+ if(!filePath.isEmpty()){ sync(); } //if an input file is given - go ahead and sync now
+}
+
+void XDGDesktop::sync(){
+ //Reset internal vars
+ isHidden=false;
+ useTerminal=false;
+ startupNotify=false;
+ type = XDGDesktop::BAD;
+ exec = tryexec = "";
+ //Read in the File
+ if(!filePath.endsWith(".desktop")){ return; }
+ lastRead = QDateTime::currentDateTime();
+ QStringList file = LUtils::readFile(filePath);
+ if(file.isEmpty()){ return; } //done with init right here - nothing to load
+ //Get the current localization code
+ type = XDGDesktop::APP; //assume this initially if we read the file properly
+ QString lang = QLocale::system().name(); //lang code
+ QString slang = lang.section("_",0,0); //short lang code
+ //Now start looping over the information
+ XDGDesktopAction CDA; //current desktop action
+ bool insection=false;
+ bool inaction=false;
+ for(int i=0; i<file.length(); i++){
+ QString line = file[i];
+ //if(filePath.contains("pcbsd")){ qDebug() << " - Check Line:" << line << inaction << insection; }
+ //Check if this is the end of a section
+ if(line.startsWith("[") && inaction){
+ insection=false; inaction=false;
+ //Add the current Action structure to the main desktop structure if appropriate
+ if(!CDA.ID.isEmpty()){ actions << CDA; CDA = XDGDesktopAction(); }
+ }else if(line.startsWith("[")){ insection=false; inaction = false; }
+ //Now check if this is the beginning of a section
+ if(line=="[Desktop Entry]"){ insection=true; continue; }
+ else if(line.startsWith("[Desktop Action ")){
+ //Grab the ID of the action out of the label
+ CDA.ID = line.section("]",0,0).section("Desktop Action",1,1).simplified();
+ inaction = true;
+ continue;
+ }else if( (!insection && !inaction) || line.startsWith("#")){ continue; }
+ //Now parse out the file
+ line = line.simplified();
+ QString var = line.section("=",0,0).simplified();
+ QString loc = var.section("[",1,1).section("]",0,0).simplified(); // localization
+ var = var.section("[",0,0).simplified(); //remove the localization
+ QString val = line.section("=",1,50).simplified();
+ //-------------------
+ if(var=="Name"){
+ if(insection){
+ if(name.isEmpty() && loc.isEmpty()){ name = val; }
+ else if(name.isEmpty() && loc==slang){ name = val; } //short locale code
+ else if(loc == lang){ name = val; }
+ }else if(inaction){
+ if(CDA.name.isEmpty() && loc.isEmpty()){ CDA.name = val; }
+ else if(CDA.name.isEmpty() && loc==slang){ CDA.name = val; } //short locale code
+ else if(loc == lang){ CDA.name = val; }
+ }
+ //hasName = true;
+ }else if(var=="GenericName" && insection){
+ if(genericName.isEmpty() && loc.isEmpty()){ genericName = val; }
+ else if(genericName.isEmpty() && loc==slang){ genericName = val; } //short locale code
+ else if(loc == lang){ genericName = val; }
+ }else if(var=="Comment" && insection){
+ if(comment.isEmpty() && loc.isEmpty()){ comment = val; }
+ else if(comment.isEmpty() && loc==slang){ comment = val; } //short locale code
+ else if(loc == lang){ comment = val; }
+ }else if(var=="Icon"){
+ if(insection){
+ if(icon.isEmpty() && loc.isEmpty()){ icon = val; }
+ else if(icon.isEmpty() && loc==slang){ icon = val; } //short locale code
+ else if(loc == lang){ icon = val; }
+ }else if(inaction){
+ if(CDA.icon.isEmpty() && loc.isEmpty()){ CDA.icon = val; }
+ else if(CDA.icon.isEmpty() && loc==slang){ CDA.icon = val; } //short locale code
+ else if(loc == lang){ CDA.icon = val; }
+ }
+ }
+ else if( (var=="TryExec") && (tryexec.isEmpty()) && insection) { tryexec = val; }
+ else if(var=="Exec"){
+ if(insection && exec.isEmpty() ){ exec = val; }
+ else if(inaction && CDA.exec.isEmpty() ){ CDA.exec = val; }
+ }
+ else if( (var=="Path") && (path.isEmpty() ) && insection){ path = val; }
+ else if(var=="NoDisplay" && !isHidden && insection){ isHidden = (val.toLower()=="true"); }
+ else if(var=="Hidden" && !isHidden && insection){ isHidden = (val.toLower()=="true"); }
+ else if(var=="Categories" && insection){ catList = val.split(";",QString::SkipEmptyParts); }
+ else if(var=="OnlyShowIn" && insection){ showInList = val.split(";",QString::SkipEmptyParts); }
+ else if(var=="NotShowIn" && insection){ notShowInList = val.split(";",QString::SkipEmptyParts); }
+ else if(var=="Terminal" && insection){ useTerminal= (val.toLower()=="true"); }
+ else if(var=="Actions" && insection){ actionList = val.split(";",QString::SkipEmptyParts); }
+ else if(var=="MimeType" && insection){ mimeList = val.split(";",QString::SkipEmptyParts); }
+ else if(var=="Keywords" && insection){
+ if(keyList.isEmpty() && loc.isEmpty()){ keyList = val.split(";",QString::SkipEmptyParts); }
+ else if(loc == lang){ keyList = val.split(";",QString::SkipEmptyParts); }
+ }
+ else if(var=="StartupNotify" && insection){ startupNotify = (val.toLower()=="true"); }
+ else if(var=="StartupWMClass" && insection){ startupWM = val; }
+ else if(var=="URL" && insection){ url = val;}
+ else if(var=="Type" && insection){
+ if(val.toLower()=="application"){ type = XDGDesktop::APP; }
+ else if(val.toLower()=="link"){ type = XDGDesktop::LINK; }
+ else if(val.toLower()=="dir"){ type = XDGDesktop::DIR; }
+ else{ type = XDGDesktop::BAD; } //Unknown type
+ //hasType = true;
+ }
+ } //end reading file
+ file.clear(); //done with contents of file
+ //If there are OnlyShowIn desktops listed, add them to the name
+ if( !showInList.isEmpty() && !showInList.contains("Lumina", Qt::CaseInsensitive) ){
+ name.append(" ("+showInList.join(", ")+")");
+ }
+ //Quick fix for showing "wine" applications (which quite often don't list a category, or have other differences)
+ if(catList.isEmpty() && filePath.contains("/wine/")){
+ catList << "Wine"; //Internal Lumina category only (not in XDG specs as of 11/14/14)
+ //Also add a fix for the location of Wine icons
+ if( !icon.isEmpty() ){
+ QStringList sizes; sizes << "256x256" << "128x128" << "64x64" << "48x48" << "32x32" << "16x16";
+ QString upath = QDir::homePath()+"/.local/share/icons/hicolor/%1/apps/%2.png";
+ //qDebug() << "Wine App: Check icon" << upath;
+ for(int i=0; i<sizes.length(); i++){
+ if( QFile::exists(upath.arg(sizes[i],icon)) ){
+ icon = upath.arg(sizes[i],icon);
+ //qDebug() << " - Found Icon:" << icon;
+ break;
+ }
+ }
+ }
+ }
+}
+
+
+bool XDGDesktop::isValid(bool showAll){
+ bool ok=true;
+ //bool DEBUG = false;
+ //if(DEBUG){ qDebug() << "[LXDG] Check File validity:" << dFile.name << dFile.filePath; }
+ switch (type){
+ case XDGDesktop::BAD:
+ ok=false;
+ //if(DEBUG){ qDebug() << " - Bad file type"; }
+ break;
+ case XDGDesktop::APP:
+ if(!tryexec.isEmpty() && !LXDG::checkExec(tryexec)){ ok=false; }//if(DEBUG){ qDebug() << " - tryexec does not exist";} }
+ else if(exec.isEmpty() || name.isEmpty()){ ok=false; }//if(DEBUG){ qDebug() << " - exec or name is empty";} }
+ else if(!LXDG::checkExec(exec.section(" ",0,0,QString::SectionSkipEmpty)) ){ ok=false; }//if(DEBUG){ qDebug() << " - first exec binary does not exist";} }
+ break;
+ case XDGDesktop::LINK:
+ ok = !url.isEmpty();
+ //if(DEBUG && !ok){ qDebug() << " - Link with missing URL"; }
+ break;
+ case XDGDesktop::DIR:
+ ok = !path.isEmpty();
+ //if(DEBUG && !ok){ qDebug() << " - Dir with missing path"; }
+ break;
+ default:
+ ok=false;
+ //if(DEBUG){ qDebug() << " - Unknown file type"; }
+ }
+ if(!showAll){
+ QString cdesk = getenv("XDG_CURRENT_DESKTOP");
+ if(cdesk.isEmpty()){ cdesk="Lumina"; }
+ if(!showInList.isEmpty()){ ok = showInList.contains(cdesk, Qt::CaseInsensitive); }
+ else if(!notShowInList.isEmpty()){ ok = !notShowInList.contains(cdesk,Qt::CaseInsensitive); }
+ else if(name.isEmpty()){ ok = false; }
+ }
+ return ok;
+}
+
+QString XDGDesktop::getDesktopExec(QString ActionID){
+ //Generate the executable line for the application
+ QString out = exec;
+ if( !ActionID.isEmpty() ){
+ //Go through and grab the proper exec for the listed action
+ for(int i=0; i<actions.length(); i++){
+ if(actions[i].ID == ActionID){
+ out = actions[i].exec;
+ break;
+ }
+ }
+ }
+
+ if(out.isEmpty()){ return ""; }
+ else if(useTerminal){
+ //Get the currently default terminal
+ QString term = LXDG::findDefaultAppForMime("application/terminal");
+ if(!QFile::exists(term)){ term = "xterm -lc"; }
+ else if(term.endsWith(".desktop")){
+ XDGDesktop DF(term);
+ if(DF.isValid()){ term = DF.getDesktopExec(); }
+ else{ term = "xterm -lc"; }
+ //DF.deleteLater(); //done with this struct
+ }else if( !LUtils::isValidBinary(term)){ term = "xterm -lc"; }
+ out = term+" -e "+out; //-e is a nearly-universal flag for terminal emulators
+ }
+ //Now perform any of the XDG flag substitutions as appropriate (9/2014 standards)
+ if(out.contains("%i") && !icon.isEmpty() ){ out.replace("%i", "--icon \'"+icon+"\'"); }
+ if(out.contains("%c")){
+ if(!name.isEmpty()){ out.replace("%c", "\'"+name+"\'"); }
+ else if(!genericName.isEmpty()){ out.replace("%c", "\'"+genericName+"\'"); }
+ else{ out.replace("%c", "\'"+filePath.section("/",-1).section(".desktop",0,0)+"\'"); }
+ }
+ if(out.contains("%k")){ out.replace("%k", "\'"+filePath+"\'"); }
+ return out;
+}
+
+bool XDGDesktop::saveDesktopFile(bool merge){
+ qDebug() << "Save Desktop File:" << filePath << "Merge:" << merge;
+ bool autofile = filePath.contains("/autostart/"); //use the "Hidden" field instead of the "NoDisplay"
+ int insertloc = -1;
+ QStringList info;
+ if(QFile::exists(filePath) && merge){
+ //Load the existing file and merge in in any changes
+ info = LUtils::readFile(filePath);
+ //set a couple flags based on the contents before we start iterating through
+ // - determine if a translated field was changed (need to remove all the now-invalid translations)
+ bool clearName, clearComment, clearGName;
+ QString tmp = "";
+ if(!info.filter("Name=").isEmpty()){ tmp = info.filter("Name=").first().section("=",1,50); }
+ clearName=(tmp!=name);
+ tmp.clear();
+ if(!info.filter("Comment=").isEmpty()){ tmp = info.filter("Comment=").first().section("=",1,50); }
+ clearComment=(tmp!=comment);
+ tmp.clear();
+ if(!info.filter("GenericName=").isEmpty()){ tmp = info.filter("GenericName=").first().section("=",1,50); }
+ clearGName=(tmp!=genericName);
+ //Now start iterating through the file and changing fields as necessary
+ bool insection = false;
+ for(int i=0; i<info.length(); i++){
+ if(info[i]=="[Desktop Entry]"){
+ insection = true;
+ continue;
+ }else if(info[i].startsWith("[")){
+ if(insection){ insertloc = i; } //save this location for later insertions
+ insection = false;
+ continue;
+ }
+ if(!insection || info[i].isEmpty() || info[i].section("#",0,0).simplified().isEmpty()){ continue; }
+ QString var = info[i].section("=",0,0);
+ QString val = info[i].section("=",1,50).simplified();
+ //NOTE: Clear the dFile variable as it is found/set in the file (to keep track of what has been used already)
+ // For boolian values, set them to false
+ // --LOCALIZED VALUES --
+ if(var.startsWith("Name")){
+ if(var.contains("[") && clearName){ info.removeAt(i); i--; continue;}
+ else if(!var.contains("[")){ info[i] = var+"="+name; name.clear(); }
+ }else if(var.startsWith("GenericName")){
+ if(var.contains("[") && clearGName){ info.removeAt(i); i--; continue;}
+ else if(!var.contains("[")){ info[i] = var+"="+genericName; genericName.clear(); }
+ }else if(var.startsWith("Comment")){
+ if(var.contains("[") && clearComment){ info.removeAt(i); i--; continue;}
+ else if(!var.contains("[")){ info[i] = var+"="+comment; comment.clear(); }
+
+ // --STRING/LIST VALUES--
+ }else if(var=="Exec"){ info[i] = var+"="+exec; exec.clear(); }
+ else if(var=="TryExec"){ info[i] = var+"="+tryexec; tryexec.clear(); }
+ else if(var=="Path"){ info[i] = var+"="+path; path.clear(); }
+ else if(var=="Icon"){ info[i] = var+"="+icon; icon.clear(); }
+ else if(var=="StartupWMClass"){ info[i] = var+"="+startupWM; startupWM.clear(); }
+ else if(var=="MimeType"){ info[i] = var+"="+mimeList.join(";"); mimeList.clear(); }
+ else if(var=="Categories"){ info[i] = var+"="+catList.join(";"); catList.clear(); }
+ else if(var=="Keywords"){ info[i] = var+"="+keyList.join(";"); keyList.clear(); }
+ else if(var=="Actions"){ info[i] = var+"="+actionList.join(";"); actionList.clear(); }
+ else if(var=="OnlyShowIn"){ info[i] = var+"="+showInList.join(";"); showInList.clear(); }
+ else if(var=="NotShowIn"){ info[i] = var+"="+notShowInList.join(";"); notShowInList.clear(); }
+ else if(var=="URL"){ info[i] = var+"="+url; url.clear(); }
+
+ // --BOOLIAN VALUES--
+ else if(var=="Hidden"){
+ if(!autofile){ info.removeAt(i); i--; continue; }
+ else{ info[i] = var+"="+(isHidden ? "true": "false"); isHidden=false;}
+ }else if(var=="NoDisplay"){
+ if(autofile){ info.removeAt(i); i--; continue; }
+ else{ info[i] = var+"="+(isHidden ? "true": "false"); isHidden=false;}
+ }else if(var=="Terminal"){
+ info[i] = var+"="+(useTerminal ? "true": "false"); useTerminal=false;
+ }else if(var=="StartupNotify"){
+ info[i] = var+"="+(startupNotify ? "true": "false"); startupNotify=false;
+ }
+ // Remove any lines that have been un-set or removed from the file
+ if(info[i].section("=",1,50).simplified().isEmpty()){ info.removeAt(i); i--; }
+ }
+
+ }else{
+ //Just write a new file and overwrite any old one
+ // (pre-set some values here which are always required)
+ info << "[Desktop Entry]";
+ info << "Version=1.0";
+ if(type==XDGDesktop::APP){ info << "Type=Application"; }
+ else if(type==XDGDesktop::LINK){ info << "Type=Link"; }
+ else if(type==XDGDesktop::DIR){ info << "Type=Dir"; }
+ }
+
+ if(insertloc<0){ insertloc = info.size(); }//put it at the end
+ //Now add in any items that did not exist in the original file
+ if( !exec.isEmpty() ){ info.insert(insertloc,"Exec="+exec); }
+ if( !tryexec.isEmpty() ){ info.insert(insertloc,"TryExec="+tryexec); }
+ if( !path.isEmpty() ){ info.insert(insertloc,"Path="+path); }
+ if( !icon.isEmpty() ){ info.insert(insertloc,"Icon="+icon); }
+ if( !name.isEmpty() ){ info.insert(insertloc,"Name="+name); }
+ if( !genericName.isEmpty() ){ info.insert(insertloc,"GenericName="+genericName); }
+ if( !comment.isEmpty() ){ info.insert(insertloc,"Comment="+comment); }
+ if( !startupWM.isEmpty() ){ info.insert(insertloc,"StartupWMClass="+startupWM); }
+ if( !mimeList.isEmpty() ){ info.insert(insertloc,"MimeType="+mimeList.join(";")); }
+ if( !catList.isEmpty() ){ info.insert(insertloc,"Categories="+catList.join(";")); }
+ if( !keyList.isEmpty() ){ info.insert(insertloc,"Keywords="+keyList.join(";")); }
+ if( !actionList.isEmpty() ){ info.insert(insertloc,"Actions="+actionList.join(";")); }
+ if( !showInList.isEmpty() ){ info.insert(insertloc,"OnlyShowIn="+showInList.join(";")); }
+ else if( !notShowInList.isEmpty() ){ info.insert(insertloc,"NotShowIn="+notShowInList.join(";")); }
+ if( !url.isEmpty() ){ info.insert(insertloc,"URL="+url); }
+ if( isHidden && autofile ){ info.insert(insertloc,"Hidden=true"); }
+ else if(isHidden){ info.insert(insertloc,"NoDisplay=true"); }
+ if( useTerminal){ info.insert(insertloc,"Terminal=true"); }
+ if( startupNotify ){ info.insert(insertloc,"StartupNotify=true"); }
+
+ //Now save the file
+ return LUtils::writeFile(filePath, info, true);
+}
+
+bool XDGDesktop::setAutoStarted(bool autostart){
+ //First get the list of system directories to search (system first, user-provided files come later and overwrite sys files as needed)
+ QStringList paths = QString(getenv("XDG_CONFIG_DIRS")).split(":");
+ QString upath = QString(getenv("XDG_CONFIG_HOME")).section(":",0,0);
+ if(upath.isEmpty()){ upath = QDir::homePath()+"/.config/autostart/"; }
+ else{ upath.append("/autostart/"); }
+ //Verify that the autostart directory exists
+ if(!QFile::exists(upath)){
+ QDir dir;
+ dir.mkpath(upath);
+ }
+
+ //Quick check/finish for user-defined files which are getting disabled (just remove the file)
+ if(filePath.startsWith(upath) && !autostart){
+ return QFile::remove(filePath);
+ }
+ bool sysfile = false;
+ for(int i=0; i<paths.length(); i++){
+ if(filePath.startsWith(paths[i]+"/autostart/") ){
+ sysfile = true;
+ //Change it to the user-modifiable directory
+ filePath = filePath.replace(paths[i]+"/autostart/", upath);
+ }
+ }
+ //Make sure the user-autostart dir is specified, and clean the app structure as necessary
+ if( !filePath.startsWith(upath) && autostart){
+ //Some other non-override autostart file - set it up to open with lumina-open
+ if(!filePath.endsWith(".desktop")){
+ exec = "lumina-open \""+filePath+"\"";
+ tryexec = filePath; //make sure this file exists
+ if(name.isEmpty()){ name = filePath.section("/",-1); }
+ if(icon.isEmpty()){ icon = LXDG::findAppMimeForFile(filePath); icon.replace("/","-"); }
+ filePath = upath+filePath.section("/",-1)+".desktop";
+ type = XDGDesktop::APP;
+ }else{
+ //Some other *.desktop file on the system (keep almost all the existing settings/values)
+ // - setup a redirect to the other file
+ exec = "lumina-open \""+filePath+"\"";
+ tryexec = filePath; //make sure this file exists
+ // - Adjust the actual path where this file will get saved
+ filePath = upath+filePath.section("/",-1);
+ }
+ }
+ //Now save the "hidden" value into the file
+ isHidden = !autostart; //if hidden, it will not be autostarted
+ //Now save the file as necessary
+ bool saved = false;
+ //qDebug() << " - Saving AutoStart File:" << filePath << name << isHidden;
+ if(sysfile){
+ //Just an override file for the "hidden" field - nothing more
+ QStringList info;
+ info << "[Desktop Entry]" << "Type=Application" << QString("Hidden=")+ (isHidden ? QString("true"): QString("false"));
+ saved = LUtils::writeFile(filePath, info, true);
+ }else{
+ //Need to actually save the full file
+ saved = saveDesktopFile();
+ }
+ return saved;
+}
+
//====XDGDesktopList Functions ====
XDGDesktopList::XDGDesktopList(QObject *parent, bool watchdirs) : QObject(parent){
- synctimer = new QTimer(this);
- synctimer->setInterval(60000); //1 minute intervals. since the polling/update only takes a few ms, this is completely reasonable
+ synctimer = new QTimer(this); //interval set automatically based on changes/interactions
connect(synctimer, SIGNAL(timeout()), this, SLOT(updateList()) );
+ keepsynced = watchdirs;
if(watchdirs){
watcher = new QFileSystemWatcher(this);
connect(watcher, SIGNAL(fileChanged(const QString&)), this, SLOT(watcherChanged()) );
@@ -34,7 +422,9 @@ XDGDesktopList::~XDGDesktopList(){
}
void XDGDesktopList::watcherChanged(){
- QTimer::singleShot(1000, this, SLOT(updateList()) ); //1 second delay before check kicks off
+ if(synctimer->isActive()){ synctimer->stop(); }
+ synctimer->setInterval(1000); //1 second delay before check kicks off
+ synctimer->start();
}
void XDGDesktopList::updateList(){
@@ -47,53 +437,62 @@ void XDGDesktopList::updateList(){
bool firstrun = lastCheck.isNull() || oldkeys.isEmpty();
lastCheck = QDateTime::currentDateTime();
//Variables for internal loop use only (to prevent re-initializing variable on every iteration)
- bool ok; QString path; QDir dir; QStringList apps; XDGDesktop dFile;
+ bool ok; QString path; QDir dir; QStringList apps;
for(int i=0; i<appDirs.length(); i++){
if( !dir.cd(appDirs[i]) ){ continue; } //could not open dir for some reason
apps = dir.entryList(QStringList() << "*.desktop",QDir::Files, QDir::Name);
for(int a=0; a<apps.length(); a++){
path = dir.absoluteFilePath(apps[a]);
- if(files.contains(path) && (files.value(path).lastRead>QFileInfo(path).lastModified()) ){
+ if(files.contains(path) && (files.value(path)->lastRead>QFileInfo(path).lastModified()) ){
//Re-use previous data for this file (nothing changed)
- dFile = files[path];
+ found << files[path]->name; //keep track of which files were already found
ok=true;
}else{
ok=false;
- dFile = LXDG::loadDesktopFile(path,ok); //will change the "ok" variable as needed
- appschanged = true; //flag that something changed - needed to load a file
- }
- if(ok && !found.contains(dFile.name)){
- if(!oldkeys.contains(path)){ newfiles << path; } //brand new file (not an update to a previously-read file)
- files.insert(path, dFile);
- found << dFile.name;
- oldkeys.removeAll(path); //make sure this key does not get cleaned up later
+ if(files.contains(path)){ appschanged = true; files.take(path)->deleteLater(); } //files.remove(path); }
+ XDGDesktop *dFile = new XDGDesktop(path, this); //will change the "ok" variable as needed
+ if(dFile->type!=XDGDesktop::BAD){
+ appschanged = true; //flag that something changed - needed to load a file
+ if(!oldkeys.contains(path)){ newfiles << path; } //brand new file (not an update to a previously-read file)
+ files.insert(path, dFile);
+ found << dFile->name;
+ }else{
+ dFile->deleteLater(); //bad file - discard it
+ }
}
+ oldkeys.removeAll(path); //make sure this key does not get cleaned up later
} //end loop over apps
} //end loop over appDirs
//Save the extra info to the internal lists
- if(!firstrun){ removedApps = oldkeys; }//files which were removed
- if(!firstrun){ newApps = newfiles; }//files which were added
+ if(!firstrun){
+ removedApps = oldkeys;//files which were removed
+ newApps = newfiles; //files which were added
+ }
//Now go through and cleanup any old keys where the associated file does not exist anymore
for(int i=0; i<oldkeys.length(); i++){
- files.remove(oldkeys[i]);
+ //qDebug() << "Removing file from internal map:" << oldkeys[i];
+ if(i==0){ appschanged = true; }
+ //files.remove(oldkeys[i]);
+ files.take(oldkeys[i])->deleteLater();
}
//If this class is automatically managing the lists, update the watched files/dirs and send out notifications
if(watcher!=0){
- //qDebug() << "App List Updated:" << lastCheck << appschanged << newfiles << oldkeys;
+ if(appschanged){ qDebug() << "Auto App List Update:" << lastCheck << "Files Found:" << files.count(); }
watcher->removePaths(QStringList() << watcher->files() << watcher->directories());
watcher->addPaths(appDirs);
if(appschanged){ emit appsUpdated(); }
+ synctimer->setInterval(60000); //Update in 1 minute if nothing changes before then
+ synctimer->start();
}
- synctimer->start();
}
-QList<XDGDesktop> XDGDesktopList::apps(bool showAll, bool showHidden){
+QList<XDGDesktop*> XDGDesktopList::apps(bool showAll, bool showHidden){
//showAll: include invalid files, showHidden: include NoShow/Hidden files
QStringList keys = files.keys();
- QList<XDGDesktop> out;
+ QList<XDGDesktop*> out;
for(int i=0; i<keys.length(); i++){
- if( LXDG::checkValidity(files[keys[i]], showAll) ){
- if( showHidden || !files[keys[i]].isHidden ){
+ if( showHidden || !files[keys[i]]->isHidden ){ //this is faster than the "checkValidity()" function below - so always filter here first
+ if( files[keys[i]]->isValid(showAll) ){
out << files[keys[i]];
}
}
@@ -104,6 +503,7 @@ QList<XDGDesktop> XDGDesktopList::apps(bool showAll, bool showHidden){
//==== LFileInfo Functions ====
//Need some extra information not usually available by a QFileInfo
void LFileInfo::loadExtraInfo(){
+ desk = 0;
//Now load the extra information
if(this->isDir()){
mime = "inode/directory";
@@ -122,17 +522,19 @@ void LFileInfo::loadExtraInfo(){
}else if( this->suffix()=="desktop"){
mime = "application/x-desktop";
icon = "application-x-desktop"; //default value
- bool ok = false;
- desk = LXDG::loadDesktopFile(this->absoluteFilePath(), ok);
- if(ok){
+ desk = new XDGDesktop(this->absoluteFilePath(), 0);
+ if(desk->type!=XDGDesktop::BAD){
//use the specific desktop file info (if possible)
- if(!desk.icon.isEmpty()){ icon = desk.icon; }
+ if(!desk->icon.isEmpty()){ icon = desk->icon; }
}
}else{
//Generic file, just determine the mimetype
mime = LXDG::findAppMimeForFile(this->fileName());
}
}
+LFileInfo::LFileInfo(){
+ desk = 0;
+}
LFileInfo::LFileInfo(QString filepath){ //overloaded contructor
this->setFile(filepath);
loadExtraInfo();
@@ -167,12 +569,13 @@ QString LFileInfo::iconfile(){
// -- Check if this is an XDG desktop file
bool LFileInfo::isDesktopFile(){
- return (!desk.filePath.isEmpty());
+ if(desk==0){ return false; }
+ return (!desk->filePath.isEmpty());
}
// -- Allow access to the XDG desktop data structure
XDGDesktop* LFileInfo::XDG(){
- return &desk;
+ return desk;
}
// -- Check if this is a readable image file (for thumbnail support)
@@ -188,296 +591,6 @@ bool LFileInfo::isAVFile(){
//==== LXDG Functions ====
-XDGDesktop LXDG::loadDesktopFile(QString filePath, bool& ok){
- //Create the outputs
- ok=false;
- XDGDesktop DF;
- DF.isHidden=false;
- DF.useTerminal=false;
- DF.startupNotify=false;
- DF.type = XDGDesktop::APP;
- DF.filePath = filePath;
- DF.lastRead = QDateTime::currentDateTime();
- DF.exec = DF.tryexec = ""; // just to make sure this is initialized
-
- //Get the current localization code
- QString lang = QLocale::system().name(); //lang code
- QString slang = lang.section("_",0,0); //short lang code
-
- //Read in the File
- bool insection=false;
- bool inaction=false;
- QStringList file = LUtils::readFile(filePath);
- if(file.isEmpty()){ return DF; }
- //if(filePath.contains("pcbsd")){ qDebug() << "Check File:" << filePath << lang << slang; }
- XDGDesktopAction CDA; //current desktop action
- for(int i=0; i<file.length(); i++){
- QString line = file[i];
- //if(filePath.contains("pcbsd")){ qDebug() << " - Check Line:" << line << inaction << insection; }
- //Check if this is the end of a section
- if(line.startsWith("[") && inaction){
- insection=false; inaction=false;
- //Add the current Action structure to the main desktop structure if appropriate
- if(!CDA.ID.isEmpty()){ DF.actions << CDA; CDA = XDGDesktopAction(); }
- }else if(line.startsWith("[")){ insection=false; inaction = false; }
- //Now check if this is the beginning of a section
- if(line=="[Desktop Entry]"){ insection=true; continue; }
- else if(line.startsWith("[Desktop Action ")){
- //Grab the ID of the action out of the label
- CDA.ID = line.section("]",0,0).section("Desktop Action",1,1).simplified();
- inaction = true;
- continue;
- }else if( (!insection && !inaction) || line.startsWith("#")){ continue; }
- //Now parse out the file
- line = line.simplified();
- QString var = line.section("=",0,0).simplified();
- QString loc = var.section("[",1,1).section("]",0,0).simplified(); // localization
- var = var.section("[",0,0).simplified(); //remove the localization
- QString val = line.section("=",1,50).simplified();
- //if(filePath.contains("pcbsd")){ qDebug() << " -- " << var << val << loc; }
- //-------------------
- if(var=="Name"){
- if(insection){
- if(DF.name.isEmpty() && loc.isEmpty()){ DF.name = val; }
- else if(DF.name.isEmpty() && loc==slang){ DF.name = val; } //short locale code
- else if(loc == lang){ DF.name = val; }
- }else if(inaction){
- if(CDA.name.isEmpty() && loc.isEmpty()){ CDA.name = val; }
- else if(CDA.name.isEmpty() && loc==slang){ CDA.name = val; } //short locale code
- else if(loc == lang){ CDA.name = val; }
- }
- //hasName = true;
- }else if(var=="GenericName" && insection){
- if(DF.genericName.isEmpty() && loc.isEmpty()){ DF.genericName = val; }
- else if(DF.genericName.isEmpty() && loc==slang){ DF.genericName = val; } //short locale code
- else if(loc == lang){ DF.genericName = val; }
- }else if(var=="Comment" && insection){
- if(DF.comment.isEmpty() && loc.isEmpty()){ DF.comment = val; }
- else if(DF.comment.isEmpty() && loc==slang){ DF.comment = val; } //short locale code
- else if(loc == lang){ DF.comment = val; }
- }else if(var=="Icon"){
- if(insection){
- if(DF.icon.isEmpty() && loc.isEmpty()){ DF.icon = val; }
- else if(DF.icon.isEmpty() && loc==slang){ DF.icon = val; } //short locale code
- else if(loc == lang){ DF.icon = val; }
- }else if(inaction){
- if(CDA.icon.isEmpty() && loc.isEmpty()){ CDA.icon = val; }
- else if(CDA.icon.isEmpty() && loc==slang){ CDA.icon = val; } //short locale code
- else if(loc == lang){ CDA.icon = val; }
- }
- }
- else if( (var=="TryExec") && (DF.tryexec.isEmpty()) && insection) { DF.tryexec = val; }
- else if(var=="Exec"){
- if(insection && DF.exec.isEmpty() ){ DF.exec = val; }
- else if(inaction && CDA.exec.isEmpty() ){ CDA.exec = val; }
- }
- else if( (var=="Path") && (DF.path.isEmpty() ) && insection){ DF.path = val; }
- else if(var=="NoDisplay" && !DF.isHidden && insection){ DF.isHidden = (val.toLower()=="true"); }
- else if(var=="Hidden" && !DF.isHidden && insection){ DF.isHidden = (val.toLower()=="true"); }
- else if(var=="Categories" && insection){ DF.catList = val.split(";",QString::SkipEmptyParts); }
- else if(var=="OnlyShowIn" && insection){ DF.showInList = val.split(";",QString::SkipEmptyParts); }
- else if(var=="NotShowIn" && insection){ DF.notShowInList = val.split(";",QString::SkipEmptyParts); }
- else if(var=="Terminal" && insection){ DF.useTerminal= (val.toLower()=="true"); }
- else if(var=="Actions" && insection){ DF.actionList = val.split(";",QString::SkipEmptyParts); }
- else if(var=="MimeType" && insection){ DF.mimeList = val.split(";",QString::SkipEmptyParts); }
- else if(var=="Keywords" && insection){
- if(DF.keyList.isEmpty() && loc.isEmpty()){ DF.keyList = val.split(";",QString::SkipEmptyParts); }
- else if(loc == lang){ DF.keyList = val.split(";",QString::SkipEmptyParts); }
- }
- else if(var=="StartupNotify" && insection){ DF.startupNotify = (val.toLower()=="true"); }
- else if(var=="StartupWMClass" && insection){ DF.startupWM = val; }
- else if(var=="URL" && insection){ DF.url = val;}
- else if(var=="Type" && insection){
- if(val.toLower()=="application"){ DF.type = XDGDesktop::APP; }
- else if(val.toLower()=="link"){ DF.type = XDGDesktop::LINK; }
- else if(val.toLower()=="dir"){ DF.type = XDGDesktop::DIR; }
- else{ DF.type = XDGDesktop::BAD; } //Unknown type
- //hasType = true;
- }
- } //end reading file
- //file.close();
- //If there are OnlyShowIn desktops listed, add them to the name
- if( !DF.showInList.isEmpty() && !DF.showInList.contains("Lumina", Qt::CaseInsensitive) ){
- /*QStringList added;
- //Need to be careful about case insensitivity here - the QList functions don't understand it
- for(int i=0; i<DF.showInList.length(); i++){
- if(DF.showInList[i].toLower()!="lumina"){ added << DF.showInList[i]; }
- }*/
- //if(!added.isEmpty()){
- DF.name.append(" ("+DF.showInList.join(", ")+")");
- //}
- }
- //Quick fix for showing "wine" applications (which quite often don't list a category, or have other differences)
- if(DF.catList.isEmpty() && filePath.contains("/wine/")){
- DF.catList << "Wine"; //Internal Lumina category only (not in XDG specs as of 11/14/14)
- //Also add a fix for the location of Wine icons
- if( !DF.icon.isEmpty() ){
- QStringList sizes; sizes << "256x256" << "128x128" << "64x64" << "48x48" << "32x32" << "16x16";
- QString upath = QDir::homePath()+"/.local/share/icons/hicolor/%1/apps/%2.png";
- //qDebug() << "Wine App: Check icon" << upath;
- for(int i=0; i<sizes.length(); i++){
- if( QFile::exists(upath.arg(sizes[i],DF.icon)) ){
- DF.icon = upath.arg(sizes[i],DF.icon);
- //qDebug() << " - Found Icon:" << DF.icon;
- break;
- }
- }
- }
- }
- //Return the structure
- //if (hasName && hasType) ok = true; //without Name and Type, the structure cannot be a valid .desktop file
- ok = true; //was able to open/read the file - validity determined later
- return DF;
-}
-
-bool LXDG::saveDesktopFile(XDGDesktop dFile, bool merge){
- qDebug() << "Save Desktop File:" << dFile.filePath << "Merge:" << merge;
- bool autofile = dFile.filePath.contains("/autostart/"); //use the "Hidden" field instead of the "NoDisplay"
- int insertloc = -1;
- QStringList info;
- if(QFile::exists(dFile.filePath) && merge){
- //Load the existing file and merge in in any changes
- info = LUtils::readFile(dFile.filePath);
- //set a couple flags based on the contents before we start iterating through
- // - determine if a translated field was changed (need to remove all the now-invalid translations)
- bool clearName, clearComment, clearGName;
- QString tmp = "";
- if(!info.filter("Name=").isEmpty()){ tmp = info.filter("Name=").first().section("=",1,50); }
- clearName=(tmp!=dFile.name);
- tmp.clear();
- if(!info.filter("Comment=").isEmpty()){ tmp = info.filter("Comment=").first().section("=",1,50); }
- clearComment=(tmp!=dFile.comment);
- tmp.clear();
- if(!info.filter("GenericName=").isEmpty()){ tmp = info.filter("GenericName=").first().section("=",1,50); }
- clearGName=(tmp!=dFile.genericName);
- //Now start iterating through the file and changing fields as necessary
- bool insection = false;
- for(int i=0; i<info.length(); i++){
- if(info[i]=="[Desktop Entry]"){
- insection = true;
- continue;
- }else if(info[i].startsWith("[")){
- if(insection){ insertloc = i; } //save this location for later insertions
- insection = false;
- continue;
- }
- if(!insection || info[i].isEmpty() || info[i].section("#",0,0).simplified().isEmpty()){ continue; }
- QString var = info[i].section("=",0,0);
- QString val = info[i].section("=",1,50).simplified();
- //NOTE: Clear the dFile variable as it is found/set in the file (to keep track of what has been used already)
- // For boolian values, set them to false
- // --LOCALIZED VALUES --
- if(var.startsWith("Name")){
- if(var.contains("[") && clearName){ info.removeAt(i); i--; continue;}
- else if(!var.contains("[")){ info[i] = var+"="+dFile.name; dFile.name.clear(); }
- }else if(var.startsWith("GenericName")){
- if(var.contains("[") && clearGName){ info.removeAt(i); i--; continue;}
- else if(!var.contains("[")){ info[i] = var+"="+dFile.genericName; dFile.genericName.clear(); }
- }else if(var.startsWith("Comment")){
- if(var.contains("[") && clearComment){ info.removeAt(i); i--; continue;}
- else if(!var.contains("[")){ info[i] = var+"="+dFile.comment; dFile.comment.clear(); }
-
- // --STRING/LIST VALUES--
- }else if(var=="Exec"){ info[i] = var+"="+dFile.exec; dFile.exec.clear(); }
- else if(var=="TryExec"){ info[i] = var+"="+dFile.tryexec; dFile.tryexec.clear(); }
- else if(var=="Path"){ info[i] = var+"="+dFile.path; dFile.path.clear(); }
- else if(var=="Icon"){ info[i] = var+"="+dFile.icon; dFile.icon.clear(); }
- else if(var=="StartupWMClass"){ info[i] = var+"="+dFile.startupWM; dFile.startupWM.clear(); }
- else if(var=="MimeType"){ info[i] = var+"="+dFile.mimeList.join(";"); dFile.mimeList.clear(); }
- else if(var=="Categories"){ info[i] = var+"="+dFile.catList.join(";"); dFile.catList.clear(); }
- else if(var=="Keywords"){ info[i] = var+"="+dFile.keyList.join(";"); dFile.keyList.clear(); }
- else if(var=="Actions"){ info[i] = var+"="+dFile.actionList.join(";"); dFile.actionList.clear(); }
- else if(var=="OnlyShowIn"){ info[i] = var+"="+dFile.showInList.join(";"); dFile.showInList.clear(); }
- else if(var=="NotShowIn"){ info[i] = var+"="+dFile.notShowInList.join(";"); dFile.notShowInList.clear(); }
- else if(var=="URL"){ info[i] = var+"="+dFile.url; dFile.url.clear(); }
-
- // --BOOLIAN VALUES--
- else if(var=="Hidden"){
- if(!autofile){ info.removeAt(i); i--; continue; }
- else{ info[i] = var+"="+(dFile.isHidden ? "true": "false"); dFile.isHidden=false;}
- }else if(var=="NoDisplay"){
- if(autofile){ info.removeAt(i); i--; continue; }
- else{ info[i] = var+"="+(dFile.isHidden ? "true": "false"); dFile.isHidden=false;}
- }else if(var=="Terminal"){
- info[i] = var+"="+(dFile.useTerminal ? "true": "false"); dFile.useTerminal=false;
- }else if(var=="StartupNotify"){
- info[i] = var+"="+(dFile.startupNotify ? "true": "false"); dFile.startupNotify=false;
- }
- // Remove any lines that have been un-set or removed from the file
- if(info[i].section("=",1,50).simplified().isEmpty()){ info.removeAt(i); i--; }
- }
-
- }else{
- //Just write a new file and overwrite any old one
- // (pre-set some values here which are always required)
- info << "[Desktop Entry]";
- info << "Version=1.0";
- if(dFile.type==XDGDesktop::APP){ info << "Type=Application"; }
- else if(dFile.type==XDGDesktop::LINK){ info << "Type=Link"; }
- else if(dFile.type==XDGDesktop::DIR){ info << "Type=Dir"; }
- }
-
- if(insertloc<0){ insertloc = info.size(); }//put it at the end
- //Now add in any items that did not exist in the original file
- if( !dFile.exec.isEmpty() ){ info.insert(insertloc,"Exec="+dFile.exec); }
- if( !dFile.tryexec.isEmpty() ){ info.insert(insertloc,"TryExec="+dFile.tryexec); }
- if( !dFile.path.isEmpty() ){ info.insert(insertloc,"Path="+dFile.path); }
- if( !dFile.icon.isEmpty() ){ info.insert(insertloc,"Icon="+dFile.icon); }
- if( !dFile.name.isEmpty() ){ info.insert(insertloc,"Name="+dFile.name); }
- if( !dFile.genericName.isEmpty() ){ info.insert(insertloc,"GenericName="+dFile.genericName); }
- if( !dFile.comment.isEmpty() ){ info.insert(insertloc,"Comment="+dFile.comment); }
- if( !dFile.startupWM.isEmpty() ){ info.insert(insertloc,"StartupWMClass="+dFile.startupWM); }
- if( !dFile.mimeList.isEmpty() ){ info.insert(insertloc,"MimeType="+dFile.mimeList.join(";")); }
- if( !dFile.catList.isEmpty() ){ info.insert(insertloc,"Categories="+dFile.catList.join(";")); }
- if( !dFile.keyList.isEmpty() ){ info.insert(insertloc,"Keywords="+dFile.keyList.join(";")); }
- if( !dFile.actionList.isEmpty() ){ info.insert(insertloc,"Actions="+dFile.actionList.join(";")); }
- if( !dFile.showInList.isEmpty() ){ info.insert(insertloc,"OnlyShowIn="+dFile.showInList.join(";")); }
- else if( !dFile.notShowInList.isEmpty() ){ info.insert(insertloc,"NotShowIn="+dFile.notShowInList.join(";")); }
- if( !dFile.url.isEmpty() ){ info.insert(insertloc,"URL="+dFile.url); }
- if( dFile.isHidden && autofile ){ info.insert(insertloc,"Hidden=true"); }
- else if(dFile.isHidden){ info.insert(insertloc,"NoDisplay=true"); }
- if( dFile.useTerminal){ info.insert(insertloc,"Terminal=true"); }
- if( dFile.startupNotify ){ info.insert(insertloc,"StartupNotify=true"); }
-
- //Now save the file
- return LUtils::writeFile(dFile.filePath, info, true);
-
-}
-
-bool LXDG::checkValidity(XDGDesktop dFile, bool showAll){
- bool ok=true;
- bool DEBUG = false;
- if(DEBUG){ qDebug() << "[LXDG] Check File validity:" << dFile.name << dFile.filePath; }
- switch (dFile.type){
- case XDGDesktop::BAD:
- ok=false;
- if(DEBUG){ qDebug() << " - Bad file type"; }
- break;
- case XDGDesktop::APP:
- if(!dFile.tryexec.isEmpty() && !LXDG::checkExec(dFile.tryexec)){ ok=false; if(DEBUG){ qDebug() << " - tryexec does not exist";} }
- else if(dFile.exec.isEmpty() || dFile.name.isEmpty()){ ok=false; if(DEBUG){ qDebug() << " - exec or name is empty";} }
- else if(!LXDG::checkExec(dFile.exec.section(" ",0,0,QString::SectionSkipEmpty)) ){ ok=false; if(DEBUG){ qDebug() << " - first exec binary does not exist";} }
- break;
- case XDGDesktop::LINK:
- ok = !dFile.url.isEmpty();
- if(DEBUG && !ok){ qDebug() << " - Link with missing URL"; }
- break;
- case XDGDesktop::DIR:
- ok = !dFile.path.isEmpty();
- if(DEBUG && !ok){ qDebug() << " - Dir with missing path"; }
- break;
- default:
- ok=false;
- if(DEBUG){ qDebug() << " - Unknown file type"; }
- }
- if(!showAll){
- if(!dFile.showInList.isEmpty()){ ok = dFile.showInList.contains("Lumina", Qt::CaseInsensitive); }
- else if(!dFile.notShowInList.isEmpty()){ ok = !dFile.notShowInList.contains("Lumina",Qt::CaseInsensitive); }
- else if(dFile.name.isEmpty()){ ok = false; }
- }
- return ok;
-}
-
bool LXDG::checkExec(QString exec){
//Return true(good) or false(bad)
if(exec.startsWith("/")){ return QFile::exists(exec); }
@@ -510,40 +623,28 @@ QStringList LXDG::systemApplicationDirs(){
return out;
}
-XDGDesktopList* LXDG::systemAppsList(){
- static XDGDesktopList *sysapps = new XDGDesktopList(0,true); //set this to automatically update as needed
- if(sysapps->lastCheck.isNull()){ sysapps->updateList(); } //catch the first time the class was used, and prompt for an update right now
- return sysapps;
-}
-
-QList<XDGDesktop> LXDG::systemDesktopFiles(bool showAll, bool showHidden){
- //Quick overload for backwards compatibility which uses the static/global class for managing app entries
- XDGDesktopList list(0, false);
- return list.apps(showAll, showHidden);
-}
-
-QHash<QString,QList<XDGDesktop> > LXDG::sortDesktopCats(QList<XDGDesktop> apps){
+QHash<QString,QList<XDGDesktop*> > LXDG::sortDesktopCats(QList<XDGDesktop*> apps){
//Sort the list of applications into their different categories (main categories only)
//Create the category lists
- QList<XDGDesktop> multimedia, dev, ed, game, graphics, network, office, science, settings, sys, utility, other, wine;
+ QList<XDGDesktop*> multimedia, dev, ed, game, graphics, network, office, science, settings, sys, utility, other, wine;
//Sort the apps into the lists
for(int i=0; i<apps.length(); i++){
- if(apps[i].catList.contains("AudioVideo")){ multimedia << apps[i]; }
- else if(apps[i].catList.contains("Development")){ dev << apps[i]; }
- else if(apps[i].catList.contains("Education")){ ed << apps[i]; }
- else if(apps[i].catList.contains("Game")){ game << apps[i]; }
- else if(apps[i].catList.contains("Graphics")){ graphics << apps[i]; }
- else if(apps[i].catList.contains("Network")){ network << apps[i]; }
- else if(apps[i].catList.contains("Office")){ office << apps[i]; }
- else if(apps[i].catList.contains("Science")){ science << apps[i]; }
- else if(apps[i].catList.contains("Settings")){ settings << apps[i]; }
- else if(apps[i].catList.contains("System")){ sys << apps[i]; }
- else if(apps[i].catList.contains("Utility")){ utility << apps[i]; }
- else if(apps[i].catList.contains("Wine")){ wine << apps[i]; }
+ if(apps[i]->catList.contains("AudioVideo")){ multimedia << apps[i]; }
+ else if(apps[i]->catList.contains("Development")){ dev << apps[i]; }
+ else if(apps[i]->catList.contains("Education")){ ed << apps[i]; }
+ else if(apps[i]->catList.contains("Game")){ game << apps[i]; }
+ else if(apps[i]->catList.contains("Graphics")){ graphics << apps[i]; }
+ else if(apps[i]->catList.contains("Network")){ network << apps[i]; }
+ else if(apps[i]->catList.contains("Office")){ office << apps[i]; }
+ else if(apps[i]->catList.contains("Science")){ science << apps[i]; }
+ else if(apps[i]->catList.contains("Settings")){ settings << apps[i]; }
+ else if(apps[i]->catList.contains("System")){ sys << apps[i]; }
+ else if(apps[i]->catList.contains("Utility")){ utility << apps[i]; }
+ else if(apps[i]->catList.contains("Wine")){ wine << apps[i]; }
else{ other << apps[i]; }
}
//Now create the output hash
- QHash<QString,QList<XDGDesktop> > out;
+ QHash<QString,QList<XDGDesktop*> > out;
if(!multimedia.isEmpty()){ out.insert("Multimedia", LXDG::sortDesktopNames(multimedia)); }
if(!dev.isEmpty()){ out.insert("Development", LXDG::sortDesktopNames(dev)); }
if(!ed.isEmpty()){ out.insert("Education", LXDG::sortDesktopNames(ed)); }
@@ -579,62 +680,22 @@ QString LXDG::DesktopCatToIcon(QString cat){
return icon;
}
-QList<XDGDesktop> LXDG::sortDesktopNames(QList<XDGDesktop> apps){
+QList<XDGDesktop*> LXDG::sortDesktopNames(QList<XDGDesktop*> apps){
//Sort the list by name of the application
- QHash<QString, XDGDesktop> sorter;
+ QHash<QString, XDGDesktop*> sorter;
for(int i=0; i<apps.length(); i++){
- sorter.insert(apps[i].name.toLower(), apps[i]);
+ sorter.insert(apps[i]->name.toLower(), apps[i]);
}
QStringList keys = sorter.keys();
keys.sort();
//Re-assemble the output list
- QList<XDGDesktop> out;
+ QList<XDGDesktop*> out;
for(int i=0; i<keys.length(); i++){
out << sorter[keys[i]];
}
return out;
}
-QString LXDG::getDesktopExec(XDGDesktop app, QString ActionID){
- //Generate the executable line for the application
- QString out;
- QString exec = app.exec;
- if( !ActionID.isEmpty() ){
- //Go through and grab the proper exec for the listed action
- for(int i=0; i<app.actions.length(); i++){
- if(app.actions[i].ID == ActionID){
- exec = app.actions[i].exec;
- break;
- }
- }
- }
-
- if(exec.isEmpty()){ return ""; }
- else if(app.useTerminal){
- //Get the currently default terminal
- QString term = findDefaultAppForMime("application/terminal");
- if(!QFile::exists(term)){ term = "xterm -lc"; }
- else if(term.endsWith(".desktop")){
- bool ok = false;
- XDGDesktop DF = LXDG::loadDesktopFile(term, ok);
- if(ok){ term = LXDG::getDesktopExec(DF); }
- else{ term = "xterm -lc"; }
- }else if( !LUtils::isValidBinary(term)){ term = "xterm -lc"; }
- out = term+" -e "+exec; //-e is a nearly-universal flag for terminal emulators
- }else{
- out =exec;
- }
- //Now perform any of the XDG flag substitutions as appropriate (9/2014 standards)
- if(out.contains("%i") && !app.icon.isEmpty() ){ out.replace("%i", "--icon \'"+app.icon+"\'"); }
- if(out.contains("%c")){
- if(!app.name.isEmpty()){ out.replace("%c", "\'"+app.name+"\'"); }
- else if(!app.genericName.isEmpty()){ out.replace("%c", "\'"+app.genericName+"\'"); }
- else{ out.replace("%c", "\'"+app.filePath.section("/",-1).section(".desktop",0,0)+"\'"); }
- }
- if(out.contains("%k")){ out.replace("%k", "\'"+app.filePath+"\'"); }
- return out;
-}
-
void LXDG::setEnvironmentVars(){
//Set the default XDG environment variables if not already set
setenv("XDG_DATA_HOME",QString(QDir::homePath()+"/.local/share").toUtf8(), 0);
@@ -1107,19 +1168,23 @@ QStringList LXDG::loadMimeFileGlobs2(){
}
file.close();
}
- }
+ if(i==dirs.length()-1 && mimeglobs.isEmpty()){
+ //Could not find the mimetype database on the system - use the fallback file distributed with Lumina
+ dirs << LOS::LuminaShare();
+ }
+ }//end loop over dirs
}
return mimeglobs;
}
//Find all the autostart *.desktop files
-QList<XDGDesktop> LXDG::findAutoStartFiles(bool includeInvalid){
+QList<XDGDesktop*> LXDG::findAutoStartFiles(bool includeInvalid){
//First get the list of directories to search (system first, user-provided files come later and overwrite sys files as needed)
QStringList paths = QString(getenv("XDG_CONFIG_DIRS")).split(":");
paths << QString(getenv("XDG_CONFIG_HOME")).split(":");
//Now go through them and find any valid *.desktop files
- QList<XDGDesktop> files;
+ QList<XDGDesktop*> files;
QStringList filenames; //make it easy to see if this filename is an override
QDir dir;
for(int i=0;i<paths.length(); i++){
@@ -1127,23 +1192,23 @@ QList<XDGDesktop> LXDG::findAutoStartFiles(bool includeInvalid){
dir.cd(paths[i]+"/autostart");
QStringList tmp = dir.entryList(QStringList() << "*.desktop", QDir::Files, QDir::Name);
for(int t=0; t<tmp.length(); t++){
- bool ok = false;
- XDGDesktop desk = LXDG::loadDesktopFile(dir.absoluteFilePath(tmp[t]), ok);
- if(!ok){ continue; } //could not read file
+ XDGDesktop *desk = new XDGDesktop(dir.absoluteFilePath(tmp[t]));
+ if(desk->type == XDGDesktop::BAD){ continue; } //could not read file
//Now figure out what to do with it
if(filenames.contains(tmp[t])){
//This is an overwrite of a lower-priority (system?) autostart file
// find the other file
int old = -1;
for(int o=0; o<files.length(); o++){
- if(files[o].filePath.endsWith("/"+tmp[t])){ old = o; break; } //found it
+ if(files[o]->filePath.endsWith("/"+tmp[t])){ old = o; break; } //found it
}
- if(LXDG::checkValidity(desk, false)){
+ if(desk->isValid(false)){
//Full override of the lower-priority file (might be replacing exec/tryexec fields)
- files[old] = desk;
+ files.takeAt(old)->deleteLater();
+ files.insert(old,desk);
}else{
//Small override file (only the "Hidden" field listed in spec)
- files[old].isHidden = desk.isHidden; //replace this value with the override
+ files[old]->isHidden = desk->isHidden; //replace this value with the override
//files << desk; //still add this to the array (will be ignored/skipped later)
}
}else{
@@ -1157,18 +1222,17 @@ QList<XDGDesktop> LXDG::findAutoStartFiles(bool includeInvalid){
//Now filter the results by validity if desired
if(!includeInvalid){
for(int i=0; i<files.length(); i++){
- if( !LXDG::checkValidity(files[i], false) || files[i].isHidden ){
+ if( !files[i]->isValid(false) || files[i]->isHidden ){
//Invalid file - go ahead and remove it from the output list
- files.removeAt(i);
+ files.takeAt(i)->deleteLater();
i--;
}
}
}
-
return files;
}
-bool LXDG::setAutoStarted(bool autostart, XDGDesktop app){
+/*bool LXDG::setAutoStarted(bool autostart, XDGDesktop *app){
//First get the list of system directories to search (system first, user-provided files come later and overwrite sys files as needed)
QStringList paths = QString(getenv("XDG_CONFIG_DIRS")).split(":");
QString upath = QString(getenv("XDG_CONFIG_HOME")).section(":",0,0);
@@ -1181,12 +1245,12 @@ bool LXDG::setAutoStarted(bool autostart, XDGDesktop app){
}
//Quick check/finish for user-defined files which are getting disabled (just remove the file)
- if(app.filePath.startsWith(upath) && !autostart){
- return QFile::remove(app.filePath);
+ if(app->filePath.startsWith(upath) && !autostart){
+ return QFile::remove(app->filePath);
}
bool sysfile = false;
for(int i=0; i<paths.length(); i++){
- if(app.filePath.startsWith(paths[i]+"/autostart/") ){
+ if(app->filePath.startsWith(paths[i]+"/autostart/") ){
sysfile = true;
//Change it to the user-modifiable directory
app.filePath = app.filePath.replace(paths[i]+"/autostart/", upath);
@@ -1226,18 +1290,18 @@ bool LXDG::setAutoStarted(bool autostart, XDGDesktop app){
saved = LXDG::saveDesktopFile(app);
}
return saved;
-}
+}*/
bool LXDG::setAutoStarted(bool autostart, QString filePath){
//Convenience function for the auto-start setter
- XDGDesktop desk;
- if(filePath.endsWith(".desktop")){
- bool ok = false;
- desk = LXDG::loadDesktopFile(filePath, ok);
- if(!ok){ return false; } //error reading input file
- }else{
+ XDGDesktop desk(filePath);
+ if(!filePath.endsWith(".desktop")){
+ //bool ok = false;
+ //desk = LXDG::loadDesktopFile(filePath, ok);
+ //if(!ok){ return false; } //error reading input file
+ //}else{
desk.filePath = filePath;
desk.useTerminal = false;
}
- return LXDG::setAutoStarted(autostart, desk);
+ return desk.setAutoStarted(autostart);
}
diff --git a/src-qt5/core/libLumina/LuminaXDG.h b/src-qt5/core/libLumina/LuminaXDG.h
index 996e5a20..1c86cedb 100644
--- a/src-qt5/core/libLumina/LuminaXDG.h
+++ b/src-qt5/core/libLumina/LuminaXDG.h
@@ -35,8 +35,8 @@
// ======================
// FreeDesktop Desktop Actions Framework (data structure)
// ======================
-class XDGDesktopAction{
-public:
+struct XDGDesktopAction{
+//public:
//Admin variables
QString ID; //The ID name for this action (should correspond to an entry in the "actionList" for the XDGDesktop below)
//General Variables
@@ -46,9 +46,11 @@ public:
// ======================
// FreeDesktop Desktop Entry Framework (data structure)
// ======================
-class XDGDesktop{
+class XDGDesktop : public QObject{
+ Q_OBJECT
public:
enum XDGDesktopType { BAD, APP, LINK, DIR };
+
//Admin variables
QString filePath; //which file this structure contains the information for (absolute path)
QDateTime lastRead; //when this structure was created from the file
@@ -62,12 +64,24 @@ public:
QStringList actionList, mimeList, catList, keyList;
bool useTerminal, startupNotify;
QList<XDGDesktopAction> actions;
+ //Type 1 Extensions for Lumina (Optional)
+ bool useVGL; //X-VGL
+
//Type 2 (LINK) variables
QString url;
-
- //Constructor/destructor
- XDGDesktop(){}
- ~XDGDesktop(){}
+
+ //Constructor/destructor
+ XDGDesktop(QString filePath="", QObject *parent = 0);
+ ~XDGDesktop(){}
+
+ //Functions for using this structure in various ways
+ void sync(); //syncronize this structure with the backend file(as listed in the "filePath" variable)
+ bool isValid(bool showAll = true); //See if this is a valid .desktop entry (showAll: don't filter out based on DE exclude/include lists)
+
+ QString getDesktopExec(QString ActionID = "");
+ bool saveDesktopFile(bool merge = true); //This will use the "filePath" variable for where to save the file
+
+ bool setAutoStarted(bool autostart = true);
};
// ========================
@@ -80,12 +94,12 @@ public:
XDGDesktopList(QObject *parent = 0, bool watchdirs = false);
~XDGDesktopList();
//Main Interface functions
- QList<XDGDesktop> apps(bool showAll, bool showHidden); //showAll: include invalid files, showHidden: include NoShow/Hidden files
+ QList<XDGDesktop*> apps(bool showAll, bool showHidden); //showAll: include invalid files, showHidden: include NoShow/Hidden files
//Administration variables (not typically used directly)
QDateTime lastCheck;
QStringList newApps, removedApps; //list of "new/removed" apps found during the last check
- QHash<QString, XDGDesktop> files; //<filepath>/<XDGDesktop structure>
+ QHash<QString, XDGDesktop*> files; //<filepath>/<XDGDesktop structure>
public slots:
void updateList(); //run the check routine
@@ -93,6 +107,7 @@ public slots:
private:
QFileSystemWatcher *watcher;
QTimer *synctimer;
+ bool keepsynced;
private slots:
void watcherChanged();
@@ -107,15 +122,18 @@ signals:
class LFileInfo : public QFileInfo{
private:
QString mime, icon;
- XDGDesktop desk;
+ XDGDesktop *desk;
void loadExtraInfo();
public:
//Couple overloaded contructors
+ LFileInfo();
LFileInfo(QString filepath);
LFileInfo(QFileInfo info);
- ~LFileInfo(){}
+ ~LFileInfo(){
+ desk->deleteLater();
+ }
//Functions for accessing the extra information
// -- Return the mimetype for the file
@@ -142,25 +160,25 @@ typedef QList<LFileInfo> LFileInfoList;
class LXDG{
public:
//Read/write a *.desktop file
- static XDGDesktop loadDesktopFile(QString filePath, bool& ok);
- static bool saveDesktopFile(XDGDesktop dFile, bool merge = true);
+ //static XDGDesktop* loadDesktopFile(QString filepath, bool&ok, QObject *parent = 0);
+ //static bool saveDesktopFile(XDGDesktop *dFile, bool merge = true);
//Check a *.desktop file for validity (showAll skips the DE-exclusivity checks)
- static bool checkValidity(XDGDesktop dFile, bool showAll = true);
+ //static bool checkValidity(XDGDesktop *dFile, bool showAll = true);
//Check for a valid executable
static bool checkExec(QString exec);
//Get a list of all the directories where *.desktop files exist
static QStringList systemApplicationDirs();
//Get a list of all the *.desktop files available on the system
- static XDGDesktopList* systemAppsList(); //return a pointer to the entire class
- static QList<XDGDesktop> systemDesktopFiles(bool showAll = false, bool showHidden = false); //simplification for getting just the files
+ //static XDGDesktopList* systemAppsList(); //return a pointer to the entire class
+ //static QList<XDGDesktop*> systemDesktopFiles(bool showAll = false, bool showHidden = false); //simplification for getting just the files
//Sort a list of Desktop files into the proper categories
- static QHash< QString, QList<XDGDesktop> > sortDesktopCats(QList<XDGDesktop> apps);
+ static QHash< QString, QList<XDGDesktop*> > sortDesktopCats(QList<XDGDesktop*> apps);
//Return the icon to use for the given category
static QString DesktopCatToIcon(QString cat);
//Sort a list of Desktop files by name
- static QList<XDGDesktop> sortDesktopNames(QList<XDGDesktop> apps);
+ static QList<XDGDesktop*> sortDesktopNames(QList<XDGDesktop*> apps);
//Get the executable line from a Desktop file
- static QString getDesktopExec(XDGDesktop app, QString ActionID = "");
+ //static QString getDesktopExec(XDGDesktop *app, QString ActionID = "");
//Set all the default XDG Environment variables
static void setEnvironmentVars();
//Find an icon from the current/default theme
@@ -191,8 +209,8 @@ public:
static QStringList loadMimeFileGlobs2();
//Find all the autostart *.desktop files
- static QList<XDGDesktop> findAutoStartFiles(bool includeInvalid = false);
- static bool setAutoStarted(bool autostart, XDGDesktop app);
+ static QList<XDGDesktop*> findAutoStartFiles(bool includeInvalid = false);
+ //static bool setAutoStarted(bool autostart, XDGDesktop *app);
static bool setAutoStarted(bool autostart, QString filePath); //for convenience
};
diff --git a/src-qt5/core/libLumina/LuminaXDG.pri b/src-qt5/core/libLumina/LuminaXDG.pri
new file mode 100644
index 00000000..6f3a2b7c
--- /dev/null
+++ b/src-qt5/core/libLumina/LuminaXDG.pri
@@ -0,0 +1,10 @@
+QT *= multimedia svg
+
+#LUtils Files
+SOURCES *= $${PWD}/LuminaXDG.cpp
+HEADERS *= $${PWD}/LuminaXDG.h
+
+INCLUDEPATH *= ${PWD}
+
+#include LUtils and LuminaOS
+include(LUtils.pri)
diff --git a/src-qt5/core/libLumina/ResizeMenu.cpp b/src-qt5/core/libLumina/ResizeMenu.cpp
new file mode 100644
index 00000000..9f291134
--- /dev/null
+++ b/src-qt5/core/libLumina/ResizeMenu.cpp
@@ -0,0 +1,106 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2013-2016, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "ResizeMenu.h"
+
+// =======================
+// RESIZEMENU CLASS
+// =======================
+ResizeMenu::ResizeMenu(QWidget *parent) : QMenu(parent){
+ this->setContentsMargins(1,1,1,1);
+ this->setMouseTracking(true);
+ resizeSide = NONE;
+ cAct = new QWidgetAction(this);
+ contents = 0;
+ connect(this, SIGNAL(aboutToShow()), this, SLOT(clearFlags()) );
+ connect(this, SIGNAL(aboutToHide()), this, SLOT(clearFlags()) );
+ connect(cAct, SIGNAL(hovered()), this, SLOT(clearFlags()) );
+}
+
+ResizeMenu::~ResizeMenu(){
+
+}
+
+void ResizeMenu::setContents(QWidget *con){
+ this->clear();
+ cAct->setDefaultWidget(con);
+ this->addAction(cAct);
+ contents = con; //save for later
+ contents->setCursor(Qt::ArrowCursor);
+}
+
+void ResizeMenu::mouseMoveEvent(QMouseEvent *ev){
+ QRect geom = this->geometry();
+ //Note: The exact position does not matter as much as the size
+ // since the window will be moved again the next time it is shown
+ // The "-2" in the sizing below accounts for the menu margins
+ QPoint gpos = this->mapToGlobal(ev->pos());
+ bool handled = false;
+ switch(resizeSide){
+ case TOP:
+ if(gpos.y() >= geom.bottom()-1){ break; }
+ geom.setTop(gpos.y());
+ this->setGeometry(geom);
+ if(contents!=0){ contents->setFixedSize(QSize(geom.width()-2, geom.height()-2));}
+ handled = true;
+ break;
+ case BOTTOM:
+ if(gpos.y() <= geom.top()+1){ break; }
+ geom.setBottom( gpos.y());
+ this->setGeometry(geom);
+ if(contents!=0){ contents->setFixedSize(QSize(geom.width()-2, geom.height()-2));}
+ handled = true;
+ break;
+ case LEFT:
+ if(gpos.x() >= geom.right()-1){ break; }
+ geom.setLeft(gpos.x());
+ this->setGeometry(geom);
+ if(contents!=0){ contents->setFixedSize(QSize(geom.width()-2, geom.height()-2));}
+ handled = true;
+ break;
+ case RIGHT:
+ if(gpos.x() <= geom.left()+1){ break; }
+ geom.setRight(gpos.x());
+ this->setGeometry(geom);
+ if(contents!=0){ contents->setFixedSize(QSize(geom.width()-2, geom.height()-2));}
+ handled = true;
+ break;
+ default: //NONE
+ //qDebug() << " - Mouse At:" << ev->pos();
+ //Just adjust the mouse cursor which is shown
+ if(ev->pos().x()<=1 && ev->pos().x() >= -1){ this->setCursor(Qt::SizeHorCursor); }
+ else if(ev->pos().x() >= this->width()-1 && ev->pos().x() <= this->width()+1){ this->setCursor(Qt::SizeHorCursor); }
+ else if(ev->pos().y()<=1 && ev->pos().y() >= -1){ this->setCursor(Qt::SizeVerCursor); }
+ else if(ev->pos().y() >= this->height()-1 && ev->pos().y() <= this->height()+1){ this->setCursor(Qt::SizeVerCursor); }
+ else{ this->setCursor(Qt::ArrowCursor); }
+ }
+ if(!handled){ QMenu::mouseMoveEvent(ev); } //do normal processing as well
+}
+
+void ResizeMenu::mousePressEvent(QMouseEvent *ev){
+ bool used = false;
+ if(ev->buttons().testFlag(Qt::LeftButton) && resizeSide==NONE){
+ //qDebug() << "Mouse Press Event:" << ev->pos() << resizeSide;
+ if(ev->pos().x()<=1 && ev->pos().x() >= -1){resizeSide = LEFT; used = true;}
+ else if(ev->pos().x() >= this->width()-1 && ev->pos().x() <= this->width()+1){ resizeSide = RIGHT; used = true;}
+ else if(ev->pos().y()<=1 && ev->pos().y() >= -1){ resizeSide = TOP; used = true; }
+ else if(ev->pos().y() >= this->height()-1 && ev->pos().y() <= this->height()+1){ resizeSide = BOTTOM; used = true; }
+ }
+ if(used){ ev->accept(); this->grabMouse(); }
+ else{ QMenu::mousePressEvent(ev); } //do normal processing
+}
+
+void ResizeMenu::mouseReleaseEvent(QMouseEvent *ev){
+ this->releaseMouse();
+ if(ev->button() == Qt::LeftButton && resizeSide!=NONE ){
+ //qDebug() << "Mouse Release Event:" << ev->pos() << resizeSide;
+ resizeSide = NONE;
+ emit MenuResized(contents->size());
+ ev->accept();
+ }else{
+ QMenu::mouseReleaseEvent(ev); //do normal processing
+ }
+}
diff --git a/src-qt5/core/libLumina/ResizeMenu.h b/src-qt5/core/libLumina/ResizeMenu.h
new file mode 100644
index 00000000..ed909da3
--- /dev/null
+++ b/src-qt5/core/libLumina/ResizeMenu.h
@@ -0,0 +1,51 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2012-2016, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#ifndef _LUMINA_LIBRARY_RESIZE_MENU_H
+#define _LUMINA_LIBRARY_RESIZE_MENU_H
+
+#include <QMenu>
+#include <QWidget>
+#include <QMouseEvent>
+#include <QAction>
+#include <QWidgetAction>
+#include <QRect>
+#include <QCursor>
+#include <QPoint>
+
+//Special subclass for a menu which the user can grab the edges and resize as necessary
+// Note: Make sure that you don't set 0pixel contents margins on this menu
+// - it needs at least 1 pixel margins for the user to be able to grab it
+class ResizeMenu : public QMenu{
+ Q_OBJECT
+public:
+ ResizeMenu(QWidget *parent = 0);
+ virtual ~ResizeMenu();
+
+ void setContents(QWidget *con);
+
+private:
+ enum SideFlag{NONE, TOP, BOTTOM, LEFT, RIGHT};
+ SideFlag resizeSide;
+ QWidget *contents;
+ QWidgetAction *cAct;
+
+private slots:
+ void clearFlags(){
+ resizeSide=NONE;
+ }
+
+protected:
+ virtual void mouseMoveEvent(QMouseEvent *ev);
+ virtual void mousePressEvent(QMouseEvent *ev);
+ virtual void mouseReleaseEvent(QMouseEvent *ev);
+
+signals:
+ void MenuResized(QSize); //Emitted when the menu is manually resized by the user
+
+};
+
+#endif
diff --git a/src-qt5/core/libLumina/ResizeMenu.pri b/src-qt5/core/libLumina/ResizeMenu.pri
new file mode 100644
index 00000000..247427f1
--- /dev/null
+++ b/src-qt5/core/libLumina/ResizeMenu.pri
@@ -0,0 +1,6 @@
+#Subproject file for bundling the ResizeMenu class into an application
+SOURCES *= $${PWD}/ResizeMenu.cpp
+HEADERS *= $${PWD}/ResizeMenu.h
+#Add this dir to the include path
+# This allows the application to simply use "#include <ResizeMenu.h>" to use it
+INCLUDEPATH *= $${PWD}
diff --git a/src-qt5/core/libLumina/colors/Black.qss.colors b/src-qt5/core/libLumina/colors/Black.qss.colors
deleted file mode 100644
index b6269188..00000000
--- a/src-qt5/core/libLumina/colors/Black.qss.colors
+++ /dev/null
@@ -1,13 +0,0 @@
-ACCENTCOLOR=rgba(204,204,204,200)
-ACCENTDISABLECOLOR=rgba(204,204,204,100)
-ALTBASECOLOR=rgb(37,37,37)
-BASECOLOR=rgb(36,36,36)
-HIGHLIGHTCOLOR=rgba(218,222,226,170)
-HIGHLIGHTDISABLECOLOR=rgba(218,222,226,160)
-PRIMARYCOLOR=rgba(0,0,4,250)
-PRIMARYDISABLECOLOR=rgba(0,0,0,180)
-SECONDARYCOLOR=rgba(192,192,192,200)
-SECONDARYDISABLECOLOR=rgba(192,192,192,100)
-TEXTCOLOR=white
-TEXTDISABLECOLOR=darkgrey
-TEXTHIGHLIGHTCOLOR=black
diff --git a/src-qt5/core/libLumina/colors/Blue-Light.qss.colors b/src-qt5/core/libLumina/colors/Blue-Light.qss.colors
deleted file mode 100644
index 5bcb85f6..00000000
--- a/src-qt5/core/libLumina/colors/Blue-Light.qss.colors
+++ /dev/null
@@ -1,13 +0,0 @@
-ACCENTCOLOR=rgba(157,161,165,200)
-ACCENTDISABLECOLOR=rgba(156,156,157,200)
-ALTBASECOLOR=rgb(239,247,255)
-BASECOLOR=rgb(165,210,255)
-HIGHLIGHTCOLOR=rgb(110,158,208)
-HIGHLIGHTDISABLECOLOR=rgba(110,158,208,150)
-PRIMARYCOLOR=rgba(181,212,238,200)
-PRIMARYDISABLECOLOR=rgba(234,237,238,100)
-SECONDARYCOLOR=rgba(200,222,243,200)
-SECONDARYDISABLECOLOR=rgba(200,222,243,100)
-TEXTCOLOR=black
-TEXTDISABLECOLOR=grey
-TEXTHIGHLIGHTCOLOR=black
diff --git a/src-qt5/core/libLumina/colors/Grey-Dark.qss.colors b/src-qt5/core/libLumina/colors/Grey-Dark.qss.colors
deleted file mode 100644
index 207edd04..00000000
--- a/src-qt5/core/libLumina/colors/Grey-Dark.qss.colors
+++ /dev/null
@@ -1,13 +0,0 @@
-ACCENTCOLOR=rgba(43,43,45,200)
-ACCENTDISABLECOLOR=rgba(43,43,45,100)
-ALTBASECOLOR=rgb(63,61,61)
-BASECOLOR=rgb(93,92,92)
-HIGHLIGHTCOLOR=rgba(218,222,226,170)
-HIGHLIGHTDISABLECOLOR=rgba(218,222,226,160)
-PRIMARYCOLOR=rgba(75,77,80,240)
-PRIMARYDISABLECOLOR=rgba(75,77,80,180)
-SECONDARYCOLOR=rgba(144,140,142,200)
-SECONDARYDISABLECOLOR=rgba(144,140,142,100)
-TEXTCOLOR=white
-TEXTDISABLECOLOR=darkgrey
-TEXTHIGHLIGHTCOLOR=black
diff --git a/src-qt5/core/libLumina/colors/Lumina-Glass.qss.colors b/src-qt5/core/libLumina/colors/Lumina-Glass.qss.colors
deleted file mode 100644
index 89534aaa..00000000
--- a/src-qt5/core/libLumina/colors/Lumina-Glass.qss.colors
+++ /dev/null
@@ -1,13 +0,0 @@
-ACCENTCOLOR=rgba(255,252,234,100)
-ACCENTDISABLECOLOR=rgba(0,0,0,100)
-ALTBASECOLOR=rgba(255,255,255,125)
-BASECOLOR=rgb(247,246,244)
-HIGHLIGHTCOLOR=rgba(212,212,212,170)
-HIGHLIGHTDISABLECOLOR=rgba(184,184,184,100)
-PRIMARYCOLOR=rgba(235,242,242,200)
-PRIMARYDISABLECOLOR=rgba(214,220,220,200)
-SECONDARYCOLOR=rgba(100,100,100,200)
-SECONDARYDISABLECOLOR=rgba(100,100,100,100)
-TEXTCOLOR=black
-TEXTDISABLECOLOR=grey
-TEXTHIGHLIGHTCOLOR=black
diff --git a/src-qt5/core/libLumina/colors/Lumina-Gold.qss.colors b/src-qt5/core/libLumina/colors/Lumina-Gold.qss.colors
deleted file mode 100644
index cfad7069..00000000
--- a/src-qt5/core/libLumina/colors/Lumina-Gold.qss.colors
+++ /dev/null
@@ -1,13 +0,0 @@
-ACCENTCOLOR=rgba(149,144,122,200)
-ACCENTDISABLECOLOR=rgba(74,71,60,200)
-ALTBASECOLOR=rgb(230,227,204)
-BASECOLOR=rgb(247,247,240)
-HIGHLIGHTCOLOR=rgba(252,237,149,170)
-HIGHLIGHTDISABLECOLOR=rgba(252,237,149,100)
-PRIMARYCOLOR=rgba(238,234,226,200)
-PRIMARYDISABLECOLOR=rgba(238,235,224,100)
-SECONDARYCOLOR=rgba(247,209,112,200)
-SECONDARYDISABLECOLOR=rgba(234,198,106,150)
-TEXTCOLOR=black
-TEXTDISABLECOLOR=grey
-TEXTHIGHLIGHTCOLOR=black \ No newline at end of file
diff --git a/src-qt5/core/libLumina/colors/Lumina-Green.qss.colors b/src-qt5/core/libLumina/colors/Lumina-Green.qss.colors
deleted file mode 100644
index 99f16acb..00000000
--- a/src-qt5/core/libLumina/colors/Lumina-Green.qss.colors
+++ /dev/null
@@ -1,13 +0,0 @@
-ACCENTCOLOR=rgba(149,144,122,200)
-ACCENTDISABLECOLOR=rgba(74,71,60,200)
-ALTBASECOLOR=rgb(230,230,230)
-BASECOLOR=rgb(247,246,244)
-HIGHLIGHTCOLOR=rgba(66,153,76,170)
-HIGHLIGHTDISABLECOLOR=rgba(66,153,76,100)
-PRIMARYCOLOR=rgba(229,231,238,200)
-PRIMARYDISABLECOLOR=rgba(229,231,238,100)
-SECONDARYCOLOR=rgba(76,197,84,200)
-SECONDARYDISABLECOLOR=rgba(76,197,84,150)
-TEXTCOLOR=black
-TEXTDISABLECOLOR=grey
-TEXTHIGHLIGHTCOLOR=black
diff --git a/src-qt5/core/libLumina/colors/Lumina-Purple.qss.colors b/src-qt5/core/libLumina/colors/Lumina-Purple.qss.colors
deleted file mode 100644
index f2ba7e05..00000000
--- a/src-qt5/core/libLumina/colors/Lumina-Purple.qss.colors
+++ /dev/null
@@ -1,13 +0,0 @@
-ACCENTCOLOR=rgba(247,231,255,200)
-ACCENTDISABLECOLOR=rgba(167,166,166,200)
-ALTBASECOLOR=rgb(63,61,61)
-BASECOLOR=rgb(93,92,92)
-HIGHLIGHTCOLOR=rgba(76,38,171,170)
-HIGHLIGHTDISABLECOLOR=rgba(57,19,139,170)
-PRIMARYCOLOR=rgba(65,67,80,240)
-PRIMARYDISABLECOLOR=rgba(65,67,80,180)
-SECONDARYCOLOR=rgba(74,65,120,200)
-SECONDARYDISABLECOLOR=rgba(71,65,120,100)
-TEXTCOLOR=white
-TEXTDISABLECOLOR=darkgrey
-TEXTHIGHLIGHTCOLOR=white \ No newline at end of file
diff --git a/src-qt5/core/libLumina/colors/Lumina-Red.qss.colors b/src-qt5/core/libLumina/colors/Lumina-Red.qss.colors
deleted file mode 100644
index f73bdb75..00000000
--- a/src-qt5/core/libLumina/colors/Lumina-Red.qss.colors
+++ /dev/null
@@ -1,13 +0,0 @@
-ACCENTCOLOR=rgba(255,244,245,200)
-ACCENTDISABLECOLOR=rgba(167,166,166,200)
-ALTBASECOLOR=rgb(63,61,61)
-BASECOLOR=rgb(93,92,92)
-HIGHLIGHTCOLOR=rgba(175,9,9,170)
-HIGHLIGHTDISABLECOLOR=rgba(154,20,20,170)
-PRIMARYCOLOR=rgba(80,66,66,240)
-PRIMARYDISABLECOLOR=rgba(80,66,66,180)
-SECONDARYCOLOR=rgba(120,22,23,200)
-SECONDARYDISABLECOLOR=rgba(120,22,23,100)
-TEXTCOLOR=white
-TEXTDISABLECOLOR=darkgrey
-TEXTHIGHLIGHTCOLOR=white \ No newline at end of file
diff --git a/src-qt5/core/libLumina/colors/PCBSD10-Default.qss.colors b/src-qt5/core/libLumina/colors/PCBSD10-Default.qss.colors
deleted file mode 100644
index efcea51d..00000000
--- a/src-qt5/core/libLumina/colors/PCBSD10-Default.qss.colors
+++ /dev/null
@@ -1,13 +0,0 @@
-ACCENTCOLOR=rgba(182,186,191,200)
-ACCENTDISABLECOLOR=rgba(190,190,191,200)
-ALTBASECOLOR=rgb(241,241,241)
-BASECOLOR=rgb(247,246,244)
-HIGHLIGHTCOLOR=rgb(129,184,243)
-HIGHLIGHTDISABLECOLOR=rgba(129,184,243,150)
-PRIMARYCOLOR=rgba(224,236,238,200)
-PRIMARYDISABLECOLOR=rgba(234,237,238,100)
-SECONDARYCOLOR=rgba(200,222,243,200)
-SECONDARYDISABLECOLOR=rgba(200,222,243,100)
-TEXTCOLOR=black
-TEXTDISABLECOLOR=grey
-TEXTHIGHLIGHTCOLOR=black
diff --git a/src-qt5/core/libLumina/colors/Solarized-Dark.qss.colors b/src-qt5/core/libLumina/colors/Solarized-Dark.qss.colors
deleted file mode 100644
index d4f0f1c9..00000000
--- a/src-qt5/core/libLumina/colors/Solarized-Dark.qss.colors
+++ /dev/null
@@ -1,16 +0,0 @@
-# Solarized is a theme created by Ethan Schoonover
-# See the project site at http://ethanschoonover.com/solarized
-# Or see the source at https://github.com/altercation/solarized
-ACCENTCOLOR=rgb(181,137,0)
-ACCENTDISABLECOLOR=rgb(181,137,0)
-ALTBASECOLOR=rgb(0,43,54)
-BASECOLOR=rgb(0,43,54)
-HIGHLIGHTCOLOR=rgb(7,54,66)
-HIGHLIGHTDISABLECOLOR=rgb(7,53,66)
-PRIMARYCOLOR=rgb(0,43,54)
-PRIMARYDISABLECOLOR=rgb(7,54,66)
-SECONDARYCOLOR=rgb(0,43,54)
-SECONDARYDISABLECOLOR=rgb(7,54,66)
-TEXTCOLOR=rgb(131,148,150)
-TEXTDISABLECOLOR=rgb(88,110,117)
-TEXTHIGHLIGHTCOLOR=rgb(147,161,161)
diff --git a/src-qt5/core/libLumina/colors/Solarized-Light.qss.colors b/src-qt5/core/libLumina/colors/Solarized-Light.qss.colors
deleted file mode 100644
index fead1915..00000000
--- a/src-qt5/core/libLumina/colors/Solarized-Light.qss.colors
+++ /dev/null
@@ -1,16 +0,0 @@
-# Solarized is a theme created by Ethan Schoonover
-# See the project site at http://ethanschoonover.com/solarized
-# Or see the source at https://github.com/altercation/solarized
-ACCENTCOLOR=rgb(38,139,210)
-ACCENTDISABLECOLOR=rgb(38,139,210)
-ALTBASECOLOR=rgb(253,246,227)
-BASECOLOR=rgb(253,246,227)
-HIGHLIGHTCOLOR=rgb(238,232,213)
-HIGHLIGHTDISABLECOLOR=rgb(238,232,213)
-PRIMARYCOLOR=rgb(253,246,227)
-PRIMARYDISABLECOLOR=rgb(238,232,213)
-SECONDARYCOLOR=rgb(253,246,227)
-SECONDARYDISABLECOLOR=rgb(238,232,213)
-TEXTCOLOR=rgb(131,148,150)
-TEXTDISABLECOLOR=rgb(147,161,161)
-TEXTHIGHLIGHTCOLOR=rgb(88,110,117)
diff --git a/src-qt5/core/libLumina/libLumina.pro b/src-qt5/core/libLumina/libLumina.pro
deleted file mode 100644
index 7f9e4203..00000000
--- a/src-qt5/core/libLumina/libLumina.pro
+++ /dev/null
@@ -1,65 +0,0 @@
-include("$${PWD}/../../OS-detect.pri")
-
-QT += core network widgets x11extras multimedia concurrent svg
-
-define
-#Setup any special defines (qmake -> C++)
-GIT_VERSION=$$system(git describe --always)
-!isEmpty(GIT_VERSION){
- DEFINES += GIT_VERSION='"\\\"$${GIT_VERSION}\\\""'
-}
-DEFINES += BUILD_DATE='"\\\"$$system(date)\\\""'
-
-TARGET=LuminaUtils
-
-target.path = $${L_LIBDIR}
-
-DESTDIR= $$_PRO_FILE_PWD_/
-
-TEMPLATE = lib
-LANGUAGE = C++
-VERSION = 1
-
-HEADERS += LuminaXDG.h \
- LuminaUtils.h \
- LuminaX11.h \
- LuminaThemes.h \
- LuminaOS.h \
- LuminaSingleApplication.h
-
-SOURCES += LuminaXDG.cpp \
- LuminaUtils.cpp \
- LuminaX11.cpp \
- LuminaThemes.cpp \
- LuminaSingleApplication.cpp
-
-# Also load the OS template as available for
-# LuminaOS support functions (or fall back to generic one)
-exists($${PWD}/LuminaOS-$${LINUX_DISTRO}.cpp){
- SOURCES += LuminaOS-$${LINUX_DISTRO}.cpp
-}else:exists($${PWD}/LuminaOS-$${OS}.cpp){
- SOURCES += LuminaOS-$${OS}.cpp
-}else{
- SOURCES += LuminaOS-template.cpp
-}
-
-LIBS += -lc -lxcb -lxcb-ewmh -lxcb-icccm -lxcb-image -lxcb-composite -lxcb-damage -lxcb-util -lXdamage
-
-include.path=$${L_INCLUDEDIR}
-include.files=LuminaXDG.h \
- LuminaUtils.h \
- LuminaX11.h \
- LuminaThemes.h \
- LuminaOS.h \
- LuminaSingleApplication.h
-
-colors.path=$${L_SHAREDIR}/lumina-desktop/colors
-colors.files=colors/*.qss.colors
-
-themes.path=$${L_SHAREDIR}/lumina-desktop/themes/
-themes.files=themes/*.qss.template
-
-#quickplugins.path=$${L_SHAREDIR}/lumina-desktop/quickplugins/
-#quickplugins.files=quickplugins/*
-
-INSTALLS += target include colors themes
diff --git a/src-qt5/core/libLumina/quickplugins/quick-sample.qml b/src-qt5/core/libLumina/quickplugins/quick-sample.qml
deleted file mode 100644
index 18b10d77..00000000
--- a/src-qt5/core/libLumina/quickplugins/quick-sample.qml
+++ /dev/null
@@ -1,12 +0,0 @@
-// Plugin-Name=Sample
-// Plugin-Description=A simple example for QtQuick/QML plugins
-// Plugin-Icon=preferences-plugin
-// Created: Ken Moore (ken@pcbsd.org) May 2015
-
-import QtQuick.Controls 1.3
-
-Label {
- text: "Sample"
- color: "blue"
- font.bold: true
-} \ No newline at end of file
diff --git a/src-qt5/core/libLumina/themes/Glass.qss.template b/src-qt5/core/libLumina/themes/Glass.qss.template
deleted file mode 100644
index d594d25e..00000000
--- a/src-qt5/core/libLumina/themes/Glass.qss.template
+++ /dev/null
@@ -1,539 +0,0 @@
-/* ALL THE TEMPLATE WIDGETS */
-INHERITS=None
-
-/* ALL THE WIDGETS WITH THE BASE COLOR */
-QMainWindow, QMenu, QDialog, QMessageBox{
- background: qradialgradient(spread:reflect, cx:0.113757, cy:0.875, radius:0.7, fx:0.045, fy:0.954545, stop:0 %%BASECOLOR%%, stop:1 %%ALTBASECOLOR%%);
- color: %%TEXTCOLOR%%;
- border: 1px solid %%ACCENTDISABLECOLOR%%;
- border-radius: 3px;
-}
-
-/* ALL THE WIDGETS WITH AN ALTERNATE BASE COLOR */
-QLineEdit, QTextEdit, QTextBrowser, QPlainTextEdit, QSpinBox, QDateEdit, QDateTimeEdit, QTimeEdit, QDoubleSpinBox{
- background: %%ALTBASECOLOR%%;
- color: %%TEXTCOLOR%%;
- border-color: %%ACCENTDISABLECOLOR%%;
- selection-background-color: %%HIGHLIGHTCOLOR%%;
- selection-color: %%TEXTHIGHLIGHTCOLOR%%;
-}
-
-/* PAGES OF CONTAINER WIDGETS */
-QStackedWidget .QWidget{
- background: transparent;
- color: %%TEXTCOLOR%%;
- border: none;
-}
-
-QToolBox::tab{
- color: %%TEXTCOLOR%%;
-}
-
-/* MENU WIDGETS */
-QMenuBar, QMenuBar::item,QToolBar{
- background: transparent;
- border: none;
- color: %%TEXTCOLOR%%;
-}
-
-QStatusBar{
- background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 transparent, stop: 0.5 %%SECONDARYCOLOR%%);
- border: none;
- color: %%TEXTCOLOR%%;
-}
-QToolBar:top{
- border-bottom: 1px solid %%ACCENTCOLOR%%;
-}
-QToolBar:bottom{
- border-top: 1px solid %%ACCENTCOLOR%%;
-}
-QToolBar:left{
- border-right: 1px solid %%ACCENTCOLOR%%;
-}
-QToolBar:right{
- border-left: 1px solid %%ACCENTCOLOR%%;
-}
-
-QMenuBar::item{
- background: transparent; /*Use the menu bar color*/
- padding-left: 4px;
- padding-right: 2px;
-}
-
-QMenuBar::item:selected, QMenuBar::item:pressed, QMenu::item:selected{
-background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%HIGHLIGHTDISABLECOLOR%%, stop: 1 %%HIGHLIGHTCOLOR%%);
-color: %%TEXTHIGHLIGHTCOLOR%%;
-border: 1px solid %%ACCENTCOLOR%%;
-}
-QMenuBar::item:disabled{
- color: %%TEXTDISABLECOLOR%%;
-}
-
-/*QMenu::item{
- border: 2px solid #808080;
-}*/
-
-QMenu::item{
- background: transparent;
- border: 1px solid transparent;
- color: %%TEXTCOLOR%%;
- padding: 4px 30px 4px 20px;
- margin-left: 3px;
- margin-right: 3px;
-}
-
-/* TAB WIDGETS */
-/*QTabBar{
- Custom Font settings need to be here and NOT in the ::tab fields,
- otherwise it will break auto-scaling of the tab sizes to fit the text
-}*/
-/* Transparency does not work on main pages within tabwidgets*/
-QTabWidget QStackedWidget .QWidget{
- background: rgb(230,230,230);
- border-bottom-left-radius: 4px;
- border-bottom-right-radius: 4px;
-}
-QTabWidget{
- color: black;
- border: none;
-}
-QTabWidget QLabel{
- color: black;
-}
-QTabBar::tab {
- background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%SECONDARYDISABLECOLOR%%, stop: 1 %%ALTBASECOLOR%%);
- border: 1px solid %%ACCENTCOLOR%%;
- padding: 2px;
- color: %%TEXTCOLOR%%;
-}
-QTabBar::tab:top{
- border-top-left-radius: 4px;
- border-top-right-radius: 4px;
- max-width: 100em;
- min-width: 0em;
-}
-QTabBar::tab:bottom{
- border-bottom-left-radius: 4px;
- border-bottom-right-radius: 4px;
- max-width: 100em;
- min-width: 0em;
-}
-/* left/right tab indicators appear to be reversed in Qt*/
-QTabBar::tab:right{
- border-top-left-radius: 4px;
- border-bottom-left-radius: 4px;
- max-height: 100em;
- min-height: 0em;
-}
-QTabBar::tab:left{
- border-top-right-radius: 4px;
- border-bottom-right-radius: 4px;
- max-height: 100em;
- min-height: 0em;
-}
-QTabBar::tab:selected{
- background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %%HIGHLIGHTDISABLECOLOR%%, stop: 1 rgb(230,230,230));
- border-bottom: none;
-}
-QTabBar::tab:hover {
- background: %%HIGHLIGHTCOLOR%%;
- border: 1px solid %%ACCENTDISABLECOLOR%%;
- }
-
-QTabBar::tab:!selected:top {
- margin-top: 4px;
-}
-QTabBar::tab:!selected:bottom{
- margin-bottom: 4px;
-}
-QTabBar::tab:!selected:right{
- margin-left: 4px;
-}
-QTabBar::tab:!selected:left{
- margin-right: 4px;
-}
-
-/* FRAME WIDGETS */
-QToolTip{
- background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%BASECOLOR%%, stop: 1 %%ALTBASECOLOR%%);
- border-radius: 3px;
- border: 1px solid %%ACCENTCOLOR%%;
- padding: 1px;
- color: %%TEXTCOLOR%%;
-}
-
-QLabel{
- background: transparent;
- border: none;
- color: %%TEXTCOLOR%%;
-}
-QAbstractButton::disabled{
- color: %%TEXTDISABLECOLOR%%;
-}
-
-/* GROUP BOX */
-QGroupBox{
- background-color: transparent;
- border-color: %%ACCENTCOLOR%%;
- border-radius: 5px;
- margin-top: 2ex;
- font-weight: bold;
-}
-QGroupBox::title{
- subcontrol-origin: margin;
- subcontrol-position: top center;
- padding: 0 3px;
- background: transparent;
- /*border: none;*/
- color: %%TEXTCOLOR%%;
-}
-
-/* COMBO BOX */
-QComboBox{
- /*border: 1px solid %%ACCENTCOLOR%%;
- border-radius: 3px;
- padding: 1px 18px 1px 3px;*/
- color: %%TEXTCOLOR%%;
- background: %%ALTBASECOLOR%%;
- selection-background-color: %%HIGHLIGHTCOLOR%%;
- }
-
-
-/* VIEW WIDGETS */
-QTreeView, QListView{
- background: %%ALTBASECOLOR%%;
- alternate-background-color: %%BASECOLOR%%;
- /*selection-background-color: %%SECONDARYCOLOR%%;*/
- border: 1px solid %%ACCENTCOLOR%%;
- border-radius: 3px;
- /*show-decoration-selected: 1;*/
- color: %%TEXTCOLOR%%;
- selection-color: %%TEXTCOLOR%%;
-}
-
-QTreeView:focus, QListView:focus{
- border: 1px solid %%HIGHLIGHTDISABLECOLOR%%;
-}
-
-/*
-QTreeView::item and QListView::item unneccessary:
-Already set though parentage and causes usage errors if set manually
-*/
-
-/*QTreeView::item:selected, QListView::item:selected{
- background: %%SECONDARYDISABLECOLOR%%;
- border-color: %%ACCENTCOLOR%%;
- color: %%TEXTCOLOR%%;
-}*/
-
-QTreeView::item:hover, QListView::item:hover{
- background: %%HIGHLIGHTDISABLECOLOR%%;
-}
-QTreeView::item:selected:hover, QListView::item:selected:hover{
- background: %%HIGHLIGHTDISABLECOLOR%%;
-}
-QTreeView::item:selected, QListView::item:selected{
- background: %%SECONDARYDISABLECOLOR%%;
-}
-QTreeView::item:selected:focus, QListView::item:selected:focus{
- background: %%SECONDARYCOLOR%%;
-}
-QHeaderView{
- background: %%HIGHLIGHTDISABLECOLOR%%;
- color: %%TEXTHIGHLIGHTCOLOR%%;
- border: none;
- border-top-left-radius: 3px; /*match the list/tree view widgets*/
- border-top-right-radius: 3px; /*match the list/tree view widgets*/
-}
-QHeaderView::section{
- background: %%HIGHLIGHTDISABLECOLOR%%; /*QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%PRIMARYDISABLECOLOR%%, stop: 1 %%PRIMARYCOLOR%%);*/
- color: %%TEXTHIGHLIGHTCOLOR%%;
- border-color: %%ACCENTCOLOR%%;
- padding: 1px;
- padding-left: 4px;
-}
-QHeaderView::section:hover{
- background: %%PRIMARYCOLOR%%;
- border-color: %%ACCENTDISABLECOLOR%%;
- color: %%TEXTCOLOR%%;
-}
-
-/* SCROLLBARS (NOTE: Changing 1 subcontrol means you have to change all of them)*/
-QScrollBar{
- background:%%ALTBASECOLOR%%;
-}
-QScrollBar:horizontal{
- margin: 0px 0px 0px 0px;
-}
-QScrollBar:vertical{
- margin: 0px 0px 0px 0px;
-}
-QScrollBar::handle{
- background: %%SECONDARYCOLOR%%;
- border: 1px solid transparent;
- border-radius: 7px;
-}
-QScrollBar::handle:hover, QScrollBar::add-line:hover, QScrollBar::sub-line:hover{
- background: %%SECONDARYDISABLECOLOR%%;
-}
-QScrollBar::add-line{
-subcontrol-origin: none;
-}
-QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical{
-height: 0px;
-}
-QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal{
-width: 0px;
-}
-QScrollBar::sub-line{
-subcontrol-origin: none;
-}
-
-/* SLIDERS */
-QSlider::groove:horizontal {
-border: 1px solid %%ACCENTCOLOR%%;
-background: %%ALTBASECOLOR%%;
-height: 10px;
-border-radius: 3px;
-}
-QSlider::groove:vertical {
-border: 1px solid %%ACCENTCOLOR%%;
-background: %%ALTBASECOLOR%%;
-width: 10px;
-border-radius: 3px;
-}
-QSlider::sub-page:horizontal {
-background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1,
- stop: 0 %%HIGHLIGHTCOLOR%%, stop: 1 %%HIGHLIGHTDISABLECOLOR%%);
-border: 1px solid %%ACCENTCOLOR%%;
-height: 10px;
-border-radius: 3px;
-}
-QSlider::sub-page:vertical {
-background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1,
- stop: 0 %%HIGHLIGHTCOLOR%%, stop: 1 %%HIGHLIGHTDISABLECOLOR%%);
-border: 1px solid %%ACCENTCOLOR%%;
-width: 10px;
-border-radius: 3px;
-}
-QSlider::add-page:horizontal{
-background: %%ALTBASECOLOR%%;
-border: 1px solid %%ACCENTCOLOR%%;
-height: 10px;
-border-radius: 3px;
-}
-QSlider::add-page:vertical{
-background: %%ALTBASECOLOR%%;
-border: 1px solid %%ACCENTCOLOR%%;
-width: 10px;
-border-radius: 3px;
-}
-QSlider::handle:horizontal{
-background: %%ALTBASECOLOR%%;
-border: 1px solid %%ACCENTCOLOR%%;
-width: 13px;
-border-radius: 4px;
-}
-QSlider::handle:vertical{
-background: %%ALTBASECOLOR%%;
-border: 1px solid %%ACCENTCOLOR%%;
-height: 13px;
-border-radius: 4px;
-}
-QSlider::handle:horizontal:hover, QSlider::handle:vertical:hover{
-border: 1px solid %%ACCENTDISABLECOLOR%%;
-/*background: %%HIGHLIGHTCOLOR%%;*/
-}
-
-QSlider::sub-page:horizontal:disabled {
-background: %%ACCENTDISABLECOLOR%%;
-border-color: %%ACCENTCOLOR%%;
-}
-
-QSlider::add-page:horizontal:disabled {
-background: %%ACCENTDISABLECOLOR%%;
-border-color: %%ACCENTCOLOR%%;
-}
-
-QSlider::handle:horizontal:disabled {
-background: %%ALTBASECOLOR%%;
-border: 1px solid %%ACCENTCOLOR%%;
-}
-
-/* BUTTONS */
-QPushButton{
- border: 1px solid %%ACCENTCOLOR%%;
- border-radius: 3px;
- background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%SECONDARYDISABLECOLOR%%, stop: 1 %%SECONDARYCOLOR%%);
- padding: 2px;
- padding-right: 4px;
- color: %%TEXTCOLOR%%;
- }
-
-QToolButton{ /* Assume a flat button for every toolbutton by default*/
- color: %%TEXTCOLOR%%;
- border: 1px solid transparent;
- border-radius: 3px;
- background-color: transparent;
- padding: 1px;
-}
-
- QPushButton:pressed, QPushButton:open, QPushButton:selected, QPushButton:checked, QPushButton:on, QToolButton:pressed, QToolButton:open, QToolButton:selected, QToolButton:checked, QToolButton:on{
- background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%HIGHLIGHTDISABLECOLOR%%, stop: 1 %%HIGHLIGHTCOLOR%%);
- margin-top: 2px;
- }
-
-QPushButton:flat, QToolButton:flat{
- background-color: transparent;
- border: 1px solid transparent; /* no border for a flat button */
-}
-
-QPushButton:hover, QToolButton:hover{
- border: 1px solid %%ACCENTCOLOR%%;
- background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%HIGHLIGHTDISABLECOLOR%%, stop: 1 %%HIGHLIGHTCOLOR%%);
- color: %%TEXTHIGHLIGHTCOLOR%%;
-}
-QRadioButton, QCheckBox{
- padding: 2px;
- border: 1px solid transparent;
- border-radius: 3px;
- color: %%TEXTCOLOR%%;
-}
-QRadioButton::hover, QCheckBox:hover{
- background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%HIGHLIGHTDISABLECOLOR%%, stop: 1 %%HIGHLIGHTCOLOR%%);
- border: 1px solid %%ACCENTCOLOR%%;
- color: %%TEXTHIGHLIGHTCOLOR%%;
-}
-QRadioButton::indicator, QCheckBox::indicator, QGroupBox::indicator{
- border: 1px solid %%TEXTCOLOR%%;
-}
-QRadioButton::indicator{
- border-radius: 7px;
-}
-QRadioButton::indicator:checked{
- background: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:1, fx:0.5, fy:0.5, stop:0 %%TEXTCOLOR%%, stop:0.25 %%TEXTCOLOR%%, stop:0.25001 transparent);
-}
-QCheckBox::indicator:checked, QGroupBox::indicator:checked{
- padding: 1px;
- background-origin: content;
- background-clip: content;
- background: %%TEXTCOLOR%%;
-}
-QCheckBox::indicator:indeterminate, QGroupBox::indicator:indeterminate{
- padding: 1px;
- background-origin: content;
- background-clip: content;
- background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0.49 transparent, stop: 0.5 %%TEXTCOLOR%%);
-}
-
-/* PROGRESSBAR */
-QProgressBar{
- background-color: %%ALTBASECOLOR%%;
- border: 1px solid %%ACCENTCOLOR%%;
- border-radius: 5px;
- color: %%TEXTCOLOR%%;
- text-align: center;
- padding: 1px;
-}
- QProgressBar::chunk {
- background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%HIGHLIGHTCOLOR%%, stop: 1 %%HIGHLIGHTDISABLECOLOR%%);
- /*border: 1px solid %%ACCENTDISABLECOLOR%%;*/
- border-radius: 5px;
- }
-QProgressBar::chunk:vertical{
- margin-left: 2px;
- margin-right: 2px;
-}
-QProgressBar::chunk:horizontal{
- margin-top: 2px;
- margin-bottom: 2px;
-}
-
-QWidget#LuminaBootSplash{
- background: qradialgradient(spread:reflect, cx:0.113757, cy:0.875, radius:0.7, fx:0.045, fy:0.954545, stop:0 rgba(234, 236, 243, 30), stop:1 rgba(229, 229, 229, 70));
- border-radius: 5px;
-}
-
-LDPlugin#applauncher{
- background-color: transparent;
- border: none;
-}
-LDPlugin#applauncher QToolButton, LDPlugin, LDPlugin#desktopview QListWidget::item{
- background-color: qradialgradient(spread:reflect, cx:0.113757, cy:0.875, radius:0.7, fx:0.045, fy:0.954545, stop:0 rgba(234, 236, 243, 30), stop:1 rgba(229, 229, 229, 70));
- border-width: 3px;
- border-style: solid;
- border-radius: 5px;
- border-top-color: qradialgradient(spread:pad, cx:0.5, cy:1, radius:0.5, fx:0.5, fy:1, stop:0 rgba(255, 255, 255, 30), stop:0.724868 rgba(255, 255, 255, 60), stop:1 rgba(255, 255, 255, 10));
- border-bottom-color: qradialgradient(spread:pad, cx:0.5, cy:0, radius:0.5, fx:0.5, fy:0, stop:0 rgba(255, 255, 255, 30), stop:0.724868 rgba(255, 255, 255, 60), stop:1 rgba(255, 255, 255, 10));
- border-left-color: qradialgradient(spread:pad, cx:1, cy:0.5, radius:0.5, fx:1, fy:0.5, stop:0 rgba(255, 255, 255, 30), stop:0.724868 rgba(255, 255, 255, 60), stop:1 rgba(255, 255, 255, 10));
- border-right-color: qradialgradient(spread:pad, cx:0, cy:0.5, radius:0.5, fx:1, fy:0.5, stop:0 rgba(255, 255, 255, 30), stop:0.724868 rgba(255, 255, 255, 60), stop:1 rgba(255, 255, 255, 10));
- color: white;
-}
-
-LDPlugin#applauncher QToolButton:hover, LDPlugin#desktopview QListWidget::item:hover{
- background-color: qradialgradient(spread:reflect, cx:0.113757, cy:0.875, radius:0.7, fx:0.045, fy:0.954545, stop:0 rgba(234, 236, 243, 100), stop:1 rgba(229, 229, 229, 150));
- border-width: 3px;
- border-style: solid;
- border-radius: 5px;
- border-top-color: qradialgradient(spread:pad, cx:0.5, cy:1, radius:0.5, fx:0.5, fy:1, stop:0 rgba(255, 255, 255, 30), stop:0.724868 rgba(255, 255, 255, 60), stop:1 rgba(255, 255, 255, 10));
- border-bottom-color: qradialgradient(spread:pad, cx:0.5, cy:0, radius:0.5, fx:0.5, fy:0, stop:0 rgba(255, 255, 255, 30), stop:0.724868 rgba(255, 255, 255, 60), stop:1 rgba(255, 255, 255, 10));
- border-left-color: qradialgradient(spread:pad, cx:1, cy:0.5, radius:0.5, fx:1, fy:0.5, stop:0 rgba(255, 255, 255, 30), stop:0.724868 rgba(255, 255, 255, 60), stop:1 rgba(255, 255, 255, 10));
- border-right-color: qradialgradient(spread:pad, cx:0, cy:0.5, radius:0.5, fx:1, fy:0.5, stop:0 rgba(255, 255, 255, 30), stop:0.724868 rgba(255, 255, 255, 60), stop:1 rgba(255, 255, 255, 10));
- color: %%TEXTHIGHLIGHTCOLOR%%;
-}
-QWidget#LuminaPanelColor{
- background: qradialgradient(spread:reflect, cx:0.113757, cy:0.875, radius:0.7, fx:0.045, fy:0.954545, stop:0 rgba(234, 236, 243, 60), stop:1 rgba(229, 229, 229, 110));
- border-radius: 3px;
-}
-/*Special taskmanager window buttons: based on window state*/
-LTBWidget{
- border: 1px solid transparent;
- border-radius: 3px;
-}
-LTBWidget::menu-indicator{ image: none; } /*disable the menu arrow*/
-LTBWidget#WindowVisible{
- background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1.1, stop: 0.1 %%PRIMARYCOLOR%%, stop: 1 transparent);
-}
-LTBWidget#WindowInvisible{
- background: transparent;
-}
-LTBWidget#WindowActive{
- background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1.1, stop: 0.1 %%HIGHLIGHTDISABLECOLOR%%, stop: 1 transparent);
-}
-LTBWidget#WindowAttention{
- background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1.1, stop: 0.1 %%HIGHLIGHTCOLOR%%, stop: 1 transparent);
-}
-LTBWidget:hover, LTBWidget#WindowVisible:hover, LTBWidget#WindowInvisible:hover, LTBWidget#WindowActive:hover, LTBWidget#WindowAttention:hover, QToolButton:hover{
- background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1.1, stop: 0.1 %%HIGHLIGHTCOLOR%%, stop: 1 transparent);
- color: %%TEXTHIGHLIGHTCOLOR%%;
- border-width: 1px;
- border-style: solid;
- border-top-color: qradialgradient(spread:pad, cx:0.5, cy:1, radius:0.5, fx:0.5, fy:1, stop:0 rgba(255, 255, 255, 30), stop:0.724868 rgba(255, 255, 255, 60), stop:1 rgba(255, 255, 255, 10));
- border-bottom-color: qradialgradient(spread:pad, cx:0.5, cy:0, radius:0.5, fx:0.5, fy:0, stop:0 rgba(255, 255, 255, 30), stop:0.724868 rgba(255, 255, 255, 60), stop:1 rgba(255, 255, 255, 10));
- border-left-color: qradialgradient(spread:pad, cx:1, cy:0.5, radius:0.5, fx:1, fy:0.5, stop:0 rgba(255, 255, 255, 30), stop:0.724868 rgba(255, 255, 255, 60), stop:1 rgba(255, 255, 255, 10));
- border-right-color: qradialgradient(spread:pad, cx:0, cy:0.5, radius:0.5, fx:1, fy:0.5, stop:0 rgba(255, 255, 255, 30), stop:0.724868 rgba(255, 255, 255, 60), stop:1 rgba(255, 255, 255, 10));
-}
-/* CALENDER WIDGET */
- /* (This is a special hack since there is no official support for stylesheets for this widget) */
- QCalendarWidget QWidget#qt_calendar_navigationbar{
- background-color: %%ALTBASECOLOR%%;
- }
-QCalendarWidget QWidget{
- background-color: %%BASECOLOR%%;
- alternate-background-color: rgba(255, 255, 255, 50);
- color: %%TEXTCOLOR%%;
-}
-QCalendarWidget QAbstractButton{
- background-color: transparent;
-}
-QCalendarWidget QAbstractButton::menu-indicator{
- image: none;
-}
-QCalendarWidget QAbstractItemView{
- selection-background-color: qradialgradient(spread:reflect, cx:0.113757, cy:0.875, radius:0.7, fx:0.045, fy:0.954545, stop:0 rgba(234, 236, 243, 20), stop:1 rgba(229, 229, 229, 100));
- selection-color: %%TEXTHIGHLIGHTCOLOR%%;
-}
-QCalendarWidget QWidget#qt_calendar_calendarview{
- background-color: rgb(220,220,220);
- border: none;
-}
diff --git a/src-qt5/core/libLumina/themes/Lumina-default.qss.template b/src-qt5/core/libLumina/themes/Lumina-default.qss.template
deleted file mode 100644
index 9f03d4ae..00000000
--- a/src-qt5/core/libLumina/themes/Lumina-default.qss.template
+++ /dev/null
@@ -1,494 +0,0 @@
-/* ALL THE TEMPLATE WIDGETS */
-INHERITS=None
-
-/* ALL THE WIDGETS WITH THE BASE COLOR */
-QMainWindow, QMenu, QDialog, QMessageBox{
- background: %%BASECOLOR%%;
- color: %%TEXTCOLOR%%;
-}
-
-/* ALL THE WIDGETS WITH AN ALTERNATE BASE COLOR */
-QLineEdit, QTextEdit, QTextBrowser, QPlainTextEdit, QSpinBox, QDateEdit, QDateTimeEdit, QTimeEdit, QDoubleSpinBox{
- background: %%ALTBASECOLOR%%;
- color: %%TEXTCOLOR%%;
- border-color: %%ACCENTDISABLECOLOR%%;
- selection-background-color: %%HIGHLIGHTCOLOR%%;
- selection-color: %%TEXTHIGHLIGHTCOLOR%%;
-
-}
-
-/* PAGES OF CONTAINER WIDGETS */
-QStackedWidget .QWidget, QTabWidget .QWidget{
- background: %%ALTBASECOLOR%%;
- color: %%TEXTCOLOR%%;
- border: none;
-}
-QToolBox::tab{
- color: %%TEXTCOLOR%%;
-}
-
-/* MENU WIDGETS */
-QMenuBar, QMenuBar::item,QToolBar{
- background: %%SECONDARYCOLOR%%;
- border: none;
- color: %%TEXTCOLOR%%;
-}
-
-QStatusBar{
- background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 transparent, stop: 0.5 %%SECONDARYCOLOR%%);
- border: none;
- color: %%TEXTCOLOR%%;
-}
-QToolBar:top{
- border-bottom: 1px solid %%ACCENTCOLOR%%;
-}
-QToolBar:bottom{
- border-top: 1px solid %%ACCENTCOLOR%%;
-}
-QToolBar:left{
- border-right: 1px solid %%ACCENTCOLOR%%;
-}
-QToolBar:right{
- border-left: 1px solid %%ACCENTCOLOR%%;
-}
-
-QMenuBar::item{
- background: transparent; /*Use the menu bar color*/
- padding-left: 4px;
- padding-right: 2px;
-}
-
-QMenuBar::item:selected, QMenuBar::item:pressed, QMenu::item:selected{
-background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%HIGHLIGHTDISABLECOLOR%%, stop: 1 %%HIGHLIGHTCOLOR%%);
-color: %%TEXTHIGHLIGHTCOLOR%%;
-border: 1px solid %%ACCENTCOLOR%%;
-}
-QMenuBar::item:disabled{
- color: %%TEXTDISABLECOLOR%%;
-}
-
-QMenu::item{
- border: 2px solid #808080;
-}
-
-QMenu::item{
- background: transparent;
- border: 1px solid transparent;
- color: %%TEXTCOLOR%%;
- padding: 4px 30px 4px 20px;
- margin-left: 3px;
- margin-right: 3px;
-}
-
-/* TAB WIDGETS */
-/*QTabBar{
- Custom Font settings need to be here and NOT in the ::tab fields,
- otherwise it will break auto-scaling of the tab sizes to fit the text
-}*/
-QTabBar::tab {
- background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%SECONDARYDISABLECOLOR%%, stop: 1 %%SECONDARYCOLOR%%);
- border: 1px solid %%ACCENTCOLOR%%;
- padding: 2px;
- color: %%TEXTCOLOR%%;
-}
-QTabBar::tab:top{
- border-top-left-radius: 4px;
- border-top-right-radius: 4px;
- max-width: 100em;
- min-width: 0em;
-}
-QTabBar::tab:bottom{
- border-bottom-left-radius: 4px;
- border-bottom-right-radius: 4px;
- max-width: 100em;
- min-width: 0em;
-}
-/* left/right tab indicators appear to be reversed in Qt*/
-QTabBar::tab:right{
- border-top-left-radius: 4px;
- border-bottom-left-radius: 4px;
- max-height: 100em;
- min-height: 0em;
-}
-QTabBar::tab:left{
- border-top-right-radius: 4px;
- border-bottom-right-radius: 4px;
- max-height: 100em;
- min-height: 0em;
-}
-QTabBar::tab:selected{
- background: %%HIGHLIGHTDISABLECOLOR%%;
-}
-QTabBar::tab:hover {
- background: %%HIGHLIGHTCOLOR%%;
- border: 1px solid %%ACCENTDISABLECOLOR%%;
- }
-
-QTabBar::tab:!selected:top {
- margin-top: 4px;
-}
-QTabBar::tab:!selected:bottom{
- margin-bottom: 4px;
-}
-QTabBar::tab:!selected:right{
- margin-left: 4px;
-}
-QTabBar::tab:!selected:left{
- margin-right: 4px;
-}
-
-/* FRAME WIDGETS */
-QToolTip{
- background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%BASECOLOR%%, stop: 1 %%ALTBASECOLOR%%);
- border-radius: 3px;
- border: 1px solid %%ACCENTCOLOR%%;
- padding: 1px;
- color: %%TEXTCOLOR%%;
-}
-
-QLabel{
- background: transparent;
- border: none;
- color: %%TEXTCOLOR%%;
-}
-QAbstractButton::disabled{
- color: %%TEXTDISABLECOLOR%%;
-}
-
-/* GROUP BOX */
-QGroupBox{
- background-color: transparent;
- border-color: %%ACCENTCOLOR%%;
- border-radius: 5px;
- margin-top: 2ex;
- font-weight: bold;
-}
-QGroupBox::title{
- subcontrol-origin: margin;
- subcontrol-position: top center;
- padding: 0 3px;
- background: transparent;
- /*border: none;*/
- color: %%TEXTCOLOR%%;
-}
-
-/* COMBO BOX */
-QComboBox{
- /*border: 1px solid %%ACCENTCOLOR%%;
- border-radius: 3px;
- padding: 1px 18px 1px 3px;*/
- color: %%TEXTCOLOR%%;
- background: %%ALTBASECOLOR%%;
- selection-background-color: %%HIGHLIGHTCOLOR%%;
- }
-
-
-/* VIEW WIDGETS */
-QTreeView, QListView{
- background: %%ALTBASECOLOR%%;
- alternate-background-color: %%BASECOLOR%%;
- /*selection-background-color: %%SECONDARYCOLOR%%;*/
- border: 1px solid %%ACCENTCOLOR%%;
- border-radius: 3px;
- /*show-decoration-selected: 1;*/
- color: %%TEXTCOLOR%%;
- selection-color: %%TEXTCOLOR%%;
-}
-
-QTreeView:focus, QListView:focus{
- border: 1px solid %%HIGHLIGHTDISABLECOLOR%%;
-}
-
-/*
-QTreeView::item and QListView::item unneccessary:
-Already set though parentage and causes usage errors if set manually
-*/
-
-/*QTreeView::item:selected, QListView::item:selected{
- background: %%SECONDARYDISABLECOLOR%%;
- border-color: %%ACCENTCOLOR%%;
- color: %%TEXTCOLOR%%;
-}*/
-
-QTreeView::item:hover, QListView::item:hover{
- background: %%HIGHLIGHTDISABLECOLOR%%;
-}
-QTreeView::item:selected:hover, QListView::item:selected:hover{
- background: %%HIGHLIGHTDISABLECOLOR%%;
-}
-QTreeView::item:selected, QListView::item:selected{
- background: %%SECONDARYDISABLECOLOR%%;
-}
-QTreeView::item:selected:focus, QListView::item:selected:focus{
- background: %%SECONDARYCOLOR%%;
-}
-QHeaderView{
- background: %%HIGHLIGHTDISABLECOLOR%%;
- color: %%TEXTHIGHLIGHTCOLOR%%;
- border: none;
- border-top-left-radius: 3px; /*match the list/tree view widgets*/
- border-top-right-radius: 3px; /*match the list/tree view widgets*/
-}
-QHeaderView::section{
- background: %%HIGHLIGHTDISABLECOLOR%%; /*QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%PRIMARYDISABLECOLOR%%, stop: 1 %%PRIMARYCOLOR%%);*/
- color: %%TEXTHIGHLIGHTCOLOR%%;
- border-color: %%ACCENTCOLOR%%;
- padding: 1px;
- padding-left: 4px;
-}
-QHeaderView::section:hover{
- background: %%PRIMARYCOLOR%%;
- border-color: %%ACCENTDISABLECOLOR%%;
- color: %%TEXTCOLOR%%;
-}
-
-/* SCROLLBARS (NOTE: Changing 1 subcontrol means you have to change all of them)*/
-QScrollBar{
- background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %%SECONDARYCOLOR%%, stop: 1 %%SECONDARYDISABLECOLOR%%);
- /*border: 1px solid %%ACCENTCOLOR%%;*/
-}
-QScrollBar:horizontal{
- margin: 0px 20px 0px 20px;
-}
-QScrollBar:vertical{
- margin: 20px 0px 20px 0px;
-}
-QScrollBar::sub-page, QScrollBar::add-page{
- background: %%BASECOLOR%%;
- border: 1px solid %%ACCENTCOLOR%%;
-}
-QScrollBar::sub-page:vertical{
- border-bottom: none;
-}
-QScrollBar::add-page:vertical{
- border-top: none;
-}
-QScrollBar::sub-page:horizontal{
- border-right: none;
-}
-QScrollBar::add-page:horizontal{
- border-left: none;
-}
-QScrollBar::handle{
- background: QLinearGradient(x1: 0, y1: -0.3, x2: 0, y2: 1.3, stop: 0 %%BASECOLOR%%, stop: 0.5 %%SECONDARYCOLOR%%, stop: 1 %%BASECOLOR%%);
- border: 1px solid %%ACCENTCOLOR%%;
-}
-QScrollBar::handle:hover, QScrollBar::add-line:hover, QScrollBar::sub-line:hover{
- background: %%HIGHLIGHTCOLOR%%;
-}
-QScrollBar::add-line{
- background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %%SECONDARYDISABLECOLOR%%, stop: 1 %%SECONDARYCOLOR%%);
- border: 1px solid %%ACCENTCOLOR%%;
- border-radius: 3px;
-subcontrol-position: bottom right;
-subcontrol-origin: margin;
-}
-QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical{
-height: 20px;
-}
-QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal{
-width: 20px;
-}
-QScrollBar::sub-line{
- background: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %%SECONDARYCOLOR%%, stop: 1 %%SECONDARYDISABLECOLOR%%);
- border: 1px solid %%ACCENTCOLOR%%;
- border-radius: 3px;
-subcontrol-position: top left;
-subcontrol-origin: margin;
-height: 20px;
-}
-/* SLIDERS */
-QSlider::groove:horizontal {
-border: 1px solid %%ACCENTCOLOR%%;
-background: %%ALTBASECOLOR%%;
-height: 10px;
-border-radius: 3px;
-}
-QSlider::groove:vertical {
-border: 1px solid %%ACCENTCOLOR%%;
-background: %%ALTBASECOLOR%%;
-width: 10px;
-border-radius: 3px;
-}
-QSlider::sub-page:horizontal {
-background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1,
- stop: 0 %%HIGHLIGHTCOLOR%%, stop: 1 %%HIGHLIGHTDISABLECOLOR%%);
-border: 1px solid %%ACCENTCOLOR%%;
-height: 10px;
-border-radius: 3px;
-}
-QSlider::sub-page:vertical {
-background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1,
- stop: 0 %%HIGHLIGHTCOLOR%%, stop: 1 %%HIGHLIGHTDISABLECOLOR%%);
-border: 1px solid %%ACCENTCOLOR%%;
-width: 10px;
-border-radius: 3px;
-}
-QSlider::add-page:horizontal{
-background: %%ALTBASECOLOR%%;
-border: 1px solid %%ACCENTCOLOR%%;
-height: 10px;
-border-radius: 3px;
-}
-QSlider::add-page:vertical{
-background: %%ALTBASECOLOR%%;
-border: 1px solid %%ACCENTCOLOR%%;
-width: 10px;
-border-radius: 3px;
-}
-QSlider::handle:horizontal{
-background: %%ALTBASECOLOR%%;
-border: 1px solid %%ACCENTCOLOR%%;
-width: 13px;
-border-radius: 4px;
-}
-QSlider::handle:vertical{
-background: %%ALTBASECOLOR%%;
-border: 1px solid %%ACCENTCOLOR%%;
-height: 13px;
-border-radius: 4px;
-}
-QSlider::handle:horizontal:hover, QSlider::handle:vertical:hover{
-border: 1px solid %%ACCENTDISABLECOLOR%%;
-/*background: %%HIGHLIGHTCOLOR%%;*/
-}
-
-QSlider::sub-page:horizontal:disabled {
-background: %%ACCENTDISABLECOLOR%%;
-border-color: %%ACCENTCOLOR%%;
-}
-
-QSlider::add-page:horizontal:disabled {
-background: %%ACCENTDISABLECOLOR%%;
-border-color: %%ACCENTCOLOR%%;
-}
-
-QSlider::handle:horizontal:disabled {
-background: %%ALTBASECOLOR%%;
-border: 1px solid %%ACCENTCOLOR%%;
-}
-
-/* BUTTONS */
-QPushButton{
- border: 1px solid %%ACCENTCOLOR%%;
- border-radius: 3px;
- background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%SECONDARYDISABLECOLOR%%, stop: 1 %%SECONDARYCOLOR%%);
- padding: 2px;
- padding-right: 4px;
- color: %%TEXTCOLOR%%;
- }
-
-QToolButton{ /* Assume a flat button for every toolbutton by default*/
- color: %%TEXTCOLOR%%;
- border: 1px solid transparent;
- border-radius: 3px;
- background-color: transparent;
- padding: 1px;
-}
-
- QPushButton:pressed, QPushButton:open, QPushButton:selected, QPushButton:checked, QPushButton:on, QToolButton:pressed, QToolButton:open, QToolButton:selected, QToolButton:checked, QToolButton:on{
- background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%HIGHLIGHTDISABLECOLOR%%, stop: 1 %%HIGHLIGHTCOLOR%%);
- margin-top: 2px;
- }
-
-QPushButton:flat, QToolButton:flat{
- background-color: transparent;
- border: 1px solid transparent; /* no border for a flat button */
-}
-
-QPushButton:hover, QToolButton:hover{
- border: 1px solid %%ACCENTCOLOR%%;
- background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%HIGHLIGHTDISABLECOLOR%%, stop: 1 %%HIGHLIGHTCOLOR%%);
- color: %%TEXTHIGHLIGHTCOLOR%%;
-}
-QRadioButton, QCheckBox{
- padding: 2px;
- border: 1px solid transparent;
- border-radius: 3px;
- color: %%TEXTCOLOR%%;
-}
-QRadioButton::hover, QCheckBox:hover{
- background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%HIGHLIGHTDISABLECOLOR%%, stop: 1 %%HIGHLIGHTCOLOR%%);
- border: 1px solid %%ACCENTCOLOR%%;
- color: %%TEXTHIGHLIGHTCOLOR%%;
-}
-QRadioButton::indicator, QCheckBox::indicator, QGroupBox::indicator{
- border: 1px solid %%TEXTCOLOR%%;
-}
-QRadioButton::indicator{
- border-radius: 7px;
-}
-QRadioButton::indicator:checked{
- background: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:1, fx:0.5, fy:0.5, stop:0 %%TEXTCOLOR%%, stop:0.25 %%TEXTCOLOR%%, stop:0.25001 transparent);
-}
-QCheckBox::indicator:checked, QGroupBox::indicator:checked{
- padding: 1px;
- background-origin: content;
- background-clip: content;
- background: %%TEXTCOLOR%%;
-}
-QCheckBox::indicator:indeterminate, QGroupBox::indicator:indeterminate{
- padding: 1px;
- background-origin: content;
- background-clip: content;
- background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0.49 transparent, stop: 0.5 %%TEXTCOLOR%%);
-}
-
-/* PROGRESSBAR */
-QProgressBar{
- background-color: %%ALTBASECOLOR%%;
- border: 1px solid %%ACCENTCOLOR%%;
- border-radius: 5px;
- color: %%TEXTCOLOR%%;
- text-align: center;
- padding: 1px;
-}
- QProgressBar::chunk {
- background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%HIGHLIGHTCOLOR%%, stop: 1 %%HIGHLIGHTDISABLECOLOR%%);
- /*border: 1px solid %%ACCENTDISABLECOLOR%%;*/
- border-radius: 5px;
- }
-QProgressBar::chunk:vertical{
- margin-left: 2px;
- margin-right: 2px;
-}
-QProgressBar::chunk:horizontal{
- margin-top: 2px;
- margin-bottom: 2px;
-}
-
- /* SPINBOX */
-/*QAbstractSpinBox{
- background-color: %%ALTBASECOLOR%%;
- border: 1px solid %%ACCENTCOLOR%%;
- border-radius: 3px;
-}
-QAbstractSpinBox:disabled{
- color: %%ACCENTDISABLECOLOR%%;
-}*/
-/*QAbstractSpinBox::down-button{
- subcontrol-origin: border;
- subcontrol-position: left;
- width: 16px;
- border-width: 1px;
-}
-QAbstractSpinBox::up-button{
- subcontrol-origin: border;
- subcontrol-position: right;
- width: 16px;
- border-width: 1px;
-}*/
-/*
-QAbstractSpinBox::down-arrow{
- border-image: url(":/trolltech/styles/commonstyle/images/left-16.png");
- width: 16px;
- height: 16px;
-}
-QAbstractSpinBox::down-arrow:disabled, QAbstractSpinBox::up-arrow:disabled, QAbstractSpinBox::down-arrow:off, QAbstractSpinBox::up-arrow:off{
- border-image: url(:/none);
-}
-QAbstractSpinBox::up-arrow{
- border-image: url(":/trolltech/styles/commonstyle/images/right-16.png");
- width: 16px;
- height: 16px;
-}*/
diff --git a/src-qt5/core/libLumina/themes/None.qss.template b/src-qt5/core/libLumina/themes/None.qss.template
deleted file mode 100644
index 7d923b1e..00000000
--- a/src-qt5/core/libLumina/themes/None.qss.template
+++ /dev/null
@@ -1,118 +0,0 @@
-/* This is a blank stylesheet to disable the Lumina Themes almost entirely*/
-QWidget{
- font-family: %%FONT%%;
- font-size: %%FONTSIZE%%;
-}
-/* Set the panel appearance for this theme (unless manually customized) */
-QWidget#LuminaPanelColor{
- background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 %%PRIMARYCOLOR%%, stop: 1 %%PRIMARYDISABLECOLOR%%);
- border-radius: 5px;
-}
-QWidget#LuminaBootSplash{
- background: %%BASECOLOR%%;
- border-radius: 5px;
-}
-
-/* Set the default canvas appearance for Lumina desktop plugins*/
-/* Default to a non-transparent background for all desktop plugins*/
-LDPlugin{
- background: %%BASECOLOR%%;
- border-radius: 5px;
-}
-/* Now specify which plugins should have a transparent background */
-LDPlugin#applauncher, LDPlugin#desktopview{
- background: transparent;
- border-radius: 5px;
-}
-
-LDPlugin#applauncher QToolButton{
-background: transparent;
- border: none;
- border-radius: 5px;
- color: white;
-}
-LDPlugin#applauncher QToolButton:hover{
- background: %%PRIMARYDISABLECOLOR%%;
- border: none;
- border-radius: 5px;
- color: %%TEXTHIGHLIGHTCOLOR%%;
-}
-
-LDPlugin#desktopview QListWidget{
- background: transparent;
- border: 1px solid transparent;
-}
-LDPlugin#desktopview QListWidget::item{
- background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
- stop: 0 transparent,
- stop: 0.7 transparent,
- stop: 1.0 %%PRIMARYDISABLECOLOR%%);
- border-radius: 5px;
- color: %%TEXTCOLOR%%;
-}
-
-LDPlugin#desktopview QListWidget::item:hover{
- background: %%PRIMARYDISABLECOLOR%%;
- border-radius: 5px;
- color: %%TEXTHIGHLIGHTCOLOR%%;
-}
-/*For the special widgets on the user button*/
-UserItemWidget, ItemWidget{
- background: transparent;
- border-radius: 3px;
-}
-UserItemWidget:hover, ItemWidget:hover{
- background: %%HIGHLIGHTCOLOR%%;
- color: %%TEXTHIGHLIGHTCOLOR%%;
-}
-
-/*Special taskmanager window buttons: based on window state*/
-LTBWidget{
- border: 1px solid transparent;
- border-radius: 3px;
-}
-LTBWidget::menu-indicator{ image: none; } /*disable the menu arrow*/
-LTBWidget#WindowVisible{
- background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1.1, stop: 0.3 %%SECONDARYCOLOR%%, stop: 1 transparent);
-}
-LTBWidget#WindowInvisible{
- /* Primary color is used for the panel appearance, so use that to make it disappear*/
- background: transparent;
-}
-LTBWidget#WindowActive{
- background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1.1, stop: 0.3 %%HIGHLIGHTDISABLECOLOR%%, stop: 1 transparent);
-}
-LTBWidget#WindowAttention{
- background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1.1, stop: 0.3 %%HIGHLIGHTCOLOR%%, stop: 1 transparent);
-}
-LTBWidget:hover, LTBWidget#WindowVisible:hover, LTBWidget#WindowInvisible:hover, LTBWidget#WindowActive:hover, LTBWidget#WindowAttention:hover{
- background: %%HIGHLIGHTCOLOR%%;
- color: %%TEXTHIGHLIGHTCOLOR%%;
- border: 1px solid %%ACCENTCOLOR%%;
-}
-
-/* CALENDER WIDGET */
- /* (This is a special hack since there is no official support for stylesheets for this widget) */
- QCalendarWidget QWidget#qt_calendar_navigationbar{
- background-color: %%ALTBASECOLOR%%;
- }
-QCalendarWidget QWidget{
- background-color: %%BASECOLOR%%;
- alternate-background-color: %%HIGHLIGHTDISABLECOLOR%%;
- color: %%TEXTCOLOR%%;
-}
-QCalendarWidget QAbstractButton{
- background-color: transparent;
-}
-QCalendarWidget QAbstractButton::menu-indicator{
- image: none;
-}
-QCalendarWidget QAbstractItemView{
- background-color: %%SECONDARYCOLOR%%;
- selection-background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 %%HIGHLIGHTDISABLECOLOR%%, stop: 1 %%HIGHLIGHTCOLOR%%);;
- selection-color: %%TEXTHIGHLIGHTCOLOR%%;
-}
-QCalendarWidget QWidget#qt_calendar_calendarview{
- background-color: %%ALTBASECOLOR%%;
- border: none;
-} \ No newline at end of file
bgstack15