Merge gio-branch

svn path=/trunk/; revision=13464
This commit is contained in:
Alexander Larsson 2007-11-30 14:51:10 +00:00
parent ce669bd18c
commit 469047a2a5
173 changed files with 19752 additions and 16003 deletions

2118
ChangeLog

File diff suppressed because it is too large Load diff

2
NEWS
View file

@ -419,7 +419,7 @@ Major changes in 2.9.90 are:
* Better icons for burn: & computer: in the ui
* Allow eject of unmounted devices
* Better handling of DnD from mozilla
* Make connect to server dialog availible as separate app
* Make connect to server dialog available as separate app
* Use GtkAboutDialog
Major changes in 2.9.2 are:

16
TODO-gio Normal file
View file

@ -0,0 +1,16 @@
Monitor for UNMOUNT file change event and close window
Break out file activation from fm-directory-view.c
File actication cancellation not implemented yet
convert delete to use trash_or_delete code
recursive deletes
progress for trash/delete
Automount location when loading it in a window and its not mounted.
"translate" gnome-vfs errors and update error handling
fm-directory-view.c: pre_copy_move stuff leaks as it waits for uris that are not in the target directory.

View file

@ -2,7 +2,6 @@ AC_PREREQ(2.54)
dnl ===========================================================================
m4_define(art_minver, 2.3.10)
m4_define(bonobo_activation_minver, 2.1.0)
m4_define(bonobo_minver, 2.1.0)
m4_define(eel_minver, 2.15.91)
@ -22,6 +21,7 @@ m4_define(exif_minver, 0.5.12)
m4_define(beagle_minver, 0.0.12)
m4_define(tracker_minver, 0.0.1)
m4_define(exempi_minver, 1.99.2)
m4_define(exempi_minver_newapi, 1.99.5)
dnl 1. If the library code has changed at all since last release, then increment revision.
dnl 2. If any interfaces have been added, then increment current and set revision to 0.
@ -29,7 +29,7 @@ dnl Interface break is not allowed.
m4_define(nautilus_extension_current, 2)
m4_define(nautilus_extension_revision, 0)
AC_INIT(nautilus, 2.20.1,
AC_INIT(nautilus, 2.21.1
[http://bugzilla.gnome.org/enter_bug.cgi?product=nautilus])
dnl ===========================================================================
@ -41,7 +41,6 @@ AM_INIT_AUTOMAKE
AM_MAINTAINER_MODE
AC_SUBST([ACLOCAL_AMFLAGS], ["\${ACLOCAL_FLAGS}"])
AC_SUBST(ART_REQUIRED, [art_minver])
AC_SUBST(BONOBO_ACTIVATION_REQUIRED, [bonobo_activation_minver])
AC_SUBST(BONOBO_REQUIRED, [bonobo_minver])
AC_SUBST(EEL_REQUIRED, [eel_minver])
@ -97,10 +96,10 @@ PKG_CHECK_MODULES(ALL, [
gnome-desktop-2.0 >= gnome_desktop_minver
gnome-vfs-2.0 >= gnome_vfs_minver
gnome-vfs-module-2.0 >= gnome_vfs_minver
gio-2.0
ORBit-2.0 >= orbit_minver
pango >= pango_minver
gtk+-2.0 >= gtk_minver
libart-2.0 >= art_minver
libbonobo-2.0 >= bonobo_minver
libgnome-2.0 >= gnome_minver
libgnomeui-2.0 >= gnome_ui_minver
@ -266,6 +265,9 @@ PKG_CHECK_MODULES(EXEMPI, exempi-2.0 >= exempi_minver, [
AC_DEFINE(HAVE_EXEMPI, 1, [Define to enable XMP support])
], [AM_CONDITIONAL(HAVE_EXEMPI, false)])
PKG_CHECK_MODULES(EXEMPI_NEW_API, exempi-2.0 >= exempi_minver_newapi,
AC_DEFINE(HAVE_EXEMPI_NEW_API, 1, [Define if we have exempi with the new API]), true)
AC_SUBST(EXEMPI_CFLAGS)
AC_SUBST(EXEMPI_LIBS)
@ -404,7 +406,7 @@ LIBNAUTILUS_EXTENSION_LIBS="`$PKG_CONFIG --libs $LIBNAUTILUS_EXTENSION_MODULES`"
AC_SUBST(LIBNAUTILUS_EXTENSION_LIBS)
dnl core nautilus (must list bonobo-activation and libbonobo because idldir does not respect "requires")
CORE_MODULES="eel-2.0 librsvg-2.0 bonobo-activation-2.0 libbonobo-2.0 esound gnome-desktop-2.0 gnome-vfs-module-2.0 $EXTRA_CORE_MODULES"
CORE_MODULES="eel-2.0 librsvg-2.0 bonobo-activation-2.0 libbonobo-2.0 esound gnome-desktop-2.0 gnome-vfs-module-2.0 gio-2.0 $EXTRA_CORE_MODULES"
CORE_CFLAGS="`$PKG_CONFIG --cflags $CORE_MODULES` $x_cflags $WARNING_CFLAGS"
AC_SUBST(CORE_CFLAGS)
CORE_LIBS="`$PKG_CONFIG --libs $CORE_MODULES` $x_libs"

View file

@ -88,7 +88,7 @@ Control can be held down while starting a drag
While doing a drag modifers affect the operation the drag causes:
Control - Copy the files
Shift - Move the files
Alt - Open a menu with the availible alternatives
Alt - Open a menu with the available alternatives
All the basic clicks are typically done with the left button, but can
be done with the other buttons to. [Do we want this?] However some of

View file

@ -165,21 +165,12 @@ nautilus_file_info_is_directory (NautilusFileInfo *file)
return NAUTILUS_FILE_INFO_GET_IFACE (file)->is_directory (file);
}
GnomeVFSFileInfo *
nautilus_file_info_get_vfs_file_info (NautilusFileInfo *file)
{
g_return_val_if_fail (NAUTILUS_IS_FILE_INFO (file), NULL);
g_return_val_if_fail (NAUTILUS_FILE_INFO_GET_IFACE (file)->get_vfs_file_info != NULL, NULL);
return NAUTILUS_FILE_INFO_GET_IFACE (file)->get_vfs_file_info (file);
}
void
nautilus_file_info_add_emblem (NautilusFileInfo *file,
const char *emblem_name)
{
g_return_if_fail (NAUTILUS_IS_FILE_INFO (file));
g_return_if_fail (NAUTILUS_FILE_INFO_GET_IFACE (file)->get_vfs_file_info != NULL);
g_return_if_fail (NAUTILUS_FILE_INFO_GET_IFACE (file)->add_emblem != NULL);
NAUTILUS_FILE_INFO_GET_IFACE (file)->add_emblem (file, emblem_name);
}
@ -218,39 +209,3 @@ nautilus_file_info_invalidate_extension_info (NautilusFileInfo *file)
NAUTILUS_FILE_INFO_GET_IFACE (file)->invalidate_extension_info (file);
}
gboolean
nautilus_file_info_has_volume (NautilusFileInfo *file)
{
g_return_val_if_fail (NAUTILUS_IS_FILE_INFO (file), FALSE);
g_return_val_if_fail (NAUTILUS_FILE_INFO_GET_IFACE (file)->has_volume != NULL, FALSE);
return NAUTILUS_FILE_INFO_GET_IFACE (file)->has_volume (file);
}
gboolean
nautilus_file_info_has_drive (NautilusFileInfo *file)
{
g_return_val_if_fail (NAUTILUS_IS_FILE_INFO (file), FALSE);
g_return_val_if_fail (NAUTILUS_FILE_INFO_GET_IFACE (file)->has_drive != NULL, FALSE);
return NAUTILUS_FILE_INFO_GET_IFACE (file)->has_drive (file);
}
GnomeVFSVolume*
nautilus_file_info_get_volume (NautilusFileInfo *file)
{
g_return_val_if_fail (NAUTILUS_IS_FILE_INFO (file),NULL);
g_return_val_if_fail (NAUTILUS_FILE_INFO_GET_IFACE (file)->get_volume != NULL,NULL);
return NAUTILUS_FILE_INFO_GET_IFACE (file)->get_volume (file);
}
GnomeVFSDrive*
nautilus_file_info_get_drive (NautilusFileInfo *file)
{
g_return_val_if_fail (NAUTILUS_IS_FILE_INFO (file),NULL);
g_return_val_if_fail (NAUTILUS_FILE_INFO_GET_IFACE (file)->get_drive != NULL,NULL);
return NAUTILUS_FILE_INFO_GET_IFACE (file)->get_drive (file);
}

View file

@ -27,8 +27,6 @@
#define NAUTILUS_FILE_INFO_H
#include <glib-object.h>
#include <libgnomevfs/gnome-vfs-file-info.h>
#include <libgnomevfs/gnome-vfs-volume.h>
G_BEGIN_DECLS
@ -65,8 +63,6 @@ struct _NautilusFileInfoIface
const char *mime_Type);
gboolean (*is_directory) (NautilusFileInfo *file);
GnomeVFSFileInfo *(*get_vfs_file_info) (NautilusFileInfo *file);
void (*add_emblem) (NautilusFileInfo *file,
const char *emblem_name);
char * (*get_string_attribute) (NautilusFileInfo *file,
@ -76,11 +72,6 @@ struct _NautilusFileInfoIface
const char *value);
void (*invalidate_extension_info) (NautilusFileInfo *file);
gboolean (*has_volume) (NautilusFileInfo *file);
gboolean (*has_drive) (NautilusFileInfo *file);
GnomeVFSVolume* (*get_volume) (NautilusFileInfo *file);
GnomeVFSDrive* (*get_drive) (NautilusFileInfo *file);
char * (*get_activation_uri) (NautilusFileInfo *file);
};
@ -105,12 +96,6 @@ gboolean nautilus_file_info_is_mime_type (NautilusFileInfo *fil
gboolean nautilus_file_info_is_directory (NautilusFileInfo *file);
/* Other File Info */
GnomeVFSFileInfo *nautilus_file_info_get_vfs_file_info (NautilusFileInfo *file);
/* Modifying the NautilusFileInfo */
void nautilus_file_info_add_emblem (NautilusFileInfo *file,
const char *emblem_name);
@ -123,11 +108,6 @@ void nautilus_file_info_add_string_attribute (NautilusFileInfo *fil
/* Invalidating file info */
void nautilus_file_info_invalidate_extension_info (NautilusFileInfo *file);
/* Volumes and Drives */
gboolean nautilus_file_info_has_volume (NautilusFileInfo *file);
gboolean nautilus_file_info_has_drive (NautilusFileInfo *file);
GnomeVFSVolume* nautilus_file_info_get_volume (NautilusFileInfo *file);
GnomeVFSDrive* nautilus_file_info_get_drive (NautilusFileInfo *file);
G_END_DECLS

View file

@ -13,7 +13,7 @@ INCLUDES = \
-DDATADIR=\""$(datadir)"\" \
-DSYSCONFDIR=\""$(sysconfdir)"\" \
-DNAUTILUS_DATADIR=\""$(datadir)/nautilus"\" \
-DNAUTILUS_EXTENSIONDIR=\""$(libdir)/nautilus/extensions-1.0"\" \
-DNAUTILUS_EXTENSIONDIR=\""$(libdir)/nautilus/extensions-2.0"\" \
$(NULL)
dependency_static_libs = \
@ -49,8 +49,6 @@ marshal_sources = \
libnautilus_private_la_SOURCES = \
$(nautilus_metafile_server_idl_sources) \
nautilus-audio-player.c \
nautilus-audio-player.h \
nautilus-bookmark.c \
nautilus-bookmark.h \
nautilus-cell-renderer-pixbuf-emblem.c \
@ -125,10 +123,9 @@ libnautilus_private_la_SOURCES = \
nautilus-icon-container.h \
nautilus-icon-dnd.c \
nautilus-icon-dnd.h \
nautilus-icon-factory-private.h \
nautilus-icon-factory.c \
nautilus-icon-factory.h \
nautilus-icon-private.h \
nautilus-icon-info.c \
nautilus-icon-info.h \
nautilus-idle-queue.c \
nautilus-idle-queue.h \
nautilus-iso9660.h \
@ -136,8 +133,6 @@ libnautilus_private_la_SOURCES = \
nautilus-keep-last-vertical-box.h \
nautilus-lib-self-check-functions.c \
nautilus-lib-self-check-functions.h \
nautilus-link-desktop-file.c \
nautilus-link-desktop-file.h \
nautilus-link.c \
nautilus-link.h \
nautilus-marshal.c \
@ -151,10 +146,16 @@ libnautilus_private_la_SOURCES = \
nautilus-metafile.h \
nautilus-mime-actions.c \
nautilus-mime-actions.h \
nautilus-mime-application-chooser.c \
nautilus-mime-application-chooser.h \
nautilus-module.c \
nautilus-module.h \
nautilus-monitor.c \
nautilus-monitor.h \
nautilus-open-with-dialog.c \
nautilus-open-with-dialog.h \
nautilus-progress-info.c \
nautilus-progress-info.h \
nautilus-program-choosing.c \
nautilus-program-choosing.h \
nautilus-recent.c \
@ -179,10 +180,6 @@ libnautilus_private_la_SOURCES = \
nautilus-query.h \
nautilus-thumbnails.c \
nautilus-thumbnails.h \
nautilus-trash-directory.c \
nautilus-trash-directory.h \
nautilus-trash-file.c \
nautilus-trash-file.h \
nautilus-trash-monitor.c \
nautilus-trash-monitor.h \
nautilus-tree-view-drag-dest.c \

View file

@ -1,549 +0,0 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* nautilus-audio-player.c - Simple threaded audio file playback.
Copyright (C) 2001 Eazel, Inc.
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The Gnome Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the Gnome Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Authors: Gene Z. Ragan <gzr@eazel.com>
*/
#include <config.h>
#include "nautilus-audio-player.h"
#include <esd.h>
#include <glib/gmem.h>
#include <glib/gstrfuncs.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/* BUFFER_FRAMES represents the size of the buffer in frames. */
#define BUFFER_FRAMES 4096
#define PLAYER_STREAM_NAME "nautilus-audio-player"
typedef enum {
FORMAT_U8,
FORMAT_S8,
FORMAT_U16_LE,
FORMAT_U16_BE,
FORMAT_U16_NE,
FORMAT_S16_LE,
FORMAT_S16_BE,
FORMAT_S16_NE
}
AudioFormat;
typedef struct {
pthread_t buffer_thread;
gint fd;
gpointer buffer;
gboolean going, prebuffer, paused;
gint buffer_size, prebuffer_size, block_size;
gint rd_index, wr_index;
gint output_time_offset;
guint64 written, output_bytes;
gint bps, ebps;
gint flush;
gint channels, frequency, latency;
AudioFormat format;
esd_format_t esd_format;
gint input_bps, input_format, input_frequency, input_channels;
char *hostname;
ESDConfig esd_config;
void *(*esd_translate)(void *, gint);
} ESDInfo;
static gboolean esdout_open (ESDInfo *info,
AudioFormat format,
gint rate,
gint nch);
static void esdout_close (ESDInfo *info);
static void esdout_set_audio_params (ESDInfo *info);
static void esdout_write (ESDInfo *info,
gpointer data,
int length);
static int esdout_used (ESDInfo *info);
static gboolean esdout_playing (ESDInfo *info);
static void *
player_thread (void *arg)
{
NautilusAudioPlayerData *data;
AFframecount frames_read;
int sample_format, frame_size, channel_count, sample_width;
double rate;
void *buffer;
ESDInfo info;
data = arg;
if (data == NULL) {
pthread_exit (NULL);
return (void *) 0;
}
/* Read information from file */
afGetSampleFormat (data->handle, AF_DEFAULT_TRACK, &sample_format, &sample_width);
frame_size = afGetFrameSize (data->handle, AF_DEFAULT_TRACK, 1);
channel_count = afGetChannels (data->handle, AF_DEFAULT_TRACK);
rate = afGetRate (data->handle, AF_DEFAULT_TRACK);
/* Attempt to open ESD */
if (!esdout_open (&info, sample_width == 16 ? FORMAT_S16_NE : FORMAT_U8, (int)rate, channel_count)) {
pthread_exit (NULL);
return (void *) 0;
}
/* Read audio data from file and send it to the esd output thread */
buffer = malloc (BUFFER_FRAMES * frame_size);
frames_read = afReadFrames (data->handle, AF_DEFAULT_TRACK, buffer, BUFFER_FRAMES);
while (frames_read > 0 && data->running) {
esdout_write (&info, buffer, frames_read * frame_size);
frames_read = afReadFrames (data->handle, AF_DEFAULT_TRACK, buffer, BUFFER_FRAMES);
}
afCloseFile (data->handle);
/* Now wait for the esd output thread to complete it task */
while (esdout_playing (&info) && data->running) {
usleep (20000);
}
/* Shutdown esd output thread */
esdout_close (&info);
g_free (buffer);
pthread_exit (NULL);
return (void *) 0;
}
NautilusAudioPlayerData *
nautilus_audio_player_play (const char *filename)
{
AFfilehandle handle;
NautilusAudioPlayerData *data;
handle = afOpenFile (filename, "r", NULL);
if (handle == AF_NULL_FILEHANDLE) {
return NULL;
}
data = g_new0 (NautilusAudioPlayerData, 1);
data->handle = handle;
data->running = TRUE;
pthread_create (&data->player_id, NULL, player_thread, data);
return data;
}
void
nautilus_audio_player_stop (NautilusAudioPlayerData *data)
{
if (data == NULL) {
return;
}
data->running = FALSE;
pthread_join (data->player_id, NULL);
}
static void
esdout_init (ESDInfo *info)
{
memset (&info->esd_config, 0, sizeof (ESDConfig));
info->fd = 0;
info->going = FALSE;
info->paused = FALSE;
info->buffer = NULL;
info->block_size = BUFFER_FRAMES;
info->rd_index = 0;
info->wr_index = 0;
info->output_time_offset = 0;
info->written = 0;
info->output_bytes = 0;
info->hostname = NULL;
info->esd_config.port = ESD_DEFAULT_PORT;
info->esd_config.buffer_size = 3000;
info->esd_config.prebuffer = 25;
}
static void
esdout_write (ESDInfo *info, gpointer data, int length)
{
int count, offset;
offset = 0;
info->written += length;
while (length > 0) {
count = MIN (length, info->buffer_size - info->wr_index);
memcpy ((char *)info->buffer + info->wr_index, (char *)data + offset, count);
info->wr_index = (info->wr_index + count) % info->buffer_size;
length -= count;
offset += count;
}
}
static gint
get_latency (ESDInfo *config)
{
int fd, amount = 0;
#ifndef HAVE_ESD_GET_LATENCY
esd_server_info_t *info;
#endif
fd = esd_open_sound (config->hostname);
if (fd == -1) {
return 0;
}
#ifdef HAVE_ESD_GET_LATENCY
amount = get_latency (fd);
#else
info = esd_get_server_info (fd);
if (info != NULL) {
if (info->format & ESD_STEREO) {
if (info->format & ESD_BITS16)
amount = (44100 * (ESD_BUF_SIZE + 64)) / info->rate;
else
amount = (44100 * (ESD_BUF_SIZE + 128)) / info->rate;
} else {
if (info->format & ESD_BITS16)
amount = (2 * 44100 * (ESD_BUF_SIZE + 128)) / info->rate;
else
amount = (2 * 44100 * (ESD_BUF_SIZE + 256)) / info->rate;
}
free (info);
}
amount += ESD_BUF_SIZE * 2;
#endif
esd_close (fd);
return amount;
}
static void *
esd_stou8 (void *data, gint length)
{
int len = length;
unsigned char *dat = (unsigned char *)data;
while (len-- > 0)
*dat++ ^= 0x80;
return data;
}
static void *
esd_utos16sw (void *data, gint length)
{
int len = length;
short *dat = data;
while ( len > 0 ) {
*dat = GUINT16_SWAP_LE_BE ( *dat ) ^ 0x8000;
dat++;
len-=2;
}
return data;
}
static void *
esd_utos16 (void *data, gint length)
{
int len = length;
short *dat = data;
while ( len > 0 ) {
*dat ^= 0x8000;
dat++;
len-=2;
}
return data;
}
static void *
esd_16sw (void *data, gint length)
{
int len = length;
short *dat = data;
while ( len > 0 ) {
*dat = GUINT16_SWAP_LE_BE( *dat );
dat++;
len-=2;
}
return data;
}
static void
esdout_setup_format (ESDInfo *info, AudioFormat format, gint rate, gint nch)
{
gboolean swap_sign = FALSE;
gboolean swap_16 = FALSE;
info->format = format;
info->frequency = rate;
info->channels = nch;
switch (format) {
case FORMAT_S8:
swap_sign = TRUE;
case FORMAT_U8:
info->esd_format = ESD_BITS8;
break;
case FORMAT_U16_LE:
case FORMAT_U16_BE:
case FORMAT_U16_NE:
swap_sign = TRUE;
case FORMAT_S16_LE:
case FORMAT_S16_BE:
case FORMAT_S16_NE:
info->esd_format = ESD_BITS16;
break;
}
#ifdef WORDS_BIGENDIAN
if (format == FORMAT_U16_LE || format == FORMAT_S16_LE)
#else
if (format == FORMAT_U16_BE || format == FORMAT_S16_BE)
#endif
swap_16 = TRUE;
info->esd_translate = (void*(*)())NULL;
if (info->esd_format == ESD_BITS8) {
if (swap_sign) {
info->esd_translate = esd_stou8;
}
} else {
if (swap_sign) {
if (swap_16) {
info->esd_translate = esd_utos16sw;
} else {
info->esd_translate = esd_utos16;
}
} else {
if (swap_16) {
info->esd_translate = esd_16sw;
}
}
}
info->bps = rate * nch;
if (info->esd_format == ESD_BITS16) {
info->bps *= 2;
}
if (nch == 1) {
info->esd_format |= ESD_MONO;
} else {
info->esd_format |= ESD_STEREO;
}
info->esd_format |= ESD_STREAM | ESD_PLAY;
info->latency = ((get_latency (info) * info->frequency) / 44100) * info->channels;
if (info->format != FORMAT_U8 && info->format != FORMAT_S8) {
info->latency *= 2;
}
}
static gint
esdout_used (ESDInfo *info)
{
if (info->wr_index >= info->rd_index) {
return info->wr_index - info->rd_index;
}
return info->buffer_size - (info->rd_index - info->wr_index);
}
static void
esdout_write_audio (ESDInfo *info, gint length)
{
AudioFormat new_format;
gint new_frequency, new_channels;
char *data;
data = (char *)info->buffer + info->rd_index;
new_format = info->input_format;
new_frequency = info->input_frequency;
new_channels = info->input_channels;
if (new_format != info->format || new_frequency != info->frequency || new_channels != info->channels) {
info->output_time_offset += (gint) ((info->output_bytes * 1000) / info->ebps);
info->output_bytes = 0;
esdout_setup_format (info, new_format, new_frequency, new_channels);
info->frequency = new_frequency;
info->channels = new_channels;
close (info->fd);
esdout_set_audio_params (info);
}
if (info->esd_translate) {
info->output_bytes += write (info->fd, info->esd_translate (data, length), length);
} else {
info->output_bytes += write (info->fd, data, length);
}
}
static void
esdout_close (ESDInfo *info)
{
info->going = FALSE;
info->wr_index = 0;
info->rd_index = 0;
info->going = 0;
g_free (info->hostname);
info->hostname = NULL;
pthread_join (info->buffer_thread, NULL);
}
static void *
esdout_loop (void *arg)
{
int length, count, used;
ESDInfo *info;
info = arg;
while (info->going) {
used = esdout_used (info);
if (used > info->prebuffer_size) {
info->prebuffer = FALSE;
}
if (used > 0 && !info->paused && !info->prebuffer) {
length = MIN (info->block_size, used);
while (length > 0) {
count = MIN (length, info->buffer_size - info->rd_index);
esdout_write_audio (info, count);
info->rd_index = (info->rd_index + count) % info->buffer_size;
length -= count;
}
} else {
usleep (10000);
}
if (info->flush != -1) {
info->output_time_offset = info->flush;
info->written = (guint64)(info->flush / 10) * (guint64)(info->input_bps / 100);
info->rd_index = info->wr_index = info->output_bytes = 0;
info->flush = -1;
info->prebuffer = TRUE;
}
}
close (info->fd);
g_free (info->buffer);
while (info->going) {
usleep (10000);
}
pthread_exit (NULL);
return (void *) 0;
}
static void
esdout_set_audio_params (ESDInfo *info)
{
info->fd = esd_play_stream (info->esd_format, info->frequency, info->hostname, PLAYER_STREAM_NAME);
info->ebps = info->frequency * info->channels;
if (info->format == FORMAT_U16_BE || info->format == FORMAT_U16_LE || info->format == FORMAT_S16_BE
|| info->format == FORMAT_S16_LE || info->format == FORMAT_S16_NE || info->format == FORMAT_U16_NE) {
info->ebps *= 2;
}
}
static gboolean
esdout_open (ESDInfo *info, AudioFormat format, gint rate, gint nch)
{
esdout_init (info);
esdout_setup_format (info, format, rate, nch);
info->input_format = info->format;
info->input_channels = info->channels;
info->input_frequency = info->frequency;
info->input_bps = info->bps;
info->buffer_size = (info->esd_config.buffer_size * info->input_bps) / 1000;
if (info->buffer_size < 8192) {
info->buffer_size = 8192;
}
info->prebuffer_size = (info->buffer_size * info->esd_config.prebuffer) / 100;
if (info->buffer_size - info->prebuffer_size < 4096) {
info->prebuffer_size = info->buffer_size - 4096;
}
info->buffer = g_malloc0 (info->buffer_size);
info->flush = -1;
info->prebuffer = TRUE;
info->wr_index = info->rd_index = info->output_time_offset = info->written = info->output_bytes = 0;
info->paused = FALSE;
if (info->hostname != NULL) {
g_free (info->hostname);
}
if (info->esd_config.use_remote) {
info->hostname = g_strdup_printf ("%s:%d", info->esd_config.server, info->esd_config.port);
} else {
info->hostname = NULL;
}
esdout_set_audio_params (info);
if (info->fd == -1) {
g_free (info->buffer);
info->buffer = NULL;
return FALSE;
}
info->going = TRUE;
pthread_create (&info->buffer_thread, NULL, esdout_loop, info);
return TRUE;
}
static gboolean
esdout_playing (ESDInfo *info)
{
if (!info->going) {
return FALSE;
}
if (esdout_used (info) <= 0) {
return FALSE;
}
return TRUE;
}

View file

@ -1,55 +0,0 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* nautilus-audio-player.h - Simple threaded audio file playback.
Copyright (C) 2001 Eazel, Inc.
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The Gnome Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the Gnome Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Authors: Gene Z. Ragan <gzr@eazel.com>
*/
#ifndef NAUTILUS_AUDIO_PLAYER_H
#define NAUTILUS_AUDIO_PLAYER_H
#include <config.h>
#include <sys/types.h>
#include <audiofile.h>
#include <pthread.h>
#include <glib/gtypes.h>
typedef struct {
gboolean use_remote;
char *server;
int port;
int buffer_size;
int prebuffer;
} ESDConfig;
typedef struct {
AFfilehandle handle;
pthread_t player_id;
gboolean running;
ESDConfig esd_config;
} NautilusAudioPlayerData;
NautilusAudioPlayerData *nautilus_audio_player_play (const char *filename);
void nautilus_audio_player_stop (NautilusAudioPlayerData *data);
#endif

View file

@ -25,7 +25,7 @@
#include <config.h>
#include "nautilus-bookmark.h"
#include "nautilus-icon-factory.h"
#include "nautilus-file.h"
#include <eel/eel-gdk-pixbuf-extensions.h>
#include <eel/eel-gtk-extensions.h>
#include <eel/eel-gtk-macros.h>
@ -35,11 +35,11 @@
#include <gtk/gtkimage.h>
#include <gtk/gtkimagemenuitem.h>
#include <gtk/gtksignal.h>
#include <gtk/gtkiconfactory.h>
#include <libgnome/gnome-macros.h>
#include <libgnome/gnome-util.h>
#include <libgnomevfs/gnome-vfs-types.h>
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <gio/gthemedicon.h>
#include <libnautilus-private/nautilus-file.h>
enum {
APPEARANCE_CHANGED,
@ -58,8 +58,8 @@ struct NautilusBookmarkDetails
{
char *name;
gboolean has_custom_name;
char *uri;
char *icon;
GFile *location;
GIcon *icon;
NautilusFile *file;
char *scroll_file;
@ -85,8 +85,10 @@ nautilus_bookmark_finalize (GObject *object)
nautilus_bookmark_disconnect_file (bookmark);
g_free (bookmark->details->name);
g_free (bookmark->details->uri);
g_free (bookmark->details->icon);
g_object_unref (bookmark->details->location);
if (bookmark->details->icon) {
g_object_unref (bookmark->details->icon);
}
g_free (bookmark->details->scroll_file);
g_free (bookmark->details);
@ -153,9 +155,9 @@ nautilus_bookmark_compare_with (gconstpointer a, gconstpointer b)
return 1;
}
if (!gnome_vfs_uris_match (bookmark_a->details->uri,
bookmark_b->details->uri)) {
return 1;
if (g_file_equal (bookmark_a->details->location,
bookmark_b->details->location)) {
return 0;
}
return 0;
@ -183,8 +185,8 @@ nautilus_bookmark_compare_uris (gconstpointer a, gconstpointer b)
bookmark_a = NAUTILUS_BOOKMARK (a);
bookmark_b = NAUTILUS_BOOKMARK (b);
return !gnome_vfs_uris_match (bookmark_a->details->uri,
bookmark_b->details->uri);
return !g_file_equal (bookmark_a->details->location,
bookmark_b->details->location);
}
NautilusBookmark *
@ -193,7 +195,7 @@ nautilus_bookmark_copy (NautilusBookmark *bookmark)
g_return_val_if_fail (NAUTILUS_IS_BOOKMARK (bookmark), NULL);
return nautilus_bookmark_new_with_icon (
bookmark->details->uri,
bookmark->details->location,
bookmark->details->name,
bookmark->details->has_custom_name,
bookmark->details->icon);
@ -219,10 +221,13 @@ nautilus_bookmark_get_has_custom_name (NautilusBookmark *bookmark)
GdkPixbuf *
nautilus_bookmark_get_pixbuf (NautilusBookmark *bookmark,
GtkIconSize icon_size)
GtkIconSize stock_size)
{
GdkPixbuf *result;
char *icon;
GIcon *icon;
NautilusIconInfo *info;
int pixel_size;
g_return_val_if_fail (NAUTILUS_IS_BOOKMARK (bookmark), NULL);
@ -230,18 +235,16 @@ nautilus_bookmark_get_pixbuf (NautilusBookmark *bookmark,
if (icon == NULL) {
return NULL;
}
result = nautilus_icon_factory_get_pixbuf_for_icon_with_stock_size
(icon, NULL,
icon_size, NULL, NULL,
TRUE, NULL);
g_free (icon);
pixel_size = nautilus_get_icon_size_for_stock_size (stock_size);
info = nautilus_icon_info_lookup (icon, pixel_size);
result = nautilus_icon_info_get_pixbuf_at_size (info, pixel_size);
g_object_unref (info);
return result;
}
char *
GIcon *
nautilus_bookmark_get_icon (NautilusBookmark *bookmark)
{
g_return_val_if_fail (NAUTILUS_IS_BOOKMARK (bookmark), NULL);
@ -249,11 +252,14 @@ nautilus_bookmark_get_icon (NautilusBookmark *bookmark)
/* Try to connect a file in case file exists now but didn't earlier. */
nautilus_bookmark_connect_file (bookmark);
return g_strdup (bookmark->details->icon);
if (bookmark->details->icon) {
return g_object_ref (bookmark->details->icon);
}
return NULL;
}
char *
nautilus_bookmark_get_uri (NautilusBookmark *bookmark)
GFile *
nautilus_bookmark_get_location (NautilusBookmark *bookmark)
{
g_return_val_if_fail(NAUTILUS_IS_BOOKMARK (bookmark), NULL);
@ -265,7 +271,19 @@ nautilus_bookmark_get_uri (NautilusBookmark *bookmark)
*/
nautilus_bookmark_connect_file (bookmark);
return g_strdup (bookmark->details->uri);
return g_object_ref (bookmark->details->location);
}
char *
nautilus_bookmark_get_uri (NautilusBookmark *bookmark)
{
GFile *file;
char *uri;
file = nautilus_bookmark_get_location (bookmark);
uri = g_file_get_uri (file);
g_object_unref (file);
return uri;
}
@ -303,12 +321,16 @@ nautilus_bookmark_set_has_custom_name (NautilusBookmark *bookmark, gboolean has_
static gboolean
nautilus_bookmark_icon_is_different (NautilusBookmark *bookmark,
char *new_icon)
GIcon *new_icon)
{
g_assert (NAUTILUS_IS_BOOKMARK (bookmark));
g_assert (new_icon != NULL);
return eel_strcmp (bookmark->details->icon, new_icon) != 0;
if (bookmark->details->icon == NULL) {
return new_icon == NULL;
}
return !g_icon_equal (bookmark->details->icon, new_icon) != 0;
}
/**
@ -318,7 +340,7 @@ nautilus_bookmark_icon_is_different (NautilusBookmark *bookmark,
static gboolean
nautilus_bookmark_update_icon (NautilusBookmark *bookmark)
{
char *new_icon;
GIcon *new_icon;
g_assert (NAUTILUS_IS_BOOKMARK (bookmark));
@ -326,14 +348,17 @@ nautilus_bookmark_update_icon (NautilusBookmark *bookmark)
return FALSE;
}
if (nautilus_icon_factory_is_icon_ready_for_file (bookmark->details->file)) {
new_icon = nautilus_icon_factory_get_icon_for_file (bookmark->details->file, FALSE);
if (nautilus_file_check_if_ready (bookmark->details->file,
NAUTILUS_FILE_ATTRIBUTES_FOR_ICON)) {
new_icon = nautilus_file_get_gicon (bookmark->details->file, 0);
if (nautilus_bookmark_icon_is_different (bookmark, new_icon)) {
g_free (bookmark->details->icon);
if (bookmark->details->icon) {
g_object_unref (bookmark->details->icon);
}
bookmark->details->icon = new_icon;
return TRUE;
}
g_free (new_icon);
g_object_unref (new_icon);
}
return FALSE;
@ -342,25 +367,26 @@ nautilus_bookmark_update_icon (NautilusBookmark *bookmark)
static void
bookmark_file_changed_callback (NautilusFile *file, NautilusBookmark *bookmark)
{
char *file_uri;
GFile *location;
gboolean should_emit_appearance_changed_signal;
gboolean should_emit_contents_changed_signal;
char *display_name;
g_assert (NAUTILUS_IS_FILE (file));
g_assert (NAUTILUS_IS_BOOKMARK (bookmark));
g_assert (file == bookmark->details->file);
should_emit_appearance_changed_signal = FALSE;
should_emit_contents_changed_signal = FALSE;
file_uri = nautilus_file_get_uri (file);
location = nautilus_file_get_location (file);
if (!gnome_vfs_uris_match (bookmark->details->uri, file_uri) &&
if (!g_file_equal (bookmark->details->location, location) &&
!nautilus_file_is_in_trash (file)) {
g_free (bookmark->details->uri);
bookmark->details->uri = file_uri;
g_object_unref (bookmark->details->location);
bookmark->details->location = location;
should_emit_contents_changed_signal = TRUE;
} else {
g_free (file_uri);
g_object_unref (location);
}
if (nautilus_file_is_gone (file) ||
@ -380,6 +406,18 @@ bookmark_file_changed_callback (NautilusFile *file, NautilusBookmark *bookmark)
should_emit_appearance_changed_signal = TRUE;
}
if (!bookmark->details->has_custom_name) {
display_name = nautilus_file_get_display_name (file);
if (strcmp (bookmark->details->name, display_name) != 0) {
g_free (bookmark->details->name);
bookmark->details->name = display_name;
should_emit_appearance_changed_signal = TRUE;
} else {
g_free (display_name);
}
}
if (should_emit_appearance_changed_signal) {
g_signal_emit (bookmark, signals[APPEARANCE_CHANGED], 0);
}
@ -401,7 +439,9 @@ nautilus_bookmark_set_icon_to_default (NautilusBookmark *bookmark)
const char *icon_name;
g_free (bookmark->details->icon);
if (bookmark->details->icon) {
g_object_unref (bookmark->details->icon);
}
if (nautilus_bookmark_uri_known_not_to_exist (bookmark)) {
icon_name = MISSING_BOOKMARK_ICON_NAME;
@ -409,7 +449,7 @@ nautilus_bookmark_set_icon_to_default (NautilusBookmark *bookmark)
icon_name = GENERIC_BOOKMARK_ICON_NAME;
}
bookmark->details->icon = g_strdup (icon_name);
bookmark->details->icon = g_themed_icon_new (icon_name);
}
/**
@ -427,9 +467,9 @@ nautilus_bookmark_set_icon_to_default (NautilusBookmark *bookmark)
*
**/
NautilusBookmark *
nautilus_bookmark_new (const char *uri, const char *name)
nautilus_bookmark_new (GFile *location, const char *name)
{
return nautilus_bookmark_new_with_icon (uri, name, FALSE, NULL);
return nautilus_bookmark_new_with_icon (location, name, FALSE, NULL);
}
static void
@ -446,7 +486,7 @@ nautilus_bookmark_disconnect_file (NautilusBookmark *bookmark)
}
if (bookmark->details->icon != NULL) {
g_free (bookmark->details->icon);
g_object_unref (bookmark->details->icon);
bookmark->details->icon = NULL;
}
}
@ -454,6 +494,8 @@ nautilus_bookmark_disconnect_file (NautilusBookmark *bookmark)
static void
nautilus_bookmark_connect_file (NautilusBookmark *bookmark)
{
char *display_name;
g_assert (NAUTILUS_IS_BOOKMARK (bookmark));
if (bookmark->details->file != NULL) {
@ -461,7 +503,7 @@ nautilus_bookmark_connect_file (NautilusBookmark *bookmark)
}
if (!nautilus_bookmark_uri_known_not_to_exist (bookmark)) {
bookmark->details->file = nautilus_file_get (bookmark->details->uri);
bookmark->details->file = nautilus_file_get (bookmark->details->location);
g_assert (!nautilus_file_is_gone (bookmark->details->file));
g_signal_connect_object (bookmark->details->file, "changed",
@ -476,22 +518,35 @@ nautilus_bookmark_connect_file (NautilusBookmark *bookmark)
nautilus_bookmark_set_icon_to_default (bookmark);
}
}
if (!bookmark->details->has_custom_name &&
bookmark->details->file &&
nautilus_file_check_if_ready (bookmark->details->file, NAUTILUS_FILE_ATTRIBUTE_INFO)) {
display_name = nautilus_file_get_display_name (bookmark->details->file);
if (strcmp (bookmark->details->name, display_name) != 0) {
g_free (bookmark->details->name);
bookmark->details->name = display_name;
} else {
g_free (display_name);
}
}
}
NautilusBookmark *
nautilus_bookmark_new_with_icon (const char *uri, const char *name, gboolean has_custom_name,
const char *icon)
nautilus_bookmark_new_with_icon (GFile *location, const char *name, gboolean has_custom_name,
GIcon *icon)
{
NautilusBookmark *new_bookmark;
new_bookmark = NAUTILUS_BOOKMARK (g_object_new (NAUTILUS_TYPE_BOOKMARK, NULL));
g_object_ref (new_bookmark);
gtk_object_sink (GTK_OBJECT (new_bookmark));
g_object_ref_sink (new_bookmark);
new_bookmark->details->name = g_strdup (name);
new_bookmark->details->uri = g_strdup (uri);
new_bookmark->details->location = g_object_ref (location);
new_bookmark->details->has_custom_name = has_custom_name;
new_bookmark->details->icon = g_strdup (icon);
if (icon) {
new_bookmark->details->icon = g_object_ref (icon);
}
nautilus_bookmark_connect_file (new_bookmark);
@ -552,7 +607,7 @@ nautilus_bookmark_uri_known_not_to_exist (NautilusBookmark *bookmark)
gboolean exists;
/* Convert to a path, returning FALSE if not local. */
path_name = gnome_vfs_get_local_path_from_uri (bookmark->details->uri);
path_name = g_file_get_path (bookmark->details->location);
if (path_name == NULL) {
return FALSE;
}

View file

@ -27,8 +27,8 @@
#include <gtk/gtkenums.h>
#include <gtk/gtkwidget.h>
#include <libnautilus-private/nautilus-icon-factory.h>
#include <gio/gfile.h>
#include <gio/gicon.h>
typedef struct NautilusBookmark NautilusBookmark;
#define NAUTILUS_TYPE_BOOKMARK \
@ -68,16 +68,17 @@ struct NautilusBookmarkClass {
typedef struct NautilusBookmarkClass NautilusBookmarkClass;
GType nautilus_bookmark_get_type (void);
NautilusBookmark * nautilus_bookmark_new (const char *uri,
NautilusBookmark * nautilus_bookmark_new (GFile *location,
const char *name);
NautilusBookmark * nautilus_bookmark_new_with_icon (const char *uri,
NautilusBookmark * nautilus_bookmark_new_with_icon (GFile *location,
const char *name,
gboolean has_custom_name,
const char *icon);
GIcon *icon);
NautilusBookmark * nautilus_bookmark_copy (NautilusBookmark *bookmark);
char * nautilus_bookmark_get_name (NautilusBookmark *bookmark);
GFile * nautilus_bookmark_get_location (NautilusBookmark *bookmark);
char * nautilus_bookmark_get_uri (NautilusBookmark *bookmark);
char * nautilus_bookmark_get_icon (NautilusBookmark *bookmark);
GIcon * nautilus_bookmark_get_icon (NautilusBookmark *bookmark);
gboolean nautilus_bookmark_get_has_custom_name (NautilusBookmark *bookmark);
gboolean nautilus_bookmark_set_name (NautilusBookmark *bookmark,
const char *new_name);

View file

@ -26,8 +26,6 @@
#include "nautilus-column-chooser.h"
#include <string.h>
#include <eel/eel-glib-extensions.h>
#include <eel/eel-gtk-macros.h>
#include <gtk/gtkalignment.h>
#include <gtk/gtkbutton.h>
#include <gtk/gtkcellrenderertext.h>
@ -71,19 +69,12 @@ enum {
};
static guint signals[LAST_SIGNAL];
static void nautilus_column_chooser_class_init (NautilusColumnChooserClass *chooser_class);
static void nautilus_column_chooser_init (NautilusColumnChooser *chooser);
static void nautilus_column_chooser_destroy (GtkObject *object);
static void nautilus_column_chooser_finalize (GObject *object);
EEL_CLASS_BOILERPLATE (NautilusColumnChooser, nautilus_column_chooser, GTK_TYPE_HBOX);
G_DEFINE_TYPE(NautilusColumnChooser, nautilus_column_chooser, GTK_TYPE_HBOX);
static void
nautilus_column_chooser_class_init (NautilusColumnChooserClass *chooser_class)
{
G_OBJECT_CLASS (chooser_class)->finalize = nautilus_column_chooser_finalize;
GTK_OBJECT_CLASS (chooser_class)->destroy = nautilus_column_chooser_destroy;
signals[CHANGED] = g_signal_new
("changed",
G_TYPE_FROM_CLASS (chooser_class),
@ -498,24 +489,20 @@ nautilus_column_chooser_init (NautilusColumnChooser *chooser)
G_CALLBACK (row_deleted_callback), chooser);
}
static void
nautilus_column_chooser_destroy (GtkObject *object)
{
NautilusColumnChooser *chooser;
chooser = NAUTILUS_COLUMN_CHOOSER (object);
}
static void
nautilus_column_chooser_finalize (GObject *object)
{
}
static void
set_visible_columns (NautilusColumnChooser *chooser,
GList *visible_columns)
char **visible_columns)
{
GHashTable *visible_columns_hash;
GtkTreeIter iter;
int i;
visible_columns_hash = g_hash_table_new (g_str_hash, g_str_equal);
for (i = 0; visible_columns[i] != NULL; ++i) {
g_hash_table_insert (visible_columns_hash,
visible_columns[i],
visible_columns[i]);
}
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (chooser->details->store),
&iter)) {
@ -528,7 +515,7 @@ set_visible_columns (NautilusColumnChooser *chooser,
COLUMN_NAME, &name,
-1);
visible = (eel_g_str_list_index (visible_columns, name) != -1);
visible = (g_hash_table_lookup (visible_columns_hash, name) != NULL);
gtk_list_store_set (chooser->details->store,
&iter,
@ -537,17 +524,18 @@ set_visible_columns (NautilusColumnChooser *chooser,
g_free (name);
} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (chooser->details->store), &iter));
}
}
g_hash_table_destroy (visible_columns_hash);
}
static GList *
static char **
get_column_names (NautilusColumnChooser *chooser, gboolean only_visible)
{
GList *ret;
GPtrArray *ret;
GtkTreeIter iter;
ret = NULL;
ret = g_ptr_array_new ();
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (chooser->details->store),
&iter)) {
do {
@ -559,14 +547,15 @@ get_column_names (NautilusColumnChooser *chooser, gboolean only_visible)
COLUMN_NAME, &name,
-1);
if (!only_visible || visible) {
/* give ownership to the list */
ret = g_list_prepend (ret, name);
/* give ownership to the array */
g_ptr_array_add (ret, name);
}
} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (chooser->details->store), &iter));
}
g_ptr_array_add (ret, NULL);
return g_list_reverse (ret);
return (char **) g_ptr_array_free (ret, FALSE);
}
static gboolean
@ -603,7 +592,7 @@ get_column_iter (NautilusColumnChooser *chooser,
static void
set_column_order (NautilusColumnChooser *chooser,
GList *column_order)
char **column_order)
{
GList *columns;
@ -646,8 +635,8 @@ set_column_order (NautilusColumnChooser *chooser,
void
nautilus_column_chooser_set_settings (NautilusColumnChooser *chooser,
GList *visible_columns,
GList *column_order)
char **visible_columns,
char **column_order)
{
g_return_if_fail (NAUTILUS_IS_COLUMN_CHOOSER (chooser));
g_return_if_fail (visible_columns != NULL);
@ -661,13 +650,13 @@ nautilus_column_chooser_set_settings (NautilusColumnChooser *chooser,
void
nautilus_column_chooser_get_settings (NautilusColumnChooser *chooser,
GList **visible_columns,
GList **column_order)
char ***visible_columns,
char ***column_order)
{
g_return_if_fail (NAUTILUS_IS_COLUMN_CHOOSER (chooser));
g_return_if_fail (visible_columns != NULL);
g_return_if_fail (column_order != NULL);
*visible_columns = get_column_names (chooser, TRUE);
*column_order = get_column_names (chooser, FALSE);
}
@ -678,5 +667,3 @@ nautilus_column_chooser_new (void)
return g_object_new (NAUTILUS_TYPE_COLUMN_CHOOSER, NULL);
}

View file

@ -50,12 +50,11 @@ typedef struct {
GType nautilus_column_chooser_get_type (void);
GtkWidget *nautilus_column_chooser_new (void);
void nautilus_column_chooser_set_settings (NautilusColumnChooser *chooser,
GList *visible_columns,
GList *column_order);
void nautilus_column_chooser_set_settings (NautilusColumnChooser *chooser,
char **visible_columns,
char **column_order);
void nautilus_column_chooser_get_settings (NautilusColumnChooser *chooser,
GList **visible_columns,
GList **column_order);
char ***visible_columns,
char ***column_order);
#endif /* NAUTILUS_COLUMN_CHOOSER_H */

View file

@ -190,18 +190,31 @@ nautilus_column_list_free (GList *columns)
}
static int
column_compare (NautilusColumn *a, NautilusColumn *b, GList *column_order)
strv_index (char **strv, const char *str)
{
int i;
for (i = 0; strv[i] != NULL; ++i) {
if (strcmp (strv[i], str) == 0)
return i;
}
return -1;
}
static int
column_compare (NautilusColumn *a, NautilusColumn *b, char **column_order)
{
int index_a;
int index_b;
char *name;
g_object_get (G_OBJECT (a), "name", &name, NULL);
index_a = eel_g_str_list_index (column_order, name);
index_a = strv_index (column_order, name);
g_free (name);
g_object_get (G_OBJECT (b), "name", &name, NULL);
index_b = eel_g_str_list_index (column_order, name);
index_b = strv_index (column_order, name);
g_free (name);
if (index_a == index_b) {
@ -226,8 +239,8 @@ column_compare (NautilusColumn *a, NautilusColumn *b, GList *column_order)
}
GList *
nautilus_sort_columns (GList *columns,
GList *column_order)
nautilus_sort_columns (GList *columns,
char **column_order)
{
return g_list_sort_with_data (columns,
(GCompareDataFunc)column_compare,

View file

@ -32,7 +32,7 @@ GList *nautilus_column_list_copy (GList *columns);
void nautilus_column_list_free (GList *columns);
GList *nautilus_sort_columns (GList *columns,
GList *column_order);
char **column_order);
#endif /* NAUTILUS_COLUMN_UTILITIES_H */

View file

@ -43,8 +43,6 @@
#include <librsvg/rsvg.h>
#include <glib/gi18n.h>
#include <libgnome/gnome-util.h>
#include <libgnomevfs/gnome-vfs-directory.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <libxml/parser.h>
#include <stdlib.h>
#include <string.h>
@ -74,14 +72,48 @@ struct NautilusCustomizationData {
/* The Property here should be one of "emblems", "colors" or "patterns" */
static char * get_global_customization_uri (const char *customization_name);
static char * get_private_customization_uri (const char *customization_name);
static char * get_global_customization_path (const char *customization_name);
static char * get_private_customization_path (const char *customization_name);
static char * get_file_path_for_mode (const NautilusCustomizationData *data,
const char *file_name);
static char* format_name_for_display (NautilusCustomizationData *data, const char *name);
static char* strip_extension (const char* string_to_strip);
static void load_name_map_hash_table (NautilusCustomizationData *data);
static gboolean
read_all_children (char *filename,
const char *attributes,
GList **list_out)
{
GFileEnumerator *enumerator;
GList *list;
GFile *file;
GFileInfo *info;
file = g_file_new_for_path (filename);
enumerator = g_file_enumerate_children (file, attributes, 0, NULL, NULL);
if (enumerator == NULL) {
return FALSE;
}
list = NULL;
do {
info = g_file_enumerator_next_file (enumerator, NULL, NULL);
if (info) {
list = g_list_prepend (list, info);
}
} while (info != NULL);
g_object_unref (enumerator);
g_object_unref (file);
*list_out = g_list_reverse (list);
return TRUE;
}
NautilusCustomizationData*
nautilus_customization_data_new (const char *customization_name,
gboolean show_public_customizations,
@ -89,42 +121,40 @@ nautilus_customization_data_new (const char *customization_name,
int maximum_icon_width)
{
NautilusCustomizationData *data;
char *public_directory_uri, *private_directory_uri;
char *public_directory_path, *private_directory_path;
char *temp_str;
GnomeVFSResult public_result, private_result;
gboolean public_result, private_result;
data = g_new0 (NautilusCustomizationData, 1);
public_result = GNOME_VFS_OK;
public_result = TRUE;
if (show_public_customizations) {
public_directory_uri = get_global_customization_uri (customization_name);
public_directory_path = get_global_customization_path (customization_name);
public_result = gnome_vfs_directory_list_load (&data->public_file_list,
public_directory_uri,
GNOME_VFS_FILE_INFO_GET_MIME_TYPE
| GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
g_free (public_directory_uri);
public_result = read_all_children (public_directory_path,
G_FILE_ATTRIBUTE_STD_NAME ","
G_FILE_ATTRIBUTE_STD_CONTENT_TYPE,
&data->public_file_list);
g_free (public_directory_path);
}
private_directory_uri = get_private_customization_uri (customization_name);
private_result = gnome_vfs_directory_list_load (&data->private_file_list,
private_directory_uri,
GNOME_VFS_FILE_INFO_GET_MIME_TYPE
| GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
g_free (private_directory_uri);
if (public_result != GNOME_VFS_OK &&
private_result != GNOME_VFS_OK) {
private_directory_path = get_private_customization_path (customization_name);
private_result = read_all_children (private_directory_path,
G_FILE_ATTRIBUTE_STD_NAME ","
G_FILE_ATTRIBUTE_STD_CONTENT_TYPE,
&data->private_file_list);
g_free (private_directory_path);
if (!public_result && !private_result) {
g_warning ("Couldn't read any of the emblem directories\n");
g_free (data);
return NULL;
}
if (private_result == GNOME_VFS_OK) {
if (private_result) {
data->reading_mode = READ_PRIVATE_CUSTOMIZATIONS;
data->current_file_list = data->private_file_list;
}
if (show_public_customizations && public_result == GNOME_VFS_OK) {
if (show_public_customizations && public_result) {
data->reading_mode = READ_PUBLIC_CUSTOMIZATIONS;
data->current_file_list = data->public_file_list;
}
@ -151,27 +181,27 @@ nautilus_customization_data_new (const char *customization_name,
return data;
}
GnomeVFSResult
gboolean
nautilus_customization_data_get_next_element_for_display (NautilusCustomizationData *data,
char **emblem_name,
GdkPixbuf **pixbuf_out,
char **label_out)
{
GnomeVFSFileInfo *current_file_info;
GFileInfo *current_file_info;
char *image_file_name;
GdkPixbuf *pixbuf;
GdkPixbuf *orig_pixbuf;
gboolean is_reset_image;
g_return_val_if_fail (data != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
g_return_val_if_fail (emblem_name != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
g_return_val_if_fail (pixbuf_out != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
g_return_val_if_fail (label_out != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
g_return_val_if_fail (data != NULL, FALSE);
g_return_val_if_fail (emblem_name != NULL, FALSE);
g_return_val_if_fail (pixbuf_out != NULL, FALSE);
g_return_val_if_fail (label_out != NULL, FALSE);
if (data->current_file_list == NULL) {
if (data->reading_mode == READ_PUBLIC_CUSTOMIZATIONS) {
if (data->private_file_list == NULL) {
return GNOME_VFS_ERROR_EOF;
return FALSE;
}
data->reading_mode = READ_PRIVATE_CUSTOMIZATIONS;
data->current_file_list = data->private_file_list;
@ -181,7 +211,7 @@ nautilus_customization_data_get_next_element_for_display (NautilusCustomizationD
label_out);
}
else {
return GNOME_VFS_ERROR_EOF;
return FALSE;
}
}
@ -191,8 +221,8 @@ nautilus_customization_data_get_next_element_for_display (NautilusCustomizationD
g_assert (current_file_info != NULL);
if (!eel_istr_has_prefix (current_file_info->mime_type, "image/")
|| eel_istr_has_prefix (current_file_info->name, ".")) {
if (!eel_istr_has_prefix (g_file_info_get_content_type (current_file_info), "image/")
|| eel_istr_has_prefix (g_file_info_get_name (current_file_info), ".")) {
return nautilus_customization_data_get_next_element_for_display (data,
emblem_name,
pixbuf_out,
@ -200,7 +230,7 @@ nautilus_customization_data_get_next_element_for_display (NautilusCustomizationD
}
image_file_name = get_file_path_for_mode (data,
current_file_info->name);
g_file_info_get_name (current_file_info));
orig_pixbuf = gdk_pixbuf_new_from_file (image_file_name, NULL);
if (orig_pixbuf == NULL) {
@ -218,9 +248,9 @@ nautilus_customization_data_get_next_element_for_display (NautilusCustomizationD
label_out);
}
is_reset_image = eel_strcmp(current_file_info->name, RESET_IMAGE_NAME) == 0;
is_reset_image = eel_strcmp(g_file_info_get_name (current_file_info), RESET_IMAGE_NAME) == 0;
*emblem_name = g_strdup (current_file_info->name);
*emblem_name = g_strdup (g_file_info_get_name (current_file_info));
if (strcmp (data->customization_name, "patterns") == 0 &&
data->pattern_frame != NULL) {
@ -235,12 +265,12 @@ nautilus_customization_data_get_next_element_for_display (NautilusCustomizationD
*pixbuf_out = pixbuf;
*label_out = format_name_for_display (data, current_file_info->name);
*label_out = format_name_for_display (data, g_file_info_get_name (current_file_info));
if (data->reading_mode == READ_PRIVATE_CUSTOMIZATIONS) {
data->private_data_was_displayed = TRUE;
}
return GNOME_VFS_OK;
return TRUE;
}
gboolean
@ -259,8 +289,8 @@ nautilus_customization_data_destroy (NautilusCustomizationData *data)
g_object_unref (data->pattern_frame);
}
gnome_vfs_file_info_list_free (data->public_file_list);
gnome_vfs_file_info_list_free (data->private_file_list);
eel_g_object_list_free (data->public_file_list);
eel_g_object_list_free (data->private_file_list);
if (data->name_map_hash != NULL) {
g_hash_table_destroy (data->name_map_hash);
@ -279,19 +309,11 @@ nautilus_customization_data_destroy (NautilusCustomizationData *data)
Return value: The directory name where the customization's
public pixmaps are stored */
static char *
get_global_customization_uri (const char *customization_name)
get_global_customization_path (const char *customization_name)
{
char *directory_path, *directory_uri;
directory_path = g_build_filename (NAUTILUS_DATADIR,
customization_name,
NULL);
directory_uri = gnome_vfs_get_uri_from_local_path (directory_path);
g_free (directory_path);
return directory_uri;
return g_build_filename (NAUTILUS_DATADIR,
customization_name,
NULL);
}
@ -303,20 +325,18 @@ get_global_customization_uri (const char *customization_name)
Return value: The directory name where the customization's
user-specific pixmaps are stored */
static char *
get_private_customization_uri (const char *customization_name)
get_private_customization_path (const char *customization_name)
{
char *user_directory;
char *directory_path, *directory_uri;
char *directory_path;
user_directory = nautilus_get_user_directory ();
directory_path = g_build_filename (user_directory,
customization_name,
NULL);
g_free (user_directory);
directory_uri = gnome_vfs_get_uri_from_local_path (directory_path);
g_free (directory_path);
return directory_uri;
return directory_path;
}
@ -324,20 +344,18 @@ static char *
get_file_path_for_mode (const NautilusCustomizationData *data,
const char *file_name)
{
char *directory_uri, *uri, *directory_name;
char *directory_path, *file;
if (data->reading_mode == READ_PUBLIC_CUSTOMIZATIONS) {
directory_uri = get_global_customization_uri (data->customization_name);
directory_path = get_global_customization_path (data->customization_name);
}
else {
directory_uri = get_private_customization_uri (data->customization_name);
directory_path = get_private_customization_path (data->customization_name);
}
uri = g_build_filename (directory_uri, file_name, NULL);
g_free (directory_uri);
directory_name = gnome_vfs_get_local_path_from_uri (uri);
g_free (uri);
file = g_build_filename (directory_path, file_name, NULL);
g_free (directory_path);
return directory_name;
return file;
}

View file

@ -32,7 +32,6 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gtk/gtklabel.h>
#include <libgnomevfs/gnome-vfs-types.h>
#define RESET_IMAGE_NAME "reset.png"
@ -51,7 +50,7 @@ NautilusCustomizationData* nautilus_customization_data_new
* object_pixbuf - Pixbuf for graphical display of the object.
* object_label - Textual label display of the object.
*/
GnomeVFSResult nautilus_customization_data_get_next_element_for_display (NautilusCustomizationData *data,
gboolean nautilus_customization_data_get_next_element_for_display (NautilusCustomizationData *data,
char **object_name,
GdkPixbuf **object_pixbuf,
char **object_label);

View file

@ -69,7 +69,7 @@ typedef struct {
static void nautilus_desktop_directory_file_init (gpointer object,
gpointer klass);
gpointer klass);
static void nautilus_desktop_directory_file_class_init (gpointer klass);
EEL_CLASS_BOILERPLATE (NautilusDesktopDirectoryFile,
@ -370,12 +370,6 @@ desktop_directory_file_check_if_ready (NautilusFile *file,
delegated_attributes);
}
static GnomeVFSFileType
desktop_directory_file_get_file_type (NautilusFile *file)
{
return GNOME_VFS_FILE_TYPE_DIRECTORY;
}
static gboolean
desktop_directory_file_get_item_count (NautilusFile *file,
guint *count,
@ -402,7 +396,7 @@ desktop_directory_file_get_deep_counts (NautilusFile *file,
guint *directory_count,
guint *file_count,
guint *unreadable_directory_count,
GnomeVFSFileSize *total_size)
goffset *total_size)
{
NautilusDesktopDirectoryFile *desktop_file;
NautilusRequestStatus status;
@ -464,7 +458,7 @@ nautilus_desktop_directory_file_init (gpointer object, gpointer klass)
desktop_file = NAUTILUS_DESKTOP_DIRECTORY_FILE (object);
desktop_directory = NAUTILUS_DESKTOP_DIRECTORY (nautilus_directory_get (EEL_DESKTOP_URI));
desktop_directory = NAUTILUS_DESKTOP_DIRECTORY (nautilus_directory_get_by_uri (EEL_DESKTOP_URI));
desktop_file->details = g_new0 (NautilusDesktopDirectoryFileDetails, 1);
desktop_file->details->desktop_directory = desktop_directory;
@ -473,7 +467,7 @@ nautilus_desktop_directory_file_init (gpointer object, gpointer klass)
(desktop_callback_hash, desktop_callback_equal);
desktop_file->details->monitors = g_hash_table_new_full (NULL, NULL,
NULL, monitor_destroy);
real_dir = nautilus_desktop_directory_get_real_directory (desktop_directory);
real_dir_file = nautilus_directory_get_corresponding_file (real_dir);
nautilus_directory_unref (real_dir);
@ -537,12 +531,13 @@ nautilus_desktop_directory_file_class_init (gpointer klass)
object_class->finalize = desktop_finalize;
file_class->default_file_type = G_FILE_TYPE_DIRECTORY;
file_class->monitor_add = desktop_directory_file_monitor_add;
file_class->monitor_remove = desktop_directory_file_monitor_remove;
file_class->call_when_ready = desktop_directory_file_call_when_ready;
file_class->cancel_call_when_ready = desktop_directory_file_cancel_call_when_ready;
file_class->check_if_ready = desktop_directory_file_check_if_ready;
file_class->get_file_type = desktop_directory_file_get_file_type;
file_class->get_item_count = desktop_directory_file_get_item_count;
file_class->get_deep_counts = desktop_directory_file_get_deep_counts;
file_class->get_date = desktop_directory_file_get_date;

View file

@ -33,7 +33,6 @@
#include "nautilus-file-utilities.h"
#include "nautilus-global-preferences.h"
#include <eel/eel-glib-extensions.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <gtk/gtkmain.h>
#include <gtk/gtksignal.h>
#include <libgnome/gnome-macros.h>
@ -479,8 +478,8 @@ update_desktop_directory (NautilusDesktopDirectory *desktop)
}
desktop_path = nautilus_get_desktop_directory ();
desktop_uri = gnome_vfs_get_uri_from_local_path (desktop_path);
real_directory = nautilus_directory_get (desktop_uri);
desktop_uri = g_filename_to_uri (desktop_path, NULL, NULL);
real_directory = nautilus_directory_get_by_uri (desktop_uri);
g_free (desktop_uri);
g_free (desktop_path);

View file

@ -32,24 +32,16 @@
#include "nautilus-file-private.h"
#include "nautilus-file-utilities.h"
#include <eel/eel-glib-extensions.h>
#include <eel/eel-gtk-macros.h>
#include "nautilus-desktop-directory.h"
#include <gtk/gtksignal.h>
#include <glib/gi18n.h>
#include <libgnomevfs/gnome-vfs.h>
#include <string.h>
struct NautilusDesktopIconFileDetails {
NautilusDesktopLink *link;
};
static void nautilus_desktop_icon_file_init (gpointer object,
gpointer klass);
static void nautilus_desktop_icon_file_class_init (gpointer klass);
G_DEFINE_TYPE(NautilusDesktopIconFile, nautilus_desktop_icon_file, NAUTILUS_TYPE_FILE)
EEL_CLASS_BOILERPLATE (NautilusDesktopIconFile,
nautilus_desktop_icon_file,
NAUTILUS_TYPE_FILE)
static void
desktop_icon_file_monitor_add (NautilusFile *file,
@ -69,13 +61,11 @@ desktop_icon_file_monitor_remove (NautilusFile *file,
(file->details->directory, file, client);
}
static void
desktop_icon_file_call_when_ready (NautilusFile *file,
NautilusFileAttributes attributes,
NautilusFileCallback callback,
gpointer callback_data)
{
nautilus_directory_call_when_ready_internal
(file->details->directory, file,
@ -101,12 +91,6 @@ desktop_icon_file_check_if_ready (NautilusFile *file,
attributes);
}
static GnomeVFSFileType
desktop_icon_file_get_file_type (NautilusFile *file)
{
return GNOME_VFS_FILE_TYPE_REGULAR;
}
static gboolean
desktop_icon_file_get_item_count (NautilusFile *file,
guint *count,
@ -126,7 +110,7 @@ desktop_icon_file_get_deep_counts (NautilusFile *file,
guint *directory_count,
guint *file_count,
guint *unreadable_directory_count,
GnomeVFSFileSize *total_size)
goffset *total_size)
{
if (directory_count != NULL) {
*directory_count = 0;
@ -164,22 +148,20 @@ desktop_icon_file_get_where_string (NautilusFile *file)
}
static void
nautilus_desktop_icon_file_init (gpointer object, gpointer klass)
nautilus_desktop_icon_file_init (NautilusDesktopIconFile *desktop_file)
{
NautilusDesktopIconFile *desktop_file;
desktop_file = NAUTILUS_DESKTOP_ICON_FILE (object);
desktop_file->details = g_new0 (NautilusDesktopIconFileDetails, 1);
}
desktop_file->details = G_TYPE_INSTANCE_GET_PRIVATE (desktop_file,
NAUTILUS_TYPE_DESKTOP_ICON_FILE,
NautilusDesktopIconFileDetails);
}
static void
update_info_from_link (NautilusDesktopIconFile *icon_file)
{
NautilusFile *file;
GnomeVFSFileInfo *file_info;
NautilusDesktopLink *link;
GnomeVFSVolume *volume;
char *display_name;
GVolume *volume;
file = NAUTILUS_FILE (icon_file);
@ -188,46 +170,40 @@ update_info_from_link (NautilusDesktopIconFile *icon_file)
if (link == NULL) {
return;
}
file_info = file->details->info;
gnome_vfs_file_info_clear (file_info);
file_info->name = nautilus_desktop_link_get_file_name (link);
file_info->mime_type = g_strdup ("application/x-nautilus-link");
file_info->type = GNOME_VFS_FILE_TYPE_REGULAR;
file_info->flags = GNOME_VFS_FILE_FLAGS_NONE;
file_info->link_count = 1;
file_info->size = 0;
file_info->permissions =
GNOME_VFS_PERM_OTHER_WRITE |
GNOME_VFS_PERM_GROUP_WRITE |
GNOME_VFS_PERM_USER_READ |
GNOME_VFS_PERM_OTHER_READ |
GNOME_VFS_PERM_GROUP_READ |
GNOME_VFS_PERM_ACCESS_READABLE |
GNOME_VFS_PERM_ACCESS_WRITABLE;
file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
GNOME_VFS_FILE_INFO_FIELDS_FLAGS |
GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE |
GNOME_VFS_FILE_INFO_FIELDS_SIZE |
GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS |
GNOME_VFS_FILE_INFO_FIELDS_ACCESS |
GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT;
eel_ref_str_unref (file->details->mime_type);
file->details->mime_type = eel_ref_str_get_unique ("application/x-nautilus-link");
file->details->type = G_FILE_TYPE_REGULAR;
file->details->size = 0;
file->details->has_permissions = FALSE;
file->details->can_read = TRUE;
file->details->can_write = TRUE;
file->details->can_mount = FALSE;
file->details->can_unmount = FALSE;
file->details->can_eject = FALSE;
volume = nautilus_desktop_link_get_volume (link);
nautilus_file_set_volume (file, volume);
gnome_vfs_volume_unref (volume);
if (volume) {
file->details->can_unmount = g_volume_can_unmount (volume);
file->details->can_eject = g_volume_can_eject (volume);
g_object_unref (volume);
}
file->details->file_info_is_up_to_date = TRUE;
g_free (file->details->display_name);
file->details->display_name = nautilus_desktop_link_get_display_name (link);
g_free (file->details->custom_icon);
file->details->custom_icon = nautilus_desktop_link_get_icon (link);
g_free (file->details->activation_uri);
file->details->activation_uri = nautilus_desktop_link_get_activation_uri (link);
display_name = nautilus_desktop_link_get_display_name (link);
nautilus_file_set_display_name (file,
display_name, NULL, TRUE);
g_free (display_name);
if (file->details->icon != NULL) {
g_object_unref (file->details->icon);
}
file->details->icon = nautilus_desktop_link_get_icon (link);
if (file->details->activation_location) {
g_object_unref (file->details->activation_location);
}
file->details->activation_location = nautilus_desktop_link_get_activation_location (link);
file->details->got_link_info = TRUE;
file->details->link_info_is_up_to_date = TRUE;
@ -243,7 +219,6 @@ nautilus_desktop_icon_file_update (NautilusDesktopIconFile *icon_file)
update_info_from_link (icon_file);
file = NAUTILUS_FILE (icon_file);
nautilus_file_clear_cached_display_name (file);
nautilus_file_changed (file);
}
@ -275,17 +250,16 @@ nautilus_desktop_icon_file_remove (NautilusDesktopIconFile *icon_file)
nautilus_file_unref (file);
}
NautilusDesktopIconFile *
nautilus_desktop_icon_file_new (NautilusDesktopLink *link)
{
NautilusFile *file;
NautilusDirectory *directory;
NautilusDesktopIconFile *icon_file;
char *name;
GList list;
directory = nautilus_directory_get (EEL_DESKTOP_URI);
char *name;
directory = nautilus_directory_get_by_uri (EEL_DESKTOP_URI);
file = NAUTILUS_FILE (g_object_new (NAUTILUS_TYPE_DESKTOP_ICON_FILE, NULL));
@ -299,13 +273,12 @@ nautilus_desktop_icon_file_new (NautilusDesktopLink *link)
icon_file = NAUTILUS_DESKTOP_ICON_FILE (file);
icon_file->details->link = link;
file->details->info = gnome_vfs_file_info_new ();
name = nautilus_desktop_link_get_file_name (link);
file->details->relative_uri = gnome_vfs_escape_string (name);
file->details->name = eel_ref_str_new (name);
g_free (name);
update_info_from_link (icon_file);
nautilus_directory_add_file (directory, file);
list.data = file;
@ -316,7 +289,6 @@ nautilus_desktop_icon_file_new (NautilusDesktopLink *link)
return icon_file;
}
/* Note: This can return NULL if the link was recently removed (i.e. unmounted) */
NautilusDesktopLink *
nautilus_desktop_icon_file_get_link (NautilusDesktopIconFile *icon_file)
@ -328,36 +300,25 @@ nautilus_desktop_icon_file_get_link (NautilusDesktopIconFile *icon_file)
}
static void
desktop_icon_file_finalize (GObject *object)
{
NautilusDesktopIconFile *desktop_file;
desktop_file = NAUTILUS_DESKTOP_ICON_FILE (object);
g_free (desktop_file->details);
EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
}
static void
nautilus_desktop_icon_file_class_init (gpointer klass)
nautilus_desktop_icon_file_class_init (NautilusDesktopIconFileClass *klass)
{
GObjectClass *object_class;
NautilusFileClass *file_class;
object_class = G_OBJECT_CLASS (klass);
file_class = NAUTILUS_FILE_CLASS (klass);
object_class->finalize = desktop_icon_file_finalize;
file_class->default_file_type = G_FILE_TYPE_DIRECTORY;
file_class->monitor_add = desktop_icon_file_monitor_add;
file_class->monitor_remove = desktop_icon_file_monitor_remove;
file_class->call_when_ready = desktop_icon_file_call_when_ready;
file_class->cancel_call_when_ready = desktop_icon_file_cancel_call_when_ready;
file_class->check_if_ready = desktop_icon_file_check_if_ready;
file_class->get_file_type = desktop_icon_file_get_file_type;
file_class->get_item_count = desktop_icon_file_get_item_count;
file_class->get_deep_counts = desktop_icon_file_get_deep_counts;
file_class->get_date = desktop_icon_file_get_date;
file_class->get_where_string = desktop_icon_file_get_where_string;
g_type_class_add_private (object_class, sizeof(NautilusDesktopIconFileDetails));
}

View file

@ -39,12 +39,12 @@
#include <gtk/gtksignal.h>
#include <gtk/gtkstock.h>
#include <glib/gi18n.h>
#include <libgnomevfs/gnome-vfs.h>
#include <libgnomevfs/gnome-vfs-volume-monitor.h>
#include <gio/gvolumemonitor.h>
#include <libnautilus-private/nautilus-trash-monitor.h>
#include <string.h>
struct NautilusDesktopLinkMonitorDetails {
GVolumeMonitor *volume_monitor;
NautilusDirectory *desktop_dir;
NautilusDesktopLink *home_link;
@ -87,24 +87,11 @@ nautilus_desktop_link_monitor_get (void)
return the_link_monitor;
}
static gboolean
eject_for_type (GnomeVFSDeviceType type)
{
switch (type) {
case GNOME_VFS_DEVICE_TYPE_CDROM:
case GNOME_VFS_DEVICE_TYPE_ZIP:
case GNOME_VFS_DEVICE_TYPE_JAZ:
return TRUE;
default:
return FALSE;
}
}
static void
volume_delete_dialog (GtkWidget *parent_view,
NautilusDesktopLink *link)
{
GnomeVFSVolume *volume;
GVolume *volume;
char *dialog_str;
char *display_name;
@ -116,7 +103,7 @@ volume_delete_dialog (GtkWidget *parent_view,
display_name);
g_free (display_name);
if (eject_for_type (gnome_vfs_volume_get_device_type (volume))) {
if (g_volume_can_eject (volume)) {
eel_run_simple_dialog
(parent_view,
FALSE,
@ -136,7 +123,7 @@ volume_delete_dialog (GtkWidget *parent_view,
GTK_STOCK_OK, NULL);
}
gnome_vfs_volume_unref (volume);
g_object_unref (volume);
g_free (dialog_str);
}
}
@ -198,16 +185,12 @@ nautilus_desktop_link_monitor_make_filename_unique (NautilusDesktopLinkMonitor *
static void
create_volume_link (NautilusDesktopLinkMonitor *monitor,
GnomeVFSVolume *volume)
GVolume *volume)
{
NautilusDesktopLink *link;
link = NULL;
if (!gnome_vfs_volume_is_user_visible (volume)) {
return;
}
if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE)) {
link = nautilus_desktop_link_new_from_volume (volume);
monitor->details->volume_links = g_list_prepend (monitor->details->volume_links, link);
@ -217,8 +200,8 @@ create_volume_link (NautilusDesktopLinkMonitor *monitor,
static void
volume_mounted_callback (GnomeVFSVolumeMonitor *volume_monitor,
GnomeVFSVolume *volume,
volume_mounted_callback (GVolumeMonitor *volume_monitor,
GVolume *volume,
NautilusDesktopLinkMonitor *monitor)
{
create_volume_link (monitor, volume);
@ -226,23 +209,23 @@ volume_mounted_callback (GnomeVFSVolumeMonitor *volume_monitor,
static void
volume_unmounted_callback (GnomeVFSVolumeMonitor *volume_monitor,
GnomeVFSVolume *volume,
volume_unmounted_callback (GVolumeMonitor *volume_monitor,
GVolume *volume,
NautilusDesktopLinkMonitor *monitor)
{
GList *l;
NautilusDesktopLink *link;
GnomeVFSVolume *other_volume;
GVolume *other_volume;
link = NULL;
for (l = monitor->details->volume_links; l != NULL; l = l->next) {
other_volume = nautilus_desktop_link_get_volume (l->data);
if (volume == other_volume) {
gnome_vfs_volume_unref (other_volume);
g_object_unref (other_volume);
link = l->data;
break;
}
gnome_vfs_volume_unref (other_volume);
g_object_unref (other_volume);
}
if (link) {
@ -324,19 +307,17 @@ desktop_network_visible_changed (gpointer callback_data)
static void
desktop_volumes_visible_changed (gpointer callback_data)
{
GnomeVFSVolumeMonitor *volume_monitor;
NautilusDesktopLinkMonitor *monitor;
GList *l, *volumes;
volume_monitor = gnome_vfs_get_volume_monitor ();
monitor = NAUTILUS_DESKTOP_LINK_MONITOR (callback_data);
if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE)) {
if (monitor->details->volume_links == NULL) {
volumes = gnome_vfs_volume_monitor_get_mounted_volumes (volume_monitor);
volumes = g_volume_monitor_get_mounted_volumes (monitor->details->volume_monitor);
for (l = volumes; l != NULL; l = l->next) {
create_volume_link (monitor, l->data);
gnome_vfs_volume_unref (l->data);
g_object_unref (l->data);
}
g_list_free (volumes);
}
@ -366,8 +347,7 @@ nautilus_desktop_link_monitor_init (gpointer object, gpointer klass)
{
NautilusDesktopLinkMonitor *monitor;
GList *l, *volumes;
GnomeVFSVolume *volume;
GnomeVFSVolumeMonitor *volume_monitor;
GVolume *volume;
monitor = NAUTILUS_DESKTOP_LINK_MONITOR (object);
@ -375,8 +355,10 @@ nautilus_desktop_link_monitor_init (gpointer object, gpointer klass)
monitor->details = g_new0 (NautilusDesktopLinkMonitorDetails, 1);
monitor->details->volume_monitor = g_volume_monitor_get ();
/* We keep around a ref to the desktop dir */
monitor->details->desktop_dir = nautilus_directory_get (EEL_DESKTOP_URI);
monitor->details->desktop_dir = nautilus_directory_get_by_uri (EEL_DESKTOP_URI);
/* Default links */
@ -406,13 +388,11 @@ nautilus_desktop_link_monitor_init (gpointer object, gpointer klass)
/* Volume links */
volume_monitor = gnome_vfs_get_volume_monitor ();
volumes = gnome_vfs_volume_monitor_get_mounted_volumes (volume_monitor);
volumes = g_volume_monitor_get_mounted_volumes (monitor->details->volume_monitor);
for (l = volumes; l != NULL; l = l->next) {
volume = l->data;
create_volume_link (monitor, volume);
gnome_vfs_volume_unref (volume);
g_object_unref (volume);
}
g_list_free (volumes);
@ -420,10 +400,12 @@ nautilus_desktop_link_monitor_init (gpointer object, gpointer klass)
desktop_volumes_visible_changed,
monitor);
monitor->details->mount_id = g_signal_connect_object (volume_monitor, "volume_mounted",
G_CALLBACK (volume_mounted_callback), monitor, 0);
monitor->details->unmount_id = g_signal_connect_object (volume_monitor, "volume_unmounted",
G_CALLBACK (volume_unmounted_callback), monitor, 0);
monitor->details->mount_id =
g_signal_connect_object (monitor->details->volume_monitor, "volume_mounted",
G_CALLBACK (volume_mounted_callback), monitor, 0);
monitor->details->unmount_id =
g_signal_connect_object (monitor->details->volume_monitor, "volume_unmounted",
G_CALLBACK (volume_unmounted_callback), monitor, 0);
}
@ -448,6 +430,8 @@ desktop_link_monitor_finalize (GObject *object)
monitor = NAUTILUS_DESKTOP_LINK_MONITOR (object);
g_object_unref (monitor->details->volume_monitor);
/* Default links */
remove_link_and_preference (&monitor->details->home_link,

View file

@ -28,26 +28,21 @@
#include "nautilus-desktop-icon-file.h"
#include "nautilus-directory-private.h"
#include "nautilus-desktop-directory.h"
#include <eel/eel-gtk-macros.h>
#include <eel/eel-vfs-extensions.h>
#include <gtk/gtksignal.h>
#include <glib/gi18n.h>
#include <libgnomevfs/gnome-vfs.h>
#include <gio/gthemedicon.h>
#include <gio/gvolume.h>
#include <gio/gdrive.h>
#include <libnautilus-private/nautilus-file-utilities.h>
#include <libnautilus-private/nautilus-trash-monitor.h>
#include <libnautilus-private/nautilus-global-preferences.h>
#include <string.h>
#define TRASH_EMPTY_ICON "gnome-fs-trash-empty"
#define TRASH_FULL_ICON "gnome-fs-trash-full"
struct NautilusDesktopLinkDetails {
NautilusDesktopLinkType type;
char *filename;
char *display_name;
char *activation_uri;
char *icon;
GFile *activation_location;
GIcon *icon;
NautilusDesktopIconFile *icon_file;
@ -55,20 +50,10 @@ struct NautilusDesktopLinkDetails {
gulong trash_state_handler;
/* Just for volume icons: */
GnomeVFSVolume *volume;
GVolume *volume;
};
static void nautilus_desktop_link_init (gpointer object,
gpointer klass);
static void nautilus_desktop_link_class_init (gpointer klass);
static void trash_state_changed_callback (NautilusTrashMonitor *trash_monitor,
gboolean state,
gpointer callback_data);
static void nautilus_desktop_link_changed (NautilusDesktopLink *link);
EEL_CLASS_BOILERPLATE (NautilusDesktopLink,
nautilus_desktop_link,
G_TYPE_OBJECT)
G_DEFINE_TYPE(NautilusDesktopLink, nautilus_desktop_link, G_TYPE_OBJECT)
static void
create_icon_file (NautilusDesktopLink *link)
@ -76,6 +61,32 @@ create_icon_file (NautilusDesktopLink *link)
link->details->icon_file = nautilus_desktop_icon_file_new (link);
}
static void
nautilus_desktop_link_changed (NautilusDesktopLink *link)
{
if (link->details->icon_file != NULL) {
nautilus_desktop_icon_file_update (link->details->icon_file);
}
}
static void
trash_state_changed_callback (NautilusTrashMonitor *trash_monitor,
gboolean state,
gpointer callback_data)
{
NautilusDesktopLink *link;
link = NAUTILUS_DESKTOP_LINK (callback_data);
g_assert (link->details->type == NAUTILUS_DESKTOP_LINK_TRASH);
if (link->details->icon) {
g_object_unref (link->details->icon);
}
link->details->icon = nautilus_trash_monitor_get_icon ();
nautilus_desktop_link_changed (link);
}
static void
home_name_changed (gpointer callback_data)
{
@ -112,7 +123,6 @@ trash_name_changed (gpointer callback_data)
link = NAUTILUS_DESKTOP_LINK (callback_data);
g_assert (link->details->type == NAUTILUS_DESKTOP_LINK_TRASH);
g_free (link->details->display_name);
link->details->display_name = eel_preferences_get (NAUTILUS_PREFERENCES_DESKTOP_TRASH_NAME);
nautilus_desktop_link_changed (link);
@ -126,13 +136,11 @@ network_name_changed (gpointer callback_data)
link = NAUTILUS_DESKTOP_LINK (callback_data);
g_assert (link->details->type == NAUTILUS_DESKTOP_LINK_NETWORK);
g_free (link->details->display_name);
link->details->display_name = eel_preferences_get (NAUTILUS_PREFERENCES_DESKTOP_NETWORK_NAME);
nautilus_desktop_link_changed (link);
}
NautilusDesktopLink *
nautilus_desktop_link_new (NautilusDesktopLinkType type)
{
@ -145,8 +153,8 @@ nautilus_desktop_link_new (NautilusDesktopLinkType type)
case NAUTILUS_DESKTOP_LINK_HOME:
link->details->filename = g_strdup ("home");
link->details->display_name = eel_preferences_get (NAUTILUS_PREFERENCES_DESKTOP_HOME_NAME);
link->details->activation_uri = nautilus_get_home_directory_uri ();
link->details->icon = g_strdup ("gnome-fs-home");
link->details->activation_location = g_file_new_for_path (g_get_home_dir ());
link->details->icon = g_themed_icon_new ("user-home");
eel_preferences_add_callback (NAUTILUS_PREFERENCES_DESKTOP_HOME_NAME,
home_name_changed,
@ -156,12 +164,10 @@ nautilus_desktop_link_new (NautilusDesktopLinkType type)
case NAUTILUS_DESKTOP_LINK_COMPUTER:
link->details->filename = g_strdup ("computer");
link->details->display_name = eel_preferences_get (NAUTILUS_PREFERENCES_DESKTOP_COMPUTER_NAME);
link->details->activation_uri = g_strdup ("computer:///");
link->details->activation_location = g_file_new_for_uri ("computer:///");
/* TODO: This might need a different icon: */
link->details->icon = g_strdup ("gnome-fs-client");
link->details->icon = g_themed_icon_new ("gnome-fs-client");
eel_preferences_add_callback (NAUTILUS_PREFERENCES_DESKTOP_COMPUTER_NAME,
computer_name_changed,
@ -172,12 +178,8 @@ nautilus_desktop_link_new (NautilusDesktopLinkType type)
case NAUTILUS_DESKTOP_LINK_TRASH:
link->details->filename = g_strdup ("trash");
link->details->display_name = eel_preferences_get (NAUTILUS_PREFERENCES_DESKTOP_TRASH_NAME);
link->details->activation_uri = g_strdup (EEL_TRASH_URI);
if (nautilus_trash_monitor_is_empty ()) {
link->details->icon = g_strdup (TRASH_EMPTY_ICON);
} else {
link->details->icon = g_strdup (TRASH_FULL_ICON);
}
link->details->activation_location = g_file_new_for_uri (EEL_TRASH_URI);
link->details->icon = nautilus_trash_monitor_get_icon ();
eel_preferences_add_callback (NAUTILUS_PREFERENCES_DESKTOP_TRASH_NAME,
trash_name_changed,
@ -190,8 +192,8 @@ nautilus_desktop_link_new (NautilusDesktopLinkType type)
case NAUTILUS_DESKTOP_LINK_NETWORK:
link->details->filename = g_strdup ("network");
link->details->display_name = eel_preferences_get (NAUTILUS_PREFERENCES_DESKTOP_NETWORK_NAME);
link->details->activation_uri = g_strdup ("network:///");
link->details->icon = g_strdup ("gnome-fs-network");
link->details->activation_location = g_file_new_for_uri ("network:///");
link->details->icon = g_themed_icon_new ("gnome-fs-network");
eel_preferences_add_callback (NAUTILUS_PREFERENCES_DESKTOP_NETWORK_NAME,
network_name_changed,
@ -209,56 +211,59 @@ nautilus_desktop_link_new (NautilusDesktopLinkType type)
}
NautilusDesktopLink *
nautilus_desktop_link_new_from_volume (GnomeVFSVolume *volume)
nautilus_desktop_link_new_from_volume (GVolume *volume)
{
NautilusDesktopLink *link;
GnomeVFSDrive *drive;
GDrive *drive;
char *name, *filename;
link = NAUTILUS_DESKTOP_LINK (g_object_new (NAUTILUS_TYPE_DESKTOP_LINK, NULL));
link->details->type = NAUTILUS_DESKTOP_LINK_VOLUME;
link->details->volume = gnome_vfs_volume_ref (volume);
link->details->volume = g_object_ref (volume);
/* We try to use the drive name to get somewhat stable filenames
for metadata */
drive = gnome_vfs_volume_get_drive (volume);
drive = g_volume_get_drive (volume);
if (drive != NULL) {
name = gnome_vfs_drive_get_display_name (drive);
name = g_drive_get_name (drive);
g_object_unref (drive);
} else {
name = gnome_vfs_volume_get_display_name (volume);
name = g_volume_get_name (volume);
}
gnome_vfs_drive_unref (drive);
filename = g_strconcat (name, ".volume", NULL);
/* Replace slashes in name */
filename = g_strconcat (g_strdelimit (name, "/", '-'), ".volume", NULL);
link->details->filename =
nautilus_desktop_link_monitor_make_filename_unique (nautilus_desktop_link_monitor_get (),
filename);
g_free (filename);
g_free (name);
link->details->display_name = gnome_vfs_volume_get_display_name (volume);
link->details->display_name = g_volume_get_name (volume);
link->details->activation_location = g_volume_get_root (volume);
link->details->icon = g_volume_get_icon (volume);
link->details->activation_uri = gnome_vfs_volume_get_activation_uri (volume);
link->details->icon = gnome_vfs_volume_get_icon (volume);
create_icon_file (link);
return link;
}
GnomeVFSVolume *
GVolume *
nautilus_desktop_link_get_volume (NautilusDesktopLink *link)
{
return gnome_vfs_volume_ref (link->details->volume);
if (link->details->volume) {
return g_object_ref (link->details->volume);
}
return NULL;
}
NautilusDesktopLinkType
nautilus_desktop_link_get_link_type (NautilusDesktopLink *link)
nautilus_desktop_link_get_link_type (NautilusDesktopLink *link)
{
return link->details->type;
return link->details->type;
}
char *
@ -273,16 +278,22 @@ nautilus_desktop_link_get_display_name (NautilusDesktopLink *link)
return g_strdup (link->details->display_name);
}
char *
GIcon *
nautilus_desktop_link_get_icon (NautilusDesktopLink *link)
{
return g_strdup (link->details->icon);
if (link->details->icon != NULL) {
return g_object_ref (link->details->icon);
}
return NULL;
}
char *
nautilus_desktop_link_get_activation_uri (NautilusDesktopLink *link)
GFile *
nautilus_desktop_link_get_activation_location (NautilusDesktopLink *link)
{
return g_strdup (link->details->activation_uri);
if (link->details->activation_location) {
return g_object_ref (link->details->activation_location);
}
return NULL;
}
gboolean
@ -293,35 +304,6 @@ nautilus_desktop_link_get_date (NautilusDesktopLink *link,
return FALSE;
}
static void
nautilus_desktop_link_changed (NautilusDesktopLink *link)
{
if (link->details->icon_file != NULL) {
nautilus_desktop_icon_file_update (link->details->icon_file);
}
}
static void
trash_state_changed_callback (NautilusTrashMonitor *trash_monitor,
gboolean state,
gpointer callback_data)
{
NautilusDesktopLink *link;
link = NAUTILUS_DESKTOP_LINK (callback_data);
g_assert (link->details->type == NAUTILUS_DESKTOP_LINK_TRASH);
g_free (link->details->icon);
if (state) {
link->details->icon = g_strdup (TRASH_EMPTY_ICON);
} else {
link->details->icon = g_strdup (TRASH_FULL_ICON);
}
nautilus_desktop_link_changed (link);
}
gboolean
nautilus_desktop_link_can_rename (NautilusDesktopLink *link)
{
@ -362,16 +344,13 @@ nautilus_desktop_link_rename (NautilusDesktopLink *link,
return TRUE;
}
static void
nautilus_desktop_link_init (gpointer object, gpointer klass)
nautilus_desktop_link_init (NautilusDesktopLink *link)
{
NautilusDesktopLink *link;
link = NAUTILUS_DESKTOP_LINK (object);
link->details = g_new0 (NautilusDesktopLinkDetails, 1);
}
link->details = G_TYPE_INSTANCE_GET_PRIVATE (link,
NAUTILUS_TYPE_DESKTOP_LINK,
NautilusDesktopLinkDetails);
}
static void
desktop_link_finalize (GObject *object)
@ -416,25 +395,29 @@ desktop_link_finalize (GObject *object)
}
if (link->details->type == NAUTILUS_DESKTOP_LINK_VOLUME) {
gnome_vfs_volume_unref (link->details->volume);
g_object_unref (link->details->volume);
}
g_free (link->details->filename);
g_free (link->details->display_name);
g_free (link->details->activation_uri);
g_free (link->details->icon);
g_free (link->details);
if (link->details->activation_location) {
g_object_unref (link->details->activation_location);
}
if (link->details->icon) {
g_object_unref (link->details->icon);
}
EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
G_OBJECT_CLASS (nautilus_desktop_link_parent_class)->finalize (object);
}
static void
nautilus_desktop_link_class_init (gpointer klass)
nautilus_desktop_link_class_init (NautilusDesktopLinkClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->finalize = desktop_link_finalize;
g_type_class_add_private (object_class, sizeof(NautilusDesktopLinkDetails));
}

View file

@ -26,7 +26,7 @@
#define NAUTILUS_DESKTOP_LINK_H
#include <libnautilus-private/nautilus-file.h>
#include <libgnomevfs/gnome-vfs-volume.h>
#include <gio/gvolume.h>
#define NAUTILUS_TYPE_DESKTOP_LINK \
(nautilus_desktop_link_get_type ())
@ -60,20 +60,20 @@ typedef enum {
GType nautilus_desktop_link_get_type (void);
NautilusDesktopLink * nautilus_desktop_link_new (NautilusDesktopLinkType type);
NautilusDesktopLink * nautilus_desktop_link_new_from_volume (GnomeVFSVolume *volume);
NautilusDesktopLinkType nautilus_desktop_link_get_link_type (NautilusDesktopLink *link);
char * nautilus_desktop_link_get_file_name (NautilusDesktopLink *link);
char * nautilus_desktop_link_get_display_name (NautilusDesktopLink *link);
char * nautilus_desktop_link_get_icon (NautilusDesktopLink *link);
char * nautilus_desktop_link_get_activation_uri (NautilusDesktopLink *link);
gboolean nautilus_desktop_link_get_date (NautilusDesktopLink *link,
NautilusDateType date_type,
time_t *date);
GnomeVFSVolume * nautilus_desktop_link_get_volume (NautilusDesktopLink *link);
NautilusDesktopLink * nautilus_desktop_link_new (NautilusDesktopLinkType type);
NautilusDesktopLink * nautilus_desktop_link_new_from_volume (GVolume *volume);
NautilusDesktopLinkType nautilus_desktop_link_get_link_type (NautilusDesktopLink *link);
char * nautilus_desktop_link_get_file_name (NautilusDesktopLink *link);
char * nautilus_desktop_link_get_display_name (NautilusDesktopLink *link);
GIcon * nautilus_desktop_link_get_icon (NautilusDesktopLink *link);
GFile * nautilus_desktop_link_get_activation_location (NautilusDesktopLink *link);
gboolean nautilus_desktop_link_get_date (NautilusDesktopLink *link,
NautilusDateType date_type,
time_t *date);
GVolume * nautilus_desktop_link_get_volume (NautilusDesktopLink *link);
gboolean nautilus_desktop_link_can_rename (NautilusDesktopLink *link);
gboolean nautilus_desktop_link_rename (NautilusDesktopLink *link,
const char *name);
gboolean nautilus_desktop_link_can_rename (NautilusDesktopLink *link);
gboolean nautilus_desktop_link_rename (NautilusDesktopLink *link,
const char *name);
#endif /* NAUTILUS_DESKTOP_LINK_H */

File diff suppressed because it is too large Load diff

View file

@ -34,12 +34,7 @@
#include "nautilus-global-preferences.h"
#include "nautilus-metadata.h"
#include "nautilus-file-attributes.h"
#include <eel/eel-string.h>
#include <gtk/gtkmain.h>
#include <gtk/gtksignal.h>
#include <libgnome/gnome-config.h>
#include <libgnome/gnome-util.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <libbackground/preferences.h>
static void background_changed_callback (EelBackground *background,
@ -125,7 +120,7 @@ nautilus_file_background_read_desktop_settings (char **color,
if (prefs->wallpaper_enabled) {
if (prefs->wallpaper_filename != NULL &&
prefs->wallpaper_filename [0] != '\0') {
*image = gnome_vfs_get_uri_from_local_path (prefs->wallpaper_filename);
*image = g_filename_to_uri (prefs->wallpaper_filename, NULL, NULL);
} else {
*image = NULL;
}
@ -218,7 +213,7 @@ nautilus_file_background_write_desktop_settings (char *color, char *image, EelBa
original_filename = prefs->wallpaper_filename;
if (image != NULL) {
prefs->wallpaper_filename = gnome_vfs_get_local_path_from_uri (image);
prefs->wallpaper_filename = g_filename_from_uri (image, NULL, NULL);
prefs->wallpaper_enabled = TRUE;
switch (placement) {
case EEL_BACKGROUND_TILED:

View file

@ -81,7 +81,7 @@ corba_metafile_changed (PortableServer_Servant servant,
file_list = NULL;
for (buf_pos = 0; buf_pos < file_names->_length; ++buf_pos) {
file = nautilus_directory_find_file_by_internal_uri
file = nautilus_directory_find_file_by_internal_filename
(monitor->details->directory, file_names->_buffer [buf_pos]);
if (file != NULL) {

View file

@ -31,20 +31,36 @@ typedef struct {
} URIPair;
typedef struct {
char *uri;
GFile *from;
GFile *to;
} GFilePair;
typedef struct {
GFile *location;
gboolean set;
GdkPoint point;
int screen;
} NautilusFileChangesQueuePosition;
/* Almost-public change notification calls */
void nautilus_directory_notify_files_added (GList *uris);
void nautilus_directory_notify_files_changed (GList *uris);
void nautilus_directory_notify_files_moved (GList *uri_pairs);
void nautilus_directory_notify_files_removed (GList *uris);
void nautilus_directory_schedule_metadata_copy (GList *uri_pairs);
void nautilus_directory_schedule_metadata_move (GList *uri_pairs);
void nautilus_directory_schedule_metadata_remove (GList *uris);
void nautilus_directory_notify_files_added (GList *files);
void nautilus_directory_notify_files_moved (GList *file_pairs);
void nautilus_directory_notify_files_changed (GList *files);
void nautilus_directory_notify_files_removed (GList *files);
void nautilus_directory_schedule_metadata_copy (GList *file_pairs);
void nautilus_directory_schedule_metadata_move (GList *file_pairs);
void nautilus_directory_schedule_metadata_remove (GList *files);
/* Deprecated URI versions: to be converted */
void nautilus_directory_notify_files_added_by_uri (GList *uris);
void nautilus_directory_notify_files_changed_by_uri (GList *uris);
void nautilus_directory_notify_files_moved_by_uri (GList *uri_pairs);
void nautilus_directory_notify_files_removed_by_uri (GList *uris);
void nautilus_directory_schedule_metadata_copy_by_uri (GList *uri_pairs);
void nautilus_directory_schedule_metadata_move_by_uri (GList *uri_pairs);
void nautilus_directory_schedule_metadata_remove_by_uri (GList *uris);
void nautilus_directory_schedule_position_set (GList *position_setting_list);
/* Change notification hack.

View file

@ -22,10 +22,8 @@
Author: Darin Adler <darin@bentspoon.com>
*/
#include <gio/gfile.h>
#include <eel/eel-vfs-extensions.h>
#include <libgnomevfs/gnome-vfs-file-info.h>
#include <libgnomevfs/gnome-vfs-types.h>
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libnautilus-private/nautilus-directory-metafile-monitor.h>
#include <libnautilus-private/nautilus-directory.h>
#include <libnautilus-private/nautilus-file-queue.h>
@ -39,13 +37,18 @@
typedef struct LinkInfoReadState LinkInfoReadState;
typedef struct TopLeftTextReadState TopLeftTextReadState;
typedef struct FileMonitors FileMonitors;
typedef struct DirectoryLoadState DirectoryLoadState;
typedef struct DirectoryCountState DirectoryCountState;
typedef struct DeepCountState DeepCountState;
typedef struct GetInfoState GetInfoState;
typedef struct NewFilesState NewFilesState;
typedef struct MimeListState MimeListState;
typedef struct ThumbnailState ThumbnailState;
struct NautilusDirectoryDetails
{
/* The location. */
char *uri;
GnomeVFSURI *vfs_uri;
int is_local_state;
GFile *location;
/* The file objects. */
NautilusFile *as_file;
@ -77,44 +80,33 @@ struct NautilusDirectoryDetails
gboolean file_list_monitored;
gboolean directory_loaded;
gboolean directory_loaded_sent_notification;
GnomeVFSAsyncHandle *directory_load_in_progress;
DirectoryLoadState *directory_load_in_progress;
GList *pending_file_info; /* list of GnomeVFSFileInfo's that are pending */
int confirmed_file_count;
guint dequeue_pending_idle_id;
NautilusFile *load_directory_file;
int load_file_count;
GHashTable *load_mime_list_hash;
GList *get_file_infos_in_progress; /* list of GnomeVFSAsyncHandle * */
GList *new_files_in_progress; /* list of NewFilesState * */
NautilusFile *count_file;
GnomeVFSAsyncHandle *count_in_progress;
DirectoryCountState *count_in_progress;
NautilusFile *deep_count_file;
GnomeVFSAsyncHandle *deep_count_in_progress;
char *deep_count_uri;
GList *deep_count_subdirectories;
DeepCountState *deep_count_in_progress;
NautilusFile *mime_list_file;
GnomeVFSAsyncHandle *mime_list_in_progress;
GHashTable *mime_list_hash;
MimeListState *mime_list_in_progress;
NautilusFile *get_info_file;
GnomeVFSAsyncHandle *get_info_in_progress;
gboolean get_info_has_slow_mime_type;
int is_in_trash_state;
NautilusFile *slow_mime_type_file;
GnomeVFSAsyncHandle *slow_mime_type_in_progress;
GetInfoState *get_info_in_progress;
NautilusFile *extension_info_file;
NautilusInfoProvider *extension_info_provider;
NautilusOperationHandle *extension_info_in_progress;
guint extension_info_idle;
ThumbnailState *thumbnail_state;
TopLeftTextReadState *top_left_read_state;
LinkInfoReadState *link_info_read_state;
@ -136,10 +128,10 @@ typedef struct {
gboolean top_left_text;
gboolean large_top_left_text;
gboolean extension_info;
gboolean slow_mime_type;
gboolean thumbnail;
} Request;
NautilusDirectory *nautilus_directory_get_existing (const char *uri);
NautilusDirectory *nautilus_directory_get_existing (GFile *location);
/* async. interface */
void nautilus_directory_async_state_changed (NautilusDirectory *directory);
@ -195,11 +187,11 @@ void nautilus_directory_emit_files_changed (NautilusD
void nautilus_directory_emit_change_signals (NautilusDirectory *directory,
GList *changed_files);
void emit_change_signals_for_all_files (NautilusDirectory *directory);
void emit_change_signals_for_all_files_in_all_directories (void);
void nautilus_directory_emit_done_loading (NautilusDirectory *directory);
void nautilus_directory_emit_load_error (NautilusDirectory *directory,
GnomeVFSResult error_result,
const char *error_message);
NautilusDirectory *nautilus_directory_get_internal (const char *uri,
GError *error);
NautilusDirectory *nautilus_directory_get_internal (GFile *location,
gboolean create);
char * nautilus_directory_get_name_for_self_as_new_file (NautilusDirectory *directory);
void nautilus_directory_set_up_request (Request *request,
@ -207,11 +199,9 @@ void nautilus_directory_set_up_request (Request
/* Interface to the file list. */
NautilusFile * nautilus_directory_find_file_by_name (NautilusDirectory *directory,
const char *relative_uri);
NautilusFile * nautilus_directory_find_file_by_relative_uri (NautilusDirectory *directory,
const char *relative_uri);
NautilusFile * nautilus_directory_find_file_by_internal_uri (NautilusDirectory *directory,
const char *relative_uri);
const char *filename);
NautilusFile * nautilus_directory_find_file_by_internal_filename (NautilusDirectory *directory,
const char *internal_filename);
void nautilus_directory_add_file (NautilusDirectory *directory,
NautilusFile *file);

File diff suppressed because it is too large Load diff

View file

@ -26,13 +26,13 @@
#define NAUTILUS_DIRECTORY_H
#include <gtk/gtkobject.h>
#include <libgnomevfs/gnome-vfs-types.h>
#include <gio/gfile.h>
#include <libnautilus-private/nautilus-file-attributes.h>
/* NautilusDirectory is a class that manages the model for a directory,
real or virtual, for Nautilus, mainly the file-manager component. The directory is
responsible for managing both real data and cached metadata. On top of
the file system independence provided by gnome-vfs, the directory
the file system independence provided by gio, the directory
object also provides:
1) A synchronization framework, which notifies via signals as the
@ -101,8 +101,7 @@ typedef struct
void (* done_loading) (NautilusDirectory *directory);
void (* load_error) (NautilusDirectory *directory,
GnomeVFSResult error_result,
const char *error_message);
GError *error);
/*** Virtual functions for subclasses to override. ***/
gboolean (* contains_file) (NautilusDirectory *directory,
@ -152,7 +151,8 @@ GType nautilus_directory_get_type (void);
* Returns a referenced object, not a floating one. Unref when finished.
* If two windows are viewing the same uri, the directory object is shared.
*/
NautilusDirectory *nautilus_directory_get (const char *uri);
NautilusDirectory *nautilus_directory_get (GFile *location);
NautilusDirectory *nautilus_directory_get_by_uri (const char *uri);
NautilusDirectory *nautilus_directory_get_for_file (NautilusFile *file);
/* Covers for gtk_object_ref and gtk_object_unref that provide two conveniences:
@ -164,6 +164,7 @@ void nautilus_directory_unref (NautilusDirector
/* Access to a URI. */
char * nautilus_directory_get_uri (NautilusDirectory *directory);
GFile * nautilus_directory_get_location (NautilusDirectory *directory);
/* Is this file still alive and in this directory? */
gboolean nautilus_directory_contains_file (NautilusDirectory *directory,
@ -223,7 +224,6 @@ gboolean nautilus_directory_is_in_trash (NautilusDirector
*/
gboolean nautilus_directory_is_not_empty (NautilusDirectory *directory);
gboolean nautilus_directory_file_list_length_reached (NautilusDirectory *directory);
char * nautilus_directory_make_uri_canonical (const char *uri);
/* Convenience functions for dealing with a list of NautilusDirectory objects that each have a ref.
* These are just convenient names for functions that work on lists of GtkObject *.

View file

@ -40,11 +40,6 @@
#include <gtk/gtkseparatormenuitem.h>
#include <glib/gi18n.h>
#include <libgnomeui/gnome-uidefs.h>
#include <libgnomevfs/gnome-vfs-find-directory.h>
#include <libgnomevfs/gnome-vfs-ops.h>
#include <libgnomevfs/gnome-vfs-types.h>
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <libnautilus-private/nautilus-file-utilities.h>
#include <stdio.h>
#include <string.h>
@ -216,8 +211,7 @@ nautilus_drag_items_local (const char *target_uri_string, const GList *selection
* we should really test each item but that would be slow for large selections
* and currently dropped items can only be from the same container
*/
GnomeVFSURI *target_uri;
GnomeVFSURI *item_uri;
GFile *target, *item, *parent;
gboolean result;
/* must have at least one item */
@ -225,21 +219,17 @@ nautilus_drag_items_local (const char *target_uri_string, const GList *selection
result = FALSE;
target_uri = gnome_vfs_uri_new (target_uri_string);
target = g_file_new_for_uri (target_uri_string);
if (target_uri != NULL) {
/* get the parent URI of the first item in the selection */
item_uri = gnome_vfs_uri_new (((NautilusDragSelectionItem *)selection_list->data)->uri);
if (item_uri != NULL) {
result = gnome_vfs_uri_is_parent (target_uri, item_uri, FALSE);
gnome_vfs_uri_unref (item_uri);
}
gnome_vfs_uri_unref (target_uri);
/* get the parent URI of the first item in the selection */
item = g_file_new_for_uri (((NautilusDragSelectionItem *)selection_list->data)->uri);
parent = g_file_get_parent (item);
g_object_unref (item);
if (parent != NULL) {
result = g_file_equal (parent, target);
g_object_unref (parent);
}
return result;
}
@ -252,15 +242,14 @@ nautilus_drag_items_in_trash (const GList *selection_list)
* we should really test each item but that would be slow for large selections
* and currently dropped items can only be from the same container
*/
return eel_uri_is_in_trash (((NautilusDragSelectionItem *)selection_list->data)->uri);
return eel_uri_is_trash (((NautilusDragSelectionItem *)selection_list->data)->uri);
}
gboolean
nautilus_drag_items_on_desktop (const GList *selection_list)
{
char *uri;
GnomeVFSURI *vfs_uri, *desktop_vfs_uri;
char *desktop_uri;
GFile *desktop, *item, *parent;
gboolean result;
/* check if the first item on the list is in trash.
@ -272,16 +261,20 @@ nautilus_drag_items_on_desktop (const GList *selection_list)
if (eel_uri_is_desktop (uri)) {
return TRUE;
}
desktop = nautilus_get_desktop_location ();
item = g_file_new_for_uri (uri);
parent = g_file_get_parent (item);
g_object_unref (item);
vfs_uri = gnome_vfs_uri_new (uri);
desktop_uri = nautilus_get_desktop_directory_uri ();
desktop_vfs_uri = gnome_vfs_uri_new (desktop_uri);
g_free (desktop_uri);
result = FALSE;
result = gnome_vfs_uri_is_parent (desktop_vfs_uri, vfs_uri, FALSE);
gnome_vfs_uri_unref (desktop_vfs_uri);
gnome_vfs_uri_unref (vfs_uri);
if (parent) {
result = g_file_equal (desktop, parent);
g_object_unref (parent);
}
g_object_unref (desktop);
return result;
@ -303,18 +296,59 @@ nautilus_drag_default_drop_action_for_netscape_url (GdkDragContext *context)
return context->suggested_action;
}
static gboolean
check_same_fs (GFile *file1, GFile *file2)
{
GFileInfo *info1, *info2;
const char *id1, *id2;
gboolean res;
info1 = g_file_query_info (file1,
G_FILE_ATTRIBUTE_ID_FS,
0, NULL, NULL);
if (info1 == NULL) {
return FALSE;
}
id1 = g_file_info_get_attribute_string (info1, G_FILE_ATTRIBUTE_ID_FS);
if (id1 == NULL) {
g_object_unref (info1);
return FALSE;
}
info2 = g_file_query_info (file2,
G_FILE_ATTRIBUTE_ID_FS,
0, NULL, NULL);
if (info2 == NULL) {
g_object_unref (info1);
return FALSE;
}
id2 = g_file_info_get_attribute_string (info2, G_FILE_ATTRIBUTE_ID_FS);
if (id2 == NULL) {
g_object_unref (info1);
g_object_unref (info2);
return FALSE;
}
res = strcmp (id1, id2) == 0;
g_object_unref (info1);
g_object_unref (info2);
return res;
}
void
nautilus_drag_default_drop_action_for_icons (GdkDragContext *context,
const char *target_uri_string, const GList *items,
int *action)
const char *target_uri_string, const GList *items,
int *action)
{
gboolean same_fs;
gboolean target_is_source_parent;
GnomeVFSURI *target_uri;
GnomeVFSURI *dropped_uri;
GFile *target, *dropped;
GdkDragAction actions;
GnomeVFSResult result;
if (target_uri_string == NULL) {
*action = 0;
@ -340,22 +374,11 @@ nautilus_drag_default_drop_action_for_icons (GdkDragContext *context,
* passed with 700 while creating .Trash directory
*/
if (eel_uri_is_trash (target_uri_string)) {
result = gnome_vfs_find_directory (NULL, GNOME_VFS_DIRECTORY_KIND_TRASH,
&target_uri, TRUE, FALSE, 0);
if (result != GNOME_VFS_OK) {
*action = 0;
return;
}
/* Only move to Trash */
if (actions & GDK_ACTION_MOVE) {
*action = GDK_ACTION_MOVE;
}
if (target_uri) {
gnome_vfs_uri_unref (target_uri);
}
return;
} else if (g_str_has_prefix (target_uri_string, NAUTILUS_COMMAND_SPECIFIER)
@ -365,30 +388,16 @@ nautilus_drag_default_drop_action_for_icons (GdkDragContext *context,
}
return;
} else if (eel_uri_is_desktop (target_uri_string)) {
char *desktop_uri;
desktop_uri = nautilus_get_desktop_directory_uri ();
target_uri = gnome_vfs_uri_new (desktop_uri);
g_free (desktop_uri);
target = nautilus_get_desktop_location ();
} else {
target_uri = gnome_vfs_uri_new (target_uri_string);
}
if (target_uri == NULL) {
*action = 0;
return;
target = g_file_new_for_uri (target_uri_string);
}
/* Compare the first dropped uri with the target uri for same fs match. */
dropped_uri = gnome_vfs_uri_new (((NautilusDragSelectionItem *)items->data)->uri);
same_fs = TRUE;
dropped = g_file_new_for_uri (((NautilusDragSelectionItem *)items->data)->uri);
same_fs = check_same_fs (target, dropped);
target_is_source_parent = FALSE;
if (dropped_uri != NULL) {
gnome_vfs_check_same_fs_uris (dropped_uri, target_uri, &same_fs);
target_is_source_parent = gnome_vfs_uri_is_parent (target_uri, dropped_uri, FALSE);
gnome_vfs_uri_unref (dropped_uri);
}
gnome_vfs_uri_unref (target_uri);
target_is_source_parent = g_file_contains_file (target, dropped);
if (same_fs || target_is_source_parent) {
if (actions & GDK_ACTION_MOVE) {
@ -403,6 +412,10 @@ nautilus_drag_default_drop_action_for_icons (GdkDragContext *context,
*action = context->suggested_action;
}
}
g_object_unref (target);
g_object_unref (dropped);
}
/* Encode a "x-special/gnome-icon-list" selection.
@ -480,7 +493,7 @@ add_one_compatible_uri (const char *uri, int x, int y, int w, int h, gpointer da
g_string_append (result, uri);
g_string_append (result, "\r\n");
} else {
local_path = gnome_vfs_get_local_path_from_uri (uri);
local_path = g_filename_from_uri (uri, NULL, NULL);
/* Check for characters that confuse the old
* gnome_uri_list_extract_filenames implementation, and just leave

View file

@ -27,17 +27,15 @@
#include <sys/types.h>
#include <utime.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "nautilus-icon-factory.h"
#include <eel/eel-string.h>
#include "nautilus-file.h"
#include <eel/eel-glib-extensions.h>
#include <eel/eel-gdk-pixbuf-extensions.h>
#include <eel/eel-stock-dialogs.h>
#include <eel/eel-vfs-extensions.h>
#include <glib/gi18n.h>
#include <libgnomeui/gnome-icon-theme.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <gtk/gtkicontheme.h>
#include "nautilus-emblem-utils.h"
#define EMBLEM_NAME_TRASH "emblem-trash"
@ -48,14 +46,13 @@
#define EMBLEM_NAME_DESKTOP "emblem-desktop"
GList *
nautilus_emblem_list_availible (void)
nautilus_emblem_list_available (void)
{
GtkIconTheme *icon_theme;
GList *list;
icon_theme = nautilus_icon_factory_get_icon_theme ();
icon_theme = gtk_icon_theme_get_default ();
list = gtk_icon_theme_list_icons (icon_theme, "Emblems");
g_object_unref (icon_theme);
return list;
}
@ -64,9 +61,8 @@ nautilus_emblem_refresh_list (void)
{
GtkIconTheme *icon_theme;
icon_theme = nautilus_icon_factory_get_icon_theme ();
icon_theme = gtk_icon_theme_get_default ();
gtk_icon_theme_rescan_if_needed (icon_theme);
g_object_unref (icon_theme);
}
char *
@ -80,37 +76,39 @@ nautilus_emblem_get_icon_name_from_keyword (const char *keyword)
static gboolean
is_reserved_keyword (const char *keyword)
{
GList *availible;
GList *available;
char *icon_name;
gboolean result;
g_assert (keyword != NULL);
/* check intrinsic emblems */
if (eel_strcasecmp (keyword, NAUTILUS_FILE_EMBLEM_NAME_TRASH) == 0) {
if (g_strcasecmp (keyword, NAUTILUS_FILE_EMBLEM_NAME_TRASH) == 0) {
return TRUE;
}
if (eel_strcasecmp (keyword, NAUTILUS_FILE_EMBLEM_NAME_CANT_READ) == 0) {
if (g_strcasecmp (keyword, NAUTILUS_FILE_EMBLEM_NAME_CANT_READ) == 0) {
return TRUE;
}
if (eel_strcasecmp (keyword, NAUTILUS_FILE_EMBLEM_NAME_CANT_WRITE) == 0) {
if (g_strcasecmp (keyword, NAUTILUS_FILE_EMBLEM_NAME_CANT_WRITE) == 0) {
return TRUE;
}
if (eel_strcasecmp (keyword, NAUTILUS_FILE_EMBLEM_NAME_SYMBOLIC_LINK) == 0) {
if (g_strcasecmp (keyword, NAUTILUS_FILE_EMBLEM_NAME_SYMBOLIC_LINK) == 0) {
return TRUE;
}
if (eel_strcasecmp (keyword, NAUTILUS_FILE_EMBLEM_NAME_NOTE) == 0) {
if (g_strcasecmp (keyword, NAUTILUS_FILE_EMBLEM_NAME_NOTE) == 0) {
return TRUE;
}
if (eel_strcasecmp (keyword, NAUTILUS_FILE_EMBLEM_NAME_DESKTOP) == 0) {
if (g_strcasecmp (keyword, NAUTILUS_FILE_EMBLEM_NAME_DESKTOP) == 0) {
return TRUE;
}
availible = nautilus_emblem_list_availible ();
available = nautilus_emblem_list_available ();
icon_name = nautilus_emblem_get_icon_name_from_keyword (keyword);
/* see if the keyword already exists */
result = g_list_find_custom (availible,
result = g_list_find_custom (available,
(char *) icon_name,
(GCompareFunc) eel_strcasecmp) != NULL;
eel_g_list_free_deep (availible);
(GCompareFunc) g_strcasecmp) != NULL;
eel_g_list_free_deep (available);
g_free (icon_name);
return result;
}
@ -145,7 +143,7 @@ nautilus_emblem_get_keyword_from_icon_name (const char *emblem)
{
g_return_val_if_fail (emblem != NULL, NULL);
if (eel_str_has_prefix (emblem, "emblem-")) {
if (g_str_has_prefix (emblem, "emblem-")) {
return g_strdup (&emblem[7]);
} else {
return g_strdup (emblem);
@ -153,19 +151,26 @@ nautilus_emblem_get_keyword_from_icon_name (const char *emblem)
}
GdkPixbuf *
nautilus_emblem_load_pixbuf_for_emblem (const char *uri)
nautilus_emblem_load_pixbuf_for_emblem (GFile *emblem)
{
GInputStream *stream;
GdkPixbuf *pixbuf;
GdkPixbuf *scaled;
pixbuf = eel_gdk_pixbuf_load (uri);
stream = (GInputStream *) g_file_read (emblem, NULL, NULL);
if (!stream) {
return NULL;
}
pixbuf = eel_gdk_pixbuf_load_from_stream (stream);
g_return_val_if_fail (pixbuf != NULL, NULL);
scaled = eel_gdk_pixbuf_scale_down_to_fit (pixbuf,
NAUTILUS_ICON_SIZE_STANDARD,
NAUTILUS_ICON_SIZE_STANDARD);
g_object_unref (G_OBJECT (pixbuf));
g_object_unref (pixbuf);
g_object_unref (stream);
return scaled;
}
@ -227,9 +232,7 @@ nautilus_emblem_install_custom_emblem (GdkPixbuf *pixbuf,
const char *display_name,
GtkWindow *parent_window)
{
GnomeVFSURI *vfs_uri;
char *path, *dir, *stat_dir;
FILE *file;
char *basename, *path, *dir, *stat_dir;
struct stat stat_buf;
struct utimbuf ubuf;
@ -239,19 +242,25 @@ nautilus_emblem_install_custom_emblem (GdkPixbuf *pixbuf,
return;
}
dir = g_strdup_printf ("%s/.icons/hicolor/48x48/emblems",
g_get_home_dir ());
stat_dir = g_strdup_printf ("%s/.icons/hicolor",
g_get_home_dir ());
dir = g_build_filename (g_get_home_dir (),
".icons", "hicolor", "48x48", "emblems",
NULL);
stat_dir = g_build_filename (g_get_home_dir (),
".icons", "hicolor",
NULL);
vfs_uri = gnome_vfs_uri_new (dir);
if (g_mkdir_with_parents (dir, 0755) != 0) {
eel_show_error_dialog (_("The emblem cannot be installed."),
_("Sorry, unable to save custom emblem."),
GTK_WINDOW (parent_window));
g_free (dir);
g_free (stat_dir);
return;
}
g_return_if_fail (vfs_uri != NULL);
eel_make_directory_and_parents (vfs_uri, 0755);
gnome_vfs_uri_unref (vfs_uri);
path = g_strdup_printf ("%s/emblem-%s.png", dir, keyword);
basename = g_strdup_printf ("emblem-%s.png", keyword);
path = g_build_filename (dir, basename, NULL);
g_free (basename);
/* save the image */
if (eel_gdk_pixbuf_save_to_file (pixbuf, path) != TRUE) {
@ -267,23 +276,28 @@ nautilus_emblem_install_custom_emblem (GdkPixbuf *pixbuf,
g_free (path);
if (display_name != NULL) {
path = g_strdup_printf ("%s/emblem-%s.icon", dir, keyword);
file = fopen (path, "w+");
g_free (path);
char *contents;
if (file == NULL) {
basename = g_strdup_printf ("emblem-%s.icon", keyword);
path = g_build_filename (dir, basename, NULL);
g_free (basename);
contents = g_strdup_printf ("\n[Icon Data]\n\nDisplayName=%s\n",
display_name);
if (!g_file_set_contents (path, contents, strlen (contents), NULL)) {
eel_show_error_dialog (_("The emblem cannot be installed."),
_("Sorry, unable to save custom emblem name."),
GTK_WINDOW (parent_window));
g_free (contents);
g_free (path);
g_free (stat_dir);
g_free (dir);
return;
}
/* write the icon description */
fprintf (file, "\n[Icon Data]\n\nDisplayName=%s\n", display_name);
fflush (file);
fclose (file);
g_free (contents);
g_free (path);
}
/* Touch the toplevel dir */
@ -292,7 +306,7 @@ nautilus_emblem_install_custom_emblem (GdkPixbuf *pixbuf,
ubuf.modtime = time (NULL);
utime (stat_dir, &ubuf);
}
g_free (dir);
g_free (stat_dir);
@ -416,8 +430,7 @@ nautilus_emblem_rename_emblem (const char *keyword, const char *name)
fclose (file);
icon_name = nautilus_emblem_get_icon_name_from_keyword (keyword);
nautilus_icon_factory_remove_from_cache (icon_name, NULL,
NAUTILUS_ICON_SIZE_STANDARD);
nautilus_icon_info_clear_caches (); /* A bit overkill, but this happens rarely */
g_free (icon_name);

View file

@ -23,10 +23,11 @@
*/
#include <glib.h>
#include <gio/gfile.h>
#include <gtk/gtkwindow.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
GList * nautilus_emblem_list_availible (void);
GList * nautilus_emblem_list_available (void);
void nautilus_emblem_refresh_list (void);
gboolean nautilus_emblem_should_show_in_list (const char *emblem);
gboolean nautilus_emblem_verify_keyword (GtkWindow *parent_window,
@ -41,7 +42,7 @@ gboolean nautilus_emblem_remove_emblem (const char *keyword);
gboolean nautilus_emblem_rename_emblem (const char *keyword,
const char *display_name);
GdkPixbuf *nautilus_emblem_load_pixbuf_for_emblem (const char *uri);
GdkPixbuf *nautilus_emblem_load_pixbuf_for_emblem (GFile *emblem);
char * nautilus_emblem_get_keyword_from_icon_name (const char *emblem);
char * nautilus_emblem_get_icon_name_from_keyword (const char *keyword);

View file

@ -30,22 +30,16 @@
*/
typedef enum {
NAUTILUS_FILE_ATTRIBUTE_ACTIVATION_URI = 1 << 0,
NAUTILUS_FILE_ATTRIBUTE_CAPABILITIES = 1 << 1,
NAUTILUS_FILE_ATTRIBUTE_CUSTOM_ICON = 1 << 2,
NAUTILUS_FILE_ATTRIBUTE_DEEP_COUNTS = 1 << 3,
NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT = 1 << 4,
NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_MIME_TYPES = 1 << 5,
NAUTILUS_FILE_ATTRIBUTE_FILE_TYPE = 1 << 6,
NAUTILUS_FILE_ATTRIBUTE_IS_DIRECTORY = 1 << 7,
NAUTILUS_FILE_ATTRIBUTE_METADATA = 1 << 8,
NAUTILUS_FILE_ATTRIBUTE_MIME_TYPE = 1 << 9,
NAUTILUS_FILE_ATTRIBUTE_TOP_LEFT_TEXT = 1 << 10,
NAUTILUS_FILE_ATTRIBUTE_LARGE_TOP_LEFT_TEXT = 1 << 11,
NAUTILUS_FILE_ATTRIBUTE_DISPLAY_NAME = 1 << 12,
NAUTILUS_FILE_ATTRIBUTE_VOLUMES = 1 << 13,
NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO = 1 << 14,
NAUTILUS_FILE_ATTRIBUTE_SLOW_MIME_TYPE = 1 << 15
NAUTILUS_FILE_ATTRIBUTE_INFO = 1 << 0, /* All standard info */
NAUTILUS_FILE_ATTRIBUTE_LINK_INFO = 1 << 1, /* info from desktop links */
NAUTILUS_FILE_ATTRIBUTE_DEEP_COUNTS = 1 << 2,
NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT = 1 << 3,
NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_MIME_TYPES = 1 << 4,
NAUTILUS_FILE_ATTRIBUTE_METADATA = 1 << 5,
NAUTILUS_FILE_ATTRIBUTE_TOP_LEFT_TEXT = 1 << 6,
NAUTILUS_FILE_ATTRIBUTE_LARGE_TOP_LEFT_TEXT = 1 << 7,
NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO = 1 << 8,
NAUTILUS_FILE_ATTRIBUTE_THUMBNAIL = 1 << 9,
} NautilusFileAttributes;
#endif /* NAUTILUS_FILE_ATTRIBUTES_H */

View file

@ -49,8 +49,8 @@ typedef enum {
typedef struct {
NautilusFileChangeKind kind;
char *from_uri;
char *to_uri;
GFile *from;
GFile *to;
GdkPoint point;
int screen;
} NautilusFileChange;
@ -93,8 +93,12 @@ nautilus_file_changes_queue_get (void)
static void
nautilus_file_change_free (NautilusFileChange *change)
{
g_free (change->from_uri);
g_free (change->to_uri);
if (change->from) {
g_object_unref (change->from);
}
if (change->to) {
g_object_unref (change->to);
}
}
void
@ -139,7 +143,7 @@ nautilus_file_changes_queue_add_common (NautilusFileChangesQueue *queue,
}
void
nautilus_file_changes_queue_file_added (const char *uri)
nautilus_file_changes_queue_file_added (GFile *location)
{
NautilusFileChange *new_item;
NautilusFileChangesQueue *queue;
@ -148,12 +152,12 @@ nautilus_file_changes_queue_file_added (const char *uri)
new_item = g_new0 (NautilusFileChange, 1);
new_item->kind = CHANGE_FILE_ADDED;
new_item->from_uri = g_strdup (uri);
new_item->from = g_object_ref (location);
nautilus_file_changes_queue_add_common (queue, new_item);
}
void
nautilus_file_changes_queue_file_changed (const char *uri)
nautilus_file_changes_queue_file_changed (GFile *location)
{
NautilusFileChange *new_item;
NautilusFileChangesQueue *queue;
@ -162,12 +166,12 @@ nautilus_file_changes_queue_file_changed (const char *uri)
new_item = g_new0 (NautilusFileChange, 1);
new_item->kind = CHANGE_FILE_CHANGED;
new_item->from_uri = g_strdup (uri);
new_item->from = g_object_ref (location);
nautilus_file_changes_queue_add_common (queue, new_item);
}
void
nautilus_file_changes_queue_file_removed (const char *uri)
nautilus_file_changes_queue_file_removed (GFile *location)
{
NautilusFileChange *new_item;
NautilusFileChangesQueue *queue;
@ -176,12 +180,13 @@ nautilus_file_changes_queue_file_removed (const char *uri)
new_item = g_new0 (NautilusFileChange, 1);
new_item->kind = CHANGE_FILE_REMOVED;
new_item->from_uri = g_strdup (uri);
new_item->from = g_object_ref (location);
nautilus_file_changes_queue_add_common (queue, new_item);
}
void
nautilus_file_changes_queue_file_moved (const char *from, const char *to)
nautilus_file_changes_queue_file_moved (GFile *from,
GFile *to)
{
NautilusFileChange *new_item;
NautilusFileChangesQueue *queue;
@ -190,14 +195,14 @@ nautilus_file_changes_queue_file_moved (const char *from, const char *to)
new_item = g_new (NautilusFileChange, 1);
new_item->kind = CHANGE_FILE_MOVED;
new_item->from_uri = g_strdup (from);
new_item->to_uri = g_strdup (to);
new_item->from = g_object_ref (from);
new_item->to = g_object_ref (to);
nautilus_file_changes_queue_add_common (queue, new_item);
}
void
nautilus_file_changes_queue_schedule_metadata_copy (const char *from_uri,
const char *to_uri)
nautilus_file_changes_queue_schedule_metadata_copy (GFile *from,
GFile *to)
{
NautilusFileChange *new_item;
NautilusFileChangesQueue *queue;
@ -206,14 +211,14 @@ nautilus_file_changes_queue_schedule_metadata_copy (const char *from_uri,
new_item = g_new (NautilusFileChange, 1);
new_item->kind = CHANGE_METADATA_COPIED;
new_item->from_uri = g_strdup (from_uri);
new_item->to_uri = g_strdup (to_uri);
new_item->from = g_object_ref (from);
new_item->to = g_object_ref (to);
nautilus_file_changes_queue_add_common (queue, new_item);
}
void
nautilus_file_changes_queue_schedule_metadata_move (const char *from_uri,
const char *to_uri)
nautilus_file_changes_queue_schedule_metadata_move (GFile *from,
GFile *to)
{
NautilusFileChange *new_item;
NautilusFileChangesQueue *queue;
@ -222,13 +227,13 @@ nautilus_file_changes_queue_schedule_metadata_move (const char *from_uri,
new_item = g_new (NautilusFileChange, 1);
new_item->kind = CHANGE_METADATA_MOVED;
new_item->from_uri = g_strdup (from_uri);
new_item->to_uri = g_strdup (to_uri);
new_item->from = g_object_ref (from);
new_item->to = g_object_ref (to);
nautilus_file_changes_queue_add_common (queue, new_item);
}
void
nautilus_file_changes_queue_schedule_metadata_remove (const char *uri)
nautilus_file_changes_queue_schedule_metadata_remove (GFile *location)
{
NautilusFileChange *new_item;
NautilusFileChangesQueue *queue;
@ -237,12 +242,12 @@ nautilus_file_changes_queue_schedule_metadata_remove (const char *uri)
new_item = g_new (NautilusFileChange, 1);
new_item->kind = CHANGE_METADATA_REMOVED;
new_item->from_uri = g_strdup (uri);
new_item->from = g_object_ref (location);
nautilus_file_changes_queue_add_common (queue, new_item);
}
void
nautilus_file_changes_queue_schedule_position_set (const char *uri,
nautilus_file_changes_queue_schedule_position_set (GFile *location,
GdkPoint point,
int screen)
{
@ -253,14 +258,14 @@ nautilus_file_changes_queue_schedule_position_set (const char *uri,
new_item = g_new (NautilusFileChange, 1);
new_item->kind = CHANGE_POSITION_SET;
new_item->from_uri = g_strdup (uri);
new_item->from = g_object_ref (location);
new_item->point = point;
new_item->screen = screen;
nautilus_file_changes_queue_add_common (queue, new_item);
}
void
nautilus_file_changes_queue_schedule_position_remove (const char *uri)
nautilus_file_changes_queue_schedule_position_remove (GFile *location)
{
NautilusFileChange *new_item;
NautilusFileChangesQueue *queue;
@ -269,7 +274,7 @@ nautilus_file_changes_queue_schedule_position_remove (const char *uri)
new_item = g_new (NautilusFileChange, 1);
new_item->kind = CHANGE_POSITION_REMOVE;
new_item->from_uri = g_strdup (uri);
new_item->from = g_object_ref (location);
nautilus_file_changes_queue_add_common (queue, new_item);
}
@ -308,15 +313,15 @@ static void
pairs_list_free (GList *pairs)
{
GList *p;
URIPair *pair;
GFilePair *pair;
/* deep delete the list of pairs */
for (p = pairs; p != NULL; p = p->next) {
/* delete the strings in each pair */
pair = p->data;
g_free (pair->from_uri);
g_free (pair->to_uri);
g_object_unref (pair->from);
g_object_unref (pair->to);
}
/* delete the list and the now empty pair structs */
@ -331,7 +336,7 @@ position_set_list_free (GList *list)
for (p = list; p != NULL; p = p->next) {
item = p->data;
g_free (item->uri);
g_object_unref (item->location);
}
/* delete the list and the now empty structs */
eel_g_list_free_deep (list);
@ -347,7 +352,7 @@ nautilus_file_changes_consume_changes (gboolean consume_all)
GList *additions, *changes, *deletions, *moves;
GList *metadata_copy_requests, *metadata_move_requests, *metadata_remove_requests;
GList *position_set_requests;
URIPair *pair;
GFilePair *pair;
NautilusFileChangesQueuePosition *position_set;
guint chunk_count;
NautilusFileChangesQueue *queue;
@ -435,7 +440,7 @@ nautilus_file_changes_consume_changes (gboolean consume_all)
if (deletions != NULL) {
deletions = g_list_reverse (deletions);
nautilus_directory_notify_files_removed (deletions);
eel_g_list_free_deep (deletions);
eel_g_object_list_free (deletions);
deletions = NULL;
}
if (moves != NULL) {
@ -447,13 +452,13 @@ nautilus_file_changes_consume_changes (gboolean consume_all)
if (additions != NULL) {
additions = g_list_reverse (additions);
nautilus_directory_notify_files_added (additions);
eel_g_list_free_deep (additions);
eel_g_object_list_free (additions);
additions = NULL;
}
if (changes != NULL) {
changes = g_list_reverse (changes);
nautilus_directory_notify_files_changed (changes);
eel_g_list_free_deep (changes);
eel_g_object_list_free (changes);
changes = NULL;
}
if (metadata_copy_requests != NULL) {
@ -471,7 +476,7 @@ nautilus_file_changes_consume_changes (gboolean consume_all)
if (metadata_remove_requests != NULL) {
metadata_remove_requests = g_list_reverse (metadata_remove_requests);
nautilus_directory_schedule_metadata_remove (metadata_remove_requests);
eel_g_list_free_deep (metadata_remove_requests);
eel_g_object_list_free (metadata_remove_requests);
metadata_remove_requests = NULL;
}
if (position_set_requests != NULL) {
@ -490,46 +495,46 @@ nautilus_file_changes_consume_changes (gboolean consume_all)
/* add the new change to the list */
switch (change->kind) {
case CHANGE_FILE_ADDED:
additions = g_list_prepend (additions, change->from_uri);
additions = g_list_prepend (additions, change->from);
break;
case CHANGE_FILE_CHANGED:
changes = g_list_prepend (changes, change->from_uri);
changes = g_list_prepend (changes, change->from);
break;
case CHANGE_FILE_REMOVED:
deletions = g_list_prepend (deletions, change->from_uri);
deletions = g_list_prepend (deletions, change->from);
break;
case CHANGE_FILE_MOVED:
pair = g_new (URIPair, 1);
pair->from_uri = change->from_uri;
pair->to_uri = change->to_uri;
pair = g_new (GFilePair, 1);
pair->from = change->from;
pair->to = change->to;
moves = g_list_prepend (moves, pair);
break;
case CHANGE_METADATA_COPIED:
pair = g_new (URIPair, 1);
pair->from_uri = change->from_uri;
pair->to_uri = change->to_uri;
pair = g_new (GFilePair, 1);
pair->from = change->from;
pair->to = change->to;
metadata_copy_requests = g_list_prepend (metadata_copy_requests, pair);
break;
case CHANGE_METADATA_MOVED:
pair = g_new (URIPair, 1);
pair->from_uri = change->from_uri;
pair->to_uri = change->to_uri;
pair = g_new (GFilePair, 1);
pair->from = change->from;
pair->to = change->to;
metadata_move_requests = g_list_prepend (metadata_move_requests, pair);
break;
case CHANGE_METADATA_REMOVED:
metadata_remove_requests = g_list_prepend (metadata_remove_requests,
change->from_uri);
change->from);
break;
case CHANGE_POSITION_SET:
position_set = g_new (NautilusFileChangesQueuePosition, 1);
position_set->uri = change->from_uri;
position_set->location = change->from;
position_set->set = TRUE;
position_set->point = change->point;
position_set->screen = change->screen;
@ -539,7 +544,7 @@ nautilus_file_changes_consume_changes (gboolean consume_all)
case CHANGE_POSITION_REMOVE:
position_set = g_new (NautilusFileChangesQueuePosition, 1);
position_set->uri = change->from_uri;
position_set->location = change->from;
position_set->set = FALSE;
position_set_requests = g_list_prepend (position_set_requests,
position_set);

View file

@ -24,22 +24,24 @@
#define NAUTILUS_FILE_CHANGES_QUEUE_H
#include <gdk/gdktypes.h>
#include <gio/gfile.h>
void nautilus_file_changes_queue_file_added (const char *uri);
void nautilus_file_changes_queue_file_changed (const char *uri);
void nautilus_file_changes_queue_file_removed (const char *uri);
void nautilus_file_changes_queue_file_moved (const char *from_uri,
const char *to_uri);
void nautilus_file_changes_queue_schedule_metadata_copy (const char *from_uri,
const char *to_uri);
void nautilus_file_changes_queue_schedule_metadata_move (const char *from_uri,
const char *to_uri);
void nautilus_file_changes_queue_schedule_metadata_remove (const char *uri);
void nautilus_file_changes_queue_schedule_position_set (const char *uri,
GdkPoint point,
int screen);
void nautilus_file_changes_queue_schedule_position_remove (const char *uri);
void nautilus_file_changes_queue_file_added (GFile *location);
void nautilus_file_changes_queue_file_changed (GFile *location);
void nautilus_file_changes_queue_file_removed (GFile *location);
void nautilus_file_changes_queue_file_moved (GFile *from,
GFile *to);
void nautilus_file_changes_queue_schedule_metadata_copy (GFile *from,
GFile *to);
void nautilus_file_changes_queue_schedule_metadata_move (GFile *from,
GFile *to);
void nautilus_file_changes_queue_schedule_metadata_remove (GFile *location);
void nautilus_file_changes_queue_schedule_position_set (GFile *location,
GdkPoint point,
int screen);
void nautilus_file_changes_queue_schedule_position_remove (GFile *location);
void nautilus_file_changes_consume_changes (gboolean consume_all);
void nautilus_file_changes_consume_changes (gboolean consume_all);
#endif /* NAUTILUS_FILE_CHANGES_QUEUE_H */

View file

@ -30,7 +30,7 @@
#include "nautilus-dnd.h"
#include "nautilus-directory.h"
#include <eel/eel-glib-extensions.h>
#include <eel/eel-string.h>
#include <string.h>
static gboolean
nautilus_drag_can_accept_files (NautilusFile *drop_target_item)
@ -134,11 +134,11 @@ nautilus_drag_can_accept_info (NautilusFile *drop_target_item,
g_assert_not_reached ();
return FALSE;
}
}
void
nautilus_drag_file_receive_dropped_keyword (NautilusFile *file, const char *keyword)
nautilus_drag_file_receive_dropped_keyword (NautilusFile *file,
const char *keyword)
{
GList *keywords, *word;
@ -159,7 +159,7 @@ nautilus_drag_file_receive_dropped_keyword (NautilusFile *file, const char *keyw
g_list_free_1 (word);
}
}
nautilus_file_set_keywords (file, keywords);
eel_g_list_free_deep (keywords);
}

View file

@ -40,7 +40,7 @@
#include <gtk/gtktable.h>
#include <gtk/gtkvbox.h>
#include <glib/gi18n.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <glib/gurifuncs.h>
#include "nautilus-file-operations-progress-icons.h"
/* The default width of the progress dialog. It will be wider
@ -88,8 +88,8 @@ struct NautilusFileOperationsProgressDetails {
gulong files_total;
gulong file_index;
GnomeVFSFileSize bytes_copied;
GnomeVFSFileSize bytes_total;
goffset bytes_copied;
goffset bytes_total;
/* system time (microseconds) when show timeout was started */
gint64 start_time;
@ -190,7 +190,7 @@ set_text_unescaped_trimmed (GtkLabel *label, const char *text)
return;
}
unescaped_text = gnome_vfs_unescape_string_for_display (text);
unescaped_text = g_uri_unescape_string (text, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH);
unescaped_utf8 = eel_make_valid_utf8 (unescaped_text);
gtk_label_set_text (label, unescaped_utf8);
g_free (unescaped_utf8);
@ -486,7 +486,7 @@ nautilus_file_operations_progress_new (const char *title,
const char *from_prefix,
const char *to_prefix,
gulong total_files,
GnomeVFSFileSize total_bytes,
goffset total_bytes,
gboolean use_timeout)
{
GtkWidget *widget;
@ -531,7 +531,7 @@ nautilus_file_operations_progress_new (const char *title,
void
nautilus_file_operations_progress_set_total (NautilusFileOperationsProgress *progress,
gulong files_total,
GnomeVFSFileSize bytes_total)
goffset bytes_total)
{
g_return_if_fail (NAUTILUS_IS_FILE_OPERATIONS_PROGRESS (progress));
@ -562,7 +562,7 @@ nautilus_file_operations_progress_new_file (NautilusFileOperationsProgress *prog
const char *from_prefix,
const char *to_prefix,
gulong file_index,
GnomeVFSFileSize size)
goffset size)
{
char *operation_markup;
char *item_markup;
@ -621,8 +621,8 @@ nautilus_file_operations_progress_clear (NautilusFileOperationsProgress *progres
void
nautilus_file_operations_progress_update_sizes (NautilusFileOperationsProgress *progress,
GnomeVFSFileSize bytes_done_in_file,
GnomeVFSFileSize bytes_done)
goffset bytes_done_in_file,
goffset bytes_done)
{
g_return_if_fail (NAUTILUS_IS_FILE_OPERATIONS_PROGRESS (progress));

View file

@ -30,7 +30,6 @@
#define NAUTILUS_FILE_OPERATIONS_PROGRESS_H
#include <gtk/gtkdialog.h>
#include <libgnomevfs/gnome-vfs-file-size.h>
typedef struct NautilusFileOperationsProgressDetails NautilusFileOperationsProgressDetails;
@ -56,14 +55,14 @@ NautilusFileOperationsProgress *nautilus_file_operations_progress_new
const char *from_prefix,
const char *to_prefix,
gulong files_total,
GnomeVFSFileSize bytes_total,
goffset bytes_total,
gboolean use_timeout);
void nautilus_file_operations_progress_done (NautilusFileOperationsProgress *dialog);
void nautilus_file_operations_progress_set_progress_title (NautilusFileOperationsProgress *dialog,
const char *progress_title);
void nautilus_file_operations_progress_set_total (NautilusFileOperationsProgress *dialog,
gulong files_total,
GnomeVFSFileSize bytes_total);
goffset bytes_total);
void nautilus_file_operations_progress_set_operation_string (NautilusFileOperationsProgress *dialog,
const char *operation_string);
void nautilus_file_operations_progress_clear (NautilusFileOperationsProgress *dialog);
@ -75,10 +74,10 @@ void nautilus_file_operations_progress_new_file
const char *from_prefix,
const char *to_prefix,
gulong file_index,
GnomeVFSFileSize size);
goffset size);
void nautilus_file_operations_progress_update_sizes (NautilusFileOperationsProgress *dialog,
GnomeVFSFileSize bytes_done_in_file,
GnomeVFSFileSize bytes_done);
goffset bytes_done_in_file,
goffset bytes_done);
void nautilus_file_operations_progress_pause_timeout (NautilusFileOperationsProgress *progress);
void nautilus_file_operations_progress_resume_timeout (NautilusFileOperationsProgress *progress);

File diff suppressed because it is too large Load diff

View file

@ -29,9 +29,7 @@
#include <gdk/gdkdnd.h>
#include <gtk/gtkwidget.h>
#include <libgnomevfs/gnome-vfs-types.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <libgnomevfs/gnome-vfs-volume-monitor.h>
#include <gio/gvolume.h>
typedef void (* NautilusCopyCallback) (GHashTable *debuting_uris,
gpointer callback_data);
@ -42,6 +40,8 @@ typedef void (* NautilusNewFileCallback) (const char *new_file_uri,
typedef void (* NautilusSetPermissionsCallback) (gpointer callback_data);
typedef void (* NautilusDeleteCallback) (GHashTable *debuting_uris,
gpointer callback_data);
typedef void (* NautilusUnmountCallback) (GError *error,
gpointer callback_data);
/* FIXME: int copy_action should be an enum */
@ -72,27 +72,41 @@ void nautilus_file_operations_new_file_from_template (GtkWidget *p
NautilusNewFileCallback done_callback,
gpointer data);
void nautilus_file_operations_delete (const GList *item_uris,
GtkWidget *parent_view,
NautilusDeleteCallback done_callback,
gpointer done_callback_data);
void nautilus_file_operations_delete (GList *files,
GtkWindow *parent_window,
NautilusDeleteCallback done_callback,
gpointer done_callback_data);
void nautilus_file_operations_trash_or_delete (GList *files,
GtkWindow *parent_window,
NautilusDeleteCallback done_callback,
gpointer done_callback_data);
void nautilus_file_set_permissions_recursive (const char *directory,
GnomeVFSFilePermissions file_permissions,
GnomeVFSFilePermissions file_mask,
GnomeVFSFilePermissions folder_permissions,
GnomeVFSFilePermissions folder_mask,
guint32 file_permissions,
guint32 file_mask,
guint32 folder_permissions,
guint32 folder_mask,
NautilusSetPermissionsCallback callback,
gpointer callback_data);
void nautilus_file_operations_unmount_volume (GtkWidget *parent_view,
GnomeVFSVolume *volume,
GnomeVFSVolumeOpCallback callback,
gpointer user_data);
void nautilus_file_operations_unmount_volume (GtkWindow *parent_window,
GVolume *volume,
NautilusUnmountCallback callback,
gpointer user_data);
void nautilus_file_operations_unmount_drive (GtkWidget *parent_view,
GnomeVFSDrive *drive,
GnomeVFSVolumeOpCallback callback,
gpointer user_data);
void nautilus_file_operations_copy (GList *files,
GArray *relative_item_points,
GFile *target_dir,
GtkWindow *parent_window,
NautilusCopyCallback done_callback,
gpointer done_callback_data);
void nautilus_file_operations_move (GList *files,
GArray *relative_item_points,
GFile *target_dir,
GtkWindow *parent_window,
NautilusCopyCallback done_callback,
gpointer done_callback_data);
#endif /* NAUTILUS_FILE_OPERATIONS_H */

View file

@ -29,6 +29,7 @@
#include <libnautilus-private/nautilus-file.h>
#include <libnautilus-private/nautilus-monitor.h>
#include <eel/eel-glib-extensions.h>
#include <eel/eel-string.h>
#define NAUTILUS_FILE_LARGE_TOP_LEFT_TEXT_MAXIMUM_CHARACTERS_PER_LINE 80
#define NAUTILUS_FILE_LARGE_TOP_LEFT_TEXT_MAXIMUM_LINES 24
@ -39,11 +40,14 @@
#define NAUTILUS_FILE_TOP_LEFT_TEXT_MAXIMUM_BYTES 1024
#define NAUTILUS_FILE_DEFAULT_FILE_INFO_OPTIONS \
(GNOME_VFS_FILE_INFO_FOLLOW_LINKS | \
GNOME_VFS_FILE_INFO_GET_MIME_TYPE | \
GNOME_VFS_FILE_INFO_GET_SELINUX_CONTEXT | \
(GNOME_VFS_FILE_INFO_FOLLOW_LINKS | \
GNOME_VFS_FILE_INFO_GET_MIME_TYPE | \
GNOME_VFS_FILE_INFO_GET_SELINUX_CONTEXT | \
GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS)
#define NAUTILUS_FILE_DEFAULT_ATTRIBUTES \
"std:*,access:*,mountable:*,time:*,unix:*,owner:*,selinux:*,thumbnail:*,mountable:*"
/* These are in the typical sort order. Known things come first, then
* things where we can't know, finally things where we don't yet know.
*/
@ -60,39 +64,55 @@ typedef struct {
struct NautilusFileDetails
{
NautilusDirectory *directory;
char *relative_uri;
eel_ref_str name;
/* Cached version of the display name, guaranteed UTF8 safe.
* This is used a lot for sorting views.
*/
char *cached_display_name;
/* We cache the result of g_utf8_collate_key() on
* cached_display_name in order to do quick sorting on
* the display name
*/
/* File info: */
GFileType type;
eel_ref_str display_name;
char *display_name_collation_key;
eel_ref_str edit_name;
GnomeVFSFileInfo *info;
GnomeVFSResult get_info_error;
goffset size; /* -1 is unknown */
int sort_order;
guint32 permissions;
int uid; /* -1 is none */
int gid; /* -1 is none */
time_t atime; /* 0 is unknown */
time_t mtime; /* 0 is unknown */
time_t ctime; /* 0 is unknown */
char *symlink_name;
eel_ref_str mime_type;
char* selinux_context;
GError *get_info_error;
guint directory_count;
guint deep_directory_count;
guint deep_file_count;
guint deep_unreadable_count;
GnomeVFSFileSize deep_size;
goffset deep_size;
GIcon *icon;
char *thumbnail_path;
GdkPixbuf *thumbnail;
int thumbnail_size; /* 0 means original unframed thumbnail */
GList *mime_list; /* If this is a directory, the list of MIME types in it. */
char *top_left_text;
/* Info you might get from a link (.desktop, .directory or nautilus link) */
char *display_name;
char *custom_icon;
char *activation_uri;
/* The guessed (extension-based) mime type. This is saved for
* comparison vs. the slow mime type upon activation */
char *guessed_mime_type;
GFile *activation_location;
/* The following is for file operations in progress. Since
* there are normally only a few of these, we can move them to
@ -128,12 +148,10 @@ struct NautilusFileDetails
* list so the file knows not to do redundant I/O.
*/
eel_boolean_bit loading_directory : 1;
/* got_info known from info field being non-NULL */
eel_boolean_bit got_file_info : 1;
eel_boolean_bit get_info_failed : 1;
eel_boolean_bit file_info_is_up_to_date : 1;
eel_boolean_bit got_slow_mime_type : 1;
eel_boolean_bit got_directory_count : 1;
eel_boolean_bit directory_count_failed : 1;
eel_boolean_bit directory_count_is_up_to_date : 1;
@ -153,22 +171,52 @@ struct NautilusFileDetails
eel_boolean_bit got_link_info : 1;
eel_boolean_bit link_info_is_up_to_date : 1;
eel_boolean_bit got_custom_display_name : 1;
eel_boolean_bit got_custom_activation_location : 1;
eel_boolean_bit thumbnail_is_up_to_date : 1;
eel_boolean_bit thumbnail_tried_original : 1;
eel_boolean_bit thumbnailing_failed : 1;
eel_boolean_bit is_thumbnailing : 1;
eel_boolean_bit has_volume : 1;
eel_boolean_bit has_drive : 1;
/* TRUE if the file is open in a spatial window */
eel_boolean_bit has_open_window : 1;
eel_boolean_bit is_symlink : 1;
eel_boolean_bit is_mountpoint : 1;
eel_boolean_bit is_hidden : 1;
eel_boolean_bit is_backup : 1;
eel_boolean_bit has_permissions : 1;
eel_boolean_bit can_read : 1;
eel_boolean_bit can_write : 1;
eel_boolean_bit can_execute : 1;
eel_boolean_bit can_delete : 1;
eel_boolean_bit can_trash : 1;
eel_boolean_bit can_rename : 1;
eel_boolean_bit can_mount : 1;
eel_boolean_bit can_unmount : 1;
eel_boolean_bit can_eject : 1;
};
typedef struct {
NautilusFile *file;
GCancellable *cancellable;
NautilusFileOperationCallback callback;
gpointer callback_data;
gboolean is_rename;
gpointer data;
GDestroyNotify free_data;
} NautilusFileOperation;
NautilusFile *nautilus_file_new_from_info (NautilusDirectory *directory,
GnomeVFSFileInfo *info);
GFileInfo *info);
void nautilus_file_emit_changed (NautilusFile *file);
void nautilus_file_mark_gone (NautilusFile *file);
gboolean nautilus_file_info_missing (NautilusFile *file,
GnomeVFSFileInfoFields needed_mask);
char * nautilus_extract_top_left_text (const char *text,
gboolean large,
int length);
@ -178,15 +226,14 @@ gboolean nautilus_file_get_date (NautilusFile
NautilusDateType date_type,
time_t *date);
void nautilus_file_updated_deep_count_in_progress (NautilusFile *file);
void nautilus_file_clear_cached_display_name (NautilusFile *file);
void nautilus_file_clear_info (NautilusFile *file);
/* Compare file's state with a fresh file info struct, return FALSE if
* no change, update file and return TRUE if the file info contains
* new state. */
gboolean nautilus_file_update_info (NautilusFile *file,
GnomeVFSFileInfo *info,
gboolean info_has_slow_mime);
GFileInfo *info);
gboolean nautilus_file_update_name (NautilusFile *file,
const char *name);
@ -194,6 +241,11 @@ gboolean nautilus_file_update_name_and_directory (NautilusFile
const char *name,
NautilusDirectory *directory);
gboolean nautilus_file_set_display_name (NautilusFile *file,
const char *display_name,
const char *edit_name,
gboolean custom);
/* Return true if the top lefts of files in this directory should be
* fetched, according to the preference settings.
*/
@ -208,7 +260,6 @@ NautilusFileAttributes nautilus_file_get_all_attributes (void);
gboolean nautilus_file_is_self_owned (NautilusFile *file);
void nautilus_file_invalidate_count_and_mime_list (NautilusFile *file);
gboolean nautilus_file_rename_in_progress (NautilusFile *file);
GnomeVFSFileInfo * nautilus_file_peek_vfs_file_info (NautilusFile *file);
void nautilus_file_invalidate_extension_info_internal (NautilusFile *file);
void nautilus_file_info_providers_done (NautilusFile *file);
@ -217,10 +268,13 @@ void nautilus_file_info_providers_done (Nautilu
void nautilus_file_set_is_thumbnailing (NautilusFile *file,
gboolean is_thumbnailing);
/* Volumes: */
void nautilus_file_set_drive (NautilusFile *file,
GnomeVFSDrive *drive);
void nautilus_file_set_volume (NautilusFile *file,
GnomeVFSVolume *volume);
NautilusFileOperation *nautilus_file_operation_new (NautilusFile *file,
NautilusFileOperationCallback callback,
gpointer callback_data);
void nautilus_file_operation_free (NautilusFileOperation *op);
void nautilus_file_operation_complete (NautilusFileOperation *op,
GFile *result_location,
GError *error);
void nautilus_file_operation_cancel (NautilusFileOperation *op);
#endif

View file

@ -34,13 +34,10 @@
#include "nautilus-signaller.h"
#include <eel/eel-glib-extensions.h>
#include <eel/eel-string.h>
#include <eel/eel-vfs-extensions.h>
#include <eel/eel-debug.h>
#include <libgnome/gnome-util.h>
#include <glib/gi18n.h>
#include <libgnomevfs/gnome-vfs-ops.h>
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <gio/gfilemonitor.h>
#include <unistd.h>
#include <stdlib.h>
@ -57,49 +54,22 @@ static void desktop_dir_changed (void);
char *
nautilus_compute_title_for_uri (const char *text_uri)
nautilus_compute_title_for_location (GFile *location)
{
NautilusFile *file;
GnomeVFSURI *uri;
char *title, *displayname;
const char *hostname;
NautilusDirectory *directory;
NautilusQuery *query;
hostname = NULL;
char *title;
if (text_uri) {
if (eel_uri_is_search (text_uri)) {
directory = nautilus_directory_get (text_uri);
query = nautilus_search_directory_get_query (NAUTILUS_SEARCH_DIRECTORY (directory));
nautilus_directory_unref (directory);
if (query != NULL) {
title = nautilus_query_to_readable_string (query);
g_object_unref (query);
} else {
title = g_strdup (_("Search"));
}
return title;
}
file = nautilus_file_get (text_uri);
uri = gnome_vfs_uri_new (text_uri);
if (uri && strcmp (uri->method_string, "file") != 0) {
hostname = gnome_vfs_uri_get_host_name (uri);
}
displayname = nautilus_file_get_display_name (file);
if (hostname) {
title = g_strdup_printf (_("%s on %s"), displayname, hostname);
g_free (displayname);
} else {
title = displayname;
}
if (uri) {
gnome_vfs_uri_unref (uri);
}
/* TODO-gio: This doesn't really work all that great if the
info about the file isn't known atm... */
title = NULL;
if (location) {
file = nautilus_file_get (location);
title = nautilus_file_get_display_name (file);
nautilus_file_unref (file);
} else {
}
if (title == NULL) {
title = g_strdup ("");
}
@ -107,23 +77,6 @@ nautilus_compute_title_for_uri (const char *text_uri)
}
gboolean
nautilus_file_name_matches_hidden_pattern (const char *name_or_relative_uri)
{
g_return_val_if_fail (name_or_relative_uri != NULL, FALSE);
return name_or_relative_uri[0] == '.';
}
gboolean
nautilus_file_name_matches_backup_pattern (const char *name_or_relative_uri)
{
g_return_val_if_fail (name_or_relative_uri != NULL, FALSE);
return g_str_has_suffix (name_or_relative_uri, "~") &&
!g_str_equal (name_or_relative_uri, "~");
}
/**
* nautilus_get_user_directory:
*
@ -259,21 +212,19 @@ parse_xdg_dirs (const char *config_file)
}
static XdgDirEntry *cached_xdg_dirs = NULL;
static GnomeVFSMonitorHandle *cached_xdg_dirs_handle = NULL;
static GFileMonitor *cached_xdg_dirs_monitor = NULL;
static void
xdg_dir_changed (NautilusFile *file,
XdgDirEntry *dir)
{
char *file_uri;
char *dir_uri;
GFile *location, *dir_location;
char *path;
file_uri = nautilus_file_get_uri (file);
dir_uri = gnome_vfs_get_uri_from_local_path (dir->path);
if (file_uri && dir_uri &&
!gnome_vfs_uris_match (dir_uri, file_uri)) {
path = gnome_vfs_get_local_path_from_uri (file_uri);
location = nautilus_file_get_location (file);
dir_location = g_file_new_for_path (dir->path);
if (!g_file_equal (location, dir_location)) {
path = g_file_get_path (location);
if (path) {
char *argv[5];
@ -304,19 +255,18 @@ xdg_dir_changed (NautilusFile *file,
desktop_dir_changed ();
}
}
g_free (file_uri);
g_free (dir_uri);
g_object_unref (location);
g_object_unref (dir_location);
}
static void
xdg_dir_cache_changed_cb (GnomeVFSMonitorHandle *handle,
const gchar *monitor_uri,
const gchar *info_uri,
GnomeVFSMonitorEventType event_type,
gpointer user_data)
xdg_dir_cache_changed_cb (GFileMonitor *monitor,
GFile *file,
GFile *other_file,
GFileMonitorEvent event_type)
{
if (event_type == GNOME_VFS_MONITOR_EVENT_CHANGED ||
event_type == GNOME_VFS_MONITOR_EVENT_CREATED) {
if (event_type == G_FILE_MONITOR_EVENT_CHANGED ||
event_type == G_FILE_MONITOR_EVENT_CREATED) {
update_xdg_dir_cache ();
}
}
@ -378,15 +328,16 @@ destroy_xdg_dir_cache (void)
unschedule_user_dirs_changed ();
desktop_dir_changed ();
if (cached_xdg_dirs_handle != NULL) {
gnome_vfs_monitor_cancel (cached_xdg_dirs_handle);
cached_xdg_dirs_handle = NULL;
if (cached_xdg_dirs_monitor != NULL) {
g_object_unref (cached_xdg_dirs_monitor);
cached_xdg_dirs_monitor = NULL;
}
}
static void
update_xdg_dir_cache (void)
{
GFile *file;
char *config_file, *uri;
int i;
@ -399,27 +350,25 @@ update_xdg_dir_cache (void)
for (i = 0 ; cached_xdg_dirs[i].type != NULL; i++) {
cached_xdg_dirs[i].file = NULL;
if (strcmp (cached_xdg_dirs[i].path, g_get_home_dir ()) != 0) {
uri = gnome_vfs_get_uri_from_local_path (cached_xdg_dirs[i].path);
cached_xdg_dirs[i].file = nautilus_file_get (uri);
uri = g_filename_to_uri (cached_xdg_dirs[i].path, NULL, NULL);
cached_xdg_dirs[i].file = nautilus_file_get_by_uri (uri);
nautilus_file_monitor_add (cached_xdg_dirs[i].file,
&cached_xdg_dirs[i],
NAUTILUS_FILE_ATTRIBUTE_FILE_TYPE);
NAUTILUS_FILE_ATTRIBUTE_INFO);
g_signal_connect (cached_xdg_dirs[i].file,
"changed", G_CALLBACK (xdg_dir_changed), &cached_xdg_dirs[i]);
g_free (uri);
}
}
if (cached_xdg_dirs_handle == NULL) {
if (cached_xdg_dirs_monitor == NULL) {
config_file = g_build_filename (g_get_user_config_dir (),
"user-dirs.dirs", NULL);
uri = gnome_vfs_get_uri_from_local_path (config_file);
gnome_vfs_monitor_add (&cached_xdg_dirs_handle,
uri,
GNOME_VFS_MONITOR_FILE,
xdg_dir_cache_changed_cb,
NULL);
g_free (uri);
file = g_file_new_for_path (config_file);
cached_xdg_dirs_monitor = g_file_monitor_file (file, 0, NULL);
g_signal_connect (cached_xdg_dirs_monitor, "changed",
G_CALLBACK (xdg_dir_cache_changed_cb), NULL);
g_object_unref (file);
g_free (config_file);
eel_debug_call_at_shutdown (destroy_xdg_dir_cache);
@ -491,6 +440,19 @@ nautilus_get_desktop_directory (void)
return desktop_directory;
}
GFile *
nautilus_get_desktop_location (void)
{
char *desktop_directory;
GFile *res;
desktop_directory = get_desktop_path ();
res = g_file_new_for_path (desktop_directory);
g_free (desktop_directory);
return res;
}
/**
* nautilus_get_desktop_directory_uri:
@ -506,7 +468,7 @@ nautilus_get_desktop_directory_uri (void)
char *desktop_uri;
desktop_path = nautilus_get_desktop_directory ();
desktop_uri = gnome_vfs_get_uri_from_local_path (desktop_path);
desktop_uri = g_filename_to_uri (desktop_path, NULL, NULL);
g_free (desktop_path);
return desktop_uri;
@ -519,7 +481,7 @@ nautilus_get_desktop_directory_uri_no_create (void)
char *desktop_uri;
desktop_path = get_desktop_path ();
desktop_uri = gnome_vfs_get_uri_from_local_path (desktop_path);
desktop_uri = g_filename_to_uri (desktop_path, NULL, NULL);
g_free (desktop_path);
return desktop_uri;
@ -528,7 +490,7 @@ nautilus_get_desktop_directory_uri_no_create (void)
char *
nautilus_get_home_directory_uri (void)
{
return gnome_vfs_get_uri_from_local_path (g_get_home_dir ());
return g_filename_to_uri (g_get_home_dir (), NULL, NULL);
}
@ -568,7 +530,7 @@ nautilus_get_templates_directory_uri (void)
char *directory, *uri;
directory = nautilus_get_templates_directory ();
uri = gnome_vfs_get_uri_from_local_path (directory);
uri = g_filename_to_uri (directory, NULL, NULL);
g_free (directory);
return uri;
}
@ -590,21 +552,25 @@ nautilus_get_searches_directory (void)
}
/* These need to be reset to NULL when desktop_is_home_dir changes */
static char *escaped_desktop_dir = NULL;
static char *escaped_desktop_dir_dirname = NULL;
static char *escaped_desktop_dir_filename = NULL;
static GFile *desktop_dir = NULL;
static GFile *desktop_dir_dir = NULL;
static char *desktop_dir_filename = NULL;
static gboolean desktop_dir_changed_callback_installed = FALSE;
static void
desktop_dir_changed (void)
{
g_free (escaped_desktop_dir);
g_free (escaped_desktop_dir_filename);
g_free (escaped_desktop_dir_dirname);
escaped_desktop_dir = NULL;
escaped_desktop_dir_dirname = NULL;
escaped_desktop_dir_filename = NULL;
if (desktop_dir) {
g_object_unref (desktop_dir);
}
if (desktop_dir_dir) {
g_object_unref (desktop_dir_dir);
}
g_free (desktop_dir_filename);
desktop_dir = NULL;
desktop_dir_dir = NULL;
desktop_dir_filename = NULL;
}
static void
@ -616,49 +582,66 @@ desktop_dir_changed_callback (gpointer callback_data)
static void
update_desktop_dir (void)
{
char *uri, *path;
GnomeVFSURI *vfs_uri;
char *path;
char *dirname;
path = get_desktop_path ();
uri = gnome_vfs_get_uri_from_local_path (path);
vfs_uri = gnome_vfs_uri_new (uri);
desktop_dir = g_file_new_for_path (path);
dirname = g_path_get_dirname (path);
desktop_dir_dir = g_file_new_for_path (dirname);
g_free (dirname);
desktop_dir_filename = g_path_get_basename (path);
g_free (path);
g_free (uri);
escaped_desktop_dir = g_strdup (vfs_uri->text);
escaped_desktop_dir_filename = gnome_vfs_uri_extract_short_path_name (vfs_uri);
escaped_desktop_dir_dirname = gnome_vfs_uri_extract_dirname (vfs_uri);
gnome_vfs_uri_unref (vfs_uri);
}
gboolean
nautilus_is_home_directory_file_escaped (char *escaped_dirname,
char *escaped_file)
nautilus_is_home_directory_file (GFile *dir,
const char *filename)
{
static char *escaped_home_dir_dirname = NULL;
static char *escaped_home_dir_filename = NULL;
char *uri;
GnomeVFSURI *vfs_uri;
char *dirname;
static GFile *home_dir_dir = NULL;
static char *home_dir_filename = NULL;
if (escaped_home_dir_dirname == NULL) {
uri = nautilus_get_home_directory_uri ();
vfs_uri = gnome_vfs_uri_new (uri);
g_free (uri);
escaped_home_dir_filename = gnome_vfs_uri_extract_short_path_name (vfs_uri);
escaped_home_dir_dirname = gnome_vfs_uri_extract_dirname (vfs_uri);
gnome_vfs_uri_unref (vfs_uri);
if (home_dir_dir == NULL) {
dirname = g_path_get_dirname (g_get_home_dir ());
home_dir_dir = g_file_new_for_path (dirname);
g_free (dirname);
home_dir_filename = g_path_get_basename (g_get_home_dir ());
}
return (strcmp (escaped_dirname, escaped_home_dir_dirname) == 0 &&
strcmp (escaped_file, escaped_home_dir_filename) == 0);
return (g_file_equal (dir, home_dir_dir) &&
strcmp (filename, home_dir_filename) == 0);
}
gboolean
nautilus_is_desktop_directory_file_escaped (char *escaped_dirname,
char *escaped_file)
nautilus_is_home_directory (GFile *dir)
{
static GFile *home_dir = NULL;
if (home_dir == NULL) {
home_dir = g_file_new_for_path (g_get_home_dir ());
}
return g_file_equal (dir, home_dir);
}
gboolean
nautilus_is_root_directory (GFile *dir)
{
static GFile *root_dir = NULL;
if (root_dir == NULL) {
root_dir = g_file_new_for_path ("/");
}
return g_file_equal (dir, root_dir);
}
gboolean
nautilus_is_desktop_directory_file (GFile *dir,
const char *file)
{
if (!desktop_dir_changed_callback_installed) {
@ -668,16 +651,16 @@ nautilus_is_desktop_directory_file_escaped (char *escaped_dirname,
desktop_dir_changed_callback_installed = TRUE;
}
if (escaped_desktop_dir == NULL) {
if (desktop_dir == NULL) {
update_desktop_dir ();
}
return (strcmp (escaped_dirname, escaped_desktop_dir_dirname) == 0 &&
strcmp (escaped_file, escaped_desktop_dir_filename) == 0);
return (g_file_equal (dir, desktop_dir_dir) &&
strcmp (file, desktop_dir_filename) == 0);
}
gboolean
nautilus_is_desktop_directory_escaped (char *escaped_dir)
nautilus_is_desktop_directory (GFile *dir)
{
if (!desktop_dir_changed_callback_installed) {
@ -687,11 +670,11 @@ nautilus_is_desktop_directory_escaped (char *escaped_dir)
desktop_dir_changed_callback_installed = TRUE;
}
if (escaped_desktop_dir == NULL) {
if (desktop_dir == NULL) {
update_desktop_dir ();
}
return strcmp (escaped_dir, escaped_desktop_dir) == 0;
return g_file_equal (dir, desktop_dir);
}
@ -768,67 +751,52 @@ nautilus_get_data_file_path (const char *partial_path)
return NULL;
}
/**
* < 0 invalid URI
* == 0 no
* > 0 yes
**/
static int
test_uri_exists (const char *path)
{
GnomeVFSURI *uri;
gboolean exists;
uri = gnome_vfs_uri_new (path);
if (uri == NULL) {
return -1;
} else {
exists = gnome_vfs_uri_exists (uri);
gnome_vfs_uri_unref (uri);
return exists ? 1 : 0;
}
}
char *
nautilus_ensure_unique_file_name (const char *directory_uri,
const char *base_name,
const char *extension)
{
char *path, *escaped_name;
int exists;
GFileInfo *info;
char *filename;
GFile *dir, *child;
int copy;
char *res;
escaped_name = gnome_vfs_escape_string (base_name);
dir = g_file_new_for_uri (directory_uri);
path = g_strdup_printf ("%s/%s%s",
directory_uri,
escaped_name,
extension);
exists = test_uri_exists (path);
info = g_file_query_info (dir, G_FILE_ATTRIBUTE_STD_TYPE, 0, NULL, NULL);
if (info == NULL) {
g_object_unref (dir);
return NULL;
}
g_object_unref (info);
filename = g_strdup_printf ("%s%s",
base_name,
extension);
child = g_file_get_child (dir, filename);
g_free (filename);
copy = 1;
while (exists > 0) {
g_free (path);
path = g_strdup_printf ("%s/%s-%d%s",
directory_uri,
escaped_name,
copy,
extension);
exists = test_uri_exists (path);
while ((info = g_file_query_info (child, G_FILE_ATTRIBUTE_STD_TYPE, 0, NULL, NULL)) != NULL) {
g_object_unref (info);
g_object_unref (child);
filename = g_strdup_printf ("%s-%d%s",
base_name,
copy,
extension);
child = g_file_get_child (dir, filename);
g_free (filename);
copy++;
}
g_free (escaped_name);
if (exists < 0) {
g_free (path);
path = NULL;
}
return path;
res = g_file_get_uri (child);
g_object_unref (child);
g_object_unref (dir);
return res;
}
char *
@ -851,101 +819,29 @@ nautilus_unique_temporary_file_name (void)
return file_name;
}
char *
nautilus_find_existing_uri_in_hierarchy (const char *uri)
GFile *
nautilus_find_existing_uri_in_hierarchy (GFile *location)
{
GnomeVFSURI *vfs_uri, *parent_vfs_uri;
char *ret = NULL;
GFileInfo *info;
GFile *tmp;
g_assert (uri != NULL);
g_assert (location != NULL);
vfs_uri = gnome_vfs_uri_new (uri);
while (vfs_uri != NULL) {
if (gnome_vfs_uri_exists (vfs_uri)) {
ret = gnome_vfs_uri_to_string (vfs_uri, GNOME_VFS_URI_HIDE_NONE);
break;
location = g_object_ref (location);
while (location != NULL) {
info = g_file_query_info (location,
"std:name",
0, NULL, NULL);
g_object_unref (info);
if (info != NULL) {
return location;
}
parent_vfs_uri = gnome_vfs_uri_get_parent (vfs_uri);
gnome_vfs_uri_unref (vfs_uri);
vfs_uri = parent_vfs_uri;
tmp = location;
location = g_file_get_parent (location);
g_object_unref (tmp);
}
return ret;
}
const char *
nautilus_get_vfs_method_display_name (char *method)
{
if (g_ascii_strcasecmp (method, "computer") == 0 ) {
return _("Computer");
} else if (g_ascii_strcasecmp (method, "network") == 0 ) {
return _("Network");
} else if (g_ascii_strcasecmp (method, "fonts") == 0 ) {
return _("Fonts");
} else if (g_ascii_strcasecmp (method, "themes") == 0 ) {
return _("Themes");
} else if (g_ascii_strcasecmp (method, "burn") == 0 ) {
return _("CD/DVD Creator");
} else if (g_ascii_strcasecmp (method, "smb") == 0 ) {
return _("Windows Network");
} else if (g_ascii_strcasecmp (method, "dns-sd") == 0 ) {
/* translators: this is the title of the "dns-sd:///" location */
return _("Services in");
}
return NULL;
}
char *
nautilus_get_uri_shortname_for_display (GnomeVFSURI *uri)
{
char *utf8_name, *name, *tmp;
char *text_uri, *local_file;
gboolean validated;
const char *method;
validated = FALSE;
name = gnome_vfs_uri_extract_short_name (uri);
if (name == NULL) {
name = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_PASSWORD);
} else if (g_ascii_strcasecmp (uri->method_string, "file") == 0) {
text_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_PASSWORD);
local_file = gnome_vfs_get_local_path_from_uri (text_uri);
g_free (name);
if (local_file == NULL) { /* Happens for e.g. file:///# */
local_file = g_strdup ("/");
}
name = g_filename_display_basename (local_file);
g_free (local_file);
g_free (text_uri);
validated = TRUE;
} else if (!gnome_vfs_uri_has_parent (uri)) {
/* Special-case the display name for roots that are not local files */
method = nautilus_get_vfs_method_display_name (uri->method_string);
if (method == NULL) {
method = uri->method_string;
}
if (name == NULL ||
strcmp (name, GNOME_VFS_URI_PATH_STR) == 0) {
g_free (name);
name = g_strdup (method);
} else {
tmp = name;
name = g_strdup_printf ("%s: %s", method, name);
g_free (tmp);
}
}
if (!validated && !g_utf8_validate (name, -1, NULL)) {
utf8_name = eel_make_valid_utf8 (name);
g_free (name);
name = utf8_name;
}
return name;
return location;
}
#if !defined (NAUTILUS_OMIT_SELF_CHECK)

View file

@ -25,7 +25,7 @@
#ifndef NAUTILUS_FILE_UTILITIES_H
#define NAUTILUS_FILE_UTILITIES_H
#include <libgnomevfs/gnome-vfs-types.h>
#include <gio/gfile.h>
#define NAUTILUS_SAVED_SEARCH_EXTENSION ".savedSearch"
#define NAUTILUS_SAVED_SEARCH_MIMETYPE "application/x-gnome-saved-search"
@ -40,13 +40,16 @@ gboolean nautilus_file_name_matches_backup_pattern (const char *name_or_relati
char * nautilus_get_xdg_dir (const char *type);
char * nautilus_get_user_directory (void);
char * nautilus_get_desktop_directory (void);
GFile * nautilus_get_desktop_location (void);
char * nautilus_get_desktop_directory_uri (void);
char * nautilus_get_home_directory_uri (void);
gboolean nautilus_is_desktop_directory_file_escaped (char *escaped_dirname,
char *escaped_filename);
gboolean nautilus_is_desktop_directory_escaped (char *escaped_dir);
gboolean nautilus_is_home_directory_file_escaped (char *escaped_dirname,
char *escaped_file);
gboolean nautilus_is_desktop_directory_file (GFile *dir,
const char *filename);
gboolean nautilus_is_root_directory (GFile *dir);
gboolean nautilus_is_desktop_directory (GFile *dir);
gboolean nautilus_is_home_directory (GFile *dir);
gboolean nautilus_is_home_directory_file (GFile *dir,
const char *filename);
char * nautilus_get_gmc_desktop_directory (void);
char * nautilus_get_pixmap_directory (void);
@ -57,7 +60,7 @@ void nautilus_create_templates_directory (void);
char * nautilus_get_searches_directory (void);
char * nautilus_compute_title_for_uri (const char *text_uri);
char * nautilus_compute_title_for_location (GFile *file);
/* This function returns something that needs to be freed with g_free,
* is not NULL, but is not garaunteed to exist */
@ -85,9 +88,6 @@ char * nautilus_ensure_unique_file_name (const char *directory_uri,
const char *extension);
char * nautilus_unique_temporary_file_name (void);
char * nautilus_find_existing_uri_in_hierarchy (const char *uri);
const char *nautilus_get_vfs_method_display_name (char *method);
char * nautilus_get_uri_shortname_for_display (GnomeVFSURI *uri);
GFile * nautilus_find_existing_uri_in_hierarchy (GFile *location);
#endif /* NAUTILUS_FILE_UTILITIES_H */

File diff suppressed because it is too large Load diff

View file

@ -26,9 +26,11 @@
#define NAUTILUS_FILE_H
#include <gtk/gtkobject.h>
#include <libgnomevfs/gnome-vfs-types.h>
#include <libgnomevfs/gnome-vfs-volume.h>
#include <gio/gfileinfo.h>
#include <gio/gfile.h>
#include <gio/gioerror.h>
#include <libnautilus-private/nautilus-file-attributes.h>
#include <libnautilus-private/nautilus-icon-info.h>
/* NautilusFile is an object used to represent a single element of a
* NautilusDirectory. It's lightweight and relies on NautilusDirectory
@ -51,6 +53,8 @@ typedef struct NautilusFile NautilusFile;
(GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_FILE))
#define NAUTILUS_IS_FILE_CLASS(klass) \
(GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_FILE))
#define NAUTILUS_FILE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_FILE, NautilusFileClass))
typedef enum {
NAUTILUS_FILE_SORT_NONE,
@ -69,6 +73,15 @@ typedef enum {
NAUTILUS_REQUEST_DONE
} NautilusRequestStatus;
typedef enum {
NAUTILUS_FILE_ICON_FLAGS_NONE = 0,
NAUTILUS_FILE_ICON_FLAGS_USE_THUMBNAILS = (1<<0),
NAUTILUS_FILE_ICON_FLAGS_IGNORE_VISITING = (1<<1),
NAUTILUS_FILE_ICON_FLAGS_EMBEDDING_TEXT = (1<<2),
NAUTILUS_FILE_ICON_FLAGS_FOR_DRAG_ACCEPT = (1<<3),
NAUTILUS_FILE_ICON_FLAGS_FOR_OPEN_FOLDER = (1<<4)
} NautilusFileIconFlags;
/* Emblems sometimes displayed for NautilusFiles. Do not localize. */
#define NAUTILUS_FILE_EMBLEM_NAME_SYMBOLIC_LINK "symbolic-link"
#define NAUTILUS_FILE_EMBLEM_NAME_CANT_READ "noread"
@ -82,7 +95,8 @@ typedef void (*NautilusFileCallback) (NautilusFile *file,
typedef void (*NautilusFileListCallback) (GList *file_list,
gpointer callback_data);
typedef void (*NautilusFileOperationCallback) (NautilusFile *file,
GnomeVFSResult result,
GFile *result_location,
GError *error,
gpointer callback_data);
typedef int (*NautilusWidthMeasureCallback) (const char *string,
void *context);
@ -90,16 +104,21 @@ typedef char * (*NautilusTruncateCallback) (const char *string,
int width,
void *context);
#define NAUTILUS_FILE_ATTRIBUTES_FOR_ICON (NAUTILUS_FILE_ATTRIBUTE_INFO | NAUTILUS_FILE_ATTRIBUTE_LINK_INFO |NAUTILUS_FILE_ATTRIBUTE_METADATA | NAUTILUS_FILE_ATTRIBUTE_THUMBNAIL)
typedef void NautilusFileListHandle;
/* GObject requirements. */
GType nautilus_file_get_type (void);
/* Getting at a single file. */
NautilusFile * nautilus_file_get (const char *uri);
NautilusFile * nautilus_file_get (GFile *location);
NautilusFile * nautilus_file_get_by_uri (const char *uri);
/* Get a file only if the nautilus version already exists */
NautilusFile * nautilus_file_get_existing (const char *uri);
NautilusFile * nautilus_file_get_existing (GFile *location);
NautilusFile * nautilus_file_get_existing_by_uri (const char *uri);
/* Covers for gtk_object_ref and gtk_object_unref that provide two conveniences:
* 1) You don't have to cast to GtkObject *, so using these is type safe.
@ -135,20 +154,25 @@ void nautilus_file_invalidate_all_attributes (Nautilu
/* Basic attributes for file objects. */
gboolean nautilus_file_contains_text (NautilusFile *file);
char * nautilus_file_get_display_name (NautilusFile *file);
char * nautilus_file_get_edit_name (NautilusFile *file);
char * nautilus_file_get_name (NautilusFile *file);
GFile * nautilus_file_get_location (NautilusFile *file);
char * nautilus_file_get_uri (NautilusFile *file);
char * nautilus_file_get_uri_scheme (NautilusFile *file);
NautilusFile * nautilus_file_get_parent (NautilusFile *file);
GFile * nautilus_file_get_parent_location (NautilusFile *file);
char * nautilus_file_get_parent_uri (NautilusFile *file);
char * nautilus_file_get_parent_uri_for_display (NautilusFile *file);
GnomeVFSFileSize nautilus_file_get_size (NautilusFile *file);
GnomeVFSFileType nautilus_file_get_file_type (NautilusFile *file);
char * nautilus_file_get_guessed_mime_type (NautilusFile *file);
gboolean nautilus_file_can_get_size (NautilusFile *file);
goffset nautilus_file_get_size (NautilusFile *file);
time_t nautilus_file_get_mtime (NautilusFile *file);
GFileType nautilus_file_get_file_type (NautilusFile *file);
char * nautilus_file_get_mime_type (NautilusFile *file);
gboolean nautilus_file_is_mime_type (NautilusFile *file,
const char *mime_type);
gboolean nautilus_file_needs_slow_mime_type (NautilusFile *file);
gboolean nautilus_file_is_launchable (NautilusFile *file);
gboolean nautilus_file_is_symbolic_link (NautilusFile *file);
gboolean nautilus_file_is_mountpoint (NautilusFile *file);
char * nautilus_file_get_volume_free_space (NautilusFile *file);
char * nautilus_file_get_volume_name (NautilusFile *file);
char * nautilus_file_get_symbolic_link_target_path (NautilusFile *file);
@ -161,7 +185,7 @@ gboolean nautilus_file_is_in_trash (Nautilu
gboolean nautilus_file_is_in_desktop (NautilusFile *file);
gboolean nautilus_file_is_home (NautilusFile *file);
gboolean nautilus_file_is_desktop_directory (NautilusFile *file);
GnomeVFSResult nautilus_file_get_file_info_result (NautilusFile *file);
GError * nautilus_file_get_file_info_error (NautilusFile *file);
gboolean nautilus_file_get_directory_item_count (NautilusFile *file,
guint *count,
gboolean *count_unreadable);
@ -170,14 +194,20 @@ NautilusRequestStatus nautilus_file_get_deep_counts (Nautilu
guint *directory_count,
guint *file_count,
guint *unreadable_directory_count,
GnomeVFSFileSize *total_size,
goffset *total_size,
gboolean force);
gboolean nautilus_file_should_show_thumbnail (NautilusFile *file);
gboolean nautilus_file_should_show_directory_item_count (NautilusFile *file);
gboolean nautilus_file_should_show_type (NautilusFile *file);
GList * nautilus_file_get_keywords (NautilusFile *file);
void nautilus_file_set_keywords (NautilusFile *file,
GList *keywords);
GList * nautilus_file_get_emblem_names (NautilusFile *file);
GList * nautilus_file_get_emblem_icons (NautilusFile *file,
char **exclude);
GList * nautilus_file_get_emblem_pixbufs (NautilusFile *file,
int size,
gboolean force_size,
char **exclude);
char * nautilus_file_get_top_left_text (NautilusFile *file);
char * nautilus_file_peek_top_left_text (NautilusFile *file,
gboolean need_large_text,
@ -185,10 +215,15 @@ char * nautilus_file_peek_top_left_text (Nautilu
gboolean nautilus_file_get_directory_item_mime_types (NautilusFile *file,
GList **mime_list);
void nautilus_file_set_attributes (NautilusFile *file,
GFileInfo *attributes,
NautilusFileOperationCallback callback,
gpointer callback_data);
/* Permissions. */
gboolean nautilus_file_can_get_permissions (NautilusFile *file);
gboolean nautilus_file_can_set_permissions (NautilusFile *file);
GnomeVFSFilePermissions nautilus_file_get_permissions (NautilusFile *file);
guint nautilus_file_get_permissions (NautilusFile *file);
gboolean nautilus_file_can_get_owner (NautilusFile *file);
gboolean nautilus_file_can_set_owner (NautilusFile *file);
gboolean nautilus_file_can_get_group (NautilusFile *file);
@ -206,12 +241,23 @@ gboolean nautilus_file_can_read (Nautilu
gboolean nautilus_file_can_write (NautilusFile *file);
gboolean nautilus_file_can_execute (NautilusFile *file);
gboolean nautilus_file_can_rename (NautilusFile *file);
gboolean nautilus_file_can_delete (NautilusFile *file);
gboolean nautilus_file_can_trash (NautilusFile *file);
/* Volumes. */
gboolean nautilus_file_has_volume (NautilusFile *file);
gboolean nautilus_file_has_drive (NautilusFile *file);
GnomeVFSVolume * nautilus_file_get_volume (NautilusFile *file);
GnomeVFSDrive * nautilus_file_get_drive (NautilusFile *file);
gboolean nautilus_file_can_mount (NautilusFile *file);
gboolean nautilus_file_can_unmount (NautilusFile *file);
gboolean nautilus_file_can_eject (NautilusFile *file);
void nautilus_file_mount (NautilusFile *file,
GMountOperation *mount_op,
NautilusFileOperationCallback callback,
gpointer callback_data);
void nautilus_file_unmount (NautilusFile *file,
NautilusFileOperationCallback callback,
gpointer callback_data);
void nautilus_file_eject (NautilusFile *file,
NautilusFileOperationCallback callback,
gpointer callback_data);
/* Basic operations for file objects. */
void nautilus_file_set_owner (NautilusFile *file,
@ -223,7 +269,7 @@ void nautilus_file_set_group (Nautilu
NautilusFileOperationCallback callback,
gpointer callback_data);
void nautilus_file_set_permissions (NautilusFile *file,
GnomeVFSFilePermissions permissions,
guint32 permissions,
NautilusFileOperationCallback callback,
gpointer callback_data);
void nautilus_file_rename (NautilusFile *file,
@ -333,6 +379,16 @@ char * nautilus_file_get_drop_target_uri (Nautilu
char * nautilus_file_get_custom_icon (NautilusFile *file);
GIcon * nautilus_file_get_gicon (NautilusFile *file,
NautilusFileIconFlags flags);
NautilusIconInfo * nautilus_file_get_icon (NautilusFile *file,
int size,
NautilusFileIconFlags flags);
GdkPixbuf * nautilus_file_get_icon_pixbuf (NautilusFile *file,
int size,
gboolean force_size,
NautilusFileIconFlags flags);
gboolean nautilus_file_has_open_window (NautilusFile *file);
void nautilus_file_set_has_open_window (NautilusFile *file,
gboolean has_open_window);
@ -377,6 +433,12 @@ typedef enum {
typedef struct {
GObjectClass parent_slot;
/* Subclasses can set this to something other than G_FILE_TYPE_UNKNOWN and
it will be used as the default file type. This is useful when creating
a "virtual" NautilusFile subclass that you can't actually get real
information about. For exaple NautilusDesktopDirectoryFile. */
GFileType default_file_type;
/* Called when the file notices any change. */
void (* changed) (NautilusFile *file);
@ -399,7 +461,6 @@ typedef struct {
gpointer callback_data);
gboolean (* check_if_ready) (NautilusFile *file,
NautilusFileAttributes attributes);
GnomeVFSFileType (* get_file_type) (NautilusFile *file);
gboolean (* get_item_count) (NautilusFile *file,
guint *count,
gboolean *count_unreadable);
@ -407,11 +468,22 @@ typedef struct {
guint *directory_count,
guint *file_count,
guint *unreadable_directory_count,
GnomeVFSFileSize *total_size);
goffset *total_size);
gboolean (* get_date) (NautilusFile *file,
NautilusDateType type,
time_t *date);
char * (* get_where_string) (NautilusFile *file);
void (* mount) (NautilusFile *file,
GMountOperation *mount_op,
NautilusFileOperationCallback callback,
gpointer callback_data);
void (* unmount) (NautilusFile *file,
NautilusFileOperationCallback callback,
gpointer callback_data);
void (* eject) (NautilusFile *file,
NautilusFileOperationCallback callback,
gpointer callback_data);
} NautilusFileClass;
#endif /* NAUTILUS_FILE_H */

View file

@ -28,7 +28,6 @@
#include "nautilus-file-utilities.h"
#include "nautilus-file.h"
#include "nautilus-icon-factory.h"
#include <eel/eel-enumeration.h>
#include <eel/eel-glib-extensions.h>
#include <eel/eel-gtk-extensions.h>
@ -36,11 +35,9 @@
#include <eel/eel-string.h>
#include <glib/gi18n.h>
#include <libgnome/gnome-util.h>
#include <libgnomevfs/gnome-vfs-mime-handlers.h>
#include <libgnomevfs/gnome-vfs-utils.h>
/* Constants */
#define STRING_LIST_DEFAULT_TOKENS_DELIMETER ","
#define STRING_ARRAY_DEFAULT_TOKENS_DELIMETER ","
#define PREFERENCES_SORT_ORDER_MANUALLY 100
/* Path for gnome-vfs preferences */
@ -64,15 +61,14 @@ typedef enum
PREFERENCE_BOOLEAN = 1,
PREFERENCE_INTEGER,
PREFERENCE_STRING,
PREFERENCE_STRING_LIST
PREFERENCE_STRING_ARRAY
} PreferenceType;
/* Enumerations used to qualify some INTEGER preferences */
static EelEnumerationEntry speed_tradeoff_enum_entries[] = {
{ "always", N_("_Always"), NAUTILUS_SPEED_TRADEOFF_ALWAYS },
{ "local_only", N_("_Local File Only"), NAUTILUS_SPEED_TRADEOFF_LOCAL_ONLY },
{ "never", N_("_Never"), NAUTILUS_SPEED_TRADEOFF_NEVER },
{ NULL }
{ "never", N_("_Never"), NAUTILUS_SPEED_TRADEOFF_NEVER }
};
static EelEnumerationEntry default_zoom_level_enum_entries[] = {
@ -89,8 +85,7 @@ static EelEnumerationEntry default_zoom_level_enum_entries[] = {
/* xgettext:no-c-format */
{ "larger", N_("200%"), NAUTILUS_ZOOM_LEVEL_LARGER },
/* xgettext:no-c-format */
{ "largest", N_("400%"), NAUTILUS_ZOOM_LEVEL_LARGEST },
{ NULL }
{ "largest", N_("400%"), NAUTILUS_ZOOM_LEVEL_LARGEST }
};
static EelEnumerationEntry file_size_enum_entries[] = {
@ -100,8 +95,7 @@ static EelEnumerationEntry file_size_enum_entries[] = {
{ "3145728", N_("3 MB"), 3145728 },
{ "5242880", N_("5 MB"), 5242880 },
{ "10485760", N_("10 MB"), 10485760 },
{ "104857600", N_("100 MB"), 104857600 },
{ NULL }
{ "104857600", N_("100 MB"), 104857600 }
};
static EelEnumerationEntry click_policy_enum_entries[] = {
@ -112,8 +106,7 @@ static EelEnumerationEntry click_policy_enum_entries[] = {
{ "double",
N_("Activate items with a _double click"),
NAUTILUS_CLICK_POLICY_DOUBLE
},
{ NULL }
}
};
static EelEnumerationEntry executable_text_activation_enum_entries[] = {
@ -128,8 +121,7 @@ static EelEnumerationEntry executable_text_activation_enum_entries[] = {
{ "ask",
N_("_Ask each time"),
NAUTILUS_EXECUTABLE_TEXT_ASK
},
{ NULL }
}
};
static EelEnumerationEntry search_bar_type_enum_entries[] = {
@ -140,14 +132,12 @@ static EelEnumerationEntry search_bar_type_enum_entries[] = {
{ "search by text and properties",
N_("Search for files by file name and file properties"),
NAUTILUS_COMPLEX_SEARCH_BAR
},
{ NULL }
}
};
static EelEnumerationEntry default_folder_viewer_enum_entries[] = {
{ "icon_view", N_("Icon View"), NAUTILUS_DEFAULT_FOLDER_VIEWER_ICON_VIEW },
{ "list_view", N_("List View"), NAUTILUS_DEFAULT_FOLDER_VIEWER_LIST_VIEW },
{ NULL }
{ "list_view", N_("List View"), NAUTILUS_DEFAULT_FOLDER_VIEWER_LIST_VIEW }
};
static EelEnumerationEntry default_icon_view_sort_order_enum_entries[] = {
@ -157,8 +147,7 @@ static EelEnumerationEntry default_icon_view_sort_order_enum_entries[] = {
{ "size", N_("By Size"), NAUTILUS_FILE_SORT_BY_SIZE },
{ "type", N_("By Type"), NAUTILUS_FILE_SORT_BY_TYPE },
{ "modification_date", N_("By Modification Date"), NAUTILUS_FILE_SORT_BY_MTIME },
{ "emblems", N_("By Emblems"), NAUTILUS_FILE_SORT_BY_EMBLEMS },
{ NULL }
{ "emblems", N_("By Emblems"), NAUTILUS_FILE_SORT_BY_EMBLEMS }
};
static EelEnumerationEntry standard_font_size_entries[] = {
@ -170,34 +159,14 @@ static EelEnumerationEntry standard_font_size_entries[] = {
{ "18", N_("18"), 18 },
{ "20", N_("20"), 20 },
{ "22", N_("22"), 22 },
{ "24", N_("24"), 24 },
{ NULL }
{ "24", N_("24"), 24 }
};
/* These are not translated, because the text is not used in the ui */
static EelEnumerationEntry date_format_entries[] = {
{ "locale", "Locale Default", NAUTILUS_DATE_FORMAT_LOCALE },
{ "iso", "ISO Format", NAUTILUS_DATE_FORMAT_ISO },
{ "informal", "Informal", NAUTILUS_DATE_FORMAT_INFORMAL },
{ NULL }
};
/* These enumerations are used in the preferences dialog to
* populate widgets and route preferences changes between the
* storage (GConf) and the displayed values.
*/
static EelEnumerationInfo enumerations[] = {
{ "click_policy", click_policy_enum_entries },
{ "default_folder_viewer", default_folder_viewer_enum_entries },
{ "default_icon_view_sort_order", default_icon_view_sort_order_enum_entries },
{ "default_zoom_level", default_zoom_level_enum_entries },
{ "executable_text_activation", executable_text_activation_enum_entries },
{ "file_size", file_size_enum_entries },
{ "search_bar_type", search_bar_type_enum_entries },
{ "speed_tradeoff", speed_tradeoff_enum_entries },
{ "standard_font_size", standard_font_size_entries },
{ "date_format", date_format_entries },
{ NULL }
{ "informal", "Informal", NAUTILUS_DATE_FORMAT_INFORMAL }
};
/*
@ -236,7 +205,7 @@ typedef struct
* PREFERENCE_BOOLEAN
* PREFERENCE_INTEGER
* PREFERENCE_STRING
* PREFERENCE_STRING_LIST
* PREFERENCE_STRING_ARRAY
*
* 3. fallback_value
* Emergency fallback value if our gconf schemas are hosed somehow.
@ -348,7 +317,7 @@ static const PreferenceDefault preference_defaults[] = {
"search_bar_type"
},
{ NAUTILUS_PREFERENCES_ICON_VIEW_CAPTIONS,
PREFERENCE_STRING_LIST,
PREFERENCE_STRING_ARRAY,
"size,date_modified,type",
NULL, NULL,
NULL
@ -566,14 +535,47 @@ global_preferences_register_enumerations (void)
{
guint i;
/* Register the enumerations */
eel_enumeration_register (enumerations);
/* Register the enumerations.
* These enumerations are used in the preferences dialog to
* populate widgets and route preferences changes between the
* storage (GConf) and the displayed values.
*/
eel_enumeration_register ("click_policy",
click_policy_enum_entries,
G_N_ELEMENTS (click_policy_enum_entries));
eel_enumeration_register ("default_folder_viewer",
default_folder_viewer_enum_entries,
G_N_ELEMENTS (default_folder_viewer_enum_entries));
eel_enumeration_register ("default_icon_view_sort_order",
default_icon_view_sort_order_enum_entries,
G_N_ELEMENTS (default_icon_view_sort_order_enum_entries));
eel_enumeration_register ("default_zoom_level",
default_zoom_level_enum_entries,
G_N_ELEMENTS (default_zoom_level_enum_entries));
eel_enumeration_register ("executable_text_activation",
executable_text_activation_enum_entries,
G_N_ELEMENTS (executable_text_activation_enum_entries));
eel_enumeration_register ("file_size",
file_size_enum_entries,
G_N_ELEMENTS (file_size_enum_entries));
eel_enumeration_register ("search_bar_type",
search_bar_type_enum_entries,
G_N_ELEMENTS (search_bar_type_enum_entries));
eel_enumeration_register ("speed_tradeoff",
speed_tradeoff_enum_entries,
G_N_ELEMENTS (speed_tradeoff_enum_entries));
eel_enumeration_register ("standard_font_size",
standard_font_size_entries,
G_N_ELEMENTS (standard_font_size_entries));
eel_enumeration_register ("date_format",
date_format_entries,
G_N_ELEMENTS (date_format_entries));
/* Set the enumeration ids for preferences that need them */
for (i = 0; preference_defaults[i].name != NULL; i++) {
if (eel_strlen (preference_defaults[i].enumeration_id) > 0) {
g_assert (preference_defaults[i].type == PREFERENCE_STRING
|| preference_defaults[i].type == PREFERENCE_STRING_LIST
|| preference_defaults[i].type == PREFERENCE_STRING_ARRAY
|| preference_defaults[i].type == PREFERENCE_INTEGER);
eel_preferences_set_enumeration_id (preference_defaults[i].name,
preference_defaults[i].enumeration_id);
@ -587,11 +589,11 @@ global_preferences_install_one_default (const char *preference_name,
const PreferenceDefault *preference_default)
{
gpointer value = NULL;
EelStringList *string_list_value;
char **string_array_value;
g_return_if_fail (preference_name != NULL);
g_return_if_fail (preference_type >= PREFERENCE_BOOLEAN);
g_return_if_fail (preference_type <= PREFERENCE_STRING_LIST);
g_return_if_fail (preference_type <= PREFERENCE_STRING_ARRAY);
g_return_if_fail (preference_default != NULL);
/* If a callback is given, use that to fetch the default value */
@ -617,14 +619,14 @@ global_preferences_install_one_default (const char *preference_name,
eel_preferences_set_emergency_fallback_string (preference_name,
value);
break;
case PREFERENCE_STRING_LIST:
string_list_value = eel_string_list_new_from_tokens (value,
STRING_LIST_DEFAULT_TOKENS_DELIMETER,
TRUE);
eel_preferences_set_emergency_fallback_string_list (preference_name,
string_list_value);
eel_string_list_free (string_list_value);
case PREFERENCE_STRING_ARRAY:
string_array_value = g_strsplit (value,
STRING_ARRAY_DEFAULT_TOKENS_DELIMETER,
-1);
eel_preferences_set_emergency_fallback_string_array (preference_name,
string_array_value);
g_strfreev (string_array_value);
break;
default:

View file

@ -30,7 +30,6 @@
#include "nautilus-file-utilities.h"
#include "nautilus-global-preferences.h"
#include "nautilus-icon-factory.h"
#include "nautilus-icon-private.h"
#include <eel/eel-art-extensions.h>
#include <eel/eel-gdk-extensions.h>
@ -45,10 +44,6 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gtk/gtksignal.h>
#include <gdk/gdk.h>
#include <libart_lgpl/art_rgb.h>
#include <libart_lgpl/art_rgb_affine.h>
#include <libart_lgpl/art_rgb_rgba_affine.h>
#include <libart_lgpl/art_svp_vpath.h>
#include <librsvg/rsvg.h>
#include <glib/gi18n.h>
#include <eel/eel-canvas-util.h>
@ -77,7 +72,8 @@ struct NautilusIconCanvasItemDetails {
GList *emblem_pixbufs;
char *editable_text; /* Text that can be modified by a renaming function */
char *additional_text; /* Text that cannot be modifed, such as file size, etc. */
NautilusEmblemAttachPoints *attach_points;
GdkPoint *attach_points;
int n_attach_points;
/* Size of the text at current font. */
int text_dx;
@ -115,11 +111,11 @@ struct NautilusIconCanvasItemDetails {
PangoLayout *embedded_text_layout;
/* Cached rectangle in canvas coordinates */
ArtIRect canvas_rect;
ArtIRect text_rect;
ArtIRect emblem_rect;
EelIRect canvas_rect;
EelIRect text_rect;
EelIRect emblem_rect;
ArtIRect bounds_cache;
EelIRect bounds_cache;
/* Accessibility bits */
GailTextUtil *text_util;
@ -161,7 +157,7 @@ typedef struct {
typedef struct {
NautilusIconCanvasItem *icon_item;
ArtIRect icon_rect;
EelIRect icon_rect;
RectangleSide side;
int position;
int index;
@ -178,21 +174,21 @@ static void nautilus_icon_canvas_item_init (NautilusIconCanvasItem
static void draw_or_measure_label_text (NautilusIconCanvasItem *item,
GdkDrawable *drawable,
gboolean create_mask,
ArtIRect icon_rect);
EelIRect icon_rect);
static void draw_label_text (NautilusIconCanvasItem *item,
GdkDrawable *drawable,
gboolean create_mask,
ArtIRect icon_rect);
EelIRect icon_rect);
static void measure_label_text (NautilusIconCanvasItem *item);
static void get_icon_canvas_rectangle (NautilusIconCanvasItem *item,
ArtIRect *rect);
EelIRect *rect);
static void emblem_layout_reset (EmblemLayout *layout,
NautilusIconCanvasItem *icon_item,
ArtIRect icon_rect,
EelIRect icon_rect,
gboolean is_rtl);
static gboolean emblem_layout_next (EmblemLayout *layout,
GdkPixbuf **emblem_pixbuf,
ArtIRect *emblem_rect,
EelIRect *emblem_rect,
gboolean is_rtl);
static void draw_pixbuf (GdkPixbuf *pixbuf,
GdkDrawable *drawable,
@ -210,7 +206,7 @@ static void draw_label_layout (NautilusIconCanvasItem
int y,
GdkGC *gc);
static gboolean hit_test_stretch_handle (NautilusIconCanvasItem *item,
ArtIRect canvas_rect,
EelIRect canvas_rect,
GtkCornerType *corner);
static void draw_embedded_text (NautilusIconCanvasItem *icon_item,
GdkDrawable *drawable,
@ -467,8 +463,8 @@ nautilus_icon_canvas_item_get_image (NautilusIconCanvasItem *item,
GdkGC *gc;
int width, height;
int item_offset_x, item_offset_y;
ArtIRect icon_rect;
ArtIRect emblem_rect;
EelIRect icon_rect;
EelIRect emblem_rect;
GdkPixbuf *pixbuf;
GdkPixbuf *emblem_pixbuf;
EmblemLayout emblem_layout;
@ -635,14 +631,16 @@ nautilus_icon_canvas_item_set_emblems (NautilusIconCanvasItem *item,
void
nautilus_icon_canvas_item_set_attach_points (NautilusIconCanvasItem *item,
NautilusEmblemAttachPoints *attach_points)
GdkPoint *attach_points,
int n_attach_points)
{
g_free (item->details->attach_points);
item->details->attach_points = NULL;
item->details->n_attach_points = 0;
if (attach_points != NULL && attach_points->num_points != 0) {
item->details->attach_points = g_new (NautilusEmblemAttachPoints, 1);
*item->details->attach_points = *attach_points;
if (attach_points != NULL && n_attach_points != 0) {
item->details->attach_points = g_memdup (attach_points, n_attach_points * sizeof (GdkPoint));
item->details->n_attach_points = n_attach_points;
}
nautilus_icon_canvas_item_invalidate_bounds_cache (item);
@ -691,7 +689,7 @@ recompute_bounding_box (NautilusIconCanvasItem *icon_item,
*/
EelCanvasItem *item;
ArtPoint top_left, bottom_right;
EelDPoint top_left, bottom_right;
item = EEL_CANVAS_ITEM (icon_item);
@ -711,12 +709,12 @@ recompute_bounding_box (NautilusIconCanvasItem *icon_item,
&item->x2, &item->y2);
}
static ArtIRect
static EelIRect
compute_text_rectangle (const NautilusIconCanvasItem *item,
ArtIRect icon_rectangle,
EelIRect icon_rectangle,
gboolean canvas_coords)
{
ArtIRect text_rectangle;
EelIRect text_rectangle;
double pixels_per_unit;
double text_width, text_height, text_dx;
@ -751,12 +749,12 @@ compute_text_rectangle (const NautilusIconCanvasItem *item,
return text_rectangle;
}
static ArtIRect
static EelIRect
get_current_canvas_bounds (EelCanvasItem *item)
{
ArtIRect bounds;
EelIRect bounds;
g_return_val_if_fail (EEL_IS_CANVAS_ITEM (item), eel_art_irect_empty);
g_return_val_if_fail (EEL_IS_CANVAS_ITEM (item), eel_irect_empty);
bounds.x0 = item->x1;
bounds.y0 = item->y1;
@ -770,7 +768,7 @@ void
nautilus_icon_canvas_item_update_bounds (NautilusIconCanvasItem *item,
double i2w_dx, double i2w_dy)
{
ArtIRect before, after, emblem_rect;
EelIRect before, after, emblem_rect;
EmblemLayout emblem_layout;
EelCanvasItem *canvas_item;
GdkPixbuf *emblem_pixbuf;
@ -784,7 +782,7 @@ nautilus_icon_canvas_item_update_bounds (NautilusIconCanvasItem *item,
after = get_current_canvas_bounds (canvas_item);
/* If the bounds didn't change, we are done. */
if (eel_art_irect_equal (before, after)) {
if (eel_irect_equal (before, after)) {
return;
}
@ -801,7 +799,7 @@ nautilus_icon_canvas_item_update_bounds (NautilusIconCanvasItem *item,
item->details->emblem_rect.y1 = 0;
emblem_layout_reset (&emblem_layout, item, item->details->canvas_rect, is_rtl);
while (emblem_layout_next (&emblem_layout, &emblem_pixbuf, &emblem_rect, is_rtl)) {
art_irect_union (&item->details->emblem_rect, &item->details->emblem_rect, &emblem_rect);
eel_irect_union (&item->details->emblem_rect, &item->details->emblem_rect, &emblem_rect);
}
/* queue a redraw. */
@ -947,7 +945,7 @@ static void
draw_or_measure_label_text (NautilusIconCanvasItem *item,
GdkDrawable *drawable,
gboolean create_mask,
ArtIRect icon_rect)
EelIRect icon_rect)
{
NautilusIconCanvasItemDetails *details;
NautilusIconContainer *container;
@ -962,7 +960,7 @@ draw_or_measure_label_text (NautilusIconCanvasItem *item,
int max_text_width;
int x;
GdkGC *gc;
ArtIRect text_rect;
EelIRect text_rect;
int text_back_padding_x, text_back_padding_y;
icon_width = 0;
@ -1166,7 +1164,7 @@ draw_or_measure_label_text (NautilusIconCanvasItem *item,
static void
measure_label_text (NautilusIconCanvasItem *item)
{
ArtIRect rect = {0, };
EelIRect rect = {0, };
/* check to see if the cached values are still valid; if so, there's
* no work necessary
@ -1181,7 +1179,7 @@ measure_label_text (NautilusIconCanvasItem *item)
static void
draw_label_text (NautilusIconCanvasItem *item, GdkDrawable *drawable,
gboolean create_mask, ArtIRect icon_rect)
gboolean create_mask, EelIRect icon_rect)
{
draw_or_measure_label_text (item, drawable, create_mask, icon_rect);
}
@ -1232,7 +1230,7 @@ get_knob_pixbuf (void)
static void
draw_stretch_handles (NautilusIconCanvasItem *item, GdkDrawable *drawable,
const ArtIRect *rect)
const EelIRect *rect)
{
GtkWidget *widget;
GdkGC *gc;
@ -1285,7 +1283,7 @@ draw_stretch_handles (NautilusIconCanvasItem *item, GdkDrawable *drawable,
}
static void
emblem_layout_reset (EmblemLayout *layout, NautilusIconCanvasItem *icon_item, ArtIRect icon_rect, gboolean is_rtl)
emblem_layout_reset (EmblemLayout *layout, NautilusIconCanvasItem *icon_item, EelIRect icon_rect, gboolean is_rtl)
{
layout->icon_item = icon_item;
layout->icon_rect = icon_rect;
@ -1298,12 +1296,12 @@ emblem_layout_reset (EmblemLayout *layout, NautilusIconCanvasItem *icon_item, Ar
static gboolean
emblem_layout_next (EmblemLayout *layout,
GdkPixbuf **emblem_pixbuf,
ArtIRect *emblem_rect,
EelIRect *emblem_rect,
gboolean is_rtl)
{
GdkPixbuf *pixbuf;
int width, height, x, y;
NautilusEmblemAttachPoints *attach_points;
GdkPoint *attach_points;
/* Check if we have layed out all of the pixbufs. */
if (layout->emblem == NULL) {
@ -1321,12 +1319,12 @@ emblem_layout_next (EmblemLayout *layout,
attach_points = layout->icon_item->details->attach_points;
if (attach_points != NULL) {
if (layout->index >= attach_points->num_points) {
if (layout->index >= layout->icon_item->details->n_attach_points) {
return FALSE;
}
x = layout->icon_rect.x0 + attach_points->points[layout->index].x;
y = layout->icon_rect.y0 + attach_points->points[layout->index].y;
x = layout->icon_rect.x0 + attach_points[layout->index].x;
y = layout->icon_rect.y0 + attach_points[layout->index].y;
layout->index += 1;
@ -1602,9 +1600,9 @@ real_map_pixbuf (NautilusIconCanvasItem *icon_item)
audio_filename = nautilus_pixmap_file ("audio.svg");
if (audio_filename != NULL) {
audio_pixbuf = rsvg_pixbuf_from_file_at_zoom_with_max (audio_filename, zoom, zoom,
NAUTILUS_ICON_MAXIMUM_SIZE,
NAUTILUS_ICON_MAXIMUM_SIZE,
NULL);
NAUTILUS_ICON_MAXIMUM_SIZE,
NAUTILUS_ICON_MAXIMUM_SIZE,
NULL);
} else {
audio_pixbuf = NULL;
}
@ -1754,7 +1752,7 @@ nautilus_icon_canvas_item_draw (EelCanvasItem *item, GdkDrawable *drawable,
{
NautilusIconCanvasItem *icon_item;
NautilusIconCanvasItemDetails *details;
ArtIRect icon_rect, emblem_rect;
EelIRect icon_rect, emblem_rect;
EmblemLayout emblem_layout;
GdkPixbuf *emblem_pixbuf, *temp_pixbuf;
GdkRectangle draw_rect, pixbuf_rect;
@ -2017,9 +2015,9 @@ nautilus_icon_canvas_item_event (EelCanvasItem *item, GdkEvent *event)
}
static gboolean
hit_test_pixbuf (GdkPixbuf *pixbuf, ArtIRect pixbuf_location, ArtIRect probe_rect)
hit_test_pixbuf (GdkPixbuf *pixbuf, EelIRect pixbuf_location, EelIRect probe_rect)
{
ArtIRect relative_rect, pixbuf_rect;
EelIRect relative_rect, pixbuf_rect;
int x, y;
guint8 *pixel;
@ -2037,8 +2035,8 @@ hit_test_pixbuf (GdkPixbuf *pixbuf, ArtIRect pixbuf_location, ArtIRect probe_rec
pixbuf_rect.y0 = 0;
pixbuf_rect.x1 = gdk_pixbuf_get_width (pixbuf);
pixbuf_rect.y1 = gdk_pixbuf_get_height (pixbuf);
art_irect_intersect (&relative_rect, &relative_rect, &pixbuf_rect);
if (art_irect_empty (&relative_rect)) {
eel_irect_intersect (&relative_rect, &relative_rect, &pixbuf_rect);
if (eel_irect_is_empty (&relative_rect)) {
return FALSE;
}
@ -2063,10 +2061,10 @@ hit_test_pixbuf (GdkPixbuf *pixbuf, ArtIRect pixbuf_location, ArtIRect probe_rec
}
static gboolean
hit_test (NautilusIconCanvasItem *icon_item, ArtIRect canvas_rect)
hit_test (NautilusIconCanvasItem *icon_item, EelIRect canvas_rect)
{
NautilusIconCanvasItemDetails *details;
ArtIRect emblem_rect;
EelIRect emblem_rect;
EmblemLayout emblem_layout;
GdkPixbuf *emblem_pixbuf;
gboolean is_rtl;
@ -2074,9 +2072,9 @@ hit_test (NautilusIconCanvasItem *icon_item, ArtIRect canvas_rect)
details = icon_item->details;
/* Quick check to see if the rect hits the icon, text or emblems at all. */
if (!eel_art_irect_hits_irect (icon_item->details->canvas_rect, canvas_rect)
&& (!eel_art_irect_hits_irect (details->text_rect, canvas_rect))
&& (!eel_art_irect_hits_irect (details->emblem_rect, canvas_rect))) {
if (!eel_irect_hits_irect (icon_item->details->canvas_rect, canvas_rect)
&& (!eel_irect_hits_irect (details->text_rect, canvas_rect))
&& (!eel_irect_hits_irect (details->emblem_rect, canvas_rect))) {
return FALSE;
}
@ -2086,12 +2084,12 @@ hit_test (NautilusIconCanvasItem *icon_item, ArtIRect canvas_rect)
}
/* Check for hit in the icon. */
if (eel_art_irect_hits_irect (icon_item->details->canvas_rect, canvas_rect)) {
if (eel_irect_hits_irect (icon_item->details->canvas_rect, canvas_rect)) {
return TRUE;
}
/* Check for hit in the text. */
if (eel_art_irect_hits_irect (details->text_rect, canvas_rect)
if (eel_irect_hits_irect (details->text_rect, canvas_rect)
&& !icon_item->details->is_renaming) {
return TRUE;
}
@ -2114,7 +2112,7 @@ static double
nautilus_icon_canvas_item_point (EelCanvasItem *item, double x, double y, int cx, int cy,
EelCanvasItem **actual_item)
{
ArtIRect canvas_rect;
EelIRect canvas_rect;
*actual_item = item;
canvas_rect.x0 = cx;
@ -2151,7 +2149,7 @@ nautilus_icon_canvas_item_bounds (EelCanvasItem *item,
{
NautilusIconCanvasItem *icon_item;
NautilusIconCanvasItemDetails *details;
ArtIRect icon_rect, text_rect, total_rect, emblem_rect;
EelIRect icon_rect, text_rect, total_rect, emblem_rect;
double pixels_per_unit;
EmblemLayout emblem_layout;
GdkPixbuf *emblem_pixbuf;
@ -2189,7 +2187,7 @@ nautilus_icon_canvas_item_bounds (EelCanvasItem *item,
is_rtl = nautilus_icon_container_is_layout_rtl (NAUTILUS_ICON_CONTAINER (item->canvas));
/* Compute total rectangle, adding in emblem rectangles. */
art_irect_union (&total_rect, &icon_rect, &text_rect);
eel_irect_union (&total_rect, &icon_rect, &text_rect);
emblem_layout_reset (&emblem_layout, icon_item, icon_rect, is_rtl);
while (emblem_layout_next (&emblem_layout, &emblem_pixbuf, &emblem_rect, is_rtl)) {
emblem_rect.x0 = floor (emblem_rect.x0 / pixels_per_unit);
@ -2197,7 +2195,7 @@ nautilus_icon_canvas_item_bounds (EelCanvasItem *item,
emblem_rect.x1 = ceil (emblem_rect.x1 / pixels_per_unit);
emblem_rect.y1 = ceil (emblem_rect.y1 / pixels_per_unit);
art_irect_union (&total_rect, &total_rect, &emblem_rect);
eel_irect_union (&total_rect, &total_rect, &emblem_rect);
}
details->bounds_cache = total_rect;
@ -2212,14 +2210,14 @@ nautilus_icon_canvas_item_bounds (EelCanvasItem *item,
}
/* Get the rectangle of the icon only, in world coordinates. */
ArtDRect
EelDRect
nautilus_icon_canvas_item_get_icon_rectangle (const NautilusIconCanvasItem *item)
{
ArtDRect rectangle;
EelDRect rectangle;
double pixels_per_unit;
GdkPixbuf *pixbuf;
g_return_val_if_fail (NAUTILUS_IS_ICON_CANVAS_ITEM (item), eel_art_drect_empty);
g_return_val_if_fail (NAUTILUS_IS_ICON_CANVAS_ITEM (item), eel_drect_empty);
rectangle.x0 = item->details->x;
rectangle.y0 = item->details->y;
@ -2240,17 +2238,17 @@ nautilus_icon_canvas_item_get_icon_rectangle (const NautilusIconCanvasItem *item
return rectangle;
}
ArtDRect
EelDRect
nautilus_icon_canvas_item_get_text_rectangle (NautilusIconCanvasItem *item)
{
/* FIXME */
ArtIRect icon_rectangle;
ArtIRect text_rectangle;
ArtDRect ret;
EelIRect icon_rectangle;
EelIRect text_rectangle;
EelDRect ret;
double pixels_per_unit;
GdkPixbuf *pixbuf;
g_return_val_if_fail (NAUTILUS_IS_ICON_CANVAS_ITEM (item), eel_art_drect_empty);
g_return_val_if_fail (NAUTILUS_IS_ICON_CANVAS_ITEM (item), eel_drect_empty);
icon_rectangle.x0 = item->details->x;
icon_rectangle.y0 = item->details->y;
@ -2283,7 +2281,7 @@ nautilus_icon_canvas_item_get_text_rectangle (NautilusIconCanvasItem *item)
/* Get the rectangle of the icon only, in canvas coordinates. */
static void
get_icon_canvas_rectangle (NautilusIconCanvasItem *item,
ArtIRect *rect)
EelIRect *rect)
{
GdkPixbuf *pixbuf;
@ -2320,10 +2318,10 @@ nautilus_icon_canvas_item_set_show_stretch_handles (NautilusIconCanvasItem *item
/* Check if one of the stretch handles was hit. */
static gboolean
hit_test_stretch_handle (NautilusIconCanvasItem *item,
ArtIRect probe_canvas_rect,
EelIRect probe_canvas_rect,
GtkCornerType *corner)
{
ArtIRect icon_rect;
EelIRect icon_rect;
GdkPixbuf *knob_pixbuf;
int knob_width, knob_height;
int hit_corner;
@ -2337,7 +2335,7 @@ hit_test_stretch_handle (NautilusIconCanvasItem *item,
/* Quick check to see if the rect hits the icon at all. */
icon_rect = item->details->canvas_rect;
if (!eel_art_irect_hits_irect (probe_canvas_rect, icon_rect)) {
if (!eel_irect_hits_irect (probe_canvas_rect, icon_rect)) {
return FALSE;
}
@ -2368,10 +2366,10 @@ hit_test_stretch_handle (NautilusIconCanvasItem *item,
gboolean
nautilus_icon_canvas_item_hit_test_stretch_handles (NautilusIconCanvasItem *item,
ArtPoint world_point,
EelDPoint world_point,
GtkCornerType *corner)
{
ArtIRect canvas_rect;
EelIRect canvas_rect;
g_return_val_if_fail (NAUTILUS_IS_ICON_CANVAS_ITEM (item), FALSE);
@ -2391,7 +2389,7 @@ nautilus_icon_canvas_item_hit_test_stretch_handles (NautilusIconCanvasItem *item
* canvas rect.
*/
gboolean
nautilus_icon_canvas_item_hit_test_rectangle (NautilusIconCanvasItem *item, ArtIRect canvas_rect)
nautilus_icon_canvas_item_hit_test_rectangle (NautilusIconCanvasItem *item, EelIRect canvas_rect)
{
g_return_val_if_fail (NAUTILUS_IS_ICON_CANVAS_ITEM (item), FALSE);

View file

@ -25,10 +25,8 @@
#ifndef NAUTILUS_ICON_CANVAS_ITEM_H
#define NAUTILUS_ICON_CANVAS_ITEM_H
#include <libart_lgpl/art_rect.h>
#include <libart_lgpl/art_point.h>
#include <eel/eel-canvas.h>
#include <libnautilus-private/nautilus-icon-factory.h>
#include <eel/eel-art-extensions.h>
G_BEGIN_DECLS
@ -70,7 +68,8 @@ void nautilus_icon_canvas_item_set_emblems (NautilusIconCanv
void nautilus_icon_canvas_item_set_show_stretch_handles (NautilusIconCanvasItem *item,
gboolean show_stretch_handles);
void nautilus_icon_canvas_item_set_attach_points (NautilusIconCanvasItem *item,
NautilusEmblemAttachPoints *attach_points);
GdkPoint *attach_points,
int n_attach_points);
void nautilus_icon_canvas_item_set_embedded_text_rect (NautilusIconCanvasItem *item,
const GdkRectangle *text_rect);
void nautilus_icon_canvas_item_set_embedded_text (NautilusIconCanvasItem *item,
@ -82,13 +81,13 @@ void nautilus_icon_canvas_item_set_renaming (NautilusIconCanv
/* geometry and hit testing */
gboolean nautilus_icon_canvas_item_hit_test_rectangle (NautilusIconCanvasItem *item,
ArtIRect canvas_rect);
EelIRect canvas_rect);
gboolean nautilus_icon_canvas_item_hit_test_stretch_handles (NautilusIconCanvasItem *item,
ArtPoint world_point,
GtkCornerType *corner);
EelDPoint world_point,
GtkCornerType *corner);
void nautilus_icon_canvas_item_invalidate_label_size (NautilusIconCanvasItem *item);
ArtDRect nautilus_icon_canvas_item_get_icon_rectangle (const NautilusIconCanvasItem *item);
ArtDRect nautilus_icon_canvas_item_get_text_rectangle (NautilusIconCanvasItem *item);
EelDRect nautilus_icon_canvas_item_get_icon_rectangle (const NautilusIconCanvasItem *item);
EelDRect nautilus_icon_canvas_item_get_text_rectangle (NautilusIconCanvasItem *item);
void nautilus_icon_canvas_item_update_bounds (NautilusIconCanvasItem *item,
double i2w_dx, double i2w_dy);
void nautilus_icon_canvas_item_set_is_visible (NautilusIconCanvasItem *item,

View file

@ -41,6 +41,7 @@
#include <eel/eel-gdk-pixbuf-extensions.h>
#include <eel/eel-gnome-extensions.h>
#include <eel/eel-gtk-extensions.h>
#include <eel/eel-art-extensions.h>
#include <eel/eel-editable-label.h>
#include <eel/eel-marshal.h>
#include <eel/eel-string.h>
@ -299,7 +300,7 @@ icon_set_position (NautilusIcon *icon,
int left, top, right, bottom;
int width;
int container_x, container_y, container_width, container_height;
ArtDRect icon_bounds;
EelDRect icon_bounds;
if (icon->x == x && icon->y == y) {
return;
@ -585,9 +586,9 @@ set_pending_icon_to_reveal (NautilusIconContainer *container, NautilusIcon *icon
}
static void
item_get_canvas_bounds (EelCanvasItem *item, ArtIRect *bounds)
item_get_canvas_bounds (EelCanvasItem *item, EelIRect *bounds)
{
ArtDRect world_rect;
EelDRect world_rect;
eel_canvas_item_get_bounds (item,
&world_rect.x0,
@ -619,7 +620,7 @@ reveal_icon (NautilusIconContainer *container,
NautilusIconContainerDetails *details;
GtkAllocation *allocation;
GtkAdjustment *hadj, *vadj;
ArtIRect bounds;
EelIRect bounds;
if (!icon_is_positioned (icon)) {
set_pending_icon_to_reveal (container, icon);
@ -1008,9 +1009,9 @@ lay_down_icons_horizontal (NautilusIconContainer *container,
double canvas_width, y, canvas_height;
GArray *positions;
IconPositions *position;
ArtDRect bounds;
ArtDRect icon_bounds;
ArtDRect text_bounds;
EelDRect bounds;
EelDRect icon_bounds;
EelDRect text_bounds;
EelCanvasItem *item;
double max_height_above, max_height_below;
double height_above, height_below;
@ -1168,7 +1169,7 @@ snap_position (NautilusIconContainer *container,
int baseline_y;
int icon_width;
int icon_height;
ArtDRect icon_position;
EelDRect icon_position;
icon_position = nautilus_icon_canvas_item_get_icon_rectangle (icon->item);
icon_width = icon_position.x1 - icon_position.x0;
@ -1263,7 +1264,7 @@ placement_grid_free (PlacementGrid *grid)
}
static gboolean
placement_grid_position_is_free (PlacementGrid *grid, ArtIRect pos)
placement_grid_position_is_free (PlacementGrid *grid, EelIRect pos)
{
int x, y;
@ -1284,7 +1285,7 @@ placement_grid_position_is_free (PlacementGrid *grid, ArtIRect pos)
}
static void
placement_grid_mark (PlacementGrid *grid, ArtIRect pos)
placement_grid_mark (PlacementGrid *grid, EelIRect pos)
{
int x, y;
@ -1302,8 +1303,8 @@ placement_grid_mark (PlacementGrid *grid, ArtIRect pos)
static void
canvas_position_to_grid_position (PlacementGrid *grid,
ArtIRect canvas_position,
ArtIRect *grid_position)
EelIRect canvas_position,
EelIRect *grid_position)
{
/* The first causes minimal moving around during a snap, but
* can end up with partially overlapping icons. The second one won't
@ -1330,8 +1331,8 @@ canvas_position_to_grid_position (PlacementGrid *grid,
static void
placement_grid_mark_icon (PlacementGrid *grid, NautilusIcon *icon)
{
ArtIRect icon_pos;
ArtIRect grid_pos;
EelIRect icon_pos;
EelIRect grid_pos;
icon_get_bounding_box (icon,
&icon_pos.x0, &icon_pos.y0,
@ -1354,8 +1355,8 @@ find_empty_location (NautilusIconContainer *container,
double icon_width, icon_height;
int canvas_width;
int canvas_height;
ArtIRect icon_position;
ArtDRect pixbuf_rect;
EelIRect icon_position;
EelDRect pixbuf_rect;
gboolean collision;
/* Get container dimensions */
@ -1379,7 +1380,7 @@ find_empty_location (NautilusIconContainer *container,
icon_position.y1 = icon_position.y0 + icon_height;
do {
ArtIRect grid_position;
EelIRect grid_position;
collision = FALSE;
@ -1458,9 +1459,10 @@ align_icons (NautilusIconContainer *container)
}
static double
get_mirror_x_position (NautilusIconContainer *container, NautilusIcon *icon, double x) {
ArtDRect icon_bounds;
get_mirror_x_position (NautilusIconContainer *container, NautilusIcon *icon, double x)
{
EelDRect icon_bounds;
icon_bounds = nautilus_icon_canvas_item_get_icon_rectangle (icon->item);
return CANVAS_WIDTH(container) - x - (icon_bounds.x1 - icon_bounds.x0);
@ -1492,7 +1494,7 @@ lay_down_icons_vertical (NautilusIconContainer *container, GList *icons)
NautilusIcon *icon;
int width, height, max_width, column_width, icon_width, icon_height;
int x, y, x1, x2, y1, y2;
ArtDRect icon_rect;
EelDRect icon_rect;
/* Get container dimensions */
width = CANVAS_WIDTH(container);
@ -1746,7 +1748,7 @@ reload_icon_positions (NautilusIconContainer *container)
NautilusIcon *icon;
gboolean have_stored_position;
NautilusIconPosition position;
ArtDRect bounds;
EelDRect bounds;
double bottom;
EelCanvasItem *item;
@ -1961,13 +1963,13 @@ nautilus_icon_container_move_icon (NautilusIconContainer *container,
/* Implementation of rubberband selection. */
static void
rubberband_select (NautilusIconContainer *container,
const ArtDRect *previous_rect,
const ArtDRect *current_rect)
const EelDRect *previous_rect,
const EelDRect *current_rect)
{
GList *p;
gboolean selection_changed, is_in, canvas_rect_calculated;
NautilusIcon *icon;
ArtIRect canvas_rect;
EelIRect canvas_rect;
EelCanvas *canvas;
selection_changed = FALSE;
@ -2022,7 +2024,7 @@ rubberband_timeout_callback (gpointer data)
int adj_y;
gboolean adj_changed;
ArtDRect selection_rect;
EelDRect selection_rect;
widget = GTK_WIDGET (data);
container = NAUTILUS_ICON_CONTAINER (data);
@ -2301,7 +2303,7 @@ compare_icons_by_uri (NautilusIconContainer *container,
static int
get_cmp_point_x (NautilusIconContainer *container,
ArtDRect icon_rect)
EelDRect icon_rect)
{
if (container->details->label_position == NAUTILUS_ICON_LABEL_POSITION_BESIDE) {
if (gtk_widget_get_direction (GTK_WIDGET (container)) == GTK_TEXT_DIR_RTL) {
@ -2316,7 +2318,7 @@ get_cmp_point_x (NautilusIconContainer *container,
static int
get_cmp_point_y (NautilusIconContainer *container,
ArtDRect icon_rect)
EelDRect icon_rect)
{
if (container->details->label_position == NAUTILUS_ICON_LABEL_POSITION_BESIDE) {
return (icon_rect.y0 + icon_rect.y1)/2;
@ -2330,7 +2332,7 @@ compare_icons_horizontal_first (NautilusIconContainer *container,
NautilusIcon *icon_a,
NautilusIcon *icon_b)
{
ArtDRect world_rect;
EelDRect world_rect;
int ax, ay, bx, by;
world_rect = nautilus_icon_canvas_item_get_icon_rectangle (icon_a->item);
@ -2368,7 +2370,7 @@ compare_icons_vertical_first_reverse_horizontal (NautilusIconContainer *containe
NautilusIcon *icon_a,
NautilusIcon *icon_b)
{
ArtDRect world_rect;
EelDRect world_rect;
int ax, ay, bx, by;
world_rect = nautilus_icon_canvas_item_get_icon_rectangle (icon_a->item);
@ -2407,7 +2409,7 @@ compare_icons_vertical_first (NautilusIconContainer *container,
NautilusIcon *icon_a,
NautilusIcon *icon_b)
{
ArtDRect world_rect;
EelDRect world_rect;
int ax, ay, bx, by;
world_rect = nautilus_icon_canvas_item_get_icon_rectangle (icon_a->item);
@ -2631,7 +2633,7 @@ closest_in_90_degrees (NautilusIconContainer *container,
NautilusIcon *candidate,
void *data)
{
ArtDRect world_rect;
EelDRect world_rect;
int x, y;
int dx, dy;
int dist;
@ -2694,13 +2696,13 @@ closest_in_90_degrees (NautilusIconContainer *container,
return FALSE;
}
static ArtDRect
static EelDRect
get_rubberband (NautilusIcon *icon1,
NautilusIcon *icon2)
{
ArtDRect rect1;
ArtDRect rect2;
ArtDRect ret;
EelDRect rect1;
EelDRect rect2;
EelDRect ret;
eel_canvas_item_get_bounds (EEL_CANVAS_ITEM (icon1->item),
&rect1.x0, &rect1.y0,
@ -2709,7 +2711,7 @@ get_rubberband (NautilusIcon *icon1,
&rect2.x0, &rect2.y0,
&rect2.x1, &rect2.y1);
art_drect_union (&ret, &rect1, &rect2);
eel_drect_union (&ret, &rect1, &rect2);
return ret;
}
@ -2732,7 +2734,7 @@ keyboard_move_to (NautilusIconContainer *container,
container->details->keyboard_rubberband_start = NULL;
} else if ((event->state & GDK_SHIFT_MASK) != 0) {
/* Do rubberband selection */
ArtDRect rect;
EelDRect rect;
if (from && !container->details->keyboard_rubberband_start) {
set_keyboard_rubberband_start (container, from);
@ -2804,7 +2806,7 @@ record_arrow_key_start (NautilusIconContainer *container,
NautilusIcon *icon,
GtkDirectionType direction)
{
ArtDRect world_rect;
EelDRect world_rect;
world_rect = nautilus_icon_canvas_item_get_icon_rectangle (icon->item);
eel_canvas_w2c
@ -3420,7 +3422,7 @@ start_stretching (NautilusIconContainer *container)
{
NautilusIconContainerDetails *details;
NautilusIcon *icon;
ArtPoint world_point;
EelDPoint world_point;
GtkWidget *toplevel;
GtkCornerType corner;
GdkCursor *cursor;
@ -5095,13 +5097,6 @@ nautilus_icon_container_instance_init (NautilusIconContainer *container)
container->details = details;
/* Make sure that we find out if the icons change. */
g_signal_connect_object
(nautilus_icon_factory_get (),
"icons_changed",
G_CALLBACK (nautilus_icon_container_request_update_all),
container, G_CONNECT_SWAPPED);
/* when the background changes, we must set up the label text color */
background = eel_get_widget_background (GTK_WIDGET (container));
@ -5582,11 +5577,13 @@ get_icon_being_renamed (NautilusIconContainer *container)
return rename_icon;
}
static char *
static NautilusIconInfo *
nautilus_icon_container_get_icon_images (NautilusIconContainer *container,
NautilusIconData *data,
GList **emblem_icons,
int size,
GList **emblem_pixbufs,
char **embedded_text,
gboolean for_drag_accept,
gboolean need_large_embeddded_text,
gboolean *embedded_text_needs_loading,
gboolean *has_open_window)
@ -5596,7 +5593,7 @@ nautilus_icon_container_get_icon_images (NautilusIconContainer *container,
klass = NAUTILUS_ICON_CONTAINER_GET_CLASS (container);
g_return_val_if_fail (klass->get_icon_images != NULL, NULL);
return klass->get_icon_images (container, data, emblem_icons, embedded_text, need_large_embeddded_text, embedded_text_needs_loading, has_open_window);
return klass->get_icon_images (container, data, size, emblem_pixbufs, embedded_text, for_drag_accept, need_large_embeddded_text, embedded_text_needs_loading, has_open_window);
}
@ -5732,90 +5729,6 @@ handle_vadjustment_changed (GtkAdjustment *adjustment,
nautilus_icon_container_update_visible_icons (container);
}
/*
* used to resize ICON_NAME_THUMBNAIL_LOADING to the expected thumbnail size.
*/
static void
sanitize_loading_thumbnail_image_size (NautilusIconContainer *container,
const char *mime_type,
GdkPixbuf **image,
NautilusEmblemAttachPoints *attach_points,
GdkRectangle *embedded_text_rect)
{
NautilusIconContainerDetails *details;
double pixels_per_unit;
details = container->details;
pixels_per_unit = (double) nautilus_get_icon_size_for_zoom_level (container->details->zoom_level)
/ NAUTILUS_ICON_SIZE_STANDARD;
if (gdk_pixbuf_get_width (*image) < NAUTILUS_ICON_SIZE_THUMBNAIL * pixels_per_unit &&
gdk_pixbuf_get_height (*image) < NAUTILUS_ICON_SIZE_THUMBNAIL * pixels_per_unit) {
/* TODO? this only handles icons smaller than the expected thumbnail size ATM.
* Should not be a common problem, though */
GdkPixbuf *new_image;
double x_size;
double y_size;
double x_offset;
double y_offset;
int i;
if (g_str_has_prefix (mime_type, "video/")) {
/* assume 4:3 aspect ratio for videos i.e. we'll always occupy the full width. */
x_size = NAUTILUS_ICON_SIZE_THUMBNAIL * pixels_per_unit;
y_size = 3./4 * x_size;
} else {
/* scale up to the max. thumbnail size.
* This is correct at least in one dimension, and prevents the icons from jumping
* around as the thumbnail is created, if it is tall for text below icon, and if it
* is wide for text beside icon.
*/
x_size = NAUTILUS_ICON_SIZE_THUMBNAIL * pixels_per_unit;
y_size = NAUTILUS_ICON_SIZE_THUMBNAIL * pixels_per_unit;
}
/* maybe the estimated size was smaller than the input pixbuf, so size the surrounding
* image up. This only seems to be relevant in the 4:3 case, for y_size.
*/
x_size = MAX (x_size, gdk_pixbuf_get_width (*image));
y_size = MAX (y_size, gdk_pixbuf_get_height (*image));
x_offset = x_size - gdk_pixbuf_get_width (*image);
y_offset = y_size - gdk_pixbuf_get_height (*image);
/* center wrt "minor" dimension, i.e. horizontally for text below
* and vertically for text besides icon */
if (details->label_position == NAUTILUS_ICON_LABEL_POSITION_BESIDE)
y_offset /= 2;
else
x_offset /= 2;
new_image = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE,
gdk_pixbuf_get_bits_per_sample (*image),
x_size, y_size);
gdk_pixbuf_fill (new_image, 0x00000000);
gdk_pixbuf_copy_area (*image,
0, 0,
gdk_pixbuf_get_width (*image),
gdk_pixbuf_get_height (*image),
new_image,
x_offset, y_offset);
g_object_unref (*image);
*image = new_image;
for (i = 0; i < attach_points->num_points; i++) {
attach_points->points[i].x += x_offset;
attach_points->points[i].y += y_offset;
}
embedded_text_rect->x += x_offset;
embedded_text_rect->y += y_offset;
}
}
void
nautilus_icon_container_update_icon (NautilusIconContainer *container,
NautilusIcon *icon)
@ -5823,18 +5736,18 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
NautilusIconContainerDetails *details;
guint icon_size;
guint min_image_size, max_image_size;
char *icon_name;
NautilusEmblemAttachPoints attach_points;
GdkPixbuf *pixbuf, *emblem_pixbuf;
GList *emblem_icon_names, *emblem_pixbufs, *p;
NautilusIconInfo *icon_info;
GdkPoint *attach_points;
int n_attach_points;
gboolean has_embedded_text_rect;
GdkPixbuf *pixbuf;
GList *emblem_pixbufs;
char *editable_text, *additional_text;
char *embedded_text;
guint emblem_size;
GdkRectangle embedded_text_rect;
gboolean large_embedded_text;
gboolean embedded_text_needs_loading;
gboolean has_open_window;
char *modifier;
if (icon == NULL) {
return;
@ -5853,62 +5766,29 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
icon_size = MIN (icon_size, max_image_size);
/* Get the icons. */
emblem_icon_names = NULL;
emblem_pixbufs = NULL;
embedded_text = NULL;
large_embedded_text = icon_size > ICON_SIZE_FOR_LARGE_EMBEDDED_TEXT;
icon_name = nautilus_icon_container_get_icon_images (
container, icon->data,
&emblem_icon_names,
&embedded_text, large_embedded_text, &embedded_text_needs_loading,
&has_open_window);
modifier = NULL;
if (has_open_window) {
modifier = "visiting";
}
if (icon == details->drop_target) {
modifier = "accept";
}
pixbuf = nautilus_icon_factory_get_pixbuf_for_file_with_icon
((NautilusFile *) icon->data,
icon_name,
modifier,
icon_size,
&attach_points,
&embedded_text_rect,
FALSE, TRUE, NULL);
icon_info = nautilus_icon_container_get_icon_images (container, icon->data, icon_size,
&emblem_pixbufs,
&embedded_text,
icon == details->drop_target,
large_embedded_text, &embedded_text_needs_loading,
&has_open_window);
if (embedded_text_rect.width > MINIMUM_EMBEDDED_TEXT_RECT_WIDTH &&
embedded_text_rect.height > MINIMUM_EMBEDDED_TEXT_RECT_HEIGHT &&
embedded_text_needs_loading) {
pixbuf = nautilus_icon_info_get_pixbuf (icon_info);
nautilus_icon_info_get_attach_points (icon_info, &attach_points, &n_attach_points);
has_embedded_text_rect = nautilus_icon_info_get_embedded_rect (icon_info,
&embedded_text_rect);
if (has_embedded_text_rect && embedded_text_needs_loading) {
icon->is_monitored = TRUE;
nautilus_icon_container_start_monitor_top_left (container, icon->data, icon, large_embedded_text);
}
emblem_pixbufs = NULL;
icon_size = MAX (nautilus_get_icon_size_for_zoom_level (container->details->zoom_level)
* icon->scale, NAUTILUS_ICON_SIZE_SMALLEST);
emblem_size = nautilus_icon_factory_get_emblem_size_for_icon_size (icon_size);
if (emblem_size != 0) {
for (p = emblem_icon_names; p != NULL; p = p->next) {
emblem_pixbuf = nautilus_icon_factory_get_pixbuf_for_icon
(p->data,
NULL,
emblem_size,
NULL,
NULL,
FALSE, FALSE, NULL);
if (emblem_pixbuf != NULL) {
emblem_pixbufs = g_list_prepend
(emblem_pixbufs, emblem_pixbuf);
}
}
}
emblem_pixbufs = g_list_reverse (emblem_pixbufs);
eel_g_list_free_deep (emblem_icon_names);
* icon->scale, NAUTILUS_ICON_SIZE_SMALLEST);
nautilus_icon_container_get_icon_text (container,
icon->data,
@ -5932,19 +5812,8 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
"highlighted_for_drop", icon == details->drop_target,
NULL);
if (nautilus_file_is_thumbnailing ((NautilusFile *) icon->data)) {
char* mime_type;
mime_type = nautilus_file_get_mime_type ((NautilusFile *)icon->data);
sanitize_loading_thumbnail_image_size (container,
mime_type,
&pixbuf,
&attach_points,
&embedded_text_rect);
g_free (mime_type);
}
nautilus_icon_canvas_item_set_image (icon->item, pixbuf);
nautilus_icon_canvas_item_set_attach_points (icon->item, &attach_points);
nautilus_icon_canvas_item_set_attach_points (icon->item, attach_points, n_attach_points);
nautilus_icon_canvas_item_set_emblems (icon->item, emblem_pixbufs);
nautilus_icon_canvas_item_set_embedded_text_rect (icon->item, &embedded_text_rect);
nautilus_icon_canvas_item_set_embedded_text (icon->item, embedded_text);
@ -5956,7 +5825,7 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
g_free (editable_text);
g_free (additional_text);
g_free (icon_name);
g_object_unref (icon_info);
}
static gboolean
@ -7060,8 +6929,8 @@ nautilus_icon_container_start_renaming_selected_item (NautilusIconContainer *con
{
NautilusIconContainerDetails *details;
NautilusIcon *icon;
ArtDRect icon_rect;
ArtDRect text_rect;
EelDRect icon_rect;
EelDRect text_rect;
PangoContext *context;
PangoFontDescription *desc;
const char *editable_text;

View file

@ -27,7 +27,7 @@
#define NAUTILUS_ICON_CONTAINER_H
#include <eel/eel-canvas.h>
#include <libnautilus-private/nautilus-icon-factory.h>
#include <libnautilus-private/nautilus-icon-info.h>
#define NAUTILUS_ICON_CONTAINER(obj) \
GTK_CHECK_CAST (obj, nautilus_icon_container_get_type (), NautilusIconContainer)
@ -128,10 +128,12 @@ typedef struct {
* These must be implemented. The default "do nothing" is not
* good enough, these are _not_ signals.
*/
char * (* get_icon_images) (NautilusIconContainer *container,
NautilusIconInfo *(* get_icon_images) (NautilusIconContainer *container,
NautilusIconData *data,
GList **emblem_icons,
int icon_size,
GList **emblem_pixbufs,
char **embedded_text,
gboolean for_drag_accept,
gboolean need_large_embeddded_text,
gboolean *embedded_text_needs_loading,
gboolean *has_window_open);

View file

@ -59,9 +59,6 @@
#include <eel/eel-canvas-rect-ellipse.h>
#include <libgnomeui/gnome-stock-icons.h>
#include <libgnomeui/gnome-uidefs.h>
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <libgnomevfs/gnome-vfs-mime-utils.h>
#include <libnautilus-private/nautilus-file-utilities.h>
#include <libnautilus-private/nautilus-file-changes-queue.h>
#include <stdio.h>
@ -193,10 +190,10 @@ typedef struct {
static void
canvas_rect_world_to_widget (EelCanvas *canvas,
ArtDRect *world_rect,
ArtIRect *widget_rect)
EelDRect *world_rect,
EelIRect *widget_rect)
{
ArtDRect window_rect;
EelDRect window_rect;
eel_canvas_world_to_window (canvas,
world_rect->x0, world_rect->y0,
@ -225,8 +222,8 @@ static gboolean
icon_get_data_binder (NautilusIcon *icon, gpointer data)
{
IconGetDataBinderContext *context;
ArtDRect world_rect;
ArtIRect widget_rect;
EelDRect world_rect;
EelIRect widget_rect;
char *uri;
NautilusIconContainer *container;
@ -246,11 +243,11 @@ icon_get_data_binder (NautilusIcon *icon, gpointer data)
return TRUE;
}
widget_rect = eel_art_irect_offset_by (widget_rect,
widget_rect = eel_irect_offset_by (widget_rect,
- container->details->dnd_info->drag_info.start_x,
- container->details->dnd_info->drag_info.start_y);
widget_rect = eel_art_irect_scale_by (widget_rect,
widget_rect = eel_irect_scale_by (widget_rect,
1 / EEL_CANVAS (container)->pixels_per_unit);
/* pass the uri, mouse-relative x/y and icon width/height */
@ -409,7 +406,7 @@ get_direct_save_filename (GdkDragContext *context)
static void
set_direct_save_uri (GtkWidget *widget, GdkDragContext *context, NautilusDragInfo *drag_info, int x, int y)
{
GnomeVFSURI *base, *file_uri;
GFile *base, *child;
char *filename, *drop_target;
gchar *uri;
@ -433,11 +430,11 @@ set_direct_save_uri (GtkWidget *widget, GdkDragContext *context, NautilusDragInf
if (filename != NULL && drop_target != NULL) {
/* Resolve relative path */
base = gnome_vfs_uri_new (drop_target);
file_uri = gnome_vfs_uri_append_file_name (base, (const gchar *) filename);
uri = gnome_vfs_uri_to_string (file_uri, GNOME_VFS_URI_HIDE_NONE);
gnome_vfs_uri_unref (base);
gnome_vfs_uri_unref (file_uri);
base = g_file_new_for_uri (drop_target);
child = g_file_get_child (base, filename);
uri = g_file_get_uri (child);
g_object_unref (base);
g_object_unref (child);
/* Change the uri property */
gdk_property_change (GDK_DRAWABLE (context->source_window),
@ -541,8 +538,8 @@ nautilus_icon_container_item_at (NautilusIconContainer *container,
{
GList *p;
int size;
ArtDRect point;
ArtIRect canvas_point;
EelDRect point;
EelIRect canvas_point;
/* build the hit-test rectangle. Base the size on the scale factor to ensure that it is
* non-empty even at the smallest scale factor
@ -602,12 +599,7 @@ nautilus_icon_container_selection_items_local (NautilusIconContainer *container,
/* get the URI associated with the container */
container_uri_string = get_container_uri (container);
if (eel_uri_is_trash (container_uri_string)) {
/* Special-case "trash:" because the nautilus_drag_items_local
* would not work for it.
*/
result = nautilus_drag_items_in_trash (items);
} else if (eel_uri_is_desktop (container_uri_string)) {
if (eel_uri_is_desktop (container_uri_string)) {
result = nautilus_drag_items_on_desktop (items);
} else {
result = nautilus_drag_items_local (container_uri_string, items);
@ -716,7 +708,7 @@ receive_dropped_keyword (NautilusIconContainer *container, const char *keyword,
"dropped emblem '%s' on icon container URI: %s",
keyword, uri);
file = nautilus_file_get (uri);
file = nautilus_file_get_by_uri (uri);
g_free (uri);
nautilus_drag_file_receive_dropped_keyword (file, keyword);
@ -960,7 +952,7 @@ handle_local_move (NautilusIconContainer *container,
* this screen
*/
file = nautilus_file_get (item->uri);
file = nautilus_file_get_by_uri (item->uri);
screen = gtk_widget_get_screen (GTK_WIDGET (container));
screen_string = g_strdup_printf ("%d",
@ -1097,7 +1089,7 @@ nautilus_icon_container_find_drop_target (NautilusIconContainer *container,
if (drop_target_icon != NULL) {
icon_uri = nautilus_icon_container_get_icon_uri (container, drop_target_icon);
if (icon_uri != NULL) {
file = nautilus_file_get (icon_uri);
file = nautilus_file_get_by_uri (icon_uri);
if (!nautilus_drag_can_accept_info (file,
container->details->dnd_info->drag_info.data_type,
@ -1130,9 +1122,11 @@ nautilus_icon_container_find_drop_target (NautilusIconContainer *container,
static gboolean
selection_is_image_file (GList *selection_list)
{
char *mime_type;
const char *mime_type;
NautilusDragSelectionItem *selected_item;
gboolean result;
GFile *location;
GFileInfo *info;
/* Make sure only one item is selected */
if (selection_list == NULL ||
@ -1142,11 +1136,22 @@ selection_is_image_file (GList *selection_list)
selected_item = selection_list->data;
mime_type = gnome_vfs_get_mime_type (selected_item->uri);
mime_type = NULL;
location = g_file_new_for_uri (selected_item->uri);
info = g_file_query_info (location,
G_FILE_ATTRIBUTE_STD_CONTENT_TYPE,
0, NULL, NULL);
if (info) {
mime_type = g_file_info_get_content_type (info);
}
result = eel_istr_has_prefix (mime_type, "image/");
g_free (mime_type);
if (info) {
g_object_unref (info);
}
g_object_unref (location);
return result;
}
@ -1339,7 +1344,7 @@ nautilus_icon_dnd_update_drop_target (NautilusIconContainer *container,
/* Find if target icon accepts our drop. */
if (icon != NULL && (container->details->dnd_info->drag_info.data_type != NAUTILUS_ICON_DND_KEYWORD)) {
uri = nautilus_icon_container_get_icon_uri (container, icon);
file = nautilus_file_get (uri);
file = nautilus_file_get_by_uri (uri);
g_free (uri);
if (!nautilus_drag_can_accept_info (file,
@ -1633,74 +1638,6 @@ nautilus_icon_dnd_end_drag (NautilusIconContainer *container)
*/
}
/**
* implements the gnome 1.x gnome_vfs_uri_list_extract_uris(), which
* returns a GList of char *uris.
**/
GList *
nautilus_icon_dnd_uri_list_extract_uris (const char *uri_list)
{
/* Note that this is mostly very stolen from old libgnome/gnome-mime.c */
const gchar *p, *q;
gchar *retval;
GList *result = NULL;
g_return_val_if_fail (uri_list != NULL, NULL);
p = uri_list;
/* We don't actually try to validate the URI according to RFC
* 2396, or even check for allowed characters - we just ignore
* comments and trim whitespace off the ends. We also
* allow LF delimination as well as the specified CRLF.
*/
while (p != NULL) {
if (*p != '#') {
while (g_ascii_isspace (*p))
p++;
q = p;
while ((*q != '\0')
&& (*q != '\n')
&& (*q != '\r'))
q++;
if (q > p) {
q--;
while (q > p
&& g_ascii_isspace (*q))
q--;
retval = g_malloc (q - p + 2);
strncpy (retval, p, q - p + 1);
retval[q - p + 1] = '\0';
result = g_list_prepend (result, retval);
}
}
p = strchr (p, '\n');
if (p != NULL)
p++;
}
return g_list_reverse (result);
}
/**
* nautilus_icon_dnd_uri_list_free_strings:
* @list: A GList returned by nautilus_icon_dnd_uri_list_extract_uris()
*
* Releases all of the resources allocated by @list.
*
* stolen from gnome-mime.c
*/
void
nautilus_icon_dnd_uri_list_free_strings (GList *list)
{
eel_g_list_free_deep (list);
}
/** this callback is called in 2 cases.
It is called upon drag_motion events to get the actual data
In that case, it just makes sure it gets the data.
@ -1833,12 +1770,16 @@ drag_data_received_callback (GtkWidget *widget,
drag_info->selection_data->data[0] == 'S' &&
drag_info->direct_save_uri != NULL) {
GdkPoint p;
GFile *location;
nautilus_file_changes_queue_file_added (drag_info->direct_save_uri);
location = g_file_new_for_uri (drag_info->direct_save_uri);
nautilus_file_changes_queue_file_added (location);
p.x = x; p.y = y;
nautilus_file_changes_queue_schedule_position_set (drag_info->direct_save_uri,
nautilus_file_changes_queue_schedule_position_set (location,
p,
gdk_screen_get_number (gtk_widget_get_screen (widget)));
g_object_unref (location);
nautilus_file_changes_consume_changes (TRUE);
}
success = TRUE;

View file

@ -59,7 +59,4 @@ void nautilus_icon_dnd_begin_drag (NautilusIconContainer *container
int start_y);
void nautilus_icon_dnd_end_drag (NautilusIconContainer *container);
GList *nautilus_icon_dnd_uri_list_extract_uris (const char *uri_list);
void nautilus_icon_dnd_uri_list_free_strings (GList *list);
#endif /* NAUTILUS_ICON_DND_H */

View file

@ -1,34 +0,0 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-icon-factory-private.h: Private interface for use within
the icon factory code.
Copyright (C) 2000 Eazel, 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.
Author: Darin Adler <darin@bentspoon.com>
*/
#ifndef NAUTILUS_ICON_FACTORY_PRIVATE_H
#define NAUTILUS_ICON_FACTORY_PRIVATE_H
#include <gdk-pixbuf/gdk-pixbuf.h>
/* Convenience routine to return the appropriate thumbnail frame. */
GdkPixbuf *nautilus_icon_factory_get_thumbnail_frame (void);
#endif /* NAUTILUS_ICON_FACTORY_PRIVATE_H */

File diff suppressed because it is too large Load diff

View file

@ -1,185 +0,0 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-icon-factory.h: Class for obtaining icons for files and other objects.
Copyright (C) 1999, 2000 Red Hat Inc.
Copyright (C) 1999, 2000 Eazel, 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.
Author: John Sullivan <sullivan@eazel.com>
*/
#ifndef NAUTILUS_ICON_FACTORY_H
#define NAUTILUS_ICON_FACTORY_H
#include <eel/eel-string-list.h>
#include <gdk/gdktypes.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gtk/gtkobject.h>
#include <libnautilus-private/nautilus-file.h>
#include <libgnomeui/gnome-icon-theme.h>
#include <libgnomeui/gnome-thumbnail.h>
/* NautilusIconFactory is a class that knows how to hand out icons to be
* used for representing files and some other objects. It was designed
* specifically to be useful for the Nautilus file browser, but could be
* used by any program that wants to display the standard icon for a
* file.
*
* The most common usage is to get a NautilusIconFactory object with
* nautilus_get_current_icon_factory, then ask for an icon for a specific
* file with nautilus_icon_factory_get_icon_for_file. The caller can ask
* for any size icon, but normally will use one of the defined
* NAUTILUS_ICON_SIZE macros.
*/
/* Names for Nautilus's different zoom levels, from tiniest items to largest items */
typedef enum {
NAUTILUS_ZOOM_LEVEL_SMALLEST,
NAUTILUS_ZOOM_LEVEL_SMALLER,
NAUTILUS_ZOOM_LEVEL_SMALL,
NAUTILUS_ZOOM_LEVEL_STANDARD,
NAUTILUS_ZOOM_LEVEL_LARGE,
NAUTILUS_ZOOM_LEVEL_LARGER,
NAUTILUS_ZOOM_LEVEL_LARGEST
} NautilusZoomLevel;
/* Nominal icon sizes for each Nautilus zoom level.
* This scheme assumes that icons are designed to
* fit in a square space, though each image needn't
* be square. Since individual icons can be stretched,
* each icon is not constrained to this nominal size.
*/
#define NAUTILUS_ICON_SIZE_SMALLEST 16
#define NAUTILUS_ICON_SIZE_SMALLER 24
#define NAUTILUS_ICON_SIZE_SMALL 32
#define NAUTILUS_ICON_SIZE_STANDARD 48
#define NAUTILUS_ICON_SIZE_LARGE 72
#define NAUTILUS_ICON_SIZE_LARGER 96
#define NAUTILUS_ICON_SIZE_LARGEST 192
#define NAUTILUS_ICON_SIZE_THUMBNAIL 96
/* Maximum size of an icon that the icon factory will ever produce */
#define NAUTILUS_ICON_MAXIMUM_SIZE 320
/* here's a structure to hold the emblem attach points */
#define MAX_ATTACH_POINTS 12
typedef struct {
int num_points;
GdkPoint points[MAX_ATTACH_POINTS];
} NautilusEmblemAttachPoints;
/* Instead of a class declaration here, I will just document
* the signals.
*
* "icons_changed", no parameters
*/
/* There's a single NautilusIconFactory object.
* The only thing you need it for is to connect to its signals.
*/
GObject * nautilus_icon_factory_get (void);
/* Relationship between zoom levels and icons sizes. */
guint nautilus_get_icon_size_for_zoom_level (NautilusZoomLevel zoom_level);
float nautilus_get_relative_icon_size_for_zoom_level (NautilusZoomLevel zoom_level);
/* Choose the appropriate icon, but don't render it yet. */
char * nautilus_icon_factory_get_icon_for_file (NautilusFile *file,
gboolean embedd_text);
gboolean nautilus_icon_factory_is_icon_ready_for_file (NautilusFile *file);
NautilusFileAttributes nautilus_icon_factory_get_required_file_attributes (void);
GList * nautilus_icon_factory_get_emblem_icons_for_file (NautilusFile *file,
EelStringList *exclude);
char * nautilus_icon_factory_get_emblem_icon_by_name (const char *emblem_name);
guint nautilus_icon_factory_get_emblem_size_for_icon_size (guint size);
guint nautilus_icon_factory_get_larger_icon_size (guint size);
guint nautilus_icon_factory_get_smaller_icon_size (guint size);
/* Render an icon to a particular size.
* Ownership of a ref. count in this pixbuf comes with the deal.
* This allows scaling in both dimensions. All other calls assume
* that X and Y scaling are the same. Optionally, we also pass
* back an array of emblem attach points, if the pointer is non-null
* If the wants_default boolean is set, return a default icon instead
* of NULL if we can't find anything
*/
GdkPixbuf *nautilus_icon_factory_get_pixbuf_for_icon (const char *icon,
const char *modifier,
guint nominal_size,
NautilusEmblemAttachPoints *attach_points,
GdkRectangle *embedded_text_rect,
gboolean force_size,
gboolean wants_default,
char **display_name);
GdkPixbuf *nautilus_icon_factory_get_pixbuf_for_icon_with_stock_size (const char *icon,
const char *modifier,
GtkIconSize stock_size,
NautilusEmblemAttachPoints *attach_points,
GdkRectangle *embedded_text_rect,
gboolean wants_default,
char **display_name);
/* Convenience functions for the common case where you want to choose
* and render the icon into a pixbuf all at once.
*/
GdkPixbuf *nautilus_icon_factory_get_pixbuf_for_file (NautilusFile *file,
const char *modifer,
guint size_in_pixels,
gboolean force_size);
GdkPixbuf *nautilus_icon_factory_get_pixbuf_for_file_with_stock_size (NautilusFile *file,
const char *modifier,
GtkIconSize stock_size);
GdkPixbuf * nautilus_icon_factory_get_pixbuf_for_file_with_icon (NautilusFile *file,
const char *icon,
const char *modifier,
guint size_in_pixels,
NautilusEmblemAttachPoints *attach_points,
GdkRectangle *embedded_text_rect,
gboolean force_size,
gboolean wants_default,
char **display_name);
/* Convenience routine for getting a pixbuf from an icon name
*/
GdkPixbuf * nautilus_icon_factory_get_pixbuf_from_name (const char *icon_name,
const char *modifer,
guint size_in_pixels,
gboolean force_size,
char **display_name);
GdkPixbuf * nautilus_icon_factory_get_pixbuf_from_name_with_stock_size (const char *icon_name,
const char *modifer,
GtkIconSize stock_size,
char **display_name);
GtkIconTheme * nautilus_icon_factory_get_icon_theme (void);
GnomeThumbnailFactory *nautilus_icon_factory_get_thumbnail_factory (void);
gboolean nautilus_icon_factory_remove_from_cache (const char *icon_name,
const char *modifier,
guint size);
#endif /* NAUTILUS_ICON_FACTORY_H */

View file

@ -0,0 +1,666 @@
/* nautilus-icon-info.c
* Copyright (C) 2007 Red Hat, Inc., Alexander Larsson <alexl@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <config.h>
#include <string.h>
#include "nautilus-icon-info.h"
#include "nautilus-default-file-icon.h"
#include <gtk/gtkicontheme.h>
#include <gtk/gtkiconfactory.h>
#include <gio/gloadableicon.h>
#include <gio/gthemedicon.h>
#include <eel/eel-gdk-pixbuf-extensions.h>
#define NAUTILUS_EMBLEM_NAME_PREFIX "emblem-"
struct _NautilusIconInfo
{
GObject parent;
gboolean sole_owner;
guint64 last_use_time;
GdkPixbuf *pixbuf;
gboolean got_embedded_rect;
GdkRectangle embedded_rect;
gint n_attach_points;
GdkPoint *attach_points;
char *display_name;
char *icon_name;
};
struct _NautilusIconInfoClass
{
GObjectClass parent_class;
};
static void schedule_reap_cache (void);
G_DEFINE_TYPE (NautilusIconInfo,
nautilus_icon_info,
G_TYPE_OBJECT);
static void
nautilus_icon_info_init (NautilusIconInfo *icon)
{
icon->last_use_time = g_thread_gettime ();
icon->sole_owner = TRUE;
}
static void
pixbuf_toggle_notify (gpointer info,
GObject *object,
gboolean is_last_ref)
{
NautilusIconInfo *icon = info;
if (is_last_ref) {
icon->sole_owner = TRUE;
g_object_remove_toggle_ref (object,
pixbuf_toggle_notify,
info);
icon->last_use_time = g_thread_gettime ();
schedule_reap_cache ();
}
}
static void
nautilus_icon_info_finalize (GObject *object)
{
NautilusIconInfo *icon;
icon = NAUTILUS_ICON_INFO (object);
if (!icon->sole_owner && icon->pixbuf) {
g_object_remove_toggle_ref (G_OBJECT (icon->pixbuf),
pixbuf_toggle_notify,
icon);
}
if (icon->pixbuf) {
g_object_unref (icon->pixbuf);
}
g_free (icon->attach_points);
g_free (icon->display_name);
g_free (icon->icon_name);
G_OBJECT_CLASS (nautilus_icon_info_parent_class)->finalize (object);
}
static void
nautilus_icon_info_class_init (NautilusIconInfoClass *icon_info_class)
{
GObjectClass *gobject_class;
gobject_class = (GObjectClass *) icon_info_class;
gobject_class->finalize = nautilus_icon_info_finalize;
}
NautilusIconInfo *
nautilus_icon_info_new_for_pixbuf (GdkPixbuf *pixbuf)
{
NautilusIconInfo *icon;
icon = g_object_new (NAUTILUS_TYPE_ICON_INFO, NULL);
if (pixbuf) {
icon->pixbuf = g_object_ref (pixbuf);
}
return icon;
}
static NautilusIconInfo *
nautilus_icon_info_new_for_icon_info (GtkIconInfo *icon_info)
{
NautilusIconInfo *icon;
GdkPoint *points;
gint n_points;
const char *filename;
char *basename, *p;
icon = g_object_new (NAUTILUS_TYPE_ICON_INFO, NULL);
icon->pixbuf = gtk_icon_info_load_icon (icon_info, NULL);
icon->got_embedded_rect = gtk_icon_info_get_embedded_rect (icon_info,
&icon->embedded_rect);
if (gtk_icon_info_get_attach_points (icon_info, &points, &n_points)) {
icon->n_attach_points = n_points;
icon->attach_points = points;
}
icon->display_name = g_strdup (gtk_icon_info_get_display_name (icon_info));
filename = gtk_icon_info_get_display_name (icon_info);
if (filename != NULL) {
basename = g_path_get_basename (filename);
p = strrchr (basename, '.');
if (p) {
*p = 0;
}
icon->icon_name = basename;
}
return icon;
}
typedef struct {
GIcon *icon;
int size;
} LoadableIconKey;
typedef struct {
char *filename;
int size;
} ThemedIconKey;
static GHashTable *loadable_icon_cache = NULL;
static GHashTable *themed_icon_cache = NULL;
static guint reap_cache_timeout = 0;
#define NSEC_PER_SEC ((guint64)1000000000L)
static guint time_now;
static gboolean
reap_old_icon (gpointer key,
gpointer value,
gpointer user_info)
{
NautilusIconInfo *icon = value;
gboolean *reapable_icons_left = user_info;
if (icon->sole_owner) {
if (time_now - icon->last_use_time > 30 * NSEC_PER_SEC) {
/* This went unused 30 secs ago. reap */
return TRUE;
} else {
/* We can reap this soon */
*reapable_icons_left = TRUE;
}
}
return FALSE;
}
static gboolean
reap_cache (gpointer data)
{
gboolean reapable_icons_left;
reapable_icons_left = TRUE;
time_now = g_thread_gettime ();
if (loadable_icon_cache) {
g_hash_table_foreach_remove (loadable_icon_cache,
reap_old_icon,
&reapable_icons_left);
}
if (themed_icon_cache) {
g_hash_table_foreach_remove (themed_icon_cache,
reap_old_icon,
&reapable_icons_left);
}
if (reapable_icons_left) {
return TRUE;
} else {
reap_cache_timeout = 0;
return FALSE;
}
}
static void
schedule_reap_cache (void)
{
if (reap_cache_timeout == 0) {
reap_cache_timeout = g_timeout_add_seconds_full (0, 5,
reap_cache,
NULL, NULL);
}
}
void
nautilus_icon_info_clear_caches (void)
{
if (loadable_icon_cache) {
g_hash_table_remove_all (loadable_icon_cache);
}
if (themed_icon_cache) {
g_hash_table_remove_all (themed_icon_cache);
}
}
static guint
loadable_icon_key_hash (LoadableIconKey *key)
{
return g_icon_hash (key->icon) ^ key->size;
}
static gboolean
loadable_icon_key_equal (const LoadableIconKey *a,
const LoadableIconKey *b)
{
return a->size == b->size &&
g_icon_equal (a->icon, b->icon);
}
static LoadableIconKey *
loadable_icon_key_new (GIcon *icon, int size)
{
LoadableIconKey *key;
key = g_slice_new (LoadableIconKey);
key->icon = g_object_ref (icon);
key->size = size;
return key;
}
static void
loadable_icon_key_free (LoadableIconKey *key)
{
g_object_unref (key->icon);
g_slice_free (LoadableIconKey, key);
}
static guint
themed_icon_key_hash (ThemedIconKey *key)
{
return g_str_hash (key->filename) ^ key->size;
}
static gboolean
themed_icon_key_equal (const ThemedIconKey *a,
const ThemedIconKey *b)
{
return a->size == b->size &&
g_str_equal (a->filename, b->filename);
}
static ThemedIconKey *
themed_icon_key_new (const char *filename, int size)
{
ThemedIconKey *key;
key = g_slice_new (ThemedIconKey);
key->filename = g_strdup (filename);
key->size = size;
return key;
}
static void
themed_icon_key_free (ThemedIconKey *key)
{
g_free (key->filename);
g_slice_free (ThemedIconKey, key);
}
NautilusIconInfo *
nautilus_icon_info_lookup (GIcon *icon,
int size)
{
NautilusIconInfo *icon_info;
GdkPixbuf *pixbuf;
if (G_IS_LOADABLE_ICON (icon)) {
LoadableIconKey lookup_key;
LoadableIconKey *key;
GInputStream *stream;
if (loadable_icon_cache == NULL) {
loadable_icon_cache =
g_hash_table_new_full ((GHashFunc)loadable_icon_key_hash,
(GEqualFunc)loadable_icon_key_equal,
(GDestroyNotify) loadable_icon_key_free,
(GDestroyNotify) g_object_unref);
}
lookup_key.icon = icon;
lookup_key.size = size;
icon_info = g_hash_table_lookup (loadable_icon_cache, &lookup_key);
if (icon_info) {
return g_object_ref (icon_info);
}
pixbuf = NULL;
stream = g_loadable_icon_load (G_LOADABLE_ICON (icon),
size,
NULL, NULL, NULL);
if (stream) {
pixbuf = eel_gdk_pixbuf_load_from_stream (stream);
/* TODO: resize icon? */
g_object_unref (stream);
}
icon_info = nautilus_icon_info_new_for_pixbuf (pixbuf);
key = loadable_icon_key_new (icon, size);
g_hash_table_insert (loadable_icon_cache, key, icon_info);
return g_object_ref (icon_info);
} else if (G_IS_THEMED_ICON (icon)) {
const char * const *names;
ThemedIconKey lookup_key;
ThemedIconKey *key;
GtkIconTheme *icon_theme;
GtkIconInfo *gtkicon_info;
const char *filename;
if (themed_icon_cache == NULL) {
themed_icon_cache =
g_hash_table_new_full ((GHashFunc)themed_icon_key_hash,
(GEqualFunc)themed_icon_key_equal,
(GDestroyNotify) themed_icon_key_free,
(GDestroyNotify) g_object_unref);
}
names = g_themed_icon_get_names (G_THEMED_ICON (icon));
icon_theme = gtk_icon_theme_get_default ();
gtkicon_info = gtk_icon_theme_choose_icon (icon_theme, (const char **)names, size, 0);
if (gtkicon_info == NULL) {
return nautilus_icon_info_new_for_pixbuf (NULL);
}
filename = gtk_icon_info_get_filename (gtkicon_info);
lookup_key.filename = (char *)filename;
lookup_key.size = size;
icon_info = g_hash_table_lookup (themed_icon_cache, &lookup_key);
if (icon_info) {
gtk_icon_info_free (gtkicon_info);
return g_object_ref (icon_info);
}
icon_info = nautilus_icon_info_new_for_icon_info (gtkicon_info);
key = themed_icon_key_new (filename, size);
g_hash_table_insert (themed_icon_cache, key, icon_info);
gtk_icon_info_free (gtkicon_info);
return g_object_ref (icon_info);
}
return nautilus_icon_info_new_for_pixbuf (NULL);
}
NautilusIconInfo *
nautilus_icon_info_lookup_from_name (const char *name,
int size)
{
GIcon *icon;
NautilusIconInfo *info;
icon = g_themed_icon_new (name);
info = nautilus_icon_info_lookup (icon, size);
g_object_unref (icon);
return info;
}
GdkPixbuf *
nautilus_icon_info_get_pixbuf_nodefault (NautilusIconInfo *icon)
{
GdkPixbuf *res;
if (icon->pixbuf == NULL) {
res = NULL;
} else {
res = g_object_ref (icon->pixbuf);
icon->sole_owner = FALSE;
g_object_add_toggle_ref (G_OBJECT (res),
pixbuf_toggle_notify,
icon);
}
return res;
}
GdkPixbuf *
nautilus_icon_info_get_pixbuf (NautilusIconInfo *icon)
{
GdkPixbuf *res;
res = nautilus_icon_info_get_pixbuf_nodefault (icon);
if (res == NULL) {
res = gdk_pixbuf_new_from_data (nautilus_default_file_icon,
GDK_COLORSPACE_RGB,
TRUE,
8,
nautilus_default_file_icon_width,
nautilus_default_file_icon_height,
nautilus_default_file_icon_width * 4, /* stride */
NULL, /* don't destroy info */
NULL);
}
return res;
}
GdkPixbuf *
nautilus_icon_info_get_pixbuf_nodefault_at_size (NautilusIconInfo *icon,
gsize forced_size)
{
GdkPixbuf *pixbuf, *scaled_pixbuf;
int w, h, s;
double scale;
pixbuf = nautilus_icon_info_get_pixbuf_nodefault (icon);
if (pixbuf == NULL)
return NULL;
w = gdk_pixbuf_get_width (pixbuf);
h = gdk_pixbuf_get_height (pixbuf);
s = MAX (w, h);
scale = (double)forced_size / s;
scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf,
w * scale, h * scale,
GDK_INTERP_HYPER);
g_object_unref (pixbuf);
return scaled_pixbuf;
}
GdkPixbuf *
nautilus_icon_info_get_pixbuf_at_size (NautilusIconInfo *icon,
gsize forced_size)
{
GdkPixbuf *pixbuf, *scaled_pixbuf;
int w, h, s;
double scale;
pixbuf = nautilus_icon_info_get_pixbuf (icon);
w = gdk_pixbuf_get_width (pixbuf);
h = gdk_pixbuf_get_height (pixbuf);
s = MAX (w, h);
scale = (double)forced_size / s;
scaled_pixbuf = gdk_pixbuf_scale_simple (pixbuf,
w * scale, h * scale,
GDK_INTERP_HYPER);
g_object_unref (pixbuf);
return scaled_pixbuf;
}
gboolean
nautilus_icon_info_get_embedded_rect (NautilusIconInfo *icon,
GdkRectangle *rectangle)
{
*rectangle = icon->embedded_rect;
return icon->got_embedded_rect;
}
gboolean
nautilus_icon_info_get_attach_points (NautilusIconInfo *icon,
GdkPoint **points,
gint *n_points)
{
*n_points = icon->n_attach_points;
*points = icon->attach_points;
return icon->n_attach_points != 0;
}
G_CONST_RETURN char *
nautilus_icon_info_get_display_name (NautilusIconInfo *icon)
{
return icon->display_name;
}
G_CONST_RETURN char *
nautilus_icon_info_get_used_name (NautilusIconInfo *icon)
{
return icon->icon_name;
}
/* Return nominal icon size for given zoom level.
* @zoom_level: zoom level for which to find matching icon size.
*
* Return value: icon size between NAUTILUS_ICON_SIZE_SMALLEST and
* NAUTILUS_ICON_SIZE_LARGEST, inclusive.
*/
guint
nautilus_get_icon_size_for_zoom_level (NautilusZoomLevel zoom_level)
{
switch (zoom_level) {
case NAUTILUS_ZOOM_LEVEL_SMALLEST:
return NAUTILUS_ICON_SIZE_SMALLEST;
case NAUTILUS_ZOOM_LEVEL_SMALLER:
return NAUTILUS_ICON_SIZE_SMALLER;
case NAUTILUS_ZOOM_LEVEL_SMALL:
return NAUTILUS_ICON_SIZE_SMALL;
case NAUTILUS_ZOOM_LEVEL_STANDARD:
return NAUTILUS_ICON_SIZE_STANDARD;
case NAUTILUS_ZOOM_LEVEL_LARGE:
return NAUTILUS_ICON_SIZE_LARGE;
case NAUTILUS_ZOOM_LEVEL_LARGER:
return NAUTILUS_ICON_SIZE_LARGER;
case NAUTILUS_ZOOM_LEVEL_LARGEST:
return NAUTILUS_ICON_SIZE_LARGEST;
}
g_return_val_if_reached (NAUTILUS_ICON_SIZE_STANDARD);
}
float
nautilus_get_relative_icon_size_for_zoom_level (NautilusZoomLevel zoom_level)
{
return (float)nautilus_get_icon_size_for_zoom_level (zoom_level) / NAUTILUS_ICON_SIZE_STANDARD;
}
guint
nautilus_icon_get_larger_icon_size (guint size)
{
if (size < NAUTILUS_ICON_SIZE_SMALLEST) {
return NAUTILUS_ICON_SIZE_SMALLEST;
}
if (size < NAUTILUS_ICON_SIZE_SMALLER) {
return NAUTILUS_ICON_SIZE_SMALLER;
}
if (size < NAUTILUS_ICON_SIZE_SMALL) {
return NAUTILUS_ICON_SIZE_SMALL;
}
if (size < NAUTILUS_ICON_SIZE_STANDARD) {
return NAUTILUS_ICON_SIZE_STANDARD;
}
if (size < NAUTILUS_ICON_SIZE_LARGE) {
return NAUTILUS_ICON_SIZE_LARGE;
}
if (size < NAUTILUS_ICON_SIZE_LARGER) {
return NAUTILUS_ICON_SIZE_LARGER;
}
return NAUTILUS_ICON_SIZE_LARGEST;
}
guint
nautilus_icon_get_smaller_icon_size (guint size)
{
if (size > NAUTILUS_ICON_SIZE_LARGEST) {
return NAUTILUS_ICON_SIZE_LARGEST;
}
if (size > NAUTILUS_ICON_SIZE_LARGER) {
return NAUTILUS_ICON_SIZE_LARGER;
}
if (size > NAUTILUS_ICON_SIZE_LARGE) {
return NAUTILUS_ICON_SIZE_LARGE;
}
if (size > NAUTILUS_ICON_SIZE_STANDARD) {
return NAUTILUS_ICON_SIZE_STANDARD;
}
if (size > NAUTILUS_ICON_SIZE_SMALL) {
return NAUTILUS_ICON_SIZE_SMALL;
}
if (size > NAUTILUS_ICON_SIZE_SMALLER) {
return NAUTILUS_ICON_SIZE_SMALLER;
}
return NAUTILUS_ICON_SIZE_SMALLEST;
}
gint
nautilus_get_icon_size_for_stock_size (GtkIconSize size)
{
gint w, h;
if (gtk_icon_size_lookup (size, &w, &h)) {
return MAX (w, h);
}
return NAUTILUS_ZOOM_LEVEL_STANDARD;
}
char *
nautilus_icon_get_emblem_icon_by_name (const char *emblem_name)
{
char *name_with_prefix;
name_with_prefix = g_strconcat (NAUTILUS_EMBLEM_NAME_PREFIX, emblem_name, NULL);
return name_with_prefix;
}
guint
nautilus_icon_get_emblem_size_for_icon_size (guint size)
{
if (size >= 96)
return 48;
if (size >= 64)
return 32;
if (size >= 48)
return 24;
if (size >= 32)
return 16;
return 0; /* no emblems for smaller sizes */
}

View file

@ -0,0 +1,90 @@
#ifndef NAUTILUS_ICON_INFO_H
#define NAUTILUS_ICON_INFO_H
#include <glib-object.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk/gdktypes.h>
#include <gio/gicon.h>
#include <gtk/gtkstock.h>
G_BEGIN_DECLS
/* Names for Nautilus's different zoom levels, from tiniest items to largest items */
typedef enum {
NAUTILUS_ZOOM_LEVEL_SMALLEST,
NAUTILUS_ZOOM_LEVEL_SMALLER,
NAUTILUS_ZOOM_LEVEL_SMALL,
NAUTILUS_ZOOM_LEVEL_STANDARD,
NAUTILUS_ZOOM_LEVEL_LARGE,
NAUTILUS_ZOOM_LEVEL_LARGER,
NAUTILUS_ZOOM_LEVEL_LARGEST
} NautilusZoomLevel;
/* Nominal icon sizes for each Nautilus zoom level.
* This scheme assumes that icons are designed to
* fit in a square space, though each image needn't
* be square. Since individual icons can be stretched,
* each icon is not constrained to this nominal size.
*/
#define NAUTILUS_ICON_SIZE_SMALLEST 16
#define NAUTILUS_ICON_SIZE_SMALLER 24
#define NAUTILUS_ICON_SIZE_SMALL 32
#define NAUTILUS_ICON_SIZE_STANDARD 48
#define NAUTILUS_ICON_SIZE_LARGE 72
#define NAUTILUS_ICON_SIZE_LARGER 96
#define NAUTILUS_ICON_SIZE_LARGEST 192
/* Maximum size of an icon that the icon factory will ever produce */
#define NAUTILUS_ICON_MAXIMUM_SIZE 320
typedef struct _NautilusIconInfo NautilusIconInfo;
typedef struct _NautilusIconInfoClass NautilusIconInfoClass;
#define NAUTILUS_TYPE_ICON_INFO (nautilus_icon_info_get_type ())
#define NAUTILUS_ICON_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_ICON_INFO, NautilusIconInfo))
#define NAUTILUS_ICON_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_ICON_INFO, NautilusIconInfoClass))
#define NAUTILUS_IS_ICON_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_ICON_INFO))
#define NAUTILUS_IS_ICON_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_ICON_INFO))
#define NAUTILUS_ICON_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_ICON_INFO, NautilusIconInfoClass))
GType nautilus_icon_info_get_type (void) G_GNUC_CONST;
NautilusIconInfo * nautilus_icon_info_new_for_pixbuf (GdkPixbuf *pixbuf);
NautilusIconInfo * nautilus_icon_info_lookup (GIcon *icon,
int size);
NautilusIconInfo * nautilus_icon_info_lookup_from_name (const char *name,
int size);
GdkPixbuf * nautilus_icon_info_get_pixbuf (NautilusIconInfo *icon);
GdkPixbuf * nautilus_icon_info_get_pixbuf_nodefault (NautilusIconInfo *icon);
GdkPixbuf * nautilus_icon_info_get_pixbuf_nodefault_at_size (NautilusIconInfo *icon,
gsize forced_size);
GdkPixbuf * nautilus_icon_info_get_pixbuf_at_size (NautilusIconInfo *icon,
gsize forced_size);
gboolean nautilus_icon_info_get_embedded_rect (NautilusIconInfo *icon,
GdkRectangle *rectangle);
gboolean nautilus_icon_info_get_attach_points (NautilusIconInfo *icon,
GdkPoint **points,
gint *n_points);
G_CONST_RETURN char *nautilus_icon_info_get_display_name (NautilusIconInfo *icon);
G_CONST_RETURN char *nautilus_icon_info_get_used_name (NautilusIconInfo *icon);
void nautilus_icon_info_clear_caches (void);
/* Relationship between zoom levels and icons sizes. */
guint nautilus_get_icon_size_for_zoom_level (NautilusZoomLevel zoom_level);
float nautilus_get_relative_icon_size_for_zoom_level (NautilusZoomLevel zoom_level);
guint nautilus_icon_get_larger_icon_size (guint size);
guint nautilus_icon_get_smaller_icon_size (guint size);
gint nautilus_get_icon_size_for_stock_size (GtkIconSize size);
char *nautilus_icon_get_emblem_icon_by_name (const char *emblem_name);
guint nautilus_icon_get_emblem_size_for_icon_size (guint size);
G_END_DECLS
#endif /* NAUTILUS_ICON_INFO_H */

View file

@ -30,7 +30,6 @@
#include <libnautilus-private/nautilus-icon-canvas-item.h>
#include <libnautilus-private/nautilus-icon-container.h>
#include <libnautilus-private/nautilus-icon-dnd.h>
#include <libnautilus-private/nautilus-icon-factory.h>
/* An Icon. */
@ -83,7 +82,7 @@ typedef struct {
guint timer_id;
guint prev_x, prev_y;
ArtDRect prev_rect;
EelDRect prev_rect;
int last_adj_y;
} NautilusIconRubberbandInfo;

View file

@ -44,7 +44,6 @@ void nautilus_run_lib_self_checks (void);
macro (nautilus_self_check_directory) \
macro (nautilus_self_check_file) \
macro (nautilus_self_check_icon_container) \
macro (nautilus_self_check_icon_factory) \
/* Add new self-check functions to the list above this line. */
/* Generate prototypes for all the functions. */

View file

@ -1,409 +0,0 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-link-desktop-file.c: .desktop link files.
Copyright (C) 2001 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 historicalied 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.
Authors: Jonathan Blandford <jrb@redhat.com>
Alexander Larsson <alexl@redhat.com>
*/
#include <config.h>
#include "nautilus-link-desktop-file.h"
#include "nautilus-directory-notify.h"
#include "nautilus-directory.h"
#include "nautilus-file-attributes.h"
#include "nautilus-file-utilities.h"
#include "nautilus-icon-factory.h"
#include "nautilus-file.h"
#include "nautilus-metadata.h"
#include "nautilus-program-choosing.h"
#include <eel/eel-glib-extensions.h>
#include <eel/eel-gnome-extensions.h>
#include <eel/eel-stock-dialogs.h>
#include <eel/eel-string.h>
#include <eel/eel-xml-extensions.h>
#include <eel/eel-vfs-extensions.h>
#include <glib/gi18n.h>
#include <libgnome/gnome-util.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <libxml/parser.h>
#include <stdlib.h>
#define NAUTILUS_LINK_GENERIC_TAG "Link"
#define NAUTILUS_LINK_TRASH_TAG "X-nautilus-trash"
#define NAUTILUS_LINK_MOUNT_TAG "FSDevice"
#define NAUTILUS_LINK_HOME_TAG "X-nautilus-home"
static char *
slurp_key_string (const char *uri,
const char *keyname,
gboolean localize)
{
GnomeDesktopItem *desktop_file;
const char *text;
char *result;
desktop_file = gnome_desktop_item_new_from_uri (uri, 0, NULL);
if (desktop_file == NULL) {
return NULL;
}
if (localize) {
text = gnome_desktop_item_get_localestring (desktop_file, keyname);
} else {
text = gnome_desktop_item_get_string (desktop_file, keyname);
}
result = g_strdup (text);
gnome_desktop_item_unref (desktop_file);
return result;
}
gboolean
nautilus_link_desktop_file_local_create (const char *directory_uri,
const char *base_name,
const char *display_name,
const char *image,
const char *target_uri,
const GdkPoint *point,
int screen,
gboolean unique_filename)
{
char *real_directory_uri;
char *uri, *contents, *escaped_name;
GnomeDesktopItem *desktop_item;
GList dummy_list;
NautilusFileChangesQueuePosition item;
g_return_val_if_fail (directory_uri != NULL, FALSE);
g_return_val_if_fail (base_name != NULL, FALSE);
g_return_val_if_fail (display_name != NULL, FALSE);
g_return_val_if_fail (target_uri != NULL, FALSE);
if (eel_uri_is_trash (directory_uri) ||
eel_uri_is_search (directory_uri)) {
return FALSE;
}
if (eel_uri_is_desktop (directory_uri)) {
real_directory_uri = nautilus_get_desktop_directory_uri ();
} else {
real_directory_uri = g_strdup (directory_uri);
}
if (unique_filename) {
uri = nautilus_ensure_unique_file_name (real_directory_uri,
base_name, ".desktop");
if (uri == NULL) {
g_free (real_directory_uri);
return FALSE;
}
} else {
escaped_name = gnome_vfs_escape_string (base_name);
uri = g_strdup_printf ("%s/%s.desktop", real_directory_uri, escaped_name);
g_free (escaped_name);
}
g_free (real_directory_uri);
contents = g_strdup_printf ("[Desktop Entry]\n"
"Encoding=UTF-8\n"
"Name=%s\n"
"Type=Link\n"
"URL=%s\n"
"%s%s\n",
display_name,
target_uri,
image != NULL ? "Icon=" : "",
image != NULL ? image : "");
desktop_item = gnome_desktop_item_new_from_string (uri,
contents,
strlen (contents),
0,
NULL);
if (!desktop_item) {
g_free (contents);
g_free (uri);
return FALSE;
}
if (!gnome_desktop_item_save (desktop_item, uri, TRUE, NULL)) {
gnome_desktop_item_unref (desktop_item);
g_free (contents);
g_free (uri);
return FALSE;
}
dummy_list.data = uri;
dummy_list.next = NULL;
dummy_list.prev = NULL;
nautilus_directory_notify_files_added (&dummy_list);
nautilus_directory_schedule_metadata_remove (&dummy_list);
if (point != NULL) {
item.uri = uri;
item.set = TRUE;
item.point.x = point->x;
item.point.y = point->y;
item.screen = screen;
dummy_list.data = &item;
dummy_list.next = NULL;
dummy_list.prev = NULL;
nautilus_directory_schedule_position_set (&dummy_list);
}
gnome_desktop_item_unref (desktop_item);
g_free (contents);
g_free (uri);
return TRUE;
}
gboolean
nautilus_link_desktop_file_local_set_text (const char *uri,
const char *text)
{
GnomeDesktopItem *desktop_file;
gboolean success;
desktop_file = gnome_desktop_item_new_from_uri (uri, 0, NULL);
if (desktop_file == NULL) {
return FALSE;
}
gnome_desktop_item_set_localestring (desktop_file, "Name", text);
success = gnome_desktop_item_save (desktop_file, NULL, FALSE, NULL);
gnome_desktop_item_unref (desktop_file);
return success;
}
char *
nautilus_link_desktop_file_local_get_text (const char *path)
{
return slurp_key_string (path, "Name", TRUE);
}
char *
nautilus_link_desktop_file_local_get_additional_text (const char *path)
{
/* The comment field of current .desktop files is often bad.
* It just contains a copy of the name. This is probably because the
* panel shows the comment field as a tooltip.
*/
return NULL;
#ifdef THIS_IS_NOT_USED_RIGHT_NOW
char *type;
char *retval;
type = slurp_key_string (path, "Type", FALSE);
retval = NULL;
if (type == NULL) {
return NULL;
}
if (strcmp (type, "Application") == 0) {
retval = slurp_key_string (path, "Comment", TRUE);
}
g_free (type);
return retval;
#endif
}
static char *
nautilus_link_desktop_file_get_link_uri_from_desktop (GnomeDesktopItem *desktop_file)
{
const char *launch_string;
const char *type;
char *retval;
retval = NULL;
type = gnome_desktop_item_get_string (desktop_file, "Type");
if (type == NULL) {
return NULL;
}
if (strcmp (type, "Application") == 0) {
launch_string = gnome_desktop_item_get_string (desktop_file, "Exec");
if (launch_string == NULL) {
return NULL;
}
launch_string = gnome_desktop_item_get_location (desktop_file);
retval = g_strconcat (NAUTILUS_DESKTOP_COMMAND_SPECIFIER, launch_string, NULL);
} else if (strcmp (type, "URL") == 0) {
/* Some old broken desktop files use this nonstandard feature, we need handle it though */
retval = g_strdup (gnome_desktop_item_get_string (desktop_file, "Exec"));
} else if ((strcmp (type, NAUTILUS_LINK_GENERIC_TAG) == 0) ||
(strcmp (type, NAUTILUS_LINK_MOUNT_TAG) == 0) ||
(strcmp (type, NAUTILUS_LINK_TRASH_TAG) == 0) ||
(strcmp (type, NAUTILUS_LINK_HOME_TAG) == 0)) {
retval = g_strdup (gnome_desktop_item_get_string (desktop_file, "URL"));
}
return retval;
}
static char *
nautilus_link_desktop_file_get_link_name_from_desktop (GnomeDesktopItem *desktop_file)
{
return g_strdup (gnome_desktop_item_get_localestring (desktop_file, "Name"));
}
static char *
nautilus_link_desktop_file_get_link_icon_from_desktop (GnomeDesktopItem *desktop_file)
{
char *icon_uri;
const char *icon;
GnomeDesktopItemType desktop_type;
icon_uri = g_strdup (gnome_desktop_item_get_string (desktop_file, "X-Nautilus-Icon"));
if (icon_uri != NULL) {
return icon_uri;
}
icon = gnome_desktop_item_get_string (desktop_file, GNOME_DESKTOP_ITEM_ICON);
if (icon != NULL) {
return g_strdup (icon);
}
desktop_type = gnome_desktop_item_get_entry_type (desktop_file);
switch (desktop_type) {
case GNOME_DESKTOP_ITEM_TYPE_APPLICATION:
return g_strdup ("gnome-fs-executable");
case GNOME_DESKTOP_ITEM_TYPE_LINK:
return g_strdup ("gnome-dev-symlink");
case GNOME_DESKTOP_ITEM_TYPE_FSDEVICE:
return g_strdup ("gnome-dev-harddisk");
case GNOME_DESKTOP_ITEM_TYPE_DIRECTORY:
return g_strdup ("gnome-fs-directory");
case GNOME_DESKTOP_ITEM_TYPE_SERVICE:
case GNOME_DESKTOP_ITEM_TYPE_SERVICE_TYPE:
return g_strdup ("gnome-fs-web");
default:
return g_strdup ("gnome-fs-regular");
}
g_assert_not_reached ();
return NULL;
}
char *
nautilus_link_desktop_file_local_get_link_uri (const char *uri)
{
GnomeDesktopItem *desktop_file;
char *retval;
desktop_file = gnome_desktop_item_new_from_uri (uri, 0, NULL);
if (desktop_file == NULL) {
return NULL;
}
retval = nautilus_link_desktop_file_get_link_uri_from_desktop (desktop_file);
gnome_desktop_item_unref (desktop_file);
return retval;
}
void
nautilus_link_desktop_file_get_link_info_given_file_contents (const char *file_contents,
int link_file_size,
char **uri,
char **name,
char **icon,
gulong *drive_id,
gulong *volume_id)
{
GnomeDesktopItem *desktop_file;
const char *id;
desktop_file = gnome_desktop_item_new_from_string (NULL, file_contents, link_file_size, 0, NULL);
if (desktop_file == NULL) {
return;
}
*uri = nautilus_link_desktop_file_get_link_uri_from_desktop (desktop_file);
*name = nautilus_link_desktop_file_get_link_name_from_desktop (desktop_file);
*icon = nautilus_link_desktop_file_get_link_icon_from_desktop (desktop_file);
id = gnome_desktop_item_get_string (desktop_file, "X-Gnome-Volume");
if (id != NULL) {
*volume_id = atol (id);
}
id = gnome_desktop_item_get_string (desktop_file, "X-Gnome-Drive");
if (id != NULL) {
*drive_id = atol (id);
}
gnome_desktop_item_unref (desktop_file);
}
void
nautilus_link_desktop_file_local_create_from_gnome_entry (GnomeDesktopItem *entry,
const char *dest_uri,
const GdkPoint *position,
int screen)
{
GList dummy_list;
NautilusFileChangesQueuePosition item;
GnomeDesktopItem *new_entry;
char *file_uri;
const char *name;
name = gnome_desktop_item_get_string (entry, GNOME_DESKTOP_ITEM_NAME);
file_uri = g_strdup_printf ("%s/%s.desktop", dest_uri, name);
new_entry = gnome_desktop_item_copy (entry);
gnome_desktop_item_save (new_entry, file_uri, TRUE, NULL);
dummy_list.data = file_uri;
dummy_list.next = NULL;
dummy_list.prev = NULL;
nautilus_directory_notify_files_added (&dummy_list);
nautilus_directory_schedule_metadata_remove (&dummy_list);
if (position != NULL) {
item.uri = file_uri;
item.set = TRUE;
item.point.x = position->x;
item.point.y = position->y;
item.screen = screen;
dummy_list.data = &item;
dummy_list.next = NULL;
dummy_list.prev = NULL;
nautilus_directory_schedule_position_set (&dummy_list);
}
gnome_desktop_item_unref (new_entry);
}

View file

@ -1,55 +0,0 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-link-desktop-file.h: .
Copyright (C) 2001 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.
Authors: Jonathan Blandford <jrb@redhat.com>
*/
#ifndef NAUTILUS_LINK_DESKTOP_FILE_H
#define NAUTILUS_LINK_DESKTOP_FILE_H
#include <libnautilus-private/nautilus-link.h>
gboolean nautilus_link_desktop_file_local_create (const char *directory_uri,
const char *base_name,
const char *display_name,
const char *image,
const char *target_uri,
const GdkPoint *point,
int screen,
gboolean unique_filename);
gboolean nautilus_link_desktop_file_local_set_text (const char *uri,
const char *text);
char * nautilus_link_desktop_file_local_get_text (const char *uri);
char * nautilus_link_desktop_file_local_get_additional_text (const char *uri);
char * nautilus_link_desktop_file_local_get_link_uri (const char *uri);
void nautilus_link_desktop_file_get_link_info_given_file_contents (const char *file_contents,
int link_file_size,
char **uri,
char **name,
char **icon,
gulong *drive_id,
gulong *volume_id);
void nautilus_link_desktop_file_local_create_from_gnome_entry (GnomeDesktopItem *entry,
const char *dest_uri,
const GdkPoint *position,
int screen);
#endif /* NAUTILUS_LINK_DESKTOP_FILE_H */

View file

@ -1,8 +1,8 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-link.c: xml-based link files.
nautilus-link.c: .desktop link files.
Copyright (C) 1999, 2000, 2001 Eazel, Inc.
Copyright (C) 2001 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
@ -10,7 +10,7 @@
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
but WITHOUT ANY WARRANTY; without even the historicalied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
@ -19,39 +19,30 @@
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Author: Andy Hertzfeld <andy@eazel.com>
Authors: Jonathan Blandford <jrb@redhat.com>
Alexander Larsson <alexl@redhat.com>
*/
#include <config.h>
#include "nautilus-link.h"
#include "nautilus-link-desktop-file.h"
#include "nautilus-directory-notify.h"
#include "nautilus-directory.h"
#include "nautilus-file-attributes.h"
#include "nautilus-file.h"
#include "nautilus-file-utilities.h"
#include "nautilus-global-preferences.h"
#include "nautilus-metadata.h"
#include <eel/eel-glib-extensions.h>
#include <eel/eel-gnome-extensions.h>
#include <eel/eel-stock-dialogs.h>
#include <eel/eel-string.h>
#include "nautilus-file.h"
#include "nautilus-program-choosing.h"
#include <eel/eel-vfs-extensions.h>
#include <eel/eel-xml-extensions.h>
#include <libxml/parser.h>
#include <glib/gi18n.h>
#include <libgnome/gnome-util.h>
#include <libgnomevfs/gnome-vfs-ops.h>
#include <libgnomevfs/gnome-vfs-mime-utils.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <gio/gfile.h>
#include <gio/gfileinfo.h>
#include <gio/gcontenttype.h>
#include <stdlib.h>
#include <string.h>
/* NOTE: This is pretty ugly.
* We once supported another type of link, "historical" links, which were xml files.
* I've now removed that code, but that makes this file sort of unnecessary, and we
* could clean up the code a lot since we know we're dealing with desktop files.
*/
#define NAUTILUS_LINK_GENERIC_TAG "Link"
#define NAUTILUS_LINK_TRASH_TAG "X-nautilus-trash"
#define NAUTILUS_LINK_MOUNT_TAG "FSDevice"
#define NAUTILUS_LINK_HOME_TAG "X-nautilus-home"
static gboolean
is_link_mime_type (const char *mime_type)
@ -61,37 +52,36 @@ is_link_mime_type (const char *mime_type)
g_ascii_strcasecmp (mime_type, "application/x-desktop") == 0)) {
return TRUE;
}
return FALSE;
}
static gboolean
is_local_file_a_link (const char *uri, GnomeVFSFileInfo *opt_info)
is_local_file_a_link (const char *uri)
{
gboolean link;
GnomeVFSResult result;
GnomeVFSFileInfo *info;
GFile *file;
GFileInfo *info;
GError *error;
if (!(info = opt_info)) {
info = gnome_vfs_file_info_new ();
error = NULL;
link = FALSE;
result = gnome_vfs_get_file_info (uri, info,
GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
if (result != GNOME_VFS_OK) {
gnome_vfs_file_info_unref (info);
info = NULL;
}
file = g_file_new_for_uri (uri);
info = g_file_query_info (file,
G_FILE_ATTRIBUTE_STD_CONTENT_TYPE,
0, NULL, &error);
if (info) {
link = is_link_mime_type (g_file_info_get_content_type (info));
g_object_unref (info);
}
else {
g_warning ("Error getting info: %s\n", error->message);
g_error_free (error);
}
if (info && info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE) {
link = is_link_mime_type (info->mime_type);
} else {
link = FALSE;
}
if (!opt_info && info)
gnome_vfs_file_info_unref (info);
g_object_unref (file);
return link;
}
@ -99,74 +89,380 @@ is_local_file_a_link (const char *uri, GnomeVFSFileInfo *opt_info)
static gboolean
is_link_data (const char *file_contents, int file_size)
{
return is_link_mime_type
(gnome_vfs_get_mime_type_for_data (file_contents, file_size));
char *mimetype;
gboolean res;
mimetype = g_content_type_guess (NULL, file_contents, file_size, NULL);
res = is_link_mime_type (mimetype);
g_free (mimetype);
return res;
}
static char *
slurp_key_string (const char *uri,
const char *keyname,
gboolean localize)
{
GnomeDesktopItem *desktop_file;
const char *text;
char *result;
desktop_file = gnome_desktop_item_new_from_uri (uri, 0, NULL);
if (desktop_file == NULL) {
return NULL;
}
if (localize) {
text = gnome_desktop_item_get_localestring (desktop_file, keyname);
} else {
text = gnome_desktop_item_get_string (desktop_file, keyname);
}
result = g_strdup (text);
gnome_desktop_item_unref (desktop_file);
return result;
}
gboolean
nautilus_link_local_create (const char *directory_uri,
const char *file_name,
const char *display_name,
const char *image,
const char *target_uri,
nautilus_link_local_create (const char *directory_uri,
const char *base_name,
const char *display_name,
const char *image,
const char *target_uri,
const GdkPoint *point,
int screen,
gboolean unique_filename)
int screen,
gboolean unique_filename)
{
return nautilus_link_desktop_file_local_create (directory_uri,
file_name,
display_name, image,
target_uri,
point, screen,
unique_filename);
char *real_directory_uri;
char *uri, *contents;
GnomeDesktopItem *desktop_item;
GList dummy_list;
NautilusFileChangesQueuePosition item;
g_return_val_if_fail (directory_uri != NULL, FALSE);
g_return_val_if_fail (base_name != NULL, FALSE);
g_return_val_if_fail (display_name != NULL, FALSE);
g_return_val_if_fail (target_uri != NULL, FALSE);
if (eel_uri_is_trash (directory_uri) ||
eel_uri_is_search (directory_uri)) {
return FALSE;
}
if (eel_uri_is_desktop (directory_uri)) {
real_directory_uri = nautilus_get_desktop_directory_uri ();
} else {
real_directory_uri = g_strdup (directory_uri);
}
if (unique_filename) {
uri = nautilus_ensure_unique_file_name (real_directory_uri,
base_name, ".desktop");
if (uri == NULL) {
g_free (real_directory_uri);
return FALSE;
}
} else {
char *link_name;
GFile *dir, *link;
link_name = g_strdup_printf ("%s.desktop", base_name);
/* replace '/' with '-', just in case */
g_strdelimit (link_name, "/", '-');
dir = g_file_new_for_uri (directory_uri);
link = g_file_get_child (dir, link_name);
uri = g_file_get_uri (link);
g_free (link_name);
g_object_unref (dir);
g_object_unref (link);
}
g_free (real_directory_uri);
contents = g_strdup_printf ("[Desktop Entry]\n"
"Encoding=UTF-8\n"
"Name=%s\n"
"Type=Link\n"
"URL=%s\n"
"%s%s\n",
display_name,
target_uri,
image != NULL ? "Icon=" : "",
image != NULL ? image : "");
desktop_item = gnome_desktop_item_new_from_string (uri,
contents,
strlen (contents),
0,
NULL);
if (!desktop_item) {
g_free (contents);
g_free (uri);
return FALSE;
}
if (!gnome_desktop_item_save (desktop_item, uri, TRUE, NULL)) {
gnome_desktop_item_unref (desktop_item);
g_free (contents);
g_free (uri);
return FALSE;
}
dummy_list.data = uri;
dummy_list.next = NULL;
dummy_list.prev = NULL;
nautilus_directory_notify_files_added_by_uri (&dummy_list);
nautilus_directory_schedule_metadata_remove_by_uri (&dummy_list);
if (point != NULL) {
item.location = g_file_new_for_uri (uri);
item.set = TRUE;
item.point.x = point->x;
item.point.y = point->y;
item.screen = screen;
dummy_list.data = &item;
dummy_list.next = NULL;
dummy_list.prev = NULL;
nautilus_directory_schedule_position_set (&dummy_list);
g_object_unref (item.location);
}
gnome_desktop_item_unref (desktop_item);
g_free (contents);
g_free (uri);
return TRUE;
}
/* returns additional text to display under the name, NULL if none */
char *
nautilus_link_local_get_additional_text (const char *uri)
gboolean
nautilus_link_local_set_text (const char *uri,
const char *text)
{
if (!is_local_file_a_link (uri, NULL)) {
GnomeDesktopItem *desktop_file;
gboolean success;
desktop_file = gnome_desktop_item_new_from_uri (uri, 0, NULL);
if (desktop_file == NULL) {
return FALSE;
}
gnome_desktop_item_set_localestring (desktop_file, "Name", text);
success = gnome_desktop_item_save (desktop_file, NULL, FALSE, NULL);
gnome_desktop_item_unref (desktop_file);
return success;
}
char *
nautilus_link_local_get_text (const char *path)
{
return slurp_key_string (path, "Name", TRUE);
}
char *
nautilus_link_local_get_additional_text (const char *path)
{
/* The comment field of current .desktop files is often bad.
* It just contains a copy of the name. This is probably because the
* panel shows the comment field as a tooltip.
*/
return NULL;
#ifdef THIS_IS_NOT_USED_RIGHT_NOW
char *type;
char *retval;
if (!is_local_file_a_link (uri)) {
return NULL;
}
type = slurp_key_string (path, "Type", FALSE);
retval = NULL;
if (type == NULL) {
return NULL;
}
if (strcmp (type, "Application") == 0) {
retval = slurp_key_string (path, "Comment", TRUE);
}
return nautilus_link_desktop_file_local_get_additional_text (uri);
g_free (type);
return retval;
#endif
}
static char *
nautilus_link_get_link_uri_from_desktop (GnomeDesktopItem *desktop_file)
{
const char *launch_string;
const char *type;
char *retval;
retval = NULL;
type = gnome_desktop_item_get_string (desktop_file, "Type");
if (type == NULL) {
return NULL;
}
if (strcmp (type, "Application") == 0) {
launch_string = gnome_desktop_item_get_string (desktop_file, "Exec");
if (launch_string == NULL) {
return NULL;
}
launch_string = gnome_desktop_item_get_location (desktop_file);
retval = g_strconcat (NAUTILUS_DESKTOP_COMMAND_SPECIFIER, launch_string, NULL);
} else if (strcmp (type, "URL") == 0) {
/* Some old broken desktop files use this nonstandard feature, we need handle it though */
retval = g_strdup (gnome_desktop_item_get_string (desktop_file, "Exec"));
} else if ((strcmp (type, NAUTILUS_LINK_GENERIC_TAG) == 0) ||
(strcmp (type, NAUTILUS_LINK_MOUNT_TAG) == 0) ||
(strcmp (type, NAUTILUS_LINK_TRASH_TAG) == 0) ||
(strcmp (type, NAUTILUS_LINK_HOME_TAG) == 0)) {
retval = g_strdup (gnome_desktop_item_get_string (desktop_file, "URL"));
}
return retval;
}
static char *
nautilus_link_get_link_name_from_desktop (GnomeDesktopItem *desktop_file)
{
return g_strdup (gnome_desktop_item_get_localestring (desktop_file, "Name"));
}
static char *
nautilus_link_get_link_icon_from_desktop (GnomeDesktopItem *desktop_file)
{
char *icon_uri;
const char *icon;
GnomeDesktopItemType desktop_type;
icon_uri = g_strdup (gnome_desktop_item_get_string (desktop_file, "X-Nautilus-Icon"));
if (icon_uri != NULL) {
return icon_uri;
}
icon = gnome_desktop_item_get_string (desktop_file, GNOME_DESKTOP_ITEM_ICON);
if (icon != NULL) {
return g_strdup (icon);
}
desktop_type = gnome_desktop_item_get_entry_type (desktop_file);
switch (desktop_type) {
case GNOME_DESKTOP_ITEM_TYPE_APPLICATION:
return g_strdup ("gnome-fs-executable");
case GNOME_DESKTOP_ITEM_TYPE_LINK:
return g_strdup ("gnome-dev-symlink");
case GNOME_DESKTOP_ITEM_TYPE_FSDEVICE:
return g_strdup ("gnome-dev-harddisk");
case GNOME_DESKTOP_ITEM_TYPE_DIRECTORY:
return g_strdup ("gnome-fs-directory");
case GNOME_DESKTOP_ITEM_TYPE_SERVICE:
case GNOME_DESKTOP_ITEM_TYPE_SERVICE_TYPE:
return g_strdup ("gnome-fs-web");
default:
return g_strdup ("gnome-fs-regular");
}
g_assert_not_reached ();
return NULL;
}
/* Returns the link uri associated with a link file. */
char *
nautilus_link_local_get_link_uri (const char *uri)
{
if (!is_local_file_a_link (uri, NULL)) {
GnomeDesktopItem *desktop_file;
char *retval;
if (!is_local_file_a_link (uri)) {
return NULL;
}
return nautilus_link_desktop_file_local_get_link_uri (uri);
}
void
nautilus_link_get_link_info_given_file_contents (const char *file_contents,
int link_file_size,
char **uri,
char **name,
char **icon,
gulong *drive_id,
gulong *volume_id)
{
*uri = NULL;
*name = NULL;
*icon = NULL;
*drive_id = 0;
*volume_id = 0;
if (is_link_data (file_contents, link_file_size)) {
nautilus_link_desktop_file_get_link_info_given_file_contents (file_contents, link_file_size, uri, name, icon, drive_id, volume_id);
desktop_file = gnome_desktop_item_new_from_uri (uri, 0, NULL);
if (desktop_file == NULL) {
return NULL;
}
retval = nautilus_link_get_link_uri_from_desktop (desktop_file);
gnome_desktop_item_unref (desktop_file);
return retval;
}
void
nautilus_link_local_create_from_gnome_entry (GnomeDesktopItem *item,
const char *dest_uri,
const GdkPoint *position,
int screen)
nautilus_link_get_link_info_given_file_contents (const char *file_contents,
int link_file_size,
char **uri,
char **name,
char **icon)
{
nautilus_link_desktop_file_local_create_from_gnome_entry (item, dest_uri, position, screen);
GnomeDesktopItem *desktop_file;
if (!is_link_data (file_contents, link_file_size)) {
return;
}
desktop_file = gnome_desktop_item_new_from_string (NULL, file_contents, link_file_size, 0, NULL);
if (desktop_file == NULL) {
return;
}
*uri = nautilus_link_get_link_uri_from_desktop (desktop_file);
*name = nautilus_link_get_link_name_from_desktop (desktop_file);
*icon = nautilus_link_get_link_icon_from_desktop (desktop_file);
gnome_desktop_item_unref (desktop_file);
}
void
nautilus_link_local_create_from_gnome_entry (GnomeDesktopItem *entry,
const char *dest_uri,
const GdkPoint *position,
int screen)
{
GList dummy_list;
NautilusFileChangesQueuePosition item;
GnomeDesktopItem *new_entry;
char *file_uri;
const char *name;
name = gnome_desktop_item_get_string (entry, GNOME_DESKTOP_ITEM_NAME);
file_uri = g_strdup_printf ("%s/%s.desktop", dest_uri, name);
new_entry = gnome_desktop_item_copy (entry);
gnome_desktop_item_save (new_entry, file_uri, TRUE, NULL);
dummy_list.data = file_uri;
dummy_list.next = NULL;
dummy_list.prev = NULL;
nautilus_directory_notify_files_added_by_uri (&dummy_list);
nautilus_directory_schedule_metadata_remove_by_uri (&dummy_list);
if (position != NULL) {
item.location = g_file_new_for_uri (file_uri);
item.set = TRUE;
item.point.x = position->x;
item.point.y = position->y;
item.screen = screen;
dummy_list.data = &item;
dummy_list.next = NULL;
dummy_list.prev = NULL;
nautilus_directory_schedule_position_set (&dummy_list);
g_object_unref (item.location);
}
gnome_desktop_item_unref (new_entry);
}

View file

@ -1,9 +1,8 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-link.h: xml-based link files that control their appearance
and behavior.
nautilus-link.h: .
Copyright (C) 2000 Eazel, Inc.
Copyright (C) 2001 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
@ -20,7 +19,7 @@
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Authors: Andy Hertzfeld <andy@eazel.com>
Authors: Jonathan Blandford <jrb@redhat.com>
*/
#ifndef NAUTILUS_LINK_H
@ -28,44 +27,28 @@
#include <gdk/gdktypes.h>
#include <libgnome/gnome-desktop-item.h>
#include <libgnomevfs/gnome-vfs-file-info.h>
/* Create a new link file. Takes a path, works locally, and uses sync. I/O.
* Returns TRUE if it succeeds, FALSE if it fails.
*/
gboolean nautilus_link_local_create (const char *directory_uri,
const char *file_name,
const char *display_name,
const char *image,
const char *target_uri,
const GdkPoint *point,
int screen,
gboolean unique_filename);
/* Returns additional text to display under the name, NULL if
* none. Despite the fact that it takes a URI parameter, works only if
* the file is local and does sync. I/O.
*/
char * nautilus_link_local_get_additional_text (const char *uri);
/* Returns the link uri associated with a link file. The first version
* works only if the file is local and does sync. I/O, despite the
* fact that it takes a URI parameter. The second version takes the
* contents of a file already in memory.
*/
char * nautilus_link_local_get_link_uri (const char *uri);
void nautilus_link_get_link_info_given_file_contents (const char *file_contents,
int link_file_size,
char **uri,
char **name,
char **icon,
gulong *drive_id,
gulong *volume_id);
void nautilus_link_local_create_from_gnome_entry (GnomeDesktopItem *item,
const char *dest_uri,
const GdkPoint *position,
int screen);
gboolean nautilus_link_local_create (const char *directory_uri,
const char *base_name,
const char *display_name,
const char *image,
const char *target_uri,
const GdkPoint *point,
int screen,
gboolean unique_filename);
gboolean nautilus_link_local_set_text (const char *uri,
const char *text);
char * nautilus_link_local_get_text (const char *uri);
char * nautilus_link_local_get_additional_text (const char *uri);
char * nautilus_link_local_get_link_uri (const char *uri);
void nautilus_link_get_link_info_given_file_contents (const char *file_contents,
int link_file_size,
char **uri,
char **name,
char **icon);
void nautilus_link_local_create_from_gnome_entry (GnomeDesktopItem *entry,
const char *dest_uri,
const GdkPoint *position,
int screen);
#endif /* NAUTILUS_LINK_H */

View file

@ -559,7 +559,7 @@ real_directory_notify_files_removed (NautilusDirectory *real_directory)
}
if (files) {
nautilus_directory_notify_files_removed (files);
nautilus_directory_notify_files_removed_by_uri (files);
}
eel_g_list_free_deep (files);

View file

@ -36,12 +36,9 @@
#include <eel/eel-string.h>
#include <eel/eel-vfs-extensions.h>
#include <eel/eel-xml-extensions.h>
#include <glib/gurifuncs.h>
#include <libxml/parser.h>
#include <gtk/gtkmain.h>
#include <libgnomevfs/gnome-vfs-file-info.h>
#include <libgnomevfs/gnome-vfs-types.h>
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libgnomevfs/gnome-vfs.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
@ -110,14 +107,13 @@ BONOBO_CLASS_BOILERPLATE_FULL (NautilusMetafile, nautilus_metafile,
BonoboObject, BONOBO_OBJECT_TYPE)
typedef struct MetafileReadState {
EelReadFileHandle *handle;
GnomeVFSAsyncHandle *get_file_info_handle;
NautilusMetafile *metafile;
GCancellable *cancellable;
} MetafileReadState;
typedef struct MetafileWriteState {
GnomeVFSAsyncHandle *handle;
xmlChar *buffer;
GnomeVFSFileSize size;
goffset size;
gboolean write_again;
} MetafileWriteState;
@ -137,7 +133,6 @@ struct NautilusMetafileDetails {
char *private_uri;
char *directory_uri;
GnomeVFSURI *directory_vfs_uri;
};
static GHashTable *metafiles;
@ -162,9 +157,6 @@ finalize (GObject *object)
async_read_cancel (metafile);
g_assert (metafile->details->read_state == NULL);
if (metafile->details->directory_vfs_uri != NULL) {
gnome_vfs_uri_unref (metafile->details->directory_vfs_uri);
}
g_hash_table_remove (metafiles, metafile->details->directory_uri);
@ -181,6 +173,43 @@ finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static char *
escape_slashes (const char *str)
{
int n_reserved;
const char *p;
char *escaped, *e;
n_reserved = 0;
for (p = str; *p != 0; p++) {
if (*p == '%' || *p == '/') {
n_reserved++;
}
}
escaped = g_malloc (strlen (str) + 2*n_reserved + 1);
e = escaped;
for (p = str; *p != 0; p++) {
if (*p == '%') {
*e++ = '%';
*e++ = '2';
*e++ = '5';
} else if (*p == '/') {
*e++ = '%';
*e++ = '2';
*e++ = 'f';
} else {
*e++ = *p;
}
}
*e = 0;
return escaped;
}
static char *
construct_private_metafile_uri (const char *uri)
{
@ -195,7 +224,7 @@ construct_private_metafile_uri (const char *uri)
mkdir (metafiles_directory, 0700);
/* Construct a file name from the URI. */
escaped_uri = gnome_vfs_escape_slashes (uri);
escaped_uri = escape_slashes (uri);
file_name = g_strconcat (escaped_uri, ".xml", NULL);
g_free (escaped_uri);
@ -203,7 +232,7 @@ construct_private_metafile_uri (const char *uri)
alternate_path = g_build_filename (metafiles_directory, file_name, NULL);
g_free (metafiles_directory);
g_free (file_name);
alternate_uri = gnome_vfs_get_uri_from_local_path (alternate_path);
alternate_uri = g_filename_to_uri (alternate_path, NULL, NULL);
g_free (alternate_path);
return alternate_uri;
@ -220,11 +249,6 @@ nautilus_metafile_set_directory_uri (NautilusMetafile *metafile,
g_free (metafile->details->directory_uri);
metafile->details->directory_uri = g_strdup (directory_uri);
if (metafile->details->directory_vfs_uri != NULL) {
gnome_vfs_uri_unref (metafile->details->directory_vfs_uri);
}
metafile->details->directory_vfs_uri = gnome_vfs_uri_new (directory_uri);
g_free (metafile->details->private_uri);
metafile->details->private_uri
= construct_private_metafile_uri (directory_uri);
@ -247,6 +271,7 @@ nautilus_metafile_get (const char *directory_uri)
{
NautilusMetafile *metafile;
char *canonical_uri;
GFile *file;
g_return_val_if_fail (directory_uri != NULL, NULL);
@ -259,8 +284,11 @@ nautilus_metafile_get (const char *directory_uri)
metafiles = eel_g_hash_table_new_free_at_exit
(g_str_hash, g_str_equal, __FILE__ ": metafiles");
}
canonical_uri = nautilus_directory_make_uri_canonical (directory_uri);
file = g_file_new_for_uri (directory_uri);
canonical_uri = g_file_get_uri (file);
g_object_unref (file);
metafile = g_hash_table_lookup (metafiles, canonical_uri);
@ -992,6 +1020,7 @@ get_file_node (NautilusMetafile *metafile,
{
GHashTable *hash;
xmlNode *root, *node;
char *escaped_file_name;
g_assert (NAUTILUS_IS_METAFILE (metafile));
@ -1004,7 +1033,9 @@ get_file_node (NautilusMetafile *metafile,
if (create) {
root = create_metafile_root (metafile);
node = xmlNewChild (root, NULL, "file", NULL);
xmlSetProp (node, "name", file_name);
escaped_file_name = g_uri_escape_string (file_name, NULL, 0);
xmlSetProp (node, "name", escaped_file_name);
g_free (escaped_file_name);
g_hash_table_insert (hash, xmlMemStrdup (file_name), node);
return node;
}
@ -1523,10 +1554,16 @@ static char *
metafile_get_file_uri (NautilusMetafile *metafile,
const char *file_name)
{
char *escaped_file_name, *uri;
g_return_val_if_fail (NAUTILUS_IS_METAFILE (metafile), NULL);
g_return_val_if_fail (file_name != NULL, NULL);
return g_build_filename (metafile->details->directory_uri, file_name, NULL);
escaped_file_name = g_uri_escape_string (file_name, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, FALSE);
uri = g_build_filename (metafile->details->directory_uri, escaped_file_name, NULL);
g_free (escaped_file_name);
return uri;
}
static void
@ -1539,6 +1576,7 @@ rename_file_metadata (NautilusMetafile *metafile,
xmlNode *file_node;
GHashTable *hash;
char *old_file_uri, *new_file_uri;
char *escaped;
g_return_if_fail (NAUTILUS_IS_METAFILE (metafile));
g_return_if_fail (old_file_name != NULL);
@ -1559,7 +1597,9 @@ rename_file_metadata (NautilusMetafile *metafile,
xmlFree (key);
g_hash_table_insert (hash,
xmlMemStrdup (new_file_name), value);
xmlSetProp (file_node, "name", new_file_name);
escaped = g_uri_escape_string (new_file_name, NULL, FALSE);
xmlSetProp (file_node, "name", escaped);
g_free (escaped);
directory_request_write_metafile (metafile);
}
} else {
@ -1667,6 +1707,7 @@ real_copy_file_metadata (NautilusMetafile *source_metafile,
{
xmlNodePtr source_node, node, root;
GHashTable *hash, *changes;
char *escaped;
real_remove_file_metadata (destination_metafile, destination_file_name);
g_assert (get_file_node (destination_metafile, destination_file_name, FALSE) == NULL);
@ -1676,7 +1717,9 @@ real_copy_file_metadata (NautilusMetafile *source_metafile,
node = xmlCopyNode (source_node, TRUE);
root = create_metafile_root (destination_metafile);
xmlAddChild (root, node);
xmlSetProp (node, "name", destination_file_name);
escaped = g_uri_escape_string (destination_file_name, NULL, FALSE);
xmlSetProp (node, "name", escaped);
g_free (escaped);
set_file_node_timestamp (node);
g_hash_table_insert (destination_metafile->details->node_hash,
xmlMemStrdup (destination_file_name), node);
@ -1803,6 +1846,7 @@ set_metafile_contents (NautilusMetafile *metafile,
GHashTable *hash;
xmlNodePtr node;
xmlChar *name;
char *unescaped_name;
g_return_if_fail (NAUTILUS_IS_METAFILE (metafile));
g_return_if_fail (metafile->details->xml == NULL);
@ -1819,11 +1863,13 @@ set_metafile_contents (NautilusMetafile *metafile,
node != NULL; node = node->next) {
if (strcmp (node->name, "file") == 0) {
name = xmlGetProp (node, "name");
if (g_hash_table_lookup (hash, name) != NULL) {
unescaped_name = g_uri_unescape_string (name, "/");
if (unescaped_name == NULL ||
g_hash_table_lookup (hash, unescaped_name) != NULL) {
xmlFree (name);
/* FIXME: Should we delete duplicate nodes as we discover them? */
} else {
g_hash_table_insert (hash, name, node);
g_hash_table_insert (hash, unescaped_name, node);
}
}
}
@ -1833,21 +1879,23 @@ static void
metafile_read_cancel (NautilusMetafile *metafile)
{
if (metafile->details->read_state != NULL) {
if (metafile->details->read_state->handle != NULL) {
eel_read_file_cancel (metafile->details->read_state->handle);
}
if (metafile->details->read_state->get_file_info_handle != NULL) {
gnome_vfs_async_cancel (metafile->details->read_state->get_file_info_handle);
}
g_free (metafile->details->read_state);
g_cancellable_cancel (metafile->details->read_state->cancellable);
metafile->details->read_state->metafile = NULL;
metafile->details->read_state = NULL;
}
}
static void
metafile_read_state_free (MetafileReadState *state)
{
g_object_unref (state->cancellable);
g_free (state);
}
static void
metafile_read_mark_done (NautilusMetafile *metafile)
{
g_free (metafile->details->read_state);
metafile_read_state_free (metafile->details->read_state);
metafile->details->read_state = NULL;
metafile->details->is_read = TRUE;
@ -1862,66 +1910,58 @@ metafile_read_mark_done (NautilusMetafile *metafile)
}
static void
metafile_read_done (NautilusMetafile *metafile)
metafile_read_done_callback (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
MetafileReadState *state;
NautilusMetafile *metafile;
gsize file_size;
char *file_contents;
state = user_data;
if (state->metafile == NULL) {
/* Operation was cancelled. Bail out */
metafile_read_state_free (state);
return;
}
metafile = state->metafile;
g_assert (metafile->details->xml == NULL);
if (g_file_load_contents_finish (G_FILE (source_object),
res,
&file_contents, &file_size,
NULL, NULL)) {
set_metafile_contents (metafile, xmlParseMemory (file_contents, file_size));
g_free (file_contents);
}
metafile_read_mark_done (metafile);
nautilus_metadata_process_ready_copies ();
nautilus_metadata_process_ready_removals ();
}
static void
metafile_read_failed (NautilusMetafile *metafile)
{
g_assert (NAUTILUS_IS_METAFILE (metafile));
metafile->details->read_state->handle = NULL;
metafile_read_done (metafile);
}
static void
metafile_read_done_callback (GnomeVFSResult result,
GnomeVFSFileSize file_size,
char *file_contents,
gpointer callback_data)
{
NautilusMetafile *metafile;
int size;
char *buffer;
metafile = NAUTILUS_METAFILE (callback_data);
g_assert (metafile->details->xml == NULL);
if (result != GNOME_VFS_OK) {
g_assert (file_contents == NULL);
metafile_read_failed (metafile);
return;
}
size = file_size;
if ((GnomeVFSFileSize) size != file_size) {
g_free (file_contents);
metafile_read_failed (metafile);
return;
}
/* The libxml parser requires a zero-terminated array. */
buffer = g_realloc (file_contents, size + 1);
buffer[size] = '\0';
set_metafile_contents (metafile, xmlParseMemory (buffer, size));
g_free (buffer);
metafile_read_done (metafile);
}
static void
metafile_read_restart (NautilusMetafile *metafile)
{
metafile->details->read_state->handle = eel_read_entire_file_async
(metafile->details->private_uri,
GNOME_VFS_PRIORITY_DEFAULT,
metafile_read_done_callback, metafile);
GFile *location;
MetafileReadState *state;
state = g_new0 (MetafileReadState, 1);
state->metafile = metafile;
state->cancellable = g_cancellable_new ();
metafile->details->read_state = state;
location = g_file_new_for_uri (metafile->details->private_uri);
g_file_load_contents_async (location, state->cancellable,
metafile_read_done_callback, state);
g_object_unref (location);
}
static gboolean
@ -1973,7 +2013,6 @@ metafile_read_start (NautilusMetafile *metafile)
if (!allow_metafile (metafile)) {
metafile_read_mark_done (metafile);
} else {
metafile->details->read_state = g_new0 (MetafileReadState, 1);
metafile_read_restart (metafile);
}
}
@ -2083,7 +2122,7 @@ metafile_write_start (NautilusMetafile *metafile)
metafile_uri = metafile->details->private_uri;
metafile_path = gnome_vfs_get_local_path_from_uri (metafile_uri);
metafile_path = g_filename_from_uri (metafile_uri, NULL, NULL);
g_assert (metafile_path != NULL);
metafile_write_local (metafile, metafile_path);

File diff suppressed because it is too large Load diff

View file

@ -25,22 +25,36 @@
#ifndef NAUTILUS_MIME_ACTIONS_H
#define NAUTILUS_MIME_ACTIONS_H
#include <libgnomevfs/gnome-vfs-mime-handlers.h>
#include <gio/gappinfo.h>
#include <libnautilus-private/nautilus-file.h>
#include <libnautilus-private/nautilus-window-info.h>
NautilusFileAttributes nautilus_mime_actions_get_minimum_file_attributes (void);
NautilusFileAttributes nautilus_mime_actions_get_full_file_attributes (void);
NautilusFileAttributes nautilus_mime_actions_get_required_file_attributes (void);
GnomeVFSMimeApplication *nautilus_mime_get_default_application_for_file (NautilusFile *file);
GList * nautilus_mime_get_open_with_applications_for_file (NautilusFile *file);
GList * nautilus_mime_get_applications_for_file (NautilusFile *file);
GAppInfo * nautilus_mime_get_default_application_for_file (NautilusFile *file);
GList * nautilus_mime_get_applications_for_file (NautilusFile *file);
GnomeVFSMimeApplication *nautilus_mime_get_default_application_for_files (GList *files);
GList * nautilus_mime_get_open_with_applications_for_files (GList *files);
GList * nautilus_mime_get_applications_for_files (GList *file);
GAppInfo * nautilus_mime_get_default_application_for_files (GList *files);
GList * nautilus_mime_get_applications_for_files (GList *file);
gboolean nautilus_mime_has_any_applications_for_file (NautilusFile *file);
gboolean nautilus_mime_has_any_applications_for_files (GList *files);
gboolean nautilus_mime_file_opens_in_view (NautilusFile *file);
gboolean nautilus_mime_file_opens_in_external_app (NautilusFile *file);
void nautilus_mime_activate_files (GtkWindow *parent_window,
NautilusWindowInfo *window_info,
GList *files,
const char *launch_directory,
NautilusWindowOpenMode mode,
NautilusWindowOpenFlags flags);
void nautilus_mime_activate_file (GtkWindow *parent_window,
NautilusWindowInfo *window_info,
NautilusFile *file,
const char *launch_directory,
NautilusWindowOpenMode mode,
NautilusWindowOpenFlags flags);
gboolean nautilus_mime_has_any_applications_for_file (NautilusFile *file);
gboolean nautilus_mime_has_any_applications_for_files (GList *files);
#endif /* NAUTILUS_MIME_ACTIONS_H */

View file

@ -0,0 +1,676 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/*
nautilus-mime-application-chooser.c: an mime-application chooser
Copyright (C) 2004 Novell, Inc.
Copyright (C) 2007 Red Hat, Inc.
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The Gnome Library is distributed in the hope that it will be useful,
but APPLICATIONOUT ANY WARRANTY; applicationout even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along application the Gnome Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Authors: Dave Camp <dave@novell.com>
Alexander Larsson <alexl@redhat.com>
*/
#include <config.h>
#include "nautilus-mime-application-chooser.h"
#include "nautilus-open-with-dialog.h"
#include "nautilus-signaller.h"
#include <eel/eel-stock-dialogs.h>
#include <eel/eel-glib-extensions.h>
#include <string.h>
#include <glib/gi18n-lib.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gtk/gtkalignment.h>
#include <gtk/gtkbox.h>
#include <gtk/gtkbutton.h>
#include <gtk/gtkcellrenderertext.h>
#include <gtk/gtkcellrenderertoggle.h>
#include <gtk/gtkcellrendererpixbuf.h>
#include <gtk/gtkentry.h>
#include <gtk/gtkhbbox.h>
#include <gtk/gtkimage.h>
#include <gtk/gtkicontheme.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkliststore.h>
#include <gtk/gtkscrolledwindow.h>
#include <gtk/gtkstock.h>
#include <gtk/gtktreeview.h>
#include <gtk/gtktreeselection.h>
#include <gtk/gtkvbox.h>
#include <gio/gcontenttype.h>
#include <gio/gthemedicon.h>
#include <gio/gfileicon.h>
struct _NautilusMimeApplicationChooserDetails {
char *uri;
char *content_type;
char *extension;
char *type_description;
char *orig_mime_type;
guint refresh_timeout;
GtkWidget *label;
GtkWidget *entry;
GtkWidget *treeview;
GtkWidget *remove_button;
GtkListStore *model;
GtkCellRenderer *toggle_renderer;
};
enum {
COLUMN_APPINFO,
COLUMN_DEFAULT,
COLUMN_ICON,
COLUMN_NAME,
NUM_COLUMNS
};
static void refresh_model (NautilusMimeApplicationChooser *chooser);
static void refresh_model_soon (NautilusMimeApplicationChooser *chooser);
static gpointer parent_class;
static void
nautilus_mime_application_chooser_finalize (GObject *object)
{
NautilusMimeApplicationChooser *chooser;
chooser = NAUTILUS_MIME_APPLICATION_CHOOSER (object);
if (chooser->details->refresh_timeout) {
g_source_remove (chooser->details->refresh_timeout);
}
g_free (chooser->details->uri);
g_free (chooser->details->content_type);
g_free (chooser->details->extension);
g_free (chooser->details->type_description);
g_free (chooser->details->orig_mime_type);
g_free (chooser->details);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
nautilus_mime_application_chooser_destroy (GtkObject *object)
{
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
static void
nautilus_mime_application_chooser_class_init (NautilusMimeApplicationChooserClass *class)
{
GObjectClass *gobject_class;
GtkObjectClass *object_class;
parent_class = g_type_class_peek_parent (class);
gobject_class = G_OBJECT_CLASS (class);
gobject_class->finalize = nautilus_mime_application_chooser_finalize;
object_class = GTK_OBJECT_CLASS (class);
object_class->destroy = nautilus_mime_application_chooser_destroy;
}
static void
default_toggled_cb (GtkCellRendererToggle *renderer,
const char *path_str,
gpointer user_data)
{
NautilusMimeApplicationChooser *chooser;
GtkTreeIter iter;
GtkTreePath *path;
GError *error;
chooser = NAUTILUS_MIME_APPLICATION_CHOOSER (user_data);
path = gtk_tree_path_new_from_string (path_str);
if (gtk_tree_model_get_iter (GTK_TREE_MODEL (chooser->details->model),
&iter, path)) {
gboolean is_default;
gboolean success;
GAppInfo *info;
char *message;
gtk_tree_model_get (GTK_TREE_MODEL (chooser->details->model),
&iter,
COLUMN_DEFAULT, &is_default,
COLUMN_APPINFO, &info,
-1);
if (!is_default && info != NULL) {
error = NULL;
if (chooser->details->extension) {
success = g_app_info_set_as_default_for_extension (info,
chooser->details->extension,
&error);
} else {
success = g_app_info_set_as_default_for_type (info,
chooser->details->content_type,
&error);
}
if (!success) {
message = g_strdup_printf (_("Could not set application as the default: %s"), error->message);
eel_show_error_dialog (_("Could not set as default application"),
message,
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (chooser))));
g_free (message);
g_error_free (error);
}
g_signal_emit_by_name (nautilus_signaller_get_current (),
"mime_data_changed");
}
g_object_unref (info);
}
gtk_tree_path_free (path);
}
static GAppInfo *
get_selected_application (NautilusMimeApplicationChooser *chooser)
{
GtkTreeIter iter;
GtkTreeSelection *selection;
GAppInfo *info;
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (chooser->details->treeview));
info = NULL;
if (gtk_tree_selection_get_selected (selection,
NULL,
&iter)) {
gtk_tree_model_get (GTK_TREE_MODEL (chooser->details->model),
&iter,
COLUMN_APPINFO, &info,
-1);
}
return info;
}
static void
selection_changed_cb (GtkTreeSelection *selection,
gpointer user_data)
{
NautilusMimeApplicationChooser *chooser;
GAppInfo *info;
chooser = NAUTILUS_MIME_APPLICATION_CHOOSER (user_data);
info = get_selected_application (chooser);
if (info) {
gtk_widget_set_sensitive (chooser->details->remove_button,
g_app_info_can_remove_supports_type (info));
g_object_unref (info);
} else {
gtk_widget_set_sensitive (chooser->details->remove_button,
FALSE);
}
}
static GtkWidget *
create_tree_view (NautilusMimeApplicationChooser *chooser)
{
GtkWidget *treeview;
GtkListStore *store;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
GtkTreeSelection *selection;
treeview = gtk_tree_view_new ();
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
store = gtk_list_store_new (NUM_COLUMNS,
G_TYPE_APP_INFO,
G_TYPE_BOOLEAN,
GDK_TYPE_PIXBUF,
G_TYPE_STRING);
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
COLUMN_NAME,
GTK_SORT_ASCENDING);
gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
GTK_TREE_MODEL (store));
chooser->details->model = store;
renderer = gtk_cell_renderer_toggle_new ();
g_signal_connect (renderer, "toggled",
G_CALLBACK (default_toggled_cb),
chooser);
gtk_cell_renderer_toggle_set_radio (GTK_CELL_RENDERER_TOGGLE (renderer),
TRUE);
column = gtk_tree_view_column_new_with_attributes (_("Default"),
renderer,
"active",
COLUMN_DEFAULT,
NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
renderer = gtk_cell_renderer_pixbuf_new ();
column = gtk_tree_view_column_new_with_attributes (_("Icon"),
renderer,
"pixbuf",
COLUMN_ICON,
NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
chooser->details->toggle_renderer = renderer;
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (_("Name"),
renderer,
"markup",
COLUMN_NAME,
NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
g_signal_connect (selection, "changed",
G_CALLBACK (selection_changed_cb),
chooser);
return treeview;
}
static void
add_clicked_cb (GtkButton *button,
gpointer user_data)
{
NautilusMimeApplicationChooser *chooser;
GtkWidget *dialog;
chooser = NAUTILUS_MIME_APPLICATION_CHOOSER (user_data);
dialog = nautilus_add_application_dialog_new (chooser->details->uri,
chooser->details->orig_mime_type);
gtk_window_set_screen (GTK_WINDOW (dialog),
gtk_widget_get_screen (GTK_WIDGET (chooser)));
gtk_widget_show (dialog);
}
static void
remove_clicked_cb (GtkButton *button,
gpointer user_data)
{
NautilusMimeApplicationChooser *chooser;
GError *error;
GAppInfo *info;
chooser = NAUTILUS_MIME_APPLICATION_CHOOSER (user_data);
info = get_selected_application (chooser);
if (info) {
error = NULL;
if (!g_app_info_remove_supports_type (info,
chooser->details->content_type,
&error)) {
eel_show_error_dialog (_("Could not remove application"),
error->message,
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (chooser))));
g_error_free (error);
}
g_signal_emit_by_name (nautilus_signaller_get_current (),
"mime_data_changed");
g_object_unref (info);
}
}
static void
mime_type_data_changed_cb (GObject *signaller,
gpointer user_data)
{
NautilusMimeApplicationChooser *chooser;
chooser = NAUTILUS_MIME_APPLICATION_CHOOSER (user_data);
refresh_model_soon (chooser);
}
static void
nautilus_mime_application_chooser_instance_init (NautilusMimeApplicationChooser *chooser)
{
GtkWidget *box;
GtkWidget *scrolled;
GtkWidget *button;
chooser->details = g_new0 (NautilusMimeApplicationChooserDetails, 1);
gtk_container_set_border_width (GTK_CONTAINER (chooser), 8);
gtk_box_set_spacing (GTK_BOX (chooser), 0);
gtk_box_set_homogeneous (GTK_BOX (chooser), FALSE);
chooser->details->label = gtk_label_new ("");
gtk_misc_set_alignment (GTK_MISC (chooser->details->label), 0.0, 0.5);
gtk_label_set_line_wrap (GTK_LABEL (chooser->details->label), TRUE);
gtk_label_set_line_wrap_mode (GTK_LABEL (chooser->details->label),
PANGO_WRAP_WORD_CHAR);
gtk_box_pack_start (GTK_BOX (chooser), chooser->details->label,
FALSE, FALSE, 0);
gtk_widget_show (chooser->details->label);
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled),
GTK_SHADOW_IN);
gtk_widget_show (scrolled);
gtk_box_pack_start (GTK_BOX (chooser), scrolled, TRUE, TRUE, 6);
chooser->details->treeview = create_tree_view (chooser);
gtk_widget_show (chooser->details->treeview);
gtk_container_add (GTK_CONTAINER (scrolled),
chooser->details->treeview);
box = gtk_hbutton_box_new ();
gtk_box_set_spacing (GTK_BOX (box), 6);
gtk_button_box_set_layout (GTK_BUTTON_BOX (box), GTK_BUTTONBOX_END);
gtk_box_pack_start (GTK_BOX (chooser), box, FALSE, FALSE, 6);
gtk_widget_show (box);
button = gtk_button_new_from_stock (GTK_STOCK_ADD);
g_signal_connect (button, "clicked",
G_CALLBACK (add_clicked_cb),
chooser);
gtk_widget_show (button);
gtk_container_add (GTK_CONTAINER (box), button);
button = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
g_signal_connect (button, "clicked",
G_CALLBACK (remove_clicked_cb),
chooser);
gtk_widget_show (button);
gtk_container_add (GTK_CONTAINER (box), button);
chooser->details->remove_button = button;
g_signal_connect (nautilus_signaller_get_current (),
"mime_data_changed",
G_CALLBACK (mime_type_data_changed_cb),
chooser);
}
static char *
get_extension (const char *basename)
{
char *p;
p = strrchr (basename, '.');
if (p && *(p + 1) != '\0') {
return g_strdup (p + 1);
} else {
return NULL;
}
}
static GdkPixbuf *
get_pixbuf_for_icon (GIcon *icon)
{
GdkPixbuf *pixbuf;
char *filename;
pixbuf = NULL;
if (G_IS_FILE_ICON (icon)) {
filename = g_file_get_path (g_file_icon_get_file (G_FILE_ICON (icon)));
if (filename) {
pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 24, 24, NULL);
}
g_free (filename);
} else if (G_IS_THEMED_ICON (icon)) {
const char * const *names;
char *icon_no_extension;
char *p;
names = g_themed_icon_get_names (G_THEMED_ICON (icon));
if (names != NULL && names[0] != NULL) {
icon_no_extension = g_strdup (names[0]);
p = strrchr (icon_no_extension, '.');
if (p &&
(strcmp (p, ".png") == 0 ||
strcmp (p, ".xpm") == 0 ||
strcmp (p, ".svg") == 0)) {
*p = 0;
}
pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
icon_no_extension, 24, 0, NULL);
g_free (icon_no_extension);
}
}
return pixbuf;
}
static gboolean
refresh_model_timeout (gpointer data)
{
NautilusMimeApplicationChooser *chooser = data;
chooser->details->refresh_timeout = 0;
refresh_model (chooser);
return FALSE;
}
/* This adds a slight delay so that we're sure the mime data is
done writing */
static void
refresh_model_soon (NautilusMimeApplicationChooser *chooser)
{
if (chooser->details->refresh_timeout != 0)
return;
chooser->details->refresh_timeout =
g_timeout_add (300,
refresh_model_timeout,
chooser);
}
static void
refresh_model (NautilusMimeApplicationChooser *chooser)
{
GList *applications;
GAppInfo *default_app;
GList *l;
GtkTreeSelection *selection;
GtkTreeViewColumn *column;
column = gtk_tree_view_get_column (GTK_TREE_VIEW (chooser->details->treeview), 0);
gtk_tree_view_column_set_visible (column, TRUE);
gtk_list_store_clear (chooser->details->model);
applications = g_app_info_get_all_for_type (chooser->details->content_type);
default_app = g_app_info_get_default_for_type (chooser->details->content_type, FALSE);
for (l = applications; l != NULL; l = l->next) {
GtkTreeIter iter;
gboolean is_default;
GAppInfo *application;
char *escaped;
GIcon *icon;
GdkPixbuf *pixbuf;
pixbuf = NULL;
application = l->data;
is_default = default_app && g_app_info_equal (default_app, application);
escaped = g_markup_escape_text (g_app_info_get_name (application), -1);
icon = g_app_info_get_icon (application);
if (icon != NULL) {
pixbuf = get_pixbuf_for_icon (icon);
}
gtk_list_store_append (chooser->details->model, &iter);
gtk_list_store_set (chooser->details->model, &iter,
COLUMN_APPINFO, application,
COLUMN_DEFAULT, is_default,
COLUMN_ICON, pixbuf,
COLUMN_NAME, escaped,
-1);
g_free (escaped);
if (pixbuf != NULL) {
g_object_unref (pixbuf);
}
}
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (chooser->details->treeview));
if (applications) {
g_object_set (chooser->details->toggle_renderer,
"visible", TRUE,
NULL);
gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
} else {
GtkTreeIter iter;
char *name;
gtk_tree_view_column_set_visible (column, FALSE);
gtk_list_store_append (chooser->details->model, &iter);
name = g_strdup_printf ("<i>%s</i>", _("No applications selected"));
gtk_list_store_set (chooser->details->model, &iter,
COLUMN_NAME, name,
COLUMN_APPINFO, NULL,
-1);
g_free (name);
gtk_tree_selection_set_mode (selection, GTK_SELECTION_NONE);
}
if (default_app) {
g_object_unref (default_app);
}
eel_g_object_list_free (applications);
}
static gboolean
set_uri_and_type (NautilusMimeApplicationChooser *chooser,
const char *uri,
const char *mime_type)
{
char *label;
char *name;
char *emname;
char *extension;
GFile *file;
chooser->details->uri = g_strdup (uri);
file = g_file_new_for_uri (uri);
name = g_file_get_basename (file);
g_object_unref (file);
chooser->details->orig_mime_type = g_strdup (mime_type);
extension = get_extension (name);
if (extension != NULL &&
g_content_type_is_unknown (mime_type)) {
chooser->details->extension = g_strdup (extension);
chooser->details->content_type = g_strdup_printf ("application/x-extension-%s", extension);
/* the %s here is a file extension */
chooser->details->type_description =
g_strdup_printf (_("%s document"), extension);
} else {
char *description;
chooser->details->content_type = g_strdup (mime_type);
description = g_content_type_get_description (mime_type);
if (description == NULL) {
description = g_strdup (_("Unknown"));
}
chooser->details->type_description = description;
}
g_free (extension);
/* first %s is filename, second %s is mime-type description */
emname = g_strdup_printf ("<i>%s</i>", name);
label = g_strdup_printf (_("Select an application to open %s and other files of type \"%s\""),
emname, chooser->details->type_description);
g_free (emname);
gtk_label_set_markup (GTK_LABEL (chooser->details->label), label);
g_free (label);
g_free (name);
refresh_model (chooser);
return TRUE;
}
GtkWidget *
nautilus_mime_application_chooser_new (const char *uri,
const char *mime_type)
{
GtkWidget *chooser;
chooser = gtk_widget_new (NAUTILUS_TYPE_MIME_APPLICATION_CHOOSER, NULL);
set_uri_and_type (NAUTILUS_MIME_APPLICATION_CHOOSER (chooser), uri, mime_type);
return chooser;
}
GType
nautilus_mime_application_chooser_get_type (void)
{
static GType type = 0;
if (!type) {
const GTypeInfo info = {
sizeof (NautilusMimeApplicationChooserClass),
NULL,
NULL,
(GClassInitFunc)nautilus_mime_application_chooser_class_init,
NULL,
NULL,
sizeof (NautilusMimeApplicationChooser),
0,
(GInstanceInitFunc)nautilus_mime_application_chooser_instance_init,
};
type = g_type_register_static (GTK_TYPE_VBOX,
"NautilusMimeApplicationChooser",
&info, 0);
}
return type;
}

View file

@ -0,0 +1,53 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/*
nautilus-mime-application-chooser.c: Manages applications for mime types
Copyright (C) 2004 Novell, Inc.
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The Gnome Library is distributed in the hope that it will be useful,
but APPLICATIONOUT ANY WARRANTY; applicationout even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along application the Gnome Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Authors: Dave Camp <dave@novell.com>
*/
#ifndef NAUTILUS_MIME_APPLICATION_CHOOSER_H
#define NAUTILUS_MIME_APPLICATION_CHOOSER_H
#include <gtk/gtkvbox.h>
#define NAUTILUS_TYPE_MIME_APPLICATION_CHOOSER (nautilus_mime_application_chooser_get_type ())
#define NAUTILUS_MIME_APPLICATION_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_MIME_APPLICATION_CHOOSER, NautilusMimeApplicationChooser))
#define NAUTILUS_MIME_APPLICATION_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_MIME_APPLICATION_CHOOSER, NautilusMimeApplicationChooserClass))
#define NAUTILUS_IS_MIME_APPLICATION_CHOOSER(obj) (G_TYPE_INSTANCE_CHECK_TYPE ((obj), NAUTILUS_TYPE_MIME_APPLICATION_CHOOSER)
typedef struct _NautilusMimeApplicationChooser NautilusMimeApplicationChooser;
typedef struct _NautilusMimeApplicationChooserClass NautilusMimeApplicationChooserClass;
typedef struct _NautilusMimeApplicationChooserDetails NautilusMimeApplicationChooserDetails;
struct _NautilusMimeApplicationChooser {
GtkVBox parent;
NautilusMimeApplicationChooserDetails *details;
};
struct _NautilusMimeApplicationChooserClass {
GtkVBoxClass parent_class;
};
GType nautilus_mime_application_chooser_get_type (void);
GtkWidget* nautilus_mime_application_chooser_new (const char *uri,
const char *mime_type);
#endif /* NAUTILUS_MIME_APPLICATION_CHOOSER_H */

View file

@ -29,13 +29,11 @@
#include "nautilus-file-changes-queue.h"
#include "nautilus-file-utilities.h"
#include <gio/gdirectorymonitor.h>
#include <libgnome/gnome-util.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <libgnomevfs/gnome-vfs-ops.h>
#include <libgnomevfs/gnome-vfs-volume-monitor.h>
struct NautilusMonitor {
GnomeVFSMonitorHandle *handle;
GDirectoryMonitor *monitor;
};
gboolean
@ -43,49 +41,25 @@ nautilus_monitor_active (void)
{
static gboolean tried_monitor = FALSE;
static gboolean monitor_success;
char *desktop_directory, *uri;
NautilusMonitor *monitor;
GDirectoryMonitor *dir_monitor;
GFile *file;
if (tried_monitor == FALSE) {
desktop_directory = nautilus_get_desktop_directory ();
uri = gnome_vfs_get_uri_from_local_path (desktop_directory);
monitor = nautilus_monitor_directory (uri);
monitor_success = (monitor != NULL);
if (monitor != NULL) {
nautilus_monitor_cancel (monitor);
file = g_file_new_for_path (g_get_home_dir ());
dir_monitor = g_file_monitor_directory (file, G_FILE_MONITOR_FLAGS_NONE, NULL);
g_object_unref (file);
monitor_success = (dir_monitor != NULL);
if (dir_monitor) {
g_object_unref (dir_monitor);
}
g_free (desktop_directory);
g_free (uri);
tried_monitor = TRUE;
}
return monitor_success;
}
static gboolean
path_is_on_readonly_volume (const char *path)
{
GnomeVFSVolumeMonitor *volume_monitor;
GnomeVFSVolume *volume;
gboolean res;
g_assert (path != NULL);
volume_monitor = gnome_vfs_get_volume_monitor ();
volume = gnome_vfs_volume_monitor_get_volume_for_path (volume_monitor,
path);
res = FALSE;
if (volume != NULL) {
res = gnome_vfs_volume_is_read_only (volume);
gnome_vfs_volume_unref (volume);
}
return res;
}
static gboolean call_consume_changes_idle_id = 0;
static gboolean
@ -96,92 +70,81 @@ call_consume_changes_idle_cb (gpointer not_used)
return FALSE;
}
static void
monitor_notify_cb (GnomeVFSMonitorHandle *handle,
const gchar *monitor_uri,
const gchar *info_uri,
GnomeVFSMonitorEventType event_type,
gpointer user_data)
static void
dir_changed (GDirectoryMonitor* monitor,
GFile *child,
GFile *other_file,
GFileMonitorEvent event_type,
gpointer user_data)
{
switch (event_type) {
case GNOME_VFS_MONITOR_EVENT_CHANGED:
nautilus_file_changes_queue_file_changed (info_uri);
break;
case GNOME_VFS_MONITOR_EVENT_DELETED:
nautilus_file_changes_queue_schedule_metadata_remove (info_uri);
nautilus_file_changes_queue_file_removed (info_uri);
break;
case GNOME_VFS_MONITOR_EVENT_CREATED:
nautilus_file_changes_queue_file_added (info_uri);
break;
char *uri, *to_uri;
uri = g_file_get_uri (child);
to_uri = NULL;
if (other_file) {
to_uri = g_file_get_uri (other_file);
}
/* None of the following are supported yet */
case GNOME_VFS_MONITOR_EVENT_STARTEXECUTING:
case GNOME_VFS_MONITOR_EVENT_STOPEXECUTING:
case GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED:
switch (event_type) {
default:
case G_FILE_MONITOR_EVENT_CHANGED:
/* ignore */
break;
case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
nautilus_file_changes_queue_file_changed (child);
break;
case G_FILE_MONITOR_EVENT_DELETED:
nautilus_file_changes_queue_file_removed (child);
break;
case G_FILE_MONITOR_EVENT_CREATED:
nautilus_file_changes_queue_file_added (child);
break;
case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
/* TODO: Do something */
break;
case G_FILE_MONITOR_EVENT_UNMOUNTED:
/* TODO: Do something */
break;
}
g_free (uri);
g_free (to_uri);
if (call_consume_changes_idle_id == 0) {
call_consume_changes_idle_id =
g_idle_add (call_consume_changes_idle_cb, NULL);
}
}
static NautilusMonitor *
monitor_add_internal (const char *uri, gboolean is_directory)
NautilusMonitor *
nautilus_monitor_directory (GFile *location)
{
gchar *path;
GDirectoryMonitor *dir_monitor;
NautilusMonitor *ret;
GnomeVFSResult result;
path = gnome_vfs_get_local_path_from_uri (uri);
dir_monitor = g_file_monitor_directory (location, G_FILE_MONITOR_FLAGS_MONITOR_MOUNTS, NULL);
/*
* Don't monitor URIs on a read-only volume.
* This is a hack to avoid FAM keeping open fds to CD-ROMs,
* causing unmount/eject to fail.
*/
if (path != NULL && path_is_on_readonly_volume (path) == TRUE) {
g_free (path);
if (dir_monitor == NULL) {
return NULL;
}
g_free (path);
ret = g_new0 (NautilusMonitor, 1);
ret->monitor = dir_monitor;
result = gnome_vfs_monitor_add (&ret->handle,
uri,
is_directory == TRUE ?
GNOME_VFS_MONITOR_DIRECTORY :
GNOME_VFS_MONITOR_FILE,
monitor_notify_cb,
NULL);
if (result != GNOME_VFS_OK) {
g_free (ret);
return NULL;
}
g_signal_connect (ret->monitor, "changed", (GCallback)dir_changed, ret);
return ret;
}
NautilusMonitor *
nautilus_monitor_directory (const char *uri)
{
return monitor_add_internal (uri, TRUE);
}
NautilusMonitor *
nautilus_monitor_file (const char *uri)
{
return monitor_add_internal (uri, FALSE);
}
void
nautilus_monitor_cancel (NautilusMonitor *monitor)
{
if (monitor->handle != NULL) {
gnome_vfs_monitor_cancel (monitor->handle);
if (monitor->monitor != NULL) {
g_signal_handlers_disconnect_by_func (monitor->monitor, dir_changed, monitor);
g_directory_monitor_cancel (monitor->monitor);
g_object_unref (monitor->monitor);
}
g_free (monitor);

View file

@ -27,12 +27,12 @@
#define NAUTILUS_MONITOR_H
#include <glib/gtypes.h>
#include <gio/gfile.h>
typedef struct NautilusMonitor NautilusMonitor;
gboolean nautilus_monitor_active (void);
NautilusMonitor *nautilus_monitor_file (const char *uri);
NautilusMonitor *nautilus_monitor_directory (const char *uri);
NautilusMonitor *nautilus_monitor_directory (GFile *location);
void nautilus_monitor_cancel (NautilusMonitor *monitor);
#endif /* NAUTILUS_MONITOR_H */

View file

@ -0,0 +1,982 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/*
eel-open-with-dialog.c: an open-with dialog
Copyright (C) 2004 Novell, Inc.
Copyright (C) 2007 Red Hat, Inc.
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The Gnome Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the Gnome Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Authors: Dave Camp <dave@novell.com>
Alexander Larsson <alexl@redhat.com>
*/
#include <config.h>
#include "nautilus-open-with-dialog.h"
#include "nautilus-signaller.h"
#include <eel/eel-stock-dialogs.h>
#include <string.h>
#include <glib/gi18n-lib.h>
#include <gtk/gtkalignment.h>
#include <gtk/gtkbox.h>
#include <gtk/gtkexpander.h>
#include <gtk/gtkbutton.h>
#include <gtk/gtkdialog.h>
#include <gtk/gtkentry.h>
#include <gtk/gtkfilechooserdialog.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtkicontheme.h>
#include <gtk/gtkiconfactory.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkscrolledwindow.h>
#include <gtk/gtkstock.h>
#include <gtk/gtktreeview.h>
#include <gtk/gtktreeselection.h>
#include <gtk/gtkcellrenderertext.h>
#include <gtk/gtkcellrendererpixbuf.h>
#include <gtk/gtkvbox.h>
#include <gio/gcontenttype.h>
#include <gio/gthemedicon.h>
#include <gio/gfileicon.h>
#define sure_string(s) ((const char *)((s)!=NULL?(s):""))
#define DESKTOP_ENTRY_GROUP "Desktop Entry"
struct _NautilusOpenWithDialogDetails {
GAppInfo *selected_app_info;
char *content_type;
char *extension;
char *type_description;
GtkWidget *label;
GtkWidget *entry;
GtkWidget *button;
GtkWidget *desc_label;
GtkWidget *open_label;
GtkWidget *program_list;
GtkListStore *program_list_store;
GSList *add_icon_paths;
gint add_items_idle_id;
gint add_icons_idle_id;
};
enum {
COLUMN_APP_INFO,
COLUMN_ICON,
COLUMN_GICON,
COLUMN_NAME,
COLUMN_COMMENT,
COLUMN_EXEC,
NUM_COLUMNS
};
enum {
RESPONSE_OPEN
};
enum {
APPLICATION_SELECTED,
LAST_SIGNAL
};
static gpointer parent_class;
static guint signals[LAST_SIGNAL] = { 0 };
static void
nautilus_open_with_dialog_finalize (GObject *object)
{
NautilusOpenWithDialog *dialog;
dialog = NAUTILUS_OPEN_WITH_DIALOG (object);
if (dialog->details->add_icons_idle_id) {
g_source_remove (dialog->details->add_icons_idle_id);
}
if (dialog->details->add_items_idle_id) {
g_source_remove (dialog->details->add_items_idle_id);
}
if (dialog->details->selected_app_info) {
g_object_unref (dialog->details->selected_app_info);
}
g_free (dialog->details->content_type);
g_free (dialog->details->extension);
g_free (dialog->details->type_description);
g_free (dialog->details);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
nautilus_open_with_dialog_destroy (GtkObject *object)
{
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
/* An application is valid if:
*
* 1) The file exists
* 2) The user has permissions to run the file
*/
static gboolean
check_application (NautilusOpenWithDialog *dialog)
{
char *command;
char *path = NULL;
char **argv = NULL;
int argc;
GError *error = NULL;
gint retval = TRUE;
command = NULL;
if (dialog->details->selected_app_info != NULL) {
command = g_strdup (g_app_info_get_executable (dialog->details->selected_app_info));
}
if (command == NULL) {
command = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->details->entry)));
}
g_shell_parse_argv (command, &argc, &argv, &error);
if (error) {
eel_show_error_dialog (_("Could not run application"),
error->message,
GTK_WINDOW (dialog));
g_error_free (error);
retval = FALSE;
goto cleanup;
}
path = g_find_program_in_path (argv[0]);
if (!path) {
char *error_message;
error_message = g_strdup_printf (_("Could not find '%s'"),
argv[0]);
eel_show_error_dialog (_("Could not find application"),
error_message,
GTK_WINDOW (dialog));
g_free (error_message);
retval = FALSE;
goto cleanup;
}
cleanup:
g_strfreev (argv);
g_free (path);
g_free (command);
return retval;
}
/* Only called for non-desktop files */
static char *
get_app_name (const char *commandline, GError **error)
{
char *basename;
char *unquoted;
char **argv;
int argc;
if (!g_shell_parse_argv (commandline,
&argc, &argv, error)) {
return NULL;
}
unquoted = g_shell_unquote (argv[0], NULL);
if (unquoted) {
basename = g_path_get_basename (unquoted);
} else {
basename = g_strdup (argv[0]);
}
g_free (unquoted);
g_strfreev (argv);
return basename;
}
/* This will check if the application the user wanted exists will return that
* application. If it doesn't exist, it will create one and return that.
* It also sets the app info as the default for this type.
*/
static GAppInfo *
add_or_find_application (NautilusOpenWithDialog *dialog)
{
GAppInfo *app;
char *app_name;
const char *commandline;
GError *error;
gboolean success;
char *message;
error = NULL;
app = NULL;
if (dialog->details->selected_app_info) {
app = g_object_ref (dialog->details->selected_app_info);
} else {
commandline = gtk_entry_get_text (GTK_ENTRY (dialog->details->entry));
app_name = get_app_name (commandline, &error);
if (app_name != NULL) {
app = g_app_info_create_from_commandline (commandline,
app_name,
G_APP_INFO_CREATE_FLAGS_NONE,
&error);
}
}
if (app == NULL) {
message = g_strdup_printf (_("Could not add application to the application database: %s"), error->message);
eel_show_error_dialog (_("Could not add application"),
message,
GTK_WINDOW (dialog));
g_free (message);
g_error_free (error);
return NULL;
}
if (dialog->details->content_type) {
success = g_app_info_set_as_default_for_type (app,
dialog->details->content_type,
&error);
} else {
success = g_app_info_set_as_default_for_extension (app,
dialog->details->extension,
&error);
}
if (!success) {
message = g_strdup_printf (_("Could not set application as the default: %s"), error->message);
eel_show_error_dialog (_("Could not set as default application"),
message,
GTK_WINDOW (dialog));
g_free (message);
g_error_free (error);
}
g_signal_emit_by_name (nautilus_signaller_get_current (),
"mime_data_changed");
return app;
}
static void
emit_application_selected (NautilusOpenWithDialog *dialog,
GAppInfo *application)
{
g_signal_emit (G_OBJECT (dialog), signals[APPLICATION_SELECTED], 0,
application);
}
static void
response_cb (NautilusOpenWithDialog *dialog,
int response_id,
gpointer data)
{
GAppInfo *application;
switch (response_id) {
case RESPONSE_OPEN:
if (check_application (dialog)) {
application = add_or_find_application (dialog);
if (application) {
emit_application_selected (dialog, application);
g_object_unref (application);
gtk_widget_destroy (GTK_WIDGET (dialog));
}
}
break;
case GTK_RESPONSE_NONE:
case GTK_RESPONSE_DELETE_EVENT:
case GTK_RESPONSE_CANCEL:
gtk_widget_destroy (GTK_WIDGET (dialog));
break;
default :
g_assert_not_reached ();
}
}
static void
nautilus_open_with_dialog_class_init (NautilusOpenWithDialogClass *class)
{
GObjectClass *gobject_class;
GtkObjectClass *object_class;
parent_class = g_type_class_peek_parent (class);
gobject_class = G_OBJECT_CLASS (class);
gobject_class->finalize = nautilus_open_with_dialog_finalize;
object_class = GTK_OBJECT_CLASS (class);
object_class->destroy = nautilus_open_with_dialog_destroy;
signals[APPLICATION_SELECTED] =
g_signal_new ("application_selected",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (NautilusOpenWithDialogClass,
application_selected),
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE,
1, G_TYPE_POINTER);
}
static void
chooser_response_cb (GtkFileChooser *chooser,
int response,
gpointer user_data)
{
NautilusOpenWithDialog *dialog;
dialog = NAUTILUS_OPEN_WITH_DIALOG (user_data);
if (response == GTK_RESPONSE_OK) {
char *filename;
filename = gtk_file_chooser_get_filename (chooser);
if (filename) {
char *quoted_text;
quoted_text = g_shell_quote (filename);
gtk_entry_set_text (GTK_ENTRY (dialog->details->entry),
quoted_text);
gtk_entry_set_position (GTK_ENTRY (dialog->details->entry), -1);
g_free (quoted_text);
g_free (filename);
}
}
gtk_widget_destroy (GTK_WIDGET (chooser));
}
static void
browse_clicked_cb (GtkWidget *button,
gpointer user_data)
{
NautilusOpenWithDialog *dialog;
GtkWidget *chooser;
dialog = NAUTILUS_OPEN_WITH_DIALOG (user_data);
chooser = gtk_file_chooser_dialog_new (_("Select an Application"),
GTK_WINDOW (dialog),
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN,
GTK_RESPONSE_OK,
NULL);
gtk_window_set_destroy_with_parent (GTK_WINDOW (chooser), TRUE);
g_signal_connect (chooser, "response",
G_CALLBACK (chooser_response_cb), dialog);
gtk_dialog_set_default_response (GTK_DIALOG (chooser),
GTK_RESPONSE_OK);
gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), TRUE);
gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (chooser),
FALSE);
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser),
"/usr/bin");
gtk_widget_show (chooser);
}
static void
entry_changed_cb (GtkWidget *entry,
NautilusOpenWithDialog *dialog)
{
/* We are writing in the entry, so we are not using a known appinfo anymore */
if (dialog->details->selected_app_info != NULL) {
g_object_unref (dialog->details->selected_app_info);
dialog->details->selected_app_info = NULL;
}
if (gtk_entry_get_text (GTK_ENTRY (dialog->details->entry))[0] == '\000') {
gtk_widget_set_sensitive (dialog->details->button, FALSE);
} else {
gtk_widget_set_sensitive (dialog->details->button, TRUE);
}
}
static GdkPixbuf *
get_pixbuf_for_icon (GIcon *icon)
{
GdkPixbuf *pixbuf;
char *filename;
pixbuf = NULL;
if (G_IS_FILE_ICON (icon)) {
filename = g_file_get_path (g_file_icon_get_file (G_FILE_ICON (icon)));
if (filename) {
pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 24, 24, NULL);
}
g_free (filename);
} else if (G_IS_THEMED_ICON (icon)) {
const char * const *names;
char *icon_no_extension;
char *p;
names = g_themed_icon_get_names (G_THEMED_ICON (icon));
if (names != NULL && names[0] != NULL) {
icon_no_extension = g_strdup (names[0]);
p = strrchr (icon_no_extension, '.');
if (p &&
(strcmp (p, ".png") == 0 ||
strcmp (p, ".xpm") == 0 ||
strcmp (p, ".svg") == 0)) {
*p = 0;
}
pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
icon_no_extension, 24, 0, NULL);
g_free (icon_no_extension);
}
}
return pixbuf;
}
static gboolean
nautilus_open_with_dialog_add_icon_idle (NautilusOpenWithDialog *dialog)
{
GtkTreeIter iter;
GtkTreePath *path;
GdkPixbuf *pixbuf;
GIcon *icon;
gboolean long_operation;
long_operation = FALSE;
do {
if (!dialog->details->add_icon_paths) {
dialog->details->add_icons_idle_id = 0;
return FALSE;
}
path = dialog->details->add_icon_paths->data;
dialog->details->add_icon_paths->data = NULL;
dialog->details->add_icon_paths = g_slist_delete_link (dialog->details->add_icon_paths,
dialog->details->add_icon_paths);
if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (dialog->details->program_list_store),
&iter, path)) {
gtk_tree_path_free (path);
continue;
}
gtk_tree_path_free (path);
gtk_tree_model_get (GTK_TREE_MODEL (dialog->details->program_list_store), &iter,
COLUMN_GICON, &icon, -1);
if (icon == NULL) {
continue;
}
pixbuf = get_pixbuf_for_icon (icon);
if (pixbuf) {
long_operation = TRUE;
gtk_list_store_set (dialog->details->program_list_store, &iter, COLUMN_ICON, pixbuf, -1);
g_object_unref (pixbuf);
}
/* don't go back into the main loop if this wasn't very hard to do */
} while (!long_operation);
return TRUE;
}
static gboolean
nautilus_open_with_search_equal_func (GtkTreeModel *model,
int column,
const char *key,
GtkTreeIter *iter,
gpointer user_data)
{
char *normalized_key;
char *name, *normalized_name;
char *path, *normalized_path;
char *basename, *normalized_basename;
gboolean ret;
if (key != NULL) {
normalized_key = g_utf8_casefold (key, -1);
g_assert (normalized_key != NULL);
ret = TRUE;
gtk_tree_model_get (model, iter,
COLUMN_NAME, &name,
COLUMN_EXEC, &path,
-1);
if (name != NULL) {
normalized_name = g_utf8_casefold (name, -1);
g_assert (normalized_name != NULL);
if (strncmp (normalized_name, normalized_key, strlen (normalized_key)) == 0) {
ret = FALSE;
}
g_free (normalized_name);
}
if (ret && path != NULL) {
normalized_path = g_utf8_casefold (path, -1);
g_assert (normalized_path != NULL);
basename = g_path_get_basename (path);
g_assert (basename != NULL);
normalized_basename = g_utf8_casefold (basename, -1);
g_assert (normalized_basename != NULL);
if (strncmp (normalized_path, normalized_key, strlen (normalized_key)) == 0 ||
strncmp (normalized_basename, normalized_key, strlen (normalized_key)) == 0) {
ret = FALSE;
}
g_free (basename);
g_free (normalized_basename);
g_free (normalized_path);
}
g_free (name);
g_free (path);
g_free (normalized_key);
return ret;
} else {
return TRUE;
}
}
static gboolean
nautilus_open_with_dialog_add_items_idle (NautilusOpenWithDialog *dialog)
{
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
GList *all_applications;
GList *l;
const char *prev_name;
/* create list store */
dialog->details->program_list_store = gtk_list_store_new (NUM_COLUMNS,
G_TYPE_APP_INFO,
GDK_TYPE_PIXBUF,
G_TYPE_ICON,
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_STRING);
all_applications = g_app_info_get_all ();
prev_name = NULL;
for (l = all_applications; l; l = l->next) {
GAppInfo *app = l->data;
GtkTreeIter iter;
GtkTreePath *path;
gtk_list_store_append (dialog->details->program_list_store, &iter);
gtk_list_store_set (dialog->details->program_list_store, &iter,
COLUMN_APP_INFO, app,
COLUMN_ICON, NULL,
COLUMN_GICON, g_app_info_get_icon (app),
COLUMN_NAME, g_app_info_get_name (app),
COLUMN_COMMENT, g_app_info_get_description (app),
COLUMN_EXEC, g_app_info_get_executable,
-1);
path = gtk_tree_model_get_path (GTK_TREE_MODEL (dialog->details->program_list_store), &iter);
if (path != NULL) {
dialog->details->add_icon_paths = g_slist_prepend (dialog->details->add_icon_paths, path);
}
}
g_list_free (all_applications);
gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->details->program_list),
GTK_TREE_MODEL (dialog->details->program_list_store));
gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (dialog->details->program_list),
nautilus_open_with_search_equal_func,
NULL, NULL);
renderer = gtk_cell_renderer_pixbuf_new ();
column = gtk_tree_view_column_new ();
gtk_tree_view_column_pack_start (column, renderer, FALSE);
gtk_tree_view_column_set_attributes (column, renderer,
"pixbuf", COLUMN_ICON,
NULL);
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, renderer, TRUE);
gtk_tree_view_column_set_attributes (column, renderer,
"text", COLUMN_NAME,
NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (dialog->details->program_list), column);
dialog->details->add_icon_paths = g_slist_reverse (dialog->details->add_icon_paths);
if (!dialog->details->add_icons_idle_id) {
dialog->details->add_icons_idle_id =
g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, (GSourceFunc) nautilus_open_with_dialog_add_icon_idle,
dialog, NULL);
}
dialog->details->add_items_idle_id = 0;
return FALSE;
}
static void
program_list_selection_changed (GtkTreeSelection *selection,
NautilusOpenWithDialog *dialog)
{
GtkTreeModel *model;
GtkTreeIter iter;
GAppInfo *info;
if (!gtk_tree_selection_get_selected (selection, &model, &iter)) {
gtk_widget_set_sensitive (dialog->details->button, FALSE);
return;
}
info = NULL;
gtk_tree_model_get (model, &iter,
COLUMN_APP_INFO, &info,
-1);
if (info == NULL) {
return;
}
gtk_entry_set_text (GTK_ENTRY (dialog->details->entry),
sure_string (g_app_info_get_executable (info)));
gtk_label_set_text (GTK_LABEL (dialog->details->desc_label),
sure_string (g_app_info_get_description (info)));
gtk_widget_set_sensitive (dialog->details->button, TRUE);
if (dialog->details->selected_app_info) {
g_object_unref (dialog->details->selected_app_info);
}
dialog->details->selected_app_info = info;
}
static void
program_list_selection_activated (GtkTreeView *view,
GtkTreePath *path,
GtkTreeViewColumn *column,
NautilusOpenWithDialog *dialog)
{
GtkTreeSelection *selection;
/* update the entry with the info from the selection */
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->details->program_list));
program_list_selection_changed (selection, dialog);
gtk_dialog_response (GTK_DIALOG (&dialog->parent), RESPONSE_OPEN);
}
static void
expander_toggled (GtkWidget *expander, NautilusOpenWithDialog *dialog)
{
if (gtk_expander_get_expanded (GTK_EXPANDER (expander)) == TRUE) {
gtk_widget_grab_focus (dialog->details->entry);
gtk_window_resize (GTK_WINDOW (dialog), 400, 1);
} else {
GtkTreeSelection *selection;
gtk_widget_grab_focus (dialog->details->program_list);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->details->program_list));
program_list_selection_changed (selection, dialog);
}
}
static void
nautilus_open_with_dialog_instance_init (NautilusOpenWithDialog *dialog)
{
GtkWidget *hbox;
GtkWidget *vbox;
GtkWidget *vbox2;
GtkWidget *label;
GtkWidget *align;
GtkWidget *scrolled_window;
GtkWidget *expander;
GtkTreeSelection *selection;
dialog->details = g_new0 (NautilusOpenWithDialogDetails, 1);
gtk_window_set_title (GTK_WINDOW (dialog), _("Open With"));
gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2);
vbox = gtk_vbox_new (FALSE, 12);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
vbox2 = gtk_vbox_new (FALSE, 6);
gtk_box_pack_start (GTK_BOX (vbox), vbox2, TRUE, TRUE, 0);
dialog->details->label = gtk_label_new ("");
gtk_misc_set_alignment (GTK_MISC (dialog->details->label), 0.0, 0.5);
gtk_label_set_line_wrap (GTK_LABEL (dialog->details->label), TRUE);
gtk_box_pack_start (GTK_BOX (vbox2), dialog->details->label,
FALSE, FALSE, 0);
gtk_widget_show (dialog->details->label);
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_size_request (scrolled_window, 400, 300);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
GTK_SHADOW_IN);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
dialog->details->program_list = gtk_tree_view_new ();
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (dialog->details->program_list),
FALSE);
gtk_container_add (GTK_CONTAINER (scrolled_window), dialog->details->program_list);
gtk_box_pack_start (GTK_BOX (vbox2), scrolled_window, TRUE, TRUE, 0);
dialog->details->desc_label = gtk_label_new (_("Select an application to view its description."));
gtk_misc_set_alignment (GTK_MISC (dialog->details->desc_label), 0.0, 0.5);
gtk_label_set_justify (GTK_LABEL (dialog->details->desc_label), GTK_JUSTIFY_LEFT);
gtk_label_set_line_wrap (GTK_LABEL (dialog->details->desc_label), TRUE);
gtk_label_set_single_line_mode (GTK_LABEL (dialog->details->desc_label), FALSE);
gtk_box_pack_start (GTK_BOX (vbox2), dialog->details->desc_label, FALSE, FALSE, 0);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->details->program_list));
gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
g_signal_connect (selection, "changed",
G_CALLBACK (program_list_selection_changed),
dialog);
g_signal_connect (dialog->details->program_list, "row-activated",
G_CALLBACK (program_list_selection_activated),
dialog);
dialog->details->add_items_idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
(GSourceFunc) nautilus_open_with_dialog_add_items_idle,
dialog, NULL);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), vbox, TRUE, TRUE, 0);
gtk_widget_show_all (vbox);
expander = gtk_expander_new_with_mnemonic (_("_Use a custom command"));
gtk_box_pack_start (GTK_BOX (vbox), expander, FALSE, FALSE, 0);
g_signal_connect_after (expander, "activate", G_CALLBACK (expander_toggled), dialog);
gtk_widget_show (expander);
hbox = gtk_hbox_new (FALSE, 6);
gtk_container_add (GTK_CONTAINER (expander), hbox);
gtk_widget_show (hbox);
dialog->details->entry = gtk_entry_new ();
gtk_entry_set_activates_default (GTK_ENTRY (dialog->details->entry), TRUE);
gtk_box_pack_start (GTK_BOX (hbox), dialog->details->entry,
TRUE, TRUE, 0);
gtk_widget_show (dialog->details->entry);
dialog->details->button = gtk_button_new_with_mnemonic (_("_Browse..."));
g_signal_connect (dialog->details->button, "clicked",
G_CALLBACK (browse_clicked_cb), dialog);
gtk_box_pack_start (GTK_BOX (hbox), dialog->details->button, FALSE, FALSE, 0);
gtk_widget_show (dialog->details->button);
gtk_dialog_add_button (GTK_DIALOG (dialog),
GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL);
/* Create a custom stock icon */
dialog->details->button = gtk_button_new ();
/* Hook up the entry to the button */
gtk_widget_set_sensitive (dialog->details->button, FALSE);
g_signal_connect (G_OBJECT (dialog->details->entry), "changed",
G_CALLBACK (entry_changed_cb), dialog);
hbox = gtk_hbox_new (FALSE, 2);
gtk_widget_show (hbox);
label = gtk_label_new_with_mnemonic (_("_Open"));
gtk_label_set_mnemonic_widget (GTK_LABEL (label), GTK_WIDGET (dialog->details->button));
gtk_widget_show (label);
dialog->details->open_label = label;
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_widget_show (align);
gtk_widget_show (dialog->details->button);
GTK_WIDGET_SET_FLAGS (dialog->details->button, GTK_CAN_DEFAULT);
gtk_container_add (GTK_CONTAINER (align), hbox);
gtk_container_add (GTK_CONTAINER (dialog->details->button), align);
gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
dialog->details->button, RESPONSE_OPEN);
gtk_dialog_set_default_response (GTK_DIALOG (dialog),
RESPONSE_OPEN);
g_signal_connect (dialog, "response",
G_CALLBACK (response_cb),
dialog);
}
static char *
get_extension (const char *basename)
{
char *p;
p = strrchr (basename, '.');
if (p && *(p + 1) != '\0') {
return g_strdup (p + 1);
} else {
return NULL;
}
}
static void
set_uri_and_type (NautilusOpenWithDialog *dialog,
const char *uri,
const char *mime_type)
{
char *label;
char *name;
char *emname;
GFile *file;
char *extension;
const char *description;
file = g_file_new_for_uri (uri);
name = g_file_get_basename (file);
g_object_unref (file);
extension = get_extension (name);
if (extension != NULL &&
g_content_type_is_unknown (mime_type)) {
dialog->details->extension = g_strdup (extension);
/* the %s here is a file extension */
dialog->details->type_description =
g_strdup_printf (_("%s document"), extension);
} else {
dialog->details->content_type = g_strdup (mime_type);
description = g_content_type_get_description (mime_type);
if (description == NULL) {
description = _("Unknown");
}
dialog->details->type_description = g_strdup (description);
}
g_free (extension);
emname = g_strdup_printf ("<i>%s</i>", name);
label = g_strdup_printf (_("Open %s and other files of type \"%s\" with:"), emname, dialog->details->type_description);
g_free (emname);
gtk_label_set_markup (GTK_LABEL (dialog->details->label), label);
g_free (label);
g_free (name);
}
GtkWidget *
nautilus_open_with_dialog_new (const char *uri,
const char *mime_type)
{
GtkWidget *dialog;
dialog = gtk_widget_new (NAUTILUS_TYPE_OPEN_WITH_DIALOG, NULL);
set_uri_and_type (NAUTILUS_OPEN_WITH_DIALOG (dialog), uri, mime_type);
return dialog;
}
GtkWidget*
nautilus_add_application_dialog_new (const char *uri,
const char *mime_type)
{
NautilusOpenWithDialog *dialog;
dialog = NAUTILUS_OPEN_WITH_DIALOG (nautilus_open_with_dialog_new (uri, mime_type));
gtk_label_set_text_with_mnemonic (GTK_LABEL (dialog->details->open_label),
_("_Add"));
gtk_window_set_title (GTK_WINDOW (dialog), _("Add Application"));
return GTK_WIDGET (dialog);
}
GType
nautilus_open_with_dialog_get_type (void)
{
static GType type = 0;
if (!type) {
const GTypeInfo info = {
sizeof (NautilusOpenWithDialogClass),
NULL,
NULL,
(GClassInitFunc)nautilus_open_with_dialog_class_init,
NULL,
NULL,
sizeof (NautilusOpenWithDialog),
0,
(GInstanceInitFunc)nautilus_open_with_dialog_instance_init,
};
type = g_type_register_static (GTK_TYPE_DIALOG,
"NautilusOpenWithDialog",
&info, 0);
}
return type;
}

View file

@ -0,0 +1,61 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/*
nautilus-open-with-dialog.c: an open-with dialog
Copyright (C) 2004 Novell, Inc.
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The Gnome Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the Gnome Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Authors: Dave Camp <dave@novell.com>
*/
#ifndef NAUTILUS_OPEN_WITH_DIALOG_H
#define NAUTILUS_OPEN_WITH_DIALOG_H
#include <gtk/gtkdialog.h>
#include <gio/gappinfo.h>
#define NAUTILUS_TYPE_OPEN_WITH_DIALOG (nautilus_open_with_dialog_get_type ())
#define NAUTILUS_OPEN_WITH_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_OPEN_WITH_DIALOG, NautilusOpenWithDialog))
#define NAUTILUS_OPEN_WITH_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_OPEN_WITH_DIALOG, NautilusOpenWithDialogClass))
#define NAUTILUS_IS_OPEN_WITH_DIALOG(obj) (G_TYPE_INSTANCE_CHECK_TYPE ((obj), NAUTILUS_TYPE_OPEN_WITH_DIALOG)
typedef struct _NautilusOpenWithDialog NautilusOpenWithDialog;
typedef struct _NautilusOpenWithDialogClass NautilusOpenWithDialogClass;
typedef struct _NautilusOpenWithDialogDetails NautilusOpenWithDialogDetails;
struct _NautilusOpenWithDialog {
GtkDialog parent;
NautilusOpenWithDialogDetails *details;
};
struct _NautilusOpenWithDialogClass {
GtkDialogClass parent_class;
void (*application_selected) (NautilusOpenWithDialog *dialog,
GAppInfo *application);
};
GType nautilus_open_with_dialog_get_type (void);
GtkWidget* nautilus_open_with_dialog_new (const char *uri,
const char *mime_type);
GtkWidget* nautilus_add_application_dialog_new (const char *uri,
const char *mime_type);
#endif /* NAUTILUS_OPEN_WITH_DIALOG_H */

View file

@ -28,38 +28,27 @@
#include "nautilus-mime-actions.h"
#include "nautilus-global-preferences.h"
#include "nautilus-icon-factory.h"
#include "nautilus-icon-info.h"
#include "nautilus-recent.h"
#include <eel/eel-glib-extensions.h>
#include <eel/eel-gnome-extensions.h>
#include <eel/eel-vfs-extensions.h>
#include <eel/eel-stock-dialogs.h>
#include <eel/eel-preferences.h>
#include <eel/eel-string.h>
#include <eel/eel-app-launch-context.h>
#include <gtk/gtk.h>
#include <libgnome/gnome-config.h>
#include <glib/gi18n.h>
#include <gio/gfileicon.h>
#include <gio/gthemedicon.h>
#include <libgnome/gnome-util.h>
#include <libgnome/gnome-desktop-item.h>
#include <libgnome/gnome-url.h>
#include <libgnomeui/gnome-uidefs.h>
#include <libgnomevfs/gnome-vfs-mime-handlers.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <stdlib.h>
/* This number controls a maximum character count for a URL that is
* displayed as part of a dialog. It's fairly arbitrary -- big enough
* to allow most "normal" URIs to display in full, but small enough to
* prevent the dialog from getting insanely wide.
*/
#define MAX_URI_IN_DIALOG_LENGTH 60
#ifdef HAVE_STARTUP_NOTIFICATION
#define SN_API_NOT_YET_FROZEN
#include <libsn/sn.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#endif
extern char **environ;
@ -116,7 +105,7 @@ my_gdk_spawn_make_environment_for_screen (GdkScreen *screen,
* @parent_window: A window to use as the parent for any error dialogs.
* */
static void
application_cannot_open_location (GnomeVFSMimeApplication *application,
application_cannot_open_location (GAppInfo *application,
NautilusFile *file,
const char *uri_scheme,
GtkWindow *parent_window)
@ -136,8 +125,8 @@ application_cannot_open_location (GnomeVFSMimeApplication *application,
prompt = _("Open Failed, would you like to choose another application?");
message = g_strdup_printf (_("\"%s\" can't open \"%s\" because \"%s\" can't access files at \"%s\" "
"locations."),
application->name, file_name,
application->name, uri_scheme);
g_app_info_get_name (application), file_name,
g_app_info_get_name (application), uri_scheme);
} else {
prompt = _("Open Failed, would you like to choose another action?");
message = g_strdup_printf (_("The default action can't open \"%s\" because it can't access files at \"%s\" "
@ -166,8 +155,8 @@ application_cannot_open_location (GnomeVFSMimeApplication *application,
} else {
if (application != NULL) {
prompt = g_strdup_printf (_("\"%s\" can't open \"%s\" because \"%s\" can't access files at \"%s\" "
"locations."), application->name, file_name,
application->name, uri_scheme);
"locations."), g_app_info_get_name (application), file_name,
g_app_info_get_name (application), uri_scheme);
message = _("No other applications are available to view this file. "
"If you copy this file onto your computer, you may be able to open "
"it.");
@ -187,179 +176,6 @@ application_cannot_open_location (GnomeVFSMimeApplication *application,
#endif
}
#ifdef HAVE_STARTUP_NOTIFICATION
static void
sn_error_trap_push (SnDisplay *display,
Display *xdisplay)
{
gdk_error_trap_push ();
}
static void
sn_error_trap_pop (SnDisplay *display,
Display *xdisplay)
{
gdk_error_trap_pop ();
}
extern char **environ;
static char **
make_spawn_environment_for_sn_context (SnLauncherContext *sn_context,
char **envp)
{
char **retval;
int i, j;
retval = NULL;
if (envp == NULL) {
envp = environ;
}
for (i = 0; envp[i]; i++) {
/* Count length */
}
retval = g_new (char *, i + 2);
for (i = 0, j = 0; envp[i]; i++) {
if (!g_str_has_prefix (envp[i], "DESKTOP_STARTUP_ID=")) {
retval[j] = g_strdup (envp[i]);
++j;
}
}
retval[j] = g_strdup_printf ("DESKTOP_STARTUP_ID=%s",
sn_launcher_context_get_startup_id (sn_context));
++j;
retval[j] = NULL;
return retval;
}
/* This should be fairly long, as it's confusing to users if a startup
* ends when it shouldn't (it appears that the startup failed, and
* they have to relaunch the app). Also the timeout only matters when
* there are bugs and apps don't end their own startup sequence.
*
* This timeout is a "last resort" timeout that ignores whether the
* startup sequence has shown activity or not. Metacity and the
* tasklist have smarter, and correspondingly able-to-be-shorter
* timeouts. The reason our timeout is dumb is that we don't monitor
* the sequence (don't use an SnMonitorContext)
*/
#define STARTUP_TIMEOUT_LENGTH (30 /* seconds */ * 1000)
typedef struct
{
GdkScreen *screen;
GSList *contexts;
guint timeout_id;
} StartupTimeoutData;
static void
free_startup_timeout (void *data)
{
StartupTimeoutData *std;
std = data;
g_slist_foreach (std->contexts,
(GFunc) sn_launcher_context_unref,
NULL);
g_slist_free (std->contexts);
if (std->timeout_id != 0) {
g_source_remove (std->timeout_id);
std->timeout_id = 0;
}
g_free (std);
}
static gboolean
startup_timeout (void *data)
{
StartupTimeoutData *std;
GSList *tmp;
GTimeVal now;
int min_timeout;
std = data;
min_timeout = STARTUP_TIMEOUT_LENGTH;
g_get_current_time (&now);
tmp = std->contexts;
while (tmp != NULL) {
SnLauncherContext *sn_context;
GSList *next;
long tv_sec, tv_usec;
double elapsed;
sn_context = tmp->data;
next = tmp->next;
sn_launcher_context_get_last_active_time (sn_context,
&tv_sec, &tv_usec);
elapsed =
((((double)now.tv_sec - tv_sec) * G_USEC_PER_SEC +
(now.tv_usec - tv_usec))) / 1000.0;
if (elapsed >= STARTUP_TIMEOUT_LENGTH) {
std->contexts = g_slist_remove (std->contexts,
sn_context);
sn_launcher_context_complete (sn_context);
sn_launcher_context_unref (sn_context);
} else {
min_timeout = MIN (min_timeout, (STARTUP_TIMEOUT_LENGTH - elapsed));
}
tmp = next;
}
if (std->contexts == NULL) {
std->timeout_id = 0;
} else {
std->timeout_id = g_timeout_add (min_timeout,
startup_timeout,
std);
}
/* always remove this one, but we may have reinstalled another one. */
return FALSE;
}
static void
add_startup_timeout (GdkScreen *screen,
SnLauncherContext *sn_context)
{
StartupTimeoutData *data;
data = g_object_get_data (G_OBJECT (screen), "nautilus-startup-data");
if (data == NULL) {
data = g_new (StartupTimeoutData, 1);
data->screen = screen;
data->contexts = NULL;
data->timeout_id = 0;
g_object_set_data_full (G_OBJECT (screen), "nautilus-startup-data",
data, free_startup_timeout);
}
sn_launcher_context_ref (sn_context);
data->contexts = g_slist_prepend (data->contexts, sn_context);
if (data->timeout_id == 0) {
data->timeout_id = g_timeout_add (STARTUP_TIMEOUT_LENGTH,
startup_timeout,
data);
}
}
/* FIXME: This is the wrong way to do this; there should be some event
* (e.g. button press) available with a good time. A function like
* this should not be needed.
@ -411,250 +227,8 @@ slowly_and_stupidly_obtain_timestamp (Display *xdisplay)
return event.xproperty.time;
}
#endif /* HAVE_STARTUP_NOTIFICATION */
/**
* nautilus_launch_show_file:
*
* Shows a file using gnome_url_show.
*
* @file: the file whose uri will be shown.
* @parent_window: window to use as parent for error dialog.
*/
void nautilus_launch_show_file (NautilusFile *file,
GtkWindow *parent_window)
{
GnomeVFSResult result;
GnomeVFSMimeApplication *application;
GdkScreen *screen;
char **envp;
char *uri, *uri_scheme;
char *error_message, *detail_message;
char *full_uri_for_display;
char *uri_for_display;
GnomeVFSURI *vfs_uri;
#ifdef HAVE_STARTUP_NOTIFICATION
SnLauncherContext *sn_context;
SnDisplay *sn_display;
gboolean startup_notify;
startup_notify = FALSE;
#endif
uri = NULL;
if (nautilus_file_is_nautilus_link (file)) {
uri = nautilus_file_get_activation_uri (file);
}
if (uri == NULL) {
uri = nautilus_file_get_uri (file);
}
application = nautilus_mime_get_default_application_for_file (file);
screen = gtk_window_get_screen (parent_window);
envp = my_gdk_spawn_make_environment_for_screen (screen, NULL);
#ifdef HAVE_STARTUP_NOTIFICATION
sn_display = sn_display_new (gdk_display,
sn_error_trap_push,
sn_error_trap_pop);
/* Only initiate notification if application supports it. */
if (application) {
startup_notify = gnome_vfs_mime_application_supports_startup_notification (application);
} else {
startup_notify = FALSE;
}
if (startup_notify == TRUE) {
char *name;
char *icon;
sn_context = sn_launcher_context_new (sn_display,
screen ? gdk_screen_get_number (screen) :
DefaultScreen (gdk_display));
name = nautilus_file_get_display_name (file);
if (name != NULL) {
char *description;
sn_launcher_context_set_name (sn_context, name);
description = g_strdup_printf (_("Opening %s"), name);
sn_launcher_context_set_description (sn_context, description);
g_free (name);
g_free (description);
}
icon = nautilus_icon_factory_get_icon_for_file (file, FALSE);
if (icon != NULL) {
sn_launcher_context_set_icon_name (sn_context, icon);
g_free (icon);
}
if (!sn_launcher_context_get_initiated (sn_context)) {
const char *binary_name;
char **old_envp;
Time timestamp;
timestamp = slowly_and_stupidly_obtain_timestamp (GDK_WINDOW_XDISPLAY (GTK_WIDGET (parent_window)->window));
binary_name = gnome_vfs_mime_application_get_binary_name (application);
sn_launcher_context_set_binary_name (sn_context,
binary_name);
sn_launcher_context_initiate (sn_context,
g_get_prgname () ? g_get_prgname () : "unknown",
binary_name,
timestamp);
old_envp = envp;
envp = make_spawn_environment_for_sn_context (sn_context, envp);
g_strfreev (old_envp);
}
} else {
sn_context = NULL;
}
#endif /* HAVE_STARTUP_NOTIFICATION */
result = gnome_vfs_url_show_with_env (uri, envp);
#ifdef HAVE_STARTUP_NOTIFICATION
if (sn_context != NULL) {
if (result != GNOME_VFS_OK) {
sn_launcher_context_complete (sn_context); /* end sequence */
} else {
add_startup_timeout (screen ? screen :
gdk_display_get_default_screen (gdk_display_get_default ()),
sn_context);
}
sn_launcher_context_unref (sn_context);
}
sn_display_unref (sn_display);
#endif /* HAVE_STARTUP_NOTIFICATION */
full_uri_for_display = eel_format_uri_for_display (uri);
/* Truncate the URI so it doesn't get insanely wide. Note that even
* though the dialog uses wrapped text, if the URI doesn't contain
* white space then the text-wrapping code is too stupid to wrap it.
*/
uri_for_display = eel_str_middle_truncate
(full_uri_for_display, MAX_URI_IN_DIALOG_LENGTH);
g_free (full_uri_for_display);
error_message = detail_message = NULL;
switch (result) {
case GNOME_VFS_OK:
break;
case GNOME_VFS_ERROR_NOT_SUPPORTED:
uri_scheme = nautilus_file_get_uri_scheme (file);
application_cannot_open_location (NULL,
file,
uri_scheme,
parent_window);
g_free (uri_scheme);
break;
case GNOME_VFS_ERROR_NO_DEFAULT:
case GNOME_VFS_ERROR_NO_HANDLER:
#ifdef NEW_MIME_COMPLETE
nautilus_program_chooser_show_no_choices_message
(action_type, file, parent_window);
break;
#endif
error_message = g_strdup_printf (_("Couldn't display \"%s\"."),
uri_for_display);
/* TODO: This really needs to be something saying "no app
* handling this file type", but there is a string freeze. */
detail_message = g_strdup ("");
break;
case GNOME_VFS_ERROR_LAUNCH:
/* TODO: These strings suck pretty badly, but we're in string-freeze,
* and I found these in other places to reuse. We should make them
* better later. */
error_message = g_strdup_printf (_("Couldn't display \"%s\"."),
uri_for_display);
detail_message = g_strdup (_("There was an error launching the application."));
break;
default:
switch (nautilus_file_get_file_info_result (file)) {
case GNOME_VFS_ERROR_ACCESS_DENIED:
error_message = g_strdup_printf (_("Couldn't display \"%s\"."),
uri_for_display);
detail_message = g_strdup (_("The attempt to log in failed."));
break;
case GNOME_VFS_ERROR_NOT_PERMITTED:
error_message = g_strdup_printf (_("Couldn't display \"%s\"."),
uri_for_display);
detail_message = g_strdup (_("Access was denied."));
break;
case GNOME_VFS_ERROR_INVALID_HOST_NAME:
case GNOME_VFS_ERROR_HOST_NOT_FOUND:
vfs_uri = gnome_vfs_uri_new (uri);
error_message = g_strdup_printf (_("Couldn't display \"%s\", because no host \"%s\" could be found."),
uri_for_display,
gnome_vfs_uri_get_host_name (vfs_uri));
detail_message = g_strdup (_("Check that the spelling is correct and that your proxy settings are correct."));
gnome_vfs_uri_unref (vfs_uri);
break;
case GNOME_VFS_ERROR_INVALID_URI:
error_message = g_strdup_printf
(_("\"%s\" is not a valid location."),
uri_for_display);
detail_message = g_strdup
(_("Please check the spelling and try again."));
break;
case GNOME_VFS_ERROR_NOT_FOUND:
error_message = g_strdup_printf
(_("Couldn't find \"%s\"."),
uri_for_display);
detail_message = g_strdup
(_("Please check the spelling and try again."));
break;
case GNOME_VFS_ERROR_CANCELLED:
break;
case GNOME_VFS_OK:
default:
#ifdef NEW_MIME_COMPLETE
nautilus_program_chooser_show_invalid_message
(action_type, file, parent_window);
#endif
break;
}
}
if (error_message != NULL) {
eel_show_error_dialog (error_message, detail_message, parent_window);
g_free (error_message);
g_free (detail_message);
}
g_free (uri_for_display);
if (application != NULL)
gnome_vfs_mime_application_free (application);
g_strfreev (envp);
g_free (uri);
}
/**
* nautilus_launch_application:
*
@ -666,166 +240,89 @@ void nautilus_launch_show_file (NautilusFile *file,
* @parent_window: A window to use as the parent for any error dialogs.
*/
void
nautilus_launch_application (GnomeVFSMimeApplication *application,
nautilus_launch_application (GAppInfo *application,
GList *files,
GtkWindow *parent_window)
{
GdkScreen *screen;
char *uri;
char *uri_scheme;
GList *uris, *l;
GList *locations, *l;
GFile *location;
NautilusFile *file;
char **envp;
GnomeVFSResult result;
#ifdef HAVE_STARTUP_NOTIFICATION
SnLauncherContext *sn_context;
SnDisplay *sn_display;
#endif
gboolean result;
GError *error;
EelAppLaunchContext *launch_context;
NautilusIconInfo *icon;
g_assert (files != NULL);
uris = NULL;
locations = NULL;
for (l = files; l != NULL; l = l->next) {
file = NAUTILUS_FILE (l->data);
uri = NULL;
location = NULL;
if (nautilus_file_is_nautilus_link (file)) {
uri = nautilus_file_get_activation_uri (file);
location = g_file_new_for_uri (uri);
g_free (uri);
}
if (uri == NULL) {
uri = nautilus_file_get_uri (file);
if (location == NULL) {
location = nautilus_file_get_location (file);
}
uris = g_list_prepend (uris, uri);
locations = g_list_prepend (locations, location);
}
uris = g_list_reverse (uris);
locations = g_list_reverse (locations);
screen = gtk_window_get_screen (parent_window);
envp = my_gdk_spawn_make_environment_for_screen (screen, NULL);
launch_context = eel_app_launch_context_new ();
if (parent_window)
eel_app_launch_context_set_screen (launch_context,
gtk_window_get_screen (parent_window));
file = NAUTILUS_FILE (files->data);
icon = nautilus_file_get_icon (file, 48, 0);
if (icon) {
eel_app_launch_context_set_icon_name (launch_context,
nautilus_icon_info_get_used_name (icon));
g_object_unref (icon);
}
#ifdef HAVE_STARTUP_NOTIFICATION
sn_display = sn_display_new (gdk_display,
sn_error_trap_push,
sn_error_trap_pop);
error = NULL;
result = g_app_info_launch (application,
locations,
G_APP_LAUNCH_CONTEXT (launch_context),
&error);
g_object_unref (launch_context);
/* Only initiate notification if application supports it. */
if (gnome_vfs_mime_application_supports_startup_notification (application))
{
char *name;
char *description;
char *icon;
int files_count;
file = NAUTILUS_FILE (files->data);
sn_context = sn_launcher_context_new (sn_display,
screen ? gdk_screen_get_number (screen) :
DefaultScreen (gdk_display));
files_count = g_list_length (files);
if (files_count == 1) {
name = nautilus_file_get_display_name (file);
description = g_strdup_printf (_("Opening %s"), name);
if (!result) {
if (error->domain == G_IO_ERROR &&
error->code == G_IO_ERROR_NOT_SUPPORTED) {
uri_scheme = nautilus_file_get_uri_scheme (NAUTILUS_FILE (files->data));
application_cannot_open_location (application,
file,
uri_scheme,
parent_window);
g_free (uri_scheme);
} else {
name = NULL;
description = g_strdup_printf (ngettext ("Opening %d Item",
"Opening %d Items",
files_count),
files_count);
}
if (name != NULL) {
sn_launcher_context_set_name (sn_context, name);
g_free (name);
}
if (description != NULL) {
sn_launcher_context_set_description (sn_context, description);
g_free (description);
}
icon = nautilus_icon_factory_get_icon_for_file (file, FALSE);
if (icon == NULL) {
icon = g_strdup (gnome_vfs_mime_application_get_icon (application));
}
if (icon != NULL) {
sn_launcher_context_set_icon_name (sn_context, icon);
g_free (icon);
}
if (!sn_launcher_context_get_initiated (sn_context)) {
const char *binary_name;
char **old_envp;
Time timestamp;
timestamp = slowly_and_stupidly_obtain_timestamp (GDK_WINDOW_XDISPLAY (GTK_WIDGET (parent_window)->window));
binary_name = gnome_vfs_mime_application_get_binary_name (application);
sn_launcher_context_set_binary_name (sn_context,
binary_name);
sn_launcher_context_initiate (sn_context,
g_get_prgname () ? g_get_prgname () : "unknown",
binary_name,
timestamp);
old_envp = envp;
envp = make_spawn_environment_for_sn_context (sn_context, envp);
g_strfreev (old_envp);
#ifdef NEW_MIME_COMPLETE
nautilus_program_chooser_show_invalid_message
(GNOME_VFS_MIME_ACTION_TYPE_APPLICATION, file, parent_window);
#else
g_warning ("Can't open app: %s\n", error->message);
#endif
}
} else {
sn_context = NULL;
}
#endif /* HAVE_STARTUP_NOTIFICATION */
result = gnome_vfs_mime_application_launch_with_env (application, uris, envp);
#ifdef HAVE_STARTUP_NOTIFICATION
if (sn_context != NULL) {
if (result != GNOME_VFS_OK) {
sn_launcher_context_complete (sn_context); /* end sequence */
} else {
add_startup_timeout (screen ? screen :
gdk_display_get_default_screen (gdk_display_get_default ()),
sn_context);
for (l = files; l != NULL; l = l->next) {
file = NAUTILUS_FILE (l->data);
nautilus_recent_add_file (file, application);
}
sn_launcher_context_unref (sn_context);
}
sn_display_unref (sn_display);
#endif /* HAVE_STARTUP_NOTIFICATION */
switch (result) {
case GNOME_VFS_OK:
break;
case GNOME_VFS_ERROR_NOT_SUPPORTED:
uri_scheme = nautilus_file_get_uri_scheme (NAUTILUS_FILE (files->data));
application_cannot_open_location (application,
file,
uri_scheme,
parent_window);
g_free (uri_scheme);
break;
default:
#ifdef NEW_MIME_COMPLETE
nautilus_program_chooser_show_invalid_message
(GNOME_VFS_MIME_ACTION_TYPE_APPLICATION, file, parent_window);
#endif
break;
}
eel_g_list_free_deep (uris);
g_strfreev (envp);
eel_g_object_list_free (locations);
}
/**
@ -859,7 +356,7 @@ nautilus_launch_application_from_command (GdkScreen *screen,
if (use_terminal) {
eel_gnome_open_terminal_on_screen (full_command, screen);
} else {
eel_gnome_shell_execute_on_screen (full_command, screen);
gdk_spawn_command_line_on_screen (screen, full_command, NULL);
}
g_free (full_command);
@ -879,9 +376,8 @@ nautilus_launch_desktop_file (GdkScreen *screen,
const GList *p;
int total, count;
char **envp;
#ifdef HAVE_STARTUP_NOTIFICATION
GFile *file;
Time timestamp;
#endif
/* strip the leading command specifier */
if (eel_str_has_prefix (desktop_file_uri, NAUTILUS_DESKTOP_COMMAND_SPECIFIER)) {
@ -893,8 +389,9 @@ nautilus_launch_desktop_file (GdkScreen *screen,
* nfs are treated as remote) to partially mitigate the security
* risk of executing arbitrary commands.
*/
if (!eel_vfs_has_capability (desktop_file_uri,
EEL_VFS_CAPABILITY_SAFE_TO_EXECUTE)) {
file = g_file_new_for_uri (desktop_file_uri);
if (!g_file_is_native (file)) {
g_object_unref (file);
eel_show_error_dialog
(_("Sorry, but you can't execute commands from "
"a remote site."),
@ -903,6 +400,7 @@ nautilus_launch_desktop_file (GdkScreen *screen,
return;
}
g_object_unref (file);
error = NULL;
ditem = gnome_desktop_item_new_from_uri (desktop_file_uri, 0,
@ -923,7 +421,7 @@ nautilus_launch_desktop_file (GdkScreen *screen,
count = 0;
total = g_list_length ((GList *) parameter_uris);
for (p = parameter_uris; p != NULL; p = p->next) {
local_path = gnome_vfs_get_local_path_from_uri ((const char *) p->data);
local_path = g_filename_from_uri ((const char *) p->data, NULL, NULL);
if (local_path != NULL) {
g_free (local_path);
count++;
@ -968,10 +466,8 @@ nautilus_launch_desktop_file (GdkScreen *screen,
error = NULL;
#ifdef HAVE_STARTUP_NOTIFICATION
timestamp = slowly_and_stupidly_obtain_timestamp (GDK_WINDOW_XDISPLAY (GTK_WIDGET (parent_window)->window));
gnome_desktop_item_set_launch_time (ditem, timestamp);
#endif
gnome_desktop_item_launch_with_env (ditem, (GList *) parameter_uris,
flags, envp,
&error);

View file

@ -27,16 +27,16 @@
#define NAUTILUS_PROGRAM_CHOOSING_H
#include <gtk/gtkwindow.h>
#include <libgnomevfs/gnome-vfs-mime-handlers.h>
#include <gio/gappinfo.h>
#include <libnautilus-private/nautilus-file.h>
#define NAUTILUS_COMMAND_SPECIFIER "command:"
#define NAUTILUS_DESKTOP_COMMAND_SPECIFIER "desktop-file:"
typedef void (*NautilusApplicationChoiceCallback) (GnomeVFSMimeApplication *application,
typedef void (*NautilusApplicationChoiceCallback) (GAppInfo *application,
gpointer callback_data);
void nautilus_launch_application (GnomeVFSMimeApplication *application,
void nautilus_launch_application (GAppInfo *application,
GList *files,
GtkWindow *parent_window);
void nautilus_launch_application_from_command (GdkScreen *screen,
@ -48,7 +48,5 @@ void nautilus_launch_desktop_file (GdkScreen *screen,
const char *desktop_file_uri,
const GList *parameter_uris,
GtkWindow *parent_window);
void nautilus_launch_show_file (NautilusFile *file,
GtkWindow *parent_window);
#endif /* NAUTILUS_PROGRAM_CHOOSING_H */

View file

@ -0,0 +1,752 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-progress-info.h: file operation progress info.
Copyright (C) 2007 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.
Author: Alexander Larsson <alexl@redhat.com>
*/
#include <config.h>
#include <math.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <eel/eel-string.h>
#include <eel/eel-glib-extensions.h>
#include "nautilus-progress-info.h"
enum {
CHANGED,
PROGRESS_CHANGED,
STARTED,
FINISHED,
LAST_SIGNAL
};
/* TODO:
* Want an icon for the operation.
* Add and implement cancel button
*/
#define SIGNAL_DELAY_MSEC 100
static guint signals[LAST_SIGNAL] = { 0 };
struct _NautilusProgressInfo
{
GObject parent_instance;
GCancellable *cancellable;
char *status;
char *details;
double progress;
gboolean activity_mode;
gboolean started;
gboolean finished;
GSource *idle_source;
gboolean source_is_now;
gboolean start_at_idle;
gboolean finish_at_idle;
gboolean changed_at_idle;
gboolean progress_at_idle;
};
struct _NautilusProgressInfoClass
{
GObjectClass parent_class;
};
static GList *active_progress_infos = NULL;
static GtkStatusIcon *status_icon = NULL;
static int n_progress_ops = 0;
G_LOCK_DEFINE_STATIC(progress_info);
G_DEFINE_TYPE (NautilusProgressInfo, nautilus_progress_info, G_TYPE_OBJECT)
GList *
nautilus_get_all_progress_info (void)
{
GList *l;
G_LOCK (progress_info);
l = eel_g_object_list_copy (active_progress_infos);
G_UNLOCK (progress_info);
return l;
}
static void
nautilus_progress_info_finalize (GObject *object)
{
NautilusProgressInfo *info;
info = NAUTILUS_PROGRESS_INFO (object);
g_free (info->status);
g_free (info->details);
g_object_unref (info->cancellable);
if (G_OBJECT_CLASS (nautilus_progress_info_parent_class)->finalize) {
(*G_OBJECT_CLASS (nautilus_progress_info_parent_class)->finalize) (object);
}
}
static void
nautilus_progress_info_dispose (GObject *object)
{
NautilusProgressInfo *info;
info = NAUTILUS_PROGRESS_INFO (object);
G_LOCK (progress_info);
/* Remove from active list in dispose, since a get_all_progress_info()
call later could revive the object */
active_progress_infos = g_list_remove (active_progress_infos, object);
/* Destroy source in dispose, because the callback
could come here before the destroy, which should
ressurect the object for a while */
if (info->idle_source) {
g_source_destroy (info->idle_source);
g_source_unref (info->idle_source);
info->idle_source = NULL;
}
G_UNLOCK (progress_info);
}
static void
nautilus_progress_info_class_init (NautilusProgressInfoClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = nautilus_progress_info_finalize;
gobject_class->dispose = nautilus_progress_info_dispose;
signals[CHANGED] =
g_signal_new ("changed",
NAUTILUS_TYPE_PROGRESS_INFO,
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
signals[PROGRESS_CHANGED] =
g_signal_new ("progress-changed",
NAUTILUS_TYPE_PROGRESS_INFO,
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
signals[STARTED] =
g_signal_new ("started",
NAUTILUS_TYPE_PROGRESS_INFO,
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
signals[FINISHED] =
g_signal_new ("finished",
NAUTILUS_TYPE_PROGRESS_INFO,
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}
static gboolean
delete_event (GtkWidget *widget,
GdkEventAny *event)
{
gtk_widget_hide (widget);
return TRUE;
}
static GtkWidget *
get_progress_window (void)
{
static GtkWidget *progress_window = NULL;
GtkWidget *vbox;
if (progress_window != NULL) {
return progress_window;
}
progress_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_resizable (GTK_WINDOW (progress_window),
FALSE);
gtk_window_set_title (GTK_WINDOW (progress_window),
_("File operations"));
gtk_window_set_wmclass (GTK_WINDOW (progress_window),
"file_progress", "Nautilus");
gtk_window_set_type_hint (GTK_WINDOW (progress_window),
GDK_WINDOW_TYPE_HINT_DIALOG);
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
gtk_widget_show (vbox);
gtk_container_add (GTK_CONTAINER (progress_window),
vbox);
g_signal_connect (progress_window, "delete_event", (GCallback)delete_event, NULL);
status_icon = gtk_status_icon_new_from_icon_name ("stock_folder-copy");
g_signal_connect_swapped (status_icon, "activate", (GCallback)gtk_window_present, progress_window);
gtk_status_icon_set_visible (status_icon, FALSE);
return progress_window;
}
typedef struct {
GtkWidget *widget;
NautilusProgressInfo *info;
GtkLabel *status;
GtkLabel *details;
GtkProgressBar *progress_bar;
} ProgressWidgetData;
static void
progress_widget_data_free (ProgressWidgetData *data)
{
g_object_unref (data->info);
g_free (data);
}
static void
update_data (ProgressWidgetData *data)
{
char *status, *details;
char *markup;
status = nautilus_progress_info_get_status (data->info);
gtk_label_set_text (data->status, status);
g_free (status);
details = nautilus_progress_info_get_details (data->info);
markup = g_markup_printf_escaped ("<span size='small'>%s</span>", details);
gtk_label_set_markup (data->details, markup);
g_free (details);
g_free (markup);
}
static void
update_progress (ProgressWidgetData *data)
{
double progress;
progress = nautilus_progress_info_get_progress (data->info);
if (progress < 0) {
gtk_progress_bar_pulse (data->progress_bar);
} else {
gtk_progress_bar_set_fraction (data->progress_bar, progress);
}
}
static void
update_status_icon_and_window (void)
{
char *tooltip;
tooltip = g_strdup_printf (_("%d file operations active"),
n_progress_ops);
gtk_status_icon_set_tooltip (status_icon, tooltip);
g_free (tooltip);
if (n_progress_ops == 0) {
gtk_status_icon_set_visible (status_icon, FALSE);
gtk_widget_hide (get_progress_window ());
} else {
gtk_status_icon_set_visible (status_icon, TRUE);
}
}
static void
op_finished (ProgressWidgetData *data)
{
gtk_widget_destroy (data->widget);
n_progress_ops--;
update_status_icon_and_window ();
}
static GtkWidget *
progress_widget_new (NautilusProgressInfo *info)
{
ProgressWidgetData *data;
GtkWidget *label, *bar;
data = g_new0 (ProgressWidgetData, 1);
data->info = g_object_ref (info);
data->widget = gtk_vbox_new (FALSE, 0);
g_object_set_data_full (G_OBJECT (data->widget),
"data", data, (GDestroyNotify)progress_widget_data_free);
label = gtk_label_new ("details");
gtk_widget_set_size_request (label,
400, -1);
data->status = GTK_LABEL (label);
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_widget_show (label);
gtk_box_pack_start (GTK_BOX (data->widget),
label,
FALSE, FALSE,
2);
bar = gtk_progress_bar_new ();
data->progress_bar = GTK_PROGRESS_BAR (bar);
gtk_progress_bar_set_pulse_step (data->progress_bar, 0.05);
gtk_widget_show (bar);
gtk_box_pack_start (GTK_BOX (data->widget),
bar,
FALSE, FALSE,
2);
label = gtk_label_new ("status");
gtk_widget_set_size_request (label,
400, -1);
data->details = GTK_LABEL (label);
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_widget_show (label);
gtk_box_pack_start (GTK_BOX (data->widget),
label,
FALSE, FALSE,
0);
update_data (data);
update_progress (data);
g_signal_connect_swapped (data->info, "changed", (GCallback)update_data, data);
g_signal_connect_swapped (data->info, "progress_changed", (GCallback)update_progress, data);
g_signal_connect_swapped (data->info, "finished", (GCallback)op_finished, data);
gtk_widget_show (data->widget);
return data->widget;
}
static void
handle_new_progress_info (NautilusProgressInfo *info)
{
GtkWidget *window, *progress;
window = get_progress_window ();
progress = progress_widget_new (info);
gtk_box_pack_start (GTK_BOX (GTK_BIN (window)->child),
progress,
FALSE, FALSE, 6);
gtk_window_present (GTK_WINDOW (window));
n_progress_ops++;
update_status_icon_and_window ();
}
static gboolean
new_op_started_timeout (NautilusProgressInfo *info)
{
if (!nautilus_progress_info_get_is_finished (info)) {
handle_new_progress_info (info);
}
g_object_unref (info);
return FALSE;
}
static void
new_op_started (NautilusProgressInfo *info)
{
g_signal_handlers_disconnect_by_func (info, (GCallback)new_op_started, NULL);
g_timeout_add_seconds (2,
(GSourceFunc)new_op_started_timeout,
g_object_ref (info));
}
static void
nautilus_progress_info_init (NautilusProgressInfo *info)
{
info->cancellable = g_cancellable_new ();
G_LOCK (progress_info);
active_progress_infos = g_list_append (active_progress_infos, info);
G_UNLOCK (progress_info);
g_signal_connect (info, "started", (GCallback)new_op_started, NULL);
}
NautilusProgressInfo *
nautilus_progress_info_new (void)
{
NautilusProgressInfo *info;
info = g_object_new (NAUTILUS_TYPE_PROGRESS_INFO, NULL);
return info;
}
char *
nautilus_progress_info_get_status (NautilusProgressInfo *info)
{
char *res;
G_LOCK (progress_info);
if (info->status) {
res = g_strdup (info->status);
} else {
res = g_strdup (_("Preparing"));
}
G_UNLOCK (progress_info);
return res;
}
char *
nautilus_progress_info_get_details (NautilusProgressInfo *info)
{
char *res;
G_LOCK (progress_info);
if (info->details) {
res = g_strdup (info->details);
} else {
res = g_strdup (_("Preparing"));
}
G_UNLOCK (progress_info);
return res;
}
double
nautilus_progress_info_get_progress (NautilusProgressInfo *info)
{
double res;
G_LOCK (progress_info);
if (info->activity_mode) {
res = -1.0;
} else {
res = info->progress;
}
G_UNLOCK (progress_info);
return res;
}
GCancellable *
nautilus_progress_info_get_cancellable (NautilusProgressInfo *info)
{
GCancellable *c;
G_LOCK (progress_info);
c = g_object_ref (info->cancellable);
G_UNLOCK (progress_info);
return c;
}
gboolean
nautilus_progress_info_get_is_started (NautilusProgressInfo *info)
{
gboolean res;
G_LOCK (progress_info);
res = info->started;
G_UNLOCK (progress_info);
return res;
}
gboolean
nautilus_progress_info_get_is_finished (NautilusProgressInfo *info)
{
gboolean res;
G_LOCK (progress_info);
res = info->finished;
G_UNLOCK (progress_info);
return res;
}
static gboolean
idle_callback (gpointer data)
{
NautilusProgressInfo *info = data;
gboolean start_at_idle;
gboolean finish_at_idle;
gboolean changed_at_idle;
gboolean progress_at_idle;
GSource *source;
source = g_main_current_source ();
G_LOCK (progress_info);
/* Protect agains races where the source has
been destroyed on another thread while it
was being dispatched.
Similar to what gdk_threads_add_idle does.
*/
if (g_source_is_destroyed (source)) {
G_UNLOCK (progress_info);
return FALSE;
}
/* We hadn't destroyed the source, so take a ref.
* This might ressurect the object from dispose, but
* that should be ok.
*/
g_object_ref (info);
g_assert (source == info->idle_source);
g_source_unref (source);
info->idle_source = NULL;
start_at_idle = info->start_at_idle;
finish_at_idle = info->finish_at_idle;
changed_at_idle = info->changed_at_idle;
progress_at_idle = info->progress_at_idle;
info->start_at_idle = FALSE;
info->finish_at_idle = FALSE;
info->changed_at_idle = FALSE;
info->progress_at_idle = FALSE;
G_UNLOCK (progress_info);
if (start_at_idle) {
g_signal_emit (info,
signals[STARTED],
0);
}
if (changed_at_idle) {
g_signal_emit (info,
signals[CHANGED],
0);
}
if (progress_at_idle) {
g_signal_emit (info,
signals[PROGRESS_CHANGED],
0);
}
if (finish_at_idle) {
g_signal_emit (info,
signals[FINISHED],
0);
}
g_object_unref (info);
return FALSE;
}
/* Called with lock held */
static void
queue_idle (NautilusProgressInfo *info, gboolean now)
{
if (info->idle_source == NULL ||
(now && !info->source_is_now)) {
if (info->idle_source) {
g_source_destroy (info->idle_source);
g_source_unref (info->idle_source);
info->idle_source = NULL;
}
info->source_is_now = now;
if (now) {
info->idle_source = g_idle_source_new ();
} else {
info->idle_source = g_timeout_source_new (SIGNAL_DELAY_MSEC);
}
g_source_set_callback (info->idle_source, idle_callback, info, NULL);
g_source_attach (info->idle_source, NULL);
}
}
void
nautilus_progress_info_start (NautilusProgressInfo *info)
{
G_LOCK (progress_info);
if (!info->started) {
info->started = TRUE;
info->start_at_idle = TRUE;
queue_idle (info, TRUE);
}
G_UNLOCK (progress_info);
}
void
nautilus_progress_info_finish (NautilusProgressInfo *info)
{
G_LOCK (progress_info);
if (!info->finished) {
info->finished = TRUE;
info->finish_at_idle = TRUE;
queue_idle (info, TRUE);
}
G_UNLOCK (progress_info);
}
void
nautilus_progress_info_take_status (NautilusProgressInfo *info,
char *status)
{
G_LOCK (progress_info);
if (eel_strcmp (info->status, status) != 0) {
g_free (info->status);
info->status = status;
info->changed_at_idle = TRUE;
queue_idle (info, FALSE);
} else {
g_free (status);
}
G_UNLOCK (progress_info);
}
void
nautilus_progress_info_set_status (NautilusProgressInfo *info,
const char *status)
{
G_LOCK (progress_info);
if (eel_strcmp (info->status, status) != 0) {
g_free (info->status);
info->status = g_strdup (status);
info->changed_at_idle = TRUE;
queue_idle (info, FALSE);
}
G_UNLOCK (progress_info);
}
void
nautilus_progress_info_take_details (NautilusProgressInfo *info,
char *details)
{
G_LOCK (progress_info);
if (eel_strcmp (info->details, details) != 0) {
g_free (info->details);
info->details = details;
info->changed_at_idle = TRUE;
queue_idle (info, FALSE);
} else {
g_free (details);
}
G_UNLOCK (progress_info);
}
void
nautilus_progress_info_set_details (NautilusProgressInfo *info,
const char *details)
{
G_LOCK (progress_info);
if (eel_strcmp (info->details, details) != 0) {
g_free (info->details);
info->details = g_strdup (details);
info->changed_at_idle = TRUE;
queue_idle (info, FALSE);
}
G_UNLOCK (progress_info);
}
void
nautilus_progress_info_pulse_progress (NautilusProgressInfo *info)
{
G_LOCK (progress_info);
info->activity_mode = TRUE;
info->progress = 0.0;
info->progress_at_idle = TRUE;
queue_idle (info, FALSE);
G_UNLOCK (progress_info);
}
void
nautilus_progress_info_set_progress (NautilusProgressInfo *info,
double current_percent)
{
G_LOCK (progress_info);
if (info->activity_mode || /* emit on switch from activity mode */
fabs (current_percent - info->progress) > 0.005 /* Emit on change of 0.5 percent */
) {
info->activity_mode = FALSE;
info->progress = current_percent;
info->progress_at_idle = TRUE;
queue_idle (info, FALSE);
}
G_UNLOCK (progress_info);
}

View file

@ -0,0 +1,80 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-progress-info.h: file operation progress info.
Copyright (C) 2007 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.
Author: Alexander Larsson <alexl@redhat.com>
*/
#ifndef NAUTILUS_PROGRESS_INFO_H
#define NAUTILUS_PROGRESS_INFO_H
#include <glib-object.h>
#include <gio/gcancellable.h>
#define NAUTILUS_TYPE_PROGRESS_INFO (nautilus_progress_info_get_type ())
#define NAUTILUS_PROGRESS_INFO(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NAUTILUS_TYPE_PROGRESS_INFO, NautilusProgressInfo))
#define NAUTILUS_PROGRESS_INFO_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NAUTILUS_TYPE_PROGRESS_INFO, NautilusProgressInfoClass))
#define NAUTILUS_IS_PROGRESS_INFO(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NAUTILUS_TYPE_PROGRESS_INFO))
#define NAUTILUS_IS_PROGRESS_INFO_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NAUTILUS_TYPE_PROGRESS_INFO))
#define NAUTILUS_PROGRESS_INFO_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NAUTILUS_TYPE_PROGRESS_INFO, NautilusProgressInfoClass))
typedef struct _NautilusProgressInfo NautilusProgressInfo;
typedef struct _NautilusProgressInfoClass NautilusProgressInfoClass;
GType nautilus_progress_info_get_type (void) G_GNUC_CONST;
/* Signals:
"changed" - status or details changed
"progress-changed" - the percentage progress changed (or we pulsed if in activity_mode
"started" - emited on job start
"finished" - emitted when job is done
All signals are emitted from idles in main loop.
All methods are threadsafe.
*/
NautilusProgressInfo *nautilus_progress_info_new (void);
GList * nautilus_get_all_progress_info (void);
char * nautilus_progress_info_get_status (NautilusProgressInfo *info);
char * nautilus_progress_info_get_details (NautilusProgressInfo *info);
double nautilus_progress_info_get_progress (NautilusProgressInfo *info);
GCancellable *nautilus_progress_info_get_cancellable (NautilusProgressInfo *info);
gboolean nautilus_progress_info_get_is_started (NautilusProgressInfo *info);
gboolean nautilus_progress_info_get_is_finished (NautilusProgressInfo *info);
void nautilus_progress_info_start (NautilusProgressInfo *info);
void nautilus_progress_info_finish (NautilusProgressInfo *info);
void nautilus_progress_info_set_status (NautilusProgressInfo *info,
const char *status);
void nautilus_progress_info_take_status (NautilusProgressInfo *info,
char *status);
void nautilus_progress_info_set_details (NautilusProgressInfo *info,
const char *details);
void nautilus_progress_info_take_details (NautilusProgressInfo *info,
char *details);
void nautilus_progress_info_set_progress (NautilusProgressInfo *info,
double current_percent);
void nautilus_progress_info_pulse_progress (NautilusProgressInfo *info);
#endif /* NAUTILUS_PROGRESS_INFO_H */

View file

@ -25,7 +25,6 @@
#define NAUTILUS_QUERY_H
#include <glib-object.h>
#include <libgnomevfs/gnome-vfs-result.h>
#define NAUTILUS_TYPE_QUERY (nautilus_query_get_type ())
#define NAUTILUS_QUERY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_QUERY, NautilusQuery))

View file

@ -20,6 +20,8 @@
#include "nautilus-recent.h"
#include <eel/eel-vfs-extensions.h>
#define DEFAULT_APP_EXEC "gnome-open %u"
static GtkRecentManager *
@ -37,23 +39,21 @@ nautilus_recent_get_manager (void)
void
nautilus_recent_add_file (NautilusFile *file,
GnomeVFSMimeApplication *application)
GAppInfo *application)
{
GtkRecentData recent_data;
char *uri;
GnomeVFSURI *vfs_uri;
uri = nautilus_file_get_uri (file);
/* Only add real gnome-vfs uris to recent. Not things like
trash:// and x-nautilus-desktop:// */
vfs_uri = gnome_vfs_uri_new (uri);
if (vfs_uri == NULL) {
/* do not add trash:// etc */
if (eel_uri_is_trash (uri) ||
eel_uri_is_search (uri) ||
eel_uri_is_desktop (uri)) {
g_free (uri);
return;
}
gnome_vfs_uri_unref (vfs_uri);
recent_data.display_name = NULL;
recent_data.description = NULL;
@ -61,7 +61,7 @@ nautilus_recent_add_file (NautilusFile *file,
recent_data.app_name = g_strdup (g_get_application_name ());
if (application != NULL)
recent_data.app_exec = g_strdup (gnome_vfs_mime_application_get_exec (application));
recent_data.app_exec = g_strdup (g_app_info_get_executable (application));
else
recent_data.app_exec = g_strdup (DEFAULT_APP_EXEC);

View file

@ -5,9 +5,9 @@
#include <gtk/gtkrecentmanager.h>
#include <libnautilus-private/nautilus-file.h>
#include <libgnomevfs/gnome-vfs-mime-handlers.h>
#include <gio/gappinfo.h>
void nautilus_recent_add_file (NautilusFile *file,
GnomeVFSMimeApplication *application);
GAppInfo *application);
#endif

View file

@ -24,39 +24,26 @@
*/
#include <config.h>
#include "nautilus-saved-search-file.h"
#include <eel/eel-gtk-macros.h>
static void nautilus_saved_search_file_init (gpointer object, gpointer klass);
static void nautilus_saved_search_file_class_init (gpointer klass);
EEL_CLASS_BOILERPLATE (NautilusSavedSearchFile,
nautilus_saved_search_file,
NAUTILUS_TYPE_VFS_FILE)
#include "nautilus-file-private.h"
G_DEFINE_TYPE(NautilusSavedSearchFile, nautilus_saved_search_file, NAUTILUS_TYPE_VFS_FILE)
static void
nautilus_saved_search_file_init (gpointer object, gpointer klass)
nautilus_saved_search_file_init (NautilusSavedSearchFile *search_file)
{
NautilusVFSFile *file;
NautilusFile *file;
file = NAUTILUS_VFS_FILE (object);
}
static GnomeVFSFileType
saved_search_get_file_type (NautilusFile *file)
{
return GNOME_VFS_FILE_TYPE_DIRECTORY;
file = NAUTILUS_FILE (search_file);
}
static void
nautilus_saved_search_file_class_init (gpointer klass)
nautilus_saved_search_file_class_init (NautilusSavedSearchFileClass * klass)
{
NautilusFileClass *file_class;
file_class = NAUTILUS_FILE_CLASS (klass);
file_class->get_file_type = saved_search_get_file_type;
file_class->default_file_type = G_FILE_TYPE_DIRECTORY;
}

View file

@ -32,24 +32,18 @@
#include "nautilus-file-private.h"
#include "nautilus-file-utilities.h"
#include <eel/eel-glib-extensions.h>
#include <eel/eel-gtk-macros.h>
#include "nautilus-search-directory.h"
#include <gtk/gtksignal.h>
#include <glib/gi18n.h>
#include <string.h>
static void nautilus_search_directory_file_init (gpointer object,
gpointer klass);
static void nautilus_search_directory_file_class_init (gpointer klass);
EEL_CLASS_BOILERPLATE (NautilusSearchDirectoryFile,
nautilus_search_directory_file,
NAUTILUS_TYPE_FILE);
struct NautilusSearchDirectoryFileDetails {
NautilusSearchDirectory *search_directory;
};
G_DEFINE_TYPE(NautilusSearchDirectoryFile, nautilus_search_directory_file, NAUTILUS_TYPE_FILE);
static void
search_directory_file_monitor_add (NautilusFile *file,
gconstpointer client,
@ -57,6 +51,9 @@ search_directory_file_monitor_add (NautilusFile *file,
{
/* No need for monitoring, we always emit changed when files
are added/removed, and no other metadata changes */
/* Update display name, in case this didn't happen yet */
nautilus_search_directory_file_update_display_name (NAUTILUS_SEARCH_DIRECTORY_FILE (file));
}
static void
@ -73,6 +70,9 @@ search_directory_file_call_when_ready (NautilusFile *file,
gpointer callback_data)
{
/* Update display name, in case this didn't happen yet */
nautilus_search_directory_file_update_display_name (NAUTILUS_SEARCH_DIRECTORY_FILE (file));
/* All data for directory-as-file is always uptodate */
(* callback) (file, callback_data);
}
@ -85,7 +85,6 @@ search_directory_file_cancel_call_when_ready (NautilusFile *file,
/* Do nothing here, we don't have any pending calls */
}
static gboolean
search_directory_file_check_if_ready (NautilusFile *file,
NautilusFileAttributes attributes)
@ -93,12 +92,6 @@ search_directory_file_check_if_ready (NautilusFile *file,
return TRUE;
}
static GnomeVFSFileType
search_directory_file_get_file_type (NautilusFile *file)
{
return GNOME_VFS_FILE_TYPE_DIRECTORY;
}
static gboolean
search_directory_file_get_item_count (NautilusFile *file,
guint *count,
@ -125,13 +118,13 @@ search_directory_file_get_deep_counts (NautilusFile *file,
guint *directory_count,
guint *file_count,
guint *unreadable_directory_count,
GnomeVFSFileSize *total_size)
goffset *total_size)
{
NautilusSearchDirectory *search_dir;
NautilusFile *dir_file;
GList *file_list, *l;
guint dirs, files;
GnomeVFSFileType type;
GFileType type;
search_dir = NAUTILUS_SEARCH_DIRECTORY (file->details->directory);
@ -141,7 +134,7 @@ search_directory_file_get_deep_counts (NautilusFile *file,
for (l = file_list; l != NULL; l = l->next) {
dir_file = NAUTILUS_FILE (l->data);
type = nautilus_file_get_file_type (dir_file);
if (type == GNOME_VFS_FILE_TYPE_DIRECTORY) {
if (type == G_FILE_TYPE_DIRECTORY) {
dirs++;
} else {
files++;
@ -172,54 +165,67 @@ search_directory_file_get_where_string (NautilusFile *file)
{
return g_strdup (_("Search"));
}
static void
nautilus_search_directory_file_init (gpointer object, gpointer klass)
void
nautilus_search_directory_file_update_display_name (NautilusSearchDirectoryFile *search_file)
{
NautilusSearchDirectoryFile *search_file;
NautilusFile *file;
GnomeVFSFileInfo *file_info;
NautilusSearchDirectory *search_dir;
NautilusQuery *query;
char *display_name;
gboolean changed;
search_file = NAUTILUS_SEARCH_DIRECTORY_FILE (object);
file = NAUTILUS_FILE(object);
file_info = file->details->info = gnome_vfs_file_info_new ();
file_info->name = g_strdup (_("Search"));
file_info->mime_type = g_strdup ("x-directory/normal");
file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY;
file_info->flags = GNOME_VFS_FILE_FLAGS_NONE;
file_info->link_count = 1;
file_info->size = 0;
file_info->permissions =
GNOME_VFS_PERM_OTHER_WRITE |
GNOME_VFS_PERM_GROUP_WRITE |
GNOME_VFS_PERM_USER_READ |
GNOME_VFS_PERM_OTHER_READ |
GNOME_VFS_PERM_GROUP_READ;
file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
GNOME_VFS_FILE_INFO_FIELDS_FLAGS |
GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE |
GNOME_VFS_FILE_INFO_FIELDS_SIZE |
GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS |
GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT;
display_name = NULL;
file = NAUTILUS_FILE (search_file);
if (file->details->directory) {
search_dir = NAUTILUS_SEARCH_DIRECTORY (file->details->directory);
query = nautilus_search_directory_get_query (search_dir);
if (query != NULL) {
display_name = nautilus_query_to_readable_string (query);
g_object_unref (query);
}
}
if (display_name == NULL) {
display_name = g_strdup (_("Search"));
}
changed = nautilus_file_set_display_name (file, display_name, NULL, FALSE);
if (changed) {
nautilus_file_emit_changed (file);
}
}
static void
nautilus_search_directory_file_init (NautilusSearchDirectoryFile *search_file)
{
NautilusFile *file;
file = NAUTILUS_FILE (search_file);
file->details->got_file_info = TRUE;
file->details->mime_type = eel_ref_str_get_unique ("x-directory/normal");
file->details->type = G_FILE_TYPE_DIRECTORY;
file->details->size = 0;
file->details->file_info_is_up_to_date = TRUE;
file->details->display_name = g_strdup (_("Search"));
file->details->custom_icon = NULL;
file->details->activation_uri = NULL;
file->details->activation_location = NULL;
file->details->got_link_info = TRUE;
file->details->link_info_is_up_to_date = TRUE;
file->details->directory_count = 0;
file->details->got_directory_count = TRUE;
file->details->directory_count_is_up_to_date = TRUE;
nautilus_file_set_display_name (file, _("Search"), NULL, FALSE);
}
static void
nautilus_search_directory_file_class_init (gpointer klass)
nautilus_search_directory_file_class_init (NautilusSearchDirectoryFileClass *klass)
{
GObjectClass *object_class;
NautilusFileClass *file_class;
@ -227,11 +233,12 @@ nautilus_search_directory_file_class_init (gpointer klass)
object_class = G_OBJECT_CLASS (klass);
file_class = NAUTILUS_FILE_CLASS (klass);
file_class->default_file_type = G_FILE_TYPE_DIRECTORY;
file_class->monitor_add = search_directory_file_monitor_add;
file_class->monitor_remove = search_directory_file_monitor_remove;
file_class->call_when_ready = search_directory_file_call_when_ready;
file_class->cancel_call_when_ready = search_directory_file_cancel_call_when_ready;
file_class->get_file_type = search_directory_file_get_file_type;
file_class->check_if_ready = search_directory_file_check_if_ready;
file_class->get_item_count = search_directory_file_get_item_count;
file_class->get_deep_counts = search_directory_file_get_deep_counts;

View file

@ -51,5 +51,6 @@ typedef struct {
} NautilusSearchDirectoryFileClass;
GType nautilus_search_directory_file_get_type (void);
void nautilus_search_directory_file_update_display_name (NautilusSearchDirectoryFile *search_file);
#endif /* NAUTILUS_SEARCH_DIRECTORY_FILE_H */

View file

@ -22,6 +22,7 @@
#include <config.h>
#include "nautilus-search-directory.h"
#include "nautilus-search-directory-file.h"
#include "nautilus-directory-private.h"
#include "nautilus-file.h"
@ -29,8 +30,8 @@
#include "nautilus-file-utilities.h"
#include "nautilus-search-engine.h"
#include <eel/eel-glib-extensions.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <gtk/gtksignal.h>
#include <gio/gioerror.h>
#include <libgnome/gnome-macros.h>
#include <string.h>
#include <sys/time.h>
@ -484,7 +485,7 @@ search_engine_hits_added (NautilusSearchEngine *engine, GList *hits,
continue;
}
file = nautilus_file_get (uri);
file = nautilus_file_get_by_uri (uri);
for (monitor_list = search->details->monitor_list; monitor_list; monitor_list = monitor_list->next) {
monitor = monitor_list->data;
@ -522,7 +523,7 @@ search_engine_hits_subtracted (NautilusSearchEngine *engine, GList *hits,
for (hit_list = hits; hit_list != NULL; hit_list = hit_list->next) {
uri = hit_list->data;
file = nautilus_file_get (uri);
file = nautilus_file_get_by_uri (uri);
for (monitor_list = search->details->monitor_list; monitor_list;
monitor_list = monitor_list->next) {
@ -559,8 +560,13 @@ search_callback_add_pending_file_callbacks (SearchCallback *callback)
static void
search_engine_error (NautilusSearchEngine *engine, const char *error_message, NautilusSearchDirectory *search)
{
GError *error;
error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_FAILED,
error_message);
nautilus_directory_emit_load_error (NAUTILUS_DIRECTORY (search),
-1, error_message);
error);
g_error_free (error);
}
static void
@ -746,12 +752,9 @@ char *
nautilus_search_directory_generate_new_uri (void)
{
static int counter = 0;
struct timeval tv;
char *uri;
gettimeofday (&tv, NULL);
uri = g_strdup_printf (EEL_SEARCH_URI"///%ld-%ld-%d/", tv.tv_sec, tv.tv_usec, counter++);
uri = g_strdup_printf (EEL_SEARCH_URI"//%d/", counter++);
return uri;
}
@ -761,10 +764,13 @@ void
nautilus_search_directory_set_query (NautilusSearchDirectory *search,
NautilusQuery *query)
{
NautilusDirectory *dir;
NautilusFile *as_file;
if (search->details->query != query) {
search->details->modified = TRUE;
}
if (query) {
g_object_ref (query);
}
@ -774,6 +780,12 @@ nautilus_search_directory_set_query (NautilusSearchDirectory *search,
}
search->details->query = query;
dir = NAUTILUS_DIRECTORY (search);
as_file = dir->details->as_file;
if (as_file != NULL) {
nautilus_search_directory_file_update_display_name (NAUTILUS_SEARCH_DIRECTORY_FILE (as_file));
}
}
NautilusQuery *
@ -797,7 +809,7 @@ nautilus_search_directory_new_from_saved_search (const char *uri)
search->details->saved_search_uri = g_strdup (uri);
file = gnome_vfs_get_local_path_from_uri (uri);
file = g_filename_from_uri (uri, NULL, NULL);
if (file != NULL) {
query = nautilus_query_load (file);
if (query != NULL) {
@ -839,7 +851,7 @@ nautilus_search_directory_save_to_file (NautilusSearchDirectory *search,
{
char *file;
file = gnome_vfs_get_local_path_from_uri (save_file_uri);
file = g_filename_from_uri (save_file_uri, NULL, NULL);
if (file == NULL) {
return;
}

View file

@ -28,23 +28,26 @@
#include <glib/gstrfuncs.h>
#include <eel/eel-gtk-macros.h>
#include <eel/eel-glib-extensions.h>
#include <libgnomevfs/gnome-vfs-directory.h>
#include <gio/gfile.h>
#include <gio/gfileenumerator.h>
#include <gio/gcontenttype.h>
#define BATCH_SIZE 500
typedef struct {
NautilusSearchEngineSimple *engine;
GCancellable *cancellable;
GnomeVFSURI *uri;
GList *mime_types;
char **words;
GList *found_list;
GQueue *directories; /* GFiles */
GHashTable *visited;
gint n_processed_files;
GList *uri_hits;
/* accessed on both threads: */
volatile gboolean cancelled;
} SearchThreadData;
@ -89,18 +92,23 @@ search_thread_data_new (NautilusSearchEngineSimple *engine,
{
SearchThreadData *data;
char *text, *lower, *normalized, *uri;
GFile *location;
data = g_new0 (SearchThreadData, 1);
data->engine = engine;
data->directories = g_queue_new ();
data->visited = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
uri = nautilus_query_get_location (query);
location = NULL;
if (uri != NULL) {
data->uri = gnome_vfs_uri_new (uri);
location = g_file_new_for_uri (uri);
g_free (uri);
}
if (data->uri == NULL) {
data->uri = gnome_vfs_uri_new ("file:///");
if (location == NULL) {
location = g_file_new_for_path ("/");
}
g_queue_push_tail (data->directories, location);
text = nautilus_query_get_text (query);
normalized = g_utf8_normalize (text, -1, G_NORMALIZE_NFD);
@ -112,15 +120,22 @@ search_thread_data_new (NautilusSearchEngineSimple *engine,
data->mime_types = nautilus_query_get_mime_types (query);
data->cancellable = g_cancellable_new ();
return data;
}
static void
search_thread_data_free (SearchThreadData *data)
{
gnome_vfs_uri_unref (data->uri);
g_queue_foreach (data->directories,
(GFunc)g_object_unref, NULL);
g_queue_free (data->directories);
g_hash_table_destroy (data->visited);
g_object_unref (data->cancellable);
g_strfreev (data->words);
eel_g_list_free_deep (data->mime_types);
eel_g_list_free_deep (data->uri_hits);
g_free (data);
}
@ -131,7 +146,7 @@ search_thread_done_idle (gpointer user_data)
data = user_data;
if (!data->cancelled) {
if (!g_cancellable_is_cancelled (data->cancellable)) {
nautilus_search_engine_finished (NAUTILUS_SEARCH_ENGINE (data->engine));
data->engine->details->active_search = NULL;
}
@ -154,7 +169,7 @@ search_thread_add_hits_idle (gpointer user_data)
hits = user_data;
if (!hits->thread_data->cancelled) {
if (!g_cancellable_is_cancelled (hits->thread_data->cancellable)) {
nautilus_search_engine_hits_added (NAUTILUS_SEARCH_ENGINE (hits->thread_data->engine),
hits->uris);
}
@ -181,46 +196,54 @@ send_batch (SearchThreadData *data)
data->uri_hits = NULL;
}
static gboolean
search_visit_func (const gchar *rel_path,
GnomeVFSFileInfo *info,
gboolean recursing_will_loop,
gpointer user_data,
gboolean *recurse)
#define STD_ATTRIBUTES \
G_FILE_ATTRIBUTE_STD_NAME "," \
G_FILE_ATTRIBUTE_STD_DISPLAY_NAME "," \
G_FILE_ATTRIBUTE_STD_IS_HIDDEN "," \
G_FILE_ATTRIBUTE_STD_TYPE "," \
G_FILE_ATTRIBUTE_ID_FILE
static void
visit_directory (GFile *dir, SearchThreadData *data)
{
SearchThreadData *data;
int i;
GFileEnumerator *enumerator;
GFileInfo *info;
GFile *child;
const char *mime_type, *display_name;
char *lower_name, *normalized;
GnomeVFSURI *uri;
gboolean hit;
int i;
GList *l;
gboolean is_hidden;
data = user_data;
const char *id;
gboolean visited;
if (data->cancelled) {
return FALSE;
enumerator = g_file_enumerate_children (dir,
data->mime_types != NULL ?
STD_ATTRIBUTES ","
G_FILE_ATTRIBUTE_STD_CONTENT_TYPE
:
STD_ATTRIBUTES
,
0, data->cancellable, NULL);
if (enumerator == NULL) {
return;
}
is_hidden = *info->name == '.';
if (recursing_will_loop || is_hidden) {
*recurse = FALSE;
} else {
*recurse = TRUE;
}
hit = FALSE;
if (!is_hidden) {
if (g_utf8_validate (info->name, -1, NULL)) {
normalized = g_utf8_normalize (info->name, -1, G_NORMALIZE_NFD);
lower_name = g_utf8_strdown (normalized, -1);
g_free (normalized);
} else {
lower_name = g_ascii_strdown (info->name, -1);
while ((info = g_file_enumerator_next_file (enumerator, data->cancellable, NULL)) != NULL) {
if (g_file_info_get_is_hidden (info)) {
goto next;
}
display_name = g_file_info_get_display_name (info);
if (display_name == NULL) {
goto next;
}
normalized = g_utf8_normalize (display_name, -1, G_NORMALIZE_NFD);
lower_name = g_utf8_strdown (normalized, -1);
g_free (normalized);
hit = TRUE;
for (i = 0; data->words[i] != NULL; i++) {
if (strstr (lower_name, data->words[i]) == NULL) {
@ -229,56 +252,82 @@ search_visit_func (const gchar *rel_path,
}
}
g_free (lower_name);
}
if (hit && data->mime_types != NULL) {
hit = FALSE;
if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE) {
for (l = data->mime_types; l != NULL; l = l->next) {
if (strcmp (info->mime_type, l->data) == 0) {
if (hit && data->mime_types) {
mime_type = g_file_info_get_content_type (info);
hit = FALSE;
for (l = data->mime_types; mime_type != NULL && l != NULL; l = l->next) {
if (g_content_type_equals (mime_type, l->data) == 0) {
hit = TRUE;
break;
}
}
}
child = g_file_get_child (dir, g_file_info_get_name (info));
if (hit) {
data->uri_hits = g_list_prepend (data->uri_hits, g_file_get_uri (child));
}
data->n_processed_files++;
if (data->n_processed_files > BATCH_SIZE) {
send_batch (data);
}
if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) {
id = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_ID_FILE);
visited = FALSE;
if (id) {
if (g_hash_table_lookup_extended (data->visited,
id, NULL, NULL)) {
visited = TRUE;
} else {
g_hash_table_insert (data->visited, g_strdup (id), NULL);
}
}
if (!visited) {
g_queue_push_tail (data->directories, g_object_ref (child));
}
}
g_object_unref (child);
next:
g_object_unref (info);
}
if (hit) {
uri = gnome_vfs_uri_append_string (data->uri, rel_path);
data->uri_hits = g_list_prepend (data->uri_hits, gnome_vfs_uri_to_string (uri, 0));
gnome_vfs_uri_unref (uri);
}
data->n_processed_files++;
if (data->n_processed_files > BATCH_SIZE) {
send_batch (data);
}
return TRUE;
g_object_unref (enumerator);
}
static gpointer
search_thread_func (gpointer user_data)
{
SearchThreadData *data;
GnomeVFSResult res;
GnomeVFSDirectoryVisitOptions visit_options;
GFile *dir;
GFileInfo *info;
const char *id;
data = user_data;
visit_options = GNOME_VFS_DIRECTORY_VISIT_LOOPCHECK |
GNOME_VFS_DIRECTORY_VISIT_IGNORE_RECURSE_ERROR;
res = gnome_vfs_directory_visit_uri (data->uri,
GNOME_VFS_FILE_INFO_GET_MIME_TYPE,
visit_options,
search_visit_func,
data);
/* Insert id for toplevel directory into visited */
dir = g_queue_peek_head (data->directories);
info = g_file_query_info (dir, G_FILE_ATTRIBUTE_ID_FILE, 0, data->cancellable, NULL);
if (info) {
id = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_ID_FILE);
if (id) {
g_hash_table_insert (data->visited, g_strdup (id), NULL);
}
g_object_unref (info);
}
while (!g_cancellable_is_cancelled (data->cancellable) &&
(dir = g_queue_pop_head (data->directories)) != NULL) {
visit_directory (dir, data);
g_object_unref (dir);
}
send_batch (data);
g_idle_add (search_thread_done_idle, data);
@ -317,7 +366,7 @@ nautilus_search_engine_simple_stop (NautilusSearchEngine *engine)
simple = NAUTILUS_SEARCH_ENGINE_SIMPLE (engine);
if (simple->details->active_search != NULL) {
simple->details->active_search->cancelled = TRUE;
g_cancellable_cancel (simple->details->active_search->cancellable);
simple->details->active_search = NULL;
}
}

View file

@ -24,7 +24,6 @@
#include <config.h>
#include "nautilus-search-engine-tracker.h"
#include <tracker.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <eel/eel-gtk-macros.h>
#include <eel/eel-glib-extensions.h>
@ -92,7 +91,7 @@ search_callback (char **results, GError *error, gpointer user_data)
char *uri;
uri = gnome_vfs_get_uri_from_local_path ((char *)*results_p);
uri = g_filename_to_uri ((char *)*results_p);
if (uri) {
hit_uris = g_list_prepend (hit_uris, (char *)uri);
}
@ -132,7 +131,7 @@ nautilus_search_engine_tracker_start (NautilusSearchEngine *engine)
location_uri = nautilus_query_get_location (tracker->details->query);
if (location_uri) {
location = gnome_vfs_get_local_path_from_uri (location_uri);
location = g_filename_from_uri (location_uri, NULL, NULL);
g_free (location_uri);
} else {
location = NULL;

View file

@ -25,7 +25,6 @@
#define NAUTILUS_SEARCH_ENGINE_H
#include <glib-object.h>
#include <libgnomevfs/gnome-vfs-result.h>
#include <libnautilus-private/nautilus-query.h>
#define NAUTILUS_TYPE_SEARCH_ENGINE (nautilus_search_engine_get_type ())

View file

@ -40,6 +40,7 @@ enum {
EMBLEMS_CHANGED,
POPUP_MENU_CHANGED,
USER_DIRS_CHANGED,
MIME_DATA_CHANGED,
LAST_SIGNAL
};
@ -103,4 +104,12 @@ nautilus_signaller_class_init (NautilusSignallerClass *class)
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
signals[MIME_DATA_CHANGED] =
g_signal_new ("mime_data_changed",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}

View file

@ -1,288 +0,0 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-theme.c: theme framework with xml-based theme definition files
Copyright (C) 1999, 2000 Eazel, 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.
Author: Andy Hertzfeld <andy@eazel.com>
*/
#include <config.h>
#include "nautilus-theme.h"
#include "nautilus-file-utilities.h"
#include "nautilus-file.h"
#include "nautilus-global-preferences.h"
#include "nautilus-metadata.h"
#include <eel/eel-debug.h>
#include <eel/eel-gdk-pixbuf-extensions.h>
#include <eel/eel-glib-extensions.h>
#include <eel/eel-string-list.h>
#include <eel/eel-string.h>
#include <eel/eel-vfs-extensions.h>
#include <eel/eel-xml-extensions.h>
#include <libxml/parser.h>
#include <glib/gi18n.h>
#include <libgnome/gnome-util.h>
#include <libgnome/gnome-util.h>
#include <libgnomevfs/gnome-vfs.h>
#include <libgnomevfs/gnome-vfs-mime-utils.h>
#include <librsvg/rsvg.h>
/* static globals to hold the last accessed theme files */
static char *last_theme_name = NULL;
static xmlDocPtr last_theme_document = NULL;
static char *theme_from_preferences = NULL;
#define THEME_PREVIEW_ICON_WIDTH 70
#define THEME_PREVIEW_ICON_HEIGHT 48
static void
theme_changed_callback (gpointer callback_data)
{
g_free (theme_from_preferences);
theme_from_preferences = eel_preferences_get (NAUTILUS_PREFERENCES_THEME);
}
/* return the current theme by asking the preferences machinery */
char *
nautilus_theme_get_theme (void)
{
static gboolean theme_changed_callback_installed = FALSE;
/* Add the callback once for the life of our process */
if (!theme_changed_callback_installed) {
eel_preferences_add_callback (NAUTILUS_PREFERENCES_THEME,
theme_changed_callback,
NULL);
theme_changed_callback_installed = TRUE;
/* Peek for the first time */
theme_changed_callback (NULL);
}
return g_strdup (theme_from_preferences);
}
/* load and parse a theme file */
static xmlDocPtr
load_theme_document (const char *theme_name)
{
xmlDocPtr theme_document;
char *theme_path, *temp_str;
char *user_themes_directory;
temp_str = g_strdup_printf("%s/%s.xml", theme_name, theme_name);
theme_path = nautilus_pixmap_file (temp_str);
g_free(temp_str);
/* if we can't find the theme document in the global area, try in the user's home */
if (theme_path == NULL) {
user_themes_directory = nautilus_theme_get_user_themes_directory ();
temp_str = g_strdup_printf("%s/%s.xml", theme_name, theme_name);
theme_path = g_build_filename (user_themes_directory, temp_str, NULL);
g_free (user_themes_directory);
g_free (temp_str);
if (!g_file_test (theme_path, G_FILE_TEST_EXISTS)) {
g_free (theme_path);
theme_path = NULL;
}
}
/* if the file cannot be found, return NULL for no document */
if (theme_path == NULL) {
return NULL;
}
/* load and parse the theme file */
theme_document = xmlParseFile (theme_path);
g_free (theme_path);
return theme_document;
}
static void
free_last_theme (void)
{
if (last_theme_document != NULL) {
xmlFreeDoc (last_theme_document);
}
g_free (last_theme_name);
}
/* Fetch data from the specified theme. Cache the last theme file as a parsed xml document
*/
char *
nautilus_theme_get_theme_data_from_theme (const char *resource_name, const char *property_name, const char *theme_name)
{
char *temp_str;
char *theme_data;
xmlDocPtr theme_document;
xmlNodePtr resource_node;
static gboolean did_set_up_free_last_theme = FALSE;
/* fetch the current theme name */
theme_data = NULL;
if (eel_strcmp (theme_name, last_theme_name) == 0) {
theme_document = last_theme_document;
} else {
/* release the old saved data, since the theme changed */
if (!did_set_up_free_last_theme) {
eel_debug_call_at_shutdown (free_last_theme);
did_set_up_free_last_theme = TRUE;
}
free_last_theme ();
last_theme_name = g_strdup (theme_name);
last_theme_document = load_theme_document (theme_name);
theme_document = last_theme_document;
}
if (theme_document != NULL) {
/* fetch the resource node */
resource_node = eel_xml_get_child_by_name (xmlDocGetRootElement (theme_document), resource_name);
if (resource_node != NULL) {
temp_str = xmlGetProp (resource_node, property_name);
if (temp_str != NULL) {
theme_data = g_strdup (temp_str);
xmlFree (temp_str);
}
}
}
return theme_data;
}
/* Fetch data from the current theme.
*/
char *
nautilus_theme_get_theme_data (const char *resource_name, const char *property_name)
{
char *result;
char *theme_name;
theme_name = nautilus_theme_get_theme ();
result = nautilus_theme_get_theme_data_from_theme (resource_name, property_name, theme_name);
g_free (theme_name);
return result;
}
/* utility routine to return the full path to a themed image that
searches the local themes if it can't find it in the shared space */
static char *
nautilus_pixmap_file_may_be_local (const char *themed_image)
{
char *image_path, *user_themes_directory;
image_path = nautilus_pixmap_file (themed_image);
if (image_path == NULL) {
user_themes_directory = nautilus_theme_get_user_themes_directory ();
image_path = g_build_filename (user_themes_directory, themed_image, NULL);
if (!g_file_test (image_path, G_FILE_TEST_EXISTS)) {
g_free (image_path);
image_path = NULL;
}
g_free (user_themes_directory);
}
return image_path;
}
/* given a theme, fetch the full path name of an image with the passed-in name */
/* return NULL if there isn't a corresponding image. Optionally, add a .png suffix if we */
/* cant otherwise find one. */
char *
nautilus_theme_get_image_path_from_theme (const char *image_name, const char* theme_name)
{
char *image_path, *png_string, *temp_str;
temp_str = g_strdup_printf ("%s/%s", theme_name, image_name);
image_path = nautilus_pixmap_file_may_be_local (temp_str);
/* see if a theme-specific image exists; if so, return it */
if (image_path != NULL) {
g_free (temp_str);
return image_path;
}
/* try if with a .png extension if it doesn't already have one */
if (!eel_istr_has_suffix (image_name, ".png")) {
png_string = g_strconcat (temp_str, ".png", NULL);
image_path = nautilus_pixmap_file_may_be_local (png_string);
g_free (png_string);
if (image_path) {
g_free (temp_str);
return image_path;
}
}
g_free (temp_str);
/* we couldn't find a theme specific one, so look for a general image */
image_path = nautilus_pixmap_file (image_name);
if (image_path != NULL) {
return image_path;
}
/* if it doesn't have a .png extension, try it with that */
if (!eel_istr_has_suffix (image_name, ".png")) {
png_string = g_strconcat (image_name, ".png", NULL);
image_path = nautilus_pixmap_file (png_string);
g_free (png_string);
if (image_path) {
return image_path;
}
}
/* we couldn't find anything, so return NULL */
g_free (image_path);
return NULL;
}
/* commonly used cover to get_image_path_from_theme to return an image path using the current theme */
char *
nautilus_theme_get_image_path (const char *image_name)
{
char *theme_name, *image_path;
theme_name = nautilus_theme_get_theme ();
image_path = nautilus_theme_get_image_path_from_theme (image_name, theme_name);
g_free (theme_name);
return image_path;
}
char *
nautilus_theme_get_user_themes_directory (void)
{
char *user_directory;
char *user_themes_directory;
user_directory = nautilus_get_user_directory ();
user_themes_directory = g_build_filename (user_directory, "themes", NULL);
g_free (user_directory);
return user_themes_directory;
}

View file

@ -1,62 +0,0 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-theme.h: theme framework with xml-based theme definition files
Copyright (C) 2000 Eazel, 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.
Authors: Andy Hertzfeld <andy@eazel.com>
*/
#ifndef NAUTILUS_THEME_H
#define NAUTILUS_THEME_H
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <libgnomevfs/gnome-vfs-types.h>
/* A callback which can be invoked for each available theme. */
typedef void (*NautilusThemeCallback) (const char *name,
const char *path,
const char *display_name,
const char *description,
GdkPixbuf *preview_pixbuf,
gboolean builtin,
gpointer callback_data);
/* get the current theme */
char *nautilus_theme_get_theme (void);
/* fetch data from the current theme */
char *nautilus_theme_get_theme_data (const char *resource_name,
const char *property_name);
/* fetch data from the specified theme */
char *nautilus_theme_get_theme_data_from_theme (const char *resource_name,
const char *property_name,
const char *theme_name);
/* given the current theme, get the path name of an image with the passed-in name */
char *nautilus_theme_get_image_path (const char *image_name);
/* like get_image_path, put use the passed in theme instead of the current one */
char *nautilus_theme_get_image_path_from_theme (const char *image_name,
const char *theme_name);
/* Return the directory where user themes are stored */
char *nautilus_theme_get_user_themes_directory (void);
#endif /* NAUTILUS_THEME_H */

View file

@ -28,15 +28,13 @@
#include "nautilus-directory-notify.h"
#include "nautilus-global-preferences.h"
#include "nautilus-icon-factory-private.h"
#include "nautilus-icon-factory.h"
#include "nautilus-file-utilities.h"
#include <math.h>
#include <eel/eel-gdk-pixbuf-extensions.h>
#include <eel/eel-graphic-effects.h>
#include <eel/eel-string.h>
#include <eel/eel-vfs-extensions.h>
#include <gtk/gtkmain.h>
#include <libgnomevfs/gnome-vfs.h>
#include <librsvg/rsvg.h>
#include <errno.h>
#include <stdio.h>
@ -45,6 +43,7 @@
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <libgnomeui/gnome-thumbnail.h>
#include "nautilus-file-private.h"
@ -70,7 +69,7 @@ typedef struct {
} NautilusThumbnailInfo;
struct NautilusThumbnailAsyncLoadHandle {
EelReadFileHandle *eel_read_handle;
GCancellable *cancellable;
char *file_path;
guint base_size;
guint nominal_size;
@ -120,18 +119,17 @@ static int thumbnail_icon_size = 0;
static gboolean
get_file_mtime (const char *file_uri, time_t* mtime)
{
GnomeVFSFileInfo *file_info;
GFile *file;
GFileInfo *info;
/* gather the info and then compare modification times */
file_info = gnome_vfs_file_info_new ();
gnome_vfs_get_file_info (file_uri, file_info, GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
*mtime = INVALID_MTIME;
if (file_info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MTIME)
*mtime = file_info->mtime;
else
*mtime = INVALID_MTIME;
gnome_vfs_file_info_unref (file_info);
file = g_file_new_for_uri (file_uri);
info = g_file_query_info (file, G_FILE_ATTRIBUTE_TIME_MODIFIED, 0, NULL, NULL);
if (info) {
*mtime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
g_object_unref (info);
}
return TRUE;
}
@ -144,6 +142,19 @@ free_thumbnail_info (NautilusThumbnailInfo *info)
g_free (info);
}
static GnomeThumbnailFactory *
get_thumbnail_factory (void)
{
static GnomeThumbnailFactory *thumbnail_factory = NULL;
if (thumbnail_factory == NULL) {
thumbnail_factory = gnome_thumbnail_factory_new (GNOME_THUMBNAIL_SIZE_NORMAL);
}
return thumbnail_factory;
}
/* This function is added as a very low priority idle function to start the
thread to create any needed thumbnails. It is added with a very low priority
so that it doesn't delay showing the directory in the icon/list views.
@ -156,7 +167,7 @@ thumbnail_thread_starter_cb (gpointer data)
/* Don't do this in thread, since g_object_ref is not threadsafe */
if (thumbnail_factory == NULL) {
thumbnail_factory = nautilus_icon_factory_get_thumbnail_factory ();
thumbnail_factory = get_thumbnail_factory ();
}
/* We create the thread in the detached state, as we don't need/want
@ -190,33 +201,32 @@ nautilus_update_thumbnail_file_copied (const char *source_file_uri,
{
char *old_thumbnail_path;
GdkPixbuf *pixbuf;
GnomeVFSFileInfo *file_info;
GFileInfo *file_info;
GnomeThumbnailFactory *factory;
GFile *destination_file;
old_thumbnail_path = gnome_thumbnail_path_for_uri (source_file_uri, GNOME_THUMBNAIL_SIZE_NORMAL);
if (old_thumbnail_path != NULL &&
g_file_test (old_thumbnail_path, G_FILE_TEST_EXISTS)) {
file_info = gnome_vfs_file_info_new ();
if (gnome_vfs_get_file_info (destination_file_uri,
file_info,
GNOME_VFS_FILE_INFO_DEFAULT) == GNOME_VFS_OK) {
destination_file = g_file_new_for_uri (destination_file_uri);
file_info = g_file_query_info (destination_file, G_FILE_ATTRIBUTE_TIME_MODIFIED, 0, NULL, NULL);
g_object_unref (destination_file);
if (file_info != NULL) {
pixbuf = gdk_pixbuf_new_from_file (old_thumbnail_path, NULL);
if (pixbuf && gnome_thumbnail_has_uri (pixbuf, source_file_uri)) {
factory = nautilus_icon_factory_get_thumbnail_factory ();
factory = get_thumbnail_factory ();
gnome_thumbnail_factory_save_thumbnail (factory,
pixbuf,
destination_file_uri,
file_info->mtime);
g_object_unref (factory);
g_file_info_get_attribute_uint64 (file_info, G_FILE_ATTRIBUTE_TIME_MODIFIED));
}
if (pixbuf) {
g_object_unref (pixbuf);
}
g_object_unref (file_info);
}
gnome_vfs_file_info_unref (file_info);
}
g_free (old_thumbnail_path);
@ -242,6 +252,24 @@ nautilus_remove_thumbnail_for_file (const char *file_uri)
g_free (thumbnail_path);
}
static GdkPixbuf *
nautilus_get_thumbnail_frame (void)
{
char *image_path;
static GdkPixbuf *thumbnail_frame = NULL;
if (thumbnail_frame == NULL) {
image_path = nautilus_pixmap_file ("thumbnail_frame.png");
if (image_path != NULL) {
thumbnail_frame = gdk_pixbuf_new_from_file (image_path, NULL);
}
g_free (image_path);
}
return thumbnail_frame;
}
void
nautilus_thumbnail_frame_image (GdkPixbuf **pixbuf)
{
@ -252,22 +280,59 @@ nautilus_thumbnail_frame_image (GdkPixbuf **pixbuf)
* an old Nautilus), so we must embed it in a frame.
*/
frame = nautilus_icon_factory_get_thumbnail_frame ();
frame = nautilus_get_thumbnail_frame ();
if (frame == NULL) {
return;
}
left_offset = 3;
top_offset = 3;
right_offset = 6;
bottom_offset = 6;
left_offset = NAUTILUS_THUMBNAIL_FRAME_LEFT;
top_offset = NAUTILUS_THUMBNAIL_FRAME_TOP;
right_offset = NAUTILUS_THUMBNAIL_FRAME_RIGHT;
bottom_offset = NAUTILUS_THUMBNAIL_FRAME_BOTTOM;
pixbuf_with_frame = eel_embed_image_in_frame
(*pixbuf, frame,
left_offset, top_offset, right_offset, bottom_offset);
g_object_unref (*pixbuf);
*pixbuf=pixbuf_with_frame;
*pixbuf = pixbuf_with_frame;
}
GdkPixbuf *
nautilus_thumbnail_unframe_image (GdkPixbuf *pixbuf)
{
GdkPixbuf *pixbuf_without_frame, *frame;
int left_offset, top_offset, right_offset, bottom_offset;
int w, h;
/* The pixbuf isn't already framed (i.e., it was not made by
* an old Nautilus), so we must embed it in a frame.
*/
frame = nautilus_get_thumbnail_frame ();
if (frame == NULL) {
return NULL;
}
left_offset = NAUTILUS_THUMBNAIL_FRAME_LEFT;
top_offset = NAUTILUS_THUMBNAIL_FRAME_TOP;
right_offset = NAUTILUS_THUMBNAIL_FRAME_RIGHT;
bottom_offset = NAUTILUS_THUMBNAIL_FRAME_BOTTOM;
w = gdk_pixbuf_get_width (pixbuf) - left_offset - right_offset;
h = gdk_pixbuf_get_height (pixbuf) - top_offset - bottom_offset;
pixbuf_without_frame =
gdk_pixbuf_new (gdk_pixbuf_get_colorspace (pixbuf),
gdk_pixbuf_get_has_alpha (pixbuf),
gdk_pixbuf_get_bits_per_sample (pixbuf),
w, h);
gdk_pixbuf_copy_area (pixbuf,
left_offset, top_offset,
w, h,
pixbuf_without_frame, 0, 0);
return pixbuf_without_frame;
}
typedef struct {
@ -443,26 +508,30 @@ nautilus_thumbnail_load_image (const char *path,
}
static void
async_thumbnail_read_image (GnomeVFSResult result,
GnomeVFSFileSize file_size,
char *file_contents,
async_thumbnail_read_image (GObject *source_object,
GAsyncResult *res,
gpointer callback_data)
{
NautilusThumbnailAsyncLoadHandle *handle = callback_data;
GdkPixbuf *pixbuf;
double scale_x, scale_y;
NautilusThumbnailAsyncLoadHandle *handle = callback_data;
gsize file_size;
char *file_contents;
pixbuf = NULL;
scale_x = scale_y = 1.0;
if (result == GNOME_VFS_OK) {
if (g_file_load_contents_finish (G_FILE (source_object),
res,
&file_contents, &file_size,
NULL, NULL)) {
pixbuf = get_pixbuf_from_data (file_contents, file_size,
handle->file_path,
handle->base_size,
handle->nominal_size,
handle->force_nominal,
&scale_x, &scale_y);
g_free (file_contents);
}
handle->load_func (handle,
@ -472,6 +541,7 @@ async_thumbnail_read_image (GnomeVFSResult result,
gdk_pixbuf_unref (pixbuf);
g_object_unref (handle->cancellable);
g_free (handle->file_path);
g_free (handle);
}
@ -485,18 +555,11 @@ nautilus_thumbnail_load_image_async (const char *path,
gpointer load_func_user_data)
{
NautilusThumbnailAsyncLoadHandle *handle;
char *uri;
GFile *location;
uri = gnome_vfs_get_uri_from_local_path (path);
if (uri == NULL) {
return NULL;
}
handle = g_new (NautilusThumbnailAsyncLoadHandle, 1);
handle->eel_read_handle =
eel_read_entire_file_async (uri, GNOME_VFS_PRIORITY_DEFAULT,
(EelReadFileCallback) async_thumbnail_read_image,
handle);
handle->cancellable = g_cancellable_new ();
handle->file_path = g_strdup (path);
handle->base_size = base_size;
handle->nominal_size = nominal_size;
@ -504,8 +567,13 @@ nautilus_thumbnail_load_image_async (const char *path,
handle->load_func = load_func;
handle->load_func_user_data = load_func_user_data;
g_free (uri);
location = g_file_new_for_path (path);
g_file_load_contents_async (location, handle->cancellable,
async_thumbnail_read_image,
handle);
g_object_unref (location);
return handle;
}
@ -514,9 +582,7 @@ nautilus_thumbnail_load_image_cancel (NautilusThumbnailAsyncLoadHandle *handle)
{
g_assert (handle != NULL);
eel_read_file_cancel (handle->eel_read_handle);
g_free (handle->file_path);
g_free (handle);
g_cancellable_cancel (handle->cancellable);
}
void
@ -642,14 +708,16 @@ thumbnail_thread_notify_file_changed (gpointer image_uri)
GDK_THREADS_ENTER ();
file = nautilus_file_get ((char *) image_uri);
file = nautilus_file_get_by_uri ((char *) image_uri);
#ifdef DEBUG_THUMBNAILS
g_message ("(Thumbnail Thread) Notifying file changed file:%p uri: %s\n", file, (char*) image_uri);
#endif
if (file != NULL) {
nautilus_file_set_is_thumbnailing (file, FALSE);
nautilus_file_changed (file);
nautilus_file_invalidate_attributes (file,
NAUTILUS_FILE_ATTRIBUTE_THUMBNAIL |
NAUTILUS_FILE_ATTRIBUTE_INFO);
nautilus_file_unref (file);
}
g_free (image_uri);
@ -659,6 +727,30 @@ thumbnail_thread_notify_file_changed (gpointer image_uri)
return FALSE;
}
gboolean
nautilus_can_thumbnail (NautilusFile *file)
{
GnomeThumbnailFactory *factory;
gboolean res;
char *uri;
time_t mtime;
char *mime_type;
uri = nautilus_file_get_uri (file);
mime_type = nautilus_file_get_mime_type (file);
mtime = nautilus_file_get_mtime (file);
factory = get_thumbnail_factory ();
res = gnome_thumbnail_factory_can_thumbnail (factory,
uri,
mime_type,
mtime);
g_free (mime_type);
g_free (uri);
return res;
}
void
nautilus_create_thumbnail (NautilusFile *file)
{
@ -675,10 +767,10 @@ nautilus_create_thumbnail (NautilusFile *file)
/* Hopefully the NautilusFile will already have the image file mtime,
so we can just use that. Otherwise we have to get it ourselves. */
if (file->details->info
&& file->details->file_info_is_up_to_date
&& file->details->info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MTIME) {
file_mtime = file->details->info->mtime;
if (file->details->got_file_info &&
file->details->file_info_is_up_to_date &&
file->details->mtime != 0) {
file_mtime = file->details->mtime;
} else {
get_file_mtime (info->image_uri, &file_mtime);
}

View file

@ -37,9 +37,17 @@ typedef void (* NautilusThumbnailAsyncLoadFunc) (NautilusThumbnailAsyncLoadHandl
double scale_y,
gpointer user_data);
#define NAUTILUS_THUMBNAIL_FRAME_LEFT 3
#define NAUTILUS_THUMBNAIL_FRAME_TOP 3
#define NAUTILUS_THUMBNAIL_FRAME_RIGHT 6
#define NAUTILUS_THUMBNAIL_FRAME_BOTTOM 6
/* Returns NULL if there's no thumbnail yet. */
void nautilus_create_thumbnail (NautilusFile *file);
gboolean nautilus_can_thumbnail (NautilusFile *file);
void nautilus_thumbnail_frame_image (GdkPixbuf **pixbuf);
GdkPixbuf *nautilus_thumbnail_unframe_image (GdkPixbuf *pixbuf);
GdkPixbuf *nautilus_thumbnail_load_image (const char *path,
guint base_size,
guint nominal_size,

View file

@ -1,362 +0,0 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-trash-directory.c: Subclass of NautilusDirectory to implement the
virtual trash directory.
Copyright (C) 1999, 2000 Eazel, 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.
Author: Darin Adler <darin@bentspoon.com>
*/
#include <config.h>
#include "nautilus-trash-directory.h"
#include "nautilus-directory-private.h"
#include "nautilus-trash-monitor.h"
#include <eel/eel-glib-extensions.h>
#include <eel/eel-stock-dialogs.h>
#include <gtk/gtkmain.h>
#include <gtk/gtksignal.h>
#include <glib/gi18n.h>
#include <libgnome/gnome-macros.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <libgnomevfs/gnome-vfs-volume-monitor.h>
struct NautilusTrashDirectoryDetails {
GHashTable *volumes;
};
typedef struct {
NautilusTrashDirectory *trash;
GnomeVFSVolume *volume;
GnomeVFSAsyncHandle *handle;
NautilusDirectory *real_directory;
} TrashVolume;
static void add_volume (NautilusTrashDirectory *trash,
GnomeVFSVolume *volume);
GNOME_CLASS_BOILERPLATE (NautilusTrashDirectory, nautilus_trash_directory,
NautilusMergedDirectory, NAUTILUS_TYPE_MERGED_DIRECTORY)
static void
find_directory_callback (GnomeVFSAsyncHandle *handle,
GList *results,
gpointer callback_data)
{
TrashVolume *trash_volume;
GnomeVFSFindDirectoryResult *result;
char *uri;
NautilusDirectory *directory;
trash_volume = callback_data;
g_assert (eel_g_list_exactly_one_item (results));
g_assert (trash_volume != NULL);
g_assert (NAUTILUS_IS_TRASH_DIRECTORY (trash_volume->trash));
g_assert (trash_volume->real_directory == NULL);
g_assert (trash_volume->handle == handle);
/* We are done with the async. I/O. */
trash_volume->handle = NULL;
/* If we can't find the trash, ignore it silently. */
result = results->data;
if (result->result != GNOME_VFS_OK) {
return;
}
/* If we can't make a directory object, ignore it silently. */
uri = gnome_vfs_uri_to_string (result->uri,
GNOME_VFS_URI_HIDE_NONE);
directory = nautilus_directory_get (uri);
g_free (uri);
if (directory == NULL) {
return;
}
/* Add the directory object. */
trash_volume->real_directory = directory;
nautilus_merged_directory_add_real_directory
(NAUTILUS_MERGED_DIRECTORY (trash_volume->trash),
directory);
}
static gboolean
get_trash_volume (NautilusTrashDirectory *trash,
GnomeVFSVolume *volume,
TrashVolume **trash_volume,
GnomeVFSURI **volume_mount_uri)
{
char *uri_str;
/* Quick out if we already know about this volume. */
*trash_volume = g_hash_table_lookup (trash->details->volumes,
volume);
if (*trash_volume != NULL && (*trash_volume)->real_directory != NULL) {
return FALSE;
}
if (!gnome_vfs_volume_handles_trash (volume)) {
return FALSE;
}
uri_str = gnome_vfs_volume_get_activation_uri (volume);
*volume_mount_uri = gnome_vfs_uri_new (uri_str);
g_free (uri_str);
if (*trash_volume == NULL) {
/* Make the structure used to track the trash for this volume. */
*trash_volume = g_new0 (TrashVolume, 1);
(*trash_volume)->trash = trash;
(*trash_volume)->volume = gnome_vfs_volume_ref (volume);
g_hash_table_insert (trash->details->volumes, volume, *trash_volume);
}
return TRUE;
}
static void
add_volume (NautilusTrashDirectory *trash,
GnomeVFSVolume *volume)
{
TrashVolume *trash_volume;
GnomeVFSURI *volume_mount_uri;
GList vfs_uri_as_list;
if (!get_trash_volume (trash, volume, &trash_volume, &volume_mount_uri)) {
return;
}
if (trash_volume->handle) {
/* Already searching for trash */
gnome_vfs_uri_unref (volume_mount_uri);
return;
}
/* Find the real trash directory for this one. */
vfs_uri_as_list.data = volume_mount_uri;
vfs_uri_as_list.next = NULL;
vfs_uri_as_list.prev = NULL;
/* Search for Trash directories but don't create new ones. */
gnome_vfs_async_find_directory
(&trash_volume->handle, &vfs_uri_as_list,
GNOME_VFS_DIRECTORY_KIND_TRASH, FALSE, TRUE, 0777,
GNOME_VFS_PRIORITY_DEFAULT,
find_directory_callback, trash_volume);
gnome_vfs_uri_unref (volume_mount_uri);
}
static void
check_trash_created (NautilusTrashDirectory *trash,
GnomeVFSVolume *volume)
{
GnomeVFSResult result;
TrashVolume *trash_volume;
GnomeVFSURI *volume_mount_uri;
GnomeVFSURI *trash_uri;
char *uri;
if (!get_trash_volume (trash, volume, &trash_volume, &volume_mount_uri)) {
return;
}
/* Do a synch trash lookup -- if the trash directory was just created, it's location will
* be known and returned immediately without any blocking.
*/
result = gnome_vfs_find_directory (volume_mount_uri, GNOME_VFS_DIRECTORY_KIND_TRASH,
&trash_uri, FALSE, FALSE, 077);
gnome_vfs_uri_unref (volume_mount_uri);
if (result != GNOME_VFS_OK) {
return;
}
uri = gnome_vfs_uri_to_string (trash_uri,
GNOME_VFS_URI_HIDE_NONE);
trash_volume->real_directory = nautilus_directory_get (uri);
g_free (uri);
gnome_vfs_uri_unref (trash_uri);
if (trash_volume->real_directory == NULL) {
return;
}
/* Add the directory object. */
nautilus_merged_directory_add_real_directory
(NAUTILUS_MERGED_DIRECTORY (trash_volume->trash),
trash_volume->real_directory);
}
static void
remove_trash_volume (TrashVolume *trash_volume, gboolean finalizing)
{
g_hash_table_remove (trash_volume->trash->details->volumes,
trash_volume->volume);
if (trash_volume->handle != NULL) {
gnome_vfs_async_cancel (trash_volume->handle);
}
if (trash_volume->real_directory != NULL) {
if (! finalizing) {
nautilus_merged_directory_remove_real_directory
(NAUTILUS_MERGED_DIRECTORY (trash_volume->trash),
trash_volume->real_directory);
}
nautilus_directory_unref (trash_volume->real_directory);
}
gnome_vfs_volume_unref (trash_volume->volume);
g_free (trash_volume);
}
static void
remove_volume (NautilusTrashDirectory *trash,
GnomeVFSVolume *volume)
{
TrashVolume *trash_volume;
/* Quick out if don't already know about this volume. */
trash_volume = g_hash_table_lookup (trash->details->volumes, volume);
if (trash_volume != NULL) {
remove_trash_volume (trash_volume, FALSE);
}
}
static void
check_trash_directory_added_callback (GnomeVFSVolumeMonitor *monitor,
GnomeVFSVolume *volume,
NautilusTrashDirectory *trash)
{
check_trash_created (trash, volume);
}
static void
volume_unmount_started_callback (GnomeVFSVolumeMonitor *monitor,
GnomeVFSVolume *volume,
NautilusTrashDirectory *trash)
{
remove_volume (trash, volume);
}
static void
volume_mounted_callback (GnomeVFSVolumeMonitor *monitor,
GnomeVFSVolume *volume,
NautilusTrashDirectory *trash)
{
add_volume (trash, volume);
}
static void
volume_unmounted_callback (GnomeVFSVolumeMonitor *monitor,
GnomeVFSVolume *volume,
NautilusTrashDirectory *trash)
{
remove_volume (trash, volume);
}
static void
nautilus_trash_directory_instance_init (NautilusTrashDirectory *trash)
{
GnomeVFSVolumeMonitor *volume_monitor;
trash->details = g_new0 (NautilusTrashDirectoryDetails, 1);
trash->details->volumes = g_hash_table_new (NULL, NULL);
volume_monitor = gnome_vfs_get_volume_monitor ();
g_signal_connect_object (volume_monitor, "volume_mounted",
G_CALLBACK (volume_mounted_callback), trash, 0);
g_signal_connect_object (volume_monitor, "volume_pre_unmount",
G_CALLBACK (volume_unmount_started_callback), trash, 0);
g_signal_connect_object (volume_monitor, "volume_unmounted",
G_CALLBACK (volume_unmounted_callback), trash, 0);
}
/* Finish initializing a new NautilusTrashDirectory. We have to do the
* remaining initialization here rather than in nautilus_trash_directory_init
* because of a cyclic dependency between the NautilusTrashDirectory and
* NautilusTrashMonitor instances.
*/
void
nautilus_trash_directory_finish_initializing (NautilusTrashDirectory *trash)
{
GnomeVFSVolumeMonitor *volume_monitor;
GList *volumes, *l;
volume_monitor = gnome_vfs_get_volume_monitor ();
g_signal_connect_object (nautilus_trash_monitor_get (), "check_trash_directory_added",
G_CALLBACK (check_trash_directory_added_callback), trash, 0);
volumes = gnome_vfs_volume_monitor_get_mounted_volumes (volume_monitor);
for (l = volumes; l != NULL; l = l->next) {
add_volume (trash, l->data);
gnome_vfs_volume_unref (l->data);
}
g_list_free (volumes);
}
static void
remove_trash_volume_finalizing_cover (gpointer key, gpointer value, gpointer callback_data)
{
TrashVolume *trash_volume;
g_assert (key != NULL);
g_assert (value != NULL);
g_assert (callback_data == NULL);
trash_volume = value;
g_assert (NAUTILUS_IS_TRASH_DIRECTORY (trash_volume->trash));
g_assert (trash_volume->volume == key);
remove_trash_volume (trash_volume, TRUE);
}
static void
trash_finalize (GObject *object)
{
NautilusTrashDirectory *trash;
trash = NAUTILUS_TRASH_DIRECTORY (object);
eel_g_hash_table_safe_for_each (trash->details->volumes,
remove_trash_volume_finalizing_cover, NULL);
g_hash_table_destroy (trash->details->volumes);
g_free (trash->details);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static char *
trash_get_name_for_self_as_new_file (NautilusDirectory *directory)
{
g_assert (NAUTILUS_IS_TRASH_DIRECTORY (directory));
return g_strdup (_("Trash"));
}
static void
nautilus_trash_directory_class_init (NautilusTrashDirectoryClass *class)
{
G_OBJECT_CLASS (class)->finalize = trash_finalize;
NAUTILUS_DIRECTORY_CLASS (class)->get_name_for_self_as_new_file = trash_get_name_for_self_as_new_file;
}

View file

@ -1,56 +0,0 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-trash-directory.h: Subclass of NautilusDirectory to implement
the virtual trash directory.
Copyright (C) 1999, 2000 Eazel, 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.
Author: Darin Adler <darin@bentspoon.com>
*/
#ifndef NAUTILUS_TRASH_DIRECTORY_H
#define NAUTILUS_TRASH_DIRECTORY_H
#include <libnautilus-private/nautilus-merged-directory.h>
#define NAUTILUS_TYPE_TRASH_DIRECTORY \
(nautilus_trash_directory_get_type ())
#define NAUTILUS_TRASH_DIRECTORY(obj) \
(GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_TRASH_DIRECTORY, NautilusTrashDirectory))
#define NAUTILUS_TRASH_DIRECTORY_CLASS(klass) \
(GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_TRASH_DIRECTORY, NautilusTrashDirectoryClass))
#define NAUTILUS_IS_TRASH_DIRECTORY(obj) \
(GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_TRASH_DIRECTORY))
#define NAUTILUS_IS_TRASH_DIRECTORY_CLASS(klass) \
(GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_TRASH_DIRECTORY))
typedef struct NautilusTrashDirectoryDetails NautilusTrashDirectoryDetails;
typedef struct {
NautilusMergedDirectory parent_slot;
NautilusTrashDirectoryDetails *details;
} NautilusTrashDirectory;
typedef struct {
NautilusMergedDirectoryClass parent_slot;
} NautilusTrashDirectoryClass;
GType nautilus_trash_directory_get_type (void);
void nautilus_trash_directory_finish_initializing (NautilusTrashDirectory *trash);
#endif /* NAUTILUS_TRASH_DIRECTORY_H */

View file

@ -1,784 +0,0 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-trash-file.c: Subclass of NautilusFile to help implement the
virtual trash directory.
Copyright (C) 1999, 2000, 2001 Eazel, 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.
Author: Darin Adler <darin@bentspoon.com>
*/
#include <config.h>
#include "nautilus-trash-file.h"
#include "nautilus-directory-notify.h"
#include "nautilus-directory-private.h"
#include "nautilus-file-attributes.h"
#include "nautilus-file-private.h"
#include "nautilus-file-utilities.h"
#include <eel/eel-glib-extensions.h>
#include <eel/eel-gtk-macros.h>
#include "nautilus-trash-directory.h"
#include <gtk/gtksignal.h>
#include <glib/gi18n.h>
#include <string.h>
struct NautilusTrashFileDetails {
NautilusTrashDirectory *trash_directory;
GList *files;
GHashTable *callbacks;
GHashTable *monitors;
};
typedef struct {
NautilusTrashFile *trash;
NautilusFileCallback callback;
gpointer callback_data;
NautilusFileAttributes delegated_attributes;
NautilusFileAttributes non_delegated_attributes;
GList *non_ready_files;
gboolean initializing;
} TrashCallback;
typedef struct {
NautilusTrashFile *trash;
NautilusFileAttributes delegated_attributes;
NautilusFileAttributes non_delegated_attributes;
} TrashMonitor;
static void nautilus_trash_file_init (gpointer object,
gpointer klass);
static void nautilus_trash_file_class_init (gpointer klass);
EEL_CLASS_BOILERPLATE (NautilusTrashFile,
nautilus_trash_file,
NAUTILUS_TYPE_FILE)
static NautilusFileAttributes
get_delegated_attributes_mask (void)
{
return NAUTILUS_FILE_ATTRIBUTE_DEEP_COUNTS |
NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT |
NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_MIME_TYPES;
}
static void
partition_attributes (NautilusFileAttributes attributes,
NautilusFileAttributes *delegated_attributes,
NautilusFileAttributes *non_delegated_attributes)
{
NautilusFileAttributes mask;
mask = get_delegated_attributes_mask ();
*delegated_attributes = attributes & mask;
*non_delegated_attributes = attributes & ~mask;
}
static void
real_monitor_add (NautilusFile *file,
gconstpointer client,
NautilusFileAttributes attributes)
{
nautilus_directory_monitor_add_internal
(file->details->directory, file,
client, TRUE, TRUE, attributes, NULL, NULL);
}
static void
real_monitor_remove (NautilusFile *file,
gconstpointer client)
{
nautilus_directory_monitor_remove_internal
(file->details->directory, file, client);
}
static void
real_call_when_ready (NautilusFile *file,
NautilusFileAttributes attributes,
NautilusFileCallback callback,
gpointer callback_data)
{
nautilus_directory_call_when_ready_internal
(file->details->directory, file,
attributes, FALSE, NULL, callback, callback_data);
}
static void
real_cancel_call_when_ready (NautilusFile *file,
NautilusFileCallback callback,
gpointer callback_data)
{
nautilus_directory_cancel_callback_internal
(file->details->directory, file,
NULL, callback, callback_data);
}
static gboolean
real_check_if_ready (NautilusFile *file,
NautilusFileAttributes attributes)
{
return nautilus_directory_check_if_ready_internal
(file->details->directory, file,
attributes);
}
static guint
trash_callback_hash (gconstpointer trash_callback_as_pointer)
{
const TrashCallback *trash_callback;
trash_callback = trash_callback_as_pointer;
return GPOINTER_TO_UINT (trash_callback->callback)
^ GPOINTER_TO_UINT (trash_callback->callback_data);
}
static gboolean
trash_callback_equal (gconstpointer trash_callback_as_pointer,
gconstpointer trash_callback_as_pointer_2)
{
const TrashCallback *trash_callback, *trash_callback_2;
trash_callback = trash_callback_as_pointer;
trash_callback_2 = trash_callback_as_pointer_2;
return trash_callback->callback == trash_callback_2->callback
&& trash_callback->callback_data == trash_callback_2->callback_data;
}
static void
trash_callback_destroy (TrashCallback *trash_callback)
{
g_assert (trash_callback != NULL);
g_assert (NAUTILUS_IS_TRASH_FILE (trash_callback->trash));
nautilus_file_unref (NAUTILUS_FILE (trash_callback->trash));
g_list_free (trash_callback->non_ready_files);
g_free (trash_callback);
}
static void
trash_callback_check_done (TrashCallback *trash_callback)
{
/* Check if we are ready. */
if (trash_callback->initializing || trash_callback->non_ready_files != NULL) {
return;
}
/* Remove from the hash table before sending it. */
g_hash_table_remove (trash_callback->trash->details->callbacks,
trash_callback);
/* We are ready, so do the real callback. */
(* trash_callback->callback) (NAUTILUS_FILE (trash_callback->trash),
trash_callback->callback_data);
/* And we are done. */
trash_callback_destroy (trash_callback);
}
static void
trash_callback_remove_file (TrashCallback *trash_callback,
NautilusFile *file)
{
trash_callback->non_ready_files = g_list_remove
(trash_callback->non_ready_files, file);
trash_callback_check_done (trash_callback);
}
static void
ready_callback (NautilusFile *file,
gpointer callback_data)
{
TrashCallback *trash_callback;
g_assert (NAUTILUS_IS_FILE (file));
g_assert (callback_data != NULL);
trash_callback = callback_data;
g_assert (g_list_find (trash_callback->non_ready_files, file) != NULL);
trash_callback_remove_file (trash_callback, file);
}
static void
real_file_changed_callback (NautilusFile *real_file,
gpointer callback_data)
{
NautilusTrashFile *trash_file;
trash_file = NAUTILUS_TRASH_FILE (callback_data);
nautilus_file_changed (NAUTILUS_FILE (trash_file));
}
static void
monitor_add_file (gpointer key,
gpointer value,
gpointer callback_data)
{
TrashMonitor *monitor;
monitor = value;
nautilus_file_monitor_add
(NAUTILUS_FILE (callback_data),
monitor,
monitor->delegated_attributes);
}
static void
add_real_file (NautilusTrashFile *trash,
NautilusFile *real_file)
{
g_return_if_fail (NAUTILUS_IS_TRASH_FILE (trash));
g_return_if_fail (NAUTILUS_IS_FILE (real_file));
g_return_if_fail (!NAUTILUS_IS_TRASH_FILE (real_file));
g_return_if_fail (g_list_find (trash->details->files, real_file) == NULL);
nautilus_file_ref (real_file);
trash->details->files = g_list_prepend
(trash->details->files, real_file);
g_signal_connect_object (real_file, "changed",
G_CALLBACK (real_file_changed_callback), trash, 0);
/* Add the file to any extant monitors. */
g_hash_table_foreach (trash->details->monitors,
monitor_add_file,
real_file);
}
static void
trash_callback_remove_file_cover (gpointer key,
gpointer value,
gpointer callback_data)
{
trash_callback_remove_file
(value, NAUTILUS_FILE (callback_data));
}
static void
monitor_remove_file (gpointer key,
gpointer value,
gpointer callback_data)
{
nautilus_file_monitor_remove
(NAUTILUS_FILE (callback_data), value);
}
static void
remove_real_file (NautilusTrashFile *trash,
NautilusFile *real_file)
{
g_return_if_fail (NAUTILUS_IS_TRASH_FILE (trash));
g_return_if_fail (NAUTILUS_IS_FILE (real_file));
g_return_if_fail (g_list_find (trash->details->files, real_file) != NULL);
eel_g_hash_table_safe_for_each
(trash->details->callbacks,
trash_callback_remove_file_cover,
real_file);
g_hash_table_foreach
(trash->details->monitors,
monitor_remove_file,
real_file);
g_signal_handlers_disconnect_by_func
(real_file, G_CALLBACK (real_file_changed_callback), trash);
trash->details->files = g_list_remove
(trash->details->files, real_file);
nautilus_file_unref (real_file);
}
static void
add_real_file_given_directory (NautilusTrashFile *trash_file,
NautilusDirectory *real_directory)
{
NautilusFile *real_file;
real_file = nautilus_directory_get_corresponding_file (real_directory);
add_real_file (trash_file, real_file);
nautilus_file_unref (real_file);
}
static void
add_directory_callback (NautilusTrashDirectory *trash_directory,
NautilusDirectory *real_directory,
NautilusTrashFile *trash_file)
{
g_assert (NAUTILUS_IS_TRASH_DIRECTORY (trash_directory));
g_assert (NAUTILUS_IS_DIRECTORY (real_directory));
g_assert (!NAUTILUS_IS_MERGED_DIRECTORY (real_directory));
g_assert (NAUTILUS_IS_TRASH_FILE (trash_file));
g_assert (trash_file->details->trash_directory == trash_directory);
add_real_file_given_directory (trash_file, real_directory);
nautilus_file_changed (NAUTILUS_FILE (trash_file));
}
static void
remove_directory_callback (NautilusTrashDirectory *trash_directory,
NautilusDirectory *real_directory,
NautilusTrashFile *trash_file)
{
NautilusFile *real_file;
g_assert (NAUTILUS_IS_TRASH_DIRECTORY (trash_directory));
g_assert (NAUTILUS_IS_DIRECTORY (real_directory));
g_assert (!NAUTILUS_IS_MERGED_DIRECTORY (real_directory));
g_assert (NAUTILUS_IS_TRASH_FILE (trash_file));
g_assert (trash_file->details->trash_directory == trash_directory);
real_file = nautilus_directory_get_corresponding_file (real_directory);
remove_real_file (trash_file, real_file);
nautilus_file_unref (real_file);
nautilus_file_changed (NAUTILUS_FILE (trash_file));
}
static void
trash_file_call_when_ready (NautilusFile *file,
NautilusFileAttributes attributes,
NautilusFileCallback callback,
gpointer callback_data)
{
NautilusTrashFile *trash;
TrashCallback search_key, *trash_callback;
GList *node;
trash = NAUTILUS_TRASH_FILE (file);
/* Check to be sure we aren't overwriting. */
search_key.callback = callback;
search_key.callback_data = callback_data;
if (g_hash_table_lookup (trash->details->callbacks, &search_key) != NULL) {
g_warning ("tried to add a new callback while an old one was pending");
return;
}
/* Create a trash_callback record. */
trash_callback = g_new0 (TrashCallback, 1);
nautilus_file_ref (file);
trash_callback->trash = trash;
trash_callback->callback = callback;
trash_callback->callback_data = callback_data;
trash_callback->initializing = TRUE;
partition_attributes (attributes,
&trash_callback->delegated_attributes,
&trash_callback->non_delegated_attributes);
trash_callback->non_ready_files = g_list_prepend
(trash_callback->non_ready_files, file);
for (node = trash->details->files; node != NULL; node = node->next) {
trash_callback->non_ready_files = g_list_prepend
(trash_callback->non_ready_files, node->data);
}
/* Put it in the hash table. */
g_hash_table_insert (trash->details->callbacks,
trash_callback, trash_callback);
/* Now connect to each file's call_when_ready. */
real_call_when_ready
(file, trash_callback->non_delegated_attributes,
ready_callback, trash_callback);
for (node = trash->details->files; node != NULL; node = node->next) {
nautilus_file_call_when_ready
(node->data, trash_callback->delegated_attributes,
ready_callback, trash_callback);
}
trash_callback->initializing = FALSE;
/* Check if any files became read while we were connecting up
* the call_when_ready callbacks (also handles the pathological
* case where there are no files at all).
*/
trash_callback_check_done (trash_callback);
}
static void
trash_file_cancel_call_when_ready (NautilusFile *file,
NautilusFileCallback callback,
gpointer callback_data)
{
NautilusTrashFile *trash;
TrashCallback search_key, *trash_callback;
GList *node;
trash = NAUTILUS_TRASH_FILE (file);
/* Find the entry in the table. */
search_key.callback = callback;
search_key.callback_data = callback_data;
trash_callback = g_hash_table_lookup (trash->details->callbacks, &search_key);
if (trash_callback == NULL) {
return;
}
/* Remove from the hash table before working with it. */
g_hash_table_remove (trash_callback->trash->details->callbacks, trash_callback);
/* Tell all the directories to cancel the call. */
real_cancel_call_when_ready (file, ready_callback, trash_callback);
for (node = trash_callback->non_ready_files; node != NULL; node = node->next) {
nautilus_file_cancel_call_when_ready
(node->data, ready_callback, trash_callback);
}
trash_callback_destroy (trash_callback);
}
static gboolean
trash_file_check_if_ready (NautilusFile *file,
NautilusFileAttributes attributes)
{
NautilusFileAttributes delegated_attributes, non_delegated_attributes;
NautilusTrashFile *trash;
GList *node;
gboolean ready;
trash = NAUTILUS_TRASH_FILE (file);
partition_attributes (attributes,
&delegated_attributes,
&non_delegated_attributes);
ready = real_check_if_ready (file, non_delegated_attributes);
if (ready) {
for (node = trash->details->files; node != NULL; node = node->next) {
if (!nautilus_file_check_if_ready (node->data,
delegated_attributes)) {
ready = FALSE;
break;
}
}
}
return ready;
}
static void
trash_file_monitor_add (NautilusFile *file,
gconstpointer client,
NautilusFileAttributes attributes)
{
NautilusTrashFile *trash;
TrashMonitor *monitor;
GList *node;
trash = NAUTILUS_TRASH_FILE (file);
/* Map the client to a unique value so this doesn't interfere
* with direct monitoring of the file by the same client.
*/
monitor = g_hash_table_lookup (trash->details->monitors, client);
if (monitor != NULL) {
g_assert (monitor->trash == trash);
} else {
monitor = g_new0 (TrashMonitor, 1);
monitor->trash = trash;
g_hash_table_insert (trash->details->monitors,
(gpointer) client, monitor);
}
partition_attributes (attributes,
&monitor->delegated_attributes,
&monitor->non_delegated_attributes);
real_monitor_add (file, monitor,
monitor->non_delegated_attributes);
for (node = trash->details->files; node != NULL; node = node->next) {
nautilus_file_monitor_add (node->data, monitor,
monitor->delegated_attributes);
}
}
static void
trash_file_monitor_remove (NautilusFile *file,
gconstpointer client)
{
NautilusTrashFile *trash;
TrashMonitor *monitor;
GList *node;
trash = NAUTILUS_TRASH_FILE (file);
/* Map the client to the value used by the earlier add call. */
monitor = g_hash_table_lookup (trash->details->monitors, client);
if (monitor == NULL) {
return;
}
g_hash_table_remove (trash->details->monitors, client);
/* Call through to the real file remove calls. */
real_monitor_remove (file, monitor);
for (node = trash->details->files; node != NULL; node = node->next) {
nautilus_file_monitor_remove (node->data, monitor);
}
g_free (monitor);
}
static GnomeVFSFileType
trash_file_get_file_type (NautilusFile *file)
{
return GNOME_VFS_FILE_TYPE_DIRECTORY;
}
static gboolean
trash_file_get_item_count (NautilusFile *file,
guint *count,
gboolean *count_unreadable)
{
NautilusTrashFile *trash;
GList *node;
guint one_count;
int one_unreadable;
gboolean got_count;
trash = NAUTILUS_TRASH_FILE (file);
got_count = TRUE;
if (count != NULL) {
*count = 0;
}
if (count_unreadable != NULL) {
*count_unreadable = FALSE;
}
for (node = trash->details->files; node != NULL; node = node->next) {
if (!nautilus_file_get_directory_item_count (node->data,
&one_count,
&one_unreadable)) {
got_count = FALSE;
}
if (count != NULL) {
*count += one_count;
}
if (count_unreadable != NULL && one_unreadable) {
*count_unreadable = TRUE;
}
}
return got_count;
}
static NautilusRequestStatus
trash_file_get_deep_counts (NautilusFile *file,
guint *directory_count,
guint *file_count,
guint *unreadable_directory_count,
GnomeVFSFileSize *total_size)
{
NautilusTrashFile *trash;
GList *node;
NautilusRequestStatus status, one_status;
guint one_directory_count, one_file_count, one_unreadable_directory_count;
GnomeVFSFileSize one_total_size;
trash = NAUTILUS_TRASH_FILE (file);
status = NAUTILUS_REQUEST_DONE;
if (directory_count != NULL) {
*directory_count = 0;
}
if (file_count != NULL) {
*file_count = 0;
}
if (unreadable_directory_count != NULL) {
*unreadable_directory_count = 0;
}
if (total_size != NULL) {
*total_size = 0;
}
for (node = trash->details->files; node != NULL; node = node->next) {
one_status = nautilus_file_get_deep_counts
(node->data,
&one_directory_count,
&one_file_count,
&one_unreadable_directory_count,
&one_total_size,
TRUE);
if (one_status < status) {
status = one_status;
}
if (directory_count != NULL) {
*directory_count += one_directory_count;
}
if (file_count != NULL) {
*file_count += one_file_count;
}
if (unreadable_directory_count != NULL) {
*unreadable_directory_count += one_unreadable_directory_count;
}
if (total_size != NULL) {
*total_size += one_total_size;
}
}
return status;
}
static gboolean
trash_file_get_date (NautilusFile *file,
NautilusDateType date_type,
time_t *date)
{
NautilusTrashFile *trash;
GList *node;
gboolean got_at_least_one;
gboolean got_all;
time_t one_date;
trash = NAUTILUS_TRASH_FILE (file);
got_at_least_one = FALSE;
got_all = TRUE;
for (node = trash->details->files; node != NULL; node = node->next) {
if (nautilus_file_get_date (node->data,
date_type,
&one_date)) {
if (!got_at_least_one) {
got_at_least_one = TRUE;
if (date != NULL) {
*date = one_date;
}
} else {
if (date != NULL && one_date > *date) {
*date = one_date;
}
}
} else {
got_all = FALSE;
}
}
return got_at_least_one && got_all;
}
static char *
trash_file_get_where_string (NautilusFile *file)
{
return g_strdup (_("on the desktop"));
}
static void
remove_all_real_files (NautilusTrashFile *trash)
{
while (trash->details->files != NULL) {
remove_real_file (trash, trash->details->files->data);
}
}
static void
nautilus_trash_file_init (gpointer object, gpointer klass)
{
NautilusTrashFile *trash_file;
NautilusTrashDirectory *trash_directory;
GList *real_directories, *node;
trash_file = NAUTILUS_TRASH_FILE (object);
trash_directory = NAUTILUS_TRASH_DIRECTORY (nautilus_directory_get (EEL_TRASH_URI));
trash_file->details = g_new0 (NautilusTrashFileDetails, 1);
trash_file->details->trash_directory = trash_directory;
trash_file->details->callbacks = g_hash_table_new
(trash_callback_hash, trash_callback_equal);
trash_file->details->monitors = g_hash_table_new (NULL, NULL);
g_signal_connect_object (trash_directory, "add_real_directory",
G_CALLBACK (add_directory_callback), trash_file, 0);
g_signal_connect_object (trash_directory, "remove_real_directory",
G_CALLBACK (remove_directory_callback), trash_file, 0);
real_directories = nautilus_merged_directory_get_real_directories
(NAUTILUS_MERGED_DIRECTORY (trash_directory));
for (node = real_directories; node != NULL; node = node->next) {
add_real_file_given_directory (trash_file, node->data);
}
g_list_free (real_directories);
}
static void
trash_finalize (GObject *object)
{
NautilusTrashFile *trash_file;
NautilusTrashDirectory *trash_directory;
trash_file = NAUTILUS_TRASH_FILE (object);
trash_directory = trash_file->details->trash_directory;
remove_all_real_files (trash_file);
if (g_hash_table_size (trash_file->details->callbacks) != 0) {
g_warning ("call_when_ready still pending when trash virtual file is destroyed");
}
if (g_hash_table_size (trash_file->details->monitors) != 0) {
g_warning ("file monitor still active when trash virtual file is destroyed");
}
g_hash_table_destroy (trash_file->details->callbacks);
g_hash_table_destroy (trash_file->details->monitors);
g_free (trash_file->details);
nautilus_directory_unref (NAUTILUS_DIRECTORY (trash_directory));
EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
}
static void
nautilus_trash_file_class_init (gpointer klass)
{
GObjectClass *object_class;
NautilusFileClass *file_class;
object_class = G_OBJECT_CLASS (klass);
file_class = NAUTILUS_FILE_CLASS (klass);
object_class->finalize = trash_finalize;
file_class->monitor_add = trash_file_monitor_add;
file_class->monitor_remove = trash_file_monitor_remove;
file_class->call_when_ready = trash_file_call_when_ready;
file_class->cancel_call_when_ready = trash_file_cancel_call_when_ready;
file_class->check_if_ready = trash_file_check_if_ready;
file_class->get_file_type = trash_file_get_file_type;
file_class->get_item_count = trash_file_get_item_count;
file_class->get_deep_counts = trash_file_get_deep_counts;
file_class->get_date = trash_file_get_date;
file_class->get_where_string = trash_file_get_where_string;
}

View file

@ -1,55 +0,0 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-trash-file.h: Subclass of NautilusFile to implement the
the case of a TRASH file.
Copyright (C) 1999, 2000 Eazel, 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.
Author: Darin Adler <darin@bentspoon.com>
*/
#ifndef NAUTILUS_TRASH_FILE_H
#define NAUTILUS_TRASH_FILE_H
#include <libnautilus-private/nautilus-file.h>
#define NAUTILUS_TYPE_TRASH_FILE \
(nautilus_trash_file_get_type ())
#define NAUTILUS_TRASH_FILE(obj) \
(GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_TRASH_FILE, NautilusTrashFile))
#define NAUTILUS_TRASH_FILE_CLASS(klass) \
(GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_TRASH_FILE, NautilusTrashFileClass))
#define NAUTILUS_IS_TRASH_FILE(obj) \
(GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_TRASH_FILE))
#define NAUTILUS_IS_TRASH_FILE_CLASS(klass) \
(GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_TRASH_FILE))
typedef struct NautilusTrashFileDetails NautilusTrashFileDetails;
typedef struct {
NautilusFile parent_slot;
NautilusTrashFileDetails *details;
} NautilusTrashFile;
typedef struct {
NautilusFileClass parent_slot;
} NautilusTrashFileClass;
GType nautilus_trash_file_get_type (void);
#endif /* NAUTILUS_TRASH_FILE_H */

View file

@ -29,46 +29,52 @@
#include "nautilus-directory-notify.h"
#include "nautilus-directory.h"
#include "nautilus-file-attributes.h"
#include "nautilus-trash-directory.h"
#include <eel/eel-debug.h>
#include <eel/eel-gtk-macros.h>
#include <eel/eel-vfs-extensions.h>
#include <gtk/gtksignal.h>
#include <libgnomevfs/gnome-vfs-find-directory.h>
#include <libgnomevfs/gnome-vfs-types.h>
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <libgnomevfs/gnome-vfs-volume-monitor.h>
#include <gio/gthemedicon.h>
#include <gio/gfilemonitor.h>
#include <string.h>
struct NautilusTrashMonitorDetails {
NautilusDirectory *trash_directory;
gboolean empty;
GIcon *icon;
GFileMonitor *file_monitor;
};
enum {
TRASH_STATE_CHANGED,
CHECK_TRASH_DIRECTORY_ADDED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
static NautilusTrashMonitor *nautilus_trash_monitor;
static NautilusTrashMonitor *nautilus_trash_monitor = NULL;
static void nautilus_trash_monitor_class_init (NautilusTrashMonitorClass *klass);
static void nautilus_trash_monitor_init (gpointer object,
gpointer klass);
static void destroy (GtkObject *object);
G_DEFINE_TYPE(NautilusTrashMonitor, nautilus_trash_monitor, G_TYPE_OBJECT)
EEL_CLASS_BOILERPLATE (NautilusTrashMonitor, nautilus_trash_monitor, GTK_TYPE_OBJECT)
static void
nautilus_trash_monitor_finalize (GObject *object)
{
NautilusTrashMonitor *trash_monitor;
trash_monitor = NAUTILUS_TRASH_MONITOR (object);
if (trash_monitor->details->icon) {
g_object_unref (trash_monitor->details->icon);
}
if (trash_monitor->details->file_monitor) {
g_object_unref (trash_monitor->details->file_monitor);
}
G_OBJECT_CLASS (nautilus_trash_monitor_parent_class)->finalize (object);
}
static void
nautilus_trash_monitor_class_init (NautilusTrashMonitorClass *klass)
{
GtkObjectClass *object_class;
GObjectClass *object_class;
object_class = GTK_OBJECT_CLASS (klass);
object_class = G_OBJECT_CLASS (klass);
object_class->destroy = destroy;
object_class->finalize = nautilus_trash_monitor_finalize;
signals[TRASH_STATE_CHANGED] = g_signal_new
("trash_state_changed",
@ -80,89 +86,105 @@ nautilus_trash_monitor_class_init (NautilusTrashMonitorClass *klass)
G_TYPE_NONE, 1,
G_TYPE_BOOLEAN);
signals[CHECK_TRASH_DIRECTORY_ADDED] = g_signal_new
("check_trash_directory_added",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (NautilusTrashMonitorClass, check_trash_directory_added),
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1,
G_TYPE_POINTER);
g_type_class_add_private (object_class, sizeof(NautilusTrashMonitorDetails));
}
static void
nautilus_trash_files_changed_callback (NautilusDirectory *directory, GList *files,
gpointer callback_data)
update_info_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
NautilusTrashMonitor *trash_monitor;
gboolean old_empty_state;
NautilusFile *file;
GFileInfo *info;
GIcon *icon;
const char * const *names;
gboolean empty;
int i;
trash_monitor = NAUTILUS_TRASH_MONITOR (user_data);
trash_monitor = callback_data;
g_assert (NAUTILUS_IS_TRASH_MONITOR (trash_monitor));
g_assert (trash_monitor->details->trash_directory == directory);
info = g_file_query_info_finish (G_FILE (source_object),
res, NULL);
/* Something about the Trash NautilusDirectory changed, find out if
* it affected the empty state.
*/
old_empty_state = trash_monitor->details->empty;
trash_monitor->details->empty = !nautilus_directory_is_not_empty (directory);
if (info != NULL) {
icon = g_file_info_get_icon (info);
if (old_empty_state != trash_monitor->details->empty) {
file = nautilus_file_get (EEL_TRASH_URI);
nautilus_file_changed (file);
nautilus_file_unref (file);
if (icon) {
g_object_unref (trash_monitor->details->icon);
trash_monitor->details->icon = g_object_ref (icon);
empty = TRUE;
if (G_IS_THEMED_ICON (icon)) {
names = g_themed_icon_get_names (G_THEMED_ICON (icon));
for (i = 0; names[i] != NULL; i++) {
if (strcmp (names[i], "user-trash-full") == 0) {
empty = FALSE;
break;
}
}
}
trash_monitor->details->empty = empty;
/* trash got empty or full, notify everyone who cares */
g_signal_emit (trash_monitor,
signals[TRASH_STATE_CHANGED], 0,
trash_monitor->details->empty);
/* trash got empty or full, notify everyone who cares */
g_signal_emit (trash_monitor,
signals[TRASH_STATE_CHANGED], 0,
trash_monitor->details->empty);
}
}
g_object_unref (trash_monitor);
}
static void
nautilus_trash_monitor_init (gpointer object, gpointer klass)
schedule_update_info (NautilusTrashMonitor *trash_monitor)
{
GFile *location;
location = g_file_new_for_uri ("trash:///");
g_file_query_info_async (location,
G_FILE_ATTRIBUTE_STD_ICON,
0, 0, NULL,
update_info_cb, g_object_ref (trash_monitor));
g_object_unref (location);
}
static void
file_changed (GDirectoryMonitor* monitor,
GFile *child,
GFile *other_file,
GFileMonitorEvent event_type,
gpointer user_data)
{
NautilusDirectory *trash_directory;
NautilusTrashMonitor *trash_monitor;
NautilusFileAttributes attributes;
trash_monitor = NAUTILUS_TRASH_MONITOR (object);
trash_monitor = NAUTILUS_TRASH_MONITOR (user_data);
/* set up a NautilusDirectory for the Trash directory to monitor */
schedule_update_info (trash_monitor);
}
trash_directory = nautilus_directory_get (EEL_TRASH_URI);
static void
nautilus_trash_monitor_init (NautilusTrashMonitor *trash_monitor)
{
GFile *location;
trash_monitor->details = G_TYPE_INSTANCE_GET_PRIVATE (trash_monitor,
NAUTILUS_TYPE_TRASH_MONITOR,
NautilusTrashMonitorDetails);
trash_monitor->details = g_new0 (NautilusTrashMonitorDetails, 1);
trash_monitor->details->trash_directory = trash_directory;
trash_monitor->details->empty = TRUE;
trash_monitor->details->icon = g_themed_icon_new ("user-trash");
attributes = NAUTILUS_FILE_ATTRIBUTE_METADATA;
location = g_file_new_for_uri ("trash:///");
/* Make sure we get notified about changes */
nautilus_directory_file_monitor_add
(trash_directory, trash_monitor, TRUE, TRUE, attributes,
nautilus_trash_files_changed_callback, trash_monitor);
trash_monitor->details->file_monitor = g_file_monitor_file (location, 0, NULL);
g_signal_connect_object (trash_directory, "files_added",
G_CALLBACK (nautilus_trash_files_changed_callback), trash_monitor, 0);
g_signal_connect_object (trash_directory, "files_changed",
G_CALLBACK (nautilus_trash_files_changed_callback), trash_monitor, 0);
}
g_signal_connect (trash_monitor->details->file_monitor, "changed",
(GCallback)file_changed, trash_monitor);
static void
destroy (GtkObject *object)
{
NautilusTrashMonitor *trash_monitor;
g_object_unref (location);
trash_monitor = NAUTILUS_TRASH_MONITOR (object);
nautilus_directory_file_monitor_remove
(trash_monitor->details->trash_directory,
trash_monitor);
nautilus_directory_unref (trash_monitor->details->trash_directory);
g_free (trash_monitor->details);
schedule_update_info (trash_monitor);
}
static void
@ -174,25 +196,12 @@ unref_trash_monitor (void)
NautilusTrashMonitor *
nautilus_trash_monitor_get (void)
{
NautilusDirectory *trash_directory;
if (nautilus_trash_monitor == NULL) {
/* not running yet, start it up */
/* the trash directory object will get created by this */
trash_directory = nautilus_directory_get (EEL_TRASH_URI);
nautilus_trash_monitor = NAUTILUS_TRASH_MONITOR
(g_object_new (NAUTILUS_TYPE_TRASH_MONITOR, NULL));
g_object_ref (nautilus_trash_monitor);
gtk_object_sink (GTK_OBJECT (nautilus_trash_monitor));
eel_debug_call_at_shutdown (unref_trash_monitor);
/* make sure we get signalled when trash directories get added */
nautilus_trash_directory_finish_initializing
(NAUTILUS_TRASH_DIRECTORY (trash_directory));
nautilus_directory_unref (trash_directory);
}
return nautilus_trash_monitor;
@ -201,76 +210,26 @@ nautilus_trash_monitor_get (void)
gboolean
nautilus_trash_monitor_is_empty (void)
{
return nautilus_trash_monitor_get ()->details->empty;
NautilusTrashMonitor *monitor;
monitor = nautilus_trash_monitor_get ();
return monitor->details->empty;
}
GList *
nautilus_trash_monitor_get_trash_directories (void)
GIcon *
nautilus_trash_monitor_get_icon (void)
{
GList *result;
char *uri_str;
GnomeVFSURI *volume_mount_point_uri;
GnomeVFSURI *trash_uri;
GnomeVFSVolume *volume;
GList *l, *volumes;
NautilusTrashMonitor *monitor;
result = NULL;
/* Collect the trash directories on all the mounted volumes. */
volumes = gnome_vfs_volume_monitor_get_mounted_volumes (gnome_vfs_get_volume_monitor ());
for (l = volumes; l != NULL; l = l->next) {
volume = l->data;
if (gnome_vfs_volume_handles_trash (volume)) {
/* Get the uri of the volume mount point as the place
* "near" which to look for trash on the given volume.
*/
uri_str = gnome_vfs_volume_get_activation_uri (volume);
volume_mount_point_uri = gnome_vfs_uri_new (uri_str);
g_free (uri_str);
g_assert (volume_mount_point_uri != NULL);
/* Look for trash. It is OK to use a sync call here because
* the options we use (don't create, don't look for it if we
* already don't know where it is) do not cause any IO.
*/
if (gnome_vfs_find_directory (volume_mount_point_uri,
GNOME_VFS_DIRECTORY_KIND_TRASH, &trash_uri,
FALSE, FALSE, 0777) == GNOME_VFS_OK) {
/* found trash, put it on the list */
result = g_list_prepend (result, trash_uri);
}
gnome_vfs_uri_unref (volume_mount_point_uri);
}
gnome_vfs_volume_unref (volume);
monitor = nautilus_trash_monitor_get ();
if (monitor->details->icon) {
return g_object_ref (monitor->details->icon);
}
g_list_free (volumes);
return result;
return NULL;
}
void
void
nautilus_trash_monitor_add_new_trash_directories (void)
{
NautilusTrashMonitor *trash_monitor;
GList *l, *volumes;
GnomeVFSVolume *volume;
trash_monitor = nautilus_trash_monitor_get ();
volumes = gnome_vfs_volume_monitor_get_mounted_volumes (gnome_vfs_get_volume_monitor ());
for (l = volumes; l != NULL; l = l->next) {
volume = l->data;
g_signal_emit (trash_monitor,
signals[CHECK_TRASH_DIRECTORY_ADDED], 0,
volume);
gnome_vfs_volume_unref (volume);
}
g_list_free (volumes);
/* We trashed something... */
}

View file

@ -27,7 +27,7 @@
#define NAUTILUS_TRASH_MONITOR_H
#include <gtk/gtkobject.h>
#include <libgnomevfs/gnome-vfs-volume.h>
#include <gio/gicon.h>
typedef struct NautilusTrashMonitor NautilusTrashMonitor;
typedef struct NautilusTrashMonitorClass NautilusTrashMonitorClass;
@ -45,24 +45,23 @@ typedef struct NautilusTrashMonitorDetails NautilusTrashMonitorDetails;
(GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_TRASH_MONITOR))
struct NautilusTrashMonitor {
GtkObject object;
GObject object;
NautilusTrashMonitorDetails *details;
};
struct NautilusTrashMonitorClass {
GtkObjectClass parent_class;
GObjectClass parent_class;
void (* trash_state_changed) (NautilusTrashMonitor *trash_monitor,
gboolean new_state);
void (* check_trash_directory_added) (NautilusTrashMonitor *trash_monitor,
GnomeVFSVolume *volume);
};
GtkType nautilus_trash_monitor_get_type (void);
NautilusTrashMonitor *nautilus_trash_monitor_get (void);
gboolean nautilus_trash_monitor_is_empty (void);
GList * nautilus_trash_monitor_get_trash_directories (void);
void nautilus_trash_monitor_add_new_trash_directories (void);
GIcon *nautilus_trash_monitor_get_icon (void);
void nautilus_trash_monitor_add_new_trash_directories (void);
#endif

Some files were not shown because too many files have changed in this diff Show more