- Bugfixes and cleanup

This commit is contained in:
Dorian Zedler 2020-11-25 14:40:16 +01:00
parent 90c68fcd37
commit e72cdd81df
Signed by: dorian
GPG Key ID: D3B255CB8BC7CD37
40 changed files with 2004 additions and 1451 deletions

View File

@ -1,3 +1,6 @@
# Modern Linbo GUI
A new and more modern GUI for the image manager Linbo (from [linuxmuster.net](https://github.com/linuxmuster/linuxmuster-linbo))
A new and more modern GUI for the image manager Linbo (from [linuxmuster.net](https://github.com/linuxmuster/linuxmuster-linbo))
# Icons
All of the SVG icons in this Gui were taken from [fontawesome.com](https://fontawesome.com/license) and slighlty modified.

View File

@ -40,48 +40,6 @@
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Start</string>
</attribute>
<widget class="Q3ScrollView" name="startView" native="true">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>600</width>
<height>180</height>
</rect>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
</widget>
<widget class="QLabel" name="versionLabel">
<property name="geometry">
<rect>
<x>10</x>
<y>200</y>
<width>600</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>Version</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</widget>
<widget class="QWidget" name="tab">
<property name="autoFillBackground">
<bool>false</bool>

15
forumsbeitrag.md Normal file
View File

@ -0,0 +1,15 @@
Hallo zusammen,
Ich habe vor einiger Zeit mein erstes Linuxmuster.net Netzwerk aufgesetzt und bin begeistert von dem Funktionsumfang, den es bietet. Nur eines stört mich: das GUI von Linbo. Es sieht einfach nicht mehr zeitgemäß aus und viele Leihen sind damit überfordert.
Daher habe ich mir ein bisschen Zeit genommen und angefangen, ein neues GUI für Linbo zu programmieren. Das neue Frontend (Entspricht dem "Start" Tab) ist so gut wie fertig. Für das Imaging habe ich erstmal das alte GUI gelassen, weil der normale Nutzer das eh fast nie zu Gesicht bekommt.
Hier ein kurzes Video mit einer Demo:
Sobald alles richtig funktioniert, werde ich eine Pullrequest bei LinboRepo öffnen.
Hat noch jemand von euch Vorschläge, was geändert werden sollte?
Viele Grüße
Dorian

View File

@ -25,12 +25,8 @@
#include <QProcess>
#include <QTimer>
#include <QElapsedTimer>
#include <vector>
#include <iostream>
#include <fstream>
#include <istream>
#include <stdlib.h>
#include <QFile>
#include <QSettings>
#include "linbologger.h"
#include "linboconfig.h"
@ -46,7 +42,7 @@ class LinboBackend : public QObject
Q_PROPERTY(LinboBackend::LinboState state READ getState NOTIFY stateChanged)
Q_PROPERTY(LinboOs* currentOs READ getCurrentOs WRITE setCurrentOs NOTIFY currentOsChanged)
Q_PROPERTY(double autostartTimeoutProgress READ getAutostartTimeoutProgress NOTIFY autostartTimeoutProgressChanged)
//Q_PROPERTY(int autostartTimeoutRemainingSeconds READ getAutostartTimeoutRemainingSeconds NOTIFY autostartTimeoutProgressChanged)
Q_PROPERTY(int autostartTimeoutRemainingSeconds READ getAutostartTimeoutRemainingSeconds NOTIFY autostartTimeoutProgressChanged)
public:
explicit LinboBackend(QObject *parent = nullptr);
@ -74,11 +70,14 @@ public:
int getAutostartTimeoutRemainingSeconds();
protected:
bool read_pair(ifstream* input, QString& key, QString& value);
void loadStartConfiguration(QString startConfFilePath);
void loadEnvironmentValues();
void writeToLinboConfig(QMap<QString, QString> config, LinboConfig* linboConfig);
void writeToPartitionConfig(QMap<QString, QString> config, LinboDiskPartition* partition);
void writeToOsConfig(QMap<QString, QString> config, LinboOs* os);
bool toBool(const QString& value);
LinboOs* read_os(ifstream* input);
LinboDiskPartition* read_partition(ifstream* input);
void read_globals( ifstream* input, LinboConfig* config );
private:
LinboState state;
@ -138,6 +137,8 @@ public slots:
bool initializeCache();
bool updateLinbo();
bool cancelCurrentAction();
private slots:
void executeAutostart();
void handleAutostartTimerTimeout();

View File

@ -2,6 +2,10 @@
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** Portions of the code in this file are based on code by:
** Copyright (C) 2007 Martin Oehler <oehler@knopper.net>
** Copyright (C) 2007 Klaus Knopper <knopper@knopper.net>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
@ -26,20 +30,20 @@ class LinboConfig : public QObject
public:
friend class LinboBackend;
const QString& getServer() const {return this->server;}
const QString& getServerIpAddress() const {return this->serverIpAddress;}
const QString& getIpAddress() const {return this->ipAddress;}
const QString& getMacAddress() const {return this->macAddress;}
const QString& getVersion() const {return this->version;}
const QString& getLinboVersion() const {return this->LinboVersion;}
const QString& getHostname() const {return this->hostname;}
const QString& getCpu() const {return this->cpu;}
const QString& getCpuModel() const {return this->cpuModel;}
const QString& getRamSize() const {return this->ramSize;}
const QString& getCacheSize() const {return this->cacheSize;}
const QString& getHddSize() const {return this->hddSize;}
const QString& getCache() const {return this->cache;}
const QString& getHostgroup() const {return this->hostgroup;}
const QString& getCachePath() const {return this->cachePath;}
const QString& getHostGroup() const {return this->hostGroup;}
const unsigned int& getRootTimeout() const {return this->rootTimeout;}
const bool& getAutopartition() {return this->autoPartition;}
const bool& getAutoPartition() {return this->autoPartition;}
const bool& getAutoInitCache() {return this->autoInitCache;}
const QString& getBackgroundFontcolor() {return this->backgroundFontcolor;}
const QString& getConsoleFontcolorStdout() {return this->consoleFontcolorStdout;}
@ -47,22 +51,22 @@ public:
const QString& getDownloadType() {return this->downloadType;}
const bool& getAutoFormat() {return this->autoFormat;}
protected:
private:
explicit LinboConfig(QObject *parent = nullptr);
void setServer( const QString& server ) {this->server = server;}
void setServerIpAddress( const QString& serverIpAddress ) {this->serverIpAddress = serverIpAddress;}
void setIpAddress( const QString& ipAddress ) {this->ipAddress = ipAddress;}
void setMacAddress( const QString& macAddress ) {this->macAddress = macAddress;}
void setVersion( const QString& version ) {this->version = version;}
void setLinboVersion( const QString& linboVersion ) {this->LinboVersion = linboVersion;}
void setHostname( const QString& hostname ) {this->hostname = hostname;}
void setCpu( const QString& cpu ) {this->cpu = cpu;}
void setCpuModel( const QString& cpuModel ) {this->cpuModel = cpuModel;}
void setRamSize( const QString& ramSize ) {this->ramSize = ramSize;}
void setCacheSize( const QString& cacheSize ) {this->cacheSize = cacheSize;}
void setHddSize( const QString& hddSize ) {this->hddSize = hddSize;}
void setCache( const QString& cache ) {this->cache = cache;}
void setHostgroup( const QString& hostgroup ) {this->hostgroup = hostgroup;}
void setCachePath( const QString& cachePath ) {this->cachePath = cachePath;}
void setHostGroup( const QString& hostGroup ) {this->hostGroup = hostGroup;}
void setRootTimeout( const unsigned int& rootTimeout ) {this->rootTimeout = rootTimeout;}
void setAutopartition( const bool& autoPartition ){this->autoPartition = autoPartition;}
void setAutoPartition( const bool& autoPartition ){this->autoPartition = autoPartition;}
void setAutoInitCache( const bool& autoInitCache ){this->autoInitCache = autoInitCache;}
void setBackgroundFontcolor( const QString& backgroundFontcolor ){this->backgroundFontcolor = backgroundFontcolor;}
void setConsoleFontcolorStdout( const QString& consoleFontcolorStdout ){this->consoleFontcolorStdout = consoleFontcolorStdout;}
@ -70,10 +74,25 @@ protected:
void setDownloadType( const QString& downloadType ){this->downloadType = downloadType;}
void setAutoFormat( const bool& autoFormat ){this->autoFormat = autoFormat;}
private:
QString server, ipAddress, macAddress, version, hostname, cpu, ramSize, cacheSize, hddSize, cache, hostgroup, downloadType, backgroundFontcolor, consoleFontcolorStdout, consoleFontcolorStderr;
QString serverIpAddress;
QString ipAddress;
QString macAddress;
QString LinboVersion;
QString hostname;
QString cpuModel;
QString ramSize;
QString cacheSize;
QString hddSize;
QString cachePath;
QString hostGroup;
QString downloadType;
QString backgroundFontcolor;
QString consoleFontcolorStdout;
QString consoleFontcolorStderr;
unsigned int rootTimeout;
bool autoPartition, autoInitCache, autoFormat;
bool autoPartition;
bool autoInitCache;
bool autoFormat;
signals:

View File

@ -2,6 +2,10 @@
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** Portions of the code in this file are based on code by:
** Copyright (C) 2007 Martin Oehler <oehler@knopper.net>
** Copyright (C) 2007 Klaus Knopper <knopper@knopper.net>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
@ -33,7 +37,7 @@ public:
const unsigned int& getSize() const {return this->size;}
const bool& getBootable() const {return this->bootable;}
protected:
private:
explicit LinboDiskPartition(QObject *parent = nullptr);
void setPath( const QString& path ) {this->path = path;}
@ -42,10 +46,11 @@ protected:
void setSize( const unsigned int& size ) {this->size = size;}
void setBootable( const bool& bootable ) {this->bootable = bootable;}
private:
QString path, id, fstype;
unsigned int size;
bool bootable;
QString path;
QString id;
QString fstype;
unsigned int size;
bool bootable;
signals:

View File

@ -2,6 +2,10 @@
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** Portions of the code in this file are based on code by:
** Copyright (C) 2007 Martin Oehler <oehler@knopper.net>
** Copyright (C) 2007 Klaus Knopper <knopper@knopper.net>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
@ -37,8 +41,8 @@ protected:
void setName(const QString& name) {this->name = name;}
private:
QString name,
description;
QString name;
QString description;
};

View File

@ -1,9 +1,28 @@
/****************************************************************************
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef LINBOLOGGER_H
#define LINBOLOGGER_H
#include <QObject>
#include <QtDebug>
#include <QDateTime>
#include <QFile>
class LinboLogger : public QObject
{
@ -33,10 +52,12 @@ public:
private:
explicit LinboLogger(QObject *parent = nullptr);
explicit LinboLogger(QString logFilePath, QObject *parent = nullptr);
void log(QString logText, LinboLogType logType);
bool writeToLogFile(QString text);
QString logFilePath;
QList<LinboLog> logHistory;
signals:

View File

@ -2,6 +2,10 @@
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** Portions of the code in this file are based on code by:
** Copyright (C) 2007 Martin Oehler <oehler@knopper.net>
** Copyright (C) 2007 Klaus Knopper <knopper@knopper.net>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
@ -48,74 +52,61 @@ public:
const QString& getKernel() const {return this->kernel;}
const QString& getInitrd() const {return this->initrd;}
const QString& getKernelOptions() const {return this->kernelOptions;}
const bool& getSyncbutton() const {return this->syncButton;}
const bool& getStartbutton() const {return this->startButton;}
const bool& getNewbutton() const {return this->newButton;}
const bool& getAutostart() const {return this->autostart;}
bool getSyncActionEnabled() const {return this->baseImage != nullptr && this->syncButtonEnabled;}
bool getStartActionEnabled() const {return this->baseImage != nullptr && this->startButtonEnabled;}
bool getReinstallActionEnabled() const {return this->baseImage != nullptr && this->reinstallButtonEnabled;}
bool getAutostartEnabled() const {return this->baseImage != nullptr && this->autostartEnabled;}
const int& getAutostartTimeout() const {return this->autostartTimeout;}
const LinboOsStartAction& getDefaultAction() const {return this->defaultAction;}
const bool& getHidden() const {return this->hidden;}
bool getActionEnabled(LinboOsStartAction action) {
switch (action) {
case StartOs: return this->getStartbutton();
case SyncOs: return this->getSyncbutton();
case ReinstallOs: return this->getNewbutton();
case UnknownAction: return false;
}
}
static LinboOsStartAction startActionFromString(const QString& name) {
if(name == "start")
return StartOs;
else if(name == "sync")
return SyncOs;
else if(name == "new")
return ReinstallOs;
return UnknownAction;
}
protected:
explicit LinboOs(QObject *parent = nullptr);
void setName( const QString& name ) {this->name = name;}
void setDescription ( const QString& description ) {this->description = description;}
void setVersion( const QString& version ) {this->version = version;}
void setBaseImage( LinboImage* baseImage ) {this->baseImage = baseImage;}
void setDifferentialImage(LinboImage* differentialImage) {this->differentialImage = differentialImage;}
void setIconName( const QString& iconName ) {this->iconName = iconName;}
void setRootPartition( const QString& rootPartition ) {this->rootPartition = rootPartition;}
void setBootPartition( const QString& bootPartition ) {this->bootPartition = bootPartition;}
void setKernel( const QString& kernel ) {this->kernel = kernel;}
void setInitrd( const QString& initrd ) {this->initrd = initrd;}
void setKernelOptions( const QString& kernelOptions ) {this->kernelOptions = kernelOptions;}
void setSyncButton ( const bool& syncButton ) {this->syncButton = syncButton;}
void setStartButton( const bool& startButton) {this->startButton = startButton;}
void setNewButton ( const bool& newButton ) {this->newButton = newButton;}
void setAutostart ( const bool& autostart ) {this->autostart = autostart;}
void setAutostartTimeout ( const int& autostartTimeout ) {this->autostartTimeout = autostartTimeout;}
void setDefaultAction ( const LinboOsStartAction& defaultAction ) {this->defaultAction = defaultAction;}
void setHidden ( const bool& hidden ) {this->hidden = hidden;}
bool getActionEnabled(LinboOsStartAction action);
static LinboOsStartAction startActionFromString(const QString& name);
private:
QString name, // OS Name
version,
description,
iconName, // Thumbnail for Image
rootPartition, // Root partition
bootPartition, // Root partition
image,
kernel,
initrd,
kernelOptions;
int autostartTimeout;
bool syncButton, startButton, newButton, autostart,
hidden; // show OS tab or not
LinboOsStartAction defaultAction;
explicit LinboOs(QObject *parent = nullptr);
void setName (const QString& name) {this->name = name;}
void setDescription (const QString& description) {this->description = description;}
void setVersion (const QString& version) {this->version = version;}
void setBaseImage (LinboImage* baseImage) {this->baseImage = baseImage;}
void setDifferentialImage(LinboImage* differentialImage) {this->differentialImage = differentialImage;}
void setIconName (const QString& iconName) {this->iconName = iconName;}
void setRootPartition (const QString& rootPartition) {this->rootPartition = rootPartition;}
void setBootPartition (const QString& bootPartition) {this->bootPartition = bootPartition;}
void setKernel (const QString& kernel) {this->kernel = kernel;}
void setInitrd (const QString& initrd) {this->initrd = initrd;}
void setKernelOptions (const QString& kernelOptions) {this->kernelOptions = kernelOptions;}
void setSyncButtonEnabled (const bool& syncButtonEnabled) {this->syncButtonEnabled = syncButtonEnabled;}
void setStartButtonEnabled (const bool& startButtonEnabled) {this->startButtonEnabled = startButtonEnabled;}
void setReinstallButtonEnabled (const bool& reinstallButtonEnabled) {this->reinstallButtonEnabled = reinstallButtonEnabled;}
void setAutostartEnabled (const bool& autostartEnabled) {this->autostartEnabled = autostartEnabled;}
void setAutostartTimeout (const int& autostartTimeout) {this->autostartTimeout = autostartTimeout;}
void setDefaultAction (const LinboOsStartAction& defaultAction) {this->defaultAction = defaultAction;}
void setHidden (const bool& hidden) {this->hidden = hidden;}
QString name;
QString version;
QString description;
QString iconName;
QString rootPartition;
QString bootPartition;
QString image;
QString kernel;
QString initrd;
QString kernelOptions;
int autostartTimeout;
bool syncButtonEnabled;
bool startButtonEnabled;
bool reinstallButtonEnabled;
bool autostartEnabled;
bool hidden;
LinboOsStartAction defaultAction;
LinboImage* baseImage;
LinboImage* differentialImage;
};
#endif // LINBOOS_H

View File

@ -48,56 +48,57 @@ class linboPasswordBoxImpl;
class linboGUIImpl : public QDialog, public Ui::linboGUI
{
Q_OBJECT
Q_OBJECT
public slots:
void readFromStdout();
void readFromStderr();
void enableButtons();
void resetButtons();
void disableButtons();
void restoreButtonsState();
void tabWatcher( QWidget* );
void processTimeout();
void executeAutostart();
void shutdown();
void reboot();
void autostartTimeoutSlot();
void readFromStdout();
void readFromStderr();
void enableButtons();
void resetButtons();
void disableButtons();
void restoreButtonsState();
void tabWatcher( QWidget* );
void processTimeout();
void executeAutostart();
void shutdown();
void reboot();
void autostartTimeoutSlot();
void loginAndOpen();
private:
linboCounterImpl* myCounter;
QTimer* myTimer;
QTimer* myAutostartTimer;
linboMsgImpl *waiting;
QString linestdout, linestderr;
QString logfilepath, fonttemplate;
bool root, withicons, outputvisible;
QProcess* process;
QDialog* myQPasswordBox;
linboPasswordBoxImpl* myLPasswordBox;
linbopushbutton *autostart, *autopartition, *autoinitcache;
int preTab, autostarttimeout;
linboLogConsole* logConsole;
vector<int> buttons_config;
vector<bool> buttons_config_save;
linboCounterImpl* myCounter;
QTimer* myTimer;
QTimer* myAutostartTimer;
linboMsgImpl *waiting;
QString linestdout, linestderr;
QString logfilepath, fonttemplate;
bool root, withicons, outputvisible;
QProcess* process;
QDialog* myQPasswordBox;
linboPasswordBoxImpl* myLPasswordBox;
linbopushbutton *autostart, *autopartition, *autoinitcache;
int preTab, autostarttimeout;
linboLogConsole* logConsole;
vector<int> buttons_config;
vector<bool> buttons_config_save;
public:
vector<linbopushbutton*> p_buttons;
// 0 = disabled
// 1 = enabled
// 2 = admin button
vector<linbopushbutton*> p_buttons;
// 0 = disabled
// 1 = enabled
// 2 = admin button
globals config;
vector<os_item> elements;
vector<diskpartition> partitions;
globals config;
vector<os_item> elements;
vector<diskpartition> partitions;
linboGUIImpl(QWidget* parent = nullptr);
linboGUIImpl(QWidget* parent = nullptr);
~linboGUIImpl();
~linboGUIImpl();
bool isRoot() const;
void showImagingTab();
void log( const QString& data );
bool isRoot() const;
void showImagingTab();
void log( const QString& data );
};

View File

@ -41,6 +41,7 @@ private:
LinboOsSelectButton(QString icon, LinboOs* os, QButtonGroup* buttonGroup, QWidget* parent = nullptr);
LinboOs* getOs();
void setVisibleAnimated(bool visible);
void setVisible(bool visible) override;
QModernPushButton* button;

View File

@ -1,9 +1,28 @@
/****************************************************************************
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef LINBOOSSELECTIONROW_H
#define LINBOOSSELECTIONROW_H
#include <QObject>
#include <QWidget>
#include <Q3ButtonGroup>
#include <QButtonGroup>
#include <QLabel>
#include "linbobackend.h"
#include "linboosselectbutton.h"
@ -24,7 +43,12 @@ private:
LinboBackend* backend;
QList<LinboOsSelectButton*> osButtons;
QButtonGroup* osButtonGroup;
QLabel* noOsLabel;
QFont noOsLabelFont;
QLabel* environmentValuesLabel;
QFont environmentValuesLabelFont;
bool showOnlySelectedButton;
bool inited;
private slots:
void resizeAndPositionAllButtons();

View File

@ -1,3 +1,21 @@
/****************************************************************************
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef LINBOSTARTACTIONS_H
#define LINBOSTARTACTIONS_H
@ -33,7 +51,10 @@ private:
QModernPushButton* startOsButton;
QModernPushButton* syncOsButton;
QModernPushButton* reinstallOsButton;
QModernPushButton* cancelButton;
QList<QModernPushButton*> actionButtons;
QLabel* noBaseImageLabel;
QFont noBaseImageLabelFont;
QWidget* progressBarWidget;
QModernProgressBar* progressBar;

View File

@ -19,6 +19,24 @@
#ifndef LINBOGUISTARTPAGE_H
#define LINBOGUISTARTPAGE_H
/****************************************************************************
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include <QObject>
#include <QWidget>
#include <QBoxLayout>
@ -46,6 +64,8 @@ private:
LinboStartActions* startActionsWidget;
QList<QModernPushButton*> powerActionButtons;
bool inited;
private slots:
void handleLinboStateChanged(LinboBackend::LinboState newState);

View File

@ -1,3 +1,21 @@
/****************************************************************************
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef QMODERNPROGRESSBAR_H
#define QMODERNPROGRESSBAR_H

View File

@ -38,7 +38,7 @@ class QModernPushButton : public QAbstractButton
public:
QModernPushButton(QString icon, QWidget* parent = nullptr);
void setVisibleAnimated(bool visible, bool asynchronos = true);
void setVisibleAnimated(bool visible);
void setGeometryAnimated(const QRect& geometry);

View File

@ -1,3 +1,21 @@
/****************************************************************************
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef QMODERNPUSHBUTTONOVERLAY_H
#define QMODERNPUSHBUTTONOVERLAY_H
@ -26,6 +44,7 @@ private:
void setAnimationDuration(int duration);
void setVisible(bool visible);
void setVisibleAnimated(bool visible);
void setEffectEnabled(bool enabled);
private slots:

View File

@ -1,3 +1,21 @@
/****************************************************************************
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef QMODERNSTACKEDWIDGET_H
#define QMODERNSTACKEDWIDGET_H

View File

@ -64,7 +64,6 @@ SOURCES += \
sources/legacy/linboConsoleImpl.cc \
sources/legacy/linboCounterImpl.cc \
sources/legacy/linboGUIImpl.cc \
sources/legacy/linboGUIImplTmp.cpp \
sources/legacy/linboImageSelectorImpl.cc \
sources/legacy/linboImageUploadImpl.cc \
sources/legacy/linboInfoBrowserImpl.cc \

View File

@ -27,5 +27,6 @@
<file>svgIcons/rebootAction.svg</file>
<file>svgIcons/settingsAction.svg</file>
<file>fonts/SegoeUI.ttf</file>
<file>svgIcons/cancel.svg</file>
</qresource>
</RCC>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
focusable="false"
data-prefix="far"
data-icon="times-circle"
class="svg-inline--fa fa-times-circle fa-w-16"
role="img"
viewBox="0 0 500 500"
version="1.1"
id="svg4"
width="500"
height="500">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<path
fill="currentColor"
d="m 250,99.999998 c -82.8629,0 -150,67.137092 -150,150.000002 0,82.8629 67.1371,150 150,150 82.8629,0 150,-67.1371 150,-150 C 400,167.13709 332.8629,99.999998 250,99.999998 Z m 0,270.967742 c -66.83468,0 -120.96774,-54.13306 -120.96774,-120.96774 0,-66.83468 54.13306,-120.96774 120.96774,-120.96774 66.83467,0 120.96773,54.13306 120.96773,120.96774 0,66.83468 -54.13306,120.96774 -120.96773,120.96774 z M 311.57258,212.37903 273.95161,250 l 37.62097,37.62097 c 2.84274,2.84274 2.84274,7.43951 0,10.28226 l -13.66935,13.66935 c -2.84276,2.84274 -7.43953,2.84274 -10.28226,0 L 250,273.95161 212.37903,311.57258 c -2.84274,2.84274 -7.43951,2.84274 -10.28227,0 l -13.66935,-13.66935 c -2.84274,-2.84275 -2.84274,-7.43952 0,-10.28226 L 226.04838,250 188.42741,212.37903 c -2.84274,-2.84274 -2.84274,-7.43951 0,-10.28226 l 13.66935,-13.66935 c 2.84276,-2.84275 7.43953,-2.84275 10.28227,0 L 250,226.04839 287.62097,188.42742 c 2.84273,-2.84275 7.4395,-2.84275 10.28226,0 l 13.66935,13.66935 c 2.84274,2.84275 2.84274,7.43952 0,10.28226 z"
id="path2"
style="stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke:none;stroke-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -2,6 +2,10 @@
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** Portions of the code in this file are based on code by:
** Copyright (C) 2007 Martin Oehler <oehler@knopper.net>
** Copyright (C) 2007 Klaus Knopper <knopper@knopper.net>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
@ -18,132 +22,52 @@
#include "linbobackend.h"
#define LINBO_CMD(arg) QStringList("linbo_cmd") << (arg)
using namespace std;
/*
* TODO:
* - State StartError (ish)
* - enter state StartError when starting / syncing / reinstalling fails
*/
LinboBackend::LinboBackend(QObject *parent) : QObject(parent)
{
this->setState(Initializing);
this->logger = new LinboLogger(this);
this->config = new LinboConfig(this);
this->autostartTimer = new QTimer();
this->autostartTimer->setSingleShot(true);
connect(this->autostartTimer, SIGNAL(timeout()), this, SLOT(handleAutostartTimerTimeout()));
this->autostartRemainingTimeRefreshTimer = new QTimer();
this->autostartRemainingTimeRefreshTimer->setSingleShot(false);
this->autostartRemainingTimeRefreshTimer->setInterval(10);
connect(this->autostartRemainingTimeRefreshTimer, SIGNAL(timeout()), this, SIGNAL(autostartTimeoutProgressChanged()));
this->autostartElapsedTimer = new QElapsedTimer();
this->currentOs = nullptr;
// read start.conf
this->logger->log("Starting to parse start.conf", LinboLogger::LinboGuiInfo);
ifstream input;
input.open( "start.conf", ios_base::in );
// Init some objects
this->logger = new LinboLogger("/tmp/linbo.log", this);
this->config = new LinboConfig(this);
QString tmp_qstring;
// autostart timers
this->autostartTimer = new QTimer(this);
this->autostartTimer->setSingleShot(true);
connect(this->autostartTimer, SIGNAL(timeout()),
this, SLOT(handleAutostartTimerTimeout()));
while( !input.eof() ) {
// *** Image description section ***
this->autostartRemainingTimeRefreshTimer = new QTimer(this);
this->autostartRemainingTimeRefreshTimer->setSingleShot(false);
this->autostartRemainingTimeRefreshTimer->setInterval(10);
connect(this->autostartRemainingTimeRefreshTimer, SIGNAL(timeout()),
this, SIGNAL(autostartTimeoutProgressChanged()));
// entry in start tab
char line[500];
input.getline(line,500,'\n');
tmp_qstring = QString::fromAscii( line, -1 ).stripWhiteSpace();
this->autostartElapsedTimer = new QElapsedTimer();
if ( tmp_qstring.startsWith("#") || tmp_qstring.isEmpty() ) continue;
tmp_qstring = tmp_qstring.section("#",0,0).stripWhiteSpace(); // Strip comment
if(tmp_qstring.lower().compare("[os]") == 0) {
LinboOs* tmpOs = read_os(&input);
if(!tmpOs->getName().isEmpty()) {
this->operatingSystems.append(tmpOs);
if(tmpOs->getAutostart() && this->currentOs == nullptr)
this->currentOs = tmpOs;
// check if this is an additional/incremental image for an existing OS
/* TODO unsigned int i; // Being checked later.
for(i = 0; i < elements.size(); i++ ) {
if(tmp_os.get_name().lower().compare(elements[i].get_name().lower()) == 0) {
elements[i].image_history.push_back(tmp_image); break;
}
}
if(i==elements.size()) { // Not included yet -> new image
tmp_os.image_history.push_back(tmp_image);
elements.push_back(tmp_os);
}*/
}
else {
tmpOs->deleteLater();
}
} else if(tmp_qstring.lower().compare("[linbo]") == 0) {
read_globals(&input, config);
} else if(tmp_qstring.lower().compare("[partition]") == 0) {
LinboDiskPartition* tmpPartition = read_partition(&input);
if(!tmpPartition->getPath().isEmpty()) {
diskPartitions.append(tmpPartition);
}
else {
tmpPartition->deleteLater();
}
}
}
input.close();
this->logger->log("Finished to parsing start.conf", LinboLogger::LinboGuiInfo);
this->logger->log("Loading global configuration", LinboLogger::LinboGuiInfo);
// load global config
QStringList command;
// Processes
this->asynchronosProcess = new QProcess(this);
// ascynchorons commands are logged to logger
this->asynchronosProcess = new QProcess();
connect( asynchronosProcess, SIGNAL(readyReadStandardOutput()),
this, SLOT(readFromStdout()) );
connect( asynchronosProcess, SIGNAL(readyReadStandardError()),
this, SLOT(readFromStderr()) );
// synchronos commands are not logged
this->synchronosProcess = new QProcess();
this->synchronosProcess = new QProcess(this);
// client ip
this->config->setIpAddress(this->executeCommand(true, "ip"));
// load all configuration
this->loadStartConfiguration("start.conf");
this->loadEnvironmentValues();
// mac address
this->config->setMacAddress(this->executeCommand(true, "mac"));
// Version
this->config->setVersion(this->executeCommand(true, "version").stripWhiteSpace());
// hostname
this->config->setHostname(this->executeCommand(true, "hostname"));
// CPU
this->config->setCpu(this->executeCommand(true, "cpu"));
// Memory
this->config->setRamSize(this->executeCommand(true, "memory"));
// Cache Size
this->config->setCacheSize(this->executeCommand(true, "size"));
// Harddisk Size
QRegExp *removePartition = new QRegExp("[0-9]{1,2}");
QString hd = this->config->getCache();
// e.g. turn /dev/sda1 into /dev/sda
hd.remove( *removePartition );
this->config->setHddSize(this->executeCommand(true, "size", hd));
this->logger->log("Finished loading global configuration", LinboLogger::LinboGuiInfo);
// default select first OS if no other OS has been selected yet
if(this->operatingSystems.length() > 0 && this->currentOs == nullptr)
this->currentOs = this->operatingSystems[0];
// triger autostart
if(this->currentOs->getAutostart())
// triger autostart if necessary
if(this->currentOs != nullptr && this->currentOs->getAutostartEnabled())
this->executeAutostart();
else
this->setState(Idle);
@ -204,7 +128,7 @@ void LinboBackend::reboot() {
bool LinboBackend::startCurrentOs() {
LinboOs* os = this->currentOs;
if(os == nullptr || (this->state != Idle && this->state != Autostarting) || !os->getStartbutton())
if(os == nullptr || (this->state != Idle && this->state != Autostarting) || !os->getActionEnabled(LinboOs::StartOs))
return false;
this->setState(Starting);
@ -217,7 +141,7 @@ bool LinboBackend::startCurrentOs() {
os->getKernel(),
os->getInitrd(),
os->getKernelOptions(),
this->config->getCache()
this->config->getCachePath()
);
return true;
@ -226,18 +150,26 @@ bool LinboBackend::startCurrentOs() {
bool LinboBackend::syncCurrentOs() {
LinboOs* os = this->currentOs;
if(os == nullptr || (this->state != Idle && this->state != Autostarting) || !os->getSyncbutton())
if(os == nullptr || (this->state != Idle && this->state != Autostarting) || !os->getActionEnabled(LinboOs::SyncOs))
return false;
this->setState(Syncing);
qDebug() << "TEST2";
QString differentialImage;
if(os->getDifferentialImage() == nullptr)
differentialImage = "";
else
differentialImage = os->getDifferentialImage()->getName();
this->executeCommand(
false,
"syncstart",
this->config->getServer(),
this->config->getCache(),
this->config->getServerIpAddress(),
this->config->getCachePath(),
os->getBaseImage()->getName(),
os->getDifferentialImage()->getName(),
differentialImage,
os->getBootPartition(),
os->getRootPartition(),
os->getKernel(),
@ -251,18 +183,24 @@ bool LinboBackend::syncCurrentOs() {
bool LinboBackend::reinstallCurrentOs() {
LinboOs* os = this->currentOs;
if(os == nullptr || (this->state != Idle && this->state != Autostarting) || !os->getNewbutton())
if(os == nullptr || (this->state != Idle && this->state != Autostarting) || !os->getActionEnabled(LinboOs::ReinstallOs))
return false;
this->setState(Reinstalling);
QString differentialImage;
if(os->getDifferentialImage() == nullptr)
differentialImage = "";
else
differentialImage = os->getDifferentialImage()->getName();
this->executeCommand(
false,
"syncr",
this->config->getServer(),
this->config->getCache(),
this->config->getServerIpAddress(),
this->config->getCachePath(),
os->getBaseImage()->getName(),
os->getDifferentialImage()->getName(),
differentialImage,
os->getBootPartition(),
os->getRootPartition(),
os->getKernel(),
@ -305,7 +243,7 @@ bool LinboBackend::initializeCache() {
this->setState(InitializingCache);
QStringList commandArgs = this->buildCommand("initcache", config->getServer(), config->getCache());
QStringList commandArgs = this->buildCommand("initcache", config->getServerIpAddress(), config->getCachePath());
if( this->config->getDownloadType().isEmpty() )
commandArgs.append(this->config->getDownloadType());
@ -329,11 +267,35 @@ bool LinboBackend::updateLinbo() {
if(this->state != Root)
return false;
this->executeCommand("update", this->config->getServer(), this->config->getCache());
this->executeCommand("update", this->config->getServerIpAddress(), this->config->getCachePath());
return true;
}
bool LinboBackend::cancelCurrentAction() {
switch (this->state) {
case Autostarting:
this->logger->log("Cancelling autostart", LinboLogger::LinboGuiInfo);
this->autostartTimer->stop();
this->autostartRemainingTimeRefreshTimer->stop();
this->autostartElapsedTimer->invalidate();
this->setState(Idle);
return true;
case Starting:
case Syncing:
case Reinstalling:
this->logger->log("Cancelling current start action: " + QString::number(this->state), LinboLogger::LinboGuiInfo);
this->asynchronosProcess->kill();
this->setState(Idle);
return true;
default:
this->logger->log("Cannot cancel current action: " + QString::number(this->state), LinboLogger::LinboGuiInfo);
return false;
}
}
LinboLogger* LinboBackend::getLogger() {
return this->logger;
}
@ -393,7 +355,6 @@ QString LinboBackend::executeCommand(bool waitForFinished, QString command, QStr
}
}
void LinboBackend::readFromStdout() {
QString stdOut = this->asynchronosProcess->readAllStandardOutput();
QStringList lines = stdOut.split("\n");
@ -420,88 +381,235 @@ void LinboBackend::setState(LinboState state) {
this->state = state;
emit this->stateChanged(this->state);
this->logger->log("Linbo state changed to: " + QString::number(state), LinboLogger::LinboGuiInfo);
}
// Return true unless beginning of new section '[' is found.
bool LinboBackend::read_pair(ifstream* input, QString& key, QString& value) {
char line[1024];
if(input->peek() == '[') return false; // Next section found.
input->getline(line,1024,'\n');
QString s = QString::fromAscii( line, -1 ).stripWhiteSpace();
key = s.section("=",0,0).stripWhiteSpace().lower();
if(s.startsWith("#")||key.isEmpty()) {
key = QString(""); value = QString("");
} else {
value=s.section("=",1).section("#",0,0).stripWhiteSpace();
void LinboBackend::loadStartConfiguration(QString startConfFilePath) {
// read start.conf
this->logger->log("Starting to parse start.conf", LinboLogger::LinboGuiInfo);
QFile inputFile(startConfFilePath);
if (inputFile.open(QIODevice::ReadOnly))
{
QTextStream input(&inputFile);
QString currentSection;
QMap<QString, QString> linboConfig;
QList<QMap<QString, QString>> partitionConfigs;
QList<QMap<QString, QString>> osConfigs;
bool firstLineOfSection = false;
while(!input.atEnd()) {
QString thisLine = input.readLine();
// ignore comments and empty lines
if(thisLine.startsWith("#")||thisLine.isEmpty())
continue;
// Remove comments from the end of the line
thisLine = thisLine.split("#")[0];
// ignore capitalization
thisLine = thisLine.toLower();
// remove empty characters
thisLine = thisLine.stripWhiteSpace();
thisLine = thisLine.simplified();
//qDebug() << "reading line: " << thisLine;
if(thisLine.startsWith("[")) {
// we found a new section!
currentSection = thisLine;
firstLineOfSection = true;
continue;
}
// parse key value pair
// ignore invalid lines
if(!thisLine.contains("=") || thisLine.startsWith("="))
continue;
// split string at
QStringList keyValueList = thisLine.split("=");
if(keyValueList.length() < 2)
continue;
QString key = keyValueList[0].stripWhiteSpace();
QString value = keyValueList[1].stripWhiteSpace();
// ignore empty keys and values
if(key.isEmpty() || value.isEmpty())
continue;
// insert the values into our internal objects
if(currentSection == "[linbo]") {
// we are parsing the linbo config
linboConfig.insert(key, value);
}
else if(currentSection == "[partition]") {
// we are parsing a partition block
if(firstLineOfSection)
partitionConfigs.append(QMap<QString, QString>());
partitionConfigs.last().insert(key, value);
}
else if(currentSection == "[os]") {
// we are parsing an os block
if(firstLineOfSection)
osConfigs.append(QMap<QString, QString>());
osConfigs.last().insert(key, value);
}
// ignore everything else
firstLineOfSection = false;
}
inputFile.close();
// write the config our internal objects
this->writeToLinboConfig(linboConfig, this->config);
for(QMap<QString, QString> partitionConfig : partitionConfigs) {
LinboDiskPartition* tmpPartition = new LinboDiskPartition(this);
this->writeToPartitionConfig(partitionConfig, tmpPartition);
if(tmpPartition->getPath() != "")
this->diskPartitions.append(tmpPartition);
else
tmpPartition->deleteLater();
}
for(QMap<QString, QString> osConfig : osConfigs) {
LinboOs* tmpOs = new LinboOs(this);
this->writeToOsConfig(osConfig, tmpOs);
if(tmpOs->getName() != "") {
this->operatingSystems.append(tmpOs);
if(tmpOs->getAutostartEnabled() && this->currentOs == nullptr)
// If the autostart of this OS is enabled and there is
// no other OS active yet -> set this OS as current OS
this->currentOs = tmpOs;
// check if this is an additional/incremental image for an existing OS
/* TODO unsigned int i; // Being checked later.
for(i = 0; i < elements.size(); i++ ) {
if(tmp_os.get_name().lower().compare(elements[i].get_name().lower()) == 0) {
elements[i].image_history.push_back(tmp_image); break;
}
}
if(i==elements.size()) { // Not included yet -> new image
tmp_os.image_history.push_back(tmp_image);
elements.push_back(tmp_os);
}*/
}
else
tmpOs->deleteLater();
}
// default select first OS if no other OS has been selected yet
if(this->operatingSystems.length() > 0 && this->currentOs == nullptr)
this->currentOs = this->operatingSystems[0];
}
else
this->logger->log("Error opening the start configuration file: " + startConfFilePath, LinboLogger::LinboGuiError);
this->logger->log("Finished parsing start.conf", LinboLogger::LinboGuiInfo);
}
void LinboBackend::loadEnvironmentValues() {
this->logger->log("Loading environment values", LinboLogger::LinboGuiInfo);
// client ip
this->config->setIpAddress(this->executeCommand(true, "ip").replace("\n", ""));
// mac address
this->config->setMacAddress(this->executeCommand(true, "mac").replace("\n", ""));
// Version
this->config->setLinboVersion(this->executeCommand(true, "version").stripWhiteSpace().replace("\n", ""));
// hostname
this->config->setHostname(this->executeCommand(true, "hostname").replace("\n", ""));
// CPU
this->config->setCpuModel(this->executeCommand(true, "cpu").replace("\n", ""));
// Memory
this->config->setRamSize(this->executeCommand(true, "memory").replace("\n", ""));
// Cache Size
this->config->setCacheSize(this->executeCommand(true, "size", this->config->getCachePath()).replace("\n", ""));
// Harddisk Size
QRegExp *removePartition = new QRegExp("[0-9]{1,2}");
QString hd = this->config->getCachePath();
// e.g. turn /dev/sda1 into /dev/sda
hd.remove( *removePartition );
this->config->setHddSize(this->executeCommand(true, "size", hd).replace("\n", ""));
this->logger->log("Finished loading environment values", LinboLogger::LinboGuiInfo);
}
void LinboBackend::writeToLinboConfig(QMap<QString, QString> config, LinboConfig* linboConfig) {
for(QString key : config.keys()) {
QString value = config[key];
if(key == "server") linboConfig->setServerIpAddress(value);
else if(key == "cache") linboConfig->setCachePath(value);
else if(key == "roottimeout") linboConfig->setRootTimeout((unsigned int)value.toInt());
else if(key == "group") linboConfig->setHostGroup(value);
else if(key == "autopartition") linboConfig->setAutoPartition(toBool(value));
else if(key == "autoinitcache") linboConfig->setAutoInitCache(toBool(value));
else if(key == "autoformat") linboConfig->setAutoFormat(toBool(value));
else if(key == "backgroundfontcolor") linboConfig->setBackgroundFontcolor(value);
else if(key == "consolefontcolorstdout") linboConfig->setConsoleFontcolorStdout(value);
else if(key == "consolefontcolorstderr") linboConfig->setConsoleFontcolorStderr(value);
else if(key == "usemulticast") {
if(value.toInt() == 0)
linboConfig->setDownloadType("rsync");
else
linboConfig->setDownloadType("multicast");
}
else if(key == "downloadtype") linboConfig->setDownloadType(value);
}
}
void LinboBackend::writeToPartitionConfig(QMap<QString, QString> config, LinboDiskPartition* partition) {
for(QString key : config.keys()) {
QString value = config[key];
if(key == "dev") partition->setPath(value);
else if(key == "size") partition->setSize(value.toInt());
else if(key == "id") partition->setId(value);
else if(key == "fstype") partition->setFstype(value);
else if(key.startsWith("bootable", false)) partition->setBootable(toBool(value));
}
}
void LinboBackend::writeToOsConfig(QMap<QString, QString> config, LinboOs* os) {
for(QString key : config.keys()) {
QString value = config[key];
if(key == "name") os->setName(value);
else if(key == "description") os->setDescription(value);
else if(key == "version") os->setVersion(value);
else if(key == "iconname") os->setIconName(value);
else if(key == "image") os->setDifferentialImage(new LinboImage(value, os));
else if(key == "baseimage") os->setBaseImage(new LinboImage(value, os));
else if(key == "boot") os->setBootPartition(value);
else if(key == "root") os->setRootPartition(value);
else if(key == "kernel") os->setKernel(value);
else if(key == "initrd") os->setInitrd(value);
else if(key == "append") os->setKernelOptions(value);
else if(key == "syncenabled") os->setSyncButtonEnabled(toBool(value));
else if(key == "startenabled") os->setStartButtonEnabled(toBool(value));
else if((key == "remotesyncenabled") || (key == "newenabled")) os->setReinstallButtonEnabled(toBool(value));
else if(key == "defaultaction") os->setDefaultAction(os->startActionFromString(value));
else if(key == "autostart") os->setAutostartEnabled(toBool(value));
else if(key == "autostarttimeout") os->setAutostartTimeout(value.toInt());
else if(key == "hidden") os->setHidden(toBool(value));
}
return true;
}
bool LinboBackend::toBool(const QString& value) {
if(value.startsWith("yes",false)) return true;
if(value.startsWith("true",false)) return true;
if(value.startsWith("enable",false)) return true;
return false;
}
LinboOs* LinboBackend::read_os(ifstream* input) {
LinboOs* os = new LinboOs(this);
QString key, value;
while(!input->eof() && read_pair(input, key, value)) {
if(key.compare("name") == 0) os->setName(value);
else if(key.compare("description") == 0) os->setDescription(value);
else if(key.compare("version") == 0) os->setVersion(value);
else if(key.compare("iconname") == 0) os->setIconName(value);
else if(key.compare("image") == 0) os->setDifferentialImage(new LinboImage(value, os));
else if(key.compare("baseimage") == 0) os->setBaseImage(new LinboImage(value, os));
else if(key.compare("boot") == 0) os->setBootPartition(value);
else if(key.compare("root") == 0) os->setRootPartition(value);
else if(key.compare("kernel") == 0) os->setKernel(value);
else if(key.compare("initrd") == 0) os->setInitrd(value);
else if(key.compare("append") == 0) os->setKernelOptions(value);
else if(key.compare("syncenabled") == 0) os->setSyncButton(toBool(value));
else if(key.compare("startenabled") == 0) os->setStartButton(toBool(value));
else if((key.compare("remotesyncenabled") == 0) || (key.compare("newenabled") == 0)) os->setNewButton(toBool(value));
else if(key.compare("defaultaction") == 0) os->setDefaultAction(os->startActionFromString(value));
else if(key.compare("autostart") == 0) os->setAutostart(toBool(value));
else if(key.compare("autostarttimeout") == 0) os->setAutostartTimeout(value.toInt());
else if(key.compare("hidden") == 0) os->setHidden(toBool(value));
}
return os;
}
LinboDiskPartition* LinboBackend::read_partition(ifstream* input) {
LinboDiskPartition* partition = new LinboDiskPartition(this);
QString key, value;
while(!input->eof() && read_pair(input, key, value)) {
if(key.compare("dev") == 0) partition->setPath(value);
else if(key.compare("size") == 0) partition->setSize(value.toInt());
else if(key.compare("id") == 0) partition->setId(value);
else if(key.compare("fstype") == 0) partition->setFstype(value);
else if(key.startsWith("bootable", false)) partition->setBootable(toBool(value));
}
return partition;
}
void LinboBackend::read_globals( ifstream* input, LinboConfig* config ) {
QString key, value;
while(!input->eof() && read_pair(input, key, value)) {
if(key.compare("server") == 0) config->setServer(value);
else if(key.compare("cache") == 0) config->setCache(value);
else if(key.compare("roottimeout") == 0) config->setRootTimeout((unsigned int)value.toInt());
else if(key.compare("group") == 0) config->setHostgroup(value);
else if(key.compare("autopartition") == 0) config->setAutopartition(toBool(value));
else if(key.compare("autoinitcache") == 0) config->setAutoInitCache(toBool(value));
else if(key.compare("autoformat") == 0) config->setAutoFormat(toBool(value));
else if(key.compare("backgroundfontcolor") == 0) config->setBackgroundFontcolor(value);
else if(key.compare("consolefontcolorstdout") == 0) config->setConsoleFontcolorStdout(value);
else if(key.compare("consolefontcolorstderr") == 0) config->setConsoleFontcolorStderr(value);
else if(key.compare("usemulticast") == 0) {
if( (unsigned int)value.toInt() == 0 )
config->setDownloadType("rsync");
else
config->setDownloadType("multicast");
}
else if(key.compare("downloadtype") == 0) config->setDownloadType(value);
}
QStringList trueWords("yes");
trueWords.append("true");
trueWords.append("enable");
return trueWords.contains(value.stripWhiteSpace());
}

View File

@ -16,7 +16,7 @@
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "../../headers/backend/linboconfig.h"
#include "linboconfig.h"
LinboConfig::LinboConfig(QObject *parent) : QObject(parent)
{

View File

@ -16,7 +16,7 @@
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "../../headers/backend/linbodiskpartition.h"
#include "linbodiskpartition.h"
LinboDiskPartition::LinboDiskPartition(QObject *parent) : QObject(parent)
{

View File

@ -16,7 +16,7 @@
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "../../headers/backend/linboimage.h"
#include "linboimage.h"
LinboImage::LinboImage(QString name, QObject *parent) : QObject(parent)
{

View File

@ -1,8 +1,26 @@
#include "../../headers/backend/linbologger.h"
/****************************************************************************
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
LinboLogger::LinboLogger(QObject *parent) : QObject(parent)
#include "linbologger.h"
LinboLogger::LinboLogger(QString logFilePath, QObject *parent) : QObject(parent)
{
this->logFilePath = logFilePath;
}
QString LinboLogger::logTypeToString(LinboLogType logType) {
@ -24,11 +42,29 @@ void LinboLogger::log(QString logText, LinboLogType logType) {
if(logText.isEmpty() || logText == "")
return;
qDebug() << qPrintable("[" + this->logTypeToString(logType) + "]") << logText;
LinboLog latestLog {logText, logType, QDateTime::currentDateTime()};
this->logHistory.append(latestLog);
// TODO: Log error, when this fails
this->writeToLogFile("[" + this->logTypeToString(logType) + "]" + logText);
emit this->latestLogChanged(latestLog);
}
bool LinboLogger::writeToLogFile(QString text) {
// write to logfile
QFile logfile(this->logFilePath);
if(!logfile.open( QIODevice::WriteOnly | QIODevice::Append ))
return false;
QTextStream logstream( &logfile );
logstream << text << "\n";
logfile.flush();
logfile.close();
return true;
}
const LinboLogger::LinboLog& LinboLogger::getLatestLog() {
return this->logHistory.last();
}

View File

@ -16,14 +16,35 @@
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "../../headers/backend/linboos.h"
#include "linboos.h"
LinboOs::LinboOs(QObject *parent) : QObject(parent)
{
autostart = false;
autostartTimeout = 0;
hidden = false;
defaultAction = SyncOs;
// TODO ?? image_history.clear();
iconName = QString("defaultIcon.svg");
this->autostartEnabled = false;
this->autostartTimeout = 0;
this->hidden = false;
this->defaultAction = SyncOs;
this->iconName = QString("defaultIcon.svg");
this->baseImage = nullptr;
this->differentialImage = nullptr;
// TODO ?? image_history.clear();
}
bool LinboOs::getActionEnabled(LinboOsStartAction action) {
switch (action) {
case StartOs: return this->getStartActionEnabled();
case SyncOs: return this->getSyncActionEnabled();
case ReinstallOs: return this->getReinstallActionEnabled();
default: return false;
}
}
LinboOs::LinboOsStartAction LinboOs::startActionFromString(const QString& name) {
if(name == "start")
return StartOs;
else if(name == "sync")
return SyncOs;
else if(name == "new")
return ReinstallOs;
return UnknownAction;
}

View File

@ -15,7 +15,6 @@ linboCounterImpl::linboCounterImpl( QWidget* parent ) : linboDialog()
if( parent )
myParent = parent;
QRect qRect(QApplication::desktop()->screenGeometry());
// open in the upper left of our screen
int xpos= 10;
int ypos= 10;

File diff suppressed because it is too large Load Diff

View File

@ -10,206 +10,204 @@
linboPasswordBoxImpl::linboPasswordBoxImpl( QDialog* parent ) : linboDialog()
{
Ui_linboPasswordBox::setupUi((QDialog*)this);
Ui_linboPasswordBox::setupUi((QDialog*)this);
connect(passwordInput,SIGNAL(returnPressed()),this,SLOT(postcmd()));
connect(passwordInput,SIGNAL(returnPressed()),this,SLOT(postcmd()));
process=new QProcess( this );
if(parent)
myParent = parent;
process=new QProcess( this );
if(parent)
myParent = parent;
myTimer = new QTimer(this);
myCounter = new linboCounterImpl(this);
myTimer = new QTimer(this);
myCounter = new linboCounterImpl(this);
logConsole = new linboLogConsole(0);
logConsole = new linboLogConsole(0);
connect( myTimer, SIGNAL(timeout()), this, SLOT(processTimeout()) );
connect( myTimer, SIGNAL(timeout()), this, SLOT(processTimeout()) );
// connect SLOT for finished process
connect( process, SIGNAL(finished(int, QProcess::ExitStatus) ),
this, SLOT(processFinished(int, QProcess::ExitStatus)) );
// connect SLOT for finished process
connect( process, SIGNAL(finished(int, QProcess::ExitStatus) ),
this, SLOT(processFinished(int, QProcess::ExitStatus)) );
// connect stdout and stderr to linbo console
connect( process, SIGNAL(readyReadStandardOutput()),
this, SLOT(readFromStdout()) );
// connect stdout and stderr to linbo console
connect( process, SIGNAL(readyReadStandardOutput()),
this, SLOT(readFromStdout()) );
connect( process, SIGNAL(readyReadStandardError()),
this, SLOT(readFromStderr()) );
connect( process, SIGNAL(readyReadStandardError()),
this, SLOT(readFromStderr()) );
Qt::WindowFlags flags;
flags = Qt::Dialog | Qt::WindowStaysOnTopHint | Qt::WindowTitleHint;
setWindowFlags( flags );
Qt::WindowFlags flags;
flags = Qt::Dialog | Qt::WindowStaysOnTopHint | Qt::WindowTitleHint;
setWindowFlags( flags );
QRect qRect(QApplication::desktop()->screenGeometry());
// open in the upper left of our screen
int xpos=10;
int ypos=10;
this->move(xpos,ypos);
this->setFixedSize( this->width(), this->height() );
// open in the upper left of our screen
int xpos=10;
int ypos=10;
this->move(xpos,ypos);
this->setFixedSize( this->width(), this->height() );
}
linboPasswordBoxImpl::~linboPasswordBoxImpl()
{
delete myTimer;
delete process;
delete myCounter;
delete myTimer;
delete process;
delete myCounter;
}
void linboPasswordBoxImpl::precmd() {
// nothing to do
// nothing to do
}
void linboPasswordBoxImpl::postcmd() {
this->hide();
app = static_cast<linboGUIImpl*>( myMainApp );
this->hide();
app = static_cast<linboGUIImpl*>( myMainApp );
if( app ) {
// build authentication command
arguments.clear();
arguments.append("linbo_cmd");
arguments.append( "authenticate" );
arguments.append( app->config.get_server() );
arguments.append( "linbo" );
arguments.append( passwordInput->text() );
arguments.append( "linbo" );
if( app ) {
// build authentication command
arguments.clear();
arguments.append("linbo_cmd");
arguments.append( "authenticate" );
arguments.append( app->config.get_server() );
arguments.append( "linbo" );
arguments.append( passwordInput->text() );
arguments.append( "linbo" );
QStringList processargs( arguments );
QString command = processargs.takeFirst();
QStringList processargs( arguments );
QString command = processargs.takeFirst();
process->start( command, processargs );
process->start( command, processargs );
while( !process->waitForFinished(10000) ) {
};
// Console->insert( QString("Test linboPasswordBoxImpl exitCode() == ") + QString::number( process->exitCode() ) );
while( !process->waitForFinished(10000) ) {
};
if ( process->exitCode() == 0 ) {
if( app ) {
// Console->insert( QString("Test linboPasswordBoxImpl exitCode() == ") + QString::number( process->exitCode() ) );
// set password in all buttons
QStringList tmp;
if ( process->exitCode() == 0 ) {
if( app ) {
// set password in all buttons
QStringList tmp;
for( unsigned int i = 0; i < app->p_buttons.size(); i++ )
{
linboDialog* tmpDialog = app->p_buttons[i]->getLinboDialog();
if( tmpDialog ) {
// in this case, we have a sub-dialogue
tmp = tmpDialog->getCommand();
// fear the segmentation fault!
// fifth argument is password
if( tmp.size() > 4 ) {
for( unsigned int i = 0; i < app->p_buttons.size(); i++ )
{
if( tmp[1] == QString("upload") ||
tmp[1] == QString("register") ) {
// change upload password
tmp[4] = passwordInput->text();
tmpDialog->setCommand( tmp );
}
}
}
// this is for the case we have no associated linbo dialog
if( app->p_buttons[i] ) {
tmp.clear();
tmp = app->p_buttons[i]->getCommand();
// fifth argument is password
if( tmp.size() > 4 ) {
if( tmp[1] == QString("upload") ||
tmp[1] == QString("register") ) {
// change upload password
tmp[4] = passwordInput->text();
app->p_buttons[i]->setCommand( tmp );
}
}
}
}
app->enableButtons();
app->showImagingTab();
myTimer->stop();
myTimer->start( 1000, FALSE );
currentTimeout = app->config.get_roottimeout();
myCounter->counter->display( currentTimeout );
connect( myCounter->logoutButton, SIGNAL(pressed()), app, SLOT(resetButtons()) );
connect( myCounter->logoutButton, SIGNAL(clicked()), myTimer, SLOT(stop()) );
myCounter->show();
myCounter->raise();
myCounter->move( QPoint( 5, 5 ) );
}
linboDialog* tmpDialog = app->p_buttons[i]->getLinboDialog();
if( tmpDialog ) {
// in this case, we have a sub-dialogue
tmp = tmpDialog->getCommand();
// fear the segmentation fault!
// fifth argument is password
if( tmp.size() > 4 ) {
if( tmp[1] == QString("upload") ||
tmp[1] == QString("register") ) {
// change upload password
tmp[4] = passwordInput->text();
tmpDialog->setCommand( tmp );
}
}
}
// this is for the case we have no associated linbo dialog
if( app->p_buttons[i] ) {
tmp.clear();
tmp = app->p_buttons[i]->getCommand();
// fifth argument is password
if( tmp.size() > 4 ) {
if( tmp[1] == QString("upload") ||
tmp[1] == QString("register") ) {
// change upload password
tmp[4] = passwordInput->text();
app->p_buttons[i]->setCommand( tmp );
}
}
}
}
app->enableButtons();
app->showImagingTab();
myTimer->stop();
myTimer->start( 1000, FALSE );
currentTimeout = app->config.get_roottimeout();
myCounter->counter->display( currentTimeout );
connect( myCounter->logoutButton, SIGNAL(pressed()), app, SLOT(resetButtons()) );
connect( myCounter->logoutButton, SIGNAL(clicked()), myTimer, SLOT(stop()) );
myCounter->show();
myCounter->raise();
myCounter->move( QPoint( 5, 5 ) );
}
}
}
}
passwordInput->clear();
this->close();
passwordInput->clear();
this->close();
}
void linboPasswordBoxImpl::setCommand(const QStringList& arglist)
{
arguments = arglist;
arguments = arglist;
}
QStringList linboPasswordBoxImpl::getCommand()
{
return arguments;
return arguments;
}
void linboPasswordBoxImpl::setMainApp( QWidget* newMainApp ) {
if ( newMainApp ) {
myMainApp = newMainApp;
}
if ( newMainApp ) {
myMainApp = newMainApp;
}
}
void linboPasswordBoxImpl::readFromStdout()
{
logConsole->writeStdOut( process->readAllStandardOutput() );
logConsole->writeStdOut( process->readAllStandardOutput() );
}
void linboPasswordBoxImpl::readFromStderr()
{
logConsole->writeStdErr( process->readAllStandardError() );
logConsole->writeStdErr( process->readAllStandardError() );
}
void linboPasswordBoxImpl::setTextBrowser( const QString& new_consolefontcolorstdout,
const QString& new_consolefontcolorstderr,
QTextEdit* newBrowser )
const QString& new_consolefontcolorstderr,
QTextEdit* newBrowser )
{
logConsole->setLinboLogConsole( new_consolefontcolorstdout,
new_consolefontcolorstderr,
newBrowser );
logConsole->setLinboLogConsole( new_consolefontcolorstdout,
new_consolefontcolorstderr,
newBrowser );
}
void linboPasswordBoxImpl::processTimeout() {
if( !myCounter->timeoutCheck->isChecked() ) {
// do nothing but dont stop timer
}
else {
if( currentTimeout > 0 ) {
currentTimeout--;
myCounter->counter->display( currentTimeout );
if( !myCounter->timeoutCheck->isChecked() ) {
// do nothing but dont stop timer
}
else {
app->resetButtons();
myCounter->close();
if( currentTimeout > 0 ) {
currentTimeout--;
myCounter->counter->display( currentTimeout );
}
else {
app->resetButtons();
myCounter->close();
}
}
}
}
void linboPasswordBoxImpl::processFinished( int retval,
QProcess::ExitStatus status) {
QProcess::ExitStatus status) {
logConsole->writeResult( retval, status, process->error() );
logConsole->writeResult( retval, status, process->error() );
// app->restoreButtonsState();
// app->restoreButtonsState();
}

View File

@ -16,7 +16,7 @@
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "../headers/linbogui.h"
#include "linbogui.h"
LinboGui::LinboGui()
{
@ -29,9 +29,8 @@ LinboGui::LinboGui()
this->setFixedHeight(QApplication::desktop()->screenGeometry().height());
this->setFixedWidth(QApplication::desktop()->screenGeometry().width());
QFontDatabase db;
qDebug() << QFontDatabase::addApplicationFont(":/fonts/SegoeUI.ttf");
qDebug() << db.families();
// Load segoe font
QFontDatabase::addApplicationFont(":/fonts/SegoeUI.ttf");
// white bakground
// linuxmuster background color: #394f5e

View File

@ -35,8 +35,12 @@ LinboOs* LinboOsSelectButton::getOs() {
return this->os;
}
void LinboOsSelectButton::setVisibleAnimated(bool visible) {
this->button->setVisibleAnimated(visible);
}
void LinboOsSelectButton::setVisible(bool visible) {
this->button->setVisibleAnimated(visible, true);
this->button->setVisible(visible);
}
void LinboOsSelectButton::resizeEvent(QResizeEvent *event) {

View File

@ -1,7 +1,27 @@
#include "../headers/linboosselectionrow.h"
/****************************************************************************
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "linboosselectionrow.h"
LinboOsSelectionRow::LinboOsSelectionRow(LinboBackend* backend, QWidget *parent) : QWidget(parent)
{
this->inited = false;
this->backend = backend;
connect(this->backend, SIGNAL(stateChanged(LinboBackend::LinboState)), this, SLOT(handleLinboStateChanged(LinboBackend::LinboState)));
@ -20,29 +40,85 @@ LinboOsSelectionRow::LinboOsSelectionRow(LinboBackend* backend, QWidget *parent)
this->osButtons.append(osButton);
}
if(this->osButtons.length() == 0) {
this->noOsLabel = new QLabel(tr("No Operating system configured in start.conf"), this);
this->noOsLabel->hide();
this->noOsLabel->setAlignment(Qt::AlignCenter);
this->noOsLabelFont = QFont("Segoe UI");
this->noOsLabelFont.setBold(true);
this->noOsLabel->setFont(this->noOsLabelFont);
QString environmentValuesText;
environmentValuesText += tr("Host") + ": " + this->backend->getConfig()->getHostname() + "\n";
//noOsText += tr("Group") + ": " + this->backend->getConfig()->getHostGroup() + "\n";
environmentValuesText += tr("IP-Address") + ": " + this->backend->getConfig()->getIpAddress() + "\n";
//noOsText += tr("Server IP-Address") + ": " + this->backend->getConfig()->getServerIpAddress() + "\n";
environmentValuesText += tr("Mac-Address") + ": " + this->backend->getConfig()->getMacAddress() + "\n";
this->environmentValuesLabel = new QLabel(environmentValuesText, this);
this->environmentValuesLabel->hide();
this->environmentValuesLabel->setAlignment(Qt::AlignCenter);
this->environmentValuesLabelFont = QFont("Segoe UI");
this->environmentValuesLabel->setFont(this->environmentValuesLabelFont);
}
this->handleLinboStateChanged(this->backend->getState());
}
void LinboOsSelectionRow::resizeAndPositionAllButtons() {
int buttonWidth = this->width() / this->osButtonGroup->buttons().length();
if(this->showOnlySelectedButton) {
if(this->osButtons.length() > 0) {
int buttonWidth = 0;
buttonWidth = this->width() / this->osButtonGroup->buttons().length();
for(int i = 0; i < this->osButtons.length(); i++) {
if(!this->osButtons[i]->button->isChecked())
this->osButtons[i]->hide();
else {
QPropertyAnimation* moveAnimation = new QPropertyAnimation(this->osButtons[i], "geometry");
moveAnimation->setEasingCurve(QEasingCurve::InOutQuad);
moveAnimation->setDuration(400);
moveAnimation->setStartValue(this->osButtons[i]->geometry());
moveAnimation->setEndValue(QRect((this->width() - buttonWidth) / 2, 0, buttonWidth, this->height()));
moveAnimation->start();
}
bool visible = true;
QRect geometry = this->osButtons[i]->geometry();
if(!this->osButtons[i]->button->isChecked() || !this->showOnlySelectedButton) {
visible = !this->showOnlySelectedButton;
geometry = QRect(buttonWidth * i, 0, buttonWidth, this->height());
}
else {
visible = true;
geometry = QRect((this->width() - buttonWidth) / 2, 0, buttonWidth, this->height());
}
if(this->inited) {
this->osButtons[i]->setVisibleAnimated(visible);
QPropertyAnimation* moveAnimation = new QPropertyAnimation(this->osButtons[i], "geometry");
moveAnimation->setEasingCurve(QEasingCurve::InOutQuad);
moveAnimation->setDuration(400);
moveAnimation->setStartValue(this->osButtons[i]->geometry());
moveAnimation->setEndValue(geometry);
moveAnimation->start();
}
else {
// Do not animate the first time
this->osButtons[i]->setVisible(visible);
this->osButtons[i]->setGeometry(geometry);
}
}
}
else {
for(int i = 0; i < this->osButtons.length(); i++) {
this->osButtons[i]->setGeometry(buttonWidth * i, 0, buttonWidth, this->height());
}
int infoLabelHeight = this->height();
int infoLabelWidth = this->width() * 0.8;
int noOsLabelHeight = this->height() * 0.2;
this->noOsLabelFont.setPixelSize(noOsLabelHeight * 0.8);
this->noOsLabel->setFont(this->noOsLabelFont);
this->noOsLabel->setGeometry((this->width() - infoLabelWidth) / 2, 0, infoLabelWidth, noOsLabelHeight);
this->noOsLabel->show();
this->environmentValuesLabelFont.setPixelSize(infoLabelHeight * 0.1);
this->environmentValuesLabel->setFont(this->environmentValuesLabelFont);
this->environmentValuesLabel->setGeometry((this->width() - infoLabelWidth) / 2, noOsLabelHeight, infoLabelWidth, infoLabelHeight);
this->environmentValuesLabel->show();
}
this->inited = true;
}
void LinboOsSelectionRow::handleButtonToggled(bool checked) {
@ -67,7 +143,8 @@ void LinboOsSelectionRow::setShowOnlySelectedButton(bool value) {
this->showOnlySelectedButton = value;
this->resizeAndPositionAllButtons();
if(this->inited)
this->resizeAndPositionAllButtons();
}
void LinboOsSelectionRow::resizeEvent(QResizeEvent *event) {
@ -82,6 +159,7 @@ void LinboOsSelectionRow::handleLinboStateChanged(LinboBackend::LinboState newSt
this->setShowOnlySelectedButton(false);
break;
case LinboBackend::Autostarting:
case LinboBackend::Starting:
case LinboBackend::Syncing:
case LinboBackend::Reinstalling:

View File

@ -1,4 +1,22 @@
#include "../headers/linbostartactions.h"
/****************************************************************************
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "linbostartactions.h"
LinboStartActions::LinboStartActions(LinboBackend* backend, QWidget *parent) : QWidget(parent)
{
@ -24,6 +42,13 @@ LinboStartActions::LinboStartActions(LinboBackend* backend, QWidget *parent) : Q
this->reinstallOsButton = new QModernPushButton(":/svgIcons/resetAction.svg", this->buttonWidget);
connect(this->reinstallOsButton, SIGNAL(clicked()), this->backend, SLOT(reinstallCurrentOs()));
this->noBaseImageLabel = new QLabel(tr("No baseimage defined"), this->buttonWidget);
this->noBaseImageLabel->setStyleSheet("QLabel { color : red; }");
this->noBaseImageLabelFont = QFont("Segoe UI");
this->noBaseImageLabel->setFont(this->noBaseImageLabelFont);
this->noBaseImageLabel->hide();
this->noBaseImageLabel->setAlignment(Qt::AlignCenter);
this->stackView->addWidget(this->buttonWidget);
// Progress bar
@ -38,8 +63,10 @@ LinboStartActions::LinboStartActions(LinboBackend* backend, QWidget *parent) : Q
this->logFont = QFont("Segoe UI");
this->logLabel->setFont(this->logFont);
this->cancelButton = new QModernPushButton(":/svgIcons/cancel.svg", this->progressBarWidget);
connect(this->cancelButton, SIGNAL(clicked()), this->backend, SLOT(cancelCurrentAction()));
this->stackView->addWidget(this->progressBarWidget);
this->stackView->setCurrentWidget(nullptr);
connect(this->stackView, SIGNAL(currentChanged(int)), this, SLOT(resizeAndPositionAllItems()));
this->handleLinboStateChanged(this->backend->getState());
@ -91,9 +118,9 @@ void LinboStartActions::resizeAndPositionAllItems() {
positionsEnabled.append(false);
if(selectedOs != nullptr) {
positionsEnabled[startOsPosition] = selectedOs->getStartbutton();
positionsEnabled[syncOsPosition] = selectedOs->getSyncbutton();
positionsEnabled[reinstallOsPosition] = selectedOs->getNewbutton();
positionsEnabled[startOsPosition] = selectedOs->getStartActionEnabled();
positionsEnabled[syncOsPosition] = selectedOs->getSyncActionEnabled();
positionsEnabled[reinstallOsPosition] = selectedOs->getReinstallActionEnabled();
}
QList<QRect> geometries;
@ -149,17 +176,32 @@ void LinboStartActions::resizeAndPositionAllItems() {
}
}
if(selectedOs != nullptr && selectedOs->getBaseImage() == nullptr) {
int noBaseImageLabelHeight = this->height() * 0.2;
this->noBaseImageLabelFont.setPixelSize(noBaseImageLabelHeight * 0.8);
this->noBaseImageLabel->setFont(this->noBaseImageLabelFont);
this->noBaseImageLabel->setGeometry(0, (this->height() - noBaseImageLabelHeight) / 2, this->width(), noBaseImageLabelHeight);
this->noBaseImageLabel->show();
}
else {
this->noBaseImageLabel->hide();
}
// Progress bar
this->progressBarWidget->setFixedSize(this->size());
int progressBarHeight = this->height() * 0.1;
int progressBarWidth = this->width() * 0.5;
int logLabelHeight = progressBarHeight * 2;
int logLabelWidth = this->width() * 0.8;
progressBar->setGeometry((this->width() - progressBarWidth) / 2, (this->height() - logLabelHeight - progressBarHeight) / 2, progressBarWidth, progressBarHeight);
int cancelButtonWidth = this->height() * 0.4;
this->logFont.setPixelSize(logLabelHeight * 0.8);
this->logLabel->setFont(this->logFont);
this->logLabel->setGeometry((this->width() - logLabelWidth) / 2, this->height() - logLabelHeight, logLabelWidth, logLabelHeight);
this->logLabel->setGeometry((this->width() - logLabelWidth) / 2, 0, logLabelWidth, logLabelHeight);
progressBar->setGeometry((this->width() - progressBarWidth) / 2, this->logLabel->y() + logLabelHeight + this->height() * 0.15, progressBarWidth, progressBarHeight);
this->cancelButton->setGeometry((this->width() - cancelButtonWidth) / 2, this->progressBar->y() + progressBarHeight + this->height() * 0.05, cancelButtonWidth, cancelButtonWidth);
this->inited = true;
}
@ -180,7 +222,6 @@ void LinboStartActions::handleLinboStateChanged(LinboBackend::LinboState newStat
switch (newState) {
case LinboBackend::Autostarting:
qDebug() << "Linbo state is: autostart";
this->progressBar->setIndeterminate(false);
this->progressBar->setReversed(true);
this->progressBar->setValue(0);
@ -210,6 +251,9 @@ void LinboStartActions::handleLinboStateChanged(LinboBackend::LinboState newStat
void LinboStartActions::handleLatestLogChanged(const LinboLogger::LinboLog& latestLog) {
if(this->backend->getState() == LinboBackend::Idle)
return;
QString logColor = "black";
switch (latestLog.type) {
case LinboLogger::StdErr:

View File

@ -16,10 +16,11 @@
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "../headers/linbostartpage.h"
#include "linbostartpage.h"
LinboStartPage::LinboStartPage(LinboBackend* backend, QWidget *parent) : QWidget(parent)
{
this->inited = false;
this->backend = backend;
connect(this->backend, SIGNAL(stateChanged(LinboBackend::LinboState)), this, SLOT(handleLinboStateChanged(LinboBackend::LinboState)));
@ -54,7 +55,7 @@ LinboStartPage::LinboStartPage(LinboBackend* backend, QWidget *parent) : QWidget
mainLayout->addItem(new QSpacerItem(0,0, QSizePolicy::Minimum, QSizePolicy::Expanding));
QLabel* versionLabel = new QLabel(backend->getConfig()->getVersion() + " - mod by Dorian Zedler");
QLabel* versionLabel = new QLabel(backend->getConfig()->getLinboVersion() + " - mod by Dorian Zedler");
versionLabel->setFont(QFont("Segoe UI"));
mainLayout->addWidget(versionLabel);
@ -68,7 +69,7 @@ LinboStartPage::LinboStartPage(LinboBackend* backend, QWidget *parent) : QWidget
powerActionsLayoutWidget->setGeometry(QRect(this->width() - (width + margins), this->height() - (height + margins), width * 1.1, height));
QModernPushButton* settingsActionButton = new QModernPushButton(":/svgIcons/settingsAction.svg");
connect(settingsActionButton, SIGNAL(clicked()), legacyGui, SLOT(open()));
connect(settingsActionButton, SIGNAL(clicked()), legacyGui, SLOT(loginAndOpen()));
this->powerActionButtons.append(settingsActionButton);
settingsActionButton->setFixedHeight(buttonWidth);
settingsActionButton->setFixedWidth(buttonWidth);
@ -90,23 +91,29 @@ LinboStartPage::LinboStartPage(LinboBackend* backend, QWidget *parent) : QWidget
powerActionsLayout->addWidget(settingsActionButton);
powerActionsLayout->addWidget(rebootActionButton);
powerActionsLayout->addWidget(shutdownActionButton);
this->handleLinboStateChanged(this->backend->getState());
}
void LinboStartPage::handleLinboStateChanged(LinboBackend::LinboState newState) {
bool powerActionButtonsVisible = true;
switch (newState) {
case LinboBackend::Idle:
for(QModernPushButton* powerActionButton : this->powerActionButtons)
powerActionButton->setVisibleAnimated(true);
break;
case LinboBackend::Autostarting:
case LinboBackend::Starting:
case LinboBackend::Syncing:
case LinboBackend::Reinstalling:
for(QModernPushButton* powerActionButton : this->powerActionButtons)
powerActionButton->setVisibleAnimated(false);
powerActionButtonsVisible = false;
break;
default:
break;
}
for(QModernPushButton* powerActionButton : this->powerActionButtons)
if(this->inited)
powerActionButton->setVisibleAnimated(powerActionButtonsVisible);
else
powerActionButton->setVisible(powerActionButtonsVisible);
this->inited = true;
}

View File

@ -1,16 +1,5 @@
// STL-includes
#include <iostream>
#include <qwindowsystem_qws.h>
#include <QWSServer>
#include <qimage.h>
#include <qtimer.h>
// qt
#include <qapplication.h>
#include <QtGui>
#include <QPalette>
#include <QBrush>
#include <QScreen>
#include <QLocale>
#include <QApplication>
#include "linbogui.h"
@ -20,12 +9,7 @@ int main( int argc, char* argv[] )
QWSServer* wsServer = QWSServer::instance();
QImage bgimg( "/icons/linbo_wallpaper.png", "PNG" );
int width = qt_screen->deviceWidth();
int height = qt_screen->deviceHeight();
if ( wsServer ) {
wsServer->setBackground( QBrush( bgimg.scaled( width, height, Qt::IgnoreAspectRatio ) ) );
wsServer->refresh();
}

View File

@ -1,4 +1,22 @@
#include "../headers/qmodernprogressbar.h"
/****************************************************************************
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "qmodernprogressbar.h"
QModernProgressBar::QModernProgressBar(QWidget* parent) : QProgressBar(parent)
{

View File

@ -16,7 +16,7 @@
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "../headers/qmodernpushbutton.h"
#include "qmodernpushbutton.h"
QModernPushButton::QModernPushButton(QString icon, QWidget* parent) : QAbstractButton(parent)
{
@ -42,7 +42,7 @@ QModernPushButton::QModernPushButton(QString icon, QWidget* parent) : QAbstractB
this->overlays.append(overlay);
}
this->overlays[0]->setVisible(true);
this->overlays[0]->setVisibleAnimated(true);
this->overlays[0]->setAnimationDuration(200);
this->overlays[1]->setAnimationDuration(200);
this->overlays[2]->setAnimationDuration(100);
@ -54,7 +54,7 @@ void QModernPushButton::handleToggled(bool checked) {
if(checked)
emit this->checked();
if(this->overlays.length() >= 4)
this->overlays[3]->setVisible(checked);
this->overlays[3]->setVisibleAnimated(checked);
}
void QModernPushButton::resizeEvent(QResizeEvent *event) {
@ -76,12 +76,23 @@ void QModernPushButton::setGeometryAnimated(const QRect& geometry) {
this->geometryAnimation->start();
}
void QModernPushButton::setVisibleAnimated(bool visible, bool asynchronos) {
if(!this->isVisible())
void QModernPushButton::setVisibleAnimated(bool visible) {
if(!this->isVisible()) {
// if the parent was hidden
// -> Show it to be able to fade the overlays in
// -> Hide overlays to prevent them from appearing without an animation!
this->setVisible(true);
for(QModernPushButtonOverlay* overlay : this->overlays)
overlay->setVisible(false);
}
this->setEnabled(visible);
this->overlays[0]->setVisible(visible);
if(!visible)
for(QModernPushButtonOverlay* overlay : this->overlays)
overlay->setVisibleAnimated(false);
else
this->overlays[0]->setVisible(true);
}
void QModernPushButton::paintEvent(QPaintEvent *e) {
@ -101,24 +112,24 @@ void QModernPushButton::keyReleaseEvent(QKeyEvent *e) {
void QModernPushButton::enterEvent(QEvent *e) {
if(this->overlays.length() >= 2 && this->isEnabled())
this->overlays[1]->setVisible(true);
this->overlays[1]->setVisibleAnimated(true);
return QAbstractButton::enterEvent(e);
}
void QModernPushButton::leaveEvent(QEvent *e) {
if(this->overlays.length() >= 2)
this->overlays[1]->setVisible(false);
this->overlays[1]->setVisibleAnimated(false);
return QAbstractButton::leaveEvent(e);
}
void QModernPushButton::mousePressEvent(QMouseEvent *e) {
if(this->overlays.length() >= 3 && this->isEnabled())
this->overlays[2]->setVisible(true);
this->overlays[2]->setVisibleAnimated(true);
return QAbstractButton::mousePressEvent(e);
}
void QModernPushButton::mouseReleaseEvent(QMouseEvent *e) {
if(this->overlays.length() >= 3)
this->overlays[2]->setVisible(false);
this->overlays[2]->setVisibleAnimated(false);
return QAbstractButton::mouseReleaseEvent(e);
}

View File

@ -1,4 +1,22 @@
#include "../headers/qmodernpushbuttonoverlay.h"
/****************************************************************************
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "qmodernpushbuttonoverlay.h"
QModernPushButtonOverlay::QModernPushButtonOverlay(QWidget* overlayWidget, QObject *parent) : QObject(parent)
{
@ -28,6 +46,14 @@ void QModernPushButtonOverlay::setVisible(bool visible) {
if(this->widget->isVisible() == visible)
return;
this->effect->setOpacity(0);
this->widget->setVisible(visible);
}
void QModernPushButtonOverlay::setVisibleAnimated(bool visible) {
if(this->widget->isVisible() == visible)
return;
int startValue = visible ? 0:1;
this->animation->setStartValue(startValue);
this->animation->setEndValue(1-startValue);

View File

@ -1,4 +1,22 @@
#include "../headers/qmodernstackedwidget.h"
/****************************************************************************
** Modern Linbo GUI
** Copyright (C) 2020 Dorian Zedler <dorian@itsblue.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as published
** by the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "qmodernstackedwidget.h"
QModernStackedWidget::QModernStackedWidget(QWidget* parent) : QStackedWidget(parent)
{