Artemis 4 RC1
This commit is contained in:
48
ui/About.qml
Normal file
48
ui/About.qml
Normal file
@@ -0,0 +1,48 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls.Material
|
||||
|
||||
Dialog {
|
||||
x: (parent.width - width) / 2
|
||||
y: (parent.height - height) / 2
|
||||
|
||||
property int currentYear: new Date().getFullYear()
|
||||
|
||||
modal: true
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
spacing: 10
|
||||
|
||||
Image {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
|
||||
sourceSize.height: 80
|
||||
sourceSize.width: 80
|
||||
source: "qrc:///images/artemis_icon.svg"
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "<style>a { color: " + Material.accent + "; }</style>" +
|
||||
"<p><b>Artemis</a> " + APPLICATION_VERSION + "</b></p>" +
|
||||
"<p>" + "<a href=\"https://github.com/AresValley/Artemis\">ARTEMIS</a> " +
|
||||
qsTr("- The Radio Signals Recognition Manual") + "<br/>" +
|
||||
"Powered By Python " + PYTHON_VERSION + " & Qt " + QT_VERSION + "</p>" +
|
||||
"<p>Copyright (c) 2014-" + currentYear + " <a href=\"https://aresvalley.com\">" + qsTr("AresValley") +
|
||||
"</a> GPLv3 License</p>"
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 200
|
||||
|
||||
textFormat: Text.RichText
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
onLinkActivated: (link) => {
|
||||
Qt.openUrlExternally(link)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
450
ui/Artemis.qml
Normal file
450
ui/Artemis.qml
Normal file
@@ -0,0 +1,450 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Dialogs
|
||||
|
||||
|
||||
Window {
|
||||
id: window
|
||||
width: 1100
|
||||
height: 800
|
||||
|
||||
Component.onCompleted: {
|
||||
x = Screen.width/2 - width/2
|
||||
y = Screen.height/2 - height/2
|
||||
}
|
||||
|
||||
title: qsTr("Artemis")
|
||||
visible: true
|
||||
|
||||
modality: Qt.ApplicationModal
|
||||
flags: Qt.Window
|
||||
|
||||
// Windows without upper bar
|
||||
//flags: Qt.FramelessWindowHint
|
||||
|
||||
signal loadSignal(int signalId)
|
||||
signal showPref()
|
||||
signal showDBmanager()
|
||||
signal showCatManager()
|
||||
signal openSigEditor(string type, var sig_param, bool is_new)
|
||||
signal showSpaceWeather()
|
||||
signal checkDbUpdates()
|
||||
signal startDownloader()
|
||||
signal openDbDirectory()
|
||||
signal newDb(string name)
|
||||
signal exportDb(string path)
|
||||
signal importDb(string path)
|
||||
|
||||
property var loadedList
|
||||
|
||||
function populateList(signalsList) {
|
||||
loadedList = signalsList
|
||||
textFieldSearch.enabled = true
|
||||
var currentIndex = listView.currentIndex
|
||||
refreshList()
|
||||
// Set the currentIndex back after refreshing the list
|
||||
if (currentIndex >= 0 && currentIndex < listModel.count) {
|
||||
listView.currentIndex = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
function refreshList() {
|
||||
listModel.clear()
|
||||
for (var i = 0; i < loadedList.length; i++) {
|
||||
var name = loadedList[i].name.toLowerCase()
|
||||
var search = textFieldSearch.text.toLowerCase()
|
||||
if (name.includes(search)) {
|
||||
listModel.append(loadedList[i])
|
||||
}
|
||||
}
|
||||
itemChangedList()
|
||||
}
|
||||
|
||||
function itemChangedList() {
|
||||
var selected_sig = listModel.get(listView.currentIndex)
|
||||
if (selected_sig !== undefined) {
|
||||
loadSignal(listModel.get(listView.currentIndex).SIG_ID)
|
||||
editSignalMenu.enabled = true
|
||||
} else {
|
||||
editSignalMenu.enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
function clearList() {
|
||||
listModel.clear()
|
||||
loadedList = []
|
||||
textFieldSearch.clear()
|
||||
textFieldSearch.enabled = false
|
||||
}
|
||||
|
||||
function lockMenu(toggle) {
|
||||
if (toggle) {
|
||||
openFileMenu.enabled = false
|
||||
exportFileMenu.enabled = false
|
||||
newSignalMenu.enabled = false
|
||||
editCategoryMenu.enabled = false
|
||||
} else {
|
||||
openFileMenu.enabled = true
|
||||
exportFileMenu.enabled = true
|
||||
newSignalMenu.enabled = true
|
||||
editCategoryMenu.enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
function bottomInfoBar(message, messageType) {
|
||||
bottomInfoLabel.text = message
|
||||
switch (messageType) {
|
||||
case "warning":
|
||||
bottomInfoLabel.color = Material.color(Material.Red)
|
||||
break
|
||||
case "info":
|
||||
bottomInfoLabel.color = Material.foreground
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
function openGeneralDialog(messageType, title, message) {
|
||||
dialogGeneral.messageType = messageType
|
||||
dialogGeneral.title = title
|
||||
dialogGeneral.message = message
|
||||
dialogGeneral.open()
|
||||
}
|
||||
|
||||
function openDialogDownloadDb(messageType, title, message) {
|
||||
dialogDownloadDb.messageType = messageType
|
||||
dialogDownloadDb.title = title
|
||||
dialogDownloadDb.message = message
|
||||
dialogDownloadDb.open()
|
||||
}
|
||||
|
||||
function openDialogDownloadArtemis(messageType, title, message) {
|
||||
dialogDownloadArtemis.messageType = messageType
|
||||
dialogDownloadArtemis.title = title
|
||||
dialogDownloadArtemis.message = message
|
||||
dialogDownloadArtemis.open()
|
||||
}
|
||||
|
||||
DialogMessage {
|
||||
id: dialogDownloadDb
|
||||
modal: true
|
||||
|
||||
standardButtons: Dialog.Cancel | Dialog.Yes
|
||||
|
||||
onAccepted: {
|
||||
startDownloader()
|
||||
}
|
||||
}
|
||||
|
||||
DialogMessage {
|
||||
id: dialogDownloadArtemis
|
||||
modal: true
|
||||
|
||||
standardButtons: Dialog.Cancel | Dialog.Yes
|
||||
|
||||
onAccepted: {
|
||||
Qt.openUrlExternally("https://github.com/AresValley/Artemis")
|
||||
}
|
||||
}
|
||||
|
||||
DialogMessage {
|
||||
id: dialogGeneral
|
||||
modal: true
|
||||
|
||||
standardButtons: Dialog.Ok
|
||||
}
|
||||
|
||||
Dialog {
|
||||
id: dialogNewDb
|
||||
|
||||
x: (parent.width - width) / 2
|
||||
y: (parent.height - height) / 2
|
||||
|
||||
modal: true
|
||||
closePolicy: Popup.NoAutoClose
|
||||
|
||||
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
TextField {
|
||||
id: newDbName
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("New DB Name")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
newDb(newDbName.text)
|
||||
}
|
||||
}
|
||||
|
||||
FileDialog {
|
||||
id: exportDialog
|
||||
title: "Please choose a save folder..."
|
||||
fileMode: FileDialog.SaveFile
|
||||
nameFilters: ["Archive (.tar)"]
|
||||
|
||||
onAccepted: {
|
||||
exportDb(selectedFile)
|
||||
}
|
||||
}
|
||||
|
||||
FileDialog {
|
||||
id: importDialog
|
||||
title: "Please choose a valid tar.gz archive..."
|
||||
fileMode: FileDialog.OpenFile
|
||||
nameFilters: ["Archive (*.tar)"]
|
||||
|
||||
onAccepted: {
|
||||
importDb(selectedFile)
|
||||
}
|
||||
}
|
||||
|
||||
About {
|
||||
id: aboutDialog
|
||||
}
|
||||
|
||||
Page {
|
||||
anchors.fill: parent
|
||||
leftPadding: 5
|
||||
rightPadding: 5
|
||||
bottomPadding: 5
|
||||
|
||||
header: MenuBar {
|
||||
id: topBar
|
||||
|
||||
Menu {
|
||||
title: qsTr("File")
|
||||
|
||||
MenuItem {
|
||||
text: "New Database..."
|
||||
onClicked: {dialogNewDb.open()}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: "Load Database..."
|
||||
onClicked: {showDBmanager()}
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
MenuItem {
|
||||
id: importFileMenu
|
||||
text: "Import Database"
|
||||
onClicked: {importDialog.open()}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
id: exportFileMenu
|
||||
text: "Export Database"
|
||||
onClicked: {exportDialog.open()}
|
||||
enabled: false
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
MenuItem {
|
||||
id: editCategoryMenu
|
||||
text: "Edit Tags"
|
||||
onClicked: {showCatManager()}
|
||||
enabled: false
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
MenuItem {
|
||||
id: openFileMenu
|
||||
text: "Open Database Folder"
|
||||
onClicked: {openDbDirectory()}
|
||||
enabled: false
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: "Preferences"
|
||||
onClicked: {showPref()}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: "Exit"
|
||||
onClicked: {window.close()}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Menu {
|
||||
id: signalMenu
|
||||
title: qsTr("Signal")
|
||||
|
||||
MenuItem {
|
||||
id: newSignalMenu
|
||||
enabled: false
|
||||
text: "New.."
|
||||
onClicked: {openSigEditor('Signal', [], true)}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
id: editSignalMenu
|
||||
enabled: false
|
||||
text: "Edit..."
|
||||
onClicked: {openSigEditor('Signal', [], false)}
|
||||
}
|
||||
}
|
||||
|
||||
Menu {
|
||||
title: qsTr("Space Weather")
|
||||
|
||||
MenuItem {
|
||||
text: "Check Report"
|
||||
onClicked: {
|
||||
showSpaceWeather()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Menu {
|
||||
id: aboutMenu
|
||||
title: qsTr("Help")
|
||||
|
||||
MenuItem {
|
||||
text: "Check for Updates"
|
||||
onClicked: {checkDbUpdates()}
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
MenuItem {
|
||||
text: "Documentation"
|
||||
onClicked: {Qt.openUrlExternally('https://AresValley.github.io/Artemis')}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: "Show Release Notes"
|
||||
onClicked: {Qt.openUrlExternally('https://github.com/AresValley/Artemis/blob/master/CHANGELOG.md')}
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
MenuItem {
|
||||
text: "Report Issue"
|
||||
onClicked: {Qt.openUrlExternally('https://github.com/AresValley/Artemis/issues')}
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
MenuItem {
|
||||
text: "About"
|
||||
onClicked: {
|
||||
aboutDialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer: Label {
|
||||
id: bottomInfoLabel
|
||||
font.pixelSize: 12
|
||||
leftPadding: 5
|
||||
rightPadding: 5
|
||||
bottomPadding: 5
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 20
|
||||
|
||||
ColumnLayout {
|
||||
Layout.maximumWidth: 250
|
||||
|
||||
TextField {
|
||||
id: textFieldSearch
|
||||
enabled: false
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 10
|
||||
placeholderText: qsTr("Search")
|
||||
onTextChanged: {
|
||||
refreshList()
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
highlightMoveDuration: 0
|
||||
clip: true
|
||||
focus: true
|
||||
ScrollBar.vertical: bar
|
||||
highlight: Rectangle { color: Material.accent; radius: 5 }
|
||||
onCurrentIndexChanged: { itemChangedList() }
|
||||
delegate: Item {
|
||||
id: listDelegate
|
||||
width: ListView.view.width
|
||||
height: 20
|
||||
Label {text: name}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: listView.currentIndex = index
|
||||
}
|
||||
}
|
||||
model: ListModel {
|
||||
id: listModel
|
||||
}
|
||||
}
|
||||
|
||||
ScrollBar {
|
||||
id: bar
|
||||
Layout.fillHeight: true
|
||||
active: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
TabBar {
|
||||
id: tabBar
|
||||
width: parent.width
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
|
||||
TabButton {
|
||||
text: qsTr("Signal")
|
||||
}
|
||||
|
||||
TabButton {
|
||||
text: qsTr("Filter")
|
||||
}
|
||||
}
|
||||
|
||||
StackLayout {
|
||||
currentIndex: tabBar.currentIndex
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
Item {
|
||||
SignalPage {
|
||||
id: signalPage
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
FilterPage {
|
||||
id: filterPage
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
214
ui/CategoryEditor.qml
Normal file
214
ui/CategoryEditor.qml
Normal file
@@ -0,0 +1,214 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
|
||||
|
||||
Window {
|
||||
id: windowCategoryEditor
|
||||
title: 'Artemis - Category Manager'
|
||||
|
||||
width: 450
|
||||
height: 400
|
||||
|
||||
Component.onCompleted: {
|
||||
x = Screen.width/2 - width/2
|
||||
y = Screen.height/2 - height/2
|
||||
}
|
||||
|
||||
modality: Qt.ApplicationModal
|
||||
flags: Qt.Window
|
||||
|
||||
signal saveParam(var data, bool isNew)
|
||||
signal deleteParam(int clbId)
|
||||
|
||||
function loadList(dict) {
|
||||
clearAll()
|
||||
for (var i = 0; i < dict.length; i++) {
|
||||
myModel.append(dict[i])
|
||||
}
|
||||
}
|
||||
|
||||
function itemChanged() {
|
||||
var selected_cat = myModel.get(listView.currentIndex)
|
||||
if (selected_cat !== undefined) {
|
||||
renameButton.enabled = true
|
||||
deleteButton.enabled = true
|
||||
} else {
|
||||
renameButton.enabled = false
|
||||
deleteButton.enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
function getModel() {
|
||||
var modelList = []
|
||||
for (var i = 0; i < myModel.count; i++) {
|
||||
modelList.push(myModel.get(i).value)
|
||||
}
|
||||
return modelList
|
||||
}
|
||||
|
||||
function clearAll() {
|
||||
myModel.clear()
|
||||
}
|
||||
|
||||
DialogMessage {
|
||||
id: dialogDeleteConfirmation
|
||||
modal: true
|
||||
title: "Are you sure?"
|
||||
message: "You are about to delete the selected category tag. The process cannot be undone."
|
||||
messageType: "warn"
|
||||
standardButtons: Dialog.Cancel | Dialog.Yes
|
||||
|
||||
onAccepted: {
|
||||
deleteParam(myModel.get(listView.currentIndex).clb_id)
|
||||
}
|
||||
}
|
||||
|
||||
Dialog {
|
||||
id: dialogNewCat
|
||||
|
||||
x: (parent.width - width) / 2
|
||||
y: (parent.height - height) / 2
|
||||
|
||||
modal: true
|
||||
closePolicy: Popup.NoAutoClose
|
||||
|
||||
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
TextField {
|
||||
id: newCatName
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Tag")
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
saveParam([newCatName.text], true)
|
||||
}
|
||||
}
|
||||
|
||||
Dialog {
|
||||
id: dialogRenameCat
|
||||
|
||||
x: (parent.width - width) / 2
|
||||
y: (parent.height - height) / 2
|
||||
|
||||
modal: true
|
||||
closePolicy: Popup.NoAutoClose
|
||||
|
||||
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
TextField {
|
||||
id: renameCatName
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Tag")
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
saveParam(
|
||||
[
|
||||
renameCatName.text,
|
||||
myModel.get(listView.currentIndex).clb_id
|
||||
],
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Page {
|
||||
anchors.fill: parent
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: 10
|
||||
anchors.leftMargin: 10
|
||||
anchors.bottomMargin: 10
|
||||
anchors.topMargin: 10
|
||||
|
||||
RowLayout {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
highlightMoveDuration: 0
|
||||
highlight: Rectangle { color: Material.accent; radius: 5 }
|
||||
onCurrentIndexChanged: { itemChanged() }
|
||||
delegate: Item {
|
||||
id: listDelegate
|
||||
width: ListView.view.width
|
||||
height: 20
|
||||
Label { text: value }
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
listView.currentIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
model: ListModel {
|
||||
id: myModel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
Button {
|
||||
id: addButton
|
||||
text: qsTr("Add")
|
||||
onClicked: {
|
||||
dialogNewCat.open()
|
||||
}
|
||||
icon.source: "qrc:/images/icons/add.svg"
|
||||
display: AbstractButton.TextBesideIcon
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Button {
|
||||
id: renameButton
|
||||
text: qsTr("Rename")
|
||||
onClicked: {
|
||||
dialogRenameCat.open()
|
||||
}
|
||||
icon.source: "qrc:/images/icons/rename.svg"
|
||||
enabled: false
|
||||
display: AbstractButton.TextBesideIcon
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Button {
|
||||
id: deleteButton
|
||||
text: qsTr("Delete")
|
||||
onClicked: {
|
||||
dialogDeleteConfirmation.open()
|
||||
}
|
||||
icon.source: "qrc:/images/icons/delete.svg"
|
||||
enabled: false
|
||||
display: AbstractButton.TextBesideIcon
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
293
ui/DbManager.qml
Normal file
293
ui/DbManager.qml
Normal file
@@ -0,0 +1,293 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
|
||||
Window {
|
||||
id: windowDBmanager
|
||||
|
||||
width: 500
|
||||
height: 400
|
||||
|
||||
modality: Qt.ApplicationModal
|
||||
flags: Qt.Dialog
|
||||
|
||||
title: qsTr("Artemis - Load Database")
|
||||
|
||||
signal loadDB (string dbName)
|
||||
signal deleteDB (string dbName)
|
||||
signal renameDB (string dbName, string newDbName)
|
||||
|
||||
function loadList(dict) {
|
||||
clearAll()
|
||||
for (var i = 0; i < dict.length; i++) {
|
||||
myModel.append(dict[i])
|
||||
}
|
||||
itemChanged()
|
||||
}
|
||||
|
||||
function itemChanged() {
|
||||
var selected_db = myModel.get(listView.currentIndex)
|
||||
if (selected_db !== undefined) {
|
||||
lockMenu(false)
|
||||
titleLabel.text = myModel.get(listView.currentIndex).name
|
||||
totDocsLabel.text = myModel.get(listView.currentIndex).documents_n
|
||||
totSignalsLabel.text = myModel.get(listView.currentIndex).signals_n
|
||||
totImagesLabel.text = myModel.get(listView.currentIndex).images_n
|
||||
totAudioLabel.text = myModel.get(listView.currentIndex).audio_n
|
||||
} else {
|
||||
lockMenu(true)
|
||||
}
|
||||
}
|
||||
|
||||
function getModel() {
|
||||
var modelList = []
|
||||
for (var i = 0; i < myModel.count; i++) {
|
||||
modelList.push(myModel.get(i).name)
|
||||
}
|
||||
return modelList
|
||||
}
|
||||
|
||||
function clearAll() {
|
||||
titleLabel.text = 'N/A'
|
||||
totDocsLabel.text = ''
|
||||
totSignalsLabel.text = ''
|
||||
totImagesLabel.text = ''
|
||||
totAudioLabel.text = ''
|
||||
myModel.clear()
|
||||
}
|
||||
|
||||
function loadDBButton() {
|
||||
loadDB(myModel.get(listView.currentIndex).db_dir_name)
|
||||
}
|
||||
|
||||
|
||||
function renameDb() {
|
||||
if (textDBName.readOnly) {
|
||||
textDBName.focus = true
|
||||
textDBName.readOnly = false
|
||||
renameButton.highlighted = true
|
||||
createDbButton.enabled = false
|
||||
deleteDbButton.enabled = false
|
||||
}
|
||||
else {
|
||||
renameDB(myModel.get(listView.currentIndex).db_dir_name, textDBName.text)
|
||||
textDBName.focus = false
|
||||
textDBName.readOnly = true
|
||||
renameButton.highlighted = false
|
||||
createDbButton.enabled = true
|
||||
deleteDbButton.enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
function lockMenu(toggle) {
|
||||
if (toggle) {
|
||||
deleteButton.enabled = false
|
||||
renameButton.enabled = false
|
||||
loadButton.enabled = false
|
||||
} else {
|
||||
deleteButton.enabled = true
|
||||
renameButton.enabled = true
|
||||
loadButton.enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
DialogMessage {
|
||||
id: dialogDeleteConfirmation
|
||||
modal: true
|
||||
title: "Are you sure?"
|
||||
message: "You are about to delete the database and all its contents permanently. The process cannot be undone."
|
||||
messageType: "warn"
|
||||
|
||||
standardButtons: Dialog.Cancel | Dialog.Yes
|
||||
|
||||
onAccepted: {
|
||||
deleteDB(myModel.get(listView.currentIndex).db_dir_name)
|
||||
}
|
||||
}
|
||||
|
||||
Dialog {
|
||||
id: renameDb
|
||||
|
||||
x: (parent.width - width) / 2
|
||||
y: (parent.height - height) / 2
|
||||
|
||||
modal: true
|
||||
closePolicy: Popup.NoAutoClose
|
||||
|
||||
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
TextField {
|
||||
id: newDbName
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("New DB Name")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
renameDB(myModel.get(listView.currentIndex).db_dir_name, newDbName.text)
|
||||
}
|
||||
}
|
||||
|
||||
Page {
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: 10
|
||||
anchors.leftMargin: 10
|
||||
anchors.bottomMargin: 10
|
||||
anchors.topMargin: 10
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
width: 150
|
||||
Layout.fillHeight: true
|
||||
highlight: Rectangle { color: Material.accent; radius: 5 }
|
||||
onCurrentIndexChanged: { itemChanged() }
|
||||
delegate: Item {
|
||||
id: listDelegate
|
||||
width: ListView.view.width
|
||||
height: 20
|
||||
Label { text: name }
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
listView.currentIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
model: ListModel {
|
||||
id: myModel
|
||||
}
|
||||
}
|
||||
|
||||
ToolSeparator {
|
||||
rightPadding: 10
|
||||
leftPadding: 10
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
Label {
|
||||
id: titleLabel
|
||||
Layout.bottomMargin: 20
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
font.pointSize: 15
|
||||
font.bold: true
|
||||
}
|
||||
GridLayout {
|
||||
columnSpacing: 25
|
||||
columns: 2
|
||||
|
||||
Label {
|
||||
text: qsTr("Total Signals:")
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: totSignalsLabel
|
||||
text: qsTr("0")
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Total Documents:")
|
||||
font.pointSize: 12
|
||||
}
|
||||
|
||||
Label {
|
||||
id: totDocsLabel
|
||||
text: qsTr("0")
|
||||
font.pointSize: 12
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Images:")
|
||||
Layout.leftMargin: 15
|
||||
font.pointSize: 12
|
||||
}
|
||||
|
||||
Label {
|
||||
id: totImagesLabel
|
||||
text: qsTr("0")
|
||||
font.pointSize: 12
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Audio:")
|
||||
Layout.leftMargin: 15
|
||||
font.pointSize: 12
|
||||
}
|
||||
|
||||
Label {
|
||||
id: totAudioLabel
|
||||
text: qsTr("0")
|
||||
font.pointSize: 12
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Button {
|
||||
id: deleteButton
|
||||
text: qsTr("Delete")
|
||||
icon.source: "qrc:/images/icons/delete.svg"
|
||||
display: AbstractButton.TextBesideIcon
|
||||
enabled: false
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
onClicked: {
|
||||
dialogDeleteConfirmation.open()
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Button {
|
||||
id: renameButton
|
||||
text: qsTr("Rename")
|
||||
icon.source: "qrc:/images/icons/rename.svg"
|
||||
display: AbstractButton.TextBesideIcon
|
||||
enabled: false
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
onClicked: {
|
||||
renameDb.open()
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Button {
|
||||
id: loadButton
|
||||
text: qsTr("Load")
|
||||
icon.source: "qrc:/images/icons/load.svg"
|
||||
display: AbstractButton.TextBesideIcon
|
||||
enabled: false
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
onClicked: {
|
||||
loadDBButton()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
55
ui/DialogMessage.qml
Normal file
55
ui/DialogMessage.qml
Normal file
@@ -0,0 +1,55 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Window
|
||||
|
||||
|
||||
Dialog {
|
||||
x: (parent.width - width) / 2
|
||||
y: (parent.height - height) / 2
|
||||
|
||||
modal: true
|
||||
closePolicy: Popup.NoAutoClose
|
||||
|
||||
property string message
|
||||
property string messageType
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 10
|
||||
|
||||
Image {
|
||||
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
||||
sourceSize.height: 60
|
||||
sourceSize.width: 60
|
||||
|
||||
source: {
|
||||
switch (messageType.toLowerCase()) {
|
||||
case "question":
|
||||
return "qrc:///images/icons/dialog_quest.svg"
|
||||
case "warn":
|
||||
return "qrc:///images/icons/dialog_warn.svg"
|
||||
case "error":
|
||||
return "qrc:///images/icons/dialog_error.svg"
|
||||
case "info":
|
||||
return "qrc:///images/icons/dialog_info.svg"
|
||||
default:
|
||||
return "qrc:///images/icons/dialog_info.svg"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
text: message
|
||||
|
||||
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 200
|
||||
Layout.maximumWidth: 300
|
||||
|
||||
textFormat: Text.RichText
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
}
|
||||
538
ui/DocumentsManager.qml
Normal file
538
ui/DocumentsManager.qml
Normal file
@@ -0,0 +1,538 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Dialogs
|
||||
|
||||
Window {
|
||||
id: documentsManageranager
|
||||
|
||||
width: 800
|
||||
height: 500
|
||||
|
||||
Component.onCompleted: {
|
||||
x = Screen.width/2 - width/2
|
||||
y = Screen.height/2 - height/2
|
||||
}
|
||||
|
||||
modality: Qt.ApplicationModal
|
||||
flags: Qt.Window
|
||||
|
||||
title: qsTr("Artemis - Documents Manager")
|
||||
|
||||
signal saveNewDoc (variant docParamLst)
|
||||
signal updateDoc (variant docParamLst)
|
||||
signal deleteDoc (string docId, string extension, string type, bool preview)
|
||||
signal openDoc (string docId, string extension)
|
||||
|
||||
|
||||
function loadList(dict) {
|
||||
clearAll()
|
||||
for (var i = 0; i < dict.length; i++) {
|
||||
myModel.append(dict[i])
|
||||
}
|
||||
itemChanged()
|
||||
}
|
||||
|
||||
function getModel() {
|
||||
var dictionaryList = []
|
||||
for (var i = 0; i < myModel.count; i++) {
|
||||
var dictionary = [
|
||||
myModel.get(i).doc_id,
|
||||
myModel.get(i).name,
|
||||
myModel.get(i).description,
|
||||
myModel.get(i).type,
|
||||
myModel.get(i).preview,
|
||||
myModel.get(i).extension
|
||||
]
|
||||
dictionaryList.push(dictionary)
|
||||
}
|
||||
return dictionaryList
|
||||
}
|
||||
|
||||
function itemChanged() {
|
||||
var selected_doc = myModel.get(listView.currentIndex)
|
||||
if (selected_doc !== undefined) {
|
||||
|
||||
var docId = selected_doc.doc_id
|
||||
var extension = selected_doc.extension
|
||||
var name = selected_doc.name
|
||||
var description = selected_doc.description
|
||||
var type = selected_doc.type
|
||||
var preview = selected_doc.preview
|
||||
|
||||
nameField.text = name
|
||||
fileNameField.text = docId + '.' + extension
|
||||
descriptionField.text = description
|
||||
lockMenu(false)
|
||||
|
||||
if (type === 'Image' || type === 'Audio') {
|
||||
switchPreview.visible = true
|
||||
if (preview === 1) {
|
||||
switchPreview.checked = true
|
||||
} else {
|
||||
switchPreview.checked = false
|
||||
}
|
||||
} else {
|
||||
switchPreview.visible = false
|
||||
}
|
||||
} else {
|
||||
lockMenu(true)
|
||||
}
|
||||
}
|
||||
|
||||
function contentChanged() {
|
||||
if (listView.currentIndex !== -1) {
|
||||
myModel.set(
|
||||
listView.currentIndex,
|
||||
{
|
||||
'name': nameField.text,
|
||||
'description': descriptionField.text,
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function lockMenu(toggle) {
|
||||
if (toggle) {
|
||||
openButton.enabled = false
|
||||
switchPreview.visible = false
|
||||
deleteButton.enabled = false
|
||||
editButton.enabled = false
|
||||
} else {
|
||||
openButton.enabled = true
|
||||
deleteButton.enabled = true
|
||||
editButton.enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
function clearAll() {
|
||||
nameField.clear()
|
||||
fileNameField.clear()
|
||||
descriptionField.clear()
|
||||
myModel.clear()
|
||||
}
|
||||
|
||||
function previewChanged(is_preview) {
|
||||
var previewItem = myModel.get(listView.currentIndex)
|
||||
if (previewItem.preview !== is_preview) {
|
||||
if (is_preview) {
|
||||
for (var i = 0; i < myModel.count; i++) {
|
||||
if (myModel.get(i).type === previewItem.type) {
|
||||
myModel.get(i).preview = 0
|
||||
}
|
||||
}
|
||||
previewItem.preview = 1
|
||||
} else {
|
||||
previewItem.preview = 0
|
||||
}
|
||||
updateDoc(getModel())
|
||||
itemChanged()
|
||||
changeSavedDialog.open()
|
||||
}
|
||||
}
|
||||
|
||||
function validateFields() {
|
||||
if (newPathField.text === '' || newNameField.text === '') {
|
||||
// message file or name not selected
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
function setEditFileTypeComboBox(type) {
|
||||
for (var idx = 0; idx < editFileTypeComboBox.count; idx ++) {
|
||||
if (type === editFileTypeComboBox.valueAt(idx)) {
|
||||
editFileTypeComboBox.currentIndex = idx
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function editCurrentDoc(name, description, type) {
|
||||
var selected_doc = myModel.get(listView.currentIndex)
|
||||
var doc_param = [
|
||||
selected_doc.doc_id,
|
||||
name,
|
||||
description,
|
||||
type,
|
||||
selected_doc.preview,
|
||||
]
|
||||
updateDoc([doc_param])
|
||||
}
|
||||
|
||||
FileDialog {
|
||||
id: fileDialog
|
||||
title: "Please choose a file"
|
||||
nameFilters: [
|
||||
"Image (*.jpg *.png)",
|
||||
"Audio (*.mp3 *.m4a *.ogg)",
|
||||
"Document (*.txt *.pdf)",
|
||||
"All files (*)"
|
||||
]
|
||||
|
||||
onAccepted: {
|
||||
newPathField.text = selectedFile
|
||||
|
||||
if (selectedNameFilter.name === 'Image') {
|
||||
newFileTypeComboBox.currentIndex = 0
|
||||
} else if (selectedNameFilter.name === 'Audio') {
|
||||
newFileTypeComboBox.currentIndex = 1
|
||||
} else if (selectedNameFilter.name === 'Document') {
|
||||
newFileTypeComboBox.currentIndex = 2
|
||||
} else {
|
||||
newFileTypeComboBox.currentIndex = 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dialog {
|
||||
id: dialogAddNew
|
||||
height: 400
|
||||
width: 400
|
||||
x: (parent.width - width) / 2
|
||||
y: (parent.height - height) / 2
|
||||
|
||||
modal: true
|
||||
closePolicy: Popup.NoAutoClose
|
||||
|
||||
standardButtons: Dialog.Save | Dialog.Close
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
TextField {
|
||||
id: newPathField
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Path")
|
||||
readOnly: true
|
||||
}
|
||||
|
||||
Button {
|
||||
text: qsTr("Browse")
|
||||
onClicked: {
|
||||
fileDialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
ComboBox {
|
||||
id: newFileTypeComboBox
|
||||
model: ["Image", "Audio", "Document", "Other"]
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: newNameField
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Name")
|
||||
}
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
ScrollBar.vertical.interactive: true
|
||||
|
||||
TextArea {
|
||||
id: newDescriptionField
|
||||
placeholderText: qsTr("Description")
|
||||
wrapMode: TextEdit.WordWrap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
if (validateFields()) {
|
||||
saveNewDoc(
|
||||
[
|
||||
newPathField.text,
|
||||
newNameField.text,
|
||||
newDescriptionField.text,
|
||||
newFileTypeComboBox.currentText
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dialog {
|
||||
id: dialogEdit
|
||||
height: 400
|
||||
width: 400
|
||||
x: (parent.width - width) / 2
|
||||
y: (parent.height - height) / 2
|
||||
|
||||
modal: true
|
||||
closePolicy: Popup.NoAutoClose
|
||||
|
||||
standardButtons: Dialog.Save | Dialog.Close
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
ComboBox {
|
||||
id: editFileTypeComboBox
|
||||
model: ["Image", "Audio", "Document", "Other"]
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: editNameField
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Name")
|
||||
}
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
ScrollBar.vertical.interactive: true
|
||||
|
||||
TextArea {
|
||||
id: editDescriptionField
|
||||
placeholderText: qsTr("Description")
|
||||
wrapMode: TextEdit.WordWrap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
editCurrentDoc(
|
||||
editNameField.text,
|
||||
editDescriptionField.text,
|
||||
editFileTypeComboBox.currentText
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
DialogMessage {
|
||||
id: dialogDeleteConfirmation
|
||||
modal: true
|
||||
title: "Are you sure?"
|
||||
message: "You are about to delete the selected document. The process cannot be undone."
|
||||
messageType: "warn"
|
||||
|
||||
standardButtons: Dialog.Cancel | Dialog.Yes
|
||||
|
||||
onAccepted: {
|
||||
deleteDoc(
|
||||
myModel.get(listView.currentIndex).doc_id,
|
||||
myModel.get(listView.currentIndex).extension,
|
||||
myModel.get(listView.currentIndex).type,
|
||||
myModel.get(listView.currentIndex).preview
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
DialogMessage {
|
||||
id: changeSavedDialog
|
||||
title: 'Change Saved!'
|
||||
message: 'Your changes have been successfully saved!'
|
||||
standardButtons: Dialog.Ok
|
||||
}
|
||||
|
||||
Page {
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: 10
|
||||
anchors.leftMargin: 10
|
||||
anchors.bottomMargin: 10
|
||||
spacing: 0
|
||||
anchors.topMargin: 10
|
||||
|
||||
ColumnLayout {
|
||||
Layout.minimumWidth: 150
|
||||
RowLayout {
|
||||
Component {
|
||||
id: sectionHeading
|
||||
Rectangle {
|
||||
width: ListView.view.width
|
||||
height: 30
|
||||
color: "#00000000"
|
||||
Label {
|
||||
text: section
|
||||
font.capitalization: Font.AllUppercase
|
||||
font.bold: true
|
||||
font.pixelSize: 16
|
||||
color: Material.accent
|
||||
font.letterSpacing: 0.5
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
highlightMoveDuration: 0
|
||||
clip: true
|
||||
focus: true
|
||||
ScrollBar.vertical: bar
|
||||
highlight: Rectangle { color: Material.accent; radius: 5 }
|
||||
onCurrentIndexChanged: { itemChanged() }
|
||||
delegate: Item {
|
||||
id: listDelegate
|
||||
width: ListView.view.width
|
||||
height: 20
|
||||
Label { text: name }
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
listView.currentIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
model: ListModel {
|
||||
id: myModel
|
||||
}
|
||||
|
||||
section.property: "type"
|
||||
section.criteria: ViewSection.FullString
|
||||
section.delegate: sectionHeading
|
||||
}
|
||||
ScrollBar {
|
||||
id: bar
|
||||
Layout.fillHeight: true
|
||||
active: true
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: addButton
|
||||
text: qsTr("Add")
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
icon.source: "qrc:/images/icons/add.svg"
|
||||
display: AbstractButton.TextBesideIcon
|
||||
onClicked: {
|
||||
dialogAddNew.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ToolSeparator {
|
||||
id: toolSeparator
|
||||
rightPadding: 10
|
||||
leftPadding: 10
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.preferredWidth: 300
|
||||
|
||||
Label {
|
||||
text: qsTr("FILE DETAILS")
|
||||
font.letterSpacing: 0.5
|
||||
color: Material.accent
|
||||
font.pixelSize: 18
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: nameField
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Name")
|
||||
onTextChanged: {
|
||||
contentChanged()
|
||||
}
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: fileNameField
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("File")
|
||||
readOnly: true
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
ScrollBar.vertical.interactive: true
|
||||
|
||||
TextArea {
|
||||
id: descriptionField
|
||||
wrapMode: TextEdit.WordWrap
|
||||
font.pointSize: 10
|
||||
onTextChanged: {
|
||||
contentChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Button {
|
||||
id: deleteButton
|
||||
text: qsTr("Delete")
|
||||
icon.source: "qrc:/images/icons/delete.svg"
|
||||
display: AbstractButton.TextBesideIcon
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
onClicked: {
|
||||
dialogDeleteConfirmation.open()
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Switch {
|
||||
id: switchPreview
|
||||
text: qsTr("Main")
|
||||
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
previewChanged(1)
|
||||
} else {
|
||||
previewChanged(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: editButton
|
||||
text: qsTr("Edit")
|
||||
enabled: false
|
||||
icon.source: "qrc:/images/icons/rename.svg"
|
||||
display: AbstractButton.TextBesideIcon
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
onClicked: {
|
||||
editNameField.text = myModel.get(listView.currentIndex).name
|
||||
setEditFileTypeComboBox(myModel.get(listView.currentIndex).type)
|
||||
editDescriptionField.text = myModel.get(listView.currentIndex).description
|
||||
dialogEdit.open()
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: openButton
|
||||
text: qsTr("Open")
|
||||
enabled: false
|
||||
icon.source: "qrc:/images/icons/open.svg"
|
||||
display: AbstractButton.TextBesideIcon
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
onClicked: {
|
||||
openDoc(
|
||||
myModel.get(listView.currentIndex).doc_id,
|
||||
myModel.get(listView.currentIndex).extension
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
60
ui/Downloader.qml
Normal file
60
ui/Downloader.qml
Normal file
@@ -0,0 +1,60 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
|
||||
Window {
|
||||
id: windowDownloader
|
||||
|
||||
width: 400
|
||||
height: 130
|
||||
|
||||
maximumHeight: height
|
||||
maximumWidth: width
|
||||
|
||||
minimumHeight: height
|
||||
minimumWidth: width
|
||||
|
||||
modality: Qt.ApplicationModal
|
||||
flags: Qt.Dialog
|
||||
|
||||
title: qsTr("Artemis - Downloader")
|
||||
|
||||
signal onAbort()
|
||||
|
||||
Page {
|
||||
id: page
|
||||
anchors.fill: parent
|
||||
|
||||
ColumnLayout {
|
||||
id: columnLayout
|
||||
anchors.fill: parent
|
||||
|
||||
Label {
|
||||
text: qsTr("Downloading in progress...")
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
ProgressBar {
|
||||
objectName: "progressBar"
|
||||
Layout.rightMargin: 20
|
||||
Layout.leftMargin: 20
|
||||
Layout.fillWidth: true
|
||||
value: 0
|
||||
}
|
||||
|
||||
Label {
|
||||
objectName: "labelProgress"
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
Button {
|
||||
text: qsTr("Abort")
|
||||
icon.source: "qrc:/images/icons/abort.svg"
|
||||
display: AbstractButton.TextBesideIcon
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||
onClicked: { onAbort() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
632
ui/FilterPage.qml
Normal file
632
ui/FilterPage.qml
Normal file
@@ -0,0 +1,632 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
|
||||
|
||||
Page {
|
||||
id: filterPage
|
||||
anchors.fill: parent
|
||||
objectName: "filterPageObj"
|
||||
|
||||
signal applyFilter(var filterDict)
|
||||
signal sendBottomAlert(string message, string messagType)
|
||||
|
||||
property var filterDict: {}
|
||||
|
||||
function updateFilterDict() {
|
||||
filterDict = {}
|
||||
if (switchFreq.checked) {
|
||||
var unitFreqValue = comboBoxFreq.currentValue.value
|
||||
var lower_band = parseFloat(textFieldFreq.text) * unitFreqValue * (1 - tolFreq.value)
|
||||
var upper_band = parseFloat(textFieldFreq.text) * unitFreqValue * (1 + tolFreq.value)
|
||||
filterDict['frequency'] = {
|
||||
'lower_band': lower_band,
|
||||
'upper_band': upper_band
|
||||
}
|
||||
}
|
||||
|
||||
if (switchBand.checked) {
|
||||
var unitBandValue = comboBoxBand.currentValue.value
|
||||
var lower_band = parseFloat(textFieldBand.text) * unitBandValue * (1 - tolBand.value)
|
||||
var upper_band = parseFloat(textFieldBand.text) * unitBandValue * (1 + tolBand.value)
|
||||
filterDict['bandwidth'] = {
|
||||
'lower_band': lower_band,
|
||||
'upper_band': upper_band
|
||||
}
|
||||
}
|
||||
|
||||
if (switchACF.checked) {
|
||||
var lower_band = parseFloat(textFieldACF.text) * (1 - tolACF.value)
|
||||
var upper_band = parseFloat(textFieldACF.text) * (1 + tolACF.value)
|
||||
filterDict['acf'] = {
|
||||
'lower_band': lower_band,
|
||||
'upper_band': upper_band
|
||||
}
|
||||
}
|
||||
|
||||
if (switchModulation.checked) {
|
||||
var modulationList = []
|
||||
for (var i = 0; i < modelModulation.count; i++) {
|
||||
if (modelModulation.get(i).checked) {
|
||||
modulationList.push(
|
||||
modelModulation.get(i).value
|
||||
)
|
||||
}
|
||||
}
|
||||
filterDict['modulation'] = modulationList
|
||||
}
|
||||
|
||||
if (switchLocation.checked) {
|
||||
var locationList = []
|
||||
for (var i = 0; i < modelLocation.count; i++) {
|
||||
if (modelLocation.get(i).checked) {
|
||||
locationList.push(
|
||||
modelLocation.get(i).value
|
||||
)
|
||||
}
|
||||
}
|
||||
filterDict['location'] = locationList
|
||||
}
|
||||
|
||||
if (switchCategory.checked) {
|
||||
var categoryList = []
|
||||
for (var i = 0; i < modelCategory.count; i++) {
|
||||
if (modelCategory.get(i).checked) {
|
||||
categoryList.push(
|
||||
modelCategory.get(i).clb_id
|
||||
)
|
||||
}
|
||||
}
|
||||
filterDict['category'] = categoryList
|
||||
}
|
||||
applyFilter(filterDict)
|
||||
}
|
||||
|
||||
function resetAll() {
|
||||
switchFreq.checked = false
|
||||
switchBand.checked = false
|
||||
switchACF.checked = false
|
||||
switchModulation.checked = false
|
||||
switchLocation.checked = false
|
||||
switchCategory.checked = false
|
||||
lockFreq(true)
|
||||
lockBand(true)
|
||||
lockACF(true)
|
||||
}
|
||||
|
||||
function lockFreq(toggle) {
|
||||
if(toggle) {
|
||||
textFieldFreq.enabled = false
|
||||
comboBoxFreq.enabled = false
|
||||
tolFreq.enabled = false
|
||||
summaryFreq.text = ''
|
||||
}
|
||||
else {
|
||||
textFieldFreq.enabled = true
|
||||
comboBoxFreq.enabled = true
|
||||
tolFreq.enabled = true
|
||||
if (textFieldFreq.text !== '') {
|
||||
updateSummaryFreq()
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function lockBand(toggle) {
|
||||
if(toggle) {
|
||||
textFieldBand.enabled = false
|
||||
comboBoxBand.enabled = false
|
||||
tolBand.enabled = false
|
||||
summaryBand.text = ''
|
||||
}
|
||||
else {
|
||||
textFieldBand.enabled = true
|
||||
comboBoxBand.enabled = true
|
||||
tolBand.enabled = true
|
||||
if (textFieldBand.text !== '') {
|
||||
updateSummaryBand()
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function lockACF(toggle) {
|
||||
if(toggle) {
|
||||
textFieldACF.enabled = false
|
||||
tolACF.enabled = false
|
||||
summaryACF.text = ''
|
||||
}
|
||||
else {
|
||||
textFieldACF.enabled = true
|
||||
tolACF.enabled = true
|
||||
if (textFieldACF.text !== '') {
|
||||
updateSummaryACF()
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateSummaryFreq() {
|
||||
if (textFieldFreq.text !== "") {
|
||||
var unitFreqText = comboBoxFreq.currentValue.text
|
||||
var lowFreq = (parseFloat(textFieldFreq.text) * (1 - tolFreq.value)).toFixed(1)
|
||||
var uppFreq = (parseFloat(textFieldFreq.text) * (1 + tolFreq.value)).toFixed(1)
|
||||
|
||||
if (tolFreq.value === 0) {
|
||||
summaryFreq.text = lowFreq + " " + unitFreqText
|
||||
}
|
||||
else {
|
||||
summaryFreq.text = lowFreq + " " + unitFreqText + " - " + uppFreq + " " + unitFreqText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateSummaryBand() {
|
||||
if (textFieldBand.text !== "") {
|
||||
var unitBandText = comboBoxBand.currentValue.text
|
||||
var lowBand = (parseFloat(textFieldBand.text) * (1 - tolBand.value)).toFixed(1)
|
||||
var uppBand = (parseFloat(textFieldBand.text) * (1 + tolBand.value)).toFixed(1)
|
||||
|
||||
if (tolBand.value === 0) {
|
||||
summaryBand.text = lowBand + " " + unitBandText
|
||||
}
|
||||
else {
|
||||
summaryBand.text = lowBand + " " + unitBandText + " - " + uppBand + " " + unitBandText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateSummaryACF() {
|
||||
if (textFieldACF.text !== "") {
|
||||
var lowBand = (parseFloat(textFieldACF.text) * (1 - tolACF.value)).toFixed(1)
|
||||
var uppBand = (parseFloat(textFieldACF.text) * (1 + tolACF.value)).toFixed(1)
|
||||
|
||||
if (tolACF.value === 0) {
|
||||
summaryACF.text = lowBand + " ms"
|
||||
}
|
||||
else {
|
||||
summaryACF.text = lowBand + " ms" + " - " + uppBand + " ms"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadLists(filterList) {
|
||||
modelModulation.clear()
|
||||
var modulationDict = filterList[0].modulation
|
||||
for (var i = 0; i < modulationDict.length; i++) {
|
||||
modelModulation.append(modulationDict[i])
|
||||
}
|
||||
|
||||
modelLocation.clear()
|
||||
var locationDict = filterList[0].location
|
||||
for (var i = 0; i < locationDict.length; i++) {
|
||||
modelLocation.append(locationDict[i])
|
||||
}
|
||||
|
||||
modelCategory.clear()
|
||||
var categoryDict = filterList[0].category
|
||||
for (var i = 0; i < categoryDict.length; i++) {
|
||||
modelCategory.append(categoryDict[i])
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
GridLayout {
|
||||
rows: 2
|
||||
columns: 3
|
||||
rowSpacing: 10
|
||||
columnSpacing: 10
|
||||
|
||||
GroupBox {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout {
|
||||
Label {
|
||||
text: qsTr("Frequency")
|
||||
Layout.fillWidth: true
|
||||
font.bold: true
|
||||
font.pointSize: 12
|
||||
font.capitalization: Font.SmallCaps
|
||||
}
|
||||
|
||||
Switch {
|
||||
id: switchFreq
|
||||
onToggled: {
|
||||
if(switchFreq.checked) {
|
||||
lockFreq(false)
|
||||
}
|
||||
else {
|
||||
lockFreq(true)
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
TextField {
|
||||
id: textFieldFreq
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Frequency")
|
||||
validator: DoubleValidator{bottom: 0}
|
||||
enabled: false
|
||||
onTextChanged: {
|
||||
if(switchFreq.checked && textFieldFreq.text !== '') {
|
||||
updateSummaryFreq()
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: comboBoxFreq
|
||||
enabled: false
|
||||
textRole: 'text'
|
||||
model: ListModel {
|
||||
ListElement { text: "Hz"; value: 1 }
|
||||
ListElement { text: "kHz"; value: 1e3 }
|
||||
ListElement { text: "MHz"; value: 1e6 }
|
||||
ListElement { text: "GHz"; value: 1e9 }
|
||||
}
|
||||
onActivated: {
|
||||
if(switchFreq.checked && textFieldFreq.text !== '') {
|
||||
updateSummaryFreq()
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Slider {
|
||||
id: tolFreq
|
||||
Layout.fillWidth: true
|
||||
enabled: false
|
||||
value: 0
|
||||
onValueChanged: {
|
||||
if(switchFreq.checked && textFieldFreq.text !== '') {
|
||||
updateSummaryFreq()
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
id: summaryFreq
|
||||
color: Material.color(Material.Green)
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GroupBox {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout {
|
||||
Label {
|
||||
text: qsTr("Bandwidth")
|
||||
Layout.fillWidth: true
|
||||
font.bold: true
|
||||
font.pointSize: 12
|
||||
font.capitalization: Font.SmallCaps
|
||||
}
|
||||
|
||||
Switch {
|
||||
id: switchBand
|
||||
onToggled: {
|
||||
if(switchBand.checked) {
|
||||
lockBand(false)
|
||||
}
|
||||
else {
|
||||
lockBand(true)
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
TextField {
|
||||
id: textFieldBand
|
||||
validator: DoubleValidator {
|
||||
bottom: 0
|
||||
}
|
||||
onTextChanged: {
|
||||
if(switchBand.checked && textFieldBand.text !== '') {
|
||||
updateSummaryBand()
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Bandwidth")
|
||||
enabled: false
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: comboBoxBand
|
||||
enabled: false
|
||||
textRole: 'text'
|
||||
model: ListModel {
|
||||
ListElement { text: "Hz"; value: 1 }
|
||||
ListElement { text: "kHz"; value: 1e3 }
|
||||
ListElement { text: "MHz"; value: 1e6 }
|
||||
ListElement { text: "GHz"; value: 1e9 }
|
||||
}
|
||||
onActivated: {
|
||||
if(switchBand.checked && textFieldBand.text !== '') {
|
||||
updateSummaryBand()
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Slider {
|
||||
id: tolBand
|
||||
Layout.fillWidth: true
|
||||
enabled: false
|
||||
value: 0
|
||||
onValueChanged: {
|
||||
if(switchBand.checked && textFieldBand.text !== '') {
|
||||
updateSummaryBand()
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
}
|
||||
Label {
|
||||
id: summaryBand
|
||||
color: Material.color(Material.Green)
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GroupBox {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout {
|
||||
Label {
|
||||
text: qsTr("ACF")
|
||||
Layout.fillWidth: true
|
||||
font.bold: true
|
||||
font.pointSize: 12
|
||||
font.capitalization: Font.SmallCaps
|
||||
}
|
||||
|
||||
Switch {
|
||||
id: switchACF
|
||||
onToggled: {
|
||||
if(switchACF.checked) {
|
||||
lockACF(false)
|
||||
} else {
|
||||
lockACF(true)
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
TextField {
|
||||
id: textFieldACF
|
||||
validator: DoubleValidator {
|
||||
bottom: 0
|
||||
}
|
||||
onTextChanged: {
|
||||
if(switchACF.checked && textFieldACF.text !== '') {
|
||||
updateSummaryACF()
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("ACF")
|
||||
enabled: false
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
enabled: false
|
||||
model: ['ms']
|
||||
}
|
||||
}
|
||||
|
||||
Slider {
|
||||
id: tolACF
|
||||
Layout.fillWidth: true
|
||||
enabled: false
|
||||
value: 0
|
||||
onValueChanged: {
|
||||
if(switchACF.checked && textFieldACF.text !== '') {
|
||||
updateSummaryACF()
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
}
|
||||
Label {
|
||||
id: summaryACF
|
||||
color: Material.color(Material.Green)
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GroupBox {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout {
|
||||
Label {
|
||||
text: qsTr("Modulation")
|
||||
Layout.fillWidth: true
|
||||
font.bold: true
|
||||
font.pointSize: 12
|
||||
font.capitalization: Font.SmallCaps
|
||||
}
|
||||
Switch {
|
||||
id: switchModulation
|
||||
onToggled: {
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
Layout.minimumHeight: 200
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
highlightMoveDuration: 0
|
||||
clip: true
|
||||
focus: true
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
active: true
|
||||
}
|
||||
delegate: Item {
|
||||
width: ListView.view.width
|
||||
height: 30
|
||||
CheckBox {
|
||||
enabled: switchModulation.checked
|
||||
text: value
|
||||
onCheckedChanged: {
|
||||
modelModulation.setProperty(index, "checked", checked)
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
}
|
||||
model: ListModel {
|
||||
id: modelModulation
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GroupBox {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout {
|
||||
Label {
|
||||
text: qsTr("Location")
|
||||
Layout.fillWidth: true
|
||||
font.bold: true
|
||||
font.pointSize: 12
|
||||
font.capitalization: Font.SmallCaps
|
||||
}
|
||||
Switch {
|
||||
id: switchLocation
|
||||
onToggled: {
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
Layout.minimumHeight: 200
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
highlightMoveDuration: 0
|
||||
clip: true
|
||||
focus: true
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
active: true
|
||||
}
|
||||
delegate: Item {
|
||||
width: ListView.view.width
|
||||
height: 30
|
||||
CheckBox {
|
||||
enabled: switchLocation.checked
|
||||
text: value
|
||||
onCheckedChanged: {
|
||||
modelLocation.setProperty(index, "checked", checked)
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
}
|
||||
model: ListModel {
|
||||
id: modelLocation
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GroupBox {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout {
|
||||
Label {
|
||||
text: qsTr("Category")
|
||||
Layout.fillWidth: true
|
||||
font.bold: true
|
||||
font.pointSize: 12
|
||||
font.capitalization: Font.SmallCaps
|
||||
}
|
||||
Switch {
|
||||
id: switchCategory
|
||||
onToggled: {
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
Layout.minimumHeight: 200
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
highlightMoveDuration: 0
|
||||
clip: true
|
||||
focus: true
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
active: true
|
||||
}
|
||||
delegate: Item {
|
||||
width: ListView.view.width
|
||||
height: 30
|
||||
CheckBox {
|
||||
enabled: switchCategory.checked
|
||||
text: value
|
||||
onCheckedChanged: {
|
||||
modelCategory.setProperty(index, "checked", checked)
|
||||
updateFilterDict()
|
||||
}
|
||||
}
|
||||
}
|
||||
model: ListModel {
|
||||
id: modelCategory
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
151
ui/Preferences.qml
Normal file
151
ui/Preferences.qml
Normal file
@@ -0,0 +1,151 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
|
||||
|
||||
Window {
|
||||
id: windowPreferences
|
||||
|
||||
width: 450
|
||||
height: 400
|
||||
|
||||
Component.onCompleted: {
|
||||
x = Screen.width/2 - width/2
|
||||
y = Screen.height/2 - height/2
|
||||
}
|
||||
|
||||
modality: Qt.ApplicationModal
|
||||
flags: Qt.Window
|
||||
|
||||
title: qsTr("Artemis - Preferences")
|
||||
|
||||
signal saveMaterialAccent(string arg)
|
||||
signal saveMaterialTheme(string arg)
|
||||
|
||||
function saveAll() {
|
||||
saveMaterialAccent(comboBoxAccent.currentText)
|
||||
saveMaterialTheme(comboBoxTheme.currentText)
|
||||
}
|
||||
|
||||
function loadMaterialAccent(accent) {
|
||||
for (var idx = 0; idx < comboBoxAccent.count; idx ++) {
|
||||
if (accent === comboBoxAccent.valueAt(idx)) {
|
||||
comboBoxAccent.currentIndex = idx
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadMaterialTheme(theme) {
|
||||
for (var idx = 0; idx < comboBoxTheme.count; idx ++) {
|
||||
if (theme === comboBoxTheme.valueAt(idx)) {
|
||||
comboBoxTheme.currentIndex = idx
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DialogMessage {
|
||||
id: dialogPreferencesSaved
|
||||
modal: true
|
||||
|
||||
title: "Preferences saved!"
|
||||
message: "User preferences has been saved succesfully! Artemis restart is require for changes to take effect."
|
||||
|
||||
standardButtons: Dialog.Ok
|
||||
|
||||
onAccepted: {
|
||||
windowPreferences.close()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Pane {
|
||||
anchors.fill: parent
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: 15
|
||||
anchors.leftMargin: 15
|
||||
anchors.bottomMargin: 15
|
||||
anchors.topMargin: 15
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
Label {
|
||||
text: "Material Theme"
|
||||
font.pixelSize: 12
|
||||
clip: true
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: comboBoxTheme
|
||||
width: 137
|
||||
height: 48
|
||||
model: [
|
||||
"System",
|
||||
"Light",
|
||||
"Dark"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
Label {
|
||||
text: "Material Accent"
|
||||
font.pixelSize: 12
|
||||
clip: true
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: comboBoxAccent
|
||||
width: 137
|
||||
height: 48
|
||||
model: [
|
||||
"Red",
|
||||
"Pink",
|
||||
"Purple",
|
||||
"DeepPurple",
|
||||
"Indigo",
|
||||
"Blue",
|
||||
"LightBlue",
|
||||
"Cyan",
|
||||
"Teal",
|
||||
"Green",
|
||||
"LightGreen",
|
||||
"Lime",
|
||||
"Yellow",
|
||||
"Amber",
|
||||
"Orange",
|
||||
"DeepOrange",
|
||||
"Brown",
|
||||
"Grey",
|
||||
"BlueGrey"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
Button {
|
||||
text: qsTr("Save")
|
||||
icon.source: "qrc:/images/icons/save.svg"
|
||||
display: AbstractButton.TextBesideIcon
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignBottom
|
||||
onClicked: {
|
||||
saveAll()
|
||||
dialogPreferencesSaved.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
204
ui/SignalEditor.qml
Normal file
204
ui/SignalEditor.qml
Normal file
@@ -0,0 +1,204 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
|
||||
|
||||
Window {
|
||||
id: windowSignalEditor
|
||||
|
||||
width: 500
|
||||
height: 400
|
||||
|
||||
Component.onCompleted: {
|
||||
x = Screen.width/2 - width/2
|
||||
y = Screen.height/2 - height/2
|
||||
}
|
||||
|
||||
modality: Qt.ApplicationModal
|
||||
flags: Qt.Window
|
||||
|
||||
signal saveParam(string type, var data, bool isNew)
|
||||
signal deleteParam(string type, int ID)
|
||||
|
||||
property string paramType
|
||||
property int paramID
|
||||
property bool isNew
|
||||
|
||||
property var validator_freq: /^\d+(\.\d+)?$/
|
||||
property var validator_all: /.*/
|
||||
|
||||
|
||||
function load(type, sig_param, is_new) {
|
||||
clearAll()
|
||||
isNew = is_new
|
||||
paramType = type
|
||||
|
||||
paramValue.placeholderText = paramType
|
||||
|
||||
if (isNew) {
|
||||
paramID = 0
|
||||
windowSignalEditor.title = 'Artemis - New ' + paramType
|
||||
} else {
|
||||
paramID = sig_param[0]
|
||||
windowSignalEditor.title = 'Artemis - Edit ' + paramType
|
||||
if (paramType === 'Frequency' || paramType === 'Bandwidth') {
|
||||
var freq = changeUnit(sig_param[1])
|
||||
paramValue.text = sig_param[1] / freq.scale
|
||||
loadUnitComboBox(freq.unit)
|
||||
} else {
|
||||
paramValue.text = sig_param[1]
|
||||
}
|
||||
paramDescription.text = sig_param[2]
|
||||
}
|
||||
}
|
||||
|
||||
function save() {
|
||||
if (paramType === 'Frequency' || paramType === 'Bandwidth') {
|
||||
var scaleFactor = unitComboBox.currentValue.value
|
||||
var mainValue = paramValue.text * scaleFactor
|
||||
} else {
|
||||
var mainValue = paramValue.text
|
||||
}
|
||||
var param = [paramID, mainValue, paramDescription.text]
|
||||
saveParam(paramType, param, isNew)
|
||||
changeSavedDialog.open()
|
||||
}
|
||||
|
||||
function clearAll() {
|
||||
paramValue.clear()
|
||||
paramDescription.clear()
|
||||
loadUnitComboBox('Hz')
|
||||
}
|
||||
|
||||
function changeUnit(frequency) {
|
||||
var digits = frequency.toString().length
|
||||
|
||||
if (digits < 4)
|
||||
return { scale: 1, unit: "Hz" }
|
||||
else if (digits < 7)
|
||||
return { scale: Math.pow(10, 3), unit: "kHz" }
|
||||
else if (digits < 10)
|
||||
return { scale: Math.pow(10, 6), unit: "MHz" }
|
||||
else
|
||||
return { scale: Math.pow(10, 9), unit: "GHz" }
|
||||
}
|
||||
|
||||
function loadUnitComboBox(unit) {
|
||||
for (var idx = 0; idx < unitComboBox.count; idx ++) {
|
||||
if (unit === unitComboBox.valueAt(idx).text) {
|
||||
unitComboBox.currentIndex = idx
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DialogMessage {
|
||||
id: changeSavedDialog
|
||||
title: 'Change Saved!'
|
||||
message: 'Your changes have been successfully saved!'
|
||||
standardButtons: Dialog.Ok
|
||||
|
||||
onAccepted: {
|
||||
windowSignalEditor.close()
|
||||
}
|
||||
}
|
||||
|
||||
DialogMessage {
|
||||
id: dialogDeleteConfirmation
|
||||
modal: true
|
||||
title: "Are you sure?"
|
||||
message: "You are about to delete the selected " + paramType + ". The process cannot be undone."
|
||||
messageType: "warn"
|
||||
standardButtons: Dialog.Cancel | Dialog.Yes
|
||||
|
||||
onAccepted: {
|
||||
deleteParam(paramType, paramID)
|
||||
windowSignalEditor.close()
|
||||
}
|
||||
}
|
||||
|
||||
Page {
|
||||
anchors.fill: parent
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 10
|
||||
anchors.rightMargin: 10
|
||||
anchors.topMargin: 10
|
||||
anchors.bottomMargin: 10
|
||||
|
||||
RowLayout {
|
||||
|
||||
TextField {
|
||||
id: paramValue
|
||||
visible: paramType !== 'Description' ? true : false
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Frequency")
|
||||
validator: RegularExpressionValidator {
|
||||
regularExpression: paramType === 'Frequency' || paramType === 'Bandwidth' ? validator_freq : validator_all
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: unitComboBox
|
||||
visible: paramType === 'Frequency' || paramType === 'Bandwidth' ? true : false
|
||||
textRole: 'text'
|
||||
model: ListModel {
|
||||
ListElement { text: 'Hz'; value: 1 }
|
||||
ListElement { text: 'kHz'; value: 1e3 }
|
||||
ListElement { text: 'MHz'; value: 1e6 }
|
||||
ListElement { text: 'GHz'; value: 1e9 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 5
|
||||
Layout.fillHeight: true
|
||||
ScrollBar.vertical.interactive: true
|
||||
|
||||
TextArea {
|
||||
id: paramDescription
|
||||
placeholderText: qsTr("Description")
|
||||
wrapMode: TextEdit.WordWrap
|
||||
font.pointSize: 10
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
|
||||
Button {
|
||||
id: deleteButton
|
||||
visible: isNew ? false : true
|
||||
text: qsTr("Delete")
|
||||
icon.source: "qrc:/images/icons/delete.svg"
|
||||
display: AbstractButton.TextBesideIcon
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
onClicked: {
|
||||
dialogDeleteConfirmation.open()
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Button {
|
||||
id: saveButton
|
||||
text: qsTr("Save")
|
||||
icon.source: "qrc:/images/icons/save.svg"
|
||||
display: AbstractButton.TextBesideIcon
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
onClicked: {
|
||||
save()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
644
ui/SignalPage.qml
Normal file
644
ui/SignalPage.qml
Normal file
@@ -0,0 +1,644 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
|
||||
import './components' as UIComponents
|
||||
|
||||
|
||||
Page {
|
||||
id: signalPage
|
||||
anchors.fill: parent
|
||||
objectName: "signalPageObj"
|
||||
|
||||
signal openDocManager()
|
||||
signal openSigEditor(string type, var sig_param, bool is_new)
|
||||
signal addCatTag(int clbId)
|
||||
signal deleteCatTag(int catId)
|
||||
|
||||
property string urlSigidwiki
|
||||
property var frequencyList
|
||||
property var bandwidthList
|
||||
property var categoryList
|
||||
property var allCategoryList
|
||||
property var modulationList
|
||||
property var modeList
|
||||
property var acfList
|
||||
property var locationList
|
||||
|
||||
|
||||
function populateSignalParam(sig) {
|
||||
var sig = sig[0]
|
||||
signalName.text = sig.name
|
||||
frequencyList = sig.frequency
|
||||
bandwidthList = sig.bandwidth
|
||||
|
||||
var freq_lo = sig.frequency[0]
|
||||
var freq_up = sig.frequency.slice(-1)[0]
|
||||
var band_lo = sig.bandwidth[0]
|
||||
var band_up = sig.bandwidth.slice(-1)[0]
|
||||
|
||||
freqValue.text = format_range(freq_lo, freq_up)
|
||||
bandValue.text = format_range(band_lo, band_up)
|
||||
|
||||
categoryList = sig.category
|
||||
allCategoryList = sig.all_category
|
||||
modeList = sig.mode
|
||||
modulationList = sig.modulation
|
||||
locationList = sig.location
|
||||
acfList = sig.acf
|
||||
|
||||
descriptionTextArea.text = sig.description
|
||||
|
||||
if (freq_lo !== undefined) {
|
||||
bandBar.setBandBar(freq_lo[1], freq_up[1])
|
||||
}
|
||||
|
||||
if (sig.url !== undefined) {
|
||||
urlButton.visible = true
|
||||
urlSigidwiki = sig.url
|
||||
}
|
||||
else {
|
||||
urlButton.visible = false
|
||||
}
|
||||
|
||||
image.source = sig.spectrum_path
|
||||
|
||||
if (sig.audio_path !== '') {
|
||||
loadPlayer(sig.audio_path)
|
||||
} else {
|
||||
lockPlayer()
|
||||
}
|
||||
|
||||
lockMenu(false)
|
||||
}
|
||||
|
||||
function format_range(lower_freq, upper_freq) {
|
||||
try {
|
||||
if (lower_freq[1] !== upper_freq[1]) {
|
||||
return lower_freq[3] + ' - ' + upper_freq[3]
|
||||
} else {
|
||||
return lower_freq[3]
|
||||
}
|
||||
} catch (error) {
|
||||
return 'UNKNOWN'
|
||||
}
|
||||
}
|
||||
|
||||
function loadPlayer(audio_path) {
|
||||
audioPlayer.resetPlayer()
|
||||
audioPlayer.loadSound(audio_path)
|
||||
}
|
||||
|
||||
function lockPlayer() {
|
||||
audioPlayer.resetPlayer()
|
||||
}
|
||||
|
||||
function resetAll() {
|
||||
signalName.text = ""
|
||||
freqValue.text = "-"
|
||||
bandValue.text = "-"
|
||||
frequencyList = []
|
||||
bandwidthList = []
|
||||
categoryList = []
|
||||
modeList = []
|
||||
modulationList = []
|
||||
locationList = []
|
||||
acfList = []
|
||||
descriptionTextArea.text = ""
|
||||
bandBar.resetBandBar()
|
||||
audioPlayer.resetPlayer()
|
||||
image.source = "qrc:///images/spectrum_not_available.svg"
|
||||
lockMenu(true)
|
||||
}
|
||||
|
||||
function lockMenu(toggle) {
|
||||
if (toggle) {
|
||||
urlButton.visible = false
|
||||
docManagerButton.visible = false
|
||||
freqButton.enabled = false
|
||||
bandButton.enabled = false
|
||||
modulationButton.enabled = false
|
||||
modeButton.enabled = false
|
||||
acfButton.enabled = false
|
||||
locationButton.enabled = false
|
||||
addTagButton.enabled = false
|
||||
} else {
|
||||
docManagerButton.visible = true
|
||||
freqButton.enabled = true
|
||||
bandButton.enabled = true
|
||||
modulationButton.enabled = true
|
||||
modeButton.enabled = true
|
||||
acfButton.enabled = true
|
||||
locationButton.enabled = true
|
||||
addTagButton.enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
Dialog {
|
||||
id: dialogAddCategory
|
||||
|
||||
x: (parent.width - width) / 2
|
||||
y: (parent.height - height) / 2
|
||||
|
||||
modal: true
|
||||
closePolicy: Popup.CloseOnPressOutside
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
Repeater {
|
||||
model: allCategoryList
|
||||
delegate: Button {
|
||||
text: modelData.value
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 25
|
||||
highlighted: true
|
||||
bottomInset: 3
|
||||
topInset: 3
|
||||
flat: false
|
||||
onClicked: {
|
||||
addCatTag(modelData.clb_id)
|
||||
dialogAddCategory.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
Label {
|
||||
id: signalName
|
||||
color: Material.accent
|
||||
font.pixelSize: 25
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
Layout.topMargin: 10
|
||||
Layout.fillHeight: false
|
||||
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
||||
clip: true
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
Repeater {
|
||||
model: categoryList
|
||||
delegate: Button {
|
||||
text: modelData[1]
|
||||
Layout.preferredHeight: 25
|
||||
highlighted: true
|
||||
bottomInset: 3
|
||||
topInset: 3
|
||||
flat: false
|
||||
ToolTip {
|
||||
visible: hovered
|
||||
text: 'Click to remove'
|
||||
}
|
||||
onClicked: {
|
||||
deleteCatTag(modelData[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: addTagButton
|
||||
enabled: false
|
||||
Layout.preferredHeight: 25
|
||||
Layout.preferredWidth: 25
|
||||
bottomInset: 3
|
||||
topInset: 3
|
||||
text: '+'
|
||||
onClicked: {
|
||||
dialogAddCategory.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
|
||||
ColumnLayout {
|
||||
Label {
|
||||
color: Material.accent
|
||||
text: qsTr("FREQUENCY RANGE")
|
||||
font.pixelSize: 12
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: freqValue
|
||||
color: Material.accent
|
||||
text: qsTr("-")
|
||||
font.pixelSize: 18
|
||||
font.bold: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Label {
|
||||
color: Material.accent
|
||||
text: qsTr("BANDWIDTH RANGE")
|
||||
font.pixelSize: 12
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: bandValue
|
||||
color: Material.accent
|
||||
text: qsTr("-")
|
||||
font.pixelSize: 18
|
||||
font.bold: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UIComponents.BandBar {
|
||||
id: bandBar
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
|
||||
RowLayout {
|
||||
width: 100
|
||||
height: 100
|
||||
Layout.topMargin: 5
|
||||
spacing: 15
|
||||
|
||||
ColumnLayout {
|
||||
width: 100
|
||||
height: 100
|
||||
|
||||
RowLayout {
|
||||
Button {
|
||||
id: freqButton
|
||||
enabled: false
|
||||
contentItem: Label {
|
||||
text: "FREQUENCY"
|
||||
horizontalAlignment : Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: 14
|
||||
font.bold: true
|
||||
}
|
||||
Layout.minimumWidth: 120
|
||||
height: 25
|
||||
flat: true
|
||||
bottomInset: 0
|
||||
topInset: 0
|
||||
rightPadding: 10
|
||||
leftPadding: 10
|
||||
bottomPadding: 0
|
||||
topPadding: 0
|
||||
onClicked: {
|
||||
openSigEditor('Frequency', [], true)
|
||||
}
|
||||
}
|
||||
ListView {
|
||||
height: 25
|
||||
Layout.fillWidth: true
|
||||
spacing: 5
|
||||
orientation: ListView.Horizontal
|
||||
clip: true
|
||||
model: frequencyList
|
||||
delegate: Button {
|
||||
text: modelData[3]
|
||||
height: 25
|
||||
bottomInset: 3
|
||||
topInset: 3
|
||||
flat: false
|
||||
ToolTip {
|
||||
visible: modelData[2] !== '' ? hovered : false
|
||||
text: modelData[2]
|
||||
}
|
||||
onClicked: {
|
||||
openSigEditor('Frequency', modelData, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Button {
|
||||
id: bandButton
|
||||
enabled: false
|
||||
contentItem: Label {
|
||||
text: "BANDWIDTH"
|
||||
horizontalAlignment : Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: 14
|
||||
font.bold: true
|
||||
}
|
||||
Layout.minimumWidth: 120
|
||||
height: 25
|
||||
flat: true
|
||||
bottomInset: 0
|
||||
topInset: 0
|
||||
rightPadding: 10
|
||||
leftPadding: 10
|
||||
bottomPadding: 0
|
||||
topPadding: 0
|
||||
onClicked: {
|
||||
openSigEditor('Bandwidth', [], true)
|
||||
}
|
||||
}
|
||||
ListView {
|
||||
height: 25
|
||||
Layout.fillWidth: true
|
||||
spacing: 5
|
||||
orientation: ListView.Horizontal
|
||||
clip: true
|
||||
model: bandwidthList
|
||||
delegate: Button {
|
||||
text: modelData[3]
|
||||
height: 25
|
||||
bottomInset: 3
|
||||
topInset: 3
|
||||
flat: false
|
||||
ToolTip {
|
||||
visible: modelData[2] !== '' ? hovered : false
|
||||
text: modelData[2]
|
||||
}
|
||||
onClicked: {
|
||||
openSigEditor('Bandwidth', modelData, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Button {
|
||||
id: modulationButton
|
||||
enabled: false
|
||||
contentItem: Label {
|
||||
text: "MODULATION"
|
||||
horizontalAlignment : Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: 14
|
||||
font.bold: true
|
||||
}
|
||||
Layout.minimumWidth: 120
|
||||
height: 25
|
||||
flat: true
|
||||
bottomInset: 0
|
||||
topInset: 0
|
||||
rightPadding: 10
|
||||
leftPadding: 10
|
||||
bottomPadding: 0
|
||||
topPadding: 0
|
||||
onClicked: {
|
||||
openSigEditor('Modulation', [], true)
|
||||
}
|
||||
}
|
||||
ListView {
|
||||
height: 25
|
||||
Layout.fillWidth: true
|
||||
spacing: 5
|
||||
orientation: ListView.Horizontal
|
||||
clip: true
|
||||
model: modulationList
|
||||
delegate: Button {
|
||||
text: modelData[1]
|
||||
height: 25
|
||||
bottomInset: 3
|
||||
topInset: 3
|
||||
flat: false
|
||||
ToolTip {
|
||||
visible: modelData[2] !== '' ? hovered : false
|
||||
text: modelData[2]
|
||||
}
|
||||
onClicked: {
|
||||
openSigEditor('Modulation', modelData, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Button {
|
||||
id: modeButton
|
||||
enabled: false
|
||||
contentItem: Label {
|
||||
text: "MODE"
|
||||
horizontalAlignment : Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: 14
|
||||
font.bold: true
|
||||
}
|
||||
Layout.minimumWidth: 120
|
||||
height: 25
|
||||
flat: true
|
||||
bottomInset: 0
|
||||
topInset: 0
|
||||
rightPadding: 10
|
||||
leftPadding: 10
|
||||
bottomPadding: 0
|
||||
topPadding: 0
|
||||
onClicked: {
|
||||
openSigEditor('Mode', [], true)
|
||||
}
|
||||
}
|
||||
ListView {
|
||||
height: 25
|
||||
Layout.fillWidth: true
|
||||
spacing: 5
|
||||
orientation: ListView.Horizontal
|
||||
clip: true
|
||||
model: modeList
|
||||
delegate: Button {
|
||||
text: modelData[1]
|
||||
height: 25
|
||||
bottomInset: 3
|
||||
topInset: 3
|
||||
flat: false
|
||||
ToolTip {
|
||||
visible: modelData[2] !== '' ? hovered : false
|
||||
text: modelData[2]
|
||||
}
|
||||
onClicked: {
|
||||
openSigEditor('Mode', modelData, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Button {
|
||||
id: acfButton
|
||||
enabled: false
|
||||
contentItem: Label {
|
||||
text: "ACF"
|
||||
horizontalAlignment : Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: 14
|
||||
font.bold: true
|
||||
}
|
||||
height: 25
|
||||
Layout.minimumWidth: 120
|
||||
flat: true
|
||||
bottomInset: 0
|
||||
topInset: 0
|
||||
rightPadding: 10
|
||||
leftPadding: 10
|
||||
bottomPadding: 0
|
||||
topPadding: 0
|
||||
onClicked: {
|
||||
openSigEditor('ACF', [], true)
|
||||
}
|
||||
}
|
||||
ListView {
|
||||
height: 25
|
||||
Layout.fillWidth: true
|
||||
spacing: 5
|
||||
orientation: ListView.Horizontal
|
||||
clip: true
|
||||
model: acfList
|
||||
delegate: Button {
|
||||
text: modelData[1]
|
||||
height: 25
|
||||
bottomInset: 3
|
||||
topInset: 3
|
||||
flat: false
|
||||
ToolTip {
|
||||
visible: modelData[2] !== '' ? hovered : false
|
||||
text: modelData[2]
|
||||
}
|
||||
onClicked: {
|
||||
openSigEditor('ACF', modelData, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Button {
|
||||
id: locationButton
|
||||
enabled: false
|
||||
contentItem: Label {
|
||||
text: "LOCATION"
|
||||
horizontalAlignment : Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: 14
|
||||
font.bold: true
|
||||
}
|
||||
Layout.minimumWidth: 120
|
||||
height: 25
|
||||
flat: true
|
||||
bottomInset: 0
|
||||
topInset: 0
|
||||
rightPadding: 10
|
||||
leftPadding: 10
|
||||
bottomPadding: 0
|
||||
topPadding: 0
|
||||
onClicked: {
|
||||
openSigEditor('Location', [], true)
|
||||
}
|
||||
}
|
||||
ListView {
|
||||
height: 25
|
||||
Layout.fillWidth: true
|
||||
spacing: 5
|
||||
orientation: ListView.Horizontal
|
||||
clip: true
|
||||
model: locationList
|
||||
delegate: Button {
|
||||
text: modelData[1]
|
||||
height: 25
|
||||
bottomInset: 3
|
||||
topInset: 3
|
||||
flat: false
|
||||
ToolTip {
|
||||
visible: modelData[2] !== '' ? hovered : false
|
||||
text: modelData[2]
|
||||
}
|
||||
onClicked: {
|
||||
openSigEditor('Location', modelData, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 5
|
||||
Layout.fillHeight: true
|
||||
ScrollBar.vertical.interactive: true
|
||||
|
||||
TextArea {
|
||||
id: descriptionTextArea
|
||||
wrapMode: TextEdit.WordWrap
|
||||
textFormat: Text.MarkdownText
|
||||
font.pointSize: 10
|
||||
readOnly: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: false
|
||||
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
||||
|
||||
UIComponents.AudioPlayer {
|
||||
id: audioPlayer
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||
}
|
||||
|
||||
Image {
|
||||
id: image
|
||||
source: ""
|
||||
Layout.preferredHeight: 300
|
||||
Layout.preferredWidth: 180
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
fillMode: Image.Stretch
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
|
||||
RoundButton {
|
||||
id: urlButton
|
||||
icon.source: "qrc:/images/icons/browser.svg"
|
||||
display: AbstractButton.IconOnly
|
||||
visible: false
|
||||
text: "U"
|
||||
onClicked: {
|
||||
Qt.openUrlExternally(urlSigidwiki)
|
||||
}
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: docManagerButton
|
||||
icon.source: "qrc:/images/icons/documents.svg"
|
||||
display: AbstractButton.IconOnly
|
||||
visible: false
|
||||
text: "D"
|
||||
onClicked: {
|
||||
openDocManager()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
74
ui/SpaceWeather.qml
Normal file
74
ui/SpaceWeather.qml
Normal file
@@ -0,0 +1,74 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
|
||||
Window {
|
||||
id: windowSpaceWeather
|
||||
|
||||
width: 1000
|
||||
height: 700
|
||||
|
||||
Component.onCompleted: {
|
||||
x = Screen.width/2 - width/2
|
||||
y = Screen.height/2 - height/2
|
||||
}
|
||||
|
||||
modality: Qt.ApplicationModal
|
||||
flags: Qt.Window
|
||||
|
||||
title: qsTr("Artemis - Space Weather")
|
||||
|
||||
function updateBottomBar(message) {
|
||||
spaceBottomBar.text = message
|
||||
}
|
||||
|
||||
|
||||
Page {
|
||||
anchors.fill: parent
|
||||
|
||||
footer: Label {
|
||||
id: spaceBottomBar
|
||||
font.pixelSize: 12
|
||||
leftPadding: 5
|
||||
rightPadding: 5
|
||||
bottomPadding: 5
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
TabBar {
|
||||
id: tabBar
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
|
||||
TabButton {
|
||||
text: qsTr("Current")
|
||||
}
|
||||
TabButton {
|
||||
text: qsTr("Forecasts")
|
||||
}
|
||||
}
|
||||
|
||||
StackLayout {
|
||||
currentIndex: tabBar.currentIndex
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
Item {
|
||||
SpaceWeatherCurrentPage {
|
||||
id: spaceWeatherCurrentPage
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
SpaceWeatherForecastPage {
|
||||
id: spaceWeatherForecastPage
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
400
ui/SpaceWeatherCurrentPage.qml
Normal file
400
ui/SpaceWeatherCurrentPage.qml
Normal file
@@ -0,0 +1,400 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
|
||||
import './components' as UIComponents
|
||||
|
||||
|
||||
Page {
|
||||
id: spaceWeatherCurrent
|
||||
anchors.fill: parent
|
||||
|
||||
objectName: "spaceWeatherCurrentObj"
|
||||
|
||||
property string g_now_text
|
||||
property string s_now_text
|
||||
property string r_now_text
|
||||
|
||||
function loadReport(poseidon_data) {
|
||||
setLight(lightG_now, 'G', poseidon_data['GSR_SCALES']['G_now'])
|
||||
setLight(lightS_now, 'S', poseidon_data['GSR_SCALES']['S_now'])
|
||||
setLight(lightR_now, 'R', poseidon_data['GSR_SCALES']['R_now'])
|
||||
|
||||
setLight(lightG_24h, 'G', poseidon_data['GSR_SCALES']['G_max24h'])
|
||||
setLight(lightS_24h, 'S', poseidon_data['GSR_SCALES']['S_max24h'])
|
||||
setLight(lightR_24h, 'R', poseidon_data['GSR_SCALES']['R_max24h'])
|
||||
|
||||
g_now_text = poseidon_data['GSR_SCALES']['G_now_text']
|
||||
s_now_text = poseidon_data['GSR_SCALES']['S_now_text']
|
||||
r_now_text = poseidon_data['GSR_SCALES']['R_now_text']
|
||||
|
||||
kIndexLightPanel.setLights(poseidon_data['AK']['k_index_round'])
|
||||
labelKIndex.text = 'Kp Index: ' + poseidon_data['AK']['k_index']
|
||||
|
||||
aIndexLightPanel.setLights(poseidon_data['AK']['a_index'])
|
||||
labelAIndex.text = 'A Index: ' + poseidon_data['AK']['a_index']
|
||||
|
||||
labelMux.text = poseidon_data['PROPAGATION']['MUX']
|
||||
labelEME.text = poseidon_data['PROPAGATION']['EME']
|
||||
labelMS.text = poseidon_data['PROPAGATION']['MS']
|
||||
labelHfNoise.text = poseidon_data['AK']['exp_noise']
|
||||
|
||||
labelPeakFluxClass.text = poseidon_data['XRAY']['peak_flux_class']
|
||||
labelPeakFluxClass3h.text = poseidon_data['XRAY']['peak_flux_class_3h']
|
||||
labelPeakFluxClass24h.text = poseidon_data['XRAY']['peak_flux_class_24h']
|
||||
}
|
||||
|
||||
function setLight(lightId, type, level) {
|
||||
lightId.text = type + level
|
||||
|
||||
if (level === 0) {
|
||||
|
||||
} else if (level === 1) {
|
||||
lightId.Material.background = Material.Green
|
||||
} else if (level === 2) {
|
||||
lightId.Material.background = Material.Amber
|
||||
} else if (level === 3) {
|
||||
lightId.Material.background = Material.Orange
|
||||
} else if (level === 4) {
|
||||
lightId.Material.background = Material.DeepOrange
|
||||
} else if (level === 5) {
|
||||
lightId.Material.background = Material.Red
|
||||
}
|
||||
}
|
||||
|
||||
DialogMessage {
|
||||
id: gsrDialog
|
||||
standardButtons: Dialog.Ok
|
||||
}
|
||||
|
||||
|
||||
Page {
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: 20
|
||||
anchors.leftMargin: 20
|
||||
anchors.bottomMargin: 20
|
||||
anchors.topMargin: 20
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillHeight: true
|
||||
Label {
|
||||
id: labelKIndex
|
||||
text: qsTr("Kp Index:")
|
||||
font.pointSize: 11
|
||||
font.capitalization: Font.SmallCaps
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
UIComponents.KIndexLight {
|
||||
id: kIndexLightPanel
|
||||
width: 250
|
||||
Layout.fillHeight: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
ColumnLayout {
|
||||
|
||||
Label {
|
||||
text: qsTr("NOAA SPACE WEATHER SCALE")
|
||||
font.letterSpacing: 0.5
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Frame {
|
||||
clip: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
GridLayout {
|
||||
anchors.fill: parent
|
||||
rows: 5
|
||||
columns: 3
|
||||
|
||||
Label {
|
||||
width: parent.width /3
|
||||
text: qsTr("Geomagnetic Storm")
|
||||
font.capitalization: Font.SmallCaps
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Solar Radiation Storms")
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
font.capitalization: Font.SmallCaps
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Radio Blackout")
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
font.capitalization: Font.SmallCaps
|
||||
}
|
||||
|
||||
Item {
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Current")
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
font.pointSize: 8
|
||||
}
|
||||
|
||||
Item {
|
||||
}
|
||||
|
||||
Button {
|
||||
id: lightG_now
|
||||
text: qsTr("G")
|
||||
font.pixelSize: 15
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
font.bold: true
|
||||
display: AbstractButton.TextOnly
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.text: qsTr("Click for details")
|
||||
onClicked: {
|
||||
gsrDialog.title = "Geomagnetic Storms"
|
||||
gsrDialog.message = g_now_text
|
||||
gsrDialog.open()
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: lightS_now
|
||||
text: qsTr("S")
|
||||
font.pixelSize: 15
|
||||
display: AbstractButton.TextOnly
|
||||
onClicked: {
|
||||
gsrDialog.title = "Solar Radiation Storms"
|
||||
gsrDialog.message = s_now_text
|
||||
gsrDialog.open()
|
||||
}
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
font.bold: true
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.text: qsTr("Click for details")
|
||||
}
|
||||
|
||||
Button {
|
||||
id: lightR_now
|
||||
text: qsTr("R")
|
||||
font.pixelSize: 15
|
||||
display: AbstractButton.TextOnly
|
||||
onClicked: {
|
||||
gsrDialog.title = "Radio Blackout"
|
||||
gsrDialog.message = r_now_text
|
||||
gsrDialog.open()
|
||||
}
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
font.bold: true
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.text: qsTr("Click for details")
|
||||
}
|
||||
|
||||
Item {
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("24h Maximums")
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
font.pointSize: 8
|
||||
}
|
||||
|
||||
Item {
|
||||
}
|
||||
|
||||
Button {
|
||||
id: lightG_24h
|
||||
text: qsTr("G")
|
||||
font.pixelSize: 15
|
||||
display: AbstractButton.TextOnly
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Button {
|
||||
id: lightS_24h
|
||||
text: qsTr("S")
|
||||
font.pixelSize: 15
|
||||
display: AbstractButton.TextOnly
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Button {
|
||||
id: lightR_24h
|
||||
text: qsTr("R")
|
||||
font.pixelSize: 15
|
||||
display: AbstractButton.TextOnly
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
font.bold: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||
|
||||
Label {
|
||||
text: qsTr("X-RAY SOLAR ACTIVITY")
|
||||
font.letterSpacing: 0.5
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Frame {
|
||||
clip: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
GridLayout {
|
||||
anchors.fill: parent
|
||||
columnSpacing: 15
|
||||
columns: 2
|
||||
rows: 2
|
||||
|
||||
Label {
|
||||
text: qsTr("Current Flux Class:")
|
||||
font.capitalization: Font.SmallCaps
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelPeakFluxClass
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
font.capitalization: Font.SmallCaps
|
||||
font.bold: true
|
||||
font.pointSize: 12
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Peak 3h Flux Class:")
|
||||
font.capitalization: Font.SmallCaps
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelPeakFluxClass3h
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
font.capitalization: Font.SmallCaps
|
||||
font.bold: true
|
||||
font.pointSize: 12
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Peak 24h Flux Class:")
|
||||
font.capitalization: Font.SmallCaps
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelPeakFluxClass24h
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
font.capitalization: Font.SmallCaps
|
||||
font.bold: true
|
||||
font.pointSize: 12
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||
|
||||
Label {
|
||||
text: qsTr("RF PROPAGATION")
|
||||
font.letterSpacing: 0.5
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Frame {
|
||||
clip: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
GridLayout {
|
||||
anchors.fill: parent
|
||||
columnSpacing: 15
|
||||
rows: 2
|
||||
columns: 2
|
||||
|
||||
Label {
|
||||
text: qsTr("MUX (MHz):")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelMux
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
font.capitalization: Font.SmallCaps
|
||||
font.bold: true
|
||||
font.pointSize: 12
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Earth-Moon-Earth:")
|
||||
font.capitalization: Font.SmallCaps
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEME
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
font.capitalization: Font.SmallCaps
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Meteor Scatter:")
|
||||
font.capitalization: Font.SmallCaps
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelMS
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
font.pointSize: 12
|
||||
font.capitalization: Font.SmallCaps
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Expected HF Noise:")
|
||||
font.capitalization: Font.SmallCaps
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelHfNoise
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
font.pointSize: 12
|
||||
font.capitalization: Font.SmallCaps
|
||||
font.bold: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Label {
|
||||
id: labelAIndex
|
||||
text: qsTr("A Index:")
|
||||
font.pointSize: 11
|
||||
font.capitalization: Font.SmallCaps
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
UIComponents.AIndexLight {
|
||||
id: aIndexLightPanel
|
||||
width: 250
|
||||
Layout.fillHeight: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
758
ui/SpaceWeatherForecastPage.qml
Normal file
758
ui/SpaceWeatherForecastPage.qml
Normal file
@@ -0,0 +1,758 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
|
||||
Page {
|
||||
id: spaceWeatherCurrent
|
||||
anchors.fill: parent
|
||||
|
||||
objectName: "spaceWeatherForecastObj"
|
||||
|
||||
function loadForecastReport(poseidon_data) {
|
||||
if (poseidon_data['FORCST']['SUMMARY']['G_REPORT'][0] === 1) {
|
||||
imageAttentionGReport.source = "qrc:/images/icons/dialog_warn.svg"
|
||||
} else {
|
||||
imageAttentionGReport.source = "qrc:/images/icons/dialog_info.svg"
|
||||
}
|
||||
labelGReport.text = poseidon_data['FORCST']['SUMMARY']['G_REPORT'][1]
|
||||
|
||||
if (poseidon_data['FORCST']['SUMMARY']['S_REPORT'][0] === 1) {
|
||||
imageAttentionSReport.source = "qrc:/images/icons/dialog_warn.svg"
|
||||
} else {
|
||||
imageAttentionSReport.source = "qrc:/images/icons/dialog_info.svg"
|
||||
}
|
||||
labelSReport.text = poseidon_data['FORCST']['SUMMARY']['S_REPORT'][1]
|
||||
|
||||
if (poseidon_data['FORCST']['SUMMARY']['R_REPORT'][0] === 1) {
|
||||
imageAttentionRReport.source = "qrc:/images/icons/dialog_warn.svg"
|
||||
} else {
|
||||
imageAttentionRReport.source = "qrc:/images/icons/dialog_info.svg"
|
||||
}
|
||||
labelRReport.text = poseidon_data['FORCST']['SUMMARY']['R_REPORT'][1]
|
||||
|
||||
labelDay1kp.text = poseidon_data['FORCST']['SUMMARY']['PRE_DATES'][0]
|
||||
labelDay2kp.text = poseidon_data['FORCST']['SUMMARY']['PRE_DATES'][1]
|
||||
labelDay3kp.text = poseidon_data['FORCST']['SUMMARY']['PRE_DATES'][2]
|
||||
|
||||
var timeRanges = ['00-03UT', '03-06UT', '06-09UT', '09-12UT', '12-15UT', '15-18UT', '18-21UT', '21-00UT']
|
||||
|
||||
for (var i = 0; i < timeRanges.length; i++) {
|
||||
var timeRange = timeRanges[i]
|
||||
for (var j = 0; j < 3; j++) {
|
||||
var index = j.toString()
|
||||
var labelName = 'labelKp' + (i).toString() + (j+1).toString()
|
||||
var labelText = poseidon_data['FORCST']['SUMMARY']['kp'][timeRange][j]['textual']
|
||||
var colorText = poseidon_data['FORCST']['SUMMARY']['kp'][timeRange][j]['color']
|
||||
|
||||
eval(labelName + '.text = labelText')
|
||||
if (colorText !== '') {
|
||||
eval(labelName + '.color = colorText')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
labelDay1Event.text = poseidon_data['FORCST']['PRE_DATES'][0]
|
||||
labelDay2Event.text = poseidon_data['FORCST']['PRE_DATES'][1]
|
||||
labelDay3Event.text = poseidon_data['FORCST']['PRE_DATES'][2]
|
||||
|
||||
labelEventS10.text = poseidon_data['FORCST']['SUMMARY']['S_PROB']['probS1'][0] + ' %'
|
||||
labelEventS11.text = poseidon_data['FORCST']['SUMMARY']['S_PROB']['probS1'][1] + ' %'
|
||||
labelEventS12.text = poseidon_data['FORCST']['SUMMARY']['S_PROB']['probS1'][2] + ' %'
|
||||
|
||||
labelEventMFlare0.text = poseidon_data['FORCST']['CLASS_M'][0] + ' %'
|
||||
labelEventMFlare1.text = poseidon_data['FORCST']['CLASS_M'][1] + ' %'
|
||||
labelEventMFlare2.text = poseidon_data['FORCST']['CLASS_M'][2] + ' %'
|
||||
|
||||
labelEventXFlare0.text = poseidon_data['FORCST']['CLASS_X'][0] + ' %'
|
||||
labelEventXFlare1.text = poseidon_data['FORCST']['CLASS_X'][1] + ' %'
|
||||
labelEventXFlare2.text = poseidon_data['FORCST']['CLASS_X'][2] + ' %'
|
||||
|
||||
labelEventPFlare0.text = poseidon_data['FORCST']['CLASS_PROTON'][0] + ' %'
|
||||
labelEventPFlare1.text = poseidon_data['FORCST']['CLASS_PROTON'][1] + ' %'
|
||||
labelEventPFlare2.text = poseidon_data['FORCST']['CLASS_PROTON'][2] + ' %'
|
||||
|
||||
labelEventR1R20.text = poseidon_data['FORCST']['SUMMARY']['R_PROB']['probR1'][0] + ' %'
|
||||
labelEventR1R21.text = poseidon_data['FORCST']['SUMMARY']['R_PROB']['probR1'][1] + ' %'
|
||||
labelEventR1R22.text = poseidon_data['FORCST']['SUMMARY']['R_PROB']['probR1'][2] + ' %'
|
||||
|
||||
labelEventR30.text = poseidon_data['FORCST']['SUMMARY']['R_PROB']['probR3'][0] + ' %'
|
||||
labelEventR31.text = poseidon_data['FORCST']['SUMMARY']['R_PROB']['probR3'][1] + ' %'
|
||||
labelEventR32.text = poseidon_data['FORCST']['SUMMARY']['R_PROB']['probR3'][2] + ' %'
|
||||
|
||||
var geoActiveM0 = poseidon_data['FORCST']['GEO_MID_ACTIVE'][0] + ' %'
|
||||
var geoActiveM1 = poseidon_data['FORCST']['GEO_MID_ACTIVE'][1] + ' %'
|
||||
var geoActiveM2 = poseidon_data['FORCST']['GEO_MID_ACTIVE'][2] + ' %'
|
||||
|
||||
var geoActiveH0 = poseidon_data['FORCST']['GEO_HIG_ACTIVE'][0] + ' %'
|
||||
var geoActiveH1 = poseidon_data['FORCST']['GEO_HIG_ACTIVE'][1] + ' %'
|
||||
var geoActiveH2 = poseidon_data['FORCST']['GEO_HIG_ACTIVE'][2] + ' %'
|
||||
|
||||
var geoMinorM0 = poseidon_data['FORCST']['GEO_MID_MINOR'][0] + ' %'
|
||||
var geoMinorM1 = poseidon_data['FORCST']['GEO_MID_MINOR'][1] + ' %'
|
||||
var geoMinorM2 = poseidon_data['FORCST']['GEO_MID_MINOR'][2] + ' %'
|
||||
|
||||
var geoMinorH0 = poseidon_data['FORCST']['GEO_HIG_MINOR'][0] + ' %'
|
||||
var geoMinorH1 = poseidon_data['FORCST']['GEO_HIG_MINOR'][1] + ' %'
|
||||
var geoMinorH2 = poseidon_data['FORCST']['GEO_HIG_MINOR'][2] + ' %'
|
||||
|
||||
var geoMajorM0 = poseidon_data['FORCST']['GEO_MID_MAJOR'][0] + ' %'
|
||||
var geoMajorM1 = poseidon_data['FORCST']['GEO_MID_MAJOR'][1] + ' %'
|
||||
var geoMajorM2 = poseidon_data['FORCST']['GEO_MID_MAJOR'][2] + ' %'
|
||||
|
||||
var geoMajorH0 = poseidon_data['FORCST']['GEO_HIG_MAJOR'][0] + ' %'
|
||||
var geoMajorH1 = poseidon_data['FORCST']['GEO_HIG_MAJOR'][1] + ' %'
|
||||
var geoMajorH2 = poseidon_data['FORCST']['GEO_HIG_MAJOR'][2] + ' %'
|
||||
|
||||
labelEventActive0.text = geoActiveM0 + ' / ' + geoActiveH0
|
||||
labelEventActive1.text = geoActiveM1 + ' / ' + geoActiveH1
|
||||
labelEventActive2.text = geoActiveM2 + ' / ' + geoActiveH2
|
||||
|
||||
labelEventMinor0.text = geoMinorM0 + ' / ' + geoMinorH0
|
||||
labelEventMinor1.text = geoMinorM1 + ' / ' + geoMinorH1
|
||||
labelEventMinor2.text = geoMinorM2 + ' / ' + geoMinorH2
|
||||
|
||||
labelEventMajor0.text = geoMajorM0 + ' / ' + geoMajorH0
|
||||
labelEventMajor1.text = geoMajorM1 + ' / ' + geoMajorH1
|
||||
labelEventMajor2.text = geoMajorM2 + ' / ' + geoMajorH2
|
||||
}
|
||||
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: 20
|
||||
anchors.leftMargin: 20
|
||||
anchors.bottomMargin: 20
|
||||
anchors.topMargin: 20
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
Label {
|
||||
text: qsTr("FORECAST SUMMARY")
|
||||
font.capitalization: Font.SmallCaps
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Frame {
|
||||
Layout.fillWidth: true
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 15
|
||||
|
||||
RowLayout {
|
||||
spacing: 20
|
||||
|
||||
Image {
|
||||
id: imageAttentionGReport
|
||||
sourceSize.height: 40
|
||||
sourceSize.width: 40
|
||||
fillMode: Image.PreserveAspectFit
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
Label {
|
||||
font.capitalization: Font.SmallCaps
|
||||
text: qsTr("Geomagnetic Activity")
|
||||
font.pointSize: 11
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelGReport
|
||||
wrapMode: Label.WordWrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 20
|
||||
|
||||
Image {
|
||||
id: imageAttentionSReport
|
||||
fillMode: Image.PreserveAspectFit
|
||||
sourceSize.height: 40
|
||||
sourceSize.width: 40
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillHeight: true
|
||||
Label {
|
||||
text: qsTr("Solar Radiation Storms")
|
||||
font.pointSize: 11
|
||||
font.capitalization: Font.SmallCaps
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelSReport
|
||||
wrapMode: Label.WordWrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 20
|
||||
|
||||
Image {
|
||||
id: imageAttentionRReport
|
||||
fillMode: Image.PreserveAspectFit
|
||||
sourceSize.height: 40
|
||||
sourceSize.width: 40
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillHeight: true
|
||||
|
||||
Label {
|
||||
text: qsTr("Radio Blackouts")
|
||||
font.pointSize: 11
|
||||
font.capitalization: Font.SmallCaps
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelRReport
|
||||
wrapMode: Label.WordWrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
Label {
|
||||
text: qsTr("3-DAY Kp INDEX")
|
||||
font.capitalization: Font.SmallCaps
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Frame {
|
||||
clip: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
GridLayout {
|
||||
anchors.fill: parent
|
||||
columnSpacing: 15
|
||||
rows: 9
|
||||
columns: 4
|
||||
|
||||
Label {
|
||||
text: qsTr("Time (UTC)")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelDay1kp
|
||||
text: qsTr("Day 1")
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelDay2kp
|
||||
text: qsTr("Day 2")
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelDay3kp
|
||||
text: qsTr("Day 3")
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("00-03")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp01
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp02
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp03
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("03-06")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp11
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp12
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp13
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("06-09")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp21
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp22
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp23
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("09-12")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp31
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp32
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp33
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("12-15")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp41
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp42
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp43
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("15-18")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp51
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp52
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp53
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("18-21")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp61
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp62
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp63
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("21-00")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp71
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp72
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelKp73
|
||||
Layout.leftMargin: labelDay1kp.width * 0.3
|
||||
font.pointSize: 12
|
||||
font.bold: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Label {
|
||||
text: qsTr("EVENTS PROBABILITY")
|
||||
font.capitalization: Font.SmallCaps
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Frame {
|
||||
Layout.fillWidth: true
|
||||
GridLayout {
|
||||
anchors.fill: parent
|
||||
rows: 9
|
||||
columnSpacing: 15
|
||||
columns: 4
|
||||
|
||||
Label {
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelDay1Event
|
||||
text: qsTr("Day 1")
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelDay2Event
|
||||
text: qsTr("Day 2")
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelDay3Event
|
||||
text: qsTr("Day 3")
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Solar Radiation Storm")
|
||||
font.capitalization: Font.SmallCaps
|
||||
font.bold: true
|
||||
Layout.columnSpan: 4
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("S1 or greater")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventS10
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventS11
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventS12
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Solar Flares")
|
||||
font.capitalization: Font.SmallCaps
|
||||
font.bold: true
|
||||
Layout.columnSpan: 4
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Class M flare")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventMFlare0
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventMFlare1
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventMFlare2
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Class X flare")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventXFlare0
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventXFlare1
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventXFlare2
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Proton flare")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventPFlare0
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventPFlare1
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventPFlare2
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
|
||||
Label {
|
||||
text: qsTr("Radio Blackout")
|
||||
font.capitalization: Font.SmallCaps
|
||||
font.bold: true
|
||||
Layout.columnSpan: 4
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("R1 - R2")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventR1R20
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventR1R21
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventR1R22
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("R3 or greater")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventR30
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventR31
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventR32
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Geomagnetic Activity")
|
||||
font.capitalization: Font.SmallCaps
|
||||
font.bold: true
|
||||
Layout.columnSpan: 4
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Active")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventActive0
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventActive1
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventActive2
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Minor")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventMinor0
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventMinor1
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventMinor2
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Major")
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventMajor0
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventMajor1
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: labelEventMajor2
|
||||
font.bold: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
}
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
140
ui/components/AIndexLight.qml
Normal file
140
ui/components/AIndexLight.qml
Normal file
@@ -0,0 +1,140 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
|
||||
|
||||
Item {
|
||||
|
||||
function setLights(aIndex) {
|
||||
resetLights()
|
||||
if (aIndex >= 0 && aIndex < 8) {
|
||||
rect0.color = "#539bff"
|
||||
} else if (aIndex >= 8 && aIndex < 16) {
|
||||
rect1.color = "#0ccf43"
|
||||
} else if (aIndex >= 16 && aIndex < 30) {
|
||||
rect2.color = "#f0e000"
|
||||
} else if (aIndex >= 30 && aIndex < 50) {
|
||||
rect3.color = "#ffb700"
|
||||
} else if (aIndex >= 50 && aIndex < 100) {
|
||||
rect4.color = "#ff7b00"
|
||||
} else if (aIndex >= 100) {
|
||||
rect5.color = "#e80000"
|
||||
}
|
||||
}
|
||||
|
||||
function resetLights() {
|
||||
rect0.color = "#2b4d7f"
|
||||
rect1.color = "#076823"
|
||||
rect2.color = "#797200"
|
||||
rect3.color = "#815f00"
|
||||
rect4.color = "#814100"
|
||||
rect5.color = "#750300"
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
|
||||
Rectangle {
|
||||
id: rect5
|
||||
color: "#750300"
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
topLeftRadius: 10
|
||||
topRightRadius: 10
|
||||
Label {
|
||||
text: qsTr("SEVERE STORM")
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: true
|
||||
font.pixelSize: parent.height*0.2
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rect4
|
||||
color: "#814100"
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
Label {
|
||||
text: qsTr("MAJOR STORM")
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: true
|
||||
font.pixelSize: parent.height*0.2
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rect3
|
||||
color: "#815f00"
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
Label {
|
||||
text: qsTr("MINOR STORM")
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: true
|
||||
font.pixelSize: parent.height*0.2
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rect2
|
||||
color: "#797200"
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
Label {
|
||||
text: qsTr("ACTIVE")
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: true
|
||||
font.pixelSize: parent.height*0.2
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rect1
|
||||
color: "#076823"
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
Label {
|
||||
text: qsTr("UNSETTLED")
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: true
|
||||
font.pixelSize: parent.height*0.2
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rect0
|
||||
color: "#2b4d7f"
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
bottomLeftRadius: 10
|
||||
bottomRightRadius: 10
|
||||
Label {
|
||||
text: qsTr("QUIET")
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: true
|
||||
font.pixelSize: parent.height*0.2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
156
ui/components/AudioPlayer.qml
Normal file
156
ui/components/AudioPlayer.qml
Normal file
@@ -0,0 +1,156 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtMultimedia
|
||||
|
||||
|
||||
Item {
|
||||
width: 200
|
||||
height: 80
|
||||
|
||||
property bool loop: false
|
||||
|
||||
function loadSound(audio_path) {
|
||||
player.stop()
|
||||
player.source = audio_path
|
||||
buttonPlay.icon.color = Material.accent
|
||||
buttonPlay.enabled = true
|
||||
buttonLoop.enabled = true
|
||||
}
|
||||
|
||||
function playSound() {
|
||||
buttonPlay.icon.color = Material.foreground
|
||||
buttonPause.icon.color = Material.accent
|
||||
buttonStop.icon.color = Material.accent
|
||||
buttonPlay.enabled = false
|
||||
buttonPause.enabled = true
|
||||
buttonStop.enabled = true
|
||||
buttonLoop.enabled = true
|
||||
playerPosition.enabled = player.seekable
|
||||
player.play()
|
||||
}
|
||||
|
||||
function pauseSound() {
|
||||
buttonPlay.icon.color = Material.accent
|
||||
buttonPause.icon.color = Material.foreground
|
||||
buttonPlay.enabled = true
|
||||
buttonPause.enabled = false
|
||||
player.pause()
|
||||
}
|
||||
|
||||
function stopSound() {
|
||||
buttonPlay.icon.color = Material.accent
|
||||
buttonPause.icon.color = Material.foreground
|
||||
buttonStop.icon.color = Material.foreground
|
||||
buttonLoop.icon.color = Material.foreground
|
||||
buttonPlay.enabled = true
|
||||
buttonPause.enabled = false
|
||||
buttonStop.enabled = false
|
||||
buttonLoop.enabled = false
|
||||
loop = false
|
||||
player.stop()
|
||||
}
|
||||
|
||||
function resetPlayer() {
|
||||
player.stop()
|
||||
player.source = ''
|
||||
loop = false
|
||||
buttonPlay.icon.color = Material.foreground
|
||||
buttonPause.icon.color = Material.foreground
|
||||
buttonStop.icon.color = Material.foreground
|
||||
buttonLoop.icon.color = Material.foreground
|
||||
buttonPlay.enabled = false
|
||||
buttonPause.enabled = false
|
||||
buttonStop.enabled = false
|
||||
buttonLoop.enabled = false
|
||||
playerPosition.enabled = false
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
|
||||
RoundButton {
|
||||
id: buttonPlay
|
||||
icon.color: Material.foreground
|
||||
icon.source: "qrc:/images/icons/player_play.svg"
|
||||
display: AbstractButton.IconOnly
|
||||
enabled: false
|
||||
flat: true
|
||||
onClicked: playSound()
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: buttonPause
|
||||
icon.color: Material.foreground
|
||||
icon.source: "qrc:/images/icons/player_pause.svg"
|
||||
display: AbstractButton.IconOnly
|
||||
enabled: false
|
||||
flat: true
|
||||
onClicked: pauseSound()
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: buttonStop
|
||||
icon.color: Material.foreground
|
||||
icon.source: "qrc:/images/icons/player_stop.svg"
|
||||
display: AbstractButton.IconOnly
|
||||
enabled: false
|
||||
flat: true
|
||||
onClicked: stopSound()
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: buttonLoop
|
||||
icon.color: Material.foreground
|
||||
icon.source: "qrc:/images/icons/player_loop.svg"
|
||||
display: AbstractButton.IconOnly
|
||||
enabled: false
|
||||
flat: true
|
||||
onClicked: {
|
||||
if (loop) {
|
||||
loop = false
|
||||
icon.color = Material.foreground
|
||||
} else {
|
||||
loop = true
|
||||
icon.color = Material.accent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Slider {
|
||||
id: playerPosition
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
Layout.preferredHeight: 20
|
||||
enabled: player.seekable
|
||||
value: player.duration > 0 ? player.position / player.duration : 0
|
||||
onMoved: {
|
||||
player.position = player.duration * playerPosition.position
|
||||
}
|
||||
}
|
||||
|
||||
MediaPlayer {
|
||||
id: player
|
||||
audioOutput: audioOutput
|
||||
|
||||
onPlaybackStateChanged: {
|
||||
if (player.playbackState === MediaPlayer.StoppedState) {
|
||||
if (loop) {
|
||||
playSound()
|
||||
} else {
|
||||
stopSound()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AudioOutput {
|
||||
id: audioOutput
|
||||
//volume: volumeSlider.value
|
||||
}
|
||||
}
|
||||
}
|
||||
261
ui/components/BandBar.qml
Normal file
261
ui/components/BandBar.qml
Normal file
@@ -0,0 +1,261 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
|
||||
Item {
|
||||
width: 400
|
||||
height: 20
|
||||
|
||||
function setBandBar(lof, upf) {
|
||||
resetBandBar()
|
||||
|
||||
if (lof < 30) {
|
||||
selector.anchors.left = rectangleELF.left
|
||||
} else if (lof >= 30 && lof < 300) {
|
||||
selector.anchors.left = rectangleSLF.left
|
||||
} else if (lof >= 300 && lof < 3000) {
|
||||
selector.anchors.left = rectangleULF.left
|
||||
} else if (lof >= 3000 && lof < 30000) {
|
||||
selector.anchors.left = rectangleVLF.left
|
||||
} else if (lof >= 30000 && lof < 300000) {
|
||||
selector.anchors.left = rectangleLF.left
|
||||
} else if (lof >= 300000 && lof < 3000000) {
|
||||
selector.anchors.left = rectangleMF.left
|
||||
} else if (lof >= 3000000 && lof < 30000000) {
|
||||
selector.anchors.left = rectangleHF.left
|
||||
} else if (lof >= 30000000 && lof < 300000000) {
|
||||
selector.anchors.left = rectangleVHF.left
|
||||
} else if (lof >= 300000000 && lof < 3000000000) {
|
||||
selector.anchors.left = rectangleUHF.left
|
||||
} else if (lof >= 3000000000 && lof < 30000000000) {
|
||||
selector.anchors.left = rectangleSHF.left
|
||||
} else if (lof >= 30000000000 && lof < 300000000000) {
|
||||
selector.anchors.left = rectangleEHF.left
|
||||
}
|
||||
|
||||
if (upf < 30) {
|
||||
selector.anchors.right = rectangleELF.right
|
||||
} else if (upf >= 30 && upf < 300) {
|
||||
selector.anchors.right = rectangleSLF.right
|
||||
} else if (upf >= 300 && upf < 3000) {
|
||||
selector.anchors.right = rectangleULF.right
|
||||
} else if (upf >= 3000 && upf < 30000) {
|
||||
selector.anchors.right = rectangleVLF.right
|
||||
} else if (upf >= 30000 && upf < 300000) {
|
||||
selector.anchors.right = rectangleLF.right
|
||||
} else if (upf >= 300000 && upf < 3000000) {
|
||||
selector.anchors.right = rectangleMF.right
|
||||
} else if (upf >= 3000000 && upf < 30000000) {
|
||||
selector.anchors.right = rectangleHF.right
|
||||
} else if (upf >= 30000000 && upf < 300000000) {
|
||||
selector.anchors.right = rectangleVHF.right
|
||||
} else if (upf >= 300000000 && upf < 3000000000) {
|
||||
selector.anchors.right = rectangleUHF.right
|
||||
} else if (upf >= 3000000000 && upf < 30000000000) {
|
||||
selector.anchors.right = rectangleSHF.right
|
||||
} else if (upf >= 30000000000 && upf < 300000000000) {
|
||||
selector.anchors.right = rectangleEHF.right
|
||||
}
|
||||
}
|
||||
|
||||
function resetBandBar() {
|
||||
selector.anchors.left = container.left
|
||||
selector.anchors.right = container.left
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: container
|
||||
radius: 13
|
||||
anchors.fill: parent
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Horizontal
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: "#1a000000"
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.5
|
||||
color: "#26000000"
|
||||
}
|
||||
GradientStop {
|
||||
position: 1
|
||||
color: "#1a000000"
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rectangleELF
|
||||
width: parent.width/11
|
||||
anchors.left: parent.left
|
||||
anchors.right: rectangleSLF.left
|
||||
height: 20
|
||||
color: "#00ffffff"
|
||||
Label {
|
||||
text: qsTr("ELF")
|
||||
font.bold: true
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rectangleSLF
|
||||
width: parent.width/11
|
||||
anchors.right: rectangleULF.left
|
||||
height: 20
|
||||
color: "#00ffffff"
|
||||
Label {
|
||||
text: qsTr("SLF")
|
||||
font.bold: true
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rectangleULF
|
||||
width: parent.width/11
|
||||
anchors.right: rectangleVLF.left
|
||||
height: 20
|
||||
color: "#00ffffff"
|
||||
Label {
|
||||
text: qsTr("ULF")
|
||||
font.bold: true
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rectangleVLF
|
||||
width: parent.width/11
|
||||
anchors.right: rectangleLF.left
|
||||
height: 20
|
||||
color: "#00ffffff"
|
||||
Label {
|
||||
text: qsTr("VLF")
|
||||
font.bold: true
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rectangleLF
|
||||
width: parent.width/11
|
||||
anchors.right: rectangleMF.left
|
||||
height: 20
|
||||
color: "#00ffffff"
|
||||
Label {
|
||||
text: qsTr("LF")
|
||||
font.bold: true
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rectangleMF
|
||||
width: parent.width/11
|
||||
anchors.right: rectangleHF.left
|
||||
height: 20
|
||||
color: "#00ffffff"
|
||||
Label {
|
||||
text: qsTr("MF")
|
||||
font.bold: true
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rectangleHF
|
||||
width: parent.width/11
|
||||
anchors.right: rectangleVHF.left
|
||||
height: 20
|
||||
color: "#00ffffff"
|
||||
Label {
|
||||
text: qsTr("HF")
|
||||
font.bold: true
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rectangleVHF
|
||||
width: parent.width/11
|
||||
anchors.right: rectangleUHF.left
|
||||
height: 20
|
||||
color: "#00ffffff"
|
||||
Label {
|
||||
text: qsTr("VHF")
|
||||
font.bold: true
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rectangleUHF
|
||||
width: parent.width/11
|
||||
anchors.right: rectangleSHF.left
|
||||
height: 20
|
||||
color: "#00ffffff"
|
||||
Label {
|
||||
text: qsTr("UHF")
|
||||
font.bold: true
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rectangleSHF
|
||||
width: parent.width/11
|
||||
anchors.right: rectangleEHF.left
|
||||
height: 20
|
||||
color: "#00ffffff"
|
||||
Label {
|
||||
text: qsTr("SHF")
|
||||
font.bold: true
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rectangleEHF
|
||||
width: parent.width/11
|
||||
anchors.right: parent.right
|
||||
height: 20
|
||||
color: "#00ffffff"
|
||||
Label {
|
||||
text: qsTr("EHF")
|
||||
font.bold: true
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: selector
|
||||
height: 20
|
||||
color: Material.accent
|
||||
radius: 10
|
||||
z: -1
|
||||
}
|
||||
}
|
||||
}
|
||||
216
ui/components/KIndexLight.qml
Normal file
216
ui/components/KIndexLight.qml
Normal file
@@ -0,0 +1,216 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
|
||||
|
||||
Item {
|
||||
|
||||
function setLights(kIndex) {
|
||||
resetLights()
|
||||
if (kIndex === 0) {
|
||||
rect0.color = "#539bff"
|
||||
} else if (kIndex === 1) {
|
||||
rect1.color = "#0ccf43"
|
||||
} else if (kIndex === 2) {
|
||||
rect2.color = "#0ccf43"
|
||||
} else if (kIndex === 3) {
|
||||
rect3.color = "#f0e000"
|
||||
} else if (kIndex === 4) {
|
||||
rect4.color = "#f0e000"
|
||||
} else if (kIndex === 5) {
|
||||
rect5.color = "#ffb700"
|
||||
} else if (kIndex === 6) {
|
||||
rect6.color = "#ff7b00"
|
||||
} else if (kIndex === 7) {
|
||||
rect7.color = "#e80000"
|
||||
} else if (kIndex === 8) {
|
||||
rect8.color = "#e80000"
|
||||
} else if (kIndex === 9) {
|
||||
rect9.color = "#e80000"
|
||||
}
|
||||
}
|
||||
|
||||
function resetLights() {
|
||||
rect0.color = "#2b4d7f"
|
||||
rect1.color = "#076823"
|
||||
rect2.color = "#076823"
|
||||
rect3.color = "#797200"
|
||||
rect4.color = "#797200"
|
||||
rect5.color = "#815f00"
|
||||
rect6.color = "#814100"
|
||||
rect7.color = "#750300"
|
||||
rect8.color = "#750300"
|
||||
rect9.color = "#750300"
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
|
||||
Rectangle {
|
||||
id: rect9
|
||||
color: "#750300"
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
topLeftRadius: 10
|
||||
topRightRadius: 10
|
||||
Label {
|
||||
text: qsTr("SUPER STORM")
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: true
|
||||
font.pixelSize: parent.height*0.3
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rect8
|
||||
color: "#750300"
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
Label {
|
||||
text: qsTr("EXTREME STORM")
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: true
|
||||
font.pixelSize: parent.height*0.3
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rect7
|
||||
color: "#750300"
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
Label {
|
||||
text: qsTr("SEVERE STORM")
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: true
|
||||
font.pixelSize: parent.height*0.3
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rect6
|
||||
color: "#814100"
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
Label {
|
||||
text: qsTr("MAJOR STORM")
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: true
|
||||
font.pixelSize: parent.height*0.3
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rect5
|
||||
color: "#815f00"
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
Label {
|
||||
text: qsTr("MINOR STORM")
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: true
|
||||
font.pixelSize: parent.height*0.3
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rect4
|
||||
color: "#797200"
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
Label {
|
||||
text: qsTr("ACTIVE")
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: true
|
||||
font.pixelSize: parent.height*0.3
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rect3
|
||||
color: "#797200"
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
Label {
|
||||
text: qsTr("UNSETTLED")
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: true
|
||||
font.pixelSize: parent.height*0.3
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rect2
|
||||
color: "#076823"
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
Label {
|
||||
text: qsTr("QUIET")
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: true
|
||||
font.pixelSize: parent.height*0.3
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rect1
|
||||
color: "#076823"
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
Label {
|
||||
text: qsTr("VERY QUIET")
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: true
|
||||
font.pixelSize: parent.height*0.3
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rect0
|
||||
color: "#2b4d7f"
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
clip: true
|
||||
bottomLeftRadius: 10
|
||||
bottomRightRadius: 10
|
||||
Label {
|
||||
text: qsTr("INACTIVE")
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: true
|
||||
font.pixelSize: parent.height*0.3
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user