]> git.lyx.org Git - lyx.git/blob - src/insets/InsetCounter.cpp
Allow row-breaking after some insets
[lyx.git] / src / insets / InsetCounter.cpp
1 /**
2  * \file InsetCounter.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Richard Kimberly Heck
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10 #include <config.h>
11
12 #include "InsetCounter.h"
13
14 #include "Buffer.h"
15 #include "BufferParams.h"
16 #include "Counters.h"
17 #include "LaTeXFeatures.h"
18 #include "OutputParams.h"
19 #include "output_xhtml.h"
20 #include "xml.h"
21 #include "texstream.h"
22 #include "TextClass.h"
23
24 #include "support/convert.h"
25 #include "support/counter_reps.h"
26 #include "support/docstream.h"
27 #include "support/gettext.h"
28 #include "support/lassert.h"
29 #include "support/lstrings.h"
30
31 #include <map>
32
33 /*
34 #include "Cursor.h"
35 #include "DispatchResult.h"
36 #include "Language.h"
37 #include "LyX.h"
38 #include "ParIterator.h"
39 #include "TocBackend.h"
40
41 #include "support/debug.h"
42 #include "support/textutils.h"
43 */
44
45 using namespace lyx::support;
46 using namespace std;
47
48 namespace lyx {
49
50
51 InsetCounter::InsetCounter(Buffer * buf, InsetCommandParams const & p)
52         : InsetCommand(buf, p)
53 {}
54
55
56 InsetCounter::InsetCounter(InsetCounter const & ir)
57         : InsetCommand(ir)
58 {}
59
60
61 const vector<pair<string, string>> InsetCounter::counterTable =
62 {
63         {"set", N_("Set counter to ...")},
64         {"addto", N_("Increase counter by ...")},
65         {"reset", N_("Reset counter to 0")},
66         {"save", N_("Save current counter value")},
67         {"restore", N_("Restore saved counter value")},
68 };
69
70
71 bool InsetCounter::isCompatibleCommand(string const & s)
72 {
73         for (auto & i : counterTable) {
74                 if (i.first == s)
75                         return true;
76         }
77         return false;
78 }
79
80
81 ParamInfo const & InsetCounter::findInfo(string const & /* cmdName */)
82 {
83         static ParamInfo param_info_;
84         if (param_info_.empty()) {
85                 param_info_.add("counter", ParamInfo::LYX_INTERNAL);
86                 param_info_.add("value", ParamInfo::LYX_INTERNAL);
87                 param_info_.add("lyxonly", ParamInfo::LYX_INTERNAL);
88         }
89         return param_info_;
90 }
91
92
93 void InsetCounter::latex(otexstream & os, OutputParams const &) const
94 {
95         bool const lyxonly = lowercase(getParam("lyxonly")) == "true";
96         if (lyxonly)
97                 return;
98
99         string const cmd = getCmdName();
100         docstring cntr = getParam("counter");
101         Counters & cnts = buffer().params().documentClass().counters();
102         if (cmd == "set") {
103                 docstring const & val = getParam("value");
104                 os << "\\setcounter{" << cntr << "}{" << val << "}";
105         } else if (cmd == "addto") {
106                 docstring const & val = getParam("value");
107                 os << "\\addtocounter{" << cntr << "}{" << val << "}";
108         } else if (cmd == "reset") {
109                 os << "\\setcounter{" << cntr << "}{0}";
110         } else if (cmd == "save") {
111                 cnts.saveValue(cntr);
112                 os << "\\setcounter{" << lyxSaveCounter() 
113                    << "}{\\value{" << cntr << "}}";
114         } else if (cmd == "restore") {
115                 cnts.restoreValue(cntr);
116                 os << "\\setcounter{" << cntr
117                    << "{\\value{" << lyxSaveCounter() << "}}";
118         }
119 }
120
121
122 void InsetCounter::toString(odocstream & os) const
123 {
124         os << "[Counter " << from_utf8(getCmdName()) << ": " 
125            <<  getParam("counter") << "]";
126 }
127
128
129 int InsetCounter::plaintext(odocstringstream & os,
130         OutputParams const &, size_t) const
131 {
132         toString(os);
133         return 0;
134 }
135
136
137 #if 0
138 // save this code until we get it working in InsetInfo
139 const map<string, string> InsetCounter::valueTable =
140 {
141         {"Roman", N_("Roman Uppercase")},
142         {"roman", N_("Roman Lowercase")},
143         {"Alpha", N_("Uppercase Letter")},
144         {"alpha", N_("Lowercase Letter")},
145         {"arabic", N_("Arabic Numeral")}
146 };
147
148
149 docstring InsetCounter::value() const {
150         docstring const & cnt = getParam("counter");
151         string const & vtype = getCmdName();
152         int const val = buffer().params().documentClass().counters().value(cnt);
153         if (vtype   == "Roman")
154                 return romanCounter(val);
155         if (vtype   == "roman")
156                 return lowerromanCounter(val);
157         if (vtype   == "Alpha")
158                 return docstring(1, alphaCounter(val));
159         if (vtype   == "alpha")
160                 return docstring(1, loweralphaCounter(val));
161         if (vtype   == "arabic")
162                 return convert<docstring>(val);
163         LATTEST(false);
164         return empty_docstring();
165 }
166 #endif
167
168 void InsetCounter::trackCounters(string const & cmd) const
169 {
170         Counters & cnts = buffer().params().documentClass().counters();
171         docstring cntr = getParam("counter");
172         if (cmd == "set") {
173                 docstring const & val = getParam("value");
174                 cnts.set(cntr, convert<int>(val));
175         } else if (cmd == "addto") {
176                 docstring const & val = getParam("value");
177                 cnts.addto(cntr, convert<int>(val));
178         } else if (cmd == "reset") {
179                 cnts.reset(cntr);
180         } else if (cmd == "save") {
181                 cnts.saveValue(cntr);
182         } else if (cmd == "restore") {
183                 cnts.restoreValue(cntr);
184         }
185 }
186
187 int InsetCounter::docbook(odocstream &, OutputParams const &) const
188 {
189         // Here, we need to track counter values ourselves,
190         // since unlike in the LaTeX case, there is no external
191         // mechanism for doing that.
192         trackCounters(getCmdName());
193         return 0;
194 }
195
196
197 docstring InsetCounter::xhtml(XMLStream &, OutputParams const &) const
198 {
199         // Here, we need to track counter values ourselves,
200         // since unlike in the LaTeX case, there is no external
201         // mechanism for doing that.
202         trackCounters(getCmdName());
203         return docstring();
204 }
205
206
207 void InsetCounter::updateBuffer(ParIterator const &, UpdateType, bool const)
208 {
209         string const cmd = getCmdName();
210         docstring cntr = getParam("counter");
211         Counters & cnts = buffer().params().documentClass().counters();
212         string label;
213         for (auto & i : counterTable) {
214                 if (i.first == cmd)
215                         label = i.second;
216         }
217         LASSERT(!label.empty(), return);
218         docstring const tlabel = translateIfPossible(from_ascii(label));
219
220         docstring guiname = translateIfPossible(cnts.guiName(cntr));
221         if (cmd == "set") {
222                 docstring const & val = getParam("value");
223                 cnts.set(cntr, convert<int>(val));
224                 screen_label_ = bformat(_("Counter: Set %1$s"), guiname);
225                 tooltip_ = bformat(_("Set value of counter %1$s to %2$s"), cntr, val);
226         } else if (cmd == "addto") {
227                 docstring const & val = getParam("value");
228                 cnts.addto(cntr, convert<int>(val));
229                 screen_label_ = bformat(_("Counter: Add to %1$s"), guiname);
230                 tooltip_ = bformat(_("Add %1$s to value of counter %2$s"), val, cntr);
231         } else if (cmd == "reset") {
232                 cnts.reset(cntr);               
233                 screen_label_ = bformat(_("Counter: Reset %1$s"), guiname);
234                 tooltip_ = bformat(_("Reset value of counter %1$s"), cntr);
235         } else if (cmd == "save") {
236                 cnts.saveValue(cntr);
237                 screen_label_ = bformat(_("Counter: Save %1$s"), guiname);
238                 tooltip_ = bformat(_("Save value of counter %1$s"), cntr);
239         } else if (cmd == "restore") {
240                 cnts.restoreValue(cntr);
241                 screen_label_ = bformat(_("Counter: Restore %1$s"), guiname);
242                 tooltip_ = bformat(_("Restore value of counter %1$s"), cntr);
243         }
244 }
245
246
247 docstring InsetCounter::lyxSaveCounter() const
248 {
249         docstring cntr = getParam("counter");
250         return from_ascii("LyXSave") + cntr;
251 }
252
253
254 void InsetCounter::validate(LaTeXFeatures & features) const
255 {
256         // create save counter if needed
257         string const cmd = getCmdName();
258         docstring const lyxonly = getParam("lyxonly");
259         if ((cmd == "save" || cmd == "restore") && lyxonly != "true") {
260                 features.addPreambleSnippet(from_ascii("\\newcounter{") + lyxSaveCounter() + "}");
261         }
262     InsetCommand::validate(features);
263 }
264
265
266 string InsetCounter::contextMenuName() const 
267
268         return "context-counter"; 
269 }
270 } // namespace lyx