diff --git a/FranzCocoa.xcodeproj/project.pbxproj b/FranzCocoa.xcodeproj/project.pbxproj index 583d485..7bc194b 100644 --- a/FranzCocoa.xcodeproj/project.pbxproj +++ b/FranzCocoa.xcodeproj/project.pbxproj @@ -164,6 +164,10 @@ 43D3AEA828FFD96500D52E92 /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D3AEA728FFD96500D52E92 /* Defaults.swift */; }; 43D3AEAB28FFDF3500D52E92 /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D3AEA928FFDF3500D52E92 /* PreferencesWindowController.swift */; }; 43D3AEAC28FFDF3500D52E92 /* PreferencesWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 43D3AEAA28FFDF3500D52E92 /* PreferencesWindowController.xib */; }; + 43DF30722B0FC9AC00308269 /* JumpToLineWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DF30702B0FC9AC00308269 /* JumpToLineWindowController.swift */; }; + 43DF30732B0FC9AC00308269 /* JumpToLineWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DF30702B0FC9AC00308269 /* JumpToLineWindowController.swift */; }; + 43DF30742B0FC9AC00308269 /* JumpToLineWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 43DF30712B0FC9AC00308269 /* JumpToLineWindowController.xib */; }; + 43DF30752B0FC9AC00308269 /* JumpToLineWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 43DF30712B0FC9AC00308269 /* JumpToLineWindowController.xib */; }; 43E5AE8C291245E000C74966 /* DispatchQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43E5AE8B291245E000C74966 /* DispatchQueue.swift */; }; 43E64A082928F2BF00FDBF29 /* ScriptWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43E64A062928F2BF00FDBF29 /* ScriptWindowController.swift */; }; 43E64A092928F2BF00FDBF29 /* ScriptWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 43E64A072928F2BF00FDBF29 /* ScriptWindowController.xib */; }; @@ -263,6 +267,8 @@ 43D3AEA728FFD96500D52E92 /* Defaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Defaults.swift; sourceTree = ""; }; 43D3AEA928FFDF3500D52E92 /* PreferencesWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesWindowController.swift; sourceTree = ""; }; 43D3AEAA28FFDF3500D52E92 /* PreferencesWindowController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PreferencesWindowController.xib; sourceTree = ""; }; + 43DF30702B0FC9AC00308269 /* JumpToLineWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JumpToLineWindowController.swift; sourceTree = ""; }; + 43DF30712B0FC9AC00308269 /* JumpToLineWindowController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = JumpToLineWindowController.xib; sourceTree = ""; }; 43E5AE8B291245E000C74966 /* DispatchQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DispatchQueue.swift; sourceTree = ""; }; 43E64A062928F2BF00FDBF29 /* ScriptWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptWindowController.swift; sourceTree = ""; }; 43E64A072928F2BF00FDBF29 /* ScriptWindowController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ScriptWindowController.xib; sourceTree = ""; }; @@ -367,6 +373,8 @@ 43B8DCC729546B200056E9FD /* HexViewerViewController.xib */, 43D03DD728FB03940049D44D /* Identifiers.swift */, 433C5E8A29066310005F4C4B /* Infos.swift */, + 43DF30702B0FC9AC00308269 /* JumpToLineWindowController.swift */, + 43DF30712B0FC9AC00308269 /* JumpToLineWindowController.xib */, 43D03DD328FAC6030049D44D /* Keychain.swift */, 43CD621C28CE24B100095144 /* MainMenu.xib */, 431C698028F2E0C60082986A /* NewTopicFormViewController.swift */, @@ -579,6 +587,7 @@ 43CD621E28CE24B100095144 /* MainMenu.xib in Resources */, 43804AB928D1A026002880FE /* ConnectionTableCellView.xib in Resources */, 43B8DCC929546B200056E9FD /* HexViewerViewController.xib in Resources */, + 43DF30742B0FC9AC00308269 /* JumpToLineWindowController.xib in Resources */, 43D3AEAC28FFDF3500D52E92 /* PreferencesWindowController.xib in Resources */, 435EBE5629542E7C00DCFEBF /* DataViewController.xib in Resources */, 437A77E0290D5AA1001965B0 /* TopicRecordsTableViewController.xib in Resources */, @@ -613,6 +622,7 @@ 43CDBAF02AE411A0003063D7 /* MainMenu.xib in Resources */, 43CDBAF12AE411A0003063D7 /* ConnectionTableCellView.xib in Resources */, 43CDBAF22AE411A0003063D7 /* HexViewerViewController.xib in Resources */, + 43DF30752B0FC9AC00308269 /* JumpToLineWindowController.xib in Resources */, 43CDBAF32AE411A0003063D7 /* PreferencesWindowController.xib in Resources */, 43CDBAF42AE411A0003063D7 /* DataViewController.xib in Resources */, 43CDBAF52AE411A0003063D7 /* TopicRecordsTableViewController.xib in Resources */, @@ -759,6 +769,7 @@ 4396EAE12905B0D200A15D25 /* Tabs.swift in Sources */, 437A77DF290D5AA1001965B0 /* TopicRecordsTableViewController.swift in Sources */, 43CD623E28CE282400095144 /* WelcomeWindowContentViewController.swift in Sources */, + 43DF30722B0FC9AC00308269 /* JumpToLineWindowController.swift in Sources */, 4314EDF828D85E0E00431770 /* SidebarGroupCellView.swift in Sources */, 436E71FA28D7511400ECBF49 /* WorkspaceWindowController.swift in Sources */, 43D3AEA628FFD8D100D52E92 /* Pasteboard.swift in Sources */, @@ -816,6 +827,7 @@ 43CDBACE2AE411A0003063D7 /* Tabs.swift in Sources */, 43CDBACF2AE411A0003063D7 /* TopicRecordsTableViewController.swift in Sources */, 43CDBAD02AE411A0003063D7 /* WelcomeWindowContentViewController.swift in Sources */, + 43DF30732B0FC9AC00308269 /* JumpToLineWindowController.swift in Sources */, 43CDBAD12AE411A0003063D7 /* SidebarGroupCellView.swift in Sources */, 43CDBAD22AE411A0003063D7 /* WorkspaceWindowController.swift in Sources */, 43CDBAD32AE411A0003063D7 /* Pasteboard.swift in Sources */, diff --git a/FranzCocoa/Base.lproj/MainMenu.xib b/FranzCocoa/Base.lproj/MainMenu.xib index 568d6ac..164dfa8 100644 --- a/FranzCocoa/Base.lproj/MainMenu.xib +++ b/FranzCocoa/Base.lproj/MainMenu.xib @@ -410,6 +410,12 @@ DQ + + + + + + diff --git a/FranzCocoa/Editor.swift b/FranzCocoa/Editor.swift index 4e273a7..fd4ecb3 100644 --- a/FranzCocoa/Editor.swift +++ b/FranzCocoa/Editor.swift @@ -161,6 +161,33 @@ class EditorViewController: NSViewController { private func didChangeCode() { delegate?.codeDidChange(self) } + + @objc func jumpToLine(_ sender: Any) { + let ctl = WindowManager.shared.showJumpToLineWindow() + ctl.delegate = self + } +} + +// MARK: - JumpToLineWindowDelegate +extension EditorViewController: JumpToLineWindowDelegate { + func willJumpToLine(_ lineNumber: Int) -> Bool { + guard lineNumber > 0 else { return false } + let idx = lineNumber-1 + let lines = textView.string.split( + separator: "\n", + omittingEmptySubsequences: false + ) + if idx >= lines.count { + return false + } + var lo = 0 + for i in 0.. Bool +} + +// MARK: - NSTextFieldDelegate +extension JumpToLineWindowController: NSTextFieldDelegate { + func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool { + if commandSelector == #selector(cancelOperation(_:)) { + WindowManager.shared.closeJumpToLineWindow() + return true + } else if commandSelector == #selector(insertNewline(_:)) { + guard let delegate else { return false } + if delegate.willJumpToLine(textField.integerValue) { + WindowManager.shared.closeJumpToLineWindow() + return true + } + } + return false + } +} + +// MARK: - NSWindowDelegate +extension JumpToLineWindowController: NSWindowDelegate { + func windowDidResignKey(_ notification: Notification) { + WindowManager.shared.closeJumpToLineWindow() + } +} diff --git a/FranzCocoa/JumpToLineWindowController.xib b/FranzCocoa/JumpToLineWindowController.xib new file mode 100644 index 0000000..6869adc --- /dev/null +++ b/FranzCocoa/JumpToLineWindowController.xib @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FranzCocoa/WindowManager.swift b/FranzCocoa/WindowManager.swift index 866725b..522753c 100644 --- a/FranzCocoa/WindowManager.swift +++ b/FranzCocoa/WindowManager.swift @@ -10,6 +10,7 @@ class WindowManager { private var preferencesWindowController: PreferencesWindowController? private var updatesWindowController: UpdatesWindowController? private var updatesProgressWindowController: UpdatesProgressWindowController? + private var jumpToLineWindowController: JumpToLineWindowController? private var workspaces = [WorkspaceWindowController]() private var scripts = [ScriptWindowKey: ScriptWindowController]() // workspace id -> ctl private var secureURLs = [UVarint: [URL]]() // connection id -> URLs @@ -162,6 +163,26 @@ class WindowManager { frame.makeKeyAndOrderFront(nil) } + func showJumpToLineWindow() -> JumpToLineWindowController { + if jumpToLineWindowController == nil { + jumpToLineWindowController = JumpToLineWindowController() + } + let ctl = jumpToLineWindowController! + ctl.window?.center() + ctl.window?.makeKeyAndOrderFront(nil) + ctl.showWindow(nil) + return ctl + } + + func closeJumpToLineWindow() { + guard let ctl = jumpToLineWindowController else { + return + } + ctl.window?.close() + ctl.dismissController(nil) + jumpToLineWindowController = nil + } + // XXX: Kind of a strange place for this to be in. func openManual() { if let url = Bundle.main.url(forResource: "resources/manual/index", withExtension: "html") {