diff --git a/app/qml/ApplicationSettings.qml b/app/qml/ApplicationSettings.qml index 4bcd5af..1d9cde1 100644 --- a/app/qml/ApplicationSettings.qml +++ b/app/qml/ApplicationSettings.qml @@ -356,8 +356,7 @@ QtObject{ loadProfileString(profile.obj_string); } - function addNewCustomProfile(name){ - var profileString = composeProfileString(); + function appendCustomProfile(name, profileString) { profilesList.append({text: name, obj_string: profileString, builtin: false}); } diff --git a/app/qml/InsertNameDialog.qml b/app/qml/InsertNameDialog.qml index 99c5c52..535c8f4 100644 --- a/app/qml/InsertNameDialog.qml +++ b/app/qml/InsertNameDialog.qml @@ -31,6 +31,7 @@ Window{ modality: Qt.ApplicationModal title: qsTr("Save new profile") + property alias profileName: namefield.text signal nameSelected(string name) MessageDialog { diff --git a/app/qml/SettingsEffectsTab.qml b/app/qml/SettingsEffectsTab.qml index ba8bf6c..e88998d 100644 --- a/app/qml/SettingsEffectsTab.qml +++ b/app/qml/SettingsEffectsTab.qml @@ -28,6 +28,7 @@ Tab{ anchors.fill: parent ColumnLayout{ anchors.fill: parent + spacing: 2 CheckableSlider{ name: qsTr("Bloom") onNewValue: appSettings.bloom = newValue diff --git a/app/qml/SettingsGeneralTab.qml b/app/qml/SettingsGeneralTab.qml index cc56de9..66b9721 100644 --- a/app/qml/SettingsGeneralTab.qml +++ b/app/qml/SettingsGeneralTab.qml @@ -51,6 +51,14 @@ Tab{ ColumnLayout { anchors { top: parent.top; bottom: parent.bottom } Layout.fillWidth: false + Button{ + Layout.fillWidth: true + text: qsTr("New") + onClicked: { + insertname.profileName = ""; + insertname.show() + } + } Button{ Layout.fillWidth: true property alias currentIndex: profilesView.currentRow @@ -62,11 +70,6 @@ Tab{ appSettings.loadProfile(index); } } - Button{ - Layout.fillWidth: true - text: qsTr("New") - onClicked: insertname.show() - } Button{ Layout.fillWidth: true text: qsTr("Remove") @@ -74,11 +77,12 @@ Tab{ enabled: currentIndex >= 0 && !appSettings.profilesList.get(currentIndex).builtin onClicked: { - appSettings.profilesList.remove(profilesView.currentRow); - profilesView.activated(currentIndex); + appSettings.profilesList.remove(currentIndex); + currentIndex = -1; // Unselect the profile. } } Button{ + Layout.fillWidth: true text: qsTr("Import") onClicked: { fileDialog.selectExisting = true; @@ -86,105 +90,103 @@ Tab{ fileDialog.open(); } function loadFile(url) { - if (true) - console.log("Loading file: " + url); - var profileStirng = fileIO.read(url); - appSettings.loadProfileString(profileStirng); + try { + if (appSettings.verbose) + console.log("Loading file: " + url); + + var profileObject = JSON.parse(fileIO.read(url)); + var name = profileObject.name; + + if (!name) + throw "Profile doesn't have a name"; + + delete profileObject.name; + + appSettings.appendCustomProfile(name, JSON.stringify(profileObject)); + } catch (err) { + console.log(err); + messageDialog.text = qsTr("There has been an error reading the file.") + messageDialog.open(); + } } } Button{ + property alias currentIndex: profilesView.currentRow + + Layout.fillWidth: true + text: qsTr("Export") + enabled: currentIndex >= 0 && !appSettings.profilesList.get(currentIndex).builtin onClicked: { fileDialog.selectExisting = false; fileDialog.callBack = function (url) {storeFile(url);}; fileDialog.open(); } function storeFile(url) { - if (true) - console.log("Storing file: " + url); - var profileObject = appSettings.composeProfileObject(); - fileIO.write(url, JSON.stringify(profileObject, undefined, 2)); - } - } - InsertNameDialog{ - id: insertname - onNameSelected: appSettings.addNewCustomProfile(name) - } - Loader { - property var callBack - property bool selectExisting: false - id: fileDialog + try { + var urlString = url.toString(); - sourceComponent: FileDialog{ - nameFilters: ["Json files (*.json)"] - selectMultiple: false - selectFolder: false - selectExisting: fileDialog.selectExisting - onAccepted: callBack(fileUrl); - } + // Fix the extension if it's missing. + var extension = urlString.substring(urlString.length - 5, urlString.length); + var urlTail = (extension === ".json" ? "" : ".json"); + url += urlTail; - onSelectExistingChanged: reload() + if (true) + console.log("Storing file: " + url); - function open() { - item.open(); - } + var profileObject = appSettings.profilesList.get(currentIndex); + var profileSettings = JSON.parse(profileObject.obj_string); + profileSettings["name"] = profileObject.text; - function reload() { - active = false; - active = true; + var result = fileIO.write(url, JSON.stringify(profileSettings, undefined, 2)); + if (!result) + throw "The file could not be written."; + } catch (err) { + console.log(err); + messageDialog.text = qsTr("There has been an error storing the file.") + messageDialog.open(); + } } } } } } - GroupBox{ - title: qsTr("Lights") - Layout.fillWidth: true - GridLayout{ - anchors.fill: parent - columns: 2 - Text{ text: qsTr("Brightness") } - SimpleSlider{ - onValueChanged: appSettings.brightness = value - value: appSettings.brightness - } - Text{ text: qsTr("Contrast") } - SimpleSlider{ - onValueChanged: appSettings.contrast = value - value: appSettings.contrast - } - Text{ text: qsTr("Opacity") } - SimpleSlider{ - onValueChanged: appSettings.windowOpacity = value - value: appSettings.windowOpacity - } + // DIALOGS //////////////////////////////////////////////////////////////// + InsertNameDialog{ + id: insertname + onNameSelected: { + appSettings.appendCustomProfile(name, appSettings.composeProfileString()); } } - GroupBox{ - title: qsTr("Frame") - Layout.fillWidth: true - RowLayout{ - anchors.fill: parent - ComboBox{ - id: framescombobox - Layout.fillWidth: true - model: appSettings.framesList - currentIndex: appSettings.framesIndex - onActivated: { - appSettings.frameName = appSettings.framesList.get(index).name; - } - function updateIndex(){ - var name = appSettings.frameName; - var index = appSettings.getFrameIndexByName(name); - if (index !== undefined) - currentIndex = index; - } - Component.onCompleted: updateIndex(); - Connections { - target: appSettings - onFrameNameChanged: framescombobox.updateIndex(); - } - } + MessageDialog { + id: messageDialog + title: qsTr("File Error") + onAccepted: { + messageDialog.close(); + } + } + Loader { + property var callBack + property bool selectExisting: false + id: fileDialog + + sourceComponent: FileDialog{ + nameFilters: ["Json files (*.json)"] + selectMultiple: false + selectFolder: false + selectExisting: fileDialog.selectExisting + onAccepted: callBack(fileUrl); + } + + onSelectExistingChanged: reload() + + function open() { + item.open(); + } + + function reload() { + active = false; + active = true; } } } diff --git a/app/qml/SettingsScreenTab.qml b/app/qml/SettingsScreenTab.qml new file mode 100644 index 0000000..7374624 --- /dev/null +++ b/app/qml/SettingsScreenTab.qml @@ -0,0 +1,94 @@ +/******************************************************************************* +* Copyright (c) 2013 "Filippo Scognamiglio" +* https://github.com/Swordfish90/cool-retro-term +* +* This file is part of cool-retro-term. +* +* cool-retro-term is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*******************************************************************************/ + +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import QtQuick.Dialogs 1.1 + +Tab{ + ColumnLayout{ + anchors.fill: parent + GroupBox{ + title: qsTr("Rasterization Mode") + Layout.fillWidth: true + ComboBox { + id: rasterizationBox + property string selectedElement: model[currentIndex] + anchors.fill: parent + model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels")] + currentIndex: appSettings.rasterization + onCurrentIndexChanged: { + appSettings.rasterization = currentIndex + } + } + } + GroupBox{ + title: qsTr("Lights") + Layout.fillWidth: true + GridLayout{ + anchors.fill: parent + columns: 2 + Text{ text: qsTr("Brightness") } + SimpleSlider{ + onValueChanged: appSettings.brightness = value + value: appSettings.brightness + } + Text{ text: qsTr("Contrast") } + SimpleSlider{ + onValueChanged: appSettings.contrast = value + value: appSettings.contrast + } + Text{ text: qsTr("Opacity") } + SimpleSlider{ + onValueChanged: appSettings.windowOpacity = value + value: appSettings.windowOpacity + } + } + } + GroupBox{ + title: qsTr("Frame") + Layout.fillWidth: true + RowLayout{ + anchors.fill: parent + ComboBox{ + id: framescombobox + Layout.fillWidth: true + model: appSettings.framesList + currentIndex: appSettings.framesIndex + onActivated: { + appSettings.frameName = appSettings.framesList.get(index).name; + } + function updateIndex(){ + var name = appSettings.frameName; + var index = appSettings.getFrameIndexByName(name); + if (index !== undefined) + currentIndex = index; + } + Component.onCompleted: updateIndex(); + Connections { + target: appSettings + onFrameNameChanged: framescombobox.updateIndex(); + } + } + } + } + } +} diff --git a/app/qml/SettingsTerminalTab.qml b/app/qml/SettingsTerminalTab.qml index 578e590..e3649cd 100644 --- a/app/qml/SettingsTerminalTab.qml +++ b/app/qml/SettingsTerminalTab.qml @@ -26,21 +26,8 @@ Tab{ ColumnLayout{ anchors.fill: parent GroupBox{ - title: qsTr("Rasterization Mode") - Layout.fillWidth: true - ComboBox { - id: rasterizationBox - property string selectedElement: model[currentIndex] - anchors.fill: parent - model: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels")] - currentIndex: appSettings.rasterization - onCurrentIndexChanged: { - appSettings.rasterization = currentIndex - } - } - } - GroupBox{ - title: qsTr("Font") + " (" + rasterizationBox.selectedElement + ")" + property var rasterization: [qsTr("Default"), qsTr("Scanlines"), qsTr("Pixels")][appSettings.rasterization] + title: qsTr("Font" + "(" + rasterization + ")") Layout.fillWidth: true GridLayout{ anchors.fill: parent diff --git a/app/qml/SettingsWindow.qml b/app/qml/SettingsWindow.qml index 7726402..9f4653f 100644 --- a/app/qml/SettingsWindow.qml +++ b/app/qml/SettingsWindow.qml @@ -42,6 +42,12 @@ Window { anchors.fill: parent anchors.margins: tabmargins } + SettingsScreenTab{ + id: screenTab + title: qsTr("Screen") + anchors.fill: parent + anchors.margins: tabmargins + } SettingsTerminalTab{ id: terminalTab title: qsTr("Terminal") diff --git a/app/qml/resources.qrc b/app/qml/resources.qrc index b521f67..2f76dfa 100644 --- a/app/qml/resources.qrc +++ b/app/qml/resources.qrc @@ -49,5 +49,6 @@ fonts/modern-hermit/Hermit-medium.otf fonts/modern-envy-code-r/Envy Code R.ttf fonts/modern-inconsolata/Inconsolata.otf + SettingsScreenTab.qml