]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiApplication.cpp
fix http://bugzilla.lyx.org/show_bug.cgi?id=5114
[lyx.git] / src / frontends / qt4 / GuiApplication.cpp
index c8fb616dae7920677a21f75cdf2b6a8cd3384944..95e18840a2f0c0cc851e20037342ce04ee2511e4 100644 (file)
@@ -54,6 +54,7 @@
 #include "support/gettext.h"
 #include "support/lstrings.h"
 #include "support/lyxalgo.h" // sorted
+#include "support/Messages.h"
 #include "support/os.h"
 #include "support/Package.h"
 
@@ -339,7 +340,7 @@ QIcon getIcon(FuncRequest const & f, bool unknown)
        if (icon.isEmpty())
                return QIcon();
 
-       LYXERR(Debug::GUI, "Found icon: " << icon);
+       //LYXERR(Debug::GUI, "Found icon: " << icon);
        QPixmap pm;
        if (!pm.load(icon)) {
                LYXERR0("Cannot load icon " << icon << " please verify resource system!");
@@ -629,9 +630,7 @@ struct GuiApplication::Private
 
 #ifdef Q_WS_WIN
        /// WMF Mime handler for Windows clipboard.
-       // FIXME for Windows Vista and Qt4 (see http://bugzilla.lyx.org/show_bug.cgi?id=4846)
-       // But this makes LyX crash on exit when LyX is compiled in release mode and if there
-       // is something in the clipboard.
+       /// \warning: see comment in ~GuiApplication and in bug 4846.
        QWindowsMimeMetafile wmf_mime_;
 #endif
 };
@@ -644,6 +643,13 @@ GuiApplication::~GuiApplication()
 #ifdef Q_WS_MACX
        closeAllLinkBackLinks();
 #endif
+       // FIXME: Work around bug 4846 for Windows Vista and Qt4
+       // (see http://bugzilla.lyx.org/show_bug.cgi?id=4846)
+       // If the clipboard is not cleared, LyX crashes on exit when it is
+       // compiled in release mode and if there is something in the clipboard.
+       // This is related to QWindowsMimeMetafile which is apparently not 
+       // properly destroyed.
+       qApp->clipboard()->clear(QClipboard::Clipboard);
        delete d;
 }
 
@@ -656,6 +662,9 @@ GuiApplication::GuiApplication(int & argc, char ** argv)
        QCoreApplication::setOrganizationDomain("lyx.org");
        QCoreApplication::setApplicationName(app_name + "-" + lyx_version);
 
+       // Install translator for GUI elements.
+       installTranslator(&d->qt_trans_);
+
        // FIXME: quitOnLastWindowClosed is true by default. We should have a
        // lyxrc setting for this in order to let the application stay resident.
        // But then we need some kind of dock icon, at least on Windows.
@@ -667,6 +676,11 @@ GuiApplication::GuiApplication(int & argc, char ** argv)
        // FIXME: Do we need a lyxrc setting for this on Mac? This behaviour
        // seems to be the default case for applications like LyX.
        setQuitOnLastWindowClosed(false);
+
+       // This allows to translate the strings that appear in the LyX menu.
+       /// A translator suitable for the entries in the LyX menu.
+       /// Only needed with Qt/Mac.
+       installTranslator(new MenuTranslator(this));
 #endif
        
 #ifdef Q_WS_X11
@@ -677,31 +691,6 @@ GuiApplication::GuiApplication(int & argc, char ** argv)
        QApplication::setDoubleClickInterval(300);
 #endif
 
