Back to index

salome-paravis  6.5.0
PVGUI_ParaViewSettingsPane.cxx
Go to the documentation of this file.
00001 // PARAVIS : ParaView wrapper SALOME module
00002 //
00003 // Copyright (C) 2010-2012  CEA/DEN, EDF R&D
00004 //
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License.
00009 //
00010 // This library is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this library; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00018 //
00019 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00020 //
00021 // File   : PVGUI_ParaViewSettingsPane.cxx
00022 // Author : Vitaly Smetannikov
00023 //
00024 
00025 #include "PVGUI_ParaViewSettingsPane.h"
00026 #include "ui_pqOptionsDialog.h"
00027 
00028 #include <pqOptionsContainer.h>
00029 #include <pqOptionsPage.h>
00030 #include <pqUndoStack.h>
00031 #include "pqApplicationCore.h"
00032 #include "pqApplicationOptions.h"
00033 #include "pqGlobalRenderViewOptions.h"
00034 #include "pqPluginManager.h"
00035 #include "pqViewOptionsInterface.h"
00036 #include "pqInterfaceTracker.h"
00037 
00038 #include <QAbstractItemModel>
00039 #include <QHeaderView>
00040 #include <QList>
00041 #include <QMap>
00042 #include <QString>
00043 
00044 
00045 class OptionsDialogModelItem
00046 {
00047 public:
00048   OptionsDialogModelItem();
00049   OptionsDialogModelItem(const QString &name);
00050   ~OptionsDialogModelItem();
00051 
00052   OptionsDialogModelItem *Parent;
00053   QString Name;
00054   QList<OptionsDialogModelItem *> Children;
00055 };
00056 
00057 
00058 class OptionsDialogModel : public QAbstractItemModel
00059 {
00060 public:
00061   OptionsDialogModel(QObject *parent=0);
00062   virtual ~OptionsDialogModel();
00063 
00064   virtual int rowCount(const QModelIndex &parent=QModelIndex()) const;
00065   virtual int columnCount(const QModelIndex &parent=QModelIndex()) const;
00066   virtual QModelIndex index(int row, int column,
00067       const QModelIndex &parent=QModelIndex()) const;
00068   virtual QModelIndex parent(const QModelIndex &child) const;
00069 
00070   virtual QVariant data(const QModelIndex &index,
00071       int role=Qt::DisplayRole) const;
00072 
00073   QModelIndex getIndex(const QString &path) const;
00074   QString getPath(const QModelIndex &index) const;
00075   void addPath(const QString &path);
00076   bool removeIndex(const QModelIndex &index);
00077 
00078 private:
00079   QModelIndex getIndex(OptionsDialogModelItem *item) const;
00080 
00081 private:
00082   OptionsDialogModelItem *Root;
00083 };
00084 
00085 
00086 class OptionsDialogForm : public Ui::pqOptionsFrame
00087 {
00088 public:
00089   OptionsDialogForm();
00090   ~OptionsDialogForm();
00091 
00092   QMap<QString, pqOptionsPage *> Pages;
00093   OptionsDialogModel *Model;
00094   int ApplyUseCount;
00095   //bool ApplyNeeded;
00096 };
00097 
00098 
00099 //----------------------------------------------------------------------------
00100 OptionsDialogModelItem::OptionsDialogModelItem()
00101   : Name(), Children()
00102 {
00103   this->Parent = 0;
00104 }
00105 
00106 OptionsDialogModelItem::OptionsDialogModelItem(const QString &name)
00107   : Name(name), Children()
00108 {
00109   this->Parent = 0;
00110 }
00111 
00112 OptionsDialogModelItem::~OptionsDialogModelItem()
00113 {
00114   QList<OptionsDialogModelItem *>::Iterator iter = this->Children.begin();
00115   for( ; iter != this->Children.end(); ++iter)
00116     {
00117     delete *iter;
00118     }
00119 }
00120 
00121 
00122 //----------------------------------------------------------------------------
00123 OptionsDialogModel::OptionsDialogModel(QObject *parentObject)
00124   : QAbstractItemModel(parentObject)
00125 {
00126   this->Root = new OptionsDialogModelItem();
00127 }
00128 
00129 OptionsDialogModel::~OptionsDialogModel()
00130 {
00131   delete this->Root;
00132 }
00133 
00134 int OptionsDialogModel::rowCount(const QModelIndex &parentIndex) const
00135 {
00136   OptionsDialogModelItem *item = this->Root;
00137   if(parentIndex.isValid())
00138     {
00139     item = reinterpret_cast<OptionsDialogModelItem *>(
00140         parentIndex.internalPointer());
00141     }
00142 
00143   return item->Children.size();
00144 }
00145 
00146 int OptionsDialogModel::columnCount(const QModelIndex &) const
00147 {
00148   return 1;
00149 }
00150 
00151 QModelIndex OptionsDialogModel::index(int row, int column,
00152     const QModelIndex &parentIndex) const
00153 {
00154   OptionsDialogModelItem *item = this->Root;
00155   if(parentIndex.isValid())
00156     {
00157     item = reinterpret_cast<OptionsDialogModelItem *>(
00158         parentIndex.internalPointer());
00159     }
00160 
00161   if(column == 0 && row >= 0 && row < item->Children.size())
00162     {
00163     return this->createIndex(row, column, item->Children[row]);
00164     }
00165 
00166   return QModelIndex();
00167 }
00168 
00169 QModelIndex OptionsDialogModel::parent(const QModelIndex &child) const
00170 {
00171   if(child.isValid())
00172     {
00173     OptionsDialogModelItem *item =
00174         reinterpret_cast<OptionsDialogModelItem *>(child.internalPointer());
00175     return this->getIndex(item->Parent);
00176     }
00177 
00178   return QModelIndex();
00179 }
00180 
00181 QVariant OptionsDialogModel::data(const QModelIndex &idx, int role) const
00182 {
00183   if(idx.isValid())
00184     {
00185     OptionsDialogModelItem *item =
00186         reinterpret_cast<OptionsDialogModelItem *>(idx.internalPointer());
00187     if(role == Qt::DisplayRole || role == Qt::ToolTipRole)
00188       {
00189       return QVariant(item->Name);
00190       }
00191     }
00192 
00193   return QVariant();
00194 }
00195 
00196 QModelIndex OptionsDialogModel::getIndex(const QString &path) const
00197 {
00198   OptionsDialogModelItem *item = this->Root;
00199   QStringList names = path.split(".");
00200   QStringList::Iterator iter = names.begin();
00201   for( ; item && iter != names.end(); ++iter)
00202     {
00203     OptionsDialogModelItem *child = 0;
00204     QList<OptionsDialogModelItem *>::Iterator jter = item->Children.begin();
00205     for( ; jter != item->Children.end(); ++jter)
00206       {
00207       if((*jter)->Name == *iter)
00208         {
00209         child = *jter;
00210         break;
00211         }
00212       }
00213 
00214     item = child;
00215     }
00216 
00217   if(item && item != this->Root)
00218     {
00219     return this->getIndex(item);
00220     }
00221 
00222   return QModelIndex();
00223 }
00224 
00225 QString OptionsDialogModel::getPath(const QModelIndex &idx) const
00226 {
00227   if(idx.isValid())
00228     {
00229     QString path;
00230     OptionsDialogModelItem *item =
00231         reinterpret_cast<OptionsDialogModelItem *>(idx.internalPointer());
00232     if(item)
00233       {
00234       path = item->Name;
00235       item = item->Parent;
00236       }
00237 
00238     while(item && item != this->Root)
00239       {
00240       path.prepend(".").prepend(item->Name);
00241       item = item->Parent;
00242       }
00243 
00244     return path;
00245     }
00246 
00247   return QString();
00248 }
00249 
00250 void OptionsDialogModel::addPath(const QString &path)
00251 {
00252   OptionsDialogModelItem *item = this->Root;
00253   QStringList names = path.split(".");
00254   QStringList::Iterator iter = names.begin();
00255   for( ; iter != names.end(); ++iter)
00256     {
00257     OptionsDialogModelItem *child = 0;
00258     QList<OptionsDialogModelItem *>::Iterator jter = item->Children.begin();
00259     for( ; jter != item->Children.end(); ++jter)
00260       {
00261       if((*jter)->Name == *iter)
00262         {
00263         child = *jter;
00264         break;
00265         }
00266       }
00267 
00268     if(!child)
00269       {
00270       child = new OptionsDialogModelItem(*iter);
00271       child->Parent = item;
00272       QModelIndex parentIndex = this->getIndex(item);
00273       int row = item->Children.size();
00274       this->beginInsertRows(parentIndex, row, row);
00275       item->Children.append(child);
00276       this->endInsertRows();
00277       }
00278 
00279     item = child;
00280     }
00281 }
00282 
00283 bool OptionsDialogModel::removeIndex(const QModelIndex &idx)
00284 {
00285   if(idx.isValid())
00286     {
00287     OptionsDialogModelItem *item =
00288         reinterpret_cast<OptionsDialogModelItem *>(idx.internalPointer());
00289     if(item->Children.size() == 0)
00290       {
00291       QModelIndex parentIndex = this->getIndex(item->Parent);
00292       this->beginRemoveRows(parentIndex, idx.row(), idx.row());
00293       item->Parent->Children.removeAt(idx.row());
00294       this->endRemoveRows();
00295       delete item;
00296       return true;
00297       }
00298     }
00299 
00300   return false;
00301 }
00302 
00303 QModelIndex OptionsDialogModel::getIndex(
00304     OptionsDialogModelItem *item) const
00305 {
00306   if(item && item->Parent)
00307     {
00308     return this->createIndex(item->Parent->Children.indexOf(item), 0, item);
00309     }
00310 
00311   return QModelIndex();
00312 }
00313 
00314 
00315 //----------------------------------------------------------------------------
00316 OptionsDialogForm::OptionsDialogForm()
00317   : Ui::pqOptionsFrame(), Pages()
00318 {
00319   this->Model = new OptionsDialogModel();
00320   this->ApplyUseCount = 0;
00321   //this->ApplyNeeded = false;
00322 }
00323 
00324 OptionsDialogForm::~OptionsDialogForm()
00325 {
00326   delete this->Model;
00327 }
00328 
00329 
00330 //----------------------------------------------------------------------------
00331 PVGUI_ParaViewSettingsPane::PVGUI_ParaViewSettingsPane(QWidget *widgetParent)
00332   : QtxUserDefinedContent(widgetParent)
00333 {
00334   this->Form = new OptionsDialogForm();
00335   this->Form->setupUi(this);
00336   this->Form->PageNames->setModel(this->Form->Model);
00337 
00338   // Hide the tree widget header view.
00339   this->Form->PageNames->header()->hide();
00340 
00341   // Hide the apply and reset buttons until they are needed.
00342   //this->Form->ApplyButton->setEnabled(false);
00343   //this->Form->ResetButton->setEnabled(false);
00344   //this->Form->ApplyButton->hide();
00345   //this->Form->ResetButton->hide();
00346 
00347   this->connect(this->Form->PageNames->selectionModel(),
00348       SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
00349       this, SLOT(changeCurrentPage()));
00350   //this->connect(this->Form->ApplyButton, SIGNAL(clicked()),
00351   //    this, SLOT(applyChanges()));
00352   //this->connect(this->Form->ResetButton, SIGNAL(clicked()),
00353   //    this, SLOT(resetChanges()));
00354   //this->connect(this->Form->CloseButton, SIGNAL(clicked()),
00355   //    this, SLOT(accept()));
00356 
00357   // Code From pqApplicationOptionsDialog
00358   //this->setApplyNeeded(true);
00359 
00360   pqApplicationOptions* appOptions = new pqApplicationOptions;
00361   this->addOptions(appOptions);
00362   
00363   pqGlobalRenderViewOptions* renOptions = new pqGlobalRenderViewOptions;
00364   this->addOptions(renOptions);
00365   
00366   QStringList pages = appOptions->getPageList();
00367   if(pages.size())
00368     {
00369     this->setCurrentPage(pages[0]);
00370     }
00371 
00373   QObject::connect(pqApplicationCore::instance()->getPluginManager(),
00374     SIGNAL(guiInterfaceLoaded(QObject*)),
00375     this, SLOT(pluginLoaded(QObject*)));
00376 
00377   // Load panes from already loaded plugins.
00378   foreach (QObject* plugin_interface, pqApplicationCore::instance()->interfaceTracker()->interfaces())
00379            //pqApplicationCore::instance()->getPluginManager()->interfaces())
00380     {
00381     this->pluginLoaded(plugin_interface);
00382     }
00383 }
00384 
00385 PVGUI_ParaViewSettingsPane::~PVGUI_ParaViewSettingsPane()
00386 {
00387   delete this->Form;
00388 }
00389 /*
00390 bool PVGUI_ParaViewSettingsPane::isApplyNeeded() const
00391 {
00392   return this->Form->ApplyNeeded;
00393 }
00394 */
00395 /*
00396 void PVGUI_ParaViewSettingsPane::setApplyNeeded(bool applyNeeded)
00397 {
00398   if(applyNeeded != this->Form->ApplyNeeded)
00399     {
00400     if(!applyNeeded)
00401       {
00402       this->Form->ApplyNeeded = false;
00403       //this->Form->ApplyButton->setEnabled(false);
00404       //this->Form->ResetButton->setEnabled(false);
00405       }
00406     else if(this->Form->ApplyUseCount > 0)
00407       {
00408       this->Form->ApplyNeeded = true;
00409       //this->Form->ApplyButton->setEnabled(true);
00410       //this->Form->ResetButton->setEnabled(true);
00411       }
00412     }
00413 }
00414 */
00415 void PVGUI_ParaViewSettingsPane::addOptions(const QString &path, pqOptionsPage *options)
00416 {
00417   if(!options)
00418     {
00419     return;
00420     }
00421 
00422   // See if the page is a container.
00423   pqOptionsContainer *container = qobject_cast<pqOptionsContainer *>(options);
00424   if(!container && path.isEmpty())
00425     {
00426     return;
00427     }
00428 
00429   // See if the page/container uses the apply button.
00430   if(options->isApplyUsed())
00431     {
00432     this->Form->ApplyUseCount++;
00433     /*if(this->Form->ApplyUseCount == 1)
00434       {
00435         //this->Form->ApplyButton->show();
00436         //this->Form->ResetButton->show();
00437         //QObject::connect(this, SIGNAL(accepted()), this, SLOT(applyChanges()));
00438         }*/
00439 
00440     //this->connect(options, SIGNAL(changesAvailable()),
00441     //this, SLOT(enableButtons()));
00442     }
00443 
00444   // Add the widget to the stack.
00445   this->Form->Stack->addWidget(options);
00446 
00447   // Add the page(s) to the map and the model.
00448   if(container)
00449     {
00450     // If the path is not empty, use it as the page prefix.
00451     QString prefix;
00452     if(!path.isEmpty())
00453       {
00454       prefix = path;
00455       prefix.append(".");
00456       }
00457 
00458     container->setPagePrefix(prefix);
00459 
00460     // Get the list of pages from the container.
00461     QStringList pathList = container->getPageList();
00462     QStringList::Iterator iter = pathList.begin();
00463     for( ; iter != pathList.end(); ++iter)
00464       {
00465       this->Form->Pages.insert(prefix + *iter, options);
00466       this->Form->Model->addPath(prefix + *iter);
00467       }
00468     }
00469   else
00470     {
00471     this->Form->Pages.insert(path, options);
00472     this->Form->Model->addPath(path);
00473     }
00474 }
00475 
00476 void PVGUI_ParaViewSettingsPane::addOptions(pqOptionsContainer *options)
00477 {
00478   this->addOptions(QString(), options);
00479 }
00480 
00481 void PVGUI_ParaViewSettingsPane::removeOptions(pqOptionsPage *options)
00482 {
00483   if(!options)
00484     {
00485     return;
00486     }
00487 
00488   // Remove the widget from the stack.
00489   this->Form->Stack->removeWidget(options);
00490 
00491   // See if the options use the apply button.
00492   if(options->isApplyUsed())
00493     {
00494     this->Form->ApplyUseCount--;
00495     /*if(this->Form->ApplyUseCount == 0)
00496       {
00497         //this->Form->ApplyNeeded = false;
00498       //this->Form->ApplyButton->setEnabled(false);
00499       //this->Form->ResetButton->setEnabled(false);
00500       //this->Form->ApplyButton->hide();
00501       //this->Form->ResetButton->hide();
00502       //QObject::disconnect(this, SIGNAL(accepted()), this, SLOT(applyChanges()));
00503       }*/
00504 
00505     this->disconnect(options, 0, this, 0);
00506     }
00507 
00508   // Search the map for the paths to remove.
00509   QMap<QString, pqOptionsPage *>::Iterator iter = this->Form->Pages.begin();
00510   while(iter != this->Form->Pages.end())
00511     {
00512     if(*iter == options)
00513       {
00514       QString path = iter.key();
00515       iter = this->Form->Pages.erase(iter);
00516 
00517       // Remove the item from the tree model as well.
00518       QModelIndex index = this->Form->Model->getIndex(path);
00519       QPersistentModelIndex parentIndex = index.parent();
00520       if(this->Form->Model->removeIndex(index))
00521         {
00522         // Remove any empty parent items.
00523         while(parentIndex.isValid() &&
00524             this->Form->Model->rowCount(parentIndex) == 0)
00525           {
00526           index = parentIndex;
00527           parentIndex = index.parent();
00528 
00529           // Make sure the index path isn't in the map.
00530           path = this->Form->Model->getPath(index);
00531           if(this->Form->Pages.find(path) == this->Form->Pages.end())
00532             {
00533             if(!this->Form->Model->removeIndex(index))
00534               {
00535               break;
00536               }
00537             }
00538           }
00539         }
00540       }
00541     else
00542       {
00543       ++iter;
00544       }
00545     }
00546 }
00547 
00548 void PVGUI_ParaViewSettingsPane::setCurrentPage(const QString &path)
00549 {
00550   QModelIndex current = this->Form->Model->getIndex(path);
00551   this->Form->PageNames->setCurrentIndex(current);
00552 }
00553 
00554 void PVGUI_ParaViewSettingsPane::applyChanges()
00555 {
00556   //if(this->Form->ApplyNeeded)
00557   //  {
00558     BEGIN_UNDO_SET("Changed View Settings");
00559     emit this->aboutToApplyChanges();
00560     QMap<QString, pqOptionsPage *>::Iterator iter = this->Form->Pages.begin();
00561     for( ; iter != this->Form->Pages.end(); ++iter)
00562       {
00563       (*iter)->applyChanges();
00564       }
00565 
00566     //this->setApplyNeeded(false);
00567     emit this->appliedChanges();
00568     END_UNDO_SET();
00569     //}
00570 }
00571 
00572 void PVGUI_ParaViewSettingsPane::resetChanges()
00573 {
00574   //if(this->Form->ApplyNeeded)
00575   //{
00576     QMap<QString, pqOptionsPage *>::Iterator iter = this->Form->Pages.begin();
00577     for( ; iter != this->Form->Pages.end(); ++iter)
00578       {
00579       (*iter)->resetChanges();
00580       }
00581 
00582     //this->setApplyNeeded(false);
00583     //}
00584 }
00585 
00586 void PVGUI_ParaViewSettingsPane::changeCurrentPage()
00587 {
00588   // Get the current index from the view.
00589   QModelIndex current = this->Form->PageNames->currentIndex();
00590 
00591   // Look up the path for the current index.
00592   QString path = this->Form->Model->getPath(current);
00593   QMap<QString, pqOptionsPage *>::Iterator iter = this->Form->Pages.find(path);
00594   if(iter == this->Form->Pages.end())
00595     {
00596     // If no page is found, show the blank page.
00597     this->Form->Stack->setCurrentWidget(this->Form->BlankPage);
00598     }
00599   else
00600     {
00601     this->Form->Stack->setCurrentWidget(*iter);
00602     pqOptionsContainer *container = qobject_cast<pqOptionsContainer *>(*iter);
00603     if(container)
00604       {
00605       // Get the path prefix from the container.
00606       QString prefix = container->getPagePrefix();
00607       if(!prefix.isEmpty())
00608         {
00609         // Remove the prefix from the path.
00610         path.remove(0, prefix.length());
00611         }
00612 
00613       // Set the page on the container object.
00614       container->setPage(path);
00615       }
00616     }
00617 }
00618 
00619 //-----------------------------------------------------------------------------
00620 void PVGUI_ParaViewSettingsPane::pluginLoaded(QObject* iface)
00621 {
00622   pqViewOptionsInterface* viewOptions =
00623     qobject_cast<pqViewOptionsInterface*>(iface);
00624   if (viewOptions)
00625     {
00626     foreach(QString viewtype, viewOptions->viewTypes())
00627       {
00628       // Try to create global view options
00629       pqOptionsContainer* globalOptions =
00630         viewOptions->createGlobalViewOptions(viewtype, this);
00631       if (globalOptions)
00632         {
00633         this->addOptions(globalOptions);
00634         }
00635       }
00636     }
00637 }
00638 
00639 void PVGUI_ParaViewSettingsPane::store(QtxResourceMgr* , QtxPreferenceMgr* )
00640 {
00641   applyChanges();
00642 }
00643 
00644 void PVGUI_ParaViewSettingsPane::retrieve(QtxResourceMgr* , QtxPreferenceMgr* )
00645 {
00646 }
00647