Create  Edit  FrontPage  Index  Search  Changes  History  RSS  Login

tut-gtk2-dialog-fichoo

Types Of File Chooser Dialogues

File Chooser Dialogues

We have already seen Gtk::FileChooser intrface and Gtk::FileChooserButton widget. GTK+ provides the following three widgets that implement Gtk::FileChooser interface:

We have already learnt about the Gtk::FileChooserButton and have used a file chooser to open one file and/or select a folder. There are three other features provided by the file chooser widget. In the next three examples, we will learn how to:

  • save a file,
  • create a directory (folder)
  • choose multiple files

Saving Files

In the following figure you can see a Gtk::FileChooserDialog widget that is used to save a file. You will notice that it is similar to the other figures in this article, since all file chooser dialogues implement a consistent user interface or look-and-feel to facilitate intuitive use with the emphasis on the commonalities in similar tasks. Similarly the widgets also help the programmer, as they use the same code to implement each dialogue type to minimize the amount of coding required.

dialog-fichoo-01.png

All file chooser dialogues are created with Gtk::FileChooserDialog.new regardless of what options you choose. As with other dialogues, you begin by setting the title of the dialogue and the parent window. The parent window should always be set (should never be nil), because file chooser dialogues should be modal.

Gtk::FileChooserDialog.new(title = nil, parent = nil, action = nil, backend = nil, [button_face1, response_id1], [button_face2, response_id2], ...)
Creates a new Gtk::FileChooserDialog. Since 2.4
  • title: Title of the dialog, or nil
  • parent: Transient parent of the dialog, or nil
  • action: Open or save mode for the dialog(Gtk::FileChooser::Action)
  • backend: The name of the specific filesystem backend to use or nil. (e.g.) "gnome-vfs"
  • [button_face1, response_id1], [button_face2, response_id2], ...: Button face/response ID pairs should be listed.
    • button_face: Button face can be either a stock ID(Gtk::Stock constants) such as Gtk::Stock::OK, or some arbitrary text.
    • response_id: A response ID can be any positive number, or one of the values in the Gtk::Dialog#ResponseType enumeration. If the user clicks one of these dialog buttons, Gtk::Dialog will emit the "response" signal with the corresponding response ID. If a Gtk::Dialog receives the "delete_event" signal, it will emit "response" with a response ID of Gtk::Dialog::RESPONSE_DELETE_EVENT. However, destroying a dialogue does not emit the "response" signal; so be careful relying on "response" when using the Gtk::Dialog::DESTROY_WITH_PARENT flag. Buttons are from left to right, so the first button in the list will be the leftmost button in the dialog.
  • Returns: a new Gtk::FileChooserDialog

Next, as with file chooser buttons, you have to specify the action of the file chooser that will be created. Unlike before with File Chooser Buttons, now all four action types can be set. Following is the list of possible actions:

Action
Describes whether a Gtk::FileChooser is being used to open existing files or to save to a possibly new file. Since 2.4

File chooser dialogues are used in the same way as the the other two dialogues we have seen so far, except you have to handle the response codes. The following program allows the user to choose a file name and sets the button's label to the selected file if the appropriate response code is received.

dialog-fichoo-02.png

#!/usr/bin/env ruby
require 'gtk2'

# Allow the user to enter a new file name and location for
# the file and set the button to the text of the location.
def button_clicked (parent, btt)
  dialog = Gtk::FileChooserDialog.new(
      "Save File As ...",
      parent,
      Gtk::FileChooser::ACTION_SAVE,
      nil,
      [ Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL ],
      [ Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_ACCEPT ]
  )
  dialog.signal_connect('response') do |w, r|
    odg = case r
      when Gtk::Dialog::RESPONSE_ACCEPT
        filename = dialog.filename
        btt.label = filename
        "'ACCEPT' (#{r}) button pressed -- filename is {{ #{filename} }}"
      when Gtk::Dialog::RESPONSE_CANCEL;   "'CANCEL' (#{r}) button pressed"
      else; "Undefined response ID; perhaps Close-x? (#{r})"
    end
    puts odg
    dialog.destroy 
  end
  dialog.run
end

window = Gtk::Window.new("Save a File")
window.border_width = 10
window.set_size_request(200, -1)
window.signal_connect('destroy') { Gtk.main_quit }

button = Gtk::Button.new("Save As ...")
button.signal_connect('clicked') { button_clicked(window, button) }

window.add(button)
window.show_all
Gtk.main

Creating a Folder

GTK+ allows you not only to select a folder but also to create one. A Gtk::FileChooserDialog widget of this type (Gtk::FileChooser::ACTION_CREATE_FOLDER) can be seen on the following image:

