]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormGraphics.C
Implemented controller-view split for Graphics and Index popups.
[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 "lyx_gui_misc.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 "xforms_helpers.h"     // for browseFile
31 #include "support/filetools.h" // for AddName
32 #include "insets/insetgraphicsParams.h"
33
34 using std::endl;
35 using std::make_pair;
36
37 typedef FormCB<ControlGraphics, FormDB<FD_form_graphics> > base_class;
38
39 FormGraphics::FormGraphics(ControlGraphics & c)
40         : base_class(c, _("Graphics")),
41           // The buttons c-tor values are the number of buttons we use
42           // This is only to reduce memory waste.
43           widthButtons(5), heightButtons(4), displayButtons(4),
44           last_image_path(".")
45 {}
46
47
48 void FormGraphics::hide()
49 {
50         // Remove all associations for the radio buttons
51         widthButtons.reset();
52         heightButtons.reset();
53         displayButtons.reset();
54
55         FormBase::hide();
56 }
57
58
59 void FormGraphics::build()
60 {
61         dialog_.reset(build_graphics());
62
63         // This is the place to add settings of the dialog that did not go
64         // to the .fd file.
65
66         // Set the input widgets to issue a callback to input() whenever
67         // they change, so we can verify their content.
68         fl_set_input_return (dialog_->input_width,
69                               FL_RETURN_CHANGED);
70         fl_set_input_return (dialog_->input_height,
71                               FL_RETURN_CHANGED);
72         fl_set_input_return (dialog_->input_filename,
73                               FL_RETURN_CHANGED);
74         //    fl_set_input_return(dialog_->input_rotate_angle,
75         //            FL_RETURN_CHANGED);
76
77         // Set the maximum characters that can be written in the input texts.
78         fl_set_input_maxchars(dialog_->input_width, WIDTH_MAXDIGITS);
79         fl_set_input_maxchars(dialog_->input_height, HEIGHT_MAXDIGITS);
80         fl_set_input_maxchars(dialog_->input_filename, FILENAME_MAXCHARS);
81         fl_set_input_maxchars(dialog_->input_rotate_angle, ROTATE_MAXCHARS);
82
83         // Set input filter on width and height to make them accept only
84         // unsigned numbers.
85         fl_set_input_filter(dialog_->input_width,
86                             fl_unsigned_int_filter);
87         fl_set_input_filter(dialog_->input_height,
88                             fl_unsigned_int_filter);
89
90
91         // Add the widgets of the width radio buttons to their group
92         widthButtons.reset();
93         widthButtons.registerRadioButton(dialog_->radio_width_default,
94                                          InsetGraphicsParams::DEFAULT_SIZE);
95         widthButtons.registerRadioButton(dialog_->radio_width_cm,
96                                          InsetGraphicsParams::CM);
97         widthButtons.registerRadioButton(dialog_->radio_width_inch,
98                                          InsetGraphicsParams::INCH);
99         widthButtons.registerRadioButton(dialog_->radio_width_percent_page,
100                                          InsetGraphicsParams::PERCENT_PAGE);
101         widthButtons.registerRadioButton(dialog_->radio_width_percent_column,
102                                          InsetGraphicsParams::PERCENT_COLUMN);
103
104         // Add the widgets of the height radio buttons to their group
105         heightButtons.reset();
106         heightButtons.registerRadioButton(dialog_->radio_height_default,
107                                           InsetGraphicsParams::DEFAULT_SIZE);
108         heightButtons.registerRadioButton(dialog_->radio_height_cm,
109                                           InsetGraphicsParams::CM);
110         heightButtons.registerRadioButton(dialog_->radio_height_inch,
111                                           InsetGraphicsParams::INCH);
112         heightButtons.registerRadioButton(dialog_->radio_height_percent_page,
113                                           InsetGraphicsParams::PERCENT_PAGE);
114
115         // Add the widgets of the display radio buttons to their group
116         displayButtons.reset();
117         displayButtons.registerRadioButton(dialog_->radio_display_color,
118                                            InsetGraphicsParams::COLOR);
119         displayButtons.registerRadioButton(dialog_->radio_display_grayscale,
120                                            InsetGraphicsParams::GRAYSCALE);
121         displayButtons.registerRadioButton(dialog_->radio_display_monochrome,
122                                            InsetGraphicsParams::MONOCHROME);
123         displayButtons.registerRadioButton(dialog_->radio_no_display,
124                                            InsetGraphicsParams::NONE);
125
126         // Manage the ok, apply, restore and cancel/close buttons
127         bc().setOK(dialog_->button_ok);
128         bc().setApply(dialog_->button_apply);
129         bc().setCancel(dialog_->button_cancel);
130         bc().setUndoAll(dialog_->button_restore);
131         bc().refresh();
132
133         bc().addReadOnly(dialog_->input_filename);
134         bc().addReadOnly(dialog_->button_browse);
135         bc().addReadOnly(dialog_->input_width);
136         bc().addReadOnly(dialog_->input_height);
137         bc().addReadOnly(dialog_->radio_button_group_width);
138         bc().addReadOnly(dialog_->radio_button_group_height);
139         bc().addReadOnly(dialog_->radio_button_group_display);
140         bc().addReadOnly(dialog_->input_rotate_angle);
141         bc().addReadOnly(dialog_->check_inline);
142         bc().addReadOnly(dialog_->input_subcaption);
143         bc().addReadOnly(dialog_->check_subcaption);
144 }
145
146
147 void FormGraphics::apply()
148 {
149         // Create the parameters structure and fill the data from the dialog.
150         InsetGraphicsParams & igp = controller().params();
151
152         igp.filename = fl_get_input(dialog_->input_filename);
153
154         igp.display = static_cast < InsetGraphicsParams::DisplayType >
155                       (displayButtons.getButton());
156
157         igp.widthResize = static_cast < InsetGraphicsParams::Resize >
158                           (widthButtons.getButton());
159         igp.widthSize = strToDbl(fl_get_input(dialog_->input_width));
160
161         igp.heightResize = static_cast < InsetGraphicsParams::Resize >
162                            (heightButtons.getButton());
163         igp.heightSize = strToDbl(fl_get_input(dialog_->input_height));
164
165         igp.rotateAngle = strToInt(fl_get_input(dialog_->input_rotate_angle));
166         if (igp.rotateAngle >= 360)
167                 igp.rotateAngle = igp.rotateAngle % 360;
168         if (igp.rotateAngle <= -360)
169                 igp.rotateAngle = - (( -igp.rotateAngle) % 360);
170
171         igp.subcaption = fl_get_button(dialog_->check_subcaption);
172         igp.subcaptionText = fl_get_input(dialog_->input_subcaption);
173
174         igp.inlineFigure = fl_get_button(dialog_->check_inline);
175
176         igp.testInvariant();
177 }
178
179
180 void FormGraphics::update()
181 {
182         // Update dialog with details from inset
183         InsetGraphicsParams & igp = controller().params();
184
185         // Update the filename input field
186         fl_set_input(dialog_->input_filename,
187                      igp.filename.c_str());
188
189         // Update the display depth radio buttons
190         displayButtons.setButton(igp.display);
191
192         // Update the width radio buttons and input field
193         widthButtons.setButton(igp.widthResize);
194         fl_set_input(dialog_->input_width,
195                      tostr(igp.widthSize).c_str());
196
197         // Update the height radio buttons and input field
198         heightButtons.setButton(igp.heightResize);
199         fl_set_input(dialog_->input_height,
200                      tostr(igp.heightSize).c_str());
201
202         // Update the rotate angle
203         fl_set_input(dialog_->input_rotate_angle,
204                      tostr(igp.rotateAngle).c_str());
205
206         // Update the subcaption check button and input field
207         fl_set_button(dialog_->check_subcaption,
208                       igp.subcaption);
209         fl_set_input(dialog_->input_subcaption,
210                      igp.subcaptionText.c_str());
211
212         // Update the inline figure check button
213         fl_set_button(dialog_->check_inline,
214                       igp.inlineFigure);
215
216         // Now make sure that the buttons are set correctly.
217         input(0, 0);
218 }
219
220
221 ButtonPolicy::SMInput FormGraphics::input(FL_OBJECT *, long data)
222 {
223         State cb = static_cast<State>( data );
224
225         ButtonPolicy::SMInput activate = ButtonPolicy::SMI_NOOP;
226
227         switch (cb) {
228         case CHECKINPUT:
229                 activate = checkInput();
230                 break;
231         case BROWSE:
232                 browse();
233                 break;
234         case ADVANCEDINPUT:
235                 lyxerr << "Advanced Options button depressed, "
236                        << "show advanced options dialog"
237                        << endl;
238                 break;
239         default:
240                 break;
241         }
242         
243         return activate;
244 }
245
246
247 ButtonPolicy::SMInput FormGraphics::checkInput()
248 {
249         // Put verifications that the dialog shows some sane values,
250         // if not disallow clicking on ok/apply.
251         // Possibly use a label in the bottom of the dialog to give the reason.
252
253         ButtonPolicy::SMInput activate = ButtonPolicy::SMI_VALID;
254
255         // Things that we check (meaning they are incorrect states):
256         // 1. No filename specified.
257         // 2. Width radio button is not Default and width text is not a number.
258         // 3. Height radio button is not Default and height text is a not a number
259
260         // Note: radio button default means that the user asks for the image
261         // to be included as is with no size change, in this case we don't need
262         // any width or height.
263
264         // We verify now that there is a filename, it exists, it's a file
265         // and it's readable.
266         string filename = fl_get_input(dialog_->input_filename);
267         FileInfo file(filename);
268         if (filename.empty()
269                 || !file.isOK()
270                 || !file.exist()
271                 || !file.isRegular()
272                 || !file.readable()
273            )
274                 activate = ButtonPolicy::SMI_NOOP;
275
276         // Width radio button not default and no number.
277         if (!fl_get_button(dialog_->radio_width_default)
278                 && strToDbl(fl_get_input(dialog_->input_width)) <= 0.0) {
279
280                 activate = ButtonPolicy::SMI_NOOP;
281         }
282
283         // Height radio button not default and no number.
284         if (!fl_get_button(dialog_->radio_height_default)
285                 && strToDbl(fl_get_input(dialog_->input_height)) <= 0.0) {
286
287                 activate = ButtonPolicy::SMI_NOOP;
288         }
289
290         return activate;
291 }
292
293
294 // We need these in the file browser.
295 extern string system_lyxdir;
296 extern string user_lyxdir;
297
298 void FormGraphics::browse()
299 {
300         // Get the filename from the dialog
301         string const filename = fl_get_input(dialog_->input_filename);
302
303         string const title = N_("Graphics");
304         // FIXME: currently we need the second '|' to prevent mis-interpretation 
305         string const pattern = "*.(ps|png)|";
306
307         // Does user clipart directory exist?
308         string clipdir = AddName (user_lyxdir, "clipart");
309         FileInfo fileInfo(clipdir);
310         if (!(fileInfo.isOK() && fileInfo.isDir()))
311                 // No - bail out to system clipart directory
312                 clipdir = AddName (system_lyxdir, "clipart");
313         pair<string, string> dir1(N_("Clipart"), clipdir);
314         
315         // Show the file browser dialog
316         string const new_filename =
317                 browseFile(controller().lv(), filename, title, pattern, dir1,
318                            make_pair(string(), string()));
319
320         // Save the filename to the dialog
321         if (new_filename != filename && !new_filename.empty()) {
322                 fl_set_input(dialog_->input_filename, new_filename.c_str());
323                 input(0, 0);
324         }
325 }