Merge lp:~julien-spautz/cable/model-view into lp:cable

Proposed by Julien Spautz
Status: Merged
Merged at revision: 107
Proposed branch: lp:~julien-spautz/cable/model-view
Merge into: lp:cable
Diff against target: 8665 lines (+4717/-2866)
50 files modified
CMakeLists.txt (+40/-13)
README.rst (+121/-0)
data/org.pantheon.cable.gschema.xml (+0/-5)
po/cable.pot (+138/-143)
po/fr.po (+173/-142)
src/Cable.vala (+63/-26)
src/Controller/Channel.vala (+170/-0)
src/Controller/Server.vala (+65/-0)
src/Controller/Window.vala (+163/-0)
src/Dialogs/JoinChannel.vala (+12/-11)
src/Dialogs/ManageIdentity.vala (+46/-19)
src/Dialogs/ManageNetwork.vala (+18/-11)
src/Dialogs/Preferences.vala (+23/-30)
src/Irc/Channel.vala (+322/-0)
src/Irc/Client.vala (+59/-0)
src/Irc/Irc.vala (+43/-0)
src/Irc/Maki.vala (+278/-0)
src/Irc/Server.vala (+731/-0)
src/Services/Client.vala (+0/-278)
src/Services/Identity.vala (+0/-124)
src/Services/Launcher.vala (+66/-0)
src/Services/Network.vala (+0/-104)
src/Services/Notification.vala (+48/-0)
src/Services/Settings.vala (+0/-143)
src/Services/Unity.vala (+0/-64)
src/Settings/Preferences.vala (+39/-0)
src/Settings/Settings.vala (+33/-0)
src/Tests/Tests.vala (+13/-0)
src/Tests/Utils.vala (+101/-0)
src/Utils.vala (+0/-69)
src/Utils/AutoScrolled.vala (+44/-0)
src/Utils/EmbeddedAlert.vala (+424/-0)
src/Utils/Identity.vala (+201/-0)
src/Utils/Network.vala (+146/-0)
src/Utils/Utils.vala (+65/-0)
src/View/Channel.vala (+38/-0)
src/View/Server.vala (+69/-0)
src/View/Window.vala (+100/-0)
src/Widgets/Channel.vala (+82/-73)
src/Widgets/ChatDisplay.vala (+125/-10)
src/Widgets/Room.vala (+232/-283)
src/Widgets/Server.vala (+64/-338)
src/Widgets/ServerList.vala (+0/-104)
src/Widgets/TopicBar.vala (+72/-0)
src/Widgets/User.vala (+4/-84)
src/Widgets/Welcome.vala (+23/-22)
src/Widgets/Window.vala (+263/-0)
src/Window.vala (+0/-317)
vapi/libwnck-3.0.deps (+0/-7)
vapi/libwnck-3.0.vapi (+0/-446)
To merge this branch: bzr merge lp:~julien-spautz/cable/model-view
Reviewer Review Type Date Requested Status
Eduard Gotwig (community) Needs Fixing
Review via email: mp+175434@code.launchpad.net

Description of the change

Bunch of small fixes, improves on that "internal-stuff" branch. Most importantly there is now an actual separation between frontent (widgets) and backend (maki, settings, unity, notify) so we can make UI changes without having to worry about backend stuff.

To post a comment you must log in.
Revision history for this message
Julien Spautz (julien-spautz) wrote :

4687 lines (+2199/-1537) 31 files modified (has conflicts)

Because gotwig loves unnessecarily large diffs :P

I moved some files, and the model/view separation in mainly moving a lot of code from one file to another, so that explains the diff size.

Revision history for this message
Julien Spautz (julien-spautz) wrote :

Also, when committing a merged branch, use the --author option. It seems to be missing in quite a lot of commits.

Revision history for this message
Julien Spautz (julien-spautz) wrote :

Conflicts are resolved, the branch is now ready for review.

lp:~julien-spautz/cable/model-view updated
100. By Julien Spautz

some changes to backend interface, partial cleanup of room class, fixed regressions

101. By Julien Spautz

simplified name completion function

102. By Julien Spautz

implemented automatic user colors, removed legacy code for manual user colors

Revision history for this message
Eduard Gotwig (gotwig) wrote :

A long channel topic makes the window grow very much in the X-Axis.

I would like to see a similar approach like in empathy to fix this, where you have a seperate expander button.

review: Needs Fixing
Revision history for this message
Julien Spautz (julien-spautz) wrote :

> A long channel topic makes the window grow very much in the X-Axis.
>
> I would like to see a similar approach like in empathy to fix this, where you
> have a seperate expander button.

I think you mean Y-axis (height), but yes I agree. I tried putting everything into a Gtk.Expander, but it looks weird. We'll probably need some custom widget.

lp:~julien-spautz/cable/model-view updated
103. By Julien Spautz

add topic expander

104. By Julien Spautz

only color user names, and not their messages, add some vertical padding between messaes in chat display

Revision history for this message
Julien Spautz (julien-spautz) wrote :

The topic is now collapseable/expandable. Also only user names are colored, to avoid everything being too colorful.

Revision history for this message
982c80311320c1b (alexander-wilms) wrote :

When I join channels with many users like #ubuntu the UI freezes fir me. Also, the "Join Channel" window is opened behind the main Window. Otherwise looking great

Revision history for this message
Julien Spautz (julien-spautz) wrote :

The freeze is a known bug, see bug #1201235

Revision history for this message
982c80311320c1b (alexander-wilms) wrote :

I noticed that user names in front of messages containing my name are black, not colored

Revision history for this message
982c80311320c1b (alexander-wilms) wrote :

One user, who was only online in #elementary-dev showed up in the other channels I had open, #libreoffice-design and #elementary-apps without having joined it

Revision history for this message
982c80311320c1b (alexander-wilms) wrote :

URL parsing doesn't work reliably. Valadoc urls are not completely highlighted

lp:~julien-spautz/cable/model-view updated
105. By Julien Spautz

color nick also for ping messages + add badge for unread messages

Revision history for this message
Julien Spautz (julien-spautz) wrote :

I think the valadoc URLs make problems because they contain exclamation points. There's already a bug report out there.
I fixed the color thing and added badges to the channel items displaying the amount of unread messages. The badge should also turn red if there is a ping message in the channel, but I think that's currently not possible. I might report a bug in granite for this.

lp:~julien-spautz/cable/model-view updated
106. By Julien Spautz

modified regex for URL matching

Revision history for this message
Julien Spautz (julien-spautz) wrote :

Valadoc URLs are now matched correctly.

lp:~julien-spautz/cable/model-view updated
107. By Julien Spautz

another slight regex modification

Revision history for this message
Julien Spautz (julien-spautz) wrote :
Revision history for this message
Eduard Gotwig (gotwig) wrote :

expander has no effect. (Ubuntu 13.10)

Where is the button to open Cable settings window?

Why do you use a fixed width for sidepanes?

review: Needs Fixing
Revision history for this message
Julien Spautz (julien-spautz) wrote :

The expander is a button with a gtk.arrow, don't know what went wrong but for me it works.

Prefs are currently unaccessible, not sure where to put them. The toolbar at the bottom left doesn't make sense, and an entry in the launcher quicklist is too far away... Any suggestions?

Sidepanes have a minimum size, but they are expandable. There might be some problems with the topic bar or the chat display that cause them to be fixed. I'll look into that later.

Revision history for this message
Eduard Gotwig (gotwig) wrote :

probably it would be good to link for now this settings window onto the username of the user nickname itself.

on hover, this should be a button, if the user clicks on it, open Cable preferences =)

Revision history for this message
Julien Spautz (julien-spautz) wrote :

I guess it would make more sense to open the "edit current identity" dialog when clicking the nick name.

Revision history for this message
Eduard Gotwig (gotwig) wrote :

we have such a dialog :D screenshot please...

Revision history for this message
Julien Spautz (julien-spautz) wrote :

You can open it using Ctrl+I but you currently cant change your nick name.

Revision history for this message
Julien Spautz (julien-spautz) wrote :

The bug where people appear in channels they haven't joined happens when they change their nick. The new nick is then added to all channels.

Revision history for this message
982c80311320c1b (alexander-wilms) wrote :

When I restart, Cable also often fails to re-join the channels

Revision history for this message
Julien Spautz (julien-spautz) wrote :

Yay implemented autoscrolling! (Will push soon)

lp:~julien-spautz/cable/model-view updated
108. By Julien Spautz

auto scrolling, not joined embedded alert

Revision history for this message
Julien Spautz (julien-spautz) wrote :

Pushed.

Revision history for this message
Eduard Gotwig (gotwig) wrote :

whats up with the sidebars :X sometimes they are fixed, and cant be moved.

review: Needs Information
Revision history for this message
Julien Spautz (julien-spautz) wrote :

> whats up with the sidebars :X sometimes they are fixed, and cant be moved.

It seems that this is caused by the topic, event though I don't know why. When collapsed it is ellipsized and when expanded it is wrapped so it should resize fine, but it doesn't.

lp:~julien-spautz/cable/model-view updated
109. By Julien Spautz

fixed most compilation warnings, cleaned up some code, readded preferences, made text selectable

110. By Julien Spautz

fixed issued with renaming, some internal changes, created autoscrolled class, stub controller class

111. By Julien Spautz

passive view, time stamps, unit testing, added README, fixed all warnings, activated experimental vala features (chained relational expressions and regex), use fatal warnings

Revision history for this message
Julien Spautz (julien-spautz) wrote :

Sorry guys this is taking so long, but I figured if I'm refactoring so much code, I might as well do it right.

