]> git.lyx.org Git - features.git/commitdiff
GuiLyXFiles: rework language selector
authorJuergen Spitzmueller <spitz@lyx.org>
Thu, 21 Mar 2019 08:13:09 +0000 (09:13 +0100)
committerJuergen Spitzmueller <spitz@lyx.org>
Thu, 21 Mar 2019 08:13:09 +0000 (09:13 +0100)
Now only the languages available for the selected file are displayed.
By default, LyX pre-selects the GUI language (and falls back to English
if this is not available). Once another language has been selected by
the user, this one is preferred before the GUI language (and the English
fallback).

src/frontends/qt4/GuiLyXFiles.cpp
src/frontends/qt4/GuiLyXFiles.h
src/frontends/qt4/ui/LyXFilesUi.ui

index c442b4e0230566e7c514f8c7ca64b2df98ee68da..adddf646524571c15d0efc47a2dc78f8466d33cd 100644 (file)
@@ -47,7 +47,7 @@ void GuiLyXFiles::getFiles(QMap<QString, QString> & in, QString const type)
        //   3) system_lyxdir
        // in this order. Files with a given sub-hierarchy will
        // only be listed once.
-       // We also consider i18n subdirectories and prefer them.
+       // We also consider i18n subdirectories and store them separately.
        QStringList dirs;
        QStringList relpaths;
 
@@ -56,23 +56,9 @@ void GuiLyXFiles::getFiles(QMap<QString, QString> & in, QString const type)
        string const build = addPath(package().build_support().absFileName(), fromqstr(type));
        string const system = addPath(package().system_support().absFileName(), fromqstr(type));
 
-       // First, query the current language subdir (except for English)
-       QString const lang = languageCO->itemData(languageCO->currentIndex()).toString();
-       if (!lang.startsWith("en")) {
-               // First try with the full code
-               dirs << toqstr(addPath(user, fromqstr(lang)));
-               dirs << toqstr(addPath(build, fromqstr(lang)));
-               dirs << toqstr(addPath(system, fromqstr(lang)));
-               // Then the name without country code
-               QString const shortl = lang.left(lang.indexOf('_'));
-               if (shortl != lang) {
-                       dirs << toqstr(addPath(user, fromqstr(shortl)));
-                       dirs << toqstr(addPath(build, fromqstr(shortl)));
-                       dirs << toqstr(addPath(system, fromqstr(shortl)));
-               }
-       }
+       available_languages_.insert(toqstr("en"), qt_("English"));
 
-       // Next, search in the base path
+       // Search in the base path
        dirs << toqstr(user)
             << toqstr(build)
             << toqstr(system);
@@ -84,30 +70,59 @@ void GuiLyXFiles::getFiles(QMap<QString, QString> & in, QString const type)
                        QString fn(QFile(it.next()).fileName());
                        if (!fn.endsWith(getSuffix()))
                                continue;
-                       QString const relpath = toqstr(makeRelPath(qstring_to_ucs4(fn),
-                                                                  qstring_to_ucs4(dir)));
+                       QString relpath = toqstr(makeRelPath(qstring_to_ucs4(fn),
+                                                            qstring_to_ucs4(dir)));
                        // <cat>/
                        int s = relpath.indexOf('/', 0);
                        QString cat = qt_("General");
+                       QString localization = "en";
                        if (s != -1) {
                                // <cat>/<subcat>/
                                cat = relpath.left(s);
                                int sc = relpath.indexOf('/', s + 1);
                                QString const subcat = (sc == -1) ?
                                                        QString() : relpath.mid(s + 1, sc - s - 1);
-                               if (langcodes_.contains(cat)
-                                   && !langcodes_.contains(dir.right(dir.lastIndexOf('/'))))
-                                       // Skip i18n dir
-                                       continue;
+                               if (all_languages_.contains(cat)
+                                   && !all_languages_.contains(dir.right(dir.lastIndexOf('/')))) {
+                                       QMap<QString, QString>::const_iterator li = all_languages_.find(cat);
+                                       // Skip i18n dir, but add language to the combo
+                                       if (!available_languages_.contains(li.key()))
+                                               available_languages_.insert(li.key(), li.value());
+                                       localization = cat;
+                               }
                                if (!subcat.isEmpty())
                                        cat += '/' + subcat;
                        }
                        if (!relpaths.contains(relpath)) {
                                relpaths.append(relpath);
-                               in.insert(fn, cat);
+                               if (localization == "en")
+                                       in.insert(relpath, cat);
+                               else
+                                       // strip off lang/
+                                       relpath = relpath.mid(relpath.indexOf('/') + 1);
+                               QMap<QString, QString> lm;
+                               if (localizations_.contains(relpath))
+                                       lm = localizations_.find(relpath).value();
+                               lm.insert(localization, fn);
+                               localizations_.insert(relpath, lm);
                        }
                }
        }
+       // Find and store GUI language
+       for (auto const & l : guilangs_) {
+               // First try with the full name
+               // `en' files are not in a subdirectory
+               if (available_languages_.contains(toqstr(l))) {
+                       guilang_ = toqstr(l);
+                       break;
+               }
+               // Then the name without country code
+               string const shortl = token(l, '_', 0);
+               if (available_languages_.contains(toqstr(shortl))) {
+                       guilang_ = toqstr(shortl);
+                       break;
+               }
+       }
 }
 
 
@@ -126,36 +141,20 @@ GuiLyXFiles::GuiLyXFiles(GuiView & lv)
                        languages.getLanguage(fromqstr(index.data(Qt::UserRole).toString()));
                if (!lang)
                        continue;
-               string const code = lang->code();
-               languageCO->addItem(qt_(lang->display()), toqstr(code));
-               langcodes_ << toqstr(code);
+               QString const code = toqstr(lang->code());
+               if (!all_languages_.contains(code))
+                       all_languages_.insert(code, qt_(lang->display()));
                // Also store code without country code
-               string const shortcode = token(code, '_', 0);
-               if (shortcode != code)
-                       langcodes_ << toqstr(shortcode);
+               QString const shortcode = code.left(code.indexOf('_'));
+               if (shortcode != code && !all_languages_.contains(shortcode))
+                       all_languages_.insert(shortcode, qt_(lang->display()));
        }
-       // Preset to GUI language
+       // Get GUI language
        string lang = getGuiMessages().language();
        string const language = getEnv("LANGUAGE");
        if (!language.empty())
                lang += ":" + language;
-
-       for (auto const & l : getVectorFromString(lang, ":")) {
-               // First try with the full name
-               // `en' files are not in a subdirectory
-               int i = languageCO->findData(toqstr(l));
-               if (i != -1) {
-                       languageCO->setCurrentIndex(i);
-                       break;
-               }
-               // Then the name without country code
-               string const shortl = token(l, '_', 0);
-               i = languageCO->findData(toqstr(l));
-               if (i != -1) {
-                       languageCO->setCurrentIndex(i);
-                       break;
-               }
-       }
+       guilangs_ =  getVectorFromString(lang, ":");
 
        // The filter bar
        filter_ = new FancyLineEdit(this);
@@ -226,9 +225,11 @@ void GuiLyXFiles::on_fileTypeCO_activated(int)
 }
 
 
-void GuiLyXFiles::on_languageCO_activated(int)
+void GuiLyXFiles::on_languageCO_activated(int i)
 {
-       updateContents();
+       savelang_ = languageCO->itemData(i).toString();
+       filesLW->currentItem()->setData(0, Qt::ToolTipRole, getRealPath());
+       changed();
 }
 
 
@@ -243,6 +244,46 @@ void GuiLyXFiles::on_filesLW_itemDoubleClicked(QTreeWidgetItem * item, int)
        close();
 }
 
