Jürgen Spitzmüller wrote: > Here's the patch. polished version that also handles multipart documents.
Jürgen
Index: src/Buffer.h =================================================================== --- src/Buffer.h (Revision 33363) +++ src/Buffer.h (Arbeitskopie) @@ -375,6 +375,8 @@ /// bool isMultiLingual() const; + /// + std::set<Language const *> getLanguages() const; /// BufferParams & params(); @@ -572,6 +574,8 @@ */ ReadStatus readFile(Lexer &, support::FileName const & filename, bool fromString = false); + /// + void getLanguages(std::set<Language const *> &) const; /// Use the Pimpl idiom to hide the internals. class Impl; Index: src/frontends/qt4/Menus.cpp =================================================================== --- src/frontends/qt4/Menus.cpp (Revision 33363) +++ src/frontends/qt4/Menus.cpp (Arbeitskopie) @@ -38,6 +38,7 @@ #include "FuncStatus.h" #include "IndicesList.h" #include "KeyMap.h" +#include "Language.h" #include "Lexer.h" #include "LyXAction.h" #include "LyX.h" // for lastfiles @@ -164,7 +165,9 @@ /** Available graphics groups */ GraphicsGroups, /// Words suggested by the spellchecker. - SpellingSuggestions + SpellingSuggestions, + /** Used Languages */ + LanguageSelector }; explicit MenuItem(Kind kind) : kind_(kind), optional_(false) {} @@ -322,6 +325,7 @@ void expandCiteStyles(BufferView const *); void expandGraphicsGroups(BufferView const *); void expandSpellingSuggestions(BufferView const *); + void expandLanguageSelector(Buffer const * buf); /// ItemList items_; /// @@ -428,7 +432,8 @@ md_pasterecent, md_toolbars, md_graphicsgroups, - md_spellingsuggestions + md_spellingsuggestions, + md_languageselector }; LexerKeyword menutags[] = { @@ -450,6 +455,7 @@ { "indiceslists", md_indiceslists }, { "indiceslistscontext", md_indiceslistscontext }, { "item", md_item }, + { "languageselector", md_languageselector }, { "lastfiles", md_lastfiles }, { "optitem", md_optitem }, { "optsubmenu", md_optsubmenu }, @@ -568,6 +574,10 @@ add(MenuItem(MenuItem::SpellingSuggestions)); break; + case md_languageselector: + add(MenuItem(MenuItem::LanguageSelector)); + break; + case md_indices: add(MenuItem(MenuItem::Indices)); break; @@ -754,6 +764,36 @@ } +void MenuDefinition::expandLanguageSelector(Buffer const * buf) +{ + if (!buf) + return; + + std::set<Language const *> languages = + buf->masterBuffer()->getLanguages(); + + if (languages.size() < 2) { + add(MenuItem(MenuItem::Command, qt_("Language ...|L"), + FuncRequest(LFUN_DIALOG_SHOW, "character"))); + return; + } + + MenuItem item(MenuItem::Submenu, qt_("Language|L")); + item.setSubmenu(MenuDefinition(qt_("Language"))); + std::set<Language const *>::const_iterator const begin = languages.begin(); + for (std::set<Language const *>::const_iterator cit = begin; + cit != languages.end(); ++cit) { + MenuItem w(MenuItem::Command, qt_((*cit)->display()), + FuncRequest(LFUN_LANGUAGE, (*cit)->lang())); + item.submenu().addWithStatusCheck(w); + } + item.submenu().add(MenuItem(MenuItem::Separator)); + item.submenu().add(MenuItem(MenuItem::Command, qt_("More Languages ..."), + FuncRequest(LFUN_DIALOG_SHOW, "character"))); + add(item); +} + + void MenuDefinition::expandLastfiles() { LastFilesSection::LastFiles const & lf = theSession().lastFiles().lastFiles(); @@ -1652,6 +1692,10 @@ tomenu.expandSpellingSuggestions(bv); break; + case MenuItem::LanguageSelector: + tomenu.expandLanguageSelector(buf); + break; + case MenuItem::Submenu: { MenuItem item(*cit); item.setSubmenu(MenuDefinition(cit->submenuname())); Index: src/Paragraph.cpp =================================================================== --- src/Paragraph.cpp (Revision 33363) +++ src/Paragraph.cpp (Arbeitskopie) @@ -2603,7 +2603,7 @@ bool Paragraph::isMultiLingual(BufferParams const & bparams) const { - Language const * doc_language = bparams.language; + Language const * doc_language = bparams.language; FontList::const_iterator cit = d->fontlist_.begin(); FontList::const_iterator end = d->fontlist_.end(); @@ -2616,6 +2616,20 @@ } +void Paragraph::getLanguages(std::set<Language const *> & languages) const +{ + FontList::const_iterator cit = d->fontlist_.begin(); + FontList::const_iterator end = d->fontlist_.end(); + + for (; cit != end; ++cit) { + Language const * lang = cit->font().language(); + if (lang != ignore_language && + lang != latex_language) + languages.insert(lang); + } +} + + docstring Paragraph::asString(int options) const { return asString(0, size(), options); Index: src/Text3.cpp =================================================================== --- src/Text3.cpp (Revision 33363) +++ src/Text3.cpp (Arbeitskopie) @@ -2560,6 +2560,7 @@ case LFUN_LANGUAGE: enable = !cur.inset().getLayout().isPassThru(); + flag.setOnOff(to_utf8(cmd.argument()) == cur.real_current_font.language()->lang()); break; case LFUN_BREAK_PARAGRAPH: Index: src/Buffer.cpp =================================================================== --- src/Buffer.cpp (Revision 33363) +++ src/Buffer.cpp (Arbeitskopie) @@ -2172,6 +2172,27 @@ } +std::set<Language const *> Buffer::getLanguages() const +{ + std::set<Language const *> languages; + getLanguages(languages); + return languages; +} + + +void Buffer::getLanguages(std::set<Language const *> & languages) const +{ + ParConstIterator end = par_iterator_end(); + for (ParConstIterator it = par_iterator_begin(); it != end; ++it) + it->getLanguages(languages); + // also children + std::vector<Buffer *> clist = getChildren(); + for (vector<Buffer *>::const_iterator cit = clist.begin(); + cit != clist.end(); ++cit) + (*cit)->getLanguages(languages); +} + + DocIterator Buffer::getParFromID(int const id) const { Buffer * buf = const_cast<Buffer *>(this); Index: src/Paragraph.h =================================================================== --- src/Paragraph.h (Revision 33363) +++ src/Paragraph.h (Arbeitskopie) @@ -23,6 +23,8 @@ #include "support/strfwd.h" #include "support/types.h" +#include <set> + namespace lyx { class AuthorList; @@ -117,6 +119,8 @@ Language const * from, Language const * to); /// bool isMultiLingual(BufferParams const &) const; + /// + void getLanguages(std::set<Language const *> &) const; /// Convert the paragraph to a string. /// \param AsStringParameter options. This can contain any combination of Index: lib/ui/stdcontext.inc =================================================================== --- lib/ui/stdcontext.inc (Revision 33363) +++ lib/ui/stdcontext.inc (Arbeitskopie) @@ -315,6 +315,7 @@ Item "Apply Last Text Style|A" "textstyle-apply" Submenu "Text Style|S" "edit_textstyles" Item "Paragraph Settings...|P" "layout-paragraph" + LanguageSelector Separator Item "Fullscreen Mode" "ui-toggle fullscreen" End Index: lib/ui/stdmenus.inc =================================================================== --- lib/ui/stdmenus.inc (Revision 33363) +++ lib/ui/stdmenus.inc (Arbeitskopie) @@ -111,6 +111,7 @@ Item "Move Paragraph Down|v" "paragraph-move-down" Separator Submenu "Text Style|S" "edit_textstyles" + LanguageSelector Item "Paragraph Settings...|P" "layout-paragraph" Separator # Mathed b0rkage means these don't work properly @@ -125,7 +126,7 @@ # obvious what the context is for the others) OptItem "Increase List Depth|I" "depth-increment" OptItem "Decrease List Depth|D" "depth-decrement" - OptItem "Dissolve Inset|l" "inset-dissolve" + OptItem "Dissolve Inset" "inset-dissolve" OptItem "TeX Code Settings...|C" "inset-settings ert" # 'a' shortcut to match Insert entry, shouldn't clash with Table Settings OptItem "Float Settings...|a" "inset-settings float"