view src/layout_image.c @ 220:7670d5653e1f

Honor selection while fullscreen navigation. The behavior is now consistent in full screen and windowed mode. It fixes the fact that the selection was discarded on "Next". Patch by Uwe Ohse. Cleanups by Laurent Monin.
author zas_
date Wed, 02 Apr 2008 10:40:54 +0000
parents fa0e05f985c3
children bee34a6a4aec
line wrap: on
line source

/*
 * Geeqie
 * (C) 2006 John Ellis
 *
 * Author: John Ellis
 *
 * This software is released under the GNU General Public License (GNU GPL).
 * Please read the included file COPYING for more information.
 * This software comes with no warranty of any kind, use at your own risk!
 */

#include "gqview.h"
#include "layout_image.h"

#include "collect.h"
#include "dnd.h"
#include "editors.h"
#include "filelist.h"
#include "fullscreen.h"
#include "image.h"
#include "image-overlay.h"
#include "img-view.h"
#include "info.h"
#include "layout.h"
#include "layout_util.h"
#include "menu.h"
#include "pixbuf_util.h"
#include "utilops.h"
#include "slideshow.h"
#include "ui_bookmark.h"
#include "ui_fileops.h"
#include "ui_menu.h"

#include <gdk/gdkkeysyms.h> /* for keyboard values */


static GtkWidget *layout_image_pop_menu(LayoutWindow *lw);
static void layout_image_set_buttons(LayoutWindow *lw);

/*
 *----------------------------------------------------------------------------
 * full screen overlay
 *----------------------------------------------------------------------------
 */

void layout_image_overlay_toggle(LayoutWindow *lw)
{
	if (image_osd_get(lw->image, NULL, NULL))
		{
		image_osd_set(lw->image, FALSE, FALSE);
		}
	else
		{
		image_osd_set(lw->image, (lw->full_screen != NULL), TRUE);
		image_osd_icon(lw->image, IMAGE_OSD_ICON, -1);
		}
}

void layout_image_overlay_update(LayoutWindow *lw)
{
	if (!lw) return;

	image_osd_update(lw->image);
}

/*
 *----------------------------------------------------------------------------
 * full screen
 *----------------------------------------------------------------------------
 */

static void layout_image_fullscreen_menu_pos_cb(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer data)
{
	LayoutWindow *lw = data;

	if (!lw->full_screen) return;

	gdk_window_get_origin(lw->full_screen->imd->pr->window, x, y);
	popup_menu_position_clamp(menu, x, y, 0);
}

static void layout_image_full_screen_menu_popup(LayoutWindow *lw)
{
	GtkWidget *menu;

	menu = layout_image_pop_menu(lw);
	gtk_menu_popup(GTK_MENU(menu), NULL, NULL, layout_image_fullscreen_menu_pos_cb, lw, 0, GDK_CURRENT_TIME);
}

#if 0
/* this is handled by layout_key_press_cb */


static gint layout_image_full_screen_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer data)
{
	LayoutWindow *lw = data;
	gint stop_signal;
	gint x = 0;
	gint y = 0;

	stop_signal = TRUE;
	switch (event->keyval)
		{
		case GDK_Left: case GDK_KP_Left:
			x -= 1;
			break;
		case GDK_Right: case GDK_KP_Right:
			x += 1;
			break;
		case GDK_Up: case GDK_KP_Up:
			y -= 1;
			break;
		case GDK_Down: case GDK_KP_Down:
			y += 1;
			break;
		default:
			stop_signal = FALSE;
			break;
		}

	if (x != 0 || y!= 0)
		{
		if (event->state & GDK_SHIFT_MASK)
			{
			x *= 3;
			y *= 3;
			}

		keyboard_scroll_calc(&x, &y, event);
		layout_image_scroll(lw, x, y);
		}

	if (stop_signal) return stop_signal;

	if (event->state & GDK_CONTROL_MASK)
		{
		gint n = -1;

		stop_signal = TRUE;
		switch (event->keyval)
			{
			case '1':
				n = 0;
				break;
			case '2':
				n = 1;
				break;
			case '3':
				n = 2;
				break;
			case '4':
				n = 3;
				break;
			case '5':
				n = 4;
				break;
			case '6':
				n = 5;
				break;
			case '7':
				n = 6;
				break;
			case '8':
				n = 7;
				break;
			case '9':
				n = 8;
				break;
			case '0':
				n = 9;
				break;
			case 'C': case 'c':
				file_util_copy(layout_image_get_fd(lw), NULL, NULL, widget);
				break;
			case 'M': case 'm':
				file_util_move(layout_image_get_fd(lw), NULL, NULL, widget);
				break;
			case 'R': case 'r':
				file_util_rename(layout_image_get_fd(lw), NULL, widget);
				break;
			case 'D': case 'd':
				file_util_delete(layout_image_get_fd(lw), NULL, widget);
				break;
			case 'P': case 'p':
				info_window_new(layout_image_get_fd(lw), NULL);
				break;
			case 'Q': case 'q':
				exit_gqview();
				return FALSE;
				break;
			default:
				stop_signal = FALSE;
				break;
			}
		if (n != -1)
			{
			if (!editor_window_flag_set(n))
				{
				layout_image_full_screen_stop(lw);
				}
			start_editor_from_file(n, layout_image_get_fd(lw));
			}
		}
	else if (event->state & GDK_SHIFT_MASK)
		{
		stop_signal = TRUE;
		switch (event->keyval)
			{
			case 'R': case 'r':
				layout_image_alter(lw, ALTER_ROTATE_180);
				break;
			case 'M': case 'm':
				layout_image_alter(lw, ALTER_MIRROR);
				break;
			case 'F': case 'f':
				layout_image_alter(lw, ALTER_FLIP);
				break;
			case 'G': case 'g':
				layout_image_alter(lw, ALTER_DESATURATE);
				break;
			default:
				stop_signal = FALSE;
				break;
			}
		}
	else
		{
		stop_signal = TRUE;
		switch (event->keyval)
			{
			case '+': case '=': case GDK_KP_Add:
				layout_image_zoom_adjust(lw, get_zoom_increment());
				break;
			case '-': case GDK_KP_Subtract:
				layout_image_zoom_adjust(lw, -get_zoom_increment());
				break;
			case 'X': case 'x': case GDK_KP_Multiply:
				layout_image_zoom_set(lw, 0.0);
				break;
			case 'Z': case 'z': case GDK_KP_Divide:
			case '1':
				layout_image_zoom_set(lw, 1.0);
				break;
			case '2':
				layout_image_zoom_set(lw, 2.0);
				break;
			case '3':
				layout_image_zoom_set(lw, 3.0);
				break;
			case '4':
				layout_image_zoom_set(lw, 4.0);
				break;
			case '7':
				layout_image_zoom_set(lw, -4.0);
				break;
			case '8':
				layout_image_zoom_set(lw, -3.0);
				break;
			case '9':
				layout_image_zoom_set(lw, -2.0);
				break;
			case 'W': case 'w':
				layout_image_zoom_set_fill_geometry(lw, FALSE);
				break;
			case 'H': case 'h':
				layout_image_zoom_set_fill_geometry(lw, TRUE);
				break;
			case GDK_Page_Up: case GDK_KP_Page_Up:
			case GDK_BackSpace:
			case 'B': case 'b':
				layout_image_prev(lw);
				break;
			case GDK_Page_Down: case GDK_KP_Page_Down:
			case GDK_space:
			case 'N': case 'n':
				layout_image_next(lw);
				break;
			case GDK_Home: case GDK_KP_Home:
				layout_image_first(lw);
				break;
			case GDK_End: case GDK_KP_End:
				layout_image_last(lw);
				break;
			case ']':
				layout_image_alter(lw, ALTER_ROTATE_90);
				break;
			case '[':
				layout_image_alter(lw, ALTER_ROTATE_90_CC);
				break;
			case GDK_Delete: case GDK_KP_Delete:
				if (enable_delete_key)
					{
					file_util_delete(layout_image_get_fd(lw), NULL, widget);
					}
				break;
			case GDK_Escape:
				layout_image_full_screen_stop(lw);
				break;
			case 'R': case 'r':
				layout_refresh(lw);
				break;
			case 'S': case 's':
				layout_image_slideshow_toggle(lw);
				break;
			case 'P': case 'p':
				layout_image_slideshow_pause_toggle(lw);
				break;
			case 'F': case 'f':
			case 'V': case 'v':
			case GDK_F11:
				layout_image_full_screen_stop(lw);
				break;
			case GDK_Menu:
			case GDK_F10:
				layout_image_full_screen_menu_popup(lw);
				break;
			case 'I': case 'i':
				layout_image_overlay_toggle(lw);
				break;
			default:
				stop_signal = FALSE;
				break;
			}
		}

	return stop_signal;
}

