diff options
author | Weblate <noreply@weblate.org> | 2017-11-14 00:04:49 +0000 |
---|---|---|
committer | Weblate <noreply@weblate.org> | 2017-11-14 00:04:49 +0000 |
commit | dc40a01ae695b47f87daff7ee08f3519d79b12ae (patch) | |
tree | 6e1d58f23d4537f8f501ba7e531f9ed90f269dda /src-qt5 | |
parent | Translated using Weblate (German) (diff) | |
parent | Add a special rule for Ubuntu Linux: (diff) | |
download | lumina-dc40a01ae695b47f87daff7ee08f3519d79b12ae.tar.gz lumina-dc40a01ae695b47f87daff7ee08f3519d79b12ae.tar.bz2 lumina-dc40a01ae695b47f87daff7ee08f3519d79b12ae.zip |
Merge remote-tracking branch 'origin/master'
Diffstat (limited to 'src-qt5')
188 files changed, 5691 insertions, 1846 deletions
diff --git a/src-qt5/OS-detect.pri b/src-qt5/OS-detect.pri index 9f3019e3..3d01ea5f 100644 --- a/src-qt5/OS-detect.pri +++ b/src-qt5/OS-detect.pri @@ -23,7 +23,7 @@ # ============================================= isEmpty(OS){ message("Build OS Info: $${QMAKE_HOST.os}, $${QMAKE_HOST.arch}, $${QMAKE_HOST.version_string}") - + message(" - Detected Qt Version: $${QT_VERSION}") #Load the initial library/includefile search locations (more can be added in the OS-specific sections below) LIBS = -L$${PWD}/core/libLumina -L$$[QT_INSTALL_LIBS] INCLUDEPATH = $${PWD}/core/libLumina $$[QT_INSTALL_HEADERS] $$[QT_INSTALL_PREFIX] @@ -75,12 +75,15 @@ isEmpty(OS){ #Apply any special rules for particular distros equals(LINUX_DISTRO,"Fedora"){ isEmpty(L_ETCDIR){ L_ETCDIR=/etc } - } + } equals(LINUX_DISTRO,"Gentoo"){ isEmpty(L_BINDIR){ L_BINDIR = $${PREFIX}/bin } 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/pages/getPage.cpp b/src-qt5/core-utils/lumina-config/pages/getPage.cpp index 7274ae3f..c3f88e2c 100644 --- a/src-qt5/core-utils/lumina-config/pages/getPage.cpp +++ b/src-qt5/core-utils/lumina-config/pages/getPage.cpp @@ -20,6 +20,7 @@ #include "page_session_locale.h" #include "page_session_options.h" #include "page_compton.h" +#include "page_soundtheme.h" // #include "page_mouse_trueos.h" // #include "page_bluetooth_trueos.h" @@ -51,6 +52,7 @@ QList<PAGEINFO> Pages::KnownPages(){ list << Pages::PageInfo("interface-menu", QObject::tr("Menu"), QObject::tr("Menu Plugins"), "format-list-unordered",QObject::tr("Change what options are shown on the desktop context menu"), "interface", QStringList(), QStringList() << "desktop" << "menu" << "plugins" << "shortcuts"); list << Pages::PageInfo("session-locale", QObject::tr("Localization"), QObject::tr("Locale Settings"), "preferences-desktop-locale",QObject::tr("Change the default locale settings for this user"), "user", QStringList(), QStringList() << "user"<<"locale"<<"language"<<"translations"); list << Pages::PageInfo("session-options", QObject::tr("General Options"), QObject::tr("User Settings"), "configure",QObject::tr("Change basic user settings such as time/date formats"), "user", QStringList(), QStringList() << "user"<<"settings"<<"time"<<"date"<<"icon"<<"reset"<<"numlock"<<"clock"); + list << Pages::PageInfo("soundtheme", QObject::tr("Sound Themeing"), QObject::tr("Theme"), "media-playlist-audio",QObject::tr("Change basic sound settings"), "session", QStringList(), QStringList() << "session"<<"settings"<<"sound"<<"theme"); // list << Pages::PageInfo("mouse-settings", QObject::tr("TrueOS Mouse Settings"), QObject::tr("TrueOS Mouse Settings"), "preferences-desktop-mouse",QObject::tr("Adjust mouse devices"), "user", QStringList(), QStringList() << "user"<<"speed"<<"accel"<<"mouse"); // list << Pages::PageInfo("bluetooth-settings", QObject::tr("TrueOS Bluetooth Settings"), QObject::tr("TrueOS Bluetooth Settings"), "preferences-desktop-bluetooth",QObject::tr("Setup Bluetooth devices"), "user", QStringList(), QStringList() << "user"<<"bluetooth"<<"audio"); @@ -72,7 +74,7 @@ PageWidget* Pages::GetNewPage(QString id, QWidget *parent){ else if(id=="session-locale"){ page = new page_session_locale(parent); } else if(id=="session-options"){ page = new page_session_options(parent); } else if(id=="compton"){ page = new page_compton(parent); } - + else if(id=="soundtheme"){ page = new page_soundtheme(parent); } // else if(id=="mouse-settings"){ page = new page_mouse_trueos(parent); } // else if(id=="bluetooth-settings"){ page = new page_bluetooth_trueos(parent); } //Return the main control_panel page as the fallback/default diff --git a/src-qt5/core-utils/lumina-config/pages/page_defaultapps.cpp b/src-qt5/core-utils/lumina-config/pages/page_defaultapps.cpp index c2d689ec..df7ae516 100644 --- a/src-qt5/core-utils/lumina-config/pages/page_defaultapps.cpp +++ b/src-qt5/core-utils/lumina-config/pages/page_defaultapps.cpp @@ -245,7 +245,7 @@ void page_defaultapps::setdefaultitem(){ //Now set the items for(int i=0; i<list.length(); i++){ //Set it in the back end - LXDG::setDefaultAppForMime(list[i]->whatsThis(0), app.section("/",-1)); + LXDG::setDefaultAppForMime(list[i]->whatsThis(0), app); //Set it in the UI XDGDesktop desk(app); list[i]->setWhatsThis(1,app); //app path diff --git a/src-qt5/core-utils/lumina-config/pages/page_soundtheme.cpp b/src-qt5/core-utils/lumina-config/pages/page_soundtheme.cpp new file mode 100644 index 00000000..fbb0e7e7 --- /dev/null +++ b/src-qt5/core-utils/lumina-config/pages/page_soundtheme.cpp @@ -0,0 +1,113 @@ +//=========================================== +// Lumina Desktop Source Code +// Copyright (c) 2017, JT (q5sys) +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "page_soundtheme.h" +#include "ui_page_soundtheme.h" +#include "../AppDialog.h" + +//========== +// PUBLIC +//========== +page_soundtheme::page_soundtheme(QWidget *parent) : PageWidget(parent), ui(new Ui::page_soundtheme()){ + ui->setupUi(this); +} + +page_soundtheme::~page_soundtheme(){ + +} + +//================ +// PUBLIC SLOTS +//================ +void page_soundtheme::SaveSettings(){ + sessionsettings = new QSettings("lumina-desktop", "sessionsettings"); + + sessionsettings->setValue("PlayStartupAudio", ui->checkBox_startup->isChecked()); + sessionsettings->setValue("audiofiles/login", ui->label_startup->whatsThis()); + + sessionsettings->setValue("PlayLogoutAudio", ui->checkBox_logout->isChecked()); + sessionsettings->setValue("audiofiles/logout", ui->label_logout->whatsThis()); + + sessionsettings->setValue("PlayBatteryLowAudio", ui->checkBox_battery->isChecked()); + sessionsettings->setValue("audiofiles/batterylow", ui->label_battery->whatsThis()); + +} + +void page_soundtheme::LoadSettings(int){ + emit ChangePageTitle( tr("Sound Themes") ); + + sessionsettings = new QSettings("lumina-desktop", "sessionsettings"); + + ui->label_startup->setText(sessionsettings->value("audiofiles/login").toString().section("/",-1)); + ui->label_startup->setToolTip(sessionsettings->value("audiofiles/batterylow").toString()); + ui->label_startup->setWhatsThis(sessionsettings->value("audiofiles/login").toString()); + bool playstartup = sessionsettings->value("PlayStartupAudio").toBool(); + if( playstartup ){ ui->checkBox_startup->setChecked(true); } + + ui->label_logout->setText(sessionsettings->value("audiofiles/logout").toString().section("/",-1)); + ui->label_startup->setToolTip(sessionsettings->value("audiofiles/batterylow").toString()); + ui->label_logout->setWhatsThis(sessionsettings->value("audiofiles/logout").toString()); + bool playlogout = sessionsettings->value("PlayLogoutAudio").toBool(); + if( playlogout ){ ui->checkBox_logout->setChecked(true); } + + ui->label_battery->setText(sessionsettings->value("audiofiles/batterylow").toString().section("/",-1)); + ui->label_startup->setToolTip(sessionsettings->value("audiofiles/batterylow").toString()); + ui->label_battery->setWhatsThis(sessionsettings->value("audiofiles/batterylow").toString()); + bool playbattery = sessionsettings->value("PlayBatteryLowAudio").toBool(); + if( playbattery ){ ui->checkBox_battery->setChecked(true);} + emit HasPendingChanges(false); +} + +//================= +// PRIVATE +//================= + +//================= +// PRIVATE SLOTS +//================= + +void page_soundtheme::on_pushButton_startup_clicked(){ + QString startupsound = QFileDialog::getOpenFileName(this, tr("Select Startup Sound"), QDir::homePath()); + if(startupsound.isEmpty()){ return; } + ui->label_startup->setText(startupsound.section("/",-1)); + ui->label_startup->setToolTip(startupsound); + ui->label_startup->setWhatsThis(startupsound); + settingChanged(); + qDebug() << "startup whats this" << startupsound; +} + +void page_soundtheme::on_pushButton_logout_clicked(){ + QString logoutsound = QFileDialog::getOpenFileName(this, tr("Select Logout Sound"), QDir::homePath()); + if(logoutsound.isEmpty()){ return; } + ui->label_logout->setText(logoutsound.section("/",-1)); + ui->label_logout->setToolTip(logoutsound); + ui->label_logout->setWhatsThis(logoutsound); + qDebug() << "startup whats this" << logoutsound; + settingChanged(); +} + +void page_soundtheme::on_pushButton_battery_clicked(){ + QString batterysound = QFileDialog::getOpenFileName(this, tr("Select Low Battery Sound"), QDir::homePath()); + if(batterysound.isEmpty()){ return; } + ui->label_battery->setText(batterysound.section("/",-1)); + ui->label_battery->setToolTip(batterysound); + ui->label_battery->setWhatsThis(batterysound); + qDebug() << "startup whats this" << batterysound; + settingChanged(); +} + + +void page_soundtheme::on_checkBox_startup_toggled(bool checked){ + settingChanged(); +} + +void page_soundtheme::on_checkBox_logout_toggled(bool checked){ + settingChanged(); +} + +void page_soundtheme::on_checkBox_battery_toggled(bool checked){ + settingChanged(); +} diff --git a/src-qt5/core-utils/lumina-config/pages/page_soundtheme.h b/src-qt5/core-utils/lumina-config/pages/page_soundtheme.h new file mode 100644 index 00000000..5d3bed66 --- /dev/null +++ b/src-qt5/core-utils/lumina-config/pages/page_soundtheme.h @@ -0,0 +1,42 @@ +//=========================================== +// Lumina Desktop Source Code +// Copyright (c) 2017, JT (q5sys) +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#ifndef _LUMINA_CONFIG_PAGE_SOUNDTHEME_H +#define _LUMINA_CONFIG_PAGE_SOUNDTHEME_H +#include "../globals.h" +#include "PageWidget.h" + +namespace Ui{ + class page_soundtheme; +}; + +class page_soundtheme : public PageWidget{ + Q_OBJECT +public: + page_soundtheme(QWidget *parent); + ~page_soundtheme(); + +public slots: + + void SaveSettings(); + void LoadSettings(int screennum); + + +private: + Ui::page_soundtheme *ui; + QString startupsound, logoutsound, batterysound; + QSettings *sessionsettings; + +private slots: + + void on_pushButton_startup_clicked(); + void on_pushButton_logout_clicked(); + void on_pushButton_battery_clicked(); + void on_checkBox_startup_toggled(bool checked); + void on_checkBox_logout_toggled(bool checked); + void on_checkBox_battery_toggled(bool checked); +}; +#endif diff --git a/src-qt5/core-utils/lumina-config/pages/page_soundtheme.ui b/src-qt5/core-utils/lumina-config/pages/page_soundtheme.ui new file mode 100644 index 00000000..329b68a4 --- /dev/null +++ b/src-qt5/core-utils/lumina-config/pages/page_soundtheme.ui @@ -0,0 +1,156 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>page_soundtheme</class> + <widget class="QWidget" name="page_soundtheme"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>455</width> + <height>326</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QCheckBox" name="checkBox_startup"> + <property name="text"> + <string>Enabled</string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_startup"> + <property name="text"> + <string>TextLabel</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButton_startup"> + <property name="text"> + <string>Set Startup Audio</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QCheckBox" name="checkBox_logout"> + <property name="text"> + <string>Enabled</string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_logout"> + <property name="text"> + <string>TextLabel</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButton_logout"> + <property name="text"> + <string>Set Logout Audio</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QCheckBox" name="checkBox_battery"> + <property name="text"> + <string>Enabled</string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_battery"> + <property name="text"> + <string>TextLabel</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButton_battery"> + <property name="text"> + <string>Set Battery Audio</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src-qt5/core-utils/lumina-config/pages/page_wallpaper.cpp b/src-qt5/core-utils/lumina-config/pages/page_wallpaper.cpp index 6842dce4..839269ca 100644 --- a/src-qt5/core-utils/lumina-config/pages/page_wallpaper.cpp +++ b/src-qt5/core-utils/lumina-config/pages/page_wallpaper.cpp @@ -221,7 +221,7 @@ void page_wallpaper::deskbgcoloradded(){ ui->combo_desk_bg->addItem( QString(tr("Solid Color: %1")).arg(color), color); //Now move to the last item in the list (the new image(s)); ui->combo_desk_bg->setCurrentIndex( ui->combo_desk_bg->count()-1 ); - + emit HasPendingChanges(true); } diff --git a/src-qt5/core-utils/lumina-config/pages/pages.pri b/src-qt5/core-utils/lumina-config/pages/pages.pri index ce167d27..585a2922 100644 --- a/src-qt5/core-utils/lumina-config/pages/pages.pri +++ b/src-qt5/core-utils/lumina-config/pages/pages.pri @@ -13,8 +13,9 @@ HEADERS += $${PWD}/getPage.h \ $${PWD}/page_interface_panels.h \ $${PWD}/page_session_locale.h \ $${PWD}/page_session_options.h \ - $${PWD}/page_compton.h -# $${PWD}/page_bluetooth_trueos.h + $${PWD}/page_compton.h \ + $$PWD/page_soundtheme.h +# $${PWD}/page_bluetooth_trueos.h # $${PWD}/page_mouse_trueos.h @@ -31,7 +32,8 @@ SOURCES += $${PWD}/getPage.cpp \ $${PWD}/page_interface_panels.cpp \ $${PWD}/page_session_locale.cpp \ $${PWD}/page_session_options.cpp \ - $${PWD}/page_compton.cpp + $${PWD}/page_compton.cpp \ + $$PWD/page_soundtheme.cpp # $${PWD}/page_bluetooth_trueos.cpp # $${PWD}/page_mouse_trueos.cpp @@ -49,6 +51,7 @@ FORMS += $${PWD}/page_main.ui \ $${PWD}/page_interface_panels.ui \ $${PWD}/page_session_locale.ui \ $${PWD}/page_session_options.ui \ - $${PWD}/page_compton.ui + $${PWD}/page_compton.ui \ + $$PWD/page_soundtheme.ui # $${PWD}/page_bluetooth_trueos.ui # $${PWD}/page_mouse_trueos.ui diff --git a/src-qt5/core-utils/lumina-xconfig/ScreenSettings.cpp b/src-qt5/core-utils/lumina-xconfig/ScreenSettings.cpp index 3c0edc76..a9d40554 100644 --- a/src-qt5/core-utils/lumina-xconfig/ScreenSettings.cpp +++ b/src-qt5/core-utils/lumina-xconfig/ScreenSettings.cpp @@ -13,6 +13,7 @@ void RRSettings::ApplyPrevious(){ QList<ScreenInfo> screens; QSettings set("lumina-desktop","lumina-xconfig"); + if(set.allKeys().isEmpty()){ return; } QString profile = set.value("default_profile","").toString(); if(profile.isEmpty() || !savedProfiles().contains(profile) ){ screens = PreviousSettings(); } else{ screens = PreviousSettings(profile); } @@ -167,6 +168,13 @@ bool RRSettings::SaveScreens(QList<ScreenInfo> screens, QString profile){ //Apply screen configuration void RRSettings::Apply(QList<ScreenInfo> screens){ + //Verify that there is at least 1 active/enabled monitor first + bool foundactive = false; + for(int i=0; i<screens.length() && !foundactive; i++){ + if(screens[i].isactive){ foundactive = (screens[i].applyChange!=1); } //make sure we are not turning it off + else{ foundactive = (screens[i].applyChange==2); } + } + if(!foundactive){ return; } //never disable all screens //Read all the settings and create the xrandr options to maintain these settings QStringList opts; //qDebug() << "Apply:" << screens.length(); diff --git a/src-qt5/core/README.md b/src-qt5/core/README.md index 6a17d900..6ed23f78 100644 --- a/src-qt5/core/README.md +++ b/src-qt5/core/README.md @@ -27,6 +27,7 @@ Other Files that get installed if "core" is built directly: * svg * widgets * x11extras + * NOTE: Qt5 platform theme and developer libraries are also required to build the Lumina theme engine plugin ("qtbase5-*" on Ubuntu 17.10) 2. X11 Libraries * libXdamage 3. XCB Libraries diff --git a/src-qt5/core/libLumina/ExternalProcess.h b/src-qt5/core/libLumina/ExternalProcess.h index b1e56af8..2a6f4949 100644 --- a/src-qt5/core/libLumina/ExternalProcess.h +++ b/src-qt5/core/libLumina/ExternalProcess.h @@ -15,6 +15,7 @@ #include <QString> #include <QTimer> #include <QApplication> +#include <QDebug> class ExternalProcess : public QProcess{ Q_OBJECT @@ -23,18 +24,21 @@ private: private slots: void resetCursor(){ + //qDebug() << "External Process: Reset Mouse Cursor =" << !cursorRestored; if(!cursorRestored){ QApplication::restoreOverrideCursor(); cursorRestored = true; } } void processStarting(){ + //qDebug() << "Starting External Process: Mouse Notification =" << !cursorRestored; if(!cursorRestored){ - QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); - QTimer::singleShot(15000, this, SLOT(resetCursor()) ); + QApplication::setOverrideCursor( QCursor(Qt::BusyCursor) ); + QTimer::singleShot(3000, this, SLOT(resetCursor()) ); } } void processFinished(){ + //qDebug() << "External Process Finished: Reset Mouse Cursor =" << !cursorRestored; if(!cursorRestored){ QApplication::restoreOverrideCursor(); cursorRestored = true; @@ -53,6 +57,7 @@ public: this->setStandardOutputFile(logfile); } //Setup the connection for automatic cleanup + connect(this, SIGNAL(started()), this, SLOT(processStarting()) ); connect(this, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processFinished()) ); } @@ -62,7 +67,7 @@ public: }*/ } - static void launch(QString program, QStringList args = QStringList(), bool manageCursors = false){ + static void launch(QString program, QStringList args = QStringList(), bool manageCursors = true){ //Quick launch of a process with logging disabled and automatic cleanup ExternalProcess *tmp = new ExternalProcess("", manageCursors); if(args.isEmpty()){ tmp->start(program); } diff --git a/src-qt5/core/libLumina/LDesktopUtils.cpp b/src-qt5/core/libLumina/LDesktopUtils.cpp index 54e660e6..f1b3de17 100644 --- a/src-qt5/core/libLumina/LDesktopUtils.cpp +++ b/src-qt5/core/libLumina/LDesktopUtils.cpp @@ -155,8 +155,8 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ if(sysDefaults.isEmpty()){ sysDefaults = LUtils::readFile(LOS::LuminaShare()+"luminaDesktop.conf"); } //Find the number of the left-most desktop screen QString screen = "0"; - QDesktopWidget *desk =QApplication::desktop(); QRect screenGeom; + QDesktopWidget *desk =QApplication::desktop(); for(int i=0; i<desk->screenCount(); i++){ if(desk->screenGeometry(i).x()==0){ screen = QString::number(i); @@ -401,7 +401,7 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ QStringList syscolors = LTHEME::availableSystemColors(); //theme file //qDebug() << "Detected Themes/colors:" << systhemes << syscolors; - if( !themesettings[0].startsWith("/") || !QFile::exists(themesettings[0]) || !themesettings[0].endsWith(".qss.template")){ + if( !themesettings[0].startsWith("/") || !QFile::exists(themesettings[0]) || !themesettings[0].endsWith(".qss")){ themesettings[0] = themesettings[0].section(".qss",0,0).simplified(); for(int i=0; i<systhemes.length(); i++){ if(systhemes[i].startsWith(themesettings[0]+"::::",Qt::CaseInsensitive)){ @@ -411,9 +411,9 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ } } //color file - if( !themesettings[1].startsWith("/") || !QFile::exists(themesettings[1]) || !themesettings[1].endsWith(".qss.colors") ){ + if( !themesettings[1].startsWith("/") || !QFile::exists(themesettings[1]) || !themesettings[1].endsWith(".conf") ){ //Remove any extra/invalid extension - themesettings[1] = themesettings[1].section(".qss",0,0).simplified(); + themesettings[1] = themesettings[1].section(".conf",0,0).simplified(); for(int i=0; i<syscolors.length(); i++){ if(syscolors[i].startsWith(themesettings[1]+"::::",Qt::CaseInsensitive)){ themesettings[1] = syscolors[i].section("::::",1,1); //Replace with the full path @@ -434,13 +434,6 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ //Now save the settings files if(setTheme){ LTHEME::setCurrentSettings( themesettings[0], themesettings[1], themesettings[2], themesettings[3], themesettings[4]); - QSettings themeset("lthemeengine","lthemeengine"); - themeset.setValue("Appearance/icon_theme",themesettings[2]); - //Quick hack for a "dark" theme/color to be uniform across the desktop/applications - if(themesettings[0].contains("DarkGlass") || themesettings[1].contains("Black")){ - themeset.setValue("Appearance/custom_palette", true); - themeset.setValue("Appearance/color_scheme_path", LOS::LuminaShare().section("/",0,-3)+"/lthemeengine/colors/darker.conf"); - } } LUtils::writeFile(setdir+"/sessionsettings.conf", sesset, true); LUtils::writeFile(setdir+"/desktopsettings.conf", deskset, true); @@ -463,12 +456,14 @@ void LDesktopUtils::LoadSystemDefaults(bool skipOS){ } -bool LDesktopUtils::checkUserFiles(QString lastversion){ +bool LDesktopUtils::checkUserFiles(QString lastversion, QString currentversion){ + //WARNING: Make sure you create a QApplication instance before calling this function!!! + //internal version conversion examples: // [1.0.0 -> 1000000], [1.2.3 -> 1002003], [0.6.1 -> 6001] //returns true if something changed int oldversion = LDesktopUtils::VersionStringToNumber(lastversion); - int nversion = LDesktopUtils::VersionStringToNumber(QApplication::applicationVersion()); + int nversion = LDesktopUtils::VersionStringToNumber(currentversion); bool newversion = ( oldversion < nversion ); //increasing version number bool newrelease = ( lastversion.contains("-devel", Qt::CaseInsensitive) && QApplication::applicationVersion().contains("-release", Qt::CaseInsensitive) ); //Moving from devel to release @@ -510,6 +505,43 @@ bool LDesktopUtils::checkUserFiles(QString lastversion){ } LUtils::writeFile(dset, DS, true); } + if(oldversion<1003004){ + //Lumina 1.3.4 - Migrate theme settings from old format to the new theme engine format + QString themefile = QString(getenv("XDG_CONFIG_HOME"))+"/lthemeengine/lthemeengine.conf"; + if(!QFile::exists(themefile)){ + QDir dir; + dir.mkpath(themefile.section("/",0,-2)); //make sure the main directory exists first + //Need to migrate theme settings from the old location to the new one + QSettings newtheme(themefile, QSettings::NativeFormat); + qDebug() << "Migrating Theme settings:" << newtheme.fileName(); + QStringList oldtheme = LUtils::readFile( QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/themesettings.cfg" ); + //Find the system install location for the theme engine for use later + QString enginedir = LOS::LuminaShare()+"/../lthemeengine/"; + //Find/match the icon theme + QString tmp = oldtheme.filter("ICONTHEME=").join("\n").section("=",1,-1).section("\n",0,0).simplified(); + if(tmp.isEmpty()){ tmp = "material-design-light"; } //unknown Icon theme - use the default "light" version + newtheme.setValue("Appearance/icon_theme",tmp); + //Quick detect/adjust of the tone of the color theme based on the icons/colors (no 1-to-1 color theme matching between systems) + bool isdarktheme = tmp.contains("dark"); + isdarktheme = isdarktheme || oldtheme.filter("COLORFILE=").join("\n").section("=",1,-1).section("\n",0,0).contains("DarkGlass"); + //Quick adjust for the material-design icon theme to make it match the current dark/light theme + if(tmp.contains("material-design")){ + newtheme.setValue("Appearance/icon_theme", QString("material-design-")+ (isdarktheme ? "dark" : "light") ); + } + if(isdarktheme){ + newtheme.setValue("Appearance/custom_palette", true); + newtheme.setValue("Appearance/color_scheme_path", enginedir+"colors/darker.conf"); + newtheme.setValue("Interface/desktop_stylesheets", QStringList() << enginedir+"desktop_qss/DarkGlass.qss"); + }else{ + newtheme.setValue("Appearance/custom_palette", true); + newtheme.setValue("Appearance/color_scheme_path", enginedir+"colors/airy.conf"); + newtheme.setValue("Interface/desktop_stylesheets", QStringList() << enginedir+"desktop_qss/Glass.qss"); + } + newtheme.setValue("Appearance/style", "Fusion"); + newtheme.setValue("Interface/stylesheets", QStringList() << enginedir+"qss/tooltip-simple.qss" << enginedir+"qss/scrollbar-simple.qss" << enginedir+"qss/sliders-simple.qss"); + newtheme.sync(); //flush this to file right now + } //end check for theme file existance + } //Check the fluxbox configuration files dset = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/"; diff --git a/src-qt5/core/libLumina/LDesktopUtils.h b/src-qt5/core/libLumina/LDesktopUtils.h index a9b44c67..b0ce6ba5 100644 --- a/src-qt5/core/libLumina/LDesktopUtils.h +++ b/src-qt5/core/libLumina/LDesktopUtils.h @@ -43,7 +43,7 @@ public: //Load the default setup for the system static void LoadSystemDefaults(bool skipOS = false); - static bool checkUserFiles(QString lastversion); //returns true if something changed + static bool checkUserFiles(QString lastversion, QString currentversion); //returns true if something changed static int VersionStringToNumber(QString version); //convert the lumina version string to a number for comparisons //Migrating desktop settings from one ID to another diff --git a/src-qt5/core/libLumina/LDesktopUtils.pri b/src-qt5/core/libLumina/LDesktopUtils.pri index 80bbcfa8..fcacc586 100644 --- a/src-qt5/core/libLumina/LDesktopUtils.pri +++ b/src-qt5/core/libLumina/LDesktopUtils.pri @@ -5,3 +5,4 @@ INCLUDEPATH *= ${PWD} #Now the other dependendies of it include(LUtils.pri) +include(LuminaThemes.pri) diff --git a/src-qt5/core/libLumina/LUtils.cpp b/src-qt5/core/libLumina/LUtils.cpp index 491778ca..3d3c878a 100644 --- a/src-qt5/core/libLumina/LUtils.cpp +++ b/src-qt5/core/libLumina/LUtils.cpp @@ -14,7 +14,7 @@ #include <unistd.h> -inline QStringList ProcessRun(QString cmd, QStringList args){ +/*inline QStringList ProcessRun(QString cmd, QStringList args){ //Assemble outputs QStringList out; out << "1" << ""; //error code, string output QProcess proc; @@ -38,50 +38,58 @@ inline QStringList ProcessRun(QString cmd, QStringList args){ out[0] = QString::number(proc.exitCode()); out[1] = info+QString(proc.readAllStandardOutput()); return out; -} +}*/ + //============= // LUtils Functions //============= -int LUtils::runCmd(QString cmd, QStringList args){ - /*QProcess proc; - proc.setProcessChannelMode(QProcess::MergedChannels); - if(args.isEmpty()){ - proc.start(cmd); - }else{ - proc.start(cmd, args); +QString LUtils::runCommand(bool &success, QString command, QStringList arguments, QString workdir, QStringList env){ + QProcess proc; + proc.setProcessChannelMode(QProcess::MergedChannels); //need output + //First setup the process environment as necessary + QProcessEnvironment PE = QProcessEnvironment::systemEnvironment(); + if(!env.isEmpty()){ + for(int i=0; i<env.length(); i++){ + if(!env[i].contains("=")){ continue; } + PE.insert(env[i].section("=",0,0), env[i].section("=",1,100)); + } + } + proc.setProcessEnvironment(PE); + //if a working directory is specified, check it and use it + if(!workdir.isEmpty()){ + proc.setWorkingDirectory(workdir); } - //if(!proc.waitForStarted(30000)){ return 1; } //process never started - max wait of 30 seconds - while(!proc.waitForFinished(300)){ + //Now run the command (with any optional arguments) + if(arguments.isEmpty()){ proc.start(command); } + else{ proc.start(command, arguments); } + //Wait for the process to finish (but don't block the event loop) + QString info; + while(!proc.waitForFinished(1000)){ if(proc.state() == QProcess::NotRunning){ break; } //somehow missed the finished signal - QCoreApplication::processEvents(); + QString tmp = proc.readAllStandardOutput(); + if(tmp.isEmpty()){ proc.terminate(); } + else{ info.append(tmp); } } - int ret = proc.exitCode(); - return ret;*/ - QFuture<QStringList> future = QtConcurrent::run(ProcessRun, cmd, args); - return future.result()[0].toInt(); //turn it back into an integer return code + info.append(proc.readAllStandardOutput()); //make sure we don't miss anything in the output + success = (proc.exitCode()==0); //return success/failure + return info; +} + +int LUtils::runCmd(QString cmd, QStringList args){ + bool success; + LUtils::runCommand(success, cmd, args); + return success; + + /*QFuture<QStringList> future = QtConcurrent::run(ProcessRun, cmd, args); + return future.result()[0].toInt(); //turn it back into an integer return code*/ } QStringList LUtils::getCmdOutput(QString cmd, QStringList args){ - /*QProcess proc; - QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); - env.insert("LANG", "C"); - env.insert("LC_MESSAGES", "C"); - proc.setProcessEnvironment(env); - proc.setProcessChannelMode(QProcess::MergedChannels); - if(args.isEmpty()){ - proc.start(cmd); - }else{ - proc.start(cmd,args); - } - //if(!proc.waitForStarted(30000)){ return QStringList(); } //process never started - max wait of 30 seconds - while(!proc.waitForFinished(300)){ - if(proc.state() == QProcess::NotRunning){ break; } //somehow missed the finished signal - QCoreApplication::processEvents(); - } - QStringList out = QString(proc.readAllStandardOutput()).split("\n"); - return out;*/ - QFuture<QStringList> future = QtConcurrent::run(ProcessRun, cmd, args); - return future.result()[1].split("\n"); //Split the return message into lines + bool success; + QString log = LUtils::runCommand(success, cmd, args); + return log.split("\n"); + /*QFuture<QStringList> future = QtConcurrent::run(ProcessRun, cmd, args); + return future.result()[1].split("\n"); //Split the return message into lines*/ } QStringList LUtils::readFile(QString filepath){ @@ -113,6 +121,10 @@ bool LUtils::writeFile(QString filepath, QStringList contents, bool overwrite){ } bool LUtils::isValidBinary(QString& bin){ + //Trim off any quotes + if(bin.startsWith("\"") && bin.endsWith("\"")){ bin.chop(1); bin = bin.remove(0,1); } + if(bin.startsWith("\'") && bin.endsWith("\'")){ bin.chop(1); bin = bin.remove(0,1); } + //Now look for relative/absolute path if(!bin.startsWith("/")){ //Relative path: search for it on the current "PATH" settings QStringList paths = QString(qgetenv("PATH")).split(":"); diff --git a/src-qt5/core/libLumina/LUtils.h b/src-qt5/core/libLumina/LUtils.h index a494d4da..ee04c023 100644 --- a/src-qt5/core/libLumina/LUtils.h +++ b/src-qt5/core/libLumina/LUtils.h @@ -30,6 +30,9 @@ class LUtils{ public: + //Run an external command and return output & exit code + static QString runCommand(bool &success, QString command, QStringList arguments = QStringList(), QString workdir = "", QStringList env = QStringList()); + //Run an external command and return the exit code static int runCmd(QString cmd, QStringList args = QStringList()); //Run an external command and return any text output (one line per entry) diff --git a/src-qt5/core/libLumina/LVideoLabel.cpp b/src-qt5/core/libLumina/LVideoLabel.cpp new file mode 100644 index 00000000..bddb1cba --- /dev/null +++ b/src-qt5/core/libLumina/LVideoLabel.cpp @@ -0,0 +1,120 @@ +#include "LVideoLabel.h" +#include <LuminaXDG.h> +#include <QCoreApplication> + +LVideoLabel::LVideoLabel(QString file, bool icons, QWidget *parent) : QLabel(parent) { + thumbnail = QPixmap(); + entered = false; + this->icons = icons; + filepath = file; + defaultThumbnail = LXDG::findIcon("unknown", "").pixmap(256,256); + + QTimer::singleShot(0, this, SLOT(initializeBackend()) ); +} + +LVideoLabel::~LVideoLabel() { + mediaPlayer->deleteLater(); + surface->deleteLater(); +} + +void LVideoLabel::initializeBackend(){ + mediaPlayer = new QMediaPlayer(this, QMediaPlayer::VideoSurface); + surface = new LVideoSurface(this); + mediaPlayer->setVideoOutput(surface); + mediaPlayer->setPlaybackRate(3); + mediaPlayer->setMuted(true); + + this->setPixmap(defaultThumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); + mediaPlayer->setMedia(QUrl::fromLocalFile(filepath)); + mediaPlayer->play(); + + this->connect(surface, SIGNAL(frameReceived(QPixmap)), this, SLOT(stopVideo(QPixmap))); + this->connect(mediaPlayer, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(stateChanged(QMediaPlayer::State))); + this->connect(mediaPlayer, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(setDuration(QMediaPlayer::MediaStatus))); + this->connect(this, SIGNAL(rollOver()), surface, SLOT(switchRollOver())); +} + +void LVideoLabel::enableIcons() { + this->setPixmap(thumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); + icons = true; +} + +void LVideoLabel::disableIcons() { + this->setPixmap(defaultThumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); + icons = false; +} + +void LVideoLabel::stopVideo(QPixmap pix) { + if(!entered) { + emit frameReceived(pix); + if(thumbnail.isNull()) + thumbnail = pix; + if(icons) + this->setPixmap(thumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); + mediaPlayer->pause(); + }else { + if(icons) + this->setPixmap(pix.scaled(this->size(),Qt::IgnoreAspectRatio)); + } +} + +void LVideoLabel::stateChanged(QMediaPlayer::State state) { + //qDebug() << state; +} + +void LVideoLabel::setDuration(QMediaPlayer::MediaStatus status) { + //qDebug() << status; + if(status == QMediaPlayer::BufferedMedia && !entered) { //Set duration in the middle to capture the thumbnail + mediaPlayer->setPosition(mediaPlayer->duration() / 2); + mediaPlayer->play(); + }else if(status == QMediaPlayer::EndOfMedia && entered) { //Loop back to the beginning if playback started and at the end of the video + mediaPlayer->setPosition(0); + mediaPlayer->play(); + }else if(status == QMediaPlayer::InvalidMedia){ + mediaPlayer->stop(); + mediaPlayer->play(); + }/*else if(status == QMediaPlayer::LoadingMedia) { + mediaPlayer->pause(); + QTimer timer; + timer.setSingleShot(true); + timer.setInterval(300); + timer.start(); + qDebug() << "Timer Started" << timer.remainingTime(); + while(timer.isActive()) QCoreApplication::processEvents(QEventLoop::AllEvents, 5); + qDebug() << "Timer Finished" << timer.remainingTime(); + mediaPlayer->setPosition(0); + mediaPlayer->play(); + }*/ +} + +void LVideoLabel::resizeEvent(QResizeEvent *event) { + //Resize the current pixmap to match the new size + if(!thumbnail.isNull()){ + if(icons) + this->setPixmap(thumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); + else + this->setPixmap(defaultThumbnail.scaled(this->size(),Qt::IgnoreAspectRatio)); + } + QLabel::resizeEvent(event); +} + +//Start playing the video from the beginning when the mouse enters the label +void LVideoLabel::enterEvent(QEvent *event) { + if(icons) { + entered=true; + emit rollOver(); + mediaPlayer->setPosition(0); + mediaPlayer->play(); + } + QWidget::enterEvent(event); +} + +//Stop the video and set the thumbnail back to the middle of the video when the mouse leaves the label +void LVideoLabel::leaveEvent(QEvent *event) { + if(icons) { + entered=false; + mediaPlayer->setPosition(mediaPlayer->duration() / 2); + emit rollOver(); + } + QWidget::leaveEvent(event); +} diff --git a/src-qt5/core/libLumina/LVideoLabel.h b/src-qt5/core/libLumina/LVideoLabel.h new file mode 100644 index 00000000..56defb6a --- /dev/null +++ b/src-qt5/core/libLumina/LVideoLabel.h @@ -0,0 +1,42 @@ +#ifndef LVIDEOLABEL_H +#define LVIDEOLABEL_H + +#include <QLabel> +#include <QMediaPlayer> +#include <QTimer> +#include <QResizeEvent> +#include "LVideoSurface.h" + +class LVideoLabel : public QLabel{ + Q_OBJECT + public: + LVideoLabel(QString, bool, QWidget* parent=NULL); + ~LVideoLabel(); + void enableIcons(); + void disableIcons(); + + protected: + void enterEvent(QEvent*); + void leaveEvent(QEvent*); + void resizeEvent(QResizeEvent*); + + signals: + void rollOver(); + void frameReceived(QPixmap); + + private slots: + void initializeBackend(); + void stopVideo(QPixmap); + void setDuration(QMediaPlayer::MediaStatus); + void stateChanged(QMediaPlayer::State); + + private: + QMediaPlayer *mediaPlayer; + LVideoSurface *surface; + QPixmap thumbnail; + QPixmap defaultThumbnail; + bool entered; + bool icons; + QString filepath; +}; +#endif diff --git a/src-qt5/core/libLumina/LVideoLabel.pri b/src-qt5/core/libLumina/LVideoLabel.pri new file mode 100644 index 00000000..06395c8d --- /dev/null +++ b/src-qt5/core/libLumina/LVideoLabel.pri @@ -0,0 +1,13 @@ +QT *= multimedia + +HEADERS *= $${PWD}/LVideoLabel.h +HEADERS *= $${PWD}/LVideoSurface.h +HEADERS *= $${PWD}/LVideoWidget.h +SOURCES *= $${PWD}/LVideoLabel.cpp +SOURCES *= $${PWD}/LVideoSurface.cpp +SOURCES *= $${PWD}/LVideoWidget.cpp + +INCLUDEPATH *= ${PWD} + +#Now the other dependendies of it +#include(LUtils.pri) diff --git a/src-qt5/core/libLumina/LVideoSurface.cpp b/src-qt5/core/libLumina/LVideoSurface.cpp new file mode 100644 index 00000000..3aaa81f0 --- /dev/null +++ b/src-qt5/core/libLumina/LVideoSurface.cpp @@ -0,0 +1,60 @@ +#include "LVideoSurface.h" +#include <QDebug> + +LVideoSurface::LVideoSurface(QObject *parent) : QAbstractVideoSurface(parent) { + frameImage = QPixmap(); + entered = false; +} + +bool LVideoSurface::present(const QVideoFrame &frame) { + //qDebug() << surfaceFormat().frameSize() << frame.size(); + if(!frameImage.isNull() && !entered) { + emit frameReceived(frameImage); + return true; + } + + if(frame.isValid()) { + //qDebug() << "Recording Frame"; + //qDebug() << surfaceFormat().frameSize() << frame.size(); + QVideoFrame icon(frame); + icon.map(QAbstractVideoBuffer::ReadOnly); + QImage img(icon.bits(), icon.width(), icon.height(), icon.bytesPerLine(), QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat())); + + if((frameImage.isNull() && !entered) or entered) + frameImage = QPixmap::fromImage(img.copy(img.rect())); + + icon.unmap(); + emit frameReceived(frameImage); + return true; + } + return false; +} + +QList<QVideoFrame::PixelFormat> LVideoSurface::supportedPixelFormats(QAbstractVideoBuffer::HandleType type = QAbstractVideoBuffer::NoHandle) const { + Q_UNUSED(type); + return QList<QVideoFrame::PixelFormat>() << QVideoFrame::Format_ARGB32 << QVideoFrame::Format_RGB32 << QVideoFrame::Format_RGB24 + << QVideoFrame::Format_RGB565 << QVideoFrame::Format_RGB555 << QVideoFrame::Format_BGRA32 << QVideoFrame::Format_BGR32; +} + +void LVideoSurface::stop() { + QAbstractVideoSurface::stop(); +} + +void LVideoSurface::switchRollOver() { + entered = !entered; +} + +bool LVideoSurface::start(const QVideoSurfaceFormat &format) { + const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat()); + const QSize size = format.frameSize(); + + //QVideoSurfaceFormat newFormat = format; + //Shrink the frames passed through the format to a smaller, thumbnail appropriate size and increase the frame rate + //newFormat.setFrameSize(258,258); + //newFormat.setFrameRate(90); + + if (imageFormat != QImage::Format_Invalid && !size.isEmpty()) + QAbstractVideoSurface::start(format); + + return (imageFormat != QImage::Format_Invalid && !size.isEmpty()); +} diff --git a/src-qt5/core/libLumina/LVideoSurface.h b/src-qt5/core/libLumina/LVideoSurface.h new file mode 100644 index 00000000..7a3dcaad --- /dev/null +++ b/src-qt5/core/libLumina/LVideoSurface.h @@ -0,0 +1,26 @@ +#ifndef LVIDEOSURFACE_H +#define LVIDEOSURFACE_H + +#include <QAbstractVideoSurface> +#include <QVideoSurfaceFormat> +#include <QPixmap> +#include <QDebug> + +class LVideoSurface : public QAbstractVideoSurface { + Q_OBJECT + + public: + LVideoSurface(QObject *parent=0); + virtual bool present(const QVideoFrame&); + virtual QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType) const; + bool start(const QVideoSurfaceFormat &format); + void stop(); + signals: + void frameReceived(QPixmap); + public slots: + void switchRollOver(); + private: + QPixmap frameImage; + bool entered; +}; +#endif diff --git a/src-qt5/core/libLumina/LVideoSurface.pri b/src-qt5/core/libLumina/LVideoSurface.pri new file mode 100644 index 00000000..469b8c93 --- /dev/null +++ b/src-qt5/core/libLumina/LVideoSurface.pri @@ -0,0 +1,9 @@ +QT *= multimedia + +HEADERS *= $${PWD}/LVideoSurface.h +SOURCES *= $${PWD}/LVideoSurface.cpp + +INCLUDEPATH *= ${PWD} + +#Now the other dependendies of it +#include(LUtils.pri) diff --git a/src-qt5/core/libLumina/LVideoWidget.cpp b/src-qt5/core/libLumina/LVideoWidget.cpp new file mode 100644 index 00000000..f1f74414 --- /dev/null +++ b/src-qt5/core/libLumina/LVideoWidget.cpp @@ -0,0 +1,38 @@ +#include "LVideoWidget.h" + +LVideoWidget::LVideoWidget(QString file, QSize iconSize, bool icons, QWidget *parent) : QWidget(parent) { + iconLabel = new LVideoLabel(file, icons, parent); + textLabel = new QLabel(parent); + + layout = new QHBoxLayout(this); + layout->setAlignment(Qt::AlignLeft | Qt::AlignCenter); + layout->setContentsMargins(5,5,5,5); + layout->setStretchFactor(textLabel, 1); //make sure this always occupies all extra space + + textLabel->setText(file.section("/", -1)); + iconLabel->setGeometry(QRect(QPoint(0,0), iconSize)); + iconLabel->setFixedSize(iconSize); + iconLabel->setVisible(true); + textLabel->setVisible(true); + + layout->addWidget(iconLabel); + layout->addWidget(textLabel); +} + +LVideoWidget::~LVideoWidget() { + delete iconLabel; + delete textLabel; + delete layout; +} + +void LVideoWidget::setIconSize(QSize iconSize) { + iconLabel->setFixedSize(iconSize); +} + +void LVideoWidget::enableIcons() { + iconLabel->enableIcons(); +} + +void LVideoWidget::disableIcons() { + iconLabel->disableIcons(); +} diff --git a/src-qt5/core/libLumina/LVideoWidget.h b/src-qt5/core/libLumina/LVideoWidget.h new file mode 100644 index 00000000..610fd9e5 --- /dev/null +++ b/src-qt5/core/libLumina/LVideoWidget.h @@ -0,0 +1,22 @@ +#ifndef LVIDEOWIDGET_H +#define LVIDEOWIDGET_H + +#include "LVideoLabel.h" +#include <QHBoxLayout> +#include <QResizeEvent> + +class LVideoWidget : public QWidget { + Q_OBJECT + public: + LVideoWidget(QString, QSize, bool icons, QWidget* parent=NULL); + ~LVideoWidget(); + void setIconSize(QSize); + void disableIcons(); + void enableIcons(); + + private: + LVideoLabel *iconLabel; + QLabel *textLabel; + QHBoxLayout *layout; +}; +#endif diff --git a/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp b/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp index b9346565..29a58ec9 100644 --- a/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp +++ b/src-qt5/core/libLumina/LuminaOS-FreeBSD.cpp @@ -27,12 +27,12 @@ QString LOS::SysPrefix(){ return "/usr/"; } //Prefix for system QString LOS::ControlPanelShortcut(){ return "/usr/local/share/applications/pccontrol.desktop"; } //system control panel QString LOS::AppStoreShortcut(){ return "/usr/local/share/applications/appcafe.desktop"; } //graphical app/pkg manager //OS-specific RSS feeds (Format: QStringList[ <name>::::<url> ]; ) -QStringList LOS::RSSFeeds(){ +QStringList LOS::RSSFeeds(){ QStringList feeds; feeds << "FreeBSD News Feed::::https://www.freebsd.org/news/rss.xml"; feeds << "TrueOS News Feed::::http://www.trueos.org/?feed=rss2"; return feeds; - } + } // ==== ExternalDevicePaths() ==== QStringList LOS::ExternalDevicePaths(){ @@ -59,6 +59,25 @@ QStringList LOS::ExternalDevicePaths(){ i--; } } + //Also add info about anything in the "/media" directory + QDir media("/media"); + QFileInfoList list = media.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, QDir::Type | QDir::Name); + //qDebug() << "Media files found:" << list.length(); + for(int i=0; i<list.length(); i++){ + //qDebug() << "Found media entry:" << list[i].fileName(); + if(list[i].isDir()){ + devs << "UNKNOWN::::::::/media/"+list[i].fileName(); + }else if(list[i].fileName().endsWith(".desktop")){ + QString type = list[i].fileName().section(".desktop",0,-2); + //Determine the type of hardware device based on the dev node + if(type.startsWith("da")){ type = "USB"; } + else if(type.startsWith("ada")){ type = "HDRIVE"; } + else if(type.startsWith("mmsd")){ type = "SDCARD"; } + else if(type.startsWith("cd")||type.startsWith("acd")){ type="DVD"; } + else{ type = "UNKNOWN"; } + devs << type+"::::::::/media/"+list[i].fileName(); + } + } return devs; } diff --git a/src-qt5/core/libLumina/LuminaOS.h b/src-qt5/core/libLumina/LuminaOS.h index e7a72129..98137816 100644 --- a/src-qt5/core/libLumina/LuminaOS.h +++ b/src-qt5/core/libLumina/LuminaOS.h @@ -5,8 +5,8 @@ // See the LICENSE file for full details //=========================================== // This is the main interface for any OS-specific system calls -// To port Lumina to a different operating system, just create a file -// called "LuminaOS-<Operating System>.cpp", and use that file in +// To port Lumina to a different operating system, just create a file +// called "LuminaOS-<Operating System>.cpp", and use that file in // the project (libLumina.pro) instead of LuminaOS-FreeBSD.cpp //=========================================== #ifndef _LUMINA_LIBRARY_OS_H @@ -23,7 +23,7 @@ class LOS{ public: //Return the name of the OS being used - static QString OSName(); + static QString OSName(); //OS-specific prefix(s) static QString LuminaShare(); //Install dir for Lumina share files @@ -34,7 +34,7 @@ public: static QString ControlPanelShortcut(); static QString AppStoreShortcut(); - //OS-specific RSS feeds + //OS-specific RSS feeds static QStringList RSSFeeds(); //Return Format: QStringList[ <name>::::<url> ]; //Scan for mounted external devices @@ -81,13 +81,13 @@ public: static bool batteryIsCharging(); //Battery Time Remaining static int batterySecondsLeft(); //Returns: estimated number of seconds remaining - + //Get the checksum for a file static QStringList Checksums(QStringList filepaths); //Return: checksum of each input file (same order) - + //Get the filesystem capacity static QString FileSystemCapacity(QString dir) ; //Return: percentage capacity as give by the df command - + //System CPU Information static QStringList CPUTemperatures(); //Returns: List containing the temperature of any CPU's ("50C" for example) static int CPUUsagePercent(); //Returns: Overall percentage of the amount of CPU cycles in use (-1 for errors) diff --git a/src-qt5/core/libLumina/LuminaSingleApplication.cpp b/src-qt5/core/libLumina/LuminaSingleApplication.cpp index 6811d147..5d276805 100644 --- a/src-qt5/core/libLumina/LuminaSingleApplication.cpp +++ b/src-qt5/core/libLumina/LuminaSingleApplication.cpp @@ -19,7 +19,7 @@ LSingleApplication::LSingleApplication(int &argc, char **argv, QString appname) if(appname!="lumina-desktop"){ cTrans = LUtils::LoadTranslation(this, appname); }//save the translator for later //Initialize a couple convenience internal variables cfile = QDir::tempPath()+"/.LSingleApp-%1-%2-%3"; - QString username = QString(getlogin()); + QString username = QString(getuid()); //For locking the process use the official process name - not the user input (no masking) appname = this->applicationName(); cfile = cfile.arg( username, appname, QString::number(QX11Info::appScreen()) ); diff --git a/src-qt5/core/libLumina/LuminaThemes.cpp b/src-qt5/core/libLumina/LuminaThemes.cpp index ddbc7b37..857e604b 100644 --- a/src-qt5/core/libLumina/LuminaThemes.cpp +++ b/src-qt5/core/libLumina/LuminaThemes.cpp @@ -25,42 +25,42 @@ QStringList LTHEME::availableSystemThemes(){ //returns: [name::::path] for each item - QDir dir(LOS::LuminaShare()+"themes"); - QStringList list = dir.entryList(QStringList() <<"*.qss.template", QDir::Files, QDir::Name); + QDir dir(LOS::LuminaShare()+"../lthemeengine/desktop_qss"); + QStringList list = dir.entryList(QStringList() <<"*.qss", QDir::Files, QDir::Name); for(int i=0; i<list.length(); i++){ //Format the output entry [<name>::::<fullpath>] - list[i] = list[i].section(".qss.",0,0)+"::::"+dir.absoluteFilePath(list[i]); + list[i] = list[i].section(".qss",0,0)+"::::"+dir.absoluteFilePath(list[i]); } return list; } QStringList LTHEME::availableLocalThemes(){ //returns: [name::::path] for each item - QDir dir( QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/themes"); - QStringList list = dir.entryList(QStringList() <<"*.qss.template", QDir::Files, QDir::Name); + QDir dir( QString(getenv("XDG_CONFIG_HOME"))+"/lthemeengine/desktop_qss"); + QStringList list = dir.entryList(QStringList() <<"*.qss", QDir::Files, QDir::Name); for(int i=0; i<list.length(); i++){ //Format the output entry [<name>::::<fullpath>] - list[i] = list[i].section(".qss.",0,0)+"::::"+dir.absoluteFilePath(list[i]); + list[i] = list[i].section(".qss",0,0)+"::::"+dir.absoluteFilePath(list[i]); } return list; } QStringList LTHEME::availableSystemColors(){ //returns: [name::::path] for each item //returns: [name::::path] for each item - QDir dir(LOS::LuminaShare()+"colors"); - QStringList list = dir.entryList(QStringList() <<"*.qss.colors", QDir::Files, QDir::Name); + QDir dir(LOS::LuminaShare()+"../lthemeengine/colors"); + QStringList list = dir.entryList(QStringList() <<"*.conf", QDir::Files, QDir::Name); for(int i=0; i<list.length(); i++){ //Format the output entry [<name>::::<fullpath>] - list[i] = list[i].section(".qss.",0,0)+"::::"+dir.absoluteFilePath(list[i]); + list[i] = list[i].section(".conf",0,0)+"::::"+dir.absoluteFilePath(list[i]); } return list; } QStringList LTHEME::availableLocalColors(){ //returns: [name::::path] for each item - QDir dir(QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/colors"); - QStringList list = dir.entryList(QStringList() <<"*.qss.colors", QDir::Files, QDir::Name); + QDir dir(QString(getenv("XDG_CONFIG_HOME"))+"/lthemeengine/colors"); + QStringList list = dir.entryList(QStringList() <<"*.conf", QDir::Files, QDir::Name); for(int i=0; i<list.length(); i++){ //Format the output entry [<name>::::<fullpath>] - list[i] = list[i].section(".qss.",0,0)+"::::"+dir.absoluteFilePath(list[i]); + list[i] = list[i].section(".conf",0,0)+"::::"+dir.absoluteFilePath(list[i]); } return list; } @@ -122,15 +122,21 @@ QStringList LTHEME::availableSystemCursors(){ //returns: [name] for each item //Save a new theme/color file bool LTHEME::saveLocalTheme(QString name, QStringList contents){ - QString localdir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/themes/"; - if(!QFile::exists(localdir)){ QDir dir; dir.mkpath(localdir); } - return LUtils::writeFile(localdir+name+".qss.template", contents, true); + Q_UNUSED(name); + Q_UNUSED(contents); + return false; //old format - do not use!! + //QString localdir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/themes/"; + //if(!QFile::exists(localdir)){ QDir dir; dir.mkpath(localdir); } + //return LUtils::writeFile(localdir+name+".qss.template", contents, true); } bool LTHEME::saveLocalColors(QString name, QStringList contents){ - QString localdir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/colors/"; - if(!QFile::exists(localdir)){ QDir dir; dir.mkpath(localdir); } - return LUtils::writeFile(localdir+name+".qss.colors", contents, true); + Q_UNUSED(name); + Q_UNUSED(contents); + return false; //old format - do not use!! + // QString localdir = QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/colors/"; + //if(!QFile::exists(localdir)){ QDir dir; dir.mkpath(localdir); } + //return LUtils::writeFile(localdir+name+".qss.colors", contents, true); } //Return the currently selected Theme/Colors/Icons @@ -180,23 +186,25 @@ QString LTHEME::currentCursor(){ //Change the current Theme/Colors/Icons bool LTHEME::setCurrentSettings(QString themepath, QString colorpath, QString iconname, QString font, QString fontsize){ + Q_UNUSED(font); + Q_UNUSED(fontsize); //QIcon::setThemeName(iconname); + //Save these settings into the theme engine settings QSettings engineset("lthemeengine","lthemeengine"); engineset.setValue("Appearance/icon_theme", iconname); - //engineset.setValue("Appearance/color_scheme_path", colorpath); //re-enable this once the color scheme has been synced with lthemeengine - //Need to add theme path saving here too later - - + engineset.setValue("Appearance/custom_palette", QFile::exists(colorpath) ); + engineset.setValue("Appearance/color_scheme_path", colorpath); + engineset.setValue("Interface/desktop_stylesheets", QStringList() << themepath); + return true; //Now save the theme settings file - QStringList contents; + /*QStringList contents; contents << "THEMEFILE="+themepath; contents << "COLORFILE="+colorpath; contents << "ICONTHEME="+iconname; contents << "FONTFAMILY="+font; contents << "FONTSIZE="+fontsize; bool ok = LUtils::writeFile(QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/themesettings.cfg", contents, true); - - return ok; + return ok;*/ } //Change the current Cursor Theme @@ -299,13 +307,13 @@ QStringList LTHEME::cursorInformation(QString name){ } } return out; -} +} QStringList LTHEME::CustomEnvSettings(bool useronly){ //view all the key=value settings QStringList newinfo; if(!useronly){ QStringList sysfiles; sysfiles << L_ETCDIR+"/lumina_environment.conf" << LOS::LuminaShare()+"lumina_environment.conf"; - for(int i=0; i<sysfiles.length() && newinfo.isEmpty(); i++){ + for(int i=0; i<sysfiles.length() && newinfo.isEmpty(); i++){ newinfo << LUtils::readFile(sysfiles[i]); } } diff --git a/src-qt5/core/libLumina/LuminaThemes.h b/src-qt5/core/libLumina/LuminaThemes.h index 39602f58..ca79e0bd 100644 --- a/src-qt5/core/libLumina/LuminaThemes.h +++ b/src-qt5/core/libLumina/LuminaThemes.h @@ -34,7 +34,7 @@ public: //Save a new theme/color file static bool saveLocalTheme(QString name, QStringList contents); static bool saveLocalColors(QString name, QStringList contents); - + //Return the currently selected Theme/Colors/Icons static QStringList currentSettings(); //returns [theme path, colorspath, iconsname, font, fontsize] static QString currentCursor(); //returns: current cursor theme name @@ -45,16 +45,16 @@ public: //Return the complete stylesheet for a given theme/colors static QString assembleStyleSheet(QString themepath, QString colorpath, QString font, QString fontsize); - + //Additional info for a cursor theme static QStringList cursorInformation(QString name); //returns: [Name, Comment, Sample Image File] - + //Environment settings static QStringList CustomEnvSettings(bool useronly = false); //view all the key=value settings static void LoadCustomEnvSettings(); //will push the custom settings into the environment (recommended before loading the initial QApplication) static bool setCustomEnvSetting(QString var, QString val); //variable/value pair (use an empty val to clear it) static QString readCustomEnvSetting(QString var); - + }; // Qt Style override to allow custom themeing/colors diff --git a/src-qt5/core/libLumina/LuminaXDG.cpp b/src-qt5/core/libLumina/LuminaXDG.cpp index ab1000ab..cf9e0af2 100644 --- a/src-qt5/core/libLumina/LuminaXDG.cpp +++ b/src-qt5/core/libLumina/LuminaXDG.cpp @@ -72,6 +72,7 @@ void XDGDesktop::sync(){ QString loc = var.section("[",1,1).section("]",0,0).simplified(); // localization var = var.section("[",0,0).simplified(); //remove the localization QString val = line.section("=",1,50).simplified(); + if( val.count("\"")==2 && val.startsWith("\"") && val.endsWith("\"")){ val.chop(1); val = val.remove(0,1); } //remove the starting/ending quotes //------------------- if(var=="Name"){ if(insection){ @@ -631,7 +632,7 @@ void XDGDesktopList::populateMenu(QMenu *topmenu, bool byCategory){ void LFileInfo::loadExtraInfo(){ desk = 0; //Now load the extra information - if(this->isDir()){ + if( this->suffix().isEmpty() && (this->absoluteFilePath().startsWith("/net/") || this->isDir()) ){ mime = "inode/directory"; //Special directory icons QString name = this->fileName().toLower(); @@ -644,6 +645,7 @@ void LFileInfo::loadExtraInfo(){ else if(name=="downloads"){ icon = "folder-downloads"; } else if(name=="documents"){ icon = "folder-documents"; } else if(name=="images" || name=="pictures"){ icon = "folder-image"; } + else if(this->absoluteFilePath().startsWith("/net/")){ icon = "folder-shared"; } else if( !this->isReadable() ){ icon = "folder-locked"; } }else if( this->suffix()=="desktop"){ mime = "application/x-desktop"; @@ -664,11 +666,11 @@ LFileInfo::LFileInfo(){ LFileInfo::LFileInfo(QString filepath){ //overloaded contructor this->setFile(filepath); loadExtraInfo(); -} +} LFileInfo::LFileInfo(QFileInfo info){ //overloaded contructor this->swap(info); //use the given QFileInfo without re-loading it loadExtraInfo(); -} +} //Functions for accessing the extra information // -- Return the mimetype for the file @@ -683,7 +685,7 @@ QString LFileInfo::iconfile(){ return icon; }else{ if(!mime.isEmpty()){ - QString tmp = mime; + QString tmp = mime; tmp.replace("/","-"); return tmp; }else if(this->isExecutable()){ @@ -696,7 +698,7 @@ QString LFileInfo::iconfile(){ // -- Check if this is an XDG desktop file bool LFileInfo::isDesktopFile(){ if(desk==0){ return false; } - return (!desk->filePath.isEmpty()); + return (!desk->filePath.isEmpty()); } // -- Allow access to the XDG desktop data structure @@ -726,11 +728,14 @@ bool LFileInfo::isAVFile(){ //==== LXDG Functions ==== bool LXDG::checkExec(QString exec){ //Return true(good) or false(bad) + //Check for quotes around the exec, and remove them as needed + if(exec.startsWith("\"") && exec.count("\"")>=2){ exec = exec.section("\"",1,1).simplified(); } + if(exec.startsWith("\'") && exec.count("\'")>=2){ exec = exec.section("\'",1,1).simplified(); } if(exec.startsWith("/")){ return QFile::exists(exec); } else{ QStringList paths = QString(getenv("PATH")).split(":"); for(int i=0; i<paths.length(); i++){ - if(QFile::exists(paths[i]+"/"+exec)){ return true; } + if(QFile::exists(paths[i]+"/"+exec)){ return true; } } } return false; //could not find the executable in the current path(s) @@ -747,7 +752,7 @@ QStringList LXDG::systemApplicationDirs(){ for(int i=0; i<appDirs.length(); i++){ if( QFile::exists(appDirs[i]+"/applications") ){ out << appDirs[i]+"/applications"; - //Also check any subdirs within this directory + //Also check any subdirs within this directory // (looking at you KDE - stick to the standards!!) out << LUtils::listSubDirectories(appDirs[i]+"/applications"); } @@ -891,7 +896,7 @@ QIcon LXDG::findIcon(QString iconName, QString fallback){ fall << getChildIconDirs(paths[i]+"hicolor"); //XDG fallback (apps add to this) } //Now load all the icon theme dependencies in order (Theme1 -> Theme2 -> Theme3 -> Fallback) - + //fall << LOS::AppPrefix()+"share/pixmaps"; //always use this as well as a final fallback QDir::setSearchPaths("icontheme", theme); QDir::setSearchPaths("default", oxy); @@ -926,7 +931,7 @@ QIcon LXDG::findIcon(QString iconName, QString fallback){ //simple PNG image - load directly into the QIcon structure ico.addFile(srch[i]+":"+iconName+".png"); } - + } //If still no icon found, look for any image format in the "pixmaps" directory if(ico.isNull()){ @@ -946,13 +951,13 @@ QIcon LXDG::findIcon(QString iconName, QString fallback){ break; } } - + } } //Use the fallback icon if necessary if(ico.isNull() ){ if(!fallback.isEmpty()){ ico = LXDG::findIcon(fallback,""); } - else if(iconName.contains("-x-") && !iconName.endsWith("-x-generic")){ + else if(iconName.contains("-x-") && !iconName.endsWith("-x-generic")){ //mimetype - try to use the generic type icon ico = LXDG::findIcon(iconName.section("-x-",0,0)+"-x-generic", ""); } @@ -969,7 +974,7 @@ QStringList LXDG::getChildIconDirs(QString parent){ QDir D(parent); QStringList out; QStringList dirs = D.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name); - if(!dirs.isEmpty() && (dirs.contains("32x32") || dirs.contains("scalable")) ){ + if(!dirs.isEmpty() && (dirs.contains("32x32") || dirs.contains("scalable")) ){ //Need to sort these directories by image size //qDebug() << " - Parent:" << parent << "Dirs:" << dirs; for(int i=0; i<dirs.length(); i++){ @@ -1017,7 +1022,7 @@ QStringList LXDG::systemMimeDirs(){ QStringList out; for(int i=0; i<appDirs.length(); i++){ if( QFile::exists(appDirs[i]+"/mime") ){ - out << appDirs[i]+"/mime"; + out << appDirs[i]+"/mime"; } } return out; @@ -1028,7 +1033,7 @@ QIcon LXDG::findMimeIcon(QString extension){ QString mime = LXDG::findAppMimeForFile(extension); if(mime.isEmpty()){ mime = LXDG::findAppMimeForFile(extension.toLower()); } mime.replace("/","-"); //translate to icon mime name - if(!mime.isEmpty()){ ico = LXDG::findIcon(mime, "unknown");} //use the "unknown" mimetype icon as fallback + if(!mime.isEmpty()){ ico = LXDG::findIcon(mime, "unknown");} //use the "unknown" mimetype icon as fallback if(ico.isNull()){ ico = LXDG::findIcon("unknown",""); } //just in case return ico; } @@ -1050,8 +1055,8 @@ while(mimes.isEmpty()){ return extension; } //Look for globs at the end of the filename - if(!extension.isEmpty()){ - mimes = mimefull.filter(":*."+extension); + if(!extension.isEmpty()){ + mimes = mimefull.filter(":*."+extension); //If nothing found, try a case-insensitive search if(mimes.isEmpty()){ mimes = mimefull.filter(":*."+extension, Qt::CaseInsensitive); } //Now ensure that the filter was accurate (*.<extention>.<something> will still be caught) @@ -1062,7 +1067,7 @@ while(mimes.isEmpty()){ } } //Look for globs at the start of the filename - if(mimes.isEmpty()){ + if(mimes.isEmpty()){ mimes = mimefull.filter(":"+filename.left(2)); //look for the first 2 characters initially //Note: This initial filter will only work if the wildcard (*) is not within the first 2 characters of the pattern //Now ensure that the filter was accurate diff --git a/src-qt5/core/libLumina/RootSubWindow-animations.cpp b/src-qt5/core/libLumina/obsolete/RootSubWindow-animations.cpp index efab20fe..efab20fe 100644 --- a/src-qt5/core/libLumina/RootSubWindow-animations.cpp +++ b/src-qt5/core/libLumina/obsolete/RootSubWindow-animations.cpp diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/obsolete/RootSubWindow.cpp index 5fb8ece4..5040f2f9 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/obsolete/RootSubWindow.cpp @@ -242,6 +242,16 @@ void RootSubWindow::enableFrame(bool on){ WIN->setProperty(NativeWindow::FrameExtents, QVariant::fromValue< QList<int> >(extents) ); //save to structure now } +void RootSubWindow::enableFrame(QList<NativeWindow::Type> types){ + static QList<NativeWindow::Type> noframe; + if(noframe.isEmpty()){ noframe << NativeWindow::T_DESKTOP << NativeWindow::T_DOCK << NativeWindow::T_TOOLBAR << NativeWindow::T_MENU << NativeWindow::T_SPLASH << NativeWindow::T_DROPDOWN_MENU << NativeWindow::T_POPUP_MENU << NativeWindow::T_TOOLTIP << NativeWindow::T_NOTIFICATION << NativeWindow::T_COMBO << NativeWindow::T_DND; } + for(int i=0; i<types.length(); i++){ + if(noframe.contains(types[i])){ enableFrame(false); return; } + } + enableFrame(true); + //Now make buttons visible as appropriate for the type + //NativeWindow::T_UTILITY, NativeWindow::T_DIALOG, , NativeWindow::T_NORMAL +} void RootSubWindow::LoadProperties( QList< NativeWindow::Property> list){ QList<QVariant> vals; //Always ensure that visibility changes are evaluated last @@ -370,7 +380,7 @@ void RootSubWindow::propertiesChanged(QList<NativeWindow::Property> props, QList switch(props[i]){ case NativeWindow::Visible: if(!WinWidget->isPaused() && (this->isVisible()!=vals[i].toBool()) && activeState==Normal ){ - qDebug() << "Got Visibility Change:" << vals[i] << this->geometry() << WIN->geometry(); + //qDebug() << "Got Visibility Change:" << vals[i] << this->geometry() << WIN->geometry(); if(vals[i].toBool()){ loadAnimation( DesktopSettings::instance()->value(DesktopSettings::Animation, "window/appear", "random").toString(), NativeWindow::Visible, vals[i]); } else{ loadAnimation( DesktopSettings::instance()->value(DesktopSettings::Animation, "window/disappear", "random").toString(), NativeWindow::Visible, vals[i]); } } @@ -397,7 +407,7 @@ void RootSubWindow::propertiesChanged(QList<NativeWindow::Property> props, QList i--; }else if(!WinWidget->isPaused() && activeState==Normal){ if(WIN->property(NativeWindow::Size).toSize() != WinWidget->size()){ - qDebug() << "Got Direct Geometry Change:" << WIN->geometry(); + //qDebug() << "Got Direct Geometry Change:" << WIN->geometry(); this->setGeometry( QRect(this->geometry().topLeft(), WIN->geometry().size()) ); WinWidget->resyncWindow(); } @@ -434,8 +444,8 @@ void RootSubWindow::propertiesChanged(QList<NativeWindow::Property> props, QList mainLayout->setContentsMargins( vals[i].value< QList<int> >().at(0),vals[i].value< QList<int> >().at(2) - titleLabel->height(),vals[i].value< QList<int> >().at(1),vals[i].value< QList<int> >().at(3)); break;*/ case NativeWindow::WinTypes: - qDebug() << "Got Window Types:" << vals[i].value< QList<NativeWindow::Type> >(); - enableFrame(vals[i].value< QList<NativeWindow::Type> >().contains(NativeWindow::T_NORMAL) ); + //qDebug() << "Got Window Types:" << vals[i].value< QList<NativeWindow::Type> >(); + enableFrame(vals[i].value< QList<NativeWindow::Type> >() ); break; default: qDebug() << "Window Property Unused:" << props[i] << vals[i]; diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/obsolete/RootSubWindow.h index c1964724..598298e2 100644 --- a/src-qt5/core/libLumina/RootSubWindow.h +++ b/src-qt5/core/libLumina/obsolete/RootSubWindow.h @@ -59,12 +59,14 @@ private: void initWindowFrame(); void enableFrame(bool); + void enableFrame(QList<NativeWindow::Type> types); void LoadProperties( QList< NativeWindow::Property> list); static QStringList validAnimations(NativeWindow::Property); public slots: + void ensureVisible(){ WIN->setProperty(NativeWindow::Visible, true); } void giveMouseFocus(){ WinWidget->raiseWindow(); } void removeMouseFocus(){ WinWidget->lowerWindow(); } void giveKeyboardFocus(){ WIN->requestProperty(NativeWindow::Active, true, true); } diff --git a/src-qt5/core/libLumina/RootWindow-mgmt.cpp b/src-qt5/core/libLumina/obsolete/RootWindow-mgmt.cpp index 24ea639b..24ea639b 100644 --- a/src-qt5/core/libLumina/RootWindow-mgmt.cpp +++ b/src-qt5/core/libLumina/obsolete/RootWindow-mgmt.cpp diff --git a/src-qt5/core/libLumina/RootWindow.cpp b/src-qt5/core/libLumina/obsolete/RootWindow.cpp index fdbc1eb8..705297be 100644 --- a/src-qt5/core/libLumina/RootWindow.cpp +++ b/src-qt5/core/libLumina/obsolete/RootWindow.cpp @@ -239,7 +239,9 @@ void RootWindow::NewWindow(NativeWindow *win){ connect(subwin, SIGNAL(windowAnimFinished()), this, SLOT(checkMouseFocus()) ); WINDOWS << subwin; } + //QApplication::processEvents(); CheckWindowPosition(win->id(), true); //first-time run + //QTimer::singleShot(300, subwin, SLOT(ensureVisible())); win->setProperty(NativeWindow::Visible, true); //win->requestProperty( NativeWindow::Active, true); //win->requestProperties(QList<NativeWindow::Property>() << NativeWindow::Visible << NativeWindow::Active, QList<QVariant>() << true << true, true); diff --git a/src-qt5/core/libLumina/RootWindow.h b/src-qt5/core/libLumina/obsolete/RootWindow.h index c5cd44a0..c5cd44a0 100644 --- a/src-qt5/core/libLumina/RootWindow.h +++ b/src-qt5/core/libLumina/obsolete/RootWindow.h diff --git a/src-qt5/core/libLumina/RootWindow.pri b/src-qt5/core/libLumina/obsolete/RootWindow.pri index 9426b6b4..9426b6b4 100644 --- a/src-qt5/core/libLumina/RootWindow.pri +++ b/src-qt5/core/libLumina/obsolete/RootWindow.pri diff --git a/src-qt5/core/lumina-checkpass/main.c b/src-qt5/core/lumina-checkpass/main.c index e12e7c78..2f54c8e6 100644 --- a/src-qt5/core/lumina-checkpass/main.c +++ b/src-qt5/core/lumina-checkpass/main.c @@ -14,23 +14,56 @@ //=========================================== //Standard C libary #include <unistd.h> // Standard C +#include <stdlib.h> #include <stdio.h> // Usage output #include <pwd.h> // User DB information +#include <string.h> //PAM/security libraries #include <sys/types.h> #include <security/pam_appl.h> #include <security/openpam.h> +void showUsage(){ + puts("lumina-checkpass: Simple user-level check for password validity (for screen unlockers and such)."); + puts("Usage:"); + //puts(" lumina-checkpass <password>"); + puts(" lumina-checkpass -fd <file descriptor>"); + puts(" lumina-checkpass -f <file path>"); + puts("Returns: 0 for a valid password, 1 for invalid"); +} + int main(int argc, char** argv){ //Check the inputs - if(argc!=2){ + if(argc!=3){ //Invalid inputs - show the help text - puts("lumina-checkpass: Simple user-level check for password validity (for screen unlockers and such)."); - puts("Usage: lumina-checkpass <password>"); - puts("Returns: 0 for a valid password, 1 for invalid"); + showUsage(); return 1; } + char*pass = 0; + if(argc==3 && 0==strcmp(argv[1],"-fd") ){ + FILE *fp = fdopen(atoi(argv[2]), "r"); + size_t len; + if(fp!=0){ + ssize_t slen = getline(&pass, &len, fp); + if(pass[slen-1]=='\n'){ pass[slen-1] = '\0'; } + } + fclose(fp); + }else if(argc==3 && 0==strcmp(argv[1],"-f") ){ + FILE *fp = fopen(argv[2], "r"); + size_t len; + if(fp!=0){ + ssize_t slen = getline(&pass, &len, fp); + if(pass[slen-1]=='\n'){ pass[slen-1] = '\0'; } + }else{ + puts("[ERROR] Unknown option provided"); + puts("----------------"); + showUsage(); + return 1; + } + fclose(fp); + } + if(pass == 0){ puts("Could not read password!!"); return 1; } //error in reading password //Validate current user (make sure current UID matches the logged-in user, char* cUser = getlogin(); struct passwd *pwd = 0; @@ -44,7 +77,7 @@ int main(int argc, char** argv){ int ret = pam_start( "system", cUser, &pamc, &pamh); if(ret != PAM_SUCCESS){ return 1; } //could not init PAM //char* cPassword = argv[1]; - ret = pam_set_item(pamh, PAM_AUTHTOK, argv[1]); + ret = pam_set_item(pamh, PAM_AUTHTOK, pass); //Authenticate with PAM ret = pam_authenticate(pamh,0); //this can be true without verifying password if pam_self.so is used in the auth procedures (common) if( ret == PAM_SUCCESS ){ ret = pam_acct_mgmt(pamh,0); } //Check for valid, unexpired account and verify access restrictions diff --git a/src-qt5/core/lumina-desktop-unified/LSession.cpp b/src-qt5/core/lumina-desktop-unified/LSession.cpp index d70ff973..e1251c01 100644 --- a/src-qt5/core/lumina-desktop-unified/LSession.cpp +++ b/src-qt5/core/lumina-desktop-unified/LSession.cpp @@ -104,7 +104,7 @@ void LSession::setupSession(){ splash.showScreen("user"); if(DEBUG){ qDebug() << " - Init User Files:" << timer->elapsed();} //checkUserFiles(); //adds these files to the watcher as well - + Lumina::ROOTWIN->start(); //Initialize the internal variables //DESKTOPS.clear(); @@ -116,7 +116,6 @@ void LSession::setupSession(){ if(DEBUG){ qDebug() << " - Populate App List:" << timer->elapsed();} Lumina::APPLIST->updateList(); //appmenu = new AppMenu(); - splash.showScreen("menus"); //if(DEBUG){ qDebug() << " - Init SettingsMenu:" << timer->elapsed();} //settingsmenu = new SettingsMenu(); @@ -129,15 +128,16 @@ void LSession::setupSession(){ QList<QScreen*> scrns= QApplication::screens(); for(int i=0; i<scrns.length(); i++){ qDebug() << " --- Load Wallpaper for Screen:" << scrns[i]->name(); - Lumina::ROOTWIN->ChangeWallpaper(scrns[i]->name(), RootWindow::Stretch, LOS::LuminaShare()+"desktop-background.jpg"); + RootDesktopObject::instance()->ChangeWallpaper(scrns[i]->name(),QUrl::fromLocalFile(LOS::LuminaShare()+"desktop-background.jpg").toString() ); } - Lumina::ROOTWIN->start(); Lumina::NWS->setRoot_numberOfWorkspaces(QStringList() << "one" << "two"); Lumina::NWS->setRoot_currentWorkspace(0); + if(DEBUG){ qDebug() << " - Create Desktop Context Menu"; } - DesktopContextMenu *cmenu = new DesktopContextMenu(Lumina::ROOTWIN); + + /*DesktopContextMenu *cmenu = new DesktopContextMenu(Lumina::ROOTWIN); connect(cmenu, SIGNAL(showLeaveDialog()), this, SLOT(StartLogout()) ); - cmenu->start(); + cmenu->start();*/ //desktopFiles = QDir(QDir::homePath()+"/Desktop").entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs, QDir::Name | QDir::IgnoreCase | QDir::DirsFirst); //updateDesktops(); @@ -228,7 +228,9 @@ void LSession::setupGlobalConnections(){ //Root window connections connect(Lumina::ROOTWIN, SIGNAL(RegisterVirtualRoot(WId)), Lumina::NWS, SLOT(RegisterVirtualRoot(WId)) ); connect(Lumina::ROOTWIN, SIGNAL(RootResized(QRect)), Lumina::NWS, SLOT(setRoot_desktopGeometry(QRect)) ); - connect(Lumina::ROOTWIN, SIGNAL(MouseMoved()), Lumina::SS, SLOT(newInputEvent()) ); + connect(RootDesktopObject::instance(), SIGNAL(mouseMoved()), Lumina::SS, SLOT(newInputEvent()) ); + connect(RootDesktopObject::instance(), SIGNAL(startLogout()), this, SLOT(StartLogout()) ); + connect(RootDesktopObject::instance(), SIGNAL(lockScreen()), Lumina::SS, SLOT(LockScreenNow()) ); //Native Window Class connections connect(Lumina::NEF, SIGNAL(WindowCreated(WId)), Lumina::NWS, SLOT(NewWindowDetected(WId))); @@ -356,12 +358,12 @@ void LSession::launchStartupApps(){ void LSession::checkUserFiles(){ //internal version conversion examples: // [1.0.0 -> 1000000], [1.2.3 -> 1002003], [0.6.1 -> 6001] - QString OVS = DesktopSettings::instance()->value(DesktopSettings::System,"DesktopVersion","0").toString(); //Old Version String + /*QString OVS = DesktopSettings::instance()->value(DesktopSettings::System,"DesktopVersion","0").toString(); //Old Version String bool changed = LDesktopUtils::checkUserFiles(OVS); if(changed){ //Save the current version of the session to the settings file (for next time) DesktopSettings::instance()->setValue(DesktopSettings::System,"DesktopVersion", this->applicationVersion()); - } + }*/ } diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/LICENCE b/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/LICENCE deleted file mode 100644 index aa601d5e..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/LICENCE +++ /dev/null @@ -1,7 +0,0 @@ -These audio files are BSD-licensed and were created/owned by the TrueOS Project: - - Login.ogg - - Logout.ogg - -These audio files are freely available on jewelbeat.com: -"Music by JewelBeat. Download your free music and free sound effects at www.jewelbeat.com." - - low-battery.ogg (http://www.jewelbeat.com/free/free-sound-effects/musical%20effects/Tympani_2.mp3 - converted to OGG afterward) diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Login.ogg b/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Login.ogg Binary files differdeleted file mode 100644 index 43a07e27..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Login.ogg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Logout.ogg b/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Logout.ogg Binary files differdeleted file mode 100644 index e63ae07f..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/Logout.ogg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/low-battery.ogg b/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/low-battery.ogg Binary files differdeleted file mode 100644 index d129a2b3..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/audiofiles/low-battery.ogg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/lumina-desktop.desktop b/src-qt5/core/lumina-desktop-unified/extrafiles/lumina-desktop.desktop deleted file mode 100644 index 7d87f93a..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/lumina-desktop.desktop +++ /dev/null @@ -1,34 +0,0 @@ -[Desktop Entry] -Exec=start-lumina-desktop -TryExec=start-lumina-desktop -Icon=Lumina-DE -Type=Application -Name=Lumina -Name[de]=Lumina -Name[en_GB]=Lumina -Name[en_ZA]=Lumina -Name[et]=Lumina -Name[fr]=Lumina -Name[fr_CA]=Lumina -Name[hi]=ल्यूमिना -Name[ja]=Lumina -Name[mt]=Lumina -Name[pl]=Lumina -Name[pt_BR]=Lumina -Name[ru]=Lumina -Name[uk]=Lumina -Name[vi]=Lumina -Comment=A Lightweight Desktop for FreeBSD -Comment[de]=Eine leichtgewichtige Arbeitsplatzumgebung für FreeBSD -Comment[en_GB]=A Lightweight Desktop for FreeBSD -Comment[en_ZA]=A Lightweight Desktop for FreeBSD -Comment[et]=Minimalistlik töölauakeskkond FreeBSD-le -Comment[fr]=Un environnement bureau léger pour FreeBSD -Comment[fr_CA]=Un environnement bureau léger pour FreeBSD -Comment[hi]=एक हल्का डेस्कटॉप फ्री बी.एस.डी के लिए -Comment[ja]=FreeBSD の為に作られた軽快なデスクトップ環境 -Comment[mt]=A Desktop irqiq għal FreeBSD -Comment[pl]=Lekkie Środowisko graficzne dla FreeBSD -Comment[pt_BR]=Um ambiente de trabalho leve para FreeBSD -Comment[uk]=Легковісне оточення стільниці для FreeBSD -Comment[vi]=Một máy tính để bàn nhẹ cho FreeBSD diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Fireflies.json b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Fireflies.json new file mode 100644 index 00000000..c09de308 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Fireflies.json @@ -0,0 +1,26 @@ +{ + "name" : { + "default" : "Fireflies" + }, + "description" : { + "default" : "Dancing balls of light on the screen" + }, + "author" : { + "name" : "Ken Moore", + "email" : "ken@ixsystems.com", + "website" : "https://github.com/beanpole135", + "company" : "iXsystems", + "company_website" : "http://ixsystems.com" + }, + "meta" : { + "license" : "3-clause BSD", + "license_url" : "https://github.com/trueos/lumina/blob/master/LICENSE", + "copyright" : "Copyright (c) 2017, Ken Moore (ken@ixsystems.com)", + "date_created" : "20171010", + "version" : "1.0" + }, + "qml" : { + "exec" : "qml_scripts/Fireflies.qml", + "additional_files" : ["qml_scripts/Firefly.qml"] + } +} diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/README.md b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/README.md new file mode 100644 index 00000000..d9093b44 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/README.md @@ -0,0 +1,79 @@ +## Screensaver Format +The screensaver system for the Lumina desktop allows for the creation and use of scripts written in the QML language, with a number of screensavers and other examples installed out-of-box. There are only a couple warnings/caveats to consider when developing a new screensaver: + +1. The root object in your QML script will be automatically sized to fit the screen as needed. Avoid trying to hard-code specific screen dimensions within your script as it will not work properly. +2. A JSON manifest file must be created (format listed below) and placed into one of the screensaver plugin directories for it to be recognized as a valid screensaver by the desktop. + + +### JSON Manifest +The manifest file contains all the information needed to actually validate/launch the screensaver, as well as additional information about the author and/or the screensaver itself. + +Example JSON manifest file (sample.json): +``` +{ + "name" : { + "default" : "sample", + "en_US" : "US English localization of the name", + "en" : "Generic english localization of the name" + }, + + "description" : { + "default" : "sample screensaver", + "en_US" : "US English Localization of the description" + }, + + "author" : { + "name" : "Me", + "email" : "Me@myself.net", + "website" : "http://mywebsite.net", + "company" : "iXsystems", + "company_website" : "http://ixsystems.com" + }, + + "meta" : { + "license" : "3-clause BSD", + "license_url" : "https://github.com/trueos/lumina/blob/master/LICENSE", + "copyright" : "Copyright (c) 2017, Ken Moore (ken@ixsystems.com)", + "date_created" : "20171010", + "date_updated" : "20171011", + "version" : "1.0" + }, + + "qml" : { + "exec" : "absolute/or/relative/path/to/script.qml", + "additional_files" : ["file/which/must/exist.png"], + "qt_min_version" : "5.0", + "qt_max_version" : "6.0" + } +} +``` + +Details of the individual items in the manifest: +* NOTE: for locale codes, both long and short version are acceptable: + Example 1: If the current locale is "en_GB", but the JSON manifest lists translations for "en_US" and "en", then the "en" translation will be used. + Example 2: If the current locale is "en_GB", but neither "en_GB" nor "en" translations exist, then the "default" version will be used. + +* **name** : (required) This is the official name of the screensaver to show to users + * *default* : (required) Non-translated name of the screensaver + * *[locale]* : (optional) Translated name for specific [locale] +* **description** : (required) This is a short description of the screensaver to show to users + * *default* : (required) Non-translated description of the screensaver + * *[locale]* : (optional) Translated description for specific [locale] +* **author** : (all optional) Additional information about the author(s) of the screensaver + * *name* : Name of the author + * *email* : Email to contact the author (useful for licensing questions and such) + * *website* : Personal website for the author (github/facebook/twitter profile, etc) + * *company* : Company for which the author is creating this screensaver + * *company_website* : Website for the company +* **meta** : (all optional) Additional information about the screensaver itself + * *license* : License the screensaver is released under + * *license_url* : Website which contains the full text of the license + * *copyright* : Copyright notice for this screensaver + * *date_created* : (yyyyMMdd) Date the screensaver was initially created + * *date_updated* : (yyyyMMdd) Date the screensaver was last updated + * *version* : Current version of the screensaver (typically updated every time "date_updated" is changed) +* **qml** : (required) Information about launching the screensaver and checking validity + * *exec* : (required) Absolute or relative path to the QML script (relative to the directory which contains the JSON manifest) + * *additional_files* : (optional) Array of paths for other files/scripts which must exist for the screensaver to work properly. + * *qt_min_version* : (optional) Minimum version of the Qt libraries that this screensaver supports + * *qt_max_version* : (optional) Maximum version of the Qt libraries that this screensaver supports diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Video.json b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Video.json new file mode 100644 index 00000000..2fa6e6da --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Video.json @@ -0,0 +1,25 @@ +{ + "name" : { + "default" : "Video" + }, + "description" : { + "default" : "Play a single video or a list of videos in a loop" + }, + "author" : { + "name" : "Zackary Welch", + "email" : "zwelch@ixsystems.com", + "website" : "https://github.com/ZackaryWelch", + "company" : "iXsystems", + "company_website" : "http://ixsystems.com" + }, + "meta" : { + "license" : "3-clause BSD", + "license_url" : "https://github.com/trueos/lumina/blob/master/LICENSE", + "copyright" : "Copyright (c) 2017, Ken Moore (ken@ixsystems.com)", + "date_created" : "20171025", + "version" : "1.0" + }, + "qml" : { + "exec" : "qml_scripts/Video.qml" + } +} diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Warp.json b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Warp.json new file mode 100644 index 00000000..888df01f --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/Warp.json @@ -0,0 +1,25 @@ +{ + "name" : { + "default" : "Warp" + }, + "description" : { + "default" : "Warp trail through the stars" + }, + "author" : { + "name" : "Ken Moore", + "email" : "ken@ixsystems.com", + "website" : "https://github.com/beanpole135", + "company" : "iXsystems", + "company_website" : "http://ixsystems.com" + }, + "meta" : { + "license" : "3-clause BSD", + "license_url" : "https://github.com/trueos/lumina/blob/master/LICENSE", + "copyright" : "Copyright (c) 2017, Ken Moore (ken@ixsystems.com)", + "date_created" : "20171012", + "version" : "1.0" + }, + "qml" : { + "exec" : "qml_scripts/Warp.qml" + } +} diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Fireflies.qml b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Fireflies.qml new file mode 100644 index 00000000..d8dcc1ed --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Fireflies.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 +import QtGraphicalEffects 1.0 +import "." as QML + +Rectangle { + id : canvas + anchors.fill: parent + color: "black" + + Repeater { + model: Math.round(Math.random()*canvas.width/10)+100 + QML.Firefly { + parent: canvas + x: Math.round(Math.random()*canvas.width) + y: Math.round(Math.random()*canvas.height) + } + } //end of Repeater + +} //end of canvas rectangle diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Firefly.qml b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Firefly.qml new file mode 100644 index 00000000..7b65d8ec --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Firefly.qml @@ -0,0 +1,63 @@ +import QtQuick 2.0 +import QtQuick.Window 2.2 +import QtGraphicalEffects 1.0 + +Item { + + RectangularGlow { + anchors.fill: fly + glowRadius: Math.round(fly.radius /2) + spread: 0.5 + color: Qt.rgba(1,1,1,0.3) + cornerRadius: fly.radius + glowRadius + } + + Rectangle { + id: fly + width: Math.round(Math.random()*canvas.width/200)+2 + height: width + x: parent.x + y: parent.y + color: Qt.rgba(Math.random(),Math.random(),0,0.5) + radius: Math.floor(width/2) + property int jitterX: Math.round(Math.random()*100)+10 + property int jitterY: Math.round(Math.random()*100)+10 + + Behavior on color { + ColorAnimation { + duration: 500 + } + } + Behavior on x { + SmoothedAnimation { + velocity: 10+Math.random()*canvas.width/100 + } + } + Behavior on y { + SmoothedAnimation { + velocity: 10+Math.random()*canvas.height/100 + } + } + + } + + + + Timer { + interval: 5 + repeat: true + running: true + property bool starting: true + onTriggered: { + if(starting){ interval = Math.round(Math.random()*1000)+500; starting = false; } + if ( (fly.x+fly.jitterX)>parent.width || (fly.x+fly.jitterX)<0 ){ fly.jitterX = 0-fly.jitterX } + fly.x = fly.x+fly.jitterX + if( (fly.y+fly.jitterY)>parent.height || (fly.y+fly.jitterY)<0 ){ fly.jitterY = 0-fly.jitterY } + fly.y = fly.y+fly.jitterY + fly.jitterX = (Math.round(Math.random())*2 - 1) *fly.jitterX + fly.jitterY = (Math.round(Math.random())*2 - 1) *fly.jitterY + fly.color = Qt.rgba(Math.random(),Math.random(),Math.random(),0.5) + + } + } //end of timer +} //end of item diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Grav.qml b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Grav.qml new file mode 100644 index 00000000..7a3c33cd --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Grav.qml @@ -0,0 +1,123 @@ +import QtQuick 2.7 +import QtGraphicalEffects 1.0 + +Rectangle { + id : canvas + anchors.fill: parent + width: 800 + height: 600 + color: "black" + + //TODO Add orbital trails option + + //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 + + //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) + + 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++; + } + } + } + } + + //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/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Video.qml b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Video.qml new file mode 100644 index 00000000..e7d0626d --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Video.qml @@ -0,0 +1,50 @@ +import QtQuick 2.0 +import QtMultimedia 5.7 +import QtQuick.Window 2.2 +import Qt.labs.folderlistmodel 2.1 + +Rectangle { + //width: Screen.width + //height: Screen.height + width: 800 + height: 600 + color: "black" + + FolderListModel { + id: folderModel + folder: "/usr/local/videos" + } + + Repeater { + model: folderModel + Component { + Item { + Component.onCompleted: { playlist.addItem(fileURL) } + } + } + } + + Playlist { + id: playlist + playbackMode: Playlist.Random + PlaylistItem { source: "/" } + onError: { console.log("ERROR") } + } + + MediaPlayer { + id: player + autoPlay: true + playlist: playlist + } + + VideoOutput { + id: videoOutput + source: player + anchors.fill: parent + } + + Component.onCompleted: { + playlist.shuffle() + console.log(playlist.itemCount) + } +} diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Warp.qml b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Warp.qml new file mode 100644 index 00000000..1cf9bc37 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/extrafiles/screensavers/qml_scripts/Warp.qml @@ -0,0 +1,64 @@ +import QtQuick 2.0 +import QtGraphicalEffects 1.0 + +Rectangle { + id : canvas + anchors.fill: parent + color: "black" + + function getStarColor(num){ + if(num < 1) { return "white" } + if(num < 2) { return "mistyrose" } + return "lightblue" + } + + // CREATE STARFIELD + Repeater { + model: Math.round(Math.random()*canvas.width/10)+500 + Rectangle { + parent: canvas + x: Math.round(Math.random()*canvas.width) + y: Math.round(Math.random()*canvas.height) + width: Math.round(Math.random()*3)+3 + height: width + radius: width/2 + color: getStarColor( (index%3) ) + + } + } //end of Repeater + + // NOW CREATE THE WARP EFFECT + ZoomBlur { + id: blur + anchors.fill: canvas + source: canvas + samples: 24 + length: canvas.width / 20 + horizontalOffset: 0 + verticalOffset: 0 + + Behavior on horizontalOffset{ + NumberAnimation{ + duration: 3000 + } + } + Behavior on verticalOffset{ + NumberAnimation{ + duration: 3000 + } + } + } //end of zoom blur + + Timer { + interval: 5 + repeat: true + running: true + property bool starting: true + onTriggered: { + if(starting){ interval = 3010; starting = false; } + blur.horizontalOffset = (Math.random()*canvas.width/4) - (canvas.width/8) + blur.verticalOffset = (Math.random()*canvas.height/4) - (canvas.height/8) + } + } //end of timer + +} //end of canvas rectangle diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey-zoom.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey-zoom.jpg Binary files differdeleted file mode 100644 index 481ca438..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey-zoom.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey.jpg Binary files differdeleted file mode 100644 index 9da67596..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_blue-grey.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_gold.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_gold.jpg Binary files differdeleted file mode 100644 index cba03cee..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_gold.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_green.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_green.jpg Binary files differdeleted file mode 100644 index 80b0d3e3..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_green.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue-zoom.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue-zoom.jpg Binary files differdeleted file mode 100644 index 4f753ed5..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue-zoom.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue.jpg Binary files differdeleted file mode 100644 index c214cd78..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_grey-blue.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_purple.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_purple.jpg Binary files differdeleted file mode 100644 index e4c3d7a8..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_purple.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_red.jpg b/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_red.jpg Binary files differdeleted file mode 100644 index a092f636..00000000 --- a/src-qt5/core/lumina-desktop-unified/extrafiles/wallpapers/Lumina_Wispy_red.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop-unified/global-includes.h b/src-qt5/core/lumina-desktop-unified/global-includes.h index 184f5b8d..91604362 100644 --- a/src-qt5/core/lumina-desktop-unified/global-includes.h +++ b/src-qt5/core/lumina-desktop-unified/global-includes.h @@ -19,6 +19,7 @@ #include <QMouseEvent> #include <QAction> #include <QPoint> +#include <QTemporaryFile> #include <QFile> #include <QDir> #include <QString> @@ -53,7 +54,14 @@ #include <QJsonObject> #include <QJsonArray> #include <QJsonDocument> +#include <QQuickView> +#include <QQmlContext> +#include <QQmlEngine> +#include <QQuickImageProvider> +// C++ Backend classes for QML interface +#include <RootDesktopObject.h> +#include <ScreenObject.h> // libLumina includes #include <LuminaX11.h> @@ -64,7 +72,6 @@ #include <LDesktopUtils.h> #include <LuminaSingleApplication.h> #include <DesktopSettings.h> -#include <RootWindow.h> #include <ExternalProcess.h> #include <NativeWindow.h> #include <NativeWindowSystem.h> @@ -72,8 +79,6 @@ #include <XDGMime.h> #include <LIconCache.h> -// Standard C includes -#include <unistd.h> //Setup any global defines (no classes or global objects: use "global-objects.h" for that) diff --git a/src-qt5/core/lumina-desktop-unified/global-objects.h b/src-qt5/core/lumina-desktop-unified/global-objects.h index 0c990dc6..c204587f 100644 --- a/src-qt5/core/lumina-desktop-unified/global-objects.h +++ b/src-qt5/core/lumina-desktop-unified/global-objects.h @@ -25,8 +25,12 @@ #include "src-screensaver/LScreenSaver.h" //#include "src-WM/LWindowManager.h" +#include <RootWindow.h> #include "LSession.h" +// Standard C includes +#include <unistd.h> + //Any special defines for settings/testing #define ANIMTIME 80 //animation time in milliseconds diff --git a/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro b/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro index e8cf2f28..21e46b22 100644 --- a/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro +++ b/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro @@ -1,26 +1,30 @@ include($${PWD}/../../OS-detect.pri) -QT += core gui network -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets x11extras multimedia multimediawidgets concurrent svg +lessThan(QT_MAJOR_VERSION, 5) { + message("[ERROR] Qt 5.4+ is required to use the Lumina Desktop!") + exit +} +lessThan(QT_MINOR_VERSION, 4){ + message("[ERROR] Qt 5.4+ is required to use the Lumina Desktop!") + exit +} +QT *= core gui network widgets x11extras multimedia multimediawidgets concurrent svg quick qml TARGET = lumina-desktop-unified target.path = $${L_BINDIR} #include all the special classes from the Lumina tree -include(../libLumina/ResizeMenu.pri) include(../libLumina/LDesktopUtils.pri) #includes LUtils and LOS include(../libLumina/LuminaXDG.pri) -#include(../libLumina/LuminaX11.pri) include(../libLumina/LuminaSingleApplication.pri) -include(../libLumina/LuminaThemes.pri) include(../libLumina/DesktopSettings.pri) -include(../libLumina/RootWindow.pri) include(../libLumina/ExternalProcess.pri) -include(../libLumina/NativeWindow.pri) +include(../../src-cpp/NativeWindow.pri) include(../libLumina/XDGMime.pri) -include(../libLumina/LIconCache.pri) + +include(../../src-cpp/plugins-screensaver.pri) #include all the main individual source groups include(src-screensaver/screensaver.pri) @@ -36,8 +40,7 @@ SOURCES += main.cpp \ HEADERS += global-includes.h \ global-objects.h \ LSession.h \ - BootSplash.h \ - JsonMenu.h + BootSplash.h FORMS += BootSplash.ui @@ -54,6 +57,9 @@ desktop.files = lumina-desktop.desktop defaults.path = $${L_SHAREDIR}/lumina-desktop defaults.files = defaults/* +extrafiles.path = $${L_SHAREDIR}/lumina-desktop +extrafiles.files = extrafiles/* + TRANSLATIONS = i18n/lumina-desktop_af.ts \ i18n/lumina-desktop_ar.ts \ i18n/lumina-desktop_az.ts \ @@ -120,7 +126,7 @@ TRANSLATIONS = i18n/lumina-desktop_af.ts \ dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/ dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/ -INSTALLS += target desktop defaults +INSTALLS += target desktop defaults extrafiles WITH_I18N{ INSTALLS += dotrans diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.cpp new file mode 100644 index 00000000..0cfa4e6b --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.cpp @@ -0,0 +1,44 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "RootWindow.h" + +RootWindow::RootWindow() : QObject(){ + root_win = QWindow::fromWinId( QX11Info::appRootWindow() ); // + root_view = new QQuickView(root_win); //make it a child of the root window + root_obj = RootDesktopObject::instance(); + syncRootSize(); + connect(root_win, SIGNAL(widthChanged(int)), this, SLOT(syncRootSize()) ); + connect(root_win, SIGNAL(heightChanged(int)),this, SLOT(syncRootSize()) ); + //Now setup the QQuickView + root_view->setResizeMode(QQuickView::SizeRootObjectToView); + root_view->engine()->rootContext()->setContextProperty("RootObject", root_obj); + RootDesktopObject::RegisterType(); //make sure object classes are registered with the QML subsystems +} + +RootWindow::~RootWindow(){ + root_view->deleteLater(); + root_obj->deleteLater(); +} + +void RootWindow::start(){ + root_view->setSource(QUrl("qrc:///qml/RootDesktop.qml")); + root_win->show(); + root_view->show(); +} + +void RootWindow::syncRootSize(){ + //qDebug() << "Sync Root Size:" << root_win->width() << root_win->height() << root_view->geometry(); + QList<QScreen*> screens = QApplication::screens(); + QRect unif; + for(int i=0; i<screens.length(); i++){ unif = unif.united(screens[i]->geometry()); } + if(unif.width() != root_view->width() || unif.height() != root_view->height()){ + root_view->setGeometry(0, 0, unif.width(), unif.height() ); + emit RootResized(root_view->geometry()); + } + root_obj->updateScreens(); + //qDebug() << " - after:" << root_view->geometry(); +} diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h new file mode 100644 index 00000000..ba489465 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/RootWindow.h @@ -0,0 +1,34 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#ifndef _LUMINA_DESKTOP_ROOT_WINDOW_H +#define _LUMINA_DESKTOP_ROOT_WINDOW_H +#include <global-includes.h> + +class RootWindow : public QObject{ + Q_OBJECT +private: + QWindow *root_win; + QQuickView *root_view; + RootDesktopObject *root_obj; + +public: + RootWindow(); + ~RootWindow(); + + void start(); + +public slots: + void syncRootSize(); + +signals: + void startLogout(); + void RegisterVirtualRoot(WId); + void RootResized(QRect); + void MouseMoved(); +}; + +#endif diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri b/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri index 75aef8a6..e4c4faeb 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/desktop.pri @@ -1,6 +1,11 @@ -SOURCES *= $${PWD}/ContextMenu.cpp +QT *= gui widgets qml quick -HEADERS *= $${PWD}/ContextMenu.h +SOURCES *= $${PWD}/RootWindow.cpp + +HEADERS *= $${PWD}/RootWindow.h #update the includepath so we can just #include as needed without paths -INCLUDEPATH *= ${PWD} +INCLUDEPATH *= $${PWD} + +include($${PWD}/src-cpp/src-cpp.pri) +include($${PWD}/src-qml/src-qml.pri) diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp new file mode 100644 index 00000000..9842712e --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.cpp @@ -0,0 +1,77 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "RootDesktopObject.h" +#include <QQmlEngine> +#include <QApplication> +#include <QScreen> + +#include <QDebug> + +// === PUBLIC === +RootDesktopObject::RootDesktopObject(QObject *parent) : QObject(parent){ + updateScreens(); //make sure the internal list is updated right away +} + +RootDesktopObject::~RootDesktopObject(){ + +} + +void RootDesktopObject::RegisterType(){ + qmlRegisterType<RootDesktopObject>("Lumina.Backend.RootDesktopObject", 2, 0, "RootDesktopObject"); + //Also register any types that are needed by this class + ScreenObject::RegisterType(); +} + +RootDesktopObject* RootDesktopObject::instance(){ + static RootDesktopObject* r_obj = new RootDesktopObject(); + return r_obj; +} + +//QML Read Functions +QList<ScreenObject*> RootDesktopObject::screens(){ + return s_objects; +} + +void RootDesktopObject::logout(){ + emit startLogout(); +} + +void RootDesktopObject::lockscreen(){ + emit lockScreen(); +} + +void RootDesktopObject::mousePositionChanged(){ + emit mouseMoved(); +} + +// === PUBLIC SLOTS === +void RootDesktopObject::updateScreens(){ + QList<QScreen*> scrns = QApplication::screens(); + QList<ScreenObject*> tmp; //copy of the internal array initially + for(int i=0; i<scrns.length(); i++){ + bool found = false; + for(int j=0; j<s_objects.length() && !found; j++){ + if(s_objects[j]->name()==scrns[i]->name()){ found = true; tmp << s_objects.takeAt(j); } + } + if(!found){ tmp << new ScreenObject(scrns[i], this); } + } + //Delete any leftover objects + for(int i=0; i<s_objects.length(); i++){ s_objects[i]->deleteLater(); } + s_objects = tmp; + emit screensChanged(); + for(int i=0; i<s_objects.length(); i++){ + s_objects[i]->emit geomChanged(); + } +} + +void RootDesktopObject::ChangeWallpaper(QString screen, QString value){ + for(int i=0; i<s_objects.length(); i++){ + if(s_objects[i]->name()==screen){ s_objects[i]->setBackground(value); break; } + } +} + +// === PRIVATE === diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h new file mode 100644 index 00000000..dd7c7ab3 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/RootDesktopObject.h @@ -0,0 +1,54 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +// This is the base C++ object that is used to pass information to the QML "RootDesktop" object +//=========================================== +#ifndef _LUMINA_DESKTOP_QML_BACKEND_ROOT_DESKTOP_OBJECT_H +#define _LUMINA_DESKTOP_QML_BACKEND_ROOT_DESKTOP_OBJECT_H +#include <QObject> +#include <QList> + +#include "ScreenObject.h" + +class RootDesktopObject : public QObject{ + Q_OBJECT + //Define all the QML Properties here (interface between QML and the C++ methods below) + Q_PROPERTY( QList<ScreenObject*> screens READ screens NOTIFY screensChanged) + +public: + //main contructor/destructor + RootDesktopObject(QObject *parent = 0); + ~RootDesktopObject(); + + static void RegisterType(); + + //primary interface to fetch the current instance of the class (so only one is running at any given time) + static RootDesktopObject* instance(); + + //QML Read Functions + QList<ScreenObject*> screens(); + + //QML Access Functions + Q_INVOKABLE void logout(); + Q_INVOKABLE void lockscreen(); + Q_INVOKABLE void mousePositionChanged(); +private: + QList<ScreenObject*> s_objects; + +public slots: + void updateScreens(); //rescan/update screen objects + void ChangeWallpaper(QString screen, QString); + +private slots: + +signals: + void screensChanged(); + void startLogout(); + void mouseMoved(); + void lockScreen(); + +}; +#endif diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp new file mode 100644 index 00000000..4c1d6189 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.cpp @@ -0,0 +1,31 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "ScreenObject.h" +#include <QQmlEngine> +#include <QDebug> + +ScreenObject::ScreenObject(QScreen *scrn, QObject *parent) : QObject(parent){ + bg_screen = scrn; +} + +void ScreenObject::RegisterType(){ + qmlRegisterType<ScreenObject>("Lumina.Backend.ScreenObject",2,0, "ScreenObject"); +} + +QString ScreenObject::name(){ return bg_screen->name(); } +QString ScreenObject::background(){ qDebug() << "Got Background:" << bg_screen->name() << bg << bg_screen->geometry(); return bg; } +int ScreenObject::x(){ return bg_screen->geometry().x(); } +int ScreenObject::y(){ return bg_screen->geometry().y(); } +int ScreenObject::width(){ return bg_screen->geometry().width(); } +int ScreenObject::height(){ return bg_screen->geometry().height(); } + +void ScreenObject::setBackground(QString fileOrColor){ + if(bg!=fileOrColor){ + bg = fileOrColor; + emit backgroundChanged(); + } +} diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.h b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.h new file mode 100644 index 00000000..8076f1ae --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/ScreenObject.h @@ -0,0 +1,48 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +// This is the base C++ object that is used to pass Screen/Wallpaper info to the QML classes +//=========================================== +#ifndef _LUMINA_DESKTOP_SCREEN_DESKTOP_OBJECT_H +#define _LUMINA_DESKTOP_SCREEN_DESKTOP_OBJECT_H +#include <QObject> +#include <QString> +#include <QScreen> + +class ScreenObject : public QObject { + Q_OBJECT + Q_PROPERTY( QString name READ name ) + Q_PROPERTY( QString background READ background NOTIFY backgroundChanged) + Q_PROPERTY( int x READ x NOTIFY geomChanged) + Q_PROPERTY( int y READ y NOTIFY geomChanged) + Q_PROPERTY( int width READ width NOTIFY geomChanged) + Q_PROPERTY( int height READ height NOTIFY geomChanged) + +private: + QScreen *bg_screen; + QString bg; + +public: + ScreenObject(QScreen *scrn = 0, QObject *parent = 0); + + static void RegisterType(); + + Q_INVOKABLE QString name(); + Q_INVOKABLE QString background(); + Q_INVOKABLE int x(); + Q_INVOKABLE int y(); + Q_INVOKABLE int width(); + Q_INVOKABLE int height(); + +public slots: + void setBackground(QString fileOrColor); + +signals: + void backgroundChanged(); + void geomChanged(); +}; + +#endif diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/src-cpp.pri b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/src-cpp.pri new file mode 100644 index 00000000..33b699da --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-cpp/src-cpp.pri @@ -0,0 +1,8 @@ +SOURCES *= $${PWD}/RootDesktopObject.cpp \ + $${PWD}/ScreenObject.cpp + +HEADERS *= $${PWD}/RootDesktopObject.h \ + $${PWD}/ScreenObject.h + +INCLUDEPATH *= $${PWD} + diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/ContextMenu.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/ContextMenu.qml new file mode 100644 index 00000000..e5bac0b5 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/ContextMenu.qml @@ -0,0 +1,36 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +import QtQuick 2.2 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +import Lumina.Backend.RootDesktopObject 2.0 + +Menu { + id: contextMenu + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + MenuItem { + text: "Lock Screen" + onTriggered: { + RootObject.lockscreen() + } + } + + MenuItem { + text: "Logout" + //iconName: "system-log-out" + indicator: Image{ + asynchronous: true + //autoTransform: true + //source: "image://theme/system-logout" + source: "file:///usr/local/share/icons/material-design-light/scalable/actions/system-log-out.svg" + } + onTriggered: { + RootObject.logout() + } + } + } diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml new file mode 100644 index 00000000..a1a9164f --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/RootDesktop.qml @@ -0,0 +1,57 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +// This is the base QML script the launches/controls the desktop interface itself +//=========================================== +// NOTE: This needs to be paired/used with the corresponding C++ class: RootDesktopObject +// Which should be added as the "RootObject" context property to the QML engine +//------------------ +// Example Code: +// RootDesktopObject *rootobj = new RootDesktopObject(); +// QQuickView *root = new QQuickView(); +// root->setResizeMode(QQuickView::SizeRootObjectToView); +// root->engine()->rootContext()->setContextProperty("RootObject", rootobj); +//=========================================== +import QtQuick 2.2 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +import "." as QML + +import Lumina.Backend.RootDesktopObject 2.0 +import Lumina.Backend.ScreenObject 2.0 + +Rectangle { + id: rootCanvas + color: "black" + + //Setup the right-click context menu + MouseArea { + anchors.fill: rootCanvas + acceptedButtons: Qt.RightButton + onClicked: { + contextMenu.x = mouseX + contextMenu.y = mouseY + contextMenu.open() + } + onPositionChanged: { + RootObject.mousePositionChanged() + } + } + + //Create the context menu itself + QML.ContextMenu { id: contextMenu } + + //Setup the wallpapers + Repeater{ + model: RootObject.screens + QML.WallpaperImage{ + //console.log( modelData.name() ) + object: modelData + z: 0+index + } + } +} diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/WallpaperImage.qml b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/WallpaperImage.qml new file mode 100644 index 00000000..4d39b0b8 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/WallpaperImage.qml @@ -0,0 +1,25 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +import QtQuick 2.2 +import QtQuick.Window 2.2 +import QtQuick.Controls 2.0 + +import Lumina.Backend.ScreenObject 2.0 + +AnimatedImage { + //C++ backend object + property ScreenObject object + + //Normal geometries/placements + asynchronous: true + clip: true + source: object.background + x: object.x + y: object.y + width: object.width + height: object.height + } diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri new file mode 100644 index 00000000..99905253 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.pri @@ -0,0 +1,7 @@ +#Show the QML files to lupdate for translation purposes - not for the actual build +lupdate_only{ + SOURCES *= $${PWD}/RootDesktop.qml \ + $${PWD}/ContextMenu.qml +} + +RESOURCES *= $${PWD}/src-qml.qrc diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc new file mode 100644 index 00000000..ebdcc606 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/src-qml/src-qml.qrc @@ -0,0 +1,7 @@ +<RCC> + <qresource prefix="qml"> + <file>RootDesktop.qml</file> + <file>ContextMenu.qml</file> + <file>WallpaperImage.qml</file> + </qresource> +</RCC> diff --git a/src-qt5/core/lumina-desktop-unified/src-screensaver/LLockScreen.cpp b/src-qt5/core/lumina-desktop-unified/src-screensaver/LLockScreen.cpp index 0ff70142..b791ffd2 100644 --- a/src-qt5/core/lumina-desktop-unified/src-screensaver/LLockScreen.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-screensaver/LLockScreen.cpp @@ -77,7 +77,18 @@ void LLockScreen::TryUnlock(){ this->setEnabled(false); QString pass = ui->line_password->text(); ui->line_password->clear(); - bool ok = (LUtils::runCmd("lumina-checkpass", QStringList() << pass) == 0); + //Create a temporary file for the password, then pass that file descriptor to lumina-checkpass + QTemporaryFile *TF = new QTemporaryFile(".XXXXXXXXXX"); + TF->setAutoRemove(true); + bool ok = false; + if( TF->open() ){ + QTextStream in(TF); + in << pass; + in.flush(); //make sure we push it to the file **right now** since we need to keep the file open + ok = (LUtils::runCmd("lumina-checkpass", QStringList() << "-f" << TF->fileName() ) == 0); + TF->close(); + } + delete TF; if(ok){ emit ScreenUnlocked(); this->setEnabled(true); diff --git a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp index a6d5be60..122307b3 100644 --- a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp @@ -12,19 +12,19 @@ // ======== // PUBLIC // ======== -SSBaseWidget::SSBaseWidget(QWidget *parent) : QWidget(parent){ +SSBaseWidget::SSBaseWidget(QWidget *parent) : QQuickView(parent->windowHandle()){ this->setObjectName("LuminaBaseSSWidget"); - ANIM = 0; - this->setMouseTracking(true); + this->setResizeMode(QQuickView::SizeRootObjectToView); + this->setColor(QColor("black")); //default color for the view + this->setCursor(Qt::BlankCursor); plugType="none"; restartTimer = new QTimer(this); - restartTimer->setInterval( DesktopSettings::instance()->value(DesktopSettings::ScreenSaver, "globals/plugin_time_seconds", 60).toInt() * 1000); + restartTimer->setInterval( DesktopSettings::instance()->value(DesktopSettings::ScreenSaver, "globals/plugin_time_seconds", 120).toInt() * 1000); restartTimer->setSingleShot(true); connect(restartTimer, SIGNAL(timeout()), this, SLOT(startPainting()) ); } SSBaseWidget::~SSBaseWidget(){ - if(ANIM!=0){ this->stopPainting(); } } void SSBaseWidget::setPlugin(QString plug){ @@ -35,54 +35,27 @@ void SSBaseWidget::setPlugin(QString plug){ // PUBLIC SLOTS // ============= void SSBaseWidget::startPainting(){ - cplug = plugType; //free up any old animation instance - if(ANIM!=0){ - stopPainting(); - } + stopPainting(); //If a random plugin - grab one of the known plugins - if(cplug=="random"){ - QStringList valid = BaseAnimGroup::KnownAnimations(); - valid.removeAll("none"); //they want a screensaver - remove the "none" option from the valid list - if(valid.isEmpty()){ cplug = "none"; } //no known plugins - else{ cplug = valid[ qrand()%valid.length() ]; } //grab a random plugin - } - if(DEBUG){ qDebug() << " - Screen Saver:" << plugType << cplug; } - //Now list all the various plugins and start them appropriately - QString style; - if(cplug=="none"){ - style = "background: black;"; //show the underlying black parent widget - }else{ - style = "background: black;"; + if(plugType=="random"){ + QList<SSPlugin> valid = SSPluginSystem::findAllPlugins(); + if(!valid.isEmpty()){ cplug = valid[ qrand()%valid.length() ]; } //grab a random plugin + }else if(plugType!="none"){ + cplug = SSPluginSystem::findPlugin(plugType); } - this->setStyleSheet("QWidget#LuminaBaseSSWidget{ "+style+"}"); - this->repaint(); - //If not a stylesheet-based plugin - set it here - if(cplug!="none"){ - ANIM = BaseAnimGroup::NewAnimation(cplug, this); - connect(ANIM, SIGNAL(finished()), this, SLOT(startPainting()) ); //repeat the plugin as needed - ANIM->LoadAnimations(); + if(DEBUG){ qDebug() << " - Screen Saver:" << plugType << cplug.scriptURL() << cplug.isValid(); } + if(cplug.isValid()){ + this->setSource( cplug.scriptURL() ); + if(plugType=="random"){ restartTimer->start(); } } - //Now start the animation(s) - if(ANIM!=0){ - if(ANIM->animationCount()>0){ - if(DEBUG){ qDebug() << " - Starting SS Plugin:" << cplug << ANIM->animationCount() << ANIM->duration() << ANIM->loopCount(); } - ANIM->start(); - } - } - restartTimer->start(); + } void SSBaseWidget::stopPainting(){ - if(ANIM!=0){ - if(DEBUG){ qDebug() << "Stopping Animation!!"; } - ANIM->stop(); - //ANIM->clear(); - ANIM->deleteLater(); - ANIM = 0; - //Delete any child widgets of the canvas - QList<QWidget*> widgets = this->findChildren<QWidget*>("",Qt::FindDirectChildrenOnly); - for(int i=0; i<widgets.length(); i++){ widgets[i]->deleteLater(); } + if(!this->source().isEmpty()){ + this->setSource(QUrl()); + cplug = SSPlugin(); //empty structure } if(restartTimer->isActive()){ restartTimer->stop(); } } diff --git a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h index af809127..72e02702 100644 --- a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h +++ b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.h @@ -10,9 +10,9 @@ #define _LUMINA_DESKTOP_SCREEN_SAVER_BASE_WIDGET_H #include "global-includes.h" -#include "animations/BaseAnimGroup.h" +#include <plugins-screensaver.h> -class SSBaseWidget : public QWidget{ +class SSBaseWidget : public QQuickView{ Q_OBJECT public: SSBaseWidget(QWidget *parent); @@ -25,8 +25,8 @@ public slots: void stopPainting(); private: - QString plugType, cplug; //type of custom painting to do - BaseAnimGroup *ANIM; + QString plugType; + SSPlugin cplug; QTimer *restartTimer; private slots: @@ -43,12 +43,6 @@ protected: ev->accept(); emit InputDetected(); } - void paintEvent(QPaintEvent*){ - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); - } }; diff --git a/src-qt5/core/lumina-desktop-unified/src-screensaver/screensaver.pri b/src-qt5/core/lumina-desktop-unified/src-screensaver/screensaver.pri index f95891c1..92cc7bd2 100644 --- a/src-qt5/core/lumina-desktop-unified/src-screensaver/screensaver.pri +++ b/src-qt5/core/lumina-desktop-unified/src-screensaver/screensaver.pri @@ -9,7 +9,7 @@ HEADERS *= $${PWD}/LLockScreen.h \ FORMS *= $${PWD}/LLockScreen.ui #update the includepath so we can just (#include <LScreenSaver.h>) as needed without paths -INCLUDEPATH *= ${PWD} +INCLUDEPATH *= $${PWD} #Now include all the screensaver animations/options -include(animations/animations.pri) +#include(animations/animations.pri) diff --git a/src-qt5/core/lumina-desktop/LDesktop.cpp b/src-qt5/core/lumina-desktop/LDesktop.cpp index f9ea1534..71b10bd5 100644 --- a/src-qt5/core/lumina-desktop/LDesktop.cpp +++ b/src-qt5/core/lumina-desktop/LDesktop.cpp @@ -341,7 +341,7 @@ void LDesktop::UpdateMenu(bool fast){ void LDesktop::UpdateWinMenu(){ winMenu->clear(); //Get the current list of windows - QList<WId> wins = LSession::handle()->XCB->WindowList(); + QList<WId> wins = LSession::handle()->XCB->WindowList(); //Now add them to the menu for(int i=0; i<wins.length(); i++){ LWinInfo info(wins[i]); @@ -352,7 +352,7 @@ void LDesktop::UpdateWinMenu(){ } void LDesktop::winClicked(QAction* act){ - LSession::handle()->XCB->ActivateWindow( act->data().toString().toULong() ); + LSession::handle()->XCB->ActivateWindow( act->data().toString().toULong() ); } void LDesktop::UpdateDesktop(){ @@ -393,7 +393,7 @@ void LDesktop::UpdateDesktop(){ if(settings->value(DPREFIX+"generateMediaIcons",true).toBool()){ QDir media("/media"); QStringList mediadirs = media.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot, QDir::Name); - for(int i=0; i<mediadirs.length(); i++){ + for(int i=0; i<mediadirs.length(); i++){ filelist << media.absoluteFilePath(mediadirs[i]); } } @@ -406,8 +406,8 @@ void LDesktop::RemoveDeskPlugin(QString ID){ //This is called after a plugin is manually removed by the user // just need to ensure that the plugin is also removed from the settings file QStringList plugs = settings->value(DPREFIX+"pluginlist", QStringList()).toStringList(); - if(plugs.contains(ID)){ - plugs.removeAll(ID); + if(plugs.contains(ID)){ + plugs.removeAll(ID); issyncing=true; //don't let the change cause a refresh settings->setValue(DPREFIX+"pluginlist", plugs); settings->sync(); @@ -437,7 +437,7 @@ void LDesktop::DecreaseDesktopPluginIcons(){ settings->setValue(DPREFIX+"GridSize",cur); settings->sync(); QTimer::singleShot(200, this, SLOT(UnlockSettings()) ); - bgDesktop->SetIconSize(cur); + bgDesktop->SetIconSize(cur); } void LDesktop::UpdatePanels(){ @@ -484,18 +484,18 @@ void LDesktop::UpdateDesktopPluginArea(){ QRegion shifted = visReg; QString loc = settings->value(PANELS[i]->prefix()+"location","top").toString().toLower(); int vis = PANELS[i]->visibleWidth(); - if(loc=="top"){ + if(loc=="top"){ if(!shifted.contains(QRect(rawRect.x(), rawRect.y(), rawRect.width(), vis))){ continue; } - shifted.translate(0, (rawRect.top()+vis)-shifted.boundingRect().top() ); + shifted.translate(0, (rawRect.top()+vis)-shifted.boundingRect().top() ); }else if(loc=="bottom"){ - if(!shifted.contains(QRect(rawRect.x(), rawRect.bottom()-vis, rawRect.width(), vis))){ continue; } - shifted.translate(0, (rawRect.bottom()-vis)-shifted.boundingRect().bottom()); - }else if(loc=="left"){ + if(!shifted.contains(QRect(rawRect.x(), rawRect.bottom()-vis, rawRect.width(), vis))){ continue; } + shifted.translate(0, (rawRect.bottom()-vis)-shifted.boundingRect().bottom()); + }else if(loc=="left"){ if( !shifted.contains(QRect(rawRect.x(), rawRect.y(), vis,rawRect.height())) ){ continue; } - shifted.translate((rawRect.left()+vis)-shifted.boundingRect().left() ,0); + shifted.translate((rawRect.left()+vis)-shifted.boundingRect().left() ,0); }else{ //right if(!shifted.contains(QRect(rawRect.right()-vis, rawRect.y(), vis,rawRect.height())) ){ continue; } - shifted.translate((rawRect.right()-vis)-shifted.boundingRect().right(),0); + shifted.translate((rawRect.right()-vis)-shifted.boundingRect().right(),0); } visReg = visReg.intersected( shifted ); } @@ -535,11 +535,20 @@ void LDesktop::UpdateBackground(){ //Get the list of background(s) to show QStringList bgL = settings->value(DPREFIX+"background/filelist-workspace-"+QString::number( LSession::handle()->XCB->CurrentWorkspace()), QStringList()).toStringList(); if(bgL.isEmpty()){ bgL = settings->value(DPREFIX+"background/filelist", QStringList()).toStringList(); } - + //qDebug() << " - List:" << bgL << CBG; //Remove any invalid files for(int i=0; i<bgL.length(); i++){ - if( (!QFile::exists(bgL[i]) && bgL[i]!="default" && !bgL[i].startsWith("rgb(") ) || bgL[i].isEmpty()){ bgL.removeAt(i); i--; } + if(bgL[i]=="default" || bgL[i].startsWith("rgb(") ){ continue; } //built-in definitions - treat them as valid + if(bgL[i].isEmpty()){ bgL.removeAt(i); i--; } + if( !QFile::exists(bgL[i]) ){ + //Quick Detect/replace for new path for Lumina wallpapers (change in 1.3.4) + if(bgL[i].contains("/wallpapers/Lumina-DE/")){ + bgL[i] = bgL[i].replace("/wallpapers/Lumina-DE/", "/wallpapers/lumina-desktop/"); i--; //modify the path and re-check it + }else{ + bgL.removeAt(i); i--; + } + } } if(bgL.isEmpty()){ bgL << "default"; } //always fall back on the default //Determine if the background needs to be changed @@ -552,13 +561,32 @@ void LDesktop::UpdateBackground(){ } oldBGL = bgL; //save this for later //Determine which background to use next - int index ( qrand() % bgL.length() ); - if(index== bgL.indexOf(CBG)){ //if the current wallpaper was selected by the randomization again - //Go to the next in the list - if(index < 0 || index >= bgL.length()-1){ index = 0; } //if invalid or last item in the list - go to first - else{ index++; } //go to next + QString bgFile; + while(bgFile.isEmpty() || QFileInfo(bgFile).isDir()){ + QString prefix; + if(!bgFile.isEmpty()){ + //Got a directory - update the list of files and re-randomize the selection + QStringList imgs = LUtils::imageExtensions(); + for(int i=0; i<imgs.length(); i++){ imgs[i].prepend("*."); } + QDir tdir(bgFile); + prefix=bgFile+"/"; + bgL = tdir.entryList(imgs, QDir::Files | QDir::NoDotAndDotDot, QDir::Name); + //If directory no longer has any valid images - remove it from list and try again + if(bgL.isEmpty()){ + oldBGL.removeAll(bgFile); //invalid directory - remove it from the list for the moment + bgL = oldBGL; //reset the list back to the original list (not within a directory) + } + } + //Verify that there are files in the list - otherwise use the default + if(bgL.isEmpty()){ bgFile="default"; break; } + int index = ( qrand() % bgL.length() ); + if(index== bgL.indexOf(CBG)){ //if the current wallpaper was selected by the randomization again + //Go to the next in the list + if(index < 0 || index >= bgL.length()-1){ index = 0; } //if invalid or last item in the list - go to first + else{ index++; } //go to next + } + bgFile = prefix+bgL[index]; } - QString bgFile = bgL[index]; //Save this file as the current background CBG = bgFile; //qDebug() << " - Set Background to:" << CBG << index << bgL; @@ -570,7 +598,7 @@ void LDesktop::UpdateBackground(){ bgDesktop->setBackground(backPix); //Now reset the timer for the next change (if appropriate) if(bgtimer->isActive()){ bgtimer->stop(); } - if(bgL.length() > 1){ + if(bgL.length()>1 || oldBGL.length()>1){ //get the length of the timer (in minutes) int min = settings->value(DPREFIX+"background/minutesToChange",5).toInt(); //restart the internal timer @@ -633,9 +661,9 @@ void LDesktop::NewDesktopFile(QString name){ QDir desktop(QDir::homePath()); if(desktop.exists(tr("Desktop"))){ desktop.cd(tr("Desktop")); } //translated folder else{ desktop.cd("Desktop"); } //default/english folder - if(!desktop.exists(name)){ + if(!desktop.exists(name)){ QFile file(desktop.absoluteFilePath(name)); - if(file.open(QIODevice::WriteOnly) ){ file.close(); } + if(file.open(QIODevice::WriteOnly) ){ file.close(); } } } } diff --git a/src-qt5/core/lumina-desktop/LDesktopPluginSpace.cpp b/src-qt5/core/lumina-desktop/LDesktopPluginSpace.cpp index 41a1017d..9e964f5d 100644 --- a/src-qt5/core/lumina-desktop/LDesktopPluginSpace.cpp +++ b/src-qt5/core/lumina-desktop/LDesktopPluginSpace.cpp @@ -21,7 +21,7 @@ LDesktopPluginSpace::LDesktopPluginSpace() : QWidget(){ //this->setAttribute(Qt::WA_TranslucentBackground); //this->setAttribute(Qt::WA_NoSystemBackground); this->setAutoFillBackground(false); - this->setStyleSheet("QWidget#LuminaDesktopPluginSpace{ border: none; background: transparent; }"); + this->setStyleSheet("QWidget#LuminaDesktopPluginSpace{ border: none; background: transparent; }"); this->setWindowFlags(Qt::WindowStaysOnBottomHint | Qt::CustomizeWindowHint | Qt::FramelessWindowHint); this->setAcceptDrops(true); this->setContextMenuPolicy(Qt::NoContextMenu); @@ -34,7 +34,7 @@ LDesktopPluginSpace::LDesktopPluginSpace() : QWidget(){ } LDesktopPluginSpace::~LDesktopPluginSpace(){ - + } void LDesktopPluginSpace::LoadItems(QStringList plugs, QStringList files){ @@ -76,7 +76,7 @@ void LDesktopPluginSpace::setBackground(QPixmap pix){ void LDesktopPluginSpace::setDesktopArea(QRect area){ //qDebug() << "Setting Desktop Plugin Area:" << area; desktopRect = area; - + } // =================== @@ -222,7 +222,7 @@ QRect LDesktopPluginSpace::findOpenSpot(int gridwidth, int gridheight, int start //else{ row++; } } if(!found){ col++; row=0; } //go to the next column - } + } }else if(reversed && (startRow>0 || startCol>0) ){ //Arrange Left->Right (work backwards) while(row>=0 && !found){ @@ -242,7 +242,7 @@ QRect LDesktopPluginSpace::findOpenSpot(int gridwidth, int gridheight, int start //else{ col++; } } if(!found){ row--; col=colCount-gridwidth;} //go to the previous row - } + } }else{ //Arrange Left->Right while(row<(rowCount-gridheight) && !found){ @@ -296,8 +296,8 @@ void LDesktopPluginSpace::reloadPlugins(bool ForceIconUpdate ){ QStringList plugs = plugins; QStringList items = deskitems; for(int i=0; i<ITEMS.length(); i++){ - - if( ITEMS[i]->whatsThis().startsWith("applauncher") && ForceIconUpdate){ + + if( ITEMS[i]->whatsThis().startsWith("applauncher") && ForceIconUpdate){ //Change the size of the existing plugin - preserving the location if possible /*QRect geom = ITEMS[i]->loadPluginGeometry(); //pixel coords if(!geom.isNull()){ @@ -306,14 +306,14 @@ void LDesktopPluginSpace::reloadPlugins(bool ForceIconUpdate ){ ITEMS[i]->savePluginGeometry( gridToGeom(geom)); //save it back in pixel coords }*/ //Now remove the plugin for the moment - run it through the re-creation routine below - ITEMS.takeAt(i)->deleteLater(); + ITEMS.takeAt(i)->deleteLater(); i--; } else if(plugs.contains(ITEMS[i]->whatsThis())){ plugs.removeAll(ITEMS[i]->whatsThis()); } else if(items.contains(ITEMS[i]->whatsThis().section("---",0,0).section("::",1,50))){ items.removeAll(ITEMS[i]->whatsThis().section("---",0,0).section("::",1,50)); } else{ ITEMS[i]->removeSettings(true); ITEMS.takeAt(i)->deleteLater(); i--; } //this is considered a permanent removal (cleans settings) } - + //Now create any new items //First load the plugins (almost always have fixed locations) for(int i=0; i<plugs.length(); i++){ diff --git a/src-qt5/core/lumina-desktop/LSession.cpp b/src-qt5/core/lumina-desktop/LSession.cpp index 2a1ec783..dab30f01 100644 --- a/src-qt5/core/lumina-desktop/LSession.cpp +++ b/src-qt5/core/lumina-desktop/LSession.cpp @@ -98,7 +98,7 @@ void LSession::setupSession(){ qDebug() << "Initializing Session"; if(QFile::exists("/tmp/.luminastopping")){ QFile::remove("/tmp/.luminastopping"); } QTime* timer = 0; - //if(DEBUG){ timer = new QTime(); timer->start(); qDebug() << " - Init srand:" << timer->elapsed();} + if(DEBUG){ timer = new QTime(); timer->start(); qDebug() << " - Init srand:" << timer->elapsed();} //Setup the QSettings default paths splash.showScreen("settings"); @@ -118,9 +118,9 @@ void LSession::setupSession(){ } //use the system settings //Setup the user's lumina settings directory as necessary - splash.showScreen("user"); - if(DEBUG){ qDebug() << " - Init User Files:" << timer->elapsed();} - checkUserFiles(); //adds these files to the watcher as well + //splash.showScreen("user"); + //if(DEBUG){ qDebug() << " - Init User Files:" << timer->elapsed();} + //checkUserFiles(); //adds these files to the watcher as well //Initialize the internal variables DESKTOPS.clear(); @@ -147,11 +147,12 @@ void LSession::setupSession(){ if(DEBUG){ qDebug() << " - Init Desktops:" << timer->elapsed();} desktopFiles = QDir(QDir::homePath()+"/Desktop").entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs, QDir::Name | QDir::IgnoreCase | QDir::DirsFirst); updateDesktops(); - for(int i=0; i<6; i++){ LSession::processEvents(); } //Run through this a few times so the interface systems get up and running + //if(DEBUG){ qDebug() << " - Process Events (6x):" << timer->elapsed();} + //for(int i=0; i<6; i++){ LSession::processEvents(); } //Run through this a few times so the interface systems get up and running //Now setup the system watcher for changes splash.showScreen("final"); - qDebug() << " - Initialize file system watcher"; + //qDebug() << " - Initialize file system watcher"; if(DEBUG){ qDebug() << " - Init QFileSystemWatcher:" << timer->elapsed();} watcher = new QFileSystemWatcher(this); QString confdir = sessionsettings->fileName().section("/",0,-2); @@ -171,14 +172,18 @@ void LSession::setupSession(){ connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(watcherChange(QString)) ); connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(watcherChange(QString)) ); connect(this, SIGNAL(aboutToQuit()), this, SLOT(SessionEnding()) ); - if(DEBUG){ qDebug() << " - Init Finished:" << timer->elapsed(); delete timer;} - for(int i=0; i<4; i++){ LSession::processEvents(); } //Again, just a few event loops here so thing can settle before we close the splash screen + //if(DEBUG){ qDebug() << " - Process Events (4x):" << timer->elapsed();} + //for(int i=0; i<4; i++){ LSession::processEvents(); } //Again, just a few event loops here so thing can settle before we close the splash screen + if(DEBUG){ qDebug() << " - Launch Startup Apps:" << timer->elapsed();} //launchStartupApps(); QTimer::singleShot(500, this, SLOT(launchStartupApps()) ); - splash.hide(); - LSession::processEvents(); + //if(DEBUG){ qDebug() << " - Hide Splashscreen:" << timer->elapsed();} + //splash.hide(); + //LSession::processEvents(); + if(DEBUG){ qDebug() << " - Close Splashscreen:" << timer->elapsed();} splash.close(); - LSession::processEvents(); + //LSession::processEvents(); + if(DEBUG){ qDebug() << " - Init Finished:" << timer->elapsed(); delete timer;} } void LSession::CleanupSession(){ @@ -289,7 +294,7 @@ void LSession::launchStartupApps(){ qDebug() << " - - Screen Brightness:" << QString::number(tmp)+"%"; } //QProcess::startDetached("nice lumina-open -autostart-apps"); - ExternalProcess::launch("nice lumina-open -autostart-apps"); + ExternalProcess::launch("lumina-open", QStringList() << "-autostart-apps", false); //Re-load the screen brightness and volume settings from the previous session // Wait until after the XDG-autostart functions, since the audio system might be started that way @@ -303,7 +308,7 @@ void LSession::launchStartupApps(){ QString sfile = sessionsettings->value("audiofiles/login", LOS::LuminaShare()+"Login.ogg").toString(); playAudioFile(sfile); } - qDebug() << "[DESKTOP INIT FINISHED]"; + //qDebug() << "[DESKTOP INIT FINISHED]"; } void LSession::StartLogout(){ @@ -384,15 +389,26 @@ void LSession::checkWindowGeoms(){ } } -void LSession::checkUserFiles(){ +bool LSession::checkUserFiles(){ //internal version conversion examples: // [1.0.0 -> 1000000], [1.2.3 -> 1002003], [0.6.1 -> 6001] - QString OVS = sessionsettings->value("DesktopVersion","0").toString(); //Old Version String - bool changed = LDesktopUtils::checkUserFiles(OVS); + qDebug() << "Check User Files"; + //char tmp[] = "junk\0"; + //int tmpN = 0; + //QApplication A(tmpN, (char **)&tmp); + QSettings sset("lumina-desktop", "sessionsettings"); + QString OVS = sset.value("DesktopVersion","0").toString(); //Old Version String + qDebug() << " - Old Version:" << OVS; + qDebug() << " - Current Version:" << LDesktopUtils::LuminaDesktopVersion(); + bool changed = LDesktopUtils::checkUserFiles(OVS, LDesktopUtils::LuminaDesktopVersion()); + qDebug() << " - Made Changes:" << changed; if(changed){ //Save the current version of the session to the settings file (for next time) - sessionsettings->setValue("DesktopVersion", this->applicationVersion()); + sset.setValue("DesktopVersion", LDesktopUtils::LuminaDesktopVersion()); } + qDebug() << "Finished with user files check"; + //delete A; + return changed; } void LSession::refreshWindowManager(){ @@ -573,7 +589,7 @@ void LSession::SessionEnding(){ //=============== void LSession::LaunchApplication(QString cmd){ //LSession::setOverrideCursor(QCursor(Qt::BusyCursor)); - ExternalProcess::launch(cmd); + ExternalProcess::launch(cmd, QStringList(), true); //QProcess::startDetached(cmd); } @@ -674,7 +690,7 @@ void LSession::WindowPropertyEvent(){ if(RunningApps.length() < newapps.length()){ //New Window found //qDebug() << "New window found"; - LSession::restoreOverrideCursor(); //restore the mouse cursor back to normal (new window opened?) + //LSession::restoreOverrideCursor(); //restore the mouse cursor back to normal (new window opened?) //Perform sanity checks on any new window geometries for(int i=0; i<newapps.length() && !TrayStopping; i++){ if(!RunningApps.contains(newapps[i])){ @@ -826,7 +842,7 @@ void LSession::attachTrayWindow(WId win){ if(RunningTrayApps.contains(win)){ return; } //already managed qDebug() << "Session Tray: Window Added"; RunningTrayApps << win; - LSession::restoreOverrideCursor(); + //LSession::restoreOverrideCursor(); if(DEBUG){ qDebug() << "Tray List Changed"; } emit TrayListChanged(); } diff --git a/src-qt5/core/lumina-desktop/LSession.h b/src-qt5/core/lumina-desktop/LSession.h index 0d69df84..a25f3c15 100644 --- a/src-qt5/core/lumina-desktop/LSession.h +++ b/src-qt5/core/lumina-desktop/LSession.h @@ -39,7 +39,7 @@ #define SYSTEM_TRAY_CANCEL_MESSAGE 2 /*class MenuProxyStyle : public QProxyStyle{ -public: +public: int pixelMetric(PixelMetric metric, const QStyleOption *option=0, const QWidget *widget=0) const{ if(metric==PM_SmallIconSize){ return 22; } //override QMenu icon size (make it larger) else{ return QProxyStyle::pixelMetric(metric, option, widget); } //use the current style for everything else @@ -51,6 +51,8 @@ class LSession : public LSingleApplication{ public: LSession(int &argc, char **argv); ~LSession(); + + static bool checkUserFiles(); //Functions to be called during startup void setupSession(); @@ -63,7 +65,7 @@ public: bool registerStartButton(QString ID); void unregisterStartButton(QString ID); - //Special functions for XCB event filter parsing only + //Special functions for XCB event filter parsing only // (DO NOT USE MANUALLY) void RootSizeChange(); void WindowPropertyEvent(); @@ -73,37 +75,37 @@ public: void WindowConfigureEvent(WId); void WindowDamageEvent(WId); void WindowSelectionClearEvent(WId); - + //System Access //Return a pointer to the current session static LSession* handle(){ return static_cast<LSession*>(LSession::instance()); } - + static void LaunchApplication(QString cmd); QFileInfoList DesktopFiles(); - + QRect screenGeom(int num); - + AppMenu* applicationMenu(); void systemWindow(); SettingsMenu* settingsMenu(); LXCB *XCB; //class for XCB usage - + QSettings* sessionSettings(); QSettings* DesktopPluginSettings(); - + //Keep track of which non-desktop window should be treated as active WId activeWindow(); //This will return the last active window if a desktop element is currently active - + //Temporarily change the session locale (nothing saved between sessions) void switchLocale(QString localeCode); - + //Play System Audio void playAudioFile(QString filepath); //Window Adjustment Routine (due to Fluxbox not respecting _NET_WM_STRUT) void adjustWindowGeom(WId win, bool maximize = false); - + private: //WMProcess *WM; QList<LDesktop*> DESKTOPS; @@ -136,9 +138,9 @@ private: QFileInfoList desktopFiles; void CleanupSession(); - + int VersionStringToNumber(QString version); - + public slots: void StartLogout(); void StartShutdown(bool skipupdates = false); @@ -161,7 +163,6 @@ private slots: void removeTrayWindow(WId); //Internal simplification functions - void checkUserFiles(); void refreshWindowManager(); void updateDesktops(); void registerDesktopWindows(); @@ -189,7 +190,7 @@ signals: void DesktopFilesChanged(); void MediaFilesChanged(); void WorkspaceChanged(); - + }; #endif diff --git a/src-qt5/core/lumina-desktop/LXcbEventFilter.cpp b/src-qt5/core/lumina-desktop/LXcbEventFilter.cpp index ca7fb38d..038872ff 100644 --- a/src-qt5/core/lumina-desktop/LXcbEventFilter.cpp +++ b/src-qt5/core/lumina-desktop/LXcbEventFilter.cpp @@ -52,8 +52,8 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag session->emit WorkspaceChanged(); }else if( SysNotifyAtoms.contains( ((xcb_property_notify_event_t*)ev)->atom ) ){ //Update the status/list of all running windows - session->WindowPropertyEvent(); - + session->WindowPropertyEvent(); + //window-specific property change }else if( WinNotifyAtoms.contains( ((xcb_property_notify_event_t*)ev)->atom ) ){ //Ping only that window @@ -61,7 +61,7 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag session->WindowPropertyEvent(); } break; -//============================== +//============================== case XCB_CLIENT_MESSAGE: //qDebug() << "Client Message Event"; //qDebug() << " - Root Window:" << QX11Info::appRootWindow(); @@ -72,7 +72,7 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag session->SysTrayDockRequest( ((xcb_client_message_event_t*)ev)->data.data32[2] ); } //Ignore the System Tray messages at the moment (let the WM handle it) - + //window-specific property changes /*}else if( ((xcb_client_message_event_t*)ev)->type == session->XCB->EWMH._NET_WM_STATE ){ if( session->XCB->WindowIsMaximized( ((xcb_client_message_event_t*)ev)->window ) ){ @@ -86,22 +86,22 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag session->WindowPropertyEvent(); } break; -//============================== +//============================== case XCB_DESTROY_NOTIFY: //qDebug() << "Window Closed Event"; session->WindowClosedEvent( ( (xcb_destroy_notify_event_t*)ev )->window ); break; -//============================== +//============================== case XCB_CONFIGURE_NOTIFY: //qDebug() << "Configure Notify Event"; session->WindowConfigureEvent( ((xcb_configure_notify_event_t*)ev)->window ); break; -//============================== +//============================== case XCB_SELECTION_CLEAR: //qDebug() << "Selection Clear Event"; - session->WindowSelectionClearEvent( ((xcb_selection_clear_event_t*)ev)->owner ); + session->WindowSelectionClearEvent( ((xcb_selection_clear_event_t*)ev)->owner ); break; -//============================== +//============================== default: if(TrayDmgFlag!=0){ //if( (ev->response_type & ~0x80)==TrayDmgFlag){ diff --git a/src-qt5/core/lumina-desktop/WMProcess.cpp b/src-qt5/core/lumina-desktop/WMProcess.cpp index aa01b730..0687c1fe 100644 --- a/src-qt5/core/lumina-desktop/WMProcess.cpp +++ b/src-qt5/core/lumina-desktop/WMProcess.cpp @@ -30,7 +30,7 @@ void WMProcess::startWM(){ if(!isRunning()){this->start(cmd); } /*if(ssaver->state() == QProcess::NotRunning \ && LSession::handle()->sessionSettings()->value("WindowManager", "fluxbox").toString() != "lumina-wm"){ - ssaver->start("xscreensaver -no-splash"); + ssaver->start("xscreensaver -no-splash"); }*/ } @@ -52,8 +52,8 @@ void WMProcess::restartWM(){ inShutdown = true; this->kill(); if(!this->waitForFinished(5000) ){ this->terminate(); }; - inShutdown = false; - } + inShutdown = false; + } this->startWM(); } diff --git a/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf b/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf index e453c0b8..e9520a3c 100644 --- a/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf +++ b/src-qt5/core/lumina-desktop/defaults/luminaDesktop-TrueOS.conf @@ -53,7 +53,7 @@ mime_default_application/x-tar_ifexists=lumina-archiver.desktop #THEME SETTINGS theme_themefile=DarkGlass #Name of the theme to use (disable for Lumina-Default) -theme_colorfile=Black #Name of the color spec file to use for theming +theme_colorfile=darker #Name of the color spec file to use for theming theme_iconset=material-design-dark #Name of the icon theme to use theme_font=Noto Sans #Name of the font family to use theme_fontsize=10pt #Default size of the fonts to use on the desktop (can also use a percentage of the screen height (<number>%) ) diff --git a/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf b/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf index 1327f148..40ece4f0 100644 --- a/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf +++ b/src-qt5/core/lumina-desktop/defaults/luminaDesktop.conf @@ -51,7 +51,7 @@ mime_default_application/x-shellscript=lumina-textedit.desktop #THEME SETTINGS theme_themefile=DarkGlass #Name of the theme to use (disable for Lumina-Default) -theme_colorfile=Black #Name of the color spec file to use for theming +theme_colorfile=darker #Name of the color spec file to use for theming theme_iconset=material-design-dark #Name of the icon theme to use theme_font=Arial #Name of the font family to use theme_fontsize=10pt #Default size of the fonts to use on the desktop (can also use a percentage of the screen height (<number>%) ) diff --git a/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp b/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp index 0258d561..0bf087c1 100644 --- a/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp +++ b/src-qt5/core/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp @@ -44,7 +44,8 @@ void AppLauncherPlugin::loadButton(){ QFileInfo info(path); this->contextMenu()->clear(); //qDebug() << "Default Application Launcher:" << def << path; - bool ok = QFile::exists(path); + bool ok = info.canonicalPath().startsWith("/net/"); + if(!ok){ ok = QFile::exists(path); } //do it this way to ensure the file existance check never runs for /net/ files if(!ok){ emit RemovePlugin(this->ID()); return;} icosize = this->height()-4 - 2.2*button->fontMetrics().height(); button->setFixedSize( this->width()-4, this->height()-4); diff --git a/src-qt5/core/lumina-desktop/i18n/lumina-desktop_et.ts b/src-qt5/core/lumina-desktop/i18n/lumina-desktop_et.ts index ef19e5a0..456d5aff 100644 --- a/src-qt5/core/lumina-desktop/i18n/lumina-desktop_et.ts +++ b/src-qt5/core/lumina-desktop/i18n/lumina-desktop_et.ts @@ -40,47 +40,47 @@ <message> <location filename="../desktop-plugins/applauncher/AppLauncherPlugin.cpp" line="73"/> <source>Launch %1</source> - <translation type="unfinished">Käivita %1</translation> + <translation>Käivita %1</translation> </message> <message> <location filename="../desktop-plugins/applauncher/AppLauncherPlugin.cpp" line="134"/> <source>Open</source> - <translation type="unfinished">Ava</translation> + <translation>Ava</translation> </message> <message> <location filename="../desktop-plugins/applauncher/AppLauncherPlugin.cpp" line="136"/> <source>Open With</source> - <translation type="unfinished"></translation> + <translation>Ava Kasutades</translation> </message> <message> <location filename="../desktop-plugins/applauncher/AppLauncherPlugin.cpp" line="139"/> <source>View Properties</source> - <translation type="unfinished"></translation> + <translation>Vaata Omadusi</translation> </message> <message> <location filename="../desktop-plugins/applauncher/AppLauncherPlugin.cpp" line="141"/> <source>File Operations</source> - <translation type="unfinished"></translation> + <translation>Failioperatsioonid</translation> </message> <message> <location filename="../desktop-plugins/applauncher/AppLauncherPlugin.cpp" line="143"/> <source>Rename</source> - <translation type="unfinished"></translation> + <translation>Nimeta Ümber</translation> </message> <message> <location filename="../desktop-plugins/applauncher/AppLauncherPlugin.cpp" line="146"/> <source>Copy</source> - <translation type="unfinished">Kopeeri</translation> + <translation>Kopeeri</translation> </message> <message> <location filename="../desktop-plugins/applauncher/AppLauncherPlugin.cpp" line="149"/> <source>Cut</source> - <translation type="unfinished">Lõika</translation> + <translation>Lõika</translation> </message> <message> <location filename="../desktop-plugins/applauncher/AppLauncherPlugin.cpp" line="151"/> <source>Delete</source> - <translation type="unfinished">Kustuta</translation> + <translation>Kustuta</translation> </message> <message> <location filename="../desktop-plugins/applauncher/AppLauncherPlugin.cpp" line="213"/> @@ -95,7 +95,7 @@ <message> <location filename="../desktop-plugins/applauncher/AppLauncherPlugin.cpp" line="299"/> <source>New Filename</source> - <translation type="unfinished"></translation> + <translation>Uus Failinimi</translation> </message> </context> <context> @@ -103,12 +103,12 @@ <message> <location filename="../AppMenu.cpp" line="48"/> <source>Desktop</source> - <translation type="unfinished">Töölaud</translation> + <translation>Töölaud</translation> </message> <message> <location filename="../AppMenu.cpp" line="85"/> <source>Manage Applications</source> - <translation type="unfinished"></translation> + <translation>Halda Rakendusi</translation> </message> <message> <location filename="../AppMenu.cpp" line="90"/> @@ -196,47 +196,47 @@ <message> <location filename="../BootSplash.ui" line="94"/> <source>Starting the Lumina Desktop...</source> - <translation type="unfinished"></translation> + <translation>Lumina Töölaua käivitumine...</translation> </message> <message> <location filename="../BootSplash.cpp" line="17"/> <source>Version %1</source> - <translation type="unfinished"></translation> + <translation>Versioon %1</translation> </message> <message> <location filename="../BootSplash.cpp" line="41"/> <source>This desktop is powered by coffee, coffee, and more coffee.</source> - <translation type="unfinished"></translation> + <translation>Töölaua valmimist on toetanud kohvi, kohvi ja veel rohkem kohvi.</translation> </message> <message> <location filename="../BootSplash.cpp" line="43"/> <source>Keep up with desktop news!</source> - <translation type="unfinished"></translation> + <translation>Pea silm peal töölaua uudistel!</translation> </message> <message> <location filename="../BootSplash.cpp" line="45"/> <source>There is a full handbook of information about the desktop available online.</source> - <translation type="unfinished"></translation> + <translation>Võrgus on Töölaua kohta olemas täiemahuline käsiraamat (ingl.k)</translation> </message> <message> <location filename="../BootSplash.cpp" line="47"/> <source>Want to change the interface? Everything is customizable in the desktop configuration!</source> - <translation type="unfinished"></translation> + <translation>Soovid muuta kasutajaliidest? Kõik töölaua konfiguratsioonis on muudetav!</translation> </message> <message> <location filename="../BootSplash.cpp" line="49"/> <source>Lumina can easily reproduce the interface from most other desktop environments.</source> - <translation type="unfinished"></translation> + <translation>Lumina võimaldab kergesti taasluua kasutajaliideseid enamikest muudest töölauakeskkondadest</translation> </message> <message> <location filename="../BootSplash.cpp" line="51"/> <source>This desktop is generously sponsored by iXsystems</source> - <translation type="unfinished"></translation> + <translation>Selle töölaua valmimist on heldelt toetanud iXsystems</translation> </message> <message> <location filename="../BootSplash.cpp" line="53"/> <source>I have never been hurt by what I have not said</source> - <translation type="unfinished"></translation> + <translation>Mulle ei ole kunagi haiget teenud ütlemata jäänud asjad</translation> </message> <message> <location filename="../BootSplash.cpp" line="55"/> @@ -246,22 +246,22 @@ <message> <location filename="../BootSplash.cpp" line="57"/> <source>Everything has its beauty but not everyone sees it.</source> - <translation type="unfinished"></translation> + <translation>Kõigel on oma ilu kuid mitte kõik ei oska seda näha</translation> </message> <message> <location filename="../BootSplash.cpp" line="59"/> <source>Before God we are all equally wise - and equally foolish.</source> - <translation type="unfinished"></translation> + <translation>Jumala ees oleme kõik võrdselt targad - ja võrdselt lollid.</translation> </message> <message> <location filename="../BootSplash.cpp" line="61"/> <source>We cannot do everything at once, but we can do something at once.</source> - <translation type="unfinished"></translation> + <translation>Me ei saa teha kõike ühekorraga, kuid me saame teha midagi kohe.</translation> </message> <message> <location filename="../BootSplash.cpp" line="63"/> <source>One with the law is a majority.</source> - <translation type="unfinished"></translation> + <translation type="unfinished></translation> </message> <message> <location filename="../BootSplash.cpp" line="65"/> @@ -271,217 +271,218 @@ <message> <location filename="../BootSplash.cpp" line="67"/> <source>You can't know too much, but you can say too much.</source> - <translation type="unfinished"></translation> + <translation>Sa ei saa kunagi teada liiga palju, kuid saad öelda.</translation> </message> <message> <location filename="../BootSplash.cpp" line="69"/> <source>Duty is not collective; it is personal.</source> - <translation type="unfinished"></translation> + <translation>Kohusetunne ei ole kollektiivne, see on isiklik</translation> </message> <message> <location filename="../BootSplash.cpp" line="71"/> <source>Any society that would give up a little liberty to gain a little security will deserve neither and lose both.</source> - <translation type="unfinished"></translation> + <translation>Ühiskond, mis annab ära veidikene vabadust et lisada veidikene turvalisust, ei vääri kumbagi ning kaotab mõlemad.</translation> </message> <message> <location filename="../BootSplash.cpp" line="73"/> <source>Never trust a computer you can’t throw out a window.</source> - <translation type="unfinished"></translation> + <translation>Ära kunagi usalda kompuutrit, mida ei ole võimalik aknast välja visata.</translation> </message> <message> <location filename="../BootSplash.cpp" line="75"/> <source>Study the past if you would define the future.</source> - <translation type="unfinished"></translation> + <translation>Tuleviku ennustamiseks õpi minevikku.</translation> </message> <message> <location filename="../BootSplash.cpp" line="77"/> <source>The way to get started is to quit talking and begin doing.</source> - <translation type="unfinished"></translation> + <translation>Meetod alustamiseks: lõpeta seletamine ja hakka tegema.</translation> </message> <message> <location filename="../BootSplash.cpp" line="79"/> <source>Ask and it will be given to you; search, and you will find; knock and the door will be opened for you.</source> - <translation type="unfinished"></translation> + <translation>Küsi, ja sulle antakse; Otsi, ning sa leiad; Koputa, ning uks avatakse sulle.</translation> </message> <message> <location filename="../BootSplash.cpp" line="81"/> <source>Start where you are. Use what you have. Do what you can.</source> - <translation type="unfinished"></translation> + <translation>Alusta, sealt kus sa oled. Kasuta, mis sul on. Tee, mis saad.</translation> </message> <message> <location filename="../BootSplash.cpp" line="83"/> <source>A person who never made a mistake never tried anything new.</source> - <translation type="unfinished"></translation> + <translation>Inimene, kes kunagi pole eksinud, ei ole kunagi proovinud teha midagi uut.</translation> </message> <message> <location filename="../BootSplash.cpp" line="85"/> <source>It does not matter how slowly you go as long as you do not stop.</source> - <translation type="unfinished"></translation> + <translation>Pole oluline kui aeglaselt sa kulged, kuni sa ei peatu.</translation> </message> <message> <location filename="../BootSplash.cpp" line="87"/> <source>Do what you can, where you are, with what you have.</source> - <translation type="unfinished"></translation> + <translation>Tee mis saad, kus parajasti oled, mis käepärast on.</translation> </message> <message> <location filename="../BootSplash.cpp" line="89"/> <source>Remember no one can make you feel inferior without your consent.</source> - <translation type="unfinished"></translation> + <translation>Pea meeles et mitte keegi ei saa sind panna tundma alaväärtuslikuna ilma su enda nõusolekuta</translation> </message> <message> <location filename="../BootSplash.cpp" line="91"/> <source>It’s not the years in your life that count. It’s the life in your years.</source> - <translation type="unfinished"></translation> + <translation>Olulised pole elatud aastad. Oluline on elada igas aastas.</translation> </message> <message> <location filename="../BootSplash.cpp" line="93"/> <source>Either write something worth reading or do something worth writing.</source> - <translation type="unfinished"></translation> + <translation>Kirjuta midagi väärt lugemist või tee midagi väärt kirjutamist.</translation> </message> <message> <location filename="../BootSplash.cpp" line="95"/> <source>The only way to do great work is to love what you do.</source> - <translation type="unfinished"></translation> + <translation>Ainus valem heaks tööks on armastada seda.</translation> </message> <message> <location filename="../BootSplash.cpp" line="97"/> <source>Political correctness is tyranny with manners.</source> - <translation type="unfinished"></translation> + <translation>Poliitkorrektsus on kommetega türannia.</translation> </message> <message> <location filename="../BootSplash.cpp" line="99"/> <source>Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.</source> - <translation type="unfinished"></translation> + <translation>Ainult kaks asja on lõputud. Universum ja inimese lollus. Ma ei ole kusjuures esimeses kindel.</translation> </message> + <message> <location filename="../BootSplash.cpp" line="101"/> <source>I find that the harder I work, the more luck I seem to have.</source> - <translation type="unfinished"></translation> + <translation>Olen avastanud et mida rohkem ma tööd raban, seda rohkem õnne näib mul olevat.</translation> </message> <message> <location filename="../BootSplash.cpp" line="103"/> <source>Do, or do not. There is no 'try'.</source> - <translation type="unfinished"></translation> + <translation>Tee, või ära tee. Lihtsalt proovimine ei ole variant.</translation> </message> <message> <location filename="../BootSplash.cpp" line="105"/> <source>A mathematician is a device for turning coffee into theorems.</source> - <translation type="unfinished"></translation> + <translation>Matemaatik on seade, mis muudab kohvi teoreemideks.</translation> </message> <message> <location filename="../BootSplash.cpp" line="107"/> <source>Good people do not need laws to tell them to act responsibly, while bad people will find a way around the laws.</source> - <translation type="unfinished"></translation> + <translation>Head inimesed ei vaja seadusi käitumaks vastutustundlikult, sellal kui halvad inimesed leiavad tee seadustest möödahiilimiseks.</translation> </message> <message> <location filename="../BootSplash.cpp" line="109"/> <source>Black holes are where God divided by zero.</source> - <translation type="unfinished"></translation> + <translation>Mustad augud Universumis on kohad, kus Jumal jagas nulliga.</translation> </message> <message> <location filename="../BootSplash.cpp" line="111"/> <source>It's kind of fun to do the impossible.</source> - <translation type="unfinished"></translation> + <translation>On omamoodi lõbus saata korda võimatut.</translation> </message> <message> <location filename="../BootSplash.cpp" line="113"/> <source>Knowledge speaks, but wisdom listens.</source> - <translation type="unfinished"></translation> + <translation>Teadmised räägivad, tarkus kuulab.</translation> </message> <message> <location filename="../BootSplash.cpp" line="115"/> <source>A witty saying proves nothing.</source> - <translation type="unfinished"></translation> + <translation>Kaval ütlus ei tõesta midagi.</translation> </message> <message> <location filename="../BootSplash.cpp" line="117"/> <source>Success usually comes to those who are too busy to be looking for it.</source> - <translation type="unfinished"></translation> + <translation>Edu tuleb tavaliselt nende juurde, kel on liiga kiire, selleks et seda otsida.</translation> </message> <message> <location filename="../BootSplash.cpp" line="119"/> <source>Well-timed silence hath more eloquence than speech.</source> - <translation type="unfinished"></translation> + <translation>Hästiajastatud vaikus on väljendusrikkam kui kõne</translation> </message> <message> <location filename="../BootSplash.cpp" line="121"/> <source>I have never let my schooling interfere with my education.</source> - <translation type="unfinished"></translation> + <translation>Ma ei ole kunagi lasknud koolil segada enda harimist.</translation> </message> <message> <location filename="../BootSplash.cpp" line="123"/> <source>The best way to predict the future is to invent it.</source> - <translation type="unfinished"></translation> + <translation>Parim meetod tuleviku ennustamiseks on see leiutada</translation> </message> <message> <location filename="../BootSplash.cpp" line="125"/> <source>Well done is better than well said.</source> - <translation type="unfinished"></translation> + <translation>Hästitehtu on parem kui hästiöeldu.</translation> </message> <message> <location filename="../BootSplash.cpp" line="127"/> <source>Sometimes it is not enough that we do our best; we must do what is required.</source> - <translation type="unfinished"></translation> + <translation>Vahel ei piisa meie parimast; Peame tegema seda, mis on vaja.</translation> </message> <message> <location filename="../BootSplash.cpp" line="129"/> <source>The truth is more important than the facts.</source> - <translation type="unfinished"></translation> + <translation>Tõde on olulisem kui faktid.</translation> </message> <message> <location filename="../BootSplash.cpp" line="131"/> <source>Better to remain silent and be thought a fool than to speak out and remove all doubt.</source> - <translation type="unfinished"></translation> + <translation>Parem olla vait ja lasta endast mõelda kui lollist kui teha suu lahti ja eemaldada kõik kahtlused.</translation> </message> <message> <location filename="../BootSplash.cpp" line="142"/> <source>Initializing Session …</source> - <translation type="unfinished"></translation> + <translation>Seansi käivitumine...</translation> </message> <message> <location filename="../BootSplash.cpp" line="145"/> <source>Loading System Settings …</source> - <translation type="unfinished"></translation> + <translation>Süsteemi Seadete laadimine...</translation> </message> <message> <location filename="../BootSplash.cpp" line="148"/> <source>Loading User Preferences …</source> - <translation type="unfinished"></translation> + <translation>Kasutajaeelistuste laadimine...</translation> </message> <message> <location filename="../BootSplash.cpp" line="151"/> <source>Preparing System Tray …</source> - <translation type="unfinished"></translation> + <translation>Süsteemi tööriba ettevalimistamine...</translation> </message> <message> <location filename="../BootSplash.cpp" line="154"/> <source>Starting Window Manager …</source> - <translation type="unfinished"></translation> + <translation>Aknahalduri käivitumine...</translation> </message> <message> <location filename="../BootSplash.cpp" line="157"/> <source>Detecting Applications …</source> - <translation type="unfinished"></translation> + <translation>Olemasolevate programmide tuvastamine...</translation> </message> <message> <location filename="../BootSplash.cpp" line="160"/> <source>Preparing Menus …</source> - <translation type="unfinished"></translation> + <translation>Kasutajamenüüde ettevalmistamine...</translation> </message> <message> <location filename="../BootSplash.cpp" line="163"/> <source>Preparing Workspace …</source> - <translation type="unfinished"></translation> + <translation>Töölaua ettevalmistamine...</translation> </message> <message> <location filename="../BootSplash.cpp" line="166"/> <source>Finalizing …</source> - <translation type="unfinished"></translation> + <translation>Viimased liigutused...</translation> </message> <message> <location filename="../BootSplash.cpp" line="169"/> <source>Starting App: %1</source> - <translation type="unfinished"></translation> + <translation>Käivitan rakenduse: %1</translation> </message> </context> <context> @@ -527,7 +528,7 @@ <message> <location filename="../panel-plugins/systemstart/ItemWidget.cpp" line="44"/> <source>Go Back</source> - <translation type="unfinished">Mine tagasi</translation> + <translation>Mine tagasi</translation> </message> <message> <location filename="../panel-plugins/systemstart/ItemWidget.cpp" line="190"/> @@ -547,12 +548,12 @@ <message> <location filename="../panel-plugins/systemstart/ItemWidget.cpp" line="204"/> <source>Remove from Quicklaunch</source> - <translation type="unfinished"></translation> + <translation>Eemalda Kiirkäivitusest</translation> </message> <message> <location filename="../panel-plugins/systemstart/ItemWidget.cpp" line="208"/> <source>Add to Quicklaunch</source> - <translation type="unfinished"></translation> + <translation>Lisa Kiirkäivitusse</translation> </message> </context> <context> @@ -560,7 +561,7 @@ <message> <location filename="../JsonMenu.h" line="60"/> <source>Error parsing script output: %1</source> - <translation type="unfinished"></translation> + <translation>Viga skripti väljundi töötlemisel: %1</translation> </message> </context> <context> @@ -573,92 +574,92 @@ <message> <location filename="../panel-plugins/appmenu/LAppMenuPlugin.cpp" line="38"/> <source>Applications</source> - <translation type="unfinished">Rakendused</translation> + <translation>Rakendused</translation> </message> <message> <location filename="../panel-plugins/appmenu/LAppMenuPlugin.cpp" line="68"/> <source>Browse Files</source> - <translation type="unfinished"></translation> + <translation></translation> </message> <message> <location filename="../panel-plugins/appmenu/LAppMenuPlugin.cpp" line="73"/> <source>Install Applications</source> - <translation type="unfinished">Paigalda rakendusi</translation> + <translation>Paigalda rakendusi</translation> </message> <message> <location filename="../panel-plugins/appmenu/LAppMenuPlugin.cpp" line="79"/> <source>Control Panel</source> - <translation type="unfinished">Juhtpaneel</translation> + <translation>Juhtpaneel</translation> </message> <message> <location filename="../panel-plugins/appmenu/LAppMenuPlugin.cpp" line="90"/> <source>Multimedia</source> - <translation type="unfinished">Multimeedia</translation> + <translation>Multimeedia</translation> </message> <message> <location filename="../panel-plugins/appmenu/LAppMenuPlugin.cpp" line="91"/> <source>Development</source> - <translation type="unfinished">Arendus</translation> + <translation>Arendustarkvara</translation> </message> <message> <location filename="../panel-plugins/appmenu/LAppMenuPlugin.cpp" line="92"/> <source>Education</source> - <translation type="unfinished">Haridus</translation> + <translation>Haridus</translation> </message> <message> <location filename="../panel-plugins/appmenu/LAppMenuPlugin.cpp" line="93"/> <source>Games</source> - <translation type="unfinished">Mängud</translation> + <translation>Mängud</translation> </message> <message> <location filename="../panel-plugins/appmenu/LAppMenuPlugin.cpp" line="94"/> <source>Graphics</source> - <translation type="unfinished">Graafika</translation> + <translation>Graafika</translation> </message> <message> <location filename="../panel-plugins/appmenu/LAppMenuPlugin.cpp" line="95"/> <source>Network</source> - <translation type="unfinished">Võrk</translation> + <translation>Võrk</translation> </message> <message> <location filename="../panel-plugins/appmenu/LAppMenuPlugin.cpp" line="96"/> <source>Office</source> - <translation type="unfinished">Kontor</translation> + <translation>Kontor</translation> </message> <message> <location filename="../panel-plugins/appmenu/LAppMenuPlugin.cpp" line="97"/> <source>Science</source> - <translation type="unfinished">Teadus</translation> + <translation>Teadus</translation> </message> <message> <location filename="../panel-plugins/appmenu/LAppMenuPlugin.cpp" line="98"/> <source>Settings</source> - <translation type="unfinished">Sätted</translation> + <translation>Sätted</translation> </message> <message> <location filename="../panel-plugins/appmenu/LAppMenuPlugin.cpp" line="99"/> <source>System</source> - <translation type="unfinished">Süsteem</translation> + <translation>Süsteem</translation> </message> <message> <location filename="../panel-plugins/appmenu/LAppMenuPlugin.cpp" line="100"/> <source>Utility</source> - <translation type="unfinished">Tööriistad</translation> + <translation>Tööriistad</translation> </message> <message> <location filename="../panel-plugins/appmenu/LAppMenuPlugin.cpp" line="101"/> <source>Wine</source> - <translation type="unfinished">Wine</translation> + <translation>Wine</translation> </message> <message> <location filename="../panel-plugins/appmenu/LAppMenuPlugin.cpp" line="102"/> <source>Unsorted</source> - <translation type="unfinished">Sortimata</translation> + <translation>Sortimata</translation> </message> <message> <location filename="../panel-plugins/appmenu/LAppMenuPlugin.cpp" line="139"/> <source>Leave</source> - <translation type="unfinished"></translation> + <translation>Lahku</translation> </message> </context> <context> @@ -679,12 +680,12 @@ <message> <location filename="../panel-plugins/clock/LClock.cpp" line="139"/> <source>Time Zone (%1)</source> - <translation type="unfinished"></translation> + <translation>Ajavöönd (%1)</translation> </message> <message> <location filename="../panel-plugins/clock/LClock.cpp" line="161"/> <source>Use System Time</source> - <translation type="unfinished"></translation> + <translation>Kasuta süsteemiaega</translation> </message> </context> <context> @@ -692,32 +693,32 @@ <message> <location filename="../desktop-plugins/LDPlugin.cpp" line="37"/> <source>Modify Item</source> - <translation type="unfinished"></translation> + <translation>Muuda</translation> </message> <message> <location filename="../desktop-plugins/LDPlugin.cpp" line="45"/> <source>Start Moving Item</source> - <translation type="unfinished"></translation> + <translation>Alusta liigutamist</translation> </message> <message> <location filename="../desktop-plugins/LDPlugin.cpp" line="46"/> <source>Start Resizing Item</source> - <translation type="unfinished"></translation> + <translation>Alusta suuruse muutmist</translation> </message> <message> <location filename="../desktop-plugins/LDPlugin.cpp" line="48"/> <source>Increase Item Sizes</source> - <translation type="unfinished"></translation> + <translation>Suurenda mõõte</translation> </message> <message> <location filename="../desktop-plugins/LDPlugin.cpp" line="49"/> <source>Decrease Item Sizes</source> - <translation type="unfinished"></translation> + <translation>Vähenda mõõte</translation> </message> <message> <location filename="../desktop-plugins/LDPlugin.cpp" line="51"/> <source>Remove Item</source> - <translation type="unfinished"></translation> + <translation>Eemalda</translation> </message> </context> <context> @@ -773,24 +774,24 @@ <message> <location filename="../LDesktop.cpp" line="255"/> <source>Desktop Actions</source> - <translation type="unfinished"></translation> + <translation>Töölauategevused</translation> </message> <message> <location filename="../LDesktop.cpp" line="257"/> <location filename="../LDesktop.cpp" line="608"/> <source>New Folder</source> - <translation type="unfinished"></translation> + <translation>Uus Kaust</translation> </message> <message> <location filename="../LDesktop.cpp" line="258"/> <location filename="../LDesktop.cpp" line="628"/> <source>New File</source> - <translation type="unfinished"></translation> + <translation>Uus Fail</translation> </message> <message> <location filename="../LDesktop.cpp" line="259"/> <source>Paste</source> - <translation type="unfinished"></translation> + <translation>Aseta</translation> </message> <message> <location filename="../LDesktop.cpp" line="291"/> @@ -810,24 +811,24 @@ <message> <location filename="../LDesktop.cpp" line="303"/> <source>Lock Session</source> - <translation type="unfinished"></translation> + <translation>Lukusta sessioon</translation> </message> <message> <location filename="../LDesktop.cpp" line="304"/> <source>Browse Files</source> - <translation type="unfinished"></translation> + <translation>Sirvi Faile</translation> </message> <message> <location filename="../LDesktop.cpp" line="338"/> <source>Leave</source> - <translation type="unfinished"></translation> + <translation>Lahku</translation> </message> <message> <location filename="../LDesktop.cpp" line="614"/> <location filename="../LDesktop.cpp" line="634"/> <location filename="../LDesktop.cpp" line="655"/> <source>Desktop</source> - <translation type="unfinished">Töölaud</translation> + <translation>Töölaud</translation> </message> </context> <context> @@ -835,7 +836,7 @@ <message> <location filename="../panel-plugins/desktopswitcher/LDesktopSwitcher.cpp" line="19"/> <source>Workspace 1</source> - <translation type="unfinished"></translation> + <translation>Tööruum 1</translation> </message> <message> <location filename="../panel-plugins/desktopswitcher/LDesktopSwitcher.cpp" line="135"/> @@ -848,8 +849,8 @@ <name>LQuickLaunchButton</name> <message> <location filename="../panel-plugins/systemstart/LStartButton.h" line="52"/> - <source>Remove from Quicklaunch</source> - <translation type="unfinished"></translation> + <source>Remove from QuickLaunch</source> + <translation>Eemalda Kiirkäivitusest</translation> </message> </context> <context> @@ -858,7 +859,7 @@ <location filename="../LSession.cpp" line="164"/> <location filename="../LSession.cpp" line="347"/> <source>Desktop</source> - <translation type="unfinished">Töölaud</translation> + <translation>Töölaud</translation> </message> </context> <context> @@ -879,7 +880,7 @@ <message> <location filename="../panel-plugins/systemdashboard/SysMenuQuick.ui" line="50"/> <source>Volume</source> - <translation type="unfinished"></translation> + <translation>Helitugevus</translation> </message> <message> <location filename="../panel-plugins/systemdashboard/SysMenuQuick.ui" line="111"/> @@ -954,17 +955,17 @@ <message> <location filename="../panel-plugins/taskmanager/LTaskButton.cpp" line="160"/> <source>Show All Windows</source> - <translation type="unfinished"></translation> + <translation>Näita kõiki aknaid</translation> </message> <message> <location filename="../panel-plugins/taskmanager/LTaskButton.cpp" line="161"/> <source>Minimize All Windows</source> - <translation type="unfinished"></translation> + <translation>Minimeeri kõik aknad</translation> </message> <message> <location filename="../panel-plugins/taskmanager/LTaskButton.cpp" line="162"/> <source>Close All Windows</source> - <translation type="unfinished"></translation> + <translation>Sulge kõik aknad</translation> </message> </context> <context> @@ -1005,7 +1006,7 @@ <message> <location filename="../desktop-plugins/systemmonitor/MonitorWidget.ui" line="85"/> <source>Disk I/O</source> - <translation type="unfinished"></translation> + <translation>Ketta I/O</translation> </message> </context> <context> @@ -1028,37 +1029,37 @@ <message> <location filename="../desktop-plugins/notepad/NotepadPlugin.cpp" line="138"/> <source>Name:</source> - <translation type="unfinished">Nimi:</translation> + <translation>Nimi:</translation> </message> <message> <location filename="../desktop-plugins/notepad/NotepadPlugin.cpp" line="140"/> <source>Invalid Note Name: Try Again</source> - <translation type="unfinished"></translation> + <translation>Vigane märkmenimi: Proovi uuesti</translation> </message> <message> <location filename="../desktop-plugins/notepad/NotepadPlugin.cpp" line="141"/> <source>Select a Note Name</source> - <translation type="unfinished"></translation> + <translation>Vali märkmenimi</translation> </message> <message> <location filename="../desktop-plugins/notepad/NotepadPlugin.cpp" line="168"/> <source>Open Text File</source> - <translation type="unfinished"></translation> + <translation>Ava tekstifail</translation> </message> <message> <location filename="../desktop-plugins/notepad/NotepadPlugin.cpp" line="169"/> <source>Create a Note</source> - <translation type="unfinished"></translation> + <translation>Loo märge</translation> </message> <message> <location filename="../desktop-plugins/notepad/NotepadPlugin.cpp" line="172"/> <source>Rename Note</source> - <translation type="unfinished"></translation> + <translation>Nimeta märge ümber</translation> </message> <message> <location filename="../desktop-plugins/notepad/NotepadPlugin.cpp" line="173"/> <source>Delete Note</source> - <translation type="unfinished"></translation> + <translation>Kustuta märge</translation> </message> </context> <context> @@ -1066,57 +1067,57 @@ <message> <location filename="../panel-plugins/audioplayer/PPlayerWidget.ui" line="14"/> <source>Form</source> - <translation type="unfinished">Vorm</translation> + <translation>Vorm</translation> </message> <message> <location filename="../panel-plugins/audioplayer/PPlayerWidget.cpp" line="69"/> <source>Clear Playlist</source> - <translation type="unfinished">Tühjenda esitusloend</translation> + <translation>Tühjenda esitusloend</translation> </message> <message> <location filename="../panel-plugins/audioplayer/PPlayerWidget.cpp" line="70"/> <source>Shuffle Playlist</source> - <translation type="unfinished">Sega loendi järjekord</translation> + <translation>Sega loendi järjekord</translation> </message> <message> <location filename="../panel-plugins/audioplayer/PPlayerWidget.cpp" line="72"/> <source>Add Files</source> - <translation type="unfinished">Lisa faile</translation> + <translation>Lisa faile</translation> </message> <message> <location filename="../panel-plugins/audioplayer/PPlayerWidget.cpp" line="73"/> <source>Add Directory</source> - <translation type="unfinished">Lisa kaust</translation> + <translation>Lisa kaust</translation> </message> <message> <location filename="../panel-plugins/audioplayer/PPlayerWidget.cpp" line="74"/> <source>Add URL</source> - <translation type="unfinished">Lisa URL</translation> + <translation>Lisa URL</translation> </message> <message> <location filename="../panel-plugins/audioplayer/PPlayerWidget.cpp" line="102"/> <source>Multimedia Files</source> - <translation type="unfinished">Multimeediafailid</translation> + <translation>Multimeediafailid</translation> </message> <message> <location filename="../panel-plugins/audioplayer/PPlayerWidget.cpp" line="103"/> <source>Select Multimedia Files</source> - <translation type="unfinished">Vali multimeediafailid</translation> + <translation>Vali multimeediafailid</translation> </message> <message> <location filename="../panel-plugins/audioplayer/PPlayerWidget.cpp" line="130"/> <source>Select Multimedia Directory</source> - <translation type="unfinished">Vali multimeedia kaust</translation> + <translation>Vali multimeedia kaust</translation> </message> <message> <location filename="../panel-plugins/audioplayer/PPlayerWidget.cpp" line="159"/> <source>Enter a valid URL for a multimedia file or stream:</source> - <translation type="unfinished">Sisesta multimeediafaili või -voo URL</translation> + <translation>Sisesta multimeediafaili või -voo URL</translation> </message> <message> <location filename="../panel-plugins/audioplayer/PPlayerWidget.cpp" line="161"/> <source>Multimedia URL</source> - <translation type="unfinished">Multimeedia URL</translation> + <translation>Multimeedia URL</translation> </message> </context> <context> @@ -1182,155 +1183,155 @@ <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="14"/> <source>Form</source> - <translation type="unfinished">Vorm</translation> + <translation>Vorm</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="62"/> <source>View Options</source> - <translation type="unfinished"></translation> + <translation>Vaata valikuid</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="89"/> <source>Open Website</source> - <translation type="unfinished"></translation> + <translation>Ava veebileht</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="92"/> <source>More</source> - <translation type="unfinished"></translation> + <translation>Rohkem</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="154"/> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="245"/> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="391"/> <source>Back to Feeds</source> - <translation type="unfinished"></translation> + <translation>Tagasi voo juurde</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="172"/> <source>Feed Information</source> - <translation type="unfinished"></translation> + <translation>Voo informatsioon</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="212"/> <source>Remove Feed</source> - <translation type="unfinished"></translation> + <translation>Eemalda voog</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="263"/> <source>New Feed Subscription</source> - <translation type="unfinished"></translation> + <translation>Uuele voole registreerumine</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="287"/> <source>RSS URL</source> - <translation type="unfinished"></translation> + <translation>RSS URL aadress</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="302"/> <source>Load a preset RSS Feed</source> - <translation type="unfinished"></translation> + <translation>Lae eelseadistatud RSS voog</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="332"/> <source>Add to Feeds</source> - <translation type="unfinished"></translation> + <translation>Lisa voogudele</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="409"/> <source>Feed Reader Settings</source> - <translation type="unfinished"></translation> + <translation>Uudisvoogude lugeja seaded</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="430"/> <source>Manual Sync Only</source> - <translation type="unfinished"></translation> + <translation>Ainult käsitsi sünkroniseerimine</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="437"/> <source>Some RSS feeds may request custom update intervals instead of using this setting</source> - <translation type="unfinished"></translation> + <translation>Mõned uudisvood võivad nõuda erinevaid uuendusintervalle, selle seade kasutamise asemel.</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="440"/> <source>Default Sync Interval</source> - <translation type="unfinished"></translation> + <translation>Vaikimisi sünkroniseerimise intervall</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="471"/> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="483"/> <source>Hour(s)</source> - <translation type="unfinished"></translation> + <translation>Tundides</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="478"/> <source>Minutes</source> - <translation type="unfinished"></translation> + <translation>Minutites</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.ui" line="522"/> <source>Save Settings</source> - <translation type="unfinished"></translation> + <translation>Salvesta seaded</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.cpp" line="70"/> <source>Add RSS Feed</source> - <translation type="unfinished"></translation> + <translation>Lisa uudisvoog</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.cpp" line="71"/> <source>View Feed Details</source> - <translation type="unfinished"></translation> + <translation>Vaata uudisvoo detaile</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.cpp" line="72"/> <source>Settings</source> - <translation type="unfinished">Sätted</translation> + <translation>Sätted</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.cpp" line="74"/> <source>Update Feeds Now</source> - <translation type="unfinished"></translation> + <translation>Uuenda uudisvooge</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.cpp" line="78"/> <source>Lumina Desktop RSS</source> - <translation type="unfinished"></translation> + <translation>Lumina Töölaua RSS</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.cpp" line="143"/> <source>Feed URL: %1</source> - <translation type="unfinished"></translation> + <translation>Uudisvoo URL: %1</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.cpp" line="144"/> <source>Title: %1</source> - <translation type="unfinished"></translation> + <translation>Pealkiri: %1</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.cpp" line="145"/> <source>Description: %1</source> - <translation type="unfinished"></translation> + <translation>Kirjeldus: %1</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.cpp" line="146"/> <source>Website: %1</source> - <translation type="unfinished"></translation> + <translation>Veebileht: %1</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.cpp" line="147"/> <source>Last Build Date: %1</source> - <translation type="unfinished"></translation> + <translation>Viimane koostamise aeg: %1</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.cpp" line="148"/> <source>Last Sync: %1</source> - <translation type="unfinished"></translation> + <translation>Viimane sünkr.: %1</translation> </message> <message> <location filename="../desktop-plugins/rssreader/RSSFeedPlugin.cpp" line="149"/> <source>Next Sync: %1</source> - <translation type="unfinished"></translation> + <translation>Järgmine sünkr.: %1</translation> </message> </context> <context> @@ -1343,22 +1344,22 @@ <message> <location filename="../SettingsMenu.cpp" line="26"/> <source>Preferences</source> - <translation type="unfinished"></translation> + <translation>Eelistus</translation> </message> <message> <location filename="../SettingsMenu.cpp" line="33"/> <source>Wallpaper</source> - <translation type="unfinished"></translation> + <translation>Taustapilt</translation> </message> <message> <location filename="../SettingsMenu.cpp" line="36"/> <source>Display</source> - <translation type="unfinished"></translation> + <translation>Ekraan</translation> </message> <message> <location filename="../SettingsMenu.cpp" line="39"/> <source>All Desktop Settings</source> - <translation type="unfinished"></translation> + <translation>Kõik ekraaniseaded</translation> </message> <message> <location filename="../SettingsMenu.cpp" line="54"/> @@ -1376,42 +1377,42 @@ <message> <location filename="../panel-plugins/systemstart/StartMenu.ui" line="14"/> <source>Form</source> - <translation type="unfinished">Vorm</translation> + <translation>Vorm</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.ui" line="38"/> <source>Type to search</source> - <translation type="unfinished"></translation> + <translation>Trüki millegi otsimiseks</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.ui" line="171"/> <source>Browse Files</source> - <translation type="unfinished"></translation> + <translation>Sirvi faile</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.ui" line="199"/> <source>Browse Applications</source> - <translation type="unfinished"></translation> + <translation>Sirvi programme</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.ui" line="234"/> <source>Control Panel</source> - <translation type="unfinished">Juhtpaneel</translation> + <translation>Juhtpaneel</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.ui" line="305"/> <source>Leave</source> - <translation type="unfinished"></translation> + <translation>Lahku</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.ui" line="379"/> <source>Manage Applications</source> - <translation type="unfinished"></translation> + <translation>Halda programme</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.ui" line="408"/> <source>Show Categories</source> - <translation type="unfinished"></translation> + <translation>Näita kategooriaid</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.ui" line="488"/> @@ -1421,32 +1422,32 @@ <message> <location filename="../panel-plugins/systemstart/StartMenu.ui" line="924"/> <source>Suspend</source> - <translation type="unfinished">Arvuti peatamine</translation> + <translation>Arvuti unerežiim</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.ui" line="989"/> <source>Restart</source> - <translation type="unfinished">Taaskäivita</translation> + <translation>Taaskäivita</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.ui" line="1017"/> <source>Power Off</source> - <translation type="unfinished"></translation> + <translation>Lülita välja</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.ui" line="1065"/> <source>Log Out</source> - <translation type="unfinished">Logi välja</translation> + <translation>Logi välja</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.ui" line="262"/> <source>Preferences</source> - <translation type="unfinished"></translation> + <translation>Eelistused</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.ui" line="1036"/> <source>(System Performing Updates)</source> - <translation type="unfinished"></translation> + <translation>(Süsteem paigaldab uuendusi)</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.ui" line="1125"/> @@ -1456,49 +1457,49 @@ <message> <location filename="../panel-plugins/systemstart/StartMenu.cpp" line="290"/> <source>Apply Updates?</source> - <translation type="unfinished"></translation> + <translation>Alusta uuenduste paigaldamist?</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.cpp" line="290"/> <source>You have system updates waiting to be applied! Do you wish to install them now?</source> - <translation type="unfinished"></translation> + <translation>Sul on ootel süsteemiuuendused. Kas soovid neid nüüd paigaldada?</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.cpp" line="291"/> <source>Yes</source> - <translation type="unfinished"></translation> + <translation>Jah</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.cpp" line="292"/> <source>No</source> - <translation type="unfinished"></translation> + <translation>Ei</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.cpp" line="293"/> <source>Cancel</source> - <translation type="unfinished">Loobu</translation> + <translation>Loobu</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.cpp" line="475"/> <source>%1% (Plugged In)</source> - <translation type="unfinished"></translation> + <translation>%1% (ühendatud)</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.cpp" line="479"/> <source>%1% (%2 Estimated)</source> - <translation type="unfinished"></translation> + <translation>%1% (%2 hinnanguliselt)</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.cpp" line="480"/> <source>%1% Remaining</source> - <translation type="unfinished"></translation> + <translation>%1% jäänud</translation> </message> <message> <location filename="../panel-plugins/systemstart/StartMenu.cpp" line="496"/> <location filename="../panel-plugins/systemstart/StartMenu.cpp" line="655"/> <location filename="../panel-plugins/systemstart/StartMenu.cpp" line="666"/> <source>Workspace %1/%2</source> - <translation type="unfinished">Tööruum %1/%2</translation> + <translation>Tööruum %1/%2</translation> </message> </context> <context> @@ -1521,7 +1522,7 @@ <message> <location filename="../SystemWindow.ui" line="87"/> <source>Power Off</source> - <translation type="unfinished"></translation> + <translation>Lülita välja</translation> </message> <message> <location filename="../SystemWindow.ui" line="127"/> @@ -1542,22 +1543,22 @@ <message> <location filename="../SystemWindow.cpp" line="57"/> <source>Apply Updates?</source> - <translation type="unfinished"></translation> + <translation>Paigalda uuendused?</translation> </message> <message> <location filename="../SystemWindow.cpp" line="57"/> <source>You have system updates waiting to be applied! Do you wish to install them now?</source> - <translation type="unfinished"></translation> + <translation>Sul on ootel süsteemiuuendused! Kas soovid neid kohe lasta paigaldada?</translation> </message> <message> <location filename="../SystemWindow.cpp" line="58"/> <source>Yes</source> - <translation type="unfinished"></translation> + <translation>Jah</translation> </message> <message> <location filename="../SystemWindow.cpp" line="59"/> <source>No</source> - <translation type="unfinished"></translation> + <translation>Ei</translation> </message> </context> <context> @@ -1588,7 +1589,7 @@ <message> <location filename="../panel-plugins/userbutton/UserWidget.ui" line="14"/> <source>UserWidget</source> - <translation>UserWidget</translation> + <translation>Kasutajavidin</translation> </message> <message> <location filename="../panel-plugins/userbutton/UserWidget.ui" line="24"/> @@ -1769,67 +1770,67 @@ <message> <location filename="../../libLumina/LuminaXDG.cpp" line="603"/> <source>Multimedia</source> - <translation type="unfinished">Multimeedia</translation> + <translation>Multimeedia</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="604"/> <source>Development</source> - <translation type="unfinished">Arendus</translation> + <translation>Arendus</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="605"/> <source>Education</source> - <translation type="unfinished">Haridus</translation> + <translation>Haridus</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="606"/> <source>Games</source> - <translation type="unfinished">Mängud</translation> + <translation>Mängud</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="607"/> <source>Graphics</source> - <translation type="unfinished">Graafika</translation> + <translation>Graafika</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="608"/> <source>Network</source> - <translation type="unfinished">Võrk</translation> + <translation>Võrk</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="609"/> <source>Office</source> - <translation type="unfinished">Kontor</translation> + <translation>Kontor</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="610"/> <source>Science</source> - <translation type="unfinished">Teadus</translation> + <translation>Teadus</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="611"/> <source>Settings</source> - <translation type="unfinished">Sätted</translation> + <translation>Sätted</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="612"/> <source>System</source> - <translation type="unfinished">Süsteem</translation> + <translation>Süsteem</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="613"/> <source>Utility</source> - <translation type="unfinished">Tööriistad</translation> + <translation>Tööriistad</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="614"/> <source>Wine</source> - <translation type="unfinished">Wine</translation> + <translation>Wine</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="615"/> <source>Unsorted</source> - <translation type="unfinished">Sortimata</translation> + <translation>Sortimata</translation> </message> </context> </TS> diff --git a/src-qt5/core/lumina-desktop/lumina-desktop.pro b/src-qt5/core/lumina-desktop/lumina-desktop.pro index d4e57c5c..2c944a11 100644 --- a/src-qt5/core/lumina-desktop/lumina-desktop.pro +++ b/src-qt5/core/lumina-desktop/lumina-desktop.pro @@ -77,17 +77,6 @@ fluxconf.files = fluxboxconf/fluxbox-init-rc \ fluxboxconf/fluxbox-keys fluxconf.path = $${L_SHAREDIR}/lumina-desktop/ -wallpapers.files = wallpapers/Lumina_Wispy_gold.jpg \ - wallpapers/Lumina_Wispy_green.jpg \ - wallpapers/Lumina_Wispy_purple.jpg \ - wallpapers/Lumina_Wispy_red.jpg \ - wallpapers/Lumina_Wispy_blue-grey.jpg \ - wallpapers/Lumina_Wispy_blue-grey-zoom.jpg \ - wallpapers/Lumina_Wispy_grey-blue.jpg \ - wallpapers/Lumina_Wispy_grey-blue-zoom.jpg -wallpapers.path = $${L_SHAREDIR}/wallpapers/Lumina-DE - - defaults.files = defaults/luminaDesktop.conf \ defaults/compton.conf \ audiofiles/Logout.ogg \ diff --git a/src-qt5/core/lumina-desktop/main.cpp b/src-qt5/core/lumina-desktop/main.cpp index b2bfa9be..826d697c 100644 --- a/src-qt5/core/lumina-desktop/main.cpp +++ b/src-qt5/core/lumina-desktop/main.cpp @@ -78,33 +78,19 @@ int main(int argc, char ** argv) //Startup the session LSession a(argc, argv); if(!a.isPrimaryProcess()){ return 0; } + //Ensure that the user's config files exist + /*if( LSession::checkUserFiles() ){ //make sure to create any config files before creating the QApplication + qDebug() << "User files changed - restarting the desktop session"; + return 787; //return special restart code + }*/ //Setup the log file - /* logfile.setFileName( QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/logs/runtime.log" ); - qDebug() << "Lumina Log File:" << logfile.fileName(); - if(QFile::exists(logfile.fileName()+".old")){ QFile::remove(logfile.fileName()+".old"); } - if(logfile.exists()){ QFile::rename(logfile.fileName(), logfile.fileName()+".old"); } - //Make sure the parent directory exists - if(!QFile::exists(QDir::homePath()+"/.lumina/logs")){ - QDir dir; - dir.mkpath(QDir::homePath()+"/.lumina/logs"); - } - logfile.open(QIODevice::WriteOnly | QIODevice::Append);*/ QTime *timer=0; if(DEBUG){ timer = new QTime(); timer->start(); } - //Setup Log File - //qInstallMessageHandler(MessageOutput); - //if(DEBUG){ qDebug() << "Theme Init:" << timer->elapsed(); } - //LuminaThemeEngine theme(&a); - //QObject::connect(&theme, SIGNAL(updateIcons()), &a, SLOT(reloadIconTheme()) ); - //if(DEBUG){ qDebug() << "Load Locale:" << timer->elapsed(); } - //LUtils::LoadTranslation(&a, "lumina-desktop"); if(DEBUG){ qDebug() << "Session Setup:" << timer->elapsed(); } a.setupSession(); - //theme.refresh(); if(DEBUG){ qDebug() << "Exec Time:" << timer->elapsed(); delete timer;} int retCode = a.exec(); //qDebug() << "Stopping the window manager"; qDebug() << "Finished Closing Down Lumina"; - //logfile.close(); return retCode; } diff --git a/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp b/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp index cae73d13..7a6b0e7c 100644 --- a/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp +++ b/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.cpp @@ -20,6 +20,7 @@ LBattery::LBattery(QWidget *parent, QString id, bool horizontal) : LPPlugin(pare connect(timer,SIGNAL(timeout()), this, SLOT(updateBattery()) ); timer->start(); QTimer::singleShot(0,this,SLOT(OrientationChange()) ); //update the sizing/icon + sessionsettings = new QSettings("lumina-desktop", "sessionsettings"); } LBattery::~LBattery(){ @@ -78,7 +79,8 @@ void LBattery::updateBattery(bool force){ } if(icon<iconOld && icon==0){ //Play some audio warning chime when - QString sfile = LSession::handle()->sessionSettings()->value("audiofiles/batterylow", LOS::LuminaShare()+"low-battery.ogg").toString(); + bool playaudio = sessionsettings->value("PlayBatteryLowAudio",true).toBool(); + if( playaudio ){ QString sfile = LSession::handle()->sessionSettings()->value("audiofiles/batterylow", LOS::LuminaShare()+"low-battery.ogg").toString(); LSession::handle()->playAudioFile(sfile); } @@ -95,6 +97,7 @@ void LBattery::updateBattery(bool force){ else{ tt = QString( tr("%1 % (%2 Remaining)") ).arg(QString::number(charge), getRemainingTime() ); } label->setToolTip(tt); } +} QString LBattery::getRemainingTime(){ int secs = LOS::batterySecondsLeft(); diff --git a/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.h b/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.h index d14cfc53..3c23be1c 100644 --- a/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.h +++ b/src-qt5/core/lumina-desktop/panel-plugins/battery/LBattery.h @@ -30,6 +30,7 @@ private: QTimer *timer; QLabel *label; int iconOld; + QSettings *sessionsettings; private slots: void updateBattery(bool force = false); diff --git a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp index f44add77..30e82c47 100644 --- a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp +++ b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/LStartButton.cpp @@ -26,9 +26,10 @@ LStartButtonPlugin::LStartButtonPlugin(QWidget *parent, QString id, bool horizon connect(startmenu, SIGNAL(CloseMenu()), this, SLOT(closeMenu()) ); connect(startmenu, SIGNAL(UpdateQuickLaunch(QStringList)), this, SLOT(updateQuickLaunch(QStringList))); menu->setContents(startmenu); - QSize saved = LSession::handle()->DesktopPluginSettings()->value("panelPlugs/"+this->type()+"/MenuSize", QSize(0,0)).toSize(); + QRect screenSize = QApplication::desktop()->availableGeometry(this); + QSize saved = LSession::handle()->DesktopPluginSettings()->value("panelPlugs/"+this->type()+"/MenuSize", QSize(screenSize.width() * 0.2, screenSize.height())).toSize(); if(!saved.isNull()){ startmenu->setFixedSize(saved); } //re-load the previously saved value - + button->setMenu(menu); connect(menu, SIGNAL(aboutToHide()), this, SLOT(updateButtonVisuals()) ); QTimer::singleShot(0,this, SLOT(OrientationChange())); //Update icons/sizes diff --git a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp index e8df8390..c99e2b4b 100644 --- a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp +++ b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.cpp @@ -138,7 +138,7 @@ void StartMenu::UpdateMenu(bool forceall){ } void StartMenu::ReLoadQuickLaunch(){ - emit UpdateQuickLaunch( LSession::handle()->sessionSettings()->value("QuicklaunchApps",QStringList()).toStringList() ); + emit UpdateQuickLaunch( LSession::handle()->sessionSettings()->value("QuicklaunchApps",QStringList()).toStringList() ); } void StartMenu::UpdateQuickLaunch(QString path, bool keep){ @@ -431,7 +431,9 @@ void StartMenu::UpdateFavs(){ tmp.sort(); //Sort alphabetically by name (dirs/files) for(int i=0; i<tmp.length(); i++){ if(type<2){ rest.removeAll(tmp[i]); } - if( !QFile::exists(tmp[i].section("::::",2,-1)) ){ continue; } //invalid favorite - skip it + if( !tmp[i].section("::::",2,-1).startsWith("/net/") ){ + if( !QFile::exists(tmp[i].section("::::",2,-1)) ){ continue; } //invalid favorite - skip it + } ItemWidget *it = 0; if( tmp[i].section("::::",2,-1).endsWith(".desktop")){ XDGDesktop item(tmp[i].section("::::",2,-1)); @@ -493,7 +495,7 @@ void StartMenu::on_stackedWidget_currentChanged(int val){ if(tot>1){ ui->frame_wkspace->setVisible(true); int cur = LSession::handle()->XCB->CurrentWorkspace(); - ui->label_wkspace->setText( QString(tr("Workspace %1/%2")).arg(QString::number(cur+1), QString::number(tot)) ); + ui->label_wkspace->setText( QString(tr("Workspace %1/%2")).arg(QString::number(cur+1), QString::number(tot)) ); }else{ ui->frame_wkspace->setVisible(false); } @@ -635,14 +637,14 @@ void StartMenu::on_tool_mute_audio_clicked(){ ui->slider_volume->setValue(0); } } - + //Screen Brightness void StartMenu::on_slider_bright_valueChanged(int val){ ui->label_bright->setText(QString::number(val)+"%"); LOS::setScreenBrightness(val); } - + //Workspace void StartMenu::on_tool_set_nextwkspace_clicked(){ int cur = LSession::handle()->XCB->CurrentWorkspace(); @@ -663,10 +665,10 @@ void StartMenu::on_tool_set_prevwkspace_clicked(){ if(cur<0){ cur = tot-1; } //back to end //qDebug() << " - New Current:" << cur; LSession::handle()->XCB->SetCurrentWorkspace(cur); - ui->label_wkspace->setText( QString(tr("Workspace %1/%2")).arg(QString::number(cur+1), QString::number(tot)) ); + ui->label_wkspace->setText( QString(tr("Workspace %1/%2")).arg(QString::number(cur+1), QString::number(tot)) ); } - + //Locale void StartMenu::on_combo_locale_currentIndexChanged(int){ //Get the currently selected Locale @@ -677,7 +679,7 @@ void StartMenu::on_combo_locale_currentIndexChanged(int){ LSession::handle()->switchLocale(locale); } - + //Search void StartMenu::on_line_search_textEdited(QString){ if(searchTimer->isActive()){ searchTimer->stop(); } diff --git a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h index 8ab04d94..e2dbb273 100644 --- a/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h +++ b/src-qt5/core/lumina-desktop/panel-plugins/systemstart/StartMenu.h @@ -34,13 +34,13 @@ private: Ui::StartMenu *ui; QStringList favs; QString CCat, CSearch, topsearch; //current category/search - QTimer *searchTimer; + QTimer *searchTimer; //Simple utility functions //void deleteChildren(QWidget *obj); //recursive function void ClearScrollArea(QScrollArea *area); void SortScrollArea(QScrollArea *area); - void do_search(QString search, bool force); + void do_search(QString search, bool force); bool promptAboutUpdates(bool &skip); diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey-zoom.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey-zoom.jpg Binary files differdeleted file mode 100644 index 481ca438..00000000 --- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey-zoom.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey.jpg Binary files differdeleted file mode 100644 index 9da67596..00000000 --- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_blue-grey.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_gold.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_gold.jpg Binary files differdeleted file mode 100644 index cba03cee..00000000 --- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_gold.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_green.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_green.jpg Binary files differdeleted file mode 100644 index 80b0d3e3..00000000 --- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_green.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue-zoom.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue-zoom.jpg Binary files differdeleted file mode 100644 index 4f753ed5..00000000 --- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue-zoom.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue.jpg Binary files differdeleted file mode 100644 index c214cd78..00000000 --- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_grey-blue.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_purple.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_purple.jpg Binary files differdeleted file mode 100644 index e4c3d7a8..00000000 --- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_purple.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_red.jpg b/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_red.jpg Binary files differdeleted file mode 100644 index a092f636..00000000 --- a/src-qt5/core/lumina-desktop/wallpapers/Lumina_Wispy_red.jpg +++ /dev/null diff --git a/src-qt5/core/lumina-info/i18n/lumina-info_et.ts b/src-qt5/core/lumina-info/i18n/lumina-info_et.ts index 90c031e5..09142c95 100644 --- a/src-qt5/core/lumina-info/i18n/lumina-info_et.ts +++ b/src-qt5/core/lumina-info/i18n/lumina-info_et.ts @@ -16,17 +16,17 @@ <message> <location filename="../MainUI.ui" line="89"/> <source>Source Repository</source> - <translation type="unfinished"></translation> + <translation>Lähtekoodi repositoorium</translation> </message> <message> <location filename="../MainUI.ui" line="124"/> <source>Lumina Website</source> - <translation type="unfinished"></translation> + <translation>Lumina veebileht</translation> </message> <message> <location filename="../MainUI.ui" line="152"/> <source>Bug Reports</source> - <translation type="unfinished"></translation> + <translation>Puukide raporteerimine</translation> </message> <message> <location filename="../MainUI.ui" line="179"/> @@ -46,7 +46,7 @@ <message> <location filename="../MainUI.ui" line="276"/> <source>Ask the Community</source> - <translation type="unfinished"></translation> + <translation>Küsi kommuunilt</translation> </message> <message> <location filename="../MainUI.ui" line="233"/> @@ -99,67 +99,67 @@ <message> <location filename="../../libLumina/LuminaXDG.cpp" line="603"/> <source>Multimedia</source> - <translation type="unfinished"></translation> + <translation>Multimeedia</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="604"/> <source>Development</source> - <translation type="unfinished"></translation> + <translation>Arendustegevus</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="605"/> <source>Education</source> - <translation type="unfinished"></translation> + <translation>Haridus</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="606"/> <source>Games</source> - <translation type="unfinished"></translation> + <translation>Mängud</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="607"/> <source>Graphics</source> - <translation type="unfinished"></translation> + <translation>Graafika</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="608"/> <source>Network</source> - <translation type="unfinished"></translation> + <translation>Võrk</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="609"/> <source>Office</source> - <translation type="unfinished"></translation> + <translation>Kontor</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="610"/> <source>Science</source> - <translation type="unfinished"></translation> + <translation>Teadus</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="611"/> <source>Settings</source> - <translation type="unfinished"></translation> + <translation>Sätted</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="612"/> <source>System</source> - <translation type="unfinished"></translation> + <translation>Süsteem</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="613"/> <source>Utility</source> - <translation type="unfinished"></translation> + <translation>Tööriistad</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="614"/> <source>Wine</source> - <translation type="unfinished"></translation> + <translation>Wine</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="615"/> <source>Unsorted</source> - <translation type="unfinished"></translation> + <translation>Sorteerimata</translation> </message> </context> </TS> diff --git a/src-qt5/core/lumina-open/LFileDialog.cpp b/src-qt5/core/lumina-open/LFileDialog.cpp index ce7c6a6f..dbdb6362 100644 --- a/src-qt5/core/lumina-open/LFileDialog.cpp +++ b/src-qt5/core/lumina-open/LFileDialog.cpp @@ -54,9 +54,9 @@ QString LFileDialog::getDefaultApp(QString extension){ void LFileDialog::setDefaultApp(QString extension, QString appFile){ if(!extension.contains("/")){ extension = LXDG::findAppMimeForFile(appFile); } - //mime type default: set on the system itself - if(appFile.endsWith(".desktop")){ appFile = appFile.section("/",-1); } //only need the relative path - LXDG::setDefaultAppForMime(extension, appFile); + //mime type default: set on the system itself + //if(appFile.endsWith(".desktop")){ appFile = appFile.section("/",-1); } //only need the relative path + LXDG::setDefaultAppForMime(extension, appFile); } // ----------- diff --git a/src-qt5/core/lumina-open/i18n/lumina-open_et.ts b/src-qt5/core/lumina-open/i18n/lumina-open_et.ts index df9c029b..ee6afe8b 100644 --- a/src-qt5/core/lumina-open/i18n/lumina-open_et.ts +++ b/src-qt5/core/lumina-open/i18n/lumina-open_et.ts @@ -166,7 +166,7 @@ <message> <location filename="../main.cpp" line="267"/> <source>Application entry is invalid: %1</source> - <translation type="unfinished"></translation> + <translation>Rakenduse %1 kirje on vigane.</translation> </message> <message> <location filename="../main.cpp" line="278"/> @@ -191,12 +191,12 @@ <message> <location filename="../main.cpp" line="370"/> <source>Binary Missing</source> - <translation type="unfinished"></translation> + <translation>Binaarfail puudub</translation> </message> <message> <location filename="../main.cpp" line="370"/> <source>Could not find "%1". Please ensure it is installed first.</source> - <translation type="unfinished"></translation> + <translation>Ei leidnud "%1" . Palun veendu et see on paigaldatud.</translation> </message> <message> <location filename="../main.cpp" line="421"/> @@ -214,67 +214,67 @@ <message> <location filename="../../libLumina/LuminaXDG.cpp" line="603"/> <source>Multimedia</source> - <translation type="unfinished">Multimeedia</translation> + <translation>Multimeedia</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="604"/> <source>Development</source> - <translation type="unfinished">Arendus</translation> + <translation>Arendus</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="605"/> <source>Education</source> - <translation type="unfinished">Haridus</translation> + <translation>Haridus</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="606"/> <source>Games</source> - <translation type="unfinished"></translation> + <translation>Mängud</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="607"/> <source>Graphics</source> - <translation type="unfinished">Graafika</translation> + <translation>Graafika</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="608"/> <source>Network</source> - <translation type="unfinished">Võrk</translation> + <translation>Võrk</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="609"/> <source>Office</source> - <translation type="unfinished">Kontor</translation> + <translation>Kontor</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="610"/> <source>Science</source> - <translation type="unfinished">Teadus</translation> + <translation>Teadus</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="611"/> <source>Settings</source> - <translation type="unfinished">Sätted</translation> + <translation>Sätted</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="612"/> <source>System</source> - <translation type="unfinished">Süsteem</translation> + <translation>Süsteem</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="613"/> <source>Utility</source> - <translation type="unfinished"></translation> + <translation>Tööriistad</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="614"/> <source>Wine</source> - <translation type="unfinished"></translation> + <translation>Wine</translation> </message> <message> <location filename="../../libLumina/LuminaXDG.cpp" line="615"/> <source>Unsorted</source> - <translation type="unfinished"></translation> + <translation>Sorteerimata</translation> </message> </context> </TS> diff --git a/src-qt5/core/lumina-open/lumina-open.1 b/src-qt5/core/lumina-open/lumina-open.1 index e8c555ee..cb671da3 100644 --- a/src-qt5/core/lumina-open/lumina-open.1 +++ b/src-qt5/core/lumina-open/lumina-open.1 @@ -19,7 +19,7 @@ .Sh DESCRIPTION Given a file with an absolute pathway or URL, the .Nm -utility finds the appropriate application which which to open the +utility finds the appropriate application with which to open the file. If the file is a *.desktop application shortcut, .Nm starts the application automatically. Using the appropriate flags diff --git a/src-qt5/core/lumina-open/main.cpp b/src-qt5/core/lumina-open/main.cpp index 72d09f42..2b9e9184 100644 --- a/src-qt5/core/lumina-open/main.cpp +++ b/src-qt5/core/lumina-open/main.cpp @@ -29,6 +29,8 @@ #include <LuminaOS.h> #include <LuminaThemes.h> +#define DEBUG 0 + void printUsageInfo(){ qDebug() << "lumina-open: Application launcher for the Lumina Desktop Environment"; qDebug() << "Description: Given a file (with absolute path) or URL, this utility will try to find the appropriate application with which to open the file. If the file is a *.desktop application shortcut, it will just start the application appropriately. It can also perform a few specific system operations if given special flags."; @@ -48,7 +50,6 @@ void ShowErrorDialog(int argc, char **argv, QString message){ //Setup the application QApplication App(argc, argv); App.setAttribute(Qt::AA_UseHighDpiPixmaps); - LuminaThemeEngine theme(&App); LUtils::LoadTranslation(&App,"lumina-open"); QMessageBox dlg(QMessageBox::Critical, QObject::tr("File Error"), message ); dlg.exec(); @@ -68,7 +69,7 @@ void showOSD(int argc, char **argv, QString message){ splash.setAlignment(Qt::AlignCenter); - qDebug() << "Display OSD"; + if(DEBUG) qDebug() << "Display OSD"; splash.setText(message); //Make sure it is centered on the current screen QPoint center = App.desktop()->screenGeometry(QCursor::pos()).center(); @@ -89,7 +90,7 @@ void LaunchAutoStart(){ if(cmd.contains("%")){cmd = cmd.remove("%U").remove("%u").remove("%F").remove("%f").remove("%i").remove("%c").remove("%k").simplified(); } //Now run the command if(!cmd.isEmpty()){ - qDebug() << " - Auto-Starting File:" << xdgapps[i]->filePath; + if(DEBUG) qDebug() << " - Auto-Starting File:" << xdgapps[i]->filePath; QProcess::startDetached(cmd); } } @@ -98,130 +99,129 @@ void LaunchAutoStart(){ } QString cmdFromUser(int argc, char **argv, QString inFile, QString extension, QString& path, bool showDLG=false){ - //First check to see if there is a default for this extension - QString defApp; - if(extension=="mimetype"){ + //First check to see if there is a default for this extension + QString defApp; + if(extension=="mimetype"){ //qDebug() << "inFile:" << inFile; QStringList matches = LXDG::findAppMimeForFile(inFile, true).split("::::"); //allow multiple matches - qDebug() << "Mimetype Matches:" << matches; + if(DEBUG) qDebug() << "Mimetype Matches:" << matches; for(int i=0; i<matches.length(); i++){ defApp = LXDG::findDefaultAppForMime(matches[i]); - //qDebug() << "MimeType:" << matches[i] << defApp; + //qDebug() << "MimeType:" << matches[i] << defApp; if(!defApp.isEmpty()){ extension = matches[i]; break; } else if(i+1==matches.length()){ extension = matches[0]; } } - }else{ defApp = LFileDialog::getDefaultApp(extension); } - qDebug() << "Mimetype:" << extension << "defApp:" << defApp; - if( !defApp.isEmpty() && !showDLG ){ - if(defApp.endsWith(".desktop")){ - XDGDesktop DF(defApp); - if(DF.isValid()){ - QString exec = DF.getDesktopExec(); - if(!exec.isEmpty()){ - qDebug() << "[lumina-open] Using default application:" << DF.name << "File:" << inFile; - if(!DF.path.isEmpty()){ path = DF.path; } - return exec; - } + }else{ defApp = LFileDialog::getDefaultApp(extension); } + if(DEBUG) qDebug() << "Mimetype:" << extension << "defApp:" << defApp; + if( !defApp.isEmpty() && !showDLG ){ + if(defApp.endsWith(".desktop")){ + XDGDesktop DF(defApp); + if(DF.isValid()){ + QString exec = DF.getDesktopExec(); + if(!exec.isEmpty()){ + if(DEBUG) qDebug() << "[lumina-open] Using default application:" << DF.name << "File:" << inFile; + if(!DF.path.isEmpty()){ path = DF.path; } + return exec; } - }else{ - //Only binary given - if(LUtils::isValidBinary(defApp)){ - qDebug() << "[lumina-open] Using default application:" << defApp << "File:" << inFile; - return defApp; //just use the binary - } } - //invalid default - reset it and continue on - LFileDialog::setDefaultApp(extension, ""); - } - //Final catch: directory given - no valid default found - use lumina-fm - if(extension=="inode/directory" && !showDLG){ return "lumina-fm"; } - //No default set -- Start up the application selection dialog - LTHEME::LoadCustomEnvSettings(); - QApplication App(argc, argv); - App.setAttribute(Qt::AA_UseHighDpiPixmaps); - LuminaThemeEngine theme(&App); - LUtils::LoadTranslation(&App,"lumina-open"); - - LFileDialog w; - if(extension=="email" || extension.startsWith("x-scheme-handler/")){ - //URL - w.setFileInfo(inFile, extension, false); }else{ - //File - if(inFile.endsWith("/")){ inFile.chop(1); } - w.setFileInfo(inFile.section("/",-1), extension, true); + //Only binary given + if(LUtils::isValidBinary(defApp)){ + if(DEBUG) qDebug() << "[lumina-open] Using default application:" << defApp << "File:" << inFile; + return defApp; //just use the binary } + } + //invalid default - reset it and continue on + LFileDialog::setDefaultApp(extension, ""); + } + //Final catch: directory given - no valid default found - use lumina-fm + if(extension=="inode/directory" && !showDLG){ return "lumina-fm"; } + //No default set -- Start up the application selection dialog + LTHEME::LoadCustomEnvSettings(); + QApplication App(argc, argv); + App.setAttribute(Qt::AA_UseHighDpiPixmaps); + LUtils::LoadTranslation(&App,"lumina-open"); - w.show(); - App.exec(); - if(!w.appSelected){ return ""; } - //Return the run path if appropriate - if(!w.appPath.isEmpty()){ path = w.appPath; } - //Just do the default application registration here for now - // might move it to the runtime phase later after seeing that the app has successfully started - if(w.setDefault){ - if(!w.appFile.isEmpty()){ LFileDialog::setDefaultApp(extension, w.appFile); } - else{ LFileDialog::setDefaultApp(extension, w.appExec); } - } - //Now return the resulting application command - return w.appExec; + LFileDialog w; + if(extension=="email" || extension.startsWith("x-scheme-handler/")){ + //URL + w.setFileInfo(inFile, extension, false); + }else{ + //File + if(inFile.endsWith("/")){ inFile.chop(1); } + w.setFileInfo(inFile.section("/",-1), extension, true); + } + + w.show(); + App.exec(); + if(!w.appSelected){ return ""; } + //Return the run path if appropriate + if(!w.appPath.isEmpty()){ path = w.appPath; } + //Just do the default application registration here for now + // might move it to the runtime phase later after seeing that the app has successfully started + if(w.setDefault){ + if(!w.appFile.isEmpty()){ LFileDialog::setDefaultApp(extension, w.appFile); } + else{ LFileDialog::setDefaultApp(extension, w.appExec); } + } + //Now return the resulting application command + return w.appExec; } void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& path, bool& watch){ - //Get the input file - //Make sure to load the proper system encoding first - LUtils::LoadTranslation(0,""); //bypass application modification - QString inFile, ActionID; - bool showDLG = false; //flag to bypass any default application setting - if(argc > 1){ - for(int i=1; i<argc; i++){ - if(QString(argv[i]).simplified() == "-select"){ - showDLG = true; - }else if(QString(argv[i]).simplified() == "-testcrash"){ - //Test the crash handler - binary = "internalcrashtest"; watch=true; - return; - }else if(QString(argv[i]).simplified() == "-autostart-apps"){ - LaunchAutoStart(); - return; - }else if(QString(argv[i]).simplified() == "-volumeup"){ - int vol = LOS::audioVolume()+5; //increase 5% - if(vol>100){ vol=100; } - LOS::setAudioVolume(vol); - showOSD(argc,argv, QString(QObject::tr("Audio Volume %1%")).arg(QString::number(vol)) ); - return; - }else if(QString(argv[i]).simplified() == "-volumedown"){ - int vol = LOS::audioVolume()-5; //decrease 5% - if(vol<0){ vol=0; } - LOS::setAudioVolume(vol); - showOSD(argc,argv, QString(QObject::tr("Audio Volume %1%")).arg(QString::number(vol)) ); - return; - }else if(QString(argv[i]).simplified() == "-brightnessup"){ - int bright = LOS::ScreenBrightness(); - if(bright > 0){ //brightness control available - bright = bright+5; //increase 5% - if(bright>100){ bright = 100; } - LOS::setScreenBrightness(bright); - showOSD(argc,argv, QString(QObject::tr("Screen Brightness %1%")).arg(QString::number(bright)) ); - } - return; - }else if(QString(argv[i]).simplified() == "-brightnessdown"){ - int bright = LOS::ScreenBrightness(); - if(bright > 0){ //brightness control available - bright = bright-5; //decrease 5% - if(bright<0){ bright = 0; } - LOS::setScreenBrightness(bright); - showOSD(argc,argv, QString(QObject::tr("Screen Brightness %1%")).arg(QString::number(bright)) ); - } - return; - }else if( (QString(argv[i]).simplified() =="-action") && (argc>(i+1)) ){ - ActionID = QString(argv[i+1]); - i++; //skip the next input - }else if(QString(argv[i]).simplified()=="-terminal"){ - inFile = LXDG::findDefaultAppForMime("application/terminal"); - break; - }else{ - inFile = QString::fromLocal8Bit(argv[i]); +//Get the input file + //Make sure to load the proper system encoding first + LUtils::LoadTranslation(0,""); //bypass application modification +QString inFile, ActionID; +bool showDLG = false; //flag to bypass any default application setting +if(argc > 1){ + for(int i=1; i<argc; i++){ + if(QString(argv[i]).simplified() == "-select"){ + showDLG = true; + }else if(QString(argv[i]).simplified() == "-testcrash"){ +//Test the crash handler +binary = "internalcrashtest"; watch=true; +return; + }else if(QString(argv[i]).simplified() == "-autostart-apps"){ +LaunchAutoStart(); +return; + }else if(QString(argv[i]).simplified() == "-volumeup"){ +int vol = LOS::audioVolume()+5; //increase 5% +if(vol>100){ vol=100; } +LOS::setAudioVolume(vol); +showOSD(argc,argv, QString(QObject::tr("Audio Volume %1%")).arg(QString::number(vol)) ); +return; + }else if(QString(argv[i]).simplified() == "-volumedown"){ +int vol = LOS::audioVolume()-5; //decrease 5% +if(vol<0){ vol=0; } +LOS::setAudioVolume(vol); +showOSD(argc,argv, QString(QObject::tr("Audio Volume %1%")).arg(QString::number(vol)) ); +return; + }else if(QString(argv[i]).simplified() == "-brightnessup"){ +int bright = LOS::ScreenBrightness(); +if(bright > 0){ //brightness control available + bright = bright+5; //increase 5% + if(bright>100){ bright = 100; } + LOS::setScreenBrightness(bright); + showOSD(argc,argv, QString(QObject::tr("Screen Brightness %1%")).arg(QString::number(bright)) ); +} +return; + }else if(QString(argv[i]).simplified() == "-brightnessdown"){ +int bright = LOS::ScreenBrightness(); +if(bright > 0){ //brightness control available + bright = bright-5; //decrease 5% + if(bright<0){ bright = 0; } + LOS::setScreenBrightness(bright); + showOSD(argc,argv, QString(QObject::tr("Screen Brightness %1%")).arg(QString::number(bright)) ); +} +return; + }else if( (QString(argv[i]).simplified() =="-action") && (argc>(i+1)) ){ + ActionID = QString(argv[i+1]); +i++; //skip the next input + }else if(QString(argv[i]).simplified()=="-terminal"){ + inFile = LXDG::findDefaultAppForMime("application/terminal"); + break; + }else{ + inFile = QString::fromLocal8Bit(argv[i]); break; } } @@ -268,14 +268,14 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat } switch(DF.type){ case XDGDesktop::APP: - qDebug() << "Found .desktop application:" << ActionID; + if(DEBUG) qDebug() << "Found .desktop application:" << ActionID; if(!DF.exec.isEmpty()){ cmd = DF.getDesktopExec(ActionID); - qDebug() << "Got command:" << cmd; + if(DEBUG) qDebug() << "Got command:" << cmd; if(!DF.path.isEmpty()){ path = DF.path; } - watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/"); + watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/"); }else{ - ShowErrorDialog( argc, argv, QString(QObject::tr("Application shortcut is missing the launching information (malformed shortcut): %1")).arg(inFile) ); + ShowErrorDialog( argc, argv, QString(QObject::tr("Application shortcut is missing the launching information (malformed shortcut): %1")).arg(inFile) ); } break; case XDGDesktop::LINK: @@ -284,11 +284,11 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat inFile = DF.url; cmd.clear(); extension = inFile.section(":",0,0); - if(extension=="file"){ extension = "http"; } //local file URL - Make sure we use the default browser for a LINK type + if(extension=="file"){ extension = "http"; } //local file URL - Make sure we use the default browser for a LINK type extension.prepend("x-scheme-handler/"); - watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/"); + watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/"); }else{ - ShowErrorDialog( argc, argv, QString(QObject::tr("URL shortcut is missing the URL: %1")).arg(inFile) ); + ShowErrorDialog( argc, argv, QString(QObject::tr("URL shortcut is missing the URL: %1")).arg(inFile) ); } break; case XDGDesktop::DIR: @@ -297,14 +297,14 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat inFile = DF.path; cmd.clear(); extension = "inode/directory"; - watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/"); + watch = DF.startupNotify || !DF.filePath.contains("/xdg/autostart/"); }else{ - ShowErrorDialog( argc, argv, QString(QObject::tr("Directory shortcut is missing the path to the directory: %1")).arg(inFile) ); + ShowErrorDialog( argc, argv, QString(QObject::tr("Directory shortcut is missing the path to the directory: %1")).arg(inFile) ); } break; default: - qDebug() << DF.type << DF.name << DF.icon << DF.exec; - ShowErrorDialog( argc, argv, QString(QObject::tr("Unknown type of shortcut : %1")).arg(inFile) ); + if(DEBUG) qDebug() << DF.type << DF.name << DF.icon << DF.exec; + ShowErrorDialog( argc, argv, QString(QObject::tr("Unknown type of shortcut : %1")).arg(inFile) ); } } if(cmd.isEmpty()){ @@ -344,7 +344,7 @@ void getCMD(int argc, char ** argv, QString& binary, QString& args, QString& pat cmd.append(" \""+inFile+"\""); } } - qDebug() << "Found Command:" << cmd << "Extension:" << extension; + if(DEBUG) qDebug() << "Found Command:" << cmd << "Extension:" << extension; //Clean up any leftover "Exec" field codes (should have already been replaced earlier) if(cmd.contains("%")){cmd = cmd.remove("%U").remove("%u").remove("%F").remove("%f").remove("%i").remove("%c").remove("%k").simplified(); } binary = cmd; //pass this string to the calling function @@ -367,10 +367,10 @@ int main(int argc, char **argv){ QString bin = cmd.section(" ",0,0); if( !LUtils::isValidBinary(bin) ){ //invalid binary for some reason - open a dialog to warn the user instead - QMessageBox::warning(0, QObject::tr("Binary Missing"), QString(QObject::tr("Could not find \"%1\". Please ensure it is installed first.")).arg(bin)+"\n\n"+cmd); + ShowErrorDialog(argc,argv, QString(QObject::tr("Could not find \"%1\". Please ensure it is installed first.")).arg(bin)+"\n\n"+cmd); return 1; } - qDebug() << "[lumina-open] Running Cmd:" << cmd; + if(DEBUG) qDebug() << "[lumina-open] Running Cmd:" << cmd; int retcode = 0; //Provide an override file for never watching running processes. if(watch){ watch = !QFile::exists( QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/nowatch" ); } @@ -391,12 +391,12 @@ int main(int argc, char **argv){ }else{ QProcess *p = new QProcess(); p->setProcessEnvironment(QProcessEnvironment::systemEnvironment()); - if(!path.isEmpty() && QFile::exists(path)){ + if(!path.isEmpty() && QFile::exists(path)){ //qDebug() << " - Setting working path:" << path; - p->setWorkingDirectory(path); + p->setWorkingDirectory(path); } p->start(cmd); - + //Now check up on it once every minute until it is finished while(!p->waitForFinished(60000)){ //qDebug() << "[lumina-open] process check:" << p->state(); @@ -410,19 +410,17 @@ int main(int argc, char **argv){ //qDebug() << "[lumina-open] Finished Cmd:" << cmd << retcode << p->exitStatus(); if( QFile::exists("/tmp/.luminastopping") ){ watch = false; } //closing down session - ignore "crashes" (app could have been killed during cleanup) if( (retcode < 0) && watch){ //-1 is used internally for crashed processes - most apps return >=0 - qDebug() << "[lumina-open] Application Error:" << retcode; - //Setup the application - QApplication App(argc, argv); - App.setAttribute(Qt::AA_UseHighDpiPixmaps); - LuminaThemeEngine theme(&App); - LUtils::LoadTranslation(&App,"lumina-open"); + //Setup the application + QApplication App(argc, argv); + App.setAttribute(Qt::AA_UseHighDpiPixmaps); + LUtils::LoadTranslation(&App,"lumina-open"); //App.setApplicationName("LuminaOpen"); - QMessageBox dlg(QMessageBox::Critical, QObject::tr("Application Error"), QObject::tr("The following application experienced an error and needed to close:")+"\n\n"+cmd ); - dlg.setWindowFlags(Qt::Window); - if(!log.isEmpty()){ dlg.setDetailedText(log); } - dlg.exec(); - } + QMessageBox dlg(QMessageBox::Critical, QObject::tr("Application Error"), QObject::tr("The following application experienced an error and needed to close:")+"\n\n"+cmd ); + dlg.setWindowFlags(Qt::Window); + if(!log.isEmpty()){ dlg.setDetailedText(log); } + dlg.exec(); + } } return retcode; } diff --git a/src-qt5/core/lumina-session/main.cpp b/src-qt5/core/lumina-session/main.cpp index 71244a8b..3b71bdca 100644 --- a/src-qt5/core/lumina-session/main.cpp +++ b/src-qt5/core/lumina-session/main.cpp @@ -55,14 +55,6 @@ int main(int argc, char ** argv) return QProcess::execute("xinit", args); } qDebug() << "Starting the Lumina desktop on current X11 session:" << disp; - //Setup any initialization values - LTHEME::LoadCustomEnvSettings(); - LXDG::setEnvironmentVars(); - setenv("DESKTOP_SESSION","Lumina",1); - setenv("XDG_CURRENT_DESKTOP","Lumina",1); - unsetenv("QT_QPA_PLATFORMTHEME"); //causes issues with Lumina themes - not many people have this by default... - //Check for any missing user config files - //Check for any stale desktop lock files and clean them up QString cfile = QDir::tempPath()+"/.LSingleApp-%1-%2-%3"; @@ -81,14 +73,22 @@ int main(int argc, char ** argv) } //Configure X11 monitors if needed - if(LUtils::isValidBinary("lumina-xconfig")){ + if(LUtils::isValidBinary("lumina-xconfig")){ qDebug() << " - Resetting monitor configuration to last-used settings"; QProcess::execute("lumina-xconfig --reset-monitors"); } qDebug() << " - Starting the session..."; + //Setup any initialization values + LTHEME::LoadCustomEnvSettings(); + LXDG::setEnvironmentVars(); + setenv("DESKTOP_SESSION","Lumina",1); + setenv("XDG_CURRENT_DESKTOP","Lumina",1); + unsetenv("QT_QPA_PLATFORMTHEME"); //causes issues with Lumina themes - not many people have this by default... //Startup the session - QCoreApplication a(argc, argv); + QApplication a(argc, argv); + setenv("QP_QPA_PLATFORMTHEME","lthemeengine",1); //make sure this is after the QApplication - not actually using the theme plugin for **this** process LSession sess; + sess.checkFiles(); //Make sure user files are created/installed first sess.start(unified); int retCode = a.exec(); qDebug() << "Finished Closing Down Lumina"; diff --git a/src-qt5/core/lumina-session/session.cpp b/src-qt5/core/lumina-session/session.cpp index 3fdf9e66..743fc396 100644 --- a/src-qt5/core/lumina-session/session.cpp +++ b/src-qt5/core/lumina-session/session.cpp @@ -15,6 +15,7 @@ #include <LUtils.h> #include <LuminaOS.h> +#include <LDesktopUtils.h> void LSession::stopall(){ stopping = true; @@ -38,8 +39,12 @@ void LSession::procFinished(){ stopped++; if(!stopping){ //See if this process is the main desktop binary - if(PROCS[i]->objectName()=="runtime"){ stopall(); } - else if(PROCS[i]->objectName()=="wm" && wmfails<2){ wmfails++; PROCS[i]->start(QIODevice::ReadOnly); wmTimer->start(); } //restart the WM + if(PROCS[i]->objectName()=="runtime"){ + qDebug() << "Got Desktop Process Finished:" << PROCS[i]->exitCode(); + //if(PROCS[i]->exitCode()==787){ PROCS[i]->start(QIODevice::ReadOnly); } //special internal restart code + //else{ + stopall(); //} + }else if(PROCS[i]->objectName()=="wm" && wmfails<2){ wmfails++; PROCS[i]->start(QIODevice::ReadOnly); wmTimer->start(); } //restart the WM //if(PROCS[i]->program().section("/",-1) == "lumina-desktop"){ stopall(); } //start closing down everything //else{ PROCS[i]->start(QIODevice::ReadOnly); } //restart the process //break; @@ -164,3 +169,20 @@ void LSession::start(bool unified){ startProcess("runtime","lumina-desktop-unified"); } } + +void LSession::checkFiles(){ +//internal version conversion examples: + // [1.0.0 -> 1000000], [1.2.3 -> 1002003], [0.6.1 -> 6001] + qDebug() << "[Lumina] Checking User Files"; + QSettings sset("lumina-desktop", "sessionsettings"); + QString OVS = sset.value("DesktopVersion","0").toString(); //Old Version String + qDebug() << " - Old Version:" << OVS; + qDebug() << " - Current Version:" << LDesktopUtils::LuminaDesktopVersion(); + bool changed = LDesktopUtils::checkUserFiles(OVS, LDesktopUtils::LuminaDesktopVersion()); + qDebug() << " - Made Changes:" << changed; + if(changed){ + //Save the current version of the session to the settings file (for next time) + sset.setValue("DesktopVersion", LDesktopUtils::LuminaDesktopVersion()); + } + qDebug() << "Finished with user files check"; +} diff --git a/src-qt5/core/lumina-session/session.h b/src-qt5/core/lumina-session/session.h index 5cf1ccfa..3bbcbb8e 100644 --- a/src-qt5/core/lumina-session/session.h +++ b/src-qt5/core/lumina-session/session.h @@ -83,4 +83,6 @@ public: void start(bool unified = false); + void checkFiles(); + }; diff --git a/src-qt5/core/lumina-theme-engine/qss/scrollbar-simple.qss b/src-qt5/core/lumina-theme-engine/qss/scrollbar-simple.qss index 265ff20c..d0c9b448 100644 --- a/src-qt5/core/lumina-theme-engine/qss/scrollbar-simple.qss +++ b/src-qt5/core/lumina-theme-engine/qss/scrollbar-simple.qss @@ -11,7 +11,7 @@ QScrollBar:vertical{ QScrollBar::handle{ background: palette(base); border: 1px solid transparent; - border-radius: 7px; + border-radius: 1px; } QScrollBar::handle:hover, QScrollBar::add-line:hover, QScrollBar::sub-line:hover{ background: palette(highlight); diff --git a/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss b/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss new file mode 100644 index 00000000..e8311e92 --- /dev/null +++ b/src-qt5/core/lumina-theme-engine/qss/sliders-simple.qss @@ -0,0 +1,70 @@ +/* SLIDERS */ +QSlider::groove:horizontal { +border: 1px solid transparent; +background: palette(alternate-window); +height: 10px; +border-radius: 3px; +} +QSlider::groove:vertical { +border: 1px solid transparent; +background: palette(alternate-window); +width: 10px; +border-radius: 3px; +} +QSlider::sub-page:horizontal { +background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, + stop: 0 palette(highlight), stop: 1 palette(window)); +border: 1px solid transparent; +height: 10px; +border-radius: 3px; +} +QSlider::sub-page:vertical { +background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, + stop: 0 palette(highlight), stop: 1 palette(window)); +border: 1px solid transparent; +width: 10px; +border-radius: 3px; +} +QSlider::add-page:horizontal{ +background: palette(alternate-window); +border: 1px solid transparent; +height: 10px; +border-radius: 3px; +} +QSlider::add-page:vertical{ +background: palette(alternate-window); +border: 1px solid transparent; +width: 10px; +border-radius: 3px; +} +QSlider::handle:horizontal{ +background: palette(mid); +border: 1px solid palette(mid); +width: 1em; +border-radius: 1px; +} +QSlider::handle:vertical{ +background: palette(mid); +border: 1px solid palette(mid); +height: 1em; +border-radius: 1px; +} +QSlider::handle:horizontal:hover, QSlider::handle:vertical:hover{ +border: 1px solid palette(highlight); +background: palette(highlight); +} + +QSlider::sub-page:horizontal:disabled { +background: palette(highlight); +border-color: palette(highlight); +} + +QSlider::add-page:horizontal:disabled { +background: palette(highlight); +border-color: palette(highlight); +} + +QSlider::handle:horizontal:disabled { +background: palette(alternate-window); +border: 1px solid palette(highlight); +} diff --git a/src-qt5/core/lumina-theme-engine/qss/tooltip-simple.qss b/src-qt5/core/lumina-theme-engine/qss/tooltip-simple.qss new file mode 100644 index 00000000..9bee3e08 --- /dev/null +++ b/src-qt5/core/lumina-theme-engine/qss/tooltip-simple.qss @@ -0,0 +1,7 @@ +QToolTip{ + background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 palette(window), stop: 1 palette(alternate-window)); + border-radius: 3px; + border: 1px solid palette(highlight); + padding: 1px; + color: palette(text); +} diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.cpp b/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.cpp index d4544c7b..28a5e558 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.cpp +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.cpp @@ -55,7 +55,7 @@ void MainWindow::on_buttonBox_clicked(QAbstractButton *button){ if(p) { p->writeSettings(); } } } - if(id == QDialogButtonBox::Ok || id == QDialogButtonBox::Cancel){ + if(id == QDialogButtonBox::Ok || id == QDialogButtonBox::Cancel || id== QDialogButtonBox::Close){ close(); qApp->quit(); } diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.ui b/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.ui index dd676c37..0dc3245d 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.ui +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/mainwindow.ui @@ -293,7 +293,7 @@ Styles</string> <item> <widget class="QDialogButtonBox" name="buttonBox"> <property name="standardButtons"> - <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + <set>QDialogButtonBox::Apply|QDialogButtonBox::Close</set> </property> </widget> </item> diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.cpp b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.cpp index cd88fb56..6377016c 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.cpp +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.cpp @@ -31,6 +31,7 @@ QSSPage::QSSPage(QWidget *parent, bool desktop) : TabPage(parent), m_ui(new Ui:: m_ui->removeButton->setIcon(QIcon::fromTheme("edit-delete")); m_ui->tool_enable->setEnabled(false); m_ui->tool_disable->setEnabled(false); + m_ui->copyButton->setEnabled(false); } QSSPage::~QSSPage(){ @@ -56,6 +57,7 @@ void QSSPage::on_qssListWidget_currentItemChanged(QListWidgetItem *current, QLis } //qDebug() << "Got Current Item Changed"; m_ui->tool_disable->setEnabled(current!=0); + m_ui->copyButton->setEnabled(current!=0); if(current){ m_ui->editButton->setEnabled(current->data(QSS_WRITABLE_ROLE).toBool()); m_ui->removeButton->setEnabled(current->data(QSS_WRITABLE_ROLE).toBool()); @@ -76,6 +78,7 @@ void QSSPage::on_list_disabled_currentItemChanged(QListWidgetItem *current, QLis } //qDebug() << "Got Current Item Changed"; m_ui->tool_enable->setEnabled(current!=0); + m_ui->copyButton->setEnabled(current!=0); if(current){ m_ui->editButton->setEnabled(current->data(QSS_WRITABLE_ROLE).toBool()); m_ui->removeButton->setEnabled(current->data(QSS_WRITABLE_ROLE).toBool()); @@ -127,6 +130,36 @@ void QSSPage::on_editButton_clicked(){ } } +void QSSPage::on_copyButton_clicked(){ + QListWidgetItem *sel = currentSelection(); + if(sel==0){ return; } + QString name = QInputDialog::getText(this, tr("Enter Style Sheet Name"), tr("File name:"), QLineEdit::Normal, sel->text().section(".qss",0,0)+"_copy"); + if(name.isEmpty()){ return; } + if(!name.endsWith(".qss", Qt::CaseInsensitive)){ name.append(".qss"); } + QString filePath; + if(desktop_qss){ filePath = lthemeengine::userDesktopStyleSheetPath() + name; } + else{ filePath = lthemeengine::userStyleSheetPath() + name; } + if(QFile::exists(filePath)){ + QMessageBox::warning(this, tr("Error"), tr("The file \"%1\" already exists").arg(filePath)); + return; + } + // Make sure the directory exists + QString dir = filePath.section("/",0,-2); + if(!QFile::exists(dir)){ + QDir D(dir); + D.mkpath(dir); + } + //Copy the file over + QFile::copy(sel->data(QSS_FULL_PATH_ROLE).toString(), filePath); + //creating item + QFileInfo info(filePath); + QListWidgetItem *item = new QListWidgetItem(info.fileName(), m_ui->list_disabled); + item->setToolTip(info.filePath()); + item->setData(QSS_FULL_PATH_ROLE, info.filePath()); + item->setData(QSS_WRITABLE_ROLE, info.isWritable()); + m_ui->list_disabled->setCurrentRow(m_ui->list_disabled->count()-1); +} + void QSSPage::on_removeButton_clicked(){ QListWidgetItem *item = currentSelection(); if(!item){ return; } diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.h b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.h index 5b0025c5..07df4ac2 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.h +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.h @@ -24,6 +24,7 @@ private slots: void on_qssListWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *); void on_list_disabled_currentItemChanged(QListWidgetItem *current, QListWidgetItem *); void on_createButton_clicked(); + void on_copyButton_clicked(); void on_editButton_clicked(); void on_removeButton_clicked(); void on_renameButton_clicked(); diff --git a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.ui b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.ui index f9a980f3..def99dd0 100644 --- a/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.ui +++ b/src-qt5/core/lumina-theme-engine/src/lthemeengine/qsspage.ui @@ -63,7 +63,7 @@ <item> <spacer name="horizontalSpacer_2"> <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <sizepolicy hsizetype="Fixed" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> @@ -168,7 +168,7 @@ <item> <spacer name="horizontalSpacer_3"> <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <sizepolicy hsizetype="Fixed" vsizetype="Minimum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> @@ -222,16 +222,41 @@ <property name="enabled"> <bool>true</bool> </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="text"> <string>Create</string> </property> </widget> </item> <item> + <widget class="QToolButton" name="copyButton"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Copy</string> + </property> + </widget> + </item> + <item> <widget class="QPushButton" name="editButton"> <property name="enabled"> <bool>false</bool> </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="text"> <string>Edit</string> </property> @@ -242,6 +267,12 @@ <property name="enabled"> <bool>false</bool> </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="text"> <string>Rename</string> </property> @@ -252,6 +283,12 @@ <property name="enabled"> <bool>false</bool> </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="text"> <string>Remove</string> </property> diff --git a/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp b/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp index 9d220824..79c023dc 100644 --- a/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp +++ b/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp @@ -20,7 +20,11 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){ ui->setupUi(this); - auto_extract_close = false; + delayClose = new QTimer(this); + delayClose->setInterval(500); + delayClose->setSingleShot(true); + connect(delayClose, SIGNAL(timeout()), this, SLOT(close()) ); + QString title = tr("Archive Manager"); if( getuid()==0){ title.append(" ("+tr("Admin Mode")+")"); } this->setWindowTitle(title); @@ -70,33 +74,42 @@ MainUI::~MainUI(){ } void MainUI::LoadArguments(QStringList args){ - bool burnIMG = false; - bool autoExtract = false; - //bool autoArchive = false; + int action = -1; // 0: burnIMG, 1: autoExtract, 2: autoArchive + QStringList files; for(int i=0; i<args.length(); i++){ - if(args[i]=="--burn-img"){ burnIMG = true; continue; } - if(args[i]=="--ax"){ autoExtract = true; continue; } - //if(args[i]=="--aa"){ autoArchive = true; continue; } - if(QFile::exists(args[i])){ - ui->label_progress->setText(tr("Opening Archive...")); - if(autoExtract){ - connect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(autoextractFiles()) ); - connect(BACKEND, SIGNAL(ExtractSuccessful()), this, SLOT(close()) ); - } - BACKEND->loadFile(args[i]); - ui->actionUSB_Image->setEnabled(args[i].simplified().endsWith(".img")); - if(burnIMG){ BurnImgToUSB(); } //Go ahead and launch the burn dialog right away - break; + if(args[i].startsWith("--") ){ + if(action>=0){ break; } + else if(args[i]=="--burn-img"){ action = 0; continue; } + else if(args[i]=="--ax"){ action = 1; continue; } + else if(args[i]=="--aa"){ action = 2; continue; } + else if(args[i]=="--sx"){ action = 3; continue; } + }else{ + files << args[i]; } - //if(autoArchive){ - //get rest of arguments - //for(int i=1; i<args.length(); i++){ - // aaFileList << args[i];} - // now launch autoarchive method with arg list - // autoArchiveFiles(aaFileList); - // connect(BACKEND, SIGNAL(ArchivalSuccessful()), this, SLOT(close()) ); - //} } + if(files.isEmpty()){ return; } + //Now go through and do any actions as needed + ui->label_progress->setText(tr("Opening Archive...")); + if(action==1){ + //qDebug() << "blah"; + connect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(autoextractFiles()) ); + connect(BACKEND, SIGNAL(ExtractSuccessful()), delayClose, SLOT(start()) ); + }else if(action==2){ + aaFileList.clear(); + for(int j=1; j<files.length(); j++){ aaFileList << files[j]; } + qDebug() << "AA Files:" << aaFileList; + connect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(autoArchiveFiles()) ); + connect(BACKEND, SIGNAL(ArchivalSuccessful()), delayClose, SLOT(start()) ); + }else if(action==3 && files.length()==2){ + sxFile = files[0]; + sxPath = files[1]; + connect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(simpleExtractFiles()) ); + connect(BACKEND, SIGNAL(ExtractSuccessful()), delayClose, SLOT(start()) ); + } + BACKEND->loadFile(files[0]); + ui->actionUSB_Image->setEnabled(files[0].simplified().endsWith(".img")); + if(action==0){ BurnImgToUSB(); } //Go ahead and launch the burn dialog right away + } void MainUI::loadIcons(){ @@ -255,16 +268,35 @@ void MainUI::extractFiles(){ } void MainUI::autoextractFiles(){ - disconnect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(autoextractFiles()) ); - QString dir = BACKEND->currentFile().section("/",0,-2); //parent directory of the archive - if(dir.isEmpty()){ return; } - ui->label_progress->setText(tr("Extracting...")); - BACKEND->startExtract(dir, true); + disconnect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(autoextractFiles()) ); + QString dir = BACKEND->currentFile().section("/",0,-2); //parent directory of the archive + if(dir.isEmpty()){ return; } + QDir tmp(dir); + QString name = BACKEND->currentFile().section("/",-1).section(".",0,0); + if(QFile::exists(dir+"/"+name)){ + int num = 1; + while( QFile::exists(dir+"/"+name+"_"+QString::number(num))){ num++; } + name = name+"_"+QString::number(num); + } + if(tmp.mkdir(name) ){ + dir.append("/"+name); //created sub directory } + ui->label_progress->setText(tr("Extracting...")); + BACKEND->startExtract(dir, true); +} -/* -void MainUI::autoArchiveFiles(aaFileList){ -*/ +void MainUI::simpleExtractFiles(){ + disconnect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(autoextractFiles()) ); + QString dir = sxPath; + ui->label_progress->setText(tr("Extracting...")); + BACKEND->startExtract(dir, true); +} + +void MainUI::autoArchiveFiles(){ + qDebug() << "Auto Archive Files:" << aaFileList; + ui->label_progress->setText(tr("Adding Items...")); + BACKEND->startAdd(aaFileList); +} void MainUI::extractSelection(){ if(ui->tree_contents->currentItem()==0){ return; } //nothing selected diff --git a/src-qt5/desktop-utils/lumina-archiver/MainUI.h b/src-qt5/desktop-utils/lumina-archiver/MainUI.h index a2687895..1a9d287c 100644 --- a/src-qt5/desktop-utils/lumina-archiver/MainUI.h +++ b/src-qt5/desktop-utils/lumina-archiver/MainUI.h @@ -10,6 +10,7 @@ #include <QMainWindow> #include <QString> #include <QTreeWidgetItem> +#include <QTimer> #include "TarBackend.h" @@ -24,20 +25,21 @@ public: ~MainUI(); void LoadArguments(QStringList); - void loadIcons(); - //QStringList aaFileList; + void loadIcons(); private: Ui::MainUI *ui; Backend *BACKEND; - bool auto_extract_close; + QStringList aaFileList, sxList; + QString sxPath, sxFile; + QTimer *delayClose; QTreeWidgetItem* findItem(QString path, QTreeWidgetItem *start = 0); bool cleanItems(QStringList list, QTreeWidgetItem *start = 0); //returns true if anything gets cleaned //Functions for setting the valid file extensions ("tar" limitations) QString CreateFileTypes(); - QString OpenFileTypes(); + QString OpenFileTypes(); private slots: void NewArchive(); @@ -45,14 +47,15 @@ private slots: void addFiles(); void addDirs(); void remFiles(); - void extractFiles(); - void autoextractFiles(); - //void autoArchiveFiles(QStringList aaFileList); + void extractFiles(); + void autoextractFiles(); + void autoArchiveFiles(); + void simpleExtractFiles(); void extractSelection(); void ViewFile(QTreeWidgetItem *it); void UpdateTree(); - void BurnImgToUSB(); + void BurnImgToUSB(); //Backend Handling void ProcStarting(); diff --git a/src-qt5/desktop-utils/lumina-archiver/TarBackend.cpp b/src-qt5/desktop-utils/lumina-archiver/TarBackend.cpp index e0b802a4..f110624b 100644 --- a/src-qt5/desktop-utils/lumina-archiver/TarBackend.cpp +++ b/src-qt5/desktop-utils/lumina-archiver/TarBackend.cpp @@ -36,7 +36,7 @@ void Backend::loadFile(QString path){ flags.clear(); flags << "-f" << filepath; //add the actual archive path if(QFile::exists(path)){ startList(); qDebug () << "BACKEND LOAD startList has started";} - else{ contents.clear(); emit ProcessFinished(true, ""); } + else{ contents.clear(); emit FileLoaded(); emit ProcessFinished(true, ""); } } bool Backend::canModify(){ @@ -262,8 +262,7 @@ void Backend::procFinished(int retcode, QProcess::ExitStatus){ } } if(args.contains("-x")){ result = tr("Extraction Finished"); emit ExtractSuccessful(); } - //if(args.contains("-aa")){ result = tr("Archival Finished"); emit ArchivalSuccessful(); } - else if(args.contains("-c")){ result = tr("Modification Finished"); } + else if(args.contains("-c")){ result = tr("Modification Finished"); emit ArchivalSuccessful(); } if(needupdate){ startList(); } else{ emit ProcessFinished(retcode==0, result); result.clear(); } } diff --git a/src-qt5/desktop-utils/lumina-archiver/TarBackend.h b/src-qt5/desktop-utils/lumina-archiver/TarBackend.h index d86ecf7c..183cb610 100644 --- a/src-qt5/desktop-utils/lumina-archiver/TarBackend.h +++ b/src-qt5/desktop-utils/lumina-archiver/TarBackend.h @@ -64,7 +64,7 @@ signals: void ProcessStarting(); void ProgressUpdate(int, QString); //percentage, text void ProcessFinished(bool, QString); //success, text - //void ArchivalSuccessful(); + void ArchivalSuccessful(); }; #endif diff --git a/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_ca.ts b/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_ca.ts index 98930879..9e347a2a 100644 --- a/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_ca.ts +++ b/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_ca.ts @@ -6,7 +6,7 @@ <message> <location filename="../TarBackend.cpp" line="229"/> <source>Could not read archive</source> - <translation>No s'ha pogut llegir l'arxiu</translation> + <translation>No s'ha pogut llegir l'arxiu</translation> </message> <message> <location filename="../TarBackend.cpp" line="231"/> @@ -81,7 +81,7 @@ <message> <location filename="../MainUI.ui" line="202"/> <source>Add files to archive</source> - <translation>Afegiu fitxers a l'arxiu</translation> + <translation>Afegiu fitxers a l'arxiu</translation> </message> <message> <location filename="../MainUI.ui" line="207"/> @@ -91,7 +91,7 @@ <message> <location filename="../MainUI.ui" line="210"/> <source>Remove selection from archive</source> - <translation>Elimina la selecció de l'arxiu</translation> + <translation>Elimina la selecció de l'arxiu</translation> </message> <message> <location filename="../MainUI.ui" line="215"/> @@ -101,7 +101,7 @@ <message> <location filename="../MainUI.ui" line="218"/> <source>Extract archive into a directory</source> - <translation>Extreu l'arxiu en un directori</translation> + <translation>Extreu l'arxiu en un directori</translation> </message> <message> <location filename="../MainUI.ui" line="223"/> @@ -111,7 +111,7 @@ <message> <location filename="../MainUI.ui" line="226"/> <source>Add directory to archive</source> - <translation>Afegeix un directori a l'arxiu</translation> + <translation>Afegeix un directori a l'arxiu</translation> </message> <message> <location filename="../MainUI.ui" line="231"/> @@ -131,17 +131,17 @@ <message> <location filename="../MainUI.ui" line="242"/> <source>Copy an IMG to a USB device (may require admin permission)</source> - <translation>Copia una IMG en un dispositiu USB (pot caldre permís d'administrador)</translation> + <translation>Copia una IMG en un dispositiu USB (pot caldre permís d'administrador)</translation> </message> <message> <location filename="../MainUI.cpp" line="24"/> <source>Archive Manager</source> - <translation>Gestor d'arxius</translation> + <translation>Gestor d'arxius</translation> </message> <message> <location filename="../MainUI.cpp" line="25"/> <source>Admin Mode</source> - <translation>Mode d'administrador</translation> + <translation>Mode d'administrador</translation> </message> <message> <location filename="../MainUI.cpp" line="51"/> @@ -179,7 +179,7 @@ <location filename="../MainUI.cpp" line="81"/> <location filename="../MainUI.cpp" line="220"/> <source>Opening Archive...</source> - <translation>S'obre l'arxiu...</translation> + <translation>S'obre l'arxiu...</translation> </message> <message> <location filename="../MainUI.cpp" line="164"/> @@ -301,7 +301,7 @@ <message> <location filename="../MainUI.cpp" line="210"/> <source>Could not overwrite file:</source> - <translation>No s'ha pogut sobreescriure el fitxer:</translation> + <translation>No s'ha pogut sobreescriure el fitxer:</translation> </message> <message> <location filename="../MainUI.cpp" line="218"/> @@ -312,18 +312,18 @@ <location filename="../MainUI.cpp" line="226"/> <location filename="../MainUI.cpp" line="233"/> <source>Add to Archive</source> - <translation>Afegeix a l'arxiu</translation> + <translation>Afegeix a l'arxiu</translation> </message> <message> <location filename="../MainUI.cpp" line="228"/> <location filename="../MainUI.cpp" line="235"/> <source>Adding Items...</source> - <translation>S'afegeixen elements...</translation> + <translation>S'afegeixen elements...</translation> </message> <message> <location filename="../MainUI.cpp" line="246"/> <source>Removing Items...</source> - <translation>S'eliminen elements...</translation> + <translation>S'eliminen elements...</translation> </message> <message> <location filename="../MainUI.cpp" line="251"/> @@ -337,7 +337,7 @@ <location filename="../MainUI.cpp" line="278"/> <location filename="../MainUI.cpp" line="290"/> <source>Extracting...</source> - <translation>S'extreu...</translation> + <translation>S'extreu...</translation> </message> <message> <location filename="../MainUI.cpp" line="310"/> @@ -350,67 +350,67 @@ <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="603"/> <source>Multimedia</source> - <translation type="unfinished"></translation> + <translation>Multimèdia</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="604"/> <source>Development</source> - <translation type="unfinished"></translation> + <translation>Desenvolupament</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="605"/> <source>Education</source> - <translation type="unfinished"></translation> + <translation>Educació</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="606"/> <source>Games</source> - <translation type="unfinished"></translation> + <translation>Jocs</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="607"/> <source>Graphics</source> - <translation type="unfinished"></translation> + <translation>Gràfics</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="608"/> <source>Network</source> - <translation type="unfinished"></translation> + <translation>Xarxa</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="609"/> <source>Office</source> - <translation type="unfinished"></translation> + <translation>Oficina</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="610"/> <source>Science</source> - <translation type="unfinished"></translation> + <translation>Ciència</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="611"/> <source>Settings</source> - <translation type="unfinished"></translation> + <translation>Paràmetres</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="612"/> <source>System</source> - <translation type="unfinished"></translation> + <translation>Sistema</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="613"/> <source>Utility</source> - <translation type="unfinished"></translation> + <translation>Utilitat</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="614"/> <source>Wine</source> - <translation type="unfinished"></translation> + <translation>Wine</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="615"/> <source>Unsorted</source> - <translation type="unfinished"></translation> + <translation>Sense classificar</translation> </message> </context> <context> @@ -443,7 +443,7 @@ <message> <location filename="../imgDialog.ui" line="108"/> <source>Wipe all extra space on device (conv = sync)</source> - <translation>Neteja tot l'espai extra al dispositiu (conv = sync)</translation> + <translation>Neteja tot l'espai extra al dispositiu (conv = sync)</translation> </message> <message> <location filename="../imgDialog.ui" line="132"/> @@ -473,7 +473,7 @@ <message> <location filename="../imgDialog.cpp" line="22"/> <source>Admin Mode</source> - <translation>Mode d'administrador</translation> + <translation>Mode d'administrador</translation> </message> <message> <location filename="../imgDialog.cpp" line="36"/> @@ -508,12 +508,12 @@ <message> <location filename="../imgDialog.cpp" line="170"/> <source>Administrator Permissions Needed</source> - <translation>Calen permisos d'administrador</translation> + <translation>Calen permisos d'administrador</translation> </message> <message> <location filename="../imgDialog.cpp" line="170"/> <source>This operation requires administrator priviledges.</source> - <translation>Aquesta operació requereix privilegis d'administrador.</translation> + <translation>Aquesta operació requereix privilegis d'administrador.</translation> </message> <message> <location filename="../imgDialog.cpp" line="170"/> @@ -528,7 +528,7 @@ <message> <location filename="../imgDialog.cpp" line="175"/> <source>The process could not be completed:</source> - <translation>El procés no s'ha pogut completar:</translation> + <translation>El procés no s'ha pogut completar:</translation> </message> <message> <location filename="../imgDialog.cpp" line="178"/> @@ -538,7 +538,7 @@ <message> <location filename="../imgDialog.cpp" line="178"/> <source>The image was successfully burned to the USB device</source> - <translation>La imatge s'ha gravat correctament al dispositiu USB.</translation> + <translation>La imatge s'ha gravat correctament al dispositiu USB.</translation> </message> </context> </TS> diff --git a/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_cs.ts b/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_cs.ts index c2c5a26e..0e3d0da8 100644 --- a/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_cs.ts +++ b/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_cs.ts @@ -350,67 +350,67 @@ <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="603"/> <source>Multimedia</source> - <translation type="unfinished"></translation> + <translation>Multimédia</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="604"/> <source>Development</source> - <translation type="unfinished"></translation> + <translation>Vývoj</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="605"/> <source>Education</source> - <translation type="unfinished"></translation> + <translation>Výuka</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="606"/> <source>Games</source> - <translation type="unfinished"></translation> + <translation>Hry</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="607"/> <source>Graphics</source> - <translation type="unfinished"></translation> + <translation>Grafika</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="608"/> <source>Network</source> - <translation type="unfinished"></translation> + <translation>Sítě</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="609"/> <source>Office</source> - <translation type="unfinished"></translation> + <translation>Kancelář</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="610"/> <source>Science</source> - <translation type="unfinished"></translation> + <translation>Věda</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="611"/> <source>Settings</source> - <translation type="unfinished"></translation> + <translation>Nastavení</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="612"/> <source>System</source> - <translation type="unfinished"></translation> + <translation>Systém</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="613"/> <source>Utility</source> - <translation type="unfinished"></translation> + <translation>Nástroje</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="614"/> <source>Wine</source> - <translation type="unfinished"></translation> + <translation>Wine</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="615"/> <source>Unsorted</source> - <translation type="unfinished"></translation> + <translation>Různé</translation> </message> </context> <context> diff --git a/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_da.ts b/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_da.ts index de00be03..ad4de0bd 100644 --- a/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_da.ts +++ b/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_da.ts @@ -350,67 +350,67 @@ <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="603"/> <source>Multimedia</source> - <translation type="unfinished"></translation> + <translation>Multimedie</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="604"/> <source>Development</source> - <translation type="unfinished"></translation> + <translation>Udvikling</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="605"/> <source>Education</source> - <translation type="unfinished"></translation> + <translation>Uddannelse</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="606"/> <source>Games</source> - <translation type="unfinished"></translation> + <translation>Spil</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="607"/> <source>Graphics</source> - <translation type="unfinished"></translation> + <translation>Grafik</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="608"/> <source>Network</source> - <translation type="unfinished"></translation> + <translation>Netværk</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="609"/> <source>Office</source> - <translation type="unfinished"></translation> + <translation>Kontor</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="610"/> <source>Science</source> - <translation type="unfinished"></translation> + <translation>Videnskab</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="611"/> <source>Settings</source> - <translation type="unfinished"></translation> + <translation>Indstillinger</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="612"/> <source>System</source> - <translation type="unfinished"></translation> + <translation>System</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="613"/> <source>Utility</source> - <translation type="unfinished"></translation> + <translation>Hjælpeværktøj</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="614"/> <source>Wine</source> - <translation type="unfinished"></translation> + <translation>Wine</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="615"/> <source>Unsorted</source> - <translation type="unfinished"></translation> + <translation>Usorteret</translation> </message> </context> <context> diff --git a/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_de.ts b/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_de.ts index 8869e707..52faac28 100644 --- a/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_de.ts +++ b/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_de.ts @@ -6,22 +6,22 @@ <message> <location filename="../TarBackend.cpp" line="229"/> <source>Could not read archive</source> - <translation type="unfinished"></translation> + <translation>Archiv konnte nicht gelesen werden</translation> </message> <message> <location filename="../TarBackend.cpp" line="231"/> <source>Archive Loaded</source> - <translation type="unfinished"></translation> + <translation>Archiv geladen</translation> </message> <message> <location filename="../TarBackend.cpp" line="264"/> <source>Extraction Finished</source> - <translation type="unfinished"></translation> + <translation>Extrahierung abgeschlossen</translation> </message> <message> <location filename="../TarBackend.cpp" line="266"/> <source>Modification Finished</source> - <translation type="unfinished"></translation> + <translation>Modifikation abgeschlossen</translation> </message> </context> <context> @@ -29,307 +29,307 @@ <message> <location filename="../MainUI.ui" line="35"/> <source>Archive:</source> - <translation type="unfinished"></translation> + <translation>Archiv:</translation> </message> <message> <location filename="../MainUI.ui" line="125"/> <location filename="../MainUI.cpp" line="65"/> <location filename="../MainUI.cpp" line="296"/> <source>File</source> - <translation type="unfinished"></translation> + <translation>Datei</translation> </message> <message> <location filename="../MainUI.ui" line="134"/> <source>Edit</source> - <translation type="unfinished"></translation> + <translation>Bearbeiten</translation> </message> <message> <location filename="../MainUI.ui" line="145"/> <source>Burn to Disk</source> - <translation type="unfinished"></translation> + <translation>Auf Disc brennen</translation> </message> <message> <location filename="../MainUI.ui" line="178"/> <source>&Open Archive</source> - <translation type="unfinished"></translation> + <translation>Archiv &öffnen</translation> </message> <message> <location filename="../MainUI.ui" line="181"/> <source>Open archive</source> - <translation type="unfinished"></translation> + <translation>Archiv öffnen</translation> </message> <message> <location filename="../MainUI.ui" line="186"/> <source>&New Archive</source> - <translation type="unfinished"></translation> + <translation>&Neues Archiv</translation> </message> <message> <location filename="../MainUI.ui" line="189"/> <source>New archive</source> - <translation type="unfinished"></translation> + <translation>Neues Archiv</translation> </message> <message> <location filename="../MainUI.ui" line="194"/> <source>&Quit</source> - <translation type="unfinished"></translation> + <translation>&Beenden</translation> </message> <message> <location filename="../MainUI.ui" line="199"/> <source>Add File(s)</source> - <translation type="unfinished"></translation> + <translation>Datei(en) hinzufügen</translation> </message> <message> <location filename="../MainUI.ui" line="202"/> <source>Add files to archive</source> - <translation type="unfinished"></translation> + <translation>Dateien zum Archiv hinzufügen</translation> </message> <message> <location filename="../MainUI.ui" line="207"/> <source>Remove File(s)</source> - <translation type="unfinished"></translation> + <translation>Datei(en) entfernen</translation> </message> <message> <location filename="../MainUI.ui" line="210"/> <source>Remove selection from archive</source> - <translation type="unfinished"></translation> + <translation>Auswahl aus Archiv entfernen</translation> </message> <message> <location filename="../MainUI.ui" line="215"/> <source>Extract All</source> - <translation type="unfinished"></translation> + <translation>Alles extrahieren</translation> </message> <message> <location filename="../MainUI.ui" line="218"/> <source>Extract archive into a directory</source> - <translation type="unfinished"></translation> + <translation>Archiv in ein Verzeichnis extrahieren</translation> </message> <message> <location filename="../MainUI.ui" line="223"/> <source>Add Directory</source> - <translation type="unfinished"></translation> + <translation>Verzeichnis hinzufügen</translation> </message> <message> <location filename="../MainUI.ui" line="226"/> <source>Add directory to archive</source> - <translation type="unfinished"></translation> + <translation>Verzeichnis zum Archiv hinzufügen</translation> </message> <message> <location filename="../MainUI.ui" line="231"/> <source>Extract Selection</source> - <translation type="unfinished"></translation> + <translation>Auswahl extrahieren</translation> </message> <message> <location filename="../MainUI.ui" line="234"/> <source>Extract Selected Items</source> - <translation type="unfinished"></translation> + <translation>Ausgewählte Elemente extrahieren</translation> </message> <message> <location filename="../MainUI.ui" line="239"/> <source>USB Image</source> - <translation type="unfinished"></translation> + <translation>USB-Abbild</translation> </message> <message> <location filename="../MainUI.ui" line="242"/> <source>Copy an IMG to a USB device (may require admin permission)</source> - <translation type="unfinished"></translation> + <translation>IMG auf ein USB-Gerät kopieren (eventuell Administratorberechtigung erforderlich)</translation> </message> <message> <location filename="../MainUI.cpp" line="24"/> <source>Archive Manager</source> - <translation type="unfinished"></translation> + <translation>Archivverwaltung</translation> </message> <message> <location filename="../MainUI.cpp" line="25"/> <source>Admin Mode</source> - <translation type="unfinished"></translation> + <translation>Administratormodus</translation> </message> <message> <location filename="../MainUI.cpp" line="51"/> <source>CTRL+N</source> - <translation type="unfinished"></translation> + <translation>STRG+N</translation> </message> <message> <location filename="../MainUI.cpp" line="52"/> <source>CTRL+O</source> - <translation type="unfinished"></translation> + <translation>STRG+Ö</translation> </message> <message> <location filename="../MainUI.cpp" line="53"/> <source>CTRL+Q</source> - <translation type="unfinished"></translation> + <translation>STRG+B</translation> </message> <message> <location filename="../MainUI.cpp" line="54"/> <source>CTRL+E</source> - <translation type="unfinished"></translation> + <translation>STRG+E</translation> </message> <message> <location filename="../MainUI.cpp" line="65"/> <location filename="../MainUI.cpp" line="296"/> <source>MimeType</source> - <translation type="unfinished"></translation> + <translation>MimeType</translation> </message> <message> <location filename="../MainUI.cpp" line="65"/> <location filename="../MainUI.cpp" line="296"/> <source>Size</source> - <translation type="unfinished"></translation> + <translation>Größe</translation> </message> <message> <location filename="../MainUI.cpp" line="81"/> <location filename="../MainUI.cpp" line="220"/> <source>Opening Archive...</source> - <translation type="unfinished"></translation> + <translation>Archiv wird geöffnet...</translation> </message> <message> <location filename="../MainUI.cpp" line="164"/> <source>All Types %1</source> - <translation type="unfinished"></translation> + <translation>Alle Typen %1</translation> </message> <message> <location filename="../MainUI.cpp" line="165"/> <location filename="../MainUI.cpp" line="183"/> <source>Uncompressed Archive (*.tar)</source> - <translation type="unfinished"></translation> + <translation>Unkomprimiertes Archiv (*.tar)</translation> </message> <message> <location filename="../MainUI.cpp" line="166"/> <location filename="../MainUI.cpp" line="184"/> <source>GZip Compressed Archive (*.tar.gz *.tgz)</source> - <translation type="unfinished"></translation> + <translation>GZip-komprimiertes Archiv (*.tar.gz *.tgz)</translation> </message> <message> <location filename="../MainUI.cpp" line="167"/> <location filename="../MainUI.cpp" line="185"/> <source>BZip Compressed Archive (*.tar.bz *.tbz)</source> - <translation type="unfinished"></translation> + <translation>BZip-komprimiertes Archiv (*.tar.bz *.tbz)</translation> </message> <message> <location filename="../MainUI.cpp" line="168"/> <location filename="../MainUI.cpp" line="186"/> <source>BZip2 Compressed Archive (*.tar.bz2 *.tbz2)</source> - <translation type="unfinished"></translation> + <translation>BZip2-komprimiertes Archiv (*.tar.bz2 *.tbz2)</translation> </message> <message> <location filename="../MainUI.cpp" line="169"/> <location filename="../MainUI.cpp" line="188"/> <source>LMZA Compressed Archive (*.tar.lzma *.tlz)</source> - <translation type="unfinished"></translation> + <translation>LMZA-komprimiertes Archiv (*.tar.lzma *.tlz)</translation> </message> <message> <location filename="../MainUI.cpp" line="170"/> <location filename="../MainUI.cpp" line="187"/> <source>XZ Compressed Archive (*.tar.xz *.txz)</source> - <translation type="unfinished"></translation> + <translation>XZ-komprimiertes Archiv (*.tar.xz *.txz)</translation> </message> <message> <location filename="../MainUI.cpp" line="171"/> <location filename="../MainUI.cpp" line="189"/> <source>CPIO Archive (*.cpio)</source> - <translation type="unfinished"></translation> + <translation>CPIO-Archiv (*.cpio)</translation> </message> <message> <location filename="../MainUI.cpp" line="172"/> <location filename="../MainUI.cpp" line="190"/> <source>PAX Archive (*.pax)</source> - <translation type="unfinished"></translation> + <translation>PAX-Archiv (*.pax)</translation> </message> <message> <location filename="../MainUI.cpp" line="173"/> <location filename="../MainUI.cpp" line="191"/> <source>AR Archive (*.ar)</source> - <translation type="unfinished"></translation> + <translation>AR-Archiv (*.ar)</translation> </message> <message> <location filename="../MainUI.cpp" line="174"/> <location filename="../MainUI.cpp" line="192"/> <source>SHAR Archive (*.shar)</source> - <translation type="unfinished"></translation> + <translation>SHAR-Archiv (*.shar)</translation> </message> <message> <location filename="../MainUI.cpp" line="175"/> <location filename="../MainUI.cpp" line="193"/> <source>Zip Archive (*.zip)</source> - <translation type="unfinished"></translation> + <translation>Zip-Archiv (*.zip)</translation> </message> <message> <location filename="../MainUI.cpp" line="176"/> <location filename="../MainUI.cpp" line="194"/> <source>7-Zip Archive (*.7z)</source> - <translation type="unfinished"></translation> + <translation>7-Zip-Archiv (*.7z)</translation> </message> <message> <location filename="../MainUI.cpp" line="182"/> <source>All Known Types %1</source> - <translation type="unfinished"></translation> + <translation>Alle bekannten Typen %1</translation> </message> <message> <location filename="../MainUI.cpp" line="195"/> <source>READ-ONLY: ISO image (*.iso *.img)</source> - <translation type="unfinished"></translation> + <translation>NUR LESEN: ISO-Abbild (*.iso *.img)</translation> </message> <message> <location filename="../MainUI.cpp" line="196"/> <source>READ-ONLY: XAR archive (*.xar)</source> - <translation type="unfinished"></translation> + <translation>NUR LESEN: XAR-Archiv (*.xar)</translation> </message> <message> <location filename="../MainUI.cpp" line="197"/> <source>READ-ONLY: Java archive (*.jar)</source> - <translation type="unfinished"></translation> + <translation>NUR LESEN: Java-Archiv (*.jar)</translation> </message> <message> <location filename="../MainUI.cpp" line="198"/> <source>READ-ONLY: RedHat Package (*.rpm)</source> - <translation type="unfinished"></translation> + <translation>NUR LESEN: RedHat-Paket (*.rpm)</translation> </message> <message> <location filename="../MainUI.cpp" line="199"/> <source>Show All Files (*)</source> - <translation type="unfinished"></translation> + <translation>Alle Dateien anzeigen (*)</translation> </message> <message> <location filename="../MainUI.cpp" line="207"/> <source>Create Archive</source> - <translation type="unfinished"></translation> + <translation>Archiv erstellen</translation> </message> <message> <location filename="../MainUI.cpp" line="210"/> <source>Error</source> - <translation type="unfinished"></translation> + <translation>Fehler</translation> </message> <message> <location filename="../MainUI.cpp" line="210"/> <source>Could not overwrite file:</source> - <translation type="unfinished"></translation> + <translation>Datei konnte nicht überschrieben werden:</translation> </message> <message> <location filename="../MainUI.cpp" line="218"/> <source>Open Archive</source> - <translation type="unfinished"></translation> + <translation>Archiv öffnen</translation> </message> <message> <location filename="../MainUI.cpp" line="226"/> <location filename="../MainUI.cpp" line="233"/> <source>Add to Archive</source> - <translation type="unfinished"></translation> + <translation>Zum Archiv hinzufügen</translation> </message> <message> <location filename="../MainUI.cpp" line="228"/> <location filename="../MainUI.cpp" line="235"/> <source>Adding Items...</source> - <translation type="unfinished"></translation> + <translation>Elemente werden hinzugefügt...</translation> </message> <message> <location filename="../MainUI.cpp" line="246"/> <source>Removing Items...</source> - <translation type="unfinished"></translation> + <translation>Elemente werden entfernt...</translation> </message> <message> <location filename="../MainUI.cpp" line="251"/> <location filename="../MainUI.cpp" line="276"/> <source>Extract Into Directory</source> - <translation type="unfinished"></translation> + <translation>In Verzeichnis extrahieren</translation> </message> <message> <location filename="../MainUI.cpp" line="253"/> @@ -337,12 +337,12 @@ <location filename="../MainUI.cpp" line="278"/> <location filename="../MainUI.cpp" line="290"/> <source>Extracting...</source> - <translation type="unfinished"></translation> + <translation>Extrahierungsvorgang...</translation> </message> <message> <location filename="../MainUI.cpp" line="310"/> <source>Link To: %1</source> - <translation type="unfinished"></translation> + <translation>Link auf: %1</translation> </message> </context> <context> @@ -350,67 +350,67 @@ <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="603"/> <source>Multimedia</source> - <translation type="unfinished"></translation> + <translation>Multimedia</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="604"/> <source>Development</source> - <translation type="unfinished"></translation> + <translation>Entwicklung</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="605"/> <source>Education</source> - <translation type="unfinished"></translation> + <translation>Bildung</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="606"/> <source>Games</source> - <translation type="unfinished"></translation> + <translation>Spiele</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="607"/> <source>Graphics</source> - <translation type="unfinished"></translation> + <translation>Grafik</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="608"/> <source>Network</source> - <translation type="unfinished"></translation> + <translation>Netzwerk</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="609"/> <source>Office</source> - <translation type="unfinished"></translation> + <translation>Büro</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="610"/> <source>Science</source> - <translation type="unfinished"></translation> + <translation>Wissenschaft</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="611"/> <source>Settings</source> - <translation type="unfinished"></translation> + <translation>Einstellungen</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="612"/> <source>System</source> - <translation type="unfinished"></translation> + <translation>System</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="613"/> <source>Utility</source> - <translation type="unfinished"></translation> + <translation>Dienstprogramm</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="614"/> <source>Wine</source> - <translation type="unfinished"></translation> + <translation>Wine</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="615"/> <source>Unsorted</source> - <translation type="unfinished"></translation> + <translation>Unsortiert</translation> </message> </context> <context> @@ -418,127 +418,127 @@ <message> <location filename="../imgDialog.ui" line="14"/> <source>Burn IMG to device</source> - <translation type="unfinished"></translation> + <translation>IMG auf Gerät brennen</translation> </message> <message> <location filename="../imgDialog.ui" line="29"/> <source>IMG File</source> - <translation type="unfinished"></translation> + <translation>IMG-Datei</translation> </message> <message> <location filename="../imgDialog.ui" line="54"/> <source>Block Size</source> - <translation type="unfinished"></translation> + <translation>Blockgröße</translation> </message> <message> <location filename="../imgDialog.ui" line="84"/> <source>USB Device</source> - <translation type="unfinished"></translation> + <translation>USB-Gerät</translation> </message> <message> <location filename="../imgDialog.ui" line="96"/> <source>Refresh Device List</source> - <translation type="unfinished"></translation> + <translation>Geräteliste aktualisieren</translation> </message> <message> <location filename="../imgDialog.ui" line="108"/> <source>Wipe all extra space on device (conv = sync)</source> - <translation type="unfinished"></translation> + <translation>Sämtlichen zusätzlichen Speicherplatz auf Gerät löschen (conv = sync)</translation> </message> <message> <location filename="../imgDialog.ui" line="132"/> <source>Burning to USB:</source> - <translation type="unfinished"></translation> + <translation>Auf USB brennen:</translation> </message> <message> <location filename="../imgDialog.ui" line="166"/> <source>Time Elapsed:</source> - <translation type="unfinished"></translation> + <translation>Vergangene Zeit:</translation> </message> <message> <location filename="../imgDialog.ui" line="222"/> <source>Cancel</source> - <translation type="unfinished"></translation> + <translation>Abbrechen</translation> </message> <message> <location filename="../imgDialog.ui" line="229"/> <source>Start</source> - <translation type="unfinished"></translation> + <translation>Start</translation> </message> <message> <location filename="../imgDialog.cpp" line="21"/> <source>Burn IMG to Device</source> - <translation type="unfinished"></translation> + <translation>IMG auf Gerät brennen</translation> </message> <message> <location filename="../imgDialog.cpp" line="22"/> <source>Admin Mode</source> - <translation type="unfinished"></translation> + <translation>Administratormodus</translation> </message> <message> <location filename="../imgDialog.cpp" line="36"/> <source>Kilobyte(s)</source> - <translation type="unfinished"></translation> + <translation>Kilobyte(s)</translation> </message> <message> <location filename="../imgDialog.cpp" line="37"/> <source>Megabyte(s)</source> - <translation type="unfinished"></translation> + <translation>Megabyte(s)</translation> </message> <message> <location filename="../imgDialog.cpp" line="38"/> <source>Gigabyte(s)</source> - <translation type="unfinished"></translation> + <translation>Gigabyte(s)</translation> </message> <message> <location filename="../imgDialog.cpp" line="110"/> <source>Cancel Image Burn?</source> - <translation type="unfinished"></translation> + <translation>Brennen des Abbildes abbrechen?</translation> </message> <message> <location filename="../imgDialog.cpp" line="110"/> <source>Do you wish to stop the current IMG burn process?</source> - <translation type="unfinished"></translation> + <translation>Möchten Sie den laufenden IMG-Brennprozess stoppen?</translation> </message> <message> <location filename="../imgDialog.cpp" line="110"/> <source>Warning: This will leave the USB device in an inconsistent state</source> - <translation type="unfinished"></translation> + <translation>Warnung: Dies wird das USB-Gerät in einem inkonsistenten Zustand zurücklassen</translation> </message> <message> <location filename="../imgDialog.cpp" line="170"/> <source>Administrator Permissions Needed</source> - <translation type="unfinished"></translation> + <translation>Administratorberechtigungen erforderlich</translation> </message> <message> <location filename="../imgDialog.cpp" line="170"/> <source>This operation requires administrator priviledges.</source> - <translation type="unfinished"></translation> + <translation>Dieser Vorgang erfordert Administratorrechte.</translation> </message> <message> <location filename="../imgDialog.cpp" line="170"/> <source>Would you like to enable these priviledges?</source> - <translation type="unfinished"></translation> + <translation>Möchten Sie diese Rechte aktivieren?</translation> </message> <message> <location filename="../imgDialog.cpp" line="175"/> <source>ERROR</source> - <translation type="unfinished"></translation> + <translation>FEHLER</translation> </message> <message> <location filename="../imgDialog.cpp" line="175"/> <source>The process could not be completed:</source> - <translation type="unfinished"></translation> + <translation>Der Prozess konnte nicht abgeschlossen werden:</translation> </message> <message> <location filename="../imgDialog.cpp" line="178"/> <source>SUCCESS</source> - <translation type="unfinished"></translation> + <translation>ERFOLG</translation> </message> <message> <location filename="../imgDialog.cpp" line="178"/> <source>The image was successfully burned to the USB device</source> - <translation type="unfinished"></translation> + <translation>Das Abbild wurde erfolgreich auf das USB-Gerät gebrannt</translation> </message> </context> </TS> diff --git a/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_fi.ts b/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_fi.ts index 5b1d98dc..8467eb99 100644 --- a/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_fi.ts +++ b/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_fi.ts @@ -6,22 +6,22 @@ <message> <location filename="../TarBackend.cpp" line="229"/> <source>Could not read archive</source> - <translation type="unfinished"></translation> + <translation>Arkistoa ei voitu lukea</translation> </message> <message> <location filename="../TarBackend.cpp" line="231"/> <source>Archive Loaded</source> - <translation type="unfinished"></translation> + <translation>Arkisto ladattu</translation> </message> <message> <location filename="../TarBackend.cpp" line="264"/> <source>Extraction Finished</source> - <translation type="unfinished"></translation> + <translation>Purku valmis</translation> </message> <message> <location filename="../TarBackend.cpp" line="266"/> <source>Modification Finished</source> - <translation type="unfinished"></translation> + <translation>Muutos valmis</translation> </message> </context> <context> @@ -29,307 +29,307 @@ <message> <location filename="../MainUI.ui" line="35"/> <source>Archive:</source> - <translation type="unfinished"></translation> + <translation>Arkisto:</translation> </message> <message> <location filename="../MainUI.ui" line="125"/> <location filename="../MainUI.cpp" line="65"/> <location filename="../MainUI.cpp" line="296"/> <source>File</source> - <translation type="unfinished"></translation> + <translation>Tiedosto</translation> </message> <message> <location filename="../MainUI.ui" line="134"/> <source>Edit</source> - <translation type="unfinished"></translation> + <translation>Muokkaa</translation> </message> <message> <location filename="../MainUI.ui" line="145"/> <source>Burn to Disk</source> - <translation type="unfinished"></translation> + <translation>Polta levylle</translation> </message> <message> <location filename="../MainUI.ui" line="178"/> <source>&Open Archive</source> - <translation type="unfinished"></translation> + <translation>&Avaa arkisto</translation> </message> <message> <location filename="../MainUI.ui" line="181"/> <source>Open archive</source> - <translation type="unfinished"></translation> + <translation>Avaa arkisto</translation> </message> <message> <location filename="../MainUI.ui" line="186"/> <source>&New Archive</source> - <translation type="unfinished"></translation> + <translation>&Uusi arkisto</translation> </message> <message> <location filename="../MainUI.ui" line="189"/> <source>New archive</source> - <translation type="unfinished"></translation> + <translation>Uusi arkisto</translation> </message> <message> <location filename="../MainUI.ui" line="194"/> <source>&Quit</source> - <translation type="unfinished"></translation> + <translation>&Lopeta</translation> </message> <message> <location filename="../MainUI.ui" line="199"/> <source>Add File(s)</source> - <translation type="unfinished"></translation> + <translation>Lisää tiedostoja</translation> </message> <message> <location filename="../MainUI.ui" line="202"/> <source>Add files to archive</source> - <translation type="unfinished"></translation> + <translation>Lisää arkistoon tiedostoja</translation> </message> <message> <location filename="../MainUI.ui" line="207"/> <source>Remove File(s)</source> - <translation type="unfinished"></translation> + <translation>Poista tiedostoja</translation> </message> <message> <location filename="../MainUI.ui" line="210"/> <source>Remove selection from archive</source> - <translation type="unfinished"></translation> + <translation>Poista arkistosta tiedostoja</translation> </message> <message> <location filename="../MainUI.ui" line="215"/> <source>Extract All</source> - <translation type="unfinished"></translation> + <translation>Pura kaikki</translation> </message> <message> <location filename="../MainUI.ui" line="218"/> <source>Extract archive into a directory</source> - <translation type="unfinished"></translation> + <translation>Pura arkisto kansioon</translation> </message> <message> <location filename="../MainUI.ui" line="223"/> <source>Add Directory</source> - <translation type="unfinished"></translation> + <translation>Lisää kansio</translation> </message> <message> <location filename="../MainUI.ui" line="226"/> <source>Add directory to archive</source> - <translation type="unfinished"></translation> + <translation>Lisää arkistoon kansio</translation> </message> <message> <location filename="../MainUI.ui" line="231"/> <source>Extract Selection</source> - <translation type="unfinished"></translation> + <translation>Pura valinta</translation> </message> <message> <location filename="../MainUI.ui" line="234"/> <source>Extract Selected Items</source> - <translation type="unfinished"></translation> + <translation>Pura valitut kohteet</translation> </message> <message> <location filename="../MainUI.ui" line="239"/> <source>USB Image</source> - <translation type="unfinished"></translation> + <translation>USB-levykuva</translation> </message> <message> <location filename="../MainUI.ui" line="242"/> <source>Copy an IMG to a USB device (may require admin permission)</source> - <translation type="unfinished"></translation> + <translation>Kopioi IMG-levykuva USB-laitteeseen (voi vaatia ylläpitäjän oikeuksia)</translation> </message> <message> <location filename="../MainUI.cpp" line="24"/> <source>Archive Manager</source> - <translation type="unfinished"></translation> + <translation>Arkistonhallinta</translation> </message> <message> <location filename="../MainUI.cpp" line="25"/> <source>Admin Mode</source> - <translation type="unfinished"></translation> + <translation>Ylläpitäjän tila</translation> </message> <message> <location filename="../MainUI.cpp" line="51"/> <source>CTRL+N</source> - <translation type="unfinished"></translation> + <translation>Ctrl+N</translation> </message> <message> <location filename="../MainUI.cpp" line="52"/> <source>CTRL+O</source> - <translation type="unfinished"></translation> + <translation>Ctrl+O</translation> </message> <message> <location filename="../MainUI.cpp" line="53"/> <source>CTRL+Q</source> - <translation type="unfinished"></translation> + <translation>Ctrl+Q</translation> </message> <message> <location filename="../MainUI.cpp" line="54"/> <source>CTRL+E</source> - <translation type="unfinished"></translation> + <translation>Ctrl+E</translation> </message> <message> <location filename="../MainUI.cpp" line="65"/> <location filename="../MainUI.cpp" line="296"/> <source>MimeType</source> - <translation type="unfinished"></translation> + <translation>MIME-tyyppi</translation> </message> <message> <location filename="../MainUI.cpp" line="65"/> <location filename="../MainUI.cpp" line="296"/> <source>Size</source> - <translation type="unfinished"></translation> + <translation>Koko</translation> </message> <message> <location filename="../MainUI.cpp" line="81"/> <location filename="../MainUI.cpp" line="220"/> <source>Opening Archive...</source> - <translation type="unfinished"></translation> + <translation>Avataan arkistoa...</translation> </message> <message> <location filename="../MainUI.cpp" line="164"/> <source>All Types %1</source> - <translation type="unfinished"></translation> + <translation>Kaikki tyypit %1</translation> </message> <message> <location filename="../MainUI.cpp" line="165"/> <location filename="../MainUI.cpp" line="183"/> <source>Uncompressed Archive (*.tar)</source> - <translation type="unfinished"></translation> + <translation>Pakkaamaton arkisto (*.tar)</translation> </message> <message> <location filename="../MainUI.cpp" line="166"/> <location filename="../MainUI.cpp" line="184"/> <source>GZip Compressed Archive (*.tar.gz *.tgz)</source> - <translation type="unfinished"></translation> + <translation>GZip-pakattu arkisto (*.tar.gz *.tgz)</translation> </message> <message> <location filename="../MainUI.cpp" line="167"/> <location filename="../MainUI.cpp" line="185"/> <source>BZip Compressed Archive (*.tar.bz *.tbz)</source> - <translation type="unfinished"></translation> + <translation>BZip-pakattu arkisto (*.tar.bz *.tbz)</translation> </message> <message> <location filename="../MainUI.cpp" line="168"/> <location filename="../MainUI.cpp" line="186"/> <source>BZip2 Compressed Archive (*.tar.bz2 *.tbz2)</source> - <translation type="unfinished"></translation> + <translation>BZip2-pakattu arkisto (*.tar.bz2 *.tbz2)</translation> </message> <message> <location filename="../MainUI.cpp" line="169"/> <location filename="../MainUI.cpp" line="188"/> <source>LMZA Compressed Archive (*.tar.lzma *.tlz)</source> - <translation type="unfinished"></translation> + <translation>LMZA-pakattu arkisto (*.tar.lzma *.tlz)</translation> </message> <message> <location filename="../MainUI.cpp" line="170"/> <location filename="../MainUI.cpp" line="187"/> <source>XZ Compressed Archive (*.tar.xz *.txz)</source> - <translation type="unfinished"></translation> + <translation>XZ-pakattu arkisto (*.tar.xz *.txz)</translation> </message> <message> <location filename="../MainUI.cpp" line="171"/> <location filename="../MainUI.cpp" line="189"/> <source>CPIO Archive (*.cpio)</source> - <translation type="unfinished"></translation> + <translation>CPIO-arkisto (*.cpio)</translation> </message> <message> <location filename="../MainUI.cpp" line="172"/> <location filename="../MainUI.cpp" line="190"/> <source>PAX Archive (*.pax)</source> - <translation type="unfinished"></translation> + <translation>PAX-arkisto (*.pax)</translation> </message> <message> <location filename="../MainUI.cpp" line="173"/> <location filename="../MainUI.cpp" line="191"/> <source>AR Archive (*.ar)</source> - <translation type="unfinished"></translation> + <translation>AR-arkisto (*.ar)</translation> </message> <message> <location filename="../MainUI.cpp" line="174"/> <location filename="../MainUI.cpp" line="192"/> <source>SHAR Archive (*.shar)</source> - <translation type="unfinished"></translation> + <translation>SHAR-arkisto (*.shar)</translation> </message> <message> <location filename="../MainUI.cpp" line="175"/> <location filename="../MainUI.cpp" line="193"/> <source>Zip Archive (*.zip)</source> - <translation type="unfinished"></translation> + <translation>Zip-arkisto (*.zip)</translation> </message> <message> <location filename="../MainUI.cpp" line="176"/> <location filename="../MainUI.cpp" line="194"/> <source>7-Zip Archive (*.7z)</source> - <translation type="unfinished"></translation> + <translation>7-Zip-arkisto (*.7z)</translation> </message> <message> <location filename="../MainUI.cpp" line="182"/> <source>All Known Types %1</source> - <translation type="unfinished"></translation> + <translation>Kaikki tunnetut tyypit %1</translation> </message> <message> <location filename="../MainUI.cpp" line="195"/> <source>READ-ONLY: ISO image (*.iso *.img)</source> - <translation type="unfinished"></translation> + <translation>VAIN LUKU: ISO-levykuva (*.iso *.img)</translation> </message> <message> <location filename="../MainUI.cpp" line="196"/> <source>READ-ONLY: XAR archive (*.xar)</source> - <translation type="unfinished"></translation> + <translation>VAIN LUKU: XAR-arkisto (*.xar)</translation> </message> <message> <location filename="../MainUI.cpp" line="197"/> <source>READ-ONLY: Java archive (*.jar)</source> - <translation type="unfinished"></translation> + <translation>VAIN LUKU: Java-arkisto (*.jar)</translation> </message> <message> <location filename="../MainUI.cpp" line="198"/> <source>READ-ONLY: RedHat Package (*.rpm)</source> - <translation type="unfinished"></translation> + <translation>VAIN LUKU: RedHat-paketti (*.rpm)</translation> </message> <message> <location filename="../MainUI.cpp" line="199"/> <source>Show All Files (*)</source> - <translation type="unfinished"></translation> + <translation>Näytä kaikki tiedostot (*)</translation> </message> <message> <location filename="../MainUI.cpp" line="207"/> <source>Create Archive</source> - <translation type="unfinished"></translation> + <translation>Luo arkisto</translation> </message> <message> <location filename="../MainUI.cpp" line="210"/> <source>Error</source> - <translation type="unfinished"></translation> + <translation>Virhe</translation> </message> <message> <location filename="../MainUI.cpp" line="210"/> <source>Could not overwrite file:</source> - <translation type="unfinished"></translation> + <translation>Ei voitu korvata tiedostoa:</translation> </message> <message> <location filename="../MainUI.cpp" line="218"/> <source>Open Archive</source> - <translation type="unfinished"></translation> + <translation>Avaa arkisto</translation> </message> <message> <location filename="../MainUI.cpp" line="226"/> <location filename="../MainUI.cpp" line="233"/> <source>Add to Archive</source> - <translation type="unfinished"></translation> + <translation>Lisää arkistoon</translation> </message> <message> <location filename="../MainUI.cpp" line="228"/> <location filename="../MainUI.cpp" line="235"/> <source>Adding Items...</source> - <translation type="unfinished"></translation> + <translation>Lisätään kohteita...</translation> </message> <message> <location filename="../MainUI.cpp" line="246"/> <source>Removing Items...</source> - <translation type="unfinished"></translation> + <translation>Poistetaan kohteita...</translation> </message> <message> <location filename="../MainUI.cpp" line="251"/> <location filename="../MainUI.cpp" line="276"/> <source>Extract Into Directory</source> - <translation type="unfinished"></translation> + <translation>Pura kansioon</translation> </message> <message> <location filename="../MainUI.cpp" line="253"/> @@ -337,12 +337,12 @@ <location filename="../MainUI.cpp" line="278"/> <location filename="../MainUI.cpp" line="290"/> <source>Extracting...</source> - <translation type="unfinished"></translation> + <translation>Puretaan...</translation> </message> <message> <location filename="../MainUI.cpp" line="310"/> <source>Link To: %1</source> - <translation type="unfinished"></translation> + <translation>Linkki kohteeseen: %1</translation> </message> </context> <context> @@ -350,37 +350,37 @@ <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="603"/> <source>Multimedia</source> - <translation type="unfinished"></translation> + <translation>Multimedia</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="604"/> <source>Development</source> - <translation type="unfinished"></translation> + <translation>Kehitys</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="605"/> <source>Education</source> - <translation type="unfinished"></translation> + <translation>Kasvatus</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="606"/> <source>Games</source> - <translation type="unfinished"></translation> + <translation>Pelit</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="607"/> <source>Graphics</source> - <translation type="unfinished"></translation> + <translation>Grafiikka</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="608"/> <source>Network</source> - <translation type="unfinished"></translation> + <translation>Verkko</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="609"/> <source>Office</source> - <translation type="unfinished"></translation> + <translation>Toimisto</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="610"/> @@ -418,127 +418,127 @@ <message> <location filename="../imgDialog.ui" line="14"/> <source>Burn IMG to device</source> - <translation type="unfinished"></translation> + <translation>Polta IMG-levykuva laitteelle</translation> </message> <message> <location filename="../imgDialog.ui" line="29"/> <source>IMG File</source> - <translation type="unfinished"></translation> + <translation>IMG-tiedosto</translation> </message> <message> <location filename="../imgDialog.ui" line="54"/> <source>Block Size</source> - <translation type="unfinished"></translation> + <translation>Lohkokoko</translation> </message> <message> <location filename="../imgDialog.ui" line="84"/> <source>USB Device</source> - <translation type="unfinished"></translation> + <translation>USB-laite</translation> </message> <message> <location filename="../imgDialog.ui" line="96"/> <source>Refresh Device List</source> - <translation type="unfinished"></translation> + <translation>Virkistä laiteluettelo</translation> </message> <message> <location filename="../imgDialog.ui" line="108"/> <source>Wipe all extra space on device (conv = sync)</source> - <translation type="unfinished"></translation> + <translation>Pyyhi laitteen kaikki ylimääräinen tila (conv=sync)</translation> </message> <message> <location filename="../imgDialog.ui" line="132"/> <source>Burning to USB:</source> - <translation type="unfinished"></translation> + <translation>Poltetaan USB:lle:</translation> </message> <message> <location filename="../imgDialog.ui" line="166"/> <source>Time Elapsed:</source> - <translation type="unfinished"></translation> + <translation>Aikaa kulunut:</translation> </message> <message> <location filename="../imgDialog.ui" line="222"/> <source>Cancel</source> - <translation type="unfinished"></translation> + <translation>Peru</translation> </message> <message> <location filename="../imgDialog.ui" line="229"/> <source>Start</source> - <translation type="unfinished"></translation> + <translation>Käynnistä</translation> </message> <message> <location filename="../imgDialog.cpp" line="21"/> <source>Burn IMG to Device</source> - <translation type="unfinished"></translation> + <translation>Polta IMG-levykuva laitteelle</translation> </message> <message> <location filename="../imgDialog.cpp" line="22"/> <source>Admin Mode</source> - <translation type="unfinished"></translation> + <translation>Ylläpitäjän tila</translation> </message> <message> <location filename="../imgDialog.cpp" line="36"/> <source>Kilobyte(s)</source> - <translation type="unfinished"></translation> + <translation>kilotavu(a)</translation> </message> <message> <location filename="../imgDialog.cpp" line="37"/> <source>Megabyte(s)</source> - <translation type="unfinished"></translation> + <translation>megatavu(a)</translation> </message> <message> <location filename="../imgDialog.cpp" line="38"/> <source>Gigabyte(s)</source> - <translation type="unfinished"></translation> + <translation>gigatavu(a)</translation> </message> <message> <location filename="../imgDialog.cpp" line="110"/> <source>Cancel Image Burn?</source> - <translation type="unfinished"></translation> + <translation>Perutaanko levykuvan poltto?</translation> </message> <message> <location filename="../imgDialog.cpp" line="110"/> <source>Do you wish to stop the current IMG burn process?</source> - <translation type="unfinished"></translation> + <translation>Haluatko pysäyttää käynnissä olevan IMG-levykuvan polton?</translation> </message> <message> <location filename="../imgDialog.cpp" line="110"/> <source>Warning: This will leave the USB device in an inconsistent state</source> - <translation type="unfinished"></translation> + <translation>Varoitus: Tämä jättää USB-laitteesi epävakaaseen tilaan</translation> </message> <message> <location filename="../imgDialog.cpp" line="170"/> <source>Administrator Permissions Needed</source> - <translation type="unfinished"></translation> + <translation>Ylläpitäjäoikeudet vaaditaan</translation> </message> <message> <location filename="../imgDialog.cpp" line="170"/> <source>This operation requires administrator priviledges.</source> - <translation type="unfinished"></translation> + <translation>Tämä toiminto vaatii ylläpitäjän oikeuksia.</translation> </message> <message> <location filename="../imgDialog.cpp" line="170"/> <source>Would you like to enable these priviledges?</source> - <translation type="unfinished"></translation> + <translation>Haluatko ottaa nämä oikeudet käyttöön?</translation> </message> <message> <location filename="../imgDialog.cpp" line="175"/> <source>ERROR</source> - <translation type="unfinished"></translation> + <translation>VIRHE</translation> </message> <message> <location filename="../imgDialog.cpp" line="175"/> <source>The process could not be completed:</source> - <translation type="unfinished"></translation> + <translation>Toimenpidettä ei saatu loppuun:</translation> </message> <message> <location filename="../imgDialog.cpp" line="178"/> <source>SUCCESS</source> - <translation type="unfinished"></translation> + <translation>ONNISTUI</translation> </message> <message> <location filename="../imgDialog.cpp" line="178"/> <source>The image was successfully burned to the USB device</source> - <translation type="unfinished"></translation> + <translation>Levykuva poltettiin ongelmitta USB-laitteelle</translation> </message> </context> </TS> diff --git a/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_lt.ts b/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_lt.ts index 1c53233d..d8faaae4 100644 --- a/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_lt.ts +++ b/src-qt5/desktop-utils/lumina-archiver/i18n/l-archiver_lt.ts @@ -350,7 +350,7 @@ <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="603"/> <source>Multimedia</source> - <translation type="unfinished"></translation> + <translation>Multimedija</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="604"/> @@ -360,42 +360,42 @@ <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="605"/> <source>Education</source> - <translation type="unfinished"></translation> + <translation>Švietimas</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="606"/> <source>Games</source> - <translation type="unfinished"></translation> + <translation>Žaidimai</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="607"/> <source>Graphics</source> - <translation type="unfinished"></translation> + <translation>Grafika</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="608"/> <source>Network</source> - <translation type="unfinished"></translation> + <translation>Tinklas</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="609"/> <source>Office</source> - <translation type="unfinished"></translation> + <translation>Raštinė</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="610"/> <source>Science</source> - <translation type="unfinished"></translation> + <translation>Mokslas</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="611"/> <source>Settings</source> - <translation type="unfinished"></translation> + <translation>Nustatymai</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="612"/> <source>System</source> - <translation type="unfinished"></translation> + <translation>Sistema</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="613"/> @@ -405,7 +405,7 @@ <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="614"/> <source>Wine</source> - <translation type="unfinished"></translation> + <translation>Wine</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="615"/> @@ -513,12 +513,12 @@ <message> <location filename="../imgDialog.cpp" line="170"/> <source>This operation requires administrator priviledges.</source> - <translation type="unfinished"></translation> + <translation>Ši operacija reikalauja administratoriaus teisių.</translation> </message> <message> <location filename="../imgDialog.cpp" line="170"/> <source>Would you like to enable these priviledges?</source> - <translation type="unfinished"></translation> + <translation>Ar norėtumėte leisti šias teises?</translation> </message> <message> <location filename="../imgDialog.cpp" line="175"/> diff --git a/src-qt5/desktop-utils/lumina-archiver/main.cpp b/src-qt5/desktop-utils/lumina-archiver/main.cpp index 40cd7967..01e7bda1 100644 --- a/src-qt5/desktop-utils/lumina-archiver/main.cpp +++ b/src-qt5/desktop-utils/lumina-archiver/main.cpp @@ -15,7 +15,7 @@ int main(int argc, char *argv[]) { LTHEME::LoadCustomEnvSettings(); QApplication a(argc, argv); - a.setAttribute(Qt::AA_UseHighDpiPixmaps); + a.setAttribute(Qt::AA_UseHighDpiPixmaps); LUtils::LoadTranslation(&a, "l-archiver"); //Now go ahead and setup the app QStringList args; diff --git a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp index d82f09ce..e64346ae 100644 --- a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp +++ b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp @@ -8,21 +8,25 @@ #include "MainUI.h" #include "ui_MainUI.h" +#include <QVideoFrame> #include <QFileDialog> #include <QMessageBox> #include <LUtils.h> #include <LuminaOS.h> -//LFileInfo INFO = LFileInfo(""); - -MainUI::MainUI() : QDialog(), ui(new Ui::MainUI){ +MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){ ui->setupUi(this); //load the designer form canwrite = false; terminate_thread = false; + INFO = new LFileInfo(); UpdateIcons(); //Set all the icons in the dialog SetupConnections(); - INFO = 0; + + //Disable buttons that are not working yet + //ui->actionOpen_File->setVisible(false); + //ui->actionOpen_Directory->setVisible(false); + //ui->menuSave_As->setEnabled(false); } MainUI::~MainUI(){ @@ -38,133 +42,38 @@ void MainUI::LoadFile(QString path, QString type){ //Do the first file information tab qDebug() << "Load File:" << path << type; INFO = new LFileInfo(path); - if(INFO->exists()){ canwrite = INFO->isWritable(); } - else if(!INFO->filePath().isEmpty()){ - //See if the containing directory can be written - //QFileInfo chk(INFO->absolutePath()); - canwrite = (INFO->isDir() && INFO->isWritable()); - }else{ - canwrite = true; //no associated file yet - } - if(!INFO->exists() && !type.isEmpty()){ - //Set the proper type flag on the shortcut - if(type=="APP"){ INFO->XDG()->type = XDGDesktop::APP; } - else if(type=="LINK"){ INFO->XDG()->type = XDGDesktop::LINK; } - } //First load the general file information if(!INFO->filePath().isEmpty()){ - ui->label_file_name->setText( INFO->fileName() ); - ui->label_file_mimetype->setText( INFO->mimetype() ); - if(!INFO->isDir()){ ui->label_file_size->setText( LUtils::BytesToDisplaySize( INFO->size() ) ); } - else { - ui->label_file_size->setText(tr("---Calculating---")); - QtConcurrent::run(this, &MainUI::GetDirSize, INFO->absoluteFilePath()); - } - ui->label_file_owner->setText(INFO->owner()); - ui->label_file_group->setText(INFO->group()); - ui->label_file_created->setText( INFO->created().toString(Qt::SystemLocaleLongDate) ); - ui->label_file_modified->setText( INFO->lastModified().toString(Qt::SystemLocaleLongDate) ); - //Get the file permissions - QString perms; - if(INFO->isReadable() && INFO->isWritable()){ perms = tr("Read/Write"); } - else if(INFO->isReadable()){ perms = tr("Read Only"); } - else if(INFO->isWritable()){ perms = tr("Write Only"); } - else{ perms = tr("No Access"); } - ui->label_file_perms->setText(perms); - //Now the special "type" for the file - QString ftype; - if(INFO->suffix().toLower()=="desktop"){ ftype = tr("XDG Shortcut"); } - else if(INFO->isDir()){ ftype = tr("Directory"); } - else if(INFO->isExecutable()){ ftype = tr("Binary"); } - else{ ftype = INFO->suffix().toUpper(); } - if(INFO->isHidden()){ ftype = QString(tr("Hidden %1")).arg(type); } - ui->label_file_type->setText(ftype); - //Now load the icon for the file - if(INFO->isImage()){ - //qDebug() << "Set Image:"; - QPixmap pix(INFO->absoluteFilePath()); - ui->label_file_icon->setPixmap( pix.scaledToHeight(64) ); - ui->label_file_size->setText( ui->label_file_size->text()+" ("+QString::number(pix.width())+" x "+QString::number(pix.height())+" px)" ); - //qDebug() << " - done with image"; - }else{ - ui->label_file_icon->setPixmap( LXDG::findIcon( INFO->iconfile(), "unknown").pixmap(QSize(64,64)) ); - } - //Now verify the tab is available in the widget - //qDebug() << "Check tab widget"; - if(ui->tabWidget->indexOf(ui->tab_file)<0){ - //qDebug() << "Add File Info Tab"; - ui->tabWidget->addTab(ui->tab_file, tr("File Information")); - } - //qDebug() << "Done with Tab Check"; + SyncFileInfo(); }else{ - if(ui->tabWidget->indexOf(ui->tab_file)>=0){ - ui->tabWidget->removeTab( ui->tabWidget->indexOf(ui->tab_file) ); - } + SetupNewFile(); } - //Now load the special XDG desktop info - qDebug() << "Check XDG Info:" << type; - //qDebug() << INFO->isDesktopFile() << type; - if(INFO->isDesktopFile() || !type.isEmpty()){ - - if(INFO->XDG()->type == XDGDesktop::APP){ - ui->line_xdg_command->setText(INFO->XDG()->exec); - ui->line_xdg_wdir->setText(INFO->XDG()->path); - ui->check_xdg_useTerminal->setChecked( INFO->XDG()->useTerminal ); - ui->check_xdg_startupNotify->setChecked( INFO->XDG()->startupNotify ); - }else if(INFO->XDG()->type==XDGDesktop::LINK){ - //Hide the options that are unavailable for links - //Command line (exec) - ui->line_xdg_command->setVisible(false); - ui->tool_xdg_getCommand->setVisible(false); - ui->lblCommand->setVisible(false); - //Options - ui->lblOptions->setVisible(false); - ui->check_xdg_useTerminal->setVisible(false); - ui->check_xdg_startupNotify->setVisible(false); - //Now load the variables for this type of shortcut - ui->lblWorkingDir->setText(tr("URL:")); - ui->line_xdg_wdir->setText( INFO->XDG()->url ); - ui->tool_xdg_getDir->setVisible(false); //the dir selection button - - } - ui->line_xdg_name->setText(INFO->XDG()->name); - ui->line_xdg_comment->setText(INFO->XDG()->comment); - ui->push_xdg_getIcon->setWhatsThis( INFO->XDG()->icon ); - ReloadAppIcon(); - ui->push_save->setVisible(true); - ui->push_save->setEnabled(false); - //Now ensure the xdg tab exists in the widget - if(ui->tabWidget->indexOf(ui->tab_deskedit)<0){ - qDebug() << "Adding the deskedit tab"; - ui->tabWidget->addTab(ui->tab_deskedit, tr("Edit Shortcut")); - } - }else{ - xdgvaluechanged(); //just do the disables here - //Also remove the xdg tab - if(ui->tabWidget->indexOf(ui->tab_deskedit) >= 0){ - qDebug() << "Removing the deskedit tab"; - ui->tabWidget->removeTab( ui->tabWidget->indexOf(ui->tab_deskedit) ); - } - } - //Setup the tab - if(type.isEmpty()){ ui->tabWidget->setCurrentIndex(0); } - else if(ui->tabWidget->count()>1){ ui->tabWidget->setCurrentIndex(1); } - qDebug() << "Done Loading File"; } void MainUI::UpdateIcons(){ - this->setWindowIcon(LXDG::findIcon("document-preview","unknown")); - ui->push_close->setIcon( LXDG::findIcon("dialog-close","") ); - ui->push_save->setIcon( LXDG::findIcon("document-save","") ); - ui->tool_xdg_getCommand->setIcon( LXDG::findIcon("edit-find-page","") ); - ui->tool_xdg_getDir->setIcon( LXDG::findIcon("document-open","") ); + } //============== // PRIVATE //============== void MainUI::ReloadAppIcon(){ - ui->push_xdg_getIcon->setIcon( LXDG::findIcon(ui->push_xdg_getIcon->whatsThis(),"") ); + //qDebug() << "Reload App Icon:"; + ui->label_xdg_icon->setPixmap( LXDG::findIcon(ui->line_xdg_icon->text(),"").pixmap(64,64) ); + //qDebug() << "Check Desktop File entry"; + if(INFO->iconfile()!=ui->line_xdg_icon->text()){ + xdgvaluechanged(); + } + //qDebug() << "Done with app icon"; +} + +void MainUI::stopDirSize(){ + if(sizeThread.isRunning()){ + terminate_thread = true; + sizeThread.waitForFinished(); + QApplication::processEvents(); //throw away any last signals waiting to be processed + } + terminate_thread = false; } void MainUI::GetDirSize(const QString dirname) const { @@ -215,10 +124,201 @@ void MainUI::GetDirSize(const QString dirname) const { emit folder_size_changed(filesize, file_number, dir_number, true); } +void MainUI::SyncFileInfo(){ + qDebug() << "Sync File Info"; + stopDirSize(); + if(INFO->filePath().isEmpty()){ return; } + if(INFO->exists()){ canwrite = INFO->isWritable(); } + else{ + //See if the containing directory can be written + QFileInfo chk(INFO->absolutePath()); + canwrite = (chk.isDir() && chk.isWritable()); + } + ui->label_file_name->setText( INFO->fileName() ); + ui->label_file_mimetype->setText( INFO->mimetype() ); + if(!INFO->isDir()){ ui->label_file_size->setText( LUtils::BytesToDisplaySize( INFO->size() ) ); } + else { + ui->label_file_size->setText(tr("---Calculating---")); + sizeThread = QtConcurrent::run(this, &MainUI::GetDirSize, INFO->absoluteFilePath()); + } + ui->label_file_owner->setText(INFO->owner()); + ui->label_file_group->setText(INFO->group()); + ui->label_file_created->setText( INFO->created().toString(Qt::SystemLocaleLongDate) ); + ui->label_file_modified->setText( INFO->lastModified().toString(Qt::SystemLocaleLongDate) ); + //Get the file permissions + QString perms; + if(INFO->isReadable() && INFO->isWritable()){ perms = tr("Read/Write"); } + else if(INFO->isReadable()){ perms = tr("Read Only"); } + else if(INFO->isWritable()){ perms = tr("Write Only"); } + else{ perms = tr("No Access"); } + ui->label_file_perms->setText(perms); + //Now the special "type" for the file + QString ftype; + if(INFO->suffix().toLower()=="desktop"){ ftype = tr("XDG Shortcut"); } + else if(INFO->isDir()){ ftype = tr("Directory"); } + else if(INFO->isExecutable()){ ftype = tr("Binary"); } + else{ ftype = INFO->suffix().toUpper(); } + if(INFO->isHidden()){ ftype = QString(tr("Hidden %1")).arg(ftype); } + ui->label_file_type->setText(ftype); + + //Now load the icon for the file + if(INFO->isImage()){ + QPixmap pix(INFO->absoluteFilePath()); + ui->label_file_icon->setPixmap(pix.scaledToHeight(64)); + ui->label_file_size->setText( ui->label_file_size->text()+" ("+QString::number(pix.width())+" x "+QString::number(pix.height())+" px)" ); + }else if(INFO->isVideo()){ + ui->label_file_icon->hide(); + LVideoLabel *mediaLabel = new LVideoLabel(INFO->absoluteFilePath(), true, ui->tab_file); + mediaLabel->setFixedSize(64,64); + ui->formLayout->replaceWidget(ui->label_file_icon, mediaLabel); + }else{ + ui->label_file_icon->setPixmap( LXDG::findIcon( INFO->iconfile(), "unknown").pixmap(QSize(64,64)) ); + } + + //qDebug() << "Check XDG Info:" + //qDebug() << INFO->isDesktopFile() << type; + syncXdgStruct(INFO->XDG()); + //Make sure the right tabs are available + if(ui->tabWidget->indexOf(ui->tab_file)<0){ + //qDebug() << "Add File Info Tab"; + ui->tabWidget->insertTab(0, ui->tab_file, tr("File Information")); + } + if(!INFO->isDesktopFile()){ + if(ui->tabWidget->indexOf(ui->tab_deskedit)>=0){ + ui->tabWidget->removeTab( ui->tabWidget->indexOf(ui->tab_deskedit) ); + } + }else if(ui->tabWidget->indexOf(ui->tab_deskedit)<0){ + ui->tabWidget->addTab( ui->tab_deskedit, tr("XDG Shortcut") ); + } + ui->tabWidget->setCurrentIndex(ui->tabWidget->indexOf(ui->tab_file) ); +} + +void MainUI::SetupNewFile(){ + //qDebug() << "Setup New File"; + if(!INFO->filePath().isEmpty()){ + INFO = new LFileInfo(); + } + stopDirSize(); + canwrite = true; //can always write a new file + syncXdgStruct(INFO->XDG()); + //Make sure the right tabs are enabled + if(ui->tabWidget->indexOf(ui->tab_file)>=0){ + ui->tabWidget->removeTab( ui->tabWidget->indexOf(ui->tab_file) ); + } + if(ui->tabWidget->indexOf(ui->tab_deskedit)<0){ + //qDebug() << "Adding the deskedit tab"; + ui->tabWidget->addTab(ui->tab_deskedit, tr("XDG Shortcut")); + } + ui->tabWidget->setCurrentIndex(ui->tabWidget->indexOf(ui->tab_deskedit) ); +} + +void MainUI::syncXdgStruct(XDGDesktop *XDG){ + bool cleanup = false; + if(XDG==0){ XDG = new XDGDesktop(); cleanup = true;} //make sure nothing crashes + if(XDG->type == XDGDesktop::APP){ + ui->line_xdg_command->setText(XDG->exec); + ui->line_xdg_wdir->setText(XDG->path); + ui->check_xdg_useTerminal->setChecked( XDG->useTerminal ); + ui->check_xdg_startupNotify->setChecked( XDG->startupNotify ); + }else if(XDG->type==XDGDesktop::LINK){ + //Hide the options that are unavailable for links + //Command line (exec) + ui->line_xdg_command->setVisible(false); + ui->tool_xdg_getCommand->setVisible(false); + ui->lblCommand->setVisible(false); + //Options + ui->lblOptions->setVisible(false); + ui->check_xdg_useTerminal->setVisible(false); + ui->check_xdg_startupNotify->setVisible(false); + //Now load the variables for this type of shortcut + ui->lblWorkingDir->setText(tr("URL:")); + ui->line_xdg_wdir->setText( XDG->url ); + ui->tool_xdg_getDir->setVisible(false); //the dir selection button + } + ui->line_xdg_name->setText(XDG->name); + ui->line_xdg_comment->setText(XDG->comment); + ui->line_xdg_icon->setText( XDG->icon ); + ReloadAppIcon(); + ui->actionSave_Shortcut->setVisible(true); + ui->actionSave_Shortcut->setEnabled(false); + if(cleanup){ delete XDG; } + checkXDGValidity(); +} + +bool MainUI::saveFile(QString path){ + //qDebug() << "Request save file:" << path; + XDGDesktop *XDG = INFO->XDG(); + if(XDG==0){ XDG = new XDGDesktop(); } + if(XDG->type == XDGDesktop::BAD){ XDG->type = XDGDesktop::APP; } + //Update the file path in the data structure + XDG->filePath = path; + //Now change the structure + XDG->name = ui->line_xdg_name->text(); + XDG->genericName = ui->line_xdg_name->text().toLower(); + XDG->comment = ui->line_xdg_comment->text(); + XDG->icon = ui->line_xdg_icon->text(); + //Now do the type-specific fields + if(XDG->type == XDGDesktop::APP){ + XDG->exec = ui->line_xdg_command->text(); + XDG->tryexec = ui->line_xdg_command->text().section(" ",0,0); //use the first word/binary for the existance check + XDG->path = ui->line_xdg_wdir->text(); //working dir/path + XDG->useTerminal = ui->check_xdg_useTerminal->isChecked(); + XDG->startupNotify = ui->check_xdg_startupNotify->isChecked(); + }else if(XDG->type==XDGDesktop::LINK){ + XDG->url = ui->line_xdg_wdir->text(); //we re-used this field + } + //Clear any info which this utility does not support at the moment + XDG->actionList.clear(); + XDG->actions.clear(); + //Now save the structure to file + //qDebug() << "Saving File:" << XDG->filePath; + return XDG->saveDesktopFile(true); //Try to merge the file/structure as necessary +} + +QString MainUI::findOpenDirFile(bool isdir){ + static QList<QUrl> urls; + if(urls.isEmpty()){ + urls << QUrl::fromLocalFile("/"); + QStringList dirs = QString(getenv("XDG_DATA_DIRS")).split(":"); + for(int i=0; i<dirs.length(); i++){ + if(QFile::exists(dirs[i]+"/applications")){ urls << QUrl::fromLocalFile(dirs[i]+"/applications"); } + } + //Now do the home-directory folders + urls << QUrl::fromLocalFile(QDir::homePath()); + QString localapps = QString(getenv("XDG_DATA_HOME"))+"/applications"; + if(QFile::exists(localapps)){ urls << QUrl::fromLocalFile(localapps); } + } + static QString lastdir = QDir::homePath(); + QFileDialog dlg(this); + dlg.setAcceptMode(QFileDialog::AcceptOpen); + dlg.setFileMode( isdir ? QFileDialog::Directory : QFileDialog::ExistingFiles ); + dlg.setOptions(QFileDialog::ReadOnly | QFileDialog::HideNameFilterDetails); + dlg.setViewMode(QFileDialog::Detail); + dlg.setSidebarUrls( urls ); + dlg.setDirectory(lastdir); + if(!dlg.exec() ){ return ""; } //cancelled + if(dlg.selectedFiles().isEmpty()){ return ""; } + QString path = dlg.selectedFiles().first(); + //Update the last used directory + if(isdir){ lastdir = path; } //save this for next time + else{ lastdir = path.section("/",0,-2); } + //return the path + return path; +} + + // Initialization procedures void MainUI::SetupConnections(){ + connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(closeApplication()) ); + connect(ui->actionSave_Shortcut, SIGNAL(triggered()), this, SLOT(save_clicked()) ); + connect(ui->actionLocal_Shortcut, SIGNAL(triggered()), this, SLOT(save_as_local_clicked()) ); + connect(ui->actionRegister_Shortcut, SIGNAL(triggered()), this, SLOT(save_as_register_clicked()) ); + connect(ui->actionNew_Shortcut, SIGNAL(triggered()), this, SLOT(SetupNewFile()) ); + connect(ui->actionOpen_File, SIGNAL(triggered()), this, SLOT(open_file_clicked()) ); + connect(ui->actionOpen_Directory, SIGNAL(triggered()), this, SLOT(open_dir_clicked()) ); connect(ui->line_xdg_command, SIGNAL(editingFinished()), this, SLOT(xdgvaluechanged()) ); connect(ui->line_xdg_comment, SIGNAL(editingFinished()), this, SLOT(xdgvaluechanged()) ); + connect(ui->line_xdg_icon, SIGNAL(textChanged(QString)), this, SLOT(ReloadAppIcon()) ); connect(ui->tool_xdg_getCommand, SIGNAL(clicked()), this, SLOT(getXdgCommand()) ); connect(ui->line_xdg_name, SIGNAL(editingFinished()), this, SLOT(xdgvaluechanged()) ); connect(ui->line_xdg_wdir, SIGNAL(editingFinished()), this, SLOT(xdgvaluechanged()) ); @@ -228,58 +328,81 @@ void MainUI::SetupConnections(){ } //UI Buttons -void MainUI::on_push_close_clicked(){ +void MainUI::closeApplication(){ terminate_thread = true; - if(ui->push_save->isEnabled()){ + if(ui->actionSave_Shortcut->isEnabled()){ //Still have unsaved changes //TO-DO - prompt for whether to save the changes } this->close(); } -void MainUI::on_push_save_clicked(){ +void MainUI::save_clicked(){ //Save all the xdg values into the structure - if( (!INFO->isDesktopFile() && !INFO->filePath().isEmpty()) || !canwrite){ return; } - if(INFO->filePath().isEmpty()){ + QString filePath = INFO->filePath(); + if( !filePath.isEmpty() && !INFO->isDesktopFile() ){ return; } + if(filePath.isEmpty() || !canwrite){ //Need to prompt for where to save the file and what to call it QString appdir = QString(getenv("XDG_DATA_HOME"))+"/applications/"; if(!QFile::exists(appdir)){ QDir dir; dir.mkpath(appdir); } - QString filePath = QFileDialog::getSaveFileName(this, tr("Save Application File"), appdir, tr("Application Registrations (*.desktop)") ); + filePath = QFileDialog::getSaveFileName(this, tr("Save Application File"), appdir, tr("XDG Shortcuts (*.desktop)") ); if(filePath.isEmpty()){ return; } if(!filePath.endsWith(".desktop")){ filePath.append(".desktop"); } - //Update the file paths in the data structure - INFO->setFile(filePath); - INFO->XDG()->filePath = filePath; } - XDGDesktop *XDG = INFO->XDG(); - //Now change the structure - XDG->name = ui->line_xdg_name->text(); - XDG->genericName = ui->line_xdg_name->text().toLower(); - XDG->comment = ui->line_xdg_comment->text(); - XDG->icon = ui->push_xdg_getIcon->whatsThis(); - //Now do the type-specific fields - if(XDG->type == XDGDesktop::APP){ - XDG->exec = ui->line_xdg_command->text(); - XDG->tryexec = ui->line_xdg_command->text().section(" ",0,0); //use the first word/binary for the existance check - XDG->path = ui->line_xdg_wdir->text(); //working dir/path - XDG->useTerminal = ui->check_xdg_useTerminal->isChecked(); - XDG->startupNotify = ui->check_xdg_startupNotify->isChecked(); - }else if(XDG->type==XDGDesktop::LINK){ - XDG->url = ui->line_xdg_wdir->text(); //we re-used this field + //qDebug() << " -Try Saving File:" << filePath; + bool saved = saveFile(filePath); + //qDebug() << "File Saved:" << saved; + ui->actionSave_Shortcut->setEnabled( !saved ); + if(saved){ + //Re-load the file info + LoadFile(filePath); } - //Clear any info which this utility does not support at the moment - XDG->actionList.clear(); - XDG->actions.clear(); - //Now save the structure to file - bool saved = XDG->saveDesktopFile(true); //Try to merge the file/structure as necessary - qDebug() << "File Saved:" << saved; - ui->push_save->setEnabled( !saved ); +} + +void MainUI::save_as_local_clicked(){ + QString filePath = QFileDialog::getSaveFileName(this, tr("Save Application File"), QDir::homePath(), tr("XDG Shortcuts (*.desktop)") ); + if(filePath.isEmpty()){ return; } + if(!filePath.endsWith(".desktop")){ filePath.append(".desktop"); } + + //qDebug() << " -Try Saving File:" << filePath; + bool saved = saveFile(filePath); + //qDebug() << "File Saved:" << saved; + ui->actionSave_Shortcut->setEnabled( !saved ); if(saved){ //Re-load the file info - LoadFile(INFO->absoluteFilePath()); + LoadFile(filePath); } } +void MainUI::save_as_register_clicked(){ + QString appdir = QString(getenv("XDG_DATA_HOME"))+"/applications/"; + if(!QFile::exists(appdir)){ QDir dir; dir.mkpath(appdir); } + QString filePath = QFileDialog::getSaveFileName(this, tr("Save Application File"), appdir, tr("XDG Shortcuts (*.desktop)") ); + if(filePath.isEmpty()){ return; } + if(!filePath.endsWith(".desktop")){ filePath.append(".desktop"); } + + //qDebug() << " -Try Saving File:" << filePath; + bool saved = saveFile(filePath); + //qDebug() << "File Saved:" << saved; + ui->actionSave_Shortcut->setEnabled( !saved ); + if(saved){ + //Re-load the file info + LoadFile(filePath); + } +} + +void MainUI::open_dir_clicked(){ + QString path = findOpenDirFile(true); //directory only + if(path.isEmpty()){ return; } + LoadFile(path, ""); +} + +void MainUI::open_file_clicked(){ + QString path = findOpenDirFile(false); //files only + if(path.isEmpty()){ return; } + LoadFile(path, ""); +} + void MainUI::getXdgCommand(QString prev){ //Find a binary to run QString dir = prev; //start with the previous attempt (if there was one) @@ -315,22 +438,45 @@ void MainUI::on_push_xdg_getIcon_clicked(){ for(int i=0; i<ext.length(); i++){ ext[i].prepend("*."); } //turn them into valid filters QString file = QFileDialog::getOpenFileName(this, tr("Select an icon"), dir ,QString(tr("Images (%1);; All Files (*)")).arg(ext.join(" ")) ); if(file.isEmpty()){ return; } //cancelled - ui->push_xdg_getIcon->setWhatsThis(file); + ui->line_xdg_icon->setText(file); ReloadAppIcon(); xdgvaluechanged(); } //XDG Value Changed +bool MainUI::checkXDGValidity(){ + XDGDesktop tmp; + tmp.type = XDGDesktop::APP; //make this adjustable later (GUI radio buttons?) + tmp.name = ui->line_xdg_name->text(); + tmp.genericName = ui->line_xdg_name->text().toLower(); + tmp.comment = ui->line_xdg_comment->text(); + tmp.icon = ui->line_xdg_icon->text(); + //Now do the type-specific fields + if(tmp.type == XDGDesktop::APP){ + tmp.exec = ui->line_xdg_command->text(); + tmp.tryexec = ui->line_xdg_command->text().section(" ",0,0); //use the first word/binary for the existance check + tmp.path = ui->line_xdg_wdir->text(); //working dir/path + tmp.useTerminal = ui->check_xdg_useTerminal->isChecked(); + tmp.startupNotify = ui->check_xdg_startupNotify->isChecked(); + }else if(tmp.type==XDGDesktop::LINK){ + tmp.url = ui->line_xdg_wdir->text(); //we re-used this field + } + bool valid = tmp.isValid(); + ui->label_xdg_statusicon->setPixmap( LXDG::findIcon( valid ? "dialog-ok" : "dialog-cancel", "").pixmap(32,32) ); + ui->label_xdg_status->setText( valid ? tr("Valid Settings") : tr("Invalid Settings") ); + return tmp.isValid(); +} + void MainUI::xdgvaluechanged(){ - if(INFO!=0 && (INFO->isDesktopFile() || INFO->filePath().isEmpty() ) ){ - ui->push_save->setVisible(true); + //qDebug() << "xdgvaluechanged"; + if( INFO->isDesktopFile() || INFO->filePath().isEmpty() ){ + bool valid = checkXDGValidity(); //Compare the current UI values to the file values - ui->push_save->setEnabled(canwrite); //assume changed at this point - // TO-DO + ui->menuSave_As->setEnabled(valid); + ui->actionSave_Shortcut->setEnabled(canwrite && valid); //assume changed at this point }else{ - ui->push_save->setVisible(false); - ui->push_save->setEnabled(false); + ui->actionSave_Shortcut->setEnabled(false); } } diff --git a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h index cbe23d9e..d7b17207 100644 --- a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h +++ b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h @@ -13,15 +13,20 @@ #ifndef _LUMINA_FILE_INFO_MAIN_UI_H #define _LUMINA_FILE_INFO_MAIN_UI_H -#include <QDialog> +#include <QMainWindow> +#include <QMediaPlayer> +#include <LVideoSurface.h> +#include <LVideoLabel.h> +#include <QElapsedTimer> +#include <QFuture> #include <LuminaXDG.h> namespace Ui{ - class MainUI; + class MainUI; }; -class MainUI : public QDialog{ +class MainUI : public QMainWindow{ Q_OBJECT public: MainUI(); @@ -31,36 +36,55 @@ public: public slots: void UpdateIcons(); + void ReloadAppIcon(); private: Ui::MainUI *ui; LFileInfo *INFO; + LVideoSurface *surface; + QMediaPlayer *player; + bool flag; + QElapsedTimer timer; + QFuture<void> sizeThread; bool canwrite; bool terminate_thread; //flag for terminating the GetDirSize task - void ReloadAppIcon(); + void stopDirSize(); + void GetDirSize(const QString dirname) const; //function to get folder size + void SyncFileInfo(); + + void syncXdgStruct(XDGDesktop*); + + bool saveFile(QString path); + QString findOpenDirFile(bool isdir = false); + signals: void folder_size_changed(quint64 size, quint64 files, quint64 folders, bool finished) const; //Signal for updating the folder size asynchronously private slots: + void SetupNewFile(); //Initialization functions void SetupConnections(); //UI Buttons - void on_push_close_clicked(); - void on_push_save_clicked(); + void closeApplication(); + void save_clicked(); + void save_as_local_clicked(); + void save_as_register_clicked(); + void open_dir_clicked(); + void open_file_clicked(); void getXdgCommand(QString prev = ""); - //void on_tool_xdg_getCommand_clicked(QString prev = ""); void on_tool_xdg_getDir_clicked(); void on_push_xdg_getIcon_clicked(); //XDG Value Changed + bool checkXDGValidity(); void xdgvaluechanged(); - //Folder size - void refresh_folder_size(quint64 size, quint64 files, quint64 folders, bool finished); //Slot for updating the folder size asynchronously + //Folder size + void refresh_folder_size(quint64 size, quint64 files, quint64 folders, bool finished); //Slot for updating the folder size asynchronously }; #endif diff --git a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.ui b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.ui index 51657ba1..217c1a10 100644 --- a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.ui +++ b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.ui @@ -1,432 +1,652 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainUI</class> - <widget class="QDialog" name="MainUI"> + <widget class="QMainWindow" name="MainUI"> <property name="geometry"> <rect> <x>0</x> <y>0</y> - <width>349</width> - <height>354</height> + <width>800</width> + <height>658</height> </rect> </property> <property name="windowTitle"> <string>File Information</string> </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QTabWidget" name="tabWidget"> - <property name="currentIndex"> - <number>1</number> - </property> - <widget class="QWidget" name="tab_file"> - <attribute name="title"> - <string>File Information</string> - </attribute> - <layout class="QFormLayout" name="formLayout"> - <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - <item row="0" column="0"> - <widget class="QLabel" name="label_file_icon"> - <property name="text"> - <string notr="true">icon</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item row="4" column="0" colspan="2"> - <widget class="Line" name="line_2"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item row="5" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Owner:</string> - </property> - </widget> - </item> - <item row="5" column="1"> - <widget class="QLabel" name="label_file_owner"> - <property name="text"> - <string notr="true"/> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="6" column="0"> - <widget class="QLabel" name="label_3"> - <property name="text"> - <string>Group:</string> - </property> - </widget> - </item> - <item row="6" column="1"> - <widget class="QLabel" name="label_file_group"> - <property name="text"> - <string notr="true"/> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="7" column="0"> - <widget class="QLabel" name="label_11"> - <property name="text"> - <string>Permissions:</string> - </property> - </widget> - </item> - <item row="10" column="0" colspan="2"> - <widget class="Line" name="line_3"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item row="11" column="0"> - <widget class="QLabel" name="label_7"> - <property name="text"> - <string>Created:</string> - </property> - </widget> - </item> - <item row="11" column="1"> - <widget class="QLabel" name="label_file_created"> - <property name="toolTip"> - <string>Note: The time a file was created might be more recent than the time modified if the file permissions were changed recently.</string> - </property> - <property name="text"> - <string notr="true"/> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="12" column="0"> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>Last Modified:</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_5"> - <property name="text"> - <string>Type:</string> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="label_6"> - <property name="text"> - <string>MimeType:</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLabel" name="label_file_mimetype"> - <property name="text"> - <string notr="true"/> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLabel" name="label_file_type"> - <property name="text"> - <string notr="true"/> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="7" column="1"> - <widget class="QLabel" name="label_file_perms"> - <property name="text"> - <string notr="true"/> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="12" column="1"> - <widget class="QLabel" name="label_file_modified"> - <property name="text"> - <string notr="true"/> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="3" column="0"> - <widget class="QLabel" name="label_4"> - <property name="text"> - <string>File Size:</string> - </property> - </widget> - </item> - <item row="3" column="1"> - <widget class="QLabel" name="label_file_size"> - <property name="text"> - <string notr="true"/> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLabel" name="label_file_name"> - <property name="text"> - <string notr="true"/> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="tab_deskedit"> - <attribute name="title"> - <string>Edit Shortcut</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <property name="spacing"> - <number>2</number> - </property> - <property name="leftMargin"> - <number>4</number> - </property> - <property name="topMargin"> - <number>4</number> - </property> - <property name="rightMargin"> - <number>4</number> - </property> - <property name="bottomMargin"> - <number>4</number> - </property> - <item> - <layout class="QGridLayout" name="gridLayout"> - <item row="3" column="0" alignment="Qt::AlignRight"> - <widget class="QLabel" name="lblWorkingDir"> - <property name="text"> - <string>Working Dir:</string> - </property> - </widget> - </item> - <item row="5" column="1"> - <widget class="QCheckBox" name="check_xdg_startupNotify"> - <property name="text"> - <string>Use startup notification</string> - </property> - </widget> - </item> - <item row="3" column="1"> - <widget class="QLineEdit" name="line_xdg_wdir"> - <property name="enabled"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="4" column="0" alignment="Qt::AlignRight"> - <widget class="QLabel" name="lblIcon"> - <property name="text"> - <string>Icon:</string> - </property> - </widget> - </item> - <item row="2" column="0" alignment="Qt::AlignRight"> - <widget class="QLabel" name="lblCommand"> - <property name="text"> - <string>Command:</string> - </property> - </widget> - </item> - <item row="1" column="0" alignment="Qt::AlignRight"> - <widget class="QLabel" name="lblComment"> - <property name="text"> - <string>Comment:</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLineEdit" name="line_xdg_command"/> - </item> - <item row="6" column="1"> - <widget class="QCheckBox" name="check_xdg_useTerminal"> - <property name="text"> - <string>Run in terminal</string> - </property> - </widget> - </item> - <item row="0" column="0" alignment="Qt::AlignRight"> - <widget class="QLabel" name="lblName"> - <property name="text"> - <string>Name:</string> - </property> - </widget> - </item> - <item row="5" column="0" alignment="Qt::AlignRight"> - <widget class="QLabel" name="lblOptions"> - <property name="text"> - <string>Options</string> - </property> - </widget> - </item> - <item row="0" column="1" colspan="2"> - <widget class="QLineEdit" name="line_xdg_name"/> - </item> - <item row="1" column="1" colspan="2"> - <widget class="QLineEdit" name="line_xdg_comment"/> - </item> - <item row="2" column="2"> - <widget class="QToolButton" name="tool_xdg_getCommand"> - <property name="text"> - <string notr="true"/> - </property> - </widget> - </item> - <item row="3" column="2"> - <widget class="QToolButton" name="tool_xdg_getDir"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="text"> - <string notr="true"/> - </property> - </widget> - </item> - <item row="4" column="1"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QToolButton" name="push_xdg_getIcon"> - <property name="maximumSize"> - <size> - <width>275</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>No Icon</string> - </property> - <property name="iconSize"> - <size> - <width>64</width> - <height>64</height> - </size> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - </layout> - </item> - <item> - <widget class="Line" name="line"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QToolButton" name="push_save"> - <property name="text"> - <string>Save</string> - </property> - <property name="popupMode"> - <enum>QToolButton::InstantPopup</enum> - </property> - <property name="toolButtonStyle"> - <enum>Qt::ToolButtonTextBesideIcon</enum> - </property> + <property name="windowIcon"> + <iconset theme="document-search"> + <normaloff>.</normaloff>.</iconset> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTabWidget" name="tabWidget"> + <property name="currentIndex"> + <number>1</number> + </property> + <widget class="QWidget" name="tab_file"> + <attribute name="title"> + <string>File Information</string> + </attribute> + <layout class="QFormLayout" name="formLayout"> + <property name="labelAlignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="label_file_icon"> + <property name="text"> + <string notr="true">icon</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="4" column="0" colspan="2"> + <widget class="Line" name="line_2"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Owner:</string> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QLabel" name="label_file_owner"> + <property name="text"> + <string notr="true"/> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Group:</string> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QLabel" name="label_file_group"> + <property name="text"> + <string notr="true"/> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="7" column="0"> + <widget class="QLabel" name="label_11"> + <property name="text"> + <string>Permissions:</string> + </property> + </widget> + </item> + <item row="10" column="0" colspan="2"> + <widget class="Line" name="line_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="11" column="0"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>Created:</string> + </property> + </widget> + </item> + <item row="11" column="1"> + <widget class="QLabel" name="label_file_created"> + <property name="toolTip"> + <string>Note: The time a file was created might be more recent than the time modified if the file permissions were changed recently.</string> + </property> + <property name="text"> + <string notr="true"/> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="12" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Last Modified:</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>Type:</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>MimeType:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="label_file_mimetype"> + <property name="text"> + <string notr="true"/> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="label_file_type"> + <property name="text"> + <string notr="true"/> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="7" column="1"> + <widget class="QLabel" name="label_file_perms"> + <property name="text"> + <string notr="true"/> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="12" column="1"> + <widget class="QLabel" name="label_file_modified"> + <property name="text"> + <string notr="true"/> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>File Size:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLabel" name="label_file_size"> + <property name="text"> + <string notr="true"/> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="label_file_name"> + <property name="text"> + <string notr="true"/> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + </layout> </widget> - </item> - <item> - <widget class="QToolButton" name="push_close"> - <property name="text"> - <string>Close</string> - </property> - <property name="popupMode"> - <enum>QToolButton::DelayedPopup</enum> - </property> - <property name="toolButtonStyle"> - <enum>Qt::ToolButtonTextBesideIcon</enum> - </property> + <widget class="QWidget" name="tab_deskedit"> + <attribute name="title"> + <string>XDG Shortcut</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="spacing"> + <number>2</number> + </property> + <property name="leftMargin"> + <number>4</number> + </property> + <property name="topMargin"> + <number>4</number> + </property> + <property name="rightMargin"> + <number>4</number> + </property> + <property name="bottomMargin"> + <number>4</number> + </property> + <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="3" column="0" alignment="Qt::AlignRight"> + <widget class="QLabel" name="lblWorkingDir"> + <property name="text"> + <string>Working Dir:</string> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QCheckBox" name="check_xdg_startupNotify"> + <property name="text"> + <string>Use startup notification</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLineEdit" name="line_xdg_wdir"> + <property name="enabled"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="4" column="0" alignment="Qt::AlignRight"> + <widget class="QLabel" name="lblIcon"> + <property name="text"> + <string>Icon:</string> + </property> + </widget> + </item> + <item row="2" column="0" alignment="Qt::AlignRight"> + <widget class="QLabel" name="lblCommand"> + <property name="text"> + <string>Command:</string> + </property> + </widget> + </item> + <item row="1" column="0" alignment="Qt::AlignRight"> + <widget class="QLabel" name="lblComment"> + <property name="text"> + <string>Comment:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="line_xdg_command"/> + </item> + <item row="6" column="1"> + <widget class="QCheckBox" name="check_xdg_useTerminal"> + <property name="text"> + <string>Run in terminal</string> + </property> + </widget> + </item> + <item row="0" column="0" alignment="Qt::AlignRight"> + <widget class="QLabel" name="lblName"> + <property name="text"> + <string>Name:</string> + </property> + </widget> + </item> + <item row="5" column="0" alignment="Qt::AlignRight"> + <widget class="QLabel" name="lblOptions"> + <property name="text"> + <string>Options</string> + </property> + </widget> + </item> + <item row="0" column="1" colspan="2"> + <widget class="QLineEdit" name="line_xdg_name"/> + </item> + <item row="1" column="1" colspan="2"> + <widget class="QLineEdit" name="line_xdg_comment"/> + </item> + <item row="2" column="2"> + <widget class="QToolButton" name="tool_xdg_getCommand"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>42</height> + </size> + </property> + <property name="text"> + <string notr="true"/> + </property> + <property name="icon"> + <iconset theme="edit-find"> + <normaloff>.</normaloff>.</iconset> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QToolButton" name="tool_xdg_getDir"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>42</height> + </size> + </property> + <property name="text"> + <string notr="true"/> + </property> + <property name="icon"> + <iconset theme="edit-find"> + <normaloff>.</normaloff>.</iconset> + </property> + </widget> + </item> + <item row="4" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label_xdg_icon"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>64</width> + <height>64</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>64</width> + <height>64</height> + </size> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="text"> + <string notr="true"/> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="line_xdg_icon"/> + </item> + </layout> + </item> + <item row="4" column="2"> + <widget class="QToolButton" name="push_xdg_getIcon"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>20000</width> + <height>42</height> + </size> + </property> + <property name="sizeIncrement"> + <size> + <width>2</width> + <height>2</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string notr="true"/> + </property> + <property name="icon"> + <iconset theme="edit-find"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="iconSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="label_xdg_statusicon"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="text"> + <string notr="true"/> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_xdg_status"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>32</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>32</height> + </size> + </property> + <property name="font"> + <font> + <italic>true</italic> + </font> + </property> + <property name="text"> + <string notr="true"/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + </layout> </widget> - </item> - </layout> - </item> - </layout> + </widget> + </item> + </layout> + </widget> + <widget class="QMenuBar" name="menubar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>39</height> + </rect> + </property> + <widget class="QMenu" name="menuFile"> + <property name="title"> + <string>File</string> + </property> + <widget class="QMenu" name="menuSave_As"> + <property name="title"> + <string>Save As</string> + </property> + <property name="icon"> + <iconset theme="document-save"> + <normaloff>.</normaloff>.</iconset> + </property> + <addaction name="actionLocal_Shortcut"/> + <addaction name="actionRegister_Shortcut"/> + </widget> + <addaction name="actionNew_Shortcut"/> + <addaction name="separator"/> + <addaction name="actionOpen_File"/> + <addaction name="actionOpen_Directory"/> + <addaction name="separator"/> + <addaction name="actionSave_Shortcut"/> + <addaction name="menuSave_As"/> + <addaction name="separator"/> + <addaction name="actionQuit"/> + </widget> + <addaction name="menuFile"/> + </widget> + <widget class="QStatusBar" name="statusbar"/> + <action name="actionOpen_File"> + <property name="icon"> + <iconset theme="document-open"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Open File</string> + </property> + <property name="shortcut"> + <string>Ctrl+O</string> + </property> + <property name="shortcutContext"> + <enum>Qt::ApplicationShortcut</enum> + </property> + </action> + <action name="actionQuit"> + <property name="icon"> + <iconset theme="window-close"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Quit</string> + </property> + <property name="shortcut"> + <string>Ctrl+Q</string> + </property> + <property name="shortcutContext"> + <enum>Qt::ApplicationShortcut</enum> + </property> + </action> + <action name="actionSave_Shortcut"> + <property name="icon"> + <iconset theme="document-save"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Save Shortcut</string> + </property> + <property name="shortcut"> + <string>Ctrl+S</string> + </property> + <property name="shortcutContext"> + <enum>Qt::ApplicationShortcut</enum> + </property> + </action> + <action name="actionLocal_Shortcut"> + <property name="icon"> + <iconset theme="document-new"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Local Shortcut</string> + </property> + </action> + <action name="actionRegister_Shortcut"> + <property name="icon"> + <iconset theme="bookmark-new"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Register Shortcut</string> + </property> + </action> + <action name="actionOpen_Directory"> + <property name="icon"> + <iconset theme="folder-open"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Open Directory</string> + </property> + </action> + <action name="actionNew_Shortcut"> + <property name="icon"> + <iconset theme="document-new"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>New Shortcut</string> + </property> + </action> </widget> - <layoutdefault spacing="6" margin="11"/> - <tabstops> - <tabstop>line_xdg_name</tabstop> - <tabstop>line_xdg_comment</tabstop> - <tabstop>line_xdg_command</tabstop> - <tabstop>line_xdg_wdir</tabstop> - <tabstop>check_xdg_startupNotify</tabstop> - <tabstop>check_xdg_useTerminal</tabstop> - <tabstop>tool_xdg_getCommand</tabstop> - <tabstop>tool_xdg_getDir</tabstop> - </tabstops> <resources/> <connections/> </ui> diff --git a/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro b/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro index bbaf842e..14345f50 100644 --- a/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro +++ b/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro @@ -1,7 +1,7 @@ include("$${PWD}/../../OS-detect.pri") QT += core gui -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets concurrent +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets concurrent multimedia TARGET = lumina-fileinfo @@ -13,6 +13,7 @@ target.path = $${L_BINDIR} include(../../core/libLumina/LUtils.pri) #includes LUtils include(../../core/libLumina/LuminaXDG.pri) #include(../../core/libLumina/LuminaSingleApplication.pri) +include(../../core/libLumina/LVideoLabel.pri) include(../../core/libLumina/LuminaThemes.pri) SOURCES += main.cpp\ diff --git a/src-qt5/desktop-utils/lumina-fileinfo/main.cpp b/src-qt5/desktop-utils/lumina-fileinfo/main.cpp index a602f290..ce62399d 100644 --- a/src-qt5/desktop-utils/lumina-fileinfo/main.cpp +++ b/src-qt5/desktop-utils/lumina-fileinfo/main.cpp @@ -11,46 +11,26 @@ int main(int argc, char ** argv) { LTHEME::LoadCustomEnvSettings(); QApplication a(argc, argv); - a.setAttribute(Qt::AA_UseHighDpiPixmaps); + a.setAttribute(Qt::AA_UseHighDpiPixmaps); LUtils::LoadTranslation(&a, "l-fileinfo"); - //LuminaThemeEngine theme(&a); //Read the input variables QString path = ""; QString flag = ""; for(int i=1; i<argc; i++){ - if( QString(argv[i]).startsWith("-") ){ flag = QString(argv[i]); } - else{ path = QString(argv[i]); break; } + QString tmp(argv[i]); + if( tmp=="--new-application" ){ flag = "APP"; } + else if( tmp=="--new-link" ){ flag = "LINK"; } + else if(!tmp.startsWith("-")){ path = QString(argv[i]); break; } } //Check the input variables // - path if(!path.isEmpty()){ path = LUtils::PathToAbsolute(path); } - // - flag - if(!flag.isEmpty()){ - if(flag=="-application"){ - flag = "APP"; //for internal use - }else if(flag=="-link"){ - flag = "LINK"; //for internal use - }else{ - //Invalid flag - clear the path as well - flag.clear(); - path.clear(); - } - } - if(!path.isEmpty() || !flag.isEmpty()){ + if(path.isEmpty() && flag.isEmpty()){ flag = "APP"; } MainUI w; - //QObject::connect(&theme, SIGNAL(updateIcons()), &w, SLOT(UpdateIcons()) ); w.LoadFile(path, flag); w.show(); int retCode = a.exec(); return retCode; - }else{ - //Show an error text and exit - qDebug() << "ERROR: Invalid input arguments"; - qDebug() << "Usage: \"lumina-fileinfo [-application | -link] [file]"; - return 1; - } - - } diff --git a/src-qt5/desktop-utils/lumina-fm-dev/main.cpp b/src-qt5/desktop-utils/lumina-fm-dev/main.cpp index 61d2dc95..a4a6244e 100644 --- a/src-qt5/desktop-utils/lumina-fm-dev/main.cpp +++ b/src-qt5/desktop-utils/lumina-fm-dev/main.cpp @@ -2,6 +2,7 @@ #include <QDebug> #include <QFile> #include <QStringList> +#include <QElapsedTimer> #include "MainUI.h" #include <LuminaOS.h> @@ -10,6 +11,7 @@ #include <LuminaSingleApplication.h> #include "BrowserWidget.h" +QElapsedTimer* timer = 0; int main(int argc, char ** argv) { @@ -27,6 +29,7 @@ int main(int argc, char ** argv) MainUI w; QObject::connect(&a, SIGNAL(InputsAvailable(QStringList)), &w, SLOT(slotSingleInstance(QStringList)) ); //QObject::connect(&themes, SIGNAL(updateIcons()), &w, SLOT(setupIcons()) ); + timer = new QElapsedTimer(); timer->start(); qDebug() << " - Init:" << timer->elapsed(); w.OpenDirs(in); w.show(); diff --git a/src-qt5/desktop-utils/lumina-fm-dev/widgets/DirWidget2.cpp b/src-qt5/desktop-utils/lumina-fm-dev/widgets/DirWidget2.cpp index 3790d145..2e837cfd 100644 --- a/src-qt5/desktop-utils/lumina-fm-dev/widgets/DirWidget2.cpp +++ b/src-qt5/desktop-utils/lumina-fm-dev/widgets/DirWidget2.cpp @@ -28,6 +28,8 @@ #define DEBUG 0 +extern QElapsedTimer* timer; + DirWidget::DirWidget(QString objID, QWidget *parent) : QWidget(parent), ui(new Ui::DirWidget){ ui->setupUi(this); //load the designer file ID = objID; @@ -90,6 +92,8 @@ DirWidget::DirWidget(QString objID, QWidget *parent) : QWidget(parent), ui(new U createShortcuts(); createMenus(); line_dir->setCompleter(new QCompleter(dirtreeModel, this)); + qDebug() << " - Fini:" << timer->elapsed(); + } DirWidget::~DirWidget(){ diff --git a/src-qt5/desktop-utils/lumina-fm/Browser.cpp b/src-qt5/desktop-utils/lumina-fm/Browser.cpp index f2bdc178..29cc5a99 100644 --- a/src-qt5/desktop-utils/lumina-fm/Browser.cpp +++ b/src-qt5/desktop-utils/lumina-fm/Browser.cpp @@ -16,10 +16,12 @@ Browser::Browser(QObject *parent) : QObject(parent){ watcher = new QFileSystemWatcher(this); connect(watcher, SIGNAL(fileChanged(const QString&)), this, SLOT(fileChanged(QString)) ); - connect(watcher, SIGNAL(directoryChanged(const QString&)), this, SLOT(dirChanged(QString)) ); + connect(watcher, SIGNAL(directoryChanged(const QString&)), this, SLOT(dirChanged(QString)) ); showHidden = false; showThumbs = false; imageFormats = LUtils::imageExtensions(false); //lowercase suffixes + //connect(surface, SIGNAL(frameReceived(QImage)), this, SLOT(captureFrame(QImage))); + //connect(player, &QMediaPlayer::mediaStatusChanged, this, [&]{ stopVideo(player, player->mediaStatus()); }); connect(this, SIGNAL(threadDone(QString, QImage)), this, SLOT(futureFinished(QString, QImage))); //will always be between different threads } @@ -32,6 +34,7 @@ QString Browser::currentDirectory(){ return currentDir; } void Browser::showHiddenFiles(bool show){ if(show !=showHidden){ showHidden = show; + lastcheck = QDateTime(); //reset this timestamp - need to reload all if(!currentDir.isEmpty()){ QTimer::singleShot(0, this, SLOT(loadDirectory()) ); } } } @@ -42,6 +45,7 @@ bool Browser::showingHiddenFiles(){ void Browser::showThumbnails(bool show){ if(show != showThumbs){ showThumbs = show; + lastcheck = QDateTime(); //reset this timestamp - need to reload all if(!currentDir.isEmpty()){ QTimer::singleShot(0, this, SLOT(loadDirectory()) ); } } } @@ -60,69 +64,83 @@ void Browser::loadItem(QString info, Browser *obj){ file.close(); pix.loadFromData(bytes); if(pix.width() > 256 || pix.height() > 256 ){ - pix = pix.scaled(256,256, Qt::KeepAspectRatio, Qt::SmoothTransformation); + pix = pix.scaled(256,256, Qt::KeepAspectRatio, Qt::FastTransformation); } } } - //qDebug() << " - done with item:" << info; obj->emit threadDone(info, pix); } -QIcon Browser::loadIcon(QString icon){ +QIcon* Browser::loadIcon(QString icon){ if(!mimeIcons.contains(icon)){ mimeIcons.insert(icon, LXDG::findIcon(icon, "unknown")); } - - return mimeIcons[icon]; + return &mimeIcons[icon]; } // PRIVATE SLOTS void Browser::fileChanged(QString file){ - if(file.startsWith(currentDir+"/") ){ + //qDebug() << "Got File Changed:" << file; + if(file.section("/",0,-2) == currentDir){ if(QFile::exists(file) ){ QtConcurrent::run(this, &Browser::loadItem, file, this); } //file modified but not removed - else{ QTimer::singleShot(0, this, SLOT(loadDirectory()) ); } //file removed - need to update entire dir - }else if(file==currentDir){ QTimer::singleShot(0, this, SLOT(loadDirectory()) ); } + else if(oldFiles.contains(file) ){ + oldFiles.removeAll(file); + emit itemRemoved(file); + } + }//else if(file==currentDir){ QTimer::singleShot(0, this, SLOT(loadDirectory()) ); } } void Browser::dirChanged(QString dir){ - - if(dir==currentDir){ QTimer::singleShot(500, this, SLOT(loadDirectory()) ); } + //qDebug() << "Got Dir Changed:" << dir; + if(dir==currentDir){ QTimer::singleShot(10, this, SLOT(loadDirectory()) ); } else if(dir.startsWith(currentDir)){ QtConcurrent::run(this, &Browser::loadItem, dir, this ); } } void Browser::futureFinished(QString name, QImage icon){ //Note: this will be called once for every item that loads - QIcon ico; - //LFileInfo info(name); - LFileInfo *info = new LFileInfo(name); - if(!icon.isNull() && showThumbs){ - //qDebug() << " -- Data:"; - QPixmap pix = QPixmap::fromImage(icon); - ico.addPixmap(pix); - //}else if(info->isDir()){ - //qDebug() << " -- Folder:"; - //ico = loadIcon("folder"); - } - if(ico.isNull()){ - //qDebug() << " -- MimeType:" << info.fileName() << info.mimetype(); - ico = loadIcon(info->iconfile()); - } - this->emit itemDataAvailable( ico, info); - //qDebug() << " -- done:" << name; + //Haven't added the extra files in a directory fix, but that should be easy to do + //Try to load a file with multiple videos and lots of other stuff before any other directory. It crashes for some reason + //qDebug() << name << "here"; + QIcon *ico = new QIcon(); + LFileInfo *info = new LFileInfo(name); + if(!icon.isNull() && showThumbs){ + QPixmap pix = QPixmap::fromImage(icon); + ico->addPixmap(pix); + /*}else if(info->isVideo() && showThumbs) { + if(videoImages.find(name) == videoImages.end()) { + LVideoLabel *mediaLabel = new LVideoLabel(name); + while(mediaLabel->pixmap()->isNull()) { QCoreApplication::processEvents(QEventLoop::AllEvents, 50); } + ico->addPixmap(*(mediaLabel->pixmap())); + videoImages.insert(name, *mediaLabel->pixmap()); + delete mediaLabel; + }else{ + ico->addPixmap(videoImages[name]); + }*/ + }else{ + ico = loadIcon(info->iconfile()); + } + this->emit itemDataAvailable( *ico, info); + //qDebug() << " -- done:" << name; } // PUBLIC SLOTS -void Browser::loadDirectory(QString dir){ +void Browser::loadDirectory(QString dir, bool force){ + if(force){ lastcheck = QDateTime(); } //reset check time to force reloads if(dir.isEmpty()){ dir = currentDir; } //reload current directory if(dir.isEmpty()){ return; } //nothing to do - nothing previously loaded //qDebug() << "Load Directory" << dir; + bool dirupdate = true; if(currentDir != dir){ //let the main widget know to clear all current items (completely different dir) + //videoImages.clear(); oldFiles.clear(); + lastcheck = QDateTime(); //null time emit clearItems(); + dirupdate = false; } currentDir = dir; //save this for later + QDateTime now = QDateTime::currentDateTime(); //clean up the watcher first QStringList watched; watched << watcher->files() << watcher->directories(); if(!watched.isEmpty()){ watcher->removePaths(watched); } @@ -134,15 +152,18 @@ void Browser::loadDirectory(QString dir){ QStringList files; if(showHidden){ files = directory.entryList( QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot, QDir::NoSort); } else{ files = directory.entryList( QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot, QDir::NoSort); } - emit itemsLoading(files.length()); + if(dirupdate){ emit itemsLoading(files.length()); } for(int i=0; i<files.length(); i++){ watcher->addPath(directory.absoluteFilePath(files[i])); - //qDebug() << "Future Starting:" << files[i]; QString path = directory.absoluteFilePath(files[i]); - if(old.contains(path)){ old.removeAll(path); } oldFiles << path; //add to list for next time + bool reloaditem = !dirupdate || lastcheck.isNull() || (QFileInfo(path).lastModified() > lastcheck || QFileInfo(path).created() > lastcheck); + //if(dirupdate){ qDebug() << "Reload Item:" << reloaditem << path.section("/",-1); } + //reloaditem = true; + if(old.contains(path)){ old.removeAll(path); } //still in existance //if(showThumbs && imageFormats.contains(path.section(".",-1).toLower())){ - QtConcurrent::run(this, &Browser::loadItem, path, this); + //qDebug() << "Future Starting:" << files[i]; + if(reloaditem){ QtConcurrent::run(this, &Browser::loadItem, path, this); } /*}else{ //No special icon loading - just skip the file read step futureFinished(path, QImage()); //loadItem(path, this); @@ -158,4 +179,5 @@ void Browser::loadDirectory(QString dir){ }else{ emit itemsLoading(0); //nothing to load } + lastcheck = now; // save this for later } diff --git a/src-qt5/desktop-utils/lumina-fm/Browser.h b/src-qt5/desktop-utils/lumina-fm/Browser.h index 94f6ba3f..0f4a0abe 100644 --- a/src-qt5/desktop-utils/lumina-fm/Browser.h +++ b/src-qt5/desktop-utils/lumina-fm/Browser.h @@ -15,6 +15,9 @@ #include <QIcon> //#include <QFutureWatcher> +#include <QMediaPlayer> +#include <LVideoSurface.h> +#include <LVideoLabel.h> #include <LuminaXDG.h> /*class FileItem{ public: @@ -42,22 +45,23 @@ public: private: QString currentDir; + QDateTime lastcheck; QFileSystemWatcher *watcher; + QMap<QString, QPixmap> videoImages; bool showHidden, showThumbs; - QStringList imageFormats, oldFiles; + QStringList imageFormats, videoFormats, oldFiles; QHash<QString, QIcon> mimeIcons; //cache for quickly re-using QIcons void loadItem(QString info, Browser *obj); //this is the main loader class - multiple instances each run in a separate thread - QIcon loadIcon(QString icon); //simplification for using/populating the mimIcons cache + QIcon* loadIcon(QString icon); //simplification for using/populating the mimIcons cache private slots: void fileChanged(QString); //tied into the watcher - for file change notifications void dirChanged(QString); // tied into the watcher - for new/removed files in the current dir - void futureFinished(QString, QImage); public slots: - void loadDirectory(QString dir = ""); + void loadDirectory(QString dir = "", bool force = false); signals: //Main Signals diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserModel.cpp b/src-qt5/desktop-utils/lumina-fm/BrowserModel.cpp new file mode 100644 index 00000000..d79da006 --- /dev/null +++ b/src-qt5/desktop-utils/lumina-fm/BrowserModel.cpp @@ -0,0 +1,208 @@ +//=========================================== +// Lumina Desktop source code +// Copyright (c) 2017, Ken Moore & JT Pennington +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "BrowserModel.h" + +BrowserModel::BrowserModel(QObject *parent){ + +} + +BrowserModel::~BrowserModel(){ + +} + +//Virtual overrides +QModelIndex BrowserModel::index(int row, int column, const QModelIndex &parent) const{ + +} + +QModelIndex BrowserModel::parent(const QModelIndex &index) const{ + +} + +// item management +int BrowserModel::rowCount(const QModelIndex &parent) const{ + +} + +bool BrowserModel::insertRows(int row, int count, const QModelIndex &parent){ + +} + +bool BrowserModel::removeRow(int row, const QModelIndex &parent){ + +} + +bool BrowserModel::removeRows(int row, int count, const QModelIndex &parent){ + +} + +int BrowserModel::columnCount(const QModelIndex &parent) const{ + +} + +bool BrowserModel::insertColumns(int column, int count, const QModelIndex &parent){ + +} + +bool BrowserModel::removeColumn(int column, const QModelIndex &parent){ + +} + +bool BrowserModel::removeColumns(int column, int count, const QModelIndex &parent){ + +} + + +//bool BrowserModel::hasChildren(const QModelIndex &parent) const{ + +} + + +// data functions +Qt::ItemFlags BrowserModel::flags(const QModelIndex &index) const{ + +} + +QVariant BrowserModel::data(const QModelIndex &index, int role) const{ + QFileInfo *info = indexToInfo(index); + switch(role){ + case Qt::DisplayRole: + if(index.column()==0){ return QVariant(info->fileName()); } + else if(index.column()==1){ return QVariant(info->fileSize()); } + else if(index.column()==2){ return QVariant(info->mimetype()); } + else if(index.column()==3){ return QVariant(info->lastModified()->toString(Qt::DefaultLocaleShortDate)); } + else if(index.column()==4){ return QVariant(info->created()->toString(Qt::DefaultLocaleShortDate)); } + case Qt::ToolTipRole: + return QVariant(info->absoluteFilePath()); + case Qt::StatusTipRole: + return QVariant(info->absoluteFilePath()); + case Qt::SizeHintRole; + return QVariant(QSize(100,14)); + case Qt::DecorationRole: + return QVariant(LXDG::findIcon(info->iconFile(), "unknown")); + } + return QVariant(); +} + +QVariant BrowserModel::headerData(int section, Qt::Orientation orientation, int role) const{ + if(role == Qt::DisplayRole){ + if(orientation == Qt::Horizontal){ + switch(section){ + case 0: + return QVariant(tr("File Name")); + case 1: + return QVariant("Size"); + case 2: + return QVariant("Type"); + case 3: + return QVariant("Date Modified"); + case 4: + return QVariant("Date Created"); + } + } + } + case Qt::DisplayRole: + return QVariant(tr("File Name"); + /*case Qt::ToolTipRole: + return QVariant("ToolTip"); + case Qt::StatusTipRole: + return QVariant("Status Tip"); + case Qt::SizeHintRole; + return QVariant(QSize(100,14));*/ + case Qt::DecorationRole: + return QVariant("Icon")); + } + return QVariant(); +} + +// data modification functions +bool BrowserModel::setData(const QModelIndex &index, const QVariant &value, int role){ + +} + +bool BrowserModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role){ + +} + + +// drag and drop +//QMimeData* BrowserModel::mimeData(const QModelIndexList &indexes) const{ + +} + +//QStringList BrowserModel::mimeTypes() const{ + +} + +//bool BrowserModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles){ + +} + +//Qt::DropActions BrowserModel::supportedDropActions() const{ + +} + +//bool BrowserModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent){ + +} + +//Special Functions (non virtual replacements) +LFileInfo* BrowserModel::fileInfo(QString name){ + +} + +QString BrowserModel::currentDirectory(){ + return cDir; +} + + +// ============== +// PUBLIC SLOTS +// ============== +void BrowserModel::loadDirectory(QString dir){ + + +} + +void BrowserModel::loadItem(QString itempath){ + LFileInfo *it = new LFileInfo(itempath); + //Determine the row/column that it needs to be + int row, column; + row = 0; + //Now create the index + for(int i=0; i<5; i++){ + QModelIndex index = createIndex(row, i, it); + } +} + + +// ============= +// PRIVATE +// ============= +/*QString BrowserModel::findInHash(QString path){ + QStringList keys = HASH.keys(); + for(int i=0; i<keys.length(); i++){ + if(HASH[keys[i]]->filePath() == path){ return keys[i]; } + } + return ""; +} + +QString BrowserModel::findInHash(QModelIndex index){ + QString id = QString::number(index.row())+"/"+QString::number(index.column()); + if(HASH.contains(id)){ return id; } + return ""; +} + +LFileInfo* BrowserModel::indexToInfo(QString path){ + QString id = findInHash(path); + if(id.isEmpty()){ return 0;} + return HASH[id]; +}*/ + +LFileInfo* BrowserModel::indexToInfo(QModelIndex index){ + return static_cast<LFileInfo*>(index.internalPointer()); +} diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserModel.h b/src-qt5/desktop-utils/lumina-fm/BrowserModel.h new file mode 100644 index 00000000..b30e117e --- /dev/null +++ b/src-qt5/desktop-utils/lumina-fm/BrowserModel.h @@ -0,0 +1,87 @@ +//=========================================== +// Lumina Desktop source code +// Copyright (c) 2017, Ken Moore & JT Pennington +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +// This is the main browsing backend for the file manager +//=========================================== +#ifndef _LUMINA_FM_BROWSER_MODEL_BACKEND_H +#define _LUMINA_FM_BROWSER_MODEL_BACKEND_H + +#include <QAbstractItemModel> +#include <QModelIndex> +#include <QMimeData> +#include <QMap> +#include <QVariant> +#include <QHash> + +#include <LuminaXDG.h> + +class BrowserModel : public QAbstractItemModel { + Q_OBJECT +public: + BrowserModel(QObject *parent = 0); + ~BrowserModel(); + + //Virtual overrides + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &index) const; + + // item management + int rowCount(const QModelIndex &parent = QModelIndex()) const; + bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()); + bool removeRow(int row, const QModelIndex &parent = QModelIndex()); + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); + + int columnCount(const QModelIndex &parent = QModelIndex()) const; + bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()); + bool removeColumn(int column, const QModelIndex &parent = QModelIndex()); + bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()); + + //bool hasChildren(const QModelIndex &parent = QModelIndex()) const; + + // data functions + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + // data modification functions + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole); + + // drag and drop + //QMimeData* mimeData(const QModelIndexList &indexes) const; + //QStringList mimeTypes() const; + //bool setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles); + //Qt::DropActions supportedDropActions() const; + //bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); + + //Special Functions (non virtual replacements) + LFileInfo* fileInfo(QString name); + QString currentDirectory(); + + void setShowHidden(bool showHidden); + bool showHidden + +public slots: + void loadDirectory(QString dir=""); + void loadItem(QString item); + +private: + QHash<quintptr, QModelIndex> HASH; //QString: "row/column" + QString cDir; + //simplification functions + /*QString findInHash(QString path); + QString findInHash(QModelIndex index); + LFileInfo* indexToInfo(QString path);*/ + LFileInfo* indexToInfo(QModelIndex index); + +private slots: + +protected: + +signals: + +}; + +#endif diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp index d5f219bb..87a3a6d7 100644 --- a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp +++ b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp @@ -24,7 +24,7 @@ BrowserWidget::BrowserWidget(QString objID, QWidget *parent) : QWidget(parent){ connect(BROWSER, SIGNAL(itemRemoved(QString)), this, SLOT(itemRemoved(QString)) ); connect(BROWSER, SIGNAL(itemDataAvailable(QIcon, LFileInfo*)), this, SLOT(itemDataAvailable(QIcon, LFileInfo*)) ); connect(BROWSER, SIGNAL(itemsLoading(int)), this, SLOT(itemsLoading(int)) ); - connect(this, SIGNAL(dirChange(QString)), BROWSER, SLOT(loadDirectory(QString)) ); + connect(this, SIGNAL(dirChange(QString, bool)), BROWSER, SLOT(loadDirectory(QString, bool)) ); listWidget = 0; treeWidget = 0; readDateFormat(); @@ -38,6 +38,7 @@ BrowserWidget::~BrowserWidget(){ } void BrowserWidget::changeDirectory(QString dir){ + videoMap.clear(); if(BROWSER->currentDirectory()==dir){ return; } //already on this directory //qDebug() << "Change Directory:" << dir << historyList; @@ -50,7 +51,7 @@ void BrowserWidget::changeDirectory(QString dir){ if( (historyList.isEmpty() || historyList.last()!=cleaned) && !cleaned.isEmpty() ){ historyList << cleaned; } } //qDebug() << "History:" << historyList; - emit dirChange(dir); + emit dirChange(dir, false); } void BrowserWidget::showDetails(bool show){ @@ -81,7 +82,8 @@ void BrowserWidget::showDetails(bool show){ connect(treeWidget, SIGNAL(GotFocus()), this, SLOT(selectionChanged()) ); retranslate(); treeWidget->sortItems(0, Qt::AscendingOrder); - if(!BROWSER->currentDirectory().isEmpty()){ emit dirChange(""); } + treeWidget->setColumnWidth(0, treeWidget->fontMetrics().width("W")*20); + if(!BROWSER->currentDirectory().isEmpty()){ emit dirChange("", true); } }else if(!show && listWidget==0){ listWidget = new DDListWidget(this); listWidget->setContextMenuPolicy(Qt::CustomContextMenu); @@ -91,8 +93,10 @@ void BrowserWidget::showDetails(bool show){ connect(listWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SIGNAL(contextMenuRequested()) ); connect(listWidget, SIGNAL(DataDropped(QString, QStringList)), this, SIGNAL(DataDropped(QString, QStringList)) ); connect(listWidget, SIGNAL(GotFocus()), this, SLOT(selectionChanged()) ); - if(!BROWSER->currentDirectory().isEmpty()){ emit dirChange(""); } + if(!BROWSER->currentDirectory().isEmpty()){ emit dirChange("",true); } } + if(listWidget!=0){ listWidget->setWhatsThis( BROWSER->currentDirectory() ); } + if(treeWidget!=0){ treeWidget->setWhatsThis(BROWSER->currentDirectory() ); } //qDebug() << " Done making widget"; } @@ -109,6 +113,18 @@ bool BrowserWidget::hasHiddenFiles(){ } void BrowserWidget::showThumbnails(bool show){ + //qDebug() << show << videoMap.size(); + for(QString file : videoMap.uniqueKeys()) { + QTreeWidgetItem *it = videoMap[file].first; + LVideoWidget *widget = videoMap[file].second; + if(show) { + widget->enableIcons(); + treeWidget->setItemWidget(it, 0, widget); + }else{ + widget->disableIcons(); + treeWidget->setItemWidget(it, 0, widget); + } + } BROWSER->showThumbnails(show); } @@ -125,9 +141,15 @@ void BrowserWidget::setThumbnailSize(int px){ larger = treeWidget->iconSize().height() < px; treeWidget->setIconSize(QSize(px,px)); } + for(QString file : videoMap.uniqueKeys()) { + QTreeWidgetItem *it = videoMap[file].first; + LVideoWidget *widget = videoMap[file].second; + widget->setIconSize(treeWidget->iconSize()); + treeWidget->setItemWidget(it, 0, widget); + } //qDebug() << "Changing Icon Size:" << px << larger; if(BROWSER->currentDirectory().isEmpty() || !larger ){ return; } //don't need to reload icons unless the new size is larger - emit dirChange(""); + emit dirChange("", larger); } int BrowserWidget::thumbnailSize(){ @@ -271,6 +293,8 @@ void BrowserWidget::itemRemoved(QString item){ } void BrowserWidget::itemDataAvailable(QIcon ico, LFileInfo *info){ + if(listWidget!=0){ listWidget->setWhatsThis( BROWSER->currentDirectory() ); } + if(treeWidget!=0){ treeWidget->setWhatsThis(BROWSER->currentDirectory() ); } //qDebug() << "Item Data Available:" << info->fileName(); int num = 0; if(listWidget!=0){ @@ -326,15 +350,28 @@ void BrowserWidget::itemDataAvailable(QIcon ico, LFileInfo *info){ treeWidget->addTopLevelItem(it); } }else{ - if( ! treeWidget->findItems(info->fileName(), Qt::MatchExactly, 0).isEmpty() ){ it = treeWidget->findItems(info->fileName(), Qt::MatchExactly, 0).first(); } - else{ + if( ! treeWidget->findItems(info->fileName(), Qt::MatchExactly, 0).isEmpty() ) { + it = treeWidget->findItems(info->fileName(), Qt::MatchExactly, 0).first(); + }else if(info->isVideo() && videoMap.find(info->absoluteFilePath()) == videoMap.end()) { + it = new CQTreeWidgetItem(treeWidget); + treeWidget->addTopLevelItem(it); + LVideoWidget *widget = new LVideoWidget(info->absoluteFilePath(), treeWidget->iconSize(), hasThumbnails(), treeWidget); + videoMap.insert(info->absoluteFilePath(), QPair<QTreeWidgetItem*,LVideoWidget*>(it, widget)); + treeWidget->setItemWidget(it, 0, widget); + }else if(info->isVideo()) { + it = videoMap[info->absoluteFilePath()].first; + LVideoWidget *widget = videoMap[info->absoluteFilePath()].second; + widget->setIconSize(treeWidget->iconSize()); + treeWidget->setItemWidget(it, 0, widget); + }else{ it = new CQTreeWidgetItem(treeWidget); - it->setText(0, info->fileName() ); //name (0) treeWidget->addTopLevelItem(it); + it->setText(0, info->fileName() ); //name (0) } } //Now set/update all the data - it->setIcon(0, ico); + if(!info->isVideo()) + it->setIcon(0, ico); it->setText(1, info->isDir() ? "" : LUtils::BytesToDisplaySize(info->size()) ); //size (1) it->setText(2, info->mimetype() ); //type (2) it->setText(3, DTtoString(info->lastModified() )); //modification date (3) @@ -352,7 +389,9 @@ void BrowserWidget::itemDataAvailable(QIcon ico, LFileInfo *info){ }else{ if(freshload && treeWidget!=0){ //qDebug() << "Resize Tree Widget Contents"; - for(int i=0; i<treeWidget->columnCount(); i++){ treeWidget->resizeColumnToContents(i); } + //for(int i=treeWidget->columnCount()-1; i>0; i--){ treeWidget->resizeColumnToContents(i); } + treeWidget->resizeColumnToContents(1); + //treeWidget->resizeColumnToContents(0); } freshload = false; //any further changes are updates - not a fresh load of a dir //Done loading items diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h index fafb3746..b17ad588 100644 --- a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h +++ b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h @@ -12,6 +12,8 @@ #include <QWidget> #include <QThread> +#include <LVideoWidget.h> + #include "Browser.h" #include "widgets/DDListWidgets.h" @@ -23,6 +25,7 @@ private: int numItems; //used for checking if all the items have loaded yet QString ID, statustip; QStringList date_format, historyList; + QMap<QString,QPair<QTreeWidgetItem*, LVideoWidget*>> videoMap; bool freshload; //The drag and drop brower widgets @@ -86,9 +89,10 @@ signals: void contextMenuRequested(); void DataDropped(QString, QStringList); void hasFocus(QString); //ID output + void stopLoop(); //Internal signal - void dirChange(QString); //current dir path + void dirChange(QString, bool); //current dir path, force }; #endif diff --git a/src-qt5/desktop-utils/lumina-fm/MainUI.cpp b/src-qt5/desktop-utils/lumina-fm/MainUI.cpp index abb99975..9ce7b69e 100644 --- a/src-qt5/desktop-utils/lumina-fm/MainUI.cpp +++ b/src-qt5/desktop-utils/lumina-fm/MainUI.cpp @@ -14,8 +14,10 @@ #include <LUtils.h> #include <LDesktopUtils.h> +#include <ExternalProcess.h> #define DEBUG 0 +bool rootmode = false; MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){ //for Signal/slot we must register the Typedef of QFileInfoList @@ -25,6 +27,8 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){ //qRegisterMetaType< QVector<int> >("QVector<int>"); //qRegisterMetaType< QList<QPersistentModelIndex> >("QList<QPersistentModelIndex>"); waitingToClose = false; + //put if statement here to check if running as root + rootmode = (getuid()==0); ui->setupUi(this); if(DEBUG){ qDebug() << "Initilization:"; } @@ -112,6 +116,7 @@ QSize orig = settings->value("preferences/MainWindowSize", QSize()).toSize(); TRAY = new TrayUI(this); connect(TRAY, SIGNAL(JobsFinished()), this, SLOT(TrayJobsFinished()) ); if(DEBUG){ qDebug() << " - Done with init"; } + ui->actionOpen_as_Root->setVisible(LUtils::isValidBinary("qsudo")); } MainUI::~MainUI(){ @@ -344,7 +349,7 @@ void MainUI::RebuildDeviceMenu(){ QStringList devs = LOS::ExternalDevicePaths(); //Output Format: <type>::::<filesystem>::::<path> (6/24/14 - version 0.4.0 ) // <type> = [USB, HDRIVE, SDCARD, DVD, LVM, UNKNOWN] - qDebug() << "Externally-mounted devices:" << devs; + //qDebug() << "Externally-mounted devices:" << devs; //Now add them to the menu appropriately for(int i=0; i<devs.length(); i++){ //Skip hidden mount points (usually only for system usage - not user browsing) @@ -356,6 +361,7 @@ void MainUI::RebuildDeviceMenu(){ if(path == "/"){ label = tr("Root"); } else{ label = path.section("/",-1).simplified(); } if(label.startsWith(".") ){ continue; } //don't show hidden mountpoint (not usually user-browsable) + if(label.endsWith(".desktop")){ label = label.section(".desktop",0,-2); } //chop the shortcut suffix off the end //Create entry for this device if( !fs.simplified().isEmpty()){ //Add filesystem type to the label @@ -502,13 +508,29 @@ void MainUI::goToDevice(QAction *act){ if(act==ui->actionScan){ RebuildDeviceMenu(); }else{ + QString action = act->whatsThis(); + if(action.endsWith(".desktop")){ + //Find the actual action/directory within this shortcut + XDGDesktop xdg(action); + if(xdg.type==XDGDesktop::DIR){ + action = xdg.path; //use the new path + }else{ + //Need to run the full open routine on this shortcut + QProcess::startDetached("lumina-open", QStringList() << action); + return; + } + }else if( !QFileInfo(action).isDir() ){ + //Need to run the full open routine on this file since it is not a directory + QProcess::startDetached("lumina-open", QStringList() << action); + return; + } DirWidget *dir = FindActiveBrowser(); if(dir!=0){ - dir->ChangeDir(act->whatsThis()); + dir->ChangeDir(action); return; } //If no current dir could be found - open a new tab/column - OpenDirs(QStringList() << act->whatsThis() ); + OpenDirs(QStringList() << action ); } } @@ -962,3 +984,8 @@ void MainUI::closeEvent(QCloseEvent *ev){ } QMainWindow::closeEvent(ev); //continue normal close routine } + +void MainUI::on_actionOpen_as_Root_triggered() +{ + ExternalProcess::launch("qsudo lumina-fm"); +} diff --git a/src-qt5/desktop-utils/lumina-fm/MainUI.h b/src-qt5/desktop-utils/lumina-fm/MainUI.h index 492ba533..04b80f28 100644 --- a/src-qt5/desktop-utils/lumina-fm/MainUI.h +++ b/src-qt5/desktop-utils/lumina-fm/MainUI.h @@ -67,6 +67,7 @@ class MainUI : public QMainWindow{ public: MainUI(); ~MainUI(); + //bool rootmode; public slots: void OpenDirs(QStringList); //also called from the main.cpp after initialization @@ -176,6 +177,8 @@ private slots: void TrayJobsFinished(); + void on_actionOpen_as_Root_triggered(); + signals: void Si_AdaptStatusBar(QFileInfoList fileList, QString path, QString messageFolders, QString messageFiles); diff --git a/src-qt5/desktop-utils/lumina-fm/MainUI.ui b/src-qt5/desktop-utils/lumina-fm/MainUI.ui index 744f31a3..8a635199 100644 --- a/src-qt5/desktop-utils/lumina-fm/MainUI.ui +++ b/src-qt5/desktop-utils/lumina-fm/MainUI.ui @@ -119,6 +119,8 @@ <addaction name="separator"/> <addaction name="actionClose_Browser"/> <addaction name="separator"/> + <addaction name="actionOpen_as_Root"/> + <addaction name="separator"/> <addaction name="actionClose"/> </widget> <widget class="QMenu" name="menuView"> @@ -434,6 +436,11 @@ <string>Ctrl+P</string> </property> </action> + <action name="actionOpen_as_Root"> + <property name="text"> + <string>Open as Root</string> + </property> + </action> </widget> <resources/> <connections/> diff --git a/src-qt5/desktop-utils/lumina-fm/VideoItemWidget.h b/src-qt5/desktop-utils/lumina-fm/VideoItemWidget.h new file mode 100644 index 00000000..894394d4 --- /dev/null +++ b/src-qt5/desktop-utils/lumina-fm/VideoItemWidget.h @@ -0,0 +1,144 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2016, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#ifndef _LUMINA_VIDEO_ITEM_WIDGET_H +#define _LUMINA_VIDEO_ITEM_WIDGET_H + +#include <QWidget> +#include <QVideoWidget> +#include <QMediaPlayer> +#include <QString> +#include <QObject> +#include <QLabel> +#include <QTimer> +#include <QHBoxLayout> +#include <QResizeEvent> + +#include <LVideoSurface.h> + +class RolloverVideoWidget : public QVideoWidget{ + Q_OBJECT +public: + RolloverVideoWidget(QWidget *parent = 0) : QVideoWidget(parent){ + this->setMouseTracking(true); + } +signals: + void OverWidget(); + void NotOverWidget(); + +protected: + /*void mouseMoveEvent(QMouseEvent *ev){ + QWidget::mouseMoveEvent(ev); + qDebug() << "Got video rollover"; + emit OverWidget(); + }*/ + void enterEvent(QEvent *ev){ + QWidget::enterEvent(ev); + qDebug() << "Got video enter"; + emit OverWidget(); + } + void leaveEvent(QEvent *ev){ + QWidget::leaveEvent(ev); + if(!this->underMouse()){ + qDebug() << "Got video leave"; + emit NotOverWidget(); + } + } +}; + +class VideoItemWidget : public QWidget{ + Q_OBJECT +private: + QLabel *textLabel; + QMediaPlayer *mplayer; + LVideoSurface *vwidget; + QString file, text; + QSize fixedsize; + +public: + VideoItemWidget(QString filepath, QWidget *parent = 0) : QWidget(parent){ + file = filepath; + text = filepath.section("/",-1); + textLabel = 0; + mplayer = 0; + vwidget = 0; + this->setMouseTracking(true); + QTimer::singleShot(5, this, SLOT(setupPlayer()) ); //make sure this creation routine is thread-safe + } + ~VideoItemWidget(){ mplayer->stop(); } + + //Optional overloads - it will try to automatically adjust as needed + void setText(QString txt){ + text = txt; + if(textLabel!=0){ + textLabel->setText(txt); + textLabel->setVisible( !txt.isEmpty() ); + } + } + void setIconSize(QSize sz){ + fixedsize = sz; + if(vwidget!=0 && fixedsize.isValid()){ vwidget->setFixedSize(sz); } + } + +private slots: + void setupPlayer(){ + textLabel = new QLabel(this); + vwidget = new LVideoSurface(this); //RolloverVideoWidget(this); + vwidget->setAspectRatioMode(Qt::IgnoreAspectRatio); + if(fixedsize.isValid()){ vwidget->setFixedSize(fixedsize); } + else{ vwidget->setMinimumSize(QSize(16,16)); } + mplayer = new QMediaPlayer(this, QMediaPlayer::VideoSurface); + mplayer->setVideoOutput(vwidget); + mplayer->setPlaybackRate(3); // 3x playback speed + mplayer->setMuted(true); + QHBoxLayout *tmpL = new QHBoxLayout(this); + tmpL->setAlignment(Qt::AlignLeft | Qt::AlignCenter); + tmpL->addWidget(vwidget); + tmpL->addWidget(textLabel); + tmpL->setStretchFactor(textLabel, 1); //make sure this always occupies all extra space + //connect(mplayer, SIGNAL(durationChanged(qint64)), this, SLOT(durationChanged(qint64)) ); + connect(mplayer, SIGNAL(durationChanged(qint64)), this, SLOT(stopVideo()) ); + //connect(vwidget, SIGNAL(OverWidget()), this, SLOT(startVideo()) ); + //connect(vwidget, SIGNAL(NotOverWidget()), this, SLOT(stopVideo()) ); + //Now load the file + textLabel->setText(text); + mplayer->setMedia(QUrl::fromLocalFile(file) ); + mplayer->play(); + } + void durationChanged(qint64 max){ + qDebug() << "Got Duration Changed:" << max; + mplayer->setPosition( qRound(max/2.0)); + } + + void startVideo(){ + if(mplayer==0){ return; } + if(mplayer->state()!=QMediaPlayer::PlayingState){ + qDebug() << "Start Video"; + mplayer->setPosition(0); + mplayer->play(); + } + } + + void stopVideo(){ + if(mplayer==0){ return; } + if(mplayer->state()==QMediaPlayer::PlayingState){ + qDebug() << "Stop Video"; + mplayer->pause(); + mplayer->setPosition( qRound(mplayer->duration()/2.0) ); + } + } + +protected: + void resizeEvent(QResizeEvent *ev){ + if(vwidget!=0 && !fixedsize.isValid()){ vwidget->setFixedSize( QSize(ev->size().height(), ev->size().height()) ); } + } + /*void mouseMoveEvent(QMouseEvent *ev){ + QWidget::mouseMoveEvent(ev); + stopVideo(); //not over the video widget any more + }*/ +}; + +#endif diff --git a/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro b/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro index 6c340e14..e27dad25 100644 --- a/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro +++ b/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro @@ -15,6 +15,8 @@ include(../../core/libLumina/LuminaXDG.pri) include(../../core/libLumina/LuminaSingleApplication.pri) include(../../core/libLumina/LuminaThemes.pri) include(../../core/libLumina/ExternalProcess.pri) +#include(../../core/libLumina/LVideoSurface.pri) +include(../../core/libLumina/LVideoLabel.pri) SOURCES += main.cpp \ MainUI.cpp \ diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h b/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h index 254362fd..7e4b1f22 100644 --- a/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h +++ b/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h @@ -23,6 +23,7 @@ #include <QMouseEvent> #include <QUrl> #include <QDir> +#include <QApplication> #include <LUtils.h> @@ -63,8 +64,8 @@ protected: QList<QListWidgetItem*> items = this->selectedItems(); if(items.length()<1){ return; } QList<QUrl> urilist; - for(int i=0; i<items.length(); i++){ - urilist << QUrl::fromLocalFile(items[i]->whatsThis()); + for(int i=0; i<items.length(); i++){ + urilist << QUrl::fromLocalFile(items[i]->whatsThis()); } //Create the mime data //qDebug() << "Start Drag:" << urilist; @@ -88,7 +89,7 @@ protected: ev->ignore(); } } - + void dragMoveEvent(QDragMoveEvent *ev){ if(ev->mimeData()->hasUrls() && !this->whatsThis().isEmpty() ){ //Change the drop type depending on the data/dir @@ -104,7 +105,7 @@ protected: } this->update(); } - + void dropEvent(QDropEvent *ev){ if(this->whatsThis().isEmpty() || !ev->mimeData()->hasUrls() ){ ev->ignore(); return; } //not supported //qDebug() << "Drop Event:"; @@ -125,7 +126,7 @@ protected: foreach(const QUrl &url, ev->mimeData()->urls()){ const QString filepath = url.toLocalFile(); //If the target file is modifiable, assume a move - otherwise copy - if(QFileInfo(filepath).isWritable() && (filepath.startsWith(home) && dirpath.startsWith(home))){ + if(QFileInfo(filepath).isWritable() && (filepath.startsWith(home) && dirpath.startsWith(home))){ if(filepath.section("/",0,-2)!=dirpath){ files << "cut::::"+filepath; } //don't "cut" a file into the same dir }else{ files << "copy::::"+filepath; } } @@ -133,18 +134,18 @@ protected: if(!files.isEmpty()){ emit DataDropped( dirpath, files ); } this->setCursor(Qt::ArrowCursor); } - + void mouseReleaseEvent(QMouseEvent *ev){ if(ev->button() != Qt::RightButton && ev->button() != Qt::LeftButton){ ev->ignore(); } else{ QListWidget::mouseReleaseEvent(ev); } //pass it along to the widget } void mousePressEvent(QMouseEvent *ev){ if(ev->button() != Qt::RightButton && ev->button() != Qt::LeftButton){ ev->ignore(); } - else{ QListWidget::mousePressEvent(ev); } //pass it along to the widget + else{ QListWidget::mousePressEvent(ev); } //pass it along to the widget } /*void mouseMoveEvent(QMouseEvent *ev){ if(ev->button() != Qt::RightButton && ev->button() != Qt::LeftButton){ ev->ignore(); } - else{ QListWidget::mouseMoveEvent(ev); } //pass it along to the widget + else{ QListWidget::mouseMoveEvent(ev); } //pass it along to the widget }*/ }; @@ -158,6 +159,8 @@ public: //Drag and Drop Properties this->setDragDropMode(QAbstractItemView::DragDrop); this->setDefaultDropAction(Qt::MoveAction); //prevent any built-in Qt actions - the class handles it + this->setDropIndicatorShown(true); + this->setAcceptDrops(true); //Other custom properties necessary for the FM this->setFocusPolicy(Qt::StrongFocus); this->setContextMenuPolicy(Qt::CustomContextMenu); @@ -183,8 +186,8 @@ protected: QList<QTreeWidgetItem*> items = this->selectedItems(); if(items.length()<1){ return; } QList<QUrl> urilist; - for(int i=0; i<items.length(); i++){ - urilist << QUrl::fromLocalFile(items[i]->whatsThis(0)); + for(int i=0; i<items.length(); i++){ + urilist << QUrl::fromLocalFile(items[i]->whatsThis(0)); } //Create the mime data QMimeData *mime = new QMimeData; @@ -192,35 +195,43 @@ protected: //Create the drag structure QDrag *drag = new QDrag(this); drag->setMimeData(mime); - /*if(info.first().section("::::",0,0)=="cut"){ - drag->exec(act | Qt::MoveAction); - }else{*/ + //qDebug() << "Start Drag:" << urilist; drag->exec(act | Qt::CopyAction| Qt::MoveAction); - //} + //qDebug() << " - Drag Finished"; } void dragEnterEvent(QDragEnterEvent *ev){ - //qDebug() << "Drag Enter Event:" << ev->mimeData()->hasFormat(MIME); + //qDebug() << "Drag Enter Event:" << ev->mimeData()->hasUrls() << this->whatsThis(); + //QTreeWidget::dragEnterEvent(ev); if(ev->mimeData()->hasUrls() && !this->whatsThis().isEmpty() ){ ev->acceptProposedAction(); //allow this to be dropped here }else{ ev->ignore(); - } + } } - + void dragMoveEvent(QDragMoveEvent *ev){ + //qDebug() << "Drag Move Event:" << ev->mimeData()->hasUrls() << this->whatsThis(); + //QTreeWidget::dragMoveEvent(ev); if(ev->mimeData()->hasUrls() && !this->whatsThis().isEmpty() ){ //Change the drop type depending on the data/dir QString home = QDir::homePath(); - if( this->whatsThis().startsWith(home) ){ ev->setDropAction(Qt::MoveAction); } - else{ ev->setDropAction(Qt::CopyAction); } - ev->accept(); //allow this to be dropped here + if( this->whatsThis().startsWith(home) ){ ev->setDropAction(Qt::MoveAction); this->setCursor(Qt::DragMoveCursor); } + else{ ev->setDropAction(Qt::CopyAction); this->setCursor(Qt::DragCopyCursor);} + ev->acceptProposedAction(); //allow this to be dropped here + //this->setAcceptDrops(true); }else{ + //this->setAcceptDrops(false); + this->setCursor(Qt::ForbiddenCursor); ev->ignore(); } + //this->setDropIndicatorShown(true); + //this->update(); + //QTreeWidget::dragMoveEvent(ev); } - + void dropEvent(QDropEvent *ev){ + //qDebug() << "Drop Event:" << ev->mimeData()->hasUrls() << this->whatsThis(); if(this->whatsThis().isEmpty() || !ev->mimeData()->hasUrls() ){ ev->ignore(); return; } //not supported ev->accept(); //handled here QString dirpath = this->whatsThis(); @@ -239,25 +250,25 @@ protected: foreach(const QUrl &url, ev->mimeData()->urls()){ const QString filepath = url.toLocalFile(); //If the target file is modifiable, assume a move - otherwise copy - if(QFileInfo(filepath).isWritable() && (filepath.startsWith(home) && dirpath.startsWith(home))){ + if(QFileInfo(filepath).isWritable() && (filepath.startsWith(home) && dirpath.startsWith(home))){ if(filepath.section("/",0,-2)!=dirpath){ files << "cut::::"+filepath; } //don't "cut" a file into the same dir }else{ files << "copy::::"+filepath; } } //qDebug() << "Drop Event:" << dirpath; emit DataDropped( dirpath, files ); } - + void mouseReleaseEvent(QMouseEvent *ev){ if(ev->button() != Qt::RightButton && ev->button() != Qt::LeftButton){ ev->ignore(); } else{ QTreeWidget::mouseReleaseEvent(ev); } //pass it along to the widget } void mousePressEvent(QMouseEvent *ev){ if(ev->button() != Qt::RightButton && ev->button() != Qt::LeftButton){ ev->ignore(); } - else{ QTreeWidget::mousePressEvent(ev); } //pass it along to the widget + else{ QTreeWidget::mousePressEvent(ev); } //pass it along to the widget } /*void mouseMoveEvent(QMouseEvent *ev){ if(ev->button() != Qt::RightButton && ev->button() != Qt::LeftButton){ ev->ignore(); } - else{ QTreeWidget::mouseMoveEvent(ev); } //pass it along to the widget + else{ QTreeWidget::mouseMoveEvent(ev); } //pass it along to the widget }*/ }; diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp index 8273d09c..5c6f9ef5 100644 --- a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp +++ b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp @@ -27,9 +27,12 @@ #include "../ScrollDialog.h" #define DEBUG 0 +extern bool rootmode; DirWidget::DirWidget(QString objID, QSettings *settings, QWidget *parent) : QWidget(parent), ui(new Ui::DirWidget){ ui->setupUi(this); //load the designer file + ui->label_rootmode->setVisible(rootmode); + ID = objID; //Assemble the toolbar for the widget toolbar = new QToolBar(this); @@ -59,7 +62,7 @@ DirWidget::DirWidget(QString objID, QSettings *settings, QWidget *parent) : QWid RCBW = 0; //right column browser is unavailable initially BW = new BrowserWidget("", this); ui->browser_layout->addWidget(BW); - connect(BW, SIGNAL(dirChange(QString)), this, SLOT(currentDirectoryChanged()) ); + connect(BW, SIGNAL(dirChange(QString, bool)), this, SLOT(currentDirectoryChanged()) ); connect(BW, SIGNAL(itemsActivated()), this, SLOT(runFiles()) ); connect(BW, SIGNAL(DataDropped(QString, QStringList)), this, SIGNAL(PasteFiles(QString, QStringList)) ); connect(BW, SIGNAL(contextMenuRequested()), this, SLOT(OpenContextMenu()) ); @@ -281,10 +284,11 @@ void DirWidget::createMenus(){ else{ cOpenMenu->clear(); } cOpenMenu->setTitle(tr("Launch...")); cOpenMenu->setIcon( LXDG::findIcon("quickopen","") ); - cOpenMenu->addAction(LXDG::findIcon("utilities-terminal",""), tr("Terminal"), this, SLOT(openTerminal()), kOpTerm->key()); + cOpenMenu->addAction(LXDG::findIcon("utilities-terminal",""), tr("Open Current Dir in a Terminal"), this, SLOT(openTerminal()), kOpTerm->key()); cOpenMenu->addAction(LXDG::findIcon("media-slideshow",""), tr("SlideShow"), this, SLOT(openInSlideshow()), kOpSS->key()); cOpenMenu->addAction(LXDG::findIcon("media-playback-start-circled","media-playback-start"), tr("Multimedia Player"), this, SLOT(openMultimedia()), kOpMM->key()); -/* + if(LUtils::isValidBinary("qsudo")){ cOpenMenu->addAction(LXDG::findIcon("", ""), tr("Open Current Dir as Root"), this, SLOT(openRootFM())); + /* if(cFModMenu==0){ cFModMenu = new QMenu(this); } else{ cFModMenu->clear(); } cFModMenu->setTitle(tr("Modify Files...")); @@ -319,6 +323,8 @@ void DirWidget::createMenus(){ } +} + BrowserWidget* DirWidget::currentBrowser(){ if(cBID.isEmpty() || RCBW==0){ return BW; } else{ return RCBW; } @@ -471,7 +477,7 @@ void DirWidget::on_actionDualColumn_triggered(bool checked){ if(RCBW!=0){ return; } //nothing to do RCBW = new BrowserWidget("rc", this); ui->browser_layout->addWidget(RCBW); - connect(RCBW, SIGNAL(dirChange(QString)), this, SLOT(currentDirectoryChanged()) ); + connect(RCBW, SIGNAL(dirChange(QString, bool)), this, SLOT(currentDirectoryChanged()) ); connect(RCBW, SIGNAL(itemsActivated()), this, SLOT(runFiles()) ); connect(RCBW, SIGNAL(DataDropped(QString, QStringList)), this, SIGNAL(PasteFiles(QString, QStringList)) ); connect(RCBW, SIGNAL(contextMenuRequested()), this, SLOT(OpenContextMenu()) ); @@ -482,6 +488,7 @@ void DirWidget::on_actionDualColumn_triggered(bool checked){ RCBW->showDetails(BW->hasDetails()); RCBW->showHiddenFiles( BW->hasHiddenFiles()); RCBW->setThumbnailSize( BW->thumbnailSize()); + RCBW->showThumbnails( BW->hasThumbnails()); RCBW->changeDirectory( BW->currentDirectory()); } @@ -880,3 +887,9 @@ void DirWidget::mouseReleaseEvent(QMouseEvent *ev){ ev->ignore(); //not handled here } } + +void DirWidget::openRootFM(){ + rootfmdir = "qsudo lumina-fm -new-instance " + currentDir(); + qDebug() << "rootfmdir" << rootfmdir; + ExternalProcess::launch(rootfmdir); +} diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.h b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.h index 8dd367df..4377f92d 100644 --- a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.h +++ b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.h @@ -73,9 +73,9 @@ private: Ui::DirWidget *ui; BrowserWidget *BW, *RCBW; //Main BrowserWidget and right-column browser widget QString ID, cBID; //unique ID assigned by the parent, and currently active browser widget - QString normalbasedir, snapbasedir, snaprelpath; //for maintaining directory context while moving between snapshots + QString normalbasedir, snapbasedir, snaprelpath, rootfmdir; //for maintaining directory context while moving between snapshots QStringList snapshots, needThumbs, tmpSel; - QSettings *settings; + QSettings *settings; bool canmodify; //The Toolbar and associated items @@ -83,10 +83,10 @@ private: QLineEdit *line_dir; //The context menu and associated items - QMenu *contextMenu, *cNewMenu, *cOpenMenu, *cFModMenu, *cFViewMenu, *cOpenWithMenu; + QMenu *contextMenu, *cNewMenu, *cOpenMenu, *cFModMenu, *cFViewMenu, *cOpenWithMenu; //The keyboard shortcuts for context menu items - QShortcut *kZoomIn, *kZoomOut, *kNewFile, *kNewDir, *kNewXDG, *kCut, *kCopy, *kPaste, *kRename, \ + QShortcut *kZoomIn, *kZoomOut, *kNewFile, *kNewDir, *kNewXDG, *kCut, *kCopy, *kPaste, *kRename, \ *kFav, *kDel, *kOpSS, *kOpMM, *kOpTerm, *kExtract; //, *kArchive; //Functions for internal use @@ -129,6 +129,7 @@ private slots: void fileCheckSums(); void fileProperties(); void openTerminal(); + void openRootFM(); //Browser Functions diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.ui b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.ui index b1ba9d95..5f980c67 100644 --- a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.ui +++ b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>400</width> - <height>350</height> + <height>389</height> </rect> </property> <property name="minimumSize"> @@ -19,7 +19,32 @@ <property name="windowTitle"> <string>Form</string> </property> - <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,1,0"> + <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,1,0"> + <item> + <widget class="QLabel" name="label_rootmode"> + <property name="font"> + <font> + <family>Droid Sans Mono</family> + <pointsize>16</pointsize> + <weight>75</weight> + <italic>false</italic> + <bold>true</bold> + </font> + </property> + <property name="frameShape"> + <enum>QFrame::Box</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Sunken</enum> + </property> + <property name="text"> + <string> * - FILE MANAGER RUNNING AS ROOT- * </string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> <item> <layout class="QHBoxLayout" name="toolbar_layout"/> </item> diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.cpp b/src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.cpp new file mode 100644 index 00000000..6e65ebaf --- /dev/null +++ b/src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.cpp @@ -0,0 +1,36 @@ +#include "fmwebdav.h" + +fmwebdav::fmwebdav(QObject *parent) : QNetworkAccessManager(parent) ,wdRootPath(), wdUsername(), wdUassword(), wdBaseUrl(), wdCurrentConnectionType(QWebdav::HTTP){ +// typical Qnetwork connection stuff goes here +// probably ssl parts too +} + +fmwebdav::~fmwebdav(){ +} + +QString fmwebdav::hostname() const{ return wdBaseUrl.host(); } + +int fmwebdav::port() const{ return wdBaseUrl.port(); } + +QString fmwebdav::rootPath() const{ return wdRootPath;} + +QString fmwebdav::username() const{ return wdUsername; } + +QString fmwebdav::password() const{ return wdPassword; } + +fmwebdav::QWebdavConnectionType : fmwebdav::connectionType() const{ return wdCurrentConnectionType; } + +bool fmwebdav::isSSL() const{ return (wdCurrentConnectionType==QWebdav::HTTPS); } + +void QWebdav::setConnectionSettings(const QWebdavConnectionType connectionType, const QString *hostname, const QString *rootPath, const QString *username, const QString *password, int *port){ + wdRootPath = rootPath; + if ((wdRootPath.endsWith("/")){ wdRootPath.chop(1); } + wdCurrentConnectionType = connectionType; + wdBaseUrl.setScheme(); + wdBaseUrl.setHost(hostname); + wdBaseUrl.setPath(rootPath); + if (port != 0) { // use user-defined port number if not 80 or 443 + if ( ! ( ( (port == 80) && (wdCurrentConnectionType==QWebdav::HTTP) ) || ( (port == 443) && (wdCurrentConnectionType==QWebdav::HTTPS) ) ) ){ wdBaseUrl.setPort(port); } + wdUsername = username; + wdPassword = password; +} diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.h b/src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.h new file mode 100644 index 00000000..04d29e3b --- /dev/null +++ b/src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.h @@ -0,0 +1,36 @@ +#ifndef FMWEBDAV_H +#define FMWEBDAV_H + +#include <QtCore> +#include <QtNetwork> +#include <QNetworkAccessManager> + +public: + + enum QWebdavConnectionType {HTTP = 1, HTTPS}; + + QString hostname() const; + int port() const; + QString rootPath() const; + QString username() const; + QString password() const; + QWebdavConnectionType connectionType() const; + bool isSSL() const; + + void setConnectionSettings( const QWebdavConnectionType connectionType, const QString *hostname, const QString *rootPath = "/", const QString *username = "", const QString *password = "", int *port = 0; + + +private: + + QString wdRootPath; + QString wdUsername; + QString wdPassword; + QUrl wdBaseUrl; + QWebdavConnectionType wdCurrentConnectionType; + + + + + + +#endif // FMWEBDAV diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.cpp b/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.cpp new file mode 100644 index 00000000..d0ecdecf --- /dev/null +++ b/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.cpp @@ -0,0 +1,59 @@ +#ifndef VIDNAIL_H +#define VIDNAIL_H + +extern "C" { +#include <libavcodec/avcodec.h> +#include <libavformat/avformat.h> +} + +class VidNail; + +struct vFrame { + vFrame() : *width(0), *height(0) {} + vFrame(int *width, int *height : width(width), height(height) {} + int *width; + int *height; +}; + +public: + + QString getCodec(); + void skipTo(int timeInSeconds); + void readVideoFrame(); + void getScaledVideoFrame(int scaledSize, vFrame& vFrame); + + int getWidth(); + int getHeight(); + int getLength(); + + void makeThumbnail(const QString& videoFile, QImage &image); + void setThumbnailSize(int size); + void setPercentage(int percent); + void setTime(const QString& Time); + + void writeVidNail(vFrame& frame, QImage& image); + + + private: + bool readVideoPacket(); + bool getVideoPacket(); + void scaleVideo(int scaledSize, int& scaledWidth, int& scaledHeight); + void createVFrame(AVFrame *vFrame, quint8 *frameBuffer, int width, int height); + void calculateDimensions(int size); + void generateThumbnail(const QString& videoFile, ImageWriter& imageWriter, QImage& image); + QString getMimeType(const QString& videoFile); + QString getExtension(const QString& videoFilename); + + + private: + int videoStream; + AVFormatContext *inputVideoFormatContext; + AVCodecContext *inputvideoCodecContext; + AVCodec *inputVideoCodec; + AVStream *inputVideoStream; + AVFrame *inputVideoFrame; + quint8 *inputFrameBuffer; + AVPacket *videoPacket; + + +#endif // VIDNAIL_H diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.h b/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.h new file mode 100644 index 00000000..e13894e1 --- /dev/null +++ b/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.h @@ -0,0 +1,13 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2017, q5sys +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "vidnail.h" + +VidNail::VidNail(QObject *parent) : QObject(parent){ +} + +VidNail::~VidNail(){ +} diff --git a/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp b/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp index 52a29c01..9e4ce499 100644 --- a/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp +++ b/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp @@ -496,11 +496,14 @@ void MainUI::closeEvent(QCloseEvent *ev){ unsaved << tmp->currentFile(); } } - bool quitnow = unsaved.isEmpty(); - if(!quitnow && !ui->actionShow_Popups->isChecked()){ quitnow = true; } - if(!quitnow){ - quitnow = (QMessageBox::Yes == QMessageBox::question(this, tr("Lose Unsaved Changes?"), QString(tr("There are unsaved changes.\nDo you want to close the editor anyway?\n\n%1")).arg(unsaved.join("\n")), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) ); - } - if(quitnow){ QMainWindow::closeEvent(ev); } - else{ ev->ignore(); } + 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; } + } + if(savenow){ SaveFile(); } + QMainWindow::closeEvent(ev); } diff --git a/src-qt5/desktop-utils/lumina-textedit/MainUI.ui b/src-qt5/desktop-utils/lumina-textedit/MainUI.ui index de5c1ee1..fec94a21 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>21</height> + <height>28</height> </rect> </property> <property name="contextMenuPolicy"> @@ -437,6 +437,11 @@ </property> </action> </widget> + <tabstops> + <tabstop>line_find</tabstop> + <tabstop>line_replace</tabstop> + <tabstop>tool_hideReplaceGroup</tabstop> + </tabstops> <resources/> <connections/> </ui> diff --git a/src-qt5/desktop-utils/lumina-xdg-entry/mainwindow.cpp b/src-qt5/desktop-utils/lumina-xdg-entry/mainwindow.cpp index 7b34935e..1ad6edcd 100644 --- a/src-qt5/desktop-utils/lumina-xdg-entry/mainwindow.cpp +++ b/src-qt5/desktop-utils/lumina-xdg-entry/mainwindow.cpp @@ -1,7 +1,7 @@ //=========================================== // Copyright (c) 2017, q5sys (JT) // Available under the MIT license -// See the LICENSE file for full details +// See the LICENSE file for full details //=========================================== #include "mainwindow.h" diff --git a/src-qt5/experimental/lumina-terminal/i18n/l-terminal_et.ts b/src-qt5/experimental/lumina-terminal/i18n/l-terminal_et.ts index f14c723f..e4175b01 100644 --- a/src-qt5/experimental/lumina-terminal/i18n/l-terminal_et.ts +++ b/src-qt5/experimental/lumina-terminal/i18n/l-terminal_et.ts @@ -6,12 +6,12 @@ <message> <location filename="../TerminalWidget.cpp" line="61"/> <source>Copy Selection</source> - <translation type="unfinished"></translation> + <translation>Kopeeri valitu</translation> </message> <message> <location filename="../TerminalWidget.cpp" line="62"/> <source>Paste</source> - <translation type="unfinished"></translation> + <translation>Aseta</translation> </message> </context> <context> @@ -29,17 +29,17 @@ <message> <location filename="../TrayIcon.cpp" line="130"/> <source>Close Terminal</source> - <translation type="unfinished"></translation> + <translation>Sulge Terminal</translation> </message> <message> <location filename="../TrayIcon.cpp" line="139"/> <source>Move To Monitor</source> - <translation type="unfinished"></translation> + <translation>Liiguta ekraanile</translation> </message> <message> <location filename="../TrayIcon.cpp" line="142"/> <source>Monitor %1</source> - <translation type="unfinished"></translation> + <translation>Ekraan %1</translation> </message> </context> <context> @@ -47,67 +47,67 @@ <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="603"/> <source>Multimedia</source> - <translation type="unfinished"></translation> + <translation>Multimeedia</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="604"/> <source>Development</source> - <translation type="unfinished"></translation> + <translation>Arendus</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="605"/> <source>Education</source> - <translation type="unfinished"></translation> + <translation>Haridus</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="606"/> <source>Games</source> - <translation type="unfinished"></translation> + <translation>Mängud</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="607"/> <source>Graphics</source> - <translation type="unfinished"></translation> + <translation>Graafika</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="608"/> <source>Network</source> - <translation type="unfinished"></translation> + <translation>Võrk</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="609"/> <source>Office</source> - <translation type="unfinished"></translation> + <translation>Kontor</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="610"/> <source>Science</source> - <translation type="unfinished"></translation> + <translation>Teadus</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="611"/> <source>Settings</source> - <translation type="unfinished"></translation> + <translation>Sätted</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="612"/> <source>System</source> - <translation type="unfinished"></translation> + <translation>Süsteem</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="613"/> <source>Utility</source> - <translation type="unfinished"></translation> + <translation>Tööriistad</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="614"/> <source>Wine</source> - <translation type="unfinished"></translation> + <translation>Wine</translation> </message> <message> <location filename="../../../core/libLumina/LuminaXDG.cpp" line="615"/> <source>Unsorted</source> - <translation type="unfinished"></translation> + <translation>Sorteerimata</translation> </message> </context> </TS> diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.cpp b/src-qt5/src-cpp/NativeEmbedWidget.cpp index 876c701d..57b6edde 100644 --- a/src-qt5/core/libLumina/NativeEmbedWidget.cpp +++ b/src-qt5/src-cpp/NativeEmbedWidget.cpp @@ -116,7 +116,8 @@ void NativeEmbedWidget::showWindow(){ } QImage NativeEmbedWidget::windowImage(QRect geom){ - if(DISABLE_COMPOSITING){ + //if(DISABLE_COMPOSITING){ + if(!this->isVisible()){ return QImage(); } //nothing to grab yet QList<QScreen*> screens = static_cast<QApplication*>( QApplication::instance() )->screens(); //for(int i=0; i<screens.length(); i++){ //if(screens[i]->contains(this)){ @@ -126,7 +127,7 @@ QImage NativeEmbedWidget::windowImage(QRect geom){ //} //} return QImage(); - }else{ + /*}else{ //Pull the XCB pixmap out of the compositing layer xcb_pixmap_t pix = xcb_generate_id(QX11Info::connection()); xcb_composite_name_window_pixmap(QX11Info::connection(), WIN->id(), pix); @@ -144,7 +145,7 @@ QImage NativeEmbedWidget::windowImage(QRect geom){ xcb_free_pixmap(QX11Info::connection(), pix); return img; - } + }*/ } void NativeEmbedWidget::setWinUnpaused(){ paused = false; @@ -154,6 +155,7 @@ void NativeEmbedWidget::setWinUnpaused(){ }else if(this->isVisible()){ showWindow(); } + resyncWindow(); //make sure the window knows about the new location } // ============ // PUBLIC @@ -203,6 +205,7 @@ bool NativeEmbedWidget::embedWindow(NativeWindow *window){ registerClientEvents(this->winId()); //child events get forwarded through the frame - watch this for changes too //Also use a partial-composite here - make sure the window pixmap is available even when the window is obscured xcb_composite_redirect_window(QX11Info::connection(), WIN->id(), XCB_COMPOSITE_REDIRECT_AUTOMATIC); + //xcb_composite_redirect_subwindows(QX11Info::connection(), WIN->id(), XCB_COMPOSITE_REDIRECT_MANUAL); //Also alert us when the window visual changes Damage dmgID = XDamageCreate(QX11Info::display(), WIN->id(), XDamageReportRawRectangles); @@ -264,10 +267,10 @@ void NativeEmbedWidget::resume(){ void NativeEmbedWidget::resyncWindow(){ if(WIN==0){ return; } - syncWinSize(); - if(DISABLE_COMPOSITING){ + //syncWinSize(); + //if(DISABLE_COMPOSITING){ // Specs say to send an artificial configure event to the window if the window was reparented into the frame - QPoint loc = this->mapToGlobal( QPoint(0,0)); + QPoint loc = this->mapToGlobal( QPoint(0,0) ); //Send an artificial configureNotify event to the window with the global position/size included xcb_configure_notify_event_t *event = (xcb_configure_notify_event_t*) calloc(32,1); //always 32-byes long, even if we don't need all of it event->x = loc.x(); @@ -283,12 +286,12 @@ void NativeEmbedWidget::resyncWindow(){ xcb_send_event(QX11Info::connection(), false, WIN->id(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY, (char *) event); xcb_flush(QX11Info::connection()); free(event); - }else{ + /*}else{ //Window is floating invisibly - make sure it is in the right place //Make sure the window size is syncronized and visual up to date //syncWinSize(); QTimer::singleShot(10, this, SLOT(repaintWindow()) ); - } + }*/ } @@ -328,11 +331,13 @@ void NativeEmbedWidget::hideEvent(QHideEvent *ev){ } void NativeEmbedWidget::paintEvent(QPaintEvent *ev){ + QPainter P(this); + P.setClipping(true); + P.setClipRect(0,0,this->width(), this->height()); + P.fillRect(ev->rect(), Qt::transparent); if(WIN==0){ return; } QRect geom = ev->rect(); //atomic updates //qDebug() << "Paint Rect:" << geom; - //geom.adjust(-10,-10,10,10); //add an additional few pixels in each direction to be painted - //geom = geom.intersected(QRect(0,0,this->width(), this->height())); //ensure intersection with actual window QImage img; if(!paused){ img = windowImage(geom); } else if(!winImage.isNull()){ @@ -340,23 +345,8 @@ void NativeEmbedWidget::paintEvent(QPaintEvent *ev){ else{ img = winImage.scaled(geom.size()); } //this is a fast transformation - might be slightly distorted } //Need to paint the image from the window onto the widget as an overlay + P.drawImage( geom , img, QRect(QPoint(0,0), img.size()), Qt::NoOpaqueDetection); //1-to-1 mapping - QPainter P(this); - P.setClipping(true); - P.setClipRect(0,0,this->width(), this->height()); - if(DISABLE_COMPOSITING){ P.fillRect(geom, Qt::black); } //get weird effects when partial-compositing is enabled if you layer transparent window frames above other windows - //qDebug() << "Paint Embed Window:" << geom << winImage.size(); - //if(winImage.size() == this->size()){ - P.drawImage( geom , img, QRect(QPoint(0,0), img.size()), Qt::NoOpaqueDetection); //1-to-1 mapping - //Note: Qt::NoOpaqueDetection Speeds up the paint by bypassing the checks to see if there are [semi-]transparent pixels - // Since this is an embedded image - we fully expect there to be transparency all/most of the time. - // }else{ - //P.drawImage( geom , winImage); //auto-scale it to fit (transforming a static image while paused?) - // } - //else{ QImage scaled = winImage.scaled(geom.size()); P.drawImage(geom, scaled); } - //P.drawImage( geom , winImage, geom, Qt::NoOpaqueDetection); //1-to-1 mapping - //Note: Qt::NoOpaqueDetection Speeds up the paint by bypassing the checks to see if there are [semi-]transparent pixels - // Since this is an embedded image - we fully expect there to be transparency all/most of the time. } diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.h b/src-qt5/src-cpp/NativeEmbedWidget.h index 16bb46dc..16bb46dc 100644 --- a/src-qt5/core/libLumina/NativeEmbedWidget.h +++ b/src-qt5/src-cpp/NativeEmbedWidget.h diff --git a/src-qt5/core/libLumina/NativeEventFilter.cpp b/src-qt5/src-cpp/NativeEventFilter.cpp index c13c1fc8..c13c1fc8 100644 --- a/src-qt5/core/libLumina/NativeEventFilter.cpp +++ b/src-qt5/src-cpp/NativeEventFilter.cpp diff --git a/src-qt5/core/libLumina/NativeEventFilter.h b/src-qt5/src-cpp/NativeEventFilter.h index a3be3ef1..a3be3ef1 100644 --- a/src-qt5/core/libLumina/NativeEventFilter.h +++ b/src-qt5/src-cpp/NativeEventFilter.h diff --git a/src-qt5/core/libLumina/NativeKeyToQt.cpp b/src-qt5/src-cpp/NativeKeyToQt.cpp index 06056be7..06056be7 100644 --- a/src-qt5/core/libLumina/NativeKeyToQt.cpp +++ b/src-qt5/src-cpp/NativeKeyToQt.cpp diff --git a/src-qt5/core/libLumina/NativeWindow.cpp b/src-qt5/src-cpp/NativeWindow.cpp index 02cc001e..02cc001e 100644 --- a/src-qt5/core/libLumina/NativeWindow.cpp +++ b/src-qt5/src-cpp/NativeWindow.cpp diff --git a/src-qt5/core/libLumina/NativeWindow.h b/src-qt5/src-cpp/NativeWindow.h index 67436259..67436259 100644 --- a/src-qt5/core/libLumina/NativeWindow.h +++ b/src-qt5/src-cpp/NativeWindow.h diff --git a/src-qt5/core/libLumina/NativeWindow.pri b/src-qt5/src-cpp/NativeWindow.pri index c906d6fd..c2ac0137 100644 --- a/src-qt5/core/libLumina/NativeWindow.pri +++ b/src-qt5/src-cpp/NativeWindow.pri @@ -2,7 +2,6 @@ # Files QT *= x11extras LIBS *= -lc -lxcb -lxcb-ewmh -lxcb-icccm -lxcb-image -lxcb-composite -lxcb-damage -lxcb-util -lxcb-keysyms -lXdamage -#QT *= -lxcb-render -lxcb-render-util SOURCES *= $${PWD}/NativeWindow.cpp \ $${PWD}/NativeWindowSystem.cpp \ diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/src-cpp/NativeWindowSystem.cpp index 0ee65929..e8e9655a 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/src-cpp/NativeWindowSystem.cpp @@ -492,7 +492,27 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native } if(props.contains(NativeWindow::WinTypes)){ QList< NativeWindow::Type> types; - types << NativeWindow::T_NORMAL; //make this load appropriately later + xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_window_type_unchecked(&obj->EWMH, win->id()); + xcb_ewmh_get_atoms_reply_t reply; + if(1==xcb_ewmh_get_wm_window_type_reply(&obj->EWMH, cookie, &reply, NULL) ){ + for(unsigned int i=0; i<reply.atoms_len; i++){ + if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DESKTOP){ types << NativeWindow::T_DESKTOP; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DOCK){ types << NativeWindow::T_DOCK; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_TOOLBAR){ types << NativeWindow::T_TOOLBAR; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_MENU){ types << NativeWindow::T_MENU; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_UTILITY){ types << NativeWindow::T_UTILITY; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_SPLASH){ types << NativeWindow::T_SPLASH; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DIALOG){ types << NativeWindow::T_DIALOG; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DROPDOWN_MENU){ types << NativeWindow::T_DROPDOWN_MENU; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_POPUP_MENU){ types << NativeWindow::T_POPUP_MENU; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_TOOLTIP){ types << NativeWindow::T_TOOLTIP; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_NOTIFICATION){ types << NativeWindow::T_NOTIFICATION; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_COMBO){ types << NativeWindow::T_COMBO; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_DND){ types << NativeWindow::T_DND; } + else if(reply.atoms[i]==obj->EWMH._NET_WM_WINDOW_TYPE_NORMAL){ types << NativeWindow::T_NORMAL; } + } + } + if(types.isEmpty()){ types << NativeWindow::T_NORMAL; } win->setProperty(NativeWindow::WinTypes, QVariant::fromValue< QList<NativeWindow::Type> >(types) ); } } diff --git a/src-qt5/core/libLumina/NativeWindowSystem.h b/src-qt5/src-cpp/NativeWindowSystem.h index b67ecc94..b67ecc94 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.h +++ b/src-qt5/src-cpp/NativeWindowSystem.h diff --git a/src-qt5/src-cpp/plugins-screensaver.cpp b/src-qt5/src-cpp/plugins-screensaver.cpp new file mode 100644 index 00000000..75e93c9d --- /dev/null +++ b/src-qt5/src-cpp/plugins-screensaver.cpp @@ -0,0 +1,150 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "plugins-screensaver.h" +#include <QJsonDocument> +#include <QJsonArray> +#include <QFile> +#include <QDir> +#include <QDebug> + +//Relative directory to search along the XDG paths for screensavers +#define REL_DIR QString("/lumina-desktop/screensavers") + +// ============ +// SS PLUGIN +// ============ +SSPlugin::SSPlugin(){ + +} + +SSPlugin::~SSPlugin(){ + +} + +void SSPlugin::loadFile(QString path){ + data = QJsonObject(); + currentfile = path; + QFile file(path); + if(!file.exists() || !file.open(QIODevice::ReadOnly)){ return; } + data = QJsonDocument::fromJson(file.readAll()).object(); + file.close(); +} + +bool SSPlugin::isLoaded(){ + return !data.isEmpty(); +} + +bool SSPlugin::isValid(){ + if(data.isEmpty()){ return false; } + bool ok = data.contains("name") && data.contains("qml") && data.contains("description"); + if(ok){ + //go to the next name level and see if required sub-items exist + QJsonObject tmp = data.value("name").toObject(); + ok = tmp.contains("default"); + } + if(ok){ + //go to the next description level and see if required sub-items exist + QJsonObject tmp = data.value("description").toObject(); + ok = tmp.contains("default"); + } +if(ok){ + //go to the next qml level and see if required sub-items exist + QJsonObject tmp = data.value("qml").toObject(); + QStringList mustexist; + QString exec = tmp.value("exec").toString(); + if(exec.isEmpty() || !exec.endsWith(".qml")){ return false; } + mustexist << exec; + QJsonArray tmpA = data.value("additional_files").toArray(); + for(int i=0; i<tmpA.count(); i++){ mustexist << tmpA[i].toString(); } + QString reldir = currentfile.section("/",0,-2) + "/"; + //qDebug() << "Got MustExist:" << mustexist << reldir; + for(int i=0; i<mustexist.length() && ok; i++){ + if(mustexist[i].startsWith("/")){ ok = QFile::exists(mustexist[i]); } + else { ok = QFile::exists(reldir+mustexist[i]); } + } + } + return ok; +} + +QString SSPlugin::translatedName(){ + QJsonObject tmp = data.value("name").toObject(); + //Get the current locale + QString locale = getenv("LC_ALL"); + if(locale.isEmpty()){ locale = getenv("LC_MESSAGES"); } + if(locale.isEmpty()){ locale = getenv("LANG"); } + if(locale.isEmpty()){ locale = "default"; } + if(locale.contains(".")){ locale = locale.section(".",0,0); } //chop any charset code off the end + //Now find which localized string is available and return it + if(tmp.contains(locale)){ return tmp.value(locale).toString(); } + locale = locale.section("_",0,0); //full locale not found - look for shortened form + if(tmp.contains(locale)){ return tmp.value(locale).toString(); } + return tmp.value("default").toString(); //use the default version +} + +QString SSPlugin::translatedDescription(){ + QJsonObject tmp = data.value("description").toObject(); + //Get the current locale + QString locale = getenv("LC_ALL"); + if(locale.isEmpty()){ locale = getenv("LC_MESSAGES"); } + if(locale.isEmpty()){ locale = getenv("LANG"); } + if(locale.isEmpty()){ locale = "default"; } + if(locale.contains(".")){ locale = locale.section(".",0,0); } //chop any charset code off the end + //Now find which localized string is available and return it + if(tmp.contains(locale)){ return tmp.value(locale).toString(); } + locale = locale.section("_",0,0); //full locale not found - look for shortened form + if(tmp.contains(locale)){ return tmp.value(locale).toString(); } + return tmp.value("default").toString(); //use the default version +} + +QUrl SSPlugin::scriptURL(){ + QString exec = data.value("qml").toObject().value("exec").toString(); + //qDebug() << "got exec:" << exec; + if(!exec.startsWith("/")){ exec.prepend( currentfile.section("/",0,-2)+"/" ); } + return QUrl::fromLocalFile(exec); +} + +// =================== +// SS PLUGIN SYSTEM +// =================== +SSPlugin SSPluginSystem::findPlugin(QString name){ + SSPlugin SSP; + if(name.startsWith("/") && QFile::exists(name)){ SSP.loadFile(name); return SSP;} //absolute path give - just load that one + //Cleanup the input name and ensure it has the right suffix + name = name.section("/",-1); + if(!name.endsWith(".json")){ name.append(".json"); } + //Get the list of directories to search + QStringList dirs; + dirs << QString(getenv("XDG_DATA_HOME")) << QString(getenv("XDG_DATA_DIRS")).split(":"); + //Look for that file within these directories and return the first one found + for(int i=0; i<dirs.length(); i++){ + if(!QFile::exists(dirs[i]+REL_DIR+"/"+name)){ continue; } + SSP.loadFile(dirs[i]+REL_DIR+"/"+name); + if(SSP.isValid()){ break; } //got a good one - stop here + } + return SSP; +} + +QList<SSPlugin> SSPluginSystem::findAllPlugins(bool validonly){ + QList<SSPlugin> LIST; + //Get the list of directories to search + QStringList dirs; + dirs << QString(getenv("XDG_DATA_HOME")) << QString(getenv("XDG_DATA_DIRS")).split(":"); + //Look for that file within these directories and return the first one found + for(int i=0; i<dirs.length(); i++){ + if(!QFile::exists(dirs[i]+REL_DIR)){ continue; } + QDir dir(dirs[i]+REL_DIR); + QStringList files = dir.entryList(QStringList() << "*.json", QDir::Files, QDir::Name); + //qDebug() << "Found Files:" << files; + for(int j=0; j<files.length(); j++){ + SSPlugin tmp; + tmp.loadFile(dir.absoluteFilePath(files[j])); + //qDebug() << "Loaded File:" << files[j] << tmp.isValid(); + if(!validonly || tmp.isValid()){ LIST << tmp; } + } + } + return LIST; +} diff --git a/src-qt5/src-cpp/plugins-screensaver.h b/src-qt5/src-cpp/plugins-screensaver.h new file mode 100644 index 00000000..9a7e98f5 --- /dev/null +++ b/src-qt5/src-cpp/plugins-screensaver.h @@ -0,0 +1,50 @@ +//=========================================== +// Lumina-desktop source code +// Copyright (c) 2017, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +// This is a simple class for managing all the various desktop +// screensaver plugins that could be available +//=========================================== +// NOTE: +// This class has a heirarchy-based lookup system +// USER plugins > SYSTEM plugins +// XDG_DATA_HOME/lumina-desktop/screensavers > XDG_DATA_DIRS/lumina-desktop/screensavers +//=========================================== +#ifndef _LUMINA_DESKTOP_SCREENSAVER_PLUGINS_CLASS_H +#define _LUMINA_DESKTOP_SCREENSAVER_PLUGINS_CLASS_H + +#include <QJsonObject> +#include <QString> +#include <QUrl> +#include <QObject> + +class SSPlugin{ +private: + QString currentfile; + +public: + QJsonObject data; //Hazardous to manually modify + + SSPlugin(); + ~SSPlugin(); + + void loadFile(QString path); + bool isLoaded(); + + bool isValid(); + + QString translatedName(); + QString translatedDescription(); + QUrl scriptURL(); +}; + +class SSPluginSystem{ +public: + static SSPlugin findPlugin(QString name); + static QList<SSPlugin> findAllPlugins(bool validonly = true); + +}; + +#endif diff --git a/src-qt5/src-cpp/plugins-screensaver.pri b/src-qt5/src-cpp/plugins-screensaver.pri new file mode 100644 index 00000000..ad03f34c --- /dev/null +++ b/src-qt5/src-cpp/plugins-screensaver.pri @@ -0,0 +1,4 @@ +HEADERS *= $${PWD}/plugins-screensaver.h +SOURCES *= $${PWD}/plugins-screensaver.cpp + +INCLUDEPATH *= $${PWD} diff --git a/src-qt5/src-qml/test/CPUGaugeStyle.qml b/src-qt5/src-qml/test/CPUGaugeStyle.qml new file mode 100644 index 00000000..4728d136 --- /dev/null +++ b/src-qt5/src-qml/test/CPUGaugeStyle.qml @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls.Styles 1.4 + +CircularGaugeStyle { + id: cpugauge + tickmarkInset: toPixels(0.04) + minorTickmarkInset: tickmarkInset + labelStepSize: 20 + labelInset: toPixels(0.23) + + property real xCenter: outerRadius + property real yCenter: outerRadius + property real needleLength: outerRadius - tickmarkInset * 1.25 + property real needleTipWidth: toPixels(0.02) + property real needleBaseWidth: toPixels(0.06) + property bool halfGauge: false + + function toPixels(percentage) { + return percentage * outerRadius; + } + + function degToRad(degrees) { + return degrees * (Math.PI / 180); + } + + function radToDeg(radians) { + return radians * (180 / Math.PI); + } + + function paintBackground(ctx) { + if (halfGauge) { + ctx.beginPath(); + ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height / 2); + ctx.clip(); + } + + ctx.beginPath(); + ctx.fillStyle = "black"; + ctx.ellipse(0, 0, ctx.canvas.width, ctx.canvas.height); + ctx.fill(); + + ctx.beginPath(); + ctx.lineWidth = tickmarkInset; + ctx.strokeStyle = "black"; + ctx.arc(xCenter, yCenter, outerRadius - ctx.lineWidth / 2, outerRadius - ctx.lineWidth / 2, 0, Math.PI * 2); + ctx.stroke(); + + ctx.beginPath(); + ctx.lineWidth = tickmarkInset / 2; + ctx.strokeStyle = "#222"; + ctx.arc(xCenter, yCenter, outerRadius - ctx.lineWidth / 2, outerRadius - ctx.lineWidth / 2, 0, Math.PI * 2); + ctx.stroke(); + + ctx.beginPath(); + var gradient = ctx.createRadialGradient(xCenter, yCenter, outerRadius * 0.8, xCenter, yCenter, outerRadius); + gradient.addColorStop(0, Qt.rgba(1, 1, 1, 0)); + gradient.addColorStop(0.7, Qt.rgba(1, 1, 1, 0.13)); + gradient.addColorStop(1, Qt.rgba(1, 1, 1, 1)); + ctx.fillStyle = gradient; + ctx.arc(xCenter, yCenter, outerRadius - tickmarkInset, outerRadius - tickmarkInset, 0, Math.PI * 2); + ctx.fill(); + } + + background: Canvas { + onPaint: { + var ctx = getContext("2d"); + ctx.reset(); + paintBackground(ctx); + } + + } + + needle: Canvas { + implicitWidth: needleBaseWidth + implicitHeight: needleLength + + property real xCenter: width / 2 + property real yCenter: height / 2 + + onPaint: { + var ctx = getContext("2d"); + ctx.reset(); + + ctx.beginPath(); + ctx.moveTo(xCenter, height); + ctx.lineTo(xCenter - needleBaseWidth / 2, height - needleBaseWidth / 2); + ctx.lineTo(xCenter - needleTipWidth / 2, 0); + ctx.lineTo(xCenter, yCenter - needleLength); + ctx.lineTo(xCenter, 0); + ctx.closePath(); + ctx.fillStyle = Qt.rgba(0.66, 0, 0, 0.66); + ctx.fill(); + + ctx.beginPath(); + ctx.moveTo(xCenter, height) + ctx.lineTo(width, height - needleBaseWidth / 2); + ctx.lineTo(xCenter + needleTipWidth / 2, 0); + ctx.lineTo(xCenter, 0); + ctx.closePath(); + ctx.fillStyle = Qt.lighter(Qt.rgba(0.66, 0, 0, 0.66)); + ctx.fill(); + } + } + + foreground: null +} diff --git a/src-qt5/src-qml/test/Clock.qml b/src-qt5/src-qml/test/Clock.qml new file mode 100644 index 00000000..685346cb --- /dev/null +++ b/src-qt5/src-qml/test/Clock.qml @@ -0,0 +1,101 @@ +import QtQuick 2.0 +import QtGraphicalEffects 1.0 + +Item { + id : clock + width: { + if (ListView.view && ListView.view.width >= 400) + return ListView.view.width / Math.floor(ListView.view.width / 400.0); + else + return 400; + } + + height: { + if (ListView.view && ListView.view.height >= 440) + return ListView.view.height; + else + return 440; + } + + property alias city: cityLabel.text + property int hours + property int minutes + property int seconds + property real shift + property bool night: false + property bool internationalTime: true //Unset for local time + + function timeChanged() { + var date = new Date; + hours = internationalTime ? date.getUTCHours() + Math.floor(clock.shift) : date.getHours() + night = ( hours < 7 || hours > 19 ) + minutes = internationalTime ? date.getUTCMinutes() + ((clock.shift % 1) * 60) : date.getMinutes() + seconds = date.getUTCSeconds(); + } + + Timer { + interval: 100; running: true; repeat: true; + onTriggered: clock.timeChanged() + } + + Item { + anchors.centerIn: parent + width: 200; height: 240 + Rectangle { anchors.fill: parent; color: "#80ff0000"; border.color: "red"; } + + Image { id: background; source: "clock.png"; visible: clock.night == false } + Image { source: "clock-night.png"; visible: clock.night == true } + + Image { + x: 92.5; y: 27 + source: "hour.png" + transform: Rotation { + id: hourRotation + origin.x: 7.5; origin.y: 73; + angle: (clock.hours * 30) + (clock.minutes * 0.5) + Behavior on angle { + SpringAnimation { spring: 2; damping: 0.2; modulus: 360 } + } + } + } + + Image { + x: 93.5; y: 17 + source: "minute.png" + transform: Rotation { + id: minuteRotation + origin.x: 6.5; origin.y: 83; + angle: clock.minutes * 6 + Behavior on angle { + SpringAnimation { spring: 2; damping: 0.2; modulus: 360 } + } + } + } + + Image { + x: 97.5; y: 20 + source: "second.png" + transform: Rotation { + id: secondRotation + origin.x: 2.5; origin.y: 80; + angle: clock.seconds * 6 + Behavior on angle { + SpringAnimation { spring: 2; damping: 0.2; modulus: 360 } + } + } + } + + Image { + anchors.centerIn: background; source: "center.png" + } + + Text { + id: cityLabel + y: 210; anchors.horizontalCenter: parent.horizontalCenter + color: "white" + font.family: "Helvetica" + font.bold: true; font.pixelSize: 16 + style: Text.Raised; styleColor: "black" + } + } +} diff --git a/src-qt5/src-qml/test/File.qml b/src-qt5/src-qml/test/File.qml new file mode 100644 index 00000000..4713a454 --- /dev/null +++ b/src-qt5/src-qml/test/File.qml @@ -0,0 +1,21 @@ +import QtQuick 2.0 +import Qt.labs.folderlistmodel 2.1 + +ListView { + width: 200; height: 400 + + + FolderListModel { + id: folderModel + folder: "/usr/local/videos" + } + + Component { + id: fileDelegate + Text { text: fileName } + } + + model: folderModel + delegate: fileDelegate + Component.onCompleted: { console.log(folderModel.count) } +} diff --git a/src-qt5/src-qml/test/ListData.h b/src-qt5/src-qml/test/ListData.h new file mode 100644 index 00000000..7dd6f6e2 --- /dev/null +++ b/src-qt5/src-qml/test/ListData.h @@ -0,0 +1,41 @@ +#include <QDebug> +#include <QApplication> +#include <QQuickView> +#include <QQmlEngine> +#include <QQmlContext> +#include <QObject> +#include <QStringList> +#include <QTimer> + +class ListData : public QObject{ + Q_OBJECT + Q_PROPERTY(QList<QScreen*> list READ list NOTIFY listchanged); +signals: + void listchanged(); + +private: + QStringList m_list; + //QTimer *timer; + //bool increasing; + +private slots: + void changeList(){ + /*if(m_list.isEmpty()){ increasing = true; } + else if(m_list.length() == 5){ increasing = false; } + if(increasing){ m_list << "Text - "+QString::number( m_list.length()+1 ); } + else{ m_list.takeAt(m_list.count()-1); } + emit listchanged();*/ + } + +public: + ListData() : QObject(){ + /*increasing = true; + timer = new QTimer(this); + timer->setInterval(1000); + timer->setSingleShot(false); + connect(timer, SIGNAL(timeout()), this, SLOT(changeList()) ); + timer->start();*/ + } + + QList<QScreen*> list() { return QApplication::screens(); } //m_list; } +}; diff --git a/src-qt5/src-qml/test/ListTest.qml b/src-qt5/src-qml/test/ListTest.qml new file mode 100644 index 00000000..e6b6ba35 --- /dev/null +++ b/src-qt5/src-qml/test/ListTest.qml @@ -0,0 +1,19 @@ +import QtQuick 2.2 +import QtQuick.Layouts 1.3 + +Rectangle { + id: canvas + color: "black" + + ColumnLayout{ + anchors.fill: canvas + + Repeater{ + model: cppdata.list + Text{ + color: "white" + text: modelData + } + } + } //end row layout +} diff --git a/src-qt5/src-qml/test/Video.qml b/src-qt5/src-qml/test/Video.qml new file mode 100644 index 00000000..e7d0626d --- /dev/null +++ b/src-qt5/src-qml/test/Video.qml @@ -0,0 +1,50 @@ +import QtQuick 2.0 +import QtMultimedia 5.7 +import QtQuick.Window 2.2 +import Qt.labs.folderlistmodel 2.1 + +Rectangle { + //width: Screen.width + //height: Screen.height + width: 800 + height: 600 + color: "black" + + FolderListModel { + id: folderModel + folder: "/usr/local/videos" + } + + Repeater { + model: folderModel + Component { + Item { + Component.onCompleted: { playlist.addItem(fileURL) } + } + } + } + + Playlist { + id: playlist + playbackMode: Playlist.Random + PlaylistItem { source: "/" } + onError: { console.log("ERROR") } + } + + MediaPlayer { + id: player + autoPlay: true + playlist: playlist + } + + VideoOutput { + id: videoOutput + source: player + anchors.fill: parent + } + + Component.onCompleted: { + playlist.shuffle() + console.log(playlist.itemCount) + } +} diff --git a/src-qt5/src-qml/test/main.cpp b/src-qt5/src-qml/test/main.cpp new file mode 100644 index 00000000..e65c599f --- /dev/null +++ b/src-qt5/src-qml/test/main.cpp @@ -0,0 +1,28 @@ +#include <QDebug> +#include <QApplication> +#include <QQuickView> + +int main(int argc, char** argv){ + QString QMLFile; + for(int i=1; i<argc; i++){ + if(QFile::exists(argv[i])){ QMLFile = QString(argv[i]); } + } + if(QMLFile.isEmpty()){ + qDebug() << "No QML File provided!"; + qDebug() << " Please provide a valid qml file path as an input argument"; + return 1; + } + QApplication A(argc,argv); + qDebug() << "Creating base widget"; + QQuickView base; + base.setResizeMode(QQuickView::SizeRootObjectToView); + qDebug() << "Resize base widget"; + base.resize(1024,768); + qDebug() << "Load QML File:" << QMLFile; + base.setSource(QUrl::fromLocalFile(QMLFile)); + qDebug() << "Start Event loop"; + base.show(); + int ret = A.exec(); + qDebug() << " - Finished"; + return ret; +} diff --git a/src-qt5/src-qml/test/test-basic.qml b/src-qt5/src-qml/test/test-basic.qml new file mode 100644 index 00000000..5d21ae41 --- /dev/null +++ b/src-qt5/src-qml/test/test-basic.qml @@ -0,0 +1,48 @@ +import QtQuick 2.0 +import "." as QML + +Rectangle { + id: root + width: 800; height: 600 + color: "#646464" + + ListView { + id: clockview + anchors.fill: parent + orientation: ListView.Horizontal + cacheBuffer: 2000 + snapMode: ListView.SnapOneItem + highlightRangeMode: ListView.ApplyRange + + delegate: QML.Clock { city: cityName; shift: timeShift } + model: ListModel { + ListElement { cityName: "New York"; timeShift: -4 } + ListElement { cityName: "London"; timeShift: 0 } + ListElement { cityName: "Oslo"; timeShift: 1 } + ListElement { cityName: "Mumbai"; timeShift: 5.5 } + ListElement { cityName: "Tokyo"; timeShift: 9 } + ListElement { cityName: "Brisbane"; timeShift: 10 } + ListElement { cityName: "Los Angeles"; timeShift: -8 } + } + } + + Image { + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.margins: 10 + source: "content/arrow.png" + rotation: -90 + opacity: clockview.atXBeginning ? 0 : 0.5 + Behavior on opacity { NumberAnimation { duration: 500 } } + } + + Image { + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.margins: 10 + source: "content/arrow.png" + rotation: 90 + opacity: clockview.atXEnd ? 0 : 0.5 + Behavior on opacity { NumberAnimation { duration: 500 } } + } +} diff --git a/src-qt5/src-qml/test/test-cpugauge.qml b/src-qt5/src-qml/test/test-cpugauge.qml new file mode 100644 index 00000000..1151c435 --- /dev/null +++ b/src-qt5/src-qml/test/test-cpugauge.qml @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Window 2.1 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Extras 1.4 + +import "." as QML + +Rectangle{ + id: rootwindow + visible: true + width: 800 + height: 600 + + color: "#161616" + property alias cpu: cpu + + Item { + id: container + anchors.fill: parent + property real diff: 5.1 + + Row { + id: gaugeRow + spacing: container.width * 0.02 + anchors.centerIn: parent + + CircularGauge { + id: cpu + width: height + height: container.height * 0.9 - gaugeRow.spacing + value: 0 + maximumValue: 100 + anchors.verticalCenter: parent.verticalCenter + + style: QML.CPUGaugeStyle {} + + } + + function updatevalue() { + if( container.diff >0 && cpu.value > (100-container.diff) ){ + cpu.value = 100; + container.diff = 0 - container.diff + } else if( container.diff <0 && cpu.value <(0-container.diff) ){ + cpu.value = 0; + container.diff = 0 - container.diff + } else { + cpu.value = cpu.value + container.diff + } + } + + Timer { + interval: 100; running: true; repeat: true; + onTriggered: gaugeRow.updatevalue() + } + } + } +} diff --git a/src-qt5/src-qml/test/test.pro b/src-qt5/src-qml/test/test.pro new file mode 100644 index 00000000..41d7d2a2 --- /dev/null +++ b/src-qt5/src-qml/test/test.pro @@ -0,0 +1,5 @@ +QT = core gui widgets quick quickwidgets qml + +TARGET = test + +SOURCES += main.cpp diff --git a/src-qt5/src-qml/test/testlist.cpp b/src-qt5/src-qml/test/testlist.cpp new file mode 100644 index 00000000..cc54c501 --- /dev/null +++ b/src-qt5/src-qml/test/testlist.cpp @@ -0,0 +1,37 @@ +#include <QDebug> +#include <QApplication> +#include <QQuickView> +#include <QQmlEngine> +#include <QQmlContext> +#include <QObject> +#include <QStringList> +#include <QTimer> + +#include "ListData.h" + +int main(int argc, char** argv){ + QString QMLFile; + for(int i=1; i<argc; i++){ + if(QFile::exists(argv[i])){ QMLFile = QString(argv[i]); } + } + if(QMLFile.isEmpty()){ + qDebug() << "No QML File provided!"; + qDebug() << " Please provide a valid qml file path as an input argument"; + return 1; + } + QApplication A(argc,argv); + qDebug() << "Creating base widget"; + ListData data; + QQuickView base; + base.setResizeMode(QQuickView::SizeRootObjectToView); + qDebug() << "Resize base widget"; + base.resize(1024,768); + base.engine()->rootContext()->setContextProperty("cppdata", &data); + qDebug() << "Load QML File:" << QMLFile; + base.setSource(QUrl::fromLocalFile(QMLFile)); + qDebug() << "Start Event loop"; + base.show(); + int ret = A.exec(); + qDebug() << " - Finished"; + return ret; +} diff --git a/src-qt5/src-qml/test/testlist.pro b/src-qt5/src-qml/test/testlist.pro new file mode 100644 index 00000000..69c7bc23 --- /dev/null +++ b/src-qt5/src-qml/test/testlist.pro @@ -0,0 +1,7 @@ +QT = core gui widgets quick quickwidgets qml + +TARGET = test + +SOURCES += testlist.cpp + +HEADERS += ListData.h |