Fix system-tray...
[kdenetwork.git] / kget / mainwindow.cpp
blob76f3007e7241f770d37797bb5dd8aed564477cda
1 /* This file is part of the KDE project
3 Copyright (C) 2002 by Patrick Charbonnier <pch@freeshell.org>
4 Based On Caitoo v.0.7.3 (c) 1998 - 2000, Matej Koss
5 Copyright (C) 2002 Carsten Pfeiffer <pfeiffer@kde.org>
6 Copyright (C) 2006, 2007 Urs Wolfer <uwolfer @ kde.org>
7 Copyright (C) 2006 Dario Massarin <nekkar@libero.it>
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public
11 License as published by the Free Software Foundation; either
12 version 2 of the License, or (at your option) any later version.
15 #include "mainwindow.h"
17 #include "core/kget.h"
18 #include "core/transferhandler.h"
19 #include "core/transfergrouphandler.h"
20 #include "dbus/dbusmodelobserver.h"
21 #include "settings.h"
22 #include "conf/preferencesdialog.h"
23 #include "ui/viewscontainer.h"
24 #include "ui/tray.h"
25 #include "ui/droptarget.h"
26 #include "ui/newtransferdialog.h"
28 #include <kapplication.h>
29 #include <kstandarddirs.h>
30 #include <KInputDialog>
31 #include <kmessagebox.h>
32 #include <kshortcutsdialog.h>
33 #include <kedittoolbar.h>
34 #include <knotifyconfigwidget.h>
35 #include <kfiledialog.h>
36 #include <ktoolinvocation.h>
37 #include <kmenubar.h>
38 #include <kiconloader.h>
39 #include <kstandardaction.h>
40 #include <klocale.h>
41 #include <kicon.h>
42 #include <kactionmenu.h>
43 #include <krun.h>
45 #include <QtDBus>
46 #include <QClipboard>
47 #include <QTimer>
49 MainWindow::MainWindow(bool showMainwindow, bool startWithoutAnimation, QWidget *parent)
50 : KXmlGuiWindow( parent ),
51 m_drop(0), m_dock(0), m_startWithoutAnimation(startWithoutAnimation)
53 resize(720, 380); // have a reasonable initial size, will be overwritten later if the user changes it
55 // create the model
56 KGet::self( this );
58 // create actions
59 setupActions();
61 createGUI("kgetui.rc");
63 m_viewsContainer = new ViewsContainer(this);
64 // initialize the model observer to export percents over dbus
65 m_dbusModelObserver = new DBusModelObserver();
67 setCentralWidget(m_viewsContainer);
69 // restore position, size and visibility
70 move( Settings::mainPosition() );
71 setAutoSaveSettings();
72 setPlainCaption(i18n("KGet"));
74 if ( Settings::showMain() && showMainwindow)
75 show();
76 else
77 hide();
79 //Some of the widgets are initialized in slotDelayedInit()
80 QTimer::singleShot( 0, this, SLOT(slotDelayedInit()) );
83 MainWindow::~MainWindow()
85 //Save the user's transfers
86 KGet::save();
88 slotSaveMyself();
89 delete clipboardTimer;
90 delete m_drop;
91 delete m_dock;
92 // reset konqueror integration (necessary if user enabled / disabled temporarily integration from tray)
93 slotKonquerorIntegration( Settings::konquerorIntegration() );
94 // the following call saves options set in above dtors
95 Settings::self()->writeConfig();
99 void MainWindow::setupActions()
101 QAction *newDownloadAction = actionCollection()->addAction("new_download");
102 newDownloadAction->setText(i18n("&New Download..."));
103 newDownloadAction->setIcon(KIcon("document-new"));
104 newDownloadAction->setShortcuts(KShortcut("Ctrl+N"));
105 connect(newDownloadAction, SIGNAL(triggered()), SLOT(slotNewTransfer()));
107 QAction *openAction = actionCollection()->addAction("import_transfers");
108 openAction->setText(i18n("&Import Transfers..."));
109 openAction->setIcon(KIcon("document-open"));
110 openAction->setShortcuts(KShortcut("Ctrl+I"));
111 connect(openAction, SIGNAL(triggered()), SLOT(slotImportTransfers()));
113 QAction *exportAction = actionCollection()->addAction("export_transfers");
114 exportAction->setText(i18n("&Export Transfers List..."));
115 exportAction->setIcon(KIcon("document-export"));
116 exportAction->setShortcuts(KShortcut("Ctrl+E"));
117 connect(exportAction, SIGNAL(triggered()), SLOT(slotExportTransfers()));
119 QAction *deleteGroupAction = actionCollection()->addAction("delete_groups");
120 deleteGroupAction->setText(i18n("Delete Group"));
121 deleteGroupAction->setIcon(KIcon("edit-delete"));
122 connect(deleteGroupAction, SIGNAL(triggered()), SLOT(slotDeleteGroup()));
124 QAction *renameGroupAction = actionCollection()->addAction("rename_groups");
125 renameGroupAction->setText(i18n("Rename Group"));
126 renameGroupAction->setIcon(KIcon("edit-rename"));
127 connect(renameGroupAction, SIGNAL(triggered()), SLOT(slotRenameGroup()));
129 m_autoPasteAction = new KToggleAction(KIcon("edit-paste"),
130 i18n("Auto-Paste Mode"), actionCollection());
131 actionCollection()->addAction("auto_paste", m_autoPasteAction);
132 m_autoPasteAction->setChecked(Settings::autoPaste());
133 m_autoPasteAction->setWhatsThis(i18n("<b>Auto paste</b> button toggles the auto-paste mode "
134 "on and off.\nWhen set, KGet will periodically scan "
135 "the clipboard for URLs and paste them automatically."));
136 connect(m_autoPasteAction, SIGNAL(triggered()), SLOT(slotToggleAutoPaste()));
138 m_konquerorIntegration = new KToggleAction(KIcon("konqueror"),
139 i18n("Use KGet as Konqueror Download Manager"), actionCollection());
140 actionCollection()->addAction("konqueror_integration", m_konquerorIntegration);
141 connect(m_konquerorIntegration, SIGNAL(triggered(bool)), SLOT(slotTrayKonquerorIntegration(bool)));
142 m_konquerorIntegration->setChecked(Settings::konquerorIntegration());
144 // local - Destroys all sub-windows and exits
145 QAction *quitAction = KStandardAction::quit(this, SLOT(slotQuit()), actionCollection());
146 actionCollection()->addAction("quit", quitAction);
147 // local - Standard configure actions
148 QAction *preferencesAction = KStandardAction::preferences(this, SLOT(slotPreferences()), actionCollection());
149 actionCollection()->addAction("preferences", preferencesAction);
150 QAction *configToolbarAction = KStandardAction::configureToolbars(this, SLOT(slotConfigureToolbars()), actionCollection());
151 actionCollection()->addAction("configure_toolbars", configToolbarAction);
152 QAction *keyBindingsAction = KStandardAction::keyBindings(this, SLOT(slotConfigureKeys()), actionCollection());
153 actionCollection()->addAction("configure_keys", keyBindingsAction);
154 QAction *cinfigNotifyAction = KStandardAction::configureNotifications(this, SLOT(slotConfigureNotifications()), actionCollection());
155 actionCollection()->addAction("configure_notifications", cinfigNotifyAction);
156 m_menubarAction = KStandardAction::showMenubar(this, SLOT(slotShowMenubar()), actionCollection());
157 m_menubarAction->setChecked(!menuBar()->isHidden());
158 actionCollection()->addAction("settings_showmenubar", m_menubarAction);
160 // Transfer related actions
161 QAction *deleteSelectedAction = actionCollection()->addAction("delete_selected_download");
162 deleteSelectedAction->setText(i18n("Delete Selected"));
163 deleteSelectedAction->setIcon(KIcon("edit-delete"));
164 deleteSelectedAction->setShortcuts(KShortcut("Del"));
165 connect(deleteSelectedAction, SIGNAL(triggered()), SLOT(slotDeleteSelected()));
167 QAction *startAllAction = actionCollection()->addAction("start_all_download");
168 startAllAction->setText(i18n("Start / Resume All"));
169 startAllAction->setIcon(KIcon("media-seek-forward"));
170 startAllAction->setShortcuts(KShortcut("Ctrl+R"));
171 connect(startAllAction, SIGNAL(triggered()), SLOT(slotStartAllDownload()));
173 QAction *startSelectedAction = actionCollection()->addAction("start_selected_download");
174 startSelectedAction->setText(i18n("Start / Resume Selected"));
175 startSelectedAction->setIcon(KIcon("media-playback-start"));
176 connect(startSelectedAction, SIGNAL(triggered()), SLOT(slotStartSelectedDownload()));
178 QAction *stopAllAction = actionCollection()->addAction("stop_all_download");
179 stopAllAction->setText(i18n("Stop All"));
180 stopAllAction->setIcon(KIcon("media-playback-pause"));
181 stopAllAction->setShortcuts(KShortcut("Ctrl+P"));
182 connect(stopAllAction, SIGNAL(triggered()), SLOT(slotStopAllDownload()));
184 QAction *stopSelectedAction = actionCollection()->addAction("stop_selected_download");
185 stopSelectedAction->setText(i18n("Stop Selected"));
186 stopSelectedAction->setIcon(KIcon("media-playback-pause"));
187 connect(stopSelectedAction, SIGNAL(triggered()), SLOT(slotStopSelectedDownload()));
189 KActionMenu *startActionMenu = new KActionMenu(KIcon("media-playback-start"), i18n("Start / Resume"),
190 actionCollection());
191 actionCollection()->addAction("start_menu", startActionMenu);
192 startActionMenu->setDelayed(true);
193 startActionMenu->addAction(startAllAction);
194 startActionMenu->addAction(startSelectedAction);
195 connect(startActionMenu, SIGNAL(triggered()), SLOT(slotStartDownload()));
197 KActionMenu *stopActionMenu = new KActionMenu(KIcon("media-playback-pause"), i18n("Stop"),
198 actionCollection());
199 actionCollection()->addAction("stop_menu", stopActionMenu);
200 stopActionMenu->setDelayed(true);
201 stopActionMenu->addAction(stopAllAction);
202 stopActionMenu->addAction(stopSelectedAction);
203 connect(stopActionMenu, SIGNAL(triggered()), SLOT(slotStopDownload()));
205 QAction *openDestAction = actionCollection()->addAction("transfer_open_dest");
206 openDestAction->setText(i18n("Open Destination"));
207 openDestAction->setIcon(KIcon("document-open"));
208 connect(openDestAction, SIGNAL(triggered()), SLOT(slotTransfersOpenDest()));
210 QAction *showDetailsAction = actionCollection()->addAction("transfer_show_details");
211 showDetailsAction->setText(i18n("Show Details"));
212 showDetailsAction->setIcon(KIcon("document-properties"));
213 connect(showDetailsAction, SIGNAL(triggered()), SLOT(slotTransfersShowDetails()));
215 QAction *copyUrlAction = actionCollection()->addAction("transfer_copy_source_url");
216 copyUrlAction->setText(i18n("Copy URL to Clipboard"));
217 copyUrlAction->setIcon(KIcon("edit-copy"));
218 connect(copyUrlAction, SIGNAL(triggered()), SLOT(slotTransfersCopySourceUrl()));
220 KToggleAction *showDropTargetAction = new KToggleAction(KIcon("kget"),
221 i18n("Show Drop Target"), actionCollection());
222 actionCollection()->addAction("show_drop_target", showDropTargetAction);
223 showDropTargetAction->setChecked(Settings::showDropTarget());
224 connect(showDropTargetAction, SIGNAL(triggered()), SLOT(slotToggleDropTarget()));
227 void MainWindow::slotDelayedInit()
229 //Here we import the user's transfers.
230 KGet::load( KStandardDirs::locateLocal("appdata", "transfers.kgt") );
232 m_dock = new Tray(this);
233 if(Settings::enableSystemTray()) {
234 // DockWidget
235 m_dock->show();
238 // enable dropping
239 setAcceptDrops(true);
241 // enable hide toolbar
242 setStandardToolBarMenuEnabled(true);
244 // session management stuff
245 connect(kapp, SIGNAL(saveYourself()), SLOT(slotSaveMyself()));
247 // set auto-resume in kioslaverc (is there a cleaner way?)
248 KConfig cfg("kioslaverc", KConfig::NoGlobals);
249 cfg.group(QString()).writeEntry("AutoResume", true);
250 cfg.sync();
252 // immediately start downloading if configured this way
253 if ( Settings::downloadAtStartup() )
254 slotStartDownload();
256 // DropTarget
257 m_drop = new DropTarget(this);
259 if (Settings::firstRun()) {
260 if (KMessageBox::questionYesNoCancel(this ,i18n("This is the first time you have run KGet.\n"
261 "Would you like to enable KGet as the download manager for Konqueror?"),
262 i18n("Konqueror Integration"), KGuiItem(i18n("Enable")),
263 KGuiItem(i18n("Do Not Enable")))
264 == KMessageBox::Yes) {
265 Settings::setKonquerorIntegration(true);
266 slotKonquerorIntegration(true);
269 m_drop->setVisible(true);
271 // reset the FirstRun config option
272 Settings::setFirstRun(false);
275 if (Settings::showDropTarget() && !m_startWithoutAnimation)
276 m_drop->setVisible(true);
278 //auto paste stuff
279 lastClipboard = QApplication::clipboard()->text( QClipboard::Clipboard ).trimmed();
280 clipboardTimer = new QTimer(this);
281 connect(clipboardTimer, SIGNAL(timeout()), SLOT(slotCheckClipboard()));
282 if ( Settings::autoPaste() )
283 clipboardTimer->start(1000);
286 void MainWindow::slotToggleDropTarget()
288 actionCollection()->action("show_drop_target")->setChecked(!m_drop->isVisible());
290 m_drop->setVisible(!m_drop->isVisible());
293 void MainWindow::slotNewTransfer()
295 NewTransferDialog::showNewTransferDialog();
298 void MainWindow::slotImportTransfers()
300 QString filename = KFileDialog::getOpenFileName(KUrl(),
301 "*.kgt *.metalink|" + i18n("All Openable Files") +
302 " (*.kgt *.metalink)", this, i18n("Open File"));
304 if(filename.endsWith(".kgt"))
306 KGet::load(filename);
307 return;
310 if(!filename.isEmpty())
311 KGet::addTransfer( KUrl( filename ) );
314 void MainWindow::slotQuit()
316 if (KGet::schedulerRunning()) {
317 if (KMessageBox::warningYesNoCancel(this,
318 i18n("Some transfers are still running.\n"
319 "Are you sure you want to close KGet?"),
320 i18n("Confirm Quit"),
321 KStandardGuiItem::yes(), KStandardGuiItem::no(), KStandardGuiItem::cancel(),
322 "ExitWithActiveTransfers") != KMessageBox::Yes)
323 return;
325 KGet::setSchedulerRunning(false);
328 Settings::self()->writeConfig();
329 qApp->quit();
332 void MainWindow::slotPreferences()
334 // an instance the dialog could be already created and could be cached,
335 // in which case you want to display the cached dialog
336 if ( PreferencesDialog::showDialog( "preferences" ) )
337 return;
339 // we didn't find an instance of this dialog, so lets create it
340 PreferencesDialog * dialog = new PreferencesDialog( this, Settings::self() );
341 KGet::setPluginsSettingsWidget( dialog->pluginsWidget() );
342 // keep us informed when the user changes settings
343 connect( dialog, SIGNAL(settingsChanged(const QString&)),
344 this, SLOT(slotNewConfig()) );
346 dialog->show();
349 void MainWindow::slotExportTransfers()
351 QString filename = KFileDialog::getSaveFileName
352 (KUrl(),
353 "*.kgt|" + i18n("KGet Transfer List") + " (*.kgt)",
354 this,
355 i18n("Export Transfers")
358 if(!filename.isEmpty())
359 KGet::save(filename);
362 void MainWindow::slotDeleteGroup()
364 foreach(TransferGroupHandler * it, KGet::selectedTransferGroups())
366 it->stop();
367 KGet::delGroup(it->name());
371 void MainWindow::slotRenameGroup()
373 bool ok = true;
374 QString groupName;
376 foreach(TransferGroupHandler * it, KGet::selectedTransferGroups())
378 groupName = KInputDialog::getText(i18n("Enter Group Name"),
379 i18n("Group name:"), it->name(), &ok, this);
380 if(ok)
381 it->setName(groupName);
385 void MainWindow::slotStartDownload()
387 if(KGet::selectedTransfers().size() == 0)
388 slotStartAllDownload();
389 else
390 slotStartSelectedDownload();
393 void MainWindow::slotStartAllDownload()
395 bool running;
396 foreach (TransferHandler *handler, KGet::allTransfers())
398 if (handler->statusText() == "Running")
399 running = true;
401 if (running)
403 kDebug(5001);
404 setTrayDownloading(true);
405 continue;
409 KGet::setSchedulerRunning(true);
412 void MainWindow::slotStartSelectedDownload()
414 if (KGet::selectedTransfers().isEmpty())
415 return;
417 bool downloading = false;
418 foreach(TransferHandler * it, KGet::selectedTransfers())
420 if (it->status() != Job::Finished)
422 it->start();
423 downloading = true;
427 if (downloading)
428 m_dock->setDownloading(true);
431 void MainWindow::slotStopDownload()
433 if(KGet::selectedTransfers().size() == 0)
434 slotStopAllDownload();
435 else
436 slotStopSelectedDownload();
439 void MainWindow::slotStopAllDownload()
441 m_dock->setDownloading(false);
443 KGet::setSchedulerRunning(false);
446 void MainWindow::slotStopSelectedDownload()
448 m_dock->setDownloading(false);
450 foreach(TransferHandler * it, KGet::selectedTransfers())
451 it->stop();
454 void MainWindow::slotDeleteSelected()
456 foreach(TransferHandler * it, KGet::selectedTransfers())
458 it->stop();
459 m_viewsContainer->closeTransferDetails(it);
460 KGet::delTransfer(it);
464 void MainWindow::slotTransfersOpenDest()
466 QStringList openedDirs;
467 foreach(TransferHandler * it, KGet::selectedTransfers())
469 QString directory = it->dest().directory();
470 if( !openedDirs.contains( directory ) )
472 new KRun(directory, this, 0, true, false);
473 openedDirs.append( directory );
478 void MainWindow::slotTransfersShowDetails()
480 foreach(TransferHandler * it, KGet::selectedTransfers())
482 m_viewsContainer->showTransferDetails(it);
486 void MainWindow::slotTransfersCopySourceUrl()
488 foreach(TransferHandler * it, KGet::selectedTransfers())
490 QString sourceurl = it->source().url();
491 QClipboard *cb = QApplication::clipboard();
492 cb->setText(sourceurl, QClipboard::Selection);
493 cb->setText(sourceurl, QClipboard::Clipboard);
497 void MainWindow::slotConfigureNotifications()
499 KNotifyConfigWidget::configure(this);
502 void MainWindow::slotConfigureKeys()
504 KShortcutsDialog::configure(actionCollection());
507 void MainWindow::slotConfigureToolbars()
509 KEditToolBar edit( actionCollection() );
510 connect(&edit, SIGNAL( newToolbarConfig() ), this, SLOT( slotNewToolbarConfig() ));
511 edit.exec();
515 void MainWindow::slotSaveMyself()
517 // save last parameters ..
518 Settings::setMainPosition( pos() );
519 // .. and write config to disk
520 Settings::self()->writeConfig();
523 void MainWindow::slotNewToolbarConfig()
525 createGUI();
528 void MainWindow::slotNewConfig()
530 // Update here properties modified in the config dialog and not
531 // parsed often by the code. When clicking Ok or Apply of
532 // PreferencesDialog, this function is called.
534 m_viewsContainer->setExpandableDetails(Settings::showExpandableTransferDetails());
535 m_drop->setVisible(Settings::showDropTarget(), false);
536 m_dock->setVisible(Settings::enableSystemTray());
537 if(!Settings::enableSystemTray()) setVisible(true);
539 slotKonquerorIntegration(Settings::konquerorIntegration());
540 m_konquerorIntegration->setChecked(Settings::konquerorIntegration());
542 if (Settings::autoPaste())
543 clipboardTimer->start(1000);
544 else
545 clipboardTimer->stop();
546 m_autoPasteAction->setChecked(Settings::autoPaste());
549 void MainWindow::slotToggleAutoPaste()
551 bool autoPaste = !Settings::autoPaste();
552 Settings::setAutoPaste( autoPaste );
554 if (autoPaste)
555 clipboardTimer->start(1000);
556 else
557 clipboardTimer->stop();
558 m_autoPasteAction->setChecked(autoPaste);
561 void MainWindow::slotCheckClipboard()
563 QString clipData = QApplication::clipboard()->text( QClipboard::Clipboard ).trimmed();
565 if (clipData != lastClipboard)
567 lastClipboard = clipData;
568 if (lastClipboard.isEmpty())
569 return;
571 KUrl url = KUrl(lastClipboard);
573 if (url.isValid() && !url.isLocalFile())
574 KGet::addTransfer( url );
578 void MainWindow::slotTrayKonquerorIntegration(bool enable)
580 slotKonquerorIntegration(enable);
581 if (!enable && Settings::konquerorIntegration() && !Settings::expertMode())
583 KMessageBox::information(this,
584 i18n("KGet has been temporarily disabled as download manager for Konqueror. "
585 "If you want to disable it forever, go to Settings->Advanced and disable \"Use "
586 "as download manager for Konqueror\"."),
587 i18n("Konqueror Integration disabled"),
588 "KonquerorIntegrationDisabled");
592 void MainWindow::slotKonquerorIntegration(bool konquerorIntegration)
594 KConfig cfgKonqueror("konquerorrc", KConfig::NoGlobals);
595 cfgKonqueror.group("HTML Settings").writeEntry("DownloadManager",
596 QString(konquerorIntegration ? "kget" : QString()));
597 cfgKonqueror.sync();
600 void MainWindow::slotShowMenubar()
602 if(m_menubarAction->isChecked())
603 menuBar()->show();
604 else
605 menuBar()->hide();
608 void MainWindow::setTrayDownloading(bool running)
610 m_dock->setDownloading(running);
613 /** widget events */
615 void MainWindow::closeEvent( QCloseEvent * e )
617 e->ignore();
618 if(!Settings::enableSystemTray()) {
619 slotQuit();
621 else {
622 hide();
626 void MainWindow::dragEnterEvent(QDragEnterEvent * event)
628 event->setAccepted(KUrl::List::canDecode(event->mimeData())
629 || event->mimeData()->hasText());
632 void MainWindow::dropEvent(QDropEvent * event)
634 KUrl::List list = KUrl::List::fromMimeData(event->mimeData());
635 QString str;
637 if (!list.isEmpty())
639 /**if (list.count() == 1 && list.first().url().endsWith(".kgt"))
641 int msgBoxResult = KMessageBox::questionYesNoCancel(this, "The dropped file is a KGet-Transferlist", "KGet",
642 KGuiItem(i18n("&Download"), KIcon("document-save")), KGuiItem(i18n("&Load transferlist"), KIcon("list-add")), KStandardGuiItem::cancel());
644 if (msgBoxResult == 3) //Download
645 NewTransferDialog::showNewTransferDialog(list.first().url());
646 if (msgBoxResult == 4) //Load
647 KGet::load(list.first().url());
649 else
650 {**/
651 if (list.count() == 1)
653 str = event->mimeData()->text();
654 NewTransferDialog::showNewTransferDialog(str);
656 else
657 NewTransferDialog::showNewTransferDialog(list);
660 else
662 NewTransferDialog::showNewTransferDialog();
667 /** DBUS interface */
669 void MainWindow::addTransfers(const QString& src, const QString& dest, bool start)
671 // split src for the case it is a QStringList (e.g. from konqueror plugin)
672 KGet::addTransfer(src.split(";"), dest, QString(), start);
675 bool MainWindow::dropTargetVisible() const
677 return m_drop->isVisible();
680 void MainWindow::setDropTargetVisible( bool setVisible )
682 if ( setVisible != Settings::showDropTarget() )
683 m_drop->setVisible( setVisible );
686 void MainWindow::setOfflineMode( bool offline )
688 KGet::setSchedulerRunning(offline);
691 bool MainWindow::offlineMode() const
693 return !KGet::schedulerRunning();
696 QVariantMap MainWindow::transfers() const
698 return m_dbusModelObserver->transfers();
701 int MainWindow::transfersSpeed() const
703 return m_dbusModelObserver->transfersSpeed();
706 #include "mainwindow.moc"