]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/lyx_gui.C
load files from lyx_main.C instead of lyx_gui.C, do not add session-restored files...
[lyx.git] / src / frontends / qt4 / lyx_gui.C
1 /**
2  * \file qt4/lyx_gui.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author unknown
7  * \author John Levon
8  * \author Abdelrazak Younes
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #undef QT3_SUPPORT
14
15 #include <config.h>
16
17 #include "lyx_gui.h"
18
19 // FIXME: move this stuff out again
20 #include "bufferlist.h"
21 #include "BufferView.h"
22 #include "Color.h"
23 #include "funcrequest.h"
24 #include "LColor.h"
25 #include "lyx_main.h"
26 #include "LyXAction.h"
27 #include "lyxfunc.h"
28 #include "lyxrc.h"
29 #include "lyxserver.h"
30 #include "lyxsocket.h"
31
32
33 #include "graphics/LoaderQueue.h"
34
35 #include "support/lstrings.h"
36 #include "support/os.h"
37 #include "support/package.h"
38 #include "debug.h"
39
40
41 #include "GuiView.h"
42 #include "ColorCache.h"
43 #include "FontLoader.h"
44 #include "QLImage.h"
45 #include "qt_helpers.h"
46 #include "socket_callback.h"
47 #include "Application.h"
48
49 #include <QApplication>
50 #include <QEventLoop>
51 #include <QTranslator>
52 #include <QTextCodec>
53 #include <QLocale>
54 #include <QLibraryInfo>
55
56 #include <boost/bind.hpp>
57 #include <boost/shared_ptr.hpp>
58
59
60 using lyx::support::ltrim;
61 using lyx::support::package;
62
63 using lyx::frontend::GuiImplementation;
64 using lyx::frontend::GuiView;
65 using lyx::frontend::Application;
66
67 namespace os = lyx::support::os;
68
69 using boost::shared_ptr;
70
71 #ifndef CXX_GLOBAL_CSTD
72 using std::exit;
73 #endif
74
75 using std::map;
76 using std::vector;
77 using std::string;
78
79 // FIXME: wrong place !
80 LyXServer * lyxserver;
81 LyXServerSocket * lyxsocket;
82
83 lyx::frontend::Application * theApp;
84
85 namespace {
86
87 int getDPI()
88 {
89         QWidget w;
90         return int(0.5 * (w.logicalDpiX() + w.logicalDpiY()));
91 }
92
93 map<int, shared_ptr<socket_callback> > socket_callbacks;
94
95 void cleanup()
96 {
97         delete lyxsocket;
98         lyxsocket = 0;
99         delete lyxserver;
100         lyxserver = 0;
101 }
102
103 } // namespace anon
104
105 // in QLyXKeySym.C
106 extern void initEncodings();
107
108 namespace lyx_gui {
109
110 bool use_gui = true;
111
112 int exec(int & argc, char * argv[])
113 {
114         /*
115         FIXME : Abdel 29/05/2006 (younes.a@free.fr)
116         reorganize this code. In particular make sure that this
117         advice from Qt documentation is respected:
118
119                 Since the QApplication object does so much initialization, it
120                 must be created before any other objects related to the user
121                 interface are created.
122
123         Right now this is not the case, I suspect that a number of global variables
124         contains Qt object that are initialized before the passage through
125         parse_init(). This might also explain the message displayed by Qt
126         that caused the hanging:
127
128         QObject::killTimer: timers cannot be stopped from another thread
129         */
130
131         // Force adding of font path _before_ QApplication is initialized
132         FontLoader::initFontPath();
133
134 #ifdef Q_WS_WIN
135         static Application app(argc, argv);
136 #else
137         Application app(argc, argv);
138 #endif
139
140         theApp = &app;
141
142
143         // install translation file for Qt built-in dialogs
144         // These are only installed since Qt 3.2.x
145         QTranslator qt_trans;
146         QString language_name = QString("qt_") + QLocale::system().name();
147         language_name.truncate(5);
148         if (qt_trans.load(language_name,
149                 QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
150         {
151                 qApp->installTranslator(&qt_trans);
152                 // even if the language calls for RtL, don't do that
153                 qApp->setLayoutDirection(Qt::LeftToRight);
154                 lyxerr[Debug::GUI]
155                         << "Successfully installed Qt translations for locale "
156                         << fromqstr(language_name) << std::endl;
157         } else
158                 lyxerr[Debug::GUI]
159                         << "Could not find  Qt translations for locale "
160                         << fromqstr(language_name) << std::endl;
161
162 /*#ifdef Q_WS_MACX
163         // These translations are meant to break Qt/Mac menu merging
164         // algorithm on some entries. It lists the menu names that
165         // should not be moved to the LyX menu
166         QTranslator aqua_trans(0);
167         aqua_trans.insert(QTranslatorMessage("QMenuBar", "Setting", 0,
168                                              "do_not_merge_me"));
169         aqua_trans.insert(QTranslatorMessage("QMenuBar", "Config", 0,
170                                              "do_not_merge_me"));
171         aqua_trans.insert(QTranslatorMessage("QMenuBar", "Options", 0,
172                                              "do_not_merge_me"));
173         aqua_trans.insert(QTranslatorMessage("QMenuBar", "Setup", 0,
174                                              "do_not_merge_me"));
175
176         qApp->installTranslator(&aqua_trans);
177 #endif
178 */
179         using namespace lyx::graphics;
180
181         Image::newImage = boost::bind(&QLImage::newImage);
182         Image::loadableFormats = boost::bind(&QLImage::loadableFormats);
183
184         // needs to be done before reading lyxrc
185         lyxrc.dpi = getDPI();
186
187         LoaderQueue::setPriority(10,100);
188
189         return LyX::ref().exec2(argc, argv);
190 }
191
192
193 void parse_lyxrc()
194 {}
195
196
197 LyXView * create_view(unsigned int width, unsigned int height, int posx, int posy,
198           bool maximize)
199 {
200         // this can't be done before because it needs the Languages object
201         initEncodings();
202
203         int view_id = theApp->gui().newView(width, height);
204         GuiView & view = static_cast<GuiView &> (theApp->gui().view(view_id));
205
206         // FIXME: for now we assume that there is only one LyXView with id = 0.
207         /*int workArea_id_ =*/ theApp->gui().newWorkArea(width, height, 0);
208         //WorkArea * workArea_ = & theApp->gui().workArea(workArea_id_);
209
210         LyX::ref().addLyXView(&view);
211
212         view.init();
213
214         // only true when the -geometry option was NOT used
215         if (width != 0 && height != 0) {
216                 if (posx != -1 && posy != -1) {
217 #ifdef Q_OS_WIN32
218                         // FIXME: use only setGeoemtry when Trolltech has
219                         // fixed the qt4/X11 bug
220                         view.setGeometry(posx, posy,width, height);
221 #else
222                         view.resize(width, height);
223                         view.move(posx, posy);
224 #endif
225                 } else {
226                         view.resize(width, height);
227                 }
228
229                 if (maximize)
230                         view.setWindowState(Qt::WindowMaximized);
231         }
232
233         view.show();
234
235         return &view;
236 }
237
238
239 int start(LyXView * view, string const & batch)
240 {
241         // FIXME: some code below needs moving
242
243         lyxserver = new LyXServer(&view->getLyXFunc(), lyxrc.lyxpipes);
244         lyxsocket = new LyXServerSocket(&view->getLyXFunc(),
245                           os::internal_path(package().temp_dir() + "/lyxsocket"));
246
247         // handle the batch commands the user asked for
248         if (!batch.empty()) {
249                 view->getLyXFunc().dispatch(lyxaction.lookupFunc(batch));
250         }
251
252         int const status = qApp->exec();
253
254         // FIXME
255         cleanup();
256         return status;
257 }
258
259
260 void sync_events()
261 {
262         // This is the ONLY place where processEvents may be called.
263         // During screen update/ redraw, this method is disabled to
264         // prevent keyboard events being handed to the LyX core, where
265         // they could cause re-entrant calls to screen update.
266         qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
267 }
268
269
270 void exit(int status)
271 {
272         cleanup();
273         QApplication::exit(status);
274 }
275
276
277 FuncStatus getStatus(FuncRequest const & ev)
278 {
279         FuncStatus flag;
280         switch (ev.action) {
281         case LFUN_TOOLTIPS_TOGGLE:
282                 flag.unknown(true);
283                 break;
284         default:
285                 break;
286         }
287
288         return flag;
289 }
290
291
292 bool getRGBColor(LColor_color col, lyx::RGBColor & rgbcol)
293 {
294         QColor const & qcol = lcolorcache.get(col);
295         if (!qcol.isValid()) {
296                 rgbcol.r = 0;
297                 rgbcol.g = 0;
298                 rgbcol.b = 0;
299                 return false;
300         }
301         rgbcol.r = qcol.red();
302         rgbcol.g = qcol.green();
303         rgbcol.b = qcol.blue();
304         return true;
305 }
306
307
308 string const hexname(LColor_color col)
309 {
310         return ltrim(fromqstr(lcolorcache.get(col).name()), "#");
311 }
312
313
314 void update_color(LColor_color)
315 {
316         // FIXME: Bleh, can't we just clear them all at once ?
317         lcolorcache.clear();
318 }
319
320
321 void update_fonts()
322 {
323         theApp->fontLoader().update();
324 }
325
326
327 bool font_available(LyXFont const & font)
328 {
329         return theApp->fontLoader().available(font);
330 }
331
332
333 void register_socket_callback(int fd, boost::function<void()> func)
334 {
335         socket_callbacks[fd] = shared_ptr<socket_callback>(new socket_callback(fd, func));
336 }
337
338
339 void unregister_socket_callback(int fd)
340 {
341         socket_callbacks.erase(fd);
342 }
343
344
345 string const roman_font_name()
346 {
347         if (!use_gui)
348                 return "serif";
349
350         QFont font;
351         font.setStyleHint(QFont::Serif);
352         font.setFamily("serif");
353
354         return fromqstr(QFontInfo(font).family());
355 }
356
357
358 string const sans_font_name()
359 {
360         if (!use_gui)
361                 return "sans";
362
363         QFont font;
364         font.setStyleHint(QFont::SansSerif);
365         font.setFamily("sans");
366
367         return fromqstr(QFontInfo(font).family());
368 }
369
370
371 string const typewriter_font_name()
372 {
373         if (!use_gui)
374                 return "monospace";
375
376         QFont font;
377         font.setStyleHint(QFont::TypeWriter);
378         font.setFamily("monospace");
379
380         return fromqstr(QFontInfo(font).family());
381 }
382
383 }; // namespace lyx_gui