]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiDocument.cpp
Use <cstdint> instead of <boost/cstdint.hpp>
[lyx.git] / src / frontends / qt4 / GuiDocument.cpp
index 26ffc95744bddc63337d96578f4abfb5fe93b7f8..0f143b2cc032e4be23a0e9a96949e2ab5a14a456 100644 (file)
@@ -78,6 +78,7 @@
 #include <QDirIterator>
 #include <QFontDatabase>
 #include <QHeaderView>
+#include <QPixmap>
 #include <QScrollBar>
 #include <QTextBoundaryFinder>
 #include <QTextCursor>
@@ -155,6 +156,11 @@ QMap<QString, QString> sffonts_;
 QMap<QString, QString> ttfonts_;
 QMap<QString, QString> mathfonts_;
 
+enum EncodingSets {
+       unicode = 0,
+       legacy = 1,
+       custom = 2
+};
 
 } // anonymous namespace
 
@@ -864,7 +870,7 @@ GuiDocument::GuiDocument(GuiView & lv)
        // initialize the length validator
        bc().addCheckedLineEdit(textLayoutModule->indentLE);
        bc().addCheckedLineEdit(textLayoutModule->skipLE);
-       
+
        textLayoutModule->tableStyleCO->addItem(qt_("Default"), toqstr("default"));
        getTableStyles();
 
@@ -930,11 +936,15 @@ GuiDocument::GuiDocument(GuiView & lv)
                this, SLOT(change_adaptor()));
        connect(langModule->languageCO, SIGNAL(activated(int)),
                this, SLOT(languageChanged(int)));
-       connect(langModule->defaultencodingRB, SIGNAL(clicked()),
-               this, SLOT(change_adaptor()));
-       connect(langModule->otherencodingRB, SIGNAL(clicked()),
+       connect(langModule->encodingCO, SIGNAL(activated(int)),
                this, SLOT(change_adaptor()));
        connect(langModule->encodingCO, SIGNAL(activated(int)),
+               this, SLOT(encodingSwitched(int)));
+       connect(langModule->unicodeEncodingCO, SIGNAL(activated(int)),
+               this, SLOT(change_adaptor()));
+       connect(langModule->customEncodingCO, SIGNAL(activated(int)),
+               this, SLOT(change_adaptor()));
+       connect(langModule->noInputencCB, SIGNAL(clicked()),
                this, SLOT(change_adaptor()));
        connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
                this, SLOT(change_adaptor()));
@@ -956,15 +966,44 @@ GuiDocument::GuiDocument(GuiView & lv)
        langModule->languageCO->setModel(language_model);
        langModule->languageCO->setModelColumn(0);
 
-       // Always put the default encoding in the first position.
-       langModule->encodingCO->addItem(qt_("Language Default (no inputenc)"));
-       QStringList encodinglist;
+       langModule->encodingCO->addItem(qt_("Unicode (utf8)"));
+       langModule->encodingCO->addItem(qt_("Traditional (auto-selected)"));
+       langModule->encodingCO->addItem(qt_("Custom"));
+       langModule->encodingCO->setItemData(EncodingSets::unicode,
+               "Use Unicode (utf8) for the latex source.", Qt::ToolTipRole);
+       langModule->encodingCO->setItemData(EncodingSets::legacy,
+               "Use legacy default encodings depending on text language.", Qt::ToolTipRole);
+       langModule->encodingCO->setItemData(EncodingSets::custom,
+               "Select a custom, document-wide encoding.", Qt::ToolTipRole);
+       
+       QMap<QString,QString> encodingmap_utf8;
+       for (auto const & encvar : encodings) {
+               if (!encvar.unsafe() && !encvar.guiName().empty()
+                       && std::string(encvar.name()).find("utf8") == 0)
+                       encodingmap_utf8.insert(qt_(encvar.guiName()), qt_(encvar.name()));
+       }
+       QMap<QString, QString>::const_iterator it8 = encodingmap_utf8.constBegin();
+       while (it8 != encodingmap_utf8.constEnd()) {
+               langModule->unicodeEncodingCO->addItem(it8.key(), it8.value());
+               ++it8;
+       }
+
+       QMap<QString,QString> encodingmap;
        for (auto const & encvar : encodings) {
-               if (!encvar.unsafe() && !encvar.guiName().empty())
-                       encodinglist.append(qt_(encvar.guiName()));
+               if (!encvar.unsafe() && !encvar.guiName().empty()
+                       && std::string(encvar.name()).find("utf8") != 0)
+                       encodingmap.insert(qt_(encvar.guiName()), qt_(encvar.name()));
        }
