Blame platform-demos/ca/filechooserdialog.py.page

Packit 1470ea
Packit 1470ea
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" xmlns:xi="http://www.w3.org/2001/XInclude" type="guide" style="task" id="filechooserdialog.py" xml:lang="ca">
Packit 1470ea
  <info>
Packit 1470ea
    <title type="text">FileChooserDialog (Python)</title>
Packit 1470ea
    <link type="guide" xref="beginner.py#file-selectors"/>
Packit 1470ea
    <link type="seealso" xref="gmenu.py"/>
Packit 1470ea
    <link type="seealso" xref="toolbar_builder.py"/>
Packit 1470ea
    <link type="seealso" xref="textview.py"/>
Packit 1470ea
    <link type="next" xref="combobox.py"/>
Packit 1470ea
    <revision version="0.1" date="2012-08-14" status="draft"/>
Packit 1470ea
Packit 1470ea
    <credit type="author copyright">
Packit 1470ea
      <name>Marta Maria Casetti</name>
Packit 1470ea
      <email its:translate="no">mmcasetti@gmail.com</email>
Packit 1470ea
      <years>2012</years>
Packit 1470ea
    </credit>
Packit 1470ea
Packit 1470ea
    <desc>A dialog suitable for "Open" and "Save" commands</desc>
Packit 1470ea
  </info>
Packit 1470ea
Packit 1470ea
  <title>FileChooserDialog</title>
Packit 1470ea
  <media type="image" mime="image/png" src="media/filechooserdialog_save.png"/>
Packit 1470ea
  

This FileChooserDialog saves a text document, which can be opened or written from scratch in a TextView (see below).

Packit 1470ea
  <media type="image" mime="image/png" src="media/filechooserdialog_menu.png"/>
Packit 1470ea
  

It is also possible to call a FileChooserDialog to open a new document.

Packit 1470ea
Packit 1470ea
  <links type="sections"/>
Packit 1470ea
  
Packit 1470ea
  <section id="overview">
Packit 1470ea
  <title>Steps to recreate the example</title>
Packit 1470ea
  <steps>
Packit 1470ea
    <item>

Create a file .ui to describe an app-menu with items "New", "Open", "Save", "Save as", and "Quit". This can be done with Glade or in a text editor. See <link xref="#xml"/>

</item>
Packit 1470ea
    <item>

Create a Python program for a Gtk.TextView with a Gtk.Buffer self.buffer, and a self.file which will be a Gio.File and we set initially as None.

</item>
Packit 1470ea
    <item>

In this program, create also the actions corresponding to the items in the app-menu, connect them to callback functions, and import the menu in the do_startup() method with a Gtk.Builder.

</item>
Packit 1470ea
    <item>

"New" and "Quit" actions and callback functions are quite straightforward, see <link xref="#code"/>. See <link xref="signals-callbacks.py"/> for a more detailed explanation of signals and callback functions.

</item>
Packit 1470ea
    <item>

"Open" callback should create and open a Gtk.FileChooserDialog for "Open", connected with another callback function for each of the two "Open" and "Cancel" buttons of the FileChooserDialog.

</item>
Packit 1470ea
    <item>

"Save as" works basically as "Open", but the callback function of the "Save" button depends on a more complex method save_to_file().

</item>
Packit 1470ea
    <item>

"Save" can be reduced to the case where the file is None, that is the case where self.file is a new file, which in turn is the case "Save as"; and to the case where the file is not None, which in turn is reduced to save_to_file().

</item>
Packit 1470ea
    <item>

Finally, the method save_to_file(): see <link xref="#code"/>, lines 146 - 175.

</item>
Packit 1470ea
  </steps>
Packit 1470ea
  </section>
Packit 1470ea
  
Packit 1470ea
  <section id="xml">
Packit 1470ea
  <title>XML file which creates the app-menu</title>
Packit 1470ea
  <?xml version="1.0"?>
Packit 1470ea
<interface>
Packit 1470ea
  <menu id="appmenu">
Packit 1470ea
    <section>
Packit 1470ea
      <item>
Packit 1470ea
        <attribute name="label">New</attribute>
Packit 1470ea
        <attribute name="action">win.new</attribute>
