2023-10-03 09:48:40 +00:00
|
|
|
|
import QtQuick 2.15
|
|
|
|
|
import QtQuick.Controls 2.15
|
2023-09-26 14:20:59 +00:00
|
|
|
|
import QtQuick.Controls.Universal 2.15
|
2023-10-03 09:48:40 +00:00
|
|
|
|
import QtQuick.Layouts 1.15
|
2022-10-04 20:25:14 +00:00
|
|
|
|
|
|
|
|
|
import Qt.labs.settings 1.0
|
|
|
|
|
|
2022-10-14 08:29:36 +00:00
|
|
|
|
import StatusQ.Core.Theme 0.1
|
|
|
|
|
import Storybook 1.0
|
2022-10-04 20:25:14 +00:00
|
|
|
|
|
2023-09-26 14:20:59 +00:00
|
|
|
|
import utils 1.0
|
|
|
|
|
|
2022-10-04 20:25:14 +00:00
|
|
|
|
ApplicationWindow {
|
2022-10-14 08:29:36 +00:00
|
|
|
|
id: root
|
2022-10-04 20:25:14 +00:00
|
|
|
|
|
|
|
|
|
width: 1450
|
|
|
|
|
height: 840
|
|
|
|
|
visible: true
|
|
|
|
|
|
2022-10-14 08:29:36 +00:00
|
|
|
|
property string currentPage
|
2022-10-04 20:25:14 +00:00
|
|
|
|
|
2023-06-12 12:23:50 +00:00
|
|
|
|
title: "%1 – %2".arg(currentPage).arg(Qt.application.displayName)
|
|
|
|
|
|
2023-03-20 12:29:05 +00:00
|
|
|
|
palette.window: Theme.palette.statusAppLayout.backgroundColor
|
|
|
|
|
palette.text: Theme.palette.directColor1
|
|
|
|
|
palette.windowText: Theme.palette.directColor1
|
|
|
|
|
palette.base: Theme.palette.indirectColor1
|
2022-10-14 08:29:36 +00:00
|
|
|
|
font.pixelSize: 13
|
|
|
|
|
|
2023-10-11 07:58:15 +00:00
|
|
|
|
onCurrentPageChanged: testsReRunTimer.restart()
|
|
|
|
|
|
2023-06-12 14:59:46 +00:00
|
|
|
|
QtObject {
|
|
|
|
|
id: d
|
|
|
|
|
|
|
|
|
|
function activateInspection(item) {
|
|
|
|
|
inspectionWindow.inspect(item)
|
|
|
|
|
inspectionWindow.show()
|
|
|
|
|
inspectionWindow.requestActivate()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function performInspection() {
|
2023-06-15 14:57:58 +00:00
|
|
|
|
// Find the items to inspect on the current page
|
2023-06-12 14:59:46 +00:00
|
|
|
|
const getItems = typeName =>
|
|
|
|
|
InspectionUtils.findItemsByTypeName(
|
|
|
|
|
viewLoader.item, typeName)
|
|
|
|
|
const items = [
|
|
|
|
|
...getItems(root.currentPage),
|
|
|
|
|
...getItems("Custom" + root.currentPage)
|
|
|
|
|
]
|
|
|
|
|
|
2023-06-15 14:57:58 +00:00
|
|
|
|
// Find lowest commont ancestor of found items
|
2023-06-12 14:59:46 +00:00
|
|
|
|
const lca = InspectionUtils.lowestCommonAncestor(
|
|
|
|
|
items, viewLoader.item)
|
|
|
|
|
|
2023-06-15 14:57:58 +00:00
|
|
|
|
// Inspect lca
|
2023-06-12 14:59:46 +00:00
|
|
|
|
if (lca) {
|
|
|
|
|
activateInspection(lca.parent.contentItem === lca
|
|
|
|
|
? lca.parent : lca)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-15 14:57:58 +00:00
|
|
|
|
// Look for the item for inspection on the Overlay, skip items
|
|
|
|
|
// without contentItem which can be, for example, instance of
|
|
|
|
|
// Overlay.modal or Overlay.modeless
|
|
|
|
|
const overlayChildren = root.Overlay.overlay.children
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < overlayChildren.length; i++) {
|
|
|
|
|
const item = overlayChildren[i]
|
|
|
|
|
|
|
|
|
|
if (item.contentItem) {
|
|
|
|
|
activateInspection(item)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-12 14:59:46 +00:00
|
|
|
|
nothingToInspectDialog.open()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-25 15:41:50 +00:00
|
|
|
|
PagesModel {
|
|
|
|
|
id: pagesModel
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-18 18:47:41 +00:00
|
|
|
|
HotReloader {
|
2022-10-19 19:51:39 +00:00
|
|
|
|
id: reloader
|
2022-10-18 18:47:41 +00:00
|
|
|
|
|
2022-10-19 19:51:39 +00:00
|
|
|
|
loader: viewLoader
|
|
|
|
|
enabled: hotReloaderControls.enabled
|
2023-10-11 07:58:15 +00:00
|
|
|
|
|
|
|
|
|
onReloaded: {
|
|
|
|
|
hotReloaderControls.notifyReload()
|
|
|
|
|
testsReRunTimer.restart()
|
|
|
|
|
}
|
2022-10-18 18:47:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-10 20:01:58 +00:00
|
|
|
|
TestRunnerController {
|
|
|
|
|
id: testRunnerController
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-11 07:58:15 +00:00
|
|
|
|
Timer {
|
|
|
|
|
id: testsReRunTimer
|
|
|
|
|
|
|
|
|
|
interval: 100
|
|
|
|
|
|
|
|
|
|
onTriggered: {
|
|
|
|
|
if (!settingsLayout.runTestsAutomatically)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
const testFileName = `tst_${root.currentPage}.qml`
|
|
|
|
|
const testsCount = testRunnerController.getTestsCount(testFileName)
|
|
|
|
|
|
|
|
|
|
if (testsCount === 0)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
testRunnerController.runTests(testFileName)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-14 08:29:36 +00:00
|
|
|
|
SplitView {
|
|
|
|
|
anchors.fill: parent
|
2022-10-04 20:25:14 +00:00
|
|
|
|
|
2023-09-27 12:09:20 +00:00
|
|
|
|
ColumnLayout {
|
2022-11-21 10:55:16 +00:00
|
|
|
|
SplitView.preferredWidth: 270
|
2022-10-04 21:51:14 +00:00
|
|
|
|
|
2023-09-27 12:09:20 +00:00
|
|
|
|
Pane {
|
|
|
|
|
Layout.fillWidth: true
|
|
|
|
|
Layout.fillHeight: true
|
2022-10-12 11:02:37 +00:00
|
|
|
|
|
2023-09-27 12:09:20 +00:00
|
|
|
|
ColumnLayout {
|
|
|
|
|
width: parent.width
|
|
|
|
|
height: parent.height
|
2022-10-14 08:29:36 +00:00
|
|
|
|
|
2023-09-27 12:09:20 +00:00
|
|
|
|
Button {
|
|
|
|
|
Layout.fillWidth: true
|
2022-11-21 10:55:16 +00:00
|
|
|
|
|
2023-09-27 12:09:20 +00:00
|
|
|
|
text: "Settings"
|
|
|
|
|
|
|
|
|
|
onClicked: settingsPopup.open()
|
|
|
|
|
}
|
2022-10-12 11:02:37 +00:00
|
|
|
|
|
2023-10-27 10:25:27 +00:00
|
|
|
|
CheckBox {
|
|
|
|
|
id: windowAlwaysOnTopCheckBox
|
|
|
|
|
|
|
|
|
|
Layout.fillWidth: true
|
|
|
|
|
|
|
|
|
|
text: "Always on top"
|
|
|
|
|
onCheckedChanged: {
|
|
|
|
|
if (checked)
|
|
|
|
|
root.flags |= Qt.WindowStaysOnTopHint
|
|
|
|
|
else
|
|
|
|
|
root.flags &= ~Qt.WindowStaysOnTopHint
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-27 12:09:20 +00:00
|
|
|
|
CheckBox {
|
|
|
|
|
id: darkModeCheckBox
|
2022-10-12 11:02:37 +00:00
|
|
|
|
|
2023-09-27 12:09:20 +00:00
|
|
|
|
Layout.fillWidth: true
|
2022-10-14 08:29:36 +00:00
|
|
|
|
|
2023-09-27 12:09:20 +00:00
|
|
|
|
text: "Dark mode"
|
2024-10-15 19:26:12 +00:00
|
|
|
|
onCheckedChanged: Theme.changeTheme(checked ? Universal.Dark : Universal.Light, !checked)
|
2022-11-21 10:55:16 +00:00
|
|
|
|
}
|
2022-10-12 09:42:51 +00:00
|
|
|
|
|
2023-09-27 12:09:20 +00:00
|
|
|
|
HotReloaderControls {
|
|
|
|
|
id: hotReloaderControls
|
2022-10-18 18:47:41 +00:00
|
|
|
|
|
2023-09-27 12:09:20 +00:00
|
|
|
|
Layout.fillWidth: true
|
2022-10-18 18:47:41 +00:00
|
|
|
|
|
2023-09-27 12:09:20 +00:00
|
|
|
|
onForceReloadClicked: reloader.forceReload()
|
|
|
|
|
}
|
2022-10-18 18:47:41 +00:00
|
|
|
|
|
2023-09-27 12:09:20 +00:00
|
|
|
|
MenuSeparator {
|
|
|
|
|
Layout.fillWidth: true
|
|
|
|
|
}
|
2022-10-14 08:29:36 +00:00
|
|
|
|
|
2023-09-27 12:09:20 +00:00
|
|
|
|
FilteredPagesList {
|
|
|
|
|
Layout.fillWidth: true
|
|
|
|
|
Layout.fillHeight: true
|
2022-11-21 10:55:16 +00:00
|
|
|
|
|
2023-09-27 12:09:20 +00:00
|
|
|
|
currentPage: root.currentPage
|
|
|
|
|
model: pagesModel
|
2022-10-14 08:29:36 +00:00
|
|
|
|
|
2023-09-27 12:09:20 +00:00
|
|
|
|
onPageSelected: root.currentPage = page
|
|
|
|
|
}
|
2022-10-04 21:51:14 +00:00
|
|
|
|
}
|
2022-10-04 20:25:14 +00:00
|
|
|
|
}
|
2023-09-27 12:09:20 +00:00
|
|
|
|
|
|
|
|
|
Button {
|
|
|
|
|
Layout.fillWidth: true
|
|
|
|
|
text: "Open pages directory"
|
|
|
|
|
|
|
|
|
|
onClicked: Qt.openUrlExternally(Qt.resolvedUrl(pagesFolder))
|
|
|
|
|
}
|
2022-10-04 20:25:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-21 10:55:16 +00:00
|
|
|
|
Page {
|
2022-10-14 08:29:36 +00:00
|
|
|
|
SplitView.fillWidth: true
|
2022-10-04 20:25:14 +00:00
|
|
|
|
|
|
|
|
|
Loader {
|
|
|
|
|
id: viewLoader
|
2022-10-12 11:02:37 +00:00
|
|
|
|
|
2022-10-04 20:25:14 +00:00
|
|
|
|
anchors.fill: parent
|
|
|
|
|
clip: true
|
2022-10-12 11:02:37 +00:00
|
|
|
|
|
2022-10-18 18:47:41 +00:00
|
|
|
|
source: `pages/${root.currentPage}Page.qml`
|
2022-11-21 10:55:16 +00:00
|
|
|
|
asynchronous: settingsLayout.loadAsynchronously
|
2022-10-12 11:02:37 +00:00
|
|
|
|
visible: status === Loader.Ready
|
|
|
|
|
|
|
|
|
|
// force reload when `asynchronous` changes
|
|
|
|
|
onAsynchronousChanged: {
|
2022-10-14 08:29:36 +00:00
|
|
|
|
active = false
|
|
|
|
|
active = true
|
2022-10-12 11:02:37 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BusyIndicator {
|
|
|
|
|
anchors.centerIn: parent
|
|
|
|
|
visible: viewLoader.status === Loader.Loading
|
2022-10-04 20:25:14 +00:00
|
|
|
|
}
|
2022-10-19 19:51:39 +00:00
|
|
|
|
|
|
|
|
|
Label {
|
|
|
|
|
anchors.centerIn: parent
|
|
|
|
|
visible: viewLoader.status === Loader.Error
|
|
|
|
|
text: "Loading page failed"
|
|
|
|
|
}
|
2022-11-21 10:55:16 +00:00
|
|
|
|
|
|
|
|
|
footer: PageToolBar {
|
|
|
|
|
id: pageToolBar
|
|
|
|
|
|
2023-02-28 20:58:39 +00:00
|
|
|
|
componentName: root.currentPage
|
2022-11-21 10:55:16 +00:00
|
|
|
|
figmaPagesCount: currentPageModelItem.object
|
2022-11-25 15:41:50 +00:00
|
|
|
|
? currentPageModelItem.object.figma.count : 0
|
2022-11-21 10:55:16 +00:00
|
|
|
|
|
2023-10-10 20:01:58 +00:00
|
|
|
|
testRunnerController: testRunnerController
|
|
|
|
|
|
2022-11-21 10:55:16 +00:00
|
|
|
|
Instantiator {
|
|
|
|
|
id: currentPageModelItem
|
|
|
|
|
|
|
|
|
|
model: SingleItemProxyModel {
|
2023-10-03 09:48:40 +00:00
|
|
|
|
sourceModel: pagesModel
|
2022-11-21 10:55:16 +00:00
|
|
|
|
roleName: "title"
|
|
|
|
|
value: root.currentPage
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delegate: QtObject {
|
|
|
|
|
readonly property string title: model.title
|
|
|
|
|
readonly property var figma: model.figma
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onFigmaPreviewClicked: {
|
|
|
|
|
if (!settingsLayout.figmaToken) {
|
|
|
|
|
noFigmaTokenDialog.open()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-29 10:51:19 +00:00
|
|
|
|
figmaWindow.createObject(root, {
|
2022-11-21 10:55:16 +00:00
|
|
|
|
figmaModel: currentPageModelItem.object.figma,
|
2022-11-29 10:51:19 +00:00
|
|
|
|
pageTitle: currentPageModelItem.object.title
|
2022-11-21 10:55:16 +00:00
|
|
|
|
})
|
|
|
|
|
}
|
2023-05-08 12:49:39 +00:00
|
|
|
|
|
2023-06-12 14:59:46 +00:00
|
|
|
|
onInspectClicked: d.performInspection()
|
2022-11-21 10:55:16 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Dialog {
|
|
|
|
|
id: settingsPopup
|
|
|
|
|
|
|
|
|
|
anchors.centerIn: Overlay.overlay
|
|
|
|
|
width: 420
|
|
|
|
|
modal: true
|
|
|
|
|
|
|
|
|
|
header: Pane {
|
|
|
|
|
background: null
|
|
|
|
|
|
|
|
|
|
Label {
|
|
|
|
|
text: "Settings"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SettingsLayout {
|
|
|
|
|
id: settingsLayout
|
|
|
|
|
|
|
|
|
|
width: parent.width
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Dialog {
|
|
|
|
|
id: noFigmaTokenDialog
|
|
|
|
|
|
|
|
|
|
anchors.centerIn: Overlay.overlay
|
|
|
|
|
|
|
|
|
|
title: "Figma token not set"
|
|
|
|
|
standardButtons: Dialog.Ok
|
|
|
|
|
|
|
|
|
|
Label {
|
|
|
|
|
text: "Please set Figma personal token in \"Settings\""
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FigmaLinksCache {
|
|
|
|
|
id: figmaImageLinksCache
|
|
|
|
|
|
|
|
|
|
figmaToken: settingsLayout.figmaToken
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 12:49:39 +00:00
|
|
|
|
InspectionWindow {
|
|
|
|
|
id: inspectionWindow
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-09 21:27:55 +00:00
|
|
|
|
Dialog {
|
|
|
|
|
id: nothingToInspectDialog
|
|
|
|
|
|
|
|
|
|
anchors.centerIn: Overlay.overlay
|
|
|
|
|
width: contentItem.implicitWidth + leftPadding + rightPadding
|
|
|
|
|
|
|
|
|
|
title: "No items to inspect found"
|
|
|
|
|
standardButtons: Dialog.Ok
|
|
|
|
|
modal: true
|
|
|
|
|
|
|
|
|
|
contentItem: Label {
|
2023-11-15 21:26:12 +00:00
|
|
|
|
text: '
|
|
|
|
|
Tips:\n\
|
|
|
|
|
• For inline components use naming convention of adding\n\
|
|
|
|
|
"Custom" at the begining (like Custom'+root.currentPage+')\n\
|
|
|
|
|
• For popups set closePolicy to "Popup.NoAutoClose"\n\
|
|
|
|
|
'
|
2023-05-09 21:27:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-21 10:55:16 +00:00
|
|
|
|
Component {
|
|
|
|
|
id: figmaWindow
|
|
|
|
|
|
|
|
|
|
FigmaPreviewWindow {
|
2022-11-29 10:51:19 +00:00
|
|
|
|
property string pageTitle
|
2022-11-21 10:55:16 +00:00
|
|
|
|
property alias figmaModel: figmaImagesProxyModel.sourceModel
|
|
|
|
|
|
2022-11-29 10:51:19 +00:00
|
|
|
|
title: pageTitle + " - Figma"
|
|
|
|
|
|
2022-11-21 10:55:16 +00:00
|
|
|
|
model: FigmaImagesProxyModel {
|
|
|
|
|
id: figmaImagesProxyModel
|
|
|
|
|
|
|
|
|
|
figmaLinksCache: figmaImageLinksCache
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onClosing: Qt.callLater(destroy)
|
2022-10-04 20:25:14 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Settings {
|
2023-10-11 07:58:15 +00:00
|
|
|
|
id: settings
|
|
|
|
|
|
2022-10-14 08:29:36 +00:00
|
|
|
|
property alias currentPage: root.currentPage
|
2022-11-21 10:55:16 +00:00
|
|
|
|
property alias loadAsynchronously: settingsLayout.loadAsynchronously
|
2023-10-11 07:58:15 +00:00
|
|
|
|
property alias runTestsAutomatically: settingsLayout.runTestsAutomatically
|
2022-10-14 08:29:36 +00:00
|
|
|
|
property alias darkMode: darkModeCheckBox.checked
|
2022-10-19 19:51:39 +00:00
|
|
|
|
property alias hotReloading: hotReloaderControls.enabled
|
2022-11-21 10:55:16 +00:00
|
|
|
|
property alias figmaToken: settingsLayout.figmaToken
|
2023-10-27 10:25:27 +00:00
|
|
|
|
property alias windowAlwaysOnTop: windowAlwaysOnTopCheckBox.checked
|
2022-10-04 20:25:14 +00:00
|
|
|
|
}
|
2023-06-12 14:59:46 +00:00
|
|
|
|
|
|
|
|
|
Shortcut {
|
|
|
|
|
sequence: "Ctrl+Shift+I"
|
|
|
|
|
context: Qt.ApplicationShortcut
|
|
|
|
|
onActivated: d.performInspection()
|
|
|
|
|
}
|
2022-10-04 20:25:14 +00:00
|
|
|
|
}
|