aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xdebian/Lumina-DE9
-rw-r--r--debian/changelog15
-rw-r--r--debian/control51
-rw-r--r--debian/lumina-data.install (renamed from debian/lumina-core.install)1
-rw-r--r--debian/lumina-desktop.install2
-rw-r--r--debian/lumina-qt5ct7
-rwxr-xr-xdebian/rules13
-rw-r--r--libLumina/LuminaOS-Debian.cpp5
-rw-r--r--libLumina/LuminaOS-DragonFly.cpp5
-rw-r--r--libLumina/LuminaOS-FreeBSD.cpp23
-rw-r--r--libLumina/LuminaOS-Linux.cpp4
-rw-r--r--libLumina/LuminaOS-OpenBSD.cpp17
-rw-r--r--libLumina/LuminaOS-kFreeBSD.cpp6
-rw-r--r--libLumina/LuminaOS-template.cpp5
-rw-r--r--libLumina/LuminaOS.h3
-rw-r--r--libLumina/LuminaThemes.cpp9
-rw-r--r--libLumina/LuminaThemes.h3
-rw-r--r--libLumina/LuminaUtils.cpp44
-rw-r--r--libLumina/LuminaUtils.h10
-rw-r--r--libLumina/LuminaX11.cpp99
-rw-r--r--libLumina/LuminaX11.h16
-rw-r--r--libLumina/LuminaXDG.cpp12
-rw-r--r--libLumina/libLumina.pro2
-rw-r--r--lumina-config/LPlugins.cpp9
-rw-r--r--lumina-config/mainUI.cpp127
-rw-r--r--lumina-config/mainUI.h2
-rw-r--r--lumina-config/mainUI.ui30
-rw-r--r--lumina-desktop/LDesktop.cpp1
-rw-r--r--lumina-desktop/LSession.cpp35
-rw-r--r--lumina-desktop/LWinInfo.cpp10
-rw-r--r--lumina-desktop/desktop-plugins/LDPlugin.h4
-rw-r--r--lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp42
-rw-r--r--lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h8
-rw-r--r--lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.cpp110
-rw-r--r--lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.h24
-rw-r--r--lumina-desktop/desktop-plugins/notepad/NotepadPlugin.cpp2
-rw-r--r--lumina-desktop/lumina-desktop.pro4
-rw-r--r--lumina-desktop/panel-plugins/NewPP.h3
-rw-r--r--lumina-desktop/panel-plugins/applauncher/AppLaunchButton.cpp73
-rw-r--r--lumina-desktop/panel-plugins/applauncher/AppLaunchButton.h63
-rw-r--r--lumina-desktop/panel-plugins/clock/LClock.cpp4
-rw-r--r--lumina-desktop/panel-plugins/clock/LClock.h4
-rw-r--r--lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp14
-rw-r--r--lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp7
-rw-r--r--lumina-desktop/panel-plugins/userbutton/UserItemWidget.cpp4
-rw-r--r--lumina-desktop/panel-plugins/userbutton/UserWidget.cpp12
-rw-r--r--lumina-fm/BackgroundWorker.cpp15
-rw-r--r--lumina-fm/MainUI.cpp48
-rw-r--r--lumina-fm/MainUI.h2
-rw-r--r--lumina-fm/MimeIconProvider.h10
-rw-r--r--lumina-open/LFileDialog.cpp4
-rw-r--r--lumina-open/main.cpp27
-rw-r--r--lumina-xconfig/MainUI.cpp10
53 files changed, 908 insertions, 161 deletions
diff --git a/debian/Lumina-DE b/debian/Lumina-DE
new file mode 100755
index 00000000..96e6832a
--- /dev/null
+++ b/debian/Lumina-DE
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+. /etc/default/lumina-qt5ct
+
+if test -f /usr/bin/qt5ct && test ${LUMINA_USE_QT5CT} = TRUE; then
+ export QT_QPA_PLATFORMTHEME=qt5ct
+fi
+
+/usr/bin/Lumina-DE.real
diff --git a/debian/changelog b/debian/changelog
index b9d3b36c..a06b640f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,18 @@
+lumina-desktop (0.8.3.372-1nano) unstable; urgency=low
+
+ * new GIT snapshot
+ - add build dependency on libxcb-image0-dev
+ - add Lumina-DE startup wrapper. If qt5-configuration-tool exists
+ and LUMINA_USE_QT5CT is set to TRUE in /etc/default/lumina-qt5ct,
+ then export QT_QPA_PLATFORMTHEME=qt5ct, so that it works in Lumina
+ - add lumina-data arch-indep package containing data files
+ - drop lumina-core package
+ - change lumina-desktop from arch-any to arch-indep
+ - make lumina-desktop what lumina-core was before (keeping dependencies
+ on all lumina-* packages)
+
+ -- Christopher Roy Bratusek <nano@jpberlin.de> Thu, 12 Mar 2015 18:11:17 +0100
+
lumina-desktop (0.8.3.347-1nano) unstable; urgency=low
* new GIT snapshot
diff --git a/debian/control b/debian/control
index 14bce48d..fda9e4c0 100644
--- a/debian/control
+++ b/debian/control
@@ -6,15 +6,17 @@ Build-Depends: debhelper (>= 9), qt5-qmake, qtbase5-dev, qtmultimedia5-dev,
libxcb1-dev, libx11-xcb-dev, libxcb-ewmh-dev, make, g++,
libx11-dev, libxrender-dev, libxcomposite-dev, libxdamage-dev,
libxcb-icccm4-dev, libxcb-damage0-dev, libxcb-util0-dev,
- libqt5x11extras5-dev, qttools5-dev-tools
+ libqt5x11extras5-dev, qttools5-dev-tools, libxcb-image0-dev
Standards-Version: 3.9.5
Homepage: https://github.com/pcbsd/lumina
Package: lumina-desktop
-Architecture: all
-Depends: libluminautils1, lumina-core, lumina-config, lumina-fm,
+Architecture: any
+Replaces: lumina-core (<< 0.8.3.372)
+Depends: ${misc:Depends}, ${shlibs:Depends}, libluminautils1 (= ${binary:Version}),
+ libluminautils1, lumina-config, lumina-fm, oxygen-icon-theme,
lumina-open, lumina-screenshot, lumina-search, lumina-info,
- lxpolkit
+ lxpolkit, lumina-data, fluxbox, numlockx, xbacklight, xscreensaver
Recommends: qt5-configuration-tool
Description: Lightweight Qt5-based desktop environment
Metapackage depending on all other lumina packages.
@@ -38,23 +40,10 @@ Depends: ${misc:Depends}, ${shlibs:Depends}, libluminautils-dev (= ${binary:Vers
Description: Debugging symbols for lumina desktop environment
Debugging symbols for libluminautils1
-Package: lumina-core
-Architecture: any
-Depends: ${misc:Depends}, ${shlibs:Depends}, libluminautils1 (= ${binary:Version}),
- fluxbox, numlockx, xbacklight, xscreensaver, oxygen-icon-theme
-Description: Core package for the lumina desktop environment
- This package provides the basic components of lumina
- - session manager
- - panel with plugins
- - wallpaper setter
- - fluxbox configurator
- - desktop icon manager and menu
- - wallpapers
-
Package: lumina-config
Architecture: any
Depends: ${misc:Depends}, ${shlibs:Depends}, libluminautils1 (= ${binary:Version})
-Replaces: lumina-core (<< 0.8.2)
+Replaces: lumina-core (<< 0.8.3.372)
Description: Configuration utility for the lumina desktop environment
lumina-config allows to change various aspects of lumina and fluxbox, like the
wallpaper beeing used, startup-applications, desktop-menu and more.
@@ -62,7 +51,7 @@ Description: Configuration utility for the lumina desktop environment
Package: lumina-fm
Architecture: any
Depends: ${misc:Depends}, ${shlibs:Depends}, libluminautils1 (= ${binary:Version})
-Replaces: lumina-core (<< 0.8.2)
+Replaces: lumina-core (<< 0.8.3.372)
Description: Filemanager for the lumina desktop environment
Simple filemanager for lumina with support for multiple view modes and
integrated slideshow-based picture viewer.
@@ -70,7 +59,7 @@ Description: Filemanager for the lumina desktop environment
Package: lumina-open
Architecture: any
Depends: ${misc:Depends}, ${shlibs:Depends}, libluminautils1 (= ${binary:Version})
-Replaces: lumina-core (<< 0.8.2)
+Replaces: lumina-core (<< 0.8.3.372)
Description: xdg-open like utilityfor the lumina desktop environment
lumina-open handles opening of files and urls according to the system wide
mime type association. It also provides an optional selector if more than one
@@ -79,7 +68,7 @@ Description: xdg-open like utilityfor the lumina desktop environment
Package: lumina-screenshot
Architecture: any
Depends: ${misc:Depends}, ${shlibs:Depends}, libluminautils1 (= ${binary:Version})
-Replaces: lumina-core (<< 0.8.2)
+Replaces: lumina-core (<< 0.8.3.372)
Description: Screenshot utility for the lumina desktop environment
Simple screenshot utility that allows to snapshot the whole desktop or a single
window after a configurable delay.
@@ -87,7 +76,7 @@ Description: Screenshot utility for the lumina desktop environment
Package: lumina-search
Architecture: any
Depends: ${misc:Depends}, ${shlibs:Depends}, libluminautils1 (= ${binary:Version})
-Replaces: lumina-core (<< 0.8.2)
+Replaces: lumina-core (<< 0.8.3.372)
Description: Search utility for the lumina desktop environment
Simple search utility that allows to search for applications or files and
directories in the user's HOME directory.
@@ -95,7 +84,7 @@ Description: Search utility for the lumina desktop environment
Package: lumina-info
Architecture: any
Depends: ${misc:Depends}, ${shlibs:Depends}, libluminautils1 (= ${binary:Version})
-Replaces: lumina-core (<< 0.8.2)
+Replaces: lumina-core (<< 0.8.3.372)
Description: Basic information utility for Lumina
lumina-info display various information about the Lumina installation,
like paths or version.
@@ -103,7 +92,17 @@ Description: Basic information utility for Lumina
Package: lumina-xconfig
Architecture: any
Depends: ${misc:Depends}, ${shlibs:Depends}, libluminautils1 (= ${binary:Version})
-Replaces: lumina-core (<< 0.8.2)
+Replaces: lumina-core (<< 0.8.3.372)
Description: Display configuration tool for the lumina desktop environment
- lumina-info display various information about the Lumina installation,
- like paths or version.
+ Simple multi-head aware display configuration tool for Lumina
+
+Package: lumina-data
+Architecture: all
+Depends: ${misc:Depends}, ${shlibs:Depends}, libluminautils1 (= ${binary:Version}), lumina-desktop (= ${binary:Version})
+Replaces: lumina-core (<< 0.8.3.372)
+Description: Data files for the lumina Desktop environment
+ - Lumina Wallpapers
+ - Lumina Themes
+ - Lumina Translations
+ - Lumina Sounds
+ - Fallback fluxbox configuration
diff --git a/debian/lumina-core.install b/debian/lumina-data.install
index d1d143e8..cbf45f34 100644
--- a/debian/lumina-core.install
+++ b/debian/lumina-data.install
@@ -1,4 +1,3 @@
-usr/bin/Lumina-DE
usr/share/pixmaps/Lumina-DE.png
usr/share/Lumina-DE/colors/
usr/share/Lumina-DE/themes/
diff --git a/debian/lumina-desktop.install b/debian/lumina-desktop.install
new file mode 100644
index 00000000..748ddff0
--- /dev/null
+++ b/debian/lumina-desktop.install
@@ -0,0 +1,2 @@
+usr/bin/Lumina-DE
+
diff --git a/debian/lumina-qt5ct b/debian/lumina-qt5ct
new file mode 100644
index 00000000..9553f94c
--- /dev/null
+++ b/debian/lumina-qt5ct
@@ -0,0 +1,7 @@
+#
+# if LUMINA_USE_QT5CT is TRUE Lumina Desktop
+# will use qt5-configuration-tool for theming
+# Qt. Please note that this will override some
+# of the Lumina settings in 'lumina-config'
+
+LUMINA_USE_QT5CT=FALSE
diff --git a/debian/rules b/debian/rules
index f86bf5e3..d15b44d9 100755
--- a/debian/rules
+++ b/debian/rules
@@ -38,11 +38,18 @@ override_dh_strip:
override_dh_install:
dh_install --fail-missing
- mkdir $(CURDIR)/debian/lumina-core/etc/
+ mkdir $(CURDIR)/debian/lumina-desktop/etc/
install -m644 $(CURDIR)/debian/luminaDesktop.conf \
- $(CURDIR)/debian/lumina-core/etc/luminaDesktop.conf
+ $(CURDIR)/debian/lumina-desktop/etc/luminaDesktop.conf
echo "/usr/lib/$(DEB_HOST_MULTIARCH)/lxpolkit" > \
- $(CURDIR)/debian/lumina-core/etc/luminaStartapps
+ $(CURDIR)/debian/lumina-desktop/etc/luminaStartapps
+ mv $(CURDIR)/debian/lumina-desktop/usr/bin/Lumina-DE \
+ $(CURDIR)/debian/lumina-desktop/usr/bin/Lumina-DE.real
+ install -m755 $(CURDIR)/debian/Lumina-DE \
+ $(CURDIR)/debian/lumina-desktop/usr/bin/Lumina-DE
+ mkdir -p $(CURDIR)/debian/lumina-desktop/etc/default
+ install -m644 $(CURDIR)/debian/lumina-qt5ct \
+ $(CURDIR)/debian/lumina-desktop/etc/default/lumina-qt5ct
override_dh_auto_install:
INSTALL_ROOT=$(CURDIR)/debian/tmp/ $(MAKE) install
diff --git a/libLumina/LuminaOS-Debian.cpp b/libLumina/LuminaOS-Debian.cpp
index 8228d7c4..4f2032fa 100644
--- a/libLumina/LuminaOS-Debian.cpp
+++ b/libLumina/LuminaOS-Debian.cpp
@@ -193,4 +193,9 @@ int LOS::batterySecondsLeft(){ //Returns: estimated number of seconds remaining
return 0; //not implemented yet for Linux
}
+//File Checksums
+QStringList LOS::Checksums(QStringList filepaths){ //Return: checksum of the input file
+ return QStringList();
+}
+
#endif
diff --git a/libLumina/LuminaOS-DragonFly.cpp b/libLumina/LuminaOS-DragonFly.cpp
index dd9320fc..35bff04c 100644
--- a/libLumina/LuminaOS-DragonFly.cpp
+++ b/libLumina/LuminaOS-DragonFly.cpp
@@ -171,4 +171,9 @@ int LOS::batterySecondsLeft(){ //Returns: estimated number of seconds remaining
return LUtils::getCmdOutput("apm -t").join("").toInt();
}
+//File Checksums
+QStringList LOS::Checksums(QStringList filepaths){ //Return: checksum of the input file
+ return QStringList();
+}
+
#endif
diff --git a/libLumina/LuminaOS-FreeBSD.cpp b/libLumina/LuminaOS-FreeBSD.cpp
index 8b395026..d454ce22 100644
--- a/libLumina/LuminaOS-FreeBSD.cpp
+++ b/libLumina/LuminaOS-FreeBSD.cpp
@@ -142,17 +142,22 @@ void LOS::startMixerUtility(){
bool LOS::userHasShutdownAccess(){
//User needs to be a part of the operator group to be able to run the shutdown command
QStringList groups = LUtils::getCmdOutput("id -Gn").join(" ").split(" ");
- return groups.contains("operator"); //not implemented yet
+ bool ok = groups.contains("operator"); //not implemented yet
+ if(ok){
+ //If a PC-BSD system, also disable the shutdown/restart options if the system is in the middle of upgrading
+ ok = (QProcess::execute("pgrep -F /tmp/.updateInProgress")!=0); //this is 0 if updating right now
+ }
+ return ok;
}
//System Shutdown
void LOS::systemShutdown(){ //start poweroff sequence
- QProcess::startDetached("shutdown -p now");
+ QProcess::startDetached("shutdown -po now");
}
//System Restart
void LOS::systemRestart(){ //start reboot sequence
- QProcess::startDetached("shutdown -r now");
+ QProcess::startDetached("shutdown -ro now");
}
//Battery Availability
@@ -178,4 +183,16 @@ int LOS::batterySecondsLeft(){ //Returns: estimated number of seconds remaining
return LUtils::getCmdOutput("apm -t").join("").toInt();
}
+//File Checksums
+QStringList LOS::Checksums(QStringList filepaths){ //Return: checksum of the input file
+ QStringList info = LUtils::getCmdOutput("md5 \""+filepaths.join("\" \"")+"\"");
+ for(int i=0; i<info.length(); i++){
+ if( !info[i].contains(" = ") ){ info.removeAt(i); i--; }
+ else{
+ //Strip out the extra information
+ info[i] = info[i].section(" = ",1,1);
+ }
+ }
+ return info;
+}
#endif
diff --git a/libLumina/LuminaOS-Linux.cpp b/libLumina/LuminaOS-Linux.cpp
index f0f427f4..7587a29b 100644
--- a/libLumina/LuminaOS-Linux.cpp
+++ b/libLumina/LuminaOS-Linux.cpp
@@ -190,4 +190,8 @@ int LOS::batterySecondsLeft(){ //Returns: estimated number of seconds remaining
return 0; //not implemented yet for Linux
}
+//File Checksums
+QStringList LOS::Checksums(QStringList filepaths){ //Return: checksum of the input file
+ return QStringList();
+}
#endif
diff --git a/libLumina/LuminaOS-OpenBSD.cpp b/libLumina/LuminaOS-OpenBSD.cpp
index 2c86995a..b6996795 100644
--- a/libLumina/LuminaOS-OpenBSD.cpp
+++ b/libLumina/LuminaOS-OpenBSD.cpp
@@ -190,4 +190,21 @@ int LOS::batterySecondsLeft(){ //Returns: estimated number of seconds remaining
return (min * 60);
}
+//File Checksums
+QStringList LOS::Checksums(QStringList filepaths){ //Return: checksum of the input file
+ //on OpenBSD md5 has the following layout
+ //>md5 LuminaThemes.o LuminaUtils.o
+ //MD5 (LuminaThemes.o) = 50006505d9d7e54e5154eeb095555055
+ //MD5 (LuminaUtils.o) = d490878ee8866e55e5af571b98b4d448
+
+ QStringList info = LUtils::getCmdOutput("md5 \""+filepaths.join("\" \"")+"\"");
+ for(int i=0; i<info.length(); i++){
+ if( !info[i].contains(" = ") ){ info.removeAt(i); i--; }
+ else{
+ //Strip out the extra information
+ info[i] = info[i].section(" = ",1,1);
+ }
+ }
+ return info;
+}
#endif
diff --git a/libLumina/LuminaOS-kFreeBSD.cpp b/libLumina/LuminaOS-kFreeBSD.cpp
index ab9f9827..16c8e6eb 100644
--- a/libLumina/LuminaOS-kFreeBSD.cpp
+++ b/libLumina/LuminaOS-kFreeBSD.cpp
@@ -153,6 +153,10 @@ int LOS::batterySecondsLeft(){ //Returns: estimated number of seconds remaining
return 0; //not implemented yet for Linux
}
+//File Checksums
+QStringList LOS::Checksums(QStringList filepaths){ //Return: checksum of the input file
+ return QStringList();
+}
+
#endif
#endif
-
diff --git a/libLumina/LuminaOS-template.cpp b/libLumina/LuminaOS-template.cpp
index d481984f..c06b8b11 100644
--- a/libLumina/LuminaOS-template.cpp
+++ b/libLumina/LuminaOS-template.cpp
@@ -101,4 +101,9 @@ int LOS::batterySecondsLeft(){ //Returns: estimated number of seconds remaining
return 0; //not implemented yet
}
+//File Checksums
+QStringList LOS::Checksums(QStringList filepaths){ //Return: checksum of the input file
+ return QStringList();
+}
+
#endif
diff --git a/libLumina/LuminaOS.h b/libLumina/LuminaOS.h
index e0eb2895..92a7dc7e 100644
--- a/libLumina/LuminaOS.h
+++ b/libLumina/LuminaOS.h
@@ -80,6 +80,9 @@ public:
static bool batteryIsCharging();
//Battery Time Remaining
static int batterySecondsLeft(); //Returns: estimated number of seconds remaining
+
+ //Get the checksum for a file
+ static QStringList Checksums(QStringList filepaths); //Return: checksum of each input file (same order)
};
#endif
diff --git a/libLumina/LuminaThemes.cpp b/libLumina/LuminaThemes.cpp
index 269af259..e4c13ae7 100644
--- a/libLumina/LuminaThemes.cpp
+++ b/libLumina/LuminaThemes.cpp
@@ -177,10 +177,14 @@ LuminaThemeEngine::LuminaThemeEngine(QApplication *app){
theme = current[0]; colors=current[1]; icons=current[2]; font=current[3]; fontsize=current[4];
application->setStyleSheet( LTHEME::assembleStyleSheet(theme, colors, font, fontsize) );
QIcon::setThemeName(icons); //make sure this sets set within this environment
+ syncTimer = new QTimer(this);
+ syncTimer->setSingleShot(true);
+ syncTimer->setInterval(500); //wait 1/2 second before re-loading the files
watcher = new QFileSystemWatcher(this);
watcher->addPath( QDir::homePath()+"/.lumina/themesettings.cfg" );
watcher->addPaths( QStringList() << theme << colors ); //also watch these files for changes
connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(watcherChange()) );
+ connect(syncTimer, SIGNAL(timeout()), this, SLOT(reloadFiles()) );
}
LuminaThemeEngine::~LuminaThemeEngine(){
@@ -188,6 +192,11 @@ LuminaThemeEngine::~LuminaThemeEngine(){
}
void LuminaThemeEngine::watcherChange(){
+ if(syncTimer->isActive()){ syncTimer->stop(); }
+ syncTimer->start();
+}
+
+void LuminaThemeEngine::reloadFiles(){
QStringList current = LTHEME::currentSettings();
application->setStyleSheet( LTHEME::assembleStyleSheet(current[0], current[1], current[3], current[4]) );
diff --git a/libLumina/LuminaThemes.h b/libLumina/LuminaThemes.h
index e4bbd208..9b5ad5bc 100644
--- a/libLumina/LuminaThemes.h
+++ b/libLumina/LuminaThemes.h
@@ -16,6 +16,7 @@
#include <QString>
#include <QFile>
#include <QDir>
+#include <QTimer>
class LTHEME{
public:
@@ -63,9 +64,11 @@ private:
QApplication *application;
QFileSystemWatcher *watcher;
QString theme,colors,icons, font, fontsize; //current settings
+ QTimer *syncTimer;
private slots:
void watcherChange();
+ void reloadFiles();
signals:
void updateIcons();
diff --git a/libLumina/LuminaUtils.cpp b/libLumina/LuminaUtils.cpp
index 9b8a1860..f7f5db74 100644
--- a/libLumina/LuminaUtils.cpp
+++ b/libLumina/LuminaUtils.cpp
@@ -144,6 +144,50 @@ void LUtils::LoadTranslation(QApplication *app, QString appname){
QTextCodec::setCodecForLocale( QTextCodec::codecForName(langEnc.toUtf8()) );
}
+QStringList LUtils::listFavorites(){
+ QStringList fav = LUtils::readFile(QDir::homePath()+"/.lumina/favorites/fav.list");
+ return fav;
+}
+
+bool LUtils::saveFavorites(QStringList list){
+ return LUtils::writeFile(QDir::homePath()+"/.lumina/favorites/fav.list", list, true);
+}
+
+bool LUtils::isFavorite(QString path){
+ QStringList fav = LUtils::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){
+ //Generate the type of favorite this is
+ QFileInfo info(path);
+ QString type = "file";
+ if(info.isDir()){ type="dir"; }
+ else if(info.suffix()=="desktop"){ type="app"; }
+ //Assign a name if none given
+ if(name.isEmpty()){ name = info.fileName(); }
+ //Now add it to the list
+ QStringList fav = LUtils::listFavorites();
+ bool found = false;
+ for(int i=0; i<fav.length(); i++){
+ if(fav[i].endsWith("::::"+path)){ fav[i] = name+"::::"+type+"::::"+path; }
+ }
+ if(!found){ fav << name+"::::"+type+"::::"+path; }
+ return LUtils::saveFavorites(fav);
+}
+
+void LUtils::removeFavorite(QString path){
+ QStringList fav = LUtils::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); }
+}
+
void LUtils::LoadSystemDefaults(bool skipOS){
//Will create the Lumina configuration files based on the current system template (if any)
QStringList sysDefaults;
diff --git a/libLumina/LuminaUtils.h b/libLumina/LuminaUtils.h
index ee716167..d0c8b3ad 100644
--- a/libLumina/LuminaUtils.h
+++ b/libLumina/LuminaUtils.h
@@ -44,6 +44,16 @@ public:
//Load a translation file for a Lumina Project
static void LoadTranslation(QApplication *app, QString appname);
+
+ //Various functions for the favorites sub-system
+ // Formatting Note: "<name>::::[dir/file/app]::::<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);
+
//Load the default setup for the system
static void LoadSystemDefaults(bool skipOS = false);
diff --git a/libLumina/LuminaX11.cpp b/libLumina/LuminaX11.cpp
index e73f124c..43d4e577 100644
--- a/libLumina/LuminaX11.cpp
+++ b/libLumina/LuminaX11.cpp
@@ -25,6 +25,7 @@
#include <xcb/xproto.h>
#include <xcb/xcb_ewmh.h>
#include <xcb/xcb_icccm.h>
+#include <xcb/xcb_image.h>
//===== WindowList() ========
@@ -425,6 +426,8 @@ bool LX11::EmbedWindow(WId win, WId container){
//qDebug() << "Embed Window:" << win << container;
XReparentWindow(disp, win, container,0,0);
XSync(disp, false);
+ //Map the window
+ XMapRaised(disp, win); //make it visible again and raise it to the top
//Check that the window has _XEMBED_INFO
//qDebug() << " - check for _XEMBED_INFO";
Atom embinfo = XInternAtom(disp, "_XEMBED_INFO",false);
@@ -436,7 +439,7 @@ bool LX11::EmbedWindow(WId win, WId container){
return false; //Embedding error (no info?)
}
if(data){ XFree(data); } // clean up any data found
-
+
//Now send the embed event to the app
//qDebug() << " - send _XEMBED event";
XEvent ev;
@@ -515,7 +518,7 @@ QString LX11::WindowVisibleIconName(WId win){
}
// ===== WindowIcon() =====
-QIcon LX11::WindowIcon(WId win){
+/*QIcon LX11::WindowIcon(WId win){
//Use the _NET_WM_ICON value instead of the WMHints pixmaps
// - the pixmaps are very unstable and erratic
QIcon icon;
@@ -544,11 +547,11 @@ QIcon LX11::WindowIcon(WId win){
XFree(data);
}
return icon;
-}
+}*/
// ===== WindowImage() =====
-QPixmap LX11::WindowImage(WId win, bool useleader){
+/*QPixmap LX11::WindowImage(WId win, bool useleader){
QPixmap pix;
Display *disp = QX11Info::display();
WId leader = LX11::leaderWindow(win); //check for an alternate window that contains the image
@@ -565,7 +568,7 @@ QPixmap LX11::WindowImage(WId win, bool useleader){
}
//Return the pixmap
return pix;
-}
+}*/
// ===== GetNumberOfDesktops() =====
int LX11::WindowDesktop(WId win){
@@ -1009,7 +1012,7 @@ LXCB::WINDOWSTATE LXCB::WindowState(WId win){
}
// === WindowVisibleIconName() ===
-QString LXCB::WindowVisibleIconName(WId win){ //_WM_VISIBLE_ICON_NAME
+QString LXCB::WindowVisibleIconName(WId win){ //_NET_WM_VISIBLE_ICON_NAME
QString out;
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_visible_icon_name_unchecked(&EWMH, win);
if(cookie.sequence == 0){ return out; }
@@ -1021,7 +1024,7 @@ QString LXCB::WindowVisibleIconName(WId win){ //_WM_VISIBLE_ICON_NAME
}
// === WindowIconName() ===
-QString LXCB::WindowIconName(WId win){ //_WM_ICON_NAME
+QString LXCB::WindowIconName(WId win){ //_NET_WM_ICON_NAME
QString out;
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_icon_name_unchecked(&EWMH, win);
if(cookie.sequence == 0){ return out; }
@@ -1033,7 +1036,7 @@ QString LXCB::WindowIconName(WId win){ //_WM_ICON_NAME
}
// === WindowVisibleName() ===
-QString LXCB::WindowVisibleName(WId win){ //_WM_VISIBLE_NAME
+QString LXCB::WindowVisibleName(WId win){ //_NET_WM_VISIBLE_NAME
QString out;
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_visible_name_unchecked(&EWMH, win);
if(cookie.sequence == 0){ return out; }
@@ -1045,7 +1048,7 @@ QString LXCB::WindowVisibleName(WId win){ //_WM_VISIBLE_NAME
}
// === WindowName() ===
-QString LXCB::WindowName(WId win){ //_WM_NAME
+QString LXCB::WindowName(WId win){ //_NET_WM_NAME
QString out;
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_name_unchecked(&EWMH, win);
if(cookie.sequence == 0){ return out; }
@@ -1056,6 +1059,32 @@ QString LXCB::WindowName(WId win){ //_WM_NAME
return out;
}
+// === OldWindowName() ===
+QString LXCB::OldWindowName(WId win){ //WM_NAME (old standard)
+ xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_name_unchecked(QX11Info::connection(), win);
+ xcb_icccm_get_text_property_reply_t reply;
+ if(1 == xcb_icccm_get_wm_name_reply(QX11Info::connection(), cookie, &reply, NULL) ){
+ QString name = QString::fromLocal8Bit(reply.name);
+ xcb_icccm_get_text_property_reply_wipe(&reply);
+ return name;
+ }else{
+ return "";
+ }
+}
+
+// === OldWindowIconName() ===
+QString LXCB::OldWindowIconName(WId win){ //WM_ICON_NAME (old standard)
+ xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_icon_name_unchecked(QX11Info::connection(), win);
+ xcb_icccm_get_text_property_reply_t reply;
+ if(1 == xcb_icccm_get_wm_icon_name_reply(QX11Info::connection(), cookie, &reply, NULL) ){
+ QString name = QString::fromLocal8Bit(reply.name);
+ xcb_icccm_get_text_property_reply_wipe(&reply);
+ return name;
+ }else{
+ return "";
+ }
+}
+
// === WindowIsMaximized() ===
bool LXCB::WindowIsMaximized(WId win){
//See if the _NET_WM_STATE_MAXIMIZED_[VERT/HORZ] flags are set on the window
@@ -1074,6 +1103,56 @@ bool LXCB::WindowIsMaximized(WId win){
return false;
}
+// === WindowIcon() ===
+QIcon LXCB::WindowIcon(WId win){
+ //Fetch the _NET_WM_ICON for the window and return it as a QIcon
+ QIcon icon;
+ xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_icon_unchecked(&EWMH, win);
+ xcb_ewmh_get_wm_icon_reply_t reply;
+ if(1 == xcb_ewmh_get_wm_icon_reply(&EWMH, cookie, &reply, NULL)){
+ xcb_ewmh_wm_icon_iterator_t iter = xcb_ewmh_get_wm_icon_iterator(&reply);
+ //Just use the first
+ bool done =false;
+ while(!done){
+ //Now convert the current data into a Qt image
+ // - first 2 elements are width and height (removed via XCB functions)
+ // - data in rows from left to right and top to bottom
+ QImage image(iter.width, iter.height, QImage::Format_ARGB32); //initial setup
+ uint* dat = iter.data;
+ //dat+=2; //remember the first 2 element offset
+ for(int i=0; i<image.byteCount()/4; ++i, ++dat){
+ ((uint*)image.bits())[i] = *dat;
+ }
+ icon.addPixmap(QPixmap::fromImage(image)); //layer this pixmap onto the icon
+ //Now see if there are any more icons available
+ done = (iter.rem<1); //number of icons remaining
+ if(!done){ xcb_ewmh_get_wm_icon_next(&iter); } //get the next icon data
+ }
+ xcb_ewmh_get_wm_icon_reply_wipe(&reply);
+ }
+ return icon;
+}
+
+// === WindowImage() ===
+QPixmap LXCB::WindowImage(WId win){
+ QPixmap pix;
+
+ //First get the size of the window
+ xcb_get_geometry_cookie_t cookie = xcb_get_geometry_unchecked(QX11Info::connection(), win);
+ xcb_get_geometry_reply_t *reply = xcb_get_geometry_reply(QX11Info::connection(), cookie, NULL);
+ if(reply == 0){ return pix; } //could not determine window geometry
+ //Now get the image
+ xcb_image_t *img = xcb_image_get(QX11Info::connection(), win, 0, 0, reply->width, reply->height, (uint32_t) AllPlanes, XCB_IMAGE_FORMAT_Z_PIXMAP);
+ if(img!=0){
+ //Now convert the image into a QPixmap
+ pix.convertFromImage( QImage( (const uchar*) img->data, img->width, img->height, img->stride, QImage::Format_ARGB32_Premultiplied) );
+ //Clean up the xcb_image structure
+ xcb_image_destroy(img);
+ }
+ //Return the pixmap
+ return pix;
+}
+
// === SetAsSticky() ===
void LXCB::SetAsSticky(WId win){
//Need to send a client message event for the window so the WM picks it up
@@ -1295,4 +1374,4 @@ void LXCB::MoveResizeWindow(WId win, QRect geom){
xcb_ewmh_set_workarea(&EWMH, 0, desks, dareas); //_NET_WORKAREA
//Make sure to clear that reply
xcb_ewmh_get_workarea_reply_wipe(&work);
-}*/ \ No newline at end of file
+}*/
diff --git a/libLumina/LuminaX11.h b/libLumina/LuminaX11.h
index ef6fa676..62146ebe 100644
--- a/libLumina/LuminaX11.h
+++ b/libLumina/LuminaX11.h
@@ -91,8 +91,8 @@ public:
static QString WindowVisibleName(WId); // long name (translated)
static QString WindowIconName(WId); // short name (untranslated)
static QString WindowVisibleIconName(WId); // short name (translated)
- static QIcon WindowIcon(WId); // Icon for the window
- static QPixmap WindowImage(WId win, bool useleader=true); // Image for the window
+ //static QIcon WindowIcon(WId); // Icon for the window
+ //static QPixmap WindowImage(WId win, bool useleader=true); // Image for the window
static int WindowDesktop(WId); // Which virtual desktop the window is on
static WINDOWSTATE GetWindowState(WId win); //State of activity
static WId leaderWindow(WId); //Get the main window if this one is a redirect
@@ -133,11 +133,15 @@ public:
unsigned int WindowWorkspace(WId); //The workspace the window is on
QRect WindowGeometry(WId, bool includeFrame = true); //the geometry of the window (frame excluded)
WINDOWSTATE WindowState(WId win); //Visible state of window
- QString WindowVisibleIconName(WId win); //_WM_VISIBLE_ICON_NAME
- QString WindowIconName(WId win); //_WM_ICON_NAME
- QString WindowVisibleName(WId win); //_WM_VISIBLE_NAME
- QString WindowName(WId win); //_WM_NAME
+ QString WindowVisibleIconName(WId win); //_NET_WM_VISIBLE_ICON_NAME
+ QString WindowIconName(WId win); //_NET_WM_ICON_NAME
+ QString WindowVisibleName(WId win); //_NET_WM_VISIBLE_NAME
+ QString WindowName(WId win); //_NET_WM_NAME
+ QString OldWindowName(WId win); //WM_NAME (old standard)
+ QString OldWindowIconName(WId win); //WM_ICON_NAME (old standard)
bool WindowIsMaximized(WId win);
+ QIcon WindowIcon(WId win); //_NET_WM_ICON
+ QPixmap WindowImage(WId win); //Pull the image directly from the window
//Window Modification
void SetAsSticky(WId); //Stick to all workspaces
diff --git a/libLumina/LuminaXDG.cpp b/libLumina/LuminaXDG.cpp
index 27b3b637..e4839480 100644
--- a/libLumina/LuminaXDG.cpp
+++ b/libLumina/LuminaXDG.cpp
@@ -20,7 +20,7 @@ XDGDesktop LXDG::loadDesktopFile(QString filePath, bool& ok){
DF.isHidden=false;
DF.useTerminal=false;
DF.startupNotify=false;
- DF.type = XDGDesktop::BAD;
+ DF.type = XDGDesktop::APP;
DF.filePath = filePath;
DF.exec = DF.tryexec = ""; // just to make sure this is initialized
//Check input file path validity
@@ -63,6 +63,7 @@ XDGDesktop LXDG::loadDesktopFile(QString filePath, bool& ok){
}
else if( (var=="TryExec") && (DF.tryexec.isEmpty()) ) { DF.tryexec = val; }
else if( (var=="Exec") && (DF.exec.isEmpty() ) ) { DF.exec = val; } // only take the first Exec command in the file
+ else if( (var=="Path") && (DF.path.isEmpty() ) ){ DF.path = val; }
else if(var=="NoDisplay" && !DF.isHidden){ DF.isHidden = (val.toLower()=="true"); }
else if(var=="Hidden" && !DF.isHidden){ DF.isHidden = (val.toLower()=="true"); }
else if(var=="Categories"){ DF.catList = val.split(";",QString::SkipEmptyParts); }
@@ -82,7 +83,7 @@ XDGDesktop LXDG::loadDesktopFile(QString filePath, bool& ok){
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; }
+ else{ DF.type = XDGDesktop::BAD; } //Unknown type
}
} //end reading file
file.close();
@@ -254,10 +255,11 @@ QString LXDG::getDesktopExec(XDGDesktop app){
out = app.exec;
}
//Now perform any of the XDG flag substitutions as appropriate (9/2014 standards)
- if(out.contains("%i")){ out.replace("%i", "--icon \'"+app.icon+"\'"); }
+ 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+""); }
+ 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;
diff --git a/libLumina/libLumina.pro b/libLumina/libLumina.pro
index 7606210b..e0963fc6 100644
--- a/libLumina/libLumina.pro
+++ b/libLumina/libLumina.pro
@@ -42,7 +42,7 @@ SOURCES += LuminaXDG.cpp \
INCLUDEPATH += $$PREFIX/include
-LIBS += -lX11 -lXrender -lXcomposite -lxcb -lxcb-ewmh -lxcb-icccm
+LIBS += -lX11 -lXrender -lXcomposite -lxcb -lxcb-ewmh -lxcb-icccm -lxcb-image
include.path=$$PREFIX/include/
include.files=LuminaXDG.h \
diff --git a/lumina-config/LPlugins.cpp b/lumina-config/LPlugins.cpp
index 55a5ee9e..94b61f34 100644
--- a/lumina-config/LPlugins.cpp
+++ b/lumina-config/LPlugins.cpp
@@ -135,13 +135,20 @@ void LPlugins::LoadPanelPlugins(){
info.ID = "homebutton";
info.icon = "go-home";
PANEL.insert(info.ID, info);
- //Desktop Bar
+ //Start Menu
info = LPI(); //clear it
info.name = QObject::tr("Start Menu");
info.description = QObject::tr("This provides instant-access to application that are installed on the system.");
info.ID = "appmenu";
info.icon = "Lumina-DE";
PANEL.insert(info.ID, info);
+ //Application Launcher
+ info = LPI(); //clear it
+ info.name = QObject::tr("Application Launcher");
+ info.description = QObject::tr("Pin an application shortcut directly to the panel");
+ info.ID = "applauncher";
+ info.icon = "quickopen";
+ PANEL.insert(info.ID, info);
}
void LPlugins::LoadDesktopPlugins(){
diff --git a/lumina-config/mainUI.cpp b/lumina-config/mainUI.cpp
index c633e866..8bcb4f40 100644
--- a/lumina-config/mainUI.cpp
+++ b/lumina-config/mainUI.cpp
@@ -11,11 +11,13 @@
#include <QImageReader>
#include <QTime>
#include <QDate>
+#include <QTimeZone>
MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI()){
ui->setupUi(this); //load the designer file
this->setWindowIcon( LXDG::findIcon("preferences-desktop-display","") );
PINFO = new LPlugins(); //load the info class
+ panadjust = false;
DEFAULTBG = LOS::LuminaShare()+"desktop-background.jpg";
//Be careful about the QSettings setup, it must match the lumina-desktop setup
QSettings::setPath(QSettings::NativeFormat, QSettings::UserScope, QDir::homePath()+"/.lumina");
@@ -234,6 +236,7 @@ void MainUI::setupConnections(){
connect(ui->tool_help_date, SIGNAL(clicked()), this, SLOT(sessionShowDateCodes()) );
connect(ui->line_session_time, SIGNAL(textChanged(QString)), this, SLOT(sessionLoadTimeSample()) );
connect(ui->line_session_date, SIGNAL(textChanged(QString)), this, SLOT(sessionLoadDateSample()) );
+ connect(ui->combo_session_timezone, SIGNAL(currentIndexChanged(int)), this, SLOT(sessionoptchanged()) );
}
void MainUI::setupMenus(){
@@ -272,7 +275,28 @@ void MainUI::setupMenus(){
ui->combo_session_wtheme->addItem(fbstyles[i], fbdir.absoluteFilePath(fbstyles[i]));
}
-
+ //Available Time zones
+ ui->combo_session_timezone->clear();
+ QList<QByteArray> TZList = QTimeZone::availableTimeZoneIds();
+ QDateTime DT = QDateTime::currentDateTime();
+ QStringList tzlist; //Need to create a list which can be sorted appropriately
+ for(int i=0; i<TZList.length(); i++){
+ QTimeZone TZ(TZList[i]);
+ if(TZ.country()<=0){ continue; } //skip this one
+ QString name = QLocale::countryToString(TZ.country());
+ if(name.count() > 20){ name = name.left(20)+"..."; }
+ name = QString(tr("%1 (%2)")).arg(name, TZ.abbreviation(DT));
+ if(tzlist.filter(name).isEmpty()){
+ tzlist << name+"::::"+QString::number(i);
+ }
+ }
+ tzlist.sort();
+ for(int i=0; i<tzlist.length(); i++){
+ ui->combo_session_timezone->addItem( tzlist[i].section("::::",0,0), TZList[tzlist[i].section("::::",1,1).toInt()]);
+ }
+ //ui->combo_session_timezone->sort();
+ //Now set the default/system value
+ ui->combo_session_timezone->insertItem(0,tr("System Time"));
}
int MainUI::currentDesktop(){
@@ -485,11 +509,21 @@ void MainUI::loadCurrentSettings(bool screenonly){
ui->list_panel1_plugins->clear();
for(int i=0; i<plugs.length(); i++){
QString pid = plugs[i].section("---",0,0);
- LPI info = PINFO->panelPluginInfo(pid);
- if(!info.ID.isEmpty()){
- QListWidgetItem *it = new QListWidgetItem( LXDG::findIcon(info.icon,""), info.name );
+ if(pid.startsWith("applauncher")){
+ bool ok = false;
+ XDGDesktop desk = LXDG::loadDesktopFile(pid.section("::",1,1),ok);
+ if(ok){
+ QListWidgetItem *it = new QListWidgetItem( LXDG::findIcon(desk.icon,""), desk.name );
+ it->setWhatsThis(plugs[i]); //make sure to preserve the entire plugin ID (is the unique version)
+ ui->list_panel1_plugins->addItem(it);
+ }
+ }else{
+ LPI info = PINFO->panelPluginInfo(pid);
+ if(!info.ID.isEmpty()){
+ QListWidgetItem *it = new QListWidgetItem( LXDG::findIcon(info.icon,""), info.name );
it->setWhatsThis(plugs[i]); //make sure to preserve the entire plugin ID (is the unique version)
- ui->list_panel1_plugins->addItem(it);
+ ui->list_panel1_plugins->addItem(it);
+ }
}
}
QString color = settings->value(PPrefix+"color","rgba(255,255,255,160)").toString();
@@ -864,7 +898,8 @@ void MainUI::checkpanels(){
void MainUI::adjustpanel1(){
//Adjust panel 1 to complement a panel 2 change
- if(loading){ return; }
+ if(loading || panadjust){ return; }
+ panadjust = true;
qDebug() << "Adjust Panel 1:";
ui->toolBox_panel1->setCurrentIndex( ui->toolBox_panel2->currentIndex() );
bool changed = false;
@@ -883,11 +918,13 @@ void MainUI::adjustpanel1(){
changed = true;
ui->combo_panel1_loc->setCurrentIndex(newindex);
}
+ panadjust = false;
if(!loading){ ui->push_save->setEnabled(true); modpan = true; }
}
void MainUI::adjustpanel2(){
- if(loading){ return; }
+ if(loading || panadjust){ return; }
+ panadjust = true;
//Adjust panel 2 to complement a panel 1 change
qDebug() << "Adjust Panel 2:";
ui->toolBox_panel2->setCurrentIndex( ui->toolBox_panel1->currentIndex() );
@@ -907,7 +944,8 @@ void MainUI::adjustpanel2(){
changed = true;
ui->combo_panel2_loc->setCurrentIndex(newindex);
}
- if(!loading){ ui->push_save->setEnabled(true); modpan = true; }
+ panadjust = false;
+ if(!loading && changed){ ui->push_save->setEnabled(true); modpan = true; }
}
@@ -935,14 +973,26 @@ void MainUI::addpanel1plugin(){
dlg.exec();
if(!dlg.selected){ return; } //cancelled
QString pan = dlg.plugID; //getNewPanelPlugin();
- if(pan.isEmpty()){ return; } //nothing selected
- //Add the new plugin to the list
- LPI info = PINFO->panelPluginInfo(pan);
- QListWidgetItem *it = new QListWidgetItem( LXDG::findIcon(info.icon,""), info.name);
- it->setWhatsThis(info.ID);
- ui->list_panel1_plugins->addItem(it);
- ui->list_panel1_plugins->setCurrentItem(it);
- ui->list_panel1_plugins->scrollToItem(it);
+ if(pan == "applauncher"){
+ //Prompt for the application to add
+ XDGDesktop app = getSysApp();
+ if(app.filePath.isEmpty()){ return; } //cancelled
+ pan.append("::"+app.filePath);
+ QListWidgetItem *it = new QListWidgetItem( LXDG::findIcon(app.icon,""), app.name);
+ it->setWhatsThis(pan);
+ ui->list_panel1_plugins->addItem(it);
+ ui->list_panel1_plugins->setCurrentItem(it);
+ ui->list_panel1_plugins->scrollToItem(it);
+ }else{
+ if(pan.isEmpty()){ return; } //nothing selected
+ //Add the new plugin to the list
+ LPI info = PINFO->panelPluginInfo(pan);
+ QListWidgetItem *it = new QListWidgetItem( LXDG::findIcon(info.icon,""), info.name);
+ it->setWhatsThis(info.ID);
+ ui->list_panel1_plugins->addItem(it);
+ ui->list_panel1_plugins->setCurrentItem(it);
+ ui->list_panel1_plugins->scrollToItem(it);
+ }
checkpanels(); //update buttons
if(!loading){ ui->push_save->setEnabled(true); modpan = true; }
}
@@ -953,14 +1003,26 @@ void MainUI::addpanel2plugin(){
dlg.exec();
if(!dlg.selected){ return; } //cancelled
QString pan = dlg.plugID; //getNewPanelPlugin();
- if(pan.isEmpty()){ return; } //nothing selected
- //Add the new plugin to the list
- LPI info = PINFO->panelPluginInfo(pan);
- QListWidgetItem *it = new QListWidgetItem( LXDG::findIcon(info.icon,""), info.name);
- it->setWhatsThis(info.ID);
- ui->list_panel2_plugins->addItem(it);
- ui->list_panel2_plugins->setCurrentItem(it);
- ui->list_panel2_plugins->scrollToItem(it);
+ if(pan == "applauncher"){
+ //Prompt for the application to add
+ XDGDesktop app = getSysApp();
+ if(app.filePath.isEmpty()){ return; } //cancelled
+ pan.append("::"+app.filePath);
+ QListWidgetItem *it = new QListWidgetItem( LXDG::findIcon(app.icon,""), app.name);
+ it->setWhatsThis(pan);
+ ui->list_panel2_plugins->addItem(it);
+ ui->list_panel2_plugins->setCurrentItem(it);
+ ui->list_panel2_plugins->scrollToItem(it);
+ }else{
+ if(pan.isEmpty()){ return; } //nothing selected
+ //Add the new plugin to the list
+ LPI info = PINFO->panelPluginInfo(pan);
+ QListWidgetItem *it = new QListWidgetItem( LXDG::findIcon(info.icon,""), info.name);
+ it->setWhatsThis(info.ID);
+ ui->list_panel2_plugins->addItem(it);
+ ui->list_panel2_plugins->setCurrentItem(it);
+ ui->list_panel2_plugins->scrollToItem(it);
+ }
checkpanels(); //update buttons
if(!loading){ ui->push_save->setEnabled(true); modpan = true; }
}
@@ -1729,6 +1791,14 @@ void MainUI::loadSessionSettings(){
ui->push_session_setUserIcon->setIcon( LXDG::findIcon(QDir::homePath()+"/.loginIcon.png", "user-identity") );
ui->line_session_time->setText( sessionsettings->value("TimeFormat","").toString() );
ui->line_session_date->setText( sessionsettings->value("DateFormat","").toString() );
+ if( !sessionsettings->value("CustomTimeZone", false).toBool() ){
+ //System Time selected
+ ui->combo_session_timezone->setCurrentIndex(0);
+ }else{
+ int index = ui->combo_session_timezone->findData( sessionsettings->value("TimeZoneByteCode",QByteArray()).toByteArray() );
+ if(index>0){ ui->combo_session_timezone->setCurrentIndex(index); }
+ else{ ui->combo_session_timezone->setCurrentIndex(0); }
+ }
//Now do the session theme options
ui->combo_session_themefile->clear();
@@ -1821,6 +1891,14 @@ void MainUI::saveSessionSettings(){
sessionsettings->setValue("PlayLogoutAudio", ui->check_session_playlogoutaudio->isChecked());
sessionsettings->setValue("TimeFormat", ui->line_session_time->text());
sessionsettings->setValue("DateFormat", ui->line_session_date->text());
+ if( ui->combo_session_timezone->currentIndex()==0){
+ //System Time selected
+ sessionsettings->setValue("CustomTimeZone", false);
+ sessionsettings->setValue("TimeZoneByteCode", QByteArray()); //clear the value
+ }else{
+ sessionsettings->setValue("CustomTimeZone", true);
+ sessionsettings->setValue("TimeZoneByteCode", ui->combo_session_timezone->currentData().toByteArray()); //clear the value
+ }
//Now do the theme options
QString themefile = ui->combo_session_themefile->itemData( ui->combo_session_themefile->currentIndex() ).toString();
@@ -1828,6 +1906,7 @@ void MainUI::saveSessionSettings(){
QString iconset = ui->combo_session_icontheme->currentText();
QString font = ui->font_session_theme->currentFont().family();
QString fontsize = QString::number(ui->spin_session_fontsize->value())+"pt";
+ //qDebug() << "Saving theme options:" << themefile << colorfile << iconset << font << fontsize;
LTHEME::setCurrentSettings( themefile, colorfile, iconset, font, fontsize);
}
diff --git a/lumina-config/mainUI.h b/lumina-config/mainUI.h
index 93400d93..2593d648 100644
--- a/lumina-config/mainUI.h
+++ b/lumina-config/mainUI.h
@@ -57,7 +57,7 @@ private:
QString panelcolor;
QString DEFAULTBG;
QList<XDGDesktop> sysApps;
- bool loading;
+ bool loading, panadjust;
bool moddesk, modpan, modmenu, modshort, moddef, modses; //page modified flags
int panelnumber;
diff --git a/lumina-config/mainUI.ui b/lumina-config/mainUI.ui
index fcebaff7..07abacab 100644
--- a/lumina-config/mainUI.ui
+++ b/lumina-config/mainUI.ui
@@ -109,7 +109,7 @@
<enum>QFrame::StyledPanel</enum>
</property>
<property name="currentIndex">
- <number>1</number>
+ <number>4</number>
</property>
<widget class="QWidget" name="page_desktop">
<layout class="QVBoxLayout" name="verticalLayout_3">
@@ -602,8 +602,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>263</width>
- <height>178</height>
+ <width>233</width>
+ <height>150</height>
</rect>
</property>
<attribute name="label">
@@ -799,8 +799,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>263</width>
- <height>178</height>
+ <width>233</width>
+ <height>150</height>
</rect>
</property>
<attribute name="label">
@@ -1634,6 +1634,26 @@
</property>
</widget>
</item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_26">
+ <property name="text">
+ <string>Time Zone:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QComboBox" name="combo_session_timezone">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="sizeAdjustPolicy">
+ <enum>QComboBox::AdjustToMinimumContentsLength</enum>
+ </property>
+ </widget>
+ </item>
</layout>
</item>
<item row="6" column="0" colspan="2">
diff --git a/lumina-desktop/LDesktop.cpp b/lumina-desktop/LDesktop.cpp
index 9a045e4f..c2ef4a2a 100644
--- a/lumina-desktop/LDesktop.cpp
+++ b/lumina-desktop/LDesktop.cpp
@@ -287,6 +287,7 @@ void LDesktop::UpdateDesktop(){
if(DEBUG){qDebug() << " -- New Plugin:" << plugins[i];}
plug = NewDP::createPlugin(plugins[i], bgDesktop);
if(plug != 0){
+ connect(plug, SIGNAL(OpenDesktopMenu()), this, SLOT(ShowMenu()) );
//qDebug() << " -- Show Plugin";
PLUGINS << plug;
CreateDesktopPluginContainer(plug);
diff --git a/lumina-desktop/LSession.cpp b/lumina-desktop/LSession.cpp
index 811c60da..6437524b 100644
--- a/lumina-desktop/LSession.cpp
+++ b/lumina-desktop/LSession.cpp
@@ -205,6 +205,9 @@ void LSession::launchStartupApps(){
//Now play the login music
if(sessionsettings->value("PlayStartupAudio",true).toBool()){
+ //Make sure to re-set the system volume to the last-used value at outset
+ int vol = LOS::audioVolume();
+ if(vol>=0){ LOS::setAudioVolume(vol); }
LSession::playAudioFile(LOS::LuminaShare()+"Login.ogg");
}
if(sessionsettings->value("EnableNumlock",true).toBool()){
@@ -254,6 +257,11 @@ void LSession::checkUserFiles(){
}*/
LUtils::LoadSystemDefaults();
}
+ if(oldversion <= 83){
+ //Convert the old->new favorites framework
+
+ }
+
//Check for the default applications file for lumina-open
dset = QDir::homePath()+"/.lumina/LuminaDE/lumina-open.conf";
if(!QFile::exists(dset)){
@@ -315,21 +323,24 @@ void LSession::updateDesktops(){
}
}
//qDebug() << " - Done Starting Desktops";
- //Make sure all the background windows are registered on the system as virtual roots
- QTimer::singleShot(200,this, SLOT(registerDesktopWindows()));
- if(firstrun){ return; } //Done right here on first run
+
+ if(!firstrun){//Done right here on first run
//Now go through and make sure to delete any desktops for detached screens
- for(int i=0; i<DESKTOPS.length(); i++){
- if(DESKTOPS[i]->Screen() >= DW->screenCount()){
- qDebug() << " - Close desktop on screen:" << DESKTOPS[i]->Screen();
- DESKTOPS[i]->prepareToClose(); //hide();
- delete DESKTOPS.takeAt(i);
- i--;
- }else{
- qDebug() << " - Show desktop on screen:" << DESKTOPS[i]->Screen();
- DESKTOPS[i]->show();
+ for(int i=0; i<DESKTOPS.length(); i++){
+ if(DESKTOPS[i]->Screen() >= DW->screenCount()){
+ qDebug() << " - Close desktop on screen:" << DESKTOPS[i]->Screen();
+ DESKTOPS[i]->prepareToClose(); //hide();
+ delete DESKTOPS.takeAt(i);
+ i--;
+ }else{
+ qDebug() << " - Show desktop on screen:" << DESKTOPS[i]->Screen();
+ DESKTOPS[i]->show();
+ }
}
+ WM->updateWM(); //Make sure fluxbox also gets prompted to re-load screen config
}
+ //Make sure all the background windows are registered on the system as virtual roots
+ QTimer::singleShot(100,this, SLOT(registerDesktopWindows()));
//qDebug() << " - Done Checking Desktops";
}
diff --git a/lumina-desktop/LWinInfo.cpp b/lumina-desktop/LWinInfo.cpp
index d46bef92..b1476c4e 100644
--- a/lumina-desktop/LWinInfo.cpp
+++ b/lumina-desktop/LWinInfo.cpp
@@ -15,16 +15,18 @@
QString LWinInfo::text(){
if(window==0){ return ""; }
QString nm = LSession::handle()->XCB->WindowVisibleIconName(window);
- if(nm.isEmpty()){ nm = LSession::handle()->XCB->WindowIconName(window); }
- if(nm.isEmpty()){ nm = LSession::handle()->XCB->WindowVisibleName(window); }
- if(nm.isEmpty()){ nm = LSession::handle()->XCB->WindowName(window); }
+ if(nm.simplified().isEmpty()){ nm = LSession::handle()->XCB->WindowIconName(window); }
+ if(nm.simplified().isEmpty()){ nm = LSession::handle()->XCB->WindowVisibleName(window); }
+ if(nm.simplified().isEmpty()){ nm = LSession::handle()->XCB->WindowName(window); }
+ if(nm.simplified().isEmpty()){ nm = LSession::handle()->XCB->OldWindowIconName(window); }
+ if(nm.simplified().isEmpty()){ nm = LSession::handle()->XCB->OldWindowName(window); }
return nm;
}
QIcon LWinInfo::icon(bool &noicon){
if(window==0){ noicon = true; return QIcon();}
noicon = false;
- QIcon ico = LX11::WindowIcon(window);
+ QIcon ico = LSession::handle()->XCB->WindowIcon(window);
//Check for a null icon, and supply one if necessary
if(ico.isNull()){ ico = LXDG::findIcon( this->Class().toLower(),""); }
if(ico.isNull()){ico = LXDG::findIcon("preferences-system-windows",""); noicon=true;}
diff --git a/lumina-desktop/desktop-plugins/LDPlugin.h b/lumina-desktop/desktop-plugins/LDPlugin.h
index 0e1f6847..9660a85c 100644
--- a/lumina-desktop/desktop-plugins/LDPlugin.h
+++ b/lumina-desktop/desktop-plugins/LDPlugin.h
@@ -68,6 +68,10 @@ public slots:
//This needs to be re-implemented in the subclassed plugin
//This is where all the visuals are set if using Theme-dependant icons.
}
+
+signals:
+ void OpenDesktopMenu();
+
};
#endif \ No newline at end of file
diff --git a/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp b/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp
index dc0c7596..b3c6afcf 100644
--- a/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp
+++ b/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp
@@ -7,18 +7,19 @@ AppLauncherPlugin::AppLauncherPlugin(QWidget* parent, QString ID) : LDPlugin(par
lay->setContentsMargins(0,0,0,0);
button = new QToolButton(this);
button->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
- button->setIconSize(QSize(64,64));
button->setAutoRaise(true);
button->setText("..."); //Need to set something here so that initial sizing works properly
+
lay->addWidget(button, 0, Qt::AlignCenter);
connect(button, SIGNAL(clicked()), this, SLOT(buttonClicked()) );
- this->setInitialSize(64,66+this->fontMetrics().height());
- /*if(this->settings->allKeys().isEmpty()){
- //Brand new plugin: set initial size
- this->settings->setValue("location/width",64);
- this->settings->setValue("location/height",66+this->fontMetrics().height());
- this->settings->sync();
- }*/
+ menu = new QMenu(this);
+ menu->addAction(LXDG::findIcon("zoom-in",""), tr("Increase Size"), this, SLOT(increaseIconSize()));
+ menu->addAction(LXDG::findIcon("zoom-out",""), tr("Decrease Size"), this, SLOT(decreaseIconSize()));
+ int icosize = settings->value("iconsize",64).toInt();
+ button->setIconSize(QSize(icosize,icosize));
+ this->setInitialSize(icosize,icosize+10+this->fontMetrics().height());
+ this->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(openContextMenu()) );
watcher = new QFileSystemWatcher(this);
connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT( loadButton()) );
QTimer::singleShot(1,this, SLOT(loadButton()) );
@@ -62,4 +63,27 @@ void AppLauncherPlugin::buttonClicked(){
LSession::LaunchApplication("lumina-open \""+path+"\"");
}
-} \ No newline at end of file
+}
+
+void AppLauncherPlugin::openContextMenu(){
+ if(button->underMouse()){
+ menu->popup(QCursor::pos());
+ }else{
+ emit OpenDesktopMenu();
+ }
+}
+
+void AppLauncherPlugin::increaseIconSize(){
+ int icosize = settings->value("iconsize",64).toInt();
+ icosize += 16;
+ button->setIconSize(QSize(icosize,icosize));
+ settings->setValue("iconsize",icosize);
+}
+
+void AppLauncherPlugin::decreaseIconSize(){
+ int icosize = settings->value("iconsize",64).toInt();
+ if(icosize < 20){ return; } //cannot get smaller
+ icosize -= 16;
+ button->setIconSize(QSize(icosize,icosize));
+ settings->setValue("iconsize",icosize);
+}
diff --git a/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h b/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h
index bb21b636..2c861e4d 100644
--- a/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h
+++ b/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h
@@ -16,6 +16,8 @@
#include <QFile>
#include <QFileSystemWatcher>
#include <QTimer>
+#include <QMenu>
+#include <QCursor>
#include "../LDPlugin.h"
@@ -30,9 +32,15 @@ public:
private:
QToolButton *button;
QFileSystemWatcher *watcher;
+ QMenu *menu;
private slots:
void loadButton();
void buttonClicked();
+ void openContextMenu();
+
+ void increaseIconSize();
+ void decreaseIconSize();
+
};
#endif
diff --git a/lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.cpp b/lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.cpp
index ce20c563..0aa4a3de 100644
--- a/lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.cpp
+++ b/lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.cpp
@@ -2,6 +2,8 @@
#include <QFileInfo>
#include <QDir>
+#include <QClipboard>
+#include <QMimeData>
#include <LuminaXDG.h>
#include "LSession.h"
@@ -17,17 +19,31 @@ DesktopViewPlugin::DesktopViewPlugin(QWidget* parent, QString ID) : LDPlugin(par
list->setBatchSize(10); //keep it snappy
list->setSpacing(2);
list->setSelectionBehavior(QAbstractItemView::SelectItems);
- list->setSelectionMode(QAbstractItemView::NoSelection);
+ list->setSelectionMode(QAbstractItemView::ExtendedSelection);
list->setStyleSheet( "QListWidget{ background: transparent; border: none; }" );
- list->setIconSize(QSize(64,64));
+ int icosize = settings->value("IconSize",64).toInt();
+ list->setIconSize(QSize(icosize,icosize));
list->setUniformItemSizes(true);
+ list->setContextMenuPolicy(Qt::CustomContextMenu);
+
+ menu = new QMenu(this);
+ menu->addAction( LXDG::findIcon("run-build-file",""), tr("Open"), this, SLOT(runItems()) );
+ menu->addSeparator();
+ menu->addAction( LXDG::findIcon("edit-cut",""), tr("Cut"), this, SLOT(cutItems()) );
+ menu->addAction( LXDG::findIcon("edit-copy",""), tr("Copy"), this, SLOT(copyItems()) );
+ menu->addSeparator();
+ menu->addAction( LXDG::findIcon("zoom-in",""), tr("Increase Icons"), this, SLOT(increaseIconSize()) );
+ menu->addAction( LXDG::findIcon("zoom-out",""), tr("Decrease Icons"), this, SLOT(decreaseIconSize()) );
+ menu->addSeparator();
+ menu->addAction( LXDG::findIcon("edit-delete",""), tr("Delete"), this, SLOT(deleteItems()) );
this->layout()->addWidget(list);
this->setInitialSize(600,600);
watcher = new QFileSystemWatcher(this);
watcher->addPath(QDir::homePath()+"/Desktop");
connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(updateContents()) );
- connect(list, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(runItem(QListWidgetItem*)) );
+ connect(list, SIGNAL(itemActivated(QListWidgetItem*)), this, SLOT(runItems()) );
+ connect(list, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showMenu(const QPoint&)) );
QTimer::singleShot(0,this, SLOT(updateContents()) );
}
@@ -35,13 +51,83 @@ DesktopViewPlugin::~DesktopViewPlugin(){
}
-void DesktopViewPlugin::runItem(QListWidgetItem *item){
- LSession::LaunchApplication("lumina-open \""+item->whatsThis()+"\"");
+void DesktopViewPlugin::runItems(){
+ QList<QListWidgetItem*> sel = list->selectedItems();
+ for(int i=0; i<sel.length(); i++){
+ LSession::LaunchApplication("lumina-open \""+sel[i]->whatsThis()+"\"");
+ }
+}
+
+void DesktopViewPlugin::copyItems(){
+ QList<QListWidgetItem*> sel = list->selectedItems();
+ if(sel.isEmpty()){ return; } //nothing selected
+ QStringList items;
+ //Format the data string
+ for(int i=0; i<sel.length(); i++){
+ items << "copy::::"+sel[i]->whatsThis();
+ }
+ //Now save that data to the global clipboard
+ QMimeData *dat = new QMimeData;
+ dat->clear();
+ dat->setData("x-special/lumina-copied-files", items.join("\n").toLocal8Bit());
+ QApplication::clipboard()->clear();
+ QApplication::clipboard()->setMimeData(dat);
+}
+
+void DesktopViewPlugin::cutItems(){
+ QList<QListWidgetItem*> sel = list->selectedItems();
+ if(sel.isEmpty()){ return; } //nothing selected
+ QStringList items;
+ //Format the data string
+ for(int i=0; i<sel.length(); i++){
+ items << "cut::::"+sel[i]->whatsThis();
+ }
+ //Now save that data to the global clipboard
+ QMimeData *dat = new QMimeData;
+ dat->clear();
+ dat->setData("x-special/lumina-copied-files", items.join("\n").toLocal8Bit());
+ QApplication::clipboard()->clear();
+ QApplication::clipboard()->setMimeData(dat);
+}
+
+void DesktopViewPlugin::deleteItems(){
+ QList<QListWidgetItem*> sel = list->selectedItems();
+ for(int i=0; i<sel.length(); i++){
+ QFile::remove(sel[i]->whatsThis());
+ }
+}
+
+void DesktopViewPlugin::showMenu(const QPoint &pos){
+ //Make sure there is an item underneath the mouse first
+ if(list->itemAt(pos)!=0){
+ menu->popup(pos);
+ }else{
+ //Pass the context menu request on to the desktop (emit it from the plugin)
+ emit OpenDesktopMenu();
+ }
+}
+
+void DesktopViewPlugin::increaseIconSize(){
+ int icosize = settings->value("IconSize",64).toInt();
+ icosize+=16; //go in orders of 16 pixels
+ list->setIconSize(QSize(icosize,icosize));
+ settings->setValue("IconSize",icosize);
+ updateContents();
+}
+
+void DesktopViewPlugin::decreaseIconSize(){
+ int icosize = settings->value("IconSize",64).toInt();
+ if(icosize < 20){ return; } //too small to decrease more
+ icosize-=16; //go in orders of 16 pixels
+ list->setIconSize(QSize(icosize,icosize));
+ settings->setValue("IconSize",icosize);
+ updateContents();
}
void DesktopViewPlugin::updateContents(){
list->clear();
- list->setGridSize(QSize(80,70+this->fontMetrics().height()));
+ int icosize = settings->value("IconSize",64).toInt();
+ list->setGridSize(QSize(icosize+8,icosize+4+this->fontMetrics().height()));
QDir dir(QDir::homePath()+"/Desktop");
QFileInfoList files = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Type | QDir::DirsFirst);
for(int i=0; i<files.length(); i++){
@@ -54,15 +140,19 @@ void DesktopViewPlugin::updateContents(){
bool ok = false;
XDGDesktop desk = LXDG::loadDesktopFile(files[i].absoluteFilePath(), ok);
if(ok){
- it->setIcon( LXDG::findIcon(desk.icon,"") );
- it->setText( desk.name );
+ it->setIcon( LXDG::findIcon(desk.icon,"unknown") );
+ if(desk.name.isEmpty()){
+ it->setText( files[i].fileName() );
+ }else{
+ it->setText( desk.name );
+ }
}else{
//Revert back to a standard file handling
- it->setIcon( LXDG::findMimeIcon(files[i].suffix()) );
+ it->setIcon( LXDG::findMimeIcon(files[i].fileName()) );
it->setText( files[i].fileName() );
}
}else{
- it->setIcon( LXDG::findMimeIcon(files[i].suffix()) );
+ it->setIcon( LXDG::findMimeIcon( files[i].fileName() ) );
it->setText( files[i].fileName() );
}
list->addItem(it);
diff --git a/lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.h b/lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.h
index 6ec35276..61e1caf9 100644
--- a/lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.h
+++ b/lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.h
@@ -13,6 +13,8 @@
#include <QVBoxLayout>
#include <QTimer>
#include <QFileSystemWatcher>
+#include <QMouseEvent>
+
#include "../LDPlugin.h"
class DesktopViewPlugin : public LDPlugin{
@@ -24,9 +26,16 @@ public:
private:
QListWidget *list;
QFileSystemWatcher *watcher;
+ QMenu *menu;
private slots:
- void runItem(QListWidgetItem*);
+ void runItems();
+ void copyItems();
+ void cutItems();
+ void deleteItems();
+ void showMenu(const QPoint&);
+ void increaseIconSize();
+ void decreaseIconSize();
void updateContents();
@@ -37,6 +46,19 @@ public slots:
void ThemeChange(){
QTimer::singleShot(0,this, SLOT(updateContents()));
}
+
+/*protected:
+ void mousePressEvent(QMouseEvent *ev){
+ if(ev->button()==Qt::RightButton){
+ qDebug() << " - got mouse event";
+ //Only show the context menu if an item is under the mouse (don't block the desktop menu)
+ if(list->itemAt( ev->globalPos()) !=0){
+ ev->accept();
+ showMenu(ev->globalPos());
+ }
+ }
+ }
+ */
};
#endif
diff --git a/lumina-desktop/desktop-plugins/notepad/NotepadPlugin.cpp b/lumina-desktop/desktop-plugins/notepad/NotepadPlugin.cpp
index 6d4a2b5d..dacaca60 100644
--- a/lumina-desktop/desktop-plugins/notepad/NotepadPlugin.cpp
+++ b/lumina-desktop/desktop-plugins/notepad/NotepadPlugin.cpp
@@ -200,10 +200,12 @@ void NotePadPlugin::updateContents(){
QString note = cnote->currentData().toString();
updating = true;
LUtils::writeFile(note, edit->toPlainText().split("\n"), true);
+ QApplication::processEvents(); //make sure to process/discard the file changed signal before disabling the flag
updating = false;
}
void NotePadPlugin::notesDirChanged(){
+ if(updating){ return; }
QString cfile = settings->value("currentFile","").toString();
QStringList notes;
QDir dir(QDir::homePath()+"/Notes");
diff --git a/lumina-desktop/lumina-desktop.pro b/lumina-desktop/lumina-desktop.pro
index feb49f60..6c3ee0cc 100644
--- a/lumina-desktop/lumina-desktop.pro
+++ b/lumina-desktop/lumina-desktop.pro
@@ -1,6 +1,6 @@
QT += core gui network
-greaterThan(QT_MAJOR_VERSION, 4): QT += widgets x11extras multimedia dbus
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets x11extras multimedia
TARGET = Lumina-DE
isEmpty(PREFIX) {
@@ -50,6 +50,7 @@ SOURCES += main.cpp \
panel-plugins/systemdashboard/SysMenuQuick.cpp \
panel-plugins/showdesktop/LHomeButton.cpp \
panel-plugins/appmenu/LAppMenuPlugin.cpp \
+ panel-plugins/applauncher/AppLaunchButton.cpp \
desktop-plugins/applauncher/AppLauncherPlugin.cpp \
desktop-plugins/desktopview/DesktopViewPlugin.cpp \
desktop-plugins/notepad/NotepadPlugin.cpp \
@@ -89,6 +90,7 @@ HEADERS += Globals.h \
panel-plugins/systemdashboard/SysMenuQuick.h \
panel-plugins/showdesktop/LHomeButton.h \
panel-plugins/appmenu/LAppMenuPlugin.h \
+ panel-plugins/applauncher/AppLaunchButton.h \
desktop-plugins/SamplePlugin.h \
desktop-plugins/calendar/CalendarPlugin.h \
desktop-plugins/applauncher/AppLauncherPlugin.h \
diff --git a/lumina-desktop/panel-plugins/NewPP.h b/lumina-desktop/panel-plugins/NewPP.h
index 6c5c369c..3a593629 100644
--- a/lumina-desktop/panel-plugins/NewPP.h
+++ b/lumina-desktop/panel-plugins/NewPP.h
@@ -23,6 +23,7 @@
#include "systemdashboard/LSysDashboard.h"
#include "showdesktop/LHomeButton.h"
#include "appmenu/LAppMenuPlugin.h"
+#include "applauncher/AppLaunchButton.h"
#include "systemtray/LSysTray.h" //must be last due to X11 compile issues
class NewPP{
@@ -52,6 +53,8 @@ public:
plug = new LSysDashboard(parent, plugin, horizontal);
}else if(plugin.startsWith("appmenu---")){
plug = new LAppMenuPlugin(parent, plugin, horizontal);
+ }else if(plugin.section("---",0,0).section("::",0,0)=="applauncher"){
+ plug = new AppLaunchButtonPlugin(parent, plugin, horizontal);
}else{
qWarning() << "Invalid Panel Plugin:"<<plugin << " -- Ignored";
}
diff --git a/lumina-desktop/panel-plugins/applauncher/AppLaunchButton.cpp b/lumina-desktop/panel-plugins/applauncher/AppLaunchButton.cpp
new file mode 100644
index 00000000..5bd7fa96
--- /dev/null
+++ b/lumina-desktop/panel-plugins/applauncher/AppLaunchButton.cpp
@@ -0,0 +1,73 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2015, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "AppLaunchButton.h"
+#include "../../LSession.h"
+
+#include <LuminaXDG.h>
+
+AppLaunchButtonPlugin::AppLaunchButtonPlugin(QWidget *parent, QString id, bool horizontal) : LPPlugin(parent, id, horizontal){
+ button = new QToolButton(this);
+ button->setAutoRaise(true);
+ button->setToolButtonStyle(Qt::ToolButtonIconOnly);
+ appfile = id.section("---",0,0).section("::",1,1);
+ if(!QFile::exists(appfile)){ appfile.clear(); }
+ connect(button, SIGNAL(clicked()), this, SLOT(AppClicked()));
+ this->layout()->setContentsMargins(0,0,0,0);
+ this->layout()->addWidget(button);
+
+ QTimer::singleShot(0,this, SLOT(OrientationChange())); //Update icons/sizes
+}
+
+AppLaunchButtonPlugin::~AppLaunchButtonPlugin(){
+
+}
+
+void AppLaunchButtonPlugin::updateButtonVisuals(){
+ QIcon icon;
+ QString tooltip = tr("Click to assign an application");
+ if(appfile.endsWith(".desktop")){
+ bool ok = false;
+ XDGDesktop desk = LXDG::loadDesktopFile(appfile,ok);
+ if(ok){
+ icon = LXDG::findIcon(desk.icon, "unknown");
+ tooltip = QString(tr("Launch %1")).arg(desk.name);
+ }else{
+ icon = LXDG::findIcon("task-attention","");
+ appfile.clear();
+ }
+ }else if(QFile::exists(appfile)){
+ icon = LXDG::findMimeIcon(appfile.section("/",-1));
+ tooltip = QString(tr("Open %1")).arg(appfile.section("/",-1));
+ }else{
+ icon = LXDG::findIcon("task-attention", "");
+ }
+ button->setIcon( icon );
+ button->setToolTip(tooltip);
+}
+
+// ========================
+// PRIVATE FUNCTIONS
+// ========================
+void AppLaunchButtonPlugin::AppClicked(){
+ if(appfile.isEmpty()){
+ //No App File selected
+ QList<XDGDesktop> apps = LSession::handle()->applicationMenu()->currentAppHash()->value("All");
+ QStringList names;
+ for(int i=0; i<apps.length(); i++){ names << apps[i].name; }
+ bool ok = false;
+ QString app = QInputDialog::getItem(this, tr("Select Application"), tr("Name:"), names, 0, false, &ok);
+ if(!ok || names.indexOf(app)<0){ return; } //cancelled
+ appfile = apps[ names.indexOf(app) ].filePath;
+ //Still need to find a way to set this value persistently
+ // --- perhaps replace the plugin in the desktop settings file with the new path?
+ // --- "applauncher::broken---<something>" -> "applauncher::fixed---<something>" ?
+ QTimer::singleShot(0,this, SLOT(updateButtonVisuals()));
+ }else{
+ LSession::LaunchApplication("lumina-open \""+appfile+"\"");
+ }
+}
+
diff --git a/lumina-desktop/panel-plugins/applauncher/AppLaunchButton.h b/lumina-desktop/panel-plugins/applauncher/AppLaunchButton.h
new file mode 100644
index 00000000..3aa3c7ad
--- /dev/null
+++ b/lumina-desktop/panel-plugins/applauncher/AppLaunchButton.h
@@ -0,0 +1,63 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2015, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+// This panel plugin is a simple button to launch a single application
+//===========================================
+#ifndef _LUMINA_DESKTOP_LAUNCH_APP_PANEL_PLUGIN_H
+#define _LUMINA_DESKTOP_LAUNCH_APP_PANEL_PLUGIN_H
+
+// Qt includes
+#include <QToolButton>
+#include <QString>
+#include <QWidget>
+
+
+// Lumina-desktop includes
+#include "../LPPlugin.h" //main plugin widget
+
+// libLumina includes
+#include "LuminaXDG.h"
+
+// PANEL PLUGIN BUTTON
+class AppLaunchButtonPlugin : public LPPlugin{
+ Q_OBJECT
+
+public:
+ AppLaunchButtonPlugin(QWidget *parent = 0, QString id = "applauncher", bool horizontal=true);
+ ~AppLaunchButtonPlugin();
+
+private:
+ QToolButton *button;
+ QString appfile;
+
+ void updateButtonVisuals();
+
+private slots:
+ void AppClicked();
+
+public slots:
+ void OrientationChange(){
+ if(this->layout()->direction()==QBoxLayout::LeftToRight){
+ this->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
+ button->setIconSize( QSize(this->height(), this->height()) );
+ }else{
+ this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
+ button->setIconSize( QSize(this->width(), this->width()) );
+ }
+ this->layout()->update();
+ updateButtonVisuals();
+ }
+
+ void LocaleChange(){
+ updateButtonVisuals();
+ }
+
+ void ThemeChange(){
+ updateButtonVisuals();
+ }
+};
+
+#endif \ No newline at end of file
diff --git a/lumina-desktop/panel-plugins/clock/LClock.cpp b/lumina-desktop/panel-plugins/clock/LClock.cpp
index e91a3a71..79cae84b 100644
--- a/lumina-desktop/panel-plugins/clock/LClock.cpp
+++ b/lumina-desktop/panel-plugins/clock/LClock.cpp
@@ -35,6 +35,7 @@ LClock::~LClock(){
void LClock::updateTime(){
QDateTime CT = QDateTime::currentDateTime();
+ if(useTZ){ CT = CT.toTimeZone(TZ); }
//Now update the display
QString label;
if(deftime){ label = CT.time().toString(Qt::SystemLocaleShortDate) ; }
@@ -53,5 +54,8 @@ void LClock::updateFormats(){
datefmt = LSession::handle()->sessionSettings()->value("DateFormat","").toString();
deftime = timefmt.simplified().isEmpty();
defdate = datefmt.simplified().isEmpty();
+ useTZ = LSession::handle()->sessionSettings()->value("CustomTimeZone",false).toBool();
+ if(useTZ){ TZ = QTimeZone( LSession::handle()->sessionSettings()->value("TimeZoneByteCode", QByteArray()).toByteArray() ); }
+
}
diff --git a/lumina-desktop/panel-plugins/clock/LClock.h b/lumina-desktop/panel-plugins/clock/LClock.h
index 1e4c8294..8156e7d8 100644
--- a/lumina-desktop/panel-plugins/clock/LClock.h
+++ b/lumina-desktop/panel-plugins/clock/LClock.h
@@ -13,6 +13,7 @@
#include <QWidget>
#include <QString>
#include <QLocale>
+#include <QTimeZone>
#include "../LPPlugin.h"
@@ -26,7 +27,8 @@ private:
QTimer *timer;
QLabel *labelWidget;
QString timefmt, datefmt;
- bool deftime, defdate;
+ bool deftime, defdate, useTZ;
+ QTimeZone TZ;
private slots:
void updateTime();
diff --git a/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp b/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp
index 7e0a30f6..e966f389 100644
--- a/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp
+++ b/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp
@@ -12,6 +12,10 @@
//#include <xcb/damage.h>
//static xcb_damage_damage_t dmgID;
+
+#include <LSession.h>
+#include <QScreen>
+
static int dmgID = 0;
TrayIcon::TrayIcon(QWidget *parent) : QWidget(parent){
@@ -115,17 +119,23 @@ void TrayIcon::paintEvent(QPaintEvent *event){
//qDebug() << " - Draw tray:" << AID << IID << this->winId();
//qDebug() << " - - " << event->rect().x() << event->rect().y() << event->rect().width() << event->rect().height();
//qDebug() << " - Get image:" << AID;
- QPixmap pix = LX11::WindowImage(AID, false);
+ QPixmap pix = LSession::handle()->XCB->WindowImage(AID);
if(pix.isNull()){
//Try to grab the window directly with Qt
qDebug() << " - - Grab window directly";
- pix = QPixmap::grabWindow(AID);
+ QList<QScreen*> scrnlist = QApplication::screens();
+ for(int i=0; i<scrnlist.length(); i++){
+ pix = scrnlist[i]->grabWindow(AID);
+ break; //stop here
+ }
}
//qDebug() << " - Pix size:" << pix.size().width() << pix.size().height();
//qDebug() << " - Geom:" << this->geometry().x() << this->geometry().y() << this->geometry().width() << this->geometry().height();
if(!pix.isNull()){
if(this->size() != pix.size()){ QTimer::singleShot(10, this, SLOT(updateIcon())); qDebug() << "-- Icon size mismatch"; }
painter.drawPixmap(0,0,this->width(), this->height(), pix.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation) );
+ }else{
+ qDebug() << " - - No Tray Icon/Image found!" << "ID:" << AID;
}
//qDebug() << " - Done";
}
diff --git a/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp b/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp
index 7c24dc3d..20607c60 100644
--- a/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp
+++ b/lumina-desktop/panel-plugins/taskmanager/LTaskButton.cpp
@@ -121,13 +121,14 @@ void LTaskButton::UpdateButton(){
//single window
this->setPopupMode(QToolButton::DelayedPopup);
this->setMenu(actMenu);
- if(showText){ this->setText( this->fontMetrics().elidedText(WINLIST[0].text(), Qt::ElideRight,80) ); }
- else if(noicon){ this->setText( this->fontMetrics().elidedText(cname, Qt::ElideRight ,80) ); }
- else{ this->setText(""); }
+ if(showText){ this->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); this->setText( this->fontMetrics().elidedText(WINLIST[0].text(), Qt::ElideRight,80) ); }
+ else if(noicon){ this->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); this->setText( this->fontMetrics().elidedText(cname, Qt::ElideRight ,80) ); }
+ else{ this->setToolButtonStyle(Qt::ToolButtonIconOnly); this->setText(""); }
}else if(WINLIST.length() > 1){
//multiple windows
this->setPopupMode(QToolButton::InstantPopup);
this->setMenu(winMenu);
+ this->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
if(noicon || showText){ this->setText( this->fontMetrics().elidedText(cname, Qt::ElideRight ,80) +" ("+QString::number(WINLIST.length())+")" ); }
else{ this->setText("("+QString::number(WINLIST.length())+")"); }
}
diff --git a/lumina-desktop/panel-plugins/userbutton/UserItemWidget.cpp b/lumina-desktop/panel-plugins/userbutton/UserItemWidget.cpp
index 3b8be74f..a04c6e43 100644
--- a/lumina-desktop/panel-plugins/userbutton/UserItemWidget.cpp
+++ b/lumina-desktop/panel-plugins/userbutton/UserItemWidget.cpp
@@ -30,7 +30,7 @@ UserItemWidget::UserItemWidget(QWidget *parent, QString itemPath, bool isDir, bo
}
}else{
if(itemPath.endsWith("/")){ itemPath.chop(1); }
- icon->setPixmap( LXDG::findMimeIcon(itemPath.section("/",-1).section(".",-1)).pixmap(32,32) );
+ icon->setPixmap( LXDG::findMimeIcon(itemPath.section("/",-1)).pixmap(32,32) );
name->setText( this->fontMetrics().elidedText(itemPath.section("/",-1), Qt::ElideRight, 180) );
}
linkPath = QFile::symLinkTarget(itemPath);
@@ -101,7 +101,7 @@ void UserItemWidget::setupButton(bool disable){
}else if( !QFile::exists( QDir::homePath()+"/Desktop/"+icon->whatsThis().section("/",-1) ) && !QFile::exists( QDir::homePath()+"/.lumina/favorites/"+icon->whatsThis().section("/",-1) ) ){
//This file does not have a desktop shortcut yet -- allow the user to add it
button->setWhatsThis("add");
- button->setIcon( LXDG::findIcon("favorites","") );
+ button->setIcon( LXDG::findIcon("bookmark-toolbar","") );
button->setToolTip(tr("Create Shortcut"));
connect(button, SIGNAL(clicked()), this, SLOT(buttonClicked()) );
}else{
diff --git a/lumina-desktop/panel-plugins/userbutton/UserWidget.cpp b/lumina-desktop/panel-plugins/userbutton/UserWidget.cpp
index 6ca3ba19..52d60714 100644
--- a/lumina-desktop/panel-plugins/userbutton/UserWidget.cpp
+++ b/lumina-desktop/panel-plugins/userbutton/UserWidget.cpp
@@ -16,7 +16,7 @@ UserWidget::UserWidget(QWidget* parent) : QTabWidget(parent), ui(new Ui::UserWid
sysapps = LSession::handle()->applicationMenu()->currentAppHash(); //get the raw info
//Setup the Icons
// - favorites tab
- this->setTabIcon(0, rotateIcon(LXDG::findIcon("favorites","")) );
+ this->setTabIcon(0, rotateIcon(LXDG::findIcon("folder-favorites","")) );
this->setTabText(0,"");
// - apps tab
this->setTabIcon(1, rotateIcon(LXDG::findIcon("system-run","")) );
@@ -194,6 +194,16 @@ void UserWidget::updateFavItems(){
connect(it, SIGNAL(RemovedShortcut()), this, SLOT(updateFavItems()) );
}
static_cast<QBoxLayout*>(ui->scroll_fav->widget()->layout())->addStretch();
+
+ //Clean up any broken sym-links in the favorites directory
+ /*items = favdir.entryInfoList(QDir::System | QDir::NoDotAndDotDot, QDir::Name);
+ for(int i=0; i<items.length(); i++){
+ if(items[i].isSymLink() && !items[i].exists()){
+ //Broken sym-link - remove it
+ QFile::remove(items[i].absoluteFilePath());
+ }
+ }*/
+
}
//Apps Tab
diff --git a/lumina-fm/BackgroundWorker.cpp b/lumina-fm/BackgroundWorker.cpp
index bbba8749..1438f71e 100644
--- a/lumina-fm/BackgroundWorker.cpp
+++ b/lumina-fm/BackgroundWorker.cpp
@@ -3,6 +3,8 @@
#include <LuminaXDG.h>
#include <QMediaServiceSupportedFormatsInterface>
#include <QImageReader>
+#include <QDir>
+#include <QFileInfo>
BackgroundWorker::BackgroundWorker() : QObject(){
@@ -14,6 +16,9 @@ BackgroundWorker::~BackgroundWorker(){
void BackgroundWorker::startDirChecks(QString path){
QDir dir(path);
+ //Make sure to remove any symlinks or redundency in the path
+ if(dir.canonicalPath()!=path){ path = dir.canonicalPath(); dir.cd(path); }
+ qDebug() << "Starting Dir Checks:" << path;
//First check for image files
if(imgFilter.isEmpty()){
//Initial Run - load supported image extensions
@@ -34,27 +39,30 @@ void BackgroundWorker::startDirChecks(QString path){
}
QStringList files = dir.entryList(multiFilter, QDir::Files | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase);
if(!files.isEmpty() && !multiFilter.isEmpty()){ emit MultimediaAvailable(files); }
-
+ qDebug() << " - done with audio/multimedia checks";
//Now check for ZFS snapshots of the directory
if(!QFileInfo(path).isWritable() ){ return; } //skip ZFS checks if can't restore to this dir
cdir = path;
QStringList snapDirs;
QString baseSnapDir;
bool found = false;
+ qDebug() << " - start searching for base snapshot directory";
if(cdir == path && QFile::exists(csnapdir) ){
//no need to re-search for it - just found it recently
baseSnapDir= csnapdir; found=true;
}else{
- while(dir.absolutePath()!="/" && !found){
+ while(dir.canonicalPath()!="/" && !found){
if(dir.exists(".zfs/snapshot")){
baseSnapDir = dir.canonicalPath()+"/.zfs/snapshot";
found = true;
}else{ dir.cdUp(); }
}
}
+ qDebug() << " - done with base snapshot directory";
cdir = path; csnapdir = baseSnapDir;
//Now find the snapshots that contain this directory and save them
if(found){
+ qDebug() << " - start fetching snapshots";
QString reldir = path;
reldir.remove(baseSnapDir.section("/.zfs/snapshot",0,0)); //convert to a relative path
dir.cd(baseSnapDir);
@@ -68,12 +76,13 @@ void BackgroundWorker::startDirChecks(QString path){
snapDirs[i] = QFileInfo(dir, snapDirs[i]+"/"+reldir).created().toString("yyyyMMddhhmmsszzz")+"::::"+snapDirs[i];
}
}
+ qDebug() << " - done fetching snapshots";
snapDirs.sort();
//Sort the snapshots by time (newest last) and format them
for(int i=0; i<snapDirs.length(); i++){
snapDirs[i] = dir.absolutePath()+"/"+snapDirs[i].section("::::",1,50)+"/"+reldir;
}
if(!snapDirs.isEmpty()){ emit SnapshotsAvailable(baseSnapDir, snapDirs); }
- //qDebug() << "Found snapshots:" << snapDirs;
+ qDebug() << "Found snapshots";
}
} \ No newline at end of file
diff --git a/lumina-fm/MainUI.cpp b/lumina-fm/MainUI.cpp
index 9b7ebcc6..187922e1 100644
--- a/lumina-fm/MainUI.cpp
+++ b/lumina-fm/MainUI.cpp
@@ -173,7 +173,7 @@ void MainUI::setupIcons(){
ui->tool_act_paste->setIcon( LXDG::findIcon("edit-paste","") );
ui->tool_act_rename->setIcon( LXDG::findIcon("edit-rename","") );
ui->tool_act_rm->setIcon( LXDG::findIcon("edit-delete","") );
- ui->tool_act_fav->setIcon( LXDG::findIcon("quickopen","") );
+ ui->tool_act_fav->setIcon( LXDG::findIcon("bookmark-toolbar","") );
//Multimedia Player page
ui->tool_player_next->setIcon( LXDG::findIcon("media-skip-forward","") );
@@ -945,6 +945,7 @@ void MainUI::OpenContextMenu(const QPoint &pt){
contextMenu->addAction(LXDG::findIcon("run-build-configure",""), tr("Open With..."), this, SLOT(OpenItemWith()) );
}
contextMenu->addAction(LXDG::findIcon("edit-rename",""), tr("Rename"), this, SLOT(RenameItem()) )->setEnabled(info.isWritable());
+ contextMenu->addAction(LXDG::findIcon("document-encrypted",""), tr("View Checksums"), this, SLOT(ChecksumItems()) );
contextMenu->addSeparator();
}
bool hasSelection = !getSelectedItems().isEmpty();
@@ -979,7 +980,17 @@ void MainUI::ItemSelectionChanged(){
}
QString itname;
if(sel.length()==1){ itname = sel[0].fileName(); }
- ui->tool_act_fav->setEnabled(!itname.isEmpty() && !QFile::exists(favdir+itname) );
+ bool ok = !itname.isEmpty() && (getCurrentDir()!=QDir::homePath()+"/Desktop");
+ if(ok){
+ if(QFile::exists(favdir+itname)){
+ //Make sure this favorite does not already point to the current file
+ QFileInfo info(favdir+itname);
+ if(info.isSymLink() && info.exists()){
+ ok = false; //still an active favorite - do not allow replacement
+ }
+ }
+ }
+ ui->tool_act_fav->setEnabled(ok);
}
//-------------------------------
@@ -1293,17 +1304,17 @@ void MainUI::RemoveItem(){
if(!checkUserPerms()){ return; }
//Get the selected items
QStringList paths, names;
- if(CItem.isEmpty()){
+ //if(CItem.isEmpty()){
QFileInfoList sel = getSelectedItems();
for(int i=0; i<sel.length(); i++){
paths << sel[i].absoluteFilePath();
names << sel[i].fileName();
}
if(sel.isEmpty()){ return; } //nothing selected
- }else{
+ /*}else{
paths << CItem;
names << CItem.section("/",-1);
- }
+ }*/
//Verify permanent removal of file/dir
if(QMessageBox::Yes != QMessageBox::question(this, tr("Verify Removal"), tr("WARNING: This will permanently delete the file(s) from the system!")+"\n"+tr("Are you sure you want to continue?")+"\n\n"+names.join("\n"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) ){
return; //cancelled
@@ -1371,6 +1382,7 @@ void MainUI::FavoriteItem(){
QString fname = CItem;
QString fullpath = fname;
fname = fname.section("/",-1); //turn this into just the file name
+ if(QFile::exists(favdir+fname)){ QFile::remove(favdir+fname); } //remove the stale link
QFile::link(fullpath, favdir+fname);
CItem.clear();
ItemSelectionChanged();
@@ -1470,8 +1482,30 @@ void MainUI::PasteItems(){
QApplication::clipboard()->setMimeData(dat);
}
}
- ItemSelectionChanged();
-
+ ItemSelectionChanged();
+}
+
+void MainUI::ChecksumItems(){
+ if(ui->stackedWidget->currentWidget()!=ui->page_browser){ return; }
+ QFileInfoList sel = getSelectedItems();
+ if(sel.isEmpty()){ return; }
+ QStringList info, files;
+ for(int i=0; i<sel.length(); i++){
+ files << sel[i].absoluteFilePath();
+ }
+ qDebug() << "Run Checksums:" << files;
+ info = LOS::Checksums(files);
+ qDebug() << " - Info:" << info;
+ if(info.isEmpty() || (info.length() != files.length()) ){ return; }
+ for(int i=0; i<info.length(); i++){
+ info[i] = QString("%2 \t(%1)").arg(files[i].section("/",-1), info[i]);
+ }
+ /*QMessageBox dlg(this);
+ dlg.setWindowFlags( Qt::Dialog );
+ dlg.setWindowTitle( tr("File Checksums") );
+ dlg.setInformativeText(info.join("\n"));
+ dlg.exec();*/
+ QMessageBox::information(this, tr("File Checksums"), info.join("\n") );
}
void MainUI::resizeEvent(QResizeEvent *event){
diff --git a/lumina-fm/MainUI.h b/lumina-fm/MainUI.h
index 40ef25ff..97cadf86 100644
--- a/lumina-fm/MainUI.h
+++ b/lumina-fm/MainUI.h
@@ -89,7 +89,6 @@ private:
//Phonon Widgets for the multimedia player
QMediaPlayer *mediaObj;
QVideoWidget *videoDisplay;
- //Phonon::AudioOutput *audioOut;
QSlider *playerSlider;
QString playerTTime; //total time - to prevent recalculation every tick
@@ -219,6 +218,7 @@ private slots:
void CutItems();
void CopyItems();
void PasteItems();
+ void ChecksumItems();
signals:
void DirChanged(QString path);
diff --git a/lumina-fm/MimeIconProvider.h b/lumina-fm/MimeIconProvider.h
index 344d6801..0c9ba98e 100644
--- a/lumina-fm/MimeIconProvider.h
+++ b/lumina-fm/MimeIconProvider.h
@@ -34,8 +34,16 @@ public:
if(showthumbnails && (info.suffix().toLower()=="png" || info.suffix().toLower()=="jpg") ){
//make sure to only load small versions of the files into memory: could have hundreds of them...
return QIcon( QPixmap(info.absoluteFilePath()).scaledToHeight(64) );
+ }else if(info.fileName().endsWith(".desktop") ){
+ bool ok = false;
+ XDGDesktop desk = LXDG::loadDesktopFile(info.absoluteFilePath(), ok);
+ if(ok){
+ return LXDG::findIcon(desk.icon, "unknown");
+ }else{
+ return LXDG::findMimeIcon(info.fileName());
+ }
}else{
- return LXDG::findMimeIcon(info.suffix());
+ return LXDG::findMimeIcon(info.fileName());
}
}else{
return LXDG::findIcon("unknown","");
diff --git a/lumina-open/LFileDialog.cpp b/lumina-open/LFileDialog.cpp
index d648925b..361cd99f 100644
--- a/lumina-open/LFileDialog.cpp
+++ b/lumina-open/LFileDialog.cpp
@@ -239,7 +239,7 @@ void LFileDialog::on_tool_ok_clicked(){
bool ok = false;
XDGDesktop app = LXDG::loadDesktopFile(PREFAPPS[ui->combo_rec->currentIndex()], ok);
//Set the output variables
- appExec = app.exec;
+ appExec = LXDG::getDesktopExec(app);
appPath = app.path;
appFile = app.filePath;
setPreferredApplication(app.filePath); //bump this to the top of the preferred list for next time
@@ -248,7 +248,7 @@ void LFileDialog::on_tool_ok_clicked(){
bool ok = false;
XDGDesktop app = LXDG::loadDesktopFile(ui->tree_apps->currentItem()->whatsThis(0), ok);
//Set the output variables
- appExec = app.exec;
+ appExec = LXDG::getDesktopExec(app);
appPath = app.path;
appFile = app.filePath;
setPreferredApplication(app.filePath); //save this app to this extension as a recommendation
diff --git a/lumina-open/main.cpp b/lumina-open/main.cpp
index 4a9f7639..657ffc07 100644
--- a/lumina-open/main.cpp
+++ b/lumina-open/main.cpp
@@ -43,6 +43,16 @@ void printUsageInfo(){
exit(1);
}
+void ShowErrorDialog(int argc, char **argv, QString message){
+ //Setup the application
+ QApplication App(argc, argv);
+ LuminaThemeEngine theme(&App);
+ LUtils::LoadTranslation(&App,"lumina-open");
+ QMessageBox dlg(QMessageBox::Critical, QObject::tr("File Error"), message );
+ dlg.exec();
+ exit(1);
+}
+
void showOSD(int argc, char **argv, QString message){
//Setup the application
QApplication App(argc, argv);
@@ -187,7 +197,7 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat
if(QFile::exists(inFile)){ isFile=true; }
else if(QFile::exists(QDir::currentPath()+"/"+inFile)){isFile=true; inFile = QDir::currentPath()+"/"+inFile;} //account for relative paths
else if(QUrl(inFile).isValid() && !inFile.startsWith("/") ){ isUrl=true; }
- if( !isFile && !isUrl ){ qDebug() << "Error: Invalid file or URL"; return;}
+ if( !isFile && !isUrl ){ ShowErrorDialog( argc, argv, QString(QObject::tr("Invalid file or URL: %1")).arg(inFile) ); }
//Determing the type of file (extension)
QString extension;
//qDebug() << "File Type:" << isFile << isUrl;
@@ -209,8 +219,7 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat
bool ok = false;
XDGDesktop DF = LXDG::loadDesktopFile(inFile, ok);
if(!ok){
- qDebug() << "[ERROR] Input *.desktop file could not be read:" << inFile;
- exit(1);
+ ShowErrorDialog( argc, argv, QString(QObject::tr("File could not be opened: %1")).arg(inFile) );
}
switch(DF.type){
case XDGDesktop::APP:
@@ -218,8 +227,7 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat
cmd = LXDG::getDesktopExec(DF);
if(!DF.path.isEmpty()){ path = DF.path; }
}else{
- qDebug() << "[ERROR] Input *.desktop application file is missing the Exec line:" << inFile;
- exit(1);
+ ShowErrorDialog( argc, argv, QString(QObject::tr("Application shortcut is missing the launching information (malformed shortcut): %1")).arg(inFile) );
}
break;
case XDGDesktop::LINK:
@@ -229,8 +237,7 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat
cmd.clear();
extension = inFile.section(":",0,0);
}else{
- qDebug() << "[ERROR] Input *.desktop link file is missing the URL line:" << inFile;
- exit(1);
+ ShowErrorDialog( argc, argv, QString(QObject::tr("URL shortcut is missing the URL: %1")).arg(inFile) );
}
break;
case XDGDesktop::DIR:
@@ -240,13 +247,11 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat
cmd.clear();
extension = "directory";
}else{
- qDebug() << "[ERROR] Input *.desktop directory file is missing the Path line:" << inFile;
- exit(1);
+ ShowErrorDialog( argc, argv, QString(QObject::tr("Directory shortcut is missing the path to the directory: %1")).arg(inFile) );
}
break;
default:
- qDebug() << "[ERROR] Unknown *.desktop file type:" << inFile;
- exit(1);
+ ShowErrorDialog( argc, argv, QString(QObject::tr("Unknown type of shortcut : %1")).arg(inFile) );
}
}
if(cmd.isEmpty()){
diff --git a/lumina-xconfig/MainUI.cpp b/lumina-xconfig/MainUI.cpp
index a4131649..4fa9236f 100644
--- a/lumina-xconfig/MainUI.cpp
+++ b/lumina-xconfig/MainUI.cpp
@@ -56,9 +56,13 @@ void MainUI::UpdateScreens(){
SCREENS << cscreen; //current screen finished - save it into the array
cscreen = ScreenInfo(); //Now create a new structure
}
+ //qDebug() << "Line:" << info[i];
QString dev = info[i].section(" ",0,0); //device ID
- QString devres = info[i].section("(",0,0).split(" ",QString::SkipEmptyParts).last();
- qDebug() << " - ID:" <<dev;
+ //The device resolution can be either the 3rd or 4th output - check both
+ QString devres = info[i].section(" ",2,2, QString::SectionSkipEmpty);
+ if(!devres.contains("x")){ devres = info[i].section(" ",3,3,QString::SectionSkipEmpty); }
+ if(!devres.contains("x")){ devres.clear(); }
+ qDebug() << " - ID:" <<dev << "Current Geometry:" << devres;
//qDebug() << " - Res:" << devres;
if( !devres.contains("x") || !devres.contains("+") ){ devres.clear(); }
//qDebug() << " - Res (modified):" << devres;
@@ -74,7 +78,7 @@ void MainUI::UpdateScreens(){
//Note: devres format: "<width>x<height>+<xoffset>+<yoffset>"
cscreen.geom.setRect( devres.section("+",-2,-2).toInt(), devres.section("+",-1,-1).toInt(), devres.section("x",0,0).toInt(), devres.section("+",0,0).section("x",1,1).toInt() );
- }else if(info[i].contains(" connected ")){
+ }else if(info[i].contains(" connected")){
//Device that is connected, but not attached
qDebug() << "Create new Screen entry:" << dev << "none";
cscreen.ID = dev;
bgstack15