mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-03 00:41:59 +08:00
feat: adds file filtering to gtk select/save dialogs
This commit is contained in:
parent
da20bcc8d2
commit
393a4fceb2
@ -17,9 +17,9 @@ type Renderer interface {
|
||||
NotifyEvent(eventData *messages.EventData) error
|
||||
|
||||
// Dialog Runtime
|
||||
SelectFile() string
|
||||
SelectFile(filter string) string
|
||||
SelectDirectory() string
|
||||
SelectSaveFile() string
|
||||
SelectSaveFile(filter string) string
|
||||
|
||||
// Window Runtime
|
||||
SetColour(string) error
|
||||
|
@ -114,7 +114,7 @@ func (h *Bridge) NewBinding(methodName string) error {
|
||||
|
||||
// SelectFile is unsupported for Bridge but required
|
||||
// for the Renderer interface
|
||||
func (h *Bridge) SelectFile() string {
|
||||
func (h *Bridge) SelectFile(filter string) string {
|
||||
h.log.Warn("SelectFile() unsupported in bridge mode")
|
||||
return ""
|
||||
}
|
||||
@ -128,7 +128,7 @@ func (h *Bridge) SelectDirectory() string {
|
||||
|
||||
// SelectSaveFile is unsupported for Bridge but required
|
||||
// for the Renderer interface
|
||||
func (h *Bridge) SelectSaveFile() string {
|
||||
func (h *Bridge) SelectSaveFile(filter string) string {
|
||||
h.log.Warn("SelectSaveFile() unsupported in bridge mode")
|
||||
return ""
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ func (w *WebView) NewBinding(methodName string) error {
|
||||
}
|
||||
|
||||
// SelectFile opens a dialog that allows the user to select a file
|
||||
func (w *WebView) SelectFile() string {
|
||||
func (w *WebView) SelectFile(filter string) string {
|
||||
var result string
|
||||
|
||||
// We need to run this on the main thread, however Dispatch is
|
||||
@ -255,7 +255,7 @@ func (w *WebView) SelectFile() string {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
w.window.Dispatch(func() {
|
||||
result = w.window.Dialog(wv.DialogTypeOpen, 0, "Select File", "")
|
||||
result = w.window.Dialog(wv.DialogTypeOpen, 0, "Select File", "", filter)
|
||||
wg.Done()
|
||||
})
|
||||
}()
|
||||
@ -273,7 +273,7 @@ func (w *WebView) SelectDirectory() string {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
w.window.Dispatch(func() {
|
||||
result = w.window.Dialog(wv.DialogTypeOpen, wv.DialogFlagDirectory, "Select Directory", "")
|
||||
result = w.window.Dialog(wv.DialogTypeOpen, wv.DialogFlagDirectory, "Select Directory", "", "")
|
||||
wg.Done()
|
||||
})
|
||||
}()
|
||||
@ -282,7 +282,7 @@ func (w *WebView) SelectDirectory() string {
|
||||
}
|
||||
|
||||
// SelectSaveFile opens a dialog that allows the user to select a file to save
|
||||
func (w *WebView) SelectSaveFile() string {
|
||||
func (w *WebView) SelectSaveFile(filter string) string {
|
||||
var result string
|
||||
// We need to run this on the main thread, however Dispatch is
|
||||
// non-blocking so we launch this in a goroutine and wait for
|
||||
@ -291,7 +291,7 @@ func (w *WebView) SelectSaveFile() string {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
w.window.Dispatch(func() {
|
||||
result = w.window.Dialog(wv.DialogTypeSave, 0, "Save file", "")
|
||||
result = w.window.Dialog(wv.DialogTypeSave, 0, "Save file", "", filter)
|
||||
wg.Done()
|
||||
})
|
||||
}()
|
||||
|
@ -74,9 +74,9 @@ static inline void CgoWebViewSetColor(void *w, uint8_t r, uint8_t g, uint8_t b,
|
||||
}
|
||||
|
||||
static inline void CgoDialog(void *w, int dlgtype, int flags,
|
||||
char *title, char *arg, char *res, size_t ressz) {
|
||||
char *title, char *arg, char *res, size_t ressz, char *filter) {
|
||||
webview_dialog(w, dlgtype, flags,
|
||||
(const char*)title, (const char*) arg, res, ressz);
|
||||
(const char*)title, (const char*) arg, res, ressz, filter);
|
||||
}
|
||||
|
||||
static inline int CgoWebViewEval(void *w, char *js) {
|
||||
@ -186,7 +186,7 @@ type WebView interface {
|
||||
// Dialog() opens a system dialog of the given type and title. String
|
||||
// argument can be provided for certain dialogs, such as alert boxes. For
|
||||
// alert boxes argument is a message inside the dialog box.
|
||||
Dialog(dlgType DialogType, flags int, title string, arg string) string
|
||||
Dialog(dlgType DialogType, flags int, title string, arg string, filter string) string
|
||||
// Terminate() breaks the main UI loop. This method must be called from the main thread
|
||||
// only. See Dispatch() for more details.
|
||||
Terminate()
|
||||
@ -311,7 +311,7 @@ func (w *webview) SetFullscreen(fullscreen bool) {
|
||||
C.CgoWebViewSetFullscreen(w.w, C.int(boolToInt(fullscreen)))
|
||||
}
|
||||
|
||||
func (w *webview) Dialog(dlgType DialogType, flags int, title string, arg string) string {
|
||||
func (w *webview) Dialog(dlgType DialogType, flags int, title string, arg string, filter string) string {
|
||||
const maxPath = 4096
|
||||
titlePtr := C.CString(title)
|
||||
defer C.free(unsafe.Pointer(titlePtr))
|
||||
@ -319,8 +319,10 @@ func (w *webview) Dialog(dlgType DialogType, flags int, title string, arg string
|
||||
defer C.free(unsafe.Pointer(argPtr))
|
||||
resultPtr := (*C.char)(C.calloc((C.size_t)(unsafe.Sizeof((*C.char)(nil))), (C.size_t)(maxPath)))
|
||||
defer C.free(unsafe.Pointer(resultPtr))
|
||||
filterPtr := C.CString(filter)
|
||||
defer C.free(unsafe.Pointer(filterPtr))
|
||||
C.CgoDialog(w.w, C.int(dlgType), C.int(flags), titlePtr,
|
||||
argPtr, resultPtr, C.size_t(maxPath))
|
||||
argPtr, resultPtr, C.size_t(maxPath), filterPtr)
|
||||
return C.GoString(resultPtr)
|
||||
}
|
||||
|
||||
|
@ -174,7 +174,7 @@ struct webview_priv
|
||||
WEBVIEW_API void webview_dialog(struct webview *w,
|
||||
enum webview_dialog_type dlgtype, int flags,
|
||||
const char *title, const char *arg,
|
||||
char *result, size_t resultsz);
|
||||
char *result, size_t resultsz, char *filter);
|
||||
WEBVIEW_API void webview_dispatch(struct webview *w, webview_dispatch_fn fn,
|
||||
void *arg);
|
||||
WEBVIEW_API void webview_terminate(struct webview *w);
|
||||
@ -418,7 +418,7 @@ struct webview_priv
|
||||
WEBVIEW_API void webview_dialog(struct webview *w,
|
||||
enum webview_dialog_type dlgtype, int flags,
|
||||
const char *title, const char *arg,
|
||||
char *result, size_t resultsz)
|
||||
char *result, size_t resultsz, char *filter)
|
||||
{
|
||||
GtkWidget *dlg;
|
||||
if (result != NULL)
|
||||
@ -438,6 +438,16 @@ struct webview_priv
|
||||
"_Cancel", GTK_RESPONSE_CANCEL,
|
||||
(dlgtype == WEBVIEW_DIALOG_TYPE_OPEN ? "_Open" : "_Save"),
|
||||
GTK_RESPONSE_ACCEPT, NULL);
|
||||
if (filter[0] != '\0') {
|
||||
GtkFileFilter *file_filter = gtk_file_filter_new();
|
||||
gchar **filters = g_strsplit(filter, ",", -1);
|
||||
gint i;
|
||||
for(i = 0; filters && filters[i]; i++) {
|
||||
gtk_file_filter_add_pattern(file_filter, filters[i]);
|
||||
}
|
||||
gtk_file_filter_set_name(file_filter, filter);
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dlg), file_filter);
|
||||
}
|
||||
gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dlg), FALSE);
|
||||
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dlg), FALSE);
|
||||
gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(dlg), TRUE);
|
||||
|
@ -15,8 +15,12 @@ func NewDialog(renderer interfaces.Renderer) *Dialog {
|
||||
}
|
||||
|
||||
// SelectFile prompts the user to select a file
|
||||
func (r *Dialog) SelectFile() string {
|
||||
return r.renderer.SelectFile()
|
||||
func (r *Dialog) SelectFile(params ...string) string {
|
||||
filter := ""
|
||||
if len(params) > 0 {
|
||||
filter = params[0]
|
||||
}
|
||||
return r.renderer.SelectFile(filter)
|
||||
}
|
||||
|
||||
// SelectDirectory prompts the user to select a directory
|
||||
@ -25,6 +29,10 @@ func (r *Dialog) SelectDirectory() string {
|
||||
}
|
||||
|
||||
// SelectSaveFile prompts the user to select a file for saving
|
||||
func (r *Dialog) SelectSaveFile() string {
|
||||
return r.renderer.SelectSaveFile()
|
||||
func (r *Dialog) SelectSaveFile(params ...string) string {
|
||||
filter := ""
|
||||
if len(params) > 0 {
|
||||
filter = params[0]
|
||||
}
|
||||
return r.renderer.SelectSaveFile(filter)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user