From 0b3530142f6e07f96a004ffbdcb8ad92bdf91d2e Mon Sep 17 00:00:00 2001
From: Vadim Lopatin <coolreader.org@gmail.com>
Date: Mon, 14 Aug 2017 10:11:53 +0300
Subject: [PATCH 01/13] fix commandline workspace param processing after
 dlangui arg list change - item 0 is now executable filename

---
 dub.json       | 2 +-
 src/dlangide.d | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/dub.json b/dub.json
index 3bd1b2a..d01730f 100644
--- a/dub.json
+++ b/dub.json
@@ -12,7 +12,7 @@
     "stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi", "views/res/hdpi"],
 
     "dependencies": {
-        "dlangui": "==0.9.88",
+        "dlangui": "==0.9.89",
         "dcd": "~>0.9.0"
     },
 
diff --git a/src/dlangide.d b/src/dlangide.d
index 8ce8f87..cf4a506 100644
--- a/src/dlangide.d
+++ b/src/dlangide.d
@@ -88,10 +88,10 @@ extern (C) int UIAppMain(string[] args) {
         IDEFrame frame = new IDEFrame(window);
         
         // Open project, if it specified in command line
-        if (args.length > 0)
+        if (args.length > 1)
         {
             Action a = ACTION_FILE_OPEN_WORKSPACE.clone();
-            a.stringParam = args[0].toAbsolutePath;
+            a.stringParam = args[1].toAbsolutePath;
             frame.handleAction(a);
             // Mark that workspace opened to prevent auto open
             frame.isOpenedWorkspace(true);

From 7560d8347c306c152fd49cf65e09bf9a2bae7538 Mon Sep 17 00:00:00 2001
From: Vadim Lopatin <coolreader.org@gmail.com>
Date: Tue, 15 Aug 2017 15:26:38 +0300
Subject: [PATCH 02/13] DCD fixes; waiting for DSymbol PR

---
 src/dlangide/tools/d/dcdinterface.d | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/src/dlangide/tools/d/dcdinterface.d b/src/dlangide/tools/d/dcdinterface.d
index eb6e4f8..c465825 100644
--- a/src/dlangide/tools/d/dcdinterface.d
+++ b/src/dlangide/tools/d/dcdinterface.d
@@ -4,7 +4,6 @@ import dlangui.core.logger;
 import dlangui.core.files;
 import dlangui.platforms.common.platform;
 import ddebug.common.queue;
-import dsymbol.string_interning : internString;
 
 import core.thread;
 
@@ -59,7 +58,7 @@ class DCDTask {
     }
     void createRequest() {
         request.sourceCode = cast(ubyte[])_content;
-        request.fileName = internString(_filename);
+        request.fileName = _filename;
         request.cursorPosition = _index;
         request.importPaths = _importPaths;
     }
@@ -82,25 +81,16 @@ class DCDTask {
     }
 }
 
-string[] internStrings(in string[] src) {
-    if (!src)
-        return null;
-    string[] res;
-    foreach(s; src)
-        res ~= internString(s);
-    return res;
-}
-
 class ModuleCacheAccessor {
     import dsymbol.modulecache;
     //protected ASTAllocator _astAllocator;
     protected ModuleCache _moduleCache;
     this(in string[] importPaths) {
         _moduleCache = ModuleCache(new SharedASTAllocator);
-        _moduleCache.addImportPaths(internStrings(importPaths));
+        _moduleCache.addImportPaths(importPaths);
     }
     protected ModuleCache * getModuleCache(in string[] importPaths) {
-        _moduleCache.addImportPaths(internStrings(importPaths));
+        _moduleCache.addImportPaths(importPaths);
         return &_moduleCache;
     }
 }
@@ -161,6 +151,7 @@ class DCDInterface : Thread {
 
     void threadFunc() {
         _moduleCache = new ModuleCacheAccessor(null);
+        getModuleCache(null);
         Log.d("Starting DCD tasks thread");
         while (!_queue.closed()) {
             DCDTask task;
@@ -174,6 +165,7 @@ class DCDInterface : Thread {
             }
         }
         Log.d("Exiting DCD tasks thread");
+        destroyModuleCache();
     }
 
     import dsymbol.modulecache;

From d15e6e769a0ff1787dcc7bb2d27cc43db2553896 Mon Sep 17 00:00:00 2001
From: Vadim Lopatin <coolreader.org@gmail.com>
Date: Tue, 15 Aug 2017 15:52:32 +0300
Subject: [PATCH 03/13] fix #203 - DCD problem with multithreaded app

---
 dub.json                | 1 +
 src/dlangide/ui/frame.d | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/dub.json b/dub.json
index d01730f..bc01c49 100644
--- a/dub.json
+++ b/dub.json
@@ -13,6 +13,7 @@
 
     "dependencies": {
         "dlangui": "==0.9.89",
+        "dsymbol": "~>0.2.8",
         "dcd": "~>0.9.0"
     },
 
diff --git a/src/dlangide/ui/frame.d b/src/dlangide/ui/frame.d
index 6d15c85..02f47ca 100644
--- a/src/dlangide/ui/frame.d
+++ b/src/dlangide/ui/frame.d
@@ -46,7 +46,7 @@ import std.path;
 
 immutable string HELP_PAGE_URL = "https://github.com/buggins/dlangide/wiki";
 // TODO: get version from GIT commit
-immutable dstring DLANGIDE_VERSION = "v0.7.42"d;
+immutable dstring DLANGIDE_VERSION = "v0.7.44"d;
 
 bool isSupportedSourceTextFileFormat(string filename) {
     return (filename.endsWith(".d") || filename.endsWith(".di") || filename.endsWith(".dt") || filename.endsWith(".txt") || filename.endsWith(".cpp") || filename.endsWith(".h") || filename.endsWith(".c")

From d0b9ff8a0e28d3ce1e201bc00c08448021c70b9d Mon Sep 17 00:00:00 2001
From: Vadim Lopatin <coolreader.org@gmail.com>
Date: Tue, 15 Aug 2017 17:47:02 +0300
Subject: [PATCH 04/13] implementation of #237 - save file as -- first part

---
 dub.json                         |  5 ++-
 src/dlangide/ui/dsourceedit.d    |  9 ++++++
 src/dlangide/ui/frame.d          | 52 ++++++++++++++++++++++++++++++--
 src/dlangide/workspace/project.d |  5 +++
 views/res/i18n/en.ini            |  1 +
 views/res/i18n/ru.ini            |  1 +
 6 files changed, 67 insertions(+), 6 deletions(-)

diff --git a/dub.json b/dub.json
index bc01c49..84f40d2 100644
--- a/dub.json
+++ b/dub.json
@@ -12,9 +12,8 @@
     "stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi", "views/res/hdpi"],
 
     "dependencies": {
-        "dlangui": "==0.9.89",
-        "dsymbol": "~>0.2.8",
-        "dcd": "~>0.9.0"
+        "dlangui": "==0.9.90",
+        "dcd": "~>0.9.1"
     },
 
     "copyFiles-windows": [
diff --git a/src/dlangide/ui/dsourceedit.d b/src/dlangide/ui/dsourceedit.d
index b1939cf..fbdeb66 100644
--- a/src/dlangide/ui/dsourceedit.d
+++ b/src/dlangide/ui/dsourceedit.d
@@ -125,6 +125,7 @@ class DSourceEdit : SourceEdit, EditableContentMarksChangeListener {
 
     protected ProjectSourceFile _projectSourceFile;
     @property ProjectSourceFile projectSourceFile() { return _projectSourceFile; }
+    @property void projectSourceFile(ProjectSourceFile v) { _projectSourceFile = v; }
     /// load by filename
     override bool load(string fn) {
         _projectSourceFile = null;
@@ -224,6 +225,14 @@ class DSourceEdit : SourceEdit, EditableContentMarksChangeListener {
         return _content.save();
     }
 
+    /// save to the same file
+    override bool save(string fn) {
+        bool res = super.save(fn);
+        //if (res && projectSourceFile)
+        //    projectSourceFile.setFilename(filename);
+        return res;
+    }
+
     void insertCompletion(dstring completionText) {
         TextRange range;
         TextPosition p = caretPos;
diff --git a/src/dlangide/ui/frame.d b/src/dlangide/ui/frame.d
index 02f47ca..42f7e92 100644
--- a/src/dlangide/ui/frame.d
+++ b/src/dlangide/ui/frame.d
@@ -46,7 +46,7 @@ import std.path;
 
 immutable string HELP_PAGE_URL = "https://github.com/buggins/dlangide/wiki";
 // TODO: get version from GIT commit
-immutable dstring DLANGIDE_VERSION = "v0.7.44"d;
+immutable dstring DLANGIDE_VERSION = "v0.7.45"d;
 
 bool isSupportedSourceTextFileFormat(string filename) {
     return (filename.endsWith(".d") || filename.endsWith(".di") || filename.endsWith(".dt") || filename.endsWith(".txt") || filename.endsWith(".cpp") || filename.endsWith(".h") || filename.endsWith(".c")
@@ -514,6 +514,18 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
         _tabs.removeTab(tabId);
     }
 
+    void renameTab(string oldfilename, string newfilename) {
+        int index = _tabs.tabIndex(newfilename);
+        if (index >= 0) {
+            // file is already opened in tab - close it
+            _tabs.removeTab(newfilename);
+        }
+        int oldindex = _tabs.tabIndex(oldfilename);
+        if (oldindex >= 0) {
+            _tabs.renameTab(oldindex, newfilename, UIString.fromRaw(newfilename.baseName));
+        }
+    }
+
     /// close all editor tabs
     void closeAllDocuments() {
         for (int i = _tabs.tabCount - 1; i >= 0; i--) {
@@ -879,8 +891,8 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
         }
     }
 
-    FileDialog createFileDialog(UIString caption) {
-        FileDialog dlg = new FileDialog(caption, window, null);
+    FileDialog createFileDialog(UIString caption, int fileDialogFlags = DialogFlag.Modal | DialogFlag.Resizable | FileDialogFlag.FileMustExist) {
+        FileDialog dlg = new FileDialog(caption, window, null, fileDialogFlags);
         dlg.filetypeIcons[".d"] = "text-d";
         dlg.filetypeIcons["dub.json"] = "project-d";
         dlg.filetypeIcons["dub.sdl"] = "project-d";
@@ -910,6 +922,40 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
                 case StandardAction.OpenUrl:
                     platform.openURL(a.stringParam);
                     return true;
+                case IDEActions.FileSaveAs:
+                    DSourceEdit ed = currentEditor;
+                    UIString caption;
+                    caption = UIString.fromId("HEADER_SAVE_FILE_AS"c);
+                    FileDialog dlg = createFileDialog(caption, DialogFlag.Modal | DialogFlag.Resizable | FileDialogFlag.Save);
+                    dlg.addFilter(FileFilterEntry(UIString.fromId("SOURCE_FILES"c), "*.d;*.dd;*.ddoc;*.di;*.dt;*.dh;*.json;*.sdl;*.xml;*.ini"));
+                    dlg.addFilter(FileFilterEntry(UIString.fromId("ALL_FILES"c), "*.*"));
+                    dlg.path = ed.filename.dirName;
+                    dlg.filename = ed.filename;
+                    dlg.dialogResult = delegate(Dialog d, const Action result) {
+                        if (result.id == ACTION_SAVE.id) {
+                            string oldfilename = ed.filename;
+                            string filename = result.stringParam;
+                            ed.save(filename);
+                            if (oldfilename == filename)
+                                return;
+                            renameTab(oldfilename, filename);
+                            ed.id = filename;
+                            if( filename.endsWith(".d") || filename.endsWith(".di") )
+                                ed.editorTool = new DEditorTool(this);
+                            else
+                                ed.editorTool = new DefaultEditorTool(this);
+                            //openSourceFile(filename);
+                            refreshWorkspace();
+                            ProjectSourceFile file = _wsPanel.findSourceFileItem(filename, false);
+                            if (file)
+                                ed.projectSourceFile = file;
+                            else
+                                ed.projectSourceFile = null;
+                            _settings.setRecentPath(dlg.path, "FILE_OPEN_PATH");
+                        }
+                    };
+                    dlg.show();
+                    return true;
                 case IDEActions.FileOpen:
                     UIString caption;
                     caption = UIString.fromId("HEADER_OPEN_TEXT_FILE"c);
diff --git a/src/dlangide/workspace/project.d b/src/dlangide/workspace/project.d
index a4fef92..fc2db3b 100644
--- a/src/dlangide/workspace/project.d
+++ b/src/dlangide/workspace/project.d
@@ -227,6 +227,11 @@ class ProjectSourceFile : ProjectItem {
     @property string projectFilePath() {
         return project.absoluteToRelativePath(filename);
     }
+
+    void setFilename(string filename) {
+        _filename = buildNormalizedPath(filename);
+        _name = toUTF32(baseName(_filename));
+    }
 }
 
 class WorkspaceItem {
diff --git a/views/res/i18n/en.ini b/views/res/i18n/en.ini
index 99f95ca..ca920c0 100644
--- a/views/res/i18n/en.ini
+++ b/views/res/i18n/en.ini
@@ -117,6 +117,7 @@ MENU_PROJECT_REVEAL_IN_EXPLORER=Reveal in Explorer
 HEADER_SETTINGS=DlangIDE settings
 HEADER_OPEN_WORKSPACE_OR_PROJECT=Open Workspace or Project
 HEADER_OPEN_TEXT_FILE=Open Text File
+HEADER_SAVE_FILE_AS=Save File As
 
 OPTION_ADD_TO_CURRENT_WORKSPACE=Add to current workspace
 OPTION_AUTO_OPEN_LAST_PROJECT=Auto open last project
diff --git a/views/res/i18n/ru.ini b/views/res/i18n/ru.ini
index 7c0a4cc..14258ec 100644
--- a/views/res/i18n/ru.ini
+++ b/views/res/i18n/ru.ini
@@ -117,6 +117,7 @@ MENU_PROJECT_REVEAL_IN_EXPLORER=Открыть в проводнике
 HEADER_SETTINGS=DlangIDE настройки
 HEADER_OPEN_WORKSPACE_OR_PROJECT=Открыть рабочее пространство или проект
 HEADER_OPEN_TEXT_FILE=Открыть текстовый файл
+HEADER_SAVE_FILE_AS=Сохранить как
 
 OPTION_ADD_TO_CURRENT_WORKSPACE=Добавить в текущее пр-во
 OPTION_AUTO_OPEN_LAST_PROJECT=Авт.открывать последний проект

From 8f2686677a5aebc7d4552807e96fc673fa3f1828 Mon Sep 17 00:00:00 2001
From: Vadim Lopatin <coolreader.org@gmail.com>
Date: Mon, 21 Aug 2017 14:38:15 +0300
Subject: [PATCH 05/13] update dlangui dep version - fix scrollbars

---
 dub.json                | 2 +-
 src/dlangide/ui/frame.d | 5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/dub.json b/dub.json
index 84f40d2..f948013 100644
--- a/dub.json
+++ b/dub.json
@@ -12,7 +12,7 @@
     "stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi", "views/res/hdpi"],
 
     "dependencies": {
-        "dlangui": "==0.9.90",
+        "dlangui": "==0.9.93",
         "dcd": "~>0.9.1"
     },
 
diff --git a/src/dlangide/ui/frame.d b/src/dlangide/ui/frame.d
index 42f7e92..f41b9e1 100644
--- a/src/dlangide/ui/frame.d
+++ b/src/dlangide/ui/frame.d
@@ -940,6 +940,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
                                 return;
                             renameTab(oldfilename, filename);
                             ed.id = filename;
+                            ed.setSyntaxSupport();
                             if( filename.endsWith(".d") || filename.endsWith(".di") )
                                 ed.editorTool = new DEditorTool(this);
                             else
@@ -947,9 +948,9 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
                             //openSourceFile(filename);
                             refreshWorkspace();
                             ProjectSourceFile file = _wsPanel.findSourceFileItem(filename, false);
-                            if (file)
+                            if (file) {
                                 ed.projectSourceFile = file;
-                            else
+                            } else
                                 ed.projectSourceFile = null;
                             _settings.setRecentPath(dlg.path, "FILE_OPEN_PATH");
                         }

From 99315708d30b01291087f574ba6edf453002f1f3 Mon Sep 17 00:00:00 2001
From: Vadim Lopatin <coolreader.org@gmail.com>
Date: Thu, 24 Aug 2017 10:49:08 +0300
Subject: [PATCH 06/13] update dlangui version to fix scrollbar issue #236

---
 dub.json                | 2 +-
 src/dlangide/ui/frame.d | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/dub.json b/dub.json
index f948013..7ab5943 100644
--- a/dub.json
+++ b/dub.json
@@ -12,7 +12,7 @@
     "stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi", "views/res/hdpi"],
 
     "dependencies": {
-        "dlangui": "==0.9.93",
+        "dlangui": "==0.9.94",
         "dcd": "~>0.9.1"
     },
 
diff --git a/src/dlangide/ui/frame.d b/src/dlangide/ui/frame.d
index f41b9e1..9a85863 100644
--- a/src/dlangide/ui/frame.d
+++ b/src/dlangide/ui/frame.d
@@ -46,7 +46,7 @@ import std.path;
 
 immutable string HELP_PAGE_URL = "https://github.com/buggins/dlangide/wiki";
 // TODO: get version from GIT commit
-immutable dstring DLANGIDE_VERSION = "v0.7.45"d;
+immutable dstring DLANGIDE_VERSION = "v0.7.47"d;
 
 bool isSupportedSourceTextFileFormat(string filename) {
     return (filename.endsWith(".d") || filename.endsWith(".di") || filename.endsWith(".dt") || filename.endsWith(".txt") || filename.endsWith(".cpp") || filename.endsWith(".h") || filename.endsWith(".c")

From 68307368e551cbcb4ba7830787c1917d02c33ff5 Mon Sep 17 00:00:00 2001
From: Vadim Lopatin <coolreader.org@gmail.com>
Date: Fri, 25 Aug 2017 10:17:10 +0300
Subject: [PATCH 07/13] link with zlib; put version to separate file
 views/VERSION

---
 dub.json                | 4 +++-
 src/dlangide/ui/frame.d | 3 ++-
 views/VERSION           | 1 +
 3 files changed, 6 insertions(+), 2 deletions(-)
 create mode 100644 views/VERSION

diff --git a/dub.json b/dub.json
index 7ab5943..a9f9df2 100644
--- a/dub.json
+++ b/dub.json
@@ -12,7 +12,7 @@
     "stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi", "views/res/hdpi"],
 
     "dependencies": {
-        "dlangui": "==0.9.94",
+        "dlangui": "==0.9.95",
         "dcd": "~>0.9.1"
     },
 
@@ -20,6 +20,8 @@
         "libs/windows/x86/mago-mi.exe"
     ],
 
+    "libs-linux": ["z"],
+
     "configurations" : [
         {
             "name" : "default"
diff --git a/src/dlangide/ui/frame.d b/src/dlangide/ui/frame.d
index 9a85863..aca5865 100644
--- a/src/dlangide/ui/frame.d
+++ b/src/dlangide/ui/frame.d
@@ -46,7 +46,8 @@ import std.path;
 
 immutable string HELP_PAGE_URL = "https://github.com/buggins/dlangide/wiki";
 // TODO: get version from GIT commit
-immutable dstring DLANGIDE_VERSION = "v0.7.47"d;
+//version is now stored in file views/VERSION
+immutable dstring DLANGIDE_VERSION = toUTF32(import("VERSION"));
 
 bool isSupportedSourceTextFileFormat(string filename) {
     return (filename.endsWith(".d") || filename.endsWith(".di") || filename.endsWith(".dt") || filename.endsWith(".txt") || filename.endsWith(".cpp") || filename.endsWith(".h") || filename.endsWith(".c")
diff --git a/views/VERSION b/views/VERSION
new file mode 100644
index 0000000..c836689
--- /dev/null
+++ b/views/VERSION
@@ -0,0 +1 @@
+v0.7.48
\ No newline at end of file

From fa8841ce24fdda0f41b344c2c5f25f03738d0fea Mon Sep 17 00:00:00 2001
From: Vadim Lopatin <coolreader.org@gmail.com>
Date: Fri, 25 Aug 2017 11:55:14 +0300
Subject: [PATCH 08/13] fix zlib linking

---
 .travis.yml   | 4 ++--
 dub.json      | 2 +-
 views/VERSION | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 4a49ed1..bf4e0d3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -30,10 +30,10 @@ install:
       then
         sudo dpkg --add-architecture i386
         sudo apt-get update
-        sudo apt-get install -y gcc-multilib libgl1-mesa-glx:i386 libfreetype6:i386 libsdl2-2.0-0:i386
+        sudo apt-get install -y gcc-multilib libgl1-mesa-glx:i386 libfreetype6:i386 libsdl2-2.0-0:i386 zlib1g-dev:i386
       else
         sudo apt-get update
-        sudo apt-get install -y libfreetype6 libsdl2-2.0-0
+        sudo apt-get install -y libfreetype6 libsdl2-2.0-0 zlib1g-dev
       fi
     fi
 
diff --git a/dub.json b/dub.json
index a9f9df2..ab52088 100644
--- a/dub.json
+++ b/dub.json
@@ -12,7 +12,7 @@
     "stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi", "views/res/hdpi"],
 
     "dependencies": {
-        "dlangui": "==0.9.95",
+        "dlangui": "==0.9.97",
         "dcd": "~>0.9.1"
     },
 
diff --git a/views/VERSION b/views/VERSION
index c836689..8c606b7 100644
--- a/views/VERSION
+++ b/views/VERSION
@@ -1 +1 @@
-v0.7.48
\ No newline at end of file
+v0.7.50
\ No newline at end of file

From 8fffaa9e0976dd4eea3c2d1f73342838cfe96c06 Mon Sep 17 00:00:00 2001
From: Vadim Lopatin <coolreader.org@gmail.com>
Date: Fri, 25 Aug 2017 15:07:08 +0300
Subject: [PATCH 09/13] UI settings - fontFace and fontSize

---
 src/dlangide/ui/settings.d           | 88 ++++++++++++++++++----------
 src/dlangide/workspace/idesettings.d |  2 +
 views/res/i18n/en.ini                |  1 +
 3 files changed, 61 insertions(+), 30 deletions(-)

diff --git a/src/dlangide/ui/settings.d b/src/dlangide/ui/settings.d
index 6fb134a..ef24c25 100644
--- a/src/dlangide/ui/settings.d
+++ b/src/dlangide/ui/settings.d
@@ -10,6 +10,55 @@ public import dlangide.workspace.projectsettings;
 public import dlangide.workspace.idesettings;
 public import dlangide.workspace.workspacesettings;
 
+StringListValue[] createFaceList(bool monospaceFirst) {
+    StringListValue[] faces;
+    faces.assumeSafeAppend();
+    faces ~= StringListValue("Default", "OPTION_DEFAULT"c);
+    import dlangui.graphics.fonts;
+    import std.utf : toUTF32;
+    FontFaceProps[] allFaces = FontManager.instance.getFaces();
+    import std.algorithm.sorting : sort;
+    auto fontCompMonospaceFirst = function(ref FontFaceProps a, ref FontFaceProps b) {
+        if (a.family == FontFamily.MonoSpace && b.family != FontFamily.MonoSpace)
+            return -1;
+        if (a.family != FontFamily.MonoSpace && b.family == FontFamily.MonoSpace)
+            return 1;
+        if (a.face < b.face)
+            return -1;
+        if (a.face > b.face)
+            return 1;
+        return 0;
+    };
+    auto fontComp = function(ref FontFaceProps a, ref FontFaceProps b) {
+        if (a.face < b.face)
+            return -1;
+        if (a.face > b.face)
+            return 1;
+        return 0;
+    };
+    //auto sorted = allFaces.sort!((a, b) => (a.family == FontFamily.MonoSpace && b.family != FontFamily.MonoSpace) || (a.face < b.face));
+    auto sorted = sort!((a, b) => (monospaceFirst ? fontCompMonospaceFirst(a, b) : fontComp(a, b)) < 0)(allFaces);
+
+    //allFaces = allFaces.sort!((a, b) => a.family == FontFamily.MonoSpace && b.family == FontFamily.MonoSpace || a.face < b.face);
+    //for (int i = 0; i < allFaces.length; i++) {
+    foreach (face; sorted) {
+        if (face.family == FontFamily.MonoSpace)
+            faces ~= StringListValue(face.face, "*"d ~ toUTF32(face.face));
+        else
+            faces ~= StringListValue(face.face, toUTF32(face.face));
+    }
+    return faces;
+}
+
+StringListValue[] createIntValueList(int[] values, dstring suffix = ""d) {
+    StringListValue[] res;
+    res.assumeSafeAppend();
+    foreach(n; values) {
+        res ~= StringListValue(n, to!dstring(n) ~ suffix);
+    }
+    return res;
+}
+
 /// create DlangIDE settings pages tree
 SettingsPage createSettingsPages() {
     // Root page
@@ -30,6 +79,13 @@ SettingsPage createSettingsPages() {
             StringListValue("es", "MENU_VIEW_LANGUAGE_ES"c),
 	    StringListValue("cs", "MENU_VIEW_LANGUAGE_CS"c)]);
 
+    // UI font faces
+    ui.addStringComboBox("interface/uiFontFace", UIString.fromId("OPTION_FONT_FACE"c), 
+                      createFaceList(false));
+    ui.addIntComboBox("interface/uiFontSize", UIString.fromId("OPTION_FONT_SIZE"c), 
+                      createIntValueList([6,7,8,9,10,11,12,14,16,18,20,22,24,26,28,30,32]));
+
+
     ui.addIntComboBox("interface/hintingMode", UIString.fromId("OPTION_FONT_HINTING"c), [StringListValue(0, "OPTION_FONT_HINTING_NORMAL"c), 
                 StringListValue(1, "OPTION_FONT_HINTING_FORCE"c), 
                 StringListValue(2, "OPTION_FONT_HINTING_DISABLED"c), StringListValue(3, "OPTION_FONT_HINTING_LIGHT"c)]);
@@ -67,36 +123,8 @@ SettingsPage createSettingsPages() {
     SettingsPage ed = res.addChild("editors", UIString.fromId("OPTION_EDITORS"c));
     SettingsPage texted = ed.addChild("editors/textEditor", UIString.fromId("OPTION_TEXT_EDITORS"c));
 
-    // font faces
-    StringListValue[] faces;
-    faces ~= StringListValue("Default", "OPTION_DEFAULT"c);
-    import dlangui.graphics.fonts;
-    import std.utf : toUTF32;
-    FontFaceProps[] allFaces = FontManager.instance.getFaces();
-    import std.algorithm.sorting : sort;
-    auto fontComp = function(ref FontFaceProps a, ref FontFaceProps b) {
-        if (a.family == FontFamily.MonoSpace && b.family != FontFamily.MonoSpace)
-            return -1;
-        if (a.family != FontFamily.MonoSpace && b.family == FontFamily.MonoSpace)
-            return 1;
-        if (a.face < b.face)
-            return -1;
-        if (a.face > b.face)
-            return 1;
-        return 0;
-    };
-    //auto sorted = allFaces.sort!((a, b) => (a.family == FontFamily.MonoSpace && b.family != FontFamily.MonoSpace) || (a.face < b.face));
-    auto sorted = sort!((a, b) => fontComp(a, b) < 0)(allFaces);
-    
-    //allFaces = allFaces.sort!((a, b) => a.family == FontFamily.MonoSpace && b.family == FontFamily.MonoSpace || a.face < b.face);
-    //for (int i = 0; i < allFaces.length; i++) {
-    foreach (face; sorted) {
-        if (face.family == FontFamily.MonoSpace)
-            faces ~= StringListValue(face.face, "*"d ~ toUTF32(face.face));
-        else
-            faces ~= StringListValue(face.face, toUTF32(face.face));
-    }
-    texted.addStringComboBox("editors/textEditor/fontFace", UIString.fromId("OPTION_FONT_FACE"c), faces);
+    // editor font faces
+    texted.addStringComboBox("editors/textEditor/fontFace", UIString.fromId("OPTION_FONT_FACE"c), createFaceList(true));
 
     texted.addNumberEdit("editors/textEditor/tabSize", UIString.fromId("OPTION_TAB"c), 1, 16, 4);
     texted.addCheckbox("editors/textEditor/useSpacesForTabs", UIString.fromId("OPTION_USE_SPACES"c));
diff --git a/src/dlangide/workspace/idesettings.d b/src/dlangide/workspace/idesettings.d
index d847c2a..5e0e495 100644
--- a/src/dlangide/workspace/idesettings.d
+++ b/src/dlangide/workspace/idesettings.d
@@ -30,6 +30,8 @@ class IDESettings : SettingsFile {
         ui.setIntegerDef("hintingMode", 1);
         ui.setIntegerDef("minAntialiasedFontSize", 0);
         ui.setFloatingDef("fontGamma", 0.8);
+        ui.setStringDef("uiFontFace", "Default");
+        ui.setIntegerDef("uiFontSize", 10);
         version (Windows) {
             debuggerSettings.setStringDef("executable", "mago-mi");
         } else {
diff --git a/views/res/i18n/en.ini b/views/res/i18n/en.ini
index ca920c0..6ab7e3d 100644
--- a/views/res/i18n/en.ini
+++ b/views/res/i18n/en.ini
@@ -141,6 +141,7 @@ OPTION_FONT_HINTING_FORCE=Force Auto Hint
 OPTION_FONT_HINTING_NORMAL=Normal
 OPTION_FONT_HINTING_LIGHT=LIGHT
 OPTION_FONT_FACE=Font face
+OPTION_FONT_SIZE=Font face
 OPTION_FONT_GAMMA=Font gamma
 OPTION_GDC_EXECUTABLE=GDC executable
 OPTION_LANGUAGE=Language

From a318577f97054bb31a2c660ac41938ef76e95e08 Mon Sep 17 00:00:00 2001
From: Vadim Lopatin <coolreader.org@gmail.com>
Date: Fri, 25 Aug 2017 17:01:25 +0300
Subject: [PATCH 10/13] apply ui font changes

---
 src/dlangide/ui/frame.d              | 16 ++++++++++++++++
 src/dlangide/workspace/idesettings.d | 10 ++++++++++
 2 files changed, 26 insertions(+)

diff --git a/src/dlangide/ui/frame.d b/src/dlangide/ui/frame.d
index aca5865..f7e9048 100644
--- a/src/dlangide/ui/frame.d
+++ b/src/dlangide/ui/frame.d
@@ -1354,6 +1354,22 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
         FontManager.minAnitialiasedFontSize = settings.minAntialiasedFontSize;
         Platform.instance.uiLanguage = settings.uiLanguage;
         Platform.instance.uiTheme = settings.uiTheme;
+        bool needUpdateTheme = false;
+        string oldFontFace = currentTheme.fontFace;
+        string newFontFace = settings.uiFontFace;
+        if (newFontFace == "Default")
+            newFontFace = "Helvetica Neue,Verdana,Arial,DejaVu Sans,Liberation Sans,Helvetica,Roboto,Droid Sans";
+        int oldFontSize = currentTheme.fontSize;
+        if (oldFontFace != newFontFace) {
+            currentTheme.fontFace = newFontFace;
+            needUpdateTheme = true;
+        }
+        if (oldFontSize != settings.uiFontSize) {
+            currentTheme.fontSize = settings.uiFontSize;
+            needUpdateTheme = true;
+        }
+        if (needUpdateTheme)
+            Platform.instance.onThemeChanged();
         requestLayout();
     }
 
diff --git a/src/dlangide/workspace/idesettings.d b/src/dlangide/workspace/idesettings.d
index 5e0e495..f70e6a8 100644
--- a/src/dlangide/workspace/idesettings.d
+++ b/src/dlangide/workspace/idesettings.d
@@ -126,6 +126,16 @@ class IDESettings : SettingsFile {
         return this;
     }
 
+    /// UI font face
+    @property string uiFontFace() {
+        return uiSettings.getString("uiFontFace", "Default");
+    }
+
+    /// UI font size
+    @property int uiFontSize() {
+        return pointsToPixels(cast(int)uiSettings.getInteger("uiFontSize", 10));
+    }
+
     /// text editor setting, true if need to insert spaces instead of tabs
     @property bool useSpacesForTabs() {
         return editorSettings.getBoolean("useSpacesForTabs", true);

From e530b93426d761068d5e7490ba236a39c58a856b Mon Sep 17 00:00:00 2001
From: Vadim Lopatin <coolreader.org@gmail.com>
Date: Fri, 25 Aug 2017 18:00:18 +0300
Subject: [PATCH 11/13] attempt to resolve #242, #229

---
 dub.json                   | 2 +-
 src/dlangide/ui/settings.d | 1 +
 views/VERSION              | 2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/dub.json b/dub.json
index ab52088..d3ac9c4 100644
--- a/dub.json
+++ b/dub.json
@@ -12,7 +12,7 @@
     "stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi", "views/res/hdpi"],
 
     "dependencies": {
-        "dlangui": "==0.9.97",
+        "dlangui": "==0.9.98",
         "dcd": "~>0.9.1"
     },
 
diff --git a/src/dlangide/ui/settings.d b/src/dlangide/ui/settings.d
index ef24c25..ee7aa42 100644
--- a/src/dlangide/ui/settings.d
+++ b/src/dlangide/ui/settings.d
@@ -51,6 +51,7 @@ StringListValue[] createFaceList(bool monospaceFirst) {
 }
 
 StringListValue[] createIntValueList(int[] values, dstring suffix = ""d) {
+    import std.conv : to;
     StringListValue[] res;
     res.assumeSafeAppend();
     foreach(n; values) {
diff --git a/views/VERSION b/views/VERSION
index 8c606b7..0b07401 100644
--- a/views/VERSION
+++ b/views/VERSION
@@ -1 +1 @@
-v0.7.50
\ No newline at end of file
+v0.7.51
\ No newline at end of file

From f7f97f80f2249e0f97e1027c98b564caddf8616f Mon Sep 17 00:00:00 2001
From: Vadim Lopatin <coolreader.org@gmail.com>
Date: Fri, 25 Aug 2017 19:53:53 +0300
Subject: [PATCH 12/13] #242 additional change

---
 dub.json      | 2 +-
 views/VERSION | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/dub.json b/dub.json
index d3ac9c4..026d787 100644
--- a/dub.json
+++ b/dub.json
@@ -12,7 +12,7 @@
     "stringImportPaths": ["views", "views/res", "views/res/i18n", "views/res/mdpi", "views/res/hdpi"],
 
     "dependencies": {
-        "dlangui": "==0.9.98",
+        "dlangui": "==0.9.99",
         "dcd": "~>0.9.1"
     },
 
diff --git a/views/VERSION b/views/VERSION
index 0b07401..7114f72 100644
--- a/views/VERSION
+++ b/views/VERSION
@@ -1 +1 @@
-v0.7.51
\ No newline at end of file
+v0.7.52
\ No newline at end of file

From 9d516c99d00f19e21a892d6830c8d43f1e6de283 Mon Sep 17 00:00:00 2001
From: and3md <and3md@gmail.com>
Date: Fri, 25 Aug 2017 19:55:52 +0200
Subject: [PATCH 13/13] More recent dlangui version when create new dlangui
 based project.

---
 src/dlangide/ui/newproject.d | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/dlangide/ui/newproject.d b/src/dlangide/ui/newproject.d
index f180b35..8c1f181 100644
--- a/src/dlangide/ui/newproject.d
+++ b/src/dlangide/ui/newproject.d
@@ -513,7 +513,7 @@ extern (C) int UIAppMain(string[] args) {
 immutable string DUB_JSON_DLANGUI_HELLOWORLD = q{
 {
     "dependencies": {
-        "dlangui": "~>0.9.24"
+        "dlangui": "~>0.9.99"
     }
 }