1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use v6;
unit class GuiHandlers;
use Gnome::N::N-GObject;
use Gnome::Gtk3::Main;
use Gnome::Gtk3::ListStore;
use Gnome::Gtk3::TreeStore;
use Gnome::Gtk3::TreeIter;
use Gnome::Gtk3::TreePath;
use Gnome::Gtk3::TreeView;
use Gnome::Gtk3::TreeViewColumn;
#-------------------------------------------------------------------------------
class Application {
has Gnome::Gtk3::Main $!main;
#-----------------------------------------------------------------------------
submethod BUILD (:$!main) { }
method exit-todo-viewer ( ) {
$!main.quit;
}
}
#-------------------------------------------------------------------------------
class ListView {
has Str $!filename;
#-----------------------------------------------------------------------------
method select-list-entry (
N-GtkTreePath $n-tree-path, N-GObject $n-treeview-column,
Hash :$data, Int :$data-col, Gnome::Gtk3::TreeStore :$files,
Gnome::Gtk3::ListStore :$markers
) {
my Gnome::Gtk3::TreePath $tree-path;
my Gnome::Gtk3::TreeIter $iter;
# Clear the list store of its entries
$tree-path .= new(:string('0'));
$iter = $markers.tree-model-get-iter($tree-path);
while $iter.is-valid {
$iter = $markers.list-store-remove($iter);
}
# Get the key from the data column and check
$tree-path .= new(:native-object($n-tree-path));
$iter = $files.tree-model-get-iter($tree-path);
my Array[Gnome::GObject::Value] $v = $files.tree-model-get-value(
$iter, $data-col
);
my Str $data-key = $v[0].get-string // '';
$v[0].clear-object;
# Return if there is no filename key
return 1 unless ?$data-key;
# Add new entries from the data using the filename data key
for @($data{$data-key}) -> @entry {
$iter = $markers.list-store-append;
$markers.list-store-set( $iter, |(@entry.kv));
}
$!filename = $data-key;
}
#-----------------------------------------------------------------------------
method select-marker-entry (
N-GtkTreePath $n-tree-path, N-GObject $n-treeview-column,
Gnome::Gtk3::ListStore :$markers,
) {
my Gnome::Gtk3::TreePath $tree-path .= new(:native-object($n-tree-path));
my Gnome::Gtk3::TreeIter $iter = $markers.tree-model-get-iter($tree-path);
my Array[Gnome::GObject::Value] $v =
$markers.tree-model-get-value( $iter, 1);
my Int $line = $v[0].get-int // -1;
$v[0].clear-object;
note "Start atom editor with folowing file $!filename at line $line";
shell "atom $!filename:$line &";
}
}
The first class is called GuiHandlers::Application and is used to handle program specific signals [16-28]. There is only one handler defined exit-todo-viewer()
to exit the main loop and return to the main program. It returns 1 to show that all is handled by the sub.
The second class, GuiHandlers::ListView, is used to handle events from the two tree views and to modify the markers table. There is a method select-list-entry()
[36-75] to handle the double click on the files table and another method select-marker-entry()
[78-100] to handle the double click on the markers table.
When the row-activated
signal is emitted, it will call a handler which must have the following api;
method handler (
N-GtkTreePath $path, N-GObject $column,
Gnome::GObject::Object :widget($tree_view),
*%user-options
);
The first two arguments, $n-tree-path
and $n-treeview-column
[37], are obligatory, even when you do not need them. For instance, we do not need the $n-treeview-column
variable in this case. Also, the types are needed by the library to make a proper connection and cannot be left out. The named attributes are always optional and here we left out :$widget
here. The user options are those extra named attributes given to the register-signal()
method.
Before we insert the data, we clear the table first [46-52]. We start at the top row indicated by a path 0
[47]. This path is input to the iterator initialization [48]. In a while-loop we remove the row after which a new iterator is returned now pointing to the next row [51]. The path however is still 0
because the rows move up in the table. $iter.tree-iter-is-valid()
turns False
when there are no rows left.
The argument $n-tree-path
given to the handler, holds the row where the user has clicked on and we need to make an iterator from it [55,56]. From this row we get the key into the data hash ($data
) from the hidden column ($data-col
) in the files table ($files
). All these values are provided to the handler [57-61].
Finally, the data pointed by the data key in the data hash is inserted in the markers table [67-70].
The data key is the absolute path to the filename and is stored in an attribute for later use [72].
This is the same type of handler as described above. This time we needed less named arguments, only a markers table [80].
Convert the provided path into an iterator [84,85] and get the line number from the second column [87-90]. The filename was already saved in the above signal handler select-list-entry()
in $!filename
.
Here we use it to start the github atom editor and provide the file and line number [93].