/* Copyright (C) 2003 The gtkmm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <vector>

#include <gtkmm/widget.h>
#include <gtkmm/filefilter.h>
#include <giomm/file.h>

_DEFS(gtkmm,gtk)
_PINCLUDE(glibmm/private/interface_p.h)

namespace Gtk
{

_WRAP_ENUM(FileChooserAction, GtkFileChooserAction, decl_prefix GTKMM_API)
_WRAP_ENUM(FileChooserConfirmation, GtkFileChooserConfirmation, decl_prefix GTKMM_API)

//Note that GTK_FILE_SYSTEM_ERROR is not currently public GTK+ API and should
//never be instantiated by the GTK+ C API.

/** Exception class for Gdk::FileChooser errors.
 */
_WRAP_GERROR(FileChooserError,GtkFileChooserError,GTK_FILE_CHOOSER_ERROR,decl_prefix GTKMM_API)

/**
 * Gtk::FileChooser is an interface that can be implemented by file selection
 * widgets. In gtkmm, the main objects that implement this interface are
 * FileChooserWidget and FileChooserDialog. You do not need to write an
 * object that implements the FileChooser interface unless you are trying to
 * adapt an existing file selector to expose a standard programming interface.
 *
 * @par File Names and Encodings
 * When the user is finished selecting files in a FileChooser, your program
 * can get the selected names either as filenames or as URIs. For URIs, the
 * normal escaping rules are applied if the URI contains non-ASCII characters.
 * However, filenames are always returned in the character set specified by the
 * G_FILENAME_ENCODING environment variable. Please see the Glib documentation
 * for more details about this variable.
 *
 * @par Important
 * This means that while you can pass the result of FileChooser::get_filename()
 * to <tt>open(2)</tt> or <tt>fopen(3)</tt>, you may not be able to directly
 * set it as the text of a Gtk::Label widget unless you convert it first to
 * UTF-8, which all gtkmm widgets expect. You should use
 * Glib::filename_to_utf8() to convert filenames into strings that can be
 * passed to gtkmm widgets.
 */
class GTKMM_API FileChooser : public Glib::Interface
{
  _CLASS_INTERFACE(FileChooser, GtkFileChooser, GTK_FILE_CHOOSER, GtkFileChooserClass, , , GTKMM_API)
public:

  _WRAP_METHOD(void set_action(FileChooserAction action), gtk_file_chooser_set_action)
  _WRAP_METHOD(FileChooserAction get_action() const, gtk_file_chooser_get_action)
  _WRAP_METHOD(void set_local_only(bool local_only = true), gtk_file_chooser_set_local_only)
  _WRAP_METHOD(bool get_local_only() const, gtk_file_chooser_get_local_only)
  _WRAP_METHOD(void set_select_multiple(bool select_multiple = true), gtk_file_chooser_set_select_multiple)
  _WRAP_METHOD(bool get_select_multiple() const, gtk_file_chooser_get_select_multiple)

  _WRAP_METHOD(void set_show_hidden(bool show_hidden = true), gtk_file_chooser_set_show_hidden)
  _WRAP_METHOD(bool get_show_hidden() const, gtk_file_chooser_get_show_hidden)

  _WRAP_METHOD(void set_do_overwrite_confirmation(bool do_overwrite_confirmation = true), gtk_file_chooser_set_do_overwrite_confirmation)
  _WRAP_METHOD(bool get_do_overwrite_confirmation() const, gtk_file_chooser_get_do_overwrite_confirmation)

  _WRAP_METHOD(void set_create_folders(bool create_folders = true), gtk_file_chooser_set_create_folders)
  _WRAP_METHOD(bool get_create_folders() const, gtk_file_chooser_get_create_folders)

  _WRAP_METHOD(void set_current_name(const Glib::ustring& name), gtk_file_chooser_set_current_name)
  _WRAP_METHOD(Glib::ustring get_current_name() const, gtk_file_chooser_get_current_name)

  _WRAP_METHOD(std::string get_filename() const, gtk_file_chooser_get_filename)
  _WRAP_METHOD(bool set_filename(const std::string& filename), gtk_file_chooser_set_filename)
  _WRAP_METHOD(bool select_filename(const std::string& filename), gtk_file_chooser_select_filename)
  _WRAP_METHOD(void unselect_filename(const std::string& filename), gtk_file_chooser_unselect_filename)
  _WRAP_METHOD(void select_all(), gtk_file_chooser_select_all)
  _WRAP_METHOD(void unselect_all(), gtk_file_chooser_unselect_all)

#m4 _CONVERSION(`GSList*',`std::vector<std::string>',`Glib::SListHandler<std::string>::slist_to_vector($3, Glib::OWNERSHIP_DEEP)')
  _WRAP_METHOD(std::vector<std::string> get_filenames() const, gtk_file_chooser_get_filenames)

  _WRAP_METHOD(bool set_current_folder(const std::string& filename), gtk_file_chooser_set_current_folder)
  _WRAP_METHOD(std::string get_current_folder() const, gtk_file_chooser_get_current_folder)


/* URI manipulation
 */
  _WRAP_METHOD(Glib::ustring get_uri() const, gtk_file_chooser_get_uri)
  _WRAP_METHOD(bool set_uri(const Glib::ustring& uri), gtk_file_chooser_set_uri)
  _WRAP_METHOD(bool select_uri(const Glib::ustring& uri), gtk_file_chooser_select_uri)
  _WRAP_METHOD(void unselect_uri(const Glib::ustring& uri), gtk_file_chooser_unselect_uri)
#m4 _CONVERSION(`GSList*',`std::vector<Glib::ustring>',`Glib::SListHandler<Glib::ustring>::slist_to_vector($3, Glib::OWNERSHIP_DEEP)')
  _WRAP_METHOD(std::vector<Glib::ustring> get_uris() const, gtk_file_chooser_get_uris)

  _WRAP_METHOD(bool set_current_folder_uri(const Glib::ustring& uri), gtk_file_chooser_set_current_folder_uri)
  _WRAP_METHOD(Glib::ustring get_current_folder_uri() const, gtk_file_chooser_get_current_folder_uri)

  _WRAP_METHOD(bool set_file(const Glib::RefPtr<const Gio::File>& file), gtk_file_chooser_set_file, errthrow)

  _WRAP_METHOD(bool select_file(const Glib::RefPtr<const Gio::File>& file), gtk_file_chooser_select_file, errthrow)
  _WRAP_METHOD(void unselect_file(const Glib::RefPtr<const Gio::File>& file), gtk_file_chooser_unselect_file)

#m4 _CONVERSION(`GSList*',`std::vector< Glib::RefPtr<Gio::File> >',`Glib::SListHandler< Glib::RefPtr<Gio::File> >::slist_to_vector($3, Glib::OWNERSHIP_DEEP)')
  _WRAP_METHOD(std::vector< Glib::RefPtr<Gio::File> > get_files(), gtk_file_chooser_get_files)

  _WRAP_METHOD(bool set_current_folder_file(const Glib::RefPtr<const Gio::File>& file), gtk_file_chooser_set_current_folder_file, errthrow)

  //No refreturn is needed here, because the C function provides a reference:
  _WRAP_METHOD(Glib::RefPtr<Gio::File> get_current_folder_file(), gtk_file_chooser_get_current_folder_file)

  //No refreturn is needed here, because the C function provides a reference:
  _WRAP_METHOD(Glib::RefPtr<Gio::File> get_file(), gtk_file_chooser_get_file)
  _WRAP_METHOD(Glib::RefPtr<const Gio::File> get_file() const, gtk_file_chooser_get_file, constversion)

/* Preview widget
 */
  _WRAP_METHOD(void set_preview_widget(Gtk::Widget& preview_widget), gtk_file_chooser_set_preview_widget)

  _WRAP_METHOD(Gtk::Widget* get_preview_widget(), gtk_file_chooser_get_preview_widget)
  _WRAP_METHOD(const Gtk::Widget* get_preview_widget() const, gtk_file_chooser_get_preview_widget, constversion)

  _WRAP_METHOD(void set_preview_widget_active(bool active = true), gtk_file_chooser_set_preview_widget_active)
  _WRAP_METHOD(bool get_preview_widget_active() const, gtk_file_chooser_get_preview_widget_active)

  _WRAP_METHOD(void set_use_preview_label(bool use_label = true), gtk_file_chooser_set_use_preview_label)
  _WRAP_METHOD(bool get_use_preview_label() const, gtk_file_chooser_get_use_preview_label)

#m4 _CONVERSION(`return-char*',`std::string',`Glib::convert_return_gchar_ptr_to_stdstring($3)')
  _WRAP_METHOD(std::string get_preview_filename() const, gtk_file_chooser_get_preview_filename)
  _WRAP_METHOD(Glib::ustring get_preview_uri() const, gtk_file_chooser_get_preview_uri)

