Source Code (Use browser search to find items of interest.)
Class Index
qt'QDragManager (./qt-2.1.0/src/kernel/qdragobject.h:176)
class Q_EXPORT QDragManager: public QObject {
Q_OBJECT
private:
QDragManager();
~QDragManager();
// only friend classes can use QDragManager.
friend class QDragObject;
friend class QDragMoveEvent;
friend class QDropEvent;
bool eventFilter( QObject *, QEvent * );
void timerEvent( QTimerEvent* );
bool drag( QDragObject *, QDragObject::DragMode );
void cancel( bool deleteSource = TRUE );
void move( const QPoint & );
void drop();
void updatePixmap();
private:
QDragObject * object;
void updateMode( ButtonState newstate );
void updateCursor();
QWidget * dragSource;
QWidget * dropWidget;
bool beingCancelled;
bool restoreCursor;
bool willDrop;
QPixmap *pm_cursor;
int n_cursor;
};
qt'QDragManager::timerEvent() (./qt-2.1.0/src/kernel/qdnd_x11.cpp:828)
void QDragManager::timerEvent( QTimerEvent* e )
{
if ( e->timerId() == heartbeat && qt_xdnd_source_sameanswer.isNull() )
move( QCursor::pos() );
}
qt'QDragManager::eventFilter() (./qt-2.1.0/src/kernel/qdnd_x11.cpp:834)
bool QDragManager::eventFilter( QObject * o, QEvent * e)
{
if ( beingCancelled ) {
if ( e->type() == QEvent::KeyRelease &&
((QKeyEvent*)e)->key() == Key_Escape ) {
qApp->removeEventFilter( this );
object = 0;
dragSource = 0;
beingCancelled = FALSE;
qApp->exit_loop();
return TRUE; // block the key release
}
return FALSE;
}
ASSERT( object != 0 );
if ( !o->isWidgetType() )
return FALSE;
QWidget* w = (QWidget*)o;
if ( e->type() == QEvent::MouseMove ) {
QMouseEvent* me = (QMouseEvent *)e;
updateMode(me->stateAfter());
move( w->mapToGlobal( me->pos() ) );
return TRUE;
} else if ( e->type() == QEvent::MouseButtonRelease ) {
qApp->removeEventFilter( this );
if ( willDrop )
drop();
else
cancel();
object = 0;
dragSource = 0;
beingCancelled = FALSE;
qApp->exit_loop();
return TRUE;
} else if ( e->type() == QEvent::DragResponse ) {
if ( ((QDragResponseEvent *)e)->dragAccepted() ) {
if ( !willDrop ) {
willDrop = TRUE;
}
} else {
if ( willDrop ) {
willDrop = FALSE;
}
}
updateCursor();
return TRUE;
}
if ( e->type() == QEvent::KeyPress
|| e->type() == QEvent::KeyRelease )
{
QKeyEvent *ke = ((QKeyEvent*)e);
if ( ke->key() == Key_Escape && e->type() == QEvent::KeyPress ) {
cancel();
qApp->removeEventFilter( this );
object = 0;
dragSource = 0;
beingCancelled = FALSE;
qApp->exit_loop();
} else {
updateMode(ke->stateAfter());
qt_xdnd_source_sameanswer = QRect(); // force move
move( QCursor::pos() );
}
return TRUE; // Eat all key events
}
// ### We bind modality to widgets, so we have to do this
// ### "manually".
// DnD is modal - eat all other interactive events
switch ( e->type() ) {
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseButtonDblClick:
case QEvent::MouseMove:
case QEvent::KeyPress:
case QEvent::KeyRelease:
case QEvent::Wheel:
case QEvent::Accel:
case QEvent::AccelAvailable:
return TRUE;
default:
return FALSE;
}
}
qt'QDragManager::updateMode() (./qt-2.1.0/src/kernel/qdnd_x11.cpp:926)
void QDragManager::updateMode( ButtonState newstate )
{
if ( newstate == oldstate )
return;
const int both = ShiftButton|ControlButton;
if ( (newstate & both) == both ) {
global_requested_action = QDropEvent::Link;
} else {
bool local = qt_xdnd_source_object != 0;
if ( drag_mode == QDragObject::DragMove )
global_requested_action = QDropEvent::Move;
else if ( drag_mode == QDragObject::DragCopy )
global_requested_action = QDropEvent::Copy;
else {
if ( drag_mode == QDragObject::DragDefault && local )
global_requested_action = QDropEvent::Move;
else
global_requested_action = QDropEvent::Copy;
if ( newstate & ShiftButton )
global_requested_action = QDropEvent::Move;
else if ( newstate & ControlButton )
global_requested_action = QDropEvent::Copy;
}
}
oldstate = newstate;
}
qt'QDragManager::updateCursor() (./qt-2.1.0/src/kernel/qdnd_x11.cpp:954)
void QDragManager::updateCursor()
{
if ( !noDropCursor ) {
noDropCursor = new QCursor( ForbiddenCursor );
if ( !pm_cursor[0].isNull() )
moveCursor = new QCursor(pm_cursor[0], 0,0);
if ( !pm_cursor[1].isNull() )
copyCursor = new QCursor(pm_cursor[1], 0,0);
if ( !pm_cursor[2].isNull() )
linkCursor = new QCursor(pm_cursor[2], 0,0);
}
QCursor *c;
if ( willDrop ) {
if ( global_accepted_action == QDropEvent::Copy ) {
if ( global_requested_action == QDropEvent::Move )
c = moveCursor; // (source can delete)
else
c = copyCursor;
} else if ( global_accepted_action == QDropEvent::Link ) {
c = linkCursor;
} else {
c = moveCursor;
}
if ( qt_xdnd_deco )
qt_xdnd_deco->show();
} else {
c = noDropCursor;
if ( qt_xdnd_deco )
qt_xdnd_deco->hide();
}
if ( c )
qApp->setOverrideCursor( *c, TRUE );
}
qt'QDragManager::cancel() (./qt-2.1.0/src/kernel/qdnd_x11.cpp:990)
void QDragManager::cancel( bool deleteSource )
{
if ( object ) {
beingCancelled = TRUE;
object = 0;
}
if ( qt_xdnd_current_target ) {
qt_xdnd_send_leave();
}
if ( restoreCursor ) {
QApplication::restoreOverrideCursor();
restoreCursor = FALSE;
}
if ( deleteSource )
delete qt_xdnd_source_object;
qt_xdnd_source_object = 0;
delete qt_xdnd_deco;
qt_xdnd_deco = 0;
}
static
qt'QDragManager::move() (./qt-2.1.0/src/kernel/qdnd_x11.cpp:1063)
void QDragManager::move( const QPoint & globalPos )
{
updatePixmap();
if ( qt_xdnd_source_sameanswer.contains( globalPos ) &&
qt_xdnd_source_sameanswer.isValid() ) {
return;
}
Window target = 0;
int lx = 0, ly = 0;
if ( !XTranslateCoordinates( qt_xdisplay(), qt_xrootwin(), qt_xrootwin(),
globalPos.x(), globalPos.y(),
&lx, &ly, &target) ) {
// somehow got to a different screen? ignore for now
return;
}
if ( target == qt_xrootwin() ) {
// Ok.
} else if ( target ) {
//me
target = qt_x11_findClientWindow( target, qt_wm_state, TRUE );
if ( qt_xdnd_deco && (!target || target == qt_xdnd_deco->winId()) ) {
target = findRealWindow(globalPos,qt_xrootwin(),6);
}
}
int emask = NoEventMask;
QWidget* w;
if ( target ) {
w = QWidget::find( (WId)target );
if ( w && w->isDesktop() && !w->acceptDrops() ) {
emask = EnterWindowMask;
w = 0;
}
} else {
w = 0;
target = qt_xrootwin();
}
WId proxy_target = target;
int target_version = 1;
{
Atom type = None;
int f;
unsigned long n, a;
WId *proxy_id;
qt_ignore_badwindow();
XGetWindowProperty( qt_xdisplay(), target, qt_xdnd_proxy, 0,
1, False, XA_WINDOW, &type, &f,&n,&a,(uchar**)&proxy_id );
if ( qt_badwindow() ) {
proxy_target = target = 0;
} else if ( type == XA_WINDOW && proxy_id ) {
proxy_target = *proxy_id;
XFree(proxy_id);
proxy_id = 0;
qt_ignore_badwindow();
XGetWindowProperty( qt_xdisplay(), proxy_target, qt_xdnd_proxy, 0,
1, False, XA_WINDOW, &type, &f,&n,&a,(uchar**)&proxy_id );
if ( qt_badwindow() || !type || !proxy_id || *proxy_id != proxy_target ) {
// Bogus
proxy_target = 0;
target = 0;
}
if ( proxy_id )
XFree(proxy_id);
}
if ( proxy_target ) {
int *tv;
qt_ignore_badwindow();
XGetWindowProperty( qt_xdisplay(), proxy_target, qt_xdnd_aware, 0,
1, False, AnyPropertyType, &type, &f,&n,&a,(uchar**)&tv );
target_version = QMIN(qt_xdnd_version,tv ? *tv : 1);
if ( tv ) XFree(tv);
if ( !qt_badwindow() && type )
emask = EnterWindowMask;
else
target = 0;
}
}
if ( target != qt_xdnd_current_target ) {
if ( qt_xdnd_current_target )
qt_xdnd_send_leave();
qt_xdnd_current_target = target;
qt_xdnd_current_proxy_target = proxy_target;
if ( target ) {
QArray<Atom> type;
int flags = target_version << 24;
const char* fmt;
int nfmt=0;
for (nfmt=0; (fmt=object->format(nfmt)); nfmt++) {
type.resize(nfmt+1);
type[nfmt] = *qt_xdnd_str_to_atom( fmt );
}
if ( nfmt >= 3 ) {
XChangeProperty( qt_xdisplay(),
object->source()->winId(), qt_xdnd_type_list,
XA_ATOM, 32, PropModeReplace,
(unsigned char *)type.data(),
type.size() );
flags |= 0x0001;
}
XClientMessageEvent enter;
enter.type = ClientMessage;
enter.window = target;
enter.format = 32;
enter.message_type = qt_xdnd_enter;
enter.data.l[0] = object->source()->winId();
enter.data.l[1] = flags;
enter.data.l[2] = type.size()>0 ? type[0] : 0;
enter.data.l[3] = type.size()>1 ? type[1] : 0;
enter.data.l[4] = type.size()>2 ? type[2] : 0;
// provisionally set the rectangle to 5x5 pixels...
qt_xdnd_source_sameanswer = QRect( globalPos.x() - 2,
globalPos.y() -2 , 5, 5 );
if ( w ) {
qt_handle_xdnd_enter( w, (const XEvent *)&enter, FALSE );
} else if ( target ) {
XSendEvent( qt_xdisplay(), proxy_target, FALSE, emask,
(XEvent*)&enter );
}
}
}
if ( target ) {
XClientMessageEvent move;
move.type = ClientMessage;
move.window = target;
move.format = 32;
move.message_type = qt_xdnd_position;
move.window = target;
move.data.l[0] = object->source()->winId();
move.data.l[1] = 0; // flags
move.data.l[2] = (globalPos.x() << 16) + globalPos.y();
move.data.l[3] = qt_x_time;
move.data.l[4] = qtaction_to_xdndaction( global_requested_action );
if ( w )
qt_handle_xdnd_position( w, (const XEvent *)&move, FALSE );
else
XSendEvent( qt_xdisplay(), proxy_target, FALSE, emask,
(XEvent*)&move );
} else {
if ( willDrop ) {
willDrop = FALSE;
updateCursor();
}
}
}
qt'QDragManager::drop() (./qt-2.1.0/src/kernel/qdnd_x11.cpp:1219)
void QDragManager::drop()
{
if ( !qt_xdnd_current_target )
return;
delete qt_xdnd_deco;
qt_xdnd_deco = 0;
XClientMessageEvent drop;
drop.type = ClientMessage;
drop.window = qt_xdnd_current_target;
drop.format = 32;
drop.message_type = qt_xdnd_drop;
drop.data.l[0] = object->source()->winId();
drop.data.l[1] = 1 << 24; // flags
drop.data.l[2] = 0; // ###
drop.data.l[3] = qt_x_time;
drop.data.l[4] = 0;
QWidget * w = QWidget::find( qt_xdnd_current_proxy_target );
int emask = NoEventMask;
if ( w && w->isDesktop() && !w->acceptDrops() ) {
emask = EnterWindowMask;
w = 0;
}
if ( w )
qt_handle_xdnd_drop( w, (const XEvent *)&drop, FALSE );
else
XSendEvent( qt_xdisplay(), qt_xdnd_current_proxy_target, FALSE, emask,
(XEvent*)&drop );
if ( restoreCursor ) {
QApplication::restoreOverrideCursor();
restoreCursor = FALSE;
}
}
qt'QDragManager::drag() (./qt-2.1.0/src/kernel/qdnd_x11.cpp:1531)
bool QDragManager::drag( QDragObject * o, QDragObject::DragMode mode )
{
if ( object == o )
return FALSE;
if ( object ) {
cancel();
qApp->removeEventFilter( this );
beingCancelled = FALSE;
}
qt_xdnd_source_object = o;
qt_xdnd_deco = new QShapedPixmapWidget();
willDrop = FALSE;
object = o;
updatePixmap();
dragSource = (QWidget *)(object->parent());
qApp->installEventFilter( this );
qt_xdnd_source_current_time = qt_x_time;
XSetSelectionOwner( qt_xdisplay(), qt_xdnd_selection,
dragSource->topLevelWidget()->winId(),
qt_xdnd_source_current_time );
oldstate = ButtonState(-1); // #### Should use state that caused the drag
drag_mode = mode;
global_accepted_action = QDropEvent::Copy; // #####
updateMode(ButtonState(0));
qt_xdnd_source_sameanswer = QRect();
move(QCursor::pos());
heartbeat = startTimer(200);
qApp->setOverrideCursor( arrowCursor );
restoreCursor = TRUE;
updateCursor();
qApp->enter_loop(); // Do the DND.
qApp->restoreOverrideCursor();
delete qt_xdnd_deco;
qt_xdnd_deco = 0;
killTimer(heartbeat);
heartbeat = 0;
return global_accepted_action == QDropEvent::Copy
&& global_requested_action == QDropEvent::Move; // source del?
// qt_xdnd_source_object persists for a while...
}
qt'QDragManager::updatePixmap() (./qt-2.1.0/src/kernel/qdnd_x11.cpp:1584)
void QDragManager::updatePixmap()
{
if ( qt_xdnd_deco ) {
QPixmap pm;
QPoint pm_hot(default_pm_hotx,default_pm_hoty);
if ( object ) {
pm = object->pixmap();
if ( !pm.isNull() )
pm_hot = object->pixmapHotSpot();
}
if ( pm.isNull() ) {
if ( !defaultPm )
defaultPm = new QPixmap(default_pm);
pm = *defaultPm;
}
qt_xdnd_deco->setPixmap(pm);
qt_xdnd_deco->move(QCursor::pos()-pm_hot);
//qt_xdnd_deco->repaint(FALSE);
if ( willDrop ) {
qt_xdnd_deco->show();
} else {
qt_xdnd_deco->hide();
}
}
}
qt'QDragManager::QDragManager() (./qt-2.1.0/src/kernel/qdragobject.cpp:237)
QDragManager::QDragManager()
: QObject( qApp, "global drag manager" )
{
n_cursor = 3;
pm_cursor = new QPixmap[n_cursor];
pm_cursor[0] = QPixmap((const char **)move_xpm);
pm_cursor[1] = QPixmap((const char **)copy_xpm);
pm_cursor[2] = QPixmap((const char **)link_xpm);
object = 0;
dragSource = 0;
dropWidget = 0;
if ( !manager )
manager = this;
beingCancelled = FALSE;
restoreCursor = FALSE;
willDrop = FALSE;
}
qt'QDragManager::~QDragManager() (./qt-2.1.0/src/kernel/qdragobject.cpp:256)
QDragManager::~QDragManager()
{
if ( restoreCursor )
QApplication::restoreOverrideCursor();
manager = 0;
delete [] pm_cursor;
}
/*! Constructs a drag object which is a child of \a dragSource and
named \a name.
Note that the drag object will be deleted when \a dragSource is.
*/