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 "xforms_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"
36 FormGraphics::FormGraphics(LyXView * lv, Dialogs * d)
37 : FormInset(lv, d, _("Graphics")),
39 // The buttons c-tor values are the number of buttons we use
40 // This is only to reduce memory waste.
41 widthButtons(5), heightButtons(4), displayButtons(4),
44 // let the dialog be shown
45 // This is a permanent connection so we won't bother
46 // storing a copy because we won't be disconnecting.
47 d->showGraphics.connect(slot(this, &FormGraphics::showDialog));
51 FormGraphics::~FormGraphics()
53 // Remove all associations for the radio buttons
55 heightButtons.reset();
56 displayButtons.reset();
60 void FormGraphics::build()
62 dialog_.reset(build_graphics());
64 // Workaround dumb xforms sizing bug
68 // This is the place to add settings of the dialog that did not go
71 // Set the input widgets to issue a callback to input() whenever
72 // they change, so we can verify their content.
73 fl_set_input_return (dialog_->input_width,
75 fl_set_input_return (dialog_->input_height,
77 fl_set_input_return (dialog_->input_filename,
79 // fl_set_input_return(dialog_->input_rotate_angle,
80 // FL_RETURN_CHANGED);
82 // Set the maximum characters that can be written in the input texts.
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_width,
91 fl_unsigned_int_filter);
92 fl_set_input_filter(dialog_->input_height,
93 fl_unsigned_int_filter);
96 // Add the widgets of the width radio buttons to their group
98 widthButtons.registerRadioButton(dialog_->radio_width_default,
99 InsetGraphicsParams::DEFAULT_SIZE);
100 widthButtons.registerRadioButton(dialog_->radio_width_cm,
101 InsetGraphicsParams::CM);
102 widthButtons.registerRadioButton(dialog_->radio_width_inch,
103 InsetGraphicsParams::INCH);
104 widthButtons.registerRadioButton(dialog_->radio_width_percent_page,
105 InsetGraphicsParams::PERCENT_PAGE);
106 widthButtons.registerRadioButton(dialog_->radio_width_percent_column,
107 InsetGraphicsParams::PERCENT_COLUMN);
109 // Add the widgets of the height radio buttons to their group
110 heightButtons.reset();
111 heightButtons.registerRadioButton(dialog_->radio_height_default,
112 InsetGraphicsParams::DEFAULT_SIZE);
113 heightButtons.registerRadioButton(dialog_->radio_height_cm,
114 InsetGraphicsParams::CM);
115 heightButtons.registerRadioButton(dialog_->radio_height_inch,
116 InsetGraphicsParams::INCH);
117 heightButtons.registerRadioButton(dialog_->radio_height_percent_page,
118 InsetGraphicsParams::PERCENT_PAGE);
120 // Add the widgets of the display radio buttons to their group
121 displayButtons.reset();
122 displayButtons.registerRadioButton(dialog_->radio_display_color,
123 InsetGraphicsParams::COLOR);
124 displayButtons.registerRadioButton(dialog_->radio_display_grayscale,
125 InsetGraphicsParams::GRAYSCALE);
126 displayButtons.registerRadioButton(dialog_->radio_display_monochrome,
127 InsetGraphicsParams::MONOCHROME);
128 displayButtons.registerRadioButton(dialog_->radio_no_display,
129 InsetGraphicsParams::NONE);
131 // Manage the ok, apply, restore and cancel/close buttons
132 bc().setOK(dialog_->button_ok);
133 bc().setApply(dialog_->button_apply);
134 bc().setCancel(dialog_->button_cancel);
135 bc().setUndoAll(dialog_->button_restore);
138 bc().addReadOnly(dialog_->input_filename);
139 bc().addReadOnly(dialog_->button_browse);
140 bc().addReadOnly(dialog_->input_width);
141 bc().addReadOnly(dialog_->input_height);
142 bc().addReadOnly(dialog_->radio_button_group_width);
143 bc().addReadOnly(dialog_->radio_button_group_height);
144 bc().addReadOnly(dialog_->radio_button_group_display);
145 bc().addReadOnly(dialog_->input_rotate_angle);
146 bc().addReadOnly(dialog_->check_inline);
147 bc().addReadOnly(dialog_->input_subcaption);
148 bc().addReadOnly(dialog_->check_subcaption);
152 FL_FORM * FormGraphics::form() const
155 return dialog_->form;
160 void FormGraphics::disconnect()
163 FormInset::disconnect();
167 void FormGraphics::showDialog(InsetGraphics * inset)
169 // If we are connected to another inset, disconnect.
175 ih_ = inset_->hideDialog.connect(slot(this, &FormGraphics::hide));
180 void FormGraphics::apply()
184 // Take all dialog details and insert them to the inset.
186 // Create the parameters structure and fill the data from the dialog.
187 InsetGraphicsParams igp;
189 igp.filename = fl_get_input(dialog_->input_filename);
191 igp.display = static_cast < InsetGraphicsParams::DisplayType >
192 (displayButtons.getButton());
194 igp.widthResize = static_cast < InsetGraphicsParams::Resize >
195 (widthButtons.getButton());
196 igp.widthSize = strToDbl(fl_get_input(dialog_->input_width));
198 igp.heightResize = static_cast < InsetGraphicsParams::Resize >
199 (heightButtons.getButton());
200 igp.heightSize = strToDbl(fl_get_input(dialog_->input_height));
202 igp.rotateAngle = strToInt(fl_get_input(dialog_->input_rotate_angle));
203 if (igp.rotateAngle >= 360)
204 igp.rotateAngle = igp.rotateAngle % 360;
205 if (igp.rotateAngle <= -360)
206 igp.rotateAngle = - (( -igp.rotateAngle) % 360);
208 igp.subcaption = fl_get_button(dialog_->check_subcaption);
209 igp.subcaptionText = fl_get_input(dialog_->input_subcaption);
211 igp.inlineFigure = fl_get_button(dialog_->check_inline);
215 // Set the parameters in the inset, it also returns true if the new
216 // parameters are different from what was in the inset already.
217 bool changed = inset_->setParams(igp);
219 // Tell LyX we've got a change, and mark the document dirty, if it changed.
220 lv_->view()->updateInset(inset_, changed);
224 void FormGraphics::update()
228 // Update dialog with details from inset
229 InsetGraphicsParams igp = inset_->getParams();
231 // Update the filename input field
232 fl_set_input(dialog_->input_filename,
233 igp.filename.c_str());
235 // Update the display depth radio buttons
236 displayButtons.setButton(igp.display);
238 // Update the width radio buttons and input field
239 widthButtons.setButton(igp.widthResize);
240 fl_set_input(dialog_->input_width,
241 tostr(igp.widthSize).c_str());
243 // Update the height radio buttons and input field
244 heightButtons.setButton(igp.heightResize);
245 fl_set_input(dialog_->input_height,
246 tostr(igp.heightSize).c_str());
248 // Update the rotate angle
249 fl_set_input(dialog_->input_rotate_angle,
250 tostr(igp.rotateAngle).c_str());
252 // Update the subcaption check button and input field
253 fl_set_button(dialog_->check_subcaption,
255 fl_set_input(dialog_->input_subcaption,
256 igp.subcaptionText.c_str());
258 // Update the inline figure check button
259 fl_set_button(dialog_->check_inline,
262 // update the dialog's read only / read-write status
263 bc().readOnly(lv_->buffer()->isReadonly());
265 // Now make sure that the buttons are set correctly.
270 bool FormGraphics::input(FL_OBJECT *, long data )
272 State cb = static_cast<State>( data );
278 inputOK = checkInput();
284 lyxerr << "Advanced Options button depressed, "
285 << "show advanced options dialog"
296 bool FormGraphics::checkInput()
298 // Put verifications that the dialog shows some sane values,
299 // if not disallow clicking on ok/apply.
300 // Possibly use a label in the bottom of the dialog to give the reason.
302 // Is all input boxes convey a valid meaning?
305 // Things that we check (meaning they are incorrect states):
306 // 1. No filename specified.
307 // 2. Width radio button is not Default and width text is not a number.
308 // 3. Height radio button is not Default and height text is a not a number
310 // Note: radio button default means that the user asks for the image
311 // to be included as is with no size change, in this case we don't need
312 // any width or height.
314 // We verify now that there is a filename, it exists, it's a file
315 // and it's readable.
316 string filename = fl_get_input(dialog_->input_filename);
317 FileInfo file(filename);
326 // Width radio button not default and no number.
327 if (!fl_get_button(dialog_->radio_width_default)
328 && strToDbl(fl_get_input(dialog_->input_width)) <= 0.0) {
333 // Height radio button not default and no number.
334 if (!fl_get_button(dialog_->radio_height_default)
335 && strToDbl(fl_get_input(dialog_->input_height)) <= 0.0) {
344 // We need these in the file browser.
345 extern string system_lyxdir;
346 extern string user_lyxdir;
348 void FormGraphics::browse()
350 // Get the filename from the dialog
351 string const filename = fl_get_input(dialog_->input_filename);
353 string const title = N_("Graphics");
354 // FIXME: currently we need the second '|' to prevent mis-interpretation
355 string const pattern = "*.(ps|png)|";
357 // Does user clipart directory exist?
358 string clipdir = AddName (user_lyxdir, "clipart");
359 FileInfo fileInfo(clipdir);
360 if (!(fileInfo.isOK() && fileInfo.isDir()))
361 // No - bail out to system clipart directory
362 clipdir = AddName (system_lyxdir, "clipart");
363 pair<string, string> dir1(N_("Clipart"), clipdir);
365 // Show the file browser dialog
366 string const new_filename =
367 browseFile(lv_, filename, title, pattern, dir1,
368 make_pair(string(), string()));
370 // Save the filename to the dialog
371 if (new_filename != filename && !new_filename.empty()) {
372 fl_set_input(dialog_->input_filename, new_filename.c_str());