This enables the frontends to show unicode (most of the work in
MenuBackend).

Only Qt4 tested. All frontends compile.

Will commit shortly.

Index: src/lyxfunc.C
===================================================================
--- src/lyxfunc.C	(revision 14953)
+++ src/lyxfunc.C	(working copy)
@@ -1108,7 +1108,7 @@
 			break;
 
 		case LFUN_MENU_OPEN:
-			owner->getMenubar().openByName(argument);
+			owner->getMenubar().openByName(lyx::from_utf8(argument));
 			break;
 
 		// --- lyxserver commands ----------------------------
Index: src/frontends/Menubar.h
===================================================================
--- src/frontends/Menubar.h	(revision 14953)
+++ src/frontends/Menubar.h	(working copy)
@@ -13,7 +13,7 @@
 #ifndef MENUBAR_H
 #define MENUBAR_H
 
-#include <string>
+#include "support/docstring.h"
 
 /**
  * The LyX GUI independent menubar class
@@ -24,7 +24,7 @@
 	///
 	virtual ~Menubar() {}
 	/// Opens a top-level submenu given its name
-	virtual void openByName(std::string const &) = 0;
+	virtual void openByName(lyx::docstring const &) = 0;
 	/// update the state of the menuitems
 	virtual void update() = 0;
 };
Index: src/frontends/gtk/GMenubar.C
===================================================================
--- src/frontends/gtk/GMenubar.C	(revision 14953)
+++ src/frontends/gtk/GMenubar.C	(working copy)
@@ -27,8 +27,12 @@
 
 #include "debug.h"
 #include "support/lstrings.h"
+#include "support/docstring.h"
 #include "lyxfunc.h"
 
+using lyx::char_type;
+using lyx::docstring;
+
 using std::string;
 
 namespace lyx {
@@ -52,15 +56,17 @@
 };
 
 
-// ENCODING: assume that the backend will give us a locale string
-Glib::ustring labelTrans(string const & label_src, string const & shortcut)
+Glib::ustring labelTrans(docstring const & label_src,
+			 docstring const & shortcut)
 {
-	string label = subst(label_src, "_", "__");
-	string::size_type i = label.find(shortcut);
-	if (i == string::npos)
-		return Glib::locale_to_utf8 (label);
-	label.insert(i, "_");
-	return Glib::locale_to_utf8 (label);
+	docstring label = subst(label_src,
+				lyx::from_ascii("_"),
+				lyx::from_ascii("__"));
+	docstring::size_type i = label.find(shortcut);
+	if (i == docstring::npos)
+		return lyx::to_utf8(label);
+	label.insert(i, lyx::from_ascii("_"));
+	return lyx::to_utf8(label);
 }
 
 
@@ -104,7 +110,7 @@
 		menubar_.items().back().signal_activate().connect(
 			sigc::bind(sigc::mem_fun(*this, &GMenubar::onSubMenuActivate), &(*i),
 				   &menubar_.items().back()));
-		mainMenuNames_.push_back(i->submenuname());
+		mainMenuNames_.push_back(lyx::to_utf8(i->submenuname()));
 	}
 	menubar_.show();
 	gview->getBox(GView::Top).children().push_back(
@@ -123,9 +129,9 @@
 }
 
 
-void GMenubar::openByName(string const & name)
+void GMenubar::openByName(docstring const & name)
 {
-	Glib::ustring uname = Glib::convert(name, "UTF-8", "ISO-8859-1");
+	Glib::ustring uname = lyx::to_utf8(name);
 	std::vector<Glib::ustring>::iterator it =
 		std::find(mainMenuNames_.begin(), mainMenuNames_.end(),
 			  uname);
@@ -136,7 +142,7 @@
 		return;
 	}
 	lyxerr << "GMenubar::openByName: menu "
-	       << name << " not found" << std::endl;
+	       << lyx::to_utf8(name) << " not found" << std::endl;
 }
 
 
@@ -202,8 +208,8 @@
 				// Choose an icon from the funcrequest
 				Gtk::Image * image = getGTKIcon(i->func(), Gtk::ICON_SIZE_MENU);
 				if (!image) {
-					// ENCODING, FIXME: does Pixbuf::create_from_file really 
-					// want UTF-8, or does it want filename encoding?  Is 
+					// ENCODING, FIXME: does Pixbuf::create_from_file really
+					// want UTF-8, or does it want filename encoding?  Is
 					// the backend string really in locale encoding?
 					// This shouldn't break as long as filenames are ASCII
 					Glib::ustring xpmName =
@@ -228,8 +234,9 @@
 				Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox);
 				Gtk::Label * label1 = Gtk::manage(new Gtk::Label(
 					labelTrans(i->label(), i->shortcut()), true));
-				Gtk::Label * label2 = Gtk::manage(new Gtk::Label(
-					"   " + i->binding(), false));
+				Gtk::Label * label2 =
+					Gtk::manage(new Gtk::Label(
+								   "   " + lyx::to_utf8(i->binding()), false));
 				hbox->pack_start(*label1, false, false, 0);
 				hbox->pack_end(*label2, false, false, 0);
 				imgitem->add(*hbox);
Index: src/frontends/gtk/GMenubar.h
===================================================================
--- src/frontends/gtk/GMenubar.h	(revision 14953)
+++ src/frontends/gtk/GMenubar.h	(working copy)
@@ -29,7 +29,7 @@
 	GMenubar(LyXView *, MenuBackend const &);
 	~GMenubar();
 	void update();
-	void openByName(std::string const &);
+	void openByName(lyx::docstring const &);
 private:
 	void onCommandActivate(MenuItem const * item, Gtk::MenuItem * gitem);
 	void onSubMenuActivate(MenuItem const * item, Gtk::MenuItem * gitem);
Index: src/frontends/qt3/qt_helpers.C
===================================================================
--- src/frontends/qt3/qt_helpers.C	(revision 14953)
+++ src/frontends/qt3/qt_helpers.C	(working copy)
@@ -107,7 +107,7 @@
 
 QString const toqstr(char const * str)
 {
-	return QString::fromAscii(str);
+	return QString::fromUtf8(str);
 }
 
 
Index: src/frontends/qt3/QLMenubar.C
===================================================================
--- src/frontends/qt3/QLMenubar.C	(revision 14953)
+++ src/frontends/qt3/QLMenubar.C	(working copy)
@@ -22,6 +22,8 @@
 #include <qmenubar.h>
 #include <qcursor.h>
 
+using lyx::docstring;
+
 using std::pair;
 using std::string;
 
@@ -50,7 +52,7 @@
 #endif
 }
 
-void QLMenubar::openByName(string const & name)
+void QLMenubar::openByName(docstring const & name)
 {
 	NameMap::const_iterator const cit = name_map_.find(name);
 	if (cit == name_map_.end())
Index: src/frontends/qt3/QLMenubar.h
===================================================================
--- src/frontends/qt3/QLMenubar.h	(revision 14953)
+++ src/frontends/qt3/QLMenubar.h	(working copy)
@@ -32,7 +32,7 @@
 	QLMenubar(LyXView *, MenuBackend &);
 
 	/// opens a top-level submenu given its name
-	void openByName(std::string const &);
+	void openByName(lyx::docstring const &);
 
 	/// update the state of the menuitems - not needed
 	void update();
@@ -49,7 +49,7 @@
 	/// menu controller
 	MenuBackend & menubackend_;
 
-	typedef std::map<std::string, QLPopupMenu *> NameMap;
+	typedef std::map<lyx::docstring, QLPopupMenu *> NameMap;
 
 	/// name to menu for openByName
 	NameMap name_map_;
Index: src/frontends/qt3/QLPopupMenu.C
===================================================================
--- src/frontends/qt3/QLPopupMenu.C	(revision 14953)
+++ src/frontends/qt3/QLPopupMenu.C	(working copy)
@@ -45,15 +45,17 @@
 
 namespace {
 
-string const getLabel(MenuItem const & mi)
+docstring const getLabel(MenuItem const & mi)
 {
-	string const shortcut = mi.shortcut();
-	string label = subst(mi.label(), "&", "&&");
+	docstring const shortcut = mi.shortcut();
+	docstring label = subst(mi.label(),
+				lyx::from_ascii("&"),
+				lyx::from_ascii("&&"));
 
 	if (!shortcut.empty()) {
-		string::size_type pos = label.find(shortcut);
-		if (pos != string::npos)
-			label.insert(pos, 1, '&');
+		docstring::size_type pos = label.find(shortcut);
+		if (pos != docstring::npos)
+			label.insert(pos, 1, char_type('&'));
 	}
 
 	return label;
@@ -78,7 +80,7 @@
 
 
 QLPopupMenu::QLPopupMenu(QLMenubar * owner,
-			 string const & name, bool toplevel)
+			 docstring const & name, bool toplevel)
 	: owner_(owner), name_(name)
 {
 	if (toplevel)
@@ -141,9 +143,9 @@
 				label += '\t' + key->qprint(binding.second);
 			}
 #else
-			string const binding(m->binding());
+			docstring const binding(m->binding());
 			if (!binding.empty()) {
-				label += '\t' + toqstr(binding);
+				label += char_type('\t') + toqstr(binding);
 			}
 #endif
 
Index: src/frontends/qt3/QLPopupMenu.h
===================================================================
--- src/frontends/qt3/QLPopupMenu.h	(revision 14953)
+++ src/frontends/qt3/QLPopupMenu.h	(working copy)
@@ -40,7 +40,7 @@
 	Q_OBJECT
 public:
 	QLPopupMenu(QLMenubar * owner,
-		    std::string const & name, bool toplevel);
+		    lyx::docstring const & name, bool toplevel);
 
 	/// populate the menu
 	void populate(Menu * menu);
@@ -54,7 +54,7 @@
 	QLMenubar * owner_;
 
 	/// the name of this menu
-	std::string name_;
+	lyx::docstring name_;
 
 	///
 	typedef std::vector<FuncRequest> Funcs;
Index: src/frontends/qt4/qt_helpers.C
===================================================================
--- src/frontends/qt4/qt_helpers.C	(revision 14953)
+++ src/frontends/qt4/qt_helpers.C	(working copy)
@@ -48,7 +48,7 @@
 }
 
 
-pair<string,string> parseFontName(string const & name)
+pair<string, string> parseFontName(string const & name)
 {
 	string::size_type const idx = name.find('[');
 	if (idx == string::npos || idx == 0)
@@ -60,15 +60,15 @@
 
 string widgetsToLength(QLineEdit const * input, LengthCombo const * combo)
 {
-	QString length = input->text();
+	QString const length = input->text();
 	if (length.isEmpty())
 		return string();
 
-	// don't return unit-from-choice if the input(field) contains a unit
+	// Don't return unit-from-choice if the input(field) contains a unit
 	if (isValidGlueLength(fromqstr(length)))
 		return fromqstr(length);
 
-	LyXLength::UNIT unit = combo->currentLengthItem();
+	LyXLength::UNIT const unit = combo->currentLengthItem();
 
 	return LyXLength(length.toDouble(), unit).asString();
 }
@@ -76,7 +76,7 @@
 
 LyXLength widgetsToLength(QLineEdit const * input, QComboBox const * combo)
 {
-	QString length = input->text();
+	QString const length = input->text();
 	if (length.isEmpty())
 		return LyXLength();
 
@@ -84,7 +84,7 @@
 	if (isValidGlueLength(fromqstr(length)))
 		return LyXLength(fromqstr(length));
 
-	LyXLength::UNIT unit = unitFromString(fromqstr(combo->currentText()));
+	LyXLength::UNIT const unit = unitFromString(fromqstr(combo->currentText()));
 
 	return LyXLength(length.toDouble(), unit);
 }
@@ -110,7 +110,7 @@
 
 QString const toqstr(char const * str)
 {
-	return QString::fromAscii(str);
+	return QString::fromUtf8(str);
 }
 
 
@@ -145,7 +145,7 @@
 
 docstring const qstring_to_ucs4(QString const & qstr)
 {
-	int ls = qstr.size();
+	int const ls = qstr.size();
 	docstring ucs4;
 	for (int i = 0; i < ls; ++i)
 		ucs4 += static_cast<char_type>(qstr[i].unicode());
@@ -156,7 +156,7 @@
 
 void qstring_to_ucs4(QString const & qstr, vector<char_type> & ucs4)
 {
-	int ls = qstr.size();
+	int const ls = qstr.size();
 	ucs4.clear();
 	for (int i = 0; i < ls; ++i)
 		ucs4.push_back(static_cast<boost::uint32_t>(qstr[i].unicode()));
@@ -177,13 +177,13 @@
 
 QString const qt_(char const * str)
 {
-	return toqstr(lyx::to_utf8(_(str)));
+	return toqstr(_(str));
 }
 
 
 QString const qt_(string const & str)
 {
-	return toqstr(lyx::to_utf8(_(str)));
+	return toqstr(_(str));
 }
 
 
@@ -208,8 +208,10 @@
 		string::size_type const nxtpos2 = text.find('\n', curpos);
 		string::size_type const nxtpos = std::min(nxtpos1, nxtpos2);
 
-		string const word = nxtpos == string::npos ?
-			text.substr(curpos) : text.substr(curpos, nxtpos-curpos);
+		string const word =
+			nxtpos == string::npos ?
+			text.substr(curpos) :
+			text.substr(curpos, nxtpos - curpos);
 
 		bool const newline = (nxtpos2 != string::npos &&
 				      nxtpos2 < nxtpos1);
Index: src/frontends/qt4/QLToolbar.C
===================================================================
--- src/frontends/qt4/QLToolbar.C	(revision 14953)
+++ src/frontends/qt4/QLToolbar.C	(working copy)
@@ -280,7 +280,7 @@
 	for (size_t i=0; i<ActionVector.size(); ++i)
 		ActionVector[i]->update();
 
-        // emit signal
+	// emit signal
 	updated();
 }
 
Index: src/frontends/qt4/QLMenubar.C
===================================================================
--- src/frontends/qt4/QLMenubar.C	(revision 14953)
+++ src/frontends/qt4/QLMenubar.C	(working copy)
@@ -47,10 +47,10 @@
 {
 	macxMenuBarInit();
 
-	lyxerr[Debug::GUI] << "populating menu bar" << menubackend_.getMenubar().name() << endl;
+	lyxerr[Debug::GUI] << "populating menu bar" << lyx::to_utf8(menubackend_.getMenubar().name()) << endl;
 
 	if (menubackend_.getMenubar().size() == 0) {
-		lyxerr[Debug::GUI] << "\tERROR: empty menu bar" << menubackend_.getMenubar().name() << endl;
+		lyxerr[Debug::GUI] << "\tERROR: empty menu bar" << lyx::to_utf8(menubackend_.getMenubar().name()) << endl;
 		return;
 		//			continue;
 	}
@@ -68,15 +68,15 @@
 	for (; m != end; ++m) {
 
 		if (m->kind() != MenuItem::Submenu) {
-			lyxerr[Debug::GUI] << "\tERROR: not a submenu " << m->label() << endl;
+			lyxerr[Debug::GUI] << "\tERROR: not a submenu " << lyx::to_utf8(m->label()) << endl;
 			continue;
 		}
 
-		lyxerr[Debug::GUI] << "menu bar item " << m->label() << " is a submenu named " << m->submenuname() << endl;
+		lyxerr[Debug::GUI] << "menu bar item " << lyx::to_utf8(m->label()) << " is a submenu named " << lyx::to_utf8(m->submenuname()) << endl;
 
-		string name = m->submenuname();
+		docstring name = m->submenuname();
 		if (!menubackend_.hasMenu(name)) {
-			lyxerr[Debug::GUI] << "\tERROR: " << name << " submenu has no menu!" << endl;
+			lyxerr[Debug::GUI] << "\tERROR: " << lyx::to_utf8(name) << " submenu has no menu!" << endl;
 			continue;
 		}
 
@@ -88,7 +88,7 @@
 
 		pair<NameMap::iterator, bool> I = name_map_.insert(make_pair(name, qMenu));
 		if (!I.second) {
-			lyxerr[Debug::GUI] << "\tERROR: " << name << " submenu is already there!" << endl;
+			lyxerr[Debug::GUI] << "\tERROR: " << lyx::to_utf8(name) << " submenu is already there!" << endl;
 		}
 /*
 		QObject::connect(qMenu, SIGNAL(aboutToShow()), this, SLOT(update()));
@@ -99,7 +99,7 @@
 	//QObject::connect(owner_->menuBar(), SIGNAL(triggered()), this, SLOT(update()));
 }
 
-void QLMenubar::openByName(string const & name)
+void QLMenubar::openByName(docstring const & name)
 {
 	NameMap::const_iterator const cit = name_map_.find(name);
 	if (cit == name_map_.end())
Index: src/frontends/qt4/QLMenubar.h
===================================================================
--- src/frontends/qt4/QLMenubar.h	(revision 14953)
+++ src/frontends/qt4/QLMenubar.h	(working copy)
@@ -41,7 +41,7 @@
 	QLMenubar(LyXView *, MenuBackend &);
 
 	/// opens a top-level submenu given its name
-	void openByName(std::string const &);
+	void openByName(lyx::docstring const &);
 
 	/// return the owning view
 	GuiView * view();
@@ -69,7 +69,7 @@
 	/// menu controller
 	MenuBackend & menubackend_;
 
-	typedef std::map<std::string, QLPopupMenu *> NameMap;
+	typedef std::map<lyx::docstring, QLPopupMenu *> NameMap;
 
 	/// name to menu for openByName
 	NameMap name_map_;
Index: src/frontends/qt4/QLPopupMenu.C
===================================================================
--- src/frontends/qt4/QLPopupMenu.C	(revision 14953)
+++ src/frontends/qt4/QLPopupMenu.C	(working copy)
@@ -67,7 +67,7 @@
 void QLPopupMenu::update()
 {
 	lyxerr[Debug::GUI] << BOOST_CURRENT_FUNCTION << endl;
-	lyxerr[Debug::GUI] << "\tTriggered menu: " << name_ << endl;
+	lyxerr[Debug::GUI] << "\tTriggered menu: " << lyx::to_utf8(name_) << endl;
 
 	clear();
 
@@ -78,7 +78,7 @@
 	owner_->backend().expand(fromLyxMenu, topLevelMenu_, owner_->view());
 
 	if (!owner_->backend().hasMenu(topLevelMenu_.name())) {
-		lyxerr[Debug::GUI] << "\tWARNING: menu seems empty" << topLevelMenu_.name() << endl;
+		lyxerr[Debug::GUI] << "\tWARNING: menu seems empty" << lyx::to_utf8(topLevelMenu_.name()) << endl;
 	}
 	populate(this, &topLevelMenu_);
 
@@ -87,9 +87,9 @@
 
 void QLPopupMenu::populate(QMenu* qMenu, Menu * menu)
 {
-	lyxerr[Debug::GUI] << "populating menu " << menu->name() ;
+	lyxerr[Debug::GUI] << "populating menu " << lyx::to_utf8(menu->name()) ;
 	if (menu->size() == 0) {
-		lyxerr[Debug::GUI] << "\tERROR: empty menu " << menu->name() << endl;
+		lyxerr[Debug::GUI] << "\tERROR: empty menu " << lyx::to_utf8(menu->name()) << endl;
 		return;
 	}
 	else {
@@ -108,46 +108,48 @@
 
 		} else if (m->kind() == MenuItem::Submenu) {
 
-			lyxerr[Debug::GUI] << "** creating New Sub-Menu " << getLabel(*m) << endl;
+			lyxerr[Debug::GUI] << "** creating New Sub-Menu " << lyx::to_utf8(getLabel(*m)) << endl;
 			QMenu * subMenu = qMenu->addMenu(toqstr(getLabel(*m)));
 			populate(subMenu, m->submenu());
 
 		} else { // we have a MenuItem::Command
 
-			lyxerr[Debug::GUI] << "creating Menu Item " << m->label() << endl;
+			lyxerr[Debug::GUI] << "creating Menu Item " << lyx::to_utf8(m->label()) << endl;
 
-			string label = getLabel(*m);
+			docstring label = getLabel(*m);
 			addBinding(label, *m);
 
-			Action * action = new Action(*(owner_->view()), 
-						     label, m->func());
+			Action * action = new Action(*(owner_->view()),
+						     lyx::to_utf8(label), m->func());
 			qMenu->addAction(action);
 		}
 	}
 }
 
-string const QLPopupMenu::getLabel(MenuItem const & mi)
+docstring const QLPopupMenu::getLabel(MenuItem const & mi)
 {
-	string const shortcut = mi.shortcut();
-	string label = support::subst(mi.label(), "&", "&&");
+	docstring const shortcut = mi.shortcut();
+	docstring label = support::subst(mi.label(),
+				      lyx::from_ascii("&"),
+				      lyx::from_ascii("&&"));
 
 	if (!shortcut.empty()) {
-		string::size_type pos = label.find(shortcut);
-		if (pos != string::npos)
-			label.insert(pos, 1, '&');
+		docstring::size_type pos = label.find(shortcut);
+		if (pos != docstring::npos)
+			label.insert(pos, 1, char_type('&'));
 	}
 
 	return label;
 }
 
 /// \todo Mac specific binding handling.
-void QLPopupMenu::addBinding(string & label, MenuItem const & mi)
+void QLPopupMenu::addBinding(docstring & label, MenuItem const & mi)
 {
 #ifndef Q_WS_MACX
 
-		string const binding(mi.binding());
+		docstring const binding(mi.binding());
 		if (!binding.empty()) {
-			label += '\t' + binding;
+			label += char_type('\t') + binding;
 		}
 
 #else
Index: src/frontends/qt4/QLPopupMenu.h
===================================================================
--- src/frontends/qt4/QLPopupMenu.h	(revision 14953)
+++ src/frontends/qt4/QLPopupMenu.h	(working copy)
@@ -17,9 +17,6 @@
 #include "funcrequest.h"
 #include "MenuBackend.h"
 
-#include <utility>
-#include <string>
-
 namespace lyx {
 namespace frontend {
 
@@ -46,15 +43,15 @@
 	QLMenubar * owner_;
 
 	/// the name of this menu
-	std::string name_;
+	lyx::docstring name_;
 
 private:
 	/// Get a Menu item label from the menu backend
-	std::string const getLabel(MenuItem const & mi);
+	lyx::docstring const getLabel(MenuItem const & mi);
 
 	/// add binding keys a the menu item label.
 	/// \todo Mac specific binding handling.
-	void addBinding(std::string & label, MenuItem const & mi);
+	void addBinding(lyx::docstring & label, MenuItem const & mi);
 
 	/// Top Level Menu
 	Menu topLevelMenu_;
Index: src/support/lstrings.C
===================================================================
--- src/support/lstrings.C	(revision 14953)
+++ src/support/lstrings.C	(working copy)
@@ -68,6 +68,28 @@
 }
 
 
+int compare_no_case(docstring const & s, docstring const & s2)
+{
+	docstring::const_iterator p = s.begin();
+	docstring::const_iterator p2 = s2.begin();
+
+	while (p != s.end() && p2 != s2.end()) {
+		int const lc1 = tolower(*p);
+		int const lc2 = tolower(*p2);
+		if (lc1 != lc2)
+			return (lc1 < lc2) ? -1 : 1;
+		++p;
+		++p2;
+	}
+
+	if (s.size() == s2.size())
+		return 0;
+	if (s.size() < s2.size())
+		return -1;
+	return 1;
+}
+
+
 namespace {
 	int ascii_tolower(int c) {
 		if (c >= 'A' && c <= 'Z')
@@ -210,7 +232,7 @@
 {
 	if (c >= 256)
 		return c;
-	
+
 	return tolower(c);
 }
 
@@ -345,6 +367,28 @@
 }
 
 
+docstring const token(docstring const & a, char_type delim, int n)
+{
+	if (a.empty()) return docstring();
+
+	string::size_type k = 0;
+	string::size_type i = 0;
+
+	// Find delimiter or end of string
+	for (; n--;)
+		if ((i = a.find(delim, i)) == docstring::npos)
+			break;
+		else
+			++i; // step delim
+	// i is now the n'th delim (or string::npos)
+	if (i == docstring::npos) return docstring();
+	k = a.find(delim, i);
+	// k is now the n'th + 1 delim (or string::npos)
+
+	return a.substr(i, k - i);
+}
+
+
 // this could probably be faster and/or cleaner, but it seems to work (JMarc)
 // rewritten to use new string (Lgb)
 int tokenPos(string const & a, char delim, string const & tok)
Index: src/support/lstrings.h
===================================================================
--- src/support/lstrings.h	(revision 14953)
+++ src/support/lstrings.h	(working copy)
@@ -26,6 +26,7 @@
 
 ///
 int compare_no_case(std::string const & s, std::string const & s2);
+int compare_no_case(lyx::docstring const & s, lyx::docstring const & s2);
 
 ///
 int compare_ascii_no_case(std::string const & s, std::string const & s2);
@@ -120,6 +121,8 @@
 */
 std::string const token(std::string const & a, char delim, int n);
 
