1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 2000-2001 The LyX Team.
8 * ======================================================
10 * \file FormGraphics.C
11 * \author Baruch Even, baruch.even@writeme.com
17 #pragma implementation
21 #include "ControlGraphics.h"
22 #include "FormGraphics.h"
23 #include "form_graphics.h"
25 #include "xforms_helpers.h"
26 #include "input_validators.h"
27 #include "debug.h" // for lyxerr
28 #include "support/lstrings.h" // for strToDbl & tostr
29 #include "support/FileInfo.h" // for FileInfo
30 #include "insets/insetgraphicsParams.h"
31 #include "lyxrc.h" // for lyxrc.display_graphics
37 // Zero test for double precision numbers
38 double const tol = 1.0e-08;
40 // The maximum digits for the image scale
41 int const SCALE_MAXDIGITS = 3;
43 // The maximum digits for the image width
44 int const WIDTH_MAXDIGITS = 3;
46 // The maximum digits for the image height
47 int const HEIGHT_MAXDIGITS = 3;
49 // The max characters in the rotation angle (minus sign and 3 digits)
50 int const ROTATE_MAXCHARS = 4;
52 // The maximum characters in a filename.
53 int const FILENAME_MAXCHARS = 1024;
58 typedef FormCB<ControlGraphics, FormDB<FD_form_graphics> > base_class;
60 FormGraphics::FormGraphics(ControlGraphics & c)
61 : base_class(c, _("Graphics"))
65 void FormGraphics::build()
67 dialog_.reset(build_graphics());
69 // This is the place to add settings of the dialog that did not go
72 // Set the input widgets to issue a callback to input() whenever
73 // they change, so we can verify their content.
74 fl_set_input_return (dialog_->input_filename, FL_RETURN_CHANGED);
75 fl_set_input_return (dialog_->input_scale, FL_RETURN_CHANGED);
76 fl_set_input_return (dialog_->input_width, FL_RETURN_CHANGED);
77 fl_set_input_return (dialog_->input_height, FL_RETURN_CHANGED);
78 fl_set_input_return (dialog_->input_rotate_angle, FL_RETURN_CHANGED);
79 fl_set_input_return (dialog_->input_subcaption, FL_RETURN_CHANGED);
81 // Set the maximum characters that can be written in the input texts.
82 fl_set_input_maxchars(dialog_->input_scale, SCALE_MAXDIGITS);
83 fl_set_input_maxchars(dialog_->input_width, WIDTH_MAXDIGITS);
84 fl_set_input_maxchars(dialog_->input_height, HEIGHT_MAXDIGITS);
85 fl_set_input_maxchars(dialog_->input_filename, FILENAME_MAXCHARS);
86 fl_set_input_maxchars(dialog_->input_rotate_angle, ROTATE_MAXCHARS);
88 // Set input filter on width and height to make them accept only
90 fl_set_input_filter(dialog_->input_scale, fl_unsigned_float_filter);
91 fl_set_input_filter(dialog_->input_width, fl_unsigned_float_filter);
92 fl_set_input_filter(dialog_->input_height, fl_unsigned_float_filter);
94 // Set input filter on rotate_angle to make it accept only
95 // floating point numbers.
96 fl_set_input_filter(dialog_->input_rotate_angle, fl_float_filter);
98 // Create the contents of the choices
99 string const width = " cm | inch | page %% | column %% ";
100 fl_addto_choice(dialog_->choice_width_units, width.c_str());
102 string const height = " cm | inch | page %% ";
103 fl_addto_choice(dialog_->choice_height_units, height.c_str());
105 // Manage the ok, apply, restore and cancel/close buttons
106 bc().setOK(dialog_->button_ok);
107 bc().setApply(dialog_->button_apply);
108 bc().setCancel(dialog_->button_cancel);
109 bc().setRestore(dialog_->button_restore);
111 bc().addReadOnly(dialog_->input_filename);
112 bc().addReadOnly(dialog_->button_browse);
113 bc().addReadOnly(dialog_->check_display);
114 bc().addReadOnly(dialog_->input_scale);
115 bc().addReadOnly(dialog_->input_width);
116 bc().addReadOnly(dialog_->choice_width_units);
117 bc().addReadOnly(dialog_->input_height);
118 bc().addReadOnly(dialog_->choice_height_units);
119 bc().addReadOnly(dialog_->input_rotate_angle);
120 bc().addReadOnly(dialog_->input_subcaption);
121 bc().addReadOnly(dialog_->check_subcaption);
125 void FormGraphics::apply()
127 // Create the parameters structure and fill the data from the dialog.
128 InsetGraphicsParams & igp = controller().params();
130 igp.filename = fl_get_input(dialog_->input_filename);
132 if (lyxrc.display_graphics == "no") {
133 igp.display = InsetGraphicsParams::NONE;
136 if (fl_get_button(dialog_->check_display)) {
137 if (lyxrc.display_graphics == "mono") {
138 igp.display = InsetGraphicsParams::MONOCHROME;
139 } else if (lyxrc.display_graphics == "gray") {
140 igp.display = InsetGraphicsParams::GRAYSCALE;
141 } else if (lyxrc.display_graphics == "color") {
142 igp.display = InsetGraphicsParams::COLOR;
146 igp.display = InsetGraphicsParams::NONE;
151 strToDbl(strip(fl_get_input(dialog_->input_scale)));
154 strToDbl(strip(fl_get_input(dialog_->input_width)));
157 igp.widthResize = InsetGraphicsParams::DEFAULT_SIZE;
160 switch (fl_get_choice(dialog_->choice_width_units)) {
162 igp.widthResize = InsetGraphicsParams::INCH;
166 InsetGraphicsParams::PERCENT_PAGE;
170 InsetGraphicsParams::PERCENT_COLUMN;
173 igp.widthResize = InsetGraphicsParams::CM;
176 igp.widthSize = width;
179 double const height =
180 strToDbl(strip(fl_get_input(dialog_->input_height)));
183 igp.heightResize = InsetGraphicsParams::DEFAULT_SIZE;
184 igp.heightSize = 0.0;
186 switch (fl_get_choice(dialog_->choice_height_units)) {
188 igp.heightResize = InsetGraphicsParams::INCH;
192 InsetGraphicsParams::PERCENT_PAGE;
195 igp.heightResize = InsetGraphicsParams::CM;
198 igp.heightSize = height;
202 igp.widthResize = InsetGraphicsParams::DEFAULT_SIZE;
204 igp.heightResize = InsetGraphicsParams::SCALE;
205 igp.heightSize = scale;
209 strToDbl(strip(fl_get_input(dialog_->input_rotate_angle)));
210 while (igp.rotateAngle < 0.0 || igp.rotateAngle > 360.0) {
211 if (igp.rotateAngle < 0.0) {
212 igp.rotateAngle += 360.0;
213 } else if (igp.rotateAngle > 360.0) {
214 igp.rotateAngle -= 360.0;
218 igp.subcaption = fl_get_button(dialog_->check_subcaption);
219 igp.subcaptionText = fl_get_input(dialog_->input_subcaption);
225 void FormGraphics::update()
227 // Update dialog with details from inset
228 InsetGraphicsParams & igp = controller().params();
230 // Update the filename input field
231 fl_set_input(dialog_->input_filename,
232 igp.filename.c_str());
234 // To display or not to display
235 if (lyxrc.display_graphics == "no") {
236 fl_set_button(dialog_->check_display, 0);
238 if (igp.display == InsetGraphicsParams::NONE) {
239 fl_set_button(dialog_->check_display, 0);
241 fl_set_button(dialog_->check_display, 1);
245 setEnabled(dialog_->check_display, (lyxrc.display_graphics != "no"));
247 if (igp.heightResize == InsetGraphicsParams::SCALE) {
248 string number = tostr(igp.heightSize);
249 fl_set_input(dialog_->input_scale, number.c_str());
250 fl_set_input(dialog_->input_width, "");
251 fl_set_choice(dialog_->choice_width_units, 1);
252 fl_set_input(dialog_->input_height, "");
253 fl_set_choice(dialog_->choice_height_units, 1);
256 fl_set_input(dialog_->input_scale, "");
259 if (igp.widthResize != InsetGraphicsParams::DEFAULT_SIZE) {
260 number = tostr(igp.widthSize);
262 fl_set_input(dialog_->input_width, number.c_str());
265 switch (igp.widthResize) {
266 case InsetGraphicsParams::INCH:
269 case InsetGraphicsParams::PERCENT_PAGE:
272 case InsetGraphicsParams::PERCENT_COLUMN:
278 fl_set_choice(dialog_->choice_width_units, pos);
281 if (igp.heightResize != InsetGraphicsParams::DEFAULT_SIZE) {
282 number = tostr(igp.heightSize);
284 fl_set_input(dialog_->input_height, number.c_str());
287 switch (igp.heightResize) {
288 case InsetGraphicsParams::INCH:
291 case InsetGraphicsParams::PERCENT_PAGE:
297 fl_set_choice(dialog_->choice_height_units, pos);
300 // Update the rotate angle
301 fl_set_input(dialog_->input_rotate_angle,
302 tostr(igp.rotateAngle).c_str());
304 // Update the subcaption check button and input field
305 fl_set_button(dialog_->check_subcaption,
307 fl_set_input(dialog_->input_subcaption,
308 igp.subcaptionText.c_str());
310 setEnabled(dialog_->input_subcaption,
311 fl_get_button(dialog_->check_subcaption));
315 ButtonPolicy::SMInput FormGraphics::input(FL_OBJECT * ob, long)
317 if (ob == dialog_->button_browse) {
318 // Get the filename from the dialog
319 string const in_name = fl_get_input(dialog_->input_filename);
320 string const out_name = controller().Browse(in_name);
322 if (out_name != in_name && !out_name.empty()) {
323 fl_set_input(dialog_->input_filename, out_name.c_str());
327 if (ob == dialog_->input_scale) {
329 strToDbl(strip(fl_get_input(dialog_->input_scale)));
331 fl_set_input(dialog_->input_width, "");
332 fl_set_choice(dialog_->choice_width_units, 1);
333 fl_set_input(dialog_->input_height, "");
334 fl_set_choice(dialog_->choice_height_units, 1);
338 if (ob == dialog_->input_width || ob == dialog_->input_height) {
340 strToDbl(strip(fl_get_input(dialog_->input_width)));
341 double const height =
342 strToDbl(strip(fl_get_input(dialog_->input_height)));
344 if (width > tol || height > tol) {
345 fl_set_input(dialog_->input_scale, "");
349 if (ob == dialog_->check_subcaption) {
350 setEnabled(dialog_->input_subcaption,
351 fl_get_button(dialog_->check_subcaption));
358 ButtonPolicy::SMInput FormGraphics::checkInput()
360 // Put verifications that the dialog shows some sane values,
361 // if not disallow clicking on ok/apply.
362 // Possibly use a label in the bottom of the dialog to give the reason.
364 ButtonPolicy::SMInput activate = ButtonPolicy::SMI_VALID;
366 // We verify now that there is a filename, it exists, it's a file
367 // and it's readable.
368 string filename = fl_get_input(dialog_->input_filename);
369 FileInfo file(filename);
376 activate = ButtonPolicy::SMI_INVALID;