1 /* MManager - a Desktop wide manager for multimedia applications.
3 * Copyright (C) 2008 Cosimo Cecchi <cosimoc@gnome.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library 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 GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
21 #include "mm-gtk-filter-builder.h"
22 #include "mm-gtk-attribute-store.h"
24 #include "libmmanager/mm-attribute-manager.h"
25 #include "libmmanager/mm-attribute-base-manager.h"
26 #include "libmmanager/mm-types.h"
27 #include "libmmanager/mm-string-utils.h"
28 #include "libmmanager/mm-filter-param.h"
29 #include "libmmanager/mm-attribute.h"
33 #include <glib/gi18n.h>
35 G_DEFINE_TYPE (MMGtkFilterBuilder
, mm_gtk_filter_builder
, GTK_TYPE_VBOX
);
37 #define MM_GTK_FILTER_BUILDER_GET_PRIVATE(o) \
38 (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_GTK_TYPE_FILTER_BUILDER, MMGtkFilterBuilderPrivate))
40 struct _MMGtkFilterBuilderPrivate
{
41 GtkListStore
*filter_store
;
42 MMGtkAttributeStore
*attribute_store
;
43 GtkWidget
*filter_view
;
45 GHashTable
*attr_managers
;
48 GtkWidget
*attr_combo
;
49 GtkWidget
*logic_combo
;
50 GtkWidget
*value_entry
;
53 static const char * logic_strs
[] = {
57 N_("greater or equal than"),
58 N_("less or equal than"),
62 mm_gtk_filter_builder_finalize (GObject
*obj
)
64 MMGtkFilterBuilder
*self
= MM_GTK_FILTER_BUILDER (obj
);
65 g_hash_table_destroy (self
->details
->attr_managers
);
67 G_OBJECT_CLASS (mm_gtk_filter_builder_parent_class
)->finalize (obj
);
71 mm_gtk_filter_builder_class_init (MMGtkFilterBuilderClass
*klass
)
73 GObjectClass
*oclass
= G_OBJECT_CLASS (klass
);
75 oclass
->finalize
= mm_gtk_filter_builder_finalize
;
77 g_type_class_add_private (klass
, sizeof (MMGtkFilterBuilderPrivate
));
81 populate_logic_combo (GtkWidget
*combo
)
85 for (idx
= 0; idx
< G_N_ELEMENTS (logic_strs
); idx
++) {
86 gtk_combo_box_append_text (GTK_COMBO_BOX (combo
), logic_strs
[idx
]);
89 gtk_combo_box_set_active (GTK_COMBO_BOX (combo
), 0);
92 static MMComparisionOperator
93 logic_combo_get_selected (GtkComboBox
*combo
)
97 idx
= gtk_combo_box_get_active (combo
);
98 return (MMComparisionOperator
) (idx
+ 1);
102 comparision_op_to_string (MMComparisionOperator op
)
104 return logic_strs
[op
- 1];
108 cat_combo_changed_cb (GtkComboBox
*combo
,
109 MMGtkFilterBuilder
*self
)
112 MMAttributeManager
*attr_manager
;
114 idx
= gtk_combo_box_get_active (combo
);
115 attr_manager
= g_hash_table_lookup (self
->details
->attr_managers
,
117 mm_gtk_attribute_store_set_from_attribute_manager (self
->details
->attribute_store
,
119 gtk_combo_box_set_model (GTK_COMBO_BOX (self
->details
->attr_combo
),
120 GTK_TREE_MODEL (self
->details
->attribute_store
));
121 gtk_combo_box_set_active (GTK_COMBO_BOX (self
->details
->attr_combo
), 0);
125 add_filter_button_clicked_cb (GtkButton
*button
,
126 MMGtkFilterBuilder
*self
)
129 MMAttribute
*attribute
;
130 MMComparisionOperator op
;
131 GtkTreeIter attr_iter
, fp_iter
;
133 const char * val_string
;
136 /* we need to build a filter-param object with the selected information */
137 gtk_combo_box_get_active_iter (GTK_COMBO_BOX (self
->details
->attr_combo
),
139 gtk_tree_model_get (GTK_TREE_MODEL (self
->details
->attribute_store
),
140 &attr_iter
, MM_GTK_ATTR_STORE_ATTR_COL
,
142 op
= logic_combo_get_selected (GTK_COMBO_BOX (self
->details
->logic_combo
));
143 val_string
= gtk_entry_get_text (GTK_ENTRY (self
->details
->value_entry
));
144 res
= mm_gvalue_from_string (val_string
, mm_attribute_get_value_type (attribute
),
146 /* TODO: the attribute manager should provide a method to validate values
147 * for the relevant attribute.
150 fp
= mm_filter_param_new (attribute
, &val
, op
);
151 gtk_list_store_append (self
->details
->filter_store
, &fp_iter
);
152 gtk_list_store_set (self
->details
->filter_store
, &fp_iter
,
158 filter_param_logic_cell_data_func (GtkTreeViewColumn
*column
,
159 GtkCellRenderer
*cell
,
165 const char *logic_name
;
167 gtk_tree_model_get (model
, iter
, 0, &fp
, -1);
168 logic_name
= comparision_op_to_string (mm_filter_param_get_operator (fp
));
169 g_object_set (cell
, "text", logic_name
, NULL
);
175 filter_param_value_cell_data_func (GtkTreeViewColumn
*column
,
176 GtkCellRenderer
*cell
,
185 gtk_tree_model_get (model
, iter
, 0, &fp
, -1);
186 val
= mm_filter_param_get_value (fp
);
187 value_str
= mm_gvalue_to_string (val
);
188 g_object_set (cell
, "text", value_str
, NULL
);
195 filter_param_attr_cell_data_func (GtkTreeViewColumn
*column
,
196 GtkCellRenderer
*cell
,
202 const char *attr_name
;
204 gtk_tree_model_get (model
, iter
, 0, &fp
, -1);
205 attr_name
= mm_attribute_get_name (mm_filter_param_get_attribute (fp
));
206 g_object_set (cell
, "text", attr_name
, NULL
);
212 mm_gtk_filter_builder_init (MMGtkFilterBuilder
*self
)
214 MMGtkFilterBuilderPrivate
*details
= self
->details
=
215 MM_GTK_FILTER_BUILDER_GET_PRIVATE (self
);
216 GtkWidget
*filter_view
;
217 GtkTreeViewColumn
*column
;
218 GtkCellRenderer
*renderer
;
222 details
->attribute_store
= mm_gtk_attribute_store_new ();
223 details
->attr_managers
= g_hash_table_new (g_int_hash
, g_int_equal
);
226 details
->filter_store
= gtk_list_store_new (1, MM_TYPE_FILTER_PARAM
);
227 filter_view
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (details
->filter_store
));
228 renderer
= gtk_cell_renderer_text_new ();
229 column
= gtk_tree_view_column_new ();
230 gtk_tree_view_column_set_title (column
, _("Attribute"));
231 gtk_tree_view_column_pack_start (column
, renderer
, TRUE
);
232 gtk_tree_view_column_set_cell_data_func (column
, renderer
,
233 filter_param_attr_cell_data_func
,
235 gtk_tree_view_append_column (GTK_TREE_VIEW (filter_view
), column
);
236 column
= gtk_tree_view_column_new ();
237 gtk_tree_view_column_pack_start (column
, renderer
, TRUE
);
238 gtk_tree_view_column_set_title (column
, _("Logic"));
239 gtk_tree_view_column_set_cell_data_func (column
, renderer
,
240 filter_param_logic_cell_data_func
,
242 gtk_tree_view_append_column (GTK_TREE_VIEW (filter_view
), column
);
243 column
= gtk_tree_view_column_new ();
244 gtk_tree_view_column_pack_start (column
, renderer
, TRUE
);
245 gtk_tree_view_column_set_title (column
, _("Value"));
246 gtk_tree_view_column_set_cell_data_func (column
, renderer
,
247 filter_param_value_cell_data_func
,
249 gtk_tree_view_append_column (GTK_TREE_VIEW (filter_view
), column
);
250 details
->filter_view
= filter_view
;
251 gtk_box_pack_start (GTK_BOX (self
), GTK_WIDGET (filter_view
),
253 gtk_widget_show (filter_view
);
256 table
= gtk_table_new (3, 4, FALSE
);
258 /* attribute category */
259 w
= gtk_label_new_with_mnemonic (_("Attribute _category:"));
260 gtk_table_attach (GTK_TABLE (table
), w
,
263 details
->cat_combo
= gtk_combo_box_new_text ();
264 g_signal_connect (details
->cat_combo
, "changed",
265 G_CALLBACK (cat_combo_changed_cb
), self
);
266 gtk_table_attach (GTK_TABLE (table
), details
->cat_combo
,
271 w
= gtk_label_new_with_mnemonic (_("Attribute _name:"));
272 gtk_table_attach (GTK_TABLE (table
), w
,
275 details
->attr_combo
= gtk_combo_box_new ();
276 renderer
= gtk_cell_renderer_text_new ();
277 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (details
->attr_combo
),
279 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (details
->attr_combo
),
281 "text", MM_GTK_ATTR_STORE_NAME_COL
);
282 gtk_table_attach (GTK_TABLE (table
), details
->attr_combo
,
287 w
= gtk_label_new_with_mnemonic (_("_Logic:"));
288 gtk_table_attach (GTK_TABLE (table
), w
,
291 details
->logic_combo
= gtk_combo_box_new_text ();
292 gtk_table_attach (GTK_TABLE (table
), details
->logic_combo
,
297 w
= gtk_label_new_with_mnemonic (_("_Value:"));
298 gtk_table_attach (GTK_TABLE (table
), w
,
301 details
->value_entry
= gtk_entry_new ();
302 gtk_table_attach (GTK_TABLE (table
), details
->value_entry
,
306 /* add filter button */
307 w
= gtk_button_new_from_stock (GTK_STOCK_ADD
);
308 g_signal_connect (w
, "clicked",
309 G_CALLBACK (add_filter_button_clicked_cb
), self
);
310 gtk_table_attach (GTK_TABLE (table
), w
,
313 gtk_box_pack_start (GTK_BOX (self
), table
,
315 gtk_widget_show_all (table
);
317 populate_logic_combo (details
->logic_combo
);
321 populate_from_category (MMGtkFilterBuilder
*self
, MMCategory
*cat
)
323 MMApplicationType type
;
324 MMAttributeManager
*attr_manager
;
327 /* TODO: we should take care in some way that applications may want to define
328 * a custom AttributeManager. The API here in libmmanager-gtk is already
329 * setup for that, but this needs an API addition in MMApplication.
332 g_return_if_fail (MM_GTK_IS_FILTER_BUILDER (self
));
333 g_return_if_fail (MM_IS_CATEGORY (cat
));
335 /* TODO: when I will create Photo, Video and Music attribute managers,
336 * here is the place for adding those custom attributes.
340 attr_manager
= mm_attribute_base_manager_get ();
341 mm_gtk_attribute_store_set_from_attribute_manager (self
->details
->attribute_store
,
343 gtk_combo_box_append_text (GTK_COMBO_BOX (self
->details
->cat_combo
),
344 _("Base attributes"));
345 g_hash_table_insert (self
->details
->attr_managers
, &key
, attr_manager
);
347 /* this should trigger population in the attr combo box */
348 gtk_combo_box_set_active (GTK_COMBO_BOX (self
->details
->cat_combo
), 0);
354 * mm_gtk_filter_builder_new:
355 * @category: a #MMCategory.
357 * Builds a #GtkWidget that allows to create #MMFilter objects for attributes
358 * supported by @category.
360 * Return value: a new #MMGtkFilterBuilder.
364 mm_gtk_filter_builder_new (MMCategory
*category
)
366 MMGtkFilterBuilder
*self
;
368 self
= MM_GTK_FILTER_BUILDER (g_object_new (MM_GTK_TYPE_FILTER_BUILDER
, NULL
));
369 populate_from_category (self
, category
);
375 * mm_gtk_filter_builder_get_filter:
376 * @self: a #MMGtkFilterBuilder.
378 * Gets the #MMFilter for all the conditions specified within @self.
380 * Return value: a new #MMFilter, which might be empty if no condition has
381 * been specified inside @self.
385 mm_gtk_filter_builder_get_filter (MMGtkFilterBuilder
*self
)
389 gboolean next
= TRUE
;
393 g_return_val_if_fail (MM_GTK_IS_FILTER_BUILDER (self
), NULL
);
395 filter
= mm_filter_new ();
396 res
= gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self
->details
->filter_store
),
403 gtk_tree_model_get (GTK_TREE_MODEL (self
->details
->filter_store
),
405 mm_filter_add_filtering_param (filter
, fp
);
406 next
= gtk_tree_model_iter_next (GTK_TREE_MODEL (self
->details
->filter_store
),