1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*****************************************************************************
4 * $Id: search.c,v 1.5 2005/02/18 02:12:08 nedko Exp $
12 *****************************************************************************/
21 /* ULLONG_MAX should come from limits.h but doesn't */
22 #if !defined(ULLONG_MAX) && defined(ULONG_LONG_MAX)
23 # define ULLONG_MAX ULONG_LONG_MAX
26 #include "../result.h"
27 #include "../libdb/libdb.h"
28 #include "../libfrontend/db.h"
47 #define KEY_PREFIX "mediadatabase_file_search_"
48 #define KEY_FILENAME KEY_PREFIX "filename"
49 #define KEY_FILENAME_PMM KEY_PREFIX "filename_pmm"
50 #define KEY_PATH KEY_PREFIX "path"
51 #define KEY_PATH_PMM KEY_PREFIX "path_pmm"
52 #define KEY_MIN_SIZE KEY_PREFIX "min_size"
53 #define KEY_MIN_SIZE_UNITS KEY_PREFIX "min_size_units"
54 #define KEY_MAX_SIZE KEY_PREFIX "max_size"
55 #define KEY_MAX_SIZE_UNITS KEY_PREFIX "max_size_units"
56 #define KEY_PMM KEY_PREFIX "pmm"
57 #define KEY_STORE KEY_PREFIX "store"
62 mediadb_uint nMediaID
,
63 mediadb_mediatype nMediaType
,
64 const char *pszMediaName
,
65 const char *pszMediaLocation
,
68 mediadb_filetype Filetype
,
74 GdkPixbuf
* pMediaIcon
;
78 GError
* error
= NULL
;
80 char strSize
[MAX_SIZE_DESCRIPTION
];
82 gchar
* pszIconFullname
;
84 pszFullPath
= g_malloc(strlen(pszPath
)+strlen(pszName
)+1);
85 sprintf(pszFullPath
, "%s%s", pszPath
, pszName
);
87 localtime_r(&time
, &tm
);
89 "%u-%02u-%02u %02u:%02u:%02u",
97 get_size_description(nSize
, strSize
);
101 if (Filetype
== MEDIADB_FILETYPE_DIR
)
103 pszIcon
= "icon_folder.png";
107 pszIcon
= "icon_unknown.png";
110 pszIconFullname
= path_get_data_filename(pszIcon
);
111 if (pszIconFullname
!= NULL
)
113 pIcon
= gdk_pixbuf_new_from_file(pszIconFullname
, &error
);
116 g_warning("Could not load icon: %s\n", error
->message
);
121 g_free(pszIconFullname
);
125 g_warning("Could not find icon %s\n", pszIcon
);
128 pszIcon
= "icon_cd.png";
130 pszIconFullname
= path_get_data_filename(pszIcon
);
131 if (pszIconFullname
!= NULL
)
133 pMediaIcon
= gdk_pixbuf_new_from_file(pszIconFullname
, &error
);
136 g_warning("Could not load icon: %s\n", error
->message
);
141 g_free(pszIconFullname
);
145 g_warning("Could not find icon %s\n", pszIcon
);
148 gtk_list_store_append(
151 G_OBJECT(pUserContext
),
158 G_OBJECT(pUserContext
),
162 COL_NAME
, pszFullPath
,
163 COL_SIZE
, (Filetype
== MEDIADB_FILETYPE_DIR
)?NULL
:strSize
,
165 COL_MEDIAID
, (unsigned int)nMediaID
,
166 COL_MEDIAICON
, pMediaIcon
,
167 COL_MEDIANAME
, pszMediaName
,
168 COL_MEDIALOCATION
, pszMediaLocation
,
180 const char *pszFilename
;
181 gint nFilenamePMMIndex
;
184 const char *pszMinSize
;
186 const char *pszMaxSize
;
188 const struct mediadb_pattern_match_method
*pPMM
;
189 mediadb_uint nMinSize
;
190 mediadb_uint nMaxSize
;
194 pPMM
= (const struct mediadb_pattern_match_method
*)g_object_get_data(
198 pszFilename
= gtk_entry_get_text(
204 nFilenamePMMIndex
= gtk_combo_box_get_active(
210 pszPath
= gtk_entry_get_text(
216 nPathPMMIndex
= gtk_combo_box_get_active(
222 pszMinSize
= gtk_entry_get_text(
228 nMinSizeUnits
= gtk_combo_box_get_active(
232 KEY_MIN_SIZE_UNITS
)));
234 pszMaxSize
= gtk_entry_get_text(
240 nMaxSizeUnits
= gtk_combo_box_get_active(
244 KEY_MAX_SIZE_UNITS
)));
246 /* We better handle such thing in backend
247 if (*pszFilename == 0 &&
252 pDialog = gtk_message_dialog_new(
253 GTK_WINDOW(pUserData),
254 GTK_DIALOG_DESTROY_WITH_PARENT,
257 "No search criteria ...\n");
259 gtk_dialog_run(GTK_DIALOG(pDialog));
260 gtk_widget_destroy(pDialog);
268 nMinSizeUnits
> nMaxSizeUnits
)
270 pDialog
= gtk_message_dialog_new(
271 GTK_WINDOW(pUserData
),
272 GTK_DIALOG_DESTROY_WITH_PARENT
,
275 "Min size units (%s) are bigger than max size units (%s).",
276 g_arrSizeUnits
[nMinSizeUnits
].pszUnitsName
,
277 g_arrSizeUnits
[nMaxSizeUnits
].pszUnitsName
);
279 gtk_dialog_run(GTK_DIALOG(pDialog
));
280 gtk_widget_destroy(pDialog
);
287 nMinSize
= strtoull(pszMinSize
, &pchEnd
, 10);
288 if (nMinSize
== 0 || nMinSize
== ULLONG_MAX
|| *pchEnd
)
290 pDialog
= gtk_message_dialog_new(
291 GTK_WINDOW(pUserData
),
292 GTK_DIALOG_DESTROY_WITH_PARENT
,
295 "Cannot convert \"%s\" to decimal integer number.",
298 gtk_dialog_run(GTK_DIALOG(pDialog
));
299 gtk_widget_destroy(pDialog
);
304 if (ULLONG_MAX
/ g_arrSizeUnits
[nMinSizeUnits
].nUnitSize
< nMinSize
)
306 pDialog
= gtk_message_dialog_new(
307 GTK_WINDOW(pUserData
),
308 GTK_DIALOG_DESTROY_WITH_PARENT
,
311 "%llu %s is too large number.",
313 g_arrSizeUnits
[nMinSizeUnits
].pszUnitsName
);
315 gtk_dialog_run(GTK_DIALOG(pDialog
));
316 gtk_widget_destroy(pDialog
);
321 nMinSize
= nMinSize
* g_arrSizeUnits
[nMinSizeUnits
].nUnitSize
;
326 nMaxSize
= strtoull(pszMaxSize
, &pchEnd
, 10);
327 if (nMaxSize
== 0 || nMaxSize
== ULLONG_MAX
|| *pchEnd
)
329 pDialog
= gtk_message_dialog_new(
330 GTK_WINDOW(pUserData
),
331 GTK_DIALOG_DESTROY_WITH_PARENT
,
334 "Cannot convert \"%s\" to decimal integer number.",
337 gtk_dialog_run(GTK_DIALOG(pDialog
));
338 gtk_widget_destroy(pDialog
);
343 if (ULLONG_MAX
/ g_arrSizeUnits
[nMaxSizeUnits
].nUnitSize
< nMaxSize
)
345 pDialog
= gtk_message_dialog_new(
346 GTK_WINDOW(pUserData
),
347 GTK_DIALOG_DESTROY_WITH_PARENT
,
350 "%llu %s is too large number.",
352 g_arrSizeUnits
[nMaxSizeUnits
].pszUnitsName
);
354 gtk_dialog_run(GTK_DIALOG(pDialog
));
355 gtk_widget_destroy(pDialog
);
360 nMaxSize
= nMaxSize
* g_arrSizeUnits
[nMaxSizeUnits
].nUnitSize
;
363 pDialog
= gtk_message_dialog_new(
364 GTK_WINDOW(pUserData
),
365 GTK_DIALOG_DESTROY_WITH_PARENT
,
373 *pszFilename
?"Filename \"":"",
374 *pszFilename
?pszFilename
:"",
375 *pszFilename
?"\" - ":"",
376 *pszFilename
?pPMM
[nFilenamePMMIndex
].pszDescription
:"",
377 *pszFilename
?"\n":"",
378 *pszPath
?"Path \"":"",
381 *pszPath
?pPMM
[nPathPMMIndex
].pszDescription
:"",
383 *pszMinSize
?"Min size ":"",
384 *pszMinSize
?pszMinSize
:"",
386 *pszMinSize
?g_arrSizeUnits
[nMinSizeUnits
].pszUnitsName
:"",
388 *pszMaxSize
?"Max size ":"",
389 *pszMaxSize
?pszMaxSize
:"",
391 *pszMaxSize
?g_arrSizeUnits
[nMaxSizeUnits
].pszUnitsName
:"",
392 *pszMaxSize
?"\n":"");
394 gtk_dialog_run(GTK_DIALOG(pDialog
));
395 gtk_widget_destroy(pDialog
);
397 gtk_list_store_clear(
403 r
= mediadb_files_search(
405 *pszFilename
?pPMM
[nFilenamePMMIndex
].nID
:MEDIADB_PMM_NULL
,
406 *pszFilename
?pszFilename
:NULL
,
407 *pszPath
?pPMM
[nPathPMMIndex
].nID
:MEDIADB_PMM_NULL
,
408 *pszPath
?pszPath
:NULL
,
409 *pszMinSize
?&nMinSize
:NULL
,
410 *pszMaxSize
?&nMaxSize
:NULL
,
413 if (MEDIADB_IS_ERROR(r
))
415 display_error_message_mediadb(GTK_WINDOW(pUserData
));
423 GtkWidget
*pSearchWindow
;
425 GtkWidget
*pTableMain
;
426 GtkWidget
*pTableSearchParameters
;
427 GtkWidget
*pScrolledWindow
;
429 GtkCellRenderer
* pRendererText
;
430 GtkCellRenderer
* pRendererPixbuf
;
431 GtkTreeViewColumn
* pColumn
;
432 GtkListStore
*pListStore
;
433 const struct mediadb_pattern_match_method
*pPMM
;
437 r
= mediadb_get_pattern_match_methods(
440 if (MEDIADB_IS_ERROR(r
))
442 display_error_message_mediadb(GTK_WINDOW(pMainWindow
));
446 pSearchWindow
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
448 g_object_set_data(G_OBJECT(pSearchWindow
), KEY_PMM
, (gpointer
)pPMM
);
450 gtk_window_set_role(GTK_WINDOW(pSearchWindow
), "search");
452 gtk_window_set_title(GTK_WINDOW(pSearchWindow
),
455 pTableMain
= gtk_table_new(2, 1, FALSE
);
457 pFrame
= gtk_frame_new(NULL
);
459 gtk_table_attach(GTK_TABLE(pTableMain
), pFrame
, 0, 1, 0, 1,
465 pTableSearchParameters
= gtk_table_new(
468 FALSE
); /* homogeneous */
471 GTK_CONTAINER(pFrame
),
472 pTableSearchParameters
);
474 gtk_container_set_border_width(
475 GTK_CONTAINER(pTableSearchParameters
),
478 gtk_table_set_row_spacings(GTK_TABLE(pTableSearchParameters
), 5);
479 gtk_table_set_col_spacings(GTK_TABLE(pTableSearchParameters
), 5);
482 pChild
= gtk_label_new("Filename");
485 GTK_TABLE(pTableSearchParameters
),
496 pChild
= gtk_entry_new();
498 gtk_table_attach_defaults(
499 GTK_TABLE(pTableSearchParameters
),
510 g_object_set_data(G_OBJECT(pSearchWindow
), KEY_FILENAME
, pChild
);
514 pChild
= gtk_combo_box_new_text();
518 while (pPMM
[i
].nID
!= MEDIADB_PMM_NULL
)
520 gtk_combo_box_append_text(GTK_COMBO_BOX(pChild
), pPMM
[i
].pszName
);
524 gtk_combo_box_set_active(GTK_COMBO_BOX(pChild
), 0);
527 GTK_TABLE(pTableSearchParameters
),
536 g_object_set_data(G_OBJECT(pSearchWindow
), KEY_FILENAME_PMM
, pChild
);
540 pChild
= gtk_label_new("Path");
543 GTK_TABLE(pTableSearchParameters
),
554 pChild
= gtk_entry_new();
556 gtk_table_attach_defaults(
557 GTK_TABLE(pTableSearchParameters
),
568 g_object_set_data(G_OBJECT(pSearchWindow
), KEY_PATH
, pChild
);
572 pChild
= gtk_combo_box_new_text();
576 while (pPMM
[i
].nID
!= MEDIADB_PMM_NULL
)
578 gtk_combo_box_append_text(GTK_COMBO_BOX(pChild
), pPMM
[i
].pszName
);
582 gtk_combo_box_set_active(GTK_COMBO_BOX(pChild
), 0);
585 GTK_TABLE(pTableSearchParameters
),
594 g_object_set_data(G_OBJECT(pSearchWindow
), KEY_PATH_PMM
, pChild
);
598 pChild
= gtk_label_new("Min size");
601 GTK_TABLE(pTableSearchParameters
),
612 pChild
= gtk_entry_new();
614 gtk_table_attach_defaults(
615 GTK_TABLE(pTableSearchParameters
),
626 g_object_set_data(G_OBJECT(pSearchWindow
), KEY_MIN_SIZE
, pChild
);
630 pChild
= gtk_combo_box_new_text();
634 while (g_arrSizeUnits
[i
].nUnitSize
!= 0)
638 /* Second entry should be kilobytes */
642 gtk_combo_box_append_text(GTK_COMBO_BOX(pChild
), g_arrSizeUnits
[i
].pszUnitsName
);
647 gtk_combo_box_set_active(GTK_COMBO_BOX(pChild
), j
);
650 GTK_TABLE(pTableSearchParameters
),
659 g_object_set_data(G_OBJECT(pSearchWindow
), KEY_MIN_SIZE_UNITS
, pChild
);
663 pChild
= gtk_label_new("Max size");
666 GTK_TABLE(pTableSearchParameters
),
677 pChild
= gtk_entry_new();
679 gtk_table_attach_defaults(
680 GTK_TABLE(pTableSearchParameters
),
691 g_object_set_data(G_OBJECT(pSearchWindow
), KEY_MAX_SIZE
, pChild
);
695 pChild
= gtk_combo_box_new_text();
699 while (g_arrSizeUnits
[i
].nUnitSize
!= 0)
703 /* Second entry should be kilobytes */
707 gtk_combo_box_append_text(GTK_COMBO_BOX(pChild
), g_arrSizeUnits
[i
].pszUnitsName
);
712 gtk_combo_box_set_active(GTK_COMBO_BOX(pChild
), j
);
715 GTK_TABLE(pTableSearchParameters
),
724 g_object_set_data(G_OBJECT(pSearchWindow
), KEY_MAX_SIZE_UNITS
, pChild
);
728 pChild
= gtk_button_new_from_stock(GTK_STOCK_FIND
);
731 GTK_TABLE(pTableSearchParameters
),
747 /* Tree view creation */
748 pChild
= gtk_tree_view_new();
749 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(pChild
), TRUE
);
750 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(pChild
), TRUE
);
752 pRendererText
= gtk_cell_renderer_text_new();
753 pRendererPixbuf
= gtk_cell_renderer_pixbuf_new();
755 /* --- Column #1 --- */
757 pColumn
= gtk_tree_view_column_new();
758 gtk_tree_view_column_set_title(pColumn
, "Name");
760 gtk_tree_view_column_pack_start(pColumn
, pRendererPixbuf
, FALSE
);
761 gtk_tree_view_column_set_attributes(pColumn
, pRendererPixbuf
,
765 gtk_tree_view_column_pack_start(pColumn
, pRendererText
, TRUE
);
766 gtk_tree_view_column_set_attributes(pColumn
,
771 gtk_tree_view_append_column(
772 GTK_TREE_VIEW(pChild
),
775 /* --- Column #2 --- */
777 pColumn
= gtk_tree_view_column_new_with_attributes(
783 gtk_tree_view_append_column(
784 GTK_TREE_VIEW(pChild
),
787 /* --- Column #3 --- */
789 pColumn
= gtk_tree_view_column_new_with_attributes(
795 gtk_tree_view_append_column(
796 GTK_TREE_VIEW(pChild
),
799 /* --- Column #4 --- */
801 pColumn
= gtk_tree_view_column_new_with_attributes(
807 gtk_tree_view_append_column(
808 GTK_TREE_VIEW(pChild
),
811 /* --- Column #5 --- */
813 pColumn
= gtk_tree_view_column_new();
815 gtk_tree_view_column_set_title(
819 gtk_tree_view_column_pack_start(
824 gtk_tree_view_column_set_attributes(
831 gtk_tree_view_column_pack_end(
836 gtk_tree_view_column_set_attributes(
839 "text", COL_MEDIANAME
,
842 gtk_tree_view_append_column(
843 GTK_TREE_VIEW(pChild
),
846 /* --- Column #6 --- */
848 pColumn
= gtk_tree_view_column_new_with_attributes(
851 "text", COL_MEDIALOCATION
,
854 gtk_tree_view_append_column(
855 GTK_TREE_VIEW(pChild
),
858 /* Create the store */
859 pListStore
= gtk_list_store_new(
861 GDK_TYPE_PIXBUF
, /* COL_ICON */
862 G_TYPE_STRING
, /* COL_NAME */
863 G_TYPE_STRING
, /* COL_SIZE */
864 G_TYPE_STRING
, /* COL_TIME */
865 G_TYPE_UINT
, /* COL_MEDIAID */
866 GDK_TYPE_PIXBUF
, /* COL_MEDIAICON */
867 G_TYPE_STRING
, /* COL_MEDIANAME */
868 G_TYPE_STRING
); /* COL_MEDIALOCATION */
870 /* Create a new scrolled window, with scrollbars only if needed */
872 pScrolledWindow
= gtk_scrolled_window_new(NULL
, NULL
);
874 gtk_scrolled_window_set_policy(
875 GTK_SCROLLED_WINDOW(pScrolledWindow
),
876 GTK_POLICY_AUTOMATIC
,
877 GTK_POLICY_AUTOMATIC
);
880 GTK_CONTAINER(pScrolledWindow
),
883 gtk_table_attach(GTK_TABLE(pTableMain
), pScrolledWindow
, 0, 1, 1, 2,
890 gtk_tree_view_set_model(GTK_TREE_VIEW(pChild
), GTK_TREE_MODEL(pListStore
));
892 g_object_set_data(G_OBJECT(pSearchWindow
), KEY_STORE
, pListStore
);
894 /* Add main table to top window */
895 gtk_container_add(GTK_CONTAINER(pSearchWindow
), pTableMain
);
897 gtk_window_set_default_size(GTK_WINDOW(pSearchWindow
), 600, 400);
899 gtk_widget_show_all(pSearchWindow
);
902 /*****************************************************************************
906 * !!! WARNING !!! Following lines are automatically updated by the CVS system.
909 * Revision 1.5 2005/02/18 02:12:08 nedko
910 * Use path module to access project specific data files.
912 * Revision 1.4 2004/09/18 21:34:59 nedko
913 * Return media name, media type and media location when searching files.
915 * Revision 1.3 2004/09/01 05:05:43 nedko
916 * Search partitially works.
918 * Revision 1.2 2004/09/01 00:56:43 nedko
920 * Attach callback for search action.
922 * Revision 1.1 2004/08/31 22:40:15 nedko
923 * Partitally implemented search feature.
925 *****************************************************************************/