]> git.lyx.org Git - lyx.git/blob - src/insets/InsetBranch.cpp
Fix text frame drawing.
[lyx.git] / src / insets / InsetBranch.cpp
1 /**
2  * \file InsetBranch.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Martin Vermeer
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "InsetBranch.h"
14
15 #include "Buffer.h"
16 #include "BufferParams.h"
17 #include "BranchList.h"
18 #include "Counters.h"
19 #include "Cursor.h"
20 #include "DispatchResult.h"
21 #include "FuncRequest.h"
22 #include "FuncStatus.h"
23 #include "gettext.h"
24 #include "Color.h"
25 #include "Lexer.h"
26 #include "OutputParams.h"
27
28 #include <sstream>
29
30
31 namespace lyx {
32
33 using std::string;
34 using std::istringstream;
35 using std::ostream;
36 using std::ostringstream;
37
38
39 void InsetBranch::init()
40 {
41         setButtonLabel();
42 }
43
44
45 InsetBranch::InsetBranch(BufferParams const & bp,
46                          InsetBranchParams const & params)
47         : InsetCollapsable(bp), params_(params)
48 {
49         setLayout(bp);
50         init();
51 }
52
53
54 InsetBranch::InsetBranch(InsetBranch const & in)
55         : InsetCollapsable(in), params_(in.params_)
56 {
57         init();
58 }
59
60
61 InsetBranch::~InsetBranch()
62 {
63         InsetBranchMailer(*this).hideDialog();
64 }
65
66
67 Inset * InsetBranch::clone() const
68 {
69         return new InsetBranch(*this);
70 }
71
72
73 docstring const InsetBranch::editMessage() const
74 {
75         return _("Opened Branch Inset");
76 }
77
78
79 void InsetBranch::write(Buffer const & buf, ostream & os) const
80 {
81         params_.write(os);
82         InsetCollapsable::write(buf, os);
83 }
84
85
86 void InsetBranch::read(Buffer const & buf, Lexer & lex)
87 {
88         params_.read(lex);
89         InsetCollapsable::read(buf, lex);
90         setLayout(buf.params());
91         setButtonLabel();
92 }
93
94
95 void InsetBranch::setButtonLabel()
96 {
97         docstring s = _("Branch: ") + params_.branch;
98         if (!params_.branch.empty()) {
99                 // FIXME UNICODE
100                 Color_color c = lcolor.getFromLyXName(to_utf8(params_.branch));
101                 if (c == Color::none) {
102                         s = _("Undef: ") + s;
103                 }
104         }
105         if (decoration() == Classic)
106                 setLabel(isOpen() ? s : getNewLabel(s) );
107         else
108                 setLabel(params_.branch + ": " + getNewLabel(s));
109 }
110
111
112 Color_color InsetBranch::backgroundColor() const
113 {
114         if (!params_.branch.empty()) {
115                 // FIXME UNICODE
116                 Color_color c = lcolor.getFromLyXName(to_utf8(params_.branch));
117                 if (c == Color::none) {
118                         c = Color::error;
119                 }
120                 return c;
121         } else
122                 return Inset::backgroundColor();
123 }
124
125
126 bool InsetBranch::showInsetDialog(BufferView * bv) const
127 {
128         InsetBranchMailer(const_cast<InsetBranch &>(*this)).showDialog(bv);
129         return true;
130 }
131
132
133 void InsetBranch::doDispatch(Cursor & cur, FuncRequest & cmd)
134 {
135         switch (cmd.action) {
136         case LFUN_INSET_MODIFY: {
137                 InsetBranchParams params;
138                 InsetBranchMailer::string2params(to_utf8(cmd.argument()), params);
139                 params_.branch = params.branch;
140                 setLayout(cur.buffer().params());
141                 setButtonLabel();
142                 break;
143         }
144
145         case LFUN_MOUSE_PRESS:
146                 if (cmd.button() != mouse_button::button3)
147                         InsetCollapsable::doDispatch(cur, cmd);
148                 else
149                         cur.undispatched();
150                 break;
151
152         case LFUN_INSET_DIALOG_UPDATE:
153                 InsetBranchMailer(*this).updateDialog(&cur.bv());
154                 break;
155
156         case LFUN_MOUSE_RELEASE:
157                 if (cmd.button() == mouse_button::button3 && hitButton(cmd))
158                         InsetBranchMailer(*this).showDialog(&cur.bv());
159                 else
160                         InsetCollapsable::doDispatch(cur, cmd);
161                 break;
162
163
164         case LFUN_INSET_TOGGLE:
165                 if (cmd.argument() == "assign") {
166                         // The branch inset uses "assign".
167                         if (isBranchSelected(cur.buffer())) {
168                                 if (status() != Open)
169                                         setStatus(cur, Open);
170                                 else
171                                         cur.undispatched();
172                         } else {
173                                 if (status() != Collapsed)
174                                         setStatus(cur, Collapsed);
175                                 else
176                                         cur.undispatched();
177                         }
178                 }
179                 else
180                         InsetCollapsable::doDispatch(cur, cmd);
181                 break;
182
183         default:
184                 InsetCollapsable::doDispatch(cur, cmd);
185                 break;
186         }
187 }
188
189
190 bool InsetBranch::getStatus(Cursor & cur, FuncRequest const & cmd,
191                 FuncStatus & flag) const
192 {
193         switch (cmd.action) {
194         case LFUN_INSET_MODIFY:
195         case LFUN_INSET_DIALOG_UPDATE:
196                 flag.enabled(true);
197                 break;
198
199         case LFUN_INSET_TOGGLE:
200                 if (cmd.argument() == "open" || cmd.argument() == "close" ||
201                     cmd.argument() == "toggle")
202                         flag.enabled(true);
203                 else if (cmd.argument() == "assign"
204                            || cmd.argument().empty()) {
205                         if (isBranchSelected(cur.buffer()))
206                                 flag.enabled(status() != Open);
207                         else
208                                 flag.enabled(status() != Collapsed);
209                 } else
210                         flag.enabled(true);
211                 break;
212
213         default:
214                 return InsetCollapsable::getStatus(cur, cmd, flag);
215         }
216         return true;
217 }
218
219
220 bool InsetBranch::isBranchSelected(Buffer const & buffer) const
221 {
222         Buffer const & realbuffer = *buffer.getMasterBuffer();
223         BranchList const & branchlist = realbuffer.params().branchlist();
224         BranchList::const_iterator const end = branchlist.end();
225         BranchList::const_iterator it =
226                 std::find_if(branchlist.begin(), end,
227                              BranchNamesEqual(params_.branch));
228         if (it == end)
229                 return false;
230         return it->getSelected();
231 }
232
233
234 void InsetBranch::updateLabels(Buffer const & buf, ParIterator const & it)
235 {
236         if (isBranchSelected(buf))
237                 InsetCollapsable::updateLabels(buf, it);
238         else {
239                 TextClass const & tclass = buf.params().getTextClass();
240                 Counters savecnt = tclass.counters();
241                 InsetCollapsable::updateLabels(buf, it);
242                 tclass.counters() = savecnt;
243         }
244 }
245
246
247 int InsetBranch::latex(Buffer const & buf, odocstream & os,
248                        OutputParams const & runparams) const
249 {
250         return isBranchSelected(buf) ?
251                 InsetText::latex(buf, os, runparams) : 0;
252 }
253
254
255 int InsetBranch::plaintext(Buffer const & buf, odocstream & os,
256                            OutputParams const & runparams) const
257 {
258         if (!isBranchSelected(buf))
259                 return 0;
260
261         os << '[' << buf.B_("branch") << ' ' << params_.branch << ":\n";
262         InsetText::plaintext(buf, os, runparams);
263         os << "\n]";
264
265         return PLAINTEXT_NEWLINE + 1; // one char on a separate line
266 }
267
268
269 int InsetBranch::docbook(Buffer const & buf, odocstream & os,
270                          OutputParams const & runparams) const
271 {
272         return isBranchSelected(buf) ?
273                 InsetText::docbook(buf, os, runparams) : 0;
274 }
275
276
277 void InsetBranch::textString(Buffer const & buf, odocstream & os) const
278 {
279         if (isBranchSelected(buf))
280                 os << paragraphs().begin()->asString(buf, true);
281 }
282
283
284 void InsetBranch::validate(LaTeXFeatures & features) const
285 {
286         InsetText::validate(features);
287 }
288
289
290
291 string const InsetBranchMailer::name_("branch");
292
293 InsetBranchMailer::InsetBranchMailer(InsetBranch & inset)
294         : inset_(inset)
295 {}
296
297
298 string const InsetBranchMailer::inset2string(Buffer const &) const
299 {
300         return params2string(inset_.params());
301 }
302
303
304 string const InsetBranchMailer::params2string(InsetBranchParams const & params)
305 {
306         ostringstream data;
307         data << name_ << ' ';
308         params.write(data);
309         return data.str();
310 }
311
312
313 void InsetBranchMailer::string2params(string const & in,
314                                       InsetBranchParams & params)
315 {
316         params = InsetBranchParams();
317         if (in.empty())
318                 return;
319
320         istringstream data(in);
321         Lexer lex(0,0);
322         lex.setStream(data);
323
324         string name;
325         lex >> name;
326         if (name != name_)
327                 return print_mailer_error("InsetBranchMailer", in, 1, name_);
328
329         // This is part of the inset proper that is usually swallowed
330         // by Text::readInset
331         string id;
332         lex >> id;
333         if (!lex || id != "Branch")
334                 return print_mailer_error("InsetBranchMailer", in, 2, "Branch");
335
336         params.read(lex);
337 }
338
339
340 void InsetBranchParams::write(ostream & os) const
341 {
342         os << "Branch " << to_utf8(branch) << '\n';
343 }
344
345
346 void InsetBranchParams::read(Lexer & lex)
347 {
348         lex >> branch;
349 }
350
351 } // namespace lyx