Anyway, I implemented a new design pattern called passive view (it's a Model/View/Controller pattern) that makes the code significantly more readable and maintainable, even if the code now seems more complex. I also wrote a README file which is now included in the branch where I describe cable's new structure and how it works. If anything is unclear please tell me and I'll try to clearify it.

I also added proof of concept unit testing support which might prove to be very helpful in the future. There is currently only one test, which can be run using the --unit-test CLI switch.

Btw, the resize bug is still not fixed, it is most likely because of the topic or chat widget, but I haven't yet figured out how to fix it.

lp:~julien-spautz/cable/model-view updated
112. By Julien Spautz

added some more unit tests

113. By Julien Spautz

some more unit tests

114. By Julien Spautz

fixed runtime warnings, forgot to setup signals in Irc.Server.from_name constructor...

Revision history for this message
Eduard Gotwig (gotwig) wrote :

Ok there are two things which still bug me:

1. I can't remove my user identity

2. If the user gets forwarded to the channel ##javascript when he entered #javascript, on the next restart of Cable, it tries to connect to both ##javascript and #javascript.
Instead #javascript, the original entered channel, should no longer be an entry in the list.

review: Needs Fixing
Revision history for this message
Eduard Gotwig (gotwig) wrote :

Oh, and please show the corresponding identity name after each servername, example:

Freenode (gotwig)

Freenode (kate)

review: Needs Fixing
lp:~julien-spautz/cable/model-view updated
115. By Julien Spautz

fixing some problems concerning networks and identities

Revision history for this message
Julien Spautz (julien-spautz) wrote :

Removing identities should now work as expected, and I added the nick name after the server name, though it doesn't look nice as the nick is truncated most of the time.

lp:~julien-spautz/cable/model-view updated
116. By Julien Spautz

fix compilation errors

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2013-07-14 15:58:58 +0000
3+++ CMakeLists.txt 2013-08-11 12:01:40 +0000
4@@ -47,29 +47,53 @@
5
6 include(ValaPrecompile)
7 vala_precompile(VALA_C
8+
9 src/Cable.vala
10- src/Window.vala
11- src/Utils.vala
12-
13- src/Services/Client.vala
14- src/Services/Settings.vala
15- src/Services/Identity.vala
16- src/Services/Network.vala
17- src/Services/Unity.vala
18-
19- src/Widgets/Room.vala
20+
21+ src/Utils/Utils.vala
22+ src/Utils/AutoScrolled.vala
23+ src/Utils/EmbeddedAlert.vala
24+ src/Utils/Identity.vala
25+ src/Utils/Network.vala
26+
27+ src/Irc/Maki.vala
28+ src/Irc/Irc.vala
29+ src/Irc/Client.vala
30+ src/Irc/Server.vala
31+ src/Irc/Channel.vala
32+
33+ src/Controller/Window.vala
34+ src/Controller/Server.vala
35+ src/Controller/Channel.vala
36+
37+ src/View/Server.vala
38+ src/View/Channel.vala
39+ src/View/Window.vala
40+
41+ src/Settings/Settings.vala
42+ src/Settings/Preferences.vala
43+ src/Settings/SavedState.vala
44+
45+ src/Services/Launcher.vala
46+ src/Services/Notification.vala
47+
48+ src/Widgets/Window.vala
49+ src/Widgets/Welcome.vala
50 src/Widgets/Server.vala
51 src/Widgets/Channel.vala
52+ src/Widgets/Room.vala
53 src/Widgets/ChatDisplay.vala
54- src/Widgets/ServerList.vala
55 src/Widgets/User.vala
56- src/Widgets/Welcome.vala
57-
58+ src/Widgets/TopicBar.vala
59+
60 src/Dialogs/JoinChannel.vala
61 src/Dialogs/Preferences.vala
62 src/Dialogs/ManageIdentity.vala
63 src/Dialogs/ManageNetwork.vala
64
65+ src/Tests/Tests.vala
66+ src/Tests/Utils.vala
67+
68 ${CMAKE_BINARY_DIR}/src/Config.vala
69 PACKAGES
70 gtk+-3.0
71@@ -80,6 +104,9 @@
72 OPTIONS
73 --target-glib=2.32
74 --vapidir=${CMAKE_CURRENT_SOURCE_DIR}/vapi/
75+ --enable-experimental
76+ --fatal-warnings
77+ --verbose
78 )
79
80 add_subdirectory (po)
81
82=== added file 'README.rst'
83--- README.rst 1970-01-01 00:00:00 +0000
84+++ README.rst 2013-08-11 12:01:40 +0000
85@@ -0,0 +1,121 @@
86+Developer Documentation
87+=======================
88+
89+This document explains how cable works internally and what guidelines you should follow when developing for it.
90+
91+Design Pattern
92+==============
93+
94+The current design pattern could be called "Passive View", see http://martinfowler.com/eaaDev/PassiveScreen.html.
95+
96+The View
97+--------
98+
99+The View is a software layer that acts as an interface between the program and the user. The View can be acted upon by the user and notify the application of these events (using signals). But its state can also be changed by the application to present some content to the user or request input from the user.
100+
101+In the ``src/View`` folder you will find interfaces that the Controller uses to communicate with the View. The actual implementation can be found in the ``src/Widgets`` folder. This separation bears the advantage that we can change the implementation of the View completely as long as we implement the interfaces. This makes the application independant of the GUI, and we could replace it by a text-based UI or even by a computer simulated UI to run unit tests.
102+
103+Nota bene: The View does not know about any other module (except possibly ``src/Utils`` which contains functions accessible to everyone)
104+
105+The Model/Backend
106+-----------------
107+
108+The traditional name 'Model' doesn't really fit Cable's architecture, as it is based on an interactive networking protocol (namely the IRC protocol) and not on a set of data or even a database. The following modules form the backend of the app and are more or less independant of each other.
109+
110+**Irc**
111+
112+The Irc namespace contains wrapper classes that provide convenient methods, properties and signals that map to dbus calls to the maki IRC daemon. Following naming conventions have been used:
113+
114+ - All signals are prefixed with ``event_``
115+ - All methods that send commands to the server are prefixed with ``send_``
116+ - Most methods that yield an immediate return value are properties, if it makes sense
117+
118+Examples:
119+
120+ ``public void send_join (string key = "");``
121+
122+ ``public void event_join (string from);``
123+
124+ ``public bool joined { get; }``
125+
126+**Settings**
127+
128+The Settings namespace contains convenient interfaces to the dconf/gsettings using Granite.Services.Settings.
129+
130+**Services**
131+
132+The Services should (whenever possible) be static classes. Currently there is a ``Launcher`` class as interface to libunity and a ``Notification`` class as interface to libnotify. They should have an extremely simple API and contain only functions that are actually used in the app. For example, here you see the ``Cable.Services.Launcher`` API:
133+
134+ ``public static int64 jobs { get; set }``
135+
136+ ``public static double progress { get; set }``
137+
138+ ``public static bool urgent { get; set }``
139+
140+ ``public static void init ();``
141+
142+**Utils**
143+
144+This namespace contains some useful functions and classes that are used in multiple places in the app. The Network and Identity classes, for example, store all networks and identities in a convenient way and make sure no duplicates will be created.
145+
146+The Controller
147+--------------
148+
149+The controller is the brain of the app in the sense that it connects different classes that don't know about each other and contains most of the program logic. Conversely, no one knows about the Controller, which means no one can actively act upon the Controller. To communicate with other parts of the application, the Controller connects to their public signals, or uses their public methods and properties.
150+
151+********************************************************************************
152+
153+Tiers
154+=====
155+
156+Now that you know about the separation of concerns implemented by the Passive View pattern, I want to explain a recurring pattern in the app which can be broken up into 3 (or 4) tiers, a tree-like hierarchial structure. It looks like this:
157+
158+ Application Tier (one instance)
159+
160+ ↓ (n)
161+
162+ Window Tier (n windows per application, unless artificially restricted)
163+
164+ ↓ (n)
165+
166+ Server Tier (n server connections can be established per window)
167+
168+ ↓ (n)
169+
170+ Channel Tier (n channels per server)
171+
172+This means that the app owns multiple windows, each window has a list of servers, which in turn own any number of channels. This structure exists in many places in the program, which is why it is worth noticing. Obviously it exists in the View/Widgets layer, but also the controller is split into multiple classes, to get cleaner code.
173+
174+In order to make communication between different parts of the application as clean and abstract as possible, it shall *only* occur via these tiers. That is you should not (and cannot) access, any widgets from the Controller, as all communication has to happen via ``View.Window``, ``View.Server`` or ``View.Channel``.
175+
176+So instead of calling something like this from the controller:
177+
178+ ``channel_view.room.topic.text = new_topic;``
179+
180+you would use:
181+
182+ ``channel_view.topic = new_topic;``
183+
184+and the channel widget will take care of the forwarding.
185+
186+********************************************************************************
187+
188+Unit Testing
189+============
190+
191+Unit Testing, Test Driven Development, Extreme Programming… What can we learn from these techniques?
192+
193+GLib provides a very basic way to implement unit tests, and libgee built their TestCase class on it. It allows for simple unit tests, nothing fancy but really straight forward. The main question is where does it make sense to apply unit tests and how do we implement them in a sensible way.
194+
195+Most (virtually all) of the logic lies in the Controller module, as intended. This allows us to bypass the View and replace it by a fake View that implements the same interface but is controlled by the programm. In the same way, we can replace the backend and imitate it's interface to provide a fake backend and simulate really weird server bugs that only happen very rarely and can therefore not be reproduced reliably in a real world environement.
196+
197+Functions and classes in the Utils namespace can also easily be unit tested as they are not connected with the rest of the program. An example would be the URL parsing function.
198+
199+Note that none of this has been implemented (except to a very simple test which can be run using the ``--unit-test`` CLI switch, just as a proof of concept).
200+
201+********************************************************************************
202+
203+Questions?
204+==========
205+
206+If you have any questions relating to the architecture of the app, shoot me an email at <spautz.julien@gmail.com> or ask me on IRC (#elementary-dev or #elementary-apps on irc.freenode.net). My nick is julienspautz.
207\ No newline at end of file
208
209=== modified file 'data/org.pantheon.cable.gschema.xml'
210--- data/org.pantheon.cable.gschema.xml 2013-07-07 17:40:59 +0000
211+++ data/org.pantheon.cable.gschema.xml 2013-08-11 12:01:40 +0000
212@@ -23,10 +23,5 @@
213 <summary>Channels to be joined on startup, typically from last session</summary>
214 <description>These channels in the form "network address:nickname:#channel" will be joined on startup</description>
215 </key>
216- <key name="colors" type="as">
217- <default>[]</default>
218- <summary>Colors saved, by channel</summary>
219- <description>The format is ["network address:#channel:nickname:color", "..."]</description>
220- </key>
221 </schema>
222 </schemalist>
223
224=== modified file 'po/cable.pot'
225--- po/cable.pot 2013-07-04 14:08:00 +0000
226+++ po/cable.pot 2013-08-11 12:01:40 +0000
227@@ -3,13 +3,12 @@
228 # This file is distributed under the same license as the PACKAGE package.
229 # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
230 #
231-#: /home/gotwig/cable/po/../src/Widgets/Server.vala:145
232 #, fuzzy
233 msgid ""
234 msgstr ""
235 "Project-Id-Version: PACKAGE VERSION\n"
236 "Report-Msgid-Bugs-To: \n"
237-"POT-Creation-Date: 2013-07-04 16:07+0200\n"
238+"POT-Creation-Date: 2013-07-18 00:31+0200\n"
239 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
240 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
241 "Language-Team: LANGUAGE <LL@li.org>\n"
242@@ -18,247 +17,243 @@
243 "Content-Type: text/plain; charset=UTF-8\n"
244 "Content-Transfer-Encoding: 8bit\n"
245
246-#: /home/gotwig/cable/po/../src/Window.vala:302
247-#: /home/gotwig/cable/po/../src/Window.vala:303
248+#: /home/tutebatti/internal-stuff/po/../src/Cable.vala:48
249+msgid "Development release, not all features implemented"
250+msgstr ""
251+
252+#: /home/tutebatti/internal-stuff/po/../src/Cable.vala:91
253+msgid "Stylish IRC Client"
254+msgstr ""
255+
256+#: /home/tutebatti/internal-stuff/po/../src/Cable.vala:92
257+msgid "IRC Client"
258+msgstr ""
259+
260+#: /home/tutebatti/internal-stuff/po/../src/Window.vala:251
261+#: /home/tutebatti/internal-stuff/po/../src/Window.vala:252
262 msgid "Join Channel…"
263 msgstr ""
264
265-#: /home/gotwig/cable/po/../src/Window.vala:305
266-#: /home/gotwig/cable/po/../src/Window.vala:306
267+#: /home/tutebatti/internal-stuff/po/../src/Window.vala:254
268+#: /home/tutebatti/internal-stuff/po/../src/Window.vala:255
269 msgid "Leave current Channel"
270 msgstr ""
271
272-#: /home/gotwig/cable/po/../src/Window.vala:308
273-#: /home/gotwig/cable/po/../src/Window.vala:309
274+#: /home/tutebatti/internal-stuff/po/../src/Window.vala:257
275+#: /home/tutebatti/internal-stuff/po/../src/Window.vala:258
276 msgid "Edit current Identity…"
277 msgstr ""
278
279-#: /home/gotwig/cable/po/../src/Window.vala:311
280-#: /home/gotwig/cable/po/../src/Window.vala:312
281-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:23
282-msgid "Preferences"
283-msgstr ""
284-
285-#: /home/gotwig/cable/po/../src/Window.vala:314
286-#: /home/gotwig/cable/po/../src/Window.vala:315
287-msgid "About"
288-msgstr ""
289-
290-#: /home/gotwig/cable/po/../src/Cable.vala:48
291-msgid "Development release, not all features implemented"
292-msgstr ""
293-
294-#: /home/gotwig/cable/po/../src/Cable.vala:86
295-msgid "Stylish IRC Client"
296-msgstr ""
297-
298-#: /home/gotwig/cable/po/../src/Cable.vala:87
299-msgid "IRC Client"
300-msgstr ""
301-
302-#: /home/gotwig/cable/po/../src/Widgets/Welcome.vala:30
303+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Welcome.vala:30
304 msgid "Connect to IRC"
305 msgstr ""
306
307-#: /home/gotwig/cable/po/../src/Widgets/Welcome.vala:30
308-msgid "Select a Channel to join and begin to talk."
309+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Welcome.vala:30
310+msgid "Select a channel to join and begin to talk."
311 msgstr ""
312
313-#: /home/gotwig/cable/po/../src/Widgets/Welcome.vala:38
314-#: /home/gotwig/cable/po/../src/Dialogs/JoinChannel.vala:36
315+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Welcome.vala:38
316+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/JoinChannel.vala:36
317 msgid "Network:"
318 msgstr ""
319
320-#: /home/gotwig/cable/po/../src/Widgets/Welcome.vala:42
321-#: /home/gotwig/cable/po/../src/Dialogs/JoinChannel.vala:40
322+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Welcome.vala:42
323+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/JoinChannel.vala:40
324 msgid "Identity:"
325 msgstr ""
326
327-#: /home/gotwig/cable/po/../src/Widgets/Welcome.vala:46
328-#: /home/gotwig/cable/po/../src/Dialogs/JoinChannel.vala:44
329+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Welcome.vala:46
330+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/JoinChannel.vala:44
331 msgid "Channel:"
332 msgstr ""
333
334-#: /home/gotwig/cable/po/../src/Widgets/User.vala:35
335+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Welcome.vala:50
336+msgid "Connect"
337+msgstr ""
338+
339+#: /home/tutebatti/internal-stuff/po/../src/Widgets/User.vala:35
340 msgid "Change color…"
341 msgstr ""
342
343-#: /home/gotwig/cable/po/../src/Widgets/User.vala:41
344+#: /home/tutebatti/internal-stuff/po/../src/Widgets/User.vala:41
345 #, c-format
346 msgid "Select the new color for %s"
347 msgstr ""
348
349-#: /home/gotwig/cable/po/../src/Widgets/Server.vala:134
350-#: /home/gotwig/cable/po/../src/Widgets/Server.vala:146
351-msgid "Mark Away"
352-msgstr ""
353-
354-#: /home/gotwig/cable/po/../src/Widgets/Server.vala:135
355-msgid "Leave all channels"
356-msgstr ""
357-
358-#: /home/gotwig/cable/po/../src/Widgets/Server.vala:142
359-#: /home/gotwig/cable/po/../src/Services/Identity.vala:77
360-#, c-format
361-msgid "%s is away."
362-msgstr ""
363-
364-#: /home/gotwig/cable/po/../src/Widgets/Server.vala:143
365-msgid "Mark Present"
366-msgstr ""
367-
368-#: /home/gotwig/cable/po/../src/Widgets/Channel.vala:44
369-msgid "Leave Channel"
370-msgstr ""
371-
372-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:80
373-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:217
374-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:232
375+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:81
376+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:328
377+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:343
378 msgid "Operators"
379 msgstr ""
380
381-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:133
382-msgid "Loading Topic…"
383+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:242
384+msgid "Joining $(channel.name)"
385 msgstr ""
386
387-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:216
388-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:231
389+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:327
390+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:342
391 msgid "Regular"
392 msgstr ""
393
394-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:218
395-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:233
396+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:329
397+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:344
398 msgid "Voiced"
399 msgstr ""
400
401-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:289
402+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:411
403 #, c-format
404 msgid "%s joined"
405 msgstr ""
406
407-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:292
408+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:414
409 #, c-format
410 msgid "%s left"
411 msgstr ""
412
413-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:295
414+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:417
415 #, c-format
416 msgid "%s is away"
417 msgstr ""
418
419-#: /home/gotwig/cable/po/../src/Dialogs/JoinChannel.vala:26
420-msgid "Join Channel"
421-msgstr ""
422-
423-#: /home/gotwig/cable/po/../src/Dialogs/ManageNetwork.vala:44
424+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Channel.vala:49
425+msgid "Leave Channel"
426+msgstr ""
427+
428+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Server.vala:109
429+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Server.vala:121
430+msgid "Mark Away"
431+msgstr ""
432+
433+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Server.vala:110
434+msgid "Leave All Channels"
435+msgstr ""
436+
437+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Server.vala:118
438+msgid "Mark Present"
439+msgstr ""
440+
441+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:48
442+msgid "johndoe (Without spaces/special characters)"
443+msgstr ""
444+
445+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:53
446+msgid "John Doe"
447+msgstr ""
448+
449+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:57
450+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:63
451+msgid "Good night everyone!"
452+msgstr ""
453+
454+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:60
455+msgid "Try again later!"
456+msgstr ""
457+
458+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:65
459+msgid "Nick Name:"
460+msgstr ""
461+
462+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:67
463+msgid "Real Name:"
464+msgstr ""
465+
466+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:69
467+msgid "Part Message:"
468+msgstr ""
469+
470+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:71
471+msgid "Away Message:"
472+msgstr ""
473+
474+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:73
475+msgid "Quit Message:"
476+msgstr ""
477+
478+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:96
479+msgid "Add Identity"
480+msgstr ""
481+
482+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:96
483+msgid "Edit Identity"
484+msgstr ""
485+
486+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageNetwork.vala:44
487 msgid "irc.network.net"
488 msgstr ""
489
490-#: /home/gotwig/cable/po/../src/Dialogs/ManageNetwork.vala:47
491+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageNetwork.vala:47
492 msgid "Network IRC"
493 msgstr ""
494
495-#: /home/gotwig/cable/po/../src/Dialogs/ManageNetwork.vala:49
496+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageNetwork.vala:49
497 msgid "Optional"
498 msgstr ""
499
500-#: /home/gotwig/cable/po/../src/Dialogs/ManageNetwork.vala:53
501+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageNetwork.vala:53
502 msgid "Address:"
503 msgstr ""
504
505-#: /home/gotwig/cable/po/../src/Dialogs/ManageNetwork.vala:55
506+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageNetwork.vala:55
507 msgid "Name:"
508 msgstr ""
509
510-#: /home/gotwig/cable/po/../src/Dialogs/ManageNetwork.vala:57
511+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageNetwork.vala:57
512 msgid "Password:"
513 msgstr ""
514
515-#: /home/gotwig/cable/po/../src/Dialogs/ManageNetwork.vala:77
516+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageNetwork.vala:77
517 msgid "Add Network"
518 msgstr ""
519
520-#: /home/gotwig/cable/po/../src/Dialogs/ManageNetwork.vala:78
521+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageNetwork.vala:78
522 msgid "Change Network"
523 msgstr ""
524
525-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:30
526+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/JoinChannel.vala:26
527+msgid "Join Channel"
528+msgstr ""
529+
530+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:23
531+msgid "Preferences"
532+msgstr ""
533+
534+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:30
535 msgid "Networks"
536 msgstr ""
537
538-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:31
539+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:31
540 msgid "Identities"
541 msgstr ""
542
543-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:46
544+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:46
545 msgid "Name"
546 msgstr ""
547
548-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:47
549+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:47
550 msgid "Address"
551 msgstr ""
552
553-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:66
554-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:69
555+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:66
556+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:69
557 msgid "Add…"
558 msgstr ""
559
560-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:67
561-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:70
562-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:158
563-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:161
564+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:67
565+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:70
566+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:152
567+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:155
568 msgid "Remove"
569 msgstr ""
570
571-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:137
572+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:131
573 msgid "Nick"
574 msgstr ""
575
576-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:138
577+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:132
578 msgid "Real Name"
579 msgstr ""
580
581-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:157
582-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:160
583+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:151
584+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:154
585 msgid "Add"
586 msgstr ""
587-
588-#: /home/gotwig/cable/po/../src/Dialogs/ManageIdentity.vala:44
589-msgid "johndoe (Without spaces/special characters)"
590-msgstr ""
591-
592-#: /home/gotwig/cable/po/../src/Dialogs/ManageIdentity.vala:47
593-msgid "John Doe"
594-msgstr ""
595-
596-#: /home/gotwig/cable/po/../src/Dialogs/ManageIdentity.vala:49
597-msgid "Good night everyone !"
598-msgstr ""
599-
600-#: /home/gotwig/cable/po/../src/Dialogs/ManageIdentity.vala:51
601-msgid "Nick Name:"
602-msgstr ""
603-
604-#: /home/gotwig/cable/po/../src/Dialogs/ManageIdentity.vala:53
605-msgid "Real Name:"
606-msgstr ""
607-
608-#: /home/gotwig/cable/po/../src/Dialogs/ManageIdentity.vala:55
609-msgid "Part Message:"
610-msgstr ""
611-
612-#: /home/gotwig/cable/po/../src/Dialogs/ManageIdentity.vala:75
613-msgid "Add Identity"
614-msgstr ""
615-
616-#: /home/gotwig/cable/po/../src/Dialogs/ManageIdentity.vala:76
617-msgid "Edit Identity"
618-msgstr ""
619-
620-#: /home/gotwig/cable/po/../src/Services/Identity.vala:75
621-msgid "Bye."
622-msgstr ""
623-
624-#: /home/gotwig/cable/po/../src/Services/Identity.vala:76
625-msgid "Quit server."
626-msgstr ""
627
628=== modified file 'po/fr.po'
629--- po/fr.po 2013-07-05 06:01:24 +0000
630+++ po/fr.po 2013-08-11 12:01:40 +0000
631@@ -3,262 +3,293 @@
632 # This file is distributed under the same license as the cable package.
633 # FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
634 #
635+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Server.vala:406
636 msgid ""
637 msgstr ""
638 "Project-Id-Version: cable\n"
639 "Report-Msgid-Bugs-To: \n"
640-"POT-Creation-Date: 2013-07-04 16:07+0200\n"
641+"POT-Creation-Date: 2013-07-14 18:31+0200\n"
642 "PO-Revision-Date: 2013-07-04 17:57+0000\n"
643 "Last-Translator: Corentin Noël <tintou@mailoo.org>\n"
644 "Language-Team: Spanish <es@li.org>\n"
645+"Language: es\n"
646 "MIME-Version: 1.0\n"
647 "Content-Type: text/plain; charset=UTF-8\n"
648 "Content-Transfer-Encoding: 8bit\n"
649 "X-Launchpad-Export-Date: 2013-07-05 06:00+0000\n"
650 "X-Generator: Launchpad (build 16696)\n"
651-"Language: es\n"
652-
653-#: /home/gotwig/cable/po/../src/Window.vala:302
654-#: /home/gotwig/cable/po/../src/Window.vala:303
655+
656+#: /home/tutebatti/internal-stuff/po/../src/Cable.vala:48
657+msgid "Development release, not all features implemented"
658+msgstr "Version en développement, fonctions manquantes"
659+
660+#: /home/tutebatti/internal-stuff/po/../src/Cable.vala:86
661+msgid "Stylish IRC Client"
662+msgstr "Un client IRC élégant"
663+
664+#: /home/tutebatti/internal-stuff/po/../src/Cable.vala:87
665+msgid "IRC Client"
666+msgstr "Client IRC"
667+
668+#: /home/tutebatti/internal-stuff/po/../src/Window.vala:252
669+#: /home/tutebatti/internal-stuff/po/../src/Window.vala:253
670 msgid "Join Channel…"
671 msgstr "Rejoindre le canal…"
672
673-#: /home/gotwig/cable/po/../src/Window.vala:305
674-#: /home/gotwig/cable/po/../src/Window.vala:306
675+#: /home/tutebatti/internal-stuff/po/../src/Window.vala:255
676+#: /home/tutebatti/internal-stuff/po/../src/Window.vala:256
677 msgid "Leave current Channel"
678 msgstr "Quitter le canal actuel"
679
680-#: /home/gotwig/cable/po/../src/Window.vala:308
681-#: /home/gotwig/cable/po/../src/Window.vala:309
682+#: /home/tutebatti/internal-stuff/po/../src/Window.vala:258
683+#: /home/tutebatti/internal-stuff/po/../src/Window.vala:259
684 msgid "Edit current Identity…"
685 msgstr "Modifier l'identité actuelle"
686
687-#: /home/gotwig/cable/po/../src/Window.vala:311
688-#: /home/gotwig/cable/po/../src/Window.vala:312
689-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:23
690-msgid "Preferences"
691-msgstr "Préférences"
692-
693-#: /home/gotwig/cable/po/../src/Window.vala:314
694-#: /home/gotwig/cable/po/../src/Window.vala:315
695-msgid "About"
696-msgstr "À propos"
697-
698-#: /home/gotwig/cable/po/../src/Cable.vala:48
699-msgid "Development release, not all features implemented"
700-msgstr "Version en développement, fonctions manquantes"
701-
702-#: /home/gotwig/cable/po/../src/Cable.vala:86
703-msgid "Stylish IRC Client"
704-msgstr "Un client IRC élégant"
705-
706-#: /home/gotwig/cable/po/../src/Cable.vala:87
707-msgid "IRC Client"
708-msgstr "Client IRC"
709-
710-#: /home/gotwig/cable/po/../src/Widgets/Welcome.vala:30
711+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Welcome.vala:30
712 msgid "Connect to IRC"
713 msgstr "Se connecter à IRC"
714
715-#: /home/gotwig/cable/po/../src/Widgets/Welcome.vala:30
716-msgid "Select a Channel to join and begin to talk."
717-msgstr "Sélectionner un salon pour commencer à discuter"
718+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Welcome.vala:30
719+msgid "Select a channel to join and begin to talk."
720+msgstr ""
721
722-#: /home/gotwig/cable/po/../src/Widgets/Welcome.vala:38
723-#: /home/gotwig/cable/po/../src/Dialogs/JoinChannel.vala:36
724+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Welcome.vala:38
725+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/JoinChannel.vala:36
726 msgid "Network:"
727 msgstr "Réseau :"
728
729-#: /home/gotwig/cable/po/../src/Widgets/Welcome.vala:42
730-#: /home/gotwig/cable/po/../src/Dialogs/JoinChannel.vala:40
731+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Welcome.vala:42
732+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/JoinChannel.vala:40
733 msgid "Identity:"
734 msgstr "Identité :"
735
736-#: /home/gotwig/cable/po/../src/Widgets/Welcome.vala:46
737-#: /home/gotwig/cable/po/../src/Dialogs/JoinChannel.vala:44
738+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Welcome.vala:46
739+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/JoinChannel.vala:44
740 msgid "Channel:"
741 msgstr "Canal :"
742
743-#: /home/gotwig/cable/po/../src/Widgets/User.vala:35
744+#: /home/tutebatti/internal-stuff/po/../src/Widgets/User.vala:35
745 msgid "Change color…"
746 msgstr "Changer la couleur…"
747
748-#: /home/gotwig/cable/po/../src/Widgets/User.vala:41
749+#: /home/tutebatti/internal-stuff/po/../src/Widgets/User.vala:41
750 #, c-format
751 msgid "Select the new color for %s"
752 msgstr "Sélectionner une nouvelle couleur pour %s"
753
754-#: /home/gotwig/cable/po/../src/Widgets/Server.vala:134
755-#: /home/gotwig/cable/po/../src/Widgets/Server.vala:146
756-msgid "Mark Away"
757-msgstr "Signaler comme absent"
758-
759-#: /home/gotwig/cable/po/../src/Widgets/Server.vala:135
760-msgid "Leave all channels"
761-msgstr "Quitter tout les canaux"
762-
763-#: /home/gotwig/cable/po/../src/Widgets/Server.vala:142
764-#: /home/gotwig/cable/po/../src/Services/Identity.vala:77
765-#, c-format
766-msgid "%s is away."
767-msgstr "%s est absent."
768-
769-#: /home/gotwig/cable/po/../src/Widgets/Server.vala:143
770-msgid "Mark Present"
771-msgstr "Signaler comme présent"
772-
773-#: /home/gotwig/cable/po/../src/Widgets/Channel.vala:44
774-msgid "Leave Channel"
775-msgstr "Quitter le canal"
776-
777-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:80
778-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:217
779-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:232
780+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:77
781+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:245
782+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:260
783 msgid "Operators"
784 msgstr "Modérateurs"
785
786-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:133
787-msgid "Loading Topic…"
788-msgstr "Chargement du sujet…"
789-
790-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:216
791-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:231
792+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:244
793+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:259
794 msgid "Regular"
795 msgstr "Visiteurs"
796
797-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:218
798-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:233
799+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:246
800+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:261
801 msgid "Voiced"
802-msgstr ""
803+msgstr "Participants"
804
805-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:289
806+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:317
807 #, c-format
808 msgid "%s joined"
809 msgstr "%s a rejoint le salon"
810
811-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:292
812+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:320
813 #, c-format
814 msgid "%s left"
815 msgstr "%s a quitté le salon"
816
817-#: /home/gotwig/cable/po/../src/Widgets/Room.vala:295
818+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Room.vala:323
819 #, c-format
820 msgid "%s is away"
821 msgstr "%s est absent"
822
823-#: /home/gotwig/cable/po/../src/Dialogs/JoinChannel.vala:26
824-msgid "Join Channel"
825-msgstr "Rejoindre le canal"
826-
827-#: /home/gotwig/cable/po/../src/Dialogs/ManageNetwork.vala:44
828+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Toolbar.vala:31
829+msgid "Search…"
830+msgstr "Recherche…"
831+
832+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Toolbar.vala:46
833+msgid "Preferences…"
834+msgstr "Préférences…"
835+
836+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Toolbar.vala:65
837+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Toolbar.vala:84
838+msgid "<b>Topic:</b> "
839+msgstr "<b>Sujet :</b> "
840+
841+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Channel.vala:61
842+msgid "Leave Channel"
843+msgstr "Quitter le canal"
844+
845+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Server.vala:395
846+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Server.vala:407
847+msgid "Mark Away"
848+msgstr "Signaler comme absent"
849+
850+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Server.vala:396
851+msgid "Leave All Channels"
852+msgstr ""
853+
854+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Server.vala:403
855+#: /home/tutebatti/internal-stuff/po/../src/Services/Identity.vala:90
856+#, c-format
857+msgid "%s is away."
858+msgstr "%s est absent."
859+
860+#: /home/tutebatti/internal-stuff/po/../src/Widgets/Server.vala:404
861+msgid "Mark Present"
862+msgstr "Signaler comme présent"
863+
864+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:48
865+msgid "johndoe"
866+msgstr "jeandupond"
867+
868+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:53
869+msgid "John Doe"
870+msgstr "Jean Dupond"
871+
872+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:57
873+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:63
874+msgid "Good night everyone!"
875+msgstr ""
876+
877+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:60
878+msgid "Try again later!"
879+msgstr ""
880+
881+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:65
882+msgid "Nick Name:"
883+msgstr "Surnom :"
884+
885+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:67
886+msgid "Real Name:"
887+msgstr "Nom réel :"
888+
889+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:69
890+msgid "Part Message:"
891+msgstr "Message d'au-revoir :"
892+
893+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:71
894+msgid "Away Message:"
895+msgstr ""
896+
897+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:73
898+msgid "Quit Message:"
899+msgstr ""
900+
901+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:96
902+msgid "Add Identity"
903+msgstr "Ajouter une identité"
904+
905+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageIdentity.vala:96
906+msgid "Edit Identity"
907+msgstr "Modifier l'identité"
908+
909+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageNetwork.vala:44
910 msgid "irc.network.net"
911 msgstr "irc.reseau.net"
912
913-#: /home/gotwig/cable/po/../src/Dialogs/ManageNetwork.vala:47
914+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageNetwork.vala:47
915 msgid "Network IRC"
916 msgstr "Réseau IRC"
917
918-#: /home/gotwig/cable/po/../src/Dialogs/ManageNetwork.vala:49
919+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageNetwork.vala:49
920 msgid "Optional"
921 msgstr "Facultatif"
922
923-#: /home/gotwig/cable/po/../src/Dialogs/ManageNetwork.vala:53
924+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageNetwork.vala:53
925 msgid "Address:"
926 msgstr "Addresse :"
927
928-#: /home/gotwig/cable/po/../src/Dialogs/ManageNetwork.vala:55
929+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageNetwork.vala:55
930 msgid "Name:"
931 msgstr "Nom :"
932
933-#: /home/gotwig/cable/po/../src/Dialogs/ManageNetwork.vala:57
934+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageNetwork.vala:57
935 msgid "Password:"
936 msgstr "Mot de passe :"
937
938-#: /home/gotwig/cable/po/../src/Dialogs/ManageNetwork.vala:77
939+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageNetwork.vala:77
940 msgid "Add Network"
941 msgstr "Ajouter un réseau"
942
943-#: /home/gotwig/cable/po/../src/Dialogs/ManageNetwork.vala:78
944+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/ManageNetwork.vala:78
945 msgid "Change Network"
946 msgstr "Changer de réseau"
947
948-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:30
949+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/JoinChannel.vala:26
950+msgid "Join Channel"
951+msgstr "Rejoindre le canal"
952+
953+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:23
954+msgid "Preferences"
955+msgstr "Préférences"
956+
957+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:30
958 msgid "Networks"
959 msgstr "Réseaux"
960
961-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:31
962+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:31
963 msgid "Identities"
964 msgstr "Identitées"
965
966-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:46
967+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:46
968 msgid "Name"
969 msgstr "Nom"
970
971-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:47
972+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:47
973 msgid "Address"
974 msgstr "Addresse"
975
976-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:66
977-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:69
978+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:66
979+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:69
980 msgid "Add…"
981 msgstr "Ajouter…"
982
983-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:67
984-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:70
985-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:158
986-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:161
987+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:67
988+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:70
989+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:152
990+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:155
991 msgid "Remove"
992 msgstr "Supprimer"
993
994-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:137
995+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:131
996 msgid "Nick"
997 msgstr "Surnom"
998
999-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:138
1000+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:132
1001 msgid "Real Name"
1002 msgstr "Nom réel"
1003
1004-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:157
1005-#: /home/gotwig/cable/po/../src/Dialogs/Preferences.vala:160
1006+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:151
1007+#: /home/tutebatti/internal-stuff/po/../src/Dialogs/Preferences.vala:154
1008 msgid "Add"
1009 msgstr "Ajouter"
1010
1011-#: /home/gotwig/cable/po/../src/Dialogs/ManageIdentity.vala:44
1012-msgid "johndoe (Without spaces/special characters)"
1013-msgstr ""
1014-
1015-#: /home/gotwig/cable/po/../src/Dialogs/ManageIdentity.vala:47
1016-msgid "John Doe"
1017-msgstr "Jean Dupond"
1018-
1019-#: /home/gotwig/cable/po/../src/Dialogs/ManageIdentity.vala:49
1020-msgid "Good night everyone !"
1021-msgstr "Bonne nuit tout le monde !"
1022-
1023-#: /home/gotwig/cable/po/../src/Dialogs/ManageIdentity.vala:51
1024-msgid "Nick Name:"
1025-msgstr "Surnom :"
1026-
1027-#: /home/gotwig/cable/po/../src/Dialogs/ManageIdentity.vala:53
1028-msgid "Real Name:"
1029-msgstr "Nom réel :"
1030-
1031-#: /home/gotwig/cable/po/../src/Dialogs/ManageIdentity.vala:55
1032-msgid "Part Message:"
1033-msgstr "Message d'au-revoir :"
1034-
1035-#: /home/gotwig/cable/po/../src/Dialogs/ManageIdentity.vala:75
1036-msgid "Add Identity"
1037-msgstr "Ajouter une identité"
1038-
1039-#: /home/gotwig/cable/po/../src/Dialogs/ManageIdentity.vala:76
1040-msgid "Edit Identity"
1041-msgstr "Modifier l'identité"
1042-
1043-#: /home/gotwig/cable/po/../src/Services/Identity.vala:75
1044+#: /home/tutebatti/internal-stuff/po/../src/Services/Identity.vala:88
1045 msgid "Bye."
1046 msgstr "Au revoir."
1047
1048-#: /home/gotwig/cable/po/../src/Services/Identity.vala:76
1049+#: /home/tutebatti/internal-stuff/po/../src/Services/Identity.vala:89
1050 msgid "Quit server."
1051 msgstr "Quitte le serveur."
1052+
1053+#~ msgid "About"
1054+#~ msgstr "À propos"
1055+
1056+#~ msgid "Select a Channel to join and begin to talk."
1057+#~ msgstr "Sélectionner un salon pour commencer à discuter"
1058+
1059+#~ msgid "Leave all channels"
1060+#~ msgstr "Quitter tout les canaux"
1061+
1062+#~ msgid "Loading Topic…"
1063+#~ msgstr "Chargement du sujet…"
1064+
1065+#~ msgid "Good night everyone !"
1066+#~ msgstr "Bonne nuit tout le monde !"
1067
1068=== modified file 'src/Cable.vala'
1069--- src/Cable.vala 2013-07-14 15:58:58 +0000
1070+++ src/Cable.vala 2013-08-11 12:01:40 +0000
1071@@ -10,7 +10,7 @@
1072 but WITHOUT ANY WARRANTY; without even the implied warranty of
1073 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1074 Lesser General Public License for more details.
1075-
1076+
1077 You should have received a copy of the GNU Lesser General
1078 Public License along with this library; if not, write to the
1079 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1080@@ -22,6 +22,30 @@
1081 */
1082 public class Cable.App : Granite.Application {
1083
1084+ static bool option_reset = false;
1085+ static bool option_version = false;
1086+ static bool option_test = false;
1087+
1088+ static const OptionEntry[] option_entries = {
1089+ { "reset", 0, 0, OptionArg.NONE, ref option_reset,
1090+ N_("Reset all settings and configuration to default"), null },
1091+
1092+ { "version", 0, 0, OptionArg.NONE, ref option_version,
1093+ N_("Print the version number"), null },
1094+
1095+ { "unit-test", 0, 0, OptionArg.NONE, ref option_test,
1096+ N_("Run unit tests"), null },
1097+
1098+ { null }
1099+ };
1100+
1101+ static Gee.ArrayList <Controller.Window> controllers {
1102+ get; set;
1103+ default = new Gee.ArrayList <Controller.Window> ();
1104+ }
1105+
1106+ public static const string TITLE = "Cable";
1107+
1108 construct {
1109 build_data_dir = Constants.DATADIR;
1110 build_pkg_data_dir = Constants.PKGDATADIR;
1111@@ -35,7 +59,7 @@
1112 app_years = "2012-2013";
1113 app_icon = "internet-chat";
1114 app_launcher = "cable.desktop";
1115- //application_id = "net.launchpad.cable";
1116+ application_id = "net.launchpad.cable";
1117
1118 main_url = "https://code.launchpad.net/cable";
1119 bug_url = "https://bugs.launchpad.net/cable";
1120@@ -53,43 +77,56 @@
1121 public App () {
1122 Granite.Services.Logger.initialize ("Cable");
1123 Granite.Services.Logger.DisplayLevel = Granite.Services.LogLevel.DEBUG;
1124+
1125+ Notification.init ();
1126+ Launcher.init ();
1127+ Settings.init ();
1128+ Utils.init ();
1129+ Irc.init ();
1130 }
1131
1132 public override void activate () {
1133- var window = new Cable.Window (this);
1134- this.add_window (window);
1135- window.show ();
1136+ var window = new Widgets.Window (this);
1137+ var controller = new Controller.Window (window);
1138+
1139+ add_window (window);
1140+ controllers.add (controller);
1141 }
1142-
1143- static const OptionEntry[] entries = {
1144- { null }
1145- // version
1146- // reset - reset all settings
1147- };
1148-
1149+
1150 public static int main (string[] args) {
1151- var context = new OptionContext ("File");
1152- context.add_main_entries (entries, Constants.GETTEXT_PACKAGE);
1153-
1154- Notify.init ("Cable");
1155-
1156- // libunity support
1157- Cable.Services.unity = new Cable.Services.Unity ("cable.desktop");
1158+ var context = new GLib.OptionContext ("");
1159+ context.set_help_enabled (true);
1160+ context.add_main_entries (option_entries, Constants.GETTEXT_PACKAGE);
1161
1162 try {
1163 context.parse (ref args);
1164- }
1165- catch (Error e) {
1166- print (e.message + "\n");
1167- }
1168+ } catch (GLib.OptionError e) {
1169+ warning (e.message);
1170+ warning ("Run '%s --help' to see a full list of available command line options.\n", args[0]);
1171+ return 0;
1172+ }
1173+
1174+ if (option_version) {
1175+ // XXX
1176+ }
1177+
1178+ if (option_reset) {
1179+ // XXX
1180+ }
1181+
1182+ if (option_test) {
1183+ return Tests.run (args);
1184+ }
1185+
1186
1187 var cable = new Cable.App ();
1188 return cable.run (args);
1189 }
1190-
1191- internal void translations () {
1192+
1193+ /*internal void translations () {
1194 var description = N_("Stylish IRC Client");
1195 var generic = N_("IRC Client");
1196- }
1197+ }*/
1198 }
1199
1200+
1201
1202=== added directory 'src/Controller'
1203=== added file 'src/Controller/Channel.vala'
1204--- src/Controller/Channel.vala 1970-01-01 00:00:00 +0000
1205+++ src/Controller/Channel.vala 2013-08-11 12:01:40 +0000
1206@@ -0,0 +1,170 @@
1207+internal class Cable.Controller.Channel : GLib.Object {
1208+
1209+ internal weak Server server;
1210+ internal View.Channel view;
1211+ internal Irc.Channel backend;
1212+
1213+ internal string name; //TODO id
1214+
1215+ internal Channel (Server server, string name) {
1216+debug (@"+ CONTROLLER CHANNEL $name");
1217+ this.server = server;
1218+ this.name = name;
1219+
1220+ if (server.view.has_channel (name) == false)
1221+ server.view.add_channel (name, name);
1222+
1223+ view = server.view.get_channel_by_id (name);
1224+ view.nick = server.nick;
1225+ backend = new Irc.Channel (name, server.backend);
1226+
1227+ connect_frontend_signals ();
1228+ connect_backend_signals ();
1229+
1230+ load_state ();
1231+ }
1232+
1233+ ~Channel () { debug (@"- CONTROLLER CHANNEL $name"); }
1234+
1235+ void load_state () {
1236+ /*if (backend.joined) {
1237+ view.room.state = Widgets.Room.State.CHAT;
1238+ FIXME some bug in maki returns garbage here:
1239+ -> view.room.list_users (backend.nicks, backend.prefixes);
1240+ backend.event_topic (backend.topic, "");
1241+ } else {
1242+ view.room.state = Widgets.Room.State.JOINING;
1243+ }*/
1244+ // part and rejoin to workaround bug
1245+ view.state = State.JOINING;
1246+
1247+ if (server.backend.connected == false) {
1248+ server.backend.event_connected.connect (() => {
1249+ if (backend.joined)
1250+ backend.send_part ();
1251+ backend.send_join ();
1252+ });
1253+ } else {
1254+ if (backend.joined)
1255+ backend.send_part ();
1256+ backend.send_join ();
1257+ }
1258+ }
1259+
1260+ void connect_frontend_signals () {
1261+
1262+ view.part.connect (() => {
1263+ backend.send_part ();
1264+ });
1265+
1266+ server.window.view.selected.connect ((item) => {
1267+ if (item == view)
1268+ view.unread_messages = 0;
1269+ });
1270+
1271+ view.join.connect (() => {
1272+ view.state = State.JOINING;
1273+ backend.send_join ();
1274+ });
1275+
1276+ view.send_message.connect ((message) => {
1277+ if (message.has_prefix ("/"))
1278+ server.backend.send_raw (message.replace ("/", ""));
1279+ else
1280+ server.backend.send_message (name, message);
1281+
1282+ view.entry = "";
1283+ });
1284+
1285+ view.focused.connect (() => {
1286+ Launcher.jobs = 0;
1287+ Launcher.urgent = false;
1288+ return false;
1289+ });
1290+
1291+ }
1292+
1293+ void connect_backend_signals () {
1294+ backend.event_message.connect ((from, message) => {
1295+ if (server.window.view.current_channel != view)
1296+ view.unread_messages++;
1297+ });
1298+
1299+ backend.event_topic.connect ((from, topic) => {
1300+ view.topic = topic;
1301+ });
1302+
1303+ server.backend.event_nick.connect ((from, new_nick) => {
1304+ if (server.backend.is_me (from)) {
1305+ view.nick = new_nick;
1306+ }
1307+
1308+ assert (new_nick != null);
1309+
1310+ var name = from.split ("!")[0];
1311+
1312+ if (!view.has_user (name))
1313+ return;
1314+
1315+ if (name.has_prefix ("@"))
1316+ view.rename_user (name.replace ("@", ""), new_nick, UserType.OPERATOR);
1317+ else if (name.has_prefix ("+"))
1318+ view.rename_user (name.replace ("+", ""), new_nick, UserType.VOICED);
1319+ else
1320+ view.rename_user (name, new_nick, UserType.REGULAR);
1321+ });
1322+
1323+ backend.event_part.connect ((from, message) => {
1324+ if (server.backend.is_me (from)) {
1325+ view.state = State.NOT_JOINED;
1326+ } else {
1327+ var name = from.split ("!")[0];
1328+
1329+ if (name.has_prefix ("@"))
1330+ view.remove_user (name.replace ("@", ""), message);
1331+ else if (name.has_prefix ("+"))
1332+ view.remove_user (name.replace ("+", ""), message);
1333+ else
1334+ view.remove_user (name, message);
1335+ }
1336+ });
1337+
1338+ backend.event_join.connect ((from) => {
1339+ if (server.backend.is_me (from)) {
1340+ view.state = State.CHAT;
1341+ } else {
1342+ var name = from.split ("!")[0];
1343+
1344+ if (name.has_prefix ("@"))
1345+ view.add_user (name.replace ("@", ""), UserType.OPERATOR);
1346+ else if (name.has_prefix ("+"))
1347+ view.add_user (name.replace ("+", ""), UserType.VOICED);
1348+ else
1349+ view.add_user (name, UserType.REGULAR);
1350+ }
1351+ });
1352+
1353+ backend.event_no_such.connect (() => {
1354+ view.state = State.NO_SUCH;
1355+ });
1356+
1357+ backend.event_message.connect ((from, message) => {
1358+ var nick = from.split ("!") [0];
1359+
1360+ if (message.contains (server.nick)) {
1361+
1362+ if (view.has_focus == false) {
1363+ Notification.send (nick, message);
1364+ Launcher.jobs++;
1365+ Launcher.urgent = true;
1366+ }
1367+
1368+ view.message (nick, message, MessageType.PING);
1369+ } else {
1370+ view.message (nick, message);
1371+ }
1372+ });
1373+
1374+ backend.event_names.connect (view.list_users);
1375+ }
1376+}
1377
1378=== added file 'src/Controller/Server.vala'
1379--- src/Controller/Server.vala 1970-01-01 00:00:00 +0000
1380+++ src/Controller/Server.vala 2013-08-11 12:01:40 +0000
1381@@ -0,0 +1,65 @@
1382+internal class Cable.Controller.Server : GLib.Object {
1383+
1384+ internal weak Window window;
1385+ internal View.Server view;
1386+ internal Irc.Server backend;
1387+
1388+ internal string nick; // FIXME not reliable
1389+ internal string address; // FIXME not reliable
1390+ internal string name;
1391+
1392+ internal Gee.HashMap <string, Channel> channels {
1393+ get; set;
1394+ default = new Gee.HashMap <string, Channel> ();
1395+ }
1396+
1397+ internal Server (string address, string nick, Window window) {
1398+ debug (@"+ CONTROLLER SERVER $address");
1399+ this.backend = Irc.Server.get_or_create (address, nick);
1400+
1401+ this.name = backend.name;
1402+ this.window = window;
1403+ this.nick = nick;
1404+ this.address = address;
1405+
1406+ if (!backend.connected)
1407+ backend.send_connect ();
1408+
1409+ this.view = window.view.add_server (@"$(backend.network.name) - $(nick)", backend.name);
1410+
1411+ connect_frontend_signals ();
1412+ connect_backend_signals ();
1413+ }
1414+
1415+ ~Server () { debug (@"- CONTROLLER SERVER $address"); }
1416+
1417+ void connect_frontend_signals () {
1418+ view.toggle_away.connect (() => {
1419+ if (backend.away) {
1420+ backend.send_back ();
1421+ } else {
1422+ backend.send_away ();
1423+ }
1424+ });
1425+
1426+ view.part_all.connect (() => {
1427+ foreach (var channel in channels.values)
1428+ channel.backend.send_part ();
1429+ });
1430+ }
1431+
1432+ void connect_backend_signals () {
1433+ backend.event_user_away.connect ((from, away) => {
1434+ if (backend.is_me (from)) {
1435+ view.away = away;
1436+ }
1437+ });
1438+
1439+ backend.event_quit.connect ((from, message) => {
1440+ var nick = from.split ("!")[0];
1441+
1442+ foreach (var channel in channels.values)
1443+ channel.view.remove_user (nick, message);
1444+ });
1445+ }
1446+}
1447
1448=== added file 'src/Controller/Window.vala'
1449--- src/Controller/Window.vala 1970-01-01 00:00:00 +0000
1450+++ src/Controller/Window.vala 2013-08-11 12:01:40 +0000
1451@@ -0,0 +1,163 @@
1452+internal class Cable.Controller.Window : GLib.Object {
1453+
1454+ internal View.Window view { get; set; }
1455+
1456+ internal Gee.HashMap <string, Server> servers {
1457+ get; set;
1458+ default = new Gee.HashMap <string, Server> ();
1459+ }
1460+
1461+ internal Window (View.Window window) {
1462+ GLib.Object (view: window);
1463+
1464+ connect_frontend_signals ();
1465+ connect_backend_signals ();
1466+ initialize ();
1467+ }
1468+
1469+ // restore saved state
1470+ void initialize () {
1471+ var channels = Settings.preferences.channels;
1472+
1473+ // check for joined channels
1474+ foreach (var server_name in Irc.Client.known_server_names) {
1475+ var server = new Irc.Server.from_name (server_name);
1476+ foreach (var channel in server.channel_names)
1477+ join_channel (server.address, server.nick, channel);
1478+ }
1479+
1480+ // check for channels from last session
1481+ if (channels.length > 0) {
1482+ foreach (var channel in channels) {
1483+ var parts = channel.split (":");
1484+ return_if_fail (parts.length == 3);
1485+ join_channel (parts[0], parts[1], parts[2]);
1486+ }
1487+ }
1488+
1489+ if (servers.size == 0)
1490+ view.welcome_shown = true;
1491+ }
1492+
1493+ // backend events that affect the window's state
1494+ void connect_backend_signals () {
1495+ Irc.client.event_nick.connect ((time, server, from, nick) => {
1496+ var current_channel = view.current_channel;
1497+ var current_server = view.current_server;
1498+
1499+ if (server == current_server.id)
1500+ view.title = string.join (" — ", current_channel.name, nick);
1501+ });
1502+ }
1503+
1504+ // frontend signals from the window
1505+ void connect_frontend_signals () {
1506+ view.selected.connect ((item) => {
1507+ if (item is View.Channel) {
1508+ var channel = item as View.Channel;
1509+ view.title = string.join (" — ", channel.name);
1510+ }
1511+ });
1512+
1513+ view.join.connect ((a,n,c) => {
1514+ join_channel (a,n,c);
1515+ });
1516+
1517+ view.remove_channel.connect (() => {
1518+ var channel_id = view.current_channel.id;
1519+ var server_id = view.current_server.id;
1520+
1521+ if (view.current_channel != null) {
1522+ part_channel (servers[server_id].channels[channel_id]);
1523+ } else {
1524+ warning ("No channel selected, cannot leave.");
1525+ }
1526+ });
1527+
1528+ view.add_channel.connect (() => {
1529+ var dialog = new Dialogs.JoinChannel ();
1530+ dialog.done.connect ((a,b,c) => join_channel (a.address,b.nick_name,c));
1531+ dialog.show_all ();
1532+ });
1533+
1534+ view.show_preferences.connect (() => {
1535+ var dialog = new Dialogs.Preferences ();
1536+ dialog.show_all ();
1537+ });
1538+
1539+ view.close.connect (() => {
1540+ string[] chans = {};
1541+
1542+ foreach (var server in servers.values) {
1543+ foreach (var channel in server.channels.values) {
1544+ chans += string.join (":", server.address, server.nick, channel.name);
1545+ channel.backend.send_part ();
1546+ }
1547+ }
1548+
1549+ Settings.preferences.channels = chans;
1550+ });
1551+ }
1552+
1553+ void join_channel (string address, string nick, string channel_name) {
1554+ Server server = null;
1555+ foreach (var s in servers.values)
1556+ if (s.address == address && s.nick == nick)
1557+ server = s;
1558+
1559+ if (server == null) {
1560+ server = new Server (address, nick, this);
1561+ servers[server.backend.name] = server;
1562+ }
1563+
1564+ if (server.view.has_channel (channel_name)) {
1565+ warning ("Channel is already joined");
1566+ return;
1567+ }
1568+
1569+ var channel = new Channel (server, channel_name);
1570+ server.channels[channel_name] = channel;
1571+
1572+ view.current_channel = channel.view;
1573+ view.welcome_shown = false;
1574+ }
1575+
1576+ void part_channel (Channel channel) {
1577+ var server = channel.server;
1578+
1579+ channel.backend.send_part ();
1580+ server.view.remove_channel (channel.view.id);
1581+ server.channels.unset (channel.view.id);
1582+
1583+ if (server.channels.size == 0)
1584+ servers.unset (server.view.id);
1585+
1586+ if (servers.size == 0) {
1587+ view.title = App.TITLE;
1588+ view.welcome_shown = true;
1589+ }
1590+ }
1591+
1592+ /*void leave_channel (Settings.Network network, Settings.Identity identity, string channel_name) {
1593+ var server_backend = Irc.Server.search (network.address, identity.nick_name);
1594+
1595+ var server_view = servers[server_backend.name].view;
1596+
1597+ if (server_view == null) {
1598+ warning ("Cannot leave channel: server does not exist (%s - %s)", network.address, identity.nick_name);
1599+ return;
1600+ }
1601+ if (!server_view.has_channel (channel_name)) {
1602+ warning ("Cannot leave channel: channel not joined (%s)", channel_name);
1603+ return;
1604+ }
1605+
1606+ server_view.remove_channel (channel_name);
1607+ server_backend.send_part (channel_name);
1608+
1609+ if (view.n_servers == 0) {
1610+ view.title = App.TITLE;
1611+ view.welcome_shown = true;
1612+ }
1613+ }*/
1614+}
1615
1616=== modified file 'src/Dialogs/JoinChannel.vala'
1617--- src/Dialogs/JoinChannel.vala 2013-07-04 01:34:38 +0000
1618+++ src/Dialogs/JoinChannel.vala 2013-08-11 12:01:40 +0000
1619@@ -19,7 +19,7 @@
1620
1621 public class Cable.Dialogs.JoinChannel : Granite.Widgets.LightWindow {
1622
1623- public signal void done (Settings.Network network, Settings.Identity identity, string channel);
1624+ public signal void done (Utils.Network network, Utils.Identity identity, string channel);
1625 Gtk.Button connect_button;
1626
1627 public JoinChannel () {
1628@@ -47,19 +47,20 @@
1629
1630 // Entries/Comboboxes
1631 var server_entry = new Gtk.ComboBoxText.with_entry ();
1632- for (int i = 0; i < Settings.networks.size; i++)
1633- server_entry.append (i.to_string (), Settings.networks[i].name);
1634+ for (int i = 0; i < Utils.Network.all.size; i++)
1635+ server_entry.append (i.to_string (), Utils.Network.all[i].name);
1636 server_entry.active = 0;
1637
1638 var id_entry = new Gtk.ComboBoxText.with_entry ();
1639- for (int i = 0; i < Settings.identities.size; i++)
1640- id_entry.append (i.to_string (), Settings.identities[i].nick_name);
1641+ for (int i = 0; i < Utils.Identity.all.size; i++)
1642+ id_entry.append (i.to_string (), Utils.Identity.all[i].nick_name);
1643 id_entry.active = 0;
1644
1645 var channel_entry = new Gtk.Entry ();
1646 channel_entry.text = "#";
1647 channel_entry.grab_focus ();
1648 channel_entry.set_position (-1);
1649+ channel_entry.width_request = 250;
1650
1651 channel_entry.insert_text.connect ((text) => {
1652 Utils.filter (channel_entry, text, {" ", ":"});
1653@@ -110,19 +111,19 @@
1654
1655 connect_button.clicked.connect (() => channel_entry.activate ());
1656 channel_entry.activate.connect (() => {
1657- Settings.Network network;
1658- Settings.Identity identity;
1659+ Utils.Network network;
1660+ Utils.Identity identity;
1661
1662 if (server_entry.active_id == null) {
1663- network = new Settings.Network (server_entry.get_active_text ());
1664+ network = new Utils.Network (server_entry.get_active_text ());
1665 } else {
1666- network = Settings.networks[int.parse (server_entry.active_id)];
1667+ network = Utils.Network.all[int.parse (server_entry.active_id)];
1668 }
1669
1670 if (id_entry.active_id == null) {
1671- identity = new Settings.Identity (id_entry.get_active_text ());
1672+ identity = new Utils.Identity (id_entry.get_active_text ());
1673 } else {
1674- identity = Settings.identities[int.parse (id_entry.active_id)];
1675+ identity = Utils.Identity.all[int.parse (id_entry.active_id)];
1676 }
1677
1678
1679
1680=== modified file 'src/Dialogs/ManageIdentity.vala'
1681--- src/Dialogs/ManageIdentity.vala 2013-07-04 14:06:39 +0000
1682+++ src/Dialogs/ManageIdentity.vala 2013-08-11 12:01:40 +0000
1683@@ -25,13 +25,17 @@
1684 /**
1685 * @param identity Resulting identity.
1686 */
1687- public signal void done (Settings.Identity identity);
1688+ public signal void done (Utils.Identity identity);
1689
1690 /**
1691 * @param identity Identity to be edited or null if you want to create
1692 * a new one.
1693 */
1694- public ManageIdentity (Settings.Identity? identity = null) {
1695+ public ManageIdentity (Utils.Identity? identity = null) {
1696+
1697+ var new_identity = identity == null;
1698+ var in_use = (new_identity) ? false : identity.servers.size > 0;
1699+
1700 this.modal = true;
1701 this.window_position = Gtk.WindowPosition.CENTER;
1702
1703@@ -43,55 +47,79 @@
1704 var nick_name = new Gtk.Entry ();
1705 nick_name.placeholder_text = _("johndoe (Without spaces/special characters)");
1706 nick_name.width_request = 250;
1707+ nick_name.sensitive = !in_use;
1708+
1709 var real_name = new Gtk.Entry ();
1710 real_name.placeholder_text = _("John Doe");
1711+ real_name.sensitive = !in_use;
1712+
1713 var part_message = new Gtk.Entry ();
1714- part_message.placeholder_text = _("Good night everyone !");
1715+ part_message.placeholder_text = _("Good night everyone!");
1716+
1717+ var away_message = new Gtk.Entry ();
1718+ away_message.placeholder_text = _("Try again later!");
1719+
1720+ var quit_message = new Gtk.Entry ();
1721+ quit_message.placeholder_text = _("Good night everyone!");
1722
1723- grid.attach (new Utils.Label.right (_("Nick Name:")), 0, 0, 1, 1);
1724+ grid.attach (new Utils.Label.right (_("Nick Name:"), !in_use), 0, 0, 1, 1);
1725 grid.attach (nick_name, 1, 0, 1, 1);
1726- grid.attach (new Utils.Label.right (_("Real Name:")), 0, 1, 1, 1);
1727+ grid.attach (new Utils.Label.right (_("Real Name:"), !in_use), 0, 1, 1, 1);
1728 grid.attach (real_name, 1, 1, 1, 1);
1729 grid.attach (new Utils.Label.right (_("Part Message:")), 0, 2, 1, 1);
1730 grid.attach (part_message, 1, 2, 1, 1);
1731+ grid.attach (new Utils.Label.right (_("Away Message:")), 0, 3, 1, 1);
1732+ grid.attach (away_message, 1, 3, 1, 1);
1733+ grid.attach (new Utils.Label.right (_("Quit Message:")), 0, 4, 1, 1);
1734+ grid.attach (quit_message, 1, 4, 1, 1);
1735
1736 var cancel_button = new Gtk.Button.from_stock (Gtk.Stock.CANCEL);
1737 Gtk.Button apply_button;
1738- if (identity == null) {
1739+
1740+ if (new_identity) {
1741 apply_button = new Gtk.Button.from_stock (Gtk.Stock.ADD);
1742 apply_button.get_style_context ().add_class ("affirmative");
1743- } else
1744+ } else {
1745 apply_button = new Gtk.Button.from_stock (Gtk.Stock.APPLY);
1746- apply_button.sensitive = (identity != null);
1747+ }
1748+
1749+ apply_button.sensitive = !new_identity;
1750
1751 var button_box = new Gtk.ButtonBox (Gtk.Orientation.HORIZONTAL);
1752 button_box.layout_style = Gtk.ButtonBoxStyle.END;
1753 button_box.add (cancel_button);
1754 button_box.add (apply_button);
1755
1756- grid.attach (button_box, 0, 3, 2, 1);
1757+ grid.attach (button_box, 0, 5, 2, 1);
1758
1759 this.add (grid);
1760- this.title = (identity == null) ? _("Add Identity")
1761- : _("Edit Identity");
1762+ this.title = (new_identity) ? _("Add Identity") : _("Edit Identity");
1763
1764- if (identity != null) {
1765+ if (!new_identity) {
1766 nick_name.text = identity.nick_name;
1767 real_name.text = identity.real_name;
1768 part_message.text = identity.part_message;
1769+ away_message.text = identity.away_message;
1770+ quit_message.text = identity.quit_message;
1771 }
1772
1773 nick_name.changed.connect (() => {
1774 apply_button.sensitive = (nick_name.text != "");
1775 });
1776
1777+ nick_name.activate.connect (() => apply_button.clicked);
1778+ real_name.activate.connect (() => apply_button.clicked);
1779+ part_message.activate.connect (() => apply_button.clicked);
1780+ away_message.activate.connect (() => apply_button.clicked);
1781+ quit_message.activate.connect (() => apply_button.clicked);
1782+
1783 apply_button.clicked.connect (() => {
1784- if (identity == null) {
1785+ if (new_identity) {
1786 done (create_identity (nick_name.text, real_name.text, part_message.text));
1787 } else {
1788- identity.real_name = real_name.text.strip ();
1789- identity.nick_name = nick_name.text.strip ();
1790 identity.part_message = part_message.text.strip ();
1791+ identity.away_message = away_message.text.strip ();
1792+ identity.quit_message = quit_message.text.strip ();
1793 done (identity);
1794 }
1795
1796@@ -103,18 +131,17 @@
1797 });
1798 }
1799
1800- Settings.Identity create_identity (string nick_name, string real_name,
1801- string part_message)
1802+ static Utils.Identity create_identity (string nick_name, string real_name, string part_message)
1803 requires (nick_name.strip () != "") {
1804
1805 if (nick_name.strip () == "")
1806- return (Settings.Identity) null;
1807+ return (Utils.Identity) null;
1808
1809 if (real_name.strip () == "")
1810 real_name = null;
1811 if (part_message.strip () == "")
1812 part_message = null;
1813
1814- return new Settings.Identity (nick_name, real_name, part_message);
1815+ return new Utils.Identity (nick_name, real_name, part_message);
1816 }
1817 }
1818
1819=== modified file 'src/Dialogs/ManageNetwork.vala'
1820--- src/Dialogs/ManageNetwork.vala 2013-07-04 01:34:38 +0000
1821+++ src/Dialogs/ManageNetwork.vala 2013-08-11 12:01:40 +0000
1822@@ -25,13 +25,16 @@
1823 /**
1824 * @param network Resulting network.
1825 */
1826- public signal void done (Settings.Network network);
1827+ public signal void done (Utils.Network network);
1828
1829 /**
1830 * @param network Network to be edited or null if you want to create
1831 * a new one.
1832 */
1833- public ManageNetwork (Settings.Network? network = null) {
1834+ public ManageNetwork (Utils.Network? network = null) {
1835+ var new_network = network == null;
1836+ var in_use = (new_network) ? false : network.servers.size > 0;
1837+
1838 this.modal = true;
1839 this.window_position = Gtk.WindowPosition.CENTER;
1840
1841@@ -43,14 +46,17 @@
1842 var address = new Gtk.Entry ();
1843 address.placeholder_text = _("irc.network.net");
1844 address.width_request = 250;
1845+ address.sensitive = !in_use;
1846+
1847 var name = new Gtk.Entry ();
1848 name.placeholder_text = _("Network IRC");
1849+
1850 var password = new Gtk.Entry ();
1851 password.placeholder_text = _("Optional");
1852 password.caps_lock_warning = true;
1853 password.set_visibility (false);
1854
1855- grid.attach (new Utils.Label.right (_("Address:")), 0, 0, 1, 1);
1856+ grid.attach (new Utils.Label.right (_("Address:"), !in_use), 0, 0, 1, 1);
1857 grid.attach (address, 1, 0, 1, 1);
1858 grid.attach (new Utils.Label.right (_("Name:")), 0, 1, 1, 1);
1859 grid.attach (name, 1, 1, 1, 1);
1860@@ -59,11 +65,14 @@
1861
1862 var cancel_button = new Gtk.Button.from_stock (Gtk.Stock.CANCEL);
1863 Gtk.Button apply_button;
1864+
1865 if (network == null) {
1866 apply_button = new Gtk.Button.from_stock (Gtk.Stock.ADD);
1867 apply_button.get_style_context ().add_class ("affirmative");
1868- } else
1869+ } else {
1870 apply_button = new Gtk.Button.from_stock (Gtk.Stock.APPLY);
1871+ }
1872+
1873 apply_button.sensitive = (network != null);
1874
1875 var button_box = new Gtk.ButtonBox (Gtk.Orientation.HORIZONTAL);
1876@@ -74,8 +83,7 @@
1877 grid.attach (button_box, 0, 3, 2, 1);
1878
1879 this.add (grid);
1880- this.title = (network == null) ? _("Add Network")
1881- : _("Change Network");
1882+ this.title = (network == null) ? _("Add Network") : _("Edit Network");
1883
1884 if (network != null) {
1885 address.text = network.address;
1886@@ -91,11 +99,11 @@
1887 if (network == null) {
1888 done (create_network (address.text, name.text, password.text));
1889 } else {
1890- network.address = address.text.strip ();
1891 network.name = name.text.strip ();
1892 network.password = password.text.strip ();
1893 done (network);
1894 }
1895+
1896 this.destroy ();
1897 });
1898
1899@@ -104,18 +112,17 @@
1900 });
1901 }
1902
1903- Settings.Network create_network (string address, string name,
1904- string password)
1905+ Utils.Network create_network (string address, string name, string password)
1906 requires (address.strip () != "") {
1907
1908 if (address.strip () == "")
1909- return (Settings.Network) null;
1910+ return (Utils.Network) null;
1911
1912 if (name.strip () == "")
1913 name = null;
1914 if (password.strip () == "")
1915 password = null;
1916
1917- return new Settings.Network (address, name, password);
1918+ return new Utils.Network (address, name, password);
1919 }
1920 }
1921
1922=== modified file 'src/Dialogs/Preferences.vala'
1923--- src/Dialogs/Preferences.vala 2013-07-04 01:34:38 +0000
1924+++ src/Dialogs/Preferences.vala 2013-08-11 12:01:40 +0000
1925@@ -38,13 +38,14 @@
1926
1927 public NetworkPrefs () {
1928 var tree = new Gtk.TreeView ();
1929- var scroll = new Gtk.ScrolledWindow(null, null);
1930+ var scroll = new Gtk.ScrolledWindow (null, null);
1931
1932 sync (tree);
1933
1934 var cell = new Gtk.CellRendererText ();
1935 tree.insert_column_with_attributes (-1, _("Name"), cell, "text", 0);
1936 tree.insert_column_with_attributes (-1, _("Address"), cell, "text", 1);
1937+ tree.insert_column_with_attributes (-1, _("Used"), cell, "text", 2);
1938
1939 scroll.set_size_request (300, 300);
1940 scroll.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
1941@@ -63,27 +64,28 @@
1942 toolbar.get_style_context().add_class(Gtk.STYLE_CLASS_INLINE_TOOLBAR);
1943 toolbar.get_style_context().set_junction_sides(Gtk.JunctionSides.TOP);
1944
1945- var add_button = new Gtk.ToolButton (null, _("Add…"));
1946+ var add_button = new Gtk.ToolButton (null, _("Add…"));
1947 var remove_button = new Gtk.ToolButton (null, _("Remove"));
1948+ var edit_button = new Gtk.ToolButton (null, _("Edit…"));
1949
1950 add_button.set_tooltip_text (_("Add…"));
1951 remove_button.set_tooltip_text (_("Remove"));
1952-
1953+ edit_button.set_tooltip_text (_("Edit…"));
1954+
1955 add_button.set_icon_name ("list-add-symbolic");
1956 remove_button.set_icon_name ("list-remove-symbolic");
1957-
1958+ edit_button.set_icon_name ("document-properties-symbolic");
1959+
1960 toolbar.insert (add_button, -1);
1961 toolbar.insert (remove_button, -1);
1962+ //TODO toolbar.insert (edit_button, -1);
1963
1964 this.attach (scroll, 0, 0, 1, 1);
1965 this.attach (toolbar, 0, 1, 1, 1);
1966
1967 add_button.clicked.connect (() => {
1968 var dialog = new Dialogs.ManageNetwork ();
1969- dialog.done.connect ((network) => {
1970- Settings.networks.add (network);
1971- this.sync (tree);
1972- });
1973+ dialog.done.connect ((network) => this.sync (tree));
1974 dialog.show_all ();
1975 });
1976
1977@@ -95,29 +97,27 @@
1978 return;
1979
1980 var index = path.get_indices ()[0];
1981- Settings.networks.remove (Settings.networks[index]);
1982+ Utils.Network.remove (Utils.Network.all[index].address);
1983 sync (tree);
1984 });
1985-
1986+
1987 tree.row_activated.connect ((path) => {
1988 var index = path.get_indices ()[0];
1989- var dialog = new Dialogs.ManageNetwork (Settings.networks[index]);
1990- dialog.done.connect (() => {
1991- //Settings.networks[index] = network;
1992- this.sync (tree);
1993- });
1994+ var dialog = new Dialogs.ManageNetwork (Utils.Network.all[index]);
1995+ dialog.done.connect (() => this.sync (tree));
1996 dialog.show_all ();
1997 });
1998 }
1999
2000 private void sync (Gtk.TreeView tree) {
2001- var store = new Gtk.ListStore (2, typeof (string), typeof (string));
2002+ var store = new Gtk.ListStore (3, typeof (string), typeof (string), typeof (string));
2003
2004 Gtk.TreeIter iter;
2005
2006- foreach (var network in Settings.networks) {
2007+ foreach (var network in Utils.Network.all) {
2008+ var in_use = network.servers.size > 0 ? "Used" : "";
2009 store.append (out iter);
2010- store.set (iter, 0, network.name, 1, network.address, -1);
2011+ store.set (iter, 0, network.name, 1, network.address, 2, in_use, -1);
2012 }
2013
2014 tree.model = store;
2015@@ -127,7 +127,6 @@
2016 public class Cable.Dialogs.IdentityPrefs : Gtk.Grid {
2017
2018 public IdentityPrefs () {
2019- var store = new Gtk.ListStore (2, typeof (string), typeof (string));
2020 var tree = new Gtk.TreeView ();
2021 var scroll = new Gtk.ScrolledWindow(null, null);
2022
2023@@ -171,10 +170,7 @@
2024
2025 add_button.clicked.connect (() => {
2026 var dialog = new Dialogs.ManageIdentity ();
2027- dialog.done.connect ((identitie) => {
2028- Settings.identities.add (identitie);
2029- this.sync (tree);
2030- });
2031+ dialog.done.connect (() => this.sync (tree));
2032 dialog.show_all ();
2033 });
2034
2035@@ -186,17 +182,14 @@
2036 return;
2037
2038 var index = path.get_indices ()[0];
2039- Settings.identities.remove (Settings.identities[index]);
2040+ Utils.Identity.remove (Utils.Identity.all[index].nick_name);
2041 sync (tree);
2042 });
2043
2044 tree.row_activated.connect ((path) => {
2045 var index = path.get_indices ()[0];
2046- var dialog = new Dialogs.ManageIdentity (Settings.identities[index]);
2047- dialog.done.connect (() => {
2048- //Settings.identities[index] = id;
2049- this.sync (tree);
2050- });
2051+ var dialog = new Dialogs.ManageIdentity (Utils.Identity.all[index]);
2052+ dialog.done.connect (() => this.sync (tree));
2053 dialog.show_all ();
2054 });
2055 }
2056@@ -206,7 +199,7 @@
2057
2058 Gtk.TreeIter iter;
2059
2060- foreach (var identity in Settings.identities) {
2061+ foreach (var identity in Utils.Identity.all) {
2062 store.append (out iter);
2063 store.set (iter, 0, identity.nick_name, 1, identity.real_name, -1);
2064 }
2065
2066=== added directory 'src/Irc'
2067=== added file 'src/Irc/Channel.vala'
2068--- src/Irc/Channel.vala 1970-01-01 00:00:00 +0000
2069+++ src/Irc/Channel.vala 2013-08-11 12:01:40 +0000
2070@@ -0,0 +1,322 @@
2071+/***
2072+ Copyright (C) 2013 Cable Developers
2073+
2074+ This program or library is free software; you can redistribute it
2075+ and/or modify it under the terms of the GNU Lesser General Public
2076+ License as published by the Free Software Foundation; either
2077+ version 3 of the License, or (at your option) any later version.
2078+
2079+ This library is distributed in the hope that it will be useful,
2080+ but WITHOUT ANY WARRANTY; without even the implied warranty of
2081+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2082+ Lesser General Public License for more details.
2083+
2084+ You should have received a copy of the GNU Lesser General
2085+ Public License along with this library; if not, write to the
2086+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2087+ Boston, MA 02110-1301 USA.
2088+***/
2089+
2090+public class Cable.Irc.Channel : GLib.Object {
2091+
2092+ public Irc.Server server { get; private set; }
2093+
2094+ public string name { get; private set; }
2095+
2096+ string _topic = "";
2097+ public string topic {
2098+ get {
2099+ try {
2100+ _topic = client.channel_topic (server.name, this.name);
2101+ } catch (GLib.IOError error) {
2102+ warning (error.message);
2103+ }
2104+
2105+ return _topic;
2106+ }
2107+ }
2108+
2109+ string[] _nicks = {};
2110+ public string[] nicks {
2111+ get {
2112+ try {
2113+ client.channel_nicks (server.name, this.name, out _nicks, out _prefixes);
2114+ } catch (GLib.IOError error) {
2115+ warning (error.message);
2116+ }
2117+
2118+ return _nicks;
2119+ }
2120+ }
2121+
2122+ string[] _prefixes = {};
2123+ public string[] prefixes {
2124+ get {
2125+ try {
2126+ client.channel_nicks (server.name, this.name, out _nicks, out _prefixes);
2127+ } catch (GLib.IOError error) {
2128+ warning (error.message);
2129+ }
2130+
2131+ return _prefixes;
2132+ }
2133+ }
2134+
2135+ public bool joined {
2136+ get { return name in server.channel_names; }
2137+ }
2138+
2139+ public signal void event_banlist (string mask, string who, int64 when); // TODO wtf is this?
2140+
2141+ /**
2142+ * You failed to join this channel.
2143+ * @param reason Reason you were unable to join this channel.
2144+ */
2145+ public signal void event_cannot_join (string reason);
2146+ public signal void event_invite (string from, string who); // TODO makes more sense in server!?
2147+
2148+ /**
2149+ * Someone joined the channel.
2150+ * @param from User that joined the channel.
2151+ */
2152+ public signal void event_join (string from);
2153+
2154+ /**
2155+ * A user has been kicked from the channel.
2156+ * @param from User who kicked someone.
2157+ * @param who User that was kicked.
2158+ * @param message Reason given why the user was kicked.
2159+ */
2160+ public signal void event_kick (string from, string who, string message);
2161+ public signal void event_list (int64 users, string topic); // TODO does this belong?
2162+
2163+ public signal void event_message (string from, string message);
2164+
2165+ /**
2166+ * All nicks and respective prefixes have been returned by the server.
2167+ * @param nicks List of all nick names of all users in the channel.
2168+ * @param prefixes Respective nick prefixes like "@" or "+".
2169+ */
2170+ public signal void event_names (string[] nicks, string[] prefixes);
2171+
2172+ /**
2173+ * No such channel exists.
2174+ */
2175+ public signal void event_no_such ();
2176+
2177+ /**
2178+ * Someone has left the channel.
2179+ * @param from User that left the channel.
2180+ * @param message Part message displayed to all users in the channel.
2181+ */
2182+ public signal void event_part (string from, string message);
2183+
2184+ /**
2185+ * Topic has been changed.
2186+ * @param from User that changed the topic.
2187+ * @param topic The new topic.
2188+ */
2189+ public signal void event_topic (string from, string topic);
2190+
2191+ public Channel (string channel_name, Server server) {
2192+ debug (@"+ IRC CHANNEL $channel_name");
2193+ this.name = channel_name;
2194+ this.server = server;
2195+
2196+ setup_signals ();
2197+ }
2198+
2199+ ~Channel () { debug (@"- IRC CHANNEL $name"); }
2200+
2201+ /**
2202+ * Send a message displayed in "third person"
2203+ * @param message The message to be sent.
2204+ */
2205+ public void send_action (string message) {
2206+ try {
2207+ client.action (server.name, name, message);
2208+ } catch (GLib.IOError error) {
2209+ warning (error.message);
2210+ }
2211+ }
2212+
2213+ /**
2214+ * Invite a person to join this channel.
2215+ * @param who Nick name of the person to invite.
2216+ */
2217+ public void send_invite (string who) {
2218+ try {
2219+ client.invite (server.name, name, who);
2220+ } catch (GLib.IOError error) {
2221+ warning (error.message);
2222+ }
2223+ }
2224+
2225+ /**
2226+ * Join this channel.
2227+ * @param key Password to this channel. Should be "" if there is no password.
2228+ */
2229+ public void send_join (string key = "") {
2230+ try {
2231+ client.join (server.name, name, key);
2232+ } catch (GLib.IOError error) {
2233+ warning (error.message);
2234+ }
2235+ }
2236+
2237+ /**
2238+ * Kick a user from the channel. Requires operator privileges.
2239+ * @param who Nick name of the user to be kicked.
2240+ * @param message Reason why the user has been kicked.
2241+ */
2242+ public void send_kick (string who, string message) {
2243+ try {
2244+ client.kick (server.name, name, who, message);
2245+ } catch (GLib.IOError error) {
2246+ warning (error.message);
2247+ }
2248+ }
2249+
2250+ /**
2251+ * Request topic and number of users for this channel TODO move somewhere else
2252+ */
2253+ public void send_list () {
2254+ try {
2255+ client.list (server.name, name);
2256+ } catch (GLib.IOError error) {
2257+ warning (error.message);
2258+ }
2259+ }
2260+
2261+ /**
2262+ * Send a normal message in this channel.
2263+ * @param message The message.
2264+ */
2265+ public void send_message (string message) {
2266+ try {
2267+ client.message (server.name, name, message);
2268+ } catch (GLib.IOError error) {
2269+ warning (error.message);
2270+ }
2271+ }
2272+
2273+ /**
2274+ * Request a list of names from the channel.
2275+ */
2276+ public void send_names () {
2277+ try {
2278+ client.names (server.name, name);
2279+ } catch (GLib.IOError error) {
2280+ warning (error.message);
2281+ }
2282+ }
2283+
2284+ /**
2285+ * Leave this channel.
2286+ * @param message Part message to be displayed. If null it will be fetched from the identity.
2287+ */
2288+ public void send_part (string? message = null) {
2289+ try {
2290+ client.part (server.name, name, message ?? server.identity.part_message);
2291+ } catch (GLib.IOError error) {
2292+ warning (error.message);
2293+ }
2294+ }
2295+
2296+ /**
2297+ * Change or request the channel's topic.
2298+ * @param topic The new topic, or "" if you just want to query the current topic.
2299+ */
2300+ public void send_topic (string topic = "") {
2301+ try {
2302+ client.topic (server.name, name, topic);
2303+ } catch (GLib.IOError error) {
2304+ warning (error.message);
2305+ }
2306+ }
2307+
2308+ /**
2309+ * Get the channel mode for a given user.
2310+ * @param nick Nick name of the user.
2311+ */
2312+ public string user_channel_mode (string nick) {
2313+ try {
2314+ return client.user_channel_mode (server.name, name, nick);
2315+ } catch (GLib.IOError error) {
2316+ warning (error.message);
2317+ }
2318+
2319+ return "";
2320+ }
2321+
2322+ /**
2323+ * Get the channel prefix ("@", "+") of a given user.
2324+ * @param nick Nick name of the user.
2325+ */
2326+ public string user_channel_prefix (string nick) {
2327+ try {
2328+ return client.user_channel_prefix (server.name, name, nick);
2329+ } catch (GLib.IOError error) {
2330+ warning (error.message);
2331+ }
2332+
2333+ return "";
2334+ }
2335+
2336+ void setup_signals () {
2337+ client.event_banlist.connect ((time, server, channel, mask, who, when) => {
2338+ if (server == this.server.name && name == channel)
2339+ event_banlist (mask, who, when);
2340+ });
2341+
2342+ client.event_cannot_join.connect ((time, server, channel, reason) => {
2343+ if (server == this.server.name && name == channel)
2344+ event_cannot_join (reason);
2345+ });
2346+
2347+ client.event_invite.connect ((time, server, from, channel, who) => {
2348+ if (server == this.server.name && name == channel)
2349+ event_invite (from, who);
2350+ });
2351+
2352+ client.event_join.connect ((time, server, from, channel) => {
2353+ if (server == this.server.name && name == channel)
2354+ event_join (from);
2355+ });
2356+
2357+ client.event_kick.connect ((time, server, from, channel, who, message) => {
2358+ if (server == this.server.name && name == channel)
2359+ event_kick (from, who, message);
2360+ });
2361+
2362+ client.event_list.connect ((time, server, channel, users, topic) => {
2363+ if (server == this.server.name && name == channel)
2364+ event_list (users, topic);
2365+ });
2366+
2367+ client.event_message.connect ((time, server, from, target, message) => {
2368+ if (server == this.server.name && name == target)
2369+ event_message (from, message);
2370+ });
2371+
2372+ client.event_names.connect ((time, server, channel, nicks, prefixes) => {
2373+ if (server == this.server.name && name == channel)
2374+ event_names (nicks, prefixes);
2375+ });
2376+
2377+ client.event_no_such.connect ((time, server, target, type) => {
2378+ if (server == this.server.name && name == target && type == "c")
2379+ event_no_such ();
2380+ });
2381+
2382+ client.event_part.connect ((time, server, from, channel, message) => {
2383+ if (server == this.server.name && name == channel)
2384+ event_part (from, message);
2385+ });
2386+
2387+ client.event_topic.connect ((time, server, from, channel, topic) => {
2388+ if (server == this.server.name && name == channel)
2389+ event_topic (from, topic);
2390+ });
2391+ }
2392+}
2393
2394=== added file 'src/Irc/Client.vala'
2395--- src/Irc/Client.vala 1970-01-01 00:00:00 +0000
2396+++ src/Irc/Client.vala 2013-08-11 12:01:40 +0000
2397@@ -0,0 +1,59 @@
2398+/***
2399+ Copyright (C) 2013 Cable Developers
2400+
2401+ This program or library is free software; you can redistribute it
2402+ and/or modify it under the terms of the GNU Lesser General Public
2403+ License as published by the Free Software Foundation; either
2404+ version 3 of the License, or (at your option) any later version.
2405+
2406+ This library is distributed in the hope that it will be useful,
2407+ but WITHOUT ANY WARRANTY; without even the implied warranty of
2408+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2409+ Lesser General Public License for more details.
2410+
2411+ You should have received a copy of the GNU Lesser General
2412+ Public License along with this library; if not, write to the
2413+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2414+ Boston, MA 02110-1301 USA.
2415+***/
2416+
2417+class Cable.Irc.Client : GLib.Object {
2418+
2419+ /**
2420+ * Names of the servers we are currently connected to.
2421+ */
2422+ public static string[] server_names {
2423+ owned get {
2424+ try {
2425+ return client.servers ();
2426+ } catch (GLib.IOError e) {
2427+ warning (e.message);
2428+ }
2429+
2430+ return {};
2431+ }
2432+ }
2433+
2434+ /**
2435+ * All known servers.
2436+ */
2437+ public static string[] known_server_names {
2438+ owned get {
2439+ try {
2440+ return client.server_list ("", "");
2441+ } catch (GLib.IOError e) {
2442+ warning (e.message);
2443+ }
2444+
2445+ return {};
2446+ }
2447+ }
2448+
2449+ /*public static string config_get (string group, string key) throws GLib.IOError {
2450+ return client.config_get (group, key);
2451+ }
2452+
2453+ public static void config_set (string group, string key, string value) throws GLib.IOError {
2454+ client.action (group, key, value);
2455+ }*/
2456+}
2457
2458=== added file 'src/Irc/Irc.vala'
2459--- src/Irc/Irc.vala 1970-01-01 00:00:00 +0000
2460+++ src/Irc/Irc.vala 2013-08-11 12:01:40 +0000
2461@@ -0,0 +1,43 @@
2462+/***
2463+ Copyright (C) 2013 Cable Developers
2464+
2465+ This program or library is free software; you can redistribute it
2466+ and/or modify it under the terms of the GNU Lesser General Public
2467+ License as published by the Free Software Foundation; either
2468+ version 3 of the License, or (at your option) any later version.
2469+
2470+ This library is distributed in the hope that it will be useful,
2471+ but WITHOUT ANY WARRANTY; without even the implied warranty of
2472+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2473+ Lesser General Public License for more details.
2474+
2475+ You should have received a copy of the GNU Lesser General
2476+ Public License along with this library; if not, write to the
2477+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2478+ Boston, MA 02110-1301 USA.
2479+***/
2480+
2481+/**
2482+ * Namespace for all IRC backend related classes.
2483+ */
2484+namespace Cable.Irc {
2485+
2486+ /**
2487+ * Static reference to the maki interface.
2488+ */
2489+ Maki client = null;
2490+
2491+ public void init () {
2492+ if (client == null) {
2493+ try {
2494+ client = Bus.get_proxy_sync (GLib.BusType.SESSION, "de.ikkoku.sushi", "/de/ikkoku/sushi");
2495+ } catch (GLib.IOError error) {
2496+ warning (error.message);
2497+ }
2498+
2499+ debug ("Successfully connected to Sushi dbus session.\n");
2500+ }
2501+
2502+ Server.init ();
2503+ }
2504+}
2505
2506=== added file 'src/Irc/Maki.vala'
2507--- src/Irc/Maki.vala 1970-01-01 00:00:00 +0000
2508+++ src/Irc/Maki.vala 2013-08-11 12:01:40 +0000
2509@@ -0,0 +1,278 @@
2510+/***
2511+ Copyright (C) 2013 Cable Developers
2512+
2513+ This program or library is free software; you can redistribute it
2514+ and/or modify it under the terms of the GNU Lesser General Public
2515+ License as published by the Free Software Foundation; either
2516+ version 3 of the License, or (at your option) any later version.
2517+
2518+ This library is distributed in the hope that it will be useful,
2519+ but WITHOUT ANY WARRANTY; without even the implied warranty of
2520+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2521+ Lesser General Public License for more details.
2522+
2523+ You should have received a copy of the GNU Lesser General
2524+ Public License along with this library; if not, write to the
2525+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2526+ Boston, MA 02110-1301 USA.
2527+***/
2528+
2529+/**
2530+ * This is a dbus interface to the maki daemon from the SushiIRC project.
2531+ * Use the methods to send requests or messages to the server and the
2532+ * signals to react to the server's replies.
2533+ */
2534+[DBus (name = "de.ikkoku.sushi", timeout = 120000)]
2535+public interface Cable.Irc.Maki : GLib.Object {
2536+
2537+ [DBus (name = "action")]
2538+ public abstract void action (string server, string channel, string message) throws GLib.IOError;
2539+
2540+ [DBus (name = "away")]
2541+ public abstract void away (string server, string message) throws GLib.IOError;
2542+
2543+ [DBus (name = "back")]
2544+ public abstract void back (string server) throws GLib.IOError;
2545+
2546+ [DBus (name = "channel_nicks")]
2547+ public abstract void channel_nicks (string server, string channel, out string[] nicks, out string[] prefixes) throws GLib.IOError;
2548+
2549+ [DBus (name = "channel_topic")]
2550+ public abstract string channel_topic (string server, string channel) throws GLib.IOError;
2551+
2552+ [DBus (name = "channels")]
2553+ public abstract string[] channels (string server) throws GLib.IOError;
2554+
2555+ [DBus (name = "config_get")]
2556+ public abstract string config_get (string group, string key) throws GLib.IOError;
2557+
2558+ [DBus (name = "config_set")]
2559+ public abstract void config_set (string group, string key, string value) throws GLib.IOError;
2560+
2561+ // connect to a server known to maki
2562+ [DBus (name = "connect")]
2563+ public abstract void connect (string server) throws GLib.IOError;
2564+
2565+ [DBus (name = "ctcp")]
2566+ public abstract void ctcp (string server, string target, string message) throws GLib.IOError;
2567+
2568+ [DBus (name = "dcc_send")]
2569+ public abstract void dcc_send(string server, string target, string path) throws GLib.IOError;
2570+
2571+ [DBus (name = "dcc_sends")]
2572+ public abstract void dcc_sends (out uint64[] ids, out string[] servers, out string[] froms, out string[] filenames, out uint64[] sizes, out uint64[] progresses, out uint64[] speeds, out uint64[] statuses) throws GLib.IOError;
2573+
2574+ [DBus (name = "dcc_send_accept")]
2575+ public abstract void dcc_send_accept (uint64 id) throws GLib.IOError;
2576+
2577+ [DBus (name = "dcc_send_get")]
2578+ public abstract string dcc_send_get (uint64 id, string key) throws GLib.IOError;
2579+
2580+ [DBus (name = "dcc_send_remove")]
2581+ public abstract void dcc_send_remove (uint64 id) throws GLib.IOError;
2582+
2583+ [DBus (name = "dcc_send_resume")]
2584+ public abstract void dcc_send_resume (uint64 id) throws GLib.IOError;
2585+
2586+ [DBus (name = "dcc_send_set")]
2587+ public abstract void dcc_send_set (uint64 id, string key, string value) throws GLib.IOError;
2588+
2589+ [DBus (name = "ignore")]
2590+ public abstract void ignore (string server, string pattern) throws GLib.IOError;
2591+
2592+ [DBus (name = "ignores")]
2593+ public abstract string[] ignores (string server) throws GLib.IOError;
2594+
2595+ [DBus (name = "invite")]
2596+ public abstract void invite (string server, string channel, string who) throws GLib.IOError;
2597+
2598+ [DBus (name = "join")]
2599+ public abstract void join (string server, string channel, string key) throws GLib.IOError;
2600+
2601+ [DBus (name = "kick")]
2602+ public abstract void kick (string server, string channel, string who, string message) throws GLib.IOError;
2603+
2604+ [DBus (name = "list")]
2605+ public abstract void list (string server, string channel) throws GLib.IOError;
2606+
2607+ [DBus (name = "log")]
2608+ public abstract string[] log (string server, string target, uint64 lines) throws GLib.IOError;
2609+
2610+ [DBus (name = "message")]
2611+ public abstract void message (string server, string target, string message) throws GLib.IOError;
2612+
2613+ [DBus (name = "mode")]
2614+ public abstract void mode (string server, string target, string mode) throws GLib.IOError;
2615+
2616+ [DBus (name = "names")]
2617+ public abstract void names (string server, string channel) throws GLib.IOError;
2618+
2619+ [DBus (name = "nick")]
2620+ public abstract void nick (string server, string nick) throws GLib.IOError;
2621+
2622+ [DBus (name = "nickserv")]
2623+ public abstract void nickserv (string server) throws GLib.IOError;
2624+
2625+ [DBus (name = "notice")]
2626+ public abstract void notice (string server, string target, string message) throws GLib.IOError;
2627+
2628+ [DBus (name = "oper")]
2629+ public abstract void oper (string server, string name, string password) throws GLib.IOError;
2630+
2631+ [DBus (name = "part")]
2632+ public abstract void part (string server, string channel, string message) throws GLib.IOError;
2633+
2634+ [DBus (name = "quit")]
2635+ public abstract void quit (string server, string message) throws GLib.IOError;
2636+
2637+ [DBus (name = "raw")]
2638+ public abstract void raw (string server, string command) throws GLib.IOError;
2639+
2640+ [DBus (name = "server_get")]
2641+ public abstract string server_get (string server, string group, string key) throws GLib.IOError;
2642+
2643+ [DBus (name = "server_get_list")]
2644+ public abstract string[] server_get_list (string server, string group, string key) throws GLib.IOError;
2645+
2646+ // server_list ("", "") gives a list of servers known to maki
2647+ [DBus (name = "server_list")]
2648+ public abstract string[] server_list (string server, string group) throws GLib.IOError;
2649+
2650+ [DBus (name = "server_remove")]
2651+ public abstract void server_remove (string server, string group, string key) throws GLib.IOError;
2652+
2653+ [DBus (name = "server_rename")]
2654+ public abstract void server_rename (string old, string new_) throws GLib.IOError;
2655+
2656+ [DBus (name = "server_set")]
2657+ public abstract void server_set (string server, string group, string key, string value) throws GLib.IOError;
2658+
2659+ [DBus (name = "server_set_list")]
2660+ public abstract void server_set_list (string server, string group, string key, string[] list) throws GLib.IOError;
2661+
2662+ [DBus (name = "servers")]
2663+ public abstract string[] servers () throws GLib.IOError;
2664+
2665+ [DBus (name = "shutdown")]
2666+ public abstract void shutdown (string message) throws GLib.IOError;
2667+
2668+ [DBus (name = "support_chantypes")]
2669+ public abstract string support_chantypes (string server) throws GLib.IOError;
2670+
2671+ [DBus (name = "support_prefix")]
2672+ public abstract string[] support_prefix (string server) throws GLib.IOError;
2673+
2674+ [DBus (name = "topic")]
2675+ public abstract void topic (string server, string channel, string topic) throws GLib.IOError;
2676+
2677+ [DBus (name = "unignore")]
2678+ public abstract void unignore (string server, string pattern) throws GLib.IOError;
2679+
2680+ [DBus (name = "user_away")]
2681+ public abstract bool user_away (string server, string nick) throws GLib.IOError;
2682+
2683+ [DBus (name = "user_channel_mode")]
2684+ public abstract string user_channel_mode (string server, string channel, string nick) throws GLib.IOError;
2685+
2686+ [DBus (name = "user_channel_prefix")]
2687+ public abstract string user_channel_prefix (string server, string channel, string nick) throws GLib.IOError;
2688+
2689+ [DBus (name = "user_from")]
2690+ public abstract string user_from (string server, string nick) throws GLib.IOError;
2691+
2692+ [DBus (name = "version")]
2693+ public abstract uint64[] version () throws GLib.IOError;
2694+
2695+ [DBus (name = "who")]
2696+ public abstract void who (string server, string mask, bool operators_only) throws GLib.IOError;
2697+
2698+ [DBus (name = "whois")]
2699+ public abstract void whois (string server, string mask) throws GLib.IOError;
2700+
2701+ [DBus (name = "action")]
2702+ public signal void event_action (int64 time, string server, string from, string target, string message);
2703+
2704+ [DBus (name = "away")]
2705+ public signal void event_away (int64 time, string server);
2706+
2707+ [DBus (name = "away_message")]
2708+ public signal void event_away_message (int64 time, string server, string nick, string message);
2709+
2710+ [DBus (name = "back")]
2711+ public signal void event_back (int64 time, string server);
2712+
2713+ [DBus (name = "banlist")]
2714+ public signal void event_banlist (int64 time, string server, string channel, string mask, string who, int64 when);
2715+
2716+ [DBus (name = "cannot_join")]
2717+ public signal void event_cannot_join (int64 time, string server, string channel, string reason);
2718+
2719+ [DBus (name = "connect")]
2720+ public signal void event_connect (int64 time, string server);
2721+
2722+ [DBus (name = "connected")]
2723+ public signal void event_connected (int64 time, string server);
2724+
2725+ [DBus (name = "ctcp")]
2726+ public signal void event_ctcp (int64 time, string server, string from, string target, string message);
2727+
2728+ [DBus (name = "dcc_send")]
2729+ public signal void event_dcc_send (int64 time, string server, uint64 id, string from, string filename, uint64 size, uint64 progress, uint64 speed, uint64 status);
2730+
2731+ [DBus (name = "error")]
2732+ public signal void event_error (int64 time, string server, string domain, string reason, string[] arguments);
2733+
2734+ [DBus (name = "invite")]
2735+ public signal void event_invite (int64 time, string server, string from, string channel, string who);
2736+
2737+ [DBus (name = "join")]
2738+ public signal void event_join (int64 time, string server, string from, string channel);
2739+
2740+ [DBus (name = "kick")]
2741+ public signal void event_kick (int64 time, string server, string from, string channel, string who, string message);
2742+
2743+ [DBus (name = "list")]
2744+ public signal void event_list (int64 time, string server, string channel, int64 users, string topic);
2745+
2746+ [DBus (name = "message")]
2747+ public signal void event_message (int64 time, string server, string from, string target, string message);
2748+
2749+ [DBus (name = "mode")]
2750+ public signal void event_mode (int64 time, string server, string from, string target, string mode, string parameter);
2751+
2752+ [DBus (name = "motd")]
2753+ public signal void event_motd (int64 time, string server, string message);
2754+
2755+ [DBus (name = "names")]
2756+ public signal void event_names (int64 time, string server, string channel, string[] nicks, string[] prefixes);
2757+
2758+ [DBus (name = "nick")]
2759+ public signal void event_nick (int64 time, string server, string from, string new_nick);
2760+
2761+ [DBus (name = "no_such")]
2762+ public signal void event_no_such (int64 time, string server, string target, string type);
2763+
2764+ [DBus (name = "notice")]
2765+ public signal void event_notice (int64 time, string server, string from, string target, string message);
2766+
2767+ [DBus (name = "oper")]
2768+ public signal void event_oper (int64 time, string server);
2769+
2770+ [DBus (name = "part")]
2771+ public signal void event_part (int64 time, string server, string from, string channel, string message);
2772+
2773+ [DBus (name = "quit")]
2774+ public signal void event_quit (int64 time, string server, string from, string message);
2775+
2776+ [DBus (name = "shutdown")]
2777+ public signal void event_shutdown (int64 time);
2778+
2779+ [DBus (name = "topic")]
2780+ public signal void event_topic (int64 time, string server, string from, string channel, string topic);
2781+
2782+ [DBus (name = "user_away")]
2783+ public signal void event_user_away (int64 time, string server, string from, bool away);
2784+
2785+ [DBus (name = "whois")]
2786+ public signal void event_whois (int64 time, string server, string nick, string message);
2787+}
2788
2789=== added file 'src/Irc/Server.vala'
2790--- src/Irc/Server.vala 1970-01-01 00:00:00 +0000
2791+++ src/Irc/Server.vala 2013-08-11 12:01:40 +0000
2792@@ -0,0 +1,731 @@
2793+/***
2794+ Copyright (C) 2013 Cable Developers
2795+
2796+ This program or library is free software; you can redistribute it
2797+ and/or modify it under the terms of the GNU Lesser General Public
2798+ License as published by the Free Software Foundation; either
2799+ version 3 of the License, or (at your option) any later version.
2800+
2801+ This library is distributed in the hope that it will be useful,
2802+ but WITHOUT ANY WARRANTY; without even the implied warranty of
2803+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2804+ Lesser General Public License for more details.
2805+
2806+ You should have received a copy of the GNU Lesser General
2807+ Public License along with this library; if not, write to the
2808+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2809+ Boston, MA 02110-1301 USA.
2810+***/
2811+
2812+/**
2813+ * Cable.Irc.ServerConfig is a class that allows you to change the configuration of a server.
2814+ * This configuration is a normal keyfile. Possible keys are:
2815+ *
2816+ * autoconnect (should always be true)
2817+ * port (default, maki takes care of this)
2818+ * ssl (-> network)
2819+ * nick (-> identity)
2820+ * user (automatic)
2821+ * name (-> identity)
2822+ * address (-> network)
2823+ * nickserv (-> server, I guess...)
2824+ */
2825+public class Cable.Irc.ServerConfig : GLib.Object {
2826+
2827+ /**
2828+ * The server's name. Used by maki.
2829+ */
2830+ public string name { get; set; }
2831+
2832+ /**
2833+ * Create a new ServerConfig object.
2834+ */
2835+ public ServerConfig (string name) {
2836+ Object (name: name);
2837+ }
2838+
2839+ /**
2840+ * Get the value of a given key.
2841+ * @param key Key whose value you want to query.
2842+ * @return Value of the key.
2843+ */
2844+ public new string @get (string key) {
2845+ string result = "";
2846+
2847+ try {
2848+ result = client.server_get (this.name, "server", key);
2849+ } catch (GLib.IOError error) {
2850+ warning (error.message);
2851+ }
2852+
2853+ return result;
2854+ }
2855+
2856+ /**
2857+ * Assign a new value to a given key.
2858+ * @param key Key whose value you want to change.
2859+ * @param value New value for the given key. Use null to unset the key.
2860+ */
2861+ public new void @set (string key, string? value) {
2862+ if (value == null) {
2863+ unset (key);
2864+ return;
2865+ }
2866+
2867+ try {
2868+ client.server_set (this.name, "server", key, value);
2869+ } catch (GLib.IOError error) {
2870+ warning (error.message);
2871+ }
2872+ }
2873+
2874+ /**
2875+ * Remove a key from the config file.
2876+ * @param key Key you want to remove.
2877+ */
2878+ public void unset (string key) {
2879+ try {
2880+ client.server_remove (this.name, "server", key);
2881+ } catch (GLib.IOError error) {
2882+ warning (error.message);
2883+ }
2884+ }
2885+}
2886+
2887+/**
2888+ * The Cable.Irc.Server class is an easy to use interface to the maki daemon and provides
2889+ * methods and signals to communicate with maki via dbus.
2890+ *
2891+ * This class contains a static list of all servers. This ensures that there are no duplicates.
2892+ * XXX
2893+ */
2894+public class Cable.Irc.Server : GLib.Object {
2895+
2896+ public static Gee.ArrayList <Server> all { get; private set; }
2897+
2898+ /**
2899+ * Information about the network we are connected to.
2900+ */
2901+ public Utils.Network network {
2902+ owned get {
2903+ return Utils.Network.get_or_create (config["address"]);
2904+ }
2905+ }
2906+
2907+ /**
2908+ * Information about the identity we are using for this connection.
2909+ */
2910+ public Utils.Identity identity {
2911+ owned get {
2912+ return Utils.Identity.get_or_create (config["nick"]);
2913+ }
2914+ }
2915+
2916+ public string address {
2917+ owned get { return config["address"]; }
2918+ }
2919+
2920+ public string nick {
2921+ owned get { return config["nick"]; }
2922+ }
2923+
2924+ /**
2925+ * Server configuration.
2926+ */
2927+ public ServerConfig config { get; private set; }
2928+
2929+ /**
2930+ * The name maki uses to identify a server.
2931+ */
2932+ public string name { get; private set; }
2933+
2934+ /**
2935+ * Am I away?
2936+ */
2937+ public bool away {
2938+ get {
2939+ try {
2940+ return client.user_away (this.name, identity.nick_name);
2941+ } catch (GLib.IOError error) {
2942+ warning (error.message);
2943+ }
2944+
2945+ return false;
2946+ }
2947+ }
2948+
2949+ /**
2950+ * Am I connected?
2951+ */
2952+ public bool connected {
2953+ get {
2954+ try {
2955+ return this.name in client.servers ();
2956+ } catch (GLib.IOError error) {
2957+ warning (error.message);
2958+ }
2959+
2960+ return false;
2961+ }
2962+ }
2963+
2964+
2965+ /**
2966+ * List of joined channels.
2967+ */
2968+ public string[] channel_names {
2969+ owned get {
2970+ try {
2971+ return client.channels (this.name);
2972+ } catch (GLib.IOError error) {
2973+ warning (error.message);
2974+ }
2975+
2976+ return {};
2977+ }
2978+ }
2979+
2980+ /**
2981+ * XXX
2982+ */
2983+ public string[] supported_prefixes {
2984+ owned get {
2985+ try {
2986+ return client.support_prefix (this.name);
2987+ } catch (GLib.IOError error) {
2988+ warning (error.message);
2989+ }
2990+
2991+ return {};
2992+ }
2993+ }
2994+
2995+ /**
2996+ * XXX
2997+ */
2998+ public string supported_channel_types {
2999+ owned get {
3000+ try {
3001+ return client.support_chantypes (this.name);
3002+ } catch (GLib.IOError error) {
3003+ warning (error.message);
3004+ }
3005+
3006+ return "";
3007+ }
3008+ }
3009+
3010+ /**
3011+ * XXX
3012+ */
3013+ public string[] ignores {
3014+ owned get {
3015+ try {
3016+ return client.ignores (this.name);
3017+ } catch (GLib.IOError error) {
3018+ warning (error.message);
3019+ }
3020+
3021+ return {};
3022+ }
3023+ }
3024+
3025+ /* TODO put in channel as property and use unlimited lines:
3026+ public string[] log (string target, uint64 lines) throws GLib.IOError {
3027+ return client.log (this.name, target, lines);
3028+ }*/
3029+
3030+ // TODO document this
3031+ public signal void event_away ();
3032+ public signal void event_away_message (string nick, string message);
3033+ public signal void event_back ();
3034+ public signal void event_connected ();
3035+ public signal void event_error (string domain, string reason, string[] arguments);
3036+ public signal void event_invite (string from, string channel, string who);
3037+ public signal void event_list (string channel, uint64 users, string topic);
3038+ public signal void event_message (string from, string target, string message);
3039+ public signal void event_mode (string from, string target, string mode, string parameter);
3040+ public signal void event_motd (string message);
3041+ public signal void event_nick (string from, string new_nick);
3042+ public signal void event_no_such (string target, string type);
3043+ public signal void event_notice (string from, string target, string message);
3044+ public signal void event_oper ();
3045+
3046+ /**
3047+ * Someone has quit a channel you are in.
3048+ * @param from User who quit the channel.
3049+ * @param message Message displayed when the user quits.
3050+ */
3051+ public signal void event_quit (string from, string message);
3052+
3053+ /**
3054+ * A users away status has been changed.
3055+ * @param from Affected user.
3056+ * @param away New status.
3057+ */
3058+ public signal void event_user_away (string from, bool away);
3059+ public signal void event_whois (string nick, string message);
3060+
3061+ /**
3062+ * A server is uniquely identified by a combination of a network and an identity.
3063+ */
3064+ public Server (string address, string nick) {
3065+ debug (@"+ IRC SERVER $address");
3066+ setup_signals ();
3067+
3068+ foreach (var server in Client.server_names) {
3069+ var config = new ServerConfig (server);
3070+ if (config["nick"] == nick &&
3071+ config["address"] == address &&
3072+ config["client"] == "cable") {
3073+ name = server;
3074+ break;
3075+ }
3076+ }
3077+
3078+ if (name != null) {
3079+ debug (@"Already connected to $name.");
3080+ config = new ServerConfig (name);
3081+ } else {
3082+ name = "cable|" + GLib.Random.next_int ().to_string ();
3083+
3084+ debug (@"Creating new server $name.");
3085+
3086+ config = new ServerConfig (name);
3087+
3088+ config["nick"] = nick;
3089+ config["address"] = address;
3090+ config["nickserv"] = network.password;
3091+ config["name"] = identity.real_name;
3092+ config["autoconnect"] = "true";
3093+ config["client"] = "cable";
3094+
3095+ debug ("Successfully set up server.\n");
3096+ }
3097+
3098+ all.add (this);
3099+
3100+ event_nick.connect_after ((from, new_nick) => {
3101+ if (is_me (from))
3102+ config["nick"] = new_nick;
3103+ });
3104+ }
3105+
3106+ /**
3107+ * Creates a server from its maki name.
3108+ */
3109+ public Server.from_name (string name)
3110+ requires (name in Client.known_server_names)
3111+ requires (get_by_name (name) == null)
3112+ ensures (get_by_name (name) == this) {
3113+
3114+ setup_signals ();
3115+
3116+ this.name = name;
3117+
3118+ config = new ServerConfig (name);
3119+
3120+ debug (@"+ IRC SERVER $address (from_name)");
3121+
3122+ all.add (this);
3123+
3124+ event_nick.connect_after ((from, new_nick) => {
3125+ if (is_me (from))
3126+ config["nick"] = new_nick;
3127+ });
3128+ }
3129+
3130+ ~Server () { debug (@"- IRC SERVER $address"); }
3131+
3132+ public static void init ()
3133+ requires (all == null) {
3134+
3135+ all = new Gee.ArrayList <Server> ();
3136+ }
3137+
3138+ /**
3139+ * Get a server object by its name.
3140+ *
3141+ */
3142+ public static Server? get_by_name (string query) {
3143+ foreach (var server in Server.all)
3144+ if (server.name == query)
3145+ return server;
3146+
3147+ return (Server) null;
3148+ }
3149+
3150+ /**
3151+ * Get the server that uses the given network and identity.
3152+ * @param network The network the queried server is using.
3153+ * @param identity The identity the queried server is using.
3154+ * @return The queried server if it exists, otherwise null.
3155+ */
3156+ public static Server get_or_create (string address, string nick) {
3157+ return search (address, nick) ?? new Server (address, nick);
3158+ }
3159+
3160+ public static Server? search (string address, string nick) {
3161+ foreach (var server in Server.all)
3162+ if (server.config["address"] == address &&
3163+ server.config["nick"] == nick)
3164+ return server;
3165+ return (Server) null;
3166+ }
3167+
3168+
3169+
3170+ /**
3171+ * Check if a command was issued by me.
3172+ */
3173+ public bool is_me (string from) {
3174+ var nick = from.split ("!")[0];
3175+ return nick == identity.nick_name;
3176+ }
3177+
3178+ /*void debug_message (string title, string args) {
3179+ debug (@"[$(network.address) - $(identity.nick_name)] $title ($args)");
3180+ }*/
3181+
3182+ /**
3183+ * Pass on signals from the backend daemon without the time and server parameters.
3184+ */
3185+ void setup_signals () {
3186+ client.event_away.connect ((time, server) => {
3187+ if (server == this.name)
3188+ event_away ();
3189+ });
3190+
3191+ client.event_away_message.connect ((time, server, nick, message) => {
3192+ if (server == this.name)
3193+ event_away_message (nick, message);
3194+ });
3195+
3196+ client.event_back.connect ((time, server) => {
3197+ if (server == this.name)
3198+ event_back ();
3199+ });
3200+
3201+ client.event_connected.connect ((time, server) => {
3202+ if (server == this.name)
3203+ event_connected ();
3204+ });
3205+
3206+ /* client.event_ctcp.connect ((time, server, from, target, message) => {
3207+ if (server == this.name)
3208+ event_ctcp (from, target, message);
3209+ });
3210+
3211+ client.event_dcc_send.connect ((time, server, id, from, filename, size, progress, speed, status) => {
3212+ if (server == this.name)
3213+ event_dcc_send (id, from, filename, size, progress, speed, status);
3214+ });*/
3215+
3216+ client.event_error.connect ((time, server, domain, reason, arguments) => {
3217+ if (server == this.name)
3218+ event_error (domain, reason, arguments);
3219+ });
3220+
3221+ client.event_invite.connect ((time, server, from, channel, who) => {
3222+ if (server == this.name)
3223+ event_invite (from, channel, who);
3224+ });
3225+
3226+ client.event_list.connect ((time, server, channel, users, topic) => {
3227+ if (server == this.name)
3228+ event_list (channel, users, topic);
3229+ });
3230+
3231+ client.event_message.connect ((time, server, from, target, message) => {
3232+ if (server == this.name)
3233+ event_message (from, target, message);
3234+ });
3235+
3236+ client.event_mode.connect ((time, server, from, target, mode, parameter) => {
3237+ if (server == this.name)
3238+ event_mode (from, target, mode, parameter);
3239+ });
3240+
3241+ client.event_motd.connect ((time, server, message) => {
3242+ if (server == this.name)
3243+ event_motd (message);
3244+ });
3245+
3246+ client.event_nick.connect ((time, server, from, new_nick) => {
3247+ if (server == this.name)
3248+ event_nick (from, new_nick);
3249+ });
3250+
3251+ client.event_no_such.connect ((time, server, target, type) => {
3252+ if (server == this.name)
3253+ event_no_such (target, type);
3254+ });
3255+
3256+ client.event_notice.connect ((time, server, from, target, message) => {
3257+ if (server == this.name)
3258+ event_notice (from, target, message);
3259+ });
3260+
3261+ client.event_oper.connect ((time, server) => {
3262+ if (server == this.name)
3263+ event_oper ();
3264+ });
3265+
3266+ client.event_quit.connect ((time, server, from, message) => {
3267+ if (server == this.name)
3268+ event_quit (from, message);
3269+ });
3270+
3271+ client.event_user_away.connect ((time, server, from, away) => {
3272+ if (server == this.name)
3273+ event_user_away (from, away);
3274+ });
3275+
3276+ client.event_whois.connect ((time, server, nick, message) => {
3277+ if (server == this.name)
3278+ event_whois (nick, message);
3279+ });
3280+ }
3281+
3282+ /**
3283+ * Set your status to "away" and leave a message.
3284+ * @param message Message displayed to users trying to talk to you.
3285+ */
3286+ public void send_away (string? message = null) {
3287+ try {
3288+ client.away (this.name, message ?? identity.away_message);
3289+ } catch (GLib.IOError error) {
3290+ warning (error.message);
3291+ }
3292+ }
3293+
3294+ /**
3295+ * Unsets "away" status.
3296+ */
3297+ public void send_back () {
3298+ try {
3299+ client.back (this.name);
3300+ } catch (GLib.IOError error) {
3301+ warning (error.message);
3302+ }
3303+ }
3304+
3305+ /**
3306+ * Connect to this server.
3307+ */
3308+ public new void send_connect () {
3309+ try {
3310+ client.connect (this.name);
3311+ } catch (GLib.IOError error) {
3312+ warning (error.message);
3313+ }
3314+ }
3315+
3316+ /*public void ctcp (string target, string message) throws GLib.IOError {
3317+ client.ctcp (this.name, target, message);
3318+ }
3319+
3320+ public void dcc_send (string target, string path) throws GLib.IOError {
3321+ client.action (this.name, target, path);
3322+ }
3323+
3324+ public void dcc_sends (out uint64[] ids, out string[] servers, out string[] froms, out string[] filenames, out uint64[] sizes, out uint64[] progresses, out uint64[] speeds, out uint64[] statuses) throws GLib.IOError {
3325+ client.action (this.name, channel, message);
3326+ }
3327+
3328+ public void dcc_send_accept (uint64 id) throws GLib.IOError {
3329+ client.action (this.name, channel, message);
3330+ }
3331+
3332+ public string dcc_send_get (uint64 id, string key) throws GLib.IOError {
3333+ client.action (this.name, channel, message);
3334+ }
3335+
3336+ public void dcc_send_remove (uint64 id) throws GLib.IOError {
3337+ client.action (this.name, channel, message);
3338+ }
3339+
3340+ public void dcc_send_resume (uint64 id) throws GLib.IOError {
3341+ client.action (this.name, channel, message);
3342+ }
3343+
3344+ public void dcc_send_set (uint64 id, string key, string value) throws GLib.IOError {
3345+ client.action (this.name, channel, message);
3346+ }*/
3347+
3348+ /**
3349+ * Ignore messages from users who fit the given pattern.
3350+ * @param pattern The pattern to use.
3351+ */
3352+ public void send_ignore (string pattern) {
3353+ try {
3354+ client.ignore (this.name, pattern);
3355+ } catch (GLib.IOError error) {
3356+ warning (error.message);
3357+ }
3358+ }
3359+
3360+ /**
3361+ * Send a message to a givent target.
3362+ * @param target can be a channel or a user.
3363+ * @param message Message you want to send.
3364+ */
3365+ public void send_message (string target, string message) {
3366+ try {
3367+ client.message (this.name, target, message);
3368+ } catch (GLib.IOError error) {
3369+ warning (error.message);
3370+ }
3371+ }
3372+
3373+ public void send_mode (string target, string mode) {
3374+ try {
3375+ client.mode (this.name, target, mode);
3376+ } catch (GLib.IOError error) {
3377+ warning (error.message);
3378+ }
3379+ }
3380+
3381+ /**
3382+ * Send a NICK request to change your current nick on this network.
3383+ * @param nick Your new nick name.
3384+ */
3385+ public void send_nick (string nick) {
3386+ try {
3387+ client.nick (this.name, nick);
3388+ } catch (GLib.IOError error) {
3389+ warning (error.message);
3390+ }
3391+ }
3392+
3393+ /**
3394+ * Identify with nickserv.
3395+ */
3396+ public void send_nickserv () {
3397+ try {
3398+ client.nickserv (this.name);
3399+ } catch (GLib.IOError error) {
3400+ warning (error.message);
3401+ }
3402+ }
3403+
3404+ /**
3405+ * Send a NOTICE.
3406+ * @param target Can be a TODO ??
3407+ * @param message The message you want to send.
3408+ */
3409+ public void send_notice (string target, string message) {
3410+ try {
3411+ client.notice (this.name, target, message);
3412+ } catch (GLib.IOError error) {
3413+ warning (error.message);
3414+ }
3415+ }
3416+
3417+ /**
3418+ * Send OPER request.
3419+ * @param name TODO
3420+ * @param password OP password.
3421+ */
3422+ public void send_oper (string name, string password) {
3423+ try {
3424+ client.oper (this.name, name, password);
3425+ } catch (GLib.IOError error) {
3426+ warning (error.message);
3427+ }
3428+ }
3429+
3430+ public void send_part (string channel, string? message = null) {
3431+ try {
3432+ client.part (this.name, channel, message ?? identity.part_message);
3433+ } catch (GLib.IOError error) {
3434+ warning (error.message);
3435+ }
3436+ }
3437+
3438+ /**
3439+ * Disconnect from the server and all channels.
3440+ * @param message Message displayed to other users.
3441+ */
3442+ public void send_quit (string message = identity.quit_message) {
3443+ try {
3444+ client.quit (this.name, message);
3445+ } catch (GLib.IOError error) {
3446+ warning (error.message);
3447+ }
3448+ }
3449+
3450+ /**
3451+ * Send a raw IRC command.
3452+ * @param command The raw command you want to send.
3453+ */
3454+ public void send_raw (string command) {
3455+ try {
3456+ client.raw (this.name, command);
3457+ } catch (GLib.IOError error) {
3458+ warning (error.message);
3459+ }
3460+ }
3461+
3462+ /**
3463+ * Remove a certain pattern from the ignored list.
3464+ * @param pattern The pattern.
3465+ */
3466+ public void send_unignore (string pattern) {
3467+ try {
3468+ client.unignore (this.name, pattern);
3469+ } catch (GLib.IOError error) {
3470+ warning (error.message);
3471+ }
3472+ }
3473+
3474+ /**
3475+ * TODO
3476+ */
3477+ public void send_who (string mask, bool operators_only) {
3478+ try {
3479+ client.who (this.name, mask, operators_only);
3480+ } catch (GLib.IOError error) {
3481+ warning (error.message);
3482+ }
3483+ }
3484+
3485+ /**
3486+ * TODO
3487+ */
3488+ public void send_whois (string mask) {
3489+ try {
3490+ client.whois (this.name, mask);
3491+ } catch (GLib.IOError error) {
3492+ warning (error.message);
3493+ }
3494+ }
3495+
3496+ /*public string server_get (string group, string key) throws GLib.IOError {
3497+ return client.server_get (this.name, group, key);
3498+ }
3499+
3500+ public string[] server_get_list (string group, string key) throws GLib.IOError {
3501+ return client.server_get_list (this.name, group, key);
3502+ }
3503+
3504+ public string[] server_list (string group) throws GLib.IOError {
3505+ return client.server_list (this.name, group);
3506+ }
3507+
3508+ public void server_remove (string group, string key) throws GLib.IOError {
3509+ client.server_remove (this.name, group, key);
3510+ }
3511+
3512+ public void server_rename (string new_name) throws GLib.IOError {
3513+ client.server_rename (this.name, new_name);
3514+ }
3515+
3516+ public void server_set (string group, string key, string value) throws GLib.IOError {
3517+ client.server_set (this.name, group, key, value);
3518+ }
3519+
3520+ public void server_set_list (string group, string key, string[] list) throws GLib.IOError {
3521+ client.server_set_list (this.name, group, key, list);
3522+ }*/
3523+}
3524
3525=== removed file 'src/Services/Client.vala'
3526--- src/Services/Client.vala 2013-06-25 12:47:28 +0000
3527+++ src/Services/Client.vala 1970-01-01 00:00:00 +0000
3528@@ -1,278 +0,0 @@
3529-/***
3530- Copyright (C) 2013 Cable Developers
3531-
3532- This program or library is free software; you can redistribute it
3533- and/or modify it under the terms of the GNU Lesser General Public
3534- License as published by the Free Software Foundation; either
3535- version 3 of the License, or (at your option) any later version.
3536-
3537- This library is distributed in the hope that it will be useful,
3538- but WITHOUT ANY WARRANTY; without even the implied warranty of
3539- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3540- Lesser General Public License for more details.
3541-
3542- You should have received a copy of the GNU Lesser General
3543- Public License along with this library; if not, write to the
3544- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
3545- Boston, MA 02110-1301 USA.
3546-***/
3547-
3548-/**
3549- * This is a dbus interface to the maki daemon from the SushiIRC project.
3550- * Use the methods to send requests or messages to the server and the
3551- * signals to react to the server's replies.
3552- *
3553- * TODO document each function or take the actual documentation, if it exists
3554- */
3555-[DBus (name = "de.ikkoku.sushi", timeout = 120000)]
3556-private interface Cable.Services.Client : GLib.Object {
3557-
3558- [DBus (name = "action")]
3559- public abstract void action (string server, string channel, string message) throws GLib.IOError;
3560-
3561- [DBus (name = "away")]
3562- public abstract void away (string server, string message) throws GLib.IOError;
3563-
3564- [DBus (name = "back")]
3565- public abstract void back (string server) throws GLib.IOError;
3566-
3567- [DBus (name = "channel_nicks")]
3568- public abstract void channel_nicks (string server, string channel, out string[] nicks, out string[] prefixes) throws GLib.IOError;
3569-
3570- [DBus (name = "channel_topic")]
3571- public abstract string channel_topic (string server, string channel) throws GLib.IOError;
3572-
3573- [DBus (name = "channels")]
3574- public abstract string[] channels (string server) throws GLib.IOError;
3575-
3576- [DBus (name = "config_get")]
3577- public abstract string config_get (string group, string key) throws GLib.IOError;
3578-
3579- [DBus (name = "config_set")]
3580- public abstract void config_set (string group, string key, string value) throws GLib.IOError;
3581-
3582- [DBus (name = "connect")]
3583- public abstract void connect (string server) throws GLib.IOError;
3584-
3585- [DBus (name = "ctcp")]
3586- public abstract void ctcp (string server, string target, string message) throws GLib.IOError;
3587-
3588- [DBus (name = "dcc_send")]
3589- public abstract void dcc_send(string server, string target, string path) throws GLib.IOError;
3590-
3591- [DBus (name = "dcc_sends")]
3592- public abstract void dcc_sends (out uint64[] ids, out string[] servers, out string[] froms, out string[] filenames, out uint64[] sizes, out uint64[] progresses, out uint64[] speeds, out uint64[] statuses) throws GLib.IOError;
3593-
3594- [DBus (name = "dcc_send_accept")]
3595- public abstract void dcc_send_accept (uint64 id) throws GLib.IOError;
3596-
3597- [DBus (name = "dcc_send_get")]
3598- public abstract string dcc_send_get (uint64 id, string key) throws GLib.IOError;
3599-
3600- [DBus (name = "dcc_send_remove")]
3601- public abstract void dcc_send_remove (uint64 id) throws GLib.IOError;
3602-
3603- [DBus (name = "dcc_send_resume")]
3604- public abstract void dcc_send_resume (uint64 id) throws GLib.IOError;
3605-
3606- [DBus (name = "dcc_send_set")]
3607- public abstract void dcc_send_set (uint64 id, string key, string value) throws GLib.IOError;
3608-
3609- [DBus (name = "ignore")]
3610- public abstract void ignore (string server, string pattern) throws GLib.IOError;
3611-
3612- [DBus (name = "ignores")]
3613- public abstract string[] ignores (string server) throws GLib.IOError;
3614-
3615- [DBus (name = "invite")]
3616- public abstract void invite (string server, string channel, string who) throws GLib.IOError;
3617-
3618- [DBus (name = "join")]
3619- public abstract void join (string server, string channel, string key) throws GLib.IOError;
3620-
3621- [DBus (name = "kick")]
3622- public abstract void kick (string server, string channel, string who, string message) throws GLib.IOError;
3623-
3624- [DBus (name = "list")]
3625- public abstract void list (string server, string channel) throws GLib.IOError;
3626-
3627- [DBus (name = "log")]
3628- public abstract string[] log (string server, string target, uint64 lines) throws GLib.IOError;
3629-
3630- [DBus (name = "message")]
3631- public abstract void message (string server, string target, string message) throws GLib.IOError;
3632-
3633- [DBus (name = "mode")]
3634- public abstract void mode (string server, string target, string mode) throws GLib.IOError;
3635-
3636- [DBus (name = "names")]
3637- public abstract void names (string server, string channel) throws GLib.IOError;
3638-
3639- [DBus (name = "nick")]
3640- public abstract void nick (string server, string nick) throws GLib.IOError;
3641-
3642- [DBus (name = "nickserv")]
3643- public abstract void nickserv (string server) throws GLib.IOError;
3644-
3645- [DBus (name = "notice")]
3646- public abstract void notice (string server, string target, string message) throws GLib.IOError;
3647-
3648- [DBus (name = "oper")]
3649- public abstract void oper (string server, string name, string password) throws GLib.IOError;
3650-
3651- [DBus (name = "part")]
3652- public abstract void part (string server, string channel, string message) throws GLib.IOError;
3653-
3654- [DBus (name = "quit")]
3655- public abstract void quit (string server, string message) throws GLib.IOError;
3656-
3657- [DBus (name = "raw")]
3658- public abstract void raw (string server, string command) throws GLib.IOError;
3659-
3660- [DBus (name = "server_get")]
3661- public abstract string server_get (string server, string group, string key) throws GLib.IOError;
3662-
3663- [DBus (name = "server_get_list")]
3664- public abstract string[] server_get_list (string server, string group, string key) throws GLib.IOError;
3665-
3666- [DBus (name = "server_list")]
3667- public abstract string[] server_list (string server, string group) throws GLib.IOError;
3668-
3669- [DBus (name = "server_remove")]
3670- public abstract void server_remove (string server, string group, string key) throws GLib.IOError;
3671-
3672- [DBus (name = "server_rename")]
3673- public abstract void server_rename (string old, string new_) throws GLib.IOError;
3674-
3675- [DBus (name = "server_set")]
3676- public abstract void server_set (string server, string group, string key, string value) throws GLib.IOError;
3677-
3678- [DBus (name = "server_set_list")]
3679- public abstract void server_set_list (string server, string group, string key, string[] list) throws GLib.IOError;
3680-
3681- [DBus (name = "servers")]
3682- public abstract string[] servers () throws GLib.IOError;
3683-
3684- [DBus (name = "shutdown")]
3685- public abstract void shutdown (string message) throws GLib.IOError;
3686-
3687- [DBus (name = "support_chantypes")]
3688- public abstract string support_chantypes (string server) throws GLib.IOError;
3689-
3690- [DBus (name = "support_prefix")]
3691- public abstract string[] support_prefix (string server) throws GLib.IOError;
3692-
3693- [DBus (name = "topic")]
3694- public abstract void topic (string server, string channel, string topic) throws GLib.IOError;
3695-
3696- [DBus (name = "unignore")]
3697- public abstract void unignore (string server, string pattern) throws GLib.IOError;
3698-
3699- [DBus (name = "user_away")]
3700- public abstract bool user_away (string server, string nick) throws GLib.IOError;
3701-
3702- [DBus (name = "user_channel_mode")]
3703- public abstract string user_channel_mode (string server, string channel, string nick) throws GLib.IOError;
3704-
3705- [DBus (name = "user_channel_prefix")]
3706- public abstract string user_channel_prefix (string server, string channel, string nick) throws GLib.IOError;
3707-
3708- [DBus (name = "user_from")]
3709- public abstract string user_from (string server, string nick) throws GLib.IOError;
3710-
3711- [DBus (name = "version")]
3712- public abstract uint64[] version () throws GLib.IOError;
3713-
3714- [DBus (name = "who")]
3715- public abstract void who (string server, string mask, bool operators_only) throws GLib.IOError;
3716-
3717- [DBus (name = "whois")]
3718- public abstract void whois (string server, string mask) throws GLib.IOError;
3719-
3720- [DBus (name = "action")]
3721- public signal void event_action (int64 time, string server, string from, string target, string message);
3722-
3723- [DBus (name = "away")]
3724- public signal void event_away (int64 time, string server);
3725-
3726- [DBus (name = "away_message")]
3727- public signal void event_away_message (int64 time, string server, string nick, string message);
3728-
3729- [DBus (name = "back")]
3730- public signal void event_back (int64 time, string server);
3731-
3732- [DBus (name = "banlist")]
3733- public signal void event_banlist (int64 time, string server, string channel, string mask, string who, int64 when);
3734-
3735- [DBus (name = "cannot_join")]
3736- public signal void event_cannot_join (int64 time, string server, string channel, string reason);
3737-
3738- [DBus (name = "connect")]
3739- public signal void event_connect (int64 time, string server);
3740-
3741- [DBus (name = "connected")]
3742- public signal void event_connected (int64 time, string server);
3743-
3744- [DBus (name = "ctcp")]
3745- public signal void event_ctcp (int64 time, string server, string from, string target, string message);
3746-
3747- [DBus (name = "dcc_send")]
3748- public signal void event_dcc_send (int64 time, string server, uint64 id, string from, string filename, uint64 size, uint64 progress, uint64 speed, uint64 status);
3749-
3750- [DBus (name = "error")]
3751- public signal void event_error (int64 time, string server, string domain, string reason, string[] arguments);
3752-
3753- [DBus (name = "invite")]
3754- public signal void event_invite (int64 time, string server, string from, string channel, string who);
3755-
3756- [DBus (name = "join")]
3757- public signal void event_join (int64 time, string server, string from, string channel);
3758-
3759- [DBus (name = "kick")]
3760- public signal void event_kick (int64 time, string server, string from, string channel, string who, string message);
3761-
3762- [DBus (name = "list")]
3763- public signal void event_list (int64 time, string server, string channel, int64 users, string topic);
3764-
3765- [DBus (name = "message")]
3766- public signal void event_message (int64 time, string server, string from, string target, string message);
3767-
3768- [DBus (name = "mode")]
3769- public signal void event_mode (int64 time, string server, string from, string target, string mode, string parameter);
3770-
3771- [DBus (name = "motd")]
3772- public signal void event_motd (int64 time, string server, string message);
3773-
3774- [DBus (name = "names")]
3775- public signal void event_names (int64 time, string server, string channel, string[] nicks, string[] prefixes);
3776-
3777- [DBus (name = "nick")]
3778- public signal void event_nick (int64 time, string server, string from, string new_nick);
3779-
3780- [DBus (name = "no_such")]
3781- public signal void event_no_such (int64 time, string server, string target, string type);
3782-
3783- [DBus (name = "notice")]
3784- public signal void event_notice (int64 time, string server, string from, string target, string message);
3785-
3786- [DBus (name = "oper")]
3787- public signal void event_oper (int64 time, string server);
3788-
3789- [DBus (name = "part")]
3790- public signal void event_part (int64 time, string server, string from, string channel, string message);
3791-
3792- [DBus (name = "quit")]
3793- public signal void event_quit (int64 time, string server, string from, string message);
3794-
3795- [DBus (name = "shutdown")]
3796- public signal void event_shutdown (int64 time);
3797-
3798- [DBus (name = "topic")]
3799- public signal void event_topic (int64 time, string server, string from, string channel, string topic);
3800-
3801- [DBus (name = "user_away")]
3802- public signal void event_user_away (int64 time, string server, string from, bool away);
3803-
3804- [DBus (name = "whois")]
3805- public signal void event_whois (int64 time, string server, string nick, string message);
3806-}
3807
3808=== removed file 'src/Services/Identity.vala'
3809--- src/Services/Identity.vala 2013-07-04 01:34:38 +0000
3810+++ src/Services/Identity.vala 1970-01-01 00:00:00 +0000
3811@@ -1,124 +0,0 @@
3812-/***
3813- Copyright (C) 2013 Cable Developers
3814-
3815- This program or library is free software; you can redistribute it
3816- and/or modify it under the terms of the GNU Lesser General Public
3817- License as published by the Free Software Foundation; either
3818- version 3 of the License, or (at your option) any later version.
3819-
3820- This library is distributed in the hope that it will be useful,
3821- but WITHOUT ANY WARRANTY; without even the implied warranty of
3822- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3823- Lesser General Public License for more details.
3824-
3825- You should have received a copy of the GNU Lesser General
3826- Public License along with this library; if not, write to the
3827- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
3828- Boston, MA 02110-1301 USA.
3829-***/
3830-
3831-/**
3832- * This class stores one identity and provides some convenience over a
3833- * simple struct.
3834- */
3835-public class Cable.Settings.Identity : GLib.Object {
3836-
3837- /**
3838- * Nick name displayed to other users.
3839- */
3840- public string nick_name { get; construct set; }
3841-
3842- /**
3843- * Real name, can be anything pretty much.
3844- */
3845- public string real_name { get; construct set; }
3846-
3847- /**
3848- * ...
3849- */
3850- public string user_name { get; construct set; }
3851-
3852- /**
3853- * Message displayed when leaving a channel.
3854- */
3855- public string part_message { get; construct set; }
3856-
3857- /**
3858- * Message send in reply to a private message when marked away.
3859- */
3860- public string away_message { get; construct set; }
3861-
3862- /**
3863- * Message displayed when quitting a server.
3864- */
3865- public string quit_message { get; construct set; }
3866-
3867- /**
3868- * List of all identities.
3869- */
3870- public static Utils.Array <Identity> all { get; private set; }
3871-
3872- /**
3873- * Create a new identity, only the nick name is required.
3874- */
3875- public Identity (string nick_name,
3876- string? real_name = null,
3877- string? user_name = null,
3878- string? part_message = null,
3879- string? away_message = null,
3880- string? quit_message = null)
3881- // TODO check for invalid characters and stuff
3882- requires (/^[a-z_\-\[\]\\^{}|`][a-z0-9_\-\[\]\\^{}|`]*$/i.match (nick_name)) {
3883-
3884- this.nick_name = nick_name;
3885- this.real_name = real_name ?? nick_name;
3886- this.part_message = part_message ?? _("Bye.");
3887- this.quit_message = quit_message ?? _("Quit server.");
3888- this.away_message = away_message ?? _("%s is away.").printf (nick_name);
3889-
3890- this.all.add (this);
3891- identities = all;
3892- this.notify.connect (() => Settings.identities.changed ());
3893- }
3894-
3895- ~Identity () {
3896- this.all.remove (this);
3897- }
3898-
3899- public static void init () {
3900- if (all != null)
3901- return;
3902-
3903- all = new Utils.Array <Identity> ();
3904-
3905- foreach (var identity in settings.get_strv ("identities")) {
3906- var values = identity.split (":");
3907-
3908- if (values.length != 3) {
3909- warning ("Invalid identity settings");
3910- continue;
3911- }
3912-
3913- new Settings.Identity (values[0], values[1], values[2]);
3914- }
3915-
3916- all.changed.connect (() => {
3917- string[] ids = {};
3918-
3919- foreach (var id in all)
3920- ids += string.join (":", id.nick_name, id.real_name, id.part_message);
3921-
3922- settings.set_strv ("identities", ids);
3923- });
3924- }
3925-
3926- /**
3927- * Creates the default identity from your current login.
3928- *
3929- * @returns Default identity.
3930- */
3931- public static Identity get_default () {
3932- // TODO
3933- return new Identity ("default");
3934- }
3935-}
3936
3937=== added file 'src/Services/Launcher.vala'
3938--- src/Services/Launcher.vala 1970-01-01 00:00:00 +0000
3939+++ src/Services/Launcher.vala 2013-08-11 12:01:40 +0000
3940@@ -0,0 +1,66 @@
3941+/***
3942+ Copyright (C) 2013 Cable Developers
3943+
3944+ This program or library is free software; you can redistribute it
3945+ and/or modify it under the terms of the GNU Lesser General Public
3946+ License as published by the Free Software Foundation; either
3947+ version 3 of the License, or (at your option) any later version.
3948+
3949+ This library is distributed in the hope that it will be useful,
3950+ but WITHOUT ANY WARRANTY; without even the implied warranty of
3951+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3952+ Lesser General Public License for more details.
3953+
3954+ You should have received a copy of the GNU Lesser General
3955+ Public License along with this library; if not, write to the
3956+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
3957+ Boston, MA 02110-1301 USA.
3958+***/
3959+
3960+/**
3961+ * Static class for managing the launcher using libunity.
3962+ */
3963+public class Cable.Launcher {
3964+
3965+ static Unity.LauncherEntry launcher_entry;
3966+
3967+ /**
3968+ * Number shown in the badge on the launcher.
3969+ * If the value is zero, the badge will be hidden automatically.
3970+ */
3971+ public static int64 jobs {
3972+ get { return launcher_entry.count; }
3973+ set {
3974+ assert (value >= 0);
3975+ launcher_entry.count = value;
3976+ launcher_entry.count_visible = value > 0;
3977+ }
3978+ }
3979+
3980+ /**
3981+ * Progress shown on the launcher. Will be hidden when complete.
3982+ */
3983+ public static double progress {
3984+ get { return launcher_entry.progress; }
3985+ set {
3986+ assert (0.0 <= value <= 1.0);
3987+ launcher_entry.progress = value;
3988+ launcher_entry.progress_visible = value < 1.0;
3989+ }
3990+ }
3991+
3992+ /**
3993+ * Set launcher to urgent.
3994+ */
3995+ public static bool urgent {
3996+ get { return launcher_entry.urgent; }
3997+ set { launcher_entry.urgent = value; }
3998+ }
3999+
4000+ /**
4001+ * Must be called before anything else.
4002+ */
4003+ public static void init () {
4004+ launcher_entry = Unity.LauncherEntry.get_for_desktop_id ("cable.desktop");
4005+ }
4006+}
4007
4008=== removed file 'src/Services/Network.vala'
4009--- src/Services/Network.vala 2013-07-04 01:34:38 +0000
4010+++ src/Services/Network.vala 1970-01-01 00:00:00 +0000
4011@@ -1,104 +0,0 @@
4012-/***
4013- Copyright (C) 2013 Cable Developers
4014-
4015- This program or library is free software; you can redistribute it
4016- and/or modify it under the terms of the GNU Lesser General Public
4017- License as published by the Free Software Foundation; either
4018- version 3 of the License, or (at your option) any later version.
4019-
4020- This library is distributed in the hope that it will be useful,
4021- but WITHOUT ANY WARRANTY; without even the implied warranty of
4022- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4023- Lesser General Public License for more details.
4024-
4025- You should have received a copy of the GNU Lesser General
4026- Public License along with this library; if not, write to the
4027- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
4028- Boston, MA 02110-1301 USA.
4029-***/
4030-
4031-/**
4032- * This class represents a network. All used networks must be contained in Settings.networks,
4033- * changes to this class will emit the Settings.networks.changed () signal.
4034- */
4035-
4036-public class Cable.Settings.Network : GLib.Object {
4037-
4038- /**
4039- * The address of the network, i.e., "irc.freenode.net"
4040- */
4041- public string address { get; construct set; }
4042-
4043- /**
4044- * A name to display to the user when selecting a network for instance.
4045- */
4046- public string name { get; construct set; }
4047-
4048- /**
4049- * Password, defaults to "" if it isn't required.
4050- */
4051- public string password { get; construct set; }
4052-
4053- /**
4054- * Array of all networks. Checked for duplicates.
4055- */
4056- public static Utils.Array <Network> all { get; private set; }
4057-
4058-
4059- public Network (string address, string? name = null, string? password = null)
4060- requires (address.split (".").length == 3) {
4061-
4062- this.address = address;
4063- this.name = name ?? address.split (".")[1];
4064- this.password = password ?? "";
4065-
4066- this.all.add (this);
4067- this.notify.connect (() => Settings.networks.changed ());
4068- }
4069-
4070- ~Network () {
4071- this.all.remove (this);
4072- }
4073-
4074- public static void init () {
4075- if (all != null)
4076- return;
4077-
4078- all = new Utils.Array <Network> ();
4079-
4080- foreach (var network in settings.get_strv ("networks")) {
4081- var values = network.split (":");
4082-
4083- if (values.length != 3) {
4084- warning ("Invalid network settings");
4085- continue;
4086- }
4087-
4088- new Settings.Network (values[0], values[1], values[2]);
4089- }
4090- networks = all;
4091-
4092- networks.changed.connect (() => {
4093- string[] networks = {};
4094-
4095- foreach (var network in all)
4096- networks += string.join (":", network.address, network.name, network.password);
4097-
4098- settings.set_strv ("networks", networks);
4099- });
4100- }
4101-
4102- /**
4103- *
4104- */
4105- public bool is_duplicate (string address, string? name = null) {
4106- foreach (var network in all) {
4107- if (network.address == address)
4108- return false;
4109- if (network.name == name)
4110- return false;
4111- }
4112-
4113- return true;
4114- }
4115-}
4116
4117=== added file 'src/Services/Notification.vala'
4118--- src/Services/Notification.vala 1970-01-01 00:00:00 +0000
4119+++ src/Services/Notification.vala 2013-08-11 12:01:40 +0000
4120@@ -0,0 +1,48 @@
4121+/***
4122+ Copyright (C) 2013 Cable Developers
4123+
4124+ This program or library is free software; you can redistribute it
4125+ and/or modify it under the terms of the GNU Lesser General Public
4126+ License as published by the Free Software Foundation; either
4127+ version 3 of the License, or (at your option) any later version.
4128+
4129+ This library is distributed in the hope that it will be useful,
4130+ but WITHOUT ANY WARRANTY; without even the implied warranty of
4131+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4132+ Lesser General Public License for more details.
4133+
4134+ You should have received a copy of the GNU Lesser General
4135+ Public License along with this library; if not, write to the
4136+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
4137+ Boston, MA 02110-1301 USA.
4138+***/
4139+
4140+/**
4141+ * Static class to deal with notifications.
4142+ */
4143+public class Cable.Notification : GLib.Object {
4144+
4145+ /**
4146+ * Initialize Notify. Only call this once.
4147+ */
4148+ public static void init () {
4149+ if (Notify.is_initted ()) {
4150+ warning ("Trying to reinitialize Notify.");
4151+ return;
4152+ }
4153+
4154+ Notify.init ("Cable");
4155+ }
4156+
4157+ /**
4158+ * Send a notfication.
4159+ */
4160+ public static void send (string summary, string body) {
4161+ var notify = new Notify.Notification (summary, body, "internet-chat");
4162+ try {
4163+ notify.show ();
4164+ } catch (Error e) {
4165+ warning (e.message);
4166+ }
4167+ }
4168+}
4169
4170=== removed file 'src/Services/Settings.vala'
4171--- src/Services/Settings.vala 2013-07-04 01:34:38 +0000
4172+++ src/Services/Settings.vala 1970-01-01 00:00:00 +0000
4173@@ -1,143 +0,0 @@
4174-/***
4175- Copyright (C) 2013 Cable Developers
4176-
4177- This program or library is free software; you can redistribute it
4178- and/or modify it under the terms of the GNU Lesser General Public
4179- License as published by the Free Software Foundation; either
4180- version 3 of the License, or (at your option) any later version.
4181-
4182- This library is distributed in the hope that it will be useful,
4183- but WITHOUT ANY WARRANTY; without even the implied warranty of
4184- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4185- Lesser General Public License for more details.
4186-
4187- You should have received a copy of the GNU Lesser General
4188- Public License along with this library; if not, write to the
4189- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
4190- Boston, MA 02110-1301 USA.
4191-***/
4192-
4193-/**
4194- * Pseudo static class for dealing with gsettings.
4195- *
4196- * How this works:
4197- *
4198- * All settings are stored as public and static members of this class.
4199- * On startup they are read from gsettings. They can be modified in several
4200- * ways (Through the user interface, through gsettings, by the program
4201- * itself…). The settings will then emit a "changed" signal, so the change
4202- * can be immediately propagated to the server, gsettings, the UI and so
4203- * on.
4204- */
4205-namespace Cable.Settings {
4206-
4207- public GLib.Settings settings;
4208-
4209- public Utils.Array <Network> networks;
4210- public Utils.Array <Identity> identities;
4211-
4212- /**
4213- * Load values from gsettings.
4214- */
4215- public static void init () {
4216- settings = new GLib.Settings ("org.pantheon.cable");
4217-
4218- Network.init ();
4219- Identity.init ();
4220- }
4221-}
4222-
4223- /*
4224-class Cable.Settings : GLib.Object {
4225-
4226- public static Array <Services.Identity> identities;
4227- public static Array <Services.Network> networks;
4228-
4229- static string[] _chans;
4230- public static string[] channels {
4231- get { return _chans = settings.get_strv ("channels"); }
4232- set { settings.set_strv ("channels", _chans = value); }
4233- }
4234-
4235- private static GLib.Settings settings;
4236-
4237- public static void init () {
4238- settings = new GLib.Settings ("org.pantheon.cable");
4239-
4240- identities = new Array <Services.Identity> ();
4241- networks = new Array <Services.Network> ();
4242-
4243- foreach (var id in settings.get_strv ("identities")) {
4244- var values = id.split (":");
4245-
4246- if (values.length != 3)
4247- warning ("Invalid identity settings");
4248-
4249- identities.add (
4250- new Services.Identity (values[0], values[1], values[2])
4251- );
4252- }
4253-
4254- identities.changed.connect (() => {
4255- string[] ids = {};
4256-
4257- foreach (var id in identities)
4258- ids += string.join (":", id.nick_name, id.real_name, id.part_message);
4259-
4260- settings.set_strv ("identities", ids);
4261- });
4262-
4263- foreach (var nw in settings.get_strv ("networks")) {
4264- var values = nw.split (":");
4265-
4266- if (values.length != 3) {
4267- warning ("Invalid network settings");
4268- continue;
4269- }
4270-
4271- networks.add (
4272- new Services.Network (values[0], values[1], values[2])
4273- );
4274- }
4275-
4276- networks.changed.connect (() => {
4277- string[] nws = {};
4278-
4279- foreach (var nw in networks)
4280- nws += string.join (":", nw.address, nw.name, nw.password);
4281-
4282- settings.set_strv ("networks", nws);
4283- });
4284- }
4285-
4286- private Settings () {
4287- }
4288-}
4289-
4290-public class Cable.Array <G> : Gee.ArrayList <G> {
4291-
4292- public signal void changed ();
4293-
4294- public override bool add (G item) {
4295- var ret = base.add (item);
4296- changed ();
4297- return ret;
4298- }
4299-
4300- public override bool remove (G item) {
4301- var ret = base.remove (item);
4302- changed ();
4303- return ret;
4304- }
4305-
4306- public override G remove_at (int index) {
4307- var ret = base.remove_at (index);
4308- changed ();
4309- return ret;
4310- }
4311-
4312- public override void @set (int index, G item) {
4313- base.set (index, item);
4314- changed ();
4315- }
4316-}*/
4317
4318=== removed file 'src/Services/Unity.vala'
4319--- src/Services/Unity.vala 2013-07-14 15:58:58 +0000
4320+++ src/Services/Unity.vala 1970-01-01 00:00:00 +0000
4321@@ -1,64 +0,0 @@
4322-// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
4323-/***
4324- BEGIN LICENSE
4325-
4326- Copyright (C) 2013 Mario Guerriero <mario@elementaryos.org>
4327- This program is free software: you can redistribute it and/or modify it
4328- under the terms of the GNU Lesser General Public License version 3, as published
4329- by the Free Software Foundation.
4330-
4331- This program is distributed in the hope that it will be useful, but
4332- WITHOUT ANY WARRANTY; without even the implied warranties of
4333- MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
4334- PURPOSE. See the GNU General Public License for more details.
4335-
4336- You should have received a copy of the GNU General Public License along
4337- with this program. If not, see <http://www.gnu.org/licenses/>
4338-
4339- END LICENSE
4340-***/
4341-
4342-using Unity;
4343-
4344-namespace Cable.Services {
4345-
4346- public Unity unity;
4347-
4348- public class Unity : GLib.Object {
4349-
4350- private int jobs = 0;
4351- private LauncherEntry launcher_entry;
4352-
4353- public Unity (string desktop_id) {
4354- launcher_entry = LauncherEntry.get_for_desktop_id (desktop_id);
4355- }
4356-
4357- public void set_progress (double percentage) {
4358- // If it is not 100 % show it
4359- launcher_entry.progress = (percentage/jobs);
4360- launcher_entry.progress_visible = true;
4361- }
4362-
4363- // Add new red badge to show the number of pending works
4364- public void append_job () {
4365- jobs++;
4366-
4367- launcher_entry.count = jobs;
4368- launcher_entry.count_visible = (jobs > 0);
4369- }
4370-
4371- public void remove_job () {
4372- jobs--;
4373-
4374- launcher_entry.count = jobs;
4375- launcher_entry.count_visible = (jobs > 0);
4376- }
4377-
4378- public void clear () {
4379- jobs = 0;
4380- launcher_entry.count = jobs;
4381- launcher_entry.count_visible = false;
4382- launcher_entry.progress_visible = false;
4383- }
4384- }
4385-}
4386
4387=== added directory 'src/Settings'
4388=== added file 'src/Settings/Preferences.vala'
4389--- src/Settings/Preferences.vala 1970-01-01 00:00:00 +0000
4390+++ src/Settings/Preferences.vala 2013-08-11 12:01:40 +0000
4391@@ -0,0 +1,39 @@
4392+public class Cable.Settings.Preferences : Granite.Services.Settings {
4393+
4394+ public string[] networks { get; set; }
4395+ public string[] identities { get; set; }
4396+ public string[] channels { get; set; }
4397+
4398+ public Preferences () {
4399+ base ("org.pantheon.cable");
4400+ }
4401+
4402+ /*public override void verify (string key) {
4403+ switch (key) {
4404+
4405+ case "networks":
4406+ string[] new_value = {};
4407+
4408+ foreach (var network in networks)
4409+ if (network.split (":").length == 3)
4410+ new_value += network;
4411+
4412+ if (networks != new_value)
4413+ networks = new_value;
4414+
4415+ break;
4416+
4417+ case "identities":
4418+ string[] new_value = {};
4419+
4420+ foreach (var identity in identities)
4421+ if (identity.split (":").length == 3)
4422+ new_value += identity;
4423+
4424+ if (identities != new_value)
4425+ identities = new_value;
4426+
4427+ break;
4428+ }
4429+ }*/
4430+}
4431
4432=== added file 'src/Settings/SavedState.vala'
4433=== added file 'src/Settings/Settings.vala'
4434--- src/Settings/Settings.vala 1970-01-01 00:00:00 +0000
4435+++ src/Settings/Settings.vala 2013-08-11 12:01:40 +0000
4436@@ -0,0 +1,33 @@
4437+/***
4438+ Copyright (C) 2013 Cable Developers
4439+
4440+ This program or library is free software; you can redistribute it
4441+ and/or modify it under the terms of the GNU Lesser General Public
4442+ License as published by the Free Software Foundation; either
4443+ version 3 of the License, or (at your option) any later version.
4444+
4445+ This library is distributed in the hope that it will be useful,
4446+ but WITHOUT ANY WARRANTY; without even the implied warranty of
4447+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4448+ Lesser General Public License for more details.
4449+
4450+ You should have received a copy of the GNU Lesser General
4451+ Public License along with this library; if not, write to the
4452+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
4453+ Boston, MA 02110-1301 USA.
4454+***/
4455+
4456+/**
4457+ * Namespace for accessing the app's gsettings. May be used by any part of the app.
4458+ */
4459+namespace Cable.Settings {
4460+
4461+ public static Settings.Preferences preferences;
4462+
4463+ /**
4464+ * Load values from gsettings.
4465+ */
4466+ public static void init () {
4467+ preferences = new Settings.Preferences ();
4468+ }
4469+}
4470
4471=== added directory 'src/Tests'
4472=== added file 'src/Tests/Tests.vala'
4473--- src/Tests/Tests.vala 1970-01-01 00:00:00 +0000
4474+++ src/Tests/Tests.vala 2013-08-11 12:01:40 +0000
4475@@ -0,0 +1,13 @@
4476+namespace Cable.Tests {
4477+
4478+ public int run (string[] args) {
4479+ /*Test.init (ref args);
4480+
4481+ Test.add_func ("/Utils/Markup", (TestFunc) Utils.test_markup);
4482+ Test.add_func ("/Utils/Network", (TestFunc) Utils.test_networks);
4483+ Test.add_func ("/Utils/Identity", (TestFunc) Utils.test_identities);
4484+
4485+ return Test.run ();*/
4486+ return 0;
4487+ }
4488+}
4489
4490=== added file 'src/Tests/Utils.vala'
4491--- src/Tests/Utils.vala 1970-01-01 00:00:00 +0000
4492+++ src/Tests/Utils.vala 2013-08-11 12:01:40 +0000
4493@@ -0,0 +1,101 @@
4494+using Cable.Utils;
4495+
4496+namespace Cable.Tests.Utils {
4497+
4498+ const string[] urls = {
4499+ "http://www.google.com",
4500+ "http://www.valadoc.org/#!api=libgee-0.8/Gee.HashSet",
4501+ "https://encrypted.google.com/#bav=on.2,or.r_qf.&fp=9ff24d502d1bb08f&q=%C4%91%C5%82%C5%82%7D%5D%C5%A7%E2%86%93%C2%B3%C2%BC%7D%E2%86%93%C2%B2%C4%91&safe=off",
4502+ "www.bob.com",
4503+ "mailto:test@gmail.com",
4504+ "test@gmail.com"
4505+ };
4506+
4507+ const string[] non_urls = {
4508+ "bob",
4509+ "bob.com"
4510+ };
4511+
4512+ public void test_markup () {
4513+ foreach (var url in urls)
4514+ assert (parse_string_to_markup (url) != url);
4515+
4516+ foreach (var non_url in non_urls)
4517+ assert (parse_string_to_markup (non_url) == non_url);
4518+ }
4519+
4520+ const string[] networks = {
4521+ "irc.freenode.net:Freenode:",
4522+ "irc.gimp.org:GimpNet:",
4523+ "irc.fu-berlin.de:IRCnet:",
4524+ "irc.quakenet.org:QuakeNet:",
4525+ "irc.efnet.nl:EFnet:",
4526+ "undernet.org:Undernet:",
4527+ "irc.rizon.net:Rizon:",
4528+ "c.ustream.tv:Ustream:"
4529+ };
4530+
4531+ public void test_networks () {
4532+ Cable.Settings.init ();
4533+
4534+ var settings = Cable.Settings.preferences.networks;
4535+ Cable.Settings.preferences.networks = networks;
4536+
4537+ Network.init ();
4538+ assert (Network.all.size == networks.length);
4539+
4540+ var network1 = new Network ("irc.test.net");
4541+ assert (network1.address == "irc.test.net");
4542+ assert (network1.name != null);
4543+ assert (network1.password == "");
4544+ assert (Network.all.size == networks.length + 1);
4545+
4546+ assert (Network.search ("irc.test.net") != null);
4547+ assert (Network.search ("irc.test2.net") == null);
4548+
4549+ var network2 = Network.get_or_create ("irc.test2.net");
4550+ assert (network2.address == "irc.test2.net");
4551+ assert (network2.name != null);
4552+ assert (network2.password == "");
4553+ assert (Network.all.size == networks.length + 2);
4554+
4555+ var network3 = Network.get_or_create ("irc.test2.net");
4556+ assert (network2 == network3);
4557+
4558+ Cable.Settings.preferences.networks = settings;
4559+ }
4560+
4561+ const string[] identities = {
4562+ "nick|name:Real Name:bye bye!"
4563+ };
4564+
4565+ public void test_identities () {
4566+ Cable.Settings.init ();
4567+
4568+ var settings = Cable.Settings.preferences.identities;
4569+ Cable.Settings.preferences.identities = identities;
4570+
4571+ Identity.init ();
4572+ assert (Identity.all.size == identities.length);
4573+
4574+ var identity1 = new Identity ("newnick");
4575+ assert (identity1.nick_name == "newnick");
4576+ assert (identity1.real_name != null);
4577+ assert (identity1.part_message != null);
4578+ assert (Identity.all.size == identities.length + 1);
4579+
4580+ assert (Identity.search ("newnick") != null);
4581+ assert (Identity.search ("newnick2") == null);
4582+
4583+ var identity2 = Identity.get_or_create ("newnick2");
4584+ assert (identity2.nick_name == "newnick2");
4585+ assert (identity2.real_name != null);
4586+ assert (identity2.part_message != null);
4587+ assert (Identity.all.size == identities.length + 2);
4588+
4589+ var identity3 = Identity.get_or_create ("newnick2");
4590+ assert (identity2 == identity3);
4591+
4592+ Cable.Settings.preferences.identities = settings;
4593+ }
4594+}
4595
4596=== added directory 'src/Utils'
4597=== removed file 'src/Utils.vala'
4598--- src/Utils.vala 2013-06-28 19:07:25 +0000
4599+++ src/Utils.vala 1970-01-01 00:00:00 +0000
4600@@ -1,69 +0,0 @@
4601-/***
4602- Copyright (C) 2013 Cable Developers
4603-
4604- This program or library is free software; you can redistribute it
4605- and/or modify it under the terms of the GNU Lesser General Public
4606- License as published by the Free Software Foundation; either
4607- version 3 of the License, or (at your option) any later version.
4608-
4609- This library is distributed in the hope that it will be useful,
4610- but WITHOUT ANY WARRANTY; without even the implied warranty of
4611- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4612- Lesser General Public License for more details.
4613-
4614- You should have received a copy of the GNU Lesser General
4615- Public License along with this library; if not, write to the
4616- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
4617- Boston, MA 02110-1301 USA.
4618-***/
4619-
4620-class Cable.Utils.Label : Gtk.Label {
4621-
4622- public Label (string text) {
4623- label = text;
4624- halign = Gtk.Align.START;
4625- }
4626-
4627- public Label.right (string text) {
4628- label = text;
4629- halign = Gtk.Align.END;
4630- valign = Gtk.Align.CENTER;
4631- }
4632-}
4633-
4634-public class Cable.Utils.Array <G> : Gee.ArrayList <G> {
4635-
4636- public signal void changed ();
4637-
4638- public override bool add (G item) {
4639- var ret = base.add (item);
4640- changed ();
4641- return ret;
4642- }
4643-
4644- public override bool remove (G item) {
4645- var ret = base.remove (item);
4646- changed ();
4647- return ret;
4648- }
4649-
4650- public override G remove_at (int index) {
4651- var ret = base.remove_at (index);
4652- changed ();
4653- return ret;
4654- }
4655-
4656- public override void @set (int index, G item) {
4657- base.set (index, item);
4658- changed ();
4659- }
4660-}
4661-
4662-// FIXME
4663-namespace Cable.Utils {
4664- public void filter (Gtk.Editable editable, string text, string[] needles) {
4665- foreach (var needle in needles)
4666- if (needle in text)
4667- Signal.stop_emission_by_name (editable, "insert-text");
4668- }
4669-}
4670
4671=== added file 'src/Utils/AutoScrolled.vala'
4672--- src/Utils/AutoScrolled.vala 1970-01-01 00:00:00 +0000
4673+++ src/Utils/AutoScrolled.vala 2013-08-11 12:01:40 +0000
4674@@ -0,0 +1,44 @@
4675+/***
4676+ Copyright (C) 2013 Cable Developers
4677+
4678+ This program or library is free software; you can redistribute it
4679+ and/or modify it under the terms of the GNU Lesser General Public
4680+ License as published by the Free Software Foundation; either
4681+ version 3 of the License, or (at your option) any later version.
4682+
4683+ This library is distributed in the hope that it will be useful,
4684+ but WITHOUT ANY WARRANTY; without even the implied warranty of
4685+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4686+ Lesser General Public License for more details.
4687+
4688+ You should have received a copy of the GNU Lesser General
4689+ Public License along with this library; if not, write to the
4690+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
4691+ Boston, MA 02110-1301 USA.
4692+***/
4693+
4694+public class Cable.Utils.AutoScrolled : Gtk.ScrolledWindow {
4695+
4696+ public bool autoscroll { get; set; default = true; }
4697+
4698+ public AutoScrolled () {
4699+ setup_autoscroll ();
4700+ }
4701+
4702+ void setup_autoscroll () {
4703+ var do_scroll = true;
4704+ var adj = get_vadjustment ();
4705+
4706+ get_vadjustment ().changed.connect (() => {
4707+ var do_scroll_old = do_scroll;
4708+ do_scroll = adj.value + adj.page_size == adj.upper;
4709+
4710+ if (do_scroll_old)
4711+ adj.set_value (adj.upper);
4712+ });
4713+
4714+ get_vadjustment ().value_changed.connect (() => {
4715+ do_scroll = adj.value + adj.page_size == adj.upper;
4716+ });
4717+ }
4718+}
4719
4720=== added file 'src/Utils/EmbeddedAlert.vala'
4721--- src/Utils/EmbeddedAlert.vala 1970-01-01 00:00:00 +0000
4722+++ src/Utils/EmbeddedAlert.vala 2013-08-11 12:01:40 +0000
4723@@ -0,0 +1,424 @@
4724+// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
4725+/*-
4726+ * Copyright (c) 2012 Granite Developers (http://launchpad.net/granite)
4727+ *
4728+ * This library is free software; you can redistribute it and/or
4729+ * modify it under the terms of the GNU Lesser General Public
4730+ * License as published by the Free Software Foundation; either
4731+ * version 2 of the License, or (at your option) any later version.
4732+ *
4733+ * This library is distributed in the hope that it will be useful,
4734+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4735+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4736+ * Lesser General Public License for more details.
4737+ *
4738+ * You should have received a copy of the GNU Lesser General Public
4739+ * License along with this library; if not, write to the
4740+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
4741+ * Boston, MA 02111-1307, USA.
4742+ *
4743+ * Authored by: Victor Eduardo <victoreduardm@gmail.com>
4744+ */
4745+
4746+public class Granite.Widgets.EmbeddedAlert : Gtk.EventBox {
4747+
4748+ private const int MARGIN = 78;
4749+ private const int MAX_WIDTH = 850;
4750+
4751+ private const string PRIMARY_TEXT_MARKUP = "<span weight=\"bold\" size=\"larger\">%s</span>";
4752+
4753+ private int image_size {
4754+ get {
4755+ return image.pixel_size;
4756+ }
4757+ set {
4758+ return_if_fail (value > 0 && image != null && spinner != null);
4759+ image.pixel_size = value;
4760+ image_box.set_size_request (value + 2, value);
4761+ int spinner_size = value - 10;
4762+ spinner_size = (spinner_size > 0) ? spinner_size : value;
4763+ spinner.set_size_request (spinner_size, spinner_size);
4764+ image_box.queue_resize ();
4765+ }
4766+ }
4767+
4768+ bool queued_icon_visibility = false;
4769+ public bool show_icon {
4770+ get {
4771+ return queued_icon_visibility;
4772+ }
4773+ set {
4774+ queued_icon_visibility = value;
4775+
4776+ if (!working)
4777+ set_image_box_visible (queued_icon_visibility);
4778+ }
4779+ }
4780+
4781+ public bool working {
4782+ get {
4783+ return spinner.active;
4784+ }
4785+ set {
4786+ return_if_fail (image_box != null && image != null && spinner != null);
4787+
4788+ var child = image_box.get_child ();
4789+ if (child != null)
4790+ image_box.remove (child);
4791+
4792+ image_box.add ((value) ? spinner as Gtk.Widget : image as Gtk.Widget);
4793+ set_image_box_visible (show_icon || value);
4794+ spinner.active = value;
4795+ }
4796+ }
4797+
4798+
4799+ /**
4800+ * Message header.
4801+ * The string *should not* contain any markup information, since the text will be escaped.
4802+ */
4803+ public string primary_text {
4804+ get {
4805+ return primary_text_label.label;
4806+ }
4807+ set {
4808+ set_widget_visible (primary_text_label, value.strip() != "");
4809+ primary_text_label.set_markup (Markup.printf_escaped (PRIMARY_TEXT_MARKUP, value));
4810+ }
4811+ }
4812+
4813+ /**
4814+ * Message body.
4815+ * You can include markup information along with the message.
4816+ */
4817+ public string secondary_text {
4818+ get {
4819+ return secondary_text_label.label;
4820+ }
4821+ set {
4822+ set_widget_visible (secondary_text_label, value.strip() != "");
4823+ secondary_text_label.set_markup (value);
4824+ }
4825+ }
4826+
4827+ private Gtk.MessageType _message_type = Gtk.MessageType.QUESTION;
4828+
4829+ /**
4830+ * Warning level of the message.
4831+ * Besides defining what icon to use, it also defines whether the primary and secondary
4832+ * text are selectable or not.
4833+ * The text is selectable for the WARNING, ERROR and QUESTION types.
4834+ */
4835+ public Gtk.MessageType message_type {
4836+ get {
4837+ return _message_type;
4838+ }
4839+ set {
4840+ _message_type = value;
4841+ image.set_from_icon_name (get_icon_name_for_message_type (value), Gtk.IconSize.DIALOG);
4842+
4843+ // Make sure the text is selectable if the level is WARNING, ERROR or QUESTION
4844+ bool text_selectable = value == Gtk.MessageType.WARNING ||
4845+ value == Gtk.MessageType.ERROR ||
4846+ value == Gtk.MessageType.QUESTION;
4847+ primary_text_label.selectable = secondary_text_label.selectable = text_selectable;
4848+ }
4849+ }
4850+
4851+ private Gtk.Action[] ? _actions = null;
4852+
4853+ /**
4854+ * All these actions are mapped to buttons
4855+ */
4856+ public Gtk.Action[] ? actions {
4857+ get {
4858+ return _actions;
4859+ }
4860+ set {
4861+ _actions = value;
4862+
4863+ // clear button box
4864+ foreach (var button in action_button_box.get_children ()) {
4865+ action_button_box.remove (button);
4866+ }
4867+
4868+ // Add a button for each action
4869+ if (actions != null) {
4870+ for (int i = 0; i < actions.length; i++) {
4871+ var action_item = actions[i];
4872+ if (action_item != null) {
4873+ var action_button = new_button_from_action (action_item);
4874+ action_button_box.pack_start (action_button, false, false, 0);
4875+ }
4876+ }
4877+
4878+ buttons_visible = true;
4879+ }
4880+ else {
4881+ buttons_visible = false;
4882+ }
4883+ }
4884+ }
4885+
4886+ public bool buttons_visible {
4887+ get { return action_button_box.visible; }
4888+ set { set_widget_visible (action_button_box, value); }
4889+ }
4890+
4891+ private Gtk.Grid content_grid;
4892+ private Gtk.Image image;
4893+ private Gtk.Spinner spinner;
4894+ private Gtk.EventBox image_box;
4895+ private Gtk.Label primary_text_label;
4896+ private Gtk.Label secondary_text_label;
4897+ private Gtk.ButtonBox action_button_box;
4898+
4899+ public EmbeddedAlert () {
4900+ var style = this.get_style_context ();
4901+ style.add_class (Gtk.STYLE_CLASS_VIEW);
4902+ style.add_class (Granite.StyleClass.CONTENT_VIEW);
4903+
4904+ this.primary_text_label = new Gtk.Label (null);
4905+ this.secondary_text_label = new Gtk.Label (null);
4906+
4907+ this.primary_text_label.wrap = secondary_text_label.wrap = true;
4908+ this.primary_text_label.use_markup = secondary_text_label.use_markup = true;
4909+
4910+ this.action_button_box = new Gtk.ButtonBox (Gtk.Orientation.HORIZONTAL);
4911+
4912+ this.image_box = new Gtk.EventBox ();
4913+ this.image_box.visible_window = false;
4914+ this.image_box.above_child = true;
4915+ this.image_box.halign = Gtk.Align.END;
4916+ this.image_box.valign = Gtk.Align.START;
4917+ this.image_box.margin_right = 12;
4918+
4919+ this.image = new Gtk.Image ();
4920+ this.spinner = new Gtk.Spinner ();
4921+
4922+ this.spinner.halign = Gtk.Align.CENTER;
4923+ this.spinner.valign = Gtk.Align.CENTER;
4924+
4925+ this.primary_text_label.margin_bottom = 12;
4926+ this.secondary_text_label.margin_bottom = 18;
4927+ this.primary_text_label.valign = secondary_text_label.valign = Gtk.Align.START;
4928+ this.primary_text_label.vexpand = secondary_text_label.vexpand = false;
4929+
4930+ this.action_button_box.valign = Gtk.Align.START;
4931+ this.action_button_box.vexpand = false;
4932+ this.action_button_box.spacing = 6;
4933+
4934+ this.content_grid = new Gtk.Grid ();
4935+
4936+ this.content_grid.attach (this.image_box, 1, 1, 1, 3);
4937+ this.content_grid.attach (this.primary_text_label, 2, 1, 1, 1);
4938+ this.content_grid.attach_next_to (this.secondary_text_label, this.primary_text_label,
4939+ Gtk.PositionType.BOTTOM, 1, 1);
4940+ this.content_grid.attach_next_to (this.action_button_box, this.secondary_text_label,
4941+ Gtk.PositionType.BOTTOM, 1, 1);
4942+
4943+ content_grid.halign = content_grid.valign = Gtk.Align.CENTER;
4944+ content_grid.margin = MARGIN;
4945+
4946+ // Use a fixedbin widget so that we're always in control of the size
4947+ var size_wrapper = new FixedBin (-1, -1, MAX_WIDTH, -1);
4948+ size_wrapper.set_widget (content_grid);
4949+
4950+ this.add (size_wrapper);
4951+
4952+ // INIT WIDGETS. We use these setters to avoid code duplication
4953+ this.image_size = 64;
4954+ this.working = false;
4955+ this.set_alert ("", "", null, false);
4956+ }
4957+
4958+ /** PUBLIC API **/
4959+
4960+ /**
4961+ * Convenient method that allows setting all the widget properties at once, instead of making
4962+ * single calls to set_primary_text(), set_secondary_text(), show_icon, etc. These are called
4963+ * for you internally. Using this method is recommended when you plan to destroy the widget
4964+ * after the user makes a choice, or if you want to re-use the alert to display completely
4965+ * different information, which is often the case.
4966+ */
4967+ public void set_alert (string primary_text, string secondary_text, Gtk.Action[] ? actions = null,
4968+ bool show_icon = true, Gtk.MessageType type = Gtk.MessageType.WARNING)
4969+ {
4970+ // Reset size request
4971+ set_size_request (0, 0);
4972+
4973+ this.primary_text = primary_text;
4974+ this.secondary_text = secondary_text;
4975+ this.actions = actions;
4976+ this.message_type = type;
4977+
4978+ this.show_icon = show_icon;
4979+ }
4980+
4981+ /* INTERNALS */
4982+
4983+ private void set_image_box_visible (bool visible) {
4984+ set_widget_visible (image_box, visible);
4985+ update_text_layout (visible);
4986+ }
4987+
4988+ private void update_text_layout (bool show_icon) {
4989+ // Whenever show_icon is true, the title has to be left-aligned. This also
4990+ // applies to the spinner
4991+ if (show_icon) {
4992+ primary_text_label.halign = secondary_text_label.halign = Gtk.Align.START;
4993+ primary_text_label.justify = Gtk.Justification.LEFT;
4994+ secondary_text_label.justify = Gtk.Justification.FILL;
4995+
4996+ action_button_box.set_layout (Gtk.ButtonBoxStyle.END);
4997+ action_button_box.halign = Gtk.Align.END;
4998+ }
4999+ else {
5000+ primary_text_label.halign = secondary_text_label.halign = Gtk.Align.CENTER;
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: