Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/gui.git] / src / ObjBrowser / OB_ListView.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either 
6 // version 2.1 of the License.
7 // 
8 // This library 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 GNU 
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public  
14 // License along with this library; if not, write to the Free Software 
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #include "OB_ListView.h"
20
21 #include "OB_Filter.h"
22 #include "OB_ListItem.h"
23
24 #include <SUIT_DataObject.h>
25
26 #include <qdragobject.h>
27
28 /*!
29   Constructor
30 */
31 OB_ListView::OB_ListView( QWidget* parent, const char* name, WFlags f )
32 : QtxListView( parent, name, f ),
33 myFilter( 0 )
34 {
35 }
36
37 /*!
38   Constructor
39 */
40 OB_ListView::OB_ListView( const int state, QWidget* parent, const char* name, WFlags f )
41 : QtxListView( state, parent, name, f ),
42 myFilter( 0 )
43 {
44 }
45
46 /*!
47   Destructor
48 */
49 OB_ListView::~OB_ListView()
50 {
51   delete myFilter;
52 }
53
54 /*!
55   \return filter
56 */
57 OB_Filter* OB_ListView::filter() const
58 {
59   return myFilter;
60 }
61
62 /*!
63   Changes filter
64   \param f - new filter
65 */
66 void OB_ListView::setFilter( OB_Filter* f )
67 {
68   if ( myFilter == f )
69     return;
70
71   delete myFilter;
72   myFilter = f;
73 }
74
75 /*!
76   \return true if item passes filter
77 */
78 bool OB_ListView::isOk( QListViewItem* item ) const
79 {
80   bool ok = true;
81   SUIT_DataObject* obj = dataObject( item );
82   if ( obj && filter() )
83     ok = filter()->isOk( obj );
84   return ok;
85 }
86
87 /*!
88   Creates new drag object
89 */
90 QDragObject* OB_ListView::dragObject()
91 {
92   myItems.clear();
93
94   for ( QListViewItemIterator it( this ); it.current(); ++it )
95     if ( it.current()->isSelected() )
96       myItems.append( it.current() );
97
98   return new QTextDrag( "", this );
99 }
100
101 /*!
102   Custom drag enter event filter
103 */
104 void OB_ListView::dragEnterEvent( QDragEnterEvent* e )
105 {
106   e->accept();
107 }
108
109 /*!
110   Custom drag move event filter
111 */
112 void OB_ListView::dragMoveEvent( QDragMoveEvent* e )
113 {
114   QListViewItem* item = dropItem( e );
115
116   if ( isDropAccepted( item ) )
117   {
118     setCurrentItem( item );
119     e->accept( true );
120   }
121   else
122     e->accept( false );
123 }
124
125 /*!
126   Custom drop event filter
127 */
128 void OB_ListView::dropEvent( QDropEvent* e )
129 {
130   QListViewItem* item = dropItem( e );
131   if ( isDropAccepted( item ) )
132   {
133     e->accept();
134     emit dropped( myItems, item, e->action() );
135   }
136   myItems.clear();
137 }
138
139 /*!
140   Custom key press event filter
141 */
142 void OB_ListView::keyPressEvent( QKeyEvent* ke )
143 {
144   if ( ( ke->key() == Qt::Key_Plus || ke->key() == Qt::Key_Minus ) && ke->state() & ControlButton )
145   {
146     bool isOpen = ke->key() == Qt::Key_Plus;
147     for ( QListViewItemIterator it( this ); it.current(); ++it )
148       if ( it.current()->childCount() )
149         it.current()->setOpen( isOpen );
150   }
151   else
152     QtxListView::keyPressEvent( ke );
153 }
154
155 /*!
156   Finds item, in that dragged objects are dropped by QDropEvent
157   \return tree item
158 */
159 QListViewItem* OB_ListView::dropItem( QDropEvent* e ) const
160 {
161   QListViewItem* item = 0;
162   if ( e )
163     item = itemAt( QPoint( e->pos().x() - viewport()->x(), e->pos().y() - viewport()->y() ) );
164
165   return item;
166 }
167
168 /*!
169   \return SUIT object by tree item
170   \param item - tree item
171 */
172 SUIT_DataObject* OB_ListView::dataObject( QListViewItem* item ) const
173 {
174   if ( !item )
175     return 0;
176
177   SUIT_DataObject* obj = 0;
178
179   if ( dynamic_cast<OB_ListItem*>( item ) )
180     obj = dynamic_cast<OB_ListItem*>( item )->dataObject();
181   else if ( dynamic_cast<OB_CheckListItem*>( item ) )
182     obj = dynamic_cast<OB_CheckListItem*>( item )->dataObject();
183
184   return obj;
185 }
186
187 /*!
188   \return true if it is possible to drop into item
189   \param item - tree item to be checked
190 */
191 bool OB_ListView::isDropAccepted( QListViewItem* item ) const
192 {
193   bool res = true;
194
195   for ( QPtrListIterator<QListViewItem> it( myItems ); it.current() && res; ++it )
196     res = res && isDropAccepted( it.current(), item );
197
198   return res;
199 }
200
201 /*!
202   \return true if it is possible to drop one item into other
203   \param drag - dragged item
204   \param drop - destination item
205 */
206 bool OB_ListView::isDropAccepted( QListViewItem* drag, QListViewItem* drop ) const
207 {
208   SUIT_DataObject* dragObj = dataObject( drag );
209   SUIT_DataObject* dropObj = dataObject( drop );
210
211   if ( !dragObj || !dropObj )
212     return false;
213
214   return dropObj->isDropAccepted( dragObj );
215 }
216
217 /*!
218   Sets column width
219   \param col - column index
220   \param width - column width
221 */ 
222 void OB_ListView::setColumnWidth( int col, int width )
223 {
224   int max = columnMaxWidth( col );
225   if ( max>0 && width>max )
226     width = max;
227
228   QtxListView::setColumnWidth( col, width );
229 }
230
231 /*!
232   \return column max width
233   \param col - column index
234 */ 
235 int OB_ListView::columnMaxWidth( const int col ) const
236 {
237   int res = -1;
238   if( myMaxColWidth.contains( col ) )
239     res = myMaxColWidth[col];
240   else if( myMaxColRatio.contains( col ) )
241     res = int( myMaxColRatio[col]*height() );
242   return res;
243 }
244
245 /*!
246   Changes column max width
247   \param col - column index
248   \param w - column max width
249 */ 
250 void OB_ListView::setColumnMaxWidth( const int col, const int w )
251 {
252   myMaxColWidth.insert( col, w );
253 }
254
255 /*!
256   \return column max ratio
257   \param col - column index
258 */ 
259 double OB_ListView::columnMaxRatio( const int col ) const
260 {
261   double res = 0.0;
262   if( myMaxColRatio.contains( col ) )
263     res = myMaxColRatio[col];
264   return res;
265 }
266
267 /*!
268   Changes column max ratio
269   \param col - column index
270   \param w - column max ratio
271 */ 
272 void OB_ListView::setColumnMaxRatio( const int col, const double r )
273 {
274   myMaxColRatio.insert( col, r );
275 }