CodeEditorDialog.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
3 
4  This file is part of the TerraLib - a Framework for building GIS enabled
5  applications.
6 
7  TerraLib is free software: you can redistribute it and/or modify
8  it under the terms of the GNU Lesser General Public License as published by
9  the Free Software Foundation, either version 3 of the License,
10  or (at your option) any later version.
11 
12  TerraLib is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public License
18  along with TerraLib. See COPYING. If not, write to
19  TerraLib Team at <terralib-team@terralib.org>.
20 */
21 // TerraLib
22 #include "CodeEditorDialog.h"
23 #include "../Exception.h"
24 #include "../qt/widgets/ceditor/ScriptWidget.h"
25 #include "../qt/widgets/ceditor/Utils.h"
26 #include "../vm/core/VirtualMachineManager.h"
27 #include "ui_CodeEditorDialogForm.h"
28 
29 // Qt
30 #include <QtConcurrent/qtconcurrentrun.h>
31 #include <QFileDialog>
32 #include <QFuture>
33 #include <QFutureWatcher>
34 #include <QLayout>
35 #include <QMessageBox>
36 #include <QPushButton>
37 #include <QString>
38 #include <QTimer>
39 
40 // STL
41 #include <iostream>
42 
44  : QDialog(parent, f), m_vm(nullptr), m_ui(new Ui::CodeEditorDialogForm)
45 {
46  this->setWindowTitle(tr("TerraLib Code Editor"));
47  m_ui->setupUi(this);
48 
49  // Setup the buttons
50  m_ui->m_newButton->setIcon(QIcon::fromTheme("document-new"));
51  m_ui->m_newButton->setShortcut(QKeySequence("Ctrl+N"));
52  m_ui->m_newButton->setIconSize(QSize(24, 24));
53  m_ui->m_newButton->setToolTip("New script file");
54 
55  m_ui->m_openButton->setIcon(QIcon::fromTheme("document-open"));
56  m_ui->m_openButton->setShortcut(QKeySequence("Ctrl+O"));
57  m_ui->m_openButton->setIconSize(QSize(24, 24));
58  m_ui->m_openButton->setToolTip("Open script file");
59 
60  m_ui->m_saveButton->setIcon(QIcon::fromTheme("document-save"));
61  m_ui->m_saveButton->setShortcut(QKeySequence("Ctrl+S"));
62  m_ui->m_saveButton->setIconSize(QSize(24, 24));
63  m_ui->m_saveButton->setToolTip("Save script file");
64 
65  m_ui->m_saveAsButton->setIcon(QIcon::fromTheme("document-save-as"));
66  m_ui->m_saveAsButton->setShortcut(QKeySequence("Ctrl+Shift+S"));
67  m_ui->m_saveAsButton->setIconSize(QSize(24, 24));
68  m_ui->m_saveAsButton->setToolTip("Save script file as");
69 
70  m_ui->m_runButton->setIcon(QIcon::fromTheme("media-playback-start-green"));
71  m_ui->m_runButton->setShortcut(QKeySequence("Ctrl+R"));
72  m_ui->m_runButton->setIconSize(QSize(32, 32));
73  m_ui->m_runButton->setToolTip("Run script file");
74 
75  m_ui->m_stopButton->setIcon(QIcon::fromTheme("process-stop"));
76  m_ui->m_stopButton->setShortcut(QKeySequence("Ctrl+Shift+R"));
77  m_ui->m_stopButton->setIconSize(QSize(24, 24));
78  m_ui->m_stopButton->setToolTip("Stop running script");
79 
80  m_io = new te::qt::widgets::IOWidget(this);
81  m_ui->splitter->addWidget(m_io);
82 
83  // connect all the buttons
84  connect(m_ui->m_newButton, SIGNAL(clicked()), this,
85  SLOT(onNewButtonClicked()));
86  connect(m_ui->m_openButton, SIGNAL(clicked()), this,
87  SLOT(onOpenButtonClicked()));
88  connect(m_ui->m_saveButton, SIGNAL(clicked()), this,
89  SLOT(onSaveButtonClicked()));
90  connect(m_ui->m_saveAsButton, SIGNAL(clicked()), this,
91  SLOT(onSaveAsButtonClicked()));
92  connect(m_ui->m_runButton, SIGNAL(clicked()), this,
93  SLOT(onRunButtonClicked()));
94  connect(m_ui->m_codeTab, SIGNAL(tabCloseRequested(int)), this,
95  SLOT(onCloseTabClicked(int)));
96  connect(&m_watcher, SIGNAL(finished()), this, SLOT(onRunFinished()));
97 
98  // gray out for disabled buttons
99  this->setStyleSheet(
100  QString::fromUtf8("QPushButton:disabled { color: gray }"));
101 
102  // disable stop button
103  m_ui->m_stopButton->setEnabled(false);
104 }
105 
107 {
108  m_ui->m_codeTab->clear();
109  m_vm = nullptr;
110 }
111 
113 {
114  // creates a new ScriptWidget
117 
118  // insert into the QTabWidget
119  m_ui->m_codeTab->insertTab(0, editor, "");
120 
121  // set the focus to the new tab
122  m_ui->m_codeTab->setCurrentIndex(0);
123 
124  connect(editor, SIGNAL(textChanged()), this, SLOT(onTextChanged()));
125 }
126 
128 {
129  // return if tab count is 0
130  if(m_ui->m_codeTab->count() == 0)
131  return;
132 
133  // get the current tab
135  (te::qt::widgets::ScriptWidget*)m_ui->m_codeTab->currentWidget();
136 
137  // if the tab has no filename set, calls a file dialog
138  if(editor->getFileName().isEmpty() || saveAs)
139  {
140  QString filter =
141  tr("Python (*.py *.PY);;Lua (*.lua *.LUA);;All files(*.*)");
142  QString selFilter;
143  QString file = QFileDialog::getSaveFileName(this, tr("Save Script File"),
144  "", filter, &selFilter);
145  editor->save(file);
146  auto index = m_ui->m_codeTab->currentIndex();
147  m_ui->m_codeTab->setTabText(index, QFileInfo(file).fileName());
148  m_ui->m_codeTab->setTabIcon(index, te::qt::widgets::CreateLangIcon(file));
149  }
150  // else saves to the same filename
151  else
152  {
153  auto index = m_ui->m_codeTab->currentIndex();
154  m_ui->m_codeTab->setTabText(index,
155  QFileInfo(editor->getFileName()).fileName());
156  editor->save(editor->getFileName());
157  }
158 }
159 
161 {
162  // saves before running
164 
165  if(m_ui->m_codeTab->count() == 0)
166  return;
167 
168  // get the current ScriptWidget
170  (te::qt::widgets::ScriptWidget*)m_ui->m_codeTab->currentWidget();
171 
172  // retrieves the VM for the correspondent script type
173  try
174  {
176  editor->getScriptType().toUtf8().data());
177 
178  // set the script file name in the vm
179  m_vm->setFileName(editor->getFileName());
180 
181  // VM to UI connects
182  connect(m_vm, SIGNAL(output(QString)), m_io, SLOT(append(QString)));
183  connect(m_vm, SIGNAL(requestReadline()), m_io, SLOT(addPrompt()));
184  connect(m_io, SIGNAL(command(QString)), m_vm, SLOT(readline(QString)));
185  connect(m_ui->m_stopButton, SIGNAL(clicked()), m_vm, SLOT(stop()));
186 
187  m_io->clear();
188 
189  // disable run button and enable stop button
190  m_ui->m_runButton->setDisabled(true);
191  m_ui->m_stopButton->setDisabled(false);
192 
193  // start a elapsed timer
194  m_runtime.restart();
195 
196  QFuture<void> future =
197  QtConcurrent::run(m_vm, &te::vm::core::VirtualMachine::execute);
198  m_watcher.setFuture(future);
199  }
201  {
202  QMessageBox::warning(
203  nullptr, this->windowTitle(),
204  "Could not find a interpreter to run the following file: " +
205  editor->getScriptName());
206  return;
207  }
208 }
209 
211 {
212  // get the elapsed time
213  int time = m_runtime.elapsed();
214 
215  // disconnect the VM from the UI
216  disconnect(m_vm, SIGNAL(output(QString)), m_io, SLOT(append(QString)));
217  disconnect(m_vm, SIGNAL(requestReadline()), m_io, SLOT(addPrompt()));
218  disconnect(m_io, SIGNAL(command(QString)), m_vm, SLOT(readline(QString)));
219  disconnect(m_ui->m_stopButton, SIGNAL(clicked()), m_vm, SLOT(stop()));
220 
221  // enables run button and disables stop button
222  m_ui->m_runButton->setDisabled(false);
223  m_ui->m_stopButton->setDisabled(true);
224 
225  // appends the elapse time to the output
226  std::string elapsed = "[Time elapsed: " + std::to_string(time) + "ms]";
227  m_io->append(elapsed.c_str());
228 }
229 
231 {
232  save(false);
233 }
234 
236 {
237  save(true);
238 }
239 
241 {
242  QString filter =
243  tr("Python (*.py *.PY);;Lua (*.lua *.LUA);;All files (*.*)");
244  QString selFilter;
245  // get a script filename
246  QString file = QFileDialog::getOpenFileName(this, tr("Open Script File"), "",
247  filter, &selFilter);
248 
249  // if nothing is selected, return
250  if(file.isEmpty())
251  return;
252 
253  // creates a new ScriptWidget
256 
257  // sets the filename to the ScriptWidget
258  editor->open(file);
259 
260  QFile f(file);
261  // insert the ScriptWidget to QTabWidget
262  m_ui->m_codeTab->insertTab(0, editor, te::qt::widgets::CreateLangIcon(file),
263  QFileInfo(f).fileName());
264  // set the focus to the opened script
265  m_ui->m_codeTab->setCurrentIndex(0);
266 
267  connect(editor, SIGNAL(textChanged()), this, SLOT(onTextChanged()));
268 }
270 {
271  // removes the current tab
272  m_ui->m_codeTab->removeTab(index);
273 }
274 
276 {
278  qobject_cast<te::qt::widgets::ScriptWidget*>(sender());
279  int tabIndex = m_ui->m_codeTab->indexOf(editor);
280 
281  QString tabText = m_ui->m_codeTab->tabText(tabIndex);
282  if(!tabText.endsWith(" *"))
283  {
284  tabText += " *";
285  m_ui->m_codeTab->setTabText(tabIndex, tabText);
286  }
287 }
virtual void setFileName(QString file)=0
setFileName Sets the file that will be used in the Virtual Machine.
void append(QString text)
append Appends the given text to the text edit and locks the widget for input
Definition: IOWidget.cpp:96
A widget that can be used to edit a script.
Definition: ScriptWidget.h:56
virtual void execute()=0
execute Executes the script file previously set.
void save(const QString &fileName)
Saves the content of the script into a file.
void open(const QString &fileName)
Open the script file and presents it on the text edit.
CodeEditorDialog(QWidget *parent=0, Qt::WindowFlags f=0)
static VirtualMachineManager & instance()
Return a reference to the singleton.
QString getScriptType() const
getScriptType
te::vm::core::VirtualMachine * m_vm
te::qt::widgets::IOWidget * m_io
An exception indicating that a given item was not found in a collection (or range).
QString getFileName() const
Returns the file name of the script.
Definition: ScriptWidget.h:76
VirtualMachine * get(const std::string &id) const
It returns the VM identified by id.
file(WRITE ${CMAKE_BINARY_DIR}/config_qhelp.cmake"configure_file (${TERRALIB_ABSOLUTE_ROOT_DIR}/doc/qhelp/help.qhcp.in ${CMAKE_BINARY_DIR}/share/terraview/help/help.qhcp @ONLY)") add_custom_command(OUTPUT del_dir COMMAND $
QString getScriptName() const
getScriptName
TEQTWIDGETSEXPORT QIcon CreateLangIcon(const QString &fileName)
Returns the icon related to the extension of the file.
std::unique_ptr< Ui::CodeEditorDialogForm > m_ui
QFutureWatcher< void > m_watcher
void onCloseTabClicked(int index)