#endif

static void layout_image_full_screen_stop_func(FullScreenData *fs, gpointer data)
{
	LayoutWindow *lw = data;

	/* restore image window */
	lw->image = fs->normal_imd;

	if (lw->slideshow)
		{
		lw->slideshow->imd = lw->image;
		}

	lw->full_screen = NULL;
}

void layout_image_full_screen_start(LayoutWindow *lw)
{
	if (!layout_valid(&lw)) return;

	if (lw->full_screen) return;

	lw->full_screen = fullscreen_start(lw->window, lw->image,
					   layout_image_full_screen_stop_func, lw);

	/* set to new image window */
	lw->image = lw->full_screen->imd;

	if (lw->slideshow)
		{
		lw->slideshow->imd = lw->image;
		}

	layout_image_set_buttons(lw);

	g_signal_connect(G_OBJECT(lw->full_screen->window), "key_press_event",
			 G_CALLBACK(layout_key_press_cb), lw);

	layout_actions_add_window(lw, lw->full_screen->window);
#if 0
	gtk_widget_set_sensitive(lw->window, FALSE);
	if (lw->tools) gtk_widget_set_sensitive(lw->tools, FALSE);
#endif

	if (image_osd_get(lw->full_screen->normal_imd, NULL, NULL))
		{
		image_osd_set(lw->image, TRUE, TRUE);
		image_osd_set(lw->full_screen->normal_imd, FALSE, FALSE);
		}
}

void layout_image_full_screen_stop(LayoutWindow *lw)
{
	if (!layout_valid(&lw)) return;
	if (!lw->full_screen) return;

	if (image_osd_get(lw->image, NULL, NULL))
		{
		image_osd_set(lw->full_screen->normal_imd, FALSE, TRUE);
		}
	fullscreen_stop(lw->full_screen);

#if 0
	gtk_widget_set_sensitive(lw->window, TRUE);
	if (lw->tools) gtk_widget_set_sensitive(lw->tools, TRUE);
#endif
}

void layout_image_full_screen_toggle(LayoutWindow *lw)
{
	if (!layout_valid(&lw)) return;
	if (lw->full_screen)
		{
		layout_image_full_screen_stop(lw);
		}
	else
		{
		layout_image_full_screen_start(lw);
		}
}

gint layout_image_full_screen_active(LayoutWindow *lw)
{
	if (!layout_valid(&lw)) return FALSE;

	return (lw->full_screen != NULL);
}

/*
 *----------------------------------------------------------------------------
 * slideshow
 *----------------------------------------------------------------------------
 */

static void layout_image_slideshow_next(LayoutWindow *lw)
{
	if (lw->slideshow) slideshow_next(lw->slideshow);
}

static void layout_image_slideshow_prev(LayoutWindow *lw)
{
	if (lw->slideshow) slideshow_prev(lw->slideshow);
}

static void layout_image_slideshow_stop_func(SlideShowData *ss, gpointer data)
{
	LayoutWindow *lw = data;

	lw->slideshow = NULL;
	layout_status_update_info(lw, NULL);
}

void layout_image_slideshow_start(LayoutWindow *lw)
{
	CollectionData *cd;
	CollectInfo *info;

	if (!layout_valid(&lw)) return;
	if (lw->slideshow) return;

	cd = image_get_collection(lw->image, &info);

	if (cd && info)
		{
		lw->slideshow = slideshow_start_from_collection(lw->image, cd,
				layout_image_slideshow_stop_func, lw, info);
		}
	else
		{
		lw->slideshow = slideshow_start(lw->image, lw,
				layout_list_get_index(lw, layout_image_get_path(lw)),
				layout_image_slideshow_stop_func, lw);
		}

	layout_status_update_info(lw, NULL);
}

/* note that slideshow will take ownership of the list, do not free it */
void layout_image_slideshow_start_from_list(LayoutWindow *lw, GList *list)
{
	if (!layout_valid(&lw)) return;

	if (lw->slideshow || !list)
		{
		filelist_free(list);
		return;
		}

	lw->slideshow = slideshow_start_from_filelist(lw->image, list,
						       layout_image_slideshow_stop_func, lw);

	layout_status_update_info(lw, NULL);
}

void layout_image_slideshow_stop(LayoutWindow *lw)
{
	if (!layout_valid(&lw)) return;

	if (!lw->slideshow) return;

	slideshow_free(lw->slideshow);
	/* the stop_func sets lw->slideshow to NULL for us */
}

void layout_image_slideshow_toggle(LayoutWindow *lw)
{
	if (!layout_valid(&lw)) return;

	if (lw->slideshow)
		{
		layout_image_slideshow_stop(lw);
		}
	else
		{
		layout_image_slideshow_start(lw);
		}
}

gint layout_image_slideshow_active(LayoutWindow *lw)
{
	if (!layout_valid(&lw)) return FALSE;

	return (lw->slideshow != NULL);
}

gint layout_image_slideshow_pause_toggle(LayoutWindow *lw)
{
	gint ret;

	if (!layout_valid(&lw)) return FALSE;

	ret = slideshow_pause_toggle(lw->slideshow);

	layout_status_update_info(lw, NULL);

	return ret;
}

gint layout_image_slideshow_paused(LayoutWindow *lw)
{
	if (!layout_valid(&lw)) return FALSE;

	return (slideshow_paused(lw->slideshow));
}

