]> git.lyx.org Git - lyx.git/blob - src/insets/InsetCaptionable.cpp
Improve handling of top and bottom margin
[lyx.git] / src / insets / InsetCaptionable.cpp
1 /**
2  * \file InsetCaptionable.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Alejandro Aguilar Sierra
7  * \author Jürgen Vigna
8  * \author Lars Gullik Bjønnes
9  * \author Guillaume Munch
10  *
11  * Full author contact details are available in file CREDITS.
12  */
13
14 #include <config.h>
15
16 #include "InsetCaptionable.h"
17
18 #include "InsetCaption.h"
19
20 #include "Buffer.h"
21 #include "BufferParams.h"
22 #include "BufferView.h"
23 #include "FloatList.h"
24 #include "InsetList.h"
25 #include "output_xhtml.h"
26 #include "TextClass.h"
27 #include "TocBackend.h"
28
29 #include "support/docstream.h"
30
31 using namespace std;
32
33
34 namespace lyx {
35
36
37 void InsetCaptionable::setCaptionType(std::string const & type)
38 {
39         caption_type_ = type.empty() ? "senseless" : type;
40 }
41
42
43 /// common to InsetFloat and InsetWrap
44 docstring InsetCaptionable::floatName(string const & type) const
45 {
46         BufferParams const & bp = buffer().params();
47         FloatList const & floats = bp.documentClass().floats();
48         FloatList::const_iterator it = floats[type];
49         return (it == floats.end()) ? from_utf8(type) : bp.B_(it->second.name());
50 }
51
52
53 InsetCaption const * InsetCaptionable::getCaptionInset() const
54 {
55         ParagraphList::const_iterator pit = paragraphs().begin();
56         for (; pit != paragraphs().end(); ++pit) {
57                 InsetList::const_iterator it = pit->insetList().begin();
58                 for (; it != pit->insetList().end(); ++it) {
59                         Inset & inset = *it->inset;
60                         if (inset.lyxCode() == CAPTION_CODE) {
61                                 InsetCaption const * ins =
62                                         static_cast<InsetCaption const *>(it->inset);
63                                 return ins;
64                         }
65                 }
66         }
67         return 0;
68 }
69
70
71 docstring InsetCaptionable::getCaptionText(OutputParams const & runparams) const
72 {
73         InsetCaption const * ins = getCaptionInset();
74         if (ins == 0)
75                 return docstring();
76
77         odocstringstream ods;
78         ins->getCaptionAsPlaintext(ods, runparams);
79         return ods.str();
80 }
81
82
83 docstring InsetCaptionable::getCaptionDocBook(OutputParams const & runparams) const
84 {
85         InsetCaption const * ins = getCaptionInset();
86         if (ins == nullptr)
87                 return docstring();
88
89         odocstringstream ods;
90         XMLStream xs(ods);
91         ins->getCaptionAsDocBook(xs, runparams);
92         return ods.str();
93 }
94
95
96 docstring InsetCaptionable::getCaptionHTML(OutputParams const & runparams) const
97 {
98         InsetCaption const * ins = getCaptionInset();
99         if (ins == 0)
100                 return docstring();
101
102         odocstringstream ods;
103         XMLStream xs(ods);
104         docstring def = ins->getCaptionAsHTML(xs, runparams);
105         if (!def.empty())
106                 // should already have been escaped
107                 xs << XMLStream::ESCAPE_NONE << def << '\n';
108         return ods.str();
109 }
110
111
112 void InsetCaptionable::addToToc(DocIterator const & cpit, bool output_active,
113                                                                 UpdateType utype, TocBackend & backend) const
114 {
115         DocIterator pit = cpit;
116         pit.push_back(CursorSlice(const_cast<InsetCaptionable &>(*this)));
117         docstring str;
118         // Leave str empty if we generate for output (e.g. xhtml lists of figures).
119         // This ensures that there is a caption if and only if the string is
120         // non-empty.
121         if (utype != OutputUpdate)
122                 text().forOutliner(str, TOC_ENTRY_LENGTH);
123         TocBuilder & b = backend.builder(caption_type_);
124         b.pushItem(pit, str, output_active);
125         // Proceed with the rest of the inset.
126         InsetCollapsible::addToToc(cpit, output_active, utype, backend);
127         b.pop();
128 }
129
130 void InsetCaptionable::updateBuffer(ParIterator const & it, UpdateType utype, bool const deleted)
131 {
132         Counters & cnts =
133                 buffer().masterBuffer()->params().documentClass().counters();
134         string const saveflt = cnts.current_float();
135         bool const savesubflt = cnts.isSubfloat();
136         if (utype == OutputUpdate) {
137                 // counters are local to the float
138                 cnts.saveLastCounter();
139         }
140         bool const subflt = hasSubCaptions(it);
141         // floats can only embed subfloats of their own kind
142         if (subflt && !saveflt.empty() && saveflt != "senseless")
143                 setCaptionType(saveflt);
144         // Tell captions what the current float is
145         cnts.current_float(caption_type_);
146         cnts.isSubfloat(subflt);
147         InsetCollapsible::updateBuffer(it, utype, deleted);
148         // Restore counters
149         cnts.current_float(saveflt);
150         if (utype == OutputUpdate)
151                 cnts.restoreLastCounter();
152         cnts.isSubfloat(savesubflt);
153 }
154
155
156 bool InsetCaptionable::insetAllowed(InsetCode c) const
157 {
158         return (c == CAPTION_CODE) || InsetCollapsible::insetAllowed(c);
159 }
160
161
162 } // namespace lyx