1 // GTK_PROGRESS_DIALOG.CPP
2
3 // Copyright (C) 2005 Tommi Hassinen.
4
5 // This package 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 package 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 package; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 /*################################################################################################*/
20
21 #include "gtk_progress_dialog.h"
22
23 #include "local_i18n.h"
24
25 #include <gtk/gtk.h>
26
27 #include <sstream>
28 #include <iostream>
29 using namespace std;
30
31 /*################################################################################################*/
32
gtk_progress_dialog(const char * jobname,bool show_pbar,int graphs_n,int graphs_sz)33 gtk_progress_dialog::gtk_progress_dialog(const char * jobname, bool show_pbar, int graphs_n, int graphs_sz) :
34 gtk_glade_dialog("glade/gtk_progress_dialog.glade")
35 {
36 dialog = glade_xml_get_widget(xml, "progress_dialog");
37 if (dialog == NULL)
38 {
39 cout << _("WARNING : progress_dialog : glade_xml_get_widget() failed!!!") << endl;
40 return;
41 }
42
43 cancel = false;
44
45 g_n = graphs_n;
46 g_sz = graphs_sz;
47 g_fill = 0;
48
49 g_data = NULL;
50 if (g_n > 0 && g_sz > 0)
51 {
52 g_data = new double[g_n * g_sz];
53 }
54
55 // initialize the widgets...
56
57 entry_job = glade_xml_get_widget(xml, "entry_job");
58 drawingarea_job = glade_xml_get_widget(xml, "drawingarea_job");
59 progressbar_job = glade_xml_get_widget(xml, "progressbar_job");
60
61 gtk_entry_set_text(GTK_ENTRY(entry_job), jobname);
62
63 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progressbar_job), "Progress");
64 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar_job), 0.0);
65
66 // connect the handlers...
67
68 glade_xml_signal_connect_data(xml, "on_dialog_destroy", (GtkSignalFunc) handler_Destroy, (gpointer) this);
69 glade_xml_signal_connect_data(xml, "on_button_cancel_clicked", (GtkSignalFunc) handler_ButtonCancel, (gpointer) this);
70
71 if (graphs_n > 0)
72 {
73 gtk_widget_set_size_request(drawingarea_job, 100, 100);
74 g_signal_connect(G_OBJECT(drawingarea_job), "expose_event", G_CALLBACK(handler_ExposeEvent), this);
75
76 gtk_widget_show(drawingarea_job);
77 }
78 else
79 {
80 gtk_widget_hide(drawingarea_job);
81 }
82
83 if (show_pbar)
84 {
85 gtk_widget_show(progressbar_job);
86 }
87 else
88 {
89 gtk_widget_hide(progressbar_job);
90 }
91
92 // create the dialog as a modeless one (for threads).
93
94 // but it should behave like it were modal!!!
95 // THE USER SHOULD NOT HAVE ACCESS TO ANY (POPUP-)MENUS!!!
96
97 gtk_widget_show(dialog); // MODELESS
98
99 //////////////////////////////////////////////////
100 //gtk_dialog_run(GTK_DIALOG(dialog)); // MODAL
101 }
102
~gtk_progress_dialog(void)103 gtk_progress_dialog::~gtk_progress_dialog(void)
104 {
105 if (g_data != NULL)
106 {
107 delete[] g_data;
108 g_data = NULL;
109 }
110 }
111
handler_Destroy(GtkWidget *,gpointer data)112 void gtk_progress_dialog::handler_Destroy(GtkWidget *, gpointer data)
113 {
114 gtk_progress_dialog * ref = (gtk_progress_dialog *) data;
115 //cout << "handler_Destroy() : ref = " << ref << endl;
116 }
117
handler_ButtonCancel(GtkWidget *,gpointer data)118 void gtk_progress_dialog::handler_ButtonCancel(GtkWidget *, gpointer data)
119 {
120 gtk_progress_dialog * ref = (gtk_progress_dialog *) data;
121 //cout << "handler_ButtonCancel() : ref = " << ref << endl;
122
123 // just send a message that we want cancel the current operation.
124 // the dialog is closed elsewhere (automatically if not cancelled).
125
126 ref->cancel = true;
127 }
128
handler_ExposeEvent(GtkWidget * widget,GdkEventExpose * event,gpointer data)129 gboolean gtk_progress_dialog::handler_ExposeEvent(GtkWidget * widget, GdkEventExpose * event, gpointer data)
130 {
131 gtk_progress_dialog * ref = (gtk_progress_dialog *) data;
132 //cout << "handler_ExposeEvent() : ref = " << ref << endl;
133
134 // update the graphs...
135 // ^^^^^^^^^^^^^^^^^^^^
136 // what about thread safety issues here?
137 // it appears that the gdk_threads mechanism is enough...
138
139 ref->da_w = widget->allocation.width;
140 ref->da_h = widget->allocation.height;
141
142 // there is no need to blank the drawingarea???
143 // there is no need to blank the drawingarea???
144 // there is no need to blank the drawingarea???
145
146 const double dx = ref->da_w / ref->g_sz;
147
148 int sz = ref->g_fill;
149 if (sz > ref->g_sz) sz = ref->g_sz;
150
151 for (int i = 0;i < ref->g_n;i++)
152 {
153 // find the min and max values.
154
155 double min = ref->g_data[i * ref->g_sz + 0];
156 double max = min;
157
158 for (int f = 1;f < sz;f++)
159 {
160 double v = ref->g_data[i * ref->g_sz + f];
161
162 if (v < min) min = v;
163 if (v > max) max = v;
164 }
165
166 double deltay = max - min;
167 if (deltay < 1.0)
168 {
169 deltay = 1.0;
170
171 double midy = (min + max) * 0.5;
172 min = midy - deltay * 0.5;
173 max = midy + deltay * 0.5;
174 }
175
176 // draw the graph
177
178 double xv = 0.0;
179
180 int start = (ref->g_fill % ref->g_sz);
181 if (ref->g_fill < ref->g_sz) start = 0;
182
183 for (int f = 0;f < sz - 1;f++)
184 {
185 int index1 = ((start + f + 0) % ref->g_sz);
186 int index2 = ((start + f + 1) % ref->g_sz);
187
188 double v1 = ref->g_data[i * ref->g_sz + index1];
189 double v2 = ref->g_data[i * ref->g_sz + index2];
190
191 double yv1 = ref->da_h * (1.0 - (v1 - min) / deltay);
192 double yv2 = ref->da_h * (1.0 - (v2 - min) / deltay);
193
194 gdk_draw_line(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], (int) xv, (int) yv1, (int) (xv + dx), (int) yv2);
195
196 xv += dx;
197 }
198 }
199
200 return TRUE;
201 }
202
203 /*################################################################################################*/
204
205 // eof
206