]> git.lyx.org Git - features.git/blob - src/insets/InsetSpace.cpp
f83880a2d60bc71783c84326c2ab3a4c3824f24f
[features.git] / src / insets / InsetSpace.cpp
1 /**
2  * \file InsetSpace.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Asger Alstrup Nielsen
7  * \author Jean-Marc Lasgouttes
8  * \author Lars Gullik Bjønnes
9  * \author Jürgen Spitzmüller
10  *
11  * Full author contact details are available in file CREDITS.
12  */
13
14 #include <config.h>
15
16 #include "InsetSpace.h"
17
18 #include "BufferView.h"
19 #include "Cursor.h"
20 #include "Dimension.h"
21 #include "FuncRequest.h"
22 #include "FuncStatus.h"
23 #include "Length.h"
24 #include "Lexer.h"
25 #include "MetricsInfo.h"
26 #include "OutputParams.h"
27
28 #include "support/debug.h"
29 #include "support/docstream.h"
30 #include "support/gettext.h"
31 #include "support/lstrings.h"
32
33 #include "frontends/Application.h"
34 #include "frontends/FontMetrics.h"
35 #include "frontends/Painter.h"
36
37 using namespace std;
38
39 namespace lyx {
40
41
42 InsetSpace::InsetSpace(InsetSpaceParams const & params)
43         : params_(params)
44 {}
45
46
47 InsetSpaceParams::Kind InsetSpace::kind() const
48 {
49         return params_.kind;
50 }
51
52
53 Length InsetSpace::length() const
54 {
55         return params_.length;
56 }
57
58
59 InsetSpace::~InsetSpace()
60 {
61         hideDialogs("space", this);
62 }
63
64
65 docstring InsetSpace::toolTip(BufferView const &, int, int) const
66 {
67         docstring message;
68         switch (params_.kind) {
69         case InsetSpaceParams::NORMAL:
70                 message = _("Interword Space");
71                 break;
72         case InsetSpaceParams::PROTECTED:
73                 message = _("Protected Space");
74                 break;
75         case InsetSpaceParams::THIN:
76                 message = _("Thin Space");
77                 break;
78         case InsetSpaceParams::QUAD:
79                 message = _("Quad Space");
80                 break;
81         case InsetSpaceParams::QQUAD:
82                 message = _("QQuad Space");
83                 break;
84         case InsetSpaceParams::ENSPACE:
85                 message = _("Enspace");
86                 break;
87         case InsetSpaceParams::ENSKIP:
88                 message = _("Enskip");
89                 break;
90         case InsetSpaceParams::NEGTHIN:
91                 message = _("Negative Thin Space");
92                 break;
93         case InsetSpaceParams::HFILL:
94                 message = _("Horizontal Fill");
95                 break;
96         case InsetSpaceParams::HFILL_PROTECTED:
97                 message = _("Protected Horizontal Fill");
98                 break;
99         case InsetSpaceParams::DOTFILL:
100                 message = _("Horizontal Fill (Dots)");
101                 break;
102         case InsetSpaceParams::HRULEFILL:
103                 message = _("Horizontal Fill (Rule)");
104                 break;
105         case InsetSpaceParams::LEFTARROWFILL:
106                 message = _("Horizontal Fill (Left Arrow)");
107                 break;
108         case InsetSpaceParams::RIGHTARROWFILL:
109                 message = _("Horizontal Fill (Right Arrow)");
110                 break;
111         case InsetSpaceParams::UPBRACEFILL:
112                 message = _("Horizontal Fill (Up Brace)");
113                 break;
114         case InsetSpaceParams::DOWNBRACEFILL:
115                 message = _("Horizontal Fill (Down Brace)");
116                 break;
117         case InsetSpaceParams::CUSTOM:
118                 message = support::bformat(_("Horizontal Space (%1$s)"),
119                                 params_.length.asDocstring());
120                 break;
121         case InsetSpaceParams::CUSTOM_PROTECTED:
122                 message = support::bformat(_("Protected Horizontal Space (%1$s)"),
123                                 params_.length.asDocstring());
124                 break;
125         }
126         return message;
127 }
128
129
130 void InsetSpace::doDispatch(Cursor & cur, FuncRequest & cmd)
131 {
132         switch (cmd.action) {
133
134         case LFUN_INSET_MODIFY: {
135                 string2params(to_utf8(cmd.argument()), params_);
136                 break;
137         }
138
139         case LFUN_MOUSE_RELEASE:
140                 if (!cur.selection() && cmd.button() == mouse_button::button1)
141                         cur.bv().showDialog("space", params2string(params()), this);
142                 break;
143
144         default:
145                 Inset::doDispatch(cur, cmd);
146                 break;
147         }
148 }
149
150
151 bool InsetSpace::getStatus(Cursor & cur, FuncRequest const & cmd,
152         FuncStatus & status) const
153 {
154         switch (cmd.action) {
155         // we handle these
156         case LFUN_INSET_MODIFY:
157                 if (cmd.getArg(0) == "space") {
158                         InsetSpaceParams params;
159                         string2params(to_utf8(cmd.argument()), params);
160                         status.setOnOff(params_.kind == params.kind);
161                 }
162                 status.setEnabled(true);
163                 return true;
164         default:
165                 return Inset::getStatus(cur, cmd, status);
166         }
167 }
168
169
170 void InsetSpace::edit(Cursor & cur, bool, EntryDirection)
171 {
172         cur.bv().showDialog("space", params2string(params()), this);
173 }
174
175
176 namespace {
177 int const arrow_size = 8;
178 }
179
180
181 void InsetSpace::metrics(MetricsInfo & mi, Dimension & dim) const
182 {
183         if (isStretchableSpace()) {
184                 // The metrics for this kinds are calculated externally in
185                 // \c TextMetrics::computeRowMetrics. Those are dummy value:
186                 dim = Dimension(10, 10, 10);
187                 return;
188         }
189
190         frontend::FontMetrics const & fm = theFontMetrics(mi.base.font);
191         dim.asc = fm.maxAscent();
192         dim.des = fm.maxDescent();
193
194         switch (params_.kind) {
195                 case InsetSpaceParams::THIN:
196                 case InsetSpaceParams::NEGTHIN:
197                         dim.wid = fm.width(char_type('M')) / 6;
198                         break;
199                 case InsetSpaceParams::PROTECTED:
200                 case InsetSpaceParams::NORMAL:
201                         dim.wid = fm.width(char_type(' '));
202                         break;
203                 case InsetSpaceParams::QUAD:
204                         dim.wid = fm.width(char_type('M'));
205                         break;
206                 case InsetSpaceParams::QQUAD:
207                         dim.wid = 2 * fm.width(char_type('M'));
208                         break;
209                 case InsetSpaceParams::ENSPACE:
210                 case InsetSpaceParams::ENSKIP:
211                         dim.wid = int(0.5 * fm.width(char_type('M')));
212                         break;
213                 case InsetSpaceParams::CUSTOM:
214                 case InsetSpaceParams::CUSTOM_PROTECTED: {
215                         int const w = 
216                                 params_.length.inPixels(mi.base.textwidth,
217                                                         fm.width(char_type('M')));
218                         int const minw = (w < 0) ? 3 * arrow_size : 4;
219                         dim.wid = max(minw, abs(w));
220                         break;
221                 }
222                 case InsetSpaceParams::HFILL:
223                 case InsetSpaceParams::HFILL_PROTECTED:
224                 case InsetSpaceParams::DOTFILL:
225                 case InsetSpaceParams::HRULEFILL:
226                 case InsetSpaceParams::LEFTARROWFILL:
227                 case InsetSpaceParams::RIGHTARROWFILL:
228                 case InsetSpaceParams::UPBRACEFILL:
229                 case InsetSpaceParams::DOWNBRACEFILL:
230                         // shut up compiler
231                         break;
232         }
233         // Cache the inset dimension.
234         setDimCache(mi, dim);
235 }
236
237
238 void InsetSpace::draw(PainterInfo & pi, int x, int y) const
239 {
240         Dimension const dim = dimension(*pi.base.bv);
241
242         if (isStretchableSpace() || params_.length.value() < 0) {
243                 int const asc = theFontMetrics(pi.base.font).ascent('M');
244                 int const desc = theFontMetrics(pi.base.font).descent('M');
245                 // Pixel height divisible by 2 for prettier fill graphics:
246                 int const oddheight = (asc ^ desc) & 1;
247                 int const x0 = x + 1;
248                 int const x1 = x + dim.wid - 2;
249                 int const y0 = y + desc - 1;
250                 int const y1 = y - asc + oddheight - 1;
251                 int const y2 = (y0 + y1) / 2;
252                 int xoffset = (y0 - y1) / 2;
253
254                 // Two tests for very narrow insets
255                 if (xoffset > x1 - x0
256                      && (params_.kind == InsetSpaceParams::LEFTARROWFILL
257                          || params_.kind == InsetSpaceParams::RIGHTARROWFILL))
258                                 xoffset = x1 - x0;
259                 if (xoffset * 6 > (x1 - x0)
260                      && (params_.kind == InsetSpaceParams::UPBRACEFILL
261                          || params_.kind == InsetSpaceParams::DOWNBRACEFILL))
262                                 xoffset = (x1 - x0) / 6;
263
264                 int const x2 = x0 + xoffset;
265                 int const x3 = x1 - xoffset;
266                 int const xm = (x0 + x1) / 2;
267                 int const xml = xm - xoffset;
268                 int const xmr = xm + xoffset;
269
270                 if (params_.kind == InsetSpaceParams::HFILL) {
271                         pi.pain.line(x0, y1, x0, y0, Color_added_space);
272                         pi.pain.line(x0, y2 , x1, y2, Color_added_space,
273                                 frontend::Painter::line_onoffdash);
274                         pi.pain.line(x1, y1, x1, y0, Color_added_space);
275                 } else if (params_.kind == InsetSpaceParams::HFILL_PROTECTED) {
276                         pi.pain.line(x0, y1, x0, y0, Color_latex);
277                         pi.pain.line(x0, y2 , x1, y2, Color_latex,
278                                 frontend::Painter::line_onoffdash);
279                         pi.pain.line(x1, y1, x1, y0, Color_latex);
280                 } else if (params_.kind == InsetSpaceParams::DOTFILL) {
281                         pi.pain.line(x0, y1, x0, y0, Color_special);
282                         pi.pain.line(x0, y0, x1, y0, Color_special,
283                                 frontend::Painter::line_onoffdash);
284                         pi.pain.line(x1, y1, x1, y0, Color_special);
285                 } else if (params_.kind == InsetSpaceParams::HRULEFILL) {
286                         pi.pain.line(x0, y1, x0, y0, Color_special);
287                         pi.pain.line(x0, y0, x1, y0, Color_special);
288                         pi.pain.line(x1, y1, x1, y0, Color_special);
289                 } else if (params_.kind == InsetSpaceParams::LEFTARROWFILL) {
290                         pi.pain.line(x2, y1 + 1 , x0 + 1, y2, Color_special);
291                         pi.pain.line(x0 + 1, y2 + 1 , x2, y0, Color_special);
292                         pi.pain.line(x0, y2 , x1, y2, Color_special);
293                 } else if (params_.kind == InsetSpaceParams::RIGHTARROWFILL) {
294                         pi.pain.line(x3 + 1, y1 + 1 , x1, y2, Color_special);
295                         pi.pain.line(x1, y2 + 1 , x3 + 1, y0, Color_special);
296                         pi.pain.line(x0, y2 , x1, y2, Color_special);
297                 } else if (params_.kind == InsetSpaceParams::UPBRACEFILL) {
298                         pi.pain.line(x0 + 1, y1 + 1 , x2, y2, Color_special);
299                         pi.pain.line(x2, y2 , xml, y2, Color_special);
300                         pi.pain.line(xml + 1, y2 + 1 , xm, y0, Color_special);
301                         pi.pain.line(xm + 1, y0 , xmr, y2 + 1, Color_special);
302                         pi.pain.line(xmr, y2 , x3, y2, Color_special);
303                         pi.pain.line(x3 + 1, y2 , x1, y1 + 1, Color_special);
304                 } else if (params_.kind == InsetSpaceParams::DOWNBRACEFILL) {
305                         pi.pain.line(x0 + 1, y0 , x2, y2 + 1, Color_special);
306                         pi.pain.line(x2, y2 , xml, y2, Color_special);
307                         pi.pain.line(xml + 1, y2 , xm, y1 + 1, Color_special);
308                         pi.pain.line(xm + 1, y1 + 1 , xmr, y2, Color_special);
309                         pi.pain.line(xmr, y2 , x3, y2, Color_special);
310                         pi.pain.line(x3 + 1, y2 + 1 , x1, y0, Color_special);
311                 } else if (params_.kind == InsetSpaceParams::CUSTOM) {
312                         pi.pain.line(x0, y1 + 1 , x2 + 1, y2, Color_special);
313                         pi.pain.line(x2 + 1, y2 + 1 , x0, y0, Color_special);
314                         pi.pain.line(x1 + 1, y1 + 1 , x3, y2, Color_special);
315                         pi.pain.line(x3, y2 + 1 , x1 + 1, y0, Color_special);
316                         pi.pain.line(x2, y2 , x3, y2, Color_special);
317                 } else if (params_.kind == InsetSpaceParams::CUSTOM_PROTECTED) {
318                         pi.pain.line(x0, y1 + 1 , x2 + 1, y2, Color_latex);
319                         pi.pain.line(x2 + 1, y2 + 1 , x0, y0, Color_latex);
320                         pi.pain.line(x1 + 1, y1 + 1 , x3, y2, Color_latex);
321                         pi.pain.line(x3, y2 + 1 , x1 + 1, y0, Color_latex);
322                         pi.pain.line(x2, y2 , x3, y2, Color_latex);
323                 }
324                 return;
325         }
326
327         int const w = dim.wid;
328         int const h = theFontMetrics(pi.base.font).ascent('x');
329         int xp[4], yp[4];
330
331         xp[0] = x;
332         yp[0] = y - max(h / 4, 1);
333         if (params_.kind == InsetSpaceParams::NORMAL ||
334             params_.kind == InsetSpaceParams::PROTECTED) {
335                 xp[1] = x;     yp[1] = y;
336                 xp[2] = x + w; yp[2] = y;
337         } else {
338                 xp[1] = x;     yp[1] = y + max(h / 4, 1);
339                 xp[2] = x + w; yp[2] = y + max(h / 4, 1);
340         }
341         xp[3] = x + w;
342         yp[3] = y - max(h / 4, 1);
343
344         if (params_.kind == InsetSpaceParams::PROTECTED ||
345             params_.kind == InsetSpaceParams::ENSPACE ||
346             params_.kind == InsetSpaceParams::NEGTHIN ||
347             params_.kind == InsetSpaceParams::CUSTOM_PROTECTED)
348                 pi.pain.lines(xp, yp, 4, Color_latex);
349         else
350                 pi.pain.lines(xp, yp, 4, Color_special);
351 }
352
353
354 void InsetSpaceParams::write(ostream & os) const
355 {
356         string command;
357         switch (kind) {
358         case InsetSpaceParams::NORMAL:
359                 os << "\\space{}";
360                 break;
361         case InsetSpaceParams::PROTECTED:
362                 os <<  "~";
363                 break;
364         case InsetSpaceParams::THIN:
365                 os <<  "\\thinspace{}";
366                 break;
367         case InsetSpaceParams::QUAD:
368                 os <<  "\\quad{}";
369                 break;
370         case InsetSpaceParams::QQUAD:
371                 os <<  "\\qquad{}";
372                 break;
373         case InsetSpaceParams::ENSPACE:
374                 os <<  "\\enspace{}";
375                 break;
376         case InsetSpaceParams::ENSKIP:
377                 os <<  "\\enskip{}";
378                 break;
379         case InsetSpaceParams::NEGTHIN:
380                 os <<  "\\negthinspace{}";
381                 break;
382         case InsetSpaceParams::HFILL:
383                 os <<  "\\hfill{}";
384                 break;
385         case InsetSpaceParams::HFILL_PROTECTED:
386                 os <<  "\\hspace*{\\fill}";
387                 break;
388         case InsetSpaceParams::DOTFILL:
389                 os <<  "\\dotfill{}";
390                 break;
391         case InsetSpaceParams::HRULEFILL:
392                 os <<  "\\hrulefill{}";
393                 break;
394         case InsetSpaceParams::LEFTARROWFILL:
395                 os <<  "\\leftarrowfill{}";
396                 break;
397         case InsetSpaceParams::RIGHTARROWFILL:
398                 os <<  "\\rightarrowfill{}";
399                 break;
400         case InsetSpaceParams::UPBRACEFILL:
401                 os <<  "\\upbracefill{}";
402                 break;
403         case InsetSpaceParams::DOWNBRACEFILL:
404                 os <<  "\\downbracefill{}";
405                 break;
406         case InsetSpaceParams::CUSTOM:
407                 os <<  "\\hspace{}";
408                 break;
409         case InsetSpaceParams::CUSTOM_PROTECTED:
410                 os <<  "\\hspace*{}";
411                 break;
412         }
413         
414         if (!length.empty())
415                 os << "\n\\length " << length.asString();
416 }
417
418
419 void InsetSpaceParams::read(Lexer & lex)
420 {
421         lex.setContext("InsetSpaceParams::read");
422         string command;
423         lex >> command;
424
425         if (command == "\\space{}")
426                 kind = InsetSpaceParams::NORMAL;
427         else if (command == "~")
428                 kind = InsetSpaceParams::PROTECTED;
429         else if (command == "\\thinspace{}")
430                 kind = InsetSpaceParams::THIN;
431         else if (command == "\\quad{}")
432                 kind = InsetSpaceParams::QUAD;
433         else if (command == "\\qquad{}")
434                 kind = InsetSpaceParams::QQUAD;
435         else if (command == "\\enspace{}")
436                 kind = InsetSpaceParams::ENSPACE;
437         else if (command == "\\enskip{}")
438                 kind = InsetSpaceParams::ENSKIP;
439         else if (command == "\\negthinspace{}")
440                 kind = InsetSpaceParams::NEGTHIN;
441         else if (command == "\\hfill{}")
442                 kind = InsetSpaceParams::HFILL;
443         else if (command == "\\hspace*{\\fill}")
444                 kind = InsetSpaceParams::HFILL_PROTECTED;
445         else if (command == "\\dotfill{}")
446                 kind = InsetSpaceParams::DOTFILL;
447         else if (command == "\\hrulefill{}")
448                 kind = InsetSpaceParams::HRULEFILL;
449         else if (command == "\\hspace{}")
450                 kind = InsetSpaceParams::CUSTOM;
451         else if (command == "\\leftarrowfill{}")
452                 kind = InsetSpaceParams::LEFTARROWFILL;
453         else if (command == "\\rightarrowfill{}")
454                 kind = InsetSpaceParams::RIGHTARROWFILL;
455         else if (command == "\\upbracefill{}")
456                 kind = InsetSpaceParams::UPBRACEFILL;
457         else if (command == "\\downbracefill{}")
458                 kind = InsetSpaceParams::DOWNBRACEFILL;
459         else if (command == "\\hspace*{}")
460                 kind = InsetSpaceParams::CUSTOM_PROTECTED;
461         else
462                 lex.printError("InsetSpace: Unknown kind: `$$Token'");
463
464         if (lex.checkFor("\\length"))
465                 lex >> length;
466 }
467
468
469 void InsetSpace::write(ostream & os) const
470 {
471         os << "space ";
472         params_.write(os);
473 }
474
475
476 void InsetSpace::read(Lexer & lex)
477 {
478         params_.read(lex);
479         lex >> "\\end_inset";
480 }
481
482
483 int InsetSpace::latex(odocstream & os, OutputParams const & runparams) const
484 {
485         switch (params_.kind) {
486         case InsetSpaceParams::NORMAL:
487                 os << (runparams.free_spacing ? " " : "\\ ");
488                 break;
489         case InsetSpaceParams::PROTECTED:
490                 os << (runparams.free_spacing ? ' ' : '~');
491                 break;
492         case InsetSpaceParams::THIN:
493                 os << (runparams.free_spacing ? " " : "\\,");
494                 break;
495         case InsetSpaceParams::QUAD:
496                 os << (runparams.free_spacing ? " " : "\\quad{}");
497                 break;
498         case InsetSpaceParams::QQUAD:
499                 os << (runparams.free_spacing ? " " : "\\qquad{}");
500                 break;
501         case InsetSpaceParams::ENSPACE:
502                 os << (runparams.free_spacing ? " " : "\\enspace{}");
503                 break;
504         case InsetSpaceParams::ENSKIP:
505                 os << (runparams.free_spacing ? " " : "\\enskip{}");
506                 break;
507         case InsetSpaceParams::NEGTHIN:
508                 os << (runparams.free_spacing ? " " : "\\negthinspace{}");
509                 break;
510         case InsetSpaceParams::HFILL:
511                 os << (runparams.free_spacing ? " " : "\\hfill{}");
512                 break;
513         case InsetSpaceParams::HFILL_PROTECTED:
514                 os << (runparams.free_spacing ? " " : "\\hspace*{\\fill}");
515                 break;
516         case InsetSpaceParams::DOTFILL:
517                 os << (runparams.free_spacing ? " " : "\\dotfill{}");
518                 break;
519         case InsetSpaceParams::HRULEFILL:
520                 os << (runparams.free_spacing ? " " : "\\hrulefill{}");
521                 break;
522         case InsetSpaceParams::LEFTARROWFILL:
523                 os << (runparams.free_spacing ? " " : "\\leftarrowfill{}");
524                 break;
525         case InsetSpaceParams::RIGHTARROWFILL:
526                 os << (runparams.free_spacing ? " " : "\\rightarrowfill{}");
527                 break;
528         case InsetSpaceParams::UPBRACEFILL:
529                 os << (runparams.free_spacing ? " " : "\\upbracefill{}");
530                 break;
531         case InsetSpaceParams::DOWNBRACEFILL:
532                 os << (runparams.free_spacing ? " " : "\\downbracefill{}");
533                 break;
534         case InsetSpaceParams::CUSTOM:
535                 if (runparams.free_spacing)
536                         os << " ";
537                 else
538                         os << "\\hspace{" << from_ascii(params_.length.asLatexString()) << "}";
539                 break;
540         case InsetSpaceParams::CUSTOM_PROTECTED:
541                 if (runparams.free_spacing)
542                         os << " ";
543                 else
544                         os << "\\hspace*{" << from_ascii(params_.length.asLatexString()) << "}";
545                 break;
546         }
547         return 0;
548 }
549
550
551 int InsetSpace::plaintext(odocstream & os, OutputParams const &) const
552 {
553         switch (params_.kind) {
554         case InsetSpaceParams::HFILL:
555         case InsetSpaceParams::HFILL_PROTECTED:
556                 os << "     ";
557                 return 5;
558         case InsetSpaceParams::DOTFILL:
559                 os << ".....";
560                 return 5;
561         case InsetSpaceParams::HRULEFILL:
562                 os << "_____";
563                 return 5;
564         case InsetSpaceParams::LEFTARROWFILL:
565                 os << "<----";
566                 return 5;
567         case InsetSpaceParams::RIGHTARROWFILL:
568                 os << "---->";
569                 return 5;
570         case InsetSpaceParams::UPBRACEFILL:
571                 os << "\\-v-/";
572                 return 5;
573         case InsetSpaceParams::DOWNBRACEFILL:
574                 os << "/-^-\\";
575                 return 5;
576         default:
577                 os << ' ';
578                 return 1;
579         }
580 }
581
582
583 int InsetSpace::docbook(odocstream & os, OutputParams const &) const
584 {
585         switch (params_.kind) {
586         case InsetSpaceParams::NORMAL:
587         case InsetSpaceParams::QUAD:
588         case InsetSpaceParams::QQUAD:
589         case InsetSpaceParams::ENSKIP:
590                 os << " ";
591                 break;
592         case InsetSpaceParams::PROTECTED:
593         case InsetSpaceParams::ENSPACE:
594         case InsetSpaceParams::THIN:
595         case InsetSpaceParams::NEGTHIN:
596                 os << "&nbsp;";
597                 break;
598         case InsetSpaceParams::HFILL:
599         case InsetSpaceParams::HFILL_PROTECTED:
600                 os << '\n';
601         case InsetSpaceParams::DOTFILL:
602                 // FIXME
603                 os << '\n';
604         case InsetSpaceParams::HRULEFILL:
605                 // FIXME
606                 os << '\n';
607         case InsetSpaceParams::LEFTARROWFILL:
608         case InsetSpaceParams::RIGHTARROWFILL:
609         case InsetSpaceParams::UPBRACEFILL:
610         case InsetSpaceParams::DOWNBRACEFILL:
611         case InsetSpaceParams::CUSTOM:
612         case InsetSpaceParams::CUSTOM_PROTECTED:
613                 // FIXME
614                 os << '\n';
615         }
616         return 0;
617 }
618
619
620 void InsetSpace::tocString(odocstream & os) const
621 {
622         plaintext(os, OutputParams(0));
623 }
624
625
626 bool InsetSpace::isStretchableSpace() const
627 {
628         return params_.kind == InsetSpaceParams::HFILL
629                 || params_.kind == InsetSpaceParams::HFILL_PROTECTED
630                 || params_.kind == InsetSpaceParams::DOTFILL
631                 || params_.kind == InsetSpaceParams::HRULEFILL
632                 || params_.kind == InsetSpaceParams::LEFTARROWFILL
633                 || params_.kind == InsetSpaceParams::RIGHTARROWFILL
634                 || params_.kind == InsetSpaceParams::UPBRACEFILL
635                 || params_.kind == InsetSpaceParams::DOWNBRACEFILL;
636 }
637
638
639 docstring InsetSpace::contextMenu(BufferView const &, int, int) const
640 {
641         return from_ascii("context-space");
642 }
643
644
645 void InsetSpace::string2params(string const & in, InsetSpaceParams & params)
646 {
647         params = InsetSpaceParams();
648         if (in.empty())
649                 return;
650
651         istringstream data(in);
652         Lexer lex;
653         lex.setStream(data);
654         lex.setContext("InsetSpace::string2params");
655         lex >> "space";
656
657         // There are cases, such as when we are called via getStatus() from
658         // Dialog::canApply(), where we are just called with "space" rather
659         // than a full "space \type{}\n\\end_inset".
660         if (lex.isOK())
661                 params.read(lex);
662 }
663
664
665 string InsetSpace::params2string(InsetSpaceParams const & params)
666 {
667         ostringstream data;
668         data << "space" << ' ';
669         params.write(data);
670         return data.str();
671 }
672
673
674 } // namespace lyx