*
* \author Jürgen Vigna
* \author Lars Gullik Bjønnes
+ * \author Jürgen Spitzmüller
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "InsetFloat.h"
+#include "InsetCaption.h"
#include "Buffer.h"
#include "BufferParams.h"
#include "BufferView.h"
+#include "Counters.h"
#include "Cursor.h"
-#include "debug.h"
#include "DispatchResult.h"
#include "Floating.h"
#include "FloatList.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
-#include "gettext.h"
+#include "InsetList.h"
#include "LaTeXFeatures.h"
-#include "Color.h"
#include "Lexer.h"
#include "OutputParams.h"
-#include "Paragraph.h"
-#include "TocBackend.h"
+#include "ParIterator.h"
+#include "TextClass.h"
+#include "support/debug.h"
+#include "support/gettext.h"
#include "support/lstrings.h"
+#include "support/docstream.h"
#include "support/convert.h"
+using namespace std;
namespace lyx {
-using support::contains;
-
-using std::endl;
-using std::string;
-using std::auto_ptr;
-using std::istringstream;
-using std::ostream;
-using std::ostringstream;
-
// With this inset it will be possible to support the latex package
// float.sty, and I am sure that with this and some additional support
// Lgb
-InsetFloat::InsetFloat(BufferParams const & bp, string const & type)
- : InsetCollapsable(bp)
+InsetFloat::InsetFloat(Buffer const & buf, string const & type)
+ : InsetCollapsable(buf), name_(from_utf8(type))
{
- setLabel(_("float: ") + floatName(type, bp));
- LyXFont font(LyXFont::ALL_SANE);
- font.decSize();
- font.decSize();
- font.setColor(Color::collapsable);
- setLabelFont(font);
+ setLabel(_("float: ") + floatName(type, buf.params()));
params_.type = type;
- setInsetName(from_utf8(type));
}
params_.placement = params.placement;
params_.wide = params.wide;
params_.sideways = params.sideways;
+ params_.subfloat = params.subfloat;
wide(params_.wide, cur.buffer().params());
sideways(params_.sideways, cur.buffer().params());
break;
case LFUN_MOUSE_RELEASE: {
if (cmd.button() == mouse_button::button3 && hitButton(cmd)) {
+ if (params_.subfloat)
+ break;
InsetFloatMailer(*this).showDialog(&cur.bv());
break;
}
}
+void InsetFloat::updateLabels(ParIterator const & it)
+{
+ Counters & cnts = buffer().params().documentClass().counters();
+ string const saveflt = cnts.current_float();
+ bool const savesubflt = cnts.isSubfloat();
+
+ bool const subflt = it.innerInsetOfType(FLOAT_CODE);
+ // floats can only embed subfloats of their own kind
+ if (subflt)
+ params_.type = saveflt;
+ subfloat(subflt, buffer().params());
+
+ // Tell to captions what the current float is
+ cnts.current_float(params().type);
+ cnts.isSubfloat(subflt);
+
+ InsetCollapsable::updateLabels(it);
+
+ //reset afterwards
+ cnts.current_float(saveflt);
+ cnts.isSubfloat(savesubflt);
+}
+
+
void InsetFloatParams::write(ostream & os) const
{
os << "Float " << type << '\n';
}
-void InsetFloat::write(Buffer const & buf, ostream & os) const
+void InsetFloat::write(ostream & os) const
{
params_.write(os);
- InsetCollapsable::write(buf, os);
+ InsetCollapsable::write(os);
}
-void InsetFloat::read(Buffer const & buf, Lexer & lex)
+void InsetFloat::read(Lexer & lex)
{
params_.read(lex);
- wide(params_.wide, buf.params());
- sideways(params_.sideways, buf.params());
- InsetCollapsable::read(buf, lex);
+ wide(params_.wide, buffer().params());
+ sideways(params_.sideways, buffer().params());
+ subfloat(params_.subfloat, buffer().params());
+ InsetCollapsable::read(lex);
}
void InsetFloat::validate(LaTeXFeatures & features) const
{
- if (contains(params_.placement, 'H')) {
+ if (support::contains(params_.placement, 'H'))
features.require("float");
- }
if (params_.sideways)
- features.require("rotating");
+ features.require("rotfloat");
- features.useFloat(params_.type);
- InsetCollapsable::validate(features);
-}
+ if (params_.subfloat)
+ features.require("subfig");
-
-auto_ptr<InsetBase> InsetFloat::doClone() const
-{
- return auto_ptr<InsetBase>(new InsetFloat(*this));
+ features.useFloat(params_.type, params_.subfloat);
+ InsetCollapsable::validate(features);
}
-docstring const InsetFloat::editMessage() const
+docstring InsetFloat::editMessage() const
{
return _("Opened Float Inset");
}
-int InsetFloat::latex(Buffer const & buf, odocstream & os,
- OutputParams const & runparams) const
+int InsetFloat::latex(odocstream & os, OutputParams const & runparams) const
{
- FloatList const & floats = buf.params().getLyXTextClass().floats();
- string tmptype = (params_.wide ? params_.type + "*" : params_.type);
- if (params_.sideways) {
- if (params_.type == "table")
- tmptype = "sidewaystable";
- else if (params_.type == "figure")
- tmptype = "sidewaysfigure";
+ if (params_.subfloat) {
+ if (runparams.moving_arg)
+ os << "\\protect";
+ os << "\\subfloat";
+
+ OutputParams rp = runparams;
+ docstring const caption = getCaption(rp);
+ if (!caption.empty()) {
+ os << caption;
+ }
+ os << '{';
+ int const i = InsetText::latex(os, runparams);
+ os << "}";
+
+ return i + 1;
}
+
+ FloatList const & floats = buffer().params().documentClass().floats();
+ string tmptype = params_.type;
+ if (params_.sideways)
+ tmptype = "sideways" + params_.type;
+ if (params_.wide && (!params_.sideways ||
+ params_.type == "figure" ||
+ params_.type == "table"))
+ tmptype += "*";
// Figure out the float placement to use.
// From lowest to highest:
// - float default placement
// - document wide default placement
// - specific float placement
string placement;
- string const buf_placement = buf.params().float_placement;
+ string const buf_placement = buffer().params().float_placement;
string const def_placement = floats.defaultPlacement(params_.type);
if (!params_.placement.empty()
&& params_.placement != def_placement) {
}
os << '\n';
- int const i = InsetText::latex(buf, os, runparams);
+ int const i = InsetText::latex(os, runparams);
// The \n is used to force \end{<floatname>} to appear in a new line.
// In this case, we do not case if the current output line is empty.
}
-int InsetFloat::plaintext(Buffer const & buf, odocstream & os,
- OutputParams const & runparams) const
+int InsetFloat::plaintext(odocstream & os, OutputParams const & runparams) const
{
- os << '[' << _("float") << ' ' << floatName(params_.type, buf.params()) << ":\n";
- InsetText::plaintext(buf, os, runparams);
+ os << '[' << buffer().B_("float") << ' '
+ << floatName(params_.type, buffer().params()) << ":\n";
+ InsetText::plaintext(os, runparams);
os << "\n]";
return PLAINTEXT_NEWLINE + 1; // one char on a separate line
}
-int InsetFloat::docbook(Buffer const & buf, odocstream & os,
- OutputParams const & runparams) const
+int InsetFloat::docbook(odocstream & os, OutputParams const & runparams) const
{
- // FIXME UNICODE
- os << '<' << from_ascii(params_.type) << '>';
- int const i = InsetText::docbook(buf, os, runparams);
+ // FIXME Implement subfloat!
+ // FIXME UNICODE
+ os << '<' << from_ascii(params_.type) << '>';
+ int const i = InsetText::docbook(os, runparams);
os << "</" << from_ascii(params_.type) << '>';
return i;
}
-bool InsetFloat::insetAllowed(InsetBase::Code code) const
+bool InsetFloat::insetAllowed(InsetCode code) const
{
- return code != InsetBase::FLOAT_CODE
- && code != InsetBase::FOOT_CODE
- && code != InsetBase::MARGIN_CODE;
+ return code != FOOT_CODE
+ && code != MARGIN_CODE
+ && (code != FLOAT_CODE || !params_.subfloat);
}
}
-void InsetFloat::addToToc(TocList & toclist, Buffer const & buf) const
+void InsetFloat::subfloat(bool s, BufferParams const & bp)
+{
+ params_.subfloat = s;
+ docstring lab = _("float: ") + floatName(params_.type, bp);
+ if (s)
+ lab = _("subfloat: ") + floatName(params_.type, bp);
+ setLabel(lab);
+}
+
+
+docstring InsetFloat::getCaption(OutputParams const & runparams) const
{
- // Is there a need to provide a list of float insets?
- return;
-
- // Abdel (01/02/2006): I'll let this code for reference in case
- // there's a need to do something similar for another kind of
- // inset.
- ParConstIterator pit = par_const_iterator_begin(*this);
- ParConstIterator end = par_const_iterator_end(*this);
-
- // Find a caption layout in one of the (child inset's) pars
- for (; pit != end; ++pit) {
- if (pit->layout()->labeltype == LABEL_SENSITIVE) {
- Toc & toc = toclist[params_.type];
- docstring const str =
- convert<docstring>(toc.size() + 1)
- + ". " + pit->asString(buf, false);
- toc.push_back(TocItem(pit, 0, str));
- return;
+ if (paragraphs().empty())
+ return docstring();
+
+ ParagraphList::const_iterator pit = paragraphs().begin();
+ for (; pit != paragraphs().end(); ++pit) {
+ InsetList::const_iterator it = pit->insetList().begin();
+ for (; it != pit->insetList().end(); ++it) {
+ Inset & inset = *it->inset;
+ if (inset.lyxCode() == CAPTION_CODE) {
+ odocstringstream ods;
+ InsetCaption * ins =
+ static_cast<InsetCaption *>(it->inset);
+ ins->getOptArg(ods, runparams);
+ ods << '[';
+ ins->getArgument(ods, runparams);
+ ods << ']';
+ return ods.str();
+ }
}
}
+ return docstring();
}
return print_mailer_error("InsetFloatMailer", in, 1, name_);
// This is part of the inset proper that is usually swallowed
- // by LyXText::readInset
+ // by Text::readInset
string id;
lex >> id;
if (!lex || id != "Float")