  //No refreturn is needed here, because the C function provides a reference:
  _WRAP_METHOD(Glib::RefPtr<Gio::File> get_preview_file(), gtk_file_chooser_get_preview_file)
  _WRAP_METHOD(Glib::RefPtr<const Gio::File> get_preview_file() const, gtk_file_chooser_get_preview_file, constversion)

/* Extra widget
 */
  _WRAP_METHOD(void set_extra_widget(Gtk::Widget& extra_widget), gtk_file_chooser_set_extra_widget)
  _WRAP_METHOD(Gtk::Widget* get_extra_widget(), gtk_file_chooser_get_extra_widget)
  _WRAP_METHOD(const Gtk::Widget* get_extra_widget() const, gtk_file_chooser_get_extra_widget, constversion)

/* List of user selectable filters
 */
  _WRAP_METHOD(void add_filter(const Glib::RefPtr<FileFilter>& filter), gtk_file_chooser_add_filter)
  _WRAP_METHOD(void remove_filter (const Glib::RefPtr<FileFilter>& filter), gtk_file_chooser_remove_filter)

#m4 _CONVERSION(`GSList*',`std::vector< Glib::RefPtr<FileFilter> >',`Glib::SListHandler< Glib::RefPtr<FileFilter> >::slist_to_vector($3, Glib::OWNERSHIP_SHALLOW)')
#m4 _CONVERSION(`GSList*',`std::vector< Glib::RefPtr<const FileFilter> >',`Glib::SListHandler< Glib::RefPtr<const FileFilter> >::slist_to_vector($3, Glib::OWNERSHIP_SHALLOW)')
  _WRAP_METHOD(std::vector< Glib::RefPtr<FileFilter> > list_filters(), gtk_file_chooser_list_filters)
  _WRAP_METHOD(std::vector< Glib::RefPtr<const FileFilter> > list_filters() const, gtk_file_chooser_list_filters)

/* Current filter
 */
  _WRAP_METHOD(void set_filter(const Glib::RefPtr<FileFilter>& filter), gtk_file_chooser_set_filter)
  _WRAP_METHOD(Glib::RefPtr<FileFilter> get_filter(), gtk_file_chooser_get_filter, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const FileFilter> get_filter() const, gtk_file_chooser_get_filter, refreturn, constversion)

/* Per-application shortcut folders */

  _WRAP_METHOD(bool add_shortcut_folder(const std::string& folder), gtk_file_chooser_add_shortcut_folder, errthrow)
  _WRAP_METHOD(bool remove_shortcut_folder(const std::string& folder), gtk_file_chooser_remove_shortcut_folder, errthrow)

  _WRAP_METHOD(std::vector<std::string> list_shortcut_folders() const, gtk_file_chooser_list_shortcut_folders)

  _WRAP_METHOD(bool add_shortcut_folder_uri(const Glib::ustring& uri), gtk_file_chooser_add_shortcut_folder_uri, errthrow)
  _WRAP_METHOD(bool remove_shortcut_folder_uri(const Glib::ustring& uri), gtk_file_chooser_remove_shortcut_folder_uri, errthrow)
  _WRAP_METHOD(std::vector<Glib::ustring> list_shortcut_folder_uris() const, gtk_file_chooser_list_shortcut_folder_uris)

#m4 _CONVERSION(`const std::vector<Glib::ustring>&',`const char**',`Glib::ArrayHandler<Glib::ustring>::vector_to_array($3).data ()')
  _WRAP_METHOD(void add_choice(const Glib::ustring& id, const Glib::ustring& label, const std::vector<Glib::ustring>& options, const std::vector<Glib::ustring>& option_labels), gtk_file_chooser_add_choice)

  /** Adds a boolean 'choice' to the file chooser.
   * This is typically implemented as a checkbutton. You can select
   * a value using set_boolean_choice() before the dialog is shown,
   * and you can obtain the user-selected value in the signal_response() signal handler
   * using get_choice().
   *
   * Compare set_extra_widget().
   *
   * @newin{3,22}
   *
   * @param id Id for the added choice.
   * @param label User-visible label for the added choice.
   */
  void add_choice(const Glib::ustring& id, const Glib::ustring& label);

  _WRAP_METHOD(void remove_choice(const Glib::ustring& id), gtk_file_chooser_remove_choice)
  _WRAP_METHOD(void set_choice(const Glib::ustring& id, const Glib::ustring& option), gtk_file_chooser_set_choice)
  _WRAP_METHOD(Glib::ustring get_choice(const Glib::ustring& id) const, gtk_file_chooser_get_choice)

  _WRAP_SIGNAL(void current_folder_changed(), "current_folder_changed", no_default_handler)
  _WRAP_SIGNAL(void selection_changed(), "selection_changed", no_default_handler)
  _WRAP_SIGNAL(void update_preview(), "update_preview", no_default_handler)
  _WRAP_SIGNAL(void file_activated(), "file_activated", no_default_handler)
  _WRAP_SIGNAL(FileChooserConfirmation confirm_overwrite(), "confirm-overwrite", no_default_handler)

  _WRAP_PROPERTY("action", FileChooserAction)
  _WRAP_PROPERTY("filter", Glib::RefPtr<FileFilter>)
  _WRAP_PROPERTY("local-only", bool)
  _WRAP_PROPERTY("preview-widget", Widget*)
  _WRAP_PROPERTY("preview-widget-active", bool)
  _WRAP_PROPERTY("use-preview-label", bool)
  _WRAP_PROPERTY("extra-widget", Widget*)
  _WRAP_PROPERTY("select-multiple", bool)
  _WRAP_PROPERTY("show-hidden", bool)
  _WRAP_PROPERTY("do-overwrite-confirmation", bool)
  _WRAP_PROPERTY("create-folders", bool)
};

} // namespace Gtk
