2 * FormGraphics Interface Class Implementation
6 * * Handle the case when the buffer is read-only.
7 * Initial work is done, if we are read-only the ok/cancel are
8 * disabled. Probably we need to find a better way to deal with it.
13 #pragma implementation
18 #include "lyx_gui_misc.h"
20 #include FORMS_H_LOCATION
22 #include "xform_macros.h"
23 #include "input_validators.h"
24 #include "FormGraphics.h"
25 #include "form_graphics.h"
28 #include "BufferView.h"
30 #include "debug.h" // for lyxerr
32 #include "support/lstrings.h" // for strToDbl & tostr
33 #include "support/FileInfo.h" // for FileInfo
34 #include "filedlg.h" // for LyXFileDlg
35 #include "support/filetools.h" // for AddName
36 #include "insets/insetgraphics.h"
37 #include "insets/insetgraphicsParams.h"
39 #include "RadioButtonGroup.h"
41 #ifdef ENABLE_ASSERTIONS
42 #include "support/LAssert.h"
47 C_RETURNCB(FormGraphics, WMHideCB)
48 C_GENERICCB(FormGraphics, OKCB)
49 C_GENERICCB(FormGraphics, ApplyCB)
50 C_GENERICCB(FormGraphics, CancelCB)
51 C_GENERICCB(FormGraphics, BrowseCB)
52 C_GENERICCB(FormGraphics, AdvancedOptionsCB)
53 C_GENERICCB(FormGraphics, InputCB)
56 FormGraphics::FormGraphics(LyXView * lv, Dialogs * d)
57 : dialog_(0), lv_(lv), d_(d), inset_(0),
58 // The buttons c-tor values are the number of buttons we use
59 // This is only to reduce memory waste.
60 widthButtons(5), heightButtons(4), displayButtons(4),
64 // let the dialog be shown
65 // This is a permanent connection so we won't bother
66 // storing a copy because we won't be disconnecting.
67 d->showGraphics.connect(slot(this, &FormGraphics::showDialog));
71 FormGraphics::~FormGraphics()
77 void FormGraphics::build()
79 dialog_ = build_graphics();
80 #ifdef ENABLE_ASSERTIONS
86 // This is the place to add settings of the dialog that did not go
89 // Set the input widgets to issue a callback to input() whenever
90 // they change, so we can verify their content.
91 fl_set_input_return(dialog_->input_width,
93 fl_set_input_return(dialog_->input_height,
95 fl_set_input_return(dialog_->input_filename,
97 // fl_set_input_return(dialog_->input_rotate_angle,
98 // FL_RETURN_CHANGED);
100 // Set the maximum characters that can be written in the input texts.
101 fl_set_input_maxchars(dialog_->input_width, WIDTH_MAXDIGITS);
102 fl_set_input_maxchars(dialog_->input_height, HEIGHT_MAXDIGITS);
103 fl_set_input_maxchars(dialog_->input_filename, FILENAME_MAXCHARS);
104 fl_set_input_maxchars(dialog_->input_rotate_angle, ROTATE_MAXCHARS);
106 // Set input filter on width and height to make them accept only
108 fl_set_input_filter(dialog_->input_width,
109 fl_unsigned_int_filter);
110 fl_set_input_filter(dialog_->input_height,
111 fl_unsigned_int_filter);
114 // Add the widgets of the width radio buttons to their group
115 widthButtons.reset();
116 widthButtons.registerRadioButton(dialog_->radio_width_default,
117 InsetGraphicsParams::DEFAULT_SIZE);
118 widthButtons.registerRadioButton(dialog_->radio_width_cm,
119 InsetGraphicsParams::CM);
120 widthButtons.registerRadioButton(dialog_->radio_width_inch,
121 InsetGraphicsParams::INCH);
122 widthButtons.registerRadioButton(dialog_->radio_width_percent_page,
123 InsetGraphicsParams::PERCENT_PAGE);
124 widthButtons.registerRadioButton(dialog_->radio_width_percent_column,
125 InsetGraphicsParams::PERCENT_COLUMN);
127 // Add the widgets of the height radio buttons to their group
128 heightButtons.reset();
129 heightButtons.registerRadioButton(dialog_->radio_height_default,
130 InsetGraphicsParams::DEFAULT_SIZE);
131 heightButtons.registerRadioButton(dialog_->radio_height_cm,
132 InsetGraphicsParams::CM);
133 heightButtons.registerRadioButton(dialog_->radio_height_inch,
134 InsetGraphicsParams::INCH);
135 heightButtons.registerRadioButton(dialog_->radio_height_percent_page,
136 InsetGraphicsParams::PERCENT_PAGE);
138 // Add the widgets of the display radio buttons to their group
139 displayButtons.reset();
140 displayButtons.registerRadioButton(dialog_->radio_display_color,
141 InsetGraphicsParams::COLOR);
142 displayButtons.registerRadioButton(dialog_->radio_display_grayscale,
143 InsetGraphicsParams::GRAYSCALE);
144 displayButtons.registerRadioButton(dialog_->radio_display_monochrome,
145 InsetGraphicsParams::MONOCHROME);
146 displayButtons.registerRadioButton(dialog_->radio_no_display,
147 InsetGraphicsParams::NONE);
149 // Connect a signal to hide the window when the window manager orders it.
150 fl_set_form_atclose(dialog_->form,
151 C_FormGraphicsWMHideCB, 0);
154 void FormGraphics::show()
156 // If the dialog doesn't exist yet, build it.
161 // Update the form with the data from the inset.
164 // If the form is visible
165 if (dialog_->form->visible) {
167 fl_raise_form(dialog_->form);
169 // Otherwise (invisible), show it.
170 fl_show_form(dialog_->form,
175 // And connect the signals 'updateBufferDependent',
176 // 'hideBufferDependent' and 'hideGraphics'.
177 u_ = d_->updateBufferDependent.connect(slot(this,
178 &FormGraphics::update));
179 h_ = d_->hideBufferDependent.connect(slot(this,
180 &FormGraphics::hide));
184 void FormGraphics::showDialog(InsetGraphics* inset)
186 #ifdef ENABLE_ASSERTIONS
190 // If we are connected to another inset, disconnect.
197 ih_ = inset_->hide.connect(slot(this, &FormGraphics::hide));
203 void FormGraphics::hide()
205 // If the dialog exists, and the form is allocated and visible.
208 && dialog_->form->visible) {
210 fl_hide_form(dialog_->form);
212 // And disconnect the signals.
220 // Most of the time, the dialog is not needed anymore, we'll free it
221 // now to save memory.
226 void FormGraphics::free()
228 // Remove all associations for the radio buttons
229 widthButtons.reset();
230 heightButtons.reset();
231 displayButtons.reset();
238 void FormGraphics::apply()
240 #ifdef ENABLE_ASSERTIONS
246 // Take all dialog details and insert them to the inset.
248 // Create the parameters structure and fill the data from the dialog.
249 InsetGraphicsParams igp;
251 igp.filename = fl_get_input(dialog_->input_filename);
253 igp.display = static_cast<InsetGraphicsParams::DisplayType>
254 (displayButtons.getButton());
256 igp.widthResize = static_cast<InsetGraphicsParams::Resize>
257 (widthButtons.getButton());
258 igp.widthSize = strToDbl(fl_get_input(dialog_->input_width));
260 igp.heightResize = static_cast<InsetGraphicsParams::Resize>
261 (heightButtons.getButton());
262 igp.heightSize = strToDbl(fl_get_input(dialog_->input_height));
264 igp.rotateAngle = strToInt(fl_get_input(dialog_->input_rotate_angle));
265 if (igp.rotateAngle >= 360)
266 igp.rotateAngle = igp.rotateAngle % 360;
267 if (igp.rotateAngle <= -360)
268 igp.rotateAngle = - ((-igp.rotateAngle) % 360);
270 igp.subcaption = fl_get_button(dialog_->check_subcaption);
271 igp.subcaptionText = fl_get_input(dialog_->input_subcaption);
273 igp.inlineFigure = fl_get_button(dialog_->check_inline);
275 #ifdef ENABLE_ASSERTIONS
279 // Set the parameters in the inset, it also returns true if the new
280 // parameters are different from what was in the inset already.
281 bool changed = inset_->setParams(igp);
283 // Tell LyX we've got a change, and mark the document dirty, if it changed.
284 lv_->view()->updateInset(inset_, changed);
287 void FormGraphics::update()
289 #ifdef ENABLE_ASSERTIONS
295 // Update dialog with details from inset
296 InsetGraphicsParams igp = inset_->getParams();
298 // Update the filename input field
299 fl_set_input(dialog_->input_filename,
300 igp.filename.c_str());
302 // Update the display depth radio buttons
303 displayButtons.setButton(igp.display);
305 // Update the width radio buttons and input field
306 widthButtons.setButton(igp.widthResize);
307 fl_set_input(dialog_->input_width,
308 tostr(igp.widthSize).c_str());
310 // Update the height radio buttons and input field
311 heightButtons.setButton(igp.heightResize);
312 fl_set_input(dialog_->input_height,
313 tostr(igp.heightSize).c_str());
315 // Update the rotate angle
316 fl_set_input(dialog_->input_rotate_angle,
317 tostr(igp.rotateAngle).c_str());
319 // Update the subcaption check button and input field
320 fl_set_button(dialog_->check_subcaption,
322 fl_set_input(dialog_->input_subcaption,
323 igp.subcaptionText.c_str());
325 // Update the inline figure check button
326 fl_set_button(dialog_->check_inline,
329 // Now make sure that the buttons are set correctly.
333 void FormGraphics::input()
335 // Put verifications that the dialog shows some sane values,
336 // if not disallow clicking on ok/apply.
337 // Possibly use a label in the bottom of the dialog to give the reason.
339 // Is all input boxes convey a valid meaning?
342 // Things that we check (meaning they are incorrect states):
343 // 1. No filename specified.
344 // 2. Width radio button is not Default and width text is not a number.
345 // 3. Height radio button is not Default and height text is a not a number
347 // Note: radio button default means that the user asks for the image
348 // to be included as is with no size change, in this case we don't need
349 // any width or height.
351 // We verify now that there is a filename, it exists, it's a file
352 // and it's readable.
353 string filename = fl_get_input(dialog_->input_filename);
354 FileInfo file(filename);
363 // Width radio button not default and no number.
364 if (!fl_get_button(dialog_->radio_width_default)
365 && strToDbl(fl_get_input(dialog_->input_width)) <= 0.0) {
370 // Height radio button not default and no number.
371 if (!fl_get_button(dialog_->radio_height_default)
372 && strToDbl(fl_get_input(dialog_->input_height)) <= 0.0) {
378 // Now set the buttons to the correct state.
379 if (inputOK && ! lv_->buffer()->isReadonly()) {
380 fl_activate_object(dialog_->button_ok);
381 fl_activate_object(dialog_->button_apply);
382 fl_set_object_lcol(dialog_->button_ok, FL_BLACK);
383 fl_set_object_lcol(dialog_->button_apply, FL_BLACK);
385 fl_deactivate_object(dialog_->button_ok);
386 fl_deactivate_object(dialog_->button_apply);
387 fl_set_object_lcol(dialog_->button_ok, FL_INACTIVE);
388 fl_set_object_lcol(dialog_->button_apply, FL_INACTIVE);
393 // We need these in the file browser.
394 extern string system_lyxdir;
395 extern string user_lyxdir;
396 //extern string system_tempdir;
398 // Need to move this to the form_graphics
399 string FormGraphics::browseFile(string const & filename)
401 if (! filename.empty() )
402 last_image_path = OnlyPath(filename);
404 // Does user clipart directory exist?
405 string bufclip = AddName (user_lyxdir, "clipart");
406 FileInfo fileInfo(bufclip);
407 if (!(fileInfo.isOK() && fileInfo.isDir()))
408 // No - bail out to system clipart directory
409 bufclip = AddName (system_lyxdir, "clipart");
412 fileDlg.SetButton(0, _("Clipart"), bufclip);
417 string p = fileDlg.Select(_("Graphics"),
419 "*(ps|png)", filename);
421 if (p.empty()) return p;
423 last_image_path = OnlyPath(p);
425 if (p.find_first_of("#~$% ") != string::npos) {
426 WriteAlert(_("Filename can't contain any "
427 "of these characters:"),
428 // xgettext:no-c-format
429 _("space, '#', '~', '$' or '%'."));
440 void FormGraphics::browse()
442 // Get the filename from the dialog
443 string filename = fl_get_input(dialog_->input_filename);
445 // Show the file browser dialog
446 string new_filename = browseFile(filename);
448 // Save the filename to the dialog
449 if (new_filename != filename && ! new_filename.empty()) {
450 fl_set_input(dialog_->input_filename,
451 new_filename.c_str());
452 // The above set input doesn't cause an input event so we do
453 // it manually. Otherwise the user needs to cause an input event
454 // to get the ok/apply buttons to be activated.
460 int FormGraphics::WMHideCB(FL_FORM * form, void *)
462 // Ensure that the signal h is disconnected even if the
463 // window manager is used to close the dialog.
464 FormGraphics * pre = static_cast<FormGraphics*>(form->u_vdata);
470 void FormGraphics::OKCB(FL_OBJECT * ob, long)
472 FormGraphics * pre = static_cast<FormGraphics*>(ob->form->u_vdata);
477 void FormGraphics::ApplyCB(FL_OBJECT * ob, long)
479 FormGraphics * pre = static_cast<FormGraphics*>(ob->form->u_vdata);
483 void FormGraphics::CancelCB(FL_OBJECT * ob, long)
485 FormGraphics * pre = static_cast<FormGraphics*>(ob->form->u_vdata);
489 void FormGraphics::BrowseCB(FL_OBJECT * ob, long)
491 FormGraphics * pre = static_cast<FormGraphics*>(ob->form->u_vdata);
495 void FormGraphics::AdvancedOptionsCB(FL_OBJECT * /* ob */, long)
497 // FormGraphics * pre = static_cast<FormGraphics*>(ob->form->u_vdata);
498 // pre->showAdvancedOptions();
499 lyxerr << "Advanced Options button depressed, "
500 "show advanced options dialog"
504 void FormGraphics::InputCB(FL_OBJECT * ob, long)
506 FormGraphics * pre = static_cast<FormGraphics*>(ob->form->u_vdata);