]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/lyx_gui.C
GUI API Cleanup step 3: merge with "younes" branch.
[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 int start(string const & batch, vector<string> const & files,
198           unsigned int width, unsigned int height, int posx, int posy,
199           bool maximize)
200 {
201         // this can't be done before because it needs the Languages object
202         initEncodings();
203
204         int view_id = theApp->gui().newView(width, height);
205         GuiView & view = static_cast<GuiView &> (theApp->gui().view(view_id));
206
207         // FIXME: for now we assume that there is only one LyXView with id = 0.
208         /*int workArea_id_ =*/ theApp->gui().newWorkArea(width, height, 0);
209         //WorkArea * workArea_ = & theApp->gui().workArea(workArea_id_);
210
211         LyX::ref().addLyXView(&view);
212
213         view.init();
214
215         // only true when the -geometry option was NOT used
216         if (width != 0 && height != 0) {
217                 if (posx != -1 && posy != -1) {
218 #ifdef Q_OS_WIN32
219                         // FIXME: use only setGeoemtry when Trolltech has
220                         // fixed the qt4/X11 bug
221                         view.setGeometry(posx, posy,width, height);
222 #else
223                         view.resize(width, height);
224                         view.move(posx, posy);
225 #endif
226                 } else {
227                         view.resize(width, height);
228                 }
229
230                 if (maximize)
231                         view.setWindowState(Qt::WindowMaximized);
232         }
233
234         view.show();
235
236         // FIXME: some code below needs moving
237
238         lyxserver = new LyXServer(&view.getLyXFunc(), lyxrc.lyxpipes);
239         lyxsocket = new LyXServerSocket(&view.getLyXFunc(),
240                           os::internal_path(package().temp_dir() + "/lyxsocket"));
241
242         for_each(files.begin(), files.end(),
243                  bind(&LyXView::loadLyXFile, &view, _1, true));
244
245         // handle the batch commands the user asked for
246         if (!batch.empty()) {
247                 view.getLyXFunc().dispatch(lyxaction.lookupFunc(batch));
248         }
249
250         int const status = qApp->exec();
251
252         // FIXME
253         cleanup();
254         return status;
255 }
256
257
258 void sync_events()
259 {
260         // This is the ONLY place where processEvents may be called.
261         // During screen update/ redraw, this method is disabled to
262         // prevent keyboard events being handed to the LyX core, where
263         // they could cause re-entrant calls to screen update.
264         qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
265 }
266
267
268 void exit(int status)
269 {
270         cleanup();
271         QApplication::exit(status);
272 }
273
274
275 FuncStatus getStatus(FuncRequest const & ev)
276 {
277         FuncStatus flag;
278         switch (ev.action) {
279         case LFUN_TOOLTIPS_TOGGLE:
280                 flag.unknown(true);
281                 break;
282         default:
283                 break;
284         }
285
286         return flag;
287 }
288
289
290 bool getRGBColor(LColor_color col, lyx::RGBColor & rgbcol)
291 {
292         QColor const & qcol = lcolorcache.get(col);
293         if (!qcol.isValid()) {
294                 rgbcol.r = 0;
295                 rgbcol.g = 0;
296                 rgbcol.b = 0;
297                 return false;
298         }
299         rgbcol.r = qcol.red();
300         rgbcol.g = qcol.green();
301         rgbcol.b = qcol.blue();
302         return true;
303 }
304
305
306 string const hexname(LColor_color col)
307 {
308         return ltrim(fromqstr(lcolorcache.get(col).name()), "#");
309 }
310
311
312 void update_color(LColor_color)
313 {
314         // FIXME: Bleh, can't we just clear them all at once ?
315         lcolorcache.clear();
316 }
317
318
319 void update_fonts()
320 {
321         theApp->fontLoader().update();
322 }
323
324
325 bool font_available(LyXFont const & font)
326 {
327         return theApp->fontLoader().available(font);
328 }
329
330
331 void register_socket_callback(int fd, boost::function<void()> func)
332 {
333         socket_callbacks[fd] = shared_ptr<socket_callback>(new socket_callback(fd, func));
334 }
335
336
337 void unregister_socket_callback(int fd)
338 {
339         socket_callbacks.erase(fd);
340 }
341
342
343 string const roman_font_name()
344 {
345         if (!use_gui)
346                 return "serif";
347
348         QFont font;
349         font.setStyleHint(QFont::Serif);
350         font.setFamily("serif");
351
352         return fromqstr(QFontInfo(font).family());
353 }
354
355
356 string const sans_font_name()
357 {
358         if (!use_gui)
359                 return "sans";
360
361         QFont font;
362         font.setStyleHint(QFont::SansSerif);
363         font.setFamily("sans");
364
365         return fromqstr(QFontInfo(font).family());
366 }
367
368
369 string const typewriter_font_name()
370 {
371         if (!use_gui)
372                 return "monospace";
373
374         QFont font;
375         font.setStyleHint(QFont::TypeWriter);
376         font.setFamily("monospace");
377
378         return fromqstr(QFontInfo(font).family());
379 }
380
381 }; // namespace lyx_gui