static gint layout_image_slideshow_continue_check(LayoutWindow *lw)
{
	if (!lw->slideshow) return FALSE;

	if (!slideshow_should_continue(lw->slideshow))
		{
		layout_image_slideshow_stop(lw);
		return FALSE;
		}

	return TRUE;
}

/*
 *----------------------------------------------------------------------------
 * pop-up menus
 *----------------------------------------------------------------------------
 */

static void li_pop_menu_zoom_in_cb(GtkWidget *widget, gpointer data)
{
	LayoutWindow *lw = data;

	layout_image_zoom_adjust(lw, get_zoom_increment());
}

static void li_pop_menu_zoom_out_cb(GtkWidget *widget, gpointer data)
{
	LayoutWindow *lw = data;
	layout_image_zoom_adjust(lw, -get_zoom_increment());
}

static void li_pop_menu_zoom_1_1_cb(GtkWidget *widget, gpointer data)
{
	LayoutWindow *lw = data;

	layout_image_zoom_set(lw, 1.0);
}

static void li_pop_menu_zoom_fit_cb(GtkWidget *widget, gpointer data)
{
	LayoutWindow *lw = data;

	layout_image_zoom_set(lw, 0.0);
}

static void li_pop_menu_edit_cb(GtkWidget *widget, gpointer data)
{
	LayoutWindow *lw;
	gint n;

	lw = submenu_item_get_data(widget);
	n = GPOINTER_TO_INT(data);

	if (!editor_window_flag_set(n))
		{
		layout_image_full_screen_stop(lw);
		}
	start_editor_from_file(n, layout_image_get_fd(lw));
}

static void li_pop_menu_wallpaper_cb(GtkWidget *widget, gpointer data)
{
	LayoutWindow *lw = data;

	layout_image_to_root(lw);
}

static void li_pop_menu_alter_cb(GtkWidget *widget, gpointer data)
{
	LayoutWindow *lw = data;
	AlterType type;

	lw = submenu_item_get_data(widget);
	type = (AlterType)GPOINTER_TO_INT(data);

	image_alter(lw->image, type);
}

static void li_pop_menu_info_cb(GtkWidget *widget, gpointer data)
{
	LayoutWindow *lw = data;

	info_window_new(layout_image_get_fd(lw), NULL);
}

static void li_pop_menu_new_cb(GtkWidget *widget, gpointer data)
{
	LayoutWindow *lw = data;

	view_window_new(layout_image_get_fd(lw));
}

static GtkWidget *li_pop_menu_click_parent(GtkWidget *widget, LayoutWindow *lw)
{
	GtkWidget *menu;
	GtkWidget *parent;

	menu = gtk_widget_get_toplevel(widget);
	if (!menu) return NULL;

	parent = g_object_get_data(G_OBJECT(menu), "click_parent");

	if (!parent && lw->full_screen)
		{
		parent = lw->full_screen->imd->widget;
		}

	return parent;
}

static void li_pop_menu_copy_cb(GtkWidget *widget, gpointer data)
{
	LayoutWindow *lw = data;

	file_util_copy(layout_image_get_fd(lw), NULL, NULL,
		       li_pop_menu_click_parent(widget, lw));
}

static void li_pop_menu_move_cb(GtkWidget *widget, gpointer data)
{
	LayoutWindow *lw = data;

	file_util_move(layout_image_get_fd(lw), NULL, NULL,
		       li_pop_menu_click_parent(widget, lw));
}

static void li_pop_menu_rename_cb(GtkWidget *widget, gpointer data)
{
	LayoutWindow *lw = data;

	file_util_rename(layout_image_get_fd(lw), NULL,
			 li_pop_menu_click_parent(widget, lw));
}

static void li_pop_menu_delete_cb(GtkWidget *widget, gpointer data)
{
	LayoutWindow *lw = data;

	file_util_delete(layout_image_get_fd(lw), NULL,
			 li_pop_menu_click_parent(widget, lw));
}

static void li_pop_menu_slide_start_cb(GtkWidget *widget, gpointer data)
{
	LayoutWindow *lw = data;

	layout_image_slideshow_start(lw);
}

static void li_pop_menu_slide_stop_cb(GtkWidget *widget, gpointer data)
{
	LayoutWindow *lw = data;

	layout_image_slideshow_stop(lw);
}

static void li_pop_menu_slide_pause_cb(GtkWidget *widget, gpointer data)
{
	LayoutWindow *lw = data;

	layout_image_slideshow_pause_toggle(lw);
}

static void li_pop_menu_full_screen_cb(GtkWidget *widget, gpointer data)
{
	LayoutWindow *lw = data;

	layout_image_full_screen_toggle(lw);
}

static void li_pop_menu_hide_cb(GtkWidget *widget, gpointer data)
{
	LayoutWindow *lw = data;

	layout_tools_hide_toggle(lw);
}

