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);
115 bool x11EventFilter (XEvent * ev) { return lyxX11EventFilter(ev); }
118 bool macEventFilter(EventRef event);
123 LQApplication::LQApplication(int & argc, char ** argv)
124 : QApplication(argc, argv)
127 AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
128 NewAEEventHandlerUPP(handleOpenDocuments),
134 LQApplication::~LQApplication()
139 bool LQApplication::macEventFilter(EventRef event)
141 if (GetEventClass(event) == kEventClassAppleEvent) {
142 EventRecord eventrec;
143 ConvertEventRefToEventRecord(event, &eventrec);
144 AEProcessAppleEvent(&eventrec);
155 LQApplication * app = 0;
164 void parse_init(int & argc, char * argv[])
167 FIXME : Abdel 29/05/2006 (younes.a@free.fr)
168 reorganize this code. In particular make sure that this
169 advise from Qt documentation is respected:
171 Since the QApplication object does so much initialization, it
172 must be created before any other objects related to the user
173 interface are created.
175 Right now this is not the case. For example, the call to
176 "FontLoader::initFontPath()" below is doned before the QApplication
177 creation. Moreover, I suspect that a number of global variables
178 contains Qt object that are initialized before the passage through
179 parse_init(). This might also explain the message displayed by Qt
180 that caused the hanging:
182 QObject::killTimer: timers cannot be stopped from another thread
185 // Force adding of font path _before_ QApplication is initialized
186 FontLoader::initFontPath();
189 static QApplication win_app(argc, argv);
191 app = new LQApplication(argc, argv);
194 // install translation file for Qt built-in dialogs
195 // These are only installed since Qt 3.2.x
196 static QTranslator qt_trans(0);
197 if (qt_trans.load(QString("qt_") + QTextCodec::locale(),
198 qInstallPathTranslations())) {
199 qApp->installTranslator(&qt_trans);
200 // even if the language calls for RtL, don't do that
201 qApp->setReverseLayout(false);
203 << "Successfully installed Qt translations for locale "
204 << QTextCodec::locale() << std::endl;
207 << "Could not find Qt translations for locale "
208 << QTextCodec::locale() << std::endl;
211 // These translations are meant to break Qt/Mac menu merging
212 // algorithm on some entries. It lists the menu names that
213 // should not be moved to the LyX menu
214 static QTranslator aqua_trans(0);
215 aqua_trans.insert(QTranslatorMessage("QMenuBar", "Setting", 0,
217 aqua_trans.insert(QTranslatorMessage("QMenuBar", "Config", 0,
219 aqua_trans.insert(QTranslatorMessage("QMenuBar", "Options", 0,
221 aqua_trans.insert(QTranslatorMessage("QMenuBar", "Setup", 0,
224 app.installTranslator(&aqua_trans);
227 using namespace lyx::graphics;
229 Image::newImage = boost::bind(&QLImage::newImage);
230 Image::loadableFormats = boost::bind(&QLImage::loadableFormats);
232 // needs to be done before reading lyxrc
233 lyxrc.dpi = getDPI();
235 LoaderQueue::setPriority(10,100);
243 void start(string const & batch, vector<string> const & files,
244 unsigned int width, unsigned int height, int posx, int posy)
246 // this can't be done before because it needs the Languages object
249 boost::shared_ptr<QtView> view_ptr(new QtView(width, height));
250 LyX::ref().addLyXView(view_ptr);
252 QtView & view = *view_ptr.get();
254 if (posx != -1 && posy != -1)
255 view.move(QPoint(posx, posy));
260 // FIXME: some code below needs moving
262 lyxserver = new LyXServer(&view.getLyXFunc(), lyxrc.lyxpipes);
263 lyxsocket = new LyXServerSocket(&view.getLyXFunc(),
264 os::internal_path(package().temp_dir() + "/lyxsocket"));
266 for_each(files.begin(), files.end(),
267 bind(&BufferView::loadLyXFile, view.view(), _1, true));
269 // handle the batch commands the user asked for
270 if (!batch.empty()) {
271 view.getLyXFunc().dispatch(lyxaction.lookupFunc(batch));
286 // This is the ONLY place where processEvents may be called.
287 // During screen update/ redraw, this method is disabled to
288 // prevent keyboard events being handed to the LyX core, where
289 // they could cause re-entrant calls to screen update.
290 #if QT_VERSION >= 0x030100
291 qApp->processEvents(QEventLoop::ExcludeUserInput);
302 // we cannot call qApp->exit(0) - that could return us
303 // into a static dialog return in the lyx code (for example,
304 // load autosave file QMessageBox. We have to just get the hell
311 FuncStatus getStatus(FuncRequest const & ev)
315 case LFUN_DIALOG_SHOW:
316 if (ev.argument == "preamble")
319 case LFUN_TOOLTIPS_TOGGLE:
330 bool getRGBColor(LColor_color col, lyx::RGBColor & rgbcol)
332 QColor const & qcol = lcolorcache.get(col);
333 if (!qcol.isValid()) {
339 rgbcol.r = qcol.red();
340 rgbcol.g = qcol.green();
341 rgbcol.b = qcol.blue();
346 string const hexname(LColor_color col)
348 return ltrim(fromqstr(lcolorcache.get(col).name()), "#");
352 void update_color(LColor_color)
354 // FIXME: Bleh, can't we just clear them all at once ?
365 bool font_available(LyXFont const & font)
367 return fontloader.available(font);
371 void register_socket_callback(int fd, boost::function<void()> func)
373 socket_callbacks[fd] = shared_ptr<socket_callback>(new socket_callback(fd, func));
377 void unregister_socket_callback(int fd)
379 socket_callbacks.erase(fd);
383 string const roman_font_name()
389 font.setStyleHint(QFont::Serif);
390 font.setFamily("serif");
392 return fromqstr(QFontInfo(font).family());
396 string const sans_font_name()
402 font.setStyleHint(QFont::SansSerif);
403 font.setFamily("sans");
405 return fromqstr(QFontInfo(font).family());
409 string const typewriter_font_name()
415 font.setStyleHint(QFont::TypeWriter);
416 font.setFamily("monospace");
418 return fromqstr(QFontInfo(font).family());
421 }; // namespace lyx_gui