]> git.lyx.org Git - features.git/blob - src/frontends/qt3/GuiApplication.C
This commit introduces Application_pimpl and cleanup the header includes of the affec...
[features.git] / src / frontends / qt3 / GuiApplication.C
1 /**
2  * \file qt3/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 "frontends/LyXView.h"
16 #include "frontends/WorkArea.h"
17
18 #include "GuiApplication.h"
19
20 #include "QtView.h"
21 #include "GuiWorkArea.h"
22 #include "qt_helpers.h"
23 #include "QLImage.h"
24
25 #include "BufferView.h"
26
27 // FIXME: this is needed for now because LyXFunc is still constructed
28 // there.
29 #include "frontends/Application_pimpl.h"
30
31 #include "graphics/LoaderQueue.h"
32
33 #include "support/lstrings.h"
34 #include "support/os.h"
35 #include "support/package.h"
36
37 #include "lyx_main.h"
38 #include "lyxrc.h"
39 #include "debug.h"
40
41 #include <qapplication.h>
42 #include <qclipboard.h>
43 #include <qeventloop.h>
44 #include <qlocale.h>
45 #include <qpaintdevicemetrics.h>
46 #include <qtextcodec.h>
47 #include <qtranslator.h>
48
49 #ifdef Q_WS_X11
50 #include <X11/Xlib.h>
51 #endif
52
53 #include <boost/bind.hpp>
54
55 using lyx::support::subst;
56
57 using std::string;
58 using std::endl;
59
60 // in QLyXKeySym.C
61 extern void initEncodings();
62
63 ///////////////////////////////////////////////////////////////
64 // You can find other X11 and MACX specific stuff
65 // at the end of this file...
66 ///////////////////////////////////////////////////////////////
67
68 namespace {
69
70 int getDPI()
71 {
72         QWidget w;
73         QPaintDeviceMetrics pdm(&w);
74         return int(0.5 * (pdm.logicalDpiX() + pdm.logicalDpiY()));
75 }
76
77 } // namespace anon
78
79
80 namespace lyx {
81 namespace frontend {
82
83 GuiApplication::GuiApplication(int & argc, char ** argv)
84         : QApplication(argc, argv), Application(argc, argv)
85 {
86 #ifdef Q_WS_X11
87         // doubleClickInterval() is 400 ms on X11 witch is just too long.
88         // On Windows and Mac OS X, the operating system's value is used.
89         // On Microsoft Windows, calling this function sets the double
90         // click interval for all applications. So we don't!
91         QApplication::setDoubleClickInterval(300);
92 #endif
93
94 #ifdef Q_WS_MACX
95         AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
96                               NewAEEventHandlerUPP(handleOpenDocuments),
97                               0, false);
98 #endif
99
100 #if QT_VERSION >= 0x030200
101         // install translation file for Qt built-in dialogs
102         // These are only installed since Qt 3.2.x
103         QTranslator qt_trans(0);
104         if (qt_trans.load(QString("qt_") + QTextCodec::locale(),
105                                 qInstallPathTranslations())) {
106                 qApp->installTranslator(&qt_trans);
107                 // even if the language calls for RtL, don't do that
108                 qApp->setReverseLayout(false);
109                 lyxerr[Debug::GUI]
110                         << "Successfully installed Qt translations for locale "
111                         << QTextCodec::locale() << std::endl;
112         } else
113                 lyxerr[Debug::GUI]
114                         << "Could not find  Qt translations for locale "
115                         << QTextCodec::locale() << std::endl;
116 #endif
117
118 #ifdef Q_WS_MACX
119         // These translations are meant to break Qt/Mac menu merging
120         // algorithm on some entries. It lists the menu names that
121         // should not be moved to the LyX menu
122         QTranslator aqua_trans(0);
123         aqua_trans.insert(QTranslatorMessage("QMenuBar", "Setting", 0,
124                                              "do_not_merge_me"));
125         aqua_trans.insert(QTranslatorMessage("QMenuBar", "Config", 0,
126                                              "do_not_merge_me"));
127         aqua_trans.insert(QTranslatorMessage("QMenuBar", "Options", 0,
128                                              "do_not_merge_me"));
129         aqua_trans.insert(QTranslatorMessage("QMenuBar", "Setup", 0,
130                                              "do_not_merge_me"));
131
132         qApp->installTranslator(&aqua_trans);
133 #endif
134
135         using namespace lyx::graphics;
136
137         Image::newImage = boost::bind(&QLImage::newImage);
138         Image::loadableFormats = boost::bind(&QLImage::loadableFormats);
139
140         // needs to be done before reading lyxrc
141         lyxrc.dpi = getDPI();
142
143         LoaderQueue::setPriority(10,100);
144 }
145
146
147 Clipboard& GuiApplication::clipboard()
148 {
149         return clipboard_;
150 }
151
152
153 Selection& GuiApplication::selection()
154 {
155         return selection_;
156 }
157
158
159 int const GuiApplication::exec()
160 {
161         return QApplication::exec();
162 }
163
164
165 void GuiApplication::exit(int status)
166 {
167         QApplication::exit(status);
168 }
169
170
171 // FIXME: this whole method needs to be moved to Application.
172 LyXView & GuiApplication::createView(unsigned int width,
173                                                                           unsigned int height,
174                                                                           int posx, int posy,
175                                                                           bool maximize)
176 {
177         // this can't be done before because it needs the Languages object
178         initEncodings();
179
180         int view_id = gui().newView(width, height);
181         QtView & view = static_cast<QtView &> (gui().view(view_id));
182
183         pimpl_->lyxfunc_.reset(new LyXFunc(&view));
184
185         // FIXME: for now we assume that there is only one LyXView with id = 0.
186         /*int workArea_id_ =*/ gui().newWorkArea(width, height, 0);
187         //WorkArea * workArea_ = & theApp->gui().workArea(workArea_id_);
188
189         LyX::ref().addLyXView(&view);
190
191         view.init();
192
193         // FIXME: put this initialisation code in GuiView accessible via
194         // a pure virtual method in LyXView.
195
196         // only true when the -geometry option was NOT used
197         if (width != 0 && height != 0) {
198                 view.initFloatingGeometry(QRect(posx, posy, width, height));
199                 view.resize(width, height);
200                 if (posx != -1 && posy != -1)
201                         view.move(posx, posy);
202                 view.show();
203                 if (maximize)
204                         view.setWindowState(Qt::WindowMaximized);
205         } else
206                 view.show();
207
208         return view;
209 }
210
211
212 ////////////////////////////////////////////////////////////////////////
213 // X11 specific stuff goes here...
214 #ifdef Q_WS_X11
215 bool GuiApplication::x11EventFilter(XEvent * xev)
216 {
217         switch (xev->type) {
218         case SelectionRequest:
219                 lyxerr[Debug::GUI] << "X requested selection." << endl;
220                 if (buffer_view_) {
221                         lyx::docstring const sel = buffer_view_->requestSelection();
222                         if (!sel.empty())
223                                 selection_.put(sel);
224                 }
225                 break;
226         case SelectionClear:
227                 lyxerr[Debug::GUI] << "Lost selection." << endl;
228                 if (buffer_view_)
229                         buffer_view_->clearSelection();
230                 break;
231         }
232         return false;
233 }
234 #endif
235
236
237 ////////////////////////////////////////////////////////////////////////
238 // Mac OSX specific stuff goes here...
239
240 #ifdef Q_WS_MACX
241 namespace{
242
243 OSErr checkAppleEventForMissingParams(const AppleEvent& theAppleEvent)
244  {
245         DescType returnedType;
246         Size actualSize;
247         OSErr err = AEGetAttributePtr(&theAppleEvent, keyMissedKeywordAttr,
248                                       typeWildCard, &returnedType, nil, 0,
249                                       &actualSize);
250         switch (err) {
251         case errAEDescNotFound:
252                 return noErr;
253         case noErr:
254                 return errAEEventNotHandled;
255         default:
256                 return err;
257         }
258  }
259
260 } // namespace
261
262 OSErr GuiApplication::handleOpenDocuments(const AppleEvent* inEvent,
263                                        AppleEvent* /*reply*/, long /*refCon*/)
264 {
265         QString s_arg;
266         AEDescList documentList;
267         OSErr err = AEGetParamDesc(inEvent, keyDirectObject, typeAEList,
268                                    &documentList);
269         if (err != noErr)
270                 return err;
271
272         err = checkAppleEventForMissingParams(*inEvent);
273         if (err == noErr) {
274                 long documentCount;
275                 err = AECountItems(&documentList, &documentCount);
276                 for (long documentIndex = 1;
277                      err == noErr && documentIndex <= documentCount;
278                      documentIndex++) {
279                         DescType returnedType;
280                         Size actualSize;
281                         AEKeyword keyword;
282                         FSRef ref;
283                         char qstr_buf[1024];
284                         err = AESizeOfNthItem(&documentList, documentIndex,
285                                               &returnedType, &actualSize);
286                         if (err == noErr) {
287                                 err = AEGetNthPtr(&documentList, documentIndex,
288                                                   typeFSRef, &keyword,
289                                                   &returnedType, (Ptr)&ref,
290                                                   sizeof(FSRef), &actualSize);
291                                 if (err == noErr) {
292                                         FSRefMakePath(&ref, (UInt8*)qstr_buf,
293                                                       1024);
294                                         s_arg=QString::fromUtf8(qstr_buf);
295 //                                      buffer_view_->workAreaDispatch(
296 //                                              FuncRequest(LFUN_FILE_OPEN,
297 //                                                          fromqstr(s_arg)));
298                                         break;
299                                 }
300                         }
301                 } // for ...
302         }
303         AEDisposeDesc(&documentList);
304
305         return err;
306 }
307
308 bool GuiApplication::macEventFilter(EventRef event)
309 {
310         if (GetEventClass(event) == kEventClassAppleEvent) {
311                 EventRecord eventrec;
312                 ConvertEventRefToEventRecord(event, &eventrec);
313                 AEProcessAppleEvent(&eventrec);
314
315                 return false;
316         }
317         return false;
318 }
319
320 #endif  // Q_WS_MACX
321
322 } // namespace frontend
323 } // namespace lyx