CLOUD: Add new connection wizard

- remove Options widgets of the old wizard;
- add CloudConnectionWizard dialog;
- remove old widgets and add new ones in the layouts;
- update local webserver to allow passing a callback that needs to be called if storage was connected via /connect_cloud.
This commit is contained in:
Alexander Tkachov 2023-04-01 14:24:46 +02:00 committed by Eugene Sandulenko
parent f08da80efa
commit f3149a9b5d
16 changed files with 1496 additions and 592 deletions

View File

@ -34,7 +34,7 @@
namespace Networking {
ConnectCloudHandler::ConnectCloudHandler() {}
ConnectCloudHandler::ConnectCloudHandler() : _storageConnectionCallback(nullptr) {}
ConnectCloudHandler::~ConnectCloudHandler() {}
@ -42,6 +42,11 @@ void ConnectCloudHandler::handle(Client &client) {
client.setHandler(new ConnectCloudClientHandler(this));
}
void ConnectCloudHandler::storageConnected(const Networking::ErrorResponse &response) const {
if (_storageConnectionCallback)
(*_storageConnectionCallback)(response);
}
//
ConnectCloudClientHandler::ConnectCloudClientHandler(const ConnectCloudHandler *cloudHandler):
@ -129,10 +134,11 @@ void ConnectCloudClientHandler::storageConnectionCallback(Networking::ErrorRespo
}
handleError(*_client, message, 200);
return;
} else {
handleSuccess(*_client, "Storage connected.");
}
handleSuccess(*_client, "Storage connected.");
_cloudHandler->storageConnected(response);
}
} // End of namespace Networking

View File

