Set valid tool tip in Gnome applet when no transfer selected.
[doldaconnect.git] / clients / gnome-trans-applet / dolcon-trans-applet.c
CommitLineData
1a839140 1/*
2 * Dolda Connect - Modular multiuser Direct Connect-style client
302a2600 3 * Copyright (C) 2005 Fredrik Tolf <fredrik@dolda2000.com>
1a839140 4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18*/
19
d3372da9 20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23#include <string.h>
24#include <doldaconnect/uilib.h>
25#include <doldaconnect/utils.h>
26#include <panel-applet.h>
27#include <gtk/gtk.h>
28#include <time.h>
29
30#include "conduit.h"
31
32struct appletdata
33{
34 PanelApplet *applet;
35 GtkLabel *label;
36 GtkProgressBar *pbar;
37 GtkTooltips *tips;
38 gint tiptimeout;
39 struct conduit *conduit;
40 struct transfer *curdisplay;
41};
42
43static char *ctxtmenu =
44"<popup name='button3'>"
6431aca0 45" <menuitem name='Preferences' verb='dca_pref' _label='Preferences' pixtype='stock' pixname='gtk-properties' />"
46" <menuitem name='Cancel transfer' verb='dca_cancel' _label='Cancel transfer' pixtype='stock' pixname='gtk-cancel' />"
d3372da9 47"</popup>";
48
49static void run_pref_dialog(BonoboUIComponent *uic, gpointer data, const char *cname)
50{
51}
52
6431aca0 53static void cancel_transfer(BonoboUIComponent *uic, struct appletdata *data, const char *cname)
54{
55 if(data->conduit->iface->cancel != NULL)
56 data->conduit->iface->cancel(data->conduit, data->curdisplay);
57}
58
d3372da9 59static BonoboUIVerb ctxtmenuverbs[] =
60{
61 BONOBO_UI_VERB("dca_pref", run_pref_dialog),
0a5f2058 62 BONOBO_UI_VERB("dca_cancel", (void (*)(BonoboUIComponent*, gpointer, const char *))cancel_transfer),
d3372da9 63 BONOBO_UI_VERB_END
64};
65
66static gint reconncb(struct appletdata *data)
67{
68 condtryconn(data->conduit);
69 return(FALSE);
70}
71
72static gboolean updatetip(struct appletdata *data)
73{
74 int diff, speed, left;
75 time_t now;
76 char buf[256];
77
0a5f2058
FT
78 if(data->curdisplay == NULL) {
79 gtk_tooltips_set_tip(data->tips, GTK_WIDGET(data->applet), _("No transfer selected"), NULL);
d3372da9 80 return(TRUE);
0a5f2058 81 }
d3372da9 82 now = time(NULL);
83 if(data->curdisplay->cmptime == 0)
84 {
85 strcpy(buf, _("Calculating remaining time..."));
86 } else {
87 diff = data->curdisplay->pos - data->curdisplay->cmpsize;
88 speed = diff / (now - data->curdisplay->cmptime);
89 if(speed == 0)
90 {
91 strcpy(buf, _("Time left: Infinite (Transfer is standing still)"));
92 } else {
93 left = (data->curdisplay->size - data->curdisplay->pos) / speed;
94 sprintf(buf, _("Time left: %i:%02i"), left / 3600, (left / 60) % 60);
95 }
96 }
97 gtk_tooltips_set_tip(data->tips, GTK_WIDGET(data->applet), buf, NULL);
98 return(TRUE);
99}
100
101static void update(struct appletdata *data)
102{
103 char buf[256];
daa53556 104 size_t l;
d3372da9 105
106 switch(data->conduit->state)
107 {
108 case CNDS_IDLE:
109 gtk_progress_bar_set_text(data->pbar, _("Not connected"));
110 gtk_label_set_text(data->label, "");
111 break;
112 case CNDS_SYN:
113 gtk_progress_bar_set_text(data->pbar, _("Connecting..."));
114 gtk_label_set_text(data->label, "");
115 break;
116 case CNDS_EST:
117 if(data->conduit->transfers == NULL)
118 {
119 gtk_progress_bar_set_fraction(data->pbar, 0);
120 gtk_progress_bar_set_text(data->pbar, "");
121 gtk_label_set_text(data->label, _("No transfers to display"));
122 } else if(data->curdisplay == NULL) {
123 gtk_progress_bar_set_fraction(data->pbar, 0);
124 gtk_progress_bar_set_text(data->pbar, "");
125 gtk_label_set_text(data->label, _("No transfer selected"));
126 } else {
127 if((data->curdisplay->pos > 0) && (data->curdisplay->size > 0))
128 {
129 sprintf(buf, "%'i/%'i", data->curdisplay->pos, data->curdisplay->size);
130 gtk_progress_bar_set_fraction(data->pbar, (double)data->curdisplay->pos / (double)data->curdisplay->size);
131 gtk_progress_bar_set_text(data->pbar, buf);
132 } else {
133 gtk_progress_bar_set_fraction(data->pbar, 0);
134 gtk_progress_bar_set_text(data->pbar, _("Initializing"));
135 }
daa53556 136 if((l = strlen(data->curdisplay->tag)) > 50) {
137 memcpy(buf, data->curdisplay->tag, 20);
138 memcpy(buf + 20, "...", 3);
139 memcpy(buf + 23 , data->curdisplay->tag + l - 20, 20);
140 buf[43] = 0;
141 gtk_label_set_text(data->label, buf);
142 } else {
143 gtk_label_set_text(data->label, data->curdisplay->tag);
144 }
d3372da9 145 }
146 break;
147 }
148}
149
150static void trsize(struct transfer *transfer, struct appletdata *data)
151{
152 update(data);
153}
154
155static void trpos(struct transfer *transfer, struct appletdata *data)
156{
157 update(data);
158}
159
160static void trnew(struct transfer *transfer, struct appletdata *data)
161{
162 if(data->curdisplay == NULL)
163 data->curdisplay = transfer;
164 update(data);
165}
166
167static void trfree(struct transfer *transfer, struct appletdata *data)
168{
169 if(data->curdisplay == transfer)
170 data->curdisplay = data->conduit->transfers;
171 update(data);
172}
173
174static void condstate(struct conduit *conduit, struct appletdata *data)
175{
176 if(conduit->state == CNDS_IDLE)
177 g_timeout_add(10000, (gboolean (*)(gpointer))reconncb, data);
178 update(data);
179}
180
181static void initcond(void)
182{
183 static int inited = 0;
184
185 if(!inited)
186 {
187 cb_trsize = (void (*)(struct transfer *, void *))trsize;
188 cb_trpos = (void (*)(struct transfer *, void *))trpos;
189 cb_trnew = (void (*)(struct transfer *, void *))trnew;
190 cb_trfree = (void (*)(struct transfer *, void *))trfree;
191 cb_condstate = (void (*)(struct conduit *, void *))condstate;
192 inited = 1;
193 }
194}
195
196static gboolean trview_applet_button_press(GtkWidget *widget, GdkEventButton *event, struct appletdata *data)
197{
198 if(event->button == 1)
199 {
200 if(data->curdisplay == NULL)
201 data->curdisplay = data->conduit->transfers;
202 else if(data->curdisplay->next == NULL)
203 data->curdisplay = data->conduit->transfers;
204 else
205 data->curdisplay = data->curdisplay->next;
206 update(data);
207 }
208 return(FALSE);
209}
210
d55bc1df 211static gboolean trview_applet_scroll(GtkWidget *widget, GdkEventScroll *event, struct appletdata *data)
212{
213 struct transfer *tr;
214
215 if(event->direction == GDK_SCROLL_DOWN)
216 {
217 if(data->curdisplay == NULL)
218 data->curdisplay = data->conduit->transfers;
219 else if(data->curdisplay->next == NULL)
220 data->curdisplay = data->conduit->transfers;
221 else
222 data->curdisplay = data->curdisplay->next;
223 update(data);
224 } else if(event->direction == GDK_SCROLL_UP) {
225 if(data->curdisplay == NULL)
226 {
227 data->curdisplay = data->conduit->transfers;
228 } else if(data->curdisplay->prev == NULL) {
229 for(tr = data->conduit->transfers; tr->next != NULL; tr = tr->next);
230 data->curdisplay = tr;
231 } else {
232 data->curdisplay = data->curdisplay->prev;
233 }
234 update(data);
235 }
236 return(TRUE);
237}
238
d3372da9 239static void trview_applet_destroy(GtkWidget *widget, struct appletdata *data)
240{
241 freeconduit(data->conduit);
242 g_source_remove(data->tiptimeout);
243 g_object_unref(data->applet);
244 g_object_unref(data->tips);
245 free(data);
246}
247
248static gboolean trview_applet_fill(PanelApplet *applet, const gchar *iid, gpointer uudata)
249{
250 GtkWidget *hbox, *pbar, *label;
251 struct appletdata *data;
252
253 initcond();
254 if(strcmp(iid, "OAFIID:Dolcon_Transferapplet"))
255 return(FALSE);
256
d3372da9 257 hbox = gtk_hbox_new(FALSE, 0);
258 label = gtk_label_new("");
259 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
260 pbar = gtk_progress_bar_new();
261 gtk_box_pack_start(GTK_BOX(hbox), pbar, TRUE, TRUE, 0);
262 gtk_container_add(GTK_CONTAINER(applet), hbox);
263 gtk_widget_show_all(GTK_WIDGET(applet));
264
265 data = smalloc(sizeof(*data));
266 memset(data, 0, sizeof(*data));
267 g_object_ref(data->applet = applet);
268 data->conduit = newconduit(conduit_dclib, data);
269 data->pbar = GTK_PROGRESS_BAR(pbar);
270 g_object_ref(data->tips = gtk_tooltips_new());
271 data->tiptimeout = g_timeout_add(500, (gboolean (*)(gpointer))updatetip, data);
272 data->label = GTK_LABEL(label);
273
6431aca0 274 panel_applet_setup_menu(applet, ctxtmenu, ctxtmenuverbs, data);
275
d3372da9 276 g_signal_connect(applet, "button-press-event", (GCallback)trview_applet_button_press, data);
d55bc1df 277 g_signal_connect(applet, "scroll-event", (GCallback)trview_applet_scroll, data);
d3372da9 278 g_signal_connect(applet, "destroy", (GCallback)trview_applet_destroy, data);
279
280 condtryconn(data->conduit);
281
282 update(data);
283
284 return(TRUE);
285}
286
287#define GETTEXT_PACKAGE PACKAGE
288#define GNOMELOCALEDIR LOCALEDIR
289
290PANEL_APPLET_BONOBO_FACTORY("OAFIID:Dolcon_Transferapplet_Factory",
291 PANEL_TYPE_APPLET,
292 "Doldaconnect Transfer Viewer",
293 "0",
294 trview_applet_fill,
295 NULL);