-       // install translation file for Qt built-in dialogs
-       QString language_name = QString("qt_") + QLocale::system().name();
-       
-       // language_name can be short (e.g. qt_zh) or long (e.g. qt_zh_CN). 
-       // Short-named translator can be loaded from a long name, but not the
-       // opposite. Therefore, long name should be used without truncation.
-       // c.f. http://doc.trolltech.com/4.1/qtranslator.html#load
-       if (d->qt_trans_.load(language_name,
-               QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
-       {
-               installTranslator(&d->qt_trans_);
-               // even if the language calls for RtL, don't do that
-               setLayoutDirection(Qt::LeftToRight);
-               LYXERR(Debug::GUI, "Successfully installed Qt translations for locale "
-                       << language_name);
-       } else
-               LYXERR(Debug::GUI, "Could not find  Qt translations for locale "
-                       << language_name);
-
-#ifdef Q_WS_MACX
-       // This allows to translate the strings that appear in the LyX menu.
-       /// A translator suitable for the entries in the LyX menu.
-       /// Only needed with Qt/Mac.
-       installTranslator(new MenuTranslator(this));
-#endif
        connect(this, SIGNAL(lastWindowClosed()), this, SLOT(onLastWindowClosed()));
 
        using namespace lyx::graphics;
@@ -783,7 +772,7 @@ bool GuiApplication::dispatch(FuncRequest const & cmd)
 
        case LFUN_WINDOW_CLOSE:
                // update bookmark pit of the current buffer before window close
-               for (size_t i = 0; i < LyX::ref().session().bookmarks().size(); ++i)
+               for (size_t i = 0; i < theSession().bookmarks().size(); ++i)
                        theLyXFunc().gotoBookmark(i+1, false, false);
                current_view_->close();
                break;
@@ -898,9 +887,25 @@ bool GuiApplication::dispatch(FuncRequest const & cmd)
 
 void GuiApplication::resetGui()
 {
+       // Set the language defined by the user.
+       setGuiLanguage();
+
+       // Read menus
+       if (!readUIFile(toqstr(lyxrc.ui_file)))
+               // Gives some error box here.
+               return;
+
+       // init the global menubar on Mac. This must be done after the session
+       // was recovered to know the "last files".
+       if (d->global_menubar_)
+               d->menus_.fillMenuBar(d->global_menubar_, 0, true);
+
        QHash<int, GuiView *>::iterator it;
-       for (it = d->views_.begin(); it != d->views_.end(); ++it)
-               (*it)->resetDialogs();
+       for (it = d->views_.begin(); it != d->views_.end(); ++it) {
+               GuiView * gv = *it;
+               gv->setLayoutDirection(layoutDirection());
+               gv->resetDialogs();
+       }
 
        dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE));
 }
@@ -921,13 +926,13 @@ void GuiApplication::createView(QString const & geometry_arg, bool autoShow,
                d->global_menubar_->releaseKeyboard();
 
        // create new view
-       int id = view_id > 0 ? view_id : 0;
+       int id = view_id;
        if (id == 0) {
                while (d->views_.find(id) != d->views_.end())
                        id++;
        }
+       LYXERR(Debug::GUI, "About to create new window with ID " << id);
        GuiView * view = new GuiView(id);
-       
        // register view
        d->views_[id] = view;
 
@@ -1021,8 +1026,49 @@ void GuiApplication::exit(int status)
 }
 
 
+void GuiApplication::setGuiLanguage()
+{
+       // Set the language defined by the user.
+       setRcGuiLanguage();
+
+       QString const default_language = toqstr(Messages::defaultLanguage());
+       LYXERR(Debug::LOCALE, "Tring to set default locale to: " << default_language);
+       QLocale const default_locale(default_language);
+       QLocale::setDefault(default_locale);
+
+       // install translation file for Qt built-in dialogs
+       QString const language_name = QString("qt_") + default_locale.name();
+
+       // language_name can be short (e.g. qt_zh) or long (e.g. qt_zh_CN). 
+       // Short-named translator can be loaded from a long name, but not the
+       // opposite. Therefore, long name should be used without truncation.
+       // c.f. http://doc.trolltech.com/4.1/qtranslator.html#load
+       if (!d->qt_trans_.load(language_name,
+                       QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
+               LYXERR(Debug::LOCALE, "Could not find  Qt translations for locale "
+                       << language_name);
+       } else {
+               LYXERR(Debug::LOCALE, "Successfully installed Qt translations for locale "
+                       << language_name);
+       }
+
+       switch (default_locale.language()) {
+       case QLocale::Arabic :
+       case QLocale::Hebrew :
+       case QLocale::Persian :
+       case QLocale::Urdu :
+        setLayoutDirection(Qt::RightToLeft);
+               break;
+       default:
+        setLayoutDirection(Qt::LeftToRight);
+       }
+}
+
+
 void GuiApplication::execBatchCommands()
 {
+       setGuiLanguage();
+
        // Read menus
        if (!readUIFile(toqstr(lyxrc.ui_file)))
                // Gives some error box here.
@@ -1033,7 +1079,7 @@ void GuiApplication::execBatchCommands()
        if (d->global_menubar_)
                d->menus_.fillMenuBar(d->global_menubar_, 0, true);
 
-       LyX::ref().execBatchCommands();
+       lyx::execBatchCommands();
 }
 
 QAbstractItemModel * GuiApplication::languageModel()
@@ -1067,7 +1113,7 @@ void GuiApplication::restoreGuiSession()
        if (!lyxrc.load_session)
                return;
 
-       Session & session = LyX::ref().session();
+       Session & session = theSession();
        vector<FileName> const & lastopened = session.lastOpened().getfiles();
        // do not add to the lastfile list since these files are restored from
        // last session, and should be already there (regular files), or should
@@ -1144,7 +1190,7 @@ bool GuiApplication::notify(QObject * receiver, QEvent * event)
        catch (ExceptionMessage const & e) {
                switch(e.type_) { 
                case ErrorException:
-                       LyX::cref().emergencyCleanup();
+                       emergencyCleanup();
                        setQuitOnLastWindowClosed(false);
                        closeAllViews();
                        Alert::error(e.title_, e.details_);
@@ -1175,13 +1221,13 @@ bool GuiApplication::notify(QObject * receiver, QEvent * event)
                        "\n\nException: ");
                s += from_ascii(e.what());
                Alert::error(_("Software exception Detected"), s);
-               LyX::cref().exit(1);
+               lyx_exit(1);
        }
        catch (...) {
                docstring s = _("LyX has caught some really weird exception, it will "
                        "now attempt to save all unsaved documents and exit.");
                Alert::error(_("Software exception Detected"), s);
-               LyX::cref().exit(1);
+               lyx_exit(1);
        }
 
        return false;
@@ -1325,9 +1371,16 @@ bool GuiApplication::readUIFile(QString const & name, bool include)
        // Ensure that a file is read only once (prevents include loops)
        static QStringList uifiles;
        if (uifiles.contains(name)) {
-               LYXERR(Debug::INIT, "UI file '" << name << "' has been read already. "
-                                   << "Is this an include loop?");
-               return false;
+               if (!include) {
+                       // We are reading again the top uifile so reset the safeguard:
+                       uifiles.clear();
+                       d->menus_.reset();
+                       d->toolbars_.reset();
+               } else {
+                       LYXERR(Debug::INIT, "UI file '" << name << "' has been read already. "
+                               << "Is this an include loop?");
+                       return false;
+               }
        }
 
        LYXERR(Debug::INIT, "About to read " << name << "...");
@@ -1415,7 +1468,7 @@ bool GuiApplication::x11EventFilter(XEvent * xev)
        case SelectionRequest: {
                if (xev->xselectionrequest.selection != XA_PRIMARY)
                        break;
-               LYXERR(Debug::GUI, "X requested selection.");
+               LYXERR(Debug::SELECTION, "X requested selection.");
                BufferView * bv = current_view_->view();
                if (bv) {
                        docstring const sel = bv->requestSelection();
@@ -1427,7 +1480,7 @@ bool GuiApplication::x11EventFilter(XEvent * xev)
        case SelectionClear: {
                if (xev->xselectionclear.selection != XA_PRIMARY)
                        break;
-               LYXERR(Debug::GUI, "Lost selection.");
+               LYXERR(Debug::SELECTION, "Lost selection.");
                BufferView * bv = current_view_->view();
                if (bv)
                        bv->clearSelection();