Salome HOME
Merge remote branch 'origin/V7_dev' into V8_0_0_BR
[modules/gui.git] / src / OCCViewer / OCCViewer_CreateRestoreViewDlg.cxx
1 // Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "OCCViewer_CreateRestoreViewDlg.h"
24 #include "OCCViewer_ViewPort3d.h"
25
26 #include <QPushButton>
27 #include <QGridLayout>
28 #include <QHBoxLayout>
29 #include <QListWidgetItem>
30 #include <QEvent>
31 #include <QKeyEvent>
32
33 /*!
34   Constructor
35 */
36 OCCViewer_CreateRestoreViewDlg::OCCViewer_CreateRestoreViewDlg( QWidget* aWin, OCCViewer_ViewWindow* theViewWindow )
37 : QDialog( aWin )
38 {
39   setWindowTitle( tr( "CAPTION" ) );
40
41   myParametersMap = theViewWindow->getViewAspects();
42
43   myKeyFlag = 0;
44
45   int aQuantityOfItems = myParametersMap.count();
46         
47   setFixedSize( 400, 300 );
48
49   QGridLayout* aGrid = new QGridLayout( this );
50   aGrid->setMargin( 5 );
51   aGrid->setSpacing( 10 );
52
53   QWidget* aWidget1 = new QWidget( this );
54   QWidget* aWidget2 = new QWidget( this );
55         
56   QHBoxLayout* aLayout = new QHBoxLayout( aWidget1 );
57         
58   myListBox = new QListWidget( aWidget1 );
59   myListBox->installEventFilter( this );
60
61   myCurViewPort = new OCCViewer_ViewPort3d( aWidget1, theViewWindow->getViewPort()->getViewer(), V3d_ORTHOGRAPHIC );
62   myCurViewPort->getView()->SetBackgroundColor( Quantity_NOC_BLACK );
63
64   myListBox->setEditTriggers( QAbstractItemView::DoubleClicked );
65         
66   if ( aQuantityOfItems )
67   {
68     myListBox->clear();
69     for( int i = 0; i < aQuantityOfItems; i++ ) {
70       myListBox->insertItem( i, myParametersMap[ i ].name );
71       myListBox->item( i )->setFlags( myListBox->item( i )->flags() | Qt::ItemIsEditable );
72     }
73     
74     changeImage( myListBox->item( 0 ) );
75   }
76   else
77   {
78     myListBox->clear();
79     myListBox->insertItem( 0, "No Items" );
80   }
81
82   connect( myListBox, SIGNAL( itemClicked( QListWidgetItem* ) ), this, SLOT( changeImage( QListWidgetItem* ) ) );
83   connect( myListBox, SIGNAL( itemChanged( QListWidgetItem* ) ), this, SLOT( editItemText( QListWidgetItem* ) ) );
84         
85   aLayout->addWidget( myListBox );
86   aLayout->addWidget( myCurViewPort, 30 );
87
88   QHBoxLayout* aButtonLayout = new QHBoxLayout( aWidget2 );
89   aButtonLayout->setMargin( 0 );
90   aButtonLayout->setSpacing( 5 );
91
92   QPushButton* theOk     = new QPushButton( tr( "Ok" ), aWidget2 );            theOk->setAutoDefault( false );
93   QPushButton* theCancel = new QPushButton( tr( "Cancel" ), aWidget2 );          theCancel->setAutoDefault( false );
94   QPushButton* theDelete = new QPushButton( tr( "Delete" ), aWidget2 );          theDelete->setAutoDefault( false );
95   QPushButton* theClearAll = new QPushButton( tr( "Clear List" ), aWidget2 );  theClearAll->setAutoDefault( false );
96
97   aButtonLayout->addWidget( theOk );
98   aButtonLayout->addWidget( theCancel );
99   aButtonLayout->addWidget( theDelete );
100   aButtonLayout->addWidget( theClearAll );
101
102   aGrid->addWidget( aWidget1, 0, 0 );
103   aGrid->addWidget( aWidget2, 1, 0 );
104         
105   connect( theOk, SIGNAL( clicked() ), this, SLOT( OKpressed() ) );
106   connect( theCancel, SIGNAL( clicked() ), this, SLOT( reject() ) );
107   connect( theDelete, SIGNAL( clicked() ), this, SLOT( deleteSelectedItems() ) );
108   connect( theClearAll, SIGNAL( clicked() ), this, SLOT( clearList() ) );
109 }
110
111 /*!
112   Destructor
113 */
114 OCCViewer_CreateRestoreViewDlg::~OCCViewer_CreateRestoreViewDlg()
115 {
116 }
117
118 /*!
119   Changes image in accordance with item
120   \param curItem - item contains info about view parameters
121 */
122 void OCCViewer_CreateRestoreViewDlg::changeImage( QListWidgetItem* curItem )
123 {
124   if( curItem && ( curItem->flags() & Qt::ItemIsEditable ) )
125   {
126     int lowLevel  = -1;
127     int highLevel = -1;
128     int index = curItem->listWidget()->row( curItem );
129     if( myKeyFlag == 2 )
130     {
131       for( int i = 0; i < (int)myListBox->count(); i++ )
132       {
133         if( myListBox->item( i )->isSelected() && i != index )
134         {
135           myListBox->clearSelection();
136           if( i > index )
137           {
138             lowLevel  = index;
139             highLevel = i;
140           }
141           else
142           {
143             lowLevel  = i;
144             highLevel = index;
145           }
146           for( int j = lowLevel; j <= highLevel; j++ )
147             myListBox->item( j )->setSelected( true );
148           break;
149         }
150         if( myListBox->item( i )->isSelected() && i == index )
151           myListBox->item( i )->setSelected( true );
152       }
153     }
154     
155     Handle(V3d_View) aView3d = myCurViewPort->getView();
156     myCurrentItem = myParametersMap[ index ];
157     
158     Standard_Boolean prev = aView3d->SetImmediateUpdate( Standard_False );
159     aView3d->SetScale( myCurrentItem.scale );
160 #if OCC_VERSION_LARGE <= 0x06070100
161     aView3d->SetCenter( myCurrentItem.centerX, myCurrentItem.centerY );
162 #endif
163     aView3d->SetProj( myCurrentItem.projX, myCurrentItem.projY, myCurrentItem.projZ );
164     aView3d->SetTwist( myCurrentItem.twist );
165     aView3d->SetAt( myCurrentItem.atX, myCurrentItem.atY, myCurrentItem.atZ );
166     aView3d->SetImmediateUpdate( prev );
167     aView3d->SetEye( myCurrentItem.eyeX, myCurrentItem.eyeY, myCurrentItem.eyeZ );
168     aView3d->SetAxialScale( myCurrentItem.scaleX, myCurrentItem.scaleY, myCurrentItem.scaleZ );
169   }
170 }
171
172 /*!
173   \return current view parameters (corresponding to current item)
174 */
175 viewAspect OCCViewer_CreateRestoreViewDlg::currentItem() const
176 {
177   return myCurrentItem;
178 }
179
180 /*!
181   Deletes selected items from list view
182 */
183 void OCCViewer_CreateRestoreViewDlg::deleteSelectedItems()
184 {
185   QList<QListWidgetItem*> selectedItems = myListBox->selectedItems();
186   if( myListBox->count() && selectedItems.count())
187   {
188     int curIndex = -1;
189     // Iterate by all selected items
190     for(int i = 0; i < selectedItems.count(); i++) 
191     {
192       QListWidgetItem* item =  selectedItems.at(i);
193       // get position of the selected item in the list
194       int position = myListBox->row(item);
195
196       //Calculate current index in case if "item" is last selected item.
197       if(i == selectedItems.count() - 1)
198       {
199         if(position != myListBox->count() - 1)
200           curIndex = position;
201         else 
202           curIndex = position - 1;
203       }
204
205       //Delete item
206       delete item;
207
208       //Shift parameters in the map
209       for( int j = position; j < (int)myParametersMap.count(); j++ )
210       {
211         if( j != myParametersMap.count() - 1 )
212           myParametersMap[ j ] = myParametersMap[ j + 1 ];
213         else
214           myParametersMap.removeAt( j );
215       }
216     }
217     if( curIndex >= 0 )
218     {
219       myListBox->setCurrentItem( myListBox->item( curIndex ) );
220       changeImage( myListBox->item( curIndex ) );
221     }
222   }
223   if( !myListBox->count() )
224   {
225     clearList();
226   }
227 }
228
229 /*!
230   Clears list of view aspects
231 */
232 void OCCViewer_CreateRestoreViewDlg::clearList()
233 {
234   myListBox->clear();
235   myListBox->insertItem( 0, "No Items" );
236   myParametersMap.clear();
237         
238   //Clear view
239   myCurViewPort->reset();
240 }
241
242 /*!
243   \return const reference to all view aspects
244 */
245 const viewAspectList& OCCViewer_CreateRestoreViewDlg::parameters() const
246 {
247   return myParametersMap;
248 }
249
250 /*!
251   Renames key of view aspect map in accordance with item name
252   \param anItem - item
253 */
254 void OCCViewer_CreateRestoreViewDlg::editItemText( QListWidgetItem* anItem )
255 {
256   int index = anItem->listWidget()->row( anItem );
257   myParametersMap[ index ].name = anItem->text().toLatin1();
258 }
259
260 /*!
261   Custom event filter
262 */
263 bool OCCViewer_CreateRestoreViewDlg::eventFilter( QObject* anObj, QEvent* anEv )
264 {
265   if( anEv->type() == QEvent::KeyPress )
266   {
267     QKeyEvent* aKeyEv = ( QKeyEvent* )anEv;
268     if( aKeyEv->key() == Qt::Key_Control )
269     {
270       myKeyFlag = 1;
271       myListBox->setSelectionMode( QAbstractItemView::MultiSelection ); 
272     }
273     else if( aKeyEv->key() == Qt::Key_Shift )
274     {
275       myKeyFlag = 2;
276       myListBox->setSelectionMode( QAbstractItemView::MultiSelection ); 
277     }
278     else
279       myListBox->setSelectionMode( QAbstractItemView::SingleSelection );
280   }
281   if( anEv->type() == QEvent::KeyRelease )
282     myKeyFlag = 0;
283   
284   if( !myKeyFlag )
285   {
286     if( anEv->type() == QEvent::KeyPress || anEv->type() == QEvent::MouseButtonPress )
287       myListBox->setSelectionMode( QAbstractItemView::SingleSelection );
288   }
289   return QWidget::eventFilter( anObj, anEv );
290 }
291
292 /*!
293   SLOT: called on OK click, emits dlgOk() and closes dialog
294 */
295 void OCCViewer_CreateRestoreViewDlg::OKpressed()
296 {
297   emit dlgOk();
298   accept();
299 }
300