Status: | Merged |
---|---|
Approved by: | Akshay Shekher |
Approved revision: | 17 |
Merge reported by: | Akshay Shekher |
Merged at revision: | not available |
Proposed branch: | lp:~ebanyash/cable/cable-e |
Merge into: | lp:cable |
Diff against target: |
1271 lines (+483/-335) 10 files modified
.bzrignore (+2/-0) CMakeLists.txt (+4/-3) INSTALL (+3/-3) bin/quickbuild.sh (+11/-0) src/Backend.vala (+0/-215) src/Cable.vala (+37/-37) src/Global.vala (+4/-4) src/Widgets/Room.vala (+40/-40) src/Widgets/Server.vala (+37/-33) src/doodleIRC.vala (+345/-0) |
To merge this branch: | bzr merge lp:~ebanyash/cable/cable-e |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Akshay Shekher (community) | Approve | ||
Evan Banyash (community) | Approve | ||
elementary Apps team | Pending | ||
Review via email: mp+163713@code.launchpad.net |
Commit message
Description of the change
I changed the installation instructions to be more correct, brought in voldyman's functional backend and credited him for it.
This is important because as of now, the project's trunk is non-functional. It crashes upon trying to join a channel.
Evan Banyash (ebanyash) wrote : | # |
And... done.
This is how you use the "Resubmit" review type, right?
Evan Banyash (ebanyash) wrote : | # |
> And... done.
>
> This is how you use the "Resubmit" review type, right?
...No, apparently it is not.
Sorry, I'm a bit GNU here.
Akshay Shekher (voldyman) wrote : | # |
my mistake, i meant remove the executable attribute (make all fines -x)
and your last commit is empty.
- 11. By Evan Banyash
-
small update to root cmakelists
- 12. By Evan Banyash
-
Okay, -x on everything now
- 13. By Evan Banyash
-
merging to avoid conflicting branches, apparently
Evan Banyash (ebanyash) wrote : | # |
> my mistake, i meant remove the executable attribute (make all fines -x)
>
> and your last commit is empty.
Yeah, I guess it was empty because everything was already +x. I thought that was normal when just changing permissions. I guess not. Okay, it should all be -x now except the directories because apparently you can't really use them without the execute bit.
Akshay Shekher (voldyman) wrote : | # |
for the backend, could you get the latest one from github.
that would be the ultimate merge :)
Evan Banyash (ebanyash) wrote : | # |
> for the backend, could you get the latest one from
> github.
>
> that would be the ultimate merge :)
Good idea. I'll see what I can do.
Hopefully nothing will break too bad.
Evan Banyash (ebanyash) wrote : | # |
Hmm... do you suggest that I keep doodleIRC.vala intact and change the server widget? Then we'd have two namespaces in the project. Is that okay? Or should I change the namespace of doodleIRC.vala to be in Cable?
Akshay Shekher (voldyman) wrote : | # |
You could keep it intact so the frontend and back end will be separate and
easier to update later.
On May 16, 2013 7:20 PM, "Evan Banyash" <email address hidden> wrote:
> Hmm... do you suggest that I keep doodleIRC.vala intact and change the
> server widget? Then we'd have two namespaces in the project. Is that okay?
> Or should I change the namespace of doodleIRC.vala to be in Cable?
> --
> https:/
> You are reviewing the proposed merge of lp:~ebanyash/cable/cable-e into
> lp:cable.
>
- 14. By Evan Banyash
-
Moved to latest DoodleIRC backend
- 15. By Evan Banyash
-
Deleted the old Backend.vala
Evan Banyash (ebanyash) wrote : | # |
And, done. Everything appears to still work, too!
- 16. By Evan Banyash
-
okay, I forgot to add this last time. Whew, crisis over
- 17. By Evan Banyash
-
added a script to build and test at super fast speeds
Akshay Shekher (voldyman) wrote : | # |
very good work.
Preview Diff
1 | === added file '.bzrignore' |
2 | --- .bzrignore 1970-01-01 00:00:00 +0000 |
3 | +++ .bzrignore 2013-05-17 01:15:34 +0000 |
4 | @@ -0,0 +1,2 @@ |
5 | +build |
6 | +*~ |
7 | \ No newline at end of file |
8 | |
9 | === modified file 'CMakeLists.txt' |
10 | --- CMakeLists.txt 2012-10-25 19:43:33 +0000 |
11 | +++ CMakeLists.txt 2013-05-17 01:15:34 +0000 |
12 | @@ -1,6 +1,6 @@ |
13 | # Check http://webdev.elementaryos.org/docs/developer-guide/cmake for documentation |
14 | |
15 | -project (agenda) |
16 | +project (cable) |
17 | cmake_minimum_required (VERSION 2.8) |
18 | cmake_policy (VERSION 2.6) |
19 | |
20 | @@ -41,7 +41,7 @@ |
21 | |
22 | include(ValaPrecompile) |
23 | vala_precompile(VALA_C |
24 | - src/Backend.vala |
25 | + src/doodleIRC.vala |
26 | src/Cable.vala |
27 | src/Global.vala |
28 | src/Settings.vala |
29 | @@ -52,6 +52,7 @@ |
30 | PACKAGES |
31 | granite |
32 | OPTIONS |
33 | + --target-glib=2.32 |
34 | --vapidir=${CMAKE_CURRENT_SOURCE_DIR}/vapi/ |
35 | ) |
36 | |
37 | @@ -64,4 +65,4 @@ |
38 | |
39 | install(TARGETS cable RUNTIME DESTINATION bin) |
40 | install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/data/cable.desktop DESTINATION share/applications) |
41 | -#install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/data/agenda.svg DESTINATION share/icons/hicolor/48x48/apps) |
42 | +#install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/data/cable.svg DESTINATION share/icons/hicolor/48x48/apps) And this is where I'd put my icon... IF I HAD ONE |
43 | |
44 | === modified file 'INSTALL' |
45 | --- INSTALL 2012-08-22 15:00:43 +0000 |
46 | +++ INSTALL 2013-05-17 01:15:34 +0000 |
47 | @@ -9,10 +9,10 @@ |
48 | gdk-x11-3.0 |
49 | |
50 | Installation: |
51 | - bzr branch lp:eidete |
52 | - cd eidete |
53 | + bzr branch lp:cable |
54 | + cd cable |
55 | mkdir build |
56 | cd build |
57 | - cmake .. -DCMAKE_INSTALL_PREFIX |
58 | + cmake .. |
59 | make |
60 | sudo make install |
61 | |
62 | === added directory 'bin' |
63 | === added file 'bin/quickbuild.sh' |
64 | --- bin/quickbuild.sh 1970-01-01 00:00:00 +0000 |
65 | +++ bin/quickbuild.sh 2013-05-17 01:15:34 +0000 |
66 | @@ -0,0 +1,11 @@ |
67 | +#!/bin/sh |
68 | +# |
69 | +# |
70 | +mkdir ../build; |
71 | +cd ../build; |
72 | +rm -rf *; |
73 | +cmake ..; |
74 | +make; |
75 | +cd ../bin; |
76 | +ln ../build/cable cable; |
77 | +./cable |
78 | \ No newline at end of file |
79 | |
80 | === removed file 'src/Backend.vala' |
81 | --- src/Backend.vala 2012-10-25 19:43:33 +0000 |
82 | +++ src/Backend.vala 1970-01-01 00:00:00 +0000 |
83 | @@ -1,215 +0,0 @@ |
84 | - |
85 | -namespace Cable.Backend { |
86 | - |
87 | - public class Server { |
88 | - public List<string> chans; |
89 | - string nick; |
90 | - string server_url; |
91 | - User user; |
92 | - SocketConnection connection; |
93 | - unowned Thread<int> thread; |
94 | - bool connected; |
95 | - List<string> to_send; |
96 | - |
97 | - public Server (string url, User user, string nick) { |
98 | - this.server_url = url; |
99 | - this.user = user; |
100 | - this.nick = nick; |
101 | - |
102 | - this.chans = new List<string> (); |
103 | - connected = false; |
104 | - to_send = new List<string> (); |
105 | - |
106 | - on_connect_complete.connect (() =>{ |
107 | - to_send.foreach ((cmd) => { |
108 | - print ("Sending "+cmd); |
109 | - raw_send (cmd); |
110 | - to_send.remove (cmd); |
111 | - }); |
112 | - |
113 | - }); |
114 | - } |
115 | - |
116 | - ~DoodleIRCServer () { |
117 | - quit_server ("Client Quit"); |
118 | - Thread.exit (1); |
119 | - |
120 | - } |
121 | - |
122 | - public void change_nick (string chan, string nick) { |
123 | - this.nick = nick; |
124 | - raw_send ("NICK %s\r\n".printf (this.nick)); |
125 | - } |
126 | - |
127 | - public void connect () { |
128 | - if (!connected) { |
129 | - try { |
130 | - thread = Thread.create<int> (this.loop, false); |
131 | - } catch (Error e) { |
132 | - error ("Could Not Start Thread: %s".printf (e.message)); |
133 | - } |
134 | - } |
135 | - } |
136 | - |
137 | - |
138 | - public int loop () { |
139 | - |
140 | - try { |
141 | - // Resolve hostname to IP address |
142 | - var resolver = Resolver.get_default (); |
143 | - var addresses = resolver.lookup_by_name (this.server_url, null); |
144 | - var address = addresses.nth_data (0); |
145 | - print ("Resolved %s to %s\n".printf (this.server_url, address.to_string ())); |
146 | - |
147 | - // Connect |
148 | - var client = new SocketClient (); |
149 | - connection = client.connect (new InetSocketAddress (address, 6667)); |
150 | - print ("Connected to %s\n".printf (this.server_url)); |
151 | - |
152 | - // Send USER request |
153 | - var message = "USER %s %s %s :%s\r\n".printf (user.username, user.hostname, |
154 | - user.servername, user.realname); |
155 | - raw_send (message); |
156 | - print ("Wrote request USER\n"); |
157 | - |
158 | - // Send NICK request |
159 | - message = "NICK %s\r\n".printf (nick); |
160 | - raw_send (message); |
161 | - print ("Wrote nick request\n"); |
162 | - |
163 | - var response = new DataInputStream (connection.input_stream); |
164 | - |
165 | - on_connect_complete (); |
166 | - connected = true; |
167 | - // Receive response |
168 | - string line="", msg="", sender="" , chan="" , cmd="" ; |
169 | - while (true) { |
170 | - line = response.read_line (null).strip (); |
171 | - if (line[0] == ':') |
172 | - parse_line (line, out sender,out cmd, out chan, out msg); |
173 | - else { |
174 | - cmd = line.split (" ")[0].strip (); |
175 | - } |
176 | - switch (cmd) { |
177 | - case "PING": |
178 | - print ("pinged\n"); |
179 | - raw_send (line.replace("PING","PONG")); |
180 | - break; |
181 | - case "NOTICE": |
182 | - print ("Noice: "+msg.strip ()+"\n"); |
183 | - on_notice (msg.strip ()); |
184 | - break; |
185 | - case "PRIVMSG": |
186 | - print ("Chan-> "+chan+"\nMSG-> "+msg+"\n"); |
187 | - on_message (sender, chan, msg); |
188 | - break; |
189 | - |
190 | - case "QUIT": |
191 | - print (" %s has quit\n".printf (sender)); |
192 | - break; |
193 | - |
194 | - case "JOIN": |
195 | - print ("User has Joined"); |
196 | - on_user_join (chan, nick); |
197 | - break; |
198 | - |
199 | - case "433": // nick name is use |
200 | - change_nick (chan,this.nick+"_"); |
201 | - rejoin_channels (); |
202 | - break; |
203 | - case "353": |
204 | - on_names_listed (msg.split (" ")); |
205 | - break; |
206 | - default: |
207 | - print (line+"\n\n\n"); |
208 | - break; |
209 | - } |
210 | - |
211 | - } |
212 | - } catch (Error e) { |
213 | - stderr.printf ("%s\n", e.message); |
214 | - } |
215 | - return 0; |
216 | - } |
217 | - |
218 | - private void raw_send (string line) { |
219 | - try { |
220 | - connection.output_stream.write (line.data); |
221 | - connection.output_stream.flush (); |
222 | - } catch (Error e) { |
223 | - error ("raw_send: %s".printf (e.message)); |
224 | - } |
225 | - } |
226 | - |
227 | - void parse_line (string line, out string sender,out string cmd, out string chan, out string msg) { |
228 | - //split the message from the info |
229 | - var first_split = line.split (":"); |
230 | - var info = first_split[1]; |
231 | - //msg = join_str_ar (2, first_split.length, first_split); |
232 | - msg = line.split (" :")[1]; |
233 | - |
234 | - //split the info to extract sender and chan |
235 | - var second_split = info.split (" "); |
236 | - cmd = second_split[1].strip (); |
237 | - chan = second_split[2].strip (); |
238 | - sender = second_split[0].strip (); |
239 | - } |
240 | - |
241 | - private void process_message () { |
242 | - |
243 | - } |
244 | - |
245 | - public void send (string cmd) { |
246 | - if (connected) |
247 | - raw_send (cmd); |
248 | - else |
249 | - to_send.append (cmd); |
250 | - } |
251 | - private void rejoin_channels () { |
252 | - // Send JOIN request |
253 | - foreach (string chan in chans) { |
254 | - join_chan (chan); |
255 | - print ("Wrote request to join %s\n".printf (chan)); |
256 | - } |
257 | - } |
258 | - public void kick_user (string chan, string user, string reason) { |
259 | - send ("KICK %s %s :%s\r\n".printf (chan, user, reason)); |
260 | - } |
261 | - |
262 | - public void join_chan (string chan) { |
263 | - send ("JOIN %s\r\n".printf (chan)); |
264 | - chans.append (chan); |
265 | - } |
266 | - |
267 | - public void quit_server (string message) { |
268 | - send ("QUIT :%s\r\n".printf (message)); |
269 | - } |
270 | - |
271 | - public void exit_chan (string chan) { |
272 | - send ("PART %s\r\n".printf (chan)); |
273 | - } |
274 | - |
275 | - public void write (string chan, string msg) { |
276 | - send ("PRIVMSG %s :%s\r\n".printf (chan, msg)); |
277 | - } |
278 | - |
279 | - public void get_names (string chan) { |
280 | - send ("NAMES %s\r\n".printf(chan)); |
281 | - } |
282 | - |
283 | - //public void |
284 | - public signal void on_connect_complete (); |
285 | - public signal void on_message (string sender, string chan, string msg); |
286 | - public signal void on_notice (string notice); |
287 | - public signal void on_error (string error_msg); |
288 | - public signal void on_user_join (string chan, string nick); |
289 | - public signal void on_names_listed (string[] names); |
290 | - } |
291 | - |
292 | - public struct User { |
293 | - public string username; |
294 | - public string hostname; |
295 | - public string servername; |
296 | - public string realname; |
297 | - } |
298 | -} |
299 | |
300 | === modified file 'src/Cable.vala' |
301 | --- src/Cable.vala 2012-10-25 19:43:33 +0000 |
302 | +++ src/Cable.vala 2013-05-17 01:15:34 +0000 |
303 | @@ -7,39 +7,39 @@ |
304 | { |
305 | program_name = "Cable"; |
306 | exec_name = "cable"; |
307 | - |
308 | + |
309 | build_data_dir = Constants.DATADIR; |
310 | build_pkg_data_dir = Constants.PKGDATADIR; |
311 | build_release_name = Constants.RELEASE_NAME; |
312 | build_version = Constants.VERSION; |
313 | build_version_info = Constants.VERSION_INFO; |
314 | - |
315 | + |
316 | app_years = "2012"; |
317 | app_icon = "applications-chat"; |
318 | app_launcher = "cable.desktop"; |
319 | application_id = "net.launchpad.cable"; |
320 | - |
321 | + |
322 | main_url = "https://code.launchpad.net/cable"; |
323 | bug_url = "https://bugs.launchpad.net/cable"; |
324 | help_url = "https://code.launchpad.net/cable"; |
325 | translate_url = "https://translations.launchpad.net/cable"; |
326 | - |
327 | - about_authors = {"Tom Beckmann <tombeckmann@online.de>"}; |
328 | + |
329 | + about_authors = {"Tom Beckmann <tombeckmann@online.de>", "Akshay Shekher <voldyman666@gmail.com"}; |
330 | about_documenters = {"Tom Beckmann <tombeckmann@online.de>"}; |
331 | about_artists = {"Harvey Cabaguio"}; |
332 | about_comments = "Development release, not all features implemented"; |
333 | about_translators = ""; |
334 | about_license_type = Gtk.License.GPL_3_0; |
335 | } |
336 | - |
337 | + |
338 | Gtk.Window window; |
339 | public Granite.Widgets.SourceList servers; |
340 | public Gtk.EventBox display_box; |
341 | - |
342 | + |
343 | public App () |
344 | { |
345 | } |
346 | - |
347 | + |
348 | void build () |
349 | { |
350 | window = new Gtk.Window (); |
351 | @@ -49,33 +49,33 @@ |
352 | servers = new Granite.Widgets.SourceList (); |
353 | var menu = new Gtk.Menu (); |
354 | display_box = new Gtk.EventBox (); |
355 | - |
356 | + |
357 | var join_channel = new Gtk.ToolButton (new Gtk.Image.from_icon_name ("internet-web-browser", Gtk.IconSize.LARGE_TOOLBAR), _("Join a Channel")); |
358 | var add_server = new Gtk.ToolButton (new Gtk.Image.from_icon_name ("tab-new", Gtk.IconSize.LARGE_TOOLBAR), _("Add a Server")); |
359 | var edit_user = new Gtk.MenuItem.with_label (_("Edit User Settings")); |
360 | - |
361 | + |
362 | var welcome = new Granite.Widgets.Welcome (_("Welcome to Cable"), _("Connect to the IRC world")); |
363 | welcome.append ("internet-web-browser", _("Channel"), _("Join a Channel")); |
364 | welcome.append ("tab-new", _("Server"), _("Add a Custom Server")); |
365 | - |
366 | + |
367 | var exp = new Gtk.ToolItem (); |
368 | exp.set_expand (true); |
369 | - |
370 | + |
371 | menu.append (edit_user); |
372 | - |
373 | + |
374 | toolbar.insert (join_channel, -1); |
375 | toolbar.insert (add_server, -1); |
376 | toolbar.insert (exp, -1); |
377 | toolbar.insert (create_appmenu (menu), -1); |
378 | - |
379 | + |
380 | main.pack_start (toolbar, false); |
381 | main.pack_start (paned); |
382 | - |
383 | + |
384 | paned.pack1 (servers, false, true); |
385 | paned.pack2 (display_box, true, true); |
386 | - |
387 | + |
388 | display_box.add (welcome); |
389 | - |
390 | + |
391 | window.set_application (this); |
392 | window.title = "Cable"; |
393 | window.icon_name = "applications-chat"; |
394 | @@ -83,9 +83,9 @@ |
395 | window.window_position = Gtk.WindowPosition.CENTER; |
396 | window.add (main); |
397 | window.show_all (); |
398 | - |
399 | + |
400 | window.show_all (); |
401 | - |
402 | + |
403 | welcome.activated.connect ((index) => { |
404 | if (index == 0) { |
405 | var dialog = get_join_dialog (); |
406 | @@ -124,10 +124,10 @@ |
407 | display_box.show_all (); |
408 | } |
409 | }); |
410 | - |
411 | + |
412 | /*initial setup*/ |
413 | var settings = Cable.Settings.get_default (); |
414 | - |
415 | + |
416 | //configuration incomplete |
417 | if (settings.real_name == "" || settings.nick == "") { |
418 | var settings_dialog = new Widgets.SettingsDialog (); |
419 | @@ -135,57 +135,57 @@ |
420 | settings_dialog.show_all (); |
421 | settings_dialog.run (); |
422 | } |
423 | - |
424 | + |
425 | //we got something to do |
426 | if (settings.favorites.length > 0) { |
427 | - |
428 | + |
429 | } |
430 | } |
431 | - |
432 | + |
433 | public Gtk.Dialog get_join_dialog () |
434 | { |
435 | var dialog = new Gtk.Dialog (); |
436 | dialog.modal = true; |
437 | - |
438 | + |
439 | var box = new Gtk.Grid (); |
440 | box.margin = 12; |
441 | box.column_spacing = 6; |
442 | box.row_spacing = 6; |
443 | - |
444 | + |
445 | var entry = new Gtk.Entry (); |
446 | entry.secondary_icon_name = "edit-redo-symbolic"; |
447 | - |
448 | + |
449 | var list = Widgets.Server.get_server_list (); |
450 | - |
451 | + |
452 | box.attach (new Gtk.Label (_("Server")), 0, 0, 1, 1); |
453 | box.attach (list, 1, 0, 1, 1); |
454 | box.attach (new Gtk.Label (_("Join Channel") + " #"), 0, 1, 1, 1); |
455 | box.attach (entry, 1, 1, 1, 1); |
456 | box.margin = 6; |
457 | - |
458 | + |
459 | entry.icon_release.connect (() => entry.activate ()); |
460 | entry.activate.connect (() => { |
461 | foreach (var server in servers.root.children) { |
462 | if (server is Widgets.Server && (server as Widgets.Server).uri == list.active_id) { |
463 | (server as Widgets.Server).join_channel ("#"+entry.text); |
464 | - |
465 | + |
466 | dialog.destroy (); |
467 | return; |
468 | } |
469 | } |
470 | - |
471 | + |
472 | servers.root.add (new Widgets.Server (this, list.get_active_text (), list.active_id, "#"+entry.text)); |
473 | dialog.destroy (); |
474 | }); |
475 | - |
476 | + |
477 | (dialog.get_content_area () as Gtk.Container).add (box); |
478 | dialog.title = _("Join Channel"); |
479 | - |
480 | + |
481 | entry.grab_focus (); |
482 | - |
483 | + |
484 | return dialog; |
485 | } |
486 | - |
487 | + |
488 | public override void activate () |
489 | { |
490 | build (); |
491 | @@ -196,8 +196,8 @@ |
492 | public static int main (string [] args) |
493 | { |
494 | Gtk.init (ref args); |
495 | - |
496 | + |
497 | var cable = new Cable.App (); |
498 | - |
499 | + |
500 | return cable.run (args); |
501 | } |
502 | |
503 | === modified file 'src/Global.vala' |
504 | --- src/Global.vala 2012-08-22 15:00:43 +0000 |
505 | +++ src/Global.vala 2013-05-17 01:15:34 +0000 |
506 | @@ -5,18 +5,18 @@ |
507 | get; |
508 | set; |
509 | } |
510 | - |
511 | + |
512 | Global () |
513 | { |
514 | - |
515 | + |
516 | } |
517 | - |
518 | + |
519 | static Global? instance; |
520 | public static Global get_default () |
521 | { |
522 | if (instance == null) |
523 | instance = new Global (); |
524 | - |
525 | + |
526 | return instance; |
527 | } |
528 | } |
529 | |
530 | === modified file 'src/Widgets/Room.vala' |
531 | --- src/Widgets/Room.vala 2012-10-25 19:43:33 +0000 |
532 | +++ src/Widgets/Room.vala 2013-05-17 01:15:34 +0000 |
533 | @@ -7,31 +7,31 @@ |
534 | VOICED, |
535 | REGULAR |
536 | } |
537 | - |
538 | + |
539 | public enum MessageType |
540 | { |
541 | NORMAL, |
542 | ENTER, |
543 | LEAVE |
544 | } |
545 | - |
546 | + |
547 | public class Room : Granite.Widgets.SourceList.Item |
548 | { |
549 | Granite.Widgets.SourceList.ExpandableItem operators; |
550 | Granite.Widgets.SourceList.ExpandableItem voiced; |
551 | Granite.Widgets.SourceList.ExpandableItem regular; |
552 | - |
553 | + |
554 | Granite.Widgets.SourceList users; |
555 | Gtk.TreeView chat; |
556 | Gtk.ScrolledWindow left_scrolled; |
557 | public Gtk.Box room; |
558 | - |
559 | + |
560 | public signal void send_message (string message); |
561 | - |
562 | + |
563 | public Room (string channel) |
564 | { |
565 | name = channel; |
566 | - |
567 | + |
568 | room = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); |
569 | var paned = new Gtk.Paned (Gtk.Orientation.HORIZONTAL); |
570 | var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); |
571 | @@ -45,18 +45,18 @@ |
572 | left_scrolled = new Gtk.ScrolledWindow (null, null); |
573 | var right_scrolled = new Gtk.ScrolledWindow (null, null); |
574 | var user = new Gtk.Label ("<span color='#999'>"+Global.get_default ().user_nick+"</span>"); |
575 | - |
576 | + |
577 | var left = new Gtk.CellRendererText (); |
578 | left.xalign = 1.0f; |
579 | left.width = 90; |
580 | left.font_desc = Pango.FontDescription.from_string ( |
581 | new GLib.Settings ("org.gnome.desktop.interface").get_string ("monospace-font-name")); |
582 | - |
583 | + |
584 | var right = new Gtk.CellRendererText (); |
585 | right.wrap_mode = Pango.WrapMode.WORD_CHAR; |
586 | right.wrap_width = -1; |
587 | right.font_desc = left.font_desc; |
588 | - |
589 | + |
590 | chat.enable_grid_lines = Gtk.TreeViewGridLines.VERTICAL; |
591 | chat.headers_visible = false; |
592 | chat.insert_column_with_attributes (-1, null, left, "markup", 0); |
593 | @@ -69,23 +69,23 @@ |
594 | }", -1); |
595 | } catch (Error e) { warning (e.message); } |
596 | chat.get_style_context ().add_provider (css, 40000); |
597 | - |
598 | + |
599 | label.halign = Gtk.Align.START; |
600 | - |
601 | + |
602 | topic_item.add (label); |
603 | topic_item.set_expand (true); |
604 | topic.insert (topic_item, -1); |
605 | topic.get_style_context ().add_class ("seconday-toolbar"); |
606 | - |
607 | + |
608 | operators = new Granite.Widgets.SourceList.ExpandableItem (_("Operators")); |
609 | voiced = new Granite.Widgets.SourceList.ExpandableItem ("Voiced"); |
610 | regular = new Granite.Widgets.SourceList.ExpandableItem ("Regular"); |
611 | users.root.add (operators); |
612 | users.root.add (voiced); |
613 | users.root.add (regular); |
614 | - |
615 | + |
616 | paned.get_style_context ().add_class ("sidebar-pane-separator"); |
617 | - |
618 | + |
619 | css = new Gtk.CssProvider (); |
620 | try { |
621 | css.load_from_data ("*{ |
622 | @@ -93,18 +93,18 @@ |
623 | }", -1); |
624 | } catch (Error e) { warning (e.message); } |
625 | users.get_style_context ().add_provider (css, 40000); |
626 | - |
627 | + |
628 | users.hscrollbar_policy = Gtk.PolicyType.NEVER; |
629 | users.width_request = 150; |
630 | - |
631 | + |
632 | paned.pack1 (box, true, false); |
633 | paned.pack2 (right_scrolled, false, false); |
634 | - |
635 | + |
636 | user.width_request = 99; |
637 | user.margin_right = 5; |
638 | user.xalign = 1.0f; |
639 | user.use_markup = true; |
640 | - |
641 | + |
642 | css = new Gtk.CssProvider (); |
643 | try { |
644 | css.load_from_data ("*{ |
645 | @@ -120,24 +120,24 @@ |
646 | }", -1); |
647 | } catch (Error e) { warning (e.message); } |
648 | entry.get_style_context ().add_provider (css, 40000); |
649 | - |
650 | + |
651 | bottom.pack_start (user, false); |
652 | bottom.pack_start (entry); |
653 | - |
654 | + |
655 | left_scrolled.add (chat); |
656 | - |
657 | + |
658 | box.pack_start (left_scrolled); |
659 | box.pack_start (bottom, false); |
660 | - |
661 | + |
662 | room.pack_start (topic, false); |
663 | room.pack_start (paned); |
664 | - |
665 | + |
666 | entry.activate.connect (() => { |
667 | send_message (entry.text); |
668 | - message ("tom95", entry.text); |
669 | + message (Global.get_default ().user_nick, entry.text); |
670 | entry.text = ""; |
671 | }); |
672 | - |
673 | + |
674 | bottom.draw.connect ((cr) => { |
675 | var grad = new Cairo.Pattern.linear (0, 0, 0, bottom.get_allocated_height () - 4); |
676 | grad.add_color_stop_rgb (0.0, 0.9, 0.9, 0.9); |
677 | @@ -145,18 +145,18 @@ |
678 | cr.rectangle (0, 0, bottom.get_allocated_width (), bottom.get_allocated_height ()); |
679 | cr.set_source (grad); |
680 | cr.fill (); |
681 | - |
682 | + |
683 | cr.move_to (0, 0); |
684 | cr.line_to (room.get_allocated_width (), 0); |
685 | cr.close_path (); |
686 | cr.set_source_rgba (0.1, 0.1, 0.1, 1.0); |
687 | cr.set_line_width (1); |
688 | cr.stroke (); |
689 | - |
690 | + |
691 | return false; |
692 | }); |
693 | } |
694 | - |
695 | + |
696 | public void add_user (string name, UserType type) |
697 | { |
698 | if (type == UserType.OPERATOR) |
699 | @@ -165,10 +165,10 @@ |
700 | voiced.add (new Granite.Widgets.SourceList.Item (name)); |
701 | else |
702 | regular.add (new Granite.Widgets.SourceList.Item (name)); |
703 | - |
704 | + |
705 | message (name, "", MessageType.ENTER); |
706 | } |
707 | - |
708 | + |
709 | public void remove_user (string name) |
710 | { |
711 | Granite.Widgets.SourceList.ExpandableItem[] lists = {voiced, operators, regular}; |
712 | @@ -176,36 +176,36 @@ |
713 | foreach (var child in list.children) { |
714 | if (child.name == name) { |
715 | list.remove (child); |
716 | - |
717 | + |
718 | message (child.name, "", MessageType.LEAVE); |
719 | - |
720 | + |
721 | return; |
722 | } |
723 | - |
724 | + |
725 | return; |
726 | } |
727 | } |
728 | } |
729 | - |
730 | + |
731 | public void message (owned string from, string message, MessageType type=MessageType.NORMAL) |
732 | { |
733 | bool do_scroll = left_scrolled.vadjustment.value + 10 > left_scrolled.vadjustment.upper; |
734 | - |
735 | + |
736 | Gtk.TreeIter iter; |
737 | (chat.model as Gtk.ListStore).append (out iter); |
738 | - |
739 | + |
740 | if (type == MessageType.NORMAL) { |
741 | - |
742 | + |
743 | if (from == Global.get_default ().user_nick) |
744 | from = "<span color='#999'>"+from+"</span>"; |
745 | else if (message.index_of (Global.get_default ().user_nick) != -1) |
746 | from = "<span color='#a00'>"+from+"</span>"; |
747 | - |
748 | + |
749 | (chat.model as Gtk.ListStore).set (iter, 0, from, 1, message); |
750 | } else |
751 | - (chat.model as Gtk.ListStore).set (iter, 0, "", |
752 | + (chat.model as Gtk.ListStore).set (iter, 0, "", |
753 | 1, "<span color='#999'>%s has %s the room.</span>".printf (from, type == MessageType.ENTER ? "entered" : "left")); |
754 | - |
755 | + |
756 | Timeout.add (10, () => { |
757 | if (do_scroll) |
758 | left_scrolled.vadjustment.value = left_scrolled.vadjustment.upper; |
759 | |
760 | === modified file 'src/Widgets/Server.vala' |
761 | --- src/Widgets/Server.vala 2012-10-25 19:48:49 +0000 |
762 | +++ src/Widgets/Server.vala 2013-05-17 01:15:34 +0000 |
763 | @@ -8,29 +8,34 @@ |
764 | "Freenode", " irc.freenode.net", |
765 | "GimpNET", "irc.gimp.org" |
766 | }; |
767 | - |
768 | - Backend.Server server; |
769 | + |
770 | + doodleIRC.DoodleIRCServer server; |
771 | App app; |
772 | - |
773 | + |
774 | public string uri; |
775 | - |
776 | + |
777 | public Server (App _app, string _name, string _uri, string? channel = null) |
778 | { |
779 | var settings = Settings.get_default (); |
780 | name = _name; |
781 | app = _app; |
782 | uri = _uri; |
783 | - |
784 | - Backend.User user = Backend.User () { |
785 | + |
786 | + doodleIRC.User user = doodleIRC.User () { |
787 | realname = settings.real_name, |
788 | hostname = settings.nick, |
789 | username = settings.nick, |
790 | servername = uri |
791 | }; |
792 | - server = new Backend.Server ("irc.freenode.net", user, settings.nick); |
793 | + server = new doodleIRC.DoodleIRCServer ("irc.freenode.net", user, settings.nick); |
794 | Global.get_default ().user_nick = settings.nick; //TODO use fallback nicks |
795 | - |
796 | - server.connect (); |
797 | + |
798 | + try { |
799 | + server.connect (); |
800 | + } catch (Error e) { |
801 | + //Needs Fixing |
802 | + Gtk.main_quit (); |
803 | + } |
804 | server.on_message.connect ((sender, chan, msg) => { |
805 | foreach (var room in children) { |
806 | if ((room as Room).name == chan) { |
807 | @@ -38,50 +43,50 @@ |
808 | return; |
809 | } |
810 | } |
811 | - |
812 | + |
813 | critical ("Channel '%s' has not been opened", chan); |
814 | - }); |
815 | - |
816 | + }); |
817 | + |
818 | if (channel != null) |
819 | join_channel (channel); |
820 | } |
821 | - |
822 | + |
823 | public void join_channel (string channel) |
824 | { |
825 | var room = new Room (channel); |
826 | add (room); |
827 | expand_all (); |
828 | - |
829 | + |
830 | room.send_message.connect ((msg) => server.write (room.name, msg)); |
831 | server.join_chan (channel); |
832 | - |
833 | + |
834 | app.servers.selected = room; |
835 | } |
836 | - |
837 | + |
838 | //builds up a ComboBox offering some default and your custom servers |
839 | public static Gtk.ComboBoxText get_server_list () |
840 | { |
841 | var box = new Gtk.ComboBoxText (); |
842 | - |
843 | + |
844 | //add the default ones |
845 | for (var i = 0; i < DEFAULT_SERVERS.length; i += 2) { |
846 | box.append (DEFAULT_SERVERS[i + 1], DEFAULT_SERVERS[i]); |
847 | } |
848 | - |
849 | + |
850 | //add the custom ones |
851 | foreach (var server in Settings.get_default ().servers) { |
852 | if (server == "") |
853 | continue; |
854 | - |
855 | + |
856 | var details = server.split (":"); |
857 | box.append (details[1], details[0]); |
858 | } |
859 | - |
860 | + |
861 | box.active = 0; |
862 | - |
863 | + |
864 | return box; |
865 | } |
866 | - |
867 | + |
868 | public static Gtk.Dialog get_add_dialog () |
869 | { |
870 | var dialog = new Gtk.Dialog.with_buttons (_("Add Server"), null, Gtk.DialogFlags.MODAL); |
871 | @@ -89,39 +94,38 @@ |
872 | var name = new Gtk.Entry (); |
873 | var url = new Gtk.Entry (); |
874 | var add = new Gtk.Button.with_label (_("Add Server")); |
875 | - |
876 | + |
877 | name.placeholder_text = "Server"; |
878 | url.placeholder_text = "irc.server.net"; |
879 | - |
880 | grid.margin = 12; |
881 | grid.column_spacing = 6; |
882 | grid.row_spacing = 6; |
883 | - |
884 | + |
885 | grid.attach (new Gtk.Label (_("Server Name:")), 0, 0, 1, 1); |
886 | grid.attach (name, 1, 0, 1, 1); |
887 | grid.attach (new Gtk.Label (_("Server URL:")), 0, 1, 1, 1); |
888 | grid.attach (url, 1, 1, 1, 1); |
889 | grid.attach (add, 1, 2, 1, 1); |
890 | - |
891 | + |
892 | url.activate.connect (() => add.clicked ()); |
893 | - |
894 | + |
895 | add.clicked.connect (() => { |
896 | var servers = Settings.get_default ().servers; |
897 | servers.resize (servers.length + 1); |
898 | servers[servers.length - 1] = name.text + ":" + url.text; |
899 | Settings.get_default ().servers = servers; |
900 | - |
901 | + |
902 | dialog.destroy (); |
903 | }); |
904 | - |
905 | + |
906 | name.changed.connect (() => add.sensitive = name.text != "" && url.text != ""); |
907 | url.changed.connect (() => add.sensitive = name.text != "" && url.text != ""); |
908 | - |
909 | + |
910 | add.sensitive = false; |
911 | - |
912 | + |
913 | (dialog.get_content_area () as Gtk.Container).add (grid); |
914 | - |
915 | + |
916 | return dialog; |
917 | } |
918 | } |
919 | -} |
920 | +} |
921 | \ No newline at end of file |
922 | |
923 | === added file 'src/doodleIRC.vala' |
924 | --- src/doodleIRC.vala 1970-01-01 00:00:00 +0000 |
925 | +++ src/doodleIRC.vala 2013-05-17 01:15:34 +0000 |
926 | @@ -0,0 +1,345 @@ |
927 | +// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*- |
928 | +/*** |
929 | + BEGIN LICENSE |
930 | + |
931 | + Copyright (C) 2013 Akshay Shekher <voldyman666@gmail.com> |
932 | + This program is free software: you can redistribute it and/or modify it |
933 | + under the terms of the GNU Lesser General Public License version 3, as published |
934 | + by the Free Software Foundation. |
935 | + |
936 | + This program is distributed in the hope that it will be useful, but |
937 | + WITHOUT ANY WARRANTY; without even the implied warranties of |
938 | + MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
939 | + PURPOSE. See the GNU General Public License for more details. |
940 | + |
941 | + You should have received a copy of the GNU General Public License along |
942 | + with this program. If not, see <http://www.gnu.org/licenses/> |
943 | + |
944 | + END LICENSE |
945 | +***/ |
946 | + |
947 | +namespace doodleIRC { |
948 | + |
949 | + public class DoodleIRCServer { |
950 | + |
951 | + // Signals |
952 | + public signal void on_connect_complete (); |
953 | + public signal void on_message (string sender, string chan, string msg); |
954 | + public signal void on_action (string sender, string chan, string msg); |
955 | + public signal void on_notice (string notice); |
956 | + public signal void on_error (string error_msg); |
957 | + public signal void on_user_join (string chan, string nick); |
958 | + public signal void on_join_complete (string chan, string nick); |
959 | + public signal void on_user_quit (string chan, string nick, string msg); |
960 | + public signal void on_names_listed (string chan,string[] names); |
961 | + |
962 | + public List<string> chans; |
963 | + string nick; |
964 | + bool away; |
965 | + string server_url; |
966 | + User user; |
967 | + SocketConnection connection; |
968 | + DataInputStream response; |
969 | + bool connected; |
970 | + List<string> to_send; |
971 | + Gee.HashMap<string, string> list_of_names; |
972 | + |
973 | + public DoodleIRCServer (string url, User user,string nick) { |
974 | + this.server_url = url; |
975 | + this.user = user; |
976 | + this.nick = nick; |
977 | + away = false; |
978 | + |
979 | + this.chans = new List<string> (); |
980 | + connected = false; |
981 | + to_send = new List<string> (); |
982 | + |
983 | + list_of_names = new Gee.HashMap<string,string> (); |
984 | + |
985 | + on_connect_complete.connect (() => { |
986 | + to_send.foreach ((cmd) => { |
987 | + print ("Sending "+cmd); |
988 | + raw_send (cmd); |
989 | + to_send.remove (cmd); |
990 | + }); |
991 | + }); |
992 | + } |
993 | + |
994 | + ~DoodleIRCServer () { |
995 | + print ("Exiting"); |
996 | + quit_server ("Client Quit"); |
997 | + } |
998 | + |
999 | + public async void connect (string server = "") { |
1000 | + try { |
1001 | + // Resolve hostname to IP address |
1002 | + var resolver = Resolver.get_default (); |
1003 | + var addresses = yield resolver.lookup_by_name_async (this.server_url, null); |
1004 | + var address = addresses.nth_data (0); |
1005 | + print ("Resolved %s to %s\n".printf (this.server_url, address.to_string ())); |
1006 | + |
1007 | + // Connect |
1008 | + var client = new SocketClient (); |
1009 | + connection = yield client.connect_async (new InetSocketAddress (address, 6667)); |
1010 | + print ("Connected to %s\n".printf (this.server_url)); |
1011 | + this.connected = true; |
1012 | + //response stream |
1013 | + response = new DataInputStream (connection.input_stream); |
1014 | + |
1015 | + // Send USER request |
1016 | + var message = "USER %s %s %s :%s\r\n".printf (user.username, user.hostname, |
1017 | + user.servername, user.realname); |
1018 | + raw_send (message); |
1019 | + print ("Wrote request USER\n"); |
1020 | + |
1021 | + // Send NICK request |
1022 | + message = "NICK %s\r\n".printf (nick); |
1023 | + raw_send (message); |
1024 | + print ("Wrote nick request\n"); |
1025 | + |
1026 | + wait.begin (); |
1027 | + } catch (Error e) { |
1028 | + error ("Could not connect: %s".printf (e.message)); |
1029 | + } |
1030 | + |
1031 | + } |
1032 | + |
1033 | + public async void wait () { |
1034 | + try { |
1035 | + var line = yield response.read_line_async (); |
1036 | + parse_line (line); |
1037 | + } catch (Error e) { |
1038 | + print ("Error: %s\n".printf (e.message)); |
1039 | + } |
1040 | + |
1041 | + if (connected) |
1042 | + wait.begin (); |
1043 | + } |
1044 | + |
1045 | + private void parse_line (string line) { |
1046 | + print (line + "\n"); |
1047 | + |
1048 | + if (line[0] != ':') { |
1049 | + process_named_server_message (line); |
1050 | + return; |
1051 | + } |
1052 | + |
1053 | + if (line[0] == ':') { |
1054 | + if ((line.split (" ")[1][0]).isdigit ()) { |
1055 | + process_numeric_cmd (line); |
1056 | + } else { |
1057 | + process_named_message (line); |
1058 | + } |
1059 | + } |
1060 | + } |
1061 | + |
1062 | + private void process_named_message (string line) { |
1063 | + string sender="", cmd="", chan="", msg=""; |
1064 | + parse_named_msg (line, out sender,out cmd, out chan, out msg); |
1065 | + |
1066 | + switch (cmd.up ()) { |
1067 | + case "PRIVMSG": |
1068 | + if (msg.split (" ")[0] == "\001ACTION") { |
1069 | + msg = msg.replace ("ACTION ", ""); |
1070 | + msg = msg.replace ("\001", ""); |
1071 | + on_action (sender, chan, msg); |
1072 | + break; |
1073 | + } |
1074 | + |
1075 | + print ("Chan-> "+chan+"\nMSG-> "+msg+"\n"); |
1076 | + on_message (sender, chan, msg); |
1077 | + break; |
1078 | + |
1079 | + case "QUIT": |
1080 | + print (" %s has quit\n".printf (sender)); |
1081 | + on_user_quit (chan, sender, msg); |
1082 | + break; |
1083 | + |
1084 | + case "JOIN": |
1085 | + if (sender == nick) { |
1086 | + on_join_complete (chan, sender); |
1087 | + break; |
1088 | + } |
1089 | + print ("User has Joined"); |
1090 | + on_user_join (chan, sender); |
1091 | + break; |
1092 | + } |
1093 | + } |
1094 | + |
1095 | + private void process_named_server_message (string line) { |
1096 | + var cmd = line.split (" ")[0].strip (); |
1097 | + var msg = line.split (" :")[1].strip (); |
1098 | + |
1099 | + switch (cmd.up ()) { |
1100 | + case "PING": |
1101 | + print ("pinged\n"); |
1102 | + raw_send (line.replace ("PING","PONG")); |
1103 | + break; |
1104 | + |
1105 | + case "NOTICE": |
1106 | + print ("Noice: "+msg+"\n"); |
1107 | + on_notice (msg); |
1108 | + break; |
1109 | + |
1110 | + case "ERROR": |
1111 | + print ("An Error Occured: %s\n".printf (msg)); |
1112 | + on_error (msg); |
1113 | + break; |
1114 | + } |
1115 | + } |
1116 | + |
1117 | + private void process_numeric_cmd (string line) { |
1118 | + var first_split = line.split (" "); |
1119 | + /* this might come handy in the future :) */ |
1120 | + //var sender = first_split[0].strip (); |
1121 | + var cmd = first_split[1].strip (); |
1122 | + var msg = line.split (" :")[1].strip (); |
1123 | + |
1124 | + /* more info about these commands can be found at the IRC RFC page */ |
1125 | + switch (cmd) { |
1126 | + case "001": |
1127 | + on_connect_complete (); |
1128 | + break; |
1129 | + |
1130 | + case "005": |
1131 | + // this.connect (msg); |
1132 | + break; |
1133 | + |
1134 | + case "301": |
1135 | + print ("Away: "+msg); |
1136 | + break; |
1137 | + |
1138 | + case "433": // nick name is use |
1139 | + change_nick (this.nick+"_"); |
1140 | + rejoin_channels (); |
1141 | + break; |
1142 | + |
1143 | + case "353": //RPL_NAMESLISTED |
1144 | + var chan = first_split[4]; |
1145 | + if (list_of_names.has_key (chan)) { |
1146 | + var names = list_of_names.get (chan); |
1147 | + names = " " + msg; |
1148 | + list_of_names.set (chan, names); |
1149 | + } else { |
1150 | + list_of_names.set (chan, msg); |
1151 | + } |
1152 | + |
1153 | + break; |
1154 | + |
1155 | + case "366": //RPL_ENDOFNAMES |
1156 | + foreach (var channel in list_of_names.keys.to_array ()) { |
1157 | + on_names_listed (channel, list_of_names.get (channel).split (" ")); |
1158 | + } |
1159 | + |
1160 | + list_of_names.clear (); |
1161 | + break; |
1162 | + } |
1163 | + } |
1164 | + |
1165 | + private void parse_named_msg (string line, out string sender,out string cmd, |
1166 | + out string chan, out string msg) { |
1167 | + // split the message from the info |
1168 | + var first_split = line.split (":"); |
1169 | + var info = first_split[1]; |
1170 | + // msg = join_str_ar (2, first_split.length, first_split); |
1171 | + msg = line.split (" :")[1]; |
1172 | + |
1173 | + // split the info to extract sender and chan |
1174 | + var second_split = info.split (" "); |
1175 | + cmd = second_split[1].strip (); |
1176 | + chan = second_split[2].strip (); |
1177 | + sender = second_split[0].strip ().split ("!")[0]; |
1178 | + } |
1179 | + |
1180 | + private void raw_send (string line) { |
1181 | + try { |
1182 | + connection.output_stream.write (line.data); |
1183 | + connection.output_stream.flush (); |
1184 | + } catch (Error e) { |
1185 | + error ("raw_send: %s".printf (e.message)); |
1186 | + } |
1187 | + } |
1188 | + |
1189 | + public void send (string cmd) { |
1190 | + if (connected) |
1191 | + raw_send (cmd); |
1192 | + else |
1193 | + to_send.append (cmd); |
1194 | + } |
1195 | + |
1196 | + private void rejoin_channels () { |
1197 | + // Send JOIN request |
1198 | + foreach (string chan in chans) { |
1199 | + raw_send ("JOIN %s\r\n".printf (chan)); |
1200 | + print ("Wrote request to join %s\n".printf (chan)); |
1201 | + } |
1202 | + } |
1203 | + |
1204 | + public void kick_user (string chan, string user, string reason) { |
1205 | + send ("KICK %s %s :%s\r\n".printf (chan, user, reason)); |
1206 | + } |
1207 | + |
1208 | + public void join_chan (string chan, string key="") { |
1209 | + send ("JOIN %s :%s\r\n".printf (chan, key)); |
1210 | + chans.append (chan); |
1211 | + } |
1212 | + |
1213 | + public void quit_server (string message) { |
1214 | + send ("QUIT :%s\r\n".printf (message)); |
1215 | + } |
1216 | + |
1217 | + public void leave_chan (string chan) { |
1218 | + send ("PART %s\r\n".printf (chan)); |
1219 | + } |
1220 | + |
1221 | + public void write (string chan, string msg) { |
1222 | + send ("PRIVMSG %s :%s\r\n".printf (chan, msg)); |
1223 | + } |
1224 | + |
1225 | + public void notice (string to, string text) { |
1226 | + send ("NOTICE %s :%s\r\n".printf (to, text)); |
1227 | + } |
1228 | + |
1229 | + public void get_names (string chan) { |
1230 | + send ("NAMES %s\r\n".printf (chan)); |
1231 | + } |
1232 | + |
1233 | + public void set_away (string reason) { |
1234 | + away = true; |
1235 | + send ("AWAY :%s\r\n".printf (reason)); |
1236 | + } |
1237 | + |
1238 | + public void set_back () { |
1239 | + away = false; |
1240 | + send ("AWAY \r\n"); |
1241 | + } |
1242 | + |
1243 | + public void toggle_away (string reason = "") { |
1244 | + if (this.away) |
1245 | + set_back (); |
1246 | + else |
1247 | + set_away (reason); |
1248 | + } |
1249 | + |
1250 | + public void change_nick (string nick) { |
1251 | + this.nick = nick; |
1252 | + raw_send ("NICK %s\r\n".printf (this.nick)); |
1253 | + } |
1254 | + |
1255 | + public void write_action (string chan, string msg) { |
1256 | + write (chan, "\001ACTION %s\001\r\n".printf (msg)); |
1257 | + } |
1258 | + |
1259 | + public void disconnect () { |
1260 | + raw_send ("QUIT :bye"); |
1261 | + connected = false; |
1262 | + } |
1263 | + } |
1264 | + |
1265 | + public struct User { |
1266 | + public string username; |
1267 | + public string hostname; |
1268 | + public string servername; |
1269 | + public string realname; |
1270 | + } |
1271 | +} |
nice work.
please change the permissions of the files to -x from +x.