aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWeblate <noreply@weblate.org>2018-01-02 22:18:34 +0000
committerWeblate <noreply@weblate.org>2018-01-02 22:18:34 +0000
commit4bf6d3f38634dbb517055444a22d824d6eba99d8 (patch)
treebbe3e3e511f37222cdd9db145bde2f41a35e1260
parentTranslated using Weblate (Danish) (diff)
parentMerge remote-tracking branch 'origin/master' (diff)
downloadlumina-4bf6d3f38634dbb517055444a22d824d6eba99d8.tar.gz
lumina-4bf6d3f38634dbb517055444a22d824d6eba99d8.tar.bz2
lumina-4bf6d3f38634dbb517055444a22d824d6eba99d8.zip
Merge remote-tracking branch 'origin/master'
-rw-r--r--.gitignore19
-rw-r--r--dev-tools/systray-tester/Trayapp.h11
-rw-r--r--dev-tools/systray-tester/main.cpp1
-rw-r--r--dev-tools/systray-tester/systray-tester.pro6
-rw-r--r--icon-theme/material-design-dark/actions/cursor-pointer.svg5
-rw-r--r--icon-theme/material-design-dark/actions/cursor-text.svg5
-rw-r--r--icon-theme/material-design-dark/actions/edit-find-next.svg4
-rw-r--r--icon-theme/material-design-dark/actions/edit-find-prev.svg4
-rw-r--r--icon-theme/material-design-dark/actions/media-playback-stop-circled.svg5
-rw-r--r--icon-theme/material-design-dark/actions/presentation-play.svg5
-rw-r--r--icon-theme/material-design-light/actions/cursor-pointer.svg5
-rw-r--r--icon-theme/material-design-light/actions/cursor-text.svg5
-rw-r--r--icon-theme/material-design-light/actions/edit-find-next.svg4
-rw-r--r--icon-theme/material-design-light/actions/edit-find-prev.svg4
-rw-r--r--icon-theme/material-design-light/actions/media-playback-stop-circled.svg5
-rw-r--r--icon-theme/material-design-light/actions/presentation-play.svg5
-rwxr-xr-xmkport.sh2
-rw-r--r--port-files/FreeBSD/deskutils/lumina-archiver/Makefile2
-rw-r--r--port-files/FreeBSD/deskutils/lumina-calculator/Makefile2
-rw-r--r--port-files/FreeBSD/deskutils/lumina-fileinfo/Makefile2
-rw-r--r--port-files/FreeBSD/deskutils/lumina-fm/Makefile2
-rw-r--r--port-files/FreeBSD/deskutils/lumina-notify/Makefile2
-rw-r--r--port-files/FreeBSD/deskutils/lumina-pdf/Makefile2
-rw-r--r--port-files/FreeBSD/deskutils/lumina-screenshot/Makefile2
-rw-r--r--port-files/FreeBSD/deskutils/lumina-textedit/Makefile2
-rwxr-xr-xport-files/FreeBSD/x11/lumina-core/diffReport.sh11
-rw-r--r--port-files/FreeBSD/x11/lumina-core/pkg-plist14
-rw-r--r--port-files/FreeBSD/x11/lumina/Makefile3
-rw-r--r--src-qt5/OS-detect.pri3
-rw-r--r--src-qt5/core-utils/lumina-config/lumina-config.pro4
-rw-r--r--src-qt5/core-utils/lumina-search/lumina-search.pro4
-rw-r--r--src-qt5/core-utils/lumina-xconfig/lumina-xconfig.pro4
-rw-r--r--src-qt5/core/libLumina/ExternalProcess.h11
-rw-r--r--src-qt5/core/libLumina/LDesktopUtils.cpp53
-rw-r--r--src-qt5/core/libLumina/LUtils.pri10
-rw-r--r--src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp2
-rw-r--r--src-qt5/core/libLumina/LuminaSingleApplication.cpp4
-rw-r--r--src-qt5/core/libLumina/LuminaThemes.cpp42
-rw-r--r--src-qt5/core/libLumina/LuminaThemes.h3
-rw-r--r--src-qt5/core/libLumina/LuminaXDG.cpp1
-rw-r--r--src-qt5/core/libLumina/OSInterface-template.cpp100
-rw-r--r--src-qt5/core/libLumina/OSInterface.h136
-rw-r--r--src-qt5/core/lumina-desktop-unified/LSession.cpp17
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Grav.json25
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Grav.qml47
-rw-r--r--src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Video.qml6
-rw-r--r--src-qt5/core/lumina-desktop-unified/global-includes.h7
-rw-r--r--src-qt5/core/lumina-desktop-unified/global-objects.h9
-rw-r--r--src-qt5/core/lumina-desktop-unified/lumina-desktop.pro4
-rw-r--r--src-qt5/core/lumina-desktop-unified/main.cpp6
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp139
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h44
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri6
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.cpp44
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.h49
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp53
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h19
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp26
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.h9
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/src-cpp.pri7
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/Panel.qml26
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml5
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/Screen.qml (renamed from src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/WallpaperImage.qml)2
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri3
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc3
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp7
-rw-r--r--src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h5
-rw-r--r--src-qt5/core/lumina-desktop/defaults/desktop-background-TrueOS.jpgbin4005674 -> 2403325 bytes
-rw-r--r--src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf5
-rw-r--r--src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf3
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSFeedPlugin.cpp6
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSObjects.cpp87
-rw-r--r--src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSObjects.h6
-rw-r--r--src-qt5/core/lumina-desktop/lumina-desktop.pro4
-rw-r--r--src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp2
-rw-r--r--src-qt5/core/lumina-desktop/panel-plugins/systemstart/ItemWidget.cpp22
-rw-r--r--src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp9
-rw-r--r--src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp2
-rw-r--r--src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h2
-rw-r--r--src-qt5/core/lumina-info/lumina-info.pro4
-rw-r--r--src-qt5/core/lumina-open/lumina-open.pro4
-rw-r--r--src-qt5/core/lumina-session/lumina-session.pro2
-rw-r--r--src-qt5/core/lumina-theme-engine/lumina-theme-engine.pro3
-rw-r--r--src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss16
-rw-r--r--src-qt5/core/lumina-theme-engine/qss/traynotification-simple.qss4
-rw-r--r--src-qt5/core/lumina-theme-engine/src/lthemeengine-qtplugin/lthemeengineplatformtheme.cpp4
-rw-r--r--src-qt5/core/lumina-theme-engine/src/lthemeengine-sstest/lthemeengine-sstest.pro11
-rw-r--r--src-qt5/core/lumina-theme-engine/src/lthemeengine-sstest/main.cpp18
-rw-r--r--src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.cpp39
-rw-r--r--src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.h4
-rw-r--r--src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.ui36
-rw-r--r--src-qt5/desktop-utils/lumina-archiver/MainUI.cpp4
-rw-r--r--src-qt5/desktop-utils/lumina-archiver/MainUI.h9
-rw-r--r--src-qt5/desktop-utils/lumina-archiver/TarBackend.cpp13
-rw-r--r--src-qt5/desktop-utils/lumina-archiver/TarBackend.h2
-rw-r--r--src-qt5/desktop-utils/lumina-archiver/lumina-archiver.pro4
-rw-r--r--src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_da.ts6
-rw-r--r--src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_nl.ts34
-rw-r--r--src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_pt_BR.ts26
-rw-r--r--src-qt5/desktop-utils/lumina-calculator/lumina-calculator.pro4
-rw-r--r--src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro4
-rw-r--r--src-qt5/desktop-utils/lumina-fm/MainUI.cpp1
-rw-r--r--src-qt5/desktop-utils/lumina-fm/MainUI.ui12
-rw-r--r--src-qt5/desktop-utils/lumina-fm/lumina-fm.pro4
-rw-r--r--src-qt5/desktop-utils/lumina-fm/transferd.cpp28
-rw-r--r--src-qt5/desktop-utils/lumina-fm/transferd.h13
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_ca.ts54
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_cs.ts26
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_da.ts26
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_de.ts129
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_fi.ts102
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_hu.ts72
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_lt.ts75
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_nl.ts138
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_pt_BR.ts141
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_ru.ts22
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.pro4
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/PresentationLabel.h35
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp279
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/PrintWidget.h164
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/lumina-pdf.pro15
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/mainUI.cpp370
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/mainUI.h84
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/mainUI.ui273
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/propDialog.cpp56
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/propDialog.h25
-rw-r--r--src-qt5/desktop-utils/lumina-pdf/propDialog.ui477
-rw-r--r--src-qt5/desktop-utils/lumina-screenshot/lumina-screenshot.pro4
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/MainUI.cpp103
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/MainUI.h10
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/MainUI.ui14
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp40
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.h16
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/lumina-textedit.pro4
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp17
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h8
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntax_rules/README.md4
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntax_rules/json.syntax3
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntax_rules/python.syntax3
-rw-r--r--src-qt5/desktop-utils/lumina-textedit/syntax_rules/sh.syntax3
-rw-r--r--src-qt5/experimental/lumina-screencast/lumina-screencast.pro2
-rw-r--r--src-qt5/experimental/lumina-terminal/lumina-terminal.pro2
-rw-r--r--src-qt5/src-cpp/framework-OSInterface-template.cpp150
-rw-r--r--src-qt5/src-cpp/framework-OSInterface.h190
-rw-r--r--src-qt5/src-cpp/framework-OSInterface.pri9
-rw-r--r--src-qt5/src-cpp/framework-OSInterface_private.cpp110
-rw-r--r--src-qt5/src-cpp/plugins-base.cpp50
-rw-r--r--src-qt5/src-cpp/plugins-base.h107
-rw-r--r--src-qt5/src-cpp/plugins-base.pri8
-rw-r--r--src-qt5/src-cpp/plugins-desktop.cpp40
-rw-r--r--src-qt5/src-cpp/plugins-desktop.h29
-rw-r--r--src-qt5/src-cpp/plugins-screensaver.cpp118
-rw-r--r--src-qt5/src-cpp/plugins-screensaver.h37
-rw-r--r--src-qt5/src-cpp/plugins-screensaver.pri4
-rw-r--r--src-qt5/src-cpp/tests/main.cpp38
-rw-r--r--src-qt5/src-cpp/tests/test.pro7
-rw-r--r--src-qt5/src-qml/test/Grav.qml164
-rw-r--r--src-qt5/src-qml/test/Test.qml7
158 files changed, 4201 insertions, 1208 deletions
diff --git a/.gitignore b/.gitignore
index 95c5c594..7ab4a9e7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,8 @@
global.h
*.qm
Makefile.Debug
-Makefile.Release
-*.o
+Makefile.Release
+*.o
*.qmake.stash
moc_*.cpp
ui_*.h
@@ -27,6 +27,18 @@ src-qt5/desktop-utils/lumina-archiver/lumina-archiver
src-qt5/desktop-utils/lumina-calculator/lumina-calculator
src-qt5/desktop-utils/lumina-pdf/lumina-pdf
src-qt5/desktop-utils/lumina-notify/lumina-notify
+src-qt5/core/lumina-theme-engine/src/lthemeengine-qtplugin/
+src-qt5/core/lumina-theme-engine/src/lthemeengine-qtplugin/.build/
+src-qt5/core/lumina-theme-engine/src/lthemeengine-qtplugin/Makefile
+src-qt5/core/lumina-theme-engine/src/lthemeengine-qtplugin/liblthemeengine.so
+src-qt5/core/lumina-theme-engine/src/lthemeengine-sstest/Makefile
+src-qt5/core/lumina-theme-engine/src/lthemeengine-sstest/lthemeengine-sstest
+src-qt5/core/lumina-theme-engine/src/lthemeengine-style/.build/
+src-qt5/core/lumina-theme-engine/src/lthemeengine-style/Makefile
+src-qt5/core/lumina-theme-engine/src/lthemeengine-style/liblthemeengine-style.so
+src-qt5/core/lumina-theme-engine/src/lthemeengine/Makefile
+src-qt5/core/lumina-theme-engine/src/lthemeengine/lthemeengine
+src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer
src-qt5/Makefile
src-qt5/*/Makefile
src-qt5/*/*/Makefile
@@ -34,3 +46,6 @@ src-qt5/*/*/*/Makefile
dev-tools/*/Makefile
dev-tools/systray-tester/test-tray
dev-tools/test-dbus/test
+icon-theme/Makefile
+icon-theme/*/Makefile
+Makefile
diff --git a/dev-tools/systray-tester/Trayapp.h b/dev-tools/systray-tester/Trayapp.h
index a16e1127..0d2841a0 100644
--- a/dev-tools/systray-tester/Trayapp.h
+++ b/dev-tools/systray-tester/Trayapp.h
@@ -9,7 +9,7 @@
class TrayApp : public QSystemTrayIcon {
Q_OBJECT
-
+
private:
QTimer *timer;
int iconnum;
@@ -25,12 +25,13 @@ private slots:
else if(iconnum==2){ ico = "arrow-right"; iconnum=3; }
else{ico = "arrow-down"; iconnum=0; }
this->setIcon( LXDG::findIcon(ico,"") );
+ this->showMessage("Title","Some random message", QSystemTrayIcon::Information, 1500); //1.5 second popup
}
-
+
void StopTest(){
QApplication::exit(0);
}
-
+
public:
TrayApp() : QSystemTrayIcon(){
iconnum = 0;
@@ -43,9 +44,5 @@ public:
timer->start();
}
virtual ~TrayApp(){}
-
-
-
-
};
diff --git a/dev-tools/systray-tester/main.cpp b/dev-tools/systray-tester/main.cpp
index ea631894..ff14caba 100644
--- a/dev-tools/systray-tester/main.cpp
+++ b/dev-tools/systray-tester/main.cpp
@@ -22,6 +22,7 @@ int main(int argc, char *argv[]) {
}
TrayApp tray;
+ tray.setStyleSheet(background-color: #999999);
tray.show();
QApplication::setQuitOnLastWindowClosed(false);
return a.exec();
diff --git a/dev-tools/systray-tester/systray-tester.pro b/dev-tools/systray-tester/systray-tester.pro
index b1169ae1..58fe233a 100644
--- a/dev-tools/systray-tester/systray-tester.pro
+++ b/dev-tools/systray-tester/systray-tester.pro
@@ -3,7 +3,7 @@ LANGUAGE = C++
QT += core gui widgets
CONFIG += qt warn_on release
-LIBS += -L../../libLumina -L/usr/local/lib -lLuminaUtils
+include(../../src-qt5/core/libLumina/LuminaXDG.pri)
HEADERS += Trayapp.h
@@ -11,8 +11,4 @@ SOURCES += main.cpp
INSTALLS =
-QMAKE_LIBDIR = /usr/local/lib/qt5
-
TARGET = test-tray
-
-INCLUDEPATH+= ../../libLumina /usr/local/include
diff --git a/icon-theme/material-design-dark/actions/cursor-pointer.svg b/icon-theme/material-design-dark/actions/cursor-pointer.svg
new file mode 100644
index 00000000..2645d5e6
--- /dev/null
+++ b/icon-theme/material-design-dark/actions/cursor-pointer.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="24" height="24" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve">
+ <path fill="#FFFFFF" fill-opacity="1" stroke-linejoin="round" d="M 10,2.00001C 11.1046,2.00001 12,2.89543 12,4L 12,8.50002C 12,8.50002 14,8.25002 14,9.25002C 14,9.25002 16,9.00002 16,10C 16,10 18,9.75002 18,10.75C 18,10.75 20,10.5 20,11.5L 20,15C 20,16 17,21 17,22L 9,22C 9,22 7,15 4,13C 4,13 3,7 8,12L 8,4C 8,2.89543 8.89543,2.00001 10,2.00001 Z "/>
+</svg>
diff --git a/icon-theme/material-design-dark/actions/cursor-text.svg b/icon-theme/material-design-dark/actions/cursor-text.svg
new file mode 100644
index 00000000..362be3d1
--- /dev/null
+++ b/icon-theme/material-design-dark/actions/cursor-text.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="24" height="24" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve">
+ <path fill="#FFFFFF" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 13,19C 13,19.5523 13.4477,20 14,20L 16,20L 16,22L 13.5,22C 12.9477,22 12,21.5523 12,21C 12,21.5523 11.0523,22 10.5,22L 8,22L 8,20L 10,20C 10.5523,20 11,19.5523 11,19L 11,4.99999C 11,4.44771 10.5523,3.99999 10,3.99999L 8,4L 8,2.00001L 10.5,2.00001C 11.0523,2.00001 12,2.44772 12,3C 12,2.44772 12.9477,2.00001 13.5,2.00001L 16,2.00001L 16,4L 14,3.99999C 13.4477,3.99999 13,4.44771 13,4.99999L 13,19 Z "/>
+</svg>
diff --git a/icon-theme/material-design-dark/actions/edit-find-next.svg b/icon-theme/material-design-dark/actions/edit-find-next.svg
new file mode 100644
index 00000000..30172b6f
--- /dev/null
+++ b/icon-theme/material-design-dark/actions/edit-find-next.svg
@@ -0,0 +1,4 @@
+<svg width="48" height="48" xmlns="http://www.w3.org/2000/svg">
+ <path fill-opacity="1" stroke-linejoin="round" stroke-width="0.2" fill="#FFFFFF" id="svg_1" d="m34.875,25.3125l-1.59,0l-0.549999,-0.549999c1.959999,-2.27 3.139999,-5.220001 3.139999,-8.450001c0,-7.18 -5.82,-13 -13,-13s-13,5.82 -13,13s5.82,13 13,13c3.23,0 6.18,-1.18 8.450001,-3.129999l0.549999,0.549999l0,1.58l10,9.98l2.98,-2.98l-9.98,-10zm-12,0c-4.970001,0 -9,-4.030001 -9,-9s4.029999,-9 9,-9s9,4.03 9,9s-4.030001,9 -9,9z"/>
+ <path transform="rotate(-0.164403, 11.8047, 36.8246)" id="svg_10" d="m4.090812,43.43248l7.198387,-6.610443l-7.198387,-6.609192l4.11425,-3.776335l11.31354,10.385527l-11.31354,10.390564" fill-opacity="1" stroke-linejoin="round" stroke-width="0.2" fill="#FFFFFF"/>
+</svg>
diff --git a/icon-theme/material-design-dark/actions/edit-find-prev.svg b/icon-theme/material-design-dark/actions/edit-find-prev.svg
new file mode 100644
index 00000000..8c6a1a80
--- /dev/null
+++ b/icon-theme/material-design-dark/actions/edit-find-prev.svg
@@ -0,0 +1,4 @@
+<svg width="48" height="48" xmlns="http://www.w3.org/2000/svg">
+ <path fill="#FFFFFF" stroke-linejoin="round" stroke-width="0.2" fill-opacity="1" d="m27.687553,33.124943l-1.59,0l-0.549999,-0.549999c1.959999,-2.27 3.139999,-5.220001 3.139999,-8.450001c0,-7.18 -5.82,-13.000002 -13,-13.000002s-13,5.820002 -13,13.000002s5.82,13 13,13c3.23,0 6.18,-1.18 8.450001,-3.130001l0.549999,0.549999l0,1.580002l10.000004,9.98l2.98,-2.98l-9.980003,-10zm-12,0c-4.970001,0 -9,-4.030003 -9,-9s4.029998,-9.000002 9,-9.000002s9,4.030001 9,9.000002s-4.030001,9 -9,9z" id="svg_1"/>
+ <path fill="#FFFFFF" stroke-linejoin="round" stroke-width="0.2" fill-opacity="1" d="m27.965633,17.870171l7.198387,-6.610442l-7.198387,-6.609192l4.11425,-3.776335l11.313541,10.385527l-11.313541,10.390563" id="svg_10" transform="rotate(179.921, 35.6795, 11.2622)"/>
+</svg>
diff --git a/icon-theme/material-design-dark/actions/media-playback-stop-circled.svg b/icon-theme/material-design-dark/actions/media-playback-stop-circled.svg
new file mode 100644
index 00000000..81018723
--- /dev/null
+++ b/icon-theme/material-design-dark/actions/media-playback-stop-circled.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="24" height="24" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve">
+ <path fill="#FFFFFF" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 12.0025,2.0025C 6.475,2.0025 2.0025,6.475 2.0025,12.0025C 2.0025,17.525 6.475,22.0025 12.0025,22.0025C 17.525,22.0025 22.0025,17.525 22.0025,12.0025C 22.0025,6.475 17.525,2.0025 12.0025,2.0025 Z M 8.99875,8.99875L 15,8.99875L 15,15L 8.99875,15"/>
+</svg>
diff --git a/icon-theme/material-design-dark/actions/presentation-play.svg b/icon-theme/material-design-dark/actions/presentation-play.svg
new file mode 100644
index 00000000..4cc53d60
--- /dev/null
+++ b/icon-theme/material-design-dark/actions/presentation-play.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="24" height="24" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve">
+ <path fill="#FFFFFF" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 2,3L 10,3C 10,1.89543 10.8954,1 12,1C 13.1046,1 14,1.89543 14,3L 22,3L 22,5L 21,5L 21,16L 15.25,16L 17,22L 15,22L 13.25,16L 10.75,16L 9,22L 7,22L 8.75,16L 3,16L 3,5L 2,5L 2,3 Z M 5,5.00001L 5,14L 19,14L 19,5.00001L 5,5.00001 Z M 11.8536,11.8536C 11.7631,11.944 11.6381,12 11.5,12C 11.2239,12 11,11.7761 11,11.5L 11,7.50001C 11,7.22387 11.2239,7.00001 11.5,7.00001C 11.6381,7.00001 11.7631,7.05597 11.8536,7.14646L 13.25,8.5429C 13.569,8.86193 13.8881,9.18097 13.8881,9.50001C 13.8881,9.81905 13.569,10.1381 13.25,10.4571L 11.8536,11.8536 Z "/>
+</svg>
diff --git a/icon-theme/material-design-light/actions/cursor-pointer.svg b/icon-theme/material-design-light/actions/cursor-pointer.svg
new file mode 100644
index 00000000..7cb587f2
--- /dev/null
+++ b/icon-theme/material-design-light/actions/cursor-pointer.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="24" height="24" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve">
+ <path fill="#000000" fill-opacity="1" stroke-linejoin="round" d="M 10,2.00001C 11.1046,2.00001 12,2.89543 12,4L 12,8.50002C 12,8.50002 14,8.25002 14,9.25002C 14,9.25002 16,9.00002 16,10C 16,10 18,9.75002 18,10.75C 18,10.75 20,10.5 20,11.5L 20,15C 20,16 17,21 17,22L 9,22C 9,22 7,15 4,13C 4,13 3,7 8,12L 8,4C 8,2.89543 8.89543,2.00001 10,2.00001 Z "/>
+</svg>
diff --git a/icon-theme/material-design-light/actions/cursor-text.svg b/icon-theme/material-design-light/actions/cursor-text.svg
new file mode 100644
index 00000000..0aee782c
--- /dev/null
+++ b/icon-theme/material-design-light/actions/cursor-text.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="24" height="24" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve">
+ <path fill="#000000" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 13,19C 13,19.5523 13.4477,20 14,20L 16,20L 16,22L 13.5,22C 12.9477,22 12,21.5523 12,21C 12,21.5523 11.0523,22 10.5,22L 8,22L 8,20L 10,20C 10.5523,20 11,19.5523 11,19L 11,4.99999C 11,4.44771 10.5523,3.99999 10,3.99999L 8,4L 8,2.00001L 10.5,2.00001C 11.0523,2.00001 12,2.44772 12,3C 12,2.44772 12.9477,2.00001 13.5,2.00001L 16,2.00001L 16,4L 14,3.99999C 13.4477,3.99999 13,4.44771 13,4.99999L 13,19 Z "/>
+</svg>
diff --git a/icon-theme/material-design-light/actions/edit-find-next.svg b/icon-theme/material-design-light/actions/edit-find-next.svg
new file mode 100644
index 00000000..e0391248
--- /dev/null
+++ b/icon-theme/material-design-light/actions/edit-find-next.svg
@@ -0,0 +1,4 @@
+<svg width="48" height="48" xmlns="http://www.w3.org/2000/svg">
+ <path fill-opacity="1" stroke-linejoin="round" stroke-width="0.2" fill="#000000" id="svg_1" d="m34.875,25.3125l-1.59,0l-0.549999,-0.549999c1.959999,-2.27 3.139999,-5.220001 3.139999,-8.450001c0,-7.18 -5.82,-13 -13,-13s-13,5.82 -13,13s5.82,13 13,13c3.23,0 6.18,-1.18 8.450001,-3.129999l0.549999,0.549999l0,1.58l10,9.98l2.98,-2.98l-9.98,-10zm-12,0c-4.970001,0 -9,-4.030001 -9,-9s4.029999,-9 9,-9s9,4.03 9,9s-4.030001,9 -9,9z"/>
+ <path transform="rotate(-0.164403, 11.8047, 36.8246)" id="svg_10" d="m4.090812,43.43248l7.198387,-6.610443l-7.198387,-6.609192l4.11425,-3.776335l11.31354,10.385527l-11.31354,10.390564" fill-opacity="1" stroke-linejoin="round" stroke-width="0.2" fill="#000000"/>
+</svg>
diff --git a/icon-theme/material-design-light/actions/edit-find-prev.svg b/icon-theme/material-design-light/actions/edit-find-prev.svg
new file mode 100644
index 00000000..d1288685
--- /dev/null
+++ b/icon-theme/material-design-light/actions/edit-find-prev.svg
@@ -0,0 +1,4 @@
+<svg width="48" height="48" xmlns="http://www.w3.org/2000/svg">
+ <path fill="#000000" stroke-linejoin="round" stroke-width="0.2" fill-opacity="1" d="m27.687553,33.124943l-1.59,0l-0.549999,-0.549999c1.959999,-2.27 3.139999,-5.220001 3.139999,-8.450001c0,-7.18 -5.82,-13.000002 -13,-13.000002s-13,5.820002 -13,13.000002s5.82,13 13,13c3.23,0 6.18,-1.18 8.450001,-3.130001l0.549999,0.549999l0,1.580002l10.000004,9.98l2.98,-2.98l-9.980003,-10zm-12,0c-4.970001,0 -9,-4.030003 -9,-9s4.029998,-9.000002 9,-9.000002s9,4.030001 9,9.000002s-4.030001,9 -9,9z" id="svg_1"/>
+ <path fill="#000000" stroke-linejoin="round" stroke-width="0.2" fill-opacity="1" d="m27.965633,17.870171l7.198387,-6.610442l-7.198387,-6.609192l4.11425,-3.776335l11.313541,10.385527l-11.313541,10.390563" id="svg_10" transform="rotate(179.921, 35.6795, 11.2622)"/>
+</svg>
diff --git a/icon-theme/material-design-light/actions/media-playback-stop-circled.svg b/icon-theme/material-design-light/actions/media-playback-stop-circled.svg
new file mode 100644
index 00000000..9d0f56fe
--- /dev/null
+++ b/icon-theme/material-design-light/actions/media-playback-stop-circled.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="24" height="24" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve">
+ <path fill="#000000" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 12.0025,2.0025C 6.475,2.0025 2.0025,6.475 2.0025,12.0025C 2.0025,17.525 6.475,22.0025 12.0025,22.0025C 17.525,22.0025 22.0025,17.525 22.0025,12.0025C 22.0025,6.475 17.525,2.0025 12.0025,2.0025 Z M 8.99875,8.99875L 15,8.99875L 15,15L 8.99875,15"/>
+</svg>
diff --git a/icon-theme/material-design-light/actions/presentation-play.svg b/icon-theme/material-design-light/actions/presentation-play.svg
new file mode 100644
index 00000000..f2a0dd74
--- /dev/null
+++ b/icon-theme/material-design-light/actions/presentation-play.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="24" height="24" viewBox="0 0 24.00 24.00" enable-background="new 0 0 24.00 24.00" xml:space="preserve">
+ <path fill="#000000" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 2,3L 10,3C 10,1.89543 10.8954,1 12,1C 13.1046,1 14,1.89543 14,3L 22,3L 22,5L 21,5L 21,16L 15.25,16L 17,22L 15,22L 13.25,16L 10.75,16L 9,22L 7,22L 8.75,16L 3,16L 3,5L 2,5L 2,3 Z M 5,5.00001L 5,14L 19,14L 19,5.00001L 5,5.00001 Z M 11.8536,11.8536C 11.7631,11.944 11.6381,12 11.5,12C 11.2239,12 11,11.7761 11,11.5L 11,7.50001C 11,7.22387 11.2239,7.00001 11.5,7.00001C 11.6381,7.00001 11.7631,7.05597 11.8536,7.14646L 13.25,8.5429C 13.569,8.86193 13.8881,9.18097 13.8881,9.50001C 13.8881,9.81905 13.569,10.1381 13.25,10.4571L 11.8536,11.8536 Z "/>
+</svg>
diff --git a/mkport.sh b/mkport.sh
index 3c6ed8bd..fe8b85e1 100755
--- a/mkport.sh
+++ b/mkport.sh
@@ -4,7 +4,7 @@
# Set the port
dfile="lumina"
-VERSION="1.4.0"
+VERSION="1.4.1"
massage_subdir() {
cd "$1"
diff --git a/port-files/FreeBSD/deskutils/lumina-archiver/Makefile b/port-files/FreeBSD/deskutils/lumina-archiver/Makefile
index 97657f2d..04e7ee40 100644
--- a/port-files/FreeBSD/deskutils/lumina-archiver/Makefile
+++ b/port-files/FreeBSD/deskutils/lumina-archiver/Makefile
@@ -20,9 +20,9 @@ I18N_DESC= Install localization files
MAKE_JOBS_UNSAFE=yes
+USES= qmake
USE_QT5= core gui widgets network svg \
buildtools_build x11extras concurrent multimedia
-USES= qmake
USE_GITHUB= yes
GH_ACCOUNT= trueos
GH_PROJECT= lumina
diff --git a/port-files/FreeBSD/deskutils/lumina-calculator/Makefile b/port-files/FreeBSD/deskutils/lumina-calculator/Makefile
index 782a9679..b3bd03ff 100644
--- a/port-files/FreeBSD/deskutils/lumina-calculator/Makefile
+++ b/port-files/FreeBSD/deskutils/lumina-calculator/Makefile
@@ -25,11 +25,11 @@ I18N_DESC= Install localization files
MAKE_JOBS_UNSAFE=yes
+USES= qmake
USE_GL= gl
USE_XORG= x11 xdamage xcb
USE_QT5= core gui widgets network svg \
buildtools_build x11extras concurrent multimedia
-USES= qmake
USE_GITHUB= yes
GH_ACCOUNT= trueos
GH_PROJECT= lumina
diff --git a/port-files/FreeBSD/deskutils/lumina-fileinfo/Makefile b/port-files/FreeBSD/deskutils/lumina-fileinfo/Makefile
index 88888925..180305c6 100644
--- a/port-files/FreeBSD/deskutils/lumina-fileinfo/Makefile
+++ b/port-files/FreeBSD/deskutils/lumina-fileinfo/Makefile
@@ -20,9 +20,9 @@ I18N_DESC= Install localization files
MAKE_JOBS_UNSAFE=yes
+USES= qmake
USE_QT5= core gui widgets network svg \
buildtools_build x11extras concurrent multimedia
-USES= qmake
USE_GITHUB= yes
GH_ACCOUNT= trueos
GH_PROJECT= lumina
diff --git a/port-files/FreeBSD/deskutils/lumina-fm/Makefile b/port-files/FreeBSD/deskutils/lumina-fm/Makefile
index 172411e3..14c5bf98 100644
--- a/port-files/FreeBSD/deskutils/lumina-fm/Makefile
+++ b/port-files/FreeBSD/deskutils/lumina-fm/Makefile
@@ -20,9 +20,9 @@ I18N_DESC= Install localization files
MAKE_JOBS_UNSAFE=yes
+USES= qmake
USE_QT5= core gui widgets network svg imageformats \
buildtools_build x11extras multimedia concurrent
-USES= qmake
USE_GITHUB= yes
GH_ACCOUNT= trueos
GH_PROJECT= lumina
diff --git a/port-files/FreeBSD/deskutils/lumina-notify/Makefile b/port-files/FreeBSD/deskutils/lumina-notify/Makefile
index b9c28382..5fd3e3e0 100644
--- a/port-files/FreeBSD/deskutils/lumina-notify/Makefile
+++ b/port-files/FreeBSD/deskutils/lumina-notify/Makefile
@@ -18,9 +18,9 @@ I18N_DESC= Install localization files
MAKE_JOBS_UNSAFE=yes
+USES= qmake
USE_QT5= core gui widgets network svg \
buildtools_build x11extras concurrent multimedia
-USES= qmake
USE_GITHUB= yes
GH_ACCOUNT= trueos
GH_PROJECT= lumina
diff --git a/port-files/FreeBSD/deskutils/lumina-pdf/Makefile b/port-files/FreeBSD/deskutils/lumina-pdf/Makefile
index d6789389..ab45ab1b 100644
--- a/port-files/FreeBSD/deskutils/lumina-pdf/Makefile
+++ b/port-files/FreeBSD/deskutils/lumina-pdf/Makefile
@@ -22,9 +22,9 @@ I18N_DESC= Install localization files
MAKE_JOBS_UNSAFE=yes
+USES= qmake
USE_QT5= core gui widgets network svg multimedia \
buildtools_build x11extras concurrent printsupport
-USES= qmake
USE_GITHUB= yes
GH_ACCOUNT= trueos
GH_PROJECT= lumina
diff --git a/port-files/FreeBSD/deskutils/lumina-screenshot/Makefile b/port-files/FreeBSD/deskutils/lumina-screenshot/Makefile
index 84bc1e39..7ab6bbb2 100644
--- a/port-files/FreeBSD/deskutils/lumina-screenshot/Makefile
+++ b/port-files/FreeBSD/deskutils/lumina-screenshot/Makefile
@@ -20,9 +20,9 @@ I18N_DESC= Install localization files
MAKE_JOBS_UNSAFE=yes
+USES= qmake
USE_QT5= core gui widgets network svg \
buildtools_build x11extras concurrent multimedia
-USES= qmake
USE_GITHUB= yes
GH_ACCOUNT= trueos
GH_PROJECT= lumina
diff --git a/port-files/FreeBSD/deskutils/lumina-textedit/Makefile b/port-files/FreeBSD/deskutils/lumina-textedit/Makefile
index 472d0069..554f5fcb 100644
--- a/port-files/FreeBSD/deskutils/lumina-textedit/Makefile
+++ b/port-files/FreeBSD/deskutils/lumina-textedit/Makefile
@@ -20,9 +20,9 @@ I18N_DESC= Install localization files
MAKE_JOBS_UNSAFE=yes
+USES= qmake
USE_QT5= core gui widgets network svg \
buildtools_build x11extras concurrent multimedia
-USES= qmake
USE_GITHUB= yes
GH_ACCOUNT= trueos
GH_PROJECT= lumina
diff --git a/port-files/FreeBSD/x11/lumina-core/diffReport.sh b/port-files/FreeBSD/x11/lumina-core/diffReport.sh
new file mode 100755
index 00000000..fc550c88
--- /dev/null
+++ b/port-files/FreeBSD/x11/lumina-core/diffReport.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+echo "Running for Light Directory"
+(find ~/lumina/icon-theme/material-design-light/*/*.svg | sed 's/.*material/material/' | sort) > currentFiles
+(grep -rn material-design-light ./pkg-plist | sed 's/.*material/material/g' | sed 's/scalable\///' | sort) > darkFiles
+diff currentFiles darkFiles
+rm currentFiles darkFiles
+echo "Running for Dark Directory"
+(find ~/lumina/icon-theme/material-design-dark/*/*.svg | sed 's/.*material/material/' | sort) > currentFiles
+(grep -rn material-design-dark ./pkg-plist | sed 's/.*material/material/g' | sed 's/scalable\///' | sort) > darkFiles
+diff currentFiles darkFiles
+rm currentFiles darkFiles
diff --git a/port-files/FreeBSD/x11/lumina-core/pkg-plist b/port-files/FreeBSD/x11/lumina-core/pkg-plist
index ae266444..9aad7f66 100644
--- a/port-files/FreeBSD/x11/lumina-core/pkg-plist
+++ b/port-files/FreeBSD/x11/lumina-core/pkg-plist
@@ -1,4 +1,5 @@
bin/lthemeengine
+bin/lthemeengine-sstest
bin/lumina-desktop
bin/lumina-info
bin/lumina-open
@@ -133,6 +134,8 @@ share/icons/material-design-dark/scalable/actions/configure.svg
share/icons/material-design-dark/scalable/actions/contact-mail.svg
share/icons/material-design-dark/scalable/actions/contact-new.svg
share/icons/material-design-dark/scalable/actions/contact-phone.svg
+share/icons/material-design-dark/scalable/actions/cursor-pointer.svg
+share/icons/material-design-dark/scalable/actions/cursor-text.svg
share/icons/material-design-dark/scalable/actions/dashboard-show.svg
share/icons/material-design-dark/scalable/actions/dialog-cancel.svg
share/icons/material-design-dark/scalable/actions/dialog-close.svg
@@ -168,6 +171,8 @@ share/icons/material-design-dark/scalable/actions/edit-clear.svg
share/icons/material-design-dark/scalable/actions/edit-copy.svg
share/icons/material-design-dark/scalable/actions/edit-cut.svg
share/icons/material-design-dark/scalable/actions/edit-delete.svg
+share/icons/material-design-dark/scalable/actions/edit-find-prev.svg
+share/icons/material-design-dark/scalable/actions/edit-find-next.svg
share/icons/material-design-dark/scalable/actions/edit-find-page.svg
share/icons/material-design-dark/scalable/actions/edit-find-replace.svg
share/icons/material-design-dark/scalable/actions/edit-find.svg
@@ -275,6 +280,7 @@ share/icons/material-design-dark/scalable/actions/media-playback-slow.svg
share/icons/material-design-dark/scalable/actions/media-playback-start-circled.svg
share/icons/material-design-dark/scalable/actions/media-playback-start.svg
share/icons/material-design-dark/scalable/actions/media-playback-stop.svg
+share/icons/material-design-dark/scalable/actions/media-playback-stop-circled.svg
share/icons/material-design-dark/scalable/actions/media-record.svg
share/icons/material-design-dark/scalable/actions/media-seek-backward.svg
share/icons/material-design-dark/scalable/actions/media-seek-forward.svg
@@ -298,6 +304,7 @@ share/icons/material-design-dark/scalable/actions/object-flip-horizontal.svg
share/icons/material-design-dark/scalable/actions/object-flip-vertical.svg
share/icons/material-design-dark/scalable/actions/object-rotate-left.svg
share/icons/material-design-dark/scalable/actions/object-rotate-right.svg
+share/icons/material-design-dark/scalable/actions/presentation-play.svg
share/icons/material-design-dark/scalable/actions/process-stop.svg
share/icons/material-design-dark/scalable/actions/quickopen-file.svg
share/icons/material-design-dark/scalable/actions/quickopen.svg
@@ -947,6 +954,8 @@ share/icons/material-design-light/scalable/actions/configure.svg
share/icons/material-design-light/scalable/actions/contact-mail.svg
share/icons/material-design-light/scalable/actions/contact-new.svg
share/icons/material-design-light/scalable/actions/contact-phone.svg
+share/icons/material-design-light/scalable/actions/cursor-pointer.svg
+share/icons/material-design-light/scalable/actions/cursor-text.svg
share/icons/material-design-light/scalable/actions/dashboard-show.svg
share/icons/material-design-light/scalable/actions/dialog-cancel.svg
share/icons/material-design-light/scalable/actions/dialog-close.svg
@@ -982,6 +991,8 @@ share/icons/material-design-light/scalable/actions/edit-clear.svg
share/icons/material-design-light/scalable/actions/edit-copy.svg
share/icons/material-design-light/scalable/actions/edit-cut.svg
share/icons/material-design-light/scalable/actions/edit-delete.svg
+share/icons/material-design-light/scalable/actions/edit-find-prev.svg
+share/icons/material-design-light/scalable/actions/edit-find-next.svg
share/icons/material-design-light/scalable/actions/edit-find-page.svg
share/icons/material-design-light/scalable/actions/edit-find-replace.svg
share/icons/material-design-light/scalable/actions/edit-find.svg
@@ -1089,6 +1100,7 @@ share/icons/material-design-light/scalable/actions/media-playback-slow.svg
share/icons/material-design-light/scalable/actions/media-playback-start-circled.svg
share/icons/material-design-light/scalable/actions/media-playback-start.svg
share/icons/material-design-light/scalable/actions/media-playback-stop.svg
+share/icons/material-design-light/scalable/actions/media-playback-stop-circled.svg
share/icons/material-design-light/scalable/actions/media-record.svg
share/icons/material-design-light/scalable/actions/media-seek-backward.svg
share/icons/material-design-light/scalable/actions/media-seek-forward.svg
@@ -1112,6 +1124,7 @@ share/icons/material-design-light/scalable/actions/object-flip-horizontal.svg
share/icons/material-design-light/scalable/actions/object-flip-vertical.svg
share/icons/material-design-light/scalable/actions/object-rotate-left.svg
share/icons/material-design-light/scalable/actions/object-rotate-right.svg
+share/icons/material-design-light/scalable/actions/presentation-play.svg
share/icons/material-design-light/scalable/actions/process-stop.svg
share/icons/material-design-light/scalable/actions/quickopen-file.svg
share/icons/material-design-light/scalable/actions/quickopen.svg
@@ -1652,6 +1665,7 @@ share/lthemeengine/desktop_qss/Glass.qss
share/lthemeengine/qss/scrollbar-simple.qss
share/lthemeengine/qss/sliders-simple.qss
share/lthemeengine/qss/tooltip-simple.qss
+share/lthemeengine/qss/traynotification-simple.qss
share/lumina-desktop/Login.ogg
share/lumina-desktop/Logout.ogg
share/lumina-desktop/compton.conf
diff --git a/port-files/FreeBSD/x11/lumina/Makefile b/port-files/FreeBSD/x11/lumina/Makefile
index 0231102c..55851441 100644
--- a/port-files/FreeBSD/x11/lumina/Makefile
+++ b/port-files/FreeBSD/x11/lumina/Makefile
@@ -20,8 +20,7 @@ RUN_DEPENDS= lumina-core>=0:x11/lumina-core \
lumina-mediaplayer>=0:deskutils/lumina-mediaplayer \
lumina-pdf>=0:deskutils/lumina-pdf \
lumina-screenshot>=0:deskutils/lumina-screenshot \
- lumina-textedit>=0:deskutils/lumina-textedit \
- lumina-themes>=0:x11-themes/lumina-themes
+ lumina-textedit>=0:deskutils/lumina-textedit
CONFLICTS_INSTALL= lumina-1.2.*
diff --git a/src-qt5/OS-detect.pri b/src-qt5/OS-detect.pri
index 3d01ea5f..f7c65d6f 100644
--- a/src-qt5/OS-detect.pri
+++ b/src-qt5/OS-detect.pri
@@ -81,9 +81,6 @@ isEmpty(OS){
isEmpty(L_ETCDIR){ L_ETCDIR = $${PREFIX}/../etc }
isEmpty(L_MANDIR){ L_MANDIR = $${PREFIX}/share/man }
}
- equals(LINUX_DISTRO,"Ubuntu"){
- INCLUDEPATH *= /usr/include/poppler/qt5
- }
}else{
OS="Unknown";
}
diff --git a/src-qt5/core-utils/lumina-config/lumina-config.pro b/src-qt5/core-utils/lumina-config/lumina-config.pro
index 35f4b981..f36f67d6 100644
--- a/src-qt5/core-utils/lumina-config/lumina-config.pro
+++ b/src-qt5/core-utils/lumina-config/lumina-config.pro
@@ -115,13 +115,13 @@ TRANSLATIONS = i18n/lumina-config_af.ts \
i18n/lumina-config_zu.ts
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
-dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
+dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
desktop.files=lumina-config.desktop
desktop.path=$${L_SHAREDIR}/applications/
manpage.path=$${L_MANDIR}/man1/
-manpage.extra="$${MAN_ZIP} lumina-config.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-config.1.gz"
+manpage.extra="$${MAN_ZIP} $$PWD/lumina-config.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-config.1.gz"
INSTALLS += target desktop manpage
diff --git a/src-qt5/core-utils/lumina-search/lumina-search.pro b/src-qt5/core-utils/lumina-search/lumina-search.pro
index a8ea4060..42014c69 100644
--- a/src-qt5/core-utils/lumina-search/lumina-search.pro
+++ b/src-qt5/core-utils/lumina-search/lumina-search.pro
@@ -93,13 +93,13 @@ TRANSLATIONS = i18n/lumina-search_af.ts \
i18n/lumina-search_zu.ts
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
-dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
+dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
desktop.files=lumina-search.desktop
desktop.path=$${L_SHAREDIR}/applications/
manpage.path=$${L_MANDIR}/man1/
-manpage.extra="$${MAN_ZIP} lumina-search.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-search.1.gz"
+manpage.extra="$${MAN_ZIP} $$PWD/lumina-search.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-search.1.gz"
INSTALLS += target desktop manpage
diff --git a/src-qt5/core-utils/lumina-xconfig/lumina-xconfig.pro b/src-qt5/core-utils/lumina-xconfig/lumina-xconfig.pro
index 73399ee7..c6af2c3f 100644
--- a/src-qt5/core-utils/lumina-xconfig/lumina-xconfig.pro
+++ b/src-qt5/core-utils/lumina-xconfig/lumina-xconfig.pro
@@ -89,13 +89,13 @@ TRANSLATIONS = i18n/lumina-xconfig_af.ts \
i18n/lumina-xconfig_zu.ts
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
-dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
+dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
desktop.files=lumina-xconfig.desktop
desktop.path=$${L_SHAREDIR}/applications/
manpage.path=$${L_MANDIR}/man1/
-manpage.extra="$${MAN_ZIP} lumina-xconfig.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-xconfig.1.gz"
+manpage.extra="$${MAN_ZIP} $$PWD/lumina-xconfig.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-xconfig.1.gz"
INSTALLS += target desktop manpage
diff --git a/src-qt5/core/libLumina/ExternalProcess.h b/src-qt5/core/libLumina/ExternalProcess.h
index 2a6f4949..e75d6108 100644
--- a/src-qt5/core/libLumina/ExternalProcess.h
+++ b/src-qt5/core/libLumina/ExternalProcess.h
@@ -21,6 +21,7 @@ class ExternalProcess : public QProcess{
Q_OBJECT
private:
bool cursorRestored;
+ QString logoutput;
private slots:
void resetCursor(){
@@ -46,6 +47,9 @@ private slots:
//Clean up this object
this->deleteLater();
}
+ void updateLog(){
+ logoutput.append( QString(this->readAllStandardOutput()) );
+ }
public:
ExternalProcess(QString logfile = "", bool manageCursors = false) : QProcess(){
@@ -53,6 +57,8 @@ public:
cursorRestored = !manageCursors;
if(logfile.isEmpty()){
this->setStandardOutputFile(QProcess::nullDevice());
+ }else if(logfile=="stdout"){
+ connect(this, SIGNAL(readyReadStandardOutput()), this, SLOT(updateLog()) );
}else{
this->setStandardOutputFile(logfile);
}
@@ -67,6 +73,11 @@ public:
}*/
}
+ QString log(){
+ //NOTE: This will only contain output if the "stdout" argument is used as the logfile
+ return logoutput;
+ }
+
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);
diff --git a/src-qt5/core/libLumina/LDesktopUtils.cpp b/src-qt5/core/libLumina/LDesktopUtils.cpp
index 69d4ba52..5595532a 100644
--- a/src-qt5/core/libLumina/LDesktopUtils.cpp
+++ b/src-qt5/core/libLumina/LDesktopUtils.cpp
@@ -13,10 +13,8 @@
#include "LuminaThemes.h"
-static QStringList fav;
-
QString LDesktopUtils::LuminaDesktopVersion(){
- QString ver = "1.4.0";
+ QString ver = "1.4.1";
#ifdef GIT_VERSION
ver.append( QString(" (Git Revision: %1)").arg(GIT_VERSION) );
#endif
@@ -80,22 +78,23 @@ QStringList LDesktopUtils::infoQuickPlugin(QString ID){ //Returns: [Name, Descri
}
QStringList LDesktopUtils::listFavorites(){
- static QDateTime lastRead;
- QDateTime cur = QDateTime::currentDateTime();
- if(lastRead.isNull() || lastRead<QFileInfo( QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/favorites.list").lastModified()){
+ //static QDateTime lastRead;
+ QStringList fav;
+ //QDateTime cur = QDateTime::currentDateTime();
+ //if(lastRead.isNull() || fav.isEmpty() || lastRead<QFileInfo( QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/favorites.list").lastModified()){
fav = LUtils::readFile(QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/favorites.list");
fav.removeAll(""); //remove any empty lines
fav.removeDuplicates();
- lastRead = cur;
- }
-
+ //lastRead = cur;
+ //}
return fav;
}
bool LDesktopUtils::saveFavorites(QStringList list){
list.removeDuplicates();
+ //qDebug() << "Save Favorites:" << list;
bool ok = LUtils::writeFile(QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/favorites.list", list, true);
- if(ok){ fav = list; } //also save internally in case of rapid write/read of the file
+ //if(ok){ fav = list; } //also save internally in case of rapid write/read of the file
return ok;
}
@@ -116,11 +115,13 @@ bool LDesktopUtils::addFavorite(QString path, QString name){
else{ type = LXDG::findAppMimeForFile(path); }
//Assign a name if none given
if(name.isEmpty()){ name = info.fileName(); }
+ //qDebug() << "Add Favorite:" << path << type << name;
//Now add it to the list
QStringList favs = LDesktopUtils::listFavorites();
+ //qDebug() << "Current Favorites:" << favs;
bool found = false;
for(int i=0; i<favs.length(); i++){
- if(favs[i].endsWith("::::"+path)){ favs[i] = name+"::::"+type+"::::"+path; }
+ if(favs[i].endsWith("::::"+path)){ favs[i] = name+"::::"+type+"::::"+path; found = true; }
}
if(!found){ favs << name+"::::"+type+"::::"+path; }
return LDesktopUtils::saveFavorites(favs);
@@ -143,8 +144,15 @@ void LDesktopUtils::upgradeFavorites(int){ //fromoldversionnumber
void LDesktopUtils::LoadSystemDefaults(bool skipOS){
//Will create the Lumina configuration files based on the current system template (if any)
qDebug() << "Loading System Defaults";
+ //Ensure that the settings directory exists
+ QString setdir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop";
+ if(!QFile::exists(setdir)){
+ QDir dir;
+ dir.mkpath(setdir);
+ }
+
bool skipmime = QFile::exists( QString(getenv("XDG_CONFIG_HOME"))+"/lumina-mimapps.list" );
- qDebug() << " - Skipping mimetype default apps" << skipmime;
+ //qDebug() << " - Skipping mimetype default apps" << skipmime;
QStringList sysDefaults;
if(!skipOS){ sysDefaults = LUtils::readFile(LOS::AppPrefix()+"etc/luminaDesktop.conf"); }
if(sysDefaults.isEmpty() && !skipOS){ sysDefaults = LUtils::readFile(LOS::AppPrefix()+"etc/luminaDesktop.conf.dist"); }
@@ -187,6 +195,8 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){
if(var.endsWith("_ifexists") ){
var = var.remove("_ifexists"); //remove this flag from the variable
//Check if the value exists (absolute path only)
+ val = LUtils::AppToAbsolute(val);
+ //qDebug() << "Checking if favorite app exists:" << val;
if(!QFile::exists(val)){ continue; } //skip this line - value/file does not exist
}
@@ -231,20 +241,23 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){
if(tmp[i].startsWith("#") || !tmp[i].contains("=") ){ continue; }
QString var = tmp[i].section("=",0,0).toLower().simplified();
QString val = tmp[i].section("=",1,1).section("#",0,0).simplified();
+ qDebug() << "Mime entry:" << var << val;
if(val.isEmpty()){ continue; }
QString istrue = (val.toLower()=="true") ? "true": "false";
//Change in 0.8.5 - use "_" instead of "." within variables names - need backwards compat for a little while
if(var.contains(".")){ var.replace(".","_"); }
//Now parse the variable and put the value in the proper file
- val = LUtils::AppToAbsolute(val);
//Special handling for values which need to exist first
if(var.endsWith("_ifexists") ){
var = var.remove("_ifexists"); //remove this flag from the variable
+ val = LUtils::AppToAbsolute(val);
+ //qDebug() << "Checking if Mime app exists:" << val;
//Check if the value exists (absolute path only)
if(!QFile::exists(val)){ continue; } //skip this line - value/file does not exist
}
//Now turn this variable into the mimetype only
var = var.section("_default_",1,-1);
+ //qDebug() << " - Set Default Mime:" << var << val;
LXDG::setDefaultAppForMime(var, val);
}
@@ -326,6 +339,7 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){
tmp = sysDefaults.filter("favorites_");
if(tmp.isEmpty()){ tmp = sysDefaults.filter("favorites."); }
for(int i=0; i<tmp.length(); i++){
+ //qDebug() << "Found Favorite Entry:" << tmp[i];
if(tmp[i].startsWith("#") || !tmp[i].contains("=") ){ continue; }
QString var = tmp[i].section("=",0,0).toLower().simplified();
QString val = tmp[i].section("=",1,1).section("#",0,0).simplified();
@@ -334,7 +348,7 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){
//Now parse the variable and put the value in the proper file
qDebug() << "Favorite entry:" << var << val;
val = LUtils::AppToAbsolute(val); //turn any relative files into absolute
- if(var=="favorites_add_ifexists" && QFile::exists(val)){ qDebug() << " - Exists/Adding:"; LDesktopUtils::addFavorite(val); }
+ if(var=="favorites_add_ifexists" && QFile::exists(val)){ qDebug() << " - Exists/Adding:" << val; LDesktopUtils::addFavorite(val); }
else if(var=="favorites_add"){ qDebug() << " - Adding:"; LDesktopUtils::addFavorite(val); }
else if(var=="favorites_remove"){ qDebug() << " - Removing:"; LDesktopUtils::removeFavorite(val); }
}
@@ -385,6 +399,7 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){
if(var.contains(".")){ var.replace(".","_"); }
//Now parse the variable and put the value in the proper file
if(var=="theme_themefile"){ themesettings[0] = val; }
+ else if(var=="theme_styles"){ LTHEME::setCurrentStyles( val.split(",",QString::SkipEmptyParts) ); }
else if(var=="theme_colorfile"){ themesettings[1] = val; }
else if(var=="theme_iconset"){ themesettings[2] = val; }
else if(var=="theme_font"){ themesettings[3] = val; }
@@ -425,12 +440,6 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){
}
//qDebug() << " - Final Theme Color:" << themesettings[1];
- //Ensure that the settings directory exists
- QString setdir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop";
- if(!QFile::exists(setdir)){
- QDir dir;
- dir.mkpath(setdir);
- }
//Now save the settings files
if(setTheme){
LTHEME::setCurrentSettings( themesettings[0], themesettings[1], themesettings[2], themesettings[3], themesettings[4]);
@@ -538,7 +547,7 @@ bool LDesktopUtils::checkUserFiles(QString lastversion, QString currentversion){
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.setValue("Interface/stylesheets", QStringList() << enginedir+"qss/tooltip-simple.qss" << enginedir+"qss/scrollbar-simple.qss" << enginedir+"qss/sliders-simple.qss" << enginedir+"qss/traynotification-simple.qss");
newtheme.sync(); //flush this to file right now
} //end check for theme file existance
}
@@ -569,7 +578,7 @@ bool LDesktopUtils::checkUserFiles(QString lastversion, QString currentversion){
}
int LDesktopUtils::VersionStringToNumber(QString version){
- version = version.section("-",0,0); //trim any extra labels off the end
+ version = version.section("_",0,0).section("-",0,0); //trim any extra labels off the end
int maj, mid, min; //major/middle/minor version numbers (<Major>.<Middle>.<Minor>)
maj = mid = min = 0;
bool ok = true;
diff --git a/src-qt5/core/libLumina/LUtils.pri b/src-qt5/core/libLumina/LUtils.pri
index 6ce0839c..da5a78d5 100644
--- a/src-qt5/core/libLumina/LUtils.pri
+++ b/src-qt5/core/libLumina/LUtils.pri
@@ -15,8 +15,7 @@ GIT_VERSION=$$system(git describe --always)
#DEFINES += BUILD_DATE='"\\\"$$system(date)\\\""'
#LuminaOS files
-HEADERS *= $${PWD}/LuminaOS.h \
- $${PWD}/OSInterface.h
+HEADERS *= $${PWD}/LuminaOS.h
# LuminaOS support functions (or fall back to generic one)
exists($${PWD}/LuminaOS-$${LINUX_DISTRO}.cpp){
@@ -26,13 +25,6 @@ exists($${PWD}/LuminaOS-$${LINUX_DISTRO}.cpp){
}else{
SOURCES *= $${PWD}/LuminaOS-template.cpp
}
-exists($${PWD}/OSInterface-$${LINUX_DISTRO}.cpp){
- SOURCES *= $${PWD}/OSInterface-$${LINUX_DISTRO}.cpp
-}else:exists($${PWD}/OSInterface-$${OS}.cpp){
- SOURCES *= $${PWD}/OSInterface-$${OS}.cpp
-}else{
- SOURCES *= $${PWD}/OSInterface-template.cpp
-}
#LUtils Files
SOURCES *= $${PWD}/LUtils.cpp
diff --git a/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp b/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp
index dc7de37f..1ee8fb8a 100644
--- a/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp
+++ b/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp
@@ -30,7 +30,7 @@ QString LOS::AppStoreShortcut(){ return "/usr/local/share/applications/appcafe.d
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";
+ feeds << "TrueOS News Feed::::http://www.trueos.org/feed/";
return feeds;
}
diff --git a/src-qt5/core/libLumina/LuminaSingleApplication.cpp b/src-qt5/core/libLumina/LuminaSingleApplication.cpp
index 5d276805..6107aff8 100644
--- a/src-qt5/core/libLumina/LuminaSingleApplication.cpp
+++ b/src-qt5/core/libLumina/LuminaSingleApplication.cpp
@@ -11,7 +11,7 @@
#include <QDebug>
#include <QX11Info>
-#include <unistd.h> //for getlogin()
+#include <unistd.h> //for getuid()
LSingleApplication::LSingleApplication(int &argc, char **argv, QString appname) : QApplication(argc, argv){
//Load the proper translation systems
@@ -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(getuid());
+ QString username = QString::number(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 857e604b..03524941 100644
--- a/src-qt5/core/libLumina/LuminaThemes.cpp
+++ b/src-qt5/core/libLumina/LuminaThemes.cpp
@@ -34,6 +34,17 @@ QStringList LTHEME::availableSystemThemes(){
return list;
}
+QStringList LTHEME::availableSystemStyles(){
+ //returns: [name::::path] for each item
+ QDir dir(LOS::LuminaShare()+"../lthemeengine/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]);
+ }
+ return list;
+}
+
QStringList LTHEME::availableLocalThemes(){ //returns: [name::::path] for each item
QDir dir( QString(getenv("XDG_CONFIG_HOME"))+"/lthemeengine/desktop_qss");
QStringList list = dir.entryList(QStringList() <<"*.qss", QDir::Files, QDir::Name);
@@ -44,6 +55,16 @@ QStringList LTHEME::availableLocalThemes(){ //returns: [name::::path] for each i
return list;
}
+QStringList LTHEME::availableLocalStyles(){ //returns: [name::::path] for each item
+ QDir dir( QString(getenv("XDG_CONFIG_HOME"))+"/lthemeengine/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]);
+ }
+ return list;
+}
+
QStringList LTHEME::availableSystemColors(){ //returns: [name::::path] for each item
//returns: [name::::path] for each item
QDir dir(LOS::LuminaShare()+"../lthemeengine/colors");
@@ -244,6 +265,23 @@ bool LTHEME::setCursorTheme(QString cursorname){
return LUtils::writeFile(QDir::homePath()+"/.icons/default/index.theme", info, true);
}
+bool LTHEME::setCurrentStyles(QStringList paths){
+ //Verify that the paths are all absolute paths, otherwise scan/replace with absolute paths
+ QStringList avail = LTHEME::availableSystemStyles();
+ for(int i=0; i<paths.length(); i++){
+ paths[i] = paths[i].simplified();
+ if(paths[i].startsWith("/")){ continue; } //already an absolute path
+ for(int j=0; j<avail.length(); j++){
+ if(avail[j].startsWith(paths[i].section("/",-1).section(".qss",0,0)+"::::") ){ paths[i] = avail[j].section("::::",1,-1); break; }
+ }
+ }
+ //ordered by priority: lowest -> highest
+ QSettings engineset("lthemeengine","lthemeengine");
+ engineset.setValue("Interface/stylesheets",paths);
+ engineset.sync();
+ return true;
+}
+
//Return the complete stylesheet for a given theme/colors
QString LTHEME::assembleStyleSheet(QString themepath, QString colorpath, QString font, QString fontsize){
QString stylesheet = LUtils::readFile(themepath).join("\n");
@@ -340,10 +378,10 @@ void LTHEME::LoadCustomEnvSettings(){
setenv(info[i].section("=",0,0).toLocal8Bit(), info[i].section("=",1,100).simplified().toLocal8Bit(), 1);
}
}
-
+
}
-bool LTHEME::setCustomEnvSetting(QString var, QString val){
+bool LTHEME::setCustomEnvSetting(QString var, QString val){
//variable/value pair (use an empty val to clear it)
QStringList info = LTHEME::CustomEnvSettings(true); //user only
bool changed = false;
diff --git a/src-qt5/core/libLumina/LuminaThemes.h b/src-qt5/core/libLumina/LuminaThemes.h
index ca79e0bd..133bd04d 100644
--- a/src-qt5/core/libLumina/LuminaThemes.h
+++ b/src-qt5/core/libLumina/LuminaThemes.h
@@ -25,7 +25,9 @@ class LTHEME{
public:
//Read the Themes/Colors/Icons that are available on the system
static QStringList availableSystemThemes();//returns: [name::::path] for each item
+ static QStringList availableSystemStyles();//returns: [name::::path] for each item
static QStringList availableLocalThemes(); //returns: [name::::path] for each item
+ static QStringList availableLocalStyles(); //returns: [name::::path] for each item
static QStringList availableSystemColors(); //returns: [name::::path] for each item
static QStringList availableLocalColors(); //returns: [name::::path] for each item
static QStringList availableSystemIcons(); //returns: [name] for each item
@@ -42,6 +44,7 @@ public:
//Change the current Theme/Colors/Icons
static bool setCurrentSettings(QString themepath, QString colorpath, QString iconname, QString font, QString fontsize);
static bool setCursorTheme(QString cursorname);
+ static bool setCurrentStyles(QStringList paths); //ordered by priority: lowest -> highest
//Return the complete stylesheet for a given theme/colors
static QString assembleStyleSheet(QString themepath, QString colorpath, QString font, QString fontsize);
diff --git a/src-qt5/core/libLumina/LuminaXDG.cpp b/src-qt5/core/libLumina/LuminaXDG.cpp
index 1933ba93..e1c582d9 100644
--- a/src-qt5/core/libLumina/LuminaXDG.cpp
+++ b/src-qt5/core/libLumina/LuminaXDG.cpp
@@ -1294,6 +1294,7 @@ QStringList LXDG::findAvailableAppsForMime(QString mime){
}
void LXDG::setDefaultAppForMime(QString mime, QString app){
+ //qDebug() << "Set Default App For Mime:" << mime << app;
QString filepath = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-mimeapps.list";
QStringList cinfo = LUtils::readFile(filepath);
//If this is a new file, make sure to add the header appropriately
diff --git a/src-qt5/core/libLumina/OSInterface-template.cpp b/src-qt5/core/libLumina/OSInterface-template.cpp
deleted file mode 100644
index 96b01e60..00000000
--- a/src-qt5/core/libLumina/OSInterface-template.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-//===========================================
-// Lumina desktop source code
-// Copyright (c) 2017, Ken Moore
-// Available under the 3-clause BSD license
-// See the LICENSE file for full details
-//===========================================
-#include <OSInterface.h>
-
-//===========
-// PUBLIC
-//===========
-
-//Simple functions used to determine if the current OS supports using this class, and what levels of support
-QList<OSInterface::Interface> OSInterface::supportedNotifications(){
- //Which interfaces provide change notifications
- return QList< OSInterface::Interface >();
-}
-
-QList<OSInterface::Interface> OSInterface::supportedStatus(){
- //Which interfaces are available for "status" requests
- return QList< OSInterface::Interface >();
-}
-
-QList<OSInterface::Interface> OSInterface::supportedModify(){
- //Which interfaces are available for "modify" requests
- return QList< OSInterface::Interface >();
-}
-
-//Start/stop interface watchers/notifications (each only called once per session)
-void OSInterface::start(){
- //nothing to do
-}
-
-void OSInterface::stop(){
- //nothing to do
-}
-
-//Generic status update
-QList<QVariant> OSInterface::status(OSInterface::Interface){
- // ==== Interface status output lists ====
- // Battery: [ float (percent charge), bool (is Charging), double (seconds remaining) ];
- // Volume: [int (percent volume) ]
- // Devices: [ QStringList[ name, mountpoint, type (optional)] ] (List length depends on number of devices)
- // Network: [bool (network access available)]
- // PowerOff: [bool (can power off system)]
- // Reboot: [bool (can reboot system)]
- // Suspend: [bool (can suspend system)]
- // Updates: [bool (is updating), bool (reboot required)]
- // ==========
- return QList<QVariant>();
-}
-
-//Individual Interface interactions
-bool OSInterface::modify(OSInterface::Interface, QList<QVariant>){ //returns: success/failure
- // ==== Interface modification argument lists ====
- // Battery: <NO MODIFICATION>
- // Volume: [int (set percent volume) ]
- // Devices: <NO MODIFICATION>
- // Network: <NO MODIFICATION>
- // PowerOff: [bool (skip updates - optional)]
- // Reboot: [bool (skip updates - optional)]
- // Suspend: [] (No input arguments)
- // Updates: <NO MODIFICATION>
- // ==========
- return false;
-}
-
-//=================
-// PRIVATE SLOTS
-//=================
-//FileSystemWatcher slots
-void OSInterface::watcherFileChanged(QString){
-
-}
-
-void OSInterface::watcherDirChanged(QString){
-
-}
-
-//IO Device slots
-void OSInterface::iodeviceReadyRead(){
-
-}
-
-void OSInterface::iodeviceAboutToClose(){
-
-}
-
-//NetworkAccessManager slots
-void OSInterface::netAccessChanged(QNetworkAccessManager::NetworkAccessibility){
-
-}
-
-void OSInterface::netRequestFinished(QNetworkReply*){
-
-}
-
-void OSInterface::netSslErrors(QNetworkReply*, const QList<QSslError>&){
-
-}
diff --git a/src-qt5/core/libLumina/OSInterface.h b/src-qt5/core/libLumina/OSInterface.h
deleted file mode 100644
index acbd5c38..00000000
--- a/src-qt5/core/libLumina/OSInterface.h
+++ /dev/null
@@ -1,136 +0,0 @@
-//===========================================
-// 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 main interface for any OS-specific system calls
-// To port Lumina to a different operating system, just create a file
-// called "OSInterface-<Operating System>.cpp"
-//===========================================
-#ifndef _LUMINA_LIBRARY_OS_INTERFACE_H
-#define _LUMINA_LIBRARY_OS_INTERFACE_H
-
-#include <QString>
-#include <QStringList>
-#include <QList>
-#include <QObject>
-#include <QVariant>
-#include <QHash>
-
-#include <QIODevice>
-#include <QFileSystemWatcher>
-#include <QNetworkAccessManager>
-#include <QNetworkReply>
-#include <QSslError>
-
-class OSInterface : public QObject{
- Q_OBJECT
-
-public:
- enum Interface{ Battery, Volume, Devices, Network, PowerOff, Reboot, Suspend, Updates };
-
-private slots:
- //FileSystemWatcher slots
- void watcherFileChanged(QString);
- void watcherDirChanged(QString);
- //IO Device slots
- void iodeviceReadyRead();
- void iodeviceAboutToClose();
- //NetworkAccessManager slots
- void netAccessChanged(QNetworkAccessManager::NetworkAccessibility);
- void netRequestFinished(QNetworkReply*);
- void netSslErrors(QNetworkReply*, const QList<QSslError>&);
-
-private:
- //Internal persistant data storage, OS-specific usage implementation
- QHash< OSInterface::Interface, QList<QVariant> > INFO;
-
- // ============
- // Internal possibilities for watching the system (OS-Specific usage/implementation)
- // ============
- //File System Watcher
- QFileSystemWatcher *watcher;
- //IO Device (QLocalSocket, QTcpConnection, QFile, etc)
- QIODevice *iodevice;
- //Network Access Manager (check network connectivity, etc)
- QNetworkAccessManager *netman;
-
- //Simplifications for connecting the various watcher objects to their respective slots
- void connectWatcher(){
- if(watcher==0){ return; }
- connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(watcherFileChanged(QString)) );
- connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(watcherDirChanged(QString)) );
- }
- void connectIodevice(){
- if(iodevice==0){ return; }
- connect(iodevice, SIGNAL(readyRead()), this, SLOT(iodeviceReadyRead()) );
- }
- void connectNetman(){
- if(netman==0){ return; }
- connect(netman, SIGNAL(networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility)), this, SLOT(netAccessChanged(QNetworkAccessManager::NetworkAccessibility)) );
- connect(netman, SIGNAL(requestFinished(QNetworkReply*)), this, SLOT(netRequestFinished(QNetworkReply*)) );
- connect(netman, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>&)), this, SLOT(netSslErrors(QNetworkReply*, const QList<QSslError>&)) );
- }
-
-public:
- OSInterface(QObject *parent = 0) : QObject(parent){
- watcher = 0;
- iodevice = 0;
- netman = 0;
- }
- ~OSInterface(){
- if(watcher!=0){
- QStringList paths; paths << watcher->files() << watcher->directories();
- if(!paths.isEmpty()){ watcher->removePaths(paths); }
- watcher->deleteLater();
- }
- if(iodevice!=0){
- if(iodevice->isOpen()){ iodevice->close(); }
- iodevice->deleteLater();
- }
- if(netman!=0){
- netman->deleteLater();
- }
- }
-
- //Simple functions used to determine if the current OS supports using this class, and what levels of support
- QList<OSInterface::Interface> supportedNotifications(); //Which interfaces provide change notifications
- QList<OSInterface::Interface> supportedStatus(); //Which interfaces are available for "status" requests
- QList<OSInterface::Interface> supportedModify(); //Which interfaces are available for "modify" requests
-
- //Start/stop interface watchers/notifications (each only called once per session)
- void start();
- void stop();
-
- //Generic status update
- QList<QVariant> status(OSInterface::Interface);
- // ==== Interface status output lists ====
- // Battery: [ float (percent charge), bool (is Charging), double (seconds remaining) ];
- // Volume: [int (percent volume) ]
- // Devices: [ QStringList[ name, mountpoint, type (optional)] ] (List length depends on number of devices)
- // Network: [bool (network access available)]
- // PowerOff: [bool (can power off system)]
- // Reboot: [bool (can reboot system)]
- // Suspend: [bool (can suspend system)]
- // Updates: [bool (is updating), bool (reboot required)]
- // ==========
-
- //Individual Interface interactions
- bool modify(OSInterface::Interface, QList<QVariant> args); //returns: success/failure
- // ==== Interface modification argument lists ====
- // Battery: <NO MODIFICATION>
- // Volume: [int (set percent volume) ]
- // Devices: <NO MODIFICATION>
- // Network: <NO MODIFICATION>
- // PowerOff: [bool (skip updates - optional)]
- // Reboot: [bool (skip updates - optional)]
- // Suspend: [] (No input arguments)
- // Updates: <NO MODIFICATION>
- // ==========
-
-signals:
- void interfaceChanged(OSInterface::Interface);
-
-};
-#endif
diff --git a/src-qt5/core/lumina-desktop-unified/LSession.cpp b/src-qt5/core/lumina-desktop-unified/LSession.cpp
index e1251c01..ed4d644b 100644
--- a/src-qt5/core/lumina-desktop-unified/LSession.cpp
+++ b/src-qt5/core/lumina-desktop-unified/LSession.cpp
@@ -22,6 +22,7 @@ QThread* Lumina::EVThread = 0;
RootWindow* Lumina::ROOTWIN = 0;
XDGDesktopList* Lumina::APPLIST = 0;
LShortcutEvents* Lumina::SHORTCUTS = 0;
+DesktopManager* Lumina::DESKMAN = 0;
LSession::LSession(int &argc, char ** argv) : LSingleApplication(argc, argv, "lumina-desktop-unified"){
//Initialize the global objects to null pointers
@@ -49,10 +50,11 @@ LSession::LSession(int &argc, char ** argv) : LSingleApplication(argc, argv, "lu
Lumina::NEF = new NativeEventFilter();
Lumina::NWS = new NativeWindowSystem();
Lumina::SS = new LScreenSaver();
+ Lumina::DESKMAN = new DesktopManager();
//Now put the Native Window System into it's own thread to keep things snappy
Lumina::EVThread = new QThread();
- //Lumina::NWS->moveToThread(Lumina::EVThread);
- //Lumina::EVThread->start();
+ Lumina::DESKMAN->moveToThread(Lumina::EVThread);
+ Lumina::EVThread->start();
Lumina::APPLIST = XDGDesktopList::instance();
Lumina::ROOTWIN = new RootWindow();
Lumina::SHORTCUTS = new LShortcutEvents(); //this can be moved to it's own thread eventually as well
@@ -73,6 +75,7 @@ LSession::~LSession(){
if(DesktopSettings::instance()!=0){ DesktopSettings::instance()->deleteLater(); }
if(Lumina::ROOTWIN!=0){ Lumina::ROOTWIN->deleteLater(); }
if(Lumina::APPLIST!=0){ Lumina::APPLIST->deleteLater(); }
+ if(Lumina::DESKMAN!=0){ Lumina::DESKMAN->deleteLater(); }
}
void LSession::setupSession(){
@@ -104,6 +107,10 @@ void LSession::setupSession(){
splash.showScreen("user");
if(DEBUG){ qDebug() << " - Init User Files:" << timer->elapsed();}
//checkUserFiles(); //adds these files to the watcher as well
+ Lumina::NWS->setRoot_numberOfWorkspaces(QStringList() << "one" << "two");
+ Lumina::NWS->setRoot_currentWorkspace(0);
+
+ Lumina::DESKMAN->start();
Lumina::ROOTWIN->start();
//Initialize the internal variables
//DESKTOPS.clear();
@@ -124,14 +131,12 @@ void LSession::setupSession(){
//Initialize the desktops
splash.showScreen("desktop");
- if(DEBUG){ qDebug() << " - Init Desktops:" << timer->elapsed(); }
+ /*if(DEBUG){ qDebug() << " - Init Desktops:" << timer->elapsed(); }
QList<QScreen*> scrns= QApplication::screens();
for(int i=0; i<scrns.length(); i++){
qDebug() << " --- Load Wallpaper for Screen:" << scrns[i]->name();
RootDesktopObject::instance()->ChangeWallpaper(scrns[i]->name(),QUrl::fromLocalFile(LOS::LuminaShare()+"desktop-background.jpg").toString() );
- }
- Lumina::NWS->setRoot_numberOfWorkspaces(QStringList() << "one" << "two");
- Lumina::NWS->setRoot_currentWorkspace(0);
+ }*/
if(DEBUG){ qDebug() << " - Create Desktop Context Menu"; }
diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Grav.json b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Grav.json
new file mode 100644
index 00000000..8d75d399
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Grav.json
@@ -0,0 +1,25 @@
+{
+ "name" : {
+ "default" : "Grav"
+ },
+ "description" : {
+ "default" : "Simulates a solar system, with a single star and planets erratically orbiting that star"
+ },
+ "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" : "20171101",
+ "version" : "1.0"
+ },
+ "qml" : {
+ "exec" : "qml_scripts/Grav.qml"
+ }
+}
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
index 7a3c33cd..d1e5d3c9 100644
--- 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
@@ -4,11 +4,13 @@ import QtGraphicalEffects 1.0
Rectangle {
id : canvas
anchors.fill: parent
- width: 800
- height: 600
+ width: Screen.width
+ height: Screen.height
color: "black"
//TODO Add orbital trails option
+ //TODO Fix jitteryness and start position
+ //TODO Make orbits more extreme
//Between 5 and 15 planets, read from settings
property int planets: Math.round(( Math.random() * 10 ) + 5 )
@@ -30,6 +32,7 @@ Rectangle {
property double a: Math.sqrt(b*b+c*c)
//Random angle of rotation
property double th: Math.random() * Math.PI
+ property var path: []
//Calculates starting position
x: Math.round(cx + a * Math.cos(th))
@@ -45,34 +48,40 @@ Rectangle {
//Give each planet a random color, semi-transparent
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 0.5)
- Timer {
+ /*Timer {
//Each planet updates between 1ms and 51ms (smaller times=faster)
interval: Math.round(Math.random() * 50 ) + 1
repeat: true
running: true
- property bool starting: true
property int time: 0
onTriggered: {
- //Move a planet 80 pixels away from the sun if the planet is too close
- if(starting) {
- if(x > cx && Math.abs(cx-x) < 80) {
- x+=80
- }else if(x < cx && Math.abs(cx-x) < 80) {
- x-=80
- }
-
- if(y > cy && Math.abs(cy-y) < 80) {
- y+=80
- }else if(y < cy && Math.abs(cy-y) < 80) {
- y-=80
- }
- starting = false;
- }
//Parametric equation that calculates the position of the general ellipse. Completes a loop ever 314 cycles. Credit to
x = cx+a*Math.cos(2*Math.PI*(time/314.0))*Math.cos(th) - b*Math.sin(2*Math.PI*(time/314.0))*Math.sin(th)
y = cy+a*Math.cos(2*Math.PI*(time/314.0))*Math.sin(th) + b*Math.sin(2*Math.PI*(time/314.0))*Math.cos(th)
time++;
+
+ //Move a planet 80 pixels away from the sun if the planet is too close
+ if(x > cx && Math.abs(cx-x) < 80) {
+ x+=80
+ }else if(x < cx && Math.abs(cx-x) < 80) {
+ x-=80
+ }
+
+ if(y > cy && Math.abs(cy-y) < 80) {
+ y+=80
+ }else if(y < cy && Math.abs(cy-y) < 80) {
+ y-=80
+ }
+ }
+ }*/
+
+ Component.onCompleted: {
+ pahtX[0] = x
+ pahtY[0] = y
+ for(int i = 1; i <= 200; i++) {
+ pathX[i] = cx+a*Math.cos(2*Math.PI*(i/200.0)*Math.cos(th) - b*Math.sin(2*Math.PI*(i/200.0)*Math.sin(th)
+ pathY[i] = cy+a*Math.cos(2*Math.PI*(i/200.0)*Math.sin(th) + b*Math.sin(2*Math.PI*(i/200.0)*Math.cos(th)
}
}
}
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
index e7d0626d..9948537b 100644
--- 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
@@ -4,10 +4,8 @@ import QtQuick.Window 2.2
import Qt.labs.folderlistmodel 2.1
Rectangle {
- //width: Screen.width
- //height: Screen.height
- width: 800
- height: 600
+ width: Screen.width
+ height: Screen.height
color: "black"
FolderListModel {
diff --git a/src-qt5/core/lumina-desktop-unified/global-includes.h b/src-qt5/core/lumina-desktop-unified/global-includes.h
index 40987ad4..fbc3c4f7 100644
--- a/src-qt5/core/lumina-desktop-unified/global-includes.h
+++ b/src-qt5/core/lumina-desktop-unified/global-includes.h
@@ -59,10 +59,6 @@
#include <QQmlEngine>
#include <QQuickImageProvider>
-// C++ Backend classes for QML interface
-#include <RootDesktopObject.h>
-#include <ScreenObject.h>
-
// libLumina includes
#include <LuminaX11.h>
#include <LuminaXDG.h>
@@ -80,6 +76,9 @@
#include <LIconCache.h>
#include <LFileInfo.h>
+// C++ Backend classes for QML interface
+#include <RootDesktopObject.h>
+#include <ScreenObject.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 c204587f..4cea60c2 100644
--- a/src-qt5/core/lumina-desktop-unified/global-objects.h
+++ b/src-qt5/core/lumina-desktop-unified/global-objects.h
@@ -22,9 +22,10 @@
//#include "src-events/LXcbEventFilter.h"
//#endif
#include "src-events/LShortcutEvents.h"
-
+#include "src-desktop/DesktopManager.h"
#include "src-screensaver/LScreenSaver.h"
//#include "src-WM/LWindowManager.h"
+
#include <RootWindow.h>
#include "LSession.h"
@@ -43,13 +44,13 @@ namespace Lumina{
//extern EventFilter *EFILTER; //Native Event Watcher
extern LShortcutEvents *SHORTCUTS; //Keyboard/mouse shortcut events
- //extern DesktopSettings *SETTINGS; //All Settings files
+
//ScreenSaver
extern LScreenSaver *SS;
//Root Window
extern RootWindow *ROOTWIN;
- //Window Manager
- //LWindowManager *WM;
+ //Desktop Manager
+ extern DesktopManager *DESKMAN;
//Application List
extern XDGDesktopList *APPLIST;
diff --git a/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro b/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro
index 21e46b22..bb987e25 100644
--- a/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro
+++ b/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro
@@ -24,7 +24,7 @@ include(../libLumina/ExternalProcess.pri)
include(../../src-cpp/NativeWindow.pri)
include(../libLumina/XDGMime.pri)
-include(../../src-cpp/plugins-screensaver.pri)
+include(../../src-cpp/plugins-base.pri)
#include all the main individual source groups
include(src-screensaver/screensaver.pri)
@@ -124,7 +124,7 @@ TRANSLATIONS = i18n/lumina-desktop_af.ts \
i18n/lumina-desktop_zu.ts
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
-dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
+dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
INSTALLS += target desktop defaults extrafiles
diff --git a/src-qt5/core/lumina-desktop-unified/main.cpp b/src-qt5/core/lumina-desktop-unified/main.cpp
index ed2b9b4c..3cf35e50 100644
--- a/src-qt5/core/lumina-desktop-unified/main.cpp
+++ b/src-qt5/core/lumina-desktop-unified/main.cpp
@@ -39,11 +39,11 @@ int main(int argc, char ** argv)
QTime *timer=0;
if(DEBUG){ timer = new QTime(); timer->start(); }
if(DEBUG){ qDebug() << "Theme Init:" << timer->elapsed(); }
- LuminaThemeEngine theme(&a);
- QObject::connect(&theme, SIGNAL(updateIcons()), &a, SLOT(reloadIconTheme()) );
+ /*LuminaThemeEngine theme(&a);
+ QObject::connect(&theme, SIGNAL(updateIcons()), &a, SLOT(reloadIconTheme()) );*/
if(DEBUG){ qDebug() << "Session Setup:" << timer->elapsed(); }
QTimer::singleShot(0, &a, SLOT(setupSession()) );
- theme.refresh();
+ //theme.refresh();
if(DEBUG){ qDebug() << "Exec Time:" << timer->elapsed(); delete timer;}
int retCode = a.exec();
qDebug() << "Finished Closing Down Unified Lumina";
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp
new file mode 100644
index 00000000..d6d06be9
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.cpp
@@ -0,0 +1,139 @@
+//===========================================
+// Lumina-desktop source code
+// Copyright (c) 2017-2018, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "DesktopManager.h"
+
+#include "global-objects.h"
+
+// === PUBLIC ===
+DesktopManager::DesktopManager(){
+
+}
+
+DesktopManager::~DesktopManager(){
+
+}
+
+void DesktopManager::start(){
+ connect(DesktopSettings::instance(), SIGNAL(FileModified(DesktopSettings::File)), this, SLOT(settingsChanged(DesktopSettings::File)) );
+ //Perform the initial load of the settings files
+ QTimer::singleShot(0, this, SLOT(updateDesktopSettings()) );
+ QTimer::singleShot(0, this, SLOT(updatePanelSettings()) );
+ QTimer::singleShot(0, this, SLOT(updatePluginSettings()) );
+ QTimer::singleShot(0, this, SLOT(updateMenuSettings()) );
+ QTimer::singleShot(0, this, SLOT(updateAnimationSettings()) );
+}
+
+void DesktopManager::stop(){
+ disconnect(DesktopSettings::instance(), SIGNAL(FileModified(DesktopSettings::File)), this, SLOT(settingsChanged(DesktopSettings::File)) );
+}
+
+// === PRIVATE ===
+void DesktopManager::updateWallpaper(QString screen_id, int wkspace){
+ QString current = RootDesktopObject::instance()->CurrentWallpaper(screen_id);
+ if(!current.isEmpty()){ current = QUrl(current).toLocalFile(); } //convert it back to the normal file syntax
+ //First find the list of options from the settings
+ //First look for a list that matches this exact screen/workspace combo
+ QStringList wpaperList = DesktopSettings::instance()->value(DesktopSettings::Desktop, "wallpapers/"+screen_id+"_wk_"+QString::number(wkspace), QStringList()).toStringList();
+ //Next look for a list that matches this exact workspace
+ if(wpaperList.isEmpty()){ wpaperList= DesktopSettings::instance()->value(DesktopSettings::Desktop, "wallpapers/default_wk_"+QString::number(wkspace), QStringList()).toStringList(); }
+ //Next look for a list that matches this exact screen
+ if(wpaperList.isEmpty()){ wpaperList= DesktopSettings::instance()->value(DesktopSettings::Desktop, "wallpapers/"+screen_id, QStringList()).toStringList(); }
+ //Now look for a list that matches any screen/workspace
+ if(wpaperList.isEmpty()){ wpaperList= DesktopSettings::instance()->value(DesktopSettings::Desktop, "wallpapers/default", QStringList()).toStringList(); }
+ //Now use the failover wallpaper directory
+ if(wpaperList.isEmpty()){ wpaperList << LOS::LuminaShare()+"../wallpapers/lumina-nature"; }
+ //Wallpaper selection/randomization
+ if(wpaperList.count()==1 && wpaperList.first()==current){ return; } //nothing to do - just the same image
+ QString wpaper;
+ QStringList bgL = wpaperList; //need a copy at the moment - could change the entire list in a second (opening a dir for instance)
+ while(wpaper.isEmpty() || QFileInfo(wpaper).isDir()){
+ QString prefix;
+ if(!wpaper.isEmpty()){
+ //Got a directory - update the list of files and re-randomize the selection
+ QStringList imgs = LUtils::imageExtensions(true);
+ QDir tdir(wpaper);
+ prefix=wpaper+"/";
+ 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()){
+ wpaperList.removeAll(wpaper); //invalid directory - remove it from the list for the moment
+ bgL = wpaperList; //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()){ wpaper="default"; break; }
+ int index = ( qrand() % bgL.length() );
+ if(index== bgL.indexOf(current)){ //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
+ }
+ wpaper = prefix+bgL[index];
+ }
+ //Now go ahead and set the wallpaper in the screen object
+ if(wpaper.isEmpty() || wpaper=="default"){ wpaper = LOS::LuminaShare()+"desktop-background.jpg"; } //failover image
+ qDebug() << "Updating Wallpaper:" << screen_id << wpaper;
+ RootDesktopObject::instance()->ChangeWallpaper(screen_id,QUrl::fromLocalFile(wpaper).toString() );
+}
+
+void DesktopManager::updatePanels(QString panel_id){
+
+}
+
+void DesktopManager::updatePlugins(QString plugin_id){
+
+}
+
+// === PUBLIC SLOTS ===
+void DesktopManager::workspaceChanged(int wknum){
+ qDebug() << "Got Workspace Changed:" << wknum;
+
+}
+
+void DesktopManager::settingsChanged(DesktopSettings::File type){
+ switch(type){
+ case DesktopSettings::Desktop:
+ QTimer::singleShot(0, this, SLOT(updateDesktopSettings()) );
+ case DesktopSettings::Panels:
+ QTimer::singleShot(0, this, SLOT(updatePanelSettings()) );
+ case DesktopSettings::Plugins:
+ QTimer::singleShot(0, this, SLOT(updatePluginSettings()) );
+ case DesktopSettings::ContextMenu:
+ QTimer::singleShot(0, this, SLOT(updateMenuSettings()) );
+ case DesktopSettings::Animation:
+ QTimer::singleShot(0, this, SLOT(updateAnimationSettings()) );
+ default:
+ break;
+ //Do nothing - not a settings change we care about here
+ }
+}
+
+// === PRIVATE SLOTS ===
+void DesktopManager::updateDesktopSettings(){
+ qDebug() << "Update Desktop Settings...";
+ QList<QScreen*> scrns= QApplication::screens();
+ int wkspace = Lumina::NWS->currentWorkspace();
+ for(int i=0; i<scrns.length(); i++){ updateWallpaper(scrns[i]->name(), wkspace); }
+
+}
+
+void DesktopManager::updatePanelSettings(){
+
+}
+
+void DesktopManager::updatePluginSettings(){
+
+}
+
+void DesktopManager::updateMenuSettings(){
+
+}
+
+void DesktopManager::updateAnimationSettings(){
+
+}
+
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h
new file mode 100644
index 00000000..df681afa
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/DesktopManager.h
@@ -0,0 +1,44 @@
+//===========================================
+// Lumina-desktop source code
+// Copyright (c) 2017-2018, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+// This is the main class that updates the interface objects
+// on-demand as settings files and other stuff changes
+//===========================================
+#ifndef _LUMINA_DESKTOP_OBJECT_MANAGER_H
+#define _LUMINA_DESKTOP_OBJECT_MANAGER_H
+
+#include <global-includes.h>
+
+class DesktopManager : public QObject {
+ Q_OBJECT
+public:
+ DesktopManager();
+ ~DesktopManager();
+
+ void start();
+ void stop();
+
+private:
+ void updateWallpaper(QString screen_id, int wkspace);
+ void updatePanels(QString panel_id);
+ void updatePlugins(QString plugin_id);
+
+public slots:
+ void workspaceChanged(int);
+ void settingsChanged(DesktopSettings::File);
+
+private slots:
+ void updateDesktopSettings();
+ void updatePanelSettings();
+ void updatePluginSettings();
+ void updateMenuSettings();
+ void updateAnimationSettings();
+
+signals:
+ void PanelLocationsChanged(); //reserved screen space changed
+};
+
+#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 e4c4faeb..f4a6882d 100644
--- a/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri
@@ -1,8 +1,10 @@
QT *= gui widgets qml quick
-SOURCES *= $${PWD}/RootWindow.cpp
+SOURCES *= $${PWD}/RootWindow.cpp \
+ $${PWD}/Desktopmanager.cpp
-HEADERS *= $${PWD}/RootWindow.h
+HEADERS *= $${PWD}/RootWindow.h \
+ $${PWD}/DesktopManager.h
#update the includepath so we can just #include as needed without paths
INCLUDEPATH *= $${PWD}
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.cpp
new file mode 100644
index 00000000..471da58f
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.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 "PanelObject.h"
+#include <QQmlEngine>
+#include <QDebug>
+
+PanelObject::PanelObject(QString id, QObject *parent) : QObject(parent){
+ panel_id = id;
+}
+
+void PanelObject::RegisterType(){
+ static bool done = false;
+ if(done){ return; }
+ done=true;
+ qmlRegisterType<PanelObject>("Lumina.Backend.PanelObject",2,0, "PanelObject");
+}
+
+QString PanelObject::name(){ return panel_id; }
+QString PanelObject::background(){
+ if(bg.isEmpty()){ return "transparent"; }
+ return bg;
+}
+int PanelObject::x(){ return geom.x(); }
+int PanelObject::y(){ return geom.y(); }
+int PanelObject::width(){ return geom.width(); }
+int PanelObject::height(){ return geom.height(); }
+
+void PanelObject::setBackground(QString fileOrColor){
+ if(bg!=fileOrColor){
+ bg = fileOrColor;
+ emit backgroundChanged();
+ }
+}
+
+void PanelObject::setGeometry( QRect newgeom ){
+ if(geom!=newgeom){
+ geom = newgeom;
+ emit geomChanged();
+ }
+}
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.h
new file mode 100644
index 00000000..a788fa07
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/PanelObject.h
@@ -0,0 +1,49 @@
+//===========================================
+// 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 Panel info to the QML classes
+//===========================================
+#ifndef _LUMINA_DESKTOP_PANEL_OBJECT_H
+#define _LUMINA_DESKTOP_PANEL_OBJECT_H
+#include <QObject>
+#include <QString>
+#include <QScreen>
+
+class PanelObject : 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:
+ QString panel_id, bg;
+ QRect geom;
+
+public:
+ PanelObject(QString id = "", 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);
+ void setGeometry(QRect newgeom);
+
+signals:
+ void backgroundChanged();
+ void geomChanged();
+};
+
+#endif
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
index 60cf56c3..4b01fa0d 100644
--- 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
@@ -21,6 +21,9 @@ RootDesktopObject::~RootDesktopObject(){
}
void RootDesktopObject::RegisterType(){
+ static bool done = false;
+ if(done){ return; }
+ done=true;
qmlRegisterType<RootDesktopObject>("Lumina.Backend.RootDesktopObject", 2, 0, "RootDesktopObject");
//Also register any types that are needed by this class
ScreenObject::RegisterType();
@@ -47,6 +50,47 @@ ScreenObject* RootDesktopObject::screen(QString id){
return 0;
}
+QStringList RootDesktopObject::panels(){
+ //qDebug() << "Request Panels:" << panel_objects.length();
+ QStringList names;
+ for(int i=0; i<panel_objects.length(); i++){ names << panel_objects[i]->name(); }
+ return names;
+}
+
+PanelObject* RootDesktopObject::panel(QString id){
+ //qDebug() << "Got Panel Request:" << id;
+ for(int i=0; i<panel_objects.length(); i++){
+ if(panel_objects[i]->name()==id){ return panel_objects[i]; }
+ }
+ return 0;
+}
+
+QStringList RootDesktopObject::windows(){
+ //qDebug() << "Request Panels:" << panel_objects.length();
+ QStringList names;
+ for(int i=0; i<window_objects.length(); i++){ names << QString::number(window_objects[i]->id()); }
+ return names;
+}
+
+NativeWindow* RootDesktopObject::window(QString id){
+ //qDebug() << "Got Panel Request:" << id;
+ WId chk = id.toInt(); //numerical ID's in this case
+ for(int i=0; i<window_objects.length(); i++){
+ if(window_objects[i]->id()==chk){ return window_objects[i]; }
+ }
+ return 0;
+}
+
+void RootDesktopObject::setPanels(QList<PanelObject*> list){
+ panel_objects = list;
+ emit panelsChanged();
+}
+
+void RootDesktopObject::setWindows(QList<NativeWindow*> list){
+ window_objects = list;
+ emit windowsChanged();
+}
+
void RootDesktopObject::logout(){
emit startLogout();
}
@@ -85,4 +129,13 @@ void RootDesktopObject::ChangeWallpaper(QString screen, QString value){
}
}
+QString RootDesktopObject::CurrentWallpaper(QString screen){
+ for(int i=0; i<s_objects.length(); i++){
+ if(s_objects[i]->name()==screen){ return s_objects[i]->background();}
+ }
+ return ""; //unknown
+}
+
+
+
// === 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
index ba586701..7d5182c4 100644
--- 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
@@ -10,6 +10,7 @@
#define _LUMINA_DESKTOP_QML_BACKEND_ROOT_DESKTOP_OBJECT_H
#include <QObject>
#include <QList>
+#include <global-includes.h>
#include "ScreenObject.h"
@@ -17,6 +18,8 @@ class RootDesktopObject : public QObject{
Q_OBJECT
//Define all the QML Properties here (interface between QML and the C++ methods below)
Q_PROPERTY( QStringList screens READ screens NOTIFY screensChanged)
+ Q_PROPERTY( QStringList panels READ panels NOTIFY panelsChanged)
+ Q_PROPERTY( QStringList windows READ windows NOTIFY windowsChanged);
public:
//main contructor/destructor
@@ -29,24 +32,38 @@ public:
static RootDesktopObject* instance();
//QML Read Functions
- QStringList screens();
+ Q_INVOKABLE QStringList screens();
Q_INVOKABLE ScreenObject* screen(QString id);
+ Q_INVOKABLE QStringList panels();
+ Q_INVOKABLE PanelObject* panel(QString id);
+ Q_INVOKABLE QStringList windows();
+ Q_INVOKABLE NativeWindow* window(QString id);
+
+ void setPanels(QList<PanelObject*> list);
+ void setWindows(QList<NativeWindow*> list);
//QML Access Functions
Q_INVOKABLE void logout();
Q_INVOKABLE void lockscreen();
Q_INVOKABLE void mousePositionChanged();
+
private:
QList<ScreenObject*> s_objects;
+ QList<PanelObject*> panel_objects;
+ QList<NativeWindow*> window_objects;
public slots:
void updateScreens(); //rescan/update screen objects
void ChangeWallpaper(QString screen, QString);
+ QString CurrentWallpaper(QString screen);
private slots:
signals:
void screensChanged();
+ void panelsChanged();
+ void windowsChanged();
+
void startLogout();
void mouseMoved();
void lockScreen();
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
index 4c1d6189..82622403 100644
--- 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
@@ -13,7 +13,12 @@ ScreenObject::ScreenObject(QScreen *scrn, QObject *parent) : QObject(parent){
}
void ScreenObject::RegisterType(){
+ static bool done = false;
+ if(done){ return; }
+ done=true;
qmlRegisterType<ScreenObject>("Lumina.Backend.ScreenObject",2,0, "ScreenObject");
+ //Also register any types that are needed by this class
+ PanelObject::RegisterType();
}
QString ScreenObject::name(){ return bg_screen->name(); }
@@ -29,3 +34,24 @@ void ScreenObject::setBackground(QString fileOrColor){
emit backgroundChanged();
}
}
+
+void ScreenObject::setPanels(QList<PanelObject*> list){
+ panel_objects = list;
+ emit panelsChanged();
+}
+
+//QML Read Functions
+QStringList ScreenObject::panels(){
+ //qDebug() << "Request Panels:" << panel_objects.length();
+ QStringList names;
+ for(int i=0; i<panel_objects.length(); i++){ names << panel_objects[i]->name(); }
+ return names;
+}
+
+PanelObject* ScreenObject::panel(QString id){
+ //qDebug() << "Got Panel Request:" << id;
+ for(int i=0; i<panel_objects.length(); i++){
+ if(panel_objects[i]->name()==id){ return panel_objects[i]; }
+ }
+ return 0;
+}
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
index 8076f1ae..1afff6d2 100644
--- 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
@@ -12,6 +12,8 @@
#include <QString>
#include <QScreen>
+#include "PanelObject.h"
+
class ScreenObject : public QObject {
Q_OBJECT
Q_PROPERTY( QString name READ name )
@@ -20,10 +22,12 @@ class ScreenObject : public QObject {
Q_PROPERTY( int y READ y NOTIFY geomChanged)
Q_PROPERTY( int width READ width NOTIFY geomChanged)
Q_PROPERTY( int height READ height NOTIFY geomChanged)
+ Q_PROPERTY( QStringList panels READ panels NOTIFY panelsChanged)
private:
QScreen *bg_screen;
QString bg;
+ QList<PanelObject*> panel_objects;
public:
ScreenObject(QScreen *scrn = 0, QObject *parent = 0);
@@ -36,6 +40,10 @@ public:
Q_INVOKABLE int y();
Q_INVOKABLE int width();
Q_INVOKABLE int height();
+ Q_INVOKABLE QStringList panels();
+ Q_INVOKABLE PanelObject* panel(QString id);
+
+ void setPanels(QList<PanelObject*> list);
public slots:
void setBackground(QString fileOrColor);
@@ -43,6 +51,7 @@ public slots:
signals:
void backgroundChanged();
void geomChanged();
+ void panelsChanged();
};
#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
index 33b699da..899f4968 100644
--- 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
@@ -1,8 +1,9 @@
SOURCES *= $${PWD}/RootDesktopObject.cpp \
- $${PWD}/ScreenObject.cpp
+ $${PWD}/ScreenObject.cpp \
+ $${PWD}/PanelObject.cpp
HEADERS *= $${PWD}/RootDesktopObject.h \
- $${PWD}/ScreenObject.h
+ $${PWD}/ScreenObject.h \
+ $${PWD}/PanelObject.h
INCLUDEPATH *= $${PWD}
-
diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/Panel.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/Panel.qml
new file mode 100644
index 00000000..846b5b55
--- /dev/null
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/Panel.qml
@@ -0,0 +1,26 @@
+//===========================================
+// 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 1
+
+import Lumina.Backend.PanelObject 2.0
+
+AnimatedImage {
+ //C++ backend object
+ property string screen_id
+ property PanelObject 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/RootDesktop.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml
index e0381e23..c564ee42 100644
--- 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
@@ -46,11 +46,12 @@ Rectangle {
//Create the context menu itself
QML.ContextMenu { id: contextMenu }
- //Setup the wallpapers
+ //Setup the screens/wallpapers
Repeater{
model: RootObject.screens
- QML.WallpaperImage{
+ QML.Screen{
screen_id: modelData
+ object: RootObject.screen(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/Screen.qml
index 1b44963f..3b83653a 100644
--- a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/WallpaperImage.qml
+++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/Screen.qml
@@ -13,7 +13,7 @@ import Lumina.Backend.ScreenObject 2.0
AnimatedImage {
//C++ backend object
property string screen_id
- property ScreenObject object: RootObject.screen(screen_id)
+ property ScreenObject object
//Normal geometries/placements
asynchronous: true
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
index fed18e02..ad07902a 100644
--- 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
@@ -2,7 +2,8 @@
lupdate_only{
SOURCES *= $${PWD}/RootDesktop.qml \
$${PWD}/ContextMenu.qml \
- $${PWD}/WallpaperImage.qml
+ $${PWD}/Screen.qml \
+ $${PWD}/Panel.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
index ebdcc606..b0c66e20 100644
--- 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
@@ -2,6 +2,7 @@
<qresource prefix="qml">
<file>RootDesktop.qml</file>
<file>ContextMenu.qml</file>
- <file>WallpaperImage.qml</file>
+ <file>Screen.qml</file>
+ <file>Panel.qml</file>
</qresource>
</RCC>
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 7c098887..aa3214a2 100644
--- a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp
+++ b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp
@@ -7,6 +7,9 @@
#include "SSBaseWidget.h"
+//Relative directory to search along the XDG paths for screensavers
+#define REL_DIR QString("/lumina-desktop/screensavers")
+
#define DEBUG 0
// ========
@@ -39,10 +42,10 @@ void SSBaseWidget::startPainting(){
stopPainting();
//If a random plugin - grab one of the known plugins
if(plugType=="random"){
- QList<SSPlugin> valid = SSPluginSystem::findAllPlugins();
+ QList<SSPlugin> valid = PluginSystem::findAllPlugins<SSPlugin>(REL_DIR);
if(!valid.isEmpty()){ cplug = valid[ qrand()%valid.length() ]; } //grab a random plugin
}else if(plugType!="none"){
- cplug = SSPluginSystem::findPlugin(plugType);
+ cplug = PluginSystem::findPlugin<SSPlugin>(plugType, REL_DIR);
}
if(DEBUG){ qDebug() << " - Screen Saver:" << plugType << cplug.scriptURL() << cplug.isValid(); }
if(cplug.isValid()){
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 72e02702..e0a03d17 100644
--- a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h
+++ b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h
@@ -10,6 +10,7 @@
#define _LUMINA_DESKTOP_SCREEN_SAVER_BASE_WIDGET_H
#include "global-includes.h"
+#include <plugins-base.h>
#include <plugins-screensaver.h>
class SSBaseWidget : public QQuickView{
@@ -25,8 +26,8 @@ public slots:
void stopPainting();
private:
- QString plugType;
- SSPlugin cplug;
+ QString plugType;
+ SSPlugin cplug;
QTimer *restartTimer;
private slots:
diff --git a/src-qt5/core/lumina-desktop/defaults/desktop-background-TrueOS.jpg b/src-qt5/core/lumina-desktop/defaults/desktop-background-TrueOS.jpg
index de11074e..3fd8cc49 100644
--- a/src-qt5/core/lumina-desktop/defaults/desktop-background-TrueOS.jpg
+++ b/src-qt5/core/lumina-desktop/defaults/desktop-background-TrueOS.jpg
Binary files differ
diff --git a/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf b/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf
index e9520a3c..543f9eaa 100644
--- a/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf
+++ b/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf
@@ -53,6 +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_styles=scrollbar-simple, tooltip-simple, sliders-simple, traynotification-simple
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
@@ -60,14 +61,14 @@ theme_fontsize=10pt #Default size of the fonts to use on the desktop (can also u
#DESKTOP SETTINGS (used for the primary screen in multi-screen setups)
desktop_visiblepanels=1 #[0 - 12] The number of panels visible by default
-desktop_backgroundfiles=/usr/local/share/wallpapers/TrueOS/trueos-1-4k.png #list of absolute file paths for image files (disable for Lumina default)
+desktop_backgroundfiles=/usr/local/share/lumina-desktop/desktop-background.jpg #list of absolute file paths for image files (disable for Lumina default)
desktop_backgroundrotateminutes=5 #[positive integer] number of minutes between background rotations (if multiple files)
#desktop_plugins= #list of plugins to be shown on the desktop by default
desktop_generate_icons=true #[true/false] Auto-generate launchers for ~/Desktop items
#PANEL SETTINGS (preface with panel1.<setting> or panel2.<setting>, depending on the number of panels you have visible by default)
panel1_location=bottom #[top/bottom/left/right] Screen edge the panel should be on
-panel1_pixelsize=3.5%H #number of pixels wide/high the panel should be (or <number>%[W/H] for a percentage of the screen width/height)
+panel1_pixelsize=5%H #number of pixels wide/high the panel should be (or <number>%[W/H] for a percentage of the screen width/height)
panel1_autohide=false #[true/false] Have the panel become visible on mouse-over
panel1_plugins=systemstart, taskmanager-nogroups, spacer, systemtray, clock, battery #list of plugins for the panel
panel1_pinlocation=center #[left/center/right] Note:[left/right] corresponds to [top/bottom] for vertical panels
diff --git a/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf b/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf
index e4229038..0e6101c1 100644
--- a/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf
+++ b/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf
@@ -50,7 +50,8 @@ mime_default_unknown/*=lumina-textedit.desktop
mime_default_application/x-shellscript=lumina-textedit.desktop
#THEME SETTINGS
-theme_themefile=DarkGlass #Name of the theme to use (disable for Lumina-Default)
+theme_themefile=DarkGlass #Name of the theme to use
+theme_styles=scrollbar-simple, tooltip-simple, sliders-simple, traynotification-simple
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
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSFeedPlugin.cpp b/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSFeedPlugin.cpp
index c330d6c0..e8e5adb4 100644
--- a/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSFeedPlugin.cpp
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSFeedPlugin.cpp
@@ -119,11 +119,13 @@ void RSSFeedPlugin::updateFeed(QString ID){
if(!data.items[i].author_email.isEmpty()){ html.append("<a href=\"mailto:"+data.items[i].author_email+"\" style=\"color: "+color+";\">"+data.items[i].author+"</a>"); }
else{ html.append(data.items[i].author); }
}
- html.append(")</i><br>");
+ html.append(")</i>");
+ if(data.rss)
+ html.append("<br>");
}
html.append(data.items[i].description);
//html.append("</li>\n");
- if(i+1 < data.items.length()){ html.append("<br>"); }
+ if(i+1 < data.items.length() && data.rss){ html.append("<br>"); }
}
//html.append("</ul>\n");
// - load that html into the viewer
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSObjects.cpp b/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSObjects.cpp
index cd29d5f0..5f62f99f 100644
--- a/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSObjects.cpp
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSObjects.cpp
@@ -10,6 +10,8 @@
#include "LSession.h"
+#define DEBUG 0
+
//============
// PUBLIC
//============
@@ -116,18 +118,51 @@ RSSchannel RSSReader::readRSS(QByteArray bytes){
RSSchannel rssinfo;
//qDebug() << "Can Read XML Stream:" << !xml.hasError();
if(xml.readNextStartElement()){
- //qDebug() << " - RSS Element:" << xml.name();
- if(xml.name() == "rss" && (xml.attributes().value("version") =="2.0" || xml.attributes().value("version") =="0.91") ){
+ if(DEBUG) qDebug() << " - RSS Element:" << xml.name();
+ if(xml.name() == "rss" && (xml.attributes().value("version") =="2.0" || xml.attributes().value("version") =="0.91")) {
+ rssinfo.rss = true;
while(xml.readNextStartElement()){
//qDebug() << " - RSS Element:" << xml.name();
if(xml.name()=="channel"){ rssinfo = readRSSChannel(&xml); }
else{ xml.skipCurrentElement(); }
}
+ }else if(xml.name() == "feed") {
+ rssinfo.timetolive = -1;
+ rssinfo.rss = false;
+ while(xml.readNextStartElement()){
+ if(DEBUG) qDebug() << " - ATOM Element (channel):" << xml.name();
+ if(xml.name()=="entry") {
+ rssinfo.items << readRSSItemAtom(&xml);
+ }else if(xml.name()=="title"){
+ rssinfo.title = xml.readElementText();
+ if(DEBUG) qDebug() << "title" << rssinfo.link;
+ }else if(xml.name()=="link"){
+ QXmlStreamAttributes att = xml.attributes();
+ for(int i = 0; i < att.size(); i++) {
+ if(att[i].name() == "href") {
+ rssinfo.link = att[i].value().toString();
+ }
+ }
+ xml.readElementText();
+ if(DEBUG) qDebug() << "link" << rssinfo.link;
+ }else if(xml.name()=="subtitle"){
+ rssinfo.description = xml.readElementText();
+ }else if(xml.name()=="updated"){
+ rssinfo.lastBuildDate = ATOMDateTime(xml.readElementText());
+ }else if(xml.name()=="icon"){
+ rssinfo.icon_url = xml.readElementText();
+ if(DEBUG) qDebug() << "icon" << rssinfo.icon_url;
+ requestRSS(rssinfo.icon_url);
+ }else{
+ xml.skipCurrentElement();
+ }
+ }
}
}
- if(xml.hasError()){ qDebug() << " - XML Read Error:" << xml.errorString() << "\n" << bytes; }
+ //if(xml.hasError()){ qDebug() << " - XML Read Error:" << xml.errorString() << "\n" << bytes; }
return rssinfo;
}
+
RSSchannel RSSReader::readRSSChannel(QXmlStreamReader *rss){
RSSchannel info;
info.timetolive = -1;
@@ -151,6 +186,40 @@ RSSchannel RSSReader::readRSSChannel(QXmlStreamReader *rss){
return info;
}
+RSSitem RSSReader::readRSSItemAtom(QXmlStreamReader *rss){
+ RSSitem item;
+ while(rss->readNextStartElement()){
+ if(rss->name()=="title"){
+ item.title = rss->readElementText();
+ if(DEBUG) qDebug() << rss->name() << item.title;
+ }else if(rss->name()=="link"){
+ QXmlStreamAttributes att = rss->attributes();
+ for(int i = 0; i < att.size(); i++) {
+ if(att[i].name() == "href") {
+ item.link = att[i].value().toString();
+ }
+ }
+ rss->readElementText();
+ if(DEBUG) qDebug() << rss->name() << item.link;
+ }else if(rss->name()=="summary"){
+ item.description = rss->readElementText();
+ if(DEBUG) qDebug() << rss->name() << item.description;
+ } else if(rss->name()=="comments"){
+ item.comments_url = rss->readElementText();
+ if(DEBUG) qDebug() << rss->name() << item.comments_url;
+ } else if(rss->name()=="author"){
+ rss->readNextStartElement();
+ item.author = rss->readElementText();
+ if(DEBUG) qDebug() << "author" << item.author;
+ rss->skipCurrentElement();
+ }else if(rss->name()=="updated"){
+ item.pubdate = ATOMDateTime(rss->readElementText());
+ if(DEBUG) qDebug() << rss->name() << item.pubdate;
+ } else{ rss->skipCurrentElement(); }
+ }
+ return item;
+}
+
RSSitem RSSReader::readRSSItem(QXmlStreamReader *rss){
RSSitem item;
while(rss->readNextStartElement()){
@@ -192,17 +261,21 @@ QDateTime RSSReader::RSSDateTime(QString datetime){
return QDateTime::fromString(datetime, Qt::RFC2822Date);
}
+QDateTime RSSReader::ATOMDateTime(QString datetime){
+ return QDateTime::fromString(datetime, Qt::ISODate);
+}
+
//=================
// PRIVATE SLOTS
//=================
void RSSReader::replyFinished(QNetworkReply *reply){
QString url = reply->request().url().toString();
- //qDebug() << "Got Reply:" << url;
+ qDebug() << "Got Reply:" << url;
QString key = keyForUrl(url); //current hash key for this URL
QByteArray data = reply->readAll();
outstandingURLS.removeAll(url);
if(data.isEmpty()){
- //qDebug() << "No data returned:" << url;
+ qDebug() << "No data returned:" << url;
//see if the URL can be adjusted for known issues
bool handled = false;
QUrl redirecturl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
@@ -229,13 +302,13 @@ void RSSReader::replyFinished(QNetworkReply *reply){
//Could also be an icon fetch response
QStringList keys = hash.keys();
for(int i=0; i<keys.length(); i++){
- //qDebug() << " - Check for icon URL:" << hash[keys[i]].icon_url;
+ qDebug() << " - Check for icon URL:" << hash[keys[i]].icon_url;
if(hash[keys[i]].icon_url.toLower() == url.toLower()){ //needs to be case-insensitive
//Icon fetch response
RSSchannel info = hash[keys[i]];
QImage img = QImage::fromData(data);
info.icon = QIcon( QPixmap::fromImage(img) );
- //qDebug() << "Got Icon response:" << url << info.icon;
+ qDebug() << "Got Icon response:" << url << info.icon;
hash.insert(keys[i], info); //insert back into the hash
emit rssChanged( hash[keys[i]].originalURL );
break;
diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSObjects.h b/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSObjects.h
index 3069bf8d..9d65ee57 100644
--- a/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSObjects.h
+++ b/src-qt5/core/lumina-desktop/desktop-plugins/rssreader/RSSObjects.h
@@ -51,6 +51,7 @@ struct RSSchannel{
//Internal data for bookkeeping
QDateTime lastsync, nextsync;
QString originalURL; //in case it was redirected to some "fixed" url later
+ bool rss;
};
class RSSReader : public QObject{
@@ -88,9 +89,12 @@ private:
//RSS parsing functions
RSSchannel readRSS(QByteArray bytes);
RSSchannel readRSSChannel(QXmlStreamReader *rss);
+ RSSchannel readRSSChannelAtom(QXmlStreamReader *rss);
RSSitem readRSSItem(QXmlStreamReader *rss);
- void readRSSImage(RSSchannel *item, QXmlStreamReader *rss);
+ RSSitem readRSSItemAtom(QXmlStreamReader *rss);
+ void readRSSImage(RSSchannel *item, QXmlStreamReader *rss);
QDateTime RSSDateTime(QString datetime);
+ QDateTime ATOMDateTime(QString datetime);
private slots:
void replyFinished(QNetworkReply *reply);
diff --git a/src-qt5/core/lumina-desktop/lumina-desktop.pro b/src-qt5/core/lumina-desktop/lumina-desktop.pro
index 9c8272c8..e36d11a2 100644
--- a/src-qt5/core/lumina-desktop/lumina-desktop.pro
+++ b/src-qt5/core/lumina-desktop/lumina-desktop.pro
@@ -170,10 +170,10 @@ TRANSLATIONS = i18n/lumina-desktop_af.ts \
i18n/lumina-desktop_zu.ts
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
-dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
+dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
manpage.path=$${L_MANDIR}/man1/
-manpage.extra="$${MAN_ZIP} lumina-desktop.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-desktop.1.gz"
+manpage.extra="$${MAN_ZIP} $$PWD/lumina-desktop.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-desktop.1.gz"
INSTALLS += target desktop icons defaults conf fluxconf manpage
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 7a6b0e7c..69ea5faa 100644
--- a/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp
+++ b/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp
@@ -77,6 +77,7 @@ void LBattery::updateBattery(bool force){
label->setPixmap( LXDG::findIcon("battery-unknown", "battery-missing").pixmap(label->size()) );
break;
}
+ }
if(icon<iconOld && icon==0){
//Play some audio warning chime when
bool playaudio = sessionsettings->value("PlayBatteryLowAudio",true).toBool();
@@ -97,7 +98,6 @@ 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/systemstart/ItemWidget.cpp b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/ItemWidget.cpp
index f4382ffc..545000f4 100644
--- a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/ItemWidget.cpp
+++ b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/ItemWidget.cpp
@@ -70,12 +70,12 @@ ItemWidget::ItemWidget(QWidget *parent, QString itemPath, QString type, bool gob
iconPath = itemPath;
//icon->setPixmap( QIcon(itemPath).pixmap(64,64) );
}else{
- if( LUtils::isValidBinary(itemPath) ){
+ if( LUtils::isValidBinary(itemPath) ){
if(ICONS->exists(type)){ iconPath = type; }
else{ iconPath = "application-x-executable"; }
}else{ iconPath = LXDG::findAppMimeForFile(itemPath.section("/",-1)).replace("/","-"); }
}
- name->setText( itemPath.section("/",-1) ); //this->fontMetrics().elidedText(itemPath.section("/",-1), Qt::ElideRight, TEXTCUTOFF) );
+ name->setText( itemPath.section("/",-1) ); //this->fontMetrics().elidedText(itemPath.section("/",-1), Qt::ElideRight, TEXTCUTOFF) );
text = itemPath.section("/",-1) ;
}
ICONS->loadIcon(icon, iconPath);
@@ -133,11 +133,11 @@ ItemWidget::~ItemWidget(){
//actButton->deleteLater();
contextMenu->clear();
//contextMenu->deleteLater();
- if(actButton->menu()!=0){
+ if(actButton->menu()!=0){
for(int i=0; i<actButton->menu()->actions().length(); i++){
actButton->menu()->actions().at(i)->deleteLater();
}
- actButton->menu()->deleteLater();
+ actButton->menu()->deleteLater();
}
//actButton->deleteLater();
//icon->deleteLater();
@@ -156,7 +156,7 @@ void ItemWidget::createWidget(){
menuopen = false;
menureset = new QTimer(this);
menureset->setSingleShot(true);
- menureset->setInterval(1000); //1 second
+ menureset->setInterval(1000); //1 second
this->setContentsMargins(0,0,0,0);
contextMenu = new QMenu(this);
connect(contextMenu, SIGNAL(aboutToShow()), this, SLOT(actionMenuOpen()) );
@@ -220,7 +220,7 @@ void ItemWidget::setupActions(XDGDesktop *app){
else{ ICONS->loadIcon(act, app->icon); }
act->setToolTip(app->actions[i].ID);
act->setWhatsThis(app->actions[i].ID);
- actButton->menu()->addAction(act);
+ actButton->menu()->addAction(act);
}
connect(actButton->menu(), SIGNAL(triggered(QAction*)), this, SLOT(actionClicked(QAction*)) );
connect(actButton->menu(), SIGNAL(aboutToShow()), this, SLOT(actionMenuOpen()) );
@@ -230,9 +230,11 @@ void ItemWidget::setupActions(XDGDesktop *app){
void ItemWidget::updateItems(){
//update the text/icon to match sizes
- int H = (2.5*name->fontMetrics().height() ) -4; //make sure the height is large enough for two lines
+ int H = (2.2*name->fontMetrics().height() ) -4; //make sure the height is large enough for two lines
icon->setFixedSize(QSize(H, H));
+ icon->setAlignment(Qt::AlignCenter);
actButton->setFixedSize( QSize( H/2, H) );
+ H = (1.8*name->fontMetrics().height() ) -4;
QStringList newname = text.split("<br>");
for(int i=0; i<newname.length(); i++){ newname[i] = name->fontMetrics().elidedText(newname[i], Qt::ElideRight, name->width()); }
name->setText( newname.join("<br>") );
@@ -271,9 +273,9 @@ void ItemWidget::RemoveFavorite(){
void ItemWidget::AddFavorite(){
if( LDesktopUtils::addFavorite(icon->whatsThis()) ){
linkPath = icon->whatsThis();
- emit NewShortcut();
+ emit NewShortcut();
}
-
+
}
void ItemWidget::RemoveQL(){
qDebug() << "Remove QuickLaunch Button:" << icon->whatsThis();
@@ -282,7 +284,7 @@ void ItemWidget::RemoveQL(){
void ItemWidget::AddQL(){
qDebug() << "Add QuickLaunch Button:" << icon->whatsThis();
- emit toggleQuickLaunch(icon->whatsThis(), true);
+ emit toggleQuickLaunch(icon->whatsThis(), true);
}
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 562122ae..d8014f4c 100644
--- a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp
+++ b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp
@@ -25,9 +25,11 @@ LStartButtonPlugin::LStartButtonPlugin(QWidget *parent, QString id, bool horizon
startmenu = new StartMenu(this);
connect(startmenu, SIGNAL(CloseMenu()), this, SLOT(closeMenu()) );
connect(startmenu, SIGNAL(UpdateQuickLaunch(QStringList)), this, SLOT(updateQuickLaunch(QStringList)));
- //QRect screenSize = QApplication::desktop()->availableGeometry(this);
- QSize saved = LSession::handle()->DesktopPluginSettings()->value("panelPlugs/"+this->type()+"/MenuSize", QSize(0, 0)).toSize();
- if(!saved.isNull()){ startmenu->setFixedSize(saved); } //re-load the previously saved value
+
+ QRect screenSize = QApplication::desktop()->availableGeometry(this);
+ QSize saved = LSession::handle()->DesktopPluginSettings()->value("panelPlugs/"+this->type()+"/MenuSize",QSize(this->fontMetrics().width("x")*30 ,screenSize.height()/1.8)).toSize();
+ //qDebug() << "Got Start Menu Saved Size:" << saved;
+ if(!saved.isNull() && saved.isValid()){ startmenu->setFixedSize(saved); } //re-load the previously saved value
menu->setContents(startmenu);
button->setMenu(menu);
@@ -122,6 +124,7 @@ void LStartButtonPlugin::openMenu(){
menu->setContents(startmenu);
if(old!=0){ old->deleteLater(); }*/
//--------
+ //qDebug() << "Menu Size:" << startmenu->size();
startmenu->UpdateMenu();
button->showMenu();
}
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 272bf0fa..ee3e0f80 100644
--- a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp
+++ b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp
@@ -597,7 +597,7 @@ void StartMenu::on_tool_restart_clicked(){
LSession::handle()->StartReboot(true);
}
-void StartMenu::on_tool_restart_update_clicked(){
+void StartMenu::on_tool_restart_updates_clicked(){
emit CloseMenu();
QCoreApplication::processEvents();
//bool skipupdates = false;
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 41bc3ec4..0a90311d 100644
--- a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h
+++ b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h
@@ -73,7 +73,7 @@ private slots:
void on_tool_lock_clicked();
void on_tool_logout_clicked();
void on_tool_restart_clicked();
- void on_tool_restart_update_clicked();
+ void on_tool_restart_updates_clicked();
void on_tool_shutdown_clicked();
void on_tool_suspend_clicked();
diff --git a/src-qt5/core/lumina-info/lumina-info.pro b/src-qt5/core/lumina-info/lumina-info.pro
index 0c8693a0..dc07c08e 100644
--- a/src-qt5/core/lumina-info/lumina-info.pro
+++ b/src-qt5/core/lumina-info/lumina-info.pro
@@ -92,13 +92,13 @@ TRANSLATIONS = i18n/lumina-info_af.ts \
i18n/lumina-info_zu.ts
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
-dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
+dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
desktop.files=lumina-info.desktop lumina-support.desktop
desktop.path=$${L_SHAREDIR}/applications/
manpage.path=$${L_MANDIR}/man1/
-manpage.extra="$${MAN_ZIP} lumina-info.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-info.1.gz"
+manpage.extra="$${MAN_ZIP} $$PWD/lumina-info.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-info.1.gz"
INSTALLS += target desktop manpage
diff --git a/src-qt5/core/lumina-open/lumina-open.pro b/src-qt5/core/lumina-open/lumina-open.pro
index b31c7a0e..3bc7e9bf 100644
--- a/src-qt5/core/lumina-open/lumina-open.pro
+++ b/src-qt5/core/lumina-open/lumina-open.pro
@@ -87,10 +87,10 @@ TRANSLATIONS = i18n/lumina-open_af.ts \
i18n/lumina-open_zu.ts
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
-dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
+dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
manpage.path=$${L_MANDIR}/man1/
-manpage.extra="$${MAN_ZIP} lumina-open.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-open.1.gz"
+manpage.extra="$${MAN_ZIP} $$PWD/lumina-open.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-open.1.gz"
INSTALLS += target manpage
diff --git a/src-qt5/core/lumina-session/lumina-session.pro b/src-qt5/core/lumina-session/lumina-session.pro
index 797547db..9d8e8f87 100644
--- a/src-qt5/core/lumina-session/lumina-session.pro
+++ b/src-qt5/core/lumina-session/lumina-session.pro
@@ -16,6 +16,6 @@ SOURCES += main.cpp \
HEADERS += session.h
manpage.path=$${L_MANDIR}/man8/
-manpage.extra="$${MAN_ZIP} start-lumina-desktop.8 > $(INSTALL_ROOT)$${L_MANDIR}/man8/start-lumina-desktop.8.gz"
+manpage.extra="$${MAN_ZIP} $$PWD/start-lumina-desktop.8 > $(INSTALL_ROOT)$${L_MANDIR}/man8/start-lumina-desktop.8.gz"
INSTALLS += target manpage
diff --git a/src-qt5/core/lumina-theme-engine/lumina-theme-engine.pro b/src-qt5/core/lumina-theme-engine/lumina-theme-engine.pro
index e1023752..1e8b2ca4 100644
--- a/src-qt5/core/lumina-theme-engine/lumina-theme-engine.pro
+++ b/src-qt5/core/lumina-theme-engine/lumina-theme-engine.pro
@@ -3,7 +3,8 @@ include(../../OS-detect.pri)
TEMPLATE = subdirs
SUBDIRS += src/lthemeengine-qtplugin \
src/lthemeengine-style \
- src/lthemeengine
+ src/lthemeengine \
+ src/lthemeengine-sstest
colors.files = colors/*.conf
colors.path = $${L_SHAREDIR}/lthemeengine/colors
diff --git a/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss b/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss
index e8311e92..a9b165a6 100644
--- a/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss
+++ b/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss
@@ -1,26 +1,26 @@
/* SLIDERS */
QSlider::groove:horizontal {
-border: 1px solid transparent;
+border: 1px solid palette(mid);
background: palette(alternate-window);
height: 10px;
border-radius: 3px;
}
QSlider::groove:vertical {
-border: 1px solid transparent;
+border: 1px solid palette(mid);
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));
+ stop: 0 transparent, stop: 1 palette(highlight) );
border: 1px solid transparent;
height: 10px;
border-radius: 3px;
}
-QSlider::sub-page:vertical {
+QSlider::add-page:vertical {
background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1,
- stop: 0 palette(highlight), stop: 1 palette(window));
+ stop: 0 transparent, stop: 1 palette(highlight) );
border: 1px solid transparent;
width: 10px;
border-radius: 3px;
@@ -31,7 +31,7 @@ border: 1px solid transparent;
height: 10px;
border-radius: 3px;
}
-QSlider::add-page:vertical{
+QSlider::sub-page:vertical{
background: palette(alternate-window);
border: 1px solid transparent;
width: 10px;
@@ -40,13 +40,13 @@ border-radius: 3px;
QSlider::handle:horizontal{
background: palette(mid);
border: 1px solid palette(mid);
-width: 1em;
+width: 1ex;
border-radius: 1px;
}
QSlider::handle:vertical{
background: palette(mid);
border: 1px solid palette(mid);
-height: 1em;
+height: 1ex;
border-radius: 1px;
}
QSlider::handle:horizontal:hover, QSlider::handle:vertical:hover{
diff --git a/src-qt5/core/lumina-theme-engine/qss/traynotification-simple.qss b/src-qt5/core/lumina-theme-engine/qss/traynotification-simple.qss
new file mode 100644
index 00000000..43aff087
--- /dev/null
+++ b/src-qt5/core/lumina-theme-engine/qss/traynotification-simple.qss
@@ -0,0 +1,4 @@
+QBalloonTip{
+background-color: palette(base);
+color: palette(text);
+}
diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine-qtplugin/lthemeengineplatformtheme.cpp b/src-qt5/core/lumina-theme-engine/src/lthemeengine-qtplugin/lthemeengineplatformtheme.cpp
index 670e1c9c..e581b016 100644
--- a/src-qt5/core/lumina-theme-engine/src/lthemeengine-qtplugin/lthemeengineplatformtheme.cpp
+++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine-qtplugin/lthemeengineplatformtheme.cpp
@@ -43,7 +43,7 @@ lthemeenginePlatformTheme::lthemeenginePlatformTheme(){
#endif
QGuiApplication::setFont(m_generalFont);
}
- qCDebug(llthemeengine) << "using lthemeengine plugin";
+ //qCDebug(llthemeengine) << "using lthemeengine plugin";
#ifdef QT_WIDGETS_LIB
if(!QStyleFactory::keys().contains("lthemeengine-style"))
qCCritical(llthemeengine) << "unable to find lthemeengine proxy style";
@@ -60,7 +60,7 @@ QPlatformMenuBar *lthemeenginePlatformTheme::createPlatformMenuBar() const{
if(m_checkDBusGlobalMenu){
QDBusConnection conn = QDBusConnection::sessionBus();
m_dbusGlobalMenuAvailable = conn.interface()->isServiceRegistered("com.canonical.AppMenu.Registrar");
- qCDebug(llthemeengine) << "D-Bus global menu:" << (m_dbusGlobalMenuAvailable ? "yes" : "no");
+ //qCDebug(llthemeengine) << "D-Bus global menu:" << (m_dbusGlobalMenuAvailable ? "yes" : "no");
}
return (m_dbusGlobalMenuAvailable ? new QDBusMenuBar() : nullptr);
}
diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine-sstest/lthemeengine-sstest.pro b/src-qt5/core/lumina-theme-engine/src/lthemeengine-sstest/lthemeengine-sstest.pro
new file mode 100644
index 00000000..fadc6fcb
--- /dev/null
+++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine-sstest/lthemeengine-sstest.pro
@@ -0,0 +1,11 @@
+include(../../lthemeengine.pri)
+TEMPLATE = app
+QT *= widgets
+
+SOURCES += \
+ main.cpp
+
+TARGET = lthemeengine-sstest
+target.path = $${L_BINDIR}
+
+INSTALLS += target
diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine-sstest/main.cpp b/src-qt5/core/lumina-theme-engine/src/lthemeengine-sstest/main.cpp
new file mode 100644
index 00000000..bdab0a30
--- /dev/null
+++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine-sstest/main.cpp
@@ -0,0 +1,18 @@
+#include <QApplication>
+//#include <QDebug>
+#include <QWidget>
+
+#include <LUtils.h>
+
+int main(int argc, char **argv){
+ if(argc<2){ return 1; } //error
+ unsetenv("QT_QPA_PLATFORMTHEME"); //Make sure we are not testing anything related to the current theme engine
+ QString stylesheet = LUtils::readFile(argv[1]).join("\n");
+ //qDebug() << "Found Stylesheet:" << stylesheet;
+ QApplication app(argc, argv);
+ app.setStyleSheet(stylesheet);
+ //qDebug() << " Using Stylesheet:" << app.styleSheet();
+ QWidget tmp(0,Qt::SplashScreen | Qt::BypassWindowManagerHint);
+ tmp.show(); //needed to actually run the parser on the stylesheet (unused/unchecked otherwise)
+ return 0;
+}
diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.cpp b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.cpp
index ac891a80..56289931 100644
--- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.cpp
+++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.cpp
@@ -4,6 +4,12 @@
#include "qsseditordialog.h"
#include "ui_qsseditordialog.h"
+#include <QTemporaryFile>
+#include <QTextStream>
+
+#include <LuminaXDG.h>
+#include <LUtils.h>
+
QSSEditorDialog::QSSEditorDialog(const QString &filePath, QWidget *parent) : QDialog(parent), m_ui(new Ui::QSSEditorDialog){
m_ui->setupUi(this);
m_filePath = filePath;
@@ -37,6 +43,11 @@ QSSEditorDialog::QSSEditorDialog(const QString &filePath, QWidget *parent) : QDi
for(int i=0; i<colors.length(); i++){ colorMenu->addAction( colors[i].section("::::",0,0) )->setWhatsThis(colors[i].section("::::",1,1) ); }
m_ui->tool_color->setMenu(colorMenu);
connect(colorMenu, SIGNAL(triggered(QAction*)), this, SLOT(colorPicked(QAction*)) );
+ validateTimer = new QTimer(this);
+ validateTimer->setInterval(500); //1/2 second after finish typing
+ validateTimer->setSingleShot(true);
+ connect(validateTimer, SIGNAL(timeout()), this, SLOT(validateStyleSheet()) );
+ connect(m_ui->textEdit, SIGNAL(textChanged()), validateTimer, SLOT(start()) );
}
QSSEditorDialog::~QSSEditorDialog(){
@@ -69,3 +80,31 @@ void QSSEditorDialog::colorPicked(QAction* act){
if(id.isEmpty()){ return; }
m_ui->textEdit->insertPlainText( QString("palette(%1)").arg(id) );
}
+
+bool QSSEditorDialog::isStyleSheetValid(const QString &styleSheet){
+ QTemporaryFile tempfile;
+ if(tempfile.open()){
+ QTextStream out(&tempfile);
+ out << styleSheet;
+ out.flush();
+ tempfile.close();
+ }
+ QStringList log = LUtils::getCmdOutput("lthemeengine-sstest", QStringList() << tempfile.fileName());
+ qDebug() << "Got Validation Log:" << log;
+ return log.join("").simplified().isEmpty();
+}
+
+void QSSEditorDialog::validateStyleSheet(){
+ qDebug() << "Validating StyleSheet:";
+ bool ok = isStyleSheetValid(m_ui->textEdit->toPlainText());
+
+ //Now update the button/label as needed
+ int sz = this->fontMetrics().height();
+ if(ok){
+ m_ui->label_status_icon->setPixmap(LXDG::findIcon("dialog-ok","").pixmap(sz,sz) );
+ m_ui->label_status_icon->setToolTip(tr("Valid StyleSheet"));
+ }else{
+ m_ui->label_status_icon->setPixmap(LXDG::findIcon("dialog-cancel","").pixmap(sz,sz) );
+ m_ui->label_status_icon->setToolTip(tr("Invalid StyleSheet"));
+ }
+}
diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.h b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.h
index 114611fe..f51434e9 100644
--- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.h
+++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.h
@@ -5,6 +5,7 @@
#include <QString>
#include <QMenu>
#include <QAction>
+#include <QTimer>
namespace Ui {
class QSSEditorDialog;
@@ -23,6 +24,8 @@ public:
private slots:
void on_buttonBox_clicked(QAbstractButton *button);
void colorPicked(QAction*);
+ bool isStyleSheetValid(const QString&);
+ void validateStyleSheet();
private:
void save();
@@ -30,6 +33,7 @@ private:
Ui::QSSEditorDialog *m_ui;
QString m_filePath;
QMenu *colorMenu;
+ QTimer *validateTimer;
};
diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.ui b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.ui
index f75a21c6..68a14fb1 100644
--- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.ui
+++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsseditordialog.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>643</width>
- <height>499</height>
+ <width>808</width>
+ <height>512</height>
</rect>
</property>
<property name="windowTitle">
@@ -53,6 +53,38 @@
</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="QLabel" name="label_status_icon">
+ <property name="minimumSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="scaledContents">
+ <bool>false</bool>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
diff --git a/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp b/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp
index 47c6bfe1..3d901e8c 100644
--- a/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp
+++ b/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp
@@ -67,6 +67,8 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){
ui->actionUSB_Image->setEnabled(false);
loadIcons();
ui->tree_contents->setHeaderLabels( QStringList() << tr("File") << tr("MimeType") << tr("Size")+" " );
+
+ preservePaths = false;
}
MainUI::~MainUI(){
@@ -296,7 +298,7 @@ void MainUI::simpleExtractFiles(){
void MainUI::autoArchiveFiles(){
qDebug() << "Auto Archive Files:" << aaFileList;
ui->label_progress->setText(tr("Adding Items..."));
- BACKEND->startAdd(aaFileList);
+ BACKEND->startAdd(aaFileList, true);
}
void MainUI::extractSelection(){
diff --git a/src-qt5/desktop-utils/lumina-archiver/MainUI.h b/src-qt5/desktop-utils/lumina-archiver/MainUI.h
index 1a9d287c..0a5c094c 100644
--- a/src-qt5/desktop-utils/lumina-archiver/MainUI.h
+++ b/src-qt5/desktop-utils/lumina-archiver/MainUI.h
@@ -26,13 +26,14 @@ public:
void LoadArguments(QStringList);
void loadIcons();
+ bool preservePaths;
private:
Ui::MainUI *ui;
- Backend *BACKEND;
- QStringList aaFileList, sxList;
- QString sxPath, sxFile;
- QTimer *delayClose;
+ Backend *BACKEND;
+ 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
diff --git a/src-qt5/desktop-utils/lumina-archiver/TarBackend.cpp b/src-qt5/desktop-utils/lumina-archiver/TarBackend.cpp
index 5338efec..91e233d0 100644
--- a/src-qt5/desktop-utils/lumina-archiver/TarBackend.cpp
+++ b/src-qt5/desktop-utils/lumina-archiver/TarBackend.cpp
@@ -91,7 +91,7 @@ QString Backend::linkTo(QString file){
}
//Modification routines
-void Backend::startAdd(QStringList paths){
+void Backend::startAdd(QStringList paths, bool absolutePaths){
//if(paths.isEmpty() && !insertQueue.isEmpty()){ paths = insertQueue; } //load the queue
if(paths.contains(filepath)){ paths.removeAll(filepath); }
if(paths.isEmpty()){ return; }
@@ -109,11 +109,12 @@ void Backend::startAdd(QStringList paths){
args << "-c" << "-a";
args << flags;
//Now setup the parent dir
- for(int i=0; i<paths.length(); i++){
- paths[i] = paths[i].section(parent,1,-1);
- if(paths[i].startsWith("/")){ paths[i].remove(0,1); }
- }
- args << "-C" << parent;
+ if(!absolutePaths) {
+ for(int i=0; i<paths.length(); i++){
+ paths[i] = paths[i].section(parent,1,-1);
+ if(paths[i].startsWith("/")){ paths[i].remove(0,1); }
+ }
+ args << "-C" << parent; }
args << paths;
if(QFile::exists(filepath)){ //append to existing
args.replaceInStrings(filepath, tmpfilepath);
diff --git a/src-qt5/desktop-utils/lumina-archiver/TarBackend.h b/src-qt5/desktop-utils/lumina-archiver/TarBackend.h
index 56a7dcfe..cb24a053 100644
--- a/src-qt5/desktop-utils/lumina-archiver/TarBackend.h
+++ b/src-qt5/desktop-utils/lumina-archiver/TarBackend.h
@@ -33,7 +33,7 @@ public:
QString linkTo(QString file);
//Modification routines
- void startAdd(QStringList paths);
+ void startAdd(QStringList paths, bool absolutePaths = false);
void startRemove(QStringList paths);
void startExtract(QString path, bool overwrite, QString file=""); //path to dir, overwrite, optional file to extract (everything otherwise)
void startExtract(QString path, bool overwrite, QStringList files);
diff --git a/src-qt5/desktop-utils/lumina-archiver/lumina-archiver.pro b/src-qt5/desktop-utils/lumina-archiver/lumina-archiver.pro
index 763407b9..a1b10109 100644
--- a/src-qt5/desktop-utils/lumina-archiver/lumina-archiver.pro
+++ b/src-qt5/desktop-utils/lumina-archiver/lumina-archiver.pro
@@ -87,7 +87,7 @@ TRANSLATIONS = i18n/l-archiver_af.ts \
i18n/l-archiver_zu.ts
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
-dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
+dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
desktop.files=lumina-archiver.desktop
desktop.path=$${L_SHAREDIR}/applications/
@@ -96,7 +96,7 @@ desktop.path=$${L_SHAREDIR}/applications/
#link.extra=ln -sf lumina-archiver $(INSTALL_ROOT)$${L_BINDIR}/lpac
manpage.path=$${L_MANDIR}/man1/
-manpage.extra="$${MAN_ZIP} lumina-archiver.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-archiver.1.gz"
+manpage.extra="$${MAN_ZIP} $$PWD/lumina-archiver.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-archiver.1.gz"
INSTALLS += target desktop manpage
diff --git a/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_da.ts b/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_da.ts
index 5cdf9fa4..7ae80a69 100644
--- a/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_da.ts
+++ b/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_da.ts
@@ -16,7 +16,7 @@
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="610"/>
<source>Education</source>
- <translation>Uddannelse</translation>
+ <translation>Læring</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="611"/>
@@ -41,7 +41,7 @@
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="615"/>
<source>Science</source>
- <translation>Videnskab</translation>
+ <translation>Naturvidenskab</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="616"/>
@@ -56,7 +56,7 @@
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="618"/>
<source>Utility</source>
- <translation>Hjælpeværktøj</translation>
+ <translation>Redskab</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="619"/>
diff --git a/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_nl.ts b/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_nl.ts
index 9947da6d..1cba660b 100644
--- a/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_nl.ts
+++ b/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_nl.ts
@@ -6,67 +6,67 @@
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="608"/>
<source>Multimedia</source>
- <translation type="unfinished"></translation>
+ <translation>Multimedia</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="609"/>
<source>Development</source>
- <translation type="unfinished"></translation>
+ <translation>Ontwikkeling</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="610"/>
<source>Education</source>
- <translation type="unfinished"></translation>
+ <translation>Onderwijs</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="611"/>
<source>Games</source>
- <translation type="unfinished"></translation>
+ <translation>Spellen</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="612"/>
<source>Graphics</source>
- <translation type="unfinished"></translation>
+ <translation>Grafisch</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="613"/>
<source>Network</source>
- <translation type="unfinished"></translation>
+ <translation>Netwerk</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="614"/>
<source>Office</source>
- <translation type="unfinished"></translation>
+ <translation>Kantoor</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="615"/>
<source>Science</source>
- <translation type="unfinished"></translation>
+ <translation>Wetenschappelijk</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="616"/>
<source>Settings</source>
- <translation type="unfinished"></translation>
+ <translation>Instellingen</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="617"/>
<source>System</source>
- <translation type="unfinished"></translation>
+ <translation>Systeem</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="618"/>
<source>Utility</source>
- <translation type="unfinished"></translation>
+ <translation>Hulpmiddel</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="619"/>
<source>Wine</source>
- <translation type="unfinished"></translation>
+ <translation>Wine</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="620"/>
<source>Unsorted</source>
- <translation type="unfinished"></translation>
+ <translation>Ongesorteerd</translation>
</message>
</context>
<context>
@@ -75,22 +75,22 @@
<location filename="../mainUI.ui" line="14"/>
<location filename="../mainUI.cpp" line="53"/>
<source>Calculator</source>
- <translation type="unfinished"></translation>
+ <translation>Rekenmachine</translation>
</message>
<message>
<location filename="../mainUI.ui" line="657"/>
<source>Advanced Operations</source>
- <translation type="unfinished"></translation>
+ <translation>Geavanceerde bewerkingen</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="83"/>
<source>Percentage %1</source>
- <translation type="unfinished"></translation>
+ <translation>Percentage %1</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="85"/>
<source>Power %1</source>
- <translation type="unfinished"></translation>
+ <translation>Prestatie %1</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="87"/>
diff --git a/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_pt_BR.ts b/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_pt_BR.ts
index 153a01b4..e26ecb58 100644
--- a/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_pt_BR.ts
+++ b/src-qt5/desktop-utils/lumina-calculator/i18n/l-calc_pt_BR.ts
@@ -6,67 +6,67 @@
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="608"/>
<source>Multimedia</source>
- <translation type="unfinished"></translation>
+ <translation>Multimídia</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="609"/>
<source>Development</source>
- <translation type="unfinished"></translation>
+ <translation>Desenvolvimento</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="610"/>
<source>Education</source>
- <translation type="unfinished"></translation>
+ <translation>Educação</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="611"/>
<source>Games</source>
- <translation type="unfinished"></translation>
+ <translation>Jogos</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="612"/>
<source>Graphics</source>
- <translation type="unfinished"></translation>
+ <translation>Gráficos</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="613"/>
<source>Network</source>
- <translation type="unfinished"></translation>
+ <translation>Rede</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="614"/>
<source>Office</source>
- <translation type="unfinished"></translation>
+ <translation>Escritório</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="615"/>
<source>Science</source>
- <translation type="unfinished"></translation>
+ <translation>Ciência</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="616"/>
<source>Settings</source>
- <translation type="unfinished"></translation>
+ <translation>Configurações</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="617"/>
<source>System</source>
- <translation type="unfinished"></translation>
+ <translation>Sistema</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="618"/>
<source>Utility</source>
- <translation type="unfinished"></translation>
+ <translation>Utilitários</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="619"/>
<source>Wine</source>
- <translation type="unfinished"></translation>
+ <translation>Wine</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="620"/>
<source>Unsorted</source>
- <translation type="unfinished"></translation>
+ <translation>Não classificado</translation>
</message>
</context>
<context>
diff --git a/src-qt5/desktop-utils/lumina-calculator/lumina-calculator.pro b/src-qt5/desktop-utils/lumina-calculator/lumina-calculator.pro
index c2314545..07490634 100644
--- a/src-qt5/desktop-utils/lumina-calculator/lumina-calculator.pro
+++ b/src-qt5/desktop-utils/lumina-calculator/lumina-calculator.pro
@@ -84,13 +84,13 @@ TRANSLATIONS = i18n/l-calc_af.ts \
i18n/l-calc_zu.ts
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
-dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
+dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
desktop.files=lumina-calculator.desktop
desktop.path=$${L_SHAREDIR}/applications/
manpage.path=$${L_MANDIR}/man1/
-manpage.extra="$${MAN_ZIP} lumina-calculator.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-calculator.1.gz"
+manpage.extra="$${MAN_ZIP} $$PWD/lumina-calculator.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-calculator.1.gz"
INSTALLS += target desktop manpage
diff --git a/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro b/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro
index 8a850a1c..dcfee470 100644
--- a/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro
+++ b/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro
@@ -89,13 +89,13 @@ TRANSLATIONS = i18n/l-fileinfo_af.ts \
i18n/l-fileinfo_zu.ts
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
-dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
+dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
desktop.files=lumina-fileinfo.desktop
desktop.path=$${L_SHAREDIR}/applications/
manpage.path=$${L_MANDIR}/man1/
-manpage.extra="$${MAN_ZIP} lumina-fileinfo.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-fileinfo.1.gz"
+manpage.extra="$${MAN_ZIP} $$PWD/lumina-fileinfo.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-fileinfo.1.gz"
INSTALLS += target desktop manpage
diff --git a/src-qt5/desktop-utils/lumina-fm/MainUI.cpp b/src-qt5/desktop-utils/lumina-fm/MainUI.cpp
index 28bfa20b..8455e3aa 100644
--- a/src-qt5/desktop-utils/lumina-fm/MainUI.cpp
+++ b/src-qt5/desktop-utils/lumina-fm/MainUI.cpp
@@ -118,6 +118,7 @@ QSize orig = settings->value("preferences/MainWindowSize", QSize()).toSize();
connect(TRAY, SIGNAL(JobsFinished()), this, SLOT(TrayJobsFinished()) );
if(DEBUG){ qDebug() << " - Done with init"; }
ui->actionOpen_as_Root->setVisible(LUtils::isValidBinary("qsudo"));
+ ui->transferTreeView->setVisible(false);
}
MainUI::~MainUI(){
diff --git a/src-qt5/desktop-utils/lumina-fm/MainUI.ui b/src-qt5/desktop-utils/lumina-fm/MainUI.ui
index a15f91c9..5f067786 100644
--- a/src-qt5/desktop-utils/lumina-fm/MainUI.ui
+++ b/src-qt5/desktop-utils/lumina-fm/MainUI.ui
@@ -69,7 +69,7 @@
<x>0</x>
<y>0</y>
<width>567</width>
- <height>359</height>
+ <height>161</height>
</rect>
</property>
<layout class="QHBoxLayout" name="BrowserLayout">
@@ -98,6 +98,16 @@
<widget class="QWidget" name="page_image"/>
</widget>
</item>
+ <item>
+ <widget class="QTreeView" name="transferTreeView">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
diff --git a/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro b/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro
index 4f66ce0a..b59aface 100644
--- a/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro
+++ b/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro
@@ -126,13 +126,13 @@ TRANSLATIONS = i18n/lumina-fm_af.ts \
i18n/lumina-fm_zu.ts
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
-dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
+dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
desktop.files=lumina-fm.desktop
desktop.path=$${L_SHAREDIR}/applications/
manpage.path=$${L_MANDIR}/man1/
-manpage.extra="$${MAN_ZIP} lumina-fm.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-fm.1.gz"
+manpage.extra="$${MAN_ZIP} $$PWD/lumina-fm.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-fm.1.gz"
INSTALLS += target desktop icons manpage
diff --git a/src-qt5/desktop-utils/lumina-fm/transferd.cpp b/src-qt5/desktop-utils/lumina-fm/transferd.cpp
new file mode 100644
index 00000000..c5a0a156
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-fm/transferd.cpp
@@ -0,0 +1,28 @@
+
+
+int totaltransactions = sel.length();
+QList<TransactionInfo> transaction;
+for(int i=0;i<sel.length();i++){
+ QStringList info;
+ info << sel[i] << sel[i].size() << false;
+ totalsize = totalsize + sel[i].size();
+}
+bool paused = false;
+for(int i=0; i<transaction.length(); i++){
+
+while(paused = 1 ){
+ pausetimer = new QTimer(this);
+ pausetimer->start(5000);
+}
+QElapsedTimer timer;
+timer.start();
+//copy/move file
+timer.elapsed(); // "milliseconds"
+transferTime = transferTime + timer.elapsed()
+transaction[i].value(2) = true;
+currentTransfered++;
+currentTransferedSize = currentTransferedSize + transaction[i].value(1);
+//calculate transfer data rate from transferTime and currentTransferedSize
+avgTransferRate = ( currentTransferedSize / (transferTime * 1000) )
+//can do estimates on potential time?
+}
diff --git a/src-qt5/desktop-utils/lumina-fm/transferd.h b/src-qt5/desktop-utils/lumina-fm/transferd.h
new file mode 100644
index 00000000..291541e8
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-fm/transferd.h
@@ -0,0 +1,13 @@
+class transactionInfo{
+public:
+ QString filepath;
+ qint64 filesize;
+ Bool finished;
+};
+
+
+QStringList sel;
+int totaltransactions currentTransfered;
+qint64 totalsize, currentTransferedSize, transferTime, avgTransferRate;
+bool paused;
+QElapsedTimer timer;
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_ca.ts b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_ca.ts
index ba197b5c..de6a4daf 100644
--- a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_ca.ts
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_ca.ts
@@ -59,12 +59,12 @@
<message>
<location filename="../mainUI.ui" line="368"/>
<source>Love this song</source>
- <translation>M&apos;agrada aquesta cançó</translation>
+ <translation>M'agrada aquesta cançó</translation>
</message>
<message>
<location filename="../mainUI.ui" line="384"/>
<source>Tired of this song (will not play for a month)</source>
- <translation>Cansat d&apos;aquesta cançó (no sonarà durant un mes)</translation>
+ <translation>Cansat d'aquesta cançó (no sonarà durant un mes)</translation>
</message>
<message>
<location filename="../mainUI.ui" line="397"/>
@@ -84,7 +84,7 @@
<message>
<location filename="../mainUI.ui" line="479"/>
<source>Delete current station</source>
- <translation>Suprimeix l&apos;emissora actual</translation>
+ <translation>Suprimeix l'emissora actual</translation>
</message>
<message>
<location filename="../mainUI.ui" line="482"/>
@@ -129,17 +129,17 @@
<message>
<location filename="../mainUI.ui" line="573"/>
<source>Audio Quality</source>
- <translation>Qualitat de l&apos;àudio</translation>
+ <translation>Qualitat de l'àudio</translation>
</message>
<message>
<location filename="../mainUI.ui" line="583"/>
<source>Proxy URL</source>
- <translation>URL de l&apos;intermediari</translation>
+ <translation>URL de l'intermediari</translation>
</message>
<message>
<location filename="../mainUI.ui" line="593"/>
<source>Control Proxy URL</source>
- <translation>Control de l&apos;URL de l&apos;intermediari</translation>
+ <translation>Control de l'URL de l'intermediari</translation>
</message>
<message>
<location filename="../mainUI.ui" line="618"/>
@@ -149,7 +149,7 @@
<message>
<location filename="../mainUI.ui" line="656"/>
<source>Audio Driver</source>
- <translation>Controlador d&apos;àudio</translation>
+ <translation>Controlador d'àudio</translation>
</message>
<message>
<location filename="../mainUI.ui" line="681"/>
@@ -194,7 +194,7 @@
<message>
<location filename="../mainUI.ui" line="751"/>
<source>Raise audio volume</source>
- <translation>Apuja el volum de l&apos;àudio</translation>
+ <translation>Apuja el volum de l'àudio</translation>
</message>
<message>
<location filename="../mainUI.ui" line="756"/>
@@ -204,12 +204,12 @@
<message>
<location filename="../mainUI.ui" line="759"/>
<source>Lower audio volume</source>
- <translation>Abaixa el volum de l&apos;àudio</translation>
+ <translation>Abaixa el volum de l'àudio</translation>
</message>
<message>
<location filename="../mainUI.ui" line="764"/>
<source>Close Application</source>
- <translation>Tanca l&apos;aplicació</translation>
+ <translation>Tanca l'aplicació</translation>
</message>
<message>
<location filename="../mainUI.ui" line="767"/>
@@ -224,12 +224,12 @@
<message>
<location filename="../mainUI.ui" line="786"/>
<source>From current artist</source>
- <translation>De l&apos;artista actual</translation>
+ <translation>De l'artista actual</translation>
</message>
<message>
<location filename="../mainUI.ui" line="789"/>
<source>Create station from current artist</source>
- <translation>Crea una emissora de l&apos;artista actual</translation>
+ <translation>Crea una emissora de l'artista actual</translation>
</message>
<message>
<location filename="../mainUI.ui" line="794"/>
@@ -280,7 +280,7 @@
<message>
<location filename="../mainUI.cpp" line="105"/>
<source>Please install the `pianobar` utility to enable this functionality</source>
- <translation>Si us plau, instal·leu la utilitat &quot;pianobar&quot; per habilitar aquesta funcionalitat.</translation>
+ <translation>Si us plau, instal·leu la utilitat "pianobar" per habilitar aquesta funcionalitat.</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="109"/>
@@ -332,7 +332,7 @@
<message>
<location filename="../mainUI.cpp" line="492"/>
<source>Media Buffering...</source>
- <translation>S&apos;omple la memòria intermèdia...</translation>
+ <translation>S'omple la memòria intermèdia...</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="576"/>
@@ -368,67 +368,67 @@
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="608"/>
<source>Multimedia</source>
- <translation type="unfinished"></translation>
+ <translation>Multimèdia</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="609"/>
<source>Development</source>
- <translation type="unfinished"></translation>
+ <translation>Desenvolupament</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="610"/>
<source>Education</source>
- <translation type="unfinished"></translation>
+ <translation>Educació</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="611"/>
<source>Games</source>
- <translation type="unfinished"></translation>
+ <translation>Jocs</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="612"/>
<source>Graphics</source>
- <translation type="unfinished"></translation>
+ <translation>Gràfics</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="613"/>
<source>Network</source>
- <translation type="unfinished"></translation>
+ <translation>Xarxa</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="614"/>
<source>Office</source>
- <translation type="unfinished"></translation>
+ <translation>Oficina</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="615"/>
<source>Science</source>
- <translation type="unfinished"></translation>
+ <translation>Ciència</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="616"/>
<source>Settings</source>
- <translation type="unfinished">Paràmetres</translation>
+ <translation>Paràmetres</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="617"/>
<source>System</source>
- <translation type="unfinished"></translation>
+ <translation>Sistema</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="618"/>
<source>Utility</source>
- <translation type="unfinished"></translation>
+ <translation>Utilitat</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="619"/>
<source>Wine</source>
- <translation type="unfinished"></translation>
+ <translation>Wine</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="620"/>
<source>Unsorted</source>
- <translation type="unfinished"></translation>
+ <translation>Sense classificar</translation>
</message>
</context>
</TS>
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_cs.ts b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_cs.ts
index b434a529..d1e93554 100644
--- a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_cs.ts
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_cs.ts
@@ -368,67 +368,67 @@
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="608"/>
<source>Multimedia</source>
- <translation type="unfinished"></translation>
+ <translation>Multimédia</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="609"/>
<source>Development</source>
- <translation type="unfinished"></translation>
+ <translation>Vývoj</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="610"/>
<source>Education</source>
- <translation type="unfinished"></translation>
+ <translation>Výuka</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="611"/>
<source>Games</source>
- <translation type="unfinished"></translation>
+ <translation>Hry</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="612"/>
<source>Graphics</source>
- <translation type="unfinished"></translation>
+ <translation>Grafika</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="613"/>
<source>Network</source>
- <translation type="unfinished"></translation>
+ <translation>Sítě</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="614"/>
<source>Office</source>
- <translation type="unfinished"></translation>
+ <translation>Kancelář</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="615"/>
<source>Science</source>
- <translation type="unfinished"></translation>
+ <translation>Věda</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="616"/>
<source>Settings</source>
- <translation type="unfinished">Nastavení</translation>
+ <translation>Nastavení</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="617"/>
<source>System</source>
- <translation type="unfinished"></translation>
+ <translation>Systém</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="618"/>
<source>Utility</source>
- <translation type="unfinished"></translation>
+ <translation>Nástroje</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="619"/>
<source>Wine</source>
- <translation type="unfinished"></translation>
+ <translation>Wine</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="620"/>
<source>Unsorted</source>
- <translation type="unfinished"></translation>
+ <translation>Různé</translation>
</message>
</context>
</TS>
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_da.ts b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_da.ts
index b2f87e32..612ae523 100644
--- a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_da.ts
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_da.ts
@@ -368,67 +368,67 @@
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="608"/>
<source>Multimedia</source>
- <translation type="unfinished"></translation>
+ <translation>Multimedie</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="609"/>
<source>Development</source>
- <translation type="unfinished"></translation>
+ <translation>Udvikling</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="610"/>
<source>Education</source>
- <translation type="unfinished"></translation>
+ <translation>Læring</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="611"/>
<source>Games</source>
- <translation type="unfinished"></translation>
+ <translation>Spil</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="612"/>
<source>Graphics</source>
- <translation type="unfinished"></translation>
+ <translation>Grafik</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="613"/>
<source>Network</source>
- <translation type="unfinished"></translation>
+ <translation>Netværk</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="614"/>
<source>Office</source>
- <translation type="unfinished"></translation>
+ <translation>Kontor</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="615"/>
<source>Science</source>
- <translation type="unfinished"></translation>
+ <translation>Naturvidenskab</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="616"/>
<source>Settings</source>
- <translation type="unfinished">Indstillinger</translation>
+ <translation>Indstillinger</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="617"/>
<source>System</source>
- <translation type="unfinished"></translation>
+ <translation>System</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="618"/>
<source>Utility</source>
- <translation type="unfinished"></translation>
+ <translation>Redskab</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="619"/>
<source>Wine</source>
- <translation type="unfinished"></translation>
+ <translation>Wine</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="620"/>
<source>Unsorted</source>
- <translation type="unfinished"></translation>
+ <translation>Usorteret</translation>
</message>
</context>
</TS>
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_de.ts b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_de.ts
index 7ab5151e..ac56615b 100644
--- a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_de.ts
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_de.ts
@@ -7,94 +7,94 @@
<location filename="../mainUI.ui" line="14"/>
<location filename="../mainUI.cpp" line="285"/>
<source>Media Player</source>
- <translation type="unfinished"></translation>
+ <translation>Medienabspieler</translation>
</message>
<message>
<location filename="../mainUI.ui" line="50"/>
<location filename="../mainUI.ui" line="261"/>
<location filename="../mainUI.cpp" line="631"/>
<source>Now Playing</source>
- <translation type="unfinished"></translation>
+ <translation>Wiedergabe läuft jetzt</translation>
</message>
<message>
<location filename="../mainUI.ui" line="74"/>
<source>(No Running Video)</source>
- <translation type="unfinished"></translation>
+ <translation>(Kein laufendes Video)</translation>
</message>
<message>
<location filename="../mainUI.ui" line="105"/>
<source>Playlist</source>
- <translation type="unfinished"></translation>
+ <translation>Wiedergabeliste</translation>
</message>
<message>
<location filename="../mainUI.ui" line="167"/>
<source>up</source>
- <translation type="unfinished"></translation>
+ <translation>hinauf</translation>
</message>
<message>
<location filename="../mainUI.ui" line="183"/>
<source>down</source>
- <translation type="unfinished"></translation>
+ <translation>herab</translation>
</message>
<message>
<location filename="../mainUI.ui" line="267"/>
<source>Current Song</source>
- <translation type="unfinished"></translation>
+ <translation>Aktueller Song</translation>
</message>
<message>
<location filename="../mainUI.ui" line="303"/>
<source>TITLE</source>
- <translation type="unfinished"></translation>
+ <translation>TITEL</translation>
</message>
<message>
<location filename="../mainUI.ui" line="327"/>
<source>ARTIST</source>
- <translation type="unfinished"></translation>
+ <translation>INTERPRET</translation>
</message>
<message>
<location filename="../mainUI.ui" line="337"/>
<source>ALBUM</source>
- <translation type="unfinished"></translation>
+ <translation>ALBUM</translation>
</message>
<message>
<location filename="../mainUI.ui" line="368"/>
<source>Love this song</source>
- <translation type="unfinished"></translation>
+ <translation>Liebe diesen Song</translation>
</message>
<message>
<location filename="../mainUI.ui" line="384"/>
<source>Tired of this song (will not play for a month)</source>
- <translation type="unfinished"></translation>
+ <translation>Müde von diesem Song (wird einen Monat lang nicht gespielt)</translation>
</message>
<message>
<location filename="../mainUI.ui" line="397"/>
<source>Ban this song (will never play again)</source>
- <translation type="unfinished"></translation>
+ <translation>Diesen Song verbannen (wird nie wieder abgespielt)</translation>
</message>
<message>
<location filename="../mainUI.ui" line="417"/>
<source>View details about song (launches web browser)</source>
- <translation type="unfinished"></translation>
+ <translation>Details zum Song anzeigen (startet den Webbrowser)</translation>
</message>
<message>
<location filename="../mainUI.ui" line="448"/>
<source>Current Station</source>
- <translation type="unfinished"></translation>
+ <translation>Aktueller Sender</translation>
</message>
<message>
<location filename="../mainUI.ui" line="479"/>
<source>Delete current station</source>
- <translation type="unfinished"></translation>
+ <translation>Aktuellen Sender löschen</translation>
</message>
<message>
<location filename="../mainUI.ui" line="482"/>
<source>rm</source>
- <translation type="unfinished"></translation>
+ <translation>rm</translation>
</message>
<message>
<location filename="../mainUI.ui" line="492"/>
<source>Create new station</source>
- <translation type="unfinished"></translation>
+ <translation>Neuen Sender erstellen</translation>
</message>
<message>
<location filename="../mainUI.ui" line="495"/>
@@ -104,37 +104,37 @@
<message>
<location filename="../mainUI.ui" line="512"/>
<source>Settings</source>
- <translation type="unfinished"></translation>
+ <translation>Einstellungen</translation>
</message>
<message>
<location filename="../mainUI.ui" line="521"/>
<source>Pandora Account Login</source>
- <translation type="unfinished"></translation>
+ <translation>Pandora-Kontoanmeldung</translation>
</message>
<message>
<location filename="../mainUI.ui" line="527"/>
<source>Email</source>
- <translation type="unfinished"></translation>
+ <translation>E-Mail</translation>
</message>
<message>
<location filename="../mainUI.ui" line="537"/>
<source>Password</source>
- <translation type="unfinished"></translation>
+ <translation>Passwort</translation>
</message>
<message>
<location filename="../mainUI.ui" line="557"/>
<source>&lt;a href=https://www.pandora.com/account/register&gt;Need an account?&lt;/a&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;a href=https://www.pandora.com/account/register&gt;Benötigen Sie ein Konto?&lt;/a&gt;</translation>
</message>
<message>
<location filename="../mainUI.ui" line="573"/>
<source>Audio Quality</source>
- <translation type="unfinished"></translation>
+ <translation>Audioqualität</translation>
</message>
<message>
<location filename="../mainUI.ui" line="583"/>
<source>Proxy URL</source>
- <translation type="unfinished"></translation>
+ <translation>Proxy-URL</translation>
</message>
<message>
<location filename="../mainUI.ui" line="593"/>
@@ -144,77 +144,77 @@
<message>
<location filename="../mainUI.ui" line="618"/>
<source>Apply Settings</source>
- <translation type="unfinished"></translation>
+ <translation>Einstellungen anwenden</translation>
</message>
<message>
<location filename="../mainUI.ui" line="656"/>
<source>Audio Driver</source>
- <translation type="unfinished"></translation>
+ <translation>Audiotreiber</translation>
</message>
<message>
<location filename="../mainUI.ui" line="681"/>
<source>File</source>
- <translation type="unfinished"></translation>
+ <translation>Datei</translation>
</message>
<message>
<location filename="../mainUI.ui" line="688"/>
<source>View</source>
- <translation type="unfinished"></translation>
+ <translation>Ansicht</translation>
</message>
<message>
<location filename="../mainUI.ui" line="723"/>
<source>Play</source>
- <translation type="unfinished"></translation>
+ <translation>Wiedergabe</translation>
</message>
<message>
<location filename="../mainUI.ui" line="728"/>
<source>Pause</source>
- <translation type="unfinished"></translation>
+ <translation>Pause</translation>
</message>
<message>
<location filename="../mainUI.ui" line="733"/>
<source>Stop</source>
- <translation type="unfinished"></translation>
+ <translation>Stopp</translation>
</message>
<message>
<location filename="../mainUI.ui" line="738"/>
<source>Next</source>
- <translation type="unfinished"></translation>
+ <translation>Weiter</translation>
</message>
<message>
<location filename="../mainUI.ui" line="743"/>
<source>Back</source>
- <translation type="unfinished"></translation>
+ <translation>Zurück</translation>
</message>
<message>
<location filename="../mainUI.ui" line="748"/>
<source>VolUp</source>
- <translation type="unfinished"></translation>
+ <translation>Lautstärke erhöhen</translation>
</message>
<message>
<location filename="../mainUI.ui" line="751"/>
<source>Raise audio volume</source>
- <translation type="unfinished"></translation>
+ <translation>Audiolautstärke erhöhen</translation>
</message>
<message>
<location filename="../mainUI.ui" line="756"/>
<source>VolDown</source>
- <translation type="unfinished"></translation>
+ <translation>Lautstärke verringern</translation>
</message>
<message>
<location filename="../mainUI.ui" line="759"/>
<source>Lower audio volume</source>
- <translation type="unfinished"></translation>
+ <translation>Audiolautstärke verringern</translation>
</message>
<message>
<location filename="../mainUI.ui" line="764"/>
<source>Close Application</source>
- <translation type="unfinished"></translation>
+ <translation>Anwendung schließen</translation>
</message>
<message>
<location filename="../mainUI.ui" line="767"/>
<source>Ctrl+Q</source>
- <translation type="unfinished"></translation>
+ <translation>Strg+Q</translation>
</message>
<message>
<location filename="../mainUI.ui" line="781"/>
@@ -224,7 +224,7 @@
<message>
<location filename="../mainUI.ui" line="786"/>
<source>From current artist</source>
- <translation type="unfinished"></translation>
+ <translation>Vom aktuellen Interpreten</translation>
</message>
<message>
<location filename="../mainUI.ui" line="789"/>
@@ -234,7 +234,7 @@
<message>
<location filename="../mainUI.ui" line="794"/>
<source>From current song</source>
- <translation type="unfinished"></translation>
+ <translation>Vom aktuellen Song</translation>
</message>
<message>
<location filename="../mainUI.ui" line="797"/>
@@ -244,84 +244,85 @@
<message>
<location filename="../mainUI.ui" line="808"/>
<source>Show song notifications</source>
- <translation type="unfinished"></translation>
+ <translation>Song-Benachrichtigungen anzeigen</translation>
</message>
<message>
<location filename="../mainUI.ui" line="813"/>
<source>Search...</source>
- <translation type="unfinished"></translation>
+ <translation>Suchen...</translation>
</message>
<message>
<location filename="../mainUI.ui" line="816"/>
<source>Search for a new station</source>
- <translation type="unfinished"></translation>
+ <translation>Einen neuen Sender suchen</translation>
</message>
<message>
<location filename="../mainUI.ui" line="828"/>
<location filename="../mainUI.cpp" line="276"/>
<source>Pandora Radio</source>
- <translation type="unfinished"></translation>
+ <translation>Pandora Radio</translation>
</message>
<message>
<location filename="../mainUI.ui" line="831"/>
<source>Stream from Pandora Radio</source>
- <translation type="unfinished"></translation>
+ <translation>Stream von Pandora Radio</translation>
</message>
<message>
<location filename="../mainUI.ui" line="839"/>
<source>Local Files</source>
- <translation type="unfinished"></translation>
+ <translation>Lokale Dateien</translation>
</message>
<message>
<location filename="../mainUI.ui" line="842"/>
<source>Play Local Files</source>
- <translation type="unfinished"></translation>
+ <translation>Lokale Dateien wiedergeben</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="105"/>
<source>Please install the `pianobar` utility to enable this functionality</source>
- <translation type="unfinished"></translation>
+ <translation>Bitte installieren Sie das Dienstprogramm `pianobar`, um diese Funktionalität zu aktivieren</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="109"/>
<source>Stream music from the Pandora online radio service</source>
- <translation type="unfinished"></translation>
+ <translation>Streaming von Musik vom Pandora Online-Radiodienst</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="122"/>
<source>Low</source>
- <translation type="unfinished"></translation>
+ <translation>Niedrig</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="123"/>
<source>Medium</source>
- <translation type="unfinished"></translation>
+ <translation>Mittel</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="124"/>
<source>High</source>
- <translation type="unfinished"></translation>
+ <translation>Hoch</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="358"/>
<source>Open Multimedia Files</source>
- <translation type="unfinished"></translation>
+ <translation>Multimedia-Dateien öffnen</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="406"/>
<source>Now Playing:</source>
- <translation type="unfinished"></translation>
+ <translation>Wird gerade wiedergegeben:</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="471"/>
<source>[PLAYBACK ERROR]
%1</source>
- <translation type="unfinished"></translation>
+ <translation>[WIEDERGABEFEHLER]
+%1</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="488"/>
<source>Media Loading...</source>
- <translation type="unfinished"></translation>
+ <translation>Medieninhalt wird geladen...</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="490"/>
@@ -331,27 +332,27 @@
<message>
<location filename="../mainUI.cpp" line="492"/>
<source>Media Buffering...</source>
- <translation type="unfinished"></translation>
+ <translation>Medieninhalt wird gepuffert...</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="576"/>
<source>Pandora: Create Station</source>
- <translation type="unfinished"></translation>
+ <translation>Pandora: Sender erstellen</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="576"/>
<source>Search Term</source>
- <translation type="unfinished"></translation>
+ <translation>Suchbegriff</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="654"/>
<source>Pandora Question</source>
- <translation type="unfinished"></translation>
+ <translation>Pandora-Frage</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="659"/>
<source>Pandora Error</source>
- <translation type="unfinished"></translation>
+ <translation>Pandora-Fehler</translation>
</message>
</context>
<context>
@@ -359,7 +360,7 @@
<message>
<location filename="../PianoBarProcess.cpp" line="358"/>
<source>Could not find any matches. Please try a different search term</source>
- <translation type="unfinished"></translation>
+ <translation>Keine Treffer gefunden. Bitte versuchen Sie einen anderen Suchbegriff</translation>
</message>
</context>
<context>
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_fi.ts b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_fi.ts
index 632ef536..5d01912a 100644
--- a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_fi.ts
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_fi.ts
@@ -7,134 +7,134 @@
<location filename="../mainUI.ui" line="14"/>
<location filename="../mainUI.cpp" line="285"/>
<source>Media Player</source>
- <translation type="unfinished"></translation>
+ <translation>Mediasoitin</translation>
</message>
<message>
<location filename="../mainUI.ui" line="50"/>
<location filename="../mainUI.ui" line="261"/>
<location filename="../mainUI.cpp" line="631"/>
<source>Now Playing</source>
- <translation type="unfinished"></translation>
+ <translation>Nyt soi</translation>
</message>
<message>
<location filename="../mainUI.ui" line="74"/>
<source>(No Running Video)</source>
- <translation type="unfinished"></translation>
+ <translation>(Ei videota käynnissä)</translation>
</message>
<message>
<location filename="../mainUI.ui" line="105"/>
<source>Playlist</source>
- <translation type="unfinished"></translation>
+ <translation>Soittolista</translation>
</message>
<message>
<location filename="../mainUI.ui" line="167"/>
<source>up</source>
- <translation type="unfinished"></translation>
+ <translation>ylemmäs</translation>
</message>
<message>
<location filename="../mainUI.ui" line="183"/>
<source>down</source>
- <translation type="unfinished"></translation>
+ <translation>alemmas</translation>
</message>
<message>
<location filename="../mainUI.ui" line="267"/>
<source>Current Song</source>
- <translation type="unfinished"></translation>
+ <translation>Nykyinen kappale</translation>
</message>
<message>
<location filename="../mainUI.ui" line="303"/>
<source>TITLE</source>
- <translation type="unfinished"></translation>
+ <translation>NIMI</translation>
</message>
<message>
<location filename="../mainUI.ui" line="327"/>
<source>ARTIST</source>
- <translation type="unfinished"></translation>
+ <translation>ARTISTI</translation>
</message>
<message>
<location filename="../mainUI.ui" line="337"/>
<source>ALBUM</source>
- <translation type="unfinished"></translation>
+ <translation>ALBUMI</translation>
</message>
<message>
<location filename="../mainUI.ui" line="368"/>
<source>Love this song</source>
- <translation type="unfinished"></translation>
+ <translation>Tykkään tästä</translation>
</message>
<message>
<location filename="../mainUI.ui" line="384"/>
<source>Tired of this song (will not play for a month)</source>
- <translation type="unfinished"></translation>
+ <translation>Kyllästynyt tähän (ei soiteta kuukauteen)</translation>
</message>
<message>
<location filename="../mainUI.ui" line="397"/>
<source>Ban this song (will never play again)</source>
- <translation type="unfinished"></translation>
+ <translation>Estä tämä (ei soiteta enää)</translation>
</message>
<message>
<location filename="../mainUI.ui" line="417"/>
<source>View details about song (launches web browser)</source>
- <translation type="unfinished"></translation>
+ <translation>Näytä kappaleen tiedot (käynnistää verkkoselaimen)</translation>
</message>
<message>
<location filename="../mainUI.ui" line="448"/>
<source>Current Station</source>
- <translation type="unfinished"></translation>
+ <translation>Nykyinen asema</translation>
</message>
<message>
<location filename="../mainUI.ui" line="479"/>
<source>Delete current station</source>
- <translation type="unfinished"></translation>
+ <translation>Poista nykyinen asema</translation>
</message>
<message>
<location filename="../mainUI.ui" line="482"/>
<source>rm</source>
- <translation type="unfinished"></translation>
+ <translation>poista</translation>
</message>
<message>
<location filename="../mainUI.ui" line="492"/>
<source>Create new station</source>
- <translation type="unfinished"></translation>
+ <translation>Luo uusi asema</translation>
</message>
<message>
<location filename="../mainUI.ui" line="495"/>
<source>add</source>
- <translation type="unfinished"></translation>
+ <translation>lisää</translation>
</message>
<message>
<location filename="../mainUI.ui" line="512"/>
<source>Settings</source>
- <translation type="unfinished"></translation>
+ <translation>Asetukset</translation>
</message>
<message>
<location filename="../mainUI.ui" line="521"/>
<source>Pandora Account Login</source>
- <translation type="unfinished"></translation>
+ <translation>Kirjautuminen Pandora-tilille</translation>
</message>
<message>
<location filename="../mainUI.ui" line="527"/>
<source>Email</source>
- <translation type="unfinished"></translation>
+ <translation>Sähköposti</translation>
</message>
<message>
<location filename="../mainUI.ui" line="537"/>
<source>Password</source>
- <translation type="unfinished"></translation>
+ <translation>Salasana</translation>
</message>
<message>
<location filename="../mainUI.ui" line="557"/>
<source>&lt;a href=https://www.pandora.com/account/register&gt;Need an account?&lt;/a&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;a href=https://www.pandora.com/account/register&gt;Tarvitsetko tilin?&lt;/a&gt;</translation>
</message>
<message>
<location filename="../mainUI.ui" line="573"/>
<source>Audio Quality</source>
- <translation type="unfinished"></translation>
+ <translation>Äänenlaatu</translation>
</message>
<message>
<location filename="../mainUI.ui" line="583"/>
<source>Proxy URL</source>
- <translation type="unfinished"></translation>
+ <translation>Välityspalvelimen osoite</translation>
</message>
<message>
<location filename="../mainUI.ui" line="593"/>
@@ -144,47 +144,47 @@
<message>
<location filename="../mainUI.ui" line="618"/>
<source>Apply Settings</source>
- <translation type="unfinished"></translation>
+ <translation>Ota asetukset käyttöön</translation>
</message>
<message>
<location filename="../mainUI.ui" line="656"/>
<source>Audio Driver</source>
- <translation type="unfinished"></translation>
+ <translation>Ääniajuri</translation>
</message>
<message>
<location filename="../mainUI.ui" line="681"/>
<source>File</source>
- <translation type="unfinished"></translation>
+ <translation>Tiedosto</translation>
</message>
<message>
<location filename="../mainUI.ui" line="688"/>
<source>View</source>
- <translation type="unfinished"></translation>
+ <translation>Näytä</translation>
</message>
<message>
<location filename="../mainUI.ui" line="723"/>
<source>Play</source>
- <translation type="unfinished"></translation>
+ <translation>Toista</translation>
</message>
<message>
<location filename="../mainUI.ui" line="728"/>
<source>Pause</source>
- <translation type="unfinished"></translation>
+ <translation>Tauko</translation>
</message>
<message>
<location filename="../mainUI.ui" line="733"/>
<source>Stop</source>
- <translation type="unfinished"></translation>
+ <translation>Pysäytä</translation>
</message>
<message>
<location filename="../mainUI.ui" line="738"/>
<source>Next</source>
- <translation type="unfinished"></translation>
+ <translation>Seuraava</translation>
</message>
<message>
<location filename="../mainUI.ui" line="743"/>
<source>Back</source>
- <translation type="unfinished"></translation>
+ <translation>Takaisin</translation>
</message>
<message>
<location filename="../mainUI.ui" line="748"/>
@@ -194,7 +194,7 @@
<message>
<location filename="../mainUI.ui" line="751"/>
<source>Raise audio volume</source>
- <translation type="unfinished"></translation>
+ <translation>Nosta äänenvoimakkuutta</translation>
</message>
<message>
<location filename="../mainUI.ui" line="756"/>
@@ -204,12 +204,12 @@
<message>
<location filename="../mainUI.ui" line="759"/>
<source>Lower audio volume</source>
- <translation type="unfinished"></translation>
+ <translation>Laske äänenvoimakkuutta</translation>
</message>
<message>
<location filename="../mainUI.ui" line="764"/>
<source>Close Application</source>
- <translation type="unfinished"></translation>
+ <translation>Sulje sovellus</translation>
</message>
<message>
<location filename="../mainUI.ui" line="767"/>
@@ -219,27 +219,27 @@
<message>
<location filename="../mainUI.ui" line="781"/>
<source>Close to tray when active</source>
- <translation type="unfinished"></translation>
+ <translation>Sulje aktiivisena ilmoitusalueelle</translation>
</message>
<message>
<location filename="../mainUI.ui" line="786"/>
<source>From current artist</source>
- <translation type="unfinished"></translation>
+ <translation>Nykyiseltä artistilta</translation>
</message>
<message>
<location filename="../mainUI.ui" line="789"/>
<source>Create station from current artist</source>
- <translation type="unfinished"></translation>
+ <translation>Luo nykyisestä artistista asema</translation>
</message>
<message>
<location filename="../mainUI.ui" line="794"/>
<source>From current song</source>
- <translation type="unfinished"></translation>
+ <translation>Nykyisestä kappaleesta</translation>
</message>
<message>
<location filename="../mainUI.ui" line="797"/>
<source>Create station from current song</source>
- <translation type="unfinished"></translation>
+ <translation>Luo nykyisestä kappaleesta asema</translation>
</message>
<message>
<location filename="../mainUI.ui" line="808"/>
@@ -249,43 +249,43 @@
<message>
<location filename="../mainUI.ui" line="813"/>
<source>Search...</source>
- <translation type="unfinished"></translation>
+ <translation>Etsi...</translation>
</message>
<message>
<location filename="../mainUI.ui" line="816"/>
<source>Search for a new station</source>
- <translation type="unfinished"></translation>
+ <translation>Etsi uutta asemaa</translation>
</message>
<message>
<location filename="../mainUI.ui" line="828"/>
<location filename="../mainUI.cpp" line="276"/>
<source>Pandora Radio</source>
- <translation type="unfinished"></translation>
+ <translation>Pandora-radio</translation>
</message>
<message>
<location filename="../mainUI.ui" line="831"/>
<source>Stream from Pandora Radio</source>
- <translation type="unfinished"></translation>
+ <translation>Virtaus Pandora-radiosta</translation>
</message>
<message>
<location filename="../mainUI.ui" line="839"/>
<source>Local Files</source>
- <translation type="unfinished"></translation>
+ <translation>Paikalliset tiedostot</translation>
</message>
<message>
<location filename="../mainUI.ui" line="842"/>
<source>Play Local Files</source>
- <translation type="unfinished"></translation>
+ <translation>Toista paikallisia tiedostoja</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="105"/>
<source>Please install the `pianobar` utility to enable this functionality</source>
- <translation type="unfinished"></translation>
+ <translation>Toiminnon käyttäminen vaatii pianobar-ohjelman asentamista</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="109"/>
<source>Stream music from the Pandora online radio service</source>
- <translation type="unfinished"></translation>
+ <translation>Virtauta musiikkia Pandora-verkkoradiopalvelusta</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="122"/>
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_hu.ts b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_hu.ts
index 80414a8b..1a2cf1aa 100644
--- a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_hu.ts
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_hu.ts
@@ -7,7 +7,7 @@
<location filename="../mainUI.ui" line="14"/>
<location filename="../mainUI.cpp" line="285"/>
<source>Media Player</source>
- <translation type="unfinished"></translation>
+ <translation>Média lejátszó</translation>
</message>
<message>
<location filename="../mainUI.ui" line="50"/>
@@ -154,7 +154,7 @@
<message>
<location filename="../mainUI.ui" line="681"/>
<source>File</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Fájl</translation>
</message>
<message>
<location filename="../mainUI.ui" line="688"/>
@@ -362,72 +362,4 @@
<translation type="unfinished"></translation>
</message>
</context>
-<context>
- <name>XDGDesktopList</name>
- <message>
- <location filename="../../../core/libLumina/LuminaXDG.cpp" line="608"/>
- <source>Multimedia</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../core/libLumina/LuminaXDG.cpp" line="609"/>
- <source>Development</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../core/libLumina/LuminaXDG.cpp" line="610"/>
- <source>Education</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../core/libLumina/LuminaXDG.cpp" line="611"/>
- <source>Games</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../core/libLumina/LuminaXDG.cpp" line="612"/>
- <source>Graphics</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../core/libLumina/LuminaXDG.cpp" line="613"/>
- <source>Network</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../core/libLumina/LuminaXDG.cpp" line="614"/>
- <source>Office</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../core/libLumina/LuminaXDG.cpp" line="615"/>
- <source>Science</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../core/libLumina/LuminaXDG.cpp" line="616"/>
- <source>Settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../core/libLumina/LuminaXDG.cpp" line="617"/>
- <source>System</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../core/libLumina/LuminaXDG.cpp" line="618"/>
- <source>Utility</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../core/libLumina/LuminaXDG.cpp" line="619"/>
- <source>Wine</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../core/libLumina/LuminaXDG.cpp" line="620"/>
- <source>Unsorted</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
</TS>
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_lt.ts b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_lt.ts
index ecaf4cbc..f10cf90d 100644
--- a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_lt.ts
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_lt.ts
@@ -19,7 +19,7 @@
<message>
<location filename="../mainUI.ui" line="74"/>
<source>(No Running Video)</source>
- <translation type="unfinished"></translation>
+ <translation>(Nėra paleisto vaizdo įrašo)</translation>
</message>
<message>
<location filename="../mainUI.ui" line="105"/>
@@ -89,7 +89,7 @@
<message>
<location filename="../mainUI.ui" line="482"/>
<source>rm</source>
- <translation type="unfinished"></translation>
+ <translation>šalinti</translation>
</message>
<message>
<location filename="../mainUI.ui" line="492"/>
@@ -109,7 +109,7 @@
<message>
<location filename="../mainUI.ui" line="521"/>
<source>Pandora Account Login</source>
- <translation type="unfinished"></translation>
+ <translation>Pandora paskyros prisijungimas</translation>
</message>
<message>
<location filename="../mainUI.ui" line="527"/>
@@ -139,7 +139,7 @@
<message>
<location filename="../mainUI.ui" line="593"/>
<source>Control Proxy URL</source>
- <translation type="unfinished"></translation>
+ <translation>Valdymo įgaliotojo serverio URL</translation>
</message>
<message>
<location filename="../mainUI.ui" line="618"/>
@@ -224,22 +224,22 @@
<message>
<location filename="../mainUI.ui" line="786"/>
<source>From current artist</source>
- <translation type="unfinished"></translation>
+ <translation>Iš esamo atlikėjo</translation>
</message>
<message>
<location filename="../mainUI.ui" line="789"/>
<source>Create station from current artist</source>
- <translation type="unfinished"></translation>
+ <translation>Sukurti stotį iš esamo atlikėjo</translation>
</message>
<message>
<location filename="../mainUI.ui" line="794"/>
<source>From current song</source>
- <translation type="unfinished"></translation>
+ <translation>Iš esamos dainos</translation>
</message>
<message>
<location filename="../mainUI.ui" line="797"/>
<source>Create station from current song</source>
- <translation type="unfinished"></translation>
+ <translation>Sukurti stotį iš esamos dainos</translation>
</message>
<message>
<location filename="../mainUI.ui" line="808"/>
@@ -249,23 +249,23 @@
<message>
<location filename="../mainUI.ui" line="813"/>
<source>Search...</source>
- <translation type="unfinished"></translation>
+ <translation>Ieškoti...</translation>
</message>
<message>
<location filename="../mainUI.ui" line="816"/>
<source>Search for a new station</source>
- <translation type="unfinished"></translation>
+ <translation>Ieškoti naujos stoties</translation>
</message>
<message>
<location filename="../mainUI.ui" line="828"/>
<location filename="../mainUI.cpp" line="276"/>
<source>Pandora Radio</source>
- <translation type="unfinished"></translation>
+ <translation>Pandora radijas</translation>
</message>
<message>
<location filename="../mainUI.ui" line="831"/>
<source>Stream from Pandora Radio</source>
- <translation type="unfinished"></translation>
+ <translation>Transliuoti iš Pandora radijo</translation>
</message>
<message>
<location filename="../mainUI.ui" line="839"/>
@@ -280,27 +280,27 @@
<message>
<location filename="../mainUI.cpp" line="105"/>
<source>Please install the `pianobar` utility to enable this functionality</source>
- <translation>Norėdami įjungti šį funkcionalumą, įdiekite &quot;pianobar&quot; paslaugų programą</translation>
+ <translation>Norėdami įjungti šį funkcionalumą, įdiekite "pianobar" paslaugų programą</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="109"/>
<source>Stream music from the Pandora online radio service</source>
- <translation type="unfinished"></translation>
+ <translation>Transliuoti muziką iš Pandora internetinio radijo paslaugos</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="122"/>
<source>Low</source>
- <translation type="unfinished"></translation>
+ <translation>Žema</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="123"/>
<source>Medium</source>
- <translation type="unfinished"></translation>
+ <translation>Vidutinė</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="124"/>
<source>High</source>
- <translation type="unfinished"></translation>
+ <translation>Aukšta</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="358"/>
@@ -316,32 +316,33 @@
<location filename="../mainUI.cpp" line="471"/>
<source>[PLAYBACK ERROR]
%1</source>
- <translation type="unfinished"></translation>
+ <translation>[ATKŪRIMO KLAIDA]
+%1</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="488"/>
<source>Media Loading...</source>
- <translation type="unfinished"></translation>
+ <translation>Medija įkeliama...</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="490"/>
<source>Media Stalled...</source>
- <translation type="unfinished"></translation>
+ <translation>Medija atitrūko...</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="492"/>
<source>Media Buffering...</source>
- <translation type="unfinished"></translation>
+ <translation>Medijos buferizacija...</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="576"/>
<source>Pandora: Create Station</source>
- <translation type="unfinished"></translation>
+ <translation>Pandora: Sukurti stotį</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="576"/>
<source>Search Term</source>
- <translation type="unfinished"></translation>
+ <translation>Ieškomas žodis</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="654"/>
@@ -359,7 +360,7 @@
<message>
<location filename="../PianoBarProcess.cpp" line="358"/>
<source>Could not find any matches. Please try a different search term</source>
- <translation type="unfinished"></translation>
+ <translation>Nepavyko rasti jokių atitikmenų. Pabandykite kitokį ieškomą žodį</translation>
</message>
</context>
<context>
@@ -367,67 +368,67 @@
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="608"/>
<source>Multimedia</source>
- <translation type="unfinished"></translation>
+ <translation>Multimedija</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="609"/>
<source>Development</source>
- <translation type="unfinished"></translation>
+ <translation>Programavimas</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="610"/>
<source>Education</source>
- <translation type="unfinished"></translation>
+ <translation>Švietimas</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="611"/>
<source>Games</source>
- <translation type="unfinished"></translation>
+ <translation>Žaidimai</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="612"/>
<source>Graphics</source>
- <translation type="unfinished"></translation>
+ <translation>Grafika</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="613"/>
<source>Network</source>
- <translation type="unfinished"></translation>
+ <translation>Tinklas</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="614"/>
<source>Office</source>
- <translation type="unfinished"></translation>
+ <translation>Raštinė</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="615"/>
<source>Science</source>
- <translation type="unfinished"></translation>
+ <translation>Mokslas</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="616"/>
<source>Settings</source>
- <translation type="unfinished">Nustatymai</translation>
+ <translation>Nustatymai</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="617"/>
<source>System</source>
- <translation type="unfinished"></translation>
+ <translation>Sistema</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="618"/>
<source>Utility</source>
- <translation type="unfinished"></translation>
+ <translation>Paslaugų programos</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="619"/>
<source>Wine</source>
- <translation type="unfinished"></translation>
+ <translation>Wine</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="620"/>
<source>Unsorted</source>
- <translation type="unfinished"></translation>
+ <translation>Nesurūšiuota</translation>
</message>
</context>
</TS>
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_nl.ts b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_nl.ts
index ba312720..860a0aaa 100644
--- a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_nl.ts
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_nl.ts
@@ -7,310 +7,310 @@
<location filename="../mainUI.ui" line="14"/>
<location filename="../mainUI.cpp" line="285"/>
<source>Media Player</source>
- <translation type="unfinished"></translation>
+ <translation>Mediaspeler</translation>
</message>
<message>
<location filename="../mainUI.ui" line="50"/>
<location filename="../mainUI.ui" line="261"/>
<location filename="../mainUI.cpp" line="631"/>
<source>Now Playing</source>
- <translation type="unfinished"></translation>
+ <translation>Nu wordt afgespeeld</translation>
</message>
<message>
<location filename="../mainUI.ui" line="74"/>
<source>(No Running Video)</source>
- <translation type="unfinished"></translation>
+ <translation>(geen video wordt op dit moment afgespeeld)</translation>
</message>
<message>
<location filename="../mainUI.ui" line="105"/>
<source>Playlist</source>
- <translation type="unfinished"></translation>
+ <translation>Afspeellijst</translation>
</message>
<message>
<location filename="../mainUI.ui" line="167"/>
<source>up</source>
- <translation type="unfinished"></translation>
+ <translation>omhoog</translation>
</message>
<message>
<location filename="../mainUI.ui" line="183"/>
<source>down</source>
- <translation type="unfinished"></translation>
+ <translation>omlaag</translation>
</message>
<message>
<location filename="../mainUI.ui" line="267"/>
<source>Current Song</source>
- <translation type="unfinished"></translation>
+ <translation>Huidig nummer</translation>
</message>
<message>
<location filename="../mainUI.ui" line="303"/>
<source>TITLE</source>
- <translation type="unfinished"></translation>
+ <translation>TITEL</translation>
</message>
<message>
<location filename="../mainUI.ui" line="327"/>
<source>ARTIST</source>
- <translation type="unfinished"></translation>
+ <translation>ARTIEST</translation>
</message>
<message>
<location filename="../mainUI.ui" line="337"/>
<source>ALBUM</source>
- <translation type="unfinished"></translation>
+ <translation>ALBUM</translation>
</message>
<message>
<location filename="../mainUI.ui" line="368"/>
<source>Love this song</source>
- <translation type="unfinished"></translation>
+ <translation>Houd van dit dit nummer</translation>
</message>
<message>
<location filename="../mainUI.ui" line="384"/>
<source>Tired of this song (will not play for a month)</source>
- <translation type="unfinished"></translation>
+ <translation>Heb het even gehad met dit nummer (wordt gedurende een maand niet afgespeeld)</translation>
</message>
<message>
<location filename="../mainUI.ui" line="397"/>
<source>Ban this song (will never play again)</source>
- <translation type="unfinished"></translation>
+ <translation>Verban dit nummer! (zal nooit meer worden afgespeeld)</translation>
</message>
<message>
<location filename="../mainUI.ui" line="417"/>
<source>View details about song (launches web browser)</source>
- <translation type="unfinished"></translation>
+ <translation>Bekijk meer informatie over dit nummer (start je internet browser op)</translation>
</message>
<message>
<location filename="../mainUI.ui" line="448"/>
<source>Current Station</source>
- <translation type="unfinished"></translation>
+ <translation>Huidig radiostation</translation>
</message>
<message>
<location filename="../mainUI.ui" line="479"/>
<source>Delete current station</source>
- <translation type="unfinished"></translation>
+ <translation>Verwijder huidig radiostation</translation>
</message>
<message>
<location filename="../mainUI.ui" line="482"/>
<source>rm</source>
- <translation type="unfinished"></translation>
+ <translation>rm</translation>
</message>
<message>
<location filename="../mainUI.ui" line="492"/>
<source>Create new station</source>
- <translation type="unfinished"></translation>
+ <translation>Maak een nieuw station aan</translation>
</message>
<message>
<location filename="../mainUI.ui" line="495"/>
<source>add</source>
- <translation type="unfinished"></translation>
+ <translation>voeg toe</translation>
</message>
<message>
<location filename="../mainUI.ui" line="512"/>
<source>Settings</source>
- <translation type="unfinished"></translation>
+ <translation>Voorkeuren</translation>
</message>
<message>
<location filename="../mainUI.ui" line="521"/>
<source>Pandora Account Login</source>
- <translation type="unfinished"></translation>
+ <translation>Inloggen met uw Pandora Account</translation>
</message>
<message>
<location filename="../mainUI.ui" line="527"/>
<source>Email</source>
- <translation type="unfinished"></translation>
+ <translation>E-mail</translation>
</message>
<message>
<location filename="../mainUI.ui" line="537"/>
<source>Password</source>
- <translation type="unfinished"></translation>
+ <translation>Wachtwoord</translation>
</message>
<message>
<location filename="../mainUI.ui" line="557"/>
<source>&lt;a href=https://www.pandora.com/account/register&gt;Need an account?&lt;/a&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;a href=https://www.pandora.com/account/register&gt;Nog geen account?&lt;/a&gt;</translation>
</message>
<message>
<location filename="../mainUI.ui" line="573"/>
<source>Audio Quality</source>
- <translation type="unfinished"></translation>
+ <translation>Geluidskwaliteit</translation>
</message>
<message>
<location filename="../mainUI.ui" line="583"/>
<source>Proxy URL</source>
- <translation type="unfinished"></translation>
+ <translation>Proxy URL</translation>
</message>
<message>
<location filename="../mainUI.ui" line="593"/>
<source>Control Proxy URL</source>
- <translation type="unfinished"></translation>
+ <translation>Controle Proxy URL</translation>
</message>
<message>
<location filename="../mainUI.ui" line="618"/>
<source>Apply Settings</source>
- <translation type="unfinished"></translation>
+ <translation>Pas voorkeuren toe</translation>
</message>
<message>
<location filename="../mainUI.ui" line="656"/>
<source>Audio Driver</source>
- <translation type="unfinished"></translation>
+ <translation>Geluidskaart</translation>
</message>
<message>
<location filename="../mainUI.ui" line="681"/>
<source>File</source>
- <translation type="unfinished"></translation>
+ <translation>Bestand</translation>
</message>
<message>
<location filename="../mainUI.ui" line="688"/>
<source>View</source>
- <translation type="unfinished"></translation>
+ <translation>Weergave</translation>
</message>
<message>
<location filename="../mainUI.ui" line="723"/>
<source>Play</source>
- <translation type="unfinished"></translation>
+ <translation>Speel af</translation>
</message>
<message>
<location filename="../mainUI.ui" line="728"/>
<source>Pause</source>
- <translation type="unfinished"></translation>
+ <translation>Pauze</translation>
</message>
<message>
<location filename="../mainUI.ui" line="733"/>
<source>Stop</source>
- <translation type="unfinished"></translation>
+ <translation>Stop</translation>
</message>
<message>
<location filename="../mainUI.ui" line="738"/>
<source>Next</source>
- <translation type="unfinished"></translation>
+ <translation>Volgende</translation>
</message>
<message>
<location filename="../mainUI.ui" line="743"/>
<source>Back</source>
- <translation type="unfinished"></translation>
+ <translation>Vorige</translation>
</message>
<message>
<location filename="../mainUI.ui" line="748"/>
<source>VolUp</source>
- <translation type="unfinished"></translation>
+ <translation>Volume omhoog</translation>
</message>
<message>
<location filename="../mainUI.ui" line="751"/>
<source>Raise audio volume</source>
- <translation type="unfinished"></translation>
+ <translation>Verhoog het geluidsvolume</translation>
</message>
<message>
<location filename="../mainUI.ui" line="756"/>
<source>VolDown</source>
- <translation type="unfinished"></translation>
+ <translation>Volume omlaag</translation>
</message>
<message>
<location filename="../mainUI.ui" line="759"/>
<source>Lower audio volume</source>
- <translation type="unfinished"></translation>
+ <translation>Verlaag het geluidsvolume</translation>
</message>
<message>
<location filename="../mainUI.ui" line="764"/>
<source>Close Application</source>
- <translation type="unfinished"></translation>
+ <translation>Sluit de applicatie af</translation>
</message>
<message>
<location filename="../mainUI.ui" line="767"/>
<source>Ctrl+Q</source>
- <translation type="unfinished"></translation>
+ <translation>Ctrl+Q</translation>
</message>
<message>
<location filename="../mainUI.ui" line="781"/>
<source>Close to tray when active</source>
- <translation type="unfinished"></translation>
+ <translation>Breng naar terug naar het systeemvak wanneer actief</translation>
</message>
<message>
<location filename="../mainUI.ui" line="786"/>
<source>From current artist</source>
- <translation type="unfinished"></translation>
+ <translation>Van de huidige artiest</translation>
</message>
<message>
<location filename="../mainUI.ui" line="789"/>
<source>Create station from current artist</source>
- <translation type="unfinished"></translation>
+ <translation>Maak een station aan voor de huidige artiest</translation>
</message>
<message>
<location filename="../mainUI.ui" line="794"/>
<source>From current song</source>
- <translation type="unfinished"></translation>
+ <translation>Van het huidige nummer</translation>
</message>
<message>
<location filename="../mainUI.ui" line="797"/>
<source>Create station from current song</source>
- <translation type="unfinished"></translation>
+ <translation>Maak een station aan op basis van het huidige nummer</translation>
</message>
<message>
<location filename="../mainUI.ui" line="808"/>
<source>Show song notifications</source>
- <translation type="unfinished"></translation>
+ <translation>Laat afspeelberichten zien</translation>
</message>
<message>
<location filename="../mainUI.ui" line="813"/>
<source>Search...</source>
- <translation type="unfinished"></translation>
+ <translation>Zoeken...</translation>
</message>
<message>
<location filename="../mainUI.ui" line="816"/>
<source>Search for a new station</source>
- <translation type="unfinished"></translation>
+ <translation>Zoek een nieuw station</translation>
</message>
<message>
<location filename="../mainUI.ui" line="828"/>
<location filename="../mainUI.cpp" line="276"/>
<source>Pandora Radio</source>
- <translation type="unfinished"></translation>
+ <translation></translation>
</message>
<message>
<location filename="../mainUI.ui" line="831"/>
<source>Stream from Pandora Radio</source>
- <translation type="unfinished"></translation>
+ <translation>Stream van Pandora Radio</translation>
</message>
<message>
<location filename="../mainUI.ui" line="839"/>
<source>Local Files</source>
- <translation type="unfinished"></translation>
+ <translation>Lokale bestanden</translation>
</message>
<message>
<location filename="../mainUI.ui" line="842"/>
<source>Play Local Files</source>
- <translation type="unfinished"></translation>
+ <translation>Speel lokale bestanden af</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="105"/>
<source>Please install the `pianobar` utility to enable this functionality</source>
- <translation type="unfinished"></translation>
+ <translation>Installeer alstublieft de 'pianobar' toepassing om deze functionaliteit te kunnen gebruiken</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="109"/>
<source>Stream music from the Pandora online radio service</source>
- <translation type="unfinished"></translation>
+ <translation>Stream muziek vanaf de Pandora online radio service</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="122"/>
<source>Low</source>
- <translation type="unfinished"></translation>
+ <translation>Laag</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="123"/>
<source>Medium</source>
- <translation type="unfinished"></translation>
+ <translation>Gemiddeld</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="124"/>
<source>High</source>
- <translation type="unfinished"></translation>
+ <translation>Hoog</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="358"/>
<source>Open Multimedia Files</source>
- <translation type="unfinished"></translation>
+ <translation>Open Multimedia bestanden</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="406"/>
<source>Now Playing:</source>
- <translation type="unfinished"></translation>
+ <translation>Nu aan het afspelen:</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="471"/>
@@ -321,37 +321,37 @@
<message>
<location filename="../mainUI.cpp" line="488"/>
<source>Media Loading...</source>
- <translation type="unfinished"></translation>
+ <translation>Media aan het laden...</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="490"/>
<source>Media Stalled...</source>
- <translation type="unfinished"></translation>
+ <translation>Media loopt vast...</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="492"/>
<source>Media Buffering...</source>
- <translation type="unfinished"></translation>
+ <translation>Media aan het bufferen....</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="576"/>
<source>Pandora: Create Station</source>
- <translation type="unfinished"></translation>
+ <translation>Pandora: Maak een station aan</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="576"/>
<source>Search Term</source>
- <translation type="unfinished"></translation>
+ <translation>Zoekterm</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="654"/>
<source>Pandora Question</source>
- <translation type="unfinished"></translation>
+ <translation>Pandora vraag</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="659"/>
<source>Pandora Error</source>
- <translation type="unfinished"></translation>
+ <translation>Pandora foutmelding</translation>
</message>
</context>
<context>
@@ -359,7 +359,7 @@
<message>
<location filename="../PianoBarProcess.cpp" line="358"/>
<source>Could not find any matches. Please try a different search term</source>
- <translation type="unfinished"></translation>
+ <translation>Kon geen resultaten vinden. Probeer alstublieft een andere zoekterm</translation>
</message>
</context>
<context>
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_pt_BR.ts b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_pt_BR.ts
index f60ce2a0..d30de8ba 100644
--- a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_pt_BR.ts
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_pt_BR.ts
@@ -7,7 +7,7 @@
<location filename="../mainUI.ui" line="14"/>
<location filename="../mainUI.cpp" line="285"/>
<source>Media Player</source>
- <translation type="unfinished">Media Player</translation>
+ <translation>Media Player</translation>
</message>
<message>
<location filename="../mainUI.ui" line="50"/>
@@ -24,7 +24,7 @@
<message>
<location filename="../mainUI.ui" line="105"/>
<source>Playlist</source>
- <translation type="unfinished">Playlist</translation>
+ <translation>Lista de reprodução</translation>
</message>
<message>
<location filename="../mainUI.ui" line="167"/>
@@ -74,82 +74,82 @@
<message>
<location filename="../mainUI.ui" line="417"/>
<source>View details about song (launches web browser)</source>
- <translation type="unfinished"></translation>
+ <translation>Ver detalhes da música (abre o navegador web)</translation>
</message>
<message>
<location filename="../mainUI.ui" line="448"/>
<source>Current Station</source>
- <translation type="unfinished"></translation>
+ <translation>Estação atual</translation>
</message>
<message>
<location filename="../mainUI.ui" line="479"/>
<source>Delete current station</source>
- <translation type="unfinished"></translation>
+ <translation>Remover estação atual</translation>
</message>
<message>
<location filename="../mainUI.ui" line="482"/>
<source>rm</source>
- <translation type="unfinished"></translation>
+ <translation>rm</translation>
</message>
<message>
<location filename="../mainUI.ui" line="492"/>
<source>Create new station</source>
- <translation type="unfinished"></translation>
+ <translation>Criar nova estação</translation>
</message>
<message>
<location filename="../mainUI.ui" line="495"/>
<source>add</source>
- <translation type="unfinished"></translation>
+ <translation>Add</translation>
</message>
<message>
<location filename="../mainUI.ui" line="512"/>
<source>Settings</source>
- <translation type="unfinished"></translation>
+ <translation>Configurações</translation>
</message>
<message>
<location filename="../mainUI.ui" line="521"/>
<source>Pandora Account Login</source>
- <translation type="unfinished"></translation>
+ <translation>Login na conta Pandora</translation>
</message>
<message>
<location filename="../mainUI.ui" line="527"/>
<source>Email</source>
- <translation type="unfinished"></translation>
+ <translation>E-mail</translation>
</message>
<message>
<location filename="../mainUI.ui" line="537"/>
<source>Password</source>
- <translation type="unfinished"></translation>
+ <translation>Senha</translation>
</message>
<message>
<location filename="../mainUI.ui" line="557"/>
<source>&lt;a href=https://www.pandora.com/account/register&gt;Need an account?&lt;/a&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;a href=https://www.pandora.com/account/register&gt;Precisa de uma conta?&lt;/a&gt;</translation>
</message>
<message>
<location filename="../mainUI.ui" line="573"/>
<source>Audio Quality</source>
- <translation type="unfinished"></translation>
+ <translation>Qualidade do áudio</translation>
</message>
<message>
<location filename="../mainUI.ui" line="583"/>
<source>Proxy URL</source>
- <translation type="unfinished"></translation>
+ <translation>URL do proxy</translation>
</message>
<message>
<location filename="../mainUI.ui" line="593"/>
<source>Control Proxy URL</source>
- <translation type="unfinished"></translation>
+ <translation>URL do Proxy de Controle</translation>
</message>
<message>
<location filename="../mainUI.ui" line="618"/>
<source>Apply Settings</source>
- <translation type="unfinished"></translation>
+ <translation>Aplicar configurações</translation>
</message>
<message>
<location filename="../mainUI.ui" line="656"/>
<source>Audio Driver</source>
- <translation type="unfinished"></translation>
+ <translation>Driver de áudio</translation>
</message>
<message>
<location filename="../mainUI.ui" line="681"/>
@@ -159,57 +159,57 @@
<message>
<location filename="../mainUI.ui" line="688"/>
<source>View</source>
- <translation type="unfinished"></translation>
+ <translation>Ver</translation>
</message>
<message>
<location filename="../mainUI.ui" line="723"/>
<source>Play</source>
- <translation type="unfinished"></translation>
+ <translation>Tocar</translation>
</message>
<message>
<location filename="../mainUI.ui" line="728"/>
<source>Pause</source>
- <translation type="unfinished"></translation>
+ <translation>Pausar</translation>
</message>
<message>
<location filename="../mainUI.ui" line="733"/>
<source>Stop</source>
- <translation type="unfinished"></translation>
+ <translation>Parar</translation>
</message>
<message>
<location filename="../mainUI.ui" line="738"/>
<source>Next</source>
- <translation type="unfinished"></translation>
+ <translation>Avançar</translation>
</message>
<message>
<location filename="../mainUI.ui" line="743"/>
<source>Back</source>
- <translation type="unfinished"></translation>
+ <translation>Voltar</translation>
</message>
<message>
<location filename="../mainUI.ui" line="748"/>
<source>VolUp</source>
- <translation type="unfinished"></translation>
+ <translation>VolUp</translation>
</message>
<message>
<location filename="../mainUI.ui" line="751"/>
<source>Raise audio volume</source>
- <translation type="unfinished"></translation>
+ <translation>Aumentar o volume do áudio</translation>
</message>
<message>
<location filename="../mainUI.ui" line="756"/>
<source>VolDown</source>
- <translation type="unfinished"></translation>
+ <translation>VolDown</translation>
</message>
<message>
<location filename="../mainUI.ui" line="759"/>
<source>Lower audio volume</source>
- <translation type="unfinished"></translation>
+ <translation>Diminuir o volume do áudio</translation>
</message>
<message>
<location filename="../mainUI.ui" line="764"/>
<source>Close Application</source>
- <translation type="unfinished"></translation>
+ <translation>Fechar aplicação</translation>
</message>
<message>
<location filename="../mainUI.ui" line="767"/>
@@ -219,139 +219,140 @@
<message>
<location filename="../mainUI.ui" line="781"/>
<source>Close to tray when active</source>
- <translation type="unfinished"></translation>
+ <translation>Fechar para a bandeja quando ativo</translation>
</message>
<message>
<location filename="../mainUI.ui" line="786"/>
<source>From current artist</source>
- <translation type="unfinished"></translation>
+ <translation>Do artista atual</translation>
</message>
<message>
<location filename="../mainUI.ui" line="789"/>
<source>Create station from current artist</source>
- <translation type="unfinished"></translation>
+ <translation>Criar estação do artista atual</translation>
</message>
<message>
<location filename="../mainUI.ui" line="794"/>
<source>From current song</source>
- <translation type="unfinished"></translation>
+ <translation>Da música atual</translation>
</message>
<message>
<location filename="../mainUI.ui" line="797"/>
<source>Create station from current song</source>
- <translation type="unfinished"></translation>
+ <translation>Criar uma estação da música atual</translation>
</message>
<message>
<location filename="../mainUI.ui" line="808"/>
<source>Show song notifications</source>
- <translation type="unfinished"></translation>
+ <translation>Mostrar notificações de músicas</translation>
</message>
<message>
<location filename="../mainUI.ui" line="813"/>
<source>Search...</source>
- <translation type="unfinished"></translation>
+ <translation>Procurar...</translation>
</message>
<message>
<location filename="../mainUI.ui" line="816"/>
<source>Search for a new station</source>
- <translation type="unfinished"></translation>
+ <translation>Procurar uma nova estação</translation>
</message>
<message>
<location filename="../mainUI.ui" line="828"/>
<location filename="../mainUI.cpp" line="276"/>
<source>Pandora Radio</source>
- <translation type="unfinished"></translation>
+ <translation>Pandora Radio</translation>
</message>
<message>
<location filename="../mainUI.ui" line="831"/>
<source>Stream from Pandora Radio</source>
- <translation type="unfinished"></translation>
+ <translation>Transmissão da Pandora Radio</translation>
</message>
<message>
<location filename="../mainUI.ui" line="839"/>
<source>Local Files</source>
- <translation type="unfinished"></translation>
+ <translation>Arquivos locais</translation>
</message>
<message>
<location filename="../mainUI.ui" line="842"/>
<source>Play Local Files</source>
- <translation type="unfinished"></translation>
+ <translation>Tocar arquivos locais</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="105"/>
<source>Please install the `pianobar` utility to enable this functionality</source>
- <translation type="unfinished"></translation>
+ <translation>Instale o utilitário `pianobar` para habilitar esta funcionalidade</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="109"/>
<source>Stream music from the Pandora online radio service</source>
- <translation type="unfinished"></translation>
+ <translation>Transmitir música do serviço de rádio on-line Pandora</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="122"/>
<source>Low</source>
- <translation type="unfinished"></translation>
+ <translation>Baixo</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="123"/>
<source>Medium</source>
- <translation type="unfinished"></translation>
+ <translation>Médio</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="124"/>
<source>High</source>
- <translation type="unfinished"></translation>
+ <translation>Alto</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="358"/>
<source>Open Multimedia Files</source>
- <translation type="unfinished"></translation>
+ <translation>Abrir arquivos multimídia</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="406"/>
<source>Now Playing:</source>
- <translation type="unfinished"></translation>
+ <translation>Tocando agora:</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="471"/>
<source>[PLAYBACK ERROR]
%1</source>
- <translation type="unfinished"></translation>
+ <translation>[PLAYBACK ERROR]
+%1</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="488"/>
<source>Media Loading...</source>
- <translation type="unfinished"></translation>
+ <translation>Carregando mídia...</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="490"/>
<source>Media Stalled...</source>
- <translation type="unfinished"></translation>
+ <translation>Mídia parada...</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="492"/>
<source>Media Buffering...</source>
- <translation type="unfinished"></translation>
+ <translation>Carregando mídia...</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="576"/>
<source>Pandora: Create Station</source>
- <translation type="unfinished"></translation>
+ <translation>Pandora: Criar estação</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="576"/>
<source>Search Term</source>
- <translation type="unfinished"></translation>
+ <translation>Procurar termo</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="654"/>
<source>Pandora Question</source>
- <translation type="unfinished"></translation>
+ <translation>Pergunta Pandora</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="659"/>
<source>Pandora Error</source>
- <translation type="unfinished"></translation>
+ <translation>Erro Pandora</translation>
</message>
</context>
<context>
@@ -359,7 +360,7 @@
<message>
<location filename="../PianoBarProcess.cpp" line="358"/>
<source>Could not find any matches. Please try a different search term</source>
- <translation type="unfinished"></translation>
+ <translation>Não foi possível encontrar nenhum resultado. Experimente um termo de pesquisa diferente</translation>
</message>
</context>
<context>
@@ -367,67 +368,67 @@
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="608"/>
<source>Multimedia</source>
- <translation type="unfinished"></translation>
+ <translation>Multimídia</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="609"/>
<source>Development</source>
- <translation type="unfinished"></translation>
+ <translation>Desenvolvimento</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="610"/>
<source>Education</source>
- <translation type="unfinished"></translation>
+ <translation>Educação</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="611"/>
<source>Games</source>
- <translation type="unfinished"></translation>
+ <translation>Jogos</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="612"/>
<source>Graphics</source>
- <translation type="unfinished"></translation>
+ <translation>Gráficos</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="613"/>
<source>Network</source>
- <translation type="unfinished"></translation>
+ <translation>Rede</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="614"/>
<source>Office</source>
- <translation type="unfinished"></translation>
+ <translation>Escritório</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="615"/>
<source>Science</source>
- <translation type="unfinished"></translation>
+ <translation>Ciência</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="616"/>
<source>Settings</source>
- <translation type="unfinished"></translation>
+ <translation>Configurações</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="617"/>
<source>System</source>
- <translation type="unfinished"></translation>
+ <translation>Sistema</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="618"/>
<source>Utility</source>
- <translation type="unfinished"></translation>
+ <translation>Utilitários</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="619"/>
<source>Wine</source>
- <translation type="unfinished"></translation>
+ <translation>Wine</translation>
</message>
<message>
<location filename="../../../core/libLumina/LuminaXDG.cpp" line="620"/>
<source>Unsorted</source>
- <translation type="unfinished"></translation>
+ <translation>Não classificado</translation>
</message>
</context>
</TS>
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_ru.ts b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_ru.ts
index 0664622c..364ffb87 100644
--- a/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_ru.ts
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/i18n/l-mediap_ru.ts
@@ -114,12 +114,12 @@
<message>
<location filename="../mainUI.ui" line="527"/>
<source>Email</source>
- <translation type="unfinished"></translation>
+ <translation>Эл.почта</translation>
</message>
<message>
<location filename="../mainUI.ui" line="537"/>
<source>Password</source>
- <translation type="unfinished"></translation>
+ <translation>Пароль</translation>
</message>
<message>
<location filename="../mainUI.ui" line="557"/>
@@ -154,7 +154,7 @@
<message>
<location filename="../mainUI.ui" line="681"/>
<source>File</source>
- <translation type="unfinished"></translation>
+ <translation>Файл</translation>
</message>
<message>
<location filename="../mainUI.ui" line="688"/>
@@ -164,17 +164,17 @@
<message>
<location filename="../mainUI.ui" line="723"/>
<source>Play</source>
- <translation type="unfinished"></translation>
+ <translation>Пуск</translation>
</message>
<message>
<location filename="../mainUI.ui" line="728"/>
<source>Pause</source>
- <translation type="unfinished"></translation>
+ <translation>Пауза</translation>
</message>
<message>
<location filename="../mainUI.ui" line="733"/>
<source>Stop</source>
- <translation type="unfinished"></translation>
+ <translation>Стоп</translation>
</message>
<message>
<location filename="../mainUI.ui" line="738"/>
@@ -189,7 +189,7 @@
<message>
<location filename="../mainUI.ui" line="748"/>
<source>VolUp</source>
- <translation type="unfinished"></translation>
+ <translation>Громче</translation>
</message>
<message>
<location filename="../mainUI.ui" line="751"/>
@@ -199,7 +199,7 @@
<message>
<location filename="../mainUI.ui" line="756"/>
<source>VolDown</source>
- <translation type="unfinished"></translation>
+ <translation>Тише</translation>
</message>
<message>
<location filename="../mainUI.ui" line="759"/>
@@ -310,7 +310,7 @@
<message>
<location filename="../mainUI.cpp" line="406"/>
<source>Now Playing:</source>
- <translation type="unfinished"></translation>
+ <translation>Воспроизводится:</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="471"/>
@@ -341,7 +341,7 @@
<message>
<location filename="../mainUI.cpp" line="576"/>
<source>Search Term</source>
- <translation type="unfinished"></translation>
+ <translation>Что искать</translation>
</message>
<message>
<location filename="../mainUI.cpp" line="654"/>
@@ -359,7 +359,7 @@
<message>
<location filename="../PianoBarProcess.cpp" line="358"/>
<source>Could not find any matches. Please try a different search term</source>
- <translation type="unfinished"></translation>
+ <translation>Совпадений не найдено. Попробуйте поискать что-то другое</translation>
</message>
</context>
<context>
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.pro b/src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.pro
index c9ea6a5b..d7423485 100644
--- a/src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.pro
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.pro
@@ -90,7 +90,7 @@ TRANSLATIONS = i18n/l-mediap_af.ts \
i18n/l-mediap_zu.ts
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
-dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
+dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
desktop.files=lumina-mediaplayer.desktop
desktop.path=$${L_SHAREDIR}/applications/
@@ -99,7 +99,7 @@ desktop.path=$${L_SHAREDIR}/applications/
#link.extra=ln -sf lumina-mediaplayer $(INSTALL_ROOT)$${L_BINDIR}/lplay
manpage.path=$${L_MANDIR}/man1/
-manpage.extra="$${MAN_ZIP} lumina-mediaplayer.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-mediaplayer.1.gz"
+manpage.extra="$${MAN_ZIP} $$PWD/lumina-mediaplayer.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-mediaplayer.1.gz"
INSTALLS += target desktop manpage
diff --git a/src-qt5/desktop-utils/lumina-pdf/PresentationLabel.h b/src-qt5/desktop-utils/lumina-pdf/PresentationLabel.h
new file mode 100644
index 00000000..c5b552a6
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-pdf/PresentationLabel.h
@@ -0,0 +1,35 @@
+//===========================================
+// Lumina Desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+// Simple subclass of QLabel to provide
+// some overlay information as a presentation window
+//===========================================
+#ifndef _PRESENTATION_LABEL_WIDGET_H
+#define _PRESENTATION_LABEL_WIDGET_H
+
+#include <QLabel>
+#include <QMouseEvent>
+#include <QDebug>
+
+class PresentationLabel : public QLabel{
+ Q_OBJECT
+
+signals:
+ void nextSlide();
+
+public:
+ PresentationLabel() : QLabel(0, Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint){
+ this->setContextMenuPolicy(Qt::CustomContextMenu);
+ }
+
+protected:
+ void mousePressEvent(QMouseEvent *ev){
+ QLabel::mousePressEvent(ev);
+ if(ev->button()==Qt::LeftButton){ emit nextSlide(); }
+ }
+};
+
+#endif
diff --git a/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp
new file mode 100644
index 00000000..be00e675
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.cpp
@@ -0,0 +1,279 @@
+#include "PrintWidget.h"
+
+PrintWidget::PrintWidget(QWidget *parent) : QGraphicsView(parent), scene(0), curPage(1),
+ viewMode(SinglePageView), zoomMode(FitInView), zoomFactor(1), initialized(false), fitting(true) {
+
+ this->setMouseTracking(true);
+ QList<QWidget*> children = this->findChildren<QWidget*>("",Qt::FindChildrenRecursively);
+ for(int i=0; i<children.length(); i++){
+ children[i]->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(children[i], SIGNAL(customContextMenuRequested(const QPoint&)), this, SIGNAL(customContextMenuRequested(const QPoint&)) );
+ }
+ this->setInteractive(false);
+ this->setDragMode(QGraphicsView::ScrollHandDrag);
+ this->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
+ this->setFocusPolicy(Qt::NoFocus);
+ QObject::connect(this->verticalScrollBar(), SIGNAL(valueChanged(int)),
+ this, SLOT(updateCurrentPage()));
+ QObject::connect(this, SIGNAL(resized()), this, SLOT(fit()));
+
+ scene = new QGraphicsScene(this);
+ scene->setBackgroundBrush(Qt::gray);
+ this->setScene(scene);
+
+ /*QVBoxLayout *layout = new QVBoxLayout;
+ setLayout(layout);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->addWidget(this);*/
+}
+
+PrintWidget::~PrintWidget() {
+ //delete scene;
+ //delete items in pages(?)
+}
+
+//Public Slots
+
+void PrintWidget::fitView() {
+ setZoomMode(FitInView);
+}
+
+void PrintWidget::fitToWidth() {
+ setZoomMode(FitToWidth);
+}
+
+void PrintWidget::setZoomMode(ZoomMode mode) {
+ zoomMode = mode;
+ fitting = true;
+ fit(true);
+}
+
+void PrintWidget::setAllPagesViewMode() {
+ setViewMode(AllPagesView);
+}
+
+void PrintWidget::setSinglePageViewMode() {
+ setViewMode(SinglePageView);
+}
+
+void PrintWidget::setFacingPagesViewMode() {
+ setViewMode(FacingPagesView);
+}
+
+void PrintWidget::setViewMode(ViewMode mode) {
+ viewMode = mode;
+ layoutPages();
+ if (viewMode == AllPagesView) {
+ this->fitInView(scene->itemsBoundingRect(), Qt::KeepAspectRatio);
+ fitting = false;
+ zoomMode = CustomZoom;
+ //zoomFactor = this->transform().m11() * (double(printer->logicalDpiY()) / logicalDpiY());
+ } else {
+ fitting = true;
+ fit();
+ }
+}
+
+void PrintWidget::zoomIn(double factor) {
+ fitting = false;
+ zoomMode = CustomZoom;
+ zoomFactor *= factor;
+ this->scale(factor, factor);
+}
+
+void PrintWidget::zoomOut(double factor) {
+ fitting = false;
+ zoomMode = CustomZoom;
+ zoomFactor *= factor;
+ this->scale(1/factor, 1/factor);
+}
+
+void PrintWidget::updatePreview() {
+ initialized = true;
+ generatePreview();
+ this->updateGeometry();
+}
+
+void PrintWidget::setVisible(bool visible) {
+ if(visible and !initialized)
+ updatePreview();
+ QGraphicsView::setVisible(visible);
+}
+
+void PrintWidget::setCurrentPage(int pageNumber) {
+ if(pageNumber < 1 || pageNumber > pages.count())
+ return;
+
+ int lastPage = curPage;
+ curPage = pageNumber;
+
+ if (lastPage != curPage && lastPage > 0 && lastPage <= pages.count()) {
+ if (zoomMode != FitInView) {
+ QScrollBar *hsc = this->horizontalScrollBar();
+ QScrollBar *vsc = this->verticalScrollBar();
+ QPointF pt = this->transform().map(pages.at(curPage-1)->pos());
+ vsc->setValue(int(pt.y()) - 10);
+ hsc->setValue(int(pt.x()) - 10);
+ } else {
+ this->centerOn(pages.at(curPage-1));
+ }
+ }
+}
+
+void PrintWidget::highlightText(int pageNum, QRectF textBox) {
+ PageItem *item = static_cast<PageItem*>(pages[pageNum]);
+ QPainter painter(this);
+ painter.fillRect(textBox, QColor(255, 255, 177, 128));
+}
+
+//Private functions
+
+void PrintWidget::generatePreview() {
+ populateScene(); // i.e. setPreviewPrintedPictures() e.l.
+ layoutPages();
+ curPage = qBound(1, curPage, pages.count());
+ if (fitting)
+ fit();
+}
+
+void PrintWidget::layoutPages() {
+ int numPages = pages.count();
+ if (numPages < 1)
+ return;
+
+ int numPagePlaces = numPages;
+ int cols = 1; // singleMode and default
+ if (viewMode == AllPagesView) {
+ cols = ((pictures->value(0)).width() > (pictures->value(0)).height()) ? qFloor(qSqrt(numPages)) : qCeil(qSqrt(numPages));
+ cols += cols % 2; // Nicer with an even number of cols
+ } else if (viewMode == FacingPagesView) {
+ cols = 2;
+ numPagePlaces += 1;
+ }
+ int rows = qCeil(double(numPagePlaces) / cols);
+
+ double itemWidth = pages.at(0)->boundingRect().width();
+ double itemHeight = pages.at(0)->boundingRect().height();
+ int pageNum = 1; for (int i = 0; i < rows && pageNum <= numPages; i++) {
+ for (int j = 0; j < cols && pageNum <= numPages; j++) {
+ if (!i && !j && viewMode == FacingPagesView) {
+ continue;
+ } else {
+ pages.at(pageNum-1)->setPos(QPointF(j*itemWidth, i*itemHeight));
+ pageNum++;
+ }
+ }
+ }
+ scene->setSceneRect(scene->itemsBoundingRect());
+}
+
+void PrintWidget::populateScene()
+{
+ for (int i = 0; i < pages.size(); i++)
+ scene->removeItem(pages.at(i));
+ qDeleteAll(pages);
+ pages.clear();
+
+ int numPages = pictures->count();
+ //Replace from loadingHash resolution
+ QSize paperSize = pictures->value(0).size();
+ qDebug() << "Image paperSize" << paperSize;
+
+ for (int i = 0; i < numPages; i++) {
+ PageItem* item = new PageItem(i+1, (*pictures)[i], paperSize);
+ scene->addItem(item);
+ pages.append(item);
+ }
+}
+
+//Private Slots
+void PrintWidget::updateCurrentPage() {
+ if (viewMode == AllPagesView)
+ return;
+
+ int newPage = calcCurrentPage();
+ if (newPage != curPage) {
+ curPage = newPage;
+ }
+}
+
+int PrintWidget::calcCurrentPage() {
+ int maxArea = 0;
+ int newPage = curPage;
+ QRect viewRect = this->viewport()->rect();
+ QList<QGraphicsItem*> items = this->items(viewRect);
+ for (int i=0; i<items.size(); ++i) {
+ PageItem* pg = static_cast<PageItem*>(items.at(i));
+ QRect overlap = this->mapFromScene(pg->sceneBoundingRect()).boundingRect() & viewRect;
+ int area = overlap.width() * overlap.height();
+ if (area > maxArea) {
+ maxArea = area;
+ newPage = pg->pageNumber();
+ } else if (area == maxArea && pg->pageNumber() < newPage) {
+ newPage = pg->pageNumber();
+ }
+ }
+ return newPage;
+}
+
+void PrintWidget::fit(bool doFitting) {
+ if (curPage < 1 || curPage > pages.count())
+ return;
+ if (!doFitting && !fitting)
+ return;
+
+ if (doFitting && fitting) {
+ QRect viewRect = this->viewport()->rect();
+ if (zoomMode == FitInView) {
+ QList<QGraphicsItem*> containedItems = this->items(viewRect, Qt::ContainsItemBoundingRect);
+ foreach(QGraphicsItem* item, containedItems) {
+ PageItem* pg = static_cast<PageItem*>(item);
+ if (pg->pageNumber() == curPage)
+ return;
+ }
+ }
+
+ int newPage = calcCurrentPage();
+ if (newPage != curPage)
+ curPage = newPage;
+ }
+
+ QRectF target = pages.at(curPage-1)->sceneBoundingRect();
+ if (viewMode == FacingPagesView) {
+ if (curPage % 2)
+ target.setLeft(target.left() - target.width());
+ else
+ target.setRight(target.right() + target.width());
+ } else if (viewMode == AllPagesView) {
+ target = scene->itemsBoundingRect();
+ }
+
+ if (zoomMode == FitToWidth) {
+ QTransform t;
+ qreal scale = this->viewport()->width() / target.width();
+ t.scale(scale, scale);
+ this->setTransform(t);
+ if (doFitting && fitting) {
+ QRectF viewSceneRect = this->viewportTransform().mapRect(this->viewport()->rect());
+ viewSceneRect.moveTop(target.top());
+ this->ensureVisible(viewSceneRect); // Nah...
+ }
+ } else {
+ this->fitInView(target, Qt::KeepAspectRatio);
+ if (zoomMode == FitInView) {
+ int step = qRound(this->matrix().mapRect(target).height());
+ this->verticalScrollBar()->setSingleStep(step);
+ this->verticalScrollBar()->setPageStep(step);
+ }
+ }
+
+ //zoomFactor = this->transform().m11() * (float(printer->logicalDpiY()) / this->logicalDpiY());
+}
+
+void PrintWidget::setPictures(QHash<int, QImage> *hash) {
+ pictures = hash;
+}
+
+void PrintWidget::setOrientation(QPageLayout::Orientation ori) {
+ this->orientation = ori;
+}
diff --git a/src-qt5/desktop-utils/lumina-pdf/PrintWidget.h b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.h
new file mode 100644
index 00000000..62543e45
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-pdf/PrintWidget.h
@@ -0,0 +1,164 @@
+//===========================================
+// Lumina Desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+// Simple subclass of QPrintPreviewWidget to provide
+// notification when a context menu is requested
+//===========================================
+#ifndef _PRINT_GRAPHICS_H
+#define _PRINT_GRAPHICS_H
+
+#include <QMouseEvent>
+#include <QDebug>
+#include <QGraphicsView>
+#include <QGraphicsItem>
+#include <QBoxLayout>
+#include <QScrollBar>
+#include <QStyleOptionGraphicsItem>
+#include <QtMath>
+#include <QPageLayout>
+
+namespace {
+class PageItem : public QGraphicsItem
+{
+public:
+ PageItem(int _pageNum, const QImage _pagePicture, QSize _paperSize)
+ : pageNum(_pageNum), pagePicture(_pagePicture),
+ paperSize(_paperSize)
+ {
+ brect = QRectF(QPointF(-25, -25),
+ QSizeF(paperSize)+QSizeF(50, 50));
+ setCacheMode(DeviceCoordinateCache);
+ }
+
+ QRectF boundingRect() const Q_DECL_OVERRIDE
+ { return brect; }
+
+ inline int pageNumber() const
+ { return pageNum; }
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget) Q_DECL_OVERRIDE;
+
+private:
+ int pageNum;
+ const QImage pagePicture;
+ QSize paperSize;
+ QRectF brect;
+};
+
+void PageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(widget);
+ QRectF paperRect(0,0, paperSize.width(), paperSize.height());
+
+ // Draw shadow
+ painter->setClipRect(option->exposedRect);
+ qreal shWidth = paperRect.width()/100;
+ QRectF rshadow(paperRect.topRight() + QPointF(0, shWidth),
+ paperRect.bottomRight() + QPointF(shWidth, 0));
+ QLinearGradient rgrad(rshadow.topLeft(), rshadow.topRight());
+ rgrad.setColorAt(0.0, QColor(0,0,0,255));
+ rgrad.setColorAt(1.0, QColor(0,0,0,0));
+ painter->fillRect(rshadow, QBrush(rgrad));
+ QRectF bshadow(paperRect.bottomLeft() + QPointF(shWidth, 0),
+ paperRect.bottomRight() + QPointF(0, shWidth));
+ QLinearGradient bgrad(bshadow.topLeft(), bshadow.bottomLeft());
+ bgrad.setColorAt(0.0, QColor(0,0,0,255));
+ bgrad.setColorAt(1.0, QColor(0,0,0,0));
+ painter->fillRect(bshadow, QBrush(bgrad));
+ QRectF cshadow(paperRect.bottomRight(),
+ paperRect.bottomRight() + QPointF(shWidth, shWidth));
+ QRadialGradient cgrad(cshadow.topLeft(), shWidth, cshadow.topLeft());
+ cgrad.setColorAt(0.0, QColor(0,0,0,255));
+ cgrad.setColorAt(1.0, QColor(0,0,0,0));
+ painter->fillRect(cshadow, QBrush(cgrad));
+
+ painter->setClipRect(paperRect & option->exposedRect);
+ painter->fillRect(paperRect, Qt::white);
+ if (pagePicture.isNull()){
+ qDebug() << "NULL";
+ return;
+ }
+ painter->drawImage(QPoint(0,0), pagePicture);
+}
+}
+
+class PrintWidget : public QGraphicsView
+{
+ Q_OBJECT
+public:
+ PrintWidget(QWidget *parent = 0);
+ ~PrintWidget();
+ enum ViewMode {
+ SinglePageView,
+ FacingPagesView,
+ AllPagesView
+ };
+
+ enum ZoomMode {
+ CustomZoom,
+ FitToWidth,
+ FitInView
+ };
+
+ double getZoomFactor() const { return this->zoomFactor; };
+ ZoomMode getZoomMode() const { return this->zoomMode; };
+ int currentPage() const { return curPage; };
+ void setPictures(QHash<int, QImage>*);
+
+signals:
+ void resized();
+ void customContextMenuRequested(const QPoint&);
+public slots:
+ void zoomIn(double factor=1.2);
+ void zoomOut(double factor=1.2);
+ void setCurrentPage(int);
+ void setVisible(bool) Q_DECL_OVERRIDE;
+ void setOrientation(QPageLayout::Orientation);
+ void highlightText(int, QRectF);
+
+ void updatePreview();
+ void fitView();
+ void fitToWidth();
+ void setAllPagesViewMode();
+ void setSinglePageViewMode();
+ void setFacingPagesViewMode();
+
+private slots:
+ void updateCurrentPage();
+ int calcCurrentPage();
+ void fit(bool doFitting=false);
+protected:
+ void resizeEvent(QResizeEvent* e) Q_DECL_OVERRIDE {
+ /*{
+ const QSignalBlocker blocker(verticalScrollBar()); // Don't change page, QTBUG-14517
+ QGraphicsView::resizeEvent(e);
+ }*/
+ QGraphicsView::resizeEvent(e);
+ emit resized();
+ }
+
+ void showEvent(QShowEvent* e) Q_DECL_OVERRIDE {
+ QGraphicsView::showEvent(e);
+ emit resized();
+ }
+private:
+ void generatePreview();
+ void layoutPages();
+ void populateScene();
+ void setViewMode(ViewMode);
+ void setZoomMode(ZoomMode);
+ QGraphicsScene *scene;
+
+ int curPage;
+ ViewMode viewMode;
+ ZoomMode zoomMode;
+ QPageLayout::Orientation orientation;
+ double zoomFactor;
+ bool initialized, fitting;
+ QList<QGraphicsItem*> pages;
+ QHash<int, QImage> *pictures;
+};
+#endif
diff --git a/src-qt5/desktop-utils/lumina-pdf/lumina-pdf.pro b/src-qt5/desktop-utils/lumina-pdf/lumina-pdf.pro
index e17e59c5..8ee67d06 100644
--- a/src-qt5/desktop-utils/lumina-pdf/lumina-pdf.pro
+++ b/src-qt5/desktop-utils/lumina-pdf/lumina-pdf.pro
@@ -18,14 +18,19 @@ include(../../core/libLumina/LuminaXDG.pri)
message("Qt Modules Needed: $${QT}")
SOURCES += main.cpp \
- mainUI.cpp
+ mainUI.cpp \
+ propDialog.cpp \
+ PrintWidget.cpp
-HEADERS += mainUI.h
+HEADERS += mainUI.h \
+ PrintWidget.h \
+ PresentationLabel.h \
+ PropDialog.h
-FORMS += mainUI.ui
+FORMS += mainUI.ui \
+ propDialog.ui
LIBS += -lpoppler-qt5
-INCLUDEPATH+= $${L_INCLUDEDIR}/poppler/qt5
TRANSLATIONS = i18n/l-pdf_af.ts \
i18n/l-pdf_ar.ts \
@@ -95,7 +100,7 @@ TRANSLATIONS = i18n/l-pdf_af.ts \
i18n/l-pdf_zu.ts
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
-dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
+dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
desktop.files=lumina-pdf.desktop
desktop.path=$${L_SHAREDIR}/applications/
diff --git a/src-qt5/desktop-utils/lumina-pdf/mainUI.cpp b/src-qt5/desktop-utils/lumina-pdf/mainUI.cpp
index 7a310e85..57afbfe1 100644
--- a/src-qt5/desktop-utils/lumina-pdf/mainUI.cpp
+++ b/src-qt5/desktop-utils/lumina-pdf/mainUI.cpp
@@ -16,21 +16,24 @@
#include <QApplication>
#include <QScreen>
#include <QTimer>
+#include <iostream>
#include <QtConcurrent>
#include <LuminaXDG.h>
+#include "PrintWidget.h"
MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI()){
ui->setupUi(this);
- presentationLabel = 0;
this->setWindowTitle(tr("Lumina PDF Viewer"));
this->setWindowIcon( LXDG::findIcon("application-pdf","unknown"));
- CurrentPage = 0;
+ presentationLabel = 0;
+ CurrentPage = 1;
lastdir = QDir::homePath();
- Printer = new QPrinter();
//Create the interface widgets
- WIDGET = new QPrintPreviewWidget(Printer,this);
+ WIDGET = new PrintWidget(this);
+ WIDGET->setVisible(false);
+ WIDGET->setContextMenuPolicy(Qt::CustomContextMenu);
clockTimer = new QTimer(this);
clockTimer->setInterval(1000); //1-second updates to clock
connect(clockTimer, SIGNAL(timeout()), this, SLOT(updateClock()) );
@@ -39,15 +42,22 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI()){
label_clock->setAlignment(Qt::AlignCenter );
label_clock->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
label_clock->setStyleSheet("QLabel{color: palette(highlight-text); background-color: palette(highlight); border-radius: 5px; }");
+ //Context Menu
+ contextMenu = new QMenu(this);
+ connect(contextMenu, SIGNAL(aboutToShow()), this, SLOT(updateContextMenu()));
//Now put the widgets into the UI
+ ui->bookmarksFrame->setParent(WIDGET);
+ ui->findGroup->setParent(WIDGET);
+ qDebug() << "Setting central widget";
this->setCentralWidget(WIDGET);
- connect(WIDGET, SIGNAL(paintRequested(QPrinter*)), this, SLOT(paintOnWidget(QPrinter*)) );
+ WIDGET->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(WIDGET, SIGNAL(customContextMenuRequested(const QPoint&)),this, SLOT(showContextMenu(const QPoint&)) );
DOC = 0;
connect(this, SIGNAL(PageLoaded(int)), this, SLOT(slotPageLoaded(int)) );
PrintDLG = new QPrintDialog(this);
connect(PrintDLG, SIGNAL(accepted(QPrinter*)), this, SLOT(paintToPrinter(QPrinter*)) );
- connect(ui->menuStart_Presentation, SIGNAL(triggered(QAction*)), this, SLOT(slotStartPresentation(QAction*)) );
+ //connect(ui->menuStart_Presentation, SIGNAL(triggered(QAction*)), this, SLOT(slotStartPresentation(QAction*)) );
//Create the other interface widgets
progress = new QProgressBar(this);
@@ -57,6 +67,7 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI()){
progAct->setVisible(false);
clockAct = ui->toolBar->addWidget(label_clock);
clockAct->setVisible(false);
+
//Put the various actions into logical groups
QActionGroup *tmp = new QActionGroup(this);
tmp->setExclusive(true);
@@ -71,15 +82,66 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI()){
tmp->addAction(ui->actionAll_Pages);
ui->actionSingle_Page->setChecked(true);
+ qDebug() << "Starting connections";
+
//Connect up the buttons
connect(ui->actionClose, SIGNAL(triggered()), this, SLOT(close()) );
connect(ui->actionPrint, SIGNAL(triggered()), PrintDLG, SLOT(open()) );
connect(ui->actionFit_Width, SIGNAL(triggered()), WIDGET, SLOT(fitToWidth()) );
- connect(ui->actionFit_Page, SIGNAL(triggered()), WIDGET, SLOT(fitInView()) );
+ connect(ui->actionFit_Page, SIGNAL(triggered()), WIDGET, SLOT(fitView()) );
connect(ui->actionOpen_PDF, SIGNAL(triggered()), this, SLOT(OpenNewFile()) );
connect(ui->actionSingle_Page, SIGNAL(triggered()), WIDGET, SLOT(setSinglePageViewMode()) );
connect(ui->actionDual_Pages, SIGNAL(triggered()), WIDGET, SLOT(setFacingPagesViewMode()) );
connect(ui->actionAll_Pages, SIGNAL(triggered()), WIDGET, SLOT(setAllPagesViewMode()) );
+ //connect(ui->actionScroll_Mode, &QAction::triggered, this, [&] { this->setScroll(true); });
+ //connect(ui->actionSelect_Mode, &QAction::triggered, this, [&] { this->setScroll(false); });
+ connect(ui->actionZoom_In, &QAction::triggered, WIDGET, [&] { WIDGET->zoomIn(1.2); });
+ connect(ui->actionZoom_Out, &QAction::triggered, WIDGET, [&] { WIDGET->zoomOut(1.2); });
+ connect(ui->actionRotate_Counterclockwise, &QAction::triggered, this, [&] { this->rotate(true); });
+ connect(ui->actionRotate_Clockwise, &QAction::triggered, this, [&] { this->rotate(false); });
+ connect(ui->actionZoom_In_2, &QAction::triggered, WIDGET, [&] { WIDGET->zoomIn(1.2); });
+ connect(ui->actionZoom_Out_2, &QAction::triggered, WIDGET, [&] { WIDGET->zoomOut(1.2); });
+ connect(ui->actionFirst_Page, SIGNAL(triggered()), this, SLOT(firstPage()) );
+ connect(ui->actionPrevious_Page, SIGNAL(triggered()), this, SLOT(prevPage()) );
+ connect(ui->actionNext_Page, SIGNAL(triggered()), this, SLOT(nextPage()) );
+ connect(ui->actionLast_Page, SIGNAL(triggered()), this, SLOT(lastPage()) );
+ connect(ui->actionProperties, SIGNAL(triggered()), this, SLOT(showInformation()));
+ connect(ui->actionFind, SIGNAL(triggered()), this, SLOT(enableFind()));
+ connect(ui->actionFind_Next, &QAction::triggered, this,
+ [&] { find(ui->textEdit->text(), true); });
+ connect(ui->actionFind_Previous, &QAction::triggered, this,
+ [&] { find(ui->textEdit->text(), false); });
+ connect(ui->findNextB, &QPushButton::clicked, this,
+ [&] { find(ui->textEdit->text(), true); });
+ connect(ui->findPrevB, &QPushButton::clicked, this,
+ [&] { find(ui->textEdit->text(), false); });
+ connect(ui->matchCase, &QPushButton::clicked, this,
+ [&] (bool value) { this->matchCase = value; });
+ connect(ui->closeFind, &QPushButton::clicked, this,
+ [&] { ui->findGroup->setVisible(false); this->setFocus(); });
+ connect(ui->actionClearHighlights, &QAction::triggered, WIDGET,
+ [&] { WIDGET->updatePreview(); });
+ connect(ui->actionBookmarks, SIGNAL(triggered()), this, SLOT(showBookmarks()));
+
+ qDebug() << "Finished connctions";
+
+ //int curP = WIDGET->currentPage()-1; //currentPage reports pages starting at 1
+ //int lastP = numPages-1;
+ ui->actionFirst_Page->setText(tr("First Page"));
+ ui->actionPrevious_Page->setText(tr("Previous Page"));
+ ui->actionNext_Page->setText(tr("Next Page"));
+ ui->actionLast_Page->setText(tr("Last Page"));
+ /*ui->actionFirst_Page->setEnabled(curP!=0);
+ ui->actionPrevious_Page->setEnabled(curP>0);
+ ui->actionNext_Page->setEnabled(curP<lastP);
+ ui->actionLast_Page->setEnabled(curP!=lastP);*/
+
+ ui->actionStart_Here->setText(tr("Start Presentation (current slide)"));
+ connect(ui->actionStart_Here, SIGNAL(triggered()), this, SLOT(startPresentationHere()) );
+ ui->actionStart_Begin->setText(tr("Start Presentation (at beginning)"));
+ connect(ui->actionStart_Begin, SIGNAL(triggered()), this, SLOT(startPresentationBeginning()) );
+ ui->actionStop_Presentation->setText(tr("Stop Presentation"));
+ connect(ui->actionStop_Presentation, SIGNAL(triggered()), this, SLOT(closePresentation()) );
//Setup all the icons
ui->actionPrint->setIcon( LXDG::findIcon("document-print",""));
@@ -90,10 +152,41 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI()){
ui->actionSingle_Page->setIcon(LXDG::findIcon("format-view-agenda",""));
ui->actionDual_Pages->setIcon(LXDG::findIcon("format-view-grid-small",""));
ui->actionAll_Pages->setIcon(LXDG::findIcon("format-view-grid-large",""));
+ ui->actionScroll_Mode->setIcon(LXDG::findIcon("cursor-pointer",""));
+ ui->actionSelect_Mode->setIcon(LXDG::findIcon("cursor-text",""));
+ ui->actionZoom_In->setIcon(LXDG::findIcon("zoom-in",""));
+ ui->actionZoom_Out->setIcon(LXDG::findIcon("zoom-out",""));
+ ui->actionZoom_In_2->setIcon(LXDG::findIcon("zoom-in",""));
+ ui->actionZoom_Out_2->setIcon(LXDG::findIcon("zoom-out",""));
+ ui->actionRotate_Counterclockwise->setIcon(LXDG::findIcon("object-rotate-left",""));
+ ui->actionRotate_Clockwise->setIcon(LXDG::findIcon("object-rotate-right",""));
+ ui->actionFirst_Page->setIcon(LXDG::findIcon("go-first",""));
+ ui->actionPrevious_Page->setIcon(LXDG::findIcon("go-previous",""));
+ ui->actionNext_Page->setIcon(LXDG::findIcon("go-next",""));
+ ui->actionLast_Page->setIcon(LXDG::findIcon("go-last",""));
+ ui->actionStart_Here->setIcon(LXDG::findIcon("media-playback-start-circled",""));
+ ui->actionStart_Begin->setIcon(LXDG::findIcon("presentation-play",""));
+ ui->actionStop_Presentation->setIcon(LXDG::findIcon("media-playback-stop-circled",""));
+ ui->actionBookmarks->setIcon(LXDG::findIcon("bookmark-new",""));
+ ui->actionFind->setIcon(LXDG::findIcon("edit-find",""));
+ ui->actionFind_Next->setIcon(LXDG::findIcon("edit-find-next",""));
+ ui->actionFind_Previous->setIcon(LXDG::findIcon("edit-find-prev",""));
+ ui->actionProperties->setIcon(LXDG::findIcon("dialog-information",""));
+ ui->actionSettings->setIcon(LXDG::findIcon("document-properties",""));
+ ui->findNextB->setIcon(LXDG::findIcon("go-down-search"));
+ ui->findPrevB->setIcon(LXDG::findIcon("go-up-search"));
+ ui->matchCase->setIcon(LXDG::findIcon("format-text-italic"));
+ ui->closeFind->setIcon(LXDG::findIcon("dialog-close"));
+
+ qDebug() << "Finished setting icons";
//Now set the default state of the menu's and actions
- ui->menuStart_Presentation->setEnabled(false);
ui->actionStop_Presentation->setEnabled(false);
+ ui->actionStart_Here->setEnabled(false);
+ ui->actionStart_Begin->setEnabled(false);
+
+ ui->findGroup->setVisible(false);
+ ui->bookmarksFrame->setVisible(false);
}
MainUI::~MainUI(){
@@ -101,8 +194,8 @@ MainUI::~MainUI(){
}
void MainUI::loadFile(QString path){
-
if(!QFile::exists(path) || path.isEmpty() ){ return; }
+
Poppler::Document *TDOC = Poppler::Document::load(path);
if(TDOC==0){
qDebug() << "Could not open file:" << path;
@@ -116,44 +209,56 @@ void MainUI::loadFile(QString path){
}
if(TDOC->isLocked()){ return; } //Cancelled - still locked
}
+ //qpdf.processFile(path.toLatin1().data(), pass.toLatin1().data());
if(DOC!=0){
//Clear out the old document first
delete DOC;
DOC=0;
}
- loadingHash.clear(); //clear out this hash
+ //loadingHash.clear(); //clear out this hash
numPages = -1;
DOC = TDOC; //Save this for later
qDebug() << "Opening File:" << path;
- this->setWindowTitle(DOC->title());
+ this->setWindowTitle(TDOC->title());
if(this->windowTitle().isEmpty()){ this->setWindowTitle(path.section("/",-1)); }
//Setup the Document
+ //QVector<QPDFObjectHandle> pages = (QVector<QPDFObjectHandle>)pdf.getAllPages();
+ //QPDFObjectHandle page = pages.at(0);
Poppler::Page *PAGE = DOC->page(0);
if(PAGE!=0){
lastdir = path.section("/",0,-2); //save this for later
- Printer->setPageSize( QPageSize(PAGE->pageSize(), QPageSize::Point) );
- Printer->setPageMargins(QMarginsF(0,0,0,0), QPageLayout::Point);
switch(PAGE->orientation()){
- case Poppler::Page::Landscape:
- Printer->setOrientation(QPrinter::Landscape); break;
- default:
- Printer->setOrientation(QPrinter::Portrait);
+ case Poppler::Page::Landscape:
+ WIDGET->setOrientation(QPageLayout::Landscape); break;
+ default:
+ WIDGET->setOrientation(QPageLayout::Portrait);
}
delete PAGE;
- //qDebug() << " - Document Setup : start loading pages now";
- QTimer::singleShot(10, WIDGET, SLOT(updatePreview())); //start loading the file preview
+ qDebug() << " - Document Setup : start loading pages now";
+ startLoadingPages();
+ //QTimer::singleShot(10, WIDGET, SLOT(updatePreview())); //start loading the file preview
}
}
void MainUI::loadPage(int num, Poppler::Document *doc, MainUI *obj, QSize dpi, QSizeF page){
+ //PERFORMANCE NOTES:
+ // Using Poppler to scale the image (adjust dpi value) helps a bit but you take a large CPU loading hit (and still quite a lot of pixelization)
+ // Using Qt to scale the image (adjust page value) smooths out the image quite a bit without a lot of performance loss (but cannot scale up without pixelization)
+ // The best approach seams to be to increase the DPI a bit, but match that with the same scaling on the page size (smoothing)
+
//qDebug() << " - Render Page:" << num;
Poppler::Page *PAGE = doc->page(num);
if(PAGE!=0){
- //qDebug() << "DPI:" << 4*dpi;
- loadingHash.insert(num, PAGE->renderToImage(2.5*dpi.width(), 2.5*dpi.height()).scaled(2*page.width(), 2*page.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation) );
+ //qDebug() << "DPI:" << dpi << "Size:" << page << "Page Size (pt):" << PAGE->pageSize();
+ float scalefactor = (dpi.width()/72.0); //How different the screen DPI compares to standard page DPI
+ //qDebug() << "Scale Factor:" << scalefactor;
+ QImage raw = PAGE->renderToImage((scalefactor+0.2)*dpi.width(), (scalefactor+0.2)*dpi.height()); //make the raw image a tiny bit larger than the end result
+ //qDebug() << " - Raw Image Size:" << raw.size();
+ loadingHash.insert(num, raw.scaled(scalefactor*page.width(), scalefactor*page.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation) );
+ raw = QImage(); //clear it
/*
QList<Annotation*> anno = PAGE->annotations(Annotations::AText );
QStringList annoS;
@@ -212,16 +317,20 @@ void MainUI::startPresentation(bool atStart){
//Now create the full-screen window on the selected screen
if(presentationLabel == 0){
//Create the label and any special flags for it
- presentationLabel = new QLabel(0, Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
+ presentationLabel = new PresentationLabel();
presentationLabel->setStyleSheet("background-color: black;");
presentationLabel->setAlignment(Qt::AlignCenter);
+ presentationLabel->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(presentationLabel, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint&)) );
+ connect(presentationLabel, SIGNAL(nextSlide()), this, SLOT(nextPage()) );
}
//Now put the label in the proper location
presentationLabel->setGeometry(screen->geometry());
presentationLabel->showFullScreen();
ui->actionStop_Presentation->setEnabled(true);
- ui->menuStart_Presentation->setEnabled(false);
+ ui->actionStart_Here->setEnabled(false);
+ ui->actionStart_Begin->setEnabled(false);
updateClock();
clockAct->setVisible(true);
clockTimer->start();
@@ -238,7 +347,7 @@ void MainUI::ShowPage(int page){
endPresentation();
return; //invalid - no document loaded or invalid page specified
}
- WIDGET->setCurrentPage(page+1); //page numbers start at 1 for this widget
+ WIDGET->setCurrentPage(page); //page numbers start at 1 for this widget
//Stop here if no presentation currently running
if(presentationLabel == 0 || !presentationLabel->isVisible()){ return; }
CurrentPage = page;
@@ -261,57 +370,58 @@ void MainUI::endPresentation(){
if(presentationLabel==0 || !presentationLabel->isVisible()){ return; } //not in presentation mode
presentationLabel->hide(); //just hide this (no need to re-create the label for future presentations)
ui->actionStop_Presentation->setEnabled(false);
- ui->menuStart_Presentation->setEnabled(true);
+ ui->actionStart_Here->setEnabled(true);
+ ui->actionStart_Begin->setEnabled(true);
clockTimer->stop();
clockAct->setVisible(false);
this->releaseKeyboard();
}
-void MainUI::startLoadingPages(QPrinter *printer){
+void MainUI::startLoadingPages(){
if(numPages>0){ return; } //currently loaded[ing]
- //qDebug() << " - Start Loading Pages";
+ qDebug() << " - Start Loading Pages";
numPages = DOC->numPages();
//qDebug() << "numPages:" << numPages;
progress->setRange(0,numPages);
progress->setValue(0);
progAct->setVisible(true);
- QRectF pageSize = printer->pageRect(QPrinter::DevicePixel);
- QSize DPI(printer->resolution(),printer->resolution());
+ QSizeF pageSize = DOC->page(0)->pageSizeF()*2;
+ //QSize DPI(loadingHash[0]->resolution(),loadingHash[0]->resolution());
+ QSize DPI(76,76);
+ /*qDebug() << "Screen Resolutions:";
+ QList<QScreen*> screens = QApplication::screens();
+ for(int i=0; i<screens.length(); i++){
+ qDebug() << screens[i]->name() << screens[i]->logicalDotsPerInchX() << screens[i]->logicalDotsPerInchY();
+ }*/
+ qDebug() << "Poppler pageSize: " << pageSize;
for(int i=0; i<numPages; i++){
//qDebug() << " - Kickoff page load:" << i;
- QtConcurrent::run(this, &MainUI::loadPage, i, DOC, this, DPI, pageSize.size() );
+ QtConcurrent::run(this, &MainUI::loadPage, i, DOC, this, DPI, pageSize);
}
}
void MainUI::slotPageLoaded(int page){
+ Q_UNUSED(page);
//qDebug() << "Page Loaded:" << page;
int finished = loadingHash.keys().length();
if(finished == numPages){
progAct->setVisible(false);
- QTimer::singleShot(0, WIDGET, SLOT(updatePreview()));
+ qDebug() << "Setting Pictures";
+ WIDGET->setPictures(&loadingHash);
+ WIDGET->setVisible(true);
+ //QTimer::singleShot(10, WIDGET, SLOT(updatePreview()));
+ //qDebug() << "Updating";
ui->actionStop_Presentation->setEnabled(false);
- ui->menuStart_Presentation->setEnabled(true);
+ ui->actionStart_Here->setEnabled(true);
+ ui->actionStart_Begin->setEnabled(true);
}else{
progress->setValue(finished);
}
}
-void MainUI::slotStartPresentation(QAction *act){
+/*void MainUI::slotStartPresentation(QAction *act){
startPresentation(act == ui->actionAt_Beginning);
-}
-
-void MainUI::paintOnWidget(QPrinter *PRINTER){
- if(DOC==0){ return; }
- //this->show();
- if(loadingHash.keys().length() != numPages){ startLoadingPages(PRINTER); return; }
-
- QPainter painter(PRINTER);
- for(int i=0; i<numPages; i++){
- if(i != 0){ PRINTER->newPage(); } //this is the start of the next page (not needed for first)
- if(loadingHash.contains(i)){ painter.drawImage(0,0, loadingHash[i].scaled(PRINTER->pageRect().size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); }
- else{ painter.drawImage(0,0, QImage()); }
- }
-}
+}*/
void MainUI::paintToPrinter(QPrinter *PRINTER){
if(loadingHash.keys().length() != numPages){ return; }
@@ -320,7 +430,7 @@ void MainUI::paintToPrinter(QPrinter *PRINTER){
int firstpage = 0;
int copies = PRINTER->copyCount();
bool collate = PRINTER->collateCopies();
- bool duplex = (PRINTER->duplex()!=QPrinter::DuplexNone);
+ //bool duplex = (PRINTER->duplex()!=QPrinter::DuplexNone);
//Determine the first page that needs to be printed, and the range
if((PRINTER->fromPage() != PRINTER->toPage() || PRINTER->fromPage()!=0 ) && PRINTER->printRange()==QPrinter::PageRange ){
firstpage = PRINTER->fromPage() - 1;
@@ -350,7 +460,6 @@ void MainUI::paintToPrinter(QPrinter *PRINTER){
}
}
//qDebug() << "Final Page Range:" << pageCount;
- //return;
//Generate the sizing information for the printer
QSize sz(PRINTER->pageRect().width(), PRINTER->pageRect().height());
bool landscape = PRINTER->orientation()==QPrinter::Landscape;
@@ -383,3 +492,166 @@ void MainUI::OpenNewFile(){
void MainUI::updateClock(){
label_clock->setText( QDateTime::currentDateTime().toString("<b>hh:mm:ss</b>") );
}
+
+void MainUI::setScroll(bool tog) {
+ if(tog) {
+ QApplication::setOverrideCursor(Qt::OpenHandCursor);
+ }else{
+ QApplication::setOverrideCursor(Qt::IBeamCursor);
+ }
+}
+
+void MainUI::rotate(bool ccw) {
+ for(int i = 0; i < numPages; i++) {
+ QImage image = loadingHash[i];
+ qDebug() << "Page rotating: " << i;
+ //Setup a rotation matrix that rotates 90 degrees clockwise or counterclockwise
+ QMatrix matrix = (ccw) ? QMatrix(0, -1, 1, 0, 0, 0) : QMatrix(0, 1, -1, 0, 0, 0);
+ image = image.transformed(matrix, Qt::SmoothTransformation);
+ //Updates the image in the hash
+ loadingHash.insert(i, image);
+ }
+ //Rotates the page as well as the image
+ //WIDGET->setOrientation((WIDGET->orientation() == QPageLayout::Landscape) ?
+ //QPageLayout::Portrait : QPageLayout::Landscape);
+ QTimer::singleShot(0, WIDGET, SLOT(updatePreview()));
+}
+
+void MainUI::updateContextMenu(){
+ contextMenu->clear();
+ contextMenu->addSection( QString(tr("Page %1 of %2")).arg(QString::number(WIDGET->currentPage()),
+ QString::number(numPages) ) );
+ contextMenu->addAction(ui->actionPrevious_Page);
+ contextMenu->addAction(ui->actionNext_Page);
+ contextMenu->addSeparator();
+ contextMenu->addAction(ui->actionFirst_Page);
+ contextMenu->addAction(ui->actionLast_Page);
+ contextMenu->addSeparator();
+ if(presentationLabel==0 || !presentationLabel->isVisible()){
+ contextMenu->addAction(ui->actionStart_Begin);
+ contextMenu->addAction(ui->actionStart_Here);
+ }else{
+ contextMenu->addAction(ui->actionStop_Presentation);
+ }
+}
+
+void MainUI::keyPressEvent(QKeyEvent *event){
+ //See if this is one of the special hotkeys and act appropriately
+ bool inPresentation = (presentationLabel!=0);
+ if( event->key()==Qt::Key_Escape || event->key()==Qt::Key_Backspace){
+ if(inPresentation){ endPresentation(); }
+ }else if(event->key()==Qt::Key_Right || event->key()==Qt::Key_Space ||
+ event->key()==Qt::Key_PageDown){
+ nextPage();
+ }else if(event->key()==Qt::Key_Left || event->key()==Qt::Key_PageUp){
+ prevPage();
+ }else if(event->key()==Qt::Key_Home){
+ firstPage();
+ }else if(event->key()==Qt::Key_End){
+ lastPage();
+ }else if(event->key()==Qt::Key_F11){
+ if(inPresentation){ endPresentation(); }
+ else{ startPresentationHere(); }
+ }else if(event->key() == Qt::Key_Up) {
+ //Scroll the widget up
+ }else if(event->key() == Qt::Key_Down) {
+ //Scroll the widget down
+ /*qDebug() << "Send Wheel Event";
+ QWheelEvent wEvent( WIDGET->mapFromGlobal(QCursor::pos()), QCursor::pos(),QPoint(0,0), QPoint(0,30), 0, Qt::Vertical, Qt::LeftButton, Qt::NoModifier);
+ QApplication::sendEvent(WIDGET, &wEvent);*/
+ }else{
+ QMainWindow::keyPressEvent(event);
+ }
+}
+
+void MainUI::wheelEvent(QWheelEvent *event) {
+ //Scroll the window according to the mouse wheel
+ QMainWindow::wheelEvent(event);
+}
+
+void MainUI::showInformation() {
+ PROPDIALOG = new PropDialog(DOC);
+ PROPDIALOG->show();
+}
+
+void MainUI::find(QString text, bool forward) {
+ if(!text.isEmpty()) {
+ qDebug() << "Finding Text";
+ bool newText = results.empty();
+ bool research = false;
+ if(!newText)
+ research = !results.keys()[0]->text().contains(text);
+ //Clear results if the user gives a new search string
+ if(research)
+ results.clear();
+
+ if(research or newText) {
+ for(int i = 0; i < numPages; i++) {
+ QList<Poppler::TextBox*> textList = DOC->page(i)->textList();
+ for(int j = 0; j < textList.size(); j++) {
+ if(textList[j]->text().contains(text, (matchCase)
+ ? Qt::CaseSensitive : Qt::CaseInsensitive)) {
+ results.insert(textList[j], i);
+ }
+ }
+ }
+ currentHighlight = (forward) ? -1 : results.size();
+ }
+
+ qDebug() << "Jumping to next result";
+ if(!results.empty()) {
+ //Jump to the location of the next or previous textbox and highlight
+ if(forward) {
+ currentHighlight = (currentHighlight + 1) % results.size();
+ }else{
+ currentHighlight--;
+ //Ensure currentHighlight will be between 0 and results.size() - 1
+ if(currentHighlight < 0)
+ currentHighlight = results.size() - 1;
+ }
+
+ qDebug() << "Jump to location: " << currentHighlight;
+
+ Poppler::TextBox *currentText = results.keys()[currentHighlight];
+ WIDGET->setCurrentPage(results.value(currentText));
+ WIDGET->highlightText(currentHighlight, currentText->boundingBox());
+
+ QTimer::singleShot(10, WIDGET, SLOT(updatePreview()));
+ }else{
+ //Print "No results found"
+ }
+ }
+}
+
+void MainUI::enableFind() {
+ if(ui->findGroup->isVisible()) {
+ qDebug() << "Disabling Find";
+ ui->findGroup->setVisible(false);
+ WIDGET->setGeometry(QRect(WIDGET->pos(),
+ QSize(WIDGET->width(), WIDGET->height()+ui->findGroup->height())));
+ QTimer::singleShot(0, WIDGET, SLOT(updatePreview()));
+ this->setFocus();
+ }else{
+ qDebug() << "Enabling Find";
+ ui->findGroup->setGeometry(QRect(QPoint(0, WIDGET->height()-ui->findGroup->height()),
+ QSize(WIDGET->width()-12, ui->findGroup->height())));
+ ui->findGroup->setVisible(true);
+ WIDGET->setGeometry(QRect(WIDGET->pos(),
+ QSize(WIDGET->width(), WIDGET->height()-ui->findGroup->height())));
+
+ QTimer::singleShot(0, WIDGET, SLOT(updatePreview()));
+ ui->findGroup->setFocus();
+ }
+}
+
+void MainUI::showBookmarks() {
+ ui->bookmarksFrame->setVisible(true);
+}
+
+void MainUI::resizeEvent(QResizeEvent *event) {
+ if(ui->findGroup->isVisible()) {
+ ui->findGroup->setGeometry(QRect(QPoint(0, WIDGET->height()-ui->findGroup->height()),
+ QSize(WIDGET->width()-10, ui->findGroup->height())));
+ }
+ QMainWindow::resizeEvent(event);
+}
diff --git a/src-qt5/desktop-utils/lumina-pdf/mainUI.h b/src-qt5/desktop-utils/lumina-pdf/mainUI.h
index 87d2a4e4..2d23b402 100644
--- a/src-qt5/desktop-utils/lumina-pdf/mainUI.h
+++ b/src-qt5/desktop-utils/lumina-pdf/mainUI.h
@@ -17,8 +17,12 @@
#include <QDebug>
#include <QWheelEvent>
#include <QApplication>
+#include <QMenu>
-#include <poppler-qt5.h>
+#include <poppler/qt5/poppler-qt5.h>
+#include "PresentationLabel.h"
+#include "propDialog.h"
+#include "PrintWidget.h"
namespace Ui{
class MainUI;
@@ -32,20 +36,22 @@ public:
void loadFile(QString path);
-
private:
Poppler::Document *DOC;
- QPrintPreviewWidget *WIDGET;
+ PrintWidget *WIDGET;
Ui::MainUI *ui;
- QPrinter* Printer;
+ PropDialog *PROPDIALOG;
QPrintDialog *PrintDLG;
-
QString lastdir;
+ bool matchCase;
+ QMap<Poppler::TextBox*, int> results;
+ int currentHighlight;
//Other Interface elements
QProgressBar *progress;
QAction *progAct; //action associated with the progressbar
QTimer *clockTimer;
+ QMenu *contextMenu;
//QFrame *frame_presenter;
QLabel *label_clock;
QAction *clockAct;
@@ -57,7 +63,7 @@ private:
void loadPage(int num, Poppler::Document *doc, MainUI *obj, QSize dpi, QSizeF page);
//Functions/variables for the presentation mode
- QLabel *presentationLabel;
+ PresentationLabel *presentationLabel;
QScreen *getScreen(bool current, bool &cancelled);
int CurrentPage;
void startPresentation(bool atStart);
@@ -65,11 +71,24 @@ private:
void endPresentation();
private slots:
- void startLoadingPages(QPrinter *printer);
+ void startLoadingPages();
void slotPageLoaded(int);
- void slotStartPresentation(QAction *act);
+ //void slotStartPresentation(QAction *act);
+
+ //Simplification routines
+ void nextPage(){ ShowPage( WIDGET->currentPage() ); } //currentPage() starts at 1 rather than 0
+ void prevPage(){ ShowPage( WIDGET->currentPage()-2 ); } //currentPage() starts at 1 rather than 0
+ void firstPage(){ ShowPage(0); }
+ void lastPage(){ ShowPage(numPages-1); }
+ void startPresentationHere(){ startPresentation(false); }
+ void startPresentationBeginning(){ startPresentation(true); }
+ void closePresentation(){ endPresentation(); }
+
+ void showInformation();
+ void find(QString text, bool forward);
+ void enableFind();
+ void showBookmarks();
- void paintOnWidget(QPrinter *PRINTER);
void paintToPrinter(QPrinter *PRINTER);
//Button Slots
@@ -77,49 +96,18 @@ private slots:
//Other interface slots
void updateClock();
+ void showContextMenu(const QPoint&){ contextMenu->popup(QCursor::pos()); }
+ void updateContextMenu();
+
+ void setScroll(bool);
+ void rotate(bool);
signals:
void PageLoaded(int);
protected:
- void keyPressEvent(QKeyEvent *event){
- //See if this is one of the special hotkeys and act appropriately
- //qDebug() << "Got Key Press:";
- bool inPresentation = (presentationLabel!=0);
- if(!inPresentation){
- //Alternate functionality when **not** in presentation mode
- /*if(event->key()==Qt::Key_Down){
- qDebug() << "Send Wheel Event";
- QWheelEvent event( WIDGET->mapFromGlobal(QCursor::pos()), QCursor::pos(),QPoint(0,0), QPoint(0,30), 0, Qt::Vertical, Qt::LeftButton, Qt::NoModifier);
- QApplication::sendEvent(WIDGET, &event);
- //WIDGET->scrollDown();
- return;
- }else if(event->key()==Qt::Key_Up){
- return;
- }*/
- }
-
- if( event->key()==Qt::Key_Escape || event->key()==Qt::Key_Backspace){
- //qDebug() << " - Escape/Backspace";
- endPresentation();
- }else if(event->key()==Qt::Key_Right || event->key()==Qt::Key_Down || event->key()==Qt::Key_Space || event->key()==Qt::Key_PageDown){
- //qDebug() << " - Right/Down/Spacebar" << inPresentation;
- ShowPage( WIDGET->currentPage() ); //currentPage() starts at 1 rather than 0
- }else if(event->key()==Qt::Key_Left || event->key()==Qt::Key_Up || event->key()==Qt::Key_PageUp){
- //qDebug() << " - Left/Up";
- ShowPage( WIDGET->currentPage()-2 ); //currentPage() starts at 1 rather than 0
- }else if(event->key()==Qt::Key_Home){
- //qDebug() << " - Home";
- ShowPage(0); //go to the first page
- }else if(event->key()==Qt::Key_End){
- //qDebug() << " - End";
- ShowPage( numPages-1 ); //go to the last page
- }else if(event->key()==Qt::Key_F11){
- //qDebug() << " - F11";
- endPresentation();
- }else{
- QMainWindow::keyPressEvent(event);
- }
- }
+ void keyPressEvent(QKeyEvent*);
+ void wheelEvent(QWheelEvent*);
+ void resizeEvent(QResizeEvent*);
};
#endif
diff --git a/src-qt5/desktop-utils/lumina-pdf/mainUI.ui b/src-qt5/desktop-utils/lumina-pdf/mainUI.ui
index 7f555d01..8f6fff27 100644
--- a/src-qt5/desktop-utils/lumina-pdf/mainUI.ui
+++ b/src-qt5/desktop-utils/lumina-pdf/mainUI.ui
@@ -6,21 +6,120 @@
<rect>
<x>0</x>
<y>0</y>
- <width>659</width>
- <height>588</height>
+ <width>697</width>
+ <height>694</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
- <widget class="QWidget" name="centralwidget"/>
+ <widget class="QWidget" name="centralwidget">
+ <widget class="QFrame" name="findGroup">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>560</y>
+ <width>691</width>
+ <height>61</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="closeFind">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="textEdit"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="findPrevB">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="findNextB">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="matchCase">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Find...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QFrame" name="bookmarksFrame">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>9</y>
+ <width>81</width>
+ <height>601</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <widget class="QLabel" name="label_2">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>0</y>
+ <width>71</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Bookmarks</string>
+ </property>
+ </widget>
+ </widget>
+ </widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>659</width>
- <height>28</height>
+ <width>697</width>
+ <height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@@ -32,22 +131,53 @@
<addaction name="actionOpen_PDF"/>
<addaction name="separator"/>
<addaction name="actionClose"/>
+ <addaction name="separator"/>
+ <addaction name="actionProperties"/>
</widget>
<widget class="QMenu" name="menuPresentation">
<property name="title">
<string>&amp;Presentation</string>
</property>
- <widget class="QMenu" name="menuStart_Presentation">
- <property name="title">
- <string>Start Presentation</string>
- </property>
- <addaction name="actionAt_Beginning"/>
- </widget>
- <addaction name="menuStart_Presentation"/>
+ <addaction name="actionStart_Begin"/>
+ <addaction name="actionStart_Here"/>
<addaction name="actionStop_Presentation"/>
</widget>
+ <widget class="QMenu" name="menuSettings">
+ <property name="title">
+ <string>Edit</string>
+ </property>
+ <addaction name="actionFind"/>
+ <addaction name="actionFind_Next"/>
+ <addaction name="actionFind_Previous"/>
+ <addaction name="actionClearHighlights"/>
+ <addaction name="separator"/>
+ <addaction name="actionSettings"/>
+ <addaction name="separator"/>
+ <addaction name="actionScroll_Mode"/>
+ <addaction name="actionSelect_Mode"/>
+ <addaction name="separator"/>
+ </widget>
+ <widget class="QMenu" name="menuView">
+ <property name="title">
+ <string>View</string>
+ </property>
+ <addaction name="actionZoom_In"/>
+ <addaction name="actionZoom_Out"/>
+ <addaction name="separator"/>
+ <addaction name="actionFirst_Page"/>
+ <addaction name="actionPrevious_Page"/>
+ <addaction name="actionNext_Page"/>
+ <addaction name="actionLast_Page"/>
+ <addaction name="separator"/>
+ <addaction name="actionBookmarks"/>
+ <addaction name="separator"/>
+ <addaction name="actionRotate_Counterclockwise"/>
+ <addaction name="actionRotate_Clockwise"/>
+ </widget>
<addaction name="menuFile"/>
<addaction name="menuPresentation"/>
+ <addaction name="menuSettings"/>
+ <addaction name="menuView"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QToolBar" name="toolBar">
@@ -72,6 +202,9 @@
<addaction name="actionSingle_Page"/>
<addaction name="actionDual_Pages"/>
<addaction name="actionAll_Pages"/>
+ <addaction name="separator"/>
+ <addaction name="actionZoom_In_2"/>
+ <addaction name="actionZoom_Out_2"/>
</widget>
<action name="actionOpen_PDF">
<property name="text">
@@ -137,9 +270,9 @@
<string>All Pages</string>
</property>
</action>
- <action name="actionAt_Beginning">
+ <action name="actionStart_Begin">
<property name="text">
- <string>At Beginning</string>
+ <string>Start Presentation (at beginning)</string>
</property>
</action>
<action name="actionStop_Presentation">
@@ -147,6 +280,118 @@
<string>Stop Presentation</string>
</property>
</action>
+ <action name="actionFind">
+ <property name="text">
+ <string>Find</string>
+ </property>
+ </action>
+ <action name="actionFind_Next">
+ <property name="text">
+ <string>Find Next</string>
+ </property>
+ </action>
+ <action name="actionFind_Previous">
+ <property name="text">
+ <string>Find Previous</string>
+ </property>
+ </action>
+ <action name="actionSettings">
+ <property name="text">
+ <string>Settings</string>
+ </property>
+ </action>
+ <action name="actionZoom_In">
+ <property name="text">
+ <string>Zoom In</string>
+ </property>
+ </action>
+ <action name="actionZoom_Out">
+ <property name="text">
+ <string>Zoom Out</string>
+ </property>
+ </action>
+ <action name="actionFirst_Page">
+ <property name="text">
+ <string>First Page</string>
+ </property>
+ </action>
+ <action name="actionPrevious_Page">
+ <property name="text">
+ <string>Previous Page</string>
+ </property>
+ </action>
+ <action name="actionNext_Page">
+ <property name="text">
+ <string>Next Page</string>
+ </property>
+ </action>
+ <action name="actionLast_Page">
+ <property name="text">
+ <string>Last Page</string>
+ </property>
+ </action>
+ <action name="actionProperties">
+ <property name="text">
+ <string>Properties</string>
+ </property>
+ </action>
+ <action name="actionBookmarks">
+ <property name="text">
+ <string>Bookmarks</string>
+ </property>
+ </action>
+ <action name="actionRotate_Counterclockwise">
+ <property name="text">
+ <string>Rotate Counterclockwise</string>
+ </property>
+ </action>
+ <action name="actionRotate_Clockwise">
+ <property name="text">
+ <string>Rotate Clockwise</string>
+ </property>
+ </action>
+ <action name="actionScroll_Mode">
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Scroll Mode</string>
+ </property>
+ </action>
+ <action name="actionZoom_Out_2">
+ <property name="text">
+ <string/>
+ </property>
+ </action>
+ <action name="actionZoom_In_2">
+ <property name="text">
+ <string/>
+ </property>
+ </action>
+ <action name="actionStart_Here">
+ <property name="text">
+ <string>Start Presentation (current slide)</string>
+ </property>
+ </action>
+ <action name="actionSelect_Mode">
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Select Mode</string>
+ </property>
+ </action>
+ <action name="actionClearHighlights">
+ <property name="text">
+ <string>Clear Highlights</string>
+ </property>
+ </action>
</widget>
<resources/>
<connections/>
diff --git a/src-qt5/desktop-utils/lumina-pdf/propDialog.cpp b/src-qt5/desktop-utils/lumina-pdf/propDialog.cpp
new file mode 100644
index 00000000..0c26af74
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-pdf/propDialog.cpp
@@ -0,0 +1,56 @@
+//===========================================
+// Lumina Desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+
+#include "propDialog.h"
+#include "ui_propDialog.h"
+
+#include <LuminaXDG.h>
+
+PropDialog::PropDialog(Poppler::Document *DOC) : QDialog(), ui(new Ui::PropDialog()){
+ this->setWindowTitle(tr("PDF Information"));
+ this->setWindowIcon( LXDG::findIcon("dialog-information","unknown"));
+ int verMa, verMi;
+ QString version;
+ QSize size = DOC->page(0)->pageSize();
+
+ //Grab the version
+ DOC->getPdfVersion(&verMa, &verMi);
+ version = QString::number(verMa)+"."+QString::number(verMi);
+
+ ui->setupUi(this);
+
+ connect(ui->closeButton, SIGNAL(clicked()), this, SLOT(close()));
+
+ //Setup translations
+ ui->titleL->setText(tr("Title:"));
+ ui->subjectL->setText(tr("Subject:"));
+ ui->authorL->setText(tr("Author:"));
+ ui->creatorL->setText(tr("Creator:"));
+ ui->producerL->setText(tr("Producer:"));
+ ui->keywordsL->setText(tr("Keywords:"));
+ ui->createdL->setText(tr("Created:"));
+ ui->modifiedL->setText(tr("Modified:"));
+ ui->versionL->setText(tr("PDF Version:"));
+ ui->sizeL->setText(tr("Page Size:"));
+ ui->numberL->setText(tr("Number of Pages:"));
+ ui->saveButton->setText(tr("Save"));
+ ui->closeButton->setText(tr("Close"));
+
+ //Fill the text boxes with information from the document
+ ui->titleE->setText(DOC->title());
+ ui->subjectE->setText(DOC->subject());
+ ui->authorE->setText(DOC->author());
+ ui->creatorE->setText(DOC->creator());
+ ui->producerE->setText(DOC->producer());
+ ui->keywordE->setText(DOC->keywords());
+ ui->createdEntry->setText(DOC->creationDate().toString(Qt::TextDate));
+ ui->modifiedEntry->setText(DOC->modificationDate().toString(Qt::TextDate));
+ ui->versionL->setText(ui->versionL->text()+version);
+ ui->sizeL->setText(ui->sizeL->text()+QString::number(size.height())+
+ ", "+QString::number(size.width()));
+ ui->numberL->setText(ui->numberL->text()+QString::number(DOC->numPages()));
+}
diff --git a/src-qt5/desktop-utils/lumina-pdf/propDialog.h b/src-qt5/desktop-utils/lumina-pdf/propDialog.h
new file mode 100644
index 00000000..be67ebd3
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-pdf/propDialog.h
@@ -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
+//===========================================
+#ifndef _LUMINA_PDF_VIEWER_PROP_DIALOG_H
+#define _LUMINA_PDF_VIEWER_PROP_DIALOG_H
+
+#include <QDialog>
+#include <poppler/qt5/poppler-qt5.h>
+
+namespace Ui{
+ class PropDialog;
+};
+
+class PropDialog : public QDialog {
+ Q_OBJECT
+ public:
+ PropDialog(Poppler::Document*);
+
+ private:
+ Ui::PropDialog *ui;
+};
+#endif
diff --git a/src-qt5/desktop-utils/lumina-pdf/propDialog.ui b/src-qt5/desktop-utils/lumina-pdf/propDialog.ui
new file mode 100644
index 00000000..6806f81a
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-pdf/propDialog.ui
@@ -0,0 +1,477 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PropDialog</class>
+ <widget class="QDialog" name="PropDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>PDF Information</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="titleL">
+ <property name="text">
+ <string>Title:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2">
+ <widget class="QTextEdit" name="titleE">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>256</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>512</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="sizeAdjustPolicy">
+ <enum>QAbstractScrollArea::AdjustToContents</enum>
+ </property>
+ <property name="readOnly">
+ <bool>false</bool>
+ </property>
+ <property name="acceptRichText">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="subjectL">
+ <property name="text">
+ <string>Subject:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2">
+ <widget class="QTextEdit" name="subjectE">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>256</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>512</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="sizeAdjustPolicy">
+ <enum>QAbstractScrollArea::AdjustToContents</enum>
+ </property>
+ <property name="readOnly">
+ <bool>false</bool>
+ </property>
+ <property name="acceptRichText">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="authorL">
+ <property name="text">
+ <string>Author:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" colspan="2">
+ <widget class="QTextEdit" name="authorE">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>256</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>512</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="sizeAdjustPolicy">
+ <enum>QAbstractScrollArea::AdjustToContents</enum>
+ </property>
+ <property name="readOnly">
+ <bool>false</bool>
+ </property>
+ <property name="acceptRichText">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="creatorL">
+ <property name="text">
+ <string>Creator:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" colspan="2">
+ <widget class="QTextEdit" name="creatorE">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>256</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>512</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="sizeAdjustPolicy">
+ <enum>QAbstractScrollArea::AdjustToContents</enum>
+ </property>
+ <property name="readOnly">
+ <bool>false</bool>
+ </property>
+ <property name="acceptRichText">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="producerL">
+ <property name="text">
+ <string>Producer:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" colspan="2">
+ <widget class="QTextEdit" name="producerE">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>256</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>512</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="sizeAdjustPolicy">
+ <enum>QAbstractScrollArea::AdjustToContents</enum>
+ </property>
+ <property name="readOnly">
+ <bool>false</bool>
+ </property>
+ <property name="acceptRichText">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="keywordsL">
+ <property name="text">
+ <string>Keywords:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1" colspan="2">
+ <widget class="QTextEdit" name="keywordE">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>256</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>512</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="sizeAdjustPolicy">
+ <enum>QAbstractScrollArea::AdjustToContents</enum>
+ </property>
+ <property name="readOnly">
+ <bool>false</bool>
+ </property>
+ <property name="acceptRichText">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="createdL">
+ <property name="text">
+ <string>Created: </string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1" colspan="2">
+ <widget class="QTextEdit" name="createdEntry">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>256</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>512</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="sizeAdjustPolicy">
+ <enum>QAbstractScrollArea::AdjustToContents</enum>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="acceptRichText">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="modifiedL">
+ <property name="text">
+ <string>Modified: </string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="1" colspan="2">
+ <widget class="QTextEdit" name="modifiedEntry">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>256</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>512</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="sizeAdjustPolicy">
+ <enum>QAbstractScrollArea::AdjustToContents</enum>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="acceptRichText">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0" colspan="3">
+ <widget class="QLabel" name="versionL">
+ <property name="text">
+ <string>PDF Version:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="0" colspan="3">
+ <widget class="QLabel" name="sizeL">
+ <property name="text">
+ <string>Page Size:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="0" colspan="3">
+ <widget class="QLabel" name="numberL">
+ <property name="text">
+ <string>Number of Pages:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="1">
+ <widget class="QPushButton" name="saveButton">
+ <property name="text">
+ <string>Save</string>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="2">
+ <widget class="QPushButton" name="closeButton">
+ <property name="text">
+ <string>Close</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src-qt5/desktop-utils/lumina-screenshot/lumina-screenshot.pro b/src-qt5/desktop-utils/lumina-screenshot/lumina-screenshot.pro
index d0cce451..f5118db7 100644
--- a/src-qt5/desktop-utils/lumina-screenshot/lumina-screenshot.pro
+++ b/src-qt5/desktop-utils/lumina-screenshot/lumina-screenshot.pro
@@ -90,13 +90,13 @@ TRANSLATIONS = i18n/l-screenshot_af.ts \
i18n/l-screenshot_zu.ts
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
-dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
+dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
desktop.files=lumina-screenshot.desktop
desktop.path=$${L_SHAREDIR}/applications/
manpage.path=$${L_MANDIR}/man1/
-manpage.extra="$${MAN_ZIP} lumina-screenshot.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-screenshot.1.gz"
+manpage.extra="$${MAN_ZIP} $$PWD/lumina-screenshot.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-screenshot.1.gz"
INSTALLS += target desktop manpage
diff --git a/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp b/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp
index 9e4ce499..bdb9d29c 100644
--- a/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp
+++ b/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp
@@ -29,15 +29,26 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){
fontbox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
QWidget *spacer = new QWidget(this);
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ QWidget *spacer2 = new QWidget(this);
+ spacer2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ label_readonly = new QAction(tr("Read-Only File"), this);
+ label_readonly->setEnabled(false); //not an actual button
+ label_readonly->setToolTip("");
+ QFont fnt = this->font();
+ fnt.setItalic(true);
+ fnt.setBold(true);
+ label_readonly->setFont(fnt);
fontSizes = new QSpinBox(this);
fontSizes->setRange(5, 72);
- fontSizes->setValue(9);
+ fontSizes->setValue(this->font().pointSize());
fontSizes->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
//For some reason, the FontComboBox is always 2 pixels taller than the SpinBox - manually fix that here
- fontbox->setFixedHeight(30);
- fontSizes->setFixedHeight(32);
+ fontbox->setFixedHeight(ui->toolBar->iconSize().height()-2);
+ fontSizes->setFixedHeight(ui->toolBar->iconSize().height());
ui->toolBar->addWidget(spacer);
+ ui->toolBar->addAction(label_readonly);
+ ui->toolBar->addWidget(spacer2);
ui->toolBar->addWidget(fontbox);
ui->toolBar->addWidget(fontSizes);
//Load the special Drag and Drop QTabWidget
@@ -72,6 +83,10 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){
for(int i=0; i<smodes.length(); i++){
ui->menuSyntax_Highlighting->addAction(smodes[i]);
}
+
+ bool toolbarVisible = settings->value("showToolbar",true).toBool();
+ ui->toolBar->setHidden(!toolbarVisible);
+ ui->actionShow_Toolbar->setChecked(toolbarVisible);
ui->actionLine_Numbers->setChecked( settings->value("showLineNumbers",true).toBool() );
ui->actionWrap_Lines->setChecked( settings->value("wrapLines",true).toBool() );
ui->actionShow_Popups->setChecked( settings->value("showPopupWarnings",true).toBool() );
@@ -96,6 +111,7 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){
connect(tabWidget->dndTabBar(), SIGNAL(DetachTab(int)), this, SLOT(tabDetached(int)) );
connect(tabWidget->dndTabBar(), SIGNAL(DroppedIn(QStringList)), this, SLOT(LoadArguments(QStringList)) );
connect(tabWidget->dndTabBar(), SIGNAL(DraggedOut(int, Qt::DropAction)), this, SLOT(tabDraggedOut(int, Qt::DropAction)) );
+ connect(ui->actionShow_Toolbar, SIGNAL(toggled(bool)), this, SLOT(showToolbar(bool)) );
connect(ui->actionLine_Numbers, SIGNAL(toggled(bool)), this, SLOT(showLineNumbers(bool)) );
connect(ui->actionWrap_Lines, SIGNAL(toggled(bool)), this, SLOT(wrapLines(bool)) );
connect(ui->actionShow_Popups, SIGNAL(toggled(bool)), this, SLOT(showPopupWarnings(bool)) );
@@ -184,6 +200,17 @@ QString MainUI::currentFileDir(){
return dir;
}
+QStringList MainUI::unsavedFiles(){
+ QStringList unsaved;
+ for(int i=0; i<tabWidget->count(); i++){
+ PlainTextEditor *tmp = static_cast<PlainTextEditor*>(tabWidget->widget(i));
+ if(tmp->hasChange()){
+ unsaved << tmp->currentFile();
+ }
+ }
+ return unsaved;
+}
+
// =================
// PRIVATE SLOTS
//=================
@@ -234,16 +261,27 @@ void MainUI::CloseFile(){
if(index>=0){ tabClosed(index); }
}
-void MainUI::SaveFile(){
+bool MainUI::SaveFile(){
PlainTextEditor *cur = currentEditor();
- if(cur==0){ return; }
- cur->SaveFile();
+ if(cur==0){ return true; } //nothing to do
+ return cur->SaveFile();
}
-void MainUI::SaveFileAs(){
+bool MainUI::SaveFileAs(){
PlainTextEditor *cur = currentEditor();
- if(cur==0){ return; }
- cur->SaveFile(true);
+ if(cur==0){ return true; } //nothing to do
+ return cur->SaveFile(true);
+}
+
+bool MainUI::SaveAllFiles(){
+ bool ok = true;
+ for(int i=0; i<tabWidget->count() && ok; i++){
+ PlainTextEditor *tmp = static_cast<PlainTextEditor*>(tabWidget->widget(i));
+ if(tmp->hasChange()){
+ ok = ok && tmp->SaveFile();
+ }
+ }
+ return ok;
}
void MainUI::Print() {
@@ -337,6 +375,11 @@ void MainUI::showPopupWarnings(bool show){
settings->setValue("showPopupWarnings",show);
}
+void MainUI::showToolbar(bool show){
+ settings->setValue("showToolbar",show);
+ ui->toolBar->setHidden(!show);
+}
+
void MainUI::updateTab(QString file){
PlainTextEditor *cur = 0;
int index = -1;
@@ -356,6 +399,7 @@ void MainUI::updateTab(QString file){
tabWidget->setTabWhatsThis(index, file); //needed for drag/drop functionality
ui->actionSave_File->setEnabled(changes);
this->setWindowTitle( (changes ? "*" : "") + file.section("/",-2) );
+ label_readonly->setVisible( cur->readOnlyFile() );
}
void MainUI::tabChanged(){
@@ -373,6 +417,7 @@ void MainUI::tabChanged(){
fontbox->setCurrentFont(font);
fontSizes->setValue( font.pointSize() );
ui->actionWrap_Lines->setChecked( cur->lineWrapMode()==QPlainTextEdit::WidgetWidth );
+ label_readonly->setVisible( cur->readOnlyFile() );
}
void MainUI::tabClosed(int tab){
@@ -489,21 +534,31 @@ PlainTextEditor *cur = currentEditor();
//=============
void MainUI::closeEvent(QCloseEvent *ev){
//See if any of the open editors have unsaved changes first
- QStringList unsaved;
- for(int i=0; i<tabWidget->count(); i++){
- PlainTextEditor *tmp = static_cast<PlainTextEditor*>(tabWidget->widget(i));
- if(tmp->hasChange()){
- unsaved << tmp->currentFile();
- }
+ QStringList unsaved = unsavedFiles();
+ if(unsaved.isEmpty() || !ui->actionShow_Popups->isChecked()){
+ QMainWindow::closeEvent(ev);
+ return;
+ }
+
+ //Otherwise, ask the user what to do.
+ 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);
+
+ if(but == QMessageBox::Cancel){
+ ev->ignore();
+ return;
}
- if(unsaved.isEmpty()){ QMainWindow::closeEvent(ev); return; }
- bool savenow = false;
- if(!savenow && !ui->actionShow_Popups->isChecked()){ savenow = true; }
- if(!savenow){
- 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; }
+ else if(but == QMessageBox::Yes){
+ if( !SaveAllFiles() ){
+ //cancelled by user
+ ev->ignore();
+ return;
}
- if(savenow){ SaveFile(); }
- QMainWindow::closeEvent(ev);
+
+ }
+ QMainWindow::closeEvent(ev);
}
diff --git a/src-qt5/desktop-utils/lumina-textedit/MainUI.h b/src-qt5/desktop-utils/lumina-textedit/MainUI.h
index 6e5d2d23..464e7a52 100644
--- a/src-qt5/desktop-utils/lumina-textedit/MainUI.h
+++ b/src-qt5/desktop-utils/lumina-textedit/MainUI.h
@@ -13,6 +13,8 @@
#include <QShortcut>
#include <QFontComboBox>
#include <QSpinBox>
+#include <QAction>
+#include <QApplication>
#include "PlainTextEditor.h"
#include "ColorDialog.h"
@@ -40,18 +42,21 @@ private:
QSettings *settings;
QShortcut *closeFindS;
QSpinBox *fontSizes;
+ QAction *label_readonly;
//Simplification functions
PlainTextEditor* currentEditor();
QString currentFileDir();
+ QStringList unsavedFiles();
private slots:
//Main Actions
void NewFile();
void OpenFile(QString file = "");
void CloseFile(); //current file only
- void SaveFile();
- void SaveFileAs();
+ bool SaveFile();
+ bool SaveFileAs();
+ bool SaveAllFiles();
void Print();
void fontChanged(const QFont &font);
void updateStatusTip();
@@ -60,6 +65,7 @@ private slots:
//Other Menu Actions
void UpdateHighlighting(QAction *act = 0);
+ void showToolbar(bool);
void showLineNumbers(bool);
void wrapLines(bool);
void ModifyColors();
diff --git a/src-qt5/desktop-utils/lumina-textedit/MainUI.ui b/src-qt5/desktop-utils/lumina-textedit/MainUI.ui
index 026521b3..f88f3976 100644
--- a/src-qt5/desktop-utils/lumina-textedit/MainUI.ui
+++ b/src-qt5/desktop-utils/lumina-textedit/MainUI.ui
@@ -182,7 +182,7 @@
<x>0</x>
<y>0</y>
<width>505</width>
- <height>28</height>
+ <height>24</height>
</rect>
</property>
<property name="contextMenuPolicy">
@@ -224,6 +224,7 @@
</widget>
<addaction name="menuSyntax_Highlighting"/>
<addaction name="menuTabs_Location"/>
+ <addaction name="actionShow_Toolbar"/>
<addaction name="actionLine_Numbers"/>
<addaction name="actionWrap_Lines"/>
<addaction name="actionShow_Popups"/>
@@ -436,6 +437,17 @@
<string>Ctrl+P</string>
</property>
</action>
+ <action name="actionShow_Toolbar">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Show Toolbar</string>
+ </property>
+ </action>
</widget>
<tabstops>
<tabstop>line_find</tabstop>
diff --git a/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp b/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp
index 653bd0e8..b1592cc3 100644
--- a/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp
+++ b/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.cpp
@@ -24,7 +24,7 @@ PlainTextEditor::PlainTextEditor(QSettings *set, QWidget *parent) : QPlainTextEd
LNW = new LNWidget(this);
showLNW = true;
watcher = new QFileSystemWatcher(this);
- hasChanges = false;
+ hasChanges = readonly = false;
lastSaveContents.clear();
matchleft = matchright = -1;
this->setTabStopWidth( 8 * this->fontMetrics().width(" ") ); //8 character spaces per tab (UNIX standard)
@@ -76,17 +76,22 @@ void PlainTextEditor::LoadFile(QString filepath){
bool diffFile = (filepath != this->whatsThis());
this->setWhatsThis(filepath);
this->clear();
- QList<SyntaxFile> files = SyntaxFile::availableFiles(settings);
+ /*QList<SyntaxFile> files = SyntaxFile::availableFiles(settings);
for(int i=0; i<files.length(); i++){
if(files[i].supportsFile(filepath) ){
files[i].SetupDocument(this);
SYNTAX->loadRules(files[i]);
break;
}
- }
+ }*/
//SYNTAX->loadRules( Custom_Syntax::ruleForFile(filepath.section("/",-1), settings) );
lastSaveContents = LUtils::readFile(filepath).join("\n");
if(diffFile){
+ SYNTAX->loadRules( Custom_Syntax::ruleForFile(this->whatsThis().section("/",-1), settings) );
+ if(SYNTAX->loadedRules().isEmpty()){
+ SYNTAX->loadRules( Custom_Syntax::ruleForFirstLine( lastSaveContents.section("\n",0,0,QString::SectionSkipEmpty) , settings) );
+ }
+ SYNTAX->setupDocument(this);
this->setPlainText( lastSaveContents );
}else{
//Try to keep the mouse cursor/scroll in the same position
@@ -99,18 +104,34 @@ void PlainTextEditor::LoadFile(QString filepath){
this->centerCursor(); //scroll until cursor is centered (if possible)
}
hasChanges = false;
- if(QFile::exists(filepath)){ watcher->addPath(filepath); }
+ readonly = false;
+ if(QFile::exists(filepath)){
+ readonly = !QFileInfo(filepath).isWritable();
+ watcher->addPath(filepath);
+ }else if(filepath.startsWith("/")){
+ //See if the containing directory is writable instead
+ readonly = !QFileInfo(filepath.section("/",0,-2)).isWritable();
+ }
emit FileLoaded(this->whatsThis());
}
-void PlainTextEditor::SaveFile(bool newname){
+bool PlainTextEditor::SaveFile(bool newname){
+ //NOTE: This returns true for proper behaviour, and false for a user-cancelled process
//qDebug() << "Save File:" << this->whatsThis();
+ //Quick check for a non-editable file
+ if(!newname && this->whatsThis().startsWith("/")){
+ if(!QFileInfo(this->whatsThis()).isWritable()){ newname = true; } //cannot save the current file name/location
+ }
if( !this->whatsThis().startsWith("/") || newname ){
//prompt for a filename/path
QString file = QFileDialog::getSaveFileName(this, tr("Save File"), this->whatsThis(), tr("Text File (*)"));
- if(file.isEmpty()){ return; }
+ if(file.isEmpty()){ return false; } //cancelled
this->setWhatsThis(file);
SYNTAX->loadRules( Custom_Syntax::ruleForFile(this->whatsThis().section("/",-1), settings) );
+ if(SYNTAX->loadedRules().isEmpty()){
+ SYNTAX->loadRules( Custom_Syntax::ruleForFirstLine( this->toPlainText().section("\n",0,0,QString::SectionSkipEmpty) , settings) );
+ }
+ SYNTAX->setupDocument(this);
SYNTAX->rehighlight();
}
if( !watcher->files().isEmpty() ){ watcher->removePaths(watcher->files()); }
@@ -118,6 +139,8 @@ void PlainTextEditor::SaveFile(bool newname){
hasChanges = !ok;
if(ok){ lastSaveContents = this->toPlainText(); emit FileLoaded(this->whatsThis()); }
watcher->addPath(currentFile());
+ readonly = !QFileInfo(this->whatsThis()).isWritable(); //update this flag
+ return true;
//qDebug() << " - Success:" << ok << hasChanges;
}
@@ -129,6 +152,11 @@ bool PlainTextEditor::hasChange(){
return hasChanges;
}
+bool PlainTextEditor::readOnlyFile(){
+ //qDebug() << "Read Only File:" << readonly << this->whatsThis();
+ return readonly;
+}
+
//Functions for managing the line number widget
int PlainTextEditor::LNWWidth(){
//Get the number of chars we need for line numbers
diff --git a/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.h b/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.h
index 0c83b7ce..b0a6cbc7 100644
--- a/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.h
+++ b/src-qt5/desktop-utils/lumina-textedit/PlainTextEditor.h
@@ -21,7 +21,7 @@ class PlainTextEditor : public QPlainTextEdit{
public:
PlainTextEditor(QSettings *set, QWidget *parent = 0);
~PlainTextEditor();
-
+
//Functions for setting up the editor
void showLineNumbers(bool show = true);
void LoadSyntaxRule(QString type);
@@ -29,18 +29,19 @@ public:
//File loading/setting options
void LoadFile(QString filepath);
- void SaveFile(bool newname = false);
+ bool SaveFile(bool newname = false);
QString currentFile();
bool hasChange();
+ bool readOnlyFile();
//Functions for managing the line number widget (internal - do not need to run directly)
int LNWWidth(); //replacing the LNW size hint detection
void paintLNW(QPaintEvent *ev); //forwarded from the LNW paint event
- void updateLNW();
+ void updateLNW();
QFontMetrics *metrics;
-
+
private:
QWidget *LNW; //Line Number Widget
bool showLNW;
@@ -55,8 +56,9 @@ private:
void clearMatchData();
void highlightMatch(QChar ch, bool forward, int fromPos, QChar startch);
- //Flags to keep track of changes
- bool hasChanges;
+ //Flags to keep track of changes/status
+ bool hasChanges, readonly;
+
private slots:
//Functions for managing the line number widget
void LNW_updateWidth(); // Tied to the QPlainTextEdit::blockCountChanged() signal
@@ -68,7 +70,7 @@ private slots:
void textChanged();
void cursorMoved();
//Function for prompting the user if the file changed externally
- void fileChanged();
+ void fileChanged();
protected:
void resizeEvent(QResizeEvent *ev);
diff --git a/src-qt5/desktop-utils/lumina-textedit/lumina-textedit.pro b/src-qt5/desktop-utils/lumina-textedit/lumina-textedit.pro
index a9c16a0c..77cd8798 100644
--- a/src-qt5/desktop-utils/lumina-textedit/lumina-textedit.pro
+++ b/src-qt5/desktop-utils/lumina-textedit/lumina-textedit.pro
@@ -91,7 +91,7 @@ TRANSLATIONS = i18n/l-te_af.ts \
i18n/l-te_zu.ts
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
-dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
+dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
desktop.files=lumina-textedit.desktop
desktop.path=$${L_SHAREDIR}/applications/
@@ -103,7 +103,7 @@ syntax.path=$${L_SHAREDIR}/lumina-desktop/syntax_rules
syntax.files=syntax_rules/*
manpage.path=$${L_MANDIR}/man1/
-manpage.extra="$${MAN_ZIP} lumina-textedit.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-textedit.1.gz"
+manpage.extra="$${MAN_ZIP} $$PWD/lumina-textedit.1 > $(INSTALL_ROOT)$${L_MANDIR}/man1/lumina-textedit.1.gz"
INSTALLS += target desktop link syntax manpage
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp b/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp
index 53f51f4e..a80d4149 100644
--- a/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp
+++ b/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.cpp
@@ -83,6 +83,16 @@ bool SyntaxFile::supportsFile(QString file){
return false;
}
+bool SyntaxFile::supportsFirstLine(QString line){
+ line = line.simplified();
+ if(metaObj.contains("first_line_match")){
+ return metaObj.value("first_line_match").toArray().contains(line);
+ }else if(metaObj.contains("first_line_regex")){
+ return (QRegExp( metaObj.value("first_line_regex").toString() ).indexIn(line) >=0 );
+ }
+ return false;
+}
+
bool SyntaxFile::LoadFile(QString file, QSettings *settings){
QStringList contents = LUtils::readFile(file);
//Now trim the extra non-JSON off the beginning of the file
@@ -209,6 +219,13 @@ QString Custom_Syntax::ruleForFile(QString filename, QSettings *settings){
return "";
}
+QString Custom_Syntax::ruleForFirstLine(QString line, QSettings *settings){
+ QList<SyntaxFile> files = SyntaxFile::availableFiles(settings);
+ for(int i=0; i<files.length(); i++){
+ if(files[i].supportsFirstLine(line)){ return files[i].name(); }
+ }
+ return "";
+}
void Custom_Syntax::loadRules(QString type){
QList<SyntaxFile> files = SyntaxFile::availableFiles(settings);
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h b/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h
index bffbfd1a..9949a90c 100644
--- a/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h
+++ b/src-qt5/desktop-utils/lumina-textedit/syntaxSupport.h
@@ -46,6 +46,7 @@ public:
void SetupDocument(QPlainTextEdit *editor);
bool supportsFile(QString file); //does this syntax set support the file?
+ bool supportsFirstLine(QString line); //is the type of file defined by the first line of the file? ("#!/bin/<something>" for instance)
//Main Loading routine (run this before other functions)
bool LoadFile(QString file, QSettings *settings);
@@ -66,10 +67,13 @@ public:
}
~Custom_Syntax(){}
+ QString loadedRules(){ return syntax.name(); }
+
static QStringList availableRules(QSettings *settings);
static QStringList knownColors();
static void SetupDefaultColors(QSettings *settings);
static QString ruleForFile(QString filename, QSettings *settings);
+ static QString ruleForFirstLine(QString line, QSettings *settings);
void loadRules(QString type);
void loadRules(SyntaxFile sfile);
@@ -77,6 +81,8 @@ public:
loadRules( syntax.name() );
}
+ void setupDocument(QPlainTextEdit *edit){ syntax.SetupDocument(edit); } //simple redirect for the function in the currently-loaded rules
+
protected:
void highlightBlock(const QString &text){
//qDebug() << "Highlight Block:" << text;
@@ -159,7 +165,7 @@ protected:
int last = text.length()-1;
while(last>=0 && (text[last]==' ' || text[last]=='\t' ) ){ last--; }
if(last < text.length()-1){
- setFormat(last+1, text.length()-1-last, fmt);
+ setFormat(last+1, text.length()-1-last, fmt);
}
}
}
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/README.md b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/README.md
index fa00b557..04190672 100644
--- a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/README.md
+++ b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/README.md
@@ -9,9 +9,11 @@ A small comment section may be placed at the top of the file where every line st
# Requirements
1. A "meta" object containing the following variables (meta information about the rules):
1. "name" : The name that will be shown to the user for this set of syntax rules.
- 2. If this syntax file is to be automatically applied to particular file type, then one of the following options must be set:
+ 2. If this syntax file is to be automatically applied to particular file type, then at least one of the following options must be set:
1. "file_suffix" : An array of file extensions which are supported by this syntax rule set (Example: temp.foo will be matched by "file_suffix"=["foo"] )
2. "file_regex" : A regular expression which should be used to find if the filename matches this rule set.
+ 3. "first_line_match" : *(only used if no filename rules matched)* Exact match for the first line of text in the file (Example: "#!/bin/sh")
+ 4. "first_line_regex" : *(only used if no filename rules matched)* Regular expression to use when find a match for the first line of text in the file
2. A "format" object containing the following variables (file-wide formatting):
1. "columns_per_line" : (integer, optional) For file formats with line-length restrictions, this will automatically highlight/flag any "overage" of the designated limit.
2. "highlight_whitespace_eol" : (boolian, optional) Highlight any excess whitespace at the end of a line.
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/json.syntax b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/json.syntax
index ab67d384..1982e599 100644
--- a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/json.syntax
+++ b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/json.syntax
@@ -8,7 +8,8 @@
{
"meta": {
"name": "JSON",
- "file_suffix": ["json", "syntax"]
+ "file_suffix": ["json", "syntax"],
+ "first_line_match":["{"]
},
"format": {
"line_wrap": false,
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/python.syntax b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/python.syntax
index 6690d98c..2145beec 100644
--- a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/python.syntax
+++ b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/python.syntax
@@ -8,7 +8,8 @@
{
"meta": {
"name": "Python",
- "file_suffix": ["py", "pyc"]
+ "file_suffix": ["py", "pyc"],
+ "first_line_regex" : "(#!).+(python)"
},
"format": {
"line_wrap": false,
diff --git a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/sh.syntax b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/sh.syntax
index 5f38cadc..f2256731 100644
--- a/src-qt5/desktop-utils/lumina-textedit/syntax_rules/sh.syntax
+++ b/src-qt5/desktop-utils/lumina-textedit/syntax_rules/sh.syntax
@@ -8,7 +8,8 @@
{
"meta": {
"name": "Shell",
- "file_suffix": ["sh"]
+ "file_suffix": ["sh"],
+ "first_line_match":["#!/bin/sh", "#!/sbin/openrc-run"]
},
"format": {
"line_wrap": false,
diff --git a/src-qt5/experimental/lumina-screencast/lumina-screencast.pro b/src-qt5/experimental/lumina-screencast/lumina-screencast.pro
index 5cfe89ef..5c6a1e76 100644
--- a/src-qt5/experimental/lumina-screencast/lumina-screencast.pro
+++ b/src-qt5/experimental/lumina-screencast/lumina-screencast.pro
@@ -87,7 +87,7 @@ TRANSLATIONS = i18n/l-screencast_af.ts \
i18n/l-screencast_zu.ts
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
-dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
+dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
desktop.files=lumina-screencast.desktop
desktop.path=$${L_SHAREDIR}/applications/
diff --git a/src-qt5/experimental/lumina-terminal/lumina-terminal.pro b/src-qt5/experimental/lumina-terminal/lumina-terminal.pro
index 7f5d979c..668a8741 100644
--- a/src-qt5/experimental/lumina-terminal/lumina-terminal.pro
+++ b/src-qt5/experimental/lumina-terminal/lumina-terminal.pro
@@ -91,7 +91,7 @@ TRANSLATIONS = i18n/l-terminal_af.ts \
i18n/l-terminal_zu.ts
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
-dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
+dotrans.extra=cd $$PWD/i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
desktop.files=lumina-terminal.desktop
desktop.path=$${L_SHAREDIR}/applications/
diff --git a/src-qt5/src-cpp/framework-OSInterface-template.cpp b/src-qt5/src-cpp/framework-OSInterface-template.cpp
new file mode 100644
index 00000000..972e02e0
--- /dev/null
+++ b/src-qt5/src-cpp/framework-OSInterface-template.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 <framework-OSInterface.h>
+#include <QNetworkConfiguration>
+#include <QNetworkInterface>
+
+//Start/stop interface watchers/notifications
+void OSInterface::start(){
+ setupMediaWatcher(); //will create/connect the filesystem watcher automatically
+ setupNetworkManager();
+}
+
+void OSInterface::stop(){
+ if(isRunning()){
+ watcher->deleteLater();
+ watcher = 0;
+ }
+}
+
+bool OSInterface::isRunning(){ return (watcher!=0); } //status of the object - whether it has been started yet
+
+// = Battery =
+bool OSInterface::batteryAvailable(){ return false; }
+float OSInterface::batteryCharge(){ return -1; }
+bool OSInterface::batteryCharging(){ return false; }
+double OSInterface::batterySecondsLeft(){ return -1; }
+
+// = Volume =
+bool OSInterface::volumeAvailable(){ return false; }
+int OSInterface::volume(){ return -1; }
+void OSInterface::setVolume(int){}
+
+// = Network Information =
+bool OSInterface::networkAvailable(){
+ if(INFO.contains("netaccess/available")){ return INFO.value("netaccess/available").toBool(); }
+ return false;
+}
+
+QString OSInterface::networkType(){
+ if(INFO.contains("netaccess/type")){ return INFO.value("netaccess/type").toString(); } //"wifi", "wired", or "cell"
+ return "";
+}
+
+float OSInterface::networkStrength(){ return -1; } //percentage. ("wired" type should always be 100%)
+
+QString OSInterface::networkHostname(){
+ return QHostInfo::localHostName();
+}
+
+QHostAddress OSInterface::networkAddress(){
+ QString addr;
+ if(INFO.contains("netaccess/address")){ addr = INFO.value("netaccess/address").toString(); }
+ return QHostAddress(addr);
+}
+// = Network Modification =
+
+// = Media Shortcuts =
+QStringList OSInterface::mediaDirectories(){ return QStringList() << "/media"; } //directory where XDG shortcuts are placed for interacting with media (local/remote)
+QStringList OSInterface::mediaShortcuts(){ return autoHandledMediaFiles(); } //List of currently-available XDG shortcut file paths
+
+// = Updates =
+bool OSInterface::updatesAvailable(){ return false; }
+QString OSInterface::updateDetails(){ return QString(); } //Information about any available updates
+bool OSInterface::updatesRunning(){ return false; }
+QString OSInterface::updateLog(){ return QString(); } //Information about any currently-running update
+bool OSInterface::updatesFinished(){ return false; }
+QString OSInterface::updateResults(){ return QString(); } //Information about any finished update
+void OSInterface::startUpdates(){}
+bool OSInterface::updateOnlyOnReboot(){ return false; } //Should the startUpdates function be called only when rebooting the system?
+QDateTime OSInterface::lastUpdate(){ return QDateTime(); } //The date/time of the previous updates
+QString OSInterface::lastUpdateResults(){ return QString(); } //Information about the previously-finished update
+
+// = System Power =
+bool OSInterface::canReboot(){ return false; }
+void OSInterface::startReboot(){}
+bool OSInterface::canShutdown(){ return false; }
+void OSInterface::startShutdown(){}
+bool OSInterface::canSuspend(){ return false; }
+void OSInterface::startSuspend(){}
+
+// = Screen Brightness =
+int OSInterface::brightness(){ return -1; } //percentage: 0-100 with -1 for errors
+void OSInterface::setBrightness(int){}
+
+// = System Status Monitoring
+QList<int> OSInterface::cpuPercentage(){ return QList<int>(); } // (one per CPU) percentage: 0-100 with empty list for errors
+QStringList OSInterface::cpuTemperatures(){ return QStringList(); } // (one per CPU) Temperature of CPU ("50C" for example)
+int OSInterface::memoryUsedPercentage(){ return -1; } //percentage: 0-100 with -1 for errors
+QString OSInterface::memoryTotal(){ return QString(); } //human-readable form - does not tend to change within a session
+QStringList OSInterface::diskIO(){ return QStringList(); } //Returns list of current read/write stats for each device
+int OSInterface::fileSystemPercentage(QString dir){ return -1; } //percentage of capacity used: 0-100 with -1 for errors
+QString OSInterface::fileSystemCapacity(QString dir){ return QString(); } //human-readable form - total capacity
+
+// = OS-Specific Utilities =
+bool OSInterface::hasControlPanel(){ return false; }
+QString OSInterface::controlPanelShortcut(){ return QString(); } //relative *.desktop shortcut name (Example: "some_utility.desktop")
+bool OSInterface::hasAudioMixer(){ return false; }
+QString OSInterface::audioMixerShortcut(){ return QString(); } //relative *.desktop shortcut name (Example: "some_utility.desktop")
+bool OSInterface::hasAppStore(){ return false; }
+QString OSInterface::appStoreShortcut(){ return QString(); } //relative *.desktop shortcut name (Example: "some_utility.desktop")
+
+//FileSystemWatcher slots
+void OSInterface::watcherFileChanged(QString){}
+void OSInterface::watcherDirChanged(QString dir){
+ if(handleMediaDirChange(dir)){ return; }
+}
+
+//IO Device slots
+void OSInterface::iodeviceReadyRead(){}
+void OSInterface::iodeviceAboutToClose(){}
+
+//NetworkAccessManager slots
+void OSInterface::netAccessChanged(QNetworkAccessManager::NetworkAccessibility stat){
+ INFO.insert("netaccess/available", stat== QNetworkAccessManager::Accessible);
+ //Update all the other network status info at the same time
+ QNetworkConfiguration active = netman->activeConfiguration();
+ //Type of connection
+ QString type;
+ switch(active.bearerTypeFamily()){
+ case QNetworkConfiguration::BearerEthernet: type="wired"; break;
+ case QNetworkConfiguration::BearerWLAN: type="wifi"; break;
+ case QNetworkConfiguration::Bearer2G: type="cell-2G"; break;
+ case QNetworkConfiguration::Bearer3G: type="cell-3G"; break;
+ case QNetworkConfiguration::Bearer4G: type="cell-4G"; break;
+ default: type="";
+ }
+ INFO.insert("netaccess/type", type);
+ qDebug() << "Detected Device Status:" << active.identifier() << type << stat;
+ QNetworkInterface iface = QNetworkInterface::interfaceFromName(active.name());
+ qDebug() << " - Configuration: Name:" << active.name() << active.bearerTypeName() << active.identifier();
+ qDebug() << " - Interface: MAC Address:" << iface.hardwareAddress() << "Name:" << iface.name() << iface.humanReadableName() << iface.isValid();
+ QList<QNetworkAddressEntry> addressList = iface.addressEntries();
+ QStringList address;
+ //NOTE: There are often 2 addresses, IPv4 and IPv6
+ for(int i=0; i<addressList.length(); i++){
+ address << addressList[i].ip().toString();
+ }
+ qDebug() << " - IP Address:" << address;
+ qDebug() << " - Hostname:" << networkHostname();
+ INFO.insert("netaccess/address", address.join(", "));
+ emit networkStatusChanged();
+}
+
+void OSInterface::netRequestFinished(QNetworkReply*){}
+void OSInterface::netSslErrors(QNetworkReply*, const QList<QSslError>&){}
+void OSInterface::timerUpdate(){}
diff --git a/src-qt5/src-cpp/framework-OSInterface.h b/src-qt5/src-cpp/framework-OSInterface.h
new file mode 100644
index 00000000..a173ad5a
--- /dev/null
+++ b/src-qt5/src-cpp/framework-OSInterface.h
@@ -0,0 +1,190 @@
+//===========================================
+// 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 main interface for any OS-specific system calls
+// To port Lumina to a different operating system, just create a file
+// called "OSInterface-<Operating System>.cpp"
+//===========================================
+#ifndef _LUMINA_LIBRARY_OS_INTERFACE_H
+#define _LUMINA_LIBRARY_OS_INTERFACE_H
+
+#include <QString>
+#include <QStringList>
+#include <QList>
+#include <QObject>
+#include <QVariant>
+#include <QHash>
+#include <QTimer>
+
+#include <QIODevice>
+#include <QFileSystemWatcher>
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+#include <QSslError>
+#include <QHostInfo>
+#include <QHostAddress>
+
+class OSInterface : public QObject{
+ Q_OBJECT
+ // == QML ACCESSIBLE PROPERTIES ==
+ //Battery
+ Q_PROPERTY( float batteryCharge READ batteryCharge NOTIFY batteryChargeChanged)
+ Q_PROPERTY( bool batteryCharging READ batteryCharging NOTIFY batteryChargingChanged)
+ Q_PROPERTY( double batterySecondsLeft READ batterySecondsLeft NOTIFY batterySecondsLeftChanged)
+ //Volume
+ Q_PROPERTY( int volume READ volume WRITE setVolume NOTIFY volumeChanged)
+ //Network
+ Q_PROPERTY( bool networkAvailable READ networkAvailable NOTIFY networkStatusChanged)
+ Q_PROPERTY( QString networkType READ networkType NOTIFY networkStatusChanged)
+ Q_PROPERTY( float networkStrength READ networkStrength NOTIFY networkStatusChanged)
+ Q_PROPERTY( QString networkHostname READ networkHostname NOTIFY networkStatusChanged)
+ Q_PROPERTY( QHostAddress networkAddress READ networkAddress NOTIFY networkStatusChanged)
+ //Media
+ Q_PROPERTY( QStringList mediaShortcuts READ mediaShortcuts NOTIFY mediaShortcutsChanged)
+ //Updates
+ Q_PROPERTY( bool updatesAvailable READ updatesAvailable NOTIFY updateStatusChanged)
+ Q_PROPERTY( bool updatesRunning READ updatesRunning NOTIFY updateStatusChanged)
+ Q_PROPERTY( bool updatesFinished READ updatesFinished NOTIFY updateStatusChanged)
+ //Power options
+ Q_PROPERTY( bool canReboot READ canReboot NOTIFY powerAvailableChanged)
+ Q_PROPERTY( bool canShutdown READ canShutdown NOTIFY powerAvailableChanged)
+ Q_PROPERTY( bool canSuspend READ canSuspend NOTIFY powerAvailableChanged)
+ //Brightness
+ Q_PROPERTY( int brightness READ brightness WRITE setBrightness NOTIFY brightnessChanged)
+
+public:
+ // ================
+ // SEMI-VIRTUAL FUNCTIONS - NEED TO BE DEFINED IN THE OS-SPECIFIC FILES
+ // ================
+ //Start/stop interface watchers/notifications
+ void start();
+ void stop();
+ bool isRunning(); //status of the object - whether it has been started yet
+
+ // = Battery =
+ Q_INVOKABLE bool batteryAvailable();
+ Q_INVOKABLE float batteryCharge();
+ Q_INVOKABLE bool batteryCharging();
+ Q_INVOKABLE double batterySecondsLeft();
+ // = Volume =
+ Q_INVOKABLE bool volumeAvailable();
+ Q_INVOKABLE int volume();
+ Q_INVOKABLE void setVolume(int);
+ // = Network Information =
+ Q_INVOKABLE bool networkAvailable();
+ Q_INVOKABLE QString networkType(); //"wifi", "wired", "cell", "cell-2G", "cell-3G", "cell-4G"
+ Q_INVOKABLE float networkStrength(); //percentage. ("wired" type should always be 100%)
+ Q_INVOKABLE QString networkHostname();
+ Q_INVOKABLE QHostAddress networkAddress();
+ // = Network Modification =
+
+ // = Media Shortcuts =
+ Q_INVOKABLE QStringList mediaDirectories(); //directory where XDG shortcuts are placed for interacting with media (local/remote)
+ Q_INVOKABLE QStringList mediaShortcuts(); //List of currently-available XDG shortcut file paths
+ // = Updates =
+ Q_INVOKABLE bool updatesAvailable();
+ Q_INVOKABLE QString updateDetails(); //Information about any available updates
+ Q_INVOKABLE bool updatesRunning();
+ Q_INVOKABLE QString updateLog(); //Information about any currently-running update
+ Q_INVOKABLE bool updatesFinished();
+ Q_INVOKABLE QString updateResults(); //Information about any finished update
+ Q_INVOKABLE void startUpdates();
+ Q_INVOKABLE bool updateOnlyOnReboot(); //Should the startUpdates function be called only when rebooting the system?
+ Q_INVOKABLE QDateTime lastUpdate(); //The date/time of the previous updates
+ Q_INVOKABLE QString lastUpdateResults(); //Information about the previously-finished update
+ // = System Power =
+ Q_INVOKABLE bool canReboot();
+ Q_INVOKABLE void startReboot();
+ Q_INVOKABLE bool canShutdown();
+ Q_INVOKABLE void startShutdown();
+ Q_INVOKABLE bool canSuspend();
+ Q_INVOKABLE void startSuspend();
+ // = Screen Brightness =
+ Q_INVOKABLE int brightness(); //percentage: 0-100 with -1 for errors
+ Q_INVOKABLE void setBrightness(int);
+ // = System Status Monitoring
+ Q_INVOKABLE QList<int> cpuPercentage(); // (one per CPU) percentage: 0-100 with -1 for errors
+ Q_INVOKABLE QStringList cpuTemperatures(); // (one per CPU) Temperature of CPU ("50C" for example)
+ Q_INVOKABLE int memoryUsedPercentage(); //percentage: 0-100 with -1 for errors
+ Q_INVOKABLE QString memoryTotal(); //human-readable form - does not tend to change within a session
+ Q_INVOKABLE QStringList diskIO(); //Returns list of current read/write stats for each device
+ Q_INVOKABLE int fileSystemPercentage(QString dir); //percentage of capacity used: 0-100 with -1 for errors
+ Q_INVOKABLE QString fileSystemCapacity(QString dir); //human-readable form - total capacity
+ // = OS-Specific Utilities =
+ Q_INVOKABLE bool hasControlPanel();
+ Q_INVOKABLE QString controlPanelShortcut(); //relative *.desktop shortcut name (Example: "some_utility.desktop")
+ Q_INVOKABLE bool hasAudioMixer();
+ Q_INVOKABLE QString audioMixerShortcut(); //relative *.desktop shortcut name (Example: "some_utility.desktop")
+ Q_INVOKABLE bool hasAppStore();
+ Q_INVOKABLE QString appStoreShortcut(); //relative *.desktop shortcut name (Example: "some_utility.desktop")
+
+private slots:
+ // ================
+ // SEMI-VIRTUAL FUNCTIONS - NEED TO BE DEFINED IN THE OS-SPECIFIC FILES
+ // ================
+ //FileSystemWatcher slots
+ void watcherFileChanged(QString);
+ void watcherDirChanged(QString);
+ //IO Device slots
+ void iodeviceReadyRead();
+ void iodeviceAboutToClose();
+ //NetworkAccessManager slots
+ void netAccessChanged(QNetworkAccessManager::NetworkAccessibility);
+ void netRequestFinished(QNetworkReply*);
+ void netSslErrors(QNetworkReply*, const QList<QSslError>&);
+ //Timer slots
+ void timerUpdate();
+
+signals:
+ void batteryChargeChanged();
+ void batteryChargingChanged();
+ void batterySecondsLeftChanged();
+ void volumeChanged();
+ void networkStatusChanged();
+ void mediaShortcutsChanged();
+ void updateStatusChanged();
+ void powerAvailableChanged();
+ void brightnessChanged();
+
+private:
+ //Internal persistant data storage, OS-specific usage implementation
+ QHash< QString, QVariant> INFO;
+
+ // ============
+ // Internal possibilities for watching the system (OS-Specific usage/implementation)
+ // ============
+ //File System Watcher
+ QFileSystemWatcher *watcher;
+ //IO Device (QLocalSocket, QTcpConnection, QFile, etc)
+ QIODevice *iodevice;
+ //Network Access Manager (check network connectivity, etc)
+ QNetworkAccessManager *netman;
+ //Timer for regular probes/updates
+ QTimer *timer;
+
+ // Internal implifications for connecting the various watcher objects to their respective slots
+ // (OS-agnostic - defined in the "OSInterface_private.cpp" file)
+ void connectWatcher(); //setup the internal connections *only*
+ void connectIodevice(); //setup the internal connections *only*
+ void connectNetman(); //setup the internal connections *only*
+ void connectTimer(); //setup the internal connections *only*
+
+ // External Media Management (if system uses *.desktop shortcuts only)
+ void setupMediaWatcher();
+ bool handleMediaDirChange(QString dir); //returns true if directory was handled
+ QStringList autoHandledMediaFiles();
+
+ // Qt-based NetworkAccessManager usage
+ void setupNetworkManager();
+
+public:
+ OSInterface(QObject *parent = 0);
+ ~OSInterface();
+
+ static OSInterface* instance(); //Get the currently-active instance of this class (or make a new one)
+
+};
+#endif
diff --git a/src-qt5/src-cpp/framework-OSInterface.pri b/src-qt5/src-cpp/framework-OSInterface.pri
new file mode 100644
index 00000000..be705e44
--- /dev/null
+++ b/src-qt5/src-cpp/framework-OSInterface.pri
@@ -0,0 +1,9 @@
+QT *= core network
+
+HEADERS *= $${PWD}/framework-OSInterface.h
+SOURCES *= $${PWD}/framework-OSInterface_private.cpp
+
+_os=template
+SOURCES *= $${PWD}/framework-OSInterface-$${_os}.cpp
+
+INCLUDEPATH *= $${PWD}
diff --git a/src-qt5/src-cpp/framework-OSInterface_private.cpp b/src-qt5/src-cpp/framework-OSInterface_private.cpp
new file mode 100644
index 00000000..d15d9be8
--- /dev/null
+++ b/src-qt5/src-cpp/framework-OSInterface_private.cpp
@@ -0,0 +1,110 @@
+//===========================================
+// Lumina desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+// Internal, OS-agnostic functionality for managing the object itself
+//===========================================
+#include <framework-OSInterface.h>
+#include <QFile>
+#include <QDir>
+#include <QVariant>
+
+OSInterface::OSInterface(QObject *parent) : QObject(parent){
+ watcher = 0;
+ iodevice = 0;
+ netman = 0;
+}
+
+OSInterface::~OSInterface(){
+ if(watcher!=0){
+ QStringList paths; paths << watcher->files() << watcher->directories();
+ if(!paths.isEmpty()){ watcher->removePaths(paths); }
+ watcher->deleteLater();
+ }
+ if(iodevice!=0){
+ if(iodevice->isOpen()){ iodevice->close(); }
+ iodevice->deleteLater();
+ }
+ if(netman!=0){
+ netman->deleteLater();
+ }
+}
+
+OSInterface* OSInterface::instance(){
+ static OSInterface* m_os_object = 0;
+ if(m_os_object==0){
+ m_os_object = new OSInterface();
+ }
+ return m_os_object;
+}
+
+void OSInterface::connectWatcher(){
+ if(watcher==0){ return; }
+ connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(watcherFileChanged(QString)) );
+ connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(watcherDirChanged(QString)) );
+}
+
+void OSInterface::connectIodevice(){
+ if(iodevice==0){ return; }
+ connect(iodevice, SIGNAL(readyRead()), this, SLOT(iodeviceReadyRead()) );
+}
+
+void OSInterface::connectNetman(){
+ if(netman==0){ return; }
+ connect(netman, SIGNAL(networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility)), this, SLOT(netAccessChanged(QNetworkAccessManager::NetworkAccessibility)) );
+ connect(netman, SIGNAL(finished(QNetworkReply*)), this, SLOT(netRequestFinished(QNetworkReply*)) );
+ connect(netman, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>&)), this, SLOT(netSslErrors(QNetworkReply*, const QList<QSslError>&)) );
+}
+
+void OSInterface::connectTimer(){
+ if(timer==0){ return; }
+ connect(timer, SIGNAL(timeout()), this, SLOT(timerUpdate()) );
+}
+
+// External Media Management (if system uses *.desktop shortcuts)
+void OSInterface::setupMediaWatcher(){
+ //Create/connect the watcher if needed
+ if(watcher == 0){ watcher = new QFileSystemWatcher(); connectWatcher(); }
+ QStringList dirs = this->mediaDirectories();
+ if(dirs.isEmpty()){ return; } //nothing to do
+ //Make sure each directory is scanned **right now** (if it exists)
+ for(int i=0; i<dirs.length(); i++){
+ if(QFile::exists(dirs[i])){
+ handleMediaDirChange(dirs[i]);
+ }
+ }
+}
+
+bool OSInterface::handleMediaDirChange(QString dir){ //returns true if directory was handled
+ if( !this->mediaDirectories().contains(dir) ){ return false; } //not a media directory
+ QDir qdir(dir);
+ QStringList files = qdir.entryList(QStringList() << "*.desktop", QDir::Files, QDir::Name);
+ for(int i=0; i<files.length(); i++){ files[i] = qdir.absoluteFilePath(files[i]); }
+ QString key = "media_files/"+dir;
+ if(files.isEmpty() && INFO.contains(key)){ INFO.remove(key); emit mediaShortcutsChanged(); } //no files for this directory at the moment
+ else{ INFO.insert("media_files/"+dir, files); emit mediaShortcutsChanged(); } //save these file paths for later
+ //Make sure the directory is still watched (sometimes the dir is removed/recreated on modification)
+ if(!watcher->directories().contains(dir)){ watcher->addPath(dir); }
+ return true;
+}
+
+QStringList OSInterface::autoHandledMediaFiles(){
+ QStringList files;
+ QStringList keys = INFO.keys().filter("media_files/");
+ for(int i=0; i<keys.length(); i++){
+ if(keys[i].startsWith("media_files/")){ files << INFO[keys[i]].toStringList(); }
+ }
+ return files;
+}
+
+// Qt-based NetworkAccessManager usage
+void OSInterface::setupNetworkManager(){
+ if(netman==0){
+ netman = new QNetworkAccessManager(this);
+ connectNetman();
+ }
+ //Load the initial state of the network accessibility
+ netAccessChanged(netman->networkAccessible());
+}
diff --git a/src-qt5/src-cpp/plugins-base.cpp b/src-qt5/src-cpp/plugins-base.cpp
new file mode 100644
index 00000000..f38374df
--- /dev/null
+++ b/src-qt5/src-cpp/plugins-base.cpp
@@ -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
+//===========================================
+#include "plugins-base.h"
+
+// ============
+// Base PLUGIN
+// ============
+BasePlugin::BasePlugin(){
+
+}
+
+BasePlugin::~BasePlugin(){
+
+}
+
+void BasePlugin::loadFile(QString path){
+ data = QJsonObject();
+ currentfile = path;
+ QFile file(path);
+ if(!file.exists() || !file.open(QIODevice::ReadOnly)){ return; }
+ data = QJsonDocument::fromJson(file.readAll()).object();
+ //qDebug() << "Loaded ScreenSaver Data:" << currentfile << data;
+ file.close();
+}
+
+QString BasePlugin::translatedObject(QString obj){
+ QJsonObject tmp = data.value(obj).toObject();
+ //Get the current locale
+ QString locale = getenv("LC_ALL");
+ if(locale.isEmpty()){ locale = getenv("LC_MEBaseAGES"); }
+ 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 BasePlugin::scriptURL(){
+ QString exec = data.value("qml").toObject().value("exec").toString();
+ if(!exec.startsWith("/")){ exec.prepend( currentfile.section("/",0,-2)+"/" ); }
+ return QUrl::fromLocalFile(exec);
+}
+
diff --git a/src-qt5/src-cpp/plugins-base.h b/src-qt5/src-cpp/plugins-base.h
new file mode 100644
index 00000000..26b0eacc
--- /dev/null
+++ b/src-qt5/src-cpp/plugins-base.h
@@ -0,0 +1,107 @@
+//===========================================
+// 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_BASE_PLUGINS_CLASS_H
+#define _LUMINA_DESKTOP_BASE_PLUGINS_CLASS_H
+
+#include <QJsonObject>
+#include <QString>
+#include <QUrl>
+#include <QObject>
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QFile>
+#include <QDir>
+#include <QDebug>
+
+class BasePlugin{
+protected:
+ QString currentfile;
+
+public:
+ BasePlugin();
+ virtual ~BasePlugin();
+
+ virtual void loadFile(QString path);
+ bool isLoaded() { return !data.isEmpty(); };
+ bool containsDefault(QString obj) { return data.value(obj).toObject().contains("default"); }
+
+ /**
+ * Check if the plugin is valid as long as the JSON is not empty,
+ * it contains at least a "name", "qml", and "description" object,
+ * and the "name" and "description" objects contain a "default" key.
+ **/
+ virtual bool isValid() = 0;
+
+ virtual QString translatedObject(QString obj);
+ virtual QUrl scriptURL();
+
+ QJsonObject data; //Hazardous to manually modify
+ QString relDir;
+};
+
+class PluginSystem{
+public:
+ template <class T>
+ static T findPlugin(QString, QString);
+
+ template <class T>
+ static QList<T> findAllPlugins(QString, bool validonly=true);
+};
+
+// ===================
+// Base PLUGIN SYSTEM
+// ===================
+template <class T>
+T PluginSystem::findPlugin(QString name, QString REL_DIR){
+ //qDebug() << "FindPlugin:" << name;
+ T BaseP;
+ if(name.startsWith("/") && QFile::exists(name)){ BaseP.loadFile(name); return BaseP;} //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; }
+ BaseP.loadFile(dirs[i]+REL_DIR+"/"+name);
+ if(BaseP.isValid()){ break; } //got a good one - stop here
+ }
+ return BaseP;
+}
+
+template <class T>
+QList<T> PluginSystem::findAllPlugins(QString REL_DIR, bool validonly) {
+ QList<T> 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++){
+ T tmp;
+ tmp.loadFile(dir.absoluteFilePath(files[j]));
+ //qDebug() << "Loaded File:" << files[j] << tmp.isValid();
+ if(!validonly || tmp.isValid()){ LIST << tmp; }
+ }
+ }
+ return LIST;
+}
+#endif
diff --git a/src-qt5/src-cpp/plugins-base.pri b/src-qt5/src-cpp/plugins-base.pri
new file mode 100644
index 00000000..4aa9d96e
--- /dev/null
+++ b/src-qt5/src-cpp/plugins-base.pri
@@ -0,0 +1,8 @@
+HEADERS *= $${PWD}/plugins-base.h \
+ $${PWD}/plugins-screensaver.h \
+ $${PWD}/plugins-desktop.h
+SOURCES *= $${PWD}/plugins-base.cpp \
+ $${PWD}/plugins-screensaver.cpp \
+ $${PWD}/plugins-desktop.cpp
+
+INCLUDEPATH *= $${PWD}
diff --git a/src-qt5/src-cpp/plugins-desktop.cpp b/src-qt5/src-cpp/plugins-desktop.cpp
new file mode 100644
index 00000000..fdbd676d
--- /dev/null
+++ b/src-qt5/src-cpp/plugins-desktop.cpp
@@ -0,0 +1,40 @@
+//===========================================
+// 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-desktop.h"
+
+// ============
+// DT PLUGIN
+// ============
+DTPlugin::DTPlugin(){
+
+}
+
+DTPlugin::~DTPlugin(){
+
+}
+
+bool DTPlugin::isValid(){
+ if(data.isEmpty()){ return false; }
+ bool ok = data.contains("name") && data.contains("qml") && data.contains("description");
+ ok &= containsDefault("name");
+ ok &= containsDefault("description");
+ if(ok) {
+ 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) + "/";
+ 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;
+}
diff --git a/src-qt5/src-cpp/plugins-desktop.h b/src-qt5/src-cpp/plugins-desktop.h
new file mode 100644
index 00000000..ed576db1
--- /dev/null
+++ b/src-qt5/src-cpp/plugins-desktop.h
@@ -0,0 +1,29 @@
+//===========================================
+// 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_DESKTOP_PLUGINS_CLASS_H
+#define _LUMINA_DESKTOP_DESKTOP_PLUGINS_CLASS_H
+
+#include "plugins-base.h"
+#include <QJsonObject>
+#include <QString>
+#include <QUrl>
+#include <QObject>
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QFile>
+#include <QDir>
+#include <QDebug>
+
+class DTPlugin : public BasePlugin{
+public:
+ DTPlugin();
+ ~DTPlugin();
+
+ virtual bool isValid() Q_DECL_OVERRIDE;
+};
+
+#endif
diff --git a/src-qt5/src-cpp/plugins-screensaver.cpp b/src-qt5/src-cpp/plugins-screensaver.cpp
index 4cb90aff..6370b068 100644
--- a/src-qt5/src-cpp/plugins-screensaver.cpp
+++ b/src-qt5/src-cpp/plugins-screensaver.cpp
@@ -5,14 +5,6 @@
// 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
@@ -25,35 +17,12 @@ 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();
- qDebug() << "Loaded ScreenSaver Data:" << currentfile << data;
- 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
+ ok &= containsDefault("name");
+ ok &= containsDefault("description");
+ if(ok) {
QJsonObject tmp = data.value("qml").toObject();
QStringList mustexist;
QString exec = tmp.value("exec").toString();
@@ -62,7 +31,6 @@ if(ok){
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]); }
@@ -70,83 +38,3 @@ if(ok){
}
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 << data;
- if(!exec.startsWith("/")){ exec.prepend( currentfile.section("/",0,-2)+"/" ); }
- return QUrl::fromLocalFile(exec);
-}
-
-// ===================
-// SS PLUGIN SYSTEM
-// ===================
-SSPlugin SSPluginSystem::findPlugin(QString name){
- //qDebug() << "FindPlugin:" << 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
index 9a7e98f5..042f824d 100644
--- a/src-qt5/src-cpp/plugins-screensaver.h
+++ b/src-qt5/src-cpp/plugins-screensaver.h
@@ -4,47 +4,26 @@
// 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 "plugins-base.h"
#include <QJsonObject>
#include <QString>
#include <QUrl>
#include <QObject>
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QFile>
+#include <QDir>
+#include <QDebug>
-class SSPlugin{
-private:
- QString currentfile;
-
+class SSPlugin : public BasePlugin {
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);
-
+ virtual bool isValid() Q_DECL_OVERRIDE;
};
#endif
diff --git a/src-qt5/src-cpp/plugins-screensaver.pri b/src-qt5/src-cpp/plugins-screensaver.pri
deleted file mode 100644
index ad03f34c..00000000
--- a/src-qt5/src-cpp/plugins-screensaver.pri
+++ /dev/null
@@ -1,4 +0,0 @@
-HEADERS *= $${PWD}/plugins-screensaver.h
-SOURCES *= $${PWD}/plugins-screensaver.cpp
-
-INCLUDEPATH *= $${PWD}
diff --git a/src-qt5/src-cpp/tests/main.cpp b/src-qt5/src-cpp/tests/main.cpp
new file mode 100644
index 00000000..682c318a
--- /dev/null
+++ b/src-qt5/src-cpp/tests/main.cpp
@@ -0,0 +1,38 @@
+#include <QDebug>
+#include <QApplication>
+
+#include <framework-OSInterface.h>
+
+/*
+class tester : public QObject{
+ Q_OBJECT
+public slots:
+ void finished(){ QApplication::exit(0); }
+
+public:
+ QTimer *timer;
+
+ tester(){
+ timer = new QTimer(this);
+ timer->setInterval(5000);
+ timer->setSingleShot(true);
+ connect(timer, SIGNAL(timeout()), this, SLOT(finished()) );
+ }
+
+};
+*/
+
+int main(int argc, char** argv){
+
+ QApplication A(argc,argv);
+ OSInterface OS;
+ OS.start();
+ QTimer *timer = new QTimer();
+ timer->setInterval(5000);
+ timer->setSingleShot(true);
+ QObject::connect(timer, SIGNAL(timeout()), &A, SLOT(quit()) );
+ timer->start();
+ int ret = A.exec();
+ qDebug() << " - Finished";
+ return ret;
+}
diff --git a/src-qt5/src-cpp/tests/test.pro b/src-qt5/src-cpp/tests/test.pro
new file mode 100644
index 00000000..425e7de6
--- /dev/null
+++ b/src-qt5/src-cpp/tests/test.pro
@@ -0,0 +1,7 @@
+QT = core gui widgets
+
+include(../framework-OSInterface.pri)
+
+TARGET = test
+
+SOURCES += main.cpp
diff --git a/src-qt5/src-qml/test/Grav.qml b/src-qt5/src-qml/test/Grav.qml
new file mode 100644
index 00000000..d7404a56
--- /dev/null
+++ b/src-qt5/src-qml/test/Grav.qml
@@ -0,0 +1,164 @@
+import QtQuick 2.7
+import QtQuick.Window 2.2
+import QtGraphicalEffects 1.0
+
+Rectangle {
+ id : canvas
+ anchors.fill: parent
+ width: Screen.width
+ height: Screen.height
+ color: "black"
+
+ //TODO Add orbital trails option
+ //TODO Fix jitteryness and start position
+ //TODO Make orbits more extreme
+
+ //Between 5 and 15 planets, read from settings
+ property int planets: Math.round(( Math.random() * 10 ) + 5 )
+ property int cx: Math.round(width/2)
+ property int cy: Math.round(height/2)
+
+ //Create planets
+ Repeater {
+ id: planetRepeater
+ model: planets
+
+ Rectangle {
+ id : index
+ parent: canvas
+
+ //Creates random distance for elipse
+ property double c: Math.random() * 250
+ property double b: Math.random() * 150 + c
+ property double a: Math.sqrt(b*b+c*c)
+ //Random angle of rotation
+ property double th: Math.random() * Math.PI
+ property var pathX: createPathX()
+ property var pathY: createPathY()
+ property var testArray: createTest()
+
+ //Calculates starting position
+ x: Math.round(cx + a * Math.cos(th))
+ y: Math.round(cy + b * Math.sin(th))
+
+ //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)
+
+ PathAnimation on x{
+ loops: Animation.Infinite
+ duration: 200
+ path: Path {
+ startX: x
+ startY: y
+ PathCurve { x: pathX; y: pathY }
+ }
+ }
+
+ NumberAnimation {
+
+ }
+
+ function createTest() {
+ var test = []
+ for(var i = 1; i <= 200; i++) {
+ test.push(PathCurve { x: pathX[i]; y: pathY[i] })
+ }
+ return test
+ }
+
+ function createPathX() {
+ var pathX = []
+ for(var i = 1; i <= 200; i++) {
+ pathX.push(cx+a*Math.cos(2*Math.PI*(i/200.0))*Math.cos(th) - b*Math.sin(2*Math.PI*(i/200.0))*Math.sin(th))
+ }
+ return pathX
+ }
+
+ function createPathY() {
+ var pathY = []
+ for(var i = 1; i <= 200; i++) {
+ pathY.push(cy+a*Math.cos(2*Math.PI*(i/200.0))*Math.sin(th) + b*Math.sin(2*Math.PI*(i/200.0))*Math.cos(th))
+ }
+ return pathY
+ }
+
+ /*Timer {
+ //Each planet updates between 1ms and 51ms (smaller times=faster)
+ interval: Math.round(Math.random() * 50 ) + 1
+ repeat: true
+ running: true
+ property int time: 0
+
+ onTriggered: {
+ //Parametric equation that calculates the position of the general ellipse. Completes a loop ever 314 cycles. Credit to
+ x = cx+a*Math.cos(2*Math.PI*(time/314.0))*Math.cos(th) - b*Math.sin(2*Math.PI*(time/314.0))*Math.sin(th)
+ y = cy+a*Math.cos(2*Math.PI*(time/314.0))*Math.sin(th) + b*Math.sin(2*Math.PI*(time/314.0))*Math.cos(th)
+ time++;
+
+ //Move a planet 80 pixels away from the sun if the planet is too close
+ if(x > cx && Math.abs(cx-x) < 80) {
+ x+=80
+ }else if(x < cx && Math.abs(cx-x) < 80) {
+ x-=80
+ }
+
+ if(y > cy && Math.abs(cy-y) < 80) {
+ y+=80
+ }else if(y < cy && Math.abs(cy-y) < 80) {
+ y-=80
+ }
+ }
+ }*/
+ }
+ }
+
+ //Create the star
+ Rectangle{
+ id: star
+ parent: canvas
+
+ //Centers in star in the center of the canvas, with an offset to center the animation
+ x: cx - 30
+ y: cy - 30
+
+ 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 }
+ }
+
+ 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)}
+ }
+ }
+
+ }
+}
diff --git a/src-qt5/src-qml/test/Test.qml b/src-qt5/src-qml/test/Test.qml
new file mode 100644
index 00000000..a2407b6c
--- /dev/null
+++ b/src-qt5/src-qml/test/Test.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.7
+
+Rectangle {
+ id : canvas
+ anchors.fill: parent
+ color: "black"
+}
bgstack15