dialog-fichoo-03.png

The dialogue in the following listing will handle the creation of a new folder in the current folder entered into the name field and confirmed by the user, so you do not have to take any further actions except destroying the dialogue. Note, however, that there exists already a built in button (2) solely for folder (directory) creation, and that the way it is done in this program may be confusing to the user. dialog-warning-s2.png The two fields namely the name field where a user is expected to enter a new folder name (1) and the field that opens when he or she clicks the button "Create Folder" (2) are internally related. (There may be a problem using the <Create Folder> button (#2) -- see the comment in the source code). Not that it is important, but this is not immediately apparent and takes some testing to realize that created folder shows up in the name field if you back up to the folder in which the new one was created. This exercise is useful only to show you the use of file chooser's action flag Gtk::FileChooser::ACTION_CREATE_FOLDER. You have to test run this program to understand what was just said!

dialog-warning-s2.png

#!/usr/bin/env ruby
require 'gtk2'

# NOTE:
#     Unless you are familiar with the current eroneous behaviour of
#     the extra <Create Folder> button (marked #2) on the top-right
#     side of location bar of the dialogue window, <Create Folder> 
#     button should not be used because it hangs the dialog if
#     <OK> button is pressed when the top entry field is empty.

# Create a new Gtk::FileChooserDialog used to create a new folder.
def create_folder_btt(parent)
  dialog = Gtk::FileChooserDialog.new(
    "Create a Folder ...",
    nil,
    Gtk::FileChooser::ACTION_CREATE_FOLDER,
    nil,
    [ Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL ],
    [ Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK ]
  )
  dialog.run do |response|
    if response == Gtk::Dialog::RESPONSE_OK
      new = dialog.filename
      current = dialog.current_folder
      print "Creating directory - \n[current:%s]\n[new:%s]\n" % [current, new]
    end
  end
  dialog.destroy
end

window = Gtk::Window.new("Creating a folder")
window.border_width = 10
window.set_size_request(200, -1)
window.signal_connect('destroy') { Gtk.main_quit }
button = Gtk::Button.new("Open create folder dialog")
button.signal_connect('clicked') { create_folder_btt(window) }
window.add(button)
window.show_all
Gtk.main

Most of all I want you to realize there are two folder concepts here: the current folder, and the folder that is being created.

Selecting Multiple Files

The following figure shows a standard file chooser dialogue that will allow the user to choose a file. The difference between Gtk::FileChooserDialod? and the Gtk::FileChooserButton using the Gtk::FileChooser::ACTION_OPEN flag is that contrary to what we have seen for buttons the dialogues are capable of selecting multiple files.

dialog-fichoo-04.png

#!/usr/bin/env ruby
require 'gtk2'

def button_clicked (parent)
  dialogue = Gtk::FileChooserDialog.new(
      "Open File(s) ...",
      parent,
      Gtk::FileChooser::ACTION_OPEN,
      nil,
      [ Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL ],
      [ Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_ACCEPT ]
  )
  # You can preset anything you have permissions for:
  dialogue.current_folder  = "/u3/users/iwk"
  dialogue.filename = "/u3/users/iwk/projects/tutorial.rb"

  filter1 = Gtk::FileFilter.new
  filter2 = Gtk::FileFilter.new
  filter1.name = "Source files"
  filter2.name = "All Files"
  filter1.add_pattern('*.c')
  filter1.add_pattern('*.rb')
  filter2.add_pattern('*')
  # order matters (I want All Files as default)
  dialogue.add_filter(filter2)
  dialogue.add_filter(filter1)

  dialogue.select_multiple = true
  dialogue.run do |response|
    if response == Gtk::Dialog::RESPONSE_ACCEPT
      filenames = dialogue.filenames
      puts "SELECTED FILES:"
      filenames.each {|f| print "% 40s ..... was selected\n" % [f]}
    end
  end
  dialogue.destroy
end

window = Gtk::Window.new(Gtk::Window::TOPLEVEL)
window.set_title  "Multi-file Chooser"
window.border_width = 10
window.signal_connect('delete_event') { Gtk.main_quit }

button  = Gtk::Button.new("Open Files")
button.signal_connect('clicked') { button_clicked(window) }

window.add(button)
window.show_all
Gtk.main

Note that the dialogues here are modal, hence you are required to complete the selections and then either accept or cancel the file chooser dialogue, before you can destroy the parent window.

Last modified:2012/01/22 06:48:35
Keyword(s):
References:[tut-gtk] [tut-gtk2-dialog]