]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiApplication.C
- LyX is dead slow, so the least we can do is use anti-alised text
[lyx.git] / src / frontends / qt4 / GuiApplication.C
1 /**
2  * \file qt4/GuiApplication.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 #include <config.h>
14
15 #include "GuiApplication.h"
16
17 #include "qt_helpers.h"
18 #include "QLImage.h"
19 #include "socket_callback.h"
20
21 #include "graphics/LoaderQueue.h"
22
23 #include "support/lstrings.h"
24 #include "support/os.h"
25 #include "support/package.h"
26
27 #include "BufferView.h"
28 #include "Color.h"
29 #include "debug.h"
30 #include "lyx_main.h"
31 #include "lyxrc.h"
32
33 #include <QApplication>
34 #include <QClipboard>
35 #include <QEventLoop>
36 #include <QLocale>
37 #include <QLibraryInfo>
38 #include <QTextCodec>
39 #include <QTranslator>
40 #include <QWidget>
41
42 #ifdef Q_WS_X11
43 #include <X11/Xlib.h>
44 #endif
45
46 #include <boost/bind.hpp>
47
48 using std::string;
49 using std::endl;
50
51 // in QLyXKeySym.C
52 extern void initEncodings();
53
54 ///////////////////////////////////////////////////////////////
55 // You can find other X11 and MACX specific stuff
56 // at the end of this file...
57 ///////////////////////////////////////////////////////////////
58
59 namespace {
60
61 int getDPI()
62 {
63         QWidget w;
64         return int(0.5 * (w.logicalDpiX() + w.logicalDpiY()));
65 }
66
67 } // namespace anon
68
69
70 namespace lyx {
71
72 frontend::Application * createApplication(int & argc, char * argv[])
73 {
74         return new frontend::GuiApplication(argc, argv);
75 }
76
77
78 namespace frontend {
79
80 GuiApplication * guiApp;
81
82
83 GuiApplication::~GuiApplication()
84 {
85         socket_callbacks_.clear();
86 }
87
88
89 GuiApplication::GuiApplication(int & argc, char ** argv)
90         : QApplication(argc, argv), Application(argc, argv)
91 {
92 #ifdef Q_WS_X11
93         // doubleClickInterval() is 400 ms on X11 which is just too long.
94         // On Windows and Mac OS X, the operating system's value is used.
95         // On Microsoft Windows, calling this function sets the double
96         // click interval for all applications. So we don't!
97         QApplication::setDoubleClickInterval(300);
98 #endif
99
100 #ifdef Q_WS_MACX
101         AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
102                               NewAEEventHandlerUPP(handleOpenDocuments),
103                               0, false);
104 #endif
105
106         // install translation file for Qt built-in dialogs
107         // These are only installed since Qt 3.2.x
108         QTranslator qt_trans;
109         QString language_name = QString("qt_") + QLocale::system().name();
110         language_name.truncate(5);
111         if (qt_trans.load(language_name,
112                 QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
113         {
114                 qApp->installTranslator(&qt_trans);
115                 // even if the language calls for RtL, don't do that
116                 qApp->setLayoutDirection(Qt::LeftToRight);
117                 lyxerr[Debug::GUI]
118                         << "Successfully installed Qt translations for locale "
119                         << fromqstr(language_name) << std::endl;
120         } else
121                 lyxerr[Debug::GUI]
122                         << "Could not find  Qt translations for locale "
123                         << fromqstr(language_name) << std::endl;
124
125 /*#ifdef Q_WS_MACX
126         // These translations are meant to break Qt/Mac menu merging
127         // algorithm on some entries. It lists the menu names that
128         // should not be moved to the LyX menu
129         QTranslator aqua_trans(0);
130         aqua_trans.insert(QTranslatorMessage("QMenuBar", "Setting", 0,
131                                              "do_not_merge_me"));
132         aqua_trans.insert(QTranslatorMessage("QMenuBar", "Config", 0,
133                                              "do_not_merge_me"));
134         aqua_trans.insert(QTranslatorMessage("QMenuBar", "Options", 0,
135                                              "do_not_merge_me"));
136         aqua_trans.insert(QTranslatorMessage("QMenuBar", "Setup", 0,
137                                              "do_not_merge_me"));
138
139         qApp->installTranslator(&aqua_trans);
140 #endif
141 */
142         using namespace lyx::graphics;
143
144         Image::newImage = boost::bind(&QLImage::newImage);
145         Image::loadableFormats = boost::bind(&QLImage::loadableFormats);
146
147         // needs to be done before reading lyxrc
148         lyxrc.dpi = getDPI();
149
150         LoaderQueue::setPriority(10,100);
151
152         guiApp = this;
153 }
154
155
156 Clipboard& GuiApplication::clipboard()
157 {
158         return clipboard_;
159 }
160
161
162 Selection& GuiApplication::selection()
163 {
164         return selection_;
165 }
166
167
168 int const GuiApplication::exec()
169 {
170         return QApplication::exec();
171 }
172
173
174 void GuiApplication::exit(int status)
175 {
176         QApplication::exit(status);
177 }
178
179
180 string const GuiApplication::romanFontName()
181 {
182         QFont font;
183         font.setKerning(false);
184         font.setStyleHint(QFont::Serif);
185         font.setFamily("serif");
186
187         return fromqstr(QFontInfo(font).family());
188 }
189
190
191 string const GuiApplication::sansFontName()
192 {
193         QFont font;
194         font.setKerning(false);
195         font.setStyleHint(QFont::SansSerif);
196         font.setFamily("sans");
197
198         return fromqstr(QFontInfo(font).family());
199 }
200
201
202 string const GuiApplication::typewriterFontName()
203 {
204         QFont font;
205         font.setKerning(false);
206         font.setStyleHint(QFont::TypeWriter);
207         font.setFamily("monospace");
208
209         return fromqstr(QFontInfo(font).family());
210 }
211
212
213 void GuiApplication::syncEvents()
214 {
215         // This is the ONLY place where processEvents may be called.
216         // During screen update/ redraw, this method is disabled to
217         // prevent keyboard events being handed to the LyX core, where
218         // they could cause re-entrant calls to screen update.
219         processEvents(QEventLoop::ExcludeUserInputEvents);
220 }
221
222
223 bool GuiApplication::getRgbColor(LColor_color col,
224         lyx::RGBColor & rgbcol)
225 {
226         QColor const & qcol = color_cache_.get(col);
227         if (!qcol.isValid()) {
228                 rgbcol.r = 0;
229                 rgbcol.g = 0;
230                 rgbcol.b = 0;
231                 return false;
232         }
233         rgbcol.r = qcol.red();
234         rgbcol.g = qcol.green();
235         rgbcol.b = qcol.blue();
236         return true;
237 }
238
239
240 string const GuiApplication::hexName(LColor_color col)
241 {
242         return lyx::support::ltrim(fromqstr(color_cache_.get(col).name()), "#");
243 }
244
245
246 void GuiApplication::updateColor(LColor_color)
247 {
248         // FIXME: Bleh, can't we just clear them all at once ?
249         color_cache_.clear();
250 }
251
252
253 void GuiApplication::registerSocketCallback(int fd, boost::function<void()> func)
254 {
255         socket_callbacks_[fd] =
256                 boost::shared_ptr<socket_callback>(new socket_callback(fd, func));
257 }
258
259
260 void GuiApplication::unregisterSocketCallback(int fd)
261 {
262         socket_callbacks_.erase(fd);
263 }
264
265 ////////////////////////////////////////////////////////////////////////
266 // X11 specific stuff goes here...
267 #ifdef Q_WS_X11
268 bool GuiApplication::x11EventFilter(XEvent * xev)
269 {
270         switch (xev->type) {
271         case SelectionRequest:
272                 lyxerr[Debug::GUI] << "X requested selection." << endl;
273                 if (buffer_view_) {
274                         lyx::docstring const sel = buffer_view_->requestSelection();
275                         if (!sel.empty())
276                                 selection_.put(sel);
277                 }
278                 break;
279         case SelectionClear:
280                 lyxerr[Debug::GUI] << "Lost selection." << endl;
281                 if (buffer_view_)
282                         buffer_view_->clearSelection();
283                 break;
284         }
285         return false;
286 }
287 #endif
288
289
290 ////////////////////////////////////////////////////////////////////////
291 // Mac OSX specific stuff goes here...
292
293 #ifdef Q_WS_MACX
294 namespace{
295
296 OSErr checkAppleEventForMissingParams(const AppleEvent& theAppleEvent)
297  {
298         DescType returnedType;
299         Size actualSize;
300         OSErr err = AEGetAttributePtr(&theAppleEvent, keyMissedKeywordAttr,
301                                       typeWildCard, &returnedType, nil, 0,
302                                       &actualSize);
303         switch (err) {
304         case errAEDescNotFound:
305                 return noErr;
306         case noErr:
307                 return errAEEventNotHandled;
308         default:
309                 return err;
310         }
311  }
312
313 } // namespace
314
315 OSErr GuiApplication::handleOpenDocuments(const AppleEvent* inEvent,
316                                        AppleEvent* /*reply*/, long /*refCon*/)
317 {
318         QString s_arg;
319         AEDescList documentList;
320         OSErr err = AEGetParamDesc(inEvent, keyDirectObject, typeAEList,
321                                    &documentList);
322         if (err != noErr)
323                 return err;
324
325         err = checkAppleEventForMissingParams(*inEvent);
326         if (err == noErr) {
327                 long documentCount;
328                 err = AECountItems(&documentList, &documentCount);
329                 for (long documentIndex = 1;
330                      err == noErr && documentIndex <= documentCount;
331                      documentIndex++) {
332                         DescType returnedType;
333                         Size actualSize;
334                         AEKeyword keyword;
335                         FSRef ref;
336                         char qstr_buf[1024];
337                         err = AESizeOfNthItem(&documentList, documentIndex,
338                                               &returnedType, &actualSize);
339                         if (err == noErr) {
340                                 err = AEGetNthPtr(&documentList, documentIndex,
341                                                   typeFSRef, &keyword,
342                                                   &returnedType, (Ptr)&ref,
343                                                   sizeof(FSRef), &actualSize);
344                                 if (err == noErr) {
345                                         FSRefMakePath(&ref, (UInt8*)qstr_buf,
346                                                       1024);
347                                         s_arg=QString::fromUtf8(qstr_buf);
348 //                                      buffer_view_->workAreaDispatch(
349 //                                              FuncRequest(LFUN_FILE_OPEN,
350 //                                                          fromqstr(s_arg)));
351                                         break;
352                                 }
353                         }
354                 } // for ...
355         }
356         AEDisposeDesc(&documentList);
357
358         return err;
359 }
360
361 bool GuiApplication::macEventFilter(EventRef event)
362 {
363         if (GetEventClass(event) == kEventClassAppleEvent) {
364                 EventRecord eventrec;
365                 ConvertEventRefToEventRecord(event, &eventrec);
366                 AEProcessAppleEvent(&eventrec);
367
368                 return false;
369         }
370         return false;
371 }
372
373 #endif  // Q_WS_MACX
374
375 } // namespace frontend
376 } // namespace lyx