1 // Copyright (C) 2006-2014 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "EditionScript.hxx"
21 #include "QtGuiContext.hxx"
22 #include "Resource.hxx"
23 #include "Container.hxx"
24 #include "InlineNode.hxx"
25 #include "FormContainer.hxx"
26 #include "Message.hxx"
29 #include <qsciscintilla.h>
30 #include <qscilexerpython.h>
34 #include <QTemporaryFile>
35 #include <QTextStream>
41 #include "YacsTrace.hxx"
46 using namespace YACS::HMI;
49 class myQsciScintilla: public QsciScintilla
52 myQsciScintilla(QWidget *parent=0)
53 : QsciScintilla(parent) {};
55 virtual QSize sizeHint() const { return QSize(350, 150); };
57 virtual bool event(QEvent *e);
60 bool myQsciScintilla::event(QEvent *e)
62 if (e->type() == QEvent::ShortcutOverride)
67 return QsciScintilla::event(e);
73 EditionScript::EditionScript(Subject* subject,
76 : EditionElementaryNode(subject, parent, name)
81 _subInlineNode = dynamic_cast<SubjectInlineNode*>(_subject);
82 YASSERT(_subInlineNode);
84 QSplitter *splitter = new QSplitter(this);
85 splitter->setOrientation(Qt::Vertical);
86 _wid->gridLayout1->addWidget(splitter);
88 QWidget* widg=new QWidget;
89 _portslayout = new QVBoxLayout;
90 widg->setLayout(_portslayout);
91 _portslayout->setMargin(1);
92 splitter->addWidget(widg);
94 QWidget* window=new QWidget;
95 _glayout=new QVBoxLayout;
96 window->setLayout(_glayout);
97 _glayout->setMargin(1);
98 splitter->addWidget(window);
100 fr_container = new QFrame();
101 QHBoxLayout* hboxLayout2 = new QHBoxLayout(fr_container);
102 hboxLayout2->setMargin(0);
103 QLabel* laContainer = new QLabel("Container:");
104 hboxLayout2->addWidget(laContainer);
105 cb_container = new ComboBox();
106 hboxLayout2->addWidget(cb_container);
107 _portslayout->addWidget(fr_container);
109 formcontainer = new FormContainer(this);
110 formcontainer->on_tb_container_toggled(false);
111 _portslayout->addWidget(formcontainer);
112 //end of insertion of execution mode
114 createTablePorts(_portslayout);
115 setEditablePorts(true);
119 _sci = new myQsciScintilla(this);
121 _sci = new QTextEdit(this);
123 _wid->gridLayout->removeItem(_wid->spacerItem);
125 _editor = new QPushButton("External Editor", this);
126 connect(_editor, SIGNAL(clicked()), this, SLOT(onEdit()));
127 if(!Resource::pythonExternalEditor.isEmpty())
129 _glayout->addWidget( _editor );
131 _glayout->addWidget( _sci );
135 QsciLexerPython *lex = new QsciLexerPython(_sci);
136 lex->setFont(Resource::pythonfont);
138 _sci->setBraceMatching(QsciScintilla::SloppyBraceMatch);
139 _sci->setAutoIndent(1);
140 _sci->setIndentationWidth(4);
141 _sci->setIndentationGuides(1);
142 _sci->setIndentationsUseTabs(0);
143 _sci->setAutoCompletionThreshold(2);
144 //_sci->setMarginLineNumbers(1,true);
145 _sci->setMarginWidth(1,0);
146 _sci->setFolding(QsciScintilla::PlainFoldStyle);
149 if (!QtGuiContext::getQtCurrent()->isEdition())
150 _sci->setReadOnly(true);
152 if (YACS::ENGINE::InlineNode* pyNode =
153 dynamic_cast<YACS::ENGINE::InlineNode*>(_subInlineNode->getNode()))
155 _sci->append(pyNode->getScript().c_str());
157 connect(_sci, SIGNAL(textChanged()), this, SLOT(onScriptModified()));
159 connect(cb_container, SIGNAL(mousePressed()), this, SLOT(fillContainerPanel()));
160 connect(cb_container, SIGNAL(activated(int)), this, SLOT(changeContainer(int)));
166 EditionScript::~EditionScript()
170 void EditionScript::synchronize()
172 DEBTRACE("EditionScript::synchronize " << this->_isEdited);
173 EditionElementaryNode::synchronize();
174 YACS::ENGINE::InlineNode* pyNode = dynamic_cast<YACS::ENGINE::InlineNode*>(_subInlineNode->getNode());
176 disconnect(_sci, SIGNAL(textChanged()), this, SLOT(onScriptModified()));
180 _sci->append(pyNode->getScript().c_str());
182 connect(_sci, SIGNAL(textChanged()), this, SLOT(onScriptModified()));
185 void EditionScript::onApply()
187 DEBTRACE("EditionScript::onApply");
188 bool scriptEdited = false;
190 _sci->lexer()->setFont(Resource::pythonfont);
193 if(Resource::pythonExternalEditor.isEmpty())
196 _glayout->removeWidget(_editor);
201 if(_glayout->itemAt(0)->widget() != _editor)
202 _glayout->insertWidget ( 0, _editor );
208 if (_sci->isModified())
211 std::string text=_sci->text().toStdString();
212 if(text[text.length()-1] != '\n')
214 bool ret = _subInlineNode->setScript(text);
215 if (ret) scriptEdited = false;
218 if (_sci->document()->isModified())
221 std::string text=_sci->document()->toPlainText().toStdString();
222 if(text[text.length()-1] != '\n')
224 bool ret = _subInlineNode->setScript(text);
225 if (ret) scriptEdited = false;
230 bool containerEdited = true;
231 if (formcontainer->onApply()) {
232 fillContainerPanel();
233 containerEdited = false;
235 Message mess(GuiContext::getCurrent()->_lastErrorMessage);
239 _isEdited = _isEdited || scriptEdited || containerEdited;
241 EditionElementaryNode::onApply();
244 void EditionScript::onCancel()
247 _sci->setText(_subInlineNode->getScript().c_str());
248 formcontainer->onCancel();
249 EditionElementaryNode::onCancel();
252 void EditionScript::onScriptModified()
254 DEBTRACE("EditionScript::onScriptModified");
259 void EditionScript::onEdit()
261 DEBTRACE("EditionScript::onEdit");
262 QTemporaryFile outFile;
265 QString fileName = outFile.fileName();
266 QTextStream out(&outFile);
270 out << _sci->toPlainText();
274 QStringList options=Resource::pythonExternalEditor.split(" ");
275 QString prog=options.takeAt(0);
276 QProcess::execute(prog, QStringList() << options << fileName);
278 QFile inFile(fileName);
279 if (!inFile.open(QIODevice::ReadOnly))
281 QTextStream in(&inFile);
283 _sci->setText(in.readAll());
285 _sci->setPlainText(in.readAll());
290 void EditionScript::fillContainerPanel()
292 DEBTRACE("EditionScript::fillContainerPanel ");
293 YACS::ENGINE::Proc* proc = GuiContext::getCurrent()->getProc();
295 cb_container->clear();
296 std::map<string,YACS::ENGINE::Container*>::const_iterator it = proc->containerMap.begin();
297 for(; it != proc->containerMap.end(); ++it)
298 cb_container->addItem( QString((*it).first.c_str()));
300 YACS::ENGINE::InlineNode *pyNode = dynamic_cast<YACS::ENGINE::InlineNode*>(_subInlineNode->getNode());
302 YACS::ENGINE::Container * cont = pyNode->getContainer();
305 int index = cb_container->findText(cont->getName().c_str());
306 cb_container->setCurrentIndex(index);
307 formcontainer->FillPanel(cont);
311 void EditionScript::changeContainer(int index)
313 DEBTRACE("EditionScript::changeContainer ");
314 string contName = cb_container->itemText(index).toStdString();
316 YACS::ENGINE::InlineNode *pyNode = dynamic_cast<YACS::ENGINE::InlineNode*>(_subInlineNode->getNode());
317 YACS::ENGINE::Container *oldContainer = pyNode->getContainer();
319 YACS::ENGINE::Container *newContainer = 0;
320 YACS::ENGINE::Proc* proc = GuiContext::getCurrent()->getProc();
321 if (proc->containerMap.count(contName))
322 newContainer = proc->containerMap[contName];
325 DEBTRACE("-------------> not found : " << contName);
328 YASSERT(GuiContext::getCurrent()->_mapOfSubjectContainer.count(newContainer));
329 SubjectContainer *scnt = GuiContext::getCurrent()->_mapOfSubjectContainer[newContainer];
331 _subInlineNode->setContainer(scnt);
333 // show the selected container parameters
334 formcontainer->FillPanel(newContainer);
337 void EditionScript::update(GuiEvent event, int type, Subject* son)
339 DEBTRACE("EditionScript::update " << eventName(event) <<" "<<type<<" "<<son);
340 EditionElementaryNode::update(event, type, son);
341 if(event == ASSOCIATE)
343 fillContainerPanel();
344 SubjectContainer *scont = dynamic_cast<SubjectContainer*>(son);
346 formcontainer->FillPanel(scont->getContainer());
348 else if(event == UPDATE)
350 fillContainerPanel();