Jürgen Spitzmüller wrote: > > Agreed. However, currently language switching is far too cumbersome: > > > > a) Edit>Text-style>Custom>...>select from an "endless" list, or > > > > b) M-x language ... (where you need to know the correct name of the > > desired language) > > I could not agree more. Personally, I have defined shortcuts for the > languages I need most frequently. > > I had the following idea for an UI: add a (context) menu item "Set > language" that lists the currently used languages and an accelerator for > the character dialog.
Here's the patch. Jürgen
Index: src/Buffer.h =================================================================== --- src/Buffer.h (Revision 33361) +++ src/Buffer.h (Arbeitskopie) @@ -375,6 +375,8 @@ /// bool isMultiLingual() const; + /// + std::set<Language const *> getLanguages() const; /// BufferParams & params(); Index: src/frontends/qt4/Menus.cpp =================================================================== --- src/frontends/qt4/Menus.cpp (Revision 33361) +++ 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,35 @@ } +void MenuDefinition::expandLanguageSelector(Buffer const * buf) +{ + if (!buf) + return; + + std::set<Language const *> languages = buf->getLanguages(); + + if (languages.size() < 2) { + add(MenuItem(MenuItem::Command, qt_("Set Language ..."), + FuncRequest(LFUN_DIALOG_SHOW, "character"))); + return; + } + + MenuItem item(MenuItem::Submenu, qt_("Set Language")); + item.setSubmenu(MenuDefinition(qt_("Set 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 +1691,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 33361) +++ 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 33361) +++ src/Text3.cpp (Arbeitskopie) @@ -2547,7 +2547,10 @@ } case LFUN_LANGUAGE: - enable = !cur.inset().getLayout().isPassThru(); + if (cur.inset().getLayout().isPassThru()) + enable = false; + else + 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 33361) +++ src/Buffer.cpp (Arbeitskopie) @@ -2172,6 +2172,16 @@ } +std::set<Language const *> Buffer::getLanguages() const +{ + std::set<Language const *> languages; + ParConstIterator end = par_iterator_end(); + for (ParConstIterator it = par_iterator_begin(); it != end; ++it) + it->getLanguages(languages); + return languages; +} + + DocIterator Buffer::getParFromID(int const id) const { Buffer * buf = const_cast<Buffer *>(this); Index: src/Paragraph.h =================================================================== --- src/Paragraph.h (Revision 33361) +++ 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 *> & languages) 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 33361) +++ 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 33361) +++ 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