architecture and implementation for preferences searching
Metadata is only defined for a single region at this point, (much) more to come.
This commit is contained in:
parent
09acd5f8b4
commit
15434456d5
|
@ -28,6 +28,7 @@
|
|||
#include <gtkmm/box.h>
|
||||
#include <gtkmm/alignment.h>
|
||||
#include "gtkmm2ext/utils.h"
|
||||
#include "gtkmm2ext/colors.h"
|
||||
|
||||
#include "ardour/dB.h"
|
||||
#include "ardour/rc_configuration.h"
|
||||
|
@ -36,12 +37,16 @@
|
|||
#include "ardour/utils.h"
|
||||
|
||||
#include "pbd/configuration.h"
|
||||
#include "pbd/match.h"
|
||||
#include "pbd/replace_all.h"
|
||||
#include "pbd/strsplit.h"
|
||||
|
||||
#include "widgets/frame.h"
|
||||
|
||||
#include "gui_thread.h"
|
||||
#include "option_editor.h"
|
||||
#include "public_editor.h"
|
||||
#include "ui_config.h"
|
||||
#include "utils.h"
|
||||
#include "pbd/i18n.h"
|
||||
|
||||
|
@ -58,9 +63,13 @@ OptionEditorComponent::add_widget_to_page (OptionEditorPage* p, Gtk::Widget* w)
|
|||
if (!_note.empty ()) {
|
||||
++m;
|
||||
}
|
||||
_frame = manage (new ArdourWidgets::Frame);
|
||||
_frame->add (*w);
|
||||
_frame->set_draw (false);
|
||||
_frame->set_edge_color (UIConfiguration::instance().color (X_("preference highlight")));
|
||||
|
||||
p->table.resize (m, 3);
|
||||
p->table.attach (*w, 1, 3, n, n + 1, FILL | EXPAND);
|
||||
p->table.attach (*_frame, 1, 3, n, n + 1, FILL | EXPAND);
|
||||
|
||||
maybe_add_note (p, n + 1);
|
||||
}
|
||||
|
@ -74,8 +83,13 @@ OptionEditorComponent::add_widgets_to_page (OptionEditorPage* p, Gtk::Widget* wa
|
|||
++m;
|
||||
}
|
||||
|
||||
_frame = manage (new ArdourWidgets::Frame);
|
||||
_frame->add (*wa);
|
||||
_frame->set_draw (false);
|
||||
_frame->set_edge_color (UIConfiguration::instance().color (X_("preference highlight")));
|
||||
|
||||
p->table.resize (m, 3);
|
||||
p->table.attach (*wa, 1, 2, n, n + 1, FILL);
|
||||
p->table.attach (*_frame, 1, 2, n, n + 1, FILL);
|
||||
|
||||
Alignment* a = manage (new Alignment (0, 0.5, 0, 1.0));
|
||||
a->add (*wb);
|
||||
|
@ -101,6 +115,44 @@ OptionEditorComponent::set_note (string const & n)
|
|||
_note = n;
|
||||
}
|
||||
|
||||
void
|
||||
OptionEditorComponent::highlight ()
|
||||
{
|
||||
if (_frame) {
|
||||
_frame->set_draw (true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OptionEditorComponent::end_highlight ()
|
||||
{
|
||||
if (_frame) {
|
||||
_frame->set_draw (false);
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
OptionEditorComponent::get_metadata () const
|
||||
{
|
||||
if (!_metadata.empty()) {
|
||||
return _metadata;
|
||||
}
|
||||
|
||||
gchar* tt = gtk_widget_get_tooltip_text (const_cast<OptionEditorComponent*>(this)->tip_widget().gobj());
|
||||
|
||||
if (tt) {
|
||||
return tt;
|
||||
}
|
||||
|
||||
return string();
|
||||
}
|
||||
|
||||
void
|
||||
OptionEditorComponent::set_metadata (std::string const & str)
|
||||
{
|
||||
_metadata = str;
|
||||
}
|
||||
|
||||
/*--------------------------*/
|
||||
|
||||
OptionEditorHeading::OptionEditorHeading (string const & h)
|
||||
|
@ -747,6 +799,8 @@ OptionEditorMiniPage::add_to_page (OptionEditorPage* p)
|
|||
OptionEditor::OptionEditor (PBD::Configuration* c)
|
||||
: _config (c)
|
||||
, option_tree (TreeStore::create (option_columns))
|
||||
, search_results (0)
|
||||
, search_not_found_count (0)
|
||||
, option_treeview (option_tree)
|
||||
{
|
||||
using namespace Notebook_Helpers;
|
||||
|
@ -766,6 +820,18 @@ OptionEditor::OptionEditor (PBD::Configuration* c)
|
|||
|
||||
/* Watch out for changes to parameters */
|
||||
_config->ParameterChanged.connect (config_connection, invalidator (*this), boost::bind (&OptionEditor::parameter_changed, this, _1), gui_context());
|
||||
|
||||
search_entry.show ();
|
||||
search_entry.set_text (_("Search here..."));
|
||||
search_entry.set_name (X_("ShadedEntry"));
|
||||
set_size_request_to_display_given_text (search_entry, X_("a long enough search string"), 2, 2);
|
||||
search_packer.pack_start (search_entry, true, true);
|
||||
search_packer.show ();
|
||||
|
||||
search_entry.signal_activate().connect (sigc::mem_fun (*this, &OptionEditor::search));
|
||||
search_entry.signal_key_press_event().connect (sigc::mem_fun (*this, &OptionEditor::search_key_press), false);
|
||||
search_entry.signal_focus_in_event().connect (sigc::mem_fun (*this, &OptionEditor::search_key_focus), false);
|
||||
search_entry.signal_focus_out_event().connect (sigc::mem_fun (*this, &OptionEditor::search_key_focus), false);
|
||||
}
|
||||
|
||||
OptionEditor::~OptionEditor ()
|
||||
|
@ -778,6 +844,124 @@ OptionEditor::~OptionEditor ()
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
OptionEditor::search_key_focus (GdkEventFocus* ev)
|
||||
{
|
||||
if (ev->in) {
|
||||
if (search_entry.get_name () == X_("ShadedEntry")) {
|
||||
search_entry.set_text ("");
|
||||
search_entry.set_name (X_("GtkEntry"));
|
||||
}
|
||||
} else {
|
||||
if (search_entry.get_text().empty() && search_entry.get_name () != X_("ShadedEntry")) {
|
||||
search_entry.set_text (_("Search here..."));
|
||||
search_entry.set_name (X_("ShadedEntry"));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
OptionEditor::search_key_press (GdkEventKey* ev)
|
||||
{
|
||||
if (search_entry.get_name () == X_("ShadedEntry")) {
|
||||
search_entry.set_text ("");
|
||||
search_entry.set_name (X_("GtkEntry"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
OptionEditor::search ()
|
||||
{
|
||||
string search_for = search_entry.get_text();
|
||||
|
||||
not_found_callback ();
|
||||
|
||||
if (search_for.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!search_results || search_for != last_search_string) {
|
||||
|
||||
/* (re)build search results */
|
||||
|
||||
delete search_results;
|
||||
search_results = new std::vector<SearchResult>;
|
||||
|
||||
for (auto p : pages()) {
|
||||
for (auto oc : p.second->components) {
|
||||
string metadata (oc->get_metadata());
|
||||
if (PBD::match_search_strings (metadata, search_for)) {
|
||||
search_results->push_back (SearchResult (p.first, *oc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (search_results->empty()) {
|
||||
not_found ();
|
||||
delete search_results;
|
||||
search_results = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
last_search_string = search_for;
|
||||
search_iterator = search_results->begin ();
|
||||
|
||||
} else {
|
||||
|
||||
/* have results and still searching for the same string. End
|
||||
* highlight of previous find (if not at end) and move on to
|
||||
* the next if we can.
|
||||
*/
|
||||
|
||||
if (search_iterator != search_results->end()) {
|
||||
search_iterator->component.end_highlight ();
|
||||
++search_iterator;
|
||||
}
|
||||
|
||||
if (search_iterator == search_results->end()) {
|
||||
|
||||
search_iterator = search_results->begin();
|
||||
search_highlight ((*search_iterator).page_title, (*search_iterator).component);
|
||||
search_iterator++;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move to next result, and highlight it */
|
||||
|
||||
search_highlight ((*search_iterator).page_title, (*search_iterator).component);
|
||||
}
|
||||
|
||||
void
|
||||
OptionEditor::not_found ()
|
||||
{
|
||||
search_entry.set_sensitive (false);
|
||||
not_found_timeout = Glib::signal_timeout().connect (mem_fun (*this, &OptionEditor::not_found_callback), 250);
|
||||
search_not_found_count++;
|
||||
}
|
||||
|
||||
bool
|
||||
OptionEditor::not_found_callback ()
|
||||
{
|
||||
search_entry.set_sensitive (true);
|
||||
search_entry.grab_focus ();
|
||||
search_not_found_count = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
OptionEditor::search_highlight (std::string const & page_title, OptionEditorComponent& component)
|
||||
{
|
||||
if (current_page() != page_title) {
|
||||
set_current_page (page_title);
|
||||
}
|
||||
component.highlight ();
|
||||
}
|
||||
|
||||
|
||||
/** Called when a configuration parameter has been changed.
|
||||
* @param p Parameter name.
|
||||
*/
|
||||
|
@ -793,6 +977,20 @@ OptionEditor::parameter_changed (std::string const & p)
|
|||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
OptionEditor::current_page ()
|
||||
{
|
||||
Glib::RefPtr<Gtk::TreeSelection> selection = option_treeview.get_selection();
|
||||
TreeModel::const_iterator iter = selection->get_selected();
|
||||
|
||||
if (iter) {
|
||||
TreeModel::Row row = *iter;
|
||||
return row[option_columns.name];
|
||||
}
|
||||
|
||||
return string();
|
||||
}
|
||||
|
||||
void
|
||||
OptionEditor::treeview_row_selected ()
|
||||
{
|
||||
|
@ -964,7 +1162,9 @@ OptionEditorContainer::OptionEditorContainer (PBD::Configuration* c)
|
|||
f->add (treeview());
|
||||
f->set_shadow_type (Gtk::SHADOW_OUT);
|
||||
f->set_border_width (0);
|
||||
hpacker.pack_start (*f, false, false, 4);
|
||||
treeview_packer.pack_start (*f, true, true);
|
||||
|
||||
hpacker.pack_start (treeview_packer, false, false, 4);
|
||||
hpacker.pack_start (notebook(), false, false);
|
||||
pack_start (hpacker, true, true);
|
||||
|
||||
|
@ -975,18 +1175,19 @@ OptionEditorWindow::OptionEditorWindow (PBD::Configuration* c, string const& str
|
|||
: OptionEditor (c)
|
||||
, ArdourWindow (str)
|
||||
{
|
||||
container.set_border_width (4);
|
||||
hpacker.set_border_width (4);
|
||||
Frame* f = manage (new Frame ());
|
||||
|
||||
f->add (treeview());
|
||||
f->set_shadow_type (Gtk::SHADOW_OUT);
|
||||
f->set_border_width (0);
|
||||
hpacker.pack_start (*f, false, false);
|
||||
vpacker.pack_start (*f, true, true);
|
||||
|
||||
hpacker.pack_start (vpacker, false, false);
|
||||
hpacker.pack_start (notebook(), true, true, 4);
|
||||
|
||||
container.pack_start (hpacker, true, true);
|
||||
|
||||
hpacker.show_all ();
|
||||
container.show ();
|
||||
vpacker.show ();
|
||||
|
||||
add (container);
|
||||
add (hpacker);
|
||||
}
|
||||
|
|
|
@ -64,12 +64,17 @@ namespace PBD {
|
|||
class Configuration;
|
||||
}
|
||||
|
||||
namespace ArdourWidgets {
|
||||
class Frame;
|
||||
}
|
||||
|
||||
class OptionEditorPage;
|
||||
|
||||
/** Base class for components of an OptionEditor dialog */
|
||||
class OptionEditorComponent
|
||||
{
|
||||
public:
|
||||
OptionEditorComponent() : _frame (0) {}
|
||||
virtual ~OptionEditorComponent() {}
|
||||
|
||||
/** Called when a configuration parameter's value has changed.
|
||||
|
@ -90,10 +95,18 @@ public:
|
|||
|
||||
virtual Gtk::Widget& tip_widget() = 0;
|
||||
|
||||
virtual std::string get_metadata() const;
|
||||
void set_metadata (std::string const &);
|
||||
|
||||
void highlight ();
|
||||
void end_highlight ();
|
||||
|
||||
protected:
|
||||
void maybe_add_note (OptionEditorPage *, int);
|
||||
|
||||
std::string _note;
|
||||
ArdourWidgets::Frame* _frame;
|
||||
std::string _metadata;
|
||||
};
|
||||
|
||||
/** A component which provides a subheading within the dialog */
|
||||
|
@ -705,7 +718,9 @@ public:
|
|||
void add_option (std::string const &, OptionEditorComponent *);
|
||||
void add_page (std::string const &, Gtk::Widget& page_widget);
|
||||
|
||||
std::string current_page (); /* ought to be const but .. hard */
|
||||
void set_current_page (std::string const &);
|
||||
std::map<std::string, OptionEditorPage*>& pages() { return _pages; }
|
||||
|
||||
protected:
|
||||
virtual void parameter_changed (std::string const &);
|
||||
|
@ -729,6 +744,32 @@ protected:
|
|||
OptionColumns option_columns;
|
||||
Glib::RefPtr<Gtk::TreeStore> option_tree;
|
||||
|
||||
/* searching */
|
||||
|
||||
Gtk::Entry search_entry;
|
||||
Gtk::Label search_label;
|
||||
Gtk::Button search_button;
|
||||
Gtk::HBox search_packer;
|
||||
struct SearchResult {
|
||||
SearchResult (std::string const & p, OptionEditorComponent& c) : page_title (p), component (c) {}
|
||||
|
||||
std::string page_title;
|
||||
OptionEditorComponent& component;
|
||||
};
|
||||
typedef std::vector<SearchResult> SearchResults;
|
||||
SearchResults* search_results;
|
||||
SearchResults::iterator search_iterator;
|
||||
std::string last_search_string;
|
||||
int search_not_found_count;
|
||||
sigc::connection not_found_timeout;
|
||||
|
||||
void search ();
|
||||
void search_highlight (std::string const & page_title, OptionEditorComponent&);
|
||||
bool not_found_callback ();
|
||||
bool search_key_press (GdkEventKey*);
|
||||
bool search_key_focus (GdkEventFocus*);
|
||||
void not_found ();
|
||||
|
||||
private:
|
||||
PBD::ScopedConnection config_connection;
|
||||
Gtk::Notebook _notebook;
|
||||
|
@ -747,7 +788,8 @@ class OptionEditorContainer : public OptionEditor, public Gtk::VBox
|
|||
public:
|
||||
OptionEditorContainer (PBD::Configuration *);
|
||||
~OptionEditorContainer() {}
|
||||
private:
|
||||
|
||||
Gtk::VBox treeview_packer;
|
||||
Gtk::HBox hpacker;
|
||||
};
|
||||
|
||||
|
@ -757,8 +799,8 @@ class OptionEditorWindow : public OptionEditor, public ArdourWindow
|
|||
public:
|
||||
OptionEditorWindow (PBD::Configuration *, std::string const &);
|
||||
~OptionEditorWindow() {}
|
||||
private:
|
||||
Gtk::VBox container;
|
||||
protected:
|
||||
Gtk::VBox vpacker;
|
||||
Gtk::HBox hpacker;
|
||||
};
|
||||
|
||||
|
|
|
@ -1133,6 +1133,7 @@ class FontScalingOptions : public HSliderOption
|
|||
_hscale.add_mark(250, Gtk::POS_TOP, empty);
|
||||
|
||||
set_note (_("Adjusting the scale requires an application restart for fully accurate re-layout."));
|
||||
set_metadata (_("fonts font size scaling readable readability"));
|
||||
}
|
||||
|
||||
void changed ()
|
||||
|
@ -3800,7 +3801,7 @@ These settings will only take effect after %1 is restarted.\n\
|
|||
add_option (_("Transport"), bo);
|
||||
Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
|
||||
_("<b>When enabled</b> plugins will be reset at transport stop. When disabled plugins will be left unchanged at transport stop.\n\nThis mostly affects plugins with a \"tail\" like Reverbs."));
|
||||
|
||||
bo->highlight ();
|
||||
/* PLUGINS ******************************************************************/
|
||||
|
||||
#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined VST3_SUPPORT)
|
||||
|
@ -4809,6 +4810,10 @@ These settings will only take effect after %1 is restarted.\n\
|
|||
}
|
||||
|
||||
set_current_page (_("General"));
|
||||
|
||||
/* Place the search entry */
|
||||
|
||||
treeview_packer.pack_end (search_packer, false, false);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -91,3 +91,4 @@ private:
|
|||
};
|
||||
|
||||
#endif /* __gtk_ardour_rc_option_editor_h__ */
|
||||
|
||||
|
|
|
@ -422,6 +422,10 @@ SessionOptionEditor::SessionOptionEditor (Session* s)
|
|||
add_option (_("Misc"), new FooOption (btn));
|
||||
|
||||
set_current_page (_("Timecode"));
|
||||
|
||||
/* Place the search entry */
|
||||
|
||||
vpacker.pack_end (search_packer, false, false);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in New Issue