mirror of
https://gitlab.gnome.org/GNOME/gimp
synced 2024-10-21 12:02:32 +00:00
3cff8419db
2000-12-18 Sven Neumann <sven@gimp.org> Jens Lautenbacher <jtl@gimp.org> * app/Makefile.am * app/gimpbrushlistP.h * app/gimpbrushpipeP.h * app/gimpobjectP.h: removed these three files * app/parasitelistP.h * app/channels_dialog.c * app/docindex.c * app/gimpdrawable.c * app/gimpdrawableP.h * app/gimpimage.c * app/gimpimageP.h * app/gimplist.[ch] * app/gimpobject.c * app/gimpobject.h * app/gimpsetP.h: changed according to header removal * app/airbrush.c * app/brush_select.[ch] * app/brushes_cmds.c * app/gimpbrush.[ch] * app/gimpbrushgenerated.[ch] * app/gimpbrushlist.[ch] * app/gimpbrushpipe.[ch] * app/gimpcontextpreview.c * app/paint_core.c * app/paintbrush.c * app/pencil.c * tools/pdbgen/pdb/brushes.pdb: Big Brushes Cleanup. The GimpBrush* object hierarchy and the file formats were broken by "design". This made it overly difficult to read and write pixmap brushes and brush pipes, leading to the situation that The GIMP was not able to read it's very own file formats. Since the GimpBrush format did support arbitrary color depths, the introduction of a file format for pixmap brushes was unnecessary. The GimpBrushPixmap object is dead. GimpBrush has an additional pixmap temp_buf and handles pixmap brushes transparently. The file format of pixmap brushes is not any longer a grayscale brush plus a pattern, but a simple brush with RGBA data. The old brushes can still be loaded, but the .gpb format is deprecated. GimpBrushPipe derives from GimpBrush. The fileformat is still a text header, followed by a number of brushes, but those brushes are stored in the new GimpBrush format (no pattern anymore). The pipe does not care about the depth of the contained GimpBrushes, so we get grayscale BrushPipes for free. Since the brush loader still loads the old format, old .gih files can also still be loaded. Since the brushes in the GimpBrushPipe do not any longer contain a pointer to the pipe object, we do only temporarily switch brushes in the paint_core routines. This is not very elegant, but the best we can do without a major redesign. * app/patterns.[ch]: changed the loader to work with a filedescriptor instead of a filehandle to make it work with the new brush loading code. * plug-ins/common/.cvsignore * plug-ins/common/Makefile.am * plug-ins/common/plugin-defs.pl * plug-ins/common/gih.c: new plug-in that saves GIH files in the new format (loader will follow soon) * plug-ins/common/gpb.c: removed since Pixmap Brushes are no longer supported as a special file format. * plug-ins/common/gbr.c: load and save brushes in the new brush format which allows RGBA brushes too. * plug-ins/common/pat.c: load and save grayscale patterns too
839 lines
18 KiB
C
839 lines
18 KiB
C
/* docindex.c - Creates the window used by the document index in go and gimp.
|
|
*
|
|
* Copyright (C) 1998 Chris Lahey.
|
|
*
|
|
* 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, 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.
|
|
*/
|
|
#include "config.h"
|
|
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include "dialog_handler.h"
|
|
#include "docindex.h"
|
|
#include "fileops.h"
|
|
#include "gdisplay.h"
|
|
#include "gimpimageP.h"
|
|
#include "gimpui.h"
|
|
#include "gimpdnd.h"
|
|
#include "ops_buttons.h"
|
|
#include "session.h"
|
|
|
|
#include "libgimp/gimpenv.h"
|
|
|
|
#include "libgimp/gimpintl.h"
|
|
|
|
#include "pixmaps/folder.xpm"
|
|
#include "pixmaps/raise.xpm"
|
|
#include "pixmaps/lower.xpm"
|
|
#include "pixmaps/delete.xpm"
|
|
|
|
|
|
typedef struct
|
|
{
|
|
GtkWidget *window;
|
|
GtkWidget *list;
|
|
} IdeaManager;
|
|
|
|
typedef struct
|
|
{
|
|
gboolean boole;
|
|
gchar *string;
|
|
gpointer data;
|
|
} BoolCharPair;
|
|
|
|
|
|
/* forward declarations */
|
|
|
|
static void create_idea_list (void);
|
|
static void idea_add_in_position (gchar *label,
|
|
gint position);
|
|
static void open_idea_window (void);
|
|
static void open_or_raise (gchar *file_name,
|
|
gboolean try_raise);
|
|
|
|
static void idea_open_callback (GtkWidget *widget,
|
|
gpointer data);
|
|
static void idea_open_or_raise_callback (GtkWidget *widget,
|
|
gpointer data);
|
|
static void idea_up_callback (GtkWidget *widget,
|
|
gpointer data);
|
|
static void idea_to_top_callback (GtkWidget *widget,
|
|
gpointer data);
|
|
static void idea_down_callback (GtkWidget *widget,
|
|
gpointer data);
|
|
static void idea_to_bottom_callback (GtkWidget *widget,
|
|
gpointer data);
|
|
static void idea_remove_callback (GtkWidget *widget,
|
|
gpointer data);
|
|
static void idea_hide_callback (GtkWidget *widget,
|
|
gpointer data);
|
|
|
|
static void load_idea_manager (IdeaManager *ideas);
|
|
static void save_idea_manager (IdeaManager *ideas);
|
|
|
|
static void clear_white (FILE *fp);
|
|
static gint getinteger (FILE *fp);
|
|
|
|
|
|
/* local variables */
|
|
|
|
static IdeaManager *ideas = NULL;
|
|
static GList *idea_list = NULL;
|
|
|
|
|
|
/* the ops buttons */
|
|
static GtkSignalFunc open_ext_callbacks[] =
|
|
{
|
|
idea_open_or_raise_callback, file_open_callback, NULL, NULL
|
|
};
|
|
|
|
static GtkSignalFunc raise_ext_callbacks[] =
|
|
{
|
|
idea_to_top_callback, NULL, NULL, NULL
|
|
};
|
|
|
|
static GtkSignalFunc lower_ext_callbacks[] =
|
|
{
|
|
idea_to_bottom_callback, NULL, NULL, NULL
|
|
};
|
|
|
|
static OpsButton ops_buttons[] =
|
|
{
|
|
{ folder_xpm, idea_open_callback, open_ext_callbacks,
|
|
N_("Open the selected entry\n"
|
|
"<Shift> Raise window if already open\n"
|
|
"<Ctrl> Load Image dialog"), NULL,
|
|
NULL, 0 },
|
|
{ raise_xpm, idea_up_callback, raise_ext_callbacks,
|
|
N_("Move the selected entry up in the index\n"
|
|
"<Shift> To top"), NULL,
|
|
NULL, 0 },
|
|
{ lower_xpm, idea_down_callback, lower_ext_callbacks,
|
|
N_("Move the selected entry down in the index\n"
|
|
"<Shift> To bottom"), NULL,
|
|
NULL, 0 },
|
|
{ delete_xpm, idea_remove_callback, NULL,
|
|
N_("Remove the selected entry from the index"), NULL,
|
|
NULL, 0 },
|
|
{ NULL, NULL, NULL, NULL, NULL, NULL, 0 }
|
|
};
|
|
|
|
|
|
/* dnd stuff */
|
|
|
|
static GtkTargetEntry drag_types[] =
|
|
{
|
|
GIMP_TARGET_URI_LIST,
|
|
GIMP_TARGET_TEXT_PLAIN,
|
|
GIMP_TARGET_NETSCAPE_URL
|
|
};
|
|
static gint n_drag_types = sizeof (drag_types) / sizeof (drag_types[0]);
|
|
|
|
|
|
/* public functions */
|
|
|
|
void
|
|
document_index_create (void)
|
|
{
|
|
if (ideas)
|
|
gdk_window_raise (ideas->window->window);
|
|
else
|
|
open_idea_window ();
|
|
}
|
|
|
|
void
|
|
document_index_free (void)
|
|
{
|
|
idea_hide_callback (NULL, NULL);
|
|
}
|
|
|
|
void
|
|
document_index_add (gchar *title)
|
|
{
|
|
idea_add_in_position (title, 0);
|
|
}
|
|
|
|
FILE *
|
|
document_index_parse_init (void)
|
|
{
|
|
FILE *fp;
|
|
gchar *desktopfile;
|
|
gint dummy;
|
|
|
|
desktopfile = gimp_personal_rc_file ("ideas");
|
|
|
|
fp = fopen (desktopfile, "r");
|
|
|
|
if (fp != NULL)
|
|
{
|
|
/* eventually strip away the old file format's first line */
|
|
if (fscanf (fp, "%i %i %i %i", &dummy, &dummy, &dummy, &dummy) != 4)
|
|
{
|
|
fclose (fp);
|
|
fp = fopen (desktopfile, "r");
|
|
}
|
|
}
|
|
|
|
g_free (desktopfile);
|
|
|
|
return fp;
|
|
}
|
|
|
|
gchar *
|
|
document_index_parse_line (FILE * fp)
|
|
{
|
|
gint length;
|
|
gchar *filename;
|
|
|
|
length = getinteger (fp);
|
|
|
|
if (!feof (fp) && !ferror (fp))
|
|
{
|
|
filename = g_malloc0 (length + 1);
|
|
filename[fread (filename, 1, length, fp)] = 0;
|
|
clear_white (fp);
|
|
return filename;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/* local functions */
|
|
|
|
static void
|
|
load_from_list (gpointer data,
|
|
gpointer data_null)
|
|
{
|
|
idea_add_in_position ((gchar *) data, -1);
|
|
}
|
|
|
|
static void
|
|
load_idea_manager (IdeaManager *ideas)
|
|
{
|
|
FILE *fp = NULL;
|
|
|
|
if (! idea_list)
|
|
fp = document_index_parse_init ();
|
|
|
|
if (idea_list || fp)
|
|
{
|
|
gtk_widget_show (ideas->window);
|
|
|
|
if (fp)
|
|
{
|
|
gchar *title;
|
|
|
|
clear_white (fp);
|
|
|
|
while ((title = document_index_parse_line (fp)))
|
|
{
|
|
idea_add_in_position (title, -1);
|
|
g_free (title);
|
|
}
|
|
fclose (fp);
|
|
}
|
|
else
|
|
{
|
|
g_list_foreach (idea_list, load_from_list, NULL);
|
|
g_list_foreach (idea_list, (GFunc) g_free, NULL);
|
|
g_list_free (idea_list);
|
|
idea_list = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
gtk_widget_show (ideas->window);
|
|
}
|
|
}
|
|
|
|
static void
|
|
save_to_ideas (gpointer data,
|
|
gpointer user_data)
|
|
{
|
|
gchar *title;
|
|
|
|
title = GTK_LABEL (GTK_BIN (data)->child)->label;
|
|
|
|
fprintf ((FILE *) user_data, "%d %s\n", strlen (title), title);
|
|
}
|
|
|
|
static void
|
|
save_list_to_ideas (gpointer data,
|
|
gpointer user_data)
|
|
{
|
|
gchar *title;
|
|
|
|
title = (gchar *) data;
|
|
|
|
fprintf ((FILE *) user_data, "%d %s\n", strlen (title), title);
|
|
}
|
|
|
|
static void
|
|
save_idea_manager (IdeaManager *ideas)
|
|
{
|
|
FILE *fp;
|
|
gchar *desktopfile;
|
|
|
|
/* open persistant desktop file. */
|
|
desktopfile = gimp_personal_rc_file ("ideas");
|
|
fp = fopen (desktopfile, "w");
|
|
g_free (desktopfile);
|
|
|
|
if (fp)
|
|
{
|
|
if (ideas)
|
|
{
|
|
g_list_foreach (GTK_LIST (ideas->list)->children, save_to_ideas, fp);
|
|
}
|
|
else if (idea_list)
|
|
{
|
|
g_list_foreach (idea_list, save_list_to_ideas, fp);
|
|
}
|
|
|
|
fclose (fp);
|
|
}
|
|
}
|
|
|
|
static void
|
|
save_to_list (gpointer data,
|
|
gpointer null_data)
|
|
{
|
|
gchar *title;
|
|
|
|
title = g_strdup (GTK_LABEL (GTK_BIN (data)->child)->label);
|
|
|
|
idea_list = g_list_append (idea_list, title);
|
|
}
|
|
|
|
static void
|
|
create_idea_list (void)
|
|
{
|
|
if (idea_list)
|
|
{
|
|
g_list_foreach (idea_list, (GFunc) g_free, NULL);
|
|
g_list_free (idea_list);
|
|
idea_list = 0;
|
|
}
|
|
|
|
g_list_foreach (GTK_LIST (ideas->list)->children, save_to_list, NULL);
|
|
}
|
|
|
|
static gint
|
|
list_item_callback (GtkWidget *widget,
|
|
GdkEventButton *event,
|
|
gpointer data)
|
|
{
|
|
if (GTK_IS_LIST_ITEM (widget) &&
|
|
event->type == GDK_2BUTTON_PRESS)
|
|
{
|
|
open_or_raise (GTK_LABEL (GTK_BIN (widget)->child)->label, FALSE);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
check_needed (gpointer data,
|
|
gpointer user_data)
|
|
{
|
|
BoolCharPair *pair;
|
|
|
|
pair = (BoolCharPair *) user_data;
|
|
|
|
if (strcmp (pair->string, GTK_LABEL (GTK_BIN (data)->child)->label) == 0)
|
|
{
|
|
pair->boole = TRUE;
|
|
pair->data = data;
|
|
}
|
|
}
|
|
|
|
static void
|
|
check_needed_list (gpointer data,
|
|
gpointer user_data)
|
|
{
|
|
BoolCharPair *pair;
|
|
|
|
pair = (BoolCharPair *) user_data;
|
|
|
|
if (strcmp (pair->string, (gchar *) data) == 0)
|
|
{
|
|
pair->boole = TRUE;
|
|
pair->data = data;
|
|
}
|
|
}
|
|
|
|
static void
|
|
idea_add_in_position_with_select (gchar *title,
|
|
gint position,
|
|
gboolean select)
|
|
{
|
|
BoolCharPair pair;
|
|
|
|
pair.boole = FALSE;
|
|
pair.string = title;
|
|
pair.data = NULL;
|
|
|
|
if (ideas)
|
|
{
|
|
g_list_foreach (GTK_LIST (ideas->list)->children, check_needed, &pair);
|
|
|
|
if (! pair.boole)
|
|
{
|
|
GtkWidget *listitem;
|
|
GList *list = NULL;
|
|
|
|
listitem = gtk_list_item_new_with_label (title);
|
|
list = g_list_append (list, listitem);
|
|
|
|
if (position < 0)
|
|
gtk_list_append_items (GTK_LIST (ideas->list), list);
|
|
else
|
|
gtk_list_insert_items (GTK_LIST (ideas->list), list, position);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (listitem), "button_press_event",
|
|
GTK_SIGNAL_FUNC (list_item_callback),
|
|
NULL);
|
|
|
|
gtk_widget_show (listitem);
|
|
|
|
if (select)
|
|
gtk_list_item_select (GTK_LIST_ITEM (listitem));
|
|
}
|
|
else /* move entry to top */
|
|
{
|
|
gchar *title;
|
|
|
|
title = g_strdup (GTK_LABEL (GTK_BIN (pair.data)->child)->label);
|
|
gtk_container_remove (GTK_CONTAINER (ideas->list),
|
|
GTK_WIDGET (pair.data));
|
|
idea_add_in_position_with_select (title, 0, TRUE);
|
|
g_free (title);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (! idea_list)
|
|
{
|
|
FILE *fp;
|
|
|
|
fp = document_index_parse_init ();
|
|
|
|
if (fp)
|
|
{
|
|
gchar *filename;
|
|
|
|
while ((filename = document_index_parse_line (fp)))
|
|
{
|
|
idea_list = g_list_append (idea_list, g_strdup (filename));
|
|
g_free (filename);
|
|
}
|
|
|
|
fclose (fp);
|
|
}
|
|
}
|
|
|
|
g_list_foreach (idea_list, check_needed_list, &pair);
|
|
|
|
if (! pair.boole)
|
|
{
|
|
if (position < 0)
|
|
idea_list = g_list_prepend (idea_list, g_strdup (title));
|
|
else
|
|
idea_list = g_list_insert (idea_list, g_strdup (title), position);
|
|
}
|
|
else /* move entry to top */
|
|
{
|
|
idea_list = g_list_remove (idea_list, pair.data);
|
|
g_free (pair.data);
|
|
idea_list = g_list_prepend (idea_list, g_strdup (title));
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
idea_add_in_position (gchar *title,
|
|
gint position)
|
|
{
|
|
idea_add_in_position_with_select (title, position, TRUE);
|
|
}
|
|
|
|
static void
|
|
raise_if_match (gpointer data,
|
|
gpointer user_data)
|
|
{
|
|
GDisplay *gdisp;
|
|
BoolCharPair *pair;
|
|
|
|
gdisp = (GDisplay *) data;
|
|
pair = (BoolCharPair *) user_data;
|
|
|
|
if (gdisp->gimage->has_filename &&
|
|
strcmp (pair->string, gdisp->gimage->filename) == 0)
|
|
{
|
|
pair->boole = TRUE;
|
|
gdk_window_raise (gdisp->shell->window);
|
|
}
|
|
}
|
|
|
|
static void
|
|
open_or_raise (gchar *file_name,
|
|
gboolean try_raise)
|
|
{
|
|
BoolCharPair pair;
|
|
|
|
pair.boole = FALSE;
|
|
pair.string = file_name;
|
|
pair.data = NULL;
|
|
|
|
if (try_raise)
|
|
{
|
|
gdisplays_foreach (raise_if_match, &pair);
|
|
|
|
if (! pair.boole)
|
|
{
|
|
file_open (file_name, file_name);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
file_open (file_name, file_name);
|
|
}
|
|
}
|
|
|
|
|
|
/* file parsing functions */
|
|
|
|
static gint
|
|
getinteger (FILE *fp)
|
|
{
|
|
gchar nextchar;
|
|
gint response = 0;
|
|
gboolean negative = FALSE;
|
|
|
|
while (isspace (nextchar = fgetc (fp)))
|
|
/* empty statement */ ;
|
|
|
|
if (nextchar == '-')
|
|
{
|
|
negative = TRUE;
|
|
while (isspace (nextchar = fgetc (fp)))
|
|
/* empty statement */ ;
|
|
}
|
|
|
|
for (; '0' <= nextchar && '9' >= nextchar; nextchar = fgetc (fp))
|
|
{
|
|
response *= 10;
|
|
response += nextchar - '0';
|
|
}
|
|
for (; isspace (nextchar); nextchar = fgetc (fp))
|
|
/* empty statement */ ;
|
|
|
|
if (!feof(fp))
|
|
ungetc (nextchar, fp);
|
|
if (negative)
|
|
response = -response;
|
|
|
|
return response;
|
|
}
|
|
|
|
static void
|
|
clear_white (FILE *fp)
|
|
{
|
|
gint nextchar;
|
|
|
|
while (isspace (nextchar = fgetc (fp)))
|
|
/* empty statement */ ;
|
|
|
|
if (!feof(fp))
|
|
ungetc (nextchar, fp);
|
|
}
|
|
|
|
|
|
/* toolbar / dialog callbacks */
|
|
|
|
static gint
|
|
idea_move (GtkWidget *widget,
|
|
gint distance,
|
|
gboolean select)
|
|
{
|
|
gint orig_position;
|
|
gint position;
|
|
gchar *title;
|
|
|
|
orig_position = g_list_index (GTK_LIST (ideas->list)->children, widget);
|
|
position = orig_position + distance;
|
|
|
|
if (position < 0)
|
|
position = 0;
|
|
|
|
if (position >= g_list_length (GTK_LIST (ideas->list)->children))
|
|
position = g_list_length (GTK_LIST (ideas->list)->children) - 1;
|
|
|
|
if (position != orig_position)
|
|
{
|
|
title = g_strdup (GTK_LABEL (GTK_BIN (widget)->child)->label);
|
|
gtk_container_remove (GTK_CONTAINER (ideas->list), widget);
|
|
idea_add_in_position_with_select (title, position, select);
|
|
g_free (title);
|
|
}
|
|
|
|
return position - orig_position;
|
|
}
|
|
|
|
static void
|
|
idea_open_callback (GtkWidget *widget,
|
|
gpointer data)
|
|
{
|
|
GtkWidget *selected;
|
|
|
|
if (GTK_LIST (ideas->list)->selection)
|
|
{
|
|
selected = GTK_LIST (ideas->list)->selection->data;
|
|
open_or_raise (GTK_LABEL (GTK_BIN (selected)->child)->label, FALSE);
|
|
}
|
|
else
|
|
{
|
|
file_open_callback (widget, data);
|
|
}
|
|
}
|
|
|
|
static void
|
|
idea_open_or_raise_callback (GtkWidget *widget,
|
|
gpointer data)
|
|
{
|
|
GtkWidget *selected;
|
|
|
|
if (GTK_LIST (ideas->list)->selection)
|
|
{
|
|
selected = GTK_LIST (ideas->list)->selection->data;
|
|
open_or_raise (GTK_LABEL (GTK_BIN (selected)->child)->label, TRUE);
|
|
}
|
|
else
|
|
{
|
|
file_open_callback (widget, data);
|
|
}
|
|
}
|
|
|
|
static void
|
|
idea_up_callback (GtkWidget *widget,
|
|
gpointer data)
|
|
{
|
|
GtkWidget *selected;
|
|
|
|
if (GTK_LIST (ideas->list)->selection)
|
|
{
|
|
selected = GTK_LIST (ideas->list)->selection->data;
|
|
idea_move (selected, -1, TRUE);
|
|
}
|
|
}
|
|
|
|
static void
|
|
idea_to_top_callback (GtkWidget *widget,
|
|
gpointer data)
|
|
{
|
|
GtkWidget *selected;
|
|
|
|
if (GTK_LIST (ideas->list)->selection)
|
|
{
|
|
selected = GTK_LIST (ideas->list)->selection->data;
|
|
idea_move (selected, - g_list_length (GTK_LIST (ideas->list)->children),
|
|
TRUE);
|
|
}
|
|
}
|
|
|
|
static void
|
|
idea_down_callback (GtkWidget *widget,
|
|
gpointer data)
|
|
{
|
|
GtkWidget *selected;
|
|
|
|
if (GTK_LIST (ideas->list)->selection)
|
|
{
|
|
selected = GTK_LIST (ideas->list)->selection->data;
|
|
idea_move (selected, 1, TRUE);
|
|
}
|
|
}
|
|
|
|
static void
|
|
idea_to_bottom_callback (GtkWidget *widget,
|
|
gpointer data)
|
|
{
|
|
GtkWidget *selected;
|
|
|
|
if (GTK_LIST (ideas->list)->selection)
|
|
{
|
|
selected = GTK_LIST (ideas->list)->selection->data;
|
|
idea_move (selected, g_list_length (GTK_LIST (ideas->list)->children),
|
|
TRUE);
|
|
}
|
|
}
|
|
|
|
static void
|
|
idea_remove (GtkWidget *widget)
|
|
{
|
|
gint position;
|
|
|
|
position = g_list_index (GTK_LIST (ideas->list)->children, widget);
|
|
|
|
gtk_container_remove (GTK_CONTAINER (ideas->list), widget);
|
|
|
|
if (g_list_length (GTK_LIST (ideas->list)->children) - 1 < position)
|
|
position = g_list_length (GTK_LIST (ideas->list)->children) - 1;
|
|
|
|
gtk_list_select_item (GTK_LIST (ideas->list), position);
|
|
}
|
|
|
|
static void
|
|
idea_remove_callback (GtkWidget *widget,
|
|
gpointer data)
|
|
{
|
|
GtkWidget *selected;
|
|
|
|
if (GTK_LIST (ideas->list)->selection)
|
|
{
|
|
selected = GTK_LIST (ideas->list)->selection->data;
|
|
idea_remove (selected);
|
|
}
|
|
}
|
|
|
|
static void
|
|
idea_hide_callback (GtkWidget *widget,
|
|
gpointer data)
|
|
{
|
|
if (ideas || idea_list)
|
|
save_idea_manager (ideas);
|
|
|
|
/* False if exiting */
|
|
if (ideas)
|
|
{
|
|
create_idea_list ();
|
|
dialog_unregister (ideas->window);
|
|
session_get_window_info (ideas->window, &document_index_session_info);
|
|
gtk_widget_destroy (ideas->window);
|
|
g_free (ideas);
|
|
ideas = 0;
|
|
}
|
|
}
|
|
|
|
static void
|
|
ops_buttons_update (GtkWidget *widget,
|
|
gpointer data)
|
|
{
|
|
GtkWidget *selected = NULL;
|
|
gint length = 0;
|
|
gint index = -1;
|
|
|
|
length = g_list_length (GTK_LIST (ideas->list)->children);
|
|
|
|
if (GTK_LIST (ideas->list)->selection)
|
|
{
|
|
selected = GTK_LIST (ideas->list)->selection->data;
|
|
index = g_list_index (GTK_LIST (ideas->list)->children, selected);
|
|
}
|
|
|
|
#define SET_OPS_SENSITIVE(button,condition) \
|
|
gtk_widget_set_sensitive (ops_buttons[(button)].widget, \
|
|
(condition) != 0)
|
|
|
|
SET_OPS_SENSITIVE (1, selected && index > 0);
|
|
SET_OPS_SENSITIVE (2, selected && index < (length - 1));
|
|
SET_OPS_SENSITIVE (3, selected);
|
|
|
|
#undef SET_OPS_SENSITIVE
|
|
}
|
|
|
|
static void
|
|
open_idea_window (void)
|
|
{
|
|
GtkWidget *main_vbox;
|
|
GtkWidget *scrolled_win;
|
|
GtkWidget *abox;
|
|
GtkWidget *button_box;
|
|
gint i;
|
|
|
|
ideas = g_new0 (IdeaManager, 1);
|
|
|
|
ideas->window = gimp_dialog_new (_("Document Index"), "docindex",
|
|
gimp_standard_help_func,
|
|
"dialogs/document_index.html",
|
|
GTK_WIN_POS_MOUSE,
|
|
FALSE, TRUE, FALSE,
|
|
|
|
_("Close"), idea_hide_callback,
|
|
NULL, NULL, NULL, TRUE, TRUE,
|
|
|
|
NULL);
|
|
|
|
gtk_drag_dest_set (ideas->window,
|
|
GTK_DEST_DEFAULT_ALL,
|
|
drag_types, n_drag_types,
|
|
GDK_ACTION_COPY);
|
|
|
|
gimp_dnd_file_dest_set (ideas->window);
|
|
|
|
dialog_register (ideas->window);
|
|
session_set_window_geometry (ideas->window, &document_index_session_info,
|
|
TRUE);
|
|
|
|
main_vbox = gtk_vbox_new (FALSE, 4);
|
|
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
|
|
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (ideas->window)->vbox),
|
|
main_vbox);
|
|
gtk_widget_show (main_vbox);
|
|
|
|
/* Scrolled window */
|
|
scrolled_win = gtk_scrolled_window_new (NULL, NULL);
|
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
|
|
GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS );
|
|
gtk_box_pack_start (GTK_BOX (main_vbox), scrolled_win, TRUE, TRUE, 0);
|
|
gtk_widget_show (scrolled_win);
|
|
|
|
/* Setup list */
|
|
ideas->list = gtk_list_new ();
|
|
gtk_list_set_selection_mode (GTK_LIST (ideas->list), GTK_SELECTION_BROWSE);
|
|
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win),
|
|
ideas->list);
|
|
gtk_widget_show (ideas->list);
|
|
|
|
/* The ops buttons */
|
|
abox = gtk_alignment_new (0.0, 0.5, 0.0, 0.0);
|
|
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (ideas->window)->action_area), abox,
|
|
FALSE, FALSE, 4);
|
|
gtk_widget_show (abox);
|
|
|
|
button_box = ops_button_box_new (ops_buttons, OPS_BUTTON_NORMAL);
|
|
gtk_container_add (GTK_CONTAINER (abox), button_box);
|
|
gtk_widget_show (button_box);
|
|
|
|
for (i = 0; ; i++)
|
|
{
|
|
if (ops_buttons[i].widget == NULL)
|
|
break;
|
|
|
|
gtk_misc_set_padding (GTK_MISC (GTK_BIN (ops_buttons[i].widget)->child),
|
|
12, 0);
|
|
}
|
|
|
|
/* Load and Show window */
|
|
load_idea_manager (ideas);
|
|
|
|
gtk_signal_connect_after (GTK_OBJECT (ideas->list), "selection_changed",
|
|
GTK_SIGNAL_FUNC (ops_buttons_update),
|
|
NULL);
|
|
ops_buttons_update (NULL, NULL);
|
|
}
|