]> git.lyx.org Git - lyx.git/blob - src/frontends/qt/GuiView.h
Keep dialog connected to cross-ref inset after Apply.
[lyx.git] / src / frontends / qt / GuiView.h
1 // -*- C++ -*-
2 /**
3  * \file GuiView.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Lars Gullik Bjornes
8  * \author John Levon
9  * \author Abdelrazak Younes
10  * \author Peter Kümmel
11  *
12  * Full author contact details are available in file CREDITS.
13  */
14
15 #ifndef GUI_VIEW_H
16 #define GUI_VIEW_H
17
18 #include "frontends/Delegates.h"
19
20 #include "support/strfwd.h"
21
22 #include <QMainWindow>
23 #include <QMenu>
24
25 class QCloseEvent;
26 class QDragEnterEvent;
27 class QDropEvent;
28 class QLabel;
29 class QShowEvent;
30
31
32 namespace lyx {
33
34 namespace support { class FileName; }
35
36 class Buffer;
37 class BufferView;
38 class Cursor;
39 class DispatchResult;
40 class FuncStatus;
41 class FuncRequest;
42 class Inset;
43
44 namespace frontend {
45
46 class Dialog;
47 class LayoutBox;
48 class GuiToolbar;
49 class GuiWorkArea;
50 class TabWorkArea;
51 class TocModels;
52 class ToolbarInfo;
53
54 /**
55  * GuiView - Qt main LyX window
56  *
57  * This class represents the main LyX window and provides
58  * accessor functions to its content.
59  *
60  * Note: a QObject emits a destroyed(QObject *) Qt signal when it
61  * is deleted. This might be useful for closing other dialogs
62  * depending on a given GuiView.
63  */
64 class GuiView : public QMainWindow, public GuiBufferViewDelegate,
65         public GuiBufferDelegate
66 {
67         Q_OBJECT
68
69 public:
70         /// create a main window of the given dimensions
71         GuiView(int id);
72
73         ~GuiView();
74
75         /// closes the view such that the view knows that is closed
76         /// programmatically and not by the user clicking the x.
77         bool closeScheduled();
78
79         /// Things that need to be done when the OSes session manager
80         /// requests a log out.
81         bool prepareAllBuffersForLogout();
82
83         int id() const { return id_; }
84
85         /// are we busy ?
86         bool busy() const;
87
88         /// Signal that the any "auto" minibuffer can be closed now.
89         void resetCommandExecute();
90
91         /// \name Generic accessor functions
92         //@{
93         /// The current BufferView refers to the BufferView that has the focus,
94         /// including for example the one that is created when you use the
95         /// advanced search and replace pane.
96         /// \return the currently selected buffer view.
97         BufferView * currentBufferView();
98         BufferView const * currentBufferView() const;
99
100         /// The document BufferView always refers to the view's main document
101         /// BufferView. So, even if the BufferView in e.g., the advanced
102         /// search and replace pane has the focus.
103         /// \return the current document buffer view.
104         BufferView * documentBufferView();
105         BufferView const * documentBufferView() const;
106
107         void newDocument(std::string const & filename,
108                          std::string templatefile = std::string(),
109                          bool fromTemplate = false);
110
111         /// display a message in the view
112         /// could be called from any thread
113         void message(docstring const &) override;
114
115         bool getStatus(FuncRequest const & cmd, FuncStatus & flag);
116         /// dispatch command.
117         /// \return true if the \c FuncRequest has been dispatched.
118         void dispatch(FuncRequest const & cmd, DispatchResult & dr);
119
120         void restartCaret();
121         /// Update the completion popup and the inline completion state.
122         /// If \c start is true, then a new completion might be started.
123         /// If \c keep is true, an active completion will be kept active
124         /// even though the cursor moved. The update flags of \c cur might
125         /// be changed.
126         void updateCompletion(Cursor & cur, bool start, bool keep);
127
128         ///
129         void setFocus();
130         bool hasFocus() const;
131
132         ///
133         void focusInEvent(QFocusEvent * e) override;
134         /// Add a Buffer to the View
135         /// \param b Buffer to set.
136         /// \param switch_to Whether to set it to the current workarea.
137         void setBuffer(Buffer * b, bool switch_to = true);
138
139         /// load a document into the current workarea.
140         Buffer * loadDocument(
141                 support::FileName const &  name, ///< File to load.
142                 bool tolastfiles = true  ///< append to the "Open recent" menu?
143                 );
144
145         /// add toolbar, if newline==true, add a toolbar break before the toolbar
146         GuiToolbar * makeToolbar(ToolbarInfo const & tbinfo, bool newline);
147         void updateStatusBar();
148
149         /// updates the possible layouts selectable
150         void updateLayoutList();
151         void updateToolbars();
152
153         ///
154         LayoutBox * getLayoutDialog() const;
155
156         /// hides the workarea and makes sure it is clean
157         bool hideWorkArea(GuiWorkArea * wa);
158         /// closes workarea; close buffer only if no other workareas point to it
159         bool closeWorkArea(GuiWorkArea * wa);
160         /// closes the buffer
161         bool closeBuffer(Buffer & buf);
162         ///
163         void openDocument(std::string const & filename);
164         ///
165         void importDocument(std::string const &);
166
167         /// \name GuiBufferDelegate.
168         //@{
169         void resetAutosaveTimers() override;
170         // shows an error list
171         // if from_master is true, show master's error list
172         void errors(std::string const &, bool from_master = false) override;
173         void structureChanged() override;
174         void updateTocItem(std::string const &, DocIterator const &) override;
175         //@}
176
177         ///
178         TocModels & tocModels();
179
180         /// called on timeout
181         void autoSave();
182
183         /// check for external change of any opened buffer, mainly for svn usage
184         void checkExternallyModifiedBuffers();
185
186         /** redraw \c inset in all the BufferViews in which it is currently
187          *  visible. If successful return a pointer to the owning Buffer.
188          */
189         Buffer const * updateInset(Inset const *);
190
191         /// \return the \c Workarea associated to \p  Buffer
192         /// \retval 0 if no \c WorkArea is found.
193         GuiWorkArea * workArea(Buffer & buffer);
194         /// \return the \c Workarea at index \c index
195         GuiWorkArea * workArea(int index);
196
197         /// Add a \c WorkArea
198         /// \return the \c Workarea associated to \p  Buffer
199         /// \retval 0 if no \c WorkArea is found.
200         GuiWorkArea * addWorkArea(Buffer & buffer);
201         /// \param work_area The current \c WorkArea, or \c NULL
202         void setCurrentWorkArea(GuiWorkArea * work_area);
203         ///
204         void removeWorkArea(GuiWorkArea * work_area);
205         /// return the current WorkArea (the one that has the focus).
206         GuiWorkArea const * currentWorkArea() const;
207         /// return the current WorkArea (the one that has the focus).
208         GuiWorkArea * currentWorkArea();
209
210         /// return the current document WorkArea (it may not have the focus).
211         GuiWorkArea const * currentMainWorkArea() const;
212         /// return the current document WorkArea (it may not have the focus).
213         GuiWorkArea * currentMainWorkArea();
214
215         /// Current ratio between physical pixels and device-independent pixels
216         double pixelRatio() const;
217
218 Q_SIGNALS:
219         void closing(int);
220         void triggerShowDialog(QString const & qname, QString const & qdata, Inset * inset);
221         // emitted when the work area or its buffer view changed
222         void bufferViewChanged();
223
224 public Q_SLOTS:
225         ///
226         void setBusy(bool) override;
227         /// idle timeout.
228         /// clear any temporary message and replace with current status.
229         void clearMessage();
230         ///
231         void updateWindowTitle(GuiWorkArea * wa);
232         ///
233         void disableShellEscape();
234
235 private Q_SLOTS:
236         ///
237         void resetWindowTitle();
238
239         void flatGroupBoxes(const QObject * object, bool flag);
240
241         ///
242         void checkCancelBackground();
243         ///
244         void on_currentWorkAreaChanged(GuiWorkArea *);
245         ///
246         void onBufferViewChanged();
247         ///
248         void on_lastWorkAreaRemoved();
249
250         /// For completion of autosave or export threads.
251         void processingThreadStarted();
252         void processingThreadFinished();
253         void autoSaveThreadFinished();
254
255         /// must be called in GUI thread
256         void doShowDialog(QString const & qname, QString const & qdata,
257         Inset * inset);
258
259         /// must be called from GUI thread
260         void updateStatusBarMessage(QString const & str);
261         void clearMessageText();
262
263         ///
264         void toolBarPopup(const QPoint &pos);
265
266 private:
267         /// Open given child document in current buffer directory.
268         void openChildDocument(std::string const & filename);
269         /// Close current document buffer.
270         bool closeBuffer();
271         /// Close all document buffers.
272         bool closeBufferAll();
273         ///
274         TabWorkArea * addTabWorkArea();
275
276         /// connect to signals in the given BufferView
277         void connectBufferView(BufferView & bv);
278         /// disconnect from signals in the given BufferView
279         void disconnectBufferView();
280         /// connect to signals in the given buffer
281         void connectBuffer(Buffer & buf);
282         /// disconnect from signals in the given buffer
283         void disconnectBuffer();
284         ///
285         void dragEnterEvent(QDragEnterEvent * ev) override;
286         ///
287         void dropEvent(QDropEvent * ev) override;
288         /// make sure we quit cleanly
289         void closeEvent(QCloseEvent * e) override;
290         ///
291         void showEvent(QShowEvent *) override;
292
293         /// in order to catch Tab key press.
294         bool event(QEvent * e) override;
295         bool focusNextPrevChild(bool) override;
296
297         ///
298         bool goToFileRow(std::string const & argument);
299
300         ///
301         class GuiViewPrivate;
302         GuiViewPrivate & d;
303
304 public:
305         ///
306         /// dialogs for this view
307         ///
308
309         ///
310         void resetDialogs();
311
312         /// Hide all visible dialogs
313         void hideAll() const;
314
315         /// Update all visible dialogs.
316         /**
317          *  Check the status of all visible dialogs and disable or re-enable
318          *  them as appropriate.
319          *
320          *  Disabling is needed for example when a dialog is open and the
321          *  cursor moves to a position where the corresponding inset is not
322          *  allowed.
323          */
324         void updateDialogs();
325
326         /** Show dialog could be called from arbitrary threads.
327             \param name == "bibtex", "citation" etc; an identifier used to
328             launch a particular dialog.
329             \param data is a string representation of the Inset contents.
330             It is often little more than the output from Inset::write.
331             It is passed to, and parsed by, the frontend dialog.
332             Several of these dialogs do not need any data,
333             so it defaults to string().
334             \param inset ownership is _not_ passed to the frontend dialog.
335             It is stored internally and used by the kernel to ascertain
336             what to do with the FuncRequest dispatched from the frontend
337             dialog on 'Apply'; should it be used to create a new inset at
338             the current cursor position or modify an existing, 'open' inset?
339         */
340         void showDialog(std::string const & name,
341                 std::string const & data, Inset * inset = 0) override;
342
343         /** \param name == "citation", "bibtex" etc; an identifier used
344             to reset the contents of a particular dialog with \param data.
345             See the comments to 'show', above.
346         */
347         void updateDialog(std::string const & name, std::string const & data) override;
348
349         /** All Dialogs of the given \param name will be closed if they are
350             connected to the given \param inset.
351         */
352         void hideDialog(std::string const & name, Inset * inset);
353         ///
354         void disconnectDialog(std::string const & name);
355         ///
356         bool develMode() const { return devel_mode_; }
357
358 private:
359         /// Saves the layout and geometry of the window
360         void saveLayout() const;
361         /// Saves the settings of toolbars and all dialogs
362         void saveUISettings() const;
363         ///
364         bool restoreLayout();
365         ///
366         GuiToolbar * toolbar(std::string const & name);
367         ///
368         void constructToolbars();
369         ///
370         void initToolbars();
371         ///
372         void initToolbar(std::string const & name);
373         /// Update lock (all) toolbars position
374         void updateLockToolbars();
375         ///
376         bool lfunUiToggle(std::string const & ui_component);
377         ///
378         void toggleFullScreen();
379         /// \return whether we did anything
380         bool insertLyXFile(docstring const & fname, bool ignorelang = false);
381         ///
382         /// Open Export As ... dialog. \p iformat is the format the
383         /// filter is initially set to.
384         bool exportBufferAs(Buffer & b, docstring const & iformat);
385
386         ///
387         enum RenameKind {
388                 LV_WRITE_AS,
389                 LV_WRITE_AS_TEMPLATE,
390                 LV_VC_RENAME,
391                 LV_VC_COPY,
392         };
393         /// Get a path for LFUN_BUFFER_WRITE_AS_TEMPLATE
394         std::string const getTemplatesPath(Buffer & buf);
395         /// Save a buffer as a new file.
396         /**
397         Write a buffer to a new file name and rename the buffer
398     according to the new file name.
399
400     This function is e.g. used by menu callbacks and
401     LFUN_BUFFER_WRITE_AS.
402
403     If 'newname' is empty, the user is asked via a
404     dialog for the buffer's new name and location.
405
406     If 'newname' is non-empty and has an absolute path, that is used.
407     Otherwise the base directory of the buffer is used as the base
408     for any relative path in 'newname'.
409
410          \p kind controls what is done besides the pure renaming:
411          * LV_WRITE_AS  => The buffer is written without version control actions.
412          * LV_VC_RENAME => The file is renamed in version control.
413          * LV_VC_COPY   => The file is copied in version control.
414          */
415         bool renameBuffer(Buffer & b, docstring const & newname,
416                           RenameKind kind = LV_WRITE_AS);
417         ///
418         bool saveBuffer(Buffer & b);
419         /// save and rename buffer to fn. If fn is empty, the buffer
420         /// is just saved as the filename it already has.
421         bool saveBuffer(Buffer & b, support::FileName const & fn);
422         /// closes a workarea, if close_buffer is true the buffer will
423         /// also be released, otherwise the buffer will be hidden.
424         bool closeWorkArea(GuiWorkArea * wa, bool close_buffer);
425         /// closes the tabworkarea and all tabs. If we are in a close event,
426         /// all buffers will be closed, otherwise they will be hidden.
427         bool closeTabWorkArea(TabWorkArea * twa);
428         /// gives the user the possibility to save their work
429         /// or to discard the changes. If hiding is true, the
430         /// document will be reloaded.
431         bool saveBufferIfNeeded(Buffer & buf, bool hiding);
432         /// closes all workareas
433         bool closeWorkAreaAll();
434         /// write all open workareas into the session file
435         void writeSession() const;
436         /// is the buffer in this workarea also shown in another tab ?
437         /// This tab can either be in the same view or in another one.
438         bool inMultiTabs(GuiWorkArea * wa);
439         /// is the buffer shown in some other view ?
440         bool inOtherView(Buffer & buf);
441         ///
442         enum NextOrPrevious {
443                 NEXTBUFFER,
444                 PREVBUFFER
445         };
446         ///
447         void gotoNextOrPreviousBuffer(NextOrPrevious np, bool const move);
448
449         /// Is the dialog currently visible?
450         bool isDialogVisible(std::string const & name) const;
451         ///
452         Dialog * findOrBuild(std::string const & name, bool hide_it);
453         ///
454         Dialog * build(std::string const & name);
455         ///
456         bool reloadBuffer(Buffer & buffer);
457         ///
458         void dispatchVC(FuncRequest const & cmd, DispatchResult & dr);
459         ///
460         void dispatchToBufferView(FuncRequest const & cmd, DispatchResult & dr);
461         ///
462         void showMessage();
463
464         /// This view ID.
465         int id_;
466
467         /// flag to avoid two concurrent close events.
468         bool closing_;
469         /// if the view is busy the cursor shouldn't blink for instance.
470         /// This counts the number of times more often we called
471         /// setBusy(true) compared to setBusy(false), so we can nest
472         /// functions that call setBusy;
473         int busy_;
474
475         /// Request to open the command toolbar if it is "auto"
476         bool command_execute_;
477         /// Request to give focus to minibuffer
478         bool minibuffer_focus_;
479
480         /// Statusbar widget that shows shell-escape status
481         QLabel * shell_escape_;
482         /// Statusbar widget that shows read-only status
483         QLabel * read_only_;
484         /// Statusbar widget that shows version control status
485         QLabel * version_control_;
486
487         /// The rate from which the actual zoom value is calculated
488         /// from the default zoom pref
489         double zoom_ratio_ = 1.0;
490         /// Minimum zoom percentage
491         static int const zoom_min_ = 10;
492
493         // movability flag of all toolbars
494         bool toolbarsMovable_;
495
496         // developer mode
497         bool devel_mode_;
498 };
499
500
501 class SEMenu : public QMenu
502 {
503         Q_OBJECT
504 public:
505         explicit SEMenu(QWidget * parent);
506
507 public Q_SLOTS:
508         void showMenu(QPoint const &) { exec(QCursor::pos()); }
509 };
510
511 } // namespace frontend
512 } // namespace lyx
513
514 #endif // GUIVIEW_H