aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Moore <moorekou@gmail.com>2015-07-22 16:10:11 -0400
committerKen Moore <moorekou@gmail.com>2015-07-22 16:10:11 -0400
commitb38f4f6ce26fd50cc7fac1d1b0c09ab22ee4e3ea (patch)
tree38bdba92c2ebd4bf462810c7ae7b5b58e42a231d
parentAdd support into libLumina for additional "Actions" listed in *.desktop files. (diff)
downloadlumina-b38f4f6ce26fd50cc7fac1d1b0c09ab22ee4e3ea.tar.gz
lumina-b38f4f6ce26fd50cc7fac1d1b0c09ab22ee4e3ea.tar.bz2
lumina-b38f4f6ce26fd50cc7fac1d1b0c09ab22ee4e3ea.zip
Finish up the XDG "Actions" specification for *.desktop files, and integrate it into the AppMenu and UserButton. Also add a new flag to lumina-open so that we can specify which action to use when starting an app.
-rw-r--r--libLumina/LuminaXDG.cpp34
-rw-r--r--libLumina/LuminaXDG.h2
-rw-r--r--lumina-desktop/AppMenu.cpp35
-rw-r--r--lumina-desktop/panel-plugins/userbutton/UserItemWidget.cpp35
-rw-r--r--lumina-desktop/panel-plugins/userbutton/UserItemWidget.h5
-rw-r--r--lumina-desktop/panel-plugins/userbutton/UserWidget.cpp2
-rw-r--r--lumina-open/main.cpp8
7 files changed, 96 insertions, 25 deletions
diff --git a/libLumina/LuminaXDG.cpp b/libLumina/LuminaXDG.cpp
index 19a3fbae..d2b6ef41 100644
--- a/libLumina/LuminaXDG.cpp
+++ b/libLumina/LuminaXDG.cpp
@@ -25,25 +25,21 @@ XDGDesktop LXDG::loadDesktopFile(QString filePath, bool& ok){
DF.filePath = filePath;
DF.lastRead = QDateTime::currentDateTime();
DF.exec = DF.tryexec = ""; // just to make sure this is initialized
- //Check input file path validity
- //QFile file(filePath);
- //if(!file.exists()){ return DF; } //invalid file
+
//Get the current localization code
QString lang = QLocale::system().name(); //lang code
QString slang = lang.section("_",0,0); //short lang code
- //Open the file
- //if(!file.open(QIODevice::Text | QIODevice::ReadOnly)){
- //return DF;
- //}
- //QTextStream os(&file);
+
//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;
@@ -57,13 +53,14 @@ XDGDesktop LXDG::loadDesktopFile(QString filePath, bool& ok){
CDA.ID = line.section("]",0,0).section("Desktop Action",1,1).simplified();
inaction = true;
continue;
- }else if(!insection || !inaction || line.startsWith("#")){ 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){
@@ -415,14 +412,25 @@ QList<XDGDesktop> LXDG::sortDesktopNames(QList<XDGDesktop> apps){
return out;
}
-QString LXDG::getDesktopExec(XDGDesktop app){
+QString LXDG::getDesktopExec(XDGDesktop app, QString ActionID){
//Generate the executable line for the application
QString out;
- if(app.exec.isEmpty()){ return ""; }
+ 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){
- out = "xterm -lc -e "+app.exec;
+ out = "xterm -lc -e "+exec;
}else{
- out = app.exec;
+ 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+"\'"); }
diff --git a/libLumina/LuminaXDG.h b/libLumina/LuminaXDG.h
index 879d905a..b99b3015 100644
--- a/libLumina/LuminaXDG.h
+++ b/libLumina/LuminaXDG.h
@@ -81,7 +81,7 @@ public:
//Sort a list of Desktop files by name
static QList<XDGDesktop> sortDesktopNames(QList<XDGDesktop> apps);
//Get the executable line from a Desktop file
- static QString getDesktopExec(XDGDesktop);
+ 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
diff --git a/lumina-desktop/AppMenu.cpp b/lumina-desktop/AppMenu.cpp
index 507f8f06..dec9422e 100644
--- a/lumina-desktop/AppMenu.cpp
+++ b/lumina-desktop/AppMenu.cpp
@@ -82,10 +82,31 @@ void AppMenu::updateAppList(){
connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(launchApp(QAction*)) );
QList<XDGDesktop> appL = APPS.value(cats[i]);
for( int a=0; a<appL.length(); a++){
- QAction *act = new QAction(LXDG::findIcon(appL[a].icon, ""), appL[a].name, this);
- act->setToolTip(appL[a].comment);
- act->setWhatsThis(appL[a].filePath);
- menu->addAction(act);
+ if(appL[a].actions.isEmpty()){
+ //Just a single entry point - no extra actions
+ QAction *act = new QAction(LXDG::findIcon(appL[a].icon, ""), appL[a].name, this);
+ act->setToolTip(appL[a].comment);
+ act->setWhatsThis(appL[a].filePath);
+ menu->addAction(act);
+ }else{
+ //This app has additional actions - make this a sub menu
+ // - first the main menu/action
+ QMenu *submenu = new QMenu(appL[a].name, this);
+ submenu->setIcon( LXDG::findIcon(appL[a].icon,"") );
+ //This is the normal behavior - not a special sub-action (although it needs to be at the top of the new menu)
+ QAction *act = new QAction(LXDG::findIcon(appL[a].icon, ""), appL[a].name, this);
+ act->setToolTip(appL[a].comment);
+ act->setWhatsThis(appL[a].filePath);
+ submenu->addAction(act);
+ //Now add entries for every sub-action listed
+ for(int sa=0; sa<appL[a].actions.length(); sa++){
+ QAction *sact = new QAction(LXDG::findIcon(appL[a].actions[sa].icon, appL[a].icon), appL[a].actions[sa].name, this);
+ sact->setToolTip(appL[a].comment);
+ sact->setWhatsThis("-action \""+appL[a].actions[sa].ID+"\" \""+appL[a].filePath+"\"");
+ submenu->addAction(sact);
+ }
+ menu->addMenu(submenu);
+ }
}
this->addMenu(menu);
}
@@ -121,5 +142,9 @@ void AppMenu::launchFileManager(){
void AppMenu::launchApp(QAction *act){
QString appFile = act->whatsThis();
- LSession::LaunchApplication("lumina-open \""+appFile+"\"");
+ if(appFile.startsWith("-action")){
+ LSession::LaunchApplication("lumina-open "+appFile); //already has quotes put in place properly
+ }else{
+ LSession::LaunchApplication("lumina-open \""+appFile+"\"");
+ }
}
diff --git a/lumina-desktop/panel-plugins/userbutton/UserItemWidget.cpp b/lumina-desktop/panel-plugins/userbutton/UserItemWidget.cpp
index ff77121e..76a0b4cf 100644
--- a/lumina-desktop/panel-plugins/userbutton/UserItemWidget.cpp
+++ b/lumina-desktop/panel-plugins/userbutton/UserItemWidget.cpp
@@ -6,6 +6,7 @@
//===========================================
#include "UserItemWidget.h"
#include <LuminaUtils.h>
+#include <QMenu>
#define TEXTCUTOFF 165
UserItemWidget::UserItemWidget(QWidget *parent, QString itemPath, QString type, bool goback) : QFrame(parent){
@@ -19,11 +20,14 @@ UserItemWidget::UserItemWidget(QWidget *parent, QString itemPath, QString type,
if(ok){
icon->setPixmap( LXDG::findIcon(item.icon, "preferences-system-windows-actions").pixmap(32,32) );
name->setText( this->fontMetrics().elidedText(item.name, Qt::ElideRight, TEXTCUTOFF) );
+ setupActions(item);
}else{
icon->setPixmap( LXDG::findIcon("unknown","").pixmap(32,32) );
name->setText( this->fontMetrics().elidedText(itemPath.section("/",-1), Qt::ElideRight, TEXTCUTOFF) );
+ actButton->setVisible(false);
}
}else if(type=="dir"){
+ actButton->setVisible(false);
if(itemPath.endsWith("/")){ itemPath.chop(1); }
if(goback){
icon->setPixmap( LXDG::findIcon("go-previous","").pixmap(32,32) );
@@ -33,6 +37,7 @@ UserItemWidget::UserItemWidget(QWidget *parent, QString itemPath, QString type,
name->setText( this->fontMetrics().elidedText(itemPath.section("/",-1), Qt::ElideRight, TEXTCUTOFF) );
}
}else{
+ actButton->setVisible(false);
if(itemPath.endsWith("/")){ itemPath.chop(1); }
if(QFileInfo(itemPath).isDir()){
type = "dir";
@@ -75,9 +80,9 @@ UserItemWidget::UserItemWidget(QWidget *parent, XDGDesktop item) : QFrame(parent
name->setText( this->fontMetrics().elidedText(item.name, Qt::ElideRight, TEXTCUTOFF) );
this->setWhatsThis(name->text());
icon->setWhatsThis(item.filePath);
- //Now setup the button appropriately
+ //Now setup the buttons appropriately
setupButton();
-
+ setupActions(item);
}
UserItemWidget::~UserItemWidget(){
@@ -93,12 +98,17 @@ void UserItemWidget::createWidget(){
button = new QToolButton(this);
button->setIconSize( QSize(14,14) );
button->setAutoRaise(true);
+ actButton = new QToolButton(this);
+ actButton->setPopupMode(QToolButton::InstantPopup);
+ actButton->setFixedSize( QSize(17,34) );
+ actButton->setArrowType(Qt::DownArrow);
icon = new QLabel(this);
icon->setFixedSize( QSize(34,34) );
name = new QLabel(this);
//Add them to the layout
this->setLayout(new QHBoxLayout());
this->layout()->setContentsMargins(1,1,1,1);
+ this->layout()->addWidget(actButton);
this->layout()->addWidget(icon);
this->layout()->addWidget(name);
this->layout()->addWidget(button);
@@ -138,6 +148,19 @@ void UserItemWidget::setupButton(bool disable){
}
}
+void UserItemWidget::setupActions(XDGDesktop app){
+ if(app.actions.isEmpty()){ actButton->setVisible(false); return; }
+ //Actions Available - go ahead and list them all
+ actButton->setMenu( new QMenu(this) );
+ for(int i=0; i<app.actions.length(); i++){
+ QAction *act = new QAction(LXDG::findIcon(app.actions[i].icon, app.icon), app.actions[i].name, this);
+ act->setToolTip(app.actions[i].ID);
+ act->setWhatsThis(app.actions[i].ID);
+ actButton->menu()->addAction(act);
+ }
+ connect(actButton->menu(), SIGNAL(triggered(QAction*)), this, SLOT(actionClicked(QAction*)) );
+}
+
void UserItemWidget::buttonClicked(){
button->setVisible(false);
if(button->whatsThis()=="add"){
@@ -161,3 +184,11 @@ void UserItemWidget::ItemClicked(){
if(!linkPath.isEmpty()){ emit RunItem(linkPath); }
else{ emit RunItem(icon->whatsThis()); }
}
+
+void UserItemWidget::actionClicked(QAction *act){
+ actButton->menu()->hide();
+ QString cmd = "lumina-open -action \""+act->whatsThis()+"\" \"%1\"";
+ if(!linkPath.isEmpty()){ cmd = cmd.arg(linkPath); }
+ else{ cmd = cmd.arg(icon->whatsThis()); }
+ emit RunItem(cmd);
+} \ No newline at end of file
diff --git a/lumina-desktop/panel-plugins/userbutton/UserItemWidget.h b/lumina-desktop/panel-plugins/userbutton/UserItemWidget.h
index a65d3e83..b3c5aea7 100644
--- a/lumina-desktop/panel-plugins/userbutton/UserItemWidget.h
+++ b/lumina-desktop/panel-plugins/userbutton/UserItemWidget.h
@@ -18,6 +18,7 @@
#include <QDir>
#include <QFile>
#include <QMouseEvent>
+#include <QAction>
#include <LuminaXDG.h>
@@ -30,17 +31,19 @@ public:
~UserItemWidget();
private:
- QToolButton *button;
+ QToolButton *button, *actButton;
QLabel *icon, *name;
bool isDirectory, isShortcut;
QString linkPath;
void createWidget();
void setupButton(bool disable = false);
+ void setupActions(XDGDesktop);
private slots:
void buttonClicked();
void ItemClicked();
+ void actionClicked(QAction*);
protected:
void mouseReleaseEvent(QMouseEvent *event){
diff --git a/lumina-desktop/panel-plugins/userbutton/UserWidget.cpp b/lumina-desktop/panel-plugins/userbutton/UserWidget.cpp
index 92f6178b..5d1a2bc9 100644
--- a/lumina-desktop/panel-plugins/userbutton/UserWidget.cpp
+++ b/lumina-desktop/panel-plugins/userbutton/UserWidget.cpp
@@ -188,7 +188,7 @@ void UserWidget::UpdateMenu(bool forceall){
void UserWidget::LaunchItem(QString path, bool fix){
if(!path.isEmpty()){
qDebug() << "Launch Application:" << path;
- if(fix){ LSession::LaunchApplication("lumina-open \""+path+"\""); }
+ if( fix && !path.startsWith("lumina-open") ){ LSession::LaunchApplication("lumina-open \""+path+"\""); }
else{ LSession::LaunchApplication(path); }
emit CloseMenu(); //so the menu container will close
}
diff --git a/lumina-open/main.cpp b/lumina-open/main.cpp
index dd2b1c93..3acc4ee3 100644
--- a/lumina-open/main.cpp
+++ b/lumina-open/main.cpp
@@ -148,7 +148,7 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat
//Get the input file
//Make sure to load the proper system encoding first
LUtils::LoadTranslation(0,""); //bypass application modification
- QString inFile;
+ QString inFile, ActionID;
bool showDLG = false; //flag to bypass any default application setting
if(argc > 1){
for(int i=1; i<argc; i++){
@@ -184,6 +184,9 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat
showOSD(argc,argv, QString(QObject::tr("Screen Brightness %1%")).arg(QString::number(bright)) );
}
return;
+ }else if( (QString(argv[i]).simplified() =="-action") && (argc>(i+1)) ){
+ ActionID = QString(argv[i+1]);
+ i++; //skip the next input
}else{
inFile = QString::fromLocal8Bit(argv[i]);
break;
@@ -224,7 +227,7 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat
switch(DF.type){
case XDGDesktop::APP:
if(!DF.exec.isEmpty()){
- cmd = LXDG::getDesktopExec(DF);
+ cmd = LXDG::getDesktopExec(DF,ActionID);
if(!DF.path.isEmpty()){ path = DF.path; }
watch = DF.startupNotify;
}else{
@@ -254,6 +257,7 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat
}
break;
default:
+ qDebug() << DF.type << DF.name << DF.icon << DF.exec;
ShowErrorDialog( argc, argv, QString(QObject::tr("Unknown type of shortcut : %1")).arg(inFile) );
}
}
bgstack15