]> git.lyx.org Git - lyx.git/blob - src/frontends/Application.h
Attempt to fix bug #13017.
[lyx.git] / src / frontends / Application.h
1 /**
2  * \file frontend/Application.h
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Abdelrazak Younes
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #ifndef APPLICATION_H
12 #define APPLICATION_H
13
14 #include "ColorCode.h"
15 #include "FuncCode.h"
16
17 #include "support/strfwd.h"
18
19 #include <functional>
20
21 #include <vector>
22
23
24 namespace lyx {
25
26 class Buffer;
27 class DispatchResult;
28 class docstring_list;
29 class FuncRequest;
30 class FuncStatus;
31 class Inset;
32
33 namespace frontend {
34
35 /// The main application class
36 /**
37 There should be only one instance of this class. No Qt object
38 initialisation should be done before the instantiation of this class.
39
40  Model/View/Controller separation at frontend level in qt frontend:
41
42  BufferList (N Buffers)
43    |
44    Buffer-a
45    Buffer-b
46    Buffer-c
47    Buffer-d
48
49  Application (this is the frontend really, should probably be renamed).
50    |
51    GuiView-1 (one or more in case of split-view mode).
52    |  |
53    |  <tab-widget-1-1>
54    |  |  |
55    |  |  WorkArea-1-1-1 (M1-1 WorkAreas, M1-1 <= N)
56    |  |  | |
57    |  |  | BufferView <-----------> Buffer-c
58    |  |  |   |
59    |  |  |   Cursor
60    |  |  |
61    |  |  WorkArea-1-1-2
62    |  |  | |
63    |  |  | BufferView <-----------> Buffer-a
64    |  |  |   |
65    |  |  |   Cursor
66    |  |
67    |  <tab-widget-1-2>
68    |
69    GuiView-2 (one or more in case of split-view mode).
70    |  |
71    |  <tab-widget-2-1>
72    |  |  |
73    |  |  WorkArea-2-1-1 (M2-1 WorkAreas, M2-1 <= N, M2-1 independent of M1-1)
74      ...
75
76
77  1) The Model: \c Buffer
78
79  The Buffer is the in-memory representation of a LyX file format. The
80  Buffer does not (should not) have any information on what part of it
81  is represented on screen. There is one unique Buffer per opened LyX
82  file. A Buffer may or may not be represented on screen; typically, a
83  child document does not have an associated BufferView unless the user
84  choose to visualize it.
85
86
87  2) The Controller: \c BufferView / \c Painter \c Cursor
88
89  The BufferView is a tool used by the view (\sa WorkArea) that
90  translates a part of the Buffer contents into drawing routines. The
91  BufferView asks each inset of the Buffer to draw itself onto the
92  screen using the Painter. There can be only one Buffer displayed in
93  a BufferView and it is set on construction. Ideally, a BufferView
94  should not be able to change the contents of its associated Buffer.
95  A BufferView is instantiated and destroyed by a \c WorkArea; it is
96  automatically destroyed by the parent WorkArea when its Buffer is
97  closed.
98
99  \todo Move all Buffer changing LFUN to Buffer::dispatch(),
100  LyXFunc::dispatch() or Cursor::dispatch().
101  \todo BufferView::buffer() should only offer const access.
102
103  The \c Painter is just a virtual interface to formalize each kind of
104  drawing routines (text, line, rectangle, etc).
105
106  The \c BufferView also contains a Cursor which may or may not be
107  visible on screen. The cursor is really just a bookmark to remember
108  where the next Buffer insertion/deletion is going to take place.
109
110
111  3) The View: \c WorkArea (and its qt specialisation GuiWorkArea)
112
113  This contains the real screen area where the drawing is done by the
114  Painter. One WorkArea holds one unique \c BufferView. While it could
115  be possible that multiple WorkArea share one BufferView, this is not
116  something desirable because a BufferView is dependent of the WorkArea
117  size.
118  The WorkArea also provide a scrollbar which position is translated
119  into scrolling command to the inner \c BufferView.
120
121  The WorkArea use the BufferView to translate each keyboard or mouse
122  events into terms that the Buffer can understand:
123  - insert/delete char
124  - select char
125  - etc.
126
127
128  4) The Window: \c GuiView
129
130  This is a full window containing a menubar, toolbars and a central
131  widget. A GuiView is in charge of creating and closing a View for a
132  given Buffer.
133  In the qt specialisation, \c GuiView, the central widget is a tab
134  widget. Each tab is reserved to the visualisation of one Buffer and
135  contains one WorkArea. In the qt frontend, one GuiView thus contains
136  multiple WorkAreas but this number can limited to one for another
137  frontend. The idea is that the kernel should not know how a Buffer
138  is displayed on screen; it's the frontend business.
139  It is also possible to have multiple Workareas showing
140  simultaneously in the same GuiView (ex: with split window), thus
141  sharing the menubar and toolbars.
142
143  In any case, there should be only one WorkArea that gets the focus
144  at a time.
145
146  With our current implementation using a QTabWidget, each Tab own its
147  own \c WorkArea. Clicking on a tab switch a WorkArea and not really
148  a Buffer. LFUN_BUFFER_SWITCH will tell the frontend to search the
149  WorkArea associated to this Buffer. The WorkArea is automatically
150  created if not already present.
151
152  A WorkArea is connected to the Buffer::closing signal and is thus
153  automatically destroyed when its Buffer is closed.
154
155 */
156 class Application
157 {
158 public:
159         ///
160         Application() {}
161         ///
162         virtual ~Application() {}
163
164         /// LyX dispatcher: executes lyx actions and does necessary
165         /// screen updates depending on results.
166         /// This method encapsulates all the LyX command operations.
167         /// This is the class of the LyX's "high level event handler".
168         /// Every user command is processed here, either invocated from
169         /// keyboard or from the GUI. All GUI objects, including buttons and
170         /// menus should use this class and never call kernel functions directly.
171         virtual DispatchResult const & dispatch(FuncRequest const &) = 0;
172
173         /// LyX dispatcher: executes lyx actions and returns result.
174         virtual void dispatch(FuncRequest const &, DispatchResult & dr) = 0;
175
176         ///
177         virtual FuncStatus getStatus(FuncRequest const & cmd) const = 0;
178
179         /// Load files and restore GUI Session.
180         virtual void restoreGuiSession() = 0;
181
182         ///
183         virtual Buffer const * updateInset(Inset const * inset) const = 0;
184
185         /// Start the main event loop.
186         /// The batch command is programmed to be execute once
187         /// the event loop is started.
188         virtual int exec() = 0;
189
190         /// Quit running LyX.
191         /**
192         * This may either quit directly or record the exit status
193         * and only stop the event loop.
194         */
195         virtual void exit(int status) = 0;
196
197         /**
198         * Given col, fills r, g, b in the range 0-255.
199         * The function returns true if successful.
200         * It returns false on failure and sets r, g, b to 0.
201         */
202         virtual bool getRgbColor(ColorCode col, RGBColor & rgbcol) = 0;
203         /// Like getRgbColor(), but static and slower
204         static bool getRgbColorUncached(ColorCode col, RGBColor & rgbcol);
205
206         /**
207          * @return true if LyX uses a dark theme
208          */
209         virtual bool isInDarkMode() = 0;
210
211         /** Eg, passing Color_black returns "000000",
212         *      passing Color_white returns "ffffff".
213         */
214         virtual std::string const hexName(ColorCode col) = 0;
215
216         /**
217         * add a callback for socket read notification
218         * @param fd socket descriptor (file/socket/etc)
219         */
220         typedef std::function<void()> SocketCallback;
221         virtual void registerSocketCallback(int fd, SocketCallback func) = 0;
222
223         /**
224         * remove a I/O read callback
225         * @param fd socket descriptor (file/socket/etc)
226         */
227         virtual void unregisterSocketCallback(int fd) = 0;
228
229         virtual bool searchMenu(FuncRequest const & func,
230                 docstring_list & names) const = 0;
231
232         virtual bool hasBufferView() const = 0;
233
234         /// \return the icon file name for the given action.
235         static docstring iconName(FuncRequest const & f, bool unknown);
236         /// \return the math icon name for the given command.
237         static docstring mathIcon(docstring const & c);
238
239         /// The language associated to current keyboard
240         virtual std::string inputLanguageCode() const = 0;
241         /// Handle a accented char key sequence
242         /// FIXME: this is only needed for LFUN_ACCENT_* in Text::dispatch()
243         virtual void handleKeyFunc(FuncCode action) = 0;
244
245         /// Start a long operation with some cancel possibility (button or ESC)
246         virtual void startLongOperation() = 0;
247         /// This needs to be periodically called to avoid freezing the GUI
248         virtual bool longOperationCancelled() = 0;
249         /// Stop the long operation mode (i.e., release the GUI)
250         virtual void stopLongOperation() = 0;
251         /// A started long operation is still in progress ?
252         virtual bool longOperationStarted() = 0;
253
254         // Add a buffer to the current view, do not switch to it.
255         virtual bool unhide(Buffer * buf) = 0;
256         // Apply preferences at the start
257         static void applyPrefs();
258         ///
259         virtual bool isBufferBusy(Buffer const * b) = 0;
260 };
261
262 /// Return the list of loadable formats.
263 std::vector<std::string> loadableImageFormats();
264
265 } // namespace frontend
266
267 frontend::Application * theApp();
268 frontend::Application * createApplication(int & argc, char * argv[]);
269 void hideDialogs(std::string const & name, Inset * inset);
270 /// Set locale correctly using LyXRC::gui_language
271 void setLocale();
272
273 } // namespace lyx
274
275
276 #endif // APPLICATION_H