Exemple #1
0
void update_created_files( gpointer key, gpointer data, gpointer user_data )
{
    VFSDir* dir = (VFSDir*)data;
    GSList* l;
    char* full_path;
    VFSFileInfo* file;
    GList* ll;

    if ( dir->created_files )
    {
        g_mutex_lock( dir->mutex );
        for ( l = dir->created_files; l; l = l->next )
        {
            if ( !( ll = vfs_dir_find_file( dir, (char*)l->data, NULL ) ) )
            {
                // file is not in dir file_list
                full_path = g_build_filename( dir->path, (char*)l->data, NULL );
                file = vfs_file_info_new();
                if ( vfs_file_info_get( file, full_path, NULL ) )
                {
                    // add new file to dir file_list
                    vfs_file_info_load_special_info( file, full_path );
                    dir->file_list = g_list_prepend( dir->file_list,
                                                    vfs_file_info_ref( file ) );
                    ++dir->n_files;
                    g_signal_emit( dir, signals[ FILE_CREATED_SIGNAL ], 0, file );
                }
                // else file doesn't exist in filesystem
                vfs_file_info_unref( file );
                g_free( full_path );
            }
            else
            {
                // file already exists in dir file_list
                file = vfs_file_info_ref( (VFSFileInfo*)ll->data );
                if ( update_file_info( dir, file ) )
                {
                    g_signal_emit( dir, signals[ FILE_CHANGED_SIGNAL ], 0, file );
                    vfs_file_info_unref( file );
                }
                // else was deleted, signaled, and unrefed in update_file_info
            }
            g_free( (char*)l->data );  // free file_name string
        }
        g_slist_free( dir->created_files );
        dir->created_files = NULL;
        g_mutex_unlock( dir->mutex );
    }
}
Exemple #2
0
void ptk_file_list_set_dir( PtkFileList* list, VFSDir* dir )
{
    GList* l;

    if( list->dir == dir )
        return;

    if ( list->dir )
    {
        if( list->max_thumbnail > 0 )
        {
            /* cancel all possible pending requests */
            vfs_thumbnail_loader_cancel_all_requests( list->dir, list->big_thumbnail );
        }
        g_list_foreach( list->files, (GFunc)vfs_file_info_unref, NULL );
        g_list_free( list->files );
        g_signal_handlers_disconnect_by_func( list->dir,
                                              _ptk_file_list_file_created, list );
        g_signal_handlers_disconnect_by_func( list->dir,
                                              ptk_file_list_file_deleted, list );
        g_signal_handlers_disconnect_by_func( list->dir,
                                              _ptk_file_list_file_changed, list );
        g_signal_handlers_disconnect_by_func( list->dir,
                                              on_thumbnail_loaded, list );
        g_object_unref( list->dir );
    }

    list->dir = dir;
    list->files = NULL;
    list->n_files = 0;
    if( ! dir )
        return;

    g_object_ref( list->dir );

    g_signal_connect( list->dir, "file-created",
                      G_CALLBACK(_ptk_file_list_file_created),
                      list );
    g_signal_connect( list->dir, "file-deleted",
                      G_CALLBACK(ptk_file_list_file_deleted),
                      list );
    g_signal_connect( list->dir, "file-changed",
                      G_CALLBACK(_ptk_file_list_file_changed),
                      list );

    if( dir && dir->file_list )
    {
        for( l = dir->file_list; l; l = l->next )
        {
            if( list->show_hidden ||
                    ((VFSFileInfo*)l->data)->disp_name[0] != '.' )
            {
                list->files = g_list_prepend( list->files, vfs_file_info_ref( (VFSFileInfo*)l->data) );
                ++list->n_files;
            }
        }
    }
}
Exemple #3
0
void vfs_dir_emit_file_changed( VFSDir* dir, const char* file_name,
                                        VFSFileInfo* file, gboolean force )
{
    GList* l;
//printf("vfs_dir_emit_file_changed dir=%s file_name=%s avoid=%s\n", dir->path, file_name, dir->avoid_changes ? "TRUE" : "FALSE" );

    if ( !force && dir->avoid_changes )
        return;

    if ( G_UNLIKELY( 0 == strcmp(file_name, dir->path) ) )
    {
        // Special Case: The directory itself was changed
        g_signal_emit( dir, signals[ FILE_CHANGED_SIGNAL ], 0, NULL );
        return;
    }

    g_mutex_lock( dir->mutex );

    l = vfs_dir_find_file( dir, file_name, file );
    if ( G_LIKELY( l ) )
    {
        file = vfs_file_info_ref( ( VFSFileInfo* ) l->data );
        if( !g_slist_find( dir->changed_files, file ) )
        {
            if ( force )
            {
                dir->changed_files = g_slist_prepend( dir->changed_files, file );
                if ( 0 == change_notify_timeout )
                {
                    change_notify_timeout = g_timeout_add_full( G_PRIORITY_LOW,
                                                                100,
                                                                notify_file_change,
                                                                NULL, NULL );
                }
            }
            else if( G_LIKELY( update_file_info( dir, file ) ) ) // update file info the first time
            {
                dir->changed_files = g_slist_prepend( dir->changed_files, file );
                if ( 0 == change_notify_timeout )
                {
                    change_notify_timeout = g_timeout_add_full( G_PRIORITY_LOW,
                                                                500,
                                                                notify_file_change,
                                                                NULL, NULL );
                }
                g_signal_emit( dir, signals[ FILE_CHANGED_SIGNAL ], 0, file );
            }
        }
        else
            vfs_file_info_unref( file );
    }

    g_mutex_unlock( dir->mutex );
}
Exemple #4
0
void vfs_thumbnail_loader_request( VFSDir* dir, VFSFileInfo* file, gboolean is_big )
{
    VFSThumbnailLoader* loader;
    ThumbnailRequest* req;
    gboolean new_task = FALSE;
    GList* l;

    /* g_debug( "request thumbnail: %s, is_big: %d", file->name, is_big ); */
    if( G_UNLIKELY( ! dir->thumbnail_loader ) )
    {
        dir->thumbnail_loader = vfs_thumbnail_loader_new( dir );
        new_task = TRUE;
    }

    loader = dir->thumbnail_loader;

    if( G_UNLIKELY( ! loader->task ) )
    {
        loader->task = vfs_async_task_new( (VFSAsyncFunc)thumbnail_loader_thread, loader );
        new_task = TRUE;
    }
    vfs_async_task_lock( loader->task );

    /* Check if the request is already scheduled */
    for( l = loader->queue->head; l; l = l->next )
    {
        req = (ThumbnailRequest*)l->data;
        /* If file with the same name is already in our queue */
        if( req->file == file || 0 == strcmp( req->file->name, file->name ) )
            break;
    }
    if( l )
    {
        req = (ThumbnailRequest*)l->data;
    }
    else
    {
        req = g_slice_new0( ThumbnailRequest );
        req->file = vfs_file_info_ref(file);
        g_queue_push_tail( dir->thumbnail_loader->queue, req );
    }

    ++req->n_requests[ is_big ? LOAD_BIG_THUMBNAIL : LOAD_SMALL_THUMBNAIL ];

    vfs_async_task_unlock( loader->task );

    if( new_task )
        vfs_async_task_execute( loader->task );
}
Exemple #5
0
gboolean on_dir_tree_view_button_press( GtkWidget* view,
                                        GdkEventButton* evt,
                                        PtkFileBrowser* browser )
{
    if ( evt->type == GDK_BUTTON_PRESS && evt->button == 3 )
    {
        GtkTreeModel * model;
        GtkTreePath* tree_path;
        GtkTreeIter it;

        model = gtk_tree_view_get_model( GTK_TREE_VIEW( view ) );
        if ( gtk_tree_view_get_path_at_pos( GTK_TREE_VIEW( view ),
                                            evt->x, evt->y, &tree_path, NULL, NULL, NULL ) )
        {
            if ( gtk_tree_model_get_iter( model, &it, tree_path ) )
            {
                VFSFileInfo * file;
                gtk_tree_model_get( model, &it,
                                    COL_DIR_TREE_INFO,
                                    &file, -1 );
                if ( file )
                {
                    GtkWidget * popup;
                    char* file_path;
                    GList* sel_files;
                    char* dir_name;
                    file_path = ptk_dir_view_get_dir_path( model, &it );

                    sel_files = g_list_prepend( NULL, vfs_file_info_ref(file) );
                    dir_name = g_path_get_dirname( file_path );
                    popup = ptk_file_menu_new(
                                file_path, file,
                                dir_name, sel_files, browser );
                    g_free( dir_name );
                    g_free( file_path );
                    gtk_menu_popup( GTK_MENU( popup ), NULL, NULL,
                                    NULL, NULL, 3, evt->time );

                    vfs_file_info_unref( file );
                }
            }
            gtk_tree_path_free( tree_path );
        }
    }
    return FALSE;
}
Exemple #6
0
void ptk_file_list_file_created( VFSDir* dir,
                                 VFSFileInfo* file,
                                 PtkFileList* list )
{
    GList* l;
    GtkTreeIter it;
    GtkTreePath* path;
    VFSFileInfo* file2;

    if( ! list->show_hidden && vfs_file_info_get_name(file)[0] == '.' )
        return;

    for( l = list->files; l; l = l->next )
    {
        file2 = (VFSFileInfo*)l->data;
        if( G_UNLIKELY( file == file2 || ptk_file_list_compare( file2, file, list ) == 0 ) )
        {
            /* The file is already in the list */
            return;
        }
        if( ptk_file_list_compare( file2, file, list ) > 0 )
        {
            break;
        }
    }

    list->files = g_list_insert_before( list->files, l, vfs_file_info_ref( file ) );
    ++list->n_files;

    if( l )
        l = l->prev;
    else
        l = g_list_last( list->files );

    it.stamp = list->stamp;
    it.user_data = l;
    it.user_data2 = file;

    path = gtk_tree_path_new_from_indices( g_list_index(list->files, l->data), -1 );

    gtk_tree_model_row_inserted( GTK_TREE_MODEL(list), path, &it );

    gtk_tree_path_free( path );
}
Exemple #7
0
void vfs_dir_emit_thumbnail_loaded( VFSDir* dir, VFSFileInfo* file )
{
    GList* l;
    g_mutex_lock( dir->mutex );
    l = vfs_dir_find_file( dir, file->name, file );
    if( l )
    {
        g_assert( file == (VFSFileInfo*)l->data );
        file = vfs_file_info_ref( (VFSFileInfo*)l->data );
    }
    else
        file = NULL;
    g_mutex_unlock( dir->mutex );

    if ( G_LIKELY( file ) )
    {
        g_signal_emit( dir, signals[ THUMBNAIL_LOADED_SIGNAL ], 0, file );
        vfs_file_info_unref( file );
    }
}
Exemple #8
0
void vfs_dir_emit_file_deleted( VFSDir* dir, const char* file_name, VFSFileInfo* file )
{
    GList* l;
    VFSFileInfo* file_found;

    if( G_UNLIKELY( 0 == strcmp(file_name, dir->path) ) )
    {
        /* Special Case: The directory itself was deleted... */
        file = NULL;
        /* clear the whole list */
        g_mutex_lock( dir->mutex );
        g_list_foreach( dir->file_list, (GFunc)vfs_file_info_unref, NULL );
        g_list_free( dir->file_list );
        dir->file_list = NULL;
        g_mutex_unlock( dir->mutex );

        g_signal_emit( dir, signals[ FILE_DELETED_SIGNAL ], 0, file );
        return;
    }

    l = vfs_dir_find_file( dir, file_name, file );
    if ( G_LIKELY( l ) )
    {
        file_found = vfs_file_info_ref( ( VFSFileInfo* ) l->data );
        if( !g_slist_find( dir->changed_files, file_found ) )
        {
            dir->changed_files = g_slist_prepend( dir->changed_files, file_found );
            if ( 0 == change_notify_timeout )
            {
                change_notify_timeout = g_timeout_add_full( G_PRIORITY_LOW,
                                                            200,
                                                            notify_file_change,
                                                            NULL, NULL );
            }
        }
        else
            vfs_file_info_unref( file_found );
    }
}
Exemple #9
0
void update_changed_files( gpointer key, gpointer data, gpointer user_data )
{
    VFSDir* dir = (VFSDir*)data;
    GSList* l;
    VFSFileInfo* file;

    if ( dir->changed_files )
    {
        g_mutex_lock( dir->mutex );
        for ( l = dir->changed_files; l; l = l->next )
        {
            file = vfs_file_info_ref( ( VFSFileInfo* ) l->data );  ///
            if ( update_file_info( dir, file ) )
            {
                g_signal_emit( dir, signals[ FILE_CHANGED_SIGNAL ], 0, file );
                vfs_file_info_unref( file );
            }
            // else was deleted, signaled, and unrefed in update_file_info
        }
        g_slist_free( dir->changed_files );
        dir->changed_files = NULL;
        g_mutex_unlock( dir->mutex );
    }
}
Exemple #10
0
gpointer thumbnail_loader_thread( VFSAsyncTask* task, VFSThumbnailLoader* loader )
{
    ThumbnailRequest* req;
    int i;
    gboolean load_big, need_update;

    while( G_LIKELY( ! vfs_async_task_is_cancelled(task) ))
    {
        vfs_async_task_lock( task );
        req = (ThumbnailRequest*)g_queue_pop_head( loader->queue );
        vfs_async_task_unlock( task );
        if( G_UNLIKELY( ! req ) )
            break;
        /* g_debug("pop: %s", req->file->name); */

        /* Only we have the reference. That means, no body is using the file */
        if( req->file->n_ref == 1 )
        {
            thumbnail_request_free( req );
            continue;
        }

        need_update = FALSE;
        for ( i = 0; i < 2; ++i )
        {
            if ( 0 == req->n_requests[ i ] )
                continue;
            load_big = ( i == LOAD_BIG_THUMBNAIL );
            if ( ! vfs_file_info_is_thumbnail_loaded( req->file, load_big ) )
            {
                char* full_path;
                full_path = g_build_filename( loader->dir->path,
                                              vfs_file_info_get_name( req->file ),
                                              NULL );
                vfs_file_info_load_thumbnail( req->file, full_path, load_big );
                g_free( full_path );
                /*  Slow down for displaying. */
                g_usleep(G_USEC_PER_SEC/1000);

                /* g_debug( "thumbnail loaded: %s", req->file ); */
            }
            need_update = TRUE;
        }

        if( ! vfs_async_task_is_cancelled(task) && need_update )
        {
            vfs_async_task_lock( task );
            g_queue_push_tail( loader->update_queue, vfs_file_info_ref(req->file) );
            if( 0 == loader->idle_handler)
                loader->idle_handler = g_idle_add_full( G_PRIORITY_LOW, (GSourceFunc) on_thumbnail_idle, loader, NULL );
            vfs_async_task_unlock( task );
        }
        /* g_debug( "NEED_UPDATE: %d", need_update ); */
        thumbnail_request_free( req );
    }

    if( vfs_async_task_is_cancelled(task) )
    {
        /* g_debug( "THREAD CANCELLED!!!" ); */
        vfs_async_task_lock( task );
        if( loader->idle_handler)
        {
            g_source_remove( loader->idle_handler );
            loader->idle_handler = 0;
        }
        vfs_async_task_unlock( task );
    }
    else
    {
        if( 0 == loader->idle_handler)
        {
            /* g_debug( "ADD IDLE HANDLER BEFORE THREAD ENDING" ); */
            loader->idle_handler = g_idle_add_full( G_PRIORITY_LOW, (GSourceFunc) on_thumbnail_idle, loader, NULL );
        }
    }
    /* g_debug("THREAD ENDED!");  */
    return NULL;
}
Exemple #11
0
static void on_open_files( GtkAction* action, FindFile* data )
{
    GtkTreeModel* model;
    GtkTreeSelection* sel;
    GtkTreeIter it;
    GList *row, *rows, *sel_files;
    GHashTable* hash;
    GtkWidget* w;
    VFSFileInfo* fi;
    gboolean open_files_has_dir = FALSE;  //sfm
    PtkFileBrowser* file_browser = NULL;  //sfm
    gboolean open_files = TRUE;
    
    if ( action )
        open_files = (0 == strcmp( gtk_action_get_name(action), "OpenAction") );

    sel = gtk_tree_view_get_selection( GTK_TREE_VIEW( data->result_view ) );
    rows = gtk_tree_selection_get_selected_rows( sel, &model );
    if( ! rows )
        return;

    //sfm this frees list when new value inserted - caused segfault
    //hash = g_hash_table_new_full( g_str_hash, g_str_equal, (GDestroyNotify)g_free, open_files ? (GDestroyNotify)vfs_file_info_list_free : NULL );
    hash = g_hash_table_new_full( g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL );

    for( row = rows; row; row = row->next )
    {
        char* dir;
        GtkTreePath* tp = (GtkTreePath*)row->data;

        if( gtk_tree_model_get_iter( model, &it, tp ) )
        {
            if( open_files ) /* open files */
                gtk_tree_model_get( model, &it, COL_INFO, &fi, COL_DIR, &dir, -1 );
            else  /* open containing folders */
                gtk_tree_model_get( model, &it, COL_DIR, &dir, -1 );

            if( open_files )
            {
                GList *l;
                l = g_hash_table_lookup( hash, dir );
                l = g_list_prepend( l, vfs_file_info_ref(fi) );
                g_hash_table_insert( hash, dir, l );  //sfm caused segfault with destroy function
                if ( vfs_file_info_is_dir( fi ) )  //sfm
                    open_files_has_dir = TRUE;
            }
            else
            {
                if( g_hash_table_lookup( hash, dir ) )
                    g_free( dir );
                g_hash_table_insert( hash, dir, NULL );
            }
        }
        gtk_tree_path_free( tp );
    }
    g_list_free( rows );

    if( open_files )
    {
        if ( open_files_has_dir )
        {
            w = GTK_WIDGET( fm_main_window_get_last_active() );
            if( ! w )
            {
                w = fm_main_window_new();
                gtk_window_set_default_size( GTK_WINDOW( w ), app_settings.width, app_settings.height );
            }
            gtk_window_present( (GtkWindow*)w );
            file_browser = (PtkFileBrowser*)fm_main_window_get_current_file_browser(
                                                                (FMMainWindow*)w );
        }
        g_hash_table_foreach_steal( hash, (GHRFunc)open_file, file_browser );
    }
    else
    {
        w = GTK_WIDGET( fm_main_window_get_last_active() );
        if( ! w )
        {
            w = fm_main_window_new();
            gtk_window_set_default_size( GTK_WINDOW( w ), app_settings.width, app_settings.height );
        }

        g_hash_table_foreach( hash, (GHFunc)open_dir, w );
        gtk_window_present( (GtkWindow*)w );
    }

    g_hash_table_destroy( hash );
}
Exemple #12
0
void ptk_file_list_file_created( VFSDir* dir,
                                 VFSFileInfo* file,
                                 PtkFileList* list )
{
    GList* l, *ll = NULL;
    GtkTreeIter it;
    GtkTreePath* path;
    VFSFileInfo* file2;
    
    if( ! list->show_hidden && vfs_file_info_get_name(file)[0] == '.' )
        return;

    gboolean is_desktop = vfs_file_info_is_desktop_entry( file ); //sfm
    gboolean is_desktop2;
    
    for( l = list->files; l; l = l->next )
    {
        file2 = (VFSFileInfo*)l->data;
        if( G_UNLIKELY( file == file2 ) )
        {
            /* The file is already in the list */
            return;
        }
        
        is_desktop2 = vfs_file_info_is_desktop_entry( file2 );
        if ( is_desktop || is_desktop2 )
        {
            // at least one is a desktop file, need to compare filenames
            if ( file->name && file2->name )
            {
                if ( !strcmp( file->name, file2->name ) )
                    return;
            }
        }
        else if ( ptk_file_list_compare( file2, file, list ) == 0 )
        {
            // disp_name matches ?
            // ptk_file_list_compare may return 0 on differing display names
            // if case-insensitive - need to compare filenames
            if ( list->sort_natural && list->sort_case )
                return;
            else if ( !strcmp( file->name, file2->name ) )
                return;
        }

        if ( !ll && ptk_file_list_compare( file2, file, list ) > 0 )
        {
            if ( !is_desktop && !is_desktop2 )
                break;
            else
                ll = l; // store insertion location based on disp_name
        }
    }

    if ( ll )
        l = ll;

    list->files = g_list_insert_before( list->files, l, vfs_file_info_ref( file ) );
    ++list->n_files;

    if( l )
        l = l->prev;
    else
        l = g_list_last( list->files );

    it.stamp = list->stamp;
    it.user_data = l;
    it.user_data2 = file;

    path = gtk_tree_path_new_from_indices( g_list_index(list->files, l->data), -1 );

    gtk_tree_model_row_inserted( GTK_TREE_MODEL(list), path, &it );

    gtk_tree_path_free( path );
}
Exemple #13
0
void ptk_file_list_get_value ( GtkTreeModel *tree_model,
                               GtkTreeIter *iter,
                               gint column,
                               GValue *value )
{
    GList* l;
    PtkFileList* list = PTK_FILE_LIST(tree_model);
    VFSFileInfo* info;
    GdkPixbuf* icon;

    g_return_if_fail (PTK_IS_FILE_LIST (tree_model));
    g_return_if_fail (iter != NULL);
    g_return_if_fail (column < G_N_ELEMENTS(column_types) );

    g_value_init (value, column_types[column] );

    l = (GList*) iter->user_data;
    g_return_if_fail ( l != NULL );

    info = (VFSFileInfo*)iter->user_data2;

    switch(column)
    {
    case COL_FILE_BIG_ICON:
        icon = NULL;
        /* special file can use special icons saved as thumbnails*/
        if( list->max_thumbnail > vfs_file_info_get_size( info )
            && info->flags == VFS_FILE_INFO_NONE )
            icon = vfs_file_info_get_big_thumbnail( info );

        if( ! icon )
            icon = vfs_file_info_get_big_icon( info );
        if( icon )
        {
            g_value_set_object( value, icon );
            g_object_unref( icon );
        }
        break;
    case COL_FILE_SMALL_ICON:
        icon = NULL;
        /* special file can use special icons saved as thumbnails*/
        if( list->max_thumbnail > vfs_file_info_get_size( info ) )
            icon = vfs_file_info_get_small_thumbnail( info );
        if( !icon )
            icon = vfs_file_info_get_small_icon( info );
        if( icon )
        {
            g_value_set_object( value, icon );
            g_object_unref( icon );
        }
        break;
    case COL_FILE_NAME:
        g_value_set_string( value, vfs_file_info_get_disp_name(info) );
        break;
    case COL_FILE_SIZE:
        if ( S_ISDIR( info->mode ) || ( S_ISLNK( info->mode ) &&
                                0 == strcmp( vfs_mime_type_get_type( info->mime_type ),
                                XDG_MIME_TYPE_DIRECTORY ) ) )
            g_value_set_string( value, NULL );
        else
            g_value_set_string( value, vfs_file_info_get_disp_size(info) );
        break;
    case COL_FILE_DESC:
        g_value_set_string( value, vfs_file_info_get_mime_type_desc( info ) );
        break;
    case COL_FILE_PERM:
        g_value_set_string( value, vfs_file_info_get_disp_perm(info) );
        break;
    case COL_FILE_OWNER:
        g_value_set_string( value, vfs_file_info_get_disp_owner(info) );
        break;
    case COL_FILE_MTIME:
        g_value_set_string( value, vfs_file_info_get_disp_mtime(info) );
        break;
    case COL_FILE_INFO:
        g_value_set_pointer( value, vfs_file_info_ref( info ) );
        break;
    }
}
Exemple #14
0
gboolean on_dir_tree_view_key_press( GtkWidget* view,
                                     GdkEventKey* evt,
                                     PtkFileBrowser* browser )
{
    VFSFileInfo* file;
    GtkTreeModel *model;
    GtkTreeIter iter;
    GtkTreeSelection *select = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
    
    if(!gtk_tree_selection_get_selected(select, &model, &iter))
        return FALSE;

    int keymod = ( evt->state & ( GDK_SHIFT_MASK | GDK_CONTROL_MASK |
            GDK_MOD1_MASK | GDK_SUPER_MASK | GDK_HYPER_MASK | GDK_META_MASK ) );

    GtkTreePath *path = gtk_tree_model_get_path(model, &iter);

    switch( evt->keyval ) {
    case GDK_KEY_Left:
        if(gtk_tree_view_row_expanded(GTK_TREE_VIEW(view), path)) {
            gtk_tree_view_collapse_row(GTK_TREE_VIEW(view), path);
        } else if(gtk_tree_path_up(path)) {
            gtk_tree_selection_select_path(select, path);
            gtk_tree_view_set_cursor(GTK_TREE_VIEW(view), path, NULL, FALSE);
        } else {
            gtk_tree_path_free( path );
            return FALSE;
        }
        break;
    case GDK_KEY_Right:
        if(!gtk_tree_view_row_expanded(GTK_TREE_VIEW(view), path)) {
            gtk_tree_view_expand_row(GTK_TREE_VIEW(view), path, FALSE);
        } else {
            gtk_tree_path_down(path);
            gtk_tree_selection_select_path(select, path);
            gtk_tree_view_set_cursor(GTK_TREE_VIEW(view), path, NULL, FALSE);
        }
        break;
    case GDK_KEY_F10:
    case GDK_KEY_Menu:
        if ( evt->keyval == GDK_KEY_F10 && keymod != GDK_SHIFT_MASK )
        {
            gtk_tree_path_free( path );
            return FALSE;
        }
        gtk_tree_model_get( gtk_tree_view_get_model( GTK_TREE_VIEW( view ) ),
                            &iter,
                            COL_DIR_TREE_INFO,
                            &file, -1 );
        if ( file )
        {
            GtkWidget * popup;
            char* file_path;
            GList* sel_files;
            char* dir_name;
            file_path = ptk_dir_view_get_dir_path(
                    gtk_tree_view_get_model( GTK_TREE_VIEW( view ) ), &iter );

            sel_files = g_list_prepend( NULL, vfs_file_info_ref(file) );
            dir_name = g_path_get_dirname( file_path );
            popup = ptk_file_menu_new( NULL, browser,
                        file_path, file,
                        dir_name, sel_files );
            g_free( dir_name );
            g_free( file_path );
            if ( popup )
                gtk_menu_popup( GTK_MENU( popup ), NULL, NULL,
                            NULL, NULL, 3, evt->time );

            vfs_file_info_unref( file );
        }
        break;
    default:
        gtk_tree_path_free( path );
        return FALSE;
    }
    gtk_tree_path_free( path );
    return TRUE;
}
Exemple #15
0
gboolean on_dir_tree_view_button_press( GtkWidget* view,
                                        GdkEventButton* evt,
                                        PtkFileBrowser* browser )
{
    GtkTreeModel* model;
    GtkTreePath* tree_path;
    GtkTreeViewColumn* tree_col;
    GtkTreeIter it;

    if ( evt->type == GDK_BUTTON_PRESS &&
                                    ( evt->button == 1 || evt->button == 3 ) )
    {
        // middle click 2 handled in ptk-file-browser.c on_dir_tree_button_press
        model = gtk_tree_view_get_model( GTK_TREE_VIEW( view ) );
        if ( gtk_tree_view_get_path_at_pos( GTK_TREE_VIEW( view ),
                                            evt->x, evt->y, &tree_path,
                                            &tree_col, NULL, NULL ) )
        {
            if ( gtk_tree_model_get_iter( model, &it, tree_path ) )
            {
                gtk_tree_view_set_cursor( GTK_TREE_VIEW( view ),
                                                            tree_path,
                                                            tree_col, FALSE );
                gtk_tree_view_row_activated( GTK_TREE_VIEW( view ),
                                                            tree_path,
                                                            tree_col );
                if ( evt->button == 3 )
                {
                    // right click
                    VFSFileInfo * file;
                    gtk_tree_model_get( model, &it,
                                        COL_DIR_TREE_INFO,
                                        &file, -1 );
                    if ( file )
                    {
                        GtkWidget * popup;
                        char* file_path;
                        GList* sel_files;
                        char* dir_name;
                        file_path = ptk_dir_view_get_dir_path( model, &it );

                        sel_files = g_list_prepend( NULL, vfs_file_info_ref(file) );
                        dir_name = g_path_get_dirname( file_path );
                        /* FIXME: New|Tab Here and New|File etc work on the
                         * wrong location because dir_name is really incorrect.
                         * But if set to cur dir it breaks Copy, etc. */
                        popup = ptk_file_menu_new( NULL, browser,
                                    file_path, file,
                                    dir_name, sel_files );
                        g_free( dir_name );
                        g_free( file_path );
                        if ( popup )
                            gtk_menu_popup( GTK_MENU( popup ), NULL, NULL,
                                        NULL, NULL, 3, evt->time );

                        vfs_file_info_unref( file );
                        gtk_tree_path_free( tree_path );
                        return TRUE;
                    }
                }
            }
            gtk_tree_path_free( tree_path );
        }
    }
    else if ( evt->type == GDK_2BUTTON_PRESS && evt->button == 1 )
    {
        // double click - expand/collapse
        if ( gtk_tree_view_get_path_at_pos( GTK_TREE_VIEW( view ),
                                            evt->x, evt->y, &tree_path,
                                            NULL, NULL, NULL ) )
        {
            if ( gtk_tree_view_row_expanded( GTK_TREE_VIEW( view ),
                                                                tree_path ) )
                gtk_tree_view_collapse_row( GTK_TREE_VIEW( view ), tree_path );
            else
                gtk_tree_view_expand_row( GTK_TREE_VIEW( view ), tree_path,
                                                                FALSE );
            gtk_tree_path_free( tree_path );
            return TRUE;
        }
    }
    return FALSE;
}