Back to index

salome-gui  6.5.0
SalomeApp_ListView.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 // File   : SalomeApp_ListView.cxx
00024 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
00025 //
00026 #include "SalomeApp_ListView.h"
00027 #include "SalomeApp_Application.h"
00028 
00029 #include "SUIT_ResourceMgr.h"
00030 #include "SUIT_Session.h"
00031 
00032 #include <QValidator>
00033 #include <QToolButton>
00034 #include <QPixmap>
00035 #include <QHeaderView>
00036 #include <QKeyEvent>
00037 
00038 #include <TColStd_ListOfInteger.hxx>
00039 #include <TColStd_ListOfReal.hxx>
00040 
00041 #include <TColStd_ListIteratorOfListOfInteger.hxx>
00042 #include <TColStd_ListIteratorOfListOfReal.hxx>
00043 
00047 void computeEditGeometry(SalomeApp_ListViewItem* theItem,
00048                          SalomeApp_EntityEdit*   theWidget)
00049 {
00050   if (!theItem)
00051     return;
00052   QTreeWidget* aListView = theItem->treeWidget();
00053   int anEditColumn = theItem->getEditedColumn();
00054   if (anEditColumn < 0)
00055     return;
00056 
00057   int aX = 0, aY = 0, aW = 0, aH = 0;
00058 
00059   QRect aRect = aListView->visualItemRect(theItem);
00060   aX = aListView->header()->sectionViewportPosition(anEditColumn);
00061   if (aX < 0)
00062     aX = 0; // THIS CAN BE REMOVED
00063   QSize aSize = theWidget->getControl()->sizeHint();
00064   aH = qMax(aSize.height() , aRect.height() );
00065   aY = aRect.y() - ((aH - aRect.height()) / 2);
00066   //aW = aListView->columnWidth(anEditColumn); // CAN SUBSTITUTE NEXT 3 ROWS
00067   aW = aListView->viewport()->width() - aX;
00068   if (aW < 0)
00069     aW = 0;
00070   theWidget->setGeometry(aX, aY, aW, aH);
00071 }
00072 
00076 SalomeApp_ListView::SalomeApp_ListView( QWidget* parent )
00077   : QTreeWidget/*QtxListView*/( parent )
00078 {
00079   myMouseEnabled = true;
00080   myEditingEnabled = false;
00081   setSelectionMode(QAbstractItemView::SingleSelection);
00082   setRootIsDecorated(false);
00083   setAllColumnsShowFocus(false);
00084 //  header()->setClickEnabled(false);
00085   header()->setMovable(false);
00086 
00087   myEditedItem = 0;
00088   myEdit = 0;
00089 
00090   viewport()->installEventFilter(this);
00091 
00092   connect(this, SIGNAL(itemSelectionChanged()),
00093           this, SLOT(onSelectionChanged()));
00094   connect(header(), SIGNAL(sizeChange(int, int, int)),
00095           this,     SLOT(onHeaderSizeChange(int, int, int)));
00096 }
00097 
00101 SalomeApp_ListView::~SalomeApp_ListView()
00102 {
00103   if (myEdit) {
00104     delete myEdit;
00105   }
00106   myEdit = 0;
00107   myEditedItem = 0;
00108 }
00109 
00113 void SalomeApp_ListView::updateViewer()
00114 {
00115   // temporary disconnecting selection changed SIGNAL
00116   blockSignals(true);
00117   QTreeWidgetItemIterator it( this );
00118   SalomeApp_ListViewItem* aRoot = (SalomeApp_ListViewItem*)(*it);
00119   if (aRoot)
00120     aRoot->updateAllLevels();
00121   update( contentsRect() );//updateContents();
00122   // connecting again selection changed SIGNAL
00123   blockSignals(false);
00124   emit itemSelectionChanged();
00125 }
00126 
00130 void SalomeApp_ListView::updateSelected()
00131 {
00132   // temporary disconnecting selection changed SIGNAL
00133   blockSignals(true);
00134   SalomeApp_ListViewItem* aChild = (SalomeApp_ListViewItem*)(selectedItems().first());
00135   if (aChild)
00136     aChild->updateAllLevels();
00137   update( contentsRect() );//updateContents();
00138   // connecting again selection changed SIGNAL
00139   blockSignals(false);
00140   emit itemSelectionChanged();
00141 }
00142 
00146 QString SalomeApp_ListView::popupClientType() const
00147 {
00148   return "SalomeApp_ListView";
00149 }
00150 
00154 void SalomeApp_ListView::contextMenuPopup( QMenu* aPopup )
00155 {
00156   if (aPopup) {
00157     // add items here...
00158   }
00159 }
00160 
00164 void SalomeApp_ListView::clear()
00165 {
00166   if (myEdit) {
00167     delete myEdit;
00168     myEdit = 0;
00169     myEditedItem = 0;
00170   }
00171   QTreeWidget::clear();
00172 }
00173 
00177 bool SalomeApp_ListView::isMouseEnabled()
00178 {
00179   return myMouseEnabled;
00180 }
00181 
00185 void SalomeApp_ListView::enableMouse(bool enable)
00186 {
00187   myMouseEnabled = enable;
00188 }
00189 
00193 bool SalomeApp_ListView::eventFilter(QObject* object, QEvent* event)
00194 {
00195   if (object == viewport() &&
00196        (event->type() == QEvent::MouseButtonPress   ||
00197         event->type() == QEvent::MouseButtonRelease ||
00198         event->type() == QEvent::MouseButtonDblClick)  &&
00199       !isMouseEnabled())
00200     return true;
00201   else
00202     return QTreeWidget::eventFilter(object, event);
00203 }
00204 
00208 void SalomeApp_ListView::enableEditing(bool theFlag)
00209 {
00210   myEditingEnabled = theFlag;
00211   if (!myEditingEnabled) {
00212     if (myEdit) {
00213       delete myEdit;
00214       myEdit = 0;
00215       myEditedItem = 0;
00216     }
00217   }
00218 }
00219 
00223 bool SalomeApp_ListView::isEnableEditing()
00224 {
00225   return myEditingEnabled;
00226 }
00227 
00231 void SalomeApp_ListView::accept()
00232 {
00233   finishEditing(true);
00234 }
00235 
00239 void SalomeApp_ListView::onSelectionChanged()
00240 {
00241   if (myEdit) {
00242     finishEditing(true);
00243     delete myEdit;
00244     myEdit = 0;
00245     if (myEditedItem && !myEditedItem->isAccepted()) {
00246       delete myEditedItem;
00247       update( contentsRect() );//updateContents();
00248     }
00249     myEditedItem = 0;
00250   }
00251   // editing is allowed in Single Selection Mode only
00252   if (selectionMode() != QAbstractItemView::SingleSelection || !isEnableEditing())
00253     return;
00254   SalomeApp_ListViewItem* anItem = (SalomeApp_ListViewItem*)(selectedItems().first());
00255   if (anItem) {
00256     if (!anItem->isEditable())
00257       return;
00258     myEdit = anItem->startEditing();
00259     if (myEdit) {
00260       connect(myEdit, SIGNAL(returnPressed()), this, SLOT(onEditOk()));
00261       connect(myEdit, SIGNAL(escapePressed()), this, SLOT(onEditCancel()));
00262       myEditedItem = anItem;
00263       myEdit->show();
00264       myEdit->setFocus();
00265     }
00266   }
00267 }
00268 
00272 void SalomeApp_ListView::resizeEvent( QResizeEvent * e)
00273 {
00274   QTreeWidget::resizeEvent(e);
00275   int aW = columnWidth(columnCount()-1);
00276   int aX = header()->sectionPosition(columnCount()-1);
00277   if (aW < width() - frameWidth() * 2 - aX - 1)
00278     setColumnWidth(columnCount()-1, width() - frameWidth() * 2 - aX - 1);
00279   update( contentsRect() );//updateContents();
00280 }
00281 
00285 void SalomeApp_ListView::onHeaderSizeChange(int, int, int)
00286 {
00287   int aW = columnWidth(columnCount()-1);
00288   int aX = header()->sectionPosition(columnCount()-1);
00289   if (aW < width() - frameWidth() * 2 - aX - 1)
00290     setColumnWidth(columnCount()-1, width() - frameWidth() * 2 - aX - 1);
00291 }
00292 
00296 void SalomeApp_ListView::viewportPaintEvent(QPaintEvent* e)
00297 {
00298   QTreeWidget::paintEvent(e);
00299   if (myEditedItem && myEdit) {
00300     computeEditGeometry(myEditedItem, myEdit);
00301   }
00302 }
00303 
00307 void SalomeApp_ListView::onEditOk()
00308 {
00309   finishEditing(true);
00310 }
00311 
00315 void SalomeApp_ListView::onEditCancel()
00316 {
00317   finishEditing(false);
00318 }
00319 
00323 UpdateType SalomeApp_ListView::finishEditing(bool ok)
00324 {
00325   UpdateType aNeedsUpdate = utCancel;
00326   if (myEditedItem && myEdit)
00327   {
00328     disconnect(myEdit, SIGNAL(returnPressed()), this, SLOT(onEditOk()));
00329     disconnect(myEdit, SIGNAL(escapePressed()), this, SLOT(onEditCancel()));
00330     myEditedItem->setAccepted(true);
00331     if (ok) {
00332       aNeedsUpdate = myEditedItem->finishEditing(myEdit);
00333       if (aNeedsUpdate == utCancel) {
00334         // something to do here on Cancel...
00335       }
00336       else {
00337         // something to do here on OK...
00338       }
00339       // updating contents
00340       switch (aNeedsUpdate) {
00341       case utUpdateItem:
00342         {
00343           if (myEditedItem)
00344             myEditedItem->updateAllLevels();
00345           break;
00346         }
00347       case utUpdateParent:
00348         {
00349           if (myEditedItem) {
00350             SalomeApp_ListViewItem* aParent = (SalomeApp_ListViewItem*)(myEditedItem->parent());
00351             if (aParent)
00352               aParent->updateAllLevels();
00353             else
00354               myEditedItem->updateAllLevels();
00355           }
00356           break;
00357         }
00358       case utUpdateViewer:
00359         {
00360           updateViewer();
00361           break;
00362         }
00363       case utUpdateAll:
00364         {
00365           // doing the same as for utUpdateViewer here
00366           // descendants can add extra processing
00367           updateViewer();
00368           break;
00369         }
00370       default:
00371         break;
00372       }
00373     }
00374   }
00375 
00376   // hide <myEdit> widget
00377   if (myEdit) {
00378     myEdit->hide();
00379   }
00380 
00381   return aNeedsUpdate;
00382 }
00383 
00388 QRect SalomeApp_ListView::tip(QPoint aPos,
00389                               QString& aText,
00390                               QRect& dspRect,
00391                               QFont& dspFnt) const
00392 {
00393   QRect result( -1, -1, -1, -1 );
00394   SalomeApp_ListViewItem* aItem = (SalomeApp_ListViewItem*)itemAt( aPos );
00395   if ( aItem ) {
00396     for (int i = 0; i < columnCount(); i++) {
00397       QRect aItemRect = aItem->itemRect(i);
00398       QRect aTextRect = aItem->textRect(i);
00399       if ( !aItem->text(i).isEmpty() &&
00400            ( aItemRect.width()  > header()->sectionSize(i) ||
00401              aTextRect.left()   < 0 ||
00402              aTextRect.top()    < 0 ||
00403              aTextRect.right()  > viewport()->width() ||
00404              aTextRect.bottom() > viewport()->height() ) ) {
00405         // calculating tip data
00406         aText   = aItem->tipText();
00407         dspRect = aItem->tipRect();
00408         dspFnt  = font();
00409         if (dspRect.isValid()) {
00410           result  = QRect(QPoint(0, aItemRect.top()),
00411                           QSize(viewport()->width(), aItemRect.height()));
00412         }
00413       }
00414     }
00415   }
00416   return result;
00417 }
00418 
00422 SalomeApp_ListViewItem::SalomeApp_ListViewItem(SalomeApp_ListView* parent) :
00423 QTreeWidgetItem( parent )
00424 {
00425   init();
00426 }
00427 
00431 SalomeApp_ListViewItem::SalomeApp_ListViewItem(SalomeApp_ListView*     parent,
00432                                                SalomeApp_ListViewItem* after) :
00433 QTreeWidgetItem( parent, after )
00434 {
00435   init();
00436 }
00437 
00441 SalomeApp_ListViewItem::SalomeApp_ListViewItem(SalomeApp_ListView*     parent,
00442                                                const QStringList&    theStrings,
00443                                                const bool        theEditable) :
00444 QTreeWidgetItem(parent, theStrings)
00445 {
00446   init();
00447   setEditable(theEditable);
00448 }
00449 
00453 SalomeApp_ListViewItem::SalomeApp_ListViewItem(SalomeApp_ListViewItem* parent,
00454                                                const QStringList&    theString,
00455                                                const bool        theEditable) :
00456 QTreeWidgetItem(parent, theString)
00457 {
00458   init();
00459   setEditable(theEditable);
00460 }
00461 
00465 SalomeApp_ListViewItem::SalomeApp_ListViewItem(SalomeApp_ListViewItem* parent,
00466                                                SalomeApp_ListViewItem* after,
00467                                                const QString&    theName,
00468                                                const bool        theEditable) :
00469 QTreeWidgetItem(parent, after)
00470 {
00471   setData(0,Qt::DisplayRole,QVariant(theName));
00472   init();
00473   setEditable(theEditable);
00474 }
00475 
00479 SalomeApp_ListViewItem::SalomeApp_ListViewItem(SalomeApp_ListView*     parent,
00480                                                SalomeApp_ListViewItem* after,
00481                                                const QString&    theName,
00482                                                const bool        theEditable) :
00483 QTreeWidgetItem(parent, after)
00484 {
00485   setData(0,Qt::DisplayRole,QVariant(theName));
00486   init();
00487   setEditable(theEditable);
00488 }
00489 
00493 SalomeApp_ListViewItem::SalomeApp_ListViewItem(SalomeApp_ListViewItem* parent,
00494                                                SalomeApp_ListViewItem* after,
00495                                                const QString&    theName,
00496                                                const QString&    theValue,
00497                                                const bool        theEditable) :
00498 QTreeWidgetItem(parent, after)
00499 {
00500   setData(0,Qt::DisplayRole,QVariant(theName));
00501   setData(1,Qt::DisplayRole,QVariant(theValue));
00502   init();
00503   setEditable(theEditable);
00504 }
00505 
00509 SalomeApp_ListViewItem::SalomeApp_ListViewItem(SalomeApp_ListView*     parent,
00510                                                SalomeApp_ListViewItem* after,
00511                                                const QString&    theName,
00512                                                const QString&    theValue,
00513                                                const bool        theEditable) :
00514 QTreeWidgetItem(parent, after)
00515 {
00516   setData(0,Qt::DisplayRole,QVariant(theName));
00517   setData(1,Qt::DisplayRole,QVariant(theValue));
00518   init();
00519   setEditable(theEditable);
00520 }
00521 
00525 SalomeApp_ListViewItem::~SalomeApp_ListViewItem()
00526 {
00527 }
00528 
00532 void SalomeApp_ListViewItem::init()
00533 {
00534   myEditable    = false;
00535   myAccepted    = true;
00536   myEditingType = (int)SalomeApp_EntityEdit::etLineEdit;
00537   myValueType   = (int)SalomeApp_EntityEdit::vtString;
00538   myButtons     = 0;
00539   myUserType    = -1;
00540 }
00541 
00545 int SalomeApp_ListViewItem::depth() const
00546 {
00547   int aDepth = 0;
00548   QTreeWidgetItem* aParent = parent();
00549   while ( aParent ) {
00550     aParent = aParent->parent();
00551     aDepth++;
00552   }
00553   return aDepth;
00554 }
00555 
00559 QString SalomeApp_ListViewItem::getName() const
00560 {
00561   return ( treeWidget()->columnCount() > 0 ) ? text(0) : QString("");
00562 }
00563 
00567 UpdateType SalomeApp_ListViewItem::setName(const QString& theName)
00568 {
00569   UpdateType aNeedsUpdate = utCancel;
00570   if (treeWidget()->columnCount() > 0) {
00571     setText(0, theName);
00572     aNeedsUpdate = utNone;
00573   }
00574   return aNeedsUpdate;
00575 }
00576 
00580 QString SalomeApp_ListViewItem::getValue() const
00581 {
00582   return ( treeWidget()->columnCount() > 1 ) ? text(1) : QString("");
00583 }
00584 
00588 UpdateType SalomeApp_ListViewItem::setValue(const QString& theValue)
00589 {
00590   UpdateType aNeedsUpdate = utCancel;
00591   if (treeWidget()->columnCount() > 1) {
00592     setText(1, theValue);
00593     aNeedsUpdate = utNone;
00594   }
00595   return aNeedsUpdate;
00596 }
00597 
00601 QString SalomeApp_ListViewItem::fullName()
00602 {
00603   QString aFullName = getName();
00604   SalomeApp_ListViewItem* aParent = (SalomeApp_ListViewItem*)parent();
00605   while(aParent != NULL) {
00606     aFullName = aParent->getName() + QString(".") + aFullName;
00607     aParent = (SalomeApp_ListViewItem*)(aParent->parent());
00608   }
00609   return aFullName;
00610 }
00611 
00615 void SalomeApp_ListViewItem::openAllLevels()
00616 {
00617   setExpanded(true);
00618   QTreeWidgetItemIterator it( this );
00619   SalomeApp_ListViewItem* aChild = (SalomeApp_ListViewItem*)(*it);
00620   while( aChild ) {
00621     aChild->openAllLevels();
00622     ++it;
00623     aChild = (SalomeApp_ListViewItem*)(*it);
00624   }
00625 }
00626 
00630 void SalomeApp_ListViewItem::updateAllLevels()
00631 {
00632   QTreeWidgetItemIterator it( this );
00633   SalomeApp_ListViewItem* aChild = (SalomeApp_ListViewItem*)(*it);
00634   while( aChild ) {
00635     aChild->updateAllLevels();
00636     ++it;
00637     aChild = (SalomeApp_ListViewItem*)(*it);
00638   }
00639 }
00640 
00644 bool SalomeApp_ListViewItem::isEditable() const
00645 {
00646   return myEditable;
00647 }
00648 
00652 void SalomeApp_ListViewItem::setEditable(bool theEditable)
00653 {
00654   myEditable = theEditable;
00655 }
00656 
00660 bool SalomeApp_ListViewItem::isAccepted() const
00661 {
00662   return myAccepted;
00663 }
00664 
00668 void SalomeApp_ListViewItem::setAccepted(bool theAccepted)
00669 {
00670   myAccepted = theAccepted;
00671 }
00672 
00679 int SalomeApp_ListViewItem::getEditingType()
00680 {
00681   return myEditingType;
00682 }
00683 
00690 void SalomeApp_ListViewItem::setEditingType(const int type)
00691 {
00692   myEditingType = type;
00693 }
00694 
00698 int SalomeApp_ListViewItem::getEditedColumn()
00699 {
00700   return treeWidget()->columnCount()-1;
00701 }
00702 
00707 int SalomeApp_ListViewItem::getValueType()
00708 {
00709   return myValueType;
00710 }
00711 
00715 void SalomeApp_ListViewItem::setValueType(const int valueType)
00716 {
00717   myValueType = valueType;
00718 }
00719 
00723 int SalomeApp_ListViewItem::getUserType()
00724 {
00725   return myUserType;
00726 }
00727 
00731 void SalomeApp_ListViewItem::setUserType(const int userType)
00732 {
00733   myUserType = userType;
00734 }
00735 
00740 int SalomeApp_ListViewItem::getButtons()
00741 {
00742   return myButtons;
00743 }
00744 
00748 void SalomeApp_ListViewItem::setButtons(const int buttons)
00749 {
00750   myButtons = buttons;
00751 }
00752 
00756 SalomeApp_EntityEdit* SalomeApp_ListViewItem::startEditing()
00757 {
00758   SalomeApp_EntityEdit* aWidget = 0;
00759   QTreeWidget* aListView = treeWidget();
00760   if (aListView) {
00761     if (!isEditable())
00762       return 0;
00763     int anEditType   = getEditingType();
00764     int aValueType   = getValueType();
00765     int aButtons     = getButtons();
00766     int anEditColumn = getEditedColumn();
00767     if (anEditColumn < 0 || anEditType < 0)
00768       return 0;
00769     aWidget = new SalomeApp_EntityEdit(aListView->viewport(),
00770                                  anEditType,
00771                                  aValueType,
00772                                  aButtons & SalomeApp_EntityEdit::btApply,
00773                                  aButtons & SalomeApp_EntityEdit::btCancel);
00774     computeEditGeometry(this, aWidget);
00775 
00776     fillWidgetWithValues(aWidget);
00777   }
00778   return aWidget;
00779 }
00780 
00784 void SalomeApp_ListViewItem::fillWidgetWithValues(SalomeApp_EntityEdit* theWidget)
00785 {
00786   int anEditColumn = getEditedColumn();
00787   if (theWidget && anEditColumn >= 0 && !text(anEditColumn).isEmpty())
00788     theWidget->insertItem(text(anEditColumn), true);
00789 }
00790 
00794 UpdateType SalomeApp_ListViewItem::finishEditing(SalomeApp_EntityEdit* theWidget)
00795 {
00796   UpdateType aNeedsUpdate = utCancel;
00797   try {
00798     if (theWidget) {
00799       int anEditColumn = getEditedColumn();
00800       switch (anEditColumn) {
00801       case 0:
00802         aNeedsUpdate = setName(theWidget->getText());
00803         break;
00804       case 1:
00805         aNeedsUpdate = setValue(theWidget->getText());
00806         break;
00807       default:
00808         break;
00809       }
00810     }
00811   }
00812   catch (...) {
00813     MESSAGE( "System error has been caught - SalomeApp_ListViewItem::finishEditing" )
00814   }
00815   return aNeedsUpdate;
00816 }
00817 
00821 QRect SalomeApp_ListViewItem::tipRect()
00822 {
00823   QRect aRect = QRect(-1, -1, -1, -1);
00824   QRect aItemRect = treeWidget()->visualItemRect(this);
00825   if ( !aItemRect.isValid() )
00826     return aItemRect;
00827 
00828   QString aTip = tipText();
00829   if (!aTip.isEmpty()) {
00830     QRect aRect0 = textRect(0);
00831     QFont aFont(treeWidget()->font());
00832     QFontMetrics fm(aFont);
00833     int iw = fm.width(aTip);
00834     aRect = QRect(QPoint(aRect0.x() < 0 ? 0 : aRect0.x(),
00835                          aRect0.y()),
00836                   QSize (iw,
00837                          aRect0.height()));
00838   }
00839   return aRect;
00840 }
00841 
00845 QString SalomeApp_ListViewItem::tipText()
00846 {
00847   QString aText = getName();
00848   if (!getValue().isEmpty())
00849     aText += QString(" : ") + getValue();
00850   return aText;
00851 }
00852 
00856 QRect SalomeApp_ListViewItem::textRect(const int column) const
00857 {
00858   QRect aItemRect = treeWidget()->visualItemRect( this );
00859   if ( !aItemRect.isValid() )
00860     return aItemRect;
00861 
00862   QFont aFont(treeWidget()->font());
00863   QFontMetrics fm(aFont);
00864 
00865   int decorWidth  = ( treeWidget()->rootIsDecorated() ) ?
00866                     ( treeWidget()->indentation() * (depth() + 1) ) :
00867                     ( treeWidget()->indentation() *  depth() );
00868   int pixmapWidth = ( !icon(column).isNull() ) ?
00869                       treeWidget()->iconSize().width() + 2 :
00870                       1;
00871   int prevWidth = 0;
00872   for (int i = 0; i < column; i++)
00873     prevWidth += treeWidget()->header()->sectionSize(i);
00874   int ix = prevWidth   +
00875            pixmapWidth +
00876            ((column == 0) ? decorWidth : 0);
00877   int iy = aItemRect.y();
00878   int iw = fm.width(text(column));
00879   int ih = aItemRect.height();
00880   if (!icon(column).isNull()) {
00881     iy += 1;
00882     ih -= 2;
00883   }
00884   ix -= treeWidget()->contentsRect().left();
00885 
00886   QRect theResult(QPoint(ix, iy), QSize(iw, ih));
00887   return theResult;
00888 }
00889 
00893 QRect SalomeApp_ListViewItem::itemRect(const int column) const
00894 {
00895   QRect aItemRect = treeWidget()->visualItemRect( this );
00896   if ( !aItemRect.isValid() )
00897     return aItemRect;
00898 
00899   QFont aFont(treeWidget()->font());
00900   QFontMetrics fm(aFont);
00901 
00902   int decorWidth  = ( treeWidget()->rootIsDecorated() ) ?
00903                     ( treeWidget()->indentation() * (depth() + 1) ) :
00904                     ( treeWidget()->indentation() *  depth() );
00905   int pixmapWidth = ( !icon(column).isNull() ) ?
00906                       treeWidget()->iconSize().width() + 2 :
00907                       0;
00908   int prevWidth = 0;
00909   for (int i = 0; i < column; i++)
00910     prevWidth += treeWidget()->header()->sectionSize(i);
00911   int ix = prevWidth;
00912   int iy = aItemRect.y();
00913   int iw = pixmapWidth +
00914            2 +
00915            ((column == 0) ? decorWidth : 0) +
00916            fm.width(text(column));
00917   int ih = aItemRect.height();
00918   ix -= treeWidget()->contentsRect().left();
00919 
00920   QRect theResult(QPoint(ix, iy), QSize(iw, ih));
00921   return theResult;
00922 }
00923 
00927 SalomeApp_EditBox::SalomeApp_EditBox(QWidget* parent) :
00928 QLineEdit(parent)
00929 {
00930 }
00931 
00935 void SalomeApp_EditBox::keyPressEvent( QKeyEvent *e )
00936 {
00937   if ( e->key() == Qt::Key_Escape )
00938     emit escapePressed();
00939   else
00940     QLineEdit::keyPressEvent( e );
00941   e->accept();
00942 }
00943 
00944 
00948 SalomeApp_ComboBox::SalomeApp_ComboBox(bool rw, QWidget* parent, const char* name) :
00949 QComboBox(parent)
00950 {
00951   setEditable( rw );
00952   setObjectName( name );
00953 }
00954 
00958 int SalomeApp_ComboBox::findItem(const QString& theText)
00959 {
00960   for (int i = 0; i < count(); i++)
00961     if (itemText(i) == theText)
00962       return i;
00963   return -1;
00964 }
00965 
00969 void SalomeApp_ComboBox::insertItem(const QString& theValue,
00970                                     int            theIndex)
00971 {
00972   if (duplicatesEnabled() || findItem(theValue) < 0)
00973     QComboBox::insertItem(theIndex, theValue);
00974 }
00975 
00979 void SalomeApp_ComboBox::insertList(const QStringList& theList)
00980 {
00981   for (unsigned i = 0; i < theList.count(); i++)
00982     insertItem(theList[i]);
00983 }
00984 
00988 void SalomeApp_ComboBox::insertItem(const int theValue)
00989 {
00990   int aNum;
00991   bool bOk;
00992   for (int i = 0; i < count(); i++) {
00993     aNum = itemText(i).toInt(&bOk);
00994     if (bOk) {
00995       if (aNum > theValue || (aNum == theValue && duplicatesEnabled())) {
00996         insertItem(QString::number(theValue),i);
00997         return;
00998       }
00999     }
01000   }
01001   insertItem(QString::number(theValue));
01002 }
01003 
01007 void SalomeApp_ComboBox::insertList(const TColStd_ListOfInteger& theList)
01008 {
01009   for (TColStd_ListIteratorOfListOfInteger aIter(theList); aIter.More(); aIter.Next())
01010     insertItem(aIter.Value());
01011 }
01012 
01016 void SalomeApp_ComboBox::insertItem(const double theValue)
01017 {
01018   double aNum;
01019   bool bOk;
01020   for (int i = 0; i < count(); i++) {
01021     aNum = itemText(i).toDouble(&bOk);
01022     if (bOk) {
01023       if (aNum > theValue || (aNum == theValue && duplicatesEnabled())) {
01024         insertItem(QString::number(theValue), i);
01025         return;
01026       }
01027     }
01028   }
01029   insertItem(QString::number(theValue));
01030 }
01031 
01035 void SalomeApp_ComboBox::insertList(const TColStd_ListOfReal& theList)
01036 {
01037   for (TColStd_ListIteratorOfListOfReal aIter(theList); aIter.More(); aIter.Next())
01038     insertItem(aIter.Value());
01039 }
01040 
01041 #include <qlayout.h>
01042 
01043 #define MIN_COMBO_WIDTH     1
01044 #define MIN_EDIT_WIDTH      1
01045 
01049 SalomeApp_EntityEdit::SalomeApp_EntityEdit(QWidget* parent,
01050                                int      controlType,
01051                                int      valueType,
01052                                bool     butApply,
01053                                bool     butCancel) :
01054 QWidget(parent),
01055 myEdit(0),
01056 myCombo(0),
01057 myApplyBtn(0),
01058 myCancelBtn(0)
01059 {
01060   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
01061   SUIT_ResourceMgr* mgr = app ? app->resourceMgr() : NULL;
01062 
01063   QHBoxLayout* aTopLayout = new QHBoxLayout(this);
01064   aTopLayout->setAlignment( Qt::AlignTop );
01065   aTopLayout->setSpacing( 0 );
01066   aTopLayout->setMargin( 1 );
01067   if (controlType != etLineEdit &&
01068       controlType != etComboBox &&
01069       controlType != etComboEdit)
01070     controlType = etLineEdit;
01071   if (controlType == etComboBox || controlType == etComboEdit) {
01072     // this is an editable combo box
01073     myCombo = new SalomeApp_ComboBox(controlType == etComboEdit, this);
01074     myCombo->setMinimumSize(MIN_COMBO_WIDTH, 0);
01075     myCombo->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,
01076                                        QSizePolicy::Fixed));
01077     // no insertions
01078     myCombo->setInsertPolicy(QComboBox::NoInsert);
01079     // no duplicates enabled by default
01080     myCombo->setDuplicatesEnabled(false);
01081     aTopLayout->addWidget(myCombo);
01082     // connect signals
01083     connect(myCombo, SIGNAL(activated(const QString&)), this, SLOT(onComboActivated(const QString&)));
01084     connect(myCombo, SIGNAL(textChanged(const QString&)), this, SLOT(onTextChanged(const QString&)));
01085   }
01086   else {
01087     // and this is an edit box
01088     myEdit = new SalomeApp_EditBox(this);
01089     myEdit->setMinimumSize(MIN_EDIT_WIDTH, 0);
01090     myEdit->setSizePolicy(QSizePolicy(QSizePolicy::Expanding,
01091                                       QSizePolicy::Fixed));
01092     aTopLayout->addWidget(myEdit);
01093     connect(myEdit, SIGNAL(textChanged(const QString&)), this, SLOT(onTextChanged(const QString&)));
01094     connect(myEdit, SIGNAL(returnPressed()), this, SLOT(onApply()));
01095     connect(myEdit, SIGNAL(escapePressed()), this, SLOT(onCancel()));
01096   }
01097   if (valueType != vtString &&
01098       valueType != vtInteger &&
01099       valueType != vtDouble)
01100     valueType = vtString;
01101   if (valueType == vtInteger)
01102     setValidator(new QIntValidator(this));
01103   else if (valueType == vtDouble)
01104     setValidator(new QDoubleValidator(this));
01105   if (butApply) {
01106     // Apply button (V)
01107     myApplyBtn = new QToolButton(this);
01108 
01109     QPixmap anIcon;
01110     if( mgr )
01111       anIcon = mgr->loadPixmap( "SalomeApp", tr( "ICON_APPLY" ), false );
01112 
01113     myApplyBtn->setIcon(anIcon);
01114     myApplyBtn->setEnabled(false);
01115     myApplyBtn->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
01116     myApplyBtn->setMinimumSize(16, 16);
01117     myApplyBtn->setMaximumSize(16, 20);
01118     aTopLayout->addWidget(myApplyBtn);
01119     connect(myApplyBtn, SIGNAL(clicked()), this, SLOT(onApply()));
01120   }
01121   if (butCancel) {
01122     // Cancel button (X)
01123     myCancelBtn = new QToolButton(this);
01124     QPixmap anIcon;
01125     if( mgr )
01126       anIcon = mgr->loadPixmap( "SalomeApp", tr( "ICON_CANCEL" ), false );
01127     myCancelBtn->setIcon(anIcon);
01128     myCancelBtn->setEnabled(false);
01129     myCancelBtn->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
01130     myCancelBtn->setMinimumSize(16, 16);
01131     myCancelBtn->setMaximumSize(16, 20);
01132     aTopLayout->addWidget(myCancelBtn);
01133     connect(myCancelBtn, SIGNAL(clicked()), this, SLOT(onCancel()));
01134   }
01135 }
01136 
01140 SalomeApp_EntityEdit::~SalomeApp_EntityEdit()
01141 {
01142 }
01143 
01147 void SalomeApp_EntityEdit::clear()
01148 {
01149   if (myEdit)
01150     myEdit->clear();
01151   if (myCombo)
01152     myCombo->clear();
01153 }
01154 
01158 QString SalomeApp_EntityEdit::getText()
01159 {
01160   if (myEdit)
01161     return myEdit->text();
01162   else if (myCombo)
01163     return myCombo->currentText();
01164   else
01165     return "";
01166 }
01167 
01171 void SalomeApp_EntityEdit::setText(const QString& theText)
01172 {
01173   myString = theText;
01174   if (myEdit)
01175     myEdit->setText(theText);
01176   if (myCombo) {
01177     int aFound = myCombo->findItem(theText);
01178     if (aFound >= 0) {
01179       myCombo->setCurrentIndex(aFound);
01180       onTextChanged(theText);
01181     }
01182   }
01183 }
01184 
01188 void SalomeApp_EntityEdit::insertItem(const QString& theValue,
01189                                 bool           theSetCurrent,
01190                                 int            theOrder)
01191 {
01192   if (myCombo) {
01193     int aIndexAt = -1;
01194     if (theOrder == atTop)
01195       aIndexAt = 0;
01196     else if (theOrder == atBeforeCurrent && myCombo->count() > 0)
01197       aIndexAt = myCombo->currentIndex();
01198     else if (theOrder == atAfterCurrent &&
01199              myCombo->count() > 0 &&
01200              myCombo->currentIndex() < myCombo->count()-1)
01201       aIndexAt = myCombo->currentIndex() + 1;
01202     myCombo->insertItem(theValue, aIndexAt);
01203   }
01204   if (theSetCurrent)
01205     setText(theValue);
01206 }
01207 
01211 void SalomeApp_EntityEdit::insertList(const QStringList& theList,
01212                                 const int          theCurrent)
01213 {
01214   if (myCombo)
01215     myCombo->insertList(theList);
01216   if (theCurrent >= 0 && theCurrent < (int)theList.count())
01217     setText(theList[theCurrent]);
01218 }
01219 
01223 void SalomeApp_EntityEdit::insertItem(const int theValue,
01224                                 bool      theSetCurrent)
01225 {
01226   if (myCombo) {
01227     myCombo->insertItem(theValue);
01228   }
01229   if (theSetCurrent)
01230     setText(QString::number(theValue));
01231 }
01232 
01236 void SalomeApp_EntityEdit::insertList(const TColStd_ListOfInteger& theList,
01237                                 const int                    theCurrent)
01238 {
01239   if (myCombo)
01240     myCombo->insertList(theList);
01241 
01242   TColStd_ListIteratorOfListOfInteger aIter(theList);
01243   for (unsigned i = 0; aIter.More(); aIter.Next(), i++) {
01244     if (theCurrent == i) {
01245       setText(QString::number(aIter.Value()));
01246       break;
01247     }
01248   }
01249 }
01250 
01254 void SalomeApp_EntityEdit::insertItem(const double theValue,
01255                                 bool         theSetCurrent)
01256 {
01257   if (myCombo) {
01258     myCombo->insertItem(theValue);
01259   }
01260   if (theSetCurrent)
01261     setText(QString::number(theValue));
01262 }
01263 
01267 void SalomeApp_EntityEdit::insertList(const TColStd_ListOfReal& theList,
01268                                 const int                 theCurrent)
01269 {
01270   if (myCombo)
01271     myCombo->insertList(theList);
01272 
01273   TColStd_ListIteratorOfListOfReal aIter(theList);
01274   for (unsigned i = 0; aIter.More(); aIter.Next(), i++) {
01275     if (theCurrent == i) {
01276       setText(QString::number(aIter.Value()));
01277       break;
01278     }
01279   }
01280 }
01281 
01285 QWidget* SalomeApp_EntityEdit::getControl()
01286 {
01287   if (myEdit)
01288     return myEdit;
01289   else if (myCombo)
01290     return myCombo;
01291   else
01292     return 0;
01293 }
01294 
01298 void SalomeApp_EntityEdit::setFocus()
01299 {
01300   if (myEdit) {
01301     myEdit->setFocus();
01302     //myEdit->selectAll();
01303   }
01304   else if (myCombo && myCombo->isEditable()) {
01305     myCombo->setFocus();
01306     //myCombo->lineEdit()->selectAll();
01307   }
01308 }
01309 
01313 void SalomeApp_EntityEdit::setValidator(const QValidator* theValidator)
01314 {
01315   if (myEdit)
01316     myEdit->setValidator(theValidator);
01317   if (myCombo)
01318     myCombo->setValidator(theValidator);
01319 }
01320 
01324 void SalomeApp_EntityEdit::keyPressEvent( QKeyEvent * e)
01325 {
01326   if ( (e->key() == Qt::Key_Enter ||
01327         e->key() == Qt::Key_Return ) )
01328     onApply();
01329   else if (e->key() == Qt::Key_Escape)
01330     onCancel();
01331 }
01332 
01336 void SalomeApp_EntityEdit::onComboActivated(const QString& theText)
01337 {
01338   onTextChanged(theText);
01339 }
01340 
01344 void SalomeApp_EntityEdit::onTextChanged(const QString& theText)
01345 {
01346   if (myApplyBtn)
01347     myApplyBtn->setEnabled(!(theText == myString));
01348   if (myCancelBtn)
01349     myCancelBtn->setEnabled(!(theText == myString));
01350 }
01351 
01355 void SalomeApp_EntityEdit::onCancel()
01356 {
01357   setText(myString);
01358   if (myApplyBtn)
01359     myApplyBtn->setEnabled(false);
01360   if (myCancelBtn)
01361     myCancelBtn->setEnabled(false);
01362   emit escapePressed();
01363 }
01364 
01368 void SalomeApp_EntityEdit::onApply()
01369 {
01370   myString = getText();
01371   if (myApplyBtn)
01372     myApplyBtn->setEnabled(false);
01373   if (myCancelBtn)
01374     myCancelBtn->setEnabled(false);
01375   emit returnPressed();
01376 }
01377 
01381 void SalomeApp_EntityEdit::showButtons(bool show)
01382 {
01383   if (myApplyBtn)
01384     show ? myApplyBtn->show()  : myApplyBtn->hide();
01385   if (myCancelBtn)
01386     show ? myCancelBtn->show() : myCancelBtn->hide();
01387 }
01388 
01392 void SalomeApp_EntityEdit::setDuplicatesEnabled(bool enabled)
01393 {
01394   if (myCombo)
01395     myCombo->setDuplicatesEnabled(enabled);
01396 }