1
/* Bluefish HTML Editor
2
* images.c - anything dealing with images
4
* Copyright (C) 1998-2001 Olivier Sessink
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
#include "default_include.h"
32
#include "html_diag.h" /* parse_html_for_dialogvalues() */
44
#include <gdk-pixbuf/gdk-pixbuf.h>
45
int create_thumbnail(gchar *filename, GdkPixbuf * pb, gint w, gint h);
46
#endif /* USE_GDK_PIXBUF */
48
#ifdef USE_LIBGDK_IMLIB
49
#include <gdk_imlib.h>
50
#endif /* USE_LIBGDK_IMLIB */
52
#ifdef HAVE_IMAGE_LIBS
57
GtkWidget *width_perc;
59
GtkWidget *height_perc;
78
GtkAdjustment *adjustment;
87
/************************************************************************/
88
/* function declarations */
89
void image_thumbnail_dialog_cb(GtkWidget * widget, gpointer data);
90
void image_insert_dialog_cb(GtkWidget * widget, gpointer data);
91
void image_insert_dialog_cb(GtkWidget * widget, gpointer data);
92
void image_thumbnail_dialog_cb(GtkWidget * widget, gpointer data);
93
static void image_filename_changed(GtkWidget * widget, Timagewin * image_win);
94
static void image_dialog(GtkWidget * widget, gpointer data, gboolean thumb);
95
static void insert_image_html(GtkWidget * widget, Timagewin * win);
96
static void destroy_image_win(GtkWidget * w, Timagewin * image_win);
97
static void image_adjust_changed(GtkAdjustment * adj, Timagewin * image_win);
98
/************************************************************************/
100
void image_thumbnail_dialog_cb(GtkWidget * widget, gpointer data)
102
DEBUG_MSG("image_thumbnail_dialog_cb, widget=%p, data=%p\n", widget, data);
103
image_dialog(widget, data, 1);
106
/************************************************************************/
107
void image_insert_dialog_cb(GtkWidget * widget, gpointer data)
109
DEBUG_MSG("image_insert_dialog_cb, widget=%p, data=%p\n", widget, data);
110
image_dialog(widget, data, 0);
113
/************************************************************************/
114
#ifdef USE_GDK_PIXBUF
115
static void image_filename_changed(GtkWidget * widget, Timagewin * image_win) {
121
gdk_pixbuf_unref(image_win->im);
123
image_win->im = gdk_pixbuf_new_from_file(gtk_entry_get_text(GTK_ENTRY(image_win->location)));
124
DEBUG_MSG("image_filename_changed, loaded using gdk_pixbuf\n");
125
if (!image_win->im) {
129
image_win->w = gdk_pixbuf_get_width(image_win->im);
130
temp = (gfloat) image_win->w / 250;
131
DEBUG_MSG("width, temp = %f\n", temp);
135
image_win->h = gdk_pixbuf_get_height(image_win->im);
136
temp = (gfloat) image_win->h / 300;
137
DEBUG_MSG("height, temp = %f\n", temp);
141
DEBUG_MSG("Image size -> width = %d, height = %d. Toobig = %f\n", image_win->w, image_win->h, toobig);
143
tmp_im = gdk_pixbuf_scale_simple(image_win->im, (image_win->w / toobig), (image_win->h / toobig), GDK_INTERP_NEAREST);
145
if (image_win->thumbnail) {
146
gtk_adjustment_set_value(GTK_ADJUSTMENT(image_win->adjustment), 1.0 / toobig);
147
gtk_spin_button_set_value(GTK_SPIN_BUTTON(image_win->width), image_win->w / toobig);
148
gtk_spin_button_set_value(GTK_SPIN_BUTTON(image_win->height), image_win->h / toobig);
150
gtk_spin_button_set_value(GTK_SPIN_BUTTON(image_win->width), image_win->w);
151
gtk_spin_button_set_value(GTK_SPIN_BUTTON(image_win->height), image_win->h);
154
gdk_pixbuf_render_pixmap_and_mask(tmp_im
155
,&image_win->p,&image_win->m,128);
157
gdk_pixbuf_unref (tmp_im);
159
if (image_win->pixmap) {
160
DEBUG_MSG("image_filename_changed, pimap re-set\n");
161
gtk_pixmap_set(GTK_PIXMAP(image_win->pixmap), image_win->p, image_win->m);
163
DEBUG_MSG("image_filename_changed, pximap first time set\n");
164
image_win->pixmap = gtk_pixmap_new(image_win->p, image_win->m);
165
gtk_container_add(GTK_CONTAINER(image_win->frame), image_win->pixmap);
166
gtk_widget_show(image_win->pixmap);
168
if (image_win->p) gdk_pixmap_unref (image_win->p);
169
if (image_win->m) gdk_bitmap_unref (image_win->m);
173
static void image_filename_changed(GtkWidget * widget, Timagewin * image_win)
179
gdk_imlib_destroy_image(image_win->im);
182
image_win->im = gdk_imlib_load_image(gtk_entry_get_text(GTK_ENTRY(image_win->location)));
183
DEBUG_MSG("image_filename_changed, loaded using imlib\n");
184
if (!image_win->im) {
189
image_win->w = image_win->im->rgb_width;
190
temp = (gfloat) image_win->w / 250;
191
DEBUG_MSG("width, temp = %f\n", temp);
195
image_win->h = image_win->im->rgb_height;
196
temp = (gfloat) image_win->h / 300;
197
DEBUG_MSG("height, temp = %f\n", temp);
201
DEBUG_MSG("Image size -> width = %d, height = %d. Toobig = %f\n", image_win->w, image_win->h, toobig);
202
gdk_imlib_render(image_win->im, (image_win->w / toobig), (image_win->h / toobig));
203
if (image_win->thumbnail) {
204
gtk_adjustment_set_value(GTK_ADJUSTMENT(image_win->adjustment), 1.0 / toobig);
205
gtk_spin_button_set_value(GTK_SPIN_BUTTON(image_win->width), image_win->w / toobig);
206
gtk_spin_button_set_value(GTK_SPIN_BUTTON(image_win->height), image_win->h / toobig);
208
gtk_spin_button_set_value(GTK_SPIN_BUTTON(image_win->width), image_win->w);
209
gtk_spin_button_set_value(GTK_SPIN_BUTTON(image_win->height), image_win->h);
212
image_win->p = gdk_imlib_move_image(image_win->im);
213
image_win->m = gdk_imlib_move_mask(image_win->im);
215
if (image_win->pixmap) {
216
DEBUG_MSG("image_filename_changed, pimap re-set\n");
217
gtk_pixmap_set(GTK_PIXMAP(image_win->pixmap), image_win->p, image_win->m);
219
DEBUG_MSG("image_filename_changed, pximap first time set\n");
220
image_win->pixmap = gtk_pixmap_new(image_win->p, image_win->m);
221
gtk_container_add(GTK_CONTAINER(image_win->frame), image_win->pixmap);
222
gtk_widget_show(image_win->pixmap);
224
gdk_imlib_free_pixmap(image_win->p);
225
gdk_imlib_free_bitmap(image_win->m);
230
/************************************************************************/
231
static void image_dialog(GtkWidget * widget, gpointer data, gboolean thumb)
234
Timagewin *image_win = NULL;
235
GtkWidget *table, *scale, *hbox, *but;
238
static gchar *tagitems[] = { "width", "height", "alt", "border", "src", "hspace", "vspace", "align", "name", "usemap", NULL };
239
gchar *tagvalues[11];
240
gchar *custom = NULL;
242
DEBUG_MSG("image_dialog, started\n");
244
#ifdef USE_GDK_PIXBUF
245
/* do we need a gdk_pixbuf version of setting colormaps or is that integrated? */
248
/* switch colormap to Imlib colormap, so image preview works */
250
GdkVisual *gdkvisual;
251
GdkColormap *gdkcmap;
253
gdkvisual = gdk_imlib_get_visual ();
254
gdkcmap = gdk_imlib_get_colormap ();
256
if (gdkvisual && gdkcmap) {
257
gtk_widget_push_visual (gdkvisual);
258
gtk_widget_push_colormap (gdkcmap);
263
image_win = g_malloc0(sizeof(Timagewin));
264
image_win->doc = main_v->current_document;
266
/* this is for the right click menu */
267
while (tagitems[count]) {
268
tagvalues[count] = NULL;
271
if ((data != NULL) && (widget == NULL)) {
272
parse_html_for_dialogvalues(tagitems, tagvalues, &custom, ((Ttagpopup *)data));
273
image_win->range.pos = ((Ttagpopup *)data)->pos;
274
image_win->range.len = ((Ttagpopup *)data)->len;
276
image_win->range.pos = -1;
277
image_win->range.len = -1;
279
/* end for the right click menu */
281
image_win->thumbnail = thumb;
283
image_win->pixwin = window_with_title(_("Insert image as thumbnail"), GTK_WIN_POS_CENTER, GTK_WINDOW_TOPLEVEL, 10);
285
image_win->pixwin = window_with_title(_("Insert image"), GTK_WIN_POS_CENTER, GTK_WINDOW_TOPLEVEL, 10);
288
hbox = gtk_hbox_new(FALSE, 1);
289
gtk_container_add(GTK_CONTAINER(image_win->pixwin), hbox);
291
image_win->frame = gtk_frame_new(_("Preview"));
292
/* gtk_widget_set_usize(image_win->frame, 200, 0); */
293
gtk_box_pack_start(GTK_BOX(hbox), image_win->frame, TRUE, TRUE, 5);
295
table = gtk_table_new(14, 10, 0);
296
gtk_box_pack_start(GTK_BOX(hbox), table, TRUE, TRUE, 5);
298
gtk_widget_realize(image_win->pixwin);
299
image_win->location = entry_with_text(tagvalues[4], 0);
300
gtk_table_attach_defaults(GTK_TABLE(table), image_win->location, 0, 3, 1, 2);
301
gtk_table_attach_defaults(GTK_TABLE(table), gtk_label_new(_("Image location")), 0, 2, 0, 1);
302
gtk_table_attach_defaults(GTK_TABLE(table), file_but_new(image_win->location, image_win->pixwin, 0), 3, 4, 1, 2);
303
gtk_signal_connect(GTK_OBJECT(image_win->location), "activate", image_filename_changed, image_win);
304
DEBUG_MSG("image_dialog, image_win->location=%p\n", image_win->location);
306
adj = gtk_adjustment_new((gfloat) 0, 0.0, 10000.0, 1.0, 5.0, 0.0);
307
image_win->width = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 1, 0);
308
image_win->width_perc = gtk_check_button_new_with_label("%");
309
gtk_table_attach_defaults(GTK_TABLE(table), image_win->width_perc, 1, 2, 3, 4);
310
gtk_table_attach_defaults(GTK_TABLE(table), image_win->width, 0, 1, 3, 4);
311
gtk_table_attach_defaults(GTK_TABLE(table), gtk_label_new(_("Width")), 0, 2, 2, 3);
312
parse_integer_for_dialog(tagvalues[0], image_win->width, NULL, image_win->width_perc);
314
adj = gtk_adjustment_new((gfloat) 0, 0.0, 10000.0, 1.0, 5.0, 0.0);
315
image_win->height = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 1, 0);
316
image_win->height_perc = gtk_check_button_new_with_label("%");
317
gtk_table_attach_defaults(GTK_TABLE(table), image_win->height_perc, 3, 4, 3, 4);
318
gtk_table_attach_defaults(GTK_TABLE(table), image_win->height, 2, 3, 3, 4);
319
gtk_table_attach_defaults(GTK_TABLE(table), gtk_label_new(_("Height")), 2, 4, 2, 3);
320
parse_integer_for_dialog(tagvalues[1], image_win->height, NULL, image_win->height_perc);
322
image_win->alt = entry_with_text(tagvalues[2], 0);
323
gtk_table_attach_defaults(GTK_TABLE(table), image_win->alt, 0, 4, 5, 6);
324
gtk_table_attach_defaults(GTK_TABLE(table), gtk_label_new(_("Alternate text")), 0, 4, 4, 5);
326
adj = gtk_adjustment_new((gfloat) 0, 0.0, 600.0, 1.0, 5.0, 0.0);
327
image_win->border = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 1, 0);
328
gtk_table_attach_defaults(GTK_TABLE(table), image_win->border, 1, 2, 6, 7);
329
gtk_table_attach_defaults(GTK_TABLE(table), gtk_label_new(_("Border")), 0, 1, 6, 7);
330
parse_integer_for_dialog(tagvalues[3], image_win->border, NULL, NULL);
332
image_win->align = combo_with_popdown(tagvalues[7], positionlist, 1);
333
gtk_table_attach_defaults(GTK_TABLE(table), image_win->align, 3, 4, 6, 7);
334
gtk_widget_set_usize(GTK_WIDGET(image_win->align), GTK_WIDGET(image_win->border)->allocation.width, 0);
335
gtk_table_attach_defaults(GTK_TABLE(table), gtk_label_new(_("Align")), 2, 3, 6, 7);
337
adj = gtk_adjustment_new((gfloat) 0, 0.0, 600.0, 1.0, 5.0, 0.0);
338
image_win->hspace = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 1, 0);
339
gtk_table_attach_defaults(GTK_TABLE(table), image_win->hspace, 1, 2, 7, 8);
340
gtk_table_attach_defaults(GTK_TABLE(table), gtk_label_new(_("Hspace")), 0, 1, 7, 8);
341
parse_integer_for_dialog(tagvalues[5], image_win->hspace, NULL, NULL);
343
adj = gtk_adjustment_new((gfloat) 0, 0.0, 600.0, 1.0, 5.0, 0.0);
344
image_win->vspace = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 1, 0);
345
gtk_table_attach_defaults(GTK_TABLE(table), image_win->vspace, 3, 4, 7, 8);
346
gtk_table_attach_defaults(GTK_TABLE(table), gtk_label_new(_("Vspace")), 2, 3, 7, 8);
347
parse_integer_for_dialog(tagvalues[6], image_win->vspace, NULL, NULL);
349
image_win->name = entry_with_text(tagvalues[8], 0);
350
gtk_table_attach_defaults(GTK_TABLE(table), gtk_label_new(_("Name")), 0, 2, 8, 9);
351
gtk_table_attach_defaults(GTK_TABLE(table), image_win->name, 2, 4, 8, 9);
353
image_win->usemap = entry_with_text(tagvalues[9], 0);
354
gtk_table_attach_defaults(GTK_TABLE(table), gtk_label_new(_("Usemap")), 0, 2, 9, 10);
355
gtk_table_attach_defaults(GTK_TABLE(table), image_win->usemap, 2, 4, 9, 10);
357
image_win->custom = entry_with_text(custom, 0);
358
gtk_table_attach_defaults(GTK_TABLE(table), image_win->custom, 0, 4, 11, 12);
359
gtk_table_attach_defaults(GTK_TABLE(table), gtk_label_new(_("Custom")), 0, 4, 10, 11);
361
if (image_win->thumbnail) {
362
image_win->adjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0.5, 0.001, 1.1, 0.001, 0.1, 0.1));
363
scale = gtk_hscale_new(image_win->adjustment);
364
gtk_signal_connect(GTK_OBJECT(image_win->adjustment), "value_changed", GTK_SIGNAL_FUNC(image_adjust_changed), image_win);
365
gtk_scale_set_digits(GTK_SCALE(scale), 3);
366
gtk_range_set_update_policy(GTK_RANGE(scale), GTK_UPDATE_DISCONTINUOUS);
367
gtk_table_attach_defaults(GTK_TABLE(table), scale, 0, 4, 12, 13);
370
DEBUG_MSG("image_dialog, calling activate on location entry\n");
371
gtk_signal_emit_by_name(GTK_OBJECT(image_win->location), "activate");
373
but = bf_stock_ok_button(insert_image_html, image_win);
374
gtk_window_set_default(GTK_WINDOW(image_win->pixwin), but);
375
gtk_table_attach_defaults(GTK_TABLE(table), but , 0, 2, 13, 14);
377
gtk_table_attach_defaults(GTK_TABLE(table), bf_stock_cancel_button(destroy_image_win, image_win), 2, 4, 13, 14);
378
gtk_widget_show_all(image_win->pixwin);
380
gtk_widget_realize(GTK_WIDGET(image_win->pixwin));
381
gtk_window_set_transient_for(GTK_WINDOW(image_win->pixwin), GTK_WINDOW(main_v->main_window));
385
/* switch colormap back to GdkRgb colormap */
386
gtk_widget_pop_visual ();
387
gtk_widget_pop_colormap ();
389
/* DEBUG_MSG("image_dialog, finished, image_win->replace_range=%p\n", image_win->replace_range);*/
392
/************************************************************************/
393
static void insert_image_html(GtkWidget * widget, Timagewin * win)
396
gchar *tempstring, *finalstring, *tnfilename;
397
#ifdef USE_LIBGDK_IMLIB
398
GdkImlibImage *tmp_image;
400
DEBUG_MSG("insert_image_html, started\n");
401
if (win->thumbnail) {
402
tnfilename = g_malloc0(strlen(gtk_entry_get_text(GTK_ENTRY(win->location))) + strlen(main_v->props.cfg_thumbnailstring) + 5);
403
/* copy everythging except for the last 4 chars */
404
/* FIXME: and what be if i using .jpeg not .jpg extension????
405
--> you'll get two dots in your filename (Olivier) */
406
strncpy(tnfilename, gtk_entry_get_text(GTK_ENTRY(win->location)), strlen(gtk_entry_get_text(GTK_ENTRY(win->location))) - 4);
407
strcat(tnfilename, "\0");
409
DEBUG_MSG("insert_image_html, halfway, tnfilename = %s\n", tnfilename);
410
/* add the thumbnailstring and extension */
411
strcat(tnfilename, main_v->props.cfg_thumbnailstring);
412
strcat(tnfilename, ".");
413
strcat(tnfilename, main_v->props.cfg_thumbnailtype);
414
DEBUG_MSG("insert_image_html, final, tnfilename = %s\n", tnfilename);
416
win->tnW = atoi(gtk_entry_get_text(GTK_ENTRY(win->width)));
417
win->tnH = atoi(gtk_entry_get_text(GTK_ENTRY(win->height)));
419
#ifdef USE_GDK_PIXBUF
420
create_thumbnail(tnfilename, win->im, win->tnW, win->tnH);
422
tmp_image = gdk_imlib_clone_scaled_image(win->im, win->tnW, win->tnH);
423
gdk_imlib_save_image(tmp_image, tnfilename, NULL);
424
gdk_imlib_destroy_image(tmp_image);
426
DEBUG_MSG("insert_image_html, thumbnail created\n");
429
g_strdup_printf("%s%s%s%s%s", cap("<A HREF=\""), gtk_entry_get_text(GTK_ENTRY(win->location)), cap("\"><IMG SRC=\""),
432
tempstring = insert_integer_if_spin(win->width, cap("WIDTH"), tempstring, NULL);
433
tempstring = insert_integer_if_spin(win->height, cap("HEIGHT"), tempstring, NULL);
435
tempstring = g_strdup_printf("%s%s%s", cap("<IMG SRC=\""), gtk_entry_get_text(GTK_ENTRY(win->location)), "\"");
436
tempstring = insert_integer_if_spin(win->width, cap("WIDTH"), tempstring, win->width_perc);
437
tempstring = insert_integer_if_spin(win->height, cap("HEIGHT"), tempstring, win->height_perc);
439
tempstring = insert_integer_if_spin(win->border, cap("BORDER"), tempstring, NULL);
440
tempstring = insert_integer_if_spin(win->vspace, cap("VSPACE"), tempstring, NULL);
441
tempstring = insert_integer_if_spin(win->hspace, cap("HSPACE"), tempstring, NULL);
442
tempstring = insert_string_if_entry(win->custom, NULL, tempstring, NULL);
443
tempstring = insert_string_if_entry(win->alt, cap("ALT"), tempstring, (main_v->props.xhtml == 1 ? "No description" : NULL));
444
tempstring = insert_string_if_entry(win->name, cap("NAME"), tempstring, NULL);
445
tempstring = insert_string_if_entry(win->usemap, cap("USEMAP"), tempstring, NULL);
446
tempstring = insert_string_if_entry(GTK_COMBO(win->align)->entry, cap("ALIGN"), tempstring, NULL);
447
DEBUG_MSG("insert_image_html, 3, tempstring=%s\n", tempstring);
448
if (win->thumbnail) {
449
finalstring = g_strdup_printf(main_v->props.xhtml == 1 ? "%s /></%s>" : "%s></%s>", tempstring, cap("A"));
451
finalstring = g_strdup_printf(main_v->props.xhtml == 1 ? "%s />" : "%s>", tempstring);
455
if (win->range.len == -1) {
456
doc_insert_dbl_text(win->doc, finalstring, NULL);
458
replace_text(finalstring, win->range.pos, win->range.len);
462
destroy_image_win(widget, win);
466
/************************************************************************/
467
static void destroy_image_win(GtkWidget * w, Timagewin * image_win)
469
DEBUG_MSG("destroy_image_win, started on image_win->pixwin = %p\n", image_win->pixwin);
470
gtk_signal_handlers_destroy(GTK_OBJECT(image_win->pixwin));
471
DEBUG_MSG("destroy_image_win, signal handlers destroyed\n");
472
gtk_widget_destroy(GTK_WIDGET(image_win->pixwin));
473
DEBUG_MSG("destroy_image_win, pixwin destroyed\n");
476
* probably not complete, watch memory leaks here!
479
#ifdef USE_GDK_PIXBUF
480
gdk_pixbuf_unref(image_win->im);
482
gdk_imlib_destroy_image(image_win->im);
485
DEBUG_MSG("destroy_image_win, gdk_image destroyed\n");
487
DEBUG_MSG("destroy_image_win, image_win free-ed\n");
490
/************************************************************************/
491
#ifdef USE_GDK_PIXBUF
492
static void image_adjust_changed(GtkAdjustment * adj, Timagewin * image_win)
497
DEBUG_MSG("image_adjust_changed, started, adjustment value=%f\n", image_win->adjustment->value);
498
if ((!image_win->im) || (!image_win->pixmap)) {
499
DEBUG_MSG("image_adjust_changed, no image !!!!!\n");
502
image_win->tnW = image_win->adjustment->value * image_win->w;
503
image_win->tnH = image_win->adjustment->value * image_win->h;
505
/* if width or height are 1 or lower gdk_pixbuf crashes --> check for that
506
and when the requested image is really small the memory usage peeks. A
507
resonable minimum value therefore is 10 pixels */
508
image_win->tnW = image_win->tnW <= 10 ? 10 : image_win->tnW;
509
image_win->tnH = image_win->tnH <= 10 ? 10 : image_win->tnH;
511
tempstr = g_strdup_printf("%d", image_win->tnW);
512
gtk_entry_set_text(GTK_ENTRY(image_win->width), tempstr);
515
tempstr = g_strdup_printf("%d", image_win->tnH);
516
gtk_entry_set_text(GTK_ENTRY(image_win->height), tempstr);
518
DEBUG_MSG("image_adjust_changed, tnW=%d, tnH=%d\n", image_win->tnW, image_win->tnH);
520
tmp_im = gdk_pixbuf_scale_simple (image_win->im, image_win->tnW,image_win->tnH, GDK_INTERP_NEAREST);
521
gdk_pixbuf_render_pixmap_and_mask (tmp_im, &image_win->p, &image_win->m, 128);
522
gdk_pixbuf_unref (tmp_im);
524
gtk_pixmap_set (GTK_PIXMAP(image_win->pixmap), image_win->p, image_win->m);
526
gtk_signal_emit_by_name(GTK_OBJECT(image_win->height), "activate");
527
gtk_signal_emit_by_name(GTK_OBJECT(image_win->width), "activate");
529
#else /* ifdef USE_GDK_PIXBUF */
531
static void image_adjust_changed(GtkAdjustment * adj, Timagewin * image_win)
535
DEBUG_MSG("image_adjust_changed, started, adjustment value=%f\n", image_win->adjustment->value);
536
if ((!image_win->im) || (!image_win->pixmap)) {
537
DEBUG_MSG("image_adjust_changed, no image !!!!!\n");
540
image_win->tnW = image_win->adjustment->value * image_win->w;
541
tempstr = g_strdup_printf("%d", image_win->tnW);
542
gtk_entry_set_text(GTK_ENTRY(image_win->width), tempstr);
545
image_win->tnH = image_win->adjustment->value * image_win->h;
546
tempstr = g_strdup_printf("%d", image_win->tnH);
547
gtk_entry_set_text(GTK_ENTRY(image_win->height), tempstr);
549
DEBUG_MSG("image_adjust_changed, tnW=%d, tnH=%d\n", image_win->tnW, image_win->tnH);
550
gdk_imlib_render(image_win->im, image_win->tnW, image_win->tnH);
552
* Extract the Image and mask pixmaps from the Image
554
image_win->p = gdk_imlib_move_image(image_win->im);
556
* The mask will be NULL if the image has no transparency
558
image_win->m = gdk_imlib_move_mask(image_win->im);
559
gtk_pixmap_set(GTK_PIXMAP(image_win->pixmap), image_win->p, image_win->m);
560
gdk_imlib_free_pixmap(image_win->p);
561
gdk_imlib_free_pixmap(image_win->m);
562
gtk_signal_emit_by_name(GTK_OBJECT(image_win->height), "activate");
563
gtk_signal_emit_by_name(GTK_OBJECT(image_win->width), "activate");
565
#endif /* else USE_GDK_PIXBUF */
566
/************************************************************************/
568
/************************************************************************/
569
/************************************************************************/
570
#else /* define HAVE_IMAGE_LIBS */
571
/************************************************************************/
572
/************************************************************************/
574
* touch these and I will kill you Olivier
577
static void image_insert_dialogok_lcb(GtkWidget * widget, Thtml_diag *dg) {
578
gchar *thestring, *finalstring;
580
thestring = g_strdup(cap("<IMG"));
581
thestring = insert_string_if_entry(dg->entry[0], cap("SRC"), thestring, NULL);
582
thestring = insert_integer_if_spin(dg->spin[0], cap("WIDTH"), thestring, dg->check[0]);
583
thestring = insert_integer_if_spin(dg->spin[1], cap("HEIGHT"), thestring, dg->check[1]);
584
thestring = insert_integer_if_spin(dg->spin[2], cap("BORDER"), thestring, NULL);
585
thestring = insert_integer_if_spin(dg->spin[3], cap("HSPACE"), thestring, NULL);
586
thestring = insert_integer_if_spin(dg->spin[4], cap("VSPACE"), thestring, NULL);
587
thestring = insert_string_if_entry(dg->entry[1], cap("NAME"), thestring, NULL);
588
thestring = insert_string_if_entry(dg->entry[2], cap("ALT"), thestring, NULL);
589
thestring = insert_string_if_entry(dg->entry[3], cap("USEMAP"), thestring, NULL);
590
thestring = insert_string_if_entry(GTK_WIDGET(GTK_COMBO(dg->combo[0])->entry), cap("ALIGN"), thestring, NULL);
591
thestring = insert_string_if_entry(dg->entry[4], NULL, thestring, NULL);
593
finalstring = g_strdup_printf(main_v->props.xhtml == 1 ? "%s />" : "%s>", thestring);
596
if (dg->range.len == -1) {
597
insert_dbl_text(finalstring, NULL);
599
replace_text(finalstring, dg->range.pos, dg->range.len);
603
html_diag_destroy_cb(NULL, NULL, dg);
606
void image_insert_dialog_cb(GtkWidget * widget, gpointer data) {
607
static gchar *tagitems[] = { "width", "height", "alt", "border", "src", "hspace", "vspace", "align", "name", "usemap", NULL };
608
gchar *tagvalues[11];
609
gchar *custom = NULL;
614
dg = html_diag_new(_("Insert image"));
615
fill_dialogvalues(tagitems, tagvalues, &custom, (Ttagpopup *) data, widget, dg);
617
dgtable = gtk_table_new(7, 6, 0);
618
gtk_box_pack_start(GTK_BOX(dg->vbox), dgtable, FALSE, FALSE, 0);
620
dg->entry[0] = entry_with_text(tagvalues[4], 1024);
621
gtk_table_attach_defaults(GTK_TABLE(dgtable), gtk_label_new(_("Image location")), 0, 1, 0, 1);
622
gtk_table_attach_defaults(GTK_TABLE(dgtable), dg->entry[0], 1, 5, 0, 1);
623
gtk_table_attach_defaults(GTK_TABLE(dgtable), file_but_new(dg->entry[0], dg->dialog, 0), 5, 6, 0, 1);
625
dg->spin[0] = spinbut_with_value(NULL, 0, 5000, 1.0, 10.0);
626
dg->check[0] = gtk_check_button_new_with_label("%");
627
parse_integer_for_dialog(tagvalues[0], dg->spin[0] , NULL, dg->check[0]);
628
gtk_table_attach_defaults(GTK_TABLE(dgtable), gtk_label_new(_("Width")), 0, 1, 1, 2);
629
gtk_table_attach_defaults(GTK_TABLE(dgtable), dg->spin[0], 1, 2, 1, 2);
630
gtk_table_attach_defaults(GTK_TABLE(dgtable), dg->check[0], 2, 3, 1, 2);
632
dg->spin[1] = spinbut_with_value(NULL, 0, 5000, 1.0, 10.0);
633
dg->check[1] = gtk_check_button_new_with_label("%");
634
parse_integer_for_dialog(tagvalues[1], dg->spin[1] , NULL, dg->check[1]);
635
gtk_table_attach_defaults(GTK_TABLE(dgtable), gtk_label_new(_("Height")), 0, 1, 2, 3);
636
gtk_table_attach_defaults(GTK_TABLE(dgtable), dg->spin[1], 1, 2, 2, 3);
637
gtk_table_attach_defaults(GTK_TABLE(dgtable), dg->check[1], 2, 3, 2, 3);
639
dg->entry[3] = entry_with_text(tagvalues[9], 1024);
640
gtk_table_attach_defaults(GTK_TABLE(dgtable), gtk_label_new(_("Usemap")), 0, 1, 3, 4);
641
gtk_table_attach_defaults(GTK_TABLE(dgtable), dg->entry[3], 1, 3, 3, 4);
643
dg->entry[1] = entry_with_text(tagvalues[8], 1024);
644
gtk_table_attach_defaults(GTK_TABLE(dgtable), gtk_label_new(_("Name")), 0, 1, 4, 5);
645
gtk_table_attach_defaults(GTK_TABLE(dgtable), dg->entry[1], 1, 3, 4, 5);
647
dg->entry[2] = entry_with_text(tagvalues[2], 1024);
648
gtk_table_attach_defaults(GTK_TABLE(dgtable), gtk_label_new(_("Alternate text")), 0, 1, 5, 6);
649
gtk_table_attach_defaults(GTK_TABLE(dgtable), dg->entry[2], 1, 6, 5, 6);
651
dg->entry[4] = entry_with_text(custom, 1024);
652
gtk_table_attach_defaults(GTK_TABLE(dgtable), gtk_label_new(_("Custom")), 0, 1, 6, 7);
653
gtk_table_attach_defaults(GTK_TABLE(dgtable), dg->entry[3], 1, 6, 6, 7);
655
dg->spin[3] = spinbut_with_value(tagvalues[5], 0, 500, 1.0, 5.0);
656
gtk_table_attach_defaults(GTK_TABLE(dgtable), gtk_label_new(_("Hspace")), 3, 4, 1, 2);
657
gtk_table_attach_defaults(GTK_TABLE(dgtable), dg->spin[3], 4, 6, 1, 2);
659
dg->spin[4] = spinbut_with_value(tagvalues[6], 0, 500, 1.0, 5.0);
660
gtk_table_attach_defaults(GTK_TABLE(dgtable), gtk_label_new(_("Vspace")), 3, 4, 2, 3);
661
gtk_table_attach_defaults(GTK_TABLE(dgtable), dg->spin[4], 4, 6, 2, 3);
663
dg->combo[0] = combo_with_popdown_sized(tagvalues[7], positionlist, 1, 90);
664
gtk_table_attach_defaults(GTK_TABLE(dgtable), gtk_label_new(_("Align")), 3, 4, 3, 4);
665
gtk_table_attach_defaults(GTK_TABLE(dgtable), dg->combo[0], 4, 6, 3, 4);
667
dg->spin[2] = spinbut_with_value(tagvalues[3], 0, 500, 1.0, 5.0);
668
gtk_table_attach_defaults(GTK_TABLE(dgtable),gtk_label_new(_("Border")) , 3, 4, 4, 5);
669
gtk_table_attach_defaults(GTK_TABLE(dgtable), dg->spin[2], 4, 6, 4, 5);
671
html_diag_finish(dg, image_insert_dialogok_lcb);
673
if (custom) g_free(custom);
676
/************************************************************************/
678
void image_thumbnail_dialog_cb(GtkWidget * widget, gpointer data) {
679
error_dialog(_("Insert image as thumbnail"), _("Bluefish was compiled without\nImlib support. This function is\ntherefore not available"));
682
/************************************************************************/
683
/************************************************************************/
684
#endif /* else HAVE_IMAGE_LIBS */
685
/************************************************************************/
686
/************************************************************************/
689
#ifdef HAVE_IMAGE_LIBS
691
static void img_preview_win_destroy_lcb(GtkWidget * widget, GdkEvent *event, Timage_preview *ip) {
693
if (ip != main_v->img_preview) {
694
g_print("img_preview_win_destroy_lcb, ** THIS SHOULD NOT HAPPEN **");
698
if (ip->current_img_filename != NULL) {
699
free (ip->current_img_filename);
700
ip->current_img_filename = NULL;
702
window_destroy(main_v->img_preview->w_img_preview_win);
703
g_free(main_v->img_preview);
704
main_v->img_preview = NULL;
707
static void img_preview_win (void) {
708
if (main_v->img_preview && GTK_IS_OBJECT (main_v->img_preview->w_img_preview_win)) {
713
ip = g_malloc0 (sizeof (Timage_preview));
714
main_v->img_preview = ip;
715
ip->max_width = 300; /* make this configurable */
716
ip->max_height = 300; /* make this configurable */
718
ip->w_img_preview_win = window_full(_("Image preview")
719
, GTK_WIN_POS_NONE, GTK_WINDOW_TOPLEVEL, 5
720
, img_preview_win_destroy_lcb, ip);
721
gtk_widget_set_usize(ip->w_img_preview_win, 300, 300);
722
ip->w_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
723
gtk_container_add (GTK_CONTAINER (ip->w_img_preview_win), ip->w_scrolledwin);
724
gtk_widget_show_all (ip->w_img_preview_win);
730
preview_image_by_position
731
Searches for an image-filename somewhere around the cursor position
732
and calls preview_image_by_filename.
735
void preview_image_by_position_cb (GtkWidget *widget, gpointer data)
737
gint cursorpos, idx, left, right, length;
738
gchar *text, *tag, *tmptext, *tmpsrc, *src, *basepath;
741
cursorpos = gtk_text_get_point (GTK_TEXT (main_v->current_document->textbox));
743
cursorpos = 0; /* not really */
747
/* this breaks multibyte support I suppose... */
748
length = gtk_text_get_length (GTK_TEXT (main_v->current_document->textbox));
749
text = (char *) malloc (length +1);
750
text = gtk_editable_get_chars (GTK_EDITABLE (main_v->current_document->textbox), 0, -1);
752
while ((idx > 0) && (!strchr ("<", text[idx]))) {
758
while ((idx < length) && (!strchr (">", text[idx]))) {
763
tag = (char *) malloc (right - left +1);
764
tag = strncpy (tag, &text[left], right - left);
765
tag[right - left] = '\0';
769
tmptext = strstr (tag, "src");
770
if (tmptext == NULL) {
775
tmpsrc = strchr(tmptext, '\"') + 1;
776
if (tmpsrc != NULL) tmpsrc = strtok (tmpsrc, "\"");
778
if (main_v->current_document->filename == NULL) {
779
basepath = g_get_current_dir ();
781
basepath = (char *) malloc (strlen (main_v->current_document->filename));
782
basepath = strcpy (basepath, (char *)g_dirname (main_v->current_document->filename));
785
if (tmpsrc != NULL ) {
786
src = (char *) malloc (strlen (basepath) + strlen (tmpsrc) +2);
787
if (tmpsrc[0] != DIRCHR) {
788
src = strcpy (src, basepath);
789
src = strcat (src, DIRSTR);
790
src = strcat (src, tmpsrc);
792
src = strcpy (src, tmpsrc);
795
DEBUG_MSG ("preview_image_by_position: filename: '%s'\n", src);
796
preview_image_by_filename (src);
804
void preview_image_by_filename (gchar *filename) {
805
#ifdef USE_GDK_PIXBUF
808
GdkImlibImage *image;
811
DEBUG_MSG("preview_image_by_filename, started on %s\n", filename);
813
if (main_v->img_preview == NULL) {
818
if (main_v->img_preview->current_img_filename) {
819
if (strcmp (main_v->img_preview->current_img_filename, filename) == 0) {
820
img_preview_win_destroy_lcb (NULL,NULL, main_v->img_preview);
823
free (main_v->img_preview->current_img_filename);
824
main_v->img_preview->current_img_filename = NULL;
828
main_v->img_preview->current_img_filename = (char *) malloc (strlen (filename)+1);
829
strcpy (main_v->img_preview->current_img_filename, filename);
832
#ifdef USE_GDK_PIXBUF
833
image = gdk_pixbuf_new_from_file (filename);
834
DEBUG_MSG("preview_image_by_filename, loaded using gdk_pixbuf\n");
836
image = gdk_imlib_load_image(filename);
837
DEBUG_MSG("preview_image_by_filename, loaded using imlib\n");
840
DEBUG_MSG("preview_image_by_filename, *** failed ***\n");
843
GdkPixmap *ip_pixmap;
844
GdkBitmap *ip_bitmap;
845
#ifdef USE_GDK_PIXBUF
846
gdk_pixbuf_render_pixmap_and_mask (image, &ip_pixmap, &ip_bitmap,128);
848
/* about 30 px for the scrollbars */
849
/* im_width = gdk_pixbuf_get_width (image) + 30;
850
im_height = gdk_pixbuf_get_height (image) + 30;
851
if (im_width > main_v->img_preview->max_width)
852
im_width = main_v->img_preview->max_width;
853
if (im_height > main_v->img_preview->max_height)
854
im_height = main_v->img_preview->max_height;*/
856
gdk_pixbuf_unref (image);
858
gdk_imlib_render(image, image->rgb_width, image->rgb_height);
859
ip_pixmap = gdk_imlib_move_image(image);
860
ip_bitmap = gdk_imlib_move_mask(image);
861
gdk_imlib_destroy_image(image);
863
if (!main_v->img_preview->w_image) {
864
main_v->img_preview->w_image = gtk_pixmap_new (ip_pixmap, ip_bitmap);
865
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (main_v->img_preview->w_scrolledwin), main_v->img_preview->w_image);
866
gtk_widget_show(main_v->img_preview->w_image);
868
gtk_pixmap_set (GTK_PIXMAP (main_v->img_preview->w_image), ip_pixmap, ip_bitmap);
871
gdk_pixmap_unref (ip_pixmap);
873
gdk_bitmap_unref (ip_bitmap);
876
gdk_window_raise (main_v->img_preview->w_img_preview_win->window);
880
#endif /* HAVE_IMAGE_LIBS */
882
#ifdef IMAGEMAP_EDITOR_TEST
888
GdkPixmap *dr; /* the drawing area */
889
GdkPixmap *image_cache; /* cache the rendered image, it can be re-used */
890
GdkGC *gc; /* graphics context for drawing */
891
GdkColormap* cmap; /* the colormap to use */
894
#define TEST_SIZE 300
896
static void draw_on_image(Timgmap_editor *ie) {
906
gdk_colormap_alloc_color(ie->cmap, &color, FALSE, TRUE);
907
gdk_gc_set_foreground (ie->gc, &color);
908
gdk_draw_rectangle(ie->dr,ie->gc
911
/* gdk_draw_line(ie->dr,ie->gc
916
to link on Olivier's box using gdk_pixbuf instead of imlib:
917
gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DGNULOCALEDIR=\"/usr/local/share/locale\" -DLOCALE_ALIAS_PATH=\"/usr/local/share/locale:.\" -DPKGDATADIR=\"/usr/local/share/bluefish\" -DHAVE_CONFIG_H -o bluefish html_diag.o bf_lib.o document.o project.o pixmaps.o gtk_easy.o rpopup.o html2.o stringlist.o undo2.o configure.o ref_dialog.o init.o snr2.o callbacks.o interface.o toolbars.o html.o wizards.o images.o coloursel.o network.o bluefish.o cap.o menu.o highlight.o filter.o wml.o html_table.o html_form.o spell.o spell_gui.o javascript.o char_table.o gdk_pixbuf_save.o perl.o complet.o parsedtd.o attrpage.o perl_ezembed.o -L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm -lrt -L/usr/lib -lgdk_imlib -L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm -rdynamic -L/usr/lib -L/usr/X11R6/lib -lgdk_pixbuf -lgtk -lgdk -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm -L/usr/lib -lImlib -ljpeg -ltiff -lungif -lpng -lz -lm -lXext -L/usr/X11R6/lib -lSM -lICE -lXext -lX11
919
static void imgmap_editor_cleanup(Timgmap_editor *ie) {
920
gdk_gc_unref(ie->gc);
921
gdk_colormap_unref(ie->cmap);
922
gdk_pixmap_unref(ie->image_cache);
923
gdk_pixmap_unref(ie->dr);
925
static void imgmap_editor_destroy_lcb(GtkWidget * widget, GdkEvent *event, Timgmap_editor *ie) {
926
window_destroy(ie->win);
927
imgmap_editor_cleanup(ie);
931
static Timgmap_editor *imgmap_editor_new (gchar *filename) {
933
GtkWidget *vruler, *hruler;
935
ie = g_malloc(sizeof (Timgmap_editor));
936
ie->win = window_full(_("Imagemap editor")
937
, GTK_WIN_POS_MOUSE, GTK_WINDOW_TOPLEVEL, 5
938
, imgmap_editor_destroy_lcb, ie);
939
ie->table = gtk_table_new(3, 3, FALSE);
940
gtk_container_add (GTK_CONTAINER (ie->win), ie->table);
941
vruler = gtk_vruler_new();
942
gtk_table_attach_defaults(GTK_TABLE(ie->table), vruler, 0, 1, 1, 2);
943
hruler = gtk_vruler_new();
944
gtk_table_attach_defaults(GTK_TABLE(ie->table), hruler, 1, 2, 0, 1);
945
gtk_widget_realize(ie->win);
946
ie->dr = gdk_pixmap_new(ie->win->window, TEST_SIZE,TEST_SIZE, 16);
947
ie->gc = gdk_gc_new(ie->win->window);
948
ie->cmap = gdk_colormap_get_system();
949
#ifdef USE_GDK_PIXBUF
953
image = gdk_pixbuf_new_from_file (filename);
954
gdk_pixbuf_render_pixmap_and_mask (image, &ie->image_cache, &bitmap,128);
955
gdk_pixbuf_unref(image);
956
if (bitmap) gdk_bitmap_unref(bitmap);
963
/** this function can be called multiple times to change something */
965
static void imgmap_editor_render(Timgmap_editor *ie) {
966
gdk_draw_pixmap(ie->dr, ie->gc, ie->image_cache, 0, 0, 0, 0, -1, -1);
967
/* do all drawing here */
972
if (ie->img == NULL) {
973
ie->img = gtk_pixmap_new(ie->dr, NULL);
974
gtk_table_attach_defaults(GTK_TABLE(ie->table), ie->img, 1, 2, 1, 2);
975
gtk_widget_show_all (ie->win);
979
static void parse_buf_for_imgmap(Timgmap_editor *ie, gchar *buf, gchar *mapname) {
984
void make_imagemap_win(GtkWidget * widget, gpointer data) {
985
Timgmap_editor *ie = imgmap_editor_new ("/home/olivier/bluefish/tmp/index.gif");
986
imgmap_editor_render(ie);
989
#endif /* IMAGEMAP_EDITOR_TEST */