+void GuiLyXFiles::on_filesLW_itemClicked(QTreeWidgetItem * item, int)
+{
+       QString const data = item->data(0, Qt::UserRole).toString();
+       languageCO->clear();
+       QMap<QString, QString>::const_iterator i =available_languages_.constBegin();
+       while (i != available_languages_.constEnd()) {
+               if (localizations_.contains(data)
+                   && localizations_.find(data).value().contains(i.key()))
+                       languageCO->addItem(i.value(), i.key());
+               ++i;
+       }
+       languageCO->setToolTip(qt_("All available languages of the selected file are displayed here.\n"
+                                  "The selected language version will be opened."));
+       // Set language combo
+       // first try last setting
+       if (!savelang_.isEmpty()) {
+               int index = languageCO->findData(savelang_);
+               if (index != -1) {
+                       languageCO->setCurrentIndex(index);
+                       filesLW->currentItem()->setData(0, Qt::ToolTipRole, getRealPath());
+                       return;
+               }
+       }
+       // next, try GUI lang
+       if (!guilang_.isEmpty()) {
+               int index = languageCO->findData(guilang_);
+               if (index != -1) {
+                       languageCO->setCurrentIndex(index);
+                       filesLW->currentItem()->setData(0, Qt::ToolTipRole, getRealPath());
+                       return;
+               }
+       }
+       // Finally, fall back to English (which should be always there)
+       int index = languageCO->findData(toqstr("en"));
+       if (index != -1) {
+               languageCO->setCurrentIndex(index);
+               filesLW->currentItem()->setData(0, Qt::ToolTipRole, getRealPath());
+       }
+}
+
 
 void GuiLyXFiles::on_browsePB_pressed()
 {
@@ -270,7 +311,9 @@ void GuiLyXFiles::updateContents()
 {
        QString type = fileTypeCO->itemData(fileTypeCO->currentIndex()).toString();
        QMap<QString, QString> files;
+       languageCO->clear();
        getFiles(files, type);
+       languageCO->model()->sort(0);
 
        filesLW->clear();
        QIcon user_icon(getPixmap("images/", "lyxfiles-user", "svgz,png"));
@@ -378,10 +421,20 @@ void GuiLyXFiles::resetFilter()
        filterLabels();
 }
 
+QString const GuiLyXFiles::getRealPath()
+{
+       QString const relpath = filesLW->currentItem()->data(0, Qt::UserRole).toString();
+       QString const language = languageCO->itemData(languageCO->currentIndex()).toString();
+       if (localizations_.contains(relpath)
+           && localizations_.find(relpath).value().contains(language))
+               return localizations_.find(relpath).value().find(language).value();
+       return QString();
+}
+
 
 void GuiLyXFiles::applyView()
 {
-       file_ = filesLW->currentItem()->data(0, Qt::UserRole).toString();
+       file_ = getRealPath();
 }
 
 
index e0e42197339b9e21748ee741a25a3281f318bb04..6a25697748679c82d6501a6bb5e7825486601a3e 100644 (file)
@@ -36,6 +36,7 @@ private Q_SLOTS:
        void on_fileTypeCO_activated(int);
        void on_languageCO_activated(int);
        void on_filesLW_itemDoubleClicked(QTreeWidgetItem *, int);
+       void on_filesLW_itemClicked(QTreeWidgetItem *, int);
        void on_browsePB_pressed();
        void slotButtonBox(QAbstractButton *);
        void filterLabels();
@@ -67,6 +68,8 @@ private:
        bool translateName() const;
        ///
        void getFiles(QMap<QString, QString> &, QString const);
+       /// Get the full file path in the selected localization
+       QString const getRealPath();
 
 private:
        /// contains the search box
@@ -75,8 +78,20 @@ private:
        QString type_;
        ///
        QString file_;
+       /// All languages (code, guiname)
+       QMap<QString, QString> all_languages_;
+       /// Languages available for files (code. guiname)
+       QMap<QString, QString> available_languages_;
        ///
-       QStringList langcodes_;
+       typedef QMap<QString, QMap<QString, QString>> localizationsMap;
+       ///
+       localizationsMap localizations_;
+       /// Possible GUI language representations
+       std::vector<std::string> guilangs_;
+       /// The real GUI lang as stored in available_languages_
+       QString guilang_;
+       /// The last used language
+       QString savelang_;
 };
 
 } // namespace frontend
index 41dea0eb1ffe511c5b8bc688aa91129f8c630e66..e90beb707266107c5b7cafa4fcb4bcde3f91228c 100644 (file)
@@ -42,7 +42,7 @@
      <item row="1" column="0" colspan="2">
       <widget class="QLabel" name="languageLA">
        <property name="toolTip">
-        <string>Use this language if avaliable (if not, English is used as fallback)</string>
+        <string/>
        </property>
        <property name="text">
         <string>&amp;Language:</string>
@@ -55,7 +55,7 @@
      <item row="1" column="2">
       <widget class="QComboBox" name="languageCO">
        <property name="toolTip">
-        <string>Use this language if avaliable (if not, English is used as fallback)</string>
+        <string>The available language(s) of the selected file will be displayed here</string>
        </property>
       </widget>
      </item>