diff --git a/rtdata/themes/RawTherapee-GTK3-20_.css b/rtdata/themes/RawTherapee-GTK3-20_.css index 94886d6fb..b0a7ac071 100644 --- a/rtdata/themes/RawTherapee-GTK3-20_.css +++ b/rtdata/themes/RawTherapee-GTK3-20_.css @@ -903,3 +903,13 @@ paned > separator { #PartialPasteHeaderSep { background-color: #D8D8D8; } + +/* All MyFileChooserButtons */ +button#MyFileChooserButton { + padding: 2px; + margin: 2px; +} + +#ToolPanelNotebook button { + margin: 0px; +} diff --git a/rtdata/themes/RawTherapee-GTK3-_19.css b/rtdata/themes/RawTherapee-GTK3-_19.css index 8263dd857..8443768c3 100644 --- a/rtdata/themes/RawTherapee-GTK3-_19.css +++ b/rtdata/themes/RawTherapee-GTK3-_19.css @@ -500,3 +500,9 @@ GtkNotebook { #PartialPasteHeaderSep { color: #D8D8D8; } + + +#MyFileChooserButton { + padding-left: 3px; + padding-right: 3px; +} diff --git a/rtgui/darkframe.cc b/rtgui/darkframe.cc index 83bad565a..ab9156d7d 100644 --- a/rtgui/darkframe.cc +++ b/rtgui/darkframe.cc @@ -46,7 +46,7 @@ DarkFrame::DarkFrame () : FoldableToolPanel(this, "darkframe", M("TP_DARKFRAME_L pack_start( *dfInfo, Gtk::PACK_SHRINK, 0); dfautoconn = dfAuto->signal_toggled().connect ( sigc::mem_fun(*this, &DarkFrame::dfAutoChanged), true); - dfFile = darkFrameFile->signal_file_set().connect ( sigc::mem_fun(*this, &DarkFrame::darkFrameChanged), true); + dfFile = darkFrameFile->signal_file_set().connect ( sigc::mem_fun(*this, &DarkFrame::darkFrameChanged)); //, true); btnReset->signal_clicked().connect( sigc::mem_fun(*this, &DarkFrame::darkFrameReset), true ); // Set filename filters diff --git a/rtgui/flatfield.cc b/rtgui/flatfield.cc index aec6820a5..5b52ce9d2 100644 --- a/rtgui/flatfield.cc +++ b/rtgui/flatfield.cc @@ -78,7 +78,7 @@ FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_L pack_start( *flatFieldBlurRadius, Gtk::PACK_SHRINK, 0); pack_start( *flatFieldClipControl, Gtk::PACK_SHRINK, 0); - flatFieldFileconn = flatFieldFile->signal_file_set().connect ( sigc::mem_fun(*this, &FlatField::flatFieldFileChanged), true); + flatFieldFileconn = flatFieldFile->signal_file_set().connect ( sigc::mem_fun(*this, &FlatField::flatFieldFileChanged)); //, true); flatFieldFileReset->signal_clicked().connect( sigc::mem_fun(*this, &FlatField::flatFieldFile_Reset), true ); flatFieldAutoSelectconn = flatFieldAutoSelect->signal_toggled().connect ( sigc::mem_fun(*this, &FlatField::flatFieldAutoSelectChanged), true); flatFieldBlurTypeconn = flatFieldBlurType->signal_changed().connect( sigc::mem_fun(*this, &FlatField::flatFieldBlurTypeChanged) ); diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index a72889404..49ce25b60 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -1168,9 +1168,174 @@ bool MyHScale::on_key_press_event (GdkEventKey* event) } } -MyFileChooserButton::MyFileChooserButton (const Glib::ustring& title, Gtk::FileChooserAction action) : Gtk::FileChooserButton(title, action) +MyFileChooserButton::MyFileChooserButton(const Glib::ustring &title, Gtk::FileChooserAction action): + title_(title), + action_(action), + lbl_("", Gtk::ALIGN_START), + show_hidden_(false) { - //set_size_request(35, -1); + lbl_.set_ellipsize(Pango::ELLIPSIZE_MIDDLE); + lbl_.set_justify(Gtk::JUSTIFY_LEFT); + set_none(); + box_.pack_start(lbl_, true, true); + Gtk::Image *img = Gtk::manage(new Gtk::Image()); + img->set_from_icon_name("document-open", Gtk::ICON_SIZE_BUTTON); + box_.pack_start(*Gtk::manage(new Gtk::VSeparator()), false, false, 5); + box_.pack_start(*img, false, false); + box_.show_all_children(); + add(box_); + signal_clicked().connect(sigc::mem_fun(*this, &MyFileChooserButton::show_chooser)); + + if (GTK_MINOR_VERSION < 20) { + set_border_width(2); // margin doesn't work on GTK < 3.20 + } + + set_name("MyFileChooserButton"); +} + + +void MyFileChooserButton::show_chooser() +{ + Gtk::FileChooserDialog dlg(getToplevelWindow(this), title_, action_); + dlg.add_button(M("GENERAL_CANCEL"), Gtk::RESPONSE_CANCEL); + dlg.add_button(M(action_ == Gtk::FILE_CHOOSER_ACTION_SAVE ? "GENERAL_SAVE" : "GENERAL_OPEN"), Gtk::RESPONSE_OK); + dlg.set_filename(filename_); + for (auto &f : file_filters_) { + dlg.add_filter(f); + } + if (cur_filter_) { + dlg.set_filter(cur_filter_); + } + for (auto &f : shortcut_folders_) { + dlg.add_shortcut_folder(f); + } + if (!current_folder_.empty()) { + dlg.set_current_folder(current_folder_); + } + dlg.set_show_hidden(show_hidden_); + int res = dlg.run(); + if (res == Gtk::RESPONSE_OK) { + filename_ = dlg.get_filename(); + current_folder_ = dlg.get_current_folder(); + lbl_.set_label(Glib::path_get_basename(filename_)); + selection_changed_.emit(); + } +} + + +sigc::signal &MyFileChooserButton::signal_selection_changed() +{ + return selection_changed_; +} + + +sigc::signal &MyFileChooserButton::signal_file_set() +{ + return selection_changed_; +} + + +std::string MyFileChooserButton::get_filename() const +{ + return filename_; +} + + +bool MyFileChooserButton::set_filename(const std::string &filename) +{ + filename_ = filename; + if (Glib::file_test(filename_, Glib::FILE_TEST_EXISTS)) { + lbl_.set_label(Glib::path_get_basename(filename_)); + } else { + set_none(); + } + return true; +} + + +void MyFileChooserButton::add_filter(const Glib::RefPtr &filter) +{ + file_filters_.push_back(filter); +} + + +void MyFileChooserButton::remove_filter(const Glib::RefPtr &filter) +{ + auto it = std::find(file_filters_.begin(), file_filters_.end(), filter); + if (it != file_filters_.end()) { + file_filters_.erase(it); + } +} + + +void MyFileChooserButton::set_filter(const Glib::RefPtr &filter) +{ + cur_filter_ = filter; +} + + +std::vector> MyFileChooserButton::list_filters() +{ + return file_filters_; +} + + +bool MyFileChooserButton::set_current_folder(const std::string &filename) +{ + current_folder_ = filename; + if (action_ == Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) { + set_filename(filename); + } + return true; +} + +std::string MyFileChooserButton::get_current_folder() const +{ + return current_folder_; +} + + +bool MyFileChooserButton::add_shortcut_folder(const std::string &folder) +{ + shortcut_folders_.push_back(folder); + return true; +} + + +bool MyFileChooserButton::remove_shortcut_folder(const std::string &folder) +{ + auto it = std::find(shortcut_folders_.begin(), shortcut_folders_.end(), folder); + if (it != shortcut_folders_.end()) { + shortcut_folders_.erase(it); + } + return true; +} + + +void MyFileChooserButton::unselect_all() +{ + filename_ = ""; + set_none(); +} + + +void MyFileChooserButton::unselect_filename(const std::string &filename) +{ + if (filename_ == filename) { + unselect_all(); + } +} + + +void MyFileChooserButton::set_show_hidden(bool yes) +{ + show_hidden_ = yes; +} + + +void MyFileChooserButton::set_none() +{ + lbl_.set_label(Glib::ustring("(") + M("GENERAL_NONE") + ")"); } // For an unknown reason (a bug ?), it doesn't work when action = FILE_CHOOSER_ACTION_SELECT_FOLDER ! @@ -1179,7 +1344,7 @@ bool MyFileChooserButton::on_scroll_event (GdkEventScroll* event) // If Shift is pressed, the widget is modified if (event->state & GDK_SHIFT_MASK) { - Gtk::FileChooserButton::on_scroll_event(event); + Gtk::Button::on_scroll_event(event); return true; } @@ -1197,19 +1362,6 @@ void MyFileChooserButton::get_preferred_width_for_height_vfunc (int height, int } -void bindCurrentFolder (Gtk::FileChooser& chooser, Glib::ustring& variable) -{ - chooser.signal_selection_changed ().connect ([&]() - { - const auto current_folder = chooser.get_current_folder (); - - if (!current_folder.empty ()) - variable = current_folder; - }); - - if (!variable.empty ()) - chooser.set_current_folder (variable); -} TextOrIcon::TextOrIcon (Glib::ustring fname, Glib::ustring labelTx, Glib::ustring tooltipTx, TOITypes type) { diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 7a71fc399..2861b4913 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -358,22 +358,72 @@ class MyHScale : public Gtk::HScale /** * @brief subclass of Gtk::FileChooserButton in order to handle the scrollwheel */ -class MyFileChooserButton : public Gtk::FileChooserButton -{ +class MyFileChooserButton: public Gtk::Button { +private: + void show_chooser(); + + Glib::ustring title_; + Gtk::FileChooserAction action_; + Gtk::HBox box_; + Gtk::Label lbl_; + std::string filename_; + std::string current_folder_; + std::vector> file_filters_; + Glib::RefPtr cur_filter_; + std::vector shortcut_folders_; + bool show_hidden_; + sigc::signal selection_changed_; protected: bool on_scroll_event (GdkEventScroll* event); void get_preferred_width_vfunc (int &minimum_width, int &natural_width) const; void get_preferred_width_for_height_vfunc (int height, int &minimum_width, int &natural_width) const; + void set_none(); + public: - MyFileChooserButton (const Glib::ustring& title, Gtk::FileChooserAction action = Gtk::FILE_CHOOSER_ACTION_OPEN); + MyFileChooserButton(const Glib::ustring &title, Gtk::FileChooserAction action=Gtk::FILE_CHOOSER_ACTION_OPEN); + + sigc::signal &signal_selection_changed(); + sigc::signal &signal_file_set(); + + std::string get_filename() const; + bool set_filename(const std::string &filename); + + void add_filter(const Glib::RefPtr &filter); + void remove_filter(const Glib::RefPtr &filter); + void set_filter(const Glib::RefPtr &filter); + std::vector> list_filters(); + + bool set_current_folder(const std::string &filename); + std::string get_current_folder() const; + + bool add_shortcut_folder(const std::string &folder); + bool remove_shortcut_folder(const std::string &folder); + + void unselect_all(); + void unselect_filename(const std::string &filename); + + void set_show_hidden(bool yes); }; /** * @brief A helper method to connect the current folder property of a file chooser to an arbitrary variable. */ -void bindCurrentFolder (Gtk::FileChooser& chooser, Glib::ustring& variable); +template +void bindCurrentFolder (FileChooser& chooser, Glib::ustring& variable) +{ + chooser.signal_selection_changed ().connect ([&]() + { + const auto current_folder = chooser.get_current_folder (); + + if (!current_folder.empty ()) + variable = current_folder; + }); + + if (!variable.empty ()) + chooser.set_current_folder (variable); +} typedef enum RTUpdatePolicy { RTUP_STATIC, diff --git a/rtgui/lensprofile.cc b/rtgui/lensprofile.cc index 6415c1fce..310c48d41 100644 --- a/rtgui/lensprofile.cc +++ b/rtgui/lensprofile.cc @@ -132,7 +132,7 @@ LensProfilePanel::LensProfilePanel () : ckbUseCA = Gtk::manage (new Gtk::CheckButton (M("TP_LENSPROFILE_USECA"))); pack_start (*ckbUseCA, Gtk::PACK_SHRINK, 4); - conLCPFile = fcbLCPFile->signal_file_set().connect( sigc::mem_fun(*this, &LensProfilePanel::onLCPFileChanged), true); + conLCPFile = fcbLCPFile->signal_file_set().connect( sigc::mem_fun(*this, &LensProfilePanel::onLCPFileChanged)); //, true); conUseDist = ckbUseDist->signal_toggled().connect( sigc::mem_fun(*this, &LensProfilePanel::onUseDistChanged) ); ckbUseVign->signal_toggled().connect( sigc::mem_fun(*this, &LensProfilePanel::onUseVignChanged) ); ckbUseCA->signal_toggled().connect( sigc::mem_fun(*this, &LensProfilePanel::onUseCAChanged) ); diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 974ba5450..e03542b3e 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -520,7 +520,7 @@ Gtk::Widget* Preferences::getProcParamsPanel () Gtk::Label *dfLab = Gtk::manage (new Gtk::Label (M ("PREFERENCES_DIRDARKFRAMES") + ":")); setExpandAlignProperties(dfLab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - darkFrameDir = Gtk::manage (new Gtk::FileChooserButton (M ("PREFERENCES_DIRDARKFRAMES"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + darkFrameDir = Gtk::manage (new MyFileChooserButton (M ("PREFERENCES_DIRDARKFRAMES"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); setExpandAlignProperties(darkFrameDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); dfLabel = Gtk::manage (new Gtk::Label ("Found:")); setExpandAlignProperties(dfLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); @@ -530,12 +530,12 @@ Gtk::Widget* Preferences::getProcParamsPanel () dirgrid->attach_next_to(*dfLabel, *darkFrameDir, Gtk::POS_RIGHT, 1, 1); //dfconn = darkFrameDir->signal_file_set().connect ( sigc::mem_fun(*this, &Preferences::darkFrameChanged), true); - dfconn = darkFrameDir->signal_selection_changed().connect ( sigc::mem_fun (*this, &Preferences::darkFrameChanged), true); + dfconn = darkFrameDir->signal_selection_changed().connect ( sigc::mem_fun (*this, &Preferences::darkFrameChanged)); //, true); // FLATFIELD Gtk::Label *ffLab = Gtk::manage (new Gtk::Label (M ("PREFERENCES_FLATFIELDSDIR") + ":")); setExpandAlignProperties(ffLab, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - flatFieldDir = Gtk::manage (new Gtk::FileChooserButton (M ("PREFERENCES_FLATFIELDSDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + flatFieldDir = Gtk::manage (new MyFileChooserButton (M ("PREFERENCES_FLATFIELDSDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); setExpandAlignProperties(flatFieldDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); ffLabel = Gtk::manage (new Gtk::Label ("Found:")); setExpandAlignProperties(ffLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); @@ -545,12 +545,12 @@ Gtk::Widget* Preferences::getProcParamsPanel () dirgrid->attach_next_to(*ffLabel, *flatFieldDir, Gtk::POS_RIGHT, 1, 1); //ffconn = flatFieldDir->signal_file_set().connect ( sigc::mem_fun(*this, &Preferences::flatFieldChanged), true); - ffconn = flatFieldDir->signal_selection_changed().connect ( sigc::mem_fun (*this, &Preferences::flatFieldChanged), true); + ffconn = flatFieldDir->signal_selection_changed().connect ( sigc::mem_fun (*this, &Preferences::flatFieldChanged)); //, true); //Cluts Dir Gtk::Label *clutsDirLabel = Gtk::manage (new Gtk::Label (M ("PREFERENCES_CLUTSDIR") + ":")); setExpandAlignProperties(clutsDirLabel, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - clutsDir = Gtk::manage (new Gtk::FileChooserButton (M ("PREFERENCES_CLUTSDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + clutsDir = Gtk::manage (new MyFileChooserButton (M ("PREFERENCES_CLUTSDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); setExpandAlignProperties(clutsDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); Gtk::Label* clutsRestartNeeded = Gtk::manage ( new Gtk::Label (Glib::ustring (" (") + M ("PREFERENCES_APPLNEXTSTARTUP") + ")") ); setExpandAlignProperties(clutsRestartNeeded, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); @@ -720,7 +720,7 @@ Gtk::Widget* Preferences::getColorManagementPanel () Gtk::VBox* mvbcm = Gtk::manage (new Gtk::VBox ()); mvbcm->set_spacing (4); - iccDir = Gtk::manage (new Gtk::FileChooserButton (M ("PREFERENCES_ICCDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + iccDir = Gtk::manage (new MyFileChooserButton (M ("PREFERENCES_ICCDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); setExpandAlignProperties (iccDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); Gtk::Label* pdlabel = Gtk::manage (new Gtk::Label (M ("PREFERENCES_ICCDIR") + ":", Gtk::ALIGN_START)); setExpandAlignProperties (pdlabel, false, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); @@ -1207,7 +1207,7 @@ Gtk::Widget* Preferences::getGeneralPanel () edPS = Gtk::manage ( new Gtk::RadioButton (M ("PREFERENCES_PSPATH") + ":")); setExpandAlignProperties (edPS, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - psDir = Gtk::manage ( new Gtk::FileChooserButton (M ("PREFERENCES_PSPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) ); + psDir = Gtk::manage ( new MyFileChooserButton (M ("PREFERENCES_PSPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) ); setExpandAlignProperties (psDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); externaleditorGrid->attach_next_to (*edPS, *edGimp, Gtk::POS_BOTTOM, 1, 1); externaleditorGrid->attach_next_to (*psDir, *edPS, Gtk::POS_RIGHT, 1, 1); @@ -1218,7 +1218,7 @@ Gtk::Widget* Preferences::getGeneralPanel () #elif defined WIN32 edGimp = Gtk::manage ( new Gtk::RadioButton (M ("PREFERENCES_GIMPPATH") + ":") ); setExpandAlignProperties (edGimp, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - gimpDir = Gtk::manage ( new Gtk::FileChooserButton (M ("PREFERENCES_GIMPPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) ); + gimpDir = Gtk::manage ( new MyFileChooserButton (M ("PREFERENCES_GIMPPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) ); setExpandAlignProperties (gimpDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); externaleditorGrid->attach_next_to (*edGimp, Gtk::POS_TOP, 1, 1); externaleditorGrid->attach_next_to (*gimpDir, *edGimp, Gtk::POS_RIGHT, 1, 1); @@ -1226,7 +1226,7 @@ Gtk::Widget* Preferences::getGeneralPanel () edPS = Gtk::manage ( new Gtk::RadioButton (M ("PREFERENCES_PSPATH") + ":") ); setExpandAlignProperties (edPS, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - psDir = Gtk::manage ( new Gtk::FileChooserButton (M ("PREFERENCES_PSPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) ); + psDir = Gtk::manage ( new MyFileChooserButton (M ("PREFERENCES_PSPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) ); setExpandAlignProperties (psDir, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_CENTER); externaleditorGrid->attach_next_to (*edPS, *edGimp, Gtk::POS_BOTTOM, 1, 1); externaleditorGrid->attach_next_to (*psDir, *edPS, Gtk::POS_RIGHT, 1, 1); diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 3849a175e..b3efd8b6a 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -89,15 +89,15 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener Gtk::RadioButton* sdlast; Gtk::RadioButton* sdhome; Gtk::RadioButton* sdother; - Gtk::FileChooserButton* gimpDir; - Gtk::FileChooserButton* psDir; + MyFileChooserButton* gimpDir; + MyFileChooserButton* psDir; Gtk::Entry* editorToSendTo; Gtk::RadioButton* edGimp; Gtk::RadioButton* edPS; Gtk::RadioButton* edOther; - Gtk::FileChooserButton* darkFrameDir; - Gtk::FileChooserButton* flatFieldDir; - Gtk::FileChooserButton* clutsDir; + MyFileChooserButton* darkFrameDir; + MyFileChooserButton* flatFieldDir; + MyFileChooserButton* clutsDir; Gtk::Label *dfLabel; Gtk::Label *ffLabel; @@ -105,7 +105,7 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener Gtk::CheckButton* showBasicExif; Gtk::CheckButton* showExpComp; - Gtk::FileChooserButton* iccDir; + MyFileChooserButton* iccDir; Gtk::ComboBoxText* prtProfile; Gtk::ComboBoxText* prtIntent; Gtk::CheckButton* prtBPC;