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 +

+ +

+ + Awesome + + + Download Stacer + + + Platform (GNU/Linux) + +

+ +

+ + + +

+ +## 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) + + +