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"
30 #include "graphics/LoaderQueue.h"
32 #include "support/lstrings.h"
33 #include "support/convert.h"
34 #include "support/os.h"
35 #include "support/package.h"
38 // Dear Lord, deliver us from Evil, aka the Qt headers
39 // Qt defines a macro 'signals' that clashes with a boost namespace.
40 // All is well if the namespace is visible first.
41 #include <boost/signal.hpp> // FIXME: Is this needed? (Lgb)
42 #include <boost/bind.hpp>
43 #include <boost/shared_ptr.hpp>
46 #include "lcolorcache.h"
47 #include "qfont_loader.h"
49 #include "qt_helpers.h"
50 #include "socket_callback.h"
53 #include <Carbon/Carbon.h>
56 #include <QApplication>
58 #include <QTranslator>
61 using lyx::support::ltrim;
62 using lyx::support::package;
64 using lyx::frontend::QtView;
66 namespace os = lyx::support::os;
68 using boost::shared_ptr;
70 #ifndef CXX_GLOBAL_CSTD
79 extern BufferList bufferlist;
86 return int(0.5 * (w.logicalDpiX() + w.logicalDpiY()));
89 map<int, shared_ptr<socket_callback> > socket_callbacks;
93 // FIXME: wrong place !
94 LyXServer * lyxserver;
95 LyXServerSocket * lyxsocket;
98 extern void initEncodings();
101 extern bool lyxX11EventFilter(XEvent * xev);
105 extern bool macEventFilter(EventRef event);
107 handleOpenDocuments(const AppleEvent* inEvent, AppleEvent* /*reply*/,
111 class LQApplication : public QApplication
114 LQApplication(int & argc, char ** argv);
117 bool x11EventFilter (XEvent * ev) { return lyxX11EventFilter(ev); }
120 bool macEventFilter(EventRef event);
125 LQApplication::LQApplication(int & argc, char ** argv)
126 : QApplication(argc, argv)
129 AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
130 NewAEEventHandlerUPP(handleOpenDocuments),
136 LQApplication::~LQApplication()
141 bool LQApplication::macEventFilter(EventRef event)
143 if (GetEventClass(event) == kEventClassAppleEvent) {
144 EventRecord eventrec;
145 ConvertEventRefToEventRecord(event, &eventrec);
146 AEProcessAppleEvent(&eventrec);
157 LQApplication * app = 0;
166 void parse_init(int & argc, char * argv[])
169 FIXME : Abdel 29/05/2006 (younes.a@free.fr)
170 reorganize this code. In particular make sure that this
171 advise from Qt documentation is respected:
173 Since the QApplication object does so much initialization, it
174 must be created before any other objects related to the user
175 interface are created.
177 Right now this is not the case. For example, the call to
178 "FontLoader::initFontPath()" below is doned before the QApplication
179 creation. Moreover, I suspect that a number of global variables
180 contains Qt object that are initialized before the passage through
181 parse_init(). This might also explain the message displayed by Qt
182 that caused the hanging:
184 QObject::killTimer: timers cannot be stopped from another thread
187 // Force adding of font path _before_ QApplication is initialized
188 FontLoader::initFontPath();
191 static QApplication win_app(argc, argv);
193 app = new LQApplication(argc, argv);
196 // install translation file for Qt built-in dialogs
197 // These are only installed since Qt 3.2.x
198 static QTranslator qt_trans(0);
199 if (qt_trans.load(QString("qt_") + QTextCodec::locale(),
200 qInstallPathTranslations())) {
201 qApp->installTranslator(&qt_trans);
202 // even if the language calls for RtL, don't do that
203 qApp->setReverseLayout(false);
205 << "Successfully installed Qt translations for locale "
206 << QTextCodec::locale() << std::endl;
209 << "Could not find Qt translations for locale "
210 << QTextCodec::locale() << std::endl;
213 // These translations are meant to break Qt/Mac menu merging
214 // algorithm on some entries. It lists the menu names that
215 // should not be moved to the LyX menu
216 static QTranslator aqua_trans(0);
217 aqua_trans.insert(QTranslatorMessage("QMenuBar", "Setting", 0,
219 aqua_trans.insert(QTranslatorMessage("QMenuBar", "Config", 0,
221 aqua_trans.insert(QTranslatorMessage("QMenuBar", "Options", 0,
223 aqua_trans.insert(QTranslatorMessage("QMenuBar", "Setup", 0,
226 app.installTranslator(&aqua_trans);
229 using namespace lyx::graphics;
231 Image::newImage = boost::bind(&QLImage::newImage);
232 Image::loadableFormats = boost::bind(&QLImage::loadableFormats);
234 // needs to be done before reading lyxrc
235 lyxrc.dpi = getDPI();
237 LoaderQueue::setPriority(10,100);
245 void start(string const & batch, vector<string> const & files)
247 // this can't be done before because it needs the Languages object
251 unsigned int width = 690;
252 unsigned int height = 510;
254 if (lyxrc.geometry_width != 0 && lyxrc.geometry_height != 0 ) {
255 width = lyxrc.geometry_width;
256 height = lyxrc.geometry_height;
258 // if lyxrc returns (0,0), then use session info
260 string val = LyX::ref().session().loadSessionInfo("WindowWidth");
262 width = convert<unsigned int>(val);
263 val = LyX::ref().session().loadSessionInfo("WindowHeight");
265 height = convert<unsigned int>(val);
268 boost::shared_ptr<QtView> view_ptr(new QtView(width, height));
269 LyX::ref().addLyXView(view_ptr);
271 QtView & view = *view_ptr.get();
273 // if user wants to restore window position
274 if (lyxrc.geometry_xysaved) {
275 QPoint p = view.pos();
276 string val = LyX::ref().session().loadSessionInfo("WindowPosX");
278 p.setX(convert<unsigned int>(val));
279 val = LyX::ref().session().loadSessionInfo("WindowPosY");
281 p.setY(convert<unsigned int>(val));
287 // FIXME: some code below needs moving
289 lyxserver = new LyXServer(&view.getLyXFunc(), lyxrc.lyxpipes);
290 lyxsocket = new LyXServerSocket(&view.getLyXFunc(),
291 os::internal_path(package().temp_dir() + "/lyxsocket"));
293 for_each(files.begin(), files.end(),
294 bind(&BufferView::loadLyXFile, view.view(), _1, true));
296 // handle the batch commands the user asked for
297 if (!batch.empty()) {
298 view.getLyXFunc().dispatch(lyxaction.lookupFunc(batch));
313 // This is the ONLY place where processEvents may be called.
314 // During screen update/ redraw, this method is disabled to
315 // prevent keyboard events being handed to the LyX core, where
316 // they could cause re-entrant calls to screen update.
317 #if QT_VERSION >= 0x030100
318 qApp->processEvents(QEventLoop::ExcludeUserInput);
329 // we cannot call qApp->exit(0) - that could return us
330 // into a static dialog return in the lyx code (for example,
331 // load autosave file QMessageBox. We have to just get the hell
338 FuncStatus getStatus(FuncRequest const & ev)
342 case LFUN_DIALOG_SHOW:
343 if (ev.argument == "preamble")
346 case LFUN_TOOLTIPS_TOGGLE:
357 bool getRGBColor(LColor_color col, lyx::RGBColor & rgbcol)
359 QColor const & qcol = lcolorcache.get(col);
360 if (!qcol.isValid()) {
366 rgbcol.r = qcol.red();
367 rgbcol.g = qcol.green();
368 rgbcol.b = qcol.blue();
373 string const hexname(LColor_color col)
375 return ltrim(fromqstr(lcolorcache.get(col).name()), "#");
379 void update_color(LColor_color)
381 // FIXME: Bleh, can't we just clear them all at once ?
392 bool font_available(LyXFont const & font)
394 return fontloader.available(font);
398 void register_socket_callback(int fd, boost::function<void()> func)
400 socket_callbacks[fd] = shared_ptr<socket_callback>(new socket_callback(fd, func));
404 void unregister_socket_callback(int fd)
406 socket_callbacks.erase(fd);
410 string const roman_font_name()
416 font.setStyleHint(QFont::Serif);
417 font.setFamily("serif");
419 return fromqstr(QFontInfo(font).family());
423 string const sans_font_name()
429 font.setStyleHint(QFont::SansSerif);
430 font.setFamily("sans");
432 return fromqstr(QFontInfo(font).family());
436 string const typewriter_font_name()
442 font.setStyleHint(QFont::TypeWriter);
443 font.setFamily("monospace");
445 return fromqstr(QFontInfo(font).family());
448 }; // namespace lyx_gui