Packit 1470ea
      </item>
Packit 1470ea
      <item>
Packit 1470ea
        <attribute name="label">Open</attribute>
Packit 1470ea
        <attribute name="action">win.open</attribute>
Packit 1470ea
      </item>
Packit 1470ea
    </section>
Packit 1470ea
    <section>
Packit 1470ea
      <item>
Packit 1470ea
        <attribute name="label">Save</attribute>
Packit 1470ea
        <attribute name="action">win.save</attribute>
Packit 1470ea
      </item>
Packit 1470ea
      <item>
Packit 1470ea
        <attribute name="label">Save As...</attribute>
Packit 1470ea
        <attribute name="action">win.save-as</attribute>
Packit 1470ea
      </item>
Packit 1470ea
    </section>
Packit 1470ea
    <section>
Packit 1470ea
      <item>
Packit 1470ea
        <attribute name="label">Quit</attribute>
Packit 1470ea
        <attribute name="action">app.quit</attribute>
Packit 1470ea
      </item>
Packit 1470ea
    </section>
Packit 1470ea
  </menu>
Packit 1470ea
</interface>
Packit 1470ea
Packit 1470ea
  </section>
Packit 1470ea
  
Packit 1470ea
  <section id="code">
Packit 1470ea
  <title>Code used to generate this example</title>
Packit 1470ea
  from gi.repository import Gtk
Packit 1470ea
from gi.repository import Gdk
Packit 1470ea
from gi.repository import Gio
Packit 1470ea
from gi.repository import GObject
Packit 1470ea
import sys
Packit 1470ea
Packit 1470ea
Packit 1470ea
class MyWindow(Gtk.ApplicationWindow):
Packit 1470ea
Packit 1470ea
    def __init__(self, app):
Packit 1470ea
        Gtk.Window.__init__(
Packit 1470ea
            self, title="FileChooserDialog Example", application=app)
Packit 1470ea
        self.set_default_size(400, 400)
Packit 1470ea
Packit 1470ea
        # the actions for the window menu, connected to the callback functions
Packit 1470ea
        new_action = Gio.SimpleAction.new("new", None)
Packit 1470ea
        new_action.connect("activate", self.new_callback)
Packit 1470ea
        self.add_action(new_action)
Packit 1470ea
Packit 1470ea
        open_action = Gio.SimpleAction.new("open", None)
Packit 1470ea
        open_action.connect("activate", self.open_callback)
Packit 1470ea
        self.add_action(open_action)
Packit 1470ea
Packit 1470ea
        save_action = Gio.SimpleAction.new("save", None)
Packit 1470ea
        save_action.connect("activate", self.save_callback)
Packit 1470ea
        self.add_action(save_action)
Packit 1470ea
Packit 1470ea
        save_as_action = Gio.SimpleAction.new("save-as", None)
Packit 1470ea
        save_as_action.connect("activate", self.save_as_callback)
Packit 1470ea
        self.add_action(save_as_action)
Packit 1470ea
Packit 1470ea
        # the file
Packit 1470ea
        self.file = None
Packit 1470ea
Packit 1470ea
        # the textview with the buffer
Packit 1470ea
        self.buffer = Gtk.TextBuffer()
Packit 1470ea
        textview = Gtk.TextView(buffer=self.buffer)
Packit 1470ea
        textview.set_wrap_mode(Gtk.WrapMode.WORD)
Packit 1470ea
Packit 1470ea
        # a scrolled window for the textview
Packit 1470ea
        self.scrolled_window = Gtk.ScrolledWindow()
Packit 1470ea
        self.scrolled_window.set_policy(
Packit 1470ea
            Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
Packit 1470ea
        self.scrolled_window.add(textview)
Packit 1470ea
        self.scrolled_window.set_border_width(5)
Packit 1470ea
Packit 1470ea
        # add the scrolled window to the window
Packit 1470ea
        self.add(self.scrolled_window)
Packit 1470ea
Packit 1470ea
    # callback for new
Packit 1470ea
    def new_callback(self, action, parameter):
Packit 1470ea
        self.buffer.set_text("")
Packit 1470ea
        print("New file created")
Packit 1470ea
Packit 1470ea
    # callback for open
Packit 1470ea
    def open_callback(self, action, parameter):
Packit 1470ea
        # create a filechooserdialog to open:
Packit 1470ea
        # the arguments are: title of the window, parent_window, action,
Packit 1470ea
        # (buttons, response)
Packit 1470ea
        open_dialog = Gtk.FileChooserDialog("Pick a file", self,
Packit 1470ea
                                            Gtk.FileChooserAction.OPEN,
Packit 1470ea
                                           (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Packit 1470ea
                                            Gtk.STOCK_OPEN, Gtk.ResponseType.ACCEPT))
Packit 1470ea
Packit 1470ea
        # not only local files can be selected in the file selector
Packit 1470ea
        open_dialog.set_local_only(False)
Packit 1470ea
        # dialog always on top of the textview window
Packit 1470ea
        open_dialog.set_modal(True)
Packit 1470ea
        # connect the dialog with the callback function open_response_cb()
Packit 1470ea
        open_dialog.connect("response", self.open_response_cb)
Packit 1470ea
        # show the dialog
Packit 1470ea
        open_dialog.show()
Packit 1470ea
Packit 1470ea
    # callback function for the dialog open_dialog
Packit 1470ea
    def open_response_cb(self, dialog, response_id):
Packit 1470ea
        open_dialog = dialog
Packit 1470ea
        # if response is "ACCEPT" (the button "Open" has been clicked)
Packit 1470ea
        if response_id == Gtk.ResponseType.ACCEPT:
Packit 1470ea
            # self.file is the file that we get from the FileChooserDialog
Packit 1470ea
            self.file = open_dialog.get_file()
Packit 1470ea
            # an empty string (provisionally)
Packit 1470ea
            content = ""
Packit 1470ea
            try:
Packit 1470ea
                # load the content of the file into memory:
Packit 1470ea
                # success is a boolean depending on the success of the operation
Packit 1470ea
                # content is self-explanatory
Packit 1470ea
                # etags is an entity tag (can be used to quickly determine if the
Packit 1470ea
                # file has been modified from the version on the file system)
Packit 1470ea
                [success, content, etags] = self.file.load_contents(None)
Packit 1470ea
            except GObject.GError as e:
Packit 1470ea
                print("Error: " + e.message)
Packit 1470ea
            # set the content as the text into the buffer
Packit 1470ea
            self.buffer.set_text(content, len(content))
Packit 1470ea
            print("opened: " + open_dialog.get_filename())
Packit 1470ea
        # if response is "CANCEL" (the button "Cancel" has been clicked)
Packit 1470ea
        elif response_id == Gtk.ResponseType.CANCEL:
Packit 1470ea
            print("cancelled: FileChooserAction.OPEN")
Packit 1470ea
        # destroy the FileChooserDialog
Packit 1470ea
        dialog.destroy()
Packit 1470ea
Packit 1470ea
    # callback function for save_as
Packit 1470ea
    def save_as_callback(self, action, parameter):
Packit 1470ea
        # create a filechooserdialog to save:
Packit 1470ea
        # the arguments are: title of the window, parent_window, action,
Packit 1470ea
        # (buttons, response)
Packit 1470ea
        save_dialog = Gtk.FileChooserDialog("Pick a file", self,
Packit 1470ea
                                            Gtk.FileChooserAction.SAVE,
Packit 1470ea
                                           (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Packit 1470ea
                                            Gtk.STOCK_SAVE, Gtk.ResponseType.ACCEPT))
Packit 1470ea
        # the dialog will present a confirmation dialog if the user types a file name that
Packit 1470ea
        # already exists
Packit 1470ea
        save_dialog.set_do_overwrite_confirmation(True)
Packit 1470ea
        # dialog always on top of the textview window
Packit 1470ea
        save_dialog.set_modal(True)
Packit 1470ea
        # if self.file has already been saved
Packit 1470ea
        if self.file is not None:
Packit 1470ea
            try:
Packit 1470ea
                # set self.file as the current filename for the file chooser
Packit 1470ea
                save_dialog.set_file(self.file)
Packit 1470ea
            except GObject.GError as e:
Packit 1470ea
                print("Error: " + e.message)
Packit 1470ea
        # connect the dialog to the callback function save_response_cb()
Packit 1470ea
        save_dialog.connect("response", self.save_response_cb)
Packit 1470ea
        # show the dialog
Packit 1470ea
        save_dialog.show()
Packit 1470ea
Packit 1470ea
    # callback function for the dialog save_dialog
Packit 1470ea
    def save_response_cb(self, dialog, response_id):
Packit 1470ea
        save_dialog = dialog
Packit 1470ea
        # if response is "ACCEPT" (the button "Save" has been clicked)
Packit 1470ea
        if response_id == Gtk.ResponseType.ACCEPT:
Packit 1470ea
            # self.file is the currently selected file
Packit 1470ea
            self.file = save_dialog.get_file()
Packit 1470ea
            # save to file (see below)
Packit 1470ea
            self.save_to_file()
Packit 1470ea
        # if response is "CANCEL" (the button "Cancel" has been clicked)
Packit 1470ea
        elif response_id == Gtk.ResponseType.CANCEL:
Packit 1470ea
            print("cancelled: FileChooserAction.SAVE")
Packit 1470ea
        # destroy the FileChooserDialog
Packit 1470ea
        dialog.destroy()
Packit 1470ea
Packit 1470ea
    # callback function for save
Packit 1470ea
    def save_callback(self, action, parameter):
Packit 1470ea
        # if self.file is not already there
Packit 1470ea
        if self.file is not None:
Packit 1470ea
            self.save_to_file()
Packit 1470ea
        # self.file is a new file
Packit 1470ea
        else:
Packit 1470ea
            # use save_as
Packit 1470ea
            self.save_as_callback(action, parameter)
Packit 1470ea
Packit 1470ea
    # save_to_file
Packit 1470ea
    def save_to_file(self):
Packit 1470ea
        # get the content of the buffer, without hidden characters
Packit 1470ea
        [start, end] = self.buffer.get_bounds()
Packit 1470ea
        current_contents = self.buffer.get_text(start, end, False)
Packit 1470ea
        # if there is some content
Packit 1470ea
        if current_contents != "":
Packit 1470ea
            # set the content as content of self.file.
Packit 1470ea
            # arguments: contents, etags, make_backup, flags, GError
Packit 1470ea
            try:
Packit 1470ea
                self.file.replace_contents(current_contents,
Packit 1470ea
                                           None,
Packit 1470ea
                                           False,
Packit 1470ea
                                           Gio.FileCreateFlags.NONE,
Packit 1470ea
                                           None)
Packit 1470ea
                print("saved: " + self.file.get_path())
Packit 1470ea
            except GObject.GError as e:
Packit 1470ea
                print("Error: " + e.message)
Packit 1470ea
        # if the contents are empty
Packit 1470ea
        else:
Packit 1470ea
            # create (if the file does not exist) or overwrite the file in readwrite mode.
Packit 1470ea
            # arguments: etags, make_backup, flags, GError
Packit 1470ea
            try:
Packit 1470ea
                self.file.replace_readwrite(None,
Packit 1470ea
                                            False,
Packit 1470ea
                                            Gio.FileCreateFlags.NONE,
Packit 1470ea
                                            None)
Packit 1470ea
                print("saved: " + self.file.get_path())
Packit 1470ea
            except GObject.GError as e:
Packit 1470ea
                print("Error: " + e.message)
Packit 1470ea
Packit 1470ea
Packit 1470ea
class MyApplication(Gtk.Application):
Packit 1470ea
Packit 1470ea
    def __init__(self):
Packit 1470ea
        Gtk.Application.__init__(self)
Packit 1470ea
Packit 1470ea
    def do_activate(self):
Packit 1470ea
        win = MyWindow(self)
Packit 1470ea
        win.show_all()
Packit 1470ea
Packit 1470ea
    def do_startup(self):
Packit 1470ea
        Gtk.Application.do_startup(self)
Packit 1470ea
Packit 1470ea
        # app action quit, connected to the callback function
Packit 1470ea
        quit_action = Gio.SimpleAction.new("quit", None)
Packit 1470ea
        quit_action.connect("activate", self.quit_callback)
Packit 1470ea
        self.add_action(quit_action)
Packit 1470ea
Packit 1470ea
        # get the menu from the ui file with a builder
Packit 1470ea
        builder = Gtk.Builder()
Packit 1470ea
        try:
Packit 1470ea
            builder.add_from_file("filechooserdialog.ui")
Packit 1470ea
        except:
Packit 1470ea
            print("file not found")
Packit 1470ea
            sys.exit()
Packit 1470ea
        menu = builder.get_object("appmenu")
Packit 1470ea
        self.set_app_menu(menu)
Packit 1470ea
Packit 1470ea
    # callback function for quit
Packit 1470ea
    def quit_callback(self, action, parameter):
Packit 1470ea
        self.quit()
Packit 1470ea
Packit 1470ea
app = MyApplication()
Packit 1470ea
exit_status = app.run(sys.argv)
Packit 1470ea
sys.exit(exit_status)
Packit 1470ea
Packit 1470ea
  </section>
Packit 1470ea
  
Packit 1470ea
  <section id="methods">
Packit 1470ea
  <title>Useful methods for a FileChooserDialog</title>
Packit 1470ea
    

Note that the action of the FileChooserDialog can be one of the following: Gtk.FileChooserAction.OPEN (the file chooser will only let the user pick an existing file) Gtk.FileChooserAction.SAVE (the file chooser will let the user pick an existing file, or type in a new filename), Gtk.FileChooserAction.SELECT_FOLDER (the file chooser will let the user pick an existing folder), Gtk.FileChooserAction.CREATE_FOLDER (the file chooser will let the user name an existing or new folder).

Packit 1470ea
    

Besides the methods used in the <link xref="#code"/>, we have:

Packit 1470ea
    <list>
Packit 1470ea
      <item>

set_show_hidden(True) is used to display hidden files and folders.

</item>
Packit 1470ea
      <item>

set_select_multiple(True) sets that multiple files can be selected. This is only relevant if the mode is Gtk.FileChooserAction.OPEN or Gtk.FileChooserAction.SELECT_FOLDER.

</item>
Packit 1470ea
      <item>

In a "Save as" dialog, set_current_name(current_name) sets current_name in the file selector, as if entered by the user; current_name can be something like Untitled.txt. This method should not be used except in a "Save as" dialog.

</item>
Packit 1470ea
      <item>

The default current folder is "recent items". To set another folder use set_current_folder_uri(uri); but note you should use this method and cause the file chooser to show a specific folder only when you are doing a "Save as" command and you already have a file saved somewhere.

</item>
Packit 1470ea
    </list>
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="references">
Packit 1470ea
  <title>API References</title>
Packit 1470ea
  

In this sample we used the following:

Packit 1470ea
  <list>
Packit 1470ea
    <item>

<link href="http://developer.gnome.org/gtk3/stable/GtkFileChooserDialog.html">GtkFileChooserDialog</link>

</item>
Packit 1470ea
    <item>

<link href="http://developer.gnome.org/gtk3/stable/GtkFileChooser.html">GtkFileChooser</link>

</item>
Packit 1470ea
    <item>

<link href="http://developer.gnome.org/gtk3/stable/GtkWindow.html">GtkWindow</link>

</item>
Packit 1470ea
    <item>

<link href="http://developer.gnome.org/gtk3/stable/GtkTextView.html">GtkTextView</link>

</item>
Packit 1470ea
    <item>

<link href="http://developer.gnome.org/gtk3/stable/GtkTextBuffer.html">GtkTextBuffer</link>

</item>
Packit 1470ea
    <item>

<link href="http://developer.gnome.org/gtk3/stable/GtkScrolledWindow.html">GtkScrolledWindow</link>

</item>
Packit 1470ea
    <item>

<link href="http://developer.gnome.org/gio/stable/GFile.html">GFile</link>

</item>
Packit 1470ea
    <item>

<link href="http://developer.gnome.org/gio/stable/GSimpleAction.html">GSimpleAction</link>

</item>
Packit 1470ea
    <item>

<link href="http://developer.gnome.org/gtk3/stable/GtkBuilder.html">GtkBuilder</link>

</item>
Packit 1470ea
  </list>
Packit 1470ea
  </section>
Packit 1470ea
</page>