@ -33,12 +33,17 @@ class ConnectCloudHandler: public BaseHandler {
void handleError(Client &client, Common::String message) const;
void setJsonResponseHandler(Client &client, Common::String type, Common::String message) const;
Networking::ErrorCallback _storageConnectionCallback;
public:
ConnectCloudHandler();
virtual ~ConnectCloudHandler();
virtual void handle(Client &client);
virtual bool minimalModeSupported() { return true; }
void setStorageConnectionCallback(Networking::ErrorCallback cb) { _storageConnectionCallback = cb; }
void storageConnected(const Networking::ErrorResponse& response) const;
};
class ConnectCloudClientHandler : public ClientHandler {

View File

@ -109,6 +109,12 @@ public:
bool isRunning();
static uint32 getPort();
#ifdef USE_CLOUD
#ifdef USE_LIBCURL
void setStorageConnectionCallback(Networking::ErrorCallback cb) { _connectCloudHandler.setStorageConnectionCallback(cb); }
#endif // USE_LIBCURL
#endif // USE_CLOUD
static void setClientGetHandler(Client &client, Common::String response, long code = 200, const char *mimeType = nullptr);
static void setClientGetHandler(Client &client, Common::SeekableReadStream *responseStream, long code = 200, const char *mimeType = nullptr);
static void setClientRedirectHandler(Client &client, Common::String response, Common::String location, const char *mimeType = nullptr);

View File

@ -0,0 +1,656 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "gui/cloudconnectionwizard.h"
#include "backends/cloud/cloudmanager.h"
#ifdef USE_SDL_NET
#include "backends/networking/sdl_net/localwebserver.h"
#endif // USE_SDL_NET
#include "common/formats/json.h"
#include "common/memstream.h"
#include "common/translation.h"
#include "gui/browser.h"
#include "gui/shaderbrowser-dialog.h"
#include "gui/themebrowser.h"
#include "gui/message.h"
#include "gui/gui-manager.h"
#include "gui/options.h"
#include "gui/widget.h"
#include "gui/widgets/edittext.h"
#include "gui/widgets/popup.h"
#include "gui/widgets/scrollcontainer.h"
#include "gui/widgets/tab.h"
#include "gui/ThemeEval.h"
namespace GUI {
enum {
kCloudConnectionWizardQuickModeButtonCmd = 'WQMb',
kCloudConnectionWizardManualModeButtonCmd = 'WMMb',
kCloudConnectionWizardBackButtonCmd = 'WSBb',
kCloudConnectionWizardNextButtonCmd = 'WSNb',
kCloudConnectionWizardRunServerButtonCmd = 'WRSb',
kCloudConnectionWizardOpenUrlStorageCmd = 'WOUb',
kCloudConnectionWizardReflowCmd = 'WRFb',
kCloudConnectionWizardPasteCodeCmd = 'WPCb',
};
CloudConnectionWizard::CloudConnectionWizard() :
Dialog("GlobalOptions_Cloud_ConnectionWizard"),
_currentStep(Step::NONE), _switchToSuccess(false), _switchToFailure(false),
_connecting(false) {
_backgroundType = GUI::ThemeEngine::kDialogBackgroundPlain;
_headlineLabel = new StaticTextWidget(this, "GlobalOptions_Cloud_ConnectionWizard.Headline", Common::U32String());
_closeButton = new ButtonWidget(this, "GlobalOptions_Cloud_ConnectionWizard.CancelButton", _("Cancel"), Common::U32String(), kCloseCmd);
_prevStepButton = nullptr;
_nextStepButton = nullptr;
_label0 = nullptr;
_label1 = nullptr;
_label2 = nullptr;
_label3 = nullptr;
_button0 = nullptr;
_container = nullptr;
_quickModeButton = nullptr;
_quickModeLabel = nullptr;
_manualModeButton = nullptr;
_codeBox = nullptr;
showStep(Step::MODE_SELECT);
_callback = new Common::Callback<CloudConnectionWizard, Networking::ErrorResponse>(this, &CloudConnectionWizard::storageConnectionCallback);
}
CloudConnectionWizard::~CloudConnectionWizard() {
#ifdef USE_SDL_NET
LocalServer.setStorageConnectionCallback(nullptr);
#endif // USE_SDL_NET
delete _callback;
}
void CloudConnectionWizard::showStep(Step newStep) {
if (newStep == _currentStep)
return;
switch (_currentStep) {
case Step::MODE_SELECT:
hideStepModeSelect();
break;
case Step::QUICK_MODE_STEP_1:
hideStepQuickMode1();
break;
case Step::QUICK_MODE_STEP_2:
hideStepQuickMode2();
break;
case Step::QUICK_MODE_SUCCESS:
hideStepQuickModeSuccess();
break;
case Step::MANUAL_MODE_STEP_1:
hideStepManualMode1();
break;
case Step::MANUAL_MODE_STEP_2:
hideStepManualMode2();
break;
case Step::MANUAL_MODE_FAILURE:
hideStepManualModeFailure();
break;
case Step::MANUAL_MODE_SUCCESS:
hideStepManualModeSuccess();
break;
}
_currentStep = newStep;
switch (_currentStep) {
case Step::MODE_SELECT:
showStepModeSelect();
break;
case Step::QUICK_MODE_STEP_1:
showStepQuickMode1();
break;
case Step::QUICK_MODE_STEP_2:
showStepQuickMode2();
break;
case Step::QUICK_MODE_SUCCESS:
showStepQuickModeSuccess();
break;
case Step::MANUAL_MODE_STEP_1:
showStepManualMode1();
break;
case Step::MANUAL_MODE_STEP_2:
showStepManualMode2();
break;
case Step::MANUAL_MODE_FAILURE:
showStepManualModeFailure();
break;
case Step::MANUAL_MODE_SUCCESS:
showStepManualModeSuccess();
break;
}
reflowLayout();
g_gui.scheduleTopDialogRedraw();
}
// mode select
void CloudConnectionWizard::showStepModeSelect() {
_headlineLabel->setLabel(_("Cloud Connection Wizard"));
showContainer("ConnectionWizard_ModeSelect");
_quickModeButton = new ButtonWidget(_container, "ConnectionWizard_ModeSelect.QuickModeButton", _("Quick mode"), Common::U32String(), kCloudConnectionWizardQuickModeButtonCmd);
_manualModeButton = new ButtonWidget(_container, "ConnectionWizard_ModeSelect.ManualModeButton", _("Manual mode"), Common::U32String(), kCloudConnectionWizardManualModeButtonCmd);
#ifdef USE_SDL_NET
_quickModeLabel = new StaticTextWidget(_container, "ConnectionWizard_ModeSelect.QuickModeHint", _("Will ask you to run Local Webserver"));
#else
_quickModeLabel = new StaticTextWidget(_container, "ConnectionWizard_ModeSelect.QuickModeHint", _("Requires Local Webserver feature"), Common::U32String(), ThemeEngine::kFontStyleNormal);
_quickModeLabel->setEnabled(false);
_quickModeButton->setEnabled(false);
#endif // USE_SDL_NET
}
void CloudConnectionWizard::hideStepModeSelect() {
hideContainer();
removeWidgetChecked(_quickModeButton);
removeWidgetChecked(_manualModeButton);
removeWidgetChecked(_quickModeLabel);
}
// quick mode
void CloudConnectionWizard::showStepQuickMode1() {
_headlineLabel->setLabel(_("Quick Mode: Step 1"));
showContainer("ConnectionWizard_QuickModeStep1");
showBackButton();
showNextButton();
_label0 = new StaticTextWidget(_container, "ConnectionWizard_QuickModeStep1.Line1", _("In this mode, Local Webserver must be running,"));
_label1 = new StaticTextWidget(_container, "ConnectionWizard_QuickModeStep1.Line2", _("so your browser could forward data to ScummVM"));
_button0 = new ButtonWidget(_container, "ConnectionWizard_QuickModeStep1.RunServerButton", Common::U32String(), Common::U32String(), kCloudConnectionWizardRunServerButtonCmd);
_label2 = new StaticTextWidget(_container, "ConnectionWizard_QuickModeStep1.ServerInfoLabel", Common::U32String());
refreshStepQuickMode1();
}
void CloudConnectionWizard::refreshStepQuickMode1(bool displayAsStopped) {
bool serverIsRunning = false;
#ifdef USE_SDL_NET
serverIsRunning = LocalServer.isRunning();
#endif // USE_SDL_NET
if (displayAsStopped)
serverIsRunning = false;
if (_nextStepButton)
_nextStepButton->setEnabled(serverIsRunning);
if (_button0) {
_button0->setLabel(_(serverIsRunning ? "Stop server" : "Run server"));
_button0->setTooltip(_(serverIsRunning ? "Stop local webserver" : "Run local webserver"));
}
if (_label2) {
_label2->setLabel(serverIsRunning ? LocalServer.getAddress() : _("Not running"));
}
}
void CloudConnectionWizard::hideStepQuickMode1() {
hideContainer();
hideBackButton();
hideNextButton();
removeWidgetChecked(_label0);
removeWidgetChecked(_label1);
removeWidgetChecked(_button0);
removeWidgetChecked(_label2);
}
void CloudConnectionWizard::showStepQuickMode2() {
_headlineLabel->setLabel(_("Quick Mode: Step 2"));
showContainer("ConnectionWizard_QuickModeStep2");
showBackButton();
_label0 = new StaticTextWidget(_container, "ConnectionWizard_QuickModeStep2.Line1", _("Now, open this link in your browser:"));
_button0 = new ButtonWidget(_container, "ConnectionWizard_QuickModeStep2.OpenLinkButton", Common::U32String("https://cloud.scummvm.org/"), _("Open URL"), kCloudConnectionWizardOpenUrlStorageCmd);
_label1 = new StaticTextWidget(_container, "ConnectionWizard_QuickModeStep2.Line2", _("It will automatically pass the data to ScummVM,"));
_label2 = new StaticTextWidget(_container, "ConnectionWizard_QuickModeStep2.Line3", _("and warn you should there be any errors."));
_label3 = new StaticTextWidget(_container, "ConnectionWizard_QuickModeStep2.Line4", Common::U32String(), Common::U32String(), ThemeEngine::kFontStyleNormal);
#ifdef USE_SDL_NET
_label3->setLabel(_("Local Webserver address: ") + Common::U32String(LocalServer.getAddress()));
_label3->setEnabled(false);
#endif // USE_SDL_NET
}
void CloudConnectionWizard::hideStepQuickMode2() {
hideContainer();
hideBackButton();
removeWidgetChecked(_label0);
removeWidgetChecked(_button0);
removeWidgetChecked(_label1);
removeWidgetChecked(_label2);
removeWidgetChecked(_label3);
}
void CloudConnectionWizard::showStepQuickModeSuccess() {
_headlineLabel->setLabel(_("Quick Mode: Success"));
showContainer("ConnectionWizard_Success");
_closeButton->setVisible(false);
_label0 = new StaticTextWidget(_container, "ConnectionWizard_Success.Line1", _("You cloud storage has been connected!"));
_button0 = new ButtonWidget(this, "GlobalOptions_Cloud_ConnectionWizard.FinishButton", _("Finish"), Common::U32String(), kCloseCmd);
}
void CloudConnectionWizard::hideStepQuickModeSuccess() {
hideContainer();
_closeButton->setVisible(true);
removeWidgetChecked(_label0);
removeWidgetChecked(_button0);
}
// manual mode
void CloudConnectionWizard::showStepManualMode1() {
_headlineLabel->setLabel(_("Manual Mode: Step 1"));
showContainer("ConnectionWizard_ManualModeStep1");
showBackButton();
showNextButton();
_label0 = new StaticTextWidget(_container, "ConnectionWizard_ManualModeStep1.Line1", _("Open this link in your browser:"));
_button0 = new ButtonWidget(_container, "ConnectionWizard_ManualModeStep1.OpenLinkButton", Common::U32String("https://cloud.scummvm.org/"), _("Open URL"), kCloudConnectionWizardOpenUrlStorageCmd);
_label1 = new StaticTextWidget(_container, "ConnectionWizard_ManualModeStep1.Line2", _("When it fails to pass the code to ScummVM,"));
_label2 = new StaticTextWidget(_container, "ConnectionWizard_ManualModeStep1.Line3", _("find it on Troubleshooting section of the page,"));
_label3 = new StaticTextWidget(_container, "ConnectionWizard_ManualModeStep1.Line4", _("and go to the next step here."));
}
void CloudConnectionWizard::hideStepManualMode1() {
hideContainer();
hideBackButton();
hideNextButton();
removeWidgetChecked(_label0);
removeWidgetChecked(_button0);
removeWidgetChecked(_label1);
removeWidgetChecked(_label2);
removeWidgetChecked(_label3);
}
void CloudConnectionWizard::showStepManualMode2() {
_headlineLabel->setLabel(_("Manual Mode: Step 2"));
showContainer("ConnectionWizard_ManualModeStep2");
showBackButton();
showNextButton();
_label0 = new StaticTextWidget(_container, "ConnectionWizard_ManualModeStep2.Line1", _("Copy the code from your browser here and press Next:"));
_codeBox = new EditTextWidget(_container, "ConnectionWizard_ManualModeStep2.CodeBox", Common::U32String(), Common::U32String(), 0, 0, ThemeEngine::kFontStyleConsole);
_button0 = new ButtonWidget(_container, "ConnectionWizard_ManualModeStep2.PasteButton", _("Paste"), _("Paste code from clipboard"), kCloudConnectionWizardPasteCodeCmd);
_label1 = new StaticTextWidget(_container, "ConnectionWizard_ManualModeStep2.Line2", Common::U32String());
}
void CloudConnectionWizard::hideStepManualMode2() {
hideContainer();
_closeButton->setEnabled(true);
hideBackButton();
hideNextButton();
removeWidgetChecked(_label0);
removeWidgetChecked(_codeBox);
removeWidgetChecked(_button0);
removeWidgetChecked(_label1);
}
void CloudConnectionWizard::showStepManualModeFailure() {
_headlineLabel->setLabel(_("Manual Mode: Something went wrong"));
showContainer("ConnectionWizard_Failure");
showBackButton();
_label0 = new StaticTextWidget(_container, "ConnectionWizard_Failure.Line1", _("Cloud storage was not connected."));
_label1 = new StaticTextWidget(_container, "ConnectionWizard_Failure.Line2", _("Make sure you copied the code correctly and try again."));
_label2 = new StaticTextWidget(_container, "ConnectionWizard_Failure.Line3", _("It it doesn't work, try from the beginning."));
_label3 = new StaticTextWidget(_container, "ConnectionWizard_Failure.Line4", _("Error message: ") + _errorMessage, Common::U32String(), ThemeEngine::kFontStyleNormal);
_label3->setEnabled(false);
}
void CloudConnectionWizard::hideStepManualModeFailure() {
hideContainer();
hideBackButton();
removeWidgetChecked(_label0);
removeWidgetChecked(_label1);
removeWidgetChecked(_label2);
removeWidgetChecked(_label3);
}
void CloudConnectionWizard::showStepManualModeSuccess() {
_headlineLabel->setLabel(_("Manual Mode: Success"));
showContainer("ConnectionWizard_Success");
_closeButton->setVisible(false);
_label0 = new StaticTextWidget(_container, "ConnectionWizard_Success.Line1", _("Your cloud storage has been connected!"));
_button0 = new ButtonWidget(this, "GlobalOptions_Cloud_ConnectionWizard.FinishButton", _("Finish"), Common::U32String(), kCloseCmd);
}
void CloudConnectionWizard::hideStepManualModeSuccess() {
hideContainer();
_closeButton->setVisible(true);
removeWidgetChecked(_label0);
removeWidgetChecked(_button0);
}
// utils
void CloudConnectionWizard::showContainer(const Common::String &dialogName) {
_container = new ScrollContainerWidget(this, "GlobalOptions_Cloud_ConnectionWizard.Container", dialogName, kCloudConnectionWizardReflowCmd);
_container->setTarget(this);
_container->setBackgroundType(ThemeEngine::kWidgetBackgroundNo);
}
void CloudConnectionWizard::hideContainer() {
removeWidgetChecked(_container);
}
void CloudConnectionWizard::showBackButton() {
_prevStepButton = new ButtonWidget(this, "GlobalOptions_Cloud_ConnectionWizard.PrevButton", _("Back"), Common::U32String(), kCloudConnectionWizardBackButtonCmd);
}
void CloudConnectionWizard::hideBackButton() {
removeWidgetChecked(_prevStepButton);
}
void CloudConnectionWizard::showNextButton() {
_nextStepButton = new ButtonWidget(this, "GlobalOptions_Cloud_ConnectionWizard.NextButton", _("Next"), Common::U32String(), kCloudConnectionWizardNextButtonCmd);
}
void CloudConnectionWizard::hideNextButton() {
removeWidgetChecked(_nextStepButton);
}
void CloudConnectionWizard::removeWidgetChecked(ScrollContainerWidget *&widget) {
if (widget) {
removeWidget(widget);
widget = nullptr;
}
}
void CloudConnectionWizard::removeWidgetChecked(ButtonWidget *&widget) {
if (widget) {
removeWidget(widget);
widget = nullptr;
}
}
void CloudConnectionWizard::removeWidgetChecked(StaticTextWidget *&widget) {
if (widget) {
removeWidget(widget);
widget = nullptr;
}
}
void CloudConnectionWizard::removeWidgetChecked(EditTextWidget *&widget) {
if (widget) {
removeWidget(widget);
widget = nullptr;
}
}
// logic
void CloudConnectionWizard::storageConnectionCallback(Networking::ErrorResponse response) {
if (response.failed || response.interrupted) {
return;
}
_switchToSuccess = true;
}
void CloudConnectionWizard::manualModeConnect() {
if (_connecting)
return;
if (_label1)
_label1->setLabel(Common::U32String());
// get the code entered
Common::String code = "";
if (_codeBox)
code = _codeBox->getEditString().encode();
if (code.size() == 0)
return;
// warn about other Storage working
if (CloudMan.isWorking()) {
bool cancel = true;
MessageDialog alert(_("Another Storage is working now. Do you want to interrupt it?"), _("Yes"), _("No"));
if (alert.runModal() == GUI::kMessageOK) {
if (CloudMan.isDownloading())
CloudMan.cancelDownload();
if (CloudMan.isSyncing())
CloudMan.cancelSync();
// I believe it still would return `true` here, but just in case
if (CloudMan.isWorking()) {
MessageDialog alert2(_("Wait until current Storage finishes up and try again."));
alert2.runModal();
} else {
cancel = false;
}
}
if (cancel) {
return;
}
}
// parse JSON and display message if failed
Common::MemoryWriteStreamDynamic jsonStream(DisposeAfterUse::YES);
jsonStream.write(code.c_str(), code.size());
char *contents = Common::JSON::getPreparedContents(jsonStream);
Common::JSONValue *json = Common::JSON::parse(contents);
if (json == nullptr) {
if (_label1)
_label1->setLabel(_("There is likely a mistake in the code."));
return;
}
// pass JSON to the manager
_connecting = true;
Networking::ErrorCallback callback = new Common::Callback<CloudConnectionWizard, Networking::ErrorResponse>(this, &CloudConnectionWizard::manualModeStorageConnectionCallback);
Networking::JsonResponse jsonResponse(nullptr, json);
if (!CloudMan.connectStorage(jsonResponse, callback)) { // no "storage" in JSON (or invalid one)
_connecting = false;
delete callback;
if (_label1)
_label1->setLabel(_("There is likely a mistake in the code."));
return;
}
// disable UI
if (_codeBox)
_codeBox->setEnabled(false);
if (_button0)
_button0->setEnabled(false);
if (_closeButton)
_closeButton->setEnabled(false);
if (_prevStepButton)
_prevStepButton->setEnabled(false);
if (_nextStepButton)
_nextStepButton->setEnabled(false);
}
void CloudConnectionWizard::manualModeStorageConnectionCallback(Networking::ErrorResponse response) {
if (response.failed || response.interrupted) {
if (response.failed) {
_errorMessage = _(response.response.c_str());
} else {
_errorMessage = _("Interrupted.");
}
_switchToFailure = true;
return;
}
_switchToSuccess = true;
}
// public
void CloudConnectionWizard::open() {
Dialog::open();
#ifdef USE_SDL_NET
LocalServer.setStorageConnectionCallback(_callback);
#endif // USE_SDL_NET
}
void CloudConnectionWizard::close() {
#ifdef USE_SDL_NET
LocalServer.setStorageConnectionCallback(nullptr);
#endif // USE_SDL_NET
Dialog::close();
}
void CloudConnectionWizard::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
switch (cmd) {
case kCloudConnectionWizardQuickModeButtonCmd:
showStep(Step::QUICK_MODE_STEP_1);
break;
case kCloudConnectionWizardManualModeButtonCmd:
showStep(Step::MANUAL_MODE_STEP_1);
break;
case kCloudConnectionWizardRunServerButtonCmd:
#ifdef USE_SDL_NET
if (LocalServer.isRunning()) {
LocalServer.stopOnIdle();
refreshStepQuickMode1(true);
} else {
LocalServer.start();
refreshStepQuickMode1();
}
#endif // USE_SDL_NET
break;
case kCloudConnectionWizardOpenUrlStorageCmd:
if (!g_system->openUrl("https://cloud.scummvm.org/")) {
MessageDialog alert(_("Failed to open URL!\nPlease navigate to this page manually."));
alert.runModal();
}
break;
case kCloudConnectionWizardPasteCodeCmd:
if (g_system->hasTextInClipboard()) {
Common::U32String message = g_system->getTextFromClipboard();
if (!message.empty()) {
_codeBox->setEditString(message);
}
}
break;
case kCloudConnectionWizardNextButtonCmd:
switch (_currentStep) {
case Step::QUICK_MODE_STEP_1:
showStep(Step::QUICK_MODE_STEP_2);
break;
case Step::MANUAL_MODE_STEP_1:
showStep(Step::MANUAL_MODE_STEP_2);
break;
case Step::MANUAL_MODE_STEP_2:
manualModeConnect();
break;
}
break;
case kCloudConnectionWizardBackButtonCmd:
switch (_currentStep) {
case Step::QUICK_MODE_STEP_1:
case Step::MANUAL_MODE_STEP_1:
showStep(Step::MODE_SELECT);
break;
case Step::QUICK_MODE_STEP_2:
showStep(Step::QUICK_MODE_STEP_1);
break;
case Step::MANUAL_MODE_STEP_2:
showStep(Step::MANUAL_MODE_STEP_1);
break;
case Step::MANUAL_MODE_FAILURE:
showStep(Step::MANUAL_MODE_STEP_2);
break;
}
break;
default:
Dialog::handleCommand(sender, cmd, data);
}
}
void CloudConnectionWizard::handleTickle() {
if (_connecting && _currentStep == Step::MANUAL_MODE_STEP_2) {
bool switched = false;
if (_switchToFailure) {
showStep(Step::MANUAL_MODE_FAILURE);
switched = true;
} else if (_switchToSuccess) {
showStep(Step::MANUAL_MODE_SUCCESS);
switched = true;
}
if (switched) {
_switchToFailure = false;
_switchToSuccess = false;
_connecting = false;
}
}
if (_switchToSuccess) {
showStep(Step::QUICK_MODE_SUCCESS);
_switchToSuccess = false;
}
Dialog::handleTickle();
}
} // End of namespace GUI