static GtkWidget *layout_image_pop_menu(LayoutWindow *lw)
{
	GtkWidget *menu;
	GtkWidget *item;
	GtkWidget *submenu;
	const gchar *path;
	gint fullscreen;

	path = layout_image_get_path(lw);
	fullscreen = layout_image_full_screen_active(lw);

	menu = popup_menu_short_lived();

	menu_item_add_stock(menu, _("Zoom _in"), GTK_STOCK_ZOOM_IN, G_CALLBACK(li_pop_menu_zoom_in_cb), lw);
	menu_item_add_stock(menu, _("Zoom _out"), GTK_STOCK_ZOOM_OUT, G_CALLBACK(li_pop_menu_zoom_out_cb), lw);
	menu_item_add_stock(menu, _("Zoom _1:1"), GTK_STOCK_ZOOM_100, G_CALLBACK(li_pop_menu_zoom_1_1_cb), lw);
	menu_item_add_stock(menu, _("Fit image to _window"), GTK_STOCK_ZOOM_FIT, G_CALLBACK(li_pop_menu_zoom_fit_cb), lw);
	menu_item_add_divider(menu);

	submenu = submenu_add_edit(menu, &item, G_CALLBACK(li_pop_menu_edit_cb), lw);
	if (!path) gtk_widget_set_sensitive(item, FALSE);
	menu_item_add_divider(submenu);
	menu_item_add(submenu, _("Set as _wallpaper"), G_CALLBACK(li_pop_menu_wallpaper_cb), lw);

	item = submenu_add_alter(menu, G_CALLBACK(li_pop_menu_alter_cb), lw);

	item = menu_item_add_stock(menu, _("_Properties"), GTK_STOCK_PROPERTIES, G_CALLBACK(li_pop_menu_info_cb), lw);
	if (!path) gtk_widget_set_sensitive(item, FALSE);

	item = menu_item_add_stock(menu, _("View in _new window"), GTK_STOCK_NEW, G_CALLBACK(li_pop_menu_new_cb), lw);
	if (!path || fullscreen) gtk_widget_set_sensitive(item, FALSE);

	menu_item_add_divider(menu);

	item = menu_item_add_stock(menu, _("_Copy..."), GTK_STOCK_COPY, G_CALLBACK(li_pop_menu_copy_cb), lw);
	if (!path) gtk_widget_set_sensitive(item, FALSE);
	item = menu_item_add(menu, _("_Move..."), G_CALLBACK(li_pop_menu_move_cb), lw);
	if (!path) gtk_widget_set_sensitive(item, FALSE);
	item = menu_item_add(menu, _("_Rename..."), G_CALLBACK(li_pop_menu_rename_cb), lw);
	if (!path) gtk_widget_set_sensitive(item, FALSE);
	item = menu_item_add_stock(menu, _("_Delete..."), GTK_STOCK_DELETE, G_CALLBACK(li_pop_menu_delete_cb), lw);
	if (!path) gtk_widget_set_sensitive(item, FALSE);

	menu_item_add_divider(menu);

	if (layout_image_slideshow_active(lw))
		{
		menu_item_add(menu, _("_Stop slideshow"), G_CALLBACK(li_pop_menu_slide_stop_cb), lw);
		if (layout_image_slideshow_paused(lw))
			{
			item = menu_item_add(menu, _("Continue slides_how"),
					     G_CALLBACK(li_pop_menu_slide_pause_cb), lw);
			}
		else
			{
			item = menu_item_add(menu, _("Pause slides_how"),
					     G_CALLBACK(li_pop_menu_slide_pause_cb), lw);
			}
		}
	else
                {
		menu_item_add(menu, _("_Start slideshow"), G_CALLBACK(li_pop_menu_slide_start_cb), lw);
		item = menu_item_add(menu, _("Pause slides_how"), G_CALLBACK(li_pop_menu_slide_pause_cb), lw);
		gtk_widget_set_sensitive(item, FALSE);
		}

	if (!fullscreen)
		{
		menu_item_add(menu, _("_Full screen"), G_CALLBACK(li_pop_menu_full_screen_cb), lw);
		}
	else
		{
		menu_item_add(menu, _("Exit _full screen"), G_CALLBACK(li_pop_menu_full_screen_cb), lw);
		}

	menu_item_add_divider(menu);

	item = menu_item_add_check(menu, _("Hide file _list"), lw->tools_hidden,
				   G_CALLBACK(li_pop_menu_hide_cb), lw);
	if (fullscreen) gtk_widget_set_sensitive(item, FALSE);

	return menu;
}

static void layout_image_menu_pos_cb(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer data)
{
	LayoutWindow *lw = data;

	gdk_window_get_origin(lw->image->pr->window, x, y);
	popup_menu_position_clamp(menu, x, y, 0);
}

void layout_image_menu_popup(LayoutWindow *lw)
{
	GtkWidget *menu;

	menu = layout_image_pop_menu(lw);
	gtk_menu_popup(GTK_MENU(menu), NULL, NULL, layout_image_menu_pos_cb, lw, 0, GDK_CURRENT_TIME);
}

/*
 *----------------------------------------------------------------------------
 * dnd
 *----------------------------------------------------------------------------
 */

static void layout_image_dnd_receive(GtkWidget *widget, GdkDragContext *context,
				     gint x, gint y,
				     GtkSelectionData *selection_data, guint info,
				     guint time, gpointer data)
{
	LayoutWindow *lw = data;
	gint i;
	
	
	for (i=0; i < MAX_SPLIT_IMAGES; i++) 
		{
		if (lw->split_images[i] && lw->split_images[i]->pr == widget)
			break;
		}
	if (i < MAX_SPLIT_IMAGES)
		{
		printf("dnd image activate %d\n", i);
		layout_image_activate(lw, i);
		}


	if (info == TARGET_URI_LIST || info == TARGET_APP_COLLECTION_MEMBER)
		{
		CollectionData *source;
		GList *list;
		GList *info_list;

		if (info == TARGET_URI_LIST)
			{
			list = uri_filelist_from_text((gchar *)selection_data->data, TRUE);
			source = NULL;
			info_list = NULL;
			}
		else
			{
			source = collection_from_dnd_data((gchar *)selection_data->data, &list, &info_list);
			}

		if (list)
			{
			FileData *fd = list->data;

			if (isfile(fd->path))
				{
				gchar *base;
				gint row;

				base = remove_level_from_path(fd->path);
				if (strcmp(base, layout_get_path(lw)) != 0)
					{
					layout_set_path(lw, base);
					}
				g_free(base);

				row = layout_list_get_index(lw, fd->path);
				if (source && info_list)
					{
					layout_image_set_collection(lw, source, info_list->data);
					}
				else if (row == -1)
					{
					layout_image_set_fd(lw, fd);
					}
				else
					{
					layout_image_set_index(lw, row);
					}
				}
			else if (isdir(fd->path))
				{
				layout_set_path(lw, fd->path);
				layout_image_set_fd(lw, NULL);
				}
			}

		filelist_free(list);
		g_list_free(info_list);
		}
}

static void layout_image_dnd_get(GtkWidget *widget, GdkDragContext *context,
				 GtkSelectionData *selection_data, guint info,
				 guint time, gpointer data)
{
	LayoutWindow *lw = data;
	FileData *fd;
	gint i;
	
	
	for (i=0; i < MAX_SPLIT_IMAGES; i++) 
		{
		if (lw->split_images[i] && lw->split_images[i]->pr == widget)
			break;
		}
	if (i < MAX_SPLIT_IMAGES)
		{
		printf("dnd get from %d\n", i);
		fd = image_get_fd(lw->split_images[i]);
		}
	else
		fd = layout_image_get_fd(lw);

	if (fd)
		{
		gchar *text = NULL;
		gint len;
		gint plain_text;
		GList *list;

		switch (info)
			{
			case TARGET_URI_LIST:
				plain_text = FALSE;
				break;
			case TARGET_TEXT_PLAIN:
			default:
				plain_text = TRUE;
				break;
			}
		list = g_list_append(NULL, fd);
		text = uri_text_from_filelist(list, &len, plain_text);
		g_list_free(list);
		if (text)
			{
			gtk_selection_data_set (selection_data, selection_data->target,
						8, (guchar *)text, len);
			g_free(text);
			}
		}
	else
		{
		gtk_selection_data_set (selection_data, selection_data->target,
					8, NULL, 0);
		}
}

static void layout_image_dnd_end(GtkWidget *widget, GdkDragContext *context, gpointer data)
{
	LayoutWindow *lw = data;
	if (context->action == GDK_ACTION_MOVE)
		{
		const gchar *path;
		gint row;

		path = layout_image_get_path(lw);
		row = layout_list_get_index(lw, path);
		if (row < 0) return;

		if (!isfile(path))
			{
			if (row < layout_list_count(lw, NULL) - 1)
				{
				layout_image_next(lw);
				}
			else
				{
				layout_image_prev(lw);
				}
			}
		layout_refresh(lw);
		}
}

