Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

gtask-ui-util.c

Go to the documentation of this file.
00001 #include "gtask-ui-util.h"
00002 
00003 #include <string.h>
00004 #include <glib.h>
00005 #include <libgnomevfs/gnome-vfs-ops.h>
00006 #include <gtask/gtask-file.h>
00007 
00008 #include "gtask-internals.h"
00009 
00011 #define valid_uri(uri) ( uri && strlen( uri ) > 0 )
00012 
00013 static void
00014 agg_file_list( gpointer key, gpointer value, gpointer data ) {
00015     GList **list = (GList **) data;
00016 
00017     *list = g_list_insert_sorted( *list, key, g_str_equal );
00018 }
00019 
00020 GTaskFileListInfo *
00021 gtask_ui_get_file_list_info( GList *file_list ) {
00022     GHashTable        *dir_hash = g_hash_table_new( g_str_hash, g_str_equal );
00023     GTaskFileListInfo *info = g_new0( GTaskFileListInfo, 1 );
00024     gchar             *curr_dir = g_get_current_dir( );
00025     GList             *dir_list = NULL;
00026 
00027     info->files = file_list;
00028 
00029     while( file_list ) {
00030         GTaskFile  *file = (GTaskFile *) file_list->data;
00031         const char *uri = gtask_file_get_uri( file );
00032         char       *dir_uri;
00033 
00034         if( gtask_file_get_completed( file ) ) {
00035             info->num_completed_files++;
00036         }
00037 
00038         dir_uri = g_path_get_dirname( uri );
00039 
00040         if( strcmp( dir_uri, "." ) == 0 ) {
00041             g_free( dir_uri );
00042             dir_uri = g_strdup( curr_dir );
00043         }
00044 
00045         if( g_hash_table_lookup( dir_hash, dir_uri ) )
00046             g_free( dir_uri );
00047         else
00048             g_hash_table_insert( dir_hash, dir_uri, GINT_TO_POINTER( 1 ) );
00049 
00050         info->num_files++;
00051         file_list = g_list_next( file_list );
00052     }
00053 
00056     g_free( curr_dir );
00057 
00058     g_hash_table_foreach( dir_hash, agg_file_list, &dir_list );
00059 
00060     info->num_unique_directories = g_list_length( dir_list );
00061     info->unique_directories = dir_list;
00062 
00063     g_hash_table_destroy( dir_hash );
00064 
00065     return info;
00066 }
00067 
00068 void
00069 gtask_ui_file_list_info_free( GTaskFileListInfo *info ) {
00070     g_list_free( info->files );
00071 
00072     g_list_foreach( info->unique_directories, (GFunc) g_free, NULL );
00073     g_list_free( info->unique_directories );
00074 
00075     g_free( info );
00076 }
00077 
00078 GTaskPreview *
00079 gtask_preview_new( gchar *uri, gboolean is_thumbnail ) {
00080     GTaskPreview *preview = g_new0( GTaskPreview, 1 );
00081 
00082     preview->uri = uri;
00083     preview->is_thumbnail = is_thumbnail;
00084 
00085     return preview;
00086 }
00087 
00088 GSList *
00089 gtask_ui_get_task_preview_options( GTaskGenericTask *task ) {
00090     GSList             *previews = NULL;
00091 
00092     GList              *file_list;
00093 
00094     const char         *uri;
00095 
00096     uri = gtask_generic_task_get_thumbnail_uri( task );
00097 
00098     if( valid_uri( uri ) ) {
00099         previews = g_slist_append( previews,
00100                                    gtask_preview_new( g_strdup( uri ), TRUE ) );
00101     }
00102 
00103     file_list = gtask_generic_task_get_files( task );
00104 
00105     if( g_list_length( file_list ) == 1 ) {
00106         GTaskFile *file = (GTaskFile *) file_list->data;
00107         GSList    *file_previews;
00108 
00109         file_previews = gtask_ui_get_file_preview_options( file );
00110 
00111         previews = g_slist_concat( previews, file_previews );
00112     } else {
00113         gchar *uri = g_build_filename( DATADIR,
00114                                        "pixmaps",
00115                                        "gnome-other.png",
00116                                        NULL );
00117 
00118         previews = g_slist_append( previews,
00119                                    gtask_preview_new( uri, FALSE ) );
00120     }
00121 
00122     return previews;
00123 }
00124 
00125 /* resolution order:
00126  * if the file is completed thumbnail that
00127  * then use the thumbnail uri
00128  * then use the main mime type
00129  * then use the fallback mime type
00130  * then use the best dinky graphic in the west boys!
00131  */
00132 GSList *
00133 gtask_ui_get_file_preview_options( GTaskFile *file ) {
00134     GSList      *previews = NULL;
00135     const gchar *uri;
00136     const gchar *mime_type;
00137 
00138     g_return_val_if_fail( GTASK_IS_FILE( file ), NULL );
00139 
00140     if( gtask_file_get_completed( file ) ) {
00141         const char *uri = gtask_file_get_uri( file );
00142 
00143         if( valid_uri( uri ) ) {
00144           previews = g_slist_append( previews,
00145                                    gtask_preview_new( g_strdup( uri ), TRUE ) );
00146         }
00147     }
00148 
00149     uri = gtask_file_get_thumbnail_uri( file );
00150 
00151     if( valid_uri( uri ) ) {
00152         g_slist_append( previews,
00153                        gtask_preview_new( g_strdup( uri ), TRUE ) );
00154     }
00155 
00156     mime_type = gtask_file_get_mime_type( file );
00157 
00158     if( mime_type ) {
00159         gchar **mime_split = g_strsplit( mime_type, "/", -1 );
00160         gchar  *mime_type_icon;
00161         gchar  *mime_type_uri;
00162 
00163         if( mime_split && mime_split[0] && mime_split[1] ) {
00164             mime_type_icon = g_strdup_printf( "gnome-mime-%s-%s.png",
00165                                               mime_split[0],
00166                                               mime_split[1] );
00167 
00168             mime_type_uri = g_build_filename( DATADIR,
00169                                               "pixmaps",
00170                                               "mimetypes",
00171                                               mime_type_icon,
00172                                               NULL );
00173 
00174             previews = g_slist_append( previews,
00175                                     gtask_preview_new( mime_type_uri, FALSE ) );
00176 
00177             g_free( mime_type_icon );
00178         }
00179 
00180         if( mime_split && mime_split[0] ) {
00181             mime_type_icon = g_strdup_printf( "gnome-mime-%s.png",
00182                                               mime_split[0] );
00183 
00184             mime_type_uri = g_build_filename( DATADIR,
00185                                               "pixmaps",
00186                                               "mimetypes",
00187                                               mime_type_icon,
00188                                               NULL );
00189 
00190             previews = g_slist_append( previews,
00191                                     gtask_preview_new( mime_type_uri, FALSE ) );
00192 
00193             g_free( mime_type_icon );
00194         } 
00195 
00196         g_strfreev( mime_split ); 
00197     }
00198 
00199     /* uber default here -- just an open umm . . box, yeah, just a box for the
00200      * moment */
00201     {
00202         gchar *uri = g_build_filename( DATADIR,
00203                                        "pixmaps",
00204                                        "gnome-other.png",
00205                                        NULL );
00206 
00207         previews = g_slist_append( previews,
00208                                    gtask_preview_new( uri, FALSE ) );
00209     }
00210 
00211     return previews;
00212 }
00213 
00214 void
00215 gtask_preview_free( GTaskPreview *preview ) {
00216     g_free( preview->uri );
00217 
00218     g_free( preview );
00219 }
00220 
00221 void
00222 gtask_preview_list_free( GSList *list ) {
00223     g_slist_foreach( list, (GFunc) gtask_preview_free, NULL );
00224 
00225     g_slist_free( list );
00226 }
00227 
00228 
00229 /* figures out how to get the preview -- either via thumbnailing
00230  * or ummm . . regular stuff . . and gets it, or maybe it doesn't
00231  * in which case -- tough luck buster
00232  *
00233  * @todo right now thumbnail generation happens in the main thread
00234  *       in the future it would be nice if we could delegate this off to
00235  *       another thread, return an intermediary preview and then
00236  *       register some callback to be run when the better preview is
00237  *       available.
00238  */
00239 GdkPixbuf *
00240 gtask_preview_get_pixbuf( GTaskPreview *preview,
00241                           GnomeThumbnailFactory *factory  )
00242 {
00243     GdkPixbuf             *pix_buf = NULL;
00244     GnomeVFSFileInfo       info;
00245     char                  *thumb_uri;
00246 
00247     if( preview->is_thumbnail ) {
00248         GnomeVFSResult res = gnome_vfs_get_file_info( preview->uri, &info,
00249                                             GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
00250                                             GNOME_VFS_FILE_INFO_DEFAULT );
00251 
00252         if( res != GNOME_VFS_OK )
00253             return NULL;
00254 
00255 
00256         thumb_uri = gnome_thumbnail_factory_lookup( factory,
00257                                                     preview->uri,
00258                                                     info.mtime );
00259 
00260         if( thumb_uri ) {
00261             pix_buf = gdk_pixbuf_new_from_file( thumb_uri, NULL );
00262         } else {
00263             pix_buf = gnome_thumbnail_factory_generate_thumbnail( factory,
00264                                                                preview->uri,
00265                                                                info.mime_type );
00266 
00267             if( pix_buf ) {
00268                 gnome_thumbnail_factory_save_thumbnail( factory,
00269                                                         pix_buf,
00270                                                         preview->uri,
00271                                                         info.mtime );
00272             } else {
00273                 gnome_thumbnail_factory_create_failed_thumbnail( factory,
00274                                                                  preview->uri,
00275                                                                  info.mtime );
00276             }
00277         }
00278     } else {
00279         pix_buf = gdk_pixbuf_new_from_file( preview->uri, NULL );
00280     }
00281 
00282     return pix_buf;
00283 }
00284 
00285 /*
00286 GdkPixBuf *
00287 gtask_ui_render_final_preview( GdkPixbuf *pixbuf,
00288                                GdkPixbuf *frame,
00289                                gboolean is_thumbnail,
00290                                guint bound )
00291 {
00292 }
00293 */
00294 
00297 void
00298 gtask_ui_draw_progressbar( GtkWidget *widget,
00299                         GdkWindow *window,
00300                         GdkRectangle *area,
00301                         float progress,
00302                         GTaskActivityState state,
00303                         int x,
00304                         int y,
00305                         int width,
00306                         int height )
00307 {
00308     GdkGC     *gc;
00309     GdkColor  *color;
00310     GtkStyle  *text_style;
00311     int        perc_w;
00312 
00313     g_debug( "IN: gtask_draw_progressbar" );
00314 
00315     gc = gdk_gc_new( window );
00316 
00317     /* Draw the outline */
00318     gdk_gc_set_rgb_fg_color( gc, &widget->style->fg[GTK_STATE_NORMAL] );
00319     gdk_draw_rectangle( window, gc, TRUE, x, y, width, height );
00320 
00321     /* Draw the interior */
00322     gdk_gc_set_rgb_fg_color( gc, &widget->style->bg[GTK_STATE_NORMAL] );
00323     gdk_draw_rectangle( window, gc, TRUE, x + 1, y + 1, width - 2, height - 2 );
00324 
00325     perc_w = width - 4;
00326     perc_w = (int) ( perc_w * progress );
00327 
00328     switch( state ) {
00329         case GTASK_ACTIVITY_STATE_ACTIVE:
00330             color = &widget->style->bg[GTK_STATE_SELECTED];
00331             text_style = gtk_style_copy( widget->style );
00332             break;
00333         case GTASK_ACTIVITY_STATE_INACTIVE:
00334             color = &widget->style->bg[GTK_STATE_INSENSITIVE];
00335             text_style = gtk_style_copy( widget->style );
00336             break;
00337         case GTASK_ACTIVITY_STATE_COMPLETED:
00338             color = &widget->style->fg[GTK_STATE_NORMAL];
00339 
00342             text_style = gtk_style_copy( widget->style );
00343 
00344             text_style->fg[GTK_STATE_NORMAL] = widget->style->bg[GTK_STATE_NORMAL];
00345             text_style->bg[GTK_STATE_NORMAL] = widget->style->fg[GTK_STATE_NORMAL];
00346             break;
00347         default:
00348             color = &widget->style->fg[GTK_STATE_NORMAL];
00349             text_style = gtk_style_copy( widget->style );
00350             break;
00351     }
00352 
00353     gtk_style_attach( text_style, window );
00354 
00355     /* Draw the actual progress bar */
00356     gdk_gc_set_rgb_fg_color( gc, color );
00357     gdk_draw_rectangle( window, gc, TRUE, x + 2, y + 2, perc_w, height - 4);
00358 
00359     /* negative progress values imply that we are hiding the
00360      * progressbar text */
00361     if( progress >= 0 ) {
00362         int             pos;
00363         GtkStateType    gtk_state;
00364         PangoLayout    *layout;
00365         PangoRectangle  logical_rect;
00366         GdkRectangle   *cell_area = NULL;
00367         char           *text = g_strdup_printf ("%.0f%%", progress * 100);
00368 
00369         if( area == NULL )
00370             cell_area = g_new0( GdkRectangle, 1 );
00371         else 
00372             cell_area = area;
00373 
00374         layout = gtk_widget_create_pango_layout( widget, text );
00375 
00376         pango_layout_get_pixel_extents( layout, NULL, &logical_rect );
00377 
00378         pos = ( width - logical_rect.width ) / 2;
00379 
00380         /* Determine the state to render the text in */
00381         if( state == GTASK_ACTIVITY_STATE_INACTIVE ) {
00382             gtk_state = GTK_STATE_INSENSITIVE;
00383         } else if( state == GTASK_ACTIVITY_STATE_COMPLETED ) {
00384             gtk_state = GTK_STATE_NORMAL;
00385         } else if( perc_w < pos + logical_rect.width / 2 )
00386             gtk_state = GTK_STATE_NORMAL;
00387         else
00388             gtk_state = GTK_STATE_SELECTED;
00389 
00390         /* TODO -- need to get rectangle to draw on */
00391         //gtk_paint_layout( widget->style,
00392         gtk_paint_layout( text_style,
00393                           window,
00394                           gtk_state,
00395                           FALSE,
00396                           cell_area,
00397                           widget,
00398                           "progressbar",
00399                           x + pos,
00400                           y + ( height - logical_rect.height ) / 2 - 1,
00401                           layout );
00402 
00403         if( area == NULL )
00404                 g_object_unref( G_OBJECT( cell_area ) );
00405 
00406         g_free( text );
00407         g_object_unref( G_OBJECT( layout ) );
00408 
00409     }
00410 
00411     g_object_unref( G_OBJECT( gc ) );
00412     g_object_unref( G_OBJECT( text_style ) );
00413 
00414     g_debug( "LEAVING: gtask_draw_progressbar" );
00415 }

Generated on Mon Feb 2 21:33:25 2004 for libgtask-ui by doxygen 1.3.4