aboutsummaryrefslogtreecommitdiff
path: root/src-qt5/core
diff options
context:
space:
mode:
authorKen Moore <ken@ixsystems.com>2017-03-02 09:43:19 -0500
committerKen Moore <ken@ixsystems.com>2017-03-02 09:43:19 -0500
commit33681a12eb754af6f057e8a6984db4af18dc010b (patch)
tree708a16ed1ce3ee80ac6cf1e61c77ccc9ac569b12 /src-qt5/core
parentUpdate the help text for lumina-open to include the "-action <ActionID>" synt... (diff)
downloadlumina-33681a12eb754af6f057e8a6984db4af18dc010b.tar.gz
lumina-33681a12eb754af6f057e8a6984db4af18dc010b.tar.bz2
lumina-33681a12eb754af6f057e8a6984db4af18dc010b.zip
Clean up some of the applauncher context menu functionality:
1) Add the ability for plugins to set their own high-priority context menu, and put the plugin modification menu into that as needed. 2) For the applauncher plugin, generate a custom context menu specifically for the file in question. This may include the various "actions" in .desktop files as appropriate, and also adds shortcuts for launch, open, open-with, file properties, and delete file.
Diffstat (limited to 'src-qt5/core')
-rw-r--r--src-qt5/core/libLumina/LuminaXDG.cpp4
-rw-r--r--src-qt5/core/libLumina/RootSubWindow.cpp6
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/LDPlugin.cpp32
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/LDPlugin.h11
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp51
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h9
-rw-r--r--src-qt5/core/lumina-open/main.cpp6
7 files changed, 91 insertions, 28 deletions
diff --git a/src-qt5/core/libLumina/LuminaXDG.cpp b/src-qt5/core/libLumina/LuminaXDG.cpp
index cbc90f25..f34bc0e8 100644
--- a/src-qt5/core/libLumina/LuminaXDG.cpp
+++ b/src-qt5/core/libLumina/LuminaXDG.cpp
@@ -59,7 +59,7 @@ void XDGDesktop::sync(){
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; }
+ 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();
@@ -131,6 +131,8 @@ void XDGDesktop::sync(){
else{ type = XDGDesktop::BAD; } //Unknown type
}
} //end reading file
+ if(!CDA.ID.isEmpty()){ actions << CDA; CDA = XDGDesktopAction(); } //if an action was still being read, add that to the list now
+
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) ){
diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp
index 7be89f48..e4c3c4ee 100644
--- a/src-qt5/core/libLumina/RootSubWindow.cpp
+++ b/src-qt5/core/libLumina/RootSubWindow.cpp
@@ -15,7 +15,7 @@ RootSubWindow::RootSubWindow(QMdiArea *root, NativeWindow *win) : QMdiSubWindow(
closing = false;
WinWidget = QWidget::createWindowContainer( WIN->window(), this);
this->setWidget(WinWidget);
- LoadProperties( QList< NativeWindow::Property>() << NativeWindow::WindowFlags << NativeWindow::Title << NativeWindow::Icon \
+ LoadProperties( QList< NativeWindow::Property>() << NativeWindow::Title << NativeWindow::Icon \
<< NativeWindow::MinSize << NativeWindow::MaxSize << NativeWindow::Size );
//Hookup the signals/slots
connect(this, SIGNAL(aboutToActivate()), this, SLOT(aboutToActivate()) );
@@ -89,9 +89,9 @@ void RootSubWindow::propertyChanged(NativeWindow::Property prop, QVariant val){
case NativeWindow::Active:
if(val.toBool()){ this->mdiArea()->setActiveSubWindow(this); }
break;
- case NativeWindow::WindowFlags:
+ /*case NativeWindow::WindowFlags:
this->setWindowFlags( val.value< Qt::WindowFlags >() );
- break;
+ break;*/
default:
qDebug() << "Window Property Unused:" << prop << val;
}
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/LDPlugin.cpp b/src-qt5/core/lumina-desktop/desktop-plugins/LDPlugin.cpp
index 545ba430..efae7b24 100644
--- a/src-qt5/core/lumina-desktop/desktop-plugins/LDPlugin.cpp
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/LDPlugin.cpp
@@ -16,6 +16,7 @@ LDPlugin::LDPlugin(QWidget *parent, QString id) : QFrame(parent){
settings = LSession::handle()->DesktopPluginSettings();
//Setup the plugin system control menu
menu = new QMenu(this);
+ contextM = 0;
setupMenu();
//Setup the internal timer for when to start/stop drag events
dragTimer = new QTimer(this);
@@ -33,11 +34,13 @@ LDPlugin::LDPlugin(QWidget *parent, QString id) : QFrame(parent){
void LDPlugin::setupMenu(){
menu->clear();
+ menu->setTitle(tr("Modify Item"));
+ menu->setIcon(LXDG::findIcon("preferences-desktop-icons","") );
//SPECIAL CONTEXT MENU OPTIONS FOR PARTICULAR PLUGIN TYPES
- if(PLUGID.startsWith("applauncher::")){
+ /*if(PLUGID.startsWith("applauncher::")){
menu->addAction( LXDG::findIcon("quickopen",""), tr("Launch Item"), this, SIGNAL(PluginActivated()) );
menu->addSeparator();
- }
+ }*/
//General Options
menu->addAction( LXDG::findIcon("transform-move",""), tr("Start Moving Item"), this, SLOT(slotStartMove()) );
menu->addAction( LXDG::findIcon("transform-scale",""), tr("Start Resizing Item"), this, SLOT(slotStartResize()) );
@@ -48,16 +51,17 @@ void LDPlugin::setupMenu(){
menu->addAction( LXDG::findIcon("edit-delete",""), tr("Remove Item"), this, SLOT(slotRemovePlugin()) );
}
-/*void LDPlugin::setInitialSize(int width, int height){
- //Note: Only run this in the plugin initization routine:
- // if the plugin is completely new (first time used), it will be this size
- if(settings->allKeys().filter(prefix+"location").isEmpty()){
- //Brand new plugin: set initial size
- //qDebug() << "Setting Initial Size:" << PLUGID << width << height;
- settings->setValue(prefix+"location/width",width);
- settings->setValue(prefix+"location/height",height);
- settings->sync();
+void LDPlugin::showPluginMenu(){
+ emit CloseDesktopMenu();
+ //Double check which menu should be shown
+ if(this->contextMenu()!=0){
+ //Got a special context menu for this plugin - need to layer them together
+ if(!this->contextMenu()->actions().contains(menu->menuAction())){
+ this->contextMenu()->addSeparator();
+ this->contextMenu()->addMenu(menu);
}
- //Now make sure the plugin is the saved size right away
- this->resize( settings->value(prefix+"location/width").toInt(), settings->value(prefix+"location/height").toInt());
-}*/
+ this->contextMenu()->popup( QCursor::pos() );
+ }else{
+ menu->popup( QCursor::pos() );
+ }
+}
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/LDPlugin.h b/src-qt5/core/lumina-desktop/desktop-plugins/LDPlugin.h
index 820880ed..a200ab90 100644
--- a/src-qt5/core/lumina-desktop/desktop-plugins/LDPlugin.h
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/LDPlugin.h
@@ -33,7 +33,7 @@ class LDPlugin : public QFrame{
private:
QString PLUGID, prefix;
QSettings *settings;
- QMenu *menu;
+ QMenu *menu, *contextM;
QTimer *dragTimer;
void setupMenu();
@@ -46,6 +46,10 @@ public:
QString ID(){
return PLUGID;
}
+
+ void setContextMenu(QMenu *cmen){ contextM = cmen; }
+
+ QMenu* contextMenu(){ return contextM; }
virtual QSize defaultPluginSize(){
//This needs to be re-implemented in the subclassed plugin
@@ -97,10 +101,7 @@ public slots:
//This is where all the visuals are set if using Theme-dependant icons.
setupMenu();
}
- void showPluginMenu(){
- emit CloseDesktopMenu();
- menu->popup( QCursor::pos() );
- }
+ void showPluginMenu();
signals:
void OpenDesktopMenu();
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp b/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp
index 14599c5d..8d8106f7 100644
--- a/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp
@@ -20,6 +20,9 @@ AppLauncherPlugin::AppLauncherPlugin(QWidget* parent, QString ID) : LDPlugin(par
connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT( loadButton()) );
connect(this, SIGNAL(PluginActivated()), this, SLOT(buttonClicked()) ); //in case they use the context menu to launch it.
+ this->setContextMenu( new QMenu(this) );
+ connect(this->contextMenu(), SIGNAL(triggered(QAction*)), this, SLOT(actionTriggered(QAction*)) );
+
loadButton();
//QTimer::singleShot(0,this, SLOT(loadButton()) );
}
@@ -32,6 +35,7 @@ void AppLauncherPlugin::Cleanup(){
void AppLauncherPlugin::loadButton(){
QString def = this->ID().section("::",1,50).section("---",0,0).simplified();
QString path = this->readSetting("applicationpath",def).toString(); //use the default if necessary
+ this->contextMenu()->clear();
//qDebug() << "Default Application Launcher:" << def << path;
bool ok = QFile::exists(path);
if(!ok){ emit RemovePlugin(this->ID()); return;}
@@ -53,6 +57,16 @@ void AppLauncherPlugin::loadButton(){
button->setIcon( QIcon(LXDG::findIcon(file.icon,"system-run").pixmap(QSize(icosize,icosize)).scaledToHeight(icosize, Qt::SmoothTransformation) ) );
if(!file.comment.isEmpty()){button->setToolTip(file.comment); }
txt = file.name;
+ //Put the simple Open action first (no open-with for .desktop files)
+ this->contextMenu()->addAction(button->icon(), QString(tr("Launch %1")).arg(file.name), this, SLOT(buttonClicked()) );
+ //See if there are any "actions" listed for this file, and put them in the context menu as needed.
+ if(!file.actions.isEmpty()){
+ for(int i=0; i<file.actions.length(); i++){
+ QAction *tmp = this->contextMenu()->addAction( file.actions[i].name );
+ tmp->setIcon( LXDG::findIcon(file.actions[i].icon,"quickopen-file") );
+ tmp->setWhatsThis( file.actions[i].ID );
+ }
+ }
if(!watcher->files().isEmpty()){ watcher->removePaths(watcher->files()); }
watcher->addPath(file.filePath); //make sure to update this shortcut if the file changes
}
@@ -82,6 +96,16 @@ void AppLauncherPlugin::loadButton(){
button->setText( tr("Click to Set") );
if(!watcher->files().isEmpty()){ watcher->removePaths(watcher->files()); }
}
+ //Now adjust the context menu for the button as needed
+ if(this->contextMenu()->isEmpty()){
+ this->contextMenu()->addAction(LXDG::findIcon("document-open",""), tr("Open"), this, SLOT(buttonClicked()) );
+ this->contextMenu()->addAction(LXDG::findIcon("document-preview",""), tr("Open With"), this, SLOT(openWith()) );
+ }
+ this->contextMenu()->addAction(LXDG::findIcon("document-properties",""), tr("Properties"), this, SLOT(fileProperties()) );
+ if(QFileInfo(path).isWritable()){
+ this->contextMenu()->addSeparator();
+ this->contextMenu()->addAction(LXDG::findIcon("document-close",""), tr("Delete File"), this, SLOT(fileDelete()) );
+ }
//If the file is a symlink, put the overlay on the icon
if(QFileInfo(path).isSymLink()){
QImage img = button->icon().pixmap(QSize(icosize,icosize)).toImage();
@@ -132,7 +156,7 @@ void AppLauncherPlugin::loadButton(){
QTimer::singleShot(100, this, SLOT(update()) ); //Make sure to re-draw the image in a moment
}
-void AppLauncherPlugin::buttonClicked(){
+void AppLauncherPlugin::buttonClicked(bool openwith){
QString path = button->whatsThis();
if(path.isEmpty() || !QFile::exists(path) ){
//prompt for the user to select an application
@@ -144,8 +168,33 @@ void AppLauncherPlugin::buttonClicked(){
if(!ok || names.indexOf(app)<0){ return; } //cancelled
this->saveSetting("applicationpath", apps[ names.indexOf(app) ]->filePath);
QTimer::singleShot(0,this, SLOT(loadButton()));
+ }else if(openwith){
+ LSession::LaunchApplication("lumina-open -select \""+path+"\"");
}else{
LSession::LaunchApplication("lumina-open \""+path+"\"");
}
}
+
+void AppLauncherPlugin::actionTriggered(QAction *act){
+ if(act->whatsThis().isEmpty()){ return; }
+ QString path = button->whatsThis();
+ if(path.isEmpty() || !QFile::exists(path)){ return; } //invalid file
+ LSession::LaunchApplication("lumina-open -action \""+act->whatsThis()+"\" \""+path+"\"");
+}
+
+void AppLauncherPlugin::openWith(){
+ buttonClicked(true);
+}
+
+void AppLauncherPlugin::fileProperties(){
+ QString path = button->whatsThis();
+ if(path.isEmpty() || !QFile::exists(path)){ return; } //invalid file
+ LSession::LaunchApplication("lumina-fileinfo \""+path+"\"");
+}
+
+void AppLauncherPlugin::fileDelete(){
+ QString path = button->whatsThis();
+ if(path.isEmpty() || !QFile::exists(path)){ return; } //invalid file
+ QFile::remove(path);
+}
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h b/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h
index a0f6a7cd..95fc9284 100644
--- a/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h
@@ -1,6 +1,6 @@
//===========================================
// Lumina-DE source code
-// Copyright (c) 2014, Ken Moore
+// Copyright (c) 2014-2017, Ken Moore
// Available under the 3-clause BSD license
// See the LICENSE file for full details
//===========================================
@@ -38,13 +38,18 @@ private:
private slots:
void loadButton();
- void buttonClicked();
+ void buttonClicked(bool openwith = false);
//void openContextMenu();
//void increaseIconSize();
//void decreaseIconSize();
//void deleteFile();
+ void actionTriggered(QAction *act);
+ void openWith();
+ void fileProperties();
+ void fileDelete();
+
public slots:
void LocaleChange(){
loadButton(); //force reload
diff --git a/src-qt5/core/lumina-open/main.cpp b/src-qt5/core/lumina-open/main.cpp
index 59cb05d9..7434b6c2 100644
--- a/src-qt5/core/lumina-open/main.cpp
+++ b/src-qt5/core/lumina-open/main.cpp
@@ -32,7 +32,7 @@
void printUsageInfo(){
qDebug() << "lumina-open: Application launcher for the Lumina Desktop Environment";
qDebug() << "Description: Given a file (with absolute path) or URL, this utility will try to find the appropriate application with which to open the file. If the file is a *.desktop application shortcut, it will just start the application appropriately. It can also perform a few specific system operations if given special flags.";
- qDebug() << "Usage: lumina-open [-select] <absolute file path or URL> [-action <ActionID>]";
+ qDebug() << "Usage: lumina-open [-select] [-action <ActionID>] <absolute file path or URL>";
qDebug() << " lumina-open [-volumeup, -volumedown, -brightnessup, -brightnessdown]";
qDebug() << " [-select] (optional) flag to bypass any default application settings and show the application selector window";
qDebug() << " [-action <ActionID>] (optional) Flag to run one of the alternate Actions listed in a .desktop registration file rather than the main command.";
@@ -266,8 +266,10 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat
}
switch(DF.type){
case XDGDesktop::APP:
+ qDebug() << "Found .desktop application:" << ActionID;
if(!DF.exec.isEmpty()){
cmd = DF.getDesktopExec(ActionID);
+ qDebug() << "Got command:" << cmd;
if(!DF.path.isEmpty()){ path = DF.path; }
watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/");
}else{
@@ -340,7 +342,7 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat
cmd.append(" \""+inFile+"\"");
}
}
- //qDebug() << "Found Command:" << cmd << "Extension:" << extension;
+ qDebug() << "Found Command:" << cmd << "Extension:" << extension;
//Clean up any leftover "Exec" field codes (should have already been replaced earlier)
if(cmd.contains("%")){cmd = cmd.remove("%U").remove("%u").remove("%F").remove("%f").remove("%i").remove("%c").remove("%k").simplified(); }
binary = cmd; //pass this string to the calling function
bgstack15