1 /*
2  * Copyright (c) 2008-2009, Thomas Jaeger <ThJaeger@gmail.com>
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 #ifndef __ACTIONS_H__
17 #define __ACTIONS_H__
18 
19 #include <gtkmm.h>
20 
21 class Unique;
22 class Win;
23 class ActionListDiff;
24 
25 class TreeViewMulti : public Gtk::TreeView {
26 	bool pending;
27 	Gtk::TreePath path;
28 	Gtk::TreeViewColumn *column;
29 	virtual bool on_button_press_event(GdkEventButton* event);
30 	virtual bool on_button_release_event(GdkEventButton* event);
31 	virtual void on_drag_begin(const Glib::RefPtr<Gdk::DragContext> &context);
32 public:
33 	TreeViewMulti();
negate_pending(const Glib::RefPtr<Gtk::TreeModel> & model,const Gtk::TreeModel::Path & path,bool path_currently_selected)34     bool negate_pending(const Glib::RefPtr<Gtk::TreeModel>& model,
35                         const Gtk::TreeModel::Path& path,
36                         bool path_currently_selected) {
37         return !pending;
38     }
39 };
40 
41 class Actions {
42 public:
43 	Actions();
44 private:
45 	void on_button_delete();
46 	void on_button_new();
47 	void on_button_record();
48 	void on_selection_changed();
49 	void on_name_edited(const Glib::ustring& path, const Glib::ustring& new_text);
50 	void on_type_edited(const Glib::ustring& path, const Glib::ustring& new_text);
51 	void on_something_editing_started(Gtk::CellEditable* editable, const Glib::ustring& path);
52 	void on_something_editing_canceled();
53 	void on_row_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column);
54 	void on_cell_data_name(Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter);
55 	void on_cell_data_type(Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter);
56 public:
57 	void on_accel_edited(const gchar *path_string, guint accel_key, GdkModifierType accel_mods, guint hardware_keycode);
58 	void on_combo_edited(const gchar *path_string, guint item);
59 	void on_arg_editing_started(GtkCellEditable *editable, const gchar *path);
60 	void on_text_edited(const gchar *path, const gchar *new_text);
61 	void on_cell_data_arg(GtkCellRenderer *cell, gchar *path);
62 private:
63 	int compare_ids(const Gtk::TreeModel::iterator &a, const Gtk::TreeModel::iterator &b);
64 	class OnStroke;
65 	Gtk::TreeRow get_selected_row();
66 
67 	void focus(Unique *id, int col, bool edit);
68 	bool do_focus(Unique *id, Gtk::TreeViewColumn *col, bool edit);
69 
70 	bool select_app(const Gtk::TreeModel::Path& path, const Gtk::TreeModel::iterator& iter, ActionListDiff *actions);
71 	void on_add_app();
72 	void on_add_group();
73 	void on_group_name_edited(const Glib::ustring& path, const Glib::ustring& new_text);
74 	void on_apps_selection_changed();
75 	void on_expanded();
76 	void load_app_list(const Gtk::TreeNodeChildren &ch, ActionListDiff *actions);
77 	void on_cell_data_apps(Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter);
78 	void update_action_list();
79 	void update_row(const Gtk::TreeRow &row);
80 	bool count_app_actions(const Gtk::TreeIter &i);
81 	void update_counts();
82 	void on_reset_actions();
83 	void on_remove_app();
84 
85 	class ModelColumns : public Gtk::TreeModel::ColumnRecord {
86 	public:
ModelColumns()87 		ModelColumns() {
88 			add(stroke); add(name); add(type); add(arg); add(cmd_save); add(id);
89 			add(name_bold); add(action_bold); add(deactivated);
90 		}
91 		Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > stroke;
92 		Gtk::TreeModelColumn<Glib::ustring> name, type, arg, cmd_save;
93 		Gtk::TreeModelColumn<Unique *> id;
94 		Gtk::TreeModelColumn<bool> name_bold, action_bold;
95 		Gtk::TreeModelColumn<bool> deactivated;
96 	};
97 	class Store : public Gtk::ListStore {
98 		Actions *parent;
99 	public:
Store(const Gtk::TreeModelColumnRecord & columns,Actions * p)100 		Store(const Gtk::TreeModelColumnRecord &columns, Actions *p) : Gtk::ListStore(columns), parent(p) {}
create(const Gtk::TreeModelColumnRecord & columns,Actions * parent)101 		static Glib::RefPtr<Store> create(const Gtk::TreeModelColumnRecord &columns, Actions *parent) {
102 			return Glib::RefPtr<Store>(new Store(columns, parent));
103 		}
104 	protected:
105 		bool row_draggable_vfunc(const Gtk::TreeModel::Path &path) const;
106 		bool row_drop_possible_vfunc(const Gtk::TreeModel::Path &dest, const Gtk::SelectionData &selection) const;
107 		bool drag_data_received_vfunc(const Gtk::TreeModel::Path &dest, const Gtk::SelectionData& selection);
108 	};
109 	class AppsStore : public Gtk::TreeStore {
110 		Actions *parent;
111 	public:
AppsStore(const Gtk::TreeModelColumnRecord & columns,Actions * p)112 		AppsStore(const Gtk::TreeModelColumnRecord &columns, Actions *p) : Gtk::TreeStore(columns), parent(p) {}
create(const Gtk::TreeModelColumnRecord & columns,Actions * parent)113 		static Glib::RefPtr<AppsStore> create(const Gtk::TreeModelColumnRecord &columns, Actions *parent) {
114 			return Glib::RefPtr<AppsStore>(new AppsStore(columns, parent));
115 		}
116 	protected:
117 		bool row_drop_possible_vfunc(const Gtk::TreeModel::Path &dest, const Gtk::SelectionData &selection) const;
118 		bool drag_data_received_vfunc(const Gtk::TreeModel::Path &dest, const Gtk::SelectionData& selection);
119 	};
120 	ModelColumns cols;
121 	TreeViewMulti tv;
122 	Glib::RefPtr<Store> tm;
123 
124 	Gtk::TreeView *apps_view;
125 	Glib::RefPtr<AppsStore> apps_model;
126 
127 	class Single : public Gtk::TreeModel::ColumnRecord {
128 	public:
Single()129 		Single() { add(type); }
130 		Gtk::TreeModelColumn<Glib::ustring> type;
131 	};
132 	Single type;
133 
134 	class Apps : public Gtk::TreeModel::ColumnRecord {
135 	public:
Apps()136 		Apps() { add(app); add(actions); add(count); }
137 		Gtk::TreeModelColumn<Glib::ustring> app;
138 		Gtk::TreeModelColumn<ActionListDiff *> actions;
139 		Gtk::TreeModelColumn<int> count;
140 	};
141 	Apps ca;
142 
143 	struct Focus;
144 
145 	Glib::RefPtr<Gtk::ListStore> type_store;
146 
147 	Gtk::Button *button_record, *button_delete, *button_remove_app, *button_reset_actions;
148 	Gtk::CheckButton *check_show_deleted;
149 	Gtk::Expander *expander_apps;
150 	Gtk::VPaned *vpaned_apps;
151 
152 	int vpaned_position;
153 	bool editing_new;
154 	bool editing;
155 
156 	ActionListDiff *action_list;
157 };
158 
159 #endif
160