#include "graphics/GraphicsCache.h"
#include "graphics/PreviewLoader.h"
+#include "frontends/Application.h"
#include "frontends/alert.h"
#include "frontends/Delegates.h"
#include "frontends/WorkAreaManager.h"
if (!cloned_buffer_) {
temppath = createBufferTmpDir();
lyxvc.setBuffer(owner_);
+ Language const * inplang = languages.getFromCode(theApp()->inputLanguageCode());
+ if (inplang)
+ params.language = inplang;
if (use_gui)
wa_ = new frontend::WorkAreaManager;
return;
}
+void BufferView::setCursorLanguage(std::string const & code)
+{
+ Language const * lang = languages.getFromCode(code, buffer_.getLanguages());
+ if (lang) {
+ d->cursor_.current_font.setLanguage(lang);
+ d->cursor_.real_current_font.setLanguage(lang);
+ } else
+ LYXERR0("setCursorLanguage: unknown language code " << code);
+}
+
+
bool BufferView::singleParUpdate()
{
Text & buftext = buffer_.text();
/// sets cursor.
/// This is used when handling LFUN_MOUSE_PRESS.
bool mouseSetCursor(Cursor & cur, bool select = false);
+ /// Set the cursor language from language code.
+ /* Considers first exact math with the codes used in the document,
+ * then approximate match among the same list, and finally exact
+ * or partial match with the whole list of languages.
+ */
+ void setCursorLanguage(std::string const & code);
/// sets the selection.
/* When \c backwards == false, set anchor
enum Match {
NoMatch,
ApproximateMatch,
+ VeryApproximateMatch,
ExactMatch
};
if ((code.size() == 2) && (langcode.size() > 2)
&& (code + '_' == langcode.substr(0, 3)))
return ApproximateMatch;
+ if (code.substr(0,2) == langcode.substr(0,2))
+ return VeryApproximateMatch;
return NoMatch;
}
Language const * Languages::getFromCode(string const & code) const
{
- // Try for exact match first
+ // 1/ exact match with any known language
for (auto const & l : languagelist_) {
if (match(code, l.second) == ExactMatch)
return &l.second;
}
- // If not found, look for lang prefix (without country) instead
+
+ // 2/ approximate with any known language
for (auto const & l : languagelist_) {
if (match(code, l.second) == ApproximateMatch)
return &l.second;
}
- LYXERR0("Unknown language `" + code + "'");
+ return 0;
+}
+
+
+Language const * Languages::getFromCode(string const & code,
+ set<Language const *> const & tryfirst) const
+{
+ // 1/ exact match with tryfirst list
+ for (auto const * lptr : tryfirst) {
+ if (match(code, *lptr) == ExactMatch)
+ return lptr;
+ }
+
+ // 2/ approximate match with tryfirst list
+ for (auto const * lptr : tryfirst) {
+ Match const m = match(code, *lptr);
+ if (m == ApproximateMatch || m == VeryApproximateMatch)
+ return lptr;
+ }
+
+ // 3/ stricter match in all languages
+ return getFromCode(code);
+
+ LYXERR0("Unknown language `" << code << "'");
return 0;
}
#include "support/trivstring.h"
#include <map>
+#include <set>
#include <vector>
///
Language const * getFromCode(std::string const & code) const;
///
+ Language const * getFromCode(std::string const & code,
+ std::set<Language const *> const & tryfirst) const;
+ ///
void readLayoutTranslations(support::FileName const & filename);
///
Language const * getLanguage(std::string const & language) const;
/// \return the math icon name for the given command.
static docstring mathIcon(docstring const & c);
+ /// The language associated to current keyboard
+ virtual std::string inputLanguageCode() const = 0;
/// Handle a accented char key sequence
/// FIXME: this is only needed for LFUN_ACCENT_* in Text::dispatch()
virtual void handleKeyFunc(FuncCode action) = 0;
if (lyxrc.typewriter_font_name.empty())
lyxrc.typewriter_font_name = fromqstr(typewriterFontName());
+#if (QT_VERSION >= 0x050000)
+ // Qt4 does this in event(), see below.
+ // Track change of keyboard
+ connect(inputMethod(), SIGNAL(localeChanged()), this, SLOT(onLocaleChanged()));
+#endif
+
d->general_timer_.setInterval(500);
connect(&d->general_timer_, SIGNAL(timeout()),
this, SLOT(handleRegularEvents()));
}
+string GuiApplication::inputLanguageCode() const
+{
+#if (QT_VERSION < 0x050000)
+ QLocale loc = keyboardInputLocale();
+#else
+ QLocale loc = inputMethod()->locale();
+#endif
+ //LYXERR0("input lang = " << fromqstr(loc.name()));
+ return fromqstr(loc.name());
+}
+
+
+void GuiApplication::onLocaleChanged()
+{
+ //LYXERR0("Change language to " << inputLanguage()->lang());
+ if (currentView() && currentView()->currentBufferView())
+ currentView()->currentBufferView()->setCursorLanguage(inputLanguageCode());
+}
+
+
void GuiApplication::handleKeyFunc(FuncCode action)
{
char_type c = 0;
e->accept();
return true;
}
+#if (QT_VERSION < 0x050000)
+ // Qt5 uses a signal for that, see above.
+ case QEvent::KeyboardLayoutChange:
+ //LYXERR0("keyboard change");
+ if (currentView() && currentView()->currentBufferView())
+ currentView()->currentBufferView()->setCursorLanguage(inputLanguageCode());
+ e->accept();
+ return true;
+#endif
default:
return QApplication::event(e);
}
void unregisterSocketCallback(int fd) override;
bool searchMenu(FuncRequest const & func, docstring_list & names) const override;
bool hasBufferView() const override;
+ std::string inputLanguageCode() const override;
void handleKeyFunc(FuncCode action) override;
bool unhide(Buffer * buf) override;
//@}
///
void onLastWindowClosed();
///
+ void onLocaleChanged();
+ ///
void slotProcessFuncRequestQueue() { processFuncRequestQueue(); }
private: