diff --git a/uppsrc/CtrlLib/CtrlLib.upp b/uppsrc/CtrlLib/CtrlLib.upp index 48d51bf5a..8ce3f27d7 100644 --- a/uppsrc/CtrlLib/CtrlLib.upp +++ b/uppsrc/CtrlLib/CtrlLib.upp @@ -88,6 +88,7 @@ file PrinterJob.cpp, Windows.cpp, Win32.cpp, + Gtk.cpp, TrayIconWin32.cpp, TrayIconX11.cpp, TrayIconGtk.cpp, diff --git a/uppsrc/CtrlLib/CtrlUtil.h b/uppsrc/CtrlLib/CtrlUtil.h index 13171a797..f03c7e878 100644 --- a/uppsrc/CtrlLib/CtrlUtil.h +++ b/uppsrc/CtrlLib/CtrlUtil.h @@ -336,10 +336,50 @@ public: #endif #endif -#ifdef PLATFORM_X11 +#ifdef GUI_X11 typedef FileSel FileSelector; #endif +#ifdef GUI_GTK +class FileSelector { + Vector path; + Vector< Tuple2 > type; + + String ipath; + bool confirm; + bool multi; + bool hidden; + int activetype; + +public: + bool Execute(bool open, const char *title = NULL); + bool ExecuteOpen(const char *title = NULL) { return Execute(true, title); } + bool ExecuteSaveAs(const char *title = NULL) { return Execute(false, title); } + + String Get() const { return path.GetCount() ? path[0] : String::GetVoid(); } + operator String() const { return Get(); } + String operator~() const { return Get(); } + + void Set(const String& s) { ipath = s; } + void operator=(const String& s) { Set(s); } + void operator<<=(const String& s) { Set(s); } + + int GetCount() const { return path.GetCount(); } + const String& operator[](int i) const { return path[i]; } + + FileSelector& Type(const char *name, const char *ext) { type.Add(MakeTuple(String(name), String(ext))); return *this; } + FileSelector& AllFilesType(); + FileSelector& Asking(bool b = true) { confirm = b; return *this; } + FileSelector& NoAsking() { return Asking(false); } + FileSelector& Multi(bool b = true) { multi = b; return *this; } + FileSelector& ShowHidden(bool b = true) { hidden = b; return *this; } + FileSelector& ActiveDir(const String& dir) { ipath = dir; return *this; } + FileSelector& ActiveType(int i) { activetype = i; return *this; } + + FileSelector(); +}; +#endif + class CtrlRetriever { public: struct Item { diff --git a/uppsrc/CtrlLib/Gtk.cpp b/uppsrc/CtrlLib/Gtk.cpp new file mode 100644 index 000000000..4fddfc269 --- /dev/null +++ b/uppsrc/CtrlLib/Gtk.cpp @@ -0,0 +1,74 @@ +#include "CtrlLib.h" + +NAMESPACE_UPP + +FileSelector::FileSelector() +{ + confirm = true; + multi = hidden = false; + activetype = 0; +} + +FileSelector& FileSelector::AllFilesType() { + return Type(t_("All files"), "*.*"); +} + +bool FileSelector::Execute(bool open, const char *title) +{ + Ctrl::ReleaseCtrlCapture(); + if(!title) + title = open ? t_("Open") : t_("Save as"); + Ctrl *w = Ctrl::GetActiveWindow(); + GtkWidget *fc = gtk_file_chooser_dialog_new(title, w ? w->gtk() : NULL, + open ? GTK_FILE_CHOOSER_ACTION_OPEN + : GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + open ? GTK_STOCK_OPEN : GTK_STOCK_SAVE, GTK_RESPONSE_OK, + NULL); + gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(fc), confirm); + gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(fc), true); + gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(fc), multi); + gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(fc), hidden); + + if(IsFullPath(ipath)) { + FindFile ff(ipath); + if(ff) + if(ff.IsFolder()) + gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fc), ipath); + else + gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(fc), ipath); + else { + gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fc), GetFileFolder(ipath)); + gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(fc), GetFileName(ipath)); + } + } + else + gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(fc), ipath); + ipath.Clear(); + for(int i = 0; i < type.GetCount(); i++) { + GtkFileFilter *filter = gtk_file_filter_new(); + gtk_file_filter_set_name(filter, type[i].a); + gtk_file_filter_add_pattern(filter, type[i].b); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fc), filter); + if(i == activetype) + gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(fc), filter); + } + bool ret = false; + path.Clear(); + if(gtk_dialog_run(GTK_DIALOG(fc)) == GTK_RESPONSE_OK) { + GSList *list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(fc)); + if(list) { + GSList *l; + for(l = list; l; l = l->next) { + path.Add((const char *)l->data); + g_free(l->data); + } + g_slist_free (list); + } + ret = true; + } + gtk_widget_destroy(fc); + return ret; +} + +END_UPP_NAMESPACE