1 /*
2  *
3  *   Copyright (C) 2005-2018 by C.H. Huang
4  *   plushuang.tw@gmail.com
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Lesser General Public
8  *  License as published by the Free Software Foundation; either
9  *  version 2.1 of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public
17  *  License along with this library; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  *  ---
21  *
22  *  In addition, as a special exception, the copyright holders give
23  *  permission to link the code of portions of this program with the
24  *  OpenSSL library under certain conditions as described in each
25  *  individual source file, and distribute linked combinations
26  *  including the two.
27  *  You must obey the GNU Lesser General Public License in all respects
28  *  for all of the code used other than OpenSSL.  If you modify
29  *  file(s) with this exception, you may extend this exception to your
30  *  version of the file(s), but you are not obligated to do so.  If you
31  *  do not wish to do so, delete this exception statement from your
32  *  version.  If you delete this exception statement from all source
33  *  files in the program, then also delete it here.
34  *
35  */
36 
37 #ifdef _MSC_VER
38 #define _CRT_SECURE_NO_WARNINGS
39 #endif
40 
41 #include <UgArray.h>
42 #include <UgString.h>
43 #include <UgtkCategoryForm.h>
44 
45 #include <glib/gi18n.h>
46 
47 static gchar* string_from_ug_array (UgArrayStr* uarray);
48 static void   string_to_ug_array (const gchar* string, UgArrayStr* uarray);
49 
ugtk_category_form_init(UgtkCategoryForm * cform)50 void  ugtk_category_form_init (UgtkCategoryForm* cform)
51 {
52 	GtkWidget*	label;
53 	GtkWidget*  entry;
54 	GtkGrid*	top_grid;
55 	GtkGrid*	grid;
56 	GtkWidget*  widget;
57 
58 	cform->self = gtk_grid_new ();
59 	top_grid  = (GtkGrid*) cform->self;
60 	gtk_container_set_border_width (GTK_CONTAINER (top_grid), 2);
61 
62 	label = gtk_label_new_with_mnemonic (_("Category _name:"));
63 	entry = gtk_entry_new ();
64 	gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
65 	gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
66 	g_object_set (label, "margin", 2, NULL);
67 	g_object_set (entry, "margin", 2, "hexpand", TRUE, NULL);
68 	gtk_grid_attach (top_grid, label, 0, 0, 1, 1);
69 	gtk_grid_attach (top_grid, entry, 1, 0, 1, 1);
70 	cform->name_entry = entry;
71 	cform->name_label = label;
72 
73 	// ------------------------------------------------------------------------
74 	// Capacity
75 	grid = (GtkGrid*) gtk_grid_new ();
76 	g_object_set (grid, "margin-top", 2, "margin-bottom", 2, NULL);
77 	gtk_grid_attach (top_grid, GTK_WIDGET (grid), 0, 1, 2, 1);
78 
79 	cform->spin_active = gtk_spin_button_new_with_range (1.0, 20.0, 1.0);
80 	gtk_entry_set_activates_default (GTK_ENTRY (cform->spin_active), TRUE);
81 //	gtk_entry_set_width_chars (GTK_ENTRY(cform->spin_active), 5);
82 	label = gtk_label_new_with_mnemonic (_("Active _downloads:"));
83 	gtk_label_set_mnemonic_widget (GTK_LABEL(label), cform->spin_active);
84 	g_object_set (label, "margin", 2, NULL);
85 	g_object_set (cform->spin_active, "margin-top", 2, "margin-bottom", 2, NULL);
86 	gtk_grid_attach (grid, label, 0, 0, 1, 1);
87 	gtk_grid_attach (grid, cform->spin_active, 1, 0, 1, 1);
88 
89 	cform->spin_finished = gtk_spin_button_new_with_range (0.0, 99999.0, 1.0);
90 	gtk_entry_set_activates_default (GTK_ENTRY (cform->spin_finished), TRUE);
91 //	gtk_entry_set_width_chars (GTK_ENTRY(cform->spin_finished), 5);
92 	label = gtk_label_new_with_mnemonic (_("Capacity of Finished:"));
93 	gtk_label_set_mnemonic_widget (GTK_LABEL(label), cform->spin_finished);
94 	g_object_set (label, "margin", 2, NULL);
95 	g_object_set (cform->spin_finished, "margin-top", 2, "margin-bottom", 2, NULL);
96 	gtk_grid_attach (grid, label, 0, 1, 1, 1);
97 	gtk_grid_attach (grid, cform->spin_finished, 1, 1, 1, 1);
98 
99 	cform->spin_recycled = gtk_spin_button_new_with_range (0.0, 99999.0, 1.0);
100 	gtk_entry_set_activates_default (GTK_ENTRY (cform->spin_recycled), TRUE);
101 //	gtk_entry_set_width_chars (GTK_ENTRY(cform->spin_recycled), 5);
102 	label = gtk_label_new_with_mnemonic (_("Capacity of Recycled:"));
103 	gtk_label_set_mnemonic_widget (GTK_LABEL(label), cform->spin_recycled);
104 	g_object_set (label, "margin", 2, NULL);
105 	g_object_set (cform->spin_recycled, "margin-top", 2, "margin-bottom", 2, NULL);
106 	gtk_grid_attach (grid, label, 0, 2, 1, 1);
107 	gtk_grid_attach (grid, cform->spin_recycled, 1, 2, 1, 1);
108 
109 	// ------------------------------------------------------------------------
110 	// URI Matching conditions
111 	widget = gtk_frame_new (_("URI Matching conditions"));
112 	g_object_set (grid, "margin-top", 4, "margin-bottom", 4, NULL);
113 	gtk_grid_attach (top_grid, widget, 0, 2, 2, 1);
114 	grid = (GtkGrid*) gtk_grid_new ();
115 	g_object_set (grid, "margin-top", 2, "margin-bottom", 2, NULL);
116 	gtk_container_add (GTK_CONTAINER (widget), (GtkWidget*) grid);
117 
118 	label = gtk_label_new_with_mnemonic (_("Matched _Hosts:"));
119 	entry = gtk_entry_new ();
120 	gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
121 	gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
122 	g_object_set (label, "margin", 2, NULL);
123 	g_object_set (entry, "margin", 2, "hexpand", TRUE, NULL);
124 	gtk_grid_attach (grid, label, 0, 0, 1, 1);
125 	gtk_grid_attach (grid, entry, 1, 0, 1, 1);
126 	cform->hosts_entry = entry;
127 	cform->hosts_label = label;
128 
129 	label = gtk_label_new_with_mnemonic (_("Matched _Schemes:"));
130 	entry = gtk_entry_new ();
131 	gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
132 	gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
133 	g_object_set (label, "margin", 2, NULL);
134 	g_object_set (entry, "margin", 2, "hexpand", TRUE, NULL);
135 	gtk_grid_attach (grid, label, 0, 1, 1, 1);
136 	gtk_grid_attach (grid, entry, 1, 1, 1, 1);
137 	cform->schemes_entry = entry;
138 	cform->schemes_label = label;
139 
140 	label = gtk_label_new_with_mnemonic (_("Matched _Types:"));
141 	entry = gtk_entry_new ();
142 	gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
143 	gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
144 	g_object_set (label, "margin", 2, NULL);
145 	g_object_set (entry, "margin", 2, "hexpand", TRUE, NULL);
146 	gtk_grid_attach (grid, label, 0, 2, 1, 1);
147 	gtk_grid_attach (grid, entry, 1, 2, 1, 1);
148 	cform->types_entry = entry;
149 	cform->types_label = label;
150 
151 	gtk_widget_show_all (GTK_WIDGET (top_grid));
152 }
153 
ugtk_category_form_get(UgtkCategoryForm * cform,UgData * cnode_data)154 void  ugtk_category_form_get (UgtkCategoryForm* cform, UgData* cnode_data)
155 {
156 	UgetCategory*  category;
157 	UgetCommon*    common;
158 	const gchar*   text;
159 
160 	category = ug_data_realloc(cnode_data, UgetCategoryInfo);
161 	common   = ug_data_realloc(cnode_data, UgetCommonInfo);
162 	if (gtk_widget_is_sensitive (cform->name_entry) == TRUE) {
163 		text = gtk_entry_get_text ((GtkEntry*) cform->name_entry);
164 		ug_free(common->name);
165 		common->name = (*text) ? ug_strdup(text) : NULL;
166 	}
167 	category->active_limit = gtk_spin_button_get_value_as_int (
168 			(GtkSpinButton*) cform->spin_active);
169 	// Finished
170 	category->finished_limit = gtk_spin_button_get_value_as_int (
171 			(GtkSpinButton*) cform->spin_finished);
172 	// Recycled
173 	category->recycled_limit = gtk_spin_button_get_value_as_int (
174 			(GtkSpinButton*) cform->spin_recycled);
175 
176 	// matching - clear
177 	ug_array_foreach_str (&category->hosts, (UgForeachFunc) ug_free, NULL);
178 	ug_array_foreach_str (&category->schemes, (UgForeachFunc) ug_free, NULL);
179 	ug_array_foreach_str (&category->file_exts, (UgForeachFunc) ug_free, NULL);
180 	category->hosts.length = 0;
181 	category->schemes.length = 0;
182 	category->file_exts.length = 0;
183 	// matching - set
184 	string_to_ug_array (gtk_entry_get_text ((GtkEntry*) cform->hosts_entry),
185 			&category->hosts);
186 	string_to_ug_array (gtk_entry_get_text ((GtkEntry*) cform->schemes_entry),
187 			&category->schemes);
188 	string_to_ug_array (gtk_entry_get_text ((GtkEntry*) cform->types_entry),
189 			&category->file_exts);
190 }
191 
ugtk_category_form_set(UgtkCategoryForm * cform,UgData * cnode_data)192 void  ugtk_category_form_set (UgtkCategoryForm* cform, UgData* cnode_data)
193 {
194 	UgetCommon*    common;
195 	UgetCategory*  category;
196 	gchar*  str;
197 
198 	category = ug_data_realloc(cnode_data, UgetCategoryInfo);
199 	common   = ug_data_get(cnode_data, UgetCommonInfo);
200 	if (gtk_widget_is_sensitive (cform->name_entry) == TRUE) {
201 		gtk_entry_set_text ((GtkEntry*) cform->name_entry,
202 				(common->name) ? common->name : "");
203 	}
204 	gtk_spin_button_set_value ((GtkSpinButton*) cform->spin_active,
205 			(gdouble) category->active_limit);
206 	// Finished
207 	gtk_spin_button_set_value ((GtkSpinButton*) cform->spin_finished,
208 			(gdouble) category->finished_limit);
209 	// Recycled
210 	gtk_spin_button_set_value ((GtkSpinButton*) cform->spin_recycled,
211 			(gdouble) category->recycled_limit);
212 
213 	// matching
214 	str = string_from_ug_array (&category->hosts);
215 	gtk_entry_set_text ((GtkEntry*) cform->hosts_entry, str);
216 	g_free (str);
217 	str = string_from_ug_array (&category->schemes);
218 	gtk_entry_set_text ((GtkEntry*) cform->schemes_entry, str);
219 	g_free (str);
220 	str = string_from_ug_array (&category->file_exts);
221 	gtk_entry_set_text ((GtkEntry*) cform->types_entry, str);
222 	g_free (str);
223 }
224 
ugtk_category_form_set_multiple(UgtkCategoryForm * cform,gboolean multiple_mode)225 void  ugtk_category_form_set_multiple (UgtkCategoryForm*  cform, gboolean multiple_mode)
226 {
227 	if (multiple_mode) {
228 		gtk_widget_hide (cform->name_entry);
229 		gtk_widget_hide (cform->name_label);
230 		gtk_widget_set_sensitive (cform->name_entry, FALSE);
231 		gtk_widget_set_sensitive (cform->name_label, FALSE);
232 	}
233 	else {
234 		gtk_widget_show (cform->name_entry);
235 		gtk_widget_show (cform->name_label);
236 		gtk_widget_set_sensitive (cform->name_entry, TRUE);
237 		gtk_widget_set_sensitive (cform->name_label, TRUE);
238 	}
239 }
240 
241 // ----------------------------------------------------------------------------
242 // static function
243 
string_from_ug_array(UgArrayStr * uarray)244 static gchar* string_from_ug_array (UgArrayStr* uarray)
245 {
246 	int   index, length;
247 	char* buffer;
248 
249 	for (length = 0, index = 0;  index < uarray->length;  index++)
250 		length += strlen(uarray->at[index]) + 1;  // + ';'
251 
252 	buffer = g_malloc (length + 1);
253 	buffer[0] = 0;
254 
255 	for (index = 0;  index < uarray->length;  index++) {
256 		strcat (buffer, uarray->at[index]);
257 		strcat (buffer, ";");
258 	}
259 
260 	return buffer;
261 }
262 
string_to_ug_array(const gchar * string,UgArrayStr * uarray)263 static void string_to_ug_array (const gchar* string, UgArrayStr* uarray)
264 {
265 	const gchar*  cur;
266 	const gchar*  prev;
267 
268 	for (prev = string, cur = string; ;  cur++) {
269 		if ((cur[0] == ';' || cur[0] == 0) && cur != prev) {
270 			*(char**)ug_array_alloc (uarray, 1) = ug_strndup (prev, cur - prev);
271 			prev = cur + 1;
272 		}
273 		if (cur[0] == 0)
274 			break;
275 	}
276 }
277