static void layout_image_dnd_init(LayoutWindow *lw, gint i)
{
	ImageWindow *imd = lw->split_images[i];

	gtk_drag_source_set(imd->pr, GDK_BUTTON2_MASK,
			    dnd_file_drag_types, dnd_file_drag_types_count,
			    GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
	g_signal_connect(G_OBJECT(imd->pr), "drag_data_get",
			 G_CALLBACK(layout_image_dnd_get), lw);
	g_signal_connect(G_OBJECT(imd->pr), "drag_end",
			 G_CALLBACK(layout_image_dnd_end), lw);

	gtk_drag_dest_set(imd->pr,
			  GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
			  dnd_file_drop_types, dnd_file_drop_types_count,
                          GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
	g_signal_connect(G_OBJECT(imd->pr), "drag_data_received",
			 G_CALLBACK(layout_image_dnd_receive), lw);
}


/*
 *----------------------------------------------------------------------------
 * misc
 *----------------------------------------------------------------------------
 */

void layout_image_to_root(LayoutWindow *lw)
{
	image_to_root_window(lw->image, (image_zoom_get(lw->image) == 0));
}

/*
 *----------------------------------------------------------------------------
 * manipulation + accessors
 *----------------------------------------------------------------------------
 */

void layout_image_scroll(LayoutWindow *lw, gint x, gint y)
{
	if (!layout_valid(&lw)) return;

	image_scroll(lw->image, x, y);
}

void layout_image_zoom_adjust(LayoutWindow *lw, gdouble increment)
{
	gint i;
	if (!layout_valid(&lw)) return;

	image_zoom_adjust(lw->image, increment);

	for (i=0; i < MAX_SPLIT_IMAGES; i++)
		{
		if (lw->split_images[i] && lw->split_images[i] != lw->image && lw->connect_zoom) 
			image_zoom_adjust(lw->split_images[i], increment); ;
		}
}

void layout_image_zoom_set(LayoutWindow *lw, gdouble zoom)
{
	gint i;
	if (!layout_valid(&lw)) return;

	image_zoom_set(lw->image, zoom);

	for (i=0; i < MAX_SPLIT_IMAGES; i++)
		{
		if (lw->split_images[i] && lw->split_images[i] != lw->image && lw->connect_zoom) 
			image_zoom_set(lw->split_images[i], zoom);
		}
}

void layout_image_zoom_set_fill_geometry(LayoutWindow *lw, gint vertical)
{
	if (!layout_valid(&lw)) return;

	image_zoom_set_fill_geometry(lw->image, vertical);
}

void layout_image_alter(LayoutWindow *lw, AlterType type)
{
	if (!layout_valid(&lw)) return;

	image_alter(lw->image, type);
}

const gchar *layout_image_get_path(LayoutWindow *lw)
{
	if (!layout_valid(&lw)) return NULL;

	return image_get_path(lw->image);
}

const gchar *layout_image_get_name(LayoutWindow *lw)
{
	if (!layout_valid(&lw)) return NULL;

	return image_get_name(lw->image);
}

FileData *layout_image_get_fd(LayoutWindow *lw)
{
	if (!layout_valid(&lw)) return NULL;

	return image_get_fd(lw->image);
}

CollectionData *layout_image_get_collection(LayoutWindow *lw, CollectInfo **info)
{
	if (!layout_valid(&lw)) return NULL;

	return image_get_collection(lw->image, info);
}

gint layout_image_get_index(LayoutWindow *lw)
{
	return layout_list_get_index(lw, image_get_path(lw->image));
}

/*
 *----------------------------------------------------------------------------
 * image changers
 *----------------------------------------------------------------------------
 */

void layout_image_set_fd(LayoutWindow *lw, FileData *fd)
{
	gdouble sx, sy;
	if (!layout_valid(&lw)) return;

	image_get_scroll_center(lw->image, &sx, &sy);

	image_change_fd(lw->image, fd, image_zoom_get_default(lw->image, zoom_mode));

	image_set_scroll_center(lw->image, sx, sy);

	layout_list_sync_fd(lw, fd);
	layout_image_slideshow_continue_check(lw);
	layout_bars_new_image(lw);
}

void layout_image_set_with_ahead(LayoutWindow *lw, FileData *fd, FileData *read_ahead_fd)
{
	if (!layout_valid(&lw)) return;

/*
This should be handled at the caller: in vflist_select_image
	if (path)
		{
		const gchar *old_path;

		old_path = layout_image_get_path(lw);
		if (old_path && strcmp(path, old_path) == 0) return;
		}
*/
	layout_image_set_fd(lw, fd);
	if (enable_read_ahead) image_prebuffer_set(lw->image, read_ahead_fd);
}

void layout_image_set_index(LayoutWindow *lw, gint index)
{
	FileData *fd;
	FileData *read_ahead_fd;
	gint old;

	if (!layout_valid(&lw)) return;

	old = layout_list_get_index(lw, layout_image_get_path(lw));
	fd = layout_list_get_fd(lw, index);

	if (old > index)
		{
		read_ahead_fd = layout_list_get_fd(lw, index - 1);
		}
	else
		{
		read_ahead_fd = layout_list_get_fd(lw, index + 1);
		}

 	if (layout_selection_count(lw, 0) > 1)
		{
 		GList *x = layout_selection_list_by_index(lw);
 	  	GList *y;
 	  	GList *last;

 		for (last = y = x; y; y = y->next)
 			last = y;
		for (y = x; y && ((gint)y->data) != index; y = y->next)
			;

		if (y)
			{
			gint newindex;

			if ((index > old && (index != (gint) last->data || old != (gint) x->data))
 	        	    || (old == (gint) last->data && index == (gint) x->data))
			    	{
				if (y->next)
 					newindex = (gint) y->next->data;
				else
 					newindex = (gint) x->data;
				}
			else
				{
				if (y->prev)
					newindex = (gint) y->prev->data;
				else
					newindex = (gint) last->data;
 	    			}

			read_ahead_fd = layout_list_get_fd(lw, newindex);
			}
			
		while (x)
			x = g_list_remove(x, x->data);
		}

	layout_image_set_with_ahead(lw, fd, read_ahead_fd);
}

static void layout_image_set_collection_real(LayoutWindow *lw, CollectionData *cd, CollectInfo *info, gint forward)
{
	if (!layout_valid(&lw)) return;

	image_change_from_collection(lw->image, cd, info, image_zoom_get_default(lw->image, zoom_mode));
	if (enable_read_ahead)
		{
		CollectInfo *r_info;
		if (forward)
			{
			r_info = collection_next_by_info(cd, info);
			if (!r_info) r_info = collection_prev_by_info(cd, info);
			}
		else
			{
			r_info = collection_prev_by_info(cd, info);
			if (!r_info) r_info = collection_next_by_info(cd, info);
			}
		if (r_info) image_prebuffer_set(lw->image, r_info->fd);
		}

	layout_image_slideshow_continue_check(lw);
	layout_bars_new_image(lw);
}

void layout_image_set_collection(LayoutWindow *lw, CollectionData *cd, CollectInfo *info)
{
	layout_image_set_collection_real(lw, cd, info, TRUE);
	layout_list_sync_fd(lw, layout_image_get_fd(lw));
}

void layout_image_refresh(LayoutWindow *lw)
{
	if (!layout_valid(&lw)) return;

	image_reload(lw->image);
}

void layout_image_color_profile_set(LayoutWindow *lw,
				    gint input_type, gint screen_type,
				    gint use_image)
{
	if (!layout_valid(&lw)) return;

	image_color_profile_set(lw->image, input_type, screen_type, use_image);
}

gint layout_image_color_profile_get(LayoutWindow *lw,
				    gint *input_type, gint *screen_type,
				    gint *use_image)
{
	if (!layout_valid(&lw)) return FALSE;

	return image_color_profile_get(lw->image, input_type, screen_type, use_image);
}

void layout_image_color_profile_set_use(LayoutWindow *lw, gint enable)
{
	if (!layout_valid(&lw)) return;

	image_color_profile_set_use(lw->image, enable);

	if (lw->info_color)
		{
#ifndef HAVE_LCMS
		enable = FALSE;
#endif
		gtk_widget_set_sensitive(GTK_BIN(lw->info_color)->child, enable);
		}
}

gint layout_image_color_profile_get_use(LayoutWindow *lw)
{
	if (!layout_valid(&lw)) return FALSE;

	return image_color_profile_get_use(lw->image);
}

/*
 *----------------------------------------------------------------------------
 * list walkers
 *----------------------------------------------------------------------------
 */

void layout_image_next(LayoutWindow *lw)
{
	gint current;
	CollectionData *cd;
	CollectInfo *info;

	if (!layout_valid(&lw)) return;

	if (layout_image_slideshow_active(lw))
		{
		layout_image_slideshow_next(lw);
		return;
		}

	if (layout_selection_count(lw, 0) > 1)
		{
		GList *x = layout_selection_list_by_index(lw);
		gint old = layout_list_get_index(lw, layout_image_get_path(lw));
		GList *y;

		for (y = x; y && ((gint) y->data) != old; y = y->next)
			;
		if (y)
			{
			if (y->next) 
		    		layout_image_set_index(lw, (gint) y->next->data);
		  	else
		    		layout_image_set_index(lw, (gint) x->data);
			}
		while (x)
			x = g_list_remove(x, x->data);
		if (y) /* not dereferenced */
			return;
		}

	cd = image_get_collection(lw->image, &info);

	if (cd && info)
		{
		info = collection_next_by_info(cd, info);
		if (info)
			{
			layout_image_set_collection_real(lw, cd, info, TRUE);
			}
		else
			{
			image_osd_icon(lw->image, IMAGE_OSD_LAST, -1);
			}
		return;
		}

	current = layout_image_get_index(lw);

	if (current >= 0)
		{
		if (current < layout_list_count(lw, NULL) - 1)
			{
			layout_image_set_index(lw, current + 1);
			}
		else
			{
			image_osd_icon(lw->image, IMAGE_OSD_LAST, -1);
			}
		}
	else
		{
		layout_image_set_index(lw, 0);
		}
}

void layout_image_prev(LayoutWindow *lw)
{
	gint current;
	CollectionData *cd;
	CollectInfo *info;

	if (!layout_valid(&lw)) return;

	if (layout_image_slideshow_active(lw))
		{
		layout_image_slideshow_prev(lw);
		return;
		}

	if (layout_selection_count(lw, 0) > 1)
		{
		GList *x = layout_selection_list_by_index(lw);
		gint old = layout_list_get_index(lw, layout_image_get_path(lw));
		GList *y;
		GList *last;

		for (last = y = x; y; y = y->next)
			last = y;
		for (y = x; y && ((gint) y->data) != old; y = y->next)
			;
		if (y)
			{
		  	if (y->prev)
				layout_image_set_index(lw, (gint) y->prev->data);
			else
				layout_image_set_index(lw, (gint) last->data);
			}
		while (x)
			x = g_list_remove(x, x->data);
		if (y) /* not dereferenced */
			return;
		}

	cd = image_get_collection(lw->image, &info);

	if (cd && info)
		{
		info = collection_prev_by_info(cd, info);
		if (info)
			{
			layout_image_set_collection_real(lw, cd, info, FALSE);
			}
		else
			{
			image_osd_icon(lw->image, IMAGE_OSD_FIRST, -1);
			}
		return;
		}

	current = layout_image_get_index(lw);

	if (current >= 0)
		{
		if (current > 0)
			{
			layout_image_set_index(lw, current - 1);
			}
		else
			{
			image_osd_icon(lw->image, IMAGE_OSD_FIRST, -1);
			}
		}
	else
		{
		layout_image_set_index(lw, layout_list_count(lw, NULL) - 1);
		}
}

void layout_image_first(LayoutWindow *lw)
{
	gint current;
	CollectionData *cd;
	CollectInfo *info;

	if (!layout_valid(&lw)) return;

	cd = image_get_collection(lw->image, &info);

	if (cd && info)
		{
		CollectInfo *new;
		new = collection_get_first(cd);
		if (new != info) layout_image_set_collection_real(lw, cd, new, TRUE);
		return;
		}

	current = layout_image_get_index(lw);
	if (current != 0 && layout_list_count(lw, NULL) > 0)
		{
		layout_image_set_index(lw, 0);
		}
}

void layout_image_last(LayoutWindow *lw)
{
	gint current;
	gint count;
	CollectionData *cd;
	CollectInfo *info;

	if (!layout_valid(&lw)) return;

	cd = image_get_collection(lw->image, &info);

	if (cd && info)
		{
		CollectInfo *new;
		new = collection_get_last(cd);
		if (new != info) layout_image_set_collection_real(lw, cd, new, FALSE);
		return;
		}

	current = layout_image_get_index(lw);
	count = layout_list_count(lw, NULL);
	if (current != count - 1 && count > 0)
		{
		layout_image_set_index(lw, count - 1);
		}
}

/*
 *----------------------------------------------------------------------------
 * mouse callbacks
 *----------------------------------------------------------------------------
 */

static gint image_idx(LayoutWindow *lw, ImageWindow *imd)
{
	gint i;
	
	for (i=0; i < MAX_SPLIT_IMAGES; i++) 
		{
		if (lw->split_images[i] == imd)
			break;
		}
	if (i < MAX_SPLIT_IMAGES)
		{
		return i;
		}
	return -1;
}


static void layout_image_button_cb(ImageWindow *imd, gint button, guint32 time,
				   gdouble x, gdouble y, guint state, gpointer data)
{
	LayoutWindow *lw = data;
	GtkWidget *menu;

	switch (button)
		{
		case 1:
			layout_image_next(lw);
			break;
		case 2:
			layout_image_prev(lw);
			break;
		case 3:
			menu = layout_image_pop_menu(lw);
			if (imd == lw->image)
				{
				g_object_set_data(G_OBJECT(menu), "click_parent", imd->widget);
				}
			gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, time);
			break;
		default:
			break;
		}
}

static void layout_image_scroll_cb(ImageWindow *imd, GdkScrollDirection direction, guint32 time,
				   gdouble x, gdouble y, guint state, gpointer data)
{
	LayoutWindow *lw = data;

	gint i = image_idx(lw, imd);
	
	if (i != -1)
		{
		printf("image activate scroll %d\n", i);
		layout_image_activate(lw, i);
		}


	if (state & GDK_CONTROL_MASK)
		{
		switch (direction)
			{
			case GDK_SCROLL_UP:
				image_zoom_adjust_at_point(imd, get_zoom_increment(), x, y);
				break;
			case GDK_SCROLL_DOWN:
				image_zoom_adjust_at_point(imd, -get_zoom_increment(), x, y);
				break;
			default:
				break;
			}
		}
	else if ( (state & GDK_SHIFT_MASK) != (mousewheel_scrolls))
		{
		switch (direction)
			{
			case GDK_SCROLL_UP:
				image_scroll(imd, 0, -MOUSEWHEEL_SCROLL_SIZE);
				break;
			case GDK_SCROLL_DOWN:
				image_scroll(imd, 0, MOUSEWHEEL_SCROLL_SIZE);
				break;
			case GDK_SCROLL_LEFT:
				image_scroll(imd, -MOUSEWHEEL_SCROLL_SIZE, 0);
				break;
			case GDK_SCROLL_RIGHT:
				image_scroll(imd, MOUSEWHEEL_SCROLL_SIZE, 0);
				break;
			default:
				break;
			}
		}
	else
		{
		switch (direction)
			{
			case GDK_SCROLL_UP:
				layout_image_prev(lw);
				break;
			case GDK_SCROLL_DOWN:
				layout_image_next(lw);
				break;
			default:
				break;
			}
		}
}

static void layout_image_drag_cb(ImageWindow *imd, gint button, guint32 time,
				 gdouble x, gdouble y, guint state, gdouble dx, gdouble dy, gpointer data)
{
	gint i;
	LayoutWindow *lw = data;


	for (i=0; i < MAX_SPLIT_IMAGES; i++)
		{
		if (lw->split_images[i] && lw->split_images[i] != imd)
			if (lw->connect_scroll) 
				{
				gdouble sx, sy;
				if (state & GDK_CONTROL_MASK)
					{
					image_get_scroll_center(imd, &sx, &sy);
					}
				else 
					{
					image_get_scroll_center(lw->split_images[i], &sx, &sy);
					sx += dx;
					sy += dy;
					}
				image_set_scroll_center(lw->split_images[i], sx, sy);
				}
		}
}

static void layout_image_button_inactive_cb(ImageWindow *imd, gint button, guint32 time,
				   gdouble x, gdouble y, guint state, gpointer data)
{
	LayoutWindow *lw = data;
	GtkWidget *menu;
	gint i = image_idx(lw, imd);
	
	if (i != -1)
		{
		layout_image_activate(lw, i);
		}

	switch (button)
		{
		case 3:
			menu = layout_image_pop_menu(lw);
			if (imd == lw->image)
				{
				g_object_set_data(G_OBJECT(menu), "click_parent", imd->widget);
				}
			gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, time);
			break;
		default:
			break;
		}

}

