diff options
| -rw-r--r-- | installer/background.svg | 153 | ||||
| -rw-r--r-- | installer/fadestackedwidget.cpp | 57 | ||||
| -rw-r--r-- | installer/fadestackedwidget.h | 29 | ||||
| -rw-r--r-- | installer/icon-bp.svg | 133 | ||||
| -rw-r--r-- | installer/icon.svg | 133 | ||||
| -rw-r--r-- | installer/installer.pro | 53 | ||||
| -rw-r--r-- | installer/main.cpp | 35 | ||||
| -rw-r--r-- | installer/mainwindow.cpp | 228 | ||||
| -rw-r--r-- | installer/mainwindow.h | 67 | ||||
| -rw-r--r-- | installer/mainwindow.ui | 807 | ||||
| -rw-r--r-- | installer/process/installworker.cpp | 78 | ||||
| -rw-r--r-- | installer/process/installworker.h | 35 | ||||
| -rw-r--r-- | installer/resources.qrc | 8 | ||||
| -rw-r--r-- | installer/translations/vi_VN.qm | bin | 0 -> 1522 bytes | |||
| -rw-r--r-- | theInstaller.pro | 4 |
15 files changed, 1820 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 Binary files differnew file mode 100644 index 0000000..39207f8 --- /dev/null +++ b/installer/translations/vi_VN.qm diff --git a/theInstaller.pro b/theInstaller.pro new file mode 100644 index 0000000..ada38ed --- /dev/null +++ b/theInstaller.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs + +SUBDIRS = \ + installer |
