]> git.lyx.org Git - lyx.git/blob - src/insets/InsetPreview.cpp
Fix external middle-mouse pasting with Qt5/X11.
[lyx.git] / src / insets / InsetPreview.cpp
1 /**
2  * \file InsetPreview.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Vincent van Ravesteijn
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10 #include "config.h"
11
12 #include "InsetPreview.h"
13
14 #include "Buffer.h"
15 #include "BufferParams.h"
16 #include "BufferView.h"
17 #include "Cursor.h"
18 #include "Lexer.h"
19 #include "MetricsInfo.h"
20 #include "OutputParams.h"
21 #include "RenderPreview.h"
22
23 #include "frontends/Painter.h"
24
25 #include "graphics/PreviewImage.h"
26
27 #include <sstream>
28
29 using namespace std;
30
31 namespace lyx {
32
33
34 InsetPreview::InsetPreview(Buffer * buf) 
35         : InsetText(buf),
36           preview_(new RenderPreview(this)), use_preview_(true)
37 {
38         setDrawFrame(true);
39         setFrameColor(Color_previewframe);
40 }
41
42
43 InsetPreview::~InsetPreview() 
44 {}
45
46
47 InsetPreview::InsetPreview(InsetPreview const & other)
48         : InsetText(other)
49 {
50         preview_.reset(new RenderPreview(*other.preview_, this));
51 }
52
53
54 void InsetPreview::write(ostream & os) const
55 {
56         os << "Preview" << "\n";
57         text().write(os);
58 }
59
60
61 void InsetPreview::addPreview(DocIterator const & inset_pos,
62         graphics::PreviewLoader &) const
63 {
64         preparePreview(inset_pos);
65 }
66
67
68 void InsetPreview::preparePreview(DocIterator const & pos) const  
69 {
70         TexRow texrow;
71         odocstringstream str;  
72         otexstream os(str, texrow);
73         OutputParams runparams(&pos.buffer()->params().encoding());
74         latex(os, runparams);
75         docstring const snippet = str.str();
76         preview_->addPreview(snippet, *pos.buffer());  
77 }
78
79
80 bool InsetPreview::previewState(BufferView * bv) const
81 {
82         if (!editing(bv) && RenderPreview::previewText()) {
83                 graphics::PreviewImage const * pimage =
84                         preview_->getPreviewImage(bv->buffer());
85                 return pimage && pimage->image();
86         }
87         return false;
88 }
89
90
91 void InsetPreview::reloadPreview(DocIterator const & pos) const
92 {
93         preparePreview(pos);
94         preview_->startLoading(*pos.buffer());
95 }
96
97
98 void InsetPreview::draw(PainterInfo & pi, int x, int y) const
99 {
100         use_preview_ = previewState(pi.base.bv);
101
102         if (use_preview_) {
103                 // one pixel gap in front
104                 preview_->draw(pi, x + 1 + TEXT_TO_INSET_OFFSET, y);
105                 setPosCache(pi, x, y);
106                 return;
107         }
108         InsetText::draw(pi, x, y);
109 }
110
111
112 void InsetPreview::edit(Cursor & cur, bool front, EntryDirection entry_from)
113 {
114         cur.push(*this);
115         InsetText::edit(cur, front, entry_from);
116 }
117
118
119 Inset * InsetPreview::editXY(Cursor & cur, int x, int y)
120 {
121         if (use_preview_) {
122                 edit(cur, true, ENTRY_DIRECTION_IGNORE);
123                 return this;
124         }
125         cur.push(*this);
126         return InsetText::editXY(cur, x, y);
127 }
128
129
130 void InsetPreview::metrics(MetricsInfo & mi, Dimension & dim) const
131 {
132         if (previewState(mi.base.bv)) {
133                 preview_->metrics(mi, dim);
134                 mi.base.textwidth += 2 * TEXT_TO_INSET_OFFSET;
135                 
136                 dim.wid = max(dim.wid, 4);
137                 dim.asc = max(dim.asc, 4);
138                 
139                 dim.asc += TEXT_TO_INSET_OFFSET;
140                 dim.des += TEXT_TO_INSET_OFFSET;
141                 dim.wid += TEXT_TO_INSET_OFFSET;
142                 dim_ = dim;
143                 dim.wid += TEXT_TO_INSET_OFFSET;
144                 // insert a one pixel gap
145                 dim.wid += 1;
146                 // Cache the inset dimension.
147                 setDimCache(mi, dim);
148                 Dimension dim_dummy;
149                 MetricsInfo mi_dummy = mi;
150                 InsetText::metrics(mi_dummy, dim_dummy);
151                 return;
152         }
153         InsetText::metrics(mi, dim);
154 }
155
156
157 bool InsetPreview::notifyCursorLeaves(Cursor const & old, Cursor & cur)
158 {
159         reloadPreview(old);
160         cur.screenUpdateFlags(Update::Force);
161         return InsetText::notifyCursorLeaves(old, cur);
162 }
163
164
165 } // namespace lyx