2 * \file qt4/GuiApplication.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
8 * \author Abdelrazak Younes
10 * Full author contact details are available in file CREDITS.
15 #include "GuiApplication.h"
17 #include "qt_helpers.h"
19 #include "socket_callback.h"
21 #include "frontends/LyXView.h"
23 #include "graphics/LoaderQueue.h"
25 #include "support/FileName.h"
26 #include "support/lstrings.h"
27 #include "support/os.h"
28 #include "support/Package.h"
30 #include "BufferView.h"
33 #include "FuncRequest.h"
39 #include <QApplication>
42 #include <QFileOpenEvent>
44 #include <QLibraryInfo>
47 #include <QTranslator>
51 #include <X11/Xatom.h>
55 #include <boost/bind.hpp>
62 ///////////////////////////////////////////////////////////////
63 // You can find other X11 specific stuff
64 // at the end of this file...
65 ///////////////////////////////////////////////////////////////
72 return int(0.5 * (w.logicalDpiX() + w.logicalDpiY()));
80 using support::FileName;
82 frontend::Application * createApplication(int & argc, char * argv[])
84 return new frontend::GuiApplication(argc, argv);
90 GuiApplication * guiApp;
93 GuiApplication::~GuiApplication()
95 socket_callbacks_.clear();
99 GuiApplication::GuiApplication(int & argc, char ** argv)
100 : QApplication(argc, argv), Application(argc, argv)
102 // Qt bug? setQuitOnLastWindowClosed(true); does not work
103 setQuitOnLastWindowClosed(false);
106 // doubleClickInterval() is 400 ms on X11 which is just too long.
107 // On Windows and Mac OS X, the operating system's value is used.
108 // On Microsoft Windows, calling this function sets the double
109 // click interval for all applications. So we don't!
110 QApplication::setDoubleClickInterval(300);
113 // install translation file for Qt built-in dialogs
114 QString language_name = QString("qt_") + QLocale::system().name();
116 // language_name can be short (e.g. qt_zh) or long (e.g. qt_zh_CN).
117 // Short-named translator can be loaded from a long name, but not the
118 // opposite. Therefore, long name should be used without truncation.
119 // c.f. http://doc.trolltech.com/4.1/qtranslator.html#load
120 if (qt_trans_.load(language_name,
121 QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
123 installTranslator(&qt_trans_);
124 // even if the language calls for RtL, don't do that
125 setLayoutDirection(Qt::LeftToRight);
127 << "Successfully installed Qt translations for locale "
128 << fromqstr(language_name) << std::endl;
131 << "Could not find Qt translations for locale "
132 << fromqstr(language_name) << std::endl;
135 // This allows to translate the strings that appear in the LyX menu.
139 using namespace lyx::graphics;
141 Image::newImage = boost::bind(&QLImage::newImage);
142 Image::loadableFormats = boost::bind(&QLImage::loadableFormats);
144 // needs to be done before reading lyxrc
145 lyxrc.dpi = getDPI();
147 LoaderQueue::setPriority(10,100);
153 Clipboard& GuiApplication::clipboard()
159 Selection& GuiApplication::selection()
165 int const GuiApplication::exec()
167 QTimer::singleShot(1, this, SLOT(execBatchCommands()));
168 return QApplication::exec();
172 void GuiApplication::exit(int status)
174 QApplication::exit(status);
178 void GuiApplication::execBatchCommands()
180 LyX::ref().execBatchCommands();
184 string const GuiApplication::romanFontName()
187 font.setKerning(false);
188 font.setStyleHint(QFont::Serif);
189 font.setFamily("serif");
191 return fromqstr(QFontInfo(font).family());
195 string const GuiApplication::sansFontName()
198 font.setKerning(false);
199 font.setStyleHint(QFont::SansSerif);
200 font.setFamily("sans");
202 return fromqstr(QFontInfo(font).family());
206 string const GuiApplication::typewriterFontName()
209 font.setKerning(false);
210 font.setStyleHint(QFont::TypeWriter);
211 font.setFamily("monospace");
213 return fromqstr(QFontInfo(font).family());
217 bool GuiApplication::event(QEvent * e)
220 case QEvent::FileOpen: {
221 // Open a file; this happens only on Mac OS X for now
222 QFileOpenEvent * foe = static_cast<QFileOpenEvent *>(e);
224 if (!currentView() || !currentView()->view())
225 // The application is not properly initialized yet.
226 // So we acknowledge the event and delay the file opening
227 // until LyX is ready.
228 // FIXME UNICODE: FileName accept an utf8 encoded string.
229 LyX::ref().addFileToLoad(FileName(fromqstr(foe->file())));
231 lyx::dispatch(FuncRequest(LFUN_FILE_OPEN,
232 qstring_to_ucs4(foe->file())));
238 return QApplication::event(e);
243 bool GuiApplication::notify(QObject * receiver, QEvent * event)
247 return_value = QApplication::notify(receiver, event);
249 catch (std::exception const & e) {
250 lyxerr << "Caught \"normal\" exception: " << e.what() << endl;
251 LyX::cref().emergencyCleanup();
255 lyxerr << "Caught some really weird exception..." << endl;
256 LyX::cref().emergencyCleanup();
264 void GuiApplication::syncEvents()
266 // This is the ONLY place where processEvents may be called.
267 // During screen update/ redraw, this method is disabled to
268 // prevent keyboard events being handed to the LyX core, where
269 // they could cause re-entrant calls to screen update.
270 processEvents(QEventLoop::ExcludeUserInputEvents);
274 bool GuiApplication::getRgbColor(Color_color col,
277 QColor const & qcol = color_cache_.get(col);
278 if (!qcol.isValid()) {
284 rgbcol.r = qcol.red();
285 rgbcol.g = qcol.green();
286 rgbcol.b = qcol.blue();
291 string const GuiApplication::hexName(Color_color col)
293 return lyx::support::ltrim(fromqstr(color_cache_.get(col).name()), "#");
297 void GuiApplication::updateColor(Color_color)
299 // FIXME: Bleh, can't we just clear them all at once ?
300 color_cache_.clear();
304 void GuiApplication::registerSocketCallback(int fd, boost::function<void()> func)
306 socket_callbacks_[fd] =
307 boost::shared_ptr<socket_callback>(new socket_callback(fd, func));
311 void GuiApplication::unregisterSocketCallback(int fd)
313 socket_callbacks_.erase(fd);
316 ////////////////////////////////////////////////////////////////////////
317 // X11 specific stuff goes here...
319 bool GuiApplication::x11EventFilter(XEvent * xev)
325 case SelectionRequest: {
326 if (xev->xselectionrequest.selection != XA_PRIMARY)
328 LYXERR(Debug::GUI) << "X requested selection." << endl;
329 BufferView * bv = currentView()->view();
331 docstring const sel = bv->requestSelection();
337 case SelectionClear: {
338 if (xev->xselectionclear.selection != XA_PRIMARY)
340 LYXERR(Debug::GUI) << "Lost selection." << endl;
341 BufferView * bv = currentView()->view();
343 bv->clearSelection();
352 ////////////////////////////////////////////////////////////////////////
353 // Mac specific stuff goes here...
355 class MenuTranslator : public QTranslator {
357 virtual ~MenuTranslator() {};
358 virtual QString translate(const char * context,
359 const char * sourceText,
360 const char * comment = 0) const;
364 QString MenuTranslator::translate(const char * /*context*/,
365 const char * sourceText,
368 string const s = sourceText;
369 if (s == N_("About %1") || s == N_("Preferences")
370 || s == N_("Reconfigure") || s == N_("Quit %1"))
377 void GuiApplication::addMenuTranslator()
379 menu_trans_.reset(new MenuTranslator());
380 installTranslator(menu_trans_.get());
384 } // namespace frontend
387 #include "GuiApplication_moc.cpp"