From 803a88f243120a9e349b9b33a233ad52a00dafa5 Mon Sep 17 00:00:00 2001 From: Juergen Spitzmueller Date: Fri, 27 Jul 2018 12:14:37 +0200 Subject: [PATCH] Sort out problems with InsetInfo language settings * use the context language of the info inset (rather than the buffer language), and translate strings accordingly * for menu and shortcuts, use the Gui language instead * actually care that all translatable strings end in po (this wasn't the case). Fixes: #5348, rest of #10463 --- src/Language.cpp | 28 +++++++--- src/Language.h | 2 + src/Text3.cpp | 8 +++ src/insets/InsetInfo.cpp | 112 +++++++++++++++++++++++++++------------ src/insets/InsetInfo.h | 6 ++- 5 files changed, 112 insertions(+), 44 deletions(-) diff --git a/src/Language.cpp b/src/Language.cpp index 8110c17401..d7bcbd3c58 100644 --- a/src/Language.cpp +++ b/src/Language.cpp @@ -375,6 +375,26 @@ Match match(string const & code, Language const & lang) } // namespace + +Language const * Languages::getFromCode(string const & code) const +{ + LanguageList::const_iterator const lbeg = languagelist.begin(); + LanguageList::const_iterator const lend = languagelist.end(); + // Try for exact match first + for (LanguageList::const_iterator lit = lbeg; lit != lend; ++lit) { + if (match(code, lit->second) == ExactMatch) + return &lit->second; + } + // If not found, look for lang prefix (without country) instead + for (LanguageList::const_iterator lit = lbeg; lit != lend; ++lit) { + if (match(code, lit->second) == ApproximateMatch) + return &lit->second; + } + LYXERR0("Unknown language `" + code + "'"); + return 0; +} + + void Languages::readLayoutTranslations(support::FileName const & filename) { Lexer lex; @@ -395,13 +415,7 @@ void Languages::readLayoutTranslations(support::FileName const & filename) if (!lex.next(true)) break; string const code = lex.getString(); - bool found = false; - for (LanguageList::iterator lit = lbeg; lit != lend; ++lit) { - if (match(code, lit->second) != NoMatch) { - found = true; - break; - } - } + bool found = getFromCode(code); if (!found) { lex.printError("Unknown language `" + code + "'"); break; diff --git a/src/Language.h b/src/Language.h index d3f0e17139..9587d7987a 100644 --- a/src/Language.h +++ b/src/Language.h @@ -162,6 +162,8 @@ public: /// void read(support::FileName const & filename); /// + Language const * getFromCode(std::string const & code) const; + /// void readLayoutTranslations(support::FileName const & filename); /// Language const * getLanguage(std::string const & language) const; diff --git a/src/Text3.cpp b/src/Text3.cpp index c4cf664802..e2c2f99194 100644 --- a/src/Text3.cpp +++ b/src/Text3.cpp @@ -2362,6 +2362,10 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) selectWordWhenUnderCursor(cur, WHOLE_WORD_STRICT); Font font(ignore_font, lang); toggleAndShow(cur, this, font, toggle); + // We need a buffer update if we change the language + // of an info inset + if (cur.insetInSelection(INFO_CODE)) + cur.forceBufferUpdate(); break; } @@ -2379,6 +2383,10 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) freefont = font; toggleall = toggle; toggleAndShow(cur, this, freefont, toggleall); + // We need a buffer update if we change the language + // of an info inset + if (cur.insetInSelection(INFO_CODE)) + cur.forceBufferUpdate(); cur.message(_("Character set")); } else { lyxerr << "Argument not ok"; diff --git a/src/insets/InsetInfo.cpp b/src/insets/InsetInfo.cpp index 3cec4ee77d..5f815ac17b 100644 --- a/src/insets/InsetInfo.cpp +++ b/src/insets/InsetInfo.cpp @@ -15,6 +15,7 @@ #include "BufferParams.h" #include "BufferView.h" #include "CutAndPaste.h" +#include "Font.h" #include "FuncRequest.h" #include "FuncStatus.h" #include "InsetGraphics.h" @@ -28,6 +29,8 @@ #include "LyXRC.h" #include "LyXVC.h" #include "Lexer.h" +#include "Paragraph.h" +#include "ParIterator.h" #include "ParagraphParameters.h" #include "version.h" @@ -41,6 +44,7 @@ #include "support/FileName.h" #include "support/filetools.h" #include "support/gettext.h" +#include "support/Messages.h" #include "support/lstrings.h" #include "support/qstring_helpers.h" #include "support/Translator.h" @@ -284,22 +288,29 @@ void InsetInfo::setInfo(string const & name) } -void InsetInfo::error(string const & err) +void InsetInfo::error(docstring const & err, Language const * lang) { - setText(bformat(_(err), from_utf8(name_)), - Font(inherit_font, buffer().params().language), false); + setText(bformat(translateIfPossible(err, lang->code()), from_utf8(name_)), + Font(inherit_font, lang), false); } -void InsetInfo::setText(docstring const & str) +void InsetInfo::info(docstring const & err, Language const * lang) { - setText(str, Font(inherit_font, buffer().params().language), false); + setText(translateIfPossible(err, lang->code()), + Font(inherit_font, lang), false); +} + + +void InsetInfo::setText(docstring const & str, Language const * lang) +{ + setText(str, Font(inherit_font, lang), false); } bool InsetInfo::forceLTR() const { - return !buffer().params().language->rightToLeft() || force_ltr_; + return force_ltr_; } @@ -313,11 +324,18 @@ void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype) { return; BufferParams const & bp = buffer().params(); - - force_ltr_ = false; + Language const * lang = it.paragraph().getFontSettings(bp, it.pos()).language(); + Language const * tryguilang = languages.getFromCode(Messages::guiLanguage()); + // Some info insets use the language of the GUI (if available) + Language const * guilang = tryguilang ? tryguilang : lang; + + force_ltr_ = !lang->rightToLeft(); + // This is just to get the string into the po files + docstring gui; switch (type_) { case UNKNOWN_INFO: - error("Unknown Info: %1$s"); + gui = _("Unknown Info!"); + info(from_ascii("Unknown Info!"), lang); initialized_ = false; break; case SHORTCUT_INFO: @@ -325,20 +343,21 @@ void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype) { // shortcuts can change, so we need to re-do this each time FuncRequest const func = lyxaction.lookupFunc(name_); if (func.action() == LFUN_UNKNOWN_ACTION) { - error("Unknown action %1$s"); + gui = _("Unknown action %1$s"); + error(from_ascii("Unknown action %1$s"), lang); break; } KeyMap::Bindings bindings = theTopLevelKeymap().findBindings(func); if (bindings.empty()) { - // It is impropriate to use error() for undefined shortcut - setText(_("undefined")); + gui = _("undefined"); + info(from_ascii("undefined"), lang); break; } if (type_ == SHORTCUT_INFO) - setText(bindings.begin()->print(KeySequence::Portable)); + setText(bindings.begin()->print(KeySequence::Portable), guilang); else - setText(theTopLevelKeymap().printBindings(func, KeySequence::Portable)); - force_ltr_ = true; + setText(theTopLevelKeymap().printBindings(func, KeySequence::Portable), guilang); + force_ltr_ = !guilang->rightToLeft() && !lang->rightToLeft(); break; } case LYXRC_INFO: { @@ -346,7 +365,8 @@ void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype) { // so we will recalculate each time through. ostringstream oss; if (name_.empty()) { - setText(_("undefined")); + gui = _("undefined"); + info(from_ascii("undefined"), lang); break; } // FIXME this uses the serialization mechanism to get the info @@ -354,14 +374,16 @@ void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype) { lyxrc.write(oss, true, name_); string result = oss.str(); if (result.size() < 2) { - setText(_("undefined")); + gui = _("undefined"); + info(from_ascii("undefined"), lang); break; } string::size_type loc = result.rfind("\n", result.size() - 2); loc = loc == string::npos ? 0 : loc + 1; if (result.size() < loc + name_.size() + 1 || result.substr(loc + 1, name_.size()) != name_) { - setText(_("undefined")); + gui = _("undefined"); + info(from_ascii("undefined"), lang); break; } // remove leading comments and \\name and space @@ -370,7 +392,7 @@ void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype) { // remove \n and "" result = rtrim(result, "\n"); result = trim(result, "\""); - setText(from_utf8(result)); + setText(from_utf8(result), lang); break; } case PACKAGE_INFO: @@ -378,7 +400,13 @@ void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype) { if (initialized_) break; // check in packages.lst - setText(LaTeXFeatures::isAvailable(name_) ? _("yes") : _("no")); + if (LaTeXFeatures::isAvailable(name_)) { + gui = _("yes"); + info(from_ascii("yes"), lang); + } else { + gui = _("no"); + info(from_ascii("no"), lang); + } initialized_ = true; break; @@ -389,7 +417,13 @@ void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype) { // name_ is the class name if (list.haveClass(name_)) available = list[name_].isTeXClassAvailable(); - setText(available ? _("yes") : _("no")); + if (available) { + gui = _("yes"); + info(from_ascii("yes"), lang); + } else { + gui = _("no"); + info(from_ascii("no"), lang); + } break; } case MENU_INFO: { @@ -401,22 +435,26 @@ void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype) { docstring_list names; FuncRequest const func = lyxaction.lookupFunc(name_); if (func.action() == LFUN_UNKNOWN_ACTION) { - error("Unknown action %1$s"); + gui = _("Unknown action %1$s"); + error(from_ascii("Unknown action %1$s"), lang); break; } // iterate through the menubackend to find it if (!theApp()) { - error("Can't determine menu entry for action %1$s in batch mode"); + gui = _("Can't determine menu entry for action %1$s in batch mode"); + error(from_ascii("Can't determine menu entry for action %1$s in batch mode"), lang); break; } if (!theApp()->searchMenu(func, names)) { - error("No menu entry for action %1$s"); + gui = _("No menu entry for action %1$s"); + error(from_ascii("No menu entry for action %1$s"), lang); break; } // if found, return its path. clear(); Paragraph & par = paragraphs().front(); - Font const f(inherit_font, buffer().params().language); + Font const f(inherit_font, guilang); + force_ltr_ = !guilang->rightToLeft(); //Font fu = f; //fu.fontInfo().setUnderbar(FONT_ON); for (docstring const & name : names) { @@ -479,7 +517,7 @@ void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype) { igp.width = Length(1, Length::EM); inset->setParams(igp); clear(); - Font const f(inherit_font, buffer().params().language); + Font const f(inherit_font, lang); paragraphs().front().insertInset(0, inset, f, Change(Change::UNCHANGED)); break; @@ -487,15 +525,15 @@ void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype) { case BUFFER_INFO: { // this could all change, so we will recalculate each time if (name_ == "name") { - setText(from_utf8(buffer().fileName().onlyFileName())); + setText(from_utf8(buffer().fileName().onlyFileName()), lang); break; } if (name_ == "path") { - setText(from_utf8(os::latex_path(buffer().filePath()))); + setText(from_utf8(os::latex_path(buffer().filePath())), lang); break; } if (name_ == "class") { - setText(from_utf8(bp.documentClass().name())); + setText(from_utf8(bp.documentClass().name()), lang); break; } @@ -506,7 +544,8 @@ void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype) { // this information could change, in principle, so we will // recalculate each time through if (!buffer().lyxvc().inUse()) { - setText(_("No version control")); + gui = _("No version control"); + info(from_ascii("No version control"), lang); break; } LyXVC::RevisionInfo itype = LyXVC::Unknown; @@ -521,10 +560,11 @@ void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype) { else if (name_ == "vcs-date") itype = LyXVC::Date; string binfo = buffer().lyxvc().revisionInfo(itype); - if (binfo.empty()) - setText(from_ascii(name_) + " unknown"); - else - setText(from_utf8(binfo)); + if (binfo.empty()) { + gui = _("%1$s[[vcs data]] unknown"); + error(from_ascii("%1$s[[vcs data]] unknown"), lang); + } else + setText(from_utf8(binfo), lang); break; } case LYX_INFO: @@ -532,10 +572,12 @@ void InsetInfo::updateBuffer(ParIterator const & it, UpdateType utype) { if (initialized_) break; if (name_ == "version") - setText(from_ascii(lyx_version)); + setText(from_ascii(lyx_version), lang); initialized_ = true; break; } + // Just to do something with that string + LYXERR(Debug::INFO, "info inset text: " << gui); InsetCollapsible::updateBuffer(it, utype); } diff --git a/src/insets/InsetInfo.h b/src/insets/InsetInfo.h index 9ac63489fb..c553062952 100644 --- a/src/insets/InsetInfo.h +++ b/src/insets/InsetInfo.h @@ -144,9 +144,11 @@ private: /// virtual Inset * clone() const { return new InsetInfo(*this); } /// - void error(std::string const & err); + void error(docstring const & err, Language const *); /// - void setText(docstring const & str); + void info(docstring const & err, Language const *); + /// + void setText(docstring const & str, Language const *); // make sure that the other version of setText is still available. using InsetCollapsible::setText; /// -- 2.39.5