More honesty about bug 144394, it's not quite fixed yet.
[dia.git] / app / diapagelayout.c
blob9eb374d79b7182707cc00902a2ada0e528a4f752
1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998, 1999 Alexander Larsson
4 * diapagelayout.[ch] -- a page settings widget for dia.
5 * Copyright (C) 1999 James Henstridge
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 /*#define PAGELAYOUT_TEST*/
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
28 #include "diapagelayout.h"
29 #include "widgets.h"
31 #include "intl.h"
33 #include "pixmaps/portrait.xpm"
34 #include "pixmaps/landscape.xpm"
36 #include "preferences.h"
37 #include "paper.h"
39 enum {
40 CHANGED,
41 LAST_SIGNAL
44 static guint pl_signals[LAST_SIGNAL] = { 0 };
45 static GtkObjectClass *parent_class;
47 static void dia_page_layout_class_init(DiaPageLayoutClass *class);
48 static void dia_page_layout_init(DiaPageLayout *self);
49 static void dia_page_layout_destroy(GtkObject *object);
51 GtkType
52 dia_page_layout_get_type(void)
54 static GtkType pl_type = 0;
56 if (!pl_type) {
57 static const GtkTypeInfo pl_info = {
58 "DiaPageLayout",
59 sizeof(DiaPageLayout),
60 sizeof(DiaPageLayoutClass),
61 (GtkClassInitFunc) dia_page_layout_class_init,
62 (GtkObjectInitFunc) dia_page_layout_init,
63 NULL,
64 NULL,
65 (GtkClassInitFunc) NULL,
67 pl_type = gtk_type_unique(gtk_table_get_type(), &pl_info);
69 return pl_type;
72 static void
73 dia_page_layout_class_init(DiaPageLayoutClass *class)
75 GtkObjectClass *object_class;
77 object_class = (GtkObjectClass*) class;
78 parent_class = gtk_type_class(gtk_table_get_type());
80 pl_signals[CHANGED] =
81 gtk_signal_new("changed",
82 GTK_RUN_FIRST,
83 GTK_CLASS_TYPE (object_class),
84 GTK_SIGNAL_OFFSET(DiaPageLayoutClass, changed),
85 gtk_signal_default_marshaller,
86 GTK_TYPE_NONE, 0);
87 #if 0 /* FIXME ?*/
88 gtk_object_class_add_signals(object_class, pl_signals, LAST_SIGNAL);
89 #endif
91 object_class->destroy = dia_page_layout_destroy;
94 static void darea_size_allocate(DiaPageLayout *self, GtkAllocation *alloc);
95 static gint darea_expose_event(DiaPageLayout *self, GdkEventExpose *ev);
96 static void paper_size_change(GtkMenuItem *item, DiaPageLayout *self);
97 static void orient_changed(DiaPageLayout *self);
98 static void margin_changed(DiaPageLayout *self);
99 static void scalemode_changed(DiaPageLayout *self);
100 static void scale_changed(DiaPageLayout *self);
102 static void
103 dia_page_layout_init(DiaPageLayout *self)
105 GtkWidget *frame, *box, *table, *menu, *menuitem, *wid;
106 GdkPixmap *pix;
107 GdkBitmap *mask;
108 GList *paper_names;
109 gint i;
111 gtk_table_resize(GTK_TABLE(self), 3, 2);
112 gtk_table_set_row_spacings(GTK_TABLE(self), 5);
113 gtk_table_set_col_spacings(GTK_TABLE(self), 5);
115 /* paper size */
116 frame = gtk_frame_new(_("Paper Size"));
117 gtk_table_attach(GTK_TABLE(self), frame, 0,1, 0,1,
118 GTK_FILL, GTK_FILL, 0, 0);
119 gtk_widget_show(frame);
121 box = gtk_vbox_new(FALSE, 5);
122 gtk_container_set_border_width(GTK_CONTAINER(box), 5);
123 gtk_container_add(GTK_CONTAINER(frame), box);
124 gtk_widget_show(box);
126 self->paper_size = gtk_option_menu_new();
127 gtk_box_pack_start(GTK_BOX(box), self->paper_size, TRUE, FALSE, 0);
129 menu = gtk_menu_new();
131 paper_names = get_paper_name_list();
132 for (i = 0; paper_names != NULL;
133 i++, paper_names = g_list_next(paper_names)) {
134 menuitem = gtk_menu_item_new_with_label(paper_names->data);
135 gtk_object_set_user_data(GTK_OBJECT(menuitem), GINT_TO_POINTER(i));
136 g_signal_connect(GTK_OBJECT(menuitem), "activate",
137 G_CALLBACK(paper_size_change), self);
138 gtk_container_add(GTK_CONTAINER(menu), menuitem);
139 gtk_widget_show(menuitem);
141 gtk_option_menu_set_menu(GTK_OPTION_MENU(self->paper_size), menu);
142 gtk_widget_show(self->paper_size);
144 self->paper_label = gtk_label_new("");
145 gtk_box_pack_start(GTK_BOX(box), self->paper_label, TRUE, TRUE, 0);
146 gtk_widget_show(self->paper_label);
148 /* orientation */
149 frame = gtk_frame_new(_("Orientation"));
150 gtk_table_attach(GTK_TABLE(self), frame, 1,2, 0,1,
151 GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 0);
152 gtk_widget_show(frame);
154 box = gtk_hbox_new(FALSE, 5);
155 gtk_container_set_border_width(GTK_CONTAINER(box), 5);
156 gtk_container_add(GTK_CONTAINER(frame), box);
157 gtk_widget_show(box);
159 self->orient_portrait = gtk_radio_button_new(NULL);
160 pix = gdk_pixmap_colormap_create_from_xpm_d(NULL,
161 gtk_widget_get_colormap(GTK_WIDGET(self)), &mask, NULL,
162 portrait_xpm);
163 wid = gtk_pixmap_new(pix, mask);
164 gdk_pixmap_unref(pix);
165 gdk_bitmap_unref(mask);
166 gtk_container_add(GTK_CONTAINER(self->orient_portrait), wid);
167 gtk_widget_show(wid);
169 gtk_box_pack_start(GTK_BOX(box), self->orient_portrait, TRUE, TRUE, 0);
170 gtk_widget_show(self->orient_portrait);
172 self->orient_landscape = gtk_radio_button_new(
173 gtk_radio_button_group(GTK_RADIO_BUTTON(self->orient_portrait)));
174 pix = gdk_pixmap_colormap_create_from_xpm_d(NULL,
175 gtk_widget_get_colormap(GTK_WIDGET(self)), &mask, NULL,
176 landscape_xpm);
177 wid = gtk_pixmap_new(pix, mask);
178 gdk_pixmap_unref(pix);
179 gdk_bitmap_unref(mask);
180 gtk_container_add(GTK_CONTAINER(self->orient_landscape), wid);
181 gtk_widget_show(wid);
183 gtk_box_pack_start(GTK_BOX(box), self->orient_landscape, TRUE, TRUE, 0);
184 gtk_widget_show(self->orient_landscape);
186 /* margins */
187 frame = gtk_frame_new(_("Margins"));
188 gtk_table_attach(GTK_TABLE(self), frame, 0,1, 1,2,
189 GTK_FILL, GTK_FILL, 0, 0);
190 gtk_widget_show(frame);
192 table = gtk_table_new(4, 2, FALSE);
193 gtk_container_set_border_width(GTK_CONTAINER(table), 5);
194 gtk_table_set_row_spacings(GTK_TABLE(table), 5);
195 gtk_table_set_col_spacings(GTK_TABLE(table), 5);
196 gtk_container_add(GTK_CONTAINER(frame), table);
197 gtk_widget_show(table);
199 wid = gtk_label_new(_("Top:"));
200 gtk_misc_set_alignment(GTK_MISC(wid), 1.0, 0.5);
201 gtk_table_attach(GTK_TABLE(table), wid, 0,1, 0,1,
202 GTK_FILL, GTK_FILL|GTK_EXPAND, 0, 0);
203 gtk_widget_show(wid);
205 self->tmargin = dia_unit_spinner_new(
206 GTK_ADJUSTMENT(gtk_adjustment_new(1, 0,100, 0.1,10,10)),
207 2, DIA_UNIT_CENTIMETER);
208 gtk_table_attach(GTK_TABLE(table), self->tmargin, 1,2, 0,1,
209 GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
210 gtk_widget_show(self->tmargin);
212 wid = gtk_label_new(_("Bottom:"));
213 gtk_misc_set_alignment(GTK_MISC(wid), 1.0, 0.5);
214 gtk_table_attach(GTK_TABLE(table), wid, 0,1, 1,2,
215 GTK_FILL, GTK_FILL|GTK_EXPAND, 0, 0);
216 gtk_widget_show(wid);
218 self->bmargin = dia_unit_spinner_new(
219 GTK_ADJUSTMENT(gtk_adjustment_new(1, 0,100, 0.1,10,10)),
220 2, DIA_UNIT_CENTIMETER);
221 gtk_table_attach(GTK_TABLE(table), self->bmargin, 1,2, 1,2,
222 GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
223 gtk_widget_show(self->bmargin);
225 wid = gtk_label_new(_("Left:"));
226 gtk_misc_set_alignment(GTK_MISC(wid), 1.0, 0.5);
227 gtk_table_attach(GTK_TABLE(table), wid, 0,1, 2,3,
228 GTK_FILL, GTK_FILL|GTK_EXPAND, 0, 0);
229 gtk_widget_show(wid);
231 self->lmargin = dia_unit_spinner_new(
232 GTK_ADJUSTMENT(gtk_adjustment_new(1, 0,100, 0.1,10,10)),
233 2, DIA_UNIT_CENTIMETER);
234 gtk_table_attach(GTK_TABLE(table), self->lmargin, 1,2, 2,3,
235 GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
236 gtk_widget_show(self->lmargin);
238 wid = gtk_label_new(_("Right:"));
239 gtk_misc_set_alignment(GTK_MISC(wid), 1.0, 0.5);
240 gtk_table_attach(GTK_TABLE(table), wid, 0,1, 3,4,
241 GTK_FILL, GTK_FILL|GTK_EXPAND, 0, 0);
242 gtk_widget_show(wid);
244 self->rmargin = dia_unit_spinner_new(
245 GTK_ADJUSTMENT(gtk_adjustment_new(1, 0,100, 0.1,10,10)),
246 2, DIA_UNIT_CENTIMETER);
247 gtk_table_attach(GTK_TABLE(table), self->rmargin, 1,2, 3,4,
248 GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
249 gtk_widget_show(self->rmargin);
251 /* Scaling */
252 frame = gtk_frame_new(_("Scaling"));
253 gtk_table_attach(GTK_TABLE(self), frame, 0,1, 2,3,
254 GTK_FILL, GTK_FILL, 0, 0);
255 gtk_widget_show(frame);
257 table = gtk_table_new(2, 4, FALSE);
258 gtk_container_set_border_width(GTK_CONTAINER(table), 5);
259 gtk_table_set_row_spacings(GTK_TABLE(table), 5);
260 gtk_container_add(GTK_CONTAINER(frame), table);
261 gtk_widget_show(table);
263 self->scale = gtk_radio_button_new_with_label(NULL, _("Scale:"));
264 gtk_table_attach(GTK_TABLE(table), self->scale, 0,1, 0,1,
265 GTK_FILL, GTK_FILL|GTK_EXPAND, 0, 0);
266 gtk_widget_show(self->scale);
268 self->scaling = gtk_spin_button_new(
269 GTK_ADJUSTMENT(gtk_adjustment_new(100,1,10000, 1,10,10)), 1, 1);
270 gtk_table_attach(GTK_TABLE(table), self->scaling, 1,4, 0,1,
271 GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
272 gtk_widget_show(self->scaling);
274 self->fitto = gtk_radio_button_new_with_label(
275 GTK_RADIO_BUTTON(self->scale)->group, _("Fit to:"));
276 gtk_table_attach(GTK_TABLE(table), self->fitto, 0,1, 1,2,
277 GTK_FILL, GTK_FILL|GTK_EXPAND, 0, 0);
278 gtk_widget_show(self->fitto);
280 self->fitw = gtk_spin_button_new(
281 GTK_ADJUSTMENT(gtk_adjustment_new(1, 1, 1000, 1, 10, 10)), 1, 0);
282 gtk_widget_set_sensitive(self->fitw, FALSE);
283 gtk_table_attach(GTK_TABLE(table), self->fitw, 1,2, 1,2,
284 GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
285 gtk_widget_show(self->fitw);
287 wid = gtk_label_new(_("by"));
288 gtk_misc_set_padding(GTK_MISC(wid), 5, 0);
289 gtk_table_attach(GTK_TABLE(table), wid, 2,3, 1,2,
290 GTK_FILL, GTK_FILL|GTK_EXPAND, 0, 0);
291 gtk_widget_show(wid);
293 self->fith = gtk_spin_button_new(
294 GTK_ADJUSTMENT(gtk_adjustment_new(1, 1, 1000, 1, 10, 10)), 1, 0);
295 gtk_widget_set_sensitive(self->fith, FALSE);
296 gtk_table_attach(GTK_TABLE(table), self->fith, 3,4, 1,2,
297 GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
298 gtk_widget_show(self->fith);
300 /* the drawing area */
301 self->darea = gtk_drawing_area_new();
302 gtk_table_attach(GTK_TABLE(self), self->darea, 1,2, 1,3,
303 GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
304 gtk_widget_show(self->darea);
306 /* connect the signal handlers */
307 g_signal_connect_swapped(GTK_OBJECT(self->orient_portrait), "toggled",
308 G_CALLBACK(orient_changed), GTK_OBJECT(self));
310 g_signal_connect_swapped(GTK_OBJECT(self->tmargin), "changed",
311 G_CALLBACK(margin_changed), GTK_OBJECT(self));
312 g_signal_connect_swapped(GTK_OBJECT(self->bmargin), "changed",
313 G_CALLBACK(margin_changed), GTK_OBJECT(self));
314 g_signal_connect_swapped(GTK_OBJECT(self->lmargin), "changed",
315 G_CALLBACK(margin_changed), GTK_OBJECT(self));
316 g_signal_connect_swapped(GTK_OBJECT(self->rmargin), "changed",
317 G_CALLBACK(margin_changed), GTK_OBJECT(self));
319 g_signal_connect_swapped(GTK_OBJECT(self->fitto), "toggled",
320 G_CALLBACK(scalemode_changed),
321 GTK_OBJECT(self));
322 g_signal_connect_swapped(GTK_OBJECT(self->scaling), "changed",
323 G_CALLBACK(scale_changed), GTK_OBJECT(self));
324 g_signal_connect_swapped(GTK_OBJECT(self->fitw), "changed",
325 G_CALLBACK(scale_changed), GTK_OBJECT(self));
326 g_signal_connect_swapped(GTK_OBJECT(self->fith), "changed",
327 G_CALLBACK(scale_changed), GTK_OBJECT(self));
329 g_signal_connect_swapped(GTK_OBJECT(self->darea), "size_allocate",
330 G_CALLBACK(darea_size_allocate),
331 GTK_OBJECT(self));
332 g_signal_connect_swapped(GTK_OBJECT(self->darea), "expose_event",
333 G_CALLBACK(darea_expose_event),
334 GTK_OBJECT(self));
336 gdk_color_white(gtk_widget_get_colormap(GTK_WIDGET(self)), &self->white);
337 gdk_color_black(gtk_widget_get_colormap(GTK_WIDGET(self)), &self->black);
338 self->blue.red = 0;
339 self->blue.green = 0;
340 self->blue.blue = 0x7fff;
341 gdk_color_alloc(gtk_widget_get_colormap(GTK_WIDGET(self)), &self->blue);
343 self->gc = NULL;
344 self->block_changed = FALSE;
347 GtkWidget *
348 dia_page_layout_new(void)
350 DiaPageLayout *self = gtk_type_new(dia_page_layout_get_type());
352 dia_page_layout_set_paper(self, "");
353 return GTK_WIDGET(self);
356 const gchar *
357 dia_page_layout_get_paper(DiaPageLayout *self)
359 return get_paper_name(self->papernum);
362 void
363 dia_page_layout_set_paper(DiaPageLayout *self, const gchar *paper)
365 gint i;
367 i = find_paper(paper);
368 if (i == -1)
369 i = find_paper(prefs.new_diagram.papertype);
370 gtk_option_menu_set_history(GTK_OPTION_MENU(self->paper_size), i);
371 gtk_menu_item_activate(
372 GTK_MENU_ITEM(GTK_OPTION_MENU(self->paper_size)->menu_item));
375 void
376 dia_page_layout_get_margins(DiaPageLayout *self,
377 gfloat *tmargin, gfloat *bmargin,
378 gfloat *lmargin, gfloat *rmargin)
380 if (tmargin)
381 *tmargin = dia_unit_spinner_get_value(DIA_UNIT_SPINNER(self->tmargin));
382 if (bmargin)
383 *bmargin = dia_unit_spinner_get_value(DIA_UNIT_SPINNER(self->bmargin));
384 if (lmargin)
385 *lmargin = dia_unit_spinner_get_value(DIA_UNIT_SPINNER(self->lmargin));
386 if (rmargin)
387 *rmargin = dia_unit_spinner_get_value(DIA_UNIT_SPINNER(self->rmargin));
390 void
391 dia_page_layout_set_margins(DiaPageLayout *self,
392 gfloat tmargin, gfloat bmargin,
393 gfloat lmargin, gfloat rmargin)
395 self->block_changed = TRUE;
396 dia_unit_spinner_set_value(DIA_UNIT_SPINNER(self->tmargin), tmargin);
397 dia_unit_spinner_set_value(DIA_UNIT_SPINNER(self->bmargin), bmargin);
398 dia_unit_spinner_set_value(DIA_UNIT_SPINNER(self->lmargin), lmargin);
399 dia_unit_spinner_set_value(DIA_UNIT_SPINNER(self->rmargin), rmargin);
400 self->block_changed = FALSE;
402 gtk_signal_emit(GTK_OBJECT(self), pl_signals[CHANGED]);
405 DiaPageOrientation
406 dia_page_layout_get_orientation(DiaPageLayout *self)
408 if (GTK_TOGGLE_BUTTON(self->orient_portrait)->active)
409 return DIA_PAGE_ORIENT_PORTRAIT;
410 else
411 return DIA_PAGE_ORIENT_LANDSCAPE;
414 void
415 dia_page_layout_set_orientation(DiaPageLayout *self,
416 DiaPageOrientation orient)
418 switch (orient) {
419 case DIA_PAGE_ORIENT_PORTRAIT:
420 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->orient_portrait),
421 TRUE);
422 break;
423 case DIA_PAGE_ORIENT_LANDSCAPE:
424 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->orient_landscape),
425 TRUE);
426 break;
430 gboolean
431 dia_page_layout_get_fitto(DiaPageLayout *self)
433 return GTK_TOGGLE_BUTTON(self->fitto)->active;
436 void
437 dia_page_layout_set_fitto(DiaPageLayout *self, gboolean fitto)
439 if (fitto)
440 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->fitto), TRUE);
441 else
442 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->scale), TRUE);
445 gfloat
446 dia_page_layout_get_scaling(DiaPageLayout *self)
448 return GTK_SPIN_BUTTON(self->scaling)->adjustment->value / 100.0;
451 void
452 dia_page_layout_set_scaling(DiaPageLayout *self, gfloat scaling)
454 GTK_SPIN_BUTTON(self->scaling)->adjustment->value = scaling * 100.0;
455 gtk_adjustment_value_changed(GTK_SPIN_BUTTON(self->scaling)->adjustment);
458 void
459 dia_page_layout_get_fit_dims(DiaPageLayout *self, gint *w, gint *h)
461 if (w)
462 *w = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(self->fitw));
463 if (h)
464 *h = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(self->fith));
467 void
468 dia_page_layout_set_fit_dims(DiaPageLayout *self, gint w, gint h)
470 gtk_spin_button_set_value(GTK_SPIN_BUTTON(self->fitw), w);
471 gtk_spin_button_set_value(GTK_SPIN_BUTTON(self->fith), h);
474 void
475 dia_page_layout_get_effective_area(DiaPageLayout *self, gfloat *width,
476 gfloat *height)
478 gfloat h, w, scaling;
480 if (GTK_TOGGLE_BUTTON(self->orient_portrait)->active) {
481 w = get_paper_pswidth(self->papernum);
482 h = get_paper_psheight(self->papernum);
483 } else {
484 h = get_paper_pswidth(self->papernum);
485 w = get_paper_psheight(self->papernum);
487 h -= dia_unit_spinner_get_value(DIA_UNIT_SPINNER(self->tmargin));
488 g_return_if_fail (h > 0.0);
489 h -= dia_unit_spinner_get_value(DIA_UNIT_SPINNER(self->bmargin));
490 g_return_if_fail (h > 0.0);
491 w -= dia_unit_spinner_get_value(DIA_UNIT_SPINNER(self->lmargin));
492 g_return_if_fail (w > 0.0);
493 w -= dia_unit_spinner_get_value(DIA_UNIT_SPINNER(self->rmargin));
494 g_return_if_fail (w > 0.0);
495 scaling = GTK_SPIN_BUTTON(self->scaling)->adjustment->value / 100.0;
496 h /= scaling;
497 w /= scaling;
499 if (width) *width = w;
500 if (height) *height = h;
503 void
504 dia_page_layout_get_paper_size(const gchar *paper,
505 gfloat *width, gfloat *height)
507 gint i;
509 i = find_paper(paper);
510 if (i == -1)
511 i = find_paper(prefs.new_diagram.papertype);
512 if (width)
513 *width = get_paper_pswidth(i);
514 if (height)
515 *height = get_paper_psheight(i);
518 void
519 dia_page_layout_get_default_margins(const gchar *paper,
520 gfloat *tmargin, gfloat *bmargin,
521 gfloat *lmargin, gfloat *rmargin)
523 gint i;
525 i = find_paper(paper);
526 if (i == -1)
527 i = find_paper(prefs.new_diagram.papertype);
528 if (tmargin)
529 *tmargin = get_paper_tmargin(i);
530 if (bmargin)
531 *bmargin = get_paper_bmargin(i);
532 if (lmargin)
533 *lmargin = get_paper_lmargin(i);
534 if (rmargin)
535 *rmargin = get_paper_rmargin(i);
538 static void
539 size_page(DiaPageLayout *self, GtkAllocation *a)
541 self->width = a->width - 3;
542 self->height = a->height - 3;
544 /* change to correct metrics */
545 if (GTK_TOGGLE_BUTTON(self->orient_portrait)->active) {
546 if (self->width * get_paper_psheight(self->papernum) >
547 self->height * get_paper_pswidth(self->papernum))
548 self->width = self->height * get_paper_pswidth(self->papernum) /
549 get_paper_psheight(self->papernum);
550 else
551 self->height = self->width * get_paper_psheight(self->papernum) /
552 get_paper_pswidth(self->papernum);
553 } else {
554 if (self->width * get_paper_pswidth(self->papernum) >
555 self->height * get_paper_psheight(self->papernum))
556 self->width = self->height * get_paper_psheight(self->papernum) /
557 get_paper_pswidth(self->papernum);
558 else
559 self->height = self->width * get_paper_pswidth(self->papernum) /
560 get_paper_psheight(self->papernum);
563 self->x = (a->width - self->width - 3) / 2;
564 self->y = (a->height - self->height - 3) / 2;
567 static void
568 darea_size_allocate(DiaPageLayout *self, GtkAllocation *allocation)
570 size_page(self, allocation);
573 static gint
574 darea_expose_event(DiaPageLayout *self, GdkEventExpose *event)
576 GdkWindow *window= self->darea->window;
577 gfloat val;
578 gint num;
580 if (!window)
581 return FALSE;
583 if (!self->gc)
584 self->gc = gdk_gc_new(window);
586 gdk_window_clear_area (window,
587 0, 0,
588 self->darea->allocation.width,
589 self->darea->allocation.height);
591 /* draw the page image */
592 gdk_gc_set_foreground(self->gc, &self->black);
593 gdk_draw_rectangle(window, self->gc, TRUE, self->x+3, self->y+3,
594 self->width, self->height);
595 gdk_gc_set_foreground(self->gc, &self->white);
596 gdk_draw_rectangle(window, self->gc, TRUE, self->x, self->y,
597 self->width, self->height);
598 gdk_gc_set_foreground(self->gc, &self->black);
599 gdk_draw_rectangle(window, self->gc, FALSE, self->x, self->y,
600 self->width-1, self->height-1);
602 gdk_gc_set_foreground(self->gc, &self->blue);
604 /* draw margins */
605 if (GTK_TOGGLE_BUTTON(self->orient_portrait)->active) {
606 val = dia_unit_spinner_get_value(DIA_UNIT_SPINNER(self->tmargin));
607 num = self->y + val * self->height /get_paper_psheight(self->papernum);
608 gdk_draw_line(window, self->gc, self->x+1, num, self->x+self->width-2,num);
610 val = dia_unit_spinner_get_value(DIA_UNIT_SPINNER(self->bmargin));
611 num = self->y + self->height -
612 val * self->height / get_paper_psheight(self->papernum);
613 gdk_draw_line(window, self->gc, self->x+1, num, self->x+self->width-2,num);
615 val = dia_unit_spinner_get_value(DIA_UNIT_SPINNER(self->lmargin));
616 num = self->x + val * self->width / get_paper_pswidth(self->papernum);
617 gdk_draw_line(window, self->gc, num, self->y+1,num,self->y+self->height-2);
619 val = dia_unit_spinner_get_value(DIA_UNIT_SPINNER(self->rmargin));
620 num = self->x + self->width -
621 val * self->width / get_paper_pswidth(self->papernum);
622 gdk_draw_line(window, self->gc, num, self->y+1,num,self->y+self->height-2);
623 } else {
624 val = dia_unit_spinner_get_value(DIA_UNIT_SPINNER(self->tmargin));
625 num = self->y + val * self->height /get_paper_pswidth(self->papernum);
626 gdk_draw_line(window, self->gc, self->x+1, num, self->x+self->width-2,num);
628 val = dia_unit_spinner_get_value(DIA_UNIT_SPINNER(self->bmargin));
629 num = self->y + self->height -
630 val * self->height / get_paper_pswidth(self->papernum);
631 gdk_draw_line(window, self->gc, self->x+1, num, self->x+self->width-2,num);
633 val = dia_unit_spinner_get_value(DIA_UNIT_SPINNER(self->lmargin));
634 num = self->x + val * self->width / get_paper_psheight(self->papernum);
635 gdk_draw_line(window, self->gc, num, self->y+1,num,self->y+self->height-2);
637 val = dia_unit_spinner_get_value(DIA_UNIT_SPINNER(self->rmargin));
638 num = self->x + self->width -
639 val * self->width / get_paper_psheight(self->papernum);
640 gdk_draw_line(window, self->gc, num, self->y+1,num,self->y+self->height-2);
643 return FALSE;
647 * \brief given a (page) size calculate the maximum margin size from it
649 * The function calculation assumes that more than half the size is not useful
650 * for the margin. For safety it allows a little less.
652 static float
653 max_margin (float size)
655 return size / 2.0 - 0.5;
658 static void
659 paper_size_change(GtkMenuItem *item, DiaPageLayout *self)
661 gchar buf[512];
663 self->papernum = GPOINTER_TO_INT(gtk_object_get_user_data(GTK_OBJECT(item)));
664 size_page(self, &self->darea->allocation);
665 gtk_widget_queue_draw(self->darea);
667 self->block_changed = TRUE;
668 dia_unit_spinner_set_value(DIA_UNIT_SPINNER(self->tmargin),
669 get_paper_tmargin(self->papernum));
670 dia_unit_spinner_set_value(DIA_UNIT_SPINNER(self->bmargin),
671 get_paper_bmargin(self->papernum));
672 dia_unit_spinner_set_value(DIA_UNIT_SPINNER(self->lmargin),
673 get_paper_lmargin(self->papernum));
674 dia_unit_spinner_set_value(DIA_UNIT_SPINNER(self->rmargin),
675 get_paper_rmargin(self->papernum));
677 if (GTK_TOGGLE_BUTTON(self->orient_portrait)->active) {
678 gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->tmargin))->upper =
679 max_margin(get_paper_psheight(self->papernum));
680 gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->bmargin))->upper =
681 max_margin(get_paper_psheight(self->papernum));
682 gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->lmargin))->upper =
683 max_margin(get_paper_pswidth(self->papernum));
684 gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->rmargin))->upper =
685 max_margin(get_paper_pswidth(self->papernum));
686 } else {
687 gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->tmargin))->upper =
688 max_margin(get_paper_pswidth(self->papernum));
689 gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->bmargin))->upper =
690 max_margin(get_paper_pswidth(self->papernum));
691 gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->lmargin))->upper =
692 max_margin(get_paper_psheight(self->papernum));
693 gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->rmargin))->upper =
694 max_margin(get_paper_psheight(self->papernum));
696 self->block_changed = FALSE;
698 g_snprintf(buf, sizeof(buf), _("%0.3gcm x %0.3gcm"),
699 get_paper_pswidth(self->papernum),
700 get_paper_psheight(self->papernum));
701 gtk_label_set(GTK_LABEL(self->paper_label), buf);
703 gtk_signal_emit(GTK_OBJECT(self), pl_signals[CHANGED]);
706 static void
707 orient_changed(DiaPageLayout *self)
709 size_page(self, &self->darea->allocation);
710 gtk_widget_queue_draw(self->darea);
712 if (GTK_TOGGLE_BUTTON(self->orient_portrait)->active) {
713 gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->tmargin))->upper =
714 max_margin(get_paper_psheight(self->papernum));
715 gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->bmargin))->upper =
716 max_margin(get_paper_psheight(self->papernum));
717 gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->lmargin))->upper =
718 max_margin(get_paper_pswidth(self->papernum));
719 gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->rmargin))->upper =
720 max_margin(get_paper_pswidth(self->papernum));
721 } else {
722 gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->tmargin))->upper =
723 max_margin(get_paper_pswidth(self->papernum));
724 gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->bmargin))->upper =
725 max_margin(get_paper_pswidth(self->papernum));
726 gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->lmargin))->upper =
727 max_margin(get_paper_psheight(self->papernum));
728 gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(self->rmargin))->upper =
729 max_margin(get_paper_psheight(self->papernum));
732 if (!self->block_changed)
733 gtk_signal_emit(GTK_OBJECT(self), pl_signals[CHANGED]);
736 static void
737 margin_changed(DiaPageLayout *self)
739 gtk_widget_queue_draw(self->darea);
740 if (!self->block_changed)
741 gtk_signal_emit(GTK_OBJECT(self), pl_signals[CHANGED]);
744 static void
745 scalemode_changed(DiaPageLayout *self)
747 if (GTK_TOGGLE_BUTTON(self->fitto)->active) {
748 gtk_widget_set_sensitive(self->scaling, FALSE);
749 gtk_widget_set_sensitive(self->fitw, TRUE);
750 gtk_widget_set_sensitive(self->fith, TRUE);
751 } else {
752 gtk_widget_set_sensitive(self->scaling, TRUE);
753 gtk_widget_set_sensitive(self->fitw, FALSE);
754 gtk_widget_set_sensitive(self->fith, FALSE);
756 if (!self->block_changed)
757 gtk_signal_emit(GTK_OBJECT(self), pl_signals[CHANGED]);
760 static void
761 scale_changed(DiaPageLayout *self)
763 if (!self->block_changed)
764 gtk_signal_emit(GTK_OBJECT(self), pl_signals[CHANGED]);
767 static void
768 dia_page_layout_destroy(GtkObject *object)
770 DiaPageLayout *self = DIA_PAGE_LAYOUT(object);
772 if (self->gc) {
773 gdk_gc_unref(self->gc);
774 self->gc = NULL;
777 if (parent_class->destroy)
778 (* parent_class->destroy)(object);
781 #ifdef PAGELAYOUT_TEST
783 void
784 changed_signal(DiaPageLayout *self)
786 g_message("changed");
788 void
789 fittopage_signal(DiaPageLayout *self)
791 g_message("fit to page");
794 void
795 main(int argc, char **argv)
797 GtkWidget *win, *pl;
799 gtk_init(&argc, &argv);
801 win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
802 gtk_window_set_title(GTK_WINDOW(win), _("Page Setup"));
803 g_signal_connect(GTK_OBJECT(win), "destroy",
804 G_CALLBACK(gtk_main_quit), NULL);
806 pl = dia_page_layout_new();
807 gtk_container_set_border_width(GTK_CONTAINER(pl), 5);
808 gtk_container_add(GTK_CONTAINER(win), pl);
809 gtk_widget_show(pl);
811 g_signal_connect(GTK_OBJECT(pl), "changed",
812 G_CALLBACK(changed_signal), NULL);
813 g_signal_connect(GTK_OBJECT(pl), "fittopage",
814 G_CALLBACK(fittopage_signal), NULL);
816 gtk_widget_show(win);
817 gtk_main();
820 #endif