2 * \file insetcollapsable.C
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Alejandro Aguilar Sierra
8 * \author Lars Gullik Bjønnes
10 * Full author contact details are available in file CREDITS.
15 #include "insetcollapsable.h"
18 #include "BufferView.h"
21 #include "dispatchresult.h"
24 #include "funcrequest.h"
25 #include "metricsinfo.h"
26 #include "paragraph.h"
28 #include "frontends/font_metrics.h"
29 #include "frontends/Painter.h"
30 #include "frontends/LyXView.h"
33 using lyx::graphics::PreviewLoader;
42 InsetCollapsable::InsetCollapsable(BufferParams const & bp,
43 CollapseStatus status)
44 : inset(bp), label("Label"), status_(status)
47 inset.setAutoBreakRows(true);
48 inset.setDrawFrame(InsetText::ALWAYS);
49 inset.setFrameColor(LColor::collapsableframe);
50 setInsetName("Collapsable");
55 InsetCollapsable::InsetCollapsable(InsetCollapsable const & in)
56 : UpdatableInset(in), inset(in.inset),
57 labelfont_(in.labelfont_), label(in.label), status_(in.status_)
64 void InsetCollapsable::write(Buffer const & buf, ostream & os) const
79 os << "status " << st << "\n";
80 inset.text_.write(buf, os);
84 void InsetCollapsable::read(Buffer const & buf, LyXLex & lex)
86 bool token_found = false;
89 string const token = lex.getString();
90 if (token == "status") {
92 string const tmp_token = lex.getString();
94 if (tmp_token == "inlined") {
97 } else if (tmp_token == "collapsed") {
100 } else if (tmp_token == "open") {
104 lyxerr << "InsetCollapsable::read: Missing status!"
106 // Take countermeasures
107 lex.pushToken(token);
110 lyxerr << "InsetCollapsable::Read: Missing 'status'-tag!"
112 // take countermeasures
113 lex.pushToken(token);
116 inset.read(buf, lex);
119 status_ = isOpen() ? Open : Collapsed;
125 void InsetCollapsable::dimension_collapsed(Dimension & dim) const
127 font_metrics::buttonText(label, labelfont_, dim.wid, dim.asc, dim.des);
131 int InsetCollapsable::height_collapsed() const
134 font_metrics::buttonText(label, labelfont_, dim.wid, dim.asc, dim.des);
135 return dim.asc + dim.des;
139 void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const
141 //lyxerr << "InsetCollapsable::metrics: width: " << mi.base.textwidth << endl;
142 if (status_ == Inlined) {
143 inset.metrics(mi, dim);
145 dimension_collapsed(dim);
146 if (status_ == Open) {
148 inset.metrics(mi, insetdim);
149 dim.des += insetdim.height() + TEXT_TO_BOTTOM_OFFSET;
150 dim.wid = max(dim.wid, insetdim.wid);
154 //lyxerr << "InsetCollapsable::metrics: dim.wid: " << dim.wid << endl;
158 void InsetCollapsable::draw_collapsed(PainterInfo & pi, int x, int y) const
160 pi.pain.buttonText(x, y, label, labelfont_);
164 void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const
166 setPosCache(pi, x, y);
168 if (status_ == Inlined) {
169 inset.draw(pi, x, y);
172 dimension_collapsed(dimc);
174 int const aa = ascent();
176 button_dim.x2 = dimc.width();
178 button_dim.y2 = -aa + dimc.height();
180 draw_collapsed(pi, x, y);
181 if (status_ == Open) {
184 inset.draw(pi, x, y - aa + dimc.height() + inset.ascent());
190 InsetOld::EDITABLE InsetCollapsable::editable() const
192 return status_ != Collapsed ? HIGHLY_EDITABLE : IS_EDITABLE;
196 bool InsetCollapsable::descendable() const
198 return status_ != Collapsed;
203 InsetCollapsable::lfunMouseRelease(LCursor & cur, FuncRequest const & cmd)
205 if (cmd.button() == mouse_button::button3) {
206 lyxerr << "InsetCollapsable::lfunMouseRelease 0" << endl;
207 showInsetDialog(&cur.bv());
208 return DispatchResult(true, true);
213 lyxerr << "InsetCollapsable::lfunMouseRelease 1" << endl;
216 return DispatchResult(true, true);
219 if (hitButton(cmd)) {
220 lyxerr << "InsetCollapsable::lfunMouseRelease 2" << endl;
221 setStatus(Collapsed);
222 return DispatchResult(false, FINISHED_RIGHT);
224 lyxerr << "InsetCollapsable::lfunMouseRelease 3" << endl;
225 return inset.dispatch(cur, cmd);
228 return inset.dispatch(cur, cmd);
231 return DispatchResult(true, true);
235 int InsetCollapsable::latex(Buffer const & buf, ostream & os,
236 OutputParams const & runparams) const
238 return inset.latex(buf, os, runparams);
242 int InsetCollapsable::plaintext(Buffer const & buf, ostream & os,
243 OutputParams const & runparams) const
245 return inset.plaintext(buf, os, runparams);
249 int InsetCollapsable::linuxdoc(Buffer const & buf, ostream & os,
250 OutputParams const & runparams) const
252 return inset.linuxdoc(buf, os, runparams);
256 int InsetCollapsable::docbook(Buffer const & buf, ostream & os,
257 OutputParams const & runparams) const
259 return inset.docbook(buf, os, runparams);
263 bool InsetCollapsable::hitButton(FuncRequest const & cmd) const
265 return button_dim.contains(cmd.x, cmd.y);
269 string const InsetCollapsable::getNewLabel(string const & l) const
272 pos_type const max_length = 15;
273 pos_type const p_siz = inset.paragraphs().begin()->size();
274 pos_type const n = min(max_length, p_siz);
277 for( ; i < n && j < p_siz; ++j) {
278 if (inset.paragraphs().begin()->isInset(j))
280 la += inset.paragraphs().begin()->getChar(j);
283 if (inset.paragraphs().size() > 1 || (i > 0 && j < p_siz)) {
286 return la.empty() ? l : la;
290 void InsetCollapsable::edit(LCursor & cur, bool left)
292 //lyxerr << "InsetCollapsable: edit left/right" << endl;
294 inset.edit(cur, left);
299 void InsetCollapsable::edit(LCursor & cur, int x, int y)
302 //lyxerr << "InsetCollapsable: edit xy" << endl;
303 if (status_ == Collapsed) {
306 if (y <= button_dim.y2)
309 y += inset.ascent() - height_collapsed();
311 inset.edit(cur, x, y);
316 InsetCollapsable::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
318 lyxerr << "\nInsetCollapsable::priv_dispatch (begin): cmd: " << cmd
319 << " button y: " << button_dim.y2 << endl;
320 switch (cmd.action) {
321 case LFUN_MOUSE_PRESS:
322 if (status_ == Inlined)
323 inset.dispatch(cur, cmd);
324 else if (status_ == Open && cmd.y > button_dim.y2)
325 inset.dispatch(cur, cmd);
326 return DispatchResult(true, true);
328 case LFUN_MOUSE_MOTION:
329 if (status_ == Inlined)
330 inset.dispatch(cur, cmd);
331 else if (status_ == Open && cmd.y > button_dim.y2)
332 inset.dispatch(cur, cmd);
333 return DispatchResult(true, true);
335 case LFUN_MOUSE_RELEASE:
336 return lfunMouseRelease(cur, cmd);
338 case LFUN_INSET_TOGGLE:
339 if (inset.text_.toggleInset())
340 return DispatchResult(true, true);
341 if (status_ == Open) {
343 return DispatchResult(true, true);
345 setStatus(Collapsed);
346 return DispatchResult(false, FINISHED_RIGHT);
350 return inset.dispatch(cur, cmd);
355 void InsetCollapsable::validate(LaTeXFeatures & features) const
357 inset.validate(features);
361 void InsetCollapsable::getCursorPos(CursorSlice const & cur,
362 int & x, int & y) const
364 inset.getCursorPos(cur, x, y);
368 void InsetCollapsable::getLabelList(Buffer const & buffer,
369 std::vector<string> & list) const
371 inset.getLabelList(buffer, list);
375 int InsetCollapsable::scroll(bool recursive) const
377 int sx = UpdatableInset::scroll(false);
380 sx += inset.scroll(false);
386 int InsetCollapsable::numParagraphs() const
388 return inset.numParagraphs();
392 LyXText * InsetCollapsable::getText(int i) const
394 return inset.getText(i);
398 void InsetCollapsable::open()
400 if (status_ == Collapsed) // ...but not inlined
405 void InsetCollapsable::close()
407 setStatus(Collapsed);
411 void InsetCollapsable::setLabel(string const & l)
417 void InsetCollapsable::setStatus(CollapseStatus st)
424 void InsetCollapsable::markErased()
430 void InsetCollapsable::addPreview(PreviewLoader & loader) const
432 inset.addPreview(loader);
436 bool InsetCollapsable::insetAllowed(InsetOld::Code code) const
438 return inset.insetAllowed(code);
442 void InsetCollapsable::setLabelFont(LyXFont & font)
448 void InsetCollapsable::scroll(BufferView & bv, float sx) const
450 UpdatableInset::scroll(bv, sx);
454 void InsetCollapsable::scroll(BufferView & bv, int offset) const
456 UpdatableInset::scroll(bv, offset);
460 Box const & InsetCollapsable::buttonDim() const
466 void InsetCollapsable::setBackgroundColor(LColor_color color)
468 InsetOld::setBackgroundColor(color);
469 inset.setBackgroundColor(color);