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)
384 {
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);
393 }
395 void Roster::chatCallback()
396 {
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);
404 }
406 void Roster::sendFileCallback()
407 {
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);
415 }
417 void Roster::shareCallback()
418 {
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);
426 }
428 bool Roster::buttonPressCallback(GdkEventButton* event)
429 {
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;
439 }
441 bool Roster::doSetup()
442 {
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;
532 }
535 /**
536 * Clear the roster
537 */
538 void Roster::clear()
539 {
540 treeStore->clear();
541 }
543 /**
544 * Regenerate the roster
545 */
546 void Roster::refresh()
547 {
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();
589 }
591 //#########################################################################
592 //# M E S S A G E L I S T
593 //#########################################################################
595 bool MessageList::doSetup()
596 {
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;
654 }
656 /**
657 * Clear all messages from the list
658 */
659 void MessageList::clear()
660 {
661 messageListBuffer->erase(messageListBuffer->begin(),
662 messageListBuffer->end());
663 }
666 /**
667 * Post a message to the list
668 */
669 void MessageList::postMessage(const DOMString &from, const DOMString &msg)
670 {
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);
694 }
698 //#########################################################################
699 //# U S E R L I S T
700 //#########################################################################
701 void UserList::doubleClickCallback(const Gtk::TreeModel::Path &path,
702 Gtk::TreeViewColumn *col)
703 {
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);
712 }
714 void UserList::chatCallback()
715 {
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);
723 }
725 void UserList::sendFileCallback()
726 {
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);
734 }
736 void UserList::shareCallback()
737 {
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);
745 }
747 bool UserList::buttonPressCallback(GdkEventButton* event)
748 {
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;
758 }
760 bool UserList::doSetup()
761 {
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;
839 }
841 /**
842 * Clear all messages from the list
843 */
844 void UserList::clear()
845 {
846 userListStore->clear();
847 }
850 /**
851 * Add a user to the list
852 */
853 void UserList::addUser(const DOMString &user, const DOMString &show)
854 {
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;
873 }
878 //#########################################################################
879 //# C H A T W I N D O W
880 //#########################################################################
881 ChatWindow::ChatWindow(PedroGui &par, const DOMString jidArg)
882 : parent(par)
883 {
884 jid = jidArg;
885 doSetup();
886 }
888 ChatWindow::~ChatWindow()
889 {
890 }
892 void ChatWindow::leaveCallback()
893 {
894 hide();
895 parent.chatDelete(jid);
896 }
899 void ChatWindow::hideCallback()
900 {
901 hide();
902 parent.chatDelete(jid);
903 }
905 void ChatWindow::shareCallback()
906 {
907 // hide();
908 parent.doShare(this->jid);
909 }
911 void ChatWindow::textEnterCallback()
912 {
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);
918 }
920 bool ChatWindow::doSetup()
921 {
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;
971 }
973 bool ChatWindow::postMessage(const DOMString &data)
974 {
975 messageList.postMessage(jid, data);
976 return true;
977 }
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)
987 {
988 groupJid = groupJidArg;
989 nick = nickArg;
990 doSetup();
991 }
993 GroupChatWindow::~GroupChatWindow()
994 {
995 }
998 void GroupChatWindow::leaveCallback()
999 {
1000 parent.client.groupChatLeave(groupJid, nick);
1001 hide();
1002 parent.groupChatDelete(groupJid, nick);
1003 }
1005 void GroupChatWindow::hideCallback()
1006 {
1007 parent.client.groupChatLeave(groupJid, nick);
1008 hide();
1009 parent.groupChatDelete(groupJid, nick);
1010 }
1012 void GroupChatWindow::textEnterCallback()
1013 {
1014 DOMString str = inputTxt.get_text();
1015 if (str.size() > 0)
1016 parent.client.groupChatMessage(groupJid, str);
1017 inputTxt.set_text("");
1018 }
1020 void GroupChatWindow::shareCallback()
1021 {
1022 parent.doGroupShare(groupJid);
1023 }
1025 bool GroupChatWindow::doSetup()
1026 {
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;
1082 }
1084 bool GroupChatWindow::receiveMessage(const DOMString &from,
1085 const DOMString &data)
1086 {
1087 messageList.postMessage(from, data);
1088 return true;
1089 }
1091 bool GroupChatWindow::receivePresence(const DOMString &fromNick,
1092 bool presence,
1093 const DOMString &show,
1094 const DOMString &status)
1095 {
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;
1124 }
1127 void GroupChatWindow::doChat(const DOMString &nick)
1128 {
1129 printf("##Chat with %s\n", nick.c_str());
1130 DOMString fullJid = groupJid;
1131 fullJid.append("/");
1132 fullJid.append(nick);
1133 parent.doChat(fullJid);
1134 }
1136 void GroupChatWindow::doSendFile(const DOMString &nick)
1137 {
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);
1144 }
1146 void GroupChatWindow::doShare(const DOMString &nick)
1147 {
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);
1154 }
1157 //#########################################################################
1158 //# C O N F I G D I A L O G
1159 //#########################################################################
1162 void ConfigDialog::okCallback()
1163 {
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 }
1186 }
1188 void ConfigDialog::cancelCallback()
1189 {
1190 //response(Gtk::RESPONSE_CANCEL);
1191 hide();
1192 }
1194 void ConfigDialog::on_response(int response_id)
1195 {
1196 if (response_id == Gtk::RESPONSE_OK)
1197 okCallback();
1198 else
1199 cancelCallback();
1200 }
1202 bool ConfigDialog::doSetup()
1203 {
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;
1262 }
1264 //#########################################################################
1265 //# P A S S W O R D D I A L O G
1266 //#########################################################################
1269 void PasswordDialog::okCallback()
1270 {
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 }
1293 }
1295 void PasswordDialog::cancelCallback()
1296 {
1297 //response(Gtk::RESPONSE_CANCEL);
1298 hide();
1299 }
1301 void PasswordDialog::on_response(int response_id)
1302 {
1303 if (response_id == Gtk::RESPONSE_OK)
1304 okCallback();
1305 else
1306 cancelCallback();
1307 }
1309 bool PasswordDialog::doSetup()
1310 {
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;
1369 }
1371 //#########################################################################
1372 //# C H A T D I A L O G
1373 //#########################################################################
1376 void ChatDialog::okCallback()
1377 {
1378 response(Gtk::RESPONSE_OK);
1379 hide();
1380 }
1382 void ChatDialog::cancelCallback()
1383 {
1384 response(Gtk::RESPONSE_CANCEL);
1385 hide();
1386 }
1389 bool ChatDialog::doSetup()
1390 {
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;
1439 }
1441 //#########################################################################
1442 //# G R O U P C H A T D I A L O G
1443 //#########################################################################
1446 void GroupChatDialog::okCallback()
1447 {
1448 response(Gtk::RESPONSE_OK);
1449 hide();
1450 }
1452 void GroupChatDialog::cancelCallback()
1453 {
1454 response(Gtk::RESPONSE_CANCEL);
1455 hide();
1456 }
1459 bool GroupChatDialog::doSetup()
1460 {
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;
1523 }
1528 //#########################################################################
1529 //# C O N N E C T D I A L O G
1530 //#########################################################################
1533 void ConnectDialog::okCallback()
1534 {
1535 response(Gtk::RESPONSE_OK);
1536 hide();
1537 }
1539 void ConnectDialog::saveCallback()
1540 {
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();
1577 }
1579 void ConnectDialog::cancelCallback()
1580 {
1581 response(Gtk::RESPONSE_CANCEL);
1582 hide();
1583 }
1586 void ConnectDialog::doubleClickCallback(
1587 const Gtk::TreeModel::Path &path,
1588 Gtk::TreeViewColumn *col)
1589 {
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();
1605 }
1607 void ConnectDialog::selectedCallback()
1608 {
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());
1621 }
1623 void ConnectDialog::deleteCallback()
1624 {
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();
1634 }
1638 void ConnectDialog::buttonPressCallback(GdkEventButton* event)
1639 {
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 }
1646 }
1649 bool ConnectDialog::doSetup()
1650 {
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;
1796 }
1799 /**
1800 * Regenerate the account list
1801 */
1802 void ConnectDialog::refresh()
1803 {
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();
1815 }
1819 //#########################################################################
1820 //# F I L E S E N D D I A L O G
1821 //#########################################################################
1824 void FileSendDialog::okCallback()
1825 {
1826 response(Gtk::RESPONSE_OK);
1827 hide();
1828 }
1830 void FileSendDialog::cancelCallback()
1831 {
1832 response(Gtk::RESPONSE_CANCEL);
1833 hide();
1834 }
1837 void FileSendDialog::buttonCallback()
1838 {
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 }
1849 }
1851 bool FileSendDialog::doSetup()
1852 {
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;
1908 }
1911 //#########################################################################
1912 //# F I L E R E C E I V E D I A L O G
1913 //#########################################################################
1916 void FileReceiveDialog::okCallback()
1917 {
1918 response(Gtk::RESPONSE_OK);
1919 hide();
1920 }
1922 void FileReceiveDialog::cancelCallback()
1923 {
1924 response(Gtk::RESPONSE_CANCEL);
1925 hide();
1926 }
1928 void FileReceiveDialog::buttonCallback()
1929 {
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 }
1940 }
1943 bool FileReceiveDialog::doSetup()
1944 {
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;
2028 }
2031 //#########################################################################
2032 //# M A I N W I N D O W
2033 //#########################################################################
2035 PedroGui::PedroGui()
2036 {
2037 doSetup();
2038 }
2040 PedroGui::~PedroGui()
2041 {
2042 chatDeleteAll();
2043 groupChatDeleteAll();
2044 }
2047 void PedroGui::error(const char *fmt, ...)
2048 {
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();
2060 }
2062 void PedroGui::status(const char *fmt, ...)
2063 {
2064 va_list args;
2065 va_start(args, fmt);
2066 vsnprintf(writeBuf, writeBufLen, fmt, args);
2067 va_end(args) ;
2068 messageList.postMessage("STATUS", writeBuf);
2069 }
2071 //################################
2072 //# CHAT WINDOW MANAGEMENT
2073 //################################
2074 bool PedroGui::chatCreate(const DOMString &userJid)
2075 {
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;
2086 }
2088 bool PedroGui::chatDelete(const DOMString &userJid)
2089 {
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;
2102 }
2104 bool PedroGui::chatDeleteAll()
2105 {
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;
2113 }
2115 bool PedroGui::chatMessage(const DOMString &from, const DOMString &data)
2116 {
2117 if(data.size() > 0)
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;
2134 }
2137 //################################
2138 //# GROUP CHAT WINDOW MANAGEMENT
2139 //################################
2141 bool PedroGui::groupChatCreate(const DOMString &groupJid, const DOMString &nick)
2142 {
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;
2153 }
2156 bool PedroGui::groupChatDelete(const DOMString &groupJid, const DOMString &nick)
2157 {
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;
2171 }
2174 bool PedroGui::groupChatDeleteAll()
2175 {
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;
2183 }
2186 bool PedroGui::groupChatMessage(const DOMString &groupJid,
2187 const DOMString &from, const DOMString &data)
2188 {
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;
2198 }
2200 bool PedroGui::groupChatPresence(const DOMString &groupJid,
2201 const DOMString &nick, bool presence,
2202 const DOMString &show,
2203 const DOMString &status)
2204 {
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;
2214 }
2216 //################################
2217 //# EVENTS
2218 //################################
2220 /**
2221 *
2222 */
2223 void PedroGui::padlockEnable()
2224 {
2225 padlockIcon.set(Gtk::Stock::DIALOG_AUTHENTICATION,
2226 Gtk::ICON_SIZE_MENU);
2227 }
2229 /**
2230 *
2231 */
2232 void PedroGui::padlockDisable()
2233 {
2234 padlockIcon.clear();
2235 }
2238 /**
2239 *
2240 */
2241 void PedroGui::handleConnectEvent()
2242 {
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);
2253 }
2256 /**
2257 *
2258 */
2259 void PedroGui::handleDisconnectEvent()
2260 {
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();
2274 }
2277 /**
2278 *
2279 */
2280 void PedroGui::doEvent(const XmppEvent &event)
2281 {
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 }
2394 }
2396 /**
2397 *
2398 */
2399 bool PedroGui::checkEventQueue()
2400 {
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;
2411 }
2414 //##################
2415 //# COMMANDS
2416 //##################
2417 void PedroGui::doChat(const DOMString &jid)
2418 {
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 }
2432 }
2434 void PedroGui::doSendFile(const DOMString &jid)
2435 {
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 }
2449 }
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 )
2461 {
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 }
2472 }
2474 void PedroGui::doShare(const DOMString &jid)
2475 {
2476 Inkscape::Whiteboard::SessionManager& sm =
2477 Inkscape::Whiteboard::SessionManager::instance();
2478 sm.initialiseSession(jid, Inkscape::Whiteboard::State::WHITEBOARD_PEER);
2479 }
2481 void PedroGui::doGroupShare(const DOMString &groupJid)
2482 {
2483 Inkscape::Whiteboard::SessionManager& sm =
2484 Inkscape::Whiteboard::SessionManager::instance();
2485 sm.initialiseSession(groupJid, Inkscape::Whiteboard::State::WHITEBOARD_MUC);
2486 }
2488 //##################
2489 //# CALLBACKS
2490 //##################
2491 void PedroGui::connectCallback()
2492 {
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 }
2506 }
2510 void PedroGui::chatCallback()
2511 {
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 }
2519 }
2523 void PedroGui::groupChatCallback()
2524 {
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());
2545 configSave();
2546 }
2549 void PedroGui::disconnectCallback()
2550 {
2551 client.disconnect();
2552 }
2555 void PedroGui::quitCallback()
2556 {
2557 Gtk::Main::quit();
2558 }
2561 void PedroGui::fontCallback()
2562 {
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 }
2571 }
2573 void PedroGui::colorCallback()
2574 {
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 }
2582 }
2584 void PedroGui::regPassCallback()
2585 {
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 }
2593 }
2596 void PedroGui::regCancelCallback()
2597 {
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 }
2605 }
2609 void PedroGui::sendFileCallback()
2610 {
2611 doSendFile("");
2612 }
2616 void PedroGui::aboutCallback()
2617 {
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();
2627 }
2631 void PedroGui::actionEnable(const DOMString &name, bool val)
2632 {
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);
2669 }
2672 bool PedroGui::configLoad()
2673 {
2674 if (!config.readFile("pedro.ini"))
2675 return false;
2676 return true;
2677 }
2680 bool PedroGui::configSave()
2681 {
2682 if (!config.writeFile("pedro.ini"))
2683 return false;
2684 return true;
2685 }
2690 bool PedroGui::doSetup()
2691 {
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;
2817 }
2820 } // namespace Pedro
2824 //########################################################################
2825 //# E N D O F F I L E
2826 //########################################################################