COPASI API  4.16.103
CQLayoutsWidget.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010 - 2015 by Pedro Mendes, Virginia Tech Intellectual
2 // Properties, Inc., University of Heidelberg, and The University
3 // of Manchester.
4 // All rights reserved.
5 
6 // Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
7 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
8 // and The University of Manchester.
9 // All rights reserved.
10 
11 #include "CQLayoutsWidget.h"
12 
13 #include <iostream>
14 
15 #include "CQMessageBox.h"
16 #include "CQLayoutsDM.h"
17 #include "CQSortFilterProxyModel.h"
18 #include "CQPushButtonDelegate.h"
19 
20 #include "listviews.h"
21 #include "qtUtilities.h"
23 
24 #include "copasi/layout/CLayout.h"
26 #include "copasi/model/CModel.h"
31 
33 
34 #ifndef DISABLE_QT_LAYOUT_RENDERING
36 #endif //DISABLE_QT_LAYOUT_RENDERING
37 
39 
41 
42 #include <sstream>
43 
45  : CopasiWidget(parent)
46 {
47  setupUi(this);
48 
49  // Create Source Data Model.
50  mpLayoutsDM = new CQLayoutsDM(this);
51 
52  // Create the Proxy Model for sorting/filtering and set its properties.
54  mpProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
55  mpProxyModel->setFilterKeyColumn(-1);
56  mpProxyModel->setSourceModel(mpLayoutsDM);
57 
58  mpTblLayouts->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
59  mpTblLayouts->verticalHeader()->hide();
60  mpTblLayouts->sortByColumn(COL_ROW_NUMBER, Qt::AscendingOrder);
61  mpTblLayouts->setModel(mpProxyModel);
62 
64 
65  mpTblLayouts->setItemDelegateForColumn(COL_SHOW, mpPushButtonDelegate);
66 
67  // Connect the table widget
68  connect(mpLayoutsDM, SIGNAL(notifyGUI(ListViews::ObjectType, ListViews::Action, const std::string)),
69  this, SLOT(protectedNotify(ListViews::ObjectType, ListViews::Action, const std::string)));
70  connect(mpLayoutsDM, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
71  this, SLOT(dataChanged(const QModelIndex&, const QModelIndex&)));
72  connect(mpLEFilter, SIGNAL(textChanged(const QString &)),
73  this, SLOT(slotFilterChanged()));
74  connect(mpPushButtonDelegate, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotShowLayout(const QModelIndex &)));
75 }
76 
77 // virtual
79 {
81 }
82 
83 // virtual
84 bool CQLayoutsWidget::update(ListViews::ObjectType /* objectType */, ListViews::Action /* action */, const std::string & /* key */)
85 {
86  if (!mIgnoreUpdates)
87  {
89  }
90 
91  return true;
92 }
93 
94 // virtual
96 {
97  return true;
98 }
99 
101 {
102  LayoutWindowMap::iterator it = mLayoutWindowMap.begin(), endit = mLayoutWindowMap.end();
103 
104  while (it != endit)
105  {
106  delete it->second;
107  ++it;
108  }
109 
110  mLayoutWindowMap.clear();
111 }
112 
114 {
115  const QItemSelectionModel * pSelectionModel = mpTblLayouts->selectionModel();
116 
117  QModelIndexList mappedSelRows;
118  size_t i, imax = mpLayoutsDM->rowCount();
119 
120  for (i = 0; i < imax; i++)
121  {
122  if (pSelectionModel->isRowSelected((int) i, QModelIndex()))
123  {
124  mappedSelRows.append(mpProxyModel->mapToSource(mpProxyModel->index((int) i, 0)));
125  }
126  }
127 
128  if (mappedSelRows.empty()) return;
129 
130  // We need to make sure that we remove the window mapped for each layout
131  QModelIndexList::const_iterator it = mappedSelRows.begin();
132  QModelIndexList::const_iterator end = mappedSelRows.end();
133 
134  assert(CCopasiRootContainer::getDatamodelList()->size() > 0);
135  CListOfLayouts * pListOfLayouts = (*CCopasiRootContainer::getDatamodelList())[0]->getListOfLayouts();
136 
137  for (; it != end; ++it)
138  {
139  LayoutWindowMap::iterator itWindow = mLayoutWindowMap.find((*pListOfLayouts)[it->row()]->getKey());
140 
141  if (itWindow != mLayoutWindowMap.end())
142  {
143  mLayoutWindowMap.erase(itWindow);
144  delete itWindow->second;
145  }
146  }
147 
148  mpLayoutsDM->removeRows(mappedSelRows);
149 }
150 
152 {
153  mpBtnDelete->setEnabled(mpTblLayouts->selectionModel()->selectedRows().size() > 0);
154  mpBtnClear->setEnabled(mpProxyModel->rowCount() > 0);
155 }
156 
157 // virtual
159 {
160  if (mpTblLayouts->selectionModel() != NULL)
161  {
162  disconnect(mpTblLayouts->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
163  this, SLOT(slotSelectionChanged(const QItemSelection&, const QItemSelection&)));
164  }
165 
166  assert(CCopasiRootContainer::getDatamodelList()->size() > 0);
167  CListOfLayouts * pListOfLayouts = (*CCopasiRootContainer::getDatamodelList())[0]->getListOfLayouts();
168  mpLayoutsDM->setListOfLayouts(pListOfLayouts);
169 
170  // check if we have at least a compartment
171  // that we can lay out.
173 
174  if (pDataModel != NULL &&
175  pDataModel->getModel() != NULL &&
176  pDataModel->getModel()->getCompartments().size() > 0)
177  {
178  mpBtnNew->setEnabled(true);
179  }
180  else
181  {
182  mpBtnNew->setEnabled(false);
183  }
184 
185  // We need to make sure that we have a window mapped for each layout
186  CListOfLayouts::const_iterator it = pListOfLayouts->begin();
187  CListOfLayouts::const_iterator end = pListOfLayouts->end();
188 
189  for (; it != end; ++it)
190  {
191  LayoutWindowMap::iterator pos = mLayoutWindowMap.find((*it)->getKey());
192 
193  // if this layout does not have an entry in the layout window map, add one
194  if (pos == mLayoutWindowMap.end())
195  {
196  mLayoutWindowMap.insert(std::pair<std::string, LayoutWindow*>((*it)->getKey(), (LayoutWindow*)NULL));
197  }
198  }
199 
200  connect(mpTblLayouts->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
201  this, SLOT(slotSelectionChanged(const QItemSelection&, const QItemSelection&)));
202 
203  dataChanged(QModelIndex(), QModelIndex());
204 
205  return true;
206 }
207 
209 {
210  int i, imax = mpLayoutsDM->rowCount();
211 
212  for (i = 0; i < imax; ++i)
213  {
214  this->mpTblLayouts->openPersistentEditor(mpProxyModel->index(i, COL_SHOW, QModelIndex()));
215  }
216 }
217 
218 bool hasLayout(const CListOfLayouts& layouts, const std::string &name)
219 {
220 
221  for (size_t i = 0; i < layouts.size(); ++i)
222  {
223  const CLayout *layout = layouts[i];
224  const std::string &current = layout->getObjectName();
225 
226  if (current == name)
227  return true;
228  }
229 
230  return false;
231 }
232 
233 // virtual
235 {
237  const CModel* pModel = pDataModel->getModel();
238  assert(pModel != NULL);
239 
240  std::string name = "COPASI autolayout";
241  int ncount = 1;
242 
243  while (hasLayout(*(pDataModel->getListOfLayouts()), name))
244  {
245  std::stringstream str;
246  str << "COPASI autolayout " << ncount++;
247  name = str.str();
248  }
249 
250  CQAutolayoutWizard pWizard(*pModel);
251 
252  if (pWizard.exec() != QDialog::Accepted)
253  return;
254 
255  // add the layout to the datamodel
256  std::map<std::string, std::string> m;
257 
258  CListOfLayouts * pListOfLayouts = pDataModel->getListOfLayouts();
259 
260  // create the random layout
263  pDataModel, pWizard.getSelectedCompartments(),
264  pWizard.getSelectedReactions(),
265  pWizard.getSelectedMetabolites(),
266  pWizard.getSideMetabolites(),
267  &p);
268 
269  pLayout->setObjectName(name);
270  pListOfLayouts->addLayout(pLayout, m);
271 
272  // update the table
273  mpLayoutsDM->insertRows(pListOfLayouts->size() - 1, 1);
274  dataChanged(QModelIndex(), QModelIndex());
275 
276  LayoutWindow *window = createLayoutWindow(pListOfLayouts->size() - 1, pLayout);
277  CQNewMainWindow* pWin = dynamic_cast<CQNewMainWindow*>(window);
278 
279 #ifndef DISABLE_QT_LAYOUT_RENDERING
280  CQAnimationWindow* pAnim = dynamic_cast<CQAnimationWindow*>(window);
281 
282  if (pAnim != NULL)
283  {
284  pAnim->show();
285  // now we create the spring layout
286  pAnim->slotAutoLayout();
287  }
288  else
289 #endif //DISABLE_QT_LAYOUT_RENDERING
290 
291  if (pWin != NULL)
292  {
293  pWin->updateRenderer();
294  pWin->setMode();
295  // show the new layout
296  pWin->show();
297  pWin->redrawNow();
298  // now we create the spring layout
299  pWin->slotRunSpringLayout();
300  }
301 
302  else
303  {
304  delete pLayout;
305  }
306 }
307 
308 // virtual
310 {
311  if (mpTblLayouts->hasFocus())
313 }
314 
315 // virtual
317 {
318  int ret = CQMessageBox::question(this, tr("Confirm Delete"), "Delete all Layouts?",
319  QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
320 
321  if (ret == QMessageBox::Yes)
322  {
323  mpLayoutsDM->clear();
325  }
326 }
327 
328 // virtual
329 void CQLayoutsWidget::slotSelectionChanged(const QItemSelection & /* selected */,
330  const QItemSelection & /* deselected */)
331 {
333 }
334 
335 // virtual
336 void CQLayoutsWidget::slotDoubleClicked(const QModelIndex proxyIndex)
337 {
338  QModelIndex index = mpProxyModel->mapToSource(proxyIndex);
339 
340  int row = index.row();
341 
342  if (row >= mpLayoutsDM->rowCount() || row < 0) return;
343 
344  slotShowLayout(index);
345 }
346 
347 // virtual
348 void CQLayoutsWidget::dataChanged(const QModelIndex & /* topLeft */,
349  const QModelIndex & /* bottomRight */)
350 {
351  mpTblLayouts->resizeColumnsToContents();
353  showButtons();
354 }
355 
356 // virtual
358 {
359  QRegExp regExp(mpLEFilter->text(), Qt::CaseInsensitive, QRegExp::RegExp);
360  mpProxyModel->setFilterRegExp(regExp);
361 }
362 
363 /**
364  * This creates a new layout window and return a pointer to it.
365  * In case of an error, NULL is returned.
366  */
368 {
369  if (pLayout == NULL || row < 0) return NULL;
370 
371  LayoutWindow * pWin = NULL;
372 
373 #ifndef DISABLE_QT_LAYOUT_RENDERING
374 
375  if (CCopasiRootContainer::getConfiguration()->useOpenGL())
376  {
378  (static_cast<CQNewMainWindow*>(pWin))->slotLayoutChanged(row);
379  }
380  else
381  {
382  pWin = new CQAnimationWindow(pLayout, (*CCopasiRootContainer::getDatamodelList())[0]);
383  }
384 
385 #else
387  (static_cast<CQNewMainWindow*>(pWin))->slotLayoutChanged(row);
388 #endif //DISABLE_QT_LAYOUT_RENDERING
389 
390  std::string title = "COPASI Diagram: " + pLayout->getObjectName();
391  pWin->setWindowTitle(title.c_str());
392  pWin->addToMainWindow();
393  pWin->resize(900, 600);
394  mLayoutWindowMap[pLayout->getKey()] = pWin;
395 
396  return pWin;
397 }
398 
399 void CQLayoutsWidget::slotShowLayout(const QModelIndex & index)
400 {
401  int row = index.row();
402 
403  assert(CCopasiRootContainer::getDatamodelList()->size() > 0);
404  CListOfLayouts* pListOfLayouts = (*CCopasiRootContainer::getDatamodelList())[0]->getListOfLayouts();
405 
406  CLayout* pLayout = (* pListOfLayouts)[row];
407  std::string Key = pLayout->getKey();
408 
409  if (pLayout != NULL)
410  {
411  // check if we already have a widget for the layout
412  // if yes, open it, else create one and add it to the map
413  LayoutWindow * pLayoutWindow = NULL;
414 
415  LayoutWindowMap::iterator pos = mLayoutWindowMap.find(Key);
416 
417  if (pos != mLayoutWindowMap.end())
418  {
419  pLayoutWindow = pos->second;
420  }
421 
422  if (pLayoutWindow == NULL)
423  {
424  pLayoutWindow = createLayoutWindow(row, pLayout);
425 
426  // need to add it to the list, so the window can be deleted later
427  mLayoutWindowMap[pLayout->getKey()] = pLayoutWindow;
428  }
429 
430  if (pLayoutWindow != NULL)
431  {
432  CQNewMainWindow* cqWin = dynamic_cast<CQNewMainWindow*>(pLayoutWindow);
433 
434  if (cqWin != NULL)
435  {
436  cqWin ->slotLayoutChanged(row);
437  cqWin ->setMode();
438  }
439 
440  pLayoutWindow->show();
441  pLayoutWindow->showNormal();
442  pLayoutWindow->activateWindow();
443  }
444  }
445  else
446  {
447  //std::cerr << "Could not find layout." << std::endl;
448  }
449 }
void slotAutoLayout()
Slots the auto layout.
virtual ~CQLayoutsWidget()
bool removeRows(QModelIndexList rows, const QModelIndex &index=QModelIndex())
void slotLayoutChanged(int index)
#define pdelete(p)
Definition: copasi.h:215
CQSortFilterProxyModel * mpProxyModel
virtual bool leave()
virtual bool clear()
Definition: CQLayoutsDM.cpp:31
const std::string & getObjectName() const
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
Definition: CQLayoutsDM.cpp:24
virtual size_t size() const
CQLayoutsDM * mpLayoutsDM
virtual bool update(ListViews::ObjectType objectType, ListViews::Action action, const std::string &key)
void setMode(DISPLAY_MODE mode=GRAPH_MODE)
iterator begin()
LayoutWindow * createLayoutWindow(int row, CLayout *pLayout)
virtual void slotFilterChanged()
bool hasLayout(const CListOfLayouts &layouts, const std::string &name)
const std::set< const CMetab * > & getSideMetabolites() const
virtual void slotDoubleClicked(const QModelIndex proxyIndex)
virtual bool insertRows(int position, int rows, const QModelIndex &index=QModelIndex())
bool mIgnoreUpdates
Definition: copasiWidget.h:67
void slotShowLayout(const QModelIndex &index)
const std::set< const CReaction * > & getSelectedReactions() const
static CConfigurationFile * getConfiguration()
iterator end()
std::vector< CType * >::const_iterator const_iterator
Definition: CCopasiVector.h:57
const std::set< const CMetab * > & getSelectedMetabolites() const
CQPushButtonDelegate * mpPushButtonDelegate
virtual void slotBtnDeleteClicked()
static CLayout * createLayout(CCopasiContainer *parent, const std::set< const CCompartment * > &compartments, const std::set< const CReaction * > &reactions, const std::set< const CMetab * > &metabs, const std::set< const CMetab * > &sideMetabs, Parameters *mParams=NULL)
LayoutWindowMap mLayoutWindowMap
static const QIcon & icon(const IconID &id)
virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
static CCopasiVector< CCopasiDataModel > * getDatamodelList()
virtual void slotBtnClearClicked()
virtual void slotBtnNewClicked()
CListOfLayouts * getListOfLayouts()
virtual const std::string & getKey() const
Definition: CLayout.h:71
virtual bool protectedNotify(ListViews::ObjectType objectType, ListViews::Action action, const std::string &key="")
CQLayoutsWidget(QWidget *parent)
void addLayout(CLayout *layout, const std::map< std::string, std::string > &m)
CCopasiVectorNS< CCompartment > & getCompartments()
Definition: CModel.cpp:1145
void setListOfLayouts(CListOfLayouts *pListOfLayouts)
virtual bool enterProtected()
Definition: CModel.h:50
void addToMainWindow(CopasiUI3Window *window=NULL)
virtual void slotSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
bool setObjectName(const std::string &name)
#define COL_SHOW
Definition: CQLayoutsDM.h:21
const std::set< const CCompartment * > & getSelectedCompartments() const
static StandardButton question(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons=Ok, StandardButton defaultButton=NoButton)
#define COL_ROW_NUMBER