1 // Copyright (C) 2006-2016 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 <PyEditor_Editor.h>
30 #include <PyEditor_Settings.h>
33 #include <QToolButton>
35 #include <QTemporaryFile>
36 #include <QTextStream>
42 #include "YacsTrace.hxx"
47 using namespace YACS::HMI;
49 EditionScript::EditionScript(Subject* subject,
52 : EditionElementaryNode(subject, parent, name)
57 _subInlineNode = dynamic_cast<SubjectInlineNode*>(_subject);
58 YASSERT(_subInlineNode);
60 QSplitter *splitter = new QSplitter(this);
61 splitter->setOrientation(Qt::Vertical);
62 _wid->gridLayout1->addWidget(splitter);
64 QWidget* widg=new QWidget;
65 _portslayout = new QVBoxLayout;
66 widg->setLayout(_portslayout);
67 _portslayout->setMargin(1);
68 splitter->addWidget(widg);
70 QWidget* window=new QWidget;
71 _glayout=new QVBoxLayout;
72 window->setLayout(_glayout);
73 _glayout->setMargin(1);
74 splitter->addWidget(window);
76 //add an options section in ports layout for execution mode (local or remote)
77 QHBoxLayout* hboxLayout = new QHBoxLayout();
78 hboxLayout->setMargin(0);
79 QToolButton* tb_options = new QToolButton();
80 tb_options->setCheckable(true);
82 icon.addFile("icons:icon_down.png");
83 icon.addFile("icons:icon_up.png", QSize(), QIcon::Normal, QIcon::On);
84 tb_options->setIcon(icon);
85 hboxLayout->addWidget(tb_options);
87 QLabel* label = new QLabel("Execution Mode");
92 hboxLayout->addWidget(label);
94 _portslayout->addLayout(hboxLayout);
96 fr_options = new QFrame();
97 QHBoxLayout* hboxLayout1 = new QHBoxLayout(fr_options);
98 hboxLayout1->setMargin(0);
99 radiolocal= new QRadioButton("YACS");
100 radioremote= new QRadioButton("Container");
101 radiolocal->setChecked(true);
102 hboxLayout1->addWidget(radiolocal);
103 hboxLayout1->addWidget(radioremote);
104 hboxLayout->addWidget(fr_options);
106 fr_container = new QFrame();
107 QHBoxLayout* hboxLayout2 = new QHBoxLayout(fr_container);
108 hboxLayout2->setMargin(0);
109 QLabel* laContainer = new QLabel("Container:");
110 hboxLayout2->addWidget(laContainer);
111 cb_container = new ComboBox();
112 hboxLayout2->addWidget(cb_container);
113 _portslayout->addWidget(fr_container);
116 YACS::ENGINE::InlineNode *pyNode(dynamic_cast<YACS::ENGINE::InlineNode*>(_subInlineNode->getNode()));
117 YACS::ENGINE::Container *cont(pyNode->getContainer());
118 formcontainer = new FormContainerDecorator(cont,this);
119 _portslayout->addWidget(formcontainer);
120 //_portslayout->addWidget(formcontainer->getWidget());
121 //end of insertion of execution mode
123 createTablePorts(_portslayout);
124 setEditablePorts(true);
128 _sci = new PyEditor_Editor(false, 0, this);
130 _sci = new QTextEdit(this);
132 _wid->gridLayout->removeItem(_wid->spacerItem);
134 _editor = new QPushButton("External Editor", this);
135 connect(_editor, SIGNAL(clicked()), this, SLOT(onEdit()));
136 if(!Resource::pythonExternalEditor.isEmpty())
138 _glayout->addWidget( _editor );
140 _glayout->addWidget( _sci );
142 if (!QtGuiContext::getQtCurrent()->isEdition())
143 _sci->setReadOnly(true);
145 if (YACS::ENGINE::InlineNode* pyNode =
146 dynamic_cast<YACS::ENGINE::InlineNode*>(_subInlineNode->getNode()))
148 _sci->append(pyNode->getScript().c_str());
150 connect(_sci, SIGNAL(textChanged()), this, SLOT(onScriptModified()));
152 connect(tb_options, SIGNAL(toggled(bool)), this, SLOT(on_tb_options_toggled(bool)));
153 connect(radioremote, SIGNAL(toggled(bool)), this, SLOT(on_remote_toggled(bool)));
154 connect(cb_container, SIGNAL(mousePressed()), this, SLOT(fillContainerPanel()));
155 connect(cb_container, SIGNAL(activated(int)), this, SLOT(changeContainer(int)));
158 on_tb_options_toggled(false);
161 EditionScript::~EditionScript()
165 void EditionScript::synchronize()
167 DEBTRACE("EditionScript::synchronize " << this->_isEdited);
168 EditionElementaryNode::synchronize();
169 YACS::ENGINE::InlineNode* pyNode = dynamic_cast<YACS::ENGINE::InlineNode*>(_subInlineNode->getNode());
171 disconnect(_sci, SIGNAL(textChanged()), this, SLOT(onScriptModified()));
175 _sci->append(pyNode->getScript().c_str());
177 connect(_sci, SIGNAL(textChanged()), this, SLOT(onScriptModified()));
180 void EditionScript::onApply()
182 DEBTRACE("EditionScript::onApply");
183 bool scriptEdited = false;
185 _sci->settings()->p_Font = Resource::pythonfont;
188 if(Resource::pythonExternalEditor.isEmpty())
191 _glayout->removeWidget(_editor);
196 if(_glayout->itemAt(0)->widget() != _editor)
197 _glayout->insertWidget ( 0, _editor );
202 if (_sci->document()->isModified())
205 std::string text=_sci->document()->toPlainText().toStdString();
206 if(text[text.length()-1] != '\n')
208 bool ret = _subInlineNode->setScript(text);
209 if (ret) scriptEdited = false;
213 bool containerEdited = true;
214 if (formcontainer->onApply()) {
215 fillContainerPanel();
216 containerEdited = false;
218 Message mess(GuiContext::getCurrent()->_lastErrorMessage);
222 _isEdited = _isEdited || scriptEdited || containerEdited;
224 EditionElementaryNode::onApply();
227 void EditionScript::onCancel()
230 _sci->setText(_subInlineNode->getScript().c_str());
231 formcontainer->onCancel();
232 EditionElementaryNode::onCancel();
235 void EditionScript::onScriptModified()
237 DEBTRACE("EditionScript::onScriptModified");
242 void EditionScript::onEdit()
244 DEBTRACE("EditionScript::onEdit");
245 QTemporaryFile outFile;
248 QString fileName = outFile.fileName();
249 QTextStream out(&outFile);
250 out << _sci->toPlainText();
253 QStringList options=Resource::pythonExternalEditor.split(" ");
254 QString prog=options.takeAt(0);
255 QProcess::execute(prog, QStringList() << options << fileName);
257 QFile inFile(fileName);
258 if (!inFile.open(QIODevice::ReadOnly))
260 QTextStream in(&inFile);
261 _sci->setPlainText(in.readAll());
265 void EditionScript::on_tb_options_toggled(bool checked)
267 DEBTRACE("EditionScript::on_tb_options_toggled " << checked);
274 fr_container->show();
275 formcontainer->show();
281 fr_container->hide();
282 formcontainer->hide();
286 void EditionScript::on_remote_toggled(bool checked)
288 DEBTRACE("EditionScript::on_remote_toggled " << checked);
290 YACS::ENGINE::InlineNode *pyNode = dynamic_cast<YACS::ENGINE::InlineNode*>(_subInlineNode->getNode());
291 std::string mode = pyNode->getExecutionMode();
296 //remote radio button is checked
298 _subInlineNode->setExecutionMode("remote");
299 fr_container->show();
300 formcontainer->show();
301 fillContainerPanel();
305 //remote radio button is unchecked
307 _subInlineNode->setExecutionMode("local");
308 fr_container->hide();
309 formcontainer->hide();
313 void EditionScript::fillContainerPanel()
315 DEBTRACE("EditionScript::fillContainerPanel ");
316 YACS::ENGINE::Proc* proc = GuiContext::getCurrent()->getProc();
318 cb_container->clear();
319 std::map<string,YACS::ENGINE::Container*>::const_iterator it = proc->containerMap.begin();
320 for(; it != proc->containerMap.end(); ++it)
321 cb_container->addItem( QString((*it).first.c_str()));
323 YACS::ENGINE::InlineNode *pyNode = dynamic_cast<YACS::ENGINE::InlineNode*>(_subInlineNode->getNode());
325 YACS::ENGINE::Container * cont = pyNode->getContainer();
328 int index = cb_container->findText(cont->getName().c_str());
329 cb_container->setCurrentIndex(index);
330 formcontainer->FillPanel(cont);
332 else if (cb_container->count()) {
337 void EditionScript::changeContainer(int index)
339 DEBTRACE("EditionScript::changeContainer ");
340 string contName = cb_container->itemText(index).toStdString();
342 YACS::ENGINE::InlineNode *pyNode = dynamic_cast<YACS::ENGINE::InlineNode*>(_subInlineNode->getNode());
343 YACS::ENGINE::Container *oldContainer = pyNode->getContainer();
345 YACS::ENGINE::Container *newContainer = 0;
346 YACS::ENGINE::Proc* proc = GuiContext::getCurrent()->getProc();
347 if (proc->containerMap.count(contName))
348 newContainer = proc->containerMap[contName];
351 DEBTRACE("-------------> not found : " << contName);
354 YASSERT(GuiContext::getCurrent()->_mapOfSubjectContainer.count(newContainer));
355 SubjectContainerBase *scnt(GuiContext::getCurrent()->_mapOfSubjectContainer[newContainer]);
357 _subInlineNode->setContainer(scnt);
359 // show the selected container parameters
360 formcontainer->FillPanel(newContainer);
363 void EditionScript::update(GuiEvent event, int type, Subject* son)
365 DEBTRACE("EditionScript::update " << eventName(event) <<" "<<type<<" "<<son);
366 EditionElementaryNode::update(event, type, son);
367 if(event == ASSOCIATE)
369 fillContainerPanel();
370 SubjectContainer *scont = dynamic_cast<SubjectContainer*>(son);
372 formcontainer->FillPanel(scont->getContainer());
374 else if(event == UPDATE)
376 YACS::ENGINE::InlineNode *pyNode = dynamic_cast<YACS::ENGINE::InlineNode*>(_subInlineNode->getNode());
377 std::string mode = pyNode->getExecutionMode();
381 radioremote->setChecked(true);
383 else if(mode == "local")
386 radiolocal->setChecked(true);
389 fillContainerPanel();