]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormGraphics.C
change X-windows to X window
[lyx.git] / src / frontends / xforms / FormGraphics.C
1 /* This file is part of
2  * ====================================================== 
3  *
4  *           LyX, The Document Processor
5  *
6  *           Copyright 2000-2001 The LyX Team.
7  *
8  * ======================================================
9  *
10  * \file FormGraphics.C
11  * \author Baruch Even, baruch.even@writeme.com
12  */
13
14 #include <config.h> 
15
16 #ifdef __GNUG__
17 #pragma implementation
18 #endif 
19
20 #include "xformsBC.h"
21 #include "ControlGraphics.h"
22 #include "FormGraphics.h"
23 #include "form_graphics.h"
24
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
32
33 using std::endl;
34
35 static double const tol = 1.0e-08;
36
37 typedef FormCB<ControlGraphics, FormDB<FD_form_graphics> > base_class;
38
39 FormGraphics::FormGraphics(ControlGraphics & c)
40         : base_class(c, _("Graphics"))
41 {}
42
43
44 void FormGraphics::build()
45 {
46         dialog_.reset(build_graphics());
47
48         // This is the place to add settings of the dialog that did not go
49         // to the .fd file.
50
51         // Set the input widgets to issue a callback to input() whenever
52         // they change, so we can verify their content.
53         fl_set_input_return (dialog_->input_filename,     FL_RETURN_CHANGED);
54         fl_set_input_return (dialog_->input_scale,        FL_RETURN_CHANGED);
55         fl_set_input_return (dialog_->input_width,        FL_RETURN_CHANGED);
56         fl_set_input_return (dialog_->input_height,       FL_RETURN_CHANGED);
57         fl_set_input_return (dialog_->input_rotate_angle, FL_RETURN_CHANGED);
58         fl_set_input_return (dialog_->input_subcaption,   FL_RETURN_CHANGED);
59
60         // Set the maximum characters that can be written in the input texts.
61         fl_set_input_maxchars(dialog_->input_scale,        SCALE_MAXDIGITS);
62         fl_set_input_maxchars(dialog_->input_width,        WIDTH_MAXDIGITS);
63         fl_set_input_maxchars(dialog_->input_height,       HEIGHT_MAXDIGITS);
64         fl_set_input_maxchars(dialog_->input_filename,     FILENAME_MAXCHARS);
65         fl_set_input_maxchars(dialog_->input_rotate_angle, ROTATE_MAXCHARS);
66
67         // Set input filter on width and height to make them accept only
68         // unsigned numbers.
69         fl_set_input_filter(dialog_->input_scale,  fl_unsigned_float_filter);
70         fl_set_input_filter(dialog_->input_width,  fl_unsigned_float_filter);
71         fl_set_input_filter(dialog_->input_height, fl_unsigned_float_filter);
72
73         // Set input filter on rotate_angle to make it accept only
74         // floating point numbers.
75         fl_set_input_filter(dialog_->input_rotate_angle, fl_float_filter);
76
77         // Create the contents of the choices
78         string const width = " cm | inch | page %% | column %% ";
79         fl_addto_choice(dialog_->choice_width_units, width.c_str());
80
81         string const height = " cm | inch | page %% ";
82         fl_addto_choice(dialog_->choice_height_units, height.c_str());
83
84         // Manage the ok, apply, restore and cancel/close buttons
85         bc().setOK(dialog_->button_ok);
86         bc().setApply(dialog_->button_apply);
87         bc().setCancel(dialog_->button_cancel);
88         bc().setRestore(dialog_->button_restore);
89
90         bc().addReadOnly(dialog_->input_filename);
91         bc().addReadOnly(dialog_->button_browse);
92         bc().addReadOnly(dialog_->check_display);
93         bc().addReadOnly(dialog_->input_scale);
94         bc().addReadOnly(dialog_->input_width);
95         bc().addReadOnly(dialog_->choice_width_units);
96         bc().addReadOnly(dialog_->input_height);
97         bc().addReadOnly(dialog_->choice_height_units);
98         bc().addReadOnly(dialog_->input_rotate_angle);
99         bc().addReadOnly(dialog_->input_subcaption);
100         bc().addReadOnly(dialog_->check_subcaption);
101 }
102
103
104 void FormGraphics::apply()
105 {
106         // Create the parameters structure and fill the data from the dialog.
107         InsetGraphicsParams & igp = controller().params();
108
109         igp.filename = fl_get_input(dialog_->input_filename);
110
111         if (lyxrc.display_graphics == "no") {
112                 igp.display = InsetGraphicsParams::NONE;
113
114         } else {
115                 if (fl_get_button(dialog_->check_display)) {
116                         if (lyxrc.display_graphics == "mono") {
117                                 igp.display = InsetGraphicsParams::MONOCHROME;
118                         } else if (lyxrc.display_graphics == "gray") {
119                                 igp.display = InsetGraphicsParams::GRAYSCALE;
120                         } else if (lyxrc.display_graphics == "color") {
121                                 igp.display = InsetGraphicsParams::COLOR;
122                         }
123                         
124                 } else {
125                         igp.display = InsetGraphicsParams::NONE;
126                 }
127         }
128
129         double const scale =
130                 strToDbl(strip(fl_get_input(dialog_->input_scale)));
131         if (scale < tol) {
132                 double const width =
133                         strToDbl(strip(fl_get_input(dialog_->input_width)));
134
135                 if (width < tol) {
136                         igp.widthResize = InsetGraphicsParams::DEFAULT_SIZE;
137                         igp.widthSize   = 0.0;
138                 } else {
139                         switch (fl_get_choice(dialog_->choice_width_units)) {
140                         case 2:
141                                 igp.widthResize = InsetGraphicsParams::INCH;
142                                 break;
143                         case 3:
144                                 igp.widthResize =
145                                         InsetGraphicsParams::PERCENT_PAGE;
146                                 break;
147                         case 4:
148                                 igp.widthResize =
149                                         InsetGraphicsParams::PERCENT_COLUMN;
150                                 break;
151                         default:
152                                 igp.widthResize = InsetGraphicsParams::CM;
153                                 break;
154                         }
155                         igp.widthSize = width;
156                 }
157                 
158                 double const height =
159                         strToDbl(strip(fl_get_input(dialog_->input_height)));
160                 
161                 if (height < tol) {
162                         igp.heightResize = InsetGraphicsParams::DEFAULT_SIZE;
163                         igp.heightSize   = 0.0;
164                 } else {
165                         switch (fl_get_choice(dialog_->choice_height_units)) {
166                         case 2:
167                                 igp.heightResize = InsetGraphicsParams::INCH;
168                                 break;
169                         case 3:
170                                 igp.heightResize =
171                                         InsetGraphicsParams::PERCENT_PAGE;
172                                 break;
173                         default:
174                                 igp.heightResize = InsetGraphicsParams::CM;
175                                 break;
176                         }
177                         igp.heightSize = height;
178                 }
179                 
180         } else {
181                 igp.widthResize  = InsetGraphicsParams::DEFAULT_SIZE;
182                 igp.widthSize    = 0.0;
183                 igp.heightResize = InsetGraphicsParams::SCALE;
184                 igp.heightSize   = scale;
185         }
186         
187         igp.rotateAngle =
188                 strToDbl(strip(fl_get_input(dialog_->input_rotate_angle)));
189         while (igp.rotateAngle < 0.0 || igp.rotateAngle > 360.0) {
190                 if (igp.rotateAngle < 0.0) {
191                         igp.rotateAngle += 360.0;
192                 } else if (igp.rotateAngle > 360.0) {
193                         igp.rotateAngle -= 360.0;
194                 }
195         }
196
197         igp.subcaption = fl_get_button(dialog_->check_subcaption);
198         igp.subcaptionText = fl_get_input(dialog_->input_subcaption);
199
200         igp.testInvariant();
201 }
202
203
204 void FormGraphics::update()
205 {
206         // Update dialog with details from inset
207         InsetGraphicsParams & igp = controller().params();
208
209         // Update the filename input field
210         fl_set_input(dialog_->input_filename,
211                      igp.filename.c_str());
212
213         // To display or not to display
214         if (lyxrc.display_graphics == "no") {
215                 fl_set_button(dialog_->check_display, 0);
216         } else {
217                 if (igp.display == InsetGraphicsParams::NONE) {
218                         fl_set_button(dialog_->check_display, 0);
219                 } else {
220                         fl_set_button(dialog_->check_display, 1);
221                 }
222         }
223
224         setEnabled(dialog_->check_display, (lyxrc.display_graphics != "no"));
225
226         if (igp.heightResize == InsetGraphicsParams::SCALE) {
227                 string number = tostr(igp.heightSize);
228                 fl_set_input(dialog_->input_scale, number.c_str());
229                 fl_set_input(dialog_->input_width, "");
230                 fl_set_choice(dialog_->choice_width_units, 1);
231                 fl_set_input(dialog_->input_height, "");
232                 fl_set_choice(dialog_->choice_height_units, 1);
233
234         } else {
235                 fl_set_input(dialog_->input_scale, "");
236
237                 string number;
238                 if (igp.widthResize != InsetGraphicsParams::DEFAULT_SIZE) {
239                         number = tostr(igp.widthSize);
240                 }
241                 fl_set_input(dialog_->input_width, number.c_str());
242
243                 int pos = 1;
244                 switch (igp.widthResize) {
245                 case InsetGraphicsParams::INCH:
246                         pos = 2; break;
247
248                 case InsetGraphicsParams::PERCENT_PAGE:
249                         pos = 3; break;
250
251                 case InsetGraphicsParams::PERCENT_COLUMN:
252                         pos = 4; break;
253
254                 default:
255                         break;
256                 }
257                 fl_set_choice(dialog_->choice_width_units, pos);
258
259                 number.erase();
260                 if (igp.heightResize != InsetGraphicsParams::DEFAULT_SIZE) {
261                         number = tostr(igp.heightSize);
262                 }
263                 fl_set_input(dialog_->input_height, number.c_str());
264
265                 pos = 1;
266                 switch (igp.heightResize) {
267                 case InsetGraphicsParams::INCH:
268                         pos = 2; break;
269
270                 case InsetGraphicsParams::PERCENT_PAGE:
271                         pos = 3; break;
272
273                 default:
274                         break;
275                 }
276                 fl_set_choice(dialog_->choice_height_units, pos);
277         }
278                 
279         // Update the rotate angle
280         fl_set_input(dialog_->input_rotate_angle,
281                      tostr(igp.rotateAngle).c_str());
282
283         // Update the subcaption check button and input field
284         fl_set_button(dialog_->check_subcaption,
285                       igp.subcaption);
286         fl_set_input(dialog_->input_subcaption,
287                      igp.subcaptionText.c_str());
288
289         setEnabled(dialog_->input_subcaption,
290                    fl_get_button(dialog_->check_subcaption));
291 }
292
293
294 ButtonPolicy::SMInput FormGraphics::input(FL_OBJECT * ob, long)
295 {
296         if (ob == dialog_->button_browse) {
297                 // Get the filename from the dialog
298                 string const in_name = fl_get_input(dialog_->input_filename);
299                 string const out_name = controller().Browse(in_name);
300
301                 if (out_name != in_name && !out_name.empty()) {
302                         fl_set_input(dialog_->input_filename, out_name.c_str());
303                 }
304         }
305
306         if (ob == dialog_->input_scale) {
307                 double const scale =
308                         strToDbl(strip(fl_get_input(dialog_->input_scale)));
309                 if (scale > tol) {
310                         fl_set_input(dialog_->input_width, "");
311                         fl_set_choice(dialog_->choice_width_units, 1);
312                         fl_set_input(dialog_->input_height, "");
313                         fl_set_choice(dialog_->choice_height_units, 1);
314                 }
315         }
316
317         if (ob == dialog_->input_width || ob == dialog_->input_height) {
318                 double const width =
319                         strToDbl(strip(fl_get_input(dialog_->input_width)));
320                 double const height =
321                         strToDbl(strip(fl_get_input(dialog_->input_height)));
322
323                 if (width > tol || height > tol) {
324                         fl_set_input(dialog_->input_scale, "");
325                 }
326         }
327
328         if (ob == dialog_->check_subcaption) {
329                 setEnabled(dialog_->input_subcaption,
330                            fl_get_button(dialog_->check_subcaption));
331         }
332
333         return checkInput();
334 }
335
336
337 ButtonPolicy::SMInput FormGraphics::checkInput()
338 {
339         // Put verifications that the dialog shows some sane values,
340         // if not disallow clicking on ok/apply.
341         // Possibly use a label in the bottom of the dialog to give the reason.
342
343         ButtonPolicy::SMInput activate = ButtonPolicy::SMI_VALID;
344
345         // We verify now that there is a filename, it exists, it's a file
346         // and it's readable.
347         string filename = fl_get_input(dialog_->input_filename);
348         FileInfo file(filename);
349         if (filename.empty()
350                 || !file.isOK()
351                 || !file.exist()
352                 || !file.isRegular()
353                 || !file.readable()
354            )
355                 activate = ButtonPolicy::SMI_INVALID;
356
357         return activate;
358 }