Files
SQLWorkbench/WorkbenchReplacement/App.swift
T
2026-10-16 17:26:02 +01:00

300 lines
7.7 KiB
Swift

import SwiftUI
@main
struct WorkbenchReplacementApp: App {
@StateObject private var model = DatabaseModel()
var body: some Scene {
WindowGroup("Workbench Replacement") {
MainView()
.environmentObject(model)
.frame(minWidth: 1000, minHeight: 650)
}
.commands {
CommandGroup(replacing: .newItem) {}
}
Settings {
WorkbenchSettingsView()
}
}
}
// MARK: - Application Preferences
@MainActor
final class WorkbenchPreferences: ObservableObject {
static let shared = WorkbenchPreferences()
@AppStorage("preferences.editorFontSize")
var editorFontSize = 13.0
@AppStorage("preferences.uppercaseKeywords")
var uppercaseKeywords = true
@AppStorage("preferences.showLineNumbers")
var showLineNumbers = true
@AppStorage("preferences.tabWidth")
var tabWidth = 4
@AppStorage("preferences.resultRowHeight")
var resultRowHeight = 24.0
@AppStorage("preferences.resultColumnWidth")
var resultColumnWidth = 170.0
@AppStorage("preferences.alternatingRows")
var alternatingRows = true
@AppStorage("preferences.appearance")
var appearance = "light"
@AppStorage("preferences.autoExpandTables")
var autoExpandTables = true
}
// MARK: - Workbench Settings
struct WorkbenchSettingsView: View {
@AppStorage("preferences.editorFontSize")
private var editorFontSize = 13.0
@AppStorage("preferences.uppercaseKeywords")
private var uppercaseKeywords = true
@AppStorage("preferences.showLineNumbers")
private var showLineNumbers = true
@AppStorage("preferences.tabWidth")
private var tabWidth = 4
@AppStorage("preferences.defaultRowLimit")
private var defaultRowLimit = 500
@AppStorage("preferences.resultRowHeight")
private var resultRowHeight = 24.0
@AppStorage("preferences.resultColumnWidth")
private var resultColumnWidth = 170.0
@AppStorage("preferences.alternatingRows")
private var alternatingRows = true
@AppStorage("preferences.autoExpandTables")
private var autoExpandTables = true
var body: some View {
TabView {
editorSettings
.tabItem {
Label(
"SQL Editor",
systemImage: "chevron.left.forwardslash.chevron.right"
)
}
executionSettings
.tabItem {
Label(
"Query Execution",
systemImage: "bolt"
)
}
resultSettings
.tabItem {
Label(
"Result Grid",
systemImage: "tablecells"
)
}
generalSettings
.tabItem {
Label(
"General",
systemImage: "gearshape"
)
}
}
.frame(width: 620, height: 390)
.preferredColorScheme(.light)
}
private var editorSettings: some View {
settingsPage("SQL Editor") {
settingsRow("Font Size") {
Stepper(
"\(Int(editorFontSize)) pt",
value: $editorFontSize,
in: 10...24,
step: 1
)
.frame(width: 130)
}
settingsRow("Tab Width") {
Picker("", selection: $tabWidth) {
Text("2 spaces").tag(2)
Text("4 spaces").tag(4)
Text("8 spaces").tag(8)
}
.labelsHidden()
.frame(width: 150)
}
settingsRow("SQL Formatting") {
Toggle(
"Automatically uppercase SQL keywords",
isOn: $uppercaseKeywords
)
}
settingsRow("Editor Display") {
Toggle(
"Show line numbers",
isOn: $showLineNumbers
)
}
}
}
private var executionSettings: some View {
settingsPage("Query Execution") {
settingsRow("Default Row Limit") {
HStack(spacing: 12) {
TextField(
"",
value: $defaultRowLimit,
format: .number
)
.textFieldStyle(.roundedBorder)
.frame(width: 110)
Stepper(
"",
value: $defaultRowLimit,
in: 50...100000,
step: 50
)
.labelsHidden()
}
}
Text(
"Controls the number of rows retrieved when opening a table from the schema navigator."
)
.font(.system(size: 12))
.foregroundStyle(.secondary)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.leading, 190)
Divider()
.padding(.vertical, 12)
Text("Examples")
.font(.headline)
Text(
"500 rows: Faster browsing and lower memory usage.\n" +
"5,000 rows: Useful for larger datasets.\n" +
"50,000 rows: May take longer to retrieve."
)
.font(.system(size: 12))
.foregroundStyle(.secondary)
.frame(maxWidth: .infinity, alignment: .leading)
}
}
private var resultSettings: some View {
settingsPage("Result Grid") {
settingsRow("Row Height") {
Stepper(
"\(Int(resultRowHeight)) px",
value: $resultRowHeight,
in: 18...40,
step: 1
)
.frame(width: 130)
}
settingsRow("Column Width") {
Stepper(
"\(Int(resultColumnWidth)) px",
value: $resultColumnWidth,
in: 80...400,
step: 10
)
.frame(width: 140)
}
settingsRow("Appearance") {
Toggle(
"Alternating row colours",
isOn: $alternatingRows
)
}
}
}
private var generalSettings: some View {
settingsPage("General") {
settingsRow("Navigator") {
Toggle(
"Automatically expand table folders",
isOn: $autoExpandTables
)
}
}
}
private func settingsPage<Content: View>(
_ title: String,
@ViewBuilder content: () -> Content
) -> some View {
VStack(alignment: .leading, spacing: 18) {
Text(title)
.font(.system(size: 20, weight: .semibold))
Divider()
content()
Spacer(minLength: 0)
}
.padding(26)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color(nsColor: .windowBackgroundColor))
}
private func settingsRow<Content: View>(
_ title: String,
@ViewBuilder content: () -> Content
) -> some View {
HStack(alignment: .center, spacing: 16) {
Text(title)
.font(.system(size: 13))
.frame(width: 170, alignment: .trailing)
content()
Spacer(minLength: 0)
}
.frame(height: 30)
}
}