MySQL realated stuff documented.
[mediadatabase.git] / gtk / media.c
blob0dbd864bd4870e617824e1bad8a11310a0a1e159
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*****************************************************************************
4 * $Id: media.c,v 1.9 2005/02/20 15:32:23 nedko Exp $
6 * DESCRIPTION:
7 *
9 * NOTES:
12 *****************************************************************************/
14 #include <time.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <stdio.h>
18 #include <gtk/gtk.h>
20 #include "../result.h"
21 #include "../libdb/libdb.h"
22 #include "../libfrontend/db.h"
23 #include "../libfrontend/error.h"
24 #include "common.h"
25 #include "media.h"
26 #include "helper.h"
27 #include "path.h"
28 #include "glade.h"
30 enum
32 COL_ICON,
33 COL_NAME,
34 COL_PATH,
35 COL_SIZE,
36 COL_TIME,
37 NUM_COLS
40 struct InsertChildsContext
42 GtkTreeStore *pTreeStore;
43 GtkTreeIter *pIter;
46 struct MediaWindowContext
48 mediadb_uint nMediaID;
51 static void
52 InsertPseudoChild(
53 GtkTreeStore *pTreeStore,
54 GtkTreeIter *pIter
57 GtkTreeIter IterChild;
59 gtk_tree_store_append(
60 pTreeStore,
61 &IterChild,
62 pIter);
65 static
66 void
67 file_callback(
68 void *pUserContext,
69 const char *pszPath,
70 const char *pszName,
71 mediadb_filetype Filetype,
72 mediadb_uint nSize,
73 mediadb_uint nTime)
75 GtkTreeIter IterChild;
76 gchar *pszFullPath;
77 char strTime[26];
78 time_t time = nTime;
79 char strSize[MAX_SIZE_DESCRIPTION];
80 struct tm tm;
81 GdkPixbuf * pIcon;
82 GError * error = NULL;
83 char * pszIcon;
84 gchar * pszIconFullname;
86 localtime_r(&time, &tm);
87 sprintf(strTime,
88 "%u-%02u-%02u %02u:%02u:%02u",
89 1900+tm.tm_year,
90 1+tm.tm_mon,
91 tm.tm_mday,
92 tm.tm_hour,
93 tm.tm_min,
94 tm.tm_sec);
96 get_size_description(nSize, strSize);
98 pIcon = NULL;
100 if (Filetype == MEDIADB_FILETYPE_DIR)
102 pszIcon = "icon_folder.png";
104 else
106 pszIcon = "icon_unknown.png";
109 pszIconFullname = path_get_data_filename(pszIcon);
110 if (pszIconFullname != NULL)
112 pIcon = gdk_pixbuf_new_from_file(pszIconFullname, &error);
113 if (error)
115 g_warning("Could not load icon: %s\n", error->message);
116 g_error_free(error);
117 error = NULL;
120 g_free(pszIconFullname);
122 else
124 g_warning("Could not find icon %s\n", pszIcon);
127 gtk_tree_store_append(
128 ((struct InsertChildsContext *)pUserContext)->pTreeStore,
129 &IterChild,
130 ((struct InsertChildsContext *)pUserContext)->pIter);
132 gtk_tree_store_set(
133 ((struct InsertChildsContext *)pUserContext)->pTreeStore,
134 &IterChild,
135 COL_ICON, pIcon,
136 COL_NAME, pszName,
137 COL_SIZE, (Filetype == MEDIADB_FILETYPE_DIR)?NULL:strSize,
138 COL_TIME, strTime,
139 -1);
141 if (Filetype == MEDIADB_FILETYPE_DIR)
143 InsertPseudoChild(
144 ((struct InsertChildsContext *)pUserContext)->pTreeStore,
145 &IterChild);
147 pszFullPath = g_malloc(strlen(pszPath)+strlen(pszName)+1);
148 sprintf(pszFullPath, "%s%s", pszPath, pszName);
149 gtk_tree_store_set(
150 ((struct InsertChildsContext *)pUserContext)->pTreeStore,
151 &IterChild,
152 COL_PATH, pszFullPath,
153 -1);
154 g_free(pszFullPath);
158 static void
159 InsertChilds(
160 mediadb_uint nMediaID,
161 GtkTreeStore *pTreeStore,
162 const char *pszPath,
163 GtkTreeIter *pIter
166 struct InsertChildsContext context;
167 mediadb_result r;
169 context.pTreeStore = pTreeStore;
170 context.pIter = pIter;
172 r = mediadb_files_get(
173 g_hDB,
174 nMediaID,
175 pszPath,
176 file_callback,
177 &context);
179 if (MEDIADB_IS_ERROR(r))
181 mediadb_error_printf(
182 MEDIADB_ERROR_NONCRITICAL,
183 "Cannot retrieve contents of \"%s/\" directory from media with ID %u (%s)",
184 pszPath,
185 (unsigned int)nMediaID,
186 mediadb_get_error_message(g_hDB));
190 void
191 OnRowExpanded(
192 GtkTreeView *pTreeView,
193 GtkTreeIter *pIter,
194 GtkTreePath *pPath,
195 gpointer pUserData)
197 GtkTreeModel *pModel;
198 gchar *pszPath;
199 GtkTreeIter IterChild;
201 pModel = gtk_tree_view_get_model(pTreeView);
203 if (!gtk_tree_model_iter_children(pModel, &IterChild, pIter))
204 return;
206 gtk_tree_model_get(pModel, pIter, COL_PATH, &pszPath, -1);
208 InsertChilds(
209 ((struct MediaWindowContext *)pUserData)->nMediaID,
210 GTK_TREE_STORE(pModel),
211 pszPath,
212 pIter);
214 g_free(pszPath);
216 gtk_tree_store_remove(GTK_TREE_STORE(pModel), &IterChild);
219 void
220 OnRowCollapsed(
221 GtkTreeView *pTreeView,
222 GtkTreeIter *pIter,
223 GtkTreePath *pPath,
224 gpointer pUserData)
226 GtkTreeModel *pModel;
227 GtkTreeIter IterChild;
229 pModel = gtk_tree_view_get_model(pTreeView);
231 if (!gtk_tree_model_iter_children(pModel, &IterChild, pIter))
232 return;
236 gtk_tree_store_remove(GTK_TREE_STORE(pModel), &IterChild);
238 while (gtk_tree_model_iter_children(pModel, &IterChild, pIter));
240 InsertPseudoChild(GTK_TREE_STORE(pModel), pIter);
243 void
244 OnMediaWindowDestroy(
245 GtkObject *object,
246 gpointer user_data)
248 g_free(user_data);
251 void
252 CreateMediaWindow(mediadb_uint nMediaID)
254 mediadb_result r;
255 mediadb_uint nTimeAdded;
256 mediadb_uint nTotalFiles;
257 mediadb_uint nTotalSize;
258 char *pszTitle;
259 GtkWidget *pDialog;
260 GtkWidget *pMediaWindow = NULL;
261 GtkWidget *pChild;
262 GtkCellRenderer * pRendererText;
263 GtkCellRenderer * pRendererPixbuf;
264 GtkTreeViewColumn * pColumn;
265 GtkTreeStore *pTreeStore;
266 struct MediaWindowContext * pContext;
267 GString * str;
268 char strTime[26];
269 char strTotalSize[MAX_SIZE_DESCRIPTION];
270 mediadb_mediatype nType;
271 time_t time;
272 struct tm tm;
273 mediadb_uint nLocationID;
274 mediadb_uint nLocationTypeID;
275 char *pszLocation;
276 char *pszLocationType;
278 r = mediadb_media_get_properties(
279 g_hDB,
280 nMediaID,
281 &nTimeAdded,
282 &nType,
283 &nLocationID,
284 &pszTitle);
285 if (MEDIADB_IS_ERROR(r))
287 g_warning("%s\n", mediadb_get_error_message(g_hDB));
289 pDialog = gtk_message_dialog_new(
290 GTK_WINDOW(pMainWindow),
291 GTK_DIALOG_DESTROY_WITH_PARENT,
292 GTK_MESSAGE_ERROR,
293 GTK_BUTTONS_CLOSE,
294 "%s",
295 mediadb_get_error_message(g_hDB));
297 gtk_dialog_run(GTK_DIALOG(pDialog));
298 gtk_widget_destroy(pDialog);
300 return;
303 if (nType != MEDIADB_MT_DATA)
305 g_warning("Only data cd type is supported.\n");
307 pDialog = gtk_message_dialog_new(
308 GTK_WINDOW(pMainWindow),
309 GTK_DIALOG_DESTROY_WITH_PARENT,
310 GTK_MESSAGE_ERROR,
311 GTK_BUTTONS_CLOSE,
312 "Only data cd type is supported.");
314 gtk_dialog_run(GTK_DIALOG(pDialog));
315 gtk_widget_destroy(pDialog);
316 free(pszTitle);
317 return;
320 r = mediadb_location_get_properties(
321 g_hDB,
322 nLocationID,
323 &nLocationTypeID,
324 &pszLocation);
325 if (MEDIADB_IS_ERROR(r))
327 g_warning("%s\n", mediadb_get_error_message(g_hDB));
329 pDialog = gtk_message_dialog_new(
330 GTK_WINDOW(pMainWindow),
331 GTK_DIALOG_DESTROY_WITH_PARENT,
332 GTK_MESSAGE_ERROR,
333 GTK_BUTTONS_CLOSE,
334 "%s",
335 mediadb_get_error_message(g_hDB));
337 gtk_dialog_run(GTK_DIALOG(pDialog));
338 gtk_widget_destroy(pDialog);
340 free(pszTitle);
341 return;
344 r = mediadb_location_type_get_properties(
345 g_hDB,
346 nLocationTypeID,
347 &pszLocationType);
348 if (MEDIADB_IS_ERROR(r))
350 g_warning("%s\n", mediadb_get_error_message(g_hDB));
352 pDialog = gtk_message_dialog_new(
353 GTK_WINDOW(pMainWindow),
354 GTK_DIALOG_DESTROY_WITH_PARENT,
355 GTK_MESSAGE_ERROR,
356 GTK_BUTTONS_CLOSE,
357 "%s",
358 mediadb_get_error_message(g_hDB));
360 gtk_dialog_run(GTK_DIALOG(pDialog));
361 gtk_widget_destroy(pDialog);
363 free(pszTitle);
364 free(pszLocation);
365 return;
368 r = mediadb_media_get_properties_data(
369 g_hDB,
370 nMediaID,
371 &nTotalFiles,
372 &nTotalSize);
373 if (MEDIADB_IS_ERROR(r))
375 g_warning("%s\n", mediadb_get_error_message(g_hDB));
377 pDialog = gtk_message_dialog_new(
378 GTK_WINDOW(pMainWindow),
379 GTK_DIALOG_DESTROY_WITH_PARENT,
380 GTK_MESSAGE_ERROR,
381 GTK_BUTTONS_CLOSE,
382 "%s",
383 mediadb_get_error_message(g_hDB));
385 gtk_dialog_run(GTK_DIALOG(pDialog));
386 gtk_widget_destroy(pDialog);
388 free(pszTitle);
389 free(pszLocation);
390 free(pszLocationType);
391 return;
394 time = nTimeAdded;
395 localtime_r(&time, &tm);
396 sprintf(strTime,
397 "%u-%02u-%02u %02u:%02u:%02u",
398 1900+tm.tm_year,
399 1+tm.tm_mon,
400 tm.tm_mday,
401 tm.tm_hour,
402 tm.tm_min,
403 tm.tm_sec);
405 get_size_description(nTotalSize, strTotalSize);
407 pContext = g_malloc(sizeof(struct MediaWindowContext));
408 pContext->nMediaID = nMediaID;
410 pMediaWindow = construct_glade_widget("media_window");
412 gtk_window_set_title(GTK_WINDOW(pMediaWindow),
413 pszTitle);
415 g_signal_connect(
416 G_OBJECT(pMediaWindow),
417 "destroy",
418 G_CALLBACK(OnMediaWindowDestroy),
419 pContext);
421 /* -- name -- */
422 gtk_label_set_text(GTK_LABEL(get_glade_widget_child(pMediaWindow, "media_window_label_name_data")), pszTitle);
423 free(pszTitle);
425 str = g_string_sized_new(100);
427 /* -- id -- */
428 g_string_printf(str, "%u", (unsigned int)nMediaID);
429 gtk_label_set_text(GTK_LABEL(get_glade_widget_child(pMediaWindow, "media_window_label_id_data")), str->str);
431 /* -- time -- */
432 gtk_label_set_text(GTK_LABEL(get_glade_widget_child(pMediaWindow, "media_window_label_time_data")), strTime);
434 /* -- location -- */
435 pChild = get_glade_widget_child(pMediaWindow, "media_window_label_location_data");
436 if (*pszLocation == 0)
438 gtk_label_set_text(GTK_LABEL(pChild), "");
440 else if (*pszLocationType == 0)
442 g_string_printf(str, "%s", pszLocation);
443 gtk_label_set_text(GTK_LABEL(pChild), str->str);
445 else
447 g_string_printf(str, "%s (%s)", pszLocation, pszLocationType);
448 gtk_label_set_text(GTK_LABEL(pChild), str->str);
451 /* -- type -- */
452 /* "Data CD" os hardcoded until we have support for something else */
453 gtk_label_set_text(GTK_LABEL(get_glade_widget_child(pMediaWindow, "media_window_label_type_data")), "Data CD");
455 /* -- files_count -- */
456 g_string_printf(str, "%u", (unsigned int)nTotalFiles);
457 gtk_label_set_text(GTK_LABEL(get_glade_widget_child(pMediaWindow, "media_window_label_files_count_data")), str->str);
459 /* -- size -- */
460 gtk_label_set_text(GTK_LABEL(get_glade_widget_child(pMediaWindow, "media_window_label_size_data")), strTotalSize);
462 /* Tree view */
463 pChild = get_glade_widget_child(pMediaWindow, "treeview");
465 pRendererText = gtk_cell_renderer_text_new();
466 pRendererPixbuf = gtk_cell_renderer_pixbuf_new();
468 /* --- Column #1 --- */
470 pColumn = gtk_tree_view_column_new();
471 gtk_tree_view_column_set_title(pColumn, "Name");
473 gtk_tree_view_column_pack_start(pColumn, pRendererPixbuf, FALSE);
474 gtk_tree_view_column_set_attributes(pColumn, pRendererPixbuf,
475 "pixbuf", COL_ICON,
476 NULL);
478 gtk_tree_view_column_pack_start(pColumn, pRendererText, TRUE);
479 gtk_tree_view_column_set_attributes(pColumn,
480 pRendererText,
481 "text", COL_NAME,
482 NULL);
484 gtk_tree_view_append_column(
485 GTK_TREE_VIEW(pChild),
486 pColumn);
488 /* --- Column #2 --- */
490 pColumn = gtk_tree_view_column_new_with_attributes(
491 "Size",
492 pRendererText,
493 "text", COL_SIZE,
494 NULL);
496 gtk_tree_view_append_column(
497 GTK_TREE_VIEW(pChild),
498 pColumn);
500 /* --- Column #3 --- */
502 pColumn = gtk_tree_view_column_new_with_attributes(
503 "Time",
504 pRendererText,
505 "text", COL_TIME,
506 NULL);
508 gtk_tree_view_append_column(
509 GTK_TREE_VIEW(pChild),
510 pColumn);
512 /* Create the store */
513 pTreeStore = gtk_tree_store_new(
514 NUM_COLS,
515 GDK_TYPE_PIXBUF,
516 G_TYPE_STRING,
517 G_TYPE_STRING,
518 G_TYPE_STRING,
519 G_TYPE_STRING);
521 /* Fill the top level items in store */
523 InsertChilds(nMediaID, pTreeStore, NULL, NULL);
525 /* connect the row-expanded and row-collapsed signals */
526 g_signal_connect(
527 pChild,
528 "row-expanded",
529 G_CALLBACK(OnRowExpanded),
530 pContext);
532 g_signal_connect(
533 pChild,
534 "row-collapsed",
535 G_CALLBACK(OnRowCollapsed),
536 pContext);
538 /* Set model */
539 gtk_tree_view_set_model(GTK_TREE_VIEW(pChild), GTK_TREE_MODEL(pTreeStore));
541 gtk_widget_show_all(pMediaWindow);
544 /*****************************************************************************
546 * Modifications log:
548 * !!! WARNING !!! Following lines are automatically updated by the CVS system.
550 * $Log: media.c,v $
551 * Revision 1.9 2005/02/20 15:32:23 nedko
552 * Align labels in media dialog in glade
554 * Revision 1.8 2005/02/19 13:38:56 nedko
555 * Remove disabled pre-glade code.
557 * Revision 1.7 2005/02/19 00:26:42 nedko
558 * Add prefix to media window label names
560 * Revision 1.6 2005/02/19 00:21:32 nedko
561 * Switch media window to glade
563 * Revision 1.5 2005/02/18 02:12:08 nedko
564 * Use path module to access project specific data files.
566 * Revision 1.4 2004/08/31 22:40:15 nedko
567 * Partitally implemented search feature.
569 * Revision 1.3 2004/08/08 00:47:42 nedko
570 * Get more info for media from database.
572 * Revision 1.2 2004/05/22 00:36:24 nedko
573 * set WM_WINDOWS_ROLE
575 * Revision 1.1 2004/05/21 23:43:38 nedko
576 * Implement media window.
578 *****************************************************************************/