diff --git a/qt/python/mantidqt/widgets/codeeditor/interpreter.py b/qt/python/mantidqt/widgets/codeeditor/interpreter.py index 858a66db0139282f196a1e6dcef9ec31dd5a670e..1d19431193aa7ce63af39525397f921b7600fb9d 100644 --- a/qt/python/mantidqt/widgets/codeeditor/interpreter.py +++ b/qt/python/mantidqt/widgets/codeeditor/interpreter.py @@ -53,8 +53,8 @@ class PythonFileInterpreter(QWidget): # presenter self._presenter = PythonFileInterpreterPresenter(self, PythonCodeExecution()) - def execute_all_async(self): - self._presenter.req_execute_all_async() + def execute_async(self): + self._presenter.req_execute_async() def set_editor_readonly(self, ro): self.editor.setReadOnly(ro) @@ -88,30 +88,41 @@ class PythonFileInterpreterPresenter(QObject): def __init__(self, view, model): super(PythonFileInterpreterPresenter, self).__init__() + # attributes self.view = view self.model = model + # offset of executing code from start of the file + self._code_start_offset = 0 # connect signals - self.model.sig_exec_success.connect(self.on_exec_success) - self.model.sig_exec_error.connect(self.on_exec_error) - self.model.sig_exec_progress.connect(self.view.editor.updateProgressMarker) + self.model.sig_exec_success.connect(self._on_exec_success) + self.model.sig_exec_error.connect(self._on_exec_error) + self.model.sig_exec_progress.connect(self._on_progress_update) # starts idle self.view.set_status_message(IDLE_STATUS_MSG) - def req_execute_all_async(self): - text = self.view.editor.text() - if not text: - return + def req_execute_async(self): + code_str, self._code_start_offset = self._get_code_for_execution() self.view.set_editor_readonly(True) self.view.set_status_message(RUNNING_STATUS_MSG) - return self.model.execute_async(text) + return self.model.execute_async(code_str) - def on_exec_success(self): + def _get_code_for_execution(self): + editor = self.view.editor + if editor.hasSelectedText(): + code_str = editor.selectedText() + line_from, _, _, _ = editor.getSelection() + else: + code_str = editor.text() + line_from = 0 + return code_str, line_from + + def _on_exec_success(self): self.view.set_editor_readonly(False) self.view.set_status_message(IDLE_STATUS_MSG) - def on_exec_error(self, task_error): + def _on_exec_error(self, task_error): if isinstance(task_error.exception, SyntaxError): lineno = task_error.exception.lineno else: @@ -119,3 +130,9 @@ class PythonFileInterpreterPresenter(QObject): self.view.editor.updateProgressMarker(lineno, True) self.view.set_editor_readonly(False) self.view.set_status_message(IDLE_STATUS_MSG) + + def _on_progress_update(self, lineno): + """Update progress on the view taking into account if a selection of code is + running""" + self.view.editor.updateProgressMarker(lineno + self._code_start_offset, + False) \ No newline at end of file diff --git a/qt/python/mantidqt/widgets/codeeditor/multifileinterpreter.py b/qt/python/mantidqt/widgets/codeeditor/multifileinterpreter.py index 4e9ee97534f6740de0c7e58484122af36991729a..7f62d5a02f573ca55ccb6d0030a996f29f52d1c3 100644 --- a/qt/python/mantidqt/widgets/codeeditor/multifileinterpreter.py +++ b/qt/python/mantidqt/widgets/codeeditor/multifileinterpreter.py @@ -51,7 +51,9 @@ class MultiPythonFileInterpreter(QWidget): return self._editors.currentWidget() def execute_current(self): - self.current_editor().execute_all_async() + """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" diff --git a/qt/python/mantidqt/widgets/codeeditor/test/test_codeeditor.py b/qt/python/mantidqt/widgets/codeeditor/test/test_codeeditor.py index ff465ee2e81bc3e85f031a3bdd98d9e234e68434..933547f4e0c0de6cef74fd06ff31cc0c647a8e18 100644 --- a/qt/python/mantidqt/widgets/codeeditor/test/test_codeeditor.py +++ b/qt/python/mantidqt/widgets/codeeditor/test/test_codeeditor.py @@ -60,6 +60,23 @@ class CodeEditorTest(unittest.TestCase): widget.setReadOnly(True) self.assertTrue(widget.isReadOnly()) + def test_get_selection_for_empty_selection(self): + widget = CodeEditor(TEST_LANG) + res = widget.getSelection() + self.assertEqual((-1, -1, -1, -1), res) + + def test_get_selection_for_non_empty_selection(self): + widget = CodeEditor(TEST_LANG) + widget.setText("""first line + second line + third line + fourth line + """) + selected = (0, 2, 3, 4) + widget.setSelection(*selected) + res = widget.getSelection() + self.assertEqual(selected, res) + # --------------------------------------------------------------- # Failure tests # --------------------------------------------------------------- diff --git a/qt/python/mantidqt/widgets/src/_widgetscore.sip b/qt/python/mantidqt/widgets/src/_widgetscore.sip index 75136926fb4c9e144ca73c5be2adffdc66810138..67752d51f856565e042dff93db825d7196b3e6b2 100644 --- a/qt/python/mantidqt/widgets/src/_widgetscore.sip +++ b/qt/python/mantidqt/widgets/src/_widgetscore.sip @@ -65,7 +65,16 @@ public: QWidget *parent /TransferThis/ = 0) throw(std::invalid_argument); QString fileName() const; + SIP_PYTUPLE getSelection() const; +%MethodCode + int lineFrom(-1), indexFrom(-1), lineTo(-1), indexTo(-1); + sipCpp->getSelection(&lineFrom, &indexFrom, &lineTo, &indexTo); + sipRes = sipBuildResult(nullptr, "(iiii)", lineFrom, indexFrom, + lineTo, indexTo); +%End + bool hasSelectedText() const; bool isReadOnly() const; + QString selectedText() const; QString text() const; void setCaretLineBackgroundColor (const QColor & col); @@ -74,6 +83,7 @@ public: void setFont(const QFont &f); void setMarginWidth(int margin, int width); void setReadOnly(bool ro); + void setSelection(int lineFrom, int indexFrom, int lineTo, int indexTo); void setText(const QString &text); public slots: