From 7dc123b790b2cffd30db1316dccaf993398577bf Mon Sep 17 00:00:00 2001 From: Juergen Spitzmueller Date: Fri, 22 May 2015 10:37:14 +0200 Subject: [PATCH] Add Float tag to determine allowed positioning options (#7752) --- lib/doc/Customization.lyx | 121 ++++++++++++++++++++++++++- lib/scripts/layout2layout.py | 7 +- src/FloatList.cpp | 9 ++ src/FloatList.h | 2 + src/Floating.cpp | 12 +-- src/Floating.h | 8 +- src/TextClass.cpp | 13 ++- src/frontends/qt4/FloatPlacement.cpp | 39 ++++++--- src/frontends/qt4/FloatPlacement.h | 4 + src/insets/InsetFloat.cpp | 17 +++- 10 files changed, 203 insertions(+), 29 deletions(-) diff --git a/lib/doc/Customization.lyx b/lib/doc/Customization.lyx index 06cf29a13d..c2d311df4c 100644 --- a/lib/doc/Customization.lyx +++ b/lib/doc/Customization.lyx @@ -1,7 +1,8 @@ #LyX 2.2 created this file. For more info see http://www.lyx.org/ -\lyxformat 488 +\lyxformat 493 \begin_document \begin_header +\origin /home/jspitz/lyx/lyx-devel/lib/doc/ \textclass scrbook \begin_preamble % DO NOT ALTER THIS PREAMBLE!!! @@ -15578,6 +15579,119 @@ to your layout file. (like the AGU class bundled with \SpecialChar LyX ), the information below will hopefully help you: +\change_inserted -712698321 1432283506 + +\end_layout + +\begin_layout Description + +\change_inserted -712698321 1432283705 +\begin_inset Flex Code +status collapsed + +\begin_layout Plain Layout + +\change_inserted -712698321 1432283514 +AllowedPlacement +\end_layout + +\end_inset + + [ +\begin_inset Flex Code +status collapsed + +\begin_layout Plain Layout + +\change_inserted -712698321 1432283507 +string +\end_layout + +\end_inset + +=!htbpH] Allowed placement options for this float type. + The value is a string of placement characters. + Possible characters include: +\emph on +h +\emph default + ( +\begin_inset Quotes eld +\end_inset + +here if possible +\begin_inset Quotes erd +\end_inset + +), +\emph on +t +\emph default + ( +\begin_inset Quotes eld +\end_inset + +top of page +\begin_inset Quotes erd +\end_inset + +), +\emph on +b +\emph default + ( +\begin_inset Quotes eld +\end_inset + +bottom of page +\begin_inset Quotes erd +\end_inset + +), +\emph on +p +\emph default + ( +\begin_inset Quotes eld +\end_inset + +page of floats +\begin_inset Quotes erd +\end_inset + +), +\emph on +H +\emph default + ( +\begin_inset Quotes eld +\end_inset + +here definitely +\begin_inset Quotes erd +\end_inset + +) and +\emph on +! +\emph default + ( +\begin_inset Quotes eld +\end_inset + +ignore LaTeX rules +\begin_inset Quotes erd +\end_inset + +). + The order of the characters in the string does not matter. + If no placement options are allowed, use the string +\emph on +none +\emph default +. +\change_unchanged + \end_layout \begin_layout Description @@ -22410,6 +22524,11 @@ width "100col%" special "none" height "1in" height_special "totalheight" +thickness "0.4pt" +separation "3pt" +shadowsize "4pt" +framecolor "black" +backgroundcolor "none" status open \begin_layout Plain Layout diff --git a/lib/scripts/layout2layout.py b/lib/scripts/layout2layout.py index 95412ca5da..cc634582cc 100644 --- a/lib/scripts/layout2layout.py +++ b/lib/scripts/layout2layout.py @@ -183,6 +183,9 @@ import os, re, string, sys # Incremented to format 55, 20 April 2015 by spitz # New InsetLayout and Layout tags "PassThruChars" +# Incremented to format 56, 20 May 2015 by spitz +# New Float tags "AllowedPlacement" + # Do not forget to document format change in Customization # Manual (section "Declaring a new text class"). @@ -190,7 +193,7 @@ import os, re, string, sys # development/tools/updatelayouts.py script to update all # layout files to the new format. -currentFormat = 55 +currentFormat = 56 def usage(prog_name): @@ -414,7 +417,7 @@ def convert(lines): i += 1 continue - if format >= 50 and format <= 54: + if format >= 50 and format <= 55: # nothing to do. i += 1 continue diff --git a/src/FloatList.cpp b/src/FloatList.cpp index 5725293c48..54389914b9 100644 --- a/src/FloatList.cpp +++ b/src/FloatList.cpp @@ -48,6 +48,15 @@ string const FloatList::defaultPlacement(string const & t) const } +string const FloatList::allowedPlacement(string const & t) const +{ + List::const_iterator cit = list.find(t); + if (cit != list.end()) + return cit->second.allowedPlacement(); + return string(); +} + + bool FloatList::typeExist(string const & t) const { List::const_iterator cit = list.find(t); diff --git a/src/FloatList.h b/src/FloatList.h index 50db0944b2..c647197f4c 100644 --- a/src/FloatList.h +++ b/src/FloatList.h @@ -39,6 +39,8 @@ public: /// std::string const defaultPlacement(std::string const & t) const; /// + std::string const allowedPlacement(std::string const & t) const; + /// bool typeExist(std::string const & t) const; /// Floating const & getType(std::string const & t) const; diff --git a/src/Floating.cpp b/src/Floating.cpp index 61b3b15f90..7c68189fc2 100644 --- a/src/Floating.cpp +++ b/src/Floating.cpp @@ -27,15 +27,15 @@ namespace lyx { Floating::Floating(string const & type, string const & placement, string const & ext, string const & within, string const & style, string const & name, - string const & listName, std::string const & listCmd, - string const & refPrefix, - string const & htmlTag, string const & htmlAttrib, + string const & listName, std::string const & listCmd, + string const & refPrefix, std::string const & allowedplacement, + string const & htmlTag, string const & htmlAttrib, string const & htmlStyle, bool usesfloat, bool ispredefined) : floattype_(type), placement_(placement), ext_(ext), within_(within), style_(style), name_(name), listname_(listName), listcommand_(listCmd), - refprefix_(refPrefix), usesfloatpkg_(usesfloat), - ispredefined_(ispredefined), html_tag_(htmlTag), - html_attrib_(htmlAttrib), html_style_(htmlStyle) + refprefix_(refPrefix), allowedplacement_(allowedplacement), + usesfloatpkg_(usesfloat), ispredefined_(ispredefined), + html_tag_(htmlTag), html_attrib_(htmlAttrib), html_style_(htmlStyle) {} diff --git a/src/Floating.h b/src/Floating.h index d0a51a08d1..e92fe77bdf 100644 --- a/src/Floating.h +++ b/src/Floating.h @@ -32,8 +32,8 @@ public: std::string const & ext, std::string const & within, std::string const & style, std::string const & name, std::string const & listName, std::string const & listCmd, - std::string const & refPrefix, - std::string const & htmlType, std::string const & htmlClass, + std::string const & refPrefix, std::string const & allowedplacement, + std::string const & htmlType, std::string const & htmlClass, std::string const & htmlStyle, bool usesfloat, bool isprefined); /// std::string const & floattype() const { return floattype_; } @@ -56,6 +56,8 @@ public: std::string const & listCommand() const { return listcommand_; } /// prefix to use for formatted references to such floats std::string const & refPrefix() const { return refprefix_; } + /// allowed placement options + std::string const & allowedPlacement() const { return allowedplacement_; } /// bool usesFloatPkg() const { return usesfloatpkg_; } /// @@ -88,6 +90,8 @@ private: /// std::string refprefix_; /// + std::string allowedplacement_; + /// bool usesfloatpkg_; /// bool ispredefined_; diff --git a/src/TextClass.cpp b/src/TextClass.cpp index 02fc86e9f9..2ea7053731 100644 --- a/src/TextClass.cpp +++ b/src/TextClass.cpp @@ -61,7 +61,7 @@ namespace lyx { // You should also run the development/tools/updatelayouts.py script, // to update the format of all of our layout files. // -int const LAYOUT_FORMAT = 55; //spitz: InsetLayout and Layout tags PassThruChars +int const LAYOUT_FORMAT = 56; //spitz: New Float tags AllowedPlacement namespace { @@ -256,7 +256,7 @@ LexerKeyword textClassTags[] = { { "nostyle", TC_NOSTYLE }, { "outputformat", TC_OUTPUTFORMAT }, { "outputtype", TC_OUTPUTTYPE }, - { "packageoptions", TC_PKGOPTS }, + { "packageoptions", TC_PKGOPTS }, { "pagestyle", TC_PAGESTYLE }, { "preamble", TC_PREAMBLE }, { "provides", TC_PROVIDES }, @@ -1097,10 +1097,12 @@ bool TextClass::readFloat(Lexer & lexrc) FT_HTMLTAG, FT_LISTCOMMAND, FT_REFPREFIX, + FT_ALLOWED_PLACEMENT, FT_END }; LexerKeyword floatTags[] = { + { "allowedplacement", FT_ALLOWED_PLACEMENT }, { "end", FT_END }, { "extension", FT_EXT }, { "guiname", FT_NAME }, @@ -1128,6 +1130,7 @@ bool TextClass::readFloat(Lexer & lexrc) string listcommand; string name; string placement; + string allowed_placement = "!htbpH"; string refprefix; string style; string type; @@ -1171,6 +1174,10 @@ bool TextClass::readFloat(Lexer & lexrc) lexrc.next(); placement = lexrc.getString(); break; + case FT_ALLOWED_PLACEMENT: + lexrc.next(); + allowed_placement = lexrc.getString(); + break; case FT_EXT: lexrc.next(); ext = lexrc.getString(); @@ -1245,7 +1252,7 @@ bool TextClass::readFloat(Lexer & lexrc) "not be able to produce a float list."); } Floating fl(type, placement, ext, within, style, name, - listname, listcommand, refprefix, + listname, listcommand, refprefix, allowed_placement, htmltag, htmlattr, htmlstyle, usesfloat, ispredefined); floatlist_.newFloat(fl); // each float has its own counter diff --git a/src/frontends/qt4/FloatPlacement.cpp b/src/frontends/qt4/FloatPlacement.cpp index 1f0e6e9709..19d72cdb72 100644 --- a/src/frontends/qt4/FloatPlacement.cpp +++ b/src/frontends/qt4/FloatPlacement.cpp @@ -75,6 +75,12 @@ void FloatPlacement::useSideways() } +bool FloatPlacement::possiblePlacement(char const & p) const +{ + return !spanCB->isVisible() || contains(allowed_placement_, p); +} + + void FloatPlacement::set(string const & placement) { bool def_placement = false; @@ -87,22 +93,22 @@ void FloatPlacement::set(string const & placement) if (placement.empty()) { def_placement = true; - } else if (contains(placement, 'H')) { + } else if (contains(placement, 'H') && possiblePlacement('H')) { here_definitely = true; } else { - if (contains(placement, '!')) { + if (contains(placement, '!') && possiblePlacement('!')) { force = true; } - if (contains(placement, 't')) { + if (contains(placement, 't') && possiblePlacement('t')) { top = true; } - if (contains(placement, 'b')) { + if (contains(placement, 'b') && possiblePlacement('b')) { bottom = true; } - if (contains(placement, 'p')) { + if (contains(placement, 'p') && possiblePlacement('p')) { page = true; } - if (contains(placement, 'h')) { + if (contains(placement, 'h') && possiblePlacement('h')) { here = true; } } @@ -145,6 +151,9 @@ void FloatPlacement::paramsToDialog(Inset const * inset) int const item = floatTypeCO->findData(toqstr(params.type)); floatTypeCO->setCurrentIndex(item); + allowed_placement_ = + bp.documentClass().floats().allowedPlacement(params.type); + set(params.placement); standardfloat_ = (params.type == "figure" @@ -234,12 +243,18 @@ void FloatPlacement::checkAllowed() const bool const span = spanCB->isChecked(); bool const sideways = sidewaysCB->isChecked(); defaultsCB->setEnabled(!sideways); - topCB->setEnabled(!sideways && !defaults && !heredefinitely); - bottomCB->setEnabled(!sideways && !defaults && !span && !heredefinitely); - pageCB->setEnabled(!sideways && !defaults && !heredefinitely); - herepossiblyCB->setEnabled(!sideways && !defaults && !span && !heredefinitely); - heredefinitelyCB->setEnabled(!sideways && !defaults && !span); - ignoreCB->setEnabled(!sideways && !defaults && ignore && !heredefinitely); + topCB->setEnabled(!sideways && !defaults && !heredefinitely + && contains(allowed_placement_, 't')); + bottomCB->setEnabled(!sideways && !defaults && !span && !heredefinitely + && contains(allowed_placement_, 'b')); + pageCB->setEnabled(!sideways && !defaults && !heredefinitely + && contains(allowed_placement_, 'p')); + herepossiblyCB->setEnabled(!sideways && !defaults && !span && !heredefinitely + && contains(allowed_placement_, 'h')); + heredefinitelyCB->setEnabled(!sideways && !defaults && !span + && contains(allowed_placement_, 'H')); + ignoreCB->setEnabled(!sideways && !defaults && ignore && !heredefinitely + && contains(allowed_placement_, '!')); spanCB->setEnabled(!sideways || standardfloat_); } else { topCB->setEnabled(!defaults && !heredefinitely); diff --git a/src/frontends/qt4/FloatPlacement.h b/src/frontends/qt4/FloatPlacement.h index a720a4e20d..cec0e71591 100644 --- a/src/frontends/qt4/FloatPlacement.h +++ b/src/frontends/qt4/FloatPlacement.h @@ -59,10 +59,14 @@ private: std::string const get(bool & wide, bool & sideways) const; /// void initFloatTypeCO(FloatList const & floats); + /// + bool possiblePlacement(char const & p) const; /// one of figure or table? bool standardfloat_; /// + std::string allowed_placement_; + /// FloatList const * float_list_; }; diff --git a/src/insets/InsetFloat.cpp b/src/insets/InsetFloat.cpp index a79affc0c3..c52907af74 100644 --- a/src/insets/InsetFloat.cpp +++ b/src/insets/InsetFloat.cpp @@ -369,16 +369,27 @@ void InsetFloat::latex(otexstream & os, OutputParams const & runparams_in) const // - float default placement // - document wide default placement // - specific float placement - string placement; + 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) { - placement = params_.placement; + tmpplacement = params_.placement; } else if (params_.placement.empty() && !buf_placement.empty() && buf_placement != def_placement) { - placement = buf_placement; + tmpplacement = buf_placement; + } + + // Check if placement is allowed by this float + string const allowed_placement = + floats.allowedPlacement(params_.type); + string placement; + string::const_iterator lit = tmpplacement.begin(); + string::const_iterator end = tmpplacement.end(); + for (; lit != end; ++lit) { + if (contains(allowed_placement, *lit)) + placement += *lit; } // Force \begin{} to appear in a new line.