1 /* logjam - a GTK client for LiveJournal.
2 * Copyright (C) 2000-2003 Evan Martin <evan@livejournal.com>
11 struct _ProgressWindow
{
13 GtkWidget
*parent
, *box
, *clientbox
;
14 GtkWidget
*titlelabel
, *label
, *progress
;
15 gboolean showing_error
;
18 ProgressWindowCancelFunc cancel_cb
;
19 gpointer cancel_cb_data
;
23 __attribute__ ((format(printf
, 2, 3))) void progress_window_show_error (ProgressWindow
*pw
, const char *fmt
, ...) {
28 g_vsnprintf(buf
, 1024, fmt
, ap
);
32 progress_window_set_title(pw
, _("Error"));
33 gtk_label_set_text(GTK_LABEL(pw
->label
), buf
);
34 throbber_stop(THROBBER(pw
->throbber
));
35 gtk_image_set_from_stock(GTK_IMAGE(pw
->throbber
), GTK_STOCK_DIALOG_ERROR
, GTK_ICON_SIZE_DIALOG
);
36 gtk_widget_hide(pw
->progress
);
38 gtk_widget_hide(pw
->clientbox
);
39 pw
->showing_error
= TRUE
;
42 g_print(_("Error: %s\n"), buf
);
47 static void cancel_cb (ProgressWindow
*pw
) {
48 if (pw
->showing_error
) gtk_main_quit();
49 else if (pw
->cancel_cb
) pw
->cancel_cb(pw
->cancel_cb_data
);
53 static void destroy_cb (GtkWidget
*w
, ProgressWindow
*pw
) {
54 throbber_stop(THROBBER(pw
->throbber
));
55 if (pw
->parent
) g_signal_handlers_disconnect_matched(pw
->parent
, G_SIGNAL_MATCH_DATA
, 0, 0, 0, 0, pw
);
59 static gboolean
delete_event_cb (GtkWidget
*w
, GdkEvent
*e
, ProgressWindow
*pw
) {
61 return TRUE
; /* don't destroy us. */
65 static void reposition (ProgressWindow
*pw
, gint w
, gint h
) {
66 gint ox
, oy
, px
, py
, x
, y
;
67 if (!pw
->parent
) return;
68 gdk_window_get_origin(pw
->parent
->window
, &px
, &py
);
69 if (w
== -1) w
= GTK_WIDGET(pw
)->allocation
.width
;
70 if (h
== -1) h
= GTK_WIDGET(pw
)->allocation
.height
;
71 x
= px
+(pw
->parent
->allocation
.width
-w
)/2;
72 y
= py
+(pw
->parent
->allocation
.height
-h
)/2;
73 gdk_window_get_origin(GTK_WIDGET(pw
)->window
, &ox
, &oy
);
74 if (x
!= ox
|| y
!= oy
) gtk_window_move(GTK_WINDOW(pw
), x
, y
);
78 static gboolean
parent_configure_cb (GtkWidget
*w
, GdkEvent
*e
, ProgressWindow
*pw
) {
79 reposition(pw
, -1, -1);
84 static gboolean
configure_cb (GtkWidget
*w
, GdkEventConfigure
*e
, ProgressWindow
*pw
) {
85 if (GTK_WIDGET(pw
)->allocation
.width
!= e
->width
|| GTK_WIDGET(pw
)->allocation
.height
!= e
->height
) reposition(pw
, e
->width
, e
->height
);
90 static void progress_window_set_parent (ProgressWindow
*pw
, GtkWindow
*parent
) {
91 pw
->parent
= GTK_WIDGET(parent
);
92 gtk_window_set_transient_for(GTK_WINDOW(pw
), parent
);
93 g_signal_connect(G_OBJECT(parent
), "configure-event", G_CALLBACK(parent_configure_cb
), pw
);
97 static void progress_window_init (ProgressWindow
*pw
) {
100 GtkWidget
*hbox
, *align
, *bbox
, *button
, *lbox
;
102 gtk_window_set_decorated(GTK_WINDOW(pw
), FALSE
);
103 gtk_window_set_type_hint(GTK_WINDOW(pw
), GDK_WINDOW_TYPE_HINT_DIALOG
);
104 gtk_window_set_modal(GTK_WINDOW(pw
), TRUE
);
105 gtk_window_set_default_size(GTK_WINDOW(pw
), 250, -1);
106 g_signal_connect(G_OBJECT(pw
), "destroy", G_CALLBACK(destroy_cb
), pw
);
107 g_signal_connect(G_OBJECT(pw
), "delete-event", G_CALLBACK(delete_event_cb
), pw
);
108 gtk_window_set_position(GTK_WINDOW(pw
), GTK_WIN_POS_CENTER_ON_PARENT
);
109 g_signal_connect(G_OBJECT(pw
), "configure-event", G_CALLBACK(configure_cb
), pw
);
111 vbox
= gtk_vbox_new(FALSE
, 6);
112 gtk_container_set_border_width(GTK_CONTAINER(vbox
), 6);
114 hbox
= gtk_hbox_new(FALSE
, 6);
116 pw
->throbber
= throbber_new();
117 align
= gtk_alignment_new(0.5, 0, 0, 0);
118 gtk_container_add(GTK_CONTAINER(align
), pw
->throbber
);
119 gtk_box_pack_start(GTK_BOX(hbox
), align
, FALSE
, FALSE
, 0);
120 throbber_start(THROBBER(pw
->throbber
));
122 pw
->box
= lbox
= gtk_vbox_new(FALSE
, 6);
123 pw
->titlelabel
= gtk_label_new(NULL
);
124 gtk_box_pack_start(GTK_BOX(lbox
), pw
->titlelabel
, TRUE
, TRUE
, 0);
126 pw
->label
= gtk_label_new(NULL
);
127 gtk_label_set_line_wrap(GTK_LABEL(pw
->label
), TRUE
);
128 gtk_box_pack_start(GTK_BOX(lbox
), pw
->label
, TRUE
, TRUE
, 0);
130 pw
->progress
= gtk_progress_bar_new();
131 gtk_box_pack_end(GTK_BOX(lbox
), pw
->progress
, FALSE
, FALSE
, 0);
133 gtk_box_pack_start(GTK_BOX(hbox
), lbox
, TRUE
, TRUE
, 0);
135 gtk_box_pack_start(GTK_BOX(vbox
), hbox
, TRUE
, TRUE
, 0);
137 bbox
= gtk_hbutton_box_new();
138 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox
), GTK_BUTTONBOX_END
);
139 button
= gtk_button_new_from_stock(GTK_STOCK_CANCEL
);
140 g_signal_connect_swapped(G_OBJECT(button
), "clicked", G_CALLBACK(cancel_cb
), pw
);
141 gtk_box_pack_end(GTK_BOX(bbox
), button
, FALSE
, FALSE
, 0);
142 gtk_box_pack_start(GTK_BOX(vbox
), bbox
, FALSE
, FALSE
, 0);
144 frame
= gtk_frame_new(NULL
);
145 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_OUT
);
146 gtk_container_add(GTK_CONTAINER(frame
), vbox
);
147 gtk_widget_show_all(frame
);
148 gtk_widget_hide(pw
->progress
);
149 gtk_container_add(GTK_CONTAINER(pw
), frame
);
151 GTK_WIDGET_SET_FLAGS(button
, GTK_CAN_DEFAULT
);
152 gtk_widget_grab_default(button
);
156 void progress_window_pack (ProgressWindow
*pw
, GtkWidget
*contents
) {
157 if (!pw
->clientbox
) {
158 pw
->clientbox
= gtk_vbox_new(FALSE
, 6);
159 gtk_box_pack_start(GTK_BOX(pw
->box
), pw
->clientbox
, TRUE
, TRUE
, 0);
160 gtk_widget_show(pw
->clientbox
);
162 gtk_box_pack_start(GTK_BOX(pw
->clientbox
), contents
, FALSE
, FALSE
, 0);
166 void progress_window_set_title (ProgressWindow
*pw
, const char *title
) {
168 gtk_window_set_title(GTK_WINDOW(pw
), title
);
169 t
= (title
? g_strdup_printf("<b>%s</b>", title
) : g_strdup(""));
170 gtk_label_set_markup(GTK_LABEL(pw
->titlelabel
), t
);
175 void progress_window_set_text (ProgressWindow
*pw
, const char *text
) {
176 gtk_label_set_text(GTK_LABEL(pw
->label
), text
);
180 void progress_window_set_progress (ProgressWindow
*pw
, float frac
) {
181 if (frac
>= 0) gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pw
->progress
), frac
);
182 if (frac
> 0) gtk_widget_show(pw
->progress
); //else gtk_widget_hide(pw->progress);
186 void progress_window_set_cancel_cb (ProgressWindow
*pw
, ProgressWindowCancelFunc func
, gpointer data
) {
187 pw
->cancel_cb
= func
;
188 pw
->cancel_cb_data
= data
;
192 GtkWidget
*progress_window_new (GtkWindow
*parent
, const char *title
) {
193 ProgressWindow
*pw
= PROGRESS_WINDOW(g_object_new(progress_window_get_type(), NULL
));
194 if (parent
) progress_window_set_parent(pw
, parent
);
195 progress_window_set_title(pw
, title
);
196 return GTK_WIDGET(pw
);
200 GType
progress_window_get_type (void) {
201 static GType pw_type
= 0;
203 static const GTypeInfo pw_info
= {
204 sizeof(GtkWindowClass
),
207 NULL
, /*(GClassInitFunc) progress_window_class_init, */
210 sizeof(ProgressWindow
),
212 (GInstanceInitFunc
) progress_window_init
,
214 pw_type
= g_type_register_static(GTK_TYPE_WINDOW
, "ProgressWindow", &pw_info
, 0);