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