aboutsummaryrefslogtreecommitdiff
path: root/installer
diff options
context:
space:
mode:
Diffstat (limited to 'installer')
-rw-r--r--installer/background.svg153
-rw-r--r--installer/fadestackedwidget.cpp57
-rw-r--r--installer/fadestackedwidget.h29
-rw-r--r--installer/icon-bp.svg133
-rw-r--r--installer/icon.svg133
-rw-r--r--installer/installer.pro53
-rw-r--r--installer/main.cpp35
-rw-r--r--installer/mainwindow.cpp228
-rw-r--r--installer/mainwindow.h67
-rw-r--r--installer/mainwindow.ui807
-rw-r--r--installer/process/installworker.cpp78
-rw-r--r--installer/process/installworker.h35
-rw-r--r--installer/resources.qrc8
-rw-r--r--installer/translations/vi_VN.qmbin0 -> 1522 bytes
14 files changed, 1816 insertions, 0 deletions
diff --git a/installer/background.svg b/installer/background.svg
new file mode 100644
index 0000000..4c7bf3f
--- /dev/null
+++ b/installer/background.svg
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="600"
+ height="420"
+ viewBox="0 0 158.74999 111.125"
+ version="1.1"
+ id="svg8"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="background.svg"
+ inkscape:export-filename="/Users/victor/Documents/Apps/theSlate/app-dmg-background@2x.png"
+ inkscape:export-xdpi="192"
+ inkscape:export-ydpi="192">
+ <defs
+ id="defs2">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient1506">
+ <stop
+ style="stop-color:#ff7d00;stop-opacity:1"
+ offset="0"
+ id="stop1502" />
+ <stop
+ style="stop-color:#ffc800;stop-opacity:1"
+ offset="1"
+ id="stop1504" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient1466">
+ <stop
+ style="stop-color:#ff6400;stop-opacity:1"
+ offset="0"
+ id="stop1462" />
+ <stop
+ style="stop-color:#ffaf00;stop-opacity:1"
+ offset="1"
+ id="stop1464" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1466"
+ id="linearGradient1468"
+ x1="0"
+ y1="296.99997"
+ x2="158.74998"
+ y2="185.87498"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1506"
+ id="linearGradient1508"
+ x1="0"
+ y1="296.99997"
+ x2="158.74998"
+ y2="185.87498"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.4142136"
+ inkscape:cx="260.01537"
+ inkscape:cy="198.91979"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:window-width="1920"
+ inkscape:window-height="1017"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid10"
+ empspacing="4"
+ spacingx="1.3229166"
+ spacingy="1.3229167"
+ color="#3f3fff"
+ opacity="0.1254902"
+ dotted="false" />
+ <inkscape:grid
+ type="xygrid"
+ id="grid3703"
+ dotted="true"
+ spacingy="5.2916665"
+ spacingx="5.2916665"
+ originy="2.6458333"
+ originx="2.6458333"
+ empspacing="1" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-185.87498)">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.35558617;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect4627"
+ width="158.74998"
+ height="111.12499"
+ x="3.3306688e-016"
+ y="185.87498" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-weight:normal;font-size:10.5003252px;line-height:1.25;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26250812"
+ x="78.584435"
+ y="215.60774"
+ id="text3726"
+ transform="scale(1.0079052,0.99215676)"><tspan
+ sodipodi:role="line"
+ x="78.584435"
+ y="215.60774"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Contemporary;-inkscape-font-specification:Contemporary;text-align:center;text-anchor:middle;stroke-width:0.26250812"
+ id="tspan4566">Application Name</tspan></text>
+ <path
+ style="fill:url(#linearGradient1468);stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="m 0,286.41665 31.749997,-5.29167 26.458333,7.9375 47.625,-10.58333 52.91666,7.9375 v 10.58333 H 0 Z"
+ id="path917"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient1508);stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="M 158.74999,286.41665 105.83333,278.47915 0,302.29165 h 158.74999 z"
+ id="path1500"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/installer/fadestackedwidget.cpp b/installer/fadestackedwidget.cpp
new file mode 100644
index 0000000..e925c99
--- /dev/null
+++ b/installer/fadestackedwidget.cpp
@@ -0,0 +1,57 @@
+#include "fadestackedwidget.h"
+
+FadeStackedWidget::FadeStackedWidget(QWidget *parent) : QStackedWidget(parent)
+{
+
+}
+
+void FadeStackedWidget::setCurrentIndex(int index) {
+ //Do some checks before setting the current index.
+ if (currentIndex() != index) {
+ doSetCurrentIndex(index);
+ }
+}
+
+void FadeStackedWidget::doSetCurrentIndex(int index) {
+ QWidget* currentWidget = widget(currentIndex());
+ QWidget* nextWidget = widget(index);
+ if (nextWidget == nullptr) {
+ QStackedWidget::setCurrentIndex(index);
+ } else {
+ if (doingNewAnimation) {
+ anim->stop();
+ anim->deleteLater();
+ }
+
+ doingNewAnimation = true;
+ QGraphicsOpacityEffect* currentOpacity = new QGraphicsOpacityEffect();
+ QGraphicsOpacityEffect* nextOpacity = new QGraphicsOpacityEffect();
+ currentWidget->setGraphicsEffect(currentOpacity);
+ nextWidget->setGraphicsEffect(nextOpacity);
+
+ anim = new QVariantAnimation();
+ anim->setStartValue((float) 1);
+ anim->setEndValue((float) 0);
+ anim->setDuration(500);
+ anim->setEasingCurve(QEasingCurve::InCubic);
+ connect(anim, &QVariantAnimation::finished, [=] {
+ if (anim->direction() == QVariantAnimation::Forward) {
+ anim->setDirection(QVariantAnimation::Backward);
+ QStackedWidget::setCurrentIndex(index);
+ anim->start();
+ } else {
+ doingNewAnimation = false;
+ anim->deleteLater();
+ anim = nullptr;
+ }
+ });
+ connect(anim, &QVariantAnimation::valueChanged, [=](QVariant value) {
+ if (anim->direction() == QVariantAnimation::Forward) {
+ currentOpacity->setOpacity(value.toFloat());
+ } else {
+ nextOpacity->setOpacity(value.toFloat());
+ }
+ });
+ anim->start();
+ }
+}
diff --git a/installer/fadestackedwidget.h b/installer/fadestackedwidget.h
new file mode 100644
index 0000000..9f43ba2
--- /dev/null
+++ b/installer/fadestackedwidget.h
@@ -0,0 +1,29 @@
+#ifndef FADESTACKEDWIDGET_H
+#define FADESTACKEDWIDGET_H
+
+#include <QObject>
+#include <QWidget>
+#include <QStackedWidget>
+#include <QVariantAnimation>
+#include <QGraphicsOpacityEffect>
+
+class FadeStackedWidget : public QStackedWidget
+{
+ Q_OBJECT
+public:
+ explicit FadeStackedWidget(QWidget *parent = nullptr);
+
+signals:
+
+public slots:
+ void setCurrentIndex(int index);
+
+private slots:
+ void doSetCurrentIndex(int index);
+
+private:
+ bool doingNewAnimation = false;
+ QVariantAnimation* anim;
+};
+
+#endif // FADESTACKEDWIDGET_H
diff --git a/installer/icon-bp.svg b/installer/icon-bp.svg
new file mode 100644
index 0000000..0184f82
--- /dev/null
+++ b/installer/icon-bp.svg
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="32"
+ height="32"
+ viewBox="0 0 8.4666665 8.4666669"
+ version="1.1"
+ id="svg8"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="icon-bp.svg">
+ <defs
+ id="defs2">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient20">
+ <stop
+ style="stop-color:#0064ff;stop-opacity:1"
+ offset="0"
+ id="stop16" />
+ <stop
+ style="stop-color:#00c8ff;stop-opacity:1"
+ offset="1"
+ id="stop18" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20"
+ id="linearGradient22"
+ x1="0"
+ y1="297"
+ x2="8.4666662"
+ y2="288.53333"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="15.839192"
+ inkscape:cx="12.806446"
+ inkscape:cy="19.016536"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:window-width="1920"
+ inkscape:window-height="1017"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid10"
+ empspacing="4" />
+ <inkscape:grid
+ type="xygrid"
+ id="grid12"
+ empspacing="1"
+ dotted="true"
+ originy="0.13229167"
+ originx="0.13229167" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-288.53332)">
+ <circle
+ id="path14"
+ cx="4.2333331"
+ cy="292.76666"
+ r="4.2333331"
+ style="stroke-width:0.26458332;fill-opacity:1;fill:url(#linearGradient22)" />
+ <g
+ aria-label="An"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.90897703px;line-height:1.25;font-family:Contemporary;-inkscape-font-specification:Contemporary;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.12272441"
+ id="text835">
+ <path
+ d="m 1.8721493,293.44243 -0.2552668,0.65289 q -0.044181,0.12273 -0.1914501,0.12273 H 1.2438002 q -0.044181,0 -0.078544,-0.0295 -0.029454,-0.0344 -0.029454,-0.0785 0,-0.0245 0.019636,-0.0687 l 1.2026994,-3.09756 q 0.063817,-0.162 0.220904,-0.162 h 0.2945386 q 0.1570872,0 0.220904,0.162 l 1.1977903,3.09756 q 0.019636,0.0442 0.019636,0.0687 0,0.0442 -0.034363,0.0785 -0.029454,0.0295 -0.073635,0.0295 H 4.0222812 q -0.1472693,0 -0.1914501,-0.12273 l -0.2552668,-0.65289 z m 1.5316008,-0.44181 -0.6774388,-1.7525 -0.6823478,1.7525 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Contemporary;-inkscape-font-specification:Contemporary;stroke-width:0.12272441"
+ id="path846" />
+ <path
+ d="m 7.02995,294.08551 q 0,0.054 -0.039272,0.0933 -0.039272,0.0393 -0.093271,0.0393 H 6.7157755 q -0.053999,0 -0.093271,-0.0393 -0.039272,-0.0393 -0.039272,-0.0933 v -1.29597 q 0,-0.36818 -0.1816321,-0.55963 -0.1816322,-0.19145 -0.5056247,-0.19145 -0.3190835,0 -0.5056246,0.19145 -0.1816322,0.19145 -0.1816322,0.55963 v 1.29597 q 0,0.054 -0.039272,0.0933 -0.039272,0.0393 -0.093271,0.0393 H 4.894545 q -0.053999,0 -0.093271,-0.0393 -0.039272,-0.0393 -0.039272,-0.0933 v -2.28759 q 0,-0.054 0.039272,-0.0933 0.039272,-0.0393 0.093271,-0.0393 h 0.1816322 q 0.053999,0 0.093271,0.0393 0.039272,0.0393 0.039272,0.0933 v 0.15218 q 0.1079975,-0.14236 0.2945387,-0.23563 0.1914501,-0.0982 0.4663528,-0.0982 0.3092655,0 0.5498054,0.13254 0.2405399,0.13255 0.3730823,0.3829 0.1374513,0.24545 0.1374513,0.58417 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Contemporary;-inkscape-font-specification:Contemporary;stroke-width:0.12272441"
+ id="path848" />
+ </g>
+ <g
+ aria-label="Icon"
+ style="font-style:normal;font-weight:normal;font-size:3.26337147px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.08158429"
+ id="text831">
+ <path
+ d="m 1.2271878,293.71405 q -0.035897,0 -0.062004,-0.0261 -0.026107,-0.0261 -0.026107,-0.062 v -2.10814 q 0,-0.0359 0.026107,-0.062 0.026107,-0.0261 0.062004,-0.0261 h 0.1337983 q 0.035897,0 0.062004,0.0261 0.026107,0.0261 0.026107,0.062 v 2.10814 q 0,0.0359 -0.026107,0.062 -0.026107,0.0261 -0.062004,0.0261 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Contemporary;-inkscape-font-specification:Contemporary;fill:#ffffff;fill-opacity:1;stroke-width:0.08158429"
+ id="path837" />
+ <path
+ d="m 2.6616945,293.46603 q 0.3263372,0 0.4405552,-0.25454 0.022844,-0.049 0.045687,-0.0685 0.022844,-0.0196 0.062004,-0.0196 h 0.097901 q 0.035897,0 0.062004,0.0261 0.026107,0.0228 0.026107,0.0555 0,0.11096 -0.088111,0.23823 -0.088111,0.12727 -0.254543,0.21538 -0.1664319,0.0881 -0.3916046,0.0881 -0.2316993,0 -0.4013947,-0.0979 -0.1696953,-0.0979 -0.2610697,-0.26759 -0.091374,-0.17296 -0.1011645,-0.38508 -0.00326,-0.0392 -0.00326,-0.15012 0,-0.0783 0.00326,-0.11095 0.02937,-0.33287 0.2251726,-0.54172 0.1958023,-0.20886 0.5384563,-0.20886 0.2251727,0 0.3883412,0.0881 0.166432,0.0849 0.2512796,0.21212 0.088111,0.12401 0.094638,0.23497 0.00326,0.0359 -0.026107,0.062 -0.026107,0.0261 -0.062004,0.0261 h -0.097901 q -0.03916,0 -0.062004,-0.0196 -0.022844,-0.0196 -0.045687,-0.0685 -0.114218,-0.25455 -0.4405552,-0.25455 -0.1794854,0 -0.3132836,0.12075 -0.1337983,0.12074 -0.1533785,0.3655 -0.00326,0.0359 -0.00326,0.11748 0,0.0751 0.00326,0.11095 0.022844,0.24475 0.1533785,0.3655 0.1337982,0.12074 0.3132836,0.12074 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Contemporary;-inkscape-font-specification:Contemporary;fill:#ffffff;fill-opacity:1;stroke-width:0.08158429"
+ id="path839" />
+ <path
+ d="m 5.2550551,292.7122 q 0.00653,0.0718 0.00653,0.15664 0,0.0783 -0.00653,0.15011 -0.02937,0.33287 -0.2316994,0.53193 -0.1990657,0.1958 -0.5417197,0.1958 -0.342654,0 -0.544983,-0.1958 -0.1990657,-0.19906 -0.228436,-0.53193 -0.00326,-0.0359 -0.00326,-0.15011 0,-0.12075 0.00326,-0.15664 0.026107,-0.33287 0.228436,-0.52867 0.202329,-0.19907 0.544983,-0.19907 0.342654,0 0.5449831,0.19907 0.202329,0.1958 0.228436,0.52867 z m -0.2969668,0.0163 q -0.01958,-0.20885 -0.140325,-0.33613 -0.1174814,-0.12727 -0.3361273,-0.12727 -0.2186458,0 -0.3393906,0.12727 -0.1174814,0.12728 -0.1370616,0.33613 -0.00326,0.0392 -0.00326,0.14033 0,0.0979 0.00326,0.1338 0.01958,0.20885 0.1370616,0.33612 0.1207448,0.12727 0.3393906,0.12727 0.2186459,0 0.3361273,-0.12727 0.1207447,-0.12727 0.140325,-0.33612 0.00653,-0.0718 0.00653,-0.1338 0,-0.062 -0.00653,-0.14033 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Contemporary;-inkscape-font-specification:Contemporary;fill:#ffffff;fill-opacity:1;stroke-width:0.08158429"
+ id="path841" />
+ <path
+ d="m 7.1744784,293.62594 q 0,0.0359 -0.026107,0.062 -0.026107,0.0261 -0.062004,0.0261 H 6.9656226 q -0.035897,0 -0.062004,-0.0261 -0.026107,-0.0261 -0.026107,-0.062 v -0.86153 q 0,-0.24475 -0.1207448,-0.37203 -0.1207447,-0.12727 -0.3361272,-0.12727 -0.2121192,0 -0.3361273,0.12727 -0.1207447,0.12728 -0.1207447,0.37203 v 0.86153 q 0,0.0359 -0.026107,0.062 -0.026107,0.0261 -0.062004,0.0261 H 5.7549118 q -0.035897,0 -0.062004,-0.0261 -0.026107,-0.0261 -0.026107,-0.062 v -1.52073 q 0,-0.0359 0.026107,-0.062 0.026107,-0.0261 0.062004,-0.0261 h 0.1207447 q 0.035897,0 0.062004,0.0261 0.026107,0.0261 0.026107,0.062 v 0.10116 q 0.071794,-0.0946 0.1958023,-0.15664 0.1272715,-0.0653 0.3100203,-0.0653 0.2055924,0 0.3654976,0.0881 0.1599052,0.0881 0.2480162,0.25455 0.091374,0.16317 0.091374,0.38834 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Contemporary;-inkscape-font-specification:Contemporary;fill:#ffffff;fill-opacity:1;stroke-width:0.08158429"
+ id="path843" />
+ </g>
+ </g>
+</svg>
diff --git a/installer/icon.svg b/installer/icon.svg
new file mode 100644
index 0000000..b70191e
--- /dev/null
+++ b/installer/icon.svg
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="32"
+ height="32"
+ viewBox="0 0 8.4666665 8.4666669"
+ version="1.1"
+ id="svg8"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="icon.svg">
+ <defs
+ id="defs2">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient20">
+ <stop
+ style="stop-color:#ff6400;stop-opacity:1"
+ offset="0"
+ id="stop16" />
+ <stop
+ style="stop-color:#ffc800;stop-opacity:1"
+ offset="1"
+ id="stop18" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20"
+ id="linearGradient22"
+ x1="0"
+ y1="297"
+ x2="8.4666662"
+ y2="288.53333"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="15.839192"
+ inkscape:cx="12.806446"
+ inkscape:cy="19.016536"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:window-width="1920"
+ inkscape:window-height="1017"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid10"
+ empspacing="4" />
+ <inkscape:grid
+ type="xygrid"
+ id="grid12"
+ empspacing="1"
+ dotted="true"
+ originy="0.13229167"
+ originx="0.13229167" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-288.53332)">
+ <circle
+ id="path14"
+ cx="4.2333331"
+ cy="292.76666"
+ r="4.2333331"
+ style="stroke-width:0.26458332;fill-opacity:1;fill:url(#linearGradient22)" />
+ <g
+ aria-label="An"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.90897703px;line-height:1.25;font-family:Contemporary;-inkscape-font-specification:Contemporary;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.12272441"
+ id="text835">
+ <path
+ d="m 1.8721493,293.44243 -0.2552668,0.65289 q -0.044181,0.12273 -0.1914501,0.12273 H 1.2438002 q -0.044181,0 -0.078544,-0.0295 -0.029454,-0.0344 -0.029454,-0.0785 0,-0.0245 0.019636,-0.0687 l 1.2026994,-3.09756 q 0.063817,-0.162 0.220904,-0.162 h 0.2945386 q 0.1570872,0 0.220904,0.162 l 1.1977903,3.09756 q 0.019636,0.0442 0.019636,0.0687 0,0.0442 -0.034363,0.0785 -0.029454,0.0295 -0.073635,0.0295 H 4.0222812 q -0.1472693,0 -0.1914501,-0.12273 l -0.2552668,-0.65289 z m 1.5316008,-0.44181 -0.6774388,-1.7525 -0.6823478,1.7525 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Contemporary;-inkscape-font-specification:Contemporary;stroke-width:0.12272441"
+ id="path846" />
+ <path
+ d="m 7.02995,294.08551 q 0,0.054 -0.039272,0.0933 -0.039272,0.0393 -0.093271,0.0393 H 6.7157755 q -0.053999,0 -0.093271,-0.0393 -0.039272,-0.0393 -0.039272,-0.0933 v -1.29597 q 0,-0.36818 -0.1816321,-0.55963 -0.1816322,-0.19145 -0.5056247,-0.19145 -0.3190835,0 -0.5056246,0.19145 -0.1816322,0.19145 -0.1816322,0.55963 v 1.29597 q 0,0.054 -0.039272,0.0933 -0.039272,0.0393 -0.093271,0.0393 H 4.894545 q -0.053999,0 -0.093271,-0.0393 -0.039272,-0.0393 -0.039272,-0.0933 v -2.28759 q 0,-0.054 0.039272,-0.0933 0.039272,-0.0393 0.093271,-0.0393 h 0.1816322 q 0.053999,0 0.093271,0.0393 0.039272,0.0393 0.039272,0.0933 v 0.15218 q 0.1079975,-0.14236 0.2945387,-0.23563 0.1914501,-0.0982 0.4663528,-0.0982 0.3092655,0 0.5498054,0.13254 0.2405399,0.13255 0.3730823,0.3829 0.1374513,0.24545 0.1374513,0.58417 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Contemporary;-inkscape-font-specification:Contemporary;stroke-width:0.12272441"
+ id="path848" />
+ </g>
+ <g
+ aria-label="Icon"
+ style="font-style:normal;font-weight:normal;font-size:3.26337147px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.08158429"
+ id="text831">
+ <path
+ d="m 1.2271878,293.71405 q -0.035897,0 -0.062004,-0.0261 -0.026107,-0.0261 -0.026107,-0.062 v -2.10814 q 0,-0.0359 0.026107,-0.062 0.026107,-0.0261 0.062004,-0.0261 h 0.1337983 q 0.035897,0 0.062004,0.0261 0.026107,0.0261 0.026107,0.062 v 2.10814 q 0,0.0359 -0.026107,0.062 -0.026107,0.0261 -0.062004,0.0261 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Contemporary;-inkscape-font-specification:Contemporary;fill:#ffffff;fill-opacity:1;stroke-width:0.08158429"
+ id="path837" />
+ <path
+ d="m 2.6616945,293.46603 q 0.3263372,0 0.4405552,-0.25454 0.022844,-0.049 0.045687,-0.0685 0.022844,-0.0196 0.062004,-0.0196 h 0.097901 q 0.035897,0 0.062004,0.0261 0.026107,0.0228 0.026107,0.0555 0,0.11096 -0.088111,0.23823 -0.088111,0.12727 -0.254543,0.21538 -0.1664319,0.0881 -0.3916046,0.0881 -0.2316993,0 -0.4013947,-0.0979 -0.1696953,-0.0979 -0.2610697,-0.26759 -0.091374,-0.17296 -0.1011645,-0.38508 -0.00326,-0.0392 -0.00326,-0.15012 0,-0.0783 0.00326,-0.11095 0.02937,-0.33287 0.2251726,-0.54172 0.1958023,-0.20886 0.5384563,-0.20886 0.2251727,0 0.3883412,0.0881 0.166432,0.0849 0.2512796,0.21212 0.088111,0.12401 0.094638,0.23497 0.00326,0.0359 -0.026107,0.062 -0.026107,0.0261 -0.062004,0.0261 h -0.097901 q -0.03916,0 -0.062004,-0.0196 -0.022844,-0.0196 -0.045687,-0.0685 -0.114218,-0.25455 -0.4405552,-0.25455 -0.1794854,0 -0.3132836,0.12075 -0.1337983,0.12074 -0.1533785,0.3655 -0.00326,0.0359 -0.00326,0.11748 0,0.0751 0.00326,0.11095 0.022844,0.24475 0.1533785,0.3655 0.1337982,0.12074 0.3132836,0.12074 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Contemporary;-inkscape-font-specification:Contemporary;fill:#ffffff;fill-opacity:1;stroke-width:0.08158429"
+ id="path839" />
+ <path
+ d="m 5.2550551,292.7122 q 0.00653,0.0718 0.00653,0.15664 0,0.0783 -0.00653,0.15011 -0.02937,0.33287 -0.2316994,0.53193 -0.1990657,0.1958 -0.5417197,0.1958 -0.342654,0 -0.544983,-0.1958 -0.1990657,-0.19906 -0.228436,-0.53193 -0.00326,-0.0359 -0.00326,-0.15011 0,-0.12075 0.00326,-0.15664 0.026107,-0.33287 0.228436,-0.52867 0.202329,-0.19907 0.544983,-0.19907 0.342654,0 0.5449831,0.19907 0.202329,0.1958 0.228436,0.52867 z m -0.2969668,0.0163 q -0.01958,-0.20885 -0.140325,-0.33613 -0.1174814,-0.12727 -0.3361273,-0.12727 -0.2186458,0 -0.3393906,0.12727 -0.1174814,0.12728 -0.1370616,0.33613 -0.00326,0.0392 -0.00326,0.14033 0,0.0979 0.00326,0.1338 0.01958,0.20885 0.1370616,0.33612 0.1207448,0.12727 0.3393906,0.12727 0.2186459,0 0.3361273,-0.12727 0.1207447,-0.12727 0.140325,-0.33612 0.00653,-0.0718 0.00653,-0.1338 0,-0.062 -0.00653,-0.14033 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Contemporary;-inkscape-font-specification:Contemporary;fill:#ffffff;fill-opacity:1;stroke-width:0.08158429"
+ id="path841" />
+ <path
+ d="m 7.1744784,293.62594 q 0,0.0359 -0.026107,0.062 -0.026107,0.0261 -0.062004,0.0261 H 6.9656226 q -0.035897,0 -0.062004,-0.0261 -0.026107,-0.0261 -0.026107,-0.062 v -0.86153 q 0,-0.24475 -0.1207448,-0.37203 -0.1207447,-0.12727 -0.3361272,-0.12727 -0.2121192,0 -0.3361273,0.12727 -0.1207447,0.12728 -0.1207447,0.37203 v 0.86153 q 0,0.0359 -0.026107,0.062 -0.026107,0.0261 -0.062004,0.0261 H 5.7549118 q -0.035897,0 -0.062004,-0.0261 -0.026107,-0.0261 -0.026107,-0.062 v -1.52073 q 0,-0.0359 0.026107,-0.062 0.026107,-0.0261 0.062004,-0.0261 h 0.1207447 q 0.035897,0 0.062004,0.0261 0.026107,0.0261 0.026107,0.062 v 0.10116 q 0.071794,-0.0946 0.1958023,-0.15664 0.1272715,-0.0653 0.3100203,-0.0653 0.2055924,0 0.3654976,0.0881 0.1599052,0.0881 0.2480162,0.25455 0.091374,0.16317 0.091374,0.38834 z"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Contemporary;-inkscape-font-specification:Contemporary;fill:#ffffff;fill-opacity:1;stroke-width:0.08158429"
+ id="path843" />
+ </g>
+ </g>
+</svg>
diff --git a/installer/installer.pro b/installer/installer.pro
new file mode 100644
index 0000000..2725738
--- /dev/null
+++ b/installer/installer.pro
@@ -0,0 +1,53 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2018-07-10T19:50:12
+#
+#-------------------------------------------------
+
+QT += core gui network svg
+CONFIG += static
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = installer
+TEMPLATE = app
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which has 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
+
+#DEFINES += INSTALLER_METADATA_URL=\\\"http://localhost:8000/installer.json\\\"
+DEFINES += INSTALLER_METADATA_URL=\\\"http://vicr123.com/theslate/theinstaller/installer.json\\\"
+
+SOURCES += \
+ main.cpp \
+ mainwindow.cpp \
+ fadestackedwidget.cpp \
+ process/installworker.cpp
+
+HEADERS += \
+ mainwindow.h \
+ fadestackedwidget.h \
+ process/installworker.h
+
+FORMS += \
+ mainwindow.ui
+
+TRANSLATIONS += \
+ translations/vi_VN.ts
+
+win32 {
+ #CONFIG += embed_manifest_exe
+ #QMAKE_LFLAGS_WINDOWS += /MANIFESTUAC:level=\'requireAdministrator\'
+}
+
+RESOURCES += \
+ resources.qrc
+
diff --git a/installer/main.cpp b/installer/main.cpp
new file mode 100644
index 0000000..4b62834
--- /dev/null
+++ b/installer/main.cpp
@@ -0,0 +1,35 @@
+#include "mainwindow.h"
+#include "process/installworker.h"
+#include <QApplication>
+#include <QTranslator>
+#include <QLibraryInfo>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+
+ QTranslator qtTranslator;
+ qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
+ a.installTranslator(&qtTranslator);
+
+ QTranslator myappTranslator;
+ myappTranslator.load(QLocale::system().name(), ":/translations/");
+ //myappTranslator.load("vi_VN", ":/translations/");
+ a.installTranslator(&myappTranslator);
+
+ qsrand(QDateTime::currentMSecsSinceEpoch());
+
+ if (a.arguments().contains("--install")) {
+ //Installer mode
+ InstallWorker worker;
+ if (!worker.startWork()) return 1;
+
+ a.setQuitOnLastWindowClosed(false);
+ return a.exec();
+ }
+
+ MainWindow w;
+ w.show();
+
+ return a.exec();
+}
diff --git a/installer/mainwindow.cpp b/installer/mainwindow.cpp
new file mode 100644
index 0000000..9bdb6d4
--- /dev/null
+++ b/installer/mainwindow.cpp
@@ -0,0 +1,228 @@
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+
+MainWindow::MainWindow(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::MainWindow)
+{
+ ui->setupUi(this);
+
+ this->setFixedSize(this->size());
+ backgroundImage = QIcon(":/background.svg").pixmap(this->size());
+
+ //ui->appIcon->setPixmap(QIcon(":/icon.svg").pixmap(128, 128));
+ ui->installButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_VistaShield));
+ ui->installButton_2->setIcon(QApplication::style()->standardIcon(QStyle::SP_VistaShield));
+
+ getInstallerMetadata();
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+void MainWindow::getInstallerMetadata() {
+ ui->stack->setCurrentIndex(0);
+
+ QTimer::singleShot(1000, [=] {
+ QNetworkRequest req(QUrl(INSTALLER_METADATA_URL));
+ req.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
+ QNetworkReply* reply = mgr.get(req);
+ connect(reply, &QNetworkReply::finished, [=] {
+ if (reply->error() != QNetworkReply::NoError) return;
+
+ QJsonDocument doc = QJsonDocument::fromJson(reply->readAll());
+ if (!doc.isObject()) {
+ ui->metadataErrorLabel->setText(tr("Invalid metadata was received"));
+ ui->stack->setCurrentIndex(1);
+ return;
+ }
+
+ QJsonObject obj = doc.object();
+ if (!obj.contains("name") || !obj.contains("vendor")) {
+ ui->metadataErrorLabel->setText(tr("Application name not in metadata"));
+ ui->stack->setCurrentIndex(1);
+ return;
+ }
+
+ if (!obj.contains("blueprint")) {
+ ui->streamLabel->setVisible(false);
+ ui->streamContainer->setVisible(false);
+ }
+
+ ui->openCheckbox->setText(tr("Open %1").arg(obj.value("name").toString()));
+ this->setWindowTitle(tr("Install %1").arg(obj.value("name").toString()));
+
+ this->metadata = obj;
+ setInstallPath();
+
+ ui->stack->setCurrentIndex(2);
+ });
+ connect(reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error), [=](QNetworkReply::NetworkError code) {
+ ui->metadataErrorLabel->setText(tr("Couldn't retrieve metadata"));
+ ui->stack->setCurrentIndex(1);
+ });
+ connect(reply, &QNetworkReply::sslErrors, [=](QList<QSslError> errors) {
+ ui->metadataErrorLabel->setText(tr("Couldn't connect securely to the server"));
+ ui->stack->setCurrentIndex(1);
+ });
+ });
+}
+
+void MainWindow::setInstallPath() {
+ QString tail = metadata.value("vendor").toString() + "\\" + metadata.value("name").toString() + "\\";
+ if (ui->installEveryone->isChecked()) {
+ ui->installPathLineEdit->setText(qgetenv("PROGRAMFILES") + "\\" + tail);
+ ui->installButton_2->setIcon(QApplication::style()->standardIcon(QStyle::SP_VistaShield));
+ } else {
+ ui->installPathLineEdit->setText(qgetenv("LOCALAPPDATA") + "\\Programs\\" + tail);
+ ui->installButton_2->setIcon(QIcon());
+ }
+}
+
+void MainWindow::paintEvent(QPaintEvent *event) {
+ QPainter p(this);
+ p.drawPixmap(0, 0, backgroundImage);
+}
+
+void MainWindow::on_installOptions_clicked()
+{
+ ui->stack->setCurrentIndex(3);
+}
+
+void MainWindow::on_cancelMetadataButton_clicked()
+{
+ this->close();
+}
+
+void MainWindow::on_retryMetadataButton_clicked()
+{
+ getInstallerMetadata();
+}
+
+void MainWindow::on_installEveryone_toggled(bool checked)
+{
+ setInstallPath();
+}
+
+void MainWindow::on_installButton_clicked()
+{
+ this->setWindowFlag(Qt::WindowCloseButtonHint, false);
+ this->show();
+
+ ui->stack->setCurrentIndex(4);
+ ui->statusLabel->setText(tr("Getting ready to install %1...").arg(metadata.value("name").toString()));
+
+ QLocalServer* socketServer = new QLocalServer();
+
+ QString serverNumber = QString::number(qrand());
+ if (QApplication::arguments().contains("--server-only")) {
+ serverNumber = QApplication::arguments().at(QApplication::arguments().indexOf("--server-only") + 1);
+ }
+
+ socketServer->listen("theinstaller." + metadata.value("vendor").toString() + "." + metadata.value("name").toString() + "." + serverNumber);
+ connect(socketServer, &QLocalServer::newConnection, [=] {
+ QLocalSocket* sock = socketServer->nextPendingConnection();
+
+ connect(sock, &QLocalSocket::readyRead, [=] {
+ QStringList lines = QString(sock->readAll()).split("\n");
+ for (QString line : lines) {
+ QStringList parts = line.split(" ");
+ if (parts.at(0) == "PING") {
+ QMessageBox::warning(this, "Ping!", "Ping received", QMessageBox::Ok, QMessageBox::Ok);
+ } else if (parts.at(0) == "STATUS") {
+ parts.takeFirst();
+ ui->statusLabel->setText(parts.join(" "));
+ } else if (parts.at(0) == "PROGRESS") {
+ ui->installProgress->setMaximum(parts.at(2).toLongLong());
+ ui->installProgress->setValue(parts.at(1).toLongLong());
+ } else if (parts.at(0) == "DEBUG") {
+ parts.takeFirst();
+ qDebug() << parts.join(" ");
+ }
+ }
+ });
+ connect(sock, &QLocalSocket::disconnected, [=] {
+ this->setWindowFlag(Qt::WindowCloseButtonHint, true);
+ this->show();
+ ui->stack->setCurrentIndex(6);
+ });
+
+ socketServer->close();
+ });
+
+ if (QApplication::arguments().contains("--server-only")) {
+ QMessageBox::warning(this, "Socket Server", socketServer->serverName(), QMessageBox::Ok, QMessageBox::Ok);
+ } else {
+ QStringList args;
+ args.append("\"--install\"");
+ args.append("\"--socket " + socketServer->serverName() + "\"");
+ args.append("\"--vendor " + metadata.value("vendor").toString() + "\"");
+ args.append("\"--name " + metadata.value("name").toString() + "\"");
+
+ QString destdir = ui->installPathLineEdit->text();
+ if (destdir.endsWith("\\")) {
+ destdir.append("\\");
+ }
+ args.append("\"--destdir \"\"" + destdir + "\"\"\"");
+
+ if (ui->stableStream->isChecked()) {
+ args.append("\"--stable\"");
+ args.append("\"--url " + metadata.value("stable").toObject().value("packageUrl").toString() + "\"");
+ } else {
+ args.append("\"--blueprint\"");
+ args.append("\"--url " + metadata.value("blueprint").toObject().value("packageUrl").toString() + "\"");
+ }
+
+ if (ui->installEveryone->isChecked()) {
+ args.append("\"--global\"");
+ } else {
+ args.append("\"--local\"");
+ }
+
+ QStringList psArgs;
+ psArgs.append("-FilePath \"" + QApplication::applicationFilePath() + "\"");
+ psArgs.append("-ArgumentList (" + args.join(",") + ")");
+ psArgs.append("-Verb runAs");
+ psArgs.append("-PassThru");
+ psArgs.append("-Wait");
+
+ QString encodedCommand = "Start-Process " + psArgs.join(" ") + "";
+ QProcess* proc = new QProcess();
+ proc->setProcessChannelMode(QProcess::ForwardedChannels);
+
+ QString command = "powershell -EncodedCommand " + QByteArray::fromRawData((const char*) encodedCommand.utf16(), encodedCommand.size() * 2).toBase64();
+ qDebug() << "PowerShell Command: " + encodedCommand;
+ qDebug() << "Executing " + command;
+ proc->start(command);
+ connect(proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), [=](int exitCode, QProcess::ExitStatus exitStatus) {
+ this->setWindowFlag(Qt::WindowCloseButtonHint, true);
+ this->show();
+ if (!socketServer->isListening()) {
+ socketServer->close();
+ socketServer->deleteLater();
+
+ ui->stack->setCurrentIndex(5);
+ } else {
+ ui->stack->setCurrentIndex(6);
+ }
+ proc->deleteLater();
+ });
+ }
+}
+
+void MainWindow::on_installButton_2_clicked()
+{
+ on_installButton_clicked();
+}
+
+void MainWindow::on_exitButton_clicked()
+{
+ this->close();
+}
+
+void MainWindow::on_retryInstallButton_clicked()
+{
+ getInstallerMetadata();
+}
diff --git a/installer/mainwindow.h b/installer/mainwindow.h
new file mode 100644
index 0000000..dcfd34f
--- /dev/null
+++ b/installer/mainwindow.h
@@ -0,0 +1,67 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <QNetworkAccessManager>
+#include <QPaintEvent>
+#include <QPainter>
+#include <QStyle>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QTimer>
+#include <QStandardPaths>
+#include <QDebug>
+#include <QProcess>
+#include <QLocalServer>
+#include <QLocalSocket>
+#include <QMessageBox>
+
+#include <windows.h>
+#include <shellapi.h>
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+
+private slots:
+ void on_installOptions_clicked();
+
+ void getInstallerMetadata();
+
+ void setInstallPath();
+
+ void on_cancelMetadataButton_clicked();
+
+ void on_retryMetadataButton_clicked();
+
+ void on_installEveryone_toggled(bool checked);
+
+ void on_installButton_clicked();
+
+ void on_installButton_2_clicked();
+
+ void on_exitButton_clicked();
+
+ void on_retryInstallButton_clicked();
+
+private:
+ Ui::MainWindow *ui;
+
+ void paintEvent(QPaintEvent* event);
+
+ QNetworkAccessManager mgr;
+ QPixmap backgroundImage;
+ QJsonObject metadata;
+};
+
+#endif // MAINWINDOW_H
diff --git a/installer/mainwindow.ui b/installer/mainwindow.ui
new file mode 100644
index 0000000..722e7df
--- /dev/null
+++ b/installer/mainwindow.ui
@@ -0,0 +1,807 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>420</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string notr="true">theInstaller</string>
+ </property>
+ <property name="windowIcon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/icon.svg</normaloff>:/icon.svg</iconset>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="FadeStackedWidget" name="stack">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="page_3">
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <spacer name="verticalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>270</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="gettingReadyLabel">
+ <property name="text">
+ <string>Getting ready...</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_6">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="page_4">
+ <layout class="QVBoxLayout" name="verticalLayout_6">
+ <item>
+ <spacer name="verticalSpacer_7">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>250</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="font">
+ <font>
+ <pointsize>20</pointsize>
+ </font>
+ </property>
+ <property name="text">
+ <string>This shouldn't be happening...</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="metadataErrorLabel">
+ <property name="text">
+ <string notr="true">Invalid metadata was received from the server</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
+ <item>
+ <spacer name="horizontalSpacer_6">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelMetadataButton">
+ <property name="text">
+ <string>Cancel Installation</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="retryMetadataButton">
+ <property name="text">
+ <string>Retry</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_7">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_8">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="page">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>280</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_11">
+ <item>
+ <spacer name="horizontalSpacer_15">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="installButton">
+ <property name="font">
+ <font>
+ <pointsize>15</pointsize>
+ </font>
+ </property>
+ <property name="text">
+ <string>Install Now</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_14">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="installOptions">
+ <property name="text">
+ <string>Install Options</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="page_2">
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>150</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Install To</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="installPathLineEdit"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Install for</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="streamLabel">
+ <property name="text">
+ <string>Stream</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QPushButton" name="browseInstallPathButton">
+ <property name="text">
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2">
+ <widget class="QWidget" name="widget" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="installEveryone">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Everyone</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="installMe">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>This user only</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2">
+ <widget class="QWidget" name="streamContainer" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="stableStream">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Stable</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="blueprintStream">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Blueprint</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <spacer name="horizontalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="installButton_2">
+ <property name="text">
+ <string>Install Now</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>127</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="page_5">
+ <layout class="QVBoxLayout" name="verticalLayout_7">
+ <item>
+ <spacer name="verticalSpacer_9">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>270</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="statusLabel">
+ <property name="text">
+ <string notr="true">Getting ready to install...</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_7">
+ <property name="leftMargin">
+ <number>30</number>
+ </property>
+ <property name="rightMargin">
+ <number>30</number>
+ </property>
+ <item>
+ <widget class="QProgressBar" name="installProgress">
+ <property name="maximum">
+ <number>0</number>
+ </property>
+ <property name="value">
+ <number>-1</number>
+ </property>
+ <property name="textVisible">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_10">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="page_6">
+ <layout class="QVBoxLayout" name="verticalLayout_8">
+ <item>
+ <spacer name="verticalSpacer_11">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>270</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Installation is complete.</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_8">
+ <item>
+ <spacer name="horizontalSpacer_8">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="openCheckbox">
+ <property name="text">
+ <string notr="true">Open Application Name</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_9">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_9">
+ <item>
+ <spacer name="horizontalSpacer_10">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="finishButton">
+ <property name="text">
+ <string>Finish</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_11">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_12">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="page_7">
+ <layout class="QVBoxLayout" name="verticalLayout_9">
+ <item>
+ <spacer name="verticalSpacer_13">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>250</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Installation failed.</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_10">
+ <item>
+ <spacer name="horizontalSpacer_12">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="exitButton">
+ <property name="text">
+ <string>Exit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="retryInstallButton">
+ <property name="text">
+ <string>Try Again</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_13">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_14">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <customwidgets>
+ <customwidget>
+ <class>FadeStackedWidget</class>
+ <extends>QStackedWidget</extends>
+ <header>fadestackedwidget.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources>
+ <include location="resources.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/installer/process/installworker.cpp b/installer/process/installworker.cpp
new file mode 100644
index 0000000..48c7c10
--- /dev/null
+++ b/installer/process/installworker.cpp
@@ -0,0 +1,78 @@
+#include "installworker.h"
+
+InstallWorker::InstallWorker(QObject *parent) : QObject(parent)
+{
+}
+
+bool InstallWorker::startWork() {
+ QLocalSocket* sock = new QLocalSocket();
+ QString vendor, name, url, destPath;
+ bool isStableStream = true, isGlobalInstall = true;
+
+ QString previousToken;
+ for (QString arg : QApplication::arguments()) {
+ if (previousToken != "") {
+ if (previousToken == "--socket") {
+ sock->setServerName(arg);
+ } else if (previousToken == "--vendor") {
+ vendor = arg;
+ } else if (previousToken == "--name") {
+ name = arg;
+ } else if (previousToken == "--url") {
+ url = arg;
+ } else if (previousToken == "--destdir") {
+ destPath = arg;
+ }
+ previousToken = "";
+ } else {
+ if (arg == "--socket" || arg == "--vendor" || arg == "--name" || arg == "--url" || arg == "--destdir") {
+ previousToken = arg;
+ } else if (arg == "--blueprint") {
+ isStableStream = false;
+ } else if (arg == "--stable") {
+ isStableStream = true;
+ } else if (arg == "--local") {
+ isGlobalInstall = false;
+ } else if (arg == "--global") {
+ isGlobalInstall = true;
+ }
+ }
+ }
+
+ if (sock->serverName() == "") {
+ qDebug() << "Required argument --socket missing";
+ return false;
+ }
+
+ qDebug() << "Connecting to socket server...";
+ sock->connectToServer();
+ if (!sock->waitForConnected()) {
+ qDebug() << "Failed to connect to socket server";
+ return false;
+ }
+ connect(sock, &QLocalSocket::disconnected, [=] {
+ qDebug() << "Socket closed";
+ QApplication::exit(1);
+ });
+
+ if (!packageFile.open() || !packageTemporaryDir.isValid()) {
+ return false;
+ }
+ sock->write(QString("STATUS ").append(tr("Downloading %1...").arg(name)).append("\n").toUtf8());
+ sock->write(QString("DEBUG %1").arg(packageFile.fileName()).toUtf8());
+
+ QNetworkRequest req(QUrl((QString) url));
+ req.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
+ req.setHeader(QNetworkRequest::UserAgentHeader, "theInstaller/1.0");
+ QNetworkReply* reply = mgr.get(req);
+ connect(reply, &QNetworkReply::finished, [=] {
+ sock->write(QString("STATUS ").append(tr("Unpacking %1...").arg(name)).append("\n").toUtf8());
+ sock->write("PROGRESS 0 0\n");
+ sock->write(QString("DEBUG %1").arg(packageTemporaryDir.path()).toUtf8());
+ });
+ connect(reply, &QNetworkReply::downloadProgress, [=](qint64 bytesReceived, qint64 bytesTotal) {
+ sock->write(QString("PROGRESS %1 %2\n").arg(QString::number(bytesReceived), QString::number(bytesTotal)).toUtf8());
+ });
+
+ return true;
+}
diff --git a/installer/process/installworker.h b/installer/process/installworker.h
new file mode 100644
index 0000000..84cbc48
--- /dev/null
+++ b/installer/process/installworker.h
@@ -0,0 +1,35 @@
+#ifndef INSTALLWORKER_H
+#define INSTALLWORKER_H
+
+#include <QObject>
+#include <QTextStream>
+#include <QLocalSocket>
+#include <QDebug>
+#include <QApplication>
+#include <QThread>
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QTemporaryFile>
+#include <QTemporaryDir>
+
+#include <iostream>
+
+class InstallWorker : public QObject
+{
+ Q_OBJECT
+public:
+ explicit InstallWorker(QObject *parent = nullptr);
+
+signals:
+
+public slots:
+ bool startWork();
+
+private:
+ QNetworkAccessManager mgr;
+ QTemporaryFile packageFile;
+ QTemporaryDir packageTemporaryDir;
+};
+
+#endif // INSTALLWORKER_H
diff --git a/installer/resources.qrc b/installer/resources.qrc
new file mode 100644
index 0000000..661ed75
--- /dev/null
+++ b/installer/resources.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/">
+ <file>icon.svg</file>
+ <file>icon-bp.svg</file>
+ <file>background.svg</file>
+ <file>translations/vi_VN.qm</file>
+ </qresource>
+</RCC>
diff --git a/installer/translations/vi_VN.qm b/installer/translations/vi_VN.qm
new file mode 100644
index 0000000..39207f8
--- /dev/null
+++ b/installer/translations/vi_VN.qm
Binary files differ