oficina / sheets Public

Clone
git clone https://amadan.net/oficina/sheets

Plain git — no account needed to clone.

Download

Download this file

1#if os(macOS)
2import AppKit
3import SwiftUI
4
5public struct SheetsEditorCommands: Commands {
6 @FocusedValue(\.sheetEditor) private var editor
7 public init() {}
8 private var available: Bool { editor?.model.page != nil }
9 private var writable: Bool {
10 guard let model = editor?.model else { return false }
11 return model.mayWrite && !model.busy && !model.hasUnconfirmedChanges
12 }
13 private func route(_ selector: Selector, grid: (SheetModel) -> Void) {
14 if NSApp.keyWindow?.firstResponder is NSTextView {
15 NSApp.sendAction(selector, to: nil, from: nil)
16 } else if let model = editor?.model, model.gridFocused { grid(model) }
17 else { NSApp.sendAction(selector, to: nil, from: nil) }
18 }
19 public var body: some Commands {
20
21 CommandGroup(replacing: .undoRedo) {
22 Button(sheetsMacString("Undo")) { route(Selector(("undo:"))) { model in Task { await model.command("/undo") } } }.keyboardShortcut("z")
23 Button(sheetsMacString("Redo")) { NSApp.sendAction(Selector(("redo:")), to: nil, from: nil) }.keyboardShortcut("z", modifiers: [.command, .shift])
24 }
25 CommandGroup(replacing: .pasteboard) {
26 Button(sheetsMacString("Cut")) { route(#selector(NSText.cut(_:))) { model in
27 guard model.mayWrite, !model.busy, !model.hasUnconfirmedChanges else { return }
28 model.copy(); Task { await model.clear() }
29 } }.keyboardShortcut("x")
30 Button(sheetsMacString("Copy")) { route(#selector(NSText.copy(_:))) { $0.copy() } }.keyboardShortcut("c")
31 Button(sheetsMacString("Paste")) { route(#selector(NSText.paste(_:))) { model in Task { await model.paste() } } }.keyboardShortcut("v")
32 Button(sheetsMacString("Select all")) { route(#selector(NSText.selectAll(_:))) { model in
33 model.rangeText = "A1:" + Coordinate(r: model.rows - 1, c: model.cols - 1).ref
34 model.selectRange()
35 } }.keyboardShortcut("a")
36 }
37 CommandGroup(after: .pasteboard) {
38 Button(sheetsMacString("Clear contents")) { if let model = editor?.model { Task { await model.clear() } } }.disabled(!writable)
39 Button(sheetsMacString("Fill down")) { if let model = editor?.model { Task { await model.fill(down: true) } } }.keyboardShortcut("d").disabled(!writable)
40 Button(sheetsMacString("Fill right")) { if let model = editor?.model { Task { await model.fill(down: false) } } }.disabled(!writable)
41 }
42 CommandMenu(sheetsMacString("Format")) {
43 if let model = editor?.model {
44 SheetFormatMenu(model: model)
45 Button(sheetsMacString("Row and column sizes…")) { editor?.panel.wrappedValue = "Sizes" }.disabled(!writable)
46 Button(sheetsMacString("Fit column to contents")) { Task { await model.fitColumn(model.selection.start.c) } }.disabled(!writable)
47 }
48 }
49 CommandMenu(sheetsMacString("Insert")) {
50 ForEach(["SUM", "AVERAGE", "COUNT", "MIN", "MAX"], id: \.self) { name in
51 Button(name) { if let model = editor?.model { Task { await model.insertFunction(name) } } }.disabled(!writable)
52 }
53 }
54 CommandMenu(sheetsMacString("Sheet")) {
55 Button(sheetsMacString("Sort and filter…")) { editor?.panel.wrappedValue = "Data" }.disabled(!available)
56 Button(sheetsMacString("Comments…")) { editor?.panel.wrappedValue = "Comments" }.disabled(!available)
57 Button(sheetsMacString("Refresh")) { if let model = editor?.model { Task { await model.refresh() } } }.disabled(!available)
58 }
59 }
60}
61#endif
62