]> git.lyx.org Git - lyx.git/blob - src/insets/InsetNewpage.cpp
Circumvent odd stmary font metrics (part of #9990).
[lyx.git] / src / insets / InsetNewpage.cpp
1 /**
2  * \file InsetNewpage.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author André Pönitz
7  * \author Jürgen Spitzmüller
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "InsetNewpage.h"
15
16 #include "Cursor.h"
17 #include "FuncRequest.h"
18 #include "FuncStatus.h"
19 #include "Lexer.h"
20 #include "MetricsInfo.h"
21 #include "OutputParams.h"
22 #include "output_xhtml.h"
23 #include "Text.h"
24 #include "TextMetrics.h"
25
26 #include "frontends/FontMetrics.h"
27 #include "frontends/Painter.h"
28
29 #include "support/debug.h"
30 #include "support/docstring.h"
31 #include "support/docstream.h"
32 #include "support/gettext.h"
33
34 using namespace std;
35
36
37 namespace lyx {
38
39         InsetNewpage::InsetNewpage() : Inset(0)
40 {}
41
42
43 InsetNewpage::InsetNewpage(InsetNewpageParams const & params)
44         : Inset(0), params_(params)
45 {}
46
47
48 void InsetNewpageParams::write(ostream & os) const
49 {
50         switch (kind) {
51         case InsetNewpageParams::NEWPAGE:
52                 os << "newpage";
53                 break;
54         case InsetNewpageParams::PAGEBREAK:
55                 os <<  "pagebreak";
56                 break;
57         case InsetNewpageParams::CLEARPAGE:
58                 os <<  "clearpage";
59                 break;
60         case InsetNewpageParams::CLEARDOUBLEPAGE:
61                 os <<  "cleardoublepage";
62                 break;
63         }
64 }
65
66
67 void InsetNewpageParams::read(Lexer & lex)
68 {
69         lex.setContext("InsetNewpageParams::read");
70         string token;
71         lex >> token;
72
73         if (token == "newpage")
74                 kind = InsetNewpageParams::NEWPAGE;
75         else if (token == "pagebreak")
76                 kind = InsetNewpageParams::PAGEBREAK;
77         else if (token == "clearpage")
78                 kind = InsetNewpageParams::CLEARPAGE;
79         else if (token == "cleardoublepage")
80                 kind = InsetNewpageParams::CLEARDOUBLEPAGE;
81         else
82                 lex.printError("Unknown kind");
83 }
84
85
86 void InsetNewpage::write(ostream & os) const
87 {
88         os << "Newpage ";
89         params_.write(os);
90 }
91
92
93 void InsetNewpage::read(Lexer & lex)
94 {
95         params_.read(lex);
96         lex >> "\\end_inset";
97 }
98
99
100 void InsetNewpage::metrics(MetricsInfo & mi, Dimension & dim) const
101 {
102         dim.asc = defaultRowHeight();
103         dim.des = defaultRowHeight();
104         dim.wid = mi.base.textwidth;
105         // Cache the inset dimension. 
106         setDimCache(mi, dim);
107 }
108
109
110 void InsetNewpage::draw(PainterInfo & pi, int x, int y) const
111 {
112         using frontend::Painter;
113
114         FontInfo font;
115         font.setColor(ColorName());
116         font.decSize();
117
118         Dimension const dim = dimension(*pi.base.bv);
119
120         int w = 0;
121         int a = 0;
122         int d = 0;
123         theFontMetrics(font).rectText(insetLabel(), w, a, d);
124
125         int const text_start = int(x + (dim.wid - w) / 2);
126         int const text_end = text_start + w;
127
128         pi.pain.rectText(text_start, y + d, insetLabel(), font,
129                 Color_none, Color_none);
130
131         pi.pain.line(x, y, text_start, y,
132                    ColorName(), Painter::line_onoffdash);
133         pi.pain.line(text_end, y, int(x + dim.wid), y,
134                    ColorName(), Painter::line_onoffdash);
135 }
136
137
138 void InsetNewpage::doDispatch(Cursor & cur, FuncRequest & cmd)
139 {
140         switch (cmd.action()) {
141
142         case LFUN_INSET_MODIFY: {
143                 InsetNewpageParams params;
144                 cur.recordUndo();
145                 string2params(to_utf8(cmd.argument()), params);
146                 params_.kind = params.kind;
147                 break;
148         }
149
150         default:
151                 Inset::doDispatch(cur, cmd);
152                 break;
153         }
154 }
155
156
157 bool InsetNewpage::getStatus(Cursor & cur, FuncRequest const & cmd,
158         FuncStatus & status) const
159 {
160         switch (cmd.action()) {
161         // we handle these
162         case LFUN_INSET_MODIFY:
163                 if (cmd.getArg(0) == "newpage") {
164                         InsetNewpageParams params;
165                         string2params(to_utf8(cmd.argument()), params);
166                         status.setOnOff(params_.kind == params.kind);
167                 } 
168                 status.setEnabled(true);
169                 return true;
170         default:
171                 return Inset::getStatus(cur, cmd, status);
172         }
173 }
174
175
176 docstring InsetNewpage::insetLabel() const
177 {
178         switch (params_.kind) {
179                 case InsetNewpageParams::NEWPAGE:
180                         return _("New Page");
181                         break;
182                 case InsetNewpageParams::PAGEBREAK:
183                         return _("Page Break");
184                         break;
185                 case InsetNewpageParams::CLEARPAGE:
186                         return _("Clear Page");
187                         break;
188                 case InsetNewpageParams::CLEARDOUBLEPAGE:
189                         return _("Clear Double Page");
190                         break;
191                 default:
192                         return _("New Page");
193                         break;
194         }
195 }
196
197
198 ColorCode InsetNewpage::ColorName() const
199 {
200         switch (params_.kind) {
201                 case InsetNewpageParams::PAGEBREAK:
202                         return Color_pagebreak;
203                         break;
204                 case InsetNewpageParams::NEWPAGE:
205                 case InsetNewpageParams::CLEARPAGE:
206                 case InsetNewpageParams::CLEARDOUBLEPAGE:
207                         return Color_newpage;
208                         break;
209         }
210         // not really useful, but to avoids gcc complaints
211         return Color_newpage;
212 }
213
214
215 void InsetNewpage::latex(otexstream & os, OutputParams const &) const
216 {
217         switch (params_.kind) {
218                 case InsetNewpageParams::NEWPAGE:
219                         os << "\\newpage{}";
220                         break;
221                 case InsetNewpageParams::PAGEBREAK:
222                         os << "\\pagebreak{}";
223                         break;
224                 case InsetNewpageParams::CLEARPAGE:
225                         os << "\\clearpage{}";
226                         break;
227                 case InsetNewpageParams::CLEARDOUBLEPAGE:
228                         os << "\\cleardoublepage{}";
229                         break;
230                 default:
231                         os << "\\newpage{}";
232                         break;
233         }
234 }
235
236
237 int InsetNewpage::plaintext(odocstringstream & os,
238         OutputParams const &, size_t) const
239 {
240         os << '\n';
241         return PLAINTEXT_NEWLINE;
242 }
243
244
245 int InsetNewpage::docbook(odocstream & os, OutputParams const &) const
246 {
247         os << '\n';
248         return 0;
249 }
250
251
252 docstring InsetNewpage::xhtml(XHTMLStream & xs, OutputParams const &) const
253 {
254         xs << html::CompTag("br");
255         return docstring();
256 }
257
258
259 string InsetNewpage::contextMenuName() const
260 {
261         return "context-newpage";
262 }
263
264
265 void InsetNewpage::string2params(string const & in, InsetNewpageParams & params)
266 {
267         params = InsetNewpageParams();
268         if (in.empty())
269                 return;
270
271         istringstream data(in);
272         Lexer lex;
273         lex.setStream(data);
274
275         string name;
276         lex >> name;
277         if (!lex || name != "newpage") {
278                 LYXERR0("Expected arg 2 to be \"wrap\" in " << in);
279                 return;
280         }
281
282         params.read(lex);
283 }
284
285
286 string InsetNewpage::params2string(InsetNewpageParams const & params)
287 {
288         ostringstream data;
289         data << "newpage" << ' ';
290         params.write(data);
291         return data.str();
292 }
293
294
295 } // namespace lyx