add focusController class

This commit is contained in:
Cyril Anisimov 2024-09-14 19:42:55 +02:00
parent 8547de82ea
commit 02bbcd3a31
76 changed files with 1906 additions and 1576 deletions

View file

@ -404,6 +404,9 @@ void AmneziaApplication::initControllers()
m_pageController.reset(new PageController(m_serversModel, m_settings));
m_engine->rootContext()->setContextProperty("PageController", m_pageController.get());
m_focusController.reset(new FocusController(m_engine, this));
m_engine->rootContext()->setContextProperty("FocusController", m_focusController.get());
m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_protocolsModel, m_clientManagementModel,
m_apiServicesModel, m_settings));
m_engine->rootContext()->setContextProperty("InstallController", m_installController.get());

View file

@ -19,6 +19,7 @@
#include "ui/controllers/exportController.h"
#include "ui/controllers/importController.h"
#include "ui/controllers/installController.h"
#include "ui/controllers/focusController.h"
#include "ui/controllers/pageController.h"
#include "ui/controllers/settingsController.h"
#include "ui/controllers/sitesController.h"
@ -124,6 +125,7 @@ private:
#endif
QScopedPointer<ConnectionController> m_connectionController;
QScopedPointer<FocusController> m_focusController;
QScopedPointer<PageController> m_pageController;
QScopedPointer<InstallController> m_installController;
QScopedPointer<ImportController> m_importController;

View file

@ -1,225 +1,226 @@
<RCC>
<qresource prefix="/">
<file>fonts/pt-root-ui_vf.ttf</file>
<file>images/amneziaBigLogo.png</file>
<file>images/AmneziaVPN.png</file>
<file>images/controls/alert-circle.svg</file>
<file>images/controls/amnezia.svg</file>
<file>images/controls/app.svg</file>
<file>images/controls/archive-restore.svg</file>
<file>images/controls/arrow-left.svg</file>
<file>images/controls/arrow-right.svg</file>
<file>images/controls/bug.svg</file>
<file>images/controls/check.svg</file>
<file>images/controls/chevron-down.svg</file>
<file>images/controls/chevron-right.svg</file>
<file>images/controls/chevron-up.svg</file>
<file>images/controls/close.svg</file>
<file>images/controls/copy.svg</file>
<file>images/controls/delete.svg</file>
<file>images/controls/download.svg</file>
<file>images/controls/edit-3.svg</file>
<file>images/controls/eye-off.svg</file>
<file>images/controls/eye.svg</file>
<file>images/controls/file-check-2.svg</file>
<file>images/controls/file-cog-2.svg</file>
<file>images/controls/folder-open.svg</file>
<file>images/controls/folder-search-2.svg</file>
<file>images/controls/gauge.svg</file>
<file>images/controls/github.svg</file>
<file>images/controls/help-circle.svg</file>
<file>images/controls/history.svg</file>
<file>images/controls/home.svg</file>
<file>images/controls/info.svg</file>
<file>images/controls/mail.svg</file>
<file>images/controls/map-pin.svg</file>
<file>images/controls/more-vertical.svg</file>
<file>images/controls/plus.svg</file>
<file>images/controls/qr-code.svg</file>
<file>images/controls/radio-button-inner-circle-pressed.png</file>
<file>images/controls/radio-button-inner-circle.png</file>
<file>images/controls/radio-button-pressed.svg</file>
<file>images/controls/radio-button.svg</file>
<file>images/controls/radio.svg</file>
<file>images/controls/refresh-cw.svg</file>
<file>images/controls/save.svg</file>
<file>images/controls/scan-line.svg</file>
<file>images/controls/search.svg</file>
<file>images/controls/server.svg</file>
<file>images/controls/settings-2.svg</file>
<file>images/controls/settings.svg</file>
<file>images/controls/share-2.svg</file>
<file>images/controls/split-tunneling.svg</file>
<file>images/controls/tag.svg</file>
<file>images/controls/telegram.svg</file>
<file>images/controls/text-cursor.svg</file>
<file>images/controls/trash.svg</file>
<file>images/controls/x-circle.svg</file>
<file>images/tray/active.png</file>
<file>images/tray/default.png</file>
<file>images/tray/error.png</file>
<file>images/AmneziaVPN.png</file>
<file>server_scripts/remove_container.sh</file>
<file>server_scripts/setup_host_firewall.sh</file>
<file>server_scripts/openvpn_cloak/Dockerfile</file>
<file>server_scripts/awg/configure_container.sh</file>
<file>server_scripts/awg/Dockerfile</file>
<file>server_scripts/awg/run_container.sh</file>
<file>server_scripts/awg/start.sh</file>
<file>server_scripts/awg/template.conf</file>
<file>server_scripts/build_container.sh</file>
<file>server_scripts/check_connection.sh</file>
<file>server_scripts/check_server_is_busy.sh</file>
<file>server_scripts/check_user_in_sudo.sh</file>
<file>server_scripts/dns/configure_container.sh</file>
<file>server_scripts/dns/Dockerfile</file>
<file>server_scripts/dns/run_container.sh</file>
<file>server_scripts/install_docker.sh</file>
<file>server_scripts/ipsec/configure_container.sh</file>
<file>server_scripts/ipsec/Dockerfile</file>
<file>server_scripts/ipsec/mobileconfig.plist</file>
<file>server_scripts/ipsec/run_container.sh</file>
<file>server_scripts/ipsec/start.sh</file>
<file>server_scripts/ipsec/strongswan.profile</file>
<file>server_scripts/openvpn_cloak/configure_container.sh</file>
<file>server_scripts/openvpn_cloak/Dockerfile</file>
<file>server_scripts/openvpn_cloak/run_container.sh</file>
<file>server_scripts/openvpn_cloak/start.sh</file>
<file>server_scripts/openvpn_cloak/template.ovpn</file>
<file>server_scripts/install_docker.sh</file>
<file>server_scripts/build_container.sh</file>
<file>server_scripts/prepare_host.sh</file>
<file>server_scripts/check_connection.sh</file>
<file>server_scripts/remove_all_containers.sh</file>
<file>server_scripts/openvpn_cloak/run_container.sh</file>
<file>server_scripts/openvpn/configure_container.sh</file>
<file>server_scripts/openvpn/run_container.sh</file>
<file>server_scripts/openvpn/template.ovpn</file>
<file>server_scripts/openvpn/Dockerfile</file>
<file>server_scripts/openvpn/start.sh</file>
<file>server_scripts/openvpn_shadowsocks/configure_container.sh</file>
<file>server_scripts/openvpn_shadowsocks/Dockerfile</file>
<file>server_scripts/openvpn_shadowsocks/run_container.sh</file>
<file>server_scripts/openvpn_shadowsocks/start.sh</file>
<file>server_scripts/openvpn_shadowsocks/template.ovpn</file>
<file>server_scripts/openvpn/configure_container.sh</file>
<file>server_scripts/openvpn/Dockerfile</file>
<file>server_scripts/openvpn/run_container.sh</file>
<file>server_scripts/openvpn/start.sh</file>
<file>server_scripts/openvpn/template.ovpn</file>
<file>server_scripts/prepare_host.sh</file>
<file>server_scripts/remove_all_containers.sh</file>
<file>server_scripts/remove_container.sh</file>
<file>server_scripts/setup_host_firewall.sh</file>
<file>server_scripts/sftp/configure_container.sh</file>
<file>server_scripts/sftp/Dockerfile</file>
<file>server_scripts/sftp/run_container.sh</file>
<file>server_scripts/socks5_proxy/configure_container.sh</file>
<file>server_scripts/socks5_proxy/Dockerfile</file>
<file>server_scripts/socks5_proxy/run_container.sh</file>
<file>server_scripts/socks5_proxy/start.sh</file>
<file>server_scripts/website_tor/configure_container.sh</file>
<file>server_scripts/website_tor/Dockerfile</file>
<file>server_scripts/website_tor/run_container.sh</file>
<file>server_scripts/wireguard/configure_container.sh</file>
<file>server_scripts/wireguard/Dockerfile</file>
<file>server_scripts/wireguard/run_container.sh</file>
<file>server_scripts/wireguard/start.sh</file>
<file>server_scripts/wireguard/template.conf</file>
<file>server_scripts/website_tor/configure_container.sh</file>
<file>server_scripts/website_tor/run_container.sh</file>
<file>ui/qml/Config/GlobalConfig.qml</file>
<file>ui/qml/Config/qmldir</file>
<file>server_scripts/check_server_is_busy.sh</file>
<file>server_scripts/dns/configure_container.sh</file>
<file>server_scripts/dns/Dockerfile</file>
<file>server_scripts/dns/run_container.sh</file>
<file>server_scripts/sftp/configure_container.sh</file>
<file>server_scripts/sftp/Dockerfile</file>
<file>server_scripts/sftp/run_container.sh</file>
<file>server_scripts/ipsec/configure_container.sh</file>
<file>server_scripts/ipsec/Dockerfile</file>
<file>server_scripts/ipsec/run_container.sh</file>
<file>server_scripts/ipsec/start.sh</file>
<file>server_scripts/ipsec/mobileconfig.plist</file>
<file>server_scripts/ipsec/strongswan.profile</file>
<file>server_scripts/website_tor/Dockerfile</file>
<file>server_scripts/check_user_in_sudo.sh</file>
<file>ui/qml/Controls2/BasicButtonType.qml</file>
<file>ui/qml/Controls2/TextFieldWithHeaderType.qml</file>
<file>ui/qml/Controls2/LabelWithButtonType.qml</file>
<file>images/controls/arrow-right.svg</file>
<file>images/controls/chevron-right.svg</file>
<file>ui/qml/Controls2/ImageButtonType.qml</file>
<file>ui/qml/Controls2/CardType.qml</file>
<file>ui/qml/Controls2/CheckBoxType.qml</file>
<file>images/controls/check.svg</file>
<file>ui/qml/Controls2/DropDownType.qml</file>
<file>ui/qml/Pages2/PageSetupWizardStart.qml</file>
<file>ui/qml/main2.qml</file>
<file>images/amneziaBigLogo.png</file>
<file>ui/qml/Controls2/FlickableType.qml</file>
<file>ui/qml/Pages2/PageSetupWizardCredentials.qml</file>
<file>ui/qml/Controls2/HeaderType.qml</file>
<file>images/controls/arrow-left.svg</file>
<file>ui/qml/Pages2/PageSetupWizardProtocols.qml</file>
<file>ui/qml/Pages2/PageSetupWizardEasy.qml</file>
<file>images/controls/chevron-down.svg</file>
<file>images/controls/chevron-up.svg</file>
<file>ui/qml/Controls2/TextTypes/ParagraphTextType.qml</file>
<file>ui/qml/Controls2/TextTypes/Header2TextType.qml</file>
<file>ui/qml/Controls2/HorizontalRadioButton.qml</file>
<file>ui/qml/Controls2/VerticalRadioButton.qml</file>
<file>ui/qml/Controls2/SwitcherType.qml</file>
<file>ui/qml/Controls2/TabButtonType.qml</file>
<file>ui/qml/Pages2/PageSetupWizardProtocolSettings.qml</file>
<file>ui/qml/Pages2/PageSetupWizardInstalling.qml</file>
<file>ui/qml/Pages2/PageSetupWizardConfigSource.qml</file>
<file>images/controls/folder-open.svg</file>
<file>images/controls/qr-code.svg</file>
<file>images/controls/text-cursor.svg</file>
<file>ui/qml/Pages2/PageSetupWizardTextKey.qml</file>
<file>ui/qml/Pages2/PageStart.qml</file>
<file>ui/qml/Controls2/TabImageButtonType.qml</file>
<file>images/controls/home.svg</file>
<file>images/controls/settings-2.svg</file>
<file>images/controls/share-2.svg</file>
<file>ui/qml/Pages2/PageHome.qml</file>
<file>ui/qml/Pages2/PageSettingsServersList.qml</file>
<file>ui/qml/Pages2/PageShare.qml</file>
<file>ui/qml/Controls2/TextTypes/Header1TextType.qml</file>
<file>ui/qml/Controls2/TextTypes/LabelTextType.qml</file>
<file>ui/qml/Controls2/TextTypes/ButtonTextType.qml</file>
<file>ui/qml/Controls2/Header2Type.qml</file>
<file>images/controls/plus.svg</file>
<file>ui/qml/Components/ConnectButton.qml</file>
<file>images/controls/download.svg</file>
<file>ui/qml/Controls2/ProgressBarType.qml</file>
<file>ui/qml/Components/ConnectionTypeSelectionDrawer.qml</file>
<file>ui/qml/Components/HomeContainersListView.qml</file>
<file>ui/qml/Controls2/TextTypes/CaptionTextType.qml</file>
<file>images/controls/settings.svg</file>
<file>ui/qml/Pages2/PageSettingsServerInfo.qml</file>
<file>ui/qml/Controls2/PageType.qml</file>
<file>ui/qml/Controls2/PopupType.qml</file>
<file>images/controls/edit-3.svg</file>
<file>ui/qml/Pages2/PageSettingsServerData.qml</file>
<file>ui/qml/Components/SettingsContainersListView.qml</file>
<file>ui/qml/Controls2/TextTypes/ListItemTitleType.qml</file>
<file>ui/qml/Controls2/DividerType.qml</file>
<file>ui/qml/Controls2/StackViewType.qml</file>
<file>ui/qml/Pages2/PageSettings.qml</file>
<file>images/controls/amnezia.svg</file>
<file>images/controls/app.svg</file>
<file>images/controls/radio.svg</file>
<file>images/controls/save.svg</file>
<file>images/controls/server.svg</file>
<file>ui/qml/Pages2/PageSettingsServerProtocols.qml</file>
<file>ui/qml/Pages2/PageSettingsServerServices.qml</file>
<file>ui/qml/Pages2/PageSetupWizardViewConfig.qml</file>
<file>images/controls/file-cog-2.svg</file>
<file>ui/qml/Components/QuestionDrawer.qml</file>
<file>ui/qml/Pages2/PageDeinstalling.qml</file>
<file>ui/qml/Controls2/BackButtonType.qml</file>
<file>ui/qml/Pages2/PageSettingsServerProtocol.qml</file>
<file>ui/qml/Components/TransportProtoSelector.qml</file>
<file>ui/qml/Controls2/ListViewWithRadioButtonType.qml</file>
<file>images/controls/radio-button.svg</file>
<file>images/controls/radio-button-inner-circle.png</file>
<file>images/controls/radio-button-pressed.svg</file>
<file>images/controls/radio-button-inner-circle-pressed.png</file>
<file>ui/qml/Components/ShareConnectionDrawer.qml</file>
<file>ui/qml/Pages2/PageSettingsConnection.qml</file>
<file>ui/qml/Pages2/PageSettingsDns.qml</file>
<file>ui/qml/Pages2/PageSettingsApplication.qml</file>
<file>ui/qml/Pages2/PageSettingsBackup.qml</file>
<file>images/controls/delete.svg</file>
<file>ui/qml/Pages2/PageSettingsAbout.qml</file>
<file>images/controls/github.svg</file>
<file>images/controls/mail.svg</file>
<file>images/controls/telegram.svg</file>
<file>ui/qml/Controls2/TextTypes/SmallTextType.qml</file>
<file>ui/qml/Filters/ContainersModelFilters.qml</file>
<file>ui/qml/Components/SelectLanguageDrawer.qml</file>
<file>ui/qml/Controls2/BusyIndicatorType.qml</file>
<file>ui/qml/Pages2/PageProtocolOpenVpnSettings.qml</file>
<file>ui/qml/Pages2/PageProtocolShadowSocksSettings.qml</file>
<file>ui/qml/Pages2/PageProtocolCloakSettings.qml</file>
<file>ui/qml/Pages2/PageProtocolXraySettings.qml</file>
<file>ui/qml/Pages2/PageProtocolRaw.qml</file>
<file>ui/qml/Pages2/PageSettingsLogging.qml</file>
<file>ui/qml/Pages2/PageServiceSftpSettings.qml</file>
<file>images/controls/copy.svg</file>
<file>ui/qml/Pages2/PageServiceTorWebsiteSettings.qml</file>
<file>ui/qml/Pages2/PageSetupWizardQrReader.qml</file>
<file>images/controls/eye.svg</file>
<file>images/controls/eye-off.svg</file>
<file>ui/qml/Pages2/PageSettingsSplitTunneling.qml</file>
<file>ui/qml/Controls2/ContextMenuType.qml</file>
<file>ui/qml/Controls2/TextAreaType.qml</file>
<file>images/controls/trash.svg</file>
<file>images/controls/more-vertical.svg</file>
<file>ui/qml/Controls2/ListViewWithLabelsType.qml</file>
<file>ui/qml/Pages2/PageServiceDnsSettings.qml</file>
<file>ui/qml/Controls2/TopCloseButtonType.qml</file>
<file>images/controls/x-circle.svg</file>
<file>ui/qml/Pages2/PageProtocolAwgSettings.qml</file>
<file>server_scripts/awg/template.conf</file>
<file>server_scripts/awg/start.sh</file>
<file>server_scripts/awg/configure_container.sh</file>
<file>server_scripts/awg/run_container.sh</file>
<file>server_scripts/awg/Dockerfile</file>
<file>ui/qml/Pages2/PageShareFullAccess.qml</file>
<file>images/controls/close.svg</file>
<file>images/controls/search.svg</file>
<file>server_scripts/xray/configure_container.sh</file>
<file>server_scripts/xray/Dockerfile</file>
<file>server_scripts/xray/run_container.sh</file>
<file>server_scripts/xray/start.sh</file>
<file>server_scripts/xray/template.json</file>
<file>ui/qml/Pages2/PageProtocolWireGuardSettings.qml</file>
<file>ui/qml/Components/ConnectButton.qml</file>
<file>ui/qml/Components/ConnectionTypeSelectionDrawer.qml</file>
<file>ui/qml/Components/HomeContainersListView.qml</file>
<file>ui/qml/Components/HomeSplitTunnelingDrawer.qml</file>
<file>images/controls/split-tunneling.svg</file>
<file>ui/qml/Controls2/DrawerType2.qml</file>
<file>ui/qml/Pages2/PageSettingsAppSplitTunneling.qml</file>
<file>ui/qml/Components/InstalledAppsDrawer.qml</file>
<file>images/controls/alert-circle.svg</file>
<file>images/controls/file-check-2.svg</file>
<file>ui/qml/Components/QuestionDrawer.qml</file>
<file>ui/qml/Components/SelectLanguageDrawer.qml</file>
<file>ui/qml/Components/ServersListView.qml</file>
<file>ui/qml/Components/SettingsContainersListView.qml</file>
<file>ui/qml/Components/ShareConnectionDrawer.qml</file>
<file>ui/qml/Components/TransportProtoSelector.qml</file>
<file>ui/qml/Config/GlobalConfig.qml</file>
<file>ui/qml/Config/qmldir</file>
<file>ui/qml/Controls2/BackButtonType.qml</file>
<file>ui/qml/Controls2/BasicButtonType.qml</file>
<file>ui/qml/Controls2/BusyIndicatorType.qml</file>
<file>ui/qml/Controls2/CardType.qml</file>
<file>ui/qml/Controls2/CardWithIconsType.qml</file>
<file>ui/qml/Controls2/CheckBoxType.qml</file>
<file>ui/qml/Controls2/ContextMenuType.qml</file>
<file>ui/qml/Controls2/DividerType.qml</file>
<file>ui/qml/Controls2/DrawerType2.qml</file>
<file>ui/qml/Controls2/DropDownType.qml</file>
<file>ui/qml/Controls2/FlickableType.qml</file>
<file>ui/qml/Controls2/Header2Type.qml</file>
<file>ui/qml/Controls2/HeaderType.qml</file>
<file>ui/qml/Controls2/HorizontalRadioButton.qml</file>
<file>ui/qml/Controls2/ImageButtonType.qml</file>
<file>ui/qml/Controls2/LabelWithButtonType.qml</file>
<file>ui/qml/Controls2/LabelWithImageType.qml</file>
<file>ui/qml/Controls2/ListViewWithLabelsType.qml</file>
<file>ui/qml/Controls2/ListViewWithRadioButtonType.qml</file>
<file>ui/qml/Controls2/PageType.qml</file>
<file>ui/qml/Controls2/PopupType.qml</file>
<file>ui/qml/Controls2/ProgressBarType.qml</file>
<file>ui/qml/Controls2/StackViewType.qml</file>
<file>ui/qml/Controls2/SwitcherType.qml</file>
<file>ui/qml/Controls2/TabButtonType.qml</file>
<file>ui/qml/Controls2/TabImageButtonType.qml</file>
<file>ui/qml/Controls2/TextAreaType.qml</file>
<file>ui/qml/Controls2/TextAreaWithFooterType.qml</file>
<file>ui/qml/Controls2/TextFieldWithHeaderType.qml</file>
<file>ui/qml/Controls2/TextTypes/ButtonTextType.qml</file>
<file>ui/qml/Controls2/TextTypes/CaptionTextType.qml</file>
<file>ui/qml/Controls2/TextTypes/Header1TextType.qml</file>
<file>ui/qml/Controls2/TextTypes/Header2TextType.qml</file>
<file>ui/qml/Controls2/TextTypes/LabelTextType.qml</file>
<file>ui/qml/Controls2/TextTypes/ListItemTitleType.qml</file>
<file>ui/qml/Controls2/TextTypes/ParagraphTextType.qml</file>
<file>ui/qml/Controls2/TextTypes/SmallTextType.qml</file>
<file>ui/qml/Controls2/TopCloseButtonType.qml</file>
<file>ui/qml/Controls2/VerticalRadioButton.qml</file>
<file>ui/qml/Controls2/WarningType.qml</file>
<file>fonts/pt-root-ui_vf.ttf</file>
<file>ui/qml/Modules/Style/qmldir</file>
<file>ui/qml/Filters/ContainersModelFilters.qml</file>
<file>ui/qml/main2.qml</file>
<file>ui/qml/Modules/Style/AmneziaStyle.qml</file>
<file>ui/qml/Modules/Style/qmldir</file>
<file>ui/qml/Pages2/PageDeinstalling.qml</file>
<file>ui/qml/Pages2/PageDevMenu.qml</file>
<file>ui/qml/Pages2/PageHome.qml</file>
<file>ui/qml/Pages2/PageProtocolAwgSettings.qml</file>
<file>ui/qml/Pages2/PageProtocolCloakSettings.qml</file>
<file>ui/qml/Pages2/PageProtocolOpenVpnSettings.qml</file>
<file>ui/qml/Pages2/PageProtocolRaw.qml</file>
<file>ui/qml/Pages2/PageProtocolShadowSocksSettings.qml</file>
<file>ui/qml/Pages2/PageProtocolWireGuardSettings.qml</file>
<file>ui/qml/Pages2/PageProtocolXraySettings.qml</file>
<file>ui/qml/Pages2/PageServiceDnsSettings.qml</file>
<file>ui/qml/Pages2/PageServiceSftpSettings.qml</file>
<file>ui/qml/Pages2/PageServiceSocksProxySettings.qml</file>
<file>server_scripts/socks5_proxy/run_container.sh</file>
<file>server_scripts/socks5_proxy/Dockerfile</file>
<file>server_scripts/socks5_proxy/configure_container.sh</file>
<file>server_scripts/socks5_proxy/start.sh</file>
<file>ui/qml/Pages2/PageServiceTorWebsiteSettings.qml</file>
<file>ui/qml/Pages2/PageSettings.qml</file>
<file>ui/qml/Pages2/PageSettingsAbout.qml</file>
<file>ui/qml/Pages2/PageSettingsApiLanguageList.qml</file>
<file>ui/qml/Pages2/PageSettingsApiServerInfo.qml</file>
<file>ui/qml/Pages2/PageSettingsApplication.qml</file>
<file>ui/qml/Pages2/PageSettingsAppSplitTunneling.qml</file>
<file>ui/qml/Pages2/PageSettingsBackup.qml</file>
<file>ui/qml/Pages2/PageSettingsConnection.qml</file>
<file>ui/qml/Pages2/PageSettingsDns.qml</file>
<file>ui/qml/Pages2/PageSettingsLogging.qml</file>
<file>ui/qml/Pages2/PageSettingsServerData.qml</file>
<file>ui/qml/Pages2/PageSettingsServerInfo.qml</file>
<file>ui/qml/Pages2/PageSettingsServerProtocol.qml</file>
<file>ui/qml/Pages2/PageSettingsServerProtocols.qml</file>
<file>ui/qml/Pages2/PageSettingsServerServices.qml</file>
<file>ui/qml/Pages2/PageSettingsServersList.qml</file>
<file>ui/qml/Pages2/PageSettingsSplitTunneling.qml</file>
<file>ui/qml/Pages2/PageProtocolAwgClientSettings.qml</file>
<file>ui/qml/Pages2/PageProtocolWireGuardClientSettings.qml</file>
<file>ui/qml/Pages2/PageSetupWizardApiServicesList.qml</file>
<file>ui/qml/Pages2/PageSetupWizardApiServiceInfo.qml</file>
<file>ui/qml/Controls2/CardWithIconsType.qml</file>
<file>images/controls/tag.svg</file>
<file>images/controls/history.svg</file>
<file>images/controls/gauge.svg</file>
<file>images/controls/map-pin.svg</file>
<file>ui/qml/Controls2/LabelWithImageType.qml</file>
<file>images/controls/info.svg</file>
<file>ui/qml/Controls2/TextAreaWithFooterType.qml</file>
<file>images/controls/scan-line.svg</file>
<file>images/controls/folder-search-2.svg</file>
<file>ui/qml/Pages2/PageSettingsApiServerInfo.qml</file>
<file>images/controls/bug.svg</file>
<file>ui/qml/Pages2/PageDevMenu.qml</file>
<file>images/controls/refresh-cw.svg</file>
<file>ui/qml/Pages2/PageSettingsApiLanguageList.qml</file>
<file>images/controls/archive-restore.svg</file>
<file>images/controls/help-circle.svg</file>
<file>ui/qml/Pages2/PageSetupWizardApiServicesList.qml</file>
<file>ui/qml/Pages2/PageSetupWizardConfigSource.qml</file>
<file>ui/qml/Pages2/PageSetupWizardCredentials.qml</file>
<file>ui/qml/Pages2/PageSetupWizardEasy.qml</file>
<file>ui/qml/Pages2/PageSetupWizardInstalling.qml</file>
<file>ui/qml/Pages2/PageSetupWizardProtocols.qml</file>
<file>ui/qml/Pages2/PageSetupWizardProtocolSettings.qml</file>
<file>ui/qml/Pages2/PageSetupWizardQrReader.qml</file>
<file>ui/qml/Pages2/PageSetupWizardStart.qml</file>
<file>ui/qml/Pages2/PageSetupWizardTextKey.qml</file>
<file>ui/qml/Pages2/PageSetupWizardViewConfig.qml</file>
<file>ui/qml/Pages2/PageShare.qml</file>
<file>ui/qml/Pages2/PageShareFullAccess.qml</file>
<file>ui/qml/Pages2/PageStart.qml</file>
</qresource>
<qresource prefix="/countriesFlags">
<file>images/flagKit/ZW.svg</file>

