#include "Lexer.h"
#include "output_xhtml.h"
#include "ParIterator.h"
+#include "TexRow.h"
+#include "texstream.h"
#include "TextClass.h"
#include "support/debug.h"
//FIXME: why do we set in stone the type here?
InsetFloat::InsetFloat(Buffer * buf, string params_str)
- : InsetCollapsable(buf)
+ : InsetCaptionable(buf)
{
string2params(params_str, params_);
+ setCaptionType(params_.type);
+}
+
+
+// Enforce equality of float type and caption type.
+void InsetFloat::setCaptionType(std::string const & type)
+{
+ InsetCaptionable::setCaptionType(type);
+ params_.type = captionType();
+ // check if the float type exists
+ if (buffer().params().documentClass().floats().typeExist(params_.type))
+ setNewLabel();
+ else
+ setLabel(bformat(_("ERROR: Unknown float type: %1$s"), from_utf8(params_.type)));
}
docstring InsetFloat::layoutName() const
-{
+{
return "Float:" + from_utf8(params_.type);
}
docstring InsetFloat::toolTip(BufferView const & bv, int x, int y) const
{
if (isOpen(bv))
- return InsetCollapsable::toolTip(bv, x, y);
+ return InsetCaptionable::toolTip(bv, x, y);
OutputParams rp(&buffer().params().encoding());
return getCaptionText(rp);
params_.sideways = params.sideways;
}
setNewLabel();
- if (params_.type != params.type) {
- params_.type = params.type;
- cur.forceBufferUpdate();
- }
+ if (params_.type != params.type)
+ setCaptionType(params.type);
// what we really want here is a TOC update, but that means
// a full buffer update
cur.forceBufferUpdate();
}
default:
- InsetCollapsable::doDispatch(cur, cmd);
+ InsetCaptionable::doDispatch(cur, cmd);
break;
}
}
return true;
case LFUN_INSET_SETTINGS:
- if (InsetCollapsable::getStatus(cur, cmd, flag)) {
+ if (InsetCaptionable::getStatus(cur, cmd, flag)) {
flag.setEnabled(flag.enabled() && !params_.subfloat);
return true;
} else
return false;
-
+
case LFUN_NEWLINE_INSERT:
if (params_.subfloat) {
flag.setEnabled(false);
return true;
}
+ // no subfloat:
+ // fall through
default:
- return InsetCollapsable::getStatus(cur, cmd, flag);
+ return InsetCaptionable::getStatus(cur, cmd, flag);
}
}
-void InsetFloat::updateBuffer(ParIterator const & it, UpdateType utype)
+bool InsetFloat::hasSubCaptions(ParIterator const & it) const
{
- Counters & cnts =
- buffer().masterBuffer()->params().documentClass().counters();
- if (utype == OutputUpdate) {
- // counters are local to the float
- cnts.saveLastCounter();
- }
- string const saveflt = cnts.current_float();
- bool const savesubflt = cnts.isSubfloat();
-
- bool const subflt = (it.innerInsetOfType(FLOAT_CODE)
- || it.innerInsetOfType(WRAP_CODE));
- // floats can only embed subfloats of their own kind
- if (subflt)
- params_.type = saveflt;
- setSubfloat(subflt);
-
- // Tell to captions what the current float is
- cnts.current_float(params().type);
- cnts.isSubfloat(subflt);
-
- InsetCollapsable::updateBuffer(it, utype);
-
- //reset afterwards
- cnts.current_float(saveflt);
- if (utype == OutputUpdate)
- cnts.restoreLastCounter();
- cnts.isSubfloat(savesubflt);
+ return (it.innerInsetOfType(FLOAT_CODE) || it.innerInsetOfType(WRAP_CODE));
}
void InsetFloatParams::write(ostream & os) const
{
- os << type << '\n';
+ if (type.empty()) {
+ // Better this than creating a parse error. This in fact happens in the
+ // parameters dialog via InsetFloatParams::params2string.
+ os << "senseless" << '\n';
+ } else
+ os << type << '\n';
if (!placement.empty())
os << "placement " << placement << "\n";
{
os << "Float ";
params_.write(os);
- InsetCollapsable::write(os);
+ InsetCaptionable::write(os);
}
void InsetFloat::read(Lexer & lex)
{
params_.read(lex);
- InsetCollapsable::read(lex);
- // check if the float type exists
- if (buffer().params().documentClass().floats().typeExist(params_.type))
- setLabel(_("float: ") + floatName(params_.type));
- else
- setLabel(bformat(_("ERROR: Unknown float type: %1$s"), from_utf8(params_.type)));
+ InsetCaptionable::read(lex);
+ setCaptionType(params_.type);
}
features.useFloat(params_.type, features.inFloat());
features.inFloat(true);
- InsetCollapsable::validate(features);
+ InsetCaptionable::validate(features);
features.inFloat(false);
}
odocstringstream ods;
XHTMLStream newxs(ods);
newxs << html::StartTag(htmltype, attr);
- InsetText::XHTMLOptions const opts =
+ InsetText::XHTMLOptions const opts =
InsetText::WriteLabel | InsetText::WriteInnerTag;
docstring deferred = InsetText::insetAsXHTML(newxs, rp, opts);
newxs << html::EndTag(htmltype);
- if (rp.inFloat == OutputParams::NONFLOAT)
+ if (rp.inFloat == OutputParams::NONFLOAT) {
// In this case, this float needs to be deferred, but we'll put it
// before anything the text itself deferred.
deferred = ods.str() + '\n' + deferred;
- else
+ } else {
// In this case, the whole thing is already being deferred, so
// we can write to the stream.
- // Note that things will already have been escaped, so we do not
+ // Note that things will already have been escaped, so we do not
// want to escape them again.
xs << XHTMLStream::ESCAPE_NONE << ods.str();
+ }
return deferred;
}
void InsetFloat::latex(otexstream & os, OutputParams const & runparams_in) const
{
if (runparams_in.inFloat != OutputParams::NONFLOAT) {
+ if (!paragraphs().empty() && !runparams_in.nice)
+ // improve TexRow precision in non-nice mode
+ os << safebreakln;
+
if (runparams_in.moving_arg)
os << "\\protect";
os << "\\subfloat";
OutputParams rp = runparams_in;
rp.moving_arg = true;
- docstring const caption = getCaption(rp);
- if (!caption.empty()) {
- os << caption;
- }
+ os << getCaption(rp);
os << '{';
// The main argument is the contents of the float. This is not a moving argument.
rp.moving_arg = false;
FloatList const & floats = buffer().params().documentClass().floats();
string tmptype = params_.type;
- if (params_.sideways)
+ if (params_.sideways && floats.allowsSideways(params_.type))
tmptype = "sideways" + params_.type;
- if (params_.wide && (!params_.sideways ||
- params_.type == "figure" ||
- params_.type == "table"))
+ if (params_.wide && floats.allowsWide(params_.type)
+ && (!params_.sideways ||
+ params_.type == "figure" ||
+ params_.type == "table"))
tmptype += "*";
// Figure out the float placement to use.
// From lowest to highest:
if (runparams.lastid != -1)
os.texrow().start(runparams.lastid, runparams.lastpos);
// We only output placement if different from the def_placement.
- // sidewaysfloats always use their own page
- if (!placement.empty() && !params_.sideways)
+ // sidewaysfloats always use their own page,
+ // therefore don't output the p option that is always set
+ if (!placement.empty()
+ && (!params_.sideways || (params_.sideways && from_ascii(placement) != "p")))
os << '[' << from_ascii(placement) << ']';
os << '\n';
bool InsetFloat::insetAllowed(InsetCode code) const
{
- // The case that code == FLOAT_CODE is handled in Text3.cpp,
+ // The case that code == FLOAT_CODE is handled in Text3.cpp,
// because we need to know what type of float is meant.
switch(code) {
case WRAP_CODE:
case MARGIN_CODE:
return false;
default:
- return InsetCollapsable::insetAllowed(code);
+ return InsetCaptionable::insetAllowed(code);
}
}
void InsetFloat::setWide(bool w, bool update_label)
{
- params_.wide = w;
+ if (!buffer().params().documentClass().floats().allowsWide(params_.type))
+ params_.wide = false;
+ else
+ params_.wide = w;
if (update_label)
setNewLabel();
}
void InsetFloat::setSideways(bool s, bool update_label)
{
- params_.sideways = s;
+ if (!buffer().params().documentClass().floats().allowsSideways(params_.type))
+ params_.sideways = false;
+ else
+ params_.sideways = s;
if (update_label)
setNewLabel();
}
lab += floatName(params_.type);
- if (params_.wide)
+ FloatList const & floats = buffer().params().documentClass().floats();
+
+ if (params_.wide && floats.allowsWide(params_.type))
lab += '*';
- if (params_.sideways)
+ if (params_.sideways && floats.allowsSideways(params_.type))
lab += _(" (sideways)");
setLabel(lab);
bool InsetFloat::allowsCaptionVariation(std::string const & newtype) const
{
- return !params_.subfloat && newtype != "LongTableNoNumber";
+ return !params_.subfloat && newtype != "Unnumbered";
}
-docstring InsetFloat::getCaption(OutputParams const & runparams) const
+TexString InsetFloat::getCaption(OutputParams const & runparams) const
{
- if (paragraphs().empty())
- return docstring();
-
InsetCaption const * ins = getCaptionInset();
if (ins == 0)
- return docstring();
+ return TexString();
- TexRow texrow;
- odocstringstream ods;
- otexstream os(ods, texrow);
+ otexstringstream os;
ins->getArgs(os, runparams);
- ods << '[';
- odocstringstream odss;
- otexstream oss(odss, texrow);
- ins->getArgument(oss, runparams);
- docstring arg = odss.str();
+
+ if (!runparams.nice)
+ // increase TexRow precision in non-nice mode
+ os << safebreakln;
+ os << '[';
+ otexstringstream os2;
+ ins->getArgument(os2, runparams);
+ TexString ts = os2.release();
+ docstring & arg = ts.str;
// Protect ']'
if (arg.find(']') != docstring::npos)
arg = '{' + arg + '}';
- ods << arg;
- ods << ']';
- return ods.str();
+ os << move(ts);
+ os << ']';
+ if (!runparams.nice)
+ os << safebreakln;
+ return os.release();
}