1999-02-16 Federico Mena Quintero <federico@nuclecu.unam.mx>
* gicon.c: Lots of changes to support the little symlink/stalled icons that get overlaid on the normal file icons. We now have the concept of an icon set, which is a cache of normal icons plus their overlaid versions. * gnome-file-property-dialog.c (apply_metadata_change): Use gicon_get_filename_for_icon(). (generate_icon_sel): Likewise. * gnome-file-property-dialog.c (create_general_properties): Use buffers of size MC_MAXPATHLEN. (init_metadata): Likewise.
Этот коммит содержится в:
родитель
88a4da3fe3
Коммит
c52fde6398
@ -1,3 +1,18 @@
|
||||
1999-02-16 Federico Mena Quintero <federico@nuclecu.unam.mx>
|
||||
|
||||
* gicon.c: Lots of changes to support the little symlink/stalled
|
||||
icons that get overlaid on the normal file icons. We now have the
|
||||
concept of an icon set, which is a cache of normal icons plus
|
||||
their overlaid versions.
|
||||
|
||||
* gnome-file-property-dialog.c (apply_metadata_change): Use
|
||||
gicon_get_filename_for_icon().
|
||||
(generate_icon_sel): Likewise.
|
||||
|
||||
* gnome-file-property-dialog.c (create_general_properties): Use
|
||||
buffers of size MC_MAXPATHLEN.
|
||||
(init_metadata): Likewise.
|
||||
|
||||
1999-02-16 Federico Mena Quintero <federico@nuclecu.unam.mx>
|
||||
|
||||
* gmetadata.c: Removed the gmeta_del_icon_pos() function, since it
|
||||
@ -403,7 +418,7 @@ Sun Feb 7 05:29:17 1999 Timur Bakeyev <mc@bat.ru>
|
||||
|
||||
* gdesktop.c: Init gicon here to avoid crashing when we have the
|
||||
metadata database locked. Not really important, but makes the
|
||||
code cleaner (in terms of fixes).
|
||||
code cleaner (in terms of fixes).
|
||||
|
||||
1999-01-27 Miguel de Icaza <miguel@nuclecu.unam.mx>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Desktop management for the Midnight Commander
|
||||
*
|
||||
* Copyright (C) 1998 The Free Software Foundation
|
||||
* Copyright (C) 1998-1999 The Free Software Foundation
|
||||
*
|
||||
* Authors: Federico Mena <federico@nuclecu.unam.mx>
|
||||
* Miguel de Icaza <miguel@nuclecu.unam.mx>
|
||||
@ -406,7 +406,7 @@ reload_desktop_icons (int user_pos, int xpos, int ypos)
|
||||
|
||||
full_name = g_concat_dir_and_file (desktop_directory, dirent->d_name);
|
||||
fe = file_entry_from_file (full_name);
|
||||
im = gicon_get_icon_for_file_speed (desktop_directory, fe, FALSE);
|
||||
im = gicon_get_icon_for_file (desktop_directory, fe, FALSE);
|
||||
file_entry_free (fe);
|
||||
g_free (full_name);
|
||||
|
||||
@ -1435,7 +1435,7 @@ desktop_icon_info_new (char *filename, char *url, char *caption, int xpos, int y
|
||||
caption = filename;
|
||||
}
|
||||
|
||||
icon_im = gicon_get_icon_for_file_speed (desktop_directory, fe, FALSE);
|
||||
icon_im = gicon_get_icon_for_file (desktop_directory, fe, FALSE);
|
||||
dii->dicon = desktop_icon_new (icon_im, caption);
|
||||
dii->filename = g_strdup (filename);
|
||||
dii->selected = FALSE;
|
||||
|
646
gnome/gicon.c
646
gnome/gicon.c
@ -1,353 +1,451 @@
|
||||
/*
|
||||
* Icon loading support for the Midnight Commander
|
||||
/* Icon loading support for the Midnight Commander
|
||||
*
|
||||
* Author:
|
||||
* Miguel de Icaza (miguel@gnu.org)
|
||||
* Copyright (C) 1998-1999 The Free Software Foundation
|
||||
*
|
||||
* Authors: Miguel de Icaza <miguel@nuclecu.unam.mx>
|
||||
* Federico Mena <federico@nuclecu.unam.mx>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include "dir.h"
|
||||
#include "util.h"
|
||||
#include "dialog.h"
|
||||
|
||||
|
||||
#include <gnome.h>
|
||||
#include "gicon.h"
|
||||
|
||||
static GHashTable *icon_hash;
|
||||
static int gicon_inited = FALSE;
|
||||
|
||||
/* These are some default images used in the Icon View */
|
||||
static GdkImlibImage *icon_view_directory;
|
||||
static GdkImlibImage *icon_view_dirclosed;
|
||||
static GdkImlibImage *icon_view_executable;
|
||||
static GdkImlibImage *icon_view_symlink;
|
||||
static GdkImlibImage *icon_view_regular;
|
||||
static GdkImlibImage *icon_view_core;
|
||||
static GdkImlibImage *icon_view_sock;
|
||||
static GdkImlibImage *icon_view_fifo;
|
||||
static GdkImlibImage *icon_view_char_dev;
|
||||
static GdkImlibImage *icon_view_block_dev;
|
||||
static GdkImlibImage *icon_view_stalled;
|
||||
/* What kinds of images can an icon set contain */
|
||||
typedef enum {
|
||||
ICON_TYPE_PLAIN,
|
||||
ICON_TYPE_SYMLINK,
|
||||
ICON_TYPE_STALLED
|
||||
} IconType;
|
||||
|
||||
/* Our UID and GID */
|
||||
/* Information for an icon set (plain icon plus overlayed versions) */
|
||||
typedef struct {
|
||||
GdkImlibImage *plain; /* Plain version */
|
||||
GdkImlibImage *symlink; /* Symlink version */
|
||||
GdkImlibImage *stalled; /* Stalled symlink version */
|
||||
char *filename; /* Filename for the plain image */
|
||||
} IconSet;
|
||||
|
||||
static int gicon_inited; /* Has the icon system been inited? */
|
||||
|
||||
static GHashTable *name_hash; /* Hash from filename -> IconSet */
|
||||
static GHashTable *image_hash; /* Hash from imlib image -> IconSet */
|
||||
|
||||
static GdkImlibImage *symlink_overlay; /* The little symlink overlay */
|
||||
static GdkImlibImage *stalled_overlay; /* The little stalled symlink overlay */
|
||||
|
||||
/* Default icons, guaranteed to exist */
|
||||
static IconSet *iset_directory;
|
||||
static IconSet *iset_dirclosed;
|
||||
static IconSet *iset_executable;
|
||||
static IconSet *iset_regular;
|
||||
static IconSet *iset_core;
|
||||
static IconSet *iset_sock;
|
||||
static IconSet *iset_fifo;
|
||||
static IconSet *iset_chardev;
|
||||
static IconSet *iset_blockdev;
|
||||
|
||||
/* Our UID and GID, needed to see if the user can access some files */
|
||||
static uid_t our_uid;
|
||||
static gid_t our_gid;
|
||||
|
||||
/*
|
||||
* If true, we choose the icon in a way that might be a bit slow
|
||||
*/
|
||||
|
||||
/* Whether we should always use (expensive) metadata lookups for file panels or not */
|
||||
int we_can_afford_the_speed = 0;
|
||||
|
||||
/**
|
||||
* gicon_init:
|
||||
*
|
||||
* Initializes the hash tables for the icons used in the IconList
|
||||
* view
|
||||
*/
|
||||
void
|
||||
gicon_init (void)
|
||||
{
|
||||
g_assert (gicon_inited == FALSE);
|
||||
|
||||
icon_hash = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
gicon_inited = TRUE;
|
||||
|
||||
our_uid = getuid ();
|
||||
our_gid = getgid ();
|
||||
|
||||
/* Recursive call to load the stock images */
|
||||
icon_view_directory = gicon_stock_load ("i-directory.png");
|
||||
icon_view_dirclosed = gicon_stock_load ("i-dirclosed.png");
|
||||
icon_view_executable = gicon_stock_load ("i-executable.png");
|
||||
icon_view_symlink = gicon_stock_load ("i-symlink.png");
|
||||
icon_view_regular = gicon_stock_load ("i-regular.png");
|
||||
icon_view_core = gicon_stock_load ("i-core.png");
|
||||
icon_view_sock = gicon_stock_load ("i-sock.png");
|
||||
icon_view_fifo = gicon_stock_load ("i-fifo.png");
|
||||
icon_view_char_dev = gicon_stock_load ("i-chardev.png");
|
||||
icon_view_block_dev = gicon_stock_load ("i-blockdev.png");
|
||||
icon_view_stalled = gicon_stock_load ("i-stalled.png");
|
||||
|
||||
if (icon_view_directory == NULL ||
|
||||
icon_view_dirclosed == NULL ||
|
||||
icon_view_executable == NULL ||
|
||||
icon_view_symlink == NULL ||
|
||||
icon_view_regular == NULL ||
|
||||
icon_view_core == NULL ||
|
||||
icon_view_sock == NULL ||
|
||||
icon_view_fifo == NULL ||
|
||||
icon_view_char_dev == NULL ||
|
||||
icon_view_block_dev == NULL ||
|
||||
icon_view_stalled == NULL){
|
||||
message (1, _("Error"), _("Default set of icons not found, check your installation"));
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gicon_get_by_filename:
|
||||
*
|
||||
* Fetches an icon given an absolute pathname
|
||||
*/
|
||||
GdkImlibImage *
|
||||
gicon_get_by_filename (char *fname)
|
||||
{
|
||||
GdkImlibImage *icon;
|
||||
|
||||
g_return_val_if_fail (fname != NULL, NULL);
|
||||
|
||||
if (!gicon_inited)
|
||||
gicon_init ();
|
||||
|
||||
icon = g_hash_table_lookup (icon_hash, fname);
|
||||
|
||||
if (icon)
|
||||
return icon;
|
||||
|
||||
icon = gdk_imlib_load_image (fname);
|
||||
|
||||
if (icon)
|
||||
g_hash_table_insert (icon_hash, g_strdup (fname), icon);
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* gicon_stock_load:
|
||||
*
|
||||
* Loads an icon from the Midnight Commander installation directory
|
||||
*/
|
||||
GdkImlibImage *
|
||||
gicon_stock_load (char *basename)
|
||||
|
||||
/* Builds a composite of the plain image and the litle symlink icon */
|
||||
static GdkImlibImage *
|
||||
build_overlay (GdkImlibImage *plain, GdkImlibImage *overlay)
|
||||
{
|
||||
int rowstride;
|
||||
int overlay_rowstride;
|
||||
guchar *src, *dest;
|
||||
int y;
|
||||
GdkImlibImage *im;
|
||||
char *fullname;
|
||||
|
||||
g_return_val_if_fail (basename != NULL, NULL);
|
||||
im = gdk_imlib_clone_image (plain);
|
||||
|
||||
fullname = concat_dir_and_file (ICONDIR, basename);
|
||||
im = gicon_get_by_filename (fullname);
|
||||
g_free (fullname);
|
||||
|
||||
rowstride = plain->rgb_width * 3;
|
||||
overlay_rowstride = overlay->rgb_width * 3;
|
||||
|
||||
dest = im->rgb_data + ((plain->rgb_height - overlay->rgb_height) * rowstride
|
||||
+ (plain->rgb_width - overlay->rgb_width) * 3);
|
||||
|
||||
src = overlay->rgb_data;
|
||||
|
||||
for (y = 0; y < overlay->rgb_height; y++) {
|
||||
memcpy (dest, src, overlay_rowstride);
|
||||
|
||||
dest += rowstride;
|
||||
src += overlay_rowstride;
|
||||
}
|
||||
|
||||
gdk_imlib_changed_image (im);
|
||||
return im;
|
||||
}
|
||||
|
||||
/**
|
||||
* gnome_file_entry_color:
|
||||
*
|
||||
* Returns an Imlib image appropiate for use in the icon list
|
||||
* based on the file_entry stat field and the filename. This
|
||||
* routine always succeeds.x
|
||||
/* Ensures that the icon set has the requested image */
|
||||
static void
|
||||
ensure_icon_image (IconSet *iset, IconType type)
|
||||
{
|
||||
g_assert (iset->plain != NULL);
|
||||
|
||||
switch (type) {
|
||||
case ICON_TYPE_PLAIN:
|
||||
/* The plain type always exists, so do nothing */
|
||||
break;
|
||||
|
||||
case ICON_TYPE_SYMLINK:
|
||||
iset->symlink = build_overlay (iset->plain, symlink_overlay);
|
||||
g_hash_table_insert (image_hash, iset->symlink, iset);
|
||||
break;
|
||||
|
||||
case ICON_TYPE_STALLED:
|
||||
iset->stalled = build_overlay (iset->plain, stalled_overlay);
|
||||
g_hash_table_insert (image_hash, iset->stalled, iset);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns the icon set corresponding to the specified icon filename, or NULL if
|
||||
* the file could not be loaded.
|
||||
*/
|
||||
static IconSet *
|
||||
get_icon_set (char *filename)
|
||||
{
|
||||
GdkImlibImage *im;
|
||||
IconSet *iset;
|
||||
|
||||
iset = g_hash_table_lookup (name_hash, filename);
|
||||
if (iset)
|
||||
return iset;
|
||||
|
||||
im = gdk_imlib_load_image (filename);
|
||||
if (!im)
|
||||
return NULL;
|
||||
|
||||
iset = g_new (IconSet, 1);
|
||||
iset->plain = im;
|
||||
iset->symlink = NULL;
|
||||
iset->filename = g_strdup (filename);
|
||||
|
||||
/* Insert the icon information into the hash tables */
|
||||
|
||||
g_hash_table_insert (name_hash, filename, iset);
|
||||
g_hash_table_insert (image_hash, iset->plain, iset);
|
||||
|
||||
return iset;
|
||||
}
|
||||
|
||||
/* Die because the icon installation is wrong */
|
||||
static void
|
||||
die_with_no_icons (void)
|
||||
{
|
||||
message (1, _("Error"), _("Default set of icons not found, please check your installation"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* Convenience function to load one of the default icons and die if this fails */
|
||||
static IconSet *
|
||||
get_stock_icon (char *name)
|
||||
{
|
||||
char *filename;
|
||||
IconSet *iset;
|
||||
|
||||
filename = g_concat_dir_and_file (ICONDIR, name);
|
||||
iset = get_icon_set (filename);
|
||||
g_free (filename);
|
||||
|
||||
if (!iset)
|
||||
die_with_no_icons ();
|
||||
|
||||
return iset;
|
||||
}
|
||||
|
||||
/* Convenience function to load one of the default overlays and die if this fails */
|
||||
static GdkImlibImage *
|
||||
gnome_file_entry_color (file_entry *fe)
|
||||
get_stock_overlay (char *name)
|
||||
{
|
||||
char *filename;
|
||||
GdkImlibImage *im;
|
||||
|
||||
filename = g_concat_dir_and_file (ICONDIR, name);
|
||||
im = gdk_imlib_load_image (filename);
|
||||
g_free (filename);
|
||||
|
||||
if (!im)
|
||||
die_with_no_icons ();
|
||||
|
||||
return im;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* gicon_init:
|
||||
* @void:
|
||||
*
|
||||
* Initializes the icon module.
|
||||
**/
|
||||
void
|
||||
gicon_init (void)
|
||||
{
|
||||
if (gicon_inited)
|
||||
return;
|
||||
|
||||
gicon_inited = TRUE;
|
||||
|
||||
name_hash = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
image_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
|
||||
/* Load the default icons */
|
||||
|
||||
iset_directory = get_stock_icon ("i-directory.png");
|
||||
iset_dirclosed = get_stock_icon ("i-dirclosed.png");
|
||||
iset_executable = get_stock_icon ("i-executable.png");
|
||||
iset_regular = get_stock_icon ("i-regular.png");
|
||||
iset_core = get_stock_icon ("i-core.png");
|
||||
iset_sock = get_stock_icon ("i-sock.png");
|
||||
iset_fifo = get_stock_icon ("i-fifo.png");
|
||||
iset_chardev = get_stock_icon ("i-chardev.png");
|
||||
iset_blockdev = get_stock_icon ("i-blockdev.png");
|
||||
|
||||
/* Load the overlay icons */
|
||||
|
||||
symlink_overlay = get_stock_overlay ("i-symlink.png");
|
||||
stalled_overlay = get_stock_overlay ("i-stalled.png");
|
||||
|
||||
our_uid = getuid ();
|
||||
our_gid = getgid ();
|
||||
}
|
||||
|
||||
/* Tries to get an icon from the file's metadata information */
|
||||
static GdkImlibImage *
|
||||
get_icon_from_metadata (char *filename)
|
||||
{
|
||||
int size;
|
||||
char *buf;
|
||||
GdkImlibImage *im;
|
||||
IconSet *iset;
|
||||
|
||||
/* Try the inlined icon */
|
||||
|
||||
if (gnome_metadata_get (filename, "icon-inline-png", &size, &buf) == 0) {
|
||||
im = gdk_imlib_inlined_png_to_image (buf, size);
|
||||
g_free (buf);
|
||||
|
||||
if (im)
|
||||
return im;
|
||||
}
|
||||
|
||||
/* Try the non-inlined icon */
|
||||
|
||||
if (gnome_metadata_get (filename, "icon-filename", &size, &buf) == 0) {
|
||||
iset = get_icon_set (buf);
|
||||
g_free (buf);
|
||||
|
||||
if (iset) {
|
||||
ensure_icon_image (iset, ICON_TYPE_PLAIN);
|
||||
return iset->plain;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL; /* nothing is available */
|
||||
}
|
||||
|
||||
/* Returns whether we are in the specified group or not */
|
||||
static int
|
||||
we_are_in_group (gid_t gid)
|
||||
{
|
||||
gid_t *groups;
|
||||
int ngroups, i;
|
||||
int retval;
|
||||
|
||||
if (our_gid == gid)
|
||||
return TRUE;
|
||||
|
||||
ngroups = getgroups (0, NULL);
|
||||
if (ngroups == -1 || ngroups == 0)
|
||||
return FALSE;
|
||||
|
||||
groups = g_new (gid_t, ngroups);
|
||||
ngroups = getgroups (ngroups, groups);
|
||||
if (ngroups == -1) {
|
||||
g_free (groups);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
retval = FALSE;
|
||||
|
||||
for (i = 0; i < ngroups; i++)
|
||||
if (groups[i] == gid)
|
||||
retval = TRUE;
|
||||
|
||||
g_free (groups);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Returns whether we can access the contents of directory specified by the file entry */
|
||||
static int
|
||||
can_access_directory (file_entry *fe)
|
||||
{
|
||||
mode_t test_mode;
|
||||
|
||||
if (fe->buf.st_uid == our_uid)
|
||||
test_mode = S_IRUSR | S_IXUSR;
|
||||
else if (we_are_in_group (fe->buf.st_gid))
|
||||
test_mode = S_IRGRP | S_IXGRP;
|
||||
else
|
||||
test_mode = S_IROTH | S_IXOTH;
|
||||
|
||||
return (fe->buf.st_mode & test_mode) == test_mode;
|
||||
}
|
||||
|
||||
/* This is the last resort for getting a file's icon. It uses the file mode
|
||||
* bits or a hardcoded name.
|
||||
*/
|
||||
static IconSet *
|
||||
get_default_icon (file_entry *fe)
|
||||
{
|
||||
mode_t mode = fe->buf.st_mode;
|
||||
|
||||
if (S_ISSOCK (mode))
|
||||
return icon_view_sock;
|
||||
return iset_sock;
|
||||
|
||||
if (S_ISCHR (mode))
|
||||
return icon_view_char_dev;
|
||||
return iset_chardev;
|
||||
|
||||
if (S_ISBLK (mode))
|
||||
return icon_view_block_dev;
|
||||
return iset_blockdev;
|
||||
|
||||
if (S_ISFIFO (mode))
|
||||
return icon_view_fifo;
|
||||
return iset_fifo;
|
||||
|
||||
if (is_exe (mode))
|
||||
return icon_view_executable;
|
||||
return iset_executable;
|
||||
|
||||
if (fe->fname && (!strcmp (fe->fname, "core") || !strcmp (extension (fe->fname), "core")))
|
||||
return icon_view_core;
|
||||
if (!strcmp (fe->fname, "core") || !strcmp (extension (fe->fname), "core"))
|
||||
return iset_core;
|
||||
|
||||
return icon_view_regular;
|
||||
return iset_regular; /* boooo */
|
||||
}
|
||||
|
||||
/**
|
||||
* gicon_get_icon_for_file:
|
||||
*
|
||||
* Given a filename and its stat information, we return the optimal
|
||||
* icon for it. Including a lookup in the metadata.
|
||||
*/
|
||||
* @directory: The directory on which the file resides.
|
||||
* @fe: The file entry that represents the file.
|
||||
* @do_quick: Whether the function should try to use (expensive) metadata information.
|
||||
*
|
||||
* Returns the appropriate icon for the specified file.
|
||||
*
|
||||
* Return value: The icon for the specified file.
|
||||
**/
|
||||
GdkImlibImage *
|
||||
gicon_get_icon_for_file_speed (char *directory, file_entry *fe, gboolean do_quick)
|
||||
gicon_get_icon_for_file (char *directory, file_entry *fe, gboolean do_quick)
|
||||
{
|
||||
GdkImlibImage *image;
|
||||
int size;
|
||||
char *buf, *mime_type;
|
||||
mode_t mode;
|
||||
|
||||
IconSet *iset;
|
||||
mode_t mode;
|
||||
const char *mime_type;
|
||||
|
||||
g_return_val_if_fail (directory != NULL, NULL);
|
||||
g_return_val_if_fail (fe != NULL, NULL);
|
||||
|
||||
if (!gicon_inited)
|
||||
gicon_init ();
|
||||
gicon_init ();
|
||||
|
||||
mode = fe->buf.st_mode;
|
||||
|
||||
/*
|
||||
* 1. First test for it being a directory or a link to a directory.
|
||||
*/
|
||||
if (S_ISDIR (mode)){
|
||||
if (fe->buf.st_uid != our_uid){
|
||||
{
|
||||
static int reported;
|
||||
|
||||
if (!reported){
|
||||
g_warning ("Getgroups should be used here\n");
|
||||
reported = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME:
|
||||
* Use getgroups to fetch the list of groups
|
||||
* to which I belong and test against those
|
||||
*/
|
||||
if (fe->buf.st_gid != our_gid){
|
||||
/* 1. First try the user's settings */
|
||||
|
||||
/*
|
||||
* We do not share the UID or the GID,
|
||||
* test for read/execute permissions
|
||||
*/
|
||||
if ((mode & (S_IROTH | S_IXOTH)) != (S_IROTH | S_IXOTH))
|
||||
return icon_view_dirclosed;
|
||||
} else {
|
||||
|
||||
/*
|
||||
* Same group, check if we have permissions
|
||||
*/
|
||||
if ((mode & (S_IRGRP | S_IXGRP)) != (S_IRGRP | S_IXGRP))
|
||||
return icon_view_dirclosed;
|
||||
}
|
||||
} else {
|
||||
if ((mode & (S_IRUSR | S_IXUSR)) != (S_IRUSR | S_IXUSR))
|
||||
return icon_view_dirclosed;
|
||||
}
|
||||
|
||||
return icon_view_directory;
|
||||
}
|
||||
|
||||
if (S_ISLNK (mode)){
|
||||
if (fe->f.link_to_dir)
|
||||
return icon_view_directory;
|
||||
|
||||
if (fe->f.stalled_link)
|
||||
return icon_view_stalled;
|
||||
|
||||
/* BEtter effect; do not use the symlink icon */
|
||||
#if 0
|
||||
return icon_view_symlink;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* 2. Expensive tests
|
||||
*/
|
||||
if (!do_quick || we_can_afford_the_speed) {
|
||||
char *full_name;
|
||||
GdkImlibImage *im;
|
||||
|
||||
full_name = g_concat_dir_and_file (directory, fe->fname);
|
||||
|
||||
/*
|
||||
* 2.1 Try to fetch the icon as an inline png from the metadata.
|
||||
*/
|
||||
if (gnome_metadata_get (full_name, "icon-inline-png", &size, &buf) == 0){
|
||||
image = gdk_imlib_inlined_png_to_image (buf, size);
|
||||
|
||||
g_free (buf);
|
||||
|
||||
if (image) {
|
||||
g_free (full_name);
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 2.2. Try to fetch the icon from the metadata.
|
||||
*/
|
||||
if (gnome_metadata_get (full_name, "icon-filename", &size, &buf) == 0){
|
||||
image = gicon_get_by_filename (buf);
|
||||
|
||||
g_free (buf);
|
||||
|
||||
if (image) {
|
||||
g_free (full_name);
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
im = get_icon_from_metadata (full_name);
|
||||
g_free (full_name);
|
||||
|
||||
if (im)
|
||||
return im;
|
||||
}
|
||||
|
||||
/*
|
||||
* 3. Mime-type based
|
||||
*/
|
||||
|
||||
/* 2. See if it is a directory */
|
||||
|
||||
if (S_ISDIR (mode)) {
|
||||
if (can_access_directory (fe))
|
||||
iset = iset_directory;
|
||||
else
|
||||
iset = iset_dirclosed;
|
||||
|
||||
goto add_link;
|
||||
}
|
||||
|
||||
/* 3. Try MIME-types */
|
||||
|
||||
mime_type = gnome_mime_type_or_default (fe->fname, NULL);
|
||||
if (mime_type){
|
||||
char *icon;
|
||||
if (mime_type) {
|
||||
char *icon_name;
|
||||
|
||||
icon = gnome_mime_get_value (mime_type, "icon-filename");
|
||||
|
||||
if (icon){
|
||||
image = gicon_get_by_filename (icon);
|
||||
|
||||
if (image)
|
||||
return image;
|
||||
icon_name = gnome_mime_get_value (mime_type, "icon-filename");
|
||||
if (icon_name) {
|
||||
iset = get_icon_set (icon_name);
|
||||
if (iset)
|
||||
goto add_link;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 4. Try to find an appropiate icon from the stat information or
|
||||
* the hard coded filename.
|
||||
*/
|
||||
image = gnome_file_entry_color (fe);
|
||||
|
||||
g_assert (image != NULL);
|
||||
|
||||
return image;
|
||||
}
|
||||
/* 4. Get an icon from the file mode */
|
||||
|
||||
GdkImlibImage *
|
||||
gicon_get_icon_for_file (char *directory, file_entry *fe)
|
||||
{
|
||||
return gicon_get_icon_for_file_speed (directory, fe, TRUE);
|
||||
}
|
||||
iset = get_default_icon (fe);
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
void *image;
|
||||
} lookup_name_closure_t;
|
||||
add_link:
|
||||
|
||||
void
|
||||
search_image (gpointer key, gpointer value, gpointer user_data)
|
||||
{
|
||||
lookup_name_closure_t *closure = user_data;
|
||||
g_assert (iset != NULL);
|
||||
|
||||
if (value == closure->image)
|
||||
closure->name = key;
|
||||
if (S_ISLNK (mode)) {
|
||||
if (fe->f.link_to_dir)
|
||||
iset = iset_directory;
|
||||
|
||||
if (fe->f.stalled_link) {
|
||||
ensure_icon_image (iset, ICON_TYPE_STALLED);
|
||||
return iset->stalled;
|
||||
} else {
|
||||
ensure_icon_image (iset, ICON_TYPE_SYMLINK);
|
||||
return iset->symlink;
|
||||
}
|
||||
} else {
|
||||
ensure_icon_image (iset, ICON_TYPE_PLAIN);
|
||||
return iset->plain;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file name that maps to this given GdkImlibImage
|
||||
*
|
||||
*/
|
||||
* gicon_get_filename_for_icon:
|
||||
* @image: An icon image loaded by the icon module.
|
||||
*
|
||||
* Queries the icon database for the icon filename that corresponds to the
|
||||
* specified image.
|
||||
*
|
||||
* Return value: The filename that contains the icon for the specified image.
|
||||
**/
|
||||
char *
|
||||
gicon_image_to_name (GdkImlibImage *image)
|
||||
gicon_get_filename_for_icon (GdkImlibImage *image)
|
||||
{
|
||||
lookup_name_closure_t closure;
|
||||
IconSet *iset;
|
||||
|
||||
closure.image = image;
|
||||
closure.name = NULL;
|
||||
|
||||
g_hash_table_foreach (icon_hash, &search_image, &closure);
|
||||
if (closure.name == NULL)
|
||||
return g_strdup (ICONDIR "i-regular.png");
|
||||
g_return_val_if_fail (image != NULL, NULL);
|
||||
|
||||
return g_strdup (closure.name);
|
||||
gicon_init ();
|
||||
|
||||
iset = g_hash_table_lookup (name_hash, image);
|
||||
g_assert (iset != NULL);
|
||||
return iset->filename;
|
||||
}
|
||||
|
@ -1,12 +1,23 @@
|
||||
/* Icon loading support for the Midnight Commander
|
||||
*
|
||||
* Copyright (C) 1998-1999 The Free Software Foundation
|
||||
*
|
||||
* Authors: Miguel de Icaza <miguel@nuclecu.unam.mx>
|
||||
* Federico Mena <federico@nuclecu.unam.mx>
|
||||
*/
|
||||
|
||||
#ifndef GNOME_GICON_H
|
||||
#define GNOME_GICON_H
|
||||
|
||||
GdkImlibImage *gicon_get_by_filename (char *fname);
|
||||
GdkImlibImage *gicon_stock_load (char *basename);
|
||||
GdkImlibImage *gicon_get_icon_for_file (char *directory, file_entry *fe);
|
||||
GdkImlibImage *gicon_get_icon_for_file_speed (char *directory, file_entry *fe, gboolean do_quick);
|
||||
#include <glib.h>
|
||||
#include <gdk_imlib.h>
|
||||
#include "dir.h"
|
||||
|
||||
|
||||
char *gicon_image_to_name (GdkImlibImage *image);
|
||||
void gicon_init (void);
|
||||
|
||||
GdkImlibImage *gicon_get_icon_for_file (char *directory, file_entry *fe, gboolean do_quick);
|
||||
char *gicon_get_filename_for_icon (GdkImlibImage *image);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -98,6 +98,7 @@ gnome_file_property_dialog_init (GnomeFilePropertyDialog *file_property_dialog)
|
||||
file_property_dialog->drop_target = NULL;
|
||||
file_property_dialog->im = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gnome_file_property_dialog_finalize (GtkObject *object)
|
||||
{
|
||||
@ -141,8 +142,8 @@ create_general_properties (GnomeFilePropertyDialog *fp_dlg)
|
||||
GtkWidget *align;
|
||||
gchar *direc;
|
||||
gchar *gen_string;
|
||||
gchar size[50]; /* this is a HUGE file. (: */
|
||||
gchar size2[20]; /* this is a HUGE file. (: */
|
||||
gchar buf[MC_MAXPATHLEN];
|
||||
gchar buf2[MC_MAXPATHLEN];
|
||||
file_entry *fe;
|
||||
GtkWidget *icon;
|
||||
struct tm *time;
|
||||
@ -156,7 +157,7 @@ create_general_properties (GnomeFilePropertyDialog *fp_dlg)
|
||||
direc = g_strdup (fp_dlg->file_name);
|
||||
strrchr (direc, '/')[0] = '\0';
|
||||
fe = file_entry_from_file (fp_dlg->file_name);
|
||||
fp_dlg->im = gicon_get_icon_for_file_speed (direc, fe, FALSE);
|
||||
fp_dlg->im = gicon_get_icon_for_file (direc, fe, FALSE);
|
||||
file_entry_free (fe);
|
||||
g_free (direc);
|
||||
icon = gnome_pixmap_new_from_imlib (fp_dlg->im);
|
||||
@ -203,12 +204,11 @@ create_general_properties (GnomeFilePropertyDialog *fp_dlg)
|
||||
label = gtk_label_new (_("File Type: Symbolic Link"));
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
||||
n = mc_readlink (fp_dlg->file_name, size, 49);
|
||||
n = mc_readlink (fp_dlg->file_name, buf, MC_MAXPATHLEN);
|
||||
if (n < 0)
|
||||
label = gtk_label_new (_("Target Name: INVALID LINK"));
|
||||
else {
|
||||
size[n] = '\0';
|
||||
gen_string = g_strconcat (_("Target Name: "), size, NULL);
|
||||
gen_string = g_strconcat (_("Target Name: "), buf, NULL);
|
||||
label = gtk_label_new (gen_string);
|
||||
g_free (gen_string);
|
||||
}
|
||||
@ -230,18 +230,19 @@ create_general_properties (GnomeFilePropertyDialog *fp_dlg)
|
||||
|| S_ISREG (fp_dlg->st.st_mode)
|
||||
|| S_ISLNK (fp_dlg->st.st_mode)) {
|
||||
if ((gint)fp_dlg->st.st_size < 1024) {
|
||||
snprintf (size, 19, "%d", (gint) fp_dlg->st.st_size);
|
||||
gen_string = g_strconcat (_("File Size: "), size, _(" bytes"), NULL);
|
||||
snprintf (buf, MC_MAXPATHLEN, "%d", (gint) fp_dlg->st.st_size);
|
||||
gen_string = g_strconcat (_("File Size: "), buf, _(" bytes"), NULL);
|
||||
} else if ((gint)fp_dlg->st.st_size < 1024 * 1024) {
|
||||
snprintf (size, 19, "%.1f", (gfloat) fp_dlg->st.st_size / 1024.0);
|
||||
snprintf (size2, 19, "%d", (gint) fp_dlg->st.st_size);
|
||||
gen_string = g_strconcat (_("File Size: "), size, _(" KBytes ("),
|
||||
size2, _(" bytes)"), NULL);
|
||||
snprintf (buf, MC_MAXPATHLEN, "%.1f", (gfloat) fp_dlg->st.st_size / 1024.0);
|
||||
snprintf (buf2, MC_MAXPATHLEN, "%d", (gint) fp_dlg->st.st_size);
|
||||
gen_string = g_strconcat (_("File Size: "), buf, _(" KBytes ("),
|
||||
buf2, _(" bytes)"), NULL);
|
||||
} else {
|
||||
snprintf (size, 19, "%.1f", (gfloat) fp_dlg->st.st_size / (1024.0 * 1024.0));
|
||||
snprintf (size2, 19, "%d", (gint) fp_dlg->st.st_size);
|
||||
gen_string = g_strconcat (_("File Size: "), size, _(" MBytes ("),
|
||||
size2, _(" bytes)"), NULL);
|
||||
snprintf (buf, MC_MAXPATHLEN, "%.1f",
|
||||
(gfloat) fp_dlg->st.st_size / (1024.0 * 1024.0));
|
||||
snprintf (buf2, MC_MAXPATHLEN, "%d", (gint) fp_dlg->st.st_size);
|
||||
gen_string = g_strconcat (_("File Size: "), buf, _(" MBytes ("),
|
||||
buf2, _(" bytes)"), NULL);
|
||||
}
|
||||
label = gtk_label_new (gen_string);
|
||||
g_free (gen_string);
|
||||
@ -263,8 +264,8 @@ create_general_properties (GnomeFilePropertyDialog *fp_dlg)
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
|
||||
time = gmtime (&(fp_dlg->st.st_ctime));
|
||||
strftime (size, 49, "%a, %b %d %Y, %I:%M:%S %p", time);
|
||||
label = gtk_label_new (size);
|
||||
strftime (buf, MC_MAXPATHLEN, "%a, %b %d %Y, %I:%M:%S %p", time);
|
||||
label = gtk_label_new (buf);
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 0, 1);
|
||||
|
||||
@ -272,8 +273,8 @@ create_general_properties (GnomeFilePropertyDialog *fp_dlg)
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
|
||||
time = gmtime (&(fp_dlg->st.st_mtime));
|
||||
strftime (size, 49, "%a, %b %d %Y, %I:%M:%S %p", time);
|
||||
label = gtk_label_new (size);
|
||||
strftime (buf, MC_MAXPATHLEN, "%a, %b %d %Y, %I:%M:%S %p", time);
|
||||
label = gtk_label_new (buf);
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 1, 2);
|
||||
|
||||
@ -281,8 +282,8 @@ create_general_properties (GnomeFilePropertyDialog *fp_dlg)
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3);
|
||||
time = gmtime (&(fp_dlg->st.st_atime));
|
||||
strftime (size, 49, "%a, %b %d %Y, %I:%M:%S %p", time);
|
||||
label = gtk_label_new (size);
|
||||
strftime (buf, MC_MAXPATHLEN, "%a, %b %d %Y, %I:%M:%S %p", time);
|
||||
label = gtk_label_new (buf);
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 2, 3);
|
||||
return vbox;
|
||||
@ -364,6 +365,7 @@ metadata_toggled (GtkWidget *cbox, GnomeFilePropertyDialog *fp_dlg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
switch_metadata_box (GnomeFilePropertyDialog *fp_dlg)
|
||||
{
|
||||
@ -423,6 +425,7 @@ switch_metadata_box (GnomeFilePropertyDialog *fp_dlg)
|
||||
}
|
||||
fp_dlg->changing = FALSE;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
generate_icon_sel (GnomeFilePropertyDialog *fp_dlg)
|
||||
{
|
||||
@ -430,7 +433,7 @@ generate_icon_sel (GnomeFilePropertyDialog *fp_dlg)
|
||||
gchar *icon;
|
||||
|
||||
retval = gnome_icon_entry_new ("gmc_file_icon", "Select an Icon");
|
||||
icon = gicon_image_to_name (fp_dlg->im);
|
||||
icon = gicon_get_filename_for_icon (fp_dlg->im);
|
||||
if (!icon)
|
||||
return retval;
|
||||
|
||||
@ -442,6 +445,7 @@ generate_icon_sel (GnomeFilePropertyDialog *fp_dlg)
|
||||
g_free (icon);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
generate_actions_box (GnomeFilePropertyDialog *fp_dlg)
|
||||
{
|
||||
@ -552,6 +556,7 @@ generate_actions_box (GnomeFilePropertyDialog *fp_dlg)
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_settings_pane (GnomeFilePropertyDialog *fp_dlg)
|
||||
{
|
||||
@ -643,7 +648,6 @@ perm_get_umode (GnomeFilePropertyDialog *fp_dlg)
|
||||
#undef SETBIT
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
perm_set_mode_label (GtkWidget *widget, gpointer data)
|
||||
{
|
||||
@ -792,12 +796,13 @@ perm_owner_new (GnomeFilePropertyDialog *fp_dlg)
|
||||
|
||||
return gentry;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
perm_group_new (GnomeFilePropertyDialog *fp_dlg)
|
||||
{
|
||||
GtkWidget *gentry;
|
||||
struct group *grp;
|
||||
gchar grpnum [10];
|
||||
gchar grpnum [50];
|
||||
gboolean grp_flag = FALSE;
|
||||
gchar *grpname = NULL;
|
||||
GList *templist;
|
||||
@ -814,7 +819,7 @@ perm_group_new (GnomeFilePropertyDialog *fp_dlg)
|
||||
if (grp->gr_name)
|
||||
fp_dlg->group_name = g_strdup (grp->gr_name);
|
||||
else {
|
||||
g_snprintf (grpnum, 9, "%d", (int) grp->gr_gid);
|
||||
sprintf (grpnum, "%d", (int) grp->gr_gid);
|
||||
fp_dlg->group_name = g_strdup (grpnum);
|
||||
}
|
||||
|
||||
@ -824,7 +829,7 @@ perm_group_new (GnomeFilePropertyDialog *fp_dlg)
|
||||
if (grp->gr_name)
|
||||
grpname = grp->gr_name;
|
||||
else {
|
||||
g_snprintf (grpnum, 9, "%d", (int) grp->gr_gid);
|
||||
sprintf (grpnum, "%d", (int) grp->gr_gid);
|
||||
grpname = grpnum;
|
||||
}
|
||||
}
|
||||
@ -932,13 +937,14 @@ create_perm_properties (GnomeFilePropertyDialog *fp_dlg)
|
||||
gtk_box_pack_start (GTK_BOX (vbox), perm_ownership_new (fp_dlg), TRUE, TRUE, 0);
|
||||
return vbox;
|
||||
}
|
||||
|
||||
/* finally the new dialog */
|
||||
static void
|
||||
init_metadata (GnomeFilePropertyDialog *fp_dlg)
|
||||
{
|
||||
gint size;
|
||||
char *mime_type;
|
||||
gchar link_name[60];
|
||||
gchar link_name[MC_MAXPATHLEN];
|
||||
gint n;
|
||||
gchar *file_name, *desktop_url;
|
||||
|
||||
@ -952,11 +958,9 @@ init_metadata (GnomeFilePropertyDialog *fp_dlg)
|
||||
/* Mime stuff */
|
||||
file_name = fp_dlg->file_name;
|
||||
if (S_ISLNK (fp_dlg->st.st_mode)) {
|
||||
n = mc_readlink (fp_dlg->file_name, link_name, 59);
|
||||
if (n > 0) {
|
||||
link_name[n] = '\0';
|
||||
n = mc_readlink (fp_dlg->file_name, link_name, MC_MAXPATHLEN);
|
||||
if (n > 0)
|
||||
file_name = link_name;
|
||||
}
|
||||
}
|
||||
|
||||
if (gnome_metadata_get (fp_dlg->file_name, "desktop-url", &size, &desktop_url) == 0)
|
||||
@ -987,6 +991,7 @@ init_metadata (GnomeFilePropertyDialog *fp_dlg)
|
||||
g_print ("we have an icon-filename:%s:\n", fp_dlg->icon_filename);
|
||||
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gnome_file_property_dialog_new (gchar *file_name, gboolean can_set_icon)
|
||||
{
|
||||
@ -1057,6 +1062,7 @@ gnome_file_property_dialog_new (gchar *file_name, gboolean can_set_icon)
|
||||
|
||||
return GTK_WIDGET (fp_dlg);
|
||||
}
|
||||
|
||||
static gint
|
||||
apply_mode_change (GnomeFilePropertyDialog *fpd)
|
||||
{
|
||||
@ -1068,6 +1074,7 @@ apply_mode_change (GnomeFilePropertyDialog *fpd)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gint
|
||||
apply_uid_group_change (GnomeFilePropertyDialog *fpd)
|
||||
{
|
||||
@ -1122,6 +1129,7 @@ apply_uid_group_change (GnomeFilePropertyDialog *fpd)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gint
|
||||
apply_name_change (GnomeFilePropertyDialog *fpd)
|
||||
{
|
||||
@ -1170,6 +1178,7 @@ apply_name_change (GnomeFilePropertyDialog *fpd)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static gint
|
||||
apply_metadata_change (GnomeFilePropertyDialog *fpd)
|
||||
{
|
||||
@ -1260,7 +1269,7 @@ apply_metadata_change (GnomeFilePropertyDialog *fpd)
|
||||
return 1;
|
||||
/* And finally, we set the metadata on the icon filename */
|
||||
text = gnome_icon_entry_get_filename (GNOME_ICON_ENTRY (fpd->button)); /*gtk_entry_get_text (GTK_ENTRY (gnome_icon_entry_gtk_entry (GNOME_ICON_ENTRY (fpd->button))));*/
|
||||
icon_name = gicon_image_to_name (fpd->im);
|
||||
icon_name = gicon_get_filename_for_icon (fpd->im);
|
||||
if (text) {
|
||||
if (strcmp (text, icon_name))
|
||||
/* FIXME: We make a big assumption here. If the file doesn't exist, it will
|
||||
|
@ -100,10 +100,10 @@ item_properties (GtkWidget *parent, char *fname, DesktopIconInfo *dii)
|
||||
dirname = g_strndup (fname, p - fname);
|
||||
|
||||
fe = file_entry_from_file (fname);
|
||||
icon = gicon_get_icon_for_file_speed (dirname, fe, FALSE);
|
||||
icon = gicon_get_icon_for_file (dirname, fe, FALSE);
|
||||
g_free (dirname);
|
||||
file_entry_free (fe);
|
||||
icon_filename = gicon_image_to_name (icon);
|
||||
icon_filename = gicon_get_filename_for_icon (icon);
|
||||
if (icon_filename == NULL)
|
||||
icon_filename = g_strdup (ICONDIR "i-regular.png");
|
||||
|
||||
|
@ -232,7 +232,7 @@ panel_fill_panel_icons (WPanel *panel)
|
||||
file_entry *fe = &panel->dir.list [i];
|
||||
int p;
|
||||
|
||||
image = gicon_get_icon_for_file (panel->cwd, fe);
|
||||
image = gicon_get_icon_for_file (panel->cwd, fe, TRUE);
|
||||
p = gnome_icon_list_append_imlib (icons, image, fe->fname);
|
||||
if (fe->f.marked)
|
||||
gnome_icon_list_select_icon (icons, p);
|
||||
|
Двоичные данные
gnome/i-symlink.png
Двоичные данные
gnome/i-symlink.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 1.1 KiB После Ширина: | Высота: | Размер: 131 B |
Загрузка…
x
Ссылка в новой задаче
Block a user