offset fixes, admit to textline, proper updating of height/font at attr set,
[dia.git] / app / pagesetup.c
blobef9d6101bedb238d972d5a8efc5385f71a105380
1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998, 1999 Alexander Larsson
4 * pagesetup.[ch] -- code for the page setup dialog
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 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
26 #include <gtk/gtk.h>
28 #include <math.h>
30 #include "pagesetup.h"
31 #include "intl.h"
32 #include "diapagelayout.h"
34 typedef struct _PageSetup PageSetup;
35 struct _PageSetup {
36 Diagram *dia;
37 GtkWidget *window;
38 GtkWidget *paper;
39 gboolean changed;
42 static void pagesetup_changed (GtkWidget *wid, PageSetup *ps);
43 static void pagesetup_apply (GtkWidget *wid, PageSetup *ps);
45 static gint
46 pagesetup_respond(GtkWidget *widget,
47 gint response_id,
48 gpointer data)
50 PageSetup *ps = (PageSetup *)data;
52 if ( response_id == GTK_RESPONSE_APPLY
53 || response_id == GTK_RESPONSE_OK) {
54 if (ps->changed)
55 pagesetup_apply(widget, ps);
58 if (response_id != GTK_RESPONSE_APPLY) {
59 g_object_unref(ps->dia);
60 gtk_widget_destroy(ps->window);
63 return 0;
66 void
67 create_page_setup_dlg(Diagram *dia)
69 PageSetup *ps;
70 GtkWidget *vbox;
72 ps = g_new(PageSetup, 1);
73 ps->dia = dia;
74 g_object_ref(ps->dia);
75 ps->window = gtk_dialog_new_with_buttons(
76 _("Page Setup"),
77 GTK_WINDOW (ddisplay_active()->shell),
78 GTK_DIALOG_DESTROY_WITH_PARENT,
79 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
80 GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
81 GTK_STOCK_OK, GTK_RESPONSE_OK,
82 NULL);
83 gtk_dialog_set_default_response (GTK_DIALOG(ps->window), GTK_RESPONSE_OK);
84 vbox = GTK_DIALOG(ps->window)->vbox;
85 gtk_dialog_set_response_sensitive(GTK_DIALOG(ps->window), GTK_RESPONSE_APPLY, FALSE);
86 ps->changed = FALSE;
88 g_signal_connect(G_OBJECT (ps->window), "response",
89 G_CALLBACK (pagesetup_respond), ps);
91 /* destroy ps when the dialog is closed */
92 gtk_object_set_data_full(GTK_OBJECT(ps->window), "pagesetup", ps,
93 (GtkDestroyNotify)g_free);
95 ps->paper = dia_page_layout_new();
96 dia_page_layout_set_paper(DIA_PAGE_LAYOUT(ps->paper), dia->data->paper.name);
97 dia_page_layout_set_margins(DIA_PAGE_LAYOUT(ps->paper),
98 dia->data->paper.tmargin,
99 dia->data->paper.bmargin,
100 dia->data->paper.lmargin,
101 dia->data->paper.rmargin);
102 dia_page_layout_set_orientation(DIA_PAGE_LAYOUT(ps->paper),
103 dia->data->paper.is_portrait ? DIA_PAGE_ORIENT_PORTRAIT :
104 DIA_PAGE_ORIENT_LANDSCAPE);
105 dia_page_layout_set_scaling(DIA_PAGE_LAYOUT(ps->paper),
106 dia->data->paper.scaling);
107 dia_page_layout_set_fitto(DIA_PAGE_LAYOUT(ps->paper),
108 dia->data->paper.fitto);
109 dia_page_layout_set_fit_dims(DIA_PAGE_LAYOUT(ps->paper),
110 dia->data->paper.fitwidth,
111 dia->data->paper.fitheight);
113 gtk_container_set_border_width(GTK_CONTAINER(ps->paper), 5);
114 gtk_box_pack_start(GTK_BOX(vbox), ps->paper, TRUE, TRUE, 0);
115 gtk_widget_show(ps->paper);
117 g_signal_connect(GTK_OBJECT(ps->paper), "changed",
118 G_CALLBACK(pagesetup_changed), ps);
120 gtk_widget_show(ps->window);
123 static void
124 pagesetup_changed(GtkWidget *wid, PageSetup *ps)
126 gfloat dwidth, dheight;
127 gfloat pwidth, pheight;
128 gfloat xscale, yscale;
129 gint fitw = 0, fith = 0;
130 gfloat cur_scaling;
132 /* set sensitivity on apply button */
133 gtk_dialog_set_response_sensitive(GTK_DIALOG(ps->window), GTK_RESPONSE_APPLY, TRUE);
134 ps->changed = TRUE;
136 dwidth = ps->dia->data->extents.right - ps->dia->data->extents.left;
137 dheight = ps->dia->data->extents.bottom - ps->dia->data->extents.top;
139 if (dwidth <= 0.0 || dheight <= 0.0)
140 return;
142 DIA_PAGE_LAYOUT(ps->paper)->block_changed = TRUE;
144 cur_scaling = dia_page_layout_get_scaling(DIA_PAGE_LAYOUT(ps->paper));
145 dia_page_layout_get_effective_area(DIA_PAGE_LAYOUT(ps->paper),
146 &pwidth, &pheight);
147 g_return_if_fail (pwidth > 0.0 && pheight > 0.0);
148 pwidth *= cur_scaling;
149 pheight *= cur_scaling;
151 if (dia_page_layout_get_fitto(DIA_PAGE_LAYOUT(ps->paper))) {
152 dia_page_layout_get_fit_dims(DIA_PAGE_LAYOUT(ps->paper), &fitw, &fith);
153 xscale = fitw * pwidth / dwidth;
154 yscale = fith * pheight / dheight;
155 dia_page_layout_set_scaling(DIA_PAGE_LAYOUT(ps->paper),
156 MIN(xscale, yscale));
157 } else {
158 fitw = ceil(dwidth * cur_scaling / pwidth);
159 fith = ceil(dheight * cur_scaling / pheight);
160 dia_page_layout_set_fit_dims(DIA_PAGE_LAYOUT(ps->paper), fitw, fith);
163 DIA_PAGE_LAYOUT(ps->paper)->block_changed = FALSE;
166 /* This affects the actual setup. It should only be called when
167 something has in fact changed.
169 static void
170 pagesetup_apply(GtkWidget *wid, PageSetup *ps)
172 g_free(ps->dia->data->paper.name);
173 ps->dia->data->paper.name =
174 g_strdup(dia_page_layout_get_paper(DIA_PAGE_LAYOUT(ps->paper)));
176 dia_page_layout_get_margins(DIA_PAGE_LAYOUT(ps->paper),
177 &ps->dia->data->paper.tmargin,
178 &ps->dia->data->paper.bmargin,
179 &ps->dia->data->paper.lmargin,
180 &ps->dia->data->paper.rmargin);
182 ps->dia->data->paper.is_portrait =
183 dia_page_layout_get_orientation(DIA_PAGE_LAYOUT(ps->paper)) ==
184 DIA_PAGE_ORIENT_PORTRAIT;
185 ps->dia->data->paper.scaling =
186 dia_page_layout_get_scaling(DIA_PAGE_LAYOUT(ps->paper));
188 ps->dia->data->paper.fitto = dia_page_layout_get_fitto(
189 DIA_PAGE_LAYOUT(ps->paper));
190 dia_page_layout_get_fit_dims(DIA_PAGE_LAYOUT(ps->paper),
191 &ps->dia->data->paper.fitwidth,
192 &ps->dia->data->paper.fitheight);
194 dia_page_layout_get_effective_area(DIA_PAGE_LAYOUT(ps->paper),
195 &ps->dia->data->paper.width,
196 &ps->dia->data->paper.height);
198 /* set sensitivity on apply button */
199 gtk_dialog_set_response_sensitive(GTK_DIALOG(ps->window), GTK_RESPONSE_APPLY, FALSE);
200 ps->changed = FALSE;
202 /* update diagram -- this is needed to reposition page boundaries */
203 diagram_set_modified(ps->dia, TRUE);
204 diagram_add_update_all(ps->dia);
205 diagram_flush(ps->dia);