Transfer from CVS at SourceForge
[doldaconnect.git] / clients / gnome-trans-applet / dolcon-trans-applet.c
1 #ifdef HAVE_CONFIG_H
2 #include <config.h>
3 #endif
4 #include <string.h>
5 #include <doldaconnect/uilib.h>
6 #include <doldaconnect/utils.h>
7 #include <panel-applet.h>
8 #include <gtk/gtk.h>
9 #include <time.h>
10
11 #include "conduit.h"
12
13 struct appletdata
14 {
15     PanelApplet *applet;
16     GtkLabel *label;
17     GtkProgressBar *pbar;
18     GtkTooltips *tips;
19     gint tiptimeout;
20     struct conduit *conduit;
21     struct transfer *curdisplay;
22 };
23
24 static char *ctxtmenu =
25 "<popup name='button3'>"
26 "    <menuitem name='Preferences' verb='dca_pref' _label='Preferences' pixtype='stock' pixname='gtk-properties'>"
27 "    </menuitem>"
28 "</popup>";
29
30 static void run_pref_dialog(BonoboUIComponent *uic, gpointer data, const char *cname)
31 {
32 }
33
34 static BonoboUIVerb ctxtmenuverbs[] =
35 {
36     BONOBO_UI_VERB("dca_pref", run_pref_dialog),
37     BONOBO_UI_VERB_END
38 };
39
40 static gint reconncb(struct appletdata *data)
41 {
42     condtryconn(data->conduit);
43     return(FALSE);
44 }
45
46 static gboolean updatetip(struct appletdata *data)
47 {
48     int diff, speed, left;
49     time_t now;
50     char buf[256];
51     
52     if(data->curdisplay == NULL)
53         return(TRUE);
54     now = time(NULL);
55     if(data->curdisplay->cmptime == 0)
56     {
57         strcpy(buf, _("Calculating remaining time..."));
58     } else {
59         diff = data->curdisplay->pos - data->curdisplay->cmpsize;
60         speed = diff / (now - data->curdisplay->cmptime);
61         if(speed == 0)
62         {
63             strcpy(buf, _("Time left: Infinite (Transfer is standing still)"));
64         } else {
65             left = (data->curdisplay->size - data->curdisplay->pos) / speed;
66             sprintf(buf, _("Time left: %i:%02i"), left / 3600, (left / 60) % 60);
67         }
68     }
69     gtk_tooltips_set_tip(data->tips, GTK_WIDGET(data->applet), buf, NULL);
70     return(TRUE);
71 }
72
73 static void update(struct appletdata *data)
74 {
75     char buf[256];
76     
77     switch(data->conduit->state)
78     {
79     case CNDS_IDLE:
80         gtk_progress_bar_set_text(data->pbar, _("Not connected"));
81         gtk_label_set_text(data->label, "");
82         break;
83     case CNDS_SYN:
84         gtk_progress_bar_set_text(data->pbar, _("Connecting..."));
85         gtk_label_set_text(data->label, "");
86         break;
87     case CNDS_EST:
88         if(data->conduit->transfers == NULL)
89         {
90             gtk_progress_bar_set_fraction(data->pbar, 0);
91             gtk_progress_bar_set_text(data->pbar, "");
92             gtk_label_set_text(data->label, _("No transfers to display"));
93         } else if(data->curdisplay == NULL) {
94             gtk_progress_bar_set_fraction(data->pbar, 0);
95             gtk_progress_bar_set_text(data->pbar, "");
96             gtk_label_set_text(data->label, _("No transfer selected"));
97         } else {
98             if((data->curdisplay->pos > 0) && (data->curdisplay->size > 0))
99             {
100                 sprintf(buf, "%'i/%'i", data->curdisplay->pos, data->curdisplay->size);
101                 gtk_progress_bar_set_fraction(data->pbar, (double)data->curdisplay->pos / (double)data->curdisplay->size);
102                 gtk_progress_bar_set_text(data->pbar, buf);
103             } else {
104                 gtk_progress_bar_set_fraction(data->pbar, 0);
105                 gtk_progress_bar_set_text(data->pbar, _("Initializing"));
106             }
107             gtk_label_set_text(data->label, data->curdisplay->tag);
108         }
109         break;
110     }
111 }
112
113 static void trsize(struct transfer *transfer, struct appletdata *data)
114 {
115     update(data);
116 }
117
118 static void trpos(struct transfer *transfer, struct appletdata *data)
119 {
120     update(data);
121 }
122
123 static void trnew(struct transfer *transfer, struct appletdata *data)
124 {
125     if(data->curdisplay == NULL)
126         data->curdisplay = transfer;
127     update(data);
128 }
129
130 static void trfree(struct transfer *transfer, struct appletdata *data)
131 {
132     if(data->curdisplay == transfer)
133         data->curdisplay = data->conduit->transfers;
134     update(data);
135 }
136
137 static void condstate(struct conduit *conduit, struct appletdata *data)
138 {
139     if(conduit->state == CNDS_IDLE)
140         g_timeout_add(10000, (gboolean (*)(gpointer))reconncb, data);
141     update(data);
142 }
143
144 static void initcond(void)
145 {
146     static int inited = 0;
147     
148     if(!inited)
149     {
150         cb_trsize = (void (*)(struct transfer *, void *))trsize;
151         cb_trpos = (void (*)(struct transfer *, void *))trpos;
152         cb_trnew = (void (*)(struct transfer *, void *))trnew;
153         cb_trfree = (void (*)(struct transfer *, void *))trfree;
154         cb_condstate = (void (*)(struct conduit *, void *))condstate;
155         inited = 1;
156     }
157 }
158
159 static gboolean trview_applet_button_press(GtkWidget *widget, GdkEventButton *event, struct appletdata *data)
160 {
161     if(event->button == 1)
162     {
163         if(data->curdisplay == NULL)
164             data->curdisplay = data->conduit->transfers;
165         else if(data->curdisplay->next == NULL)
166             data->curdisplay = data->conduit->transfers;
167         else
168             data->curdisplay = data->curdisplay->next;
169         update(data);
170     }
171     return(FALSE);
172 }
173
174 static void trview_applet_destroy(GtkWidget *widget, struct appletdata *data)
175 {
176     freeconduit(data->conduit);
177     g_source_remove(data->tiptimeout);
178     g_object_unref(data->applet);
179     g_object_unref(data->tips);
180     free(data);
181 }
182
183 static gboolean trview_applet_fill(PanelApplet *applet, const gchar *iid, gpointer uudata)
184 {
185     GtkWidget *hbox, *pbar, *label;
186     struct appletdata *data;
187     
188     initcond();
189     if(strcmp(iid, "OAFIID:Dolcon_Transferapplet"))
190         return(FALSE);
191     
192     panel_applet_setup_menu(applet, ctxtmenu, ctxtmenuverbs, NULL);
193
194     hbox = gtk_hbox_new(FALSE, 0);
195     label = gtk_label_new("");
196     gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
197     pbar = gtk_progress_bar_new();
198     gtk_box_pack_start(GTK_BOX(hbox), pbar, TRUE, TRUE, 0);
199     gtk_container_add(GTK_CONTAINER(applet), hbox);
200     gtk_widget_show_all(GTK_WIDGET(applet));
201     
202     data = smalloc(sizeof(*data));
203     memset(data, 0, sizeof(*data));
204     g_object_ref(data->applet = applet);
205     data->conduit = newconduit(conduit_dclib, data);
206     data->pbar = GTK_PROGRESS_BAR(pbar);
207     g_object_ref(data->tips = gtk_tooltips_new());
208     data->tiptimeout = g_timeout_add(500, (gboolean (*)(gpointer))updatetip, data);
209     data->label = GTK_LABEL(label);
210     
211     g_signal_connect(applet, "button-press-event", (GCallback)trview_applet_button_press, data);
212     g_signal_connect(applet, "destroy", (GCallback)trview_applet_destroy, data);
213     
214     condtryconn(data->conduit);
215     
216     update(data);
217     
218     return(TRUE);
219 }
220
221 #define GETTEXT_PACKAGE PACKAGE
222 #define GNOMELOCALEDIR LOCALEDIR
223
224 PANEL_APPLET_BONOBO_FACTORY("OAFIID:Dolcon_Transferapplet_Factory",
225                             PANEL_TYPE_APPLET,
226                             "Doldaconnect Transfer Viewer",
227                             "0",
228                             trview_applet_fill,
229                             NULL);