]> git.lyx.org Git - features.git/blob - src/frontends/xforms/FormGraphics.C
Baruch's graphics patch + some small tweaks to the buttoncontroller stuff
[features.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 "input_validators.h"
26 #include "debug.h" // for lyxerr
27 #include "support/lstrings.h"  // for strToDbl & tostr
28 #include "support/FileInfo.h"  // for FileInfo
29 #include "insets/insetgraphicsParams.h"
30
31 using std::endl;
32
33 typedef FormCB<ControlGraphics, FormDB<FD_form_graphics> > base_class;
34
35 FormGraphics::FormGraphics(ControlGraphics & c)
36         : base_class(c, _("Graphics")),
37           // The buttons c-tor values are the number of buttons we use
38           // This is only to reduce memory waste.
39           widthButtons(5), heightButtons(4), displayButtons(4),
40           last_image_path(".")
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_width,
54                               FL_RETURN_CHANGED);
55         fl_set_input_return (dialog_->input_height,
56                               FL_RETURN_CHANGED);
57         fl_set_input_return (dialog_->input_filename,
58                               FL_RETURN_CHANGED);
59         fl_set_input_return (dialog_->input_rotate_angle,
60                               FL_RETURN_CHANGED);
61
62         // Set the maximum characters that can be written in the input texts.
63         fl_set_input_maxchars(dialog_->input_width, WIDTH_MAXDIGITS);
64         fl_set_input_maxchars(dialog_->input_height, HEIGHT_MAXDIGITS);
65         fl_set_input_maxchars(dialog_->input_filename, FILENAME_MAXCHARS);
66         fl_set_input_maxchars(dialog_->input_rotate_angle, ROTATE_MAXCHARS);
67
68         // Set input filter on width and height to make them accept only
69         // unsigned numbers.
70         fl_set_input_filter(dialog_->input_width,
71                             fl_unsigned_int_filter);
72         fl_set_input_filter(dialog_->input_height,
73                             fl_unsigned_int_filter);
74
75         // Set input filter on rotate_angle to make it accept only
76         // floating point numbers.
77         fl_set_input_filter(dialog_->input_rotate_angle, fl_float_filter);
78
79         // Add the widgets of the width radio buttons to their group
80         widthButtons.reset();
81         widthButtons.registerRadioButton(dialog_->radio_width_default,
82                                          InsetGraphicsParams::DEFAULT_SIZE);
83         widthButtons.registerRadioButton(dialog_->radio_width_cm,
84                                          InsetGraphicsParams::CM);
85         widthButtons.registerRadioButton(dialog_->radio_width_inch,
86                                          InsetGraphicsParams::INCH);
87         widthButtons.registerRadioButton(dialog_->radio_width_percent_page,
88                                          InsetGraphicsParams::PERCENT_PAGE);
89         widthButtons.registerRadioButton(dialog_->radio_width_percent_column,
90                                          InsetGraphicsParams::PERCENT_COLUMN);
91
92         // Add the widgets of the height radio buttons to their group
93         heightButtons.reset();
94         heightButtons.registerRadioButton(dialog_->radio_height_default,
95                                           InsetGraphicsParams::DEFAULT_SIZE);
96         heightButtons.registerRadioButton(dialog_->radio_height_cm,
97                                           InsetGraphicsParams::CM);
98         heightButtons.registerRadioButton(dialog_->radio_height_inch,
99                                           InsetGraphicsParams::INCH);
100         heightButtons.registerRadioButton(dialog_->radio_height_percent_page,
101                                           InsetGraphicsParams::PERCENT_PAGE);
102
103         // Add the widgets of the display radio buttons to their group
104         displayButtons.reset();
105         displayButtons.registerRadioButton(dialog_->radio_display_color,
106                                            InsetGraphicsParams::COLOR);
107         displayButtons.registerRadioButton(dialog_->radio_display_grayscale,
108                                            InsetGraphicsParams::GRAYSCALE);
109         displayButtons.registerRadioButton(dialog_->radio_display_monochrome,
110                                            InsetGraphicsParams::MONOCHROME);
111         displayButtons.registerRadioButton(dialog_->radio_no_display,
112                                            InsetGraphicsParams::NONE);
113
114         // Manage the ok, apply, restore and cancel/close buttons
115         bc().setOK(dialog_->button_ok);
116         bc().setApply(dialog_->button_apply);
117         bc().setCancel(dialog_->button_cancel);
118         bc().setRestore(dialog_->button_restore);
119
120         bc().addReadOnly(dialog_->input_filename);
121         bc().addReadOnly(dialog_->button_browse);
122         bc().addReadOnly(dialog_->input_width);
123         bc().addReadOnly(dialog_->input_height);
124         bc().addReadOnly(dialog_->radio_button_group_width);
125         bc().addReadOnly(dialog_->radio_button_group_height);
126         bc().addReadOnly(dialog_->radio_button_group_display);
127         bc().addReadOnly(dialog_->input_rotate_angle);
128         bc().addReadOnly(dialog_->input_subcaption);
129         bc().addReadOnly(dialog_->check_subcaption);
130 }
131
132
133 void FormGraphics::apply()
134 {
135         // Create the parameters structure and fill the data from the dialog.
136         InsetGraphicsParams & igp = controller().params();
137
138         igp.filename = fl_get_input(dialog_->input_filename);
139
140         igp.display = static_cast < InsetGraphicsParams::DisplayType >
141                       (displayButtons.getButton());
142
143         igp.widthResize = static_cast < InsetGraphicsParams::Resize >
144                           (widthButtons.getButton());
145         igp.widthSize = strToDbl(fl_get_input(dialog_->input_width));
146
147         igp.heightResize = static_cast < InsetGraphicsParams::Resize >
148                            (heightButtons.getButton());
149         igp.heightSize = strToDbl(fl_get_input(dialog_->input_height));
150
151         igp.rotateAngle = strToDbl(fl_get_input(dialog_->input_rotate_angle));
152         /* // Need to redo it for floats, but I'm lazy now - BE 20010725
153         if (igp.rotateAngle >= 360)
154                 igp.rotateAngle = igp.rotateAngle % 360;
155         if (igp.rotateAngle <= -360)
156                 igp.rotateAngle = - (( -igp.rotateAngle) % 360);
157         */
158
159         igp.subcaption = fl_get_button(dialog_->check_subcaption);
160         igp.subcaptionText = fl_get_input(dialog_->input_subcaption);
161
162         igp.testInvariant();
163 }
164
165
166 void FormGraphics::update()
167 {
168         // Update dialog with details from inset
169         InsetGraphicsParams & igp = controller().params();
170
171         // Update the filename input field
172         fl_set_input(dialog_->input_filename,
173                      igp.filename.c_str());
174
175         // Update the display depth radio buttons
176         displayButtons.setButton(igp.display);
177
178         // Update the width radio buttons and input field
179         widthButtons.setButton(igp.widthResize);
180         fl_set_input(dialog_->input_width,
181                      tostr(igp.widthSize).c_str());
182
183         // Update the height radio buttons and input field
184         heightButtons.setButton(igp.heightResize);
185         fl_set_input(dialog_->input_height,
186                      tostr(igp.heightSize).c_str());
187
188         // Update the rotate angle
189         fl_set_input(dialog_->input_rotate_angle,
190                      tostr(igp.rotateAngle).c_str());
191
192         // Update the subcaption check button and input field
193         fl_set_button(dialog_->check_subcaption,
194                       igp.subcaption);
195         fl_set_input(dialog_->input_subcaption,
196                      igp.subcaptionText.c_str());
197
198         // Now make sure that the buttons are set correctly.
199         input(0, 0);
200 }
201
202
203 ButtonPolicy::SMInput FormGraphics::input(FL_OBJECT *, long data)
204 {
205         State cb = static_cast<State>( data );
206
207         ButtonPolicy::SMInput activate = ButtonPolicy::SMI_NOOP;
208
209         switch (cb) {
210         case CHECKINPUT:
211                 activate = checkInput();
212                 break;
213         case BROWSE:
214         {
215                 // Get the filename from the dialog
216                 string const in_name = fl_get_input(dialog_->input_filename);
217                 string const out_name = controller().Browse(in_name);
218
219                 if (out_name != in_name && !out_name.empty()) {
220                         fl_set_input(dialog_->input_filename, out_name.c_str());
221                         activate = input(0, CHECKINPUT);
222                 }
223                 break;
224         }
225
226         case ADVANCEDINPUT:
227                 lyxerr << "Advanced Options button depressed, "
228                        << "show advanced options dialog"
229                        << endl;
230                 break;
231         default:
232                 break;
233         }
234         
235         return activate;
236 }
237
238
239 ButtonPolicy::SMInput FormGraphics::checkInput()
240 {
241         // Put verifications that the dialog shows some sane values,
242         // if not disallow clicking on ok/apply.
243         // Possibly use a label in the bottom of the dialog to give the reason.
244
245         ButtonPolicy::SMInput activate = ButtonPolicy::SMI_VALID;
246
247         // Things that we check (meaning they are incorrect states):
248         // 1. No filename specified.
249         // 2. Width radio button is not Default and width text is not a number.
250         // 3. Height radio button is not Default and height text is a not a number
251
252         // Note: radio button default means that the user asks for the image
253         // to be included as is with no size change, in this case we don't need
254         // any width or height.
255
256         // We verify now that there is a filename, it exists, it's a file
257         // and it's readable.
258         string filename = fl_get_input(dialog_->input_filename);
259         FileInfo file(filename);
260         if (filename.empty()
261                 || !file.isOK()
262                 || !file.exist()
263                 || !file.isRegular()
264                 || !file.readable()
265            )
266                 activate = ButtonPolicy::SMI_NOOP;
267
268         // Width radio button not default and no number.
269         if (!fl_get_button(dialog_->radio_width_default)
270                 && strToDbl(fl_get_input(dialog_->input_width)) <= 0.0) {
271
272                 activate = ButtonPolicy::SMI_NOOP;
273         }
274
275         // Height radio button not default and no number.
276         if (!fl_get_button(dialog_->radio_height_default)
277                 && strToDbl(fl_get_input(dialog_->input_height)) <= 0.0) {
278
279                 activate = ButtonPolicy::SMI_NOOP;
280         }
281
282         return activate;
283 }