137
gui/cloudconnectionwizard.h Normal file
View File

@ -0,0 +1,137 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef GUI_CLOUDCONNECTIONWIZARD_H
#define GUI_CLOUDCONNECTIONWIZARD_H
#include "backends/networking/curl/request.h"
#include "common/str.h"
#include "common/ustr.h"
#include "gui/dialog.h"
namespace GUI {
class ScrollContainerWidget;
class StaticTextWidget;
class ButtonWidget;
class EditTextWidget;
class CloudConnectionWizard : public Dialog {
enum class Step {
NONE,
MODE_SELECT,
QUICK_MODE_STEP_1,
QUICK_MODE_STEP_2,
QUICK_MODE_SUCCESS,
MANUAL_MODE_STEP_1,
MANUAL_MODE_STEP_2,
MANUAL_MODE_FAILURE,
MANUAL_MODE_SUCCESS
};
// wizard flow
Step _currentStep;
bool _switchToSuccess;
bool _switchToFailure;
// state
Networking::ErrorCallback _callback;
bool _connecting;
Common::U32String _errorMessage;
// common and generic widgets
StaticTextWidget *_headlineLabel;
ButtonWidget *_closeButton;
ButtonWidget *_prevStepButton;
ButtonWidget *_nextStepButton;
StaticTextWidget *_label0;
StaticTextWidget *_label1;
StaticTextWidget *_label2;
StaticTextWidget *_label3;
ButtonWidget *_button0;
// specific widgets
ScrollContainerWidget *_container;
ButtonWidget *_quickModeButton;
StaticTextWidget *_quickModeLabel;
ButtonWidget *_manualModeButton;
EditTextWidget *_codeBox;
// wizard flow
void showStep(Step newStep);
void showStepModeSelect();
void hideStepModeSelect();
void showStepQuickMode1();
void refreshStepQuickMode1(bool displayAsStopped = false);
void hideStepQuickMode1();
void showStepQuickMode2();
void hideStepQuickMode2();
void showStepQuickModeSuccess();
void hideStepQuickModeSuccess();
void showStepManualMode1();
void hideStepManualMode1();
void showStepManualMode2();
void hideStepManualMode2();
void showStepManualModeFailure();
void hideStepManualModeFailure();
void showStepManualModeSuccess();
void hideStepManualModeSuccess();
// widgets utils
void showContainer(const Common::String &dialogName);
void hideContainer();
void showBackButton();
void hideBackButton();
void showNextButton();
void hideNextButton();
void removeWidgetChecked(ScrollContainerWidget *&widget);
void removeWidgetChecked(ButtonWidget *&widget);
void removeWidgetChecked(StaticTextWidget *&widget);
void removeWidgetChecked(EditTextWidget *&widget);
// logic
void storageConnectionCallback(Networking::ErrorResponse response);
void manualModeConnect();
void manualModeStorageConnectionCallback(Networking::ErrorResponse response);
public:
CloudConnectionWizard();
~CloudConnectionWizard() override;
void open() override;
void close() override;
void handleCommand(CommandSender *sender, uint32 cmd, uint32 data) override;
void handleTickle() override;
};
} // End of namespace GUI
#endif

View File

@ -47,6 +47,7 @@ MODULE_OBJS := \
ifdef USE_CLOUD
ifdef USE_LIBCURL
MODULE_OBJS += \
cloudconnectionwizard.o \
downloaddialog.o \
downloadpacksdialog.o \
remotebrowser.o

View File

@ -58,6 +58,7 @@
#ifdef USE_CLOUD
#ifdef USE_LIBCURL
#include "backends/cloud/cloudmanager.h"
#include "gui/cloudconnectionwizard.h"
#include "gui/downloaddialog.h"
#include "gui/downloadpacksdialog.h"
#endif
@ -129,12 +130,11 @@ enum {
kDownloadStorageCmd = 'dlst',
kRunServerCmd = 'rnsv',
kCloudTabContainerReflowCmd = 'ctcr',
kOpenCloudConnectionWizardCmd = 'OpCW',
kServerPortClearCmd = 'spcl',
kChooseRootDirCmd = 'chrp',
kRootPathClearCmd = 'clrp',
kConnectStorageCmd = 'Cnnt',
kOpenUrlStorageCmd = 'OpUr',
kPasteCodeStorageCmd = 'PsCd',
kDisconnectStorageCmd = 'DcSt',
kEnableStorageCmd = 'EnSt'
};
@ -2149,13 +2149,7 @@ GlobalOptionsDialog::GlobalOptionsDialog(LauncherDialog *launcher)
_connectingStorage = false;
_storageWizardNotConnectedHint = nullptr;
_storageWizardOpenLinkHint = nullptr;
_storageWizardLink = nullptr;
_storageWizardCodeHint = nullptr;
_storageWizardCodeBox = nullptr;
_storageWizardPasteButton = nullptr;
_storageWizardConnectButton = nullptr;
_storageWizardConnectionStatusHint = nullptr;
_redrawCloudTab = false;
#endif
#ifdef USE_SDL_NET
@ -2690,9 +2684,9 @@ void GlobalOptionsDialog::addCloudControls(GuiObject *boss, const Common::String
_storagePopUp->setSelected(_selectedStorageIndex);
if (lowres)
_storageDisabledHint = new StaticTextWidget(boss, prefix + "StorageDisabledHint", _c("4. Storage is not yet enabled. Verify that username is correct and enable it:", "lowres"));
_storageDisabledHint = new StaticTextWidget(boss, prefix + "StorageDisabledHint", _c("Storage is not yet enabled. Verify that username is correct and enable it:", "lowres"));
else
_storageDisabledHint = new StaticTextWidget(boss, prefix + "StorageDisabledHint", _("4. Storage is not yet enabled. Verify that username is correct and enable it:"));
_storageDisabledHint = new StaticTextWidget(boss, prefix + "StorageDisabledHint", _("Storage is not yet enabled. Verify that username is correct and enable it:"));
_storageEnableButton = new ButtonWidget(boss, prefix + "StorageEnableButton", _("Enable storage"), _("Confirm you want to use this account for this storage"), kEnableStorageCmd);
_storageUsernameDesc = new StaticTextWidget(boss, prefix + "StorageUsernameDesc", _("Username:"), _("Username used by this storage"));
@ -2722,19 +2716,10 @@ void GlobalOptionsDialog::addCloudControls(GuiObject *boss, const Common::String
_storageDisconnectButton = new ButtonWidget(boss, prefix + "DisconnectButton", _("Disconnect"), _("Stop using this storage on this device"), kDisconnectStorageCmd);
if (lowres)
_storageWizardNotConnectedHint = new StaticTextWidget(boss, prefix + "StorageWizardNotConnectedHint", _c("This storage is not connected yet! To connect,", "lowres"));
_storageWizardNotConnectedHint = new StaticTextWidget(boss, prefix + "StorageWizardNotConnectedHint", _c("This storage is not connected yet!", "lowres"));
else
_storageWizardNotConnectedHint = new StaticTextWidget(boss, prefix + "StorageWizardNotConnectedHint", _("This storage is not connected yet! To connect,"));
_storageWizardOpenLinkHint = new StaticTextWidget(boss, prefix + "StorageWizardOpenLinkHint", _("1. Open this link:"));
_storageWizardLink = new ButtonWidget(boss, prefix + "StorageWizardLink", Common::U32String("https://cloud.scummvm.org/"), _("Open URL"), kOpenUrlStorageCmd);
if (lowres)
_storageWizardCodeHint = new StaticTextWidget(boss, prefix + "StorageWizardCodeHint", _c("2. Get the code and enter it here:", "lowres"));
else
_storageWizardCodeHint = new StaticTextWidget(boss, prefix + "StorageWizardCodeHint", _("2. Get the code and enter it here:"));
_storageWizardCodeBox = new EditTextWidget(boss, prefix + "StorageWizardCodeBox", Common::U32String(), Common::U32String(), 0, 0, ThemeEngine::kFontStyleConsole);
_storageWizardPasteButton = new ButtonWidget(boss, prefix + "StorageWizardPasteButton", _("Paste"), _("Paste code from clipboard"), kPasteCodeStorageCmd);
_storageWizardConnectButton = new ButtonWidget(boss, prefix + "StorageWizardConnectButton", _("3. Connect"), _("Connect your cloud storage account"), kConnectStorageCmd);
_storageWizardConnectionStatusHint = new StaticTextWidget(boss, prefix + "StorageWizardConnectionStatusHint", Common::U32String("..."));
_storageWizardNotConnectedHint = new StaticTextWidget(boss, prefix + "StorageWizardNotConnectedHint", _("This storage is not connected yet!"));
_storageWizardConnectButton = new ButtonWidget(boss, prefix + "StorageWizardConnectButton", _("Connect"), _("Connect your cloud storage account"), kOpenCloudConnectionWizardCmd);
setupCloudTab();
}
@ -3320,9 +3305,14 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
setupCloudTab();
break;
}
case kOpenCloudConnectionWizardCmd: {
CloudConnectionWizard wizard;
wizard.runModal();
setupCloudTab();
reflowLayout();
break;
}
case kStoragePopUpCmd: {
if (_storageWizardCodeBox)
_storageWizardCodeBox->setEditString(Common::U32String());
// update container's scrollbar
reflowLayout();
break;
@ -3370,61 +3360,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
}
break;
}
case kPasteCodeStorageCmd: {
if (g_system->hasTextInClipboard()) {
Common::U32String message = g_system->getTextFromClipboard();
if (!message.empty()) {
_storageWizardCodeBox->setEditString(message);
_redrawCloudTab = true;
}
}
break;
}
case kConnectStorageCmd: {
Common::String code = "";
if (_storageWizardCodeBox)
code = _storageWizardCodeBox->getEditString().encode();
if (code.size() == 0)
return;
if (CloudMan.isWorking()) {
bool cancel = true;
MessageDialog alert(_("Another Storage is working now. Do you want to interrupt it?"), _("Yes"), _("No"));
if (alert.runModal() == GUI::kMessageOK) {
if (CloudMan.isDownloading())
CloudMan.cancelDownload();
if (CloudMan.isSyncing())
CloudMan.cancelSync();
// I believe it still would return `true` here, but just in case
if (CloudMan.isWorking()) {
MessageDialog alert2(_("Wait until current Storage finishes up and try again."));
alert2.runModal();
} else {
cancel = false;
}
}
if (cancel) {
return;
}
}
if (_storageWizardConnectionStatusHint)
_storageWizardConnectionStatusHint->setLabel(_("Connecting..."));
CloudMan.connectStorage(
_selectedStorageIndex, code,
new Common::Callback<GlobalOptionsDialog, Networking::ErrorResponse>(this, &GlobalOptionsDialog::storageConnectionCallback)
);
_connectingStorage = true;
_redrawCloudTab = true;
break;
}
case kDisconnectStorageCmd: {
if (_storageWizardCodeBox)
_storageWizardCodeBox->setEditString(Common::U32String());
if (_selectedStorageIndex == CloudMan.getStorageIndex() && CloudMan.isWorking()) {
bool cancel = true;
@ -3682,28 +3618,10 @@ void GlobalOptionsDialog::setupCloudTab() {
shown = (!shownConnectedInfo && shown);
bool wizardEnabled = !_connectingStorage;
if (_storageWizardNotConnectedHint) _storageWizardNotConnectedHint->setVisible(shown);
if (_storageWizardOpenLinkHint) _storageWizardOpenLinkHint->setVisible(shown);
if (_storageWizardLink) {
_storageWizardLink->setVisible(shown);
_storageWizardLink->setEnabled(g_system->hasFeature(OSystem::kFeatureOpenUrl) && wizardEnabled);
}
if (_storageWizardCodeHint) _storageWizardCodeHint->setVisible(shown);
if (_storageWizardCodeBox) {
_storageWizardCodeBox->setVisible(shown);
_storageWizardCodeBox->setEnabled(wizardEnabled);
}
if (_storageWizardPasteButton) {
_storageWizardPasteButton->setVisible(shown && g_system->hasFeature(OSystem::kFeatureClipboardSupport));
_storageWizardPasteButton->setEnabled(wizardEnabled);
}
if (_storageWizardConnectButton) {
_storageWizardConnectButton->setVisible(shown);
_storageWizardConnectButton->setEnabled(wizardEnabled);
}
if (_storageWizardConnectionStatusHint) {
_storageWizardConnectionStatusHint->setVisible(shown && _storageWizardConnectionStatusHint->getLabel() != "...");
_storageWizardConnectionStatusHint->setEnabled(wizardEnabled);
}
if (!shownConnectedInfo) {
if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.StorageDisabledHint", x, y, w, h))
@ -3714,13 +3632,7 @@ void GlobalOptionsDialog::setupCloudTab() {
shiftUp = y - shiftUp;
shiftWidget(_storageWizardNotConnectedHint, "GlobalOptions_Cloud_Container.StorageWizardNotConnectedHint", 0, -shiftUp);
shiftWidget(_storageWizardOpenLinkHint, "GlobalOptions_Cloud_Container.StorageWizardOpenLinkHint", 0, -shiftUp);
shiftWidget(_storageWizardLink, "GlobalOptions_Cloud_Container.StorageWizardLink", 0, -shiftUp);
shiftWidget(_storageWizardCodeHint, "GlobalOptions_Cloud_Container.StorageWizardCodeHint", 0, -shiftUp);
shiftWidget(_storageWizardCodeBox, "GlobalOptions_Cloud_Container.StorageWizardCodeBox", 0, -shiftUp);
shiftWidget(_storageWizardPasteButton, "GlobalOptions_Cloud_Container.StorageWizardPasteButton", 0, -shiftUp);
shiftWidget(_storageWizardConnectButton, "GlobalOptions_Cloud_Container.StorageWizardConnectButton", 0, -shiftUp);
shiftWidget(_storageWizardConnectionStatusHint, "GlobalOptions_Cloud_Container.StorageWizardConnectionStatusHint", 0, -shiftUp);
}
}
@ -3791,25 +3703,6 @@ void GlobalOptionsDialog::reflowNetworkTabLayout() {
#endif // USE_SDL_NET
#ifdef USE_LIBCURL
void GlobalOptionsDialog::storageConnectionCallback(Networking::ErrorResponse response) {
Common::U32String message("...");
if (!response.failed && !response.interrupted) {
// success
g_system->displayMessageOnOSD(_("Storage connected."));
} else {
message = _("Failed to connect storage.");
if (response.failed) {
message = _("Failed to connect storage: ") + _(response.response.c_str());
}
}
if (_storageWizardConnectionStatusHint)
_storageWizardConnectionStatusHint->setLabel(message);
_redrawCloudTab = true;
_connectingStorage = false;
}
void GlobalOptionsDialog::storageSavesSyncedCallback(Cloud::Storage::BoolResponse response) {
_redrawCloudTab = true;
}

View File

@ -350,20 +350,13 @@ protected:
bool _connectingStorage;
StaticTextWidget *_storageWizardNotConnectedHint;
StaticTextWidget *_storageWizardOpenLinkHint;
StaticTextWidget *_storageWizardLink;
StaticTextWidget *_storageWizardCodeHint;
EditTextWidget *_storageWizardCodeBox;
ButtonWidget *_storageWizardPasteButton;
ButtonWidget *_storageWizardConnectButton;
StaticTextWidget *_storageWizardConnectionStatusHint;
ButtonWidget *_storageWizardConnectButton;
bool _redrawCloudTab;
void addCloudControls(GuiObject *boss, const Common::String &prefix, bool lowres);
void setupCloudTab();
void shiftWidget(Widget *widget, const char *widgetName, int32 xOffset, int32 yOffset);
void storageConnectionCallback(Networking::ErrorResponse response);
void storageSavesSyncedCallback(Cloud::Storage::BoolResponse response);
void storageErrorCallback(Networking::ErrorResponse response);
#endif // USE_LIBCURL

View File

@ -1129,45 +1129,10 @@
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, -4, 0' spacing = '10' align = 'center'>
<layout type = 'vertical' padding = '0, 0, 2, 0' spacing = '4'>
<widget name = 'StorageWizardOpenLinkHint'
width = '96'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'vertical' padding = '0, 0, 1, 0' spacing = '4'>
<widget name = 'StorageWizardLink'
width = '192'
height = 'Globals.Line.Height'
/>
</layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '10' align = 'center'>
<widget name = 'StorageWizardCodeHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' align = 'center'>
<layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
<widget name = 'StorageWizardCodeBox'
width = '108'
height = '24'
/>
</layout>
<layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
<widget name = 'StorageWizardPasteButton'
type = 'Button'
/>
</layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '10' align = 'center'>
<widget name = 'StorageWizardConnectButton'
type = 'Button'
/>
<widget name = 'StorageWizardConnectionStatusHint'
height = 'Globals.Line.Height'
/>
</layout>
</layout>
</dialog>
@ -1292,98 +1257,185 @@
</dialog>
<dialog name = 'GlobalOptions_Cloud_ConnectionWizard' overlays = 'Dialog.GlobalOptions' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0'>
<widget name = 'Container'/>
</layout>
</dialog>
<layout type = 'vertical' padding = '16, 16, 16, 8' spacing = '0'>
<widget name = 'Headline'
height = 'Globals.Line.Height'
/>
<dialog name = 'GlobalOptions_Cloud_ConnectionWizard_Container' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container'>
<layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '0'>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' align = 'center'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '6'>
<widget name = 'Picture'
width = '109'
height = '109'
/>
<widget name = 'OpenUrlButton'
type = 'Button'
/>
<widget name = 'PasteCodeButton'
type = 'Button'
/>
</layout>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '6'>
<widget name = 'Headline'
height = 'Globals.Line.Height'
/>
<space size = '4' />
<widget name = 'NavigateLine'
height = 'Globals.Line.Height'
/>
<widget name = 'URLLine'
height = 'Globals.Line.Height'
/>
<space size = '4' />
<widget name = 'ReturnLine1'
height = 'Globals.Line.Height'
/>
<widget name = 'ReturnLine2'
height = 'Globals.Line.Height'
/>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' align = 'center'>
<widget name = 'CodeBox1'
width = '70'
height = 'Globals.Line.Height'
/>
<widget name = 'CodeBox2'
width = '70'
height = 'Globals.Line.Height'
/>
<widget name = 'CodeBox3'
width = '70'
height = 'Globals.Line.Height'
/>
<widget name = 'CodeBox4'
width = '70'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' align = 'center'>
<widget name = 'CodeBox5'
width = '70'
height = 'Globals.Line.Height'
/>
<widget name = 'CodeBox6'
width = '70'
height = 'Globals.Line.Height'
/>
<widget name = 'CodeBox7'
width = '70'
height = 'Globals.Line.Height'
/>
<widget name = 'CodeBox8'
width = '70'
height = 'Globals.Line.Height'
/>
</layout>
<widget name = 'MessageLine'
height = 'Globals.Line.Height'
/>
<space size = '6' />
</layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' align = 'center'>
<space size = '16' />
<widget name = 'Container'/>
<space />
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '12'>
<space />
<widget name = 'CancelButton'
type = 'Button'
/>
<space />
<widget name = 'ConnectButton'
<widget name = 'PrevButton'
type = 'Button'
/>
<widget name = 'NextButton'
type = 'Button'
/>
<widget name = 'FinishButton'
type = 'Button'
/>
</layout>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_ModeSelect' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '0' align = 'center'>
<widget name = 'QuickModeButton'
type = 'Button'
/>
<space size = '12' />
<widget name = 'QuickModeHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 8, 0' spacing = '0' align = 'center'>
<widget name = 'ManualModeButton'
type = 'Button'
/>
</layout>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_QuickModeStep1' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<layout type = 'vertical' padding = '0, 0, 0, 16' spacing = '0' align = 'center'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '0' align = 'center'>
<widget name = 'RunServerButton'
type = 'Button'
/>
<space size = '12' />
<widget name = 'ServerInfoLabel'
height = 'Globals.Line.Height'
/>
</layout>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_QuickModeStep2' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<layout type = 'vertical' padding = '0, 0, 0, 16' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<space size = '4' />
<widget name = 'OpenLinkButton'
width = '192'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'vertical' padding = '0, 0, 0, 12' spacing = '0' align = 'center'>
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
<widget name = 'Line3'
height = 'Globals.Line.Height'
/>
<space size = '8' />
<widget name = 'Line4'
height = 'Globals.Line.Height'
/>
</layout>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_ManualModeStep1' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<space size = '4' />
<widget name = 'OpenLinkButton'
width = '192'
height = 'Globals.Line.Height'
/>
<space size = '16' />
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
<widget name = 'Line3'
height = 'Globals.Line.Height'
/>
<widget name = 'Line4'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_ManualModeStep2' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<space size = '4' />
<widget name = 'CodeBox'
height = '24'
/>
<space size = '4' />
<widget name = 'PasteButton'
height = '24'
/>
<space size = '8' />
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_Failure' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
<widget name = 'Line3'
height = 'Globals.Line.Height'
/>
<space size = '16' />
<widget name = 'Line4'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_Success' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>
<dialog name='GlobalOptions_Accessibility' overlays='Dialog.GlobalOptions.TabWidget'>
<layout type='vertical' padding='16,16,16,16' spacing='16'>
<widget name='TTSCheckbox'

View File

@ -995,45 +995,10 @@
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, -3, 0' spacing = '6' align = 'center'>
<layout type = 'vertical' padding = '0, 0, 1, 0' spacing = '2'>
<widget name = 'StorageWizardOpenLinkHint'
width = '90'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'vertical' padding = '0, 0, 1, 0' spacing = '4'>
<widget name = 'StorageWizardLink'
width = '150'
height = 'Globals.Line.Height'
/>
</layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '6' align = 'center'>
<widget name = 'StorageWizardCodeHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' align = 'center'>
<layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
<widget name = 'StorageWizardCodeBox'
width = '72'
height = '16'
/>
</layout>
<layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
<widget name = 'StorageWizardPasteButton'
type = 'Button'
/>
</layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '6' align = 'center'>
<widget name = 'StorageWizardConnectButton'
type = 'Button'
/>
<widget name = 'StorageWizardConnectionStatusHint'
height = 'Globals.Line.Height'
/>
</layout>
</layout>
</dialog>
@ -1160,90 +1125,176 @@
</dialog>
<dialog name = 'GlobalOptions_Cloud_ConnectionWizard' overlays = 'Dialog.GlobalOptions' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0'>
<layout type = 'vertical' padding = '8, 8, 8, 4' spacing = '0'>
<widget name = 'Headline'
height = 'Globals.Line.Height'
/>
<space size = '8' />
<widget name = 'Container'/>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6'>
<space />
<widget name = 'CancelButton'
type = 'Button'
/>
<widget name = 'PrevButton'
type = 'Button'
/>
<widget name = 'NextButton'
type = 'Button'
/>
<widget name = 'FinishButton'
type = 'Button'
/>
</layout>
</layout>
</dialog>
<dialog name = 'GlobalOptions_Cloud_ConnectionWizard_Container' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container'>
<layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '4'>
<widget name = 'Headline'
height = 'Globals.Line.Height'
<dialog name = 'ConnectionWizard_ModeSelect' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '0' align = 'center'>
<widget name = 'QuickModeButton'
type = 'Button'
/>
<space size = '2' />
<widget name = 'NavigateLine'
height = 'Globals.Line.Height'
/>
<widget name = 'URLLine'
height = 'Globals.Line.Height'
/>
<space size = '2' />
<widget name = 'ReturnLine1'
height = 'Globals.Line.Height'
/>
<widget name = 'ReturnLine2'
height = 'Globals.Line.Height'
/>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' align = 'center'>
<widget name = 'CodeBox1'
width = '60'
height = '16'
/>
<widget name = 'CodeBox2'
width = '60'
height = '16'
/>
<widget name = 'CodeBox3'
width = '60'
height = '16'
/>
<widget name = 'CodeBox4'
width = '60'
height = '16'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' align = 'center'>
<widget name = 'CodeBox5'
width = '60'
height = '16'
/>
<widget name = 'CodeBox6'
width = '60'
height = '16'
/>
<widget name = 'CodeBox7'
width = '60'
height = '16'
/>
<widget name = 'CodeBox8'
width = '60'
height = '16'
/>
</layout>
<widget name = 'MessageLine'
height = 'Globals.Line.Height'
/>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' align = 'center'>
<widget name = 'OpenUrlButton'
type = 'Button'
/>
<widget name = 'PasteCodeButton'
type = 'Button'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' align = 'center'>
<widget name = 'CancelButton'
type = 'Button'
/>
<space />
<widget name = 'ConnectButton'
type = 'Button'
/>
</layout>
<space size = '6' />
<widget name = 'Picture' width = '1' height = '1' />
<widget name = 'QuickModeHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 4, 0' spacing = '0' align = 'center'>
<widget name = 'ManualModeButton'
type = 'Button'
/>
</layout>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_QuickModeStep1' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
<space size = '8' />
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '0' align = 'center'>
<widget name = 'RunServerButton'
type = 'Button'
/>
<space size = '6' />
<widget name = 'ServerInfoLabel'
height = 'Globals.Line.Height'
/>
</layout>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_QuickModeStep2' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<space size = '4' />
<widget name = 'OpenLinkButton'
width = '160'
height = 'Globals.Line.Height'
/>
<space size = '8' />
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
<widget name = 'Line3'
height = 'Globals.Line.Height'
/>
<space size = '4' />
<widget name = 'Line4'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_ManualModeStep1' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<space size = '4' />
<widget name = 'OpenLinkButton'
width = '160'
height = 'Globals.Line.Height'
/>
<space size = '8' />
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
<widget name = 'Line3'
height = 'Globals.Line.Height'
/>
<widget name = 'Line4'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_ManualModeStep2' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<space size = '4' />
<widget name = 'CodeBox'
height = '16'
/>
<space size = '4' />
<widget name = 'PasteButton'
height = '16'
/>
<space size = '8' />
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_Failure' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
<widget name = 'Line3'
height = 'Globals.Line.Height'
/>
<space size = '8' />
<widget name = 'Line4'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_Success' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>

Binary file not shown.

Binary file not shown.

View File

@ -897,45 +897,10 @@
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '10' align = 'center'>
<layout type = 'vertical' padding = '0, 0, 2, 0' spacing = '4'>
<widget name = 'StorageWizardOpenLinkHint'
width = '106'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'vertical' padding = '0, 0, 1, 0' spacing = '4'>
<widget name = 'StorageWizardLink'
width = '192'
height = 'Globals.Line.Height'
/>
</layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '10' align = 'center'>
<widget name = 'StorageWizardCodeHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' align = 'center'>
<layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
<widget name = 'StorageWizardCodeBox'
width = '108'
height = '24'
/>
</layout>
<layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
<widget name = 'StorageWizardPasteButton'
type = 'Button'
/>
</layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '10' align = 'center'>
<widget name = 'StorageWizardConnectButton'
type = 'Button'
/>
<widget name = 'StorageWizardConnectionStatusHint'
height = 'Globals.Line.Height'
/>
</layout>
</layout>
</dialog>
@ -1060,98 +1025,185 @@
</dialog>
<dialog name = 'GlobalOptions_Cloud_ConnectionWizard' overlays = 'Dialog.GlobalOptions' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0'>
<widget name = 'Container'/>
</layout>
</dialog>
<layout type = 'vertical' padding = '16, 16, 16, 8' spacing = '0'>
<widget name = 'Headline'
height = 'Globals.Line.Height'
/>
<dialog name = 'GlobalOptions_Cloud_ConnectionWizard_Container' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container'>
<layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '0'>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' align = 'center'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '6'>
<widget name = 'Picture'
width = '109'
height = '109'
/>
<widget name = 'OpenUrlButton'
type = 'Button'
/>
<widget name = 'PasteCodeButton'
type = 'Button'
/>
</layout>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '6'>
<widget name = 'Headline'
height = 'Globals.Line.Height'
/>
<space size = '4' />
<widget name = 'NavigateLine'
height = 'Globals.Line.Height'
/>
<widget name = 'URLLine'
height = 'Globals.Line.Height'
/>
<space size = '4' />
<widget name = 'ReturnLine1'
height = 'Globals.Line.Height'
/>
<widget name = 'ReturnLine2'
height = 'Globals.Line.Height'
/>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' align = 'center'>
<widget name = 'CodeBox1'
width = '70'
height = 'Globals.Line.Height'
/>
<widget name = 'CodeBox2'
width = '70'
height = 'Globals.Line.Height'
/>
<widget name = 'CodeBox3'
width = '70'
height = 'Globals.Line.Height'
/>
<widget name = 'CodeBox4'
width = '70'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' align = 'center'>
<widget name = 'CodeBox5'
width = '70'
height = 'Globals.Line.Height'
/>
<widget name = 'CodeBox6'
width = '70'
height = 'Globals.Line.Height'
/>
<widget name = 'CodeBox7'
width = '70'
height = 'Globals.Line.Height'
/>
<widget name = 'CodeBox8'
width = '70'
height = 'Globals.Line.Height'
/>
</layout>
<widget name = 'MessageLine'
height = 'Globals.Line.Height'
/>
<space size = '6' />
</layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' align = 'center'>
<space size = '16' />
<widget name = 'Container'/>
<space />
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '12'>
<space />
<widget name = 'CancelButton'
type = 'Button'
/>
<space />
<widget name = 'ConnectButton'
<widget name = 'PrevButton'
type = 'Button'
/>
<widget name = 'NextButton'
type = 'Button'
/>
<widget name = 'FinishButton'
type = 'Button'
/>
</layout>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_ModeSelect' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '0' align = 'center'>
<widget name = 'QuickModeButton'
type = 'Button'
/>
<space size = '12' />
<widget name = 'QuickModeHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 8, 0' spacing = '0' align = 'center'>
<widget name = 'ManualModeButton'
type = 'Button'
/>
</layout>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_QuickModeStep1' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<layout type = 'vertical' padding = '0, 0, 0, 16' spacing = '0' align = 'center'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '0' align = 'center'>
<widget name = 'RunServerButton'
type = 'Button'
/>
<space size = '12' />
<widget name = 'ServerInfoLabel'
height = 'Globals.Line.Height'
/>
</layout>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_QuickModeStep2' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<layout type = 'vertical' padding = '0, 0, 0, 16' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<space size = '4' />
<widget name = 'OpenLinkButton'
width = '192'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'vertical' padding = '0, 0, 0, 12' spacing = '0' align = 'center'>
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
<widget name = 'Line3'
height = 'Globals.Line.Height'
/>
<space size = '8' />
<widget name = 'Line4'
height = 'Globals.Line.Height'
/>
</layout>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_ManualModeStep1' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<space size = '4' />
<widget name = 'OpenLinkButton'
width = '192'
height = 'Globals.Line.Height'
/>
<space size = '16' />
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
<widget name = 'Line3'
height = 'Globals.Line.Height'
/>
<widget name = 'Line4'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_ManualModeStep2' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<space size = '4' />
<widget name = 'CodeBox'
height = '24'
/>
<space size = '4' />
<widget name = 'PasteButton'
height = '24'
/>
<space size = '8' />
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_Failure' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
<widget name = 'Line3'
height = 'Globals.Line.Height'
/>
<space size = '16' />
<widget name = 'Line4'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_Success' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>
<dialog name='GlobalOptions_Accessibility' overlays='Dialog.GlobalOptions.TabWidget'>
<layout type='vertical' padding='16,16,16,16' spacing='16'>
<widget name='TTSCheckbox'

View File

@ -917,45 +917,10 @@
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, -3, 0' spacing = '6' align = 'center'>
<layout type = 'vertical' padding = '0, 0, 1, 0' spacing = '2'>
<widget name = 'StorageWizardOpenLinkHint'
width = '90'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'vertical' padding = '0, 0, 1, 0' spacing = '4'>
<widget name = 'StorageWizardLink'
width = '150'
height = 'Globals.Line.Height'
/>
</layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '6' align = 'center'>
<widget name = 'StorageWizardCodeHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' align = 'center'>
<layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
<widget name = 'StorageWizardCodeBox'
width = '72'
height = '16'
/>
</layout>
<layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
<widget name = 'StorageWizardPasteButton'
type = 'Button'
/>
</layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '6' align = 'center'>
<widget name = 'StorageWizardConnectButton'
type = 'Button'
/>
<widget name = 'StorageWizardConnectionStatusHint'
height = 'Globals.Line.Height'
/>
</layout>
</layout>
</dialog>
@ -1082,92 +1047,179 @@
</dialog>
<dialog name = 'GlobalOptions_Cloud_ConnectionWizard' overlays = 'Dialog.GlobalOptions' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0'>
<widget name = 'Container'/>
</layout>
</dialog>
<layout type = 'vertical' padding = '8, 8, 8, 4' spacing = '0'>
<widget name = 'Headline'
height = 'Globals.Line.Height'
/>
<space size = '8' />
<dialog name = 'GlobalOptions_Cloud_ConnectionWizard_Container' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container'>
<layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '4'>
<widget name = 'Headline'
height = 'Globals.Line.Height'
<widget name = 'Container'/>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6'>
<space />
<widget name = 'CancelButton'
type = 'Button'
/>
<space size = '2' />
<widget name = 'NavigateLine'
height = 'Globals.Line.Height'
<widget name = 'PrevButton'
type = 'Button'
/>
<widget name = 'URLLine'
height = 'Globals.Line.Height'
<widget name = 'NextButton'
type = 'Button'
/>
<space size = '2' />
<widget name = 'ReturnLine1'
height = 'Globals.Line.Height'
<widget name = 'FinishButton'
type = 'Button'
/>
<widget name = 'ReturnLine2'
height = 'Globals.Line.Height'
/>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' align = 'center'>
<widget name = 'CodeBox1'
width = '60'
height = '16'
/>
<widget name = 'CodeBox2'
width = '60'
height = '16'
/>
<widget name = 'CodeBox3'
width = '60'
height = '16'
/>
<widget name = 'CodeBox4'
width = '60'
height = '16'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' align = 'center'>
<widget name = 'CodeBox5'
width = '60'
height = '16'
/>
<widget name = 'CodeBox6'
width = '60'
height = '16'
/>
<widget name = 'CodeBox7'
width = '60'
height = '16'
/>
<widget name = 'CodeBox8'
width = '60'
height = '16'
/>
</layout>
<widget name = 'MessageLine'
height = 'Globals.Line.Height'
/>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' align = 'center'>
<widget name = 'OpenUrlButton'
type = 'Button'
/>
<widget name = 'PasteCodeButton'
type = 'Button'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' align = 'center'>
<widget name = 'CancelButton'
type = 'Button'
/>
<space />
<widget name = 'ConnectButton'
type = 'Button'
/>
</layout>
<space size = '6' />
<widget name = 'Picture' width = '1' height = '1' />
</layout>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_ModeSelect' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '0' align = 'center'>
<widget name = 'QuickModeButton'
type = 'Button'
/>
<space size = '6' />
<widget name = 'QuickModeHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 4, 0' spacing = '0' align = 'center'>
<widget name = 'ManualModeButton'
type = 'Button'
/>
</layout>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_QuickModeStep1' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
<space size = '8' />
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '0' align = 'center'>
<widget name = 'RunServerButton'
type = 'Button'
/>
<space size = '6' />
<widget name = 'ServerInfoLabel'
height = 'Globals.Line.Height'
/>
</layout>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_QuickModeStep2' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<space size = '4' />
<widget name = 'OpenLinkButton'
width = '160'
height = 'Globals.Line.Height'
/>
<space size = '8' />
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
<widget name = 'Line3'
height = 'Globals.Line.Height'
/>
<space size = '4' />
<widget name = 'Line4'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_ManualModeStep1' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<space size = '4' />
<widget name = 'OpenLinkButton'
width = '160'
height = 'Globals.Line.Height'
/>
<space size = '8' />
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
<widget name = 'Line3'
height = 'Globals.Line.Height'
/>
<widget name = 'Line4'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_ManualModeStep2' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<space size = '4' />
<widget name = 'CodeBox'
height = '16'
/>
<space size = '4' />
<widget name = 'PasteButton'
height = '16'
/>
<space size = '8' />
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_Failure' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
<widget name = 'Line2'
height = 'Globals.Line.Height'
/>
<widget name = 'Line3'
height = 'Globals.Line.Height'
/>
<space size = '8' />
<widget name = 'Line4'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>
<dialog name = 'ConnectionWizard_Success' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container' shading = 'dim'>
<layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '0'>
<widget name = 'Line1'
height = 'Globals.Line.Height'
/>
</layout>
</dialog>
<dialog name='GlobalOptions_Accessibility' overlays='Dialog.GlobalOptions.TabWidget'>
<layout type='vertical' padding='16,16,16,16' spacing='16'>
<widget name='TTSCheckbox'

Binary file not shown.

Binary file not shown.