aboutsummaryrefslogtreecommitdiff
path: root/src-qt5
diff options
context:
space:
mode:
Diffstat (limited to 'src-qt5')
-rw-r--r--src-qt5/OS-detect.pri2
-rw-r--r--src-qt5/core-utils/lumina-config/pages/getPage.cpp4
-rw-r--r--src-qt5/core-utils/lumina-config/pages/page_defaultapps.cpp2
-rw-r--r--src-qt5/core-utils/lumina-config/pages/page_soundtheme.cpp113
-rw-r--r--src-qt5/core-utils/lumina-config/pages/page_soundtheme.h42
-rw-r--r--src-qt5/core-utils/lumina-config/pages/page_soundtheme.ui156
-rw-r--r--src-qt5/core-utils/lumina-config/pages/page_wallpaper.cpp2
-rw-r--r--src-qt5/core-utils/lumina-config/pages/pages.pri11
-rw-r--r--src-qt5/core-utils/lumina-xconfig/ScreenSettings.cpp8
-rw-r--r--src-qt5/core/libLumina/ExternalProcess.h11
-rw-r--r--src-qt5/core/libLumina/LDesktopUtils.cpp58
-rw-r--r--src-qt5/core/libLumina/LDesktopUtils.h2
-rw-r--r--src-qt5/core/libLumina/LDesktopUtils.pri1
-rw-r--r--src-qt5/core/libLumina/LUtils.cpp84
-rw-r--r--src-qt5/core/libLumina/LUtils.h3
-rw-r--r--src-qt5/core/libLumina/LVideoLabel.cpp120
-rw-r--r--src-qt5/core/libLumina/LVideoLabel.h42
-rw-r--r--src-qt5/core/libLumina/LVideoLabel.pri13
-rw-r--r--src-qt5/core/libLumina/LVideoSurface.cpp60
-rw-r--r--src-qt5/core/libLumina/LVideoSurface.h26
-rw-r--r--src-qt5/core/libLumina/LVideoSurface.pri9
-rw-r--r--src-qt5/core/libLumina/LVideoWidget.cpp38
-rw-r--r--src-qt5/core/libLumina/LVideoWidget.h22
-rw-r--r--src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp23
-rw-r--r--src-qt5/core/libLumina/LuminaOS.h14
-rw-r--r--src-qt5/core/libLumina/LuminaSingleApplication.cpp2
-rw-r--r--src-qt5/core/libLumina/LuminaThemes.cpp62
-rw-r--r--src-qt5/core/libLumina/LuminaThemes.h8
-rw-r--r--src-qt5/core/libLumina/LuminaXDG.cpp39
-rw-r--r--src-qt5/core/libLumina/obsolete/RootSubWindow-animations.cpp (renamed from src-qt5/core/libLumina/RootSubWindow-animations.cpp)0
-rw-r--r--src-qt5/core/libLumina/obsolete/RootSubWindow.cpp (renamed from src-qt5/core/libLumina/RootSubWindow.cpp)0
-rw-r--r--src-qt5/core/libLumina/obsolete/RootSubWindow.h (renamed from src-qt5/core/libLumina/RootSubWindow.h)0
-rw-r--r--src-qt5/core/libLumina/obsolete/RootWindow-mgmt.cpp (renamed from src-qt5/core/libLumina/RootWindow-mgmt.cpp)0
-rw-r--r--src-qt5/core/libLumina/obsolete/RootWindow.cpp (renamed from src-qt5/core/libLumina/RootWindow.cpp)0
-rw-r--r--src-qt5/core/libLumina/obsolete/RootWindow.h (renamed from src-qt5/core/libLumina/RootWindow.h)0
-rw-r--r--src-qt5/core/libLumina/obsolete/RootWindow.pri (renamed from src-qt5/core/libLumina/RootWindow.pri)0
-rw-r--r--src-qt5/core/lumina-checkpass/main.c43
-rw-r--r--src-qt5/core/lumina-desktop-unified/LSession.cpp20
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/LICENCE7
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Login.oggbin32111 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Logout.oggbin31255 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/low-battery.oggbin49748 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/lumina-desktop.desktop34
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Fireflies.json26
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/README.md79
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Video.json25
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Warp.json25
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Fireflies.qml19
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Firefly.qml63
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Grav.qml106
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Video.qml50
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Warp.qml64
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey-zoom.jpgbin6269314 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey.jpgbin6508360 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_gold.jpgbin2523711 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_green.jpgbin1286362 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue-zoom.jpgbin563037 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue.jpgbin361771 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_purple.jpgbin926969 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_red.jpgbin1141515 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-desktop-unified/global-includes.h11
-rw-r--r--src-qt5/core/lumina-desktop-unified/global-objects.h4
-rw-r--r--src-qt5/core/lumina-desktop-unified/lumina-desktop.pro28
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.cpp44
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h34
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri11
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp77
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h54
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp31
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.h48
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/src-cpp.pri8
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/ContextMenu.qml36
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml57
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/WallpaperImage.qml25
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri7
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc7
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-screensaver/LLockScreen.cpp13
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp65
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h14
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-screensaver/screensaver.pri4
-rw-r--r--src-qt5/core/lumina-desktop/LDesktop.cpp76
-rw-r--r--src-qt5/core/lumina-desktop/LDesktopPluginSpace.cpp18
-rw-r--r--src-qt5/core/lumina-desktop/LSession.cpp56
-rw-r--r--src-qt5/core/lumina-desktop/LSession.h31
-rw-r--r--src-qt5/core/lumina-desktop/LXcbEventFilter.cpp18
-rw-r--r--src-qt5/core/lumina-desktop/WMProcess.cpp6
-rw-r--r--src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf2
-rw-r--r--src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf2
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp3
-rw-r--r--src-qt5/core/lumina-desktop/lumina-desktop.pro11
-rw-r--r--src-qt5/core/lumina-desktop/main.cpp24
-rw-r--r--src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp5
-rw-r--r--src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.h1
-rw-r--r--src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp5
-rw-r--r--src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp18
-rw-r--r--src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h4
-rw-r--r--src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey-zoom.jpgbin6269314 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey.jpgbin6508360 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_gold.jpgbin2523711 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_green.jpgbin1286362 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue-zoom.jpgbin563037 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue.jpgbin361771 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_purple.jpgbin926969 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_red.jpgbin1141515 -> 0 bytes
-rw-r--r--src-qt5/core/lumina-open/LFileDialog.cpp6
-rw-r--r--src-qt5/core/lumina-open/lumina-open.12
-rw-r--r--src-qt5/core/lumina-open/main.cpp278
-rw-r--r--src-qt5/core/lumina-session/main.cpp20
-rw-r--r--src-qt5/core/lumina-session/session.cpp26
-rw-r--r--src-qt5/core/lumina-session/session.h2
-rw-r--r--src-qt5/core/lumina-theme-engine/qss/scrollbar-simple.qss2
-rw-r--r--src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss70
-rw-r--r--src-qt5/core/lumina-theme-engine/qss/tooltip-simple.qss7
-rw-r--r--src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.cpp2
-rw-r--r--src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.ui2
-rw-r--r--src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.cpp33
-rw-r--r--src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.h1
-rw-r--r--src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.ui41
-rw-r--r--src-qt5/desktop-utils/lumina-archiver/MainUI.cpp98
-rw-r--r--src-qt5/desktop-utils/lumina-archiver/MainUI.h19
-rw-r--r--src-qt5/desktop-utils/lumina-archiver/TarBackend.cpp5
-rw-r--r--src-qt5/desktop-utils/lumina-archiver/TarBackend.h2
-rw-r--r--src-qt5/desktop-utils/lumina-archiver/main.cpp2
-rw-r--r--src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp460
-rw-r--r--src-qt5/desktop-utils/lumina-fileinfo/MainUI.h42
-rw-r--r--src-qt5/desktop-utils/lumina-fileinfo/MainUI.ui1048
-rw-r--r--src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro3
-rw-r--r--src-qt5/desktop-utils/lumina-fileinfo/main.cpp32
-rw-r--r--src-qt5/desktop-utils/lumina-fm/Browser.cpp88
-rw-r--r--src-qt5/desktop-utils/lumina-fm/Browser.h12
-rw-r--r--src-qt5/desktop-utils/lumina-fm/BrowserModel.cpp208
-rw-r--r--src-qt5/desktop-utils/lumina-fm/BrowserModel.h87
-rw-r--r--src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp59
-rw-r--r--src-qt5/desktop-utils/lumina-fm/BrowserWidget.h6
-rw-r--r--src-qt5/desktop-utils/lumina-fm/MainUI.cpp33
-rw-r--r--src-qt5/desktop-utils/lumina-fm/MainUI.h3
-rw-r--r--src-qt5/desktop-utils/lumina-fm/MainUI.ui7
-rw-r--r--src-qt5/desktop-utils/lumina-fm/VideoItemWidget.h144
-rw-r--r--src-qt5/desktop-utils/lumina-fm/lumina-fm.pro2
-rw-r--r--src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h61
-rw-r--r--src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp21
-rw-r--r--src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.h9
-rw-r--r--src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.ui29
-rw-r--r--src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.cpp36
-rw-r--r--src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.h36
-rw-r--r--src-qt5/desktop-utils/lumina-fm/widgets/vidnail.cpp59
-rw-r--r--src-qt5/desktop-utils/lumina-fm/widgets/vidnail.h13
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/MainUI.cpp11
-rw-r--r--src-qt5/desktop-utils/lumina-xdg-entry/mainwindow.cpp2
-rw-r--r--src-qt5/src-cpp/NativeEmbedWidget.cpp (renamed from src-qt5/core/libLumina/NativeEmbedWidget.cpp)0
-rw-r--r--src-qt5/src-cpp/NativeEmbedWidget.h (renamed from src-qt5/core/libLumina/NativeEmbedWidget.h)0
-rw-r--r--src-qt5/src-cpp/NativeEventFilter.cpp (renamed from src-qt5/core/libLumina/NativeEventFilter.cpp)0
-rw-r--r--src-qt5/src-cpp/NativeEventFilter.h (renamed from src-qt5/core/libLumina/NativeEventFilter.h)0
-rw-r--r--src-qt5/src-cpp/NativeKeyToQt.cpp (renamed from src-qt5/core/libLumina/NativeKeyToQt.cpp)0
-rw-r--r--src-qt5/src-cpp/NativeWindow.cpp (renamed from src-qt5/core/libLumina/NativeWindow.cpp)0
-rw-r--r--src-qt5/src-cpp/NativeWindow.h (renamed from src-qt5/core/libLumina/NativeWindow.h)0
-rw-r--r--src-qt5/src-cpp/NativeWindow.pri (renamed from src-qt5/core/libLumina/NativeWindow.pri)1
-rw-r--r--src-qt5/src-cpp/NativeWindowSystem.cpp (renamed from src-qt5/core/libLumina/NativeWindowSystem.cpp)0
-rw-r--r--src-qt5/src-cpp/NativeWindowSystem.h (renamed from src-qt5/core/libLumina/NativeWindowSystem.h)0
-rw-r--r--src-qt5/src-cpp/plugins-screensaver.cpp150
-rw-r--r--src-qt5/src-cpp/plugins-screensaver.h50
-rw-r--r--src-qt5/src-cpp/plugins-screensaver.pri4
-rw-r--r--src-qt5/src-qml/test/CPUGaugeStyle.qml156
-rw-r--r--src-qt5/src-qml/test/Clock.qml101
-rw-r--r--src-qt5/src-qml/test/File.qml21
-rw-r--r--src-qt5/src-qml/test/ListData.h41
-rw-r--r--src-qt5/src-qml/test/ListTest.qml19
-rw-r--r--src-qt5/src-qml/test/Video.qml50
-rw-r--r--src-qt5/src-qml/test/main.cpp28
-rw-r--r--src-qt5/src-qml/test/test-basic.qml48
-rw-r--r--src-qt5/src-qml/test/test-cpugauge.qml108
-rw-r--r--src-qt5/src-qml/test/test.pro5
-rw-r--r--src-qt5/src-qml/test/testlist.cpp37
-rw-r--r--src-qt5/src-qml/test/testlist.pro7
174 files changed, 5069 insertions, 1282 deletions
diff --git a/src-qt5/OS-detect.pri b/src-qt5/OS-detect.pri
index 9f3019e3..8511bd81 100644
--- a/src-qt5/OS-detect.pri
+++ b/src-qt5/OS-detect.pri
@@ -23,7 +23,7 @@
# =============================================
isEmpty(OS){
message("Build OS Info: $${QMAKE_HOST.os}, $${QMAKE_HOST.arch}, $${QMAKE_HOST.version_string}")
-
+ message(" - Detected Qt Version: $${QT_VERSION}")
#Load the initial library/includefile search locations (more can be added in the OS-specific sections below)
LIBS = -L$${PWD}/core/libLumina -L$$[QT_INSTALL_LIBS]
INCLUDEPATH = $${PWD}/core/libLumina $$[QT_INSTALL_HEADERS] $$[QT_INSTALL_PREFIX]
diff --git a/src-qt5/core-utils/lumina-config/pages/getPage.cpp b/src-qt5/core-utils/lumina-config/pages/getPage.cpp
index 7274ae3f..c3f88e2c 100644
--- a/src-qt5/core-utils/lumina-config/pages/getPage.cpp
+++ b/src-qt5/core-utils/lumina-config/pages/getPage.cpp
@@ -20,6 +20,7 @@
#include "page_session_locale.h"
#include "page_session_options.h"
#include "page_compton.h"
+#include "page_soundtheme.h"
// #include "page_mouse_trueos.h"
// #include "page_bluetooth_trueos.h"
@@ -51,6 +52,7 @@ QList<PAGEINFO> Pages::KnownPages(){
list << Pages::PageInfo("interface-menu", QObject::tr("Menu"), QObject::tr("Menu Plugins"), "format-list-unordered",QObject::tr("Change what options are shown on the desktop context menu"), "interface", QStringList(), QStringList() << "desktop" << "menu" << "plugins" << "shortcuts");
list << Pages::PageInfo("session-locale", QObject::tr("Localization"), QObject::tr("Locale Settings"), "preferences-desktop-locale",QObject::tr("Change the default locale settings for this user"), "user", QStringList(), QStringList() << "user"<<"locale"<<"language"<<"translations");
list << Pages::PageInfo("session-options", QObject::tr("General Options"), QObject::tr("User Settings"), "configure",QObject::tr("Change basic user settings such as time/date formats"), "user", QStringList(), QStringList() << "user"<<"settings"<<"time"<<"date"<<"icon"<<"reset"<<"numlock"<<"clock");
+ list << Pages::PageInfo("soundtheme", QObject::tr("Sound Themeing"), QObject::tr("Theme"), "media-playlist-audio",QObject::tr("Change basic sound settings"), "session", QStringList(), QStringList() << "session"<<"settings"<<"sound"<<"theme");
// list << Pages::PageInfo("mouse-settings", QObject::tr("TrueOS Mouse Settings"), QObject::tr("TrueOS Mouse Settings"), "preferences-desktop-mouse",QObject::tr("Adjust mouse devices"), "user", QStringList(), QStringList() << "user"<<"speed"<<"accel"<<"mouse");
// list << Pages::PageInfo("bluetooth-settings", QObject::tr("TrueOS Bluetooth Settings"), QObject::tr("TrueOS Bluetooth Settings"), "preferences-desktop-bluetooth",QObject::tr("Setup Bluetooth devices"), "user", QStringList(), QStringList() << "user"<<"bluetooth"<<"audio");
@@ -72,7 +74,7 @@ PageWidget* Pages::GetNewPage(QString id, QWidget *parent){
else if(id=="session-locale"){ page = new page_session_locale(parent); }
else if(id=="session-options"){ page = new page_session_options(parent); }
else if(id=="compton"){ page = new page_compton(parent); }
-
+ else if(id=="soundtheme"){ page = new page_soundtheme(parent); }
// else if(id=="mouse-settings"){ page = new page_mouse_trueos(parent); }
// else if(id=="bluetooth-settings"){ page = new page_bluetooth_trueos(parent); }
//Return the main control_panel page as the fallback/default
diff --git a/src-qt5/core-utils/lumina-config/pages/page_defaultapps.cpp b/src-qt5/core-utils/lumina-config/pages/page_defaultapps.cpp
index c2d689ec..df7ae516 100644
--- a/src-qt5/core-utils/lumina-config/pages/page_defaultapps.cpp
+++ b/src-qt5/core-utils/lumina-config/pages/page_defaultapps.cpp
@@ -245,7 +245,7 @@ void page_defaultapps::setdefaultitem(){
//Now set the items
for(int i=0; i<list.length(); i++){
//Set it in the back end
- LXDG::setDefaultAppForMime(list[i]->whatsThis(0), app.section("/",-1));
+ LXDG::setDefaultAppForMime(list[i]->whatsThis(0), app);
//Set it in the UI
XDGDesktop desk(app);
list[i]->setWhatsThis(1,app); //app path
diff --git a/src-qt5/core-utils/lumina-config/pages/page_soundtheme.cpp b/src-qt5/core-utils/lumina-config/pages/page_soundtheme.cpp
new file mode 100644
index 00000000..fbb0e7e7
--- /dev/null
+++ b/src-qt5/core-utils/lumina-config/pages/page_soundtheme.cpp
@@ -0,0 +1,113 @@
+//===========================================
+// Lumina Desktop Source Code
+// Copyright (c) 2017, JT (q5sys)
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "page_soundtheme.h"
+#include "ui_page_soundtheme.h"
+#include "../AppDialog.h"
+
+//==========
+// PUBLIC
+//==========
+page_soundtheme::page_soundtheme(QWidget *parent) : PageWidget(parent), ui(new Ui::page_soundtheme()){
+ ui->setupUi(this);
+}
+
+page_soundtheme::~page_soundtheme(){
+
+}
+
+//================
+// PUBLIC SLOTS
+//================
+void page_soundtheme::SaveSettings(){
+ sessionsettings = new QSettings("lumina-desktop", "sessionsettings");
+
+ sessionsettings->setValue("PlayStartupAudio", ui->checkBox_startup->isChecked());
+ sessionsettings->setValue("audiofiles/login", ui->label_startup->whatsThis());
+
+ sessionsettings->setValue("PlayLogoutAudio", ui->checkBox_logout->isChecked());
+ sessionsettings->setValue("audiofiles/logout", ui->label_logout->whatsThis());
+
+ sessionsettings->setValue("PlayBatteryLowAudio", ui->checkBox_battery->isChecked());
+ sessionsettings->setValue("audiofiles/batterylow", ui->label_battery->whatsThis());
+
+}
+
+void page_soundtheme::LoadSettings(int){
+ emit ChangePageTitle( tr("Sound Themes") );
+
+ sessionsettings = new QSettings("lumina-desktop", "sessionsettings");
+
+ ui->label_startup->setText(sessionsettings->value("audiofiles/login").toString().section("/",-1));
+ ui->label_startup->setToolTip(sessionsettings->value("audiofiles/batterylow").toString());
+ ui->label_startup->setWhatsThis(sessionsettings->value("audiofiles/login").toString());
+ bool playstartup = sessionsettings->value("PlayStartupAudio").toBool();
+ if( playstartup ){ ui->checkBox_startup->setChecked(true); }
+
+ ui->label_logout->setText(sessionsettings->value("audiofiles/logout").toString().section("/",-1));
+ ui->label_startup->setToolTip(sessionsettings->value("audiofiles/batterylow").toString());
+ ui->label_logout->setWhatsThis(sessionsettings->value("audiofiles/logout").toString());
+ bool playlogout = sessionsettings->value("PlayLogoutAudio").toBool();
+ if( playlogout ){ ui->checkBox_logout->setChecked(true); }
+
+ ui->label_battery->setText(sessionsettings->value("audiofiles/batterylow").toString().section("/",-1));
+ ui->label_startup->setToolTip(sessionsettings->value("audiofiles/batterylow").toString());
+ ui->label_battery->setWhatsThis(sessionsettings->value("audiofiles/batterylow").toString());
+ bool playbattery = sessionsettings->value("PlayBatteryLowAudio").toBool();
+ if( playbattery ){ ui->checkBox_battery->setChecked(true);}
+ emit HasPendingChanges(false);
+}
+
+//=================
+// PRIVATE
+//=================
+
+//=================
+// PRIVATE SLOTS
+//=================
+
+void page_soundtheme::on_pushButton_startup_clicked(){
+ QString startupsound = QFileDialog::getOpenFileName(this, tr("Select Startup Sound"), QDir::homePath());
+ if(startupsound.isEmpty()){ return; }
+ ui->label_startup->setText(startupsound.section("/",-1));
+ ui->label_startup->setToolTip(startupsound);
+ ui->label_startup->setWhatsThis(startupsound);
+ settingChanged();
+ qDebug() << "startup whats this" << startupsound;
+}
+
+void page_soundtheme::on_pushButton_logout_clicked(){
+ QString logoutsound = QFileDialog::getOpenFileName(this, tr("Select Logout Sound"), QDir::homePath());
+ if(logoutsound.isEmpty()){ return; }
+ ui->label_logout->setText(logoutsound.section("/",-1));
+ ui->label_logout->setToolTip(logoutsound);
+ ui->label_logout->setWhatsThis(logoutsound);
+ qDebug() << "startup whats this" << logoutsound;
+ settingChanged();
+}
+
+void page_soundtheme::on_pushButton_battery_clicked(){
+ QString batterysound = QFileDialog::getOpenFileName(this, tr("Select Low Battery Sound"), QDir::homePath());
+ if(batterysound.isEmpty()){ return; }
+ ui->label_battery->setText(batterysound.section("/",-1));
+ ui->label_battery->setToolTip(batterysound);
+ ui->label_battery->setWhatsThis(batterysound);
+ qDebug() << "startup whats this" << batterysound;
+ settingChanged();
+}
+
+
+void page_soundtheme::on_checkBox_startup_toggled(bool checked){
+ settingChanged();
+}
+
+void page_soundtheme::on_checkBox_logout_toggled(bool checked){
+ settingChanged();
+}
+
+void page_soundtheme::on_checkBox_battery_toggled(bool checked){
+ settingChanged();
+}
diff --git a/src-qt5/core-utils/lumina-config/pages/page_soundtheme.h b/src-qt5/core-utils/lumina-config/pages/page_soundtheme.h
new file mode 100644
index 00000000..5d3bed66
--- /dev/null
+++ b/src-qt5/core-utils/lumina-config/pages/page_soundtheme.h
@@ -0,0 +1,42 @@
+//===========================================
+// Lumina Desktop Source Code
+// Copyright (c) 2017, JT (q5sys)
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#ifndef _LUMINA_CONFIG_PAGE_SOUNDTHEME_H
+#define _LUMINA_CONFIG_PAGE_SOUNDTHEME_H
+#include "../globals.h"
+#include "PageWidget.h"
+
+namespace Ui{
+ class page_soundtheme;
+};
+
+class page_soundtheme : public PageWidget{
+ Q_OBJECT
+public:
+ page_soundtheme(QWidget *parent);
+ ~page_soundtheme();
+
+public slots:
+
+ void SaveSettings();
+ void LoadSettings(int screennum);
+
+
+private:
+ Ui::page_soundtheme *ui;
+ QString startupsound, logoutsound, batterysound;
+ QSettings *sessionsettings;
+
+private slots:
+
+ void on_pushButton_startup_clicked();
+ void on_pushButton_logout_clicked();
+ void on_pushButton_battery_clicked();
+ void on_checkBox_startup_toggled(bool checked);
+ void on_checkBox_logout_toggled(bool checked);
+ void on_checkBox_battery_toggled(bool checked);
+};
+#endif
diff --git a/src-qt5/core-utils/lumina-config/pages/page_soundtheme.ui b/src-qt5/core-utils/lumina-config/pages/page_soundtheme.ui
new file mode 100644
index 00000000..329b68a4
--- /dev/null
+++ b/src-qt5/core-utils/lumina-config/pages/page_soundtheme.ui
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>page_soundtheme</class>
+ <widget class="QWidget" name="page_soundtheme">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>455</width>
+ <height>326</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QCheckBox" name="checkBox_startup">
+ <property name="text">
+ <string>Enabled</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_startup">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButton_startup">
+ <property name="text">
+ <string>Set Startup Audio</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QCheckBox" name="checkBox_logout">
+ <property name="text">
+ <string>Enabled</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_logout">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButton_logout">
+ <property name="text">
+ <string>Set Logout Audio</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QCheckBox" name="checkBox_battery">
+ <property name="text">
+ <string>Enabled</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_battery">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButton_battery">
+ <property name="text">
+ <string>Set Battery Audio</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src-qt5/core-utils/lumina-config/pages/page_wallpaper.cpp b/src-qt5/core-utils/lumina-config/pages/page_wallpaper.cpp
index 6842dce4..839269ca 100644
--- a/src-qt5/core-utils/lumina-config/pages/page_wallpaper.cpp
+++ b/src-qt5/core-utils/lumina-config/pages/page_wallpaper.cpp
@@ -221,7 +221,7 @@ void page_wallpaper::deskbgcoloradded(){
ui->combo_desk_bg->addItem( QString(tr("Solid Color: %1")).arg(color), color);
//Now move to the last item in the list (the new image(s));
ui->combo_desk_bg->setCurrentIndex( ui->combo_desk_bg->count()-1 );
-
+
emit HasPendingChanges(true);
}
diff --git a/src-qt5/core-utils/lumina-config/pages/pages.pri b/src-qt5/core-utils/lumina-config/pages/pages.pri
index ce167d27..585a2922 100644
--- a/src-qt5/core-utils/lumina-config/pages/pages.pri
+++ b/src-qt5/core-utils/lumina-config/pages/pages.pri
@@ -13,8 +13,9 @@ HEADERS += $${PWD}/getPage.h \
$${PWD}/page_interface_panels.h \
$${PWD}/page_session_locale.h \
$${PWD}/page_session_options.h \
- $${PWD}/page_compton.h
-# $${PWD}/page_bluetooth_trueos.h
+ $${PWD}/page_compton.h \
+ $$PWD/page_soundtheme.h
+# $${PWD}/page_bluetooth_trueos.h
# $${PWD}/page_mouse_trueos.h
@@ -31,7 +32,8 @@ SOURCES += $${PWD}/getPage.cpp \
$${PWD}/page_interface_panels.cpp \
$${PWD}/page_session_locale.cpp \
$${PWD}/page_session_options.cpp \
- $${PWD}/page_compton.cpp
+ $${PWD}/page_compton.cpp \
+ $$PWD/page_soundtheme.cpp
# $${PWD}/page_bluetooth_trueos.cpp
# $${PWD}/page_mouse_trueos.cpp
@@ -49,6 +51,7 @@ FORMS += $${PWD}/page_main.ui \
$${PWD}/page_interface_panels.ui \
$${PWD}/page_session_locale.ui \
$${PWD}/page_session_options.ui \
- $${PWD}/page_compton.ui
+ $${PWD}/page_compton.ui \
+ $$PWD/page_soundtheme.ui
# $${PWD}/page_bluetooth_trueos.ui
# $${PWD}/page_mouse_trueos.ui
diff --git a/src-qt5/core-utils/lumina-xconfig/ScreenSettings.cpp b/src-qt5/core-utils/lumina-xconfig/ScreenSettings.cpp
index 3c0edc76..a9d40554 100644
--- a/src-qt5/core-utils/lumina-xconfig/ScreenSettings.cpp
+++ b/src-qt5/core-utils/lumina-xconfig/ScreenSettings.cpp
@@ -13,6 +13,7 @@
void RRSettings::ApplyPrevious(){
QList<ScreenInfo> screens;
QSettings set("lumina-desktop","lumina-xconfig");
+ if(set.allKeys().isEmpty()){ return; }
QString profile = set.value("default_profile","").toString();
if(profile.isEmpty() || !savedProfiles().contains(profile) ){ screens = PreviousSettings(); }
else{ screens = PreviousSettings(profile); }
@@ -167,6 +168,13 @@ bool RRSettings::SaveScreens(QList<ScreenInfo> screens, QString profile){
//Apply screen configuration
void RRSettings::Apply(QList<ScreenInfo> screens){
+ //Verify that there is at least 1 active/enabled monitor first
+ bool foundactive = false;
+ for(int i=0; i<screens.length() && !foundactive; i++){
+ if(screens[i].isactive){ foundactive = (screens[i].applyChange!=1); } //make sure we are not turning it off
+ else{ foundactive = (screens[i].applyChange==2); }
+ }
+ if(!foundactive){ return; } //never disable all screens
//Read all the settings and create the xrandr options to maintain these settings
QStringList opts;
//qDebug() << "Apply:" << screens.length();
diff --git a/src-qt5/core/libLumina/ExternalProcess.h b/src-qt5/core/libLumina/ExternalProcess.h
index b1e56af8..2a6f4949 100644
--- a/src-qt5/core/libLumina/ExternalProcess.h
+++ b/src-qt5/core/libLumina/ExternalProcess.h
@@ -15,6 +15,7 @@
#include <QString>
#include <QTimer>
#include <QApplication>
+#include <QDebug>
class ExternalProcess : public QProcess{
Q_OBJECT
@@ -23,18 +24,21 @@ private:
private slots:
void resetCursor(){
+ //qDebug() << "External Process: Reset Mouse Cursor =" << !cursorRestored;
if(!cursorRestored){
QApplication::restoreOverrideCursor();
cursorRestored = true;
}
}
void processStarting(){
+ //qDebug() << "Starting External Process: Mouse Notification =" << !cursorRestored;
if(!cursorRestored){
- QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
- QTimer::singleShot(15000, this, SLOT(resetCursor()) );
+ QApplication::setOverrideCursor( QCursor(Qt::BusyCursor) );
+ QTimer::singleShot(3000, this, SLOT(resetCursor()) );
}
}
void processFinished(){
+ //qDebug() << "External Process Finished: Reset Mouse Cursor =" << !cursorRestored;
if(!cursorRestored){
QApplication::restoreOverrideCursor();
cursorRestored = true;
@@ -53,6 +57,7 @@ public:
this->setStandardOutputFile(logfile);
}
//Setup the connection for automatic cleanup
+ connect(this, SIGNAL(started()), this, SLOT(processStarting()) );
connect(this, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processFinished()) );
}
@@ -62,7 +67,7 @@ public:
}*/
}
- static void launch(QString program, QStringList args = QStringList(), bool manageCursors = false){
+ static void launch(QString program, QStringList args = QStringList(), bool manageCursors = true){
//Quick launch of a process with logging disabled and automatic cleanup
ExternalProcess *tmp = new ExternalProcess("", manageCursors);
if(args.isEmpty()){ tmp->start(program); }
diff --git a/src-qt5/core/libLumina/LDesktopUtils.cpp b/src-qt5/core/libLumina/LDesktopUtils.cpp
index 54e660e6..f1b3de17 100644
--- a/src-qt5/core/libLumina/LDesktopUtils.cpp
+++ b/src-qt5/core/libLumina/LDesktopUtils.cpp
@@ -155,8 +155,8 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){
if(sysDefaults.isEmpty()){ sysDefaults = LUtils::readFile(LOS::LuminaShare()+"luminaDesktop.conf"); }
//Find the number of the left-most desktop screen
QString screen = "0";
- QDesktopWidget *desk =QApplication::desktop();
QRect screenGeom;
+ QDesktopWidget *desk =QApplication::desktop();
for(int i=0; i<desk->screenCount(); i++){
if(desk->screenGeometry(i).x()==0){
screen = QString::number(i);
@@ -401,7 +401,7 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){
QStringList syscolors = LTHEME::availableSystemColors();
//theme file
//qDebug() << "Detected Themes/colors:" << systhemes << syscolors;
- if( !themesettings[0].startsWith("/") || !QFile::exists(themesettings[0]) || !themesettings[0].endsWith(".qss.template")){
+ if( !themesettings[0].startsWith("/") || !QFile::exists(themesettings[0]) || !themesettings[0].endsWith(".qss")){
themesettings[0] = themesettings[0].section(".qss",0,0).simplified();
for(int i=0; i<systhemes.length(); i++){
if(systhemes[i].startsWith(themesettings[0]+"::::",Qt::CaseInsensitive)){
@@ -411,9 +411,9 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){
}
}
//color file
- if( !themesettings[1].startsWith("/") || !QFile::exists(themesettings[1]) || !themesettings[1].endsWith(".qss.colors") ){
+ if( !themesettings[1].startsWith("/") || !QFile::exists(themesettings[1]) || !themesettings[1].endsWith(".conf") ){
//Remove any extra/invalid extension
- themesettings[1] = themesettings[1].section(".qss",0,0).simplified();
+ themesettings[1] = themesettings[1].section(".conf",0,0).simplified();
for(int i=0; i<syscolors.length(); i++){
if(syscolors[i].startsWith(themesettings[1]+"::::",Qt::CaseInsensitive)){
themesettings[1] = syscolors[i].section("::::",1,1); //Replace with the full path
@@ -434,13 +434,6 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){
//Now save the settings files
if(setTheme){
LTHEME::setCurrentSettings( themesettings[0], themesettings[1], themesettings[2], themesettings[3], themesettings[4]);
- QSettings themeset("lthemeengine","lthemeengine");
- themeset.setValue("Appearance/icon_theme",themesettings[2]);
- //Quick hack for a "dark" theme/color to be uniform across the desktop/applications
- if(themesettings[0].contains("DarkGlass") || themesettings[1].contains("Black")){
- themeset.setValue("Appearance/custom_palette", true);
- themeset.setValue("Appearance/color_scheme_path", LOS::LuminaShare().section("/",0,-3)+"/lthemeengine/colors/darker.conf");
- }
}
LUtils::writeFile(setdir+"/sessionsettings.conf", sesset, true);
LUtils::writeFile(setdir+"/desktopsettings.conf", deskset, true);
@@ -463,12 +456,14 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){
}
-bool LDesktopUtils::checkUserFiles(QString lastversion){
+bool LDesktopUtils::checkUserFiles(QString lastversion, QString currentversion){
+ //WARNING: Make sure you create a QApplication instance before calling this function!!!
+
//internal version conversion examples:
// [1.0.0 -> 1000000], [1.2.3 -> 1002003], [0.6.1 -> 6001]
//returns true if something changed
int oldversion = LDesktopUtils::VersionStringToNumber(lastversion);
- int nversion = LDesktopUtils::VersionStringToNumber(QApplication::applicationVersion());
+ int nversion = LDesktopUtils::VersionStringToNumber(currentversion);
bool newversion = ( oldversion < nversion ); //increasing version number
bool newrelease = ( lastversion.contains("-devel", Qt::CaseInsensitive) && QApplication::applicationVersion().contains("-release", Qt::CaseInsensitive) ); //Moving from devel to release
@@ -510,6 +505,43 @@ bool LDesktopUtils::checkUserFiles(QString lastversion){
}
LUtils::writeFile(dset, DS, true);
}
+ if(oldversion<1003004){
+ //Lumina 1.3.4 - Migrate theme settings from old format to the new theme engine format
+ QString themefile = QString(getenv("XDG_CONFIG_HOME"))+"/lthemeengine/lthemeengine.conf";
+ if(!QFile::exists(themefile)){
+ QDir dir;
+ dir.mkpath(themefile.section("/",0,-2)); //make sure the main directory exists first
+ //Need to migrate theme settings from the old location to the new one
+ QSettings newtheme(themefile, QSettings::NativeFormat);
+ qDebug() << "Migrating Theme settings:" << newtheme.fileName();
+ QStringList oldtheme = LUtils::readFile( QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/themesettings.cfg" );
+ //Find the system install location for the theme engine for use later
+ QString enginedir = LOS::LuminaShare()+"/../lthemeengine/";
+ //Find/match the icon theme
+ QString tmp = oldtheme.filter("ICONTHEME=").join("\n").section("=",1,-1).section("\n",0,0).simplified();
+ if(tmp.isEmpty()){ tmp = "material-design-light"; } //unknown Icon theme - use the default "light" version
+ newtheme.setValue("Appearance/icon_theme",tmp);
+ //Quick detect/adjust of the tone of the color theme based on the icons/colors (no 1-to-1 color theme matching between systems)
+ bool isdarktheme = tmp.contains("dark");
+ isdarktheme = isdarktheme || oldtheme.filter("COLORFILE=").join("\n").section("=",1,-1).section("\n",0,0).contains("DarkGlass");
+ //Quick adjust for the material-design icon theme to make it match the current dark/light theme
+ if(tmp.contains("material-design")){
+ newtheme.setValue("Appearance/icon_theme", QString("material-design-")+ (isdarktheme ? "dark" : "light") );
+ }
+ if(isdarktheme){
+ newtheme.setValue("Appearance/custom_palette", true);
+ newtheme.setValue("Appearance/color_scheme_path", enginedir+"colors/darker.conf");
+ newtheme.setValue("Interface/desktop_stylesheets", QStringList() << enginedir+"desktop_qss/DarkGlass.qss");
+ }else{
+ newtheme.setValue("Appearance/custom_palette", true);
+ newtheme.setValue("Appearance/color_scheme_path", enginedir+"colors/airy.conf");
+ newtheme.setValue("Interface/desktop_stylesheets", QStringList() << enginedir+"desktop_qss/Glass.qss");
+ }
+ newtheme.setValue("Appearance/style", "Fusion");
+ newtheme.setValue("Interface/stylesheets", QStringList() << enginedir+"qss/tooltip-simple.qss" << enginedir+"qss/scrollbar-simple.qss" << enginedir+"qss/sliders-simple.qss");
+ newtheme.sync(); //flush this to file right now
+ } //end check for theme file existance
+ }
//Check the fluxbox configuration files
dset = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/";
diff --git a/src-qt5/core/libLumina/LDesktopUtils.h b/src-qt5/core/libLumina/LDesktopUtils.h
index a9b44c67..b0ce6ba5 100644
--- a/src-qt5/core/libLumina/LDesktopUtils.h
+++ b/src-qt5/core/libLumina/LDesktopUtils.h
@@ -43,7 +43,7 @@ public:
//Load the default setup for the system
static void LoadSystemDefaults(bool skipOS = false);
- static bool checkUserFiles(QString lastversion); //returns true if something changed
+ static bool checkUserFiles(QString lastversion, QString currentversion); //returns true if something changed
static int VersionStringToNumber(QString version); //convert the lumina version string to a number for comparisons
//Migrating desktop settings from one ID to another
diff --git a/src-qt5/core/libLumina/LDesktopUtils.pri b/src-qt5/core/libLumina/LDesktopUtils.pri
index 80bbcfa8..fcacc586 100644
--- a/src-qt5/core/libLumina/LDesktopUtils.pri
+++ b/src-qt5/core/libLumina/LDesktopUtils.pri
@@ -5,3 +5,4 @@ INCLUDEPATH *= ${PWD}
#Now the other dependendies of it
include(LUtils.pri)
+include(LuminaThemes.pri)
diff --git a/src-qt5/core/libLumina/LUtils.cpp b/src-qt5/core/libLumina/LUtils.cpp
index 491778ca..3d3c878a 100644
--- a/src-qt5/core/libLumina/LUtils.cpp
+++ b/src-qt5/core/libLumina/LUtils.cpp
@@ -14,7 +14,7 @@
#include <unistd.h>
-inline QStringList ProcessRun(QString cmd, QStringList args){
+/*inline QStringList ProcessRun(QString cmd, QStringList args){
//Assemble outputs
QStringList out; out << "1" << ""; //error code, string output
QProcess proc;
@@ -38,50 +38,58 @@ inline QStringList ProcessRun(QString cmd, QStringList args){
out[0] = QString::number(proc.exitCode());
out[1] = info+QString(proc.readAllStandardOutput());
return out;
-}
+}*/
+
//=============
// LUtils Functions
//=============
-int LUtils::runCmd(QString cmd, QStringList args){
- /*QProcess proc;
- proc.setProcessChannelMode(QProcess::MergedChannels);
- if(args.isEmpty()){
- proc.start(cmd);
- }else{
- proc.start(cmd, args);
+QString LUtils::runCommand(bool &success, QString command, QStringList arguments, QString workdir, QStringList env){
+ QProcess proc;
+ proc.setProcessChannelMode(QProcess::MergedChannels); //need output
+ //First setup the process environment as necessary
+ QProcessEnvironment PE = QProcessEnvironment::systemEnvironment();
+ if(!env.isEmpty()){
+ for(int i=0; i<env.length(); i++){
+ if(!env[i].contains("=")){ continue; }
+ PE.insert(env[i].section("=",0,0), env[i].section("=",1,100));
+ }
+ }
+ proc.setProcessEnvironment(PE);
+ //if a working directory is specified, check it and use it
+ if(!workdir.isEmpty()){
+ proc.setWorkingDirectory(workdir);
}
- //if(!proc.waitForStarted(30000)){ return 1; } //process never started - max wait of 30 seconds
- while(!proc.waitForFinished(300)){
+ //Now run the command (with any optional arguments)
+ if(arguments.isEmpty()){ proc.start(command); }
+ else{ proc.start(command, arguments); }
+ //Wait for the process to finish (but don't block the event loop)
+ QString info;
+ while(!proc.waitForFinished(1000)){
if(proc.state() == QProcess::NotRunning){ break; } //somehow missed the finished signal
- QCoreApplication::processEvents();
+ QString tmp = proc.readAllStandardOutput();
+ if(tmp.isEmpty()){ proc.terminate(); }
+ else{ info.append(tmp); }
}
- int ret = proc.exitCode();
- return ret;*/
- QFuture<QStringList> future = QtConcurrent::run(ProcessRun, cmd, args);
- return future.result()[0].toInt(); //turn it back into an integer return code
+ info.append(proc.readAllStandardOutput()); //make sure we don't miss anything in the output
+ success = (proc.exitCode()==0); //return success/failure
+ return info;
+}
+
+int LUtils::runCmd(QString cmd, QStringList args){
+ bool success;
+ LUtils::runCommand(success, cmd, args);
+ return success;
+
+ /*QFuture<QStringList> future = QtConcurrent::run(ProcessRun, cmd, args);
+ return future.result()[0].toInt(); //turn it back into an integer return code*/
}
QStringList LUtils::getCmdOutput(QString cmd, QStringList args){
- /*QProcess proc;
- QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
- env.insert("LANG", "C");
- env.insert("LC_MESSAGES", "C");
- proc.setProcessEnvironment(env);
- proc.setProcessChannelMode(QProcess::MergedChannels);
- if(args.isEmpty()){
- proc.start(cmd);
- }else{
- proc.start(cmd,args);
- }
- //if(!proc.waitForStarted(30000)){ return QStringList(); } //process never started - max wait of 30 seconds
- while(!proc.waitForFinished(300)){
- if(proc.state() == QProcess::NotRunning){ break; } //somehow missed the finished signal
- QCoreApplication::processEvents();
- }
- QStringList out = QString(proc.readAllStandardOutput()).split("\n");
- return out;*/
- QFuture<QStringList> future = QtConcurrent::run(ProcessRun, cmd, args);
- return future.result()[1].split("\n"); //Split the return message into lines
+ bool success;
+ QString log = LUtils::runCommand(success, cmd, args);
+ return log.split("\n");
+ /*QFuture<QStringList> future = QtConcurrent::run(ProcessRun, cmd, args);
+ return future.result()[1].split("\n"); //Split the return message into lines*/
}
QStringList LUtils::readFile(QString filepath){
@@ -113,6 +121,10 @@ bool LUtils::writeFile(QString filepath, QStringList contents, bool overwrite){
}
bool LUtils::isValidBinary(QString& bin){
+ //Trim off any quotes
+ if(bin.startsWith("\"") && bin.endsWith("\"")){ bin.chop(1); bin = bin.remove(0,1); }
+ if(bin.startsWith("\'") && bin.endsWith("\'")){ bin.chop(1); bin = bin.remove(0,1); }
+ //Now look for relative/absolute path
if(!bin.startsWith("/")){
//Relative path: search for it on the current "PATH" settings
QStringList paths = QString(qgetenv("PATH")).split(":");
diff --git a/src-qt5/core/libLumina/LUtils.h b/src-qt5/core/libLumina/LUtils.h
index a494d4da..ee04c023 100644
--- a/src-qt5/core/libLumina/LUtils.h
+++ b/src-qt5/core/libLumina/LUtils.h
@@ -30,6 +30,9 @@
class LUtils{
public:
+ //Run an external command and return output & exit code
+ static QString runCommand(bool &success, QString command, QStringList arguments = QStringList(), QString workdir = "", QStringList env = QStringList());
+
//Run an external command and return the exit code
static int runCmd(QString cmd, QStringList args = QStringList());
//Run an external command and return any text output (one line per entry)
diff --git a/src-qt5/core/libLumina/LVideoLabel.cpp b/src-qt5/core/libLumina/LVideoLabel.cpp
new file mode 100644
index 00000000..bddb1cba
--- /dev/null
+++ b/src-qt5/core/libLumina/LVideoLabel.cpp
@@ -0,0 +1,120 @@
+#include "LVideoLabel.h"
+#include <LuminaXDG.h>
+#include <QCoreApplication>
+
+LVideoLabel::LVideoLabel(QString file, bool icons, QWidget *parent) : QLabel(parent) {
+ thumbnail = QPixmap();
+ entered = false;
+ this->icons = icons;
+ filepath = file;
+ defaultThumbnail = LXDG::findIcon("unknown", "").pixmap(256,256);
+
+ QTimer::singleShot(0, this, SLOT(initializeBackend()) );
+}
+
+LVideoLabel::~LVideoLabel() {
+ mediaPlayer->deleteLater();
+ surface->deleteLater();
+}
+
+void LVideoLabel::initializeBackend(){
+ mediaPlayer = new QMediaPlayer(this, QMediaPlayer::VideoSurface);
+ surface = new LVideoSurface(this);
+ mediaPlayer->setVideoOutput(surface);
+ mediaPlayer->setPlaybackRate(3);
+ mediaPlayer->setMuted(true);
+
+ this->setPixmap(defaultThumbnail.scaled(this->size(),Qt::IgnoreAspectRatio));
+ mediaPlayer->setMedia(QUrl::fromLocalFile(filepath));
+ mediaPlayer->play();
+
+ this->connect(surface, SIGNAL(frameReceived(QPixmap)), this, SLOT(stopVideo(QPixmap)));
+ this->connect(mediaPlayer, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(stateChanged(QMediaPlayer::State)));
+ this->connect(mediaPlayer, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(setDuration(QMediaPlayer::MediaStatus)));
+ this->connect(this, SIGNAL(rollOver()), surface, SLOT(switchRollOver()));
+}
+
+void LVideoLabel::enableIcons() {
+ this->setPixmap(thumbnail.scaled(this->size(),Qt::IgnoreAspectRatio));
+ icons = true;
+}
+
+void LVideoLabel::disableIcons() {
+ this->setPixmap(defaultThumbnail.scaled(this->size(),Qt::IgnoreAspectRatio));
+ icons = false;
+}
+
+void LVideoLabel::stopVideo(QPixmap pix) {
+ if(!entered) {
+ emit frameReceived(pix);
+ if(thumbnail.isNull())
+ thumbnail = pix;
+ if(icons)
+ this->setPixmap(thumbnail.scaled(this->size(),Qt::IgnoreAspectRatio));
+ mediaPlayer->pause();
+ }else {
+ if(icons)
+ this->setPixmap(pix.scaled(this->size(),Qt::IgnoreAspectRatio));
+ }
+}
+
+void LVideoLabel::stateChanged(QMediaPlayer::State state) {
+ //qDebug() << state;
+}
+
+void LVideoLabel::setDuration(QMediaPlayer::MediaStatus status) {
+ //qDebug() << status;
+ if(status == QMediaPlayer::BufferedMedia && !entered) { //Set duration in the middle to capture the thumbnail
+ mediaPlayer->setPosition(mediaPlayer->duration() / 2);
+ mediaPlayer->play();
+ }else if(status == QMediaPlayer::EndOfMedia && entered) { //Loop back to the beginning if playback started and at the end of the video
+ mediaPlayer->setPosition(0);
+ mediaPlayer->play();
+ }else if(status == QMediaPlayer::InvalidMedia){
+ mediaPlayer->stop();
+ mediaPlayer->play();
+ }/*else if(status == QMediaPlayer::LoadingMedia) {
+ mediaPlayer->pause();
+ QTimer timer;
+ timer.setSingleShot(true);
+ timer.setInterval(300);
+ timer.start();
+ qDebug() << "Timer Started" << timer.remainingTime();
+ while(timer.isActive()) QCoreApplication::processEvents(QEventLoop::AllEvents, 5);
+ qDebug() << "Timer Finished" << timer.remainingTime();
+ mediaPlayer->setPosition(0);
+ mediaPlayer->play();
+ }*/
+}
+
+void LVideoLabel::resizeEvent(QResizeEvent *event) {
+ //Resize the current pixmap to match the new size
+ if(!thumbnail.isNull()){
+ if(icons)
+ this->setPixmap(thumbnail.scaled(this->size(),Qt::IgnoreAspectRatio));
+ else
+ this->setPixmap(defaultThumbnail.scaled(this->size(),Qt::IgnoreAspectRatio));
+ }
+ QLabel::resizeEvent(event);
+}
+
+//Start playing the video from the beginning when the mouse enters the label
+void LVideoLabel::enterEvent(QEvent *event) {
+ if(icons) {
+ entered=true;
+ emit rollOver();
+ mediaPlayer->setPosition(0);
+ mediaPlayer->play();
+ }
+ QWidget::enterEvent(event);
+}
+
+//Stop the video and set the thumbnail back to the middle of the video when the mouse leaves the label
+void LVideoLabel::leaveEvent(QEvent *event) {
+ if(icons) {
+ entered=false;
+ mediaPlayer->setPosition(mediaPlayer->duration() / 2);
+ emit rollOver();
+ }
+ QWidget::leaveEvent(event);
+}
diff --git a/src-qt5/core/libLumina/LVideoLabel.h b/src-qt5/core/libLumina/LVideoLabel.h
new file mode 100644
index 00000000..56defb6a
--- /dev/null
+++ b/src-qt5/core/libLumina/LVideoLabel.h
@@ -0,0 +1,42 @@
+#ifndef LVIDEOLABEL_H
+#define LVIDEOLABEL_H
+
+#include <QLabel>
+#include <QMediaPlayer>
+#include <QTimer>
+#include <QResizeEvent>
+#include "LVideoSurface.h"
+
+class LVideoLabel : public QLabel{
+ Q_OBJECT
+ public:
+ LVideoLabel(QString, bool, QWidget* parent=NULL);
+ ~LVideoLabel();
+ void enableIcons();
+ void disableIcons();
+
+ protected:
+ void enterEvent(QEvent*);
+ void leaveEvent(QEvent*);
+ void resizeEvent(QResizeEvent*);
+
+ signals:
+ void rollOver();
+ void frameReceived(QPixmap);
+
+ private slots:
+ void initializeBackend();
+ void stopVideo(QPixmap);
+ void setDuration(QMediaPlayer::MediaStatus);
+ void stateChanged(QMediaPlayer::State);
+
+ private:
+ QMediaPlayer *mediaPlayer;
+ LVideoSurface *surface;
+ QPixmap thumbnail;
+ QPixmap defaultThumbnail;
+ bool entered;
+ bool icons;
+ QString filepath;
+};
+#endif
diff --git a/src-qt5/core/libLumina/LVideoLabel.pri b/src-qt5/core/libLumina/LVideoLabel.pri
new file mode 100644
index 00000000..06395c8d
--- /dev/null
+++ b/src-qt5/core/libLumina/LVideoLabel.pri
@@ -0,0 +1,13 @@
+QT *= multimedia
+
+HEADERS *= $${PWD}/LVideoLabel.h
+HEADERS *= $${PWD}/LVideoSurface.h
+HEADERS *= $${PWD}/LVideoWidget.h
+SOURCES *= $${PWD}/LVideoLabel.cpp
+SOURCES *= $${PWD}/LVideoSurface.cpp
+SOURCES *= $${PWD}/LVideoWidget.cpp
+
+INCLUDEPATH *= ${PWD}
+
+#Now the other dependendies of it
+#include(LUtils.pri)
diff --git a/src-qt5/core/libLumina/LVideoSurface.cpp b/src-qt5/core/libLumina/LVideoSurface.cpp
new file mode 100644
index 00000000..3aaa81f0
--- /dev/null
+++ b/src-qt5/core/libLumina/LVideoSurface.cpp
@@ -0,0 +1,60 @@
+#include "LVideoSurface.h"
+#include <QDebug>
+
+LVideoSurface::LVideoSurface(QObject *parent) : QAbstractVideoSurface(parent) {
+ frameImage = QPixmap();
+ entered = false;
+}
+
+bool LVideoSurface::present(const QVideoFrame &frame) {
+ //qDebug() << surfaceFormat().frameSize() << frame.size();
+ if(!frameImage.isNull() && !entered) {
+ emit frameReceived(frameImage);
+ return true;
+ }
+
+ if(frame.isValid()) {
+ //qDebug() << "Recording Frame";
+ //qDebug() << surfaceFormat().frameSize() << frame.size();
+ QVideoFrame icon(frame);
+ icon.map(QAbstractVideoBuffer::ReadOnly);
+ QImage img(icon.bits(), icon.width(), icon.height(), icon.bytesPerLine(), QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat()));
+
+ if((frameImage.isNull() && !entered) or entered)
+ frameImage = QPixmap::fromImage(img.copy(img.rect()));
+
+ icon.unmap();
+ emit frameReceived(frameImage);
+ return true;
+ }
+ return false;
+}
+
+QList<QVideoFrame::PixelFormat> LVideoSurface::supportedPixelFormats(QAbstractVideoBuffer::HandleType type = QAbstractVideoBuffer::NoHandle) const {
+ Q_UNUSED(type);
+ return QList<QVideoFrame::PixelFormat>() << QVideoFrame::Format_ARGB32 << QVideoFrame::Format_RGB32 << QVideoFrame::Format_RGB24
+ << QVideoFrame::Format_RGB565 << QVideoFrame::Format_RGB555 << QVideoFrame::Format_BGRA32 << QVideoFrame::Format_BGR32;
+}
+
+void LVideoSurface::stop() {
+ QAbstractVideoSurface::stop();
+}
+
+void LVideoSurface::switchRollOver() {
+ entered = !entered;
+}
+
+bool LVideoSurface::start(const QVideoSurfaceFormat &format) {
+ const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat());
+ const QSize size = format.frameSize();
+
+ //QVideoSurfaceFormat newFormat = format;
+ //Shrink the frames passed through the format to a smaller, thumbnail appropriate size and increase the frame rate
+ //newFormat.setFrameSize(258,258);
+ //newFormat.setFrameRate(90);
+
+ if (imageFormat != QImage::Format_Invalid && !size.isEmpty())
+ QAbstractVideoSurface::start(format);
+
+ return (imageFormat != QImage::Format_Invalid && !size.isEmpty());
+}
diff --git a/src-qt5/core/libLumina/LVideoSurface.h b/src-qt5/core/libLumina/LVideoSurface.h
new file mode 100644
index 00000000..7a3dcaad
--- /dev/null
+++ b/src-qt5/core/libLumina/LVideoSurface.h
@@ -0,0 +1,26 @@
+#ifndef LVIDEOSURFACE_H
+#define LVIDEOSURFACE_H
+
+#include <QAbstractVideoSurface>
+#include <QVideoSurfaceFormat>
+#include <QPixmap>
+#include <QDebug>
+
+class LVideoSurface : public QAbstractVideoSurface {
+ Q_OBJECT
+
+ public:
+ LVideoSurface(QObject *parent=0);
+ virtual bool present(const QVideoFrame&);
+ virtual QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType) const;
+ bool start(const QVideoSurfaceFormat &format);
+ void stop();
+ signals:
+ void frameReceived(QPixmap);
+ public slots:
+ void switchRollOver();
+ private:
+ QPixmap frameImage;
+ bool entered;
+};
+#endif
diff --git a/src-qt5/core/libLumina/LVideoSurface.pri b/src-qt5/core/libLumina/LVideoSurface.pri
new file mode 100644
index 00000000..469b8c93
--- /dev/null
+++ b/src-qt5/core/libLumina/LVideoSurface.pri
@@ -0,0 +1,9 @@
+QT *= multimedia
+
+HEADERS *= $${PWD}/LVideoSurface.h
+SOURCES *= $${PWD}/LVideoSurface.cpp
+
+INCLUDEPATH *= ${PWD}
+
+#Now the other dependendies of it
+#include(LUtils.pri)
diff --git a/src-qt5/core/libLumina/LVideoWidget.cpp b/src-qt5/core/libLumina/LVideoWidget.cpp
new file mode 100644
index 00000000..f1f74414
--- /dev/null
+++ b/src-qt5/core/libLumina/LVideoWidget.cpp
@@ -0,0 +1,38 @@
+#include "LVideoWidget.h"
+
+LVideoWidget::LVideoWidget(QString file, QSize iconSize, bool icons, QWidget *parent) : QWidget(parent) {
+ iconLabel = new LVideoLabel(file, icons, parent);
+ textLabel = new QLabel(parent);
+
+ layout = new QHBoxLayout(this);
+ layout->setAlignment(Qt::AlignLeft | Qt::AlignCenter);
+ layout->setContentsMargins(5,5,5,5);
+ layout->setStretchFactor(textLabel, 1); //make sure this always occupies all extra space
+
+ textLabel->setText(file.section("/", -1));
+ iconLabel->setGeometry(QRect(QPoint(0,0), iconSize));
+ iconLabel->setFixedSize(iconSize);
+ iconLabel->setVisible(true);
+ textLabel->setVisible(true);
+
+ layout->addWidget(iconLabel);
+ layout->addWidget(textLabel);
+}
+
+LVideoWidget::~LVideoWidget() {
+ delete iconLabel;
+ delete textLabel;
+ delete layout;
+}
+
+void LVideoWidget::setIconSize(QSize iconSize) {
+ iconLabel->setFixedSize(iconSize);
+}
+
+void LVideoWidget::enableIcons() {
+ iconLabel->enableIcons();
+}
+
+void LVideoWidget::disableIcons() {
+ iconLabel->disableIcons();
+}
diff --git a/src-qt5/core/libLumina/LVideoWidget.h b/src-qt5/core/libLumina/LVideoWidget.h
new file mode 100644
index 00000000..610fd9e5
--- /dev/null
+++ b/src-qt5/core/libLumina/LVideoWidget.h
@@ -0,0 +1,22 @@
+#ifndef LVIDEOWIDGET_H
+#define LVIDEOWIDGET_H
+
+#include "LVideoLabel.h"
+#include <QHBoxLayout>
+#include <QResizeEvent>
+
+class LVideoWidget : public QWidget {
+ Q_OBJECT
+ public:
+ LVideoWidget(QString, QSize, bool icons, QWidget* parent=NULL);
+ ~LVideoWidget();
+ void setIconSize(QSize);
+ void disableIcons();
+ void enableIcons();
+
+ private:
+ LVideoLabel *iconLabel;
+ QLabel *textLabel;
+ QHBoxLayout *layout;
+};
+#endif
diff --git a/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp b/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp
index b9346565..29a58ec9 100644
--- a/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp
+++ b/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp
@@ -27,12 +27,12 @@ QString LOS::SysPrefix(){ return "/usr/"; } //Prefix for system
QString LOS::ControlPanelShortcut(){ return "/usr/local/share/applications/pccontrol.desktop"; } //system control panel
QString LOS::AppStoreShortcut(){ return "/usr/local/share/applications/appcafe.desktop"; } //graphical app/pkg manager
//OS-specific RSS feeds (Format: QStringList[ <name>::::<url> ]; )
-QStringList LOS::RSSFeeds(){
+QStringList LOS::RSSFeeds(){
QStringList feeds;
feeds << "FreeBSD News Feed::::https://www.freebsd.org/news/rss.xml";
feeds << "TrueOS News Feed::::http://www.trueos.org/?feed=rss2";
return feeds;
- }
+ }
// ==== ExternalDevicePaths() ====
QStringList LOS::ExternalDevicePaths(){
@@ -59,6 +59,25 @@ QStringList LOS::ExternalDevicePaths(){
i--;
}
}
+ //Also add info about anything in the "/media" directory
+ QDir media("/media");
+ QFileInfoList list = media.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, QDir::Type | QDir::Name);
+ //qDebug() << "Media files found:" << list.length();
+ for(int i=0; i<list.length(); i++){
+ //qDebug() << "Found media entry:" << list[i].fileName();
+ if(list[i].isDir()){
+ devs << "UNKNOWN::::::::/media/"+list[i].fileName();
+ }else if(list[i].fileName().endsWith(".desktop")){
+ QString type = list[i].fileName().section(".desktop",0,-2);
+ //Determine the type of hardware device based on the dev node
+ if(type.startsWith("da")){ type = "USB"; }
+ else if(type.startsWith("ada")){ type = "HDRIVE"; }
+ else if(type.startsWith("mmsd")){ type = "SDCARD"; }
+ else if(type.startsWith("cd")||type.startsWith("acd")){ type="DVD"; }
+ else{ type = "UNKNOWN"; }
+ devs << type+"::::::::/media/"+list[i].fileName();
+ }
+ }
return devs;
}
diff --git a/src-qt5/core/libLumina/LuminaOS.h b/src-qt5/core/libLumina/LuminaOS.h
index e7a72129..98137816 100644
--- a/src-qt5/core/libLumina/LuminaOS.h
+++ b/src-qt5/core/libLumina/LuminaOS.h
@@ -5,8 +5,8 @@
// See the LICENSE file for full details
//===========================================
// This is the main interface for any OS-specific system calls
-// To port Lumina to a different operating system, just create a file
-// called "LuminaOS-<Operating System>.cpp", and use that file in
+// To port Lumina to a different operating system, just create a file
+// called "LuminaOS-<Operating System>.cpp", and use that file in
// the project (libLumina.pro) instead of LuminaOS-FreeBSD.cpp
//===========================================
#ifndef _LUMINA_LIBRARY_OS_H
@@ -23,7 +23,7 @@
class LOS{
public:
//Return the name of the OS being used
- static QString OSName();
+ static QString OSName();
//OS-specific prefix(s)
static QString LuminaShare(); //Install dir for Lumina share files
@@ -34,7 +34,7 @@ public:
static QString ControlPanelShortcut();
static QString AppStoreShortcut();
- //OS-specific RSS feeds
+ //OS-specific RSS feeds
static QStringList RSSFeeds(); //Return Format: QStringList[ <name>::::<url> ];
//Scan for mounted external devices
@@ -81,13 +81,13 @@ 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)
-
+
//Get the filesystem capacity
static QString FileSystemCapacity(QString dir) ; //Return: percentage capacity as give by the df command
-
+
//System CPU Information
static QStringList CPUTemperatures(); //Returns: List containing the temperature of any CPU's ("50C" for example)
static int CPUUsagePercent(); //Returns: Overall percentage of the amount of CPU cycles in use (-1 for errors)
diff --git a/src-qt5/core/libLumina/LuminaSingleApplication.cpp b/src-qt5/core/libLumina/LuminaSingleApplication.cpp
index 6811d147..5d276805 100644
--- a/src-qt5/core/libLumina/LuminaSingleApplication.cpp
+++ b/src-qt5/core/libLumina/LuminaSingleApplication.cpp
@@ -19,7 +19,7 @@ LSingleApplication::LSingleApplication(int &argc, char **argv, QString appname)
if(appname!="lumina-desktop"){ cTrans = LUtils::LoadTranslation(this, appname); }//save the translator for later
//Initialize a couple convenience internal variables
cfile = QDir::tempPath()+"/.LSingleApp-%1-%2-%3";
- QString username = QString(getlogin());
+ QString username = QString(getuid());
//For locking the process use the official process name - not the user input (no masking)
appname = this->applicationName();
cfile = cfile.arg( username, appname, QString::number(QX11Info::appScreen()) );
diff --git a/src-qt5/core/libLumina/LuminaThemes.cpp b/src-qt5/core/libLumina/LuminaThemes.cpp
index ddbc7b37..857e604b 100644
--- a/src-qt5/core/libLumina/LuminaThemes.cpp
+++ b/src-qt5/core/libLumina/LuminaThemes.cpp
@@ -25,42 +25,42 @@
QStringList LTHEME::availableSystemThemes(){
//returns: [name::::path] for each item
- QDir dir(LOS::LuminaShare()+"themes");
- QStringList list = dir.entryList(QStringList() <<"*.qss.template", QDir::Files, QDir::Name);
+ QDir dir(LOS::LuminaShare()+"../lthemeengine/desktop_qss");
+ QStringList list = dir.entryList(QStringList() <<"*.qss", QDir::Files, QDir::Name);
for(int i=0; i<list.length(); i++){
//Format the output entry [<name>::::<fullpath>]
- list[i] = list[i].section(".qss.",0,0)+"::::"+dir.absoluteFilePath(list[i]);
+ list[i] = list[i].section(".qss",0,0)+"::::"+dir.absoluteFilePath(list[i]);
}
return list;
}
QStringList LTHEME::availableLocalThemes(){ //returns: [name::::path] for each item
- QDir dir( QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/themes");
- QStringList list = dir.entryList(QStringList() <<"*.qss.template", QDir::Files, QDir::Name);
+ QDir dir( QString(getenv("XDG_CONFIG_HOME"))+"/lthemeengine/desktop_qss");
+ QStringList list = dir.entryList(QStringList() <<"*.qss", QDir::Files, QDir::Name);
for(int i=0; i<list.length(); i++){
//Format the output entry [<name>::::<fullpath>]
- list[i] = list[i].section(".qss.",0,0)+"::::"+dir.absoluteFilePath(list[i]);
+ list[i] = list[i].section(".qss",0,0)+"::::"+dir.absoluteFilePath(list[i]);
}
return list;
}
QStringList LTHEME::availableSystemColors(){ //returns: [name::::path] for each item
//returns: [name::::path] for each item
- QDir dir(LOS::LuminaShare()+"colors");
- QStringList list = dir.entryList(QStringList() <<"*.qss.colors", QDir::Files, QDir::Name);
+ QDir dir(LOS::LuminaShare()+"../lthemeengine/colors");
+ QStringList list = dir.entryList(QStringList() <<"*.conf", QDir::Files, QDir::Name);
for(int i=0; i<list.length(); i++){
//Format the output entry [<name>::::<fullpath>]
- list[i] = list[i].section(".qss.",0,0)+"::::"+dir.absoluteFilePath(list[i]);
+ list[i] = list[i].section(".conf",0,0)+"::::"+dir.absoluteFilePath(list[i]);
}
return list;
}
QStringList LTHEME::availableLocalColors(){ //returns: [name::::path] for each item
- QDir dir(QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/colors");
- QStringList list = dir.entryList(QStringList() <<"*.qss.colors", QDir::Files, QDir::Name);
+ QDir dir(QString(getenv("XDG_CONFIG_HOME"))+"/lthemeengine/colors");
+ QStringList list = dir.entryList(QStringList() <<"*.conf", QDir::Files, QDir::Name);
for(int i=0; i<list.length(); i++){
//Format the output entry [<name>::::<fullpath>]
- list[i] = list[i].section(".qss.",0,0)+"::::"+dir.absoluteFilePath(list[i]);
+ list[i] = list[i].section(".conf",0,0)+"::::"+dir.absoluteFilePath(list[i]);
}
return list;
}
@@ -122,15 +122,21 @@ QStringList LTHEME::availableSystemCursors(){ //returns: [name] for each item
//Save a new theme/color file
bool LTHEME::saveLocalTheme(QString name, QStringList contents){
- QString localdir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/themes/";
- if(!QFile::exists(localdir)){ QDir dir; dir.mkpath(localdir); }
- return LUtils::writeFile(localdir+name+".qss.template", contents, true);
+ Q_UNUSED(name);
+ Q_UNUSED(contents);
+ return false; //old format - do not use!!
+ //QString localdir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/themes/";
+ //if(!QFile::exists(localdir)){ QDir dir; dir.mkpath(localdir); }
+ //return LUtils::writeFile(localdir+name+".qss.template", contents, true);
}
bool LTHEME::saveLocalColors(QString name, QStringList contents){
- QString localdir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/colors/";
- if(!QFile::exists(localdir)){ QDir dir; dir.mkpath(localdir); }
- return LUtils::writeFile(localdir+name+".qss.colors", contents, true);
+ Q_UNUSED(name);
+ Q_UNUSED(contents);
+ return false; //old format - do not use!!
+ // QString localdir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/colors/";
+ //if(!QFile::exists(localdir)){ QDir dir; dir.mkpath(localdir); }
+ //return LUtils::writeFile(localdir+name+".qss.colors", contents, true);
}
//Return the currently selected Theme/Colors/Icons
@@ -180,23 +186,25 @@ QString LTHEME::currentCursor(){
//Change the current Theme/Colors/Icons
bool LTHEME::setCurrentSettings(QString themepath, QString colorpath, QString iconname, QString font, QString fontsize){
+ Q_UNUSED(font);
+ Q_UNUSED(fontsize);
//QIcon::setThemeName(iconname);
+ //Save these settings into the theme engine settings
QSettings engineset("lthemeengine","lthemeengine");
engineset.setValue("Appearance/icon_theme", iconname);
- //engineset.setValue("Appearance/color_scheme_path", colorpath); //re-enable this once the color scheme has been synced with lthemeengine
- //Need to add theme path saving here too later
-
-
+ engineset.setValue("Appearance/custom_palette", QFile::exists(colorpath) );
+ engineset.setValue("Appearance/color_scheme_path", colorpath);
+ engineset.setValue("Interface/desktop_stylesheets", QStringList() << themepath);
+ return true;
//Now save the theme settings file
- QStringList contents;
+ /*QStringList contents;
contents << "THEMEFILE="+themepath;
contents << "COLORFILE="+colorpath;
contents << "ICONTHEME="+iconname;
contents << "FONTFAMILY="+font;
contents << "FONTSIZE="+fontsize;
bool ok = LUtils::writeFile(QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/themesettings.cfg", contents, true);
-
- return ok;
+ return ok;*/
}
//Change the current Cursor Theme
@@ -299,13 +307,13 @@ QStringList LTHEME::cursorInformation(QString name){
}
}
return out;
-}
+}
QStringList LTHEME::CustomEnvSettings(bool useronly){ //view all the key=value settings
QStringList newinfo;
if(!useronly){
QStringList sysfiles; sysfiles << L_ETCDIR+"/lumina_environment.conf" << LOS::LuminaShare()+"lumina_environment.conf";
- for(int i=0; i<sysfiles.length() && newinfo.isEmpty(); i++){
+ for(int i=0; i<sysfiles.length() && newinfo.isEmpty(); i++){
newinfo << LUtils::readFile(sysfiles[i]);
}
}
diff --git a/src-qt5/core/libLumina/LuminaThemes.h b/src-qt5/core/libLumina/LuminaThemes.h
index 39602f58..ca79e0bd 100644
--- a/src-qt5/core/libLumina/LuminaThemes.h
+++ b/src-qt5/core/libLumina/LuminaThemes.h
@@ -34,7 +34,7 @@ public:
//Save a new theme/color file
static bool saveLocalTheme(QString name, QStringList contents);
static bool saveLocalColors(QString name, QStringList contents);
-
+
//Return the currently selected Theme/Colors/Icons
static QStringList currentSettings(); //returns [theme path, colorspath, iconsname, font, fontsize]
static QString currentCursor(); //returns: current cursor theme name
@@ -45,16 +45,16 @@ public:
//Return the complete stylesheet for a given theme/colors
static QString assembleStyleSheet(QString themepath, QString colorpath, QString font, QString fontsize);
-
+
//Additional info for a cursor theme
static QStringList cursorInformation(QString name); //returns: [Name, Comment, Sample Image File]
-
+
//Environment settings
static QStringList CustomEnvSettings(bool useronly = false); //view all the key=value settings
static void LoadCustomEnvSettings(); //will push the custom settings into the environment (recommended before loading the initial QApplication)
static bool setCustomEnvSetting(QString var, QString val); //variable/value pair (use an empty val to clear it)
static QString readCustomEnvSetting(QString var);
-
+
};
// Qt Style override to allow custom themeing/colors
diff --git a/src-qt5/core/libLumina/LuminaXDG.cpp b/src-qt5/core/libLumina/LuminaXDG.cpp
index ab1000ab..cf9e0af2 100644
--- a/src-qt5/core/libLumina/LuminaXDG.cpp
+++ b/src-qt5/core/libLumina/LuminaXDG.cpp
@@ -72,6 +72,7 @@ void XDGDesktop::sync(){
QString loc = var.section("[",1,1).section("]",0,0).simplified(); // localization
var = var.section("[",0,0).simplified(); //remove the localization
QString val = line.section("=",1,50).simplified();
+ if( val.count("\"")==2 && val.startsWith("\"") && val.endsWith("\"")){ val.chop(1); val = val.remove(0,1); } //remove the starting/ending quotes
//-------------------
if(var=="Name"){
if(insection){
@@ -631,7 +632,7 @@ void XDGDesktopList::populateMenu(QMenu *topmenu, bool byCategory){
void LFileInfo::loadExtraInfo(){
desk = 0;
//Now load the extra information
- if(this->isDir()){
+ if( this->suffix().isEmpty() && (this->absoluteFilePath().startsWith("/net/") || this->isDir()) ){
mime = "inode/directory";
//Special directory icons
QString name = this->fileName().toLower();
@@ -644,6 +645,7 @@ void LFileInfo::loadExtraInfo(){
else if(name=="downloads"){ icon = "folder-downloads"; }
else if(name=="documents"){ icon = "folder-documents"; }
else if(name=="images" || name=="pictures"){ icon = "folder-image"; }
+ else if(this->absoluteFilePath().startsWith("/net/")){ icon = "folder-shared"; }
else if( !this->isReadable() ){ icon = "folder-locked"; }
}else if( this->suffix()=="desktop"){
mime = "application/x-desktop";
@@ -664,11 +666,11 @@ LFileInfo::LFileInfo(){
LFileInfo::LFileInfo(QString filepath){ //overloaded contructor
this->setFile(filepath);
loadExtraInfo();
-}
+}
LFileInfo::LFileInfo(QFileInfo info){ //overloaded contructor
this->swap(info); //use the given QFileInfo without re-loading it
loadExtraInfo();
-}
+}
//Functions for accessing the extra information
// -- Return the mimetype for the file
@@ -683,7 +685,7 @@ QString LFileInfo::iconfile(){
return icon;
}else{
if(!mime.isEmpty()){
- QString tmp = mime;
+ QString tmp = mime;
tmp.replace("/","-");
return tmp;
}else if(this->isExecutable()){
@@ -696,7 +698,7 @@ QString LFileInfo::iconfile(){
// -- Check if this is an XDG desktop file
bool LFileInfo::isDesktopFile(){
if(desk==0){ return false; }
- return (!desk->filePath.isEmpty());
+ return (!desk->filePath.isEmpty());
}
// -- Allow access to the XDG desktop data structure
@@ -726,11 +728,14 @@ bool LFileInfo::isAVFile(){
//==== LXDG Functions ====
bool LXDG::checkExec(QString exec){
//Return true(good) or false(bad)
+ //Check for quotes around the exec, and remove them as needed
+ if(exec.startsWith("\"") && exec.count("\"")>=2){ exec = exec.section("\"",1,1).simplified(); }
+ if(exec.startsWith("\'") && exec.count("\'")>=2){ exec = exec.section("\'",1,1).simplified(); }
if(exec.startsWith("/")){ return QFile::exists(exec); }
else{
QStringList paths = QString(getenv("PATH")).split(":");
for(int i=0; i<paths.length(); i++){
- if(QFile::exists(paths[i]+"/"+exec)){ return true; }
+ if(QFile::exists(paths[i]+"/"+exec)){ return true; }
}
}
return false; //could not find the executable in the current path(s)
@@ -747,7 +752,7 @@ QStringList LXDG::systemApplicationDirs(){
for(int i=0; i<appDirs.length(); i++){
if( QFile::exists(appDirs[i]+"/applications") ){
out << appDirs[i]+"/applications";
- //Also check any subdirs within this directory
+ //Also check any subdirs within this directory
// (looking at you KDE - stick to the standards!!)
out << LUtils::listSubDirectories(appDirs[i]+"/applications");
}
@@ -891,7 +896,7 @@ QIcon LXDG::findIcon(QString iconName, QString fallback){
fall << getChildIconDirs(paths[i]+"hicolor"); //XDG fallback (apps add to this)
}
//Now load all the icon theme dependencies in order (Theme1 -> Theme2 -> Theme3 -> Fallback)
-
+
//fall << LOS::AppPrefix()+"share/pixmaps"; //always use this as well as a final fallback
QDir::setSearchPaths("icontheme", theme);
QDir::setSearchPaths("default", oxy);
@@ -926,7 +931,7 @@ QIcon LXDG::findIcon(QString iconName, QString fallback){
//simple PNG image - load directly into the QIcon structure
ico.addFile(srch[i]+":"+iconName+".png");
}
-
+
}
//If still no icon found, look for any image format in the "pixmaps" directory
if(ico.isNull()){
@@ -946,13 +951,13 @@ QIcon LXDG::findIcon(QString iconName, QString fallback){
break;
}
}
-
+
}
}
//Use the fallback icon if necessary
if(ico.isNull() ){
if(!fallback.isEmpty()){ ico = LXDG::findIcon(fallback,""); }
- else if(iconName.contains("-x-") && !iconName.endsWith("-x-generic")){
+ else if(iconName.contains("-x-") && !iconName.endsWith("-x-generic")){
//mimetype - try to use the generic type icon
ico = LXDG::findIcon(iconName.section("-x-",0,0)+"-x-generic", "");
}
@@ -969,7 +974,7 @@ QStringList LXDG::getChildIconDirs(QString parent){
QDir D(parent);
QStringList out;
QStringList dirs = D.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
- if(!dirs.isEmpty() && (dirs.contains("32x32") || dirs.contains("scalable")) ){
+ if(!dirs.isEmpty() && (dirs.contains("32x32") || dirs.contains("scalable")) ){
//Need to sort these directories by image size
//qDebug() << " - Parent:" << parent << "Dirs:" << dirs;
for(int i=0; i<dirs.length(); i++){
@@ -1017,7 +1022,7 @@ QStringList LXDG::systemMimeDirs(){
QStringList out;
for(int i=0; i<appDirs.length(); i++){
if( QFile::exists(appDirs[i]+"/mime") ){
- out << appDirs[i]+"/mime";
+ out << appDirs[i]+"/mime";
}
}
return out;
@@ -1028,7 +1033,7 @@ QIcon LXDG::findMimeIcon(QString extension){
QString mime = LXDG::findAppMimeForFile(extension);
if(mime.isEmpty()){ mime = LXDG::findAppMimeForFile(extension.toLower()); }
mime.replace("/","-"); //translate to icon mime name
- if(!mime.isEmpty()){ ico = LXDG::findIcon(mime, "unknown");} //use the "unknown" mimetype icon as fallback
+ if(!mime.isEmpty()){ ico = LXDG::findIcon(mime, "unknown");} //use the "unknown" mimetype icon as fallback
if(ico.isNull()){ ico = LXDG::findIcon("unknown",""); } //just in case
return ico;
}
@@ -1050,8 +1055,8 @@ while(mimes.isEmpty()){
return extension;
}
//Look for globs at the end of the filename
- if(!extension.isEmpty()){
- mimes = mimefull.filter(":*."+extension);
+ if(!extension.isEmpty()){
+ mimes = mimefull.filter(":*."+extension);
//If nothing found, try a case-insensitive search
if(mimes.isEmpty()){ mimes = mimefull.filter(":*."+extension, Qt::CaseInsensitive); }
//Now ensure that the filter was accurate (*.<extention>.<something> will still be caught)
@@ -1062,7 +1067,7 @@ while(mimes.isEmpty()){
}
}
//Look for globs at the start of the filename
- if(mimes.isEmpty()){
+ if(mimes.isEmpty()){
mimes = mimefull.filter(":"+filename.left(2)); //look for the first 2 characters initially
//Note: This initial filter will only work if the wildcard (*) is not within the first 2 characters of the pattern
//Now ensure that the filter was accurate
diff --git a/src-qt5/core/libLumina/RootSubWindow-animations.cpp b/src-qt5/core/libLumina/obsolete/RootSubWindow-animations.cpp
index efab20fe..efab20fe 100644
--- a/src-qt5/core/libLumina/RootSubWindow-animations.cpp
+++ b/src-qt5/core/libLumina/obsolete/RootSubWindow-animations.cpp
diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/obsolete/RootSubWindow.cpp
index 5040f2f9..5040f2f9 100644
--- a/src-qt5/core/libLumina/RootSubWindow.cpp
+++ b/src-qt5/core/libLumina/obsolete/RootSubWindow.cpp
diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/obsolete/RootSubWindow.h
index 598298e2..598298e2 100644
--- a/src-qt5/core/libLumina/RootSubWindow.h
+++ b/src-qt5/core/libLumina/obsolete/RootSubWindow.h
diff --git a/src-qt5/core/libLumina/RootWindow-mgmt.cpp b/src-qt5/core/libLumina/obsolete/RootWindow-mgmt.cpp
index 24ea639b..24ea639b 100644
--- a/src-qt5/core/libLumina/RootWindow-mgmt.cpp
+++ b/src-qt5/core/libLumina/obsolete/RootWindow-mgmt.cpp
diff --git a/src-qt5/core/libLumina/RootWindow.cpp b/src-qt5/core/libLumina/obsolete/RootWindow.cpp
index 705297be..705297be 100644
--- a/src-qt5/core/libLumina/RootWindow.cpp
+++ b/src-qt5/core/libLumina/obsolete/RootWindow.cpp
diff --git a/src-qt5/core/libLumina/RootWindow.h b/src-qt5/core/libLumina/obsolete/RootWindow.h
index c5cd44a0..c5cd44a0 100644
--- a/src-qt5/core/libLumina/RootWindow.h
+++ b/src-qt5/core/libLumina/obsolete/RootWindow.h
diff --git a/src-qt5/core/libLumina/RootWindow.pri b/src-qt5/core/libLumina/obsolete/RootWindow.pri
index 9426b6b4..9426b6b4 100644
--- a/src-qt5/core/libLumina/RootWindow.pri
+++ b/src-qt5/core/libLumina/obsolete/RootWindow.pri
diff --git a/src-qt5/core/lumina-checkpass/main.c b/src-qt5/core/lumina-checkpass/main.c
index e12e7c78..2f54c8e6 100644
--- a/src-qt5/core/lumina-checkpass/main.c
+++ b/src-qt5/core/lumina-checkpass/main.c
@@ -14,23 +14,56 @@
//===========================================
//Standard C libary
#include <unistd.h> // Standard C
+#include <stdlib.h>
#include <stdio.h> // Usage output
#include <pwd.h> // User DB information
+#include <string.h>
//PAM/security libraries
#include <sys/types.h>
#include <security/pam_appl.h>
#include <security/openpam.h>
+void showUsage(){
+ puts("lumina-checkpass: Simple user-level check for password validity (for screen unlockers and such).");
+ puts("Usage:");
+ //puts(" lumina-checkpass <password>");
+ puts(" lumina-checkpass -fd <file descriptor>");
+ puts(" lumina-checkpass -f <file path>");
+ puts("Returns: 0 for a valid password, 1 for invalid");
+}
+
int main(int argc, char** argv){
//Check the inputs
- if(argc!=2){
+ if(argc!=3){
//Invalid inputs - show the help text
- puts("lumina-checkpass: Simple user-level check for password validity (for screen unlockers and such).");
- puts("Usage: lumina-checkpass <password>");
- puts("Returns: 0 for a valid password, 1 for invalid");
+ showUsage();
return 1;
}
+ char*pass = 0;
+ if(argc==3 && 0==strcmp(argv[1],"-fd") ){
+ FILE *fp = fdopen(atoi(argv[2]), "r");
+ size_t len;
+ if(fp!=0){
+ ssize_t slen = getline(&pass, &len, fp);
+ if(pass[slen-1]=='\n'){ pass[slen-1] = '\0'; }
+ }
+ fclose(fp);
+ }else if(argc==3 && 0==strcmp(argv[1],"-f") ){
+ FILE *fp = fopen(argv[2], "r");
+ size_t len;
+ if(fp!=0){
+ ssize_t slen = getline(&pass, &len, fp);
+ if(pass[slen-1]=='\n'){ pass[slen-1] = '\0'; }
+ }else{
+ puts("[ERROR] Unknown option provided");
+ puts("----------------");
+ showUsage();
+ return 1;
+ }
+ fclose(fp);
+ }
+ if(pass == 0){ puts("Could not read password!!"); return 1; } //error in reading password
//Validate current user (make sure current UID matches the logged-in user,
char* cUser = getlogin();
struct passwd *pwd = 0;
@@ -44,7 +77,7 @@ int main(int argc, char** argv){
int ret = pam_start( "system", cUser, &pamc, &pamh);
if(ret != PAM_SUCCESS){ return 1; } //could not init PAM
//char* cPassword = argv[1];
- ret = pam_set_item(pamh, PAM_AUTHTOK, argv[1]);
+ ret = pam_set_item(pamh, PAM_AUTHTOK, pass);
//Authenticate with PAM
ret = pam_authenticate(pamh,0); //this can be true without verifying password if pam_self.so is used in the auth procedures (common)
if( ret == PAM_SUCCESS ){ ret = pam_acct_mgmt(pamh,0); } //Check for valid, unexpired account and verify access restrictions
diff --git a/src-qt5/core/lumina-desktop-unified/LSession.cpp b/src-qt5/core/lumina-desktop-unified/LSession.cpp
index d70ff973..e1251c01 100644
--- a/src-qt5/core/lumina-desktop-unified/LSession.cpp
+++ b/src-qt5/core/lumina-desktop-unified/LSession.cpp
@@ -104,7 +104,7 @@ void LSession::setupSession(){
splash.showScreen("user");
if(DEBUG){ qDebug() << " - Init User Files:" << timer->elapsed();}
//checkUserFiles(); //adds these files to the watcher as well
-
+ Lumina::ROOTWIN->start();
//Initialize the internal variables
//DESKTOPS.clear();
@@ -116,7 +116,6 @@ void LSession::setupSession(){
if(DEBUG){ qDebug() << " - Populate App List:" << timer->elapsed();}
Lumina::APPLIST->updateList();
//appmenu = new AppMenu();
-
splash.showScreen("menus");
//if(DEBUG){ qDebug() << " - Init SettingsMenu:" << timer->elapsed();}
//settingsmenu = new SettingsMenu();
@@ -129,15 +128,16 @@ void LSession::setupSession(){
QList<QScreen*> scrns= QApplication::screens();
for(int i=0; i<scrns.length(); i++){
qDebug() << " --- Load Wallpaper for Screen:" << scrns[i]->name();
- Lumina::ROOTWIN->ChangeWallpaper(scrns[i]->name(), RootWindow::Stretch, LOS::LuminaShare()+"desktop-background.jpg");
+ RootDesktopObject::instance()->ChangeWallpaper(scrns[i]->name(),QUrl::fromLocalFile(LOS::LuminaShare()+"desktop-background.jpg").toString() );
}
- Lumina::ROOTWIN->start();
Lumina::NWS->setRoot_numberOfWorkspaces(QStringList() << "one" << "two");
Lumina::NWS->setRoot_currentWorkspace(0);
+
if(DEBUG){ qDebug() << " - Create Desktop Context Menu"; }
- DesktopContextMenu *cmenu = new DesktopContextMenu(Lumina::ROOTWIN);
+
+ /*DesktopContextMenu *cmenu = new DesktopContextMenu(Lumina::ROOTWIN);
connect(cmenu, SIGNAL(showLeaveDialog()), this, SLOT(StartLogout()) );
- cmenu->start();
+ cmenu->start();*/
//desktopFiles = QDir(QDir::homePath()+"/Desktop").entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs, QDir::Name | QDir::IgnoreCase | QDir::DirsFirst);
//updateDesktops();
@@ -228,7 +228,9 @@ void LSession::setupGlobalConnections(){
//Root window connections
connect(Lumina::ROOTWIN, SIGNAL(RegisterVirtualRoot(WId)), Lumina::NWS, SLOT(RegisterVirtualRoot(WId)) );
connect(Lumina::ROOTWIN, SIGNAL(RootResized(QRect)), Lumina::NWS, SLOT(setRoot_desktopGeometry(QRect)) );
- connect(Lumina::ROOTWIN, SIGNAL(MouseMoved()), Lumina::SS, SLOT(newInputEvent()) );
+ connect(RootDesktopObject::instance(), SIGNAL(mouseMoved()), Lumina::SS, SLOT(newInputEvent()) );
+ connect(RootDesktopObject::instance(), SIGNAL(startLogout()), this, SLOT(StartLogout()) );
+ connect(RootDesktopObject::instance(), SIGNAL(lockScreen()), Lumina::SS, SLOT(LockScreenNow()) );
//Native Window Class connections
connect(Lumina::NEF, SIGNAL(WindowCreated(WId)), Lumina::NWS, SLOT(NewWindowDetected(WId)));
@@ -356,12 +358,12 @@ void LSession::launchStartupApps(){
void LSession::checkUserFiles(){
//internal version conversion examples:
// [1.0.0 -> 1000000], [1.2.3 -> 1002003], [0.6.1 -> 6001]
- QString OVS = DesktopSettings::instance()->value(DesktopSettings::System,"DesktopVersion","0").toString(); //Old Version String
+ /*QString OVS = DesktopSettings::instance()->value(DesktopSettings::System,"DesktopVersion","0").toString(); //Old Version String
bool changed = LDesktopUtils::checkUserFiles(OVS);
if(changed){
//Save the current version of the session to the settings file (for next time)
DesktopSettings::instance()->setValue(DesktopSettings::System,"DesktopVersion", this->applicationVersion());
- }
+ }*/
}
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/LICENCE b/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/LICENCE
deleted file mode 100644
index aa601d5e..00000000
--- a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/LICENCE
+++ /dev/null
@@ -1,7 +0,0 @@
-These audio files are BSD-licensed and were created/owned by the TrueOS Project:
- - Login.ogg
- - Logout.ogg
-
-These audio files are freely available on jewelbeat.com:
-"Music by JewelBeat. Download your free music and free sound effects at www.jewelbeat.com."
- - low-battery.ogg (http://www.jewelbeat.com/free/free-sound-effects/musical%20effects/Tympani_2.mp3 - converted to OGG afterward)
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Login.ogg b/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Login.ogg
deleted file mode 100644
index 43a07e27..00000000
--- a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Login.ogg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Logout.ogg b/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Logout.ogg
deleted file mode 100644
index e63ae07f..00000000
--- a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Logout.ogg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/low-battery.ogg b/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/low-battery.ogg
deleted file mode 100644
index d129a2b3..00000000
--- a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/low-battery.ogg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/lumina-desktop.desktop b/src-qt5/core/lumina-desktop-unified/extrafiles/lumina-desktop.desktop
deleted file mode 100644
index 7d87f93a..00000000
--- a/src-qt5/core/lumina-desktop-unified/extrafiles/lumina-desktop.desktop
+++ /dev/null
@@ -1,34 +0,0 @@
-[Desktop Entry]
-Exec=start-lumina-desktop
-TryExec=start-lumina-desktop
-Icon=Lumina-DE
-Type=Application
-Name=Lumina
-Name[de]=Lumina
-Name[en_GB]=Lumina
-Name[en_ZA]=Lumina
-Name[et]=Lumina
-Name[fr]=Lumina
-Name[fr_CA]=Lumina
-Name[hi]=ल्यूमिना
-Name[ja]=Lumina
-Name[mt]=Lumina
-Name[pl]=Lumina
-Name[pt_BR]=Lumina
-Name[ru]=Lumina
-Name[uk]=Lumina
-Name[vi]=Lumina
-Comment=A Lightweight Desktop for FreeBSD
-Comment[de]=Eine leichtgewichtige Arbeitsplatzumgebung für FreeBSD
-Comment[en_GB]=A Lightweight Desktop for FreeBSD
-Comment[en_ZA]=A Lightweight Desktop for FreeBSD
-Comment[et]=Minimalistlik töölauakeskkond FreeBSD-le
-Comment[fr]=Un environnement bureau léger pour FreeBSD
-Comment[fr_CA]=Un environnement bureau léger pour FreeBSD
-Comment[hi]=एक हल्का डेस्कटॉप फ्री बी.एस.डी के लिए
-Comment[ja]=FreeBSD の為に作られた軽快なデスクトップ環境
-Comment[mt]=A Desktop irqiq għal FreeBSD
-Comment[pl]=Lekkie Środowisko graficzne dla FreeBSD
-Comment[pt_BR]=Um ambiente de trabalho leve para FreeBSD
-Comment[uk]=Легковісне оточення стільниці для FreeBSD
-Comment[vi]=Một máy tính để bàn nhẹ cho FreeBSD
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Fireflies.json b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Fireflies.json
new file mode 100644
index 00000000..c09de308
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Fireflies.json
@@ -0,0 +1,26 @@
+{
+ "name" : {
+ "default" : "Fireflies"
+ },
+ "description" : {
+ "default" : "Dancing balls of light on the screen"
+ },
+ "author" : {
+ "name" : "Ken Moore",
+ "email" : "ken@ixsystems.com",
+ "website" : "https://github.com/beanpole135",
+ "company" : "iXsystems",
+ "company_website" : "http://ixsystems.com"
+ },
+ "meta" : {
+ "license" : "3-clause BSD",
+ "license_url" : "https://github.com/trueos/lumina/blob/master/LICENSE",
+ "copyright" : "Copyright (c) 2017, Ken Moore (ken@ixsystems.com)",
+ "date_created" : "20171010",
+ "version" : "1.0"
+ },
+ "qml" : {
+ "exec" : "qml_scripts/Fireflies.qml",
+ "additional_files" : ["qml_scripts/Firefly.qml"]
+ }
+}
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/README.md b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/README.md
new file mode 100644
index 00000000..d9093b44
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/README.md
@@ -0,0 +1,79 @@
+## Screensaver Format
+The screensaver system for the Lumina desktop allows for the creation and use of scripts written in the QML language, with a number of screensavers and other examples installed out-of-box. There are only a couple warnings/caveats to consider when developing a new screensaver:
+
+1. The root object in your QML script will be automatically sized to fit the screen as needed. Avoid trying to hard-code specific screen dimensions within your script as it will not work properly.
+2. A JSON manifest file must be created (format listed below) and placed into one of the screensaver plugin directories for it to be recognized as a valid screensaver by the desktop.
+
+
+### JSON Manifest
+The manifest file contains all the information needed to actually validate/launch the screensaver, as well as additional information about the author and/or the screensaver itself.
+
+Example JSON manifest file (sample.json):
+```
+{
+ "name" : {
+ "default" : "sample",
+ "en_US" : "US English localization of the name",
+ "en" : "Generic english localization of the name"
+ },
+
+ "description" : {
+ "default" : "sample screensaver",
+ "en_US" : "US English Localization of the description"
+ },
+
+ "author" : {
+ "name" : "Me",
+ "email" : "Me@myself.net",
+ "website" : "http://mywebsite.net",
+ "company" : "iXsystems",
+ "company_website" : "http://ixsystems.com"
+ },
+
+ "meta" : {
+ "license" : "3-clause BSD",
+ "license_url" : "https://github.com/trueos/lumina/blob/master/LICENSE",
+ "copyright" : "Copyright (c) 2017, Ken Moore (ken@ixsystems.com)",
+ "date_created" : "20171010",
+ "date_updated" : "20171011",
+ "version" : "1.0"
+ },
+
+ "qml" : {
+ "exec" : "absolute/or/relative/path/to/script.qml",
+ "additional_files" : ["file/which/must/exist.png"],
+ "qt_min_version" : "5.0",
+ "qt_max_version" : "6.0"
+ }
+}
+```
+
+Details of the individual items in the manifest:
+* NOTE: for locale codes, both long and short version are acceptable:
+ Example 1: If the current locale is "en_GB", but the JSON manifest lists translations for "en_US" and "en", then the "en" translation will be used.
+ Example 2: If the current locale is "en_GB", but neither "en_GB" nor "en" translations exist, then the "default" version will be used.
+
+* **name** : (required) This is the official name of the screensaver to show to users
+ * *default* : (required) Non-translated name of the screensaver
+ * *[locale]* : (optional) Translated name for specific [locale]
+* **description** : (required) This is a short description of the screensaver to show to users
+ * *default* : (required) Non-translated description of the screensaver
+ * *[locale]* : (optional) Translated description for specific [locale]
+* **author** : (all optional) Additional information about the author(s) of the screensaver
+ * *name* : Name of the author
+ * *email* : Email to contact the author (useful for licensing questions and such)
+ * *website* : Personal website for the author (github/facebook/twitter profile, etc)
+ * *company* : Company for which the author is creating this screensaver
+ * *company_website* : Website for the company
+* **meta** : (all optional) Additional information about the screensaver itself
+ * *license* : License the screensaver is released under
+ * *license_url* : Website which contains the full text of the license
+ * *copyright* : Copyright notice for this screensaver
+ * *date_created* : (yyyyMMdd) Date the screensaver was initially created
+ * *date_updated* : (yyyyMMdd) Date the screensaver was last updated
+ * *version* : Current version of the screensaver (typically updated every time "date_updated" is changed)
+* **qml** : (required) Information about launching the screensaver and checking validity
+ * *exec* : (required) Absolute or relative path to the QML script (relative to the directory which contains the JSON manifest)
+ * *additional_files* : (optional) Array of paths for other files/scripts which must exist for the screensaver to work properly.
+ * *qt_min_version* : (optional) Minimum version of the Qt libraries that this screensaver supports
+ * *qt_max_version* : (optional) Maximum version of the Qt libraries that this screensaver supports
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Video.json b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Video.json
new file mode 100644
index 00000000..2fa6e6da
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Video.json
@@ -0,0 +1,25 @@
+{
+ "name" : {
+ "default" : "Video"
+ },
+ "description" : {
+ "default" : "Play a single video or a list of videos in a loop"
+ },
+ "author" : {
+ "name" : "Zackary Welch",
+ "email" : "zwelch@ixsystems.com",
+ "website" : "https://github.com/ZackaryWelch",
+ "company" : "iXsystems",
+ "company_website" : "http://ixsystems.com"
+ },
+ "meta" : {
+ "license" : "3-clause BSD",
+ "license_url" : "https://github.com/trueos/lumina/blob/master/LICENSE",
+ "copyright" : "Copyright (c) 2017, Ken Moore (ken@ixsystems.com)",
+ "date_created" : "20171025",
+ "version" : "1.0"
+ },
+ "qml" : {
+ "exec" : "qml_scripts/Video.qml"
+ }
+}
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Warp.json b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Warp.json
new file mode 100644
index 00000000..888df01f
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Warp.json
@@ -0,0 +1,25 @@
+{
+ "name" : {
+ "default" : "Warp"
+ },
+ "description" : {
+ "default" : "Warp trail through the stars"
+ },
+ "author" : {
+ "name" : "Ken Moore",
+ "email" : "ken@ixsystems.com",
+ "website" : "https://github.com/beanpole135",
+ "company" : "iXsystems",
+ "company_website" : "http://ixsystems.com"
+ },
+ "meta" : {
+ "license" : "3-clause BSD",
+ "license_url" : "https://github.com/trueos/lumina/blob/master/LICENSE",
+ "copyright" : "Copyright (c) 2017, Ken Moore (ken@ixsystems.com)",
+ "date_created" : "20171012",
+ "version" : "1.0"
+ },
+ "qml" : {
+ "exec" : "qml_scripts/Warp.qml"
+ }
+}
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Fireflies.qml b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Fireflies.qml
new file mode 100644
index 00000000..d8dcc1ed
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Fireflies.qml
@@ -0,0 +1,19 @@
+import QtQuick 2.0
+import QtGraphicalEffects 1.0
+import "." as QML
+
+Rectangle {
+ id : canvas
+ anchors.fill: parent
+ color: "black"
+
+ Repeater {
+ model: Math.round(Math.random()*canvas.width/10)+100
+ QML.Firefly {
+ parent: canvas
+ x: Math.round(Math.random()*canvas.width)
+ y: Math.round(Math.random()*canvas.height)
+ }
+ } //end of Repeater
+
+} //end of canvas rectangle
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Firefly.qml b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Firefly.qml
new file mode 100644
index 00000000..7b65d8ec
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Firefly.qml
@@ -0,0 +1,63 @@
+import QtQuick 2.0
+import QtQuick.Window 2.2
+import QtGraphicalEffects 1.0
+
+Item {
+
+ RectangularGlow {
+ anchors.fill: fly
+ glowRadius: Math.round(fly.radius /2)
+ spread: 0.5
+ color: Qt.rgba(1,1,1,0.3)
+ cornerRadius: fly.radius + glowRadius
+ }
+
+ Rectangle {
+ id: fly
+ width: Math.round(Math.random()*canvas.width/200)+2
+ height: width
+ x: parent.x
+ y: parent.y
+ color: Qt.rgba(Math.random(),Math.random(),0,0.5)
+ radius: Math.floor(width/2)
+ property int jitterX: Math.round(Math.random()*100)+10
+ property int jitterY: Math.round(Math.random()*100)+10
+
+ Behavior on color {
+ ColorAnimation {
+ duration: 500
+ }
+ }
+ Behavior on x {
+ SmoothedAnimation {
+ velocity: 10+Math.random()*canvas.width/100
+ }
+ }
+ Behavior on y {
+ SmoothedAnimation {
+ velocity: 10+Math.random()*canvas.height/100
+ }
+ }
+
+ }
+
+
+
+ Timer {
+ interval: 5
+ repeat: true
+ running: true
+ property bool starting: true
+ onTriggered: {
+ if(starting){ interval = Math.round(Math.random()*1000)+500; starting = false; }
+ if ( (fly.x+fly.jitterX)>parent.width || (fly.x+fly.jitterX)<0 ){ fly.jitterX = 0-fly.jitterX }
+ fly.x = fly.x+fly.jitterX
+ if( (fly.y+fly.jitterY)>parent.height || (fly.y+fly.jitterY)<0 ){ fly.jitterY = 0-fly.jitterY }
+ fly.y = fly.y+fly.jitterY
+ fly.jitterX = (Math.round(Math.random())*2 - 1) *fly.jitterX
+ fly.jitterY = (Math.round(Math.random())*2 - 1) *fly.jitterY
+ fly.color = Qt.rgba(Math.random(),Math.random(),Math.random(),0.5)
+
+ }
+ } //end of timer
+} //end of item
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Grav.qml b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Grav.qml
new file mode 100644
index 00000000..d5245c9b
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Grav.qml
@@ -0,0 +1,106 @@
+import QtQuick 2.7
+import QtGraphicalEffects 1.0
+
+Rectangle {
+ id : canvas
+ anchors.fill: parent
+ width: 800
+ height: 600
+ color: "black"
+
+ //Between 5 and 15 planets, read from settings
+ property var planets: Math.round(( Math.random() * 10 ) + 5 )
+
+ //Create planets
+ Repeater {
+ model: planets
+
+ Rectangle {
+ id : index
+ parent: canvas
+
+ //Place the planet randomly on the canvas, but not too close to the edge
+ x: Math.round(Math.random()*canvas.width)
+
+ //Check to make sure the planets are not too close to the sun (outside a 50px radius)
+ //while( Math.round(Math.random()*canvas.width) < (width/2 + 50) or Math.round(Math.random()*canvas.width) > (width/2 - 50))
+
+ y: Math.round(Math.random()*canvas.height)
+
+
+ //Create the orbit animation
+
+ //Planet size between 14 and 32 pixels
+ width: Math.round(1.75 * (((Math.random() * 10) + 8 )))
+ height: width
+
+ //Make each rectangle look circular
+ radius: width / 2
+
+ //Give each planet a random color, semi-transparent
+ color: Qt.rgba(Math.random(), Math.random(), Math.random(), 0.5)
+ }
+ }
+
+ //Create the star
+ Rectangle{
+ id: star
+ parent: canvas
+
+ //Centers in star in the center of the canvas
+ x: Math.round(canvas.width / 2)
+ y: Math.round(canvas.height / 2)
+
+ width: 60
+ height: width
+
+ //Create the wobble animation
+ SequentialAnimation on height {
+ loops: Animation.Infinite
+ PropertyAnimation { duration: 2000; to: 90 }
+ PropertyAnimation { duration: 2000; to: 60 }
+ }
+
+ SequentialAnimation on width {
+ loops: Animation.Infinite
+ PropertyAnimation { duration: 2000; to: 90 }
+ PropertyAnimation { duration: 2000; to: 60 }
+ }
+
+ //border.width: 4
+ //border.color: "blue"
+ color: "black"
+ radius: width / 2
+
+ //Creates a radial gradient to make the star look cool
+ RadialGradient {
+ anchors.fill: parent
+ gradient: Gradient {
+ GradientStop { position:0 ;color: Qt.rgba(0,0,0,0)}
+ GradientStop { position:0.18 ;color: Qt.rgba(0,0,0,0)}
+ GradientStop { position:0.2 ;color: Qt.rgba(0.32,0.47,0.30,0.13)}
+ GradientStop { position:0.3 ;color: Qt.rgba(0.62,0.92,0.58,0.25)}
+ GradientStop { position:0.4 ;color: Qt.rgba(1.00,0.93,0.59,0.51)}
+ GradientStop { position:0.5 ;color: Qt.rgba(0,0,0,0)}
+ }
+ }
+
+ }
+
+ /*Motion timer
+ Timer {
+ interval: 1
+ repeat: true
+ running: true
+ property bool starting: true
+
+ onTriggered: {
+ if(starting) { interval = 3010; starting = false; }
+
+ }
+ }*/
+
+ Component.onCompleted: {
+ //console.log(Math.random())
+ }
+}
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Video.qml b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Video.qml
new file mode 100644
index 00000000..e7d0626d
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Video.qml
@@ -0,0 +1,50 @@
+import QtQuick 2.0
+import QtMultimedia 5.7
+import QtQuick.Window 2.2
+import Qt.labs.folderlistmodel 2.1
+
+Rectangle {
+ //width: Screen.width
+ //height: Screen.height
+ width: 800
+ height: 600
+ color: "black"
+
+ FolderListModel {
+ id: folderModel
+ folder: "/usr/local/videos"
+ }
+
+ Repeater {
+ model: folderModel
+ Component {
+ Item {
+ Component.onCompleted: { playlist.addItem(fileURL) }
+ }
+ }
+ }
+
+ Playlist {
+ id: playlist
+ playbackMode: Playlist.Random
+ PlaylistItem { source: "/" }
+ onError: { console.log("ERROR") }
+ }
+
+ MediaPlayer {
+ id: player
+ autoPlay: true
+ playlist: playlist
+ }
+
+ VideoOutput {
+ id: videoOutput
+ source: player
+ anchors.fill: parent
+ }
+
+ Component.onCompleted: {
+ playlist.shuffle()
+ console.log(playlist.itemCount)
+ }
+}
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Warp.qml b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Warp.qml
new file mode 100644
index 00000000..1cf9bc37
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Warp.qml
@@ -0,0 +1,64 @@
+import QtQuick 2.0
+import QtGraphicalEffects 1.0
+
+Rectangle {
+ id : canvas
+ anchors.fill: parent
+ color: "black"
+
+ function getStarColor(num){
+ if(num < 1) { return "white" }
+ if(num < 2) { return "mistyrose" }
+ return "lightblue"
+ }
+
+ // CREATE STARFIELD
+ Repeater {
+ model: Math.round(Math.random()*canvas.width/10)+500
+ Rectangle {
+ parent: canvas
+ x: Math.round(Math.random()*canvas.width)
+ y: Math.round(Math.random()*canvas.height)
+ width: Math.round(Math.random()*3)+3
+ height: width
+ radius: width/2
+ color: getStarColor( (index%3) )
+
+ }
+ } //end of Repeater
+
+ // NOW CREATE THE WARP EFFECT
+ ZoomBlur {
+ id: blur
+ anchors.fill: canvas
+ source: canvas
+ samples: 24
+ length: canvas.width / 20
+ horizontalOffset: 0
+ verticalOffset: 0
+
+ Behavior on horizontalOffset{
+ NumberAnimation{
+ duration: 3000
+ }
+ }
+ Behavior on verticalOffset{
+ NumberAnimation{
+ duration: 3000
+ }
+ }
+ } //end of zoom blur
+
+ Timer {
+ interval: 5
+ repeat: true
+ running: true
+ property bool starting: true
+ onTriggered: {
+ if(starting){ interval = 3010; starting = false; }
+ blur.horizontalOffset = (Math.random()*canvas.width/4) - (canvas.width/8)
+ blur.verticalOffset = (Math.random()*canvas.height/4) - (canvas.height/8)
+ }
+ } //end of timer
+
+} //end of canvas rectangle
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey-zoom.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey-zoom.jpg
deleted file mode 100644
index 481ca438..00000000
--- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey-zoom.jpg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey.jpg
deleted file mode 100644
index 9da67596..00000000
--- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey.jpg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_gold.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_gold.jpg
deleted file mode 100644
index cba03cee..00000000
--- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_gold.jpg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_green.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_green.jpg
deleted file mode 100644
index 80b0d3e3..00000000
--- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_green.jpg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue-zoom.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue-zoom.jpg
deleted file mode 100644
index 4f753ed5..00000000
--- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue-zoom.jpg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue.jpg
deleted file mode 100644
index c214cd78..00000000
--- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue.jpg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_purple.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_purple.jpg
deleted file mode 100644
index e4c3d7a8..00000000
--- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_purple.jpg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_red.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_red.jpg
deleted file mode 100644
index a092f636..00000000
--- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_red.jpg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-desktop-unified/global-includes.h b/src-qt5/core/lumina-desktop-unified/global-includes.h
index 184f5b8d..91604362 100644
--- a/src-qt5/core/lumina-desktop-unified/global-includes.h
+++ b/src-qt5/core/lumina-desktop-unified/global-includes.h
@@ -19,6 +19,7 @@
#include <QMouseEvent>
#include <QAction>
#include <QPoint>
+#include <QTemporaryFile>
#include <QFile>
#include <QDir>
#include <QString>
@@ -53,7 +54,14 @@
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
+#include <QQuickView>
+#include <QQmlContext>
+#include <QQmlEngine>
+#include <QQuickImageProvider>
+// C++ Backend classes for QML interface
+#include <RootDesktopObject.h>
+#include <ScreenObject.h>
// libLumina includes
#include <LuminaX11.h>
@@ -64,7 +72,6 @@
#include <LDesktopUtils.h>
#include <LuminaSingleApplication.h>
#include <DesktopSettings.h>
-#include <RootWindow.h>
#include <ExternalProcess.h>
#include <NativeWindow.h>
#include <NativeWindowSystem.h>
@@ -72,8 +79,6 @@
#include <XDGMime.h>
#include <LIconCache.h>
-// Standard C includes
-#include <unistd.h>
//Setup any global defines (no classes or global objects: use "global-objects.h" for that)
diff --git a/src-qt5/core/lumina-desktop-unified/global-objects.h b/src-qt5/core/lumina-desktop-unified/global-objects.h
index 0c990dc6..c204587f 100644
--- a/src-qt5/core/lumina-desktop-unified/global-objects.h
+++ b/src-qt5/core/lumina-desktop-unified/global-objects.h
@@ -25,8 +25,12 @@
#include "src-screensaver/LScreenSaver.h"
//#include "src-WM/LWindowManager.h"
+#include <RootWindow.h>
#include "LSession.h"
+// Standard C includes
+#include <unistd.h>
+
//Any special defines for settings/testing
#define ANIMTIME 80 //animation time in milliseconds
diff --git a/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro b/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro
index e8cf2f28..21e46b22 100644
--- a/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro
+++ b/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro
@@ -1,26 +1,30 @@
include($${PWD}/../../OS-detect.pri)
-QT += core gui network
-greaterThan(QT_MAJOR_VERSION, 4): QT += widgets x11extras multimedia multimediawidgets concurrent svg
+lessThan(QT_MAJOR_VERSION, 5) {
+ message("[ERROR] Qt 5.4+ is required to use the Lumina Desktop!")
+ exit
+}
+lessThan(QT_MINOR_VERSION, 4){
+ message("[ERROR] Qt 5.4+ is required to use the Lumina Desktop!")
+ exit
+}
+QT *= core gui network widgets x11extras multimedia multimediawidgets concurrent svg quick qml
TARGET = lumina-desktop-unified
target.path = $${L_BINDIR}
#include all the special classes from the Lumina tree
-include(../libLumina/ResizeMenu.pri)
include(../libLumina/LDesktopUtils.pri) #includes LUtils and LOS
include(../libLumina/LuminaXDG.pri)
-#include(../libLumina/LuminaX11.pri)
include(../libLumina/LuminaSingleApplication.pri)
-include(../libLumina/LuminaThemes.pri)
include(../libLumina/DesktopSettings.pri)
-include(../libLumina/RootWindow.pri)
include(../libLumina/ExternalProcess.pri)
-include(../libLumina/NativeWindow.pri)
+include(../../src-cpp/NativeWindow.pri)
include(../libLumina/XDGMime.pri)
-include(../libLumina/LIconCache.pri)
+
+include(../../src-cpp/plugins-screensaver.pri)
#include all the main individual source groups
include(src-screensaver/screensaver.pri)
@@ -36,8 +40,7 @@ SOURCES += main.cpp \
HEADERS += global-includes.h \
global-objects.h \
LSession.h \
- BootSplash.h \
- JsonMenu.h
+ BootSplash.h
FORMS += BootSplash.ui
@@ -54,6 +57,9 @@ desktop.files = lumina-desktop.desktop
defaults.path = $${L_SHAREDIR}/lumina-desktop
defaults.files = defaults/*
+extrafiles.path = $${L_SHAREDIR}/lumina-desktop
+extrafiles.files = extrafiles/*
+
TRANSLATIONS = i18n/lumina-desktop_af.ts \
i18n/lumina-desktop_ar.ts \
i18n/lumina-desktop_az.ts \
@@ -120,7 +126,7 @@ TRANSLATIONS = i18n/lumina-desktop_af.ts \
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
-INSTALLS += target desktop defaults
+INSTALLS += target desktop defaults extrafiles
WITH_I18N{
INSTALLS += dotrans
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.cpp
new file mode 100644
index 00000000..0cfa4e6b
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.cpp
@@ -0,0 +1,44 @@
+//===========================================
+// Lumina-desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "RootWindow.h"
+
+RootWindow::RootWindow() : QObject(){
+ root_win = QWindow::fromWinId( QX11Info::appRootWindow() ); //
+ root_view = new QQuickView(root_win); //make it a child of the root window
+ root_obj = RootDesktopObject::instance();
+ syncRootSize();
+ connect(root_win, SIGNAL(widthChanged(int)), this, SLOT(syncRootSize()) );
+ connect(root_win, SIGNAL(heightChanged(int)),this, SLOT(syncRootSize()) );
+ //Now setup the QQuickView
+ root_view->setResizeMode(QQuickView::SizeRootObjectToView);
+ root_view->engine()->rootContext()->setContextProperty("RootObject", root_obj);
+ RootDesktopObject::RegisterType(); //make sure object classes are registered with the QML subsystems
+}
+
+RootWindow::~RootWindow(){
+ root_view->deleteLater();
+ root_obj->deleteLater();
+}
+
+void RootWindow::start(){
+ root_view->setSource(QUrl("qrc:///qml/RootDesktop.qml"));
+ root_win->show();
+ root_view->show();
+}
+
+void RootWindow::syncRootSize(){
+ //qDebug() << "Sync Root Size:" << root_win->width() << root_win->height() << root_view->geometry();
+ QList<QScreen*> screens = QApplication::screens();
+ QRect unif;
+ for(int i=0; i<screens.length(); i++){ unif = unif.united(screens[i]->geometry()); }
+ if(unif.width() != root_view->width() || unif.height() != root_view->height()){
+ root_view->setGeometry(0, 0, unif.width(), unif.height() );
+ emit RootResized(root_view->geometry());
+ }
+ root_obj->updateScreens();
+ //qDebug() << " - after:" << root_view->geometry();
+}
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h
new file mode 100644
index 00000000..ba489465
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h
@@ -0,0 +1,34 @@
+//===========================================
+// Lumina-desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#ifndef _LUMINA_DESKTOP_ROOT_WINDOW_H
+#define _LUMINA_DESKTOP_ROOT_WINDOW_H
+#include <global-includes.h>
+
+class RootWindow : public QObject{
+ Q_OBJECT
+private:
+ QWindow *root_win;
+ QQuickView *root_view;
+ RootDesktopObject *root_obj;
+
+public:
+ RootWindow();
+ ~RootWindow();
+
+ void start();
+
+public slots:
+ void syncRootSize();
+
+signals:
+ void startLogout();
+ void RegisterVirtualRoot(WId);
+ void RootResized(QRect);
+ void MouseMoved();
+};
+
+#endif
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri b/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri
index 75aef8a6..e4c4faeb 100644
--- a/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri
@@ -1,6 +1,11 @@
-SOURCES *= $${PWD}/ContextMenu.cpp
+QT *= gui widgets qml quick
-HEADERS *= $${PWD}/ContextMenu.h
+SOURCES *= $${PWD}/RootWindow.cpp
+
+HEADERS *= $${PWD}/RootWindow.h
#update the includepath so we can just #include as needed without paths
-INCLUDEPATH *= ${PWD}
+INCLUDEPATH *= $${PWD}
+
+include($${PWD}/src-cpp/src-cpp.pri)
+include($${PWD}/src-qml/src-qml.pri)
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp
new file mode 100644
index 00000000..9842712e
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp
@@ -0,0 +1,77 @@
+//===========================================
+// Lumina-desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "RootDesktopObject.h"
+#include <QQmlEngine>
+#include <QApplication>
+#include <QScreen>
+
+#include <QDebug>
+
+// === PUBLIC ===
+RootDesktopObject::RootDesktopObject(QObject *parent) : QObject(parent){
+ updateScreens(); //make sure the internal list is updated right away
+}
+
+RootDesktopObject::~RootDesktopObject(){
+
+}
+
+void RootDesktopObject::RegisterType(){
+ qmlRegisterType<RootDesktopObject>("Lumina.Backend.RootDesktopObject", 2, 0, "RootDesktopObject");
+ //Also register any types that are needed by this class
+ ScreenObject::RegisterType();
+}
+
+RootDesktopObject* RootDesktopObject::instance(){
+ static RootDesktopObject* r_obj = new RootDesktopObject();
+ return r_obj;
+}
+
+//QML Read Functions
+QList<ScreenObject*> RootDesktopObject::screens(){
+ return s_objects;
+}
+
+void RootDesktopObject::logout(){
+ emit startLogout();
+}
+
+void RootDesktopObject::lockscreen(){
+ emit lockScreen();
+}
+
+void RootDesktopObject::mousePositionChanged(){
+ emit mouseMoved();
+}
+
+// === PUBLIC SLOTS ===
+void RootDesktopObject::updateScreens(){
+ QList<QScreen*> scrns = QApplication::screens();
+ QList<ScreenObject*> tmp; //copy of the internal array initially
+ for(int i=0; i<scrns.length(); i++){
+ bool found = false;
+ for(int j=0; j<s_objects.length() && !found; j++){
+ if(s_objects[j]->name()==scrns[i]->name()){ found = true; tmp << s_objects.takeAt(j); }
+ }
+ if(!found){ tmp << new ScreenObject(scrns[i], this); }
+ }
+ //Delete any leftover objects
+ for(int i=0; i<s_objects.length(); i++){ s_objects[i]->deleteLater(); }
+ s_objects = tmp;
+ emit screensChanged();
+ for(int i=0; i<s_objects.length(); i++){
+ s_objects[i]->emit geomChanged();
+ }
+}
+
+void RootDesktopObject::ChangeWallpaper(QString screen, QString value){
+ for(int i=0; i<s_objects.length(); i++){
+ if(s_objects[i]->name()==screen){ s_objects[i]->setBackground(value); break; }
+ }
+}
+
+// === PRIVATE ===
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h
new file mode 100644
index 00000000..dd7c7ab3
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h
@@ -0,0 +1,54 @@
+//===========================================
+// Lumina-desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+// This is the base C++ object that is used to pass information to the QML "RootDesktop" object
+//===========================================
+#ifndef _LUMINA_DESKTOP_QML_BACKEND_ROOT_DESKTOP_OBJECT_H
+#define _LUMINA_DESKTOP_QML_BACKEND_ROOT_DESKTOP_OBJECT_H
+#include <QObject>
+#include <QList>
+
+#include "ScreenObject.h"
+
+class RootDesktopObject : public QObject{
+ Q_OBJECT
+ //Define all the QML Properties here (interface between QML and the C++ methods below)
+ Q_PROPERTY( QList<ScreenObject*> screens READ screens NOTIFY screensChanged)
+
+public:
+ //main contructor/destructor
+ RootDesktopObject(QObject *parent = 0);
+ ~RootDesktopObject();
+
+ static void RegisterType();
+
+ //primary interface to fetch the current instance of the class (so only one is running at any given time)
+ static RootDesktopObject* instance();
+
+ //QML Read Functions
+ QList<ScreenObject*> screens();
+
+ //QML Access Functions
+ Q_INVOKABLE void logout();
+ Q_INVOKABLE void lockscreen();
+ Q_INVOKABLE void mousePositionChanged();
+private:
+ QList<ScreenObject*> s_objects;
+
+public slots:
+ void updateScreens(); //rescan/update screen objects
+ void ChangeWallpaper(QString screen, QString);
+
+private slots:
+
+signals:
+ void screensChanged();
+ void startLogout();
+ void mouseMoved();
+ void lockScreen();
+
+};
+#endif
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp
new file mode 100644
index 00000000..4c1d6189
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp
@@ -0,0 +1,31 @@
+//===========================================
+// Lumina-desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "ScreenObject.h"
+#include <QQmlEngine>
+#include <QDebug>
+
+ScreenObject::ScreenObject(QScreen *scrn, QObject *parent) : QObject(parent){
+ bg_screen = scrn;
+}
+
+void ScreenObject::RegisterType(){
+ qmlRegisterType<ScreenObject>("Lumina.Backend.ScreenObject",2,0, "ScreenObject");
+}
+
+QString ScreenObject::name(){ return bg_screen->name(); }
+QString ScreenObject::background(){ qDebug() << "Got Background:" << bg_screen->name() << bg << bg_screen->geometry(); return bg; }
+int ScreenObject::x(){ return bg_screen->geometry().x(); }
+int ScreenObject::y(){ return bg_screen->geometry().y(); }
+int ScreenObject::width(){ return bg_screen->geometry().width(); }
+int ScreenObject::height(){ return bg_screen->geometry().height(); }
+
+void ScreenObject::setBackground(QString fileOrColor){
+ if(bg!=fileOrColor){
+ bg = fileOrColor;
+ emit backgroundChanged();
+ }
+}
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.h
new file mode 100644
index 00000000..8076f1ae
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.h
@@ -0,0 +1,48 @@
+//===========================================
+// Lumina-desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+// This is the base C++ object that is used to pass Screen/Wallpaper info to the QML classes
+//===========================================
+#ifndef _LUMINA_DESKTOP_SCREEN_DESKTOP_OBJECT_H
+#define _LUMINA_DESKTOP_SCREEN_DESKTOP_OBJECT_H
+#include <QObject>
+#include <QString>
+#include <QScreen>
+
+class ScreenObject : public QObject {
+ Q_OBJECT
+ Q_PROPERTY( QString name READ name )
+ Q_PROPERTY( QString background READ background NOTIFY backgroundChanged)
+ Q_PROPERTY( int x READ x NOTIFY geomChanged)
+ Q_PROPERTY( int y READ y NOTIFY geomChanged)
+ Q_PROPERTY( int width READ width NOTIFY geomChanged)
+ Q_PROPERTY( int height READ height NOTIFY geomChanged)
+
+private:
+ QScreen *bg_screen;
+ QString bg;
+
+public:
+ ScreenObject(QScreen *scrn = 0, QObject *parent = 0);
+
+ static void RegisterType();
+
+ Q_INVOKABLE QString name();
+ Q_INVOKABLE QString background();
+ Q_INVOKABLE int x();
+ Q_INVOKABLE int y();
+ Q_INVOKABLE int width();
+ Q_INVOKABLE int height();
+
+public slots:
+ void setBackground(QString fileOrColor);
+
+signals:
+ void backgroundChanged();
+ void geomChanged();
+};
+
+#endif
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/src-cpp.pri b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/src-cpp.pri
new file mode 100644
index 00000000..33b699da
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/src-cpp.pri
@@ -0,0 +1,8 @@
+SOURCES *= $${PWD}/RootDesktopObject.cpp \
+ $${PWD}/ScreenObject.cpp
+
+HEADERS *= $${PWD}/RootDesktopObject.h \
+ $${PWD}/ScreenObject.h
+
+INCLUDEPATH *= $${PWD}
+
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/ContextMenu.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/ContextMenu.qml
new file mode 100644
index 00000000..e5bac0b5
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/ContextMenu.qml
@@ -0,0 +1,36 @@
+//===========================================
+// Lumina-desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+import QtQuick 2.2
+import QtQuick.Window 2.2
+import QtQuick.Controls 2.0
+
+import Lumina.Backend.RootDesktopObject 2.0
+
+Menu {
+ id: contextMenu
+ closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
+ MenuItem {
+ text: "Lock Screen"
+ onTriggered: {
+ RootObject.lockscreen()
+ }
+ }
+
+ MenuItem {
+ text: "Logout"
+ //iconName: "system-log-out"
+ indicator: Image{
+ asynchronous: true
+ //autoTransform: true
+ //source: "image://theme/system-logout"
+ source: "file:///usr/local/share/icons/material-design-light/scalable/actions/system-log-out.svg"
+ }
+ onTriggered: {
+ RootObject.logout()
+ }
+ }
+ }
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml
new file mode 100644
index 00000000..a1a9164f
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml
@@ -0,0 +1,57 @@
+//===========================================
+// Lumina-desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+// This is the base QML script the launches/controls the desktop interface itself
+//===========================================
+// NOTE: This needs to be paired/used with the corresponding C++ class: RootDesktopObject
+// Which should be added as the "RootObject" context property to the QML engine
+//------------------
+// Example Code:
+// RootDesktopObject *rootobj = new RootDesktopObject();
+// QQuickView *root = new QQuickView();
+// root->setResizeMode(QQuickView::SizeRootObjectToView);
+// root->engine()->rootContext()->setContextProperty("RootObject", rootobj);
+//===========================================
+import QtQuick 2.2
+import QtQuick.Window 2.2
+import QtQuick.Controls 2.0
+
+import "." as QML
+
+import Lumina.Backend.RootDesktopObject 2.0
+import Lumina.Backend.ScreenObject 2.0
+
+Rectangle {
+ id: rootCanvas
+ color: "black"
+
+ //Setup the right-click context menu
+ MouseArea {
+ anchors.fill: rootCanvas
+ acceptedButtons: Qt.RightButton
+ onClicked: {
+ contextMenu.x = mouseX
+ contextMenu.y = mouseY
+ contextMenu.open()
+ }
+ onPositionChanged: {
+ RootObject.mousePositionChanged()
+ }
+ }
+
+ //Create the context menu itself
+ QML.ContextMenu { id: contextMenu }
+
+ //Setup the wallpapers
+ Repeater{
+ model: RootObject.screens
+ QML.WallpaperImage{
+ //console.log( modelData.name() )
+ object: modelData
+ z: 0+index
+ }
+ }
+}
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/WallpaperImage.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/WallpaperImage.qml
new file mode 100644
index 00000000..4d39b0b8
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/WallpaperImage.qml
@@ -0,0 +1,25 @@
+//===========================================
+// Lumina-desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+import QtQuick 2.2
+import QtQuick.Window 2.2
+import QtQuick.Controls 2.0
+
+import Lumina.Backend.ScreenObject 2.0
+
+AnimatedImage {
+ //C++ backend object
+ property ScreenObject object
+
+ //Normal geometries/placements
+ asynchronous: true
+ clip: true
+ source: object.background
+ x: object.x
+ y: object.y
+ width: object.width
+ height: object.height
+ }
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri
new file mode 100644
index 00000000..99905253
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri
@@ -0,0 +1,7 @@
+#Show the QML files to lupdate for translation purposes - not for the actual build
+lupdate_only{
+ SOURCES *= $${PWD}/RootDesktop.qml \
+ $${PWD}/ContextMenu.qml
+}
+
+RESOURCES *= $${PWD}/src-qml.qrc
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc
new file mode 100644
index 00000000..ebdcc606
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc
@@ -0,0 +1,7 @@
+<RCC>
+ <qresource prefix="qml">
+ <file>RootDesktop.qml</file>
+ <file>ContextMenu.qml</file>
+ <file>WallpaperImage.qml</file>
+ </qresource>
+</RCC>
diff --git a/src-qt5/core/lumina-desktop-unified/src-screensaver/LLockScreen.cpp b/src-qt5/core/lumina-desktop-unified/src-screensaver/LLockScreen.cpp
index 0ff70142..b791ffd2 100644
--- a/src-qt5/core/lumina-desktop-unified/src-screensaver/LLockScreen.cpp
+++ b/src-qt5/core/lumina-desktop-unified/src-screensaver/LLockScreen.cpp
@@ -77,7 +77,18 @@ void LLockScreen::TryUnlock(){
this->setEnabled(false);
QString pass = ui->line_password->text();
ui->line_password->clear();
- bool ok = (LUtils::runCmd("lumina-checkpass", QStringList() << pass) == 0);
+ //Create a temporary file for the password, then pass that file descriptor to lumina-checkpass
+ QTemporaryFile *TF = new QTemporaryFile(".XXXXXXXXXX");
+ TF->setAutoRemove(true);
+ bool ok = false;
+ if( TF->open() ){
+ QTextStream in(TF);
+ in << pass;
+ in.flush(); //make sure we push it to the file **right now** since we need to keep the file open
+ ok = (LUtils::runCmd("lumina-checkpass", QStringList() << "-f" << TF->fileName() ) == 0);
+ TF->close();
+ }
+ delete TF;
if(ok){
emit ScreenUnlocked();
this->setEnabled(true);
diff --git a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp
index a6d5be60..122307b3 100644
--- a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp
+++ b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp
@@ -12,19 +12,19 @@
// ========
// PUBLIC
// ========
-SSBaseWidget::SSBaseWidget(QWidget *parent) : QWidget(parent){
+SSBaseWidget::SSBaseWidget(QWidget *parent) : QQuickView(parent->windowHandle()){
this->setObjectName("LuminaBaseSSWidget");
- ANIM = 0;
- this->setMouseTracking(true);
+ this->setResizeMode(QQuickView::SizeRootObjectToView);
+ this->setColor(QColor("black")); //default color for the view
+ this->setCursor(Qt::BlankCursor);
plugType="none";
restartTimer = new QTimer(this);
- restartTimer->setInterval( DesktopSettings::instance()->value(DesktopSettings::ScreenSaver, "globals/plugin_time_seconds", 60).toInt() * 1000);
+ restartTimer->setInterval( DesktopSettings::instance()->value(DesktopSettings::ScreenSaver, "globals/plugin_time_seconds", 120).toInt() * 1000);
restartTimer->setSingleShot(true);
connect(restartTimer, SIGNAL(timeout()), this, SLOT(startPainting()) );
}
SSBaseWidget::~SSBaseWidget(){
- if(ANIM!=0){ this->stopPainting(); }
}
void SSBaseWidget::setPlugin(QString plug){
@@ -35,54 +35,27 @@ void SSBaseWidget::setPlugin(QString plug){
// PUBLIC SLOTS
// =============
void SSBaseWidget::startPainting(){
- cplug = plugType;
//free up any old animation instance
- if(ANIM!=0){
- stopPainting();
- }
+ stopPainting();
//If a random plugin - grab one of the known plugins
- if(cplug=="random"){
- QStringList valid = BaseAnimGroup::KnownAnimations();
- valid.removeAll("none"); //they want a screensaver - remove the "none" option from the valid list
- if(valid.isEmpty()){ cplug = "none"; } //no known plugins
- else{ cplug = valid[ qrand()%valid.length() ]; } //grab a random plugin
- }
- if(DEBUG){ qDebug() << " - Screen Saver:" << plugType << cplug; }
- //Now list all the various plugins and start them appropriately
- QString style;
- if(cplug=="none"){
- style = "background: black;"; //show the underlying black parent widget
- }else{
- style = "background: black;";
+ if(plugType=="random"){
+ QList<SSPlugin> valid = SSPluginSystem::findAllPlugins();
+ if(!valid.isEmpty()){ cplug = valid[ qrand()%valid.length() ]; } //grab a random plugin
+ }else if(plugType!="none"){
+ cplug = SSPluginSystem::findPlugin(plugType);
}
- this->setStyleSheet("QWidget#LuminaBaseSSWidget{ "+style+"}");
- this->repaint();
- //If not a stylesheet-based plugin - set it here
- if(cplug!="none"){
- ANIM = BaseAnimGroup::NewAnimation(cplug, this);
- connect(ANIM, SIGNAL(finished()), this, SLOT(startPainting()) ); //repeat the plugin as needed
- ANIM->LoadAnimations();
+ if(DEBUG){ qDebug() << " - Screen Saver:" << plugType << cplug.scriptURL() << cplug.isValid(); }
+ if(cplug.isValid()){
+ this->setSource( cplug.scriptURL() );
+ if(plugType=="random"){ restartTimer->start(); }
}
- //Now start the animation(s)
- if(ANIM!=0){
- if(ANIM->animationCount()>0){
- if(DEBUG){ qDebug() << " - Starting SS Plugin:" << cplug << ANIM->animationCount() << ANIM->duration() << ANIM->loopCount(); }
- ANIM->start();
- }
- }
- restartTimer->start();
+
}
void SSBaseWidget::stopPainting(){
- if(ANIM!=0){
- if(DEBUG){ qDebug() << "Stopping Animation!!"; }
- ANIM->stop();
- //ANIM->clear();
- ANIM->deleteLater();
- ANIM = 0;
- //Delete any child widgets of the canvas
- QList<QWidget*> widgets = this->findChildren<QWidget*>("",Qt::FindDirectChildrenOnly);
- for(int i=0; i<widgets.length(); i++){ widgets[i]->deleteLater(); }
+ if(!this->source().isEmpty()){
+ this->setSource(QUrl());
+ cplug = SSPlugin(); //empty structure
}
if(restartTimer->isActive()){ restartTimer->stop(); }
}
diff --git a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h
index af809127..72e02702 100644
--- a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h
+++ b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h
@@ -10,9 +10,9 @@
#define _LUMINA_DESKTOP_SCREEN_SAVER_BASE_WIDGET_H
#include "global-includes.h"
-#include "animations/BaseAnimGroup.h"
+#include <plugins-screensaver.h>
-class SSBaseWidget : public QWidget{
+class SSBaseWidget : public QQuickView{
Q_OBJECT
public:
SSBaseWidget(QWidget *parent);
@@ -25,8 +25,8 @@ public slots:
void stopPainting();
private:
- QString plugType, cplug; //type of custom painting to do
- BaseAnimGroup *ANIM;
+ QString plugType;
+ SSPlugin cplug;
QTimer *restartTimer;
private slots:
@@ -43,12 +43,6 @@ protected:
ev->accept();
emit InputDetected();
}
- void paintEvent(QPaintEvent*){
- QStyleOption opt;
- opt.init(this);
- QPainter p(this);
- style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
- }
};
diff --git a/src-qt5/core/lumina-desktop-unified/src-screensaver/screensaver.pri b/src-qt5/core/lumina-desktop-unified/src-screensaver/screensaver.pri
index f95891c1..92cc7bd2 100644
--- a/src-qt5/core/lumina-desktop-unified/src-screensaver/screensaver.pri
+++ b/src-qt5/core/lumina-desktop-unified/src-screensaver/screensaver.pri
@@ -9,7 +9,7 @@ HEADERS *= $${PWD}/LLockScreen.h \
FORMS *= $${PWD}/LLockScreen.ui
#update the includepath so we can just (#include <LScreenSaver.h>) as needed without paths
-INCLUDEPATH *= ${PWD}
+INCLUDEPATH *= $${PWD}
#Now include all the screensaver animations/options
-include(animations/animations.pri)
+#include(animations/animations.pri)
diff --git a/src-qt5/core/lumina-desktop/LDesktop.cpp b/src-qt5/core/lumina-desktop/LDesktop.cpp
index f9ea1534..71b10bd5 100644
--- a/src-qt5/core/lumina-desktop/LDesktop.cpp
+++ b/src-qt5/core/lumina-desktop/LDesktop.cpp
@@ -341,7 +341,7 @@ void LDesktop::UpdateMenu(bool fast){
void LDesktop::UpdateWinMenu(){
winMenu->clear();
//Get the current list of windows
- QList<WId> wins = LSession::handle()->XCB->WindowList();
+ QList<WId> wins = LSession::handle()->XCB->WindowList();
//Now add them to the menu
for(int i=0; i<wins.length(); i++){
LWinInfo info(wins[i]);
@@ -352,7 +352,7 @@ void LDesktop::UpdateWinMenu(){
}
void LDesktop::winClicked(QAction* act){
- LSession::handle()->XCB->ActivateWindow( act->data().toString().toULong() );
+ LSession::handle()->XCB->ActivateWindow( act->data().toString().toULong() );
}
void LDesktop::UpdateDesktop(){
@@ -393,7 +393,7 @@ void LDesktop::UpdateDesktop(){
if(settings->value(DPREFIX+"generateMediaIcons",true).toBool()){
QDir media("/media");
QStringList mediadirs = media.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
- for(int i=0; i<mediadirs.length(); i++){
+ for(int i=0; i<mediadirs.length(); i++){
filelist << media.absoluteFilePath(mediadirs[i]);
}
}
@@ -406,8 +406,8 @@ void LDesktop::RemoveDeskPlugin(QString ID){
//This is called after a plugin is manually removed by the user
// just need to ensure that the plugin is also removed from the settings file
QStringList plugs = settings->value(DPREFIX+"pluginlist", QStringList()).toStringList();
- if(plugs.contains(ID)){
- plugs.removeAll(ID);
+ if(plugs.contains(ID)){
+ plugs.removeAll(ID);
issyncing=true; //don't let the change cause a refresh
settings->setValue(DPREFIX+"pluginlist", plugs);
settings->sync();
@@ -437,7 +437,7 @@ void LDesktop::DecreaseDesktopPluginIcons(){
settings->setValue(DPREFIX+"GridSize",cur);
settings->sync();
QTimer::singleShot(200, this, SLOT(UnlockSettings()) );
- bgDesktop->SetIconSize(cur);
+ bgDesktop->SetIconSize(cur);
}
void LDesktop::UpdatePanels(){
@@ -484,18 +484,18 @@ void LDesktop::UpdateDesktopPluginArea(){
QRegion shifted = visReg;
QString loc = settings->value(PANELS[i]->prefix()+"location","top").toString().toLower();
int vis = PANELS[i]->visibleWidth();
- if(loc=="top"){
+ if(loc=="top"){
if(!shifted.contains(QRect(rawRect.x(), rawRect.y(), rawRect.width(), vis))){ continue; }
- shifted.translate(0, (rawRect.top()+vis)-shifted.boundingRect().top() );
+ shifted.translate(0, (rawRect.top()+vis)-shifted.boundingRect().top() );
}else if(loc=="bottom"){
- if(!shifted.contains(QRect(rawRect.x(), rawRect.bottom()-vis, rawRect.width(), vis))){ continue; }
- shifted.translate(0, (rawRect.bottom()-vis)-shifted.boundingRect().bottom());
- }else if(loc=="left"){
+ if(!shifted.contains(QRect(rawRect.x(), rawRect.bottom()-vis, rawRect.width(), vis))){ continue; }
+ shifted.translate(0, (rawRect.bottom()-vis)-shifted.boundingRect().bottom());
+ }else if(loc=="left"){
if( !shifted.contains(QRect(rawRect.x(), rawRect.y(), vis,rawRect.height())) ){ continue; }
- shifted.translate((rawRect.left()+vis)-shifted.boundingRect().left() ,0);
+ shifted.translate((rawRect.left()+vis)-shifted.boundingRect().left() ,0);
}else{ //right
if(!shifted.contains(QRect(rawRect.right()-vis, rawRect.y(), vis,rawRect.height())) ){ continue; }
- shifted.translate((rawRect.right()-vis)-shifted.boundingRect().right(),0);
+ shifted.translate((rawRect.right()-vis)-shifted.boundingRect().right(),0);
}
visReg = visReg.intersected( shifted );
}
@@ -535,11 +535,20 @@ void LDesktop::UpdateBackground(){
//Get the list of background(s) to show
QStringList bgL = settings->value(DPREFIX+"background/filelist-workspace-"+QString::number( LSession::handle()->XCB->CurrentWorkspace()), QStringList()).toStringList();
if(bgL.isEmpty()){ bgL = settings->value(DPREFIX+"background/filelist", QStringList()).toStringList(); }
-
+
//qDebug() << " - List:" << bgL << CBG;
//Remove any invalid files
for(int i=0; i<bgL.length(); i++){
- if( (!QFile::exists(bgL[i]) && bgL[i]!="default" && !bgL[i].startsWith("rgb(") ) || bgL[i].isEmpty()){ bgL.removeAt(i); i--; }
+ if(bgL[i]=="default" || bgL[i].startsWith("rgb(") ){ continue; } //built-in definitions - treat them as valid
+ if(bgL[i].isEmpty()){ bgL.removeAt(i); i--; }
+ if( !QFile::exists(bgL[i]) ){
+ //Quick Detect/replace for new path for Lumina wallpapers (change in 1.3.4)
+ if(bgL[i].contains("/wallpapers/Lumina-DE/")){
+ bgL[i] = bgL[i].replace("/wallpapers/Lumina-DE/", "/wallpapers/lumina-desktop/"); i--; //modify the path and re-check it
+ }else{
+ bgL.removeAt(i); i--;
+ }
+ }
}
if(bgL.isEmpty()){ bgL << "default"; } //always fall back on the default
//Determine if the background needs to be changed
@@ -552,13 +561,32 @@ void LDesktop::UpdateBackground(){
}
oldBGL = bgL; //save this for later
//Determine which background to use next
- int index ( qrand() % bgL.length() );
- if(index== bgL.indexOf(CBG)){ //if the current wallpaper was selected by the randomization again
- //Go to the next in the list
- if(index < 0 || index >= bgL.length()-1){ index = 0; } //if invalid or last item in the list - go to first
- else{ index++; } //go to next
+ QString bgFile;
+ while(bgFile.isEmpty() || QFileInfo(bgFile).isDir()){
+ QString prefix;
+ if(!bgFile.isEmpty()){
+ //Got a directory - update the list of files and re-randomize the selection
+ QStringList imgs = LUtils::imageExtensions();
+ for(int i=0; i<imgs.length(); i++){ imgs[i].prepend("*."); }
+ QDir tdir(bgFile);
+ prefix=bgFile+"/";
+ bgL = tdir.entryList(imgs, QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
+ //If directory no longer has any valid images - remove it from list and try again
+ if(bgL.isEmpty()){
+ oldBGL.removeAll(bgFile); //invalid directory - remove it from the list for the moment
+ bgL = oldBGL; //reset the list back to the original list (not within a directory)
+ }
+ }
+ //Verify that there are files in the list - otherwise use the default
+ if(bgL.isEmpty()){ bgFile="default"; break; }
+ int index = ( qrand() % bgL.length() );
+ if(index== bgL.indexOf(CBG)){ //if the current wallpaper was selected by the randomization again
+ //Go to the next in the list
+ if(index < 0 || index >= bgL.length()-1){ index = 0; } //if invalid or last item in the list - go to first
+ else{ index++; } //go to next
+ }
+ bgFile = prefix+bgL[index];
}
- QString bgFile = bgL[index];
//Save this file as the current background
CBG = bgFile;
//qDebug() << " - Set Background to:" << CBG << index << bgL;
@@ -570,7 +598,7 @@ void LDesktop::UpdateBackground(){
bgDesktop->setBackground(backPix);
//Now reset the timer for the next change (if appropriate)
if(bgtimer->isActive()){ bgtimer->stop(); }
- if(bgL.length() > 1){
+ if(bgL.length()>1 || oldBGL.length()>1){
//get the length of the timer (in minutes)
int min = settings->value(DPREFIX+"background/minutesToChange",5).toInt();
//restart the internal timer
@@ -633,9 +661,9 @@ void LDesktop::NewDesktopFile(QString name){
QDir desktop(QDir::homePath());
if(desktop.exists(tr("Desktop"))){ desktop.cd(tr("Desktop")); } //translated folder
else{ desktop.cd("Desktop"); } //default/english folder
- if(!desktop.exists(name)){
+ if(!desktop.exists(name)){
QFile file(desktop.absoluteFilePath(name));
- if(file.open(QIODevice::WriteOnly) ){ file.close(); }
+ if(file.open(QIODevice::WriteOnly) ){ file.close(); }
}
}
}
diff --git a/src-qt5/core/lumina-desktop/LDesktopPluginSpace.cpp b/src-qt5/core/lumina-desktop/LDesktopPluginSpace.cpp
index 41a1017d..9e964f5d 100644
--- a/src-qt5/core/lumina-desktop/LDesktopPluginSpace.cpp
+++ b/src-qt5/core/lumina-desktop/LDesktopPluginSpace.cpp
@@ -21,7 +21,7 @@ LDesktopPluginSpace::LDesktopPluginSpace() : QWidget(){
//this->setAttribute(Qt::WA_TranslucentBackground);
//this->setAttribute(Qt::WA_NoSystemBackground);
this->setAutoFillBackground(false);
- this->setStyleSheet("QWidget#LuminaDesktopPluginSpace{ border: none; background: transparent; }");
+ this->setStyleSheet("QWidget#LuminaDesktopPluginSpace{ border: none; background: transparent; }");
this->setWindowFlags(Qt::WindowStaysOnBottomHint | Qt::CustomizeWindowHint | Qt::FramelessWindowHint);
this->setAcceptDrops(true);
this->setContextMenuPolicy(Qt::NoContextMenu);
@@ -34,7 +34,7 @@ LDesktopPluginSpace::LDesktopPluginSpace() : QWidget(){
}
LDesktopPluginSpace::~LDesktopPluginSpace(){
-
+
}
void LDesktopPluginSpace::LoadItems(QStringList plugs, QStringList files){
@@ -76,7 +76,7 @@ void LDesktopPluginSpace::setBackground(QPixmap pix){
void LDesktopPluginSpace::setDesktopArea(QRect area){
//qDebug() << "Setting Desktop Plugin Area:" << area;
desktopRect = area;
-
+
}
// ===================
@@ -222,7 +222,7 @@ QRect LDesktopPluginSpace::findOpenSpot(int gridwidth, int gridheight, int start
//else{ row++; }
}
if(!found){ col++; row=0; } //go to the next column
- }
+ }
}else if(reversed && (startRow>0 || startCol>0) ){
//Arrange Left->Right (work backwards)
while(row>=0 && !found){
@@ -242,7 +242,7 @@ QRect LDesktopPluginSpace::findOpenSpot(int gridwidth, int gridheight, int start
//else{ col++; }
}
if(!found){ row--; col=colCount-gridwidth;} //go to the previous row
- }
+ }
}else{
//Arrange Left->Right
while(row<(rowCount-gridheight) && !found){
@@ -296,8 +296,8 @@ void LDesktopPluginSpace::reloadPlugins(bool ForceIconUpdate ){
QStringList plugs = plugins;
QStringList items = deskitems;
for(int i=0; i<ITEMS.length(); i++){
-
- if( ITEMS[i]->whatsThis().startsWith("applauncher") && ForceIconUpdate){
+
+ if( ITEMS[i]->whatsThis().startsWith("applauncher") && ForceIconUpdate){
//Change the size of the existing plugin - preserving the location if possible
/*QRect geom = ITEMS[i]->loadPluginGeometry(); //pixel coords
if(!geom.isNull()){
@@ -306,14 +306,14 @@ void LDesktopPluginSpace::reloadPlugins(bool ForceIconUpdate ){
ITEMS[i]->savePluginGeometry( gridToGeom(geom)); //save it back in pixel coords
}*/
//Now remove the plugin for the moment - run it through the re-creation routine below
- ITEMS.takeAt(i)->deleteLater();
+ ITEMS.takeAt(i)->deleteLater();
i--;
}
else if(plugs.contains(ITEMS[i]->whatsThis())){ plugs.removeAll(ITEMS[i]->whatsThis()); }
else if(items.contains(ITEMS[i]->whatsThis().section("---",0,0).section("::",1,50))){ items.removeAll(ITEMS[i]->whatsThis().section("---",0,0).section("::",1,50)); }
else{ ITEMS[i]->removeSettings(true); ITEMS.takeAt(i)->deleteLater(); i--; } //this is considered a permanent removal (cleans settings)
}
-
+
//Now create any new items
//First load the plugins (almost always have fixed locations)
for(int i=0; i<plugs.length(); i++){
diff --git a/src-qt5/core/lumina-desktop/LSession.cpp b/src-qt5/core/lumina-desktop/LSession.cpp
index 2a1ec783..dab30f01 100644
--- a/src-qt5/core/lumina-desktop/LSession.cpp
+++ b/src-qt5/core/lumina-desktop/LSession.cpp
@@ -98,7 +98,7 @@ void LSession::setupSession(){
qDebug() << "Initializing Session";
if(QFile::exists("/tmp/.luminastopping")){ QFile::remove("/tmp/.luminastopping"); }
QTime* timer = 0;
- //if(DEBUG){ timer = new QTime(); timer->start(); qDebug() << " - Init srand:" << timer->elapsed();}
+ if(DEBUG){ timer = new QTime(); timer->start(); qDebug() << " - Init srand:" << timer->elapsed();}
//Setup the QSettings default paths
splash.showScreen("settings");
@@ -118,9 +118,9 @@ void LSession::setupSession(){
}
//use the system settings
//Setup the user's lumina settings directory as necessary
- splash.showScreen("user");
- if(DEBUG){ qDebug() << " - Init User Files:" << timer->elapsed();}
- checkUserFiles(); //adds these files to the watcher as well
+ //splash.showScreen("user");
+ //if(DEBUG){ qDebug() << " - Init User Files:" << timer->elapsed();}
+ //checkUserFiles(); //adds these files to the watcher as well
//Initialize the internal variables
DESKTOPS.clear();
@@ -147,11 +147,12 @@ void LSession::setupSession(){
if(DEBUG){ qDebug() << " - Init Desktops:" << timer->elapsed();}
desktopFiles = QDir(QDir::homePath()+"/Desktop").entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs, QDir::Name | QDir::IgnoreCase | QDir::DirsFirst);
updateDesktops();
- for(int i=0; i<6; i++){ LSession::processEvents(); } //Run through this a few times so the interface systems get up and running
+ //if(DEBUG){ qDebug() << " - Process Events (6x):" << timer->elapsed();}
+ //for(int i=0; i<6; i++){ LSession::processEvents(); } //Run through this a few times so the interface systems get up and running
//Now setup the system watcher for changes
splash.showScreen("final");
- qDebug() << " - Initialize file system watcher";
+ //qDebug() << " - Initialize file system watcher";
if(DEBUG){ qDebug() << " - Init QFileSystemWatcher:" << timer->elapsed();}
watcher = new QFileSystemWatcher(this);
QString confdir = sessionsettings->fileName().section("/",0,-2);
@@ -171,14 +172,18 @@ void LSession::setupSession(){
connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(watcherChange(QString)) );
connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(watcherChange(QString)) );
connect(this, SIGNAL(aboutToQuit()), this, SLOT(SessionEnding()) );
- if(DEBUG){ qDebug() << " - Init Finished:" << timer->elapsed(); delete timer;}
- for(int i=0; i<4; i++){ LSession::processEvents(); } //Again, just a few event loops here so thing can settle before we close the splash screen
+ //if(DEBUG){ qDebug() << " - Process Events (4x):" << timer->elapsed();}
+ //for(int i=0; i<4; i++){ LSession::processEvents(); } //Again, just a few event loops here so thing can settle before we close the splash screen
+ if(DEBUG){ qDebug() << " - Launch Startup Apps:" << timer->elapsed();}
//launchStartupApps();
QTimer::singleShot(500, this, SLOT(launchStartupApps()) );
- splash.hide();
- LSession::processEvents();
+ //if(DEBUG){ qDebug() << " - Hide Splashscreen:" << timer->elapsed();}
+ //splash.hide();
+ //LSession::processEvents();
+ if(DEBUG){ qDebug() << " - Close Splashscreen:" << timer->elapsed();}
splash.close();
- LSession::processEvents();
+ //LSession::processEvents();
+ if(DEBUG){ qDebug() << " - Init Finished:" << timer->elapsed(); delete timer;}
}
void LSession::CleanupSession(){
@@ -289,7 +294,7 @@ void LSession::launchStartupApps(){
qDebug() << " - - Screen Brightness:" << QString::number(tmp)+"%";
}
//QProcess::startDetached("nice lumina-open -autostart-apps");
- ExternalProcess::launch("nice lumina-open -autostart-apps");
+ ExternalProcess::launch("lumina-open", QStringList() << "-autostart-apps", false);
//Re-load the screen brightness and volume settings from the previous session
// Wait until after the XDG-autostart functions, since the audio system might be started that way
@@ -303,7 +308,7 @@ void LSession::launchStartupApps(){
QString sfile = sessionsettings->value("audiofiles/login", LOS::LuminaShare()+"Login.ogg").toString();
playAudioFile(sfile);
}
- qDebug() << "[DESKTOP INIT FINISHED]";
+ //qDebug() << "[DESKTOP INIT FINISHED]";
}
void LSession::StartLogout(){
@@ -384,15 +389,26 @@ void LSession::checkWindowGeoms(){
}
}
-void LSession::checkUserFiles(){
+bool LSession::checkUserFiles(){
//internal version conversion examples:
// [1.0.0 -> 1000000], [1.2.3 -> 1002003], [0.6.1 -> 6001]
- QString OVS = sessionsettings->value("DesktopVersion","0").toString(); //Old Version String
- bool changed = LDesktopUtils::checkUserFiles(OVS);
+ qDebug() << "Check User Files";
+ //char tmp[] = "junk\0";
+ //int tmpN = 0;
+ //QApplication A(tmpN, (char **)&tmp);
+ QSettings sset("lumina-desktop", "sessionsettings");
+ QString OVS = sset.value("DesktopVersion","0").toString(); //Old Version String
+ qDebug() << " - Old Version:" << OVS;
+ qDebug() << " - Current Version:" << LDesktopUtils::LuminaDesktopVersion();
+ bool changed = LDesktopUtils::checkUserFiles(OVS, LDesktopUtils::LuminaDesktopVersion());
+ qDebug() << " - Made Changes:" << changed;
if(changed){
//Save the current version of the session to the settings file (for next time)
- sessionsettings->setValue("DesktopVersion", this->applicationVersion());
+ sset.setValue("DesktopVersion", LDesktopUtils::LuminaDesktopVersion());
}
+ qDebug() << "Finished with user files check";
+ //delete A;
+ return changed;
}
void LSession::refreshWindowManager(){
@@ -573,7 +589,7 @@ void LSession::SessionEnding(){
//===============
void LSession::LaunchApplication(QString cmd){
//LSession::setOverrideCursor(QCursor(Qt::BusyCursor));
- ExternalProcess::launch(cmd);
+ ExternalProcess::launch(cmd, QStringList(), true);
//QProcess::startDetached(cmd);
}
@@ -674,7 +690,7 @@ void LSession::WindowPropertyEvent(){
if(RunningApps.length() < newapps.length()){
//New Window found
//qDebug() << "New window found";
- LSession::restoreOverrideCursor(); //restore the mouse cursor back to normal (new window opened?)
+ //LSession::restoreOverrideCursor(); //restore the mouse cursor back to normal (new window opened?)
//Perform sanity checks on any new window geometries
for(int i=0; i<newapps.length() && !TrayStopping; i++){
if(!RunningApps.contains(newapps[i])){
@@ -826,7 +842,7 @@ void LSession::attachTrayWindow(WId win){
if(RunningTrayApps.contains(win)){ return; } //already managed
qDebug() << "Session Tray: Window Added";
RunningTrayApps << win;
- LSession::restoreOverrideCursor();
+ //LSession::restoreOverrideCursor();
if(DEBUG){ qDebug() << "Tray List Changed"; }
emit TrayListChanged();
}
diff --git a/src-qt5/core/lumina-desktop/LSession.h b/src-qt5/core/lumina-desktop/LSession.h
index 0d69df84..a25f3c15 100644
--- a/src-qt5/core/lumina-desktop/LSession.h
+++ b/src-qt5/core/lumina-desktop/LSession.h
@@ -39,7 +39,7 @@
#define SYSTEM_TRAY_CANCEL_MESSAGE 2
/*class MenuProxyStyle : public QProxyStyle{
-public:
+public:
int pixelMetric(PixelMetric metric, const QStyleOption *option=0, const QWidget *widget=0) const{
if(metric==PM_SmallIconSize){ return 22; } //override QMenu icon size (make it larger)
else{ return QProxyStyle::pixelMetric(metric, option, widget); } //use the current style for everything else
@@ -51,6 +51,8 @@ class LSession : public LSingleApplication{
public:
LSession(int &argc, char **argv);
~LSession();
+
+ static bool checkUserFiles();
//Functions to be called during startup
void setupSession();
@@ -63,7 +65,7 @@ public:
bool registerStartButton(QString ID);
void unregisterStartButton(QString ID);
- //Special functions for XCB event filter parsing only
+ //Special functions for XCB event filter parsing only
// (DO NOT USE MANUALLY)
void RootSizeChange();
void WindowPropertyEvent();
@@ -73,37 +75,37 @@ public:
void WindowConfigureEvent(WId);
void WindowDamageEvent(WId);
void WindowSelectionClearEvent(WId);
-
+
//System Access
//Return a pointer to the current session
static LSession* handle(){
return static_cast<LSession*>(LSession::instance());
}
-
+
static void LaunchApplication(QString cmd);
QFileInfoList DesktopFiles();
-
+
QRect screenGeom(int num);
-
+
AppMenu* applicationMenu();
void systemWindow();
SettingsMenu* settingsMenu();
LXCB *XCB; //class for XCB usage
-
+
QSettings* sessionSettings();
QSettings* DesktopPluginSettings();
-
+
//Keep track of which non-desktop window should be treated as active
WId activeWindow(); //This will return the last active window if a desktop element is currently active
-
+
//Temporarily change the session locale (nothing saved between sessions)
void switchLocale(QString localeCode);
-
+
//Play System Audio
void playAudioFile(QString filepath);
//Window Adjustment Routine (due to Fluxbox not respecting _NET_WM_STRUT)
void adjustWindowGeom(WId win, bool maximize = false);
-
+
private:
//WMProcess *WM;
QList<LDesktop*> DESKTOPS;
@@ -136,9 +138,9 @@ private:
QFileInfoList desktopFiles;
void CleanupSession();
-
+
int VersionStringToNumber(QString version);
-
+
public slots:
void StartLogout();
void StartShutdown(bool skipupdates = false);
@@ -161,7 +163,6 @@ private slots:
void removeTrayWindow(WId);
//Internal simplification functions
- void checkUserFiles();
void refreshWindowManager();
void updateDesktops();
void registerDesktopWindows();
@@ -189,7 +190,7 @@ signals:
void DesktopFilesChanged();
void MediaFilesChanged();
void WorkspaceChanged();
-
+
};
#endif
diff --git a/src-qt5/core/lumina-desktop/LXcbEventFilter.cpp b/src-qt5/core/lumina-desktop/LXcbEventFilter.cpp
index ca7fb38d..038872ff 100644
--- a/src-qt5/core/lumina-desktop/LXcbEventFilter.cpp
+++ b/src-qt5/core/lumina-desktop/LXcbEventFilter.cpp
@@ -52,8 +52,8 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag
session->emit WorkspaceChanged();
}else if( SysNotifyAtoms.contains( ((xcb_property_notify_event_t*)ev)->atom ) ){
//Update the status/list of all running windows
- session->WindowPropertyEvent();
-
+ session->WindowPropertyEvent();
+
//window-specific property change
}else if( WinNotifyAtoms.contains( ((xcb_property_notify_event_t*)ev)->atom ) ){
//Ping only that window
@@ -61,7 +61,7 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag
session->WindowPropertyEvent();
}
break;
-//==============================
+//==============================
case XCB_CLIENT_MESSAGE:
//qDebug() << "Client Message Event";
//qDebug() << " - Root Window:" << QX11Info::appRootWindow();
@@ -72,7 +72,7 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag
session->SysTrayDockRequest( ((xcb_client_message_event_t*)ev)->data.data32[2] );
}
//Ignore the System Tray messages at the moment (let the WM handle it)
-
+
//window-specific property changes
/*}else if( ((xcb_client_message_event_t*)ev)->type == session->XCB->EWMH._NET_WM_STATE ){
if( session->XCB->WindowIsMaximized( ((xcb_client_message_event_t*)ev)->window ) ){
@@ -86,22 +86,22 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag
session->WindowPropertyEvent();
}
break;
-//==============================
+//==============================
case XCB_DESTROY_NOTIFY:
//qDebug() << "Window Closed Event";
session->WindowClosedEvent( ( (xcb_destroy_notify_event_t*)ev )->window );
break;
-//==============================
+//==============================
case XCB_CONFIGURE_NOTIFY:
//qDebug() << "Configure Notify Event";
session->WindowConfigureEvent( ((xcb_configure_notify_event_t*)ev)->window );
break;
-//==============================
+//==============================
case XCB_SELECTION_CLEAR:
//qDebug() << "Selection Clear Event";
- session->WindowSelectionClearEvent( ((xcb_selection_clear_event_t*)ev)->owner );
+ session->WindowSelectionClearEvent( ((xcb_selection_clear_event_t*)ev)->owner );
break;
-//==============================
+//==============================
default:
if(TrayDmgFlag!=0){
//if( (ev->response_type & ~0x80)==TrayDmgFlag){
diff --git a/src-qt5/core/lumina-desktop/WMProcess.cpp b/src-qt5/core/lumina-desktop/WMProcess.cpp
index aa01b730..0687c1fe 100644
--- a/src-qt5/core/lumina-desktop/WMProcess.cpp
+++ b/src-qt5/core/lumina-desktop/WMProcess.cpp
@@ -30,7 +30,7 @@ void WMProcess::startWM(){
if(!isRunning()){this->start(cmd); }
/*if(ssaver->state() == QProcess::NotRunning \
&& LSession::handle()->sessionSettings()->value("WindowManager", "fluxbox").toString() != "lumina-wm"){
- ssaver->start("xscreensaver -no-splash");
+ ssaver->start("xscreensaver -no-splash");
}*/
}
@@ -52,8 +52,8 @@ void WMProcess::restartWM(){
inShutdown = true;
this->kill();
if(!this->waitForFinished(5000) ){ this->terminate(); };
- inShutdown = false;
- }
+ inShutdown = false;
+ }
this->startWM();
}
diff --git a/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf b/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf
index e453c0b8..e9520a3c 100644
--- a/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf
+++ b/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf
@@ -53,7 +53,7 @@ mime_default_application/x-tar_ifexists=lumina-archiver.desktop
#THEME SETTINGS
theme_themefile=DarkGlass #Name of the theme to use (disable for Lumina-Default)
-theme_colorfile=Black #Name of the color spec file to use for theming
+theme_colorfile=darker #Name of the color spec file to use for theming
theme_iconset=material-design-dark #Name of the icon theme to use
theme_font=Noto Sans #Name of the font family to use
theme_fontsize=10pt #Default size of the fonts to use on the desktop (can also use a percentage of the screen height (<number>%) )
diff --git a/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf b/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf
index 1327f148..40ece4f0 100644
--- a/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf
+++ b/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf
@@ -51,7 +51,7 @@ mime_default_application/x-shellscript=lumina-textedit.desktop
#THEME SETTINGS
theme_themefile=DarkGlass #Name of the theme to use (disable for Lumina-Default)
-theme_colorfile=Black #Name of the color spec file to use for theming
+theme_colorfile=darker #Name of the color spec file to use for theming
theme_iconset=material-design-dark #Name of the icon theme to use
theme_font=Arial #Name of the font family to use
theme_fontsize=10pt #Default size of the fonts to use on the desktop (can also use a percentage of the screen height (<number>%) )
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp b/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp
index 0258d561..0bf087c1 100644
--- a/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp
@@ -44,7 +44,8 @@ void AppLauncherPlugin::loadButton(){
QFileInfo info(path);
this->contextMenu()->clear();
//qDebug() << "Default Application Launcher:" << def << path;
- bool ok = QFile::exists(path);
+ bool ok = info.canonicalPath().startsWith("/net/");
+ if(!ok){ ok = QFile::exists(path); } //do it this way to ensure the file existance check never runs for /net/ files
if(!ok){ emit RemovePlugin(this->ID()); return;}
icosize = this->height()-4 - 2.2*button->fontMetrics().height();
button->setFixedSize( this->width()-4, this->height()-4);
diff --git a/src-qt5/core/lumina-desktop/lumina-desktop.pro b/src-qt5/core/lumina-desktop/lumina-desktop.pro
index d4e57c5c..2c944a11 100644
--- a/src-qt5/core/lumina-desktop/lumina-desktop.pro
+++ b/src-qt5/core/lumina-desktop/lumina-desktop.pro
@@ -77,17 +77,6 @@ fluxconf.files = fluxboxconf/fluxbox-init-rc \
fluxboxconf/fluxbox-keys
fluxconf.path = $${L_SHAREDIR}/lumina-desktop/
-wallpapers.files = wallpapers/Lumina_Wispy_gold.jpg \
- wallpapers/Lumina_Wispy_green.jpg \
- wallpapers/Lumina_Wispy_purple.jpg \
- wallpapers/Lumina_Wispy_red.jpg \
- wallpapers/Lumina_Wispy_blue-grey.jpg \
- wallpapers/Lumina_Wispy_blue-grey-zoom.jpg \
- wallpapers/Lumina_Wispy_grey-blue.jpg \
- wallpapers/Lumina_Wispy_grey-blue-zoom.jpg
-wallpapers.path = $${L_SHAREDIR}/wallpapers/Lumina-DE
-
-
defaults.files = defaults/luminaDesktop.conf \
defaults/compton.conf \
audiofiles/Logout.ogg \
diff --git a/src-qt5/core/lumina-desktop/main.cpp b/src-qt5/core/lumina-desktop/main.cpp
index b2bfa9be..826d697c 100644
--- a/src-qt5/core/lumina-desktop/main.cpp
+++ b/src-qt5/core/lumina-desktop/main.cpp
@@ -78,33 +78,19 @@ int main(int argc, char ** argv)
//Startup the session
LSession a(argc, argv);
if(!a.isPrimaryProcess()){ return 0; }
+ //Ensure that the user's config files exist
+ /*if( LSession::checkUserFiles() ){ //make sure to create any config files before creating the QApplication
+ qDebug() << "User files changed - restarting the desktop session";
+ return 787; //return special restart code
+ }*/
//Setup the log file
- /* logfile.setFileName( QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/logs/runtime.log" );
- qDebug() << "Lumina Log File:" << logfile.fileName();
- if(QFile::exists(logfile.fileName()+".old")){ QFile::remove(logfile.fileName()+".old"); }
- if(logfile.exists()){ QFile::rename(logfile.fileName(), logfile.fileName()+".old"); }
- //Make sure the parent directory exists
- if(!QFile::exists(QDir::homePath()+"/.lumina/logs")){
- QDir dir;
- dir.mkpath(QDir::homePath()+"/.lumina/logs");
- }
- logfile.open(QIODevice::WriteOnly | QIODevice::Append);*/
QTime *timer=0;
if(DEBUG){ timer = new QTime(); timer->start(); }
- //Setup Log File
- //qInstallMessageHandler(MessageOutput);
- //if(DEBUG){ qDebug() << "Theme Init:" << timer->elapsed(); }
- //LuminaThemeEngine theme(&a);
- //QObject::connect(&theme, SIGNAL(updateIcons()), &a, SLOT(reloadIconTheme()) );
- //if(DEBUG){ qDebug() << "Load Locale:" << timer->elapsed(); }
- //LUtils::LoadTranslation(&a, "lumina-desktop");
if(DEBUG){ qDebug() << "Session Setup:" << timer->elapsed(); }
a.setupSession();
- //theme.refresh();
if(DEBUG){ qDebug() << "Exec Time:" << timer->elapsed(); delete timer;}
int retCode = a.exec();
//qDebug() << "Stopping the window manager";
qDebug() << "Finished Closing Down Lumina";
- //logfile.close();
return retCode;
}
diff --git a/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp b/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp
index cae73d13..7a6b0e7c 100644
--- a/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp
+++ b/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp
@@ -20,6 +20,7 @@ LBattery::LBattery(QWidget *parent, QString id, bool horizontal) : LPPlugin(pare
connect(timer,SIGNAL(timeout()), this, SLOT(updateBattery()) );
timer->start();
QTimer::singleShot(0,this,SLOT(OrientationChange()) ); //update the sizing/icon
+ sessionsettings = new QSettings("lumina-desktop", "sessionsettings");
}
LBattery::~LBattery(){
@@ -78,7 +79,8 @@ void LBattery::updateBattery(bool force){
}
if(icon<iconOld && icon==0){
//Play some audio warning chime when
- QString sfile = LSession::handle()->sessionSettings()->value("audiofiles/batterylow", LOS::LuminaShare()+"low-battery.ogg").toString();
+ bool playaudio = sessionsettings->value("PlayBatteryLowAudio",true).toBool();
+ if( playaudio ){ QString sfile = LSession::handle()->sessionSettings()->value("audiofiles/batterylow", LOS::LuminaShare()+"low-battery.ogg").toString();
LSession::handle()->playAudioFile(sfile);
}
@@ -95,6 +97,7 @@ void LBattery::updateBattery(bool force){
else{ tt = QString( tr("%1 % (%2 Remaining)") ).arg(QString::number(charge), getRemainingTime() ); }
label->setToolTip(tt);
}
+}
QString LBattery::getRemainingTime(){
int secs = LOS::batterySecondsLeft();
diff --git a/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.h b/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.h
index d14cfc53..3c23be1c 100644
--- a/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.h
+++ b/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.h
@@ -30,6 +30,7 @@ private:
QTimer *timer;
QLabel *label;
int iconOld;
+ QSettings *sessionsettings;
private slots:
void updateBattery(bool force = false);
diff --git a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp
index f44add77..30e82c47 100644
--- a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp
+++ b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp
@@ -26,9 +26,10 @@ LStartButtonPlugin::LStartButtonPlugin(QWidget *parent, QString id, bool horizon
connect(startmenu, SIGNAL(CloseMenu()), this, SLOT(closeMenu()) );
connect(startmenu, SIGNAL(UpdateQuickLaunch(QStringList)), this, SLOT(updateQuickLaunch(QStringList)));
menu->setContents(startmenu);
- QSize saved = LSession::handle()->DesktopPluginSettings()->value("panelPlugs/"+this->type()+"/MenuSize", QSize(0,0)).toSize();
+ QRect screenSize = QApplication::desktop()->availableGeometry(this);
+ QSize saved = LSession::handle()->DesktopPluginSettings()->value("panelPlugs/"+this->type()+"/MenuSize", QSize(screenSize.width() * 0.2, screenSize.height())).toSize();
if(!saved.isNull()){ startmenu->setFixedSize(saved); } //re-load the previously saved value
-
+
button->setMenu(menu);
connect(menu, SIGNAL(aboutToHide()), this, SLOT(updateButtonVisuals()) );
QTimer::singleShot(0,this, SLOT(OrientationChange())); //Update icons/sizes
diff --git a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp
index e8df8390..c99e2b4b 100644
--- a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp
+++ b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp
@@ -138,7 +138,7 @@ void StartMenu::UpdateMenu(bool forceall){
}
void StartMenu::ReLoadQuickLaunch(){
- emit UpdateQuickLaunch( LSession::handle()->sessionSettings()->value("QuicklaunchApps",QStringList()).toStringList() );
+ emit UpdateQuickLaunch( LSession::handle()->sessionSettings()->value("QuicklaunchApps",QStringList()).toStringList() );
}
void StartMenu::UpdateQuickLaunch(QString path, bool keep){
@@ -431,7 +431,9 @@ void StartMenu::UpdateFavs(){
tmp.sort(); //Sort alphabetically by name (dirs/files)
for(int i=0; i<tmp.length(); i++){
if(type<2){ rest.removeAll(tmp[i]); }
- if( !QFile::exists(tmp[i].section("::::",2,-1)) ){ continue; } //invalid favorite - skip it
+ if( !tmp[i].section("::::",2,-1).startsWith("/net/") ){
+ if( !QFile::exists(tmp[i].section("::::",2,-1)) ){ continue; } //invalid favorite - skip it
+ }
ItemWidget *it = 0;
if( tmp[i].section("::::",2,-1).endsWith(".desktop")){
XDGDesktop item(tmp[i].section("::::",2,-1));
@@ -493,7 +495,7 @@ void StartMenu::on_stackedWidget_currentChanged(int val){
if(tot>1){
ui->frame_wkspace->setVisible(true);
int cur = LSession::handle()->XCB->CurrentWorkspace();
- ui->label_wkspace->setText( QString(tr("Workspace %1/%2")).arg(QString::number(cur+1), QString::number(tot)) );
+ ui->label_wkspace->setText( QString(tr("Workspace %1/%2")).arg(QString::number(cur+1), QString::number(tot)) );
}else{
ui->frame_wkspace->setVisible(false);
}
@@ -635,14 +637,14 @@ void StartMenu::on_tool_mute_audio_clicked(){
ui->slider_volume->setValue(0);
}
}
-
+
//Screen Brightness
void StartMenu::on_slider_bright_valueChanged(int val){
ui->label_bright->setText(QString::number(val)+"%");
LOS::setScreenBrightness(val);
}
-
+
//Workspace
void StartMenu::on_tool_set_nextwkspace_clicked(){
int cur = LSession::handle()->XCB->CurrentWorkspace();
@@ -663,10 +665,10 @@ void StartMenu::on_tool_set_prevwkspace_clicked(){
if(cur<0){ cur = tot-1; } //back to end
//qDebug() << " - New Current:" << cur;
LSession::handle()->XCB->SetCurrentWorkspace(cur);
- ui->label_wkspace->setText( QString(tr("Workspace %1/%2")).arg(QString::number(cur+1), QString::number(tot)) );
+ ui->label_wkspace->setText( QString(tr("Workspace %1/%2")).arg(QString::number(cur+1), QString::number(tot)) );
}
-
+
//Locale
void StartMenu::on_combo_locale_currentIndexChanged(int){
//Get the currently selected Locale
@@ -677,7 +679,7 @@ void StartMenu::on_combo_locale_currentIndexChanged(int){
LSession::handle()->switchLocale(locale);
}
-
+
//Search
void StartMenu::on_line_search_textEdited(QString){
if(searchTimer->isActive()){ searchTimer->stop(); }
diff --git a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h
index 8ab04d94..e2dbb273 100644
--- a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h
+++ b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h
@@ -34,13 +34,13 @@ private:
Ui::StartMenu *ui;
QStringList favs;
QString CCat, CSearch, topsearch; //current category/search
- QTimer *searchTimer;
+ QTimer *searchTimer;
//Simple utility functions
//void deleteChildren(QWidget *obj); //recursive function
void ClearScrollArea(QScrollArea *area);
void SortScrollArea(QScrollArea *area);
- void do_search(QString search, bool force);
+ void do_search(QString search, bool force);
bool promptAboutUpdates(bool &skip);
diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey-zoom.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey-zoom.jpg
deleted file mode 100644
index 481ca438..00000000
--- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey-zoom.jpg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey.jpg
deleted file mode 100644
index 9da67596..00000000
--- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey.jpg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_gold.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_gold.jpg
deleted file mode 100644
index cba03cee..00000000
--- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_gold.jpg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_green.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_green.jpg
deleted file mode 100644
index 80b0d3e3..00000000
--- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_green.jpg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue-zoom.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue-zoom.jpg
deleted file mode 100644
index 4f753ed5..00000000
--- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue-zoom.jpg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue.jpg
deleted file mode 100644
index c214cd78..00000000
--- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue.jpg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_purple.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_purple.jpg
deleted file mode 100644
index e4c3d7a8..00000000
--- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_purple.jpg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_red.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_red.jpg
deleted file mode 100644
index a092f636..00000000
--- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_red.jpg
+++ /dev/null
Binary files differ
diff --git a/src-qt5/core/lumina-open/LFileDialog.cpp b/src-qt5/core/lumina-open/LFileDialog.cpp
index ce7c6a6f..dbdb6362 100644
--- a/src-qt5/core/lumina-open/LFileDialog.cpp
+++ b/src-qt5/core/lumina-open/LFileDialog.cpp
@@ -54,9 +54,9 @@ QString LFileDialog::getDefaultApp(QString extension){
void LFileDialog::setDefaultApp(QString extension, QString appFile){
if(!extension.contains("/")){ extension = LXDG::findAppMimeForFile(appFile); }
- //mime type default: set on the system itself
- if(appFile.endsWith(".desktop")){ appFile = appFile.section("/",-1); } //only need the relative path
- LXDG::setDefaultAppForMime(extension, appFile);
+ //mime type default: set on the system itself
+ //if(appFile.endsWith(".desktop")){ appFile = appFile.section("/",-1); } //only need the relative path
+ LXDG::setDefaultAppForMime(extension, appFile);
}
// -----------
diff --git a/src-qt5/core/lumina-open/lumina-open.1 b/src-qt5/core/lumina-open/lumina-open.1
index e8c555ee..cb671da3 100644
--- a/src-qt5/core/lumina-open/lumina-open.1
+++ b/src-qt5/core/lumina-open/lumina-open.1
@@ -19,7 +19,7 @@
.Sh DESCRIPTION
Given a file with an absolute pathway or URL, the
.Nm
-utility finds the appropriate application which which to open the
+utility finds the appropriate application with which to open the
file. If the file is a *.desktop application shortcut,
.Nm
starts the application automatically. Using the appropriate flags
diff --git a/src-qt5/core/lumina-open/main.cpp b/src-qt5/core/lumina-open/main.cpp
index 72d09f42..2b9e9184 100644
--- a/src-qt5/core/lumina-open/main.cpp
+++ b/src-qt5/core/lumina-open/main.cpp
@@ -29,6 +29,8 @@
#include <LuminaOS.h>
#include <LuminaThemes.h>
+#define DEBUG 0
+
void printUsageInfo(){
qDebug() << "lumina-open: Application launcher for the Lumina Desktop Environment";
qDebug() << "Description: Given a file (with absolute path) or URL, this utility will try to find the appropriate application with which to open the file. If the file is a *.desktop application shortcut, it will just start the application appropriately. It can also perform a few specific system operations if given special flags.";
@@ -48,7 +50,6 @@ void ShowErrorDialog(int argc, char **argv, QString message){
//Setup the application
QApplication App(argc, argv);
App.setAttribute(Qt::AA_UseHighDpiPixmaps);
- LuminaThemeEngine theme(&App);
LUtils::LoadTranslation(&App,"lumina-open");
QMessageBox dlg(QMessageBox::Critical, QObject::tr("File Error"), message );
dlg.exec();
@@ -68,7 +69,7 @@ void showOSD(int argc, char **argv, QString message){
splash.setAlignment(Qt::AlignCenter);
- qDebug() << "Display OSD";
+ if(DEBUG) qDebug() << "Display OSD";
splash.setText(message);
//Make sure it is centered on the current screen
QPoint center = App.desktop()->screenGeometry(QCursor::pos()).center();
@@ -89,7 +90,7 @@ void LaunchAutoStart(){
if(cmd.contains("%")){cmd = cmd.remove("%U").remove("%u").remove("%F").remove("%f").remove("%i").remove("%c").remove("%k").simplified(); }
//Now run the command
if(!cmd.isEmpty()){
- qDebug() << " - Auto-Starting File:" << xdgapps[i]->filePath;
+ if(DEBUG) qDebug() << " - Auto-Starting File:" << xdgapps[i]->filePath;
QProcess::startDetached(cmd);
}
}
@@ -98,130 +99,129 @@ void LaunchAutoStart(){
}
QString cmdFromUser(int argc, char **argv, QString inFile, QString extension, QString& path, bool showDLG=false){
- //First check to see if there is a default for this extension
- QString defApp;
- if(extension=="mimetype"){
+ //First check to see if there is a default for this extension
+ QString defApp;
+ if(extension=="mimetype"){
//qDebug() << "inFile:" << inFile;
QStringList matches = LXDG::findAppMimeForFile(inFile, true).split("::::"); //allow multiple matches
- qDebug() << "Mimetype Matches:" << matches;
+ if(DEBUG) qDebug() << "Mimetype Matches:" << matches;
for(int i=0; i<matches.length(); i++){
defApp = LXDG::findDefaultAppForMime(matches[i]);
- //qDebug() << "MimeType:" << matches[i] << defApp;
+ //qDebug() << "MimeType:" << matches[i] << defApp;
if(!defApp.isEmpty()){ extension = matches[i]; break; }
else if(i+1==matches.length()){ extension = matches[0]; }
}
- }else{ defApp = LFileDialog::getDefaultApp(extension); }
- qDebug() << "Mimetype:" << extension << "defApp:" << defApp;
- if( !defApp.isEmpty() && !showDLG ){
- if(defApp.endsWith(".desktop")){
- XDGDesktop DF(defApp);
- if(DF.isValid()){
- QString exec = DF.getDesktopExec();
- if(!exec.isEmpty()){
- qDebug() << "[lumina-open] Using default application:" << DF.name << "File:" << inFile;
- if(!DF.path.isEmpty()){ path = DF.path; }
- return exec;
- }
+ }else{ defApp = LFileDialog::getDefaultApp(extension); }
+ if(DEBUG) qDebug() << "Mimetype:" << extension << "defApp:" << defApp;
+ if( !defApp.isEmpty() && !showDLG ){
+ if(defApp.endsWith(".desktop")){
+ XDGDesktop DF(defApp);
+ if(DF.isValid()){
+ QString exec = DF.getDesktopExec();
+ if(!exec.isEmpty()){
+ if(DEBUG) qDebug() << "[lumina-open] Using default application:" << DF.name << "File:" << inFile;
+ if(!DF.path.isEmpty()){ path = DF.path; }
+ return exec;
}
- }else{
- //Only binary given
- if(LUtils::isValidBinary(defApp)){
- qDebug() << "[lumina-open] Using default application:" << defApp << "File:" << inFile;
- return defApp; //just use the binary
- }
}
- //invalid default - reset it and continue on
- LFileDialog::setDefaultApp(extension, "");
- }
- //Final catch: directory given - no valid default found - use lumina-fm
- if(extension=="inode/directory" && !showDLG){ return "lumina-fm"; }
- //No default set -- Start up the application selection dialog
- LTHEME::LoadCustomEnvSettings();
- QApplication App(argc, argv);
- App.setAttribute(Qt::AA_UseHighDpiPixmaps);
- LuminaThemeEngine theme(&App);
- LUtils::LoadTranslation(&App,"lumina-open");
-
- LFileDialog w;
- if(extension=="email" || extension.startsWith("x-scheme-handler/")){
- //URL
- w.setFileInfo(inFile, extension, false);
}else{
- //File
- if(inFile.endsWith("/")){ inFile.chop(1); }
- w.setFileInfo(inFile.section("/",-1), extension, true);
+ //Only binary given
+ if(LUtils::isValidBinary(defApp)){
+ if(DEBUG) qDebug() << "[lumina-open] Using default application:" << defApp << "File:" << inFile;
+ return defApp; //just use the binary
}
+ }
+ //invalid default - reset it and continue on
+ LFileDialog::setDefaultApp(extension, "");
+ }
+ //Final catch: directory given - no valid default found - use lumina-fm
+ if(extension=="inode/directory" && !showDLG){ return "lumina-fm"; }
+ //No default set -- Start up the application selection dialog
+ LTHEME::LoadCustomEnvSettings();
+ QApplication App(argc, argv);
+ App.setAttribute(Qt::AA_UseHighDpiPixmaps);
+ LUtils::LoadTranslation(&App,"lumina-open");
- w.show();
- App.exec();
- if(!w.appSelected){ return ""; }
- //Return the run path if appropriate
- if(!w.appPath.isEmpty()){ path = w.appPath; }
- //Just do the default application registration here for now
- // might move it to the runtime phase later after seeing that the app has successfully started
- if(w.setDefault){
- if(!w.appFile.isEmpty()){ LFileDialog::setDefaultApp(extension, w.appFile); }
- else{ LFileDialog::setDefaultApp(extension, w.appExec); }
- }
- //Now return the resulting application command
- return w.appExec;
+ LFileDialog w;
+ if(extension=="email" || extension.startsWith("x-scheme-handler/")){
+ //URL
+ w.setFileInfo(inFile, extension, false);
+ }else{
+ //File
+ if(inFile.endsWith("/")){ inFile.chop(1); }
+ w.setFileInfo(inFile.section("/",-1), extension, true);
+ }
+
+ w.show();
+ App.exec();
+ if(!w.appSelected){ return ""; }
+ //Return the run path if appropriate
+ if(!w.appPath.isEmpty()){ path = w.appPath; }
+ //Just do the default application registration here for now
+ // might move it to the runtime phase later after seeing that the app has successfully started
+ if(w.setDefault){
+ if(!w.appFile.isEmpty()){ LFileDialog::setDefaultApp(extension, w.appFile); }
+ else{ LFileDialog::setDefaultApp(extension, w.appExec); }
+ }
+ //Now return the resulting application command
+ return w.appExec;
}
void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& path, bool& watch){
- //Get the input file
- //Make sure to load the proper system encoding first
- LUtils::LoadTranslation(0,""); //bypass application modification
- QString inFile, ActionID;
- bool showDLG = false; //flag to bypass any default application setting
- if(argc > 1){
- for(int i=1; i<argc; i++){
- if(QString(argv[i]).simplified() == "-select"){
- showDLG = true;
- }else if(QString(argv[i]).simplified() == "-testcrash"){
- //Test the crash handler
- binary = "internalcrashtest"; watch=true;
- return;
- }else if(QString(argv[i]).simplified() == "-autostart-apps"){
- LaunchAutoStart();
- return;
- }else if(QString(argv[i]).simplified() == "-volumeup"){
- int vol = LOS::audioVolume()+5; //increase 5%
- if(vol>100){ vol=100; }
- LOS::setAudioVolume(vol);
- showOSD(argc,argv, QString(QObject::tr("Audio Volume %1%")).arg(QString::number(vol)) );
- return;
- }else if(QString(argv[i]).simplified() == "-volumedown"){
- int vol = LOS::audioVolume()-5; //decrease 5%
- if(vol<0){ vol=0; }
- LOS::setAudioVolume(vol);
- showOSD(argc,argv, QString(QObject::tr("Audio Volume %1%")).arg(QString::number(vol)) );
- return;
- }else if(QString(argv[i]).simplified() == "-brightnessup"){
- int bright = LOS::ScreenBrightness();
- if(bright > 0){ //brightness control available
- bright = bright+5; //increase 5%
- if(bright>100){ bright = 100; }
- LOS::setScreenBrightness(bright);
- showOSD(argc,argv, QString(QObject::tr("Screen Brightness %1%")).arg(QString::number(bright)) );
- }
- return;
- }else if(QString(argv[i]).simplified() == "-brightnessdown"){
- int bright = LOS::ScreenBrightness();
- if(bright > 0){ //brightness control available
- bright = bright-5; //decrease 5%
- if(bright<0){ bright = 0; }
- LOS::setScreenBrightness(bright);
- showOSD(argc,argv, QString(QObject::tr("Screen Brightness %1%")).arg(QString::number(bright)) );
- }
- return;
- }else if( (QString(argv[i]).simplified() =="-action") && (argc>(i+1)) ){
- ActionID = QString(argv[i+1]);
- i++; //skip the next input
- }else if(QString(argv[i]).simplified()=="-terminal"){
- inFile = LXDG::findDefaultAppForMime("application/terminal");
- break;
- }else{
- inFile = QString::fromLocal8Bit(argv[i]);
+//Get the input file
+ //Make sure to load the proper system encoding first
+ LUtils::LoadTranslation(0,""); //bypass application modification
+QString inFile, ActionID;
+bool showDLG = false; //flag to bypass any default application setting
+if(argc > 1){
+ for(int i=1; i<argc; i++){
+ if(QString(argv[i]).simplified() == "-select"){
+ showDLG = true;
+ }else if(QString(argv[i]).simplified() == "-testcrash"){
+//Test the crash handler
+binary = "internalcrashtest"; watch=true;
+return;
+ }else if(QString(argv[i]).simplified() == "-autostart-apps"){
+LaunchAutoStart();
+return;
+ }else if(QString(argv[i]).simplified() == "-volumeup"){
+int vol = LOS::audioVolume()+5; //increase 5%
+if(vol>100){ vol=100; }
+LOS::setAudioVolume(vol);
+showOSD(argc,argv, QString(QObject::tr("Audio Volume %1%")).arg(QString::number(vol)) );
+return;
+ }else if(QString(argv[i]).simplified() == "-volumedown"){
+int vol = LOS::audioVolume()-5; //decrease 5%
+if(vol<0){ vol=0; }
+LOS::setAudioVolume(vol);
+showOSD(argc,argv, QString(QObject::tr("Audio Volume %1%")).arg(QString::number(vol)) );
+return;
+ }else if(QString(argv[i]).simplified() == "-brightnessup"){
+int bright = LOS::ScreenBrightness();
+if(bright > 0){ //brightness control available
+ bright = bright+5; //increase 5%
+ if(bright>100){ bright = 100; }
+ LOS::setScreenBrightness(bright);
+ showOSD(argc,argv, QString(QObject::tr("Screen Brightness %1%")).arg(QString::number(bright)) );
+}
+return;
+ }else if(QString(argv[i]).simplified() == "-brightnessdown"){
+int bright = LOS::ScreenBrightness();
+if(bright > 0){ //brightness control available
+ bright = bright-5; //decrease 5%
+ if(bright<0){ bright = 0; }
+ LOS::setScreenBrightness(bright);
+ showOSD(argc,argv, QString(QObject::tr("Screen Brightness %1%")).arg(QString::number(bright)) );
+}
+return;
+ }else if( (QString(argv[i]).simplified() =="-action") && (argc>(i+1)) ){
+ ActionID = QString(argv[i+1]);
+i++; //skip the next input
+ }else if(QString(argv[i]).simplified()=="-terminal"){
+ inFile = LXDG::findDefaultAppForMime("application/terminal");
+ break;
+ }else{
+ inFile = QString::fromLocal8Bit(argv[i]);
break;
}
}
@@ -268,14 +268,14 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat
}
switch(DF.type){
case XDGDesktop::APP:
- qDebug() << "Found .desktop application:" << ActionID;
+ if(DEBUG) qDebug() << "Found .desktop application:" << ActionID;
if(!DF.exec.isEmpty()){
cmd = DF.getDesktopExec(ActionID);
- qDebug() << "Got command:" << cmd;
+ if(DEBUG) qDebug() << "Got command:" << cmd;
if(!DF.path.isEmpty()){ path = DF.path; }
- watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/");
+ watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/");
}else{
- ShowErrorDialog( argc, argv, QString(QObject::tr("Application shortcut is missing the launching information (malformed shortcut): %1")).arg(inFile) );
+ ShowErrorDialog( argc, argv, QString(QObject::tr("Application shortcut is missing the launching information (malformed shortcut): %1")).arg(inFile) );
}
break;
case XDGDesktop::LINK:
@@ -284,11 +284,11 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat
inFile = DF.url;
cmd.clear();
extension = inFile.section(":",0,0);
- if(extension=="file"){ extension = "http"; } //local file URL - Make sure we use the default browser for a LINK type
+ if(extension=="file"){ extension = "http"; } //local file URL - Make sure we use the default browser for a LINK type
extension.prepend("x-scheme-handler/");
- watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/");
+ watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/");
}else{
- ShowErrorDialog( argc, argv, QString(QObject::tr("URL shortcut is missing the URL: %1")).arg(inFile) );
+ ShowErrorDialog( argc, argv, QString(QObject::tr("URL shortcut is missing the URL: %1")).arg(inFile) );
}
break;
case XDGDesktop::DIR:
@@ -297,14 +297,14 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat
inFile = DF.path;
cmd.clear();
extension = "inode/directory";
- watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/");
+ watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/");
}else{
- ShowErrorDialog( argc, argv, QString(QObject::tr("Directory shortcut is missing the path to the directory: %1")).arg(inFile) );
+ ShowErrorDialog( argc, argv, QString(QObject::tr("Directory shortcut is missing the path to the directory: %1")).arg(inFile) );
}
break;
default:
- qDebug() << DF.type << DF.name << DF.icon << DF.exec;
- ShowErrorDialog( argc, argv, QString(QObject::tr("Unknown type of shortcut : %1")).arg(inFile) );
+ if(DEBUG) qDebug() << DF.type << DF.name << DF.icon << DF.exec;
+ ShowErrorDialog( argc, argv, QString(QObject::tr("Unknown type of shortcut : %1")).arg(inFile) );
}
}
if(cmd.isEmpty()){
@@ -344,7 +344,7 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat
cmd.append(" \""+inFile+"\"");
}
}
- qDebug() << "Found Command:" << cmd << "Extension:" << extension;
+ if(DEBUG) qDebug() << "Found Command:" << cmd << "Extension:" << extension;
//Clean up any leftover "Exec" field codes (should have already been replaced earlier)
if(cmd.contains("%")){cmd = cmd.remove("%U").remove("%u").remove("%F").remove("%f").remove("%i").remove("%c").remove("%k").simplified(); }
binary = cmd; //pass this string to the calling function
@@ -367,10 +367,10 @@ int main(int argc, char **argv){
QString bin = cmd.section(" ",0,0);
if( !LUtils::isValidBinary(bin) ){
//invalid binary for some reason - open a dialog to warn the user instead
- QMessageBox::warning(0, QObject::tr("Binary Missing"), QString(QObject::tr("Could not find \"%1\". Please ensure it is installed first.")).arg(bin)+"\n\n"+cmd);
+ ShowErrorDialog(argc,argv, QString(QObject::tr("Could not find \"%1\". Please ensure it is installed first.")).arg(bin)+"\n\n"+cmd);
return 1;
}
- qDebug() << "[lumina-open] Running Cmd:" << cmd;
+ if(DEBUG) qDebug() << "[lumina-open] Running Cmd:" << cmd;
int retcode = 0;
//Provide an override file for never watching running processes.
if(watch){ watch = !QFile::exists( QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/nowatch" ); }
@@ -391,12 +391,12 @@ int main(int argc, char **argv){
}else{
QProcess *p = new QProcess();
p->setProcessEnvironment(QProcessEnvironment::systemEnvironment());
- if(!path.isEmpty() && QFile::exists(path)){
+ if(!path.isEmpty() && QFile::exists(path)){
//qDebug() << " - Setting working path:" << path;
- p->setWorkingDirectory(path);
+ p->setWorkingDirectory(path);
}
p->start(cmd);
-
+
//Now check up on it once every minute until it is finished
while(!p->waitForFinished(60000)){
//qDebug() << "[lumina-open] process check:" << p->state();
@@ -410,19 +410,17 @@ int main(int argc, char **argv){
//qDebug() << "[lumina-open] Finished Cmd:" << cmd << retcode << p->exitStatus();
if( QFile::exists("/tmp/.luminastopping") ){ watch = false; } //closing down session - ignore "crashes" (app could have been killed during cleanup)
if( (retcode < 0) && watch){ //-1 is used internally for crashed processes - most apps return >=0
-
qDebug() << "[lumina-open] Application Error:" << retcode;
- //Setup the application
- QApplication App(argc, argv);
- App.setAttribute(Qt::AA_UseHighDpiPixmaps);
- LuminaThemeEngine theme(&App);
- LUtils::LoadTranslation(&App,"lumina-open");
+ //Setup the application
+ QApplication App(argc, argv);
+ App.setAttribute(Qt::AA_UseHighDpiPixmaps);
+ LUtils::LoadTranslation(&App,"lumina-open");
//App.setApplicationName("LuminaOpen");
- QMessageBox dlg(QMessageBox::Critical, QObject::tr("Application Error"), QObject::tr("The following application experienced an error and needed to close:")+"\n\n"+cmd );
- dlg.setWindowFlags(Qt::Window);
- if(!log.isEmpty()){ dlg.setDetailedText(log); }
- dlg.exec();
- }
+ QMessageBox dlg(QMessageBox::Critical, QObject::tr("Application Error"), QObject::tr("The following application experienced an error and needed to close:")+"\n\n"+cmd );
+ dlg.setWindowFlags(Qt::Window);
+ if(!log.isEmpty()){ dlg.setDetailedText(log); }
+ dlg.exec();
+ }
}
return retcode;
}
diff --git a/src-qt5/core/lumina-session/main.cpp b/src-qt5/core/lumina-session/main.cpp
index 71244a8b..3b71bdca 100644
--- a/src-qt5/core/lumina-session/main.cpp
+++ b/src-qt5/core/lumina-session/main.cpp
@@ -55,14 +55,6 @@ int main(int argc, char ** argv)
return QProcess::execute("xinit", args);
}
qDebug() << "Starting the Lumina desktop on current X11 session:" << disp;
- //Setup any initialization values
- LTHEME::LoadCustomEnvSettings();
- LXDG::setEnvironmentVars();
- setenv("DESKTOP_SESSION","Lumina",1);
- setenv("XDG_CURRENT_DESKTOP","Lumina",1);
- unsetenv("QT_QPA_PLATFORMTHEME"); //causes issues with Lumina themes - not many people have this by default...
- //Check for any missing user config files
-
//Check for any stale desktop lock files and clean them up
QString cfile = QDir::tempPath()+"/.LSingleApp-%1-%2-%3";
@@ -81,14 +73,22 @@ int main(int argc, char ** argv)
}
//Configure X11 monitors if needed
- if(LUtils::isValidBinary("lumina-xconfig")){
+ if(LUtils::isValidBinary("lumina-xconfig")){
qDebug() << " - Resetting monitor configuration to last-used settings";
QProcess::execute("lumina-xconfig --reset-monitors");
}
qDebug() << " - Starting the session...";
+ //Setup any initialization values
+ LTHEME::LoadCustomEnvSettings();
+ LXDG::setEnvironmentVars();
+ setenv("DESKTOP_SESSION","Lumina",1);
+ setenv("XDG_CURRENT_DESKTOP","Lumina",1);
+ unsetenv("QT_QPA_PLATFORMTHEME"); //causes issues with Lumina themes - not many people have this by default...
//Startup the session
- QCoreApplication a(argc, argv);
+ QApplication a(argc, argv);
+ setenv("QP_QPA_PLATFORMTHEME","lthemeengine",1); //make sure this is after the QApplication - not actually using the theme plugin for **this** process
LSession sess;
+ sess.checkFiles(); //Make sure user files are created/installed first
sess.start(unified);
int retCode = a.exec();
qDebug() << "Finished Closing Down Lumina";
diff --git a/src-qt5/core/lumina-session/session.cpp b/src-qt5/core/lumina-session/session.cpp
index 3fdf9e66..743fc396 100644
--- a/src-qt5/core/lumina-session/session.cpp
+++ b/src-qt5/core/lumina-session/session.cpp
@@ -15,6 +15,7 @@
#include <LUtils.h>
#include <LuminaOS.h>
+#include <LDesktopUtils.h>
void LSession::stopall(){
stopping = true;
@@ -38,8 +39,12 @@ void LSession::procFinished(){
stopped++;
if(!stopping){
//See if this process is the main desktop binary
- if(PROCS[i]->objectName()=="runtime"){ stopall(); }
- else if(PROCS[i]->objectName()=="wm" && wmfails<2){ wmfails++; PROCS[i]->start(QIODevice::ReadOnly); wmTimer->start(); } //restart the WM
+ if(PROCS[i]->objectName()=="runtime"){
+ qDebug() << "Got Desktop Process Finished:" << PROCS[i]->exitCode();
+ //if(PROCS[i]->exitCode()==787){ PROCS[i]->start(QIODevice::ReadOnly); } //special internal restart code
+ //else{
+ stopall(); //}
+ }else if(PROCS[i]->objectName()=="wm" && wmfails<2){ wmfails++; PROCS[i]->start(QIODevice::ReadOnly); wmTimer->start(); } //restart the WM
//if(PROCS[i]->program().section("/",-1) == "lumina-desktop"){ stopall(); } //start closing down everything
//else{ PROCS[i]->start(QIODevice::ReadOnly); } //restart the process
//break;
@@ -164,3 +169,20 @@ void LSession::start(bool unified){
startProcess("runtime","lumina-desktop-unified");
}
}
+
+void LSession::checkFiles(){
+//internal version conversion examples:
+ // [1.0.0 -> 1000000], [1.2.3 -> 1002003], [0.6.1 -> 6001]
+ qDebug() << "[Lumina] Checking User Files";
+ QSettings sset("lumina-desktop", "sessionsettings");
+ QString OVS = sset.value("DesktopVersion","0").toString(); //Old Version String
+ qDebug() << " - Old Version:" << OVS;
+ qDebug() << " - Current Version:" << LDesktopUtils::LuminaDesktopVersion();
+ bool changed = LDesktopUtils::checkUserFiles(OVS, LDesktopUtils::LuminaDesktopVersion());
+ qDebug() << " - Made Changes:" << changed;
+ if(changed){
+ //Save the current version of the session to the settings file (for next time)
+ sset.setValue("DesktopVersion", LDesktopUtils::LuminaDesktopVersion());
+ }
+ qDebug() << "Finished with user files check";
+}
diff --git a/src-qt5/core/lumina-session/session.h b/src-qt5/core/lumina-session/session.h
index 5cf1ccfa..3bbcbb8e 100644
--- a/src-qt5/core/lumina-session/session.h
+++ b/src-qt5/core/lumina-session/session.h
@@ -83,4 +83,6 @@ public:
void start(bool unified = false);
+ void checkFiles();
+
};
diff --git a/src-qt5/core/lumina-theme-engine/qss/scrollbar-simple.qss b/src-qt5/core/lumina-theme-engine/qss/scrollbar-simple.qss
index 265ff20c..d0c9b448 100644
--- a/src-qt5/core/lumina-theme-engine/qss/scrollbar-simple.qss
+++ b/src-qt5/core/lumina-theme-engine/qss/scrollbar-simple.qss
@@ -11,7 +11,7 @@ QScrollBar:vertical{
QScrollBar::handle{
background: palette(base);
border: 1px solid transparent;
- border-radius: 7px;
+ border-radius: 1px;
}
QScrollBar::handle:hover, QScrollBar::add-line:hover, QScrollBar::sub-line:hover{
background: palette(highlight);
diff --git a/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss b/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss
new file mode 100644
index 00000000..e8311e92
--- /dev/null
+++ b/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss
@@ -0,0 +1,70 @@
+/* SLIDERS */
+QSlider::groove:horizontal {
+border: 1px solid transparent;
+background: palette(alternate-window);
+height: 10px;
+border-radius: 3px;
+}
+QSlider::groove:vertical {
+border: 1px solid transparent;
+background: palette(alternate-window);
+width: 10px;
+border-radius: 3px;
+}
+QSlider::sub-page:horizontal {
+background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1,
+ stop: 0 palette(highlight), stop: 1 palette(window));
+border: 1px solid transparent;
+height: 10px;
+border-radius: 3px;
+}
+QSlider::sub-page:vertical {
+background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1,
+ stop: 0 palette(highlight), stop: 1 palette(window));
+border: 1px solid transparent;
+width: 10px;
+border-radius: 3px;
+}
+QSlider::add-page:horizontal{
+background: palette(alternate-window);
+border: 1px solid transparent;
+height: 10px;
+border-radius: 3px;
+}
+QSlider::add-page:vertical{
+background: palette(alternate-window);
+border: 1px solid transparent;
+width: 10px;
+border-radius: 3px;
+}
+QSlider::handle:horizontal{
+background: palette(mid);
+border: 1px solid palette(mid);
+width: 1em;
+border-radius: 1px;
+}
+QSlider::handle:vertical{
+background: palette(mid);
+border: 1px solid palette(mid);
+height: 1em;
+border-radius: 1px;
+}
+QSlider::handle:horizontal:hover, QSlider::handle:vertical:hover{
+border: 1px solid palette(highlight);
+background: palette(highlight);
+}
+
+QSlider::sub-page:horizontal:disabled {
+background: palette(highlight);
+border-color: palette(highlight);
+}
+
+QSlider::add-page:horizontal:disabled {
+background: palette(highlight);
+border-color: palette(highlight);
+}
+
+QSlider::handle:horizontal:disabled {
+background: palette(alternate-window);
+border: 1px solid palette(highlight);
+}
diff --git a/src-qt5/core/lumina-theme-engine/qss/tooltip-simple.qss b/src-qt5/core/lumina-theme-engine/qss/tooltip-simple.qss
new file mode 100644
index 00000000..9bee3e08
--- /dev/null
+++ b/src-qt5/core/lumina-theme-engine/qss/tooltip-simple.qss
@@ -0,0 +1,7 @@
+QToolTip{
+ background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 palette(window), stop: 1 palette(alternate-window));
+ border-radius: 3px;
+ border: 1px solid palette(highlight);
+ padding: 1px;
+ color: palette(text);
+}
diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.cpp b/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.cpp
index d4544c7b..28a5e558 100644
--- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.cpp
+++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.cpp
@@ -55,7 +55,7 @@ void MainWindow::on_buttonBox_clicked(QAbstractButton *button){
if(p) { p->writeSettings(); }
}
}
- if(id == QDialogButtonBox::Ok || id == QDialogButtonBox::Cancel){
+ if(id == QDialogButtonBox::Ok || id == QDialogButtonBox::Cancel || id== QDialogButtonBox::Close){
close();
qApp->quit();
}
diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.ui b/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.ui
index dd676c37..0dc3245d 100644
--- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.ui
+++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.ui
@@ -293,7 +293,7 @@ Styles</string>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
- <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ <set>QDialogButtonBox::Apply|QDialogButtonBox::Close</set>
</property>
</widget>
</item>
diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.cpp b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.cpp
index cd88fb56..6377016c 100644
--- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.cpp
+++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.cpp
@@ -31,6 +31,7 @@ QSSPage::QSSPage(QWidget *parent, bool desktop) : TabPage(parent), m_ui(new Ui::
m_ui->removeButton->setIcon(QIcon::fromTheme("edit-delete"));
m_ui->tool_enable->setEnabled(false);
m_ui->tool_disable->setEnabled(false);
+ m_ui->copyButton->setEnabled(false);
}
QSSPage::~QSSPage(){
@@ -56,6 +57,7 @@ void QSSPage::on_qssListWidget_currentItemChanged(QListWidgetItem *current, QLis
}
//qDebug() << "Got Current Item Changed";
m_ui->tool_disable->setEnabled(current!=0);
+ m_ui->copyButton->setEnabled(current!=0);
if(current){
m_ui->editButton->setEnabled(current->data(QSS_WRITABLE_ROLE).toBool());
m_ui->removeButton->setEnabled(current->data(QSS_WRITABLE_ROLE).toBool());
@@ -76,6 +78,7 @@ void QSSPage::on_list_disabled_currentItemChanged(QListWidgetItem *current, QLis
}
//qDebug() << "Got Current Item Changed";
m_ui->tool_enable->setEnabled(current!=0);
+ m_ui->copyButton->setEnabled(current!=0);
if(current){
m_ui->editButton->setEnabled(current->data(QSS_WRITABLE_ROLE).toBool());
m_ui->removeButton->setEnabled(current->data(QSS_WRITABLE_ROLE).toBool());
@@ -127,6 +130,36 @@ void QSSPage::on_editButton_clicked(){
}
}
+void QSSPage::on_copyButton_clicked(){
+ QListWidgetItem *sel = currentSelection();
+ if(sel==0){ return; }
+ QString name = QInputDialog::getText(this, tr("Enter Style Sheet Name"), tr("File name:"), QLineEdit::Normal, sel->text().section(".qss",0,0)+"_copy");
+ if(name.isEmpty()){ return; }
+ if(!name.endsWith(".qss", Qt::CaseInsensitive)){ name.append(".qss"); }
+ QString filePath;
+ if(desktop_qss){ filePath = lthemeengine::userDesktopStyleSheetPath() + name; }
+ else{ filePath = lthemeengine::userStyleSheetPath() + name; }
+ if(QFile::exists(filePath)){
+ QMessageBox::warning(this, tr("Error"), tr("The file \"%1\" already exists").arg(filePath));
+ return;
+ }
+ // Make sure the directory exists
+ QString dir = filePath.section("/",0,-2);
+ if(!QFile::exists(dir)){
+ QDir D(dir);
+ D.mkpath(dir);
+ }
+ //Copy the file over
+ QFile::copy(sel->data(QSS_FULL_PATH_ROLE).toString(), filePath);
+ //creating item
+ QFileInfo info(filePath);
+ QListWidgetItem *item = new QListWidgetItem(info.fileName(), m_ui->list_disabled);
+ item->setToolTip(info.filePath());
+ item->setData(QSS_FULL_PATH_ROLE, info.filePath());
+ item->setData(QSS_WRITABLE_ROLE, info.isWritable());
+ m_ui->list_disabled->setCurrentRow(m_ui->list_disabled->count()-1);
+}
+
void QSSPage::on_removeButton_clicked(){
QListWidgetItem *item = currentSelection();
if(!item){ return; }
diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.h b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.h
index 5b0025c5..07df4ac2 100644
--- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.h
+++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.h
@@ -24,6 +24,7 @@ private slots:
void on_qssListWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *);
void on_list_disabled_currentItemChanged(QListWidgetItem *current, QListWidgetItem *);
void on_createButton_clicked();
+ void on_copyButton_clicked();
void on_editButton_clicked();
void on_removeButton_clicked();
void on_renameButton_clicked();
diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.ui b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.ui
index f9a980f3..def99dd0 100644
--- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.ui
+++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.ui
@@ -63,7 +63,7 @@
<item>
<spacer name="horizontalSpacer_2">
<property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <sizepolicy hsizetype="Fixed" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -168,7 +168,7 @@
<item>
<spacer name="horizontalSpacer_3">
<property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <sizepolicy hsizetype="Fixed" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -222,16 +222,41 @@
<property name="enabled">
<bool>true</bool>
</property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="text">
<string>Create</string>
</property>
</widget>
</item>
<item>
+ <widget class="QToolButton" name="copyButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Copy</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QPushButton" name="editButton">
<property name="enabled">
<bool>false</bool>
</property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="text">
<string>Edit</string>
</property>
@@ -242,6 +267,12 @@
<property name="enabled">
<bool>false</bool>
</property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="text">
<string>Rename</string>
</property>
@@ -252,6 +283,12 @@
<property name="enabled">
<bool>false</bool>
</property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="text">
<string>Remove</string>
</property>
diff --git a/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp b/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp
index 9d220824..79c023dc 100644
--- a/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp
+++ b/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp
@@ -20,7 +20,11 @@
MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){
ui->setupUi(this);
- auto_extract_close = false;
+ delayClose = new QTimer(this);
+ delayClose->setInterval(500);
+ delayClose->setSingleShot(true);
+ connect(delayClose, SIGNAL(timeout()), this, SLOT(close()) );
+
QString title = tr("Archive Manager");
if( getuid()==0){ title.append(" ("+tr("Admin Mode")+")"); }
this->setWindowTitle(title);
@@ -70,33 +74,42 @@ MainUI::~MainUI(){
}
void MainUI::LoadArguments(QStringList args){
- bool burnIMG = false;
- bool autoExtract = false;
- //bool autoArchive = false;
+ int action = -1; // 0: burnIMG, 1: autoExtract, 2: autoArchive
+ QStringList files;
for(int i=0; i<args.length(); i++){
- if(args[i]=="--burn-img"){ burnIMG = true; continue; }
- if(args[i]=="--ax"){ autoExtract = true; continue; }
- //if(args[i]=="--aa"){ autoArchive = true; continue; }
- if(QFile::exists(args[i])){
- ui->label_progress->setText(tr("Opening Archive..."));
- if(autoExtract){
- connect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(autoextractFiles()) );
- connect(BACKEND, SIGNAL(ExtractSuccessful()), this, SLOT(close()) );
- }
- BACKEND->loadFile(args[i]);
- ui->actionUSB_Image->setEnabled(args[i].simplified().endsWith(".img"));
- if(burnIMG){ BurnImgToUSB(); } //Go ahead and launch the burn dialog right away
- break;
+ if(args[i].startsWith("--") ){
+ if(action>=0){ break; }
+ else if(args[i]=="--burn-img"){ action = 0; continue; }
+ else if(args[i]=="--ax"){ action = 1; continue; }
+ else if(args[i]=="--aa"){ action = 2; continue; }
+ else if(args[i]=="--sx"){ action = 3; continue; }
+ }else{
+ files << args[i];
}
- //if(autoArchive){
- //get rest of arguments
- //for(int i=1; i<args.length(); i++){
- // aaFileList << args[i];}
- // now launch autoarchive method with arg list
- // autoArchiveFiles(aaFileList);
- // connect(BACKEND, SIGNAL(ArchivalSuccessful()), this, SLOT(close()) );
- //}
}
+ if(files.isEmpty()){ return; }
+ //Now go through and do any actions as needed
+ ui->label_progress->setText(tr("Opening Archive..."));
+ if(action==1){
+ //qDebug() << "blah";
+ connect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(autoextractFiles()) );
+ connect(BACKEND, SIGNAL(ExtractSuccessful()), delayClose, SLOT(start()) );
+ }else if(action==2){
+ aaFileList.clear();
+ for(int j=1; j<files.length(); j++){ aaFileList << files[j]; }
+ qDebug() << "AA Files:" << aaFileList;
+ connect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(autoArchiveFiles()) );
+ connect(BACKEND, SIGNAL(ArchivalSuccessful()), delayClose, SLOT(start()) );
+ }else if(action==3 && files.length()==2){
+ sxFile = files[0];
+ sxPath = files[1];
+ connect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(simpleExtractFiles()) );
+ connect(BACKEND, SIGNAL(ExtractSuccessful()), delayClose, SLOT(start()) );
+ }
+ BACKEND->loadFile(files[0]);
+ ui->actionUSB_Image->setEnabled(files[0].simplified().endsWith(".img"));
+ if(action==0){ BurnImgToUSB(); } //Go ahead and launch the burn dialog right away
+
}
void MainUI::loadIcons(){
@@ -255,16 +268,35 @@ void MainUI::extractFiles(){
}
void MainUI::autoextractFiles(){
- disconnect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(autoextractFiles()) );
- QString dir = BACKEND->currentFile().section("/",0,-2); //parent directory of the archive
- if(dir.isEmpty()){ return; }
- ui->label_progress->setText(tr("Extracting..."));
- BACKEND->startExtract(dir, true);
+ disconnect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(autoextractFiles()) );
+ QString dir = BACKEND->currentFile().section("/",0,-2); //parent directory of the archive
+ if(dir.isEmpty()){ return; }
+ QDir tmp(dir);
+ QString name = BACKEND->currentFile().section("/",-1).section(".",0,0);
+ if(QFile::exists(dir+"/"+name)){
+ int num = 1;
+ while( QFile::exists(dir+"/"+name+"_"+QString::number(num))){ num++; }
+ name = name+"_"+QString::number(num);
+ }
+ if(tmp.mkdir(name) ){
+ dir.append("/"+name); //created sub directory
}
+ ui->label_progress->setText(tr("Extracting..."));
+ BACKEND->startExtract(dir, true);
+}
-/*
-void MainUI::autoArchiveFiles(aaFileList){
-*/
+void MainUI::simpleExtractFiles(){
+ disconnect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(autoextractFiles()) );
+ QString dir = sxPath;
+ ui->label_progress->setText(tr("Extracting..."));
+ BACKEND->startExtract(dir, true);
+}
+
+void MainUI::autoArchiveFiles(){
+ qDebug() << "Auto Archive Files:" << aaFileList;
+ ui->label_progress->setText(tr("Adding Items..."));
+ BACKEND->startAdd(aaFileList);
+}
void MainUI::extractSelection(){
if(ui->tree_contents->currentItem()==0){ return; } //nothing selected
diff --git a/src-qt5/desktop-utils/lumina-archiver/MainUI.h b/src-qt5/desktop-utils/lumina-archiver/MainUI.h
index a2687895..1a9d287c 100644
--- a/src-qt5/desktop-utils/lumina-archiver/MainUI.h
+++ b/src-qt5/desktop-utils/lumina-archiver/MainUI.h
@@ -10,6 +10,7 @@
#include <QMainWindow>
#include <QString>
#include <QTreeWidgetItem>
+#include <QTimer>
#include "TarBackend.h"
@@ -24,20 +25,21 @@ public:
~MainUI();
void LoadArguments(QStringList);
- void loadIcons();
- //QStringList aaFileList;
+ void loadIcons();
private:
Ui::MainUI *ui;
Backend *BACKEND;
- bool auto_extract_close;
+ QStringList aaFileList, sxList;
+ QString sxPath, sxFile;
+ QTimer *delayClose;
QTreeWidgetItem* findItem(QString path, QTreeWidgetItem *start = 0);
bool cleanItems(QStringList list, QTreeWidgetItem *start = 0); //returns true if anything gets cleaned
//Functions for setting the valid file extensions ("tar" limitations)
QString CreateFileTypes();
- QString OpenFileTypes();
+ QString OpenFileTypes();
private slots:
void NewArchive();
@@ -45,14 +47,15 @@ private slots:
void addFiles();
void addDirs();
void remFiles();
- void extractFiles();
- void autoextractFiles();
- //void autoArchiveFiles(QStringList aaFileList);
+ void extractFiles();
+ void autoextractFiles();
+ void autoArchiveFiles();
+ void simpleExtractFiles();
void extractSelection();
void ViewFile(QTreeWidgetItem *it);
void UpdateTree();
- void BurnImgToUSB();
+ void BurnImgToUSB();
//Backend Handling
void ProcStarting();
diff --git a/src-qt5/desktop-utils/lumina-archiver/TarBackend.cpp b/src-qt5/desktop-utils/lumina-archiver/TarBackend.cpp
index e0b802a4..f110624b 100644
--- a/src-qt5/desktop-utils/lumina-archiver/TarBackend.cpp
+++ b/src-qt5/desktop-utils/lumina-archiver/TarBackend.cpp
@@ -36,7 +36,7 @@ void Backend::loadFile(QString path){
flags.clear();
flags << "-f" << filepath; //add the actual archive path
if(QFile::exists(path)){ startList(); qDebug () << "BACKEND LOAD startList has started";}
- else{ contents.clear(); emit ProcessFinished(true, ""); }
+ else{ contents.clear(); emit FileLoaded(); emit ProcessFinished(true, ""); }
}
bool Backend::canModify(){
@@ -262,8 +262,7 @@ void Backend::procFinished(int retcode, QProcess::ExitStatus){
}
}
if(args.contains("-x")){ result = tr("Extraction Finished"); emit ExtractSuccessful(); }
- //if(args.contains("-aa")){ result = tr("Archival Finished"); emit ArchivalSuccessful(); }
- else if(args.contains("-c")){ result = tr("Modification Finished"); }
+ else if(args.contains("-c")){ result = tr("Modification Finished"); emit ArchivalSuccessful(); }
if(needupdate){ startList(); }
else{ emit ProcessFinished(retcode==0, result); result.clear(); }
}
diff --git a/src-qt5/desktop-utils/lumina-archiver/TarBackend.h b/src-qt5/desktop-utils/lumina-archiver/TarBackend.h
index d86ecf7c..183cb610 100644
--- a/src-qt5/desktop-utils/lumina-archiver/TarBackend.h
+++ b/src-qt5/desktop-utils/lumina-archiver/TarBackend.h
@@ -64,7 +64,7 @@ signals:
void ProcessStarting();
void ProgressUpdate(int, QString); //percentage, text
void ProcessFinished(bool, QString); //success, text
- //void ArchivalSuccessful();
+ void ArchivalSuccessful();
};
#endif
diff --git a/src-qt5/desktop-utils/lumina-archiver/main.cpp b/src-qt5/desktop-utils/lumina-archiver/main.cpp
index 40cd7967..01e7bda1 100644
--- a/src-qt5/desktop-utils/lumina-archiver/main.cpp
+++ b/src-qt5/desktop-utils/lumina-archiver/main.cpp
@@ -15,7 +15,7 @@
int main(int argc, char *argv[]) {
LTHEME::LoadCustomEnvSettings();
QApplication a(argc, argv);
- a.setAttribute(Qt::AA_UseHighDpiPixmaps);
+ a.setAttribute(Qt::AA_UseHighDpiPixmaps);
LUtils::LoadTranslation(&a, "l-archiver");
//Now go ahead and setup the app
QStringList args;
diff --git a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp
index d82f09ce..e64346ae 100644
--- a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp
+++ b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp
@@ -8,21 +8,25 @@
#include "MainUI.h"
#include "ui_MainUI.h"
+#include <QVideoFrame>
#include <QFileDialog>
#include <QMessageBox>
#include <LUtils.h>
#include <LuminaOS.h>
-//LFileInfo INFO = LFileInfo("");
-
-MainUI::MainUI() : QDialog(), ui(new Ui::MainUI){
+MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){
ui->setupUi(this); //load the designer form
canwrite = false;
terminate_thread = false;
+ INFO = new LFileInfo();
UpdateIcons(); //Set all the icons in the dialog
SetupConnections();
- INFO = 0;
+
+ //Disable buttons that are not working yet
+ //ui->actionOpen_File->setVisible(false);
+ //ui->actionOpen_Directory->setVisible(false);
+ //ui->menuSave_As->setEnabled(false);
}
MainUI::~MainUI(){
@@ -38,133 +42,38 @@ void MainUI::LoadFile(QString path, QString type){
//Do the first file information tab
qDebug() << "Load File:" << path << type;
INFO = new LFileInfo(path);
- if(INFO->exists()){ canwrite = INFO->isWritable(); }
- else if(!INFO->filePath().isEmpty()){
- //See if the containing directory can be written
- //QFileInfo chk(INFO->absolutePath());
- canwrite = (INFO->isDir() && INFO->isWritable());
- }else{
- canwrite = true; //no associated file yet
- }
- if(!INFO->exists() && !type.isEmpty()){
- //Set the proper type flag on the shortcut
- if(type=="APP"){ INFO->XDG()->type = XDGDesktop::APP; }
- else if(type=="LINK"){ INFO->XDG()->type = XDGDesktop::LINK; }
- }
//First load the general file information
if(!INFO->filePath().isEmpty()){
- ui->label_file_name->setText( INFO->fileName() );
- ui->label_file_mimetype->setText( INFO->mimetype() );
- if(!INFO->isDir()){ ui->label_file_size->setText( LUtils::BytesToDisplaySize( INFO->size() ) ); }
- else {
- ui->label_file_size->setText(tr("---Calculating---"));
- QtConcurrent::run(this, &MainUI::GetDirSize, INFO->absoluteFilePath());
- }
- ui->label_file_owner->setText(INFO->owner());
- ui->label_file_group->setText(INFO->group());
- ui->label_file_created->setText( INFO->created().toString(Qt::SystemLocaleLongDate) );
- ui->label_file_modified->setText( INFO->lastModified().toString(Qt::SystemLocaleLongDate) );
- //Get the file permissions
- QString perms;
- if(INFO->isReadable() && INFO->isWritable()){ perms = tr("Read/Write"); }
- else if(INFO->isReadable()){ perms = tr("Read Only"); }
- else if(INFO->isWritable()){ perms = tr("Write Only"); }
- else{ perms = tr("No Access"); }
- ui->label_file_perms->setText(perms);
- //Now the special "type" for the file
- QString ftype;
- if(INFO->suffix().toLower()=="desktop"){ ftype = tr("XDG Shortcut"); }
- else if(INFO->isDir()){ ftype = tr("Directory"); }
- else if(INFO->isExecutable()){ ftype = tr("Binary"); }
- else{ ftype = INFO->suffix().toUpper(); }
- if(INFO->isHidden()){ ftype = QString(tr("Hidden %1")).arg(type); }
- ui->label_file_type->setText(ftype);
- //Now load the icon for the file
- if(INFO->isImage()){
- //qDebug() << "Set Image:";
- QPixmap pix(INFO->absoluteFilePath());
- ui->label_file_icon->setPixmap( pix.scaledToHeight(64) );
- ui->label_file_size->setText( ui->label_file_size->text()+" ("+QString::number(pix.width())+" x "+QString::number(pix.height())+" px)" );
- //qDebug() << " - done with image";
- }else{
- ui->label_file_icon->setPixmap( LXDG::findIcon( INFO->iconfile(), "unknown").pixmap(QSize(64,64)) );
- }
- //Now verify the tab is available in the widget
- //qDebug() << "Check tab widget";
- if(ui->tabWidget->indexOf(ui->tab_file)<0){
- //qDebug() << "Add File Info Tab";
- ui->tabWidget->addTab(ui->tab_file, tr("File Information"));
- }
- //qDebug() << "Done with Tab Check";
+ SyncFileInfo();
}else{
- if(ui->tabWidget->indexOf(ui->tab_file)>=0){
- ui->tabWidget->removeTab( ui->tabWidget->indexOf(ui->tab_file) );
- }
+ SetupNewFile();
}
- //Now load the special XDG desktop info
- qDebug() << "Check XDG Info:" << type;
- //qDebug() << INFO->isDesktopFile() << type;
- if(INFO->isDesktopFile() || !type.isEmpty()){
-
- if(INFO->XDG()->type == XDGDesktop::APP){
- ui->line_xdg_command->setText(INFO->XDG()->exec);
- ui->line_xdg_wdir->setText(INFO->XDG()->path);
- ui->check_xdg_useTerminal->setChecked( INFO->XDG()->useTerminal );
- ui->check_xdg_startupNotify->setChecked( INFO->XDG()->startupNotify );
- }else if(INFO->XDG()->type==XDGDesktop::LINK){
- //Hide the options that are unavailable for links
- //Command line (exec)
- ui->line_xdg_command->setVisible(false);
- ui->tool_xdg_getCommand->setVisible(false);
- ui->lblCommand->setVisible(false);
- //Options
- ui->lblOptions->setVisible(false);
- ui->check_xdg_useTerminal->setVisible(false);
- ui->check_xdg_startupNotify->setVisible(false);
- //Now load the variables for this type of shortcut
- ui->lblWorkingDir->setText(tr("URL:"));
- ui->line_xdg_wdir->setText( INFO->XDG()->url );
- ui->tool_xdg_getDir->setVisible(false); //the dir selection button
-
- }
- ui->line_xdg_name->setText(INFO->XDG()->name);
- ui->line_xdg_comment->setText(INFO->XDG()->comment);
- ui->push_xdg_getIcon->setWhatsThis( INFO->XDG()->icon );
- ReloadAppIcon();
- ui->push_save->setVisible(true);
- ui->push_save->setEnabled(false);
- //Now ensure the xdg tab exists in the widget
- if(ui->tabWidget->indexOf(ui->tab_deskedit)<0){
- qDebug() << "Adding the deskedit tab";
- ui->tabWidget->addTab(ui->tab_deskedit, tr("Edit Shortcut"));
- }
- }else{
- xdgvaluechanged(); //just do the disables here
- //Also remove the xdg tab
- if(ui->tabWidget->indexOf(ui->tab_deskedit) >= 0){
- qDebug() << "Removing the deskedit tab";
- ui->tabWidget->removeTab( ui->tabWidget->indexOf(ui->tab_deskedit) );
- }
- }
- //Setup the tab
- if(type.isEmpty()){ ui->tabWidget->setCurrentIndex(0); }
- else if(ui->tabWidget->count()>1){ ui->tabWidget->setCurrentIndex(1); }
- qDebug() << "Done Loading File";
}
void MainUI::UpdateIcons(){
- this->setWindowIcon(LXDG::findIcon("document-preview","unknown"));
- ui->push_close->setIcon( LXDG::findIcon("dialog-close","") );
- ui->push_save->setIcon( LXDG::findIcon("document-save","") );
- ui->tool_xdg_getCommand->setIcon( LXDG::findIcon("edit-find-page","") );
- ui->tool_xdg_getDir->setIcon( LXDG::findIcon("document-open","") );
+
}
//==============
// PRIVATE
//==============
void MainUI::ReloadAppIcon(){
- ui->push_xdg_getIcon->setIcon( LXDG::findIcon(ui->push_xdg_getIcon->whatsThis(),"") );
+ //qDebug() << "Reload App Icon:";
+ ui->label_xdg_icon->setPixmap( LXDG::findIcon(ui->line_xdg_icon->text(),"").pixmap(64,64) );
+ //qDebug() << "Check Desktop File entry";
+ if(INFO->iconfile()!=ui->line_xdg_icon->text()){
+ xdgvaluechanged();
+ }
+ //qDebug() << "Done with app icon";
+}
+
+void MainUI::stopDirSize(){
+ if(sizeThread.isRunning()){
+ terminate_thread = true;
+ sizeThread.waitForFinished();
+ QApplication::processEvents(); //throw away any last signals waiting to be processed
+ }
+ terminate_thread = false;
}
void MainUI::GetDirSize(const QString dirname) const {
@@ -215,10 +124,201 @@ void MainUI::GetDirSize(const QString dirname) const {
emit folder_size_changed(filesize, file_number, dir_number, true);
}
+void MainUI::SyncFileInfo(){
+ qDebug() << "Sync File Info";
+ stopDirSize();
+ if(INFO->filePath().isEmpty()){ return; }
+ if(INFO->exists()){ canwrite = INFO->isWritable(); }
+ else{
+ //See if the containing directory can be written
+ QFileInfo chk(INFO->absolutePath());
+ canwrite = (chk.isDir() && chk.isWritable());
+ }
+ ui->label_file_name->setText( INFO->fileName() );
+ ui->label_file_mimetype->setText( INFO->mimetype() );
+ if(!INFO->isDir()){ ui->label_file_size->setText( LUtils::BytesToDisplaySize( INFO->size() ) ); }
+ else {
+ ui->label_file_size->setText(tr("---Calculating---"));
+ sizeThread = QtConcurrent::run(this, &MainUI::GetDirSize, INFO->absoluteFilePath());
+ }
+ ui->label_file_owner->setText(INFO->owner());
+ ui->label_file_group->setText(INFO->group());
+ ui->label_file_created->setText( INFO->created().toString(Qt::SystemLocaleLongDate) );
+ ui->label_file_modified->setText( INFO->lastModified().toString(Qt::SystemLocaleLongDate) );
+ //Get the file permissions
+ QString perms;
+ if(INFO->isReadable() && INFO->isWritable()){ perms = tr("Read/Write"); }
+ else if(INFO->isReadable()){ perms = tr("Read Only"); }
+ else if(INFO->isWritable()){ perms = tr("Write Only"); }
+ else{ perms = tr("No Access"); }
+ ui->label_file_perms->setText(perms);
+ //Now the special "type" for the file
+ QString ftype;
+ if(INFO->suffix().toLower()=="desktop"){ ftype = tr("XDG Shortcut"); }
+ else if(INFO->isDir()){ ftype = tr("Directory"); }
+ else if(INFO->isExecutable()){ ftype = tr("Binary"); }
+ else{ ftype = INFO->suffix().toUpper(); }
+ if(INFO->isHidden()){ ftype = QString(tr("Hidden %1")).arg(ftype); }
+ ui->label_file_type->setText(ftype);
+
+ //Now load the icon for the file
+ if(INFO->isImage()){
+ QPixmap pix(INFO->absoluteFilePath());
+ ui->label_file_icon->setPixmap(pix.scaledToHeight(64));
+ ui->label_file_size->setText( ui->label_file_size->text()+" ("+QString::number(pix.width())+" x "+QString::number(pix.height())+" px)" );
+ }else if(INFO->isVideo()){
+ ui->label_file_icon->hide();
+ LVideoLabel *mediaLabel = new LVideoLabel(INFO->absoluteFilePath(), true, ui->tab_file);
+ mediaLabel->setFixedSize(64,64);
+ ui->formLayout->replaceWidget(ui->label_file_icon, mediaLabel);
+ }else{
+ ui->label_file_icon->setPixmap( LXDG::findIcon( INFO->iconfile(), "unknown").pixmap(QSize(64,64)) );
+ }
+
+ //qDebug() << "Check XDG Info:"
+ //qDebug() << INFO->isDesktopFile() << type;
+ syncXdgStruct(INFO->XDG());
+ //Make sure the right tabs are available
+ if(ui->tabWidget->indexOf(ui->tab_file)<0){
+ //qDebug() << "Add File Info Tab";
+ ui->tabWidget->insertTab(0, ui->tab_file, tr("File Information"));
+ }
+ if(!INFO->isDesktopFile()){
+ if(ui->tabWidget->indexOf(ui->tab_deskedit)>=0){
+ ui->tabWidget->removeTab( ui->tabWidget->indexOf(ui->tab_deskedit) );
+ }
+ }else if(ui->tabWidget->indexOf(ui->tab_deskedit)<0){
+ ui->tabWidget->addTab( ui->tab_deskedit, tr("XDG Shortcut") );
+ }
+ ui->tabWidget->setCurrentIndex(ui->tabWidget->indexOf(ui->tab_file) );
+}
+
+void MainUI::SetupNewFile(){
+ //qDebug() << "Setup New File";
+ if(!INFO->filePath().isEmpty()){
+ INFO = new LFileInfo();
+ }
+ stopDirSize();
+ canwrite = true; //can always write a new file
+ syncXdgStruct(INFO->XDG());
+ //Make sure the right tabs are enabled
+ if(ui->tabWidget->indexOf(ui->tab_file)>=0){
+ ui->tabWidget->removeTab( ui->tabWidget->indexOf(ui->tab_file) );
+ }
+ if(ui->tabWidget->indexOf(ui->tab_deskedit)<0){
+ //qDebug() << "Adding the deskedit tab";
+ ui->tabWidget->addTab(ui->tab_deskedit, tr("XDG Shortcut"));
+ }
+ ui->tabWidget->setCurrentIndex(ui->tabWidget->indexOf(ui->tab_deskedit) );
+}
+
+void MainUI::syncXdgStruct(XDGDesktop *XDG){
+ bool cleanup = false;
+ if(XDG==0){ XDG = new XDGDesktop(); cleanup = true;} //make sure nothing crashes
+ if(XDG->type == XDGDesktop::APP){
+ ui->line_xdg_command->setText(XDG->exec);
+ ui->line_xdg_wdir->setText(XDG->path);
+ ui->check_xdg_useTerminal->setChecked( XDG->useTerminal );
+ ui->check_xdg_startupNotify->setChecked( XDG->startupNotify );
+ }else if(XDG->type==XDGDesktop::LINK){
+ //Hide the options that are unavailable for links
+ //Command line (exec)
+ ui->line_xdg_command->setVisible(false);
+ ui->tool_xdg_getCommand->setVisible(false);
+ ui->lblCommand->setVisible(false);
+ //Options
+ ui->lblOptions->setVisible(false);
+ ui->check_xdg_useTerminal->setVisible(false);
+ ui->check_xdg_startupNotify->setVisible(false);
+ //Now load the variables for this type of shortcut
+ ui->lblWorkingDir->setText(tr("URL:"));
+ ui->line_xdg_wdir->setText( XDG->url );
+ ui->tool_xdg_getDir->setVisible(false); //the dir selection button
+ }
+ ui->line_xdg_name->setText(XDG->name);
+ ui->line_xdg_comment->setText(XDG->comment);
+ ui->line_xdg_icon->setText( XDG->icon );
+ ReloadAppIcon();
+ ui->actionSave_Shortcut->setVisible(true);
+ ui->actionSave_Shortcut->setEnabled(false);
+ if(cleanup){ delete XDG; }
+ checkXDGValidity();
+}
+
+bool MainUI::saveFile(QString path){
+ //qDebug() << "Request save file:" << path;
+ XDGDesktop *XDG = INFO->XDG();
+ if(XDG==0){ XDG = new XDGDesktop(); }
+ if(XDG->type == XDGDesktop::BAD){ XDG->type = XDGDesktop::APP; }
+ //Update the file path in the data structure
+ XDG->filePath = path;
+ //Now change the structure
+ XDG->name = ui->line_xdg_name->text();
+ XDG->genericName = ui->line_xdg_name->text().toLower();
+ XDG->comment = ui->line_xdg_comment->text();
+ XDG->icon = ui->line_xdg_icon->text();
+ //Now do the type-specific fields
+ if(XDG->type == XDGDesktop::APP){
+ XDG->exec = ui->line_xdg_command->text();
+ XDG->tryexec = ui->line_xdg_command->text().section(" ",0,0); //use the first word/binary for the existance check
+ XDG->path = ui->line_xdg_wdir->text(); //working dir/path
+ XDG->useTerminal = ui->check_xdg_useTerminal->isChecked();
+ XDG->startupNotify = ui->check_xdg_startupNotify->isChecked();
+ }else if(XDG->type==XDGDesktop::LINK){
+ XDG->url = ui->line_xdg_wdir->text(); //we re-used this field
+ }
+ //Clear any info which this utility does not support at the moment
+ XDG->actionList.clear();
+ XDG->actions.clear();
+ //Now save the structure to file
+ //qDebug() << "Saving File:" << XDG->filePath;
+ return XDG->saveDesktopFile(true); //Try to merge the file/structure as necessary
+}
+
+QString MainUI::findOpenDirFile(bool isdir){
+ static QList<QUrl> urls;
+ if(urls.isEmpty()){
+ urls << QUrl::fromLocalFile("/");
+ QStringList dirs = QString(getenv("XDG_DATA_DIRS")).split(":");
+ for(int i=0; i<dirs.length(); i++){
+ if(QFile::exists(dirs[i]+"/applications")){ urls << QUrl::fromLocalFile(dirs[i]+"/applications"); }
+ }
+ //Now do the home-directory folders
+ urls << QUrl::fromLocalFile(QDir::homePath());
+ QString localapps = QString(getenv("XDG_DATA_HOME"))+"/applications";
+ if(QFile::exists(localapps)){ urls << QUrl::fromLocalFile(localapps); }
+ }
+ static QString lastdir = QDir::homePath();
+ QFileDialog dlg(this);
+ dlg.setAcceptMode(QFileDialog::AcceptOpen);
+ dlg.setFileMode( isdir ? QFileDialog::Directory : QFileDialog::ExistingFiles );
+ dlg.setOptions(QFileDialog::ReadOnly | QFileDialog::HideNameFilterDetails);
+ dlg.setViewMode(QFileDialog::Detail);
+ dlg.setSidebarUrls( urls );
+ dlg.setDirectory(lastdir);
+ if(!dlg.exec() ){ return ""; } //cancelled
+ if(dlg.selectedFiles().isEmpty()){ return ""; }
+ QString path = dlg.selectedFiles().first();
+ //Update the last used directory
+ if(isdir){ lastdir = path; } //save this for next time
+ else{ lastdir = path.section("/",0,-2); }
+ //return the path
+ return path;
+}
+
+
// Initialization procedures
void MainUI::SetupConnections(){
+ connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(closeApplication()) );
+ connect(ui->actionSave_Shortcut, SIGNAL(triggered()), this, SLOT(save_clicked()) );
+ connect(ui->actionLocal_Shortcut, SIGNAL(triggered()), this, SLOT(save_as_local_clicked()) );
+ connect(ui->actionRegister_Shortcut, SIGNAL(triggered()), this, SLOT(save_as_register_clicked()) );
+ connect(ui->actionNew_Shortcut, SIGNAL(triggered()), this, SLOT(SetupNewFile()) );
+ connect(ui->actionOpen_File, SIGNAL(triggered()), this, SLOT(open_file_clicked()) );
+ connect(ui->actionOpen_Directory, SIGNAL(triggered()), this, SLOT(open_dir_clicked()) );
connect(ui->line_xdg_command, SIGNAL(editingFinished()), this, SLOT(xdgvaluechanged()) );
connect(ui->line_xdg_comment, SIGNAL(editingFinished()), this, SLOT(xdgvaluechanged()) );
+ connect(ui->line_xdg_icon, SIGNAL(textChanged(QString)), this, SLOT(ReloadAppIcon()) );
connect(ui->tool_xdg_getCommand, SIGNAL(clicked()), this, SLOT(getXdgCommand()) );
connect(ui->line_xdg_name, SIGNAL(editingFinished()), this, SLOT(xdgvaluechanged()) );
connect(ui->line_xdg_wdir, SIGNAL(editingFinished()), this, SLOT(xdgvaluechanged()) );
@@ -228,58 +328,81 @@ void MainUI::SetupConnections(){
}
//UI Buttons
-void MainUI::on_push_close_clicked(){
+void MainUI::closeApplication(){
terminate_thread = true;
- if(ui->push_save->isEnabled()){
+ if(ui->actionSave_Shortcut->isEnabled()){
//Still have unsaved changes
//TO-DO - prompt for whether to save the changes
}
this->close();
}
-void MainUI::on_push_save_clicked(){
+void MainUI::save_clicked(){
//Save all the xdg values into the structure
- if( (!INFO->isDesktopFile() && !INFO->filePath().isEmpty()) || !canwrite){ return; }
- if(INFO->filePath().isEmpty()){
+ QString filePath = INFO->filePath();
+ if( !filePath.isEmpty() && !INFO->isDesktopFile() ){ return; }
+ if(filePath.isEmpty() || !canwrite){
//Need to prompt for where to save the file and what to call it
QString appdir = QString(getenv("XDG_DATA_HOME"))+"/applications/";
if(!QFile::exists(appdir)){ QDir dir; dir.mkpath(appdir); }
- QString filePath = QFileDialog::getSaveFileName(this, tr("Save Application File"), appdir, tr("Application Registrations (*.desktop)") );
+ filePath = QFileDialog::getSaveFileName(this, tr("Save Application File"), appdir, tr("XDG Shortcuts (*.desktop)") );
if(filePath.isEmpty()){ return; }
if(!filePath.endsWith(".desktop")){ filePath.append(".desktop"); }
- //Update the file paths in the data structure
- INFO->setFile(filePath);
- INFO->XDG()->filePath = filePath;
}
- XDGDesktop *XDG = INFO->XDG();
- //Now change the structure
- XDG->name = ui->line_xdg_name->text();
- XDG->genericName = ui->line_xdg_name->text().toLower();
- XDG->comment = ui->line_xdg_comment->text();
- XDG->icon = ui->push_xdg_getIcon->whatsThis();
- //Now do the type-specific fields
- if(XDG->type == XDGDesktop::APP){
- XDG->exec = ui->line_xdg_command->text();
- XDG->tryexec = ui->line_xdg_command->text().section(" ",0,0); //use the first word/binary for the existance check
- XDG->path = ui->line_xdg_wdir->text(); //working dir/path
- XDG->useTerminal = ui->check_xdg_useTerminal->isChecked();
- XDG->startupNotify = ui->check_xdg_startupNotify->isChecked();
- }else if(XDG->type==XDGDesktop::LINK){
- XDG->url = ui->line_xdg_wdir->text(); //we re-used this field
+ //qDebug() << " -Try Saving File:" << filePath;
+ bool saved = saveFile(filePath);
+ //qDebug() << "File Saved:" << saved;
+ ui->actionSave_Shortcut->setEnabled( !saved );
+ if(saved){
+ //Re-load the file info
+ LoadFile(filePath);
}
- //Clear any info which this utility does not support at the moment
- XDG->actionList.clear();
- XDG->actions.clear();
- //Now save the structure to file
- bool saved = XDG->saveDesktopFile(true); //Try to merge the file/structure as necessary
- qDebug() << "File Saved:" << saved;
- ui->push_save->setEnabled( !saved );
+}
+
+void MainUI::save_as_local_clicked(){
+ QString filePath = QFileDialog::getSaveFileName(this, tr("Save Application File"), QDir::homePath(), tr("XDG Shortcuts (*.desktop)") );
+ if(filePath.isEmpty()){ return; }
+ if(!filePath.endsWith(".desktop")){ filePath.append(".desktop"); }
+
+ //qDebug() << " -Try Saving File:" << filePath;
+ bool saved = saveFile(filePath);
+ //qDebug() << "File Saved:" << saved;
+ ui->actionSave_Shortcut->setEnabled( !saved );
if(saved){
//Re-load the file info
- LoadFile(INFO->absoluteFilePath());
+ LoadFile(filePath);
}
}
+void MainUI::save_as_register_clicked(){
+ QString appdir = QString(getenv("XDG_DATA_HOME"))+"/applications/";
+ if(!QFile::exists(appdir)){ QDir dir; dir.mkpath(appdir); }
+ QString filePath = QFileDialog::getSaveFileName(this, tr("Save Application File"), appdir, tr("XDG Shortcuts (*.desktop)") );
+ if(filePath.isEmpty()){ return; }
+ if(!filePath.endsWith(".desktop")){ filePath.append(".desktop"); }
+
+ //qDebug() << " -Try Saving File:" << filePath;
+ bool saved = saveFile(filePath);
+ //qDebug() << "File Saved:" << saved;
+ ui->actionSave_Shortcut->setEnabled( !saved );
+ if(saved){
+ //Re-load the file info
+ LoadFile(filePath);
+ }
+}
+
+void MainUI::open_dir_clicked(){
+ QString path = findOpenDirFile(true); //directory only
+ if(path.isEmpty()){ return; }
+ LoadFile(path, "");
+}
+
+void MainUI::open_file_clicked(){
+ QString path = findOpenDirFile(false); //files only
+ if(path.isEmpty()){ return; }
+ LoadFile(path, "");
+}
+
void MainUI::getXdgCommand(QString prev){
//Find a binary to run
QString dir = prev; //start with the previous attempt (if there was one)
@@ -315,22 +438,45 @@ void MainUI::on_push_xdg_getIcon_clicked(){
for(int i=0; i<ext.length(); i++){ ext[i].prepend("*."); } //turn them into valid filters
QString file = QFileDialog::getOpenFileName(this, tr("Select an icon"), dir ,QString(tr("Images (%1);; All Files (*)")).arg(ext.join(" ")) );
if(file.isEmpty()){ return; } //cancelled
- ui->push_xdg_getIcon->setWhatsThis(file);
+ ui->line_xdg_icon->setText(file);
ReloadAppIcon();
xdgvaluechanged();
}
//XDG Value Changed
+bool MainUI::checkXDGValidity(){
+ XDGDesktop tmp;
+ tmp.type = XDGDesktop::APP; //make this adjustable later (GUI radio buttons?)
+ tmp.name = ui->line_xdg_name->text();
+ tmp.genericName = ui->line_xdg_name->text().toLower();
+ tmp.comment = ui->line_xdg_comment->text();
+ tmp.icon = ui->line_xdg_icon->text();
+ //Now do the type-specific fields
+ if(tmp.type == XDGDesktop::APP){
+ tmp.exec = ui->line_xdg_command->text();
+ tmp.tryexec = ui->line_xdg_command->text().section(" ",0,0); //use the first word/binary for the existance check
+ tmp.path = ui->line_xdg_wdir->text(); //working dir/path
+ tmp.useTerminal = ui->check_xdg_useTerminal->isChecked();
+ tmp.startupNotify = ui->check_xdg_startupNotify->isChecked();
+ }else if(tmp.type==XDGDesktop::LINK){
+ tmp.url = ui->line_xdg_wdir->text(); //we re-used this field
+ }
+ bool valid = tmp.isValid();
+ ui->label_xdg_statusicon->setPixmap( LXDG::findIcon( valid ? "dialog-ok" : "dialog-cancel", "").pixmap(32,32) );
+ ui->label_xdg_status->setText( valid ? tr("Valid Settings") : tr("Invalid Settings") );
+ return tmp.isValid();
+}
+
void MainUI::xdgvaluechanged(){
- if(INFO!=0 && (INFO->isDesktopFile() || INFO->filePath().isEmpty() ) ){
- ui->push_save->setVisible(true);
+ //qDebug() << "xdgvaluechanged";
+ if( INFO->isDesktopFile() || INFO->filePath().isEmpty() ){
+ bool valid = checkXDGValidity();
//Compare the current UI values to the file values
- ui->push_save->setEnabled(canwrite); //assume changed at this point
- // TO-DO
+ ui->menuSave_As->setEnabled(valid);
+ ui->actionSave_Shortcut->setEnabled(canwrite && valid); //assume changed at this point
}else{
- ui->push_save->setVisible(false);
- ui->push_save->setEnabled(false);
+ ui->actionSave_Shortcut->setEnabled(false);
}
}
diff --git a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h
index cbe23d9e..d7b17207 100644
--- a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h
+++ b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h
@@ -13,15 +13,20 @@
#ifndef _LUMINA_FILE_INFO_MAIN_UI_H
#define _LUMINA_FILE_INFO_MAIN_UI_H
-#include <QDialog>
+#include <QMainWindow>
+#include <QMediaPlayer>
+#include <LVideoSurface.h>
+#include <LVideoLabel.h>
+#include <QElapsedTimer>
+#include <QFuture>
#include <LuminaXDG.h>
namespace Ui{
- class MainUI;
+ class MainUI;
};
-class MainUI : public QDialog{
+class MainUI : public QMainWindow{
Q_OBJECT
public:
MainUI();
@@ -31,36 +36,55 @@ public:
public slots:
void UpdateIcons();
+ void ReloadAppIcon();
private:
Ui::MainUI *ui;
LFileInfo *INFO;
+ LVideoSurface *surface;
+ QMediaPlayer *player;
+ bool flag;
+ QElapsedTimer timer;
+ QFuture<void> sizeThread;
bool canwrite;
bool terminate_thread; //flag for terminating the GetDirSize task
- void ReloadAppIcon();
+ void stopDirSize();
+
void GetDirSize(const QString dirname) const; //function to get folder size
+ void SyncFileInfo();
+
+ void syncXdgStruct(XDGDesktop*);
+
+ bool saveFile(QString path);
+ QString findOpenDirFile(bool isdir = false);
+
signals:
void folder_size_changed(quint64 size, quint64 files, quint64 folders, bool finished) const; //Signal for updating the folder size asynchronously
private slots:
+ void SetupNewFile();
//Initialization functions
void SetupConnections();
//UI Buttons
- void on_push_close_clicked();
- void on_push_save_clicked();
+ void closeApplication();
+ void save_clicked();
+ void save_as_local_clicked();
+ void save_as_register_clicked();
+ void open_dir_clicked();
+ void open_file_clicked();
void getXdgCommand(QString prev = "");
- //void on_tool_xdg_getCommand_clicked(QString prev = "");
void on_tool_xdg_getDir_clicked();
void on_push_xdg_getIcon_clicked();
//XDG Value Changed
+ bool checkXDGValidity();
void xdgvaluechanged();
- //Folder size
- void refresh_folder_size(quint64 size, quint64 files, quint64 folders, bool finished); //Slot for updating the folder size asynchronously
+ //Folder size
+ void refresh_folder_size(quint64 size, quint64 files, quint64 folders, bool finished); //Slot for updating the folder size asynchronously
};
#endif
diff --git a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.ui b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.ui
index 51657ba1..217c1a10 100644
--- a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.ui
+++ b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.ui
@@ -1,432 +1,652 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainUI</class>
- <widget class="QDialog" name="MainUI">
+ <widget class="QMainWindow" name="MainUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>349</width>
- <height>354</height>
+ <width>800</width>
+ <height>658</height>
</rect>
</property>
<property name="windowTitle">
<string>File Information</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QTabWidget" name="tabWidget">
- <property name="currentIndex">
- <number>1</number>
- </property>
- <widget class="QWidget" name="tab_file">
- <attribute name="title">
- <string>File Information</string>
- </attribute>
- <layout class="QFormLayout" name="formLayout">
- <property name="labelAlignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="label_file_icon">
- <property name="text">
- <string notr="true">icon</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- <item row="4" column="0" colspan="2">
- <widget class="Line" name="line_2">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item row="5" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Owner:</string>
- </property>
- </widget>
- </item>
- <item row="5" column="1">
- <widget class="QLabel" name="label_file_owner">
- <property name="text">
- <string notr="true"/>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="6" column="0">
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>Group:</string>
- </property>
- </widget>
- </item>
- <item row="6" column="1">
- <widget class="QLabel" name="label_file_group">
- <property name="text">
- <string notr="true"/>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="7" column="0">
- <widget class="QLabel" name="label_11">
- <property name="text">
- <string>Permissions:</string>
- </property>
- </widget>
- </item>
- <item row="10" column="0" colspan="2">
- <widget class="Line" name="line_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item row="11" column="0">
- <widget class="QLabel" name="label_7">
- <property name="text">
- <string>Created:</string>
- </property>
- </widget>
- </item>
- <item row="11" column="1">
- <widget class="QLabel" name="label_file_created">
- <property name="toolTip">
- <string>Note: The time a file was created might be more recent than the time modified if the file permissions were changed recently.</string>
- </property>
- <property name="text">
- <string notr="true"/>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="12" column="0">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Last Modified:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>Type:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_6">
- <property name="text">
- <string>MimeType:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLabel" name="label_file_mimetype">
- <property name="text">
- <string notr="true"/>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLabel" name="label_file_type">
- <property name="text">
- <string notr="true"/>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="7" column="1">
- <widget class="QLabel" name="label_file_perms">
- <property name="text">
- <string notr="true"/>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="12" column="1">
- <widget class="QLabel" name="label_file_modified">
- <property name="text">
- <string notr="true"/>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>File Size:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QLabel" name="label_file_size">
- <property name="text">
- <string notr="true"/>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="label_file_name">
- <property name="text">
- <string notr="true"/>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_deskedit">
- <attribute name="title">
- <string>Edit Shortcut</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <property name="spacing">
- <number>2</number>
- </property>
- <property name="leftMargin">
- <number>4</number>
- </property>
- <property name="topMargin">
- <number>4</number>
- </property>
- <property name="rightMargin">
- <number>4</number>
- </property>
- <property name="bottomMargin">
- <number>4</number>
- </property>
- <item>
- <layout class="QGridLayout" name="gridLayout">
- <item row="3" column="0" alignment="Qt::AlignRight">
- <widget class="QLabel" name="lblWorkingDir">
- <property name="text">
- <string>Working Dir:</string>
- </property>
- </widget>
- </item>
- <item row="5" column="1">
- <widget class="QCheckBox" name="check_xdg_startupNotify">
- <property name="text">
- <string>Use startup notification</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QLineEdit" name="line_xdg_wdir">
- <property name="enabled">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="4" column="0" alignment="Qt::AlignRight">
- <widget class="QLabel" name="lblIcon">
- <property name="text">
- <string>Icon:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0" alignment="Qt::AlignRight">
- <widget class="QLabel" name="lblCommand">
- <property name="text">
- <string>Command:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" alignment="Qt::AlignRight">
- <widget class="QLabel" name="lblComment">
- <property name="text">
- <string>Comment:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLineEdit" name="line_xdg_command"/>
- </item>
- <item row="6" column="1">
- <widget class="QCheckBox" name="check_xdg_useTerminal">
- <property name="text">
- <string>Run in terminal</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0" alignment="Qt::AlignRight">
- <widget class="QLabel" name="lblName">
- <property name="text">
- <string>Name:</string>
- </property>
- </widget>
- </item>
- <item row="5" column="0" alignment="Qt::AlignRight">
- <widget class="QLabel" name="lblOptions">
- <property name="text">
- <string>Options</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" colspan="2">
- <widget class="QLineEdit" name="line_xdg_name"/>
- </item>
- <item row="1" column="1" colspan="2">
- <widget class="QLineEdit" name="line_xdg_comment"/>
- </item>
- <item row="2" column="2">
- <widget class="QToolButton" name="tool_xdg_getCommand">
- <property name="text">
- <string notr="true"/>
- </property>
- </widget>
- </item>
- <item row="3" column="2">
- <widget class="QToolButton" name="tool_xdg_getDir">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="text">
- <string notr="true"/>
- </property>
- </widget>
- </item>
- <item row="4" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QToolButton" name="push_xdg_getIcon">
- <property name="maximumSize">
- <size>
- <width>275</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>No Icon</string>
- </property>
- <property name="iconSize">
- <size>
- <width>64</width>
- <height>64</height>
- </size>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </item>
- <item>
- <widget class="Line" name="line">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QToolButton" name="push_save">
- <property name="text">
- <string>Save</string>
- </property>
- <property name="popupMode">
- <enum>QToolButton::InstantPopup</enum>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextBesideIcon</enum>
- </property>
+ <property name="windowIcon">
+ <iconset theme="document-search">
+ <normaloff>.</normaloff>.</iconset>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
+ <widget class="QWidget" name="tab_file">
+ <attribute name="title">
+ <string>File Information</string>
+ </attribute>
+ <layout class="QFormLayout" name="formLayout">
+ <property name="labelAlignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_file_icon">
+ <property name="text">
+ <string notr="true">icon</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="2">
+ <widget class="Line" name="line_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Owner:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QLabel" name="label_file_owner">
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Group:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QLabel" name="label_file_group">
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_11">
+ <property name="text">
+ <string>Permissions:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="0" colspan="2">
+ <widget class="Line" name="line_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>Created:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="1">
+ <widget class="QLabel" name="label_file_created">
+ <property name="toolTip">
+ <string>Note: The time a file was created might be more recent than the time modified if the file permissions were changed recently.</string>
+ </property>
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="12" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Last Modified:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Type:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>MimeType:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="label_file_mimetype">
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="label_file_type">
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="1">
+ <widget class="QLabel" name="label_file_perms">
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="12" column="1">
+ <widget class="QLabel" name="label_file_modified">
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>File Size:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="label_file_size">
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="label_file_name">
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
- </item>
- <item>
- <widget class="QToolButton" name="push_close">
- <property name="text">
- <string>Close</string>
- </property>
- <property name="popupMode">
- <enum>QToolButton::DelayedPopup</enum>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextBesideIcon</enum>
- </property>
+ <widget class="QWidget" name="tab_deskedit">
+ <attribute name="title">
+ <string>XDG Shortcut</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="spacing">
+ <number>2</number>
+ </property>
+ <property name="leftMargin">
+ <number>4</number>
+ </property>
+ <property name="topMargin">
+ <number>4</number>
+ </property>
+ <property name="rightMargin">
+ <number>4</number>
+ </property>
+ <property name="bottomMargin">
+ <number>4</number>
+ </property>
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="3" column="0" alignment="Qt::AlignRight">
+ <widget class="QLabel" name="lblWorkingDir">
+ <property name="text">
+ <string>Working Dir:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QCheckBox" name="check_xdg_startupNotify">
+ <property name="text">
+ <string>Use startup notification</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="line_xdg_wdir">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" alignment="Qt::AlignRight">
+ <widget class="QLabel" name="lblIcon">
+ <property name="text">
+ <string>Icon:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" alignment="Qt::AlignRight">
+ <widget class="QLabel" name="lblCommand">
+ <property name="text">
+ <string>Command:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" alignment="Qt::AlignRight">
+ <widget class="QLabel" name="lblComment">
+ <property name="text">
+ <string>Comment:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="line_xdg_command"/>
+ </item>
+ <item row="6" column="1">
+ <widget class="QCheckBox" name="check_xdg_useTerminal">
+ <property name="text">
+ <string>Run in terminal</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" alignment="Qt::AlignRight">
+ <widget class="QLabel" name="lblName">
+ <property name="text">
+ <string>Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" alignment="Qt::AlignRight">
+ <widget class="QLabel" name="lblOptions">
+ <property name="text">
+ <string>Options</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2">
+ <widget class="QLineEdit" name="line_xdg_name"/>
+ </item>
+ <item row="1" column="1" colspan="2">
+ <widget class="QLineEdit" name="line_xdg_comment"/>
+ </item>
+ <item row="2" column="2">
+ <widget class="QToolButton" name="tool_xdg_getCommand">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>42</height>
+ </size>
+ </property>
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="icon">
+ <iconset theme="edit-find">
+ <normaloff>.</normaloff>.</iconset>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QToolButton" name="tool_xdg_getDir">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>42</height>
+ </size>
+ </property>
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="icon">
+ <iconset theme="edit-find">
+ <normaloff>.</normaloff>.</iconset>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label_xdg_icon">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>64</width>
+ <height>64</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>64</width>
+ <height>64</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="line_xdg_icon"/>
+ </item>
+ </layout>
+ </item>
+ <item row="4" column="2">
+ <widget class="QToolButton" name="push_xdg_getIcon">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>20000</width>
+ <height>42</height>
+ </size>
+ </property>
+ <property name="sizeIncrement">
+ <size>
+ <width>2</width>
+ <height>2</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="icon">
+ <iconset theme="edit-find">
+ <normaloff>.</normaloff>.</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_xdg_statusicon">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_xdg_status">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <italic>true</italic>
+ </font>
+ </property>
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
- </item>
- </layout>
- </item>
- </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>39</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menuFile">
+ <property name="title">
+ <string>File</string>
+ </property>
+ <widget class="QMenu" name="menuSave_As">
+ <property name="title">
+ <string>Save As</string>
+ </property>
+ <property name="icon">
+ <iconset theme="document-save">
+ <normaloff>.</normaloff>.</iconset>
+ </property>
+ <addaction name="actionLocal_Shortcut"/>
+ <addaction name="actionRegister_Shortcut"/>
+ </widget>
+ <addaction name="actionNew_Shortcut"/>
+ <addaction name="separator"/>
+ <addaction name="actionOpen_File"/>
+ <addaction name="actionOpen_Directory"/>
+ <addaction name="separator"/>
+ <addaction name="actionSave_Shortcut"/>
+ <addaction name="menuSave_As"/>
+ <addaction name="separator"/>
+ <addaction name="actionQuit"/>
+ </widget>
+ <addaction name="menuFile"/>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ <action name="actionOpen_File">
+ <property name="icon">
+ <iconset theme="document-open">
+ <normaloff>.</normaloff>.</iconset>
+ </property>
+ <property name="text">
+ <string>Open File</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+O</string>
+ </property>
+ <property name="shortcutContext">
+ <enum>Qt::ApplicationShortcut</enum>
+ </property>
+ </action>
+ <action name="actionQuit">
+ <property name="icon">
+ <iconset theme="window-close">
+ <normaloff>.</normaloff>.</iconset>
+ </property>
+ <property name="text">
+ <string>Quit</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Q</string>
+ </property>
+ <property name="shortcutContext">
+ <enum>Qt::ApplicationShortcut</enum>
+ </property>
+ </action>
+ <action name="actionSave_Shortcut">
+ <property name="icon">
+ <iconset theme="document-save">
+ <normaloff>.</normaloff>.</iconset>
+ </property>
+ <property name="text">
+ <string>Save Shortcut</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+S</string>
+ </property>
+ <property name="shortcutContext">
+ <enum>Qt::ApplicationShortcut</enum>
+ </property>
+ </action>
+ <action name="actionLocal_Shortcut">
+ <property name="icon">
+ <iconset theme="document-new">
+ <normaloff>.</normaloff>.</iconset>
+ </property>
+ <property name="text">
+ <string>Local Shortcut</string>
+ </property>
+ </action>
+ <action name="actionRegister_Shortcut">
+ <property name="icon">
+ <iconset theme="bookmark-new">
+ <normaloff>.</normaloff>.</iconset>
+ </property>
+ <property name="text">
+ <string>Register Shortcut</string>
+ </property>
+ </action>
+ <action name="actionOpen_Directory">
+ <property name="icon">
+ <iconset theme="folder-open">
+ <normaloff>.</normaloff>.</iconset>
+ </property>
+ <property name="text">
+ <string>Open Directory</string>
+ </property>
+ </action>
+ <action name="actionNew_Shortcut">
+ <property name="icon">
+ <iconset theme="document-new">
+ <normaloff>.</normaloff>.</iconset>
+ </property>
+ <property name="text">
+ <string>New Shortcut</string>
+ </property>
+ </action>
</widget>
- <layoutdefault spacing="6" margin="11"/>
- <tabstops>
- <tabstop>line_xdg_name</tabstop>
- <tabstop>line_xdg_comment</tabstop>
- <tabstop>line_xdg_command</tabstop>
- <tabstop>line_xdg_wdir</tabstop>
- <tabstop>check_xdg_startupNotify</tabstop>
- <tabstop>check_xdg_useTerminal</tabstop>
- <tabstop>tool_xdg_getCommand</tabstop>
- <tabstop>tool_xdg_getDir</tabstop>
- </tabstops>
<resources/>
<connections/>
</ui>
diff --git a/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro b/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro
index bbaf842e..14345f50 100644
--- a/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro
+++ b/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro
@@ -1,7 +1,7 @@
include("$${PWD}/../../OS-detect.pri")
QT += core gui
-greaterThan(QT_MAJOR_VERSION, 4): QT += widgets concurrent
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets concurrent multimedia
TARGET = lumina-fileinfo
@@ -13,6 +13,7 @@ target.path = $${L_BINDIR}
include(../../core/libLumina/LUtils.pri) #includes LUtils
include(../../core/libLumina/LuminaXDG.pri)
#include(../../core/libLumina/LuminaSingleApplication.pri)
+include(../../core/libLumina/LVideoLabel.pri)
include(../../core/libLumina/LuminaThemes.pri)
SOURCES += main.cpp\
diff --git a/src-qt5/desktop-utils/lumina-fileinfo/main.cpp b/src-qt5/desktop-utils/lumina-fileinfo/main.cpp
index a602f290..ce62399d 100644
--- a/src-qt5/desktop-utils/lumina-fileinfo/main.cpp
+++ b/src-qt5/desktop-utils/lumina-fileinfo/main.cpp
@@ -11,46 +11,26 @@ int main(int argc, char ** argv)
{
LTHEME::LoadCustomEnvSettings();
QApplication a(argc, argv);
- a.setAttribute(Qt::AA_UseHighDpiPixmaps);
+ a.setAttribute(Qt::AA_UseHighDpiPixmaps);
LUtils::LoadTranslation(&a, "l-fileinfo");
- //LuminaThemeEngine theme(&a);
//Read the input variables
QString path = "";
QString flag = "";
for(int i=1; i<argc; i++){
- if( QString(argv[i]).startsWith("-") ){ flag = QString(argv[i]); }
- else{ path = QString(argv[i]); break; }
+ QString tmp(argv[i]);
+ if( tmp=="--new-application" ){ flag = "APP"; }
+ else if( tmp=="--new-link" ){ flag = "LINK"; }
+ else if(!tmp.startsWith("-")){ path = QString(argv[i]); break; }
}
//Check the input variables
// - path
if(!path.isEmpty()){ path = LUtils::PathToAbsolute(path); }
- // - flag
- if(!flag.isEmpty()){
- if(flag=="-application"){
- flag = "APP"; //for internal use
- }else if(flag=="-link"){
- flag = "LINK"; //for internal use
- }else{
- //Invalid flag - clear the path as well
- flag.clear();
- path.clear();
- }
- }
- if(!path.isEmpty() || !flag.isEmpty()){
+ if(path.isEmpty() && flag.isEmpty()){ flag = "APP"; }
MainUI w;
- //QObject::connect(&theme, SIGNAL(updateIcons()), &w, SLOT(UpdateIcons()) );
w.LoadFile(path, flag);
w.show();
int retCode = a.exec();
return retCode;
- }else{
- //Show an error text and exit
- qDebug() << "ERROR: Invalid input arguments";
- qDebug() << "Usage: \"lumina-fileinfo [-application | -link] [file]";
- return 1;
- }
-
-
}
diff --git a/src-qt5/desktop-utils/lumina-fm/Browser.cpp b/src-qt5/desktop-utils/lumina-fm/Browser.cpp
index f2bdc178..29cc5a99 100644
--- a/src-qt5/desktop-utils/lumina-fm/Browser.cpp
+++ b/src-qt5/desktop-utils/lumina-fm/Browser.cpp
@@ -16,10 +16,12 @@
Browser::Browser(QObject *parent) : QObject(parent){
watcher = new QFileSystemWatcher(this);
connect(watcher, SIGNAL(fileChanged(const QString&)), this, SLOT(fileChanged(QString)) );
- connect(watcher, SIGNAL(directoryChanged(const QString&)), this, SLOT(dirChanged(QString)) );
+ connect(watcher, SIGNAL(directoryChanged(const QString&)), this, SLOT(dirChanged(QString)) );
showHidden = false;
showThumbs = false;
imageFormats = LUtils::imageExtensions(false); //lowercase suffixes
+ //connect(surface, SIGNAL(frameReceived(QImage)), this, SLOT(captureFrame(QImage)));
+ //connect(player, &QMediaPlayer::mediaStatusChanged, this, [&]{ stopVideo(player, player->mediaStatus()); });
connect(this, SIGNAL(threadDone(QString, QImage)), this, SLOT(futureFinished(QString, QImage))); //will always be between different threads
}
@@ -32,6 +34,7 @@ QString Browser::currentDirectory(){ return currentDir; }
void Browser::showHiddenFiles(bool show){
if(show !=showHidden){
showHidden = show;
+ lastcheck = QDateTime(); //reset this timestamp - need to reload all
if(!currentDir.isEmpty()){ QTimer::singleShot(0, this, SLOT(loadDirectory()) ); }
}
}
@@ -42,6 +45,7 @@ bool Browser::showingHiddenFiles(){
void Browser::showThumbnails(bool show){
if(show != showThumbs){
showThumbs = show;
+ lastcheck = QDateTime(); //reset this timestamp - need to reload all
if(!currentDir.isEmpty()){ QTimer::singleShot(0, this, SLOT(loadDirectory()) ); }
}
}
@@ -60,69 +64,83 @@ void Browser::loadItem(QString info, Browser *obj){
file.close();
pix.loadFromData(bytes);
if(pix.width() > 256 || pix.height() > 256 ){
- pix = pix.scaled(256,256, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ pix = pix.scaled(256,256, Qt::KeepAspectRatio, Qt::FastTransformation);
}
}
}
-
//qDebug() << " - done with item:" << info;
obj->emit threadDone(info, pix);
}
-QIcon Browser::loadIcon(QString icon){
+QIcon* Browser::loadIcon(QString icon){
if(!mimeIcons.contains(icon)){
mimeIcons.insert(icon, LXDG::findIcon(icon, "unknown"));
}
-
- return mimeIcons[icon];
+ return &mimeIcons[icon];
}
// PRIVATE SLOTS
void Browser::fileChanged(QString file){
- if(file.startsWith(currentDir+"/") ){
+ //qDebug() << "Got File Changed:" << file;
+ if(file.section("/",0,-2) == currentDir){
if(QFile::exists(file) ){ QtConcurrent::run(this, &Browser::loadItem, file, this); } //file modified but not removed
- else{ QTimer::singleShot(0, this, SLOT(loadDirectory()) ); } //file removed - need to update entire dir
- }else if(file==currentDir){ QTimer::singleShot(0, this, SLOT(loadDirectory()) ); }
+ else if(oldFiles.contains(file) ){
+ oldFiles.removeAll(file);
+ emit itemRemoved(file);
+ }
+ }//else if(file==currentDir){ QTimer::singleShot(0, this, SLOT(loadDirectory()) ); }
}
void Browser::dirChanged(QString dir){
-
- if(dir==currentDir){ QTimer::singleShot(500, this, SLOT(loadDirectory()) ); }
+ //qDebug() << "Got Dir Changed:" << dir;
+ if(dir==currentDir){ QTimer::singleShot(10, this, SLOT(loadDirectory()) ); }
else if(dir.startsWith(currentDir)){ QtConcurrent::run(this, &Browser::loadItem, dir, this ); }
}
void Browser::futureFinished(QString name, QImage icon){
//Note: this will be called once for every item that loads
- QIcon ico;
- //LFileInfo info(name);
- LFileInfo *info = new LFileInfo(name);
- if(!icon.isNull() && showThumbs){
- //qDebug() << " -- Data:";
- QPixmap pix = QPixmap::fromImage(icon);
- ico.addPixmap(pix);
- //}else if(info->isDir()){
- //qDebug() << " -- Folder:";
- //ico = loadIcon("folder");
- }
- if(ico.isNull()){
- //qDebug() << " -- MimeType:" << info.fileName() << info.mimetype();
- ico = loadIcon(info->iconfile());
- }
- this->emit itemDataAvailable( ico, info);
- //qDebug() << " -- done:" << name;
+ //Haven't added the extra files in a directory fix, but that should be easy to do
+ //Try to load a file with multiple videos and lots of other stuff before any other directory. It crashes for some reason
+ //qDebug() << name << "here";
+ QIcon *ico = new QIcon();
+ LFileInfo *info = new LFileInfo(name);
+ if(!icon.isNull() && showThumbs){
+ QPixmap pix = QPixmap::fromImage(icon);
+ ico->addPixmap(pix);
+ /*}else if(info->isVideo() && showThumbs) {
+ if(videoImages.find(name) == videoImages.end()) {
+ LVideoLabel *mediaLabel = new LVideoLabel(name);
+ while(mediaLabel->pixmap()->isNull()) { QCoreApplication::processEvents(QEventLoop::AllEvents, 50); }
+ ico->addPixmap(*(mediaLabel->pixmap()));
+ videoImages.insert(name, *mediaLabel->pixmap());
+ delete mediaLabel;
+ }else{
+ ico->addPixmap(videoImages[name]);
+ }*/
+ }else{
+ ico = loadIcon(info->iconfile());
+ }
+ this->emit itemDataAvailable( *ico, info);
+ //qDebug() << " -- done:" << name;
}
// PUBLIC SLOTS
-void Browser::loadDirectory(QString dir){
+void Browser::loadDirectory(QString dir, bool force){
+ if(force){ lastcheck = QDateTime(); } //reset check time to force reloads
if(dir.isEmpty()){ dir = currentDir; } //reload current directory
if(dir.isEmpty()){ return; } //nothing to do - nothing previously loaded
//qDebug() << "Load Directory" << dir;
+ bool dirupdate = true;
if(currentDir != dir){ //let the main widget know to clear all current items (completely different dir)
+ //videoImages.clear();
oldFiles.clear();
+ lastcheck = QDateTime(); //null time
emit clearItems();
+ dirupdate = false;
}
currentDir = dir; //save this for later
+ QDateTime now = QDateTime::currentDateTime();
//clean up the watcher first
QStringList watched; watched << watcher->files() << watcher->directories();
if(!watched.isEmpty()){ watcher->removePaths(watched); }
@@ -134,15 +152,18 @@ void Browser::loadDirectory(QString dir){
QStringList files;
if(showHidden){ files = directory.entryList( QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot, QDir::NoSort); }
else{ files = directory.entryList( QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot, QDir::NoSort); }
- emit itemsLoading(files.length());
+ if(dirupdate){ emit itemsLoading(files.length()); }
for(int i=0; i<files.length(); i++){
watcher->addPath(directory.absoluteFilePath(files[i]));
- //qDebug() << "Future Starting:" << files[i];
QString path = directory.absoluteFilePath(files[i]);
- if(old.contains(path)){ old.removeAll(path); }
oldFiles << path; //add to list for next time
+ bool reloaditem = !dirupdate || lastcheck.isNull() || (QFileInfo(path).lastModified() > lastcheck || QFileInfo(path).created() > lastcheck);
+ //if(dirupdate){ qDebug() << "Reload Item:" << reloaditem << path.section("/",-1); }
+ //reloaditem = true;
+ if(old.contains(path)){ old.removeAll(path); } //still in existance
//if(showThumbs && imageFormats.contains(path.section(".",-1).toLower())){
- QtConcurrent::run(this, &Browser::loadItem, path, this);
+ //qDebug() << "Future Starting:" << files[i];
+ if(reloaditem){ QtConcurrent::run(this, &Browser::loadItem, path, this); }
/*}else{
//No special icon loading - just skip the file read step
futureFinished(path, QImage()); //loadItem(path, this);
@@ -158,4 +179,5 @@ void Browser::loadDirectory(QString dir){
}else{
emit itemsLoading(0); //nothing to load
}
+ lastcheck = now; // save this for later
}
diff --git a/src-qt5/desktop-utils/lumina-fm/Browser.h b/src-qt5/desktop-utils/lumina-fm/Browser.h
index 94f6ba3f..0f4a0abe 100644
--- a/src-qt5/desktop-utils/lumina-fm/Browser.h
+++ b/src-qt5/desktop-utils/lumina-fm/Browser.h
@@ -15,6 +15,9 @@
#include <QIcon>
//#include <QFutureWatcher>
+#include <QMediaPlayer>
+#include <LVideoSurface.h>
+#include <LVideoLabel.h>
#include <LuminaXDG.h>
/*class FileItem{
public:
@@ -42,22 +45,23 @@ public:
private:
QString currentDir;
+ QDateTime lastcheck;
QFileSystemWatcher *watcher;
+ QMap<QString, QPixmap> videoImages;
bool showHidden, showThumbs;
- QStringList imageFormats, oldFiles;
+ QStringList imageFormats, videoFormats, oldFiles;
QHash<QString, QIcon> mimeIcons; //cache for quickly re-using QIcons
void loadItem(QString info, Browser *obj); //this is the main loader class - multiple instances each run in a separate thread
- QIcon loadIcon(QString icon); //simplification for using/populating the mimIcons cache
+ QIcon* loadIcon(QString icon); //simplification for using/populating the mimIcons cache
private slots:
void fileChanged(QString); //tied into the watcher - for file change notifications
void dirChanged(QString); // tied into the watcher - for new/removed files in the current dir
-
void futureFinished(QString, QImage);
public slots:
- void loadDirectory(QString dir = "");
+ void loadDirectory(QString dir = "", bool force = false);
signals:
//Main Signals
diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserModel.cpp b/src-qt5/desktop-utils/lumina-fm/BrowserModel.cpp
new file mode 100644
index 00000000..d79da006
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-fm/BrowserModel.cpp
@@ -0,0 +1,208 @@
+//===========================================
+// Lumina Desktop source code
+// Copyright (c) 2017, Ken Moore & JT Pennington
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "BrowserModel.h"
+
+BrowserModel::BrowserModel(QObject *parent){
+
+}
+
+BrowserModel::~BrowserModel(){
+
+}
+
+//Virtual overrides
+QModelIndex BrowserModel::index(int row, int column, const QModelIndex &parent) const{
+
+}
+
+QModelIndex BrowserModel::parent(const QModelIndex &index) const{
+
+}
+
+// item management
+int BrowserModel::rowCount(const QModelIndex &parent) const{
+
+}
+
+bool BrowserModel::insertRows(int row, int count, const QModelIndex &parent){
+
+}
+
+bool BrowserModel::removeRow(int row, const QModelIndex &parent){
+
+}
+
+bool BrowserModel::removeRows(int row, int count, const QModelIndex &parent){
+
+}
+
+int BrowserModel::columnCount(const QModelIndex &parent) const{
+
+}
+
+bool BrowserModel::insertColumns(int column, int count, const QModelIndex &parent){
+
+}
+
+bool BrowserModel::removeColumn(int column, const QModelIndex &parent){
+
+}
+
+bool BrowserModel::removeColumns(int column, int count, const QModelIndex &parent){
+
+}
+
+
+//bool BrowserModel::hasChildren(const QModelIndex &parent) const{
+
+}
+
+
+// data functions
+Qt::ItemFlags BrowserModel::flags(const QModelIndex &index) const{
+
+}
+
+QVariant BrowserModel::data(const QModelIndex &index, int role) const{
+ QFileInfo *info = indexToInfo(index);
+ switch(role){
+ case Qt::DisplayRole:
+ if(index.column()==0){ return QVariant(info->fileName()); }
+ else if(index.column()==1){ return QVariant(info->fileSize()); }
+ else if(index.column()==2){ return QVariant(info->mimetype()); }
+ else if(index.column()==3){ return QVariant(info->lastModified()->toString(Qt::DefaultLocaleShortDate)); }
+ else if(index.column()==4){ return QVariant(info->created()->toString(Qt::DefaultLocaleShortDate)); }
+ case Qt::ToolTipRole:
+ return QVariant(info->absoluteFilePath());
+ case Qt::StatusTipRole:
+ return QVariant(info->absoluteFilePath());
+ case Qt::SizeHintRole;
+ return QVariant(QSize(100,14));
+ case Qt::DecorationRole:
+ return QVariant(LXDG::findIcon(info->iconFile(), "unknown"));
+ }
+ return QVariant();
+}
+
+QVariant BrowserModel::headerData(int section, Qt::Orientation orientation, int role) const{
+ if(role == Qt::DisplayRole){
+ if(orientation == Qt::Horizontal){
+ switch(section){
+ case 0:
+ return QVariant(tr("File Name"));
+ case 1:
+ return QVariant("Size");
+ case 2:
+ return QVariant("Type");
+ case 3:
+ return QVariant("Date Modified");
+ case 4:
+ return QVariant("Date Created");
+ }
+ }
+ }
+ case Qt::DisplayRole:
+ return QVariant(tr("File Name");
+ /*case Qt::ToolTipRole:
+ return QVariant("ToolTip");
+ case Qt::StatusTipRole:
+ return QVariant("Status Tip");
+ case Qt::SizeHintRole;
+ return QVariant(QSize(100,14));*/
+ case Qt::DecorationRole:
+ return QVariant("Icon"));
+ }
+ return QVariant();
+}
+
+// data modification functions
+bool BrowserModel::setData(const QModelIndex &index, const QVariant &value, int role){
+
+}
+
+bool BrowserModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role){
+
+}
+
+
+// drag and drop
+//QMimeData* BrowserModel::mimeData(const QModelIndexList &indexes) const{
+
+}
+
+//QStringList BrowserModel::mimeTypes() const{
+
+}
+
+//bool BrowserModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles){
+
+}
+
+//Qt::DropActions BrowserModel::supportedDropActions() const{
+
+}
+
+//bool BrowserModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent){
+
+}
+
+//Special Functions (non virtual replacements)
+LFileInfo* BrowserModel::fileInfo(QString name){
+
+}
+
+QString BrowserModel::currentDirectory(){
+ return cDir;
+}
+
+
+// ==============
+// PUBLIC SLOTS
+// ==============
+void BrowserModel::loadDirectory(QString dir){
+
+
+}
+
+void BrowserModel::loadItem(QString itempath){
+ LFileInfo *it = new LFileInfo(itempath);
+ //Determine the row/column that it needs to be
+ int row, column;
+ row = 0;
+ //Now create the index
+ for(int i=0; i<5; i++){
+ QModelIndex index = createIndex(row, i, it);
+ }
+}
+
+
+// =============
+// PRIVATE
+// =============
+/*QString BrowserModel::findInHash(QString path){
+ QStringList keys = HASH.keys();
+ for(int i=0; i<keys.length(); i++){
+ if(HASH[keys[i]]->filePath() == path){ return keys[i]; }
+ }
+ return "";
+}
+
+QString BrowserModel::findInHash(QModelIndex index){
+ QString id = QString::number(index.row())+"/"+QString::number(index.column());
+ if(HASH.contains(id)){ return id; }
+ return "";
+}
+
+LFileInfo* BrowserModel::indexToInfo(QString path){
+ QString id = findInHash(path);
+ if(id.isEmpty()){ return 0;}
+ return HASH[id];
+}*/
+
+LFileInfo* BrowserModel::indexToInfo(QModelIndex index){
+ return static_cast<LFileInfo*>(index.internalPointer());
+}
diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserModel.h b/src-qt5/desktop-utils/lumina-fm/BrowserModel.h
new file mode 100644
index 00000000..b30e117e
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-fm/BrowserModel.h
@@ -0,0 +1,87 @@
+//===========================================
+// Lumina Desktop source code
+// Copyright (c) 2017, Ken Moore & JT Pennington
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+// This is the main browsing backend for the file manager
+//===========================================
+#ifndef _LUMINA_FM_BROWSER_MODEL_BACKEND_H
+#define _LUMINA_FM_BROWSER_MODEL_BACKEND_H
+
+#include <QAbstractItemModel>
+#include <QModelIndex>
+#include <QMimeData>
+#include <QMap>
+#include <QVariant>
+#include <QHash>
+
+#include <LuminaXDG.h>
+
+class BrowserModel : public QAbstractItemModel {
+ Q_OBJECT
+public:
+ BrowserModel(QObject *parent = 0);
+ ~BrowserModel();
+
+ //Virtual overrides
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex &index) const;
+
+ // item management
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
+ bool removeRow(int row, const QModelIndex &parent = QModelIndex());
+ bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
+
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex());
+ bool removeColumn(int column, const QModelIndex &parent = QModelIndex());
+ bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex());
+
+ //bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
+
+ // data functions
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+ // data modification functions
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+ bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole);
+
+ // drag and drop
+ //QMimeData* mimeData(const QModelIndexList &indexes) const;
+ //QStringList mimeTypes() const;
+ //bool setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles);
+ //Qt::DropActions supportedDropActions() const;
+ //bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
+
+ //Special Functions (non virtual replacements)
+ LFileInfo* fileInfo(QString name);
+ QString currentDirectory();
+
+ void setShowHidden(bool showHidden);
+ bool showHidden
+
+public slots:
+ void loadDirectory(QString dir="");
+ void loadItem(QString item);
+
+private:
+ QHash<quintptr, QModelIndex> HASH; //QString: "row/column"
+ QString cDir;
+ //simplification functions
+ /*QString findInHash(QString path);
+ QString findInHash(QModelIndex index);
+ LFileInfo* indexToInfo(QString path);*/
+ LFileInfo* indexToInfo(QModelIndex index);
+
+private slots:
+
+protected:
+
+signals:
+
+};
+
+#endif
diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp
index d5f219bb..87a3a6d7 100644
--- a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp
+++ b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp
@@ -24,7 +24,7 @@ BrowserWidget::BrowserWidget(QString objID, QWidget *parent) : QWidget(parent){
connect(BROWSER, SIGNAL(itemRemoved(QString)), this, SLOT(itemRemoved(QString)) );
connect(BROWSER, SIGNAL(itemDataAvailable(QIcon, LFileInfo*)), this, SLOT(itemDataAvailable(QIcon, LFileInfo*)) );
connect(BROWSER, SIGNAL(itemsLoading(int)), this, SLOT(itemsLoading(int)) );
- connect(this, SIGNAL(dirChange(QString)), BROWSER, SLOT(loadDirectory(QString)) );
+ connect(this, SIGNAL(dirChange(QString, bool)), BROWSER, SLOT(loadDirectory(QString, bool)) );
listWidget = 0;
treeWidget = 0;
readDateFormat();
@@ -38,6 +38,7 @@ BrowserWidget::~BrowserWidget(){
}
void BrowserWidget::changeDirectory(QString dir){
+ videoMap.clear();
if(BROWSER->currentDirectory()==dir){ return; } //already on this directory
//qDebug() << "Change Directory:" << dir << historyList;
@@ -50,7 +51,7 @@ void BrowserWidget::changeDirectory(QString dir){
if( (historyList.isEmpty() || historyList.last()!=cleaned) && !cleaned.isEmpty() ){ historyList << cleaned; }
}
//qDebug() << "History:" << historyList;
- emit dirChange(dir);
+ emit dirChange(dir, false);
}
void BrowserWidget::showDetails(bool show){
@@ -81,7 +82,8 @@ void BrowserWidget::showDetails(bool show){
connect(treeWidget, SIGNAL(GotFocus()), this, SLOT(selectionChanged()) );
retranslate();
treeWidget->sortItems(0, Qt::AscendingOrder);
- if(!BROWSER->currentDirectory().isEmpty()){ emit dirChange(""); }
+ treeWidget->setColumnWidth(0, treeWidget->fontMetrics().width("W")*20);
+ if(!BROWSER->currentDirectory().isEmpty()){ emit dirChange("", true); }
}else if(!show && listWidget==0){
listWidget = new DDListWidget(this);
listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
@@ -91,8 +93,10 @@ void BrowserWidget::showDetails(bool show){
connect(listWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SIGNAL(contextMenuRequested()) );
connect(listWidget, SIGNAL(DataDropped(QString, QStringList)), this, SIGNAL(DataDropped(QString, QStringList)) );
connect(listWidget, SIGNAL(GotFocus()), this, SLOT(selectionChanged()) );
- if(!BROWSER->currentDirectory().isEmpty()){ emit dirChange(""); }
+ if(!BROWSER->currentDirectory().isEmpty()){ emit dirChange("",true); }
}
+ if(listWidget!=0){ listWidget->setWhatsThis( BROWSER->currentDirectory() ); }
+ if(treeWidget!=0){ treeWidget->setWhatsThis(BROWSER->currentDirectory() ); }
//qDebug() << " Done making widget";
}
@@ -109,6 +113,18 @@ bool BrowserWidget::hasHiddenFiles(){
}
void BrowserWidget::showThumbnails(bool show){
+ //qDebug() << show << videoMap.size();
+ for(QString file : videoMap.uniqueKeys()) {
+ QTreeWidgetItem *it = videoMap[file].first;
+ LVideoWidget *widget = videoMap[file].second;
+ if(show) {
+ widget->enableIcons();
+ treeWidget->setItemWidget(it, 0, widget);
+ }else{
+ widget->disableIcons();
+ treeWidget->setItemWidget(it, 0, widget);
+ }
+ }
BROWSER->showThumbnails(show);
}
@@ -125,9 +141,15 @@ void BrowserWidget::setThumbnailSize(int px){
larger = treeWidget->iconSize().height() < px;
treeWidget->setIconSize(QSize(px,px));
}
+ for(QString file : videoMap.uniqueKeys()) {
+ QTreeWidgetItem *it = videoMap[file].first;
+ LVideoWidget *widget = videoMap[file].second;
+ widget->setIconSize(treeWidget->iconSize());
+ treeWidget->setItemWidget(it, 0, widget);
+ }
//qDebug() << "Changing Icon Size:" << px << larger;
if(BROWSER->currentDirectory().isEmpty() || !larger ){ return; } //don't need to reload icons unless the new size is larger
- emit dirChange("");
+ emit dirChange("", larger);
}
int BrowserWidget::thumbnailSize(){
@@ -271,6 +293,8 @@ void BrowserWidget::itemRemoved(QString item){
}
void BrowserWidget::itemDataAvailable(QIcon ico, LFileInfo *info){
+ if(listWidget!=0){ listWidget->setWhatsThis( BROWSER->currentDirectory() ); }
+ if(treeWidget!=0){ treeWidget->setWhatsThis(BROWSER->currentDirectory() ); }
//qDebug() << "Item Data Available:" << info->fileName();
int num = 0;
if(listWidget!=0){
@@ -326,15 +350,28 @@ void BrowserWidget::itemDataAvailable(QIcon ico, LFileInfo *info){
treeWidget->addTopLevelItem(it);
}
}else{
- if( ! treeWidget->findItems(info->fileName(), Qt::MatchExactly, 0).isEmpty() ){ it = treeWidget->findItems(info->fileName(), Qt::MatchExactly, 0).first(); }
- else{
+ if( ! treeWidget->findItems(info->fileName(), Qt::MatchExactly, 0).isEmpty() ) {
+ it = treeWidget->findItems(info->fileName(), Qt::MatchExactly, 0).first();
+ }else if(info->isVideo() && videoMap.find(info->absoluteFilePath()) == videoMap.end()) {
+ it = new CQTreeWidgetItem(treeWidget);
+ treeWidget->addTopLevelItem(it);
+ LVideoWidget *widget = new LVideoWidget(info->absoluteFilePath(), treeWidget->iconSize(), hasThumbnails(), treeWidget);
+ videoMap.insert(info->absoluteFilePath(), QPair<QTreeWidgetItem*,LVideoWidget*>(it, widget));
+ treeWidget->setItemWidget(it, 0, widget);
+ }else if(info->isVideo()) {
+ it = videoMap[info->absoluteFilePath()].first;
+ LVideoWidget *widget = videoMap[info->absoluteFilePath()].second;
+ widget->setIconSize(treeWidget->iconSize());
+ treeWidget->setItemWidget(it, 0, widget);
+ }else{
it = new CQTreeWidgetItem(treeWidget);
- it->setText(0, info->fileName() ); //name (0)
treeWidget->addTopLevelItem(it);
+ it->setText(0, info->fileName() ); //name (0)
}
}
//Now set/update all the data
- it->setIcon(0, ico);
+ if(!info->isVideo())
+ it->setIcon(0, ico);
it->setText(1, info->isDir() ? "" : LUtils::BytesToDisplaySize(info->size()) ); //size (1)
it->setText(2, info->mimetype() ); //type (2)
it->setText(3, DTtoString(info->lastModified() )); //modification date (3)
@@ -352,7 +389,9 @@ void BrowserWidget::itemDataAvailable(QIcon ico, LFileInfo *info){
}else{
if(freshload && treeWidget!=0){
//qDebug() << "Resize Tree Widget Contents";
- for(int i=0; i<treeWidget->columnCount(); i++){ treeWidget->resizeColumnToContents(i); }
+ //for(int i=treeWidget->columnCount()-1; i>0; i--){ treeWidget->resizeColumnToContents(i); }
+ treeWidget->resizeColumnToContents(1);
+ //treeWidget->resizeColumnToContents(0);
}
freshload = false; //any further changes are updates - not a fresh load of a dir
//Done loading items
diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h
index fafb3746..b17ad588 100644
--- a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h
+++ b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h
@@ -12,6 +12,8 @@
#include <QWidget>
#include <QThread>
+#include <LVideoWidget.h>
+
#include "Browser.h"
#include "widgets/DDListWidgets.h"
@@ -23,6 +25,7 @@ private:
int numItems; //used for checking if all the items have loaded yet
QString ID, statustip;
QStringList date_format, historyList;
+ QMap<QString,QPair<QTreeWidgetItem*, LVideoWidget*>> videoMap;
bool freshload;
//The drag and drop brower widgets
@@ -86,9 +89,10 @@ signals:
void contextMenuRequested();
void DataDropped(QString, QStringList);
void hasFocus(QString); //ID output
+ void stopLoop();
//Internal signal
- void dirChange(QString); //current dir path
+ void dirChange(QString, bool); //current dir path, force
};
#endif
diff --git a/src-qt5/desktop-utils/lumina-fm/MainUI.cpp b/src-qt5/desktop-utils/lumina-fm/MainUI.cpp
index abb99975..9ce7b69e 100644
--- a/src-qt5/desktop-utils/lumina-fm/MainUI.cpp
+++ b/src-qt5/desktop-utils/lumina-fm/MainUI.cpp
@@ -14,8 +14,10 @@
#include <LUtils.h>
#include <LDesktopUtils.h>
+#include <ExternalProcess.h>
#define DEBUG 0
+bool rootmode = false;
MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){
//for Signal/slot we must register the Typedef of QFileInfoList
@@ -25,6 +27,8 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){
//qRegisterMetaType< QVector<int> >("QVector<int>");
//qRegisterMetaType< QList<QPersistentModelIndex> >("QList<QPersistentModelIndex>");
waitingToClose = false;
+ //put if statement here to check if running as root
+ rootmode = (getuid()==0);
ui->setupUi(this);
if(DEBUG){ qDebug() << "Initilization:"; }
@@ -112,6 +116,7 @@ QSize orig = settings->value("preferences/MainWindowSize", QSize()).toSize();
TRAY = new TrayUI(this);
connect(TRAY, SIGNAL(JobsFinished()), this, SLOT(TrayJobsFinished()) );
if(DEBUG){ qDebug() << " - Done with init"; }
+ ui->actionOpen_as_Root->setVisible(LUtils::isValidBinary("qsudo"));
}
MainUI::~MainUI(){
@@ -344,7 +349,7 @@ void MainUI::RebuildDeviceMenu(){
QStringList devs = LOS::ExternalDevicePaths();
//Output Format: <type>::::<filesystem>::::<path> (6/24/14 - version 0.4.0 )
// <type> = [USB, HDRIVE, SDCARD, DVD, LVM, UNKNOWN]
- qDebug() << "Externally-mounted devices:" << devs;
+ //qDebug() << "Externally-mounted devices:" << devs;
//Now add them to the menu appropriately
for(int i=0; i<devs.length(); i++){
//Skip hidden mount points (usually only for system usage - not user browsing)
@@ -356,6 +361,7 @@ void MainUI::RebuildDeviceMenu(){
if(path == "/"){ label = tr("Root"); }
else{ label = path.section("/",-1).simplified(); }
if(label.startsWith(".") ){ continue; } //don't show hidden mountpoint (not usually user-browsable)
+ if(label.endsWith(".desktop")){ label = label.section(".desktop",0,-2); } //chop the shortcut suffix off the end
//Create entry for this device
if( !fs.simplified().isEmpty()){
//Add filesystem type to the label
@@ -502,13 +508,29 @@ void MainUI::goToDevice(QAction *act){
if(act==ui->actionScan){
RebuildDeviceMenu();
}else{
+ QString action = act->whatsThis();
+ if(action.endsWith(".desktop")){
+ //Find the actual action/directory within this shortcut
+ XDGDesktop xdg(action);
+ if(xdg.type==XDGDesktop::DIR){
+ action = xdg.path; //use the new path
+ }else{
+ //Need to run the full open routine on this shortcut
+ QProcess::startDetached("lumina-open", QStringList() << action);
+ return;
+ }
+ }else if( !QFileInfo(action).isDir() ){
+ //Need to run the full open routine on this file since it is not a directory
+ QProcess::startDetached("lumina-open", QStringList() << action);
+ return;
+ }
DirWidget *dir = FindActiveBrowser();
if(dir!=0){
- dir->ChangeDir(act->whatsThis());
+ dir->ChangeDir(action);
return;
}
//If no current dir could be found - open a new tab/column
- OpenDirs(QStringList() << act->whatsThis() );
+ OpenDirs(QStringList() << action );
}
}
@@ -962,3 +984,8 @@ void MainUI::closeEvent(QCloseEvent *ev){
}
QMainWindow::closeEvent(ev); //continue normal close routine
}
+
+void MainUI::on_actionOpen_as_Root_triggered()
+{
+ ExternalProcess::launch("qsudo lumina-fm");
+}
diff --git a/src-qt5/desktop-utils/lumina-fm/MainUI.h b/src-qt5/desktop-utils/lumina-fm/MainUI.h
index 492ba533..04b80f28 100644
--- a/src-qt5/desktop-utils/lumina-fm/MainUI.h
+++ b/src-qt5/desktop-utils/lumina-fm/MainUI.h
@@ -67,6 +67,7 @@ class MainUI : public QMainWindow{
public:
MainUI();
~MainUI();
+ //bool rootmode;
public slots:
void OpenDirs(QStringList); //also called from the main.cpp after initialization
@@ -176,6 +177,8 @@ private slots:
void TrayJobsFinished();
+ void on_actionOpen_as_Root_triggered();
+
signals:
void Si_AdaptStatusBar(QFileInfoList fileList, QString path, QString messageFolders, QString messageFiles);
diff --git a/src-qt5/desktop-utils/lumina-fm/MainUI.ui b/src-qt5/desktop-utils/lumina-fm/MainUI.ui
index 744f31a3..8a635199 100644
--- a/src-qt5/desktop-utils/lumina-fm/MainUI.ui
+++ b/src-qt5/desktop-utils/lumina-fm/MainUI.ui
@@ -119,6 +119,8 @@
<addaction name="separator"/>
<addaction name="actionClose_Browser"/>
<addaction name="separator"/>
+ <addaction name="actionOpen_as_Root"/>
+ <addaction name="separator"/>
<addaction name="actionClose"/>
</widget>
<widget class="QMenu" name="menuView">
@@ -434,6 +436,11 @@
<string>Ctrl+P</string>
</property>
</action>
+ <action name="actionOpen_as_Root">
+ <property name="text">
+ <string>Open as Root</string>
+ </property>
+ </action>
</widget>
<resources/>
<connections/>
diff --git a/src-qt5/desktop-utils/lumina-fm/VideoItemWidget.h b/src-qt5/desktop-utils/lumina-fm/VideoItemWidget.h
new file mode 100644
index 00000000..894394d4
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-fm/VideoItemWidget.h
@@ -0,0 +1,144 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2016, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#ifndef _LUMINA_VIDEO_ITEM_WIDGET_H
+#define _LUMINA_VIDEO_ITEM_WIDGET_H
+
+#include <QWidget>
+#include <QVideoWidget>
+#include <QMediaPlayer>
+#include <QString>
+#include <QObject>
+#include <QLabel>
+#include <QTimer>
+#include <QHBoxLayout>
+#include <QResizeEvent>
+
+#include <LVideoSurface.h>
+
+class RolloverVideoWidget : public QVideoWidget{
+ Q_OBJECT
+public:
+ RolloverVideoWidget(QWidget *parent = 0) : QVideoWidget(parent){
+ this->setMouseTracking(true);
+ }
+signals:
+ void OverWidget();
+ void NotOverWidget();
+
+protected:
+ /*void mouseMoveEvent(QMouseEvent *ev){
+ QWidget::mouseMoveEvent(ev);
+ qDebug() << "Got video rollover";
+ emit OverWidget();
+ }*/
+ void enterEvent(QEvent *ev){
+ QWidget::enterEvent(ev);
+ qDebug() << "Got video enter";
+ emit OverWidget();
+ }
+ void leaveEvent(QEvent *ev){
+ QWidget::leaveEvent(ev);
+ if(!this->underMouse()){
+ qDebug() << "Got video leave";
+ emit NotOverWidget();
+ }
+ }
+};
+
+class VideoItemWidget : public QWidget{
+ Q_OBJECT
+private:
+ QLabel *textLabel;
+ QMediaPlayer *mplayer;
+ LVideoSurface *vwidget;
+ QString file, text;
+ QSize fixedsize;
+
+public:
+ VideoItemWidget(QString filepath, QWidget *parent = 0) : QWidget(parent){
+ file = filepath;
+ text = filepath.section("/",-1);
+ textLabel = 0;
+ mplayer = 0;
+ vwidget = 0;
+ this->setMouseTracking(true);
+ QTimer::singleShot(5, this, SLOT(setupPlayer()) ); //make sure this creation routine is thread-safe
+ }
+ ~VideoItemWidget(){ mplayer->stop(); }
+
+ //Optional overloads - it will try to automatically adjust as needed
+ void setText(QString txt){
+ text = txt;
+ if(textLabel!=0){
+ textLabel->setText(txt);
+ textLabel->setVisible( !txt.isEmpty() );
+ }
+ }
+ void setIconSize(QSize sz){
+ fixedsize = sz;
+ if(vwidget!=0 && fixedsize.isValid()){ vwidget->setFixedSize(sz); }
+ }
+
+private slots:
+ void setupPlayer(){
+ textLabel = new QLabel(this);
+ vwidget = new LVideoSurface(this); //RolloverVideoWidget(this);
+ vwidget->setAspectRatioMode(Qt::IgnoreAspectRatio);
+ if(fixedsize.isValid()){ vwidget->setFixedSize(fixedsize); }
+ else{ vwidget->setMinimumSize(QSize(16,16)); }
+ mplayer = new QMediaPlayer(this, QMediaPlayer::VideoSurface);
+ mplayer->setVideoOutput(vwidget);
+ mplayer->setPlaybackRate(3); // 3x playback speed
+ mplayer->setMuted(true);
+ QHBoxLayout *tmpL = new QHBoxLayout(this);
+ tmpL->setAlignment(Qt::AlignLeft | Qt::AlignCenter);
+ tmpL->addWidget(vwidget);
+ tmpL->addWidget(textLabel);
+ tmpL->setStretchFactor(textLabel, 1); //make sure this always occupies all extra space
+ //connect(mplayer, SIGNAL(durationChanged(qint64)), this, SLOT(durationChanged(qint64)) );
+ connect(mplayer, SIGNAL(durationChanged(qint64)), this, SLOT(stopVideo()) );
+ //connect(vwidget, SIGNAL(OverWidget()), this, SLOT(startVideo()) );
+ //connect(vwidget, SIGNAL(NotOverWidget()), this, SLOT(stopVideo()) );
+ //Now load the file
+ textLabel->setText(text);
+ mplayer->setMedia(QUrl::fromLocalFile(file) );
+ mplayer->play();
+ }
+ void durationChanged(qint64 max){
+ qDebug() << "Got Duration Changed:" << max;
+ mplayer->setPosition( qRound(max/2.0));
+ }
+
+ void startVideo(){
+ if(mplayer==0){ return; }
+ if(mplayer->state()!=QMediaPlayer::PlayingState){
+ qDebug() << "Start Video";
+ mplayer->setPosition(0);
+ mplayer->play();
+ }
+ }
+
+ void stopVideo(){
+ if(mplayer==0){ return; }
+ if(mplayer->state()==QMediaPlayer::PlayingState){
+ qDebug() << "Stop Video";
+ mplayer->pause();
+ mplayer->setPosition( qRound(mplayer->duration()/2.0) );
+ }
+ }
+
+protected:
+ void resizeEvent(QResizeEvent *ev){
+ if(vwidget!=0 && !fixedsize.isValid()){ vwidget->setFixedSize( QSize(ev->size().height(), ev->size().height()) ); }
+ }
+ /*void mouseMoveEvent(QMouseEvent *ev){
+ QWidget::mouseMoveEvent(ev);
+ stopVideo(); //not over the video widget any more
+ }*/
+};
+
+#endif
diff --git a/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro b/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro
index 6c340e14..e27dad25 100644
--- a/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro
+++ b/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro
@@ -15,6 +15,8 @@ include(../../core/libLumina/LuminaXDG.pri)
include(../../core/libLumina/LuminaSingleApplication.pri)
include(../../core/libLumina/LuminaThemes.pri)
include(../../core/libLumina/ExternalProcess.pri)
+#include(../../core/libLumina/LVideoSurface.pri)
+include(../../core/libLumina/LVideoLabel.pri)
SOURCES += main.cpp \
MainUI.cpp \
diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h b/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h
index 254362fd..7e4b1f22 100644
--- a/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h
+++ b/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h
@@ -23,6 +23,7 @@
#include <QMouseEvent>
#include <QUrl>
#include <QDir>
+#include <QApplication>
#include <LUtils.h>
@@ -63,8 +64,8 @@ protected:
QList<QListWidgetItem*> items = this->selectedItems();
if(items.length()<1){ return; }
QList<QUrl> urilist;
- for(int i=0; i<items.length(); i++){
- urilist << QUrl::fromLocalFile(items[i]->whatsThis());
+ for(int i=0; i<items.length(); i++){
+ urilist << QUrl::fromLocalFile(items[i]->whatsThis());
}
//Create the mime data
//qDebug() << "Start Drag:" << urilist;
@@ -88,7 +89,7 @@ protected:
ev->ignore();
}
}
-
+
void dragMoveEvent(QDragMoveEvent *ev){
if(ev->mimeData()->hasUrls() && !this->whatsThis().isEmpty() ){
//Change the drop type depending on the data/dir
@@ -104,7 +105,7 @@ protected:
}
this->update();
}
-
+
void dropEvent(QDropEvent *ev){
if(this->whatsThis().isEmpty() || !ev->mimeData()->hasUrls() ){ ev->ignore(); return; } //not supported
//qDebug() << "Drop Event:";
@@ -125,7 +126,7 @@ protected:
foreach(const QUrl &url, ev->mimeData()->urls()){
const QString filepath = url.toLocalFile();
//If the target file is modifiable, assume a move - otherwise copy
- if(QFileInfo(filepath).isWritable() && (filepath.startsWith(home) && dirpath.startsWith(home))){
+ if(QFileInfo(filepath).isWritable() && (filepath.startsWith(home) && dirpath.startsWith(home))){
if(filepath.section("/",0,-2)!=dirpath){ files << "cut::::"+filepath; } //don't "cut" a file into the same dir
}else{ files << "copy::::"+filepath; }
}
@@ -133,18 +134,18 @@ protected:
if(!files.isEmpty()){ emit DataDropped( dirpath, files ); }
this->setCursor(Qt::ArrowCursor);
}
-
+
void mouseReleaseEvent(QMouseEvent *ev){
if(ev->button() != Qt::RightButton && ev->button() != Qt::LeftButton){ ev->ignore(); }
else{ QListWidget::mouseReleaseEvent(ev); } //pass it along to the widget
}
void mousePressEvent(QMouseEvent *ev){
if(ev->button() != Qt::RightButton && ev->button() != Qt::LeftButton){ ev->ignore(); }
- else{ QListWidget::mousePressEvent(ev); } //pass it along to the widget
+ else{ QListWidget::mousePressEvent(ev); } //pass it along to the widget
}
/*void mouseMoveEvent(QMouseEvent *ev){
if(ev->button() != Qt::RightButton && ev->button() != Qt::LeftButton){ ev->ignore(); }
- else{ QListWidget::mouseMoveEvent(ev); } //pass it along to the widget
+ else{ QListWidget::mouseMoveEvent(ev); } //pass it along to the widget
}*/
};
@@ -158,6 +159,8 @@ public:
//Drag and Drop Properties
this->setDragDropMode(QAbstractItemView::DragDrop);
this->setDefaultDropAction(Qt::MoveAction); //prevent any built-in Qt actions - the class handles it
+ this->setDropIndicatorShown(true);
+ this->setAcceptDrops(true);
//Other custom properties necessary for the FM
this->setFocusPolicy(Qt::StrongFocus);
this->setContextMenuPolicy(Qt::CustomContextMenu);
@@ -183,8 +186,8 @@ protected:
QList<QTreeWidgetItem*> items = this->selectedItems();
if(items.length()<1){ return; }
QList<QUrl> urilist;
- for(int i=0; i<items.length(); i++){
- urilist << QUrl::fromLocalFile(items[i]->whatsThis(0));
+ for(int i=0; i<items.length(); i++){
+ urilist << QUrl::fromLocalFile(items[i]->whatsThis(0));
}
//Create the mime data
QMimeData *mime = new QMimeData;
@@ -192,35 +195,43 @@ protected:
//Create the drag structure
QDrag *drag = new QDrag(this);
drag->setMimeData(mime);
- /*if(info.first().section("::::",0,0)=="cut"){
- drag->exec(act | Qt::MoveAction);
- }else{*/
+ //qDebug() << "Start Drag:" << urilist;
drag->exec(act | Qt::CopyAction| Qt::MoveAction);
- //}
+ //qDebug() << " - Drag Finished";
}
void dragEnterEvent(QDragEnterEvent *ev){
- //qDebug() << "Drag Enter Event:" << ev->mimeData()->hasFormat(MIME);
+ //qDebug() << "Drag Enter Event:" << ev->mimeData()->hasUrls() << this->whatsThis();
+ //QTreeWidget::dragEnterEvent(ev);
if(ev->mimeData()->hasUrls() && !this->whatsThis().isEmpty() ){
ev->acceptProposedAction(); //allow this to be dropped here
}else{
ev->ignore();
- }
+ }
}
-
+
void dragMoveEvent(QDragMoveEvent *ev){
+ //qDebug() << "Drag Move Event:" << ev->mimeData()->hasUrls() << this->whatsThis();
+ //QTreeWidget::dragMoveEvent(ev);
if(ev->mimeData()->hasUrls() && !this->whatsThis().isEmpty() ){
//Change the drop type depending on the data/dir
QString home = QDir::homePath();
- if( this->whatsThis().startsWith(home) ){ ev->setDropAction(Qt::MoveAction); }
- else{ ev->setDropAction(Qt::CopyAction); }
- ev->accept(); //allow this to be dropped here
+ if( this->whatsThis().startsWith(home) ){ ev->setDropAction(Qt::MoveAction); this->setCursor(Qt::DragMoveCursor); }
+ else{ ev->setDropAction(Qt::CopyAction); this->setCursor(Qt::DragCopyCursor);}
+ ev->acceptProposedAction(); //allow this to be dropped here
+ //this->setAcceptDrops(true);
}else{
+ //this->setAcceptDrops(false);
+ this->setCursor(Qt::ForbiddenCursor);
ev->ignore();
}
+ //this->setDropIndicatorShown(true);
+ //this->update();
+ //QTreeWidget::dragMoveEvent(ev);
}
-
+
void dropEvent(QDropEvent *ev){
+ //qDebug() << "Drop Event:" << ev->mimeData()->hasUrls() << this->whatsThis();
if(this->whatsThis().isEmpty() || !ev->mimeData()->hasUrls() ){ ev->ignore(); return; } //not supported
ev->accept(); //handled here
QString dirpath = this->whatsThis();
@@ -239,25 +250,25 @@ protected:
foreach(const QUrl &url, ev->mimeData()->urls()){
const QString filepath = url.toLocalFile();
//If the target file is modifiable, assume a move - otherwise copy
- if(QFileInfo(filepath).isWritable() && (filepath.startsWith(home) && dirpath.startsWith(home))){
+ if(QFileInfo(filepath).isWritable() && (filepath.startsWith(home) && dirpath.startsWith(home))){
if(filepath.section("/",0,-2)!=dirpath){ files << "cut::::"+filepath; } //don't "cut" a file into the same dir
}else{ files << "copy::::"+filepath; }
}
//qDebug() << "Drop Event:" << dirpath;
emit DataDropped( dirpath, files );
}
-
+
void mouseReleaseEvent(QMouseEvent *ev){
if(ev->button() != Qt::RightButton && ev->button() != Qt::LeftButton){ ev->ignore(); }
else{ QTreeWidget::mouseReleaseEvent(ev); } //pass it along to the widget
}
void mousePressEvent(QMouseEvent *ev){
if(ev->button() != Qt::RightButton && ev->button() != Qt::LeftButton){ ev->ignore(); }
- else{ QTreeWidget::mousePressEvent(ev); } //pass it along to the widget
+ else{ QTreeWidget::mousePressEvent(ev); } //pass it along to the widget
}
/*void mouseMoveEvent(QMouseEvent *ev){
if(ev->button() != Qt::RightButton && ev->button() != Qt::LeftButton){ ev->ignore(); }
- else{ QTreeWidget::mouseMoveEvent(ev); } //pass it along to the widget
+ else{ QTreeWidget::mouseMoveEvent(ev); } //pass it along to the widget
}*/
};
diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp
index 8273d09c..5c6f9ef5 100644
--- a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp
+++ b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp
@@ -27,9 +27,12 @@
#include "../ScrollDialog.h"
#define DEBUG 0
+extern bool rootmode;
DirWidget::DirWidget(QString objID, QSettings *settings, QWidget *parent) : QWidget(parent), ui(new Ui::DirWidget){
ui->setupUi(this); //load the designer file
+ ui->label_rootmode->setVisible(rootmode);
+
ID = objID;
//Assemble the toolbar for the widget
toolbar = new QToolBar(this);
@@ -59,7 +62,7 @@ DirWidget::DirWidget(QString objID, QSettings *settings, QWidget *parent) : QWid
RCBW = 0; //right column browser is unavailable initially
BW = new BrowserWidget("", this);
ui->browser_layout->addWidget(BW);
- connect(BW, SIGNAL(dirChange(QString)), this, SLOT(currentDirectoryChanged()) );
+ connect(BW, SIGNAL(dirChange(QString, bool)), this, SLOT(currentDirectoryChanged()) );
connect(BW, SIGNAL(itemsActivated()), this, SLOT(runFiles()) );
connect(BW, SIGNAL(DataDropped(QString, QStringList)), this, SIGNAL(PasteFiles(QString, QStringList)) );
connect(BW, SIGNAL(contextMenuRequested()), this, SLOT(OpenContextMenu()) );
@@ -281,10 +284,11 @@ void DirWidget::createMenus(){
else{ cOpenMenu->clear(); }
cOpenMenu->setTitle(tr("Launch..."));
cOpenMenu->setIcon( LXDG::findIcon("quickopen","") );
- cOpenMenu->addAction(LXDG::findIcon("utilities-terminal",""), tr("Terminal"), this, SLOT(openTerminal()), kOpTerm->key());
+ cOpenMenu->addAction(LXDG::findIcon("utilities-terminal",""), tr("Open Current Dir in a Terminal"), this, SLOT(openTerminal()), kOpTerm->key());
cOpenMenu->addAction(LXDG::findIcon("media-slideshow",""), tr("SlideShow"), this, SLOT(openInSlideshow()), kOpSS->key());
cOpenMenu->addAction(LXDG::findIcon("media-playback-start-circled","media-playback-start"), tr("Multimedia Player"), this, SLOT(openMultimedia()), kOpMM->key());
-/*
+ if(LUtils::isValidBinary("qsudo")){ cOpenMenu->addAction(LXDG::findIcon("", ""), tr("Open Current Dir as Root"), this, SLOT(openRootFM()));
+ /*
if(cFModMenu==0){ cFModMenu = new QMenu(this); }
else{ cFModMenu->clear(); }
cFModMenu->setTitle(tr("Modify Files..."));
@@ -319,6 +323,8 @@ void DirWidget::createMenus(){
}
+}
+
BrowserWidget* DirWidget::currentBrowser(){
if(cBID.isEmpty() || RCBW==0){ return BW; }
else{ return RCBW; }
@@ -471,7 +477,7 @@ void DirWidget::on_actionDualColumn_triggered(bool checked){
if(RCBW!=0){ return; } //nothing to do
RCBW = new BrowserWidget("rc", this);
ui->browser_layout->addWidget(RCBW);
- connect(RCBW, SIGNAL(dirChange(QString)), this, SLOT(currentDirectoryChanged()) );
+ connect(RCBW, SIGNAL(dirChange(QString, bool)), this, SLOT(currentDirectoryChanged()) );
connect(RCBW, SIGNAL(itemsActivated()), this, SLOT(runFiles()) );
connect(RCBW, SIGNAL(DataDropped(QString, QStringList)), this, SIGNAL(PasteFiles(QString, QStringList)) );
connect(RCBW, SIGNAL(contextMenuRequested()), this, SLOT(OpenContextMenu()) );
@@ -482,6 +488,7 @@ void DirWidget::on_actionDualColumn_triggered(bool checked){
RCBW->showDetails(BW->hasDetails());
RCBW->showHiddenFiles( BW->hasHiddenFiles());
RCBW->setThumbnailSize( BW->thumbnailSize());
+ RCBW->showThumbnails( BW->hasThumbnails());
RCBW->changeDirectory( BW->currentDirectory());
}
@@ -880,3 +887,9 @@ void DirWidget::mouseReleaseEvent(QMouseEvent *ev){
ev->ignore(); //not handled here
}
}
+
+void DirWidget::openRootFM(){
+ rootfmdir = "qsudo lumina-fm -new-instance " + currentDir();
+ qDebug() << "rootfmdir" << rootfmdir;
+ ExternalProcess::launch(rootfmdir);
+}
diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.h b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.h
index 8dd367df..4377f92d 100644
--- a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.h
+++ b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.h
@@ -73,9 +73,9 @@ private:
Ui::DirWidget *ui;
BrowserWidget *BW, *RCBW; //Main BrowserWidget and right-column browser widget
QString ID, cBID; //unique ID assigned by the parent, and currently active browser widget
- QString normalbasedir, snapbasedir, snaprelpath; //for maintaining directory context while moving between snapshots
+ QString normalbasedir, snapbasedir, snaprelpath, rootfmdir; //for maintaining directory context while moving between snapshots
QStringList snapshots, needThumbs, tmpSel;
- QSettings *settings;
+ QSettings *settings;
bool canmodify;
//The Toolbar and associated items
@@ -83,10 +83,10 @@ private:
QLineEdit *line_dir;
//The context menu and associated items
- QMenu *contextMenu, *cNewMenu, *cOpenMenu, *cFModMenu, *cFViewMenu, *cOpenWithMenu;
+ QMenu *contextMenu, *cNewMenu, *cOpenMenu, *cFModMenu, *cFViewMenu, *cOpenWithMenu;
//The keyboard shortcuts for context menu items
- QShortcut *kZoomIn, *kZoomOut, *kNewFile, *kNewDir, *kNewXDG, *kCut, *kCopy, *kPaste, *kRename, \
+ QShortcut *kZoomIn, *kZoomOut, *kNewFile, *kNewDir, *kNewXDG, *kCut, *kCopy, *kPaste, *kRename, \
*kFav, *kDel, *kOpSS, *kOpMM, *kOpTerm, *kExtract; //, *kArchive;
//Functions for internal use
@@ -129,6 +129,7 @@ private slots:
void fileCheckSums();
void fileProperties();
void openTerminal();
+ void openRootFM();
//Browser Functions
diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.ui b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.ui
index b1ba9d95..5f980c67 100644
--- a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.ui
+++ b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>400</width>
- <height>350</height>
+ <height>389</height>
</rect>
</property>
<property name="minimumSize">
@@ -19,7 +19,32 @@
<property name="windowTitle">
<string>Form</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,1,0">
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,1,0">
+ <item>
+ <widget class="QLabel" name="label_rootmode">
+ <property name="font">
+ <font>
+ <family>Droid Sans Mono</family>
+ <pointsize>16</pointsize>
+ <weight>75</weight>
+ <italic>false</italic>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::Box</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="text">
+ <string> * - FILE MANAGER RUNNING AS ROOT- * </string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
<item>
<layout class="QHBoxLayout" name="toolbar_layout"/>
</item>
diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.cpp b/src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.cpp
new file mode 100644
index 00000000..6e65ebaf
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.cpp
@@ -0,0 +1,36 @@
+#include "fmwebdav.h"
+
+fmwebdav::fmwebdav(QObject *parent) : QNetworkAccessManager(parent) ,wdRootPath(), wdUsername(), wdUassword(), wdBaseUrl(), wdCurrentConnectionType(QWebdav::HTTP){
+// typical Qnetwork connection stuff goes here
+// probably ssl parts too
+}
+
+fmwebdav::~fmwebdav(){
+}
+
+QString fmwebdav::hostname() const{ return wdBaseUrl.host(); }
+
+int fmwebdav::port() const{ return wdBaseUrl.port(); }
+
+QString fmwebdav::rootPath() const{ return wdRootPath;}
+
+QString fmwebdav::username() const{ return wdUsername; }
+
+QString fmwebdav::password() const{ return wdPassword; }
+
+fmwebdav::QWebdavConnectionType : fmwebdav::connectionType() const{ return wdCurrentConnectionType; }
+
+bool fmwebdav::isSSL() const{ return (wdCurrentConnectionType==QWebdav::HTTPS); }
+
+void QWebdav::setConnectionSettings(const QWebdavConnectionType connectionType, const QString *hostname, const QString *rootPath, const QString *username, const QString *password, int *port){
+ wdRootPath = rootPath;
+ if ((wdRootPath.endsWith("/")){ wdRootPath.chop(1); }
+ wdCurrentConnectionType = connectionType;
+ wdBaseUrl.setScheme();
+ wdBaseUrl.setHost(hostname);
+ wdBaseUrl.setPath(rootPath);
+ if (port != 0) { // use user-defined port number if not 80 or 443
+ if ( ! ( ( (port == 80) && (wdCurrentConnectionType==QWebdav::HTTP) ) || ( (port == 443) && (wdCurrentConnectionType==QWebdav::HTTPS) ) ) ){ wdBaseUrl.setPort(port); }
+ wdUsername = username;
+ wdPassword = password;
+}
diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.h b/src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.h
new file mode 100644
index 00000000..04d29e3b
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.h
@@ -0,0 +1,36 @@
+#ifndef FMWEBDAV_H
+#define FMWEBDAV_H
+
+#include <QtCore>
+#include <QtNetwork>
+#include <QNetworkAccessManager>
+
+public:
+
+ enum QWebdavConnectionType {HTTP = 1, HTTPS};
+
+ QString hostname() const;
+ int port() const;
+ QString rootPath() const;
+ QString username() const;
+ QString password() const;
+ QWebdavConnectionType connectionType() const;
+ bool isSSL() const;
+
+ void setConnectionSettings( const QWebdavConnectionType connectionType, const QString *hostname, const QString *rootPath = "/", const QString *username = "", const QString *password = "", int *port = 0;
+
+
+private:
+
+ QString wdRootPath;
+ QString wdUsername;
+ QString wdPassword;
+ QUrl wdBaseUrl;
+ QWebdavConnectionType wdCurrentConnectionType;
+
+
+
+
+
+
+#endif // FMWEBDAV
diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.cpp b/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.cpp
new file mode 100644
index 00000000..d0ecdecf
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.cpp
@@ -0,0 +1,59 @@
+#ifndef VIDNAIL_H
+#define VIDNAIL_H
+
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+}
+
+class VidNail;
+
+struct vFrame {
+ vFrame() : *width(0), *height(0) {}
+ vFrame(int *width, int *height : width(width), height(height) {}
+ int *width;
+ int *height;
+};
+
+public:
+
+ QString getCodec();
+ void skipTo(int timeInSeconds);
+ void readVideoFrame();
+ void getScaledVideoFrame(int scaledSize, vFrame& vFrame);
+
+ int getWidth();
+ int getHeight();
+ int getLength();
+
+ void makeThumbnail(const QString& videoFile, QImage &image);
+ void setThumbnailSize(int size);
+ void setPercentage(int percent);
+ void setTime(const QString& Time);
+
+ void writeVidNail(vFrame& frame, QImage& image);
+
+
+ private:
+ bool readVideoPacket();
+ bool getVideoPacket();
+ void scaleVideo(int scaledSize, int& scaledWidth, int& scaledHeight);
+ void createVFrame(AVFrame *vFrame, quint8 *frameBuffer, int width, int height);
+ void calculateDimensions(int size);
+ void generateThumbnail(const QString& videoFile, ImageWriter& imageWriter, QImage& image);
+ QString getMimeType(const QString& videoFile);
+ QString getExtension(const QString& videoFilename);
+
+
+ private:
+ int videoStream;
+ AVFormatContext *inputVideoFormatContext;
+ AVCodecContext *inputvideoCodecContext;
+ AVCodec *inputVideoCodec;
+ AVStream *inputVideoStream;
+ AVFrame *inputVideoFrame;
+ quint8 *inputFrameBuffer;
+ AVPacket *videoPacket;
+
+
+#endif // VIDNAIL_H
diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.h b/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.h
new file mode 100644
index 00000000..e13894e1
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.h
@@ -0,0 +1,13 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2017, q5sys
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "vidnail.h"
+
+VidNail::VidNail(QObject *parent) : QObject(parent){
+}
+
+VidNail::~VidNail(){
+}
diff --git a/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp b/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp
index 4c2ce0bd..9e4ce499 100644
--- a/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp
+++ b/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp
@@ -496,11 +496,14 @@ void MainUI::closeEvent(QCloseEvent *ev){
unsaved << tmp->currentFile();
}
}
- bool savenow = unsaved.isEmpty();
+ if(unsaved.isEmpty()){ QMainWindow::closeEvent(ev); return; }
+ bool savenow = false;
if(!savenow && !ui->actionShow_Popups->isChecked()){ savenow = true; }
if(!savenow){
- savenow = (QMessageBox::Yes == QMessageBox::question(this, tr("Save Changes before closing?"), QString(tr("There are unsaved changes.\nDo you want save them before you close the editor?\n\n%1")).arg(unsaved.join("\n")), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) );
+ QMessageBox::StandardButton but = QMessageBox::question(this, tr("Save Changes before closing?"), QString(tr("There are unsaved changes.\nDo you want save them before you close the editor?\n\n%1")).arg(unsaved.join("\n")), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::No);
+ savenow = (but == QMessageBox::Yes);
+ if(but == QMessageBox::Cancel){ ev->ignore(); return; }
}
- if(!savenow){ QMainWindow::closeEvent(ev); }
- else{ ev->ignore(); SaveFile(); }
+ if(savenow){ SaveFile(); }
+ QMainWindow::closeEvent(ev);
}
diff --git a/src-qt5/desktop-utils/lumina-xdg-entry/mainwindow.cpp b/src-qt5/desktop-utils/lumina-xdg-entry/mainwindow.cpp
index 7b34935e..1ad6edcd 100644
--- a/src-qt5/desktop-utils/lumina-xdg-entry/mainwindow.cpp
+++ b/src-qt5/desktop-utils/lumina-xdg-entry/mainwindow.cpp
@@ -1,7 +1,7 @@
//===========================================
// Copyright (c) 2017, q5sys (JT)
// Available under the MIT license
-// See the LICENSE file for full details
+// See the LICENSE file for full details
//===========================================
#include "mainwindow.h"
diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.cpp b/src-qt5/src-cpp/NativeEmbedWidget.cpp
index 57b6edde..57b6edde 100644
--- a/src-qt5/core/libLumina/NativeEmbedWidget.cpp
+++ b/src-qt5/src-cpp/NativeEmbedWidget.cpp
diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.h b/src-qt5/src-cpp/NativeEmbedWidget.h
index 16bb46dc..16bb46dc 100644
--- a/src-qt5/core/libLumina/NativeEmbedWidget.h
+++ b/src-qt5/src-cpp/NativeEmbedWidget.h
diff --git a/src-qt5/core/libLumina/NativeEventFilter.cpp b/src-qt5/src-cpp/NativeEventFilter.cpp
index c13c1fc8..c13c1fc8 100644
--- a/src-qt5/core/libLumina/NativeEventFilter.cpp
+++ b/src-qt5/src-cpp/NativeEventFilter.cpp
diff --git a/src-qt5/core/libLumina/NativeEventFilter.h b/src-qt5/src-cpp/NativeEventFilter.h
index a3be3ef1..a3be3ef1 100644
--- a/src-qt5/core/libLumina/NativeEventFilter.h
+++ b/src-qt5/src-cpp/NativeEventFilter.h
diff --git a/src-qt5/core/libLumina/NativeKeyToQt.cpp b/src-qt5/src-cpp/NativeKeyToQt.cpp
index 06056be7..06056be7 100644
--- a/src-qt5/core/libLumina/NativeKeyToQt.cpp
+++ b/src-qt5/src-cpp/NativeKeyToQt.cpp
diff --git a/src-qt5/core/libLumina/NativeWindow.cpp b/src-qt5/src-cpp/NativeWindow.cpp
index 02cc001e..02cc001e 100644
--- a/src-qt5/core/libLumina/NativeWindow.cpp
+++ b/src-qt5/src-cpp/NativeWindow.cpp
diff --git a/src-qt5/core/libLumina/NativeWindow.h b/src-qt5/src-cpp/NativeWindow.h
index 67436259..67436259 100644
--- a/src-qt5/core/libLumina/NativeWindow.h
+++ b/src-qt5/src-cpp/NativeWindow.h
diff --git a/src-qt5/core/libLumina/NativeWindow.pri b/src-qt5/src-cpp/NativeWindow.pri
index c906d6fd..c2ac0137 100644
--- a/src-qt5/core/libLumina/NativeWindow.pri
+++ b/src-qt5/src-cpp/NativeWindow.pri
@@ -2,7 +2,6 @@
# Files
QT *= x11extras
LIBS *= -lc -lxcb -lxcb-ewmh -lxcb-icccm -lxcb-image -lxcb-composite -lxcb-damage -lxcb-util -lxcb-keysyms -lXdamage
-#QT *= -lxcb-render -lxcb-render-util
SOURCES *= $${PWD}/NativeWindow.cpp \
$${PWD}/NativeWindowSystem.cpp \
diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/src-cpp/NativeWindowSystem.cpp
index e8e9655a..e8e9655a 100644
--- a/src-qt5/core/libLumina/NativeWindowSystem.cpp
+++ b/src-qt5/src-cpp/NativeWindowSystem.cpp
diff --git a/src-qt5/core/libLumina/NativeWindowSystem.h b/src-qt5/src-cpp/NativeWindowSystem.h
index b67ecc94..b67ecc94 100644
--- a/src-qt5/core/libLumina/NativeWindowSystem.h
+++ b/src-qt5/src-cpp/NativeWindowSystem.h
diff --git a/src-qt5/src-cpp/plugins-screensaver.cpp b/src-qt5/src-cpp/plugins-screensaver.cpp
new file mode 100644
index 00000000..75e93c9d
--- /dev/null
+++ b/src-qt5/src-cpp/plugins-screensaver.cpp
@@ -0,0 +1,150 @@
+//===========================================
+// Lumina-desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "plugins-screensaver.h"
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QFile>
+#include <QDir>
+#include <QDebug>
+
+//Relative directory to search along the XDG paths for screensavers
+#define REL_DIR QString("/lumina-desktop/screensavers")
+
+// ============
+// SS PLUGIN
+// ============
+SSPlugin::SSPlugin(){
+
+}
+
+SSPlugin::~SSPlugin(){
+
+}
+
+void SSPlugin::loadFile(QString path){
+ data = QJsonObject();
+ currentfile = path;
+ QFile file(path);
+ if(!file.exists() || !file.open(QIODevice::ReadOnly)){ return; }
+ data = QJsonDocument::fromJson(file.readAll()).object();
+ file.close();
+}
+
+bool SSPlugin::isLoaded(){
+ return !data.isEmpty();
+}
+
+bool SSPlugin::isValid(){
+ if(data.isEmpty()){ return false; }
+ bool ok = data.contains("name") && data.contains("qml") && data.contains("description");
+ if(ok){
+ //go to the next name level and see if required sub-items exist
+ QJsonObject tmp = data.value("name").toObject();
+ ok = tmp.contains("default");
+ }
+ if(ok){
+ //go to the next description level and see if required sub-items exist
+ QJsonObject tmp = data.value("description").toObject();
+ ok = tmp.contains("default");
+ }
+if(ok){
+ //go to the next qml level and see if required sub-items exist
+ QJsonObject tmp = data.value("qml").toObject();
+ QStringList mustexist;
+ QString exec = tmp.value("exec").toString();
+ if(exec.isEmpty() || !exec.endsWith(".qml")){ return false; }
+ mustexist << exec;
+ QJsonArray tmpA = data.value("additional_files").toArray();
+ for(int i=0; i<tmpA.count(); i++){ mustexist << tmpA[i].toString(); }
+ QString reldir = currentfile.section("/",0,-2) + "/";
+ //qDebug() << "Got MustExist:" << mustexist << reldir;
+ for(int i=0; i<mustexist.length() && ok; i++){
+ if(mustexist[i].startsWith("/")){ ok = QFile::exists(mustexist[i]); }
+ else { ok = QFile::exists(reldir+mustexist[i]); }
+ }
+ }
+ return ok;
+}
+
+QString SSPlugin::translatedName(){
+ QJsonObject tmp = data.value("name").toObject();
+ //Get the current locale
+ QString locale = getenv("LC_ALL");
+ if(locale.isEmpty()){ locale = getenv("LC_MESSAGES"); }
+ if(locale.isEmpty()){ locale = getenv("LANG"); }
+ if(locale.isEmpty()){ locale = "default"; }
+ if(locale.contains(".")){ locale = locale.section(".",0,0); } //chop any charset code off the end
+ //Now find which localized string is available and return it
+ if(tmp.contains(locale)){ return tmp.value(locale).toString(); }
+ locale = locale.section("_",0,0); //full locale not found - look for shortened form
+ if(tmp.contains(locale)){ return tmp.value(locale).toString(); }
+ return tmp.value("default").toString(); //use the default version
+}
+
+QString SSPlugin::translatedDescription(){
+ QJsonObject tmp = data.value("description").toObject();
+ //Get the current locale
+ QString locale = getenv("LC_ALL");
+ if(locale.isEmpty()){ locale = getenv("LC_MESSAGES"); }
+ if(locale.isEmpty()){ locale = getenv("LANG"); }
+ if(locale.isEmpty()){ locale = "default"; }
+ if(locale.contains(".")){ locale = locale.section(".",0,0); } //chop any charset code off the end
+ //Now find which localized string is available and return it
+ if(tmp.contains(locale)){ return tmp.value(locale).toString(); }
+ locale = locale.section("_",0,0); //full locale not found - look for shortened form
+ if(tmp.contains(locale)){ return tmp.value(locale).toString(); }
+ return tmp.value("default").toString(); //use the default version
+}
+
+QUrl SSPlugin::scriptURL(){
+ QString exec = data.value("qml").toObject().value("exec").toString();
+ //qDebug() << "got exec:" << exec;
+ if(!exec.startsWith("/")){ exec.prepend( currentfile.section("/",0,-2)+"/" ); }
+ return QUrl::fromLocalFile(exec);
+}
+
+// ===================
+// SS PLUGIN SYSTEM
+// ===================
+SSPlugin SSPluginSystem::findPlugin(QString name){
+ SSPlugin SSP;
+ if(name.startsWith("/") && QFile::exists(name)){ SSP.loadFile(name); return SSP;} //absolute path give - just load that one
+ //Cleanup the input name and ensure it has the right suffix
+ name = name.section("/",-1);
+ if(!name.endsWith(".json")){ name.append(".json"); }
+ //Get the list of directories to search
+ QStringList dirs;
+ dirs << QString(getenv("XDG_DATA_HOME")) << QString(getenv("XDG_DATA_DIRS")).split(":");
+ //Look for that file within these directories and return the first one found
+ for(int i=0; i<dirs.length(); i++){
+ if(!QFile::exists(dirs[i]+REL_DIR+"/"+name)){ continue; }
+ SSP.loadFile(dirs[i]+REL_DIR+"/"+name);
+ if(SSP.isValid()){ break; } //got a good one - stop here
+ }
+ return SSP;
+}
+
+QList<SSPlugin> SSPluginSystem::findAllPlugins(bool validonly){
+ QList<SSPlugin> LIST;
+ //Get the list of directories to search
+ QStringList dirs;
+ dirs << QString(getenv("XDG_DATA_HOME")) << QString(getenv("XDG_DATA_DIRS")).split(":");
+ //Look for that file within these directories and return the first one found
+ for(int i=0; i<dirs.length(); i++){
+ if(!QFile::exists(dirs[i]+REL_DIR)){ continue; }
+ QDir dir(dirs[i]+REL_DIR);
+ QStringList files = dir.entryList(QStringList() << "*.json", QDir::Files, QDir::Name);
+ //qDebug() << "Found Files:" << files;
+ for(int j=0; j<files.length(); j++){
+ SSPlugin tmp;
+ tmp.loadFile(dir.absoluteFilePath(files[j]));
+ //qDebug() << "Loaded File:" << files[j] << tmp.isValid();
+ if(!validonly || tmp.isValid()){ LIST << tmp; }
+ }
+ }
+ return LIST;
+}
diff --git a/src-qt5/src-cpp/plugins-screensaver.h b/src-qt5/src-cpp/plugins-screensaver.h
new file mode 100644
index 00000000..9a7e98f5
--- /dev/null
+++ b/src-qt5/src-cpp/plugins-screensaver.h
@@ -0,0 +1,50 @@
+//===========================================
+// Lumina-desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+// This is a simple class for managing all the various desktop
+// screensaver plugins that could be available
+//===========================================
+// NOTE:
+// This class has a heirarchy-based lookup system
+// USER plugins > SYSTEM plugins
+// XDG_DATA_HOME/lumina-desktop/screensavers > XDG_DATA_DIRS/lumina-desktop/screensavers
+//===========================================
+#ifndef _LUMINA_DESKTOP_SCREENSAVER_PLUGINS_CLASS_H
+#define _LUMINA_DESKTOP_SCREENSAVER_PLUGINS_CLASS_H
+
+#include <QJsonObject>
+#include <QString>
+#include <QUrl>
+#include <QObject>
+
+class SSPlugin{
+private:
+ QString currentfile;
+
+public:
+ QJsonObject data; //Hazardous to manually modify
+
+ SSPlugin();
+ ~SSPlugin();
+
+ void loadFile(QString path);
+ bool isLoaded();
+
+ bool isValid();
+
+ QString translatedName();
+ QString translatedDescription();
+ QUrl scriptURL();
+};
+
+class SSPluginSystem{
+public:
+ static SSPlugin findPlugin(QString name);
+ static QList<SSPlugin> findAllPlugins(bool validonly = true);
+
+};
+
+#endif
diff --git a/src-qt5/src-cpp/plugins-screensaver.pri b/src-qt5/src-cpp/plugins-screensaver.pri
new file mode 100644
index 00000000..ad03f34c
--- /dev/null
+++ b/src-qt5/src-cpp/plugins-screensaver.pri
@@ -0,0 +1,4 @@
+HEADERS *= $${PWD}/plugins-screensaver.h
+SOURCES *= $${PWD}/plugins-screensaver.cpp
+
+INCLUDEPATH *= $${PWD}
diff --git a/src-qt5/src-qml/test/CPUGaugeStyle.qml b/src-qt5/src-qml/test/CPUGaugeStyle.qml
new file mode 100644
index 00000000..4728d136
--- /dev/null
+++ b/src-qt5/src-qml/test/CPUGaugeStyle.qml
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls.Styles 1.4
+
+CircularGaugeStyle {
+ id: cpugauge
+ tickmarkInset: toPixels(0.04)
+ minorTickmarkInset: tickmarkInset
+ labelStepSize: 20
+ labelInset: toPixels(0.23)
+
+ property real xCenter: outerRadius
+ property real yCenter: outerRadius
+ property real needleLength: outerRadius - tickmarkInset * 1.25
+ property real needleTipWidth: toPixels(0.02)
+ property real needleBaseWidth: toPixels(0.06)
+ property bool halfGauge: false
+
+ function toPixels(percentage) {
+ return percentage * outerRadius;
+ }
+
+ function degToRad(degrees) {
+ return degrees * (Math.PI / 180);
+ }
+
+ function radToDeg(radians) {
+ return radians * (180 / Math.PI);
+ }
+
+ function paintBackground(ctx) {
+ if (halfGauge) {
+ ctx.beginPath();
+ ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height / 2);
+ ctx.clip();
+ }
+
+ ctx.beginPath();
+ ctx.fillStyle = "black";
+ ctx.ellipse(0, 0, ctx.canvas.width, ctx.canvas.height);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.lineWidth = tickmarkInset;
+ ctx.strokeStyle = "black";
+ ctx.arc(xCenter, yCenter, outerRadius - ctx.lineWidth / 2, outerRadius - ctx.lineWidth / 2, 0, Math.PI * 2);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.lineWidth = tickmarkInset / 2;
+ ctx.strokeStyle = "#222";
+ ctx.arc(xCenter, yCenter, outerRadius - ctx.lineWidth / 2, outerRadius - ctx.lineWidth / 2, 0, Math.PI * 2);
+ ctx.stroke();
+
+ ctx.beginPath();
+ var gradient = ctx.createRadialGradient(xCenter, yCenter, outerRadius * 0.8, xCenter, yCenter, outerRadius);
+ gradient.addColorStop(0, Qt.rgba(1, 1, 1, 0));
+ gradient.addColorStop(0.7, Qt.rgba(1, 1, 1, 0.13));
+ gradient.addColorStop(1, Qt.rgba(1, 1, 1, 1));
+ ctx.fillStyle = gradient;
+ ctx.arc(xCenter, yCenter, outerRadius - tickmarkInset, outerRadius - tickmarkInset, 0, Math.PI * 2);
+ ctx.fill();
+ }
+
+ background: Canvas {
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+ paintBackground(ctx);
+ }
+
+ }
+
+ needle: Canvas {
+ implicitWidth: needleBaseWidth
+ implicitHeight: needleLength
+
+ property real xCenter: width / 2
+ property real yCenter: height / 2
+
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+
+ ctx.beginPath();
+ ctx.moveTo(xCenter, height);
+ ctx.lineTo(xCenter - needleBaseWidth / 2, height - needleBaseWidth / 2);
+ ctx.lineTo(xCenter - needleTipWidth / 2, 0);
+ ctx.lineTo(xCenter, yCenter - needleLength);
+ ctx.lineTo(xCenter, 0);
+ ctx.closePath();
+ ctx.fillStyle = Qt.rgba(0.66, 0, 0, 0.66);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(xCenter, height)
+ ctx.lineTo(width, height - needleBaseWidth / 2);
+ ctx.lineTo(xCenter + needleTipWidth / 2, 0);
+ ctx.lineTo(xCenter, 0);
+ ctx.closePath();
+ ctx.fillStyle = Qt.lighter(Qt.rgba(0.66, 0, 0, 0.66));
+ ctx.fill();
+ }
+ }
+
+ foreground: null
+}
diff --git a/src-qt5/src-qml/test/Clock.qml b/src-qt5/src-qml/test/Clock.qml
new file mode 100644
index 00000000..685346cb
--- /dev/null
+++ b/src-qt5/src-qml/test/Clock.qml
@@ -0,0 +1,101 @@
+import QtQuick 2.0
+import QtGraphicalEffects 1.0
+
+Item {
+ id : clock
+ width: {
+ if (ListView.view && ListView.view.width >= 400)
+ return ListView.view.width / Math.floor(ListView.view.width / 400.0);
+ else
+ return 400;
+ }
+
+ height: {
+ if (ListView.view && ListView.view.height >= 440)
+ return ListView.view.height;
+ else
+ return 440;
+ }
+
+ property alias city: cityLabel.text
+ property int hours
+ property int minutes
+ property int seconds
+ property real shift
+ property bool night: false
+ property bool internationalTime: true //Unset for local time
+
+ function timeChanged() {
+ var date = new Date;
+ hours = internationalTime ? date.getUTCHours() + Math.floor(clock.shift) : date.getHours()
+ night = ( hours < 7 || hours > 19 )
+ minutes = internationalTime ? date.getUTCMinutes() + ((clock.shift % 1) * 60) : date.getMinutes()
+ seconds = date.getUTCSeconds();
+ }
+
+ Timer {
+ interval: 100; running: true; repeat: true;
+ onTriggered: clock.timeChanged()
+ }
+
+ Item {
+ anchors.centerIn: parent
+ width: 200; height: 240
+ Rectangle { anchors.fill: parent; color: "#80ff0000"; border.color: "red"; }
+
+ Image { id: background; source: "clock.png"; visible: clock.night == false }
+ Image { source: "clock-night.png"; visible: clock.night == true }
+
+ Image {
+ x: 92.5; y: 27
+ source: "hour.png"
+ transform: Rotation {
+ id: hourRotation
+ origin.x: 7.5; origin.y: 73;
+ angle: (clock.hours * 30) + (clock.minutes * 0.5)
+ Behavior on angle {
+ SpringAnimation { spring: 2; damping: 0.2; modulus: 360 }
+ }
+ }
+ }
+
+ Image {
+ x: 93.5; y: 17
+ source: "minute.png"
+ transform: Rotation {
+ id: minuteRotation
+ origin.x: 6.5; origin.y: 83;
+ angle: clock.minutes * 6
+ Behavior on angle {
+ SpringAnimation { spring: 2; damping: 0.2; modulus: 360 }
+ }
+ }
+ }
+
+ Image {
+ x: 97.5; y: 20
+ source: "second.png"
+ transform: Rotation {
+ id: secondRotation
+ origin.x: 2.5; origin.y: 80;
+ angle: clock.seconds * 6
+ Behavior on angle {
+ SpringAnimation { spring: 2; damping: 0.2; modulus: 360 }
+ }
+ }
+ }
+
+ Image {
+ anchors.centerIn: background; source: "center.png"
+ }
+
+ Text {
+ id: cityLabel
+ y: 210; anchors.horizontalCenter: parent.horizontalCenter
+ color: "white"
+ font.family: "Helvetica"
+ font.bold: true; font.pixelSize: 16
+ style: Text.Raised; styleColor: "black"
+ }
+ }
+}
diff --git a/src-qt5/src-qml/test/File.qml b/src-qt5/src-qml/test/File.qml
new file mode 100644
index 00000000..4713a454
--- /dev/null
+++ b/src-qt5/src-qml/test/File.qml
@@ -0,0 +1,21 @@
+import QtQuick 2.0
+import Qt.labs.folderlistmodel 2.1
+
+ListView {
+ width: 200; height: 400
+
+
+ FolderListModel {
+ id: folderModel
+ folder: "/usr/local/videos"
+ }
+
+ Component {
+ id: fileDelegate
+ Text { text: fileName }
+ }
+
+ model: folderModel
+ delegate: fileDelegate
+ Component.onCompleted: { console.log(folderModel.count) }
+}
diff --git a/src-qt5/src-qml/test/ListData.h b/src-qt5/src-qml/test/ListData.h
new file mode 100644
index 00000000..7dd6f6e2
--- /dev/null
+++ b/src-qt5/src-qml/test/ListData.h
@@ -0,0 +1,41 @@
+#include <QDebug>
+#include <QApplication>
+#include <QQuickView>
+#include <QQmlEngine>
+#include <QQmlContext>
+#include <QObject>
+#include <QStringList>
+#include <QTimer>
+
+class ListData : public QObject{
+ Q_OBJECT
+ Q_PROPERTY(QList<QScreen*> list READ list NOTIFY listchanged);
+signals:
+ void listchanged();
+
+private:
+ QStringList m_list;
+ //QTimer *timer;
+ //bool increasing;
+
+private slots:
+ void changeList(){
+ /*if(m_list.isEmpty()){ increasing = true; }
+ else if(m_list.length() == 5){ increasing = false; }
+ if(increasing){ m_list << "Text - "+QString::number( m_list.length()+1 ); }
+ else{ m_list.takeAt(m_list.count()-1); }
+ emit listchanged();*/
+ }
+
+public:
+ ListData() : QObject(){
+ /*increasing = true;
+ timer = new QTimer(this);
+ timer->setInterval(1000);
+ timer->setSingleShot(false);
+ connect(timer, SIGNAL(timeout()), this, SLOT(changeList()) );
+ timer->start();*/
+ }
+
+ QList<QScreen*> list() { return QApplication::screens(); } //m_list; }
+};
diff --git a/src-qt5/src-qml/test/ListTest.qml b/src-qt5/src-qml/test/ListTest.qml
new file mode 100644
index 00000000..e6b6ba35
--- /dev/null
+++ b/src-qt5/src-qml/test/ListTest.qml
@@ -0,0 +1,19 @@
+import QtQuick 2.2
+import QtQuick.Layouts 1.3
+
+Rectangle {
+ id: canvas
+ color: "black"
+
+ ColumnLayout{
+ anchors.fill: canvas
+
+ Repeater{
+ model: cppdata.list
+ Text{
+ color: "white"
+ text: modelData
+ }
+ }
+ } //end row layout
+}
diff --git a/src-qt5/src-qml/test/Video.qml b/src-qt5/src-qml/test/Video.qml
new file mode 100644
index 00000000..e7d0626d
--- /dev/null
+++ b/src-qt5/src-qml/test/Video.qml
@@ -0,0 +1,50 @@
+import QtQuick 2.0
+import QtMultimedia 5.7
+import QtQuick.Window 2.2
+import Qt.labs.folderlistmodel 2.1
+
+Rectangle {
+ //width: Screen.width
+ //height: Screen.height
+ width: 800
+ height: 600
+ color: "black"
+
+ FolderListModel {
+ id: folderModel
+ folder: "/usr/local/videos"
+ }
+
+ Repeater {
+ model: folderModel
+ Component {
+ Item {
+ Component.onCompleted: { playlist.addItem(fileURL) }
+ }
+ }
+ }
+
+ Playlist {
+ id: playlist
+ playbackMode: Playlist.Random
+ PlaylistItem { source: "/" }
+ onError: { console.log("ERROR") }
+ }
+
+ MediaPlayer {
+ id: player
+ autoPlay: true
+ playlist: playlist
+ }
+
+ VideoOutput {
+ id: videoOutput
+ source: player
+ anchors.fill: parent
+ }
+
+ Component.onCompleted: {
+ playlist.shuffle()
+ console.log(playlist.itemCount)
+ }
+}
diff --git a/src-qt5/src-qml/test/main.cpp b/src-qt5/src-qml/test/main.cpp
new file mode 100644
index 00000000..e65c599f
--- /dev/null
+++ b/src-qt5/src-qml/test/main.cpp
@@ -0,0 +1,28 @@
+#include <QDebug>
+#include <QApplication>
+#include <QQuickView>
+
+int main(int argc, char** argv){
+ QString QMLFile;
+ for(int i=1; i<argc; i++){
+ if(QFile::exists(argv[i])){ QMLFile = QString(argv[i]); }
+ }
+ if(QMLFile.isEmpty()){
+ qDebug() << "No QML File provided!";
+ qDebug() << " Please provide a valid qml file path as an input argument";
+ return 1;
+ }
+ QApplication A(argc,argv);
+ qDebug() << "Creating base widget";
+ QQuickView base;
+ base.setResizeMode(QQuickView::SizeRootObjectToView);
+ qDebug() << "Resize base widget";
+ base.resize(1024,768);
+ qDebug() << "Load QML File:" << QMLFile;
+ base.setSource(QUrl::fromLocalFile(QMLFile));
+ qDebug() << "Start Event loop";
+ base.show();
+ int ret = A.exec();
+ qDebug() << " - Finished";
+ return ret;
+}
diff --git a/src-qt5/src-qml/test/test-basic.qml b/src-qt5/src-qml/test/test-basic.qml
new file mode 100644
index 00000000..5d21ae41
--- /dev/null
+++ b/src-qt5/src-qml/test/test-basic.qml
@@ -0,0 +1,48 @@
+import QtQuick 2.0
+import "." as QML
+
+Rectangle {
+ id: root
+ width: 800; height: 600
+ color: "#646464"
+
+ ListView {
+ id: clockview
+ anchors.fill: parent
+ orientation: ListView.Horizontal
+ cacheBuffer: 2000
+ snapMode: ListView.SnapOneItem
+ highlightRangeMode: ListView.ApplyRange
+
+ delegate: QML.Clock { city: cityName; shift: timeShift }
+ model: ListModel {
+ ListElement { cityName: "New York"; timeShift: -4 }
+ ListElement { cityName: "London"; timeShift: 0 }
+ ListElement { cityName: "Oslo"; timeShift: 1 }
+ ListElement { cityName: "Mumbai"; timeShift: 5.5 }
+ ListElement { cityName: "Tokyo"; timeShift: 9 }
+ ListElement { cityName: "Brisbane"; timeShift: 10 }
+ ListElement { cityName: "Los Angeles"; timeShift: -8 }
+ }
+ }
+
+ Image {
+ anchors.left: parent.left
+ anchors.bottom: parent.bottom
+ anchors.margins: 10
+ source: "content/arrow.png"
+ rotation: -90
+ opacity: clockview.atXBeginning ? 0 : 0.5
+ Behavior on opacity { NumberAnimation { duration: 500 } }
+ }
+
+ Image {
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ anchors.margins: 10
+ source: "content/arrow.png"
+ rotation: 90
+ opacity: clockview.atXEnd ? 0 : 0.5
+ Behavior on opacity { NumberAnimation { duration: 500 } }
+ }
+}
diff --git a/src-qt5/src-qml/test/test-cpugauge.qml b/src-qt5/src-qml/test/test-cpugauge.qml
new file mode 100644
index 00000000..1151c435
--- /dev/null
+++ b/src-qt5/src-qml/test/test-cpugauge.qml
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Window 2.1
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Extras 1.4
+
+import "." as QML
+
+Rectangle{
+ id: rootwindow
+ visible: true
+ width: 800
+ height: 600
+
+ color: "#161616"
+ property alias cpu: cpu
+
+ Item {
+ id: container
+ anchors.fill: parent
+ property real diff: 5.1
+
+ Row {
+ id: gaugeRow
+ spacing: container.width * 0.02
+ anchors.centerIn: parent
+
+ CircularGauge {
+ id: cpu
+ width: height
+ height: container.height * 0.9 - gaugeRow.spacing
+ value: 0
+ maximumValue: 100
+ anchors.verticalCenter: parent.verticalCenter
+
+ style: QML.CPUGaugeStyle {}
+
+ }
+
+ function updatevalue() {
+ if( container.diff >0 && cpu.value > (100-container.diff) ){
+ cpu.value = 100;
+ container.diff = 0 - container.diff
+ } else if( container.diff <0 && cpu.value <(0-container.diff) ){
+ cpu.value = 0;
+ container.diff = 0 - container.diff
+ } else {
+ cpu.value = cpu.value + container.diff
+ }
+ }
+
+ Timer {
+ interval: 100; running: true; repeat: true;
+ onTriggered: gaugeRow.updatevalue()
+ }
+ }
+ }
+}
diff --git a/src-qt5/src-qml/test/test.pro b/src-qt5/src-qml/test/test.pro
new file mode 100644
index 00000000..41d7d2a2
--- /dev/null
+++ b/src-qt5/src-qml/test/test.pro
@@ -0,0 +1,5 @@
+QT = core gui widgets quick quickwidgets qml
+
+TARGET = test
+
+SOURCES += main.cpp
diff --git a/src-qt5/src-qml/test/testlist.cpp b/src-qt5/src-qml/test/testlist.cpp
new file mode 100644
index 00000000..cc54c501
--- /dev/null
+++ b/src-qt5/src-qml/test/testlist.cpp
@@ -0,0 +1,37 @@
+#include <QDebug>
+#include <QApplication>
+#include <QQuickView>
+#include <QQmlEngine>
+#include <QQmlContext>
+#include <QObject>
+#include <QStringList>
+#include <QTimer>
+
+#include "ListData.h"
+
+int main(int argc, char** argv){
+ QString QMLFile;
+ for(int i=1; i<argc; i++){
+ if(QFile::exists(argv[i])){ QMLFile = QString(argv[i]); }
+ }
+ if(QMLFile.isEmpty()){
+ qDebug() << "No QML File provided!";
+ qDebug() << " Please provide a valid qml file path as an input argument";
+ return 1;
+ }
+ QApplication A(argc,argv);
+ qDebug() << "Creating base widget";
+ ListData data;
+ QQuickView base;
+ base.setResizeMode(QQuickView::SizeRootObjectToView);
+ qDebug() << "Resize base widget";
+ base.resize(1024,768);
+ base.engine()->rootContext()->setContextProperty("cppdata", &data);
+ qDebug() << "Load QML File:" << QMLFile;
+ base.setSource(QUrl::fromLocalFile(QMLFile));
+ qDebug() << "Start Event loop";
+ base.show();
+ int ret = A.exec();
+ qDebug() << " - Finished";
+ return ret;
+}
diff --git a/src-qt5/src-qml/test/testlist.pro b/src-qt5/src-qml/test/testlist.pro
new file mode 100644
index 00000000..69c7bc23
--- /dev/null
+++ b/src-qt5/src-qml/test/testlist.pro
@@ -0,0 +1,7 @@
+QT = core gui widgets quick quickwidgets qml
+
+TARGET = test
+
+SOURCES += testlist.cpp
+
+HEADERS += ListData.h
bgstack15