X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fxforms%2FFormParagraph.C;h=a5f36f809618afe07ac452af612ffe5097a24476;hb=d5443737342903de489d527802cd2cdd38987d74;hp=cbf3a03225f9d4b1ed55c92fdaab639389a0f2a1;hpb=9c628bc4ac7d5332360b088e757b5cf9ecee509e;p=lyx.git diff --git a/src/frontends/xforms/FormParagraph.C b/src/frontends/xforms/FormParagraph.C index cbf3a03225..a5f36f8096 100644 --- a/src/frontends/xforms/FormParagraph.C +++ b/src/frontends/xforms/FormParagraph.C @@ -1,304 +1,127 @@ /** * \file FormParagraph.C - * Copyright 2000-2001 The LyX Team. - * See the file COPYING. + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. * - * \author Jürgen Vigna, jug@sad.it + * \author Jürgen Vigna + * \author Rob Lahaye + * + * Full author contact details are available in file CREDITS. */ #include -#ifdef __GNUG_ -#pragma implementation -#endif - -#include FORMS_H_LOCATION - #include "FormParagraph.h" -#include "form_paragraph.h" -#include "Dialogs.h" -#include "Liason.h" -#include "LyXView.h" -#include "buffer.h" -#include "lyxtext.h" +#include "ControlParagraph.h" +#include "forms/form_paragraph.h" + +#include "checkedwidgets.h" +#include "input_validators.h" +#include "Tooltips.h" #include "xforms_helpers.h" +#include "xformsBC.h" + +#include "controllers/helper_funcs.h" + #include "lyxrc.h" // to set the deafult length values -#include "BufferView.h" -#include "lyxtextclasslist.h" -#include "Spacing.h" #include "ParagraphParameters.h" -#include "input_validators.h" -#include "helper_funcs.h" +#include "Spacing.h" #include "support/lstrings.h" -#include "support/LAssert.h" +#include "support/convert.h" -#include +#include "lyx_forms.h" -using Liason::setMinibuffer; -using SigC::slot; -using std::vector; -using std::bind2nd; -using std::remove_if; - - -FormParagraph::FormParagraph(LyXView * lv, Dialogs * d) - : FormBaseBD(lv, d, _("Paragraph Layout")), par_(0) -{ - // let the dialog be shown - // This is a permanent connection so we won't bother - // storing a copy because we won't be disconnecting. - d->showParagraph.connect(slot(this, &FormParagraph::show)); -} - - -void FormParagraph::connect() -{ - cp_ = d_->updateParagraph - .connect(slot(this, &FormParagraph::changedParagraph)); - FormBaseBD::connect(); -} +#include +using boost::bind; -void FormParagraph::disconnect() -{ - cp_.disconnect(); - FormBaseBD::disconnect(); -} - - -Paragraph const * FormParagraph::getCurrentParagraph() const -{ - return lv_->view()->getLyXText()->cursor.par(); -} - - -void FormParagraph::changedParagraph() -{ - /// Record the paragraph - Paragraph const * const p = getCurrentParagraph(); - if (p == 0 || p == par_) - return; +using std::remove_if; - // For now, don't bother checking if the params are different. +using std::vector; +using std::string; - // Will the underlying paragraph accept our changes? - Inset * const inset = p->inInset(); - bool const accept = !(inset && inset->forceDefaultParagraphs(inset)); - bc().valid(accept); +namespace lyx { - if (!accept) { - postWarning(_("Cannot apply paragraph settings to this inset!")); - } -} +using support::contains; +using support::getStringFromVector; +using support::rtrim; +namespace frontend { -void FormParagraph::redraw() -{ - if (form() && form()->visible) - fl_redraw_form(form()); -} - +typedef FormController > base_class; -FL_FORM * FormParagraph::form() const -{ - if (dialog_.get()) - return dialog_->form; - return 0; -} +FormParagraph::FormParagraph(Dialog & parent) + : base_class(parent, _("Paragraph Settings")) +{} void FormParagraph::build() { // the tabbed folder - dialog_.reset(build_paragraph()); + dialog_.reset(build_paragraph(this)); - // Allow the base class to control messages - setMessageWidget(dialog_->text_warning); + // Manage the ok, apply, restore and cancel/close buttons + bcview().setOK(dialog_->button_ok); + bcview().setApply(dialog_->button_apply); + bcview().setCancel(dialog_->button_close); + bcview().setRestore(dialog_->button_restore); - fl_addto_choice(dialog_->choice_space_above, - _(" None | Defskip | Smallskip " - "| Medskip | Bigskip | VFill | Length ")); - fl_addto_choice(dialog_->choice_space_below, - _(" None | Defskip | Smallskip " - "| Medskip | Bigskip | VFill | Length ")); + // disable for read-only documents + bcview().addReadOnly(dialog_->check_noindent); + bcview().addReadOnly(dialog_->choice_linespacing); + bcview().addReadOnly(dialog_->input_linespacing); - fl_addto_choice(dialog_->choice_linespacing, - _(" Default | Single | OneHalf | Double | Other ")); + bcview().addReadOnly(dialog_->input_labelwidth); + + // trigger an input event for cut&paste with middle mouse button. + setPrehandler(dialog_->input_linespacing); + setPrehandler(dialog_->input_labelwidth); - fl_set_input_return(dialog_->input_space_above, FL_RETURN_CHANGED); - fl_set_input_return(dialog_->input_space_below, FL_RETURN_CHANGED); fl_set_input_return(dialog_->input_labelwidth, FL_RETURN_CHANGED); fl_set_input_return(dialog_->input_linespacing, FL_RETURN_CHANGED); + + // limit these inputs to unsigned floats fl_set_input_filter(dialog_->input_linespacing, fl_unsigned_float_filter); - setPrehandler(dialog_->input_space_above); - setPrehandler(dialog_->input_space_below); - setPrehandler(dialog_->input_labelwidth); - setPrehandler(dialog_->input_linespacing); + // add alignment radio buttons + alignment_.init(dialog_->radio_align_left, LYX_ALIGN_LEFT); + alignment_.init(dialog_->radio_align_right, LYX_ALIGN_RIGHT); + alignment_.init(dialog_->radio_align_block, LYX_ALIGN_BLOCK); + alignment_.init(dialog_->radio_align_center, LYX_ALIGN_CENTER); + + string const linespacing = _("Default|Single|OneHalf|Double|Custom"); + fl_addto_choice(dialog_->choice_linespacing, linespacing.c_str()); - // Create the contents of the unit choices - // Don't include the "%" terms... + // Create the contents of the unit choices; don't include the "%" terms. vector units_vec = getLatexUnits(); -#if 0 - for (vector::iterator it = units_vec.begin(); - it != units_vec.end(); ++it) { - if (contains(*it, "%")) - it = units_vec.erase(it, it+1) - 1; - } -#else - // Something similar to this is a better way to erase vector::iterator del = remove_if(units_vec.begin(), units_vec.end(), - bind2nd(contains_functor(), "%")); + bind(contains, _1, '%')); units_vec.erase(del, units_vec.end()); -#endif - - string units = getStringFromVector(units_vec, "|"); - - fl_addto_choice(dialog_->choice_value_space_above, units.c_str()); - fl_addto_choice(dialog_->choice_value_space_below, units.c_str()); - - // Manage the ok, apply, restore and cancel/close buttons - bc_.setOK(dialog_->button_ok); - bc_.setApply(dialog_->button_apply); - bc_.setCancel(dialog_->button_close); - bc_.setRestore(dialog_->button_restore); - - bc_.addReadOnly(dialog_->radio_align_right); - bc_.addReadOnly(dialog_->radio_align_left); - bc_.addReadOnly(dialog_->radio_align_block); - bc_.addReadOnly(dialog_->radio_align_center); - bc_.addReadOnly(dialog_->check_lines_top); - bc_.addReadOnly(dialog_->check_lines_bottom); - bc_.addReadOnly(dialog_->check_pagebreaks_top); - bc_.addReadOnly(dialog_->check_pagebreaks_bottom); - bc_.addReadOnly(dialog_->choice_space_above); - bc_.addReadOnly(dialog_->input_space_above); - bc_.addReadOnly(dialog_->check_space_above); - bc_.addReadOnly(dialog_->choice_space_below); - bc_.addReadOnly(dialog_->input_space_below); - bc_.addReadOnly(dialog_->check_space_below); - bc_.addReadOnly(dialog_->choice_linespacing); - bc_.addReadOnly(dialog_->input_linespacing); - bc_.addReadOnly(dialog_->check_noindent); - bc_.addReadOnly(dialog_->input_labelwidth); -} - - -namespace { - -VSpace setVSpaceFromWidgets(FL_OBJECT * choice_type, - FL_OBJECT * input_length, - FL_OBJECT * choice_length, - FL_OBJECT * check_keep) -{ - // Paranoia check! - lyx::Assert(choice_type && choice_type->objclass == FL_CHOICE && - input_length && input_length->objclass == FL_INPUT && - choice_length && choice_length->objclass == FL_CHOICE && - check_keep && check_keep->objclass == FL_CHECKBUTTON); - - VSpace space; - - switch (fl_get_choice(choice_type)) { - case 1: - space = VSpace(VSpace::NONE); - break; - case 2: - space = VSpace(VSpace::DEFSKIP); - break; - case 3: - space = VSpace(VSpace::SMALLSKIP); - break; - case 4: - space = VSpace(VSpace::MEDSKIP); - break; - case 5: - space = VSpace(VSpace::BIGSKIP); - break; - case 6: - space = VSpace(VSpace::VFILL); - break; - case 7: - { - string const length = - getLengthFromWidgets(input_length, choice_length); - space = VSpace(LyXGlueLength(length)); - break; - } - } - - if (fl_get_button(check_keep)) - space.setKeep(true); - - return space; -} - - -void validateVSpaceWidgets(FL_OBJECT * choice_type, FL_OBJECT * input_length) -{ - // Paranoia check! - lyx::Assert(choice_type && choice_type->objclass == FL_CHOICE && - input_length && input_length->objclass == FL_INPUT); - - if (fl_get_choice(choice_type) != 7) - return; - - // If a vspace kind is "Length" but there's no text in - // the input field, reset the kind to "None". - string const input = strip(getStringFromInput(input_length)); - if (input.empty()) - fl_set_choice(choice_type, 1); } -} // namespace anon - void FormParagraph::apply() { - if (!lv_->view()->available() || !dialog_.get()) + if (!form()) return; - // If a vspace kind is "Length" but there's no text in - // the input field, reset the kind to "None". - validateVSpaceWidgets(dialog_->choice_space_above, - dialog_->input_space_above); - validateVSpaceWidgets(dialog_->choice_space_below, - dialog_->input_space_below); - - bool const line_top = fl_get_button(dialog_->check_lines_top); - bool const line_bottom = fl_get_button(dialog_->check_lines_bottom); - bool const pagebreak_top = fl_get_button(dialog_->check_pagebreaks_top); - bool const pagebreak_bottom = fl_get_button(dialog_->check_pagebreaks_bottom); - - VSpace const space_top = - setVSpaceFromWidgets(dialog_->choice_space_above, - dialog_->input_space_above, - dialog_->choice_value_space_above, - dialog_->check_space_above); - - VSpace const space_bottom = - setVSpaceFromWidgets(dialog_->choice_space_below, - dialog_->input_space_below, - dialog_->choice_value_space_below, - dialog_->check_space_below); - - LyXAlignment align; - if (fl_get_button(dialog_->radio_align_left)) - align = LYX_ALIGN_LEFT; - else if (fl_get_button(dialog_->radio_align_right)) - align = LYX_ALIGN_RIGHT; - else if (fl_get_button(dialog_->radio_align_center)) - align = LYX_ALIGN_CENTER; - else - align = LYX_ALIGN_BLOCK; + // alignment + LyXAlignment const alignment = + static_cast(alignment_.get()); + controller().params().align(alignment); + // label width string const labelwidthstring = - getStringFromInput(dialog_->input_labelwidth); + getString(dialog_->input_labelwidth); + controller().params().labelWidthString(labelwidthstring); + // indendation bool const noindent = fl_get_button(dialog_->check_noindent); + controller().params().noindent(noindent); + // get spacing Spacing::Space linespacing = Spacing::Default; string other; switch (fl_get_choice(dialog_->choice_linespacing)) { @@ -315,287 +138,135 @@ void FormParagraph::apply() linespacing = Spacing::Double; break; case 5: - linespacing = Spacing::Other; - other = getStringFromInput(dialog_->input_linespacing); + // reset to default if input is empty + other = getString(dialog_->input_linespacing); + if (!other.empty()) { + linespacing = Spacing::Other; + } else { + linespacing = Spacing::Default; + fl_set_choice(dialog_->choice_linespacing, 1); + } break; } - Spacing const spacing(linespacing, other); - - LyXText * text(lv_->view()->getLyXText()); - text->setParagraph(lv_->view(), line_top, line_bottom, pagebreak_top, - pagebreak_bottom, space_top, space_bottom, spacing, - align, labelwidthstring, noindent); - - // Actually apply these settings - lv_->view()->update(text, - BufferView::SELECT | BufferView::FITCUR | BufferView::CHANGE); - lv_->buffer()->markDirty(); - setMinibuffer(lv_, _("Paragraph layout set")); + controller().params().spacing(spacing); } -namespace { - -void setWidgetsFromVSpace(VSpace const & space, - FL_OBJECT * choice_type, - FL_OBJECT * input_length, - FL_OBJECT * choice_length, - FL_OBJECT * check_keep) -{ - // Paranoia check! - lyx::Assert(choice_type && choice_type->objclass == FL_CHOICE && - input_length && input_length->objclass == FL_INPUT && - choice_length && choice_length->objclass == FL_CHOICE && - check_keep && check_keep->objclass == FL_CHECKBUTTON); - - fl_set_input(input_length, ""); - setEnabled(input_length, false); - setEnabled(choice_length, false); - - switch (space.kind()) { - case VSpace::NONE: - fl_set_choice(choice_type, 1); - break; - case VSpace::DEFSKIP: - fl_set_choice(choice_type, 2); - break; - case VSpace::SMALLSKIP: - fl_set_choice(choice_type, 3); - break; - case VSpace::MEDSKIP: - fl_set_choice(choice_type, 4); - break; - case VSpace::BIGSKIP: - fl_set_choice(choice_type, 5); - break; - case VSpace::VFILL: - fl_set_choice(choice_type, 6); - break; - case VSpace::LENGTH: - { - fl_set_choice(choice_type, 7); - - setEnabled(input_length, true); - setEnabled(choice_length, true); - - bool const metric = lyxrc.default_papersize > 3; - string const default_unit = metric ? "cm" : "in"; - string const length = space.length().asString(); - - updateWidgetsFromLengthString(input_length, choice_length, - length, default_unit); - break; - } - } - - fl_set_button(check_keep, space.keep()); -} - -} // namespace anon - - void FormParagraph::update() { if (!dialog_.get()) return; - // Do this first; some objects may be de/activated subsequently. - bc_.readOnly(lv_->buffer()->isReadonly()); - - /// Record the paragraph - par_ = getCurrentParagraph(); - - fl_set_input(dialog_->input_labelwidth, - par_->getLabelWidthString().c_str()); + // label width + string const labelwidth = controller().params().labelWidthString(); + fl_set_input(dialog_->input_labelwidth, labelwidth.c_str()); setEnabled(dialog_->input_labelwidth, - (par_->getLabelWidthString() != _("Senseless with this layout!"))); + labelwidth != _("Senseless with this layout!")); - fl_set_button(dialog_->radio_align_right, 0); - fl_set_button(dialog_->radio_align_left, 0); - fl_set_button(dialog_->radio_align_center, 0); - fl_set_button(dialog_->radio_align_block, 0); + // alignment + alignment_.set(controller().params().align()); - LyXTextClass const & tclass = - textclasslist[lv_->view()->buffer()->params.textclass]; + // mark default alignment + LyXAlignment const default_alignment = controller().alignDefault(); - int align = par_->getAlign(); - if (align == LYX_ALIGN_LAYOUT) - align = tclass[par_->layout()].align; + string label = _("Block"); + if (default_alignment == LYX_ALIGN_BLOCK) { + label += _(" (default)"); + } + fl_set_object_label(dialog_->radio_align_block, label.c_str()); + fl_set_button_shortcut(dialog_->radio_align_block, "#B", 1); - switch (align) { - case LYX_ALIGN_RIGHT: - fl_set_button(dialog_->radio_align_right, 1); - break; - case LYX_ALIGN_LEFT: - fl_set_button(dialog_->radio_align_left, 1); - break; - case LYX_ALIGN_CENTER: - fl_set_button(dialog_->radio_align_center, 1); - break; - default: - fl_set_button(dialog_->radio_align_block, 1); - break; + label = _("Center"); + if (default_alignment == LYX_ALIGN_CENTER) { + label += _(" (default)"); + } + fl_set_object_label(dialog_->radio_align_center, label.c_str()); + fl_set_button_shortcut(dialog_->radio_align_center, "#C", 1); + + label = _("Left"); + if (default_alignment == LYX_ALIGN_LEFT) { + label += _(" (default)"); } + fl_set_object_label(dialog_->radio_align_left, label.c_str()); + fl_set_button_shortcut(dialog_->radio_align_left, "#L", 1); - LyXAlignment alignpos = tclass[par_->layout()].alignpossible; - - setEnabled(dialog_->radio_align_block, bool(alignpos & LYX_ALIGN_BLOCK)); - setEnabled(dialog_->radio_align_center, bool(alignpos & LYX_ALIGN_CENTER)); - setEnabled(dialog_->radio_align_left, bool(alignpos & LYX_ALIGN_LEFT)); - setEnabled(dialog_->radio_align_right, bool(alignpos & LYX_ALIGN_RIGHT)); - - // no inset-text-owned paragraph may have pagebreaks - setEnabled(dialog_->check_pagebreaks_top, !par_->inInset()); - setEnabled(dialog_->check_pagebreaks_bottom, !par_->inInset()); - - fl_set_button(dialog_->check_lines_top, - par_->params().lineTop()); - fl_set_button(dialog_->check_lines_bottom, - par_->params().lineBottom()); - fl_set_button(dialog_->check_pagebreaks_top, - par_->params().pagebreakTop()); - fl_set_button(dialog_->check_pagebreaks_bottom, - par_->params().pagebreakBottom()); + label = _("Right"); + if (default_alignment == LYX_ALIGN_RIGHT) { + label = _(" (default)"); + } + fl_set_object_label(dialog_->radio_align_right, label.c_str()); + fl_set_button_shortcut(dialog_->radio_align_right, "#R", 1); + + // Ensure that there's no crud left on the screen from this change + // of labels. + fl_redraw_form(form()); + + LyXAlignment alignpos = controller().alignPossible(); + setEnabled(dialog_->radio_align_block, + bool(alignpos & LYX_ALIGN_BLOCK)); + setEnabled(dialog_->radio_align_center, + bool(alignpos & LYX_ALIGN_CENTER)); + setEnabled(dialog_->radio_align_left, + bool(alignpos & LYX_ALIGN_LEFT)); + setEnabled(dialog_->radio_align_right, + bool(alignpos & LYX_ALIGN_RIGHT)); + + // lines, pagebreaks and indent fl_set_button(dialog_->check_noindent, - par_->params().noindent()); + controller().params().noindent()); - int linespacing; - Spacing const space = par_->params().spacing(); + // linespacing + Spacing const space = controller().params().spacing(); + int pos; switch (space.getSpace()) { - default: linespacing = 1; break; - case Spacing::Single: linespacing = 2; break; - case Spacing::Onehalf: linespacing = 3; break; - case Spacing::Double: linespacing = 4; break; - case Spacing::Other: linespacing = 5; break; + case Spacing::Other: + pos = 5; + break; + case Spacing::Double: + pos = 4; + break; + case Spacing::Onehalf: + pos = 3; + break; + case Spacing::Single: + pos = 2; + break; + case Spacing::Default: + default: + pos = 1; + break; } + fl_set_choice(dialog_->choice_linespacing, pos); - fl_set_choice(dialog_->choice_linespacing, linespacing); - if (space.getSpace() == Spacing::Other) { - string const sp = tostr(space.getValue()); - fl_set_input(dialog_->input_linespacing, sp.c_str()); - setEnabled(dialog_->input_linespacing, true); + bool const spacing_other = space.getSpace() == Spacing::Other; + setEnabled(dialog_->input_linespacing, spacing_other); + if (spacing_other) { + fl_set_input(dialog_->input_linespacing, + space.getValueAsString().c_str()); } else { fl_set_input(dialog_->input_linespacing, ""); - setEnabled(dialog_->input_linespacing, false); } - setWidgetsFromVSpace(par_->params().spaceTop(), - dialog_->choice_space_above, - dialog_->input_space_above, - dialog_->choice_value_space_above, - dialog_->check_space_above); - - setWidgetsFromVSpace(par_->params().spaceBottom(), - dialog_->choice_space_below, - dialog_->input_space_below, - dialog_->choice_value_space_below, - dialog_->check_space_below); - + // no indent fl_set_button(dialog_->check_noindent, - par_->params().noindent()); + controller().params().noindent()); } -namespace { - -void synchronizeSpaceWidgets(FL_OBJECT * choice_type, - FL_OBJECT * input_length, - FL_OBJECT * choice_length, - bool readonly) +ButtonPolicy::SMInput FormParagraph::input(FL_OBJECT * ob, long) { - // Paranoia check! - lyx::Assert(choice_type && choice_type->objclass == FL_CHOICE && - input_length && input_length->objclass == FL_INPUT && - choice_length && choice_length->objclass == FL_CHOICE); - - if (fl_get_choice(choice_type) != 7) { - fl_set_input(input_length, ""); - setEnabled(input_length, false); - setEnabled(choice_length, false); - - } else { - setEnabled(input_length, !readonly); - setEnabled(choice_length, !readonly); - - string const length = getStringFromInput(input_length); - - if (strip(length).empty()) { - bool const metric = lyxrc.default_papersize > 3; - int const default_unit = metric ? 8 : 9; - - fl_set_choice(choice_length, default_unit); - } + // Enable input when custum length is choosen, + // disable 'keep' when no space is choosen + if (ob == dialog_->choice_linespacing) { + bool const custom_spacing = + fl_get_choice(dialog_->choice_linespacing) == 5; + setEnabled(dialog_->input_linespacing, custom_spacing); } -} - -bool validSpaceWidgets(FL_OBJECT * choice_type, FL_OBJECT * input_length) -{ - // Paranoia check! - lyx::Assert(choice_type && choice_type->objclass == FL_CHOICE && - input_length && input_length->objclass == FL_INPUT); - - if (fl_get_choice(choice_type) != 7) - return true; - string const input = getStringFromInput(input_length); - return (input.empty() || - isValidGlueLength(input) || - isStrDbl(input)); + return ButtonPolicy::SMI_VALID; } -} // namespace anon - - -bool FormParagraph::input(FL_OBJECT * ob, long) -{ - clearMessage(); - - // First check the buttons which are exclusive and you have to - // check only the actuall de/activated button. - // - // "Synchronize" the choices and input fields, making it - // impossible to commit senseless data. - - if (ob == dialog_->choice_space_above) { - synchronizeSpaceWidgets(dialog_->choice_space_above, - dialog_->input_space_above, - dialog_->choice_value_space_above, - lv_->buffer()->isReadonly()); - } - - if (ob == dialog_->choice_space_below) { - synchronizeSpaceWidgets(dialog_->choice_space_below, - dialog_->input_space_below, - dialog_->choice_value_space_below, - lv_->buffer()->isReadonly()); - } - - // Display a warning if the input is senseless - bool valid = (validSpaceWidgets(dialog_->choice_space_above, - dialog_->input_space_above) && - validSpaceWidgets(dialog_->choice_space_below, - dialog_->input_space_below)); - - if (!valid) { - postWarning(_("Invalid Length (valid example: 10mm)")); - } - - int const choice_spacing = fl_get_choice(dialog_->choice_linespacing); - - if (choice_spacing == 5) - setEnabled(dialog_->input_linespacing, true); - else { - fl_set_input(dialog_->input_linespacing, ""); - setEnabled(dialog_->input_linespacing, false); - } - - double const spacing = - strToDbl(getStringFromInput(dialog_->input_linespacing)); - - if (choice_spacing == 5 && int(spacing) == 0) - valid = false; - - return valid; -} +} // namespace frontend +} // namespace lyx