Code

empty messages are passed onto all listeners in pedro, gui ignores such messages
[inkscape.git] / src / jabber_whiteboard / pedrogui.cpp
1 /*
2  * Simple demo GUI for the Pedro mini-XMPP client.
3  *
4  * Authors:
5  *   Bob Jamison
6  *
7  * Copyright (C) 2005 Bob Jamison
8  *
9  *  This library is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU Lesser General Public
11  *  License as published by the Free Software Foundation; either
12  *  version 2.1 of the License, or (at your option) any later version.
13  *
14  *  This library is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  Lesser General Public License for more details.
18  *
19  *  You should have received a copy of the GNU Lesser General Public
20  *  License along with this library; if not, write to the Free Software
21  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22  */
24 #include "jabber_whiteboard/pedrogui.h"
25 #include "jabber_whiteboard/session-manager.h"
28 #include <stdarg.h>
30 namespace Pedro
31 {
35 //#########################################################################
36 //# I C O N S
37 //#########################################################################
39 static const guint8 icon_available[] =
40 { ""
41   /* Pixbuf magic (0x47646b50) */
42   "GdkP"
43   /* length: header (24) + pixel_data (672) */
44   "\0\0\2\270"
45   /* pixdata_type (0x1010002) */
46   "\1\1\0\2"
47   /* rowstride (48) */
48   "\0\0\0""0"
49   /* width (12) */
50   "\0\0\0\14"
51   /* height (14) */
52   "\0\0\0\16"
53   /* pixel_data: */
54   "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377333"
55   "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
56   "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377"
57   "\0\377\377\377\0\377\377\377\0\377333\377\377\377\377\0\377\377\377\0"
58   "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377"
59   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\37733"
60   "3\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377"
61   "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
62   "\377\377\0\377\377\377\0\377333\377\377\377\377\0\377\377\377\0\377\377"
63   "\377\0""333\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\0\377\0"
64   "\0\0\377\377\377\0\377\377\377\0\377333\377\377\377\377\0\377\377\377"
65   "\0\377\377\377\0""333\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377"
66   "\0\377\0\0\0\377\377\377\0\377\377\377\0\377333\377\377\377\377\0\377"
67   "\377\377\0\377\377\377\0""333\377\377\377\0\377\377\377\0\377\377\377"
68   "\0\377\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377333\377\377"
69   "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377"
70   "\0\377\377\377\0\377\0\0\0\377\377\377\0\377\377\377\0\377333\377\377"
71   "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""3"
72   "33\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\0\377\377\377\0"
73   "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
74   "\377\377\0\377\377\377\0""333\377\377\377\0\377\377\377\0\377\377\377"
75   "\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
76   "\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0\377\0\0\0\377"
77   "\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
78   "\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0\377\0\0\0\377"
79   "\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
80   "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377"
81   "\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
82   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
83   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
84   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0"};
87 static const guint8 icon_away[] =
88 { ""
89   /* Pixbuf magic (0x47646b50) */
90   "GdkP"
91   /* length: header (24) + pixel_data (672) */
92   "\0\0\2\270"
93   /* pixdata_type (0x1010002) */
94   "\1\1\0\2"
95   /* rowstride (48) */
96   "\0\0\0""0"
97   /* width (12) */
98   "\0\0\0\14"
99   /* height (14) */
100   "\0\0\0\16"
101   /* pixel_data: */
102   "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
103   "\0""333\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
104   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
105   "\377\0""333\377\377\377\0\377\377\377\0\377333\377\377\377\377\0\377"
106   "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
107   "\377\377\0""333\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
108   "\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
109   "\377\377\377\0\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0"
110   "\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\377\377\0\377\377\377"
111   "\0\377\377\377\0\377\0\0\377\377\377\377\377\377\377\377\377\377\377"
112   "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
113   "\377\377\377\377\377\377\0\0\377\377\377\377\0\377\0\0\377\377\377\377"
114   "\377\0\0\0\377\377\377\377\377\377\377\377\377\0\0\0\377\377\377\377"
115   "\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\0\0\377"
116   "\377\0\0\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377\377\377\0\0"
117   "\0\377\0\0\0\377\377\377\377\377\377\377\377\377\0\0\0\377\377\377\377"
118   "\377\377\0\0\377\377\0\0\377\377\377\377\377\0\0\0\377\377\377\377\377"
119   "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377"
120   "\377\377\377\0\0\377\377\0\0\377\377\377\377\377\0\0\0\377\377\377\377"
121   "\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377\377\377\377\377\377"
122   "\377\0\0\0\377\377\377\377\377\377\0\0\377\377\377\377\0\377\0\0\377"
123   "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
124   "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0"
125   "\377\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\377\377\0\0\377"
126   "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0"
127   "\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
128   "\377\0\377\377\377\0LLL\377333\377\0\0\0\377\0\0\0\377LLL\377\377\377"
129   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
130   "\377\0\377\377\377\0\377\377\377\0""333\377333\377333\377\377\377\377"
131   "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
132   "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
133   "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
134   "\0"};
137 static const guint8 icon_chat[] =
138 { ""
139   /* Pixbuf magic (0x47646b50) */
140   "GdkP"
141   /* length: header (24) + pixel_data (672) */
142   "\0\0\2\270"
143   /* pixdata_type (0x1010002) */
144   "\1\1\0\2"
145   /* rowstride (48) */
146   "\0\0\0""0"
147   /* width (12) */
148   "\0\0\0\14"
149   /* height (14) */
150   "\0\0\0\16"
151   /* pixel_data: */
152   "\377\377\377\0\377\377\377\0\377\377\377\0""333\377333\377333\377\377"
153   "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
154   "\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377\377"
155   "\0\377\377\377\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0"
156   "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377"
157   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377333\377\377\377\377"
158   "\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377"
159   "\377\0\377fff\377\377\377\0\377fff\377\377\377\0\377\377\377\0\37733"
160   "3\377\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377"
161   "fff\377\377\377\0\377fff\377\377\377\0\377fff\377\377\377\0\377333\377"
162   "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377fff"
163   "\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\0\377\0\0\0\377\0"
164   "\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""33"
165   "3\377\377\377\0\377fff\377\377\377\0\377\0\0\0\377\377\377\0\377\377"
166   "\377\0\377\377\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377"
167   "\377\0""333\377\377\377\0\377fff\377\0\0\0\377\377\377\0\377\377\377"
168   "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\377"
169   "\0\377\377\377\0\377\377\377\0""333\377\0\0\0\377\377\377\0\377\377\377"
170   "\0\377\0\0\0\377\377\377\0\377\0\0\0\377\377\377\0\377\377\377\0\377"
171   "\0\0\0\377\377\377\377\0\377\377\377\0""333\377\0\0\0\377\377\377\0\377"
172   "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
173   "\377\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0LLL\377\0\0\0\377"
174   "\377\377\0\377\377\377\0\377\0\0\0\377\377\377\0\377\0\0\0\377\377\377"
175   "\0\377\377\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0LLL\377333"
176   "\377\0\0\0\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\0\377\377"
177   "\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
178   "\377\0""333\377333\377\0\0\0\377\377\377\0\377\377\377\0\377\377\377"
179   "\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
180   "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377"
181   "\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0"};
184 static const guint8 icon_dnd[] =
185 { ""
186   /* Pixbuf magic (0x47646b50) */
187   "GdkP"
188   /* length: header (24) + pixel_data (672) */
189   "\0\0\2\270"
190   /* pixdata_type (0x1010002) */
191   "\1\1\0\2"
192   /* rowstride (48) */
193   "\0\0\0""0"
194   /* width (12) */
195   "\0\0\0\14"
196   /* height (14) */
197   "\0\0\0\16"
198   /* pixel_data: */
199   "\377\377\377\0\377\377\377\0\377\377\377\0""333\377333\377333\377\377"
200   "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
201   "\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377\377"
202   "\0\377\377\377\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0"
203   "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377"
204   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377333\377\377\377\377"
205   "\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377\377"
206   "\377\0\377fff\377\377\377\0\377fff\377\377\377\0\377\377\377\0\37733"
207   "3\377\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377"
208   "fff\377\377\377\0\377fff\377\377\377\0\377fff\377\377\377\0\377333\377"
209   "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\0\377fff"
210   "\377\377\377\0\377\377\377\0\377\377\377\0\377\177\0\0\377\177\0\0\377"
211   "\177\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"
212   "333\377\377\377\0\377fff\377\377\377\0\377\177\0\0\377\377\0\0\377\377"
213   "\0\0\377\377\0\0\377\177\0\0\377\377\377\377\0\377\377\377\0\377\377"
214   "\377\0""333\377\377\377\0\377fff\377\177\0\0\377\377\377\377\377fff\377"
215   "\377\0\0\377fff\377\377\377\377\377\177\0\0\377\377\377\377\0\377\377"
216   "\377\0\377\377\377\0""333\377\177\0\0\377\377\0\0\377fff\377\377\377"
217   "\377\377fff\377\377\377\377\377fff\377\377\0\0\377\177\0\0\377\377\377"
218   "\377\0\377\377\377\0""333\377\177\0\0\377\377\0\0\377\377\0\0\377fff"
219   "\377\377\377\377\377fff\377\377\0\0\377\377\0\0\377\177\0\0\377\377\377"
220   "\377\0\377\377\377\0LLL\377\177\0\0\377\377\0\0\377fff\377\377\377\377"
221   "\377fff\377\377\377\377\377fff\377\377\0\0\377\177\0\0\377\377\377\377"
222   "\0\377\377\377\0LLL\377333\377\177\0\0\377\377\377\377\377fff\377\377"
223   "\0\0\377fff\377\377\377\377\377\177\0\0\377\377\377\377\0\377\377\377"
224   "\0\377\377\377\0\377\377\377\0""333\377333\377\177\0\0\377\377\0\0\377"
225   "\377\0\0\377\377\0\0\377\177\0\0\377\377\377\377\0\377\377\377\0\377"
226   "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
227   "\377\377\0\177\0\0\377\177\0\0\377\177\0\0\377\377\377\377\0\377\377"
228   "\377\0\377\377\377\0"};
231 static const guint8 icon_error[] =
232 { ""
233   /* Pixbuf magic (0x47646b50) */
234   "GdkP"
235   /* length: header (24) + pixel_data (672) */
236   "\0\0\2\270"
237   /* pixdata_type (0x1010002) */
238   "\1\1\0\2"
239   /* rowstride (48) */
240   "\0\0\0""0"
241   /* width (12) */
242   "\0\0\0\14"
243   /* height (14) */
244   "\0\0\0\16"
245   /* pixel_data: */
246   "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
247   "\0""333\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
248   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377"
249   "\377\377\377\0\0\0\0\377\350\350\350\377333\377\377\377\377\0\377\377"
250   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377"
251   "\350\350\350\377fff\377\0\0\0\377\350\350\350\377\350\350\350\377333"
252   "\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377"
253   "\350\350\350\377\350\350\350\377\350\350\350\377\0\0\0\377\350\350\350"
254   "\377\350\350\350\377\350\350\350\377333\377\377\377\377\0\377\377\377"
255   "\0\377\377\377\0""333\377\350\350\350\377\350\350\350\377\0\0\0\377\0"
256   "\0\0\377fff\377\350\350\350\377\350\350\350\377333\377\377\377\377\0"
257   "\377\377\377\0\377\377\377\0""333\377\350\350\350\377\350\350\350\377"
258   "\0\0\0\377\350\350\350\377\0\0\0\377\0\0\0\377\0\0\0\377333\377\377\377"
259   "\377\0\377\377\377\0\377\377\377\0""333\377\350\350\350\377\0\0\0\377"
260   "\350\350\350\377\0\0\0\377\350\350\350\377\350\350\350\377\350\350\350"
261   "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""3"
262   "33\377\350\350\350\377\0\0\0\377\0\0\0\377\0\0\0\377\350\350\350\377"
263   "fff\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
264   "\377\0""333\377\0\0\0\377\350\350\350\377\350\350\350\377\350\350\350"
265   "\377\0\0\0\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
266   "\377\0\377\377\377\0\377\377\377\0""333\377\350\350\350\377\350\350\350"
267   "\377\350\350\350\377333\377\377\377\377\0\377\377\377\0\377\377\377\0"
268   "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0"
269   "\377\0\0\0\377\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377"
270   "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0"
271   "\0\377\0\0\0\377\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377"
272   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
273   "\377\0\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377"
274   "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
275   "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
276   "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"};
279 static const guint8 icon_offline[] =
280 { ""
281   /* Pixbuf magic (0x47646b50) */
282   "GdkP"
283   /* length: header (24) + pixel_data (672) */
284   "\0\0\2\270"
285   /* pixdata_type (0x1010002) */
286   "\1\1\0\2"
287   /* rowstride (48) */
288   "\0\0\0""0"
289   /* width (12) */
290   "\0\0\0\14"
291   /* height (14) */
292   "\0\0\0\16"
293   /* pixel_data: */
294   "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377333"
295   "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
296   "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377"
297   "\377\377\377\377\377\377\377\377\377\377333\377\377\377\377\0\377\377"
298   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377"
299   "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
300   "\377\377\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
301   "\377\0""333\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
302   "\377\377\377\377\377\377\377\377\377\377\377\377\377\377333\377\377\377"
303   "\377\0\377\377\377\0\377\377\377\0""333\377\377\377\377\377\377\377\377"
304   "\377\0\0\0\377\377\377\377\377\0\0\0\377\377\377\377\377\377\377\377"
305   "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377"
306   "\377\377\377\377\377\377\0\0\0\377\377\377\377\377\0\0\0\377\377\377"
307   "\377\377\377\377\377\377333\377\377\377\377\0\377\377\377\0\377\377\377"
308   "\0""333\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377"
309   "\377\377\377\377\377\377\377\377\377\377\377\377333\377\377\377\377\0"
310   "\377\377\377\0\377\377\377\0\377\377\377\0""333\377\377\377\377\377\377"
311   "\377\377\377\0\0\0\377\377\377\377\377\377\377\377\377333\377\377\377"
312   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377"
313   "\377\377\377\377\377\377\377\377\0\0\0\377\377\377\377\377\377\377\377"
314   "\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
315   "\377\377\0\377\377\377\0""333\377\377\377\377\377\377\377\377\377\377"
316   "\377\377\377333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
317   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0\377\0\0"
318   "\0\377\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0\377"
319   "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0LLL\377\0\0\0\377"
320   "\0\0\0\377\0\0\0\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0"
321   "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377"
322   "\0\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377"
323   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
324   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
325   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0"};
328 static const guint8 icon_xa[] =
329 { ""
330   /* Pixbuf magic (0x47646b50) */
331   "GdkP"
332   /* length: header (24) + pixel_data (672) */
333   "\0\0\2\270"
334   /* pixdata_type (0x1010002) */
335   "\1\1\0\2"
336   /* rowstride (48) */
337   "\0\0\0""0"
338   /* width (12) */
339   "\0\0\0\14"
340   /* height (14) */
341   "\0\0\0\16"
342   /* pixel_data: */
343   "\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\377333\377333\377"
344   "333\377\377\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
345   "\377\0\377\377\377\0\377\377\377\0\377\0\0\377333\377\377\377\0\377\377"
346   "\377\0\377\377\377\0\377333\377\377\0\0\377\377\377\377\0\377\377\377"
347   "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\377\377\377\0\377"
348   "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\0\0\377"
349   "\177\0\0\377\177\0\0\377\377\377\377\0\377\377\377\0""333\377\377\0\0"
350   "\377\377\377\0\377fff\377\377\377\0\377\177\0\0\377\177\0\0\377\377\0"
351   "\0\377\377\377\377\377\177\0\0\377\377\377\377\0\377\377\377\0""333\377"
352   "\377\0\0\377\177\0\0\377\177\0\0\377\177\0\0\377\377\377\377\377\377"
353   "\377\377\377\377\377\377\377\0\0\0\377\0\0\0\377\177\0\0\377\177\0\0"
354   "\377\177\0\0\377\377\0\0\377\377\377\377\377\377\377\377\377\377\377"
355   "\377\377\262\262\262\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377"
356   "\377\377\177\0\0\377\177\0\0\377\377\377\377\377\262\262\262\377\0\0"
357   "\0\377\262\262\262\377\0\0\0\377\377\377\377\377\0\0\0\377\377\377\377"
358   "\377\262\262\262\377\0\0\0\377\177\0\0\377\177\0\0\377\377\377\377\377"
359   "\0\0\0\377\377\377\377\377\0\0\0\377\0\0\0\377\377\377\377\377\0\0\0"
360   "\377\0\0\0\377\377\377\377\377\0\0\0\377\177\0\0\377\177\0\0\377\377"
361   "\377\377\377\0\0\0\377\377\377\377\377\0\0\0\377\377\377\377\377\0\0"
362   "\0\377\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\177"
363   "\0\0\377\377\377\377\0\177\0\0\377\262\262\262\377\0\0\0\377\262\262"
364   "\262\377\377\377\377\377\377\377\377\377\377\377\377\377\177\0\0\377"
365   "\177\0\0\377\177\0\0\377\377\377\377\0\377\377\377\0\177\0\0\377\377"
366   "\377\377\377\377\377\377\377\177\0\0\377\177\0\0\377\177\0\0\377\177"
367   "\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
368   "\377\377\0\177\0\0\377\177\0\0\377\177\0\0\377333\377\0\0\0\377\0\0\0"
369   "\377LLL\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377"
370   "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0""333\377333\377"
371   "333\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
372   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
373   "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377"
374   "\377\0\377\377\377\0\377\377\377\0"};
377 //#########################################################################
378 //# R O S T E R
379 //#########################################################################
382 void Roster::doubleClickCallback(const Gtk::TreeModel::Path &path,
383                    Gtk::TreeViewColumn *col)
385     Glib::RefPtr<Gtk::TreeModel> model = rosterView.get_model();
386     Glib::RefPtr<Gtk::TreeSelection> sel = rosterView.get_selection();
387     Gtk::TreeModel::iterator iter = sel->get_selected();
388     DOMString nick = iter->get_value(rosterColumns.userColumn);
389     //printf("Double clicked:%s\n", nick.c_str());
390     if (parent)
391         parent->doChat(nick);
395 void Roster::chatCallback()
397     Glib::RefPtr<Gtk::TreeModel> model = rosterView.get_model();
398     Glib::RefPtr<Gtk::TreeSelection> sel = rosterView.get_selection();
399     Gtk::TreeModel::iterator iter = sel->get_selected();
400     DOMString nick = iter->get_value(rosterColumns.userColumn);
401     //printf("Chat with:%s\n", nick.c_str());
402     if (parent)
403         parent->doChat(nick);
406 void Roster::sendFileCallback()
408     Glib::RefPtr<Gtk::TreeModel> model = rosterView.get_model();
409     Glib::RefPtr<Gtk::TreeSelection> sel = rosterView.get_selection();
410     Gtk::TreeModel::iterator iter = sel->get_selected();
411     DOMString nick = iter->get_value(rosterColumns.userColumn);
412     //printf("Send file to:%s\n", nick.c_str());
413     if (parent)
414         parent->doSendFile(nick);
417 void Roster::shareCallback()
419     Glib::RefPtr<Gtk::TreeModel> model = rosterView.get_model();
420     Glib::RefPtr<Gtk::TreeSelection> sel = rosterView.get_selection();
421     Gtk::TreeModel::iterator iter = sel->get_selected();
422     DOMString nick = iter->get_value(rosterColumns.userColumn);
423     //printf("share to:%s\n", nick.c_str());
424     if (parent)
425         parent->doShare(nick);
428 bool Roster::buttonPressCallback(GdkEventButton* event)
430     if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) )
431         {
432         Gtk::Widget *wid = uiManager->get_widget("/PopupMenu");
433         Gtk::Menu *popupMenu = dynamic_cast<Gtk::Menu*>(wid);
434         popupMenu->popup(event->button, event->time);
435         return true;
436         }
437     else
438         return false;
441 bool Roster::doSetup()
443     set_size_request(200,200);
445     pixbuf_available = Gdk::Pixbuf::create_from_inline(
446                       sizeof(icon_available), icon_available, false);
447     pixbuf_away     = Gdk::Pixbuf::create_from_inline(
448                       sizeof(icon_away), icon_away, false);
449     pixbuf_chat     = Gdk::Pixbuf::create_from_inline(
450                       sizeof(icon_chat), icon_chat, false);
451     pixbuf_dnd      = Gdk::Pixbuf::create_from_inline(
452                       sizeof(icon_dnd), icon_dnd, false);
453     pixbuf_error    = Gdk::Pixbuf::create_from_inline(
454                       sizeof(icon_error), icon_error, false);
455     pixbuf_offline  = Gdk::Pixbuf::create_from_inline(
456                       sizeof(icon_offline), icon_offline, false);
457     pixbuf_xa       = Gdk::Pixbuf::create_from_inline(
458                       sizeof(icon_xa), icon_xa, false);
460     rosterView.setParent(this);
461     treeStore = Gtk::TreeStore::create(rosterColumns);
462     rosterView.set_model(treeStore);
464     Gtk::CellRendererText *rend0 = new Gtk::CellRendererText();
465     //rend0->property_background() = "gray";
466     //rend0->property_foreground() = "black";
467     rosterView.append_column("Group", *rend0);
468     Gtk::TreeViewColumn *col0 = rosterView.get_column(0);
469     col0->add_attribute(*rend0, "text", 0);
471     Gtk::CellRendererPixbuf *rend1 = new Gtk::CellRendererPixbuf();
472     rosterView.append_column("Status", *rend1);
473     Gtk::TreeViewColumn *col1 = rosterView.get_column(1);
474     col1->add_attribute(*rend1, "pixbuf", 1);
476     Gtk::CellRendererText *rend2 = new Gtk::CellRendererText();
477     rosterView.append_column("Item", *rend2);
478     Gtk::TreeViewColumn *col2 = rosterView.get_column(2);
479     col2->add_attribute(*rend2, "text", 2);
481     Gtk::CellRendererText *rend3 = new Gtk::CellRendererText();
482     rosterView.append_column("Name", *rend3);
483     Gtk::TreeViewColumn *col3 = rosterView.get_column(3);
484     col3->add_attribute(*rend3, "text", 3);
486     Gtk::CellRendererText *rend4 = new Gtk::CellRendererText();
487     rosterView.append_column("Subscription", *rend4);
488     Gtk::TreeViewColumn *col4 = rosterView.get_column(4);
489     col4->add_attribute(*rend4, "text", 4);
491     rosterView.signal_row_activated().connect(
492         sigc::mem_fun(*this, &Roster::doubleClickCallback) );
494     add(rosterView);
495     set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
497     //##### POPUP MENU
498     Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
500     actionGroup->add( Gtk::Action::create("UserMenu", "_User Menu") );
502     actionGroup->add( Gtk::Action::create("Chat",
503                                   Gtk::Stock::CONNECT, "Chat"),
504     sigc::mem_fun(*this, &Roster::chatCallback) );
505     actionGroup->add( Gtk::Action::create("SendFile",
506                                   Gtk::Stock::CONNECT, "Send file"),
507     sigc::mem_fun(*this, &Roster::sendFileCallback) );
508     actionGroup->add( Gtk::Action::create("Share",
509                                   Gtk::Stock::CONNECT, "Share whiteboard"),
510     sigc::mem_fun(*this, &Roster::shareCallback) );
513     uiManager = Gtk::UIManager::create();
515     uiManager->insert_action_group(actionGroup, 0);
517     Glib::ustring ui_info =
518         "<ui>"
519         "  <popup name='PopupMenu'>"
520         "    <menuitem action='Chat'/>"
521         "    <menuitem action='SendFile'/>"
522         "    <menuitem action='Share'/>"
523         "  </popup>"
524         "</ui>";
526     uiManager->add_ui_from_string(ui_info);
529     show_all_children();
531     return true;
535 /**
536  * Clear the roster
537  */
538 void Roster::clear()
540     treeStore->clear();
543 /**
544  * Regenerate the roster
545  */
546 void Roster::refresh()
548    if (!parent)
549         return;
550     treeStore->clear();
551     std::vector<XmppUser> items = parent->client.getRoster();
553     //## Add in tree fashion
554     DOMString lastGroup = "";
555     Gtk::TreeModel::Row row = *(treeStore->append());
556     row[rosterColumns.groupColumn] = "";
557     for (unsigned int i=0 ; i<items.size() ; i++)
558         {
559         XmppUser user = items[i];
560         if (user.group != lastGroup)
561             {
562             if (lastGroup.size()>0)
563                 row = *(treeStore->append());
564             row[rosterColumns.groupColumn] = user.group;
565             lastGroup = user.group;
566             }
567         Glib::RefPtr<Gdk::Pixbuf> pb = pixbuf_offline;
568         if (user.show == "available")
569             pb = pixbuf_available;
570         else if (user.show == "away")
571             pb = pixbuf_away;
572         else if (user.show == "chat")
573             pb = pixbuf_chat;
574         else if (user.show == "dnd")
575             pb = pixbuf_dnd;
576         else if (user.show == "xa")
577             pb = pixbuf_xa;
578         else
579             {
580             //printf("Unknown show for %s:'%s'\n", user.c_str(), show.c_str());
581             }
582         Gtk::TreeModel::Row childRow = *(treeStore->append(row.children()));
583         childRow[rosterColumns.statusColumn] = pb;
584         childRow[rosterColumns.userColumn]   = user.jid;
585         childRow[rosterColumns.nameColumn]   = user.nick;
586         childRow[rosterColumns.subColumn]    = user.subscription;
587         }
588     rosterView.expand_all();
591 //#########################################################################
592 //# M E S S A G E    L I S T
593 //#########################################################################
595 bool MessageList::doSetup()
597     set_size_request(400,200);
599     messageListBuffer = Gtk::TextBuffer::create();
600     messageList.set_buffer(messageListBuffer);
601     messageList.set_editable(false);
602     messageList.set_wrap_mode(Gtk::WRAP_WORD_CHAR);
604     Glib::RefPtr<Gtk::TextBuffer::TagTable> table =
605         messageListBuffer->get_tag_table();
606     Glib::RefPtr<Gtk::TextBuffer::Tag> color0 =
607         Gtk::TextBuffer::Tag::create("color0");
608     color0->property_foreground() = "DarkGreen";
609     color0->property_weight()     = Pango::WEIGHT_BOLD;
610     table->add(color0);
611     Glib::RefPtr<Gtk::TextBuffer::Tag> color1 =
612         Gtk::TextBuffer::Tag::create("color1");
613     color1->property_foreground() = "chocolate4";
614     color1->property_weight()     = Pango::WEIGHT_BOLD;
615     table->add(color1);
616     Glib::RefPtr<Gtk::TextBuffer::Tag> color2 =
617         Gtk::TextBuffer::Tag::create("color2");
618     color2->property_foreground() = "red4";
619     color2->property_weight()     = Pango::WEIGHT_BOLD;
620     table->add(color2);
621     Glib::RefPtr<Gtk::TextBuffer::Tag> color3 =
622         Gtk::TextBuffer::Tag::create("color3");
623     color3->property_foreground() = "MidnightBlue";
624     color3->property_weight()     = Pango::WEIGHT_BOLD;
625     table->add(color3);
626     Glib::RefPtr<Gtk::TextBuffer::Tag> color4 =
627         Gtk::TextBuffer::Tag::create("color4");
628     color4->property_foreground() = "turquoise4";
629     color4->property_weight()     = Pango::WEIGHT_BOLD;
630     table->add(color4);
631     Glib::RefPtr<Gtk::TextBuffer::Tag> color5 =
632         Gtk::TextBuffer::Tag::create("color5");
633     color5->property_foreground() = "OliveDrab";
634     color5->property_weight()     = Pango::WEIGHT_BOLD;
635     table->add(color5);
636     Glib::RefPtr<Gtk::TextBuffer::Tag> color6 =
637         Gtk::TextBuffer::Tag::create("color6");
638     color6->property_foreground() = "purple4";
639     color6->property_weight()     = Pango::WEIGHT_BOLD;
640     table->add(color6);
641     Glib::RefPtr<Gtk::TextBuffer::Tag> color7 =
642         Gtk::TextBuffer::Tag::create("color7");
643     color7->property_foreground() = "VioletRed4";
644     color7->property_weight()     = Pango::WEIGHT_BOLD;
645     table->add(color7);
647     add(messageList);
648     set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
651     show_all_children();
653     return true;
656 /**
657  * Clear all messages from the list
658  */
659 void MessageList::clear()
661     messageListBuffer->erase(messageListBuffer->begin(),
662                              messageListBuffer->end());
666 /**
667  * Post a message to the list
668  */
669 void MessageList::postMessage(const DOMString &from, const DOMString &msg)
671     DOMString out = "<";
672     out.append(from);
673     out.append("> ");
675     int val = 0;
676     for (unsigned int i=0 ; i<from.size() ; i++)
677        val += from[i];
678     val = val % 8;
680     char buf[16];
681     sprintf(buf, "color%d", val);
682     DOMString tagName = buf;
684     messageListBuffer->insert_with_tag(
685             messageListBuffer->end(), out, tagName);
686     messageListBuffer->insert(messageListBuffer->end(), msg);
687     messageListBuffer->insert(messageListBuffer->end(), "\n");
688     //Gtk::Adjustment *adj = get_vadjustment();
689     //adj->set_value(adj->get_upper()-adj->get_page_size());
690     Glib::RefPtr<Gtk::TextBuffer::Mark> mark =
691         messageListBuffer->create_mark("temp", messageListBuffer->end());
692     messageList.scroll_mark_onscreen(mark);
693     messageListBuffer->delete_mark(mark);
698 //#########################################################################
699 //# U S E R     L I S T
700 //#########################################################################
701 void UserList::doubleClickCallback(const Gtk::TreeModel::Path &path,
702                    Gtk::TreeViewColumn *col)
704     Glib::RefPtr<Gtk::TreeModel> model = userList.get_model();
705     Glib::RefPtr<Gtk::TreeSelection> sel = userList.get_selection();
706     Gtk::TreeModel::iterator iter = sel->get_selected();
707     DOMString nick = iter->get_value(userListColumns.userColumn);
708     //printf("Double clicked:%s\n", nick.c_str());
709     if (parent)
710         parent->doChat(nick);
714 void UserList::chatCallback()
716     Glib::RefPtr<Gtk::TreeModel> model = userList.get_model();
717     Glib::RefPtr<Gtk::TreeSelection> sel = userList.get_selection();
718     Gtk::TreeModel::iterator iter = sel->get_selected();
719     DOMString nick = iter->get_value(userListColumns.userColumn);
720     //printf("Chat with:%s\n", nick.c_str());
721     if (parent)
722         parent->doChat(nick);
725 void UserList::sendFileCallback()
727     Glib::RefPtr<Gtk::TreeModel> model = userList.get_model();
728     Glib::RefPtr<Gtk::TreeSelection> sel = userList.get_selection();
729     Gtk::TreeModel::iterator iter = sel->get_selected();
730     DOMString nick = iter->get_value(userListColumns.userColumn);
731     //printf("Send file to:%s\n", nick.c_str());
732     if (parent)
733         parent->doSendFile(nick);
736 void UserList::shareCallback()
738     Glib::RefPtr<Gtk::TreeModel> model = userList.get_model();
739     Glib::RefPtr<Gtk::TreeSelection> sel = userList.get_selection();
740     Gtk::TreeModel::iterator iter = sel->get_selected();
741     DOMString nick = iter->get_value(userListColumns.userColumn);
742     //printf("Send file to:%s\n", nick.c_str());
743     if (parent)
744         parent->doShare(nick);
747 bool UserList::buttonPressCallback(GdkEventButton* event)
749     if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) )
750         {
751         Gtk::Widget *wid = uiManager->get_widget("/PopupMenu");
752         Gtk::Menu *popupMenu = dynamic_cast<Gtk::Menu*>(wid);
753         popupMenu->popup(event->button, event->time);
754         return true;
755         }
756     else
757         return false;
760 bool UserList::doSetup()
762     set_size_request(200,200);
764     setParent(NULL);
766     pixbuf_available = Gdk::Pixbuf::create_from_inline(
767                       sizeof(icon_available), icon_available, false);
768     pixbuf_away     = Gdk::Pixbuf::create_from_inline(
769                       sizeof(icon_away), icon_away, false);
770     pixbuf_chat     = Gdk::Pixbuf::create_from_inline(
771                       sizeof(icon_chat), icon_chat, false);
772     pixbuf_dnd      = Gdk::Pixbuf::create_from_inline(
773                       sizeof(icon_dnd), icon_dnd, false);
774     pixbuf_error    = Gdk::Pixbuf::create_from_inline(
775                       sizeof(icon_error), icon_error, false);
776     pixbuf_offline  = Gdk::Pixbuf::create_from_inline(
777                       sizeof(icon_offline), icon_offline, false);
778     pixbuf_xa       = Gdk::Pixbuf::create_from_inline(
779                       sizeof(icon_xa), icon_xa, false);
781     userList.setParent(this);
782     userListStore = Gtk::ListStore::create(userListColumns);
783     userList.set_model(userListStore);
785     Gtk::CellRendererPixbuf *rend0 = new Gtk::CellRendererPixbuf();
786     userList.append_column("Status", *rend0);
787     Gtk::TreeViewColumn *col0 = userList.get_column(0);
788     col0->add_attribute(*rend0, "pixbuf", 0);
790     Gtk::CellRendererText *rend1 = new Gtk::CellRendererText();
791     //rend1->property_background() = "gray";
792     //rend1->property_foreground() = "black";
793     userList.append_column("User", *rend1);
794     Gtk::TreeViewColumn *col1 = userList.get_column(1);
795     col1->add_attribute(*rend1, "text", 1);
797     userList.set_headers_visible(false);
799     userList.signal_row_activated().connect(
800         sigc::mem_fun(*this, &UserList::doubleClickCallback) );
802     add(userList);
803     set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
805     //##### POPUP MENU
806     Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
808     actionGroup->add( Gtk::Action::create("UserMenu", "_User Menu") );
810     actionGroup->add( Gtk::Action::create("Chat",
811                                   Gtk::Stock::CONNECT, "Chat"),
812     sigc::mem_fun(*this, &UserList::chatCallback) );
813     actionGroup->add( Gtk::Action::create("SendFile",
814                                   Gtk::Stock::CONNECT, "Send file"),
815     sigc::mem_fun(*this, &UserList::sendFileCallback) );
816     actionGroup->add( Gtk::Action::create("Share",
817                                   Gtk::Stock::CONNECT, "Share whiteboard"),
818     sigc::mem_fun(*this, &UserList::shareCallback) );
821     uiManager = Gtk::UIManager::create();
823     uiManager->insert_action_group(actionGroup, 0);
825     Glib::ustring ui_info =
826         "<ui>"
827         "  <popup name='PopupMenu'>"
828         "    <menuitem action='Chat'/>"
829         "    <menuitem action='SendFile'/>"
830         "    <menuitem action='Share'/>"
831         "  </popup>"
832         "</ui>";
834     uiManager->add_ui_from_string(ui_info);
836     show_all_children();
838     return true;
841 /**
842  * Clear all messages from the list
843  */
844 void UserList::clear()
846     userListStore->clear();
850 /**
851  * Add a user to the list
852  */
853 void UserList::addUser(const DOMString &user, const DOMString &show)
855     Glib::RefPtr<Gdk::Pixbuf> pb = pixbuf_offline;
856     if (show == "available")
857         pb = pixbuf_available;
858     else if (show == "away")
859         pb = pixbuf_away;
860     else if (show == "chat")
861         pb = pixbuf_chat;
862     else if (show == "dnd")
863         pb = pixbuf_dnd;
864     else if (show == "xa")
865         pb = pixbuf_xa;
866     else
867         {
868         //printf("Unknown show for %s:'%s'\n", user.c_str(), show.c_str());
869         }
870     Gtk::TreeModel::Row row = *(userListStore->append());
871     row[userListColumns.userColumn]   = user;
872     row[userListColumns.statusColumn] = pb;
878 //#########################################################################
879 //# C H A T    W I N D O W
880 //#########################################################################
881 ChatWindow::ChatWindow(PedroGui &par, const DOMString jidArg)
882                         : parent(par)
884     jid = jidArg;
885     doSetup();
888 ChatWindow::~ChatWindow()
892 void ChatWindow::leaveCallback()
894     hide();
895     parent.chatDelete(jid);
899 void ChatWindow::hideCallback()
901     hide();
902     parent.chatDelete(jid);
905 void ChatWindow::shareCallback()
907 //    hide();
908     parent.doShare(this->jid);
911 void ChatWindow::textEnterCallback()
913     DOMString str = inputTxt.get_text();
914     if (str.size() > 0)
915         parent.client.message(jid, str);
916     inputTxt.set_text("");
917     messageList.postMessage(parent.client.getJid(), str);
920 bool ChatWindow::doSetup()
922     DOMString title = "Private Chat - ";
923     title.append(jid);
924     set_title(title);
926     set_size_request(500,300);
928     signal_hide().connect(
929            sigc::mem_fun(*this, &ChatWindow::hideCallback) );
931     Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
932     actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
933     actionGroup->add( Gtk::Action::create("Leave",  Gtk::Stock::CANCEL),
934         sigc::mem_fun(*this, &ChatWindow::leaveCallback) );
935     actionGroup->add( Gtk::Action::create("Share",  Gtk::Stock::CONNECT,
936         "Share whiteboard"), sigc::mem_fun(*this, &ChatWindow::shareCallback) );
939     Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
941     uiManager->insert_action_group(actionGroup, 0);
942     add_accel_group(uiManager->get_accel_group());
944     Glib::ustring ui_info =
945         "<ui>"
946         "  <menubar name='MenuBar'>"
947         "    <menu action='MenuFile'>"
948         "      <menuitem action='Leave'/>"
949         "      <menuitem action='Share'/>"
950         "    </menu>"
951         "  </menubar>"
952         "</ui>";
954     add(vbox);
956     uiManager->add_ui_from_string(ui_info);
957     Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
958     vbox.pack_start(*pMenuBar, Gtk::PACK_SHRINK);
960     vbox.pack_end(vPaned);
962     vPaned.add1(messageList);
963     vPaned.add2(inputTxt);
965     inputTxt.signal_activate().connect(
966            sigc::mem_fun(*this, &ChatWindow::textEnterCallback) );
968     show_all_children();
970     return true;
973 bool ChatWindow::postMessage(const DOMString &data)
975     messageList.postMessage(jid, data);
976     return true;
979 //#########################################################################
980 //# G R O U P    C H A T    W I N D O W
981 //#########################################################################
983 GroupChatWindow::GroupChatWindow(PedroGui &par,
984                                  const DOMString &groupJidArg,
985                                  const DOMString &nickArg)
986                                : parent(par)
988     groupJid = groupJidArg;
989     nick     = nickArg;
990     doSetup();
993 GroupChatWindow::~GroupChatWindow()
998 void GroupChatWindow::leaveCallback()
1000     parent.client.groupChatLeave(groupJid, nick);
1001     hide();
1002     parent.groupChatDelete(groupJid, nick);
1005 void GroupChatWindow::hideCallback()
1007     parent.client.groupChatLeave(groupJid, nick);
1008     hide();
1009     parent.groupChatDelete(groupJid, nick);
1012 void GroupChatWindow::textEnterCallback()
1014     DOMString str = inputTxt.get_text();
1015     if (str.size() > 0)
1016         parent.client.groupChatMessage(groupJid, str);
1017     inputTxt.set_text("");
1020 void GroupChatWindow::shareCallback()
1022     parent.doGroupShare(groupJid);
1025 bool GroupChatWindow::doSetup()
1027     DOMString title = "Group Chat - ";
1028     title.append(groupJid);
1029     set_title(title);
1031     userList.setParent(this);
1033     set_size_request(500,300);
1035     signal_hide().connect(
1036            sigc::mem_fun(*this, &GroupChatWindow::hideCallback) );
1038     Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1039     actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1040     actionGroup->add( Gtk::Action::create("Leave",  Gtk::Stock::CANCEL),
1041         sigc::mem_fun(*this, &GroupChatWindow::leaveCallback) );
1042     actionGroup->add( Gtk::Action::create("Share",  Gtk::Stock::CONNECT, "Share whiteboard"),
1043         sigc::mem_fun(*this, &GroupChatWindow::shareCallback) );
1046     Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1048     uiManager->insert_action_group(actionGroup, 0);
1049     add_accel_group(uiManager->get_accel_group());
1051     Glib::ustring ui_info =
1052         "<ui>"
1053         "  <menubar name='MenuBar'>"
1054         "    <menu action='MenuFile'>"
1055         "      <menuitem action='Leave'/>"
1056         "      <menuitem action='Share'/>"
1057         "    </menu>"
1058         "  </menubar>"
1059         "</ui>";
1061     add(vbox);
1062     uiManager->add_ui_from_string(ui_info);
1063     Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1064     vbox.pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1066     vbox.pack_end(vPaned);
1068     vPaned.add1(hPaned);
1069     vPaned.add2(inputTxt);
1070     inputTxt.signal_activate().connect(
1071            sigc::mem_fun(*this, &GroupChatWindow::textEnterCallback) );
1074     hPaned.add1(messageList);
1075     hPaned.add2(userList);
1078     show_all_children();
1081     return true;
1084 bool GroupChatWindow::receiveMessage(const DOMString &from,
1085                                      const DOMString &data)
1087     messageList.postMessage(from, data);
1088     return true;
1091 bool GroupChatWindow::receivePresence(const DOMString &fromNick,
1092                                       bool presence,
1093                                       const DOMString &show,
1094                                       const DOMString &status)
1097     DOMString presStr = "";
1098     presStr.append(fromNick);
1099     if (!presence)
1100         presStr.append(" left the group");
1101     else
1102         {
1103         if (show.size()<1)
1104             presStr.append(" joined the group");
1105         else
1106             {
1107             presStr.append(" : ");
1108             presStr.append(show);
1109             }
1110         }
1112     if (presStr != "xa")
1113         messageList.postMessage("*", presStr);
1115     userList.clear();
1116     std::vector<XmppUser> memberList =
1117          parent.client.groupChatGetUserList(groupJid);
1118     for (unsigned int i=0 ; i<memberList.size() ; i++)
1119         {
1120         XmppUser user = memberList[i];
1121         userList.addUser(user.nick, user.show);
1122         }
1123     return true;
1127 void GroupChatWindow::doChat(const DOMString &nick)
1129     printf("##Chat with %s\n", nick.c_str());
1130     DOMString fullJid = groupJid;
1131     fullJid.append("/");
1132     fullJid.append(nick);
1133     parent.doChat(fullJid);
1136 void GroupChatWindow::doSendFile(const DOMString &nick)
1138     printf("##Send file to %s\n", nick.c_str());
1139     DOMString fullJid = groupJid;
1140     fullJid.append("/");
1141     fullJid.append(nick);
1142     parent.doSendFile(fullJid);
1146 void GroupChatWindow::doShare(const DOMString &nick)
1148     printf("##Share inkboard with %s\n", nick.c_str());
1149     DOMString fullJid = groupJid;
1150     fullJid.append("/");
1151     fullJid.append(nick);
1152     parent.doShare(fullJid);
1157 //#########################################################################
1158 //# C O N F I G    D I A L O G
1159 //#########################################################################
1162 void ConfigDialog::okCallback()
1164     Glib::ustring pass     = passField.get_text();
1165     Glib::ustring newpass  = newField.get_text();
1166     Glib::ustring confpass = confField.get_text();
1167     if ((pass.size()     < 5 || pass.size()    > 12 ) ||
1168         (newpass.size()  < 5 || newpass.size() > 12 ) ||
1169         (confpass.size() < 5 || confpass.size()> 12 ))
1170         {
1171         Gtk::MessageDialog dlg(*this, "Password must be 5 to 12 characters",
1172             false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
1173         dlg.run();
1174         }
1175     else if (newpass != confpass)
1176         {
1177         Gtk::MessageDialog dlg(*this, "New password and confirmation do not match",
1178             false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
1179         dlg.run();
1180         }
1181     else
1182         {
1183         //response(Gtk::RESPONSE_OK);
1184         hide();
1185         }
1188 void ConfigDialog::cancelCallback()
1190     //response(Gtk::RESPONSE_CANCEL);
1191     hide();
1194 void ConfigDialog::on_response(int response_id)
1196     if (response_id == Gtk::RESPONSE_OK)
1197         okCallback();
1198     else
1199         cancelCallback();
1202 bool ConfigDialog::doSetup()
1204     set_title("Change Password");
1205     set_size_request(300,200);
1207     Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1208     actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1209     actionGroup->add( Gtk::Action::create("Change", Gtk::Stock::OK, "Change Password"),
1210         sigc::mem_fun(*this, &ConfigDialog::okCallback) );
1211     actionGroup->add( Gtk::Action::create("Cancel",  Gtk::Stock::CANCEL, "Cancel"),
1212          sigc::mem_fun(*this, &ConfigDialog::cancelCallback) );
1215     Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1217     uiManager->insert_action_group(actionGroup, 0);
1218     add_accel_group(uiManager->get_accel_group());
1220     Glib::ustring ui_info =
1221         "<ui>"
1222         "  <menubar name='MenuBar'>"
1223         "    <menu action='MenuFile'>"
1224         "      <menuitem action='Change'/>"
1225         "      <separator/>"
1226         "      <menuitem action='Cancel'/>"
1227         "    </menu>"
1228         "  </menubar>"
1229         "</ui>";
1231     uiManager->add_ui_from_string(ui_info);
1232     Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1233     get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1235     table.resize(3, 2);
1236     get_vbox()->pack_start(table);
1238     passLabel.set_text("Current Password");
1239     table.attach(passLabel, 0, 1, 0, 1);
1240     passField.set_visibility(false);
1241     passField.set_text(parent.client.getPassword());
1242     table.attach(passField, 1, 2, 0, 1);
1244     newLabel.set_text("New Password");
1245     table.attach(newLabel, 0, 1, 1, 2);
1246     newField.set_visibility(false);
1247     table.attach(newField, 1, 2, 1, 2);
1249     confLabel.set_text("Confirm New Password");
1250     table.attach(confLabel, 0, 1, 2, 3);
1251     confField.set_visibility(false);
1252     confField.signal_activate().connect(
1253            sigc::mem_fun(*this, &ConfigDialog::okCallback) );
1254     table.attach(confField, 1, 2, 2, 3);
1256     add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1257     add_button(Gtk::Stock::OK,     Gtk::RESPONSE_OK);
1259     show_all_children();
1261     return true;
1264 //#########################################################################
1265 //# P A S S W O R D      D I A L O G
1266 //#########################################################################
1269 void PasswordDialog::okCallback()
1271     Glib::ustring pass     = passField.get_text();
1272     Glib::ustring newpass  = newField.get_text();
1273     Glib::ustring confpass = confField.get_text();
1274     if ((pass.size()     < 5 || pass.size()    > 12 ) ||
1275         (newpass.size()  < 5 || newpass.size() > 12 ) ||
1276         (confpass.size() < 5 || confpass.size()> 12 ))
1277         {
1278         Gtk::MessageDialog dlg(*this, "Password must be 5 to 12 characters",
1279             false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
1280         dlg.run();
1281         }
1282     else if (newpass != confpass)
1283         {
1284         Gtk::MessageDialog dlg(*this, "New password and confirmation do not match",
1285             false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
1286         dlg.run();
1287         }
1288     else
1289         {
1290         //response(Gtk::RESPONSE_OK);
1291         hide();
1292         }
1295 void PasswordDialog::cancelCallback()
1297     //response(Gtk::RESPONSE_CANCEL);
1298     hide();
1301 void PasswordDialog::on_response(int response_id)
1303     if (response_id == Gtk::RESPONSE_OK)
1304         okCallback();
1305     else
1306         cancelCallback();
1309 bool PasswordDialog::doSetup()
1311     set_title("Change Password");
1312     set_size_request(300,200);
1314     Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1315     actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1316     actionGroup->add( Gtk::Action::create("Change", Gtk::Stock::OK, "Change Password"),
1317         sigc::mem_fun(*this, &PasswordDialog::okCallback) );
1318     actionGroup->add( Gtk::Action::create("Cancel",  Gtk::Stock::CANCEL, "Cancel"),
1319         sigc::mem_fun(*this, &PasswordDialog::cancelCallback) );
1322     Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1324     uiManager->insert_action_group(actionGroup, 0);
1325     add_accel_group(uiManager->get_accel_group());
1327     Glib::ustring ui_info =
1328         "<ui>"
1329         "  <menubar name='MenuBar'>"
1330         "    <menu action='MenuFile'>"
1331         "      <menuitem action='Change'/>"
1332         "      <separator/>"
1333         "      <menuitem action='Cancel'/>"
1334         "    </menu>"
1335         "  </menubar>"
1336         "</ui>";
1338     uiManager->add_ui_from_string(ui_info);
1339     Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1340     get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1342     table.resize(3, 2);
1343     get_vbox()->pack_start(table);
1345     passLabel.set_text("Current Password");
1346     table.attach(passLabel, 0, 1, 0, 1);
1347     passField.set_visibility(false);
1348     passField.set_text(parent.client.getPassword());
1349     table.attach(passField, 1, 2, 0, 1);
1351     newLabel.set_text("New Password");
1352     table.attach(newLabel, 0, 1, 1, 2);
1353     newField.set_visibility(false);
1354     table.attach(newField, 1, 2, 1, 2);
1356     confLabel.set_text("Confirm New Password");
1357     table.attach(confLabel, 0, 1, 2, 3);
1358     confField.set_visibility(false);
1359     confField.signal_activate().connect(
1360            sigc::mem_fun(*this, &PasswordDialog::okCallback) );
1361     table.attach(confField, 1, 2, 2, 3);
1363     add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1364     add_button(Gtk::Stock::OK,     Gtk::RESPONSE_OK);
1366     show_all_children();
1368     return true;
1371 //#########################################################################
1372 //# C H A T    D I A L O G
1373 //#########################################################################
1376 void ChatDialog::okCallback()
1378     response(Gtk::RESPONSE_OK);
1379     hide();
1382 void ChatDialog::cancelCallback()
1384     response(Gtk::RESPONSE_CANCEL);
1385     hide();
1389 bool ChatDialog::doSetup()
1391     set_title("Chat with User");
1392     set_size_request(300,200);
1394     Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1395     actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1396     actionGroup->add( Gtk::Action::create("Chat", Gtk::Stock::CONNECT, "Chat"),
1397     sigc::mem_fun(*this, &ChatDialog::okCallback) );
1398     actionGroup->add( Gtk::Action::create("Cancel",  Gtk::Stock::CANCEL, "Cancel"),
1399     sigc::mem_fun(*this, &ChatDialog::cancelCallback) );
1402     Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1404     uiManager->insert_action_group(actionGroup, 0);
1405     add_accel_group(uiManager->get_accel_group());
1407     Glib::ustring ui_info =
1408         "<ui>"
1409         "  <menubar name='MenuBar'>"
1410         "    <menu action='MenuFile'>"
1411         "      <menuitem action='Chat'/>"
1412         "      <separator/>"
1413         "      <menuitem action='Cancel'/>"
1414         "    </menu>"
1415         "  </menubar>"
1416         "</ui>";
1418     uiManager->add_ui_from_string(ui_info);
1419     Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1420     get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1422     table.resize(2, 2);
1423     get_vbox()->pack_start(table);
1425     userLabel.set_text("User");
1426     table.attach(userLabel, 0, 1, 0, 1);
1427     //userField.set_text("");
1428     table.attach(userField, 1, 2, 0, 1);
1430     //userField.set_text("");
1431     table.attach(textField, 0, 2, 1, 2);
1433     add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1434     add_button(Gtk::Stock::OPEN,   Gtk::RESPONSE_OK);
1436     show_all_children();
1438     return true;
1441 //#########################################################################
1442 //# G R O U P    C H A T   D I A L O G
1443 //#########################################################################
1446 void GroupChatDialog::okCallback()
1448     response(Gtk::RESPONSE_OK);
1449     hide();
1452 void GroupChatDialog::cancelCallback()
1454     response(Gtk::RESPONSE_CANCEL);
1455     hide();
1459 bool GroupChatDialog::doSetup()
1461     set_title("Join Group Chat");
1462     set_size_request(300,200);
1464     Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1465     actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1466     actionGroup->add( Gtk::Action::create("Join", Gtk::Stock::CONNECT, "Join Group"),
1467     sigc::mem_fun(*this, &GroupChatDialog::okCallback) );
1468     actionGroup->add( Gtk::Action::create("Cancel",  Gtk::Stock::CANCEL, "Cancel"),
1469     sigc::mem_fun(*this, &GroupChatDialog::cancelCallback) );
1472     Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1474     uiManager->insert_action_group(actionGroup, 0);
1475     add_accel_group(uiManager->get_accel_group());
1477     Glib::ustring ui_info =
1478         "<ui>"
1479         "  <menubar name='MenuBar'>"
1480         "    <menu action='MenuFile'>"
1481         "      <menuitem action='Join'/>"
1482         "      <separator/>"
1483         "      <menuitem action='Cancel'/>"
1484         "    </menu>"
1485         "  </menubar>"
1486         "</ui>";
1488     uiManager->add_ui_from_string(ui_info);
1489     Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1490     get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1492     table.resize(4, 2);
1493     get_vbox()->pack_start(table);
1495     groupLabel.set_text("Group");
1496     table.attach(groupLabel, 0, 1, 0, 1);
1497     groupField.set_text(parent.config.getMucGroup());
1498     table.attach(groupField, 1, 2, 0, 1);
1500     hostLabel.set_text("Host");
1501     table.attach(hostLabel, 0, 1, 1, 2);
1502     hostField.set_text(parent.config.getMucHost());
1503     table.attach(hostField, 1, 2, 1, 2);
1505     nickLabel.set_text("Alt Name");
1506     table.attach(nickLabel, 0, 1, 2, 3);
1507     nickField.set_text(parent.config.getMucNick());
1508     table.attach(nickField, 1, 2, 2, 3);
1510     passLabel.set_text("Password");
1511     table.attach(passLabel, 0, 1, 3, 4);
1512     passField.set_visibility(false);
1513     passField.set_text(parent.config.getMucPassword());
1514     table.attach(passField, 1, 2, 3, 4);
1517     add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1518     add_button(Gtk::Stock::OPEN,   Gtk::RESPONSE_OK);
1520     show_all_children();
1522     return true;
1528 //#########################################################################
1529 //# C O N N E C T    D I A L O G
1530 //#########################################################################
1533 void ConnectDialog::okCallback()
1535     response(Gtk::RESPONSE_OK);
1536     hide();
1539 void ConnectDialog::saveCallback()
1541     Gtk::Entry txtField;
1542     Gtk::Dialog dlg("Account name", *this, true, true);
1543     dlg.get_vbox()->pack_start(txtField);
1544     txtField.signal_activate().connect(
1545            sigc::bind(sigc::mem_fun(dlg, &Gtk::Dialog::response),
1546               Gtk::RESPONSE_OK  ));
1547     dlg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1548     dlg.add_button(Gtk::Stock::OK,     Gtk::RESPONSE_OK);
1549     dlg.show_all_children();
1550     int ret = dlg.run();
1551     if (ret != Gtk::RESPONSE_OK)
1552         return;
1554     Glib::ustring name = txtField.get_text();
1555     if (name.size() < 1)
1556         {
1557         parent.error("Account name too short");
1558         return;
1559         }
1561     if (parent.config.accountExists(name))
1562         {
1563         parent.config.accountRemove(name);          
1564         }
1566     XmppAccount account;
1567     account.setName(name);
1568     account.setHost(getHost());
1569     account.setPort(getPort());
1570     account.setUsername(getUser());
1571     account.setPassword(getPass());
1572     parent.config.accountAdd(account);
1574     refresh();
1576     parent.configSave();
1579 void ConnectDialog::cancelCallback()
1581     response(Gtk::RESPONSE_CANCEL);
1582     hide();
1586 void ConnectDialog::doubleClickCallback(
1587                    const Gtk::TreeModel::Path &path,
1588                    Gtk::TreeViewColumn *col)
1590     Glib::RefPtr<Gtk::TreeModel> model = accountView.get_model();
1591     Glib::RefPtr<Gtk::TreeSelection> sel = accountView.get_selection();
1592     Gtk::TreeModel::iterator iter = sel->get_selected();
1593     DOMString name = iter->get_value(accountColumns.nameColumn);
1594     //printf("Double clicked:%s\n", name.c_str());
1595     XmppAccount account;
1596     if (!parent.config.accountFind(name, account))
1597         return;
1598     setHost(account.getHost()); 
1599     setPort(account.getPort()); 
1600     setUser(account.getUsername()); 
1601     setPass(account.getPassword()); 
1603     response(Gtk::RESPONSE_OK);
1604     hide();
1607 void ConnectDialog::selectedCallback()
1609     Glib::RefPtr<Gtk::TreeModel> model = accountView.get_model();
1610     Glib::RefPtr<Gtk::TreeSelection> sel = accountView.get_selection();
1611     Gtk::TreeModel::iterator iter = sel->get_selected();
1612     DOMString name = iter->get_value(accountColumns.nameColumn);
1613     //printf("Single clicked:%s\n", name.c_str());
1614     XmppAccount account;
1615     if (!parent.config.accountFind(name, account))
1616         return;
1617     setHost(account.getHost()); 
1618     setPort(account.getPort()); 
1619     setUser(account.getUsername()); 
1620     setPass(account.getPassword()); 
1623 void ConnectDialog::deleteCallback()
1625     Glib::RefPtr<Gtk::TreeModel> model = accountView.get_model();
1626     Glib::RefPtr<Gtk::TreeSelection> sel = accountView.get_selection();
1627     Gtk::TreeModel::iterator iter = sel->get_selected();
1628     DOMString name = iter->get_value(accountColumns.nameColumn);
1630     parent.config.accountRemove(name);
1631     refresh();
1632     parent.configSave();
1633     
1638 void ConnectDialog::buttonPressCallback(GdkEventButton* event)
1640     if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) )
1641         {
1642         Gtk::Widget *wid = accountUiManager->get_widget("/PopupMenu");
1643         Gtk::Menu *popupMenu = dynamic_cast<Gtk::Menu*>(wid);
1644         popupMenu->popup(event->button, event->time);
1645         }
1649 bool ConnectDialog::doSetup()
1651     set_title("Connect");
1652     set_size_request(300,400);
1654     Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1655     actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1656     actionGroup->add( Gtk::Action::create("Connect",
1657         Gtk::Stock::CONNECT, "Connect"),
1658         sigc::mem_fun(*this, &ConnectDialog::okCallback) );
1659     actionGroup->add( Gtk::Action::create("Save",
1660         Gtk::Stock::CONNECT, "Save as account"),
1661         sigc::mem_fun(*this, &ConnectDialog::saveCallback) );
1662     actionGroup->add( Gtk::Action::create("Cancel",
1663         Gtk::Stock::CANCEL, "Cancel"),
1664         sigc::mem_fun(*this, &ConnectDialog::cancelCallback) );
1667     Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1669     uiManager->insert_action_group(actionGroup, 0);
1670     add_accel_group(uiManager->get_accel_group());
1672     Glib::ustring ui_info =
1673         "<ui>"
1674         "  <menubar name='MenuBar'>"
1675         "    <menu action='MenuFile'>"
1676         "      <menuitem action='Connect'/>"
1677         "      <separator/>"
1678         "      <menuitem action='Save'/>"
1679         "      <separator/>"
1680         "      <menuitem action='Cancel'/>"
1681         "    </menu>"
1682         "  </menubar>"
1683         "</ui>";
1685     uiManager->add_ui_from_string(ui_info);
1686     Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1687     get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1689     table.resize(6, 2);
1690     get_vbox()->pack_start(table);
1692     parent.client.setHost("broadway.dynalias.com");
1693     parent.client.setPort(5222);
1694     parent.client.setUsername("");
1695     parent.client.setPassword("");
1696     parent.client.setResource("pedroXmpp");
1698     hostLabel.set_text("Host");
1699     table.attach(hostLabel, 0, 1, 0, 1);
1700     hostField.set_text(parent.client.getHost());
1701     table.attach(hostField, 1, 2, 0, 1);
1703     portLabel.set_text("Port");
1704     table.attach(portLabel, 0, 1, 1, 2);
1705     portSpinner.set_digits(0);
1706     portSpinner.set_range(1, 65000);
1707     portSpinner.set_value(parent.client.getPort());
1708     table.attach(portSpinner, 1, 2, 1, 2);
1710     userLabel.set_text("Username");
1711     table.attach(userLabel, 0, 1, 2, 3);
1712     userField.set_text(parent.client.getUsername());
1713     table.attach(userField, 1, 2, 2, 3);
1715     passLabel.set_text("Password");
1716     table.attach(passLabel, 0, 1, 3, 4);
1717     passField.set_visibility(false);
1718     passField.set_text(parent.client.getPassword());
1719     passField.signal_activate().connect(
1720            sigc::mem_fun(*this, &ConnectDialog::okCallback) );
1721     table.attach(passField, 1, 2, 3, 4);
1723     resourceLabel.set_text("Resource");
1724     table.attach(resourceLabel, 0, 1, 4, 5);
1725     resourceField.set_text(parent.client.getResource());
1726     table.attach(resourceField, 1, 2, 4, 5);
1728     registerLabel.set_text("Register");
1729     table.attach(registerLabel, 0, 1, 5, 6);
1730     registerButton.set_active(false);
1731     table.attach(registerButton, 1, 2, 5, 6);
1733     add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1734     add_button(Gtk::Stock::OPEN,   Gtk::RESPONSE_OK);
1737     //######################
1738     //# ACCOUNT LIST
1739     //######################
1742     accountListStore = Gtk::ListStore::create(accountColumns);
1743     accountView.set_model(accountListStore);
1745     accountView.signal_row_activated().connect(
1746         sigc::mem_fun(*this, &ConnectDialog::doubleClickCallback) );
1748     accountView.get_selection()->signal_changed().connect(
1749         sigc::mem_fun(*this, &ConnectDialog::selectedCallback) );
1751     accountView.append_column("Account", accountColumns.nameColumn);
1752     accountView.append_column("Host",    accountColumns.hostColumn);
1754     //accountView.signal_row_activated().connect(
1755     //    sigc::mem_fun(*this, &AccountDialog::connectCallback) );
1757     accountScroll.add(accountView);
1758     accountScroll.set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
1760     get_vbox()->pack_start(accountScroll);
1762     //##### POPUP MENU
1763     accountView.signal_button_press_event().connect_notify(
1764         sigc::mem_fun(*this, &ConnectDialog::buttonPressCallback) );
1766     Glib::RefPtr<Gtk::ActionGroup> accountActionGroup =
1767                 Gtk::ActionGroup::create();
1769     accountActionGroup->add( Gtk::Action::create("PopupMenu", "_Account") );
1771     accountActionGroup->add( Gtk::Action::create("Delete",
1772                                   Gtk::Stock::DELETE, "Delete"),
1773         sigc::mem_fun(*this, &ConnectDialog::deleteCallback) );
1776     accountUiManager = Gtk::UIManager::create();
1778     accountUiManager->insert_action_group(accountActionGroup, 0);
1780     Glib::ustring account_ui_info =
1781         "<ui>"
1782         "  <popup name='PopupMenu'>"
1783         "    <menuitem action='Delete'/>"
1784         "  </popup>"
1785         "</ui>";
1787     accountUiManager->add_ui_from_string(account_ui_info);
1788     //Gtk::Widget* accountMenuBar = uiManager->get_widget("/PopupMenu");
1789     //get_vbox()->pack_start(*accountMenuBar, Gtk::PACK_SHRINK);
1791     refresh();
1793     show_all_children();
1795     return true;
1799 /**
1800  * Regenerate the account list
1801  */
1802 void ConnectDialog::refresh()
1804     accountListStore->clear();
1806     std::vector<XmppAccount> accounts = parent.config.getAccounts();
1807     for (unsigned int i=0 ; i<accounts.size() ; i++)
1808         {
1809         XmppAccount account = accounts[i];
1810         Gtk::TreeModel::Row row = *(accountListStore->append());
1811         row[accountColumns.nameColumn] = account.getName();
1812         row[accountColumns.hostColumn] = account.getHost();
1813         }
1814     accountView.expand_all();
1819 //#########################################################################
1820 //# F I L E    S E N D    D I A L O G
1821 //#########################################################################
1824 void FileSendDialog::okCallback()
1826     response(Gtk::RESPONSE_OK);
1827     hide();
1830 void FileSendDialog::cancelCallback()
1832     response(Gtk::RESPONSE_CANCEL);
1833     hide();
1837 void FileSendDialog::buttonCallback()
1839     Gtk::FileChooserDialog dlg("Select a file to send",
1840                       Gtk::FILE_CHOOSER_ACTION_OPEN);
1841     dlg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1842     dlg.add_button(Gtk::Stock::OPEN,   Gtk::RESPONSE_OK);
1843     int ret = dlg.run();
1844     if (ret == Gtk::RESPONSE_OK || ret == Gtk::RESPONSE_ACCEPT)
1845         {
1846         fileName = dlg.get_filename();
1847         fileNameField.set_text(fileName);
1848         }
1851 bool FileSendDialog::doSetup()
1853     set_title("Send file to user");
1854     set_size_request(400,150);
1856     Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1857     actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1858     actionGroup->add( Gtk::Action::create("Send", Gtk::Stock::NETWORK, "Send File"),
1859         sigc::mem_fun(*this, &FileSendDialog::okCallback) );
1860     actionGroup->add( Gtk::Action::create("Cancel",  Gtk::Stock::CANCEL, "Cancel"),
1861         sigc::mem_fun(*this, &FileSendDialog::cancelCallback) );
1864     Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1866     uiManager->insert_action_group(actionGroup, 0);
1867     add_accel_group(uiManager->get_accel_group());
1869     Glib::ustring ui_info =
1870         "<ui>"
1871         "  <menubar name='MenuBar'>"
1872         "    <menu action='MenuFile'>"
1873         "      <menuitem action='Send'/>"
1874         "      <separator/>"
1875         "      <menuitem action='Cancel'/>"
1876         "    </menu>"
1877         "  </menubar>"
1878         "</ui>";
1880     uiManager->add_ui_from_string(ui_info);
1881     Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1882     get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1884     table.resize(2, 2);
1885     get_vbox()->pack_start(table);
1887     jidLabel.set_text("User ID");
1888     table.attach(jidLabel, 0, 1, 0, 1);
1889     jidField.set_text("inkscape");
1890     table.attach(jidField, 1, 2, 0, 1);
1892     selectFileButton.set_label("Select");
1893     selectFileButton.signal_clicked().connect(
1894            sigc::mem_fun(*this, &FileSendDialog::buttonCallback) );
1895     table.attach(selectFileButton, 0, 1, 1, 2);
1897     fileName = "";
1898     fileNameField.set_text("No file selected");
1899     fileNameField.set_editable(false);
1900     table.attach(fileNameField, 1, 2, 1, 2);
1902     add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1903     add_button(Gtk::Stock::OPEN,   Gtk::RESPONSE_OK);
1905     show_all_children();
1907     return true;
1911 //#########################################################################
1912 //# F I L E    R E C E I V E   D I A L O G
1913 //#########################################################################
1916 void FileReceiveDialog::okCallback()
1918     response(Gtk::RESPONSE_OK);
1919     hide();
1922 void FileReceiveDialog::cancelCallback()
1924     response(Gtk::RESPONSE_CANCEL);
1925     hide();
1928 void FileReceiveDialog::buttonCallback()
1930     Gtk::FileChooserDialog dlg("Select a file to save",
1931                       Gtk::FILE_CHOOSER_ACTION_SAVE);
1932     dlg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1933     dlg.add_button(Gtk::Stock::OPEN,   Gtk::RESPONSE_OK);
1934     int ret = dlg.run();
1935     if (ret == Gtk::RESPONSE_OK || ret == Gtk::RESPONSE_ACCEPT)
1936         {
1937         fileName = dlg.get_filename();
1938         fileNameField.set_text(fileName);
1939         }
1943 bool FileReceiveDialog::doSetup()
1945     set_title("File being sent by user");
1946     set_size_request(450,250);
1948     Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
1949     actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
1950     actionGroup->add( Gtk::Action::create("Send", Gtk::Stock::NETWORK, "Send File"),
1951         sigc::mem_fun(*this, &FileReceiveDialog::okCallback) );
1952     actionGroup->add( Gtk::Action::create("Cancel",  Gtk::Stock::CANCEL, "Cancel"),
1953         sigc::mem_fun(*this, &FileReceiveDialog::cancelCallback) );
1956     Glib::RefPtr<Gtk::UIManager> uiManager = Gtk::UIManager::create();
1958     uiManager->insert_action_group(actionGroup, 0);
1959     add_accel_group(uiManager->get_accel_group());
1961     Glib::ustring ui_info =
1962         "<ui>"
1963         "  <menubar name='MenuBar'>"
1964         "    <menu action='MenuFile'>"
1965         "      <menuitem action='Send'/>"
1966         "      <separator/>"
1967         "      <menuitem action='Cancel'/>"
1968         "    </menu>"
1969         "  </menubar>"
1970         "</ui>";
1972     uiManager->add_ui_from_string(ui_info);
1973     Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
1974     get_vbox()->pack_start(*pMenuBar, Gtk::PACK_SHRINK);
1976     table.resize(6, 2);
1977     get_vbox()->pack_start(table);
1979     jidLabel.set_text("User ID");
1980     table.attach(jidLabel, 0, 1, 0, 1);
1981     jidField.set_text(jid);
1982     jidField.set_editable(false);
1983     table.attach(jidField, 1, 2, 0, 1);
1985     offeredLabel.set_text("File Offered");
1986     table.attach(offeredLabel, 0, 1, 1, 2);
1987     offeredField.set_text(offeredName);
1988     offeredField.set_editable(false);
1989     table.attach(offeredField, 1, 2, 1, 2);
1991     descLabel.set_text("Description");
1992     table.attach(descLabel, 0, 1, 2, 3);
1993     descField.set_text(desc);
1994     descField.set_editable(false);
1995     table.attach(descField, 1, 2, 2, 3);
1997     char buf[32];
1998     snprintf(buf, 31, "%ld", fileSize);
1999     sizeLabel.set_text("Size");
2000     table.attach(sizeLabel, 0, 1, 3, 4);
2001     sizeField.set_text(buf);
2002     sizeField.set_editable(false);
2003     table.attach(sizeField, 1, 2, 3, 4);
2005     hashLabel.set_text("MD5 Hash");
2006     table.attach(hashLabel, 0, 1, 4, 5);
2007     hashField.set_text(hash);
2008     hashField.set_editable(false);
2009     table.attach(hashField, 1, 2, 4, 5);
2011     selectFileButton.set_label("Select");
2012     selectFileButton.signal_clicked().connect(
2013            sigc::mem_fun(*this, &FileReceiveDialog::buttonCallback) );
2014     table.attach(selectFileButton, 0, 1, 5, 6);
2016     fileName = "";
2017     fileNameField.set_text("No file selected");
2018     fileNameField.set_editable(false);
2019     table.attach(fileNameField, 1, 2, 5, 6);
2022     add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
2023     add_button(Gtk::Stock::OPEN,   Gtk::RESPONSE_OK);
2025     show_all_children();
2027     return true;
2031 //#########################################################################
2032 //# M A I N    W I N D O W
2033 //#########################################################################
2035 PedroGui::PedroGui()
2037     doSetup();
2040 PedroGui::~PedroGui()
2042     chatDeleteAll();
2043     groupChatDeleteAll();
2047 void PedroGui::error(const char *fmt, ...)
2049     va_list args;
2050     va_start(args, fmt);
2051     vsnprintf(writeBuf, writeBufLen, fmt, args);
2052     va_end(args) ;
2054     Gtk::MessageDialog dlg(writeBuf,
2055                            false,
2056                            Gtk::MESSAGE_ERROR,
2057                            Gtk::BUTTONS_OK,
2058                            true);
2059     dlg.run();
2062 void PedroGui::status(const char *fmt, ...)
2064     va_list args;
2065     va_start(args, fmt);
2066     vsnprintf(writeBuf, writeBufLen, fmt, args);
2067     va_end(args) ;
2068     messageList.postMessage("STATUS", writeBuf);
2071 //################################
2072 //# CHAT WINDOW MANAGEMENT
2073 //################################
2074 bool PedroGui::chatCreate(const DOMString &userJid)
2076     std::vector<ChatWindow *>::iterator iter;
2077     for (iter=chats.begin() ; iter != chats.end() ; iter++)
2078         {
2079         if (userJid == (*iter)->getJid())
2080             return false;
2081         }
2082     ChatWindow *chat = new ChatWindow(*this, userJid);
2083     chat->show();
2084     chats.push_back(chat);
2085     return true;
2088 bool PedroGui::chatDelete(const DOMString &userJid)
2090     std::vector<ChatWindow *>::iterator iter;
2091     for (iter=chats.begin() ; iter != chats.end() ; )
2092         {
2093         if (userJid == (*iter)->getJid())
2094             {
2095             delete(*iter);
2096             iter = chats.erase(iter);
2097             }
2098         else
2099             iter++;
2100         }
2101     return true;
2104 bool PedroGui::chatDeleteAll()
2106     std::vector<ChatWindow *>::iterator iter;
2107     for (iter=chats.begin() ; iter != chats.end() ; )
2108         {
2109         delete(*iter);
2110         iter = chats.erase(iter);
2111         }
2112     return true;
2115 bool PedroGui::chatMessage(const DOMString &from, const DOMString &data)
2117     if(data.size() < 1)
2118     {
2119         std::vector<ChatWindow *>::iterator iter;
2120         for (iter=chats.begin() ; iter != chats.end() ; iter++)
2121             {
2122             if (from == (*iter)->getJid())
2123                 {
2124                 (*iter)->postMessage(data);
2125                 return true;
2126                 }
2127             }
2128         ChatWindow *chat = new ChatWindow(*this, from);
2129         chat->show();
2130         chats.push_back(chat);
2131         chat->postMessage(data);
2132     }
2133     return true;
2137 //################################
2138 //# GROUP CHAT WINDOW MANAGEMENT
2139 //################################
2141 bool PedroGui::groupChatCreate(const DOMString &groupJid, const DOMString &nick)
2143     std::vector<GroupChatWindow *>::iterator iter;
2144     for (iter=groupChats.begin() ; iter != groupChats.end() ; iter++)
2145         {
2146         if (groupJid == (*iter)->getGroupJid())
2147             return false;
2148         }
2149     GroupChatWindow *chat = new GroupChatWindow(*this, groupJid, nick);
2150     chat->show();
2151     groupChats.push_back(chat);
2152     return true;
2156 bool PedroGui::groupChatDelete(const DOMString &groupJid, const DOMString &nick)
2158     std::vector<GroupChatWindow *>::iterator iter;
2159     for (iter=groupChats.begin() ; iter != groupChats.end() ;)
2160         {
2161         if (groupJid == (*iter)->getGroupJid() &&
2162             nick     == (*iter)->getNick())
2163             {
2164             delete(*iter);
2165             iter = groupChats.erase(iter);
2166             }
2167         else
2168             iter++;
2169         }
2170     return true;
2174 bool PedroGui::groupChatDeleteAll()
2176     std::vector<GroupChatWindow *>::iterator iter;
2177     for (iter=groupChats.begin() ; iter != groupChats.end() ; )
2178         {
2179         delete(*iter);
2180         iter = groupChats.erase(iter);
2181         }
2182     return true;
2186 bool PedroGui::groupChatMessage(const DOMString &groupJid,
2187               const DOMString &from, const DOMString &data)
2189     std::vector<GroupChatWindow *>::iterator iter;
2190     for (iter=groupChats.begin() ; iter != groupChats.end() ; iter++)
2191         {
2192         if (groupJid == (*iter)->getGroupJid())
2193             {
2194             (*iter)->receiveMessage(from, data);
2195             }
2196         }
2197     return true;
2200 bool PedroGui::groupChatPresence(const DOMString &groupJid,
2201                       const DOMString &nick, bool presence,
2202                       const DOMString &show,
2203                       const DOMString &status)
2205     std::vector<GroupChatWindow *>::iterator iter;
2206     for (iter=groupChats.begin() ; iter != groupChats.end() ; iter++)
2207         {
2208         if (groupJid == (*iter)->getGroupJid())
2209             {
2210             (*iter)->receivePresence(nick, presence, show, status);
2211             }
2212         }
2213     return true;
2216 //################################
2217 //# EVENTS
2218 //################################
2220 /**
2221  *
2222  */
2223 void PedroGui::padlockEnable()
2225     padlockIcon.set(Gtk::Stock::DIALOG_AUTHENTICATION,
2226                Gtk::ICON_SIZE_MENU);
2229 /**
2230  *
2231  */
2232 void PedroGui::padlockDisable()
2234     padlockIcon.clear();
2238 /**
2239  *
2240  */
2241 void PedroGui::handleConnectEvent()
2243      status("##### CONNECTED");
2244      actionEnable("Connect",    false);
2245      actionEnable("Chat",       true);
2246      actionEnable("GroupChat",  true);
2247      actionEnable("Disconnect", true);
2248      actionEnable("RegPass",    true);
2249      actionEnable("RegCancel",  true);
2250      DOMString title = "Pedro - ";
2251      title.append(client.getJid());
2252      set_title(title);
2256 /**
2257  *
2258  */
2259 void PedroGui::handleDisconnectEvent()
2261      status("##### DISCONNECTED");
2262      actionEnable("Connect",    true);
2263      actionEnable("Chat",       false);
2264      actionEnable("GroupChat",  false);
2265      actionEnable("Disconnect", false);
2266      actionEnable("RegPass",    false);
2267      actionEnable("RegCancel",  false);
2268      padlockDisable();
2269      DOMString title = "Pedro";
2270      set_title(title);
2271      chatDeleteAll();
2272      groupChatDeleteAll();
2273      roster.clear();
2277 /**
2278  *
2279  */
2280 void PedroGui::doEvent(const XmppEvent &event)
2283     int typ = event.getType();
2284     switch (typ)
2285         {
2286         case XmppEvent::EVENT_STATUS:
2287             {
2288             //printf("##### STATUS: %s\n", event.getData().c_str());
2289             status(event.getData().c_str());
2290             break;
2291             }
2292         case XmppEvent::EVENT_ERROR:
2293             {
2294             //printf("##### ERROR: %s\n", event.getData().c_str());
2295             error(event.getData().c_str());
2296             padlockDisable();
2297             break;
2298             }
2299         case XmppEvent::EVENT_SSL_STARTED:
2300             {
2301             padlockEnable();
2302             break;
2303             }
2304         case XmppEvent::EVENT_CONNECTED:
2305             {
2306             handleConnectEvent();
2307             break;
2308             }
2309         case XmppEvent::EVENT_DISCONNECTED:
2310             {
2311             handleDisconnectEvent();
2312             break;
2313             }
2314         case XmppEvent::EVENT_MESSAGE:
2315             {
2316             status("##### MESSAGE: %s\n", event.getFrom().c_str());
2317             chatMessage(event.getFrom(), event.getData());
2318             break;
2319             }
2320         case XmppEvent::EVENT_PRESENCE:
2321             {
2322             status("##### PRESENCE: %s\n", event.getFrom().c_str());
2323             roster.refresh();
2324             break;
2325             }
2326         case XmppEvent::EVENT_ROSTER:
2327             {
2328             status("##### ROSTER\n");
2329             roster.refresh();
2330             break;
2331             }
2332         case XmppEvent::EVENT_MUC_JOIN:
2333             {
2334             status("##### GROUP JOINED: %s\n", event.getGroup().c_str());
2335             break;
2336             }
2337         case XmppEvent::EVENT_MUC_MESSAGE:
2338             {
2339             //printf("##### MUC_MESSAGE: %s\n", event.getGroup().c_str());
2340             groupChatMessage(event.getGroup(),
2341                     event.getFrom(), event.getData());
2342             break;
2343             }
2344         case XmppEvent::EVENT_MUC_PRESENCE:
2345             {
2346             //printf("##### MUC_USER LIST: %s\n", event.getFrom().c_str());
2347             groupChatPresence(event.getGroup(),
2348                               event.getFrom(),
2349                               event.getPresence(),
2350                               event.getShow(),
2351                               event.getStatus());
2352             break;
2353             }
2354         case XmppEvent::EVENT_MUC_LEAVE:
2355             {
2356             status("##### GROUP LEFT: %s\n", event.getGroup().c_str());
2357             groupChatDelete(event.getGroup(), event.getFrom());
2358             break;
2359             }
2360         case XmppEvent::EVENT_FILE_RECEIVE:
2361             {
2362             status("##### FILE RECEIVE: %s\n", event.getFileName().c_str());
2363             doReceiveFile(event.getFrom(), event.getIqId(), event.getStreamId(),
2364                        event.getFileName(), event.getFileDesc(),
2365                        event.getFileSize(), event.getFileHash());
2366             break;
2367             }
2368         case XmppEvent::EVENT_REGISTRATION_NEW:
2369             {
2370             status("##### REGISTERED: %s at %s\n",
2371                        event.getTo().c_str(), event.getFrom().c_str());
2372             break;
2373             }
2374         case XmppEvent::EVENT_REGISTRATION_CHANGE_PASS:
2375             {
2376             status("##### PASSWORD CHANGED: %s at %s\n",
2377                        event.getTo().c_str(), event.getFrom().c_str());
2378             break;
2379             }
2380         case XmppEvent::EVENT_REGISTRATION_CANCEL:
2381             {
2382             //client.disconnect();
2383             status("##### REGISTERATION CANCELLED: %s at %s\n",
2384                        event.getTo().c_str(), event.getFrom().c_str());
2385             break;
2386             }
2387         default:
2388             {
2389             printf("unknown event type: %d\n", typ);
2390             break;
2391             }
2392         }
2396 /**
2397  *
2398  */
2399 bool PedroGui::checkEventQueue()
2401     while (client.eventQueueAvailable() > 0)
2402         {
2403         XmppEvent evt = client.eventQueuePop();
2404         doEvent(evt);
2405         }
2407     while( Gtk::Main::events_pending() )
2408         Gtk::Main::iteration();
2410     return true;
2414 //##################
2415 //# COMMANDS
2416 //##################
2417 void PedroGui::doChat(const DOMString &jid)
2419     if (jid.size()>0)
2420         {
2421         chatCreate(jid);
2422         return;
2423         }
2425     FileSendDialog dlg(*this);
2426     int ret = dlg.run();
2427     if (ret == Gtk::RESPONSE_OK)
2428         {
2429         chatCreate(dlg.getJid());
2430         }
2434 void PedroGui::doSendFile(const DOMString &jid)
2436     FileSendDialog dlg(*this);
2437     if (jid.size()>0)
2438         dlg.setJid(jid);
2439     int ret = dlg.run();
2440     if (ret == Gtk::RESPONSE_OK)
2441         {
2442         DOMString fileName = dlg.getFileName();
2443         printf("fileName:%s\n", fileName.c_str());
2444         DOMString offeredName = "";
2445         DOMString desc = "";
2446         client.fileSendBackground(jid, offeredName, fileName, desc);
2447         }
2451 void PedroGui::doReceiveFile(
2452                       const DOMString &jid,
2453                       const DOMString &iqId,
2454                       const DOMString &streamId,
2455                       const DOMString &offeredName,
2456                       const DOMString &desc,
2457                       long  size,
2458                       const DOMString &hash
2459                       )
2462     FileReceiveDialog dlg(*this, jid, iqId, streamId,
2463                           offeredName, desc, size, hash);
2464     int ret = dlg.run();
2465     if (ret == Gtk::RESPONSE_OK)
2466         {
2467         DOMString fileName = dlg.getFileName();
2468         printf("fileName:%s\n", fileName.c_str());
2469         client.fileReceiveBackground(jid, iqId, streamId, fileName, size, hash);
2470         }
2474 void PedroGui::doShare(const DOMString &jid)
2476     Inkscape::Whiteboard::SessionManager& sm =
2477          Inkscape::Whiteboard::SessionManager::instance();
2478     sm.initialiseSession(jid, Inkscape::Whiteboard::State::WHITEBOARD_PEER);
2481 void PedroGui::doGroupShare(const DOMString &groupJid)
2483     Inkscape::Whiteboard::SessionManager& sm =
2484         Inkscape::Whiteboard::SessionManager::instance();
2485     sm.initialiseSession(groupJid, Inkscape::Whiteboard::State::WHITEBOARD_MUC);
2488 //##################
2489 //# CALLBACKS
2490 //##################
2491 void PedroGui::connectCallback()
2493     ConnectDialog dialog(*this);
2494     int result = dialog.run();
2495     dialog.hide();
2496     if (result == Gtk::RESPONSE_OK)
2497         {
2498         client.setHost(dialog.getHost());
2499         client.setPort(dialog.getPort());
2500         client.setUsername(dialog.getUser());
2501         client.setPassword(dialog.getPass());
2502         client.setResource(dialog.getResource());
2503         client.setDoRegister(dialog.getRegister());
2504         client.connect();
2505         }
2510 void PedroGui::chatCallback()
2512     ChatDialog dialog(*this);
2513     int result = dialog.run();
2514     dialog.hide();
2515     if (result == Gtk::RESPONSE_OK)
2516         {
2517         client.message(dialog.getUser(), dialog.getText());
2518         }
2523 void PedroGui::groupChatCallback()
2525     GroupChatDialog dialog(*this);
2526     int result = dialog.run();
2527     dialog.hide();
2528     if (result != Gtk::RESPONSE_OK)
2529         return;
2530     DOMString groupJid = dialog.getGroup();
2531     groupJid.append("@");
2532     groupJid.append(dialog.getHost());
2533     if (client.groupChatExists(groupJid))
2534         {
2535         error("Group chat %s already exists", groupJid.c_str());
2536         return;
2537         }
2538     groupChatCreate(groupJid, dialog.getNick());
2539     client.groupChatJoin(groupJid, dialog.getNick(), dialog.getPass() );
2540     config.setMucGroup(dialog.getGroup());
2541     config.setMucHost(dialog.getHost());
2542     config.setMucNick(dialog.getNick());
2543     config.setMucPassword(dialog.getPass());
2544  
2545     configSave();
2549 void PedroGui::disconnectCallback()
2551     client.disconnect();
2555 void PedroGui::quitCallback()
2557     Gtk::Main::quit();
2561 void PedroGui::fontCallback()
2563     Gtk::FontSelectionDialog dlg;
2564     int ret = dlg.run();
2565     if (ret == Gtk::RESPONSE_OK)
2566         {
2567         Glib::ustring fontName = dlg.get_font_name();
2568         Pango::FontDescription fontDesc(fontName);
2569         modify_font(fontDesc);
2570         }
2573 void PedroGui::colorCallback()
2575     Gtk::ColorSelectionDialog dlg;
2576     int ret = dlg.run();
2577     if (ret == Gtk::RESPONSE_OK)
2578         {
2579         Gdk::Color col = dlg.get_colorsel()->get_current_color();
2580         modify_bg(Gtk::STATE_NORMAL, col);
2581         }
2584 void PedroGui::regPassCallback()
2586     PasswordDialog dlg(*this);
2587     int ret = dlg.run();
2588     if (ret == Gtk::RESPONSE_OK)
2589         {
2590         DOMString newpass = dlg.getNewPass();
2591         client.inBandRegistrationChangePassword(newpass);
2592         }
2596 void PedroGui::regCancelCallback()
2598     Gtk::MessageDialog dlg(*this, "Do you want to cancel your registration on the server?",
2599         false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true);
2600     int ret = dlg.run();
2601     if (ret == Gtk::RESPONSE_YES)
2602         {
2603         client.inBandRegistrationCancel();
2604         }
2609 void PedroGui::sendFileCallback()
2611     doSendFile("");
2616 void PedroGui::aboutCallback()
2618     Gtk::AboutDialog dlg;
2619     std::vector<Glib::ustring>authors;
2620     authors.push_back("Bob Jamison");
2621     dlg.set_authors(authors);
2622     DOMString comments = "A simple XMPP gui client  ";
2623     comments.append("Based on the Pedro XMPP client");
2624     dlg.set_comments(comments);
2625     dlg.set_version("1.0");
2626     dlg.run();
2631 void PedroGui::actionEnable(const DOMString &name, bool val)
2633     DOMString path = "/ui/MenuBar/";
2634     path.append(name);
2635     Glib::RefPtr<Gtk::Action> action = uiManager->get_action(path);
2636     if (!action)
2637         {
2638         path = "/ui/MenuBar/MenuFile/";
2639         path.append(name);
2640         action = uiManager->get_action(path);
2641         }
2642     if (!action)
2643         {
2644         path = "/ui/MenuBar/MenuEdit/";
2645         path.append(name);
2646         action = uiManager->get_action(path);
2647         }
2648     if (!action)
2649         {
2650         path = "/ui/MenuBar/MenuRegister/";
2651         path.append(name);
2652         action = uiManager->get_action(path);
2653         }
2654     if (!action)
2655         {
2656         path = "/ui/MenuBar/MenuTransfer/";
2657         path.append(name);
2658         action = uiManager->get_action(path);
2659         }
2660     if (!action)
2661         {
2662         path = "/ui/MenuBar/MenuHelp/";
2663         path.append(name);
2664         action = uiManager->get_action(path);
2665         }
2666     if (!action)
2667         return;
2668     action->set_sensitive(val);
2672 bool PedroGui::configLoad()
2674     if (!config.readFile("pedro.ini"))
2675         return false;
2676     return true;
2680 bool PedroGui::configSave()
2682     if (!config.writeFile("pedro.ini"))
2683         return false;
2684     return true;
2690 bool PedroGui::doSetup()
2692     configLoad();
2694     set_title("Pedro XMPP Client");
2695     set_size_request(500, 300);
2696     add(mainBox);
2698     Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
2700     //### FILE MENU
2701     actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
2703     actionGroup->add( Gtk::Action::create("Connect",
2704                                   Gtk::Stock::CONNECT, "Connect"),
2705     sigc::mem_fun(*this, &PedroGui::connectCallback) );
2707     actionGroup->add( Gtk::Action::create("Chat",
2708                                   Gtk::Stock::CONNECT, "Chat"),
2709     sigc::mem_fun(*this, &PedroGui::chatCallback) );
2711     actionGroup->add( Gtk::Action::create("GroupChat",
2712                                   Gtk::Stock::CONNECT, "Group Chat"),
2713     sigc::mem_fun(*this, &PedroGui::groupChatCallback) );
2715     actionGroup->add( Gtk::Action::create("Disconnect",
2716                                   Gtk::Stock::DISCONNECT, "Disconnect"),
2717     sigc::mem_fun(*this, &PedroGui::disconnectCallback) );
2719     actionGroup->add( Gtk::Action::create("Quit", Gtk::Stock::QUIT),
2720     sigc::mem_fun(*this, &PedroGui::quitCallback) );
2722     //### EDIT MENU
2723     actionGroup->add( Gtk::Action::create("MenuEdit", "_Edit") );
2724     actionGroup->add( Gtk::Action::create("SelectFont",
2725                                   Gtk::Stock::SELECT_FONT, "Select Font"),
2726     sigc::mem_fun(*this, &PedroGui::fontCallback) );
2727     actionGroup->add( Gtk::Action::create("SelectColor",
2728                                   Gtk::Stock::SELECT_COLOR, "Select Color"),
2729     sigc::mem_fun(*this, &PedroGui::colorCallback) );
2731     //### REGISTER MENU
2732     actionGroup->add( Gtk::Action::create("MenuRegister", "_Registration") );
2733     actionGroup->add( Gtk::Action::create("RegPass",
2734                                   Gtk::Stock::DIALOG_AUTHENTICATION, "Change Password"),
2735     sigc::mem_fun(*this, &PedroGui::regPassCallback) );
2736     actionGroup->add( Gtk::Action::create("RegCancel",
2737                                   Gtk::Stock::CANCEL, "Cancel Registration"),
2738     sigc::mem_fun(*this, &PedroGui::regCancelCallback) );
2740     //### TRANSFER MENU
2741     actionGroup->add( Gtk::Action::create("MenuTransfer", "_Transfer") );
2742     actionGroup->add( Gtk::Action::create("SendFile",
2743                                   Gtk::Stock::NETWORK, "Send File"),
2744     sigc::mem_fun(*this, &PedroGui::sendFileCallback) );
2746     //### HELP MENU
2747     actionGroup->add( Gtk::Action::create("MenuHelp", "_Help") );
2748     actionGroup->add( Gtk::Action::create("About",
2749                                   Gtk::Stock::ABOUT, "About Pedro"),
2750     sigc::mem_fun(*this, &PedroGui::aboutCallback) );
2752     uiManager = Gtk::UIManager::create();
2754     uiManager->insert_action_group(actionGroup, 0);
2755     add_accel_group(uiManager->get_accel_group());
2757     Glib::ustring ui_info =
2758         "<ui>"
2759         "  <menubar name='MenuBar'>"
2760         "    <menu action='MenuFile'>"
2761         "      <menuitem action='Connect'/>"
2762         "      <separator/>"
2763         "      <menuitem action='Chat'/>"
2764         "      <menuitem action='GroupChat'/>"
2765         "      <separator/>"
2766         "      <menuitem action='Disconnect'/>"
2767         "      <menuitem action='Quit'/>"
2768         "    </menu>"
2769         "    <menu action='MenuEdit'>"
2770         "      <menuitem action='SelectFont'/>"
2771         "      <menuitem action='SelectColor'/>"
2772         "    </menu>"
2773         "    <menu action='MenuRegister'>"
2774         "      <menuitem action='RegPass'/>"
2775         "      <menuitem action='RegCancel'/>"
2776         "    </menu>"
2777         "    <menu action='MenuTransfer'>"
2778         "      <menuitem action='SendFile'/>"
2779         "    </menu>"
2780         "    <menu action='MenuHelp'>"
2781         "      <menuitem action='About'/>"
2782         "    </menu>"
2783         "  </menubar>"
2784         "</ui>";
2786     uiManager->add_ui_from_string(ui_info);
2787     Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
2788     menuBarBox.pack_start(*pMenuBar, Gtk::PACK_SHRINK);
2790     padlockDisable();
2791     menuBarBox.pack_end(padlockIcon, Gtk::PACK_SHRINK);
2793     mainBox.pack_start(menuBarBox, Gtk::PACK_SHRINK);
2795     actionEnable("Connect",    true);
2796     actionEnable("Chat",       false);
2797     actionEnable("GroupChat",  false);
2798     actionEnable("Disconnect", false);
2799     actionEnable("RegPass",    false);
2800     actionEnable("RegCancel",  false);
2802     mainBox.pack_start(vPaned);
2803     vPaned.add1(roster);
2804     vPaned.add2(messageList);
2805     roster.setParent(this);
2807     show_all_children();
2809     //# Start a timer to check the queue every nn milliseconds
2810     Glib::signal_timeout().connect(
2811            sigc::mem_fun(*this, &PedroGui::checkEventQueue), 20 );
2813     //client.addXmppEventListener(*this);
2814     client.eventQueueEnable(true);
2816     return true;
2820 } // namespace Pedro
2824 //########################################################################
2825 //# E N D    O F     F I L E
2826 //########################################################################