-       encodinglist.sort();
-       langModule->encodingCO->addItems(encodinglist);
+       QMap<QString, QString>::const_iterator it = encodingmap.constBegin();
+       while (it != encodingmap.constEnd()) {
+               langModule->customEncodingCO->addItem(it.key(), it.value());
+               ++it;
+       }
+       // equalise the width of encoding selectors
+       langModule->unicodeEncodingCO->setMinimumSize(
+               langModule->customEncodingCO->minimumSizeHint());
+       langModule->noInputencCB->setMinimumSize(
+               langModule->customEncodingCO->minimumSizeHint());
 
        langModule->languagePackageCO->addItem(
                qt_("Default"), toqstr("default"));
@@ -1243,6 +1282,13 @@ GuiDocument::GuiDocument(GuiView & lv)
        numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
        numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
        setSectionResizeMode(numberingModule->tocTW->header(), QHeaderView::ResizeToContents);
+       connect(numberingModule->linenoCB, SIGNAL(toggled(bool)),
+               this, SLOT(linenoToggled(bool)));
+       connect(numberingModule->linenoCB, SIGNAL(clicked()),
+               this, SLOT(change_adaptor()));
+       connect(numberingModule->linenoLE, SIGNAL(textChanged(QString)),
+               this, SLOT(change_adaptor()));
+
 
        // biblio
        biblioModule = new UiWidget<Ui::BiblioUi>(this);
@@ -1767,6 +1813,10 @@ void GuiDocument::filterModules(QString const & str)
        modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
                        return 0 < b.name.localeAwareCompare(a.name);
                });
+
+       QIcon user_icon(getPixmap("images/", "lyxfiles-user", "svgz,png"));
+       QIcon system_icon(getPixmap("images/", "lyxfiles-system", "svgz,png"));
+
        int i = 0;
        for (modInfoStruct const & m : modInfoList) {
                if (m.name.contains(str, Qt::CaseInsensitive) || contains(m.id, fromqstr(str))) {
@@ -1774,6 +1824,10 @@ void GuiDocument::filterModules(QString const & str)
                        item->setData(m.name, Qt::DisplayRole);
                        item->setData(toqstr(m.id), Qt::UserRole);
                        item->setData(m.description, Qt::ToolTipRole);
+                       if (m.local)
+                               item->setIcon(user_icon);
+                       else
+                               item->setIcon(system_icon);
                        modules_av_model_.insertRow(i, item);
                        ++i;
                }
@@ -2165,7 +2219,8 @@ void GuiDocument::languageChanged(int i)
        // some languages only work with Polyglossia
        Language const * lang = lyx::languages.getLanguage(
                fromqstr(langModule->languageCO->itemData(i).toString()));
-       if (lang->babel().empty() && !lang->polyglossia().empty()) {
+       if (lang->babel().empty() && !lang->polyglossia().empty()
+               && lang->requires() != "CJK" && lang->requires() != "japanese") {
                        // If we force to switch fontspec on, store
                        // current state (#8717)
                        if (fontModule->osFontsCB->isEnabled())
@@ -2236,10 +2291,9 @@ void GuiDocument::osFontsChanged(bool nontexfonts)
        fontModule->font_sf_scale = font_sf_scale;
        fontModule->font_tt_scale = font_tt_scale;
 
-       langModule->encodingCO->setEnabled(tex_fonts &&
-               !langModule->defaultencodingRB->isChecked());
-       langModule->defaultencodingRB->setEnabled(tex_fonts);
-       langModule->otherencodingRB->setEnabled(tex_fonts);
+       // non-tex fonts override the "\inputencoding" option with "utf8-plain"
+       langModule->encodingCO->setEnabled(tex_fonts);
+       inputencodingToDialog();
 
        fontModule->fontsDefaultCO->setEnabled(tex_fonts);
        fontModule->fontsDefaultLA->setEnabled(tex_fonts);
@@ -2257,12 +2311,50 @@ void GuiDocument::osFontsChanged(bool nontexfonts)
 }
 
 
+void GuiDocument::encodingSwitched(int i)
+{
+       bool const tex_fonts = !fontModule->osFontsCB->isChecked();
+       langModule->unicodeEncodingCO->setEnabled(tex_fonts);
+       langModule->customEncodingCO->setEnabled(tex_fonts);
+       langModule->noInputencCB->setEnabled(tex_fonts);
+       langModule->unicodeEncodingCO->setVisible(i == EncodingSets::unicode);
+       langModule->noInputencCB->setVisible(i == EncodingSets::legacy);
+       langModule->customEncodingCO->setVisible(i == EncodingSets::custom);
+}
+
+void GuiDocument::inputencodingToDialog()
+{
+       QString inputenc = toqstr(bp_.inputenc);
+       int p;
+       if (fontModule->osFontsCB->isChecked()) { // non-tex fonts require utf8-plain
+               langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
+               langModule->unicodeEncodingCO->setCurrentIndex(
+                       langModule->unicodeEncodingCO->findData("utf8-plain"));
+       } else if (inputenc.startsWith("utf8")) {
+               langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
+               p = langModule->unicodeEncodingCO->findData(inputenc);
+               if (p != -1)
+                       langModule->unicodeEncodingCO->setCurrentIndex(p);
+       } else if (inputenc.startsWith("auto")) {
+               langModule->encodingCO->setCurrentIndex(EncodingSets::legacy);
+               langModule->noInputencCB->setChecked(inputenc == "auto-legacy-plain");
+       } else {
+               langModule->encodingCO->setCurrentIndex(EncodingSets::custom);
+               p = langModule->customEncodingCO->findData(inputenc);
+               if (p != -1)
+                       langModule->customEncodingCO->setCurrentIndex(p);
+               else
+                       langModule->encodingCO->setCurrentIndex(EncodingSets::unicode);
+       }
+       encodingSwitched(langModule->encodingCO->currentIndex());
+}
+
+
 void GuiDocument::mathFontChanged(int)
 {
        updateFontOptions();
 }
 
-
 void GuiDocument::fontOsfToggled(bool state)
 {
        if (fontModule->osFontsCB->isChecked())
@@ -3200,34 +3292,27 @@ void GuiDocument::applyView()
        indicesModule->apply(bp_);
 
        // language & quotes
-       if (langModule->defaultencodingRB->isChecked()) {
-               bp_.inputenc = "auto";
-       } else {
-               int i = langModule->encodingCO->currentIndex();
-               if (i == 0)
-                       bp_.inputenc = "default";
-               else {
-                       QString const enc_gui =
-                               langModule->encodingCO->currentText();
-                       Encodings::const_iterator it = encodings.begin();
-                       Encodings::const_iterator const end = encodings.end();
-                       bool found = false;
-                       for (; it != end; ++it) {
-                               if (qt_(it->guiName()) == enc_gui &&
-                                   !it->unsafe()) {
-                                       bp_.inputenc = it->name();
-                                       found = true;
-                                       break;
-                               }
-                       }
-                       if (!found) {
-                               // should not happen
-                               lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
-                               bp_.inputenc = "default";
-                       }
+       switch (langModule->encodingCO->currentIndex()) {
+               case EncodingSets::unicode: {
+                       bp_.inputenc = fromqstr(langModule->unicodeEncodingCO->itemData(
+                               langModule->unicodeEncodingCO->currentIndex()).toString());
+                       break;
+               }
+               case EncodingSets::legacy: {
+                       bp_.inputenc = "auto-legacy";
+                       if (langModule->noInputencCB->isChecked())
+                               bp_.inputenc = "auto-legacy-plain";
+                       break;
                }
+               case EncodingSets::custom: {
+                       bp_.inputenc = fromqstr(langModule->customEncodingCO->itemData(
+                               langModule->customEncodingCO->currentIndex()).toString());
+                       break;
+               }
+               default:
+                       // this should never happen
+                       bp_.inputenc = "utf8";
        }
-
        bp_.quotes_style = (InsetQuotesParams::QuoteStyle) langModule->quoteStyleCO->itemData(
                langModule->quoteStyleCO->currentIndex()).toInt();
        bp_.dynamic_quotes = langModule->dynamicQuotesCB->isChecked();
@@ -3264,6 +3349,8 @@ void GuiDocument::applyView()
                bp_.tocdepth = numberingModule->tocSL->value();
                bp_.secnumdepth = numberingModule->depthSL->value();
        }
+       bp_.use_lineno = numberingModule->linenoCB->isChecked();
+       bp_.lineno_opts = fromqstr(numberingModule->linenoLE->text());
 
        // bullets
        bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
@@ -3718,35 +3805,9 @@ void GuiDocument::paramsToDialog()
                langModule->quoteStyleCO->findData(bp_.quotes_style));
        langModule->dynamicQuotesCB->setChecked(bp_.dynamic_quotes);
 
-       bool default_enc = true;
-       if (bp_.inputenc != "auto") {
-               default_enc = false;
-               if (bp_.inputenc == "default") {
-                       langModule->encodingCO->setCurrentIndex(0);
-               } else {
-                       string enc_gui;
-                       Encodings::const_iterator it = encodings.begin();
-                       Encodings::const_iterator const end = encodings.end();
-                       for (; it != end; ++it) {
-                               if (it->name() == bp_.inputenc &&
-                                   !it->unsafe()) {
-                                       enc_gui = it->guiName();
-                                       break;
-                               }
-                       }
-                       int const i = langModule->encodingCO->findText(
-                                       qt_(enc_gui));
-                       if (i >= 0)
-                               langModule->encodingCO->setCurrentIndex(i);
-                       else
-                               // unknown encoding. Set to default.
-                               default_enc = true;
-               }
-       }
-       langModule->defaultencodingRB->setChecked(default_enc);
-       langModule->otherencodingRB->setChecked(!default_enc);
+       // LaTeX input encoding: set after the fonts (see below)
 
-       int const p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
+       int p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
        if (p == -1) {
                langModule->languagePackageCO->setCurrentIndex(
                          langModule->languagePackageCO->findData("custom"));
@@ -3796,6 +3857,11 @@ void GuiDocument::paramsToDialog()
                numberingModule->tocTW->clear();
        }
 
+       numberingModule->linenoCB->setChecked(bp_.use_lineno);
+       numberingModule->linenoLE->setEnabled(bp_.use_lineno);
+       numberingModule->linenoLA->setEnabled(bp_.use_lineno);
+       numberingModule->linenoLE->setText(toqstr(bp_.lineno_opts));
+
        // bullets
        bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
        bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
@@ -4008,7 +4074,8 @@ void GuiDocument::paramsToDialog()
                fromqstr(langModule->languageCO->itemData(
                        langModule->languageCO->currentIndex()).toString()));
        bool const need_fontspec =
-               lang->babel().empty() && !lang->polyglossia().empty();
+               lang->babel().empty() && !lang->polyglossia().empty()
+               && lang->requires() != "CJK" && lang->requires() != "japanese";
        bool const os_fonts_available =
                bp_.baseClass()->outputType() == lyx::LATEX
                && LaTeXFeatures::isAvailable("fontspec");
@@ -4097,6 +4164,10 @@ void GuiDocument::paramsToDialog()
                fontModule->fontencLE->setText(toqstr(bp_.fontenc));
        }
 
+       // LaTeX input encoding
+       // Set after fonts because non-tex fonts override "\inputencoding".
+       inputencodingToDialog();
+
        // Formats
        // This must be set _after_ fonts since updateDefaultFormat()
        // checks osFontsCB settings.
@@ -4239,9 +4310,13 @@ void GuiDocument::updateAvailableModules()
        modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
                        return 0 < b.name.localeAwareCompare(a.name);
                });
+       QIcon user_icon(getPixmap("images/", "lyxfiles-user", "svgz,png"));
+       QIcon system_icon(getPixmap("images/", "lyxfiles-system", "svgz,png"));
        int i = 0;
        QFont catfont;
        catfont.setBold(true);
+       QBrush unavbrush;
+       unavbrush.setColor(Qt::gray);
        for (modInfoStruct const & m : modInfoList) {
                QStandardItem * item = new QStandardItem();
                QStandardItem * catItem = new QStandardItem();
@@ -4255,10 +4330,17 @@ void GuiDocument::updateAvailableModules()
                        modules_av_model_.insertRow(i, catItem);
                        ++i;
                }
+               item->setEditable(false);
                catItem->setEditable(false);
                item->setData(m.name, Qt::DisplayRole);
+               if (m.missingreqs)
+                       item->setForeground(unavbrush);
                item->setData(toqstr(m.id), Qt::UserRole);
                item->setData(m.description, Qt::ToolTipRole);
+               if (m.local)
+                       item->setIcon(user_icon);
+               else
+                       item->setIcon(system_icon);
                catItem->appendRow(item);
        }
        modules_av_model_.sort(0);
@@ -4611,6 +4693,8 @@ GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
                else {
                        m.id = name;
                        m.name = toqstr(name + " (") + qt_("Not Found") + toqstr(")");
+                       m.local = false;
+                       m.missingreqs = true;
                }
                mInfo.push_back(m);
        }
