/** * \file FormFloat.C * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * * \author Lars Gullik Bjønnes * \author Jürgen Spitzmüller * \author Rob Lahaye * * Full author contact details are available in file CREDITS. */ #include #include "FormFloat.h" #include "ControlFloat.h" #include "forms/form_float.h" #include "Tooltips.h" #include "xforms_helpers.h" #include "xformsBC.h" #include "insets/insetfloat.h" #include "support/lstrings.h" #include "lyx_forms.h" using std::string; namespace lyx { using support::contains; namespace frontend { namespace { enum { DOCUMENT_DEFAULTS, HERE_DEFINITELY, ALTERNATIVES }; } // namespace anon typedef FormController > base_class; FormFloat::FormFloat(Dialog & parent) : base_class(parent, _("Float Settings")) {} void FormFloat::build() { dialog_.reset(build_float(this)); // Manage the ok, apply and cancel/close buttons bcview().setOK(dialog_->button_ok); bcview().setApply(dialog_->button_apply); bcview().setCancel(dialog_->button_close); bcview().setRestore(dialog_->button_restore); // disable for read-only documents bcview().addReadOnly(dialog_->radio_default); bcview().addReadOnly(dialog_->radio_here_definitely); bcview().addReadOnly(dialog_->radio_alternatives); bcview().addReadOnly(dialog_->check_top); bcview().addReadOnly(dialog_->check_bottom); bcview().addReadOnly(dialog_->check_page); bcview().addReadOnly(dialog_->check_here); bcview().addReadOnly(dialog_->check_force); bcview().addReadOnly(dialog_->check_wide); bcview().addReadOnly(dialog_->check_sideways); placement_.init(dialog_->radio_default, DOCUMENT_DEFAULTS); placement_.init(dialog_->radio_here_definitely, HERE_DEFINITELY); placement_.init(dialog_->radio_alternatives, ALTERNATIVES); // set up the tooltips string str = _("Use the document's default settings."); tooltips().init(dialog_->radio_default, str); str = _("Enforce placement of float here."); tooltips().init(dialog_->radio_here_definitely, str); str = _("Alternative suggestions for placement of float."); tooltips().init(dialog_->radio_alternatives, str); str = _("Try top of page."); tooltips().init(dialog_->check_top, str); str = _("Try bottom of page."); tooltips().init(dialog_->check_bottom, str); str = _("Put float on a separate page of floats."); tooltips().init(dialog_->check_page, str); str = _("Try float here."); tooltips().init(dialog_->check_here, str); str = _("Ignore internal settings. This is the \"!\" in LaTeX."); tooltips().init(dialog_->check_force, str); str = _("Span float over the columns."); tooltips().init(dialog_->check_wide, str); str = _("Rotate the float sideways by 90 degs."); tooltips().init(dialog_->check_sideways, str); } void FormFloat::apply() { bool const wide = fl_get_button(dialog_->check_wide); bool const sideways = fl_get_button(dialog_->check_sideways); string placement; switch (placement_.get()) { case ALTERNATIVES: if (fl_get_button(dialog_->check_force)) { // Ignore internal LaTeX rules placement += '!'; } if (fl_get_button(dialog_->check_top)) { // Top of page placement += 't'; } if (fl_get_button(dialog_->check_bottom)) { // Bottom of page placement += 'b'; } if (fl_get_button(dialog_->check_page)) { // Page of floats placement += 'p'; } // ignore if wide is selected if (!wide && fl_get_button(dialog_->check_here)) { // Here, if possible placement += 'h'; } if (placement == "!") { // ignore placement if only force is selected. placement.erase(); } if (placement.length() == 0) { // none of Alternatives is selected; flip to default placement.erase(); placement_.set(dialog_->radio_default); setEnabled(dialog_->check_force, false); setEnabled(dialog_->check_top, false); setEnabled(dialog_->check_bottom, false); setEnabled(dialog_->check_page, false); setEnabled(dialog_->check_here, false); } break; case HERE_DEFINITELY: placement = "H"; break; case DOCUMENT_DEFAULTS: // default, do nothing. break; } controller().params().placement = placement; controller().params().wide = wide; controller().params().sideways = sideways; } void FormFloat::update() { string placement(controller().params().placement); bool const wide = controller().params().wide; bool const sideways = controller().params().sideways; bool const sideways_possible = (controller().params().type == "figure" || controller().params().type == "table"); bool const here_definitely = contains(placement, 'H'); bool const top = contains(placement, 't'); bool const bottom = contains(placement, 'b'); bool const page = contains(placement, 'p'); bool const here = contains(placement, 'h'); bool const force = contains(placement, '!'); bool const alternatives = top || bottom || page || (here && !wide); if (alternatives) { placement_.set(dialog_->radio_alternatives); } else if (here_definitely) { placement_.set(dialog_->radio_here_definitely); } else { placement_.set(dialog_->radio_default); } fl_set_button(dialog_->check_force, force); fl_set_button(dialog_->check_top, top); fl_set_button(dialog_->check_bottom, bottom); fl_set_button(dialog_->check_page, page); fl_set_button(dialog_->check_here, here); fl_set_button(dialog_->check_wide, wide); fl_set_button(dialog_->check_sideways, sideways); setEnabled(dialog_->radio_here_definitely, !wide && !sideways); setEnabled(dialog_->check_force, alternatives && !sideways); setEnabled(dialog_->check_top, alternatives && !sideways); setEnabled(dialog_->check_bottom, alternatives && !sideways); setEnabled(dialog_->check_page, alternatives && !sideways); setEnabled(dialog_->check_here, alternatives && !wide && !sideways); setEnabled(dialog_->check_wide, !sideways); setEnabled(dialog_->radio_default, !sideways); setEnabled(dialog_->radio_alternatives, !sideways); setEnabled(dialog_->check_sideways, sideways_possible); } ButtonPolicy::SMInput FormFloat::input(FL_OBJECT * ob, long) { bool const alternatives = placement_.get() == ALTERNATIVES; bool const wide = fl_get_button(dialog_->check_wide); bool const sideways = fl_get_button(dialog_->check_sideways); if (ob == dialog_->radio_default || ob == dialog_->radio_here_definitely || ob == dialog_->radio_alternatives) { // enable check buttons only for Alternatives setEnabled(dialog_->check_top, alternatives); setEnabled(dialog_->check_page, alternatives); // wide float doesn't allow 'here' or 'bottom' placement setEnabled(dialog_->check_here, alternatives && !wide); setEnabled(dialog_->check_bottom, alternatives && !wide); } else if (ob == dialog_->check_wide) { if (wide && placement_.get() == HERE_DEFINITELY) { // wide float doesn't allow 'Here, definitely!' // placement placement_.set(dialog_->radio_default); } setEnabled(dialog_->check_here, alternatives && !wide); setEnabled(dialog_->radio_here_definitely, !wide); setEnabled(dialog_->check_bottom, alternatives && !wide); } else if (ob == dialog_->check_sideways) { setEnabled(dialog_->radio_default, !sideways); setEnabled(dialog_->radio_alternatives, !sideways); setEnabled(dialog_->radio_here_definitely, !wide && !sideways); setEnabled(dialog_->check_top, alternatives && !sideways); setEnabled(dialog_->check_bottom, alternatives && !wide && !sideways); setEnabled(dialog_->check_page, alternatives && !sideways); setEnabled(dialog_->check_here, alternatives && !wide && !sideways); setEnabled(dialog_->check_wide, !sideways); } // enable force button, if Alternatives is selected and at least // one of its check buttons bool const enable_force = alternatives && !sideways && (fl_get_button(dialog_->check_top) || fl_get_button(dialog_->check_bottom) || fl_get_button(dialog_->check_page) || (fl_get_button(dialog_->check_here) && !wide)); setEnabled(dialog_->check_force, enable_force); return ButtonPolicy::SMI_VALID; } } // namespace frontend } // namespace lyx