31 set_column_types(
col);
35 Gtk::TreeModel::const_iterator i =
const_cast<PresetStore*
>(
this)->get_iter(path);
36 Glib::ustring s(i->get_value(
col.
name));
62 preset_row_del_conn(),
67 in_current_preset(false),
70 load_widget_pointers(bld);
71 actions.
new_bank = Gtk::Action::create(
"NewBank");
72 actions.
group->add(actions.
new_bank, sigc::mem_fun(*
this, &PresetWindow::on_new_bank));
73 gtk_activatable_set_related_action(GTK_ACTIVATABLE(new_preset_bank->gobj()), actions.
new_bank->gobj());
74 actions.
save_changes = Gtk::Action::create(
"Save", _(
"_Save changes"));
75 actions.
group->add(actions.
save_changes, sigc::mem_fun(*
this, &PresetWindow::on_preset_save));
76 gtk_activatable_set_related_action(GTK_ACTIVATABLE(save_preset->gobj()), actions.
save_changes->gobj());
77 actions.
organize = Gtk::ToggleAction::create(
"Organize", _(
"_Organize"));
78 actions.
group->add(actions.
organize, sigc::mem_fun(*
this, &PresetWindow::on_organize));
79 gtk_activatable_set_related_action(GTK_ACTIVATABLE(organize_presets->gobj()), GTK_ACTION(actions.
organize->gobj()));
87 gtk_activatable_set_related_action(GTK_ACTIVATABLE(online_preset->gobj()), actions.
online_preset_bank->gobj());
89 online_preset->set_sensitive(
false);
91 bank_treeview->set_model(Gtk::ListStore::create(bank_col));
92 bank_treeview->set_name(
"PresetView");
93 bank_treeview->get_selection()->set_select_function(
94 sigc::mem_fun(*
this, &PresetWindow::select_func));
95 bank_treeview->set_has_tooltip(
true);
96 bank_treeview->signal_query_tooltip().connect(
97 sigc::mem_fun(*
this, &PresetWindow::on_bank_query_tooltip));
98 pb_edit = bank_treeview->render_icon(Gtk::Stock::EDIT, Gtk::ICON_SIZE_MENU);
99 pb_del = bank_treeview->render_icon(Gtk::Stock::DELETE, Gtk::ICON_SIZE_MENU);
100 pb_scratch = Gdk::Pixbuf::create_from_file(options.
get_style_filepath(
"scratch.png"));
101 pb_versiondiff = Gdk::Pixbuf::create_from_file(options.
get_style_filepath(
"versiondiff.png"));
102 pb_readonly = Gdk::Pixbuf::create_from_file(options.
get_style_filepath(
"readonly.png"));
103 pb_factory = Gdk::Pixbuf::create_from_file(options.
get_style_filepath(
"factory.png"));
104 bank_treeview->set_row_separator_func(sigc::mem_fun(*
this, &PresetWindow::is_row_separator));
105 bank_cellrenderer->signal_edited().connect(
106 sigc::bind(sigc::mem_fun(*
this, &PresetWindow::on_bank_edited), bank_treeview));
107 bank_cellrenderer->signal_editing_canceled().connect(
108 sigc::bind(sigc::mem_fun(*
this, &PresetWindow::on_edit_canceled), bank_treeview->get_column(1)));
109 bank_cellrenderer->signal_editing_started().connect(
110 sigc::bind(sigc::mem_fun(*
this, &PresetWindow::on_editing_started), bank_treeview->get_model()));
111 Gtk::TreeViewColumn *col = bank_treeview->get_column(1);
112 col->set_cell_data_func(**col->get_cell_renderers().begin(), sigc::mem_fun(*
this, &PresetWindow::highlight_current_bank));
114 std::vector<Gtk::TargetEntry> listTargets;
115 listTargets.push_back(Gtk::TargetEntry(
"GTK_TREE_MODEL_ROW", Gtk::TARGET_SAME_WIDGET, MODELROW_TARGET));
116 listTargets.push_back(Gtk::TargetEntry(
"text/uri-list", Gtk::TARGET_OTHER_APP, URILIST_TARGET));
117 bank_treeview->enable_model_drag_source(listTargets, Gdk::BUTTON1_MASK, Gdk::ACTION_COPY);
118 bank_treeview->drag_source_add_text_targets();
119 bank_treeview->signal_drag_motion().connect(sigc::mem_fun(*
this, &PresetWindow::on_bank_drag_motion),
false);
120 bank_treeview->enable_model_drag_dest(listTargets, Gdk::ACTION_COPY);
121 bank_treeview->signal_drag_data_received().connect(
122 sigc::mem_fun(*
this, &PresetWindow::on_bank_drag_data_received));
123 bank_treeview->signal_drag_data_get().connect(
124 sigc::mem_fun(*
this, &PresetWindow::on_bank_drag_data_get));
125 bank_treeview->signal_drag_begin().connect(
127 Glib::RefPtr<Gtk::TreeSelection> sel = bank_treeview->get_selection();
128 sel->set_mode(Gtk::SELECTION_BROWSE);
129 sel->signal_changed().connect(sigc::mem_fun(*
this, &PresetWindow::on_bank_changed));
130 bank_treeview->signal_button_release_event().connect(sigc::mem_fun(*
this, &PresetWindow::on_bank_button_release),
true);
131 Glib::RefPtr<Gtk::TreeModel> ls = bank_treeview->get_model();
132 bank_row_del_conn = ls->signal_row_deleted().connect(sigc::mem_fun(*
this, &PresetWindow::on_bank_reordered));
134 preset_treeview->set_model(pstore);
135 preset_treeview->set_name(
"PresetView");
136 preset_treeview->signal_drag_motion().connect(sigc::mem_fun(*
this, &PresetWindow::on_preset_drag_motion),
false);
137 preset_treeview->signal_drag_data_get().connect(sigc::mem_fun(*
this, &PresetWindow::on_preset_drag_data_get));
138 preset_treeview->signal_row_activated().connect(sigc::mem_fun(*
this, &PresetWindow::on_preset_row_activated));
139 preset_treeview->signal_button_press_event().connect(sigc::mem_fun(*
this, &PresetWindow::on_preset_button_press));
140 preset_treeview->signal_button_release_event().connect(sigc::mem_fun(*
this, &PresetWindow::on_preset_button_release),
true);
141 preset_row_del_conn = pstore->signal_row_deleted().connect(sigc::mem_fun(*
this, &PresetWindow::on_preset_reordered));
142 preset_treeview->get_selection()->set_mode(Gtk::SELECTION_BROWSE);
143 preset_treeview->get_selection()->set_select_function(
144 sigc::mem_fun(*
this, &PresetWindow::select_func));
145 preset_treeview->get_selection()->signal_changed().connect(sigc::mem_fun(*
this, &PresetWindow::on_preset_changed));
146 preset_treeview->signal_cursor_changed().connect(sigc::mem_fun(*
this, &PresetWindow::on_cursor_changed));
147 preset_cellrenderer->signal_edited().connect(sigc::mem_fun(*
this, &PresetWindow::on_preset_edited));
148 preset_cellrenderer->signal_editing_canceled().connect(
149 sigc::bind(sigc::mem_fun(*
this, &PresetWindow::on_edit_canceled), preset_treeview->get_column(0)));
150 preset_cellrenderer->signal_editing_started().connect(
152 sigc::mem_fun(*
this, &PresetWindow::on_editing_started),
153 Glib::RefPtr<Gtk::TreeModel>::cast_static(pstore)));
154 preset_treeview->get_column(0)->set_cell_data_func(
155 *preset_cellrenderer, sigc::mem_fun(*
this, &PresetWindow::text_func));
156 banks_combobox->signal_changed().connect(
157 sigc::mem_fun(*
this, &PresetWindow::on_preset_combo_changed));
158 presets_target_treeview->get_selection()->set_mode(Gtk::SELECTION_NONE);
159 std::vector<Gtk::TargetEntry> listTargets3;
160 listTargets3.push_back(
161 Gtk::TargetEntry(
"application/x-guitarix-preset", Gtk::TARGET_SAME_APP, 0));
162 presets_target_treeview->enable_model_drag_dest(listTargets3, Gdk::ACTION_COPY);
163 presets_target_treeview->signal_drag_motion().connect(
164 sigc::mem_fun(*
this, &PresetWindow::on_target_drag_motion),
false);
165 presets_target_treeview->signal_drag_data_received().connect_notify(
166 sigc::mem_fun(*
this, &PresetWindow::target_drag_data_received));
168 sigc::mem_fun(*
this, &PresetWindow::on_selection_changed));
171 gtk_size_group_add_widget(lc, GTK_WIDGET(close_preset->gobj()));
172 gtk_size_group_add_widget(lc, GTK_WIDGET(save_preset->gobj()));
173 gtk_size_group_add_widget(lc, GTK_WIDGET(new_preset_bank->gobj()));
174 gtk_size_group_add_widget(lc, GTK_WIDGET(organize_presets->gobj()));
175 gtk_size_group_add_widget(lc, GTK_WIDGET(online_preset->gobj()));
181 void PresetWindow::on_selection_changed() {
182 Gtk::TreeIter it = bank_treeview->get_selection()->get_selected();
184 it = preset_treeview->get_selection()->get_selected();
186 Glib::RefPtr<Gdk::Window> w = bank_treeview->get_window();
188 gdk_window_invalidate_rect(w->gobj(), 0,
true);
189 gdk_window_invalidate_rect(preset_treeview->get_window()->gobj(), 0,
true);
205 void PresetWindow::load_widget_pointers(Glib::RefPtr<gx_gui::GxBuilder> bld) {
206 bld->find_widget(
"close_preset", close_preset);
207 bld->find_widget(
"save_preset", save_preset);
208 bld->find_widget(
"new_preset_bank", new_preset_bank);
209 bld->find_widget(
"organize_presets", organize_presets);
210 bld->find_widget(
"online_preset", online_preset);
212 bld->find_widget(
"bank_cellrenderer", bank_cellrenderer);
214 bld->find_widget(
"preset_cellrenderer", preset_cellrenderer);
215 bld->find_widget(
"banks_combobox", banks_combobox);
217 bld->find_widget(
"preset_title", preset_title);
218 bld->find_widget(
"presets_target_scrolledbox", presets_target_scrolledbox);
219 bld->find_widget(
"bank_column_edit", bank_column_edit);
220 bld->find_widget(
"bank_column_delete", bank_column_delete);
221 bld->find_widget(
"preset_column_edit", preset_column_edit);
222 bld->find_widget(
"preset_column_delete", preset_column_delete);
223 bld->find_widget(
"main_vpaned", main_vpaned);
224 bld->find_widget(
"preset_scrolledbox", preset_scrolledbox);
227 static bool preset_button_press_idle(Gtk::Widget& w) {
232 bool PresetWindow::on_bank_query_tooltip(
int x,
int y,
bool kb_tooltip, Glib::RefPtr<Gtk::Tooltip> tooltip) {
234 if (!bank_treeview->get_tooltip_context_iter(x, y, kb_tooltip, it)) {
237 int tp = it->get_value(bank_col.
tp);
241 Gtk::TreeModel::Path pt;
242 Gtk::TreeViewColumn *col;
244 if (!bank_treeview->get_path_at_pos(x, y, pt, col, dx, dy)) {
247 Glib::ustring nm = it->get_value(bank_col.
name);
252 if (col == bank_treeview->get_column(0) || col == bank_treeview->get_column(1)) {
255 tooltip->set_text(_(
"damaged bank file; click to delete"));
258 Glib::ustring::compose(_(
"wrong format version (is %1, need %2)\nclick to convert"),
262 tooltip->set_text(_(
"readonly bank, click to change to read-write"));
263 }
else if (col == bank_treeview->get_column(0)){
264 tooltip->set_text(_(
"click to set to readonly"));
269 tooltip->set_text(_(
"predefined factory preset bank"));
271 tooltip->set_text(_(
"scratch preset bank: changes will be persistent (without explicit saving)"));
275 }
else if (col == bank_treeview->get_column(2)) {
279 tooltip->set_text(_(
"click to edit the bank name"));
280 }
else if (col == bank_treeview->get_column(3)) {
284 tooltip->set_text(_(
"click to delete the bank"));
288 bank_treeview->set_tooltip_cell(tooltip, &pt, col, 0);
292 void PresetWindow::on_preset_row_activated(
const Gtk::TreePath& path, Gtk::TreeViewColumn* column) {
293 bool in_organize = actions.
organize->get_active();
296 preset_treeview->get_selection()->select(path);
300 bool PresetWindow::on_preset_button_press(GdkEventButton *ev) {
301 if (ev->type == GDK_BUTTON_PRESS) {
302 Glib::signal_idle().connect(sigc::bind(sigc::ptr_fun(preset_button_press_idle), sigc::ref(*preset_treeview)));
308 void PresetWindow::on_preset_drag_data_get(
const Glib::RefPtr<Gdk::DragContext>& context, Gtk::SelectionData& selection,
int info,
int timestamp) {
309 if (selection.get_target() ==
"application/x-guitarix-preset") {
310 Gtk::TreeModel::Path path;
311 Gtk::TreeViewColumn *focus_column;
312 preset_treeview->get_cursor(path, focus_column);
313 Glib::ustring data = pstore->get_iter(path)->get_value(pstore->col.name);
314 selection.set(
"application/x-guitarix-preset", data);
318 void PresetWindow::on_bank_drag_data_get(
const Glib::RefPtr<Gdk::DragContext>& context, Gtk::SelectionData& selection,
int info,
int timestamp) {
319 if (info != URILIST_TARGET && info != TEXT_TARGETS) {
322 Gtk::TreeModel::Path path;
323 Gtk::TreeViewColumn *focus_column;
324 bank_treeview->get_cursor(path, focus_column);
325 Glib::RefPtr<Gio::File> f =
326 Gio::File::create_for_path(
328 bank_treeview->get_model()->get_iter(path)->get_value(bank_col.
name)));
329 if (info == TEXT_TARGETS) {
330 selection.set_text(f->get_path());
332 std::vector<std::string> uris;
333 uris.push_back(f->get_uri());
334 selection.set_uris(uris);
338 void PresetWindow::on_bank_drag_data_received(
const Glib::RefPtr<Gdk::DragContext>& context,
int x,
int y,
const Gtk::SelectionData& data, guint info, guint timestamp) {
339 if (info != URILIST_TARGET) {
343 bool is_move = context->get_selected_action() == Gdk::ACTION_MOVE;
345 bool is_move = context->gobj()->action == GDK_ACTION_MOVE;
347 bool success =
false;
348 std::vector<Glib::ustring> uris = data.get_uris();
349 Glib::RefPtr<Gtk::ListStore> ls = Glib::RefPtr<Gtk::ListStore>::cast_dynamic(bank_treeview->get_model());
350 for (std::vector<Glib::ustring>::iterator i = uris.begin(); i != uris.end(); ++i) {
353 Gtk::TreeIter i = ls->prepend();
354 set_row_for_presetfile(i,f);
355 bank_treeview->set_cursor(ls->get_path(i));
356 bank_treeview->get_selection()->select(i);
360 context->drag_finish(success,
false, timestamp);
363 Glib::ustring PresetWindow::get_combo_selection() {
364 Gtk::TreeIter idx = banks_combobox->get_active();
368 return idx->get_value(target_col.
name);
375 void PresetWindow::target_drag_data_received(
const Glib::RefPtr<Gdk::DragContext>& context,
int x,
int y,
const Gtk::SelectionData& data, guint info, guint timestamp) {
376 Glib::ustring bank = get_combo_selection();
378 presets_target_treeview->signal_drag_data_received().emission_stop();
382 Glib::RefPtr<Gtk::ListStore> ls = Glib::RefPtr<Gtk::ListStore>::cast_dynamic(presets_target_treeview->get_model());
383 Glib::ustring srcnm = data.get_data_as_string();
384 Glib::ustring dstnm = srcnm;
390 Glib::ustring src_bank = get_current_bank();
392 if (src_bank == bank) {
396 Gtk::TreeModel::Path pt;
397 Gtk::TreeViewDropPosition dst;
398 if (!presets_target_treeview->get_dest_row_at_pos(x, y, pt, dst)) {
399 ls->append()->set_value(target_col.
name, dstnm);
402 Gtk::TreeIter it = ls->get_iter(pt);
403 if (dst == Gtk::TREE_VIEW_DROP_BEFORE || dst == Gtk::TREE_VIEW_DROP_INTO_OR_BEFORE) {
404 ls->insert(it)->set_value(target_col.
name, dstnm);
407 ls->insert_after(it)->set_value(target_col.
name, dstnm);
411 if (context->get_action() == Gdk::ACTION_MOVE) {
412 Gtk::TreeModel::Path pt;
413 Gtk::TreeViewColumn *col;
414 preset_treeview->get_cursor(pt, col);
415 preset_row_del_conn.block();
416 pstore->erase(pstore->get_iter(pt));
417 preset_row_del_conn.unblock();
420 if (src_bank == bank) {
425 bool PresetWindow::on_target_drag_motion(
const Glib::RefPtr<Gdk::DragContext>& context,
int x,
int y, guint timestamp) {
426 Gtk::Widget *source_widget = Gtk::Widget::drag_get_source_widget(context);
427 if (source_widget != preset_treeview || get_combo_selection().empty()) {
428 context->drag_status((Gdk::DragAction)0, timestamp);
431 presets_target_treeview->on_drag_motion(context, x, y, timestamp);
432 Gtk::TreeIter it = bank_treeview->get_selection()->get_selected();
433 int tp = it->get_value(bank_col.
tp);
434 Glib::ustring nm = it->get_value(bank_col.
name);
436 get_combo_selection() == nm) {
437 context->drag_status(Gdk::ACTION_COPY, timestamp);
442 void PresetWindow::reload_combo() {
443 Glib::ustring old = get_combo_selection();
444 Glib::RefPtr<Gtk::ListStore> ls = Glib::RefPtr<Gtk::ListStore>::cast_dynamic(banks_combobox->get_model());
449 int tp = i->get_type();
453 if (i->get_flags()) {
456 Glib::ustring s = i->get_name();
457 ls->append()->set_value(bank_col.
name, s);
463 banks_combobox->set_active(nn);
466 void PresetWindow::on_preset_combo_changed() {
467 Glib::RefPtr<Gtk::ListStore> ls = Glib::RefPtr<Gtk::ListStore>::cast_dynamic(presets_target_treeview->get_model());
469 Glib::ustring nm = get_combo_selection();
475 ls->
append()->set_value(bank_col.
name, i->name);
479 void PresetWindow::reload_target() {
480 on_preset_combo_changed();
487 bool PresetWindow::select_func(
const Glib::RefPtr<Gtk::TreeModel>& model,
const Gtk::TreePath& path,
bool path_currently_selected) {
488 Glib::ustring s = model->get_iter(path)->get_value(bank_col.
name);
495 void PresetWindow::on_editing_started(
const Gtk::CellEditable* edit,
const Glib::ustring& path, Glib::RefPtr<Gtk::TreeModel>& model) {
496 Glib::ustring s = model->get_iter(path)->get_value(bank_col.
name);
498 dynamic_cast<Gtk::Entry*
>(
const_cast<Gtk::CellEditable*
>(edit))->set_text(
"");
500 dynamic_cast<Gtk::Entry*
>(
const_cast<Gtk::CellEditable*
>(edit))->set_text(s);
502 dynamic_cast<Gtk::Window*
>(main_vpaned->get_toplevel())->remove_accel_group(actions.
accels);
505 bool PresetWindow::edit_cell(
const Gtk::TreeModel::Path pt, Gtk::TreeViewColumn& col, Gtk::CellRenderer& cell) {
506 dynamic_cast<Gtk::CellRendererText*
>(&cell)->property_editable().set_value(
true);
507 col.get_tree_view()->set_cursor(pt, col,
true);
511 void PresetWindow::reset_edit(Gtk::TreeViewColumn& col) {
513 Glib::RefPtr<Gtk::ListStore> ls = Glib::RefPtr<Gtk::ListStore>::cast_dynamic(col.get_tree_view()->get_model());
514 ls->erase(edit_iter);
515 edit_iter = ls->children().end();
517 Gtk::CellRendererText& cell = *
dynamic_cast<Gtk::CellRendererText*
>(col.get_first_cell_renderer());
518 cell.property_editable().set_value(
false);
519 col.set_min_width(0);
522 dynamic_cast<Gtk::Window*
>(main_vpaned->get_toplevel())->add_accel_group(actions.
accels);
525 void PresetWindow::on_edit_canceled(Gtk::TreeViewColumn *col) {
529 void PresetWindow::start_edit(
const Gtk::TreeModel::Path& pt, Gtk::TreeViewColumn& col, Gtk::CellRenderer& cell) {
530 col.set_min_width(100);
531 Glib::signal_idle().connect(
532 sigc::bind(sigc::mem_fun(*
this, &PresetWindow::edit_cell),
533 pt, sigc::ref(col), sigc::ref(cell)));
540 void PresetWindow::highlight_current_bank(Gtk::CellRenderer *cell,
const Gtk::TreeModel::iterator& iter) {
541 Glib::ustring t = iter->get_value(bank_col.
name);
545 Gtk::CellRendererText *tc =
dynamic_cast<Gtk::CellRendererText*
>(cell);
547 tc->property_foreground().set_value(
"#f00");
549 tc->property_foreground_set().set_value(
false);
551 int n = machine.
bank_size() - *bank_treeview->get_model()->get_path(iter).begin();
558 t = Glib::ustring::compose(
"%1: %2",
char(
'A'+n), t);
560 cell->set_property(
"text", t);
563 Glib::ustring PresetWindow::get_current_bank() {
564 Gtk::TreeIter it = get_current_bank_iter();
568 return it->get_value(bank_col.
name);
571 bool PresetWindow::run_message_dialog(Gtk::Widget& w,
const Glib::ustring& msg) {
572 Gtk::MessageDialog d(*dynamic_cast<Gtk::Window*>(w.get_toplevel()), msg,
false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_OK_CANCEL,
true);
573 d.set_position(Gtk::WIN_POS_MOUSE);
574 return d.run() == Gtk::RESPONSE_OK;
577 bool PresetWindow::on_bank_button_release(GdkEventButton *ev) {
579 Gtk::TreeModel::Path pt;
580 Gtk::TreeViewColumn *col;
582 if (!bank_treeview->get_path_at_pos(ev->x, ev->y, pt, col, dx, dy)) {
585 Gtk::TreeModel::Path path;
586 Gtk::TreeViewColumn *focus_column;
587 bank_treeview->get_cursor(path, focus_column);
588 if (col != focus_column || pt != path) {
591 Glib::RefPtr<Gtk::ListStore> ls = Glib::RefPtr<Gtk::ListStore>::cast_dynamic(bank_treeview->get_model());
592 Gtk::TreeModel::iterator it = ls->get_iter(pt);
593 Glib::ustring nm = it->get_value(bank_col.
name);
594 int tp = it->get_value(bank_col.
tp);
595 if (col == bank_treeview->get_column(0)) {
604 if (run_message_dialog(*bank_treeview,
"convert bank " + nm +
" to new version?")) {
614 if (run_message_dialog(*bank_treeview,
"convert readonly bank " + nm +
" to new version?")) {
620 if (run_message_dialog(
621 *bank_treeview,
"delete damaged bank " + nm +
"?" 622 " Export it before deleting and ask in the" 623 " guitarix online forum if you want to try to repair it!")) {
634 if (col == bank_treeview->get_column(2)) {
635 col = bank_treeview->get_column(1);
636 start_edit(pt, *col, *col->get_first_cell_renderer());
637 }
else if (col == bank_treeview->get_column(3)) {
638 Gtk::MessageDialog d(*dynamic_cast<Gtk::Window*>(bank_treeview->get_toplevel()),
"delete bank " + nm +
"?",
false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_OK_CANCEL,
true);
639 d.set_position(Gtk::WIN_POS_MOUSE);
640 if (d.run() == Gtk::RESPONSE_OK) {
641 bank_row_del_conn.block();
643 bank_row_del_conn.unblock();
654 void PresetWindow::on_bank_edited(
const Glib::ustring& path,
const Glib::ustring& newtext, Gtk::TreeView* w) {
655 Gtk::TreeIter sel = w->get_model()->get_iter(path);
656 Glib::ustring oldname = sel->get_value(bank_col.
name);
657 Glib::ustring newname = newtext;
659 if (newname.empty() || newname == oldname) {
660 Gtk::TreeViewColumn *p = w->get_column(1);
664 Glib::RefPtr<Gtk::ListStore> ls = Glib::RefPtr<Gtk::ListStore>::cast_dynamic(banks_combobox->get_model());
668 ls->prepend()->set_value(target_col.
name, f->
get_name());
669 edit_iter = ls->children().end();
670 set_row_for_presetfile(sel, f);
671 w->get_selection()->select(sel);
675 Gtk::TreeNodeChildren ch = ls->children();
676 for (Gtk::TreeIter it = ch.begin(); it != ch.end(); ++it) {
677 if (it->get_value(bank_col.
name) == oldname) {
678 it->set_value(bank_col.
name, newname);
681 w->get_model()->get_iter(path)->set_value(bank_col.
name, newname);
683 Gtk::TreeViewColumn *p = w->get_column(1);
687 bool PresetWindow::is_row_separator(
const Glib::RefPtr<Gtk::TreeModel>& model,
const Gtk::TreeModel::iterator& iter) {
691 void PresetWindow::on_new_bank() {
692 Glib::RefPtr<Gtk::ListStore> m = Glib::RefPtr<Gtk::ListStore>::cast_dynamic(bank_treeview->get_model());
693 edit_iter = m->prepend();
696 start_edit(m->get_path(edit_iter), *bank_treeview->get_column(1), *bank_cellrenderer);
701 bool PresetWindow::insertRequested(
const char *ur, gpointer data)
704 const char *file_name = strrchr( ur,
'/' ) + 1;
705 const gchar* dest = g_strdup_printf(
"file:///tmp/%s",file_name);
707 Glib::RefPtr<Gtk::ListStore> ls = Glib::RefPtr<Gtk::ListStore>::cast_dynamic(
self.bank_treeview->get_model());
710 Gtk::TreeIter i = ls->prepend();
711 self.set_row_for_presetfile(i,f);
712 self.bank_treeview->set_cursor(ls->get_path(i));
713 self.bank_treeview->get_selection()->select(i);
718 void PresetWindow::download_status(GObject*
object, GParamSpec* pspec, gpointer data) {
719 WebKitDownload *download;
720 WebKitDownloadStatus status;
723 download = WEBKIT_DOWNLOAD(
object);
724 status = webkit_download_get_status(download);
725 uri = webkit_download_get_uri(download);
728 case WEBKIT_DOWNLOAD_STATUS_ERROR:
730 boost::format(_(
"ERROR download %1%")) % uri);
732 case WEBKIT_DOWNLOAD_STATUS_CREATED:
735 case WEBKIT_DOWNLOAD_STATUS_STARTED:
738 case WEBKIT_DOWNLOAD_STATUS_CANCELLED:
740 boost::format(_(
"download cancelled %1%")) % uri);
742 case WEBKIT_DOWNLOAD_STATUS_FINISHED:
744 boost::format(_(
"download finished %1%")) % uri);
745 insertRequested(uri, data);
748 g_assert_not_reached();
752 bool PresetWindow::downloadRequested(WebKitWebView* webView, WebKitDownload *download, gpointer data)
754 const char *ur = webkit_download_get_uri (download);
755 const char *file_name = strrchr( ur,
'/' ) + 1;
756 const gchar* dest = g_strdup_printf(
"file:///tmp/%s",file_name);
757 webkit_download_set_destination_uri(download, dest);
758 g_signal_connect(download,
"notify::status", G_CALLBACK(download_status), data);
762 bool PresetWindow::uploadRequested(WebKitWebView* webView, WebKitFileChooserRequest *request,gpointer data )
764 Gtk::FileChooserDialog d(
"Select upload file");
765 d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
766 d.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
767 d.add_shortcut_folder(
string(getenv(
"HOME")) +
string(
"/.config/guitarix/bamks"));
768 Gtk::FileFilter banks;
769 banks.set_name(
"Bank Files");
770 banks.add_pattern(
"*.gx");
773 all.add_pattern(
"*");
774 all.set_name(
"All Files");
776 d.set_current_folder(
string(getenv(
"HOME")) +
string(
"/.config/guitarix/banks"));
778 if (d.run() != Gtk::RESPONSE_OK) {
781 Glib::ustring filename = d.get_filename();
782 const gchar* f[2] = {filename.c_str(),0};
783 webkit_file_chooser_request_select_files (request, f);
787 void PresetWindow::show_online_preset() {
789 Gtk::Window *window =
new Gtk::Window();
790 Gtk::ScrolledWindow *scrollbox = Gtk::manage(
new Gtk::ScrolledWindow());
791 scrollbox->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
792 window->set_default_size( 800, 500 );
793 WebKitWebView * web_view = WEBKIT_WEB_VIEW( webkit_web_view_new() );
794 WebKitWebSettings *settings = webkit_web_settings_new ();
795 g_object_set (G_OBJECT(settings),
"enable-offline-web-application-cache", TRUE, NULL);
796 g_object_set (G_OBJECT(settings),
"enable-page-cache", TRUE, NULL);
797 webkit_web_view_set_settings (WEBKIT_WEB_VIEW(web_view), settings);
800 scrollbox->add(*Gtk::manage((
Glib::wrap(GTK_WIDGET(web_view )))));
801 window->add(*Gtk::manage(scrollbox));
802 webkit_web_view_load_uri(web_view,
"https://api.musical-artifacts.com/guitarix-presets/");
803 g_signal_connect(G_OBJECT (web_view),
"download-requested", G_CALLBACK(downloadRequested),
this);
804 g_signal_connect(G_OBJECT (web_view),
"run-file-chooser", G_CALLBACK(uploadRequested),
this);
808 void PresetWindow::on_online_preset() {
809 Glib::signal_idle().connect_once(sigc::mem_fun(*
this, &PresetWindow::show_online_preset));
814 bool PresetWindow::on_bank_drag_motion(
const Glib::RefPtr<Gdk::DragContext>& context,
int x,
int y, guint timestamp) {
815 Gtk::Widget *source_widget = Gtk::Widget::drag_get_source_widget(context);
816 if (!source_widget) {
819 if (context->get_suggested_action() == Gdk::ACTION_MOVE) {
820 a = context->get_suggested_action();
822 a = Gdk::ACTION_COPY;
824 context->drag_status(a, timestamp);
825 }
else if (source_widget != bank_treeview) {
827 context->drag_status((Gdk::DragAction)0, timestamp);
830 Gtk::TreeIter it = bank_treeview->get_selection()->get_selected();
834 int tp = it->get_value(bank_col.
tp);
836 context->drag_status((Gdk::DragAction)0, timestamp);
839 Gtk::TreeModel::Path pt;
840 Gtk::TreeViewDropPosition dst;
841 if (bank_treeview->get_dest_row_at_pos(x, y, pt, dst)) {
842 tp = bank_treeview->get_model()->get_iter(pt)->get_value(bank_col.
tp);
844 context->drag_status((Gdk::DragAction)0, timestamp);
848 bank_treeview->on_drag_motion(context, x, y, timestamp);
849 context->drag_status(Gdk::ACTION_MOVE, timestamp);
854 void PresetWindow::on_bank_changed() {
855 preset_row_del_conn.block();
860 preset_row_del_conn.unblock();
861 Gtk::TreeIter it = bank_treeview->get_selection()->get_selected();
863 in_current_preset =
false;
866 Glib::ustring nm = it->get_value(bank_col.
name);
867 preset_title->set_text(nm);
873 preset_treeview->unset_rows_drag_source();
875 preset_treeview->unset_rows_drag_source();
876 preset_treeview->set_reorderable(
true);
877 std::vector<Gtk::TargetEntry> listTargets2;
878 listTargets2.push_back(Gtk::TargetEntry(
"GTK_TREE_MODEL_ROW", Gtk::TARGET_SAME_WIDGET, 0));
879 listTargets2.push_back(Gtk::TargetEntry(
"application/x-guitarix-preset", Gtk::TARGET_SAME_APP, 1));
880 preset_treeview->enable_model_drag_source(listTargets2, Gdk::BUTTON1_MASK, Gdk::ACTION_COPY|Gdk::ACTION_MOVE);
884 i = pstore->append();
885 i->set_value(pstore->col.name, s->name);
887 i->set_value(pstore->col.edit_pb, pb_edit);
888 i->set_value(pstore->col.del_pb, pb_del);
891 if (preset_treeview->get_mapped()) {
892 preset_treeview->scroll_to_row(pstore->get_path(i));
897 i = pstore->append();
904 i->set_value(bank_col.
type_pb, pb_del);
906 i->set_value(bank_col.
type_pb, pb_versiondiff);
908 i->set_value(bank_col.
type_pb, pb_readonly);
911 i->set_value(bank_col.
tp, tp);
913 i->set_value(bank_col.
type_pb, pb_scratch);
915 i->set_value(bank_col.
type_pb, pb_factory);
917 i->set_value(bank_col.
edit_pb, pb_edit);
918 i->set_value(bank_col.
del_pb, pb_del);
922 void PresetWindow::reload_banks(
const Glib::ustring& sel_bank) {
923 preset_row_del_conn.block();
925 preset_row_del_conn.unblock();
926 Glib::RefPtr<Gtk::ListStore> ls = Glib::RefPtr<Gtk::ListStore>::cast_dynamic(bank_treeview->get_model());
927 bank_row_del_conn.block();
929 bank_row_del_conn.unblock();
931 int in_factory =
false;
939 set_row_for_presetfile(i, *v);
940 if (v->get_name() == sel_bank) {
941 bank_treeview->get_selection()->select(i);
947 void PresetWindow::set_presets() {
951 void PresetWindow::on_bank_reordered(
const Gtk::TreeModel::Path& path) {
952 Glib::RefPtr<Gtk::TreeModel> ls = bank_treeview->get_model();
953 Gtk::TreeModel::Children ch = ls->children();
954 std::vector<Glib::ustring> l;
955 for (Gtk::TreeIter i = ch.begin(); i != ch.end(); ++i) {
956 int tp = i->get_value(bank_col.
tp);
957 Glib::ustring nm = i->get_value(bank_col.
name);
969 void PresetWindow::text_func(Gtk::CellRenderer *cell,
const Gtk::TreeModel::iterator& iter) {
970 Glib::ustring val = iter->get_value(pstore->col.name);
971 Glib::ustring t = val;
972 #if false // gtk 2.24 973 if (t.empty() && !cell->property_editing().get_value()) {
977 g_object_get(cell->gobj(),
"editing", &editing, NULL);
978 if (t.empty() && !editing) {
981 }
else if (in_current_preset) {
982 int n = *pstore->get_path(iter).begin();
986 t = Glib::ustring::compose(
"%1: %2", (n == 9 ? 0 : n+1), t);
989 cell->set_property(
"text", t);
990 Gtk::CellRendererText *tc =
dynamic_cast<Gtk::CellRendererText*
>(cell);
992 tc->property_foreground().set_value(
"#f00");
994 tc->property_foreground_set().set_value(
false);
998 bool PresetWindow::on_preset_button_release(GdkEventButton *ev) {
999 Gtk::TreeModel::Path pt;
1000 Gtk::TreeViewColumn *col;
1002 if (!preset_treeview->get_path_at_pos(ev->x, ev->y, pt, col, dx, dy)) {
1005 Gtk::TreeModel::Path path;
1006 Gtk::TreeViewColumn *focus_column;
1007 preset_treeview->get_cursor(path, focus_column);
1008 if (col != focus_column || !path || pt != path) {
1011 Gtk::TreeIter bank_iter = get_current_bank_iter();
1012 int tp = bank_iter->get_value(bank_col.
tp);
1016 if (col == preset_treeview->get_column(1)) {
1017 col = preset_treeview->get_column(0);
1018 start_edit(pt, *col, *col->get_first_cell_renderer());
1019 }
else if (col == preset_treeview->get_column(2)) {
1020 Glib::ustring nm = pstore->get_iter(pt)->get_value(pstore->col.name);
1021 Gtk::MessageDialog d(*dynamic_cast<Gtk::Window*>(preset_treeview->get_toplevel()), Glib::ustring::compose(
"delete preset %1?", nm),
false,
1022 Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_OK_CANCEL,
true);
1023 d.set_position(Gtk::WIN_POS_MOUSE);
1024 if (d.run() == Gtk::RESPONSE_OK) {
1025 preset_row_del_conn.block();
1026 pstore->erase(pstore->get_iter(pt));
1027 preset_row_del_conn.unblock();
1035 void PresetWindow::on_preset_edited(
const Glib::ustring& path,
const Glib::ustring& newtext) {
1036 Gtk::TreeIter it = pstore->get_iter(path);
1037 Glib::ustring oldname = it->get_value(pstore->col.name);
1038 Glib::ustring newname = newtext;
1040 if (newname.empty() || newname == oldname) {
1041 reset_edit(*preset_treeview->get_column(0));
1046 if (newname.find_first_of(
"ÜüÖöÄä") != Glib::ustring::npos) {
1047 gx_print_error(
"PresetWindow",
"Vowel mutation isn't allowed in preset names, please choose a name without (ÜüÖöÄä)");
1048 reset_edit(*preset_treeview->get_column(0));
1052 Glib::ustring t = newname;
1055 newname = Glib::ustring::compose(
"%1-%2", t, n);
1058 it->set_value(pstore->col.name, newname);
1059 it->set_value(pstore->col.edit_pb, pb_edit);
1060 it->set_value(pstore->col.del_pb, pb_del);
1061 if (oldname.empty()) {
1077 reset_edit(*preset_treeview->get_column(0));
1080 void PresetWindow::on_cursor_changed() {
1084 Gtk::TreeModel::Path path;
1085 Gtk::TreeViewColumn *focus_column;
1086 preset_treeview->get_cursor(path, focus_column);
1087 if (!pstore->get_iter(path)->get_value(pstore->col.name).empty()) {
1091 start_edit(path, *preset_treeview->get_column(0), *preset_cellrenderer);
1094 bool PresetWindow::on_preset_drag_motion(
const Glib::RefPtr<Gdk::DragContext>& context,
int x,
int y, guint timestamp) {
1095 if (Gtk::Widget::drag_get_source_widget(context) == preset_treeview) {
1096 Gtk::TreeIter it = bank_treeview->get_selection()->get_selected();
1099 preset_treeview->on_drag_motion(context, x, y, timestamp);
1100 Gtk::TreeModel::Path pt;
1101 Gtk::TreeViewDropPosition dst;
1102 if (preset_treeview->get_dest_row_at_pos(x, y, pt, dst)) {
1103 if (dst == Gtk::TREE_VIEW_DROP_BEFORE ||
1104 (dst == Gtk::TREE_VIEW_DROP_AFTER &&
1105 !pstore->get_iter(pt)->get_value(pstore->col.name).empty())) {
1106 context->drag_status(Gdk::ACTION_MOVE, timestamp);
1112 context->drag_status((Gdk::DragAction)0, timestamp);
1116 void PresetWindow::on_preset_reordered(
const Gtk::TreeModel::Path& path) {
1118 Gtk::TreeModel::Children ch = pstore->children();
1119 std::vector<Glib::ustring> l;
1120 for (Gtk::TreeIter i = ch.begin(); i != ch.end(); ++i) {
1121 Glib::ustring s = i->get_value(pstore->col.name);
1130 void PresetWindow::autosize() {
1131 if (bank_treeview->get_mapped()) {
1132 bank_treeview->columns_autosize();
1133 preset_treeview->columns_autosize();
1137 void PresetWindow::on_organize() {
1138 bool v = organize_presets->get_active();
1139 bank_column_edit->set_visible(v);
1140 bank_column_delete->set_visible(v);
1141 preset_column_edit->set_visible(v);
1142 preset_column_delete->set_visible(v);
1143 Glib::RefPtr<Gtk::TreeSelection> sel = preset_treeview->get_selection();
1145 actions.
presets->set_active(
true);
1146 sel->set_mode(Gtk::SELECTION_NONE);
1147 banks_combobox->set_active(-1);
1148 banks_combobox->show();
1149 presets_target_scrolledbox->show();
1152 sel->set_mode(Gtk::SELECTION_BROWSE);
1153 banks_combobox->hide();
1154 presets_target_scrolledbox->hide();
1165 void PresetWindow::on_presets_close() {
1166 actions.
presets->set_active(
false);
1173 bool PresetWindow::animate_preset_show() {
1174 vpaned_pos -= vpaned_step;
1175 if (vpaned_pos <= vpaned_target) {
1176 main_vpaned->set_position(vpaned_target);
1178 Gtk::TreeIter it = get_current_bank_iter();
1180 bank_treeview->scroll_to_row(bank_treeview->get_model()->get_path(it));
1184 main_vpaned->set_position(vpaned_pos);
1188 bool PresetWindow::animate_preset_hide() {
1189 vpaned_pos += vpaned_step;
1190 if (vpaned_pos >= vpaned_target) {
1191 preset_scrolledbox->hide();
1194 main_vpaned->set_position(vpaned_pos);
1198 void PresetWindow::on_preset_changed() {
1199 if (actions.
organize->get_active()) {
1204 Gtk::TreeIter it = bank_treeview->get_selection()->get_selected();
1208 bank = it->get_value(bank_col.
name);
1209 it = preset_treeview->get_selection()->get_selected();
1213 name = it->get_value(pstore->col.name);
1214 bool is_scratch =
false;
1229 in_current_preset =
true;
1235 void PresetWindow::on_preset_save() {
1246 void PresetWindow::display_paned(
bool show_preset,
int paned_child_height) {
1247 if (preset_scrolledbox->get_parent() == main_vpaned) {
1248 vpaned_pos = main_vpaned->get_allocation().get_height();
1250 main_vpaned->get_handle_window()->get_size(w, h);
1251 vpaned_target = vpaned_pos - paned_child_height - h;
1252 main_vpaned->set_position(vpaned_target);
1255 preset_scrolledbox->show();
1256 if (!show_preset || !in_current_preset) {
1259 on_map_conn.disconnect();
1265 Gtk::TreeIter it = get_current_bank_iter();
1267 Glib::signal_idle().connect_once(
1269 sigc::mem_fun1(bank_treeview, &MyTreeView::scroll_to_row),
1270 bank_treeview->get_model()->get_path(it)));
1272 Gtk::TreeNodeChildren ch = pstore->children();
1273 for (it = ch.begin(); it != ch.end(); ++it) {
1275 Glib::signal_idle().connect_once(
1277 sigc::mem_fun1(*preset_treeview, &MyTreeView::scroll_to_row),
1278 pstore->get_path(it)));
1285 static bool first_time =
true;
1288 paned_child_height += 1;
1291 on_map_conn.disconnect();
1292 bool is_mapped = main_vpaned->get_toplevel()->get_mapped();
1293 bool rack_visible = actions.
show_rack->get_active();
1297 }
else if (!get_current_bank_iter()) {
1299 if (!bank.empty()) {
1304 Gtk::TreeIter it = get_current_bank_iter();
1305 if (it && animated && is_mapped) {
1306 bank_treeview->scroll_to_row(bank_treeview->get_model()->get_path(it));
1311 on_map_conn = main_vpaned->get_toplevel()->signal_map().connect(
1313 sigc::mem_fun(*
this, &PresetWindow::display_paned),
1314 true, paned_child_height));
1315 }
else if (animated && rack_visible) {
1317 vpaned_pos = main_vpaned->get_allocation().get_height();
1319 main_vpaned->get_handle_window()->get_size(w, h);
1320 vpaned_target = vpaned_pos - paned_child_height - h;
1321 main_vpaned->set_position(vpaned_pos);
1322 vpaned_step = paned_child_height / 5;
1323 preset_scrolledbox->show();
1324 animate_preset_show();
1325 Glib::signal_timeout().connect(sigc::mem_fun(*
this, &PresetWindow::animate_preset_show), 20);
1327 display_paned(
false, paned_child_height);
1330 vpaned_target = main_vpaned->get_allocation().get_height();
1331 vpaned_pos = main_vpaned->get_position();
1332 if (animated && is_mapped && rack_visible) {
1333 vpaned_step = paned_child_height / 5;
1335 Glib::signal_timeout().connect(sigc::mem_fun(*
this, &PresetWindow::animate_preset_hide), 20);
1337 preset_scrolledbox->hide();
1339 actions.
organize->set_active(
false);
virtual gx_system::PresetFileGui * get_current_bank_file()=0
virtual void reorder_preset(gx_system::PresetFileGui &pf, const std::vector< Glib::ustring > &neworder)=0
void gx_print_info(const char *, const std::string &)
virtual void bank_set_flag(gx_system::PresetFileGui *pf, int flag, bool v)=0
bool has_entry(const Glib::ustring &name)
virtual bank_iterator bank_begin()=0
virtual std::string bank_get_filename(const Glib::ustring &bank)=0
Gtk::TreeModelColumn< Glib::RefPtr< Gdk::Pixbuf > > type_pb
virtual void pf_insert_before(gx_system::PresetFileGui &pf, const Glib::ustring &src, gx_system::PresetFileGui &pftgt, const Glib::ustring &pos, const Glib::ustring &name)=0
virtual void pf_insert_after(gx_system::PresetFileGui &pf, const Glib::ustring &src, gx_system::PresetFileGui &pftgt, const Glib::ustring &pos, const Glib::ustring &name)=0
virtual int bank_size()=0
virtual gx_system::PresetFileGui * get_bank_file(const Glib::ustring &bank) const =0
std::vector< Position >::iterator iterator
virtual bool convert_preset(gx_system::PresetFileGui &pf)=0
Glib::RefPtr< Gtk::Action > save_changes
virtual gx_system::PresetFileGui * bank_insert_new(const Glib::ustring &newname)=0
virtual bool setting_is_preset()=0
static MyTreeView * create_from_builder(BaseObjectType *cobject)
Glib::RefPtr< Gtk::ToggleAction > show_rack
virtual void erase_preset(gx_system::PresetFileGui &pf, const Glib::ustring &name)=0
virtual bool rename_bank(const Glib::ustring &oldname, Glib::ustring &newname)=0
const SettingsFileHeader & get_header()
std::string get_style_filepath(const std::string &basename) const
void gx_print_error(const char *, const std::string &)
Glib::RefPtr< Gtk::ActionGroup > group
virtual bool bank_remove(const Glib::ustring &bank)=0
virtual const Glib::ustring & get_current_bank()=0
Gtk::TreeModelColumn< Glib::RefPtr< Gdk::Pixbuf > > del_pb
void append(const Glib::ustring &name)
virtual bool bank_check_reparse()=0
Gtk::TreeModelColumn< Glib::RefPtr< Gdk::Pixbuf > > edit_pb
Glib::RefPtr< Gtk::Action > new_bank
virtual bool row_draggable_vfunc(const TreeModel::Path &path) const
virtual sigc::signal< void > & signal_selection_changed()=0
Glib::RefPtr< Gtk::ToggleAction > organize
std::string to_string(const T &t)
void on_preset_select(bool v, bool animated, int preset_window_height)
PresetStore::PresetModelColumns col
virtual void load_preset(gx_system::PresetFileGui *pf, const Glib::ustring &name)=0
Glib::RefPtr< Gtk::AccelGroup > accels
Glib::RefPtr< Gtk::Action > online_preset_bank
void strip(Glib::ustring &s)
Gtk::TreeModelColumn< Glib::ustring > name
PresetWindow(Glib::RefPtr< gx_gui::GxBuilder > bld, gx_engine::GxMachineBase &machine, const gx_system::CmdlineOptions &options, GxActions &actions, GtkSizeGroup *lc)
Gxw::BigKnob * wrap(GxBigKnob *object, bool take_copy)
void child_set_property(Gtk::Container &container, Gtk::Widget &child, const char *property_name, bool value)
Glib::RefPtr< Gtk::ToggleAction > presets
virtual bool rename_preset(gx_system::PresetFileGui &pf, const Glib::ustring &oldname, const Glib::ustring &newname)=0
Gtk::TreeModelColumn< int > tp
virtual void bank_reorder(const std::vector< Glib::ustring > &neworder)=0
const Glib::ustring & get_name(int n)
virtual const Glib::ustring & get_current_name()=0
virtual void bank_drag_begin()=0
Gtk::TreeModelColumn< Glib::ustring > name
virtual void pf_append(gx_system::PresetFileGui &pf, const Glib::ustring &src, gx_system::PresetFileGui &pftgt, const Glib::ustring &name)=0
virtual void pf_save(gx_system::PresetFileGui &pf, const Glib::ustring &name)=0
virtual gx_system::PresetFileGui * bank_insert_uri(const Glib::ustring &uri, bool move)=0
virtual gx_system::PresetFileGui * bank_get_file(const Glib::ustring &bank) const =0
Gtk::TreeModelColumn< Glib::ustring > name
virtual bank_iterator bank_end()=0