swat 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +3 -0
- data/README +18 -0
- data/TODO +0 -0
- data/bin/swat +24 -0
- data/ext/Makefile +149 -0
- data/ext/eggaccelerators.c +657 -0
- data/ext/eggaccelerators.h +87 -0
- data/ext/eggaccelerators.o +0 -0
- data/ext/extconf.rb +84 -0
- data/ext/keybinder.c +49 -0
- data/ext/keybinder.o +0 -0
- data/ext/keybinder.so +0 -0
- data/ext/mkmf-gnome2.rb +286 -0
- data/ext/tomboykeybinder.c +320 -0
- data/ext/tomboykeybinder.h +27 -0
- data/ext/tomboykeybinder.o +0 -0
- data/lib/add_todo_dialog.rb +36 -0
- data/lib/list_helper.rb +67 -0
- data/lib/stat_box.rb +83 -0
- data/lib/swat.rb +51 -0
- data/lib/swat_meta_data.rb +61 -0
- data/lib/todo_context_menu.rb +22 -0
- data/lib/todo_data.rb +106 -0
- data/lib/todo_window.rb +169 -0
- data/lib/wish_list.rb +64 -0
- data/resources/add_todo.glade +114 -0
- data/resources/control_end_blue.png +0 -0
- data/resources/control_rewind_blue.png +0 -0
- data/resources/gedit-icon.png +0 -0
- data/resources/todo.org +27 -0
- data/resources/todo.png +0 -0
- data/resources/todo_window.glade +174 -0
- data/resources/toggle_icon.png +0 -0
- data/resources/working_window.glade +127 -0
- data/tests/test_helper.rb +7 -0
- data/tests/test_todo_data.rb +29 -0
- metadata +81 -0
@@ -0,0 +1,320 @@
|
|
1
|
+
#include <string.h>
|
2
|
+
|
3
|
+
#include <gdk/gdk.h>
|
4
|
+
#include <gdk/gdkwindow.h>
|
5
|
+
#include <gdk/gdkx.h>
|
6
|
+
#include <X11/Xlib.h>
|
7
|
+
|
8
|
+
#include "eggaccelerators.h"
|
9
|
+
#include "tomboykeybinder.h"
|
10
|
+
|
11
|
+
/* Uncomment the next line to print a debug trace. */
|
12
|
+
/* #define DEBUG */
|
13
|
+
|
14
|
+
#ifdef DEBUG
|
15
|
+
# define TRACE(x) x
|
16
|
+
#else
|
17
|
+
# define TRACE(x) do {} while (FALSE);
|
18
|
+
#endif
|
19
|
+
|
20
|
+
typedef struct _Binding {
|
21
|
+
TomboyBindkeyHandler handler;
|
22
|
+
gpointer user_data;
|
23
|
+
char *keystring;
|
24
|
+
uint keycode;
|
25
|
+
uint modifiers;
|
26
|
+
} Binding;
|
27
|
+
|
28
|
+
static GSList *bindings = NULL;
|
29
|
+
static guint32 last_event_time = 0;
|
30
|
+
static gboolean processing_event = FALSE;
|
31
|
+
|
32
|
+
static guint num_lock_mask, caps_lock_mask, scroll_lock_mask;
|
33
|
+
|
34
|
+
static void
|
35
|
+
lookup_ignorable_modifiers (GdkKeymap *keymap)
|
36
|
+
{
|
37
|
+
egg_keymap_resolve_virtual_modifiers (keymap,
|
38
|
+
EGG_VIRTUAL_LOCK_MASK,
|
39
|
+
&caps_lock_mask);
|
40
|
+
|
41
|
+
egg_keymap_resolve_virtual_modifiers (keymap,
|
42
|
+
EGG_VIRTUAL_NUM_LOCK_MASK,
|
43
|
+
&num_lock_mask);
|
44
|
+
|
45
|
+
egg_keymap_resolve_virtual_modifiers (keymap,
|
46
|
+
EGG_VIRTUAL_SCROLL_LOCK_MASK,
|
47
|
+
&scroll_lock_mask);
|
48
|
+
}
|
49
|
+
|
50
|
+
static void
|
51
|
+
grab_ungrab_with_ignorable_modifiers (GdkWindow *rootwin,
|
52
|
+
Binding *binding,
|
53
|
+
gboolean grab)
|
54
|
+
{
|
55
|
+
guint mod_masks [] = {
|
56
|
+
0, /* modifier only */
|
57
|
+
num_lock_mask,
|
58
|
+
caps_lock_mask,
|
59
|
+
scroll_lock_mask,
|
60
|
+
num_lock_mask | caps_lock_mask,
|
61
|
+
num_lock_mask | scroll_lock_mask,
|
62
|
+
caps_lock_mask | scroll_lock_mask,
|
63
|
+
num_lock_mask | caps_lock_mask | scroll_lock_mask,
|
64
|
+
};
|
65
|
+
int i;
|
66
|
+
|
67
|
+
for (i = 0; i < G_N_ELEMENTS (mod_masks); i++) {
|
68
|
+
if (grab) {
|
69
|
+
XGrabKey (GDK_WINDOW_XDISPLAY (rootwin),
|
70
|
+
binding->keycode,
|
71
|
+
binding->modifiers | mod_masks [i],
|
72
|
+
GDK_WINDOW_XWINDOW (rootwin),
|
73
|
+
False,
|
74
|
+
GrabModeAsync,
|
75
|
+
GrabModeAsync);
|
76
|
+
} else {
|
77
|
+
XUngrabKey (GDK_WINDOW_XDISPLAY (rootwin),
|
78
|
+
binding->keycode,
|
79
|
+
binding->modifiers | mod_masks [i],
|
80
|
+
GDK_WINDOW_XWINDOW (rootwin));
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
static gboolean
|
86
|
+
do_grab_key (Binding *binding)
|
87
|
+
{
|
88
|
+
GdkKeymap *keymap = gdk_keymap_get_default ();
|
89
|
+
GdkWindow *rootwin = gdk_get_default_root_window ();
|
90
|
+
|
91
|
+
EggVirtualModifierType virtual_mods = 0;
|
92
|
+
guint keysym = 0;
|
93
|
+
|
94
|
+
if (keymap == NULL || rootwin == NULL)
|
95
|
+
return FALSE;
|
96
|
+
|
97
|
+
if (!egg_accelerator_parse_virtual (binding->keystring,
|
98
|
+
&keysym,
|
99
|
+
&virtual_mods))
|
100
|
+
return FALSE;
|
101
|
+
|
102
|
+
TRACE (g_print ("Got accel %d, %d\n", keysym, virtual_mods));
|
103
|
+
|
104
|
+
binding->keycode = XKeysymToKeycode (GDK_WINDOW_XDISPLAY (rootwin),
|
105
|
+
keysym);
|
106
|
+
if (binding->keycode == 0)
|
107
|
+
return FALSE;
|
108
|
+
|
109
|
+
TRACE (g_print ("Got keycode %d\n", binding->keycode));
|
110
|
+
|
111
|
+
egg_keymap_resolve_virtual_modifiers (keymap,
|
112
|
+
virtual_mods,
|
113
|
+
&binding->modifiers);
|
114
|
+
|
115
|
+
TRACE (g_print ("Got modmask %d\n", binding->modifiers));
|
116
|
+
|
117
|
+
gdk_error_trap_push ();
|
118
|
+
|
119
|
+
grab_ungrab_with_ignorable_modifiers (rootwin,
|
120
|
+
binding,
|
121
|
+
TRUE /* grab */);
|
122
|
+
|
123
|
+
gdk_flush ();
|
124
|
+
|
125
|
+
if (gdk_error_trap_pop ()) {
|
126
|
+
g_warning ("Binding '%s' failed!\n", binding->keystring);
|
127
|
+
return FALSE;
|
128
|
+
}
|
129
|
+
|
130
|
+
return TRUE;
|
131
|
+
}
|
132
|
+
|
133
|
+
static gboolean
|
134
|
+
do_ungrab_key (Binding *binding)
|
135
|
+
{
|
136
|
+
GdkWindow *rootwin = gdk_get_default_root_window ();
|
137
|
+
|
138
|
+
TRACE (g_print ("Removing grab for '%s'\n", binding->keystring));
|
139
|
+
|
140
|
+
grab_ungrab_with_ignorable_modifiers (rootwin,
|
141
|
+
binding,
|
142
|
+
FALSE /* ungrab */);
|
143
|
+
|
144
|
+
return TRUE;
|
145
|
+
}
|
146
|
+
|
147
|
+
static GdkFilterReturn
|
148
|
+
filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
|
149
|
+
{
|
150
|
+
GdkFilterReturn return_val = GDK_FILTER_CONTINUE;
|
151
|
+
XEvent *xevent = (XEvent *) gdk_xevent;
|
152
|
+
guint event_mods;
|
153
|
+
GSList *iter;
|
154
|
+
|
155
|
+
TRACE (g_print ("Got Event! %d, %d\n", xevent->type, event->type));
|
156
|
+
|
157
|
+
switch (xevent->type) {
|
158
|
+
case KeyPress:
|
159
|
+
TRACE (g_print ("Got KeyPress! keycode: %d, modifiers: %d\n",
|
160
|
+
xevent->xkey.keycode,
|
161
|
+
xevent->xkey.state));
|
162
|
+
|
163
|
+
/*
|
164
|
+
* Set the last event time for use when showing
|
165
|
+
* windows to avoid anti-focus-stealing code.
|
166
|
+
*/
|
167
|
+
processing_event = TRUE;
|
168
|
+
last_event_time = xevent->xkey.time;
|
169
|
+
|
170
|
+
event_mods = xevent->xkey.state & ~(num_lock_mask |
|
171
|
+
caps_lock_mask |
|
172
|
+
scroll_lock_mask);
|
173
|
+
|
174
|
+
for (iter = bindings; iter != NULL; iter = iter->next) {
|
175
|
+
Binding *binding = (Binding *) iter->data;
|
176
|
+
|
177
|
+
if (binding->keycode == xevent->xkey.keycode &&
|
178
|
+
binding->modifiers == event_mods) {
|
179
|
+
|
180
|
+
TRACE (g_print ("Calling handler for '%s'...\n",
|
181
|
+
binding->keystring));
|
182
|
+
|
183
|
+
(binding->handler) (binding->keystring,
|
184
|
+
binding->user_data);
|
185
|
+
}
|
186
|
+
}
|
187
|
+
|
188
|
+
processing_event = FALSE;
|
189
|
+
break;
|
190
|
+
case KeyRelease:
|
191
|
+
TRACE (g_print ("Got KeyRelease! \n"));
|
192
|
+
break;
|
193
|
+
}
|
194
|
+
|
195
|
+
return return_val;
|
196
|
+
}
|
197
|
+
|
198
|
+
static void
|
199
|
+
keymap_changed (GdkKeymap *map)
|
200
|
+
{
|
201
|
+
GdkKeymap *keymap = gdk_keymap_get_default ();
|
202
|
+
GSList *iter;
|
203
|
+
|
204
|
+
TRACE (g_print ("Keymap changed! Regrabbing keys..."));
|
205
|
+
|
206
|
+
for (iter = bindings; iter != NULL; iter = iter->next) {
|
207
|
+
Binding *binding = (Binding *) iter->data;
|
208
|
+
do_ungrab_key (binding);
|
209
|
+
}
|
210
|
+
|
211
|
+
lookup_ignorable_modifiers (keymap);
|
212
|
+
|
213
|
+
for (iter = bindings; iter != NULL; iter = iter->next) {
|
214
|
+
Binding *binding = (Binding *) iter->data;
|
215
|
+
do_grab_key (binding);
|
216
|
+
}
|
217
|
+
}
|
218
|
+
|
219
|
+
void
|
220
|
+
tomboy_keybinder_init (void)
|
221
|
+
{
|
222
|
+
GdkKeymap *keymap = gdk_keymap_get_default ();
|
223
|
+
GdkWindow *rootwin = gdk_get_default_root_window ();
|
224
|
+
|
225
|
+
lookup_ignorable_modifiers (keymap);
|
226
|
+
|
227
|
+
gdk_window_add_filter (rootwin,
|
228
|
+
filter_func,
|
229
|
+
NULL);
|
230
|
+
|
231
|
+
g_signal_connect (keymap,
|
232
|
+
"keys_changed",
|
233
|
+
G_CALLBACK (keymap_changed),
|
234
|
+
NULL);
|
235
|
+
}
|
236
|
+
|
237
|
+
void
|
238
|
+
tomboy_keybinder_bind (const char *keystring,
|
239
|
+
TomboyBindkeyHandler handler,
|
240
|
+
gpointer user_data)
|
241
|
+
{
|
242
|
+
Binding *binding;
|
243
|
+
gboolean success;
|
244
|
+
|
245
|
+
binding = g_new0 (Binding, 1);
|
246
|
+
binding->keystring = g_strdup (keystring);
|
247
|
+
binding->handler = handler;
|
248
|
+
binding->user_data = user_data;
|
249
|
+
|
250
|
+
/* Sets the binding's keycode and modifiers */
|
251
|
+
success = do_grab_key (binding);
|
252
|
+
|
253
|
+
if (success) {
|
254
|
+
bindings = g_slist_prepend (bindings, binding);
|
255
|
+
} else {
|
256
|
+
g_free (binding->keystring);
|
257
|
+
g_free (binding);
|
258
|
+
}
|
259
|
+
}
|
260
|
+
|
261
|
+
void
|
262
|
+
tomboy_keybinder_unbind (const char *keystring,
|
263
|
+
TomboyBindkeyHandler handler)
|
264
|
+
{
|
265
|
+
GSList *iter;
|
266
|
+
|
267
|
+
for (iter = bindings; iter != NULL; iter = iter->next) {
|
268
|
+
Binding *binding = (Binding *) iter->data;
|
269
|
+
|
270
|
+
if (strcmp (keystring, binding->keystring) != 0 ||
|
271
|
+
handler != binding->handler)
|
272
|
+
continue;
|
273
|
+
|
274
|
+
do_ungrab_key (binding);
|
275
|
+
|
276
|
+
bindings = g_slist_remove (bindings, binding);
|
277
|
+
|
278
|
+
g_free (binding->keystring);
|
279
|
+
g_free (binding);
|
280
|
+
break;
|
281
|
+
}
|
282
|
+
}
|
283
|
+
|
284
|
+
/*
|
285
|
+
* From eggcellrenderkeys.c.
|
286
|
+
*/
|
287
|
+
gboolean
|
288
|
+
tomboy_keybinder_is_modifier (guint keycode)
|
289
|
+
{
|
290
|
+
gint i;
|
291
|
+
gint map_size;
|
292
|
+
XModifierKeymap *mod_keymap;
|
293
|
+
gboolean retval = FALSE;
|
294
|
+
|
295
|
+
mod_keymap = XGetModifierMapping (gdk_display);
|
296
|
+
|
297
|
+
map_size = 8 * mod_keymap->max_keypermod;
|
298
|
+
|
299
|
+
i = 0;
|
300
|
+
while (i < map_size) {
|
301
|
+
if (keycode == mod_keymap->modifiermap[i]) {
|
302
|
+
retval = TRUE;
|
303
|
+
break;
|
304
|
+
}
|
305
|
+
++i;
|
306
|
+
}
|
307
|
+
|
308
|
+
XFreeModifiermap (mod_keymap);
|
309
|
+
|
310
|
+
return retval;
|
311
|
+
}
|
312
|
+
|
313
|
+
guint32
|
314
|
+
tomboy_keybinder_get_current_event_time (void)
|
315
|
+
{
|
316
|
+
if (processing_event)
|
317
|
+
return last_event_time;
|
318
|
+
else
|
319
|
+
return GDK_CURRENT_TIME;
|
320
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
#ifndef __TOMBOY_KEY_BINDER_H__
|
3
|
+
#define __TOMBOY_KEY_BINDER_H__
|
4
|
+
|
5
|
+
#include <glib/gtypes.h>
|
6
|
+
|
7
|
+
G_BEGIN_DECLS
|
8
|
+
|
9
|
+
typedef void (* TomboyBindkeyHandler) (char *keystring, gpointer user_data);
|
10
|
+
|
11
|
+
void tomboy_keybinder_init (void);
|
12
|
+
|
13
|
+
void tomboy_keybinder_bind (const char *keystring,
|
14
|
+
TomboyBindkeyHandler handler,
|
15
|
+
gpointer user_data);
|
16
|
+
|
17
|
+
void tomboy_keybinder_unbind (const char *keystring,
|
18
|
+
TomboyBindkeyHandler handler);
|
19
|
+
|
20
|
+
gboolean tomboy_keybinder_is_modifier (guint keycode);
|
21
|
+
|
22
|
+
guint32 tomboy_keybinder_get_current_event_time (void);
|
23
|
+
|
24
|
+
G_END_DECLS
|
25
|
+
|
26
|
+
#endif /* __TOMBOY_KEY_BINDER_H__ */
|
27
|
+
|
Binary file
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Swat
|
2
|
+
class AddTodoDialog
|
3
|
+
attr_accessor :todo_glade,:add_dialog
|
4
|
+
def initialize(old_categories,&block)
|
5
|
+
@old_categories = old_categories
|
6
|
+
@add_callback = block
|
7
|
+
@todo_glade = GladeXML.new("#{SWAT_APP}/resources/add_todo.glade") { |handler| method(handler) }
|
8
|
+
@add_dialog = @todo_glade.get_widget("add_todo_dialog")
|
9
|
+
@todo_text_entry = @todo_glade.get_widget("todo_text_entry")
|
10
|
+
@category_combo = @todo_glade.get_widget("todo_category_entry")
|
11
|
+
@priority_combo = @todo_glade.get_widget("priority_combo")
|
12
|
+
populate_old_categories
|
13
|
+
@add_dialog.show_all
|
14
|
+
end
|
15
|
+
|
16
|
+
def populate_old_categories
|
17
|
+
model = Gtk::ListStore.new(String)
|
18
|
+
@category_combo.model = model
|
19
|
+
@category_combo.text_column = 0
|
20
|
+
@old_categories.each do |x|
|
21
|
+
iter = model.append
|
22
|
+
iter[0] = x
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def on_add_todo_button_activate
|
27
|
+
@add_callback.call(@priority_combo.active_text,@category_combo.child.text,@todo_text_entry.buffer.text)
|
28
|
+
@add_dialog.destroy
|
29
|
+
end
|
30
|
+
|
31
|
+
def on_button2_clicked
|
32
|
+
@add_dialog.destroy
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
data/lib/list_helper.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
module Swat
|
2
|
+
module ListHelper
|
3
|
+
def reload_view
|
4
|
+
@model = create_model
|
5
|
+
load_available_lists
|
6
|
+
@list_view.expand_all
|
7
|
+
end
|
8
|
+
|
9
|
+
def load_available_lists
|
10
|
+
@list_view.model = @model
|
11
|
+
@list_view.rules_hint = false
|
12
|
+
@list_view.selection.mode = Gtk::SELECTION_SINGLE
|
13
|
+
end
|
14
|
+
def add_columns
|
15
|
+
model = @list_view.model
|
16
|
+
renderer = Gtk::CellRendererText.new
|
17
|
+
renderer.xalign = 0.0
|
18
|
+
|
19
|
+
col_offset = @list_view.insert_column(-1, 'Category', renderer, 'text' => 0,'background' => 1,:weight => 2)
|
20
|
+
column = @list_view.get_column(col_offset - 1)
|
21
|
+
column.clickable = true
|
22
|
+
@list_view.expander_column = column
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_model
|
26
|
+
model = Gtk::TreeStore.new(String,String,Fixnum,Fixnum)
|
27
|
+
|
28
|
+
todo_data.open_tasks do |key,value|
|
29
|
+
iter = model.append(nil)
|
30
|
+
iter[0] = key
|
31
|
+
iter[1] = "white"
|
32
|
+
iter[2] = 900
|
33
|
+
iter[3] = 0
|
34
|
+
value.each do |todo_item|
|
35
|
+
child_iter = model.append(iter)
|
36
|
+
child_iter[0] = wrap_line(todo_item.text)
|
37
|
+
child_iter[1] = chose_color(todo_item)
|
38
|
+
child_iter[2] = 500
|
39
|
+
child_iter[3] = todo_item.index
|
40
|
+
end
|
41
|
+
end
|
42
|
+
return model
|
43
|
+
end
|
44
|
+
|
45
|
+
def wrap_line(line)
|
46
|
+
line_array = []
|
47
|
+
loop do
|
48
|
+
first,last = line.unpack("a90a*")
|
49
|
+
first << "-" if last =~ /^\w/
|
50
|
+
line_array << first
|
51
|
+
break if last.empty?
|
52
|
+
line = last
|
53
|
+
end
|
54
|
+
return line_array.join("\n")
|
55
|
+
end
|
56
|
+
|
57
|
+
def chose_color(todo_item)
|
58
|
+
case todo_item.priority
|
59
|
+
when 1: 'yellow'
|
60
|
+
when 0: 'blue'
|
61
|
+
when 2: '#E3B8B8'
|
62
|
+
when 3: '#15B4F1'
|
63
|
+
when 4: '#F1F509'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|