@@ -4806,7 +4890,12 @@ GuiDocument::modInfoStruct GuiDocument::modInfo(LyXModule const & mod)
        // change requires a lot of others
        modInfoStruct m;
        m.id = mod.getID();
-       m.name = toqstr(translateIfPossible(from_utf8(mod.getName())));
+       QString const guiname = toqstr(translateIfPossible(from_utf8(mod.getName())));
+       m.missingreqs = !isModuleAvailable(mod.getID());
+       if (m.missingreqs) {
+               m.name = QString(qt_("%1 (missing req.)")).arg(guiname);
+       } else
+               m.name = guiname;
        m.category = mod.category().empty() ? qt_("Miscellaneous")
                                            : toqstr(translateIfPossible(from_utf8(mod.category())));
        QString desc = toqstr(translateIfPossible(from_utf8(mod.getDescription())));
@@ -4815,11 +4904,15 @@ GuiDocument::modInfoStruct GuiDocument::modInfo(LyXModule const & mod)
        int pos = bf.toNextBoundary();
        if (pos > 0)
                desc.truncate(pos);
-       QString modulename = QString(qt_("(Module name: %1)")).arg(toqstr(m.id));
-       // Tooltip is the desc followed by the module name
-       m.description = QString("%1<i>%2</i>")
+       m.local = mod.isLocal();
+       QString const mtype = m.local ? qt_("personal module") : qt_("distributed module");
+       QString modulename = QString(qt_("<b>Module name:</b> <i>%1</i> (%2)")).arg(toqstr(m.id)).arg(mtype);
+       // Tooltip is the desc followed by the module name and the type
+       m.description = QString("%1%2")
                .arg(desc.isEmpty() ? QString() : QString("<p>%1</p>").arg(desc),
                     modulename);
+       if (m.missingreqs)
+               m.description += QString("<p>%1</p>").arg(qt_("<b>Note:</b> Some requirements for this module are missing!"));
        return m;
 }
 
@@ -4901,6 +4994,14 @@ void GuiDocument::allPackages(int col)
 }
 
 
+void GuiDocument::linenoToggled(bool on)
+{
+       numberingModule->linenoLE->setEnabled(on);
+       numberingModule->linenoLA->setEnabled(on);
+}
+
+
+
 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }