]> git.lyx.org Git - lyx.git/blob - src/insets/InsetBranch.cpp
* Text3.cpp (doDispatch): fix the behaviour of word-delete-forward,
[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 "Cursor.h"
19 #include "DispatchResult.h"
20 #include "FuncRequest.h"
21 #include "FuncStatus.h"
22 #include "gettext.h"
23 #include "Color.h"
24 #include "Lexer.h"
25 #include "OutputParams.h"
26
27 #include <sstream>
28
29
30 namespace lyx {
31
32 using std::string;
33 using std::auto_ptr;
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         init();
50 }
51
52
53 InsetBranch::InsetBranch(InsetBranch const & in)
54         : InsetCollapsable(in), params_(in.params_)
55 {
56         init();
57 }
58
59
60 InsetBranch::~InsetBranch()
61 {
62         InsetBranchMailer(*this).hideDialog();
63 }
64
65
66 auto_ptr<Inset> InsetBranch::doClone() const
67 {
68         return auto_ptr<Inset>(new InsetBranch(*this));
69 }
70
71
72 docstring const InsetBranch::editMessage() const
73 {
74         return _("Opened Branch Inset");
75 }
76
77
78 void InsetBranch::write(Buffer const & buf, ostream & os) const
79 {
80         params_.write(os);
81         InsetCollapsable::write(buf, os);
82 }
83
84
85 void InsetBranch::read(Buffer const & buf, Lexer & lex)
86 {
87         params_.read(lex);
88         InsetCollapsable::read(buf, lex);
89         setButtonLabel();
90 }
91
92
93 void InsetBranch::setButtonLabel()
94 {
95         Font font(Font::ALL_SANE);
96         font.decSize();
97         font.decSize();
98
99         docstring s = _("Branch: ") + params_.branch;
100         if (!params_.branch.empty()) {
101                 // FIXME UNICODE
102                 Color_color c = lcolor.getFromLyXName(to_utf8(params_.branch));
103                 if (c == Color::none) {
104                         s = _("Undef: ") + s;
105                 }
106         }
107         font.setColor(Color::foreground);
108         setLabel(isOpen() ? s : getNewLabel(s) );
109         setLabelFont(font);
110 }
111
112
113 Color_color InsetBranch::backgroundColor() const
114 {
115         if (!params_.branch.empty()) {
116                 // FIXME UNICODE
117                 Color_color c = lcolor.getFromLyXName(to_utf8(params_.branch));
118                 if (c == Color::none) {
119                         c = Color::error;
120                 }
121                 return c;
122         } else
123                 return Inset::backgroundColor();
124 }
125
126
127 bool InsetBranch::showInsetDialog(BufferView * bv) const
128 {
129         InsetBranchMailer(const_cast<InsetBranch &>(*this)).showDialog(bv);
130         return true;
131 }
132
133
134 void InsetBranch::doDispatch(Cursor & cur, FuncRequest & cmd)
135 {
136         switch (cmd.action) {
137         case LFUN_INSET_MODIFY: {
138                 InsetBranchParams params;
139                 InsetBranchMailer::string2params(to_utf8(cmd.argument()), params);
140                 params_.branch = params.branch;
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 int InsetBranch::latex(Buffer const & buf, odocstream & os,
235                        OutputParams const & runparams) const
236 {
237         return isBranchSelected(buf) ?
238                 InsetText::latex(buf, os, runparams) : 0;
239 }
240
241
242 int InsetBranch::plaintext(Buffer const & buf, odocstream & os,
243                            OutputParams const & runparams) const
244 {
245         if (!isBranchSelected(buf))
246                 return 0;
247
248         os << '[' << buf.B_("branch") << ' ' << params_.branch << ":\n";
249         InsetText::plaintext(buf, os, runparams);
250         os << "\n]";
251
252         return PLAINTEXT_NEWLINE + 1; // one char on a separate line
253 }
254
255
256 int InsetBranch::docbook(Buffer const & buf, odocstream & os,
257                          OutputParams const & runparams) const
258 {
259         return isBranchSelected(buf) ?
260                 InsetText::docbook(buf, os, runparams) : 0;
261 }
262
263
264 void InsetBranch::textString(Buffer const & buf, odocstream & os) const
265 {
266         if (isBranchSelected(buf))
267                 os << paragraphs().begin()->asString(buf, true);
268 }
269
270
271 void InsetBranch::validate(LaTeXFeatures & features) const
272 {
273         InsetText::validate(features);
274 }
275
276
277
278 string const InsetBranchMailer::name_("branch");
279
280 InsetBranchMailer::InsetBranchMailer(InsetBranch & inset)
281         : inset_(inset)
282 {}
283
284
285 string const InsetBranchMailer::inset2string(Buffer const &) const
286 {
287         return params2string(inset_.params());
288 }
289
290
291 string const InsetBranchMailer::params2string(InsetBranchParams const & params)
292 {
293         ostringstream data;
294         data << name_ << ' ';
295         params.write(data);
296         return data.str();
297 }
298
299
300 void InsetBranchMailer::string2params(string const & in,
301                                       InsetBranchParams & params)
302 {
303         params = InsetBranchParams();
304         if (in.empty())
305                 return;
306
307         istringstream data(in);
308         Lexer lex(0,0);
309         lex.setStream(data);
310
311         string name;
312         lex >> name;
313         if (name != name_)
314                 return print_mailer_error("InsetBranchMailer", in, 1, name_);
315
316         // This is part of the inset proper that is usually swallowed
317         // by Text::readInset
318         string id;
319         lex >> id;
320         if (!lex || id != "Branch")
321                 return print_mailer_error("InsetBranchMailer", in, 2, "Branch");
322
323         params.read(lex);
324 }
325
326
327 void InsetBranchParams::write(ostream & os) const
328 {
329         os << "Branch " << to_utf8(branch) << '\n';
330 }
331
332
333 void InsetBranchParams::read(Lexer & lex)
334 {
335         lex >> branch;
336 }
337
338 } // namespace lyx