pidgin/gtkdialogs.c

changeset 16238
33bf2fd32108
parent 12967
8e59b7aa8ae0
parent 16158
04028f467df0
equal deleted inserted replaced
13071:b98e72d4089a 16238:33bf2fd32108
1 /*
2 * @file gtkdialogs.c GTK+ Dialogs
3 * @ingroup gtkui
4 *
5 * pidgin
6 *
7 * Pidgin is the legal property of its developers, whose names are too numerous
8 * to list here. Please refer to the COPYRIGHT file distributed with this
9 * source distribution.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25 #include "internal.h"
26 #include "pidgin.h"
27
28 #include "debug.h"
29 #include "notify.h"
30 #include "prpl.h"
31 #include "request.h"
32 #include "util.h"
33
34 #include "gtkblist.h"
35 #include "gtkdialogs.h"
36 #include "gtkimhtml.h"
37 #include "gtkimhtmltoolbar.h"
38 #include "gtklog.h"
39 #include "gtkutils.h"
40 #include "pidginstock.h"
41
42 static GList *dialogwindows = NULL;
43
44 static GtkWidget *about = NULL;
45
46 struct _PidginGroupMergeObject {
47 PurpleGroup* parent;
48 char *new_name;
49 };
50
51 struct developer {
52 char *name;
53 char *role;
54 char *email;
55 };
56
57 struct translator {
58 char *language;
59 char *abbr;
60 char *name;
61 char *email;
62 };
63
64 struct artist {
65 char *name;
66 char *email;
67 };
68
69 /* Order: Lead Developer, then Alphabetical by Last Name */
70 static struct developer developers[] = {
71 {"Sean Egan", N_("lead developer"), "sean.egan@gmail.com"},
72 {"Daniel 'datallah' Atallah", N_("developer"), NULL},
73 {"Ethan 'Paco-Paco' Blanton", N_("developer"), NULL},
74 {"Thomas Butter", N_("developer"), NULL},
75 {"Sadrul Habib Chowdhury", N_("developer"), NULL},
76 {"Mark 'KingAnt' Doliner", N_("developer"), NULL},
77 {"Christian 'ChipX86' Hammond", N_("developer & webmaster"), NULL},
78 {"Gary 'grim' Kramlich", N_("developer"), NULL},
79 {"Richard 'rlaager' Laager", N_("developer"), NULL},
80 {"Richard 'wabz' Nelson", N_("developer"), NULL},
81 {"Christopher 'siege' O'Brien", N_("developer"), "taliesein@users.sf.net"},
82 {"Bartosz Oler", N_("developer"), NULL},
83 {"Etan 'deryni' Reisner", N_("developer"), NULL},
84 {"Tim 'marv' Ringenbach", N_("developer"), NULL},
85 {"Luke 'LSchiere' Schierer", N_("support"), "lschiere@users.sf.net"},
86 {"Megan 'Cae' Schneider", N_("support/QA"), NULL},
87 {"Evan Schoenberg", N_("developer"), NULL},
88 {"Stu 'nosnilmot' Tomlinson", N_("developer"), NULL},
89 {"Nathan 'faceprint' Walp", N_("developer"), NULL},
90 {NULL, NULL, NULL}
91 };
92
93 /* Order: Alphabetical by Last Name */
94 static struct developer patch_writers[] = {
95 {"Ka-Hing 'javabsp' Cheung", NULL, NULL},
96 {"Felipe 'shx' Contreras", NULL, NULL},
97 {"Decklin Foster", NULL, NULL},
98 {"Casey Harkins", NULL, NULL},
99 {"Peter 'Bleeter' Lawler", NULL, NULL},
100 {"Robert 'Robot101' McQueen", NULL, NULL},
101 {"Benjamin Miller", NULL, NULL},
102 {"Kevin 'SimGuy' Stange", NULL, NULL},
103 {NULL, NULL, NULL}
104 };
105
106 /* Order: Alphabetical by Last Name */
107 static struct developer retired_developers[] = {
108 {"Herman Bloggs", N_("win32 port"), "herman@bluedigits.com"},
109 {"Jim Duchek", N_("maintainer"), "jim@linuxpimps.com"},
110 {"Rob Flynn", N_("maintainer"), "purple@robflynn.com"},
111 {"Adam Fritzler", N_("libfaim maintainer"), NULL},
112 /* If "lazy bum" translates literally into a serious insult, use something else or omit it. */
113 {"Syd Logan", N_("hacker and designated driver [lazy bum]"), NULL},
114 {"Jim Seymour", N_("Jabber developer"), NULL},
115 {"Mark Spencer", N_("original author"), "markster@marko.net"},
116 {"Eric Warmenhoven", N_("lead developer"), "warmenhoven@yahoo.com"},
117 {NULL, NULL, NULL}
118 };
119
120 /* Order: Code, then Alphabetical by Last Name */
121 static struct translator current_translators[] = {
122 {N_("Afrikaans"), "af", "Friedel Wolff", "friedel@translate.org.za"},
123 {N_("Arabic"), "ar", "Mohamed Magdy", "alnokta@yahoo.com"},
124 {N_("Bulgarian"), "bg", "Vladimira Girginova", "missing@here.is"},
125 {N_("Bulgarian"), "bg", "Vladimir (Kaladan) Petkov", "vpetkov@i-space.org"},
126 {N_("Bengali"), "bn", "INDRANIL DAS GUPTA", "indradg@l2c2.org"},
127 {N_("Bengali"), "bn", "Jamil Ahmed", "jamil@bengalinux.org"},
128 {N_("Bengali"), "bn", "Samia Nimatullah", "mailsamia2001@yahoo.com"},
129 {N_("Bengali"), "bn", "Tisa Nafisa", "tisa_nafisa@yahoo.com"},
130 {N_("Bosnian"), "bs", "Lejla Hadzialic", "lejlah@gmail.com"},
131 {N_("Catalan"), "ca", "Josep Puigdemont", "josep.puigdemont@gmail.com"},
132 {N_("Valencian-Catalan"), "ca@valencia", "Toni Hermoso", "toniher@softcatala.org"},
133 {N_("Valencian-Catalan"), "ca@valencia", "Josep Puigdemont", "tradgnome@softcatala.org"},
134 {N_("Czech"), "cs", "Miloslav Trmac", "mitr@volny.cz"},
135 {N_("Danish"), "da", "Morten Brix Pedersen", "morten@wtf.dk"},
136 {N_("Danish"), "da", "Peter Bach", "bach.peter@gmail.com"},
137 {N_("German"), "de", "Björn Voigt", "bjoern@cs.tu-berlin.de"},
138 {N_("German"), "de", "Jochen Kemnade", "kemnade@gmail.com"},
139 {N_("Dzongkha"), "dz", "Norbu", "nor_den@hotmail.com"},
140 {N_("Dzongkha"), "dz", "Jurmey Rabgay", "jur_gay@yahoo.com"},
141 {N_("Dzongkha"), "dz", "Wangmo Sherpa", "rinwanshe@yahoo.com"},
142 {N_("Greek"), "el", "Katsaloulis Panayotis", "panayotis@panayotis.com"},
143 {N_("Greek"), "el", "Bouklis Panos", "panos@echidna-band.com"},
144 {N_("Australian English"), "en_AU", "Peter Lawler", "trans@six-by-nine.com.au"},
145 {N_("Canadian English"), "en_CA", "Adam Weinberger", "adamw@gnome.org"},
146 {N_("British English"), "en_GB", "Luke Ross", "lukeross@sys3175.co.uk"},
147 {N_("Esperanto"), "eo", "Stéphane Fillod", "fillods@users.sourceforge.net"},
148 {N_("Spanish"), "es", "Javier Fernández-Sanguino Peña", "jfs@debian.org"},
149 {N_("Euskera(Basque)"), "eu", "Hizkuntza Politikarako Sailburuordetza", "hizkpol@ej-gv.es"},
150 {N_("Euskera(Basque)"), "eu", "Iñaki Larrañaga Murgoitio", "dooteo@zundan.com"},
151 {N_("Persian"), "fa", "Elnaz Sarbar", "elnaz@farsiweb.info"},
152 {N_("Persian"), "fa", "Meelad Zakaria", "meelad@farsiweb.info"},
153 {N_("Persian"), "fa", "Roozbeh Pournader ", "roozbeh@farsiweb.info"},
154 {N_("Finnish"), "fi", "Timo Jyrinki", "timo.jyrinki@iki.fi"},
155 {N_("French"), "fr", "Éric Boumaour", "zongo_fr@users.sourceforge.net"},
156 {N_("Galician"), "gl", "Ignacio Casal Quinteiro", "nacho.resa@gmail.com"},
157 {N_("Gujarati"), "gu", "Ankit Patel", "ankit_patel@users.sf.net"},
158 {N_("Gujarati"), "gu", "Gujarati Language Team", "indianoss-gujarati@lists.sourceforge.net"},
159 {N_("Hebrew"), "he", "Shalom Craimer", "scraimer@gmail.com"},
160 {N_("Hindi"), "hi", "Ravishankar Shrivastava", "raviratlami@yahoo.com"},
161 {N_("Hungarian"), "hu", "Zoltan Sutto", "sutto.zoltan@rutinsoft.hu"},
162 {N_("Indonesian"), "id", "Rai S. Regawa", "raireg@yahoo.com"},
163 {N_("Italian"), "it", "Claudio Satriano", "satriano@na.infn.it"},
164 {N_("Japanese"), "ja", "Takashi Aihana", "aihana@gnome.gr.jp"},
165 {N_("Georgian"), "ka", "Ubuntu Georgian Translators", "alexander.didebulidze@stusta.mhn.de"},
166 {N_("Kannada"), "kn", "Kannada Translation team", "translation@sampada.info"},
167 {N_("Korean"), "ko", "Kyung-uk Son", "vvs740@chol.com"},
168 {N_("Kurdish"), "ku", "Erdal Ronahi", "erdal.ronahi@gmail.com"},
169 {N_("Kurdish"), "ku", "Amed Ç. Jiyan", "amedcj@hotmail.com"},
170 {N_("Kurdish"), "ku", "Rizoyê Xerzî", "rizoxerzi@hotmail.com"},
171 {N_("Lithuanian"), "lt", "Laurynas Biveinis", "laurynas.biveinis@gmail.com"},
172 {N_("Macedonian"), "mk", "Tomislav Markovski", "herrera@users.sf.net"},
173 {N_("Bokmål Norwegian"), "nb", "Hallvard Glad", "hallvard.glad@gmail.com"},
174 {N_("Nepali"), "ne", "Shyam Krishna Bal", "shyamkrishna_bal@yahoo.com"},
175 {N_("Dutch, Flemish"), "nl", "Vincent van Adrighem", "V.vanAdrighem@dirck.mine.nu"},
176 {N_("Norwegian"), "no", "Petter Johan Olsen", "petter.olsen@cc.uit.no"},
177 {N_("Polish"), "pl", "Emil Nowak", "emil5@go2.pl"},
178 {N_("Polish"), "pl", "Paweł Godlewski", "pawel@bajk.pl"},
179 {N_("Polish"), "pl", "Krzysztof Foltman", "krzysztof@foltman.com"},
180 {N_("Portuguese"), "pt", "Duarte Henriques", "duarte_henriques@myrealbox.com"},
181 {N_("Portuguese-Brazil"), "pt_BR", "Maurício de Lemos Rodrigues Collares Neto", "mauricioc@gmail.com"},
182 {N_("Pashto"), "ps", "Kashif Masood", "masudmails@yahoo.com"},
183 {N_("Romanian"), "ro", "Mişu Moldovan", "dumol@gnome.ro"},
184 {N_("Russian"), "ru", "Dmitry Beloglazov", "dmaa@users.sf.net"},
185 {N_("Slovak"), "sk", "Jozef Káčer", "quickparser@gmail.com"},
186 {N_("Slovak"), "sk", "loptosko", "loptosko@gmail.com"},
187 {N_("Slovenian"), "sl", "Martin Srebotnjak", "miles@filmsi.net"},
188 {N_("Albanian"), "sq", "Besnik Bleta", "besnik@programeshqip.org"},
189 {N_("Serbian"), "sr", "Danilo Šegan", "dsegan@gmx.net"},
190 {N_("Serbian"), "sr", "Aleksandar Urosevic", "urke@users.sourceforge.net"},
191 {N_("Swedish"), "sv", "Tore Lundqvist", "tlt@mima.x.se"},
192 {N_("Tamil"), "ta", "Viveka Nathan K", "vivekanathan@users.sourceforge.net"},
193 {N_("Telugu"), "te", "Mr. Subbaramaih", "info.gist@cdac.in"},
194 {N_("Thai"), "th", "Isriya Paireepairit", "markpeak@gmail.com"},
195 {N_("Turkish"), "tr", "Ahmet Alp BALKAN", "prf_q@users.sf.net"},
196 {N_("Vietnamese"), "vi", N_("T.M.Thanh and the Gnome-Vi Team"), "gnomevi-list@lists.sf.net"},
197 {N_("Simplified Chinese"), "zh_CN", "Funda Wang", "fundawang@linux.net.cn"},
198 {N_("Traditional Chinese"), "zh_TW", "Ambrose C. Li", "acli@ada.dhs.org"},
199 {N_("Traditional Chinese"), "zh_TW", "Paladin R. Liu", "paladin@ms1.hinet.net"},
200 {NULL, NULL, NULL, NULL}
201 };
202
203
204 static struct translator past_translators[] = {
205 {N_("Amharic"), "am", "Daniel Yacob", NULL},
206 {N_("Bulgarian"), "bg", "Hristo Todorov", NULL},
207 {N_("Catalan"), "ca", "JM Pérez Cáncer", NULL},
208 {N_("Catalan"), "ca", "Robert Millan", NULL},
209 {N_("Czech"), "cs", "Honza Král", NULL},
210 {N_("German"), "de", "Daniel Seifert, Karsten Weiss", NULL},
211 {N_("Spanish"), "es", "JM Pérez Cáncer", NULL},
212 {N_("Spanish"), "es", "Nicolás Lichtmaier", NULL},
213 {N_("Spanish"), "es", "Amaya Rodrigo", NULL},
214 {N_("Spanish"), "es", "Alejandro G Villar", NULL},
215 {N_("Finnish"), "fi", "Arto Alakulju", NULL},
216 {N_("Finnish"), "fi", "Tero Kuusela", NULL},
217 {N_("French"), "fr", "Sébastien François", NULL},
218 {N_("French"), "fr", "Stéphane Pontier", NULL},
219 {N_("French"), "fr", "Stéphane Wirtel", NULL},
220 {N_("French"), "fr", "Loïc Jeannin", NULL},
221 {N_("Hebrew"), "he", "Pavel Bibergal", NULL},
222 {N_("Italian"), "it", "Salvatore di Maggio", NULL},
223 {N_("Japanese"), "ja", "Ryosuke Kutsuna", NULL},
224 {N_("Japanese"), "ja", "Taku Yasui", NULL},
225 {N_("Japanese"), "ja", "Junichi Uekawa", NULL},
226 {N_("Georgian"), "ka", "Temuri Doghonadze", NULL},
227 {N_("Korean"), "ko", "Sang-hyun S, A Ho-seok Lee", NULL},
228 {N_("Lithuanian"), "lt", "Andrius Štikonas", NULL},
229 {N_("Lithuanian"), "lt", "Gediminas Čičinskas", NULL},
230 {N_("Polish"), "pl", "Przemysław Sułek", NULL},
231 {N_("Russian"), "ru", "Alexandre Prokoudine", NULL},
232 {N_("Russian"), "ru", "Sergey Volozhanin", NULL},
233 {N_("Slovak"), "sk", "Daniel Režný", NULL},
234 {N_("Slovak"), "sk", "helix84", "helix84@centrum.sk"},
235 {N_("Slovak"), "sk", "Richard Golier", "golierr@gmail.com"},
236 {N_("Slovenian"), "sl", "Matjaz Horvat", NULL},
237 {N_("Swedish"), "sv", "Christian Rose", NULL},
238 {N_("Simplified Chinese"), "zh_CN", "Hashao, Rocky S. Lee", NULL},
239 {N_("Traditional Chinese"), "zh_TW", "Hashao, Rocky S. Lee", NULL},
240 {NULL, NULL, NULL, NULL}
241 };
242
243 static struct artist artists[] = {
244 {"Hylke Bons", "h.bons@student.rug.nl"},
245 {NULL, NULL}
246 };
247
248 void
249 pidgindialogs_destroy_all()
250 {
251 while (dialogwindows) {
252 gtk_widget_destroy(dialogwindows->data);
253 dialogwindows = g_list_remove(dialogwindows, dialogwindows->data);
254 }
255 }
256
257 static void destroy_about()
258 {
259 if (about != NULL)
260 gtk_widget_destroy(about);
261 about = NULL;
262 }
263
264 /* This function puts the version number onto the pixmap we use in the 'about'
265 * screen in Purple. */
266 static void
267 pidgin_logo_versionize(GdkPixbuf **original, GtkWidget *widget) {
268 GdkPixmap *pixmap;
269 GtkStyle *style;
270 PangoContext *context;
271 PangoLayout *layout;
272 gchar *markup;
273 gint width, height;
274 gint lwidth = 0, lheight = 0;
275
276 style = gtk_widget_get_style(widget);
277
278 gdk_pixbuf_render_pixmap_and_mask(*original, &pixmap, NULL, 255);
279 width = gdk_pixbuf_get_width(*original);
280 height = gdk_pixbuf_get_height(*original);
281 g_object_unref(G_OBJECT(*original));
282
283 context = gtk_widget_get_pango_context(widget);
284 layout = pango_layout_new(context);
285
286 markup = g_strdup_printf("<span foreground=\"#FFFFFF\" size=\"larger\">%s</span>", VERSION);
287 pango_layout_set_font_description(layout, style->font_desc);
288 pango_layout_set_markup(layout, markup, strlen(markup));
289 g_free(markup);
290
291 pango_layout_get_pixel_size(layout, &lwidth, &lheight);
292 gdk_draw_layout(GDK_DRAWABLE(pixmap), style->bg_gc[GTK_STATE_NORMAL],
293 width - (lwidth + 3), height - (lheight + 1), layout);
294 g_object_unref(G_OBJECT(layout));
295
296 *original = gdk_pixbuf_get_from_drawable(NULL, pixmap, NULL,
297 0, 0, 0, 0,
298 width, height);
299 g_object_unref(G_OBJECT(pixmap));
300 }
301
302 void pidgindialogs_about()
303 {
304 GtkWidget *hbox;
305 GtkWidget *vbox;
306 GtkWidget *logo;
307 GtkWidget *frame;
308 GtkWidget *text;
309 GtkWidget *bbox;
310 GtkWidget *button;
311 GtkTextIter iter;
312 GString *str;
313 int i;
314 AtkObject *obj;
315 char* filename, *tmp;
316 GdkPixbuf *pixbuf;
317
318 if (about != NULL) {
319 gtk_window_present(GTK_WINDOW(about));
320 return;
321 }
322
323 PIDGIN_DIALOG(about);
324 tmp = g_strdup_printf(_("About %s"), PIDGIN_NAME);
325 gtk_window_set_title(GTK_WINDOW(about), tmp);
326 g_free(tmp);
327 gtk_window_set_role(GTK_WINDOW(about), "about");
328 gtk_window_set_resizable(GTK_WINDOW(about), TRUE);
329 gtk_window_set_default_size(GTK_WINDOW(about), 340, 450);
330
331 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
332 gtk_container_set_border_width(GTK_CONTAINER(hbox), PIDGIN_HIG_BORDER);
333 gtk_container_add(GTK_CONTAINER(about), hbox);
334
335 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER);
336 gtk_container_add(GTK_CONTAINER(hbox), vbox);
337
338 /* Generate a logo with a version number */
339 logo = gtk_window_new(GTK_WINDOW_TOPLEVEL);
340 gtk_widget_realize(logo);
341 filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "logo.png", NULL);
342 pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
343 g_free(filename);
344 pidgin_logo_versionize(&pixbuf, logo);
345 gtk_widget_destroy(logo);
346 logo = gtk_image_new_from_pixbuf(pixbuf);
347 gdk_pixbuf_unref(pixbuf);
348 /* Insert the logo */
349 obj = gtk_widget_get_accessible(logo);
350 atk_object_set_description(obj, PIDGIN_NAME " " VERSION);
351 gtk_box_pack_start(GTK_BOX(vbox), logo, FALSE, FALSE, 0);
352
353 frame = pidgin_create_imhtml(FALSE, &text, NULL, NULL);
354 gtk_imhtml_set_format_functions(GTK_IMHTML(text), GTK_IMHTML_ALL ^ GTK_IMHTML_SMILEY);
355 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
356
357 str = g_string_sized_new(4096);
358
359 g_string_append_printf(str,
360 _("%s is a modular messaging client capable of using "
361 "AIM, MSN, Yahoo!, Jabber, ICQ, IRC, SILC, SIP/SIMPLE, "
362 "Novell GroupWise, Lotus Sametime, Bonjour, Zephyr, "
363 "Gadu-Gadu, and QQ all at once. "
364 "It is written using GTK+.<BR><BR>"
365 "You may modify and redistribute the program under "
366 "the terms of the GPL (version 2 or later). A copy of the GPL is "
367 "contained in the 'COPYING' file distributed with %s. "
368 "%s is copyrighted by its contributors. See the 'COPYRIGHT' "
369 "file for the complete list of contributors. We provide no "
370 "warranty for this program.<BR><BR>"), PIDGIN_NAME, PIDGIN_NAME, PIDGIN_NAME);
371
372 g_string_append(str, "<FONT SIZE=\"4\">URL:</FONT> <A HREF=\""
373 PURPLE_WEBSITE "\">" PURPLE_WEBSITE "</A><BR/><BR/>");
374 #ifdef _WIN32
375 g_string_append_printf(str, _("<FONT SIZE=\"4\">IRC:</FONT> "
376 "#pidgwin on irc.freenode.net<BR><BR>"));
377 #else
378 g_string_append_printf(str, _("<FONT SIZE=\"4\">IRC:</FONT> "
379 "#pidgin on irc.freenode.net<BR><BR>"));
380 #endif
381
382 /* Current Developers */
383 g_string_append_printf(str, "<FONT SIZE=\"4\">%s:</FONT><BR/>",
384 _("Current Developers"));
385 for (i = 0; developers[i].name != NULL; i++) {
386 if (developers[i].email != NULL) {
387 g_string_append_printf(str, " %s (%s) &lt;<a href=\"mailto:%s\">%s</a>&gt;<br/>",
388 developers[i].name, _(developers[i].role),
389 developers[i].email, developers[i].email);
390 } else {
391 g_string_append_printf(str, " %s (%s)<br/>",
392 developers[i].name, _(developers[i].role));
393 }
394 }
395 g_string_append(str, "<BR/>");
396
397 /* Crazy Patch Writers */
398 g_string_append_printf(str, "<FONT SIZE=\"4\">%s:</FONT><BR/>",
399 _("Crazy Patch Writers"));
400 for (i = 0; patch_writers[i].name != NULL; i++) {
401 if (patch_writers[i].email != NULL) {
402 g_string_append_printf(str, " %s &lt;<a href=\"mailto:%s\">%s</a>&gt;<br/>",
403 patch_writers[i].name,
404 patch_writers[i].email, patch_writers[i].email);
405 } else {
406 g_string_append_printf(str, " %s<br/>",
407 patch_writers[i].name);
408 }
409 }
410 g_string_append(str, "<BR/>");
411
412 /* Retired Developers */
413 g_string_append_printf(str, "<FONT SIZE=\"4\">%s:</FONT><BR/>",
414 _("Retired Developers"));
415 for (i = 0; retired_developers[i].name != NULL; i++) {
416 if (retired_developers[i].email != NULL) {
417 g_string_append_printf(str, " %s (%s) &lt;<a href=\"mailto:%s\">%s</a>&gt;<br/>",
418 retired_developers[i].name, _(retired_developers[i].role),
419 retired_developers[i].email, retired_developers[i].email);
420 } else {
421 g_string_append_printf(str, " %s (%s)<br/>",
422 retired_developers[i].name, _(retired_developers[i].role));
423 }
424 }
425 g_string_append(str, "<BR/>");
426
427 /* Artists */
428 g_string_append_printf(str, "<FONT SIZE=\"4\">%s:</FONT><BR/>",
429 _("Artists"));
430 for (i = 0; artists[i].name != NULL; i++) {
431 if (artists[i].email != NULL) {
432 g_string_append_printf(str, " %s &lt;<a href=\"mailto:%s\">%s</a>&gt;<br/>",
433 artists[i].name,
434 artists[i].email, artists[i].email);
435 } else {
436 g_string_append_printf(str, " %s<br/>",
437 artists[i].name);
438 }
439 }
440 g_string_append(str, "<BR/>");
441
442 /* Current Translators */
443 g_string_append_printf(str, "<FONT SIZE=\"4\">%s:</FONT><BR/>",
444 _("Current Translators"));
445 for (i = 0; current_translators[i].language != NULL; i++) {
446 if (current_translators[i].email != NULL) {
447 g_string_append_printf(str, " <b>%s (%s)</b> - %s &lt;<a href=\"mailto:%s\">%s</a>&gt;<br/>",
448 _(current_translators[i].language),
449 current_translators[i].abbr,
450 _(current_translators[i].name),
451 current_translators[i].email,
452 current_translators[i].email);
453 } else {
454 g_string_append_printf(str, " <b>%s (%s)</b> - %s<br/>",
455 _(current_translators[i].language),
456 current_translators[i].abbr,
457 _(current_translators[i].name));
458 }
459 }
460 g_string_append(str, "<BR/>");
461
462 /* Past Translators */
463 g_string_append_printf(str, "<FONT SIZE=\"4\">%s:</FONT><BR/>",
464 _("Past Translators"));
465 for (i = 0; past_translators[i].language != NULL; i++) {
466 if (past_translators[i].email != NULL) {
467 g_string_append_printf(str, " <b>%s (%s)</b> - %s &lt;<a href=\"mailto:%s\">%s</a>&gt;<br/>",
468 _(past_translators[i].language),
469 past_translators[i].abbr,
470 _(past_translators[i].name),
471 past_translators[i].email,
472 past_translators[i].email);
473 } else {
474 g_string_append_printf(str, " <b>%s (%s)</b> - %s<br/>",
475 _(past_translators[i].language),
476 past_translators[i].abbr,
477 _(past_translators[i].name));
478 }
479 }
480 g_string_append(str, "<BR/>");
481
482 g_string_append_printf(str, "<FONT SIZE=\"4\">%s</FONT><br/>", _("Debugging Information"));
483
484 /* The following primarly intented for user/developer interaction and thus
485 ought not be translated */
486
487 #ifdef CONFIG_ARGS /* win32 build doesn't use configure */
488 g_string_append(str, " <b>Arguments to <i>./configure</i>:</b> " CONFIG_ARGS "<br/>");
489 #endif
490
491 #ifndef _WIN32
492 #ifdef DEBUG
493 g_string_append(str, " <b>Print debugging messages:</b> Yes<br/>");
494 #else
495 g_string_append(str, " <b>Print debugging messages:</b> No<br/>");
496 #endif
497 #endif
498
499 #ifdef PURPLE_PLUGINS
500 g_string_append(str, " <b>Plugins:</b> Enabled<br/>");
501 #else
502 g_string_append(str, " <b>Plugins:</b> Disabled<br/>");
503 #endif
504
505 #ifdef HAVE_SSL
506 g_string_append(str, " <b>SSL:</b> " PIDGIN_NAME " was compiled with SSL support.<br/>");
507 #else
508 g_string_append(str, " <b>SSL:</b> " PIDGIN_NAME " was <b><i>NOT</i></b> compiled with any SSL support!<br/>");
509 #endif
510
511 /* This might be useful elsewhere too, but it is particularly useful for
512 * debugging stuff known to be GTK+/Glib bugs on Windows */
513 #ifdef _WIN32
514 g_string_append_printf(str, " <b>GTK+ Runtime:</b> %u.%u.%u<br/>"
515 " <b>Glib Runtime:</b> %u.%u.%u<br/>",
516 gtk_major_version, gtk_minor_version, gtk_micro_version,
517 glib_major_version, glib_minor_version, glib_micro_version);
518 #endif
519
520 g_string_append(str, "<br/> <b>Library Support</b><br/>");
521
522 #ifdef HAVE_CYRUS_SASL
523 g_string_append_printf(str, " <b>Cyrus SASL:</b> Enabled<br/>");
524 #else
525 g_string_append_printf(str, " <b>Cyrus SASL:</b> Disabled<br/>");
526 #endif
527
528 #ifndef _WIN32
529 #ifdef HAVE_DBUS
530 g_string_append_printf(str, " <b>D-Bus:</b> Enabled<br/>");
531 #else
532 g_string_append_printf(str, " <b>D-Bus:</b> Disabled<br/>");
533 #endif
534
535 #ifdef HAVE_EVOLUTION_ADDRESSBOOK
536 g_string_append_printf(str, " <b>Evolution Addressbook:</b> Enabled<br/>");
537 #else
538 g_string_append_printf(str, " <b>Evolution Addressbook:</b> Disabled<br/>");
539 #endif
540 #endif
541
542 #if defined(_WIN32) || defined(USE_INTERNAL_LIBGADU)
543 g_string_append(str, " <b>Gadu-Gadu library (libgadu):</b> Internal<br/>");
544 #else
545 #ifdef HAVE_LIBGADU
546 g_string_append(str, " <b>Gadu-Gadu library (libgadu):</b> Enabled<br/>");
547 #else
548 g_string_append(str, " <b>Gadu-Gadu library (libgadu):</b> Disabled<br/>");
549 #endif
550 #endif
551
552 #ifdef USE_GTKSPELL
553 g_string_append(str, " <b>GtkSpell:</b> Enabled<br/>");
554 #else
555 g_string_append(str, " <b>GtkSpell:</b> Disabled<br/>");
556 #endif
557
558 #ifdef HAVE_GNUTLS
559 g_string_append(str, " <b>GnuTLS:</b> Enabled<br/>");
560 #else
561 g_string_append(str, " <b>GnuTLS:</b> Disabled<br/>");
562 #endif
563
564 #ifndef _WIN32
565 #ifdef USE_GSTREAMER
566 g_string_append(str, " <b>GStreamer:</b> Enabled<br/>");
567 #else
568 g_string_append(str, " <b>GStreamer:</b> Disabled<br/>");
569 #endif
570 #endif
571
572 #ifndef _WIN32
573 #ifdef ENABLE_MONO
574 g_string_append(str, " <b>Mono:</b> Enabled<br/>");
575 #else
576 g_string_append(str, " <b>Mono:</b> Disabled<br/>");
577 #endif
578 #endif
579
580 #ifndef _WIN32
581 #ifdef HAVE_LIBNM
582 g_string_append(str, " <b>NetworkManager:</b> Enabled<br/>");
583 #else
584 g_string_append(str, " <b>NetworkManager:</b> Disabled<br/>");
585 #endif
586 #endif
587
588 #ifdef HAVE_NSS
589 g_string_append(str, " <b>Network Security Services (NSS):</b> Enabled<br/>");
590 #else
591 g_string_append(str, " <b>Network Security Services (NSS):</b> Disabled<br/>");
592 #endif
593
594 #ifdef HAVE_PERL
595 g_string_append(str, " <b>Perl:</b> Enabled<br/>");
596 #else
597 g_string_append(str, " <b>Perl:</b> Disabled<br/>");
598 #endif
599
600 #ifndef _WIN32
601 #ifdef HAVE_STARTUP_NOTIFICATION
602 g_string_append(str, " <b>Startup Notification:</b> Enabled<br/>");
603 #else
604 g_string_append(str, " <b>Startup Notification:</b> Disabled<br/>");
605 #endif
606 #endif
607
608 #ifdef HAVE_TCL
609 g_string_append(str, " <b>Tcl:</b> Enabled<br/>");
610 #else
611 g_string_append(str, " <b>Tcl:</b> Disabled<br/>");
612 #endif
613
614 #ifdef HAVE_TK
615 g_string_append(str, " <b>Tk:</b> Enabled<br/>");
616 #else
617 g_string_append(str, " <b>Tk:</b> Disabled<br/>");
618 #endif
619
620 #ifndef _WIN32
621 #ifdef USE_SM
622 g_string_append(str, " <b>X Session Management:</b> Enabled<br/>");
623 #else
624 g_string_append(str, " <b>X Session Management:</b> Disabled<br/>");
625 #endif
626
627 #ifdef USE_SCREENSAVER
628 g_string_append(str, " <b>XScreenSaver:</b> Enabled<br/>");
629 #else
630 g_string_append(str, " <b>XScreenSaver:</b> Disabled<br/>");
631 #endif
632
633 #ifdef LIBZEPHYR_EXT
634 g_string_append(str, " <b>Zephyr library (libzephyr):</b> External<br/>");
635 #else
636 g_string_append(str, " <b>Zephyr library (libzephyr):</b> Not External<br/>");
637 #endif
638
639 #ifdef ZEPHYR_USES_KERBEROS
640 g_string_append(str, " <b>Zephyr uses Kerberos:</b> Yes<br/>");
641 #else
642 g_string_append(str, " <b>Zephyr uses Kerberos:</b> No<br/>");
643 #endif
644 #endif
645
646 /* End of not to be translated section */
647
648 gtk_imhtml_append_text(GTK_IMHTML(text), str->str, GTK_IMHTML_NO_SCROLL);
649 g_string_free(str, TRUE);
650
651 gtk_text_buffer_get_start_iter(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), &iter);
652 gtk_text_buffer_place_cursor(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), &iter);
653
654 /* Close Button */
655 bbox = gtk_hbutton_box_new();
656 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
657 gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
658
659 button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
660 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
661
662 g_signal_connect_swapped(G_OBJECT(button), "clicked",
663 G_CALLBACK(destroy_about), G_OBJECT(about));
664 g_signal_connect(G_OBJECT(about), "destroy",
665 G_CALLBACK(destroy_about), G_OBJECT(about));
666
667 /* this makes the sizes not work? */
668 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
669 gtk_widget_grab_default(button);
670
671 /* Let's give'em something to talk about -- woah woah woah */
672 gtk_widget_show_all(about);
673 gtk_window_present(GTK_WINDOW(about));
674 }
675
676 static void
677 pidgindialogs_im_cb(gpointer data, PurpleRequestFields *fields)
678 {
679 PurpleAccount *account;
680 const char *username;
681
682 account = purple_request_fields_get_account(fields, "account");
683 username = purple_request_fields_get_string(fields, "screenname");
684
685 pidgindialogs_im_with_user(account, username);
686 }
687
688 void
689 pidgindialogs_im(void)
690 {
691 PurpleRequestFields *fields;
692 PurpleRequestFieldGroup *group;
693 PurpleRequestField *field;
694
695 fields = purple_request_fields_new();
696
697 group = purple_request_field_group_new(NULL);
698 purple_request_fields_add_group(fields, group);
699
700 field = purple_request_field_string_new("screenname", _("_Name"), NULL, FALSE);
701 purple_request_field_set_type_hint(field, "screenname");
702 purple_request_field_set_required(field, TRUE);
703 purple_request_field_group_add_field(group, field);
704
705 field = purple_request_field_account_new("account", _("_Account"), NULL);
706 purple_request_field_set_type_hint(field, "account");
707 purple_request_field_set_visible(field,
708 (purple_connections_get_all() != NULL &&
709 purple_connections_get_all()->next != NULL));
710 purple_request_field_set_required(field, TRUE);
711 purple_request_field_group_add_field(group, field);
712
713 purple_request_fields(purple_get_blist(), _("New Instant Message"),
714 NULL,
715 _("Please enter the screen name or alias of the person "
716 "you would like to IM."),
717 fields,
718 _("OK"), G_CALLBACK(pidgindialogs_im_cb),
719 _("Cancel"), NULL,
720 NULL);
721 }
722
723 void
724 pidgindialogs_im_with_user(PurpleAccount *account, const char *username)
725 {
726 PurpleConversation *conv;
727
728 g_return_if_fail(account != NULL);
729 g_return_if_fail(username != NULL);
730
731 conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, username, account);
732
733 if (conv == NULL)
734 conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, username);
735
736 purple_conversation_present(conv);
737 }
738
739 static gboolean
740 pidgindialogs_ee(const char *ee)
741 {
742 GtkWidget *window;
743 GtkWidget *hbox;
744 GtkWidget *label;
745 GtkWidget *img;
746 gchar *norm = purple_strreplace(ee, "rocksmyworld", "");
747
748 label = gtk_label_new(NULL);
749 if (!strcmp(norm, "zilding"))
750 gtk_label_set_markup(GTK_LABEL(label),
751 "<span weight=\"bold\" size=\"large\" foreground=\"purple\">Amazing! Simply Amazing!</span>");
752 else if (!strcmp(norm, "robflynn"))
753 gtk_label_set_markup(GTK_LABEL(label),
754 "<span weight=\"bold\" size=\"large\" foreground=\"#1f6bad\">Pimpin\' Penguin Style! *Waddle Waddle*</span>");
755 else if (!strcmp(norm, "flynorange"))
756 gtk_label_set_markup(GTK_LABEL(label),
757 "<span weight=\"bold\" size=\"large\" foreground=\"blue\">You should be me. I'm so cute!</span>");
758 else if (!strcmp(norm, "ewarmenhoven"))
759 gtk_label_set_markup(GTK_LABEL(label),
760 "<span weight=\"bold\" size=\"large\" foreground=\"orange\">Now that's what I like!</span>");
761 else if (!strcmp(norm, "markster97"))
762 gtk_label_set_markup(GTK_LABEL(label),
763 "<span weight=\"bold\" size=\"large\" foreground=\"brown\">Ahh, and excellent choice!</span>");
764 else if (!strcmp(norm, "seanegn"))
765 gtk_label_set_markup(GTK_LABEL(label),
766 "<span weight=\"bold\" size=\"large\" foreground=\"#009900\">Everytime you click my name, an angel gets its wings.</span>");
767 else if (!strcmp(norm, "chipx86"))
768 gtk_label_set_markup(GTK_LABEL(label),
769 "<span weight=\"bold\" size=\"large\" foreground=\"red\">This sunflower seed taste like pizza.</span>");
770 else if (!strcmp(norm, "markdoliner"))
771 gtk_label_set_markup(GTK_LABEL(label),
772 "<span weight=\"bold\" size=\"large\" foreground=\"#6364B1\">Hey! I was in that tumbleweed!</span>");
773 else if (!strcmp(norm, "lschiere"))
774 gtk_label_set_markup(GTK_LABEL(label),
775 "<span weight=\"bold\" size=\"large\" foreground=\"gray\">I'm not anything.</span>");
776 g_free(norm);
777
778 if (strlen(gtk_label_get_label(GTK_LABEL(label))) <= 0)
779 return FALSE;
780
781 window = gtk_dialog_new_with_buttons(PIDGIN_ALERT_TITLE, NULL, 0, GTK_STOCK_CLOSE, GTK_RESPONSE_OK, NULL);
782 gtk_dialog_set_default_response (GTK_DIALOG(window), GTK_RESPONSE_OK);
783 g_signal_connect(G_OBJECT(window), "response", G_CALLBACK(gtk_widget_destroy), NULL);
784
785 gtk_container_set_border_width (GTK_CONTAINER(window), PIDGIN_HIG_BOX_SPACE);
786 gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
787 gtk_dialog_set_has_separator(GTK_DIALOG(window), FALSE);
788 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(window)->vbox), PIDGIN_HIG_BORDER);
789 gtk_container_set_border_width (GTK_CONTAINER(GTK_DIALOG(window)->vbox), PIDGIN_HIG_BOX_SPACE);
790
791 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
792 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->vbox), hbox);
793 img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_COOL, gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE));
794 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
795
796 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
797 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
798 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
799
800 gtk_widget_show_all(window);
801 return TRUE;
802 }
803
804 static void
805 pidgindialogs_info_cb(gpointer data, PurpleRequestFields *fields)
806 {
807 char *username;
808 gboolean found = FALSE;
809 PurpleAccount *account;
810
811 account = purple_request_fields_get_account(fields, "account");
812
813 username = g_strdup(purple_normalize(account,
814 purple_request_fields_get_string(fields, "screenname")));
815
816 if (username != NULL && purple_str_has_suffix(username, "rocksmyworld"))
817 found = pidgindialogs_ee(username);
818
819 if (!found && username != NULL && *username != '\0' && account != NULL)
820 serv_get_info(purple_account_get_connection(account), username);
821
822 g_free(username);
823 }
824
825 void
826 pidgindialogs_info(void)
827 {
828 PurpleRequestFields *fields;
829 PurpleRequestFieldGroup *group;
830 PurpleRequestField *field;
831
832 fields = purple_request_fields_new();
833
834 group = purple_request_field_group_new(NULL);
835 purple_request_fields_add_group(fields, group);
836
837 field = purple_request_field_string_new("screenname", _("_Name"), NULL, FALSE);
838 purple_request_field_set_type_hint(field, "screenname");
839 purple_request_field_set_required(field, TRUE);
840 purple_request_field_group_add_field(group, field);
841
842 field = purple_request_field_account_new("account", _("_Account"), NULL);
843 purple_request_field_set_type_hint(field, "account");
844 purple_request_field_set_visible(field,
845 (purple_connections_get_all() != NULL &&
846 purple_connections_get_all()->next != NULL));
847 purple_request_field_set_required(field, TRUE);
848 purple_request_field_group_add_field(group, field);
849
850 purple_request_fields(purple_get_blist(), _("Get User Info"),
851 NULL,
852 _("Please enter the screen name or alias of the person "
853 "whose info you would like to view."),
854 fields,
855 _("OK"), G_CALLBACK(pidgindialogs_info_cb),
856 _("Cancel"), NULL,
857 NULL);
858 }
859
860 static void
861 pidgindialogs_log_cb(gpointer data, PurpleRequestFields *fields)
862 {
863 char *username;
864 PurpleAccount *account;
865 GSList *cur;
866
867 account = purple_request_fields_get_account(fields, "account");
868
869 username = g_strdup(purple_normalize(account,
870 purple_request_fields_get_string(fields, "screenname")));
871
872 if (username != NULL && *username != '\0' && account != NULL)
873 {
874 PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist();
875 GSList *buddies;
876
877 pidgin_set_cursor(gtkblist->window, GDK_WATCH);
878
879 buddies = purple_find_buddies(account, username);
880 for (cur = buddies; cur != NULL; cur = cur->next)
881 {
882 PurpleBlistNode *node = cur->data;
883 if ((node != NULL) && ((node->prev != NULL) || (node->next != NULL)))
884 {
885 pidgin_log_show_contact((PurpleContact *)node->parent);
886 g_slist_free(buddies);
887 pidgin_clear_cursor(gtkblist->window);
888 g_free(username);
889 return;
890 }
891 }
892 g_slist_free(buddies);
893
894 pidgin_log_show(PURPLE_LOG_IM, username, account);
895
896 pidgin_clear_cursor(gtkblist->window);
897 }
898
899 g_free(username);
900 }
901
902 /*
903 * TODO - This needs to deal with logs of all types, not just IM logs.
904 */
905 void
906 pidgindialogs_log(void)
907 {
908 PurpleRequestFields *fields;
909 PurpleRequestFieldGroup *group;
910 PurpleRequestField *field;
911
912 fields = purple_request_fields_new();
913
914 group = purple_request_field_group_new(NULL);
915 purple_request_fields_add_group(fields, group);
916
917 field = purple_request_field_string_new("screenname", _("_Name"), NULL, FALSE);
918 purple_request_field_set_type_hint(field, "screenname-all");
919 purple_request_field_set_required(field, TRUE);
920 purple_request_field_group_add_field(group, field);
921
922 field = purple_request_field_account_new("account", _("_Account"), NULL);
923
924 /* purple_request_field_account_new() only sets a default value if you're
925 * connected, and it sets it from the list of connected accounts. Since
926 * we're going to set show_all here, it makes sense to use the first
927 * account, not the first connected account. */
928 if (purple_accounts_get_all() != NULL) {
929 purple_request_field_account_set_default_value(field, purple_accounts_get_all()->data);
930 purple_request_field_account_set_value(field, purple_accounts_get_all()->data);
931 }
932
933 purple_request_field_set_type_hint(field, "account");
934 purple_request_field_account_set_show_all(field, TRUE);
935 purple_request_field_set_visible(field,
936 (purple_accounts_get_all() != NULL &&
937 purple_accounts_get_all()->next != NULL));
938 purple_request_field_set_required(field, TRUE);
939 purple_request_field_group_add_field(group, field);
940
941 purple_request_fields(purple_get_blist(), _("View User Log"),
942 NULL,
943 _("Please enter the screen name or alias of the person "
944 "whose log you would like to view."),
945 fields,
946 _("OK"), G_CALLBACK(pidgindialogs_log_cb),
947 _("Cancel"), NULL,
948 NULL);
949 }
950
951 static void
952 pidgindialogs_alias_contact_cb(PurpleContact *contact, const char *new_alias)
953 {
954 purple_contact_set_alias(contact, new_alias);
955 }
956
957 void
958 pidgindialogs_alias_contact(PurpleContact *contact)
959 {
960 g_return_if_fail(contact != NULL);
961
962 purple_request_input(NULL, _("Alias Contact"), NULL,
963 _("Enter an alias for this contact."),
964 contact->alias, FALSE, FALSE, NULL,
965 _("Alias"), G_CALLBACK(pidgindialogs_alias_contact_cb),
966 _("Cancel"), NULL, contact);
967 }
968
969 static void
970 pidgindialogs_alias_buddy_cb(PurpleBuddy *buddy, const char *new_alias)
971 {
972 purple_blist_alias_buddy(buddy, new_alias);
973 serv_alias_buddy(buddy);
974 }
975
976 void
977 pidgindialogs_alias_buddy(PurpleBuddy *buddy)
978 {
979 gchar *secondary;
980
981 g_return_if_fail(buddy != NULL);
982
983 secondary = g_strdup_printf(_("Enter an alias for %s."), buddy->name);
984
985 purple_request_input(NULL, _("Alias Buddy"), NULL,
986 secondary, buddy->alias, FALSE, FALSE, NULL,
987 _("Alias"), G_CALLBACK(pidgindialogs_alias_buddy_cb),
988 _("Cancel"), NULL, buddy);
989
990 g_free(secondary);
991 }
992
993 static void
994 pidgindialogs_alias_chat_cb(PurpleChat *chat, const char *new_alias)
995 {
996 purple_blist_alias_chat(chat, new_alias);
997 }
998
999 void
1000 pidgindialogs_alias_chat(PurpleChat *chat)
1001 {
1002 g_return_if_fail(chat != NULL);
1003
1004 purple_request_input(NULL, _("Alias Chat"), NULL,
1005 _("Enter an alias for this chat."),
1006 chat->alias, FALSE, FALSE, NULL,
1007 _("Alias"), G_CALLBACK(pidgindialogs_alias_chat_cb),
1008 _("Cancel"), NULL, chat);
1009 }
1010
1011 static void
1012 pidgindialogs_remove_contact_cb(PurpleContact *contact)
1013 {
1014 PurpleBlistNode *bnode, *cnode;
1015 PurpleGroup *group;
1016
1017 cnode = (PurpleBlistNode *)contact;
1018 group = (PurpleGroup*)cnode->parent;
1019 for (bnode = cnode->child; bnode; bnode = bnode->next) {
1020 PurpleBuddy *buddy = (PurpleBuddy*)bnode;
1021 if (purple_account_is_connected(buddy->account))
1022 purple_account_remove_buddy(buddy->account, buddy, group);
1023 }
1024 purple_blist_remove_contact(contact);
1025 }
1026
1027 void
1028 pidgindialogs_remove_contact(PurpleContact *contact)
1029 {
1030 PurpleBuddy *buddy = purple_contact_get_priority_buddy(contact);
1031
1032 g_return_if_fail(contact != NULL);
1033 g_return_if_fail(buddy != NULL);
1034
1035 if (((PurpleBlistNode*)contact)->child == (PurpleBlistNode*)buddy &&
1036 !((PurpleBlistNode*)buddy)->next) {
1037 pidgindialogs_remove_buddy(buddy);
1038 } else {
1039 gchar *text;
1040 text = g_strdup_printf(
1041 ngettext(
1042 "You are about to remove the contact containing %s "
1043 "and %d other buddy from your buddy list. Do you "
1044 "want to continue?",
1045 "You are about to remove the contact containing %s "
1046 "and %d other buddies from your buddy list. Do you "
1047 "want to continue?", contact->totalsize - 1),
1048 buddy->name, contact->totalsize - 1);
1049
1050 purple_request_action(contact, NULL, _("Remove Contact"), text, 0, contact, 2,
1051 _("_Remove Contact"), G_CALLBACK(pidgindialogs_remove_contact_cb),
1052 _("Cancel"), NULL);
1053
1054 g_free(text);
1055 }
1056 }
1057
1058 static void free_ggmo(struct _PidginGroupMergeObject *ggp)
1059 {
1060 g_free(ggp->new_name);
1061 g_free(ggp);
1062 }
1063
1064 static void
1065 pidgindialogs_merge_groups_cb(struct _PidginGroupMergeObject *GGP)
1066 {
1067 purple_blist_rename_group(GGP->parent, GGP->new_name);
1068 free_ggmo(GGP);
1069 }
1070
1071 void
1072 pidgindialogs_merge_groups(PurpleGroup *source, const char *new_name)
1073 {
1074 gchar *text;
1075 struct _PidginGroupMergeObject *ggp;
1076
1077 g_return_if_fail(source != NULL);
1078 g_return_if_fail(new_name != NULL);
1079
1080 text = g_strdup_printf(
1081 _("You are about to merge the group called %s into the group "
1082 "called %s. Do you want to continue?"), source->name, new_name);
1083
1084 ggp = g_new(struct _PidginGroupMergeObject, 1);
1085 ggp->parent = source;
1086 ggp->new_name = g_strdup(new_name);
1087
1088 purple_request_action(source, NULL, _("Merge Groups"), text, 0, ggp, 2,
1089 _("_Merge Groups"), G_CALLBACK(pidgindialogs_merge_groups_cb),
1090 _("Cancel"), G_CALLBACK(free_ggmo));
1091
1092 g_free(text);
1093 }
1094
1095 static void
1096 pidgindialogs_remove_group_cb(PurpleGroup *group)
1097 {
1098 PurpleBlistNode *cnode, *bnode;
1099
1100 cnode = ((PurpleBlistNode*)group)->child;
1101
1102 while (cnode) {
1103 if (PURPLE_BLIST_NODE_IS_CONTACT(cnode)) {
1104 bnode = cnode->child;
1105 cnode = cnode->next;
1106 while (bnode) {
1107 PurpleBuddy *buddy;
1108 if (PURPLE_BLIST_NODE_IS_BUDDY(bnode)) {
1109 buddy = (PurpleBuddy*)bnode;
1110 bnode = bnode->next;
1111 if (purple_account_is_connected(buddy->account)) {
1112 purple_account_remove_buddy(buddy->account, buddy, group);
1113 purple_blist_remove_buddy(buddy);
1114 }
1115 } else {
1116 bnode = bnode->next;
1117 }
1118 }
1119 } else if (PURPLE_BLIST_NODE_IS_CHAT(cnode)) {
1120 PurpleChat *chat = (PurpleChat *)cnode;
1121 cnode = cnode->next;
1122 if (purple_account_is_connected(chat->account))
1123 purple_blist_remove_chat(chat);
1124 } else {
1125 cnode = cnode->next;
1126 }
1127 }
1128
1129 purple_blist_remove_group(group);
1130 }
1131
1132 void
1133 pidgindialogs_remove_group(PurpleGroup *group)
1134 {
1135 gchar *text;
1136
1137 g_return_if_fail(group != NULL);
1138
1139 text = g_strdup_printf(_("You are about to remove the group %s and all its members from your buddy list. Do you want to continue?"),
1140 group->name);
1141
1142 purple_request_action(group, NULL, _("Remove Group"), text, 0, group, 2,
1143 _("_Remove Group"), G_CALLBACK(pidgindialogs_remove_group_cb),
1144 _("Cancel"), NULL);
1145
1146 g_free(text);
1147 }
1148
1149 /* XXX - Some of this should be moved into the core, methinks. */
1150 static void
1151 pidgindialogs_remove_buddy_cb(PurpleBuddy *buddy)
1152 {
1153 PurpleGroup *group;
1154 gchar *name;
1155 PurpleAccount *account;
1156
1157 group = purple_buddy_get_group(buddy);
1158 name = g_strdup(buddy->name); /* b->name is a crasher after remove_buddy */
1159 account = buddy->account;
1160
1161 purple_debug_info("blist", "Removing '%s' from buddy list.\n", buddy->name);
1162 /* TODO - Should remove from blist first... then call purple_account_remove_buddy()? */
1163 purple_account_remove_buddy(buddy->account, buddy, group);
1164 purple_blist_remove_buddy(buddy);
1165
1166 g_free(name);
1167 }
1168
1169 void
1170 pidgindialogs_remove_buddy(PurpleBuddy *buddy)
1171 {
1172 gchar *text;
1173
1174 g_return_if_fail(buddy != NULL);
1175
1176 text = g_strdup_printf(_("You are about to remove %s from your buddy list. Do you want to continue?"),
1177 buddy->name);
1178
1179 purple_request_action(buddy, NULL, _("Remove Buddy"), text, 0, buddy, 2,
1180 _("_Remove Buddy"), G_CALLBACK(pidgindialogs_remove_buddy_cb),
1181 _("Cancel"), NULL);
1182
1183 g_free(text);
1184 }
1185
1186 static void
1187 pidgindialogs_remove_chat_cb(PurpleChat *chat)
1188 {
1189 purple_blist_remove_chat(chat);
1190 }
1191
1192 void
1193 pidgindialogs_remove_chat(PurpleChat *chat)
1194 {
1195 const gchar *name;
1196 gchar *text;
1197
1198 g_return_if_fail(chat != NULL);
1199
1200 name = purple_chat_get_name(chat);
1201 text = g_strdup_printf(_("You are about to remove the chat %s from your buddy list. Do you want to continue?"),
1202 name ? name : "");
1203
1204 purple_request_action(chat, NULL, _("Remove Chat"), text, 0, chat, 2,
1205 _("_Remove Chat"), G_CALLBACK(pidgindialogs_remove_chat_cb),
1206 _("Cancel"), NULL);
1207
1208 g_free(text);
1209 }

mercurial