|
|
|
/***************************************************************************
|
|
|
|
* Copyright (C) 2006 - 2008 Robert Hogan *
|
|
|
|
* robert@roberthogan.net *
|
|
|
|
* *
|
|
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
* This program is distributed in the hope that it will be useful, *
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
* GNU General Public License for more details. *
|
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU General Public License *
|
|
|
|
* along with this program; if not, write to the *
|
|
|
|
* Free Software Foundation, Inc., *
|
|
|
|
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#include "dndlistview.h"
|
|
|
|
#include "torkconfig.h"
|
|
|
|
#include "kdebug.h"
|
|
|
|
#include <ntqapplication.h>
|
|
|
|
#include <ntqheader.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
#include <tdelocale.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
|
|
|
|
#include <ntqsimplerichtext.h>
|
|
|
|
#include <ntqpainter.h>
|
|
|
|
|
|
|
|
DndListView::DndListView( TQWidget * parent, const char * name, WFlags f ) :
|
|
|
|
TQListView( parent, name, f ), oldCurrent( 0 ),
|
|
|
|
dropItem( 0 ), mousePressed( FALSE ),m_recentDrop( FALSE)
|
|
|
|
{
|
|
|
|
|
|
|
|
setAllColumnsShowFocus( TRUE );
|
|
|
|
//setResizeMode( TQListView::AllColumns );
|
|
|
|
setSelectionMode( TQListView::Extended );
|
|
|
|
|
|
|
|
setAcceptDrops( TRUE );
|
|
|
|
viewport()->setAcceptDrops( TRUE );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//static const int autoopenTime = 750;
|
|
|
|
|
|
|
|
|
|
|
|
void DndListView::contentsDragEnterEvent( TQDragEnterEvent *e )
|
|
|
|
{
|
|
|
|
|
|
|
|
setSelectionMode( TQListView::Single );
|
|
|
|
|
|
|
|
if ( !TQTextDrag::canDecode( e ) ) {
|
|
|
|
e->ignore();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
oldCurrent = currentItem();
|
|
|
|
|
|
|
|
TQListViewItem *i = itemAt( contentsToViewport(e->pos()) );
|
|
|
|
if ( i ) {
|
|
|
|
dropItem = i;
|
|
|
|
/* autoopen_timer->start( autoopenTime );*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DndListView::contentsDragMoveEvent( TQDragMoveEvent *e )
|
|
|
|
{
|
|
|
|
if ( !TQTextDrag::canDecode( e ) ) {
|
|
|
|
e->ignore();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
TQPoint vp = contentsToViewport( ( (TQDragMoveEvent*)e )->pos() );
|
|
|
|
TQListViewItem *i = itemAt( vp );
|
|
|
|
|
|
|
|
//!(e->source() == this) &&
|
|
|
|
|
|
|
|
if ((TQString(this->name()).contains("circuitList")) &&
|
|
|
|
(TQString(e->source()->name()).contains("serverList"))) {
|
|
|
|
|
|
|
|
if ( i ){
|
|
|
|
setSelected( i, TRUE );
|
|
|
|
if ( i != dropItem ) {
|
|
|
|
dropItem = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e->accept();
|
|
|
|
}else if ((TQString(this->name()).contains("circuitList")) &&
|
|
|
|
(TQString(e->source()->name()).contains("circuitList"))) {
|
|
|
|
if ( i ){
|
|
|
|
setSelected( i, TRUE );
|
|
|
|
if ( i != dropItem ) {
|
|
|
|
dropItem = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e->accept();
|
|
|
|
}else if ((TQString(this->name()).contains("circuitList")) &&
|
|
|
|
(TQString(e->source()->name()).contains("ORList"))) {
|
|
|
|
if ( i ){
|
|
|
|
setSelected( i, TRUE );
|
|
|
|
if ( i != dropItem ) {
|
|
|
|
dropItem = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e->accept();
|
|
|
|
}else if ((TQString(this->name()).contains("circuitList")) &&
|
|
|
|
(TQString(e->source()->name()).contains("streamList"))) {
|
|
|
|
if ( i ){
|
|
|
|
setSelected( i, TRUE );
|
|
|
|
if ( i != dropItem ) {
|
|
|
|
dropItem = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e->accept();
|
|
|
|
|
|
|
|
}else {
|
|
|
|
e->ignore();
|
|
|
|
dropItem = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DndListView::contentsDragLeaveEvent( TQDragLeaveEvent * )
|
|
|
|
{
|
|
|
|
/* autoopen_timer->stop();*/
|
|
|
|
|
|
|
|
dropItem = 0;
|
|
|
|
|
|
|
|
setCurrentItem( oldCurrent );
|
|
|
|
setSelected( oldCurrent, TRUE );
|
|
|
|
|
|
|
|
setSelectionMode( TQListView::Extended );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void DndListView::contentsDropEvent( TQDropEvent *e )
|
|
|
|
{
|
|
|
|
// autoopen_timer->stop();
|
|
|
|
m_recentDrop = true;
|
|
|
|
dropTimer = startTimer( 3000 );
|
|
|
|
|
|
|
|
setSelectionMode( TQListView::Extended );
|
|
|
|
|
|
|
|
TQString text;
|
|
|
|
if ( !TQTextDrag::decode( e, text ) ) {
|
|
|
|
e->ignore();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_mousepos = e->pos() ;
|
|
|
|
|
|
|
|
TQListViewItem *item = itemAt( contentsToViewport(e->pos()) );
|
|
|
|
if (TQString(this->name()).contains("circuitList")){
|
|
|
|
e->accept();
|
|
|
|
if ( item ) {
|
|
|
|
if (TQString(e->source()->name()).contains("serverList"))
|
|
|
|
emit extendCircuit(item->text(0),text,true);
|
|
|
|
else if (TQString(e->source()->name()).contains("circuitList"))
|
|
|
|
emit extendCircuit(item->text(0),text, true);
|
|
|
|
else if (TQString(e->source()->name()).contains("ORList"))
|
|
|
|
emit extendCircuit(item->text(0),text, false);
|
|
|
|
else if (TQString(e->source()->name()).contains("streamList"))
|
|
|
|
emit attach(item->text(0),text);
|
|
|
|
} else{
|
|
|
|
if (TQString(e->source()->name()).contains("serverList"))
|
|
|
|
emit createCircuit(text,true);
|
|
|
|
else if (TQString(e->source()->name()).contains("ORList"))
|
|
|
|
emit createCircuit(text,false);
|
|
|
|
}
|
|
|
|
}else
|
|
|
|
e->ignore();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void DndListView::contentsMousePressEvent( TQMouseEvent* e )
|
|
|
|
{
|
|
|
|
TQPoint p( contentsToViewport( e->pos() ) );
|
|
|
|
//TQListViewItem *i = itemAt( p );
|
|
|
|
/* if ( i ) {
|
|
|
|
// if the user clicked into the root decoration of the item, don't try to start a drag!
|
|
|
|
if ( p.x() > header()->cellPos( header()->mapToActual( 0 ) ) +
|
|
|
|
treeStepSize() * ( i->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() ||
|
|
|
|
p.x() < header()->cellPos( header()->mapToActual( 0 ) ) ) {
|
|
|
|
presspos = e->pos();
|
|
|
|
mousePressed = TRUE;
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
|
|
|
|
if (e->button() == TQt::LeftButton){
|
|
|
|
presspos = e->pos();
|
|
|
|
mousePressed = TRUE;
|
|
|
|
}
|
|
|
|
TQListView::contentsMousePressEvent( e );
|
|
|
|
}
|
|
|
|
|
|
|
|
void DndListView::contentsMouseMoveEvent( TQMouseEvent* e )
|
|
|
|
{
|
|
|
|
if ( mousePressed ) {
|
|
|
|
kdDebug() << "in mouse move drag" << endl;
|
|
|
|
|
|
|
|
mousePressed = FALSE;
|
|
|
|
//TQListViewItem *item = itemAt( contentsToViewport(presspos) );
|
|
|
|
|
|
|
|
int column;
|
|
|
|
if (TQString(this->name()).contains("circuitList"))
|
|
|
|
column = 2;
|
|
|
|
else if (TQString(this->name()).contains("ORList"))
|
|
|
|
column = 1;
|
|
|
|
else if (TQString(this->name()).contains("streamList"))
|
|
|
|
column = 0;
|
|
|
|
else
|
|
|
|
column = 2;
|
|
|
|
|
|
|
|
TQString selectedItems;
|
|
|
|
TQListViewItemIterator it(this, TQListViewItemIterator::Selected);
|
|
|
|
while ( it.current() ) {
|
|
|
|
if (this->isSelected( it.current()))
|
|
|
|
selectedItems.append(it.current()->text(column)+" ");
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
if (!selectedItems.isEmpty()){
|
|
|
|
selectedItems = selectedItems.stripWhiteSpace();
|
|
|
|
TQDragObject *d = new TQTextDrag( selectedItems, this );
|
|
|
|
d->dragCopy(); // do NOT delete d.
|
|
|
|
}
|
|
|
|
|
|
|
|
}else
|
|
|
|
TQListView::contentsMouseMoveEvent( e );
|
|
|
|
}
|
|
|
|
|
|
|
|
void DndListView::contentsMouseReleaseEvent( TQMouseEvent* e)
|
|
|
|
{
|
|
|
|
/* kdDebug() << "mouse released" << endl;*/
|
|
|
|
mousePressed = FALSE;
|
|
|
|
TQListView::contentsMouseReleaseEvent(e);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void DndListView::mouseReleaseEvent( TQMouseEvent* e)
|
|
|
|
{
|
|
|
|
/* kdDebug() << "mouse released" << endl;*/
|
|
|
|
mousePressed = FALSE;
|
|
|
|
TQListView::mouseReleaseEvent(e);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
TQPoint DndListView::getMousePos()
|
|
|
|
{
|
|
|
|
return m_mousepos;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DndListView::timerEvent( TQTimerEvent * )
|
|
|
|
{
|
|
|
|
//if ( e->timerId() == dropTimer ) // stop showing date
|
|
|
|
m_recentDrop = false;
|
|
|
|
killTimer( dropTimer );
|
|
|
|
dropTimer = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
DndListView::viewportPaintEvent( TQPaintEvent *e )
|
|
|
|
{
|
|
|
|
TQListView::viewportPaintEvent( e );
|
|
|
|
|
|
|
|
if (!TorkConfig::displayBubble())
|
|
|
|
return;
|
|
|
|
// Superimpose bubble help
|
|
|
|
// Taken from mediabrowser.cpp in Amarok
|
|
|
|
|
|
|
|
if (( childCount() == 0 ) && (TQString(this->name()).contains("streamList")))
|
|
|
|
{
|
|
|
|
TQPainter p( viewport() );
|
|
|
|
|
|
|
|
TQSimpleRichText t( i18n(
|
|
|
|
"<div align=center>"
|
|
|
|
"<h4>Almost Everything Is Clickable.</h4>"
|
|
|
|
"You can drag servers to create circuits. You can drag connections onto circuits "
|
|
|
|
" if you right-click here first. "
|
|
|
|
"You can right-click on servers to include/exclude them or their country from your "
|
|
|
|
"connections. Remember though: <b> messing with stuff is fun, but generally bad for "
|
|
|
|
"anonymity.</b>"
|
|
|
|
"</div>" ), TQApplication::font() );
|
|
|
|
|
|
|
|
t.setWidth( width() - 50 );
|
|
|
|
|
|
|
|
const uint w = t.width() + 20;
|
|
|
|
const uint h = t.height() + 20;
|
|
|
|
|
|
|
|
p.setBrush( colorGroup().background() );
|
|
|
|
p.drawRoundRect( 15, 15, w, h, (8*200)/w, (8*200)/h );
|
|
|
|
t.draw( &p, 20, 20, TQRect(), colorGroup() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// TQDragObject *DndListView::dragObject()
|
|
|
|
// {
|
|
|
|
// kdDebug() << "dragging item" << endl;
|
|
|
|
// return new TQTextDrag( currentItem()->text(0), this );
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// void DndListView::dragEnterEvent( TQDragEnterEvent *evt )
|
|
|
|
// {
|
|
|
|
// kdDebug() << "drag enter event" << endl;
|
|
|
|
// if ( TQTextDrag::canDecode( evt ) )
|
|
|
|
// evt->accept();
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// void DndListView::dropEvent( TQDropEvent *evt )
|
|
|
|
// {
|
|
|
|
// TQString text;
|
|
|
|
//
|
|
|
|
// if ( TQTextDrag::decode( evt, text ) )
|
|
|
|
// kdDebug() << text << endl;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// void DndListView::contentsMousePressEvent( TQMouseEvent *evt )
|
|
|
|
// {
|
|
|
|
// dragging = TRUE;
|
|
|
|
// kdDebug() << "draggng mouse" << endl;
|
|
|
|
// TQListView::mousePressEvent( evt );
|
|
|
|
//
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// void DndListView::contentsMouseMoveEvent( TQMouseEvent * )
|
|
|
|
// {
|
|
|
|
// if ( dragging ) {
|
|
|
|
// kdDebug() << "dragging" << endl;
|
|
|
|
// TQDragObject *d = new TQTextDrag( currentItem()->text(0), this );
|
|
|
|
// d->dragCopy(); // do NOT delete d.
|
|
|
|
// dragging = FALSE;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
#include "dndlistview.moc"
|