3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
9 * Full author contact details are available in file CREDITS.
16 // FIXME: move this stuff out again
17 #include "bufferlist.h"
18 #include "BufferView.h"
20 #include "funcrequest.h"
23 #include "LyXAction.h"
26 #include "lyxserver.h"
27 #include "lyxsocket.h"
29 #include "graphics/LoaderQueue.h"
31 #include "support/lstrings.h"
32 #include "support/os.h"
33 #include "support/package.h"
36 // Dear Lord, deliver us from Evil, aka the Qt headers
37 // Qt defines a macro 'signals' that clashes with a boost namespace.
38 // All is well if the namespace is visible first.
39 #include <boost/signal.hpp> // FIXME: Is this needed? (Lgb)
40 #include <boost/bind.hpp>
41 #include <boost/shared_ptr.hpp>
44 #include "lcolorcache.h"
45 #include "qfont_loader.h"
47 #include "qt_helpers.h"
48 #include "socket_callback.h"
51 #include <Carbon/Carbon.h>
54 #include <QApplication>
56 #include <QTranslator>
59 using lyx::support::ltrim;
60 using lyx::support::package;
62 using lyx::frontend::QtView;
64 namespace os = lyx::support::os;
66 using boost::shared_ptr;
68 #ifndef CXX_GLOBAL_CSTD
77 extern BufferList bufferlist;
84 return int(0.5 * (w.logicalDpiX() + w.logicalDpiY()));
87 map<int, shared_ptr<socket_callback> > socket_callbacks;
91 // FIXME: wrong place !
92 LyXServer * lyxserver;
93 LyXServerSocket * lyxsocket;
96 extern void initEncodings();
99 extern bool lyxX11EventFilter(XEvent * xev);
103 extern bool macEventFilter(EventRef event);
105 handleOpenDocuments(const AppleEvent* inEvent, AppleEvent* /*reply*/,
109 class LQApplication : public QApplication
112 LQApplication(int & argc, char ** argv);
114 bool x11EventFilter (XEvent * ev) { return lyxX11EventFilter(ev); }
117 bool macEventFilter(EventRef event);
122 LQApplication::LQApplication(int & argc, char ** argv)
123 : QApplication(argc, argv)
126 AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
127 NewAEEventHandlerUPP(handleOpenDocuments),
134 bool LQApplication::macEventFilter(EventRef event)
136 if (GetEventClass(event) == kEventClassAppleEvent) {
137 EventRecord eventrec;
138 ConvertEventRefToEventRecord(event, &eventrec);
139 AEProcessAppleEvent(&eventrec);
150 LQApplication * app = 0;
159 void parse_init(int & argc, char * argv[])
162 FIXME : Abdel 29/05/2006 (younes.a@free.fr)
163 reorganize this code. In particular make sure that this
164 advise from Qt documentation is respected:
166 Since the QApplication object does so much initialization, it
167 must be created before any other objects related to the user
168 interface are created.
170 Right now this is not the case. For example, the call to
171 "FontLoader::initFontPath()" below is doned before the QApplication
172 creation. Moreover, I suspect that a number of global variables
173 contains Qt object that are initialized before the passage through
174 parse_init(). This might also explain the message displayed by Qt
175 that caused the hanging:
177 QObject::killTimer: timers cannot be stopped from another thread
180 // Force adding of font path _before_ QApplication is initialized
181 FontLoader::initFontPath();
184 static QApplication win_app(argc, argv);
186 app = new LQApplication(argc, argv);
189 // install translation file for Qt built-in dialogs
190 // These are only installed since Qt 3.2.x
191 static QTranslator qt_trans(0);
192 if (qt_trans.load(QString("qt_") + QTextCodec::locale(),
193 qInstallPathTranslations())) {
194 qApp->installTranslator(&qt_trans);
195 // even if the language calls for RtL, don't do that
196 qApp->setReverseLayout(false);
198 << "Successfully installed Qt translations for locale "
199 << QTextCodec::locale() << std::endl;
202 << "Could not find Qt translations for locale "
203 << QTextCodec::locale() << std::endl;
206 // These translations are meant to break Qt/Mac menu merging
207 // algorithm on some entries. It lists the menu names that
208 // should not be moved to the LyX menu
209 static QTranslator aqua_trans(0);
210 aqua_trans.insert(QTranslatorMessage("QMenuBar", "Setting", 0,
212 aqua_trans.insert(QTranslatorMessage("QMenuBar", "Config", 0,
214 aqua_trans.insert(QTranslatorMessage("QMenuBar", "Options", 0,
216 aqua_trans.insert(QTranslatorMessage("QMenuBar", "Setup", 0,
219 app.installTranslator(&aqua_trans);
222 using namespace lyx::graphics;
224 Image::newImage = boost::bind(&QLImage::newImage);
225 Image::loadableFormats = boost::bind(&QLImage::loadableFormats);
227 // needs to be done before reading lyxrc
228 lyxrc.dpi = getDPI();
230 LoaderQueue::setPriority(10,100);
238 void start(string const & batch, vector<string> const & files,
239 unsigned int width, unsigned int height, int posx, int posy)
241 // this can't be done before because it needs the Languages object
244 boost::shared_ptr<QtView> view_ptr(new QtView(width, height));
245 LyX::ref().addLyXView(view_ptr);
247 QtView & view = *view_ptr.get();
249 if (posx != -1 && posy != -1)
250 view.move(QPoint(posx, posy));
255 // FIXME: some code below needs moving
257 lyxserver = new LyXServer(&view.getLyXFunc(), lyxrc.lyxpipes);
258 lyxsocket = new LyXServerSocket(&view.getLyXFunc(),
259 os::internal_path(package().temp_dir() + "/lyxsocket"));
261 for_each(files.begin(), files.end(),
262 bind(&BufferView::loadLyXFile, view.view(), _1, true));
264 // handle the batch commands the user asked for
265 if (!batch.empty()) {
266 view.getLyXFunc().dispatch(lyxaction.lookupFunc(batch));
281 // This is the ONLY place where processEvents may be called.
282 // During screen update/ redraw, this method is disabled to
283 // prevent keyboard events being handed to the LyX core, where
284 // they could cause re-entrant calls to screen update.
285 #if QT_VERSION >= 0x030100
286 qApp->processEvents(QEventLoop::ExcludeUserInput);
297 // we cannot call qApp->exit(0) - that could return us
298 // into a static dialog return in the lyx code (for example,
299 // load autosave file QMessageBox. We have to just get the hell
306 FuncStatus getStatus(FuncRequest const & ev)
310 case LFUN_DIALOG_SHOW:
311 if (ev.argument == "preamble")
314 case LFUN_TOOLTIPS_TOGGLE:
325 bool getRGBColor(LColor_color col, lyx::RGBColor & rgbcol)
327 QColor const & qcol = lcolorcache.get(col);
328 if (!qcol.isValid()) {
334 rgbcol.r = qcol.red();
335 rgbcol.g = qcol.green();
336 rgbcol.b = qcol.blue();
341 string const hexname(LColor_color col)
343 return ltrim(fromqstr(lcolorcache.get(col).name()), "#");
347 void update_color(LColor_color)
349 // FIXME: Bleh, can't we just clear them all at once ?
360 bool font_available(LyXFont const & font)
362 return fontloader.available(font);
366 void register_socket_callback(int fd, boost::function<void()> func)
368 socket_callbacks[fd] = shared_ptr<socket_callback>(new socket_callback(fd, func));
372 void unregister_socket_callback(int fd)
374 socket_callbacks.erase(fd);
378 string const roman_font_name()
384 font.setStyleHint(QFont::Serif);
385 font.setFamily("serif");
387 return fromqstr(QFontInfo(font).family());
391 string const sans_font_name()
397 font.setStyleHint(QFont::SansSerif);
398 font.setFamily("sans");
400 return fromqstr(QFontInfo(font).family());
404 string const typewriter_font_name()
410 font.setStyleHint(QFont::TypeWriter);
411 font.setFamily("monospace");
413 return fromqstr(QFontInfo(font).family());
416 }; // namespace lyx_gui