static void layout_image_drag_inactive_cb(ImageWindow *imd, gint button, guint32 time,
				 gdouble x, gdouble y, guint state, gdouble dx, gdouble dy, gpointer data)
{
	LayoutWindow *lw = data;

	gint i = image_idx(lw, imd);
	
	if (i != -1)
		{
		layout_image_activate(lw, i);
		}


	/* continue as with active image */
	layout_image_drag_cb(imd, button, time, x, y, state, dx, dy, data);
}


static void layout_image_set_buttons(LayoutWindow *lw)
{
	image_set_button_func(lw->image, layout_image_button_cb, lw);
	image_set_scroll_func(lw->image, layout_image_scroll_cb, lw);
}

static void layout_image_set_buttons_inactive(LayoutWindow *lw, gint i)
{
	image_set_button_func(lw->split_images[i], layout_image_button_inactive_cb, lw);
	image_set_scroll_func(lw->split_images[i], layout_image_scroll_cb, lw);
}

/*
 *----------------------------------------------------------------------------
 * setup
 *----------------------------------------------------------------------------
 */

static void layout_image_update_cb(ImageWindow *imd, gpointer data)
{
	LayoutWindow *lw = data;
	layout_status_update_image(lw);
}

GtkWidget *layout_image_new(LayoutWindow *lw, gint i)
{
	if (!lw->split_images[i]) 
		{
		lw->split_images[i] = image_new(TRUE);

		gtk_widget_ref(lw->split_images[i]->widget);

		image_background_set_color(lw->split_images[i], user_specified_window_background ? &window_background_color : NULL);

		image_auto_refresh(lw->split_images[i], 0);

		layout_image_dnd_init(lw, i);
		image_color_profile_set(lw->split_images[i],
					color_profile_input_type, color_profile_screen_type,
					color_profile_use_image);
		image_color_profile_set_use(lw->split_images[i], color_profile_enabled);
		}

	return lw->split_images[i]->widget;
}

void layout_image_deactivate(LayoutWindow *lw, gint i)
{

	if (!lw->split_images[i]) return;
	image_set_update_func(lw->split_images[i], NULL, NULL);
	layout_image_set_buttons_inactive(lw, i);
	image_set_drag_func(lw->split_images[i], layout_image_drag_inactive_cb, lw);

	image_attach_window(lw->split_images[i], NULL, NULL, NULL, FALSE);
	image_select(lw->split_images[i], FALSE);
}


void layout_image_activate(LayoutWindow *lw, gint i)
{
	FileData *fd;

	gchar *base;
	gint row;
	gint j;
	
	if (!lw->split_images[i]) return;

	/* deactivate currently active */
	if (lw->active_split_image != i)
		layout_image_deactivate(lw, lw->active_split_image);

	lw->image = lw->split_images[i];
	lw->active_split_image = i;
	
	image_set_update_func(lw->image, layout_image_update_cb, lw);
	layout_image_set_buttons(lw);
	image_set_drag_func(lw->image, layout_image_drag_cb, lw);

	image_attach_window(lw->image, lw->window, NULL, "Geeqie", FALSE);

	/* do not hilight selected image in SPLIT_NONE */
	/* maybe the image should be selected always and hilight should be controled by
	   another image option */
	if (lw->split_mode != SPLIT_NONE)
		image_select(lw->split_images[i], TRUE);
	else
		image_select(lw->split_images[i], FALSE);

	fd = image_get_fd(lw->image);

        if (fd)
		{
//		layout_list_sync_path(lw, path);
		layout_set_path(lw, fd->path);
		}
}


GtkWidget *layout_image_setup_split_none(LayoutWindow *lw)
{
	gint i;
	
	lw->split_mode = SPLIT_NONE;

	if (!lw->split_images[0])
		{
		layout_image_new(lw, 0);
		image_set_frame(lw->split_images[0], (!lw->tools_float && !lw->tools_hidden));
		image_set_selectable(lw->split_images[0], 0);
		layout_image_activate(lw, 0);
		}
	else
		{
		image_set_frame(lw->split_images[0], (!lw->tools_float && !lw->tools_hidden));
		image_set_selectable(lw->split_images[0], 0);
		}
		
	for (i=1; i < MAX_SPLIT_IMAGES; i++)
		{
		if (lw->split_images[i])
			{
			gtk_widget_unref(lw->split_images[i]->widget);
			lw->split_images[i] = NULL;
			}
		}


	layout_image_activate(lw, 0);
	
	lw->split_image_widget = lw->split_images[0]->widget;
			
	return lw->split_image_widget;
}

GtkWidget *layout_image_setup_split_hv(LayoutWindow *lw, gboolean horizontal)
{
	GtkWidget *paned;
	gint i;

	lw->split_mode = horizontal ? SPLIT_HOR : SPLIT_VERT;
	
	if (!lw->split_images[0])
		{
		layout_image_new(lw, 0);
		}
	image_set_frame(lw->split_images[0], 1);
	image_set_selectable(lw->split_images[0], 1);

	if (!lw->split_images[1])
		{
		layout_image_new(lw, 1);
		image_set_frame(lw->split_images[1], 1);
		image_set_selectable(lw->split_images[1], 1);
		if (lw->image)
			{
			gdouble sx, sy;
			image_change_fd(lw->split_images[1], 
				image_get_fd(lw->image), image_zoom_get(lw->image));
			image_get_scroll_center(lw->image, &sx, &sy);
			image_set_scroll_center(lw->split_images[1], sx, sy);
			}
		layout_image_deactivate(lw, 1);
		layout_image_activate(lw, 0);
		}
	else
		{
		image_set_frame(lw->split_images[1], 1);
		image_set_selectable(lw->split_images[1], 1);
		}

	
	for (i=2; i < MAX_SPLIT_IMAGES; i++)
		{
		if (lw->split_images[i])
			{
			gtk_widget_unref(lw->split_images[i]->widget);
			lw->split_images[i] = NULL;
			}
		}

        if (!lw->image || lw->active_split_image < 0 || lw->active_split_image > 1)
		{
		layout_image_activate(lw, 0);
		}

	/* horizontal split means vpaned and vice versa */
	if (horizontal)
		paned = gtk_vpaned_new ();
	else
		paned = gtk_hpaned_new ();

	gtk_paned_pack1 (GTK_PANED (paned), lw->split_images[0]->widget, TRUE, TRUE);
	gtk_paned_pack2 (GTK_PANED (paned), lw->split_images[1]->widget, TRUE, TRUE);
	
	gtk_widget_show (lw->split_images[0]->widget);
	gtk_widget_show (lw->split_images[1]->widget);
	

	lw->split_image_widget = paned;
			
	return lw->split_image_widget;

}

GtkWidget *layout_image_setup_split_quad(LayoutWindow *lw)
{
	GtkWidget *hpaned;
	GtkWidget *vpaned1;
	GtkWidget *vpaned2;
	gint i;
	
	lw->split_mode = SPLIT_QUAD;

	if (!lw->split_images[0])
		{
		layout_image_new(lw, 0);
		}

	image_set_frame(lw->split_images[0], 1);
	image_set_selectable(lw->split_images[0], 1);

	if (!lw->split_images[1])
		{
		layout_image_activate(lw, 0);
		}

	for (i=1; i < 4; i++)
		if (!lw->split_images[i])
			{
			layout_image_new(lw, i);
			image_set_frame(lw->split_images[i], 1);
			image_set_selectable(lw->split_images[i], 1);
			if (lw->image)
				{
				gdouble sx, sy;
				image_change_fd(lw->split_images[i], 
					image_get_fd(lw->image), image_zoom_get(lw->image));
				image_get_scroll_center(lw->image, &sx, &sy);
				image_set_scroll_center(lw->split_images[i], sx, sy);
				}
			layout_image_deactivate(lw, i);
			}
		else
			{
			image_set_frame(lw->split_images[i], 1);
			image_set_selectable(lw->split_images[i], 1);
			}

	for (i=4; i < MAX_SPLIT_IMAGES; i++)
		{
		if (lw->split_images[i])
			{
			gtk_widget_unref(lw->split_images[i]->widget);
			lw->split_images[i] = NULL;
			}
		}


        if (!lw->image || lw->active_split_image < 0 || lw->active_split_image > 3)
		{
		layout_image_activate(lw, 0);
		}

	hpaned = gtk_hpaned_new ();
	vpaned1 = gtk_vpaned_new ();
	vpaned2 = gtk_vpaned_new ();

	gtk_paned_pack1 (GTK_PANED (vpaned1), lw->split_images[0]->widget, TRUE, TRUE);
	gtk_paned_pack2 (GTK_PANED (vpaned1), lw->split_images[2]->widget, TRUE, TRUE);

	gtk_paned_pack1 (GTK_PANED (vpaned2), lw->split_images[1]->widget, TRUE, TRUE);
	gtk_paned_pack2 (GTK_PANED (vpaned2), lw->split_images[3]->widget, TRUE, TRUE);

	gtk_paned_pack1 (GTK_PANED (hpaned), vpaned1, TRUE, TRUE);
	gtk_paned_pack2 (GTK_PANED (hpaned), vpaned2, TRUE, TRUE);

	
	for (i=0; i < 4; i++)
		gtk_widget_show (lw->split_images[i]->widget);
	gtk_widget_show (vpaned1);
	gtk_widget_show (vpaned2);
	

	lw->split_image_widget = hpaned;
			
	return lw->split_image_widget;

}

GtkWidget *layout_image_setup_split(LayoutWindow *lw, ImageSplitMode mode)
{
	switch (mode)
		{
		case SPLIT_HOR: 
			return layout_image_setup_split_hv(lw, TRUE);
		case SPLIT_VERT:
			return layout_image_setup_split_hv(lw, FALSE);
		case SPLIT_QUAD:
			return layout_image_setup_split_quad(lw);
		case SPLIT_NONE:
		default:
			return layout_image_setup_split_none(lw);
		}
}


/*
 *-----------------------------------------------------------------------------
 * maintenance (for rename, move, remove)
 *-----------------------------------------------------------------------------
 */

void layout_image_maint_renamed(LayoutWindow *lw, FileData *fd)
{
	FileData *img_fd;

	img_fd = layout_image_get_fd(lw);
	if (img_fd == fd)
		{
		image_set_fd(lw->image, fd);
		layout_bars_maint_renamed(lw);
		}
}

void layout_image_maint_removed(LayoutWindow *lw, FileData *fd)
{
	FileData *img_fd;

	img_fd = layout_image_get_fd(lw);
	if (img_fd == fd)
		{
		CollectionData *cd;
		CollectInfo *info;

		cd = image_get_collection(lw->image, &info);
		if (cd && info)
			{
			CollectInfo *new;

			new = collection_next_by_info(cd, info);
			if (!new) new = collection_prev_by_info(cd, info);

			if (new)
				{
				layout_image_set_collection(lw, cd, new);
				return;
				}
			}

		layout_image_set_fd(lw, NULL);
		}
}

void layout_image_maint_moved(LayoutWindow *lw, FileData *fd)
{
	layout_image_maint_renamed(lw, fd);
}