mirror of
https://gitlab.gnome.org/GNOME/nautilus
synced 2024-10-02 14:03:39 +00:00
Merge gio-branch
svn path=/trunk/; revision=13464
This commit is contained in:
parent
ce669bd18c
commit
469047a2a5
2
NEWS
2
NEWS
|
@ -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
16
TODO-gio
Normal 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.
|
||||
|
||||
|
12
configure.in
12
configure.in
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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:
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
@ -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 *.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
@ -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 */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
@ -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 */
|
||||
|
666
libnautilus-private/nautilus-icon-info.c
Normal file
666
libnautilus-private/nautilus-icon-info.c
Normal 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 */
|
||||
}
|
90
libnautilus-private/nautilus-icon-info.h
Normal file
90
libnautilus-private/nautilus-icon-info.h
Normal 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 */
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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 */
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
@ -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 */
|
||||
|
|
676
libnautilus-private/nautilus-mime-application-chooser.c
Normal file
676
libnautilus-private/nautilus-mime-application-chooser.c
Normal 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;
|
||||
}
|
53
libnautilus-private/nautilus-mime-application-chooser.h
Normal file
53
libnautilus-private/nautilus-mime-application-chooser.h
Normal 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 */
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
982
libnautilus-private/nautilus-open-with-dialog.c
Normal file
982
libnautilus-private/nautilus-open-with-dialog.c
Normal 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;
|
||||
}
|
61
libnautilus-private/nautilus-open-with-dialog.h
Normal file
61
libnautilus-private/nautilus-open-with-dialog.h
Normal 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 */
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
752
libnautilus-private/nautilus-progress-info.c
Normal file
752
libnautilus-private/nautilus-progress-info.c
Normal 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);
|
||||
}
|
80
libnautilus-private/nautilus-progress-info.h
Normal file
80
libnautilus-private/nautilus-progress-info.h
Normal 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 */
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ())
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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... */
|
||||
}
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue