Commit 7c0e6dc2 authored by Havoc Pennington's avatar Havoc Pennington

hmm, finally add these files :-)

parent f9feecb6
/* -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*-
* GNOME File Manager (Directory list object)
*
* Copyright (C) 1999 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* Developed by: Havoc Pennington
*/
#include "fm-directory-list.h"
#include "fm-icon-cache.h"
/*
* Prototypes for private FMDirectoryListEntry functions
*/
static FMDirectoryListEntry* fm_directory_list_entry_new (GnomeVFSFileInfo *info, GdkPixbuf *icon);
/*
* FMDirectoryList object
*/
static void stop_load (FMDirectoryList *dlist);
/* GtkObject implementation details */
static void fm_directory_list_class_init (FMDirectoryListClass *class);
static void fm_directory_list_init (FMDirectoryList *dlist);
static void fm_directory_list_destroy (GtkObject *object);
static void fm_directory_list_finalize (GtkObject *object);
enum {
ENTRIES_LOADED,
FINISHED_LOAD,
ENTRY_ICON_CHANGED,
ENTRY_NAME_CHANGED,
LAST_SIGNAL
};
static GtkObjectClass *parent_class;
static guint dlist_signals[LAST_SIGNAL];
GtkType
fm_directory_list_get_type (void)
{
static GtkType fm_directory_list_type = 0;
if (!fm_directory_list_type) {
GtkTypeInfo fm_directory_list_info = {
"FMDirectoryList",
sizeof (FMDirectoryList),
sizeof (FMDirectoryListClass),
(GtkClassInitFunc) fm_directory_list_class_init,
(GtkObjectInitFunc) fm_directory_list_init,
NULL, /* reserved_1 */
NULL, /* reserved_2 */
(GtkClassInitFunc) NULL
};
fm_directory_list_type = gtk_type_unique (gtk_object_get_type (), &fm_directory_list_info);
}
return fm_directory_list_type;
}
static void
fm_directory_list_class_init (FMDirectoryListClass *class)
{
GtkObjectClass *object_class;
object_class = (GtkObjectClass *) class;
parent_class = gtk_type_class (gnome_canvas_get_type ());
dlist_signals[ENTRIES_LOADED] =
gtk_signal_new ("entries_loaded",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (FMDirectoryListClass,
entries_loaded),
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
dlist_signals[FINISHED_LOAD] =
gtk_signal_new ("finished_load",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (FMDirectoryListClass,
finished_load),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
dlist_signals[ENTRY_ICON_CHANGED] =
gtk_signal_new ("entry_icon_changed",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (FMDirectoryListClass,
entry_icon_changed),
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
dlist_signals[ENTRY_NAME_CHANGED] =
gtk_signal_new ("entry_name_changed",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (FMDirectoryListClass,
entry_name_changed),
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
gtk_object_class_add_signals (object_class,
dlist_signals, LAST_SIGNAL);
object_class->destroy = fm_directory_list_destroy;
object_class->finalize = fm_directory_list_finalize;
}
static void
fm_directory_list_init (FMDirectoryList *dlist)
{
dlist->directory_list = NULL;
dlist->vfs_async_handle = NULL;
dlist->uri = NULL;
}
static void
fm_directory_list_destroy (GtkObject *object)
{
FMDirectoryList *dlist;
g_return_if_fail(object != NULL);
g_return_if_fail(FM_IS_DIRECTORY_LIST(object));
dlist = FM_DIRECTORY_LIST(object);
if (dlist->directory_list != NULL)
stop_load(dlist);
if (dlist->uri) {
gnome_vfs_uri_unref(dlist->uri);
dlist->uri = NULL;
}
(* GTK_OBJECT_CLASS(parent_class)->destroy) (object);
}
static void
fm_directory_list_finalize (GtkObject *object)
{
FMDirectoryList *canvas;
g_return_if_fail(object != NULL);
g_return_if_fail(FM_IS_DIRECTORY_LIST(object));
(* GTK_OBJECT_CLASS(parent_class)->finalize) (object);
}
FMDirectoryList*
fm_directory_list_new (void)
{
FMDirectoryList *dlist;
dlist = gtk_type_new(fm_directory_list_get_type());
return dlist;
}
/*
* The meat of FMDirectoryList
*/
#define ENTRIES_PER_CB 1 /* FIXME 1 for debugging, but for performance
more would be better */
static void
stop_load (FMDirectoryList *dlist)
{
GSList *iter;
iter = dlist->entries;
while (iter != NULL) {
fm_directory_list_entry_unref(iter->data);
iter = g_slist_next(iter);
}
dlist->entries = NULL;
dlist->entries_tail = NULL;
if (dlist->vfs_async_handle != NULL) {
/* Destroys the async handle and the directory list */
gnome_vfs_async_cancel (dlist->vfs_async_handle);
dlist->vfs_async_handle = NULL;
}
dlist->directory_list = NULL;
gtk_signal_emit(GTK_OBJECT(dlist),
dlist_signals[FINISHED_LOAD]);
}
static void
directory_load_cb (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
GnomeVFSDirectoryList *list,
guint entries_read,
gpointer callback_data)
{
FMDirectoryList *dlist;
g_assert(entries_read <= ENTRIES_PER_CB);
dlist = FM_DIRECTORY_LIST (callback_data);
if (dlist->directory_list == NULL) {
if (result == GNOME_VFS_OK || result == GNOME_VFS_ERROR_EOF) {
dlist->directory_list = list;
} else if (entries_read == 0) {
g_warning("our error handling here is not implemented, FIXME: %s", gnome_vfs_result_to_string(result));
/*
gtk_signal_emit (GTK_OBJECT (dlist),
signals[OPEN_FAILED]);
*/
}
}
/* OK, the directory list is supposed to always be positioned
at the start of the NEW entries we haven't seen yet.
*/
{
GSList *new_entries = NULL;
guint i;
i = 0;
while (i < entries_read) {
GnomeVFSFileInfo *info;
FMDirectoryListEntry *entry;
GdkPixbuf *pixbuf;
info = gnome_vfs_directory_list_current (dlist->directory_list);
g_assert(info != NULL);
pixbuf = fm_icon_cache_get_icon(fm_get_current_icon_cache(),
info);
g_assert(pixbuf != NULL);
entry = fm_directory_list_entry_new(info, pixbuf);
new_entries = g_slist_prepend(new_entries, entry);
gdk_pixbuf_unref(pixbuf);
/* The info doesn't need an unref, the directory
list owns it */
gnome_vfs_directory_list_next (dlist->directory_list);
++i;
}
new_entries = g_slist_reverse(new_entries);
gtk_signal_emit(GTK_OBJECT(dlist),
dlist_signals[ENTRIES_LOADED],
new_entries);
if (dlist->entries == NULL) {
dlist->entries = new_entries;
dlist->entries_tail = g_slist_last(dlist->entries);
} else {
g_assert(dlist->entries_tail != NULL);
dlist->entries_tail->next = new_entries;
dlist->entries_tail = g_slist_last(new_entries);
}
}
if (result == GNOME_VFS_ERROR_EOF) {
stop_load (dlist);
} else if (result != GNOME_VFS_OK) {
stop_load (dlist);
/* FIXME error */
}
}
void
fm_directory_list_load_uri (FMDirectoryList *dlist,
const gchar *uri)
{
GnomeVFSResult result;
static GnomeVFSDirectorySortRule sort_rules[] = {
GNOME_VFS_DIRECTORY_SORT_DIRECTORYFIRST,
GNOME_VFS_DIRECTORY_SORT_BYNAME,
GNOME_VFS_DIRECTORY_SORT_NONE
}; /* FIXME */
if (dlist->uri) {
/* stop current */
stop_load(dlist);
gnome_vfs_uri_unref(dlist->uri);
}
/* start new */
dlist->uri = gnome_vfs_uri_new(uri);
g_assert(dlist->uri);
result = gnome_vfs_async_load_directory_uri
(&dlist->vfs_async_handle, /* handle */
dlist->uri, /* uri */
(GNOME_VFS_FILE_INFO_GETMIMETYPE /* options */
| GNOME_VFS_FILE_INFO_FASTMIMETYPE
| GNOME_VFS_FILE_INFO_FOLLOWLINKS),
NULL, /* meta_keys */
sort_rules, /* sort_rules */
FALSE, /* reverse_order */
GNOME_VFS_DIRECTORY_FILTER_NONE, /* filter_type */
(GNOME_VFS_DIRECTORY_FILTER_NOSELFDIR /* filter_options */
| GNOME_VFS_DIRECTORY_FILTER_NOPARENTDIR),
NULL, /* filter_pattern */
ENTRIES_PER_CB, /* items_per_notification */
directory_load_cb, /* callback */
dlist); /* callback_data */
g_return_if_fail(result == GNOME_VFS_OK);
}
/*
* Directory list entry
*/
struct _FMDirectoryListEntry {
guint refcount;
GnomeVFSFileInfo *info;
GdkPixbuf *icon;
};
FMDirectoryListEntry*
fm_directory_list_entry_new (GnomeVFSFileInfo *info, GdkPixbuf *icon)
{
FMDirectoryListEntry *entry;
g_return_val_if_fail(info != NULL, NULL);
g_return_val_if_fail(icon != NULL, NULL);
entry = g_new(FMDirectoryListEntry, 1);
entry->refcount = 1;
entry->info = info;
entry->icon = icon;
gnome_vfs_file_info_ref(entry->info);
gdk_pixbuf_ref(entry->icon);
return entry;
}
void
fm_directory_list_entry_ref (FMDirectoryListEntry *entry)
{
g_return_if_fail(entry != NULL);
entry->refcount += 1;
}
void
fm_directory_list_entry_unref (FMDirectoryListEntry *entry)
{
g_return_if_fail(entry != NULL);
g_return_if_fail(entry->refcount > 0);
entry->refcount -= 1;
if (entry->refcount == 0) {
if (entry->info)
gnome_vfs_file_info_unref(entry->info);
if (entry->icon)
gdk_pixbuf_unref(entry->icon);
g_free(entry);
}
}
GnomeVFSFileInfo*
fm_directory_list_entry_get_file_info (FMDirectoryListEntry *entry)
{
g_return_val_if_fail(entry != NULL, NULL);
g_return_val_if_fail(entry->info != NULL, NULL);
return entry->info;
}
GdkPixbuf*
fm_directory_list_entry_get_icon (FMDirectoryListEntry *entry)
{
g_return_val_if_fail(entry != NULL, NULL);
g_return_val_if_fail(entry->icon != NULL, NULL);
return entry->icon;
}
const gchar*
fm_directory_list_entry_get_name (FMDirectoryListEntry *entry)
{
g_return_val_if_fail(entry != NULL, NULL);
g_return_val_if_fail(entry->info != NULL, NULL);
return entry->info->name;
}
/* -*- Mode: C; c-set-style: linux; indent-tabs-mode: nil; c-basic-offset: 8 -*-
* GNOME File Manager (Directory list object)
*
* Copyright (C) 1999 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* Developed by: Havoc Pennington
*/
#ifndef __FM_DIRECTORY_LIST_H__
#define __FM_DIRECTORY_LIST_H__
#include <libgnome/gnome-defs.h>
#include <libgnomevfs/gnome-vfs.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gtk/gtk.h>
BEGIN_GNOME_DECLS
/* An entry in the directory list */
typedef struct _FMDirectoryListEntry FMDirectoryListEntry;
void fm_directory_list_entry_ref (FMDirectoryListEntry *entry);
void fm_directory_list_entry_unref (FMDirectoryListEntry *entry);
GnomeVFSFileInfo* fm_directory_list_entry_get_file_info (FMDirectoryListEntry *entry);
GdkPixbuf* fm_directory_list_entry_get_icon (FMDirectoryListEntry *entry);
const gchar* fm_directory_list_entry_get_name (FMDirectoryListEntry *entry);
/* FMDirectoryList represents the non-graphical part of a
directory listing; two different kinds of view
currently exist, the FMDirectoryView and the
DesktopCanvas
*/
typedef struct _FMDirectoryList FMDirectoryList;
typedef struct _FMDirectoryListClass FMDirectoryListClass;
#define FM_TYPE_DIRECTORY_LIST (fm_directory_list_get_type ())
#define FM_DIRECTORY_LIST(obj) (GTK_CHECK_CAST ((obj), FM_TYPE_DIRECTORY_LIST, FMDirectoryList))
#define FM_DIRECTORY_LIST_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), FM_TYPE_DIRECTORY_LIST, FMDirectoryListClass))
#define FM_IS_DIRECTORY_LIST(obj) (GTK_CHECK_TYPE ((obj), FM_TYPE_DIRECTORY_LIST))
#define FM_IS_DIRECTORY_LIST_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), FM_TYPE_DIRECTORY_LIST))
struct _FMDirectoryList {
GtkObject object;
GnomeVFSDirectoryList *directory_list;
GnomeVFSAsyncHandle *vfs_async_handle;
GnomeVFSURI *uri;
GSList *entries;
GSList *entries_tail;
};
struct _FMDirectoryListClass {
GtkObjectClass object_class;
/* Eventually we might want signals like file_deleted,
file_added, blah blah; for now there's just the
stuff for loading a directory. */
/* You must add a refcount to these FMDirectoryListEntry
objects if you want to keep hold of them outside of the
signal handler. */
/* Each entry loaded after calling
fm_directory_list_load_uri() will be passed out via this
signal exactly ONE time; there is no guarantee about how
many each time, you may get all the entries in one signal
or one entry at a time. */
void (* entries_loaded) (FMDirectoryList *list,
GSList *entries);
/* Emitted when all entries have been loaded; icon/name
changed signals can come after this, but no more
entries_loaded signals */
void (* finished_load) (FMDirectoryList *list);
/* These are called if the icon or name for a directory
changes. In particular, icon_changed will be used if we
are doing slow MIME magic in an idle handler, and need to
update the icons to the more accurate ones. */
void (* entry_icon_changed) (FMDirectoryList *list,
FMDirectoryListEntry *entry);
void (* entry_name_changed) (FMDirectoryList *list,
FMDirectoryListEntry *entry);
};
GtkType fm_directory_list_get_type (void);
FMDirectoryList *fm_directory_list_new (void);
void fm_directory_list_load_uri (FMDirectoryList *dlist,
const gchar *uri);
END_GNOME_DECLS
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment