Code

plumb XML::Document parameter into duplication, courtesy of bryce
[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     gchar * buffer = g_strdup_vprintf(fmt, args);
2052     va_end(args) ;
2054     Gtk::MessageDialog dlg(buffer,
2055                            false,
2056                            Gtk::MESSAGE_ERROR,
2057                            Gtk::BUTTONS_OK,
2058                            true);
2059     dlg.run();
2060     g_free(buffer);
2063 void PedroGui::status(const char *fmt, ...)
2065     va_list args;
2066     va_start(args, fmt);
2067     gchar * buffer = g_strdup_vprintf(fmt, args);
2068     va_end(args) ;
2069     messageList.postMessage("STATUS", buffer);
2070     g_free(buffer);
2073 //################################
2074 //# CHAT WINDOW MANAGEMENT
2075 //################################
2076 bool PedroGui::chatCreate(const DOMString &userJid)
2078     std::vector<ChatWindow *>::iterator iter;
2079     for (iter=chats.begin() ; iter != chats.end() ; iter++)
2080         {
2081         if (userJid == (*iter)->getJid())
2082             return false;
2083         }
2084     ChatWindow *chat = new ChatWindow(*this, userJid);
2085     chat->show();
2086     chats.push_back(chat);
2087     return true;
2090 bool PedroGui::chatDelete(const DOMString &userJid)
2092     std::vector<ChatWindow *>::iterator iter;
2093     for (iter=chats.begin() ; iter != chats.end() ; )
2094         {
2095         if (userJid == (*iter)->getJid())
2096             {
2097             delete(*iter);
2098             iter = chats.erase(iter);
2099             }
2100         else
2101             iter++;
2102         }
2103     return true;
2106 bool PedroGui::chatDeleteAll()
2108     std::vector<ChatWindow *>::iterator iter;
2109     for (iter=chats.begin() ; iter != chats.end() ; )
2110         {
2111         delete(*iter);
2112         iter = chats.erase(iter);
2113         }
2114     return true;
2117 bool PedroGui::chatMessage(const DOMString &from, const DOMString &data)
2119     if(data.size() > 0)
2120     {
2121         std::vector<ChatWindow *>::iterator iter;
2122         for (iter=chats.begin() ; iter != chats.end() ; iter++)
2123             {
2124             if (from == (*iter)->getJid())
2125                 {
2126                 (*iter)->postMessage(data);
2127                 return true;
2128                 }
2129             }
2130         ChatWindow *chat = new ChatWindow(*this, from);
2131         chat->show();
2132         chats.push_back(chat);
2133         chat->postMessage(data);
2134     }
2135     return true;
2139 //################################
2140 //# GROUP CHAT WINDOW MANAGEMENT
2141 //################################
2143 bool PedroGui::groupChatCreate(const DOMString &groupJid, const DOMString &nick)
2145     std::vector<GroupChatWindow *>::iterator iter;
2146     for (iter=groupChats.begin() ; iter != groupChats.end() ; iter++)
2147         {
2148         if (groupJid == (*iter)->getGroupJid())
2149             return false;
2150         }
2151     GroupChatWindow *chat = new GroupChatWindow(*this, groupJid, nick);
2152     chat->show();
2153     groupChats.push_back(chat);
2154     return true;
2158 bool PedroGui::groupChatDelete(const DOMString &groupJid, const DOMString &nick)
2160     std::vector<GroupChatWindow *>::iterator iter;
2161     for (iter=groupChats.begin() ; iter != groupChats.end() ;)
2162         {
2163         if (groupJid == (*iter)->getGroupJid() &&
2164             nick     == (*iter)->getNick())
2165             {
2166             delete(*iter);
2167             iter = groupChats.erase(iter);
2168             }
2169         else
2170             iter++;
2171         }
2172     return true;
2176 bool PedroGui::groupChatDeleteAll()
2178     std::vector<GroupChatWindow *>::iterator iter;
2179     for (iter=groupChats.begin() ; iter != groupChats.end() ; )
2180         {
2181         delete(*iter);
2182         iter = groupChats.erase(iter);
2183         }
2184     return true;
2188 bool PedroGui::groupChatMessage(const DOMString &groupJid,
2189               const DOMString &from, const DOMString &data)
2191     std::vector<GroupChatWindow *>::iterator iter;
2192     for (iter=groupChats.begin() ; iter != groupChats.end() ; iter++)
2193         {
2194         if (groupJid == (*iter)->getGroupJid())
2195             {
2196             (*iter)->receiveMessage(from, data);
2197             }
2198         }
2199     return true;
2202 bool PedroGui::groupChatPresence(const DOMString &groupJid,
2203                       const DOMString &nick, bool presence,
2204                       const DOMString &show,
2205                       const DOMString &status)
2207     std::vector<GroupChatWindow *>::iterator iter;
2208     for (iter=groupChats.begin() ; iter != groupChats.end() ; iter++)
2209         {
2210         if (groupJid == (*iter)->getGroupJid())
2211             {
2212             (*iter)->receivePresence(nick, presence, show, status);
2213             }
2214         }
2215     return true;
2218 //################################
2219 //# EVENTS
2220 //################################
2222 /**
2223  *
2224  */
2225 void PedroGui::padlockEnable()
2227     padlockIcon.set(Gtk::Stock::DIALOG_AUTHENTICATION,
2228                Gtk::ICON_SIZE_MENU);
2231 /**
2232  *
2233  */
2234 void PedroGui::padlockDisable()
2236     padlockIcon.clear();
2240 /**
2241  *
2242  */
2243 void PedroGui::handleConnectEvent()
2245      status("##### CONNECTED");
2246      actionEnable("Connect",    false);
2247      actionEnable("Chat",       true);
2248      actionEnable("GroupChat",  true);
2249      actionEnable("Disconnect", true);
2250      actionEnable("RegPass",    true);
2251      actionEnable("RegCancel",  true);
2252      DOMString title = "Pedro - ";
2253      title.append(client.getJid());
2254      set_title(title);
2258 /**
2259  *
2260  */
2261 void PedroGui::handleDisconnectEvent()
2263      status("##### DISCONNECTED");
2264      actionEnable("Connect",    true);
2265      actionEnable("Chat",       false);
2266      actionEnable("GroupChat",  false);
2267      actionEnable("Disconnect", false);
2268      actionEnable("RegPass",    false);
2269      actionEnable("RegCancel",  false);
2270      padlockDisable();
2271      DOMString title = "Pedro";
2272      set_title(title);
2273      chatDeleteAll();
2274      groupChatDeleteAll();
2275      roster.clear();
2279 /**
2280  *
2281  */
2282 void PedroGui::doEvent(const XmppEvent &event)
2285     int typ = event.getType();
2286     switch (typ)
2287         {
2288         case XmppEvent::EVENT_STATUS:
2289             {
2290             //printf("##### STATUS: %s\n", event.getData().c_str());
2291             status("%s", event.getData().c_str());
2292             break;
2293             }
2294         case XmppEvent::EVENT_ERROR:
2295             {
2296             //printf("##### ERROR: %s\n", event.getData().c_str());
2297             error("%s", event.getData().c_str());
2298             padlockDisable();
2299             break;
2300             }
2301         case XmppEvent::EVENT_SSL_STARTED:
2302             {
2303             padlockEnable();
2304             break;
2305             }
2306         case XmppEvent::EVENT_CONNECTED:
2307             {
2308             handleConnectEvent();
2309             break;
2310             }
2311         case XmppEvent::EVENT_DISCONNECTED:
2312             {
2313             handleDisconnectEvent();
2314             break;
2315             }
2316         case XmppEvent::EVENT_MESSAGE:
2317             {
2318             status("##### MESSAGE: %s\n", event.getFrom().c_str());
2319             chatMessage(event.getFrom(), event.getData());
2320             break;
2321             }
2322         case XmppEvent::EVENT_PRESENCE:
2323             {
2324             status("##### PRESENCE: %s\n", event.getFrom().c_str());
2325             roster.refresh();
2326             break;
2327             }
2328         case XmppEvent::EVENT_ROSTER:
2329             {
2330             status("##### ROSTER\n");
2331             roster.refresh();
2332             break;
2333             }
2334         case XmppEvent::EVENT_MUC_JOIN:
2335             {
2336             status("##### GROUP JOINED: %s\n", event.getGroup().c_str());
2337             break;
2338             }
2339         case XmppEvent::EVENT_MUC_MESSAGE:
2340             {
2341             //printf("##### MUC_MESSAGE: %s\n", event.getGroup().c_str());
2342             groupChatMessage(event.getGroup(),
2343                     event.getFrom(), event.getData());
2344             break;
2345             }
2346         case XmppEvent::EVENT_MUC_PRESENCE:
2347             {
2348             //printf("##### MUC_USER LIST: %s\n", event.getFrom().c_str());
2349             groupChatPresence(event.getGroup(),
2350                               event.getFrom(),
2351                               event.getPresence(),
2352                               event.getShow(),
2353                               event.getStatus());
2354             break;
2355             }
2356         case XmppEvent::EVENT_MUC_LEAVE:
2357             {
2358             status("##### GROUP LEFT: %s\n", event.getGroup().c_str());
2359             groupChatDelete(event.getGroup(), event.getFrom());
2360             break;
2361             }
2362         case XmppEvent::EVENT_FILE_RECEIVE:
2363             {
2364             status("##### FILE RECEIVE: %s\n", event.getFileName().c_str());
2365             doReceiveFile(event.getFrom(), event.getIqId(), event.getStreamId(),
2366                        event.getFileName(), event.getFileDesc(),
2367                        event.getFileSize(), event.getFileHash());
2368             break;
2369             }
2370         case XmppEvent::EVENT_REGISTRATION_NEW:
2371             {
2372             status("##### REGISTERED: %s at %s\n",
2373                        event.getTo().c_str(), event.getFrom().c_str());
2374             break;
2375             }
2376         case XmppEvent::EVENT_REGISTRATION_CHANGE_PASS:
2377             {
2378             status("##### PASSWORD CHANGED: %s at %s\n",
2379                        event.getTo().c_str(), event.getFrom().c_str());
2380             break;
2381             }
2382         case XmppEvent::EVENT_REGISTRATION_CANCEL:
2383             {
2384             //client.disconnect();
2385             status("##### REGISTERATION CANCELLED: %s at %s\n",
2386                        event.getTo().c_str(), event.getFrom().c_str());
2387             break;
2388             }
2389         default:
2390             {
2391             printf("unknown event type: %d\n", typ);
2392             break;
2393             }
2394         }
2398 /**
2399  *
2400  */
2401 bool PedroGui::checkEventQueue()
2403     while (client.eventQueueAvailable() > 0)
2404         {
2405         XmppEvent evt = client.eventQueuePop();
2406         doEvent(evt);
2407         }
2409     while( Gtk::Main::events_pending() )
2410         Gtk::Main::iteration();
2412     return true;
2416 //##################
2417 //# COMMANDS
2418 //##################
2419 void PedroGui::doChat(const DOMString &jid)
2421     if (jid.size()>0)
2422         {
2423         chatCreate(jid);
2424         return;
2425         }
2427     FileSendDialog dlg(*this);
2428     int ret = dlg.run();
2429     if (ret == Gtk::RESPONSE_OK)
2430         {
2431         chatCreate(dlg.getJid());
2432         }
2436 void PedroGui::doSendFile(const DOMString &jid)
2438     FileSendDialog dlg(*this);
2439     if (jid.size()>0)
2440         dlg.setJid(jid);
2441     int ret = dlg.run();
2442     if (ret == Gtk::RESPONSE_OK)
2443         {
2444         DOMString fileName = dlg.getFileName();
2445         printf("fileName:%s\n", fileName.c_str());
2446         DOMString offeredName = "";
2447         DOMString desc = "";
2448         client.fileSendBackground(jid, offeredName, fileName, desc);
2449         }
2453 void PedroGui::doReceiveFile(
2454                       const DOMString &jid,
2455                       const DOMString &iqId,
2456                       const DOMString &streamId,
2457                       const DOMString &offeredName,
2458                       const DOMString &desc,
2459                       long  size,
2460                       const DOMString &hash
2461                       )
2464     FileReceiveDialog dlg(*this, jid, iqId, streamId,
2465                           offeredName, desc, size, hash);
2466     int ret = dlg.run();
2467     if (ret == Gtk::RESPONSE_OK)
2468         {
2469         DOMString fileName = dlg.getFileName();
2470         printf("fileName:%s\n", fileName.c_str());
2471         client.fileReceiveBackground(jid, iqId, streamId, fileName, size, hash);
2472         }
2476 void PedroGui::doShare(const DOMString &jid)
2478     Inkscape::Whiteboard::SessionManager& sm =
2479          Inkscape::Whiteboard::SessionManager::instance();
2480     sm.initialiseSession(jid, Inkscape::Whiteboard::State::WHITEBOARD_PEER);
2483 void PedroGui::doGroupShare(const DOMString &groupJid)
2485     Inkscape::Whiteboard::SessionManager& sm =
2486         Inkscape::Whiteboard::SessionManager::instance();
2487     sm.initialiseSession(groupJid, Inkscape::Whiteboard::State::WHITEBOARD_MUC);
2490 //##################
2491 //# CALLBACKS
2492 //##################
2493 void PedroGui::connectCallback()
2495     ConnectDialog dialog(*this);
2496     int result = dialog.run();
2497     dialog.hide();
2498     if (result == Gtk::RESPONSE_OK)
2499         {
2500         client.setHost(dialog.getHost());
2501         client.setPort(dialog.getPort());
2502         client.setUsername(dialog.getUser());
2503         client.setPassword(dialog.getPass());
2504         client.setResource(dialog.getResource());
2505         client.setDoRegister(dialog.getRegister());
2506         client.connect();
2507         }
2512 void PedroGui::chatCallback()
2514     ChatDialog dialog(*this);
2515     int result = dialog.run();
2516     dialog.hide();
2517     if (result == Gtk::RESPONSE_OK)
2518         {
2519         client.message(dialog.getUser(), dialog.getText());
2520         }
2525 void PedroGui::groupChatCallback()
2527     GroupChatDialog dialog(*this);
2528     int result = dialog.run();
2529     dialog.hide();
2530     if (result != Gtk::RESPONSE_OK)
2531         return;
2532     DOMString groupJid = dialog.getGroup();
2533     groupJid.append("@");
2534     groupJid.append(dialog.getHost());
2535     if (client.groupChatExists(groupJid))
2536         {
2537         error("Group chat %s already exists", groupJid.c_str());
2538         return;
2539         }
2540     groupChatCreate(groupJid, dialog.getNick());
2541     client.groupChatJoin(groupJid, dialog.getNick(), dialog.getPass() );
2542     config.setMucGroup(dialog.getGroup());
2543     config.setMucHost(dialog.getHost());
2544     config.setMucNick(dialog.getNick());
2545     config.setMucPassword(dialog.getPass());
2546  
2547     configSave();
2551 void PedroGui::disconnectCallback()
2553     client.disconnect();
2557 void PedroGui::quitCallback()
2559     client.disconnect();
2560     hide();
2561     //Severe overkill!  :-)
2562     //Gtk::Main::quit();
2566 void PedroGui::fontCallback()
2568     Gtk::FontSelectionDialog dlg;
2569     int ret = dlg.run();
2570     if (ret == Gtk::RESPONSE_OK)
2571         {
2572         Glib::ustring fontName = dlg.get_font_name();
2573         Pango::FontDescription fontDesc(fontName);
2574         modify_font(fontDesc);
2575         }
2578 void PedroGui::colorCallback()
2580     Gtk::ColorSelectionDialog dlg;
2581     int ret = dlg.run();
2582     if (ret == Gtk::RESPONSE_OK)
2583         {
2584         Gdk::Color col = dlg.get_colorsel()->get_current_color();
2585         modify_bg(Gtk::STATE_NORMAL, col);
2586         }
2589 void PedroGui::regPassCallback()
2591     PasswordDialog dlg(*this);
2592     int ret = dlg.run();
2593     if (ret == Gtk::RESPONSE_OK)
2594         {
2595         DOMString newpass = dlg.getNewPass();
2596         client.inBandRegistrationChangePassword(newpass);
2597         }
2601 void PedroGui::regCancelCallback()
2603     Gtk::MessageDialog dlg(*this, "Do you want to cancel your registration on the server?",
2604         false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true);
2605     int ret = dlg.run();
2606     if (ret == Gtk::RESPONSE_YES)
2607         {
2608         client.inBandRegistrationCancel();
2609         }
2614 void PedroGui::sendFileCallback()
2616     doSendFile("");
2621 void PedroGui::aboutCallback()
2623     Gtk::AboutDialog dlg;
2624     std::vector<Glib::ustring>authors;
2625     authors.push_back("Bob Jamison");
2626     dlg.set_authors(authors);
2627     DOMString comments = "A simple XMPP gui client  ";
2628     comments.append("Based on the Pedro XMPP client");
2629     dlg.set_comments(comments);
2630     dlg.set_version("1.0");
2631     dlg.run();
2636 void PedroGui::actionEnable(const DOMString &name, bool val)
2638     DOMString path = "/ui/MenuBar/";
2639     path.append(name);
2640     Glib::RefPtr<Gtk::Action> action = uiManager->get_action(path);
2641     if (!action)
2642         {
2643         path = "/ui/MenuBar/MenuFile/";
2644         path.append(name);
2645         action = uiManager->get_action(path);
2646         }
2647     if (!action)
2648         {
2649         path = "/ui/MenuBar/MenuEdit/";
2650         path.append(name);
2651         action = uiManager->get_action(path);
2652         }
2653     if (!action)
2654         {
2655         path = "/ui/MenuBar/MenuRegister/";
2656         path.append(name);
2657         action = uiManager->get_action(path);
2658         }
2659     if (!action)
2660         {
2661         path = "/ui/MenuBar/MenuTransfer/";
2662         path.append(name);
2663         action = uiManager->get_action(path);
2664         }
2665     if (!action)
2666         {
2667         path = "/ui/MenuBar/MenuHelp/";
2668         path.append(name);
2669         action = uiManager->get_action(path);
2670         }
2671     if (!action)
2672         return;
2673     action->set_sensitive(val);
2677 bool PedroGui::configLoad()
2679     if (!config.readFile("pedro.ini"))
2680         return false;
2681     return true;
2685 bool PedroGui::configSave()
2687     if (!config.writeFile("pedro.ini"))
2688         return false;
2689     return true;
2695 bool PedroGui::doSetup()
2697     configLoad();
2699     set_title("Pedro XMPP Client");
2700     set_size_request(500, 300);
2701     add(mainBox);
2703     Glib::RefPtr<Gtk::ActionGroup> actionGroup = Gtk::ActionGroup::create();
2705     //### FILE MENU
2706     actionGroup->add( Gtk::Action::create("MenuFile", "_File") );
2708     actionGroup->add( Gtk::Action::create("Connect",
2709                                   Gtk::Stock::CONNECT, "Connect"),
2710     sigc::mem_fun(*this, &PedroGui::connectCallback) );
2712     actionGroup->add( Gtk::Action::create("Chat",
2713                                   Gtk::Stock::CONNECT, "Chat"),
2714     sigc::mem_fun(*this, &PedroGui::chatCallback) );
2716     actionGroup->add( Gtk::Action::create("GroupChat",
2717                                   Gtk::Stock::CONNECT, "Group Chat"),
2718     sigc::mem_fun(*this, &PedroGui::groupChatCallback) );
2720     actionGroup->add( Gtk::Action::create("Disconnect",
2721                                   Gtk::Stock::DISCONNECT, "Disconnect"),
2722     sigc::mem_fun(*this, &PedroGui::disconnectCallback) );
2724     actionGroup->add( Gtk::Action::create("Quit", Gtk::Stock::QUIT),
2725     sigc::mem_fun(*this, &PedroGui::quitCallback) );
2727     //### EDIT MENU
2728     actionGroup->add( Gtk::Action::create("MenuEdit", "_Edit") );
2729     actionGroup->add( Gtk::Action::create("SelectFont",
2730                                   Gtk::Stock::SELECT_FONT, "Select Font"),
2731     sigc::mem_fun(*this, &PedroGui::fontCallback) );
2732     actionGroup->add( Gtk::Action::create("SelectColor",
2733                                   Gtk::Stock::SELECT_COLOR, "Select Color"),
2734     sigc::mem_fun(*this, &PedroGui::colorCallback) );
2736     //### REGISTER MENU
2737     actionGroup->add( Gtk::Action::create("MenuRegister", "_Registration") );
2738     actionGroup->add( Gtk::Action::create("RegPass",
2739                                   Gtk::Stock::DIALOG_AUTHENTICATION, "Change Password"),
2740     sigc::mem_fun(*this, &PedroGui::regPassCallback) );
2741     actionGroup->add( Gtk::Action::create("RegCancel",
2742                                   Gtk::Stock::CANCEL, "Cancel Registration"),
2743     sigc::mem_fun(*this, &PedroGui::regCancelCallback) );
2745     //### TRANSFER MENU
2746     actionGroup->add( Gtk::Action::create("MenuTransfer", "_Transfer") );
2747     actionGroup->add( Gtk::Action::create("SendFile",
2748                                   Gtk::Stock::NETWORK, "Send File"),
2749     sigc::mem_fun(*this, &PedroGui::sendFileCallback) );
2751     //### HELP MENU
2752     actionGroup->add( Gtk::Action::create("MenuHelp", "_Help") );
2753     actionGroup->add( Gtk::Action::create("About",
2754                                   Gtk::Stock::ABOUT, "About Pedro"),
2755     sigc::mem_fun(*this, &PedroGui::aboutCallback) );
2757     uiManager = Gtk::UIManager::create();
2759     uiManager->insert_action_group(actionGroup, 0);
2760     add_accel_group(uiManager->get_accel_group());
2762     Glib::ustring ui_info =
2763         "<ui>"
2764         "  <menubar name='MenuBar'>"
2765         "    <menu action='MenuFile'>"
2766         "      <menuitem action='Connect'/>"
2767         "      <separator/>"
2768         "      <menuitem action='Chat'/>"
2769         "      <menuitem action='GroupChat'/>"
2770         "      <separator/>"
2771         "      <menuitem action='Disconnect'/>"
2772         "      <menuitem action='Quit'/>"
2773         "    </menu>"
2774         "    <menu action='MenuEdit'>"
2775         "      <menuitem action='SelectFont'/>"
2776         "      <menuitem action='SelectColor'/>"
2777         "    </menu>"
2778         "    <menu action='MenuRegister'>"
2779         "      <menuitem action='RegPass'/>"
2780         "      <menuitem action='RegCancel'/>"
2781         "    </menu>"
2782         "    <menu action='MenuTransfer'>"
2783         "      <menuitem action='SendFile'/>"
2784         "    </menu>"
2785         "    <menu action='MenuHelp'>"
2786         "      <menuitem action='About'/>"
2787         "    </menu>"
2788         "  </menubar>"
2789         "</ui>";
2791     uiManager->add_ui_from_string(ui_info);
2792     Gtk::Widget* pMenuBar = uiManager->get_widget("/MenuBar");
2793     menuBarBox.pack_start(*pMenuBar, Gtk::PACK_SHRINK);
2795     padlockDisable();
2796     menuBarBox.pack_end(padlockIcon, Gtk::PACK_SHRINK);
2798     mainBox.pack_start(menuBarBox, Gtk::PACK_SHRINK);
2800     actionEnable("Connect",    true);
2801     actionEnable("Chat",       false);
2802     actionEnable("GroupChat",  false);
2803     actionEnable("Disconnect", false);
2804     actionEnable("RegPass",    false);
2805     actionEnable("RegCancel",  false);
2807     mainBox.pack_start(vPaned);
2808     vPaned.add1(roster);
2809     vPaned.add2(messageList);
2810     roster.setParent(this);
2812     show_all_children();
2814     //# Start a timer to check the queue every nn milliseconds
2815     Glib::signal_timeout().connect(
2816            sigc::mem_fun(*this, &PedroGui::checkEventQueue), 20 );
2818     //client.addXmppEventListener(*this);
2819     client.eventQueueEnable(true);
2821     return true;
2825 } // namespace Pedro
2829 //########################################################################
2830 //# E N D    O F     F I L E
2831 //########################################################################