1 // Copyright (c) 2012 Dennco Project
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
8 // This program 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
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 // Created by tkawata on Sep-30, 2012.
19 #include "dctoolwindowcelleditor.h"
21 #include "dceditablelabel.h"
22 #include "dceditabletreeview.h"
23 #include "dccelltypecombobox.h"
25 #include "dccreator.h"
26 #include "dcreceptor.h"
28 #include "dccellcode.h"
29 #include "dcaxonterminal.h"
30 #include "dccontainer.h"
31 #include "utils/dcresources.h"
32 #include "utils/dcqtitemmodel.h"
33 #include "utils/dcutil.h"
35 #include <QGridLayout>
38 #include <QSizePolicy>
41 class ReceptorModel : public DCQtItemModel
43 DCToolWindowCellEditor *d_owner;
45 ReceptorModel(DCToolWindowCellEditor *owner) : DCQtItemModel(QStringList("name")), d_owner(owner)
50 virtual ~ReceptorModel()
54 virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)
56 if (role != Qt::EditRole)
59 DCCell *cell = d_owner->getCell();
63 DCQtItemModelItem *item = getItem(index);
64 QString oldReceptorName = item->data(index.column()).toString();
65 QString newReceptorName = value.toString().trimmed();
66 if (newReceptorName.length() == 0)
71 if (oldReceptorName == newReceptorName)
73 //nothing actually changes
77 if (!d_owner->getIsViewUpdating())
79 if (cell->getReceptor(newReceptorName))
82 QMessageBox::warning(NULL, tr("Rename receptor failed"), tr("The receptor name already exist"));
86 bool result = item->setData(index.column(), newReceptorName);
90 DCCreator *creator = d_owner->getController();
91 if (creator->doCommandRenameReceptorName(d_owner, cell, oldReceptorName, newReceptorName, true))
93 emit dataChanged(index, index);
97 item->setData(index.column(), oldReceptorName);
104 return item->setData(index.column(), newReceptorName);
108 virtual Qt::ItemFlags flags(const QModelIndex &index) const
110 if (!index.isValid())
113 Qt::ItemFlags flags = Qt::ItemIsEnabled;
115 if (index.column() == 0 && index.isValid() && index.parent().isValid() && !index.parent().parent().isValid())
117 flags |= Qt::ItemIsEditable | Qt::ItemIsSelectable;
124 class AxonTerminalModel : public DCQtItemModel
126 DCToolWindowCellEditor *d_owner;
128 AxonTerminalModel(DCToolWindowCellEditor *owner) : DCQtItemModel(QStringList("name")), d_owner(owner)
133 virtual ~AxonTerminalModel()
137 virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)
139 if (role != Qt::EditRole)
142 DCCell *cell = d_owner->getCell();
146 DCQtItemModelItem *item = getItem(index);
147 QString oldReceptorName = item->data(index.column()).toString();
148 QString newReceptorName = value.toString().trimmed();
149 if (newReceptorName.length() == 0)
154 if (oldReceptorName == newReceptorName)
156 //nothing actually changes
160 DCCell *axonTargetCell = NULL;
161 if (!d_owner->getIsViewUpdating())
163 bool alreadyExist = false;
164 DCAxon *axon = cell->getAxon();
165 int num = axon->getNumberOfTerminals();
166 for (int i = 0; i < num; i++)
168 DCReceptor *receptor = dynamic_cast<DCReceptor*>(axon->getTerminalAt(i)->getTarget());
171 DCCell *targetCell = dynamic_cast<DCCell*>(receptor->getOwnerCell());
174 QString targetReceptorName = QString::fromStdString(targetCell->getReceptorName(receptor));
175 if (targetReceptorName == newReceptorName)
180 else if (targetReceptorName == oldReceptorName)
182 axonTargetCell = targetCell;
190 QMessageBox::warning(NULL, tr("Rename receptor failed"), tr("The receptor name already exist"));
198 result = item->setData(index.column(), newReceptorName);
202 DCCreator *creator = d_owner->getController();
203 if (creator->doCommandRenameReceptorName(d_owner, axonTargetCell, oldReceptorName, newReceptorName, true))
205 emit dataChanged(index, index);
209 item->setData(index.column(), oldReceptorName);
217 return item->setData(index.column(), newReceptorName);
221 virtual Qt::ItemFlags flags(const QModelIndex &index) const
223 if (!index.isValid())
226 Qt::ItemFlags flags = Qt::ItemIsEnabled;
228 if (index.column() == 0 && index.isValid() && index.parent().isValid() && index.parent().parent().isValid() && !index.parent().parent().parent().isValid())
230 flags |= Qt::ItemIsEditable | Qt::ItemIsSelectable;
238 DCToolWindowCellEditor::DCToolWindowCellEditor(DCCreator *creator) :
239 DCToolWindowBase("CELL:", creator), d_cell(NULL), d_isViewUpdating(false)
241 d_layout = new QGridLayout;
242 d_layout->setSpacing(6);
243 d_layout->setContentsMargins(0,0,0,0);
244 d_layout->addWidget(new QLabel(tr("page")),0,0);
245 d_layout->addWidget(new QLabel(tr("type")),1,0);
246 d_layout->addWidget(new QLabel(tr("cell code")),2,0);
247 d_layout->addWidget(new QLabel(tr("custom script")),3,0);
249 d_detailButton = new QPushButton(tr("detail..."));
250 d_detailButton->setStyleSheet("background-color: rgba(255,255,255,60);");
252 d_layout->addWidget(d_detailButton,6,0,1,2);
254 d_textPage = new DCEditableLabel(this, "");
255 d_comboType = new DCCellTypeComboBox(creator, this);
256 d_layout->addWidget(d_textPage, 0,1);
257 d_layout->addWidget(d_comboType, 1,1);
259 d_classButton = new QPushButton("...");
260 d_customScriptButton = new QPushButton(tr("edit..."));
262 d_layout->addWidget(d_classButton, 2,1);
263 d_layout->addWidget(d_customScriptButton, 3,1);
265 d_receptors = new DCEditableTreeView(this);
266 d_receptors->setHeaderHidden(true);
267 d_receptors->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
269 d_axonTerminals = new DCEditableTreeView(this);
270 d_axonTerminals->setHeaderHidden(true);
271 d_axonTerminals->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
274 d_receptorItemModel = new ReceptorModel(this);
275 d_axonTerminalItemModel = new AxonTerminalModel(this);
277 d_receptors->setModel(d_receptorItemModel);
278 d_axonTerminals->setModel(d_axonTerminalItemModel);
280 d_layout->addWidget(d_receptors, 4,0,1,2);
281 d_layout->addWidget(d_axonTerminals, 5, 0, 1, 2);
283 contentLayout()->addLayout(d_layout);
285 connect(d_receptors, SIGNAL(collapsed(QModelIndex)), this, SLOT(slotReceptorTreeCollapsed(QModelIndex)));
286 connect(d_receptors, SIGNAL(expanded(QModelIndex)), this, SLOT(slotReceptorTreeExpanded(QModelIndex)));
287 connect(d_receptors, SIGNAL(clicked(QModelIndex)), this, SLOT(slotReceptorItemClicked(QModelIndex)));
288 connect(d_receptors, SIGNAL(vscrollbarShown()), this, SLOT(adjustTreeColumnWidth()));
289 connect(d_receptors, SIGNAL(vscrollbarHidden()), this, SLOT(adjustTreeColumnWidth()));
290 connect(d_axonTerminals, SIGNAL(collapsed(QModelIndex)), this, SLOT(slotAxonTerminalTreeCollapsed(QModelIndex)));
291 connect(d_axonTerminals, SIGNAL(expanded(QModelIndex)), this, SLOT(slotAxonTerminalTreeExpanded(QModelIndex)));
292 connect(d_axonTerminals, SIGNAL(clicked(QModelIndex)), this, SLOT(slotAxonTerminalItemClicked(QModelIndex)));
293 connect(d_axonTerminals, SIGNAL(vscrollbarShown()), this, SLOT(adjustTreeColumnWidth()));
294 connect(d_axonTerminals, SIGNAL(vscrollbarHidden()), this, SLOT(adjustTreeColumnWidth()));
296 connect(d_classButton, SIGNAL(clicked()), this, SLOT(slotCellCodeEditButtonPressed()));
297 connect(d_customScriptButton, SIGNAL(clicked()), this, SLOT(slotCustomScriptEditButtonPressed()));
300 DCToolWindowCellEditor::~DCToolWindowCellEditor()
302 d_receptors->disconnect(this);
303 d_axonTerminals->disconnect(this);
305 if (d_receptorItemModel)
306 d_receptorItemModel->deleteLater();
308 if (d_axonTerminalItemModel)
309 d_axonTerminalItemModel->deleteLater();
312 void DCToolWindowCellEditor::setCell(DCCell *cell)
315 d_cell->disconnect(this);
318 QString title = "CELL:";
321 title.append(QString::fromStdString(cell->getName()));
322 connect(cell, SIGNAL(destroyed(QObject*)), this, SLOT(slotCellDestroyed()));
323 d_comboType->setEditingCell(cell);
326 setButtonedWindowTitle(title);
331 void DCToolWindowCellEditor::updateView()
333 d_isViewUpdating = true;
334 d_receptorItemModel->removeAllItems();
335 d_axonTerminalItemModel->removeAllItems();
337 DCContainer *container = getController()->getCurrentContainer();
339 if (d_cell && container)
341 if (container->getIsScriptable(d_cell->getType()))
343 if (d_cell->getIsCellCodeClassAssgined())
345 d_classButton->setText(QString::fromStdString(d_cell->getCellCode()->getFQNName()));
349 d_classButton->setText("...");
351 d_classButton->setEnabled(true);
353 d_customScriptButton->setText("Edit...");
354 d_customScriptButton->setEnabled(true);
358 d_classButton->setText("N/A");
359 d_classButton->setEnabled(false);
360 d_customScriptButton->setText("N/A");
361 d_customScriptButton->setEnabled(false);
364 d_comboType->updateSelection();
365 d_comboType->setEnabled(!d_cell->getIsCellCodeClassAssgined());
367 d_textPage->setText(QString::fromStdString(d_cell->getLocation()));
369 d_receptorItemModel->insertString("receptors");
370 d_receptorItemModel->insertColumns(1,2);
371 d_receptorItemModel->setData(d_receptorItemModel->index(0,1), QVariant::fromValue(DCResources::addItemIcon()));
373 d_axonTerminalItemModel->insertString("axonTerminals");
374 d_axonTerminalItemModel->insertColumns(1,2);
375 d_axonTerminalItemModel->setData(d_axonTerminalItemModel->index(0,1), QVariant::fromValue(DCResources::addItemIcon()));
377 const TKReceptorMap *receptors = d_cell->getReceptors();
378 TKReceptorMap::const_iterator it = receptors->begin();
379 QModelIndex rroot = d_receptorItemModel->index(0,0);
381 while( it != receptors->end())
384 QString receptorName = QString::fromStdString((*it).first);
385 d_receptorItemModel->insertString(receptorName,rroot);
386 d_receptorItemModel->setData(rroot.child(i,2), QVariant::fromValue(DCResources::deleteItemIcon()));
388 TKReceptor *receptor = (*it).second;
389 TKAxonTerminal *terminal = receptor->getTarget();
392 TKCell *targetCell = terminal->getOwner()->getOwner();
395 QString targetPath = DCUtil::getFQNPath(targetCell->getLocation(), targetCell->getName());
396 d_receptorItemModel->insertString(targetPath,rroot.child(i,0));
404 d_receptors->expand(rroot);
405 for (int i = 0; i < d_receptorItemModel->rowCount(rroot); i++)
407 QModelIndex index = rroot.child(i,0);
408 d_receptors->collapse(index);
409 if (d_receptorItemModel->rowCount(index) > 0)
411 d_receptors->collapse(index.child(0,0));
415 QModelIndex aroot = d_axonTerminalItemModel->index(0,0);
416 DCAxon *axon = d_cell->getAxon();
417 int acnt = axon->getNumberOfTerminals();
418 for (int i = 0; i < acnt; i++)
420 DCReceptor *targetReceptor = NULL;
421 DCCell *targetCell = NULL;
422 DCAxonTerminal *tarminal = axon->getTerminalAt(i);
425 targetReceptor = dynamic_cast<DCReceptor*>(tarminal->getTarget());
428 targetCell = dynamic_cast<DCCell*>(targetReceptor->getOwnerCell());
434 QString targetPath = DCUtil::getFQNPath(targetCell->getLocation(), targetCell->getName());
435 QString targetReceptorName = QString::fromStdString(targetCell->getReceptorName(targetReceptor));
436 d_axonTerminalItemModel->insertString(targetPath,aroot);
437 d_receptorItemModel->setData(aroot.child(i,2), QVariant::fromValue(DCResources::deleteItemIcon()));
438 d_axonTerminalItemModel->insertString(targetReceptorName,aroot.child(i,0));
446 d_axonTerminals->expand(aroot);
447 for (int i = 0; i < d_axonTerminalItemModel->rowCount(aroot); i++)
449 QModelIndex index = aroot.child(i,0);
450 d_axonTerminals->collapse(index);
451 if (d_axonTerminalItemModel->rowCount(index) > 0)
453 d_axonTerminals->collapse(index.child(0,0));
459 d_isViewUpdating = false;
462 void DCToolWindowCellEditor::slotReceptorTreeCollapsed(const QModelIndex &index)
467 void DCToolWindowCellEditor::slotReceptorTreeExpanded(const QModelIndex &index)
472 void DCToolWindowCellEditor::slotReceptorItemClicked(const QModelIndex &index)
474 switch (index.column())
477 qDebug() << "add item clicked..";
478 if (!index.parent().isValid())
480 getController()->doCommandStartAddAxonTerminalFromReceptor(this, d_cell);
485 qDebug() << "delete item clicked..";
486 if (index.parent().row() == 0)
488 int itemRowIndex = index.row();
489 if (itemRowIndex >= 0)
491 QModelIndex itemIndex = d_receptorItemModel->index(itemRowIndex,0,index.parent());
492 QString receptorName = d_receptorItemModel->data(itemIndex,Qt::DisplayRole).toString();
493 if (receptorName.length()>0)
495 d_receptors->setCurrentIndex(itemIndex);
496 getController()->doCommandRemoveAxonTerminal(this, d_cell, receptorName);
503 qDebug() << "other clicked..";
510 void DCToolWindowCellEditor::slotAxonTerminalTreeCollapsed(const QModelIndex &index)
515 void DCToolWindowCellEditor::slotAxonTerminalTreeExpanded(const QModelIndex &index)
520 void DCToolWindowCellEditor::slotAxonTerminalItemClicked(const QModelIndex &index)
522 switch (index.column())
525 qDebug() << "add item clicked..";
526 if (!index.parent().isValid())
528 getController()->doCommandStartAddAxonTerminalFromAxon(this, d_cell);
533 qDebug() << "delete item clicked..";
534 if (index.parent().row() == 0)
536 int itemIndex = index.row();
539 d_axonTerminals->setCurrentIndex(d_axonTerminalItemModel->index(itemIndex,0,index.parent()));
540 getController()->doCommandRemoveAxonTerminal(this, d_cell, d_cell->getAxon()->getTerminalAt(itemIndex));
546 qDebug() << "other clicked..";
552 void DCToolWindowCellEditor::slotCellCodeEditButtonPressed()
556 getController()->doCommandStartEditCellCode(this, d_cell);
560 void DCToolWindowCellEditor::slotCustomScriptEditButtonPressed()
564 getController()->doCommandStartEditCellCode(this, d_cell);
569 // There may be better / proper way to do this.
570 // The goal is to adjust the window height to fit all inside components
571 // with its desigered size.
572 void DCToolWindowCellEditor::resizeView()
575 int spacing = d_layout->verticalSpacing();
576 for (int i = 0 ; i < d_layout->rowCount(); i++ )
578 int maxHeightInRow = 0;
579 for (int j = 0; j < d_layout->columnCount(); j++)
581 QLayoutItem *item = d_layout->itemAtPosition(i,j);
584 QWidget *pWidget = item->widget();
587 QSize sh = pWidget->sizeHint();
588 pWidget->setFixedHeight(sh.height());
589 if (sh.height() > maxHeightInRow)
591 maxHeightInRow = sh.height();
596 totalHeight += maxHeightInRow + spacing;
600 int left,top,right,bottom;
601 contentLayout()->getContentsMargins(&left,&top,&right,&bottom);
602 s.setHeight(totalHeight + getTitleButtonHeight() + top + bottom);
605 adjustTreeColumnWidth();
608 void DCToolWindowCellEditor::adjustTreeColumnWidth()
610 d_receptors->setColumnWidth(1, 18);
611 d_receptors->setColumnWidth(2, 18);
612 QScrollBar *sb = d_receptors->verticalScrollBar();
613 if (sb && sb->isVisible())
614 d_receptors->setColumnWidth(0, d_receptors->width()-44 - sb->width());
616 d_receptors->setColumnWidth(0, d_receptors->width()-42);
618 d_axonTerminals->setColumnWidth(1, 18);
619 d_axonTerminals->setColumnWidth(2, 18);
620 d_axonTerminals->setColumnWidth(0, d_axonTerminals->width()-42);
621 sb = d_axonTerminals->verticalScrollBar();
622 if (sb && sb->isVisible())
623 d_axonTerminals->setColumnWidth(0, d_axonTerminals->width()-44 - sb->width());
625 d_axonTerminals->setColumnWidth(0, d_axonTerminals->width()-42);
628 void DCToolWindowCellEditor::slotCellDestroyed()