Skip to content

Commit afd49e3

Browse files
committed
Add FileDialog convenience methods.
1 parent 48bb7c6 commit afd49e3

File tree

3 files changed

+147
-3
lines changed

3 files changed

+147
-3
lines changed

Sources/Gtk/FileChooser.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
// SwiftGtk
44
//
55
// Created by Rene Hexel on 4/8/19.
6-
// Copyright © 2019, 2020 Rene Hexel. All rights reserved.
6+
// Copyright © 2019, 2020, 2024 Rene Hexel. All rights reserved.
77
//
88
import CGtk
99
import GtkCHelpers
1010
import GLib
1111
import GLibObject
1212
import GIO
1313

14+
@available(*, deprecated, renamed: "FileDialog")
1415
public extension FileChooserDialog {
1516
/// Convenience constructor to create a file chooser dialog with two buttons.
1617
/// - Parameter title: Title of the dialog

Sources/Gtk/FileChooserNative.swift

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,22 @@
33
// Gtk
44
//
55
// Created by Rene Hexel on 18/8/19.
6-
// Copyright © 2019, 2020 Rene Hexel. All rights reserved.
6+
// Copyright © 2019, 2020, 2024 Rene Hexel. All rights reserved.
77
//
88
import CGtk
99
import GtkCHelpers
1010
import GLib
1111
import GLibObject
1212
import GIO
1313

14+
@available(*, deprecated, renamed: "FileDialog")
1415
public extension FileChooserNative {
1516
/// Convenence initialiser to create a new, native file chooser
1617
/// - Parameter title: Title of the native file chooser (optional)
1718
/// - Parameter action: File chooser kind, e.g. `.open` or `.save`
1819
/// - Parameter acceptLabel: Text of the accept button or `nil` for the default
19-
/// - Parameter cancelLabel: Text of the cancel button or `nil` for the default
20+
/// - Parameter cancelLabel: Text of the cancel button or `nil` for the defaults
21+
/// - Note: ``FileChooserNative`` has been deprecated in gtk-4.10. Use ``FileDialog`` instead.
2022
@inlinable convenience init(title: UnsafePointer<gchar>! = nil, action: FileChooserAction = .open, acceptLabel: UnsafePointer<gchar>? = nil, cancelLabel: UnsafePointer<gchar>? = nil) {
2123
self.init(gtk_file_chooser_native_new(title, nil, action, acceptLabel, cancelLabel))
2224
}
@@ -27,6 +29,7 @@ public extension FileChooserNative {
2729
/// - Parameter action: File chooser kind, e.g. `.open` or `.save`
2830
/// - Parameter acceptLabel: Text of the accept button or `nil` for the default
2931
/// - Parameter cancelLabel: Text of the cancel button or `nil` for the default
32+
/// - Note: ``FileChooserNative`` has been deprecated in gtk-4.10. Use ``FileDialog`` instead.
3033
@inlinable convenience init<W: WindowProtocol>(title: UnsafePointer<gchar>! = nil, parent: W, action: FileChooserAction = .open, acceptLabel: UnsafePointer<gchar>? = nil, cancelLabel: UnsafePointer<gchar>? = nil) {
3134
self.init(gtk_file_chooser_native_new(title, parent.window_ptr, action, acceptLabel, cancelLabel))
3235
}

Sources/Gtk/FileDialog.swift

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
//
2+
// FileDialog.swift
3+
//
4+
// Created by Rene Hexel on 24/1/2024.
5+
// Copyright © 2024 Rene Hexel. All rights reserved.
6+
//
7+
import CGtk
8+
import GtkCHelpers
9+
import GLib
10+
import GLibObject
11+
import GIO
12+
13+
public extension FileDialogProtocol {
14+
/// Open the file dialog.
15+
///
16+
/// This method initiates an asynchronous file selection operation,
17+
/// showing the dialog to the user. The callback provided will be
18+
/// called when the user has selected a file name, or has cancelled
19+
/// the operation.
20+
///
21+
/// - Parameters:
22+
/// - parentWindow: The parent ``Window`` to attach the dialog to.
23+
/// - cancellable: The ``Cancellable`` to cancel the operation.
24+
/// - callback: The function or closure to call when interaction has completed.
25+
@inlinable
26+
public func open<W: WindowProtocol, C: CancellableProtocol>(parentWindow: W, cancellable: C, callback: @escaping (FileDialogRef, Result<FileRef, any Error>) -> Void) {
27+
open(parentWindowRef: WindowRef(parentWindow), cancellableRef: GIO.CancellableRef(cancellable), callback: callback)
28+
}
29+
30+
/// Open the file dialog.
31+
///
32+
/// This method initiates an asynchronous file selection operation,
33+
/// showing the dialog to the user. The callback provided will be
34+
/// called when the user has selected a file name, or has cancelled
35+
/// the operation.
36+
///
37+
/// - Parameters:
38+
/// - parentWindow: The parent ``Window`` to attach the dialog to.
39+
/// - callback: The function or closure to call when interaction has completed.
40+
@inlinable
41+
public func open<W: WindowProtocol>(parentWindow: W, callback: @escaping (FileDialogRef, Result<FileRef, any Error>) -> Void) {
42+
open(parentWindowRef: WindowRef(parentWindow), cancellableRef: nil, callback: callback)
43+
}
44+
45+
/// Open the file dialog.
46+
///
47+
/// This method initiates an asynchronous file selection operation,
48+
/// showing the dialog to the user. The callback provided will be
49+
/// called when the user has selected a file name, or has cancelled
50+
/// the operation.
51+
///
52+
/// - Parameters:
53+
/// - callback: The function or closure to call when interaction has completed.
54+
@inlinable
55+
public func open(callback: @escaping (FileDialogRef, Result<FileRef, any Error>) -> Void) {
56+
open(parentWindowRef: nil, cancellableRef: nil, callback: callback)
57+
}
58+
59+
/// Open the file dialog.
60+
///
61+
/// This method initiates an asynchronous file selection operation,
62+
/// showing the dialog to the user. The callback provided will be
63+
/// called when the user has selected a file name, or has cancelled
64+
/// the operation.
65+
/// - Parameters:
66+
/// - parentWindowRef: A reference to the parent ``Window``.
67+
/// - cancellableRef: A reference to a ``Cancellable`` to cancel the operation.
68+
/// - callback: The closure to call when interaction has completed.
69+
@inlinable
70+
public func open(parentWindowRef: WindowRef?, cancellableRef: GIO.CancellableRef?, callback: @escaping (FileDialogRef, Result<FileRef, any Error>) -> Void) {
71+
let callbackHolder = ClosureHolder<(FileDialogRef, Result<FileRef, any Error>), Void> { callback($0.0, $0.1) }
72+
let asyncReadyCallbackHolder = unsafeBitCast(Unmanaged.passRetained(callbackHolder).toOpaque(), to: gpointer.self)
73+
open(parent: parentWindowRef, cancellable: cancellableRef, callback: {
74+
(dialogPtr, result, userData) in
75+
let callbackHolder = Unmanaged<ClosureHolder<(FileDialogRef, Result<FileRef, any Error>), Void>>.fromOpaque(userData!).takeRetainedValue()
76+
let dialogRef = FileDialogRef(gpointer: dialogPtr)!
77+
let dialogResult = Result {
78+
try dialogRef.openFinish(result: GIO.AsyncResultRef(result))!
79+
}
80+
callbackHolder.call((dialogRef, dialogResult))
81+
}, userData: asyncReadyCallbackHolder)
82+
}
83+
}
84+
85+
// MARK: - async methods
86+
87+
public extension FileDialogProtocol {
88+
/// Asynchronously opens the file dialog.
89+
///
90+
/// This method initiates an asynchronous file selection operation,
91+
/// showing the dialog to the user. The returned result will contain
92+
/// the file the user has selected, or an errof if the operation was cancelled.
93+
/// - Returns: The result of the file dialog interaction.
94+
@available(macOS 10.15, *)
95+
@inlinable
96+
func open() async -> Result<FileRef, any Error> {
97+
await withCheckedContinuation { continuation in
98+
open {
99+
continuation.resume(returning: $1)
100+
}
101+
}
102+
}
103+
104+
/// Asynchronously opens the file dialog.
105+
///
106+
/// This method initiates an asynchronous file selection operation,
107+
/// showing the dialog to the user. The returned result will contain
108+
/// the file the user has selected, or an errof if the operation was cancelled.
109+
/// - Parameter parentWindow: The parent ``Window`` to attach the dialog to.
110+
/// - Returns: The result of the file dialog interaction.
111+
@available(macOS 10.15, *)
112+
@inlinable
113+
func open<W: WindowProtocol>(parentWindow: W) async -> Result<FileRef, any Error> {
114+
await withCheckedContinuation { continuation in
115+
open(parentWindow: parentWindow) {
116+
continuation.resume(returning: $1)
117+
}
118+
}
119+
}
120+
121+
/// Asynchronously opens the file dialog.
122+
///
123+
/// This method initiates an asynchronous file selection operation,
124+
/// showing the dialog to the user. The returned result will contain
125+
/// the file the user has selected, or an errof if the operation was cancelled.
126+
/// - Returns: The result of the file operation
127+
/// - Parameters:
128+
/// - parentWindow: The parent ``Window`` to attach the dialog to.
129+
/// - cancellable: The ``Cancellable`` to cancel the operation.
130+
@available(macOS 10.15, *)
131+
@inlinable
132+
func open<W: WindowProtocol, C: CancellableProtocol>(parentWindow: W, cancellable: C) async -> Result<FileRef, any Error> {
133+
await withCheckedContinuation { continuation in
134+
open(parentWindow: parentWindow, cancellable: cancellable) {
135+
continuation.resume(returning: $1)
136+
}
137+
}
138+
}
139+
140+
}

0 commit comments

Comments
 (0)