From aa9543fa2bcb1bda0435cee5c1a24a2c3d5008b7 Mon Sep 17 00:00:00 2001 From: Juergen Spitzmueller Date: Thu, 10 May 2018 20:15:11 +0200 Subject: [PATCH] Add support for global float alignment It is now possible in the float settings (doc dialog) to specify a global (inner) alignment for floats, and in the float settings, this can be overridden (just as with float placement) Fixes: #8665 File format change. --- development/FORMAT | 8 + lib/lyx2lyx/lyx_2_4.py | 74 +++++- src/Buffer.cpp | 1 + src/BufferParams.cpp | 7 +- src/BufferParams.h | 2 + src/frontends/qt4/FloatPlacement.cpp | 106 ++++++-- src/frontends/qt4/FloatPlacement.h | 14 +- src/frontends/qt4/GuiDocument.cpp | 10 +- src/frontends/qt4/ui/FloatPlacementUi.ui | 305 ++++++++++++++++------- src/insets/InsetFloat.cpp | 35 ++- src/insets/InsetFloat.h | 5 +- src/version.h | 4 +- 12 files changed, 431 insertions(+), 140 deletions(-) diff --git a/development/FORMAT b/development/FORMAT index 8338ee1b39..d443601afb 100644 --- a/development/FORMAT +++ b/development/FORMAT @@ -7,6 +7,14 @@ changes happened in particular if possible. A good example would be ----------------------- +2018-05-10 Jürgen Spitzmüller + * format incremented to 552: support for float alignment + - add buffer param \float_alignment [class|left|center|right] + - add buffer param \float_placement class + - add float param alignment [class|document|left|center|right] + - add float param placement class (=> new param) + - add float param placement document(=> like formerly empty param) + 2018-05-06 Jürgen Spitzmüller * format incremented to 551: add font info param \nospellcheck that prevents text from being spellchecked. diff --git a/lib/lyx2lyx/lyx_2_4.py b/lib/lyx2lyx/lyx_2_4.py index 941703a163..fae273d0af 100644 --- a/lib/lyx2lyx/lyx_2_4.py +++ b/lib/lyx2lyx/lyx_2_4.py @@ -213,6 +213,74 @@ def revert_nospellcheck(document): del document.body[i] +def revert_floatpclass(document): + " Remove float placement params 'document' and 'class' " + + i = 0 + i = find_token(document.header, "\\float_placement class", 0) + if i != -1: + del document.header[i] + + i = 0 + while True: + i = find_token(document.body, '\\begin_inset Float', i) + if i == -1: + break + j = find_end_of_inset(document.body, i) + k = find_token(document.body, 'placement class', i, i + 2) + if k == -1: + k = find_token(document.body, 'placement document', i, i + 2) + if k != -1: + del document.body[k] + i = j + continue + del document.body[k] + + +def revert_floatalignment(document): + " Remove float alignment params " + + i = 0 + i = find_token(document.header, "\\float_alignment", 0) + galignment = "" + if i != -1: + galignment = get_value(document.header, "\\float_alignment", i) + del document.header[i] + + i = 0 + while True: + i = find_token(document.body, '\\begin_inset Float', i) + if i == -1: + break + j = find_end_of_inset(document.body, i) + if j == -1: + document.warning("Malformed LyX document: Can't find end of inset at line " + str(i)) + i += 1 + k = find_token(document.body, 'alignment', i, i + 4) + if k == -1: + i = j + continue + alignment = get_value(document.body, "alignment", k) + if alignment == "document": + alignment = galignment + del document.body[k] + l = find_token(document.body, "\\begin_layout Plain Layout", i, j) + if l == -1: + document.warning("Can't find float layout!") + i = j + continue + alcmd = [] + if alignment == "left": + alcmd = put_cmd_in_ert("\\raggedright{}") + elif alignment == "center": + alcmd = put_cmd_in_ert("\\centering{}") + elif alignment == "right": + alcmd = put_cmd_in_ert("\\raggedleft{}") + if len(alcmd) > 0: + document.body[l+1:l+1] = alcmd + i = j + + ## # Conversion hub # @@ -225,11 +293,13 @@ convert = [ [548, []], [549, []], [550, [convert_fontenc]], - [551, []] + [551, []], + [552, []] ] revert = [ - [549, [revert_nospellcheck]], + [551, [revert_floatpclass, revert_floatalignment]], + [550, [revert_nospellcheck]], [549, [revert_fontenc]], [548, []],# dummy format change [547, [revert_lscape]], diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 83a82f84c8..47db5f0552 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -888,6 +888,7 @@ int Buffer::readHeader(Lexer & lex) params().options.erase(); params().master.erase(); params().float_placement.erase(); + params().float_alignment.erase(); params().paperwidth.erase(); params().paperheight.erase(); params().leftmargin.erase(); diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index 7211f12b83..6d52731f76 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -1071,6 +1071,8 @@ string BufferParams::readToken(Lexer & lex, string const & token, spacing().set(spacetranslator().find(nspacing), tmp_val); } else if (token == "\\float_placement") { lex >> float_placement; + } else if (token == "\\float_alignment") { + lex >> float_alignment; } else if (prefixIs(token, "\\pdf_") || token == "\\use_hyperref") { string toktmp = pdfoptions().readToken(lex, token); @@ -1261,9 +1263,10 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const os << "\\bibtex_command " << bibtex_command << '\n'; os << "\\index_command " << index_command << '\n'; - if (!float_placement.empty()) { + if (!float_placement.empty()) os << "\\float_placement " << float_placement << '\n'; - } + if (!float_alignment.empty()) + os << "\\float_alignment " << float_alignment << '\n'; os << "\\paperfontsize " << fontsize << '\n'; spacing().writeFile(os); diff --git a/src/BufferParams.h b/src/BufferParams.h index bc5c10d194..21c6cff557 100644 --- a/src/BufferParams.h +++ b/src/BufferParams.h @@ -352,6 +352,8 @@ public: /// std::string float_placement; /// + std::string float_alignment; + /// unsigned int columns; /// bool justification; diff --git a/src/frontends/qt4/FloatPlacement.cpp b/src/frontends/qt4/FloatPlacement.cpp index 59bdf62ec8..810644a6b4 100644 --- a/src/frontends/qt4/FloatPlacement.cpp +++ b/src/frontends/qt4/FloatPlacement.cpp @@ -5,6 +5,7 @@ * * \author Edwin Leuven * \author John Levon + * \author Jürgen Spitzmüller * * Full author contact details are available in file CREDITS. */ @@ -33,12 +34,13 @@ namespace lyx { namespace frontend { FloatPlacement::FloatPlacement(bool show_options, QWidget * parent) - : InsetParamsWidget(parent), standardfloat_ (true), + : InsetParamsWidget(parent), standardfloat_(true), allows_wide_(true), allows_sideways_(true), float_list_(0) { setupUi(this); connect(floatTypeCO, SIGNAL(activated(int)), this, SLOT(changedSlot())); + connect(placementCO, SIGNAL(activated(int)), this, SLOT(changedSlot())); connect(topCB, SIGNAL(clicked()), this, SLOT(changedSlot())); connect(bottomCB, SIGNAL(clicked()), this, SLOT(changedSlot())); connect(pageCB, SIGNAL(clicked()), this, SLOT(changedSlot())); @@ -47,11 +49,19 @@ FloatPlacement::FloatPlacement(bool show_options, QWidget * parent) connect(ignoreCB, SIGNAL(clicked()), this, SLOT(changedSlot())); connect(spanCB, SIGNAL(clicked()), this, SLOT(changedSlot())); connect(sidewaysCB, SIGNAL(clicked()), this, SLOT(changedSlot())); + connect(alignClassDefaultRB, SIGNAL(clicked()), this, SLOT(changedSlot())); + connect(alignDocDefaultRB, SIGNAL(clicked()), this, SLOT(changedSlot())); + connect(alignLeftRB, SIGNAL(clicked()), this, SLOT(changedSlot())); + connect(alignCenterRB, SIGNAL(clicked()), this, SLOT(changedSlot())); + connect(alignRightRB, SIGNAL(clicked()), this, SLOT(changedSlot())); floatTypeTitle->setVisible(show_options); floatTypeCO->setVisible(show_options); + alignDocDefaultRB->setVisible(show_options); spanCB->setVisible(show_options); sidewaysCB->setVisible(show_options); + optionsGB->setVisible(show_options); + initFloatPlacementCO(show_options); } @@ -59,7 +69,10 @@ docstring FloatPlacement::dialogToParams() const { InsetFloatParams params; params.type = fromqstr(floatTypeCO->itemData(floatTypeCO->currentIndex()).toString()); - params.placement = get(params.wide, params.sideways); + params.wide = spanCB->isChecked(); + params.sideways = sidewaysCB->isChecked(); + params.alignment = getAlignment(); + params.placement = getPlacement(); return from_ascii(InsetFloat::params2string(params)); } @@ -82,9 +95,10 @@ bool FloatPlacement::possiblePlacement(char const & p) const } -void FloatPlacement::set(string const & placement) +void FloatPlacement::setPlacement(string const & placement) { bool def_placement = false; + bool doc_placement = false; bool top = false; bool bottom = false; bool page = false; @@ -92,9 +106,11 @@ void FloatPlacement::set(string const & placement) bool force = false; bool here_definitely = false; - if (placement.empty()) { + if (placement.empty() || placement == "class") def_placement = true; - } else if (contains(placement, 'H') && possiblePlacement('H')) { + else if (placement == "document") + doc_placement = true; + else if (contains(placement, 'H') && possiblePlacement('H')) { here_definitely = true; } else { if (contains(placement, '!') && possiblePlacement('!')) { @@ -114,7 +130,12 @@ void FloatPlacement::set(string const & placement) } } - defaultsCB->setChecked(def_placement); + if (def_placement) + placementCO->setCurrentIndex(placementCO->findData(toqstr("class"))); + else if (doc_placement) + placementCO->setCurrentIndex(placementCO->findData(toqstr("document"))); + else + placementCO->setCurrentIndex(placementCO->findData(toqstr("custom"))); topCB->setChecked(top); bottomCB->setChecked(bottom); pageCB->setChecked(page); @@ -125,6 +146,21 @@ void FloatPlacement::set(string const & placement) } +void FloatPlacement::setAlignment(string const & alignment) +{ + if (alignment == "document") + alignDocDefaultRB->setChecked(true); + else if (alignment == "left") + alignLeftRB->setChecked(true); + else if (alignment == "center") + alignCenterRB->setChecked(true); + else if (alignment == "right") + alignRightRB->setChecked(true); + else + alignClassDefaultRB->setChecked(true); +} + + void FloatPlacement::initFloatTypeCO(FloatList const & floats) { if (float_list_ == &floats) @@ -141,6 +177,15 @@ void FloatPlacement::initFloatTypeCO(FloatList const & floats) } +void FloatPlacement::initFloatPlacementCO(bool const local) +{ + placementCO->addItem(qt_("Class Defaults"), "class"); + if (local) + placementCO->addItem(qt_("Document Defaults"), "document"); + placementCO->addItem(qt_("Custom"), "custom"); +} + + void FloatPlacement::paramsToDialog(Inset const * inset) { InsetFloat const * fl = static_cast(inset); @@ -157,7 +202,8 @@ void FloatPlacement::paramsToDialog(Inset const * inset) allows_sideways_ = floats.allowsSideways(params.type); allows_wide_ = floats.allowsWide(params.type); - set(params.placement); + setPlacement(params.placement); + setAlignment(params.alignment); standardfloat_ = (params.type == "figure" || params.type == "table"); @@ -175,21 +221,16 @@ void FloatPlacement::paramsToDialog(Inset const * inset) } -string const FloatPlacement::get(bool & wide, bool & sideways) const -{ - wide = spanCB->isChecked(); - sideways = sidewaysCB->isChecked(); - - return get(); -} - - -string const FloatPlacement::get() const +string const FloatPlacement::getPlacement() const { string placement; - if (defaultsCB->isChecked()) - return placement; + QString const data = + placementCO->itemData(placementCO->currentIndex()).toString(); + if (data == "class") + return "class"; + if (data == "document") + return "document"; if (heredefinitelyCB->isChecked()) { placement += 'H'; @@ -214,10 +255,24 @@ string const FloatPlacement::get() const } -void FloatPlacement::on_defaultsCB_stateChanged(int state) +string const FloatPlacement::getAlignment() const +{ + if (alignDocDefaultRB->isChecked()) + return "document"; + if (alignLeftRB->isChecked()) + return "left"; + if (alignCenterRB->isChecked()) + return "center"; + if (alignRightRB->isChecked()) + return "right"; + return "class"; +} + + +void FloatPlacement::on_placementCO_currentIndexChanged(QString const & text) { checkAllowed(); - if (state == Qt::Checked) + if (text != "custom") return; if (topCB->isChecked() || bottomCB->isChecked() || pageCB->isChecked() || herepossiblyCB->isChecked() @@ -235,7 +290,8 @@ void FloatPlacement::changedSlot() void FloatPlacement::checkAllowed() const { - bool const defaults = defaultsCB->isChecked(); + bool const defaults = + placementCO->itemData(placementCO->currentIndex()).toString() != "custom"; bool const ignore = topCB->isChecked() || bottomCB->isChecked() || pageCB->isChecked() || herepossiblyCB->isChecked(); bool const heredefinitely = heredefinitelyCB->isChecked(); @@ -273,7 +329,7 @@ void FloatPlacement::checkAllowed() const bottomCB->setChecked(false); spanCB->setEnabled(allows_wide_ && (!sideways || standardfloat_)); sidewaysCB->setEnabled(allows_sideways_); - defaultsCB->setEnabled(!(sideways && span)); + placementCO->setEnabled(!(sideways && span)); } else { topCB->setEnabled(!defaults && !heredefinitely); bottomCB->setEnabled(!defaults && !heredefinitely); @@ -289,8 +345,8 @@ bool FloatPlacement::checkWidgets(bool readonly) const { if (readonly) { floatTypeCO->setEnabled(false); - defaultsCB->setEnabled(false); - options->setEnabled(false); + placementCO->setEnabled(false); + aligmentGB->setEnabled(false); spanCB->setEnabled(false); sidewaysCB->setEnabled(false); } else diff --git a/src/frontends/qt4/FloatPlacement.h b/src/frontends/qt4/FloatPlacement.h index c5f8dd7ef1..d5d9449538 100644 --- a/src/frontends/qt4/FloatPlacement.h +++ b/src/frontends/qt4/FloatPlacement.h @@ -45,22 +45,26 @@ public: /// void useSideways(); /// - void set(std::string const & placement); + void setPlacement(std::string const & placement); /// - std::string const get() const; + void setAlignment(std::string const & placement); + /// + std::string const getPlacement() const; + /// + std::string const getAlignment() const; private Q_SLOTS: - void on_defaultsCB_stateChanged(int state); + void on_placementCO_currentIndexChanged(QString const &); void changedSlot(); private: /// void checkAllowed() const; /// - std::string const get(bool & wide, bool & sideways) const; - /// void initFloatTypeCO(FloatList const & floats); /// + void initFloatPlacementCO(bool const); + /// bool possiblePlacement(char const & p) const; /// one of figure or table? diff --git a/src/frontends/qt4/GuiDocument.cpp b/src/frontends/qt4/GuiDocument.cpp index 5fc1e062c6..b51967799a 100644 --- a/src/frontends/qt4/GuiDocument.cpp +++ b/src/frontends/qt4/GuiDocument.cpp @@ -1556,7 +1556,7 @@ GuiDocument::GuiDocument(GuiView & lv) docPS->addPanel(indicesModule, N_("Indexes")); docPS->addPanel(pdfSupportModule, N_("PDF Properties")); docPS->addPanel(mathsModule, N_("Math Options")); - docPS->addPanel(floatModule, N_("Float Placement")); + docPS->addPanel(floatModule, N_("Float Settings")); docPS->addPanel(listingsModule, N_("Listings[[inset]]")); docPS->addPanel(bulletsModule, N_("Bullets")); docPS->addPanel(branchesModule, N_("Branches")); @@ -3216,8 +3216,9 @@ void GuiDocument::applyView() bp_.maintain_unincluded_children = masterChildModule->maintainAuxCB->isChecked(); - // Float Placement - bp_.float_placement = floatModule->get(); + // Float Settings + bp_.float_placement = floatModule->getPlacement(); + bp_.float_alignment = floatModule->getAlignment(); // Listings // text should have passed validation @@ -3747,7 +3748,8 @@ void GuiDocument::paramsToDialog() bp_.maintain_unincluded_children); // Float Settings - floatModule->set(bp_.float_placement); + floatModule->setPlacement(bp_.float_placement); + floatModule->setAlignment(bp_.float_alignment); // ListingsSettings // break listings_params to multiple lines diff --git a/src/frontends/qt4/ui/FloatPlacementUi.ui b/src/frontends/qt4/ui/FloatPlacementUi.ui index f6e02ae76a..3e447071b3 100644 --- a/src/frontends/qt4/ui/FloatPlacementUi.ui +++ b/src/frontends/qt4/ui/FloatPlacementUi.ui @@ -1,121 +1,258 @@ - + + FloatPlacementUi - - + + 0 0 - 207 - 382 + 530 + 413 - + Form - - - - - Float Type: - - + + + + + + + Float T&ype: + + + floatTypeCO + + + + + + + + 1 + 0 + + + + + - - - - - 1 - 0 - + + + + Qt::Vertical - + + + 20 + 154 + + + - - - - Use &default placement + + + + Qt::Vertical - + + + 20 + 20 + + + - - - - Advanced Placement Options + + + + Alignment of Contents - - + + true + + + 9 - + + 9 + + + 9 + + + 9 + + 6 - - - - &Top of page + + + + Use the document's default alignment for floats, as specified in Document Settings. + + + D&ocument Defaults - - - - &Ignore LaTeX rules + + + + Left-align float contents + + + &Left - - - - Here de&finitely + + + + Center float contents + + + &Center - - - - &Here if possible + + + + Right-align float contents + + + &Right - - - - &Page of floats + + + + Use the class' default alignment for floats, whatever it is. - - - - - - &Bottom of page + + Class &Defaults - - - - &Span columns + + + + Further Options + + + + + &Span columns + + + + + + + Rotate side&ways + + + + - - - - &Rotate sideways + + + + Position on Page + + + + + + + Place&ment Settings: + + + placementCO + + + + + + + + + + + + &Top of page + + + + + + + &Bottom of page + + + + + + + &Page of floats + + + + + + + &Here if possible + + + + + + + Here de&finitely + + + + + + + &Ignore LaTeX rules + + + + - - - - Qt::Vertical + + + + Qt::Horizontal - + - 20 + 303 + 20 + + + + + + + + Qt::Horizontal + + + + 40 20 @@ -124,7 +261,6 @@ - defaultsCB topCB bottomCB pageCB @@ -133,25 +269,8 @@ ignoreCB - qt_i18n.h + qt_i18n.h - - - defaultsCB - toggled(bool) - options - setDisabled(bool) - - - 51 - 20 - - - 201 - 47 - - - - + diff --git a/src/insets/InsetFloat.cpp b/src/insets/InsetFloat.cpp index 021b7f3b17..c3600a111d 100644 --- a/src/insets/InsetFloat.cpp +++ b/src/insets/InsetFloat.cpp @@ -166,6 +166,7 @@ void InsetFloat::doDispatch(Cursor & cur, FuncRequest & cmd) params_.wide = params.wide; params_.sideways = params.sideways; } + params_.alignment = params.alignment; setNewLabel(); if (params_.type != params.type) setCaptionType(params.type); @@ -235,6 +236,8 @@ void InsetFloatParams::write(ostream & os) const if (!placement.empty()) os << "placement " << placement << "\n"; + if (!alignment.empty()) + os << "alignment " << alignment << "\n"; if (wide) os << "wide true\n"; @@ -254,6 +257,8 @@ void InsetFloatParams::read(Lexer & lex) lex >> type; if (lex.checkFor("placement")) lex >> placement; + if (lex.checkFor("alignment")) + lex >> alignment; lex >> "wide" >> wide; lex >> "sideways" >> sideways; } @@ -366,13 +371,14 @@ void InsetFloat::latex(otexstream & os, OutputParams const & runparams_in) const string tmpplacement; string const buf_placement = buffer().params().float_placement; string const def_placement = floats.defaultPlacement(params_.type); - if (!params_.placement.empty() - && params_.placement != def_placement) { - tmpplacement = params_.placement; - } else if (params_.placement.empty() - && !buf_placement.empty() - && buf_placement != def_placement) { + if (params_.placement == "document" + && !buf_placement.empty() + && buf_placement != def_placement) { tmpplacement = buf_placement; + } else if (!params_.placement.empty() + && params_.placement != "document" + && params_.placement != def_placement) { + tmpplacement = params_.placement; } // Check if placement is allowed by this float @@ -386,6 +392,17 @@ void InsetFloat::latex(otexstream & os, OutputParams const & runparams_in) const placement += *lit; } + string alignment; + string const buf_alignment = buffer().params().float_alignment; + if (params_.alignment == "document" + && !buf_alignment.empty()) { + alignment = buf_alignment; + } else if (!params_.alignment.empty() + && params_.alignment != "class" + && params_.alignment != "document") { + alignment = params_.alignment; + } + // Force \begin{} to appear in a new line. os << breakln << "\\begin{" << from_ascii(tmptype) << '}'; if (runparams.lastid != -1) @@ -397,6 +414,12 @@ void InsetFloat::latex(otexstream & os, OutputParams const & runparams_in) const && (!params_.sideways || (params_.sideways && from_ascii(placement) != "p"))) os << '[' << from_ascii(placement) << ']'; os << '\n'; + if (alignment == "left") + os << "\\raggedright" << breakln; + else if (alignment == "center") + os << "\\centering" << breakln; + else if (alignment == "right") + os << "\\raggedleft" << breakln; InsetText::latex(os, runparams); diff --git a/src/insets/InsetFloat.h b/src/insets/InsetFloat.h index e05f5678e2..0c56d9ee65 100644 --- a/src/insets/InsetFloat.h +++ b/src/insets/InsetFloat.h @@ -25,7 +25,8 @@ class InsetFloatParams { public: /// - InsetFloatParams() : type("senseless"), wide(false), sideways(false), subfloat(false) {} + InsetFloatParams() : type("senseless"), placement("document"), alignment("document"), + wide(false), sideways(false), subfloat(false) {} /// void write(std::ostream & os) const; /// @@ -34,6 +35,8 @@ public: std::string type; /// std::string placement; + /// + std::string alignment; /// span columns bool wide; /// diff --git a/src/version.h b/src/version.h index ede6c33411..c2dd25abfa 100644 --- a/src/version.h +++ b/src/version.h @@ -32,8 +32,8 @@ extern char const * const lyx_version_info; // Do not remove the comment below, so we get merge conflict in // independent branches. Instead add your own. -#define LYX_FORMAT_LYX 551 // spitz: \nospellcheck font param -#define LYX_FORMAT_TEX2LYX 551 +#define LYX_FORMAT_LYX 552 // spitz: float alignment +#define LYX_FORMAT_TEX2LYX 552 #if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX #ifndef _MSC_VER