home *** CD-ROM | disk | FTP | other *** search
- /* The GIMP -- an image manipulation program
- * Copyright (C) 1995 Spencer Kimball and Peter Mattis */
- #define GUASH_TIMESTAMP "Time-stamp: <1999/03/17 22:29:44 narazaki@gimp.org>"
- /* guash.c -- This is a plug-in/extension for the GIMP 1.X
- * Guash: Gimp Users' Another SHell (pronounced like 'gouache')
- * Copyright (C) 1997-1999 Shuji Narazaki <narazaki@gimp.org>
- * guash uses internally for loading xv's thumbnail:
- * xvpict (Copyright (C) 1997 Marco Lamberto <lm@geocities.com>)
- * (slighly modified xvpict is embedded into guash for reducing communication
- * overhead)
- *
- * 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.
- *
- * THANKS
- * this release of guash was applied patches from:
- * Marco Lamberto <lm@geocities.com>
- * Vincent Hascoet <hascoet@lep.research.philips.com>
- * J"urgen Koslowski <koslowj@iti.cs.tu-bs.de>
- * meo@netads.com (Miles O'Neal)
- * Casper Maarbjerg <casper@tv1.dk>
- * Drew Ronneberg <drew@rnaworld.princeton.edu>
- * craig@pablo.ppco.com (Craig Brockmeier)
- * Colin Plumb <colin@nyx.net>
- * Shawn Houston <houston@arsc.edu>
- */
-
- #include "config.h"
-
- #include <gtk/gtk.h>
- #include <gdk/gdkkeysyms.h>
- #include <libgimp/gimp.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #ifdef HAVE_DIRENT_H
- #include <dirent.h>
- #endif
- #include <fcntl.h>
- #ifdef HAVE_PWD_H
- #include <pwd.h>
- #endif
- #include <errno.h>
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif
-
- #include "guash-config.h"
- #include "VERSION"
- #include "include/debug.h"
- #include "data/guash-banner.h"
- #include "data/guash-dir_icon.h"
- #include "data/guash-pdir_icon.h"
- #include "data/guash-file_icon.h"
-
- #ifdef G_OS_WIN32
- #define mkdir(p, m) _mkdir (p)
- #define sleep(s) g_usleep (s*1000000)
- #define readlink(p, b, l) (-1)
- #endif
-
- /* The following definition is only for narazaki@gimp.org (linux user) */
- #ifdef CHECK_PERFORMANCE
- # include <sys/times.h>
- # define WATCH(exp) \
- { \
- struct tms _t;\
- gulong _start = (gulong) times (&_t);\
- exp;\
- printf ("Elapsed time: %ld msec.\n", (gulong) times (&_t) - _start);\
- }
- #else
- # define WATCH(exp) exp
- #endif
-
- /* CONSTANTS */
- #ifdef DEBUG
- # define PLUG_IN_NAME "extension_guash_debug"
- # define PLUG_IN_NAME_SUB "plug_in_guash_debug"
- # define PLUG_IN_NAME_FOR_SELECTION "extension_guash_script_fu_interface"
- # define SHORT_NAME "Guash (debug)"
- # define MENU_PATH_AS_EXTENSION "<Toolbox>/Xtns/Guash (debug)"
- # define MENU_PATH_AS_PLUG_IN "<Image>/File/Guash (debug)"
- #else
- # define PLUG_IN_NAME "extension_guash"
- # define PLUG_IN_NAME_SUB "plug_in_guash"
- # define PLUG_IN_NAME_FOR_SELECTION "extension_guash_script_fu_interface"
- # define SHORT_NAME "Guash"
- # define MENU_PATH_AS_EXTENSION "<Toolbox>/Xtns/Guash"
- # define MENU_PATH_AS_PLUG_IN "<Image>/File/Guash"
- #endif
-
- #ifndef NEW_DND_API
- #define GUASH_DND_SIGNATURE "Guash copy files:\n"
- #endif
- #define THUMBNAIL_DIR "/.xvpics"
- #define DELETE_CORE TRUE
-
- #ifdef GIMP_HAVE_PARASITES
- #define GUASH_PARASITE_NAME "guash-selection"
- #endif
-
- /* VISUAL PARAMETERS */
- #define JUMP_BUTTON_WIDTH 40 /* change it if you use a large font */
- #define LABEL_PADDING 4 /* [pixel] from left margin */
- #define SCROLLBAR_WIDTH 15 /* the width of scrollbar */
- #define THUMBNAIL_TSEPARATOR 2 /* v. pad between thumb. and name */
- #define THUMBNAIL_BORDER_WIDTH 2 /* width of selection border */
- #define WHITE_COLOR { 255, 255, 255 }
- #define CURSOR_DEFAULT GDK_TOP_LEFT_ARROW
- #define CURSOR_HAND GDK_HAND2
- #define CURSOR_WAIT GDK_WATCH
- #define NCOL_OF_THUMBNAIL_PANEL_MIN 4 /* minimal size (width) of panel */
- #define NROW_OF_THUMBNAIL_PANEL_MIN 1 /* minimal size (height) of panel */
-
- /* VISUAL CONSTANTS */
- #define THUMBNAIL_WIDTH 80 /* Max width of XV thumbnail */
- #define THUMBNAIL_HEIGHT 60 /* Max height of XV thumbnail */
-
- #define LABEL_WIDTH(x) ((x) - JUMP_BUTTON_WIDTH - LABEL_PADDING)
- #define THUMBNAIL_THEIGHT (the_panel.font_height + THUMBNAIL_TSEPARATOR)
- #define THUMBNAIL_FULLHEIGHT (THUMBNAIL_HEIGHT + THUMBNAIL_THEIGHT)
- #define THUMBNAIL_FULLHEIGHT (THUMBNAIL_HEIGHT + THUMBNAIL_THEIGHT)
- #define THUMBNAIL_SEPARATOR (2 * THUMBNAIL_BORDER_WIDTH + 3)
-
- /* OTHER CONSTANTS */
- #define INITIALIZATION_DELAY 100 /* [msec] */
- #define BANNER_UP_PERIOD 200 /* [msec] */
- #define INITIALIZATION_SLEEP_PERIOD 1200 /* [msec] */
- #define STARTUP_SLEEP_PERIOD 300 /* [msec] */
- #define EVENT_MASK (GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK)
- #define LINE_BUF_SIZE 1024
- #define PATH_LENGTH 2049
-
- #define INTERFACE guash_interface
- #define DIALOG guash_dialog
- #define VALS guash_vals
-
- #define INDEX_TO_X(i) ((i % the_panel.ncol)\
- * (THUMBNAIL_WIDTH + THUMBNAIL_SEPARATOR)\
- + THUMBNAIL_SEPARATOR)
- #define INDEX_TO_Y(i) ((i / the_panel.ncol)\
- * (THUMBNAIL_FULLHEIGHT + THUMBNAIL_SEPARATOR)\
- + THUMBNAIL_SEPARATOR)
- #define VALID_POS_P(x,y) ((y < \
- (THUMBNAIL_FULLHEIGHT + THUMBNAIL_SEPARATOR)\
- * the_panel.nrow)\
- && \
- ((x < \
- (THUMBNAIL_WIDTH + THUMBNAIL_SEPARATOR)\
- * the_panel.ncol)))
- #define POS_TO_INDEX(x,y) (cwd_cache->display_page * the_panel.nthumb_in_page \
- + (y - THUMBNAIL_SEPARATOR) \
- / (THUMBNAIL_FULLHEIGHT + THUMBNAIL_SEPARATOR)\
- * the_panel.ncol \
- + x / (THUMBNAIL_WIDTH + THUMBNAIL_SEPARATOR))
- #define COL2WIDTH(col) (col * (THUMBNAIL_WIDTH + THUMBNAIL_SEPARATOR) + THUMBNAIL_SEPARATOR)
- #define ROW2HEIGHT(row) (row * (THUMBNAIL_FULLHEIGHT + THUMBNAIL_SEPARATOR) + THUMBNAIL_SEPARATOR)
- #define WIDTH2COL(w) (w - THUMBNAIL_SEPARATOR) / (THUMBNAIL_WIDTH + THUMBNAIL_SEPARATOR)
- #define HEIGHT2ROW(h) (h - THUMBNAIL_SEPARATOR) / (THUMBNAIL_FULLHEIGHT + THUMBNAIL_SEPARATOR)
-
- /* programming stuff */
- #define ASSERT(predicate) if (! (predicate)) return
-
- /* gtkWrapper */
- /* gtkW is the abbreviation of gtk Wrapper */
- #define GTKW_ENTRY_BUFFER_SIZE 3
- #define GTKW_ENTRY_WIDTH 20
- #define GTKW_SCALE_WIDTH 200
- #define GTKW_BORDER_WIDTH 0
-
- /* gtkW type */
- typedef struct
- {
- GtkWidget *widget;
- gpointer value;
- void (*updater)();
- } gtkW_widget_table;
- gtkW_widget_table widget_pointer[1];
-
- /* gtkW global variables */
- gint gtkW_border_width = GTKW_BORDER_WIDTH;
- gint gtkW_border_height = 0;
- gint gtkW_homogeneous_layout = FALSE;
- gint gtkW_frame_shadow_type = GTK_SHADOW_ETCHED_IN;
- gint gtkW_align_x = GTK_FILL;
- gint gtkW_align_y = GTK_FILL;
-
- #include "include/gtkW.h"
-
- /* define enums */
- /* for binding_style {BINDING_GIMP, BINDING_EMACS } I*/
- #define BINDING_GIMP 0
- #define BINDING_EMACS 1
- #define NBINDINGS 2 /* number of bindings */
-
- /* for file_kind { NOT_EXIST, REGFILE, DIRECTORY, SLNKFILE, SLNKDIR } */
- #define NOT_EXIST 0
- #define REGFILE (1 << 0)
- #define DIRECTORY (1 << 1)
- #define SLNKFILE (1 << 2)
- #define SLNKDIR (1 << 3)
-
- /* for directory_cache.savable { FALSE, TRUE, UNKNOWN } */
- #define UNKNOWN 2
-
- /* for selection_kind { FALSE, SELECTION_IMAGE, SELECTION_DIRECTORY } */
- #define SELECTION_IMAGE 1
- #define SELECTION_DISPLAY 2
-
- /* for sensives { SENSITIVE_SELECTION, SENSITIVE_SCROLL } */
- #define SENSITIVE_SELECTION (1 << 0)
- #define SENSITIVE_SCROLL (1 << 1)
-
- /* getters and setters for misc attributes for structs */
- #define INITIALIZE_ATTRIBUTES(obj) ((obj)->attributes = 0)
- /* assumed each attribute is represented by 1 bit. bogus. */
- #define GET_ATTRIBUTE(obj, key) (((obj)->attributes & (key)) >> (key))
- #define HAS_ATTRIBUTE(obj, key) ((obj)->attributes & (key))
- #define HAS_NO_ATTRIBUTE(obj, key) (! ((obj)->attributes & (key)))
- #define SET_ATTRIBUTE(obj, key) ((obj)->attributes |= (key))
- #define RESET_ATTRIBUTE(obj, key) ((obj)->attributes &= ~(key))
- #define SET_TO_ATTRIBUTE(obj, key, val) ((val) ? SET_ATTRIBUTE(obj, key) : RESET_ATTRIBUTE(obj, key))
- #define COPY_ATTRIBUTE(dest, key, src) (SET_TO_ATTRIBUTE(dest, key, HAS_ATTRIBUTE(src, key)))
- #define TOGGLE_ATTRIBUTE(obj, key) (SET_TO_ATTRIBUTE(obj, key, HAS_NO_ATTRIBUTE(obj, key)))
-
- /* attributes for VAL */
- #define DISPLAY_IMAGE_P (1 << 0)
- #define SORT_BY_NAME_P (1 << 1)
- /* SAVE_AS_XVPICT_P should be used only for save thumbnail.
- And don't use to determine whether thumbnails were saved */
- #define SAVE_AS_XVPICT_P (1 << 2)
- #define SAVE_AS_GPICT_P (1 << 3)
- #define CONFIRM_P (1 << 4)
- #define MONITOR_P (1 << 5)
-
- typedef struct
- {
- guint attributes;
- GCHAR last_dir_name[PATH_LENGTH];
- GCHAR mapping_command[LINE_BUF_SIZE];
- } VALS;
-
- typedef struct
- {
- guchar *data;
- gint width;
- gint height;
- gint ch;
- gint size;
- } image_buffer;
-
- /* attributes for Thumbnail */
- #define DIRECTORY_P (1 << 0)
- #define SYMLINK_P (1 << 1)
- #define DELETED_P (1 << 2)
- #define PARENT_DIRECTORY_P (1 << 3)
- #define SELECTED_P (1 << 4)
-
- typedef struct
- {
- guint attributes; /* 5 collective attributes above */
- image_buffer *image;
- GCHAR *name;
- GCHAR *info;
- gint selection_timestamp;
- } Thumbnail;
-
- typedef struct
- {
- GdkPixmap *pixmap;
- guchar *line_buffer;
- gint width;
- gint height;
- GdkGC *gc;
- GdkColor black;
- GdkColor white;
- } Pixmap_struct;
-
- /* attributes for directory_cache */
- /* #define DISPLAY_IMAGE_P shared with VALS */
- /* #define SORT_BY_NAME_P shared with VALS */
- #define FILED_P (1 << 2)
- #define DISORDERED_P (1 << 3)
-
- typedef struct
- {
- GCHAR name[PATH_LENGTH];
- guint attributes; /* filed and purged */
- gint birth_index;
- gshort savable; /* three values */
- Thumbnail *image;
- Thumbnail *dir;
- gint ndir;
- gint nimage;
- gint max_ndir;
- gint max_nimage;
- gint display_page;
- gint selection_timestamp;
- gint num_selection;
- gint selection_top;
- gint last_focus;
- gdouble timestamp;
- } directory_cache;
-
- typedef struct
- {
- GCHAR key;
- guint mod;
- } Gtk_binding;
-
- typedef struct
- {
- GCHAR *label;
- void (* command) (GtkWidget *, gpointer);
- gint sensitive;
- GtkWidget *widget;
- Gtk_binding binding[NBINDINGS];
- } image_command_table;
-
- typedef struct
- {
- GCHAR *action;
- GCHAR *condition;
- GCHAR *behavior;
- gint flush_left;
- } help_table;
-
- struct
- {
- gint width;
- gint height;
- gint ncol;
- gint nrow;
- gint nthumb_in_page;
- gint resized;
- gint current_page1;
- gint current_page;
- gint last_index;
- gint font_height;
- GCHAR info[256];
- } the_panel;
-
- typedef struct
- {
- gint index;
- gint selection_timestamp;
- Thumbnail *thumbnail;
- } selection_iterator_entry;
-
- typedef struct
- {
- gint length;
- gint unvisit_index;
- selection_iterator_entry *body;
- } selection_iterator;
-
- VALS VAL;
- directory_cache *cwd_cache = NULL;
- Thumbnail *the_loaded_data = NULL;
- image_buffer *banner;
- image_buffer *dir_icon;
- image_buffer *pdir_icon;
- image_buffer *file_icon;
- Pixmap_struct *text_buffer = NULL;
- GHashTable *directory_cache_table;
- gint directory_cache_max_images = 1024;
- gint directory_cache_table_max_size = DIRECTORY_CACHE_TABLE_MAX_SIZE;
- gint directory_cache_table_size = 0;
- GtkWidget *dlg = NULL;
- GtkWidget *cwd_label = NULL;
- GtkWidget *thumbnail_panel = NULL;
- GtkWidget *file_property = NULL;
- GtkWidget *thumbnail_panel_root_menu = NULL;
- GtkWidget *thumbnail_panel_selection_menu = NULL;
- GtkWidget *thumbnail_panel_hidden_menu = NULL;
- GCHAR **inhibit_suffix_table = NULL;
- gint num_inhibit_suffix = -1;
- gint selection_kind = FALSE;
- guchar thumbnail_colormap[256 * 3];
- GCHAR fileselector_last_pathname[PATH_LENGTH];
- gint guash_is_initialized = FALSE;
- GCHAR *guash_tmp_dir = NULL;
- gint binding_style = BINDING_GIMP;
- gint directory_monitor_interval = 0;
- guint delayed_updating = 0; /* This is not a flag: a kind of countable semaphore */
- guint during_buildup_thumbnail_panel = FALSE;
-
- #define NSCROLLER 2
- GtkWidget *widget_for_scroll[NSCROLLER];
-
- #ifdef NEW_DND_API
- enum {
- TARGET_STRING,
- };
-
- static GtkTargetEntry dnd_target_table[] =
- {
- { "STRING", 0, TARGET_STRING },
- { "text/plain", 0, TARGET_STRING },
- };
- static guint dnd_n_targets = sizeof(dnd_target_table) / sizeof(dnd_target_table[0]);
- #else
- gchar *possible_dnd_types[] = {"text/plain"};
- #endif
-
- #define NSELECTION_BUTTON 2
- GtkWidget *widget_for_selecion[NSELECTION_BUTTON];
-
- /* //HB: the old version of the macro. The new one uses INDEXED images
- * and a shared color map, defined in data/guash-banner.h
- */
- #ifndef INDEXED_HEADER
- #define HEADER_PIXEL(data,pixel) {\
- pixel[0] = (((data[0] - 33) << 2) | ((data[1] - 33) >> 4)); \
- pixel[1] = ((((data[1] - 33) & 0xF) << 4) | ((data[2] - 33) >> 2)); \
- pixel[2] = ((((data[2] - 33) & 0x3) << 6) | ((data[3] - 33))); \
- data += 4; }
- #endif
-
- #include "include/guash-f.h"
-
- #define MENU_SEPARATOR { NULL, NULL, 0, NULL, \
- { { 0, 0 }, \
- { 0, 0 } \
- } }
-
- image_command_table
- image_root_commands [] =
- {
- { "Next page", next_page_callback, SENSITIVE_SCROLL, NULL,
- { { ' ', 0 },
- { ' ', 0 }
- } },
- { "Prev page", prev_page_callback, SENSITIVE_SCROLL, NULL,
- { { 'B', 0 },
- { 'B', 0 }
- } },
- { "Selection All", select_all_callback, FALSE, NULL,
- { { 'A', GDK_CONTROL_MASK },
- { 'A', GDK_CONTROL_MASK }
- } },
- MENU_SEPARATOR,
- { "Make new directory", fileselector_for_mkdir_callback, FALSE, NULL,
- { { 'D', GDK_SHIFT_MASK },
- { '+', GDK_SHIFT_MASK }
- } },
- { "Change directory", fileselector_for_chdir_callback, FALSE, NULL,
- { { 'C', 0 },
- { 'D', GDK_CONTROL_MASK }
- } },
- { "Change to parent directory", parent_directory_callback, FALSE, NULL,
- { { '0', 0 },
- { '0', 0 }
- } },
- { "Update", update_callback, FALSE, NULL,
- { { 'R', 0 },
- { 'G', 0 }
- } },
- { "Change display mode", toggle_display_mode_callback, FALSE, NULL,
- { { 'S', GDK_SHIFT_MASK },
- { 'S', GDK_SHIFT_MASK }
- } },
- { "Change thumbnail save mode", toggle_save_mode_callback, FALSE, NULL,
- { { 'T', 0 },
- { 'T', 0 }
- } },
- { "Change sort mode", toggle_sort_mode_callback, FALSE, NULL,
- { { 'S', 0 },
- { 'S', 0 }
- } },
- { "Remove all thumbnail files", purge_thumbnail_file_callback, FALSE, NULL,
- { { 'R', GDK_MOD1_MASK },
- { 'P', GDK_MOD1_MASK }
- } },
- MENU_SEPARATOR,
- { "Help", help_callback, FALSE, NULL,
- { { '?', 0 },
- { 'H', GDK_CONTROL_MASK }
- } },
- { "Quit", gtkW_close_callback, FALSE, NULL,
- { { 'Q', 0 },
- { 'Q', GDK_CONTROL_MASK }
- } }
- };
-
- image_command_table
- image_selection_commands [] =
- {
- { "Open", open_callback, SENSITIVE_SELECTION, NULL,
- { { 'O', GDK_CONTROL_MASK },
- { 'O', GDK_CONTROL_MASK }
- } },
- #ifdef GIMP_HAVE_PARASITES
- { "Show comment", show_comment_callback, SENSITIVE_SELECTION, NULL,
- { { 'C', GDK_SHIFT_MASK },
- { 'C', GDK_SHIFT_MASK }
- } },
- #endif
- { "Selection None", select_none_callback, FALSE, NULL,
- { { 'A', GDK_CONTROL_MASK|GDK_SHIFT_MASK },
- { 'A', GDK_CONTROL_MASK|GDK_SHIFT_MASK }
- } },
- MENU_SEPARATOR,
- { "Copy to...", fileselector_for_copy_callback, SENSITIVE_SELECTION, NULL,
- { { 'C', GDK_CONTROL_MASK },
- { 'C', GDK_CONTROL_MASK }
- } },
- { "Move to...", fileselector_for_move_callback, SENSITIVE_SELECTION, NULL,
- { { 'V', GDK_CONTROL_MASK },
- { 'R', GDK_CONTROL_MASK }
- } },
- { "Map script-fu on...", selection_map_script_callback, SENSITIVE_SELECTION, NULL,
- { { 'X', 0 },
- { '!', GDK_SHIFT_MASK }
- } },
- { "Map unix command on...", selection_map_unix_command_callback, SENSITIVE_SELECTION, NULL,
- { { 'X', GDK_SHIFT_MASK },
- { '|', GDK_SHIFT_MASK }
- } },
- { "Delete the thumbnail files", purge_selected_thumbnail_file_callback, SENSITIVE_SELECTION, NULL,
- { { 'T', GDK_CONTROL_MASK },
- { 'T', GDK_MOD1_MASK }
- } },
- MENU_SEPARATOR,
- { "Root menu", NULL, FALSE, NULL,
- { { 0, 0 },
- { 0, 0 }
- } },
- MENU_SEPARATOR,
- { "Delete the selected files", delete_callback, SENSITIVE_SELECTION, NULL,
- { { 'X', GDK_CONTROL_MASK },
- { 'D', GDK_MOD1_MASK }
- } }
- };
-
- image_command_table
- image_hidden_commands [] =
- {
- { "Forward image", forward_callback, FALSE, NULL,
- { { 'F', 0 },
- { 'F', GDK_CONTROL_MASK }
- } },
- { "Backward image", backward_callback, FALSE, NULL,
- { { 'B', 0 },
- { 'B', GDK_CONTROL_MASK }
- } },
- { "Down image", next_callback, FALSE, NULL,
- { { 'D', 0 },
- { 'N', GDK_CONTROL_MASK }
- } },
- { "Up image", prev_callback, FALSE, NULL,
- { { 'U', 0 },
- { 'P', GDK_CONTROL_MASK }
- } },
- { "Select then go forward", select_and_forward_callback, FALSE, NULL,
- { { ' ', GDK_CONTROL_MASK },
- { ' ', GDK_CONTROL_MASK }
- } },
- { "Jump to subdirectory1", jump_to_subdir1_callback, FALSE, NULL,
- { { '1', 0 },
- { '1', 0 }
- } },
- { "Jump to subdirectory2", jump_to_subdir2_callback, FALSE, NULL,
- { { '2', 0 },
- { '2', 0 }
- } },
- { "Jump to subdirectory3", jump_to_subdir3_callback, FALSE, NULL,
- { { '3', 0 },
- { '3', 0 }
- } },
- { "Jump to subdirectory4", jump_to_subdir4_callback, FALSE, NULL,
- { { '4', 0 },
- { '4', 0 }
- } },
- { "Jump to subdirectory5", jump_to_subdir5_callback, FALSE, NULL,
- { { '5', 0 },
- { '5', 0 }
- } },
- { "Jump to subdirectory6", jump_to_subdir6_callback, FALSE, NULL,
- { { '6', 0 },
- { '6', 0 }
- } },
- { "Jump to subdirectory7", jump_to_subdir7_callback, FALSE, NULL,
- { { '7', 0 },
- { '7', 0 }
- } },
- { "Jump to subdirectory8", jump_to_subdir8_callback, FALSE, NULL,
- { { '8', 0 },
- { '8', 0 }
- } },
- { "Jump to subdirectory9", jump_to_subdir9_callback, FALSE, NULL,
- { { '9', 0 },
- { '9', 0 }
- } }
- };
- #undef MENU_SEPARATOR
-
- #define DOCUMENT_SEPARATOR { NULL, NULL, NULL, FALSE }
- #define CENTERING FALSE
- #define ALIGN_LEFT TRUE
-
- help_table
- help_document [] =
- {
- { NULL, "Gimp Users' Another SHell", NULL, CENTERING},
- { NULL, GUASH_VERSION, NULL, CENTERING},
- DOCUMENT_SEPARATOR,
- { "ACTION", "CONDITION", "COMMAND", CENTERING },
- /* -------------------- */
- { "Left-click", "on unselected image file",
- "Select only the image file", ALIGN_LEFT },
- { "Left-click", "on selected image file",
- "Open the selected image files", ALIGN_LEFT },
- { "Left-click", "on directory",
- "Jump to the directory", ALIGN_LEFT },
- { "Shift + Left-click", "on image file",
- "Add/delete the file to/from selection", ALIGN_LEFT },
- { "Control + Left-click", "on directory & active selection",
- "Copy selected files to the directory", ALIGN_LEFT },
- { "Shift + Left-click", "on directory & active selection",
- "Move selected files to the directory", ALIGN_LEFT },
- { "Middle-click", NULL,
- "Go to the next page of panel", ALIGN_LEFT },
- { "Shift + Middle-click", NULL,
- "Go to the pevious page of panel", ALIGN_LEFT },
- { "Right-click", "no selection",
- "Open root menu", ALIGN_LEFT },
- { "Right-click", "active selection",
- "Open selection menu", ALIGN_LEFT },
- { "Shift + Right-click", NULL,
- "Open root menu", ALIGN_LEFT },
- DOCUMENT_SEPARATOR,
- { NULL, "You can set options through your gimprc file like:", NULL, CENTERING },
- { NULL, "(guash-option-string \"NEIXNA\") ; default is \"CGIXNM\"", NULL, CENTERING },
- { NULL, "Each character means (do Confirm/Not), (key-binding Gimp/Emacs), (show Images/Files), ", NULL, CENTERING },
- { NULL, "(thumbnail Xv/Guash/Unsave), (sort Name/Date), (update Automatically/Manually) respectively.", NULL, CENTERING }
- };
-
- #undef DOCUMENT_SEPARATOR
- #undef CENTERING
- #undef ALIGN_LEFT
-
- GPlugInInfo PLUG_IN_INFO =
- {
- NULL, /* init_proc */
- NULL, /* quit_proc */
- query, /* query_proc */
- run, /* run_proc */
- };
-
- MAIN ()
-
- static void
- query ()
- {
- /* NOTE: `[] = {}' is illegal on MIPS C++ */
-
- static GParamDef eargs [] =
- {
- { PARAM_INT32, "run_mode", "Interactive, non-interactive"},
- { PARAM_STRING, "directory_name", "directory name used as the default directory" },
- };
- static GParamDef pargs [] =
- {
- { PARAM_INT32, "run_mode", "Interactive, non-interactive"},
- { PARAM_IMAGE, "image", "Input image" },
- { PARAM_DRAWABLE, "drawable", "drawable (unused)" },
- };
- static GParamDef *return_vals = NULL;
-
- static GParamDef sargs [] =
- {
- { PARAM_STRING, "file_name", "the filename that defines selection for script-fu"},
- };
- static GParamDef srets [] =
- {
- { PARAM_STRING, "file_name", "the filename that defines selection for script-fu"},
- };
-
- static int neargs = sizeof (eargs) / sizeof (eargs[0]);
- static int nreturn_vals = 0;
- static int npargs = sizeof (pargs) / sizeof (pargs[0]);
- static int nsargs = sizeof (sargs) / sizeof (sargs[0]);
- static int nsrets = sizeof (srets) / sizeof (srets[0]);
-
- gimp_install_procedure (PLUG_IN_NAME,
- "Thumbnail-based directory browser",
- "Thumbnail-based directory browser",
- "Shuji Narazaki <narazaki@gimp.org>",
- "Shuji Narazaki",
- "1997, 1998",
- MENU_PATH_AS_EXTENSION,
- "",
- PROC_EXTENSION,
- neargs, nreturn_vals,
- eargs, return_vals);
- gimp_install_procedure (PLUG_IN_NAME_SUB,
- "Thumbnail-based directory browser",
- "Thumbnail-based directory browser",
- "Shuji Narazaki <narazaki@gimp.org>",
- "Shuji Narazaki",
- "1997, 1998",
- MENU_PATH_AS_PLUG_IN,
- "",
- PROC_PLUG_IN,
- npargs, nreturn_vals,
- pargs, return_vals);
- gimp_install_procedure (PLUG_IN_NAME_FOR_SELECTION,
- "Return the name of the file that defines %guash-selection",
- "Return the name of the file that defines %guash-selection",
- "Shuji Narazaki <narazaki@gimp.org>",
- "Shuji Narazaki",
- "1997, 1998",
- NULL,
- "",
- PROC_PLUG_IN,
- nsargs, nsrets,
- sargs, srets);
- }
-
- static void
- run (char *name,
- int nparams,
- GParam *param,
- int *nreturn_vals,
- GParam **return_vals)
- {
- GParam *values;
- GStatusType status = STATUS_EXECUTION_ERROR;
- GRunModeType run_mode;
-
- DEBUGBLOCK (N_("run\n"));
-
- if (strcmp (name, PLUG_IN_NAME_FOR_SELECTION) == 0)
- {
- GCHAR tmp[128];
- values = g_new (GParam, 2);
- *nreturn_vals = 2;
- *return_vals = values;
- #if 0
- strcpy (tmp, "/tmp/guash0000.scm");
- #else
- /* //HB: use glib function for portability */
- strcpy (tmp, g_get_tmp_dir ());
- strcat (tmp, G_DIR_SEPARATOR_S "guash0000.scm");
- #endif
- /* gimp_get_data (PLUG_IN_NAME_FOR_SELECTION, &tmp); */
- values[0].type = PARAM_STATUS;
- values[0].data.d_status = STATUS_SUCCESS;
- values[1].type = PARAM_STRING;
- strcpy (tmp, param[0].data.d_string);
- values[1].data.d_string = g_strdup (tmp);
- DPRINT (N_("delete %s\n"), tmp);
- os_delete_file (tmp);
- RETURN;
- }
-
- values = g_new (GParam, 1);
- run_mode = param[0].data.d_int32;
-
- *nreturn_vals = 1;
- *return_vals = values;
-
- values[0].type = PARAM_STATUS;
- values[0].data.d_status = status;
-
- DPRINT (N_("guash is just started.\n"));
- #if defined(_DEBUG) && defined(G_OS_WIN32)
- g_warning("Guash needs DEBUGGING!");
- {
- int i;
- for (i = 0; i < 20; i ++)
- {
- Sleep(1000);
- g_print(".");
- }
- }
- #endif
- switch (run_mode)
- {
- case RUN_INTERACTIVE:
- case RUN_WITH_LAST_VALS:
- SET_ATTRIBUTE (&VAL, DISPLAY_IMAGE_P);
- SET_ATTRIBUTE (&VAL, SAVE_AS_XVPICT_P);
- SET_ATTRIBUTE (&VAL, SAVE_AS_GPICT_P);
- SET_ATTRIBUTE (&VAL, SORT_BY_NAME_P);
- VAL.mapping_command[0] = VAL.last_dir_name[0] = 0;
- gimp_get_data (PLUG_IN_NAME, &VAL);
-
- if (strcmp (name, PLUG_IN_NAME_SUB) == 0)
- {
- GCHAR *str = guash_get_image_filename (param[1].data.d_image);
-
- if (str)
- {
- GCHAR *dir = pathname_get_directoryname (str);
-
- if (dir)
- {
- strcpy (VAL.last_dir_name, dir);
- g_free (dir);
- }
- g_free (str);
- }
- }
-
- directory_cache_table = g_hash_table_new ((GHashFunc) g_str_hash,
- (GCompareFunc) g_str_equal);
- if (0 < strlen (VAL.last_dir_name))
- os_file_change_current_directory (VAL.last_dir_name);
-
- dir_icon = image_buffer_new_with_header (dir_icon_data,
- dir_icon_width,
- dir_icon_height);
- pdir_icon = image_buffer_new_with_header (pdir_icon_data,
- pdir_icon_width,
- pdir_icon_height);
- file_icon = image_buffer_new_with_header (file_icon_data,
- file_icon_width,
- file_icon_height);
-
- DPRINT (N_("icons are set\n"));
- /* Let's set rational options of ps file hander for guash. */
- {
- GParam* return_vals;
- gint retvals;
- /* //HB: ... but first query if available */
- char *proc_blurb, *proc_help, *proc_author, *proc_copyright, *proc_date;
- int proc_type, nparams, nreturn_vals;
- GParamDef *params1, *params2;
-
- if (gimp_query_procedure("file_ps_load_setargs",
- &proc_blurb, &proc_help,
- &proc_author, &proc_copyright, &proc_date,
- &proc_type, &nparams, &nreturn_vals,
- ¶ms1, ¶ms2)) {
- /* now dismiss unneded information; wouldn't it be nice
- * to don't get unneeded by setting NULL pointers?
- */
- g_free(proc_blurb);
- g_free(proc_help);
- g_free(proc_author);
- g_free(proc_date);
- gimp_destroy_paramdefs (params1, nparams);
-
- if (nreturn_vals && return_vals[0].data.d_status == STATUS_SUCCESS) {
- /* first destruct old parameters */
- gimp_destroy_paramdefs (params2, nreturn_vals);
-
- /* finally run file_ps_load */
-
- return_vals = gimp_run_procedure ("file_ps_load_setargs",
- &retvals,
- PARAM_INT32, 75, /* resolution */
- PARAM_INT32, THUMBNAIL_WIDTH,
- PARAM_INT32, THUMBNAIL_HEIGHT,
- PARAM_INT32, 1, /* use BBox */
- PARAM_STRING, "1", /* only 1 page */
- PARAM_INT32, 7, /* automatic color */
- PARAM_INT32, 1, /* text alpha */
- PARAM_INT32, 1,
- PARAM_END);
- gimp_destroy_params (return_vals, retvals);
- }
- }
- }
-
- DPRINT (N_("open dialog\n"));
- DIALOG ();
- DPRINT (N_("success to close the dialog\n"));
-
- gimp_displays_flush();
- if (strcmp (name, PLUG_IN_NAME) == 0)
- gimp_set_data (PLUG_IN_NAME, &VAL, sizeof (VALS));
- status = STATUS_SUCCESS;
- break;
- case RUN_NONINTERACTIVE:
- break;
- }
-
- g_hash_table_destroy (directory_cache_table);
-
- image_buffer_free (banner);
- image_buffer_free (dir_icon);
- image_buffer_free (pdir_icon);
- image_buffer_free (file_icon);
-
- g_free (inhibit_suffix_table);
-
- DPRINT (N_("success to free memory chunks\n"));
-
- values[0].type = PARAM_STATUS;
- values[0].data.d_status = status;
-
- DEBUGEND;
- }
-
- static guchar *
- indexed_to_rgb (guchar data, guchar *dest)
- {
- guchar *color = thumbnail_colormap + (data * 3);
-
- *dest++ = *color++;
- *dest++ = *color++;
- *dest++ = *color;
-
- return dest;
- }
-
- /*
- * guash classes for packing misc functions
- */
- static void
- guash_build_thumbnail_colormap ()
- {
- gint i;
- guchar *ptr = thumbnail_colormap;
-
- for (i = 0; i < 256; i++)
- {
- *ptr++ = (((i >> 5) & 0x07) * 255) / 7;
- *ptr++ = (((i >> 2) & 0x07) * 255) / 7;
- *ptr++ = (((i >> 0) & 0x03) * 255) / 3;
- }
- }
-
- static void
- guash_build_inhibit_suffix_table (GCHAR *buffer)
- {
- GCHAR *ptr = buffer;
- GCHAR **chunk;
- gint chunk_index = 0;
- gint chunk_size = 8;
-
- DEBUGBLOCK (N_("guash_build_inhibit_suffix_table (\"%s\")\n"), buffer);
-
- chunk = g_new (GCHAR *, chunk_size);
-
- while (*ptr != 0)
- {
- gint index = 0;
- GCHAR *new_str;
-
- while ((*(ptr + index) != ':') && (*(ptr + index) != 0))
- index++;
-
- if (0 < index)
- {
- new_str = g_malloc (index + 1); /* end of str */
- g_memmove (new_str, ptr, index);
- new_str[index] = 0;
-
- if (chunk_size <= chunk_index)
- {
- DPRINT (N_("Exapnd chunk(%s) size: %d..."), chunk[chunk_index -1], chunk_size);
- chunk_size *= 2;
- #ifdef GIMP_HAVE_PARASITES
- /* This condition is not true one. I'd like to check glib
- version. */
- chunk = g_renew (GCHAR *, chunk, chunk_size);
- #else
- chunk = g_realloc ((gpointer) chunk,
- chunk_size * sizeof (GCHAR *));
- #endif
- DPRINT (N_("done\n"));
- }
- chunk[chunk_index++] = new_str;
- }
- if (*(ptr + index) == 0)
- break;
- else
- ptr += index + 1;
- }
-
- inhibit_suffix_table = chunk;
- num_inhibit_suffix = chunk_index;
-
- RETURN;
- }
-
- static gint
- guash_change_current_directory (GCHAR *pathname, Thumbnail *thumbnail)
- {
- DEBUGBLOCK (N_("guash_change_directory (\"%s\")\n"), pathname);
-
- if (-1 == os_file_change_current_directory (pathname))
- {
- GCHAR tmp[LINE_BUF_SIZE];
-
- if (thumbnail != NULL)
- {
- cwd_cache->timestamp = os_file_get_modify_timestamp (cwd_cache->name);
- SET_ATTRIBUTE (thumbnail, DELETED_P);
- guash_update_cwd_cache (GC);
- }
- sprintf (tmp, "Abort: %s does not exist now", pathname);
- thumbnail_panel_set_info (tmp);
- RETURN FALSE;
- }
- else
- {
- guash_update_cwd_cache (REDRAW);
- RETURN TRUE;
- }
- }
-
- static gint
- guash_confirm_operation (GCHAR *operation_phrase)
- {
- gint flag = TRUE;
-
- if (! selection_is_active ())
- return flag;
-
- G_ASSERT (HAS_ATTRIBUTE (directory_cache_get_nth (cwd_cache,
- cwd_cache->selection_top),
- SELECTED_P));
-
- if (HAS_ATTRIBUTE (&VAL, CONFIRM_P))
- {
- GCHAR buffer [LINE_BUF_SIZE];
-
- if (selection_length () == 1)
- {
- Thumbnail *selected;
-
- selected = directory_cache_get_nth (cwd_cache, cwd_cache->selection_top);
- sprintf (buffer, _(" %s the selected image: %s? \n\
- Guash is NO WARRANTY program. "),
- operation_phrase,
- selected->name);
- }
- else
- {
- sprintf (buffer, _(" %s the selected %d images? \n\
- Guash is NO WARRANTY program. "),
- operation_phrase,
- selection_length ());
- }
-
- if (! gtkW_confirmor_dialog (TRUE, buffer, FALSE))
- flag = FALSE;
- }
-
- return flag;
- }
-
- static gint
- guash_discard_events ()
- {
- gint invalids = FALSE;
- gint redraw = FALSE;
- GdkEvent *e;
-
- DEBUGBLOCK (N_("guash_discard_events\n"));
- /*
- * Tue May 12 20:49:27 1998
- * gtk+ FAQ uses gtk_events_pending (), but it returns 1 anytime.
- * On the other hand, gdk_events_pending () returns zero if no events!
- * That's what I want!
- */
- while (gdk_events_pending ())
- {
- if ((e = gdk_event_get ()) != NULL)
- {
- switch (e->type)
- {
- case GDK_BUTTON_PRESS:
- case GDK_2BUTTON_PRESS:
- case GDK_3BUTTON_PRESS:
- case GDK_KEY_PRESS:
- invalids = TRUE;
- gdk_event_free (e);
- break;
- case GDK_EXPOSE:
- redraw = TRUE;
- gdk_event_free (e);
- default:
- gtk_main_iteration ();
- break;
- }
- }
- }
- if (redraw)
- gtk_widget_queue_draw (dlg);
-
- RETURN invalids;
- }
-
- static GCHAR *
- guash_generate_unix_command (GCHAR *template, GCHAR *directory, GCHAR *filename)
- {
- GCHAR *new = NULL, *tmp;
- gint index = -1;
- gint directory_p = FALSE;
- gint i = 0;
-
- for (tmp = template; *tmp; tmp++, i++)
- {
- if ((*tmp == '{') && (*(tmp + 1) == '}'))
- {
- directory_p = FALSE;
- index = i;
- break;
- }
- if ((*tmp == '%') && (*(tmp + 1) == '%'))
- {
- directory_p = TRUE;
- index = i;
- break;
- }
- }
- if (-1 < index)
- {
- if (directory_p)
- new = g_malloc (strlen (template) + strlen (directory) + 1);
- else
- new = g_malloc (strlen (template)
- + strlen (directory) + strlen (filename) + 1);
- i = index;
- g_memmove (new, template, i);
- if (directory_p)
- {
- g_memmove (new + i, directory, strlen (directory));
- i += strlen (directory);
- }
- else
- {
- g_memmove (new + i, filename, strlen (filename));
- i += strlen (filename);
- }
- g_memmove (new + i, template + index + 2, strlen (template) - index - 2);
- i += strlen (template) - index - 2;
- new[i] = 0;
-
- tmp = guash_generate_unix_command (new, directory, filename);
- g_free (new);
- return tmp;
- }
- else
- {
- return g_strdup (template);
- }
- }
-
- static GCHAR *
- guash_get_image_filename (gint image_id)
- {
- GCHAR *path = gimp_image_get_filename (image_id);
-
- if (pathname_get_last_separator_index (path) < 0)
- {
- GCHAR tmp[PATH_LENGTH];
- gint index;
-
- os_file_get_current_directory (tmp);
- index = strlen (tmp);
- tmp[index] = G_DIR_SEPARATOR;
- g_memmove (tmp + index + 1, path, strlen (path) + 1);
- g_free (path);
- path = g_strdup (tmp);
- }
- return path;
- }
-
- static Thumbnail *
- guash_build_thumbnail_from_gimage (gint32 i_id, GCHAR *pathname)
- {
- gint32 d_id;
- gint new_width, new_height;
- gint width, height;
- GCHAR image_type[16];
- GParam* return_vals;
- gint retvals;
- GCHAR info[256];
-
- DEBUGBLOCK (N_("guash_build_thumbnail_from_gimage (%d, \"%s\")\n"),
- i_id, pathname);
-
- if (gimp_image_base_type (i_id) != RGB)
- {
- if (gimp_image_base_type (i_id) == INDEXED)
- strcpy (image_type, "Indexed file");
- else
- strcpy (image_type, "Gray file");
-
- DPRINT (N_("convert image to RGB\n"));
-
- return_vals = gimp_run_procedure ("gimp_convert_rgb",
- &retvals,
- PARAM_IMAGE, i_id,
- PARAM_END);
- gimp_destroy_params (return_vals, retvals);
- }
- else
- strcpy (image_type, "RGB file");
-
- new_width = width = gimp_image_width (i_id);
- new_height = height = gimp_image_height (i_id);
-
- if (THUMBNAIL_HEIGHT < new_height)
- {
- new_width = new_width * THUMBNAIL_HEIGHT / new_height;
- new_height = THUMBNAIL_HEIGHT;
- }
- if (THUMBNAIL_WIDTH < new_width)
- {
- new_height = new_height * THUMBNAIL_WIDTH / new_width;
- new_width = THUMBNAIL_WIDTH;
- }
- if (new_width < 2) new_width = 2;
- if (new_height < 2) new_height = 2;
-
- {
- guchar tr[] = BASE_COLOR;
- guchar bg[3];
-
- gimp_palette_get_background (bg, bg + 1, bg + 2);
- gimp_palette_set_background (tr[0], tr[1], tr[2]);
- gimp_image_flatten (i_id);
- gimp_palette_set_background (bg[0], bg[1], bg[2]);
- }
-
- d_id = gimp_image_get_active_layer (i_id);
- G_ASSERT (0 <= d_id);
-
- if ((width != new_width) || (height != new_height))
- {
- gimp_layer_scale (d_id, new_width, new_height, 0);
- DPRINT (N_("resized to thumbnail size.\n"));
- }
-
- sprintf (info, "%dx%d %s (%d bytes)",
- width, height,
- image_type, os_file_size (pathname));
- gimp_layer_set_name (d_id, info);
-
- if (the_loaded_data->name)
- g_free (the_loaded_data->name);
- the_loaded_data->name = g_strdup (pathname_get_basename (pathname));
-
- if (the_loaded_data->info)
- g_free (the_loaded_data->info);
- {
- GCHAR tmp[PATH_LENGTH];
- #ifdef GIMP_HAVE_PARASITES
- Parasite *para = NULL;
-
- para = gimp_image_parasite_find (i_id, "gimp-comment");
- if ((para != NULL) && (0 < para->size))
- {
- GCHAR comment[242];
- GCHAR *src = (GCHAR *) para->data;
- gint i;
-
- /* maybe newline in info field in xv thumbnail causes a trouble. */
- for (i = 0; i < 241; i++)
- {
- if (!(comment[i] = *src++))
- break;
- if (comment[i] == '\n')
- {
- comment[i] = 0;
- break;
- }
- }
- DPRINT (N_("found gimp-comment parasite: %s\n"), comment);
- sprintf (tmp, "%s %s \"%s\"", the_loaded_data->name, info, comment);
- }
- else
- sprintf (tmp, "%s %s", the_loaded_data->name, info);
- if (para != NULL)
- parasite_free (para);
- #else
- sprintf (tmp, "%s %s", the_loaded_data->name, info);
- #endif
- the_loaded_data->info = g_strdup (tmp);
- }
-
- image_buffer_copy_drawable (the_loaded_data->image, d_id);
-
- RETURN the_loaded_data;
- }
-
- /* if thumbnail_p is non-FALSE, check only thumbnail */
- static Thumbnail *
- guash_get_image_from_file (GCHAR *pathname, gint thumbnail_p)
- {
- GParam* return_vals;
- gint retvals;
- gint32 i_id;
-
- DEBUGBLOCK (N_("guash_get_image_from_file (\"%s\", %d)\n"),
- pathname, thumbnail_p);
- G_ASSERT (*pathname == G_DIR_SEPARATOR);
-
- if (thumbnail_p) /* thumbnail file */
- pathname = pathname_build_thumbnail_filename (pathname);
-
- DPRINT (N_("thumbnail_file is \"%s\"\n"), pathname);
-
- if ((os_file_kind (pathname, TRUE)) == NOT_EXIST)
- {
- DPRINT (N_("%s is not found\n"), pathname);
- RETURN NULL;
- }
-
- if (thumbnail_p)
- {
- Thumbnail *thumb = load_xvpict_image (pathname);
-
- DPRINT (N_("cache is%s found\n"), (thumb == NULL) ? " not" : "");
- RETURN thumb;
- }
-
- return_vals = gimp_run_procedure ("gimp_file_load",
- &retvals,
- PARAM_INT32, RUN_NONINTERACTIVE,
- PARAM_STRING, pathname,
- PARAM_STRING, pathname,
- PARAM_END);
- if (return_vals[0].data.d_status != STATUS_SUCCESS)
- {
- gimp_destroy_params (return_vals, retvals);
-
- DPRINT (N_("fail to load (maybe non-image file)\n"));
- RETURN NULL;
- }
- else
- #if 0
- gimp_destroy_params (return_vals, retvals);
-
- i_id = return_vals[1].data.d_image;
- #else
- {
- /* //HB: bug in original source:
- * change: first set i_id, then destroy
- */
- i_id = return_vals[1].data.d_image;
- gimp_destroy_params (return_vals, retvals);
- }
- #endif
-
- DPRINT (N_("loaded from the file\n"));
-
- /* Some file-loader returns STATUS_SUCCESS even if it fails to load !!! */
- if ((i_id < 0) || (gimp_image_get_active_layer (i_id) < 0))
- {
- DPRINT (N_("failed to loading (i_id:%d, active_layer:%d)\n"),
- i_id, gimp_image_get_active_layer (i_id));
- if (0 <= i_id)
- gimp_image_delete (i_id);
- RETURN NULL;
- }
- gimp_image_undo_disable (i_id);
- guash_build_thumbnail_from_gimage (i_id, pathname);
- gimp_image_delete (i_id);
-
- RETURN the_loaded_data;
- }
-
- static directory_cache *
- guash_lookup_directory_cache (GCHAR *dir)
- {
- return (directory_cache *) g_hash_table_lookup (directory_cache_table,
- (gpointer) dir);
- }
-
- static void
- guash_parse_gimprc ()
- {
- GCHAR buf[LINE_BUF_SIZE];
- gint tmp = 0;
-
- DEBUGBLOCK (N_("guash_parse_gimprc\n"));
-
- gtkW_parse_gimprc_string ("guash-option-string", buf);
- if (strlen (buf) == 6)
- {
- GCHAR *ptr = buf;
-
- #define c_l_eq_p_(C, c) ((('a' - 'A') | (C)) == (c))
- SET_TO_ATTRIBUTE (&VAL, CONFIRM_P, c_l_eq_p_ (*ptr++, 'c'));
- binding_style = c_l_eq_p_ (*ptr++, 'e') ? BINDING_EMACS : BINDING_GIMP;
- SET_TO_ATTRIBUTE (&VAL, DISPLAY_IMAGE_P, (! c_l_eq_p_ (*ptr++, 'f')));
- SET_TO_ATTRIBUTE (&VAL, SAVE_AS_XVPICT_P, (! c_l_eq_p_ (*ptr, 'u')));
- /*
- * o an EXPERIMENTAL 16bit color thumbnail format. NO DOCUMENT.
- * NO COMPRESSION (the size reaches to 10KB!) THE FORMAT MIGHT BE
- * MODIFIED/DISCARED IN FUTURE RELEASE.
- */
- SET_TO_ATTRIBUTE (&VAL, SAVE_AS_GPICT_P, c_l_eq_p_ (*ptr++, 'g'));
- SET_TO_ATTRIBUTE (&VAL, SORT_BY_NAME_P, (! c_l_eq_p_ (*ptr++, 'd')));
- SET_TO_ATTRIBUTE (&VAL, MONITOR_P, c_l_eq_p_ (*ptr, 'a'));
- #undef c_l_eq_p_
- }
- else if (0 < strlen (buf))
- g_warning ("The length of guash-option-string is not 6. Ignored.");
-
- gtkW_parse_gimprc_string ("guash-inhibit-suffix", buf);
- if (*buf == 0)
- strcpy (buf, GUASH_INHIBIT_SUFFIX_TABLE_DEFAULT);
- guash_build_inhibit_suffix_table (buf);
-
- gtkW_parse_gimprc_string ("guash-mapping-command", buf);
- if (*buf == 0)
- strcpy (buf, MAPPING_COMMAND_DEFAULT);
- if ((VAL.mapping_command == NULL) || strlen (VAL.mapping_command) == 0)
- strcpy (VAL.mapping_command, buf);
-
- tmp = gtkW_parse_gimprc_gint ("guash-max-images-in-dir",
- directory_cache_max_images);
- if (0 < tmp)
- directory_cache_max_images = CLAMP (tmp, 1, 2000);
- else
- directory_cache_max_images = -1;
-
- tmp = 0;
- tmp = gtkW_parse_gimprc_gint ("guash-directory-history-length",
- directory_cache_table_max_size);
- if (0 <= tmp)
- directory_cache_table_max_size = CLAMP (tmp, 1, 16);
- else
- directory_cache_table_max_size = -1;
-
- directory_monitor_interval = DIRECTORY_MONITOR_INTERVAL_DEFAULT * 1000;
- tmp = 0;
- tmp = gtkW_parse_gimprc_gint ("guash-directory-monitor-interval", tmp);
- if (0 < tmp)
- directory_monitor_interval = CLAMP (tmp, 1, 200) * 1000;
-
- gtkW_parse_gimprc_string ("temp-path", buf);
- #if 0
- guash_tmp_dir = *buf ? g_strdup (buf) : "/tmp";
- #else
- /* //HB: use glib function for portability
- * Do I really need g_strdup () for it?
- */
- guash_tmp_dir = *buf ? g_strdup (buf) : g_strdup (g_get_tmp_dir ());
- #endif
- if (guash_tmp_dir[strlen (guash_tmp_dir) - 1] == G_DIR_SEPARATOR)
- guash_tmp_dir[strlen (guash_tmp_dir) - 1] = 0;
-
- RETURN;
- }
-
- static void
- guash_set_fileselector_last_value (GCHAR *pathname)
- {
- if (os_file_kind (pathname, TRUE) == DIRECTORY)
- {
- strcpy (fileselector_last_pathname, pathname);
- }
- else
- {
- gint len;
-
- strcpy (fileselector_last_pathname,
- pathname_get_directoryname (pathname));
- len = strlen (fileselector_last_pathname);
- fileselector_last_pathname[len] = G_DIR_SEPARATOR;
- fileselector_last_pathname[len + 1] = 0;
- }
- }
-
- static directory_cache *
- guash_update_cwd_cache (gint mode)
- {
- /* mode is either of
- RESCAN: to build w/o current information
- REDRAW: only to update panel
- GC: to remove unexisting files from panel
- */
- gpointer ptr = NULL;
- GCHAR dir[PATH_LENGTH];
-
- os_file_get_current_directory (dir);
-
- DEBUGBLOCK (N_("guash_update_cwd_cache (%d) at %s\n"), mode, dir);
-
- G_ASSERT (mode == RESCAN || mode == GC || mode == REDRAW);
-
- if ((ptr = g_hash_table_lookup (directory_cache_table, (gpointer) dir)))
- {
- cwd_cache = (directory_cache *) ptr;
-
- DPRINT (N_("found directory_cache for %s\n"), dir);
-
- g_hash_table_foreach (directory_cache_table,
- directory_cache_table_aging,
- NULL);
- cwd_cache->birth_index = directory_cache_table_size;
- DPRINT (N_("success to LRU ordering to directory_caches\n"));
-
- if (mode == RESCAN)
- {
- cwd_cache_update ();
- }
- else if (mode == GC)
- {
- directory_cache_garbage_collect (cwd_cache);
- }
- else
- {
- if ((HAS_NO_ATTRIBUTE (cwd_cache, DISPLAY_IMAGE_P)
- && HAS_ATTRIBUTE (&VAL, DISPLAY_IMAGE_P))
- || (HAS_ATTRIBUTE (cwd_cache, DISPLAY_IMAGE_P)
- && HAS_NO_ATTRIBUTE (&VAL, DISPLAY_IMAGE_P))
- || (HAS_ATTRIBUTE (cwd_cache, SORT_BY_NAME_P)
- && HAS_NO_ATTRIBUTE (&VAL, SORT_BY_NAME_P))
- || (HAS_NO_ATTRIBUTE (cwd_cache, SORT_BY_NAME_P)
- && HAS_ATTRIBUTE (&VAL, SORT_BY_NAME_P)))
- cwd_cache_update ();
- else
- {
- if (HAS_ATTRIBUTE (cwd_cache, DISORDERED_P))
- {
- directory_cache_garbage_collect (cwd_cache);
- DPRINT (N_("success to garbage collect\n"));
- }
- else
- thumbnail_panel_update ();
- }
- }
- }
- else
- {
- if ((0 < directory_cache_table_max_size) &&
- (directory_cache_table_max_size <= directory_cache_table_size))
- {
- directory_cache *tmp = NULL;
-
- DPRINT (N_("recycle directory_cache\n"));
- /* First, set cwd_cache to NULL. */
- cwd_cache = NULL;
- /* Second: map recycler.
- * Recycler sets one of the oldest entries to cwd_cache
- * and sets the 1st entry of directory hashtable to tmp. */
- g_hash_table_foreach (directory_cache_table,
- directory_cache_table_recycler,
- (gpointer) &tmp);
- if (cwd_cache) /* recycler worked fine, finding an entry! */
- {
- /* Then, delete it from directory_cache_table */
- g_hash_table_remove (directory_cache_table, cwd_cache->name);
- /* Finally, set the name as the new key */
- strcpy (cwd_cache->name, dir);
- directory_cache_initialize (cwd_cache);
- cwd_cache->birth_index = directory_cache_table_max_size;
- }
- else /* should not happen! FAILSAFE path */
- {
- if (tmp == NULL)
- {
- printf ("CATASTROPHIC ERROR: CACHE RECYCLE FAILED!!!\n");
- cwd_cache = directory_cache_new (dir);
- }
- else
- {
- printf ("Warning: directory_cache recycle failed (%s)!\n", tmp->name);
- cwd_cache = tmp;
- /* tmp is born again as cwd_cache */
- cwd_cache->birth_index = directory_cache_table_size;
- }
- }
- }
- else
- {
- if (0 < directory_cache_table_max_size)
- directory_cache_table_size++;
-
- DPRINT (N_("making a new directory_cache...\n"));
- cwd_cache = directory_cache_new (dir);
- DPRINT (N_("making a new directory_cache... done\n"));
- }
- g_hash_table_insert (directory_cache_table,
- cwd_cache->name,
- (gpointer) cwd_cache);
-
- cwd_cache_update ();
- }
- directory_cache_auto_shrink (cwd_cache, FALSE);
- strcpy (VAL.last_dir_name, cwd_cache->name);
-
- RETURN cwd_cache;
- }
-
- static gint
- guash_add_entry (GCHAR *pathname, Thumbnail *thumb)
- {
- GCHAR *dirname;
- directory_cache *dcache;
-
- DEBUGBLOCK (N_("guash_add_entry (\"%s\", %s_thumb.)\n"), pathname,
- (thumb ? thumb->name : "no"));
-
- dirname = pathname_get_directoryname (pathname);
-
- if ((dcache = guash_lookup_directory_cache (dirname)) == NULL)
- {
- DPRINT (N_("%s was not visted\n"), dirname);
- g_free (dirname);
- DPRINT (N_("done of guash_add_entry\n"));
- RETURN FALSE;
- }
- directory_cache_update_thumbnail_for (dcache, pathname, thumb);
- SET_ATTRIBUTE (dcache, DISORDERED_P);
-
- g_free (dirname);
- RETURN (cwd_cache == dcache);
- }
-
- static gint
- guash_copy_image_file (GCHAR *filename, GCHAR *newname)
- {
- /* FIXME
- UPDATE timestamp!
- */
- if (! guash_validate_src_file (filename))
- return FALSE;
-
- if (os_file_kind (newname, TRUE) == NOT_EXIST)
- {
- GCHAR *from_thumbnail_name;
- GCHAR *to_thumbnail_name;
- mode_t mode = NEW_DIRECTORY_MODE;
-
- if (os_copy_file (filename, newname) == FALSE)
- return FALSE;
-
- /* copy thumbnail */
- from_thumbnail_name = pathname_build_thumbnail_filename (filename);
- if (os_file_kind (from_thumbnail_name, TRUE) != REGFILE)
- {
- g_free (from_thumbnail_name);
- return TRUE;
- }
- to_thumbnail_name = pathname_build_thumbnail_filename (newname);
- {
- GCHAR *to_dir_name;
-
- to_dir_name = pathname_get_directoryname (to_thumbnail_name);
-
- if (os_make_directory (to_dir_name, mode) == -1)
- if (errno != EEXIST)
- {
- g_free (to_dir_name);
- g_free (to_thumbnail_name);
- g_free (from_thumbnail_name);
- return TRUE;
- }
- if (os_file_kind (to_dir_name, TRUE) != DIRECTORY)
- {
- g_free (to_dir_name);
- g_free (to_thumbnail_name);
- g_free (from_thumbnail_name);
- return TRUE;
- }
- g_free (to_dir_name);
- }
- os_copy_file (from_thumbnail_name, to_thumbnail_name);
-
- g_free (from_thumbnail_name);
- g_free (to_thumbnail_name);
- return TRUE;
- }
- else
- return FALSE;
- }
-
- static gint
- guash_delete_image_file (GCHAR *filename)
- {
- if (! guash_validate_src_file (filename))
- return FALSE;
-
- return (os_delete_file (filename) == 0);
- }
-
- static gint
- guash_move_image_file (GCHAR *filename, GCHAR *newname)
- {
- DEBUGBLOCK (N_("guash_move_image_file (\"%s\", \"%s\")\n"),
- filename, newname);
-
- if (! guash_validate_src_file (filename))
- RETURN FALSE;
-
- if (os_file_kind (newname, TRUE) == NOT_EXIST)
- {
- if (os_rename_file (filename, newname) == 0)
- {
- GCHAR *from_thumbnail_name = NULL;
- GCHAR *to_thumbnail_name = NULL;
- GCHAR *thumbnail_dir = NULL;
- mode_t mode = NEW_DIRECTORY_MODE;
-
- from_thumbnail_name = pathname_build_thumbnail_filename (filename);
-
- if (os_file_kind (from_thumbnail_name, TRUE) != REGFILE)
- {
- g_free (from_thumbnail_name);
- RETURN TRUE;
- }
- to_thumbnail_name = pathname_build_thumbnail_filename (newname);
- thumbnail_dir = pathname_get_directoryname (to_thumbnail_name);
-
- if (os_make_directory (thumbnail_dir, mode) == -1)
- if (errno != EEXIST)
- {
- g_free (thumbnail_dir);
- g_free (to_thumbnail_name);
- g_free (from_thumbnail_name);
- RETURN TRUE;
- }
- if (os_file_kind (thumbnail_dir, TRUE) != DIRECTORY)
- {
- g_free (thumbnail_dir);
- g_free (to_thumbnail_name);
- g_free (from_thumbnail_name);
- RETURN TRUE;
- }
- g_free (thumbnail_dir);
-
- if (os_rename_file (from_thumbnail_name, to_thumbnail_name) == -1)
- {
- perror ("rename thumbnail file");
- printf ("from %s to %s\n", from_thumbnail_name, to_thumbnail_name);
- }
-
- g_free (from_thumbnail_name);
- g_free (to_thumbnail_name);
- RETURN TRUE;
- }
- else
- {
- if (errno == EXDEV)
- {
- if (guash_copy_image_file (filename, newname))
- {
- guash_delete_image_file (filename);
- RETURN TRUE;
- }
- else
- RETURN FALSE;
- }
- else
- {
- perror ("file_move");
- RETURN FALSE;
- }
- }
- }
- else
- {
- GString *message;
-
- message = g_string_new ("NOP: ");
- g_string_append (message, newname);
- g_string_append (message, " already exists");
- gtkW_message_dialog (TRUE, message->str);
- g_string_free (message, TRUE);
-
- RETURN FALSE;
- }
- }
-
- static gint
- guash_open_image_file (GCHAR *filename)
- {
- GParam* return_vals;
- gint retvals;
- gint i_id;
-
- if (! guash_validate_src_file (filename))
- return -1;
-
- return_vals = gimp_run_procedure ("gimp_file_load",
- &retvals,
- PARAM_INT32, RUN_INTERACTIVE,
- PARAM_STRING, filename,
- PARAM_STRING, filename,
- PARAM_END);
-
- if (return_vals[0].data.d_status != STATUS_SUCCESS)
- {
- gimp_destroy_params (return_vals, retvals);
- return -1;
- }
- else
- gimp_destroy_params (return_vals, retvals);
-
- i_id = return_vals[1].data.d_image;
- /* the following sequence is copied from app/fileops.c */
- /* enable & clear all undo steps */
- gimp_image_undo_enable (i_id);
- /* set the image to clean */
- gimp_image_clean_all (i_id);
- /* display the image */
- gimp_display_new (i_id);
-
- return i_id;
- }
-
- static gint
- guash_validate_src_file (GCHAR *filename)
- {
- if (os_file_kind (filename, TRUE) == NOT_EXIST)
- {
- GCHAR tmp[LINE_BUF_SIZE];
-
- sprintf (tmp, "%s does not exist", filename);
- gtkW_message_dialog (TRUE, tmp);
- return FALSE;
- }
- return TRUE;
- }
-
- /*
- * selection class: internal data structure
- */
- static void
- selection_show ()
- {
- thumbnail_panel_draw_selection_frame (TRUE);
- thumbnail_panel_update_selection_buttons ();
- }
-
- static gint
- selection_add (gint index)
- {
- return directory_cache_update_selection (cwd_cache, SELECTION_ADD, index);
- }
-
- static gint
- selection_add_and_show (gint index)
- {
- if (selection_add (index))
- {
- selection_show ();
- return TRUE;
- }
- else
- return FALSE;
- }
-
- static gint
- selection_delete (gint index)
- {
- Thumbnail *thumb = directory_cache_get_nth (cwd_cache, index);
-
- if (thumb && HAS_ATTRIBUTE (thumb, SELECTED_P))
- {
- thumbnail_panel_draw_selection_frame (FALSE);
- directory_cache_update_selection (cwd_cache, SELECTION_DELETE, index);
-
- if (selection_is_active ())
- thumbnail_panel_draw_selection_frame (TRUE);
- else
- thumbnail_panel_set_info (NULL);
- thumbnail_panel_update_selection_buttons ();
- return TRUE;
- }
- else
- return FALSE;
- }
-
- static gint
- selection_is_active ()
- {
- return (0 < cwd_cache->num_selection);
- }
-
- static gint
- selection_length ()
- {
- return cwd_cache->num_selection;
- }
-
- static gint
- selection_member_p (gint index)
- {
- return HAS_ATTRIBUTE (directory_cache_get_nth (cwd_cache, index), SELECTED_P);
- }
-
- static gint
- selection_reset ()
- {
- Thumbnail *thumb;
- gint i;
- gint max = directory_cache_num_entry (cwd_cache);
-
- G_ASSERT (cwd_cache);
-
- DEBUGBLOCK (N_("selection_reset\n"));
-
- thumbnail_panel_draw_selection_frame (FALSE);
- DPRINT (N_("success to call thumbnail_panel_clear_selection_frame\n"));
-
- if (0 < cwd_cache->num_selection)
- {
- G_ASSERT (HAS_ATTRIBUTE (directory_cache_get_nth (cwd_cache,
- cwd_cache->selection_top),
- SELECTED_P));
-
- for (i = cwd_cache->selection_top; i < max; i++)
- {
- thumb = directory_cache_get_nth (cwd_cache, i);
-
- G_ASSERT (thumb);
-
- if (HAS_ATTRIBUTE (thumb, SELECTED_P))
- RESET_ATTRIBUTE (thumb, SELECTED_P);
- }
- }
- cwd_cache->num_selection = 0;
- cwd_cache->selection_top = -1;
- cwd_cache->selection_timestamp = 0;
- DPRINT (N_("success to remove all thumbnails from selection\n"));
-
- thumbnail_panel_update_selection_buttons ();
- gtk_widget_queue_draw (thumbnail_panel);
-
- cwd_cache->last_focus = 0;
- RETURN TRUE;
- }
-
- static gint
- selection_reverse_member (gint index)
- {
- gint flag = selection_member_p (index);
-
- if (flag)
- selection_delete (index);
- else
- selection_add_and_show (index);
- return (! flag);
- }
-
- static gint
- selection_validate_image ()
- {
- if (selection_is_active ())
- return TRUE;
- else
- {
- thumbnail_panel_set_info (_("No image is selected"));
- return FALSE;
- }
- }
-
- static selection_iterator *
- selection_make_iterator (gint mode)
- {
- selection_iterator *si;
- gint length = selection_length ();
- gint index = 0;
- gint max = directory_cache_num_entry (cwd_cache);
- gint id;
- gint count = 0;
-
- __DEBUGBLOCK (N_("selection_make_iterator (length %d)\n"), length);
-
- if (length < 1)
- RETURN NULL;
-
- si = g_new (selection_iterator, 1);
- si->length = length;
- si->unvisit_index = 0;
- si->body = g_new (selection_iterator_entry, length);
-
- G_ASSERT (selection_is_active ());
- G_ASSERT (HAS_ATTRIBUTE (directory_cache_get_nth (cwd_cache,
- cwd_cache->selection_top),
- SELECTED_P));
-
- for (id = cwd_cache->selection_top; id < max; id++)
- {
- Thumbnail *thumb = directory_cache_get_nth (cwd_cache, id);
-
- G_ASSERT (thumb != NULL);
-
- if (HAS_ATTRIBUTE (thumb, SELECTED_P)
- && HAS_NO_ATTRIBUTE (thumb, DELETED_P))
- {
- selection_iterator_entry *entry = si->body + index++;
-
- entry->index = id;
- entry->selection_timestamp = thumb->selection_timestamp;
- entry->thumbnail = thumb;
- count++;
- }
- }
- DPRINT (N_("success to gather selected %d thumbnails\n"), index);
-
- G_ASSERT (count == cwd_cache->num_selection);
-
- if (mode == SELECTION_ORDER_TIMESTAMP)
- {
- qsort (si->body,
- length,
- sizeof (selection_iterator_entry),
- (sort_compare_function) selection_iterator_compare_timestamp);
- DPRINT (N_("success to sort by timestamp\n"));
- }
- RETURN si;
- }
-
- static gint
- selection_iterator_compare_timestamp (void *a, void *b)
- {
- gint a_stamp = ((selection_iterator_entry *) a)->selection_timestamp;
- gint b_stamp = ((selection_iterator_entry *) b)->selection_timestamp;
-
- if (a_stamp < b_stamp)
- return -1;
- else if (a_stamp == b_stamp)
- return 0;
- else
- return 1;
- }
-
- static selection_iterator_entry *
- selection_iterator_get_next_entry (selection_iterator *si)
- {
- DEBUGBLOCK (N_("selection_iterator_get_next_entry\n"));
-
- if (si == NULL)
- RETURN NULL;
-
- DPRINT (N_("unvisit_index: %d, length: %d\n"), si->unvisit_index, si->length);
-
- if (si->unvisit_index < si->length)
- {
- RETURN si->body + si->unvisit_index++;
- }
- else
- {
- DPRINT (N_("delete iterator\n"));
- g_free (si->body);
- g_free (si);
- RETURN NULL;
- }
- }
-
- static Thumbnail *
- selection_iterator_get_next_thumbnail (selection_iterator *si)
- {
- selection_iterator_entry *next = NULL;
-
- DEBUGBLOCK (N_("selection_iterator_get_next_thumbnail\n"));
-
- next = selection_iterator_get_next_entry (si);
- DPRINT (N_("success to call selection_iterator_get_next_entry (%ld)\n"),
- (next == NULL ? 0 : (glong) next->thumbnail));
-
- RETURN (next == NULL ? NULL : next->thumbnail);
- }
-
- static void
- selection_map_script ()
- {
- gint retvals;
- FILE *file;
- GCHAR script_file[PATH_LENGTH];
- selection_iterator *iterator;
- Thumbnail *selected;
- GCHAR buf[LINE_BUF_SIZE];
-
- ASSERT (cwd_cache_validate ());
-
- DEBUGBLOCK (N_("selection_map_script\n"));
-
- if (os_file_kind (guash_tmp_dir, TRUE) != DIRECTORY)
- {
- gtkW_message_dialog (TRUE, "Abort execution: you don't have an appropriate directory");
- RETURN;
- }
-
- gtkW_widget_set_cursor (dlg, CURSOR_WAIT);
- gtkW_widget_set_cursor (thumbnail_panel, CURSOR_WAIT);
-
- thumbnail_panel_set_info (_("Map script-fu: wait a moment..."));
-
- sprintf (script_file, N_("%s%cguash%d.scm"), guash_tmp_dir, G_DIR_SEPARATOR, getpid ());
- DPRINT (N_("script_file is %s\n"), script_file);
-
- if ((file = fopen (script_file, "w")) == NULL)
- {
- sprintf (buf, _(" Failed to save to %s "), script_file);
- gtkW_message_dialog (TRUE, buf); /* info is too short to display filename */
- }
- fprintf (file, N_(";; This file was generated by guash automatically.\n"));
- fprintf (file, N_(";; You can delete me without trouble.\n\n"));
- fprintf (file, N_("(set! %%guash-selection\n"));
- fprintf (file, N_(" '(\n"));
-
- iterator = selection_make_iterator (SELECTION_ORDER_TIMESTAMP);
- while (NULL != (selected = selection_iterator_get_next_thumbnail (iterator)))
- {
- gint ppos, i;
-
- fprintf (file,
- N_(" (\"%s%c%s\" \"%s\" \""),
- cwd_cache->name, G_DIR_SEPARATOR, selected->name, /* full path */
- cwd_cache->name /* directory that does not end with slash */
- );
-
- ppos = pathname_get_last_period_index (selected->name);
-
- for (i = 0; i < ppos; i++)
- fprintf (file, N_("%c"), selected->name[i]);
-
- fprintf (file, N_("\" \""));
-
- for (i = ppos + 1; i < strlen (selected->name); i++)
- fprintf (file, N_("%c"), selected->name[i]);
-
- fprintf (file, N_("\")\n"));
- }
- fprintf (file, N_(" ))\n"));
- fclose (file);
-
- #ifdef GIMP_HAVE_PARASITES
- #ifndef BROKEN_SCRIPT_FU
- {
- Parasite *para = NULL;
-
- /*
- if ((para = gimp_parasite_find (GUASH_PARASITE_NAME)) != NULL)
- gimp_parasite_detach (GUASH_PARASITE_NAME);
- */
- gimp_attach_new_parasite (GUASH_PARASITE_NAME,
- FALSE,
- strlen (script_file) + 1,
- script_file);
- }
- #endif
- #endif
-
- /* And all script-fus return NULL always */
- #ifndef BROKEN_SCRIPT_FU
- thumbnail_panel_set_info (_("Map script-fu: start launchar..."));
-
- gimp_run_procedure ("script-fu-map-on-guash-selection",
- &retvals,
- PARAM_INT32, RUN_INTERACTIVE,
- PARAM_STRING, "/tmp/guash", /* the filename */
- PARAM_INT32, TRUE, /* delete the file */
- PARAM_STRING, "gm-sample", /* function */
- PARAM_INT32, FALSE, /* display */
- PARAM_INT32, FALSE, /* overwrite */
- PARAM_INT32, FALSE, /* sort */
- PARAM_INT32, FALSE, /* reverse order */
- PARAM_STRING, "()", /* extra arg list */
- PARAM_END);
-
- os_delete_file (script_file);
- thumbnail_panel_set_info (_("Map script-fu: finished"));
- #else
- retvals = 0;
- sprintf (buf, _("Wrote %s. Run script-fu-map-on-guash-selection with it"),
- script_file);
- thumbnail_panel_set_info (buf);
- #endif
- gtkW_widget_set_cursor (dlg, CURSOR_DEFAULT);
- gtkW_widget_set_cursor (thumbnail_panel, CURSOR_HAND);
-
- RETURN;
- }
-
- static void
- selection_map_unix_command ()
- {
- selection_iterator *iterator;
- Thumbnail *selected;
- GCHAR template[LINE_BUF_SIZE];
-
- ASSERT (cwd_cache_validate ());
-
- gtkW_query_box ("Guash: mapping unix command on selection",
- "Type command to map on the selected image files. \n\
- \"{}\" in the command string is replaced to each filename without directory. \n\
- \"%%\" in the command string is replaced to the directory part of each file. \n\
- - SAMPLES -\n\
- rm .xvpics/{} \n\
- uuencode {} {} > /tmp/{}.uu; chmod go-r /tmp/{}.uu",
- VAL.mapping_command, template);
- if (strlen (template) == 0)
- return;
-
- iterator = selection_make_iterator (SELECTION_ORDER_TIMESTAMP);
- while (NULL != (selected = selection_iterator_get_next_thumbnail (iterator)))
- {
- GCHAR *command;
-
- command = guash_generate_unix_command (template, cwd_cache->name, selected->name);
- if (command)
- {
- system (command);
- g_free (command);
- }
- }
- strcpy (VAL.mapping_command, template);
- }
-
- static void
- selection_open_files ()
- {
- Thumbnail *selected;
- selection_iterator *iterator;
- gint first_missing = TRUE;
-
- ASSERT (cwd_cache_validate () && selection_validate_image ());
-
- DEBUGBLOCK (N_("selection_open_files\n"));
-
- gtkW_widget_set_cursor (dlg, CURSOR_WAIT);
- gtkW_widget_set_cursor (thumbnail_panel, CURSOR_WAIT);
-
- thumbnail_panel_set_info (_("Loading..."));
-
- iterator = selection_make_iterator (SELECTION_ORDER_INDEX);
- while (NULL != (selected = selection_iterator_get_next_thumbnail (iterator)))
- {
- gint f_kind;
-
- if (HAS_NO_ATTRIBUTE (selected, SELECTED_P))
- continue;
-
- f_kind = os_file_kind (selected->name, TRUE);
-
- if (f_kind == REGFILE)
- {
- GCHAR filename[PATH_LENGTH];
-
- sprintf (filename, "%s%c%s", cwd_cache->name, G_DIR_SEPARATOR, selected->name);
- guash_open_image_file (filename);
- }
- else if (f_kind == NOT_EXIST)
- {
- if (first_missing)
- {
- gdk_beep ();
- thumbnail_panel_set_info (_("the selected image does not exist now!"));
- DPRINT (N_("file lost %s\n"), selected->name);
- sleep (1);
- first_missing = FALSE;
- }
- }
- }
-
- gtkW_widget_set_cursor (dlg, CURSOR_DEFAULT);
- gtkW_widget_set_cursor (thumbnail_panel, CURSOR_HAND);
-
- if (guash_discard_events ())
- thumbnail_panel_set_info (_("FYI, events during opening an image were discarded"));
- else
- {
- Thumbnail *thumb = NULL;
-
- G_ASSERT (0 < cwd_cache->last_focus);
- thumb = directory_cache_get_nth (cwd_cache, cwd_cache->last_focus);
- G_ASSERT (thumb != NULL);
- thumbnail_panel_set_info (thumb->info);
- }
-
- DEBUGEND;
- }
-
- static void
- selection_copy_files_to (GCHAR *pathname)
- {
- selection_iterator *iterator;
- Thumbnail *selected;
- GCHAR info[256], first_file[LINE_BUF_SIZE];
- gint kind = NOT_EXIST;
- gint success = 0;
-
- ASSERT (cwd_cache_validate () && selection_validate_image ());
-
- DEBUGBLOCK (N_("selection_copy_files_to (\"%s\")\n"), pathname);
-
- iterator = selection_make_iterator (SELECTION_ORDER_INDEX);
- while (NULL != (selected = selection_iterator_get_next_thumbnail (iterator)))
- {
- kind = os_file_kind (pathname, TRUE);
-
- if ((kind == NOT_EXIST) || (kind == DIRECTORY))
- {
- GString *name, *new;
-
- name = g_string_new (cwd_cache->name);
- g_string_append_c (name, G_DIR_SEPARATOR);
- G_ASSERT (selected->name);
- g_string_append (name, selected->name);
- new = g_string_new (pathname);
- if (kind == DIRECTORY)
- {
- if (pathname [strlen (pathname) - 1] != G_DIR_SEPARATOR)
- g_string_append_c (new, G_DIR_SEPARATOR);
- g_string_append (new, selected->name);
- }
- if (os_file_kind (new->str, TRUE) != NOT_EXIST)
- {
- sprintf (info, _("%s already exists"), new->str);
- gtkW_message_dialog (TRUE, info);
- }
- else if (guash_copy_image_file (name->str, new->str) == TRUE)
- {
- guash_add_entry (new->str, selected);
-
- if (success++ == 0)
- strcpy (first_file, selected->name);
- }
-
- g_string_free (name, TRUE);
- g_string_free (new, TRUE);
- }
- else if (kind == REGFILE)
- {
- sprintf (info, _("%s already exists"), pathname);
- gtkW_message_dialog (TRUE, info);
- }
- }
-
- if (0 < success)
- cwd_cache_update_after_file_operation (success, "copied", first_file, pathname);
- else
- thumbnail_panel_set_info ("Failed to copy");
-
- RETURN;
- }
-
- static void
- selection_delete_files ()
- {
- selection_iterator *iterator;
- selection_iterator_entry *entry;
- GCHAR first_file[LINE_BUF_SIZE];
- gint success = 0;
-
- ASSERT (cwd_cache_validate () && selection_validate_image ());
-
- DEBUGBLOCK (N_("selection_delete_files\n"));
-
- iterator = selection_make_iterator (SELECTION_ORDER_INDEX);
- while (NULL != (entry = selection_iterator_get_next_entry (iterator)))
- {
- Thumbnail *selected = entry->thumbnail;
- GCHAR pathname[PATH_LENGTH];
-
- sprintf (pathname, "%s%c%s", cwd_cache->name, G_DIR_SEPARATOR, selected->name);
- if (os_delete_file (pathname) == 0)
- {
- GCHAR *thumbnail_name;
-
- thumbnail_name = pathname_build_thumbnail_filename (pathname);
- os_delete_file (thumbnail_name);
- selection_delete (entry->index);
- SET_ATTRIBUTE (selected, DELETED_P);
- if (success++ == 0)
- strcpy (first_file, selected->name);
- DPRINT (N_("success to delete %s\n"), selected->name);
-
- g_free (thumbnail_name);
- }
- }
- DPRINT (N_("done and display the page %d\n"), cwd_cache->display_page);
-
- if (0 < success)
- {
- SET_ATTRIBUTE (cwd_cache, DISORDERED_P);
- cwd_cache_update_after_file_operation (success, "deleted",
- first_file, NULL);
- }
- else
- thumbnail_panel_set_info (_("Failed to delete (permission problem?)"));
-
- DEBUGEND;
- }
-
- static void
- selection_move_files_to (GCHAR *pathname)
- {
- selection_iterator *iterator;
- selection_iterator_entry *entry;
- GCHAR info[256], first_file[LINE_BUF_SIZE];
- gint kind = NOT_EXIST;
- gint success = 0;
-
- ASSERT (cwd_cache_validate () && selection_validate_image ());
-
- DEBUGBLOCK (N_("selection_move_files_to (\"%s\")\n"), pathname);
-
- iterator = selection_make_iterator (SELECTION_ORDER_INDEX);
- while (NULL != (entry = selection_iterator_get_next_entry (iterator)))
- {
- Thumbnail *selected = entry->thumbnail;
-
- G_ASSERT (selected != NULL);
-
- kind = os_file_kind (pathname, TRUE); /* might be overwrited */
- if ((kind == NOT_EXIST) || (kind == DIRECTORY))
- {
- GCHAR src_name[PATH_LENGTH];
- GCHAR dest_name[PATH_LENGTH];
-
- sprintf (src_name, "%s%c%s", cwd_cache->name, G_DIR_SEPARATOR, selected->name);
- if (kind == DIRECTORY)
- if (pathname [strlen (pathname) - 1] != G_DIR_SEPARATOR)
- sprintf (dest_name, "%s%c%s", pathname, G_DIR_SEPARATOR, selected->name);
- else
- sprintf (dest_name, "%s%s", pathname, selected->name);
- else
- sprintf (dest_name, "%s", pathname);
-
- DPRINT (N_("src : %s, dest: %s\n"), src_name, dest_name);
-
- if (guash_move_image_file (src_name, dest_name))
- {
- guash_add_entry (dest_name, selected);
- selection_delete (entry->index);
- SET_ATTRIBUTE (selected, DELETED_P);
- SET_ATTRIBUTE (cwd_cache, DISORDERED_P);
- if (success++ == 0)
- strcpy (first_file, selected->name);
- }
- }
- else if (kind == REGFILE)
- {
- sprintf (info, _("%s already exists"), pathname);
- gtkW_message_dialog (TRUE, info);
- }
- }
- DPRINT (N_("success to move file(s)\n"));
-
- if (0 < success)
- cwd_cache_update_after_file_operation (success, "moved", first_file, pathname);
- else
- thumbnail_panel_set_info (_("Failed to move (permission problem?)"));
-
- RETURN;
- }
-
- /*
- * thumbnail_panel: visible element
- */
- static void
- thumbnail_panel_initialize_banner ()
- {
- guchar data[] = BASE_COLOR;
- guchar *ptr;
-
- DEBUGBLOCK (N_("thumbnail_panel_initialize_banner\n"));
-
- if (VAL.last_dir_name[0] != 0)
- {
- banner_width = the_panel.width;
- banner_height = 2; /* for BASE_COLOR and FRAME_COLOR */
- }
-
- /* to call thumbnail_panel_clear, only the 1st line should be cleared. */
- banner = image_buffer_new (banner_width, banner_height, 3);
- for (ptr = banner->data; ptr < banner->data + 3 * banner->width;)
- {
- *ptr++ = *data;
- *ptr++ = *(data + 1);
- *ptr++ = *(data + 2);
- }
-
- thumbnail_panel_clear ();
-
- if (VAL.last_dir_name[0] == 0)
- image_buffer_set_from_header (banner,
- banner_data,
- banner_width, banner_height);
- RETURN;
- }
-
- static void
- thumbnail_panel_reinitialize_banner ()
- {
- guchar base[3] = BASE_COLOR;
- guchar frame[3] = FRAME_COLOR;
- guchar *ptr;
-
- DEBUGBLOCK (N_("thumbnail_panel_reinitialize_banner\n"));
-
- /* Then, we use banner to clear thumbnail_panel. Thus clear the 1st row. */
- for (ptr = banner->data; ptr < banner->data + 3 * banner->width;)
- {
- *ptr++ = *base;
- *ptr++ = *(base + 1);
- *ptr++ = *(base + 2);
- }
- /* And use second row to draw frame */
- for (ptr = banner->data + 3 * banner->width; ptr < banner->data + 6 * banner->width;)
- {
- *ptr++ = *frame;
- *ptr++ = *(frame + 1);
- *ptr++ = *(frame + 2);
- }
-
- RETURN;
- }
-
- static void
- thumbnail_panel_show_banner_step1 ()
- {
- guchar white[3] = WHITE_COLOR;
- gint x, y;
- gint sx, sy;
-
- DEBUGBLOCK (N_("thumbnail_panel_show_banner_step1\n"));
-
- if (VAL.last_dir_name[0] != 0)
- {
- RETURN;
- }
-
- sx = MAX (0, ((the_panel.width - banner->width) / 2));
- sy = MAX (0, ((the_panel.height - banner->height) / 2));
-
- thumbnail_panel_draw_image_buffer (banner, sx, sy, FALSE);
-
- for (y = 19; y < 24; y++)
- for (x = 101; x < 106; x++)
- gtk_preview_draw_row (GTK_PREVIEW (thumbnail_panel), white,
- sx + x, sy + y, 1);
-
- {
- gint i;
- guchar color[3];
- guchar draw[3] = DRAW_COLOR;
-
- for (i = 0; i < 3; i++)
- color[i] = (2 * white[i] + draw[i]) / 3;
-
- thumbnail_panel_draw_string (GUASH_VERSION,
- the_panel.width / 2, sy + banner->height,
- color, TRUE, the_panel.width);
-
- gtkW_preview_force_to_update (thumbnail_panel);
- }
-
- RETURN;
- }
-
- static void
- thumbnail_panel_show_banner_step2 ()
- {
- guchar color[3];
- guchar draw[3] = DRAW_COLOR;
- guchar white[3] = WHITE_COLOR;
- gint sx, sy, y;
- gint i;
-
- DEBUGBLOCK (N_("thumbnail_panel_banner_step2\n"));
-
- sx = MAX (0, ((the_panel.width - banner->width) / 2));
- sy = MAX (0, ((the_panel.height - banner->height) / 2));
-
- thumbnail_panel_clear ();
- thumbnail_panel_draw_image_buffer (banner, sx, sy, FALSE);
-
- for (y = 18; y < 24; y++)
- gtk_preview_draw_row (GTK_PREVIEW (thumbnail_panel),
- banner->data + ((y * banner->width + 100) * 3),
- sx + 100, sy + y, 6);
-
- for (i = 0; i < 3; i++)
- color[i] = (white[i] + draw[i]) / 2;
-
- thumbnail_panel_draw_string (GUASH_VERSION,
- the_panel.width / 2, sy + banner->height,
- color, TRUE, the_panel.width);
-
- gtkW_preview_force_to_update (thumbnail_panel);
-
- RETURN;
- }
-
- static void
- thumbnail_panel_show_banner_step3 ()
- {
- guchar draw[3] = DRAW_COLOR;
- guchar white[3] = WHITE_COLOR;
- gint sx, sy, x, y;
-
- DEBUGBLOCK (N_("thumbnail_panel_show_banner_step3\n"));
-
- sx = MAX (0, ((the_panel.width - banner->width) / 2));
- sy = MAX (0, ((the_panel.height - banner->height) / 2));
-
- thumbnail_panel_draw_string (GUASH_VERSION,
- the_panel.width / 2, sy + banner->height,
- draw, TRUE, the_panel.width);
-
- gtkW_preview_force_to_update (thumbnail_panel);
-
- for (y = 18; y < 24; y++)
- for (x = 101; x < 106; x++)
- gtk_preview_draw_row (GTK_PREVIEW (thumbnail_panel), white,
- sx + x, sy + y, 1);
-
- for (y = 19; y < 24; y++)
- gtk_preview_draw_row (GTK_PREVIEW (thumbnail_panel),
- banner->data + ((y * banner->width + 100) * 3),
- sx + 100 + 3, sy + y + 2, 6);
-
- gtkW_preview_force_to_update (thumbnail_panel);
-
- RETURN;
- }
-
- static void
- thumbnail_panel_clear ()
- {
- gint x, y, scan;
-
- if (! thumbnail_panel)
- return;
-
- DEBUGBLOCK (N_("thumbnail_panel_clear()\n"));
-
- for (y = 0; y < the_panel.height; y++)
- for (x = 0; x < the_panel.width; x += scan)
- {
- scan = MIN (the_panel.width - x, banner->width);
- gtk_preview_draw_row (GTK_PREVIEW (thumbnail_panel),
- banner->data, x, y, scan);
- }
- gtk_widget_draw (thumbnail_panel, NULL);
-
- DEBUGEND;
- }
-
- static void
- thumbnail_panel_draw_image_buffer (image_buffer *buffer,
- gint sx,
- gint sy,
- gint align_p)
- {
- gint width, height;
- gint y;
-
- G_ASSERT (buffer);
-
- DEBUGBLOCK (N_("thumbnail_panel_draw_image_buffer (width: %d, height %d)\n"),
- buffer->width, buffer->height);
-
- if (buffer->data == NULL)
- RETURN;
-
- if (align_p)
- {
- sx += (THUMBNAIL_WIDTH - buffer->width) / 2;
- sy += (THUMBNAIL_HEIGHT - buffer->height) / 2;
- }
-
- width = MIN (the_panel.width - sx, buffer->width);
- height = MIN (the_panel.height - sy, buffer->height);
-
- if (buffer->ch == 1)
- {
- guchar fixed_buf[THUMBNAIL_WIDTH * 3];
- guchar *dynamic_buffer = NULL;
- guchar *buf = NULL;
- guchar *data = buffer->data;
-
- DPRINT (N_("draw indexed image\n"));
-
- if (buffer->width <= THUMBNAIL_WIDTH)
- buf = fixed_buf;
- else
- buf = dynamic_buffer = g_new (guchar, buffer->width * 3);
-
- for (y = 0; y < height; y++)
- {
- gint x;
- guchar *tmp = buf;
-
- for (x = 0; x < buffer->width; x++)
- tmp = indexed_to_rgb (*data++, tmp);
-
- gtk_preview_draw_row (GTK_PREVIEW (thumbnail_panel),
- buf,
- sx, sy + y,
- width);
- }
- if (dynamic_buffer)
- g_free (dynamic_buffer);
- }
- else
- {
- for (y = 0; y < height; y++)
- gtk_preview_draw_row (GTK_PREVIEW (thumbnail_panel),
- buffer->data + (y * buffer->width * 3),
- sx, sy + y,
- width);
-
- }
- RETURN;
- }
-
- static void
- thumbnail_panel_draw_string (GCHAR *string,
- gint x,
- gint y,
- guchar *color,
- gint align_p,
- gint frame_width)
- {
- GtkWidget *widget = GTK_WIDGET (thumbnail_panel);
- GdkFont *font = widget->style->font;
- GdkImage *image = NULL;
- #ifdef DRAW_STRING_BY_CHARACTER
- GCHAR buffer[LINE_BUF_SIZE];
- #endif
- guchar base[3] = BASE_COLOR;
- guchar *ptr = NULL;
- gint ox, oy, width = 0, height;
-
- DEBUGBLOCK (N_("thumbnail_panel_draw_string (\"%s\",...)\n"), string);
-
- if ((string == NULL) || (string[0] == 0))
- RETURN;
-
- #ifdef DRAW_STRING_BY_CHARACTER
- {
- gint index = strlen (string);
- gint rest;
- gint font_width = the_panel.font_height * 2; /* should be safe */
-
- strcpy (buffer, string);
- while (0 < (rest = (width = gdk_string_width (font, buffer)) - frame_width))
- {
- index -= MAX (rest / font_width, 1);
- buffer[index] = 0;
- }
- string = buffer;
- }
- #else
- width = gdk_string_width (font, string);
- width = MIN (width, frame_width);
- #endif
-
- if (align_p)
- x -= width / 2;
-
- height = the_panel.font_height;
- if (the_panel.height <= y + height)
- {
- DPRINT (N_("abort:too tall\n"));
- RETURN;
- }
-
- if (! text_buffer || (text_buffer->width < width) || (text_buffer->height < height))
- {
- if (text_buffer)
- {
- gdk_pixmap_unref (text_buffer->pixmap);
- gdk_gc_destroy (text_buffer->gc);
- g_free (text_buffer->line_buffer);
- g_free (text_buffer);
- }
- text_buffer = g_new (Pixmap_struct, 1);
- text_buffer->width = width;
- text_buffer->height = height;
- text_buffer->pixmap = gdk_pixmap_new (NULL, width, height, 1);
- text_buffer->line_buffer = g_malloc (3 * width);
- text_buffer->gc = gdk_gc_new (text_buffer->pixmap);
- gdk_gc_set_font (text_buffer->gc, font);
- #if !defined (GDK_WINDOWING_WIN32)
- text_buffer->black.pixel
- = BlackPixel (((Display *) GDK_DISPLAY()),
- DefaultScreen (((Display *) GDK_DISPLAY())));
- #else
- text_buffer->black.pixel = 0;
- text_buffer->black.red =
- text_buffer->black.green =
- text_buffer->black.blue = 0;
- #endif
- #if !defined (GDK_WINDOWING_WIN32)
- text_buffer->white.pixel
- = WhitePixel (((Display *) GDK_DISPLAY()),
- DefaultScreen (((Display *) GDK_DISPLAY())));
- #else
- /* //HB: ??? */
- text_buffer->white.pixel = 1;
- text_buffer->white.red =
- text_buffer->white.green =
- text_buffer->white.blue = 65535;
- #endif
-
- DPRINT (N_("success to build text_buffer\n"));
- }
- gdk_gc_set_foreground (text_buffer->gc, &text_buffer->white);
- gdk_draw_rectangle (text_buffer->pixmap, text_buffer->gc, 1, 0, 0,
- text_buffer->width, text_buffer->height);
- gdk_gc_set_foreground (text_buffer->gc, &text_buffer->black);
-
- gdk_draw_string (text_buffer->pixmap, font, text_buffer->gc,
- 0, font->ascent, string);
- DPRINT (N_("success to draw \"%s\" on text_buffer\n"), string);
-
- /* then make GdkImage */
- if (! (image = gdk_image_get (text_buffer->pixmap, 0, 0, width, height)))
- {
- DPRINT (N_("abort: fail to gdk_image_get\n"));
- RETURN;
- }
-
- for (oy = 0; oy < height; oy++)
- {
- ptr = text_buffer->line_buffer;
- for (ox = 0; ox < width; ox++)
- {
- if (gdk_image_get_pixel (image, ox, oy) == text_buffer->black.pixel)
- {
- *ptr++ = *color;
- *ptr++ = *(color + 1);
- *ptr++ = *(color + 2);
- }
- else
- {
- *ptr++ = *base;
- *ptr++ = *(base + 1);
- *ptr++ = *(base + 2);
- }
- }
- /* copy it to preview's buffer */
- gtk_preview_draw_row (GTK_PREVIEW (thumbnail_panel),
- text_buffer->line_buffer, x, y + oy, width);
- }
-
- DPRINT (N_("success to gtk_preview_draw_row\n"));
-
- gdk_image_destroy (image);
-
- RETURN;
- }
-
- static gint
- thumbnail_panel_draw_thumbnail (Thumbnail *thumb)
- {
- guchar draw[3] = DRAW_COLOR;
- guchar slink[3] = SLINK_COLOR;
- guchar *color = NULL;
- gint sx, sy;
- gint pdir_p;
- image_buffer *icon = NULL;
-
- G_ASSERT (thumb);
-
- __DEBUGBLOCK (N_("thumbnail_panel_draw_thumbnail of %s\n"), thumb->name);
-
- the_panel.last_index++;
- if (the_panel.nthumb_in_page <= the_panel.last_index)
- {
- RETURN FALSE;
- }
-
- sx = INDEX_TO_X (the_panel.last_index);
- sy = INDEX_TO_Y (the_panel.last_index);
-
- pdir_p = HAS_ATTRIBUTE (thumb, PARENT_DIRECTORY_P);
- color = HAS_ATTRIBUTE (thumb, SYMLINK_P) ? slink : draw;
-
- if (HAS_ATTRIBUTE (thumb, DIRECTORY_P))
- icon = pdir_p ? pdir_icon : dir_icon;
- else
- {
- if (thumb->image &&
- (0 < thumb->image->width) && (0 < thumb->image->height))
- icon = thumb->image;
- else
- icon = file_icon;
- }
-
- thumbnail_panel_draw_image_buffer (icon, sx, sy, TRUE);
- thumbnail_panel_draw_string ((pdir_p ? "..(parent)" : thumb->name),
- sx + THUMBNAIL_WIDTH / 2,
- sy + THUMBNAIL_HEIGHT + THUMBNAIL_TSEPARATOR,
- color,
- TRUE,
- THUMBNAIL_WIDTH);
- DPRINT (N_("success to draw_string\n"));
-
- gtkW_preview_force_to_update_partially (thumbnail_panel,
- sx - THUMBNAIL_BORDER_WIDTH - 1,
- sy - THUMBNAIL_BORDER_WIDTH - 1,
- THUMBNAIL_WIDTH + THUMBNAIL_SEPARATOR,
- THUMBNAIL_FULLHEIGHT + THUMBNAIL_SEPARATOR);
-
- DPRINT (N_("success to gtkW_preview_force_to_update_partially\n"));
-
- RETURN TRUE;
- }
-
- static void
- thumbnail_panel_set_directory_info ()
- {
- GCHAR title[LINE_BUF_SIZE];
- GCHAR label[LINE_BUF_SIZE];
- gint from = 0;
-
- sprintf (title, "%s: %s", SHORT_NAME, pathname_get_basename (cwd_cache->name));
- gtk_window_set_title (GTK_WINDOW (dlg), title);
-
- the_panel.current_page1 = cwd_cache->display_page + 1;
-
- if (1 < cwd_cache_npage ())
- sprintf (label,
- "%s%s (%d/%d by %s) ",
- (from == 0) ? "" : "*",
- cwd_cache->name + from,
- cwd_cache->display_page + 1,
- cwd_cache_npage (),
- (HAS_ATTRIBUTE (&VAL, SORT_BY_NAME_P) ? "name" : "date"));
- else
- sprintf (label,
- "%s%s (by %s)",
- (from == 0) ? "" : "*",
- cwd_cache->name + from,
- (HAS_ATTRIBUTE (&VAL, SORT_BY_NAME_P) ? "name" : "date"));
- #ifdef GTK_HAVE_FEATURES_1_1_0
- gtk_label_set_text (GTK_LABEL (cwd_label), label);
- #else
- gtk_label_set (GTK_LABEL (cwd_label), label);
- #endif
- gtk_label_set_justify (GTK_LABEL (cwd_label), GTK_JUSTIFY_FILL);
- }
-
- static void
- thumbnail_panel_set_info (GCHAR *name)
- {
- G_ASSERT (GTK_IS_LABEL (file_property));
- #ifdef GTK_HAVE_FEATURES_1_1_0
- gtk_label_set_text (GTK_LABEL (file_property),
- ((name == NULL) ? the_panel.info : name));
- #else
- gtk_label_set (GTK_LABEL (file_property),
- ((name == NULL) ? the_panel.info : name));
- #endif
- /* Since info field should be updated immediately, I use gtk_widget_draw ()
- instead of gtk_widget_queue_draw () here. */
- gtk_widget_realize (file_property);
- gtk_widget_show (file_property);
-
- gtk_widget_queue_draw (file_property);
- gtk_widget_draw (file_property, NULL);
-
- during_buildup_thumbnail_panel = TRUE;
- while (gtk_events_pending())
- gtk_main_iteration();
- during_buildup_thumbnail_panel = FALSE;
-
- gdk_flush ();
- }
-
- static void
- thumbnail_panel_set_info_default ()
- {
- if (! cwd_cache)
- the_panel.info[0] = 0;
- else if (1 == cwd_cache->ndir)
- sprintf (the_panel.info, "%d %s",
- cwd_cache->nimage,
- (HAS_ATTRIBUTE (&VAL, DISPLAY_IMAGE_P)
- ? ((1 < cwd_cache->nimage) ? _("images") : _("image"))
- : ((1 < cwd_cache->nimage) ? _("files") : _("file"))));
- else
- sprintf (the_panel.info, _("%d %s and %d %s"),
- cwd_cache->nimage,
- (HAS_ATTRIBUTE (&VAL, DISPLAY_IMAGE_P)
- ? ((1 < cwd_cache->nimage) ? _("images") : _("image"))
- : ((1 < cwd_cache->nimage) ? _("files") : _("file"))),
- (cwd_cache->ndir - 1),
- ((2 < cwd_cache->ndir) ? _("subdirectories") : _("subdirectory")));
- }
-
- static void
- thumbnail_panel_draw_frame (gint index, gint draw_p)
- {
- gint x, y;
- gint xi, yi;
- gint endx;
- gint scan = 0;
- gint border = THUMBNAIL_BORDER_WIDTH;
- guchar *data;
- GtkPreview *preview = GTK_PREVIEW (thumbnail_panel);
-
- index -= cwd_cache->display_page * the_panel.nthumb_in_page;
- x = INDEX_TO_X (index);
- y = INDEX_TO_Y (index);
-
- data = banner->data + (draw_p ? 3 * banner->width : 0);
-
- /* draw top */
- endx = x + THUMBNAIL_WIDTH + border + 1;
- for (yi = y - border - 1;
- yi < y - 1;
- yi++)
- for (xi = x - border - 1;
- xi < endx;
- xi += scan)
- {
- scan = MIN (endx - xi, banner->width);
- gtk_preview_draw_row (preview, data, xi, yi, scan);
- }
- /* draw left */
- endx = x - 1;
- for (yi = y - border - 1;
- yi < y + THUMBNAIL_FULLHEIGHT + border + 1;
- yi++)
- for (xi = x - border - 1;
- xi < endx;
- xi += scan)
- {
- scan = MIN (endx - xi, banner->width);
- gtk_preview_draw_row (preview, data, xi, yi, scan);
- }
- /* draw right */
- endx = x + THUMBNAIL_WIDTH + border + 1;
- for (yi = y - border - 1;
- yi < y + THUMBNAIL_FULLHEIGHT + border + 1;
- yi++)
- for (xi = x + THUMBNAIL_WIDTH + 1;
- xi < endx;
- xi += scan)
- {
- scan = MIN (endx - xi, banner->width);
- gtk_preview_draw_row (preview, data, xi, yi, scan);
- }
- /* draw bottom */
- for (yi = y + THUMBNAIL_FULLHEIGHT + 1;
- yi < y + THUMBNAIL_FULLHEIGHT + border + 1;
- yi++)
- for (xi = x - border - 1;
- xi < endx;
- xi += scan)
- {
- scan = MIN (endx - xi, banner->width);
- gtk_preview_draw_row (preview, data, xi, yi, scan);
- }
- }
-
- static void
- thumbnail_panel_draw_selection_frame (gint mode)
- {
- gint max, index;
- gint flag = FALSE;
-
- max = MIN ((1 + cwd_cache->display_page) * the_panel.nthumb_in_page,
- directory_cache_num_entry (cwd_cache));
-
- for (index = cwd_cache->display_page * the_panel.nthumb_in_page;
- index < max;
- index++)
- if (HAS_ATTRIBUTE (directory_cache_get_nth (cwd_cache, index), SELECTED_P))
- {
- thumbnail_panel_draw_frame (index, mode);
- flag = TRUE;
- }
- if (flag)
- gtk_widget_queue_draw (thumbnail_panel);
- }
-
- static void
- thumbnail_panel_finalize_update ()
- {
- __DEBUGBLOCK (N_("thumbnail_panel_finalize_update\n"));
-
- the_panel.current_page1 = cwd_cache->display_page + 1;
- thumbnail_panel_set_directory_info ();
- thumbnail_panel_set_info_default ();
- if (selection_is_active ())
- {
- Thumbnail *selected;
-
- selected = directory_cache_get_nth (cwd_cache,
- cwd_cache->selection_top);
- thumbnail_panel_draw_selection_frame (TRUE);
- thumbnail_panel_set_info (selected->info);
- }
- else
- thumbnail_panel_set_info (NULL);
- thumbnail_panel_update_sensitive_menu ();
-
- gdk_flush ();
-
- RETURN;
- }
-
- static void
- thumbnail_panel_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
- {
- gint ncol, nrow;
-
- g_return_if_fail (widget != NULL);
- g_return_if_fail (GTK_IS_PREVIEW (widget));
- g_return_if_fail (requisition != NULL);
-
- __DEBUGBLOCK (N_("thumbnail_panel_size_request\n"));
-
- if (! cwd_cache)
- {
- ncol = the_panel.ncol;
- nrow = the_panel.nrow;
- }
- else
- {
- ncol = NCOL_OF_THUMBNAIL_PANEL_MIN;
- nrow = NROW_OF_THUMBNAIL_PANEL_MIN;
- }
- requisition->width = COL2WIDTH (ncol);
- requisition->height = ROW2HEIGHT (nrow);
-
- RETURN;
- }
-
- static gint
- thumbnail_panel_size_allocate (GtkWidget *widget, gpointer value)
- {
- g_return_val_if_fail (widget != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_DIALOG (widget), FALSE);
-
- __DEBUGBLOCK (N_("thumbnail_panel_size_allocate\n"));
-
- /* widget->allocation = *allocation;*/
- widget = thumbnail_panel;
-
- if ((the_panel.width != widget->allocation.width)
- || (the_panel.height != widget->allocation.height))
- the_panel.resized = TRUE;
-
- the_panel.width = widget->allocation.width;
- the_panel.height = widget->allocation.height;
-
- the_panel.ncol = WIDTH2COL (the_panel.width);
- the_panel.nrow = HEIGHT2ROW (the_panel.height);
- the_panel.nthumb_in_page = the_panel.ncol * the_panel.nrow;
-
- if (GTK_WIDGET_REALIZED (widget))
- {
- if (cwd_cache)
- if (((GtkAdjustment *) widget_pointer[0].widget)->upper != cwd_cache_npage () + 1)
- {
- the_panel.current_page1 = cwd_cache_npage () + 1;
- ((GtkAdjustment *) widget_pointer[0].widget)->upper
- = cwd_cache_npage () + 1;
- }
- }
- gtk_preview_size (GTK_PREVIEW (thumbnail_panel),
- the_panel.width,
- the_panel.height);
-
- RETURN FALSE;
- }
-
- /* this function does not check the current size of thumbnail_panel */
- static gint
- thumbnail_panel_update ()
- {
- gint index, max;
-
- DEBUGBLOCK (N_("thumbnail_panel_update\n"));
-
- if (! cwd_cache)
- RETURN FALSE;
-
- gtkW_widget_set_cursor (dlg, CURSOR_WAIT);
- gtkW_widget_set_cursor (thumbnail_panel, CURSOR_WAIT);
- /* from 0.99.5, this function must also check the page number, since resize
- changes the number of pages. */
- DPRINT (N_("display_page: %d, max_page: %d\n"),
- cwd_cache->display_page,
- (cwd_cache_npage () - 1));
- cwd_cache->display_page = CLAMP (cwd_cache->display_page,
- 0,
- (cwd_cache_npage () - 1));
- the_panel.current_page1 = cwd_cache->display_page + 1;
- thumbnail_panel_clear ();
-
- max = MIN ((1 + cwd_cache->display_page) * the_panel.nthumb_in_page,
- directory_cache_num_entry (cwd_cache));
-
- the_panel.last_index = -1;
- for (index = cwd_cache->display_page * the_panel.nthumb_in_page;
- index < max;
- index++)
- thumbnail_panel_draw_thumbnail (directory_cache_get_nth (cwd_cache, index));
-
- thumbnail_panel_finalize_update ();
-
- DPRINT (N_("success to call thumbnail_panel_finalize_update\n"));
-
- gtkW_widget_set_cursor (dlg, CURSOR_DEFAULT);
- gtkW_widget_set_cursor (thumbnail_panel, CURSOR_HAND);
-
- RETURN TRUE;
- }
-
- static gint
- thumbnail_panel_update_delayed (GtkWidget *widget)
- {
- if (0 < delayed_updating)
- {
- delayed_updating = 0;
- thumbnail_panel_update ();
- }
- /* By returning FALSE, this idle_func is removed automatically. */
- return FALSE;
- }
-
- /* this function does not check the current size of thumbnail_panel */
- static gint
- thumbnail_panel_update_partially (gint index)
- {
- gint shown_first = cwd_cache->display_page * the_panel.nthumb_in_page;
- gint unshown_first = shown_first + the_panel.nthumb_in_page;
-
- DEBUGBLOCK (N_("thumbnail_panel_update_partially\n"));
-
- if ((index < shown_first) || (unshown_first <= index))
- RETURN FALSE;
-
- if (index == shown_first)
- {
- the_panel.last_index = -1;
- thumbnail_panel_clear ();
- }
- thumbnail_panel_draw_thumbnail (directory_cache_get_nth (cwd_cache, index));
- DPRINT (N_("success to thumbnail_panel_draw_thumbnail\n"));
-
- RETURN (index == unshown_first - 1);
- }
-
- static void
- thumbnail_panel_update_sensitive_menu ()
- {
- DEBUGBLOCK (N_("thumbnail_panel_update_sensitive_menu\n"));
-
- thumbnail_panel_update_selection_buttons ();
- thumbnail_panel_update_scroller ();
-
- RETURN;
- }
-
- static void
- thumbnail_panel_update_selection_buttons ()
- {
- gint ncommand =
- sizeof (image_selection_commands) / sizeof (image_selection_commands[0]);
- gint flag = selection_is_active ();
- gint i;
-
- for (i = 0; i < ncommand; i++)
- if (image_selection_commands[i].sensitive & SENSITIVE_SELECTION)
- gtk_widget_set_sensitive (image_selection_commands[i].widget, flag);
- for (i = 0 ; i < NSELECTION_BUTTON; i++)
- if (widget_for_selecion[i] != NULL)
- gtk_widget_set_sensitive (widget_for_selecion[i], flag);
-
- #ifndef NEW_DND_API
- for (i = 0 ; i < NSELECTION_BUTTON; i++)
- if (widget_for_selecion[i] != NULL)
- gtk_widget_dnd_drag_set (widget_for_selecion[i],
- flag, possible_dnd_types, 1);
- #endif
- }
-
- static void
- thumbnail_panel_update_scroller ()
- {
- gint ncommand = sizeof (image_root_commands) / sizeof (image_root_commands[0]);
- gint i;
- gint flags[2];
- GtkAdjustment *adjustment;
-
- DEBUGBLOCK (N_("thumbnail_panel_update_scroller display_page %d, max %d\n"),
- cwd_cache->display_page, cwd_cache_npage ());
-
- if (! cwd_cache)
- RETURN;
- if ((widget_pointer[0].widget == NULL) || (widget_pointer[0].updater == NULL))
- RETURN;
-
- flags[0] = flags[1] = TRUE; /* 0 for back(prev), 1 for next */
- if (cwd_cache->display_page == 0)
- flags[0] = FALSE;
- if (cwd_cache_npage () <= 1 + cwd_cache->display_page)
- flags[1] = FALSE;
-
- {
- GCHAR buffer[GTKW_ENTRY_BUFFER_SIZE];
-
- sprintf (buffer, "%d", the_panel.current_page1);
- gtk_entry_set_text (GTK_ENTRY (widget_for_scroll[1]), buffer);
- }
-
- adjustment = (GtkAdjustment *) widget_pointer[0].widget;
- adjustment->value = the_panel.current_page1;
-
- if (adjustment->upper != cwd_cache_npage () + 1)
- {
- gdouble current_page = the_panel.current_page1;
-
- DPRINT (N_("change upper from %d to %d\n"),
- (gint) adjustment->upper,
- cwd_cache_npage () + 1);
-
- adjustment->upper = cwd_cache_npage () + 1;
- /* force update! Wed Aug 26 11:01:02 1998 */
- adjustment->value = -1;
- /* From 0.99.5 changes of the_panel.current_page1 propagates here. */
- gtk_signal_emit_by_name (GTK_OBJECT (adjustment), "changed");
-
- DPRINT (N_("adjustment->value :%d, old :%d\n"),
- (gint) adjustment->value,
- (gint) current_page);
- /* as a side-effect, value is reseted. [Mon Sep 14 15:05:45 1998] */
- adjustment->value = current_page;
- the_panel.current_page1 = current_page;
- /* dirty design! to stop the 2nd panel flush, cancel the result of
- signal_emit [Wed Sep 16 19:15:02 1998] */
- _DPRINT (N_("delayed updating %d\n"), delayed_updating);
- delayed_updating = 0;
- }
- /* The following statement is still required to update scroll-bar. */
- (widget_pointer[0].updater) (widget_pointer);
-
- for (i = 0; i < NSCROLLER; i++)
- {
- gtk_widget_set_sensitive (widget_for_scroll[i],
- (1 < cwd_cache_npage ()));
- gtk_widget_queue_draw (widget_for_scroll[i]);
- }
- {
- gint j = 1;
-
- for (i = 0; i < ncommand; i++)
- if (image_root_commands[i].sensitive & SENSITIVE_SCROLL)
- {
- gtk_widget_set_sensitive (image_root_commands[i].widget, flags[j]);
- j = 0;
- }
- }
-
- DPRINT (N_("display_page: %d\n"), cwd_cache->display_page);
-
- RETURN;
- }
-
- static void
- thumbnail_panel_create_menu_for (GtkWidget *menu,
- image_command_table *commands,
- gint ncommand,
- #ifdef GTK_HAVE_FEATURES_1_1_0
- GtkAccelGroup *accel_group
- #else
- GtkAcceleratorTable *accelerator_table
- #endif
- )
- {
- GtkWidget *menu_item;
- gint i;
-
- #ifdef GTK_HAVE_FEATURES_1_1_0
- gtk_menu_set_accel_group (GTK_MENU (menu), accel_group);
- #else
- gtk_menu_set_accelerator_table (GTK_MENU (menu), accelerator_table);
- #endif
- for (i = 0; i < ncommand; i++)
- {
- if (commands[i].label)
- menu_item = gtk_menu_item_new_with_label (commands[i].label);
- else
- menu_item = gtk_menu_item_new ();
-
- commands[i].widget = menu_item;
- gtk_menu_append (GTK_MENU (menu), menu_item);
- if (commands[i].command)
- gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
- (GtkSignalFunc) commands[i].command,
- (gpointer) commands[i].label);
- else if (commands[i].label)
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item),
- thumbnail_panel_root_menu);
-
- if (commands[i].label
- && (commands[i].binding[binding_style].key != 0))
- #ifdef GTK_HAVE_FEATURES_1_1_0
- gtk_widget_add_accelerator (menu_item,
- "activate",
- accel_group,
- commands[i].binding[binding_style].key,
- commands[i].binding[binding_style].mod,
- GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED);
- #else
- gtk_widget_install_accelerator (menu_item,
- accelerator_table,
- "activate",
- commands[i].binding[binding_style].key,
- commands[i].binding[binding_style].mod);
- #endif
- gtk_widget_show (menu_item);
- if (! commands[i].label) /* separator should not focus on */
- gtk_widget_set_sensitive (menu_item, FALSE);
- }
- #ifndef GTK_HAVE_FEATURES_1_1_0
- gtk_window_add_accelerator_table (GTK_WINDOW (dlg), accelerator_table);
- #endif
- }
-
- static void
- thumbnail_panel_create_menu ()
- {
- #ifdef GTK_HAVE_FEATURES_1_1_0
- GtkAccelGroup *accel_group = gtk_accel_group_new ();
- #else
- GtkAcceleratorTable *accelerator_table = gtk_accelerator_table_new ();
- #endif
- gint modified = FALSE;
-
- DEBUGBLOCK (N_("thumbail_panel_create_menu\n"));
- if (! thumbnail_panel_root_menu)
- {
- thumbnail_panel_root_menu = gtk_menu_new ();
- thumbnail_panel_create_menu_for (thumbnail_panel_root_menu,
- image_root_commands,
- sizeof (image_root_commands)
- / sizeof (image_root_commands[0]),
- #ifdef GTK_HAVE_FEATURES_1_1_0
- accel_group
- #else
- accelerator_table
- #endif
- );
- modified = TRUE;
- }
- if (! thumbnail_panel_selection_menu)
- {
- thumbnail_panel_selection_menu = gtk_menu_new ();
- thumbnail_panel_create_menu_for (thumbnail_panel_selection_menu,
- image_selection_commands,
- sizeof (image_selection_commands)
- / sizeof (image_selection_commands[0]),
- #ifdef GTK_HAVE_FEATURES_1_1_0
- accel_group
- #else
- accelerator_table
- #endif
- );
- modified = TRUE;
- }
- if (! thumbnail_panel_hidden_menu)
- {
- thumbnail_panel_hidden_menu = gtk_menu_new ();
- thumbnail_panel_create_menu_for (thumbnail_panel_hidden_menu,
- image_hidden_commands,
- sizeof (image_hidden_commands)
- / sizeof (image_hidden_commands[0]),
- #ifdef GTK_HAVE_FEATURES_1_1_0
- accel_group
- #else
- accelerator_table
- #endif
- );
- modified = TRUE;
- }
- if (modified)
- #ifdef GTK_HAVE_FEATURES_1_1_0
- gtk_window_add_accel_group (GTK_WINDOW (dlg), accel_group);
- #else
- gtk_window_add_accelerator_table (GTK_WINDOW (dlg),accelerator_table);
- #endif
- RETURN;
- }
-
- static gint
- thumbnail_panel_move_focus (gint offset)
- {
- gint index = -1;
- gint new_index = -1;
- gint new_page = cwd_cache->display_page;
- Thumbnail *thumbnail;
-
- DEBUGBLOCK (N_("thumbnail_panel_move_focus (%d)\n"), offset);
-
- if (selection_is_active ())
- {
- index = cwd_cache->last_focus;
- if (! directory_cache_valid_image_index (cwd_cache, index))
- index = cwd_cache->selection_top;
- new_index = index + offset;
- }
- else
- if (0 < cwd_cache->nimage)
- {
- if (0 < offset)
- new_index = MAX ((cwd_cache->display_page * the_panel.nthumb_in_page),
- cwd_cache->ndir);
- else
- new_index = MIN ((1 + cwd_cache->display_page) * the_panel.nthumb_in_page -1,
- (directory_cache_num_entry (cwd_cache) -1));
- }
- if (directory_cache_valid_image_index (cwd_cache, new_index))
- {
- if (0 < index)
- selection_delete (index);
- new_page = new_index / (the_panel.ncol * the_panel.nrow);
- if (new_page != cwd_cache->display_page)
- {
- cwd_cache->display_page = new_page;
- thumbnail_panel_update ();
- }
- selection_add_and_show (new_index);
- thumbnail = directory_cache_get_nth (cwd_cache, new_index);
- thumbnail_panel_set_info (thumbnail->info);
- cwd_cache->last_focus = new_index;
- }
- else
- thumbnail_panel_set_info (NULL);
-
- thumbnail_panel_update_sensitive_menu ();
-
- RETURN new_index;
- }
-
- /*
- * directory_cache: internal data structure
- */
- static void
- directory_cache_initialize (directory_cache *dcache)
- {
- INITIALIZE_ATTRIBUTES (dcache);
-
- dcache->savable = FALSE;
- dcache->ndir = 0;
- dcache->nimage = 0;
- dcache->display_page = 0;
- dcache->selection_timestamp = 0;
- dcache->num_selection = 0;
- dcache->selection_top = -1;
- dcache->last_focus = 0;
- dcache->timestamp = 0;
- }
-
- static directory_cache *
- directory_cache_new (GCHAR *name)
- {
- directory_cache *p;
- gint i;
-
- DEBUGBLOCK (N_("directory_cache_new\n"));
-
- p = g_new (directory_cache, 1);
- strcpy (p->name, name);
- p->birth_index = directory_cache_table_size;
-
- p->max_ndir = 2;
- p->dir = g_new (Thumbnail, p->max_ndir);
- memset (p->dir, 0, p->max_ndir * sizeof (Thumbnail));
- for (i = 0; i < p->max_ndir; i++)
- thumbnail_initialize (p->dir + i);
-
- p->max_nimage = 16;
- p->image = g_new (Thumbnail, p->max_nimage);
- memset (p->image, 0, p->max_nimage * sizeof (Thumbnail));
- for (i = 0; i < p->max_nimage; i++)
- thumbnail_initialize (p->image + i);
-
- directory_cache_initialize (p);
- p->last_focus = 0;
-
- RETURN p;
- }
-
- static void
- directory_cache_auto_shrink (directory_cache *dcache, gint force)
- {
- gint true_last;
- gint i;
- gint nfree = 0;
-
- __DEBUGBLOCK (N_("directory_cache_auto_shrink (%d in %d)\n"),
- dcache->nimage, dcache->max_nimage);
-
- true_last = dcache->max_nimage - 1;
- while ((0 <= true_last) && ((dcache->image + true_last)->image == NULL))
- true_last--;
- /* now true_last is the index of image which has alloccated memory. */
-
- if (true_last < 0)
- RETURN;
-
- if (force)
- nfree = true_last - dcache->nimage + 1;
- else if (dcache->nimage * 2 < true_last)
- nfree = MAX ((true_last - dcache->nimage) / 2, 1);
-
- /* release memory in reverse order */
- DPRINTIF (0 < nfree) (N_("free %d thumbnail->images\n"), nfree);
-
- for (i = true_last; true_last - nfree < i; i--)
- thumbnail_free_image (dcache->image + i);
-
- /*
- {
- gint flag = TRUE;
-
- DPRINT (N_("seek last index...\n"));
-
- true_last = dcache->max_nimage - 1;
- while ((0 <= true_last) && flag)
- {
- if ((dcache->image + true_last)->image != NULL)
- flag = FALSE;
- else
- true_last--;
- }
- DPRINT (N_("new allocated last is %d\n"), true_last);
- }
- */
- RETURN;
- }
-
- static gint
- directory_cache_garbage_collect (directory_cache *dcache)
- {
- /* side-effect: selection is reset and thumbnail_panel is updated
- */
- gint index;
- gint old_ndir, old_nimage;
- gint nsel = 0;
- Thumbnail *chunk;
-
- DEBUGBLOCK (N_("directory_cache_garbage_collect\n"));
-
- old_ndir = dcache->ndir;
- chunk = dcache->dir;
- index = 0;
- while (index < dcache->ndir)
- {
- if (HAS_ATTRIBUTE (chunk + index, DELETED_P))
- {
- GCHAR *name, *info;
-
- /* shift to the left */
- dcache->ndir--;
- info = chunk[index].info;
- name = chunk[index].name;
-
- g_memmove (chunk + index,
- chunk + (index + 1),
- sizeof (Thumbnail) * (dcache->ndir - index));
- /* the dubbling pointer is back to the world */
- chunk[dcache->ndir].info = info;
- chunk[dcache->ndir].name = name;
- }
- else
- index++;
- }
-
- old_nimage = dcache->nimage;
- chunk = dcache->image;
- index = 0;
- while (index < dcache->nimage)
- {
- if (HAS_ATTRIBUTE (chunk + index, DELETED_P))
- {
- image_buffer *ibuf;
- GCHAR *name, *info;
-
- G_ASSERT (HAS_NO_ATTRIBUTE (chunk + index, SELECTED_P));
-
- /* shift to the left */
- dcache->nimage--;
- ibuf = chunk[index].image;
- info = chunk[index].info;
- name = chunk[index].name;
-
- g_memmove (chunk + index,
- chunk + (index + 1),
- sizeof (Thumbnail) * (dcache->nimage - index));
- /* the dubbling pointer is back to the world */
- chunk[dcache->nimage].image = ibuf;
- chunk[dcache->nimage].info = info;
- chunk[dcache->nimage].name = name;
- }
- else
- {
- if (HAS_ATTRIBUTE (chunk + index, SELECTED_P))
- {
- nsel++;
- if (index < dcache->selection_top)
- dcache->selection_top = index + dcache->ndir;
- }
- index++;
- }
- }
-
- G_ASSERT (nsel == dcache->num_selection);
-
- if (dcache == cwd_cache)
- {
- if (cwd_cache_npage () <= dcache->display_page)
- dcache->display_page = cwd_cache_npage () - 1;
-
- guash_discard_events ();
- DPRINT (N_("npage: %d, display_page: %d\n"),
- cwd_cache_npage (),
- dcache->display_page);
- if (HAS_ATTRIBUTE (cwd_cache, DISORDERED_P))
- {
- directory_cache_reorder (cwd_cache);
- RESET_ATTRIBUTE (cwd_cache, DISORDERED_P);
- DPRINT (N_("success to reorder\n"));
- }
- thumbnail_panel_update ();
- }
-
- RETURN TRUE;
- }
-
- static Thumbnail *
- directory_cache_get_image (directory_cache *dcache, GCHAR *pathname)
- {
- Thumbnail *val = NULL;
-
- G_ASSERT (dcache != NULL);
- G_ASSERT (*pathname == G_DIR_SEPARATOR);
-
- DEBUGBLOCK (N_("directory_cache_get_image (\"%s\", \"%s\")\n"),
- dcache->name, pathname);
-
- if (HAS_ATTRIBUTE (dcache, FILED_P)) /* check thumbnail */
- val = guash_get_image_from_file (pathname, TRUE);
- DPRINT (N_("success to try to load the thumbnail\n"));
-
- if ((val == NULL) && HAS_ATTRIBUTE (dcache, DISPLAY_IMAGE_P))
- {
- val = guash_get_image_from_file (pathname, FALSE);
- if (val != NULL)
- /* Now we can save image as an XV thumbnail.*/
- if (HAS_ATTRIBUTE (&VAL, SAVE_AS_XVPICT_P))
- {
- if (dcache->savable == UNKNOWN)
- directory_cache_make_thumbnail_directory (dcache);
- if (dcache->savable == TRUE)
- {
- directory_cache_save_thumbnail_to (cwd_cache, val);
- DPRINT (N_("success to save thumbnail\n"));
- }
- }
- }
- RETURN val;
- }
-
- static gint
- directory_cache_add_directory (directory_cache *dcache,
- GCHAR *pathname,
- gint f_kind)
- {
- Thumbnail *thumbnail;
-
- DEBUGBLOCK (N_("directory_cache_add_directory (\"%s\", %d)\n"),
- pathname, f_kind);
-
- if ((0 < directory_cache_max_images)
- && (directory_cache_max_images < directory_cache_num_entry (dcache)))
- RETURN FALSE;
-
- if (dcache->max_ndir <= dcache->ndir)
- {
- gint i = dcache->max_ndir;
-
- dcache->max_ndir *= 2;
- dcache->dir =
- (Thumbnail *) g_realloc ((gpointer) dcache->dir,
- dcache->max_ndir * sizeof (Thumbnail));
-
- for (; i < dcache->max_ndir; i++)
- thumbnail_initialize (dcache->dir + i);
-
- DPRINT (N_("expand directory table to %d\n"), dcache->max_ndir);
- }
-
- thumbnail = &dcache->dir[dcache->ndir];
-
- INITIALIZE_ATTRIBUTES (thumbnail);
- RESET_ATTRIBUTE (thumbnail, DELETED_P);
- SET_ATTRIBUTE (thumbnail, DIRECTORY_P);
- SET_TO_ATTRIBUTE (thumbnail, SYMLINK_P, (f_kind == SLNKDIR));
-
- if (thumbnail->name)
- g_free (thumbnail->name);
- thumbnail->name = g_strdup (pathname);
-
- if (dcache->ndir == 0)
- SET_ATTRIBUTE (thumbnail, PARENT_DIRECTORY_P);
-
- if (thumbnail->info)
- g_free (thumbnail->info);
- thumbnail->info = NULL;
-
- thumbnail_free_image (thumbnail);
-
- dcache->ndir++; /* increment before calling update_partially */
-
- if (dcache == cwd_cache)
- thumbnail_panel_update_partially (dcache->ndir - 1);
-
- _DPRINT (N_("success to add_directory\n"));
-
- RETURN TRUE;
- }
-
- static gint
- directory_cache_add_image (directory_cache *dcache,
- GCHAR *pathname,
- Thumbnail *thumb,
- gint f_kind)
- {
- Thumbnail *thumbnail;
-
- DEBUGBLOCK (N_("directory_cache_add_image (\"%s\", %s, %d)\n"),
- pathname, ((thumb != NULL) ? "a thumb." : ""), f_kind);
-
- if ((0 < directory_cache_max_images)
- && (directory_cache_max_images < directory_cache_num_entry (dcache)))
- {
- DPRINT (N_("done (too many: %d)\n"), dcache->nimage);
- RETURN FALSE;
- }
-
- if (dcache->max_nimage <= dcache->nimage)
- {
- gint i = dcache->max_nimage;
-
- DPRINT (N_("expand image table...\n"));
-
- dcache->max_nimage *= 2;
- dcache->image
- = (Thumbnail *) g_realloc ((gpointer) dcache->image,
- dcache->max_nimage * sizeof (Thumbnail));
- for (; i < dcache->max_nimage; i++)
- thumbnail_initialize (dcache->image + i);
-
- DPRINT (N_("expand image table...done\n"));
- }
-
- thumbnail = &dcache->image[dcache->nimage];
-
- G_ASSERT (thumbnail);
-
- INITIALIZE_ATTRIBUTES (thumbnail);
-
- if (thumbnail->info)
- g_free (thumbnail->info);
-
- if (thumb != NULL)
- {
- thumbnail_copy_data (thumbnail, thumb, FALSE);
-
- if (f_kind == SLNKFILE)
- {
- GCHAR tmp[LINE_BUF_SIZE];
-
- sprintf (tmp, _("(symlink) %s"), thumb->info);
- thumbnail->info = g_strdup (tmp);
- }
- else
- thumbnail->info = g_strdup (thumb->info);
- }
- else
- {
- thumbnail_free_image (thumbnail);
- thumbnail->info = g_strdup (pathname_get_basename (pathname));
- }
-
- RESET_ATTRIBUTE (thumbnail, DIRECTORY_P);
- RESET_ATTRIBUTE (thumbnail, PARENT_DIRECTORY_P);
- SET_TO_ATTRIBUTE (thumbnail, SYMLINK_P, (f_kind == SLNKFILE));
- if (thumbnail->name)
- g_free (thumbnail->name);
- thumbnail->name = g_strdup (pathname_get_basename (pathname));
-
- dcache->nimage++;
-
- if (dcache == cwd_cache)
- thumbnail_panel_update_partially (directory_cache_num_entry (dcache) - 1);
- RETURN TRUE;
- }
-
- static gint
- directory_cache_num_entry (directory_cache *dcache)
- {
- return dcache->ndir + dcache->nimage;
- }
-
- static gint
- directory_cache_valid_index (directory_cache *dcache, gint index)
- {
- return ((0 <= index) && (index < dcache->ndir + dcache->nimage));
- }
-
- static gint
- directory_cache_valid_image_index (directory_cache *dcache, gint index)
- {
- return ((dcache->ndir <= index) && (index < dcache->ndir + dcache->nimage));
- }
-
- static directory_cache *
- directory_cache_of (GCHAR *name)
- {
- return (directory_cache *) g_hash_table_lookup (directory_cache_table,
- (gpointer) name);
- }
-
- static void
- directory_cache_reorder (directory_cache *dcache)
- {
- int (func)(Thumbnail *, Thumbnail *);
-
- DEBUGBLOCK (N_("directory_cache_reorder\n"));
-
- if (HAS_ATTRIBUTE (dcache, SORT_BY_NAME_P))
- {
- qsort (dcache->dir,
- dcache->ndir,
- sizeof (Thumbnail),
- (sort_compare_function) thumbnail_compare_name);
- qsort (dcache->image,
- dcache->nimage,
- sizeof (Thumbnail),
- (sort_compare_function) thumbnail_compare_name);
- DPRINT (N_("success to reorder by name\n"));
- }
-
- if (0 < dcache->num_selection)
- {
- gint i;
- Thumbnail *thumb = dcache->image;
-
- dcache->selection_top = -1;
- for (i = 0; i < dcache->nimage; i++, thumb++)
- if (HAS_ATTRIBUTE (thumb, SELECTED_P))
- {
- dcache->selection_top = i + dcache->ndir;
- break;
- }
- DPRINT (N_("success to recompute selection_top\n"));
- }
- RETURN;
- }
-
- static void
- directory_cache_table_aging (gpointer key,
- gpointer value,
- gpointer user_data)
- {
- directory_cache *dcache = (directory_cache *) value;
-
- if (dcache != cwd_cache)
- {
- if (cwd_cache->birth_index < dcache->birth_index)
- dcache->birth_index--;
- }
- DPRINT (N_("birth_index:%d (cwd_cache:%d)\n"),
- dcache->birth_index,
- cwd_cache->birth_index);
- }
-
- static void
- directory_cache_table_recycler (gpointer key,
- gpointer value,
- gpointer user_data)
- {
- directory_cache *dcache, **fail_safe;
-
- dcache = (directory_cache *) value;
- fail_safe = (directory_cache **)user_data;
-
- /* This is for fail safe */
- if ((cwd_cache == NULL) && (*fail_safe == NULL))
- *fail_safe = dcache;
-
- /* set the oldest entry to cwd_cache */
- if ((--(dcache->birth_index) == 0) && (cwd_cache == NULL))
- cwd_cache = (directory_cache *) value;
- }
-
- static Thumbnail *
- directory_cache_get_nth (directory_cache *dcache, gint index)
- {
- G_ASSERT (index < directory_cache_num_entry (dcache));
-
- if (index < dcache->ndir)
- {
- G_ASSERT (dcache->dir);
- return dcache->dir + index;
- }
- else
- {
- G_ASSERT (dcache->image);
- return dcache->image + (index - dcache->ndir);
- }
- }
-
- static Thumbnail *
- directory_cache_lookup (directory_cache *dcache, GCHAR *name)
- {
- gint index;
- Thumbnail *ptr = dcache->image;
-
- for (index = 0; index < dcache->nimage; index++)
- if (strcmp ((ptr + index)->name, name) == 0)
- return (ptr + index);
- return NULL;
- }
-
- static gint
- directory_cache_make_thumbnail_directory (directory_cache *dentry)
- {
- GCHAR *thumbnail_dir;
- mode_t mode = NEW_DIRECTORY_MODE;
-
- DEBUGBLOCK (N_("directory_cache_make_thumbnail_directory (\"%s\")\n"),
- dentry->name);
-
- thumbnail_dir = pathname_build_thumbnail_dirname (dentry->name);
-
- if (os_make_directory (thumbnail_dir, mode) == -1)
- {
- switch (errno)
- {
- case EEXIST:
- dentry->savable = os_file_is_writable (thumbnail_dir);
- SET_ATTRIBUTE (dentry, FILED_P);
- break;
- default:
- dentry->savable = FALSE;
- RESET_ATTRIBUTE (dentry, FILED_P);
- break;
- }
- g_free (thumbnail_dir);
- RETURN FALSE;
- }
- else
- {
- dentry->savable = TRUE;
- SET_ATTRIBUTE (dentry, FILED_P);
-
- g_free (thumbnail_dir);
- RETURN TRUE;
- }
- }
-
- static gint
- directory_cache_save_thumbnail_to (directory_cache *dcache,
- Thumbnail *thumb)
- {
- GString *s;
-
- DEBUGBLOCK (N_("directory_cache_save_thumbnail_to (%s, %s)\n"),
- dcache->name, thumb->name);
-
- G_ASSERT (cwd_cache->savable != FALSE);
-
- s= g_string_new (pathname_build_thumbnail_dirname (dcache->name));
- g_string_append_c (s, G_DIR_SEPARATOR);
- G_ASSERT (thumb->name);
- g_string_append (s, thumb->name);
-
- dcache->savable = save_thumbnail_as_xvpict_image (s->str, thumb);
- SET_ATTRIBUTE (cwd_cache, FILED_P);
-
- g_string_free (s, TRUE);
-
- RETURN TRUE;
- }
-
- /* if force is TRUE, all thumbnails and directory are deleted.
- * Otherwise, only obsolete thumbnails are deleted.
- * This function returns TRUE if some thumbnail is old. Otherwise FALSE.
- */
- static gint
- directory_cache_delete_invalid_cache_files (directory_cache *dcache,
- gint force)
- {
- GCHAR *path;
- DIR *dir;
- struct dirent *dentry;
- gint index = 0;
- gint flag = FALSE;
-
- DEBUGBLOCK (N_("directory_cache_delete_invalid_cache_files\n"));
-
- path = pathname_build_thumbnail_dirname (dcache->name);
-
- if (os_file_kind (path, TRUE) != DIRECTORY)
- RETURN flag;
-
- dir = opendir (path);
- rewinddir (dir);
-
- for (; (dentry = readdir (dir)); index++)
- {
- GString *file;
-
- file = g_string_new (g_strdup (path));
- g_string_append_c (file, G_DIR_SEPARATOR);
- g_string_append (file, dentry->d_name);
-
- if (os_file_kind (file->str, TRUE) == REGFILE)
- {
- if (force || (pathname_is_valid_thumbnail_filename (file->str) == FALSE))
- {
- DPRINT (N_("delete thumbnail file: %s\n"), file->str);
- os_delete_file (file->str);
- flag = TRUE;
- }
- }
- g_string_free (file, TRUE);
- }
- if (force)
- {
- if (os_delete_file (path) == 0)
- thumbnail_panel_set_info (_("Thumbnail directory was deleted"));
- else
- thumbnail_panel_set_info (_("Failed to delete thumbnail directory (permission problem?)"));
-
- RESET_ATTRIBUTE (dcache, FILED_P);
- }
-
- g_free (path);
- closedir (dir);
-
- RETURN flag;
- }
-
- static GtkWidget *
- directory_cache_create_parents_menu ()
- {
- GtkWidget *menu;
- gint count, index;
- GCHAR *cwd;
- GtkWidget *menuitem;
- GCHAR *label = NULL;
-
- menu = gtk_menu_new ();
- cwd = cwd_cache->name;
-
- label = (GCHAR *) g_malloc (2);
- label[0] = G_DIR_SEPARATOR;
- label[1] = 0;
- menuitem = gtk_menu_item_new_with_label (label);
- gtk_menu_append (GTK_MENU (menu), menuitem);
- gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
- (GtkSignalFunc) menu_change_directory_callback,
- (gpointer) label);
- gtk_widget_show (menuitem);
-
- for (count = index = 1; index < strlen (cwd); index++)
- if (cwd[index] == G_DIR_SEPARATOR)
- {
- label = (GCHAR *) g_malloc (index);
- g_memmove (label, cwd, index);
- label[index] = 0;
-
- menuitem = gtk_menu_item_new_with_label (label);
- gtk_menu_prepend (GTK_MENU (menu), menuitem);
- gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
- (GtkSignalFunc) menu_change_directory_callback,
- (gpointer) label);
- gtk_widget_show (menuitem);
- }
-
- return menu;
- }
-
- static void
- directory_cache_create_history_menu_foreach (gpointer key,
- gpointer value,
- gpointer user_data)
- {
- GtkWidget *menu_item;
- GtkWidget *menu;
-
- menu = (GtkWidget *) user_data;
-
- menu_item = gtk_menu_item_new_with_label ((GCHAR *)key);
- gtk_menu_append (GTK_MENU (menu), menu_item);
- gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
- (GtkSignalFunc) menu_change_directory_callback,
- key);
- gtk_widget_show (menu_item);
- }
-
- static GtkWidget *
- directory_cache_create_history_menu ()
- {
- GtkWidget *menu;
-
- menu = gtk_menu_new ();
-
- g_hash_table_foreach (directory_cache_table,
- directory_cache_create_history_menu_foreach,
- menu);
-
- return menu;
- }
-
- static gint
- directory_cache_update_selection (directory_cache *dcache, gint kind, gint index)
- {
- Thumbnail *thumb = directory_cache_get_nth (dcache, index);
-
- G_ASSERT (thumb);
- G_ASSERT (0 <= index);
-
- dcache->last_focus = index;
-
- if (kind == SELECTION_ADD)
- {
- if (HAS_ATTRIBUTE (thumb, SELECTED_P))
- return TRUE;
-
- SET_ATTRIBUTE (thumb, SELECTED_P);
- thumb->selection_timestamp = ++dcache->selection_timestamp;
-
- if (dcache->num_selection == 0)
- dcache->selection_top = index;
- else
- dcache->selection_top = MIN (dcache->selection_top, index);
-
- dcache->num_selection++;
- DPRINT (N_("num_selection: %d\n"), dcache->num_selection);
- return TRUE;
- }
- else if (kind == SELECTION_DELETE)
- {
- gint i;
- gint max = directory_cache_num_entry (dcache);
-
- if (HAS_NO_ATTRIBUTE (thumb, SELECTED_P))
- return (0 < dcache->num_selection);
-
- RESET_ATTRIBUTE (thumb, SELECTED_P);
-
- if (0 < dcache->num_selection)
- dcache->num_selection--;
- DPRINT (N_("num_selection: %d\n"), dcache->num_selection);
-
- if (dcache->num_selection == 0)
- {
- dcache->last_focus = 0;
- return FALSE;
- }
- if (dcache->selection_top == index)
- for (i = index; i < max; i++)
- {
- if (HAS_ATTRIBUTE (directory_cache_get_nth (dcache, i), SELECTED_P))
- {
- dcache->selection_top = i;
- return TRUE;
- }
- }
- return TRUE;
- }
- return FALSE;
- }
-
- /* name is a short name, which does not include the directory part */
- static gint
- directory_cache_update_thumbnail_for (directory_cache *dcache,
- GCHAR *pathname,
- Thumbnail *src_thumb)
- {
- Thumbnail *thumbnail, *thumb = NULL;
- gint offset, index;
- gint last_index;
- GCHAR *basename = pathname_get_basename (pathname);
-
- DEBUGBLOCK (N_("directory_cache_update_thumbnail_for (\"%s\", \"%s\" with%s thumb.)\n"),
- dcache->name,
- pathname,
- (src_thumb == NULL ? "out" : ""));
-
- if (src_thumb)
- thumb = src_thumb;
-
- if ((thumbnail = directory_cache_lookup (dcache, basename)) == NULL)
- {
- DPRINT (N_("%s is a new image file\n"), basename);
-
- if ((thumb == NULL)
- && ((thumb = directory_cache_get_image (dcache, pathname)) == NULL))
- {
- if (HAS_ATTRIBUTE (dcache, DISPLAY_IMAGE_P))
- RETURN FALSE;
- }
-
- directory_cache_add_image (dcache, pathname, thumb,
- os_file_kind (pathname, FALSE));
- SET_ATTRIBUTE (dcache, DISORDERED_P);
- RETURN TRUE;
- }
-
- if ((thumb == NULL)
- && ((thumb = directory_cache_get_image (dcache, pathname)) == NULL))
- RETURN FALSE;
-
- /* copy all data [Sun Sep 13 15:15:24 1998] */
- thumbnail_copy_data (thumbnail, thumb, TRUE);
-
- DPRINT (N_("success to copy all data\n"));
-
- if (dcache != cwd_cache)
- RETURN FALSE;
-
- offset = POS_TO_INDEX (0, 0);
- last_index = MIN (offset + the_panel.nthumb_in_page,
- directory_cache_num_entry (dcache));
- for (index = offset; index < last_index; index++)
- {
- if (directory_cache_get_nth (dcache, index) == thumbnail)
- {
- DPRINT (N_("updated thumbnail is the %dth thumb in the panel\n"),
- index);
- RETURN TRUE;
- break;
- }
- }
-
- RETURN FALSE;
- }
-
- /*
- * cwd_cache: special function only for cwd_cache
- */
-
- static gint
- cwd_cache_npage ()
- {
- gint page;
-
- page = directory_cache_num_entry (cwd_cache) / the_panel.nthumb_in_page;
- if (directory_cache_num_entry (cwd_cache) % the_panel.nthumb_in_page != 0)
- page++;
- return page;
- }
-
- static gint
- cwd_cache_jump_to_subdirectory_index (gint nth)
- {
- if (nth < cwd_cache->ndir)
- {
- Thumbnail *thumb = directory_cache_get_nth (cwd_cache, nth);
- GCHAR tmp[PATH_LENGTH];
-
- sprintf (tmp, "%s%c%s", cwd_cache->name, G_DIR_SEPARATOR, thumb->name);
- guash_change_current_directory (tmp, thumb);
- return TRUE;
- }
- else
- return FALSE;
- }
-
- static gint
- cwd_cache_validate ()
- {
- __DEBUGBLOCK (N_("cwd_cache_validate\n"));
-
- if (os_file_kind (cwd_cache->name, TRUE) == NOT_EXIST)
- {
- GCHAR *new_dir;
-
- gdk_beep ();
- thumbnail_panel_set_info (_("Error: the directory does not exist now!"));
- gdk_flush ();
-
- DPRINT (N_("cwd_cache->name %s\n"), cwd_cache->name);
- sleep (1);
- new_dir = pathname_get_vaild_directoryname (cwd_cache->name);
- os_file_change_current_directory (new_dir);
- /* to delete the obsolete directory_cache, we must recycle it now.
- Thus hack the name before calling guash_update_cwd_cache. */
- strcpy (cwd_cache->name, new_dir);
- g_free (new_dir);
- guash_update_cwd_cache (RESCAN);
-
- thumbnail_panel_set_info (_("Error: the directory does not exist now! Jumped up"));
-
- RETURN FALSE;
- }
- else
- RETURN TRUE;
- }
-
- static gint
- cwd_cache_update ()
- {
- /* side-effect: selection is reset */
- GCHAR path[PATH_LENGTH], counter[256], *fname;
- gint index_to_update;
- gint index = 0;
- GCHAR **filename_list;
- gint nentry;
- gint update_threshold;
- #ifdef DELETE_CORE
- gint no_core;
- #endif
-
- DEBUGBLOCK (N_("cwd_cache_update\n"));
-
- gtkW_widget_set_cursor (dlg, CURSOR_WAIT);
- gtkW_widget_set_cursor (thumbnail_panel, CURSOR_WAIT);
- {
- GCHAR *thumbnail_dir;
-
- thumbnail_dir = pathname_build_thumbnail_dirname (cwd_cache->name);
- switch (os_file_kind (thumbnail_dir, TRUE))
- {
- case NOT_EXIST:
- cwd_cache->savable = UNKNOWN;
- RESET_ATTRIBUTE (cwd_cache, FILED_P);
- break;
- case DIRECTORY:
- cwd_cache->savable = os_file_is_writable (thumbnail_dir);
- SET_ATTRIBUTE (cwd_cache, FILED_P);
- break;
- default:
- cwd_cache->savable = FALSE;
- RESET_ATTRIBUTE (cwd_cache, FILED_P);
- break;
- }
- g_free (thumbnail_dir);
- }
- /* set attributes here. The values may be used by
- thumbnail_panel_update_partially. */
- COPY_ATTRIBUTE (cwd_cache, DISPLAY_IMAGE_P, &VAL);
- COPY_ATTRIBUTE (cwd_cache, SORT_BY_NAME_P, &VAL);
-
- if (VAL.last_dir_name[0] != 0)
- {
- thumbnail_panel_clear ();
- gtkW_preview_force_to_update (thumbnail_panel);
- }
- if (HAS_ATTRIBUTE (cwd_cache, FILED_P))
- gtk_window_set_title (GTK_WINDOW (dlg),
- "Guash: scanning with saved thumbnails...");
- else
- gtk_window_set_title (GTK_WINDOW (dlg),
- "Guash: wait a minute...");
- #ifdef GTK_HAVE_FEATURES_1_1_0
- gtk_label_set_text (GTK_LABEL (cwd_label), cwd_cache->name);
- #else
- gtk_label_set (GTK_LABEL (cwd_label), cwd_cache->name);
- #endif
- gtk_widget_draw (cwd_label, NULL);
-
- selection_reset ();
-
- cwd_cache->nimage = cwd_cache->ndir = 0;
- index_to_update = (1 + cwd_cache->display_page) * the_panel.nthumb_in_page;
-
- {
- GCHAR *tmp;
-
- tmp = pathname_get_directoryname (cwd_cache->name);
- directory_cache_add_directory (cwd_cache, tmp, DIRECTORY);
- g_free (tmp);
- }
-
- DPRINT (N_("scandir %s\n"), cwd_cache->name);
- nentry = os_scandir (cwd_cache->name, &filename_list, &os_scandir_selector,
- HAS_ATTRIBUTE (&VAL, SORT_BY_NAME_P));
-
- /* For displaying eagarly, I use two pass scanning. */
- #ifdef DELETE_CORE
- /* before the traverse, check the existance of core */
- no_core = (os_file_kind ("core", TRUE) == NOT_EXIST);
-
- DPRINTIF (! no_core) (N_("Checking core: found\n"));
- #endif
-
- /* 1st path: for collecting directories */
- DPRINT (N_("Scanning directory 1st path\n"));
- thumbnail_panel_set_info ("Reading the directory.");
-
- for (index = 0; index < nentry; index++)
- {
- gint f_kind = NOT_EXIST;
-
- fname = filename_list[index];
- if (fname[0] == '.')
- continue;
-
- f_kind = os_file_kind (fname, FALSE);
-
- switch (f_kind)
- {
- case DIRECTORY:
- case SLNKDIR:
- directory_cache_add_directory (cwd_cache, fname, f_kind);
- break;
- default:
- break;
- }
- }
- if (index_to_update < cwd_cache->ndir)
- {
- /* gtkW_preview_force_to_update (thumbnail_panel); */
- /* stop further update */
- index_to_update = -1;
- }
-
- /* 2nd path: for loading image files */
- DPRINT (N_("Scanning directory 2nd path\n"));
- thumbnail_panel_set_info (_("Reading the directory.."));
-
- update_threshold = the_panel.ncol;
- for (index = 0; index < nentry; index++)
- {
- gint f_kind = NOT_EXIST;
- gint no_need_to_load = FALSE;
-
- if (index == update_threshold)
- {
- sprintf (counter, _("Reading the directory (%02.0f%%)..."),
- 100 * (gfloat) index / (gfloat) nentry);
- thumbnail_panel_set_info (counter);
- update_threshold += update_threshold + the_panel.nthumb_in_page / 2;
- }
-
- fname = filename_list[index];
- if (fname[0] == '.')
- continue;
- no_need_to_load = pathname_match_inhibit_suffix (fname);
- if (no_need_to_load && HAS_ATTRIBUTE (cwd_cache, DISPLAY_IMAGE_P))
- continue;
-
- sprintf (path, "%s%c%s", cwd_cache->name, G_DIR_SEPARATOR, fname);
- f_kind = os_file_kind (path, FALSE);
-
- switch (f_kind)
- {
- case REGFILE:
- case SLNKFILE:
- /* new semantics from 1.2.0 [Wed Sep 9 02:31:44 1998] */
- if ((! no_need_to_load)
- && (directory_cache_get_image (cwd_cache, path) != NULL))
- directory_cache_add_image (cwd_cache, path, the_loaded_data, f_kind);
- else if (HAS_NO_ATTRIBUTE (cwd_cache, DISPLAY_IMAGE_P))
- directory_cache_add_image (cwd_cache, path, NULL, f_kind);
- else
- {
- DPRINT (N_("non image: %s\n"), fname);
- }
- break;
- default:
- break;
- }
- if (index_to_update == directory_cache_num_entry (cwd_cache))
- {
- /* gtkW_preview_force_to_update (thumbnail_panel); */
- /* if the next entry is non-directory/image, another update is
- occurred, unless reset index_to_update. */
- index_to_update = -1;
- }
- }
- g_free (filename_list);
-
- DPRINT (N_("end of scan\n"));
-
- #ifdef DELETE_CORE
- if (no_core && (os_file_kind ("core", TRUE) == REGFILE))
- {
- DPRINT (N_("unlink newly generated core file\n"));
- os_delete_file ("core");
- if (os_file_kind ("core", TRUE) == NOT_EXIST)
- DPRINT (N_("success to remove core\n"));
- else
- DPRINT (N_("fail to remove core!\n"));
- }
- #endif
- cwd_cache->timestamp = os_file_get_modify_timestamp (cwd_cache->name);
-
- if (cwd_cache_npage () <= cwd_cache->display_page)
- {
- cwd_cache->display_page = cwd_cache_npage () - 1;
- thumbnail_panel_update ();
- }
- else if (directory_cache_num_entry (cwd_cache) < index_to_update)
- {
- thumbnail_panel_finalize_update ();
- }
- else
- {
- /* Then thumbnail_panel doesn't know the true number of dir & image. */
- thumbnail_panel_finalize_update ();
- if ((0 < directory_cache_max_images)
- && (directory_cache_max_images < directory_cache_num_entry (cwd_cache)))
- {
- GCHAR buffer[256];
-
- sprintf (buffer,
- _("Warning: # of files is beyond the display limit (%d)"),
- directory_cache_max_images);
- thumbnail_panel_set_info (buffer);
- printf (buffer);
- printf (".\nCheck guash's README file to control display limit\n");
- }
- else
- thumbnail_panel_set_info (NULL);
- }
- if (guash_discard_events ())
- thumbnail_panel_set_info (_("FYI, events during directory scan were discarded"));
-
- directory_cache_auto_shrink (cwd_cache, FALSE);
-
- gtkW_widget_set_cursor (dlg, CURSOR_DEFAULT);
- gtkW_widget_set_cursor (thumbnail_panel, CURSOR_HAND);
-
- RETURN TRUE;
- }
-
- static gint
- cwd_cache_update_after_file_operation (gint count,
- GCHAR *operation,
- GCHAR *first_success,
- GCHAR *target)
- {
- GCHAR buffer[LINE_BUF_SIZE];
-
- G_ASSERT (0 < count);
-
- if (HAS_ATTRIBUTE (cwd_cache, DISORDERED_P))
- guash_update_cwd_cache (GC);
-
- if (target)
- {
- if (count == 1)
- sprintf (buffer, _("%s was %s to %s"), first_success, operation, target);
- else
- sprintf (buffer, _("%d files were %s to %s"), count, operation, target);
- }
- else
- {
- if (count == 1)
- sprintf (buffer, _("%s was %s"), first_success, operation);
- else
- sprintf (buffer, _("%d files were %s"), count, operation);
- }
-
- thumbnail_panel_set_info (buffer);
-
- cwd_cache->timestamp = os_file_get_modify_timestamp (cwd_cache->name);
-
- return TRUE;
- }
-
- /*
- * image_buffer
- */
- static image_buffer *
- image_buffer_new (gint width, gint height, gint ch)
- {
- image_buffer *new;
-
- DEBUGBLOCK (N_("image_buffer_new (%d, %d, %d)\n"), width, height, ch);
-
- new = g_new (image_buffer, 1);
-
- G_ASSERT (new);
-
- new->size = 0;
- new->data = NULL;
- image_buffer_resize (new, width, height, ch);
-
- RETURN new;
- }
-
- static void
- image_buffer_resize (image_buffer *ibuf, gint width, gint height, gint ch)
- {
- gint size = width * height * ch;
-
- DEBUGBLOCK (N_("image_buffer_resize (%d %d %d: %d)\n"),
- width, height, ch, ibuf->size);
-
- if ((ibuf->size < size) || (! ibuf->data))
- {
- if (ibuf->data)
- g_free (ibuf->data);
- ibuf->size = size;
- ibuf->data = g_new (guchar, size);
- G_ASSERT (ibuf->data);
- memset (ibuf->data, 0, ibuf->size);
- }
- ibuf->width = width;
- ibuf->height = height;
- ibuf->ch = ch;
-
- RETURN;
- }
-
- static void
- image_buffer_free (image_buffer *ibuf)
- {
- G_ASSERT (ibuf);
-
- if (ibuf->data)
- g_free (ibuf->data);
-
- g_free (ibuf);
- }
-
- static image_buffer *
- image_buffer_new_with_header (gchar *data, gint width, gint height)
- {
- image_buffer *new;
- guchar *ptr;
-
- DEBUGBLOCK (N_("image_buffer_new_with_header\n"));
-
- new = image_buffer_new (width, height, 3);
- for (ptr = new->data; ptr < new->data + new->size; ptr += 3)
- HEADER_PIXEL (data, ptr);
-
- RETURN new;
- }
-
- static image_buffer *
- image_buffer_set_from_header (image_buffer *buffer,
- gchar *data,
- gint width,
- gint height)
- {
- guchar *ptr;
-
- DEBUGBLOCK (N_("image_buffer_set_from_header"));
-
- image_buffer_resize (buffer, width, height, 3);
-
- for (ptr = buffer->data; ptr < buffer->data + buffer->size; ptr += 3)
- HEADER_PIXEL (data, ptr);
-
- RETURN buffer;
- }
-
- static void
- image_buffer_copy (image_buffer *dest, image_buffer *src)
- {
- G_ASSERT (src->data);
-
- DEBUGBLOCK (N_("image_buffer_copy\n"));
-
- image_buffer_resize (dest, src->width, src->height, src->ch);
- g_memmove (dest->data, src->data, src->width * src->height * src->ch);
-
- RETURN;
- }
-
- static void
- image_buffer_copy_drawable (image_buffer *ibuf, gint32 drawable_id)
- {
- gint x, y;
- GDrawable *drawable;
- GPixelRgn src_rgn;
- GCHAR *src;
- gpointer pr;
- gint gap = 0;
-
- DEBUGBLOCK (N_("thumbnail_set_data_from_drawable\n"));
-
- image_buffer_resize (ibuf, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, 3);
-
- drawable = gimp_drawable_get (drawable_id);
- G_ASSERT (drawable != NULL);
-
- ibuf->width = gimp_drawable_width (drawable_id);
- ibuf->height = gimp_drawable_height (drawable_id);
-
- gap = (gimp_drawable_has_alpha (drawable_id)) ? 1 : 0;
- gimp_pixel_rgn_init (&src_rgn, drawable, 0, 0,
- ibuf->width, ibuf->height,
- FALSE, FALSE);
- pr = gimp_pixel_rgns_register (1, &src_rgn);
-
- for (; pr != NULL; pr = gimp_pixel_rgns_process (pr))
- {
- gint gx = src_rgn.x;
- gint gy = src_rgn.y;
-
- for (y = 0; y < src_rgn.h; y++)
- {
- src = src_rgn.data + y * src_rgn.rowstride;
-
- for (x = 0; x < src_rgn.w; x++)
- {
- guchar *ch = src + (x * (3 + gap));
- gint offset = (gy + y) * ibuf->width * 3 + (gx + x) * 3;
-
- ibuf->data[offset ] = *ch;
- ibuf->data[offset + 1] = *(ch + 1);
- ibuf->data[offset + 2] = *(ch + 2);
- }
- }
- }
-
- RETURN;
- }
-
- /*
- * Thumbnail
- */
- static void
- thumbnail_initialize (Thumbnail *thumb)
- {
- G_ASSERT (thumb);
-
- INITIALIZE_ATTRIBUTES (thumb);
- thumb->image = NULL;
- thumb->name = NULL;
- thumb->info = NULL;
- }
-
- static gint
- thumbnail_compare_name (Thumbnail *a, Thumbnail *b)
- {
- return strcmp (a->name, b->name);
- }
-
- static void
- thumbnail_copy_data (Thumbnail *dest, Thumbnail *src, gint all_p)
- {
- DEBUGBLOCK (N_("thumbnail_copy_data (to %sinitialized thumb.)\n"),
- (dest->image ? "" : "un"));
-
- if (src->image != NULL)
- {
- if (! dest->image)
- {
- dest->image = image_buffer_new (THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, 1);
- DPRINT (N_("success to new\n"));
- }
- image_buffer_copy (dest->image, src->image);
- DPRINT (N_("success to copy to image_buffer\n"));
- }
- else
- {
- DPRINT (N_("src thumbnail has no image_buffer\n"));
- }
-
- if (all_p)
- {
- G_ASSERT (src->name);
-
- if (dest->name)
- g_free (dest->name);
- dest->name = g_strdup (src->name);
-
- G_ASSERT (src->info);
-
- if (dest->info)
- g_free (dest->info);
- dest->info = g_strdup (src->info);
- }
- RETURN;
- }
-
- static void
- thumbnail_free_image (Thumbnail *thumb)
- {
- DEBUGBLOCK (N_("thumbnail_free_image\n"));
- G_ASSERT (thumb);
-
- if (thumb->image)
- {
- image_buffer_free (thumb->image);
- thumb->image = NULL;
- }
- RETURN;
- }
-
- /*
- * filename
- */
-
- /* foo/bar.baz => foo/bar.baz/.xvpics */
- static GCHAR *
- pathname_build_thumbnail_dirname (GCHAR *dirname)
- {
- gint dir_len, cd_len, cp_len;
- GCHAR *thumbnail_dcname;
- GCHAR *thumbnail_dir = THUMBNAIL_DIR;
-
- dir_len = strlen (dirname);
- cd_len = strlen (THUMBNAIL_DIR);
- cp_len = dir_len + cd_len;
- thumbnail_dcname = (GCHAR *) g_malloc (cp_len + 1);
-
- g_memmove (thumbnail_dcname, dirname, dir_len);
- g_memmove (thumbnail_dcname + dir_len, thumbnail_dir, cd_len);
- thumbnail_dcname[cp_len] = 0;
-
- return thumbnail_dcname;
- }
-
- static GCHAR *
- pathname_build_thumbnail_filename (GCHAR *filename)
- {
- gint index;
- gint fname_len, tname_len;
- GCHAR *thumbnail_fcname;
- GCHAR *thumbnail_dir = THUMBNAIL_DIR;
-
- fname_len = strlen (filename);
- tname_len = fname_len + strlen (thumbnail_dir);
- index = pathname_get_last_separator_index (filename);
-
- G_ASSERT (0 <= index);
-
- thumbnail_fcname = (GCHAR *) g_malloc (tname_len + 1);
- g_memmove (thumbnail_fcname, filename, index);
- g_memmove (thumbnail_fcname + index, thumbnail_dir, strlen (thumbnail_dir));
- g_memmove (thumbnail_fcname + (index + strlen (thumbnail_dir)),
- filename + index,
- fname_len - index);
- thumbnail_fcname [tname_len] = 0;
- return thumbnail_fcname;
- }
-
- static GCHAR *
- pathname_get_canonical_name (GCHAR *name)
- {
- GCHAR cwd[PATH_LENGTH];
- GCHAR *dir;
-
- dir = g_malloc (PATH_LENGTH);
-
- os_file_get_current_directory (cwd);
- if (os_file_change_current_directory (name) == -1)
- {
- g_free (dir);
- return NULL;
- }
- os_file_get_current_directory (dir);
- os_file_change_current_directory (cwd);
-
- return dir;
- }
-
- static gint
- pathname_get_last_period_index (GCHAR *pathname)
- {
- gint index;
- gint pname_len;
-
- pname_len = strlen (pathname);
-
- for (index = pname_len - 2; 0 <= index; index--)
- if (pathname[index] == '.') break;
-
- return index;
- }
-
- static gint
- pathname_get_last_separator_index (GCHAR *pathname)
- {
- gint index;
- gint pname_len;
-
- G_ASSERT (pathname);
- pname_len = strlen (pathname);
-
- for (index = pname_len - 2; 0 <= index; index--)
- if (pathname[index] == G_DIR_SEPARATOR) break;
-
- return index;
- }
-
- /* /foo/bar/baz => /foo/bar
- /foo/bar/baz/ => /foo/bar/baz (impossible case)
- */
- static GCHAR *
- pathname_get_directoryname (GCHAR *pathname)
- {
- gint pname_len, slash_pos;
- GCHAR *dirname;
-
- __DEBUGBLOCK (N_("pathname_get_directoryname (\"%s\")\n"), pathname);
- G_ASSERT (pathname);
-
- pname_len = strlen (pathname);
- slash_pos = pathname_get_last_separator_index (pathname);
-
- if (slash_pos <= 0)
- RETURN ((strcmp (pathname, G_DIR_SEPARATOR_S) == 0) ? NULL : g_strdup (G_DIR_SEPARATOR_S));
-
- dirname = (GCHAR *) g_malloc (slash_pos + 1);
- g_memmove (dirname, pathname, slash_pos);
- dirname[slash_pos] = 0;
-
- RETURN dirname;
- }
-
- static GCHAR *
- pathname_get_vaild_directoryname (GCHAR *pathname)
- {
- GCHAR *dirname;
-
- DEBUGBLOCK (N_("pathname_get_vaild_directoryname (\"%s\")\n"), pathname);
- G_ASSERT (pathname);
-
- dirname = pathname_get_directoryname (pathname);
- while (os_file_kind (dirname, TRUE) != DIRECTORY)
- {
- GCHAR *tmp;
-
- tmp = pathname_get_vaild_directoryname (dirname);
- g_free (dirname);
- dirname = tmp;
- }
- RETURN dirname;
- }
-
- /* foo/bar.baz => bar.baz */
- static GCHAR *
- pathname_get_basename (GCHAR *pathname)
- {
- return pathname + pathname_get_last_separator_index (pathname) + 1;
- }
-
- /* pathname_is_valid_thumbnail_filename return nil if:
- 1. thumbnail is older than the corresponding image file, or
- 2. thumbnail file does not exist */
- static gint
- pathname_is_valid_thumbnail_filename (GCHAR *thumbnail_name)
- {
- GCHAR *file_name;
- struct stat image_f, thumbnail_f;
- gint stripper;
- gint last_slash, parent_slash;
-
- stripper = strlen (THUMBNAIL_DIR);
- file_name = (GCHAR *) g_malloc (strlen (thumbnail_name) - stripper + 1);
- last_slash = pathname_get_last_separator_index (thumbnail_name);
- parent_slash = last_slash - strlen (THUMBNAIL_DIR);
- /* /.../dir/ */
- g_memmove (file_name, thumbnail_name, parent_slash);
- /* /.../dir/image.file */
- g_memmove (file_name + parent_slash,
- thumbnail_name + last_slash,
- strlen (thumbnail_name) - last_slash);
- /* /.../dir/image.file + TERMINATOR */
- file_name [strlen (thumbnail_name) - stripper] = 0;
-
- if (stat (file_name, &image_f) != 0)
- return FALSE;
- if (stat (thumbnail_name, &thumbnail_f) != 0)
- return FALSE;
-
- return (image_f.st_mtime <= thumbnail_f.st_mtime);
- }
-
- static gint
- pathname_match_inhibit_suffix (GCHAR *pathname)
- {
- gint index = 0;
- gint pathlen = strlen (pathname);
-
- for (; index < num_inhibit_suffix; index++)
- {
- GCHAR *suffix = inhibit_suffix_table[index];
- gint prelen = strlen (suffix);
-
- if (pathlen < prelen)
- continue;
-
- /* the last letter check. It will be much cheap test. */
- if (suffix[prelen - 1] == pathname[pathlen - 1])
- if (strcmp (suffix, pathname + (pathlen - prelen)) == 0)
- return TRUE;
- }
- return FALSE;
- }
-
- /*
- * system call (mainly file operations) interface
- */
- static gint
- os_file_change_current_directory (GCHAR *pathname)
- {
- #ifdef G_OS_WIN32
- /* //HB: On windoze e.g. chdir("D:") has a special meaning
- * which isn't meant here
- */
- if ((2 == strlen(pathname)) && (':' == pathname[1]))
- return chdir ("\\");
- #endif
- return chdir (pathname);
- }
-
- static void
- os_file_get_current_directory (GCHAR *buffer)
- {
- GCHAR *dir;
-
- *buffer = 0;
-
- /* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
- * and, if that wasn't bad enough, hangs in doing so.
- */
- #if defined (sun) && !defined (__SVR4)
- dir = getwd (buffer);
- #else /* !sun */
- dir = getcwd (buffer, PATH_LENGTH - 1);
- #endif /* !sun */
-
- #ifdef G_OS_WIN32
- /* //HB: Only the root drive gets a backslash at it's end
- * Remove it; we don't need it.
- */
- if ((strlen(buffer) == 3) && (':' == buffer[1]) && ('\\' == buffer[2]))
- buffer[2] = 0;
- #endif
-
- if (!dir || !*buffer)
- {
- /* hm, should we g_error() out here?
- * this can happen if e.g. "./" has mode \0000
- */
- buffer[0] = G_DIR_SEPARATOR;
- buffer[1] = 0;
- }
- }
-
- static gdouble
- os_file_get_modify_timestamp (GCHAR *pathname)
- {
- struct stat path_stat;
-
- stat (pathname, &path_stat);
-
- return (gdouble) path_stat.st_mtime;
- }
-
- /* if b has larger name than a, return 1 */
- /* Warning: file existance check is omitted */
- static gint
- os_file_alphasort (GCHAR **a, GCHAR **b)
- {
- return strcmp (*a, *b);
- }
-
- /* if b is newer than a, return 1 This means we get reverse ordered list. */
- static gint
- os_file_mtimesort (GCHAR **a, GCHAR **b)
- {
- struct stat a_stat;
- struct stat b_stat;
-
- stat (*a, &a_stat);
- stat (*b, &b_stat);
-
- if (a_stat.st_mtime < b_stat.st_mtime)
- return 1;
- else if (a_stat.st_mtime == b_stat.st_mtime)
- return 0;
- else
- return -1;
- }
-
- static gint
- os_scandir_selector (GCHAR *filename)
- {
- return 1;
- }
-
- static gint
- os_scandir (GCHAR *dir_name,
- GCHAR ***filename_list,
- scandir_selector_function selector,
- gint sort_by_name_p)
- {
- GCHAR **list = NULL;
- struct dirent *dirent_ptr;
- DIR *directory;
- gint entry_count = 32;
- gint fail_p = FALSE;
- gint i;
-
- DEBUGBLOCK (N_("os_scandir (\"%s\", ...)\n"), dir_name);
-
- *filename_list = NULL;
- if (! (directory = opendir (dir_name)))
- {
- closedir (directory);
- RETURN 0;
- }
-
- if (NULL == (list = g_new (GCHAR *, entry_count)))
- {
- closedir (directory);
- RETURN 0;
- }
-
- i = 0;
- while ((! fail_p) && (NULL != (dirent_ptr = readdir (directory))))
- {
- if (i == entry_count)
- {
- gint new_count = entry_count * 2;
- GCHAR **new_list = NULL;
-
- /* expand list */
- new_list = g_realloc (list, new_count * sizeof (GCHAR *));
- if (new_list == NULL)
- {
- /* too much, try allocating less */
- new_count = entry_count + 1;
- new_list = g_realloc (list, new_count * sizeof (GCHAR *));
- if (new_list == NULL)
- fail_p = TRUE;
- }
- list = new_list;
- entry_count = new_count;
- }
- /* then copy the name to the cache */
- if (NULL == (list[i] = g_malloc (strlen (dirent_ptr->d_name) + 1)))
- fail_p = TRUE;
- else
- strcpy (list[i++], dirent_ptr->d_name);
- }
- closedir (directory);
-
- if (fail_p)
- {
- while (0 < i--)
- g_free (list[i]);
- g_free (list);
-
- RETURN 0;
- }
-
- if (i < entry_count)
- {
- list = g_realloc (list, i * sizeof (GCHAR *));
- entry_count = i;
- }
-
- qsort (list,
- entry_count,
- sizeof (GCHAR *),
- (sort_compare_function) (sort_by_name_p ? &os_file_alphasort : &os_file_mtimesort));
-
- *filename_list = list;
-
- RETURN entry_count;
- }
-
- static gint
- os_copy_file (GCHAR *filename, GCHAR *newname)
- {
- gint from;
- gint to;
- gint size;
- GCHAR buffer[LINE_BUF_SIZE];
- mode_t mode = NEW_FILE_MODE;
-
- if ((from = open (filename, O_RDONLY)) == -1)
- {
- perror ("os_copy_file: can't open source file");
- return FALSE;
- }
- if ((to = creat (newname, mode)) == -1)
- {
- close (from);
- perror ("os_copy_file: can't create destination file");
- return FALSE;
- }
- while (0 < (size = read (from, buffer, LINE_BUF_SIZE - 1)))
- write (to, buffer, size);
-
- close (from);
- close (to);
-
- return TRUE;
- }
-
- static gint
- os_delete_file (GCHAR *filename)
- {
- gint type = os_file_kind (filename, TRUE);
-
- switch (type)
- {
- case REGFILE:
- return unlink (filename);
- break;
- case DIRECTORY:
- return rmdir (filename);
- break;
- default:
- return -1;
- break;
- }
- }
-
- static gint
- os_file_is_writable (GCHAR *filename)
- {
- struct stat ent;
- gint flag = FALSE;
-
- DEBUGBLOCK (N_("os_file_is_writable (\"%s\")\n"), filename);
-
- if (stat (filename, &ent) == 0)
- {
- #ifdef S_IWUSR
- flag = S_IWUSR & ent.st_mode;
- #else
- flag = S_IWRITE & ent.st_mode;
- #endif
-
- #if !defined (G_OS_WIN32)
- if (flag)
- flag = (ent.st_uid == getuid ());
- if (! flag)
- flag = (S_IWGRP & ent.st_mode) && (ent.st_gid == getgid ());
- if (! flag)
- flag = (S_IWOTH & ent.st_mode);
- #else
- /* //HB: I don't know if only the M$VC compiler is bogus, but
- * we need to return either FALSE==0 or TRUE==1
- */
- flag = (flag) ? TRUE : FALSE;
- #endif
- }
-
- DPRINT (N_("%s is%s writable.\n"), filename, flag ? "" : " not");
- RETURN flag;
- }
-
- /* If SHRINK is non-FALSE, symbolic links are referred. */
- static gint
- os_file_kind (GCHAR *filename, gint shrink)
- {
- struct stat ent_sbuf;
- gint flag = TRUE; /* fail safe */
- gint symlink = FALSE;
- gint size = 0;
- GCHAR fname[PATH_LENGTH], tmp[PATH_LENGTH];
-
- G_ASSERT (filename);
-
- #if !defined (G_OS_WIN32)
- if (*filename == G_DIR_SEPARATOR)
- #else
- if ((strlen(filename) > 1) && (':' == filename[1]))
- #endif
- strcpy (fname, filename);
- else
- sprintf (fname, "%s%c%s", cwd_cache->name, G_DIR_SEPARATOR, filename);
-
- while ((size = readlink (fname, tmp, PATH_LENGTH - 1)) != -1)
- {
- /* fname is a symbolic link. */
- symlink = TRUE;
- tmp[size] = 0;
- if (tmp[0] != G_DIR_SEPARATOR)
- {
- GCHAR *dir = NULL;
- GCHAR scratch[PATH_LENGTH];
-
- dir = pathname_get_directoryname (fname);
- sprintf (scratch, "%s%c%s", dir, G_DIR_SEPARATOR, tmp);
- strcpy (fname, scratch);
- g_free (dir);
- }
- else
- {
- strcpy (fname, tmp);
- }
- }
-
- if (stat (fname, &ent_sbuf) == 0)
- {
- /* something exists */
- if (S_ISDIR (ent_sbuf.st_mode))
- flag = DIRECTORY;
- else if (S_ISREG (ent_sbuf.st_mode))
- flag = REGFILE;
-
- if ((! shrink) && symlink)
- {
- switch (flag)
- {
- case REGFILE:
- flag = SLNKFILE;
- break;
- case DIRECTORY:
- flag = SLNKDIR;
- break;
- default:
- break;
- }
- }
- }
- else
- {
- /* error was occured */
- if (errno == ENOENT)
- flag = NOT_EXIST;
- }
- return flag;
- }
-
- static gint
- os_file_size (GCHAR *filename)
- {
- struct stat ent_sbuf;
- gint size = 0;
- gint f_size = -1;
- GCHAR fname[PATH_LENGTH], tmp[PATH_LENGTH];
-
- strcpy (fname, filename);
- while ((size = readlink (fname, tmp, PATH_LENGTH - 1)) != -1)
- {
- /* fname is a symbolic link. */
- tmp[size] = 0;
- strcpy (fname, tmp);
- }
- if (stat (fname, &ent_sbuf) == 0)
- f_size = ent_sbuf.st_size;
-
- return f_size;
- }
-
- static gint
- os_mkdir (GCHAR *pathname)
- {
- GCHAR info[256];
- mode_t mode = NEW_DIRECTORY_MODE;
- gint kind;
-
- kind = os_file_kind (pathname, TRUE);
-
- if (NOT_EXIST == kind)
- {
- if (os_make_directory (pathname, mode) != -1)
- {
- GCHAR *canonical;
-
- canonical = pathname_get_canonical_name (pathname);
- if (canonical != NULL)
- {
- GCHAR *parent;
- directory_cache *dcache = NULL;
-
- parent = pathname_get_directoryname (canonical);
- dcache = guash_lookup_directory_cache (parent);
-
- if (dcache != NULL)
- {
- directory_cache_add_directory (dcache,
- pathname_get_basename(canonical),
- DIRECTORY);
- dcache->timestamp = os_file_get_modify_timestamp (dcache->name);
- SET_ATTRIBUTE (dcache, DISORDERED_P);
- }
- if (dcache == cwd_cache)
- {
- guash_update_cwd_cache (REDRAW);
- }
-
- g_free (parent);
- }
- else
- printf ("os_mkdir: can't move to the directory\n");
- g_free (canonical);
- }
- }
- else
- {
- sprintf (info, _("%s already exists"), pathname);
- thumbnail_panel_set_info (info);
- }
- return (NOT_EXIST == kind);
- }
-
- static gint
- os_make_directory (GCHAR *pathname, gint mode)
- {
- return mkdir (pathname, mode);
- }
-
- static gint
- os_rename_file (GCHAR *filename, GCHAR *newname)
- {
- return rename (filename, newname);
- }
-
- /* dialog stuff */
- static int
- DIALOG (gint restart)
- {
- GtkWidget *hbox;
- GtkWidget *ps_box;
- GtkWidget *thumbnail_panel_frame = NULL;
- GtkWidget *button;
- gchar **argv;
- gint argc;
-
- DEBUGBLOCK (N_("DIALOG (building dialog window)\n"));
-
- argc = 1;
- argv = g_new (gchar *, 1);
- argv[0] = g_strdup (PLUG_IN_NAME);
- gdk_set_use_xshm (gimp_use_xshm ());
-
- /* Initialize Gtk toolkit */
- gtk_set_locale ();
-
- #ifdef HAVE_LC_MESSAGES
- setlocale(LC_MESSAGES, "");
- #endif
- #if defined(ENABLE_NLS) & defined(LOCALEDIR)
- bindtextdomain(TEXT_DOMAIN, LOCALEDIR);
- textdomain(TEXT_DOMAIN);
- #endif
-
- gtk_init (&argc, &argv);
- gtk_rc_parse (gimp_gtkrc ());
-
- dlg = gtk_dialog_new ();
- gtk_window_set_wmclass (GTK_WINDOW (dlg), "Guash", "Gimp");
- gtk_window_set_title (GTK_WINDOW (dlg), "Guash: initializing...");
- gtk_window_position (GTK_WINDOW (dlg), GTK_WIN_POS_MOUSE);
- gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
- (GtkSignalFunc) gtkW_close_callback, NULL);
- /* handle the wm close signal */
- gtk_signal_connect (GTK_OBJECT (dlg), "delete_event",
- (GtkSignalFunc) gtkW_close_callback, NULL);
-
- /* Hey, don't remove the following sentence!
- Desired behavior of Cursor keys depends on it, magically... */
- gtk_signal_connect (GTK_OBJECT (dlg), "key_press_event",
- (GtkSignalFunc) cursor_event_handler,
- NULL);
- /* set geometric parameters */
- #ifdef GTK_HAVE_FEATURES_1_1_0
- the_panel.font_height = gdk_string_height (GTK_WIDGET (dlg)->style->font, "yX");
- #else
- #ifdef THUMBNAIL_FONT_SIZE
- the_panel.font_height = THUMBNAIL_FONT_SIZE;
- #else
- the_panel.font_height = 18;
- #endif
- #endif
- the_panel.ncol = gtkW_parse_gimprc_gint ("guash-ncol",
- NCOL_OF_THUMBNAIL_PANEL_DEFAULT);
- the_panel.ncol = CLAMP (the_panel.ncol, NCOL_OF_THUMBNAIL_PANEL_MIN, 10);
- the_panel.nrow = gtkW_parse_gimprc_gint ("guash-nrow",
- NROW_OF_THUMBNAIL_PANEL_DEFAULT);
- the_panel.nrow = CLAMP (the_panel.nrow, NROW_OF_THUMBNAIL_PANEL_MIN, 10);
- the_panel.nthumb_in_page = the_panel.ncol * the_panel.nrow;
- the_panel.width = COL2WIDTH (the_panel.ncol);
- the_panel.height = ROW2HEIGHT (the_panel.nrow);
-
- /* Action Area */
- gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (dlg)->action_area), 0);
- gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dlg)->action_area), 0);
-
- widget_for_selecion[0]
- = button
- #ifdef NEW_DND_API
- = gtk_button_new_with_label ("Copy/Move");
- #else
- = gtk_button_new_with_label ("Drag copy");
- #endif
- GTK_CONTAINER (button)->border_width = 0;
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), button,
- TRUE, TRUE, 0);
- gtk_widget_show (button);
- gtk_widget_realize (button);
- gtk_signal_connect (GTK_OBJECT (button),
- "clicked",
- GTK_SIGNAL_FUNC (dnd_drag_button_callback),
- button);
- #ifdef NEW_DND_API
- gtk_signal_connect (GTK_OBJECT (button),
- "drag_data_get",
- GTK_SIGNAL_FUNC (dnd_drag_request_callback),
- NULL);
- gtk_drag_source_set (button, GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
- dnd_target_table, dnd_n_targets,
- GDK_ACTION_COPY | GDK_ACTION_MOVE);
- gtk_signal_connect (GTK_OBJECT (button),
- "drag_data_delete",
- GTK_SIGNAL_FUNC (dnd_source_delete_data),
- NULL);
- #else
- gtk_signal_connect (GTK_OBJECT (button),
- "drag_request_event",
- GTK_SIGNAL_FUNC (dnd_drag_request_callback),
- NULL);
-
- gtk_widget_dnd_drag_set (button, FALSE, possible_dnd_types, 1);
- #endif
- gtk_widget_set_sensitive (button, 0);
-
- #if defined(USE_UPDATE_BUTTON) & (USE_UPDATE_BUTTON == 1)
- button = gtk_button_new_with_label ("Update");
- GTK_CONTAINER (button)->border_width = 0;
- gtk_signal_connect (GTK_OBJECT (button), "clicked",
- (GtkSignalFunc) update_callback, dlg);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), button,
- TRUE, TRUE, 0);
- gtk_widget_show (button);
- #else
- #ifdef NEW_DND_API
- widget_for_selecion[1]
- = button
- = gtk_button_new_with_label ("Move");
- GTK_CONTAINER (button)->border_width = 0;
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), button,
- TRUE, TRUE, 0);
- gtk_widget_show (button);
- gtk_widget_realize (button);
- gtk_signal_connect (GTK_OBJECT (button),
- "clicked",
- GTK_SIGNAL_FUNC (dnd_drag_button_callback),
- button);
- gtk_signal_connect (GTK_OBJECT (button),
- "drag_data_get",
- GTK_SIGNAL_FUNC (dnd_drag_request_callback),
- NULL);
- gtk_drag_source_set (button, GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
- dnd_target_table, dnd_n_targets,
- GDK_ACTION_MOVE);
- gtk_signal_connect (GTK_OBJECT (button),
- "drag_data_delete",
- GTK_SIGNAL_FUNC (dnd_source_delete_data),
- NULL);
- gtk_widget_set_sensitive (button, 0);
- #endif
- #endif
-
- button = gtk_button_new_with_label ("Help");
- GTK_CONTAINER (button)->border_width = 0;
- gtk_signal_connect (GTK_OBJECT (button), "clicked",
- (GtkSignalFunc) help_callback, dlg);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), button,
- TRUE, TRUE, 0);
- gtk_widget_show (button);
-
- button = gtk_button_new_with_label ("Close");
- GTK_CONTAINER (button)->border_width = 0;
- gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
- (GtkSignalFunc) gtkW_close_callback,
- GTK_OBJECT(dlg));
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), button,
- TRUE, TRUE, 0);
- gtk_widget_show (button);
-
- /* top row */
- hbox = gtkW_hbox_new ((GTK_DIALOG (dlg)->vbox), FALSE, FALSE);
-
- cwd_label = gtk_label_new ("Gimp Users' Another SHell");
- gtk_widget_set_usize (cwd_label,
- LABEL_WIDTH (COL2WIDTH(NCOL_OF_THUMBNAIL_PANEL_MIN)),
- 0);
- gtk_box_pack_start (GTK_BOX (hbox), cwd_label, TRUE, TRUE, LABEL_PADDING);
- gtk_misc_set_alignment (GTK_MISC (cwd_label), 0.0, 0.4);
- gtk_widget_show (cwd_label);
-
- button = gtk_button_new_with_label ("Jump");
- gtk_signal_connect (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (directory_jump_callback),
- NULL);
- gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
- gtk_widget_set_usize (button, JUMP_BUTTON_WIDTH, 0);
- gtk_widget_show (button);
-
- gtk_widget_show (hbox);
-
- /* 2nd row */
- ps_box = gtkW_hbox_new ((GTK_DIALOG (dlg)->vbox), TRUE, TRUE);
-
- gdk_set_use_xshm (gimp_use_xshm ());
- gtk_preview_set_gamma (gimp_gamma ());
- {
- guchar *color_cube;
- color_cube = gimp_color_cube ();
- gtk_preview_set_color_cube (color_cube[0], color_cube[1],
- color_cube[2], color_cube[3]);
- }
- {
- GtkPreviewInfo *info;
-
- info = gtk_preview_get_info ();
- if ( info->visual->type != GDK_VISUAL_PSEUDO_COLOR)
- {
- /* rule of thumb: An extension should not share cmap with the gimp. */
- gtk_preview_set_install_cmap (gimp_install_cmap ());
- }
- gtk_widget_set_default_colormap (gtk_preview_get_cmap ());
- gtk_preview_reset ();
- gtk_widget_set_default_visual (gtk_preview_get_visual ());
- }
-
- thumbnail_panel = gtk_preview_new (GTK_PREVIEW_COLOR);
- gtk_preview_size (GTK_PREVIEW (thumbnail_panel),
- the_panel.width,
- the_panel.height);
- gtk_preview_set_expand (GTK_PREVIEW (thumbnail_panel), TRUE);
- GTK_WIDGET_CLASS (GTK_OBJECT (thumbnail_panel)->klass)->size_request
- = thumbnail_panel_size_request;
- gtk_signal_connect_after (GTK_OBJECT (dlg), "size_allocate",
- (GtkSignalFunc) thumbnail_panel_size_allocate,
- NULL);
- GTK_WIDGET_CLASS (GTK_OBJECT (thumbnail_panel)->klass)->key_press_event
- = cursor_event_handler;
- gtk_widget_set_events (thumbnail_panel, EVENT_MASK);
- gtk_signal_connect (GTK_OBJECT (thumbnail_panel), "event",
- (GtkSignalFunc) preview_event_handler,
- NULL);
- gtk_widget_show (thumbnail_panel);
-
- thumbnail_panel_frame = gtkW_frame_new (NULL, NULL);
- gtk_container_border_width (GTK_CONTAINER (thumbnail_panel_frame), 0);
- gtk_container_add (GTK_CONTAINER (thumbnail_panel_frame), thumbnail_panel);
- gtk_widget_show (thumbnail_panel_frame);
-
- gtkW_ivscroll_entry_new (&widget_for_scroll[0],
- &widget_for_scroll[1],
- (GtkSignalFunc) gtkW_iscroll_update,
- (GtkSignalFunc) gtkW_ientry_update,
- &the_panel.current_page1,
- 1, 5, 1, &widget_pointer[0]);
- gtk_widget_set_usize (widget_for_scroll[0], SCROLLBAR_WIDTH, 0);
- gtk_widget_set_usize (widget_for_scroll[1], JUMP_BUTTON_WIDTH, 0);
- gtk_widget_show (widget_for_scroll[0]);
- gtk_widget_show (widget_for_scroll[1]);
-
- gtk_box_pack_start (GTK_BOX (ps_box), thumbnail_panel_frame, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (ps_box), widget_for_scroll[0], FALSE, FALSE, 0);
-
- gtk_widget_show (ps_box);
-
- #ifdef NEW_DND_API
- #if 0
- /* drag side */
- gtk_drag_source_set (thumbnail_panel, GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
- dnd_target_table, dnd_n_targets,
- GDK_ACTION_COPY | GDK_ACTION_MOVE);
- gtk_signal_connect (GTK_OBJECT (thumbnail_panel),
- "drag_data_get",
- GTK_SIGNAL_FUNC (dnd_drag_request_callback),
- NULL);
- gtk_signal_connect (GTK_OBJECT (thumbnail_panel),
- "drag_data_delete",
- GTK_SIGNAL_FUNC (dnd_source_delete_data),
- NULL);
- #endif
- /* drop size */
- gtk_drag_dest_set (thumbnail_panel,
- GTK_DEST_DEFAULT_ALL,
- dnd_target_table, dnd_n_targets,
- GDK_ACTION_COPY | GDK_ACTION_MOVE);
- gtk_signal_connect (GTK_OBJECT (thumbnail_panel),
- "drag_drop",
- GTK_SIGNAL_FUNC (dnd_drop),
- thumbnail_panel);
- gtk_signal_connect (GTK_OBJECT (thumbnail_panel),
- "drag_data_received",
- GTK_SIGNAL_FUNC (dnd_data_received),
- thumbnail_panel);
- #else
- gtk_signal_connect (GTK_OBJECT (thumbnail_panel),
- "drop_data_available_event",
- GTK_SIGNAL_FUNC (dnd_drop),
- thumbnail_panel);
- gtk_widget_dnd_drop_set (thumbnail_panel, TRUE, possible_dnd_types, 1, FALSE);
- #endif
-
- /* 3rd row */
- hbox = gtkW_hbox_new ((GTK_DIALOG (dlg)->vbox), FALSE, FALSE);
-
- file_property = gtk_label_new ("Gimp Users' Another SHell: initializing...");
- gtk_widget_set_usize (file_property,
- LABEL_WIDTH (COL2WIDTH (NCOL_OF_THUMBNAIL_PANEL_MIN)),
- 0);
- gtk_box_pack_start (GTK_BOX (hbox), file_property, TRUE, TRUE, LABEL_PADDING);
- gtk_misc_set_alignment (GTK_MISC (file_property), 0.0, 0.4);
- gtk_label_set_justify (GTK_LABEL (file_property), GTK_JUSTIFY_FILL);
- gtk_widget_show (file_property);
-
- gtk_box_pack_end (GTK_BOX (hbox), widget_for_scroll[1], FALSE, FALSE, 0);
- gtk_widget_show (hbox);
-
- gtk_window_set_title (GTK_WINDOW (dlg), SHORT_NAME);
- gtk_widget_show (dlg);
-
- DPRINT (N_("Setting timer\n"));
- guash_is_initialized = FALSE;
- gtk_timeout_add (INITIALIZATION_DELAY, timer_initialize_guash, NULL);
- gtk_timeout_add (((VAL.last_dir_name[0] == 0) ?
- INITIALIZATION_SLEEP_PERIOD : STARTUP_SLEEP_PERIOD),
- timer_start_guash,
- NULL);
-
- DEBUGEND;
-
- gtk_main ();
- gdk_flush ();
- return 1;
- }
-
- static gint
- timer_initialize_guash (gpointer data)
- {
- DEBUGBLOCK (N_("timer_initialize_guash\n"));
-
- if (guash_is_initialized == TRUE)
- {
- if ((VAL.last_dir_name[0] == 0) && (cwd_cache == NULL))
- thumbnail_panel_show_banner_step2 ();
- return FALSE;
- }
-
- thumbnail_panel_initialize_banner ();
- thumbnail_panel_show_banner_step1 ();
-
- guash_parse_gimprc ();
- thumbnail_panel_create_menu ();
- guash_build_thumbnail_colormap ();
-
- guash_is_initialized = TRUE;
- gtk_timeout_add (BANNER_UP_PERIOD, timer_initialize_guash, NULL);
-
- RETURN FALSE;
- }
-
- static gint
- timer_start_guash (gpointer data)
- {
- gint flag = FALSE;
-
- DEBUGBLOCK (N_("timer_start_guash\n"));
-
- if (guash_is_initialized == FALSE)
- {
- DPRINT (N_("not yet initialized. resleeping\n"));
- gtk_timeout_add (STARTUP_SLEEP_PERIOD, timer_start_guash, NULL);
- return FALSE;
- }
- if (VAL.last_dir_name[0] == 0)
- thumbnail_panel_show_banner_step3 ();
-
- thumbnail_panel_reinitialize_banner ();
-
- flag = (strlen (VAL.last_dir_name) == 0);
-
- the_loaded_data = g_new (Thumbnail, 1);
- thumbnail_initialize (the_loaded_data);
- the_loaded_data->image
- = image_buffer_new (THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, 3);
- INITIALIZE_ATTRIBUTES (the_loaded_data);
-
- guash_update_cwd_cache (REDRAW);
-
- if (flag)
- gimp_set_data (PLUG_IN_NAME, &VAL, sizeof (VALS));
-
- if (HAS_ATTRIBUTE (&VAL, MONITOR_P) && (0 < directory_monitor_interval))
- gtk_timeout_add (directory_monitor_interval,
- timer_directory_monitor,
- NULL);
- RETURN FALSE;
- }
-
- static gint
- timer_directory_monitor ()
- {
- gint *image_ids;
- gint num_images, index;
- gint update_p = FALSE;
-
- DEBUGBLOCK (N_("timer_directory_monitor\n"));
-
- if (HAS_NO_ATTRIBUTE (&VAL, DISPLAY_IMAGE_P))
- {
- gtk_timeout_add (directory_monitor_interval,
- timer_directory_monitor,
- NULL);
- RETURN FALSE;
- }
-
- image_ids = gimp_query_images (&num_images);
-
- for (index = 0; index < num_images; index++)
- {
- GCHAR *file_name = guash_get_image_filename (image_ids[index]);
-
- if (file_name && (os_file_kind (file_name, TRUE) == REGFILE))
- {
- GCHAR *path = NULL;
- GCHAR *thumbnail_fname = NULL;
- directory_cache *dcache = NULL;
-
- path = pathname_get_directoryname (file_name);
- dcache = directory_cache_of (path);
- thumbnail_fname = pathname_build_thumbnail_filename (file_name);
-
- if (dcache
- && (dcache->savable == TRUE)
- && HAS_ATTRIBUTE (dcache, FILED_P)
- && (dcache->timestamp < os_file_get_modify_timestamp (file_name))
- && (! pathname_is_valid_thumbnail_filename (thumbnail_fname)))
- {
- os_delete_file (thumbnail_fname);
- if (directory_cache_update_thumbnail_for (cwd_cache, file_name, NULL))
- {
- if (cwd_cache == dcache)
- update_p = TRUE;
- }
- }
- g_free (path);
- }
- g_free (file_name);
- }
-
- if ((cwd_cache->savable == TRUE)
- && (during_buildup_thumbnail_panel == FALSE)
- && HAS_ATTRIBUTE (cwd_cache, FILED_P)
- && (cwd_cache->timestamp < os_file_get_modify_timestamp (cwd_cache->name)))
- thumbnail_panel_set_info (_("FYI, the directory is just updated"));
-
- if (update_p)
- {
- thumbnail_panel_update ();
- thumbnail_panel_set_info (_("Directory monitor found updated file(s)"));
- }
-
- gtk_timeout_add (directory_monitor_interval, timer_directory_monitor, NULL);
-
- RETURN FALSE;
- }
-
- static gint
- about_dialog ()
- {
- GtkWidget *a_dlg;
- GtkWidget *button;
- GtkWidget *frame;
- GtkWidget *hbox;
- GtkWidget *table;
- GtkWidget *hseparator;
- gint index, i, nhelp;
- gint align;
-
- nhelp = sizeof (help_document) / sizeof (help_document[0]);
-
- a_dlg = gtk_dialog_new ();
- gtk_window_set_wmclass (GTK_WINDOW (a_dlg), "Guash", "Gimp");
- gtk_window_set_title (GTK_WINDOW (a_dlg), "Guash help");
- gtk_window_position (GTK_WINDOW (a_dlg), GTK_WIN_POS_MOUSE);
- gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (a_dlg)->action_area),
- gtkW_border_width);
-
- button = gtk_button_new_with_label (GUASH_TIMESTAMP);
- GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
- gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
- (GtkSignalFunc) gtk_widget_destroy,
- GTK_OBJECT(a_dlg));
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (a_dlg)->action_area), button,
- TRUE, TRUE, 0);
- gtk_widget_grab_default (button);
- gtk_widget_show (button);
-
- hbox = gtkW_hbox_new ((GTK_DIALOG (a_dlg)->vbox), FALSE, TRUE);
- frame = gtkW_frame_new (hbox, NULL);
-
- table = gtkW_table_new (frame, nhelp + 2, 3);
- index = 0;
- align = gtkW_align_x;
- gtkW_align_x = GTK_EXPAND|GTK_FILL;
-
- for (i = 0; i < nhelp; i++, index++)
- {
- if (help_document[i].action)
- {
- gtkW_table_add_label (table, help_document[i].action,
- 0, 1, index, help_document[i].flush_left);
- if (help_document[i].condition)
- gtkW_table_add_label (table, help_document[i].condition,
- 1, 2, index, help_document[i].flush_left);
- gtkW_table_add_label (table, help_document[i].behavior,
- 2, 3, index, help_document[i].flush_left);
- }
- else
- {
- if (help_document[i].condition)
- {
- gtkW_table_add_label (table, help_document[i].condition,
- 0, 3, index, FALSE);
- }
- else /* hseparator */
- {
- hseparator = gtk_hseparator_new ();
- gtk_table_attach (GTK_TABLE (table), hseparator,
- 0, 3, index, index + 1,
- GTK_FILL, GTK_FILL,
- gtkW_border_width, 2 * gtkW_border_width);
- gtk_widget_show (hseparator);
- }
- }
- }
- gtkW_align_x = align;
- gtk_widget_show (a_dlg);
-
- gdk_flush ();
- return 1;
- }
-
- /*
- * callbacks
- */
-
- static void
- menu_change_directory_callback (GtkWidget *widget, gpointer data)
- {
- if (data != NULL)
- guash_change_current_directory ((GCHAR *) data, NULL);
- }
-
- static void
- directory_jump_callback (GtkWidget *widget, gpointer data)
- {
- GtkWidget *jump_menu, *parents_menu, *menu_item;
-
- jump_menu = gtk_menu_new ();
-
- parents_menu = gtk_menu_item_new_with_label ("Parents");
- gtk_menu_append (GTK_MENU (jump_menu), parents_menu);
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (parents_menu),
- directory_cache_create_parents_menu ());
- gtk_widget_show (parents_menu);
-
- if (1 < directory_cache_table_size)
- {
- GtkWidget *history_menu;
-
- history_menu = gtk_menu_item_new_with_label ("History");
- gtk_menu_append (GTK_MENU (jump_menu), history_menu);
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (history_menu),
- directory_cache_create_history_menu ());
- gtk_widget_show (history_menu);
- }
-
- menu_item = gtk_menu_item_new_with_label ("To ...");
- gtk_menu_append (GTK_MENU (jump_menu), menu_item);
- gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
- (GtkSignalFunc) fileselector_for_chdir_callback,
- NULL);
- gtk_widget_show (menu_item);
-
- menu_item = gtk_menu_item_new_with_label ("Close menu");
- gtk_menu_append (GTK_MENU (jump_menu), menu_item);
- gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
- (GtkSignalFunc) NULL,
- NULL);
- gtk_widget_show (menu_item);
-
- gtk_menu_popup (GTK_MENU (jump_menu), NULL, NULL, NULL, NULL, 1, 0);
- }
-
- static void
- parent_directory_callback (GtkWidget *widget, gpointer data)
- {
- guash_change_current_directory ("..", NULL);
- }
-
- static void
- forward_callback (GtkWidget *widget, gpointer data)
- {
- thumbnail_panel_move_focus (1);
- }
-
- static void
- select_and_forward_callback (GtkWidget *widget, gpointer data)
- {
- gint index = -1;
- Thumbnail *thumbnail;
-
- if (selection_is_active ())
- {
- index = cwd_cache->last_focus + 1;
-
- if (! directory_cache_valid_index (cwd_cache, index))
- index = -1;
- }
- else
- if (0 < cwd_cache->nimage)
- index = cwd_cache->ndir;
-
- if (directory_cache_valid_image_index (cwd_cache, index))
- {
- selection_add_and_show (index);
- thumbnail = directory_cache_get_nth (cwd_cache, index);
- thumbnail_panel_set_info (thumbnail->info);
- cwd_cache->last_focus = index;
- }
- else
- thumbnail_panel_set_info (NULL);
-
- thumbnail_panel_update_sensitive_menu ();
- }
-
- static void
- backward_callback (GtkWidget *widget, gpointer data)
- {
- thumbnail_panel_move_focus (-1);
- }
-
- static void
- next_callback (GtkWidget *widget, gpointer data)
- {
- thumbnail_panel_move_focus (the_panel.ncol);
- }
-
- static void
- prev_callback (GtkWidget *widget, gpointer data)
- {
- thumbnail_panel_move_focus (- the_panel.ncol);
- }
-
- static void
- next_page_callback (GtkWidget *widget, gpointer data)
- {
- if (cwd_cache->display_page + 1 < cwd_cache_npage ())
- {
- cwd_cache->display_page++;
- thumbnail_panel_update ();
- }
- }
-
- static void
- prev_page_callback (GtkWidget *widget, gpointer data)
- {
- if (0 < cwd_cache->display_page)
- {
- cwd_cache->display_page--;
- thumbnail_panel_update ();
- }
- }
-
- static void
- show_comment_callback (GtkWidget *widget, gpointer data)
- {
- if (directory_cache_valid_image_index (cwd_cache, cwd_cache->last_focus))
- {
- Thumbnail *selected;
- GCHAR *str;
-
- selected = directory_cache_get_nth (cwd_cache, cwd_cache->last_focus);
-
- if (selected == NULL)
- return;
-
- str = selected->info;
- /* OK. search the beginning of comment part in str */
- while (*str)
- if (*str++ == ' ')
- {
- if ((*str == 0) || (*str == '"'))
- break;
- }
- if (*str == 0)
- str = _("no comment");
- #ifdef TRANSLATE_PHOTOSHOP_TM
- #warning "Enable translation of the Photoshop comment (in show_comment_callback)"
- else if (! g_strncasecmp ("\"File written by Adobe Photoshop\250", str, 33))
- str[32] = ' ';
- #endif
- thumbnail_panel_set_info (str);
- }
- }
-
- static void
- open_callback (GtkWidget *widget, gpointer data)
- {
- selection_open_files ();
- guash_discard_events ();
- }
-
- static void
- update_callback (GtkWidget *widget, gpointer data)
- {
- ASSERT (cwd_cache_validate ());
-
- DEBUGBLOCK (N_("update_callback\n"));
-
- directory_cache_delete_invalid_cache_files (cwd_cache, FALSE);
- cwd_cache_update ();
-
- if (HAS_NO_ATTRIBUTE (cwd_cache, DISPLAY_IMAGE_P))
- thumbnail_panel_set_info ("FYI, thumbnails are not updated in `display all files' mode");
-
- RETURN;
- }
-
- static void
- toggle_display_mode_callback (GtkWidget *widget, gpointer data)
- {
- ASSERT (cwd_cache_validate ());
-
- TOGGLE_ATTRIBUTE (&VAL, DISPLAY_IMAGE_P);
- guash_update_cwd_cache (RESCAN);
- thumbnail_panel_set_info (HAS_ATTRIBUTE (&VAL, DISPLAY_IMAGE_P)
- ? _("Changed to `display only image' mode")
- : _("Changed to `display all files' mode"));
- }
-
- /* ASSERT (cwd_cache_validate ()); */
-
- static void
- toggle_save_mode_callback (GtkWidget *widget, gpointer data)
- {
- GCHAR *message;
-
- if (HAS_ATTRIBUTE (&VAL, SAVE_AS_XVPICT_P)
- && HAS_ATTRIBUTE (&VAL, SAVE_AS_GPICT_P))
- {
- RESET_ATTRIBUTE (&VAL, SAVE_AS_GPICT_P);
- message = "Changed to `save thumbnails in xvpict format' mode";
- }
- else if (HAS_ATTRIBUTE (&VAL, SAVE_AS_XVPICT_P)
- && HAS_NO_ATTRIBUTE (&VAL, SAVE_AS_GPICT_P))
- {
- RESET_ATTRIBUTE (&VAL, SAVE_AS_XVPICT_P);
- message = "Changed to `unsave thumbnails' mode";
- }
- else
- {
- SET_ATTRIBUTE (&VAL, SAVE_AS_XVPICT_P);
- SET_ATTRIBUTE (&VAL, SAVE_AS_GPICT_P);
- message = "Changed to `save thumbnails in 16bit format' mode";
- }
-
- thumbnail_panel_set_info (_(message));
- }
-
- static void
- toggle_sort_mode_callback (GtkWidget *widget, gpointer data)
- {
- ASSERT (cwd_cache_validate ());
-
- TOGGLE_ATTRIBUTE (&VAL, SORT_BY_NAME_P);
- guash_update_cwd_cache (RESCAN);
- thumbnail_panel_set_info (HAS_ATTRIBUTE (&VAL, SORT_BY_NAME_P)
- ? _("Changed to `sort by name' mode")
- : _("Changed to `sort by date' mode"));
- }
-
- static void
- purge_selected_thumbnail_file_callback (GtkWidget *widget, gpointer data)
- {
- selection_iterator *iterator;
- Thumbnail *selected;
- GCHAR tmp[PATH_LENGTH];
-
- iterator = selection_make_iterator (SELECTION_ORDER_INDEX);
- while (NULL != (selected = selection_iterator_get_next_thumbnail (iterator)))
- {
- GCHAR *thumbnail_filename = NULL;
-
- sprintf (tmp, "%s%c%s", cwd_cache->name, G_DIR_SEPARATOR, selected->name);
- thumbnail_filename = pathname_build_thumbnail_filename (tmp);
-
- if (pathname_is_valid_thumbnail_filename (thumbnail_filename))
- os_delete_file (thumbnail_filename);
- g_free (thumbnail_filename);
- }
- thumbnail_panel_set_info ("The thumbnail file of the selected image were deleted");
- }
-
- static void
- purge_thumbnail_file_callback (GtkWidget *widget, gpointer data)
- {
- ASSERT (cwd_cache_validate ());
-
- directory_cache_delete_invalid_cache_files (cwd_cache, TRUE);
- }
-
- static void
- help_callback (GtkWidget *widget, gpointer client_data)
- {
- about_dialog ();
- }
-
- static void
- fileselector_for_copy_callback (GtkWidget *widget, gpointer client_data)
- {
- GtkWidget *filesel;
-
- ASSERT (cwd_cache_validate () && selection_validate_image ());
-
- filesel = gtk_file_selection_new ("Copy selected images to");
- gtk_window_position (GTK_WINDOW (filesel), GTK_WIN_POS_MOUSE);
-
- gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->ok_button),
- "clicked", (GtkSignalFunc) copy_callback,
- filesel);
-
- gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->cancel_button),
- "clicked", (GtkSignalFunc) gtk_widget_destroy,
- GTK_OBJECT (GTK_WINDOW (filesel)));
-
- if (selection_is_active ())
- {
- Thumbnail *selected;
- GCHAR tmp[PATH_LENGTH];
-
- selected = directory_cache_get_nth (cwd_cache, cwd_cache->selection_top);
-
- sprintf (tmp, "%s%c%s", cwd_cache->name, G_DIR_SEPARATOR, selected->name);
- gtk_file_selection_set_filename (GTK_FILE_SELECTION (filesel), tmp);
- }
- else if (strlen (VAL.last_dir_name) > 0)
- {
- gtk_file_selection_set_filename (GTK_FILE_SELECTION (filesel),
- VAL.last_dir_name);
- }
- else
- {
- gtk_file_selection_set_filename (GTK_FILE_SELECTION (filesel),
- cwd_cache->name);
- }
- gtk_widget_show (filesel);
- }
-
- static void
- fileselector_for_move_callback (GtkWidget *widget, gpointer client_data)
- {
- GtkWidget *filesel;
-
- ASSERT (cwd_cache_validate () && selection_validate_image ());
-
- if (guash_confirm_operation ("Move") == FALSE)
- return;
-
- filesel = gtk_file_selection_new ("Move selected images to");
- gtk_window_position (GTK_WINDOW (filesel), GTK_WIN_POS_MOUSE);
-
- gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->ok_button),
- "clicked", (GtkSignalFunc) move_callback,
- filesel);
-
- gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->cancel_button),
- "clicked", (GtkSignalFunc) gtk_widget_destroy,
- GTK_OBJECT (GTK_WINDOW (filesel)));
-
- if (fileselector_last_pathname)
- gtk_file_selection_set_filename (GTK_FILE_SELECTION (filesel),
- fileselector_last_pathname);
- gtk_widget_show (filesel);
- }
-
- static void
- fileselector_for_chdir_callback (GtkWidget *widget, gpointer client_data)
- {
- GtkWidget *filesel;
-
- ASSERT (cwd_cache_validate ());
-
- filesel = gtk_file_selection_new ("Change directory");
- gtk_window_position (GTK_WINDOW (filesel), GTK_WIN_POS_MOUSE);
-
- gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->ok_button),
- "clicked", (GtkSignalFunc) chdir_callback,
- filesel);
-
- gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->cancel_button),
- "clicked", (GtkSignalFunc) gtk_widget_destroy,
- GTK_OBJECT (GTK_WINDOW (filesel)));
- {
- GCHAR tmp[PATH_LENGTH];
-
- sprintf (tmp, "%s%c.", cwd_cache->name, G_DIR_SEPARATOR);
- gtk_file_selection_set_filename (GTK_FILE_SELECTION (filesel), tmp);
- }
-
- gtk_widget_show (filesel);
- }
-
- static void
- fileselector_for_mkdir_callback (GtkWidget *widget, gpointer client_data)
- {
- GtkWidget *filesel;
-
- ASSERT (cwd_cache_validate ());
-
- filesel = gtk_file_selection_new ("New directory");
- gtk_window_position (GTK_WINDOW (filesel), GTK_WIN_POS_MOUSE);
-
- {
- GCHAR tmp[PATH_LENGTH];
-
- sprintf (tmp, "%s%c.", cwd_cache->name, G_DIR_SEPARATOR);
- gtk_file_selection_set_filename (GTK_FILE_SELECTION (filesel), tmp);
- }
-
- gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->ok_button),
- "clicked", (GtkSignalFunc) mkdir_callback,
- filesel);
-
- gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (filesel)->cancel_button),
- "clicked", (GtkSignalFunc) gtk_widget_destroy,
- GTK_OBJECT (GTK_WINDOW (filesel)));
-
- gtk_widget_show (filesel);
- }
-
- static void
- copy_callback (GtkWidget *widget, gpointer data)
- {
- GCHAR *pathname, *tmp;
-
- ASSERT (cwd_cache_validate () && selection_validate_image ());
-
- tmp = gtk_file_selection_get_filename (GTK_FILE_SELECTION (data));
- pathname = (GCHAR *) g_malloc (strlen (tmp) + 1);
- strcpy (pathname, tmp);
- guash_set_fileselector_last_value (pathname);
-
- gtk_widget_destroy (GTK_WIDGET (data));
-
- selection_copy_files_to (pathname);
-
- g_free (pathname);
- }
-
- static void
- move_callback (GtkWidget *widget, gpointer data)
- {
- GCHAR *pathname, *tmp;
-
- ASSERT (cwd_cache_validate () && selection_validate_image ());
-
- tmp = gtk_file_selection_get_filename (GTK_FILE_SELECTION (data));
- pathname = (GCHAR *) g_malloc (strlen (tmp) + 1);
- strcpy (pathname, tmp);
- guash_set_fileselector_last_value (pathname);
-
- gtk_widget_destroy (GTK_WIDGET (data));
-
- selection_move_files_to (pathname);
-
- g_free (pathname);
- }
-
- static void
- delete_callback (GtkWidget *widget, gpointer data)
- {
- ASSERT (cwd_cache_validate () && selection_validate_image ());
-
- if (HAS_ATTRIBUTE (&VAL, CONFIRM_P))
- {
- GCHAR buffer [LINE_BUF_SIZE];
-
- if (selection_length () == 1)
- {
- Thumbnail *selected;
-
- selected = directory_cache_get_nth (cwd_cache, cwd_cache->selection_top);
- sprintf (buffer, _(" Do you want to delete the selected image: %s? "),
- selected->name);
- }
- else
- {
- sprintf (buffer, _(" Do you want to delete the selected %d images? "),
- selection_length ());
- }
- if (! gtkW_confirmor_dialog (TRUE, buffer, FALSE))
- return;
- }
- selection_delete_files ();
- guash_discard_events ();
- }
-
- static void
- select_all_callback (GtkWidget *widget, gpointer data)
- {
- gint index;
- gint max = directory_cache_num_entry (cwd_cache);
-
- for (index = cwd_cache->ndir; index < max; index++)
- selection_add (index);
- selection_show ();
- thumbnail_panel_set_info (NULL);
- }
-
- static void
- select_none_callback (GtkWidget *widget, gpointer data)
- {
- selection_reset ();
- thumbnail_panel_set_info (NULL);
- }
-
- static void
- chdir_callback (GtkWidget *widget, gpointer data)
- {
- GCHAR *pathname, *tmp;
- gint f_kind;
-
- ASSERT (cwd_cache_validate ());
-
- tmp = gtk_file_selection_get_filename (GTK_FILE_SELECTION (data));
- pathname = (GCHAR *) g_malloc (strlen (tmp) + 1);
- strcpy (pathname, tmp);
- guash_set_fileselector_last_value (pathname);
-
- gtk_widget_destroy (GTK_WIDGET (data));
-
- tmp = pathname;
- f_kind = os_file_kind (tmp, TRUE);
- while ((f_kind == NOT_EXIST) || (f_kind == REGFILE))
- {
- tmp = pathname_get_directoryname (tmp);
- f_kind = os_file_kind (tmp, TRUE);
- }
-
- switch (os_file_kind (tmp, TRUE))
- {
- case DIRECTORY:
- guash_change_current_directory (tmp, NULL);
- break;
- default:
- thumbnail_panel_set_info (_("Can't move there"));
- break;
- }
- g_free (pathname);
- }
-
- static void
- mkdir_callback (GtkWidget *widget, gpointer data)
- {
- GCHAR *pathname, *tmp;
-
- ASSERT (cwd_cache_validate ());
-
- tmp = gtk_file_selection_get_filename (GTK_FILE_SELECTION (data));
- pathname = (GCHAR *) g_malloc (strlen (tmp) + 1);
- strcpy (pathname, tmp);
- gtk_widget_destroy (GTK_WIDGET (data));
-
- os_mkdir (pathname);
-
- /* guash_set_fileselector_last_value should be called after making the directory */
- guash_set_fileselector_last_value (pathname);
-
- g_free (pathname);
- }
-
- static void
- selection_map_script_callback (GtkWidget *widget, gpointer data)
- {
- ASSERT (cwd_cache_validate () && selection_validate_image ());
-
- selection_map_script ();
- }
-
- static void
- selection_map_unix_command_callback (GtkWidget *widget, gpointer data)
- {
- ASSERT (cwd_cache_validate () && selection_validate_image ());
-
- selection_map_unix_command ();
- }
-
- static void
- jump_to_subdir1_callback (GtkWidget *widget, gpointer data)
- {
- cwd_cache_jump_to_subdirectory_index (1);
- }
-
- static void
- jump_to_subdir2_callback (GtkWidget *widget, gpointer data)
- {
- cwd_cache_jump_to_subdirectory_index (2);
- }
-
- static void
- jump_to_subdir3_callback (GtkWidget *widget, gpointer data)
- {
- cwd_cache_jump_to_subdirectory_index (3);
- }
-
- static void
- jump_to_subdir4_callback (GtkWidget *widget, gpointer data)
- {
- cwd_cache_jump_to_subdirectory_index (4);
- }
-
- static void
- jump_to_subdir5_callback (GtkWidget *widget, gpointer data)
- {
- cwd_cache_jump_to_subdirectory_index (5);
- }
-
- static void
- jump_to_subdir6_callback (GtkWidget *widget, gpointer data)
- {
- cwd_cache_jump_to_subdirectory_index (6);
- }
-
- static void
- jump_to_subdir7_callback (GtkWidget *widget, gpointer data)
- {
- cwd_cache_jump_to_subdirectory_index (7);
- }
-
- static void
- jump_to_subdir8_callback (GtkWidget *widget, gpointer data)
- {
- cwd_cache_jump_to_subdirectory_index (8);
- }
-
- static void
- jump_to_subdir9_callback (GtkWidget *widget, gpointer data)
- {
- cwd_cache_jump_to_subdirectory_index (9);
- }
-
- static gint
- preview_event_handler (GtkWidget *widget, GdkEvent *event)
- {
- GdkEventButton *bevent;
- gint x, y, index;
-
- DEBUGBLOCK (N_("preview_event_handler\n"));
-
- gtk_widget_get_pointer (widget, &x, &y);
-
- bevent = (GdkEventButton *) event;
- index = (cwd_cache && VALID_POS_P (x, y)) ? (POS_TO_INDEX (x, y)) : -1;
-
- switch (event->type)
- {
- case GDK_BUTTON_PRESS:
- _DPRINT (N_("GDK_BUTTON PRESS\n"));
- if (during_buildup_thumbnail_panel == TRUE)
- break;
- switch (bevent->button)
- {
- case 1:
- if (directory_cache_valid_index (cwd_cache, index))
- {
- Thumbnail *thumbnail = directory_cache_get_nth (cwd_cache, index);
-
- if (HAS_ATTRIBUTE (thumbnail, DIRECTORY_P))
- {
- GCHAR tmp[PATH_LENGTH];
- GCHAR *ptr;
-
- if (HAS_ATTRIBUTE (thumbnail, PARENT_DIRECTORY_P))
- //#ifndef NATIVE_WIN32
- #if 1
- ptr = thumbnail->name;
- #else
- ptr = "..";
- #endif
- else
- {
- sprintf (tmp, "%s%c%s", cwd_cache->name, G_DIR_SEPARATOR, thumbnail->name);
- ptr = tmp;
- }
-
- if (selection_is_active ())
- {
- if (bevent->state & GDK_CONTROL_MASK)
- {
- selection_copy_files_to (ptr);
- }
- else if (bevent->state & GDK_SHIFT_MASK)
- {
- if (guash_confirm_operation ("Move"))
- selection_move_files_to (ptr);
- }
- else
- {
- guash_change_current_directory (ptr, thumbnail);
- }
- }
- else
- {
- WATCH (guash_change_current_directory (ptr, thumbnail));
- }
- }
- else
- {
- if (bevent->state & GDK_SHIFT_MASK)
- {
- selection_reverse_member (index);
- if (selection_is_active ())
- thumbnail_panel_set_info (thumbnail->info);
- else
- thumbnail_panel_set_info (NULL);
- }
- else
- {
- if (selection_is_active () && selection_member_p (index))
- selection_open_files ();
- else
- {
- selection_reset ();
- selection_add_and_show (index);
- thumbnail_panel_set_info (thumbnail->info);
- }
- }
- }
- }
- else
- {
- thumbnail_panel_set_info (NULL);
- }
- break;
- case 2:
- if (bevent->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK))
- {
- if (0 < cwd_cache->display_page)
- cwd_cache->display_page--;
- else
- cwd_cache->display_page = cwd_cache_npage () - 1;
- }
- else
- {
- if (cwd_cache->display_page + 1 < cwd_cache_npage ())
- cwd_cache->display_page++;
- else if (0 < cwd_cache->display_page)
- cwd_cache->display_page = 0;
- }
- thumbnail_panel_update ();
- break;
- case 3:
- if (bevent->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK))
- gtk_menu_popup (GTK_MENU (thumbnail_panel_root_menu),
- NULL, NULL, NULL, NULL, 3, bevent->time);
- else if (selection_is_active ())
- gtk_menu_popup (GTK_MENU (thumbnail_panel_selection_menu),
- NULL, NULL, NULL, NULL, 3, bevent->time);
- else
- gtk_menu_popup (GTK_MENU (thumbnail_panel_root_menu),
- NULL, NULL, NULL, NULL, 3, bevent->time);
- break;
- default:
- thumbnail_panel_update ();
- break;
- }
- break;
- case GDK_EXPOSE:
- _DPRINT (N_("GDK_EXPOSE\n"));
- /* current string render works only if the window is on the top. Thus
- we need repaint when the window receives GDK_EXPOSE.
- Sun Aug 30 00:48:40 1998 */
- if (the_panel.resized && (during_buildup_thumbnail_panel == FALSE))
- {
- the_panel.resized = FALSE;
- DPRINT (N_("resized: rendering...\n"));
- thumbnail_panel_update ();
- DPRINT (N_("resized: rendering... done\n"));
- gtk_widget_draw (thumbnail_panel, NULL);
- }
- /* from 0.99.5 [Sat Feb 28 06:30:45 1998] gtk_widget_show (dlg); */
- gdk_flush ();
- break;
- default:
- break;
- }
- _DPRINT (N_("end of preview_event_handler\n"));
-
- RETURN FALSE;
- }
-
- static gint
- cursor_event_handler (GtkWidget *widget, GdkEventKey *event)
- {
- GdkEventKey *kevent;
-
- kevent = (GdkEventKey *) event;
-
- switch (kevent->keyval)
- {
- case GDK_Left:
- thumbnail_panel_move_focus (-1);
- break;
- case GDK_Right:
- thumbnail_panel_move_focus (1);
- break;
- case GDK_Up:
- thumbnail_panel_move_focus (- the_panel.ncol);
- break;
- case GDK_Down:
- thumbnail_panel_move_focus (the_panel.ncol);
- break;
- default:
- #ifdef GTK_HAVE_FEATURES_1_1_0
- gtk_accel_groups_activate (GTK_OBJECT (thumbnail_panel),
- kevent->keyval,
- kevent->state);
- #endif
- break;
- }
- gtk_widget_grab_focus (thumbnail_panel);
- return FALSE;
- }
-
- static void
- dnd_drag_button_callback (GtkWidget *widget, GdkEvent *event)
- {
- thumbnail_panel_set_info (_("You failed to copy/move. Don't click but drag the button"));
- }
-
- #ifdef NEW_DND_API
- static void
- dnd_drag_request_callback (GtkWidget *widget,
- GdkDragContext *context,
- GtkSelectionData *selection_data,
- guint info,
- guint time,
- gpointer data)
- #else
- static void
- dnd_drag_request_callback (GtkWidget *widget, GdkEvent *event)
- #endif
- {
- selection_iterator *iterator;
- Thumbnail *selected;
- GString *str;
-
- ASSERT (cwd_cache_validate () && selection_validate_image ());
-
- DEBUGBLOCK (N_("dnd_drag_request_callback\n"));
-
- #ifdef NEW_DND_API
- str = g_string_new ("");
- #else
- str = g_string_new (GUASH_DND_SIGNATURE);
- #endif
-
- iterator = selection_make_iterator (SELECTION_ORDER_INDEX);
- while (NULL != (selected = selection_iterator_get_next_thumbnail (iterator)))
- {
- g_string_append (str, cwd_cache->name);
- g_string_append_c (str, G_DIR_SEPARATOR);
- g_string_append (str, selected->name);
- g_string_append_c (str, '\n');
- }
-
- #ifdef NEW_DND_API
- DPRINT (N_("set data in dnd_drag_request_callback\n"));
- gtk_selection_data_set (selection_data,
- selection_data->target,
- 8, str->str, strlen (str->str) + 1);
- #else
- gtk_widget_dnd_data_set (widget, event, str->str, strlen (str->str) + 1);
- #endif
- g_string_free (str, TRUE);
-
- RETURN;
- }
-
- #ifdef NEW_DND_API
- static void
- dnd_source_delete_data (GtkWidget *widget,
- GdkDragContext *context,
- gpointer data)
- {
- DEBUGBLOCK (N_("dnd_source_delete_data\n"));
-
- if (context->action == GDK_ACTION_MOVE)
- {
- DPRINT (N_("action is GDK_ACTION_MOVE: delete the selected image\n"));
- selection_delete_files ();
- }
-
- RETURN;
- }
-
- static void
- dnd_data_received (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- GtkSelectionData *data,
- guint info,
- guint time)
-
- {
- GCHAR *ptr = NULL;
- GCHAR dest[PATH_LENGTH];
- GCHAR *subdir_p = NULL;
- gint index;
-
- ASSERT (cwd_cache_validate ());
-
- DEBUGBLOCK (N_("dnd_data_received\n"));
-
- ptr = (GCHAR *) data->data;
- index = VALID_POS_P (x, y) ? POS_TO_INDEX (x, y): -1;
-
- if (directory_cache_valid_index (cwd_cache, index))
- {
- Thumbnail *thumbnail = directory_cache_get_nth (cwd_cache, index);
-
- if (HAS_ATTRIBUTE (thumbnail, DIRECTORY_P))
- {
- if (HAS_ATTRIBUTE (thumbnail, PARENT_DIRECTORY_P))
- {
- sprintf (dest, "%s", thumbnail->name);
- subdir_p = "the parent directory";
- }
- else
- {
- sprintf (dest, "%s%c%s", cwd_cache->name, G_DIR_SEPARATOR, thumbnail->name);
- subdir_p = thumbnail->name;
- }
- }
- else
- strcpy (dest, cwd_cache->name);
- }
- else
- strcpy (dest, cwd_cache->name);
-
- {
- GCHAR *message;
-
- if (subdir_p == NULL)
- message = "current directory";
- else
- message = subdir_p;
-
- if (dnd_copy_files_to (ptr, dest, message, (subdir_p == NULL)))
- {
- if (context->action == GDK_ACTION_MOVE)
- gtk_drag_finish (context, TRUE, TRUE, time);
- else
- gtk_drag_finish (context, TRUE, FALSE, time);
- }
- else
- {
- context->action = GDK_ACTION_COPY;
- gtk_drag_finish (context, FALSE, FALSE, time);
- }
- }
- RETURN;
- }
-
- static gboolean
- dnd_drop (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- guint time)
- {
- DEBUGBLOCK (N_("dnd_drop\n"));
- RETURN FALSE;
-
- DPRINTIF (context->targets) (N_("set data\n"));
-
- if (context->targets)
- gtk_drag_get_data (widget, context,
- GPOINTER_TO_INT (context->targets->data),
- time);
- RETURN FALSE;
- }
-
- #else
- static void
- dnd_drop (GtkWidget *widget, GdkEvent *event)
- {
- GCHAR *ptr = NULL;
- GCHAR dest[PATH_LENGTH];
- GCHAR *subdir_p = NULL;
- gint x, y, index;
-
- ASSERT (cwd_cache_validate ());
-
- DEBUGBLOCK (N_("dnd_drop\n"));
-
- gtk_widget_get_pointer (widget, &x, &y);
-
- ptr = (GCHAR *)event->dropdataavailable.data;
-
- if (strlen (ptr) < strlen (GUASH_DND_SIGNATURE))
- RETURN;
- if (strncmp (ptr, GUASH_DND_SIGNATURE, strlen (GUASH_DND_SIGNATURE)) != 0)
- RETURN;
- ptr += strlen (GUASH_DND_SIGNATURE);
- index = VALID_POS_P (x, y) ? POS_TO_INDEX (x, y): -1;
-
- if (directory_cache_valid_index (cwd_cache, index))
- {
- Thumbnail *thumbnail = directory_cache_get_nth (cwd_cache, index);
-
- if (HAS_ATTRIBUTE (thumbnail, DIRECTORY_P))
- {
- sprintf (dest, "%s%c%s", cwd_cache->name, G_DIR_SEPARATOR, thumbnail->name);
- subdir_p = thumbnail->name;
- }
- else
- strcpy (dest, cwd_cache->name);
- }
- else
- strcpy (dest, cwd_cache->name);
-
- {
- GCHAR *message;
-
- if (subdir_p == NULL)
- message = "current directory";
- else
- message = subdir_p;
-
- dnd_copy_files_to (ptr, dest, message, (subdir_p == NULL));
- }
- RETURN;
- }
- #endif
-
- static gint
- dnd_copy_files_to (GCHAR *buffer, GCHAR *pathname, GCHAR *dir, gint cwd_p)
- {
- GCHAR info[LINE_BUF_SIZE];
- GCHAR first_file[LINE_BUF_SIZE];
- GCHAR *ptr = buffer;
- gint kind = NOT_EXIST;
- gint success = 0;
- gint fail = FALSE;
- directory_cache *dcache = NULL;
-
- DEBUGBLOCK (N_("dnd_copy_files_to (\"...\", \"%s\", \"%s\", %d)\n"),
- pathname, dir, cwd_p);
-
- dcache = guash_lookup_directory_cache (pathname);
-
- while (*ptr)
- {
- gint index = 0;
-
- kind = os_file_kind (pathname, TRUE);
- while ((ptr[index] != 0) && (ptr[index] != '\n'))
- index++;
-
- if ((kind == NOT_EXIST) || (kind == DIRECTORY))
- {
- GCHAR name[PATH_LENGTH];
- GCHAR new[PATH_LENGTH];
- GCHAR *file_basename;
-
- g_memmove (name, ptr, index);
- name[index] = 0;
- DPRINT (N_("name: %s\n"), name);
- file_basename = pathname_get_basename (name);
-
- if (kind == DIRECTORY)
- {
- if (pathname [strlen (pathname) - 1] != G_DIR_SEPARATOR)
- sprintf (new, "%s%c%s", pathname, G_DIR_SEPARATOR, file_basename);
- else
- sprintf (new, "%s%s", pathname, file_basename);
- }
- else
- sprintf (new, "%s", pathname);
-
- DPRINT (N_("destination: %s\n"), new);
- /* try to copy `name' to `new->str' */
- if (os_file_kind (new, TRUE) != NOT_EXIST)
- {
- fail = TRUE;
- sprintf (info, _("%s already exists"), new);
- gtkW_message_dialog (TRUE, info);
- }
- else if (guash_copy_image_file (name, new) == TRUE)
- {
- if (success++ == 0)
- strcpy (first_file, file_basename);
- if (dcache != NULL)
- directory_cache_update_thumbnail_for (dcache, name, NULL);
- }
- else
- fail = TRUE;
- }
- else if (kind == REGFILE)
- {
- fail = TRUE;
- sprintf (info, _("%s already exists"), pathname);
- gtkW_message_dialog (TRUE, info);
- }
- if (ptr[index] == 0)
- break;
- else
- ptr += index + 1;
- }
-
- if (0 < success)
- {
- if (dcache != NULL)
- dcache->timestamp = os_file_get_modify_timestamp (dcache->name);
- cwd_cache_update_after_file_operation (success, "copied", first_file, dir);
- }
- else
- thumbnail_panel_set_info (_("Failed to copy"));
-
- RETURN (! fail);
- }
-
- /*
- * start of GtkW lib
- */
- static void
- gtkW_close_callback (GtkWidget *widget,
- gpointer data)
- {
- gtk_main_quit ();
- }
-
- static void
- gtkW_message_dialog (gint gtk_was_initialized, GCHAR *message)
- {
- GtkWidget *dlg;
- GtkWidget *table;
- GtkWidget *label;
- gchar **argv;
- gint argc;
-
- if (! gtk_was_initialized)
- {
- argc = 1;
- argv = g_new (gchar *, 1);
- argv[0] = g_strdup (PLUG_IN_NAME);
- gtk_init (&argc, &argv);
- gtk_rc_parse (gimp_gtkrc ());
- }
-
- dlg = gtkW_message_dialog_new (PLUG_IN_NAME);
- gtk_window_set_wmclass (GTK_WINDOW (dlg), "Guash", "Gimp");
-
- table = gtkW_table_new (GTK_DIALOG (dlg)->vbox, 1, 1);
-
- label = gtk_label_new (message);
- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL|GTK_EXPAND,
- 0, 0, 0);
-
- gtk_widget_show (label);
- gtk_widget_show (dlg);
-
- gtk_main ();
- gdk_flush ();
- }
-
- static GtkWidget *
- gtkW_message_dialog_new (GCHAR *name)
- {
- GtkWidget *dlg, *button;
-
- dlg = gtk_dialog_new ();
- gtk_window_set_title (GTK_WINDOW (dlg), name);
- gtk_window_position (GTK_WINDOW (dlg), GTK_WIN_POS_MOUSE);
- gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
- (GtkSignalFunc) gtkW_close_callback, NULL);
- gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (dlg)->action_area),
- gtkW_border_width);
-
- /* Action Area */
- button = gtk_button_new_with_label ("OK");
- GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
- gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
- (GtkSignalFunc) gtk_widget_destroy,
- GTK_OBJECT (dlg));
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), button,
- TRUE, TRUE, 0);
- gtk_widget_grab_default (button);
- gtk_widget_show (button);
-
- return dlg;
- }
-
- static gint
- gtkW_confirmor_dialog (gint gtk_was_initialized, GCHAR *message, gint default_value)
- {
- GtkWidget *dlg;
- GtkWidget *table;
- GtkWidget *label;
- gtkW_widget_table wtable;
- gchar **argv;
- gint argc;
-
- if (! gtk_was_initialized)
- {
- argc = 1;
- argv = g_new (gchar *, 1);
- argv[0] = g_strdup (PLUG_IN_NAME);
- gtk_init (&argc, &argv);
- gtk_rc_parse (gimp_gtkrc ());
- }
-
- dlg = gtkW_confirmor_new (PLUG_IN_NAME, default_value, &wtable);
-
- table = gtkW_table_new (GTK_DIALOG (dlg)->vbox, 1, 1);
-
- label = gtk_label_new (message);
- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL|GTK_EXPAND,
- 0, 0, 0);
-
- gtk_widget_show (label);
- gtk_widget_show (dlg);
-
- gtk_main ();
- gdk_flush ();
- return (gint) wtable.value;
- }
-
- static GtkWidget *
- gtkW_confirmor_new (GCHAR *name, gint default_value, gtkW_widget_table *table)
- {
- GtkWidget *dlg, *button;
-
- dlg = gtk_dialog_new ();
- gtk_window_set_title (GTK_WINDOW (dlg), name);
- gtk_window_position (GTK_WINDOW (dlg), GTK_WIN_POS_MOUSE);
- gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
- (GtkSignalFunc) gtkW_close_callback, NULL);
- gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (dlg)->action_area),
- gtkW_border_width);
- table->widget = dlg;
-
- /* Action Area */
- button = gtk_button_new_with_label ("Yes");
- gtk_signal_connect (GTK_OBJECT (button), "clicked",
- (GtkSignalFunc) gtkW_confirmor_yes,
- (gpointer) table);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), button,
- TRUE, TRUE, 0);
- GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
- if (default_value == TRUE)
- {
- gtk_widget_grab_default (button);
- }
- gtk_widget_show (button);
-
- button = gtk_button_new_with_label ("No");
- gtk_signal_connect (GTK_OBJECT (button), "clicked",
- (GtkSignalFunc) gtkW_confirmor_no,
- (gpointer) table);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), button,
- TRUE, TRUE, 0);
- GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
- if (default_value == FALSE)
- {
- gtk_widget_grab_default (button);
- }
- gtk_widget_show (button);
-
- return dlg;
- }
-
- static void
- gtkW_confirmor_yes (GtkWidget *widget, gpointer data)
- {
- gtkW_widget_table *table;
-
- table = (gtkW_widget_table *)data;
- table->value = (gpointer) TRUE;
- gtk_widget_destroy ((GtkWidget *) (table->widget));
- }
-
- static void
- gtkW_confirmor_no (GtkWidget *widget, gpointer data)
- {
- gtkW_widget_table *table;
-
- table = (gtkW_widget_table *)data;
- table->value = (gpointer) FALSE;
- gtk_widget_destroy ((GtkWidget *) (table->widget));
- }
-
- static GtkWidget *
- gtkW_frame_new (GtkWidget *parent, GCHAR *name)
- {
- GtkWidget *frame;
-
- frame = gtk_frame_new (name);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), gtkW_frame_shadow_type);
- gtk_container_border_width (GTK_CONTAINER (frame), gtkW_border_width);
- if (parent != NULL)
- gtk_box_pack_start (GTK_BOX(parent), frame, TRUE, TRUE, 0);
- gtk_widget_show (frame);
-
- return frame;
- }
-
- static GtkWidget *
- gtkW_hbox_new (GtkWidget *parent, gint expand, gint fill)
- {
- GtkWidget *hbox;
-
- hbox = gtk_hbox_new (FALSE, 2);
- gtk_container_border_width (GTK_CONTAINER (hbox), gtkW_border_width);
- if (parent)
- {
- gtk_box_pack_start (GTK_BOX (parent), hbox, expand, fill,
- gtkW_border_width);
- /* gtk_container_add (GTK_CONTAINER (parent), hbox); */
- }
- gtk_widget_show (hbox);
-
- return hbox;
- }
-
- static GtkWidget *
- gtkW_table_new (GtkWidget *parent, gint col, gint row)
- {
- GtkWidget *table;
-
- table = gtk_table_new (col,row, FALSE);
- gtk_container_border_width (GTK_CONTAINER (table), gtkW_border_width);
- gtk_container_add (GTK_CONTAINER (parent), table);
- gtk_widget_show (table);
-
- return table;
- }
-
- static GtkWidget *
- gtkW_table_add_label (GtkWidget *table,
- GCHAR *text,
- gint x0,
- gint x1,
- gint y,
- gint flush_left)
- {
- GtkWidget *label;
-
- label = gtk_label_new (text);
- if (flush_left)
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
- gtk_table_attach (GTK_TABLE(table), label, x0, x1, y, y+1,
- gtkW_align_x, gtkW_align_y, 5, 0);
- gtk_widget_show (label);
-
- return label;
- }
-
- static void
- gtkW_iscroll_entry_change_value (gtkW_widget_table *wtable)
- {
- GtkWidget *entry;
- gchar buffer[32];
- GtkAdjustment *adjustment = (GtkAdjustment *) (wtable->widget);
-
- if (! cwd_cache)
- return;
- /* adustment->value is double, that is not precise to hold long interger. */
- adjustment->value = * (gint *) (wtable->value);
- gtk_signal_emit_by_name (GTK_OBJECT (adjustment), "value_changed");
- entry = gtk_object_get_user_data (GTK_OBJECT (adjustment));
- if (entry)
- {
- sprintf (buffer, "%d", (gint) adjustment->value);
- gtk_entry_set_text (GTK_ENTRY (entry), buffer);
- }
- }
-
- static void
- gtkW_iscroll_update (GtkAdjustment *adjustment,
- gpointer data)
- {
- GtkWidget *entry;
- gchar buffer[32];
- gint *val;
-
- if (! cwd_cache)
- return;
- val = data;
- if (*val != (gint) adjustment->value)
- {
- *val = adjustment->value;
-
- entry = gtk_object_get_user_data (GTK_OBJECT (adjustment));
- if (entry)
- {
- sprintf (buffer, "%d", (int) adjustment->value);
- gtk_entry_set_text (GTK_ENTRY (entry), buffer);
- }
- cwd_cache->display_page = (gint) adjustment->value - 1;
-
- if (delayed_updating == 0)
- delayed_updating = gtk_idle_add ((GtkFunction) thumbnail_panel_update_delayed, NULL);
- }
- }
-
- static void
- gtkW_ivscroll_entry_new (GtkWidget **scroll,
- GtkWidget **entry,
- GtkSignalFunc scroll_update,
- GtkSignalFunc entry_update,
- gint *value,
- gdouble min,
- gdouble max,
- gdouble step,
- gpointer widget_entry)
- {
- GtkObject *adjustment;
- GCHAR buffer[GTKW_ENTRY_BUFFER_SIZE];
-
- adjustment = gtk_adjustment_new (*value, min, max, step, step, step);
- gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
- (GtkSignalFunc) scroll_update, value);
-
- *scroll = gtk_vscrollbar_new (GTK_ADJUSTMENT (adjustment));
- gtk_range_set_update_policy (GTK_RANGE (*scroll), GTK_UPDATE_CONTINUOUS);
-
- *entry = gtk_entry_new ();
- gtk_object_set_user_data (GTK_OBJECT (*entry), adjustment);
- gtk_object_set_user_data (GTK_OBJECT (adjustment), *entry);
- gtk_widget_set_usize (*entry, GTKW_ENTRY_WIDTH, 0);
-
- sprintf (buffer, "%d", *value);
- gtk_entry_set_text (GTK_ENTRY (*entry), buffer);
- gtk_signal_connect (GTK_OBJECT (*entry), "changed",
- (GtkSignalFunc) entry_update, value);
-
- if (widget_entry)
- {
- gtkW_widget_table *tentry = (gtkW_widget_table *) widget_entry;
-
- tentry->widget = (GtkWidget *) adjustment;
- tentry->updater = gtkW_iscroll_entry_change_value;
- tentry->value = value;
- }
- }
-
- static void
- gtkW_ientry_update (GtkWidget *widget,
- gpointer data)
- {
- GtkAdjustment *adjustment;
- gint val, new_val;
-
- if (! cwd_cache)
- return;
-
- val = cwd_cache->display_page + 1;
- new_val = atoi (gtk_entry_get_text (GTK_ENTRY (widget)));
-
- if (val != new_val)
- {
- adjustment = gtk_object_get_user_data (GTK_OBJECT (widget));
-
- if ((new_val >= adjustment->lower) &&
- (new_val <= adjustment->upper))
- {
- adjustment->value = new_val;
- cwd_cache->display_page = (gint) new_val - 1;
- gtk_signal_emit_by_name (GTK_OBJECT (adjustment), "value_changed");
- }
- }
- }
-
- static void
- gtkW_query_box (GCHAR *title, GCHAR *message, GCHAR *initial, GCHAR *data)
- {
- GtkWidget *qbox;
-
- qbox = gtkW_query_string_box_new (title, message, initial, (gpointer) data);
- gtk_main ();
- gdk_flush ();
- }
-
- static void
- gtkW_preview_force_to_update (GtkWidget *widget)
- {
- GtkPreview *preview = GTK_PREVIEW (widget);
-
- DEBUGBLOCK (N_("gtkW_preview_force_to_update\n"));
-
- gtk_preview_put (GTK_PREVIEW (widget),
- widget->window, widget->style->black_gc,
- (widget->allocation.width - preview->buffer_width) / 2,
- (widget->allocation.height - preview->buffer_height) / 2,
- 0, 0,
- widget->allocation.width, widget->allocation.height);
- gdk_flush ();
-
- RETURN;
- }
-
- static void
- gtkW_preview_force_to_update_partially (GtkWidget *widget,
- gint x, gint y,
- gint width, gint height)
- {
- GdkRectangle current_row;
-
- current_row.x = x;
- current_row.y = y;
- current_row.width = width;
- current_row.height = height;
-
- gtk_widget_draw (widget, ¤t_row);
- }
-
- /* copied from gimp/app/interface.c */
- /*
- * A text string query box
- */
- typedef struct _QueryBox QueryBox;
-
- struct _QueryBox
- {
- GtkWidget *qbox;
- GtkWidget *entry;
- gpointer data;
- };
-
- static GtkWidget *
- gtkW_query_string_box_new (char *title,
- char *message,
- char *initial,
- gpointer data)
- {
- QueryBox *query_box;
- GtkWidget *qbox;
- GtkWidget *vbox;
- GtkWidget *label;
- GtkWidget *entry;
- GtkWidget *button;
-
- query_box = g_new (QueryBox, 1);
-
- qbox = gtk_dialog_new ();
- gtk_window_set_title (GTK_WINDOW (qbox), title);
- gtk_window_position (GTK_WINDOW (qbox), GTK_WIN_POS_MOUSE);
- gtk_signal_connect (GTK_OBJECT (qbox), "delete_event",
- (GtkSignalFunc) gtkW_query_box_delete_callback,
- query_box);
- gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (qbox)->action_area),
- gtkW_border_height);
-
- button = gtk_button_new_with_label ("OK");
- GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
- gtk_signal_connect (GTK_OBJECT (button), "clicked",
- (GtkSignalFunc) gtkW_query_box_ok_callback,
- query_box);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (qbox)->action_area), button, TRUE, TRUE, 0);
- gtk_widget_grab_default (button);
- gtk_widget_show (button);
-
- button = gtk_button_new_with_label ("Cancel");
- GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
- gtk_signal_connect (GTK_OBJECT (button), "clicked",
- (GtkSignalFunc) gtkW_query_box_cancel_callback,
- query_box);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (qbox)->action_area), button, TRUE, TRUE, 0);
- gtk_widget_show (button);
-
- vbox = gtk_vbox_new (FALSE, 1);
- gtk_container_border_width (GTK_CONTAINER (vbox), gtkW_border_width);
- gtk_container_add (GTK_CONTAINER (GTK_DIALOG (qbox)->vbox), vbox);
- gtk_widget_show (vbox);
-
- label = gtk_label_new (message);
- gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, FALSE, 0);
- gtk_widget_show (label);
-
- entry = gtk_entry_new ();
- gtk_box_pack_start (GTK_BOX (vbox), entry, TRUE, TRUE, 0);
- if (initial)
- gtk_entry_set_text (GTK_ENTRY (entry), initial);
- gtk_widget_show (entry);
-
- query_box->qbox = qbox;
- query_box->entry = entry;
- query_box->data = data;
-
- gtk_widget_show (qbox);
-
- return qbox;
- }
-
- static gint
- gtkW_query_box_delete_callback (GtkWidget *w,
- GdkEvent *e,
- gpointer client_data)
- {
- gtkW_query_box_cancel_callback (w, client_data);
- return FALSE;
- }
-
- static void
- gtkW_query_box_cancel_callback (GtkWidget *w, gpointer client_data)
- {
- QueryBox *query_box;
-
- query_box = (QueryBox *) client_data;
-
- *((GCHAR *) query_box->data) = 0;
- /* Destroy the box */
- gtk_widget_destroy (query_box->qbox);
- g_free (query_box);
- gtk_main_quit ();
- }
-
- static void
- gtkW_query_box_ok_callback (GtkWidget *w, gpointer client_data)
- {
- QueryBox *query_box;
- char *string;
-
- query_box = (QueryBox *) client_data;
-
- /* Get the entry data */
- string = g_strdup (gtk_entry_get_text (GTK_ENTRY (query_box->entry)));
-
- /* Call the user defined callback */
- /* (* query_box->callback) (w, query_box->data, (gpointer) string); */
- strcpy ((GCHAR *)query_box->data, string);
- /* Destroy the box */
- gtk_widget_destroy (query_box->qbox);
- g_free (query_box);
- gtk_main_quit ();
- }
-
- static gint
- gtkW_parse_gimprc_gint (GCHAR *name, gint default_value)
- {
- GParam *return_vals;
- gint nreturn_vals;
- gint val = default_value;
-
- return_vals = gimp_run_procedure ("gimp_gimprc_query",
- &nreturn_vals,
- PARAM_STRING, name,
- PARAM_END);
- if (return_vals[0].data.d_status == STATUS_SUCCESS)
- val = atoi (return_vals[1].data.d_string);
- gimp_destroy_params (return_vals, nreturn_vals);
-
- return val;
- }
-
- static GCHAR *
- gtkW_parse_gimprc_string (GCHAR *name, GCHAR *result)
- {
- GParam *return_vals;
- gint nreturn_vals;
-
- return_vals = gimp_run_procedure ("gimp_gimprc_query",
- &nreturn_vals,
- PARAM_STRING, name,
- PARAM_END);
- if (return_vals[0].data.d_status == STATUS_SUCCESS)
- strcpy (result, return_vals[1].data.d_string);
- else
- *result = 0;
- gimp_destroy_params (return_vals, nreturn_vals);
-
- return result;
- }
-
- static void
- gtkW_widget_set_cursor (GtkWidget *widget, GdkCursorType cursortype)
- {
- GdkCursor *cursor = NULL;
-
- cursor = gdk_cursor_new (cursortype);
- gdk_window_set_cursor (widget->window, cursor);
- gdk_cursor_destroy (cursor);
- }
- /* gtkW ends here */
-
- static gint
- save_thumbnail_as_xvpict_image (char *filename, Thumbnail *thumb)
- {
- FILE *dest;
- gint i_width = thumb->image->width;
- gint i_height = thumb->image->height;
- gint npixel = i_width * i_height;
-
- DEBUGBLOCK (N_("save_thumbnail_as_xvpict_image (\"%s\"\n"), filename);
-
- if ((dest = fopen (filename, "wb")) == NULL)
- RETURN FALSE;
- fprintf (dest, "P7 332\n");
- fprintf (dest, "#XVVERSION:Version 3.10a Rev: 12/29/94 (faked by The GIMP/GUASH%s)\n",
- HAS_ATTRIBUTE (&VAL, SAVE_AS_GPICT_P)? " 2.0" : " 1.0");
- fprintf (dest, "#IMGINFO:%s\n", thumb->info + strlen (thumb->name) + 1);
- fprintf (dest, "#END_OF_COMMENTS\n");
- fprintf (dest, "%d %d 255\n", i_width, i_height);
- if (thumb->image->ch == 3)
- {
- guchar *ch, val;
- gint rerr=0, gerr=0, berr=0;
-
- if (HAS_NO_ATTRIBUTE (&VAL, SAVE_AS_GPICT_P))
- {
- for (ch = thumb->image->data;
- ch < thumb->image->data + npixel * 3;
- )
- {
- gint32 r, g, b;
-
- r = *(ch++) + rerr;
- r = CLAMP (r, 0, 255);
- g = *(ch++) + gerr;
- g = CLAMP (g, 0, 255);
- b = *(ch++) + berr;
- b = CLAMP (b, 0, 255);
-
- fprintf (dest, "%c", ((r>>5)<<5) | ((g>>5)<<2) | (b>>6));
-
- rerr = r - ( (r>>5) * 255 ) / 7;
- gerr = g - ( (g>>5) * 255 ) / 7;
- berr = b - ( (b>>6) * 255 ) / 3;
- }
- }
- else
- {
- guchar diff_buf[THUMBNAIL_WIDTH * THUMBNAIL_HEIGHT];
- guchar *diff_ptr = diff_buf;
- guchar tmp;
- gint limit = npixel;
-
- DPRINT (N_("save as gpict\n"));
- for (ch = thumb->image->data;
- ch < thumb->image->data + limit * 3;
- )
- {
- val = *ch & 0xE0;
- tmp = (*ch++ & 0x1C) << 3;
- val |= (*ch & 0xE0) >> 3;
- tmp |= *ch++ & 0x18;
- val |= (*ch & 0xC0) >> 6;
- tmp |= (*ch++ & 0x38) >> 3;
-
- fprintf (dest, "%c", val);
- /* build difference datum */
- *diff_ptr++ = tmp;
- }
- /* save the rest pixels */
- for (ch = thumb->image->data + limit * 3;
- ch < thumb->image->data + npixel * 3;
- )
- {
- /* can't combine into a expression. evaluation order problem? */
- val = (*(ch++) & 0xE0);
- val |= ((*(ch++) & 0xE0) >> 3);
- val |= ((*(ch++) & 0xC0) >> 6);
- fprintf (dest, "%c", val);
- }
- {
- guchar *compress = NULL;
- gint clen;
-
- clen = compress_string (diff_buf, npixel, &compress);
- /* then save difference data */
- if (0 < clen)
- fwrite (compress, clen, 1, dest);
- else
- fwrite (diff_buf, npixel, 1, dest);
- g_free (compress);
- }
- }
- }
- else
- fwrite (thumb->image->data, i_width * i_height, 1, dest);
- fclose (dest);
- RETURN TRUE;
- }
-
- static Thumbnail *
- load_xvpict_image (char *filename)
- {
- FILE *fd;
- gint width, height, size;
- GCHAR w_buf[4], h_buf[4];
- GCHAR comment[LINE_BUF_SIZE];
- guchar gpict_buffer[THUMBNAIL_WIDTH * THUMBNAIL_HEIGHT + 3];
-
- DEBUGBLOCK (N_("load_xvpict_image (\"%s\")\n"), filename);
-
- fd = fopen (filename, "rb");
- if (!fd)
- RETURN NULL;
-
- {
- gint flag = TRUE;
- GCHAR buffer[LINE_BUF_SIZE];
-
- while (flag)
- {
- if (fgets (buffer, LINE_BUF_SIZE -1, fd) == NULL)
- return NULL;
- #if defined (_MSC_VER)
- /* //HB: The MSVCRT library function does NOT eliminate the 0x0A in binary mode!
- */
- if (0x0A == buffer[ strlen (buffer) - 1 ])
- buffer[strlen(buffer)-1] = 0x0;
- #endif
- if (g_strncasecmp (buffer, "#IMGINFO", 8) == 0)
- strcpy (comment, buffer);
- else if (g_strncasecmp (buffer, "#END_OF_COMMENTS", 16) == 0)
- flag = FALSE;
- }
- }
-
- /* read the last line of comment that contains info on image size */
- if (fscanf (fd, "%s %s", w_buf, h_buf) != 2)
- {
- fclose (fd);
- RETURN NULL;
- }
- width = atoi (w_buf);
- height = atoi (h_buf);
- size = width * height;
-
- /* assure the position in the file!!!
- Wed Jul 8 23:21:09 1998 -> reimplement Sun Jul 19 03:17:33 1998
- */
- while (fgetc (fd) != '\n');
-
- {
- GCHAR tmp[LINE_BUF_SIZE];
- GCHAR *basename = pathname_get_basename (filename);
-
- if (the_loaded_data->name)
- g_free (the_loaded_data->name);
- the_loaded_data->name = g_strdup (basename);
-
- comment[strlen (comment) - 1] = 0; /* chop newline */
-
- sprintf (tmp, "%s %s", basename, comment + 9);
- if (the_loaded_data->info)
- g_free (the_loaded_data->info);
- the_loaded_data->info = g_strdup (tmp);
- }
- image_buffer_resize (the_loaded_data->image, width, height, 1);
- if (1 != fread (the_loaded_data->image->data, size, 1, fd))
- {
- fclose (fd);
- DPRINT (N_("fail to load thumbnail\n"));
- RETURN NULL;
- }
-
- if (HAS_ATTRIBUTE (&VAL, SAVE_AS_GPICT_P)
- && (1 == fread (gpict_buffer, size, 1, fd)))
- {
- guchar dynamic_buffer[THUMBNAIL_WIDTH * THUMBNAIL_HEIGHT];
- guchar diff[4];
- guchar *ch = NULL;
- guchar *data = NULL;
- gint i;
-
- DPRINT (N_("guash extended thumbnail format\n"));
-
- g_memmove (dynamic_buffer, the_loaded_data->image->data, size);
- image_buffer_resize (the_loaded_data->image, width, height, 3);
-
- data = dynamic_buffer;
- ch = the_loaded_data->image->data;
-
- for (i = 0; i < size; i++)
- {
- *ch++ = *data & 0xE0;
- *ch++ = (*data & 0x1C) << 3;
- *ch++ = (*data++ & 0x03) << 6;
- }
-
- data = the_loaded_data->image->data;
- diff[0] = 0;
- diff[1] = gpict_buffer[0];
- diff[2] = gpict_buffer[1];
- diff[3] = gpict_buffer[2];
- for (ch = gpict_buffer; ch < gpict_buffer + size;)
- {
- gint i;
-
- for (i = 0; i < 4; i++)
- {
- gint shift = 2 * (3 - i);
- gint index = (*ch >> shift) & 0x03;
- guchar val = diff[index];
-
- val = *ch++;
- *data |= (val & 0xC0) >> 3;
- *data = (guchar) (*data * 0xFF / 0xFC);
- data++;
- *data |= val & 0x18;
- *data = (guchar) (*data * 0xFF / 0xF8);
- data++;
- *data |= (val & 0x07) << 3;
- *data = (guchar) (*data * 0xFF / 0xFC);
- data++;
- }
- }
- }
- fclose (fd);
-
- RETURN the_loaded_data;
- }
-
- /* I GAVE UP!
- * gpict is the hidden feature of 2.0.0
- * I tried to implement some simple but high compression algorithm in vain.
- * The current gpict requires x2 file size, 16bit quality, x3 heap memory.
- * Is this acceptable??
- * I might delete the codes in 2.1.0.... Or never put it in public....
- */
- static gint
- compress_string (guchar *str, gint length, guchar **dest)
- {
- gint hist[256];
- gint i, m[3];
- gint clen = (gint) (length / 4) * 4;
- guchar *ch, *buf;
-
- return -1;
-
- DEBUGBLOCK (N_("compress_string\n"));
-
- if (length < 4)
- RETURN -1;
-
- for (i = 0; i < 256; i++)
- {
- hist[i] = hist[i] = 0;
- }
- for (i = 0; i < length; i++)
- {
- hist[(gint) str[i]]++;
- hist[str[i] & 0x29]++;
- }
-
- m[0] = m[1] = m[2] = 0;
- for (i = 0; i < 256; i++)
- if (hist[m[2]] < hist[i])
- {
- if (hist[m[0]] < hist[i])
- {
- m[2] = m[1];
- m[1] = m[0];
- m[0] = i;
- }
- else if (hist[m[1]] < hist[i])
- {
- m[2] = m[1];
- m[1] = i;
- }
- else
- m[2] = i;
- }
-
- DPRINT (N_("1st letter: %d/%d (ratio: %f)\n"),
- hist[m[0]], length, (gint) hist[m[0]] / (gdouble) length);
- DPRINT (N_("2nd letter: %d/%d (ratio: %f)\n"),
- hist[m[1]], length, (gint) hist[m[1]] / (gdouble) length);
- DPRINT (N_("3rd letter: %d/%d (ratio: %f)\n"),
- hist[m[2]], length, (gint) hist[m[2]] / (gdouble) length);
- DPRINT (N_("cover rate: %d/%d (ration: %f)\n"),
- hist[m[0]] + hist[m[1]] + hist[m[2]],
- length, (gint) (hist[m[0]] + hist[m[1]] + hist[m[2]]) / (gdouble) length);
-
- buf = g_new (guchar, 3 + clen);
- buf[0] = hist[m[0]];
- buf[1] = hist[m[1]];
- buf[2] = hist[m[2]];
-
- for (ch = buf, i = 0; i < clen * 4; ch++)
- {
- gint p;
-
- *ch = 0;
- for (p = 0; p < 4; p++)
- {
- gint shift = 2 * (3 - p);
- if (m[0] == str[i])
- *ch |= 0x01 << shift;
- else if (m[1] == str[i])
- *ch |= 0x10 << shift;
- else if (m[2] == str[i])
- *ch |= 0x11 << shift;
- i++;
- }
- }
-
- *dest = buf;
- RETURN 3 + clen;
- }
-
- /*
- * Local variables:
- * compile-command: "gimptool --install guash.c"
- * End:
- */
- /* guash.c ends here */
-