diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9b2e52e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+Stacer.pro.user*
+dist/
+build/
+#*.AppImage
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..cad9d18
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Oguzhan Inan
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..995d9af
--- /dev/null
+++ b/README.md
@@ -0,0 +1,133 @@
+
+
+
+
+
+ Linux System Optimizer and Monitoring
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Reviews
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+### Required Packages
+- curl
+- systemd
+
+## Distribution independent installation
+
+- Install
+
+ Run `bash -c "$(wget https://gitlab.com/oguzhaninan/Stacer-Develop/raw/master/install.sh -O -)"`
+
+- Uninstall
+
+ Run `sudo bash uninstal-stacer`
+
+### Debian x64
+
+1. Download `stacer_1.0.8_amd64.deb` from the [Stacer releases page](https://github.com/oguzhaninan/Stacer/releases).
+2. Run `sudo dpkg -i stacer*.deb` on the downloaded package.
+3. Launch Stacer using the installed `stacer` command.
+
+### Fedora x64
+
+1. Download `stacer_1.0.8_amd64.rpm` from the [Stacer releases page](https://github.com/oguzhaninan/Stacer/releases).
+2. Run `sudo rpm --install stacer*.rpm` on the downloaded package.
+3. Launch Stacer using the installed `stacer` command.
+
+## Build from source
+
+1. `git clone https://github.com/oguzhaninan/Stacer.git`
+2. `cd Stacer`
+3. `./deploy.sh`
+
+## Screenshots
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Stacer.pro b/Stacer.pro
new file mode 100644
index 0000000..1abee39
--- /dev/null
+++ b/Stacer.pro
@@ -0,0 +1,5 @@
+TEMPLATE = subdirs
+
+SUBDIRS += \
+ stacer-core \
+ stacer
diff --git a/deploy.sh b/deploy.sh
new file mode 100755
index 0000000..1d2088c
--- /dev/null
+++ b/deploy.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+P_DIR=$(pwd)
+DIST_DIR=dist
+BUILD_DIR=build
+
+#export PATH=/qt/path/gcc_64/bin:$PATH
+#export QTDIR=/qt/path/gcc_64
+export QT_PLUGIN_PATH=$QTDIR/plugins
+export LD_LIBRARY_PATH=$QTDIR/lib
+
+#clean
+rm -rf dist
+
+mkdir -p $DIST_DIR/$BUILD_DIR
+cd $DIST_DIR/$BUILD_DIR
+
+#build
+$QTDIR/bin/qmake -spec linux-g++ "CONFIG += release" $P_DIR/Stacer.pro && make
+
+cd $P_DIR/$DIST_DIR/$BUILD_DIR/stacer-core && make
+cd $P_DIR/$DIST_DIR/$BUILD_DIR/stacer && make
+
+mkdir $P_DIR/$DIST_DIR/$BUILD_DIR/stacer/lib
+
+cp $P_DIR/$DIST_DIR/$BUILD_DIR/stacer-core/libstacer-core.so.1.0.0 $P_DIR/$DIST_DIR/$BUILD_DIR/stacer/lib/libstacer-core.so.1
+
+cd $P_DIR
+lrelease stacer/stacer.pro
+
+mkdir $P_DIR/$DIST_DIR/$BUILD_DIR/stacer/translations
+
+mv $P_DIR/translations/*.qm $P_DIR/$DIST_DIR/$BUILD_DIR/stacer/translations
+
+rm -rf $P_DIR/$DIST_DIR/$BUILD_DIR/stacer-core
+
+find $P_DIR/$DIST_DIR/$BUILD_DIR/stacer \( -name "moc_*" -or -name "*.o" -or -name "qrc_*" -or -name "Makefile*" -or -name "*.a" -or -name "*.h" \) -exec rm {} \;
+
+cd $P_DIR/$DIST_DIR/$BUILD_DIR/stacer &&
+cp $P_DIR/stacer/static/logo.png stacer.png &&
+cp $P_DIR/stacer.desktop stacer.desktop
+
+cd $P_DIR
+
+if [ "$1" == "appimage" ]; then
+ linuxdeployqt $DIST_DIR/$BUILD_DIR/stacer/stacer -no-translations -appimage
+else
+ linuxdeployqt $DIST_DIR/$BUILD_DIR/stacer/stacer -no-translations
+fi
+
+rm $P_DIR/$DIST_DIR/$BUILD_DIR/stacer/{AppRun,.DirIcon}
+
+
diff --git a/icons/hicolor/128x128/apps/stacer.png b/icons/hicolor/128x128/apps/stacer.png
new file mode 100644
index 0000000..2abbaf6
Binary files /dev/null and b/icons/hicolor/128x128/apps/stacer.png differ
diff --git a/icons/hicolor/16x16/apps/stacer.png b/icons/hicolor/16x16/apps/stacer.png
new file mode 100644
index 0000000..073fb3b
Binary files /dev/null and b/icons/hicolor/16x16/apps/stacer.png differ
diff --git a/icons/hicolor/256x256/apps/stacer.png b/icons/hicolor/256x256/apps/stacer.png
new file mode 100644
index 0000000..716367c
Binary files /dev/null and b/icons/hicolor/256x256/apps/stacer.png differ
diff --git a/icons/hicolor/32x32/apps/stacer.png b/icons/hicolor/32x32/apps/stacer.png
new file mode 100644
index 0000000..680d0d7
Binary files /dev/null and b/icons/hicolor/32x32/apps/stacer.png differ
diff --git a/icons/hicolor/64x64/apps/stacer.png b/icons/hicolor/64x64/apps/stacer.png
new file mode 100644
index 0000000..a41bbe5
Binary files /dev/null and b/icons/hicolor/64x64/apps/stacer.png differ
diff --git a/install.sh b/install.sh
new file mode 100755
index 0000000..cf50728
--- /dev/null
+++ b/install.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+APPIMAGE_FILE=
+DESKTOP_FILE=
+ICON=
+
+cd /tmp
+
+wget $APPIMAGE_FILE
+wget $DESKTOP_FILE
+wget $ICON
+
+sudo mv *.AppImage /usr/bin/stacer
+sudo chmod 755 /usr/bin/stacer
+
+sudo mv stacer.desktop /usr/share/applications/
+cp /usr/share/applications/stacer.desktop ~/Desktop
+
+sudo mv stacer.png /usr/share/icons/hicolor/128x128/apps/
+
+# uninstall file
+sudo touch /usr/bin/uninstall-stacer
+sudo bash -c "echo -e '#!/bin/bash
+
+sudo rm -f /usr/bin/stacer \\
+/usr/share/applications/stacer.desktop \\
+/usr/share/icons/hicolor/128x128/apps/stacer.png
+
+rm -f /usr/bin/uninstall-stacer
+
+echo Successfully uninstalled ' > /usr/bin/uninstall-stacer"
+
+echo "Successfully installed"
+
diff --git a/screenshots/Screenshot-2.0.0-1.png b/screenshots/Screenshot-2.0.0-1.png
new file mode 100644
index 0000000..7994f2b
Binary files /dev/null and b/screenshots/Screenshot-2.0.0-1.png differ
diff --git a/screenshots/Screenshot-2.0.0-10.png b/screenshots/Screenshot-2.0.0-10.png
new file mode 100644
index 0000000..36bcf0e
Binary files /dev/null and b/screenshots/Screenshot-2.0.0-10.png differ
diff --git a/screenshots/Screenshot-2.0.0-11.png b/screenshots/Screenshot-2.0.0-11.png
new file mode 100644
index 0000000..77e166c
Binary files /dev/null and b/screenshots/Screenshot-2.0.0-11.png differ
diff --git a/screenshots/Screenshot-2.0.0-12.png b/screenshots/Screenshot-2.0.0-12.png
new file mode 100644
index 0000000..f022a71
Binary files /dev/null and b/screenshots/Screenshot-2.0.0-12.png differ
diff --git a/screenshots/Screenshot-2.0.0-13.png b/screenshots/Screenshot-2.0.0-13.png
new file mode 100644
index 0000000..ad145df
Binary files /dev/null and b/screenshots/Screenshot-2.0.0-13.png differ
diff --git a/screenshots/Screenshot-2.0.0-2.png b/screenshots/Screenshot-2.0.0-2.png
new file mode 100644
index 0000000..261632b
Binary files /dev/null and b/screenshots/Screenshot-2.0.0-2.png differ
diff --git a/screenshots/Screenshot-2.0.0-3.png b/screenshots/Screenshot-2.0.0-3.png
new file mode 100644
index 0000000..be2303f
Binary files /dev/null and b/screenshots/Screenshot-2.0.0-3.png differ
diff --git a/screenshots/Screenshot-2.0.0-4.png b/screenshots/Screenshot-2.0.0-4.png
new file mode 100644
index 0000000..accb978
Binary files /dev/null and b/screenshots/Screenshot-2.0.0-4.png differ
diff --git a/screenshots/Screenshot-2.0.0-5.png b/screenshots/Screenshot-2.0.0-5.png
new file mode 100644
index 0000000..5c2463c
Binary files /dev/null and b/screenshots/Screenshot-2.0.0-5.png differ
diff --git a/screenshots/Screenshot-2.0.0-6.png b/screenshots/Screenshot-2.0.0-6.png
new file mode 100644
index 0000000..f15ad1e
Binary files /dev/null and b/screenshots/Screenshot-2.0.0-6.png differ
diff --git a/screenshots/Screenshot-2.0.0-7.png b/screenshots/Screenshot-2.0.0-7.png
new file mode 100644
index 0000000..61a9e75
Binary files /dev/null and b/screenshots/Screenshot-2.0.0-7.png differ
diff --git a/screenshots/Screenshot-2.0.0-8.png b/screenshots/Screenshot-2.0.0-8.png
new file mode 100644
index 0000000..712beaf
Binary files /dev/null and b/screenshots/Screenshot-2.0.0-8.png differ
diff --git a/screenshots/Screenshot-2.0.0-9.png b/screenshots/Screenshot-2.0.0-9.png
new file mode 100644
index 0000000..7e7d2bc
Binary files /dev/null and b/screenshots/Screenshot-2.0.0-9.png differ
diff --git a/screenshots/header.png b/screenshots/header.png
new file mode 100644
index 0000000..329a4f5
Binary files /dev/null and b/screenshots/header.png differ
diff --git a/stacer-core/Info/cpu_info.cpp b/stacer-core/Info/cpu_info.cpp
new file mode 100644
index 0000000..0da2ac6
--- /dev/null
+++ b/stacer-core/Info/cpu_info.cpp
@@ -0,0 +1,96 @@
+#include "cpu_info.h"
+
+CpuInfo::CpuInfo()
+{ }
+
+quint8 CpuInfo::getCpuCoreCount()
+{
+ static quint8 count = 0;
+
+ if (! count)
+ {
+ QStringList cpuinfo = FileUtil::readListFromFile(PROC_CPUINFO);
+
+ if (! cpuinfo.isEmpty())
+ count = cpuinfo.filter(QRegExp("^processor")).count();
+ }
+
+ return count;
+}
+
+QList CpuInfo::getCpuPercents()
+{
+ QList cpuTimes;
+
+ QList cpuPercents;
+
+ QStringList times = FileUtil::readListFromFile(PROC_STAT);
+
+ if (! times.isEmpty())
+ {
+ /* user nice system idle iowait irq softirq steal guest guest_nice
+ cpu 4705 356 584 3699 23 23 0 0 0 0
+ .
+ cpuN 4705 356 584 3699 23 23 0 0 0 0
+
+ The meanings of the columns are as follows, from left to right:
+ - user: normal processes executing in user mode
+ - nice: niced processes executing in user mode
+ - system: processes executing in kernel mode
+ - idle: twiddling thumbs
+ - iowait: waiting for I/O to complete
+ - irq: servicing interrupts
+ - softirq: servicing softirqs
+ - steal: involuntary wait
+ - guest: running a normal guest
+ - guest_nice: running a niced guest
+ */
+
+ for (int i = 0; i < CpuInfo::getCpuCoreCount()+1; ++i)
+ {
+ QStringList n_times = times.at(i).split(QRegExp("\\s+"));
+ n_times.removeFirst();
+ foreach (QString t, n_times)
+ cpuTimes << t.toDouble();
+
+ cpuPercents << getCpuPercent(cpuTimes, i);
+
+ cpuTimes.clear();
+ }
+ }
+
+ return cpuPercents;
+}
+
+int CpuInfo::getCpuPercent(QListcpuTimes, int processor)
+{
+ const int N = getCpuCoreCount()+1;
+
+ static QVector l_idles(N);
+ static QVector l_totals(N);
+
+ double idle, total,
+ idle_delta, total_delta;
+
+ int utilisation = 0;
+
+ if (cpuTimes.count() > 0) {
+
+ idle = cpuTimes.at(3) + cpuTimes.at(4); // get (idle + iowait)
+ foreach (double t, cpuTimes) total += t; // get total time
+
+ idle_delta = idle - l_idles[processor];
+ total_delta = total - l_totals[processor];
+
+ if (total_delta)
+ utilisation = 100 * ((total_delta - idle_delta) / total_delta);
+
+ l_idles[processor] = idle;
+ l_totals[processor] = total;
+ }
+
+ if (utilisation > 100) utilisation = 100;
+ else if (utilisation < 0) utilisation = 0;
+
+ return utilisation;
+}
diff --git a/stacer-core/Info/cpu_info.h b/stacer-core/Info/cpu_info.h
new file mode 100644
index 0000000..0b26d48
--- /dev/null
+++ b/stacer-core/Info/cpu_info.h
@@ -0,0 +1,29 @@
+#ifndef CPUINFO_H
+#define CPUINFO_H
+
+#include
+#include
+#include
+
+#include "Utils/file_util.h"
+
+#define PROC_CPUINFO "/proc/cpuinfo"
+#define PROC_STAT "/proc/stat"
+
+#include "stacer-core_global.h"
+
+class STACERCORESHARED_EXPORT CpuInfo : public QObject
+{
+ Q_OBJECT
+
+public:
+ CpuInfo();
+
+ quint8 getCpuCoreCount();
+ QList getCpuPercents();
+
+private:
+ int getCpuPercent(QListcpuTimes, int processor = 0);
+};
+
+#endif // CPUINFO_H
diff --git a/stacer-core/Info/disk_info.cpp b/stacer-core/Info/disk_info.cpp
new file mode 100644
index 0000000..2f2872c
--- /dev/null
+++ b/stacer-core/Info/disk_info.cpp
@@ -0,0 +1,31 @@
+#include "disk_info.h"
+#include
+
+DiskInfo::DiskInfo()
+{
+
+}
+
+QList DiskInfo::getDisks() const
+{
+ return disks;
+}
+
+void DiskInfo::updateDiskInfo()
+{
+ try {
+ QStringList result = CommandUtil::exec("df -Pl").split("\n");
+
+ foreach(QString line, result.filter(QRegExp("^/")))
+ {
+ Disk disk;
+ disk.size = line.split(QRegExp("\\s+")).at(1).toLong() << 10;
+ disk.used = line.split(QRegExp("\\s+")).at(2).toLong() << 10;
+ disk.free = line.split(QRegExp("\\s+")).at(3).toLong() << 10;
+
+ disks << disk;
+ }
+ } catch (QString &ex) {
+ qCritical() << ex;
+ }
+}
diff --git a/stacer-core/Info/disk_info.h b/stacer-core/Info/disk_info.h
new file mode 100644
index 0000000..6676c0e
--- /dev/null
+++ b/stacer-core/Info/disk_info.h
@@ -0,0 +1,37 @@
+#ifndef DISKINFO_H
+#define DISKINFO_H
+
+#include
+#include "Utils/command_util.h"
+#include "Utils/file_util.h"
+
+#define PROC_MOUNTS "/proc/mounts"
+
+class Disk;
+
+#include "stacer-core_global.h"
+
+class STACERCORESHARED_EXPORT DiskInfo : public QObject
+{
+ Q_OBJECT
+
+public:
+ DiskInfo();
+
+ QList getDisks() const;
+ void updateDiskInfo();
+
+private:
+ QList disks;
+};
+
+class Disk {
+public:
+ Disk() {}
+
+ quint64 size;
+ quint64 free;
+ quint64 used;
+};
+
+#endif // DISKINFO_H
diff --git a/stacer-core/Info/memory_info.cpp b/stacer-core/Info/memory_info.cpp
new file mode 100644
index 0000000..32149e8
--- /dev/null
+++ b/stacer-core/Info/memory_info.cpp
@@ -0,0 +1,53 @@
+#include "memory_info.h"
+
+MemoryInfo::MemoryInfo():
+ memTotal(0),
+ memAvailable(0),
+ memUsed(0)
+{ }
+
+void MemoryInfo::updateMemoryInfo()
+{
+ QStringList lines = FileUtil::readListFromFile(PROC_MEMINFO)
+ .filter(QRegExp("^MemTotal|^MemAvailable|^SwapTotal|^SwapFree"));
+
+ #define getValue(l) lines.at(l).split(QRegExp("\\s+")).at(1).toLong() << 10;
+ memTotal = getValue(0);
+ memAvailable = getValue(1);
+ swapTotal = getValue(2);
+ swapFree = getValue(3)
+ #undef getValue
+
+ memUsed = (memTotal - memAvailable);
+ swapUsed = (swapTotal - swapFree);
+}
+
+quint64 MemoryInfo::getSwapUsed() const
+{
+ return swapUsed;
+}
+
+quint64 MemoryInfo::getSwapFree() const
+{
+ return swapFree;
+}
+
+quint64 MemoryInfo::getSwapTotal() const
+{
+ return swapTotal;
+}
+
+quint64 MemoryInfo::getMemUsed() const
+{
+ return memUsed;
+}
+
+quint64 MemoryInfo::getMemAvailable() const
+{
+ return memAvailable;
+}
+
+quint64 MemoryInfo::getMemTotal() const
+{
+ return memTotal;
+}
diff --git a/stacer-core/Info/memory_info.h b/stacer-core/Info/memory_info.h
new file mode 100644
index 0000000..a73469f
--- /dev/null
+++ b/stacer-core/Info/memory_info.h
@@ -0,0 +1,42 @@
+#ifndef MEMORYINFO_H
+#define MEMORYINFO_H
+
+#include
+
+#include
+#include "Utils/file_util.h"
+
+#define PROC_MEMINFO "/proc/meminfo"
+
+#include "stacer-core_global.h"
+
+class STACERCORESHARED_EXPORT MemoryInfo : public QObject
+{
+ Q_OBJECT
+
+public:
+ MemoryInfo();
+
+ void updateMemoryInfo();
+
+ quint64 getMemTotal() const;
+ quint64 getMemAvailable() const;
+ quint64 getMemUsed() const;
+
+ quint64 getSwapTotal() const;
+ quint64 getSwapFree() const;
+ quint64 getSwapUsed() const;
+
+private:
+ // memory
+ quint64 memTotal;
+ quint64 memAvailable;
+ quint64 memUsed;
+
+ // swap
+ quint64 swapTotal;
+ quint64 swapFree;
+ quint64 swapUsed;
+};
+
+#endif // MEMORYINFO_H
diff --git a/stacer-core/Info/network_info.cpp b/stacer-core/Info/network_info.cpp
new file mode 100644
index 0000000..c7e7ecb
--- /dev/null
+++ b/stacer-core/Info/network_info.cpp
@@ -0,0 +1,43 @@
+#include "network_info.h"
+
+NetworkInfo::NetworkInfo()
+{
+ QStringList lines = FileUtil::readListFromFile(PROC_NET_ROUTE);
+
+ if(lines.count() > 2)
+ defaultNetworkInterface = lines
+ .at(2)
+ .split(QRegExp("\\s+"))
+ .first();
+ else
+ defaultNetworkInterface = "";
+
+ rxPath = QString("/sys/class/net/%1/statistics/rx_bytes")
+ .arg(defaultNetworkInterface);
+
+ txPath = QString("/sys/class/net/%1/statistics/tx_bytes")
+ .arg(defaultNetworkInterface);
+}
+
+QString NetworkInfo::getDefaultNetworkInterface() const
+{
+ return defaultNetworkInterface;
+}
+
+quint64 NetworkInfo::getRXbytes()
+{
+ quint64 rx = FileUtil::readStringFromFile(rxPath)
+ .trimmed()
+ .toLong();
+
+ return rx;
+}
+
+quint64 NetworkInfo::getTXbytes()
+{
+ quint64 tx = FileUtil::readStringFromFile(txPath)
+ .trimmed()
+ .toLong();
+
+ return tx;
+}
diff --git a/stacer-core/Info/network_info.h b/stacer-core/Info/network_info.h
new file mode 100644
index 0000000..430d0dc
--- /dev/null
+++ b/stacer-core/Info/network_info.h
@@ -0,0 +1,33 @@
+#ifndef NETWORK_INFO_H
+#define NETWORK_INFO_H
+
+#include
+#include
+
+#include "Utils/file_util.h"
+#include "Utils/command_util.h"
+
+#define PROC_NET_ROUTE "/proc/net/route"
+
+#include "stacer-core_global.h"
+
+class STACERCORESHARED_EXPORT NetworkInfo : public QObject
+{
+ Q_OBJECT
+
+public:
+ NetworkInfo();
+
+ QString getDefaultNetworkInterface() const;
+
+ quint64 getRXbytes();
+ quint64 getTXbytes();
+
+private:
+ QString defaultNetworkInterface;
+
+ QString rxPath;
+ QString txPath;
+};
+
+#endif // NETWORK_INFO_H
diff --git a/stacer-core/Info/process.cpp b/stacer-core/Info/process.cpp
new file mode 100644
index 0000000..6c758e3
--- /dev/null
+++ b/stacer-core/Info/process.cpp
@@ -0,0 +1,146 @@
+#include "process.h"
+
+Process::Process()
+{
+
+}
+
+pid_t Process::getPid() const
+{
+ return pid;
+}
+
+void Process::setPid(const pid_t &value)
+{
+ pid = value;
+}
+
+quint64 Process::getRss() const
+{
+ return rss;
+}
+
+void Process::setRss(const quint64 &value)
+{
+ rss = value;
+}
+
+double Process::getPmem() const
+{
+ return pmem;
+}
+
+void Process::setPmem(double value)
+{
+ pmem = value;
+}
+
+quint64 Process::getVsize() const
+{
+ return vsize;
+}
+
+void Process::setVsize(const quint64 &value)
+{
+ vsize = value;
+}
+
+QString Process::getUname() const
+{
+ return uname;
+}
+
+void Process::setUname(const QString &value)
+{
+ uname = value;
+}
+
+double Process::getPcpu() const
+{
+ return pcpu;
+}
+
+void Process::setPcpu(double value)
+{
+ pcpu = value;
+}
+
+QString Process::getCmd() const
+{
+ return cmd;
+}
+
+void Process::setCmd(const QString &value)
+{
+ cmd = value;
+}
+
+QString Process::getStartTime() const
+{
+ return startTime;
+}
+
+void Process::setStartTime(const QString &value)
+{
+ startTime = value;
+}
+
+QString Process::getState() const
+{
+ return state;
+}
+
+void Process::setState(const QString &value)
+{
+ state = value;
+}
+
+QString Process::getGroup() const
+{
+ return group;
+}
+
+void Process::setGroup(const QString &value)
+{
+ group = value;
+}
+
+int Process::getNice() const
+{
+ return nice;
+}
+
+void Process::setNice(int value)
+{
+ nice = value;
+}
+
+QString Process::getCpuTime() const
+{
+ return cpuTime;
+}
+
+void Process::setCpuTime(const QString &value)
+{
+ cpuTime = value;
+}
+
+QString Process::getSession() const
+{
+ return session;
+}
+
+void Process::setSession(const QString &value)
+{
+ session = value;
+}
+
+QString Process::getSeat() const
+{
+ return seat;
+}
+
+void Process::setSeat(const QString &value)
+{
+ seat = value;
+}
diff --git a/stacer-core/Info/process.h b/stacer-core/Info/process.h
new file mode 100644
index 0000000..0b4e3a7
--- /dev/null
+++ b/stacer-core/Info/process.h
@@ -0,0 +1,80 @@
+#ifndef PROCESS_H
+#define PROCESS_H
+
+#include
+
+#include
+#include "Utils/file_util.h"
+
+// defines
+#define PROC_PID_CMD "/proc/%1/comm"
+#define PROC_PID_STATUS "/proc/%1/comm"
+
+#include "stacer-core_global.h"
+
+class STACERCORESHARED_EXPORT Process {
+
+public:
+ Process();
+
+ pid_t getPid() const;
+ void setPid(const pid_t &value);
+
+ quint64 getRss() const;
+ void setRss(const quint64 &value);
+
+ double getPmem() const;
+ void setPmem(double value);
+
+ quint64 getVsize() const;
+ void setVsize(const quint64 &value);
+
+ QString getUname() const;
+ void setUname(const QString &value);
+
+ double getPcpu() const;
+ void setPcpu(double value);
+
+ QString getStartTime() const;
+ void setStartTime(const QString &value);
+
+ QString getState() const;
+ void setState(const QString &value);
+
+ QString getGroup() const;
+ void setGroup(const QString &value);
+
+ int getNice() const;
+ void setNice(int value);
+
+ QString getCpuTime() const;
+ void setCpuTime(const QString &value);
+
+ QString getSession() const;
+ void setSession(const QString &value);
+
+ QString getSeat() const;
+ void setSeat(const QString &value);
+
+ QString getCmd() const;
+ void setCmd(const QString &value);
+
+private:
+ pid_t pid;
+ quint64 rss;
+ double pmem;
+ quint64 vsize;
+ QString uname;
+ double pcpu;
+ QString startTime;
+ QString state;
+ QString group;
+ int nice;
+ QString cpuTime;
+ QString session;
+ QString seat;
+ QString cmd;
+};
+
+
+#endif // PROCESS_H
diff --git a/stacer-core/Info/process_info.cpp b/stacer-core/Info/process_info.cpp
new file mode 100644
index 0000000..1d98d65
--- /dev/null
+++ b/stacer-core/Info/process_info.cpp
@@ -0,0 +1,56 @@
+#include "process_info.h"
+
+ProcessInfo::ProcessInfo()
+{
+
+}
+
+void ProcessInfo::updateProcesses()
+{
+ processList.clear();
+
+ try {
+
+ QStringList columns = { "pid", "rss", "pmem", "vsize", "uname", "pcpu", "start_time",
+ "state", "group", "nice", "cputime", "session", "seat", "cmd"};
+
+ QStringList lines = CommandUtil::exec("ps", {"ax", "-eo", columns.join(","), "--no-headings"})
+ .trimmed()
+ .split("\n");
+
+ if (! lines.isEmpty()) {
+ foreach (QString line, lines) {
+ QStringList procLine = line.trimmed().split(QRegExp("\\s+"));
+
+ if (procLine.count() >= columns.count()) {
+ Process proc;
+
+ proc.setPid(procLine.at(0).toLong());
+ proc.setRss(procLine.at(1).toLong() << 10);
+ proc.setPmem(procLine.at(2).toDouble());
+ proc.setVsize(procLine.at(3).toLong() << 10);
+ proc.setUname(procLine.at(4));
+ proc.setPcpu(procLine.at(5).toDouble());
+ proc.setStartTime(procLine.at(6));
+ proc.setState(procLine.at(7));
+ proc.setGroup(procLine.at(8));
+ proc.setNice(procLine.at(9).toInt());
+ proc.setCpuTime(procLine.at(10));
+ proc.setSession(procLine.at(11));
+ proc.setSeat(procLine.at(12));
+ proc.setCmd(procLine.at(13));
+
+ processList << proc;
+ }
+ }
+ }
+
+ } catch (QString &ex) {
+ qCritical() << ex;
+ }
+}
+
+QList ProcessInfo::getProcessList() const
+{
+ return processList;
+}
diff --git a/stacer-core/Info/process_info.h b/stacer-core/Info/process_info.h
new file mode 100644
index 0000000..d3c857e
--- /dev/null
+++ b/stacer-core/Info/process_info.h
@@ -0,0 +1,30 @@
+#ifndef PROCESS_INFO_H
+#define PROCESS_INFO_H
+
+#include
+#include
+
+#include
+#include
+#include "process.h"
+
+#define PROC_PID_CMD "/proc/%1/comm"
+
+#include "stacer-core_global.h"
+
+class STACERCORESHARED_EXPORT ProcessInfo : public QObject
+{
+ Q_OBJECT
+
+public:
+ ProcessInfo();
+ QList getProcessList() const;
+
+public slots:
+ void updateProcesses();
+
+private:
+ QList processList;
+};
+
+#endif // PROCESS_INFO_H
diff --git a/stacer-core/Info/system_info.cpp b/stacer-core/Info/system_info.cpp
new file mode 100644
index 0000000..54bd439
--- /dev/null
+++ b/stacer-core/Info/system_info.cpp
@@ -0,0 +1,104 @@
+#include "system_info.h"
+
+SystemInfo::SystemInfo() :
+ info(new QSysInfo)
+{
+ QStringList lines = FileUtil::readListFromFile(PROC_CPUINFO)
+ .filter(QRegExp("^model name"));
+
+ if (! lines.isEmpty()) {
+ QStringList model = lines.first().split(":").at(1).split("@");
+
+ if ( model.count() > 1) {
+ this->cpuModel = model.at(0).trimmed().replace(QRegExp("\\s+"), " ");
+ this->cpuSpeed = model.at(1).trimmed().replace(QRegExp("\\s+"), " ");
+ }
+ }
+ else {
+ this->cpuModel = tr("Unknown");
+ this->cpuSpeed = tr("Unknown");
+ }
+
+ CpuInfo ci;
+ this->cpuCore = QString::number(ci.getCpuCoreCount());
+
+ // get username
+ QString name = qgetenv("USER");
+
+ if (name.isEmpty())
+ name = qgetenv("USERNAME");
+
+ try {
+ if (name.isEmpty())
+ name = CommandUtil::exec("whoami").trimmed();
+ } catch (QString &ex) {
+ qCritical() << ex;
+ }
+
+ username = name;
+}
+
+QString SystemInfo::getUsername() const
+{
+ return username;
+}
+
+QString SystemInfo::getHostname()
+{
+ return QSysInfo::machineHostName();
+}
+
+QString SystemInfo::getPlatform()
+{
+ return QString("%1 %2")
+ .arg(QSysInfo::kernelType())
+ .arg(QSysInfo::currentCpuArchitecture());
+}
+
+QString SystemInfo::getDistribution()
+{
+ return QSysInfo::prettyProductName();
+}
+
+QString SystemInfo::getKernel()
+{
+ return QSysInfo::kernelVersion();
+}
+
+QString SystemInfo::getCpuModel()
+{
+ return this->cpuModel;
+}
+
+QString SystemInfo::getCpuSpeed()
+{
+ return this->cpuSpeed;
+}
+
+QString SystemInfo::getCpuCore()
+{
+ return this->cpuCore;
+}
+
+QFileInfoList SystemInfo::getCrashReports()
+{
+ QDir reports("/var/crash");
+
+ return reports.entryInfoList(QDir::Files);
+}
+
+QFileInfoList SystemInfo::getAppLogs()
+{
+ QDir logs("/var/log");
+
+ return logs.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
+}
+
+QFileInfoList SystemInfo::getAppCaches()
+{
+ QString homePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
+
+ QDir caches(homePath + "/.cache");
+
+ return caches.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
+}
diff --git a/stacer-core/Info/system_info.h b/stacer-core/Info/system_info.h
new file mode 100644
index 0000000..acebe82
--- /dev/null
+++ b/stacer-core/Info/system_info.h
@@ -0,0 +1,47 @@
+#ifndef SYSTEMINFO_H
+#define SYSTEMINFO_H
+
+#include
+#include
+#include
+#include
+
+#include "Utils/file_util.h"
+#include "Utils/format_util.h"
+#include "Utils/command_util.h"
+#include "Info/cpu_info.h"
+
+#define PROC_CPUINFO "/proc/cpuinfo"
+
+#include "stacer-core_global.h"
+class STACERCORESHARED_EXPORT SystemInfo : public QObject
+{
+ Q_OBJECT
+public:
+ SystemInfo();
+
+ QString getHostname();
+ QString getPlatform();
+ QString getDistribution();
+ QString getKernel();
+ QString getCpuModel();
+ QString getCpuSpeed();
+ QString getCpuCore();
+
+ QFileInfoList getCrashReports();
+ QFileInfoList getAppLogs();
+ QFileInfoList getAppCaches();
+
+ QString getUsername() const;
+
+private:
+ QString cpuCore;
+ QString cpuModel;
+ QString cpuSpeed;
+
+ QSysInfo *info;
+
+ QString username;
+};
+
+#endif // SYSTEMINFO_H
diff --git a/stacer-core/Tools/package_tool.cpp b/stacer-core/Tools/package_tool.cpp
new file mode 100644
index 0000000..f7a6cb0
--- /dev/null
+++ b/stacer-core/Tools/package_tool.cpp
@@ -0,0 +1,168 @@
+#include "package_tool.h"
+
+PackageTool::PackageTool()
+{
+ if (CommandUtil::isExecutable("apt-get")) {
+ currentPackageTool = APT;
+ } else if (CommandUtil::isExecutable("dnf")) {
+ currentPackageTool = DNF;
+ } else if (CommandUtil::isExecutable("yum")) {
+ currentPackageTool = YUM;
+ } else if (CommandUtil::isExecutable("pacman")) {
+ currentPackageTool = PACMAN;
+ } else if (CommandUtil::isExecutable("zypper")) {
+ currentPackageTool = ZYPPER;
+ } else {
+ currentPackageTool = UNKNOWN;
+ }
+}
+
+PackageTool::PackageTools PackageTool::getCurrentPackageTool() const
+{
+ return currentPackageTool;
+}
+
+/***********
+ * DPKG /var/cache/yum/development/packages/
+ ***********/
+QFileInfoList PackageTool::getDpkgPackageCaches()
+{
+ QDir caches("/var/cache/apt/archives/");
+
+ return caches.entryInfoList(QDir::Files);
+}
+
+QStringList PackageTool::getDpkgPackages()
+{
+ QStringList packageList = {};
+
+ try {
+ packageList = CommandUtil::exec("bash", {"-c", "dpkg --get-selections 2> /dev/null"})
+ .trimmed()
+ .split("\n");
+
+ for (int i = 0; i < packageList.count(); ++i)
+ packageList[i] = packageList.at(i).split(QRegExp("\\s+")).first();
+
+ } catch(QString &ex) {
+ qCritical() << ex;
+ }
+
+ return packageList;
+}
+
+bool PackageTool::dpkgRemovePackages(QStringList packages)
+{
+ try {
+ packages.insert(0, "remove");
+ packages.insert(1, "-y");
+
+ CommandUtil::sudoExec("apt-get", packages);
+
+ return true;
+
+ } catch(QString &ex) {
+ qCritical() << ex;
+ }
+
+ return false;
+}
+
+/**********
+ * RPM
+ **********/
+QStringList PackageTool::getRpmPackages()
+{
+ QStringList packageList = {};
+
+ try {
+ packageList = CommandUtil::exec("bash", {"-c", "rpm -qa 2> /dev/null"})
+ .trimmed()
+ .split("\n");
+
+ } catch(QString &ex) {
+ qCritical() << ex;
+ }
+
+ return packageList;
+}
+
+bool PackageTool::dnfRemovePackages(QStringList packages)
+{
+ try {
+ packages.insert(0, "remove");
+ packages.insert(1, "-y");
+
+ CommandUtil::sudoExec("dnf", packages);
+
+ return true;
+
+ } catch(QString &ex) {
+ qCritical() << ex;
+ }
+
+ return false;
+}
+
+bool PackageTool::yumRemovePackages(QStringList packages)
+{
+ try {
+ packages.insert(0, "remove");
+ packages.insert(1, "-y");
+
+ CommandUtil::sudoExec("yum", packages);
+
+ return true;
+
+ } catch(QString &ex) {
+ qCritical() << ex;
+ }
+
+ return false;
+}
+
+/**********
+ * PACMAN
+ **********/
+QFileInfoList PackageTool::getPacmanPackageCaches()
+{
+ QDir caches("/var/cache/pacman/pkg/");
+
+ return caches.entryInfoList(QDir::Files);
+}
+
+QStringList PackageTool::getPacmanPackages()
+{
+ QStringList packageList = {};
+
+ try {
+ packageList = CommandUtil::exec("bash", {"-c", "pacman -Q 2> /dev/null"})
+ .trimmed()
+ .split("\n");
+
+ for (int i = 0; i < packageList.count(); ++i)
+ packageList[i] = packageList.at(i).split(QRegExp("\\s+")).first();
+
+ } catch(QString &ex) {
+ qCritical() << ex;
+ }
+
+ return packageList;
+}
+
+bool PackageTool::pacmanRemovePackages(QStringList packages)
+{
+ try {
+ packages.push_back("--noconfirm");
+ packages.push_back("-R");
+
+ CommandUtil::sudoExec("pacman", packages);
+
+ return true;
+
+ } catch(QString &ex) {
+ qCritical() << ex;
+ }
+
+ return false;
+}
diff --git a/stacer-core/Tools/package_tool.h b/stacer-core/Tools/package_tool.h
new file mode 100644
index 0000000..b81af65
--- /dev/null
+++ b/stacer-core/Tools/package_tool.h
@@ -0,0 +1,51 @@
+#ifndef PACKAGE_TOOL_H
+#define PACKAGE_TOOL_H
+
+#include
+#include
+#include
+
+#include "Utils/command_util.h"
+#include "Utils/file_util.h"
+
+#include "stacer-core_global.h"
+
+class STACERCORESHARED_EXPORT PackageTool : public QObject
+{
+ Q_OBJECT
+
+public:
+ enum PackageTools {
+ APT, // debian
+ DNF, // fedora
+ YUM, // fedora
+ PACMAN, // arch
+ ZYPPER, // opensuse
+ UNKNOWN
+ };
+
+public:
+ PackageTool();
+
+public slots:
+ // APT
+ QFileInfoList getDpkgPackageCaches();
+ QStringList getDpkgPackages();
+ bool dpkgRemovePackages(QStringList packages);
+
+ // DNF - YUM
+ QStringList getRpmPackages();
+ bool dnfRemovePackages(QStringList packages);
+ bool yumRemovePackages(QStringList packages);
+
+ // Arch
+ QFileInfoList getPacmanPackageCaches();
+ QStringList getPacmanPackages();
+ bool pacmanRemovePackages(QStringList packages);
+
+ PackageTools getCurrentPackageTool() const;
+private:
+ PackageTools currentPackageTool;
+};
+
+#endif // PACKAGE_TOOL_H
diff --git a/stacer-core/Tools/service_tool.cpp b/stacer-core/Tools/service_tool.cpp
new file mode 100644
index 0000000..399b391
--- /dev/null
+++ b/stacer-core/Tools/service_tool.cpp
@@ -0,0 +1,104 @@
+#include "service_tool.h"
+
+ServiceTool::ServiceTool()
+{
+
+}
+
+QList ServiceTool::getServicesWithSystemctl()
+{
+ QList services = {};
+
+ try {
+
+ QStringList args = { "list-unit-files", "-t", "service", "-a", "--state=enabled,disabled" };
+
+ QStringList lines = CommandUtil::exec("systemctl", args)
+ .split("\n")
+ .filter(QRegExp("[^@].service"));
+
+ foreach(QString line, lines)
+ {
+ // e.g apache2.service [enabled|disabled]
+ QStringList s = line.trimmed().split(QRegExp("\\s+"));
+
+ QString name = s.first().trimmed().replace(".service", "");
+ bool status = ! s.last().trimmed().compare("enabled");
+ bool active = serviceIsActive(s.first().trimmed());
+
+ Service service(name, status, active);
+
+ services << service;
+ }
+
+ } catch(QString &ex) {
+ qCritical() << ex;
+ }
+
+ return services;
+}
+
+
+bool ServiceTool::serviceIsActive(QString serviceName)
+{
+ QStringList args = { "is-active", serviceName };
+
+ QString result("");
+
+ try {
+ result = CommandUtil::exec("systemctl", args);
+ } catch(QString &ex) {
+ qCritical() << ex;
+ }
+
+ return ! result.trimmed().compare("active");
+}
+
+bool ServiceTool::serviceIsEnabled(QString serviceName)
+{
+ QStringList args = { "is-enabled", serviceName };
+
+ QString result("");
+
+ try {
+ result = CommandUtil::exec("systemctl", args);
+ } catch(QString &ex) {
+ qCritical() << ex;
+ }
+
+ return ! result.trimmed().compare("enabled");
+}
+
+bool ServiceTool::changeServiceStatus(QString sname, bool status)
+{
+ try {
+
+ QStringList args = { (status ? "enable" : "disable") , sname };
+
+ CommandUtil::sudoExec("systemctl", args);
+
+ return true;
+
+ } catch(QString &ex) {
+ qCritical() << ex;
+ }
+
+ return false;
+}
+
+bool ServiceTool::changeServiceActive(QString sname, bool status)
+{
+ try {
+
+ QStringList args = { (status ? "start" : "stop") , sname };
+
+ CommandUtil::sudoExec("systemctl", args);
+
+ return true;
+
+ } catch(QString &ex) {
+ qCritical() << ex;
+ }
+
+ return false;
+}
diff --git a/stacer-core/Tools/service_tool.h b/stacer-core/Tools/service_tool.h
new file mode 100644
index 0000000..55a7ca5
--- /dev/null
+++ b/stacer-core/Tools/service_tool.h
@@ -0,0 +1,40 @@
+#ifndef SERVICE_TOOL_H
+#define SERVICE_TOOL_H
+
+#include
+#include
+
+#include
+
+#include "stacer-core_global.h"
+class STACERCORESHARED_EXPORT Service {
+
+public:
+ Service(QString name, bool status, bool active) {
+ this->name = name;
+ this->status = status;
+ this->active = active;
+ }
+
+ QString name;
+ bool status;
+ bool active;
+};
+
+class ServiceTool : public QObject
+{
+ Q_OBJECT
+
+public:
+ ServiceTool();
+
+ QList getServicesWithSystemctl();
+ bool serviceIsActive(QString serviceName);
+ bool changeServiceStatus(QString sname, bool status);
+ bool changeServiceActive(QString sname, bool status);
+ bool serviceIsEnabled(QString serviceName);
+private:
+
+};
+
+#endif // SERVICE_TOOL_H
diff --git a/stacer-core/Utils/command_util.cpp b/stacer-core/Utils/command_util.cpp
new file mode 100644
index 0000000..09749da
--- /dev/null
+++ b/stacer-core/Utils/command_util.cpp
@@ -0,0 +1,57 @@
+#include "command_util.h"
+
+CommandUtil::CommandUtil()
+{
+
+}
+
+QString CommandUtil::sudoExec(QString cmd, QStringList args)
+{
+ args.push_front(cmd);
+
+ QString result("");
+
+ try {
+ result = CommandUtil::exec("pkexec", args);
+ } catch (QString &ex) {
+ qCritical() << ex;
+ }
+
+ return result;
+}
+
+QString CommandUtil::exec(QString cmd, QStringList args)
+{
+ QProcess* process = new QProcess;
+
+ if(args.isEmpty())
+ process->start(cmd);
+ else
+ process->start(cmd, args);
+
+ process->waitForFinished();
+
+ QTextStream stdOut(process->readAllStandardOutput());
+
+ QString err = process->errorString();
+
+ process->kill();
+ process->close();
+
+ if (process->error() != QProcess::UnknownError)
+ throw err;
+
+ return stdOut.readAll().trimmed();
+}
+
+bool CommandUtil::isExecutable(QString cmd)
+{
+ QStringList paths;
+ paths << "/usr/bin/" << "/bin/" << "/sbin/" << "/usr/sbin/";
+
+ foreach (QString path, paths)
+ if(QFile::exists(path + cmd))
+ return true;
+
+ return false;
+}
diff --git a/stacer-core/Utils/command_util.h b/stacer-core/Utils/command_util.h
new file mode 100644
index 0000000..29bd23a
--- /dev/null
+++ b/stacer-core/Utils/command_util.h
@@ -0,0 +1,24 @@
+#ifndef COMMAND_UTIL_H
+#define COMMAND_UTIL_H
+
+#include
+#include
+#include
+#include
+#include
+
+#include "stacer-core_global.h"
+
+class STACERCORESHARED_EXPORT CommandUtil : public QObject
+{
+ Q_OBJECT
+
+public:
+ static QString sudoExec(QString cmd, QStringList args = {});
+ static QString exec(QString cmd, QStringList args = {});
+ static bool isExecutable(QString cmd);
+private:
+ CommandUtil();
+};
+
+#endif // COMMAND_UTIL_H
diff --git a/stacer-core/Utils/file_util.cpp b/stacer-core/Utils/file_util.cpp
new file mode 100644
index 0000000..dbfcff7
--- /dev/null
+++ b/stacer-core/Utils/file_util.cpp
@@ -0,0 +1,84 @@
+#include "file_util.h"
+
+FileUtil::FileUtil()
+{
+
+}
+
+QString FileUtil::readStringFromFile(QString path, QIODevice::OpenMode mode)
+{
+ QSharedPointer file(new QFile(path));
+
+ QString data;
+
+ if(file->open(mode)) {
+
+ data = file->readAll();
+
+ file->close();
+ }
+
+ return data;
+}
+
+QStringList FileUtil::readListFromFile(QString path, QIODevice::OpenMode mode)
+{
+ QStringList list = FileUtil::readStringFromFile(path, mode).trimmed().split("\n");
+
+ return list;
+}
+
+bool FileUtil::writeFile(QString path, QString content, QIODevice::OpenMode mode)
+{
+ QFile file(path);
+
+ if(file.open(mode))
+ {
+ QTextStream stream(&file);
+ stream << content.toUtf8();
+
+ file.close();
+
+ return true;
+ }
+
+ return false;
+}
+
+QStringList FileUtil::directoryList(QString path)
+{
+ QDir dir(path);
+
+ QStringList list;
+
+ foreach (QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files))
+ list << info.fileName();
+
+ return list;
+}
+
+quint64 FileUtil::getFileSize(QString path)
+{
+ quint64 totalSize = 0;
+
+ QFileInfo info(path);
+
+ if (info.exists())
+ {
+ if (info.isFile()) {
+ totalSize += info.size();
+ }
+ else if (info.isDir()) {
+
+ QDir dir(path);
+
+ foreach (QFileInfo i, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs)) {
+ totalSize += getFileSize(i.absoluteFilePath());
+ }
+ }
+ }
+
+ return totalSize;
+}
+
+
diff --git a/stacer-core/Utils/file_util.h b/stacer-core/Utils/file_util.h
new file mode 100644
index 0000000..24de0f1
--- /dev/null
+++ b/stacer-core/Utils/file_util.h
@@ -0,0 +1,32 @@
+#ifndef FILEUTIL_H
+#define FILEUTIL_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include "stacer-core_global.h"
+
+class STACERCORESHARED_EXPORT FileUtil : public QObject
+{
+ Q_OBJECT
+
+public:
+ static QString readStringFromFile(QString path, QIODevice::OpenMode mode = QIODevice::ReadOnly);
+ static QStringList readListFromFile(QString path, QIODevice::OpenMode mode = QIODevice::ReadOnly);
+
+ static bool writeFile(QString path, QString content, QIODevice::OpenMode mode = QIODevice::ReadWrite);
+ static QStringList directoryList(QString path);
+ static quint64 getFileSize(QString path);
+
+private:
+ FileUtil();
+};
+
+#endif // FILEUTIL_H
diff --git a/stacer-core/Utils/format_util.cpp b/stacer-core/Utils/format_util.cpp
new file mode 100644
index 0000000..c7c7473
--- /dev/null
+++ b/stacer-core/Utils/format_util.cpp
@@ -0,0 +1,31 @@
+#include "format_util.h"
+
+FormatUtil::FormatUtil()
+{
+
+}
+
+QString FormatUtil::formatBytes(quint64 bytes)
+{
+#define formatUnit(v, u, t) QString().sprintf("%.1f %s", \
+ ((double) v / (double) u), t)
+
+ if (bytes == 1L) // bytes
+ return QString("%1 byte").arg(bytes);
+ else if (bytes < KIBI) // bytes
+ return QString("%1 bytes").arg(bytes);
+ else if (bytes < MEBI) // KiB
+ return formatUnit(bytes, KIBI, "KiB");
+ else if (bytes < GIBI) // MiB
+ return formatUnit(bytes, MEBI, "MiB");
+ else if (bytes < TEBI) // GiB
+ return formatUnit(bytes, GIBI, "GiB");
+ else if (bytes < PEBI) // TiB
+ return formatUnit(bytes, TEBI, "TiB");
+ else if (bytes < EXBI) // PiB
+ return formatUnit(bytes, PEBI, "PiB");
+ else // EiB
+ return formatUnit(bytes, EXBI, "EiB");
+
+#undef formatUnit
+}
diff --git a/stacer-core/Utils/format_util.h b/stacer-core/Utils/format_util.h
new file mode 100644
index 0000000..a6b8386
--- /dev/null
+++ b/stacer-core/Utils/format_util.h
@@ -0,0 +1,28 @@
+#ifndef FORMAT_UTIL_H
+#define FORMAT_UTIL_H
+
+#include
+#include
+
+#include "stacer-core_global.h"
+
+class STACERCORESHARED_EXPORT FormatUtil : public QObject
+{
+ Q_OBJECT
+
+public:
+ static QString formatBytes(quint64 bytes);
+
+private:
+ FormatUtil();
+
+ static const quint64 KIBI = 1L << 10;
+ static const quint64 MEBI = 1L << 20;
+ static const quint64 GIBI = 1L << 30;
+ static const quint64 TEBI = 1L << 40;
+ static const quint64 PEBI = 1L << 50;
+ static const quint64 EXBI = 1L << 60;
+
+};
+
+#endif // FORMAT_UTIL_H
diff --git a/stacer-core/stacer-core.pro b/stacer-core/stacer-core.pro
new file mode 100644
index 0000000..ebc8942
--- /dev/null
+++ b/stacer-core/stacer-core.pro
@@ -0,0 +1,57 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2017-07-02T15:48:51
+#
+#-------------------------------------------------
+
+QT -= gui
+
+TARGET = stacer-core
+TEMPLATE = lib
+
+DEFINES += STACERCORE_LIBRARY
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which as been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+ Utils/command_util.cpp \
+ Utils/file_util.cpp \
+ Info/network_info.cpp \
+ Info/cpu_info.cpp \
+ Info/disk_info.cpp \
+ Info/memory_info.cpp \
+ Info/system_info.cpp \
+ Utils/format_util.cpp \
+ Tools/service_tool.cpp \
+ Tools/package_tool.cpp \
+ Info/process_info.cpp \
+ Info/process.cpp
+
+HEADERS += \
+ stacer-core_global.h \
+ Utils/command_util.h \
+ Info/network_info.h \
+ Info/cpu_info.h \
+ Info/disk_info.h \
+ Info/memory_info.h \
+ Info/system_info.h \
+ Utils/format_util.h \
+ Utils/file_util.h \
+ Tools/service_tool.h \
+ Tools/package_tool.h \
+ Info/process_info.h \
+ Info/process.h
+
+unix {
+ target.path = /usr/lib
+ INSTALLS += target
+}
diff --git a/stacer-core/stacer-core_global.h b/stacer-core/stacer-core_global.h
new file mode 100644
index 0000000..8e4ae73
--- /dev/null
+++ b/stacer-core/stacer-core_global.h
@@ -0,0 +1,12 @@
+#ifndef STACERCORE_GLOBAL_H
+#define STACERCORE_GLOBAL_H
+
+#include
+
+#if defined(STACERCORE_LIBRARY)
+# define STACERCORESHARED_EXPORT Q_DECL_EXPORT
+#else
+# define STACERCORESHARED_EXPORT Q_DECL_IMPORT
+#endif
+
+#endif // STACERCORE_GLOBAL_H
diff --git a/stacer.desktop b/stacer.desktop
new file mode 100644
index 0000000..f31652b
--- /dev/null
+++ b/stacer.desktop
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Type=Application
+Name=Stacer
+Exec=stacer
+Icon=stacer
+Comment=System Optimizer
+Categories=System
+Terminal=false
diff --git a/stacer/Managers/app_manager.cpp b/stacer/Managers/app_manager.cpp
new file mode 100644
index 0000000..60a0dca
--- /dev/null
+++ b/stacer/Managers/app_manager.cpp
@@ -0,0 +1,126 @@
+#include "app_manager.h"
+
+AppManager *AppManager::_instance = NULL;
+
+AppManager *AppManager::ins()
+{
+ if (_instance == NULL) {
+ _instance = new AppManager;
+ }
+
+ return _instance;
+}
+
+AppManager::AppManager(QObject *parent) : QObject(parent)
+{
+ // font settings
+ QFontDatabase::addApplicationFont(":/static/font/Ubuntu-R.ttf");
+
+ configPath = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
+
+ settings = new QSettings(QString("%1/settings.conf").arg(configPath), QSettings::NativeFormat);
+
+ loadLanguageList();
+
+ loadThemeList();
+
+ themeName = settings->value(THEME_PROP, "default").toString();
+
+ if (translator.load(QString("stacer_%1").arg(getLanguageCode()), qApp->applicationDirPath() + "/translations")) {
+ qApp->installTranslator(&translator);
+ } else {
+ qCritical() << "Translator could not load.";
+ }
+
+ styleValues = new QSettings(QString(":/static/themes/%1/style/values.ini").arg(themeName), QSettings::NativeFormat);
+}
+
+QSettings *AppManager::getStyleValues() const
+{
+ return styleValues;
+}
+
+/************
+ * LANGUAGE
+ ***********/
+void AppManager::loadLanguageList()
+{
+ QJsonArray langs = QJsonDocument::fromJson(FileUtil::readStringFromFile(":/static/languages.json").toUtf8())
+ .array();
+
+ for (int i = 0; i < langs.count(); ++i) {
+
+ QJsonObject ob = langs.at(i).toObject();
+
+ languageList.insert(ob["value"].toString(), ob["text"].toString());
+ }
+}
+
+void AppManager::setLanguage(QString value)
+{
+ settings->setValue(LANG_PROP, value);
+}
+
+QString AppManager::getLanguageCode()
+{
+ return settings->value(LANG_PROP, "en").toString();
+}
+
+QMap AppManager::getLanguageList()
+{
+ return languageList;
+}
+
+/************
+ * THEME
+ ***********/
+void AppManager::loadThemeList()
+{
+ QJsonArray themes = QJsonDocument::fromJson(FileUtil::readStringFromFile(":/static/themes.json").toUtf8())
+ .array();
+
+ for (int i = 0; i < themes.count(); ++i) {
+
+ QJsonObject ob = themes.at(i).toObject();
+
+ themeList.insert(ob["value"].toString(), ob["text"].toString());
+ }
+}
+
+QMap AppManager::getThemeList() const
+{
+ return themeList;
+}
+
+QString AppManager::getThemeName() const
+{
+ return themeName;
+}
+
+void AppManager::updateStylesheet()
+{
+ styleValues = new QSettings(QString(":/static/themes/%1/style/values.ini").arg(themeName), QSettings::NativeFormat);
+
+ stylesheetFileContent = FileUtil::readStringFromFile(QString(":/static/themes/%1/style/style.qss").arg(themeName));
+
+ // set values
+ foreach (QString key, styleValues->allKeys()) {
+ stylesheetFileContent.replace(key, styleValues->value(key).toString());
+ }
+
+ qApp->setStyleSheet(stylesheetFileContent);
+
+ emit changedTheme();
+}
+
+void AppManager::setThemeName(const QString &value)
+{
+ themeName = value;
+
+ settings->setValue(THEME_PROP, value);
+}
+
+QString AppManager::getStylesheetFileContent() const
+{
+ return stylesheetFileContent;
+}
diff --git a/stacer/Managers/app_manager.h b/stacer/Managers/app_manager.h
new file mode 100644
index 0000000..0229e66
--- /dev/null
+++ b/stacer/Managers/app_manager.h
@@ -0,0 +1,59 @@
+#ifndef APP_MANAGER_H
+#define APP_MANAGER_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+
+#define THEME_PROP "ThemeName"
+#define LANG_PROP "Language"
+
+class AppManager : public QObject
+{
+ Q_OBJECT
+public:
+ static AppManager *ins();
+
+ QString getLanguageCode();
+ void setLanguage(QString value);
+ QMap getLanguageList();
+ void loadLanguageList();
+ QString getStylesheetFileContent() const;
+
+ void updateStylesheet();
+ void setThemeName(const QString &value);
+ QString getThemeName() const;
+ QMap getThemeList() const;
+ void loadThemeList();
+ QSettings *getStyleValues() const;
+
+signals:
+ void changedTheme();
+
+private:
+ static AppManager *_instance;
+ explicit AppManager(QObject *parent = nullptr);
+
+private:
+ QTranslator translator;
+ QString configPath;
+ QString themeName;
+ QSettings *settings;
+ QSettings *styleValues;
+ QMap languageList;
+ QMap themeList;
+ QString stylesheetFileContent;
+};
+
+#endif // APP_MANAGER_H
diff --git a/stacer/Managers/info_manager.cpp b/stacer/Managers/info_manager.cpp
new file mode 100644
index 0000000..758154f
--- /dev/null
+++ b/stacer/Managers/info_manager.cpp
@@ -0,0 +1,121 @@
+#include "info_manager.h"
+
+InfoManager::InfoManager()
+{
+
+}
+
+InfoManager *InfoManager::_instance = NULL;
+
+InfoManager *InfoManager::ins()
+{
+ if(_instance == NULL)
+ _instance = new InfoManager;
+
+ return _instance;
+}
+
+QString InfoManager::getUserName()
+{
+ return si.getUsername();
+}
+
+/********************
+ * CPU INFORMATION
+ *******************/
+quint8 InfoManager::getCpuCoreCount()
+{
+ return ci.getCpuCoreCount();
+}
+
+QList InfoManager::getCpuPercents()
+{
+ return ci.getCpuPercents();
+}
+
+/********************
+ * MEMORY INFORMATION
+ *******************/
+void InfoManager::updateMemoryInfo()
+{
+ mi.updateMemoryInfo();
+}
+
+quint64 InfoManager::getSwapUsed()
+{
+ return mi.getSwapUsed();
+}
+
+quint64 InfoManager::getSwapTotal()
+{
+ return mi.getSwapTotal();
+}
+
+quint64 InfoManager::getMemUsed()
+{
+ return mi.getMemUsed();
+}
+
+quint64 InfoManager::getMemTotal()
+{
+ return mi.getMemTotal();
+}
+
+/********************
+ * DISK INFORMATION
+ *******************/
+QList InfoManager::getDisks()
+{
+ return di.getDisks();
+}
+
+void InfoManager::updateDiskInfo()
+{
+ return di.updateDiskInfo();
+}
+
+/********************
+ * NETWORK INFORMATION
+ *******************/
+quint64 InfoManager::getRXbytes()
+{
+ return ni.getRXbytes();
+}
+
+quint64 InfoManager::getTXbytes()
+{
+ return ni.getTXbytes();
+}
+
+/********************
+ * CLEANER INFORMATION
+ *******************/
+QFileInfoList InfoManager::getCrashReports()
+{
+ return si.getCrashReports();
+}
+
+QFileInfoList InfoManager::getAppLogs()
+{
+ return si.getAppLogs();
+}
+
+QFileInfoList InfoManager::getAppCaches()
+{
+ return si.getAppCaches();
+}
+
+/********************
+ * PROCESSES INFORMATION
+ *******************/
+void InfoManager::updateProcesses()
+{
+ pi.updateProcesses();
+}
+
+QList InfoManager::getProcesses()
+{
+ return pi.getProcessList();
+}
+
+
diff --git a/stacer/Managers/info_manager.h b/stacer/Managers/info_manager.h
new file mode 100644
index 0000000..48826e7
--- /dev/null
+++ b/stacer/Managers/info_manager.h
@@ -0,0 +1,54 @@
+#ifndef INFO_MANAGER_H
+#define INFO_MANAGER_H
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+class InfoManager
+{
+public:
+ static InfoManager *ins();
+
+ quint8 getCpuCoreCount();
+ QList getCpuPercents();
+
+ quint64 getSwapUsed();
+ quint64 getSwapTotal();
+ quint64 getMemUsed();
+ quint64 getMemTotal();
+ void updateMemoryInfo();
+
+ quint64 getRXbytes();
+ quint64 getTXbytes();
+ QList getDisks();
+ void updateDiskInfo();
+
+ QFileInfoList getCrashReports();
+ QFileInfoList getAppLogs();
+ QFileInfoList getAppCaches();
+
+ void updateProcesses();
+ QList getProcesses();
+ QString getUserName();
+private:
+ InfoManager();
+ static InfoManager *_instance;
+
+private:
+ CpuInfo ci;
+ DiskInfo di;
+ MemoryInfo mi;
+ NetworkInfo ni;
+ SystemInfo si;
+ ProcessInfo pi;
+};
+
+#endif // INFO_MANAGER_H
diff --git a/stacer/Managers/tool_manager.cpp b/stacer/Managers/tool_manager.cpp
new file mode 100644
index 0000000..5b384bc
--- /dev/null
+++ b/stacer/Managers/tool_manager.cpp
@@ -0,0 +1,110 @@
+#include "tool_manager.h"
+
+ToolManager *ToolManager::_instance = NULL;
+
+ToolManager *ToolManager::ins()
+{
+ if(_instance == NULL)
+ _instance = new ToolManager;
+
+ return _instance;
+}
+
+ToolManager::ToolManager() :
+ st(new ServiceTool),
+ pt(new PackageTool)
+{
+
+}
+
+/******************
+ * SERVICES
+ *****************/
+QList ToolManager::getServices()
+{
+ return st->getServicesWithSystemctl();
+}
+
+bool ToolManager::changeServiceStatus(QString sname, bool status)
+{
+ return st->changeServiceStatus(sname, status);
+}
+
+bool ToolManager::changeServiceActive(QString sname, bool status)
+{
+ return st->changeServiceActive(sname, status);
+}
+
+bool ToolManager::serviceIsActive(QString sname)
+{
+ return st->serviceIsActive(sname);
+}
+
+bool ToolManager::serviceIsEnabled(QString sname)
+{
+ return st->serviceIsEnabled(sname);
+}
+
+/******************
+ * PACKAGES
+ *****************/
+QStringList ToolManager::getPackages()
+{
+ switch (pt->getCurrentPackageTool()) {
+ case PackageTool::PackageTools::APT:
+ return pt->getDpkgPackages();
+ break;
+ case PackageTool::PackageTools::YUM:
+ case PackageTool::PackageTools::DNF:
+ return pt->getRpmPackages();
+ break;
+ case PackageTool::PackageTools::PACMAN:
+ return pt->getPacmanPackages();
+ break;
+ default:
+ return QStringList();
+ break;
+ }
+}
+
+QFileInfoList ToolManager::getPackageCaches()
+{
+ switch (pt->getCurrentPackageTool()) {
+ case PackageTool::PackageTools::APT:
+ return pt->getDpkgPackageCaches();
+ break;
+ case PackageTool::PackageTools::YUM:
+ case PackageTool::PackageTools::DNF:
+ return pt->getPacmanPackageCaches();
+ break;
+ case PackageTool::PackageTools::PACMAN:
+ return pt->getPacmanPackageCaches();
+ break;
+ default:
+ return QFileInfoList();
+ break;
+ }
+}
+
+void ToolManager::uninstallPackages(QStringList packages)
+{
+ uninstallStarted();
+
+ switch (pt->getCurrentPackageTool()) {
+ case PackageTool::PackageTools::APT:
+ pt->dpkgRemovePackages(packages);
+ break;
+ case PackageTool::PackageTools::YUM:
+ pt->yumRemovePackages(packages);
+ break;
+ case PackageTool::PackageTools::DNF:
+ pt->dnfRemovePackages(packages);
+ break;
+ case PackageTool::PackageTools::PACMAN:
+ pt->pacmanRemovePackages(packages);
+ break;
+ }
+
+ uninstallFinished();
+}
+
diff --git a/stacer/Managers/tool_manager.h b/stacer/Managers/tool_manager.h
new file mode 100644
index 0000000..9391aee
--- /dev/null
+++ b/stacer/Managers/tool_manager.h
@@ -0,0 +1,41 @@
+#ifndef TOOL_MANAGER_H
+#define TOOL_MANAGER_H
+
+#include
+#include
+
+#include
+#include
+
+class ToolManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ static ToolManager *ins();
+
+public:
+ QList getServices();
+ QStringList getPackages();
+
+ QFileInfoList getPackageCaches();
+public slots:
+ bool changeServiceStatus(QString sname, bool status);
+ bool changeServiceActive(QString sname, bool status);
+ bool serviceIsActive(QString sname);
+ bool serviceIsEnabled(QString sname);
+ void uninstallPackages(QStringList packages);
+
+signals:
+ void uninstallFinished();
+ void uninstallStarted();
+
+private:
+ ToolManager();
+ static ToolManager *_instance;
+
+ ServiceTool *st;
+ PackageTool *pt;
+};
+
+#endif // TOOL_MANAGER_H
diff --git a/stacer/Pages/Dashboard/circlebar.cpp b/stacer/Pages/Dashboard/circlebar.cpp
new file mode 100644
index 0000000..83da61e
--- /dev/null
+++ b/stacer/Pages/Dashboard/circlebar.cpp
@@ -0,0 +1,70 @@
+#include "circlebar.h"
+#include "ui_circlebar.h"
+
+CircleBar::~CircleBar()
+{
+ delete ui;
+ delete chart;
+ delete chartView;
+ delete series;
+}
+
+CircleBar::CircleBar(QString title, QStringList colors, QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::CircleBar),
+ colors(colors),
+ chart(new QChart),
+ chartView(new QChartView(chart)),
+ series(new QPieSeries)
+{
+ ui->setupUi(this);
+
+ ui->chartTitle->setText(title);
+
+ init();
+}
+
+void CircleBar::init()
+{
+ // series settings
+ series->setHoleSize(0.67);
+ series->setPieSize(165);
+ series->setPieStartAngle(-115);
+ series->setPieEndAngle(115);
+ series->setLabelsVisible(false);
+ series->append("1", 0);
+ series->append("2", 0);
+ series->slices().first()->setBorderColor("transparent");
+ series->slices().last()->setBorderColor("transparent");
+ QConicalGradient gradient;
+ gradient.setAngle(115);
+ for (int i = 0; i < colors.count(); ++i)
+ gradient.setColorAt(i, QColor(colors.at(i)));
+ series->slices().first()->setBrush(gradient);
+
+ // chart settings
+ chart->setBackgroundBrush(QBrush("transparent"));
+ chart->setContentsMargins(-15, -18, -15, -60);
+ chart->addSeries(series);
+ chart->legend()->hide();
+
+ // chartview settings
+ chartView->setRenderHint(QPainter::Antialiasing);
+
+ ui->chartLayout->insertWidget(1, chartView);
+
+ connect(AppManager::ins(), &AppManager::changedTheme, this, [this](){
+ chartView->setBackgroundBrush(QColor(AppManager::ins()->getStyleValues()->value("@circleChartBackgroundColor").toString()));
+
+ series->slices().last()->setColor(AppManager::ins()->getStyleValues()->value("@pageContent").toString()); // trail color
+ });
+}
+
+void CircleBar::setValue(int value, QString valueText)
+{
+ series->slices().first()->setValue(value);
+ series->slices().last()->setValue(100 - value);
+
+ ui->chartValue->setText(valueText);
+}
+
diff --git a/stacer/Pages/Dashboard/circlebar.h b/stacer/Pages/Dashboard/circlebar.h
new file mode 100644
index 0000000..f5e460e
--- /dev/null
+++ b/stacer/Pages/Dashboard/circlebar.h
@@ -0,0 +1,37 @@
+#ifndef CIRCLEBAR_H
+#define CIRCLEBAR_H
+
+#include
+#include
+#include "Managers/app_manager.h"
+
+namespace Ui {
+ class CircleBar;
+}
+
+class CircleBar : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit CircleBar(QString title, QStringList colors, QWidget *parent = 0);
+ ~CircleBar();
+
+public slots:
+ void setValue(int value, QString valueText);
+
+private slots:
+ void init();
+
+private:
+ Ui::CircleBar *ui;
+
+private:
+ QStringList colors;
+
+ QChart *chart;
+ QChartView *chartView;
+ QPieSeries *series;
+};
+
+#endif // CIRCLEBAR_H
diff --git a/stacer/Pages/Dashboard/circlebar.ui b/stacer/Pages/Dashboard/circlebar.ui
new file mode 100644
index 0000000..f8c626b
--- /dev/null
+++ b/stacer/Pages/Dashboard/circlebar.ui
@@ -0,0 +1,89 @@
+
+
+ CircleBar
+
+
+
+ 0
+ 0
+ 383
+ 317
+
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 10
+
+
+ 0
+
+
+ 10
+
+ -
+
+
+
+
+
+ Title
+
+
+
+ -
+
+
+ Value
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/Pages/Dashboard/dashboard_page.cpp b/stacer/Pages/Dashboard/dashboard_page.cpp
new file mode 100644
index 0000000..cf80d2c
--- /dev/null
+++ b/stacer/Pages/Dashboard/dashboard_page.cpp
@@ -0,0 +1,198 @@
+#include "dashboard_page.h"
+#include "ui_dashboard_page.h"
+
+DashboardPage::~DashboardPage()
+{
+ delete ui;
+ delete cpuBar;
+ delete memBar;
+ delete diskBar;
+ delete downloadBar;
+ delete uploadBar;
+ delete timer;
+}
+
+DashboardPage::DashboardPage(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::DashboardPage),
+ cpuBar(new CircleBar(tr("CPU"), {"#A8E063", "#56AB2F"})),
+ memBar(new CircleBar(tr("MEMORY"), {"#FFB75E", "#ED8F03"})),
+ diskBar(new CircleBar(tr("DISK"), {"#DC2430", "#7B4397"})),
+ downloadBar(new LineBar(tr("DOWNLOAD"))),
+ uploadBar(new LineBar(tr("UPLOAD"))),
+ timer(new QTimer),
+ im(InfoManager::ins())
+{
+ ui->setupUi(this);
+
+ init();
+
+ systemInformationInit();
+}
+
+void DashboardPage::init()
+{
+ // Circle bars
+ ui->circleBarsLayout->addWidget(cpuBar);
+ ui->circleBarsLayout->addWidget(memBar);
+ ui->circleBarsLayout->addWidget(diskBar);
+
+ // line bars
+ ui->lineBarsLayout->addWidget(downloadBar);
+ ui->lineBarsLayout->addWidget(uploadBar);
+
+ // connections
+ connect(timer, &QTimer::timeout, this, &DashboardPage::updateCpuBar);
+ connect(timer, &QTimer::timeout, this, &DashboardPage::updateMemoryBar);
+ connect(timer, &QTimer::timeout, this, &DashboardPage::updateNetworkBar);
+
+ QTimer *timerDisk = new QTimer;
+ connect(timerDisk, &QTimer::timeout, this, &DashboardPage::updateDiskBar);
+ timerDisk->start(10 * 1000);
+
+ timer->start(1 * 1000);
+
+ // initialization
+ updateCpuBar();
+ updateMemoryBar();
+ updateDiskBar();
+ updateNetworkBar();
+
+ ui->updateBarWidget->hide();
+
+ // check update
+ checkUpdate();
+}
+
+void DashboardPage::checkUpdate()
+{
+ QString requestResult;
+
+ if (CommandUtil::isExecutable("curl")) {
+ try {
+ requestResult = CommandUtil::exec("curl", { "https://api.github.com/repos/oguzhaninan/Stacer/releases/latest" });
+ } catch (QString &ex) {
+ qCritical() << ex;
+ }
+
+ if (! requestResult.isEmpty()) {
+ QJsonDocument result = QJsonDocument::fromJson(requestResult.toUtf8());
+
+ QRegExp ex("[0-9].[0-9].[0-9]");
+ ex.indexIn(result.object().value("tag_name").toString());
+
+ QString version;
+ if (! ex.captureCount())
+ version = ex.cap();
+
+ if (qApp->applicationVersion() != version) {
+ ui->updateBarWidget->show();
+ }
+ }
+ }
+}
+
+void DashboardPage::on_downloadUpdateBtn_clicked()
+{
+ QDesktopServices::openUrl(QUrl("https://github.com/oguzhaninan/Stacer/releases/latest"));
+}
+
+void DashboardPage::systemInformationInit()
+{
+ // get system information
+ SystemInfo sysInfo;
+
+ QStringList infos;
+ infos
+ << tr("Hostname: %1").arg(sysInfo.getHostname())
+ << tr("Platform: %1").arg(sysInfo.getPlatform())
+ << tr("Distribution: %1").arg(sysInfo.getDistribution())
+ << tr("Kernel Release: %1").arg(sysInfo.getKernel())
+ << tr("CPU Model: %1").arg(sysInfo.getCpuModel())
+ << tr("CPU Speed: %1").arg(sysInfo.getCpuSpeed())
+ << tr("CPU Core: %1").arg(sysInfo.getCpuCore());
+
+ QStringListModel *systemInfoModel = new QStringListModel(infos);
+
+ ui->systemInfoList->setModel(systemInfoModel);
+}
+
+void DashboardPage::updateCpuBar()
+{
+ int cpuUsedPercent = im->getCpuPercents().at(0);
+
+ cpuBar->setValue(cpuUsedPercent, QString("%1%").arg(cpuUsedPercent));
+}
+
+void DashboardPage::updateMemoryBar()
+{
+ im->updateMemoryInfo();
+
+ int memUsedPercent = 0;
+ if (im->getMemTotal())
+ memUsedPercent = ((double)im->getMemUsed() / (double)im->getMemTotal()) * 100.0;
+
+ QString f_memUsed = FormatUtil::formatBytes(im->getMemUsed());
+ QString f_memTotal = FormatUtil::formatBytes(im->getMemTotal());
+
+ memBar->setValue(memUsedPercent, QString("%1 / %2")
+ .arg(f_memUsed)
+ .arg(f_memTotal));
+}
+
+void DashboardPage::updateDiskBar()
+{
+ im->updateDiskInfo();
+
+ if(! im->getDisks().isEmpty())
+ {
+ quint64 size = im->getDisks().at(0).size;
+ quint64 used = im->getDisks().at(0).used;
+
+ QString sizeText = FormatUtil::formatBytes(size);
+ QString usedText = FormatUtil::formatBytes(used);
+
+ int diskPercent = 0;
+ if (size)
+ diskPercent = ( (double) used / (double) size ) * 100.0;
+
+ diskBar->setValue(diskPercent, QString("%1 / %2")
+ .arg(usedText)
+ .arg(sizeText));
+ }
+}
+
+void DashboardPage::updateNetworkBar()
+{
+ static quint64 l_RXbytes = im->getRXbytes();
+ static quint64 l_TXbytes = im->getTXbytes();
+ static quint64 max_RXbytes = 1L << 20; // 1 MEBI
+ static quint64 max_TXbytes = 1L << 20; // 1 MEBI
+
+ quint64 RXbytes = im->getRXbytes();
+ quint64 TXbytes = im->getTXbytes();
+
+ quint64 d_RXbytes = (RXbytes - l_RXbytes);
+ quint64 d_TXbytes = (TXbytes - l_TXbytes);
+
+ QString downText = FormatUtil::formatBytes(d_RXbytes);
+ QString upText = FormatUtil::formatBytes(d_TXbytes);
+
+ int downPercent = ((double) d_RXbytes / (double) max_RXbytes) * 100.0;
+ int upPercent = ((double) d_TXbytes / (double) max_TXbytes) * 100.0;
+
+ downloadBar->setValue(downPercent,
+ QString("%1/s").arg(downText),
+ tr("Total: %1").arg(FormatUtil::formatBytes(RXbytes)));
+
+ uploadBar->setValue(upPercent,
+ QString("%1/s").arg(upText),
+ tr("Total: %1").arg(FormatUtil::formatBytes(TXbytes)));
+
+ max_RXbytes = qMax(max_RXbytes, d_RXbytes);
+ max_TXbytes = qMax(max_TXbytes, d_TXbytes);
+
+ l_RXbytes = RXbytes;
+ l_TXbytes = TXbytes;
+}
+
diff --git a/stacer/Pages/Dashboard/dashboard_page.h b/stacer/Pages/Dashboard/dashboard_page.h
new file mode 100644
index 0000000..01bf768
--- /dev/null
+++ b/stacer/Pages/Dashboard/dashboard_page.h
@@ -0,0 +1,55 @@
+#ifndef DASHBOARDPAGE_H
+#define DASHBOARDPAGE_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include "circlebar.h"
+#include "linebar.h"
+
+namespace Ui {
+ class DashboardPage;
+}
+
+class DashboardPage : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit DashboardPage(QWidget *parent = 0);
+ ~DashboardPage();
+
+private slots:
+ void init();
+ void checkUpdate();
+ void systemInformationInit();
+
+ void updateCpuBar();
+ void updateMemoryBar();
+ void updateDiskBar();
+ void updateNetworkBar();
+
+ void on_downloadUpdateBtn_clicked();
+
+private:
+ Ui::DashboardPage *ui;
+
+private:
+ CircleBar* cpuBar;
+ CircleBar* memBar;
+ CircleBar* diskBar;
+
+ LineBar *downloadBar;
+ LineBar *uploadBar;
+
+ QTimer *timer;
+ InfoManager *im;
+};
+
+#endif // DASHBOARDPAGE_H
diff --git a/stacer/Pages/Dashboard/dashboard_page.ui b/stacer/Pages/Dashboard/dashboard_page.ui
new file mode 100644
index 0000000..4cb163a
--- /dev/null
+++ b/stacer/Pages/Dashboard/dashboard_page.ui
@@ -0,0 +1,264 @@
+
+
+ DashboardPage
+
+
+
+ 0
+ 0
+ 811
+ 565
+
+
+
+
+ 0
+ 0
+
+
+
+ Form
+
+
+
+ 20
+
+
+ 10
+
+
+ 20
+
+
+ 10
+
+
+ 10
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 150
+ 0
+
+
+
+
+ 20
+
+
+ 0
+
+
+ 10
+
+
+ 0
+
+
+ 0
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 200
+
+
+
+
+ 25
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 200
+ 0
+
+
+
+ Qt::WheelFocus
+
+
+
+ 10
+
+
+ 10
+
+
+ 0
+
+
+ 10
+
+
+ 0
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 20
+
+
+
+
+ -
+
+
+ SYSTEM INFO
+
+
+
+ -
+
+
+ Qt::NoFocus
+
+
+ Qt::ScrollBarAlwaysOff
+
+
+ Qt::ScrollBarAlwaysOff
+
+
+ false
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+ QAbstractItemView::NoSelection
+
+
+ QAbstractItemView::SelectRows
+
+
+ 5
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 0
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 30
+
+
+
+
+
+
+
+ 0
+
+
+ 15
+
+
+ 0
+
+
+ 5
+
+
+ 0
+
+ -
+
+
+ There are update currently available.
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+ Download
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/Pages/Dashboard/linebar.cpp b/stacer/Pages/Dashboard/linebar.cpp
new file mode 100644
index 0000000..2599b49
--- /dev/null
+++ b/stacer/Pages/Dashboard/linebar.cpp
@@ -0,0 +1,23 @@
+#include "linebar.h"
+#include "ui_linebar.h"
+
+LineBar::~LineBar()
+{
+ delete ui;
+}
+
+LineBar::LineBar(QString title, QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::LineBar)
+{
+ ui->setupUi(this);
+
+ ui->lineChartTitle->setText(title);
+}
+
+void LineBar::setValue(int value, QString text, QString totalText)
+{
+ ui->lineChartProgress->setValue(value);
+ ui->lineChartValue->setText(text);
+ ui->lineChartTotal->setText(totalText);
+}
diff --git a/stacer/Pages/Dashboard/linebar.h b/stacer/Pages/Dashboard/linebar.h
new file mode 100644
index 0000000..9b0ccc7
--- /dev/null
+++ b/stacer/Pages/Dashboard/linebar.h
@@ -0,0 +1,24 @@
+#ifndef LINEBAR_H
+#define LINEBAR_H
+
+#include
+
+namespace Ui {
+ class LineBar;
+}
+
+class LineBar : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit LineBar(QString title, QWidget *parent = 0);
+ ~LineBar();
+
+public slots:
+ void setValue(int value, QString text, QString totalText);
+private:
+ Ui::LineBar *ui;
+};
+
+#endif // LINEBAR_H
diff --git a/stacer/Pages/Dashboard/linebar.ui b/stacer/Pages/Dashboard/linebar.ui
new file mode 100644
index 0000000..abe6e9e
--- /dev/null
+++ b/stacer/Pages/Dashboard/linebar.ui
@@ -0,0 +1,167 @@
+
+
+ LineBar
+
+
+
+ 0
+ 0
+ 474
+ 110
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+ 25
+
+
+ 0
+
+
+ 25
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ Total
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Expanding
+
+
+
+ 1
+ 15
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Expanding
+
+
+
+ 1
+ 15
+
+
+
+
+ -
+
+
+
+ 0
+ 20
+
+
+
+
+ 16777215
+ 20
+
+
+
+
+
+
+ 0
+
+
+ false
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Expanding
+
+
+
+ 1
+ 15
+
+
+
+
+ -
+
+
+ Title
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Expanding
+
+
+
+ 1
+ 15
+
+
+
+
+ -
+
+
+ Value
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/Pages/Processes/processes_page.cpp b/stacer/Pages/Processes/processes_page.cpp
new file mode 100644
index 0000000..2badeb0
--- /dev/null
+++ b/stacer/Pages/Processes/processes_page.cpp
@@ -0,0 +1,229 @@
+#include "processes_page.h"
+#include "ui_processes_page.h"
+
+ProcessesPage::~ProcessesPage()
+{
+ delete ui;
+ delete model;
+ delete sortModel;
+ delete timer;
+}
+
+ProcessesPage::ProcessesPage(QWidget *parent) :
+ QWidget(parent),
+ model(new QStandardItemModel(this)),
+ sortModel(new QSortFilterProxyModel(this)),
+ im(InfoManager::ins()),
+ timer(new QTimer(this)),
+ ui(new Ui::ProcessesPage)
+{
+ ui->setupUi(this);
+
+ init();
+}
+
+void ProcessesPage::init()
+{
+ // slider settings
+ ui->refreshSlider->setRange(1, 10);
+ ui->refreshSlider->setPageStep(1);
+ ui->refreshSlider->setSingleStep(1);
+
+ // Table settings
+ sortModel->setSourceModel(model);
+
+ headers << "PID" << tr("Resident Memory") << tr("%Memory") << tr("Virtual Memory") << tr("User") << "%CPU"
+ << tr("Start Time") << tr("State") << tr("Group") << tr("Nice") << tr("CPU Time")
+ << tr("Session") << tr("Seat") << tr("Process");
+
+ model->setHorizontalHeaderLabels(headers);
+
+ ui->processTable->setModel(sortModel);
+ sortModel->setSortRole(1);
+ sortModel->setDynamicSortFilter(true);
+ sortModel->sort(5, Qt::SortOrder::DescendingOrder);
+
+ ui->processTable->horizontalHeader()->setSectionsMovable(true);
+ ui->processTable->horizontalHeader()->setFixedHeight(36);
+ ui->processTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+ ui->processTable->horizontalHeader()->setCursor(Qt::PointingHandCursor);
+
+ ui->processTable->horizontalHeader()->resizeSection(0, 70);
+
+ loadProcesses();
+
+ connect(timer, &QTimer::timeout, this, &ProcessesPage::loadProcesses);
+ timer->setInterval(1000);
+ timer->start();
+
+ ui->processTable->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);
+
+ connect(ui->processTable->horizontalHeader(), SIGNAL(customContextMenuRequested(const QPoint&)),
+ this, SLOT(on_processTable_customContextMenuRequested(const QPoint&)));
+
+ loadHeaderMenu();
+}
+
+void ProcessesPage::loadHeaderMenu()
+{
+ int i = 0;
+ foreach (QString kolon, headers) {
+ QAction *action = new QAction(kolon);
+ action->setCheckable(true);
+ action->setChecked(true);
+ action->setData(i++);
+
+ headerMenu.addAction(action);
+ }
+
+ QList hiddenHeaders = { 6, 7, 8, 9, 10, 11, 12 };
+ foreach (int i, hiddenHeaders) {
+ ui->processTable->horizontalHeader()->setSectionHidden(i, true);
+ headerMenu.actions().at(i)->setChecked(false);
+ }
+}
+
+void ProcessesPage::loadProcesses()
+{
+ QModelIndexList selecteds = ui->processTable->selectionModel()->selectedRows();
+
+ model->removeRows(0, model->rowCount());
+
+ im->updateProcesses();
+
+ foreach (Process proc, im->getProcesses()) {
+ if (ui->allProcessesCheck->isChecked()) {
+ model->appendRow(createRow(proc));
+ }
+ else {
+ if (im->getUserName() == proc.getUname())
+ model->appendRow(createRow(proc));
+ }
+ }
+
+ ui->processTitleLbl->setText(tr("Processes (%1)").arg(model->rowCount()));
+
+ // selected item
+ if(! selecteds.isEmpty()) {
+ seletedRowModel = selecteds.first();
+
+ for (int i = 0; i < sortModel->rowCount(); ++i) {
+ if (sortModel->index(i, 0).data(1).toInt() == seletedRowModel.data(1).toInt())
+ ui->processTable->selectRow(i);
+ }
+ } else {
+ seletedRowModel = QModelIndex();
+ }
+}
+
+QList ProcessesPage::createRow(Process proc)
+{
+ QList row;
+
+ int data = 1;
+
+ QStandardItem *pid_i = new QStandardItem(QString::number(proc.getPid()));
+ pid_i->setData(proc.getPid(), data);
+ pid_i->setData(proc.getPid(), Qt::ToolTipRole);
+
+ QStandardItem *rss_i = new QStandardItem(FormatUtil::formatBytes(proc.getRss()));
+ rss_i->setData(proc.getRss(), data);
+ rss_i->setData(FormatUtil::formatBytes(proc.getRss()), Qt::ToolTipRole);
+
+ QStandardItem *pmem_i = new QStandardItem(QString::number(proc.getPmem()));
+ pmem_i->setData(proc.getPmem(), data);
+ pmem_i->setData(proc.getPmem(), Qt::ToolTipRole);
+
+ QStandardItem *vsize_i = new QStandardItem(FormatUtil::formatBytes(proc.getVsize()));
+ vsize_i->setData(proc.getVsize(), data);
+ vsize_i->setData(FormatUtil::formatBytes(proc.getVsize()), Qt::ToolTipRole);
+
+ QStandardItem *uname_i = new QStandardItem(proc.getUname());
+ uname_i->setData(proc.getUname(), data);
+ uname_i->setData(proc.getUname(), Qt::ToolTipRole);
+
+ QStandardItem *pcpu_i = new QStandardItem(QString::number(proc.getPcpu()));
+ pcpu_i->setData(proc.getPcpu(), data);
+ pcpu_i->setData(proc.getPcpu(), Qt::ToolTipRole);
+
+ QStandardItem *starttime_i = new QStandardItem(proc.getStartTime());
+ starttime_i->setData(proc.getStartTime(), data);
+ starttime_i->setData(proc.getStartTime(), Qt::ToolTipRole);
+
+ QStandardItem *state_i = new QStandardItem(proc.getState());
+ state_i->setData(proc.getState(), data);
+ state_i->setData(proc.getState(), Qt::ToolTipRole);
+
+ QStandardItem *group_i = new QStandardItem(proc.getGroup());
+ group_i->setData(proc.getGroup(), data);
+ group_i->setData(proc.getGroup(), Qt::ToolTipRole);
+
+ QStandardItem *nice_i = new QStandardItem(QString::number(proc.getNice()));
+ nice_i->setData(proc.getNice(), data);
+ nice_i->setData(proc.getNice(), Qt::ToolTipRole);
+
+ QStandardItem *cpuTime_i = new QStandardItem(proc.getCpuTime());
+ cpuTime_i->setData(proc.getCpuTime(), data);
+ cpuTime_i->setData(proc.getCpuTime(), Qt::ToolTipRole);
+
+ QStandardItem *session_i = new QStandardItem(proc.getSession());
+ session_i->setData(proc.getSession(), data);
+ session_i->setData(proc.getSession(), Qt::ToolTipRole);
+
+ QStandardItem *seat_i = new QStandardItem(proc.getSeat());
+ seat_i->setData(proc.getSeat(), data);
+ seat_i->setData(proc.getSeat(), Qt::ToolTipRole);
+
+ QStandardItem *cmd_i = new QStandardItem(proc.getCmd());
+ cmd_i->setData(proc.getCmd(), data);
+ cmd_i->setData(proc.getCmd(), Qt::ToolTipRole);
+
+ row << pid_i << rss_i << pmem_i << vsize_i << uname_i << pcpu_i
+ << starttime_i << state_i << group_i << nice_i << cpuTime_i
+ << session_i << seat_i<< cmd_i;
+
+ return row;
+}
+
+void ProcessesPage::on_processSearchBox_textChanged(const QString &val)
+{
+ QRegExp query(val, Qt::CaseInsensitive, QRegExp::Wildcard);
+
+ sortModel->setFilterKeyColumn(headers.count() - 1); // process name
+ sortModel->setFilterRegExp(query);
+}
+
+void ProcessesPage::on_refreshSlider_valueChanged(int i)
+{
+ ui->refreshLabel->setText(tr("Refresh (%1)").arg(i));
+ timer->setInterval(i * 1000);
+}
+
+void ProcessesPage::on_endProcessBtn_clicked()
+{
+ pid_t pid = seletedRowModel.data(1).toInt();
+
+ QString selectedUname = sortModel->index(seletedRowModel.row(), 4).data(1).toString();
+
+ try {
+ if (pid) {
+ if (selectedUname == im->getUserName())
+ CommandUtil::exec("kill", { QString::number(pid) });
+ else
+ CommandUtil::sudoExec("kill", { QString::number(pid) });
+ }
+ } catch (QString &ex) {
+ qCritical() << ex;
+ }
+}
+
+void ProcessesPage::on_processTable_customContextMenuRequested(const QPoint &pos)
+{
+ QPoint globalPos = ui->processTable->mapToGlobal(pos);
+
+ QAction *action = headerMenu.exec(globalPos);
+
+ if (action)
+ ui->processTable->horizontalHeader()->setSectionHidden(action->data().toInt(),
+ ! action->isChecked());
+}
diff --git a/stacer/Pages/Processes/processes_page.h b/stacer/Pages/Processes/processes_page.h
new file mode 100644
index 0000000..0f30edc
--- /dev/null
+++ b/stacer/Pages/Processes/processes_page.h
@@ -0,0 +1,50 @@
+#ifndef PROCESSESPAGE_H
+#define PROCESSESPAGE_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "Managers/info_manager.h"
+
+namespace Ui {
+ class ProcessesPage;
+}
+
+class ProcessesPage : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ProcessesPage(QWidget *parent = 0);
+ ~ProcessesPage();
+
+private slots:
+ void init();
+ void loadProcesses();
+ QList createRow(Process proc);
+ void on_processSearchBox_textChanged(const QString &val);
+ void on_refreshSlider_valueChanged(int i);
+ void on_endProcessBtn_clicked();
+ void on_processTable_customContextMenuRequested(const QPoint &pos);
+ void loadHeaderMenu();
+
+private:
+ Ui::ProcessesPage *ui;
+
+private:
+ QStandardItemModel *model;
+ QSortFilterProxyModel *sortModel;
+ QModelIndex seletedRowModel;
+ QStringList headers;
+ InfoManager *im;
+ QTimer *timer;
+ QMenu headerMenu;
+};
+
+#endif // PROCESSESPAGE_H
diff --git a/stacer/Pages/Processes/processes_page.ui b/stacer/Pages/Processes/processes_page.ui
new file mode 100644
index 0000000..dd9e97c
--- /dev/null
+++ b/stacer/Pages/Processes/processes_page.ui
@@ -0,0 +1,217 @@
+
+
+ ProcessesPage
+
+
+
+ 0
+ 0
+ 835
+ 612
+
+
+
+
+
+
+
+
+
+
+ 20
+
+
+ 5
+
+
+ 20
+
+
+ 20
+
+
+ 0
+
+
+ 5
+
+ -
+
+
+ 10
+
+
+ 5
+
+
+ 0
+
+
+ 10
+
+ -
+
+
+ Processes
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+ All Processes
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Search...
+
+
+ true
+
+
+
+
+
+ -
+
+
+ Qt::NoFocus
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Sunken
+
+
+ QAbstractScrollArea::AdjustToContents
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+ QAbstractItemView::SingleSelection
+
+
+ QAbstractItemView::SelectRows
+
+
+ Qt::ElideMiddle
+
+
+ Qt::SolidLine
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+ -
+
+
+
+ 10
+
+
+ 0
+
+
+ 5
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ Refresh (1)
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+ End Process
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/Pages/Resources/history_chart.cpp b/stacer/Pages/Resources/history_chart.cpp
new file mode 100644
index 0000000..e0c0fbb
--- /dev/null
+++ b/stacer/Pages/Resources/history_chart.cpp
@@ -0,0 +1,103 @@
+#include "history_chart.h"
+#include "ui_history_chart.h"
+
+HistoryChart::~HistoryChart()
+{
+ delete ui;
+ delete chart;
+ delete chartView;
+}
+
+HistoryChart::HistoryChart(QString title, int seriesCount, QWidget *parent) :
+ QWidget(parent),
+ title(title),
+ yMax(0),
+ seriesCount(seriesCount),
+ chartView(new QChartView),
+ chart(chartView->chart()),
+ apm(AppManager::ins()),
+ ui(new Ui::HistoryChart)
+{
+ ui->setupUi(this);
+
+ init();
+}
+
+void HistoryChart::init()
+{
+ ui->historyTitle->setText(title);
+
+ // create lists
+ for (int i = 0; i < seriesCount; i++)
+ seriesList.append(new QLineSeries);
+
+ // add series to chart
+ for (int i = 0; i < seriesList.count(); ++i)
+ chart->addSeries(seriesList.at(i));
+
+ chartView->setRenderHint(QPainter::Antialiasing);
+
+ QList colors = {
+ 0x2ecc71, 0xe74c3c, 0x3498db, 0xf1c40f, 0xe67e22,
+ 0x1abc9c, 0x9b59b6, 0x34495e, 0xd35400, 0xc0392b,
+ 0x8e44ad, 0xFF8F00, 0xEF6C00, 0x4E342E, 0x424242,
+ 0x5499C7, 0x58D68D, 0xCD6155, 0xF5B041, 0x566573
+ };
+ // set colors
+ for (int i = 0; i < seriesList.count(); ++i)
+ seriesList.at(i)->setColor(QColor(colors.at(i)));
+
+ // Chart Settings
+ chart->createDefaultAxes();
+
+ chart->axisX()->setRange(0, 60);
+ chart->axisX()->setReverse(true);
+
+ chart->setContentsMargins(-11, -11, -11, -11);
+ chart->setMargins(QMargins(20, 0, 10, 10));
+ ui->verticalLayout->addWidget(chartView);
+
+ // theme changed
+ connect(AppManager::ins(), &AppManager::changedTheme, this, [this]() {
+ chart->axisX()->setLabelsColor(apm->getStyleValues()->value("@chartLabelColor").toString());
+ chart->axisX()->setGridLineColor(apm->getStyleValues()->value("@chartGridColor").toString());
+
+ chart->axisY()->setLabelsColor(apm->getStyleValues()->value("@chartLabelColor").toString());
+ chart->axisY()->setGridLineColor(apm->getStyleValues()->value("@chartGridColor").toString());
+
+ chart->setBackgroundBrush(QColor(apm->getStyleValues()->value("@historyChartBackgroundColor").toString()));
+ chart->legend()->setLabelColor(apm->getStyleValues()->value("@chartLabelColor").toString());
+ });
+}
+
+void HistoryChart::setYMax(int value)
+{
+ yMax = value;
+}
+
+QVector HistoryChart::getSeriesList() const
+{
+ return seriesList;
+}
+
+void HistoryChart::setSeriesList(QVector &value)
+{
+ seriesList = value;
+
+ for (int i = 0; i < seriesList.count(); ++i)
+ chart->series().replace(0, seriesList.at(i));
+
+ if(yMax) chart->axisY()->setRange(0, yMax);
+
+ chartView->repaint();
+}
+
+void HistoryChart::on_historyTitle_clicked(bool checked)
+{
+ QLayout *charts = topLevelWidget()->findChild("charts")->layout();
+
+ for (int i = 0; i < charts->count(); ++i)
+ charts->itemAt(i)->widget()->setVisible(! checked);
+
+ show();
+}
diff --git a/stacer/Pages/Resources/history_chart.h b/stacer/Pages/Resources/history_chart.h
new file mode 100644
index 0000000..ce8d1e5
--- /dev/null
+++ b/stacer/Pages/Resources/history_chart.h
@@ -0,0 +1,46 @@
+#ifndef HISTORYCHART_H
+#define HISTORYCHART_H
+
+#include
+#include
+#include
+#include
+
+#include "Managers/app_manager.h"
+
+namespace Ui {
+ class HistoryChart;
+}
+
+class HistoryChart : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit HistoryChart(QString title, int seriesCount, QWidget *parent = 0);
+ ~HistoryChart();
+
+ QVector getSeriesList() const;
+
+public slots:
+ void setYMax(int value);
+ void setSeriesList(QVector &value);
+
+private slots:
+ void init();
+ void on_historyTitle_clicked(bool checked);
+
+private:
+ Ui::HistoryChart *ui;
+
+private:
+ QString title;
+ int yMax;
+ int seriesCount;
+ QChartView *chartView;
+ QChart *chart;
+ QVector seriesList;
+ AppManager *apm;
+};
+
+#endif // HISTORYCHART_H
diff --git a/stacer/Pages/Resources/history_chart.ui b/stacer/Pages/Resources/history_chart.ui
new file mode 100644
index 0000000..f3069ba
--- /dev/null
+++ b/stacer/Pages/Resources/history_chart.ui
@@ -0,0 +1,52 @@
+
+
+ HistoryChart
+
+
+
+ 0
+ 0
+ 930
+ 387
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+ Chart Title
+
+
+
+
+
+
+
+
diff --git a/stacer/Pages/Resources/resources_page.cpp b/stacer/Pages/Resources/resources_page.cpp
new file mode 100644
index 0000000..671b065
--- /dev/null
+++ b/stacer/Pages/Resources/resources_page.cpp
@@ -0,0 +1,165 @@
+#include "resources_page.h"
+#include "ui_resources_page.h"
+
+ResourcesPage::~ResourcesPage()
+{
+ delete ui;
+ delete cpuChart;
+ delete memoryChart;
+ delete networkChart;
+ delete timer;
+}
+
+ResourcesPage::ResourcesPage(QWidget *parent) :
+ QWidget(parent),
+ timer(new QTimer),
+ im(InfoManager::ins()),
+ ui(new Ui::ResourcesPage)
+{
+ ui->setupUi(this);
+
+ init();
+}
+
+void ResourcesPage::init()
+{
+ cpuChart = new HistoryChart(tr("CPU History"), im->getCpuCoreCount());
+ cpuChart->setYMax(100);
+
+ memoryChart = new HistoryChart(tr("Memory History"), 2);
+ memoryChart->setYMax(100);
+
+ networkChart = new HistoryChart(tr("Network History"), 2);
+
+ ui->chartsLayout->addWidget(cpuChart);
+ ui->chartsLayout->addWidget(memoryChart);
+ ui->chartsLayout->addWidget(networkChart);
+
+ connect(timer, &QTimer::timeout, this, &ResourcesPage::updateCpuChart);
+ connect(timer, &QTimer::timeout, this, &ResourcesPage::updateMemoryChart);
+ connect(timer, &QTimer::timeout, this, &ResourcesPage::updateNetworkChart);
+
+ timer->start(1 * 1000);
+}
+
+void ResourcesPage::updateNetworkChart()
+{
+ static int second = 0;
+
+ QVector seriesList = networkChart->getSeriesList();
+
+ // points swap
+ for (int j = 0; j < seriesList.count(); j++) {
+ for (int i = 0; i < (second < 61 ? second : 61); i++)
+ seriesList.at(j)->replace(i, (i+1), seriesList.at(j)->at(i).y());
+
+ if(second > 61)
+ seriesList.at(j)->removePoints(61, 1);
+ }
+
+ static quint64 l_RXbytes = im->getRXbytes();
+ static quint64 l_TXbytes = im->getTXbytes();
+ static quint64 max_RXbytes = 1L << 20; // 1 MEBI
+ static quint64 max_TXbytes = 1L << 20; // 1 MEBI
+
+ quint64 RXbytes = im->getRXbytes();
+ quint64 TXbytes = im->getTXbytes();
+
+ quint64 d_RXbytes = (RXbytes - l_RXbytes);
+ quint64 d_TXbytes = (TXbytes - l_TXbytes);
+
+ QString downText = FormatUtil::formatBytes(d_RXbytes);
+ QString upText = FormatUtil::formatBytes(d_TXbytes);
+
+ // Download
+ seriesList.at(0)->insert(0, QPointF(0, d_RXbytes >> 10));
+ seriesList.at(0)->setName(tr("Download %1/s Total: %2")
+ .arg(downText)
+ .arg(FormatUtil::formatBytes(RXbytes)));
+
+ seriesList.at(1)->insert(0, QPointF(0, d_TXbytes >> 10));
+ seriesList.at(1)->setName(tr("Upload %1/s Total: %2")
+ .arg(upText)
+ .arg(FormatUtil::formatBytes(TXbytes)));
+
+ max_RXbytes = qMax(max_RXbytes, d_RXbytes);
+ max_TXbytes = qMax(max_TXbytes, d_TXbytes);
+
+ int max = qMax(max_RXbytes, max_TXbytes) >> 10;
+ networkChart->setYMax(max);
+
+ l_RXbytes = RXbytes;
+ l_TXbytes = TXbytes;
+
+ second++;
+
+ networkChart->setSeriesList(seriesList);
+}
+
+void ResourcesPage::updateMemoryChart()
+{
+ static int second = 0;
+
+ QVector seriesList = memoryChart->getSeriesList();
+
+ im->updateMemoryInfo();
+
+ // points swap
+ for (int j = 0; j < seriesList.count(); j++) {
+ for (int i = 0; i < (second < 61 ? second : 61); i++)
+ seriesList.at(j)->replace(i, (i+1), seriesList.at(j)->at(i).y());
+
+ if(second > 61)
+ seriesList.at(j)->removePoints(61, 1);
+ }
+
+ // Swap
+ double percent = 0;
+ if (im->getSwapTotal()) // aritmetic exception control
+ percent = ((double) im->getSwapUsed() / (double) im->getSwapTotal()) * 100.0;
+
+ seriesList.at(0)->insert(0, QPointF(0, percent));
+ seriesList.at(0)->setName(tr("Swap %1 (%2%) %3")
+ .arg(FormatUtil::formatBytes(im->getSwapUsed()))
+ .arg(QString().sprintf("%.1f",percent))
+ .arg(FormatUtil::formatBytes(im->getSwapTotal())));
+
+ // Memory
+ double percent2 = ((double) im->getMemUsed() / (double) im->getMemTotal()) * 100.0;
+
+ seriesList.at(1)->insert(0, QPointF(0, percent2));
+ seriesList.at(1)->setName(tr("Memory %1 (%2%) %3")
+ .arg(FormatUtil::formatBytes(im->getMemUsed()))
+ .arg(QString().sprintf("%.1f",percent2))
+ .arg(FormatUtil::formatBytes(im->getMemTotal())));
+
+ second++;
+
+ memoryChart->setSeriesList(seriesList);
+}
+
+void ResourcesPage::updateCpuChart()
+{
+ static int second = 0;
+
+ QList cpuPercents = im->getCpuPercents();
+
+ QVector seriesList = cpuChart->getSeriesList();
+
+ for (int j = 0; j < seriesList.count(); j++){
+ int p = cpuPercents.at(j+1);
+
+ for (int i = 0; i < (second < 61 ? second : 61); i++)
+ seriesList.at(j)->replace(i, (i+1), seriesList.at(j)->at(i).y());
+
+ seriesList.at(j)->insert(0, QPointF(0, p));
+
+ seriesList.at(j)->setName(QString("CPU%1 %2%").arg(j+1).arg(p));
+
+ if(second > 61) seriesList.at(j)->removePoints(61, 1);
+ }
+
+ second++;
+
+ cpuChart->setSeriesList(seriesList);
+}
diff --git a/stacer/Pages/Resources/resources_page.h b/stacer/Pages/Resources/resources_page.h
new file mode 100644
index 0000000..f45df77
--- /dev/null
+++ b/stacer/Pages/Resources/resources_page.h
@@ -0,0 +1,40 @@
+#ifndef RESOURCESPAGE_H
+#define RESOURCESPAGE_H
+
+#include
+#include
+
+#include "history_chart.h"
+#include "Managers/info_manager.h"
+
+namespace Ui {
+ class ResourcesPage;
+}
+
+class ResourcesPage : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ResourcesPage(QWidget *parent = 0);
+ ~ResourcesPage();
+
+private slots:
+ void updateCpuChart();
+ void updateMemoryChart();
+ void updateNetworkChart();
+
+private:
+ Ui::ResourcesPage *ui;
+ void init();
+
+private:
+ HistoryChart *cpuChart;
+ HistoryChart *memoryChart;
+ HistoryChart *networkChart;
+
+ QTimer *timer;
+ InfoManager *im;
+};
+
+#endif // RESOURCESPAGE_H
diff --git a/stacer/Pages/Resources/resources_page.ui b/stacer/Pages/Resources/resources_page.ui
new file mode 100644
index 0000000..d346e6f
--- /dev/null
+++ b/stacer/Pages/Resources/resources_page.ui
@@ -0,0 +1,57 @@
+
+
+ ResourcesPage
+
+
+
+ 0
+ 0
+ 890
+ 537
+
+
+
+
+
+
+
+ 0
+
+
+ 10
+
+
+ 10
+
+
+ 10
+
+
+ 1
+
+ -
+
+
+
+ 10
+
+
+ 10
+
+
+ 0
+
+
+ 10
+
+
+ 10
+
+
+
+
+
+
+
+
+
diff --git a/stacer/Pages/Services/service_item.cpp b/stacer/Pages/Services/service_item.cpp
new file mode 100644
index 0000000..8bde30e
--- /dev/null
+++ b/stacer/Pages/Services/service_item.cpp
@@ -0,0 +1,37 @@
+#include "service_item.h"
+#include "ui_service_item.h"
+
+ServiceItem::~ServiceItem()
+{
+ delete ui;
+}
+
+ServiceItem::ServiceItem(QString name, bool status, bool active, QWidget *parent) :
+ QWidget(parent),
+ name(name),
+ tm(ToolManager::ins()),
+ ui(new Ui::ServiceItem)
+{
+ ui->setupUi(this);
+
+ ui->serviceName->setText(name);
+ ui->runningBtn->setChecked(active);
+ ui->startupBtn->setChecked(status);
+
+ connect(ui->startupBtn, &QCheckBox::clicked, this, &ServiceItem::startupBtn_toggled);
+ connect(ui->runningBtn, &QCheckBox::clicked, this, &ServiceItem::runningBtn_toggled);
+}
+
+void ServiceItem::startupBtn_toggled(bool status)
+{
+ tm->changeServiceStatus(ui->serviceName->text(), status);
+
+ ui->startupBtn->setChecked(tm->serviceIsEnabled(name));
+}
+
+void ServiceItem::runningBtn_toggled(bool status)
+{
+ tm->changeServiceActive(ui->serviceName->text(), status);
+
+ ui->runningBtn->setChecked(tm->serviceIsActive(name));
+}
diff --git a/stacer/Pages/Services/service_item.h b/stacer/Pages/Services/service_item.h
new file mode 100644
index 0000000..a8848b0
--- /dev/null
+++ b/stacer/Pages/Services/service_item.h
@@ -0,0 +1,33 @@
+#ifndef SERVICE_ITEM_H
+#define SERVICE_ITEM_H
+
+#include
+#include
+#include "Managers/tool_manager.h"
+
+namespace Ui {
+ class ServiceItem;
+}
+
+class ServiceItem : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ServiceItem(QString name, bool status, bool active, QWidget *parent = 0);
+ ~ServiceItem();
+
+private slots:
+ void runningBtn_toggled(bool status);
+ void startupBtn_toggled(bool status);
+
+private:
+ Ui::ServiceItem *ui;
+
+private:
+ QString name;
+
+ ToolManager *tm;
+};
+
+#endif // SERVICE_ITEM_H
diff --git a/stacer/Pages/Services/service_item.ui b/stacer/Pages/Services/service_item.ui
new file mode 100644
index 0000000..ed66148
--- /dev/null
+++ b/stacer/Pages/Services/service_item.ui
@@ -0,0 +1,171 @@
+
+
+ ServiceItem
+
+
+
+ 0
+ 0
+ 713
+ 45
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 45
+
+
+
+
+ 16777215
+ 45
+
+
+
+ ArrowCursor
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+ 0
+ 45
+
+
+
+
+ 16777215
+ 45
+
+
+
+
+ 15
+
+
+ 10
+
+
+ 10
+
+
+ 0
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 60
+ 0
+
+
+
+
+ -
+
+
+
+ 25
+ 25
+
+
+
+
+ 25
+ 25
+
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+ Service Name
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/Pages/Services/services_page.cpp b/stacer/Pages/Services/services_page.cpp
new file mode 100644
index 0000000..32122e3
--- /dev/null
+++ b/stacer/Pages/Services/services_page.cpp
@@ -0,0 +1,52 @@
+#include "services_page.h"
+#include "ui_services_page.h"
+
+ServicesPage::~ServicesPage()
+{
+ delete ui;
+}
+
+ServicesPage::ServicesPage(QWidget *parent) :
+ QWidget(parent),
+ tm(ToolManager::ins()),
+ ui(new Ui::ServicesPage)
+{
+ ui->setupUi(this);
+
+ init();
+}
+
+void ServicesPage::init()
+{
+ loadServices();
+
+ if(ui->serviceListWidget->count()) {
+ ui->notFoundWidget->hide();
+ }
+ else { // list widget is empty show not found
+ ui->notFoundWidget->show();
+ ui->serviceListWidget->hide();
+ }
+}
+
+void ServicesPage::loadServices()
+{
+ foreach (Service s, tm->getServices()) {
+
+ ServiceItem *service = new ServiceItem(s.name, s.status, s.active, this);
+
+ QListWidgetItem *item = new QListWidgetItem(ui->serviceListWidget);
+
+ item->setSizeHint(service->sizeHint());
+
+ ui->serviceListWidget->setItemWidget(item, service);
+ }
+
+ setAppCount();
+}
+
+void ServicesPage::setAppCount()
+{
+ ui->servicesTitle->setText(tr("System Services (%1)")
+ .arg(ui->serviceListWidget->count()));
+}
diff --git a/stacer/Pages/Services/services_page.h b/stacer/Pages/Services/services_page.h
new file mode 100644
index 0000000..b64bf35
--- /dev/null
+++ b/stacer/Pages/Services/services_page.h
@@ -0,0 +1,36 @@
+#ifndef SERVICESPAGE_H
+#define SERVICESPAGE_H
+
+#include
+#include
+#include
+#include "service_item.h"
+#include "Managers/tool_manager.h"
+
+namespace Ui {
+ class ServicesPage;
+}
+
+class ServicesPage : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ServicesPage(QWidget *parent = 0);
+ ~ServicesPage();
+
+private slots:
+ void init();
+ void loadServices();
+
+public slots:
+ void setAppCount();
+
+private:
+ Ui::ServicesPage *ui;
+
+private:
+ ToolManager *tm;
+};
+
+#endif // SERVICESPAGE_H
diff --git a/stacer/Pages/Services/services_page.ui b/stacer/Pages/Services/services_page.ui
new file mode 100644
index 0000000..ee68d53
--- /dev/null
+++ b/stacer/Pages/Services/services_page.ui
@@ -0,0 +1,304 @@
+
+
+ ServicesPage
+
+
+
+ 0
+ 0
+ 882
+ 549
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+
+
+
+ 0
+
+
+ 30
+
+
+ 10
+
+
+ 30
+
+
+ 30
+
+ -
+
+
+ 0
+
+
+ 15
+
+
+ 45
+
+
+ 0
+
+ -
+
+
+
+ Ubuntu
+ 11
+
+
+
+
+
+
+ System Services
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 20
+ 20
+
+
+
+
+ 80
+ 16777215
+
+
+
+
+ Ubuntu
+ 10
+
+
+
+ Startup at boot ?
+
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 100
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 20
+ 20
+
+
+
+
+ 100
+ 16777215
+
+
+
+
+ Ubuntu
+ 10
+
+
+
+ Running Now ?
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 200
+
+
+
+
+ 16777215
+ 9999999
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 180
+
+
+
+
+ -
+
+
+ Not Found System Service
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 0
+
+
+
+
+
+
+
+ -
+
+
+ Qt::NoFocus
+
+
+ Qt::ScrollBarAlwaysOff
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+ QAbstractItemView::NoSelection
+
+
+ QAbstractItemView::SelectRows
+
+
+ QListView::Adjust
+
+
+ QListView::Batched
+
+
+ 4
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/Pages/Settings/settings_page.cpp b/stacer/Pages/Settings/settings_page.cpp
new file mode 100644
index 0000000..10ff8bf
--- /dev/null
+++ b/stacer/Pages/Settings/settings_page.cpp
@@ -0,0 +1,60 @@
+#include "settings_page.h"
+#include "ui_settings_page.h"
+
+SettingsPage::~SettingsPage()
+{
+ delete ui;
+}
+
+SettingsPage::SettingsPage(QWidget *parent) :
+ QWidget(parent),
+ apm(AppManager::ins()),
+ ui(new Ui::SettingsPage)
+{
+ ui->setupUi(this);
+
+ init();
+}
+
+void SettingsPage::init()
+{
+ // load languages
+ QMapIterator lang(apm->getLanguageList());
+
+ while (lang.hasNext()) {
+ lang.next();
+ ui->languagesCmb->addItem(lang.value(),lang.key());
+ }
+
+ QString lc = apm->getLanguageCode();
+ ui->languagesCmb->setCurrentText(apm->getLanguageList().value(lc));
+
+ // load themes
+ QMapIterator theme(apm->getThemeList());
+
+ while (theme.hasNext()) {
+ theme.next();
+ ui->themesCmb->addItem(theme.value(),theme.key());
+ }
+
+ QString tn = apm->getThemeName();
+ ui->themesCmb->setCurrentText(apm->getThemeList().value(tn));
+
+ connect(ui->languagesCmb, SIGNAL(currentIndexChanged(int)), this, SLOT(languagesCmbChanged(int)));
+ connect(ui->themesCmb, SIGNAL(currentIndexChanged(int)), this, SLOT(themesCmbChanged(int)));
+}
+
+void SettingsPage::languagesCmbChanged(int index)
+{
+ QString langCode = ui->languagesCmb->itemData(index).toString();
+
+ apm->setLanguage(langCode);
+}
+
+void SettingsPage::themesCmbChanged(int index)
+{
+ QString themeName = ui->themesCmb->itemData(index).toString();
+
+ apm->setThemeName(themeName);
+ apm->updateStylesheet();
+}
diff --git a/stacer/Pages/Settings/settings_page.h b/stacer/Pages/Settings/settings_page.h
new file mode 100644
index 0000000..b32aab9
--- /dev/null
+++ b/stacer/Pages/Settings/settings_page.h
@@ -0,0 +1,34 @@
+#ifndef SETTINGS_PAGE_H
+#define SETTINGS_PAGE_H
+
+#include
+#include
+
+#include "Managers/app_manager.h"
+
+namespace Ui {
+ class SettingsPage;
+}
+
+class SettingsPage : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit SettingsPage(QWidget *parent = 0);
+ ~SettingsPage();
+
+private slots:
+ void init();
+
+ void themesCmbChanged(int index);
+ void languagesCmbChanged(int index);
+
+private:
+ Ui::SettingsPage *ui;
+
+private:
+ AppManager *apm;
+};
+
+#endif // SETTINGS_PAGE_H
diff --git a/stacer/Pages/Settings/settings_page.ui b/stacer/Pages/Settings/settings_page.ui
new file mode 100644
index 0000000..a3e71d0
--- /dev/null
+++ b/stacer/Pages/Settings/settings_page.ui
@@ -0,0 +1,105 @@
+
+
+ SettingsPage
+
+
+
+ 0
+ 0
+ 733
+ 479
+
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+
+ 15
+
+
+ 15
+
+
+ 15
+
+
+ 15
+
+
+ 30
+
+
+ 10
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+ -
+
+
+ Language
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+ -
+
+
+ Theme
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
diff --git a/stacer/Pages/StartupApps/startup_app.cpp b/stacer/Pages/StartupApps/startup_app.cpp
new file mode 100644
index 0000000..d9bf64f
--- /dev/null
+++ b/stacer/Pages/StartupApps/startup_app.cpp
@@ -0,0 +1,84 @@
+#include "startup_app.h"
+#include "ui_startup_app.h"
+
+StartupApp::~StartupApp()
+{
+ delete ui;
+ delete startupAppEdit;
+}
+
+StartupApp::StartupApp(QString appName, bool enabled, QString filePath, QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::StartupApp),
+ startupAppEdit(new StartupAppEdit),
+ appName(appName),
+ enabled(enabled),
+ filePath(filePath)
+{
+ ui->setupUi(this);
+
+ ui->appName->setText(appName);
+ ui->startupCheck->setChecked(enabled);
+
+ ui->deleteAppBtn->setToolTip(tr("Delete"));
+ ui->editAppBtn->setToolTip(tr("Edit"));
+
+ connect(startupAppEdit, &StartupAppEdit::closeWindow, (StartupAppsPage*)parent, &StartupAppsPage::loadApps);
+}
+
+void StartupApp::on_startupCheck_clicked(bool status)
+{
+ QStringList lines = FileUtil::readListFromFile(filePath);
+
+ int pos = lines.indexOf(QRegExp("X-GNOME-Autostart-enabled=.*"));
+
+ if(pos != -1)
+ {
+ lines.replace(pos, QString("X-GNOME-Autostart-enabled=%1").arg(status ? "true" : "false"));
+
+ FileUtil::writeFile(filePath, lines.join("\n"));
+ }
+}
+
+void StartupApp::on_deleteAppBtn_clicked()
+{
+ if(QFile::remove(filePath))
+ deleteApp();
+}
+
+void StartupApp::on_editAppBtn_clicked()
+{
+ StartupAppEdit::selectedFilePath = filePath;
+ startupAppEdit->show();
+}
+
+QString StartupApp::getAppName() const
+{
+ return appName;
+}
+
+void StartupApp::setAppName(const QString &value)
+{
+ appName = value;
+}
+
+bool StartupApp::getEnabled() const
+{
+ return enabled;
+}
+
+void StartupApp::setEnabled(bool value)
+{
+ enabled = value;
+}
+
+QString StartupApp::getFilePath() const
+{
+ return filePath;
+}
+
+void StartupApp::setFilePath(const QString &value)
+{
+ filePath = value;
+}
+
diff --git a/stacer/Pages/StartupApps/startup_app.h b/stacer/Pages/StartupApps/startup_app.h
new file mode 100644
index 0000000..826ee6d
--- /dev/null
+++ b/stacer/Pages/StartupApps/startup_app.h
@@ -0,0 +1,51 @@
+#ifndef STARTUP_APP_H
+#define STARTUP_APP_H
+
+#include
+#include
+#include
+
+#include "startup_app_edit.h"
+#include "startup_apps_page.h"
+
+namespace Ui {
+ class StartupApp;
+}
+
+class StartupApp : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit StartupApp(QString appName, bool enabled, QString filePath, QWidget *parent = 0);
+ ~StartupApp();
+
+ QString getAppName() const;
+ void setAppName(const QString &value);
+
+ bool getEnabled() const;
+ void setEnabled(bool value);
+
+ QString getFilePath() const;
+ void setFilePath(const QString &value);
+
+private slots:
+ void on_startupCheck_clicked(bool);
+ void on_deleteAppBtn_clicked();
+ void on_editAppBtn_clicked();
+
+signals:
+ void deleteApp();
+
+private:
+ Ui::StartupApp *ui;
+
+private:
+ QString appName;
+ QString appComment;
+ bool enabled;
+ QString filePath;
+ StartupAppEdit *startupAppEdit;
+};
+
+#endif // STARTUP_APP_H
diff --git a/stacer/Pages/StartupApps/startup_app.ui b/stacer/Pages/StartupApps/startup_app.ui
new file mode 100644
index 0000000..609bcf7
--- /dev/null
+++ b/stacer/Pages/StartupApps/startup_app.ui
@@ -0,0 +1,177 @@
+
+
+ StartupApp
+
+
+
+ 0
+ 0
+ 661
+ 45
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 45
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ ArrowCursor
+
+
+
+ 15
+
+
+ 15
+
+
+ 10
+
+
+ 10
+
+
+ 10
+
+ -
+
+
+
+ 22
+ 24
+
+
+
+
+ 22
+ 24
+
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+ App Name
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+
+ 18
+ 20
+
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+
+ 22
+ 22
+
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+
+ 45
+ 23
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/Pages/StartupApps/startup_app_edit.cpp b/stacer/Pages/StartupApps/startup_app_edit.cpp
new file mode 100644
index 0000000..18af086
--- /dev/null
+++ b/stacer/Pages/StartupApps/startup_app_edit.cpp
@@ -0,0 +1,117 @@
+#include "startup_app_edit.h"
+#include "ui_startup_app_edit.h"
+
+StartupAppEdit::~StartupAppEdit()
+{
+ delete ui;
+}
+
+QString StartupAppEdit::selectedFilePath = "";
+
+StartupAppEdit::StartupAppEdit(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::StartupAppEdit)
+{
+ ui->setupUi(this);
+
+ init();
+}
+
+void StartupAppEdit::init()
+{
+ setGeometry(
+ QStyle::alignedRect(
+ Qt::LeftToRight,
+ Qt::AlignCenter,
+ size(),
+ qApp->desktop()->availableGeometry())
+ );
+
+ ui->errorMsg->hide();
+
+ setStyleSheet(AppManager::ins()->getStylesheetFileContent());
+
+ newAppTemplate = "[Desktop Entry]\n"
+ "Name=%1\n"
+ "Comment=%2\n"
+ "Exec=%3\n"
+ "Type=Application\n"
+ "Terminal=false\n"
+ "X-GNOME-Autostart-enabled=true";
+}
+
+void StartupAppEdit::show()
+{
+ // clear fields
+ ui->appNameTxt->clear();
+ ui->appCommentTxt->clear();
+ ui->appCommandTxt->clear();
+ ui->errorMsg->hide();
+
+ if(! selectedFilePath.isEmpty())
+ {
+ QStringList lines = FileUtil::readListFromFile(selectedFilePath);
+
+ if(! lines.isEmpty())
+ {
+#define getValue(r) lines.filter(r).first().split("=").last().trimmed()
+ ui->appNameTxt->setText(getValue(NAME_REG));
+ ui->appCommentTxt->setText(getValue(COMMENT_REG));
+ ui->appCommandTxt->setText(getValue(EXEC_REG));
+#undef getValue
+ }
+ }
+
+ QDialog::show();
+}
+
+void StartupAppEdit::on_saveBtn_clicked()
+{
+ static QString autostartPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/autostart";
+
+ if(isValid())
+ {
+ if(! selectedFilePath.isEmpty())
+ {
+ QStringList lines = FileUtil::readListFromFile(selectedFilePath);
+
+ lines.replace(lines.indexOf(NAME_REG), QString("Name=%1").arg(ui->appNameTxt->text()));
+ lines.replace(lines.indexOf(COMMENT_REG), QString("Comment=%1").arg(ui->appCommentTxt->text()));
+ lines.replace(lines.indexOf(EXEC_REG), QString("Exec=%1").arg(ui->appCommandTxt->text()));
+
+ FileUtil::writeFile(selectedFilePath, QString(lines.join("\n")), QIODevice::ReadWrite | QIODevice::Truncate);
+ }
+ else
+ {
+ // new file content
+ QString appContent = newAppTemplate
+ .arg(ui->appNameTxt->text())
+ .arg(ui->appCommentTxt->text())
+ .arg(ui->appCommandTxt->text());
+
+ // file name
+ QString appFileName = ui->appNameTxt->text()
+ .replace(" ", "_")
+ .replace(QRegExp("\\W+"), "");
+
+ QString path = QString("%1/%2.desktop").arg(autostartPath).arg(appFileName);
+
+ FileUtil::writeFile(path, appContent);
+ }
+
+ close();
+ closeWindow(); // signal
+ }
+ else {
+ ui->errorMsg->show();
+ }
+
+ selectedFilePath = "";
+}
+
+bool StartupAppEdit::isValid()
+{
+ return ! ui->appNameTxt->text().isEmpty() &&
+ ! ui->appCommentTxt->text().isEmpty() &&
+ ! ui->appCommandTxt->text().isEmpty();
+}
diff --git a/stacer/Pages/StartupApps/startup_app_edit.h b/stacer/Pages/StartupApps/startup_app_edit.h
new file mode 100644
index 0000000..f848c34
--- /dev/null
+++ b/stacer/Pages/StartupApps/startup_app_edit.h
@@ -0,0 +1,46 @@
+#ifndef STARTUP_APP_EDIT_H
+#define STARTUP_APP_EDIT_H
+
+#include
+#include
+
+#include "Managers/app_manager.h"
+
+#define NAME_REG QRegExp("(\\W+|^)Name=.*")
+#define COMMENT_REG QRegExp("(\\W+|^)Comment=.*")
+#define EXEC_REG QRegExp("(\\W+|^)Exec=.*")
+
+namespace Ui {
+ class StartupAppEdit;
+}
+
+class StartupAppEdit : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit StartupAppEdit(QWidget *parent = 0);
+ ~StartupAppEdit();
+
+public:
+ static QString selectedFilePath;
+
+signals:
+ void closeWindow();
+
+public slots:
+ void show();
+
+private slots:
+ void init();
+ bool isValid();
+ void on_saveBtn_clicked();
+
+private:
+ Ui::StartupAppEdit *ui;
+
+private:
+ QString newAppTemplate;
+};
+
+#endif // STARTUP_APP_EDIT_H
diff --git a/stacer/Pages/StartupApps/startup_app_edit.ui b/stacer/Pages/StartupApps/startup_app_edit.ui
new file mode 100644
index 0000000..5449975
--- /dev/null
+++ b/stacer/Pages/StartupApps/startup_app_edit.ui
@@ -0,0 +1,115 @@
+
+
+ StartupAppEdit
+
+
+
+ 0
+ 0
+ 380
+ 260
+
+
+
+
+ 380
+ 260
+
+
+
+ Startup App
+
+
+ true
+
+
+
+ 30
+
+
+ 20
+
+
+ 30
+
+
+ 20
+
+
+ 15
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+ Save
+
+
+ true
+
+
+
+ -
+
+
+ Fields cannot be left blank.
+
+
+
+ -
+
+
+ App Comment
+
+
+
+ -
+
+
+ App Name
+
+
+
+ -
+
+
+ Command
+
+
+
+ -
+
+
+ Application
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 0
+
+
+
+
+
+
+
+ appNameTxt
+ appCommentTxt
+ appCommandTxt
+ saveBtn
+
+
+
+
diff --git a/stacer/Pages/StartupApps/startup_apps_page.cpp b/stacer/Pages/StartupApps/startup_apps_page.cpp
new file mode 100644
index 0000000..3c57979
--- /dev/null
+++ b/stacer/Pages/StartupApps/startup_apps_page.cpp
@@ -0,0 +1,90 @@
+#include "startup_apps_page.h"
+#include "ui_startup_apps_page.h"
+
+StartupAppsPage::~StartupAppsPage()
+{
+ delete ui;
+ delete startupAppEdit;
+}
+
+StartupAppsPage::StartupAppsPage(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::StartupAppsPage),
+ startupAppEdit(new StartupAppEdit)
+{
+ ui->setupUi(this);
+
+ init();
+}
+
+void StartupAppsPage::init()
+{
+ loadApps();
+
+ connect(startupAppEdit, &StartupAppEdit::closeWindow, this, &StartupAppsPage::loadApps);
+}
+
+void StartupAppsPage::loadApps()
+{
+ // clear layout
+ ui->startupListWidget->clear();
+
+ static QString autostartPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/autostart";
+
+ QDir autostartFiles(autostartPath, "*.desktop");
+
+ foreach (QFileInfo f, autostartFiles.entryInfoList())
+ {
+ QStringList lines = FileUtil::readListFromFile(f.absoluteFilePath());
+
+ QStringList d_name = lines.filter(QRegExp("(\\W+|^)Name=")); // get name
+
+ if(! d_name.isEmpty()) // has a name
+ {
+ QString appName = d_name.first().split("=").last().trimmed();
+
+ QStringList d_autostart = lines.filter(QRegExp("(\\W+|^)X-GNOME-Autostart-enabled="));
+
+ bool enabled = false;
+ if(! d_autostart.isEmpty())
+ {
+ // X-GNOME-Autostart-enabled=[true|false]
+ QString status = d_autostart.first()
+ .split("=").last().toLower().trimmed();
+
+ enabled = ! status.compare("true");
+ }
+
+ QListWidgetItem *item = new QListWidgetItem(ui->startupListWidget);
+ // new app
+ StartupApp *app = new StartupApp(appName, enabled, f.absoluteFilePath(), this);
+
+ // delete button click
+ connect(app, &StartupApp::deleteApp, this, &StartupAppsPage::loadApps);
+
+ item->setSizeHint(app->sizeHint());
+
+ ui->startupListWidget->setItemWidget(item, app);
+ }
+ }
+
+ setAppCount();
+}
+
+void StartupAppsPage::setAppCount()
+{
+ int count = ui->startupListWidget->count();
+
+ ui->startupAppsTitleLbl->setText(
+ tr("System Startup Applications (%1)")
+ .arg(QString::number(count)));
+
+ ui->notFoundWidget->setVisible(! count);
+ ui->startupListWidget->setVisible(count);
+}
+
+void StartupAppsPage::on_addStartupAppBtn_clicked()
+{
+ StartupAppEdit::selectedFilePath = "";
+ startupAppEdit->show();
+}
diff --git a/stacer/Pages/StartupApps/startup_apps_page.h b/stacer/Pages/StartupApps/startup_apps_page.h
new file mode 100644
index 0000000..b85c145
--- /dev/null
+++ b/stacer/Pages/StartupApps/startup_apps_page.h
@@ -0,0 +1,39 @@
+#ifndef STARTUPAPPSPAGE_H
+#define STARTUPAPPSPAGE_H
+
+#include
+#include
+
+#include "startup_app.h"
+#include "startup_app_edit.h"
+
+#include
+
+namespace Ui {
+ class StartupAppsPage;
+}
+
+class StartupAppsPage : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit StartupAppsPage(QWidget *parent = 0);
+ ~StartupAppsPage();
+
+public slots:
+ void loadApps();
+
+private slots:
+ void init();
+ void on_addStartupAppBtn_clicked();
+ void setAppCount();
+
+private:
+ Ui::StartupAppsPage *ui;
+
+private:
+ StartupAppEdit *startupAppEdit;
+};
+
+#endif // STARTUPAPPSPAGE_H
diff --git a/stacer/Pages/StartupApps/startup_apps_page.ui b/stacer/Pages/StartupApps/startup_apps_page.ui
new file mode 100644
index 0000000..ddf2096
--- /dev/null
+++ b/stacer/Pages/StartupApps/startup_apps_page.ui
@@ -0,0 +1,243 @@
+
+
+ StartupAppsPage
+
+
+
+ 0
+ 0
+ 892
+ 591
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ ArrowCursor
+
+
+
+
+
+
+ 60
+
+
+ 20
+
+
+ 60
+
+
+ 30
+
+
+ 5
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Ubuntu
+
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+ Add Startup App
+
+
+
+ -
+
+
+
+ Ubuntu
+ 11
+ false
+
+
+
+
+
+
+ System Startup Applications
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 200
+
+
+
+
+ 16777215
+ 200
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ Not Found Startup Apps
+
+
+
+
+
+
+ -
+
+
+ Qt::NoFocus
+
+
+ QFrame::NoFrame
+
+
+ Qt::ScrollBarAlwaysOff
+
+
+ QAbstractItemView::EditKeyPressed
+
+
+ QAbstractItemView::NoSelection
+
+
+ QAbstractItemView::SelectRows
+
+
+ QListView::Adjust
+
+
+ QListView::Batched
+
+
+ 5
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/Pages/SystemCleaner/system_cleaner_page.cpp b/stacer/Pages/SystemCleaner/system_cleaner_page.cpp
new file mode 100644
index 0000000..d346cc1
--- /dev/null
+++ b/stacer/Pages/SystemCleaner/system_cleaner_page.cpp
@@ -0,0 +1,315 @@
+#include "system_cleaner_page.h"
+#include "ui_system_cleaner_page.h"
+
+SystemCleanerPage::~SystemCleanerPage()
+{
+ delete ui;
+ delete loadingMovie;
+ delete loadingMovie_2;
+}
+
+SystemCleanerPage::SystemCleanerPage(QWidget *parent) :
+ QWidget(parent),
+ im(InfoManager::ins()),
+ tmr(ToolManager::ins()),
+ defaultIcon(QIcon::fromTheme("application-x-executable")),
+ ui(new Ui::SystemCleanerPage)
+{
+ ui->setupUi(this);
+
+ init();
+
+ ui->stackedWidget->setCurrentIndex(0);
+}
+
+void SystemCleanerPage::init()
+{
+ // treview settings
+ ui->scanResultTreeW->setColumnCount(2);
+ ui->scanResultTreeW->setColumnWidth(0, 600);
+
+ ui->scanResultTreeW->header()->setFixedHeight(30);
+ ui->scanResultTreeW->setHeaderLabels({ tr("File Name"), tr("Size") });
+
+ // loaders
+ connect(AppManager::ins(), &AppManager::changedTheme, this, [this]() {
+ loadingMovie = new QMovie(QString(":/static/themes/%1/img/scanLoading.gif").arg(AppManager::ins()->getThemeName()));
+ ui->loading->setMovie(loadingMovie);
+ loadingMovie->start();
+ ui->loading->hide();
+
+ loadingMovie_2 = new QMovie(QString(":/static/themes/%1/img/loading.gif").arg(AppManager::ins()->getThemeName()));
+ ui->loading_2->setMovie(loadingMovie_2);
+ loadingMovie_2->start();
+ ui->loading_2->hide();
+ });
+}
+
+void SystemCleanerPage::addTreeRoot(CleanCategories cat, QString title, QFileInfoList infos, bool noChild)
+{
+ QTreeWidgetItem *root = new QTreeWidgetItem(ui->scanResultTreeW);
+ root->setData(2, 0, cat);
+ root->setData(2, 1, title);
+ if (! infos.isEmpty())
+ root->setData(3, 0, infos.at(0).absoluteDir().path());
+ root->setCheckState(0, Qt::Unchecked);
+
+ // add children
+ quint64 totalSize = 0;
+
+ if(! noChild) {
+ foreach (QFileInfo i, infos) {
+ quint64 size = FileUtil::getFileSize(i.absoluteFilePath());
+
+ addTreeChild(i.absoluteFilePath(), i.fileName(), size, root);
+
+ totalSize += size;
+ }
+
+ root->setText(0, QString("%1 (%2)")
+ .arg(title)
+ .arg(infos.count()));
+
+ } else {
+ if (! infos.isEmpty())
+ totalSize += FileUtil::getFileSize(infos.first().absoluteFilePath());
+
+ root->setText(0, QString("%1")
+ .arg(title));
+ }
+
+ root->setText(1, QString("%1").arg(FormatUtil::formatBytes(totalSize)));
+}
+
+void SystemCleanerPage::addTreeChild(QString data, QString text, quint64 size, QTreeWidgetItem *parent)
+{
+ QTreeWidgetItem *item = new QTreeWidgetItem(parent);
+ item->setIcon(0, QIcon::fromTheme(text, defaultIcon));
+ item->setText(0, text);
+ item->setText(1, FormatUtil::formatBytes(size));
+ item->setData(2, 0, data);
+ item->setCheckState(0, Qt::Unchecked);
+}
+
+void SystemCleanerPage::addTreeChild(CleanCategories cat, QString text, quint64 size)
+{
+ QTreeWidgetItem *item = new QTreeWidgetItem(ui->scanResultTreeW);
+ item->setText(0, text);
+ item->setText(1, FormatUtil::formatBytes(size));
+ item->setData(2, 0, cat);
+ item->setCheckState(0, Qt::Unchecked);
+}
+
+void SystemCleanerPage::on_scanResultTreeW_itemClicked(QTreeWidgetItem *item, int column)
+{
+ if(column == 0) {
+ // new check state
+ Qt::CheckState cs = (item->checkState(column) == Qt::Checked ? Qt::Unchecked : Qt::Checked);
+
+ // update check state
+ item->setCheckState(column, cs);
+
+ // change check state if has children
+ for (int i = 0; i < item->childCount(); ++i)
+ item->child(i)->setCheckState(column, cs);
+ }
+}
+
+void SystemCleanerPage::systemScan()
+{
+ if (ui->packageCacheCheck->isChecked() ||
+ ui->crashReportsCheck->isChecked() ||
+ ui->logCheck->isChecked() ||
+ ui->appCacheCheck->isChecked() ||
+ ui->trashCheck->isChecked()
+ ){
+ ui->scanBtn->hide();
+ ui->loading->show();
+ ui->packageCacheCheck->setEnabled(false);
+ ui->crashReportsCheck->setEnabled(false);
+ ui->logCheck->setEnabled(false);
+ ui->appCacheCheck->setEnabled(false);
+ ui->trashCheck->setEnabled(false);
+
+ QThread::sleep(1);
+
+ ui->scanResultTreeW->clear();
+
+ // Package Caches
+ if (ui->packageCacheCheck->isChecked()) {
+ addTreeRoot(PACKAGE_CACHE,
+ ui->packageCacheLabel->text(),
+ tmr->getPackageCaches());
+ }
+
+ // Crash Reports
+ if (ui->crashReportsCheck->isChecked()) {
+ addTreeRoot(CRASH_REPORTS,
+ ui->crashReportsLabel->text(),
+ im->getCrashReports());
+ }
+
+ // Application Logs
+ if (ui->logCheck->isChecked()) {
+ addTreeRoot(APPLICATION_LOGS,
+ ui->logLabel->text(),
+ im->getAppLogs());
+ }
+
+ // Application Cache
+ if (ui->appCacheCheck->isChecked()) {
+ addTreeRoot(APPLICATION_CACHES,
+ ui->appCacheLabel->text(),
+ im->getAppCaches());
+ }
+
+ // Trash
+ if(ui->trashCheck->isChecked()) {
+ addTreeRoot(TRASH,
+ ui->trashLabel->text(),
+ { QFileInfo("/home/oguzhan/.local/share/Trash/") },
+ true);
+ }
+
+ // scan results page
+ ui->stackedWidget->setCurrentIndex(1);
+
+ ui->packageCacheCheck->setChecked(false);
+ ui->crashReportsCheck->setChecked(false);
+ ui->logCheck->setChecked(false);
+ ui->appCacheCheck->setChecked(false);
+ ui->trashCheck->setChecked(false);
+ }
+}
+
+bool SystemCleanerPage::cleanValid()
+{
+ for (int i = 0; i < ui->scanResultTreeW->topLevelItemCount(); ++i) {
+
+ QTreeWidgetItem *it = ui->scanResultTreeW->topLevelItem(i);
+
+ if (it->checkState(0) == Qt::Checked)
+ return true;
+
+ for (int j = 0; j < it->childCount(); ++j)
+ if (it->child(j)->checkState(0) == Qt::Checked)
+ return true;
+ }
+
+ return false;
+}
+
+void SystemCleanerPage::systemClean()
+{
+ if (cleanValid())
+ {
+ ui->cleanBtn->hide();
+ ui->loading_2->show();
+ ui->scanResultTreeW->setEnabled(false);
+
+ quint64 totalCleanedSize = 0;
+
+ QTreeWidget *tree = ui->scanResultTreeW;
+
+ QStringList filesToDelete;
+
+ QList children;
+
+ for (int i = 0; i < tree->topLevelItemCount(); ++i) {
+
+ QTreeWidgetItem *it = tree->topLevelItem(i);
+
+ CleanCategories cat = (CleanCategories) it->data(2, 0).toInt();
+
+ // Package Caches | Crash Reports | Application Logs | Application Caches
+ if (cat != CleanCategories::TRASH) {
+
+ for (int j = 0; j < it->childCount(); ++j) { // files
+
+ if(it->child(j)->checkState(0) == Qt::Checked) { // if checked
+
+ QString filePath = it->child(j)->data(2, 0).toString();
+
+ filesToDelete << filePath;
+
+ children.append(it->child(j));
+ }
+ }
+ }
+
+ // Trash
+ else if (cat == CleanCategories::TRASH) {
+
+ if (it->checkState(0) == Qt::Checked) {
+
+ QString homePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
+
+ QDir(homePath + "/.local/share/Trash/files").removeRecursively();
+ QDir(homePath + "/.local/share/Trash/info").removeRecursively();
+ }
+ }
+ }
+
+ // get removed files total size
+ foreach (QString file, filesToDelete) {
+ totalCleanedSize += FileUtil::getFileSize(file);
+ }
+
+ // remove selected files
+ if(! filesToDelete.isEmpty()) {
+ CommandUtil::sudoExec("rm", QStringList() << "-rf" << filesToDelete);
+ }
+
+ QThread::sleep(1);
+
+ for (int i = 0; i < tree->topLevelItemCount(); ++i) {
+ // clear removed childs
+ foreach (QTreeWidgetItem *item, children) {
+ tree->topLevelItem(i)->removeChild(item);
+ }
+ }
+
+ // update titles
+ for (int i = 0; i < tree->topLevelItemCount(); ++i) {
+
+ QTreeWidgetItem *it = tree->topLevelItem(i);
+
+ it->setText(0, QString("%1 (%2)")
+ .arg(it->data(2, 1).toString())
+ .arg(it->childCount()));
+
+ it->setText(1, QString("%1")
+ .arg(FormatUtil::formatBytes(FileUtil::getFileSize(it->data(3, 0).toString()))));
+ }
+
+ ui->removedTotalSizeLbl->setText(tr("%1 size files cleaned.")
+ .arg(FormatUtil::formatBytes(totalCleanedSize)));
+
+ ui->cleanBtn->show();
+ ui->loading_2->hide();
+ ui->scanResultTreeW->setEnabled(true);
+ }
+}
+
+void SystemCleanerPage::on_scanBtn_clicked()
+{
+ QtConcurrent::run(this, &SystemCleanerPage::systemScan);
+}
+
+void SystemCleanerPage::on_cleanBtn_clicked()
+{
+ QtConcurrent::run(this, &SystemCleanerPage::systemClean);
+}
+
+void SystemCleanerPage::on_backButtton_clicked()
+{
+ ui->scanBtn->show();
+ ui->loading->hide();
+ ui->packageCacheCheck->setEnabled(true);
+ ui->crashReportsCheck->setEnabled(true);
+ ui->logCheck->setEnabled(true);
+ ui->appCacheCheck->setEnabled(true);
+ ui->trashCheck->setEnabled(true);
+ ui->scanResultTreeW->clear();
+ ui->stackedWidget->setCurrentIndex(0);
+}
diff --git a/stacer/Pages/SystemCleaner/system_cleaner_page.h b/stacer/Pages/SystemCleaner/system_cleaner_page.h
new file mode 100644
index 0000000..0102e69
--- /dev/null
+++ b/stacer/Pages/SystemCleaner/system_cleaner_page.h
@@ -0,0 +1,64 @@
+#ifndef SYSTEMCLEANERPAGE_H
+#define SYSTEMCLEANERPAGE_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "Managers/app_manager.h"
+
+#include
+#include
+
+namespace Ui {
+ class SystemCleanerPage;
+}
+
+class SystemCleanerPage : public QWidget
+{
+ Q_OBJECT
+
+public:
+ enum CleanCategories {
+ PACKAGE_CACHE,
+ CRASH_REPORTS,
+ APPLICATION_LOGS,
+ APPLICATION_CACHES,
+ TRASH
+ };
+
+public:
+ explicit SystemCleanerPage(QWidget *parent = 0);
+ ~SystemCleanerPage();
+
+private slots:
+ void init();
+ void addTreeRoot(CleanCategories cat, QString title, QFileInfoList infos, bool noChild = false);
+ void addTreeChild(CleanCategories cat, QString text, quint64 size);
+ void addTreeChild(QString data, QString text, quint64 size, QTreeWidgetItem *parent);
+
+ void on_scanResultTreeW_itemClicked(QTreeWidgetItem *item, int column);
+ void on_cleanBtn_clicked();
+ void on_scanBtn_clicked();
+ void on_backButtton_clicked();
+
+ void systemScan();
+ void systemClean();
+ bool cleanValid();
+
+private:
+ Ui::SystemCleanerPage *ui;
+
+private:
+ InfoManager *im;
+ ToolManager *tmr;
+
+ QIcon defaultIcon;
+ QMovie *loadingMovie;
+ QMovie *loadingMovie_2;
+};
+
+#endif // SYSTEMCLEANERPAGE_H
diff --git a/stacer/Pages/SystemCleaner/system_cleaner_page.ui b/stacer/Pages/SystemCleaner/system_cleaner_page.ui
new file mode 100644
index 0000000..05fda31
--- /dev/null
+++ b/stacer/Pages/SystemCleaner/system_cleaner_page.ui
@@ -0,0 +1,636 @@
+
+
+ SystemCleanerPage
+
+
+
+ 0
+ 0
+ 784
+ 507
+
+
+
+
+
+
+
+ 0
+
+
+ 15
+
+
+ 0
+
+
+ 15
+
+
+ 15
+
+ -
+
+
+
+
+
+ 1
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 40
+
+
+ 20
+
+ -
+
+
+ Crash Reports
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
+ -
+
+
+
+ 90
+ 90
+
+
+
+
+ 90
+ 90
+
+
+
+
+
+
+ :/static/themes/default/img/c_crash.png
+
+
+ false
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 0
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 90
+ 90
+
+
+
+
+ 90
+ 90
+
+
+
+
+
+
+ :/static/themes/default/img/c_cache.png
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ Application Logs
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
+ -
+
+
+
+ 90
+ 90
+
+
+
+
+ 90
+ 90
+
+
+
+
+
+
+ :/static/themes/default/img/c_trash.png
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ Application Caches
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
+ -
+
+
+
+ 90
+ 90
+
+
+
+
+ 90
+ 90
+
+
+
+ Qt::AutoText
+
+
+ :/static/themes/default/img/c_package.png
+
+
+ false
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+
+ -
+
+
+
+ 100
+ 100
+
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+
+ 100
+ 100
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 30
+
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+
+ -
+
+
+ Trash
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
+ -
+
+
+
+ 90
+ 90
+
+
+
+
+ 90
+ 90
+
+
+
+
+
+
+ :/static/themes/default/img/c_logs.png
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ Package Caches
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 100
+
+
+
+
+ -
+
+
+
+ 100
+ 100
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 5
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 10
+
+ -
+
+
+ PointingHandCursor
+
+
+ Back
+
+
+
+ :/static/themes/default/img/back.svg :/static/themes/default/img/back.svg
+
+
+
+ 20
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ PreferAntialias
+
+
+
+ ArrowCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+ QAbstractItemView::NoSelection
+
+
+ Qt::ElideMiddle
+
+
+ QAbstractItemView::ScrollPerItem
+
+
+ true
+
+
+ true
+
+
+
+ 1
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 100
+ 100
+
+
+
+
+ 100
+ 100
+
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 20
+ 0
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 100
+ 20
+
+
+
+
+ 16777215
+ 20
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/Pages/Uninstaller/uninstaller_page.cpp b/stacer/Pages/Uninstaller/uninstaller_page.cpp
new file mode 100644
index 0000000..c66deed
--- /dev/null
+++ b/stacer/Pages/Uninstaller/uninstaller_page.cpp
@@ -0,0 +1,120 @@
+#include "uninstaller_page.h"
+#include "ui_uninstallerpage.h"
+
+UninstallerPage::~UninstallerPage()
+{
+ delete ui;
+ delete loadingMovie;
+}
+
+UninstallerPage::UninstallerPage(QWidget *parent) :
+ QWidget(parent),
+ tm(ToolManager::ins()),
+ icon(QIcon(QString(":/static/themes/%1/img/package.svg").arg(AppManager::ins()->getThemeName()))),
+ loadingMovie(new QMovie(QString(":/static/themes/%1/img/loading.gif").arg(AppManager::ins()->getThemeName()))),
+ ui(new Ui::UninstallerPage)
+{
+ ui->setupUi(this);
+
+ init();
+}
+
+void UninstallerPage::init()
+{
+ ui->loading->setMovie(loadingMovie);
+ loadingMovie->start();
+ ui->loading->hide();
+ ui->notFoundWidget->hide();
+
+ QtConcurrent::run(this, &UninstallerPage::loadPackages);
+
+ connect(tm, &ToolManager::uninstallFinished, this, &UninstallerPage::loadPackages);
+ connect(tm, &ToolManager::uninstallStarted, this, &UninstallerPage::uninstallStarted);
+}
+
+void UninstallerPage::loadPackages()
+{
+ uninstallStarted();
+
+ // clear items
+ ui->packagesList->clear();
+
+ foreach (QString package, tm->getPackages())
+ {
+ QListWidgetItem *item = new QListWidgetItem(QIcon::fromTheme(package, icon), QString(" %1").arg(package));
+
+ item->setCheckState(Qt::Unchecked);
+
+ ui->packagesList->addItem(item);
+ }
+ setAppCount();
+
+ ui->packagesList->setEnabled(true);
+ ui->packageSearch->setEnabled(true);
+ ui->uninstallBtn->show();
+ ui->packageSearch->clear();
+
+ ui->loading->hide();
+}
+
+void UninstallerPage::setAppCount()
+{
+ int count = ui->packagesList->count();
+
+ ui->packagesTitle->setText(
+ tr("System Installed Packages (%1)")
+ .arg(QString::number(count)));
+
+ ui->notFoundWidget->setVisible(! count);
+ ui->packagesList->setVisible(count);
+}
+
+QStringList UninstallerPage::getSelectedPackages()
+{
+ QStringList selectedPackages = {};
+
+ for (int i = 0; i < ui->packagesList->count(); i++)
+ {
+ QListWidgetItem *item = ui->packagesList->item(i);
+
+ if(item->checkState() == Qt::Checked)
+ selectedPackages << item->text().trimmed();
+ }
+
+ return selectedPackages;
+}
+
+void UninstallerPage::on_uninstallBtn_clicked()
+{
+ QStringList selectedPackages = getSelectedPackages();
+
+ if(! selectedPackages.isEmpty())
+ {
+ QtConcurrent::run([selectedPackages]() -> void {
+ ToolManager::ins()->uninstallPackages(selectedPackages);
+ });
+ }
+}
+
+void UninstallerPage::uninstallStarted()
+{
+ ui->packagesList->setEnabled(false);
+ ui->packageSearch->setEnabled(false);
+ ui->uninstallBtn->hide();
+
+ ui->loading->show();
+}
+
+void UninstallerPage::on_packageSearch_textChanged(const QString &val)
+{
+ // Get matches items
+ QList matches = ui->packagesList->findItems(val, Qt::MatchFlag::MatchContains);
+
+ // All items hide
+ for (int i = 0; i < ui->packagesList->count(); ++i)
+ ui->packagesList->item(i)->setHidden(true);
+
+ // Matches items show
+ foreach (QListWidgetItem* item, matches)
+ item->setHidden(false);
+}
diff --git a/stacer/Pages/Uninstaller/uninstaller_page.h b/stacer/Pages/Uninstaller/uninstaller_page.h
new file mode 100644
index 0000000..d35f171
--- /dev/null
+++ b/stacer/Pages/Uninstaller/uninstaller_page.h
@@ -0,0 +1,44 @@
+#ifndef UNINSTALLERPAGE_H
+#define UNINSTALLERPAGE_H
+
+#include
+#include
+#include
+#include
+
+#include "Managers/tool_manager.h"
+#include "Managers/app_manager.h"
+
+namespace Ui {
+ class UninstallerPage;
+}
+
+class UninstallerPage : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit UninstallerPage(QWidget *parent = 0);
+ ~UninstallerPage();
+
+public slots:
+ void uninstallStarted();
+private slots:
+ void init();
+ void setAppCount();
+
+ void on_packageSearch_textChanged(const QString &val);
+ void on_uninstallBtn_clicked();
+ QStringList getSelectedPackages();
+ void loadPackages();
+
+private:
+ Ui::UninstallerPage *ui;
+
+private:
+ ToolManager *tm;
+ QIcon icon;
+ QMovie *loadingMovie;
+};
+
+#endif // UNINSTALLERPAGE_H
diff --git a/stacer/Pages/Uninstaller/uninstallerpage.ui b/stacer/Pages/Uninstaller/uninstallerpage.ui
new file mode 100644
index 0000000..1f741dc
--- /dev/null
+++ b/stacer/Pages/Uninstaller/uninstallerpage.ui
@@ -0,0 +1,292 @@
+
+
+ UninstallerPage
+
+
+
+ 0
+ 0
+ 916
+ 553
+
+
+
+
+
+
+
+ 0
+
+
+ 10
+
+
+ 10
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+
+
+
+ 30
+
+
+ 0
+
+
+ 30
+
+
+ 20
+
+
+ 5
+
+ -
+
+
+
+ Ubuntu
+ 10
+
+
+
+ Qt::NoFocus
+
+
+
+
+
+ 10
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+ QAbstractItemView::NoSelection
+
+
+ QAbstractItemView::SelectRows
+
+
+
+ 20
+ 20
+
+
+
+ Qt::ElideMiddle
+
+
+ 4
+
+
+ false
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 10
+
+
+
+
+ -
+
+
+ true
+
+
+
+ Ubuntu
+
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+ Uninstall Selected
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 200
+
+
+
+
+ 16777215
+ 200
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ Not Found Installed Packages
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 5
+
+
+ 15
+
+
+ 0
+
+
+ 20
+
+
+ 0
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Ubuntu
+ 11
+ false
+
+
+
+
+
+
+ System Installed Packages
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 170
+ 0
+
+
+
+
+ 170
+ 16777215
+
+
+
+
+ 10
+
+
+
+ Qt::StrongFocus
+
+
+
+
+
+ Search...
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/app.cpp b/stacer/app.cpp
new file mode 100644
index 0000000..4f7d2d4
--- /dev/null
+++ b/stacer/app.cpp
@@ -0,0 +1,116 @@
+#include "app.h"
+#include "ui_app.h"
+
+App::~App()
+{
+ delete ui;
+ delete dashboardPage;
+ delete startupAppsPage;
+ delete systemCleanerPage;
+ delete servicesPage;
+ delete processPage;
+ delete uninstallerPage;
+ delete resourcesPage;
+ delete settingsPage;
+}
+
+App::App(QWidget *parent) :
+ QMainWindow(parent),
+ apm(AppManager::ins()),
+ dashboardPage(new DashboardPage),
+ startupAppsPage(new StartupAppsPage),
+ systemCleanerPage(new SystemCleanerPage),
+ servicesPage(new ServicesPage),
+ processPage(new ProcessesPage),
+ uninstallerPage(new UninstallerPage),
+ resourcesPage(new ResourcesPage),
+ settingsPage(new SettingsPage),
+ ui(new Ui::App)
+{
+ ui->setupUi(this);
+
+ init();
+}
+
+void App::init()
+{
+ setGeometry(
+ QStyle::alignedRect(
+ Qt::LeftToRight,
+ Qt::AlignCenter,
+ size(),
+ qApp->desktop()->availableGeometry())
+ );
+
+ // form settings
+ ui->horizontalLayout->setContentsMargins(0,0,0,0);
+ ui->horizontalLayout->setSpacing(0);
+
+ // icon sizes of the buttons on the sidebar 30x30
+ foreach (QPushButton *btn, ui->sidebar->findChildren())
+ btn->setIconSize(QSize(26, 26));
+
+ // add pages
+ ui->pageStacked->addWidget(dashboardPage);
+ ui->pageStacked->addWidget(startupAppsPage);
+ ui->pageStacked->addWidget(systemCleanerPage);
+ ui->pageStacked->addWidget(servicesPage);
+ ui->pageStacked->addWidget(processPage);
+ ui->pageStacked->addWidget(uninstallerPage);
+ ui->pageStacked->addWidget(resourcesPage);
+ ui->pageStacked->addWidget(settingsPage);
+
+ on_dashBtn_clicked();
+}
+
+void App::pageClick(QPushButton *btn, QWidget *w, QString title)
+{
+ // all button checked false
+ foreach (QPushButton *b, ui->sidebar->findChildren())
+ b->setChecked(false);
+ btn->setChecked(true); // clicked button set active style
+ apm->updateStylesheet(); // update style
+
+ ui->pageTitle->setText(title);
+ ui->pageStacked->setCurrentWidget(w);
+}
+
+void App::on_dashBtn_clicked()
+{
+ pageClick(ui->dashBtn, dashboardPage, tr("Dashboard"));
+}
+
+void App::on_systemCleanerBtn_clicked()
+{
+ pageClick(ui->systemCleanerBtn, systemCleanerPage, tr("System Cleaner"));
+}
+
+void App::on_startupAppsBtn_clicked()
+{
+ pageClick(ui->startupAppsBtn, startupAppsPage, tr("System Startup Apps"));
+}
+
+void App::on_servicesBtn_clicked()
+{
+ pageClick(ui->servicesBtn, servicesPage, tr("System Services"));
+}
+
+void App::on_uninstallerBtn_clicked()
+{
+ pageClick(ui->uninstallerBtn, uninstallerPage, tr("Uninstaller"));
+}
+
+void App::on_resourcesBtn_clicked()
+{
+ pageClick(ui->resourcesBtn, resourcesPage, tr("Resources"));
+}
+
+void App::on_processesBtn_clicked()
+{
+ pageClick(ui->processesBtn, processPage, tr("Processes"));
+}
+
+void App::on_settingsBtn_clicked()
+{
+ pageClick(ui->settingsBtn, settingsPage, tr("Settings"));
+}
diff --git a/stacer/app.h b/stacer/app.h
new file mode 100644
index 0000000..4f25f36
--- /dev/null
+++ b/stacer/app.h
@@ -0,0 +1,62 @@
+#ifndef APP_H
+#define APP_H
+
+#include
+
+// Pages
+#include "Pages/Dashboard/dashboard_page.h"
+#include "Pages/StartupApps/startup_apps_page.h"
+#include "Pages/SystemCleaner/system_cleaner_page.h"
+#include "Pages/Services/services_page.h"
+#include "Pages/Processes/processes_page.h"
+#include "Pages/Uninstaller/uninstaller_page.h"
+#include "Pages/Resources/resources_page.h"
+#include "Pages/Settings/settings_page.h"
+
+#include "Managers/app_manager.h"
+
+namespace Ui {
+ class App;
+}
+
+class App : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit App(QWidget *parent = 0);
+ ~App();
+
+public:
+
+private slots:
+ void init();
+ void pageClick(QPushButton *btn, QWidget *w, QString title);
+
+ void on_dashBtn_clicked();
+ void on_systemCleanerBtn_clicked();
+ void on_startupAppsBtn_clicked();
+ void on_servicesBtn_clicked();
+ void on_uninstallerBtn_clicked();
+ void on_resourcesBtn_clicked();
+ void on_processesBtn_clicked();
+ void on_settingsBtn_clicked();
+
+private:
+ Ui::App *ui;
+
+private:
+ // Pages
+ DashboardPage *dashboardPage;
+ StartupAppsPage *startupAppsPage;
+ SystemCleanerPage *systemCleanerPage;
+ ServicesPage *servicesPage;
+ ProcessesPage *processPage;
+ UninstallerPage *uninstallerPage;
+ ResourcesPage *resourcesPage;
+ SettingsPage *settingsPage;
+
+ AppManager *apm;
+};
+
+#endif // APP_H
diff --git a/stacer/app.ui b/stacer/app.ui
new file mode 100644
index 0000000..f6646e6
--- /dev/null
+++ b/stacer/app.ui
@@ -0,0 +1,322 @@
+
+
+ App
+
+
+ Qt::NonModal
+
+
+
+ 0
+ 0
+ 850
+ 550
+
+
+
+ Stacer
+
+
+
+ :/static/icons/icon256x256.png :/static/icons/icon256x256.png
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 60
+ 0
+
+
+
+
+ 60
+ 16777215
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+ PointingHandCursor
+
+
+ Qt::NoFocus
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+ dashBtn
+ servicesBtn
+ uninstallerBtn
+ startupAppsBtn
+ resourcesBtn
+ verticalSpacer_2
+ systemCleanerBtn
+ processesBtn
+ settingsBtn
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Ubuntu
+ 12
+
+
+
+
+
+
+ Title
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+
+
+ pageContent
+ sidebar
+
+
+
+
+
+
+
diff --git a/stacer/main.cpp b/stacer/main.cpp
new file mode 100644
index 0000000..f8bce29
--- /dev/null
+++ b/stacer/main.cpp
@@ -0,0 +1,72 @@
+#include
+#include
+#include "app.h"
+
+void messageHandler(QtMsgType type,
+ const QMessageLogContext &context,
+ const QString &message)
+{
+ QString level;
+
+ switch (type) {
+ case QtDebugMsg:
+ level = "DEBUG"; break;
+ case QtInfoMsg:
+ level = "INFO"; break;
+ case QtWarningMsg:
+ level = "WARNING"; break;
+ case QtCriticalMsg:
+ level = "CRITICAL"; break;
+ case QtFatalMsg:
+ level = "FATAL"; break;
+ default:
+ level = "UNDEFIEND"; break;
+ }
+
+ if (type != QtWarningMsg) {
+
+ QString text = QString("[%1] [%2] %3")
+ .arg(QDateTime::currentDateTime().toString("dd-MM-yyyy hh:mm:ss"))
+ .arg(level)
+ .arg(message);
+
+ static QString logPath = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/log";
+
+ QDir().mkdir(logPath);
+
+ QFile file(logPath + "/stacer.log");
+
+ QIODevice::OpenMode openMode;
+
+ if (file.size() > (1L << 20))
+ openMode = QIODevice::WriteOnly | QIODevice::Truncate;
+ else
+ openMode = QIODevice::WriteOnly | QIODevice::Append;
+
+ if (file.open(openMode)) {
+ QTextStream stream(&file);
+ stream << text << endl;
+
+ file.close();
+ }
+ }
+}
+
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ qApp->setApplicationName("stacer");
+ qApp->setApplicationDisplayName("Stacer");
+ qApp->setApplicationVersion("1.0.8");
+ qApp->setWindowIcon(QIcon(":/static/logo.png"));
+
+ qInstallMessageHandler(messageHandler);
+
+ App w;
+
+ w.show();
+
+ return app.exec();
+}
diff --git a/stacer/stacer.pro b/stacer/stacer.pro
new file mode 100644
index 0000000..72896b2
--- /dev/null
+++ b/stacer/stacer.pro
@@ -0,0 +1,100 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2017-07-02T15:41:12
+#
+#-------------------------------------------------
+
+QT += core gui charts svg concurrent
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = stacer
+TEMPLATE = app
+
+CONFIG += c++11
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which as been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+ main.cpp \
+ app.cpp \
+ Pages/Dashboard/circlebar.cpp \
+ Pages/Dashboard/linebar.cpp \
+ Managers/info_manager.cpp \
+ Pages/StartupApps/startup_app.cpp \
+ Pages/StartupApps/startup_app_edit.cpp \
+ Pages/StartupApps/startup_apps_page.cpp \
+ Pages/Services/service_item.cpp \
+ Managers/tool_manager.cpp \
+ Pages/Resources/history_chart.cpp \
+ Pages/SystemCleaner/system_cleaner_page.cpp \
+ Pages/Uninstaller/uninstaller_page.cpp \
+ Pages/Services/services_page.cpp \
+ Pages/Resources/resources_page.cpp \
+ Pages/Dashboard/dashboard_page.cpp \
+ Pages/Processes/processes_page.cpp \
+ Pages/Settings/settings_page.cpp \
+ Managers/app_manager.cpp
+
+HEADERS += \
+ app.h \
+ Pages/Dashboard/circlebar.h \
+ Pages/Dashboard/linebar.h \
+ Managers/info_manager.h \
+ Pages/StartupApps/startup_app.h \
+ Pages/StartupApps/startup_app_edit.h \
+ Pages/StartupApps/startup_apps_page.h \
+ Pages/Services/service_item.h \
+ Managers/tool_manager.h \
+ Pages/Resources/history_chart.h \
+ Pages/SystemCleaner/system_cleaner_page.h \
+ Pages/Uninstaller/uninstaller_page.h \
+ Pages/Resources/resources_page.h \
+ Pages/Processes/processes_page.h \
+ Pages/Dashboard/dashboard_page.h \
+ Pages/Services/services_page.h \
+ Pages/Settings/settings_page.h \
+ Managers/app_manager.h
+
+FORMS += \
+ app.ui \
+ Pages/Uninstaller/uninstallerpage.ui \
+ Pages/Dashboard/circlebar.ui \
+ Pages/Dashboard/linebar.ui \
+ Pages/StartupApps/startup_app.ui \
+ Pages/StartupApps/startup_app_edit.ui \
+ Pages/StartupApps/startup_apps_page.ui \
+ Pages/Services/service_item.ui \
+ Pages/Resources/history_chart.ui \
+ Pages/SystemCleaner/system_cleaner_page.ui \
+ Pages/Dashboard/dashboard_page.ui \
+ Pages/Processes/processes_page.ui \
+ Pages/Resources/resources_page.ui \
+ Pages/Services/services_page.ui \
+ Pages/Settings/settings_page.ui
+
+TRANSLATIONS += \
+ ../translations/stacer_en.ts \
+ ../translations/stacer_es.ts \
+ ../translations/stacer_fr.ts \
+ ../translations/stacer_pt.ts \
+ ../translations/stacer_sv.ts \
+ ../translations/stacer_tr.ts \
+ ../translations/stacer_hi.ts
+
+RESOURCES += \
+ static.qrc
+
+unix:!macx: LIBS += -L$$OUT_PWD/../stacer-core/ -lstacer-core
+
+INCLUDEPATH += $$PWD/../stacer-core
+DEPENDPATH += $$PWD/../stacer-core
diff --git a/stacer/static.qrc b/stacer/static.qrc
new file mode 100644
index 0000000..7dca82f
--- /dev/null
+++ b/stacer/static.qrc
@@ -0,0 +1,63 @@
+
+
+ static/themes/default/style/style.qss
+ static/themes/default/img/sidebar-icons/dash.png
+ static/themes/default/img/sidebar-icons/cleaner.svg
+ static/themes/default/img/sidebar-icons/process.png
+ static/themes/default/img/sidebar-icons/resources.png
+ static/themes/default/img/sidebar-icons/services.svg
+ static/themes/default/img/sidebar-icons/startup-apps.svg
+ static/themes/default/img/sidebar-icons/uninstaller.png
+ static/themes/default/img/checkbox.svg
+ static/themes/default/img/un-checkbox.svg
+ static/themes/default/img/app.svg
+ static/themes/default/img/trash.svg
+ static/themes/default/img/not-found.svg
+ static/themes/default/img/edit.svg
+ static/themes/default/img/service.svg
+ static/themes/default/img/package.svg
+ static/themes/default/img/search.svg
+ static/themes/default/img/check.svg
+ static/themes/default/img/un-check.svg
+ static/themes/default/img/loading.gif
+ static/themes/default/img/scanLoading.gif
+ static/themes/default/img/refresh.svg
+ static/themes/default/img/asc.svg
+ static/themes/default/img/dsc.svg
+ static/themes/default/img/c_package.png
+ static/themes/default/img/c_crash.png
+ static/themes/default/img/c_logs.png
+ static/themes/default/img/c_cache.png
+ static/themes/default/img/c_trash.png
+ static/themes/default/img/fit.svg
+ static/themes/default/img/collapse.svg
+ static/themes/default/img/scan.svg
+ static/themes/default/img/scan-active.svg
+ static/themes/default/img/clean.svg
+ static/themes/default/img/clean-active.svg
+ static/themes/default/img/down-arrow.svg
+ static/themes/default/img/right-arrow.svg
+ static/themes/default/img/back.svg
+ static/font/Ubuntu-R.ttf
+ static/themes/default/img/sidebar-icons/settings.svg
+ static/languages.json
+ static/themes.json
+ static/themes/light/style/style.qss
+ static/themes/light/img/app.svg
+ static/themes/light/img/clean-active.svg
+ static/themes/light/img/clean.svg
+ static/themes/light/img/down-arrow.svg
+ static/themes/light/img/edit.svg
+ static/themes/light/img/right-arrow.svg
+ static/themes/light/img/scan-active.svg
+ static/themes/light/img/scan.svg
+ static/themes/light/img/scanLoading.gif
+ static/themes/light/img/loading.gif
+ static/themes/light/img/package.svg
+ static/themes/light/style/values.ini
+ static/themes/default/style/values.ini
+ static/logo.png
+ static/themes/default/img/run.svg
+ static/themes/default/img/power.svg
+
+
diff --git a/stacer/static/font/Ubuntu-R.ttf b/stacer/static/font/Ubuntu-R.ttf
new file mode 100644
index 0000000..d748728
Binary files /dev/null and b/stacer/static/font/Ubuntu-R.ttf differ
diff --git a/stacer/static/languages.json b/stacer/static/languages.json
new file mode 100644
index 0000000..5853c1c
--- /dev/null
+++ b/stacer/static/languages.json
@@ -0,0 +1,9 @@
+[
+ {"value" : "en", "text": "English"},
+ {"value" : "es", "text": "Español"},
+ {"value" : "fr", "text": "Français"},
+ {"value" : "hi", "text": "हिंदी"},
+ {"value" : "pt", "text": "Português"},
+ {"value" : "sv", "text": "Svenska"},
+ {"value" : "tr", "text": "Türkçe"}
+]
diff --git a/stacer/static/logo.png b/stacer/static/logo.png
new file mode 100644
index 0000000..716367c
Binary files /dev/null and b/stacer/static/logo.png differ
diff --git a/stacer/static/themes.json b/stacer/static/themes.json
new file mode 100644
index 0000000..14f82c4
--- /dev/null
+++ b/stacer/static/themes.json
@@ -0,0 +1,4 @@
+[
+ {"value" : "default", "text": "Default"},
+ {"value" : "light", "text": "Light"}
+]
diff --git a/stacer/static/themes/default/img/app.svg b/stacer/static/themes/default/img/app.svg
new file mode 100644
index 0000000..c38c9fd
--- /dev/null
+++ b/stacer/static/themes/default/img/app.svg
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/img/asc.svg b/stacer/static/themes/default/img/asc.svg
new file mode 100644
index 0000000..5a2d3af
--- /dev/null
+++ b/stacer/static/themes/default/img/asc.svg
@@ -0,0 +1,55 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/img/back.svg b/stacer/static/themes/default/img/back.svg
new file mode 100644
index 0000000..ef2b269
--- /dev/null
+++ b/stacer/static/themes/default/img/back.svg
@@ -0,0 +1,44 @@
+
+image/svg+xml
\ No newline at end of file
diff --git a/stacer/static/themes/default/img/c_cache.png b/stacer/static/themes/default/img/c_cache.png
new file mode 100644
index 0000000..bbda8b2
Binary files /dev/null and b/stacer/static/themes/default/img/c_cache.png differ
diff --git a/stacer/static/themes/default/img/c_crash.png b/stacer/static/themes/default/img/c_crash.png
new file mode 100644
index 0000000..beb7d1f
Binary files /dev/null and b/stacer/static/themes/default/img/c_crash.png differ
diff --git a/stacer/static/themes/default/img/c_logs.png b/stacer/static/themes/default/img/c_logs.png
new file mode 100644
index 0000000..8a936b0
Binary files /dev/null and b/stacer/static/themes/default/img/c_logs.png differ
diff --git a/stacer/static/themes/default/img/c_package.png b/stacer/static/themes/default/img/c_package.png
new file mode 100644
index 0000000..be079a0
Binary files /dev/null and b/stacer/static/themes/default/img/c_package.png differ
diff --git a/stacer/static/themes/default/img/c_trash.png b/stacer/static/themes/default/img/c_trash.png
new file mode 100644
index 0000000..2169cb1
Binary files /dev/null and b/stacer/static/themes/default/img/c_trash.png differ
diff --git a/stacer/static/themes/default/img/check.svg b/stacer/static/themes/default/img/check.svg
new file mode 100644
index 0000000..2bacc01
--- /dev/null
+++ b/stacer/static/themes/default/img/check.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/stacer/static/themes/default/img/checkbox.svg b/stacer/static/themes/default/img/checkbox.svg
new file mode 100644
index 0000000..7f83de2
--- /dev/null
+++ b/stacer/static/themes/default/img/checkbox.svg
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/img/clean-active.svg b/stacer/static/themes/default/img/clean-active.svg
new file mode 100644
index 0000000..c771dd5
--- /dev/null
+++ b/stacer/static/themes/default/img/clean-active.svg
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/img/clean.svg b/stacer/static/themes/default/img/clean.svg
new file mode 100644
index 0000000..8571e03
--- /dev/null
+++ b/stacer/static/themes/default/img/clean.svg
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/img/collapse.svg b/stacer/static/themes/default/img/collapse.svg
new file mode 100644
index 0000000..0abdd21
--- /dev/null
+++ b/stacer/static/themes/default/img/collapse.svg
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/img/down-arrow.svg b/stacer/static/themes/default/img/down-arrow.svg
new file mode 100644
index 0000000..53e42d8
--- /dev/null
+++ b/stacer/static/themes/default/img/down-arrow.svg
@@ -0,0 +1,45 @@
+
+image/svg+xml
\ No newline at end of file
diff --git a/stacer/static/themes/default/img/dsc.svg b/stacer/static/themes/default/img/dsc.svg
new file mode 100644
index 0000000..9b247eb
--- /dev/null
+++ b/stacer/static/themes/default/img/dsc.svg
@@ -0,0 +1,55 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/img/edit.svg b/stacer/static/themes/default/img/edit.svg
new file mode 100644
index 0000000..5a52c53
--- /dev/null
+++ b/stacer/static/themes/default/img/edit.svg
@@ -0,0 +1,65 @@
+
+image/svg+xml
\ No newline at end of file
diff --git a/stacer/static/themes/default/img/fit.svg b/stacer/static/themes/default/img/fit.svg
new file mode 100644
index 0000000..4d30133
--- /dev/null
+++ b/stacer/static/themes/default/img/fit.svg
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/img/loading.gif b/stacer/static/themes/default/img/loading.gif
new file mode 100644
index 0000000..041761b
Binary files /dev/null and b/stacer/static/themes/default/img/loading.gif differ
diff --git a/stacer/static/themes/default/img/loadings.gif b/stacer/static/themes/default/img/loadings.gif
new file mode 100644
index 0000000..a13dc01
Binary files /dev/null and b/stacer/static/themes/default/img/loadings.gif differ
diff --git a/stacer/static/themes/default/img/not-found.svg b/stacer/static/themes/default/img/not-found.svg
new file mode 100644
index 0000000..09d9171
--- /dev/null
+++ b/stacer/static/themes/default/img/not-found.svg
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/img/package.svg b/stacer/static/themes/default/img/package.svg
new file mode 100644
index 0000000..c5cf62e
--- /dev/null
+++ b/stacer/static/themes/default/img/package.svg
@@ -0,0 +1,98 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/img/power.svg b/stacer/static/themes/default/img/power.svg
new file mode 100644
index 0000000..4b1b2b1
--- /dev/null
+++ b/stacer/static/themes/default/img/power.svg
@@ -0,0 +1,56 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/img/refresh.svg b/stacer/static/themes/default/img/refresh.svg
new file mode 100644
index 0000000..edc5b10
--- /dev/null
+++ b/stacer/static/themes/default/img/refresh.svg
@@ -0,0 +1,54 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/img/right-arrow.svg b/stacer/static/themes/default/img/right-arrow.svg
new file mode 100644
index 0000000..093a07b
--- /dev/null
+++ b/stacer/static/themes/default/img/right-arrow.svg
@@ -0,0 +1,45 @@
+
+image/svg+xml
\ No newline at end of file
diff --git a/stacer/static/themes/default/img/run.svg b/stacer/static/themes/default/img/run.svg
new file mode 100644
index 0000000..aff9e96
--- /dev/null
+++ b/stacer/static/themes/default/img/run.svg
@@ -0,0 +1,58 @@
+
+image/svg+xml
\ No newline at end of file
diff --git a/stacer/static/themes/default/img/scan-active.svg b/stacer/static/themes/default/img/scan-active.svg
new file mode 100644
index 0000000..dadd9c0
--- /dev/null
+++ b/stacer/static/themes/default/img/scan-active.svg
@@ -0,0 +1,157 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/img/scan.svg b/stacer/static/themes/default/img/scan.svg
new file mode 100644
index 0000000..7fc8fbb
--- /dev/null
+++ b/stacer/static/themes/default/img/scan.svg
@@ -0,0 +1,157 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/img/scanLoading.gif b/stacer/static/themes/default/img/scanLoading.gif
new file mode 100644
index 0000000..6d90c5d
Binary files /dev/null and b/stacer/static/themes/default/img/scanLoading.gif differ
diff --git a/stacer/static/themes/default/img/search.svg b/stacer/static/themes/default/img/search.svg
new file mode 100644
index 0000000..1abfe60
--- /dev/null
+++ b/stacer/static/themes/default/img/search.svg
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/img/service.svg b/stacer/static/themes/default/img/service.svg
new file mode 100644
index 0000000..d9ad058
--- /dev/null
+++ b/stacer/static/themes/default/img/service.svg
@@ -0,0 +1,93 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/img/sidebar-icons/cleaner.svg b/stacer/static/themes/default/img/sidebar-icons/cleaner.svg
new file mode 100644
index 0000000..d954306
--- /dev/null
+++ b/stacer/static/themes/default/img/sidebar-icons/cleaner.svg
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/img/sidebar-icons/dash.png b/stacer/static/themes/default/img/sidebar-icons/dash.png
new file mode 100644
index 0000000..12d7dbe
Binary files /dev/null and b/stacer/static/themes/default/img/sidebar-icons/dash.png differ
diff --git a/stacer/static/themes/default/img/sidebar-icons/process.png b/stacer/static/themes/default/img/sidebar-icons/process.png
new file mode 100644
index 0000000..ab0ac32
Binary files /dev/null and b/stacer/static/themes/default/img/sidebar-icons/process.png differ
diff --git a/stacer/static/themes/default/img/sidebar-icons/resources.png b/stacer/static/themes/default/img/sidebar-icons/resources.png
new file mode 100644
index 0000000..46427f9
Binary files /dev/null and b/stacer/static/themes/default/img/sidebar-icons/resources.png differ
diff --git a/stacer/static/themes/default/img/sidebar-icons/services.svg b/stacer/static/themes/default/img/sidebar-icons/services.svg
new file mode 100644
index 0000000..5d93cde
--- /dev/null
+++ b/stacer/static/themes/default/img/sidebar-icons/services.svg
@@ -0,0 +1,93 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/img/sidebar-icons/settings.svg b/stacer/static/themes/default/img/sidebar-icons/settings.svg
new file mode 100644
index 0000000..d12d505
--- /dev/null
+++ b/stacer/static/themes/default/img/sidebar-icons/settings.svg
@@ -0,0 +1,56 @@
+
+image/svg+xml
\ No newline at end of file
diff --git a/stacer/static/themes/default/img/sidebar-icons/startup-apps.png b/stacer/static/themes/default/img/sidebar-icons/startup-apps.png
new file mode 100644
index 0000000..7955249
Binary files /dev/null and b/stacer/static/themes/default/img/sidebar-icons/startup-apps.png differ
diff --git a/stacer/static/themes/default/img/sidebar-icons/startup-apps.svg b/stacer/static/themes/default/img/sidebar-icons/startup-apps.svg
new file mode 100644
index 0000000..7423852
--- /dev/null
+++ b/stacer/static/themes/default/img/sidebar-icons/startup-apps.svg
@@ -0,0 +1,105 @@
+
+image/svg+xml
\ No newline at end of file
diff --git a/stacer/static/themes/default/img/sidebar-icons/uninstaller.png b/stacer/static/themes/default/img/sidebar-icons/uninstaller.png
new file mode 100644
index 0000000..91cbbd0
Binary files /dev/null and b/stacer/static/themes/default/img/sidebar-icons/uninstaller.png differ
diff --git a/stacer/static/themes/default/img/trash.svg b/stacer/static/themes/default/img/trash.svg
new file mode 100644
index 0000000..43033b9
--- /dev/null
+++ b/stacer/static/themes/default/img/trash.svg
@@ -0,0 +1,76 @@
+
+image/svg+xml
\ No newline at end of file
diff --git a/stacer/static/themes/default/img/un-check.svg b/stacer/static/themes/default/img/un-check.svg
new file mode 100644
index 0000000..94c9016
--- /dev/null
+++ b/stacer/static/themes/default/img/un-check.svg
@@ -0,0 +1,62 @@
+
+image/svg+xml
\ No newline at end of file
diff --git a/stacer/static/themes/default/img/un-checkbox.svg b/stacer/static/themes/default/img/un-checkbox.svg
new file mode 100644
index 0000000..cd361f7
--- /dev/null
+++ b/stacer/static/themes/default/img/un-checkbox.svg
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/default/style/style.qss b/stacer/static/themes/default/style/style.qss
new file mode 100644
index 0000000..9c8e98d
--- /dev/null
+++ b/stacer/static/themes/default/style/style.qss
@@ -0,0 +1,817 @@
+/****** DEFAULT THEME ******/
+
+/**************************
+ SCROLL BAR
+***************************/
+
+QScrollArea {
+ border: 0;
+}
+
+QScrollBar:vertical {
+ width: 12;
+ margin: 0 0 0 2;
+ border-radius: 2;
+ background-color: transparent;
+}
+
+QScrollBar::handle:vertical {
+ background-color: @color01;
+ min-height: 20px;
+ border-radius: 2;
+}
+
+QScrollBar::add-line:vertical,
+QScrollBar::sub-line:vertical {
+ height: 0;
+}
+
+QScrollBar::add-page:vertical,
+QScrollBar::sub-page:vertical {
+ border-bottom-right-radius: 2;
+ border-bottom-left-radius: 2;
+ background-color: transparent;
+}
+
+QScrollBar:horizontal {
+ height: 12;
+ margin: 2 0 0 0;
+ border-radius: 2;
+ background-color: transparent;
+}
+
+QScrollBar::handle:horizontal {
+ background-color: @color01;
+ min-width: 20px;
+ border-radius: 2;
+}
+
+QScrollBar::add-line:horizontal,
+QScrollBar::sub-line:horizontal {
+ height: 0;
+}
+
+QScrollBar::add-page:horizontal,
+QScrollBar::sub-page:horizontal {
+ border-bottom-right-radius: 2;
+ border-bottom-left-radius: 2;
+ background-color: transparent;
+}
+
+QAbstractScrollArea::corner {
+ background: transparent;
+}
+
+/**************************
+ QMENU
+***************************/
+QMenu {
+ background-color: @color02;
+ border-radius: 2;
+ margin: 3px 5px;
+}
+
+QMenu::item {
+ padding: 2px 30px;
+ color: @color05;
+ font-size: 10pt;
+}
+
+QMenu::item:selected {
+ background-color: @color03;
+}
+
+QMenu::indicator {
+ width: 14px;
+ height: 14px;
+}
+
+QMenu::indicator:non-exclusive:unchecked {
+ image: url(:/static/themes/default/img/un-check.svg);
+}
+
+QMenu::indicator:non-exclusive:checked {
+ image: url(:/static/themes/default/img/check.svg);
+}
+
+/**************************
+ QCHECKBOX
+***************************/
+
+QCheckBox::indicator {
+ width: 45px;
+ height: 25px;
+}
+
+QCheckBox::indicator:checked {
+ image: url(:/static/themes/default/img/checkbox.svg);
+}
+
+QCheckBox::indicator:unchecked {
+ image: url(:/static/themes/default/img/un-checkbox.svg);
+}
+
+
+QToolTip {
+ color: @color05;
+ background-color: @color04;
+ border: 1px solid @color04;
+ border-radius: 2;
+}
+
+/**************************
+ NOT FOUND
+***************************/
+
+#notFoundWidget {
+ background: url(:/static/themes/default/img/not-found.svg) no-repeat top center;
+}
+
+#notFoundWidget #label {
+ color: @color06;
+ font-size: 13pt;
+}
+
+/**************************
+ MAIN WINDOW
+***************************/
+
+QMainWindow * {
+ font-family: "Ubuntu";
+}
+
+QWidget#sidebar {
+ background-color: @sidebar;
+ min-width:60;
+}
+
+QWidget#sidebar QPushButton {
+ border: 0px;
+ min-width: 46;
+ min-height: 46;
+ max-width: 46;
+ max-height: 46;
+ border-style: solid;
+ color: @color07;
+ margin: 5 7;
+ border-radius:2;
+}
+
+QWidget#sidebar QPushButton[checked=true],
+QWidget#sidebar QPushButton:hover {
+ background-color: @color03;
+}
+
+QLabel#pageTitle {
+ color: @color04;
+ padding: 5 0 8 0;
+ margin: 5 10;
+ border: 0;
+ border-bottom: 1 solid @color04;
+}
+
+QWidget#pageContent {
+ background-color: @color08;
+}
+
+QPushButton#dashBtn {
+ qproperty-icon: url(:/static/themes/default/img/sidebar-icons/dash.png);
+}
+
+QPushButton#systemCleanerBtn {
+ qproperty-icon: url(:/static/themes/default/img/sidebar-icons/cleaner.svg);
+}
+
+QPushButton#startupAppsBtn {
+ qproperty-icon: url(:/static/themes/default/img/sidebar-icons/startup-apps.svg);
+}
+
+QPushButton#servicesBtn {
+ qproperty-icon: url(:/static/themes/default/img/sidebar-icons/services.svg);
+}
+
+QPushButton#processesBtn {
+ qproperty-icon: url(:/static/themes/default/img/sidebar-icons/process.png);
+}
+
+QPushButton#uninstallerBtn {
+ qproperty-icon: url(:/static/themes/default/img/sidebar-icons/uninstaller.png);
+}
+
+QPushButton#resourcesBtn {
+ qproperty-icon: url(:/static/themes/default/img/sidebar-icons/resources.png);
+}
+
+QPushButton#settingsBtn {
+ qproperty-icon: url(:/static/themes/default/img/sidebar-icons/settings.svg);
+}
+
+/**************************
+ DASHBOARD PAGE
+***************************/
+
+/* - Circle Bar - */
+
+QWidget#chartWidget {
+ background-color: @color01;
+ border-radius: 1;
+}
+
+QLabel#chartTitle,
+QLabel#chartValue {
+ color: @color05;
+}
+
+QLabel#chartTitle {
+ font-size: 13pt;
+ margin: 0;
+}
+
+QLabel#chartValue {
+ font-size: 13pt;
+ margin: 0;
+}
+
+/* - Line Bar - */
+
+QWidget#lineChartWidget {
+ background-color: @color01;
+ border-radius: 1;
+}
+
+QLabel#lineChartTitle {
+ color: @color05;
+ font-size: 13pt;
+}
+
+QLabel#lineChartValue {
+ color: @color05;
+ font-size: 13pt;
+}
+
+QLabel#lineChartTotal {
+ color: @color06;
+ font-size: 11pt;
+}
+
+QProgressBar#lineChartProgress {
+ background-color: @color08;
+ border: 0;
+ border-radius: 0;
+}
+
+QProgressBar#lineChartProgress::chunk {
+ background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #3498db, stop:1 #2980b9);
+}
+
+/* - System Info - */
+
+QListView#systemInfoList {
+ border: 0;
+ background-color: transparent;
+ font-size: 12pt;
+ color: @color06;
+}
+
+QLabel#systemInfoTitle {
+ color: @color05;
+ font-size: 13pt;
+ padding-left: 5;
+}
+
+/**************************
+ SYSTEM CLEANER PAGE
+***************************/
+
+#cleanerCategories QLabel {
+ font-size: 11pt;
+ color: @color05;
+}
+
+#SystemCleanerPage QCheckBox::indicator {
+ min-width: 25;
+ min-height: 25;
+}
+
+#SystemCleanerPage QCheckBox::indicator:unchecked {
+ image: url(:/static/themes/default/img/un-check.svg);
+}
+
+#SystemCleanerPage QCheckBox::indicator:checked {
+ image: url(:/static/themes/default/img/check.svg);
+}
+
+/* - System Scan Button - */
+
+#SystemCleanerPage #scanBtn {
+ border: 0;
+}
+
+#SystemCleanerPage #scanBtn {
+ background: url(:/static/themes/default/img/scan.svg) no-repeat center;
+}
+
+#SystemCleanerPage #scanBtn:hover {
+ background: url(:/static/themes/default/img/scan-active.svg) no-repeat center;
+}
+
+/* - System Clean Button - */
+
+#SystemCleanerPage #cleanBtn {
+ border: 0;
+}
+
+#SystemCleanerPage #cleanBtn {
+ background: url(:/static/themes/default/img/clean.svg) no-repeat center;
+}
+
+#SystemCleanerPage #cleanBtn:hover {
+ background: url(:/static/themes/default/img/clean-active.svg) no-repeat center;
+}
+
+/* - System Scan Results - */
+
+#backButtton {
+ border: 0;
+ font-size: 11pt;
+ color: @color03;
+}
+
+#scanResultTreeW {
+ border: 1 solid @color13;
+ background-color: transparent;
+ border-radius: 2;
+}
+
+#scanResultTreeW QHeaderView::section {
+ border-top: 1;
+}
+
+#scanResultTreeW::item {
+ border-bottom: 1 solid @color14;
+ padding: 7 3;
+ font-size: 11pt;
+ color: @color11;
+}
+
+#scanResultTreeW::indicator {
+ width: 14;
+ height: 14;
+}
+
+#scanResultTreeW::indicator:checked {
+ image: url(:/static/themes/default/img/check.svg);
+}
+
+#scanResultTreeW::indicator:unchecked {
+ image: url(:/static/themes/default/img/un-check.svg);
+}
+
+#scanResultTreeW::branch:has-children:!has-siblings:closed,
+#scanResultTreeW::branch:closed:has-children:has-siblings {
+ border-image: none;
+ image: url(:/static/themes/default/img/right-arrow.svg);
+ padding: 4;
+}
+
+#scanResultTreeW::branch:open:has-children:!has-siblings,
+#scanResultTreeW::branch:open:has-children:has-siblings {
+ border-image: none;
+ image: url(:/static/themes/default/img/down-arrow.svg);
+ padding: 4;
+}
+
+#scanResultTreeW::branch {
+ border-bottom: 1 solid @color14;
+}
+
+#removedTotalSizeLbl {
+ font-size: 11pt;
+ color: @color15;
+}
+/**************************
+ STARTUP APPS PAGE
+***************************/
+#startupListWidget {
+ background-color: transparent;
+}
+
+#addStartupAppBtn {
+ border:0;
+ border-radius: 2;
+ background-color: @color03;
+ color: @color05;
+ padding: 7 15;
+}
+
+#addStartupAppBtn:hover {
+ background-color: @color10;
+}
+
+#startupAppsTitleLbl {
+ color: @color11;
+ padding: 10 0 10 20;
+}
+
+#refreshAppsBtn {
+ border: 0;
+}
+
+/* - Startup App - */
+
+#startupAppWidget {
+ border-radius: 2;
+ background-color: @color01;
+}
+
+#appIcon {
+ image: url(:/static/themes/default/img/app.svg);
+}
+
+#startupAppWidget:hover {
+ background-color: @color02;
+}
+
+#startupAppWidget #appName {
+ font-size: 11pt;
+ color: @color05;
+}
+
+#startupCheck {
+ margin-top: 3;
+}
+
+#startupAppWidget #deleteAppBtn {
+ qproperty-icon: url(:/static/themes/default/img/trash.svg);
+ border: 0;
+}
+
+#startupAppWidget #editAppBtn {
+ qproperty-icon: url(:/static/themes/default/img/edit.svg);
+ border: 0;
+ margin-bottom: 2;
+}
+
+/* - Startup App Edit - */
+
+#StartupAppEdit {
+ background-color: @color08;
+}
+
+#StartupAppEdit #title {
+ color: @color06;
+ font-size: 11pt;
+}
+
+#StartupAppEdit QLineEdit {
+ border-radius: 2;
+ padding: 10;
+ background-color: @color01;
+ font-size: 10pt;
+ color: @color05;
+}
+
+#StartupAppEdit #saveBtn {
+ border-radius: 2;
+ padding: 7 25;
+ font-size: 11pt;
+ background-color: @color03;
+ color: @color07;
+}
+
+#StartupAppEdit #saveBtn:hover {
+ background-color: @color10;
+}
+
+#StartupAppEdit #errorMsg {
+ color: @color09;
+}
+
+/**************************
+ SERVICES PAGE
+***************************/
+
+#ServicesPage QListWidget {
+ background-color: transparent;
+}
+
+#servicesTitle {
+ font-size: 11pt;
+ color: @color11;
+ padding: 10 0;
+}
+
+#serviceStartupTitle,
+#systemRunningTitle {
+ font-size: 10pt;
+ color: @color11;
+}
+
+/* - Service Item - */
+
+#serviceItemWidget QCheckBox {
+ margin-top: 2;
+}
+
+#serviceItemWidget {
+ border-radius: 2;
+ background-color: @color01;
+}
+
+#serviceIcon {
+ image: url(:/static/themes/default/img/service.svg);
+}
+
+#serviceItemWidget:hover {
+ background-color: @color02;
+}
+
+#ServiceItem #serviceName {
+ font-size: 10pt;
+ color: @color05;
+}
+
+#serviceStartupImg {
+ image: url(:/static/themes/default/img/power.svg);
+}
+
+#systemRunningImg {
+ image: url(:/static/themes/default/img/run.svg);
+}
+
+/**************************
+ PROCESSES PAGE
+***************************/
+
+#processTitleLbl {
+ color: @color11;
+ padding: 10 0;
+ font-size: 11pt;
+}
+
+#allProcessesCheck {
+ margin-top: 2;
+ color: @color12;
+ font-size: 10pt;
+}
+
+#allProcessesCheck::indicator {
+ width: 14;
+ height: 14;
+}
+
+#allProcessesCheck::indicator:unchecked {
+ image: url(:/static/themes/default/img/un-check.svg);
+}
+
+#allProcessesCheck::indicator:checked {
+ image: url(:/static/themes/default/img/check.svg);
+}
+
+#processSearchBox {
+ width: 150;
+ padding: 4 12;
+ border-radius: 12;
+ background: @color01 url(:/static/themes/default/img/search.svg) no-repeat right center;
+ border: 1px solid @color02;
+ color: @color12;
+}
+
+QTableView {
+ background-color: transparent;
+ selection-color: @color05;
+ color: @color05;
+ font-size: 10pt;
+ gridline-color: @color08;
+ border-radius: 2;
+}
+
+QTableView::item {
+ font-size: 11pt;
+ color: @color05;
+ padding: 6 0 6 -10;
+ background-color: @color01;
+}
+
+QTableView::item:selected {
+ background-color: @color02;
+}
+
+QHeaderView::section {
+ background-color: @color02;
+ border-width: 1 1 1 0;
+ border-style: solid;
+ border-color: @color08;
+ font-size: 11pt;
+ color: @color16;
+ padding-left:10;
+}
+
+QHeaderView::up-arrow {
+ image: url(:/static/themes/default/img/asc.svg);
+}
+
+QHeaderView::down-arrow {
+ image: url(:/static/themes/default/img/dsc.svg);
+}
+
+#refreshLabel {
+ color: @color12;
+ font-size: 10pt;
+}
+
+#refreshSlider {
+ margin-top: 3;
+}
+
+#refreshSlider::groove:horizontal {
+ height: 2px;
+ background: @color12;
+ margin: 2px 0;
+}
+
+#refreshSlider::handle:horizontal {
+ background-color: @color03;
+ width: 14px;
+ height: 14px;
+ margin: -6px 0;
+ border-radius: 7px;
+}
+
+#endProcessBtn {
+ border:0;
+ border-radius: 2;
+ background-color: @color03;
+ color: @color05;
+ padding: 7 15;
+}
+
+#endProcessBtn:hover {
+ background-color: @color10;
+}
+/**************************
+ UNINSTALLER PAGE
+***************************/
+
+#packagesTitle {
+ color: @color11;
+ padding: 10 0;
+ font-size: 11pt;
+}
+
+#packageSearch {
+ padding: 4 12;
+ border-radius: 12;
+ background: @color01 url(:/static/themes/default/img/search.svg) no-repeat right center;
+ border: 1px solid @color02;
+ color: @color12;
+}
+
+#packagesList {
+ border:0;
+ background-color: transparent;
+ font-size:10pt;
+}
+
+#packagesList::indicator {
+ min-width: 16;
+ min-height: 16;
+}
+
+#packagesList::indicator:unchecked {
+ image: url(:/static/themes/default/img/un-check.svg);
+}
+
+#packagesList::indicator:checked {
+ image: url(:/static/themes/default/img/check.svg);
+}
+
+#packagesList::item {
+ border-radius: 2;
+ min-height: 45;
+ background-color: @color01;
+}
+
+#packagesList::item:text {
+ color: @color05;
+ padding-left: 15;
+}
+
+#packagesList::item:selected {
+ background-color: @color02;
+ border: 0;
+}
+
+#packagesList::item:hover {
+ background-color: @color02;
+}
+
+#uninstallBtn {
+ border: 0;
+ padding: 6 15;
+ color: @color11;
+ border: 1px solid @color01;
+ border-radius: 5;
+}
+
+#uninstallBtn:hover {
+ background-color: @color01;
+}
+
+#refreshPackagesBtn {
+ border: 0;
+}
+
+/**************************
+ HISTORIES
+***************************/
+
+QCheckBox#historyTitle {
+ font-size: 11pt;
+ margin: 0 0 10 10;
+ color: @color12;
+}
+
+QCheckBox#historyTitle::indicator {
+ width: 20;
+ height: 20;
+}
+
+QCheckBox#historyTitle::indicator:unchecked {
+ image: url(:/static/themes/default/img/fit.svg);
+}
+
+QCheckBox#historyTitle::indicator:checked {
+ image: url(:/static/themes/default/img/collapse.svg);
+}
+
+/**************************
+ SETTINGS
+***************************/
+
+#SettingsPage QLabel {
+ font-size: 11pt;
+ color: @color12;
+}
+
+#SettingsPage QMenu {
+ background-color: @color01;
+}
+
+#SettingsPage QComboBox {
+ border: 0;
+ border-radius: 2;
+ background-color: @color01;
+ padding: 4 0 4 10;
+ font-size: 11pt;
+ color: @color05;
+ min-width: 100;
+}
+
+#SettingsPage QComboBox::drop-down {
+ background-color: @color01;
+ subcontrol-position: top right;
+ width: 14;
+ padding: 0 5;
+ color: @color05;
+
+ border-left-width: 1px;
+ border-left-color: @color01;
+ border-left-style: solid;
+ image: url(:/static/themes/default/img/down-arrow.svg);
+ border-top-right-radius: 2;
+ border-bottom-right-radius: 2;
+}
+
+#SettingsPage QComboBox::down-arrow:on {
+ background-color: @color01;
+ color: @color05;
+}
+
+#SettingsPage QComboBox QAbstractItemView {
+ background-color: @color01;
+ border: 0;
+}
+
+/**************************
+ UPDATE BAR
+***************************/
+
+#updateBarWidget {
+ background-color: @color03;
+ border-radius: 2;
+}
+
+#updateBarTextLabel {
+ font-size: 10pt;
+ color: @color05;
+}
+
+#downloadUpdateBtn {
+ font-size: 10pt;
+ color: @color05;
+ background-color: @color01;
+ border: 0;
+ padding: 4 10;
+ border-radius: 2;
+}
diff --git a/stacer/static/themes/default/style/values.ini b/stacer/static/themes/default/style/values.ini
new file mode 100644
index 0000000..9005913
--- /dev/null
+++ b/stacer/static/themes/default/style/values.ini
@@ -0,0 +1,22 @@
+@pageContent=#1b252f
+@sidebar=#15191c
+@circleChartBackgroundColor=#212f3c
+@historyChartBackgroundColor=#212f3c
+@chartLabelColor=#eeeeee
+@chartGridColor=#8394a6
+@color01=#212f3c
+@color02=#263848
+@color03=#075ffe
+@color04=#8394a6
+@color05=#eeeeee
+@color06=#7d8ea0
+@color07=#ffffff
+@color08=#1b252f
+@color09=#f44336
+@color10=#075fbb
+@color11=#dddddd
+@color12=#aeb5bf
+@color13=#293945
+@color14=#314452
+@color15=#00eb55
+@color16=#00d4ff
diff --git a/stacer/static/themes/light/img/app.svg b/stacer/static/themes/light/img/app.svg
new file mode 100644
index 0000000..d7f77ce
--- /dev/null
+++ b/stacer/static/themes/light/img/app.svg
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/light/img/clean-active.svg b/stacer/static/themes/light/img/clean-active.svg
new file mode 100644
index 0000000..f3c5675
--- /dev/null
+++ b/stacer/static/themes/light/img/clean-active.svg
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/light/img/clean.svg b/stacer/static/themes/light/img/clean.svg
new file mode 100644
index 0000000..02b5b1d
--- /dev/null
+++ b/stacer/static/themes/light/img/clean.svg
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/light/img/down-arrow.svg b/stacer/static/themes/light/img/down-arrow.svg
new file mode 100644
index 0000000..3d7284b
--- /dev/null
+++ b/stacer/static/themes/light/img/down-arrow.svg
@@ -0,0 +1,45 @@
+
+image/svg+xml
\ No newline at end of file
diff --git a/stacer/static/themes/light/img/edit.svg b/stacer/static/themes/light/img/edit.svg
new file mode 100644
index 0000000..5846cfd
--- /dev/null
+++ b/stacer/static/themes/light/img/edit.svg
@@ -0,0 +1,65 @@
+
+image/svg+xml
\ No newline at end of file
diff --git a/stacer/static/themes/light/img/loading.gif b/stacer/static/themes/light/img/loading.gif
new file mode 100644
index 0000000..41fc3e1
Binary files /dev/null and b/stacer/static/themes/light/img/loading.gif differ
diff --git a/stacer/static/themes/light/img/package.svg b/stacer/static/themes/light/img/package.svg
new file mode 100644
index 0000000..c5cf62e
--- /dev/null
+++ b/stacer/static/themes/light/img/package.svg
@@ -0,0 +1,98 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/light/img/right-arrow.svg b/stacer/static/themes/light/img/right-arrow.svg
new file mode 100644
index 0000000..7992d50
--- /dev/null
+++ b/stacer/static/themes/light/img/right-arrow.svg
@@ -0,0 +1,45 @@
+
+image/svg+xml
\ No newline at end of file
diff --git a/stacer/static/themes/light/img/scan-active.svg b/stacer/static/themes/light/img/scan-active.svg
new file mode 100644
index 0000000..99a5d6a
--- /dev/null
+++ b/stacer/static/themes/light/img/scan-active.svg
@@ -0,0 +1,157 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/light/img/scan.svg b/stacer/static/themes/light/img/scan.svg
new file mode 100644
index 0000000..878b8d8
--- /dev/null
+++ b/stacer/static/themes/light/img/scan.svg
@@ -0,0 +1,158 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stacer/static/themes/light/img/scanLoading.gif b/stacer/static/themes/light/img/scanLoading.gif
new file mode 100644
index 0000000..7c682d0
Binary files /dev/null and b/stacer/static/themes/light/img/scanLoading.gif differ
diff --git a/stacer/static/themes/light/style/style.qss b/stacer/static/themes/light/style/style.qss
new file mode 100644
index 0000000..f074f3b
--- /dev/null
+++ b/stacer/static/themes/light/style/style.qss
@@ -0,0 +1,817 @@
+/****** LIGHT THEME ******/
+
+/**************************
+ SCROLL BAR
+***************************/
+QScrollArea {
+ border: 0;
+}
+
+QScrollBar:vertical {
+ width: 12;
+ margin: 0 0 0 2;
+ border-radius: 2;
+ background-color: transparent;
+}
+
+QScrollBar::handle:vertical {
+ background-color: @color01;
+ min-height: 20px;
+ border-radius: 2;
+}
+
+QScrollBar::add-line:vertical,
+QScrollBar::sub-line:vertical {
+ height: 0;
+}
+
+QScrollBar::add-page:vertical,
+QScrollBar::sub-page:vertical {
+ border-bottom-right-radius: 2;
+ border-bottom-left-radius: 2;
+ background-color: transparent;
+}
+
+QScrollBar:horizontal {
+ height: 12;
+ margin: 2 0 0 0;
+ border-radius: 2;
+ background-color: transparent;
+}
+
+QScrollBar::handle:horizontal {
+ background-color: @color01;
+ min-width: 20px;
+ border-radius: 2;
+}
+
+QScrollBar::add-line:horizontal,
+QScrollBar::sub-line:horizontal {
+ height: 0;
+}
+
+QScrollBar::add-page:horizontal,
+QScrollBar::sub-page:horizontal {
+ border-bottom-right-radius: 2;
+ border-bottom-left-radius: 2;
+ background-color: transparent;
+}
+
+QAbstractScrollArea::corner {
+ background: transparent;
+}
+
+/**************************
+ QMENU
+***************************/
+QMenu {
+ background-color: @color07;
+ border-radius: 2;
+ margin: 3px 5px;
+}
+
+QMenu::item {
+ padding: 2px 30px;
+ color: @color02;
+ font-size: 10pt;
+}
+
+QMenu::item:selected {
+ background-color: @color01;
+}
+
+QMenu::indicator {
+ width: 14px;
+ height: 14px;
+}
+
+QMenu::indicator:non-exclusive:unchecked {
+ image: url(:/static/themes/default/img/un-check.svg);
+}
+
+QMenu::indicator:non-exclusive:checked {
+ image: url(:/static/themes/default/img/check.svg);
+}
+
+/**************************
+ QCHECKBOX
+***************************/
+
+QCheckBox::indicator {
+ width: 45px;
+ height: 25px;
+}
+
+QCheckBox::indicator:checked {
+ image: url(:/static/themes/default/img/checkbox.svg);
+}
+
+QCheckBox::indicator:unchecked {
+ image: url(:/static/themes/default/img/un-checkbox.svg);
+}
+
+QToolTip {
+ color: @color01;
+ background-color: #8394a6;
+ border: 1px solid #8394a6;
+ border-radius: 2;
+}
+
+/**************************
+ NOT FOUND
+***************************/
+
+#notFoundWidget {
+ background: url(:/static/themes/default/img/not-found.svg) no-repeat top center;
+}
+
+#notFoundWidget #label {
+ color: @color02;
+ font-size: 13pt;
+}
+
+/**************************
+ MAIN WINDOW
+***************************/
+
+QMainWindow * {
+ font-family: "Ubuntu";
+}
+
+QWidget#sidebar {
+ background-color: @sidebar;
+ min-width:60;
+}
+
+QWidget#sidebar QPushButton {
+ border: 0px;
+ min-width: 46;
+ min-height: 46;
+ max-width: 46;
+ max-height: 46;
+ border-style: solid;
+ color: @color01;
+ margin: 5 7;
+ border-radius:2;
+}
+
+QWidget#sidebar QPushButton[checked=true],
+QWidget#sidebar QPushButton:hover {
+ background-color: @color03;
+}
+
+QLabel#pageTitle {
+ color: @color02;
+ padding: 5 0 8 0;
+ margin: 5 10;
+ border: 0;
+ border-bottom: 1 solid @color09;
+}
+
+QWidget#pageContent {
+ background-color: @pageContent;
+}
+
+QPushButton#dashBtn {
+ qproperty-icon: url(:/static/themes/default/img/sidebar-icons/dash.png);
+}
+
+QPushButton#systemCleanerBtn {
+ qproperty-icon: url(:/static/themes/default/img/sidebar-icons/cleaner.svg);
+}
+
+QPushButton#startupAppsBtn {
+ qproperty-icon: url(:/static/themes/default/img/sidebar-icons/startup-apps.svg);
+}
+
+QPushButton#servicesBtn {
+ qproperty-icon: url(:/static/themes/default/img/sidebar-icons/services.svg);
+}
+
+QPushButton#processesBtn {
+ qproperty-icon: url(:/static/themes/default/img/sidebar-icons/process.png);
+}
+
+QPushButton#uninstallerBtn {
+ qproperty-icon: url(:/static/themes/default/img/sidebar-icons/uninstaller.png);
+}
+
+QPushButton#resourcesBtn {
+ qproperty-icon: url(:/static/themes/default/img/sidebar-icons/resources.png);
+}
+
+QPushButton#settingsBtn {
+ qproperty-icon: url(:/static/themes/default/img/sidebar-icons/settings.svg);
+}
+
+/**************************
+ DASHBOARD PAGE
+***************************/
+
+/* - Circle Bar - */
+
+QWidget#chartWidget {
+ background-color: @color01;
+ border-radius: 1;
+}
+
+QLabel#chartTitle,
+QLabel#chartValue {
+ color: @color02;
+}
+
+QLabel#chartTitle {
+ font-size: 13pt;
+ margin: 0;
+}
+
+QLabel#chartValue {
+ font-size: 13pt;
+ margin: 0;
+}
+
+/* - Line Bar - */
+
+QWidget#lineChartWidget {
+ background-color: @color01;
+ border-radius: 1;
+}
+
+QLabel#lineChartTitle {
+ color: @color02;
+ font-size: 13pt;
+}
+
+QLabel#lineChartValue {
+ color: @color02;
+ font-size: 13pt;
+}
+
+QLabel#lineChartTotal {
+ color: @color02;
+ font-size: 11pt;
+}
+
+QProgressBar#lineChartProgress {
+ background-color: @pageContent;
+ border: 0;
+ border-radius: 0;
+}
+
+QProgressBar#lineChartProgress::chunk {
+ background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 #3498db, stop:1 #2980b9);
+}
+
+/* - System Info - */
+
+QListView#systemInfoList {
+ border: 0;
+ background-color: transparent;
+ font-size: 12pt;
+ color: @color02;
+}
+
+QLabel#systemInfoTitle {
+ color: @color02;
+ font-size: 13pt;
+ padding-left: 5;
+}
+
+/**************************
+ SYSTEM CLEANER PAGE
+***************************/
+
+#cleanerCategories QLabel {
+ font-size: 11pt;
+ color: @color02;
+}
+
+#SystemCleanerPage QCheckBox::indicator {
+ min-width: 25;
+ min-height: 25;
+}
+
+#SystemCleanerPage QCheckBox::indicator:unchecked {
+ image: url(:/static/themes/default/img/un-check.svg);
+}
+
+#SystemCleanerPage QCheckBox::indicator:checked {
+ image: url(:/static/themes/default/img/check.svg);
+}
+
+/* - System Scan Button - */
+
+#SystemCleanerPage #scanBtn {
+ border: 0;
+}
+
+#SystemCleanerPage #scanBtn {
+ background: url(:/static/themes/light/img/scan.svg) no-repeat center;
+}
+
+#SystemCleanerPage #scanBtn:hover {
+ background: url(:/static/themes/light/img/scan-active.svg) no-repeat center;
+}
+
+/* - System Clean Button - */
+
+#SystemCleanerPage #cleanBtn {
+ border: 0;
+}
+
+#SystemCleanerPage #cleanBtn {
+ background: url(:/static/themes/light/img/clean.svg) no-repeat center;
+}
+
+#SystemCleanerPage #cleanBtn:hover {
+ background: url(:/static/themes/light/img/clean-active.svg) no-repeat center;
+}
+
+/* - System Scan Results - */
+
+#backButtton {
+ border: 0;
+ font-size: 11pt;
+ color: @color03;
+}
+
+#scanResultTreeW {
+ border: 1 solid @color01;
+ background-color: @color01;
+ border-radius: 2;
+}
+
+#scanResultTreeW QHeaderView::section {
+ border-top: 1;
+}
+
+#scanResultTreeW::item {
+ border-bottom: 1 solid @pageContent;
+ padding: 7 3;
+ font-size: 11pt;
+ color: @color02;
+}
+
+#scanResultTreeW::indicator {
+ width: 14;
+ height: 14;
+}
+
+#scanResultTreeW::indicator:checked {
+ image: url(:/static/themes/default/img/check.svg);
+}
+
+#scanResultTreeW::indicator:unchecked {
+ image: url(:/static/themes/default/img/un-check.svg);
+}
+
+#scanResultTreeW::branch:has-children:!has-siblings:closed,
+#scanResultTreeW::branch:closed:has-children:has-siblings {
+ border-image: none;
+ image: url(:/static/themes/light/img/right-arrow.svg);
+ padding: 4;
+}
+
+#scanResultTreeW::branch:open:has-ch ildren:!has-siblings,
+#scanResultTreeW::branch:open:has-children:has-siblings {
+ border-image: none;
+ image: url(:/static/themes/light/img/down-arrow.svg);
+ padding: 4;
+}
+
+#scanResultTreeW::branch {
+ border-bottom: 1 solid @pageContent;
+}
+
+#removedTotalSizeLbl {
+ font-size: 11pt;
+ color: @color04;
+}
+
+/**************************
+ STARTUP APPS PAGE
+***************************/
+#startupListWidget {
+ background-color: transparent;
+}
+
+#addStartupAppBtn {
+ border:0;
+ border-radius: 2;
+ background-color: @color03;
+ color: @color05;
+ padding: 7 15;
+}
+
+#addStartupAppBtn:hover {
+ background-color: @color10;
+}
+
+#startupAppsTitleLbl {
+ color: @color03;
+ padding: 10 0 10 20;
+}
+
+#refreshAppsBtn {
+ border: 0;
+}
+
+/* - Startup App - */
+
+#startupAppWidget {
+ border-radius: 2;
+ background-color: @color01;
+}
+
+#appIcon {
+ image: url(:/static/themes/light/img/app.svg);
+}
+
+#startupAppWidget:hover {
+ background-color: @color07;
+}
+
+#startupAppWidget #appName {
+ font-size: 11pt;
+ color: @color02;
+}
+
+#startupCheck {
+ margin-top: 3;
+}
+
+#startupAppWidget #deleteAppBtn {
+ qproperty-icon: url(:/static/themes/default/img/trash.svg);
+ border: 0;
+}
+
+#startupAppWidget #editAppBtn {
+ qproperty-icon: url(:/static/themes/light/img/edit.svg);
+ border: 0;
+ margin-bottom: 2;
+}
+
+/* - Startup App Edit - */
+
+#StartupAppEdit {
+ background-color: @pageContent;
+}
+
+#StartupAppEdit #title {
+ color: @color02;
+ font-size: 11pt;
+}
+
+#StartupAppEdit QLineEdit {
+ border-radius: 2;
+ padding: 10;
+ background-color: @color01;
+ font-size: 10pt;
+ color: @color02;
+}
+
+#StartupAppEdit #saveBtn {
+ border-radius: 2;
+ padding: 7 25;
+ font-size: 11pt;
+ background-color: @color03;
+ color: @color01;
+}
+
+#StartupAppEdit #saveBtn:hover {
+ background-color: @color10;
+}
+
+#StartupAppEdit #errorMsg {
+ color: #f44336;
+}
+
+/**************************
+ SERVICES PAGE
+***************************/
+
+#ServicesPage QListWidget {
+ background-color: transparent;
+}
+
+#servicesTitle {
+ font-size: 11pt;
+ color: @color03;
+ padding: 10 0;
+}
+
+#serviceStartupTitle,
+#systemRunningTitle {
+ font-size: 10pt;
+ color: #ddd;
+}
+
+/* - Service Item - */
+
+#serviceItemWidget QCheckBox {
+ margin-top: 2;
+}
+
+#serviceItemWidget {
+ border-radius: 2;
+ background-color: @color01;
+}
+
+#serviceIcon {
+ image: url(:/static/themes/default/img/service.svg);
+}
+
+#serviceItemWidget:hover {
+ background-color: @color07;
+}
+
+#ServiceItem #serviceName {
+ font-size: 10pt;
+ color: @color02;
+}
+
+#serviceStartupImg {
+ image: url(:/static/themes/default/img/power.svg);
+}
+
+#systemRunningImg {
+ image: url(:/static/themes/default/img/run.svg);
+}
+
+/**************************
+ PROCESSES PAGE
+***************************/
+
+#processTitleLbl {
+ color: @color03;
+ padding: 10 0;
+ font-size: 11pt;
+}
+
+#allProcessesCheck {
+ margin-top: 2;
+ color: @color02;
+ font-size: 10pt;
+}
+
+#allProcessesCheck::indicator {
+ width: 14;
+ height: 14;
+}
+
+#allProcessesCheck::indicator:unchecked {
+ image: url(:/static/themes/default/img/un-check.svg);
+}
+
+#allProcessesCheck::indicator:checked {
+ image: url(:/static/themes/default/img/check.svg);
+}
+
+#processSearchBox {
+ width: 150;
+ padding: 4 12;
+ border-radius: 12;
+ background: @color01 url(:/static/themes/default/img/search.svg) no-repeat right center;
+ border: 1px solid @color07;
+ color: @color02;
+}
+
+QTableView {
+ background-color: transparent;
+ selection-color: @color02;
+ color: @color02;
+ font-size: 10pt;
+ gridline-color: @pageContent;
+ border-radius: 2;
+}
+
+QTableView::item {
+ font-size: 11pt;
+ color: @color02;
+ padding: 6 0 6 -10;
+ background-color: @color01;
+}
+
+QTableView::item:selected {
+ background-color: @color07;
+}
+
+QHeaderView::section {
+ background-color: @color07;
+ border-width: 1 1 1 0;
+ border-style: solid;
+ border-color: @pageContent;
+ font-size: 11pt;
+ color: @color06;
+ padding-left:10;
+}
+
+QHeaderView::up-arrow {
+ image: url(:/static/themes/default/img/asc.svg);
+}
+
+QHeaderView::down-arrow {
+ image: url(:/static/themes/default/img/dsc.svg);
+}
+
+#refreshLabel {
+ color: @color02;
+ font-size: 10pt;
+}
+
+#refreshSlider {
+ margin-top: 3;
+}
+
+#refreshSlider::groove:horizontal {
+ height: 2px;
+ background-color: @color08;
+ margin: 2px 0;
+}
+
+#refreshSlider::handle:horizontal {
+ background-color: @color03;
+ width: 14px;
+ height: 14px;
+ margin: -6px 0;
+ border-radius: 7px;
+}
+
+#endProcessBtn {
+ border:0;
+ border-radius: 2;
+ background-color: @color03;
+ color: @color05;
+ padding: 7 15;
+}
+
+#endProcessBtn:hover {
+ background-color: @color01;
+}
+/**************************
+ UNINSTALLER PAGE
+***************************/
+
+#packagesTitle {
+ color: @color03;
+ padding: 10 0;
+ font-size: 11pt;
+}
+
+#packageSearch {
+ padding: 4 12;
+ border-radius: 12;
+ background: @color01 url(:/static/themes/default/img/search.svg) no-repeat right center;
+ border: 1px solid @color07;
+ color: @color08;
+}
+
+#packagesList {
+ border:0;
+ background-color: transparent;
+ font-size:10pt;
+}
+
+#packagesList::indicator {
+ min-width: 16;
+ min-height: 16;
+}
+
+#packagesList::indicator:unchecked {
+ image: url(:/static/themes/default/img/un-check.svg);
+}
+
+#packagesList::indicator:checked {
+ image: url(:/static/themes/default/img/check.svg);
+}
+
+#packagesList::item {
+ border-radius: 2;
+ min-height: 40;
+ max-height: 40;
+ background-color: @color01;
+}
+
+#packagesList::item:text {
+ color: @color02;
+ padding-left: 15;
+}
+
+#packagesList::item:selected {
+ background-color: @color07;
+ border: 0;
+}
+
+#packagesList::item:hover {
+ background-color: @color07;
+}
+
+#uninstallBtn {
+ border: 0;
+ padding: 6 15;
+ color: @color02;
+ border: 1px solid @color01;
+ border-radius: 5;
+}
+
+#uninstallBtn:hover {
+ background-color: @color01;
+}
+
+#refreshPackagesBtn {
+ border: 0;
+}
+
+/**************************
+ HISTORIES
+***************************/
+
+QCheckBox#historyTitle {
+ font-size: 11pt;
+ margin: 0 0 10 10;
+ color: @color02;
+}
+
+QCheckBox#historyTitle::indicator {
+ width: 20;
+ height: 20;
+}
+
+QCheckBox#historyTitle::indicator:unchecked {
+ image: url(:/static/themes/default/img/fit.svg);
+}
+
+QCheckBox#historyTitle::indicator:checked {
+ image: url(:/static/themes/default/img/collapse.svg);
+}
+
+/**************************
+ SETTINGS
+***************************/
+
+#SettingsPage QLabel {
+ font-size: 11pt;
+ color: @color02;
+}
+
+#SettingsPage QMenu {
+ background-color: @color01;
+}
+
+#SettingsPage QComboBox {
+ border: 0;
+ border-radius: 2;
+ background-color: @color01;
+ padding: 4 0 4 10;
+ font-size: 11pt;
+ color: @color02;
+ min-width: 100;
+}
+
+#SettingsPage QComboBox::drop-down {
+ background-color: @color01;
+ subcontrol-position: top right;
+ width: 14;
+ padding: 0 5;
+ color: @color02;
+
+ border-left-width: 1px;
+ border-left-color: @color01;
+ border-left-style: solid;
+ image: url(:/static/themes/light/img/down-arrow.svg);
+ border-top-right-radius: 2;
+ border-bottom-right-radius: 2;
+}
+
+#SettingsPage QComboBox::down-arrow:on {
+ background-color: @color01;
+ color: @color02;
+}
+
+#SettingsPage QComboBox QAbstractItemView {
+ background-color: @color01;
+ border: 0;
+}
+
+/**************************
+ UPDATE BAR
+***************************/
+
+#updateBarWidget {
+ background-color: @color03;
+ border-radius: 2;
+}
+
+#updateBarTextLabel {
+ font-size: 10pt;
+ color: @color05;
+}
+
+#downloadUpdateBtn {
+ font-size: 10pt;
+ color: @color09;
+ background-color: @color01;
+ border: 0;
+ padding: 4 10;
+ border-radius: 2;
+}
diff --git a/stacer/static/themes/light/style/values.ini b/stacer/static/themes/light/style/values.ini
new file mode 100644
index 0000000..34b0f7a
--- /dev/null
+++ b/stacer/static/themes/light/style/values.ini
@@ -0,0 +1,16 @@
+@pageContent=#daebf5
+@sidebar=#15191c
+@circleChartBackgroundColor=#ffffff
+@historyChartBackgroundColor=#ffffff
+@chartLabelColor=#7d8ea0
+@chartGridColor=#8394a6
+@color01=#ffffff
+@color02=#7d8ea0
+@color03=#075ffe
+@color04=#00eb55
+@color05=#eeeeee
+@color06=#00d4ff
+@color07=#f6fafd
+@color08=#aeb5bf
+@color09=#8394a6
+@color10=#075fbb
diff --git a/translations/stacer_en.ts b/translations/stacer_en.ts
new file mode 100644
index 0000000..5a15c6a
--- /dev/null
+++ b/translations/stacer_en.ts
@@ -0,0 +1,453 @@
+
+
+
+
+ App
+
+
+ Dashboard
+
+
+
+
+ System Cleaner
+
+
+
+
+ System Startup Apps
+
+
+
+
+ System Services
+
+
+
+
+ Uninstaller
+
+
+
+
+ Resources
+
+
+
+
+ Processes
+
+
+
+
+ Settings
+
+
+
+
+ DashboardPage
+
+
+ SYSTEM INFO
+
+
+
+
+ There are update currently available.
+
+
+
+
+ Download
+
+
+
+
+ CPU
+
+
+
+
+ MEMORY
+
+
+
+
+ DISK
+
+
+
+
+ DOWNLOAD
+
+
+
+
+ UPLOAD
+
+
+
+
+ Hostname: %1
+
+
+
+
+ Platform: %1
+
+
+
+
+ Distribution: %1
+
+
+
+
+ Kernel Release: %1
+
+
+
+
+ CPU Model: %1
+
+
+
+
+ CPU Speed: %1
+
+
+
+
+ CPU Core: %1
+
+
+
+
+
+ Total: %1
+
+
+
+
+ ProcessesPage
+
+
+ Processes
+
+
+
+
+ All Processes
+
+
+
+
+ Search...
+
+
+
+
+ End Process
+
+
+
+
+ User
+
+
+
+
+ Resident Memory
+
+
+
+
+ %Memory
+
+
+
+
+ Virtual Memory
+
+
+
+
+ Start Time
+
+
+
+
+ State
+
+
+
+
+ Group
+
+
+
+
+ Nice
+
+
+
+
+ CPU Time
+
+
+
+
+ Session
+
+
+
+
+ Seat
+
+
+
+
+ Process
+
+
+
+
+ Processes (%1)
+
+
+
+
+ Refresh (%1)
+
+
+
+
+ ResourcesPage
+
+
+ CPU History
+
+
+
+
+ Memory History
+
+
+
+
+ Network History
+
+
+
+
+ Download %1/s Total: %2
+
+
+
+
+ Upload %1/s Total: %2
+
+
+
+
+ Swap %1 (%2%) %3
+
+
+
+
+ Memory %1 (%2%) %3
+
+
+
+
+ ServicesPage
+
+
+ System Services
+
+
+
+
+ Startup at boot ?
+
+
+
+
+ Running Now ?
+
+
+
+
+ Not Found System Service
+
+
+
+
+ System Services (%1)
+
+
+
+
+ SettingsPage
+
+
+ Language
+
+
+
+
+ Theme
+
+
+
+
+ StartupApp
+
+
+ Delete
+
+
+
+
+ Edit
+
+
+
+
+ StartupAppEdit
+
+
+ Startup App
+
+
+
+
+ Save
+
+
+
+
+ Fields cannot be left blank.
+
+
+
+
+ App Comment
+
+
+
+
+ App Name
+
+
+
+
+ Command
+
+
+
+
+ Application
+
+
+
+
+ StartupAppsPage
+
+
+ Not Found Startup Apps
+
+
+
+
+ System Startup Applications
+
+
+
+
+ Add Startup App
+
+
+
+
+ System Startup Applications (%1)
+
+
+
+
+ SystemCleanerPage
+
+
+ Crash Reports
+
+
+
+
+ Application Logs
+
+
+
+
+ Application Caches
+
+
+
+
+ Trash
+
+
+
+
+ Package Caches
+
+
+
+
+ Back
+
+
+
+
+ File Name
+
+
+
+
+ Size
+
+
+
+
+ %1 size files cleaned.
+
+
+
+
+ UninstallerPage
+
+
+ System Installed Packages
+
+
+
+
+ Search...
+
+
+
+
+ Not Found Installed Packages
+
+
+
+
+ Uninstall Selected
+
+
+
+
+ System Installed Packages (%1)
+
+
+
+
diff --git a/translations/stacer_es.ts b/translations/stacer_es.ts
new file mode 100644
index 0000000..c79433c
--- /dev/null
+++ b/translations/stacer_es.ts
@@ -0,0 +1,453 @@
+
+
+
+
+ App
+
+
+ Dashboard
+ Panel de instrumentos
+
+
+
+ System Cleaner
+ Limpiador del Sistema
+
+
+
+ System Startup Apps
+ Aplicaciones en el inicio del sistema
+
+
+
+ System Services
+ Servicios del Sistema
+
+
+
+ Uninstaller
+ Paquetes instalado en el sistema
+
+
+
+ Resources
+ Recursos
+
+
+
+ Processes
+ Procesos
+
+
+
+ Settings
+ Opciones
+
+
+
+ DashboardPage
+
+
+ SYSTEM INFO
+ INFORMACIÓN DEL SISTEMA
+
+
+
+ There are update currently available.
+ Actualmente hay actualizaciones disponibles.
+
+
+
+ Download
+ Descargar
+
+
+
+ CPU
+ CPU
+
+
+
+ MEMORY
+ MEMORIA
+
+
+
+ DISK
+ DISCO
+
+
+
+ DOWNLOAD
+ DESCARGAR
+
+
+
+ UPLOAD
+ ENVÍOS
+
+
+
+ Hostname: %1
+ Nombre de host: %1
+
+
+
+ Platform: %1
+ Plataforma: %1
+
+
+
+ Distribution: %1
+ Distribución: %1
+
+
+
+ Kernel Release: %1
+ Versión del kernel: %1
+
+
+
+ CPU Model: %1
+ Modelo de CPU: %1
+
+
+
+ CPU Speed: %1
+ Velocidad de la CPU: %1
+
+
+
+ CPU Core: %1
+ Núcleo de la CPU:%1
+
+
+
+
+ Total: %1
+ Total: %1
+
+
+
+ ProcessesPage
+
+
+ Processes
+ Procesos
+
+
+
+ All Processes
+ Todos los Procesos
+
+
+
+ Search...
+ Buscar...
+
+
+
+ End Process
+ Proceso Final
+
+
+
+ User
+ Usuario
+
+
+
+ Resident Memory
+ Memoria Residente
+
+
+
+ %Memory
+ %Memoria
+
+
+
+ Virtual Memory
+ Memoria virtual
+
+
+
+ Start Time
+ Hora de inicio
+
+
+
+ State
+ Estado
+
+
+
+ Group
+ Grupo
+
+
+
+ Nice
+ Bonito
+
+
+
+ CPU Time
+
+
+
+
+ Session
+ Sesión
+
+
+
+ Seat
+ Asiento
+
+
+
+ Process
+ Proceso
+
+
+
+ Processes (%1)
+ Procesos (%1)
+
+
+
+ Refresh (%1)
+ Refresco (%1)
+
+
+
+ ResourcesPage
+
+
+ CPU History
+ Actividades Cpu
+
+
+
+ Memory History
+ Actividades Mémoire
+
+
+
+ Network History
+ Actividades Internet
+
+
+
+ Download %1/s Total: %2
+ Descargar %1/s Total: %2
+
+
+
+ Upload %1/s Total: %2
+ Subida %1 /s Total: %2
+
+
+
+ Swap %1 (%2%) %3
+ Intercambio %1 (%2%) %3
+
+
+
+ Memory %1 (%2%) %3
+ Memoria %1 (%2%) %3
+
+
+
+ ServicesPage
+
+
+ System Services
+ Servicios del Sistema
+
+
+
+ Startup at boot ?
+ Inicio en el arranque ?
+
+
+
+ Running Now ?
+ Corriendo Ahora ?
+
+
+
+ Not Found System Service
+ Servicio del Sistema No Encontrado
+
+
+
+ System Services (%1)
+ Servicios del Sistema (%1)
+
+
+
+ SettingsPage
+
+
+ Language
+ Idioma
+
+
+
+ Theme
+ Tema
+
+
+
+ StartupApp
+
+
+ Delete
+ Borrar
+
+
+
+ Edit
+ Editar
+
+
+
+ StartupAppEdit
+
+
+ Startup App
+ Aplicación de Inicio
+
+
+
+ Save
+ Salvar
+
+
+
+ Fields cannot be left blank.
+ Los campos no se pueden dejar en blanco.
+
+
+
+ App Comment
+ Comentario de la Aplicación
+
+
+
+ App Name
+ Nombre de la Aplicación
+
+
+
+ Command
+ Mando
+
+
+
+ Application
+ Aplicación
+
+
+
+ StartupAppsPage
+
+
+ Not Found Startup Apps
+ Aplicaciones de Inicio No Encontradas
+
+
+
+ System Startup Applications
+ Aplicaciones de Inicio del Sistema
+
+
+
+ Add Startup App
+ Añadir Aplicación de Inicio
+
+
+
+ System Startup Applications (%1)
+ Aplicaciones de Inicio del Sistema (%1)
+
+
+
+ SystemCleanerPage
+
+
+ Crash Reports
+ Informes de fallos
+
+
+
+ Application Logs
+ Registros de Aplicaciones
+
+
+
+ Application Caches
+ Aplicaciones en Caché
+
+
+
+ Trash
+ Basura
+
+
+
+ Package Caches
+ Paquete de Cachés
+
+
+
+ Back
+ Espalda
+
+
+
+ File Name
+ Nombre del Archivo
+
+
+
+ Size
+ Tamaño
+
+
+
+ %1 size files cleaned.
+ %1 archivos de tamaño limpiado.
+
+
+
+ UninstallerPage
+
+
+ System Installed Packages
+ Paquetes Instalados del Sistema
+
+
+
+ Search...
+ Buscar...
+
+
+
+ Not Found Installed Packages
+ Paquetes Instalados no Encontrados
+
+
+
+ Uninstall Selected
+ Desinstalar Seleccionados
+
+
+
+ System Installed Packages (%1)
+ Paquetes Instalados del Sistema (%1)
+
+
+
diff --git a/translations/stacer_fr.ts b/translations/stacer_fr.ts
new file mode 100644
index 0000000..4d91c14
--- /dev/null
+++ b/translations/stacer_fr.ts
@@ -0,0 +1,453 @@
+
+
+
+
+ App
+
+
+ Dashboard
+ Tableau de bord
+
+
+
+ System Cleaner
+ Nettoyeur Système
+
+
+
+ System Startup Apps
+ Applications au Démarrage
+
+
+
+ System Services
+ Services Système
+
+
+
+ Uninstaller
+ Paquets Installés sur le Système
+
+
+
+ Resources
+ Ressources
+
+
+
+ Processes
+ Processus
+
+
+
+ Settings
+ Options
+
+
+
+ DashboardPage
+
+
+ SYSTEM INFO
+ INFORMATIONS SYSTÈME
+
+
+
+ There are update currently available.
+ Il existe actuellement des mises à jour disponibles.
+
+
+
+ Download
+ Télécharger
+
+
+
+ CPU
+ CPU
+
+
+
+ MEMORY
+ MÉMOIRE
+
+
+
+ DISK
+ DISQUE
+
+
+
+ DOWNLOAD
+ TÉLÉCHARGER
+
+
+
+ UPLOAD
+ TÉLÉVERSEMENT
+
+
+
+ Hostname: %1
+ Nom d’Hôte: %1
+
+
+
+ Platform: %1
+ Plateforme: %1
+
+
+
+ Distribution: %1
+ Distribution: %1
+
+
+
+ Kernel Release: %1
+ Version du Noyau: %1
+
+
+
+ CPU Model: %1
+ Modèle du CPU: %1
+
+
+
+ CPU Speed: %1
+ Vitesse du CPU: %1
+
+
+
+ CPU Core: %1
+ CPU Coeur: %1
+
+
+
+
+ Total: %1
+ Total: %1
+
+
+
+ ProcessesPage
+
+
+ Processes
+ Processus
+
+
+
+ All Processes
+ Tous les Processus
+
+
+
+ Search...
+ Chercher...
+
+
+
+ End Process
+ Processus Final
+
+
+
+ User
+ Utilisateur
+
+
+
+ Resident Memory
+ Mémoire Résidante
+
+
+
+ %Memory
+ %Mémoire
+
+
+
+ Virtual Memory
+ Mémoire Virtuelle
+
+
+
+ Start Time
+ Heure de Début
+
+
+
+ State
+ Etat
+
+
+
+ Group
+ Groupe
+
+
+
+ Nice
+ Agréable
+
+
+
+ CPU Time
+ Temps CPU
+
+
+
+ Session
+ Session
+
+
+
+ Seat
+ Siège
+
+
+
+ Process
+ Processus
+
+
+
+ Processes (%1)
+ Processus (%1)
+
+
+
+ Refresh (%1)
+ Rafraîchir (%1)
+
+
+
+ ResourcesPage
+
+
+ CPU History
+ Historique CPU
+
+
+
+ Memory History
+ Histoire de la Mémoire
+
+
+
+ Network History
+ Historique du Réseau
+
+
+
+ Download %1/s Total: %2
+ Télécharger %1 /s Total :%2
+
+
+
+ Upload %1/s Total: %2
+ Télécharger %1/s Total: %2
+
+
+
+ Swap %1 (%2%) %3
+ Échanger %1 (%2%) %3
+
+
+
+ Memory %1 (%2%) %3
+ Mémoire %1 (%2%) %3
+
+
+
+ ServicesPage
+
+
+ System Services
+ Services Système
+
+
+
+ Startup at boot ?
+ Démarrage au démarrage ?
+
+
+
+ Running Now ?
+ Vous Exécutez Maintenant?
+
+
+
+ Not Found System Service
+ Service Système non Trouvé
+
+
+
+ System Services (%1)
+ Services Système (%1)
+
+
+
+ SettingsPage
+
+
+ Language
+ La langue
+
+
+
+ Theme
+ Thème
+
+
+
+ StartupApp
+
+
+ Delete
+ Effacer
+
+
+
+ Edit
+ Modifier
+
+
+
+ StartupAppEdit
+
+
+ Startup App
+ Application de Démarrage
+
+
+
+ Save
+ Sauver
+
+
+
+ Fields cannot be left blank.
+ Les champs ne peuvent pas être laissés en blanc.
+
+
+
+ App Comment
+ Commentaire de l'Application
+
+
+
+ App Name
+ Nom de l'application
+
+
+
+ Command
+ Commander
+
+
+
+ Application
+ Application
+
+
+
+ StartupAppsPage
+
+
+ Not Found Startup Apps
+ Applications de Démarrage non Trouvées
+
+
+
+ System Startup Applications
+ Applications au Démarrage
+
+
+
+ Add Startup App
+ Ajouter une Application de Démarrage
+
+
+
+ System Startup Applications (%1)
+ Applications au Démarrage (%1)
+
+
+
+ SystemCleanerPage
+
+
+ Crash Reports
+ Rapport D’erreurs
+
+
+
+ Application Logs
+ Journal des Applications
+
+
+
+ Application Caches
+ Cache des Applications
+
+
+
+ Trash
+ Poubelle
+
+
+
+ Package Caches
+ Emballage Caches
+
+
+
+ Back
+ Arrière
+
+
+
+ File Name
+ Nom de fichier
+
+
+
+ Size
+ Taille
+
+
+
+ %1 size files cleaned.
+ %1 fichiers de taille nettoyés.
+
+
+
+ UninstallerPage
+
+
+ System Installed Packages
+ Forfaits Installés par Système
+
+
+
+ Search...
+ Chercher...
+
+
+
+ Not Found Installed Packages
+ Paquets Installés non Trouvés
+
+
+
+ Uninstall Selected
+ Désinstallation Sélectionnée
+
+
+
+ System Installed Packages (%1)
+ Forfaits Installés par Système (%1)
+
+
+
diff --git a/translations/stacer_hi.ts b/translations/stacer_hi.ts
new file mode 100644
index 0000000..f8a691b
--- /dev/null
+++ b/translations/stacer_hi.ts
@@ -0,0 +1,453 @@
+
+
+
+
+ App
+
+
+ Dashboard
+ डैशबोर्ड
+
+
+
+ System Cleaner
+ सिस्टम क्लीनर
+
+
+
+ System Startup Apps
+ स्टार्टअप ऐप
+
+
+
+ System Services
+ सेवाएं
+
+
+
+ Uninstaller
+ अनइंस्टॉलर
+
+
+
+ Resources
+ साधन
+
+
+
+ Processes
+ प्रक्रियाओं
+
+
+
+ Settings
+ सेटिंग्स
+
+
+
+ DashboardPage
+
+
+ SYSTEM INFO
+ व्यवस्था की सूचना
+
+
+
+ There are update currently available.
+ वर्तमान में उपलब्ध अपडेट उपलब्ध हैं.
+
+
+
+ Download
+ डाउनलोड
+
+
+
+ CPU
+ CPU
+
+
+
+ MEMORY
+ याद
+
+
+
+ DISK
+ डिस्क
+
+
+
+ DOWNLOAD
+ डाउनलोड
+
+
+
+ UPLOAD
+ अपलोड
+
+
+
+ Hostname: %1
+ होस्ट का नाम: %1
+
+
+
+ Platform: %1
+ मंच: %1
+
+
+
+ Distribution: %1
+ वितरण: %1
+
+
+
+ Kernel Release: %1
+ कर्नेल रिलीज: %1
+
+
+
+ CPU Model: %1
+ CPU आदर्श: %1
+
+
+
+ CPU Speed: %1
+ CPU गति: %1
+
+
+
+ CPU Core: %1
+ CPU कोर: %1
+
+
+
+
+ Total: %1
+ कुल: %1
+
+
+
+ ProcessesPage
+
+
+ Processes
+ प्रक्रियाओं
+
+
+
+ All Processes
+ सभी प्रक्रियाएं
+
+
+
+ Search...
+ खोज...
+
+
+
+ End Process
+ प्रक्रिया समाप्त
+
+
+
+ Resident Memory
+ निवासी मेमोरी
+
+
+
+ %Memory
+ %याद
+
+
+
+ Virtual Memory
+ अप्रत्यक्ष स्मृति
+
+
+
+ User
+ उपयोगकर्ता
+
+
+
+ Start Time
+ समय शुरू
+
+
+
+ State
+ राज्य
+
+
+
+ Group
+ समूह
+
+
+
+ Nice
+ अच्छा
+
+
+
+ CPU Time
+ CPU पहर
+
+
+
+ Session
+ अधिवेशन
+
+
+
+ Seat
+ सीट
+
+
+
+ Process
+ प्रक्रिया
+
+
+
+ Processes (%1)
+ प्रक्रियाओं (%1)
+
+
+
+ Refresh (%1)
+ ताज़ा करना (%1)
+
+
+
+ ResourcesPage
+
+
+ CPU History
+ CPU इतिहास
+
+
+
+ Memory History
+ मेमोरी इतिहास
+
+
+
+ Network History
+ नेटवर्क इतिहास
+
+
+
+ Download %1/s Total: %2
+ डाउनलोड %1/s कुल: %2
+
+
+
+ Upload %1/s Total: %2
+ अपलोड %1/s कुल: %2
+
+
+
+ Swap %1 (%2%) %3
+ विनिमय %1 (%2%) %3
+
+
+
+ Memory %1 (%2%) %3
+ याद %1 (%2%) %3
+
+
+
+ ServicesPage
+
+
+ System Services
+ सिस्टम सेवाएं
+
+
+
+ Startup at boot ?
+ बूट पर स्टार्टअप?
+
+
+
+ Running Now ?
+ अब चल रहा है?
+
+
+
+ Not Found System Service
+ सिस्टम सर्विस नहीं मिला
+
+
+
+ System Services (%1)
+ सिस्टम सेवाएं (%1)
+
+
+
+ SettingsPage
+
+
+ Language
+ भाषा
+
+
+
+ Theme
+ विषय
+
+
+
+ StartupApp
+
+
+ Delete
+ हटाना
+
+
+
+ Edit
+ संपादित करें
+
+
+
+ StartupAppEdit
+
+
+ Startup App
+ स्टार्टअप ऐप
+
+
+
+ Save
+ बचाना
+
+
+
+ Fields cannot be left blank.
+ फ़ील्ड को रिक्त नहीं छोड़ा जा सकता.
+
+
+
+ App Comment
+ ऐप टिप्पणी
+
+
+
+ App Name
+ एप्लिकेशन का नाम
+
+
+
+ Command
+ आदेश
+
+
+
+ Application
+ आवेदन
+
+
+
+ StartupAppsPage
+
+
+ Add Startup App
+ स्टार्टअप ऐप जोड़ें
+
+
+
+ System Startup Applications
+ सिस्टम स्टार्टअप एप्लीकेशन
+
+
+
+ Not Found Startup Apps
+ स्टार्टअप ऐप्स नहीं मिला
+
+
+
+ System Startup Applications (%1)
+ सिस्टम स्टार्टअप एप्लीकेशन (%1)
+
+
+
+ SystemCleanerPage
+
+
+ Crash Reports
+ क्रैश रिपोर्ट
+
+
+
+ Application Logs
+ एप्लिकेशन लॉग
+
+
+
+ Application Caches
+ आवेदन कैश
+
+
+
+ Trash
+ कचरा
+
+
+
+ Package Caches
+ पैकेज कैश
+
+
+
+ Back
+ वापस
+
+
+
+ File Name
+ फ़ाइल का नाम
+
+
+
+ Size
+ आकार
+
+
+
+ %1 size files cleaned.
+ %1 आकार की फ़ाइलों को साफ किया गया.
+
+
+
+ UninstallerPage
+
+
+ Uninstall Selected
+ स्थापना रद्द करें चयनित
+
+
+
+ Not Found Installed Packages
+ स्थापित नहीं मिला संकुल
+
+
+
+ System Installed Packages
+ सिस्टम स्थापित संकुल
+
+
+
+ Search...
+ खोज...
+
+
+
+ System Installed Packages (%1)
+ सिस्टम स्थापित संकुल (%1)
+
+
+
diff --git a/translations/stacer_pt.ts b/translations/stacer_pt.ts
new file mode 100644
index 0000000..3b241fe
--- /dev/null
+++ b/translations/stacer_pt.ts
@@ -0,0 +1,453 @@
+
+
+
+
+ App
+
+
+ Dashboard
+ Visão Geral
+
+
+
+ System Cleaner
+ Limpador do Sistema
+
+
+
+ System Startup Apps
+ Aplicativos de Inicialização
+
+
+
+ System Services
+ Serviços
+
+
+
+ Uninstaller
+ Desinstalador
+
+
+
+ Resources
+ Recursos
+
+
+
+ Processes
+ Processos
+
+
+
+ Settings
+ Configurações
+
+
+
+ DashboardPage
+
+
+ SYSTEM INFO
+ INFORMAÇÃO DO SISTEMA
+
+
+
+ There are update currently available.
+ Há atualizações disponíveis.
+
+
+
+ Download
+ Download
+
+
+
+ CPU
+ CPU
+
+
+
+ MEMORY
+ MEMÓRIA
+
+
+
+ DISK
+ DISCO
+
+
+
+ DOWNLOAD
+ DOWNLOAD
+
+
+
+ UPLOAD
+ UPLOAD
+
+
+
+ Hostname: %1
+ Nome de usuário: %1
+
+
+
+ Platform: %1
+ Plataforma: %1
+
+
+
+ Distribution: %1
+ Distribuição: %1
+
+
+
+ Kernel Release: %1
+ Lançamento do Kernel: %1
+
+
+
+ CPU Model: %1
+ Modelo do CPU: %1
+
+
+
+ CPU Speed: %1
+ Velocidade do CPU: %1
+
+
+
+ CPU Core: %1
+ Núcleos do CPU: %1
+
+
+
+
+ Total: %1
+ Total: %1
+
+
+
+ ProcessesPage
+
+
+ Processes
+ Processos
+
+
+
+ All Processes
+ Todos os Processos
+
+
+
+ Search...
+ Pesquisa...
+
+
+
+ End Process
+ Processo Final
+
+
+
+ User
+ Usuário
+
+
+
+ Resident Memory
+ Memória Residente
+
+
+
+ %Memory
+ %Memória
+
+
+
+ Virtual Memory
+ Memória Virtual
+
+
+
+ Start Time
+ Hora de Início
+
+
+
+ State
+ Estado
+
+
+
+ Group
+ Grupo
+
+
+
+ Nice
+ Agradável
+
+
+
+ CPU Time
+ CPU Tempo
+
+
+
+ Session
+ Sessão
+
+
+
+ Seat
+ Assento
+
+
+
+ Process
+ Processo
+
+
+
+ Processes (%1)
+ Processos (%1)
+
+
+
+ Refresh (%1)
+ Atualizar (%1)
+
+
+
+ ResourcesPage
+
+
+ CPU History
+ História da CPU
+
+
+
+ Memory History
+ História da Memória
+
+
+
+ Network History
+ História da Rede
+
+
+
+ Download %1/s Total: %2
+ Download %1/s Total: %2
+
+
+
+ Upload %1/s Total: %2
+ Upload %1/s Total: %2
+
+
+
+ Swap %1 (%2%) %3
+ Troca %1 (%2%) %3
+
+
+
+ Memory %1 (%2%) %3
+ Memória %1 (%2%) %3
+
+
+
+ ServicesPage
+
+
+ System Services
+ Serviços de Sistema
+
+
+
+ Startup at boot ?
+ Startup no arranque?
+
+
+
+ Running Now ?
+ Correndo Agora?
+
+
+
+ Not Found System Service
+ Serviço do Sistema Não Encontrado
+
+
+
+ System Services (%1)
+ Serviços de Sistema (%1)
+
+
+
+ SettingsPage
+
+
+ Language
+ Linguagem
+
+
+
+ Theme
+ Tema
+
+
+
+ StartupApp
+
+
+ Delete
+ Excluir
+
+
+
+ Edit
+ Editar
+
+
+
+ StartupAppEdit
+
+
+ Startup App
+ Aplicação de Inicialização
+
+
+
+ Save
+ Salve
+
+
+
+ Fields cannot be left blank.
+ Os campos não podem ser deixados em branco.
+
+
+
+ App Comment
+ Comentário do Aplicativo
+
+
+
+ App Name
+ Nome do Aplicativo
+
+
+
+ Command
+ Comando
+
+
+
+ Application
+ Aplicação
+
+
+
+ StartupAppsPage
+
+
+ Not Found Startup Apps
+ Não Foram Encontrados Aplicativos de Icialização
+
+
+
+ System Startup Applications
+ Aplicações de Inicialização do Sistema
+
+
+
+ Add Startup App
+ Adicionar Aplicativo de Inicialização
+
+
+
+ System Startup Applications (%1)
+ Aplicações de Inicialização do Sistema (%1)
+
+
+
+ SystemCleanerPage
+
+
+ Crash Reports
+ Crash Reports
+
+
+
+ Application Logs
+ Logs de Aplicativos
+
+
+
+ Application Caches
+ Caches de Aplicação
+
+
+
+ Trash
+ Lixo
+
+
+
+ Package Caches
+ Pacote Caches
+
+
+
+ Back
+ Costas
+
+
+
+ File Name
+ Nome do Arquivo
+
+
+
+ Size
+ Tamanho
+
+
+
+ %1 size files cleaned.
+ %1 arquivos de tamanho limpos.
+
+
+
+ UninstallerPage
+
+
+ System Installed Packages
+ Pacotes Instalados no Sistema
+
+
+
+ Search...
+ Pesquisa...
+
+
+
+ Not Found Installed Packages
+ Pacotes Instalados Não Encontrados
+
+
+
+ Uninstall Selected
+ Desinstalar Selecionado
+
+
+
+ System Installed Packages (%1)
+ Pacotes Instalados no Sistema (%1)
+
+
+
diff --git a/translations/stacer_sv.ts b/translations/stacer_sv.ts
new file mode 100644
index 0000000..70b38c9
--- /dev/null
+++ b/translations/stacer_sv.ts
@@ -0,0 +1,453 @@
+
+
+
+
+ App
+
+
+ Dashboard
+ Instrumentbräda
+
+
+
+ System Cleaner
+ Systemrensare
+
+
+
+ System Startup Apps
+ Uppstart Appar
+
+
+
+ System Services
+ Tjänster
+
+
+
+ Uninstaller
+ Avinstallerare
+
+
+
+ Resources
+ Resurser
+
+
+
+ Processes
+ Processer
+
+
+
+ Settings
+ Inställningar
+
+
+
+ DashboardPage
+
+
+ SYSTEM INFO
+ SYSTEM INFO
+
+
+
+ There are update currently available.
+ Det finns förnärvarande tillgängliga uppdateringar.
+
+
+
+ Download
+ Ladda Ner
+
+
+
+ CPU
+ CPU
+
+
+
+ MEMORY
+ MINNE
+
+
+
+ DISK
+ DISK
+
+
+
+ DOWNLOAD
+ LADDA UPP
+
+
+
+ UPLOAD
+ LADDA UPP
+
+
+
+ Hostname: %1
+ Värdnamn: %1
+
+
+
+ Platform: %1
+ Plattform: %1
+
+
+
+ Distribution: %1
+ Distribution: %1
+
+
+
+ Kernel Release: %1
+ Kernelutgåva: %1
+
+
+
+ CPU Model: %1
+ CPU-modell: %1
+
+
+
+ CPU Speed: %1
+ CPU-hastighet: %1
+
+
+
+ CPU Core: %1
+ CPU-kärnor: %1
+
+
+
+
+ Total: %1
+ Total: %1
+
+
+
+ ProcessesPage
+
+
+ Processes
+ Processer
+
+
+
+ All Processes
+ Alla Processer
+
+
+
+ Search...
+ Sök...
+
+
+
+ End Process
+ Avsluta Process
+
+
+
+ Resident Memory
+ Bosatt Minne
+
+
+
+ %Memory
+ %Minne
+
+
+
+ Virtual Memory
+ Virtuell Minne
+
+
+
+ User
+ Användare
+
+
+
+ Start Time
+ Starttid
+
+
+
+ State
+ Stat
+
+
+
+ Group
+ Grupp
+
+
+
+ Nice
+ Trevlig
+
+
+
+ CPU Time
+ CPU Tid
+
+
+
+ Session
+ Session
+
+
+
+ Seat
+ Sittplats
+
+
+
+ Process
+ Process
+
+
+
+ Processes (%1)
+ Processer (%1)
+
+
+
+ Refresh (%1)
+ Uppdateras (%1)
+
+
+
+ ResourcesPage
+
+
+ CPU History
+ CPU-Historik
+
+
+
+ Memory History
+ Minneshistorik
+
+
+
+ Network History
+ Nätverkshistorik
+
+
+
+ Download %1/s Total: %2
+ Nerladdning %1/s Total: %2
+
+
+
+ Upload %1/s Total: %2
+ Ladda Upp %1/s Total: %2
+
+
+
+ Swap %1 (%2%) %3
+ Byte %1 (%2%) %3
+
+
+
+ Memory %1 (%2%) %3
+ Minne %1 (%2%) %3
+
+
+
+ ServicesPage
+
+
+ System Services
+ Systemtjänster
+
+
+
+ Startup at boot ?
+ Uppstart vid start?
+
+
+
+ Running Now ?
+ Kör nu?
+
+
+
+ Not Found System Service
+ Inte Hittad Systemtjänst
+
+
+
+ System Services (%1)
+ Systemtjänster (%1)
+
+
+
+ SettingsPage
+
+
+ Language
+ Språk
+
+
+
+ Theme
+ Tema
+
+
+
+ StartupApp
+
+
+ Delete
+ Radera
+
+
+
+ Edit
+ Redigera
+
+
+
+ StartupAppEdit
+
+
+ Startup App
+ Startprogram
+
+
+
+ Save
+ Spara
+
+
+
+ Fields cannot be left blank.
+ Fält kan inte lämnas tomt.
+
+
+
+ App Comment
+ Appkommentar
+
+
+
+ App Name
+ Appnamn
+
+
+
+ Command
+ Kommando
+
+
+
+ Application
+ Ansökan
+
+
+
+ StartupAppsPage
+
+
+ Add Startup App
+ Lägg Till Startprogrammet
+
+
+
+ System Startup Applications
+ Systemstart Program
+
+
+
+ Not Found Startup Apps
+ Ej Hittade Startprogram
+
+
+
+ System Startup Applications (%1)
+ Systemstart Program (%1)
+
+
+
+ SystemCleanerPage
+
+
+ Crash Reports
+ Kraschrapporter
+
+
+
+ Application Logs
+ Applikations Loggar
+
+
+
+ Application Caches
+ Application Caches
+
+
+
+ Trash
+ Skräp
+
+
+
+ Package Caches
+ Paket Caches
+
+
+
+ Back
+ Tillbaka
+
+
+
+ File Name
+ Filnamn
+
+
+
+ Size
+ Storlek
+
+
+
+ %1 size files cleaned.
+ %1 storlek filer rengöras.
+
+
+
+ UninstallerPage
+
+
+ Uninstall Selected
+ Avinstallera Vald
+
+
+
+ Not Found Installed Packages
+ Ej Hittade Installerade Paket
+
+
+
+ System Installed Packages
+ System Installerade Paket
+
+
+
+ Search...
+ Sök...
+
+
+
+ System Installed Packages (%1)
+ System Installerade Paket (%1)
+
+
+
diff --git a/translations/stacer_tr.ts b/translations/stacer_tr.ts
new file mode 100644
index 0000000..ca12883
--- /dev/null
+++ b/translations/stacer_tr.ts
@@ -0,0 +1,453 @@
+
+
+
+
+ App
+
+
+ Dashboard
+ Genel
+
+
+
+ System Cleaner
+ Sistem Temizleyici
+
+
+
+ System Startup Apps
+ Başlangıç Uygulamaları
+
+
+
+ System Services
+ Servisler
+
+
+
+ Uninstaller
+ Kaldırıcı
+
+
+
+ Resources
+ Kaynaklar
+
+
+
+ Processes
+ İşlemler
+
+
+
+ Settings
+ Ayarlar
+
+
+
+ DashboardPage
+
+
+ SYSTEM INFO
+ SİSTEM BİLGİLERİ
+
+
+
+ There are update currently available.
+ Şu anda mevcut güncelleme var.
+
+
+
+ Download
+ İndir
+
+
+
+ CPU
+ CPU
+
+
+
+ MEMORY
+ BELLEK
+
+
+
+ DISK
+ DİSK
+
+
+
+ DOWNLOAD
+ İNDİRME
+
+
+
+ UPLOAD
+ YÜKLEME
+
+
+
+ Hostname: %1
+ Bilgisayar Adı: %1
+
+
+
+ Platform: %1
+ Platform: %1
+
+
+
+ Distribution: %1
+ Dağıtım: %1
+
+
+
+ Kernel Release: %1
+ Çekirdek Sürümü: %1
+
+
+
+ CPU Model: %1
+ CPU Modeli: %1
+
+
+
+ CPU Speed: %1
+ CPU Hızı: %1
+
+
+
+ CPU Core: %1
+ CPU Çekirdek: %1
+
+
+
+
+ Total: %1
+ Toplam: %1
+
+
+
+ ProcessesPage
+
+
+ Processes
+ İşlemler
+
+
+
+ All Processes
+ Bütün İşlemler
+
+
+
+ Search...
+ Arama...
+
+
+
+ End Process
+ İşlemi Sonlandır
+
+
+
+ User
+ Kullanıcı
+
+
+
+ Resident Memory
+ Yerleşmiş Bellek
+
+
+
+ %Memory
+ %Bellek
+
+
+
+ Virtual Memory
+ Sanal Bellek
+
+
+
+ Start Time
+ Başlangıç Zamanı
+
+
+
+ State
+ Durum
+
+
+
+ Group
+ Grup
+
+
+
+ Nice
+ Güzel
+
+
+
+ CPU Time
+ CPU Zamanı
+
+
+
+ Session
+ Oturum
+
+
+
+ Seat
+ Yer
+
+
+
+ Process
+ İşlem
+
+
+
+ Processes (%1)
+ İşlemler (%1)
+
+
+
+ Refresh (%1)
+ Yenile (%1)
+
+
+
+ ResourcesPage
+
+
+ CPU History
+ CPU Geçmişi
+
+
+
+ Memory History
+ Bellek Geçmişi
+
+
+
+ Network History
+ Ağ Geçmişi
+
+
+
+ Download %1/s Total: %2
+ İndirme %1/s Toplam: %2
+
+
+
+ Upload %1/s Total: %2
+ Yükleme %1/s Toplam: %2
+
+
+
+ Swap %1 (%2%) %3
+ Takas %1 (%2%) %3
+
+
+
+ Memory %1 (%2%) %3
+ Bellek %1 (%2%) %3
+
+
+
+ ServicesPage
+
+
+ System Services
+ Sistem Servisleri
+
+
+
+ Startup at boot ?
+ Açılışta başlatma ?
+
+
+
+ Running Now ?
+ Şimdi Çalışıyor ?
+
+
+
+ Not Found System Service
+ Sistem Servisi Bulunamadı
+
+
+
+ System Services (%1)
+ Sistem Servisleri (%1)
+
+
+
+ SettingsPage
+
+
+ Language
+ Dil
+
+
+
+ Theme
+ Tema
+
+
+
+ StartupApp
+
+
+ Delete
+ Sil
+
+
+
+ Edit
+ Düzenle
+
+
+
+ StartupAppEdit
+
+
+ Startup App
+ Başlangıç Uygulaması
+
+
+
+ Save
+ Kaydet
+
+
+
+ Fields cannot be left blank.
+ Alanları boş bırakmayın.
+
+
+
+ App Comment
+ Uygulama Yorum
+
+
+
+ App Name
+ Uygulama Adı
+
+
+
+ Command
+ Komut
+
+
+
+ Application
+ Uygulama
+
+
+
+ StartupAppsPage
+
+
+ Not Found Startup Apps
+ Başlangıç Uygulaması Bulunamadı
+
+
+
+ System Startup Applications
+ Sistem Başlangıç Uygulamaları
+
+
+
+ Add Startup App
+ Başlangıç Uygulaması Ekle
+
+
+
+ System Startup Applications (%1)
+ Sistem Başlangıç Uygulamaları (%1)
+
+
+
+ SystemCleanerPage
+
+
+ Crash Reports
+ Kilitlenme Raporları
+
+
+
+ Application Logs
+ Uygulama Günlükleri
+
+
+
+ Application Caches
+ Uygulama Önbellekleri
+
+
+
+ Trash
+ Çöp
+
+
+
+ Package Caches
+ Paket Önbellekleri
+
+
+
+ Back
+ Geri
+
+
+
+ File Name
+ Dosya Adı
+
+
+
+ Size
+ Boyut
+
+
+
+ %1 size files cleaned.
+ %1 boyutunda dosya temizlendi.
+
+
+
+ UninstallerPage
+
+
+ System Installed Packages
+ Sistemde Yüklü Uygulamalar
+
+
+
+ Search...
+ Arama...
+
+
+
+ Not Found Installed Packages
+ Yüklü Uygulama Bulunamadı
+
+
+
+ Uninstall Selected
+ Seçilenleri Kaldır
+
+
+
+ System Installed Packages (%1)
+ Sistemde Yüklü Uygulamalar (%1)
+
+
+