00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "ui/droptarget.h"
00013
00014 #include "core/kget.h"
00015 #include "settings.h"
00016 #include "mainwindow.h"
00017 #include "ui/newtransferdialog.h"
00018
00019 #include <kwindowsystem.h>
00020 #include <klocale.h>
00021 #include <kmenu.h>
00022 #include <kmessagebox.h>
00023 #include <KPassivePopup>
00024 #include <kstandarddirs.h>
00025 #include <kactioncollection.h>
00026 #include <kapplication.h>
00027 #include <kiconloader.h>
00028 #include <KGlobalSettings>
00029
00030 #include <QBitmap>
00031 #include <QPainter>
00032 #include <QTimer>
00033 #include <QClipboard>
00034
00035 #include <math.h>
00036
00037 #define TARGET_SIZE 64
00038 #define TARGET_ANI_MS 20
00039
00040 DropTarget::DropTarget(MainWindow * mw)
00041 : QWidget(0, Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint),
00042 parentWidget(mw), animTimer(0), showInformation(false)
00043 {
00044 KWindowSystem::setState(winId(), NET::SkipTaskbar);
00045
00046 QRect desk = KGlobalSettings::desktopGeometry(this);
00047 desk.setRight( desk.right() - TARGET_SIZE );
00048 desk.setBottom( desk.bottom() - TARGET_SIZE );
00049
00050 if (desk.contains(Settings::dropPosition())
00051 && ((Settings::dropPosition().x() != 0) || (Settings::dropPosition().y() != 0)))
00052 position = QPoint(Settings::dropPosition());
00053 else
00054 position = QPoint((int)desk.width() / 2, (int)desk.height() / 2);
00055
00056 resize(TARGET_SIZE, TARGET_SIZE);
00057
00058 if(Settings::dropSticky())
00059 KWindowSystem::setState(winId(), KWindowSystem::Sticky);
00060
00061 cachedPixmap = DesktopIcon("kget", TARGET_SIZE);
00062 if (!cachedPixmap.mask().isNull())
00063 {
00064 QBitmap mask(size());
00065 mask.fill(Qt::color0);
00066 QBitmap pixMask = cachedPixmap.mask();
00067 QPainter p(&mask);
00068 p.drawPixmap((mask.width() - pixMask.width())/2, (mask.height() - pixMask.height())/2,
00069 pixMask);
00070 setMask(mask);
00071 }
00072 else
00073 setMask(QBitmap());
00074
00075 update();
00076
00077
00078 popupMenu = new KMenu();
00079 popupMenu->addTitle(mw->windowTitle());
00080
00081 QAction * downloadAction = mw->actionCollection()->action("start_all_download");
00082 popupMenu->addAction( downloadAction );
00083 connect( downloadAction, SIGNAL( toggled(bool) ), this, SLOT( slotStartStopToggled(bool) ) );
00084 popupMenu->addSeparator();
00085 pop_show = popupMenu->addAction( QString(), this, SLOT( toggleMinimizeRestore() ) );
00086 popupMenu->addAction(parentWidget->actionCollection()->action("show_drop_target"));
00087 pop_sticky = popupMenu->addAction(i18n("Sticky"), this, SLOT(toggleSticky()));
00088 pop_sticky->setCheckable(true);
00089 pop_sticky->setChecked(Settings::dropSticky());
00090 popupMenu->addSeparator();
00091 popupMenu->addAction( mw->actionCollection()->action("preferences") );
00092
00093 QAction *quitAction = new QAction(this);
00094 quitAction->setText(i18n("Quit KGet"));
00095 quitAction->setIcon(KIcon("system-log-out"));
00096 connect(quitAction, SIGNAL(triggered()), mw, SLOT(slotQuit()));
00097 popupMenu->addAction(quitAction);
00098
00099 isdragging = false;
00100
00101
00102 setAcceptDrops(true);
00103
00104 if ( Settings::showDropTarget() && Settings::firstRun() ) {
00105 showInformation = true;
00106 }
00107
00108 }
00109
00110
00111 DropTarget::~DropTarget()
00112 {
00113 Settings::setDropPosition( pos() );
00114 Settings::setShowDropTarget( !isHidden() );
00115
00116
00117
00118 delete popupMenu;
00119 delete animTimer;
00120 }
00121
00122 void DropTarget::setVisible( bool shown, bool internal )
00123 {
00124 if (shown == !isHidden())
00125 return;
00126
00127 if ( internal )
00128 Settings::setShowDropTarget( shown );
00129
00130 if (!shown)
00131 {
00132 Settings::setDropPosition( pos() );
00133 if ( Settings::animateDropTarget() )
00134 playAnimationHide();
00135 else
00136 hide();
00137 }
00138 else
00139 {
00140 show();
00141 if ( Settings::animateDropTarget() )
00142 playAnimationShow();
00143 else
00144 move(position);
00145 }
00146 }
00147
00148 void DropTarget::playAnimationShow()
00149 {
00150 if ( animTimer )
00151 delete animTimer;
00152 animTimer = new QTimer;
00153 connect( animTimer, SIGNAL( timeout() ),
00154 this, SLOT( slotAnimateShow() ));
00155
00156 move(position.x(), -TARGET_SIZE);
00157
00158 ani_y = -1;
00159 ani_vy = 0;
00160 animTimer->start(TARGET_ANI_MS);
00161 }
00162
00163 void DropTarget::playAnimationHide()
00164 {
00165 if ( animTimer )
00166 {
00167 if ( animTimer->isActive() )
00168 move( x(), (int)(ani_y) );
00169 delete animTimer;
00170 }
00171 animTimer = new QTimer;
00172 connect( animTimer, SIGNAL( timeout() ),
00173 this, SLOT( slotAnimateHide() ));
00174 ani_y = (float)y();
00175 ani_vy = 0;
00176 animTimer->start(TARGET_ANI_MS);
00177 }
00178
00179 void DropTarget::playAnimationSync()
00180 {
00181 if ( animTimer )
00182 {
00183 if ( animTimer->isActive() )
00184 move( x(), (int)(ani_y) );
00185 delete animTimer;
00186 }
00187 animTimer = new QTimer;
00188 connect( animTimer, SIGNAL( timeout() ),
00189 this, SLOT( slotAnimateSync() ));
00190 ani_y = (float)y();
00191 ani_vy = -1;
00192 animTimer->start(TARGET_ANI_MS);
00193 }
00194
00195 void DropTarget::slotStartStopToggled( bool started )
00196 {
00197 if ( started && Settings::animateDropTarget() )
00198 playAnimationSync();
00199 }
00200
00201
00204 void DropTarget::dragEnterEvent(QDragEnterEvent * event)
00205 {
00206 event->setAccepted(KUrl::List::canDecode(event->mimeData())
00207 || event->mimeData()->hasText());
00208 }
00209
00210
00211 void DropTarget::dropEvent(QDropEvent * event)
00212 {
00213 KUrl::List list = KUrl::List::fromMimeData(event->mimeData());
00214 QString str;
00215
00216 if (!list.isEmpty())
00217 {
00230 if (list.count() == 1)
00231 {
00232 str = event->mimeData()->text();
00233 NewTransferDialog::showNewTransferDialog(str);
00234 }
00235 else
00236 NewTransferDialog::showNewTransferDialog(list);
00237
00238 }
00239 else
00240 {
00241 NewTransferDialog::showNewTransferDialog();
00242 }
00243
00244 if ( Settings::animateDropTarget() )
00245 playAnimationSync();
00246 }
00247
00248
00249 void DropTarget::closeEvent( QCloseEvent * e )
00250 {
00251 if( kapp->sessionSaving() )
00252 e->ignore();
00253 else
00254 {
00255 setVisible( false );
00256 e->accept();
00257 }
00258 }
00259
00260 void DropTarget::mousePressEvent(QMouseEvent * e)
00261 {
00262
00263 if(animTimer)
00264 {
00265 animTimer->stop();
00266 delete animTimer;
00267 animTimer = 0;
00268 }
00269
00270 if (e->button() == Qt::LeftButton)
00271 {
00272 isdragging = true;
00273 dx = e->globalPos().x() - pos().x();
00274 dy = e->globalPos().y() - pos().y();
00275 }
00276 else if (e->button() == Qt::RightButton)
00277 {
00278 pop_show->setText(parentWidget->isHidden() ?
00279 i18n("Show Main Window") :
00280 i18n("Hide Main Window") );
00281 popupMenu->popup(e->globalPos());
00282 }
00283 else if (e->button() == Qt::MidButton)
00284 {
00285
00286 QString newtransfer = QApplication::clipboard()->text();
00287 newtransfer = newtransfer.trimmed();
00288
00289 if(!newtransfer.isEmpty())
00290 KGet::addTransfer(KUrl(newtransfer), QString(), QString(), true);
00291 }
00292 }
00293
00294 void DropTarget::mouseReleaseEvent(QMouseEvent *)
00295 {
00296 isdragging = false;
00297 }
00298
00299 void DropTarget::mouseDoubleClickEvent(QMouseEvent * e)
00300 {
00301 if (e->button() == Qt::LeftButton)
00302 toggleMinimizeRestore();
00303 }
00304
00305 void DropTarget::mouseMoveEvent(QMouseEvent * e)
00306 {
00307 Q_UNUSED(e);
00308 if ( isdragging && !Settings::dropSticky() )
00309 {
00310 move( QCursor::pos().x() - dx, QCursor::pos().y() - dy );
00311 e->accept();
00312 }
00313 }
00314
00315 void DropTarget::paintEvent( QPaintEvent * )
00316 {
00317 QPainter p(this);
00318 p.drawPixmap(0, 0, cachedPixmap);
00319 }
00320
00321 void DropTarget::toggleSticky()
00322 {
00323 Settings::setDropSticky( !Settings::dropSticky() );
00324 pop_sticky->setChecked(Settings::dropSticky());
00325
00326 if ( Settings::dropSticky() )
00327 KWindowSystem::setState(winId(), KWindowSystem::SkipTaskbar | KWindowSystem::StaysOnTop | KWindowSystem::Sticky);
00328 else
00329 KWindowSystem::clearState(winId(), KWindowSystem::Sticky);
00330 }
00331
00332 void DropTarget::toggleMinimizeRestore()
00333 {
00334 bool nextState = parentWidget->isHidden();
00335 Settings::setShowMain( nextState );
00336 parentWidget->setVisible( nextState );
00337 }
00338
00340 void DropTarget::slotAnimateShow()
00341 {
00342 static float dT = TARGET_ANI_MS / 1000.0;
00343
00344 ani_vy -= ani_y * 30 * dT;
00345 ani_vy *= 0.95;
00346 ani_y += ani_vy * dT;
00347
00348 move(x(), (int)(position.y() * (1 + ani_y)));
00349
00350 if ( fabs(ani_y) < 0.01 && fabs(ani_vy) < 0.01 && animTimer )
00351 {
00352 animTimer->stop();
00353 delete animTimer;
00354 animTimer = 0;
00355
00356 if (showInformation)
00357 KPassivePopup::message(i18n("Drop Target"),
00358 i18n("You can drag download links into the drop target."), this);
00359 }
00360 }
00361
00362 void DropTarget::slotAnimateHide()
00363 {
00364 static float dT = TARGET_ANI_MS / 1000.0;
00365
00366 ani_vy += -2000 * dT;
00367 float new_y = y() + ani_vy * dT;
00368
00369 if ( new_y < -height() )
00370 {
00371 animTimer->stop();
00372 delete animTimer;
00373 animTimer = 0;
00374 move( x(), (int)(ani_y) );
00375 hide();
00376 } else
00377 move( x(), (int)(new_y) );
00378 }
00379
00380 void DropTarget::slotAnimateSync()
00381 {
00382 static float dT = TARGET_ANI_MS / 1000.0;
00383
00384 ani_vy += 4 * dT;
00385 float i = 2 * M_PI * ani_vy;
00386 float j = (i == 0.0) ? 1 : (sin( i ) / i) * (1 + fabs(ani_vy));
00387
00388 if ( ani_vy >= 1 )
00389 {
00390 animTimer->stop();
00391 delete animTimer;
00392 animTimer = 0;
00393 move( x(), (int)(ani_y) );
00394 } else
00395 move( x(), (int)(ani_y + 6*j) );
00396 }
00397
00398 void DropTarget::slotClose()
00399 {
00400 if (!Settings::expertMode())
00401 {
00402 KMessageBox::information(parentWidget,
00403 i18n("Drop target has been hidden. If you want to show it "
00404 "again, go to Settings->Configure KGet->Look & Feel."),
00405 i18n("Hiding drop target"),
00406 "CloseDroptarget");
00407 }
00408 setVisible( false );
00409 }
00410
00411 #include "droptarget.moc"