mirror of
https://github.com/johndoe6345789/tustu.git
synced 2026-04-24 13:45:00 +00:00
- Implemented OfflineActivationDialog.qml for offline activation process with detailed instructions and file handling. - Created RegistrationDialog.qml for user registration with manual input and email parsing options. - Added new components: RoundGauge.qml, ScalarEditor.qml, Table2DEditor.qml, Table3DEditor.qml, TableEditorPanel.qml, and TableEditorView.qml for enhanced table editing features. - Updated main.py to include clipboard operations and file handling for saving/loading activation requests and codes. - Enhanced README.md to document new features and file structure.
279 lines
9.3 KiB
QML
279 lines
9.3 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
import QtQuick.Dialogs
|
|
|
|
ApplicationWindow {
|
|
id: offlineActivationDialog
|
|
width: 650
|
|
height: 700
|
|
minimumWidth: 600
|
|
minimumHeight: 650
|
|
title: "Offline Activate TunerStudio MS"
|
|
color: "#f5f5f5"
|
|
|
|
// Signals
|
|
signal activationComplete(string activationCode)
|
|
signal activationCancelled()
|
|
|
|
// Properties
|
|
property string productName: "TunerStudio MS"
|
|
property string activationRequest: ""
|
|
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
anchors.margins: 15
|
|
spacing: 15
|
|
|
|
// Main panel
|
|
GroupBox {
|
|
Layout.fillWidth: true
|
|
title: productName + " Offline Registration Activation"
|
|
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
spacing: 10
|
|
|
|
// Instructions
|
|
Label {
|
|
Layout.fillWidth: true
|
|
text: "<h2>5 Step Offline Activation</h2>" +
|
|
"<p><b>Step 1</b> - Save Activation Request to File ActivationRequest.txt on a USB drive or other medium.</p>" +
|
|
"<p><b>Step 2</b> - On a Computer that is connected to the Internet, open a web browser and go to<br>" +
|
|
" <font color=\"blue\"><u>https://www.efianalytics.com/activate</u></font></p>" +
|
|
"<p><b>Step 3</b> - Upload your saved ActivationRequest.txt, the site will provide you with ActivationCode.txt</p>" +
|
|
"<p><b>Step 4</b> - Return to TunerStudio and click Load Activation From File to load ActivationCode.txt into TunerStudio</p>" +
|
|
"<p><b>Step 5</b> - Click Accept</p>" +
|
|
"<p><b>Done!</b></p>"
|
|
wrapMode: Text.WordWrap
|
|
textFormat: Text.RichText
|
|
onLinkActivated: Qt.openUrlExternally(link)
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
acceptedButtons: Qt.NoButton
|
|
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Activation Request section
|
|
GroupBox {
|
|
Layout.fillWidth: true
|
|
title: "Activation Request"
|
|
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
spacing: 10
|
|
|
|
ScrollView {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: 120
|
|
Layout.minimumHeight: 60
|
|
|
|
TextArea {
|
|
id: requestTextArea
|
|
text: activationRequest
|
|
readOnly: true
|
|
selectByMouse: true
|
|
wrapMode: TextEdit.Wrap
|
|
background: Rectangle {
|
|
color: "#d3d3d3"
|
|
border.color: "#999"
|
|
border.width: 1
|
|
radius: 3
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
selectAll()
|
|
}
|
|
}
|
|
}
|
|
|
|
RowLayout {
|
|
Layout.alignment: Qt.AlignRight
|
|
spacing: 10
|
|
|
|
Label {
|
|
text: "Step 1 -->"
|
|
font.bold: true
|
|
}
|
|
|
|
Button {
|
|
text: "Save Request to File"
|
|
onClicked: saveRequestDialog.open()
|
|
}
|
|
|
|
Button {
|
|
text: "Copy Request to Clipboard"
|
|
onClicked: {
|
|
clipboardHelper.setClipboardText(requestTextArea.text)
|
|
statusLabel.text = "✓ Copied to clipboard"
|
|
statusTimer.start()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Server Activation Code section
|
|
GroupBox {
|
|
Layout.fillWidth: true
|
|
title: "Server Activation Code"
|
|
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
spacing: 10
|
|
|
|
ScrollView {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: 120
|
|
Layout.minimumHeight: 60
|
|
|
|
TextArea {
|
|
id: activationCodeArea
|
|
placeholderText: "Paste or load activation code here..."
|
|
selectByMouse: true
|
|
wrapMode: TextEdit.Wrap
|
|
background: Rectangle {
|
|
color: "white"
|
|
border.color: "#ccc"
|
|
border.width: 1
|
|
radius: 3
|
|
}
|
|
|
|
onTextChanged: {
|
|
acceptButton.enabled = text.trim().length > 0
|
|
}
|
|
}
|
|
}
|
|
|
|
RowLayout {
|
|
Layout.alignment: Qt.AlignRight
|
|
spacing: 10
|
|
|
|
Label {
|
|
text: "Step 4 -->"
|
|
font.bold: true
|
|
}
|
|
|
|
Button {
|
|
text: "Load Activation From File"
|
|
onClicked: loadActivationDialog.open()
|
|
}
|
|
|
|
Button {
|
|
text: "Paste Activation Code"
|
|
onClicked: {
|
|
activationCodeArea.text = clipboardHelper.getClipboardText()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Status label
|
|
Label {
|
|
id: statusLabel
|
|
Layout.fillWidth: true
|
|
Layout.alignment: Qt.AlignHCenter
|
|
color: "#4CAF50"
|
|
font.bold: true
|
|
visible: text.length > 0
|
|
}
|
|
|
|
Timer {
|
|
id: statusTimer
|
|
interval: 3000
|
|
onTriggered: statusLabel.text = ""
|
|
}
|
|
|
|
Item {
|
|
Layout.fillHeight: true
|
|
}
|
|
|
|
// Bottom buttons
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
Layout.alignment: Qt.AlignRight
|
|
spacing: 10
|
|
|
|
Label {
|
|
text: "Step 5 -->"
|
|
font.bold: true
|
|
}
|
|
|
|
Button {
|
|
id: acceptButton
|
|
text: "Accept"
|
|
enabled: false
|
|
highlighted: true
|
|
onClicked: {
|
|
if (activationCodeArea.text.trim().length > 0) {
|
|
activationComplete(activationCodeArea.text.trim())
|
|
offlineActivationDialog.close()
|
|
}
|
|
}
|
|
}
|
|
|
|
Button {
|
|
text: "Cancel"
|
|
onClicked: {
|
|
activationCancelled()
|
|
offlineActivationDialog.close()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// File dialogs
|
|
FileDialog {
|
|
id: saveRequestDialog
|
|
fileMode: FileDialog.SaveFile
|
|
defaultSuffix: "txt"
|
|
nameFilters: ["Text files (*.txt)", "All files (*)"]
|
|
currentFolder: "file:///" + clipboardHelper.getHomeDirectory()
|
|
|
|
onAccepted: {
|
|
clipboardHelper.saveTextToFile(selectedFile.toString(), requestTextArea.text)
|
|
statusLabel.text = "✓ Saved to file"
|
|
statusTimer.start()
|
|
}
|
|
}
|
|
|
|
FileDialog {
|
|
id: loadActivationDialog
|
|
fileMode: FileDialog.OpenFile
|
|
nameFilters: ["Text files (*.txt)", "All files (*)"]
|
|
currentFolder: "file:///" + clipboardHelper.getHomeDirectory()
|
|
|
|
onAccepted: {
|
|
var content = clipboardHelper.loadTextFromFile(selectedFile.toString())
|
|
if (content) {
|
|
activationCodeArea.text = content
|
|
statusLabel.text = "✓ Loaded from file"
|
|
statusTimer.start()
|
|
}
|
|
}
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
// Generate mock activation request on load
|
|
generateMockActivationRequest()
|
|
}
|
|
|
|
function generateMockActivationRequest() {
|
|
var timestamp = new Date().toISOString()
|
|
activationRequest = "=== ACTIVATION REQUEST ===\n" +
|
|
"Product: " + productName + "\n" +
|
|
"Computer ID: ABC123XYZ789\n" +
|
|
"Timestamp: " + timestamp + "\n" +
|
|
"Request Code: 1A2B3C4D5E6F7G8H\n" +
|
|
"=========================\n" +
|
|
"Please submit this to:\n" +
|
|
"https://www.efianalytics.com/activate"
|
|
requestTextArea.text = activationRequest
|
|
}
|
|
}
|