Le 04/10/2015 23:20, Guillaume Munch a écrit :
Dear list,

Has there been some discussion already about allowing UTF-8 in the
source code, in particular for translatable strings? Is this
something we long for?


Guillaume



Seeing how there is unanimous interest, here's a proof of concept.

Please read the commit log carefully including the rationale and the "TODO". Skip the first third regarding string updates (yes I can make them in a separate patch).

While the subject of the patch may seem trivial, I think that setting
this up is a good investment for future use of Unicode in the interface.



Guillaume
>From a3471a5d734cb06cd3f552b079ff94985d755ea0 Mon Sep 17 00:00:00 2001
From: Guillaume Munch <g...@lyx.org>
Date: Sat, 3 Oct 2015 05:16:05 +0100
Subject: [PATCH] U+2026 HORIZONTAL ELLIPSIS instead of "..."
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* Set up the translation chain for UTF-8 strings.

* docstring::operator{==,=+,+} are now compatible UTF-8 (the implementation has
  not changed for the ASCII subset).

Rationale:

We must use UTF-8 strings in the source code instead of defining a global
constant "support::ellipsis = 0x2026" and using concatenation. For two reasons:

 * All translatable strings containing ... are changed, and the former
   translation is correctly suggested as a fuzzy translation. Only substituting
   ... in the string is the route the less confusing for translators who won't
   have to scratch their heads to adapt all the translation strings. It also
   means that the translation remains correct until somebody updates it.

 * We want to keep the source readable. There are already several places where
   for a single unicode character we push_back() a wide char defined by its code
   point and then we have to describe it in a comment. By allowing UTF-8
   strings, we encourage the use of Unicode in the interface. This could be
   useful, for a document processor that has the most advanced Unicode output
   capabilities.

Audit of the usability of UTF-8 strings in the source:

 * to define a docstring:

   * use from_utf8("…")

   * use _() (it uses from_utf8 internally) (source: src/support/Messages.cpp:
     Messages::get())

   * use operator{==,=+,+}. (new)

 * to define a QString:

   * use QString::fromUtf8("…")

   * use qt_() (it uses QString::fromUtf8 internally) (source:
     src/frontends/qt4/qt_helpers.cpp)

Warning: QString::operator{==,=+,+} are NOT compatible with UTF-8 strings in
     source (they use a locale-dependant conversion). Use QString::fromUtf8()
     first. (The locale-dependant conversion can be disabled by defining
     QT_NO_CAST_FROM_ASCII. This will disable all dangerous functions at
     compile-time, see the manual.)

 * Python: only Python 3 is UTF-8 by default. So we change nothing there.

 * Qt designer/creator must be configured to save in UTF-8.

TODO:
 * ensure that the c++ compiler runs under (the equivalent of) LC_ALL=C or
   LC_ALL=UTF-8.
 * Define QT_NO_CAST_FROM_ASCII
---
 lib/ui/stdcontext.inc                     |  72 ++++++++++----------
 lib/ui/stdmenus.inc                       | 108 +++++++++++++++---------------
 po/Makevars                               |   2 +-
 po/Rules-lyx                              |   5 +-
 po/utf-8.pot.in                           |   6 ++
 src/BiblioInfo.cpp                        |   2 +-
 src/Buffer.cpp                            |  10 +--
 src/BufferView.cpp                        |   6 +-
 src/Converter.cpp                         |   2 +-
 src/LyXRC.cpp                             |   2 +-
 src/Text3.cpp                             |   3 +-
 src/VCBackend.cpp                         |   4 +-
 src/frontends/qt4/GuiApplication.cpp      |   6 +-
 src/frontends/qt4/GuiCompare.cpp          |   2 +-
 src/frontends/qt4/GuiDocument.cpp         |  10 +--
 src/frontends/qt4/GuiHyperlink.cpp        |   4 +-
 src/frontends/qt4/GuiView.cpp             |  14 ++--
 src/frontends/qt4/GuiWorkArea.cpp         |  11 +--
 src/frontends/qt4/Menus.cpp               |   8 +--
 src/frontends/qt4/ui/BibtexAddUi.ui       |   2 +-
 src/frontends/qt4/ui/BibtexUi.ui          |   8 +--
 src/frontends/qt4/ui/BranchesUi.ui        |   4 +-
 src/frontends/qt4/ui/ColorUi.ui           |   8 +--
 src/frontends/qt4/ui/CompareUi.ui         |   4 +-
 src/frontends/qt4/ui/ErrorListUi.ui       |   2 +-
 src/frontends/qt4/ui/ExternalUi.ui        |   2 +-
 src/frontends/qt4/ui/GraphicsUi.ui        |   4 +-
 src/frontends/qt4/ui/HSpaceUi.ui          |  12 ++--
 src/frontends/qt4/ui/IncludeUi.ui         |   2 +-
 src/frontends/qt4/ui/IndicesUi.ui         |   4 +-
 src/frontends/qt4/ui/LaTeXUi.ui           |   4 +-
 src/frontends/qt4/ui/PrefColorsUi.ui      |   2 +-
 src/frontends/qt4/ui/PrefCompletionUi.ui  |   4 +-
 src/frontends/qt4/ui/PrefFileformatsUi.ui |   2 +-
 src/frontends/qt4/ui/PrefInputUi.ui       |   4 +-
 src/frontends/qt4/ui/PrefPathsUi.ui       |  16 ++---
 src/frontends/qt4/ui/PrefShortcutsUi.ui   |   2 +-
 src/frontends/qt4/ui/PrefUi.ui            |   2 +-
 src/insets/InsetCollapsable.cpp           |   2 +-
 src/insets/RenderGraphic.cpp              |   8 +--
 src/support/docstring.cpp                 |  33 ++++++---
 src/support/docstring.h                   |  24 ++++---
 src/support/filetools.cpp                 |   3 +-
 src/support/lstrings.cpp                  |   2 +-
 44 files changed, 229 insertions(+), 208 deletions(-)
 create mode 100644 po/utf-8.pot.in

diff --git a/lib/ui/stdcontext.inc b/lib/ui/stdcontext.inc
index 630892c..d0b30a3 100644
--- a/lib/ui/stdcontext.inc
+++ b/lib/ui/stdcontext.inc
@@ -34,8 +34,8 @@ Menuset
 		Item "Gathered Environment|h" "math-insert \gathered"
 		Item "Split Environment|S" "command-sequence math-insert \split; inset-modify tabular append-column"
 		Separator
-		Item "Delimiters...|r" "dialog-show mathdelimiter"
-		Item "Matrix...|x" "dialog-show mathmatrix"
+		Item "Delimiters…|r" "dialog-show mathdelimiter"
+		Item "Matrix…|x" "dialog-show mathmatrix"
 		Item "Macro|o" "math-macro newmacroname newcommand"
 	End
 
@@ -95,7 +95,7 @@ Menuset
 		Item "Formatted Reference|t" "inset-modify changetype formatted"
 		Item "Textual Reference|x" "inset-modify changetype nameref"
 		Separator
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 	End
 
 #
@@ -107,7 +107,7 @@ Menuset
 		Separator
 		Item "Copy as Reference|C" "label-copy-as-reference"
 		Separator
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 	End
 
 
@@ -117,7 +117,7 @@ Menuset
 	Menu "context-citation"
 		CiteStyles
 		Separator
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 	End
 
 
@@ -125,16 +125,16 @@ Menuset
 # InsetBibtex context menu
 #
 	Menu "context-bibtex"
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 		Separator
-		Item "Edit Database(s) Externally...|x" "inset-edit"
+		Item "Edit Database(s) Externally…|x" "inset-edit"
 	End
 
 #
 # InsetBibItem context menu
 #
 	Menu "context-bibitem"
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 	End
 
 #
@@ -145,14 +145,14 @@ Menuset
 		OptItem "Close Inset|C" "inset-toggle close"
 		Separator
 		Item "Dissolve Inset|D" "inset-dissolve"
-		OptItem "Settings...|S" "inset-settings"
+		OptItem "Settings…|S" "inset-settings"
 	End
 
 	Menu "context-conglomerate"
 		Item "Show Label|L" "inset-toggle"
 		Item "Dissolve Inset|D" "inset-dissolve charstyle"
 		Separator
-		OptItem "Settings...|S" "inset-settings"
+		OptItem "Settings…|S" "inset-settings"
 	End
 
 #
@@ -233,7 +233,7 @@ Menuset
 		Item "Horizontal Fill (Down Brace)|B" "inset-modify space \downbracefill{}"
 		Item "Custom Length|C" "command-sequence inset-modify space \hspace{}; inset-settings"
 		Separator
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 	End
 
 #
@@ -251,7 +251,7 @@ Menuset
 		Item "Double Quad Space|u" "inset-modify mathspace \qquad{}"
 		Item "Custom Length|C" "command-sequence inset-modify mathspace \hspace{} \length 1in; inset-settings"
 		Separator
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 	End
 
 #
@@ -265,7 +265,7 @@ Menuset
 		Item "VFill|F" "inset-modify vspace vfill"
 		Item "Custom|C" "command-sequence inset-modify vspace custom; inset-settings"
 		Separator
-		Item "Settings...|e" "inset-settings"
+		Item "Settings…|e" "inset-settings"
 	End
 
 #
@@ -278,9 +278,9 @@ Menuset
 		Item "Verbatim (marked blanks)|b" "inset-modify changetype verbatiminput*"
 		Item "Listing|L" "inset-modify changetype lstinputlisting"
 		Separator
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 		Separator
-		Item "Edit Included File...|E" "inset-edit"
+		Item "Edit Included File…|E" "inset-edit"
 	End
 
 #
@@ -340,7 +340,7 @@ Menuset
 		Separator
 		Item "Apply Last Text Style|A" "textstyle-apply"
 		Submenu "Text Style|x" "edit_textstyles"
-		Item "Paragraph Settings...|P" "layout-paragraph"
+		Item "Paragraph Settings…|P" "layout-paragraph"
 		LanguageSelector
 		Separator
 		Item "Fullscreen Mode" "ui-toggle fullscreen"
@@ -383,10 +383,10 @@ Menuset
 #
 
 	Menu "context-graphics"
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 		Item "Reload|R" "graphics-reload"
 		Separator
-		Item "Edit Externally...|x" "inset-edit"
+		Item "Edit Externally…|x" "inset-edit"
 		Separator
 		GraphicsGroups
 	End
@@ -396,9 +396,9 @@ Menuset
 #
 
 	Menu "context-external"
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 		Separator
-		Item "Edit Externally...|x" "inset-edit"
+		Item "Edit Externally…|x" "inset-edit"
 	End
 
 #
@@ -435,7 +435,7 @@ Menuset
 		Item "Move Column Right|v" "inset-modify tabular move-column-right"
 		Item "Move Column Left" "inset-modify tabular move-column-left"
 		Separator
-		Item "Settings...|S" "inset-settings tabular"
+		Item "Settings…|S" "inset-settings tabular"
 	End
 
 #
@@ -460,7 +460,7 @@ Menuset
 		Submenu "Document Info|D" "buffer-info"
 		Separator
 		Item "Copy Text|o" "inset-copy-as"
-		Item "Settings...|S" "inset-settings info"
+		Item "Settings…|S" "inset-settings info"
 	End
 
 #
@@ -483,7 +483,7 @@ Menuset
 		OptItem "Copy as Reference|C" "label-copy-as-reference"
 		OptItem "Insert Reference at Cursor Position|I" "label-insert-as-reference"
 		Separator
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 	End
 
 #
@@ -494,7 +494,7 @@ Menuset
 		OptItem "Activate Branch|A" "branch-activate"
 		OptItem "Deactivate Branch|e" "branch-deactivate"
 		Separator
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 	End
 
 #
@@ -502,9 +502,9 @@ Menuset
 #
 
 	Menu "context-toc-graphics"
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 		Separator
-		Item "Edit Externally...|x" "inset-edit"
+		Item "Edit Externally…|x" "inset-edit"
 	End
 
 #
@@ -512,7 +512,7 @@ Menuset
 #
 
 	Menu "context-toc-citation"
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 	End
 
 #
@@ -520,7 +520,7 @@ Menuset
 #
 
 	Menu "context-toc-figure"
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 	End
 
 #
@@ -528,7 +528,7 @@ Menuset
 #
 
 	Menu "context-toc-listing"
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 	End
 
 #
@@ -536,7 +536,7 @@ Menuset
 #
 
 	Menu "context-toc-table"
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 	End
 
 #
@@ -549,9 +549,9 @@ Menuset
 		Item "Verbatim (marked blanks)|b" "inset-modify changetype verbatiminput*"
 		Item "Listing|L" "inset-modify changetype lstinputlisting"
 		Separator
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 		Separator
-		Item "Edit Included File...|E" "inset-edit"
+		Item "Edit Included File…|E" "inset-edit"
 	End
 
 #
@@ -559,7 +559,7 @@ Menuset
 #
 
 	Menu "context-toc-index"
-		OptItem "Settings...|S" "inset-settings"
+		OptItem "Settings…|S" "inset-settings"
 	End
 
 #
@@ -580,7 +580,7 @@ Menuset
 		Separator
 		Item "Subindex|b" "inset-modify toggle-subindex"
 		Separator
-		OptItem "Settings...|S" "inset-settings"
+		OptItem "Settings…|S" "inset-settings"
 	End
 
 #
@@ -588,7 +588,7 @@ Menuset
 #
 
 	Menu "context-nomenclprint"
-		OptItem "Settings...|S" "inset-settings"
+		OptItem "Settings…|S" "inset-settings"
 	End
 
 
@@ -634,7 +634,7 @@ Menuset
 # InsetHyperlink context menu
 #
 	Menu "context-hyperlink"
-		Item "Settings...|S" "inset-settings"
+		Item "Settings…|S" "inset-settings"
 	End
 
 End
diff --git a/lib/ui/stdmenus.inc b/lib/ui/stdmenus.inc
index 5ac9879..558fe97 100644
--- a/lib/ui/stdmenus.inc
+++ b/lib/ui/stdmenus.inc
@@ -43,21 +43,21 @@ Menuset
 
 	Menu "file"
 		Item "New|N" "buffer-new"
-		Item "New from Template...|m" "buffer-new-template"
-		Item "Open...|O" "file-open"
+		Item "New from Template…|m" "buffer-new-template"
+		Item "Open…|O" "file-open"
 		Submenu "Open Recent|t" "file_lastfiles"
 		Separator
 		Item "Close|C" "buffer-close"
 		Item "Close All" "buffer-close-all"
 		Item "Save|S" "buffer-write"
-		Item "Save As...|A" "buffer-write-as"
+		Item "Save As…|A" "buffer-write-as"
 		Item "Save All|l" "buffer-write-all"
 		Item "Revert to Saved|R" "buffer-reload"
 		Submenu "Version Control|V" "file_vc"
 		Separator
 		Submenu "Import|I" "file_import"
 		Submenu "Export|E" "file_export"
-		OptItem "Fax...|F" "buffer-export fax"
+		OptItem "Fax…|F" "buffer-export fax"
 		Separator
 		Item "New Window|W" "window-new"
 		Item "Close Window|d" "window-close"
@@ -70,16 +70,16 @@ Menuset
 	End
 
 	Menu "file_vc"
-		OptItem "Register...|R" "vc-register"
-		OptItem "Check In Changes...|I" "vc-check-in"
+		OptItem "Register…|R" "vc-register"
+		OptItem "Check In Changes…|I" "vc-check-in"
 		OptItem "Check Out for Edit|O" "vc-check-out"
 		OptItem "Copy|p" "vc-copy"
 		OptItem "Rename|R" "vc-rename"
 		OptItem "Update Local Directory From Repository|d" "vc-repo-update"
 		OptItem "Revert to Repository Version|v" "vc-revert"
 		OptItem "Undo Last Check In|U" "vc-undo-last"
-		OptItem "Compare with Older Revision...|C" "vc-compare"
-		OptItem "Show History...|H" "dialog-show vclog"
+		OptItem "Compare with Older Revision…|C" "vc-compare"
+		OptItem "Show History…|H" "dialog-show vclog"
 		OptItem "Use Locking Property|L" "vc-locking-toggle"
 	End
 
@@ -88,9 +88,9 @@ Menuset
 	End
 
 	Menu "file_export"
-		Item "Export As...|s" "buffer-export-as"
+		Item "Export As…|s" "buffer-export-as"
 		ExportFormats
-		Item "More Formats & Options...|O" "buffer-export custom"
+		Item "More Formats & Options…|O" "buffer-export custom"
 	End
 
 #
@@ -110,15 +110,15 @@ Menuset
 		Item "Select Whole Inset" "inset-select-all"
 		Item "Select All" "command-sequence buffer-begin ; buffer-end-select"
 		Separator
-		Item "Find & Replace (Quick)...|F" "dialog-show findreplace"
-		Item "Find & Replace (Advanced)..." "dialog-show findreplaceadv"
+		Item "Find & Replace (Quick)…|F" "dialog-show findreplace"
+		Item "Find & Replace (Advanced)…" "dialog-show findreplaceadv"
 		Separator
 		Item "Move Paragraph Up|o" "paragraph-move-up"
 		Item "Move Paragraph Down|v" "paragraph-move-down"
 		Separator
 		Submenu "Text Style|S" "edit_textstyles"
 		LanguageSelector
-		Item "Paragraph Settings...|P" "layout-paragraph"
+		Item "Paragraph Settings…|P" "layout-paragraph"
 		Separator
 # Mathed b0rkage means these don't work properly
 		OptSubmenu "Table|T" "edit_tabular"
@@ -134,22 +134,22 @@ Menuset
 		OptItem "Decrease List Depth|D" "depth-decrement"
 		EnvironmentSeparators
 		OptItem "Dissolve Inset" "inset-dissolve"
-		OptItem "TeX Code Settings...|C" "inset-settings ert"
+		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"
-		OptItem "Text Wrap Settings...|W" "inset-settings wrap"
-		OptItem "Note Settings...|N" "inset-settings note"
-		OptItem "Phantom Settings...|h" "inset-settings phantom"
-		OptItem "Branch Settings...|B" "inset-settings branch"
-		OptItem "Box Settings...|x" "inset-settings box"
-		OptItem "Index Entry Settings...|y" "inset-settings index"
-		OptItem "Index Settings...|x" "inset-settings index_print"
-		OptItem "Info Settings...|n" "inset-settings info"
-		OptItem "Listings Settings...|g" "inset-settings listings"
+		OptItem "Float Settings…|a" "inset-settings float"
+		OptItem "Text Wrap Settings…|W" "inset-settings wrap"
+		OptItem "Note Settings…|N" "inset-settings note"
+		OptItem "Phantom Settings…|h" "inset-settings phantom"
+		OptItem "Branch Settings…|B" "inset-settings branch"
+		OptItem "Box Settings…|x" "inset-settings box"
+		OptItem "Index Entry Settings…|y" "inset-settings index"
+		OptItem "Index Settings…|x" "inset-settings index_print"
+		OptItem "Info Settings…|n" "inset-settings info"
+		OptItem "Listings Settings…|g" "inset-settings listings"
 # Hey, guess what's broken ? Surprise surprise, it's tabular stuff
 # This is in the Table submenu instead for now.
-#	OptItem "Table Settings...|a" "inset-settings tabular"
-		OptItem "Table Settings...|a" "layout-tabular"
+#	OptItem "Table Settings…|a" "inset-settings tabular"
+		OptItem "Table Settings…|a" "layout-tabular"
 	End
 
 	Menu "edit_paste"
@@ -182,7 +182,7 @@ Menuset
 		CharStyles
 		Elements
 		Separator
-		Item "Customized...|C" "dialog-show character"
+		Item "Customized…|C" "dialog-show character"
 		Separator
 		Item "Capitalize|a" "word-capitalize"
 		Item "Uppercase|U" "word-upcase"
@@ -367,17 +367,17 @@ Menuset
 		Submenu "Box[[Menu]]|x" "insert_box"
 		OptSubmenu "Insert Regular Expression" "context-edit-regexp"
 		Separator
-		Item "Citation...|C" "dialog-show-new-inset citation"
-		Item "Cross-Reference...|R" "dialog-show-new-inset ref"
-		Item "Label...|L" "label-insert"
+		Item "Citation…|C" "dialog-show-new-inset citation"
+		Item "Cross-Reference…|R" "dialog-show-new-inset ref"
+		Item "Label…|L" "label-insert"
 		Captions
 		Indices
-		Item "Nomenclature Entry...|y" "nomencl-insert"
+		Item "Nomenclature Entry…|y" "nomencl-insert"
 		Separator
-		Item "Table...|T" "tabular-insert"
-		Item "Graphics...|G" "dialog-show-new-inset graphics"
+		Item "Table…|T" "tabular-insert"
+		Item "Graphics…|G" "dialog-show-new-inset graphics"
 		Item "URL|U" "flex-insert URL"
-		Item "Hyperlink...|k" "href-insert"
+		Item "Hyperlink…|k" "href-insert"
 		Item "Footnote|F" "footnote-insert"
 		Item "Marginal Note|M" "marginalnote-insert"
 		Arguments
@@ -388,7 +388,7 @@ Menuset
 	End
 
 	Menu "insert_special"
-		Item "Symbols...|b" "dialog-show symbols"
+		Item "Symbols…|b" "dialog-show symbols"
 		Item "Ellipsis|i" "specialchar-insert dots"
 		Item "End of Sentence|E" "specialchar-insert end-of-sentence"
 		Item "Ordinary Quote|Q" "self-insert \""
@@ -411,9 +411,9 @@ Menuset
 		Item "Protected Space|P" "space-insert protected"
 		Item "Interword Space|w" "space-insert normal"
 		Item "Thin Space|T" "space-insert thin"
-		Item "Horizontal Space...|o" "command-alternatives dialog-show-new-inset space;dialog-show-new-inset mathspace"
-		Item "Horizontal Line...|L" "dialog-show-new-inset line"
-		Item "Vertical Space...|V" "dialog-show-new-inset vspace"
+		Item "Horizontal Space…|o" "command-alternatives dialog-show-new-inset space;dialog-show-new-inset mathspace"
+		Item "Horizontal Line…|L" "dialog-show-new-inset line"
+		Item "Vertical Space…|V" "dialog-show-new-inset vspace"
 		Submenu "Phantom|m" "insert_phantom"
 		Separator
 		Item "Hyphenation Point|H" "specialchar-insert hyphenation"
@@ -447,8 +447,8 @@ Menuset
 		Item "Gathered Environment|h" "math-insert \gathered"
 		Item "Split Environment|S" "command-sequence math-insert \split; inset-modify tabular append-column"
 		Separator
-		Item "Delimiters...|r" "dialog-show mathdelimiter"
-		Item "Matrix...|x" "dialog-show mathmatrix"
+		Item "Delimiters…|r" "dialog-show mathdelimiter"
+		Item "Matrix…|x" "dialog-show mathmatrix"
 		Item "Macro|o" "math-macro newmacroname newcommand"
 	End
 
@@ -465,16 +465,16 @@ Menuset
 		IndicesLists
 		Item "List of Listings|L" "inset-insert toc CommandInset toc LatexCommand lstlistoflistings \end_inset"
 		Item "Nomenclature|N" "nomencl-print"
-		Item "BibTeX Bibliography...|B" "dialog-show-new-inset bibtex"
+		Item "BibTeX Bibliography…|B" "dialog-show-new-inset bibtex"
 	End
 
 	Menu "insert_file"
-		Item "LyX Document...|X" "file-insert"
-		Item "Plain Text...|T" "file-insert-plaintext"
-		Item "Plain Text, Join Lines...|J" "file-insert-plaintext-para"
+		Item "LyX Document…|X" "file-insert"
+		Item "Plain Text…|T" "file-insert-plaintext"
+		Item "Plain Text, Join Lines…|J" "file-insert-plaintext-para"
 		Separator
-		Item "External Material...|M" "dialog-show-new-inset external"
-		Item "Child Document...|d" "dialog-show-new-inset include"
+		Item "External Material…|M" "dialog-show-new-inset external"
+		Item "Child Document…|d" "dialog-show-new-inset include"
 	End
 
 	Menu "insert_box"
@@ -496,7 +496,7 @@ Menuset
 	Menu "insert_branches"
 		Branches
 		Separator
-		Item "Insert New Branch...|I" "branch-add-insert"
+		Item "Insert New Branch…|I" "branch-add-insert"
 	End
 
 	Menu "insert_phantom"
@@ -526,12 +526,12 @@ Menuset
 		Separator
 		Item "Compressed|o" "buffer-toggle-compression"
 		Item "Disable Editing|E" "buffer-toggle-read-only"
-		Item "Settings...|S" "dialog-show document"
+		Item "Settings…|S" "dialog-show document"
 	End
 
 	Menu "document_change"
 		Item "Track Changes|T" "changes-track"
-		Item "Merge Changes...|M" "changes-merge"
+		Item "Merge Changes…|M" "changes-merge"
 		Item "Accept Change|A" "change-accept"
 		Item "Reject Change|R" "change-reject"
 		Item "Accept All Changes|c" "all-changes-accept"
@@ -570,18 +570,18 @@ Menuset
 #
 
 	Menu "tools"
-		Item "Spellchecker...|S" "dialog-show spellchecker"
-		OptItem "Thesaurus...|T" "thesaurus-entry"
-		Item "Statistics...|a" "statistics"
+		Item "Spellchecker…|S" "dialog-show spellchecker"
+		OptItem "Thesaurus…|T" "thesaurus-entry"
+		Item "Statistics…|a" "statistics"
 		OptItem "Check TeX|h" "buffer-chktex"
 		Item "TeX Information|I" "dialog-show texinfo"
-		Item "Compare...|C" "dialog-show compare"
+		Item "Compare…|C" "dialog-show compare"
 		Separator
 # A LOT of applications have Tools->Prefs. Remember this
 # should be rarely used - Edit menu is not a good place to
 # have it.
 		Item "Reconfigure|R" "reconfigure"
-		Item "Preferences...|P" "dialog-show prefs"
+		Item "Preferences…|P" "dialog-show prefs"
 	End
 
 #
diff --git a/po/Makevars b/po/Makevars
index 22a3fa9..446eb66 100644
--- a/po/Makevars
+++ b/po/Makevars
@@ -8,7 +8,7 @@ subdir = po
 top_builddir = ..
 
 # These options get passed to xgettext.
-XGETTEXT_OPTIONS = --language=C++ --join-existing --keyword=_ --keyword=N_ --keyword=B_ --keyword=qt_
+XGETTEXT_OPTIONS = --language=C++ --join-existing --from-code=UTF-8 --keyword=_ --keyword=N_ --keyword=B_ --keyword=qt_
 
 # This is the copyright holder that gets inserted into the header of the
 # $(DOMAIN).pot file.  Set this to the copyright holder of the surrounding
diff --git a/po/Rules-lyx b/po/Rules-lyx
index 01883c4..30075f5 100644
--- a/po/Rules-lyx
+++ b/po/Rules-lyx
@@ -16,10 +16,13 @@ ${srcdir}/POTFILES.in: $(POTFILE_IN_DEPS)
 	     sort | uniq ) > $@-t \
 	&& mv $@-t $@
 
-l10n_pots: qt4_l10n.pot layouts_l10n.pot languages_l10n.pot latexfonts_l10n.pot encodings_l10n.pot ui_l10n.pot external_l10n.pot formats_l10n.pot
+l10n_pots: utf-8.pot qt4_l10n.pot layouts_l10n.pot languages_l10n.pot latexfonts_l10n.pot encodings_l10n.pot ui_l10n.pot external_l10n.pot formats_l10n.pot
 	cat $^ | msguniq -o $(DOMAIN).po
 	rm $^
 
+utf-8.pot: utf-8.pot.in
+	cp $(srcdir)/utf-8.pot.in $@
+
 LYX_POT = LC_ALL=C ; export LC_ALL ; \
   $(PYTHON) $(srcdir)/lyx_pot.py -b $(top_srcdir)
 
diff --git a/po/utf-8.pot.in b/po/utf-8.pot.in
new file mode 100644
index 0000000..f0d1845
--- /dev/null
+++ b/po/utf-8.pot.in
@@ -0,0 +1,6 @@
+# C++ strings are UTF-8
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
diff --git a/src/BiblioInfo.cpp b/src/BiblioInfo.cpp
index f2bf332..3aa4ff7 100644
--- a/src/BiblioInfo.cpp
+++ b/src/BiblioInfo.cpp
@@ -928,7 +928,7 @@ docstring const BiblioInfo::getLabel(vector<docstring> keys,
 	}
 
 	if (too_many_keys)
-		ret.push_back(0x2026);//HORIZONTAL ELLIPSIS
+		ret += "…";
 	support::truncateWithEllipsis(ret, max_size);
 	return ret;
 }
diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index f7f12c8..195bcff 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -1430,7 +1430,7 @@ bool Buffer::writeFile(FileName const & fname) const
 
 	bool retval = false;
 
-	docstring const str = bformat(_("Saving document %1$s..."),
+	docstring const str = bformat(_("Saving document %1$s…"),
 		makeDisplayPath(fname.absFileName()));
 	message(str);
 
@@ -1481,7 +1481,7 @@ docstring Buffer::emergencyWrite()
 			user_message += "  " + bformat(_("Saved to %1$s. Phew.\n"), from_utf8(s));
 			return user_message;
 		} else {
-			user_message += "  " + _("Save failed! Trying again...\n");
+			user_message += "  " + _("Save failed! Trying again…\n");
 		}
 	}
 
@@ -1495,7 +1495,7 @@ docstring Buffer::emergencyWrite()
 		return user_message;
 	}
 
-	user_message += "  " + _("Save failed! Trying yet again...\n");
+	user_message += "  " + _("Save failed! Trying yet again…\n");
 
 	// 3) In "/tmp" directory.
 	// MakeAbsPath to prepend the current
@@ -2097,7 +2097,7 @@ int Buffer::runChktex()
 	string const org_path = filePath();
 
 	PathChanger p(path); // path to LaTeX file
-	message(_("Running chktex..."));
+	message(_("Running chktex…"));
 
 	// Generate the LaTeX file if neccessary
 	OutputParams runparams(&params().encoding());
@@ -3820,7 +3820,7 @@ bool Buffer::autoSave() const
 	if (buf->d->bak_clean || isReadonly())
 		return true;
 
-	message(_("Autosaving current document..."));
+	message(_("Autosaving current document…"));
 	buf->d->bak_clean = true;
 
 	FileName const fname = getAutosaveFileName();
diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 097a465..27a9494 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -973,7 +973,7 @@ void BufferView::makeDocumentClass()
 
 void BufferView::updateDocumentClass(DocumentClassConstPtr olddc)
 {
-	message(_("Converting document to new document class..."));
+	message(_("Converting document to new document class…"));
 
 	StableDocIterator backcur(d->cursor_);
 	ErrorList & el = buffer_.errorList("Class Switch");
@@ -1884,7 +1884,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 				break;
 			docstring insname = ins->layoutName();
 			while (!insname.empty()) {
-				if (insname == name || name == from_utf8("*")) {
+				if (insname == name || name == "*") {
 					cur.recordUndo();
 					lyx::dispatch(fr, dr);
 					++iterations;
@@ -2771,7 +2771,7 @@ void BufferView::insertLyXFile(FileName const & fname)
 
 	docstring const disp_fn = makeDisplayPath(filename.absFileName());
 	// emit message signal.
-	message(bformat(_("Inserting document %1$s..."), disp_fn));
+	message(bformat(_("Inserting document %1$s…"), disp_fn));
 
 	docstring res;
 	Buffer buf(filename.absFileName(), false);
diff --git a/src/Converter.cpp b/src/Converter.cpp
index ee17f57..740d22a 100644
--- a/src/Converter.cpp
+++ b/src/Converter.cpp
@@ -645,7 +645,7 @@ bool Converters::runLaTeX(Buffer const & buffer, string const & command,
 			  OutputParams const & runparams, ErrorList & errorList)
 {
 	buffer.setBusy(true);
-	buffer.message(_("Running LaTeX..."));
+	buffer.message(_("Running LaTeX…"));
 
 	// do the LaTeX run(s)
 	string const name = buffer.latexName();
diff --git a/src/LyXRC.cpp b/src/LyXRC.cpp
index 4fb1b02..5872a29 100644
--- a/src/LyXRC.cpp
+++ b/src/LyXRC.cpp
@@ -3112,7 +3112,7 @@ string const LyXRC::getDescription(LyXRCTags tag)
 		break;
 
 	case RC_COMPLETION_INLINE_DOTS:
-		str = _("Use \"...\" to shorten long completions.");
+		str = _("Use \"…\" to shorten long completions.");
 		break;
 
 	case RC_AUTOCORRECTION_MATH:
diff --git a/src/Text3.cpp b/src/Text3.cpp
index 8efec47..caa7b26 100644
--- a/src/Text3.cpp
+++ b/src/Text3.cpp
@@ -1430,8 +1430,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 		}
 
 		if (!hasLayout) {
-			cur.errorMessage(from_utf8(N_("Layout ")) + cmd.argument() +
-				from_utf8(N_(" not known")));
+			cur.errorMessage(N_("Layout ") + cmd.argument() + N_(" not known"));
 			break;
 		}
 
diff --git a/src/VCBackend.cpp b/src/VCBackend.cpp
index 6a6ea08..266491b 100644
--- a/src/VCBackend.cpp
+++ b/src/VCBackend.cpp
@@ -956,7 +956,7 @@ string CVS::repoUpdate()
 				"Possible file conflicts must be then resolved manually "
 				"or you will need to revert back to the repository version."), file);
 		int ret = frontend::Alert::prompt(_("Changes detected"),
-				text, 0, 1, _("&Continue"), _("&Abort"), _("View &Log ..."));
+				text, 0, 1, _("&Continue"), _("&Abort"), _("View &Log…"));
 		if (ret == 2) {
 			dispatch(FuncRequest(LFUN_DIALOG_SHOW, "file " + tmpf.absFileName()));
 			ret = frontend::Alert::prompt(_("Changes detected"),
@@ -1515,7 +1515,7 @@ string SVN::repoUpdate()
 				"will be preferred."
 				"\n\nContinue?"), file);
 		int ret = frontend::Alert::prompt(_("Changes detected"),
-				text, 0, 1, _("&Yes"), _("&No"), _("View &Log ..."));
+				text, 0, 1, _("&Yes"), _("&No"), _("View &Log…"));
 		if (ret == 2) {
 			dispatch(FuncRequest(LFUN_DIALOG_SHOW, "file " + tmpf.absFileName()));
 			ret = frontend::Alert::prompt(_("Changes detected"),
diff --git a/src/frontends/qt4/GuiApplication.cpp b/src/frontends/qt4/GuiApplication.cpp
index 5e213e6..9480726 100644
--- a/src/frontends/qt4/GuiApplication.cpp
+++ b/src/frontends/qt4/GuiApplication.cpp
@@ -1506,7 +1506,7 @@ void GuiApplication::reconfigure(string const & option)
 {
 	// emit message signal.
 	if (current_view_)
-		current_view_->message(_("Running configure..."));
+		current_view_->message(_("Running configure…"));
 
 	// Run configure in user lyx directory
 	string const lock_file = package().getConfigureLockName();
@@ -1514,7 +1514,7 @@ void GuiApplication::reconfigure(string const & option)
 	int const ret = package().reconfigureUserLyXDir(option);
 	// emit message signal.
 	if (current_view_)
-		current_view_->message(_("Reloading configuration..."));
+		current_view_->message(_("Reloading configuration…"));
 	lyxrc.read(libFileSearch(QString(), "lyxrc.defaults"), false);
 	// Re-read packages.lst
 	LaTeXPackages::getAvailable();
@@ -1694,7 +1694,7 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 			       << arg << "'. Bad installation?" << endl;
 			break;
 		}
-		current_view_->message(bformat(_("Opening help file %1$s..."),
+		current_view_->message(bformat(_("Opening help file %1$s…"),
 					       makeDisplayPath(fname.absFileName())));
 		Buffer * buf = current_view_->loadDocument(fname, false);
 
diff --git a/src/frontends/qt4/GuiCompare.cpp b/src/frontends/qt4/GuiCompare.cpp
index 83ffd5a..efbbf18 100644
--- a/src/frontends/qt4/GuiCompare.cpp
+++ b/src/frontends/qt4/GuiCompare.cpp
@@ -260,7 +260,7 @@ void GuiCompare::slotOK()
 void GuiCompare::slotCancel()
 {
 	if (compare_ && compare_->isRunning()) {
-		statusBar->showMessage(qt_("Aborting process..."));
+		statusBar->showMessage(qt_("Aborting process."));
 		compare_->abort();
 	} else {
 		GuiDialog::slotClose();
diff --git a/src/frontends/qt4/GuiDocument.cpp b/src/frontends/qt4/GuiDocument.cpp
index e9d0f41..a23bec5 100644
--- a/src/frontends/qt4/GuiDocument.cpp
+++ b/src/frontends/qt4/GuiDocument.cpp
@@ -544,7 +544,7 @@ void LocalLayout::apply(BufferParams & params)
 void LocalLayout::textChanged()
 {
 	static const QString message =
-		qt_("Press button to check validity...");
+		qt_("Press button to check validity…");
 	string const layout =
 		fromqstr(locallayoutTE->document()->toPlainText().trimmed());
 
@@ -1640,7 +1640,7 @@ void GuiDocument::changeBackgroundColor()
 	// set the button color and text
 	colorModule->backgroundPB->setStyleSheet(
 		colorButtonStyleSheet(newColor));
-	colorModule->backgroundPB->setText(qt_("&Change..."));
+	colorModule->backgroundPB->setText(qt_("&Change…"));
 	// save color
 	set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
 	is_backgroundcolor = true;
@@ -1653,7 +1653,7 @@ void GuiDocument::deleteBackgroundColor()
 	// set the button color back to default by setting an empty StyleSheet
 	colorModule->backgroundPB->setStyleSheet(QLatin1String(""));
 	// change button text
-	colorModule->backgroundPB->setText(qt_("&Default..."));
+	colorModule->backgroundPB->setText(qt_("&Default…"));
 	// save default color (white)
 	set_backgroundcolor = rgbFromHexName("#ffffff");
 	is_backgroundcolor = false;
@@ -1670,7 +1670,7 @@ void GuiDocument::changeFontColor()
 	// set the button color and text
 	colorModule->fontColorPB->setStyleSheet(
 		colorButtonStyleSheet(newColor));
-	colorModule->fontColorPB->setText(qt_("&Change..."));
+	colorModule->fontColorPB->setText(qt_("&Change…"));
 	// save color
 	set_fontcolor = rgbFromHexName(fromqstr(newColor.name()));
 	is_fontcolor = true;
@@ -1683,7 +1683,7 @@ void GuiDocument::deleteFontColor()
 	// set the button color back to default by setting an empty StyleSheet
 	colorModule->fontColorPB->setStyleSheet(QLatin1String(""));
 	// change button text
-	colorModule->fontColorPB->setText(qt_("&Default..."));
+	colorModule->fontColorPB->setText(qt_("&Default…"));
 	// save default color (black)
 	set_fontcolor = rgbFromHexName("#000000");
 	is_fontcolor = false;
diff --git a/src/frontends/qt4/GuiHyperlink.cpp b/src/frontends/qt4/GuiHyperlink.cpp
index 3111d19..b2cabf1 100644
--- a/src/frontends/qt4/GuiHyperlink.cpp
+++ b/src/frontends/qt4/GuiHyperlink.cpp
@@ -75,9 +75,9 @@ bool GuiHyperlink::initialiseParams(std::string const & data)
 		return false;
 	targetED->setText(toqstr(params["target"]));
 	nameED->setText(toqstr(params["name"]));
-	if (params["type"] == from_utf8("mailto:"))
+	if (params["type"] == "mailto:")
 		emailRB->setChecked(true);
-	else if (params["type"] == from_utf8("file:"))
+	else if (params["type"] == "file:")
 		fileRB->setChecked(true);
 	else
 		webRB->setChecked(true);
diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp
index 32a9a98..32be0b5 100644
--- a/src/frontends/qt4/GuiView.cpp
+++ b/src/frontends/qt4/GuiView.cpp
@@ -2180,7 +2180,7 @@ void GuiView::openDocument(string const & fname)
 	}
 
 	docstring const disp_fn = makeDisplayPath(filename);
-	message(bformat(_("Opening document %1$s..."), disp_fn));
+	message(bformat(_("Opening document %1$s…"), disp_fn));
 
 	docstring str2;
 	Buffer * buf = loadDocument(fullname);
@@ -2342,7 +2342,7 @@ void GuiView::importDocument(string const & argument)
 		}
 	}
 
-	message(bformat(_("Importing %1$s..."), displaypath));
+	message(bformat(_("Importing %1$s…"), displaypath));
 	ErrorList errorList;
 	if (import(this, fullname, format, errorList))
 		message(_("imported."));
@@ -3276,7 +3276,7 @@ void GuiView::openChildDocument(string const & fname)
 		child = theBufferList().getBuffer(filename);
 		setBuffer(child);
 	} else {
-		message(bformat(_("Opening child document %1$s..."),
+		message(bformat(_("Opening child document %1$s…"),
 			makeDisplayPath(filename.absFileName())));
 		child = loadDocument(filename, false);
 	}
@@ -3527,7 +3527,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 					See the update_unincluded flag */
 			d.asyncBufferProcessing(argument,
 						doc_buffer,
-						_("Exporting ..."),
+						_("Exporting…"),
 						&GuiViewPrivate::exportAndDestroy,
 						&Buffer::doExport,
 						0);
@@ -3547,7 +3547,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 		case LFUN_BUFFER_UPDATE: {
 			d.asyncBufferProcessing(argument,
 						doc_buffer,
-						_("Exporting ..."),
+						_("Exporting…"),
 						&GuiViewPrivate::compileAndDestroy,
 						&Buffer::doExport,
 						0);
@@ -3556,7 +3556,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 		case LFUN_BUFFER_VIEW: {
 			d.asyncBufferProcessing(argument,
 						doc_buffer,
-						_("Previewing ..."),
+						_("Previewing…"),
 						&GuiViewPrivate::previewAndDestroy,
 						0,
 						&Buffer::preview);
@@ -3720,7 +3720,7 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 			Buffer * first = theBufferList().first();
 			if (!first)
 				break;
-			message(_("Saving all documents..."));
+			message(_("Saving all documents…"));
 			// We cannot use a for loop as the buffer list cycles.
 			Buffer * b = first;
 			do {
diff --git a/src/frontends/qt4/GuiWorkArea.cpp b/src/frontends/qt4/GuiWorkArea.cpp
index 11596d5..a63ef60 100644
--- a/src/frontends/qt4/GuiWorkArea.cpp
+++ b/src/frontends/qt4/GuiWorkArea.cpp
@@ -1852,7 +1852,7 @@ public:
 
 		if (!dotted) {
 			if (dottedPrefix_ && !prefix_.isEmpty())
-				prefix_ += ellipsisSlash_;
+				prefix_ += QString::fromUtf8("…/");
 			prefix_ += postfix_.front() + "/";
 		}
 		dottedPrefix_ = dotted && !prefix_.isEmpty();
@@ -1865,7 +1865,7 @@ public:
 			return filename_;
 
 		bool dots = dottedPrefix_ || !postfix_.isEmpty();
-		return prefix_ + (dots ? ellipsisSlash_ : "") + filename_;
+		return prefix_ + QString::fromUtf8(dots ? "…/" : "") + filename_;
 	}
 	///
 	QString forecastPathString() const
@@ -1874,7 +1874,7 @@ public:
 			return displayString();
 
 		return prefix_
-			+ (dottedPrefix_ ? ellipsisSlash_ : "")
+			+ (dottedPrefix_ ? QString::fromUtf8("…/") : "")
 			+ postfix_.front() + "/";
 	}
 	///
@@ -1883,8 +1883,6 @@ public:
 	int tab() const { return tab_; }
 
 private:
-	/// ".../"
-	static QString const ellipsisSlash_;
 	///
 	QString prefix_;
 	///
@@ -1900,9 +1898,6 @@ private:
 };
 
 
-QString const DisplayPath::ellipsisSlash_ = QString(QChar(0x2026)) + "/";
-
-
 ///
 bool operator<(DisplayPath const & a, DisplayPath const & b)
 {
diff --git a/src/frontends/qt4/Menus.cpp b/src/frontends/qt4/Menus.cpp
index 2507ae3..7b9c106 100644
--- a/src/frontends/qt4/Menus.cpp
+++ b/src/frontends/qt4/Menus.cpp
@@ -703,7 +703,7 @@ bool MenuDefinition::hasFunc(FuncRequest const & func) const
 void MenuDefinition::catSub(docstring const & name)
 {
 	add(MenuItem(MenuItem::Submenu,
-		     qt_("More...|M"), toqstr(name), QString(), false));
+		     qt_("More…|M"), toqstr(name), QString(), false));
 }
 
 void MenuDefinition::cat(MenuDefinition const & other)
@@ -891,7 +891,7 @@ void MenuDefinition::expandLanguageSelector(Buffer const * buf)
 
 	MenuItem item(MenuItem::Submenu, qt_("Language|L"));
 	item.setSubmenu(MenuDefinition(qt_("Language")));
-	QString morelangs = qt_("More Languages ...|M");
+	QString morelangs = qt_("More Languages…|M");
 	QStringList accelerators;
 	if (morelangs.contains('|'))
 		accelerators.append(morelangs.section('|', -1));
@@ -1095,7 +1095,7 @@ void MenuDefinition::expandFormats(MenuItem::Kind const kind, Buffer const * buf
 
 		switch (kind) {
 		case MenuItem::ImportFormats:
-			label += from_ascii("...");
+			label += "…";
 			break;
 		case MenuItem::ViewFormats:
 		case MenuItem::UpdateFormats:
@@ -1311,7 +1311,7 @@ void MenuDefinition::expandToc(Buffer const * buf)
 		MenuDefinition submenu;
 		// "Open outliner..." entry
 		FuncRequest f(LFUN_DIALOG_SHOW, "toc " + cit->first);
-		submenu.add(MenuItem(MenuItem::Command, qt_("Open outliner..."), f));
+		submenu.add(MenuItem(MenuItem::Command, qt_("Open outliner…"), f));
 		submenu.add(MenuItem(MenuItem::Separator));
 		// add entries
 		submenu.expandToc2(* cit->second, 0, cit->second->size(), 0);
diff --git a/src/frontends/qt4/ui/BibtexAddUi.ui b/src/frontends/qt4/ui/BibtexAddUi.ui
index 4b7353e..93bb9ac 100644
--- a/src/frontends/qt4/ui/BibtexAddUi.ui
+++ b/src/frontends/qt4/ui/BibtexAddUi.ui
@@ -43,7 +43,7 @@
    <item row="2" column="0" >
     <widget class="QPushButton" name="browsePB" >
      <property name="text" >
-      <string>&amp;Browse...</string>
+      <string>&amp;Browse…</string>
      </property>
      <property name="autoDefault" >
       <bool>false</bool>
diff --git a/src/frontends/qt4/ui/BibtexUi.ui b/src/frontends/qt4/ui/BibtexUi.ui
index b99ddac..d01e22a 100644
--- a/src/frontends/qt4/ui/BibtexUi.ui
+++ b/src/frontends/qt4/ui/BibtexUi.ui
@@ -94,7 +94,7 @@
       <string>Choose a style file</string>
      </property>
      <property name="text" >
-      <string>&amp;Browse...</string>
+      <string>&amp;Browse…</string>
      </property>
      <property name="autoDefault" >
       <bool>false</bool>
@@ -128,7 +128,7 @@
       </sizepolicy>
      </property>
      <property name="toolTip" >
-      <string>This bibliography section contains...</string>
+      <string>This bibliography section contains…</string>
      </property>
      <property name="text" >
       <string>&amp;Content:</string>
@@ -141,7 +141,7 @@
    <item row="9" column="1" >
     <widget class="QComboBox" name="btPrintCO" >
      <property name="toolTip" >
-      <string>This bibliography section contains...</string>
+      <string>This bibliography section contains…</string>
      </property>
      <item>
       <property name="text" >
@@ -269,7 +269,7 @@
       <string>Add a BibTeX database file</string>
      </property>
      <property name="text" >
-      <string>&amp;Add...</string>
+      <string>&amp;Add…</string>
      </property>
     </widget>
    </item>
diff --git a/src/frontends/qt4/ui/BranchesUi.ui b/src/frontends/qt4/ui/BranchesUi.ui
index 4c83b18..381cef0 100644
--- a/src/frontends/qt4/ui/BranchesUi.ui
+++ b/src/frontends/qt4/ui/BranchesUi.ui
@@ -123,7 +123,7 @@
       <string>Define or change background color</string>
      </property>
      <property name="text" >
-      <string>Alter Co&amp;lor...</string>
+      <string>Alter Co&amp;lor…</string>
      </property>
     </widget>
    </item>
@@ -143,7 +143,7 @@
       <string>Change the name of the selected branch</string>
      </property>
      <property name="text" >
-      <string>Re&amp;name...</string>
+      <string>Re&amp;name…</string>
      </property>
     </widget>
    </item>
diff --git a/src/frontends/qt4/ui/ColorUi.ui b/src/frontends/qt4/ui/ColorUi.ui
index 85eaf9c..3607e1a 100644
--- a/src/frontends/qt4/ui/ColorUi.ui
+++ b/src/frontends/qt4/ui/ColorUi.ui
@@ -54,7 +54,7 @@
              <string>Click to change the color</string>
             </property>
             <property name="text" >
-             <string>Default...</string>
+             <string>Default…</string>
             </property>
            </widget>
           </item>
@@ -115,7 +115,7 @@
              <string>Click to change the color</string>
             </property>
             <property name="text" >
-             <string>&amp;Change...</string>
+             <string>&amp;Change…</string>
             </property>
            </widget>
           </item>
@@ -192,7 +192,7 @@
              <string>Click to change the color</string>
             </property>
             <property name="text" >
-             <string>Default...</string>
+             <string>Default…</string>
             </property>
            </widget>
           </item>
@@ -253,7 +253,7 @@
              <string>Click to change the color</string>
             </property>
             <property name="text" >
-             <string>&amp;Change...</string>
+             <string>&amp;Change…</string>
             </property>
            </widget>
           </item>
diff --git a/src/frontends/qt4/ui/CompareUi.ui b/src/frontends/qt4/ui/CompareUi.ui
index 31573c3..8f1c077 100644
--- a/src/frontends/qt4/ui/CompareUi.ui
+++ b/src/frontends/qt4/ui/CompareUi.ui
@@ -47,7 +47,7 @@
           <item row="1" column="1" >
             <widget class="QPushButton" name="newFilePB" >
               <property name="text" >
-                <string>&amp;Browse...</string>
+                <string>&amp;Browse…</string>
               </property>
               <property name="autoDefault" >
                 <bool>false</bool>
@@ -80,7 +80,7 @@
           <item row="3" column="1" >
             <widget class="QPushButton" name="oldFilePB" >
               <property name="text" >
-                <string>Bro&amp;wse...</string>
+                <string>Bro&amp;wse…</string>
               </property>
               <property name="autoDefault" >
                 <bool>false</bool>
diff --git a/src/frontends/qt4/ui/ErrorListUi.ui b/src/frontends/qt4/ui/ErrorListUi.ui
index 9775a9f..12d5e57 100644
--- a/src/frontends/qt4/ui/ErrorListUi.ui
+++ b/src/frontends/qt4/ui/ErrorListUi.ui
@@ -83,7 +83,7 @@
       <string>Open the LaTeX Log File dialog</string>
      </property>
      <property name="text" >
-      <string>View Complete &amp;Log...</string>
+      <string>View Complete &amp;Log…</string>
      </property>
     </widget>
    </item>
diff --git a/src/frontends/qt4/ui/ExternalUi.ui b/src/frontends/qt4/ui/ExternalUi.ui
index 12967c5..4300e66 100644
--- a/src/frontends/qt4/ui/ExternalUi.ui
+++ b/src/frontends/qt4/ui/ExternalUi.ui
@@ -67,7 +67,7 @@
           <string>Select a file</string>
          </property>
          <property name="text" >
-          <string>&amp;Browse...</string>
+          <string>&amp;Browse…</string>
          </property>
         </widget>
        </item>
diff --git a/src/frontends/qt4/ui/GraphicsUi.ui b/src/frontends/qt4/ui/GraphicsUi.ui
index 3942651..3734acd 100644
--- a/src/frontends/qt4/ui/GraphicsUi.ui
+++ b/src/frontends/qt4/ui/GraphicsUi.ui
@@ -55,7 +55,7 @@
           <string>Select an image file</string>
          </property>
          <property name="text" >
-          <string>&amp;Browse...</string>
+          <string>&amp;Browse…</string>
          </property>
         </widget>
        </item>
@@ -637,7 +637,7 @@
              <string>Click to define a new graphics group.</string>
             </property>
             <property name="text" >
-             <string>O&amp;pen new group...</string>
+             <string>O&amp;pen new group…</string>
             </property>
            </widget>
           </item>
diff --git a/src/frontends/qt4/ui/HSpaceUi.ui b/src/frontends/qt4/ui/HSpaceUi.ui
index 026b157..90bb659 100644
--- a/src/frontends/qt4/ui/HSpaceUi.ui
+++ b/src/frontends/qt4/ui/HSpaceUi.ui
@@ -34,32 +34,32 @@
      </item>
      <item>
       <property name="text" >
-       <string>...............</string>
+       <string>…… (dots)</string>
       </property>
      </item>
      <item>
       <property name="text" >
-       <string>________</string>
+       <string>___ (line)</string>
       </property>
      </item>
      <item>
       <property name="text" >
-       <string>&lt;-----------</string>
+       <string>⟵ (left arrow)</string>
       </property>
      </item>
      <item>
       <property name="text" >
-       <string>-----------></string>
+       <string>⟶ (right arrow)</string>
       </property>
      </item>
      <item>
       <property name="text" >
-       <string>\-----v-----/</string>
+       <string>︸ (bottom bracket)</string>
       </property>
      </item>
      <item>
       <property name="text" >
-       <string>/-----^-----\</string>
+       <string>︷ (top bracket)</string>
       </property>
      </item>
     </widget>
diff --git a/src/frontends/qt4/ui/IncludeUi.ui b/src/frontends/qt4/ui/IncludeUi.ui
index 0522d3d..999ee98 100644
--- a/src/frontends/qt4/ui/IncludeUi.ui
+++ b/src/frontends/qt4/ui/IncludeUi.ui
@@ -332,7 +332,7 @@
       <string>Select a file</string>
      </property>
      <property name="text" >
-      <string>&amp;Browse...</string>
+      <string>&amp;Browse…</string>
      </property>
     </widget>
    </item>
diff --git a/src/frontends/qt4/ui/IndicesUi.ui b/src/frontends/qt4/ui/IndicesUi.ui
index a7b92b9..0644eb4 100644
--- a/src/frontends/qt4/ui/IndicesUi.ui
+++ b/src/frontends/qt4/ui/IndicesUi.ui
@@ -172,7 +172,7 @@
       <string>Rename the selected index</string>
      </property>
      <property name="text" >
-      <string>R&amp;ename...</string>
+      <string>R&amp;ename…</string>
      </property>
     </widget>
    </item>
@@ -182,7 +182,7 @@
       <string>Define or change button color</string>
      </property>
      <property name="text" >
-      <string>Alter Co&amp;lor...</string>
+      <string>Alter Co&amp;lor…</string>
      </property>
     </widget>
    </item>
diff --git a/src/frontends/qt4/ui/LaTeXUi.ui b/src/frontends/qt4/ui/LaTeXUi.ui
index 0302063..5ac3846 100644
--- a/src/frontends/qt4/ui/LaTeXUi.ui
+++ b/src/frontends/qt4/ui/LaTeXUi.ui
@@ -44,7 +44,7 @@
          <string>Click to select a local document class definition file</string>
         </property>
         <property name="text">
-         <string>&amp;Local Layout...</string>
+         <string>&amp;Local Layout…</string>
         </property>
        </widget>
       </item>
@@ -157,7 +157,7 @@
       <item row="0" column="2">
        <widget class="QPushButton" name="childDocPB">
         <property name="text">
-         <string>&amp;Browse...</string>
+         <string>&amp;Browse…</string>
         </property>
        </widget>
       </item>
diff --git a/src/frontends/qt4/ui/PrefColorsUi.ui b/src/frontends/qt4/ui/PrefColorsUi.ui
index e7c89c2..db15269 100644
--- a/src/frontends/qt4/ui/PrefColorsUi.ui
+++ b/src/frontends/qt4/ui/PrefColorsUi.ui
@@ -43,7 +43,7 @@
         </sizepolicy>
        </property>
        <property name="text">
-        <string>A&amp;lter...</string>
+        <string>A&amp;lter…</string>
        </property>
       </widget>
      </item>
diff --git a/src/frontends/qt4/ui/PrefCompletionUi.ui b/src/frontends/qt4/ui/PrefCompletionUi.ui
index 45faee4..6ae6987 100644
--- a/src/frontends/qt4/ui/PrefCompletionUi.ui
+++ b/src/frontends/qt4/ui/PrefCompletionUi.ui
@@ -282,10 +282,10 @@
       <item>
        <widget class="QCheckBox" name="inlineDotsCB">
         <property name="toolTip">
-         <string>Long completions are cut-off and shown with &quot;...&quot;.</string>
+         <string>Long completions are cut-off and shown with &quot;…&quot;.</string>
         </property>
         <property name="text">
-         <string>&amp;Use &quot;...&quot; to shorten long completions</string>
+         <string>&amp;Use &quot;…&quot; to shorten long completions</string>
         </property>
        </widget>
       </item>
diff --git a/src/frontends/qt4/ui/PrefFileformatsUi.ui b/src/frontends/qt4/ui/PrefFileformatsUi.ui
index faa24e4..2765864 100644
--- a/src/frontends/qt4/ui/PrefFileformatsUi.ui
+++ b/src/frontends/qt4/ui/PrefFileformatsUi.ui
@@ -43,7 +43,7 @@
    <item row="0" column="3">
     <widget class="QPushButton" name="formatNewPB">
      <property name="text">
-      <string>&amp;New...</string>
+      <string>&amp;New…</string>
      </property>
     </widget>
    </item>
diff --git a/src/frontends/qt4/ui/PrefInputUi.ui b/src/frontends/qt4/ui/PrefInputUi.ui
index 9964e3f..968ba25 100644
--- a/src/frontends/qt4/ui/PrefInputUi.ui
+++ b/src/frontends/qt4/ui/PrefInputUi.ui
@@ -62,7 +62,7 @@
          <bool>false</bool>
         </property>
         <property name="text">
-         <string>Br&amp;owse...</string>
+         <string>Br&amp;owse…</string>
         </property>
         <property name="autoDefault">
          <bool>false</bool>
@@ -108,7 +108,7 @@
          <bool>false</bool>
         </property>
         <property name="text">
-         <string>&amp;Browse...</string>
+         <string>&amp;Browse…</string>
         </property>
         <property name="autoDefault">
          <bool>false</bool>
diff --git a/src/frontends/qt4/ui/PrefPathsUi.ui b/src/frontends/qt4/ui/PrefPathsUi.ui
index 927c75c..ecc9a95 100644
--- a/src/frontends/qt4/ui/PrefPathsUi.ui
+++ b/src/frontends/qt4/ui/PrefPathsUi.ui
@@ -72,7 +72,7 @@
    <item row="6" column="2" >
     <widget class="QPushButton" name="thesaurusDirPB" >
      <property name="text" >
-      <string>Browse...</string>
+      <string>Browse…</string>
      </property>
      <property name="autoDefault" >
       <bool>false</bool>
@@ -95,7 +95,7 @@
    <item row="5" column="2" >
     <widget class="QPushButton" name="tempDirPB" >
      <property name="text" >
-      <string>Browse...</string>
+      <string>Browse…</string>
      </property>
      <property name="autoDefault" >
       <bool>false</bool>
@@ -118,7 +118,7 @@
    <item row="4" column="2" >
     <widget class="QPushButton" name="lyxserverDirPB" >
      <property name="text" >
-      <string>Browse...</string>
+      <string>Browse…</string>
      </property>
      <property name="autoDefault" >
       <bool>false</bool>
@@ -141,7 +141,7 @@
    <item row="3" column="2" >
     <widget class="QPushButton" name="backupDirPB" >
      <property name="text" >
-      <string>Browse...</string>
+      <string>Browse…</string>
      </property>
      <property name="autoDefault" >
       <bool>false</bool>
@@ -164,7 +164,7 @@
    <item row="2" column="2" >
     <widget class="QPushButton" name="exampleDirPB" >
      <property name="text" >
-      <string>Browse...</string>
+      <string>Browse…</string>
      </property>
      <property name="autoDefault" >
       <bool>false</bool>
@@ -187,7 +187,7 @@
    <item row="1" column="2" >
     <widget class="QPushButton" name="templateDirPB" >
      <property name="text" >
-      <string>Browse...</string>
+      <string>Browse…</string>
      </property>
      <property name="autoDefault" >
       <bool>false</bool>
@@ -210,7 +210,7 @@
    <item row="0" column="2" >
     <widget class="QPushButton" name="workingDirPB" >
      <property name="text" >
-      <string>Browse...</string>
+      <string>Browse…</string>
      </property>
      <property name="autoDefault" >
       <bool>false</bool>
@@ -246,7 +246,7 @@
    <item row="8" column="2" >
     <widget class="QPushButton" name="hunspellDirPB" >
      <property name="text" >
-      <string>Browse...</string>
+      <string>Browse…</string>
      </property>
      <property name="autoDefault" >
       <bool>false</bool>
diff --git a/src/frontends/qt4/ui/PrefShortcutsUi.ui b/src/frontends/qt4/ui/PrefShortcutsUi.ui
index e756eb8..1a8901a 100644
--- a/src/frontends/qt4/ui/PrefShortcutsUi.ui
+++ b/src/frontends/qt4/ui/PrefShortcutsUi.ui
@@ -80,7 +80,7 @@
    <item row="0" column="2" >
     <widget class="QPushButton" name="bindFilePB" >
      <property name="text" >
-      <string>Br&amp;owse...</string>
+      <string>Br&amp;owse…</string>
      </property>
     </widget>
    </item>
diff --git a/src/frontends/qt4/ui/PrefUi.ui b/src/frontends/qt4/ui/PrefUi.ui
index fde3d85..2310734 100644
--- a/src/frontends/qt4/ui/PrefUi.ui
+++ b/src/frontends/qt4/ui/PrefUi.ui
@@ -47,7 +47,7 @@
         <item>
          <widget class="QPushButton" name="uiFilePB">
           <property name="text">
-           <string>Bro&amp;wse...</string>
+           <string>Bro&amp;wse…</string>
           </property>
          </widget>
         </item>
diff --git a/src/insets/InsetCollapsable.cpp b/src/insets/InsetCollapsable.cpp
index 623cebb..953b377 100644
--- a/src/insets/InsetCollapsable.cpp
+++ b/src/insets/InsetCollapsable.cpp
@@ -432,7 +432,7 @@ docstring const InsetCollapsable::getNewLabel(docstring const & l) const
 		++i;
 	}
 	if (paragraphs().size() > 1 || (i > 0 && j < p_siz)) {
-		label += "...";
+		label += "…";
 	}
 	return label.empty() ? l : label;
 }
diff --git a/src/insets/RenderGraphic.cpp b/src/insets/RenderGraphic.cpp
index 48b41e2..0111303 100644
--- a/src/insets/RenderGraphic.cpp
+++ b/src/insets/RenderGraphic.cpp
@@ -87,16 +87,16 @@ docstring const statusMessage(graphics::Params const & params,
 			ret = _("Not shown.");
 			break;
 		case graphics::Loading:
-			ret = _("Loading...");
+			ret = _("Loading…");
 			break;
 		case graphics::Converting:
-			ret = _("Converting to loadable format...");
+			ret = _("Converting to loadable format…");
 			break;
 		case graphics::Loaded:
-			ret = _("Loaded into memory. Generating pixmap...");
+			ret = _("Loaded into memory. Generating pixmap…");
 			break;
 		case graphics::ScalingEtc:
-			ret = _("Scaling etc...");
+			ret = _("Scaling etc…");
 			break;
 		case graphics::Ready:
 			ret = _("Ready to display");
diff --git a/src/support/docstring.cpp b/src/support/docstring.cpp
index f44259d..9b83204 100644
--- a/src/support/docstring.cpp
+++ b/src/support/docstring.cpp
@@ -175,11 +175,14 @@ bool operator==(lyx::docstring const & l, char const * r)
 	lyx::docstring::const_iterator it = l.begin();
 	lyx::docstring::const_iterator end = l.end();
 	for (; it != end; ++it, ++r) {
-		LASSERT(static_cast<unsigned char>(*r) < 0x80, return false);
-		if (!*r)
-			return false;
-		if (*it != static_cast<lyx::docstring::value_type>(*r))
-			return false;
+		if (static_cast<unsigned char>(*r) < 0x80) {
+			if (!*r)
+				return false;
+			if (*it != static_cast<lyx::docstring::value_type>(*r))
+				return false;
+		} else
+			return l.compare(it - l.begin(), lyx::docstring::npos,
+							 from_utf8(std::string(r)));
 	}
 	return *r == '\0';
 }
@@ -189,8 +192,10 @@ lyx::docstring operator+(lyx::docstring const & l, char const * r)
 {
 	lyx::docstring s(l);
 	for (char const * c = r; *c; ++c) {
-		LASSERT(static_cast<unsigned char>(*c) < 0x80, return l);
-		s.push_back(*c);
+		if (static_cast<unsigned char>(*c) < 0x80)
+			s.push_back(*c);
+		else
+			return s += from_utf8(string(c));
 	}
 	return s;
 }
@@ -200,8 +205,12 @@ lyx::docstring operator+(char const * l, lyx::docstring const & r)
 {
 	lyx::docstring s;
 	for (char const * c = l; *c; ++c) {
-		LASSERT(static_cast<unsigned char>(*c) < 0x80, return r);
-		s.push_back(*c);
+		if (static_cast<unsigned char>(*c) < 0x80)
+			s.push_back(*c);
+		else {
+			s += from_utf8(string(c));
+			break;
+		}
 	}
 	s += r;
 	return s;
@@ -227,8 +236,10 @@ lyx::docstring operator+(char l, lyx::docstring const & r)
 lyx::docstring & operator+=(lyx::docstring & l, char const * r)
 {
 	for (char const * c = r; *c; ++c) {
-		LASSERT(static_cast<unsigned char>(*c) < 0x80, return l);
-		l.push_back(*c);
+		if (static_cast<unsigned char>(*c) < 0x80)
+			l.push_back(*c);
+		else
+			return l += from_utf8(string(c));
 	}
 	return l;
 }
diff --git a/src/support/docstring.h b/src/support/docstring.h
index 2c2901b..2c14859 100644
--- a/src/support/docstring.h
+++ b/src/support/docstring.h
@@ -28,7 +28,8 @@ docstring const from_ascii(std::string const &);
 /// Creates a std::string of ASCII characters from a docstring
 std::string const to_ascii(docstring const &);
 
-/// Creates a docstring from a UTF8 string. This should go eventually.
+/// Creates a docstring from a UTF8 string.  Use this to convert string
+/// literals.
 docstring const from_utf8(std::string const &);
 
 /// Creates a UTF8 string from a docstring. This should go eventually.
@@ -61,22 +62,28 @@ docstring const from_iconv_encoding(std::string const & s,
 /// normalize \p s to precomposed form c
 docstring const normalize_c(docstring const & s);
 
-/// Compare a docstring with a C string of ASCII characters
+/// Compare a docstring with a C string of UTF-8 characters
+/// Optimised for ASCII
 bool operator==(docstring const &, char const *);
 
-/// Compare a C string of ASCII characters with a docstring
+/// Compare a C string of UTF-8 characters with a docstring
+/// Optimised for ASCII
 inline bool operator==(char const * l, docstring const & r) { return r == l; }
 
-/// Compare a docstring with a C string of ASCII characters
+/// Compare a docstring with a C string of UTF-8 characters
+/// Optimised for ASCII
 inline bool operator!=(docstring const & l, char const * r) { return !(l == r); }
 
-/// Compare a C string of ASCII characters with a docstring
+/// Compare a C string of UTF-8 characters with a docstring
+/// Optimised for ASCII
 inline bool operator!=(char const * l, docstring const & r) { return !(r == l); }
 
-/// Concatenate a docstring and a C string of ASCII characters
+/// Concatenate a docstring and a C string of UTF-8 characters
+/// Optimised for ASCII
 docstring operator+(docstring const &, char const *);
 
-/// Concatenate a C string of ASCII characters and a docstring
+/// Concatenate a C string of UTF-8 characters and a docstring
+/// Optimised for ASCII
 docstring operator+(char const *, docstring const &);
 
 /// Concatenate a docstring and a single ASCII character
@@ -85,7 +92,8 @@ docstring operator+(docstring const & l, char r);
 /// Concatenate a single ASCII character and a docstring
 docstring operator+(char l, docstring const & r);
 
-/// Append a C string of ASCII characters to a docstring
+/// Append a C string of UTF-8 characters to a docstring
+/// Optimised for ASCII
 docstring & operator+=(docstring &, char const *);
 
 /// Append a single ASCII character to a docstring
diff --git a/src/support/filetools.cpp b/src/support/filetools.cpp
index 6acfdf0..be3aae4 100644
--- a/src/support/filetools.cpp
+++ b/src/support/filetools.cpp
@@ -931,7 +931,6 @@ docstring const makeDisplayPath(string const & path, unsigned int threshold)
 	if (str.length() <= threshold)
 		return from_utf8(os::external_path(str));
 
-	string const prefix = ".../";
 	docstring dstr = from_utf8(str);
 	docstring temp;
 
@@ -949,7 +948,7 @@ docstring const makeDisplayPath(string const & path, unsigned int threshold)
 				dstr.substr(len - threshold / 2 - 2, len - 1);
 	}
 
-	return from_utf8(os::external_path(prefix + to_utf8(dstr)));
+	return from_utf8(os::external_path("…/" + to_utf8(dstr)));
 }
 
 
diff --git a/src/support/lstrings.cpp b/src/support/lstrings.cpp
index d06458b..5b2337c 100644
--- a/src/support/lstrings.cpp
+++ b/src/support/lstrings.cpp
@@ -1290,7 +1290,7 @@ docstring wrapParas(docstring const & str, int const indent,
 				else
 					truncateWithEllipsis(last, i);
 			} else
-				last.push_back(0x2026);//HORIZONTAL ELLIPSIS
+				last += "…";
 			tmp.pop_back();
 			tmp.push_back(last);
 		}
-- 
2.1.4

Reply via email to