diff options
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; |