]> git.lyx.org Git - lyx.git/blob - src/insets/InsetCommand.cpp
pimpl not needed here
[lyx.git] / src / insets / InsetCommand.cpp
1 /**
2  * \file InsetCommand.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Angus Leeming
7  * \author Lars Gullik Bjønnes
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "InsetCommand.h"
15
16 #include "Buffer.h"
17 #include "BufferView.h"
18 #include "DispatchResult.h"
19 #include "FuncRequest.h"
20 #include "FuncStatus.h"
21 #include "gettext.h"
22 #include "Lexer.h"
23 #include "MetricsInfo.h"
24
25 #include <sstream>
26
27
28 namespace lyx {
29
30 using std::string;
31 using std::istringstream;
32 using std::ostringstream;
33
34
35 // FIXME Would it now be possible to use the InsetCode in 
36 // place of the mailer name and recover that information?
37 InsetCommand::InsetCommand(InsetCommandParams const & p,
38                            string const & mailer_name)
39         : p_(p),
40           mailer_name_(mailer_name),
41           mouse_hover_(false),
42           updateButtonLabel_(true)
43 {}
44
45
46 InsetCommand::~InsetCommand()
47 {
48         if (!mailer_name_.empty())
49                 InsetCommandMailer(mailer_name_, *this).hideDialog();
50 }
51
52
53 void InsetCommand::metrics(MetricsInfo & mi, Dimension & dim) const
54 {
55         if (updateButtonLabel_) {
56                 updateButtonLabel_ = false;
57                 button_.update(getScreenLabel(mi.base.bv->buffer()),
58                                editable() != NOT_EDITABLE);
59         }
60         button_.metrics(mi, dim);
61 }
62
63
64 bool InsetCommand::setMouseHover(bool mouse_hover)
65 {
66         mouse_hover_ = mouse_hover;
67         return true;
68 }
69
70
71 void InsetCommand::draw(PainterInfo & pi, int x, int y) const
72 {
73         button_.setRenderState(mouse_hover_);
74         button_.draw(pi, x, y);
75 }
76
77
78 void InsetCommand::setParams(InsetCommandParams const & p)
79 {
80         p_ = p;
81         updateButtonLabel_ = true;
82 }
83
84
85 int InsetCommand::latex(Buffer const &, odocstream & os,
86                         OutputParams const &) const
87 {
88         os << getCommand();
89         return 0;
90 }
91
92
93 int InsetCommand::plaintext(Buffer const & buf, odocstream & os,
94                             OutputParams const &) const
95 {
96         docstring const str = "[" + buf.B_("LaTeX Command: ") + from_utf8(getCmdName()) + "]";
97         os << str;
98         return str.size();
99 }
100
101
102 int InsetCommand::docbook(Buffer const &, odocstream &,
103                           OutputParams const &) const
104 {
105         return 0;
106 }
107
108
109 void InsetCommand::doDispatch(Cursor & cur, FuncRequest & cmd)
110 {
111         switch (cmd.action) {
112         case LFUN_INSET_REFRESH:
113                 updateButtonLabel_ = true;
114                 break;
115
116         case LFUN_INSET_MODIFY: {
117                 InsetCommandParams p(p_.code());
118                 InsetCommandMailer::string2params(mailer_name_, to_utf8(cmd.argument()), p);
119                 if (p.getCmdName().empty())
120                         cur.noUpdate();
121                 else
122                         setParams(p);
123                 break;
124         }
125
126         case LFUN_INSET_DIALOG_UPDATE: {
127                 string const name = to_utf8(cmd.argument());
128                 InsetCommandMailer(name, *this).updateDialog(&cur.bv());
129                 break;
130         }
131
132         case LFUN_MOUSE_RELEASE: {
133                 if (!cur.selection())
134                         edit(cur, true);
135                 break;
136         }
137
138         default:
139                 Inset::doDispatch(cur, cmd);
140                 break;
141         }
142
143 }
144
145
146 bool InsetCommand::getStatus(Cursor & cur, FuncRequest const & cmd,
147         FuncStatus & status) const
148 {
149         switch (cmd.action) {
150         // suppress these
151         case LFUN_ERT_INSERT:
152                 status.enabled(false);
153                 return true;
154         // we handle these
155         case LFUN_INSET_REFRESH:
156         case LFUN_INSET_MODIFY:
157         case LFUN_INSET_DIALOG_UPDATE:
158                 status.enabled(true);
159                 return true;
160         default:
161                 return Inset::getStatus(cur, cmd, status);
162         }
163 }
164
165
166 void InsetCommand::edit(Cursor & cur, bool)
167 {
168         if (!mailer_name_.empty())
169                 InsetCommandMailer(mailer_name_, *this).showDialog(&cur.bv());
170 }
171
172
173 InsetCommandMailer::InsetCommandMailer(
174         string const & name, InsetCommand & inset)
175         : name_(name), inset_(inset)
176 {}
177
178
179 string const InsetCommandMailer::inset2string(Buffer const &) const
180 {
181         return params2string(name(), inset_.params());
182 }
183
184
185 //FIXME This could take an InsetCode instead of a string
186 bool InsetCommandMailer::string2params(
187         string const & name, string const & in, InsetCommandParams & params)
188 {
189         params.clear();
190         if (in.empty())
191                 return false;
192
193         istringstream data(in);
194         Lexer lex(0,0);
195         lex.setStream(data);
196
197         string n;
198         lex >> n;
199         if (!lex || n != name) {
200                 print_mailer_error("InsetCommandMailer", in, 1, name);
201                 return false;
202         }
203
204         // This is part of the inset proper that is usually swallowed
205         // by Text::readInset
206         string id;
207         lex >> id;
208         if (!lex || id != "CommandInset") {
209                 print_mailer_error("InsetCommandMailer", in, 2, "LatexCommand");
210                 return false;
211         }
212
213         params.read(lex);
214         return true;
215 }
216
217
218 //FIXME This could take an InsetCode instead of a string
219 string const
220 InsetCommandMailer::params2string(string const & name,
221                                   InsetCommandParams const & params)
222 {
223         ostringstream data;
224         data << name << ' ';
225         params.write(data);
226         data << "\\end_inset\n";
227         return data.str();
228 }
229
230
231 } // namespace lyx