From 5329556cb0efd7039d06115e3caeee39f760a6fe Mon Sep 17 00:00:00 2001
From: Martyn Gigg <martyn.gigg@gmail.com>
Date: Mon, 15 Jan 2018 09:19:01 +0000
Subject: [PATCH] Mark tab as modified when editor content is modified

Refs #21251
---
 .../workbench/workbench/app/mainwindow.py     |  6 +--
 .../widgets/codeeditor/interpreter.py         |  7 +++-
 .../codeeditor/multifileinterpreter.py        | 41 ++++++++++++++-----
 .../mantidqt/widgets/src/_widgetscore.sip     |  3 ++
 4 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/qt/applications/workbench/workbench/app/mainwindow.py b/qt/applications/workbench/workbench/app/mainwindow.py
index 8723ff693fd..d71698bcc9c 100644
--- a/qt/applications/workbench/workbench/app/mainwindow.py
+++ b/qt/applications/workbench/workbench/app/mainwindow.py
@@ -127,7 +127,7 @@ class MainWindow(QMainWindow):
         # Menus
         self.file_menu = None
         self.file_menu_actions = None
-        self.editors_menu = None
+        self.editor_menu = None
 
         # Allow splash screen text to be overridden in set_splash
         self.splash = SPLASH
@@ -157,7 +157,7 @@ class MainWindow(QMainWindow):
         self.set_splash("Loading code editing widget")
         from workbench.plugins.editor import MultiFileEditor
         self.editor = MultiFileEditor(self)
-        self.editor.register_plugin(self.editors_menu)
+        self.editor.register_plugin(self.editor_menu)
         self.widgets.append(self.editor)
 
         self.setup_layout()
@@ -173,7 +173,7 @@ class MainWindow(QMainWindow):
 
     def create_menus(self):
         self.file_menu = self.menuBar().addMenu("&File")
-        self.editors_menu = self.menuBar().addMenu("&Editors")
+        self.editor_menu = self.menuBar().addMenu("&Editor")
 
     def create_actions(self):
         # --- general application menu options --
diff --git a/qt/python/mantidqt/widgets/codeeditor/interpreter.py b/qt/python/mantidqt/widgets/codeeditor/interpreter.py
index 0df153ca682..0d55d36adba 100644
--- a/qt/python/mantidqt/widgets/codeeditor/interpreter.py
+++ b/qt/python/mantidqt/widgets/codeeditor/interpreter.py
@@ -20,7 +20,7 @@ from __future__ import (absolute_import, unicode_literals)
 import sys
 
 # 3rd party imports
-from qtpy.QtCore import QObject
+from qtpy.QtCore import QObject, Signal
 from qtpy.QtGui import QColor, QFontMetrics
 from qtpy.QtWidgets import QStatusBar, QVBoxLayout, QWidget
 
@@ -41,6 +41,8 @@ TAB_WIDTH = 4
 
 class PythonFileInterpreter(QWidget):
 
+    sig_editor_modified = Signal(bool)
+
     def __init__(self, default_content=None, parent=None):
         """
         :param parent: A parent QWidget
@@ -58,9 +60,10 @@ class PythonFileInterpreter(QWidget):
 
         self._setup_editor(default_content)
 
-        # presenter
         self._presenter = PythonFileInterpreterPresenter(self, PythonCodeExecution())
 
+        self.editor.modificationChanged.connect(self.sig_editor_modified)
+
     def execute_async(self):
         self._presenter.req_execute_async()
 
diff --git a/qt/python/mantidqt/widgets/codeeditor/multifileinterpreter.py b/qt/python/mantidqt/widgets/codeeditor/multifileinterpreter.py
index 60ca774d5c5..765e4eeed0c 100644
--- a/qt/python/mantidqt/widgets/codeeditor/multifileinterpreter.py
+++ b/qt/python/mantidqt/widgets/codeeditor/multifileinterpreter.py
@@ -22,6 +22,9 @@ from qtpy.QtWidgets import QTabWidget, QVBoxLayout, QWidget
 # local imports
 from mantidqt.widgets.codeeditor.interpreter import PythonFileInterpreter
 
+NEW_TAB_TITLE = 'temp.py'
+MODIFIED_MARKER = '*'
+
 
 class MultiPythonFileInterpreter(QWidget):
     """Provides a tabbed widget for editing multiple files"""
@@ -33,10 +36,10 @@ class MultiPythonFileInterpreter(QWidget):
         self.default_content = default_content
 
         # layout
-        self._editors = QTabWidget(self)
-        self._editors.setMovable(True)
+        self._tabs = QTabWidget(self)
+        self._tabs.setMovable(True)
         layout = QVBoxLayout()
-        layout.addWidget(self._editors)
+        layout.addWidget(self._tabs)
         self.setLayout(layout)
         layout.setContentsMargins(0, 0, 0, 0)
 
@@ -45,18 +48,36 @@ class MultiPythonFileInterpreter(QWidget):
 
     @property
     def editor_count(self):
-        return self._editors.count()
+        return self._tabs.count()
+
+    def append_new_editor(self):
+        interpreter = PythonFileInterpreter(self.default_content,
+                                            parent=self._tabs)
+        interpreter.sig_editor_modified.connect(self.update_tab_title)
+        self._tabs.addTab(interpreter, NEW_TAB_TITLE)
+        self.update_tab_title(modified=True)
 
     def current_editor(self):
-        return self._editors.currentWidget()
+        return self._tabs.currentWidget()
 
     def execute_current(self):
         """Execute content of the current file. If a selection is active
         then only this portion of code is executed"""
         self.current_editor().execute_async()
 
-    def append_new_editor(self):
-        title = "New"
-        self._editors.addTab(PythonFileInterpreter(self.default_content,
-                                                   parent=None),
-                             title)
+    def update_tab_title(self, modified):
+        """Update the current tab title to indicate that the
+        content has been modified"""
+        idx_cur = self._tabs.currentIndex()
+        title_cur = self._tabs.tabText(idx_cur)
+        if modified:
+            if not title_cur.endswith(MODIFIED_MARKER):
+                title_new = title_cur + MODIFIED_MARKER
+            else:
+                title_new = title_cur
+        else:
+            if title_cur.endswith(MODIFIED_MARKER):
+                title_new = title_cur.rstrip('*')
+            else:
+                title_new = title_cur
+        self._tabs.setTabText(idx_cur, title_new)
diff --git a/qt/python/mantidqt/widgets/src/_widgetscore.sip b/qt/python/mantidqt/widgets/src/_widgetscore.sip
index 06ef1537e53..7df091cbfb1 100644
--- a/qt/python/mantidqt/widgets/src/_widgetscore.sip
+++ b/qt/python/mantidqt/widgets/src/_widgetscore.sip
@@ -97,6 +97,9 @@ public:
 public slots:
   void updateProgressMarker(int lineno, bool error);
 
+signals:
+  void modificationChanged(bool m);
+
 private:
   ScriptEditor(const ScriptEditor&);
 };
-- 
GitLab