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