+lyx::docstring const token(lyx::docstring const & a,
+			   lyx::char_type delim, int n);
 
 /** Search a token in this string using the delim.
     Doesn't modify the original string. Returns -1 in case of
Index: src/support/convert.C
===================================================================
--- src/support/convert.C	(revision 14953)
+++ src/support/convert.C	(working copy)
@@ -13,10 +13,14 @@
 
 #include "convert.h"
 
+#include "support/docstring.h"
+
 #include <boost/lexical_cast.hpp>
 
 #include <string>
 
+using lyx::docstring;
+
 using boost::lexical_cast;
 
 using std::string;
@@ -49,6 +53,11 @@
 	return lexical_cast<string>(i);
 }
 
+template<>
+docstring convert<docstring>(int i)
+{
+	return lyx::from_ascii(lexical_cast<string>(i));
+}
 
 template<>
 string convert<string>(unsigned int ui)
Index: src/MenuBackend.C
===================================================================
--- src/MenuBackend.C	(revision 14953)
+++ src/MenuBackend.C	(working copy)
@@ -47,6 +47,9 @@
 
 #include <algorithm>
 
+using lyx::char_type;
+using lyx::docstring;
+using lyx::support::compare_no_case;
 using lyx::support::compare_ascii_no_case;
 using lyx::support::contains;
 using lyx::support::makeDisplayPath;
@@ -71,14 +74,14 @@
 
 class MenuNamesEqual : public std::unary_function<Menu, bool> {
 public:
-	MenuNamesEqual(string const & name)
+	MenuNamesEqual(docstring const & name)
 		: name_(name) {}
 	bool operator()(Menu const & menu) const
 	{
 		return menu.name() == name_;
 	}
 private:
-	string name_;
+	docstring name_;
 };
 
 } // namespace anon
@@ -93,8 +96,8 @@
 {}
 
 
-MenuItem::MenuItem(Kind kind, string const & label,
-		   string const & submenu, bool optional)
+MenuItem::MenuItem(Kind kind, docstring const & label,
+		   docstring const & submenu, bool optional)
 	: kind_(kind), label_(label),
 	  submenuname_(submenu), optional_(optional)
 {
@@ -102,7 +105,7 @@
 }
 
 
-MenuItem::MenuItem(Kind kind, string const & label,
+MenuItem::MenuItem(Kind kind, docstring const & label,
 		   FuncRequest const & func, bool optional)
 	: kind_(kind), label_(label), func_(func), optional_(optional)
 {
@@ -120,35 +123,35 @@
 }
 
 
-string const MenuItem::label() const
+docstring const MenuItem::label() const
 {
-	return token(label_, '|', 0);
+	return token(label_, char_type('|'), 0);
 }
 
 
-string const MenuItem::shortcut() const
+docstring const MenuItem::shortcut() const
 {
-	return token(label_, '|', 1);
+	return token(label_, char_type('|'), 1);
 }
 
 
-string const MenuItem::binding() const
+docstring const MenuItem::binding() const
 {
 	if (kind_ != Command)
-		return string();
+		return docstring();
 
 	// Get the keys bound to this action, but keep only the
 	// first one later
 	kb_keymap::Bindings bindings = toplevel_keymap->findbindings(func_);
 
 	if (bindings.size()) {
-		return bindings.begin()->print();
+		return lyx::from_utf8(bindings.begin()->print());
 	} else {
 		lyxerr[Debug::KBMAP]
 			<< "No binding for "
 			<< lyxaction.getActionName(func_.action)
 			<< '(' << lyx::to_utf8(func_.argument()) << ')' << endl;
-		return string();
+		return docstring();
 	}
 
 }
@@ -269,7 +272,7 @@
 			// fallback to md_item
 		case md_item: {
 			lex.next(true);
-			string const name = lyx::to_utf8(_(lex.getString()));
+			docstring const name = _(lex.getString());
 			lex.next(true);
 			string const command = lex.getString();
 			FuncRequest func = lyxaction.lookupFunc(command);
@@ -335,9 +338,9 @@
 			// fallback to md_submenu
 		case md_submenu: {
 			lex.next(true);
-			string const mlabel = lyx::to_utf8(_(lex.getString()));
+			docstring const mlabel = _(lex.getString());
 			lex.next(true);
-			string const mname = lex.getString();
+			docstring const mname = lyx::from_utf8(lex.getString());
 			add(MenuItem(MenuItem::Submenu, mlabel, mname,
 				     optional));
 			optional = false;
@@ -378,19 +381,19 @@
 	// This is a quadratic algorithm, but we do not care because
 	// menus are short enough
 	for (const_iterator it1 = begin(); it1 != end(); ++it1) {
-		string shortcut = it1->shortcut();
+		docstring shortcut = it1->shortcut();
 		if (shortcut.empty())
 			continue;
 		if (!contains(it1->label(), shortcut))
 			lyxerr << "Menu warning: menu entry \""
-			       << it1->label()
+			       << lyx::to_utf8(it1->label())
 			       << "\" does not contain shortcut `"
-			       << shortcut << "'." << endl;
+			       << lyx::to_utf8(shortcut) << "'." << endl;
 		for (const_iterator it2 = begin(); it2 != it1 ; ++it2) {
-			if (!compare_ascii_no_case(it2->shortcut(), shortcut)) {
+			if (!compare_no_case(it2->shortcut(), shortcut)) {
 				lyxerr << "Menu warning: menu entries "
-				       << '"' << it1->fulllabel()
-				       << "\" and \"" << it2->fulllabel()
+				       << '"' << lyx::to_utf8(it1->fulllabel())
+				       << "\" and \"" << lyx::to_utf8(it2->fulllabel())
 				       << "\" share the same shortcut."
 				       << endl;
 			}
@@ -399,7 +402,7 @@
 }
 
 
-void MenuBackend::specialMenu(string const &name)
+void MenuBackend::specialMenu(docstring const &name)
 {
 	if (hasMenu(name))
 		specialmenu_ = &getMenu(name);
@@ -434,9 +437,9 @@
 	int ii = 1;
 
 	for (; lfit != lf.end() && ii < 10; ++lfit, ++ii) {
-		string const label = convert<string>(ii) + ". "
-			+ makeDisplayPath((*lfit), 30)
-			+ '|' + convert<string>(ii);
+		docstring const label = convert<docstring>(ii) + lyx::from_ascii(". ")
+			+ lyx::from_utf8(makeDisplayPath((*lfit), 30))
+			+ char_type('|') + convert<docstring>(ii);
 		tomenu.add(MenuItem(MenuItem::Command, label, FuncRequest(LFUN_FILE_OPEN, (*lfit))), view);
 	}
 }
@@ -448,7 +451,7 @@
 	Strings const names = bufferlist.getFileNames();
 
 	if (names.empty()) {
-		tomenu.add(MenuItem(MenuItem::Command, lyx::to_utf8(_("No Documents Open!")),
+		tomenu.add(MenuItem(MenuItem::Command, _("No Documents Open!"),
 				    FuncRequest(LFUN_NOACTION)), view);
 		return;
 	}
@@ -457,9 +460,9 @@
 	Strings::const_iterator docit = names.begin();
 	Strings::const_iterator end = names.end();
 	for (; docit != end; ++docit, ++ii) {
-		string label = makeDisplayPath(*docit, 20);
+		docstring label = lyx::from_utf8(makeDisplayPath(*docit, 20));
 		if (ii < 10)
-			label = convert<string>(ii) + ". " + label + '|' + convert<string>(ii);
+			label = convert<docstring>(ii) + lyx::from_ascii(". ") + label + char_type('|') + convert<docstring>(ii);
 		tomenu.add(MenuItem(MenuItem::Command, label, FuncRequest(LFUN_BUFFER_SWITCH, *docit)), view);
 	}
 }
@@ -469,7 +472,7 @@
 {
 	if (!view->buffer() && kind != MenuItem::ImportFormats) {
 		tomenu.add(MenuItem(MenuItem::Command,
-				    lyx::to_utf8(_("No Documents Open!")),
+				    _("No Documents Open!"),
 				    FuncRequest(LFUN_NOACTION)),
 				    view);
 		return;
@@ -503,15 +506,15 @@
 	for (; fit != end ; ++fit) {
 		if ((*fit)->dummy())
 			continue;
-		string label = (*fit)->prettyname();
+		docstring label = lyx::from_utf8((*fit)->prettyname());
 
 		switch (kind) {
 		case MenuItem::ImportFormats:
 			if ((*fit)->name() == "text")
-				label = lyx::to_utf8(_("Plain Text as Lines"));
+				label = _("Plain Text as Lines");
 			else if ((*fit)->name() == "textparagraph")
-				label = lyx::to_utf8(_("Plain Text as Paragraphs"));
-			label += "...";
+				label = _("Plain Text as Paragraphs");
+			label += lyx::from_ascii("...");
 			break;
 		case MenuItem::ViewFormats:
 		case MenuItem::ExportFormats:
@@ -524,7 +527,7 @@
 			break;
 		}
 		if (!(*fit)->shortcut().empty())
-			label += '|' + (*fit)->shortcut();
+			label += char_type('|') + lyx::from_utf8((*fit)->shortcut());
 
 		tomenu.add(MenuItem(MenuItem::Command, label,
 				    FuncRequest(action, (*fit)->name())),
@@ -537,7 +540,7 @@
 {
 	if (!view->buffer()) {
 		tomenu.add(MenuItem(MenuItem::Command,
-				    lyx::to_utf8(_("No Documents Open!")),
+				    _("No Documents Open!"),
 				    FuncRequest(LFUN_NOACTION)),
 			   view);
 		return;
@@ -549,7 +552,7 @@
 	FloatList::const_iterator end = floats.end();
 	for (; cit != end; ++cit) {
 		tomenu.add(MenuItem(MenuItem::Command,
-				    lyx::to_utf8(_(cit->second.listName())),
+				    _(cit->second.listName()),
 				    FuncRequest(LFUN_FLOAT_LIST,
 						cit->second.type())),
 			   view);
@@ -561,7 +564,7 @@
 {
 	if (!view->buffer()) {
 		tomenu.add(MenuItem(MenuItem::Command,
-				    lyx::to_utf8(_("No Documents Open!")),
+				    _("No Documents Open!"),
 				    FuncRequest(LFUN_NOACTION)),
 			   view);
 		return;
@@ -573,7 +576,7 @@
 	FloatList::const_iterator end = floats.end();
 	for (; cit != end; ++cit) {
 		// normal float
-		string const label = lyx::to_utf8(_(cit->second.name()));
+		docstring const label = _(cit->second.name());
 		tomenu.add(MenuItem(MenuItem::Command, label,
 				    FuncRequest(LFUN_FLOAT_INSERT,
 						cit->second.type())),
@@ -586,7 +589,7 @@
 {
 	if (!view->buffer()) {
 		tomenu.add(MenuItem(MenuItem::Command,
-				    lyx::to_utf8(_("No Documents Open!")),
+				    _("No Documents Open!"),
 				    FuncRequest(LFUN_NOACTION)),
 			   view);
 		return;
@@ -596,7 +599,7 @@
 	CharStyles::iterator cit = charstyles.begin();
 	CharStyles::iterator end = charstyles.end();
 	for (; cit != end; ++cit) {
-		string const label = cit->name;
+		docstring const label = lyx::from_utf8(cit->name);
 		tomenu.add(MenuItem(MenuItem::Command, label,
 				    FuncRequest(LFUN_CHARSTYLE_INSERT,
 						cit->name)), view);
@@ -623,12 +626,12 @@
 
 	if (to - from <= max_number_of_items) {
 		for (lyx::toc::Toc::size_type i = from; i < to; ++i) {
-			string label(4 * max(0, toc_list[i].depth() - depth),' ');
-			label += limit_string_length(toc_list[i].str());
+			docstring label(4 * max(0, toc_list[i].depth() - depth), char_type(' '));
+			label += lyx::from_utf8(limit_string_length(toc_list[i].str()));
 			if (toc_list[i].depth() == depth
 			    && shortcut_count < 9) {
-				if (label.find(convert<string>(shortcut_count + 1)) != string::npos)
-					label += '|' + convert<string>(++shortcut_count);
+				if (label.find(convert<docstring>(shortcut_count + 1)) != docstring::npos)
+					label += char_type('|') + convert<docstring>(++shortcut_count);
 			}
 			tomenu.add(MenuItem(MenuItem::Command, label,
 					    FuncRequest(toc_list[i].action())));
@@ -641,12 +644,12 @@
 			       toc_list[new_pos].depth() > depth)
 				++new_pos;
 
-			string label(4 * max(0, toc_list[pos].depth() - depth), ' ');
-			label += limit_string_length(toc_list[pos].str());
+			docstring label(4 * max(0, toc_list[pos].depth() - depth), ' ');
+			label += lyx::from_utf8(limit_string_length(toc_list[pos].str()));
 			if (toc_list[pos].depth() == depth &&
 			    shortcut_count < 9) {
-				if (label.find(convert<string>(shortcut_count + 1)) != string::npos)
-					label += '|' + convert<string>(++shortcut_count);
+				if (label.find(convert<docstring>(shortcut_count + 1)) != docstring::npos)
+					label += char_type('|') + convert<docstring>(++shortcut_count);
 				}
 			if (new_pos == pos + 1) {
 				tomenu.add(MenuItem(MenuItem::Command,
@@ -675,7 +678,7 @@
 	Buffer const * buf = view->buffer();
 	if (!buf) {
 		tomenu.add(MenuItem(MenuItem::Command,
-				    lyx::to_utf8(_("No Documents Open!")),
+				    _("No Documents Open!"),
 				    FuncRequest(LFUN_NOACTION)),
 			   view);
 		return;
@@ -695,13 +698,13 @@
 		lyx::toc::Toc::const_iterator ccit = cit->second.begin();
 		lyx::toc::Toc::const_iterator eend = cit->second.end();
 		for (; ccit != eend; ++ccit) {
-			string const label = limit_string_length(ccit->str());
+			docstring const label = lyx::from_utf8(limit_string_length(ccit->str()));
 			menu->add(MenuItem(MenuItem::Command,
 					   label,
 					   FuncRequest(ccit->action())));
 		}
 		string const & floatName = floatlist.getType(cit->first).listName();
-		MenuItem item(MenuItem::Submenu, lyx::to_utf8(_(floatName)));
+		MenuItem item(MenuItem::Submenu, _(floatName));
 		item.submenu(menu.release());
 		tomenu.add(item);
 	}
@@ -710,7 +713,7 @@
 	cit = toc_list.find("TOC");
 	if (cit == end) {
 		tomenu.add(MenuItem(MenuItem::Command,
-				    lyx::to_utf8(_("No Table of contents")),
+				    _("No Table of contents"),
 				    FuncRequest()),
 			   view);
 	} else {
@@ -731,7 +734,7 @@
 	vector<string>::const_iterator end = sel.end();
 
 	for (unsigned int index = 0; cit != end; ++cit, ++index) {
-		tomenu.add(MenuItem(MenuItem::Command, *cit,
+		tomenu.add(MenuItem(MenuItem::Command, lyx::from_utf8(*cit),
 				    FuncRequest(LFUN_PASTE, convert<string>(index))));
 	}
 }
@@ -748,9 +751,9 @@
 	BranchList::const_iterator end = params.branchlist().end();
 
 	for (int ii = 1; cit != end; ++cit, ++ii) {
-		string label = cit->getBranch();
+		docstring label = lyx::from_utf8(cit->getBranch());
 		if (ii < 10)
-			label = convert<string>(ii) + ". " + label + "|" + convert<string>(ii);
+			label = convert<docstring>(ii) + lyx::from_ascii(". ") + label + char_type('|') + convert<docstring>(ii);
 		tomenu.add(MenuItem(MenuItem::Command, label,
 				    FuncRequest(LFUN_BRANCH_INSERT,
 						cit->getBranch())), view);
@@ -873,7 +876,7 @@
 			break;
 		case md_menu: {
 			lex.next(true);
-			string const name = lex.getString();
+			docstring const name = lyx::from_utf8(lex.getString());
 			if (hasMenu(name)) {
 				getMenu(name).read(lex);
 			} else {
@@ -902,27 +905,27 @@
 }
 
 
-bool MenuBackend::hasMenu(string const & name) const
+bool MenuBackend::hasMenu(docstring const & name) const
 {
 	return find_if(begin(), end(), MenuNamesEqual(name)) != end();
 }
 
 
-Menu const & MenuBackend::getMenu(string const & name) const
+Menu const & MenuBackend::getMenu(docstring const & name) const
 {
 	const_iterator cit = find_if(begin(), end(), MenuNamesEqual(name));
 	if (cit == end())
-		lyxerr << "No submenu named " << name << endl;
+		lyxerr << "No submenu named " << lyx::to_utf8(name) << endl;
 	BOOST_ASSERT(cit != end());
 	return (*cit);
 }
 
 
-Menu & MenuBackend::getMenu(string const & name)
+Menu & MenuBackend::getMenu(docstring const & name)
 {
 	iterator it = find_if(begin(), end(), MenuNamesEqual(name));
 	if (it == end())
-		lyxerr << "No submenu named " << name << endl;
+		lyxerr << "No submenu named " << lyx::to_utf8(name) << endl;
 	BOOST_ASSERT(it != end());
 	return (*it);
 }
Index: src/MenuBackend.h
===================================================================
--- src/MenuBackend.h	(revision 14953)
+++ src/MenuBackend.h	(working copy)
@@ -74,23 +74,23 @@
 	explicit MenuItem(Kind kind);
 
 	MenuItem(Kind kind,
-		 std::string const & label,
-		 std::string const & command = std::string(),
+		 lyx::docstring const & label,
+		 lyx::docstring const & submenu = lyx::docstring(),
 		 bool optional = false);
 
 	MenuItem(Kind kind,
-		 std::string const & label,
+		 lyx::docstring const & label,
 		 FuncRequest const & func,
 		 bool optional = false);
 
 	/// This one is just to please boost::shared_ptr<>
 	~MenuItem();
 	/// The label of a given menuitem
-	std::string const label() const;
+	lyx::docstring const label() const;
 	/// The keyboard shortcut (usually underlined in the entry)
-	std::string const shortcut() const;
+	lyx::docstring const shortcut() const;
 	/// The complete label, with label and shortcut separated by a '|'
-	std::string const fulllabel() const { return label_;}
+	lyx::docstring const fulllabel() const { return label_;}
 	/// The kind of entry
 	Kind kind() const { return kind_; }
 	/// the action (if relevant)
@@ -104,11 +104,11 @@
 	/// returns the status of the lfun associated with this entry
 	void status(FuncStatus const & status) { status_ = status; }
 	/// returns the binding associated to this action
-	std::string const binding() const;
+	lyx::docstring const binding() const;
 	/// the description of the  submenu (if relevant)
-	std::string const & submenuname() const { return submenuname_; }
+	lyx::docstring const & submenuname() const { return submenuname_; }
 	/// set the description of the  submenu
-	void submenuname(std::string const & name) { submenuname_ = name; }
+	void submenuname(lyx::docstring const & name) { submenuname_ = name; }
 	///
 	Menu * submenu() const { return submenu_.get(); }
 	///
@@ -119,11 +119,11 @@
 	///
 	Kind kind_;
 	///
-	std::string label_;
+	lyx::docstring label_;
 	///
 	FuncRequest func_;
 	///
-	std::string submenuname_;
+	lyx::docstring submenuname_;
 	///
 	bool optional_;
 	///
@@ -143,14 +143,14 @@
 	///
 	typedef ItemList::size_type size_type;
 	///
-	explicit Menu(std::string const & name = std::string())
+	explicit Menu(lyx::docstring const & name = lyx::docstring())
 		: name_(name) {}
 	///
 	Menu & add(MenuItem const &, LyXView const * view = 0);
 	///
 	Menu & read(LyXLex &);
 	///
-	std::string const & name() const { return name_; }
+	lyx::docstring const & name() const { return name_; }
 	///
 	bool empty() const { return items_.empty(); }
 	/// Clear the menu content.
@@ -178,7 +178,7 @@
 	///
 	ItemList items_;
 	///
-	std::string name_;
+	lyx::docstring name_;
 };
 
 
@@ -198,11 +198,11 @@
 	///
 	void add(Menu const &);
 	///
-	bool hasMenu(std::string const &) const;
+	bool hasMenu(lyx::docstring const &) const;
 	///
-	Menu & getMenu(std::string const &);
+	Menu & getMenu(lyx::docstring const &);
 	///
-	Menu const & getMenu(std::string const &) const;
+	Menu const & getMenu(lyx::docstring const &) const;
 	///
 	Menu const & getMenubar() const;
 	///
@@ -211,7 +211,7 @@
 	    will be removed by expand() in other menus. This is used by
 	    the Qt/Mac code
 	*/
-	void specialMenu(std::string const &);
+	void specialMenu(lyx::docstring const &);
 	/// Expands some special entries of the menu
 	/** The entries with the following kind are expanded to a
 	    sequence of Command MenuItems: Lastfiles, Documents,
-- 
        Lgb

Reply via email to