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