diff --git a/.github/workflows/android-qt6.yml b/.github/workflows/android-qt6.yml new file mode 100644 index 00000000..9bcdcd14 --- /dev/null +++ b/.github/workflows/android-qt6.yml @@ -0,0 +1,85 @@ +name: Build for Android (Qt6) + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the master branch +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + runs-on: ubuntu-20.04 + + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: 'recursive' + + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: 17 + distribution: temurin + + - name: Setup Android SDK + uses: android-actions/setup-android@7c5672355aaa8fde5f97a91aa9a99616d1ace6bc # v2 + + - uses: nttld/setup-ndk@8c3b609ff4d54576ea420551943fd34b4d03b0dc # v1 + id: setup-ndk + with: + ndk-version: r25 + add-to-path: false + + - name: Install Qt + uses: jurplel/install-qt-action@43ec12788e42f375acfcb2cec059edfb9572fbaa # v3 + with: + version: '6.6.1' + host: 'linux' + target: 'android' + # Qt 6 only supports multi-arch builds with CMake + arch: 'android_arm64_v8a' + cache: true + + # Qt 6 for Android needs the desktop version for building as well + - name: Install Qt (desktop) + uses: jurplel/install-qt-action@43ec12788e42f375acfcb2cec059edfb9572fbaa # v3 + with: + version: '6.6.1' + host: 'linux' + target: 'desktop' + cache: true + + - name: Build firebird + env: + ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} + ANDROID_NDK_ROOT: ${{ steps.setup-ndk.outputs.ndk-path }} + run: | + mkdir build + cd build + qmake .. + make -j4 apk_install_target + + - name: Pack APK + env: + ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} + ANDROID_NDK_ROOT: ${{ steps.setup-ndk.outputs.ndk-path }} + ANDROID_KEYSTORE: ${{ secrets.ANDROID_KEYSTORE }} + ANDROID_KEYSTORE_PWD: ${{ secrets.ANDROID_KEYSTORE_PWD }} + run: | + cd build + if [ -n "$ANDROID_KEYSTORE_PWD" ]; then + echo "$ANDROID_KEYSTORE" | base64 -d > keystore.jks + androiddeployqt --input android-firebird-emu-deployment-settings.json --output android-build --apk firebird-emu.apk --sign keystore.jks firebirdemugh --storepass "$ANDROID_KEYSTORE_PWD" + else + androiddeployqt --input android-firebird-emu-deployment-settings.json --output android-build --apk firebird-emu.apk + fi + + - name: Upload zip + uses: actions/upload-artifact@v3 + with: + name: firebird-emu-android + path: build/firebird-emu.apk + if-no-files-found: error diff --git a/.github/workflows/macOS.yml b/.github/workflows/macOS.yml index 71a2f53d..62722b20 100644 --- a/.github/workflows/macOS.yml +++ b/.github/workflows/macOS.yml @@ -2,20 +2,20 @@ name: Build macOS on: push: - branches: [ master, ci/macOS ] + branches: [ master ] pull_request: - branches: [ master, ci/macOS ] + branches: [ master ] release: types: [published] jobs: build: - name: "Build: ${{ matrix.os }}" - runs-on: ${{ matrix.os }} + name: "Qt ${{ matrix.qt }}" + runs-on: macOS-latest strategy: fail-fast: false matrix: - os: [macOS-latest] + qt: [ "5.15.2", "6.4.1" ] steps: - name: Checkout Git Repo @@ -26,6 +26,7 @@ jobs: - name: Install Qt uses: jurplel/install-qt-action@43ec12788e42f375acfcb2cec059edfb9572fbaa # v3 with: + version: "${{ matrix.qt }}" target: desktop setup-python: false @@ -86,5 +87,5 @@ jobs: - name: "Upload DMG" uses: actions/upload-artifact@v3 with: - name: firebird-emu_macOS + name: "firebird-emu_macOS-Qt${{ matrix.qt }}" path: firebird-emu_macOS.dmg diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 6a5437b1..da52433f 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -2,22 +2,29 @@ name: Build for Windows on: push: - branches: [ master, ci/windows ] + branches: [ master ] pull_request: - branches: [ master, ci/windows ] + branches: [ master ] release: types: [published] jobs: build: - name: "Build: ${{ matrix.arch }}" + name: "Qt ${{ matrix.qt }} ${{ matrix.arch }}" runs-on: windows-2022 strategy: fail-fast: false matrix: - arch: - - win32 - - win64 + include: + - qt: '5.15.2' + qtmaj: '5' + arch: 'win32' + - qt: '5.15.2' + qtmaj: '5' + arch: 'win64' + - qt: '6.4.1' + qtmaj: '6' + arch: 'win64' steps: - name: Checkout Git Repo @@ -25,20 +32,33 @@ jobs: with: submodules: 'recursive' - - name: Install Qt + - name: "Install Qt ${{ matrix.qt }}" uses: jurplel/install-qt-action@43ec12788e42f375acfcb2cec059edfb9572fbaa # v3 + if: matrix.qtmaj == '5' with: - version: '5.15.2' + version: '${{ matrix.qt }}' host: 'windows' target: 'desktop' arch: '${{ matrix.arch }}_mingw81' tools: 'tools_mingw,qt.tools.${{ matrix.arch }}_mingw810' cache: true + - name: "Install Qt ${{ matrix.qt }}" + uses: jurplel/install-qt-action@43ec12788e42f375acfcb2cec059edfb9572fbaa # v3 + if: matrix.qtmaj != '5' + with: + version: '${{ matrix.qt }}' + host: 'windows' + target: 'desktop' + arch: '${{ matrix.arch }}_mingw' + tools: 'tools_mingw90' + cache: true + - name: Fixup PATH run: | echo "$env:IQTA_TOOLS/mingw810_32/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append echo "$env:IQTA_TOOLS/mingw810_64/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + echo "$env:IQTA_TOOLS/mingw1120_64/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - name: Build firebird-emu run: | @@ -53,7 +73,7 @@ jobs: - name: Upload zip uses: actions/upload-artifact@v3 with: - name: firebird-emu-${{ matrix.arch }} - # Use a wildcard to force a subfolder - path: "build/*-emu/" - if-no-files-found: error + name: firebird-emu-Qt${{ matrix.qtmaj }}-${{ matrix.arch }} + # Use a wildcard to force a subfolder + path: "build/*-emu/" + if-no-files-found: error diff --git a/firebird.pro b/firebird.pro index 8edd798a..20c895a2 100644 --- a/firebird.pro +++ b/firebird.pro @@ -15,7 +15,7 @@ isEmpty(SUPPORT_LINUX) | equals(SUPPORT_LINUX, auto) { # Localization TRANSLATIONS += i18n/de_DE.ts i18n/fr_FR.ts i18n/pl_PL.ts -QT += core gui widgets quickwidgets +QT += core gui widgets quick android: QT += androidextras CONFIG += c++11 diff --git a/lcdwidget.cpp b/lcdwidget.cpp index 6b71ff8f..c626d132 100644 --- a/lcdwidget.cpp +++ b/lcdwidget.cpp @@ -16,7 +16,8 @@ LCDWidget::LCDWidget(QWidget *parent, Qt::WindowFlags f) void LCDWidget::mousePressEvent(QMouseEvent *event) { - the_qml_bridge->setTouchpadState((qreal)event->x() / width(), (qreal)event->y() / height(), true, event->button() == Qt::RightButton); + const auto pos = event->pos(); + the_qml_bridge->setTouchpadState((qreal)pos.x() / width(), (qreal)pos.y() / height(), true, event->button() == Qt::RightButton); } void LCDWidget::mouseReleaseEvent(QMouseEvent *event) @@ -33,7 +34,8 @@ void LCDWidget::mouseReleaseEvent(QMouseEvent *event) void LCDWidget::mouseMoveEvent(QMouseEvent *event) { - the_qml_bridge->setTouchpadState((qreal)event->x() / width(), (qreal)event->y() / height(), keypad.touchpad_contact, keypad.touchpad_down); + const auto pos = event->pos(); + the_qml_bridge->setTouchpadState((qreal)pos.x() / width(), (qreal)pos.y() / height(), keypad.touchpad_contact, keypad.touchpad_down); } void LCDWidget::showEvent(QShowEvent *e) diff --git a/main.cpp b/main.cpp index 53a2b312..5e6e5d70 100644 --- a/main.cpp +++ b/main.cpp @@ -73,12 +73,14 @@ static void migrateSettings() int main(int argc, char **argv) { - #ifdef Q_OS_ANDROID - QGuiApplication::setAttribute(Qt::AA_DisableHighDpiScaling); - #else - QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + #ifdef Q_OS_ANDROID + QGuiApplication::setAttribute(Qt::AA_DisableHighDpiScaling); + #else + QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + #endif + QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #endif - QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #ifdef MOBILE_UI QGuiApplication app(argc, argv); @@ -104,7 +106,9 @@ int main(int argc, char **argv) QCoreApplication::setApplicationName(QStringLiteral("firebird-emu")); // Needed for settings migration - qRegisterMetaTypeStreamOperators(); + #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + qRegisterMetaTypeStreamOperators(); + #endif qRegisterMetaType(); migrateSettings(); diff --git a/mainwindow.cpp b/mainwindow.cpp index 7e42a95c..78d38f58 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "core/debug.h" #include "core/emu.h" @@ -34,14 +35,19 @@ MainWindow::MainWindow(QWidget *parent) : ui->setupUi(this); ui->statusBar->addWidget(&status_label); + // Create Keypad view + auto *keypadView = new QQuickView; + keypadView->setSource(QStringLiteral("qrc:/qml/qml/ScrollingKeypad.qml")); + keypadView->setResizeMode(QQuickView::SizeRootObjectToView); + auto *keypadWidget = QWidget::createWindowContainer(keypadView); + ui->keypadLayout->addWidget(keypadWidget); + // Register QtKeypadBridge for the virtual keyboard functionality - ui->keypadWidget->installEventFilter(&qt_keypad_bridge); + keypadView->installEventFilter(&qt_keypad_bridge); ui->lcdView->installEventFilter(&qt_keypad_bridge); lcd.installEventFilter(&qt_keypad_bridge); - ui->keypadWidget->setAttribute(Qt::WA_AcceptTouchEvents); - - qml_engine = ui->keypadWidget->engine(); + qml_engine = keypadView->engine(); qml_engine->addImportPath(QStringLiteral("qrc:/qml/qml")); // Create config dialog component @@ -123,7 +129,7 @@ MainWindow::MainWindow(QWidget *parent) : languageCode.chop(3); // Chop off file extension QLocale locale(languageCode); QAction *action = new QAction(locale.nativeLanguageName(), ui->menuLanguage); - connect(action, &QAction::triggered, this, [this,languageCode] { this->switchTranslator(languageCode); }); + connect(action, &QAction::triggered, this, [this,locale] { this->switchTranslator(locale); }); ui->menuLanguage->addAction(action); } @@ -950,14 +956,3 @@ void MainWindow::switchToMobileUI() { switchUIMode(true); } - -bool QQuickWidgetLessBroken::event(QEvent *event) -{ - if(event->type() == QEvent::Leave) - { - QMouseEvent ev(QMouseEvent::MouseMove, QPointF(0, 0), Qt::NoButton, Qt::NoButton, Qt::NoModifier); - QQuickWidget::event(&ev); - } - - return QQuickWidget::event(event); -} diff --git a/mainwindow.h b/mainwindow.h index 94833dee..4a240df0 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -4,7 +4,6 @@ #include #include #include -#include #include "emuthread.h" #include "fbaboutdialog.h" @@ -15,24 +14,6 @@ namespace Ui { class MainWindow; } -/* QQuickWidget does not care about QEvent::Leave, - * which results in MouseArea::containsMouse to get stuck when - * the mouse leaves the widget without triggering a move outside - * the MouseArea. Work around it by translating QEvent::Leave - * to a MouseMove to (0/0). */ - -class QQuickWidgetLessBroken : public QQuickWidget -{ - Q_OBJECT - -public: - explicit QQuickWidgetLessBroken(QWidget *parent) : QQuickWidget(parent) {} - virtual ~QQuickWidgetLessBroken() {} - -protected: - bool event(QEvent *event) override; -}; - class MainWindow : public QMainWindow { Q_OBJECT diff --git a/mainwindow.ui b/mainwindow.ui index 2daea3ba..d44111c4 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -343,41 +343,7 @@ Keypad - - - - - - 0 - 0 - - - - - 265 - 90 - - - - - 999999 - 999999 - - - - Qt::NoFocus - - - QQuickWidget::SizeRootObjectToView - - - - qrc:/qml/qml/ScrollingKeypad.qml - - - - - + @@ -664,11 +630,6 @@ - - QQuickWidgetLessBroken - QWidget -
mainwindow.h
-
LCDWidget QWidget diff --git a/qml/ConfigPageDebug.qml b/qml/ConfigPageDebug.qml index a55e8ee4..6ff8b63f 100644 --- a/qml/ConfigPageDebug.qml +++ b/qml/ConfigPageDebug.qml @@ -1,5 +1,5 @@ import QtQuick 2.0 -import QtQuick.Controls 1.0 +import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import Firebird.Emu 1.0 import Firebird.UIComponents 1.0 @@ -43,8 +43,9 @@ ColumnLayout { id: gdbPort Layout.maximumWidth: TextMetrics.normalSize * 8 - minimumValue: 1 - maximumValue: 65535 + from: 1 + to: 65535 + textFromValue: function(value, locale) { return "" + value; } value: Emu.gdbPort onValueChanged: { @@ -91,8 +92,9 @@ ColumnLayout { id: rdbPort Layout.maximumWidth: TextMetrics.normalSize * 8 - minimumValue: 1 - maximumValue: 65535 + from: 1 + to: 65535 + textFromValue: function(value, locale) { return "" + value; } value: Emu.rdbPort onValueChanged: { diff --git a/qml/ConfigPageEmulation.qml b/qml/ConfigPageEmulation.qml index 210bae58..1410ac12 100644 --- a/qml/ConfigPageEmulation.qml +++ b/qml/ConfigPageEmulation.qml @@ -1,5 +1,5 @@ import QtQuick 2.0 -import QtQuick.Controls 1.0 +import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import Firebird.Emu 1.0 import Firebird.UIComponents 1.0 diff --git a/qml/ConfigPageFileTransfer.qml b/qml/ConfigPageFileTransfer.qml index b20a1480..b925a184 100644 --- a/qml/ConfigPageFileTransfer.qml +++ b/qml/ConfigPageFileTransfer.qml @@ -1,7 +1,7 @@ import QtQuick 2.0 -import QtQuick.Controls 1.0 -import QtQuick.Dialogs 1.1 +import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 +import Qt.labs.platform 1.1 import Firebird.Emu 1.0 import Firebird.UIComponents 1.0 @@ -35,12 +35,12 @@ ColumnLayout { active: false sourceComponent: FileDialog { nameFilters: [ qsTr("TNS Documents") +"(*.tns)", qsTr("Operating Systems") + "(*.tno *.tnc *.tco *.tcc *.tlo *.tmo *.tmc *.tco2 *.tcc2 *.tct2)" ] - selectMultiple: true + fileMode: FileDialog.OpenFiles onAccepted: { transferStatus.text = qsTr("Starting"); transferProgress.indeterminate = true; - for(let i = 0; i < fileUrls.length; ++i) - Emu.sendFile(fileUrls[i], Emu.usbdir); + for(let i = 0; i < files.length; ++i) + Emu.sendFile(files[i], Emu.usbdir); } } } @@ -64,8 +64,8 @@ ColumnLayout { ProgressBar { id: transferProgress Layout.fillWidth: true - minimumValue: 0 - maximumValue: 100 + from: 0 + to: 100 } } diff --git a/qml/ConfigPageKits.qml b/qml/ConfigPageKits.qml index e7d50738..ffbe8f8d 100644 --- a/qml/ConfigPageKits.qml +++ b/qml/ConfigPageKits.qml @@ -1,5 +1,5 @@ import QtQuick 2.0 -import QtQuick.Controls 1.0 +import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import Firebird.Emu 1.0 import Firebird.UIComponents 1.0 @@ -26,7 +26,6 @@ ColumnLayout { GroupBox { Layout.fillWidth: true Layout.minimumWidth: contentItem.Layout.minimumWidth - Layout.bottomMargin: -1 title: qsTr("Kit Properties") GridLayout { diff --git a/qml/DrawerButton.qml b/qml/DrawerButton.qml index 7dc64c35..93d37fd7 100644 --- a/qml/DrawerButton.qml +++ b/qml/DrawerButton.qml @@ -1,5 +1,5 @@ import QtQuick 2.0 -import QtQuick.Controls 1.3 +import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import Firebird.UIComponents 1.0 diff --git a/qml/FBConfigDialog.qml b/qml/FBConfigDialog.qml index 6f101504..b8a2f291 100644 --- a/qml/FBConfigDialog.qml +++ b/qml/FBConfigDialog.qml @@ -1,6 +1,6 @@ import QtQuick 2.0 import QtQuick.Window 2.2 -import QtQuick.Controls 1.2 +import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import Firebird.UIComponents 1.0 diff --git a/qml/Firebird/UIComponents/FBLabel.qml b/qml/Firebird/UIComponents/FBLabel.qml index be369ccf..6d5cefd7 100644 --- a/qml/Firebird/UIComponents/FBLabel.qml +++ b/qml/Firebird/UIComponents/FBLabel.qml @@ -1,5 +1,5 @@ import QtQuick 2.0 -import QtQuick.Controls 1.0 +import QtQuick.Controls 2.0 Label { font.family: Qt.platform.os === "windows" ? "Segoe UI" : "system" diff --git a/qml/Firebird/UIComponents/FBLink.qml b/qml/Firebird/UIComponents/FBLink.qml index 542124f3..0c76b9c9 100644 --- a/qml/Firebird/UIComponents/FBLink.qml +++ b/qml/Firebird/UIComponents/FBLink.qml @@ -1,5 +1,5 @@ import QtQuick 2.0 -import QtQuick.Controls 1.0 +import QtQuick.Controls 2.0 FBLabel { signal clicked diff --git a/qml/Firebird/UIComponents/FileSelect.qml b/qml/Firebird/UIComponents/FileSelect.qml index bc40257c..3926d83b 100644 --- a/qml/Firebird/UIComponents/FileSelect.qml +++ b/qml/Firebird/UIComponents/FileSelect.qml @@ -1,10 +1,11 @@ import QtQuick 2.0 -import QtQuick.Controls 1.0 -import QtQuick.Dialogs 1.0 +import QtQuick.Controls 2.3 +import Qt.labs.platform 1.1 import QtQuick.Layouts 1.0 import Firebird.Emu 1.0 RowLayout { + id: root property string filePath: "" property bool selectExisting: true property alias subtext: subtextLabel.text @@ -20,9 +21,9 @@ RowLayout { sourceComponent: FileDialog { folder: Emu.dir(filePath) // If save dialogs are not supported, force an open dialog - selectExisting: parent.selectExisting || !Emu.saveDialogSupported() + fileMode: (root.selectExisting || !Emu.saveDialogSupported()) ? FileDialog.OpenFile : FileDialog.SaveFile onAccepted: { - filePath = Emu.toLocalFile(fileUrl); + filePath = Emu.toLocalFile(file); forceRefresh++; } } @@ -61,18 +62,18 @@ RowLayout { // Button for either custom creation functionality (onCreate) or // if the open file dialog doesn't allow creation, to open a file creation dialog. - IconButton { + Button { visible: showCreateButton || (!selectExisting && !Emu.saveDialogSupported()) - icon: "qrc:/icons/resources/icons/document-new.png" + icon.source: "qrc:/icons/resources/icons/document-new.png" Loader { id: createDialogLoader active: false sourceComponent: FileDialog { - folder: Emu.dir(filePath) - selectExisting: false + folder: Emu.dir(file) + fileMode: FileDialog.SaveFile onAccepted: { - filePath = Emu.toLocalFile(fileUrl); + filePath = Emu.toLocalFile(file); forceRefresh++; } } @@ -88,8 +89,8 @@ RowLayout { } } - IconButton { - icon: "qrc:/icons/resources/icons/document-edit.png" + Button { + icon.source: "qrc:/icons/resources/icons/document-edit.png" onClicked: { dialogLoader.active = true; dialogLoader.item.visible = true; diff --git a/qml/Firebird/UIComponents/IconButton.qml b/qml/Firebird/UIComponents/IconButton.qml deleted file mode 100644 index d8c93ac4..00000000 --- a/qml/Firebird/UIComponents/IconButton.qml +++ /dev/null @@ -1,23 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Controls 1.0 - -/* A push button with a symbol instead of text. - * ToolButton and in Label don't size correctly, - * so do it manually. - * With QQC2, button icons have a better default size - * and it can also be specified explicitly. */ - -Button { - property alias icon: image.source - - implicitHeight: TextMetrics.normalSize * 2.5 - implicitWidth: implicitHeight - - Image { - id: image - height: Math.round(parent.height * 0.6) - anchors.centerIn: parent - - fillMode: Image.PreserveAspectFit - } -} diff --git a/qml/Firebird/UIComponents/KitItem.qml b/qml/Firebird/UIComponents/KitItem.qml index f0b852c4..9eb39598 100644 --- a/qml/Firebird/UIComponents/KitItem.qml +++ b/qml/Firebird/UIComponents/KitItem.qml @@ -1,5 +1,5 @@ import QtQuick 2.0 -import QtQuick.Controls 1.0 +import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 ColumnLayout { diff --git a/qml/Firebird/UIComponents/KitList.qml b/qml/Firebird/UIComponents/KitList.qml index 022ef059..8eacf92f 100644 --- a/qml/Firebird/UIComponents/KitList.qml +++ b/qml/Firebird/UIComponents/KitList.qml @@ -1,5 +1,5 @@ import QtQuick 2.0 -import QtQuick.Controls 1.0 +import QtQuick.Controls 2.2 import Firebird.Emu 1.0 Rectangle { @@ -22,6 +22,7 @@ Rectangle { anchors.fill: parent activeFocusOnTab: true + clip: true ListView { id: listView diff --git a/qml/Firebird/UIComponents/PageDelegate.qml b/qml/Firebird/UIComponents/PageDelegate.qml index 3bb01e3c..8ff18cdc 100644 --- a/qml/Firebird/UIComponents/PageDelegate.qml +++ b/qml/Firebird/UIComponents/PageDelegate.qml @@ -1,5 +1,5 @@ import QtQuick 2.0 -import QtQuick.Controls 1.0 +import QtQuick.Controls 2.0 import QtQuick.Layouts 1.1 import Firebird.UIComponents 1.0 diff --git a/qml/Firebird/UIComponents/VerticalSwipeBar.qml b/qml/Firebird/UIComponents/VerticalSwipeBar.qml index 143d9b48..33f11db6 100644 --- a/qml/Firebird/UIComponents/VerticalSwipeBar.qml +++ b/qml/Firebird/UIComponents/VerticalSwipeBar.qml @@ -19,12 +19,12 @@ Rectangle { property point orig; anchors.fill: parent - onPressed: { + onPressed: function(mouse) { orig.x = mouse.x; orig.y = mouse.y; } - onReleased: { + onReleased: function(mouse) { if(Math.abs(orig.x - mouse.x) < 5 && Math.abs(orig.y - mouse.y) < 5) parent.clicked(); diff --git a/qml/FlashDialog.qml b/qml/FlashDialog.qml index 85b32aa9..879d4ccb 100644 --- a/qml/FlashDialog.qml +++ b/qml/FlashDialog.qml @@ -1,16 +1,14 @@ import QtQuick 2.0 import QtQuick.Layouts 1.1 -import QtQuick.Controls 1.2 -import QtQuick.Dialogs 1.3 +import QtQuick.Controls 2.0 +import QtQuick.Window 2.2 +import Qt.labs.platform 1.0 import Firebird.Emu 1.0 import Firebird.UIComponents 1.0 -Dialog { +Window { id: flashDialog title: qsTr("Create Flash Image") - // Work around QTBUG-89607: Menu (used by ComboBox) doesn't work in modal windows - modality: Qt.platform.pluginName == "cocoa" ? Qt.NonModal : Qt.WindowModal - standardButtons: Dialog.Save | Dialog.Cancel onVisibleChanged: { // For some reason the initial size on wayland is too big. // Setting it to -1 initially appears to work around that. @@ -20,11 +18,18 @@ Dialog { } } + SystemPalette { + id: paletteActive + } + + color: paletteActive.window + signal flashCreated(string filePath) GridLayout { id: layout - width: parent.width + anchors.fill: parent + anchors.margins: 5 columns: 2 FBLabel { @@ -144,6 +149,17 @@ Dialog { color: "red" text: parent.validationText } + + Button { + Layout.alignment: Qt.AlignRight + Layout.columnSpan: 2 + text: qsTr("Save as") + enabled: layout.validationText == "" + onClicked: { + fileDialogLoader.active = true; + fileDialogLoader.item.visible = true; + } + } } MessageDialog { @@ -156,9 +172,9 @@ Dialog { id: fileDialogLoader active: false sourceComponent: FileDialog { - selectExisting: false + fileMode: FileDialog.SaveFile onAccepted: { - var filePath = Emu.toLocalFile(fileUrl); + var filePath = Emu.toLocalFile(file); var success = false; if (!modelCombo.cx2Selected) success = Emu.createFlash(filePath, modelCombo.productId, subtypeCombo.featureValue, manufSelect.filePath, boot2Select.filePath, osSelect.filePath, diagsSelect.filePath); @@ -174,17 +190,4 @@ Dialog { } } } - - onActionChosen: { - if (action.button === Dialog.Save) { - // Don't close the dialog now, but only - // after successful saving - action.accepted = false; - - if (!layout.validationText) { - fileDialogLoader.active = true; - fileDialogLoader.item.visible = true; - } - } - } } diff --git a/qml/MobileUI.qml b/qml/MobileUI.qml index 05138f02..f41280d5 100644 --- a/qml/MobileUI.qml +++ b/qml/MobileUI.qml @@ -2,8 +2,8 @@ import Firebird.Emu 1.0 import Firebird.UIComponents 1.0 import QtQuick 2.0 -import QtQuick.Controls 1.2 -import QtQuick.Dialogs 1.1 +import QtQuick.Controls 2.0 +import Qt.labs.platform 1.1 import QtQuick.Layouts 1.0 ApplicationWindow { @@ -60,12 +60,11 @@ ApplicationWindow { MessageDialog { id: suspendFailedDialog - standardButtons: StandardButton.Yes | StandardButton.No - icon: StandardIcon.Warning + buttons: MessageDialog.Yes | MessageDialog.No title: qsTr("Suspend failed") text: qsTr("Suspending the emulation failed. Do you still want to quit Firebird?") - onYes: { + onYesClicked: { ignoreSuspendOnClose = true; app.close(); } @@ -73,7 +72,7 @@ ApplicationWindow { Connections { target: Emu - onEmuSuspended: { + function onEmuSuspended() { if(closeAfterSuspend) { closeAfterSuspend = false; @@ -87,14 +86,14 @@ ApplicationWindow { suspendFailedDialog.visible = true; } } - onToastMessage: { + function onToastMessage(msg) { toast.showMessage(msg); } } Connections { target: Qt.application - onStateChanged: { + function onStateChanged() { switch (Qt.application.state) { case Qt.ApplicationSuspended: // Might be reaped on mobile diff --git a/qml/MobileUIConfig.qml b/qml/MobileUIConfig.qml index 17b14f2a..11a04857 100644 --- a/qml/MobileUIConfig.qml +++ b/qml/MobileUIConfig.qml @@ -1,7 +1,6 @@ import QtQuick 2.7 -import QtQuick.Layouts 1.0 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.2 +import QtQuick.Controls 2.0 import Firebird.UIComponents 1.0 @@ -9,8 +8,7 @@ Item { Layout.fillHeight: true Layout.fillWidth: true - TabView { - id: tabView + ColumnLayout { anchors { left: parent.left right: swipeBar.left @@ -19,39 +17,35 @@ Item { bottomMargin: 2 } - property var model: ConfigPagesModel {} + TabBar { + id: bar + property var model: ConfigPagesModel {} - /* style: TabViewStyle { - tab: Rectangle { - color: styleData.selected ? "darkgrey" :"lightgrey" + Repeater { + id: rep + model: bar.model - implicitWidth: tabView.width / model.count - implicitHeight: title.contentHeight + 10 - - FBLabel { - id: title - anchors.fill: parent - text: styleData.title - font.pixelSize: TextMetrics.title1Size - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - elide: Text.ElideRight - color: styleData.selected ? "white" : "black" + TabButton { + text: qsTranslate("ConfigPagesModel", rep.model.get(index).title) } } - frame: Rectangle { color: "#eeeeee" } - }*/ + } + + SwipeView { + Layout.fillHeight: true + Layout.fillWidth: true + currentIndex: bar.currentIndex + clip: true - Repeater { - id: rep - model: tabView.model + Repeater { + model: bar.model - Tab { - title: qsTranslate("ConfigPagesModel", rep.model.get(index).title) - source: file + Loader { + source: file + } } } - } +} FBLabel { id: autoSaveLabel diff --git a/qml/MobileUIDrawer.qml b/qml/MobileUIDrawer.qml index bde2437c..9fa2f69e 100644 --- a/qml/MobileUIDrawer.qml +++ b/qml/MobileUIDrawer.qml @@ -1,5 +1,5 @@ import QtQuick 2.0 -import QtQuick.Dialogs 1.1 +import Qt.labs.platform 1.1 import QtQuick.Layouts 1.0 import Firebird.Emu 1.0 @@ -88,14 +88,12 @@ Rectangle { id: saveFailedDialog title: qsTr("Error") text: qsTr("Failed to save changes!") - icon: StandardIcon.Warning } MessageDialog { id: snapWarnDialog title: qsTr("Warning") text: qsTr("Flash saved, but no snapshot location configured.\nYou won't be able to resume.") - icon: StandardIcon.Warning } onClicked: { diff --git a/qml/NButton.qml b/qml/NButton.qml index 90e8886f..8a9bd117 100644 --- a/qml/NButton.qml +++ b/qml/NButton.qml @@ -45,6 +45,7 @@ Rectangle { font.pixelSize: height*0.55 color: font_color font.bold: true + renderType: Text.QtRendering // Workaround: Text.AutoText doesn't seem to work for properties (?) textFormat: text.indexOf(">") == -1 ? Text.PlainText : Text.RichText verticalAlignment: Text.AlignVCenter @@ -95,7 +96,7 @@ Rectangle { hoverEnabled: !Emu.isMobile() - onPressed: { + onPressed: function(mouse) { mouse.accepted = true; if(mouse.button == Qt.LeftButton) @@ -110,7 +111,7 @@ Rectangle { } } - onReleased: { + onReleased: function(mouse) { mouse.accepted = true; if(mouse.button == Qt.LeftButton diff --git a/qml/ScrollingKeypad.qml b/qml/ScrollingKeypad.qml index abd2b0b1..7a2b2110 100644 --- a/qml/ScrollingKeypad.qml +++ b/qml/ScrollingKeypad.qml @@ -1,11 +1,11 @@ import QtQuick 2.0 -import QtQuick.Controls 1.0 +import QtQuick.Controls 2.2 ScrollView { id: controls property alias keypad: keypad - horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff - verticalScrollBarPolicy: Qt.ScrollBarAlwaysOff + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + ScrollBar.vertical.policy: ScrollBar.AlwaysOff Flickable { flickableDirection: Flickable.VerticalFlick diff --git a/qml/SidebarButton.qml b/qml/SidebarButton.qml index 919cfa76..82533b5e 100644 --- a/qml/SidebarButton.qml +++ b/qml/SidebarButton.qml @@ -1,5 +1,5 @@ import QtQuick 2.0 -import QtQuick.Controls 1.3 +import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import Firebird.UIComponents 1.0 diff --git a/qml/Touchpad.qml b/qml/Touchpad.qml index 95b73955..d7db8499 100644 --- a/qml/Touchpad.qml +++ b/qml/Touchpad.qml @@ -103,7 +103,7 @@ Rectangle { submitState(); } - onReleased: { + onReleased: function(mouse) { if(clickOnHoldTimer.running) { clickOnHoldTimer.stop(); @@ -116,7 +116,7 @@ Rectangle { submitState(); } - onPressed: { + onPressed: function(mouse) { origX = mouse.x; origY = mouse.y; isDown = false; diff --git a/qmlbridge.cpp b/qmlbridge.cpp index f1233f9e..7a0cc3f3 100644 --- a/qmlbridge.cpp +++ b/qmlbridge.cpp @@ -288,9 +288,13 @@ QString QMLBridge::basename(QString path) if(path.startsWith(QStringLiteral("content://"))) { - auto parts = path.splitRef(QStringLiteral("%2F"), QString::SkipEmptyParts, Qt::CaseInsensitive); + #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + auto parts = path.split(QStringLiteral("%2F"), QString::SkipEmptyParts, Qt::CaseInsensitive); + #else + auto parts = path.split(QStringLiteral("%2F"), Qt::SkipEmptyParts, Qt::CaseInsensitive); + #endif if(parts.length() > 1) - return parts.last().toString(); + return parts.last(); return tr("(Android File)"); } diff --git a/resources.qrc b/resources.qrc index 7008cea3..2e06f51f 100644 --- a/resources.qrc +++ b/resources.qrc @@ -59,7 +59,6 @@ qml/DrawerButton.qml qml/Firebird/UIComponents/VerticalSwipeBar.qml qml/FlashDialog.qml - qml/Firebird/UIComponents/IconButton.qml i18n/de_DE.qm