aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libLumina/LuminaUtils.cpp1
-rw-r--r--libLumina/LuminaXDG.cpp170
-rw-r--r--libLumina/LuminaXDG.h4
3 files changed, 169 insertions, 6 deletions
diff --git a/libLumina/LuminaUtils.cpp b/libLumina/LuminaUtils.cpp
index dd498559..e3aa6f13 100644
--- a/libLumina/LuminaUtils.cpp
+++ b/libLumina/LuminaUtils.cpp
@@ -78,6 +78,7 @@ bool LUtils::writeFile(QString filepath, QStringList contents, bool overwrite){
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;
}
diff --git a/libLumina/LuminaXDG.cpp b/libLumina/LuminaXDG.cpp
index 85a90aa9..78e56823 100644
--- a/libLumina/LuminaXDG.cpp
+++ b/libLumina/LuminaXDG.cpp
@@ -17,7 +17,7 @@ XDGDesktop LXDG::loadDesktopFile(QString filePath, bool& ok){
//Create the outputs
ok=false;
//following the specifications, Name and Type are the mandatory in any .desktop file
- bool hasName=false, hasType=false;
+ //bool hasName=false, hasType=false;
XDGDesktop DF;
DF.isHidden=false;
DF.useTerminal=false;
@@ -53,7 +53,7 @@ XDGDesktop LXDG::loadDesktopFile(QString filePath, bool& ok){
if(var=="Name"){
if(DF.name.isEmpty() && loc.isEmpty()){ DF.name = val; }
else if(loc == lang){ DF.name = val; }
- hasName = true;
+ //hasName = true;
}else if(var=="GenericName"){
if(DF.genericName.isEmpty() && loc.isEmpty()){ DF.genericName = val; }
else if(loc == lang){ DF.genericName = val; }
@@ -87,7 +87,7 @@ XDGDesktop LXDG::loadDesktopFile(QString filePath, bool& ok){
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;
+ //hasType = true;
}
} //end reading file
file.close();
@@ -109,10 +109,121 @@ XDGDesktop LXDG::loadDesktopFile(QString filePath, bool& ok){
DF.catList << "Wine"; //Internal Lumina category only (not in XDG specs as of 11/14/14)
}
//Return the structure
- if (hasName && hasType) ok = true; //without Name and Type, the structure cannot be a valid .desktop file
+ //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){
+ 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 = info.filter("Name=").first().section("=",1,50);
+ clearName=(tmp!=dFile.name);
+ tmp = info.filter("Comment=").first().section("=",1,50);
+ clearComment=(tmp!=dFile.comment);
+ 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;
@@ -142,6 +253,7 @@ bool LXDG::checkValidity(XDGDesktop dFile, bool showAll){
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.genericName.isEmpty()){ ok = false; }
}
return ok;
}
@@ -713,7 +825,7 @@ QList<XDGDesktop> LXDG::findAutoStartFiles(bool includeInvalid){
}else{
//Small override file (only the "Hidden" field listed in spec)
files[old].isHidden = desk.isHidden; //replace this value with the override
- files << desk; //still add this to the array (will be ignored/skipped later)
+ //files << desk; //still add this to the array (will be ignored/skipped later)
}
}else{
//This is a new autostart file
@@ -737,3 +849,51 @@ QList<XDGDesktop> LXDG::findAutoStartFiles(bool includeInvalid){
return files;
}
+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);
+ if(upath.isEmpty()){ upath = QDir::homePath()+"/.config/autostart/"; }
+ bool sysfile = false;
+ for(int i=0; i<paths.length(); i++){
+ 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);
+ }
+ }
+ //Make sure the user-autostart dir is specified, and clean the app structure as necessary
+ if( !app.filePath.startsWith(upath) && autostart){
+ //Some other non-override autostart file - set it up to open with lumina-open
+ if(!app.filePath.endsWith(".desktop")){
+ app.exec = "lumina-open \""+app.filePath+"\"";
+ app.tryexec = app.filePath; //make sure this file exists
+ if(app.name.isEmpty()){ app.name = app.filePath.section("/",-1); }
+ if(app.icon.isEmpty()){ app.icon = LXDG::findAppMimeForFile(app.filePath); }
+ app.filePath = upath+app.filePath.section("/",-1)+".desktop";
+ app.type = XDGDesktop::APP;
+ }else{
+ //Some other *.desktop file on the system
+ // - setup a redirect to the other file
+ app.exec = "lumina-open \""+app.filePath+"\"";
+ app.tryexec = app.filePath; //make sure this file exists
+ // - Adjust the actual path where this file will get saved
+ app.filePath = upath+app.filePath.section("/",-1);
+ }
+ }
+ //Now save the "hidden" value into the file
+ app.isHidden = !autostart; //if hidden, it will not be autostarted
+ //Now save the file as necessary
+ bool saved = false;
+ if(sysfile){
+ //Just an override file for the "hidden" field - nothing more
+ QStringList info;
+ info << "[Desktop Entry]" << "Type=Application" << QString("Hidden=")+ (app.isHidden ? QString("true"): QString("false"));
+ saved = LUtils::writeFile(app.filePath, info, true);
+ }else{
+ //Need to actually save the full file
+ saved = LXDG::saveDesktopFile(app);
+ }
+ return saved;
+}
+
diff --git a/libLumina/LuminaXDG.h b/libLumina/LuminaXDG.h
index e9a6081e..a66e3ad2 100644
--- a/libLumina/LuminaXDG.h
+++ b/libLumina/LuminaXDG.h
@@ -55,8 +55,9 @@ public:
class LXDG{
public:
- //Read a *.desktop file
+ //Read/write a *.desktop file
static XDGDesktop loadDesktopFile(QString filePath, bool& ok);
+ 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);
//Check for a valid executable
@@ -102,6 +103,7 @@ public:
//Find all the autostart *.desktop files
static QList<XDGDesktop> findAutoStartFiles(bool includeInvalid = false);
+ static bool setAutoStarted(bool autostart, XDGDesktop app);
};
#endif
bgstack15