]> git.lyx.org Git - lyx.git/blob - src/frontends/LyXView.C
This commit transfer the ErrorList handling from LyXView to Buffer. It also removes...
[lyx.git] / src / frontends / LyXView.C
1 /**
2  * \file LyXView.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars Gullik Bjønnes
7  * \author John Levon
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "LyXView.h"
15 #include "Gui.h"
16 #include "Dialogs.h"
17 #include "Timeout.h"
18 #include "Toolbars.h"
19 #include "Menubar.h"
20 #include "WorkArea.h"
21
22 #include "buffer.h"
23 #include "bufferparams.h"
24 #include "BufferView.h"
25 #include "bufferview_funcs.h"
26 #include "cursor.h"
27 #include "debug.h"
28 #include "funcrequest.h"
29 #include "gettext.h"
30 #include "intl.h"
31 #include "lyx_cb.h"
32 #include "lyxfunc.h"
33 #include "lyxrc.h"
34 #include "lyxtext.h"
35 #include "MenuBackend.h"
36 #include "paragraph.h"
37
38 #include "controllers/ControlCommandBuffer.h"
39
40 #include "support/lstrings.h"
41 #include "support/filetools.h" // OnlyFilename()
42
43 #include <boost/bind.hpp>
44
45 #ifdef HAVE_SYS_TIME_H
46 # include <sys/time.h>
47 #endif
48 #ifdef HAVE_UNISTD_H
49 # include <unistd.h>
50 #endif
51
52 using lyx::frontend::Gui;
53 using lyx::frontend::WorkArea;
54
55 using lyx::support::bformat;
56 using lyx::support::makeDisplayPath;
57 using lyx::support::onlyFilename;
58
59 using std::endl;
60 using std::string;
61
62 using lyx::frontend::ControlCommandBuffer;
63
64 string current_layout;
65
66 Gui & LyXView::gui()
67 {
68         return owner_;
69 }
70
71
72 LyXView::LyXView(Gui & owner)
73         : work_area_(0),
74           owner_(owner),
75           toolbars_(new Toolbars(*this)),
76           intl_(new Intl),
77           autosave_timeout_(new Timeout(5000)),
78           lyxfunc_(new LyXFunc(this)),
79           dialogs_(new Dialogs(*this)),
80           controlcommand_(new ControlCommandBuffer(*this))
81 {
82         lyxerr[Debug::INIT] << "Initializing LyXFunc" << endl;
83 }
84
85 LyXView::~LyXView()
86 {
87 }
88
89
90 void LyXView::setWorkArea(WorkArea * work_area)
91 {
92         work_area_ = work_area;
93 }
94
95
96 void LyXView::redrawWorkArea()
97 {
98         work_area_->redraw();
99         updateStatusBar();
100 }
101
102
103 WorkArea * LyXView::workArea()
104 {
105         return work_area_;
106 }
107
108
109 void LyXView::init()
110 {
111         updateLayoutChoice();
112         updateMenubar();
113
114         // Start autosave timer
115         if (lyxrc.autosave) {
116                 autosave_timeout_->timeout.connect(boost::bind(&LyXView::autoSave, this));
117                 autosave_timeout_->setTimeout(lyxrc.autosave * 1000);
118                 autosave_timeout_->start();
119         }
120
121         intl_->initKeyMapper(lyxrc.use_kbmap);
122 }
123
124
125 Buffer * LyXView::buffer() const
126 {
127         return work_area_->bufferView().buffer();
128 }
129
130
131 void LyXView::setBuffer(Buffer * b)
132 {
133         if (work_area_->bufferView().buffer())
134                 disconnectBuffer();
135
136         work_area_->bufferView().setBuffer(b);
137         updateMenubar();
138         updateToolbars();
139         updateLayoutChoice();
140         updateWindowTitle();
141         if (b) {
142                 connectBuffer(*b);
143                 setLayout(work_area_->bufferView().firstLayout());
144         }
145         redrawWorkArea();
146 }
147
148
149 bool LyXView::loadLyXFile(string const & filename, bool tolastfiles)
150 {
151         if (work_area_->bufferView().buffer())
152                 disconnectBuffer();
153
154         bool loaded = work_area_->bufferView().loadLyXFile(filename, tolastfiles);
155         updateMenubar();
156         updateToolbars();
157         updateLayoutChoice();
158         updateWindowTitle();
159         if (loaded) {
160                 connectBuffer(*work_area_->bufferView().buffer());
161                 setLayout(work_area_->bufferView().firstLayout());
162         }
163         redrawWorkArea();
164         return loaded;
165 }
166
167
168 void LyXView::connectBuffer(Buffer & buf)
169 {
170         if (errorsConnection_.connected())
171                 disconnectBuffer();
172
173         // FIXME: (Abdel 15/07/2006) The connection below is not used for
174         // now.
175         // Nevertheless, it would be a very good idea to replace all manual
176         // calls of showErrorList to a call of the new modified
177         // "Buffer::errors" boost signal.
178         errorsConnection_ =
179                 buf.errors.connect(
180                         boost::bind(&LyXView::showErrorList, this, _1));
181
182         messageConnection_ =
183                 buf.message.connect(
184                         boost::bind(&LyXView::message, this, _1));
185
186         busyConnection_ =
187                 buf.busy.connect(
188                         boost::bind(&LyXView::busy, this, _1));
189
190         titleConnection_ =
191                 buf.updateTitles.connect(
192                         boost::bind(&LyXView::updateWindowTitle, this));
193
194         timerConnection_ =
195                 buf.resetAutosaveTimers.connect(
196                         boost::bind(&LyXView::resetAutosaveTimer, this));
197
198         readonlyConnection_ =
199                 buf.readonly.connect(
200                         boost::bind(&LyXView::showReadonly, this, _1));
201
202         closingConnection_ =
203                 buf.closing.connect(
204                         boost::bind(&LyXView::setBuffer, this, (Buffer *)0));
205 }
206
207
208 void LyXView::disconnectBuffer()
209 {
210         messageConnection_.disconnect();
211         busyConnection_.disconnect();
212         titleConnection_.disconnect();
213         timerConnection_.disconnect();
214         readonlyConnection_.disconnect();
215         closingConnection_.disconnect();
216 }
217
218
219 void LyXView::showErrorList(string const & action)
220 {
221         Buffer * b = work_area_->bufferView().buffer();
222         if (!b->getErrorList().empty()) {
223                 string const title = bformat(_("%1$s Errors (%2$s)"),
224                         action, buffer()->fileName());
225                 getDialogs().show("errorlist", title);
226         }
227 }
228
229
230 void LyXView::showReadonly(bool)
231 {
232         updateWindowTitle();
233         getDialogs().updateBufferDependent(false);
234 }
235
236
237 BufferView * LyXView::view() const
238 {
239         return &work_area_->bufferView();
240 }
241
242
243 void LyXView::setLayout(string const & layout)
244 {
245         toolbars_->setLayout(layout);
246 }
247
248
249 void LyXView::updateToolbars()
250 {
251         bool const math = work_area_->bufferView().cursor().inMathed();
252         bool const table =
253                 getLyXFunc().getStatus(FuncRequest(LFUN_LAYOUT_TABULAR)).enabled();
254         toolbars_->update(math, table);
255         // update redaonly status of open dialogs. This could also be in
256         // updateMenubar(), but since updateToolbars() and updateMenubar()
257         // are always called together it is only here.
258         getDialogs().checkStatus();
259 }
260
261
262 void LyXView::updateMenubar()
263 {
264         menubar_->update();
265 }
266
267
268 void LyXView::autoSave()
269 {
270         lyxerr[Debug::INFO] << "Running autoSave()" << endl;
271
272         if (view()->available()) {
273                 ::autoSave(view());
274         }
275 }
276
277
278 void LyXView::resetAutosaveTimer()
279 {
280         if (lyxrc.autosave)
281                 autosave_timeout_->restart();
282 }
283
284
285 void LyXView::updateLayoutChoice()
286 {
287         // Don't show any layouts without a buffer
288         if (!view()->buffer()) {
289                 toolbars_->clearLayoutList();
290                 return;
291         }
292
293         // Update the layout display
294         if (toolbars_->updateLayoutList(buffer()->params().textclass)) {
295                 current_layout = buffer()->params().getLyXTextClass().defaultLayoutName();
296         }
297
298         if (work_area_->bufferView().cursor().inMathed())
299                 return;
300
301         string const & layout =
302                 work_area_->bufferView().cursor().paragraph().layout()->name();
303
304         if (layout != current_layout) {
305                 toolbars_->setLayout(layout);
306                 current_layout = layout;
307         }
308 }
309
310
311 void LyXView::updateWindowTitle()
312 {
313         static string last_title = "LyX";
314         string maximize_title = "LyX";
315         string minimize_title = "LyX";
316
317         if (view()->available()) {
318                 string const cur_title = buffer()->fileName();
319                 if (!cur_title.empty()) {
320                         maximize_title += ": " + makeDisplayPath(cur_title, 30);
321                         minimize_title = onlyFilename(cur_title);
322                         if (!buffer()->isClean()) {
323                                 maximize_title += _(" (changed)");
324                                 minimize_title += '*';
325                         }
326                         if (buffer()->isReadonly())
327                                 maximize_title += _(" (read only)");
328                 }
329         }
330
331         if (maximize_title != last_title) {
332                 setWindowTitle(maximize_title, minimize_title);
333                 last_title = maximize_title;
334         }
335 }
336
337
338 void LyXView::dispatch(FuncRequest const & cmd)
339 {
340         getLyXFunc().dispatch(cmd);
341 }
342
343
344 Buffer const * const LyXView::updateInset(InsetBase const * inset) const
345 {
346         Buffer const * buffer_ptr = 0;
347         if (inset) {
348                 buffer_ptr = work_area_->bufferView().buffer();
349                 // No FitCursor:
350                 work_area_->bufferView().update(Update::Force);
351         }
352         return buffer_ptr;
353 }