~ubuntu-branches/ubuntu/trusty/pcmanfm/trusty-proposed

« back to all changes in this revision

Viewing changes to src/ptk/ptk-file-list.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Lee
  • Date: 2008-09-26 10:19:20 UTC
  • mfrom: (4.1.5 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080926101920-cfldybkmwgwrtv9u
Tags: 0.5-3
* Correct spellings,  03_correct_spelling.dpatch (Closes:498794) 
* Code in some files are taken from other projects, added these
  informations into copyright file. (Closes:499678)
* Applied 04_defaut_terminal.dpatch to support x-terminal-emulator
  alternative. (Closes:497494) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
*  C Implementation: ptk-file-list
3
3
*
4
 
* Description: 
 
4
* Description:
5
5
*
6
6
*
7
7
* Author: Hong Jen Yee (PCMan) <pcman.tw (AT) gmail.com>, (C) 2006
15
15
 
16
16
#include "glib-mem.h"
17
17
#include "vfs-file-info.h"
 
18
#include "vfs-thumbnail-loader.h"
 
19
 
 
20
#include <string.h>
18
21
 
19
22
static void ptk_file_list_init ( PtkFileList *list );
20
23
 
94
97
 
95
98
/* signal handlers */
96
99
 
97
 
static void ptk_file_list_file_created( VFSDir* dir, VFSFileInfo* file,
98
 
                                        PtkFileList* list );
99
 
 
100
 
static void ptk_file_list_file_deleted( VFSDir* dir, VFSFileInfo* file,
101
 
                                        PtkFileList* list );
102
 
 
103
 
static void ptk_file_list_file_changed( VFSDir* dir, VFSFileInfo* file,
104
 
                                        PtkFileList* list );
105
 
 
 
100
static void on_thumbnail_loaded( VFSDir* dir, VFSFileInfo* file, PtkFileList* list );
 
101
 
 
102
/*
 
103
 * already declared in ptk-file-list.h
 
104
void ptk_file_list_file_created( VFSDir* dir, VFSFileInfo* file,
 
105
                                        PtkFileList* list );
 
106
 
 
107
void ptk_file_list_file_deleted( VFSDir* dir, VFSFileInfo* file,
 
108
                                        PtkFileList* list );
 
109
 
 
110
void ptk_file_list_file_changed( VFSDir* dir, VFSFileInfo* file,
 
111
                                        PtkFileList* list );
 
112
*/
106
113
 
107
114
static GObjectClass* parent_class = NULL;
108
115
 
109
116
static GType column_types[ N_FILE_LIST_COLS ];
110
117
 
111
 
 
112
 
typedef struct _ThumbThreadData
113
 
{
114
 
    PtkFileList* list;
115
 
    gboolean big;
116
 
}ThumbThreadData;
117
 
 
118
 
 
119
118
GType ptk_file_list_get_type ( void )
120
119
{
121
120
    static GType type = 0;
257
256
    return list;
258
257
}
259
258
 
 
259
static void _ptk_file_list_file_changed( VFSDir* dir, VFSFileInfo* file,
 
260
                                        PtkFileList* list )
 
261
{
 
262
    ptk_file_list_file_changed( dir, file, list );
 
263
 
 
264
    /* check if reloading of thumbnail is needed. */
 
265
    if( vfs_file_info_is_image( file )
 
266
        && vfs_file_info_get_size( file ) < list->max_thumbnail )
 
267
    {
 
268
        if( ! vfs_file_info_is_thumbnail_loaded( file, list->big_thumbnail ) )
 
269
            vfs_thumbnail_loader_request( list->dir, file, list->big_thumbnail );
 
270
    }
 
271
}
 
272
 
 
273
static void _ptk_file_list_file_created( VFSDir* dir, VFSFileInfo* file,
 
274
                                        PtkFileList* list )
 
275
{
 
276
    ptk_file_list_file_created( dir, file, list );
 
277
 
 
278
    /* check if reloading of thumbnail is needed. */
 
279
    if( vfs_file_info_is_image( file )
 
280
        && vfs_file_info_get_size( file ) < list->max_thumbnail )
 
281
    {
 
282
        if( ! vfs_file_info_is_thumbnail_loaded( file, list->big_thumbnail ) )
 
283
            vfs_thumbnail_loader_request( list->dir, file, list->big_thumbnail );
 
284
    }
 
285
}
 
286
 
260
287
void ptk_file_list_set_dir( PtkFileList* list, VFSDir* dir )
261
288
{
262
289
    GList* l;
263
 
    int i;
264
 
    VFSFileInfo* file;
265
290
 
266
291
    if( list->dir == dir )
267
292
        return;
270
295
    {
271
296
        if( list->max_thumbnail > 0 )
272
297
        {
273
 
            for( l = list->files; l; l = l->next )
274
 
            {
275
 
                file = (VFSFileInfo*)l->data;
276
 
                if( vfs_file_info_is_image( file )
277
 
                    && vfs_file_info_get_size( file ) < list->max_thumbnail )
278
 
                {
279
 
                    /* FIXME: vfs_dir_cancel_thumbnail_request(  ); */
280
 
                }
281
 
            }
 
298
            /* cancel all possible pending requests */
 
299
            vfs_thumbnail_loader_cancel_all_requests( list->dir, list->big_thumbnail );
282
300
        }
283
301
        g_list_foreach( list->files, (GFunc)vfs_file_info_unref, NULL );
284
302
        g_list_free( list->files );
285
303
        g_signal_handlers_disconnect_by_func( list->dir,
286
 
                                              ptk_file_list_file_created, list );
 
304
                                              _ptk_file_list_file_created, list );
287
305
        g_signal_handlers_disconnect_by_func( list->dir,
288
306
                                              ptk_file_list_file_deleted, list );
289
307
        g_signal_handlers_disconnect_by_func( list->dir,
290
 
                                              ptk_file_list_file_changed, list );
291
 
        vfs_dir_unref( list->dir );
 
308
                                              _ptk_file_list_file_changed, list );
 
309
        g_signal_handlers_disconnect_by_func( list->dir,
 
310
                                              on_thumbnail_loaded, list );
 
311
        g_object_unref( list->dir );
292
312
    }
293
313
 
294
314
    list->dir = dir;
297
317
    if( ! dir )
298
318
        return;
299
319
 
300
 
    vfs_dir_ref( list->dir );
 
320
    g_object_ref( list->dir );
301
321
 
302
322
    g_signal_connect( list->dir, "file-created",
303
 
                      G_CALLBACK(ptk_file_list_file_created),
 
323
                      G_CALLBACK(_ptk_file_list_file_created),
304
324
                      list );
305
325
    g_signal_connect( list->dir, "file-deleted",
306
326
                      G_CALLBACK(ptk_file_list_file_deleted),
307
327
                      list );
308
328
    g_signal_connect( list->dir, "file-changed",
309
 
                      G_CALLBACK(ptk_file_list_file_changed),
 
329
                      G_CALLBACK(_ptk_file_list_file_changed),
310
330
                      list );
311
331
 
312
332
    if( dir && dir->file_list )
316
336
            if( list->show_hidden ||
317
337
                    ((VFSFileInfo*)l->data)->disp_name[0] != '.' )
318
338
            {
319
 
                list->files = g_list_prepend( list->files, l->data );
320
 
                vfs_file_info_ref( (VFSFileInfo*)l->data );
 
339
                list->files = g_list_prepend( list->files, vfs_file_info_ref( (VFSFileInfo*)l->data) );
321
340
                ++list->n_files;
322
341
            }
323
342
        }
425
444
    case COL_FILE_BIG_ICON:
426
445
        icon = NULL;
427
446
        /* special file can use special icons saved as thumbnails*/
428
 
        if( list->max_thumbnail > vfs_file_info_get_size( info ) 
 
447
        if( list->max_thumbnail > vfs_file_info_get_size( info )
429
448
            && info->flags == VFS_FILE_INFO_NONE )
430
449
            icon = vfs_file_info_get_big_thumbnail( info );
 
450
 
431
451
        if( ! icon )
432
452
            icon = vfs_file_info_get_big_icon( info );
433
453
        if( icon )
468
488
        g_value_set_string( value, vfs_file_info_get_disp_mtime(info) );
469
489
        break;
470
490
    case COL_FILE_INFO:
471
 
        vfs_file_info_ref( info );
472
 
        g_value_set_pointer( value, info );
 
491
        g_value_set_pointer( value, vfs_file_info_ref( info ) );
473
492
        break;
474
493
    }
475
494
}
696
715
    g_free( new_order );
697
716
}
698
717
 
 
718
gboolean ptk_file_list_find_iter(  PtkFileList* list, GtkTreeIter* it, VFSFileInfo* fi )
 
719
{
 
720
    GList* l;
 
721
    for( l = list->files; l; l = l->next )
 
722
    {
 
723
        VFSFileInfo* fi2 = (VFSFileInfo*)l->data;
 
724
        if( G_UNLIKELY( fi2 == fi
 
725
            || 0 == strcmp( vfs_file_info_get_name(fi), vfs_file_info_get_name(fi2) ) ) )
 
726
        {
 
727
            it->stamp = list->stamp;
 
728
            it->user_data = l;
 
729
            it->user_data2 = fi2;
 
730
            return TRUE;
 
731
        }
 
732
    }
 
733
    return FALSE;
 
734
}
 
735
 
699
736
void ptk_file_list_file_created( VFSDir* dir,
700
737
                                 VFSFileInfo* file,
701
738
                                 PtkFileList* list )
711
748
    for( l = list->files; l; l = l->next )
712
749
    {
713
750
        file2 = (VFSFileInfo*)l->data;
714
 
        if( ptk_file_list_compare( file2, file, list ) >= 0 )
 
751
        if( G_UNLIKELY( file == file2 || ptk_file_list_compare( file2, file, list ) == 0 ) )
 
752
        {
 
753
            /* The file is already in the list */
 
754
            return;
 
755
        }
 
756
        if( ptk_file_list_compare( file2, file, list ) > 0 )
715
757
        {
716
758
            break;
717
759
        }
718
760
    }
719
761
 
720
 
    list->files = g_list_insert_before( list->files, l, file );
721
 
    vfs_file_info_ref( file );
 
762
    list->files = g_list_insert_before( list->files, l, vfs_file_info_ref( file ) );
722
763
    ++list->n_files;
723
764
 
724
765
    if( l )
744
785
    GList* l;
745
786
    GtkTreePath* path;
746
787
 
 
788
    /* If there is no file info, that means the dir itself was deleted. */
 
789
    if( G_UNLIKELY( ! file ) )
 
790
    {
 
791
        /* Clear the whole list */
 
792
        path = gtk_tree_path_new_from_indices(0, -1);
 
793
        for( l = list->files; l; l = list->files )
 
794
        {
 
795
            gtk_tree_model_row_deleted( GTK_TREE_MODEL(list), path );
 
796
            file = (VFSFileInfo*)l->data;
 
797
            list->files = g_list_delete_link( list->files, l );
 
798
            vfs_file_info_unref( file );
 
799
            --list->n_files;
 
800
        }
 
801
        gtk_tree_path_free( path );
 
802
        return;
 
803
    }
 
804
 
747
805
    if( ! list->show_hidden && vfs_file_info_get_name(file)[0] == '.' )
748
806
        return;
749
807
 
750
808
    l = g_list_find( list->files, file );
751
 
 
752
809
    if( ! l )
753
810
        return;
754
811
 
789
846
    gtk_tree_path_free( path );
790
847
}
791
848
 
 
849
void on_thumbnail_loaded( VFSDir* dir, VFSFileInfo* file, PtkFileList* list )
 
850
{
 
851
    /* g_debug( "LOADED: %s", file->name ); */
 
852
    ptk_file_list_file_changed( dir, file, list );
 
853
}
792
854
 
793
 
void ptk_file_list_show_thumbnails( PtkFileList* list, gboolean big,
 
855
void ptk_file_list_show_thumbnails( PtkFileList* list, gboolean is_big,
794
856
                                    int max_file_size )
795
857
{
796
858
    GList* l;
797
859
    VFSFileInfo* file;
 
860
    int old_max_thumbnail;
798
861
 
 
862
    old_max_thumbnail = list->max_thumbnail;
799
863
    list->max_thumbnail = max_file_size;
800
 
    /* FIXME: This is extremely buggy!!! must be fixed before release
801
 
        Loading of big icons and small ones should be separate threads.
 
864
    list->big_thumbnail = is_big;
 
865
    /* FIXME: This is buggy!!! Further testing might be needed.
802
866
    */
803
867
    if( 0 == max_file_size )
 
868
    {
 
869
        if( old_max_thumbnail > 0 ) /* cancel thumbnails */
 
870
        {
 
871
            vfs_thumbnail_loader_cancel_all_requests( list->dir, list->big_thumbnail );
 
872
            g_signal_handlers_disconnect_by_func( list->dir, on_thumbnail_loaded, list );
 
873
 
 
874
            for( l = list->files; l; l = l->next )
 
875
            {
 
876
                file = (VFSFileInfo*)l->data;
 
877
                if( vfs_file_info_is_image( file )
 
878
                    && vfs_file_info_is_thumbnail_loaded( file, is_big ) )
 
879
                {
 
880
                    /* update the model */
 
881
                    ptk_file_list_file_changed( list->dir, file, list );
 
882
                }
 
883
            }
 
884
        }
804
885
        return;
 
886
    }
 
887
 
 
888
    g_signal_connect( list->dir, "thumbnail-loaded",
 
889
                                    G_CALLBACK(on_thumbnail_loaded), list );
805
890
 
806
891
    for( l = list->files; l; l = l->next )
807
892
    {
809
894
        if( vfs_file_info_is_image( file )
810
895
            && vfs_file_info_get_size( file ) < list->max_thumbnail )
811
896
        {
812
 
            if( vfs_file_info_is_thumbnail_loaded( file, big ) )
 
897
            if( vfs_file_info_is_thumbnail_loaded( file, is_big ) )
813
898
                ptk_file_list_file_changed( list->dir, file, list );
814
899
            else
815
 
                vfs_dir_request_thumbnail( list->dir, file, big );
816
 
        }
817
 
    }
818
 
}
819
 
 
820
 
#if 0
821
 
/* I still have doubt if this works */
822
 
 
823
 
void ptk_file_list_show_hidden_files( PtkFileList* list )
824
 
{
825
 
    GList *l, *l2, *new_item;
826
 
    VFSFileInfo* info;
827
 
    int i = 0;
828
 
    GtkTreePath* path;
829
 
    GtkTreeIter it;
830
 
 
831
 
    if( list->show_hidden )
832
 
        return;
833
 
    for( l = list->dir->file_list; l; l = l->next )
834
 
    {
835
 
        info = (VFSFileInfo*)l->data;
836
 
        if( vfs_file_info_get_disp_name(info)[0] != '.' )
837
 
            continue;
838
 
        for( i = 0, l2 = list->files; l2; l2 = l2->next, ++i )
839
 
        {
840
 
            if( ptk_file_list_compare(info, l2->data, list) >= 0 )
841
900
            {
842
 
                list->files = g_list_insert_before( list->files, info, l2 );
843
 
                it.user_data = l2->prev;
844
 
                it.user_data2 = info;
845
 
                it.stamp = list->stamp;
846
 
                path = gtk_tree_path_new_from_indices(i, -1);
847
 
                gtk_tree_model_row_inserted( list, path, &it );
848
 
                gtk_tree_path_free( path );
849
 
                break;
 
901
                vfs_thumbnail_loader_request( list->dir, file, is_big );
 
902
                /* g_debug( "REQUEST: %s", file->name ); */
850
903
            }
851
904
        }
852
905
    }
853
906
}
854
 
 
855
 
void ptk_file_list_hide_hidden_files( PtkFileList* list )
856
 
{
857
 
    GList* l;
858
 
    VFSFileInfo* info;
859
 
    GtkTreePath* path;
860
 
 
861
 
    if( ! list->show_hidden )
862
 
        return;
863
 
    path = gtk_tree_path_new_first();
864
 
    for( l = list->files; l; )
865
 
    {
866
 
        info = (VFSFileInfo*)l->data;
867
 
        /* hidden file */
868
 
        if( G_UNLIKELY(vfs_file_info_get_disp_name(info)[0] == '.') )
869
 
        {
870
 
            l = l->next;
871
 
            list->files = g_list_delete_link( list->files, l->prev );
872
 
            gtk_tree_model_row_deleted( GTK_TREE_MODEL(list), path );
873
 
        }
874
 
        else
875
 
        {
876
 
            l = l->next;
877
 
            gtk_tree_path_next( path );
878
 
        }
879
 
    }
880
 
    gtk_tree_path_free( path );
881
 
}
882
 
 
883
 
#endif