2 * \file InsetCaption.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Lars Gullik Bjønnes
8 * Full author contact details are available in file CREDITS.
13 #include "InsetCaption.h"
14 #include "InsetFloat.h"
15 #include "InsetWrap.h"
18 #include "BufferParams.h"
19 #include "BufferView.h"
22 #include "Dimension.h"
24 #include "FloatList.h"
25 #include "FuncRequest.h"
26 #include "FuncStatus.h"
27 #include "InsetList.h"
28 #include "MetricsInfo.h"
29 #include "output_latex.h"
30 #include "OutputParams.h"
31 #include "Paragraph.h"
32 #include "paragraph_funcs.h"
33 #include "TextClass.h"
34 #include "TocBackend.h"
36 #include "frontends/FontMetrics.h"
37 #include "frontends/Painter.h"
39 #include "support/gettext.h"
40 #include "support/lstrings.h"
45 using namespace lyx::support
;
50 InsetCaption::InsetCaption(Buffer
const & buf
)
51 : InsetText(buf
, InsetText::PlainLayout
)
53 setAutoBreakRows(true);
55 setFrameColor(Color_captionframe
);
59 void InsetCaption::write(ostream
& os
) const
62 text().write(buffer(), os
);
66 void InsetCaption::read(Lexer
& lex
)
69 // We will enably this check again when the compability
70 // code is removed from Buffer::Read (Lgb)
71 lex
.setContext("InsetCaption::Read: consistency check");
78 docstring
InsetCaption::editMessage() const
80 return _("Opened Caption Inset");
84 void InsetCaption::cursorPos(BufferView
const & bv
,
85 CursorSlice
const & sl
, bool boundary
, int & x
, int & y
) const
87 InsetText::cursorPos(bv
, sl
, boundary
, x
, y
);
92 void InsetCaption::setCustomLabel(docstring
const & label
)
94 if (!isAscii(label
) || label
.empty())
95 // This must be a user defined layout. We cannot translate
96 // this, since gettext accepts only ascii keys.
97 custom_label_
= label
;
99 custom_label_
= _(to_ascii(label
));
103 void InsetCaption::addToToc(DocIterator
const & cpit
)
108 DocIterator pit
= cpit
;
109 pit
.push_back(CursorSlice(*this));
111 Toc
& toc
= buffer().tocBackend().toc(type_
);
112 docstring
const str
= full_label_
+ ". " + text().getPar(0).asString();
113 toc
.push_back(TocItem(pit
, 0, str
));
115 // Proceed with the rest of the inset.
116 InsetText::addToToc(cpit
);
120 void InsetCaption::metrics(MetricsInfo
& mi
, Dimension
& dim
) const
122 FontInfo tmpfont
= mi
.base
.font
;
123 mi
.base
.font
= mi
.base
.bv
->buffer().params().getFont().fontInfo();
124 labelwidth_
= theFontMetrics(mi
.base
.font
).width(full_label_
);
125 // add some space to separate the label from the inset text
126 labelwidth_
+= 2 * TEXT_TO_INSET_OFFSET
;
127 dim
.wid
= labelwidth_
;
129 // Correct for button and label width
130 mi
.base
.textwidth
-= dim
.wid
;
131 InsetText::metrics(mi
, textdim
);
132 mi
.base
.font
= tmpfont
;
133 mi
.base
.textwidth
+= dim
.wid
;
134 dim
.des
= max(dim
.des
- textdim
.asc
+ dim
.asc
, textdim
.des
);
135 dim
.asc
= textdim
.asc
;
136 dim
.wid
+= textdim
.wid
;
140 void InsetCaption::draw(PainterInfo
& pi
, int x
, int y
) const
142 // We must draw the label, we should get the label string
143 // from the enclosing float inset.
144 // The question is: Who should draw the label, the caption inset,
145 // the text inset or the paragraph?
146 // We should also draw the float number (Lgb)
148 // Answer: the text inset (in buffer_funcs.cpp: setCaption).
150 FontInfo tmpfont
= pi
.base
.font
;
151 pi
.base
.font
= pi
.base
.bv
->buffer().params().getFont().fontInfo();
152 pi
.pain
.text(x
, y
, full_label_
, pi
.base
.font
);
153 InsetText::draw(pi
, x
+ labelwidth_
, y
);
154 pi
.base
.font
= tmpfont
;
158 void InsetCaption::edit(Cursor
& cur
, bool front
, EntryDirection entry_from
)
161 InsetText::edit(cur
, front
, entry_from
);
165 Inset
* InsetCaption::editXY(Cursor
& cur
, int x
, int y
)
168 return InsetText::editXY(cur
, x
, y
);
172 bool InsetCaption::insetAllowed(InsetCode code
) const
183 return InsetText::insetAllowed(code
);
188 bool InsetCaption::getStatus(Cursor
& cur
, FuncRequest
const & cmd
,
189 FuncStatus
& status
) const
191 switch (cmd
.action
) {
193 case LFUN_BREAK_PARAGRAPH
:
194 status
.setEnabled(false);
197 case LFUN_OPTIONAL_INSERT
:
198 status
.setEnabled(cur
.paragraph().insetList().find(OPTARG_CODE
) == -1);
201 case LFUN_INSET_TOGGLE
:
202 // pass back to owner
207 return InsetText::getStatus(cur
, cmd
, status
);
212 int InsetCaption::latex(odocstream
& os
,
213 OutputParams
const & runparams_in
) const
215 if (runparams_in
.inFloat
== OutputParams::SUBFLOAT
)
216 // caption is output as an optional argument
218 // This is a bit too simplistic to take advantage of
219 // caption options we must add more later. (Lgb)
220 // This code is currently only able to handle the simple
221 // \caption{...}, later we will make it take advantage
222 // of the one of the caption packages. (Lgb)
223 OutputParams runparams
= runparams_in
;
224 // FIXME: actually, it is moving only when there is no
225 // optional argument.
226 runparams
.moving_arg
= true;
228 int l
= latexOptArgInsets(paragraphs()[0], os
, runparams
, 1);
230 l
+= InsetText::latex(os
, runparams
);
232 runparams_in
.encoding
= runparams
.encoding
;
237 int InsetCaption::plaintext(odocstream
& os
,
238 OutputParams
const & runparams
) const
240 os
<< '[' << full_label_
<< "\n";
241 InsetText::plaintext(os
, runparams
);
244 return PLAINTEXT_NEWLINE
+ 1; // one char on a separate line
248 int InsetCaption::docbook(odocstream
& os
,
249 OutputParams
const & runparams
) const
253 ret
= InsetText::docbook(os
, runparams
);
259 docstring
InsetCaption::xhtml(odocstream
& os
,
260 OutputParams
const & rp
) const
262 if (rp
.disable_captions
)
264 os
<< "<div class='float-caption'>\n";
265 docstring def
= getCaptionAsHTML(os
, rp
);
270 int InsetCaption::getArgument(odocstream
& os
,
271 OutputParams
const & runparams
) const
273 return InsetText::latex(os
, runparams
);
277 int InsetCaption::getOptArg(odocstream
& os
,
278 OutputParams
const & runparams
) const
280 return latexOptArgInsets(paragraphs()[0], os
, runparams
, 1);
284 int InsetCaption::getCaptionAsPlaintext(odocstream
& os
,
285 OutputParams
const & runparams
) const
287 os
<< full_label_
<< ' ';
288 return InsetText::plaintext(os
, runparams
);
292 docstring
InsetCaption::getCaptionAsHTML(odocstream
& os
,
293 OutputParams
const & runparams
) const
295 os
<< full_label_
<< ' ';
296 return InsetText::xhtml(os
, runparams
);
300 void InsetCaption::updateLabels(ParIterator
const & it
)
302 Buffer
const & master
= *buffer().masterBuffer();
303 DocumentClass
const & tclass
= master
.params().documentClass();
304 Counters
& cnts
= tclass
.counters();
305 string
const & type
= cnts
.current_float();
306 // Memorize type for addToToc().
309 full_label_
= master
.B_("Senseless!!! ");
311 // FIXME: life would be _much_ simpler if listings was
312 // listed in Floating.
314 if (type
== "listing")
315 name
= master
.B_("Listing");
317 name
= master
.B_(tclass
.floats().getType(type
).name());
318 docstring counter
= from_utf8(type
);
319 if (cnts
.isSubfloat()) {
320 counter
= "sub-" + from_utf8(type
);
321 name
= bformat(_("Sub-%1$s"),
322 master
.B_(tclass
.floats().getType(type
).name()));
324 if (cnts
.hasCounter(counter
)) {
326 full_label_
= bformat(from_ascii("%1$s %2$s:"),
328 cnts
.theCounter(counter
));
330 full_label_
= bformat(from_ascii("%1$s #:"), name
);
333 // Do the real work now.
334 InsetText::updateLabels(it
);