Jürgen Spitzmüller wrote:
Am Freitag, 26. Januar 2007 22:57 schrieb Abdelrazak Younes:
1) LateX doesn't accept multiple lines caption so we might have to
forbid that I guess.
I think a line break is allowed, but no paragraph break.
What is a line break? If it is mean the one with Ctrl-Enter, LateX does
not like it. If you mean normal row-breaking (word-wrap), that is OK
with LateX.
2) If you put multiple captions inside a same float, they are numbered
sequentially even though they refer to the same float. I guess I should
update my patch accordingly... What do you think?
You should do what the LaTeX output does
Yes, that's what I've done in my latest patch for 2). I don't know how
to fix 1).
(you are aware of subfig?).
Never used it but yes. Do we need to do something special for this?
Anyway, here's an updated patch that mostly fix the text flowing issue.
The only remaining issues are:
* major one: lyx2lyx support: Georg promised to do it soon
* minor one: the red frame around the caption is not drawn correctly if
there's more than one caption in the same float.
Georg, if you're going to do the lyx2lyx support, please take the patch
and commit it at the same time.
Thanks,
Abdel.
Index: buffer_funcs.C
===================================================================
--- buffer_funcs.C (revision 16876)
+++ buffer_funcs.C (working copy)
@@ -38,6 +38,7 @@
#include "frontends/Alert.h"
#include "insets/insetbibitem.h"
+#include "insets/insetcaption.h"
#include "insets/insetinclude.h"
#include "support/filetools.h"
@@ -351,6 +352,67 @@
}
+void setCaptionLabels(InsetBase & inset, Floating const & fl,
+ Counters & counters)
+{
+ if (!inset.getText(0))
+ return;
+
+ // All caption within this inset will have the same label and number.
+ ParagraphList & pars = inset.getText(0)->paragraphs();
+ if (pars.empty())
+ return;
+
+ // FIXME UNICODE
+ docstring const counter = from_ascii(fl.type());
+ docstring const label = from_utf8(fl.name());
+
+ ParagraphList::iterator p = pars.begin();
+ for (; p != pars.end(); ++p) {
+ InsetList::iterator it2 = p->insetlist.begin();
+ InsetList::iterator end2 = p->insetlist.end();
+ // Any caption within this float should have the same
+ // label and number.
+ for (; it2 != end2; ++it2) {
+ InsetBase & icap = *it2->inset;
+ // Look deeper just in case.
+ setCaptionLabels(icap, fl, counters);
+ if (icap.lyxCode() == InsetBase::CAPTION_CODE) {
+ // We found a caption!
+ counters.step(counter);
+ int number = counters.value(counter);
+ static_cast<InsetCaption
&>(icap).setCount(number);
+ static_cast<InsetCaption
&>(icap).setLabel(label);
+ }
+ }
+ }
+}
+
+
+void setCaptions(Paragraph & par, LyXTextClass const & textclass)
+{
+ if (par.insetlist.empty())
+ return;
+
+ Counters & counters = textclass.counters();
+
+ InsetList::iterator it = par.insetlist.begin();
+ InsetList::iterator end = par.insetlist.end();
+ for (; it != end; ++it) {
+ InsetBase & inset = *it->inset;
+ if (inset.lyxCode() != InsetBase::FLOAT_CODE
+ && inset.lyxCode() != InsetBase::WRAP_CODE)
+ continue;
+
+ docstring const & type = inset.getInsetName();
+ if (type.empty())
+ continue;
+
+ Floating const & fl =
textclass.floats().getType(to_ascii(type));
+ setCaptionLabels(inset, fl, counters);
+ }
+}
+
// set the label of a paragraph. This includes the counters.
void setLabel(Buffer const & buf, ParIterator & it, LyXTextClass const &
textclass)
{
@@ -477,34 +539,7 @@
par.params().labelString(
par.translateIfPossible(layout->labelstring(),
buf.params()));
// In biblio shouldn't be following counters but...
- } else if (layout->labeltype == LABEL_SENSITIVE) {
- // Search for the first float or wrap inset in the iterator
- size_t i = it.depth();
- InsetBase * in;
- while (i > 0) {
- --i;
- in = &it[i].inset();
- if (in->lyxCode() == InsetBase::FLOAT_CODE
- || in->lyxCode() == InsetBase::WRAP_CODE)
- break;
- }
- docstring const & type = in->getInsetName();
- if (!type.empty()) {
- Floating const & fl =
textclass.floats().getType(to_ascii(type));
- // FIXME UNICODE
- counters.step(from_ascii(fl.type()));
-
- // Doesn't work... yet.
- par.params().labelString(par.translateIfPossible(
- bformat(from_ascii("%1$s #:"),
from_utf8(fl.name())),
- buf.params()));
- } else {
- // par->SetLayout(0);
- par.params().labelString(par.translateIfPossible(
- layout->labelstring(), buf.params()));
- }
-
} else if (layout->labeltype == LABEL_NO_LABEL)
par.params().labelString(docstring());
else
@@ -602,6 +637,11 @@
// set the counter for this paragraph
setLabel(buf, it, textclass);
+ // It is better to set the captions after setLabel because
+ // the caption number might need the section number in the
+ // future.
+ setCaptions(*it, textclass);
+
// Now included docs
InsetList::const_iterator iit = it->insetlist.begin();
InsetList::const_iterator end = it->insetlist.end();
Index: insets/insetcaption.C
===================================================================
--- insets/insetcaption.C (revision 16876)
+++ insets/insetcaption.C (working copy)
@@ -90,44 +90,24 @@
}
-void InsetCaption::setLabel(LCursor & cur) const
+void InsetCaption::setLabel(docstring const & label)
{
- // Set caption label _only_ if the cursor is in _this_ float:
- if (cur.top().text() == &text_) {
- string s;
- size_t i = cur.depth();
- while (i > 0) {
- --i;
- InsetBase * const in = &cur[i].inset();
- if (in->lyxCode() == InsetBase::FLOAT_CODE ||
- in->lyxCode() == InsetBase::WRAP_CODE) {
- s = to_utf8(in->getInsetName());
- break;
- }
- }
- Floating const & fl = textclass_.floats().getType(s);
- s = fl.name();
- docstring num;
- if (s.empty())
- s = "Senseless";
- else
- num = convert<docstring>(counter_);
-
- // Generate the label
- label = bformat(from_ascii("%1$s %2$s:"), _(s), num);
- }
+ label_ = _(to_ascii(label));
}
bool InsetCaption::metrics(MetricsInfo & mi, Dimension & dim) const
{
mi.base.textwidth -= 2 * TEXT_TO_INSET_OFFSET;
- LCursor cur = mi.base.bv->cursor();
- setLabel(cur);
- labelwidth_ = theFontMetrics(mi.base.font).width(label);
+ docstring const number = convert<docstring>(counter_);
+ full_label_ = bformat(from_ascii("%1$s %2$s:"), label_, number);
+ labelwidth_ = theFontMetrics(mi.base.font).width(full_label_);
dim.wid = labelwidth_;
Dimension textdim;
InsetText::metrics(mi, textdim);
+ // Correct for button width, and re-fit
+ mi.base.textwidth -= dim.wid;
+ InsetText::metrics(mi, textdim);
dim.des = std::max(dim.des - textdim.asc + dim.asc, textdim.des);
dim.asc = textdim.asc;
dim.wid += textdim.wid;
@@ -149,11 +129,9 @@
// the text inset or the paragraph?
// We should also draw the float number (Lgb)
- // See if we can find the name of the float this caption
- // belongs to.
- LCursor cur = pi.base.bv->cursor();
- setLabel(cur);
- labelwidth_ = pi.pain.text(x, y, label, pi.base.font);
+ // Answer: the text inset (in buffer_funcs.C: setCaption).
+
+ labelwidth_ = pi.pain.text(x, y, full_label_, pi.base.font);
InsetText::draw(pi, x + labelwidth_, y);
setPosCache(pi, x, y);
}
Index: insets/insetcaption.h
===================================================================
--- insets/insetcaption.h (revision 16876)
+++ insets/insetcaption.h (working copy)
@@ -12,7 +12,6 @@
#ifndef INSETCAPTION_H
#define INSETCAPTION_H
-
#include "insettext.h"
#include "lyxtextclass.h"
@@ -61,18 +60,21 @@
OutputParams const & runparams) const;
///
void setCount(int c) { counter_ = c; }
+ ///
+ void setLabel(docstring const & label);
+
private:
///
- void setLabel(LCursor & cur) const;
- ///
virtual std::auto_ptr<InsetBase> doClone() const;
///
- mutable docstring label;
+ mutable docstring full_label_;
///
mutable int labelwidth_;
///
- mutable int counter_;
+ docstring label_;
///
+ int counter_;
+ ///
LyXTextClass const & textclass_;
};
Index: text3.C
===================================================================
--- text3.C (revision 16876)
+++ text3.C (working copy)
@@ -1127,8 +1127,8 @@
#if 0
case LFUN_LIST_INSERT:
case LFUN_THEOREM_INSERT:
- case LFUN_CAPTION_INSERT:
#endif
+ case LFUN_CAPTION_INSERT:
case LFUN_NOTE_INSERT:
case LFUN_CHARSTYLE_INSERT:
case LFUN_BOX_INSERT:
@@ -1159,9 +1159,8 @@
case LFUN_WRAP_INSERT:
doInsertInset(cur, this, cmd, true, true);
cur.posRight();
- // FIXME: the "Caption" name should not be hardcoded,
- // but given by the float definition.
- cur.dispatch(FuncRequest(LFUN_LAYOUT, "Caption"));
+ cur.dispatch(FuncRequest(LFUN_CAPTION_INSERT));
+ updateLabels(cur.buffer());
break;
case LFUN_INDEX_INSERT: