~ubuntu-branches/debian/sid/kdevelop/sid

« back to all changes in this revision

Viewing changes to kdevdesigner/designer/listviewdnd.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jeremy Lainé
  • Date: 2010-05-05 07:21:55 UTC
  • mfrom: (1.2.3 upstream) (5.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100505072155-h78lx19pu04sbhtn
Tags: 4:4.0.0-2
* Upload to unstable (Closes: #579947, #481832).
* Acknowledge obsolete NMU fixes (Closes: #562410, #546961).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**********************************************************************
2
 
** Copyright (C) 2002 Trolltech AS.  All rights reserved.
3
 
**
4
 
** This file is part of Qt Designer.
5
 
**
6
 
** This file may be distributed and/or modified under the terms of the
7
 
** GNU General Public License version 2 as published by the Free Software
8
 
** Foundation and appearing in the file LICENSE.GPL included in the
9
 
** packaging of this file.
10
 
**
11
 
** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
12
 
** licenses may use this file in accordance with the Qt Commercial License
13
 
** Agreement provided with the Software.
14
 
**
15
 
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16
 
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17
 
**
18
 
** See http://www.trolltech.com/gpl/ for GPL licensing information.
19
 
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
20
 
**   information about Qt Commercial License Agreements.
21
 
**
22
 
** Contact info@trolltech.com if any conditions of this licensing are
23
 
** not clear to you.
24
 
**
25
 
**********************************************************************/
26
 
 
27
 
#include "listviewdnd.h"
28
 
#include <qwidget.h>
29
 
#include <qheader.h>
30
 
#include <qpainter.h>
31
 
#include <qdragobject.h>
32
 
#include <qvaluelist.h>
33
 
 
34
 
// The Dragobject Declaration ---------------------------------------
35
 
class ListViewItemDrag : public QStoredDrag
36
 
{
37
 
public:
38
 
    enum DropRelation { Sibling, Child };
39
 
    ListViewItemDrag( ListViewItemList & items, QWidget * parent = 0, const char * name = 0 );
40
 
    ~ListViewItemDrag() {};
41
 
    static bool canDecode( QDragMoveEvent * event );
42
 
    static bool decode( QDropEvent * event, QListView * parent, QListViewItem * insertPoint, DropRelation dr );
43
 
};
44
 
// ------------------------------------------------------------------
45
 
 
46
 
ListViewDnd::ListViewDnd( QListView * eventSource, const char * name )
47
 
    : ListDnd( eventSource, name ) { }
48
 
 
49
 
void ListViewDnd::confirmDrop( QListViewItem * )
50
 
{
51
 
    dropConfirmed = TRUE;
52
 
}
53
 
 
54
 
bool ListViewDnd::dropEvent( QDropEvent * event )
55
 
{
56
 
    if ( dragInside ) {
57
 
    
58
 
        if ( dMode & NullDrop ) { // combined with Move, a NullDrop will delete an item
59
 
            event->accept();
60
 
            emit dropped( 0 ); // a NullDrop
61
 
            return TRUE;
62
 
        }
63
 
        
64
 
        QPoint pos = event->pos();
65
 
 
66
 
        ListViewItemDrag::DropRelation dr = ListViewItemDrag::Sibling;
67
 
        QListViewItem *item = itemAt( pos );
68
 
        int dpos = dropDepth( item, pos );
69
 
 
70
 
        if ( item ) {
71
 
            if ( dpos > item->depth() && !(dMode & Flat) ) {
72
 
                // Child node
73
 
                dr = ListViewItemDrag::Child;
74
 
            } else if ( dpos < item->depth() ) {
75
 
                // Parent(s) Sibling
76
 
                while ( item && (item->depth() > dpos) )
77
 
                    item = item->parent();
78
 
            }
79
 
        }
80
 
 
81
 
        if ( ListViewItemDrag::decode( event, (QListView *) src, item, dr ) ) {
82
 
            event->accept();
83
 
            emit dropped( 0 ); // Use ID instead of item?
84
 
        }
85
 
    }
86
 
 
87
 
    line->hide();
88
 
    dragInside = FALSE;
89
 
 
90
 
    return TRUE;
91
 
}
92
 
 
93
 
bool ListViewDnd::mouseMoveEvent( QMouseEvent * event )
94
 
{
95
 
    if ( event->state() & LeftButton ) {
96
 
        if ( ( event->pos() - mousePressPos ).manhattanLength() > 3 ) {
97
 
            ListViewItemList list;
98
 
 
99
 
            if ( dMode & Flat )
100
 
                buildFlatList( list );
101
 
            else
102
 
                buildTreeList( list );
103
 
 
104
 
            ListViewItemDrag * dragobject = new ListViewItemDrag( list, (QListView *) src );
105
 
 
106
 
            if ( dMode & Move ) {
107
 
                disabledItems = list;
108
 
                setVisibleItems( FALSE );
109
 
            }
110
 
 
111
 
            dragobject->dragCopy();
112
 
 
113
 
            if ( dMode & Move ) {
114
 
                // Did the target accept the drop?
115
 
                if ( dropConfirmed ) {
116
 
                    // Shouldn't autoDelete handle this?
117
 
                    for( list.first(); list.current(); list.next() ) 
118
 
                        delete list.current();
119
 
                    dropConfirmed = FALSE;
120
 
                } else {
121
 
                    // Reenable disabled items since 
122
 
                    // drag'n'drop was aborted
123
 
                    setVisibleItems( TRUE );
124
 
                }
125
 
                disabledItems.clear();
126
 
            }
127
 
        }
128
 
    }
129
 
    return FALSE;
130
 
}
131
 
 
132
 
int ListViewDnd::buildFlatList( ListViewItemList & list )
133
 
{
134
 
    bool addKids = FALSE;
135
 
    QListViewItem *nextSibling = 0;
136
 
    QListViewItem *nextParent = 0;
137
 
    QListViewItemIterator it = ((QListView *)src)->firstChild();
138
 
    for ( ; *it; it++ ) {
139
 
        // Hit the nextSibling, turn of child processing
140
 
        if ( (*it) == nextSibling )
141
 
            addKids = FALSE;
142
 
 
143
 
        if ( (*it)->isSelected() ) {
144
 
            if ( (*it)->childCount() == 0 ) {
145
 
                // Selected, no children
146
 
                list.append( *it );
147
 
            } else if ( !addKids ) {
148
 
                // Children processing not set, so set it
149
 
                // Also find the item were we shall quit
150
 
                // processing children...if any such item
151
 
                addKids = TRUE;
152
 
                nextSibling = (*it)->nextSibling();
153
 
                nextParent = (*it)->parent();
154
 
                while ( nextParent && !nextSibling ) {
155
 
                    nextSibling = nextParent->nextSibling();
156
 
                    nextParent = nextParent->parent();
157
 
                }
158
 
            }
159
 
        } else if ( ((*it)->childCount() == 0) && addKids ) {
160
 
            // Leaf node, and we _do_ process children
161
 
            list.append( *it );
162
 
        }
163
 
    }
164
 
    return list.count();
165
 
}
166
 
 
167
 
int ListViewDnd::buildTreeList( ListViewItemList & list )
168
 
{
169
 
    QListViewItemIterator it = ((QListView *)src)->firstChild();
170
 
    for ( ; *it; it++ ) {
171
 
        if ( (*it)->isSelected() )
172
 
            list.append( *it );
173
 
    }
174
 
    return list.count();
175
 
}
176
 
 
177
 
void ListViewDnd::setVisibleItems( bool b )
178
 
{
179
 
    if ( disabledItems.isEmpty() ) 
180
 
        return;
181
 
    
182
 
    disabledItems.first();
183
 
    do {
184
 
        disabledItems.current()->setVisible( b );
185
 
    } while ( disabledItems.next() );
186
 
}
187
 
 
188
 
void ListViewDnd::updateLine( const QPoint & dragPos )
189
 
{
190
 
    QListViewItem * item = itemAt(dragPos);
191
 
    QListView * src = (QListView *) this->src;
192
 
 
193
 
    int ypos = item ? 
194
 
        ( src->itemRect( item ).bottom() - ( line->height() / 2 ) ) : 
195
 
        ( src->itemRect( src->firstChild() ).top() );
196
 
 
197
 
    int xpos = dropDepth( item, dragPos ) * src->treeStepSize();
198
 
    line->resize( src->viewport()->width() - xpos, line->height() );
199
 
    line->move( xpos, ypos );
200
 
}
201
 
 
202
 
QListViewItem * ListViewDnd::itemAt( QPoint pos )
203
 
{
204
 
    QListView * src = (QListView *) this->src;
205
 
    int headerHeight = (int)(src->header()->height());
206
 
    pos.ry() -= headerHeight;
207
 
    QListViewItem * result = src->itemAt( pos );
208
 
 
209
 
    if ( result && ( pos.ry() < (src->itemPos(result) + result->height()/2) ) )
210
 
        result = result->itemAbove();
211
 
 
212
 
    // Wind back if has parent, and we're in flat mode
213
 
    while ( result && result->parent() && (dMode & Flat) )
214
 
        result = result->parent();
215
 
 
216
 
    // Wind back if has parent, and we're in flat mode
217
 
    while ( result && !result->isVisible() && result->parent() )
218
 
        result = result->parent();
219
 
 
220
 
    if ( !result && src->firstChild() && (pos.y() > src->itemRect(src->firstChild()).bottom()) ) {
221
 
        result = src->lastItem();
222
 
        if ( !result->isVisible() )
223
 
            // Handle special case where last item is actually hidden
224
 
            result = result->itemAbove();
225
 
    }
226
 
 
227
 
    return result;
228
 
}
229
 
 
230
 
int ListViewDnd::dropDepth( QListViewItem * item, QPoint pos )
231
 
{
232
 
    if ( !item || (dMode & Flat) )
233
 
        return 0;
234
 
 
235
 
    int result     = 0;
236
 
    int itemDepth  = item->depth();
237
 
    int indentSize = ((QListView *)src)->treeStepSize();
238
 
    int itemLeft   = indentSize * itemDepth;
239
 
    int childMargin  = indentSize*2;
240
 
    if ( pos.x() > itemLeft + childMargin ) {
241
 
        result = itemDepth + 1;
242
 
    } else if ( pos.x() < itemLeft ) {
243
 
        result = pos.x() / indentSize;
244
 
    } else {
245
 
        result = itemDepth;
246
 
    }
247
 
    return result;
248
 
}
249
 
 
250
 
bool ListViewDnd::canDecode( QDragEnterEvent * event )
251
 
{
252
 
    return ListViewItemDrag::canDecode( event );
253
 
}
254
 
 
255
 
// ------------------------------------------------------------------
256
 
// The Dragobject Implementation ------------------------------------
257
 
// ------------------------------------------------------------------
258
 
 
259
 
QDataStream & operator<< ( QDataStream & stream, const QListViewItem & item );
260
 
QDataStream & operator>> ( QDataStream & stream, QListViewItem & item );
261
 
 
262
 
ListViewItemDrag::ListViewItemDrag( ListViewItemList & items, QWidget * parent, const char * name )
263
 
    : QStoredDrag( "qt/listviewitem", parent, name )
264
 
{
265
 
    // ### FIX!
266
 
    QByteArray data( sizeof( Q_INT32 ) + sizeof( QListViewItem ) * items.count() );
267
 
    QDataStream stream( data, IO_WriteOnly );
268
 
 
269
 
    stream << items.count();
270
 
 
271
 
    QListViewItem *i = items.first();
272
 
    while ( i ) {
273
 
        stream << *i;
274
 
        i = items.next();
275
 
    }
276
 
 
277
 
    setEncodedData( data );
278
 
}
279
 
 
280
 
bool ListViewItemDrag::canDecode( QDragMoveEvent * event )
281
 
{
282
 
    return event->provides( "qt/listviewitem" );
283
 
}
284
 
 
285
 
bool ListViewItemDrag::decode( QDropEvent * event, QListView * parent, QListViewItem * insertPoint, DropRelation dr )
286
 
{
287
 
    QByteArray data = event->encodedData( "qt/listviewitem" );
288
 
    QListViewItem* itemParent = insertPoint ? insertPoint->parent() : 0;
289
 
 
290
 
    // Change from sibling (default) to child creation
291
 
    if ( insertPoint && dr == Child ) {
292
 
        itemParent = insertPoint;
293
 
        insertPoint = 0;
294
 
    }
295
 
 
296
 
    if ( data.size() ) {
297
 
        event->accept();
298
 
        QDataStream stream( data, IO_ReadOnly );
299
 
 
300
 
        int count = 0;
301
 
        stream >> count;
302
 
 
303
 
        for( int i = 0; i < count; i++ ) {
304
 
            if ( itemParent ) {
305
 
                insertPoint = new QListViewItem( itemParent, insertPoint );
306
 
                itemParent->setOpen( TRUE );
307
 
            } else { // No parent for insertPoint, use QListView
308
 
                insertPoint = new QListViewItem( parent, insertPoint );
309
 
            }
310
 
            stream >> *insertPoint;
311
 
        }
312
 
        return TRUE;
313
 
    }
314
 
    return FALSE;
315
 
}
316
 
 
317
 
 
318
 
QDataStream & operator<< ( QDataStream & stream, const QListViewItem & item )
319
 
{
320
 
    int columns = item.listView()->columns();
321
 
    stream << columns;
322
 
 
323
 
    Q_UINT8 b = 0;
324
 
 
325
 
    int i;
326
 
    for ( i = 0; i < columns; i++ ) {
327
 
        b = (Q_UINT8) ( item.text( i ) != QString::null ); // does column i have a string ?
328
 
        stream << b;
329
 
        if ( b ) {
330
 
            stream << item.text( i );
331
 
        }
332
 
    }
333
 
    
334
 
    for ( i = 0; i < columns; i++ ) {
335
 
        b = (Q_UINT8) ( !!item.pixmap( i ) ); // does column i have a pixmap ?
336
 
        stream << b;
337
 
        if ( b ) {
338
 
            stream << ( *item.pixmap( i ) );
339
 
        }
340
 
    }
341
 
 
342
 
    stream << (Q_UINT8) item.isOpen();
343
 
    stream << (Q_UINT8) item.isSelectable();
344
 
    stream << (Q_UINT8) item.isExpandable();
345
 
    stream << (Q_UINT8) item.dragEnabled();
346
 
    stream << (Q_UINT8) item.dropEnabled();
347
 
    stream << (Q_UINT8) item.isVisible();
348
 
 
349
 
    for ( i = 0; i < columns; i++ ) {
350
 
        stream << (Q_UINT8) item.renameEnabled( i );
351
 
    }
352
 
 
353
 
    stream << (Q_UINT8) item.multiLinesEnabled();
354
 
    stream << item.childCount();
355
 
 
356
 
    if ( item.childCount() > 0 ) {
357
 
        QListViewItem * child = item.firstChild();
358
 
        while ( child ) {
359
 
            stream << ( *child ); // recursive call
360
 
            child = child->nextSibling();
361
 
        }
362
 
    }
363
 
 
364
 
    return stream;
365
 
}
366
 
    
367
 
QDataStream & operator>> ( QDataStream & stream, QListViewItem & item )
368
 
{
369
 
    Q_INT32 columns;
370
 
    stream >> columns;
371
 
 
372
 
    Q_UINT8 b = 0;
373
 
 
374
 
    QString text;
375
 
    int i;
376
 
    for ( i = 0; i < columns; i++ ) {
377
 
        stream >> b;
378
 
        if ( b ) { // column i has string ?
379
 
            stream >> text;
380
 
            item.setText( i, text );
381
 
        }
382
 
    }
383
 
 
384
 
    QPixmap pixmap;
385
 
    for ( i = 0; i < columns; i++ ) {
386
 
        stream >> b; // column i has pixmap ?
387
 
        if ( b ) {
388
 
            stream >> pixmap;
389
 
            item.setPixmap( i, pixmap );
390
 
        }
391
 
    }
392
 
 
393
 
    stream >> b;
394
 
    item.setOpen( b );
395
 
 
396
 
    stream >> b;
397
 
    item.setSelectable( b );
398
 
 
399
 
    stream >> b;
400
 
    item.setExpandable( b );
401
 
 
402
 
    stream >> b;
403
 
    item.setDragEnabled( b );
404
 
 
405
 
    stream >> b;
406
 
    item.setDropEnabled( b );
407
 
 
408
 
    stream >> b;
409
 
    item.setVisible( b );
410
 
 
411
 
    for ( i = 0; i < columns; i++ ) {
412
 
        stream >> b;
413
 
        item.setRenameEnabled( i, b );
414
 
    }
415
 
 
416
 
    stream >> b;
417
 
    item.setMultiLinesEnabled( b );
418
 
 
419
 
    int childCount;
420
 
    stream >> childCount;
421
 
 
422
 
    QListViewItem *child = 0;
423
 
    QListViewItem *prevchild = 0;
424
 
    for ( i = 0; i < childCount; i++ ) {
425
 
        child = new QListViewItem( &item, prevchild );
426
 
        stream >> ( *child );
427
 
        item.insertItem( child );
428
 
        prevchild = child;
429
 
    }
430
 
 
431
 
    return stream;
432
 
}