Is there any way to make the FileChooserDialog to select both files and folders?
I know there are the FileChooserAction OPEN and SELECT_FOLDER but they are exclusive.
PD: I dont't want two buttons, I already know how to do this. What I want is to get the routes of all selected elements (both files and folders) with the same button.
The File chooser action is different from what you want. I think you are after the set_select_multiple ()
method or the select_multiple
property (both inherited from the Gtk.FileChooser interface).
Then you can use the methods get_filenames ()
or get_uris ()
, depending on your needs.
The default GtkFileChooserDialog only allows you to select folders and files if you are on the Recent "tab" but as soon as you use a normal folder it won't let you do that.
In order to achieve that you must use Gtk.FileChooserWidget by composing a solution or creating a new widget (eg. subclassing Gtk.FileChooserWidget or Gtk.Dialog).
I've created a simple example that will work as you want and that you can easily change to suit your needs.
The following code is based on Valadoc.org Gtk.FileChooserWidget page, which does what you are asking:
public class Application : Gtk.Window {
public Application () {
// Prepare Gtk.Window:
this.window_position = Gtk.WindowPosition.CENTER;
this.destroy.connect (Gtk.main_quit);
// VBox:
Gtk.Box vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 5);
this.add (vbox);
// HeaderBar:
Gtk.HeaderBar hbar = new Gtk.HeaderBar ();
hbar.set_title ("MyFileChooser");
hbar.set_subtitle ("Select Files and Folders");
// HeaderBar Buttons
Gtk.Button cancel = new Gtk.Button.with_label ("Cancel");
Gtk.Button select = new Gtk.Button.with_label ("Select");
hbar.pack_start (cancel);
hbar.pack_end (select);
this.set_titlebar (hbar);
// Add a chooser:
Gtk.FileChooserWidget chooser = new Gtk.FileChooserWidget (Gtk.FileChooserAction.OPEN);
vbox.pack_start (chooser, true, true, 0);
// Multiple files can be selected:
chooser.select_multiple = true;
// Add a preview widget:
Gtk.Image preview_area = new Gtk.Image ();
chooser.set_preview_widget (preview_area);
chooser.update_preview.connect (() => {
string uri = chooser.get_preview_uri ();
// We only display local files:
if (uri.has_prefix ("file://") == true) {
try {
Gdk.Pixbuf pixbuf = new Gdk.Pixbuf.from_file (uri.substring (7));
Gdk.Pixbuf scaled = pixbuf.scale_simple (150, 150, Gdk.InterpType.BILINEAR);
preview_area.set_from_pixbuf (scaled);
preview_area.show ();
} catch (Error e) {
preview_area.hide ();
}
} else {
preview_area.hide ();
}
});
// HBox:
Gtk.Box hbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 5);
vbox.pack_start(hbox, false, false, 0);
// Setup buttons callbacks
cancel.clicked.connect (() => {
this.destroy ();
});
select.clicked.connect (() => {
SList<string> uris = chooser.get_uris ();
foreach (unowned string uri in uris) {
stdout.printf (" %s\n", uri);
}
this.destroy ();
});
}
public static int main (string[] args) {
Gtk.init (ref args);
Application app = new Application ();
app.show_all ();
Gtk.main ();
return 0;
}
}
Compile with:
valac --pkg gtk+-3.0 Gtk.FileChooserDialog.vala
After you choose select, the application will print your selection to the console:
Dumps (path partially replaced with ...
):
file:///.../stackoverflow/3305/1
file:///.../stackoverflow/3305/2
file:///.../stackoverflow/3305/3
file:///.../stackoverflow/3305/Gtk.FileChooserDialog
file:///.../stackoverflow/3305/Gtk.FileChooserDialog.vala
file:///.../stackoverflow/3305/Gtk.FileChooserWidget
file:///.../stackoverflow/3305/Gtk.FileChooserWidget.vala
file:///.../stackoverflow/3305/img1.jpg
file:///.../stackoverflow/3305/img2.jpg
file:///.../stackoverflow/3305/img3.jpg
file:///.../stackoverflow/3305/Makefile