aboutsummaryrefslogtreecommitdiff
path: root/src-qt5
diff options
context:
space:
mode:
Diffstat (limited to 'src-qt5')
-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
130 files changed, 4087 insertions, 1183 deletions
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