]> git.lyx.org Git - lyx.git/blob - src/insets/InsetCounter.cpp
Improve handling of top and bottom margin
[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 void InsetCounter::docbook(XMLStream &, 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 }
194
195
196 docstring InsetCounter::xhtml(XMLStream &, OutputParams const &) const
197 {
198         // Here, we need to track counter values ourselves,
199         // since unlike in the LaTeX case, there is no external
200         // mechanism for doing that.
201         trackCounters(getCmdName());
202         return docstring();
203 }
204
205
206 void InsetCounter::updateBuffer(ParIterator const &, UpdateType, bool const)
207 {
208         string const cmd = getCmdName();
209         docstring cntr = getParam("counter");
210         Counters & cnts = buffer().params().documentClass().counters();
211         string label;
212         for (auto & i : counterTable) {
213                 if (i.first == cmd)
214                         label = i.second;
215         }
216         LASSERT(!label.empty(), return);
217         docstring const tlabel = translateIfPossible(from_ascii(label));
218
219         docstring guiname = translateIfPossible(cnts.guiName(cntr));
220         if (cmd == "set") {
221                 docstring const & val = getParam("value");
222                 cnts.set(cntr, convert<int>(val));
223                 screen_label_ = bformat(_("Counter: Set %1$s"), guiname);
224                 tooltip_ = bformat(_("Set value of counter %1$s to %2$s"), cntr, val);
225         } else if (cmd == "addto") {
226                 docstring const & val = getParam("value");
227                 cnts.addto(cntr, convert<int>(val));
228                 screen_label_ = bformat(_("Counter: Add to %1$s"), guiname);
229                 tooltip_ = bformat(_("Add %1$s to value of counter %2$s"), val, cntr);
230         } else if (cmd == "reset") {
231                 cnts.reset(cntr);               
232                 screen_label_ = bformat(_("Counter: Reset %1$s"), guiname);
233                 tooltip_ = bformat(_("Reset value of counter %1$s"), cntr);
234         } else if (cmd == "save") {
235                 cnts.saveValue(cntr);
236                 screen_label_ = bformat(_("Counter: Save %1$s"), guiname);
237                 tooltip_ = bformat(_("Save value of counter %1$s"), cntr);
238         } else if (cmd == "restore") {
239                 cnts.restoreValue(cntr);
240                 screen_label_ = bformat(_("Counter: Restore %1$s"), guiname);
241                 tooltip_ = bformat(_("Restore value of counter %1$s"), cntr);
242         }
243 }
244
245
246 docstring InsetCounter::lyxSaveCounter() const
247 {
248         docstring cntr = getParam("counter");
249         return from_ascii("LyXSave") + cntr;
250 }
251
252
253 void InsetCounter::validate(LaTeXFeatures & features) const
254 {
255         // create save counter if needed
256         string const cmd = getCmdName();
257         docstring const lyxonly = getParam("lyxonly");
258         if ((cmd == "save" || cmd == "restore") && lyxonly != "true") {
259                 features.addPreambleSnippet(from_ascii("\\newcounter{") + lyxSaveCounter() + "}");
260         }
261     InsetCommand::validate(features);
262 }
263
264
265 string InsetCounter::contextMenuName() const 
266
267         return "context-counter"; 
268 }
269 } // namespace lyx