View file

@ -0,0 +1,476 @@
#include "focusController.h"
#include <QQuickWindow>
#include <QQmlApplicationEngine>
#include <QQuickItem>
#include <QQueue>
#include <QPointF>
#include <QRectF>
bool isVisible(QObject* item)
{
const auto res = item->property("visible").toBool();
// qDebug() << "==>> " << (res ? "VISIBLE" : "NOT visible") << item;
return res;
}
bool isFocusable(QObject* item)
{
const auto res = item->property("isFocusable").toBool();
// qDebug() << "==>> " << (res ? "FOCUSABLE" : "NOT focusable") << item;
return res;
}
QRectF getItemCoordsOnScene(QQuickItem* item) // TODO: remove?
{
if (!item) return {};
return item->mapRectToScene(item->childrenRect());
}
QPointF getItemCenterPointOnScene(QQuickItem* item)
{
const auto x0 = item->x() + (item->width() / 2);
const auto y0 = item->y() + (item->height() / 2);
return item->parentItem()->mapToScene(QPointF{x0, y0});
}
bool isLess(QObject* item1, QObject* item2)
{
const auto p1 = getItemCenterPointOnScene(qobject_cast<QQuickItem*>(item1));
const auto p2 = getItemCenterPointOnScene(qobject_cast<QQuickItem*>(item2));
return (p1.y() == p2.y()) ? (p1.x() < p2.x()) : (p1.y() < p2.y());
}
bool isListView(QObject* item)
{
return item->inherits("QQuickListView");
}
bool isOnTheScene(QObject* object)
{
QQuickItem* item = qobject_cast<QQuickItem*>(object);
if (!item) {
qWarning() << "Couldn't recognize object as item";
return false;
}
if (!item->isVisible()) {
qInfo() << "The item is not visible: " << item;
return false;
}
QRectF itemRect{}; // TODO: ListView couln't get into list because it's children's rect is too large
// if (isListView(item)) {
// itemRect = QRectF(item->x(), item->y(), item->width(), item->height());
// } else {
itemRect = item->mapRectToScene(item->childrenRect());
// }
QQuickWindow* window = item->window();
if (!window) {
qWarning() << "Couldn't get the window on the Scene check";
return false;
}
// const auto contentItem = window->contentItem();
// if (!contentItem) {
// qWarning() << "Couldn't get the content item on the Scene check";
// return false;
// }
// QRectF windowRect = contentItem->childrenRect();
// const auto res = (windowRect.contains(itemRect) || isListView(item));
// // qDebug() << (res ? "===>> item is inside the Scene" : "===>> ITEM IS OUTSIDE THE SCENE") << " itemRect: " << itemRect << "; windowRect: " << windowRect;
// return res;
return true;
}
bool isEnabled(QObject* obj)
{
const auto item = qobject_cast<QQuickItem*>(obj);
return item && item->isEnabled();
}
QQuickItem* getPageOfItem(QQuickItem* item) // TODO: remove?
{
if(!item) {
qWarning() << "item is null";
return {};
}
const auto pagePattern = QString::fromLatin1("Page");
QString className{item->metaObject()->className()};
qDebug() << "=====================>> Item: " << item << " with name: " << item->metaObject()->className();
const auto isPage = className.contains(pagePattern, Qt::CaseSensitive);
if(isPage) {
return item;
} else {
return getPageOfItem(item->parentItem());
}
}
QList<QObject*> getSubChain(QObject* item)
{
QList<QObject*> res;
if (!item) {
qDebug() << "null top item";
return res;
}
const auto children = item->children();
for(const auto child : children) {
if (child
&& isFocusable(child)
&& (isOnTheScene(child))
&& isEnabled(child)
) {
res.append(child);
// qDebug() << "==>> [*** added ***] " << qobject_cast<QQuickItem*>(child);
} else {
// qDebug() << "==>> [** skipped **] " << qobject_cast<QQuickItem*>(child);
res.append(getSubChain(child));
}
}
return res;
}
template<typename T>
void printItems(const T& items, QObject* current_item)
{
qDebug() << "**********************************************";
for(const auto& item : items) {
QQuickItem* i = qobject_cast<QQuickItem*>(item);
QPointF coords {getItemCenterPointOnScene(i)};
QString prefix = current_item == i ? "==>" : " ";
qDebug() << prefix << " Item: " << i << " with coords: " << coords;
}
qDebug() << "**********************************************";
}
/*!
* \brief The ListViewFocusController class manages the focus of elements in ListView
* \details This class object moving focus to ListView's controls since ListView stores
* it's data implicitly and it could be got one by one.
*
* This class was made to store as less as possible data getting it from QML
* when it's needed.
*/
class ListViewFocusController : public QObject
{
public:
explicit ListViewFocusController(QQuickItem* listView, QObject* parent = nullptr);
~ListViewFocusController();
void incrementIndex();
void decrementCurrentIndex();
void positionViewAtIndex();
void focusNextItem();
void focusPreviousItem();
void resetFocusChain();
bool isListViewLastFocusItem();
bool isDelegateLastFocusItem();
private:
int size() const;
int currentIndex() const;
QQuickItem* itemAtIndex(const int index);
QQuickItem* currentDelegate();
QQuickItem* focusedItem();
QQuickItem* m_listView;
QList<QObject*> m_focusChain;
QQuickItem* m_focusedItem;
qsizetype m_focusedItemIndex;
qsizetype m_delegateIndex;
};
ListViewFocusController::ListViewFocusController(QQuickItem* listView, QObject* parent)
: QObject{parent}
, m_listView{listView}
, m_focusChain{}
, m_focusedItem{nullptr}
, m_focusedItemIndex{-1}
, m_delegateIndex{0}
{
}
ListViewFocusController::~ListViewFocusController()
{
}
void ListViewFocusController::positionViewAtIndex()
{
QMetaObject::invokeMethod(m_listView, "positionViewAtIndex",
Q_ARG(int, m_delegateIndex), // Index
Q_ARG(int, 2)); // PositionMode (0 = Visible)
}
int ListViewFocusController::size() const
{
return m_listView->property("count").toInt();
}
int ListViewFocusController::currentIndex() const
{
return m_delegateIndex;
}
void ListViewFocusController::incrementIndex()
{
m_delegateIndex++;
}
void ListViewFocusController::decrementCurrentIndex()
{
m_delegateIndex--;
}
QQuickItem* ListViewFocusController::itemAtIndex(const int index)
{
QQuickItem* item{nullptr};
QMetaObject::invokeMethod(m_listView, "itemAtIndex",
Q_RETURN_ARG(QQuickItem*, item),
Q_ARG(int, index));
return item;
}
QQuickItem* ListViewFocusController::currentDelegate()
{
return itemAtIndex(m_delegateIndex);
}
QQuickItem* ListViewFocusController::focusedItem()
{
return m_focusedItem;
}
void ListViewFocusController::focusNextItem()
{
if (m_focusChain.empty()) {
qWarning() << "Empty focusChain with current delegate: " << currentDelegate();
m_focusChain = getSubChain(currentDelegate());
}
m_focusedItemIndex++;
m_focusedItem = qobject_cast<QQuickItem*>(m_focusChain.at(m_focusedItemIndex));
m_focusedItem->forceActiveFocus();
}
void ListViewFocusController::focusPreviousItem()
{
// TODO: implement
}
void ListViewFocusController::resetFocusChain()
{
m_focusChain.clear();
m_focusedItem = nullptr;
m_focusedItemIndex = -1;
}
bool ListViewFocusController::isDelegateLastFocusItem()
{
return m_focusedItem && (m_focusedItem == m_focusChain.last());
}
bool ListViewFocusController::isListViewLastFocusItem()
{
return (m_delegateIndex == size() - 1) && isDelegateLastFocusItem();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
FocusController::FocusController(QQmlApplicationEngine* engine, QObject *parent)
: QObject{parent}
, m_engine{engine}
, m_focusChain{}
, m_focusedItem{nullptr}
, m_focusedItemIndex{-1}
, m_rootItem{nullptr}
, m_lvfc{nullptr}
{
connect(this, &FocusController::rootItemChanged, this, &FocusController::reload);
}
void FocusController::resetFocus()
{
reload();
if (m_focusChain.empty()) {
qWarning() << "There is no focusable elements";
return;
}
if(m_focusedItemIndex == -1) {
m_focusedItemIndex = 0;
m_focusedItem = qobject_cast<QQuickItem*>(m_focusChain.at(m_focusedItemIndex));
m_focusedItem->forceActiveFocus();
}
}
void FocusController::nextKeyTabItem()
{
if (m_lvfc) {
focusNextListViewItem(); // Need to go on first element by default?
return;
}
reload();
if(m_focusChain.empty()) {
qWarning() << "There are no items to navigate";
return;
}
if (m_focusedItemIndex == (m_focusChain.size() - 1)) {
qDebug() << "Last focus index. Making it zero";
m_focusedItemIndex = 0;
} else {
qDebug() << "Incrementing focus index";
m_focusedItemIndex++;
}
m_focusedItem = qobject_cast<QQuickItem*>(m_focusChain.at(m_focusedItemIndex));
if(m_focusedItem == nullptr) {
qWarning() << "Failed to get item to focus on";
return;
}
if(isListView(m_focusedItem)) {
qDebug() << "===>> Found ListView Item: " << m_focusedItem; // TODO: remove?
m_lvfc = new ListViewFocusController(m_focusedItem, this);
focusNextListViewItem();
return;
}
m_focusedItem->forceActiveFocus(Qt::TabFocusReason);
printItems(m_focusChain, m_focusedItem);
}
void FocusController::focusNextListViewItem()
{
m_lvfc->focusNextItem();
if (m_lvfc->isListViewLastFocusItem()) {
delete m_lvfc;
m_lvfc = nullptr;
} else if (m_lvfc->isDelegateLastFocusItem()) {
m_lvfc->resetFocusChain();
m_lvfc->incrementIndex();
m_lvfc->positionViewAtIndex();
}
}
void FocusController::focusPreviousListViewItem()
{
// TODO: implement
}
void FocusController::previousKeyTabItem()
{
reload();
if(m_focusChain.empty()) {
return;
}
if (m_focusedItemIndex <= 0) {
m_focusedItemIndex = m_focusChain.size() - 1;
} else {
m_focusedItemIndex--;
}
m_focusedItem = qobject_cast<QQuickItem*>(m_focusChain.at(m_focusedItemIndex));
m_focusedItem->forceActiveFocus(Qt::TabFocusReason);
qDebug() << "--> Current focus was changed to " << m_focusedItem;
}
void FocusController::nextKeyUpItem()
{
qDebug() << "nextKeyUpItem" << "triggered";
}
void FocusController::nextKeyDownItem()
{
qDebug() << "nextKeyDownItem" << "triggered";
}
void FocusController::nextKeyLeftItem()
{
qDebug() << "nextKeyLeftItem" << "triggered";
}
void FocusController::nextKeyRightItem()
{
qDebug() << "nextKeyRightItem" << "triggered";
}
void FocusController::reload()
{
m_focusChain.clear();
QObjectList rootObjects;
const auto rootItem = m_rootItem;
if (rootItem != nullptr) {
qDebug() << "*** root item: " << rootItem;
rootObjects << qobject_cast<QObject*>(rootItem);
} else {
qDebug() << "*** root item is null";
rootObjects = m_engine->rootObjects();
}
if(rootObjects.empty()) {
qWarning() << "Empty focus chain detected!";
emit focusChainChanged();
return;
}
for(const auto object : rootObjects) {
m_focusChain.append(getSubChain(object));
}
std::sort(m_focusChain.begin(), m_focusChain.end(), isLess);
printItems(m_focusChain, m_focusedItem);
emit focusChainChanged();
if (m_focusChain.empty()) {
m_focusedItemIndex = -1;
qWarning() << "reloaded to empty focus chain";
return;
}
QQuickWindow* window = qobject_cast<QQuickWindow*>(rootObjects[0]);
if (!window) {
window = qobject_cast<QQuickItem*>(rootObjects[0])->window();
}
if (!window) {
qCritical() << "Couldn't get the current window";
return;
}
// qDebug() << "==> Active Focused Item: " << window->activeFocusItem();
// qDebug() << "--> Active Focused Object: " << window->focusObject();
// qDebug() << ">>> Current Focused Item: " << m_focused_item;
m_focusedItemIndex = m_focusChain.indexOf(window->activeFocusItem());
if(m_focusedItemIndex == -1) {
qDebug() << "===>> No focus item in chain. Moving focus to begin...";
// m_focused_item_index = 0; // if not in focus chain current
return;
}
m_focusedItem = qobject_cast<QQuickItem*>(m_focusChain.at(m_focusedItemIndex));
m_focusedItem->forceActiveFocus();
}
void FocusController::setRootItem(QQuickItem* item)
{
m_rootItem = item;
}

View file

@ -0,0 +1,52 @@
#ifndef FOCUSCONTROLLER_H
#define FOCUSCONTROLLER_H
#include <QObject>
class QQuickItem;
class QQmlApplicationEngine;
class ListViewFocusController;
class FocusController : public QObject
{
Q_OBJECT
public:
explicit FocusController(QQmlApplicationEngine* engine, QObject *parent = nullptr);
~FocusController() override = default;
Q_INVOKABLE void nextKeyTabItem();
Q_INVOKABLE void previousKeyTabItem();
Q_INVOKABLE void nextKeyUpItem();
Q_INVOKABLE void nextKeyDownItem();
Q_INVOKABLE void nextKeyLeftItem();
Q_INVOKABLE void nextKeyRightItem();
signals:
void nextTabItemChanged(QObject* item);
void previousTabItemChanged(QObject* item);
void nextKeyUpItemChanged(QObject* item);
void nextKeyDownItemChanged(QObject* item);
void nextKeyLeftItemChanged(QObject* item);
void nextKeyRightItemChanged(QObject* item);
void focusChainChanged();
void rootItemChanged();
public slots:
void resetFocus();
void reload();
void setRootItem(QQuickItem* item);
private:
void focusNextListViewItem();
void focusPreviousListViewItem();
QQmlApplicationEngine* m_engine; // Pointer to engine to get root object
QList<QObject*> m_focusChain; // List of current objects to be focused
QQuickItem* m_focusedItem; // Pointer to the active focus item
qsizetype m_focusedItemIndex; // Active focus item's index in focus chain
QQuickItem* m_rootItem;
ListViewFocusController* m_lvfc; // ListView focus manager
};
#endif // FOCUSCONTROLLER_H

View file

@ -81,7 +81,7 @@ void PageController::keyPressEvent(Qt::Key key)
case Qt::Key_Escape: {
if (m_drawerDepth) {
emit closeTopDrawer();
setDrawerDepth(getDrawerDepth() - 1);
decrementDrawerDepth();
} else {
emit escapePressed();
}
@ -142,11 +142,25 @@ void PageController::setDrawerDepth(const int depth)
}
}
int PageController::getDrawerDepth()
int PageController::getDrawerDepth() const
{
return m_drawerDepth;
}
int PageController::incrementDrawerDepth()
{
return ++m_drawerDepth;
}
int PageController::decrementDrawerDepth()
{
if (m_drawerDepth == 0) {
return m_drawerDepth;
} else {
return --m_drawerDepth;
}
}
void PageController::onShowErrorMessage(ErrorCode errorCode)
{
const auto fullErrorMessage = errorString(errorCode);

View file

@ -100,7 +100,9 @@ public slots:
void closeApplication();
void setDrawerDepth(const int depth);
int getDrawerDepth();
int getDrawerDepth() const;
int incrementDrawerDepth();
int decrementDrawerDepth();
private slots:
void onShowErrorMessage(amnezia::ErrorCode errorCode);
@ -135,9 +137,6 @@ signals:
void escapePressed();
void closeTopDrawer();
void forceTabBarActiveFocus();
void forceStackActiveFocus();
private:
QSharedPointer<ServersModel> m_serversModel;

View file

@ -16,6 +16,16 @@ Button {
property string connectedButtonColor: AmneziaStyle.color.goldenApricot
property bool buttonActiveFocus: activeFocus && (Qt.platform.os !== "android" || SettingsController.isOnTv())
property bool isFocusable: true
Keys.onTabPressed: {
FocusController.nextKeyTabItem()
}
Keys.onBacktabPressed: {
FocusController.previousKeyTabItem()
}
implicitWidth: 190
implicitHeight: 190

View file

@ -14,7 +14,7 @@ DrawerType2 {
width: parent.width
height: parent.height
expandedContent: ColumnLayout {
expandedStateContent: ColumnLayout {
id: content
anchors.top: parent.top
@ -26,14 +26,6 @@ DrawerType2 {
root.expandedHeight = content.implicitHeight + 32
}
Connections {
target: root
enabled: !GC.isMobile()
function onOpened() {
focusItem.forceActiveFocus()
}
}
Header2Type {
Layout.fillWidth: true
Layout.topMargin: 24
@ -44,11 +36,6 @@ DrawerType2 {
headerText: qsTr("Add new connection")
}
Item {
id: focusItem
KeyNavigation.tab: ip.rightButton
}
LabelWithButtonType {
id: ip
Layout.fillWidth: true
@ -61,8 +48,6 @@ DrawerType2 {
PageController.goToPage(PageEnum.PageSetupWizardCredentials)
root.close()
}
KeyNavigation.tab: qrCode.rightButton
}
DividerType {}
@ -78,8 +63,6 @@ DrawerType2 {
PageController.goToPage(PageEnum.PageSetupWizardConfigSource)
root.close()
}
KeyNavigation.tab: focusItem
}
DividerType {}

View file

@ -20,52 +20,71 @@ ListView {
property bool a: true
width: rootWidth
height: menuContent.contentItem.height
height: contentItem.height // TODO: It should be fixed size, not content item height
clip: true
interactive: false
// interactive: false
property FlickableType parentFlickable
property var lastItemTabClicked
// property FlickableType parentFlickable
// property var lastItemTabClicked
property int currentFocusIndex: 0
// property int currentFocusIndex: 0
activeFocusOnTab: true
onActiveFocusChanged: {
if (activeFocus) {
this.currentFocusIndex = 0
this.itemAtIndex(currentFocusIndex).forceActiveFocus()
}
}
snapMode: ListView.SnapToItem
// ScrollBar.vertical: ScrollBar {}
property bool isFocusable: true
Keys.onTabPressed: {
if (currentFocusIndex < this.count - 1) {
currentFocusIndex += 1
this.itemAtIndex(currentFocusIndex).forceActiveFocus()
} else {
currentFocusIndex = 0
if (lastItemTabClicked && typeof lastItemTabClicked === "function") {
lastItemTabClicked()
}
}
console.debug("--> Tab is pressed on HomeContainersListView: ", objectName)
FocusController.nextKeyTabItem()
}
onVisibleChanged: {
if (visible) {
currentFocusIndex = 0
focusItem.forceActiveFocus()
}
Keys.onBacktabPressed: {
console.debug("--> Shift+Tab is pressed on HomeContainersListView: ", objectName)
FocusController.previousKeyTabItem()
}
Item {
id: focusItem
}
// activeFocusOnTab: true
// onActiveFocusChanged: {
// console.log("===========================")
// positionViewAtEnd()
// parentFlickable.ensureVisible(this.itemAtIndex(6))
// if (activeFocus) {
// this.currentFocusIndex = 0
// this.itemAtIndex(currentFocusIndex).forceActiveFocus()
// }
// }
onCurrentFocusIndexChanged: {
if (parentFlickable) {
parentFlickable.ensureVisible(this.itemAtIndex(currentFocusIndex))
}
}
// Keys.onTabPressed: {
// if (currentFocusIndex < this.count - 1) {
// currentFocusIndex += 1
// this.itemAtIndex(currentFocusIndex).forceActiveFocus()
// } else {
// currentFocusIndex = 0
// if (lastItemTabClicked && typeof lastItemTabClicked === "function") {
// lastItemTabClicked()
// }
// }
// }
// onVisibleChanged: {
// if (visible) {
// currentFocusIndex = 0
// focusItem.forceActiveFocus()
// }
// }
// Item {
// id: focusItem
// }
// onCurrentFocusIndexChanged: {
// if (parentFlickable) {
// parentFlickable.ensureVisible(this.itemAtIndex(currentFocusIndex))
// }
// }
ButtonGroup {
id: containersRadioButtonGroup
@ -75,12 +94,6 @@ ListView {
implicitWidth: rootWidth
implicitHeight: content.implicitHeight
onActiveFocusChanged: {
if (activeFocus) {
containerRadioButton.forceActiveFocus()
}
}
ColumnLayout {
id: content
@ -111,13 +124,13 @@ ListView {
}
if (checked) {
containersDropDown.close()
containersDropDown.closeTriggered() // TODO: containersDropDown is outside this file
ServersModel.setDefaultContainer(ServersModel.defaultIndex, proxyDefaultServerContainersModel.mapToSource(index))
} else {
ContainersModel.setProcessedContainerIndex(proxyDefaultServerContainersModel.mapToSource(index))
InstallController.setShouldCreateServer(false)
PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
containersDropDown.close()
containersDropDown.closeTriggered()
}
}

View file

@ -16,7 +16,7 @@ DrawerType2 {
anchors.fill: parent
expandedHeight: parent.height * 0.9
expandedContent: ColumnLayout {
expandedStateContent: ColumnLayout {
id: content
anchors.top: parent.top
@ -24,14 +24,6 @@ DrawerType2 {
anchors.right: parent.right
spacing: 0
Connections {
target: root
enabled: !GC.isMobile()
function onOpened() {
focusItem.forceActiveFocus()
}
}
Header2Type {
Layout.fillWidth: true
Layout.topMargin: 24
@ -43,11 +35,6 @@ DrawerType2 {
descriptionText: qsTr("Allows you to connect to some sites or applications through a VPN connection and bypass others")
}
Item {
id: focusItem
KeyNavigation.tab: splitTunnelingSwitch.visible ? splitTunnelingSwitch : siteBasedSplitTunnelingSwitch.rightButton
}
LabelWithButtonType {
id: splitTunnelingSwitch
Layout.fillWidth: true
@ -59,7 +46,7 @@ DrawerType2 {
descriptionText: qsTr("Enabled \nCan't be disabled for current server")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
KeyNavigation.tab: siteBasedSplitTunnelingSwitch.visible ? siteBasedSplitTunnelingSwitch.rightButton : focusItem
// KeyNavigation.tab: siteBasedSplitTunnelingSwitch.visible ? siteBasedSplitTunnelingSwitch.rightButton : focusItem
clickedFunction: function() {
// PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
@ -80,13 +67,13 @@ DrawerType2 {
descriptionText: enabled && SitesModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
KeyNavigation.tab: appSplitTunnelingSwitch.visible ?
appSplitTunnelingSwitch.rightButton :
focusItem
// KeyNavigation.tab: appSplitTunnelingSwitch.visible ?
// appSplitTunnelingSwitch.rightButton :
// focusItem
clickedFunction: function() {
PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
root.close()
root.closeTriggered()
}
}
@ -103,11 +90,11 @@ DrawerType2 {
descriptionText: AppSplitTunnelingModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
KeyNavigation.tab: focusItem
// KeyNavigation.tab: focusItem
clickedFunction: function() {
PageController.goToPage(PageEnum.PageSettingsAppSplitTunneling)
root.close()
root.closeTriggered()
}
}

View file

@ -26,7 +26,7 @@ DrawerType2 {
id: installedAppsModel
}
expandedContent: Item {
expandedStateContent: Item {
id: container
implicitHeight: expandedHeight

View file

@ -20,7 +20,7 @@ DrawerType2 {
property var yesButtonFunction
property var noButtonFunction
expandedContent: ColumnLayout {
expandedStateContent: ColumnLayout {
id: content
anchors.top: parent.top
@ -37,7 +37,11 @@ DrawerType2 {
target: root
enabled: !GC.isMobile()
function onOpened() {
focusItem.forceActiveFocus()
FocusController.setRoot(root)
}
function onClosed() {
FocusController.setRoot(null)
}
}
@ -59,11 +63,6 @@ DrawerType2 {
text: descriptionText
}
Item {
id: focusItem
KeyNavigation.tab: yesButton
}
BasicButtonType {
id: yesButton
Layout.fillWidth: true
@ -78,8 +77,6 @@ DrawerType2 {
yesButtonFunction()
}
}
KeyNavigation.tab: noButton
}
BasicButtonType {
@ -102,8 +99,6 @@ DrawerType2 {
noButtonFunction()
}
}
KeyNavigation.tab: focusItem
}
}
}

View file

@ -11,7 +11,7 @@ import "../Config"
DrawerType2 {
id: root
expandedContent: Item {
expandedStateContent: Item {
id: container
implicitHeight: root.height * 0.9
@ -24,13 +24,12 @@ DrawerType2 {
target: root
enabled: !GC.isMobile()
function onOpened() {
focusItem.forceActiveFocus()
}
FocusController.setRoot(root)
}
Item {
id: focusItem
KeyNavigation.tab: backButton
function onClosed() {
FocusController.setRoot(null)
}
}
ColumnLayout {
@ -44,8 +43,7 @@ DrawerType2 {
BackButtonType {
id: backButton
backButtonImage: "qrc:/images/controls/arrow-left.svg"
backButtonFunction: function() { root.close() }
KeyNavigation.tab: listView
backButtonFunction: function() { root.closeTriggered() }
}
}
@ -97,15 +95,15 @@ DrawerType2 {
}
}
Keys.onTabPressed: {
if (currentFocusIndex < this.count - 1) {
currentFocusIndex += 1
this.itemAtIndex(currentFocusIndex).forceActiveFocus()
} else {
listViewFocusItem.forceActiveFocus()
focusItem.forceActiveFocus()
}
}
// Keys.onTabPressed: {
// if (currentFocusIndex < this.count - 1) {
// currentFocusIndex += 1
// this.itemAtIndex(currentFocusIndex).forceActiveFocus()
// } else {
// listViewFocusItem.forceActiveFocus()
// focusItem.forceActiveFocus()
// }
// }
Item {
id: listViewFocusItem
@ -195,7 +193,7 @@ DrawerType2 {
onClicked: {
listView.currentIndex = index
LanguageModel.changeLanguage(languageIndex)
root.close()
root.closeTriggered()
}
}
}

View file

@ -0,0 +1,208 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import SortFilterProxyModel 0.2
import PageEnum 1.0
import ProtocolEnum 1.0
import ContainerProps 1.0
import ContainersModelFilters 1.0
import Style 1.0
import "./"
import "../Controls2"
import "../Controls2/TextTypes"
import "../Config"
ListView {
id: root
anchors.top: serversMenuHeader.bottom
anchors.right: parent.right
anchors.left: parent.left
anchors.bottom: parent.bottom
anchors.topMargin: 16
model: ServersModel
currentIndex: ServersModel.defaultIndex
ScrollBar.vertical: ScrollBar {
id: scrollBar
objectName: "scrollBar"
policy: root.height >= root.contentHeight ? ScrollBar.AlwaysOff : ScrollBar.AlwaysOn
}
readonly property bool isFocusable: true
// Keys.onTabPressed: {
// FocusController.nextKeyTabItem()
// }
// activeFocusOnTab: true
// focus: true
property int focusItemIndex: 0
// onFocusItemIndexChanged: {
// console.debug("===>> root onFocusItemIndexChanged")
// // const focusedElement = root.itemAtIndex(focusItemIndex)
// // if (focusedElement) {
// // if (focusedElement.y + focusedElement.height > root.height) {
// // root.contentY = focusedElement.y + focusedElement.height - root.height
// // } else {
// // root.contentY = 0
// // }
// // }
// }
Keys.onUpPressed: scrollBar.decrease()
Keys.onDownPressed: scrollBar.increase()
// Connections {
// target: drawer
// enabled: !GC.isMobile()
// function onIsCollapsedChanged() {
// if (drawer.isCollapsedStateActive) {
// const item = root.itemAtIndex(root.focusItemIndex)
// if (item) { item.serverRadioButtonProperty.focus = false }
// }
// }
// }
Connections {
target: ServersModel
function onDefaultServerIndexChanged(serverIndex) {
root.currentIndex = serverIndex
}
}
clip: true
delegate: Item {
id: menuContentDelegate
objectName: "menuContentDelegate"
property variant delegateData: model
property VerticalRadioButton serverRadioButtonProperty: serverRadioButton
implicitWidth: root.width
implicitHeight: serverRadioButtonContent.implicitHeight
ColumnLayout {
id: serverRadioButtonContent
objectName: "serverRadioButtonContent"
anchors.fill: parent
anchors.rightMargin: 16
anchors.leftMargin: 16
spacing: 0
RowLayout {
objectName: "serverRadioButtonRowLayout"
Layout.fillWidth: true
VerticalRadioButton {
id: serverRadioButton
objectName: "serverRadioButton"
Layout.fillWidth: true
focus: true
text: name
descriptionText: serverDescription
checked: index === root.currentIndex
checkable: !ConnectionController.isConnected
ButtonGroup.group: serversRadioButtonGroup
onClicked: {
if (ConnectionController.isConnected) {
PageController.showNotificationMessage(qsTr("Unable change server while there is an active connection"))
return
}
root.currentIndex = index
ServersModel.defaultIndex = index
}
MouseArea {
anchors.fill: serverRadioButton
cursorShape: Qt.PointingHandCursor
enabled: false
}
// Keys.onTabPressed: serverInfoButton.forceActiveFocus()
Keys.onEnterPressed: serverRadioButton.clicked()
Keys.onReturnPressed: serverRadioButton.clicked()
}
ImageButtonType {
id: serverInfoButton
objectName: "serverInfoButton"
// signal keyTabOnLastElement
// isFocusable: false
image: "qrc:/images/controls/settings.svg"
imageColor: AmneziaStyle.color.paleGray
implicitWidth: 56
implicitHeight: 56
z: 1
// onActiveFocusChanged: {
// console.debug("===>> serverInfoButton::activeFocusChanged")
// if (activeFocus) {
// if (currentIndex === root.count - 1) {
// console.log("---> Latest element")
// keyTabOnLastElement()
// }
// console.log("--->>", currentIndex)
// // serverRadioButton.forceActiveFocus()
// }
// }
// onKeyTabOnLastElement: {
// console.log("*** Signal emmited! ***")
// FocusController.nextKeyTabItem()
// }
// Keys.onTabPressed: {
// console.log("===>> serverInfoButton::Keys.onTabPressed")
// if (root.focusItemIndex < root.count - 1) {
// root.focusItemIndex++
// root.itemAtIndex(root.focusItemIndex).forceActiveFocus()
// } else {
// FocusController.nextKeyTabItem()
// root.contentY = 0
// }
// }
Keys.onEnterPressed: serverInfoButton.clicked()
Keys.onReturnPressed: serverInfoButton.clicked()
onClicked: function() {
console.debug("===>> onClicked serverInfoButton")
ServersModel.processedIndex = index
PageController.goToPage(PageEnum.PageSettingsServerInfo)
drawer.closeTriggered()
}
}
}
DividerType {
Layout.fillWidth: true
Layout.leftMargin: 0
Layout.rightMargin: 0
}
}
}
}

View file

@ -36,7 +36,7 @@ DrawerType2 {
configFileName = "amnezia_config"
}
expandedContent: Item {
expandedStateContent: Item {
implicitHeight: root.expandedHeight
Connections {
@ -57,8 +57,6 @@ DrawerType2 {
anchors.rightMargin: 16
headerText: root.headerText
KeyNavigation.tab: shareButton
}
FlickableType {
@ -86,8 +84,6 @@ DrawerType2 {
text: qsTr("Share")
leftImageSource: "qrc:/images/controls/share-2.svg"
KeyNavigation.tab: copyConfigTextButton
clickedFunc: function() {
var fileName = ""
if (GC.isMobile()) {
@ -124,8 +120,6 @@ DrawerType2 {
Keys.onReturnPressed: { copyConfigTextButton.clicked() }
Keys.onEnterPressed: { copyConfigTextButton.clicked() }
KeyNavigation.tab: copyNativeConfigStringButton.visible ? copyNativeConfigStringButton : showSettingsButton
}
BasicButtonType {
@ -166,8 +160,6 @@ DrawerType2 {
clickedFunc: function() {
configContentDrawer.open()
}
KeyNavigation.tab: header
}
DrawerType2 {
@ -184,24 +176,11 @@ DrawerType2 {
}
}
expandedContent: Item {
expandedStateContent: Item {
id: configContentContainer
implicitHeight: configContentDrawer.expandedHeight
Connections {
target: configContentDrawer
enabled: !GC.isMobile()
function onOpened() {
focusItem.forceActiveFocus()
}
}
Item {
id: focusItem
KeyNavigation.tab: backButton
}
Connections {
target: copyNativeConfigStringButton
function onClicked() {
@ -232,8 +211,6 @@ DrawerType2 {
anchors.topMargin: 16
backButtonFunction: function() { configContentDrawer.close() }
KeyNavigation.tab: focusItem
}
FlickableType {

View file

@ -39,8 +39,6 @@ Rectangle {
implicitWidth: (rootWidth - 32) / 2
text: "UDP"
KeyNavigation.tab: tcpButton
onClicked: {
root.currentIndex = 0
}

View file

@ -4,23 +4,27 @@ import Qt5Compat.GraphicalEffects
import Style 1.0
Item {
FocusScope {
id: root
property string backButtonImage: "qrc:/images/controls/arrow-left.svg"
property var backButtonFunction
// property bool isFocusable: true
// Keys.onTabPressed: {
// FocusController.nextKeyTabItem()
// }
// Keys.onBacktabPressed: {
// FocusController.previousKeyTabItem()
// }
implicitWidth: content.implicitWidth
implicitHeight: content.implicitHeight
visible: backButtonImage !== ""
onActiveFocusChanged: {
if (activeFocus) {
backButton.forceActiveFocus()
}
}
RowLayout {
id: content
@ -35,6 +39,8 @@ Item {
implicitWidth: 40
implicitHeight: 40
// focus: true
onClicked: {
if (backButtonFunction && typeof backButtonFunction === "function") {
backButtonFunction()

View file

@ -35,12 +35,25 @@ Button {
property alias buttonTextLabel: buttonText
property bool isFocusable: true
Keys.onTabPressed: {
console.debug("--> Tab is pressed on BasicButtonType: ", objectName)
FocusController.nextKeyTabItem()
}
Keys.onBacktabPressed: {
console.debug("--> Shift+Tab is pressed on ", objectName)
FocusController.previousKeyTabItem()
}
implicitHeight: 56
hoverEnabled: true
focusPolicy: Qt.TabFocus
onFocusChanged: {
console.debug("===>> BUTTON: active.focus: ", root.activeFocus, " parentFlickable: ", root.parentFlickable )
if (root.activeFocus) {
if (root.parentFlickable) {
root.parentFlickable.ensureVisible(this)

View file

@ -25,10 +25,13 @@ Button {
property real textOpacity: 1.0
property alias focusItem: rightImage
hoverEnabled: true
background: Rectangle {
id: backgroundRect
anchors.fill: parent
radius: 16
@ -44,8 +47,10 @@ Button {
anchors.right: parent.right
implicitHeight: content.implicitHeight
RowLayout {
id: content
anchors.fill: parent
Image {
@ -61,6 +66,7 @@ Button {
}
ColumnLayout {
ListItemTitleType {
text: root.headerText
visible: text !== ""
@ -123,6 +129,7 @@ Button {
Rectangle {
id: rightImageBackground
anchors.fill: parent
radius: 12
color: "transparent"
@ -131,10 +138,9 @@ Button {
PropertyAnimation { duration: 200 }
}
}
onClicked: {
if (clickedFunction && typeof clickedFunction === "function") {
clickedFunction()
}
root.clicked()
}
}
}

View file

@ -9,17 +9,17 @@ import "TextTypes"
Item {
id: root
readonly property string drawerExpanded: "expanded"
readonly property string drawerCollapsed: "collapsed"
readonly property string drawerExpandedStateName: "expanded"
readonly property string drawerCollapsedStateName: "collapsed"
readonly property bool isOpened: drawerContent.state === root.drawerExpanded || (drawerContent.state === root.drawerCollapsed && dragArea.drag.active === true)
readonly property bool isClosed: drawerContent.state === root.drawerCollapsed && dragArea.drag.active === false
// readonly property bool isExpanded: isExpandedStateActive()
// readonly property bool isCollapsed: isCollapsedStateActive()
readonly property bool isExpanded: drawerContent.state === root.drawerExpanded
readonly property bool isCollapsed: drawerContent.state === root.drawerCollapsed
readonly property bool isOpened: isExpandedStateActive() || (isCollapsedStateActive && (dragArea.drag.active === true))
readonly property bool isClosed: isCollapsedStateActive() && (dragArea.drag.active === false)
property Component collapsedContent
property Component expandedContent
property Component collapsedStateContent
property Component expandedStateContent
property string defaultColor: AmneziaStyle.color.onyxBlack
property string borderColor: AmneziaStyle.color.slateGray
@ -29,29 +29,43 @@ Item {
property int depthIndex: 0
signal entered
signal exited
signal cursorEntered
signal cursorExited
signal pressed(bool pressed, bool entered)
signal aboutToHide
signal aboutToShow
signal close
signal open
signal closeTriggered
signal openTriggered
signal closed
signal opened
function isExpandedStateActive() {
return isStateActive(drawerExpandedStateName)
}
function isCollapsedStateActive() {
return isStateActive(drawerCollapsedStateName)
}
function isStateActive(stateName) {
return drawerContent.state === stateName
}
Connections {
target: PageController
function onCloseTopDrawer() {
console.debug("===>> onCloseTopDrawer function")
if (depthIndex === PageController.getDrawerDepth()) {
if (isCollapsed) {
if (isCollapsedStateActive()) {
return
}
aboutToHide()
drawerContent.state = root.drawerCollapsed
drawerContent.state = root.drawerCollapsedStateName
depthIndex = 0
closed()
}
@ -61,30 +75,62 @@ Item {
Connections {
target: root
function onClose() {
if (isCollapsed) {
function onCloseTriggered() {
console.debug("***>> onClose root connection")
if (isCollapsedStateActive()) {
return
}
aboutToHide()
drawerContent.state = root.drawerCollapsed
depthIndex = 0
PageController.setDrawerDepth(PageController.getDrawerDepth() - 1)
closed()
}
function onOpen() {
if (isExpanded) {
function onClosed() {
console.debug("***>> onClosed root connection")
drawerContent.state = root.drawerCollapsedStateName
if (root.isCollapsedStateActive()) {
var initialPageNavigationBarColor = PageController.getInitialPageNavigationBarColor()
if (initialPageNavigationBarColor !== 0xFF1C1D21) {
PageController.updateNavigationBarColor(initialPageNavigationBarColor)
}
}
depthIndex = 0
PageController.decrementDrawerDepth()
FocusController.setRootItem(null)
}
function onOpenTriggered() {
console.debug("===>> onOpen root connection")
if (root.isExpandedStateActive()) {
return
}
aboutToShow()
root.aboutToShow()
drawerContent.state = root.drawerExpanded
depthIndex = PageController.getDrawerDepth() + 1
PageController.setDrawerDepth(depthIndex)
opened()
root.opened()
}
function onOpened() {
drawerContent.state = root.drawerExpandedStateName
console.debug("===>> onOpened root connection")
if (isExpandedStateActive()) {
console.error("new state - extended")
if (PageController.getInitialPageNavigationBarColor() !== 0xFF1C1D21) {
PageController.updateNavigationBarColor(0xFF1C1D21)
}
}
depthIndex = PageController.incrementDrawerDepth()
FocusController.setRootItem(root)
console.debug("===>> Root item has changed to ", root)
}
}
@ -102,18 +148,18 @@ Item {
MouseArea {
id: emptyArea
anchors.fill: parent
enabled: root.isExpanded
visible: enabled
onClicked: {
root.close()
console.debug("===>> onClicked emptyArea")
root.closeTriggered()
}
}
MouseArea {
id: dragArea
objectName: "dragArea"
anchors.fill: drawerContentBackground
cursorShape: root.isCollapsed ? Qt.PointingHandCursor : Qt.ArrowCursor
hoverEnabled: true
enabled: drawerContent.implicitHeight > 0
@ -125,35 +171,46 @@ Item {
/** If drag area is released at any point other than min or max y, transition to the other state */
onReleased: {
if (root.isCollapsed && drawerContent.y < dragArea.drag.maximumY) {
root.open()
console.debug("===>> onReleased dragArea")
if (isCollapsedStateActive() && drawerContent.y < dragArea.drag.maximumY) {
root.openTriggered()
return
}
if (root.isExpanded && drawerContent.y > dragArea.drag.minimumY) {
root.close()
if (isExpandedStateActive() && drawerContent.y > dragArea.drag.minimumY) {
root.closeTriggered()
return
}
}
onEntered: {
root.entered()
console.debug("===>> onEntered dragArea")
root.cursorEntered()
}
onExited: {
root.exited()
console.debug("===>> onExited dragArea")
root.cursorExited()
}
onPressedChanged: {
console.debug("===>> onPressedChanged dragArea")
root.pressed(pressed, entered)
}
onClicked: {
if (root.isCollapsed) {
root.open()
console.debug("===>> onClicked dragArea")
if (isCollapsedStateActive()) {
root.openTriggered()
}
}
}
Rectangle {
id: drawerContentBackground
objectName: "drawerContentBackground"
anchors { left: drawerContent.left; right: drawerContent.right; top: drawerContent.top }
height: root.height
@ -174,53 +231,80 @@ Item {
Item {
id: drawerContent
objectName: "drawerContent"
Drag.active: dragArea.drag.active
anchors.right: root.right
anchors.left: root.left
y: root.height - drawerContent.height
state: root.drawerCollapsed
implicitHeight: root.isCollapsed ? collapsedHeight : expandedHeight
onStateChanged: {
if (root.isCollapsed) {
var initialPageNavigationBarColor = PageController.getInitialPageNavigationBarColor()
if (initialPageNavigationBarColor !== 0xFF1C1D21) {
PageController.updateNavigationBarColor(initialPageNavigationBarColor)
}
return
}
if (root.isExpanded) {
if (PageController.getInitialPageNavigationBarColor() !== 0xFF1C1D21) {
PageController.updateNavigationBarColor(0xFF1C1D21)
}
return
}
}
state: root.drawerCollapsedStateName
states: [
State {
name: root.drawerCollapsed
name: root.drawerCollapsedStateName
PropertyChanges {
target: drawerContent
implicitHeight: collapsedHeight
y: root.height - root.collapsedHeight
}
PropertyChanges {
target: background
color: AmneziaStyle.color.transparent
}
PropertyChanges {
target: dragArea
cursorShape: Qt.PointingHandCursor
}
PropertyChanges {
target: emptyArea
enabled: false
visible: false
}
PropertyChanges {
target: collapsedLoader
// visible: true
}
PropertyChanges {
target: expandedLoader
visible: false
}
},
State {
name: root.drawerExpanded
name: root.drawerExpandedStateName
PropertyChanges {
target: drawerContent
implicitHeight: expandedHeight
y: dragArea.drag.minimumY
}
PropertyChanges {
target: background
color: Qt.rgba(14/255, 14/255, 17/255, 0.8)
}
PropertyChanges {
target: dragArea
cursorShape: Qt.ArrowCursor
}
PropertyChanges {
target: emptyArea
enabled: true
visible: true
}
PropertyChanges {
target: collapsedLoader
// visible: false
}
PropertyChanges {
target: expandedLoader
visible: true
}
}
]
transitions: [
Transition {
from: root.drawerCollapsed
to: root.drawerExpanded
from: root.drawerCollapsedStateName
to: root.drawerExpandedStateName
PropertyAnimation {
target: drawerContent
properties: "y"
@ -228,8 +312,8 @@ Item {
}
},
Transition {
from: root.drawerExpanded
to: root.drawerCollapsed
from: root.drawerExpandedStateName
to: root.drawerCollapsedStateName
PropertyAnimation {
target: drawerContent
properties: "y"
@ -241,7 +325,7 @@ Item {
Loader {
id: collapsedLoader
sourceComponent: root.collapsedContent
sourceComponent: root.collapsedStateContent
anchors.right: parent.right
anchors.left: parent.left
@ -250,8 +334,7 @@ Item {
Loader {
id: expandedLoader
visible: root.isExpanded
sourceComponent: root.expandedContent
sourceComponent: root.expandedStateContent
anchors.right: parent.right
anchors.left: parent.left

View file

@ -45,33 +45,51 @@ Item {
property Item drawerParent
property Component listView
signal open
signal close
signal openTriggered
signal closeTriggered
function popupClosedFunc() {
if (!GC.isMobile()) {
this.forceActiveFocus()
}
readonly property bool isFocusable: true
Keys.onTabPressed: {
FocusController.nextKeyTabItem()
}
property var parentFlickable
onFocusChanged: {
if (root.activeFocus) {
if (root.parentFlickable) {
root.parentFlickable.ensureVisible(root)
}
}
}
// function popupClosedFunc() {
// if (!GC.isMobile()) {
// this.forceActiveFocus()
// }
// }
// property var parentFlickable
// onFocusChanged: {
// if (root.activeFocus) {
// if (root.parentFlickable) {
// root.parentFlickable.ensureVisible(root)
// }
// }
// }
implicitWidth: rootButtonContent.implicitWidth
implicitHeight: rootButtonContent.implicitHeight
onOpen: {
menu.open()
onOpenTriggered: {
menu.openTriggered()
}
onClose: {
menu.close()
onCloseTriggered: {
menu.closeTriggered()
}
Keys.onEnterPressed: {
if (menu.isClosed) {
menu.openTriggered()
}
}
Keys.onReturnPressed: {
if (menu.isClosed) {
menu.openTriggered()
}
}
Rectangle {
@ -153,6 +171,8 @@ Item {
}
ImageButtonType {
// isFocusable: false
Layout.rightMargin: 16
implicitWidth: 40
@ -173,7 +193,7 @@ Item {
if (rootButtonClickedFunction && typeof rootButtonClickedFunction === "function") {
rootButtonClickedFunction()
} else {
menu.open()
menu.openTriggered()
}
}
}
@ -186,27 +206,14 @@ Item {
anchors.fill: parent
expandedHeight: drawerParent.height * drawerHeight
onClosed: {
root.popupClosedFunc()
}
// onClosed: {
// root.popupClosedFunc()
// }
expandedContent: Item {
expandedStateContent: Item {
id: container
implicitHeight: menu.expandedHeight
Connections {
target: menu
enabled: !GC.isMobile()
function onOpened() {
focusItem.forceActiveFocus()
}
}
Item {
id: focusItem
KeyNavigation.tab: backButton
}
ColumnLayout {
id: header
@ -218,17 +225,11 @@ Item {
BackButtonType {
id: backButton
backButtonImage: root.headerBackButtonImage
backButtonFunction: function() { menu.close() }
KeyNavigation.tab: listViewLoader.item
backButtonFunction: function() { menu.closeTriggered() }
// KeyNavigation.tab: listViewLoader.item
}
}
FlickableType {
id: flickable
anchors.top: header.bottom
anchors.topMargin: 16
contentHeight: col.implicitHeight
Column {
id: col
anchors.top: parent.top
@ -253,26 +254,14 @@ Item {
sourceComponent: root.listView
onLoaded: {
listViewLoader.item.parentFlickable = flickable
listViewLoader.item.lastItemTabClicked = function() {
focusItem.forceActiveFocus()
// listViewLoader.item.parentFlickable = flickable
// FocusController.reload()
// listViewLoader.item.lastItemTabClicked = function() {
// focusItem.forceActiveFocus()
// }
}
}
}
}
}
}
}
Keys.onEnterPressed: {
if (menu.isClosed) {
menu.open()
}
}
Keys.onReturnPressed: {
if (menu.isClosed) {
menu.open()
}
}
}

View file

@ -7,7 +7,7 @@ Flickable {
function ensureVisible(item) {
if (item.y < fl.contentY) {
fl.contentY = item.y
fl.contentY = item.y - 40 // 40 is a top margin
} else if (item.y + item.height > fl.contentY + fl.height) {
fl.contentY = item.y + item.height - fl.height + 40 // 40 is a bottom margin
}

View file

@ -27,6 +27,18 @@ RadioButton {
implicitWidth: content.implicitWidth
implicitHeight: content.implicitHeight
property bool isFocusable: true
Keys.onTabPressed: {
console.debug("--> Tab is pressed on BasicButtonType: ", objectName)
FocusController.nextKeyTabItem()
}
Keys.onBacktabPressed: {
console.debug("--> Shift+Tab is pressed on ", objectName)
FocusController.previousKeyTabItem()
}
indicator: Rectangle {
anchors.fill: parent
radius: 16

View file

@ -24,22 +24,23 @@ Button {
property int borderFocusedWidth: 1
hoverEnabled: true
focus: true
focusPolicy: Qt.TabFocus
icon.source: image
icon.color: root.enabled ? imageColor : disableImageColor
property Flickable parentFlickable
property bool isFocusable: true
onFocusChanged: {
if (root.activeFocus) {
if (root.parentFlickable) {
root.parentFlickable.ensureVisible(this)
}
Keys.onTabPressed: {
FocusController.nextKeyTabItem()
}
Keys.onBacktabPressed: {
FocusController.previousKeyTabItem()
}
Keys.onEnterPressed: root.clicked()
Keys.onReturnPressed: root.clicked()
Behavior on icon.color {
PropertyAnimation { duration: 200 }
}

View file

@ -41,27 +41,37 @@ Item {
property bool descriptionOnTop: false
property bool hideDescription: true
property bool isFocusable: !(eyeImage.visible || rightImage.visible) // TODO: this component already has focusable items
Keys.onTabPressed: {
FocusController.nextKeyTabItem()
}
Keys.onBacktabPressed: {
FocusController.previousKeyTabItem()
}
implicitWidth: content.implicitWidth + content.anchors.topMargin + content.anchors.bottomMargin
implicitHeight: content.implicitHeight + content.anchors.leftMargin + content.anchors.rightMargin
onFocusChanged: {
if (root.activeFocus) {
if (root.parentFlickable) {
root.parentFlickable.ensureVisible(root)
}
}
}
// onFocusChanged: {
// if (root.activeFocus) {
// if (root.parentFlickable) {
// root.parentFlickable.ensureVisible(root)
// }
// }
// }
Connections {
target: rightImage
function onFocusChanged() {
if (rightImage.activeFocus) {
if (root.parentFlickable) {
root.parentFlickable.ensureVisible(root)
}
}
}
}
// Connections {
// target: rightImage
// function onFocusChanged() {
// if (rightImage.activeFocus) {
// if (root.parentFlickable) {
// root.parentFlickable.ensureVisible(root)
// }
// }
// }
// }
MouseArea {
anchors.fill: parent

View file

@ -33,40 +33,14 @@ ListView {
property int currentFocusIndex: 0
activeFocusOnTab: true
onActiveFocusChanged: {
if (activeFocus) {
this.currentFocusIndex = 0
this.itemAtIndex(currentFocusIndex).forceActiveFocus()
}
}
property bool isFocusable: true
Keys.onTabPressed: {
if (currentFocusIndex < this.count - 1) {
currentFocusIndex += 1
} else {
currentFocusIndex = 0
}
this.itemAtIndex(currentFocusIndex).forceActiveFocus()
FocusController.nextKeyTabItem()
}
Item {
id: focusItem
Keys.onTabPressed: {
root.forceActiveFocus()
}
}
onVisibleChanged: {
if (visible) {
focusItem.forceActiveFocus()
}
}
onCurrentFocusIndexChanged: {
if (parentFlickable) {
parentFlickable.ensureVisible(this.itemAtIndex(currentFocusIndex))
}
Keys.onBacktabPressed: {
FocusController.previousKeyTabItem()
}
ButtonGroup {
@ -83,12 +57,6 @@ ListView {
implicitWidth: rootWidth
implicitHeight: content.implicitHeight
onActiveFocusChanged: {
if (activeFocus) {
radioButton.forceActiveFocus()
}
}
ColumnLayout {
id: content

View file

@ -9,30 +9,12 @@ Item {
property StackView stackView: StackView.view
property var defaultActiveFocusItem: null
onVisibleChanged: {
if (visible && !GC.isMobile()) {
timer.start()
}
}
function lastItemTabClicked(focusItem) {
if (GC.isMobile()) {
return
}
if (focusItem) {
focusItem.forceActiveFocus()
PageController.forceTabBarActiveFocus()
} else {
if (defaultActiveFocusItem) {
defaultActiveFocusItem.forceActiveFocus()
}
PageController.forceTabBarActiveFocus()
}
}
// MouseArea {
// id: globalMouseArea
// z: 99
@ -49,11 +31,10 @@ Item {
// Set a timer to set focus after a short delay
Timer {
id: timer
interval: 100 // Milliseconds
interval: 1000 // Milliseconds // TODO: return to 500
onTriggered: {
if (defaultActiveFocusItem) {
defaultActiveFocusItem.forceActiveFocus()
}
console.debug("===>> Page creation completed")
FocusController.resetFocus()
}
repeat: false // Stop the timer after one trigger
running: !GC.isMobile() // Start the timer

View file

@ -28,11 +28,11 @@ Popup {
}
onOpened: {
focusItem.forceActiveFocus()
FocusController.setRoot(root)
}
onClosed: {
PageController.forceStackActiveFocus()
FocusController.setRoot(null)
}
background: Rectangle {
@ -72,11 +72,6 @@ Popup {
}
}
Item {
id: focusItem
KeyNavigation.tab: closeButton
}
BasicButtonType {
id: closeButton
visible: closeButtonVisible
@ -92,7 +87,6 @@ Popup {
borderWidth: 0
text: qsTr("Close")
KeyNavigation.tab: focusItem
clickedFunc: function() {
root.close()

View file

@ -35,6 +35,16 @@ Switch {
property string hoveredIndicatorBackgroundColor: AmneziaStyle.color.translucentWhite
property string defaultIndicatorBackgroundColor: AmneziaStyle.color.transparent
property bool isFocusable: true
Keys.onTabPressed: {
FocusController.nextKeyTabItem()
}
Keys.onBacktabPressed: {
FocusController.previousKeyTabItem()
}
hoverEnabled: enabled ? true : false
focusPolicy: Qt.TabFocus

View file

@ -17,10 +17,19 @@ TabButton {
property bool isSelected: false
property bool isFocusable: true
Keys.onTabPressed: {
FocusController.nextKeyTabItem()
}
Keys.onBacktabPressed: {
FocusController.previousKeyTabItem()
}
implicitHeight: 48
hoverEnabled: true
focusPolicy: Qt.TabFocus
background: Rectangle {
id: background

View file

@ -14,13 +14,23 @@ TabButton {
property bool isSelected: false
property bool isFocusable: true
Keys.onTabPressed: {
FocusController.nextKeyTabItem()
}
Keys.onBacktabPressed: {
FocusController.previousKeyTabItem()
}
property string borderFocusedColor: AmneziaStyle.color.paleGray
property int borderFocusedWidth: 1
property var clickedFunc
hoverEnabled: true
focusPolicy: Qt.TabFocus
// focusPolicy: Qt.TabFocus
icon.source: image
icon.color: isSelected ? selectedColor : defaultColor
@ -43,6 +53,7 @@ TabButton {
}
Keys.onEnterPressed: {
console.log("$$$$$$$$$ ENTER PRESSED INSIDE TABIMAGEBUTTONTYPE")
if (root.clickedFunc && typeof root.clickedFunc === "function") {
root.clickedFunc()
}

View file

@ -78,9 +78,6 @@ Rectangle {
placeholderText: root.placeholderText
text: root.text
KeyNavigation.tab: firstButton
onCursorVisibleChanged: {
if (textArea.cursorVisible) {
fl.interactive = true

View file

@ -84,7 +84,16 @@ Item {
TextField {
id: textField
activeFocusOnTab: false
// activeFocusOnTab: false
property bool isFocusable: true
Keys.onTabPressed: {
FocusController.nextKeyTabItem()
}
Keys.onBacktabPressed: {
FocusController.previousKeyTabItem()
}
enabled: root.textFieldEditable
color: root.enabled ? root.textFieldTextColor : root.textFieldTextDisabledColor
@ -209,9 +218,9 @@ Item {
clickedFunc()
}
if (KeyNavigation.tab) {
KeyNavigation.tab.forceActiveFocus();
}
// if (KeyNavigation.tab) {
// KeyNavigation.tab.forceActiveFocus();
// }
}
Keys.onReturnPressed: {
@ -219,8 +228,8 @@ Item {
clickedFunc()
}
if (KeyNavigation.tab) {
KeyNavigation.tab.forceActiveFocus();
}
// if (KeyNavigation.tab) {
// KeyNavigation.tab.forceActiveFocus();
// }
}
}

View file

@ -28,8 +28,14 @@ RadioButton {
property string imageSource
property bool showImage
property bool isFocusable: true
Keys.onTabPressed: {
FocusController.nextKeyTabItem()
}
hoverEnabled: true
focusPolicy: Qt.TabFocus
// focusPolicy: Qt.TabFocus
indicator: Rectangle {
id: background

View file

@ -16,13 +16,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: focusItem
Item {
id: focusItem
KeyNavigation.tab: backButton
}
ColumnLayout {
id: backButtonLayout
@ -34,7 +27,6 @@ PageType {
BackButtonType {
id: backButton
// KeyNavigation.tab: removeButton
}
}
@ -61,7 +53,6 @@ PageType {
headerText: "Dev menu"
}
TextFieldWithHeaderType {
id: passwordTextField
@ -86,8 +77,6 @@ PageType {
SettingsController.gatewayEndpoint = textFieldText
}
}
// KeyNavigation.tab: saveButton
}
SwitcherType {

View file

@ -19,13 +19,13 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: focusItem
Connections {
objectName: "pageControllerConnections"
target: PageController
function onRestorePageHomeState(isContainerInstalled) {
drawer.open()
drawer.openTriggered()
if (isContainerInstalled) {
containersDropDown.rootButtonClickedFunction()
}
@ -33,23 +33,22 @@ PageType {
}
Item {
objectName: "homeColumnItem"
anchors.fill: parent
anchors.bottomMargin: drawer.collapsedHeight
ColumnLayout {
objectName: "homeColumnLayout"
anchors.fill: parent
anchors.topMargin: 34
anchors.bottomMargin: 34
Item {
id: focusItem
KeyNavigation.tab: loggingButton.visible ?
loggingButton :
connectButton
}
BasicButtonType {
id: loggingButton
objectName: "loggingButton"
property bool isLoggingEnabled: SettingsController.isLoggingEnabled
Layout.alignment: Qt.AlignHCenter
@ -69,8 +68,6 @@ PageType {
Keys.onEnterPressed: loggingButton.clicked()
Keys.onReturnPressed: loggingButton.clicked()
KeyNavigation.tab: connectButton
onClicked: {
PageController.goToPage(PageEnum.PageSettingsLogging)
}
@ -78,13 +75,15 @@ PageType {
ConnectButton {
id: connectButton
objectName: "connectButton"
Layout.fillHeight: true
Layout.alignment: Qt.AlignCenter
KeyNavigation.tab: splitTunnelingButton
}
BasicButtonType {
id: splitTunnelingButton
objectName: "splitTunnelingButton"
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.bottomMargin: 34
@ -115,53 +114,47 @@ PageType {
Keys.onEnterPressed: splitTunnelingButton.clicked()
Keys.onReturnPressed: splitTunnelingButton.clicked()
KeyNavigation.tab: drawer
onClicked: {
homeSplitTunnelingDrawer.open()
homeSplitTunnelingDrawer.openTriggered()
}
HomeSplitTunnelingDrawer {
id: homeSplitTunnelingDrawer
objectName: "homeSplitTunnelingDrawer"
parent: root
onClosed: {
if (!GC.isMobile()) {
focusItem.forceActiveFocus()
console.log(objectName, " was closed...")
FocusController.setRootItem(null)
}
}
}
}
}
}
DrawerType2 {
id: drawer
objectName: "drawerProtocol"
anchors.fill: parent
onClosed: {
if (!GC.isMobile()) {
focusItem.forceActiveFocus()
}
}
collapsedStateContent: Item {
objectName: "ProtocolDrawerCollapsedContent"
collapsedContent: Item {
implicitHeight: Qt.platform.os !== "ios" ? root.height * 0.9 : screen.height * 0.77
Component.onCompleted: {
drawer.expandedHeight = implicitHeight
}
Connections {
objectName: "drawerConnections"
target: drawer
enabled: !GC.isMobile()
function onActiveFocusChanged() {
if (drawer.activeFocus && !drawer.isOpened) {
collapsedButtonChevron.forceActiveFocus()
}
}
}
ColumnLayout {
id: collapsed
objectName: "collapsedColumnLayout"
anchors.left: parent.left
anchors.right: parent.right
@ -180,6 +173,8 @@ PageType {
}
RowLayout {
objectName: "rowLayout"
Layout.topMargin: 14
Layout.leftMargin: 24
Layout.rightMargin: 24
@ -188,9 +183,11 @@ PageType {
spacing: 0
Connections {
objectName: "drawerConnections"
target: drawer
function onEntered() {
if (drawer.isCollapsed) {
function onCursorEntered() {
if (drawer.isCollapsedStateActive) {
collapsedButtonChevron.backgroundColor = collapsedButtonChevron.hoveredColor
collapsedButtonHeader.opacity = 0.8
} else {
@ -198,8 +195,8 @@ PageType {
}
}
function onExited() {
if (drawer.isCollapsed) {
function onCursorExited() {
if (drawer.isCollapsedStateActive) {
collapsedButtonChevron.backgroundColor = collapsedButtonChevron.defaultColor
collapsedButtonHeader.opacity = 1
} else {
@ -208,7 +205,7 @@ PageType {
}
function onPressed(pressed, entered) {
if (drawer.isCollapsed) {
if (drawer.isCollapsedStateActive) {
collapsedButtonChevron.backgroundColor = pressed ? collapsedButtonChevron.pressedColor : entered ? collapsedButtonChevron.hoveredColor : collapsedButtonChevron.defaultColor
collapsedButtonHeader.opacity = 0.7
} else {
@ -219,6 +216,8 @@ PageType {
Header1TextType {
id: collapsedButtonHeader
objectName: "collapsedButtonHeader"
Layout.maximumWidth: drawer.width - 48 - 18 - 12
maximumLineCount: 2
@ -227,8 +226,6 @@ PageType {
text: ServersModel.defaultServerName
horizontalAlignment: Qt.AlignHCenter
KeyNavigation.tab: tabBar
Behavior on opacity {
PropertyAnimation { duration: 200 }
}
@ -236,10 +233,11 @@ PageType {
ImageButtonType {
id: collapsedButtonChevron
objectName: "collapsedButtonChevron"
Layout.leftMargin: 8
visible: drawer.isCollapsed
visible: drawer.isCollapsedStateActive()
hoverEnabled: false
image: "qrc:/images/controls/chevron-down.svg"
@ -254,18 +252,19 @@ PageType {
Keys.onEnterPressed: collapsedButtonChevron.clicked()
Keys.onReturnPressed: collapsedButtonChevron.clicked()
Keys.onTabPressed: lastItemTabClicked()
onClicked: {
if (drawer.isCollapsed) {
drawer.open()
console.debug("onClicked collapsedButtonChevron")
if (drawer.isCollapsedStateActive()) {
drawer.openTriggered()
FocusController.setRootItem(drawer)
}
}
}
}
RowLayout {
objectName: "rowLayoutLabel"
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
Layout.topMargin: 8
Layout.bottomMargin: drawer.isCollapsed ? 44 : ServersModel.isDefaultServerFromApi ? 61 : 16
@ -316,6 +315,7 @@ PageType {
ColumnLayout {
id: serversMenuHeader
objectName: "serversMenuHeader"
anchors.top: collapsed.bottom
anchors.right: parent.right
@ -327,13 +327,9 @@ PageType {
visible: !ServersModel.isDefaultServerFromApi
Item {
id: focusItem1
KeyNavigation.tab: containersDropDown
}
DropDownType {
id: containersDropDown
objectName: "containersDropDown"
rootButtonImageColor: AmneziaStyle.color.midnightBlack
rootButtonBackgroundColor: AmneziaStyle.color.paleGray
@ -350,22 +346,23 @@ PageType {
headerBackButtonImage: "qrc:/images/controls/arrow-left.svg"
rootButtonClickedFunction: function() {
containersDropDown.open()
containersDropDown.openTriggered()
}
drawerParent: root
KeyNavigation.tab: serversMenuContent
listView: HomeContainersListView {
id: containersListView
objectName: "containersListView"
rootWidth: root.width
onVisibleChanged: {
if (containersDropDown.visible && !GC.isMobile()) {
focusItem1.forceActiveFocus()
}
}
height: 500 // TODO: make calculated
// isFocusable: false // TODO: this is a workaround. Need to remove it
Connections {
objectName: "rowLayoutConnections"
target: ServersModel
function onDefaultServerIndexChanged() {
@ -407,169 +404,12 @@ PageType {
ButtonGroup {
id: serversRadioButtonGroup
objectName: "serversRadioButtonGroup"
}
ListView {
ServersListView {
id: serversMenuContent
anchors.top: serversMenuHeader.bottom
anchors.right: parent.right
anchors.left: parent.left
anchors.bottom: parent.bottom
anchors.topMargin: 16
model: ServersModel
currentIndex: ServersModel.defaultIndex
ScrollBar.vertical: ScrollBar {
id: scrollBar
policy: serversMenuContent.height >= serversMenuContent.contentHeight ? ScrollBar.AlwaysOff : ScrollBar.AlwaysOn
}
activeFocusOnTab: true
focus: true
property int focusItemIndex: 0
onActiveFocusChanged: {
if (activeFocus) {
serversMenuContent.focusItemIndex = 0
serversMenuContent.itemAtIndex(focusItemIndex).forceActiveFocus()
}
}
onFocusItemIndexChanged: {
const focusedElement = serversMenuContent.itemAtIndex(focusItemIndex)
if (focusedElement) {
if (focusedElement.y + focusedElement.height > serversMenuContent.height) {
serversMenuContent.contentY = focusedElement.y + focusedElement.height - serversMenuContent.height
} else {
serversMenuContent.contentY = 0
}
}
}
Keys.onUpPressed: scrollBar.decrease()
Keys.onDownPressed: scrollBar.increase()
Connections {
target: drawer
enabled: !GC.isMobile()
function onIsCollapsedChanged() {
if (drawer.isCollapsed) {
const item = serversMenuContent.itemAtIndex(serversMenuContent.focusItemIndex)
if (item) { item.serverRadioButtonProperty.focus = false }
}
}
}
Connections {
target: ServersModel
function onDefaultServerIndexChanged(serverIndex) {
serversMenuContent.currentIndex = serverIndex
}
}
clip: true
delegate: Item {
id: menuContentDelegate
property variant delegateData: model
property VerticalRadioButton serverRadioButtonProperty: serverRadioButton
implicitWidth: serversMenuContent.width
implicitHeight: serverRadioButtonContent.implicitHeight
onActiveFocusChanged: {
if (activeFocus) {
serverRadioButton.forceActiveFocus()
}
}
ColumnLayout {
id: serverRadioButtonContent
anchors.fill: parent
anchors.rightMargin: 16
anchors.leftMargin: 16
spacing: 0
RowLayout {
Layout.fillWidth: true
VerticalRadioButton {
id: serverRadioButton
Layout.fillWidth: true
text: name
descriptionText: serverDescription
checked: index === serversMenuContent.currentIndex
checkable: !ConnectionController.isConnected
ButtonGroup.group: serversRadioButtonGroup
onClicked: {
if (ConnectionController.isConnected) {
PageController.showNotificationMessage(qsTr("Unable change server while there is an active connection"))
return
}
serversMenuContent.currentIndex = index
ServersModel.defaultIndex = index
}
MouseArea {
anchors.fill: serverRadioButton
cursorShape: Qt.PointingHandCursor
enabled: false
}
Keys.onTabPressed: serverInfoButton.forceActiveFocus()
Keys.onEnterPressed: serverRadioButton.clicked()
Keys.onReturnPressed: serverRadioButton.clicked()
}
ImageButtonType {
id: serverInfoButton
image: "qrc:/images/controls/settings.svg"
imageColor: AmneziaStyle.color.paleGray
implicitWidth: 56
implicitHeight: 56
z: 1
Keys.onTabPressed: {
if (serversMenuContent.focusItemIndex < serversMenuContent.count - 1) {
serversMenuContent.focusItemIndex++
serversMenuContent.itemAtIndex(serversMenuContent.focusItemIndex).forceActiveFocus()
} else {
focusItem1.forceActiveFocus()
serversMenuContent.contentY = 0
}
}
Keys.onEnterPressed: serverInfoButton.clicked()
Keys.onReturnPressed: serverInfoButton.clicked()
onClicked: function() {
ServersModel.processedIndex = index
PageController.goToPage(PageEnum.PageSettingsServerInfo)
drawer.close()
}
}
}
DividerType {
Layout.fillWidth: true
Layout.leftMargin: 0
Layout.rightMargin: 0
}
}
}
objectName: "serversMenuContent"
}
}
}

View file

@ -17,18 +17,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: listview.currentItem.portTextField.textField
Item {
id: focusItem
onFocusChanged: {
if (activeFocus) {
fl.ensureVisible(focusItem)
}
}
KeyNavigation.tab: backButton
}
ColumnLayout {
id: backButtonLayout
@ -40,7 +28,6 @@ PageType {
BackButtonType {
id: backButton
KeyNavigation.tab: listview.currentItem.portTextField.textField
}
}
@ -114,8 +101,26 @@ PageType {
}
checkEmptyText: true
}
KeyNavigation.tab: junkPacketCountTextField.textField
TextFieldWithHeaderType {
id: mtuTextField
Layout.fillWidth: true
Layout.topMargin: 16
headerText: qsTr("MTU")
textFieldText: mtu
textField.validator: IntValidator { bottom: 576; top: 65535 }
textField.onEditingFinished: {
if (textFieldText === "") {
textFieldText = "0"
}
if (textFieldText !== mtu) {
mtu = textFieldText
}
}
checkEmptyText: true
}
TextFieldWithHeaderType {
@ -139,8 +144,6 @@ PageType {
}
checkEmptyText: true
KeyNavigation.tab: junkPacketMinSizeTextField.textField
}
TextFieldWithHeaderType {
@ -160,8 +163,6 @@ PageType {
}
checkEmptyText: true
KeyNavigation.tab: junkPacketMaxSizeTextField.textField
}
TextFieldWithHeaderType {
@ -181,8 +182,6 @@ PageType {
}
checkEmptyText: true
KeyNavigation.tab: initPacketJunkSizeTextField.textField
}
TextFieldWithHeaderType {
@ -202,8 +201,6 @@ PageType {
}
checkEmptyText: true
KeyNavigation.tab: responsePacketJunkSizeTextField.textField
}
TextFieldWithHeaderType {
@ -223,8 +220,6 @@ PageType {
}
checkEmptyText: true
KeyNavigation.tab: initPacketMagicHeaderTextField.textField
}
TextFieldWithHeaderType {
@ -244,8 +239,6 @@ PageType {
}
checkEmptyText: true
KeyNavigation.tab: responsePacketMagicHeaderTextField.textField
}
TextFieldWithHeaderType {
@ -265,8 +258,6 @@ PageType {
}
checkEmptyText: true
KeyNavigation.tab: transportPacketMagicHeaderTextField.textField
}
TextFieldWithHeaderType {
@ -286,8 +277,6 @@ PageType {
}
checkEmptyText: true
KeyNavigation.tab: underloadPacketMagicHeaderTextField.textField
}
TextFieldWithHeaderType {
@ -307,8 +296,6 @@ PageType {
}
checkEmptyText: true
KeyNavigation.tab: saveRestartButton
}
BasicButtonType {
@ -332,8 +319,6 @@ PageType {
text: qsTr("Save")
Keys.onTabPressed: lastItemTabClicked(focusItem)
clickedFunc: function() {
forceActiveFocus()

View file

@ -16,13 +16,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: listview.currentItem.trafficFromField.textField
Item {
id: focusItem
KeyNavigation.tab: backButton
}
ColumnLayout {
id: backButtonLayout
@ -34,7 +27,6 @@ PageType {
BackButtonType {
id: backButton
KeyNavigation.tab: listview.currentItem.trafficFromField.textField
}
}
@ -110,8 +102,6 @@ PageType {
}
}
}
KeyNavigation.tab: portTextField.textField
}
TextFieldWithHeaderType {
@ -130,8 +120,6 @@ PageType {
port = textFieldText
}
}
KeyNavigation.tab: cipherDropDown
}
DropDownType {
@ -143,7 +131,6 @@ PageType {
headerText: qsTr("Cipher")
drawerParent: root
KeyNavigation.tab: saveRestartButton
listView: ListViewWithRadioButtonType {
id: cipherListView

View file

@ -17,18 +17,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: listview.currentItem.vpnAddressSubnetTextField.textField
Item {
id: focusItem
KeyNavigation.tab: backButton
onActiveFocusChanged: {
if (activeFocus) {
fl.ensureVisible(focusItem)
}
}
}
ColumnLayout {
id: backButtonLayout
@ -40,7 +28,6 @@ PageType {
BackButtonType {
id: backButton
KeyNavigation.tab: listview.currentItem.vpnAddressSubnetTextField.textField
}
}
@ -104,7 +91,6 @@ PageType {
textFieldText: subnetAddress
parentFlickable: fl
KeyNavigation.tab: transportProtoSelector
textField.onEditingFinished: {
if (textFieldText !== subnetAddress) {
@ -132,8 +118,6 @@ PageType {
return transportProto === "tcp" ? 1 : 0
}
KeyNavigation.tab: portTextField.enabled ? portTextField.textField : autoNegotiateEncryprionSwitcher
onCurrentIndexChanged: {
if (transportProto === "tcp" && currentIndex === 0) {
transportProto = "udp"
@ -162,8 +146,6 @@ PageType {
port = textFieldText
}
}
KeyNavigation.tab: autoNegotiateEncryprionSwitcher
}
SwitcherType {
@ -181,10 +163,6 @@ PageType {
autoNegotiateEncryprion = checked
}
}
KeyNavigation.tab: hashDropDown.enabled ?
hashDropDown :
tlsAuthCheckBox
}
DropDownType {
@ -199,9 +177,6 @@ PageType {
drawerParent: root
parentFlickable: fl
KeyNavigation.tab: cipherDropDown.enabled ?
cipherDropDown :
tlsAuthCheckBox
listView: ListViewWithRadioButtonType {
id: hashListView
@ -252,8 +227,6 @@ PageType {
drawerParent: root
parentFlickable: fl
KeyNavigation.tab: tlsAuthCheckBox
listView: ListViewWithRadioButtonType {
id: cipherListView
@ -320,8 +293,6 @@ PageType {
text: qsTr("TLS auth")
checked: tlsAuth
KeyNavigation.tab: blockDnsCheckBox
onCheckedChanged: {
if (checked !== tlsAuth) {
console.log("tlsAuth changed to: " + checked)
@ -339,8 +310,6 @@ PageType {
text: qsTr("Block DNS requests outside of VPN")
checked: blockDns
KeyNavigation.tab: additionalClientCommandsSwitcher
onCheckedChanged: {
if (checked !== blockDns) {
blockDns = checked
@ -355,9 +324,6 @@ PageType {
Layout.fillWidth: true
Layout.topMargin: 32
parentFlickable: fl
KeyNavigation.tab: additionalClientCommandsTextArea.visible ?
additionalClientCommandsTextArea.textArea :
additionalServerCommandsSwitcher
checked: additionalClientCommands !== ""
@ -376,7 +342,7 @@ PageType {
Layout.topMargin: 16
visible: additionalClientCommandsSwitcher.checked
KeyNavigation.tab: additionalServerCommandsSwitcher
parentFlickable: fl
textAreaText: additionalClientCommands
@ -394,9 +360,6 @@ PageType {
Layout.fillWidth: true
Layout.topMargin: 16
parentFlickable: fl
KeyNavigation.tab: additionalServerCommandsTextArea.visible ?
additionalServerCommandsTextArea.textArea :
saveRestartButton
checked: additionalServerCommands !== ""
@ -419,7 +382,6 @@ PageType {
textAreaText: additionalServerCommands
placeholderText: qsTr("Commands:")
parentFlickable: fl
KeyNavigation.tab: saveRestartButton
textArea.onEditingFinished: {
if (additionalServerCommands !== textAreaText) {
additionalServerCommands = textAreaText

View file

@ -19,13 +19,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: focusItem
Item {
id: focusItem
KeyNavigation.tab: backButton
}
ColumnLayout {
id: header
@ -37,7 +30,6 @@ PageType {
BackButtonType {
id: backButton
KeyNavigation.tab: listView
}
HeaderType {
@ -104,8 +96,6 @@ PageType {
configContentDrawer.open()
}
KeyNavigation.tab: removeButton
MouseArea {
anchors.fill: button
cursorShape: Qt.PointingHandCursor
@ -129,7 +119,7 @@ PageType {
parent: root
anchors.fill: parent
expandedContent: Item {
expandedStateContent: Item {
implicitHeight: configContentDrawer.expandedHeight
Connections {
@ -140,11 +130,6 @@ PageType {
}
}
Item {
id: focusItem1
KeyNavigation.tab: backButton1
}
BackButtonType {
id: backButton1
@ -156,8 +141,6 @@ PageType {
backButtonFunction: function() {
configContentDrawer.close()
}
KeyNavigation.tab: focusItem1
}
FlickableType {

View file

@ -16,15 +16,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: listview.currentItem.focusItemId.enabled ?
listview.currentItem.focusItemId.textField :
focusItem
Item {
id: focusItem
KeyNavigation.tab: backButton
}
ColumnLayout {
id: backButtonLayout
@ -36,9 +27,6 @@ PageType {
BackButtonType {
id: backButton
KeyNavigation.tab: listview.currentItem.focusItemId.enabled ?
listview.currentItem.focusItemId.textField :
focusItem
}
}
@ -114,8 +102,6 @@ PageType {
port = textFieldText
}
}
KeyNavigation.tab: cipherDropDown
}
DropDownType {
@ -129,9 +115,9 @@ PageType {
headerText: qsTr("Cipher")
drawerParent: root
KeyNavigation.tab: saveRestartButton
listView: ListViewWithRadioButtonType {
id: cipherListView
rootWidth: root.width

View file

@ -16,13 +16,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: listview
Item {
id: focusItem
KeyNavigation.tab: backButton
}
ColumnLayout {
id: backButtonLayout
@ -34,7 +27,6 @@ PageType {
BackButtonType {
id: backButton
KeyNavigation.tab: listview
}
}
@ -64,12 +56,12 @@ PageType {
model: WireGuardConfigModel
activeFocusOnTab: true
onActiveFocusChanged: {
if (activeFocus) {
listview.itemAtIndex(0)?.focusItemId.forceActiveFocus()
}
}
// activeFocusOnTab: true
// onActiveFocusChanged: {
// if (activeFocus) {
// listview.itemAtIndex(0)?.focusItemId.forceActiveFocus()
// }
// }
delegate: Item {
id: delegateItem
@ -109,8 +101,6 @@ PageType {
textField.maximumLength: 5
textField.validator: IntValidator { bottom: 1; top: 65535 }
KeyNavigation.tab: saveButton
textField.onEditingFinished: {
if (textFieldText !== port) {
port = textFieldText
@ -120,6 +110,26 @@ PageType {
checkEmptyText: true
}
TextFieldWithHeaderType {
id: mtuTextField
Layout.fillWidth: true
Layout.topMargin: 16
headerText: qsTr("MTU")
textFieldText: mtu
textField.validator: IntValidator { bottom: 576; top: 65535 }
textField.onEditingFinished: {
if (textFieldText === "") {
textFieldText = "0"
}
if (textFieldText !== mtu) {
mtu = textFieldText
}
}
checkEmptyText: true
}
BasicButtonType {
id: saveButton
Layout.fillWidth: true

View file

@ -17,13 +17,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: listview
Item {
id: focusItem
KeyNavigation.tab: backButton
}
ColumnLayout {
id: backButtonLayout
@ -35,7 +28,6 @@ PageType {
BackButtonType {
id: backButton
KeyNavigation.tab: listview
}
}
@ -65,12 +57,12 @@ PageType {
model: XrayConfigModel
activeFocusOnTab: true
onActiveFocusChanged: {
if (activeFocus) {
listview.itemAtIndex(0)?.focusItemId.forceActiveFocus()
}
}
// activeFocusOnTab: true
// onActiveFocusChanged: {
// if (activeFocus) {
// listview.itemAtIndex(0)?.focusItemId.forceActiveFocus()
// }
// }
delegate: Item {
property alias focusItemId: textFieldWithHeaderType.textField
@ -103,8 +95,6 @@ PageType {
headerText: qsTr("Disguised as traffic from")
textFieldText: site
KeyNavigation.tab: basicButton
textField.onEditingFinished: {
if (textFieldText !== site) {
var tmpText = textFieldText

View file

@ -16,13 +16,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: focusItem
Item {
id: focusItem
KeyNavigation.tab: backButton
}
ColumnLayout {
id: backButtonLayout
@ -34,7 +27,6 @@ PageType {
BackButtonType {
id: backButton
KeyNavigation.tab: removeButton
}
}

View file

@ -16,8 +16,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: focusItem
Connections {
target: InstallController
@ -26,11 +24,6 @@ PageType {
}
}
Item {
id: focusItem
KeyNavigation.tab: backButton
}
ColumnLayout {
id: backButtonLayout
@ -42,7 +35,6 @@ PageType {
BackButtonType {
id: backButton
KeyNavigation.tab: listview
}
}
@ -107,7 +99,6 @@ PageType {
Layout.topMargin: 32
parentFlickable: fl
KeyNavigation.tab: portLabel.rightButton
text: qsTr("Host")
descriptionText: ServersModel.getProcessedServerData("hostName")
@ -136,7 +127,6 @@ PageType {
descriptionOnTop: true
parentFlickable: fl
KeyNavigation.tab: usernameLabel.rightButton
rightImageSource: "qrc:/images/controls/copy.svg"
rightImageColor: AmneziaStyle.color.paleGray
@ -160,7 +150,6 @@ PageType {
descriptionOnTop: true
parentFlickable: fl
KeyNavigation.tab: passwordLabel.eyeButton
rightImageSource: "qrc:/images/controls/copy.svg"
rightImageColor: AmneziaStyle.color.paleGray
@ -184,7 +173,7 @@ PageType {
descriptionOnTop: true
parentFlickable: fl
eyeButton.KeyNavigation.tab: passwordLabel.rightButton
rightButton.Keys.onTabPressed: {
if (mountButton.visible) {
mountButton.forceActiveFocus()
@ -225,7 +214,6 @@ PageType {
borderWidth: 1
parentFlickable: fl
KeyNavigation.tab: detailedInstructionsButton
text: qsTr("Mount folder on device")

View file

@ -17,8 +17,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: listview
Connections {
target: InstallController
@ -27,11 +25,6 @@ PageType {
}
}
Item {
id: focusItem
KeyNavigation.tab: backButton
}
ColumnLayout {
id: backButtonLayout
@ -43,7 +36,6 @@ PageType {
BackButtonType {
id: backButton
KeyNavigation.tab: listview
}
}
@ -99,7 +91,6 @@ PageType {
Layout.topMargin: 32
parentFlickable: fl
KeyNavigation.tab: portLabel.rightButton
text: qsTr("Host")
descriptionText: ServersModel.getProcessedServerData("hostName")
@ -128,7 +119,6 @@ PageType {
descriptionOnTop: true
parentFlickable: fl
KeyNavigation.tab: usernameLabel.rightButton
rightImageSource: "qrc:/images/controls/copy.svg"
rightImageColor: AmneziaStyle.color.paleGray
@ -152,7 +142,6 @@ PageType {
descriptionOnTop: true
parentFlickable: fl
KeyNavigation.tab: passwordLabel.eyeButton
rightImageSource: "qrc:/images/controls/copy.svg"
rightImageColor: AmneziaStyle.color.paleGray
@ -176,8 +165,6 @@ PageType {
descriptionOnTop: true
parentFlickable: fl
eyeButton.KeyNavigation.tab: passwordLabel.rightButton
rightButton.KeyNavigation.tab: changeSettingsButton
rightImageSource: "qrc:/images/controls/copy.svg"
rightImageColor: AmneziaStyle.color.paleGray
@ -206,7 +193,7 @@ PageType {
}
}
expandedContent: ColumnLayout {
expandedStateContent: ColumnLayout {
property string tempPort: port
property string tempUsername: username
property string tempPassword: password
@ -239,11 +226,6 @@ PageType {
}
}
Item {
id: drawerFocusItem
KeyNavigation.tab: portTextField.textField
}
HeaderType {
Layout.fillWidth: true
@ -268,8 +250,6 @@ PageType {
port = textFieldText
}
}
KeyNavigation.tab: usernameTextField.textField
}
TextFieldWithHeaderType {
@ -290,8 +270,6 @@ PageType {
username = textFieldText
}
}
KeyNavigation.tab: passwordTextField.textField
}
TextFieldWithHeaderType {
@ -322,8 +300,6 @@ PageType {
password = textFieldText
}
}
KeyNavigation.tab: saveButton
}
BasicButtonType {

View file

@ -17,8 +17,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: focusItem
Connections {
target: InstallController
@ -27,11 +25,6 @@ PageType {
}
}
Item {
id: focusItem
KeyNavigation.tab: backButton
}
ColumnLayout {
id: backButtonLayout
@ -43,7 +36,6 @@ PageType {
BackButtonType {
id: backButton
KeyNavigation.tab: websiteName.rightButton
}
}

View file

@ -14,9 +14,7 @@ import "../Config"
PageType {
id: root
defaultActiveFocusItem: header
FlickableType {
FlickableType { // TODO: refactor either replace with ListView or Repeater
id: fl
anchors.top: parent.top
anchors.bottom: parent.bottom
@ -39,8 +37,6 @@ PageType {
Layout.leftMargin: 16
headerText: qsTr("Settings")
KeyNavigation.tab: account.rightButton
}
LabelWithButtonType {
@ -55,8 +51,6 @@ PageType {
clickedFunction: function() {
PageController.goToPage(PageEnum.PageSettingsServersList)
}
KeyNavigation.tab: connection.rightButton
}
DividerType {}
@ -72,8 +66,6 @@ PageType {
clickedFunction: function() {
PageController.goToPage(PageEnum.PageSettingsConnection)
}
KeyNavigation.tab: application.rightButton
}
DividerType {}
@ -89,8 +81,6 @@ PageType {
clickedFunction: function() {
PageController.goToPage(PageEnum.PageSettingsApplication)
}
KeyNavigation.tab: backup.rightButton
}
DividerType {}
@ -106,8 +96,6 @@ PageType {
clickedFunction: function() {
PageController.goToPage(PageEnum.PageSettingsBackup)
}
KeyNavigation.tab: about.rightButton
}
DividerType {}
@ -123,8 +111,6 @@ PageType {
clickedFunction: function() {
PageController.goToPage(PageEnum.PageSettingsAbout)
}
KeyNavigation.tab: close
}
DividerType {}
@ -138,8 +124,6 @@ PageType {
rightImageSource: "qrc:/images/controls/chevron-right.svg"
leftImageSource: "qrc:/images/controls/bug.svg"
// Keys.onTabPressed: lastItemTabClicked(header)
clickedFunction: function() {
PageController.goToPage(PageEnum.PageDevMenu)
}
@ -156,10 +140,9 @@ PageType {
Layout.preferredHeight: about.height
text: qsTr("Close application")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
leftImageSource: "qrc:/images/controls/x-circle.svg"
isLeftImageHoverEnabled: false
Keys.onTabPressed: lastItemTabClicked(header)
// isLeftImageHoverEnabled: false
clickedFunction: function() {
PageController.closeApplication()

View file

@ -14,18 +14,16 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: focusItem
// Item {
// id: focusItem
// KeyNavigation.tab: backButton
Item {
id: focusItem
KeyNavigation.tab: backButton
onFocusChanged: {
if (focusItem.activeFocus) {
fl.contentY = 0
}
}
}
// onFocusChanged: {
// if (focusItem.activeFocus) {
// fl.contentY = 0
// }
// }
// }
BackButtonType {
id: backButton
@ -34,8 +32,6 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
KeyNavigation.tab: telegramButton
}
FlickableType {
@ -106,7 +102,6 @@ PageType {
descriptionText: qsTr("To discuss features")
leftImageSource: "qrc:/images/controls/telegram.svg"
KeyNavigation.tab: mailButton
parentFlickable: fl
clickedFunction: function() {
@ -124,7 +119,6 @@ PageType {
descriptionText: qsTr("For reviews and bug reports")
leftImageSource: "qrc:/images/controls/mail.svg"
KeyNavigation.tab: githubButton
parentFlickable: fl
clickedFunction: function() {
@ -143,7 +137,6 @@ PageType {
text: qsTr("GitHub")
leftImageSource: "qrc:/images/controls/github.svg"
KeyNavigation.tab: websiteButton
parentFlickable: fl
clickedFunction: function() {
@ -161,7 +154,6 @@ PageType {
text: qsTr("Website")
leftImageSource: "qrc:/images/controls/amnezia.svg"
KeyNavigation.tab: checkUpdatesButton
parentFlickable: fl
clickedFunction: function() {
@ -209,7 +201,6 @@ PageType {
text: qsTr("Check for updates")
KeyNavigation.tab: privacyPolicyButton
parentFlickable: fl
clickedFunc: function() {

View file

@ -15,8 +15,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: focusItem
FlickableType {
id: fl
anchors.top: parent.top
@ -32,11 +30,6 @@ PageType {
spacing: 0
Item {
id: focusItem
// KeyNavigation.tab: backButton
}
LabelWithImageType {
Layout.fillWidth: true
Layout.margins: 16

View file

@ -21,8 +21,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: focusItem
property bool pageEnabled
Component.onCompleted: {
@ -66,11 +64,6 @@ PageType {
}
}
Item {
id: focusItem
KeyNavigation.tab: backButton
}
ColumnLayout {
id: header
@ -82,7 +75,6 @@ PageType {
BackButtonType {
id: backButton
KeyNavigation.tab: switcher
}
RowLayout {
@ -103,10 +95,6 @@ PageType {
enabled: root.pageEnabled
KeyNavigation.tab: selector.enabled ?
selector :
searchField.textField
checked: AppSplitTunnelingModel.isTunnelingEnabled
onToggled: {
AppSplitTunnelingModel.toggleSplitTunneling(checked)
@ -130,8 +118,6 @@ PageType {
enabled: Qt.platform.os === "android" && root.pageEnabled
KeyNavigation.tab: searchField.textField
listView: ListViewWithRadioButtonType {
rootWidth: root.width

View file

@ -14,18 +14,15 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: focusItem
// Item {
// id: focusItem
Item {
id: focusItem
KeyNavigation.tab: backButton
onFocusChanged: {
if (focusItem.activeFocus) {
fl.contentY = 0
}
}
}
// onFocusChanged: {
// if (focusItem.activeFocus) {
// fl.contentY = 0
// }
// }
// }
BackButtonType {
id: backButton
@ -35,7 +32,7 @@ PageType {
anchors.right: parent.right
anchors.topMargin: 20
KeyNavigation.tab: GC.isMobile() ? switcher : switcherAutoStart
// KeyNavigation.tab: GC.isMobile() ? switcher : switcherAutoStart
}
FlickableType {
@ -77,8 +74,8 @@ PageType {
}
}
KeyNavigation.tab: Qt.platform.os === "android" && !SettingsController.isNotificationPermissionGranted ?
labelWithButtonNotification.rightButton : labelWithButtonLanguage.rightButton
// KeyNavigation.tab: Qt.platform.os === "android" && !SettingsController.isNotificationPermissionGranted ?
// labelWithButtonNotification.rightButton : labelWithButtonLanguage.rightButton
parentFlickable: fl
}
@ -95,7 +92,7 @@ PageType {
descriptionText: qsTr("Enable notifications to show the VPN state in the status bar")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
KeyNavigation.tab: labelWithButtonLanguage.rightButton
// KeyNavigation.tab: labelWithButtonLanguage.rightButton
parentFlickable: fl
clickedFunction: function() {
@ -117,7 +114,6 @@ PageType {
text: qsTr("Auto start")
descriptionText: qsTr("Launch the application every time the device is starts")
KeyNavigation.tab: switcherAutoConnect
parentFlickable: fl
checked: SettingsController.isAutoStartEnabled()
@ -142,7 +138,6 @@ PageType {
text: qsTr("Auto connect")
descriptionText: qsTr("Connect to VPN on app start")
KeyNavigation.tab: switcherStartMinimized
parentFlickable: fl
checked: SettingsController.isAutoConnectEnabled()
@ -167,7 +162,6 @@ PageType {
text: qsTr("Start minimized")
descriptionText: qsTr("Launch application minimized")
KeyNavigation.tab: labelWithButtonLanguage.rightButton
parentFlickable: fl
checked: SettingsController.isStartMinimizedEnabled()
@ -190,11 +184,10 @@ PageType {
descriptionText: LanguageModel.currentLanguageName
rightImageSource: "qrc:/images/controls/chevron-right.svg"
KeyNavigation.tab: labelWithButtonLogging.rightButton
parentFlickable: fl
clickedFunction: function() {
selectLanguageDrawer.open()
selectLanguageDrawer.openTriggered()
}
}
@ -208,7 +201,6 @@ PageType {
descriptionText: SettingsController.isLoggingEnabled ? qsTr("Enabled") : qsTr("Disabled")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
KeyNavigation.tab: labelWithButtonReset.rightButton
parentFlickable: fl
clickedFunction: function() {
@ -245,12 +237,12 @@ PageType {
}
if (!GC.isMobile()) {
root.defaultActiveFocusItem.forceActiveFocus()
// root.defaultActiveFocusItem.forceActiveFocus()
}
}
var noButtonFunction = function() {
if (!GC.isMobile()) {
root.defaultActiveFocusItem.forceActiveFocus()
// root.defaultActiveFocusItem.forceActiveFocus()
}
}
@ -268,10 +260,10 @@ PageType {
width: root.width
height: root.height
onClosed: {
if (!GC.isMobile()) {
focusItem.forceActiveFocus()
}
}
// onClosed: {
// if (!GC.isMobile()) {
// focusItem.forceActiveFocus()
// }
// }
}
}

View file

@ -17,7 +17,7 @@ import "../Controls2/TextTypes"
PageType {
id: root
defaultActiveFocusItem: focusItem
// defaultActiveFocusItem: focusItem
Connections {
target: SettingsController
@ -36,11 +36,6 @@ PageType {
}
}
Item {
id: focusItem
KeyNavigation.tab: backButton
}
BackButtonType {
id: backButton
@ -48,8 +43,6 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
KeyNavigation.tab: makeBackupButton
}
FlickableType {
@ -111,8 +104,6 @@ PageType {
PageController.showNotificationMessage(qsTr("Backup file saved"))
}
}
KeyNavigation.tab: restoreBackupButton
}
BasicButtonType {

View file

@ -12,15 +12,8 @@ import "../Config"
PageType {
id: root
defaultActiveFocusItem: focusItem
property bool isAppSplitTinnelingEnabled: Qt.platform.os === "windows" || Qt.platform.os === "android"
Item {
id: focusItem
KeyNavigation.tab: backButton
}
BackButtonType {
id: backButton
@ -28,8 +21,6 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
KeyNavigation.tab: amneziaDnsSwitch
}
FlickableType {
@ -67,8 +58,6 @@ PageType {
SettingsController.toggleAmneziaDns(checked)
}
}
KeyNavigation.tab: dnsServersButton.rightButton
}
DividerType {}
@ -84,8 +73,6 @@ PageType {
clickedFunction: function() {
PageController.goToPage(PageEnum.PageSettingsDns)
}
KeyNavigation.tab: splitTunnelingButton.rightButton
}
DividerType {}

View file

@ -14,13 +14,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: primaryDns.textField
Item {
id: focusItem
KeyNavigation.tab: backButton
}
BackButtonType {
id: backButton
@ -28,8 +21,6 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
KeyNavigation.tab: root.defaultActiveFocusItem
}
FlickableType {
@ -80,8 +71,6 @@ PageType {
textField.validator: RegularExpressionValidator {
regularExpression: InstallController.ipAddressRegExp()
}
KeyNavigation.tab: secondaryDns.textField
}
TextFieldWithHeaderType {
@ -94,8 +83,6 @@ PageType {
textField.validator: RegularExpressionValidator {
regularExpression: InstallController.ipAddressRegExp()
}
KeyNavigation.tab: restoreDefaultButton
}
BasicButtonType {
@ -124,19 +111,17 @@ PageType {
PageController.showNotificationMessage(qsTr("Settings have been reset"))
if (!GC.isMobile()) {
defaultActiveFocusItem.forceActiveFocus()
// defaultActiveFocusItem.forceActiveFocus()
}
}
var noButtonFunction = function() {
if (!GC.isMobile()) {
defaultActiveFocusItem.forceActiveFocus()
// defaultActiveFocusItem.forceActiveFocus()
}
}
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
}
KeyNavigation.tab: saveButton
}
BasicButtonType {

View file

@ -16,13 +16,6 @@ import "../Controls2/TextTypes"
PageType {
id: root
defaultActiveFocusItem: focusItem
Item {
id: focusItem
KeyNavigation.tab: backButton
}
BackButtonType {
id: backButton
@ -30,8 +23,6 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
KeyNavigation.tab: switcher
}
FlickableType {
@ -68,12 +59,21 @@ PageType {
text: qsTr("Enable logs")
checked: SettingsController.isLoggingEnabled
//KeyNavigation.tab: openFolderButton
onCheckedChanged: {
if (checked !== SettingsController.isLoggingEnabled) {
SettingsController.isLoggingEnabled = checked
}
}
onFocusChanged: {
console.debug("MOVE THIS LOGIC TO CPP!")
if (activeFocus) {
if (fl) {
fl.ensureVisible(this)
}
}
}
}
DividerType {}
@ -87,8 +87,6 @@ PageType {
leftImageSource: "qrc:/images/controls/trash.svg"
isSmallLeftImage: true
// KeyNavigation.tab: labelWithButton3
clickedFunction: function() {
var headerText = qsTr("Clear logs?")
var yesButtonText = qsTr("Continue")
@ -104,9 +102,9 @@ PageType {
}
}
var noButtonFunction = function() {
if (!GC.isMobile()) {
focusItem.forceActiveFocus()
}
// if (!GC.isMobile()) {
// focusItem.forceActiveFocus()
// }
}
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
@ -142,8 +140,6 @@ PageType {
leftImageSource: "qrc:/images/controls/folder-open.svg"
isSmallLeftImage: true
// KeyNavigation.tab: labelWithButton3
clickedFunction: function() {
SettingsController.openLogsFolder()
}
@ -161,7 +157,14 @@ PageType {
leftImageSource: "qrc:/images/controls/save.svg"
isSmallLeftImage: true
// KeyNavigation.tab: labelWithButton3
onFocusChanged: {
console.debug("MOVE THIS LOGIC TO CPP!")
if (activeFocus) {
if (fl) {
fl.ensureVisible(this)
}
}
}
clickedFunction: function() {
var fileName = ""
@ -221,7 +224,14 @@ PageType {
leftImageSource: "qrc:/images/controls/folder-open.svg"
isSmallLeftImage: true
// KeyNavigation.tab: labelWithButton3
onFocusChanged: {
console.debug("MOVE THIS LOGIC TO CPP!")
if (activeFocus) {
if (fl) {
fl.ensureVisible(this)
}
}
}
clickedFunction: function() {
SettingsController.openServiceLogsFolder()
@ -245,7 +255,14 @@ PageType {
leftImageSource: "qrc:/images/controls/save.svg"
isSmallLeftImage: true
// KeyNavigation.tab: labelWithButton3
onFocusChanged: {
console.debug("MOVE THIS LOGIC TO CPP!")
if (activeFocus) {
if (fl) {
fl.ensureVisible(this)
}
}
}
clickedFunction: function() {
var fileName = ""

View file

@ -100,8 +100,6 @@ PageType {
text: qsTr("Check the server for previously installed Amnezia services")
descriptionText: qsTr("Add them to the application if they were not displayed")
KeyNavigation.tab: labelWithButton2
clickedFunction: function() {
PageController.showBusyIndicator(true)
InstallController.scanServerForInstalledContainers()
@ -121,8 +119,6 @@ PageType {
text: qsTr("Reboot server")
textColor: AmneziaStyle.color.vibrantRed
KeyNavigation.tab: labelWithButton3
clickedFunction: function() {
var headerText = qsTr("Do you want to reboot the server?")
var descriptionText = qsTr("The reboot process may take approximately 30 seconds. Are you sure you wish to proceed?")

View file

@ -25,7 +25,7 @@ PageType {
property int pageSettingsApiServerInfo: 3
property int pageSettingsApiLanguageList: 4
defaultActiveFocusItem: focusItem
// defaultActiveFocusItem: focusItem
Connections {
target: PageController
@ -46,11 +46,6 @@ PageType {
]
}
Item {
id: focusItem
KeyNavigation.tab: header
}
ColumnLayout {
anchors.fill: parent
@ -75,7 +70,6 @@ PageType {
BackButtonType {
id: backButton
KeyNavigation.tab: headerContent.actionButton
backButtonFunction: function() {
if (nestedStackView.currentIndex === root.pageSettingsApiServerInfo &&
@ -108,13 +102,11 @@ PageType {
}
}
KeyNavigation.tab: tabBar
actionButtonFunction: function() {
if (nestedStackView.currentIndex === root.pageSettingsApiLanguageList) {
nestedStackView.currentIndex = root.pageSettingsApiServerInfo
} else {
serverNameEditDrawer.open()
serverNameEditDrawer.openTriggered()
}
}
}
@ -133,7 +125,7 @@ PageType {
}
}
expandedContent: ColumnLayout {
expandedStateContent: ColumnLayout {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
@ -149,11 +141,6 @@ PageType {
}
}
Item {
id: focusItem1
KeyNavigation.tab: serverName.textField
}
TextFieldWithHeaderType {
id: serverName
@ -162,8 +149,6 @@ PageType {
textFieldText: name
textField.maximumLength: 30
checkEmptyText: true
KeyNavigation.tab: saveButton
}
BasicButtonType {
@ -172,7 +157,6 @@ PageType {
Layout.fillWidth: true
text: qsTr("Save")
KeyNavigation.tab: focusItem1
clickedFunc: function() {
if (serverName.textFieldText === "") {
@ -182,7 +166,7 @@ PageType {
if (serverName.textFieldText !== name) {
name = serverName.textFieldText
}
serverNameEditDrawer.close()
serverNameEditDrawer.closeTriggered()
}
}
}
@ -219,7 +203,6 @@ PageType {
isSelected: tabBar.currentIndex === root.pageSettingsServerProtocols
text: qsTr("Protocols")
KeyNavigation.tab: servicesTab
Keys.onReturnPressed: tabBar.currentIndex = root.pageSettingsServerProtocols
Keys.onEnterPressed: tabBar.currentIndex = root.pageSettingsServerProtocols
}
@ -231,7 +214,6 @@ PageType {
isSelected: tabBar.currentIndex === root.pageSettingsServerServices
text: qsTr("Services")
KeyNavigation.tab: dataTab
Keys.onReturnPressed: tabBar.currentIndex = root.pageSettingsServerServices
Keys.onEnterPressed: tabBar.currentIndex = root.pageSettingsServerServices
}

View file

@ -21,13 +21,6 @@ PageType {
property bool isClearCacheVisible: ServersModel.isProcessedServerHasWriteAccess() && !ContainersModel.isServiceContainer(ContainersModel.getProcessedContainerIndex())
defaultActiveFocusItem: focusItem
Item {
id: focusItem
KeyNavigation.tab: backButton
}
ColumnLayout {
id: header
@ -39,7 +32,6 @@ PageType {
BackButtonType {
id: backButton
KeyNavigation.tab: protocols
}
HeaderType {
@ -168,7 +160,6 @@ PageType {
Layout.fillWidth: true
visible: root.isClearCacheVisible
KeyNavigation.tab: removeButton
text: qsTr("Clear profile")

View file

@ -18,13 +18,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: focusItem
Item {
id: focusItem
KeyNavigation.tab: backButton
}
ColumnLayout {
id: header
@ -36,7 +29,6 @@ PageType {
BackButtonType {
id: backButton
KeyNavigation.tab: servers
}
HeaderType {
@ -48,41 +40,36 @@ PageType {
}
}
FlickableType {
id: fl
ListView {
id: servers
objectName: "servers"
width: parent.width
anchors.top: header.bottom
anchors.topMargin: 16
contentHeight: col.implicitHeight
Column {
id: col
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
ListView {
id: servers
width: parent.width
height: servers.contentItem.height
height: 500 // servers.contentItem.height // TODO: calculate height
model: ServersModel
clip: true
interactive: false
activeFocusOnTab: true
focus: true
Keys.onTabPressed: {
if (currentIndex < servers.count - 1) {
servers.incrementCurrentIndex()
} else {
servers.currentIndex = 0
focusItem.forceActiveFocus()
root.lastItemTabClicked()
}
// activeFocusOnTab: true
// focus: true
// Keys.onTabPressed: {
// if (currentIndex < servers.count - 1) {
// servers.incrementCurrentIndex()
// } else {
// servers.currentIndex = 0
// focusItem.forceActiveFocus()
// root.lastItemTabClicked()
// }
fl.ensureVisible(this.currentItem)
}
// fl.ensureVisible(this.currentItem)
// }
onVisibleChanged: {
if (visible) {
@ -94,11 +81,11 @@ PageType {
implicitWidth: servers.width
implicitHeight: delegateContent.implicitHeight
onFocusChanged: {
if (focus) {
server.rightButton.forceActiveFocus()
}
}
// onFocusChanged: {
// if (focus) {
// server.rightButton.forceActiveFocus()
// }
// }
ColumnLayout {
id: delegateContent
@ -112,7 +99,7 @@ PageType {
Layout.fillWidth: true
text: name
parentFlickable: fl
// parentFlickable: fl
descriptionText: {
var servicesNameString = ""
var servicesName = ServersModel.getAllInstalledServicesName(index)
@ -139,5 +126,3 @@ PageType {
}
}
}
}
}

View file

@ -23,13 +23,6 @@ PageType {
property var isServerFromTelegramApi: ServersModel.getDefaultServerData("isServerFromTelegramApi")
defaultActiveFocusItem: searchField.textField
Item {
id: focusItem
KeyNavigation.tab: backButton
}
property bool pageEnabled
Component.onCompleted: {
@ -99,7 +92,6 @@ PageType {
BackButtonType {
id: backButton
KeyNavigation.tab: switcher
}
RowLayout {
@ -129,8 +121,6 @@ PageType {
onToggled: { onToggledFunc() }
Keys.onEnterPressed: { onToggledFunc() }
Keys.onReturnPressed: { onToggledFunc() }
KeyNavigation.tab: selector
}
}
@ -180,11 +170,11 @@ PageType {
}
}
KeyNavigation.tab: {
return sites.count > 0 ?
sites :
searchField.textField
}
// KeyNavigation.tab: {
// return sites.count > 0 ?
// sites :
// searchField.textField
// }
}
}
@ -325,7 +315,7 @@ PageType {
textFieldPlaceholderText: qsTr("website or IP")
buttonImageSource: "qrc:/images/controls/plus.svg"
KeyNavigation.tab: GC.isMobile() ? focusItem : addSiteButtonImage
// KeyNavigation.tab: GC.isMobile() ? focusItem : addSiteButtonImage
clickedFunc: function() {
PageController.showBusyIndicator(true)
@ -344,7 +334,7 @@ PageType {
imageColor: AmneziaStyle.color.paleGray
onClicked: function () {
moreActionsDrawer.open()
moreActionsDrawer.openTriggered()
}
Keys.onReturnPressed: addSiteButtonImage.clicked()
@ -361,12 +351,12 @@ PageType {
expandedHeight: parent.height * 0.4375
onClosed: {
if (root.defaultActiveFocusItem && !GC.isMobile()) {
root.defaultActiveFocusItem.forceActiveFocus()
}
// if (root.defaultActiveFocusItem && !GC.isMobile()) {
// root.defaultActiveFocusItem.forceActiveFocus()
// }
}
expandedContent: ColumnLayout {
expandedStateContent: ColumnLayout {
id: moreActionsDrawerContent
anchors.top: parent.top
@ -387,11 +377,6 @@ PageType {
}
}
Item {
id: focusItem1
KeyNavigation.tab: importSitesButton.rightButton
}
Header2Type {
Layout.fillWidth: true
Layout.margins: 16
@ -407,10 +392,8 @@ PageType {
rightImageSource: "qrc:/images/controls/chevron-right.svg"
clickedFunction: function() {
importSitesDrawer.open()
importSitesDrawer.openTriggered()
}
KeyNavigation.tab: exportSitesButton
}
DividerType {}
@ -420,8 +403,6 @@ PageType {
Layout.fillWidth: true
text: qsTr("Save site list")
KeyNavigation.tab: focusItem1
clickedFunction: function() {
var fileName = ""
if (GC.isMobile()) {
@ -436,7 +417,7 @@ PageType {
if (fileName !== "") {
PageController.showBusyIndicator(true)
SitesController.exportSites(fileName)
moreActionsDrawer.close()
moreActionsDrawer.closeTriggered()
PageController.showBusyIndicator(false)
}
}
@ -458,7 +439,7 @@ PageType {
}
}
expandedContent: Item {
expandedStateContent: Item {
implicitHeight: importSitesDrawer.expandedHeight
Connections {
@ -469,11 +450,6 @@ PageType {
}
}
Item {
id: focusItem2
KeyNavigation.tab: importSitesDrawerBackButton
}
BackButtonType {
id: importSitesDrawerBackButton
@ -482,10 +458,8 @@ PageType {
anchors.right: parent.right
anchors.topMargin: 16
KeyNavigation.tab: importSitesButton2
backButtonFunction: function() {
importSitesDrawer.close()
importSitesDrawer.closeTriggered()
}
}
@ -516,7 +490,6 @@ PageType {
Layout.fillWidth: true
text: qsTr("Replace site list")
KeyNavigation.tab: importSitesButton3
clickedFunction: function() {
var fileName = SystemController.getFileName(qsTr("Open sites file"),
@ -533,7 +506,6 @@ PageType {
id: importSitesButton3
Layout.fillWidth: true
text: qsTr("Add imported sites to existing ones")
KeyNavigation.tab: focusItem2
clickedFunction: function() {
var fileName = SystemController.getFileName(qsTr("Open sites file"),
@ -548,8 +520,8 @@ PageType {
PageController.showBusyIndicator(true)
SitesController.importSites(fileName, replaceExistingSites)
PageController.showBusyIndicator(false)
importSitesDrawer.close()
moreActionsDrawer.close()
importSitesDrawer.closeTriggered()
moreActionsDrawer.closeTriggered()
}
DividerType {}

View file

@ -15,8 +15,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: focusItem
FlickableType {
id: fl
anchors.top: parent.top
@ -32,15 +30,9 @@ PageType {
spacing: 0
Item {
id: focusItem
KeyNavigation.tab: backButton
}
BackButtonType {
id: backButton
Layout.topMargin: 20
// KeyNavigation.tab: fileButton.rightButton
}
HeaderType {

View file

@ -14,8 +14,6 @@ import "../Config"
PageType {
id: root
defaultActiveFocusItem: focusItem
FlickableType {
id: fl
anchors.top: parent.top
@ -31,15 +29,9 @@ PageType {
spacing: 0
Item {
id: focusItem
KeyNavigation.tab: backButton
}
BackButtonType {
id: backButton
Layout.topMargin: 20
// KeyNavigation.tab: fileButton.rightButton
}
HeaderType {

View file

@ -25,7 +25,7 @@ PageType {
}
}
defaultActiveFocusItem: focusItem
// defaultActiveFocusItem: focusItem
FlickableType {
id: fl
@ -42,13 +42,9 @@ PageType {
spacing: 0
Item {
id: focusItem
KeyNavigation.tab: textKey.textField
}
HeaderType {
id: moreButton
property bool isVisible: SettingsController.getInstallationUuid() !== "" || PageController.isStartPageVisible()
Layout.fillWidth: true
@ -60,7 +56,16 @@ PageType {
actionButtonImage: isVisible ? "qrc:/images/controls/more-vertical.svg" : ""
actionButtonFunction: function() {
moreActionsDrawer.open()
moreActionsDrawer.openTriggered()
}
actionButton.onFocusChanged: {
console.debug("MOVE THIS LOGIC TO CPP!")
if (actionButton.activeFocus) {
if (fl) {
fl.ensureVisible(moreButton)
}
}
}
DrawerType2 {
@ -71,7 +76,7 @@ PageType {
anchors.fill: parent
expandedHeight: root.height * 0.5
expandedContent: ColumnLayout {
expandedStateContent: ColumnLayout {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
@ -154,8 +159,6 @@ PageType {
textField.text = ""
textField.paste()
}
KeyNavigation.tab: continueButton
}
BasicButtonType {
@ -166,10 +169,18 @@ PageType {
Layout.rightMargin: 16
Layout.leftMargin: 16
onFocusChanged: {
console.debug("MOVE THIS LOGIC TO CPP!")
if (activeFocus) {
if (fl) {
fl.ensureVisible(this)
}
}
}
visible: textKey.textFieldText !== ""
text: qsTr("Continue")
Keys.onTabPressed: lastItemTabClicked(focusItem)
clickedFunc: function() {
if (ImportController.extractConfigFromData(textKey.textFieldText)) {
@ -203,6 +214,15 @@ PageType {
rightImageSource: "qrc:/images/controls/chevron-right.svg"
leftImageSource: "qrc:/images/controls/amnezia.svg"
focusItem.onFocusChanged: {
console.debug("MOVE THIS LOGIC TO CPP!")
if (focusItem.activeFocus) {
if (fl) {
fl.ensureVisible(apiInstalling)
}
}
}
onClicked: function() {
PageController.showBusyIndicator(true)
var result = InstallController.fillAvailableServices()
@ -227,6 +247,15 @@ PageType {
rightImageSource: "qrc:/images/controls/chevron-right.svg"
leftImageSource: "qrc:/images/controls/server.svg"
focusItem.onFocusChanged: {
console.debug("MOVE THIS LOGIC TO CPP!")
if (focusItem.activeFocus) {
if (fl) {
fl.ensureVisible(manualInstalling)
}
}
}
onClicked: {
PageController.goToPage(PageEnum.PageSetupWizardCredentials)
}
@ -247,6 +276,15 @@ PageType {
rightImageSource: "qrc:/images/controls/chevron-right.svg"
leftImageSource: "qrc:/images/controls/archive-restore.svg"
focusItem.onFocusChanged: {
console.debug("MOVE THIS LOGIC TO CPP!")
if (focusItem.activeFocus) {
if (fl) {
fl.ensureVisible(backupRestore)
}
}
}
onClicked: {
var filePath = SystemController.getFileName(qsTr("Open backup file"),
qsTr("Backup files (*.backup)"))
@ -271,6 +309,13 @@ PageType {
rightImageSource: "qrc:/images/controls/chevron-right.svg"
leftImageSource: "qrc:/images/controls/folder-search-2.svg"
focusItem.onFocusChanged: {
console.debug("MOVE THIS LOGIC TO CPP!")
if (fl) {
fl.ensureVisible(openFile)
}
}
onClicked: {
var nameFilter = !ServersModel.getServersCount() ? "Config or backup files (*.vpn *.ovpn *.conf *.json *.backup)" :
"Config files (*.vpn *.ovpn *.conf *.json)"
@ -298,6 +343,15 @@ PageType {
rightImageSource: "qrc:/images/controls/chevron-right.svg"
leftImageSource: "qrc:/images/controls/scan-line.svg"
focusItem.onFocusChanged: {
console.debug("MOVE THIS LOGIC TO CPP!")
if (focusItem.activeFocus) {
if (fl) {
fl.ensureVisible(scanQr)
}
}
}
onClicked: {
ImportController.startDecodingQr()
if (Qt.platform.os === "ios") {
@ -321,6 +375,15 @@ PageType {
rightImageSource: "qrc:/images/controls/chevron-right.svg"
leftImageSource: "qrc:/images/controls/help-circle.svg"
focusItem.onFocusChanged: {
console.debug("MOVE THIS LOGIC TO CPP!")
if (focusItem.activeFocus) {
if (fl) {
fl.ensureVisible(siteLink)
}
}
}
onClicked: {
Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl())
}

View file

@ -13,12 +13,7 @@ import "../Controls2/TextTypes"
PageType {
id: root
defaultActiveFocusItem: hostname.textField
Item {
id: focusItem
KeyNavigation.tab: backButton
}
// defaultActiveFocusItem: hostname.textField
BackButtonType {
id: backButton
@ -27,8 +22,6 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
KeyNavigation.tab: hostname.textField
}
FlickableType {
@ -64,8 +57,6 @@ PageType {
textField.onFocusChanged: {
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
}
KeyNavigation.tab: username.textField
}
TextFieldWithHeaderType {
@ -78,8 +69,6 @@ PageType {
textField.onFocusChanged: {
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
}
KeyNavigation.tab: secretData.textField
}
TextFieldWithHeaderType {
@ -100,8 +89,6 @@ PageType {
textField.onFocusChanged: {
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
}
KeyNavigation.tab: continueButton
}
BasicButtonType {
@ -112,8 +99,6 @@ PageType {
text: qsTr("Continue")
Keys.onTabPressed: lastItemTabClicked(focusItem)
clickedFunc: function() {
forceActiveFocus()
if (!isCredentialsFilled()) {

View file

@ -17,7 +17,6 @@ PageType {
id: root
property bool isEasySetup: true
defaultActiveFocusItem: focusItem
SortFilterProxyModel {
id: proxyContainersModel
@ -34,14 +33,6 @@ PageType {
}
}
Item {
id: focusItem
implicitWidth: 1
implicitHeight: 54
KeyNavigation.tab: backButton
}
BackButtonType {
id: backButton
@ -49,8 +40,6 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
KeyNavigation.tab: continueButton
}
FlickableType {
@ -163,7 +152,7 @@ PageType {
implicitWidth: parent.width
text: qsTr("Continue")
KeyNavigation.tab: setupLaterButton
parentFlickable: fl
clickedFunc: function() {

View file

@ -62,19 +62,12 @@ PageType {
anchors.rightMargin: 16
anchors.leftMargin: 16
Item {
id: focusItem
KeyNavigation.tab: backButton
}
BackButtonType {
id: backButton
Layout.topMargin: 20
Layout.rightMargin: -16
Layout.leftMargin: -16
KeyNavigation.tab: showDetailsButton
}
HeaderType {
@ -113,13 +106,13 @@ PageType {
parent: root
onClosed: {
if (!GC.isMobile()) {
defaultActiveFocusItem.forceActiveFocus()
// defaultActiveFocusItem.forceActiveFocus()
}
}
anchors.fill: parent
expandedHeight: parent.height * 0.9
expandedContent: Item {
expandedStateContent: Item {
Connections {
target: showDetailsDrawer
enabled: !GC.isMobile()
@ -130,15 +123,15 @@ PageType {
implicitHeight: showDetailsDrawer.expandedHeight
Item {
id: focusItem2
KeyNavigation.tab: showDetailsBackButton
onFocusChanged: {
if (focusItem2.activeFocus) {
fl.contentY = 0
}
}
}
// Item {
// id: focusItem2
// KeyNavigation.tab: showDetailsBackButton
// onFocusChanged: {
// if (focusItem2.activeFocus) {
// fl.contentY = 0
// }
// }
// }
BackButtonType {
id: showDetailsBackButton
@ -148,8 +141,6 @@ PageType {
anchors.right: parent.right
anchors.topMargin: 16
KeyNavigation.tab: showDetailsCloseButton
backButtonFunction: function() {
showDetailsDrawer.close()
}
@ -230,7 +221,7 @@ PageType {
Layout.fillWidth: true
rootWidth: root.width
KeyNavigation.tab: (port.visible && port.enabled) ? port.textField : installButton
// KeyNavigation.tab: (port.visible && port.enabled) ? port.textField : installButton
}
TextFieldWithHeaderType {
@ -242,8 +233,6 @@ PageType {
headerText: qsTr("Port")
textField.maximumLength: 5
textField.validator: IntValidator { bottom: 1; top: 65535 }
KeyNavigation.tab: installButton
}
Rectangle {
@ -289,10 +278,10 @@ PageType {
transportProtoSelector.visible = protocolSelectorVisible
transportProtoHeader.visible = protocolSelectorVisible
if (port.visible && port.enabled)
defaultActiveFocusItem = port.textField
else
defaultActiveFocusItem = focusItem
// if (port.visible && port.enabled)
// defaultActiveFocusItem = port.textField
// else
// defaultActiveFocusItem = focusItem
}
}
}

View file

@ -15,13 +15,6 @@ import "../Config"
PageType {
id: root
defaultActiveFocusItem: focusItem
Item {
id: focusItem
KeyNavigation.tab: backButton
}
SortFilterProxyModel {
id: proxyContainersModel
sourceModel: ContainersModel
@ -52,7 +45,6 @@ PageType {
BackButtonType {
id: backButton
KeyNavigation.tab: containers
}
}

View file

@ -14,8 +14,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: focusItem
ColumnLayout {
id: content
@ -32,11 +30,6 @@ PageType {
Layout.preferredHeight: 287
}
Item {
id: focusItem
KeyNavigation.tab: startButton
}
BasicButtonType {
id: startButton
Layout.fillWidth: true
@ -50,8 +43,6 @@ PageType {
clickedFunc: function() {
PageController.goToPage(PageEnum.PageSetupWizardConfigSource)
}
Keys.onTabPressed: lastItemTabClicked(focusItem)
}
}
}

View file

@ -13,14 +13,6 @@ import "../Config"
PageType {
id: root
defaultActiveFocusItem: textKey.textField
Item {
id: focusItem
KeyNavigation.tab: backButton
}
FlickableType {
id: fl
anchors.top: parent.top
@ -39,7 +31,6 @@ PageType {
BackButtonType {
id: backButton
Layout.topMargin: 20
KeyNavigation.tab: textKey.textField
}
HeaderType {
@ -67,8 +58,6 @@ PageType {
textField.text = ""
textField.paste()
}
KeyNavigation.tab: continueButton
}
}
}

View file

@ -16,13 +16,6 @@ PageType {
property bool showContent: false
defaultActiveFocusItem: focusItem
Item {
id: focusItem
KeyNavigation.tab: backButton
}
BackButtonType {
id: backButton
@ -30,8 +23,6 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
KeyNavigation.tab: showContentButton
}
Connections {
@ -107,7 +98,6 @@ PageType {
textColor: AmneziaStyle.color.goldenApricot
text: showContent ? qsTr("Collapse content") : qsTr("Show content")
KeyNavigation.tab: connectButton
clickedFunc: function() {
showContent = !showContent

View file

@ -18,8 +18,6 @@ import "../Config"
PageType {
id: root
defaultActiveFocusItem: clientNameTextField.textField
enum ConfigType {
AmneziaConnection,
OpenVpn,
@ -47,7 +45,7 @@ PageType {
shareConnectionDrawer.headerText = qsTr("Connection to ") + serverSelector.text
shareConnectionDrawer.configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
shareConnectionDrawer.open()
shareConnectionDrawer.
shareConnectionDrawer.contentVisible = false
PageController.showBusyIndicator(true)
@ -104,7 +102,7 @@ PageType {
}
function onExportErrorOccurred(error) {
shareConnectionDrawer.close()
shareConnectionDrawer.closeTriggered()
PageController.showErrorMessage(error)
}
@ -172,16 +170,6 @@ PageType {
spacing: 0
Item {
id: focusItem
KeyNavigation.tab: header.actionButton
onFocusChanged: {
if (focusItem.activeFocus) {
a.contentY = 0
}
}
}
HeaderType {
id: header
Layout.fillWidth: true
@ -191,10 +179,18 @@ PageType {
actionButtonImage: "qrc:/images/controls/more-vertical.svg"
actionButtonFunction: function() {
shareFullAccessDrawer.open()
shareFullAccessDrawer.openTriggered()
}
KeyNavigation.tab: connectionRadioButton
// KeyNavigation.tab: connectionRadioButton
actionButton.onFocusChanged: {
console.debug("MOVE THIS LOGIC TO CPP!")
if (actionButton.activeFocus) {
if (fl) {
fl.ensureVisible(moreButton)
}
}
}
DrawerType2 {
id: shareFullAccessDrawer
@ -205,11 +201,11 @@ PageType {
expandedHeight: root.height
onClosed: {
if (!GC.isMobile()) {
clientNameTextField.textField.forceActiveFocus()
// clientNameTextField.textField.forceActiveFocus()
}
}
expandedContent: ColumnLayout {
expandedStateContent: ColumnLayout {
id: shareFullAccessDrawerContent
anchors.top: parent.top
anchors.left: parent.left
@ -226,7 +222,7 @@ PageType {
target: shareFullAccessDrawer
enabled: !GC.isMobile()
function onOpened() {
focusItem.forceActiveFocus()
// focusItem.forceActiveFocus()
}
}
@ -240,10 +236,10 @@ PageType {
descriptionText: qsTr("Use for your own devices, or share with those you trust to manage the server.")
}
Item {
id: focusItem
KeyNavigation.tab: shareFullAccessButton.rightButton
}
// Item {
// id: focusItem
// // KeyNavigation.tab: shareFullAccessButton.rightButton
// }
LabelWithButtonType {
id: shareFullAccessButton
@ -251,11 +247,11 @@ PageType {
text: qsTr("Share")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
KeyNavigation.tab: focusItem
// KeyNavigation.tab: focusItem
clickedFunction: function() {
PageController.goToPage(PageEnum.PageShareFullAccess)
shareFullAccessDrawer.close()
shareFullAccessDrawer.closeTriggered()
}
}
@ -288,12 +284,12 @@ PageType {
implicitWidth: (root.width - 32) / 2
text: qsTr("Connection")
KeyNavigation.tab: usersRadioButton
// KeyNavigation.tab: usersRadioButton
onClicked: {
accessTypeSelector.currentIndex = 0
if (!GC.isMobile()) {
clientNameTextField.textField.forceActiveFocus()
// clientNameTextField.textField.forceActiveFocus()
}
}
}
@ -305,7 +301,7 @@ PageType {
implicitWidth: (root.width - 32) / 2
text: qsTr("Users")
KeyNavigation.tab: accessTypeSelector.currentIndex === 0 ? clientNameTextField.textField : serverSelector
// KeyNavigation.tab: accessTypeSelector.currentIndex === 0 ? clientNameTextField.textField : serverSelector
onClicked: {
accessTypeSelector.currentIndex = 1
@ -313,7 +309,7 @@ PageType {
ExportController.updateClientManagementModel(ContainersModel.getProcessedContainerIndex(),
ServersModel.getProcessedServerCredentials())
PageController.showBusyIndicator(false)
focusItem.forceActiveFocus()
// focusItem.forceActiveFocus()
}
}
}
@ -343,7 +339,7 @@ PageType {
checkEmptyText: true
KeyNavigation.tab: serverSelector
// KeyNavigation.tab: serverSelector
}
@ -390,7 +386,7 @@ PageType {
serverSelector.severSelectorIndexChanged()
}
serverSelector.close()
serverSelector.closeTriggered()
}
Component.onCompleted: {
@ -409,7 +405,7 @@ PageType {
}
}
KeyNavigation.tab: protocolSelector
// KeyNavigation.tab: protocolSelector
}
DropDownType {
@ -450,7 +446,7 @@ PageType {
clickedFunction: function() {
handler()
protocolSelector.close()
protocolSelector.closeTriggered()
}
Connections {
@ -509,11 +505,11 @@ PageType {
}
}
KeyNavigation.tab: accessTypeSelector.currentIndex === 0 ?
exportTypeSelector :
isSearchBarVisible ?
searchTextField.textField :
usersHeader.actionButton
// KeyNavigation.tab: accessTypeSelector.currentIndex === 0 ?
// exportTypeSelector : searchTextField.textField
// isSearchBarVisible ?
// searchTextField.textField :
// usersHeader.actionButton
}
DropDownType {
@ -549,7 +545,7 @@ PageType {
clickedFunction: function() {
exportTypeSelector.text = selectedText
exportTypeSelector.currentIndex = currentIndex
exportTypeSelector.close()
exportTypeSelector.closeTriggered()
}
Component.onCompleted: {
@ -558,7 +554,7 @@ PageType {
}
}
KeyNavigation.tab: shareButton
// KeyNavigation.tab: shareButton
}
@ -622,11 +618,11 @@ PageType {
target: root
function onIsSearchBarVisibleChanged() {
if (root.isSearchBarVisible) {
searchTextField.textField.forceActiveFocus()
// searchTextField.textField.forceActiveFocus()
} else {
searchTextField.textFieldText = ""
if (!GC.isMobile()) {
usersHeader.actionButton.forceActiveFocus()
// usersHeader.actionButton.forceActiveFocus()
}
}
}
@ -638,15 +634,15 @@ PageType {
function navigateTo() {
if (GC.isMobile()) {
focusItem.forceActiveFocus()
// focusItem.forceActiveFocus()
return;
}
if (searchTextField.textFieldText === "") {
root.isSearchBarVisible = false
usersHeader.actionButton.forceActiveFocus()
// usersHeader.actionButton.forceActiveFocus()
} else {
closeSearchButton.forceActiveFocus()
// closeSearchButton.forceActiveFocus()
}
}
@ -663,9 +659,9 @@ PageType {
Keys.onTabPressed: {
if (!GC.isMobile()) {
if (clientsListView.model.count > 0) {
clientsListView.forceActiveFocus()
// clientsListView.forceActiveFocus()
} else {
lastItemTabClicked(focusItem)
// lastItemTabClicked(focusItem)
}
}
}
@ -706,10 +702,10 @@ PageType {
if (!GC.isMobile()) {
if (currentIndex < this.count - 1) {
this.incrementCurrentIndex()
currentItem.focusItem.forceActiveFocus()
// currentItem.focusItem.forceActiveFocus()
} else {
this.currentIndex = 0
lastItemTabClicked(focusItem)
// lastItemTabClicked(focusItem)
}
}
}
@ -717,7 +713,7 @@ PageType {
onActiveFocusChanged: {
if (focus && !GC.isMobile()) {
currentIndex = 0
currentItem.focusItem.forceActiveFocus()
// currentItem.focusItem.forceActiveFocus()
}
}
@ -735,7 +731,7 @@ PageType {
implicitWidth: clientsListView.width
implicitHeight: delegateContent.implicitHeight
property alias focusItem: clientFocusItem.rightButton
// property alias focusItem: clientFocusItem.rightButton
ColumnLayout {
id: delegateContent
@ -755,7 +751,7 @@ PageType {
rightImageSource: "qrc:/images/controls/chevron-right.svg"
clickedFunction: function() {
clientInfoDrawer.open()
clientInfoDrawer.openTriggered()
}
}
@ -768,15 +764,15 @@ PageType {
onClosed: {
if (!GC.isMobile()) {
focusItem.forceActiveFocus()
// focusItem.forceActiveFocus()
}
}
width: root.width
height: root.height
expandedContent: ColumnLayout {
id: expandedContent
expandedStateContent: ColumnLayout {
id: expandedStateContent
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
@ -785,14 +781,14 @@ PageType {
anchors.rightMargin: 16
onImplicitHeightChanged: {
clientInfoDrawer.expandedHeight = expandedContent.implicitHeight + 32
clientInfoDrawer.expandedHeight = expandedStateContent.implicitHeight + 32
}
Connections {
target: clientInfoDrawer
enabled: !GC.isMobile()
function onOpened() {
focusItem1.forceActiveFocus()
// focusItem1.forceActiveFocus()
}
}
@ -846,11 +842,6 @@ PageType {
text: qsTr("Allowed IPs: %1").arg(allowedIps)
}
Item {
id: focusItem1
KeyNavigation.tab: renameButton
}
BasicButtonType {
id: renameButton
Layout.fillWidth: true
@ -865,10 +856,10 @@ PageType {
text: qsTr("Rename")
KeyNavigation.tab: revokeButton
// KeyNavigation.tab: revokeButton
clickedFunc: function() {
clientNameEditDrawer.open()
clientNameEditDrawer.openTriggered()
}
DrawerType2 {
@ -881,11 +872,11 @@ PageType {
onClosed: {
if (!GC.isMobile()) {
focusItem1.forceActiveFocus()
// focusItem1.forceActiveFocus()
}
}
expandedContent: ColumnLayout {
expandedStateContent: ColumnLayout {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
@ -897,15 +888,10 @@ PageType {
target: clientNameEditDrawer
enabled: !GC.isMobile()
function onOpened() {
clientNameEditor.textField.forceActiveFocus()
// clientNameEditor.textField.forceActiveFocus()
}
}
Item {
id: focusItem2
KeyNavigation.tab: clientNameEditor.textField
}
TextFieldWithHeaderType {
id: clientNameEditor
Layout.fillWidth: true
@ -914,7 +900,7 @@ PageType {
textField.maximumLength: 20
checkEmptyText: true
KeyNavigation.tab: saveButton
// KeyNavigation.tab: saveButton
}
BasicButtonType {
@ -923,7 +909,7 @@ PageType {
Layout.fillWidth: true
text: qsTr("Save")
KeyNavigation.tab: focusItem2
// KeyNavigation.tab: focusItem2
clickedFunc: function() {
if (clientNameEditor.textFieldText === "") {
@ -937,7 +923,7 @@ PageType {
ContainersModel.getProcessedContainerIndex(),
ServersModel.getProcessedServerCredentials())
PageController.showBusyIndicator(false)
clientNameEditDrawer.close()
clientNameEditDrawer.closeTriggered()
}
}
}
@ -958,7 +944,7 @@ PageType {
borderWidth: 1
text: qsTr("Revoke")
KeyNavigation.tab: focusItem1
// KeyNavigation.tab: focusItem1
clickedFunc: function() {
var headerText = qsTr("Revoke the config for a user - %1?").arg(clientName)
@ -967,12 +953,12 @@ PageType {
var noButtonText = qsTr("Cancel")
var yesButtonFunction = function() {
clientInfoDrawer.close()
clientInfoDrawer.closeTriggered()
root.revokeConfig(index)
}
var noButtonFunction = function() {
if (!GC.isMobile()) {
focusItem1.forceActiveFocus()
// focusItem1.forceActiveFocus()
}
}
@ -993,7 +979,7 @@ PageType {
anchors.fill: parent
onClosed: {
if (!GC.isMobile()) {
clientNameTextField.textField.forceActiveFocus()
// clientNameTextField.textField.forceActiveFocus()
}
}
}
@ -1001,7 +987,7 @@ PageType {
MouseArea {
anchors.fill: parent
onPressed: function(mouse) {
forceActiveFocus()
// forceActiveFocus()
mouse.accepted = false
}
}

View file

@ -18,12 +18,7 @@ import "../Config"
PageType {
id: root
defaultActiveFocusItem: focusItem
Item {
id: focusItem
KeyNavigation.tab: backButton
}
// defaultActiveFocusItem: focusItem
BackButtonType {
id: backButton
@ -32,8 +27,6 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
KeyNavigation.tab: serverSelector
}
FlickableType {
@ -85,8 +78,6 @@ PageType {
descriptionText: qsTr("Server")
headerText: qsTr("Server")
KeyNavigation.tab: shareButton
listView: ListViewWithRadioButtonType {
id: serverSelectorListView
@ -137,8 +128,6 @@ PageType {
text: qsTr("Share")
leftImageSource: "qrc:/images/controls/share-2.svg"
Keys.onTabPressed: lastItemTabClicked(focusItem)
clickedFunc: function() {
PageController.showBusyIndicator(true)
@ -166,10 +155,5 @@ PageType {
id: shareConnectionDrawer
anchors.fill: parent
onClosed: {
if (!GC.isMobile()) {
focusItem.forceActiveFocus()
}
}
}
}

View file

@ -15,12 +15,12 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: homeTabButton
property bool isControlsDisabled: false
property bool isTabBarDisabled: false
Connections {
objectName: "pageControllerConnection"
target: PageController
function onGoToPageHome() {
@ -91,18 +91,20 @@ PageType {
}
}
function onForceTabBarActiveFocus() {
homeTabButton.focus = true
tabBar.forceActiveFocus()
}
// function onForceTabBarActiveFocus() {
// homeTabButton.focus = true
// tabBar.forceActiveFocus()
// }
function onForceStackActiveFocus() {
homeTabButton.focus = true
tabBarStackView.forceActiveFocus()
}
// function onForceStackActiveFocus() {
// homeTabButton.focus = true
// tabBarStackView.forceActiveFocus()
// }
}
Connections {
objectName: "installControllerConnections"
target: InstallController
function onInstallationErrorOccurred(error) {
@ -165,6 +167,8 @@ PageType {
}
Connections {
objectName: "connectionControllerConnections"
target: ConnectionController
function onReconnectWithUpdatedContainer(message) {
@ -182,6 +186,8 @@ PageType {
}
Connections {
objectName: "importControllerConnections"
target: ImportController
function onImportErrorOccurred(error, goToPageHome) {
@ -196,6 +202,8 @@ PageType {
}
Connections {
objectName: "settingsControllerConnections"
target: SettingsController
function onLoggingDisableByWatcher() {
@ -218,6 +226,7 @@ PageType {
StackViewType {
id: tabBarStackView
objectName: "tabBarStackView"
anchors.top: parent.top
anchors.right: parent.right
@ -254,6 +263,7 @@ PageType {
TabBar {
id: tabBar
objectName: "tabBar"
anchors.right: parent.right
anchors.left: parent.left
@ -269,6 +279,8 @@ PageType {
enabled: !root.isControlsDisabled && !root.isTabBarDisabled
background: Shape {
objectName: "backgroundShape"
width: parent.width
height: parent.height
@ -289,21 +301,25 @@ PageType {
TabImageButtonType {
id: homeTabButton
objectName: "homeTabButton"
isSelected: tabBar.currentIndex === 0
image: "qrc:/images/controls/home.svg"
clickedFunc: function () {
tabBarStackView.goToTabBarPage(PageEnum.PageHome)
ServersModel.processedIndex = ServersModel.defaultIndex
tabBar.currentIndex = 0
FocusController.setRootItem(null) // TODO: move to do it automaticaly
}
KeyNavigation.tab: shareTabButton
Keys.onEnterPressed: this.clicked()
Keys.onReturnPressed: this.clicked()
// KeyNavigation.tab: shareTabButton
// Keys.onEnterPressed: this.clicked()
// Keys.onReturnPressed: this.clicked()
}
TabImageButtonType {
id: shareTabButton
objectName: "shareTabButton"
Connections {
target: ServersModel
@ -325,11 +341,13 @@ PageType {
tabBar.currentIndex = 1
}
KeyNavigation.tab: settingsTabButton
// KeyNavigation.tab: settingsTabButton
}
TabImageButtonType {
id: settingsTabButton
objectName: "settingsTabButton"
isSelected: tabBar.currentIndex === 2
image: "qrc:/images/controls/settings-2.svg"
clickedFunc: function () {
@ -337,11 +355,13 @@ PageType {
tabBar.currentIndex = 2
}
KeyNavigation.tab: plusTabButton
// KeyNavigation.tab: plusTabButton
}
TabImageButtonType {
id: plusTabButton
objectName: "plusTabButton"
isSelected: tabBar.currentIndex === 3
image: "qrc:/images/controls/plus.svg"
clickedFunc: function () {
@ -349,7 +369,7 @@ PageType {
tabBar.currentIndex = 3
}
Keys.onTabPressed: PageController.forceStackActiveFocus()
// Keys.onTabPressed: PageController.forceStackActiveFocus()
}
}
}

View file

@ -33,6 +33,8 @@ Window {
title: "AmneziaVPN"
Connections {
objectName: "pageControllerConnections"
target: PageController
function onRaiseMainWindow() {
@ -72,6 +74,8 @@ Window {
}
Connections {
objectName: "settingsControllerConnections"
target: SettingsController
function onChangeSettingsFinished(finishedMessage) {
@ -80,11 +84,15 @@ Window {
}
PageStart {
objectName: "pageStart"
width: root.width
height: root.height
}
Item {
objectName: "popupNotificationItem"
anchors.right: parent.right
anchors.left: parent.left
anchors.bottom: parent.bottom
@ -108,6 +116,8 @@ Window {
}
Item {
objectName: "popupErrorMessageItem"
anchors.right: parent.right
anchors.left: parent.left
anchors.bottom: parent.bottom
@ -120,6 +130,8 @@ Window {
}
Item {
objectName: "privateKeyPassphraseDrawerItem"
anchors.fill: parent
DrawerType2 {
@ -128,7 +140,7 @@ Window {
anchors.fill: parent
expandedHeight: root.height * 0.35
expandedContent: ColumnLayout {
expandedStateContent: ColumnLayout {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
@ -168,7 +180,7 @@ Window {
hidePassword = !hidePassword
}
KeyNavigation.tab: saveButton
// KeyNavigation.tab: saveButton
}
BasicButtonType {
@ -195,6 +207,8 @@ Window {
}
Item {
objectName: "questionDrawerItem"
anchors.fill: parent
QuestionDrawer {
@ -205,6 +219,8 @@ Window {
}
Item {
objectName: "busyIndicatorItem"
anchors.fill: parent
BusyIndicatorType {
@ -221,26 +237,26 @@ Window {
questionDrawer.noButtonText = noButtonText
questionDrawer.yesButtonFunction = function() {
questionDrawer.close()
questionDrawer.closeTriggered()
if (yesButtonFunction && typeof yesButtonFunction === "function") {
yesButtonFunction()
}
}
questionDrawer.noButtonFunction = function() {
questionDrawer.close()
questionDrawer.closeTriggered()
if (noButtonFunction && typeof noButtonFunction === "function") {
noButtonFunction()
}
}
questionDrawer.open()
questionDrawer.openTriggered()
}
FileDialog {
id: mainFileDialog
objectName: "mainFileDialog"
property bool isSaveMode: false
objectName: "mainFileDialog"
fileMode: isSaveMode ? FileDialog.SaveFile : FileDialog.OpenFile
onAccepted: SystemController.fileDialogClosed(true)