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