2 * FormGraphics Interface Class Implementation
11 #include "lyx_gui_misc.h"
12 #include "input_validators.h"
13 #include "FormGraphics.h"
14 #include "form_graphics.h"
17 #include "BufferView.h"
19 #include "debug.h" // for lyxerr
21 #include "support/lstrings.h" // for strToDbl & tostr
22 #include "support/FileInfo.h" // for FileInfo
23 #include "xform_helpers.h" // for browseFile
24 #include "support/filetools.h" // for AddName
25 #include "insets/insetgraphics.h"
26 #include "insets/insetgraphicsParams.h"
28 #include "RadioButtonGroup.h"
30 #include "support/LAssert.h"
35 FormGraphics::FormGraphics(LyXView * lv, Dialogs * d)
36 : FormInset(lv, d, _("Graphics"), new NoRepeatedApplyReadOnlyPolicy),
37 dialog_(0), inset_(0),
38 // The buttons c-tor values are the number of buttons we use
39 // This is only to reduce memory waste.
40 widthButtons(5), heightButtons(4), displayButtons(4),
43 // let the dialog be shown
44 // This is a permanent connection so we won't bother
45 // storing a copy because we won't be disconnecting.
46 d->showGraphics.connect(slot(this, &FormGraphics::showDialog));
50 FormGraphics::~FormGraphics()
52 // Remove all associations for the radio buttons
54 heightButtons.reset();
55 displayButtons.reset();
62 void FormGraphics::build()
64 dialog_ = build_graphics();
67 lyxerr << "ERROR: Failed to create the Graphics Inset dialog." << endl;
71 // Workaround dumb xforms sizing bug
75 // This is the place to add settings of the dialog that did not go
78 // Set the input widgets to issue a callback to input() whenever
79 // they change, so we can verify their content.
80 fl_set_input_return (dialog_->input_width,
82 fl_set_input_return (dialog_->input_height,
84 fl_set_input_return (dialog_->input_filename,
86 // fl_set_input_return(dialog_->input_rotate_angle,
87 // FL_RETURN_CHANGED);
89 // Set the maximum characters that can be written in the input texts.
90 fl_set_input_maxchars(dialog_->input_width, WIDTH_MAXDIGITS);
91 fl_set_input_maxchars(dialog_->input_height, HEIGHT_MAXDIGITS);
92 fl_set_input_maxchars(dialog_->input_filename, FILENAME_MAXCHARS);
93 fl_set_input_maxchars(dialog_->input_rotate_angle, ROTATE_MAXCHARS);
95 // Set input filter on width and height to make them accept only
97 fl_set_input_filter(dialog_->input_width,
98 fl_unsigned_int_filter);
99 fl_set_input_filter(dialog_->input_height,
100 fl_unsigned_int_filter);
103 // Add the widgets of the width radio buttons to their group
104 widthButtons.reset();
105 widthButtons.registerRadioButton(dialog_->radio_width_default,
106 InsetGraphicsParams::DEFAULT_SIZE);
107 widthButtons.registerRadioButton(dialog_->radio_width_cm,
108 InsetGraphicsParams::CM);
109 widthButtons.registerRadioButton(dialog_->radio_width_inch,
110 InsetGraphicsParams::INCH);
111 widthButtons.registerRadioButton(dialog_->radio_width_percent_page,
112 InsetGraphicsParams::PERCENT_PAGE);
113 widthButtons.registerRadioButton(dialog_->radio_width_percent_column,
114 InsetGraphicsParams::PERCENT_COLUMN);
116 // Add the widgets of the height radio buttons to their group
117 heightButtons.reset();
118 heightButtons.registerRadioButton(dialog_->radio_height_default,
119 InsetGraphicsParams::DEFAULT_SIZE);
120 heightButtons.registerRadioButton(dialog_->radio_height_cm,
121 InsetGraphicsParams::CM);
122 heightButtons.registerRadioButton(dialog_->radio_height_inch,
123 InsetGraphicsParams::INCH);
124 heightButtons.registerRadioButton(dialog_->radio_height_percent_page,
125 InsetGraphicsParams::PERCENT_PAGE);
127 // Add the widgets of the display radio buttons to their group
128 displayButtons.reset();
129 displayButtons.registerRadioButton(dialog_->radio_display_color,
130 InsetGraphicsParams::COLOR);
131 displayButtons.registerRadioButton(dialog_->radio_display_grayscale,
132 InsetGraphicsParams::GRAYSCALE);
133 displayButtons.registerRadioButton(dialog_->radio_display_monochrome,
134 InsetGraphicsParams::MONOCHROME);
135 displayButtons.registerRadioButton(dialog_->radio_no_display,
136 InsetGraphicsParams::NONE);
138 // Manage the ok, apply, restore and cancel/close buttons
139 bc_.setOK(dialog_->button_ok);
140 bc_.setApply(dialog_->button_apply);
141 bc_.setCancel(dialog_->button_cancel);
142 bc_.setUndoAll(dialog_->button_restore);
145 bc_.addReadOnly(dialog_->input_filename);
146 bc_.addReadOnly(dialog_->button_browse);
147 bc_.addReadOnly(dialog_->input_width);
148 bc_.addReadOnly(dialog_->input_height);
149 bc_.addReadOnly(dialog_->radio_button_group_width);
150 bc_.addReadOnly(dialog_->radio_button_group_height);
151 bc_.addReadOnly(dialog_->radio_button_group_display);
152 bc_.addReadOnly(dialog_->input_rotate_angle);
153 bc_.addReadOnly(dialog_->check_inline);
154 bc_.addReadOnly(dialog_->input_subcaption);
155 bc_.addReadOnly(dialog_->check_subcaption);
159 FL_FORM * FormGraphics::form() const
161 if (dialog_ ) return dialog_->form;
166 void FormGraphics::disconnect()
169 FormInset::disconnect();
173 void FormGraphics::showDialog(InsetGraphics * inset)
175 // If we are connected to another inset, disconnect.
181 ih_ = inset_->hide.connect(slot(this, &FormGraphics::hide));
186 void FormGraphics::apply()
190 // Take all dialog details and insert them to the inset.
192 // Create the parameters structure and fill the data from the dialog.
193 InsetGraphicsParams igp;
195 igp.filename = fl_get_input(dialog_->input_filename);
197 igp.display = static_cast < InsetGraphicsParams::DisplayType >
198 (displayButtons.getButton());
200 igp.widthResize = static_cast < InsetGraphicsParams::Resize >
201 (widthButtons.getButton());
202 igp.widthSize = strToDbl(fl_get_input(dialog_->input_width));
204 igp.heightResize = static_cast < InsetGraphicsParams::Resize >
205 (heightButtons.getButton());
206 igp.heightSize = strToDbl(fl_get_input(dialog_->input_height));
208 igp.rotateAngle = strToInt(fl_get_input(dialog_->input_rotate_angle));
209 if (igp.rotateAngle >= 360)
210 igp.rotateAngle = igp.rotateAngle % 360;
211 if (igp.rotateAngle <= -360)
212 igp.rotateAngle = - (( -igp.rotateAngle) % 360);
214 igp.subcaption = fl_get_button(dialog_->check_subcaption);
215 igp.subcaptionText = fl_get_input(dialog_->input_subcaption);
217 igp.inlineFigure = fl_get_button(dialog_->check_inline);
221 // Set the parameters in the inset, it also returns true if the new
222 // parameters are different from what was in the inset already.
223 bool changed = inset_->setParams(igp);
225 // Tell LyX we've got a change, and mark the document dirty, if it changed.
226 lv_->view()->updateInset(inset_, changed);
230 void FormGraphics::update()
234 // Update dialog with details from inset
235 InsetGraphicsParams igp = inset_->getParams();
237 // Update the filename input field
238 fl_set_input(dialog_->input_filename,
239 igp.filename.c_str());
241 // Update the display depth radio buttons
242 displayButtons.setButton(igp.display);
244 // Update the width radio buttons and input field
245 widthButtons.setButton(igp.widthResize);
246 fl_set_input(dialog_->input_width,
247 tostr(igp.widthSize).c_str());
249 // Update the height radio buttons and input field
250 heightButtons.setButton(igp.heightResize);
251 fl_set_input(dialog_->input_height,
252 tostr(igp.heightSize).c_str());
254 // Update the rotate angle
255 fl_set_input(dialog_->input_rotate_angle,
256 tostr(igp.rotateAngle).c_str());
258 // Update the subcaption check button and input field
259 fl_set_button(dialog_->check_subcaption,
261 fl_set_input(dialog_->input_subcaption,
262 igp.subcaptionText.c_str());
264 // Update the inline figure check button
265 fl_set_button(dialog_->check_inline,
268 // update the dialog's read only / read-write status
269 bc_.readOnly(lv_->buffer()->isReadonly());
271 // Now make sure that the buttons are set correctly.
276 bool FormGraphics::input(FL_OBJECT *, long data )
278 State cb = static_cast<State>( data );
284 inputOK = checkInput();
290 lyxerr << "Advanced Options button depressed, "
291 << "show advanced options dialog"
302 bool FormGraphics::checkInput()
304 // Put verifications that the dialog shows some sane values,
305 // if not disallow clicking on ok/apply.
306 // Possibly use a label in the bottom of the dialog to give the reason.
308 // Is all input boxes convey a valid meaning?
311 // Things that we check (meaning they are incorrect states):
312 // 1. No filename specified.
313 // 2. Width radio button is not Default and width text is not a number.
314 // 3. Height radio button is not Default and height text is a not a number
316 // Note: radio button default means that the user asks for the image
317 // to be included as is with no size change, in this case we don't need
318 // any width or height.
320 // We verify now that there is a filename, it exists, it's a file
321 // and it's readable.
322 string filename = fl_get_input(dialog_->input_filename);
323 FileInfo file(filename);
332 // Width radio button not default and no number.
333 if (!fl_get_button(dialog_->radio_width_default)
334 && strToDbl(fl_get_input(dialog_->input_width)) <= 0.0) {
339 // Height radio button not default and no number.
340 if (!fl_get_button(dialog_->radio_height_default)
341 && strToDbl(fl_get_input(dialog_->input_height)) <= 0.0) {
350 // We need these in the file browser.
351 extern string system_lyxdir;
352 extern string user_lyxdir;
354 void FormGraphics::browse()
356 // Get the filename from the dialog
357 string const filename = fl_get_input(dialog_->input_filename);
359 string const title = N_("Graphics");
360 string const pattern = "*(ps|png)";
362 // Does user clipart directory exist?
363 string clipdir = AddName (user_lyxdir, "clipart");
364 FileInfo fileInfo(clipdir);
365 if (!(fileInfo.isOK() && fileInfo.isDir()))
366 // No - bail out to system clipart directory
367 clipdir = AddName (system_lyxdir, "clipart");
368 pair<string, string> dir1(N_("Clipart"), clipdir);
370 // Show the file browser dialog
371 string const new_filename =
372 browseFile(filename, title, pattern, dir1,
373 make_pair(string(), string()));
375 // Save the filename to the dialog
376 if (new_filename != filename && !new_filename.empty()) {
377 fl_set_input(dialog_->input_filename, new_filename.c_str());