1 /***************************************************************************
2 *                                                                         *
3 *   This program is free software; you can redistribute it and/or modify  *
4 *   it under the terms of the GNU General Public License as published by  *
5 *   the Free Software Foundation; either version 3 of the License, or     *
6 *   (at your option) any later version.                                   *
7 *                                                                         *
8 ***************************************************************************/
9 
10 #include "MainWindow.h"
11 #include "Notification.h"
12 
13 #include <stdlib.h>
14 #include <string>
15 #include <iostream>
16 
17 #include <QPainter>
18 #include <QPushButton>
19 #include <QSize>
20 #include <QModelIndex>
21 #include <QItemSelectionModel>
22 #include <QtDebug>
23 #include <QTextCodec>
24 #include <QMessageBox>
25 #include <QClipboard>
26 #include <QKeyEvent>
27 #include <QProgressBar>
28 #include <QFileDialog>
29 #include <QRegExp>
30 #include <QDir>
31 #include <QInputDialog>
32 #include <QDockWidget>
33 #include <QLabel>
34 #include <QShortcut>
35 #include <QKeySequence>
36 #include <QToolButton>
37 #include <QRegExp>
38 #include <QTreeView>
39 #include <QMetaType>
40 #include <QTimer>
41 #include <QAction>
42 #include <QStatusBar>
43 
44 #include "ArenaWidgetManager.h"
45 #include "ArenaWidgetFactory.h"
46 #include "HubFrame.h"
47 #include "HubManager.h"
48 #include "HashProgress.h"
49 #include "PMWindow.h"
50 #include "TransferView.h"
51 #include "ShareBrowser.h"
52 #include "QuickConnect.h"
53 #include "SearchFrame.h"
54 #include "ADLS.h"
55 #include "CmdDebug.h"
56 #include "Settings.h"
57 #include "FavoriteHubs.h"
58 #include "PublicHubs.h"
59 #include "FavoriteUsers.h"
60 #include "DownloadQueue.h"
61 #include "FinishedTransfers.h"
62 #include "AntiSpamFrame.h"
63 #include "IPFilterFrame.h"
64 #include "ToolBar.h"
65 #include "Magnet.h"
66 #include "FileHasher.h"
67 #include "SpyFrame.h"
68 #include "SideBar.h"
69 #include "ActionCustomizer.h"
70 #include "MultiLineToolBar.h"
71 #include "IPFilter.h"
72 #include "SearchBlacklist.h"
73 #include "QueuedUsers.h"
74 #ifdef FREE_SPACE_BAR_C
75 #include "extra/freespace.h"
76 #endif
77 #ifdef USE_JS
78 #include "ScriptManagerDialog.h"
79 #include "scriptengine/ScriptConsole.h"
80 #include "scriptengine/ScriptEngine.h"
81 #endif
82 
83 #include "dcpp/ShareManager.h"
84 #include "dcpp/ConnectivityManager.h"
85 #include "dcpp/Singleton.h"
86 #include "dcpp/SettingsManager.h"
87 #include "WulforSettings.h"
88 #include "WulforUtil.h"
89 
90 using namespace std;
91 
92 class MainWindowPrivate {
93 public:
94         typedef QList<QAction*> ActionList;
95 
96         bool isUnload;
97         bool exitBegin;
98 
99         // position and geometry
100         bool showMax;
101         int w;
102         int h;
103         int xPos;
104         int yPos;
105 
106         // Widgets
107         QDockWidget *arena;
108         QDockWidget *transfer_dock;
109         QDockWidget *sideDock;
110 
111         ToolBar *fBar; //for actions
112         ToolBar *sBar; //for fast search
113 
114         LineEdit   *searchLineEdit;
115         QStringList core_msg_history;
116         QLabel *statusLabel;
117         QLabel *statusSPLabel;
118         QLabel *statusDLabel;
119         QLabel *statusTRLabel;
120         QLabel *msgLabel;
121         QProgressBar *progressSpace;
122         QProgressBar *progressHashing;
123         HashProgress *_progress_dialog; // Hashing progress dialog
124 
125         QMenu   *menuFile;
126         QAction *fileOpenMagnet;
127         QAction *fileFileListBrowser;
128         QAction *fileFileHasher;
129         QAction *fileFileListBrowserLocal;
130         QAction *fileFileListMatchAll;
131         QAction *fileRefreshShareHashProgress;
132         QAction *fileOpenLogFile;
133         QAction *fileOpenDownloadDirectory;
134         QAction *fileHideWindow;
135         QAction *fileQuit;
136 
137         QMenu   *menuHubs;
138         QAction *hubsHubReconnect;
139         QAction *hubsQuickConnect;
140         QAction *hubsFavoriteHubs;
141         QAction *hubsPublicHubs;
142         QAction *hubsFavoriteUsers;
143 
144         QMenu   *menuTools;
145         QAction *toolsSearch;
146         QAction *toolsADLS;
147         QAction *toolsCmdDebug;
148         QAction *toolsTransfers;
149         QAction *toolsDownloadQueue;
150         QAction *toolsQueuedUsers;
151         QAction *toolsFinishedDownloads;
152         QAction *toolsFinishedUploads;
153         QAction *toolsSpy;
154         QAction *toolsAntiSpam;
155         QAction *toolsIPFilter;
156         QAction *menuAwayAction;
157         QAction *toolsHubManager;
158         // submenu
159         QMenu   *menuAway;
160         QActionGroup *awayGroup;
161         QAction *toolsAwayOn;
162         QAction *toolsAwayOff;
163         QAction *toolsAutoAway;
164         // end
165         QAction *toolsHideProgressSpace;
166         QAction *toolsHideLastStatus;
167         QAction *toolsHideUsersStatisctics;
168         QAction *toolsCopyWindowTitle;
169         QAction *toolsOptions;
170 #ifdef USE_JS
171         QAction *toolsJS;
172         QAction *toolsJSConsole;
173         ScriptConsole *scriptConsole;
174 #endif
175         QAction *toolsSwitchSpeedLimit;
176 
177         QMenu   *menuPanels;
178         // submenu
179         QMenu   *sh_menu;
180         // end
181         QAction *panelsWidgets;
182         QAction *panelsTools;
183         QAction *panelsSearch;
184 
185         // Standalone shortcuts
186         QAction *prevTabShortCut;
187         QAction *nextTabShortCut;
188         QAction *prevMsgShortCut;
189         QAction *nextMsgShortCut;
190         QAction *closeWidgetShortCut;
191         QAction *toggleMainMenuShortCut;
192 
193         QAction *chatDisable;
194         QAction *findInWidget;
195         QAction *chatClear;
196 
197         QMenu *menuWidgets;
198         QHash<QAction*, ArenaWidget*> menuWidgetsHash;
199 
200         QMenu   *menuAbout;
201         QAction *aboutHomepage;
202         QAction *aboutSource;
203         QAction *aboutIssues;
204         QAction *aboutWiki;
205         QAction *aboutChangelog;
206         QAction *aboutClient;
207         QAction *aboutQt;
208 
209         ActionList toolBarActions;
210         ActionList fileMenuActions;
211         ActionList hubsMenuActions;
212         ActionList toolsMenuActions;
213 
214         QMenu *favHubMenu;
215 };
216 
217 static const QString &TOOLBUTTON_STYLE = "mainwindow/toolbar-toolbutton-style";
218 static const QString &EMPTY_SETTINGS = "mainwindow/empty-settings";
219 static const QString &SIDEBAR_SHOW_CLOSEBUTTONS = "mainwindow/sidebar-with-close-buttons";
220 
MainWindow(QWidget * parent)221 MainWindow::MainWindow (QWidget *parent):
222         QMainWindow(parent),
223         d_ptr(new MainWindowPrivate())
224 {
225     Q_D(MainWindow);
226 
227     d->statusLabel = NULL;
228     d->fBar = NULL;
229     d->sBar = NULL;
230     d->_progress_dialog = NULL;
231     d->sideDock = NULL;
232     d->menuPanels = NULL;
233 #ifdef USE_JS
234     d->scriptConsole = NULL;
235 #endif
236     d->favHubMenu = NULL;
237 
238     d->exitBegin = false;
239 
240     if (WBGET(WB_ANTISPAM_ENABLED)){
241         AntiSpam::newInstance();
242 
243         AntiSpam::getInstance()->loadLists();
244         AntiSpam::getInstance()->loadSettings();
245     }
246 
247     if (WBGET(WB_IPFILTER_ENABLED)){
248         IPFilter::newInstance();
249 
250         IPFilter::getInstance()->loadList();
251     }
252 
253     ShortcutManager::newInstance();
254 
255     init();
256 
257     retranslateUi();
258 
259     LogManager::getInstance()->addListener(this);
260     TimerManager::getInstance()->addListener(this);
261     QueueManager::getInstance()->addListener(this);
262 
263     startSocket(false);
264 
265     setStatusMessage(tr("Ready"));
266 
267     TransferView::newInstance();
268 
269     d->transfer_dock->setWidget(TransferView::getInstance());
270     d->toolsTransfers->setChecked(d->transfer_dock->isVisible());
271 
272     QFont f;
273 
274     if (!WSGET(WS_APP_FONT).isEmpty() && f.fromString(WSGET(WS_APP_FONT)))
275         qApp->setFont(f);
276 
277     if (!WSGET(WS_APP_THEME).isEmpty())
278         qApp->setStyle(WSGET(WS_APP_THEME));
279 
280     if (WBGET(WB_APP_REMOVE_NOT_EX_DIRS)){
281         StringPairList directories = ShareManager::getInstance()->getDirectories();
282         for (const auto &it : directories){
283             QDir dir(_q(it.second));
284 
285             if (!dir.exists()){
286                 try {
287                     ShareManager::getInstance()->removeDirectory(it.second);
288                 }
289                 catch (const std::exception&){}
290             }
291         }
292     }
293 
294 }
295 
progress_dialog()296 HashProgress* MainWindow::progress_dialog() {
297     Q_D(MainWindow);
298 
299     if (!d->_progress_dialog)
300         d->_progress_dialog = new HashProgress(this);
301 
302     return d->_progress_dialog;
303 }
304 
~MainWindow()305 MainWindow::~MainWindow(){
306     LogManager::getInstance()->removeListener(this);
307     TimerManager::getInstance()->removeListener(this);
308     QueueManager::getInstance()->removeListener(this);
309 
310     if (AntiSpam::getInstance()){
311         AntiSpam::getInstance()->saveLists();
312         AntiSpam::getInstance()->saveSettings();
313         AntiSpam::deleteInstance();
314     }
315 
316     Q_D(MainWindow);
317 
318     delete d->arena;
319     delete d->fBar;
320     delete d->sBar;
321 
322     ShortcutManager::deleteInstance();
323     SearchBlacklist::deleteInstance();
324 
325     delete d_ptr;
326 }
327 
setUnload(bool b)328 void MainWindow::setUnload ( bool b ) {
329     Q_D(MainWindow);
330 
331     d->isUnload = b;
332 }
333 
closeEvent(QCloseEvent * c_e)334 void MainWindow::closeEvent(QCloseEvent *c_e){
335     Q_D(MainWindow);
336 
337 #if defined(Q_WS_MAC)
338     if (!d->isUnload){
339 #else // defined(Q_WS_MAC)
340     if (!d->isUnload && WBGET(WB_TRAY_ENABLED)){
341 #endif // defined(Q_WS_MAC)
342         hide();
343         c_e->ignore();
344 
345         return;
346     }
347 
348     if (d->isUnload && WBGET(WB_EXIT_CONFIRM) && !d->exitBegin){
349         QMessageBox::StandardButton ret;
350 
351         ret = QMessageBox::question(this, tr("Exit confirm"),
352                                     tr("Exit program?"),
353                                     QMessageBox::Yes | QMessageBox::No,
354                                     QMessageBox::Yes);
355 
356         if (ret == QMessageBox::Yes){
357             d->exitBegin = true;
358         }
359         else{
360             setUnload(false);
361 
362             c_e->ignore();
363 
364             return;
365         }
366     }
367 
368     saveSettings();
369 
370     if (WBGET("app/clear-search-history-on-exit", false))
371         WSSET(WS_SEARCH_HISTORY, "");
372     if (WBGET("app/clear-download-directories-history-on-exit", false))
373         WSSET(WS_DOWNLOAD_DIR_HISTORY, "");
374 
375     if (d->sideDock)
376         d->sideDock->hide();
377 
378     d->transfer_dock->hide();
379 
380     blockSignals(true);
381 
382     if (TransferView::getInstance()){
383         TransferView::getInstance()->close();
384         TransferView::deleteInstance();
385     }
386 
387     if (SearchManager::getInstance())
388         SearchManager::getInstance()->disconnect();
389 
390     if (ConnectionManager::getInstance())
391         ConnectionManager::getInstance()->disconnect();
392 
393     if (Notification::getInstance())
394         Notify->enableTray(false);
395 
396     d->arena->hide();
397     d->arena->setWidget(NULL);
398 
399     c_e->accept();
400 }
401 
402 void MainWindow::beginExit(){
403     Q_D(MainWindow);
404 
405     d->exitBegin = true;
406 
407     setUnload(true);
408 }
409 
410 void MainWindow::show(){
411     Q_D(MainWindow);
412 
413     if (d->showMax)
414         showMaximized();
415     else
416         showNormal();
417 }
418 
419 void MainWindow::showEvent(QShowEvent *e){
420     Q_D(MainWindow);
421 
422     if (!d->showMax && d->w > 0 && d->h > 0 && d->w != width() && d->h != height())
423         this->resize(QSize(d->w, d->h));
424 
425     if (WBGET(WB_APP_AUTO_AWAY) && !Util::getManualAway()){
426         Util::setAway(false);
427 
428         d->toolsAwayOff->setChecked(true);
429     }
430 
431     if (d->transfer_dock->isVisible())
432         d->toolsTransfers->setChecked(true);
433 
434     if (d->sideDock)
435         d->sideDock->setVisible(d->panelsWidgets->isChecked());
436 
437     ArenaWidget *awgt = qobject_cast<ArenaWidget*>(d->arena->widget());
438 
439     if (!awgt)
440         return;
441 
442     ArenaWidget::Role role = awgt->role();
443 
444     bool widgetWithFilter = role == ArenaWidget::Hub ||
445                             role == ArenaWidget::PrivateMessage ||
446                             role == ArenaWidget::ShareBrowser ||
447                             role == ArenaWidget::PublicHubs ||
448                             role == ArenaWidget::Search;
449 
450     d->chatClear->setEnabled(role == ArenaWidget::Hub || role == ArenaWidget::PrivateMessage);
451     d->findInWidget->setEnabled(widgetWithFilter);
452     d->chatDisable->setEnabled(role == ArenaWidget::Hub);
453 
454     if (_q(SETTING(NICK)).isEmpty()){
455         activateWindow();
456         raise();
457 
458         bool ok = false;
459         QString new_nick = QInputDialog::getText(this, tr("Enter user nick"), tr("Nick"), QLineEdit::Normal, tr("User"), &ok);
460 
461         if (ok && !new_nick.isEmpty()){
462             SettingsManager::getInstance()->set(SettingsManager::NICK, _tq(new_nick));
463 
464             ok = (QMessageBox::question(this, "EiskaltDC++", tr("Would you like to change other settings?"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::No);
465         }
466 
467         if (!ok)
468             slotToolsSettings();
469     }
470 
471     e->accept();
472 }
473 
474 void MainWindow::getWindowGeometry(){
475     Q_D(MainWindow);
476 
477     d->showMax = isMaximized();
478 
479     if (!d->showMax){
480         d->h = height();
481         d->w = width();
482         d->xPos = x();
483         d->yPos = y();
484     }
485 }
486 
487 void MainWindow::hideEvent(QHideEvent *e){
488     Q_D(MainWindow);
489 
490     getWindowGeometry();
491 
492     e->accept();
493 
494     if (d->sideDock && d->sideDock->isFloating())
495         d->sideDock->hide();
496 
497     if (WBGET(WB_APP_AUTO_AWAY)){
498         Util::setAway(true);
499 
500         d->toolsAwayOn->setChecked(true);
501     }
502 }
503 
504 bool MainWindow::eventFilter(QObject *obj, QEvent *e){
505     Q_D(MainWindow);
506 
507     if (e->type() == QEvent::WindowActivate) {
508         redrawToolPanel();
509     }
510     else if( obj == d->progressHashing && e->type() == QEvent::MouseButtonDblClick ) {
511         slotFileHashProgress();
512 
513         return true;
514     }
515     else if (obj == d->progressSpace && e->type() == QEvent::MouseButtonDblClick ){
516         slotFileOpenDownloadDirectory();
517 
518         return true;
519     }
520 
521     return QMainWindow::eventFilter(obj, e);
522 }
523 
524 void MainWindow::init(){
525     Q_D(MainWindow);
526 
527     setObjectName("MainWindow");
528 
529     connect(this, SIGNAL(coreLogMessage(QString)), this, SLOT(setStatusMessage(QString)), Qt::QueuedConnection);
530     connect(this, SIGNAL(coreOpenShare(dcpp::UserPtr,QString,QString)), this, SLOT(showShareBrowser(dcpp::UserPtr,QString,QString)), Qt::QueuedConnection);
531     connect(this, SIGNAL(coreUpdateStats(QMap<QString,QString>)), this, SLOT(updateStatus(QMap<QString,QString>)), Qt::QueuedConnection);
532 
533     d->arena = new QDockWidget();
534     d->arena->setWidget(NULL);
535     d->arena->setFloating(false);
536     d->arena->setContentsMargins(0, 0, 0, 0);
537     d->arena->setAllowedAreas(Qt::RightDockWidgetArea);
538     d->arena->setFeatures(QDockWidget::NoDockWidgetFeatures);
539     d->arena->setContextMenuPolicy(Qt::CustomContextMenu);
540     d->arena->setTitleBarWidget(new QWidget(d->arena));
541     d->arena->setMinimumSize( 10, 10 );
542 
543     d->transfer_dock = new QDockWidget(this);
544     d->transfer_dock->setWidget(NULL);
545     d->transfer_dock->setFloating(false);
546     d->transfer_dock->setObjectName("transfer_dock");
547     d->transfer_dock->setAllowedAreas(Qt::BottomDockWidgetArea);
548     d->transfer_dock->setFeatures(QDockWidget::NoDockWidgetFeatures);
549     d->transfer_dock->setContextMenuPolicy(Qt::CustomContextMenu);
550     d->transfer_dock->setTitleBarWidget(new QWidget(d->transfer_dock));
551     d->transfer_dock->setMinimumSize(QSize(8, 8));
552 
553     setCentralWidget(d->arena);
554     //addDockWidget(Qt::RightDockWidgetArea, arena);
555     addDockWidget(Qt::BottomDockWidgetArea, d->transfer_dock);
556 
557     d->transfer_dock->hide();
558 
559     this->setWindowIcon(WICON(WulforUtil::eiICON_APPL));
560 
561     setWindowTitle(QString("%1").arg(EISKALTDCPP_WND_TITLE));
562 
563     initActions();
564 
565     initMenuBar();
566 #if defined(Q_WS_MAC)
567     initDockMenuBar();
568 #endif
569 
570     initStatusBar();
571 
572     initSearchBar();
573 
574     initToolbar();
575 
576     initSideBar();
577 
578     loadSettings();
579 
580     connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(slotExit()));
581 
582     connect(ArenaWidgetManager::getInstance(), SIGNAL(activated(ArenaWidget*)), this, SLOT(mapWidgetOnArena(ArenaWidget*)));
583     connect(ArenaWidgetManager::getInstance(), SIGNAL(added(ArenaWidget*)),     this, SLOT(insertWidget(ArenaWidget*)));
584     connect(ArenaWidgetManager::getInstance(), SIGNAL(removed(ArenaWidget*)),   this, SLOT(removeWidget(ArenaWidget*)));
585     connect(ArenaWidgetManager::getInstance(), SIGNAL(updated(ArenaWidget*)),   this, SLOT(updated(ArenaWidget*)));
586 
587 #ifdef LUA_SCRIPT
588     ScriptManager::getInstance()->load();
589     if (BOOLSETTING(USE_LUA)){
590         // Start as late as possible, as we might (formatting.lua) need to examine settings
591         string defaultluascript="startup.lua";
592         ScriptManager::getInstance()->EvaluateFile(defaultluascript);
593     }
594 #endif
595 }
596 
597 void MainWindow::loadSettings(){
598     Q_D(MainWindow);
599     WulforSettings *WS = WulforSettings::getInstance();
600 
601     d->showMax = WS->getBool(WB_MAINWINDOW_MAXIMIZED);
602     d->w = WS->getInt(WI_MAINWINDOW_WIDTH);
603     d->h = WS->getInt(WI_MAINWINDOW_HEIGHT);
604     d->xPos = WS->getInt(WI_MAINWINDOW_X);
605     d->yPos = WS->getInt(WI_MAINWINDOW_Y);
606 
607     QPoint p(d->xPos, d->yPos);
608     QSize  sz(d->w, d->h);
609 
610     if (p.x() >= 0 && p.y() >= 0)
611         this->move(p);
612 
613     if (sz.width() > 0 && sz.height() > 0)
614         this->resize(sz);
615 
616     QString dockwidgetsState = WSGET(WS_MAINWINDOW_STATE);
617 
618     if (!dockwidgetsState.isEmpty())
619         this->restoreState(QByteArray::fromBase64(dockwidgetsState.toUtf8()));
620 
621     d->fBar->setVisible(WBGET(WB_TOOLS_PANEL_VISIBLE));
622     d->panelsTools->setChecked(WBGET(WB_TOOLS_PANEL_VISIBLE));
623 
624     d->sBar->setVisible(WBGET(WB_SEARCH_PANEL_VISIBLE));
625     d->panelsSearch->setChecked(WBGET(WB_SEARCH_PANEL_VISIBLE));
626 
627     if (d->sideDock){
628         if (d->sideDock->isFloating() && WBGET(WB_MAINWINDOW_HIDE) && WBGET(WB_TRAY_ENABLED))
629             d->sideDock->hide();
630         else
631             d->sideDock->setVisible(WBGET(WB_WIDGETS_PANEL_VISIBLE));
632     } else if ( findChild<MultiLineToolBar*> ( "multiLineTabbar" ) ) {
633         findChild<MultiLineToolBar*> ( "multiLineTabbar" )->setVisible ( WBGET ( WB_WIDGETS_PANEL_VISIBLE ) );
634     } else if ( findChild<ToolBar*> ( "tBar" ) ) {
635         findChild<ToolBar*> ( "tBar" )->setVisible ( WBGET ( WB_WIDGETS_PANEL_VISIBLE ) );
636     }
637 
638     d->panelsWidgets->setChecked(WBGET(WB_WIDGETS_PANEL_VISIBLE));
639 
640     if (!WBGET(WB_MAIN_MENU_VISIBLE))
641         toggleMainMenu(false);
642 
643     if (WBGET("mainwindow/dont-show-icons-in-menus", false))
644         qApp->setAttribute(Qt::AA_DontShowIconsInMenus);
645 }
646 
647 void MainWindow::saveSettings(){
648     Q_D(MainWindow);
649     static bool stateIsSaved = false;
650 
651     if (stateIsSaved)
652         return;
653 
654     if (isVisible())
655         d->showMax = isMaximized();
656 
657     WBSET(WB_MAINWINDOW_MAXIMIZED, d->showMax);
658 
659     if (!d->showMax && height() > 0 && width() > 0){
660         WISET(WI_MAINWINDOW_HEIGHT, height());
661         WISET(WI_MAINWINDOW_WIDTH, width());
662     }
663     else{
664         WISET(WI_MAINWINDOW_HEIGHT, d->h);
665         WISET(WI_MAINWINDOW_WIDTH, d->w);
666     }
667 
668     if (!d->showMax && x() >= 0 && y() >= 0){
669         WISET(WI_MAINWINDOW_X, x());
670         WISET(WI_MAINWINDOW_Y, y());
671     }
672     else{
673         WISET(WI_MAINWINDOW_X, d->xPos);
674         WISET(WI_MAINWINDOW_Y, d->yPos);
675     }
676 
677     if (WBGET(WB_MAINWINDOW_REMEMBER))
678         WBSET(WB_MAINWINDOW_HIDE, !isVisible());
679 
680     QString dockwidgetsState = QString::fromUtf8(saveState().toBase64());
681     WSSET(WS_MAINWINDOW_STATE, dockwidgetsState);
682 
683     stateIsSaved = true;
684 }
685 
686 void MainWindow::initActions(){
687     Q_D(MainWindow);
688 
689     WulforUtil *WU = WulforUtil::getInstance();
690     ShortcutManager *SM = ShortcutManager::getInstance();
691 
692     {
693         d->fileOpenMagnet = new QAction("", this);
694         d->fileOpenMagnet->setObjectName("fileOpenMagnet");
695         SM->registerShortcut(d->fileOpenMagnet, tr("Ctrl+I"));
696         d->fileOpenMagnet->setIcon(WU->getPixmap(WulforUtil::eiDOWNLOAD));
697         connect(d->fileOpenMagnet, SIGNAL(triggered()), this, SLOT(slotOpenMagnet()));
698 
699         d->fileFileListBrowserLocal = new QAction("", this);
700         d->fileFileListBrowserLocal->setObjectName("fileFileListBrowserLocal");
701         SM->registerShortcut(d->fileFileListBrowserLocal, tr("Ctrl+L"));
702         d->fileFileListBrowserLocal->setIcon(WU->getPixmap(WulforUtil::eiOWN_FILELIST));
703         connect(d->fileFileListBrowserLocal, SIGNAL(triggered()), this, SLOT(slotFileBrowseOwnFilelist()));
704 
705         d->fileFileListBrowser = new QAction("", this);
706         d->fileFileListBrowser->setObjectName("fileFileListBrowser");
707         d->fileFileListBrowser->setIcon(WU->getPixmap(WulforUtil::eiOPENLIST));
708         connect(d->fileFileListBrowser, SIGNAL(triggered()), this, SLOT(slotFileBrowseFilelist()));
709 
710         d->fileFileListMatchAll = new QAction("", this);
711         d->fileFileListMatchAll->setObjectName("fileFileListMatchAll");
712         //d->fileFileListMatchAll->setIcon(WU->getPixmap(WulforUtil::eiOPENLIST));
713         connect(d->fileFileListMatchAll, SIGNAL(triggered()), this, SLOT(slotFileMatchAllList()));
714 
715         d->fileFileHasher = new QAction("", this);
716         d->fileFileHasher->setObjectName("fileFileHasher");
717         d->fileFileHasher->setIcon(WU->getPixmap(WulforUtil::eiOPENLIST));
718         connect(d->fileFileHasher, SIGNAL(triggered()), this, SLOT(slotFileHasher()));
719 
720         d->fileOpenLogFile = new QAction("", this);
721         d->fileOpenLogFile->setObjectName("fileOpenLogFile");
722         d->fileOpenLogFile->setIcon(WU->getPixmap(WulforUtil::eiOPEN_LOG_FILE));
723         connect(d->fileOpenLogFile, SIGNAL(triggered()), this, SLOT(slotFileOpenLogFile()));
724 
725         d->fileOpenDownloadDirectory = new QAction("", this);
726         d->fileOpenDownloadDirectory->setObjectName("fileOpenDownloadDirectory");
727         d->fileOpenDownloadDirectory->setIcon(WU->getPixmap(WulforUtil::eiFOLDER_BLUE));
728         connect(d->fileOpenDownloadDirectory, SIGNAL(triggered()), this, SLOT(slotFileOpenDownloadDirectory()));
729 
730         d->fileRefreshShareHashProgress = new QAction("", this);
731         d->fileRefreshShareHashProgress->setObjectName("fileRefreshShareHashProgress");
732         SM->registerShortcut(d->fileRefreshShareHashProgress, tr("Ctrl+E"));
733         d->fileRefreshShareHashProgress->setIcon(WU->getPixmap(WulforUtil::eiHASHING));
734         connect(d->fileRefreshShareHashProgress, SIGNAL(triggered()), this, SLOT(slotFileRefreshShareHashProgress()));
735 
736         d->fileHideWindow = new QAction("", this);
737         d->fileHideWindow->setObjectName("fileHideWindow");
738         SM->registerShortcut(d->fileHideWindow, tr("Ctrl+Alt+H"));
739         d->fileHideWindow->setIcon(WU->getPixmap(WulforUtil::eiHIDEWINDOW));
740         connect(d->fileHideWindow, SIGNAL(triggered()), this, SLOT(slotHideWindow()));
741 
742         d->fileQuit = new QAction("", this);
743         d->fileQuit->setObjectName("fileQuit");
744         SM->registerShortcut(d->fileQuit, tr("Ctrl+Q"));
745         d->fileQuit->setMenuRole(QAction::QuitRole);
746         d->fileQuit->setIcon(WU->getPixmap(WulforUtil::eiEXIT));
747         connect(d->fileQuit, SIGNAL(triggered()), this, SLOT(slotExit()));
748 
749         d->hubsHubReconnect = new QAction("", this);
750         d->hubsHubReconnect->setObjectName("hubsHubReconnect");
751         SM->registerShortcut(d->hubsHubReconnect, tr("Ctrl+R"));
752         d->hubsHubReconnect->setIcon(WU->getPixmap(WulforUtil::eiRECONNECT));
753         connect(d->hubsHubReconnect, SIGNAL(triggered()), this, SLOT(slotHubsReconnect()));
754 
755         d->hubsQuickConnect = new QAction("", this);
756         d->hubsQuickConnect->setObjectName("hubsQuickConnect");
757         SM->registerShortcut(d->hubsQuickConnect, tr("Ctrl+N"));
758         d->hubsQuickConnect->setIcon(WU->getPixmap(WulforUtil::eiCONNECT));
759         connect(d->hubsQuickConnect, SIGNAL(triggered()), this, SLOT(slotQC()));
760 
761         d->hubsFavoriteHubs = new QAction("", this);
762         d->hubsFavoriteHubs->setObjectName("hubsFavoriteHubs");
763         SM->registerShortcut(d->hubsFavoriteHubs, tr("Ctrl+H"));
764         d->hubsFavoriteHubs->setIcon(WU->getPixmap(WulforUtil::eiFAVSERVER));
765         connect(d->hubsFavoriteHubs, SIGNAL(triggered()), this, SLOT(slotHubsFavoriteHubs()));
766 
767         d->hubsPublicHubs = new QAction("", this);
768         d->hubsPublicHubs->setObjectName("hubsPublicHubs");
769         SM->registerShortcut(d->hubsPublicHubs, tr("Ctrl+P"));
770         d->hubsPublicHubs->setIcon(WU->getPixmap(WulforUtil::eiSERVER));
771         connect(d->hubsPublicHubs, SIGNAL(triggered()), this, SLOT(slotHubsPublicHubs()));
772 
773         d->hubsFavoriteUsers = new QAction("", this);
774         d->hubsFavoriteUsers->setObjectName("hubsFavoriteUsers");
775         SM->registerShortcut(d->hubsFavoriteUsers, tr("Ctrl+U"));
776         d->hubsFavoriteUsers->setIcon(WU->getPixmap(WulforUtil::eiFAVUSERS));
777         connect(d->hubsFavoriteUsers, SIGNAL(triggered()), this, SLOT(slotHubsFavoriteUsers()));
778 
779         d->toolsHubManager = new QAction("", this);
780         d->toolsHubManager->setObjectName("toolsHubManager");
781         d->toolsHubManager->setIcon(WU->getPixmap(WulforUtil::eiSERVER));
782         connect(d->toolsHubManager, SIGNAL(triggered()), this, SLOT(slotToolsHubManager()));
783 
784         d->toolsCopyWindowTitle = new QAction("", this);
785         d->toolsCopyWindowTitle->setObjectName("toolsCopyWindowTitle");
786         d->toolsCopyWindowTitle->setIcon(WU->getPixmap(WulforUtil::eiEDITCOPY));
787         connect(d->toolsCopyWindowTitle, SIGNAL(triggered()), this, SLOT(slotToolsCopyWindowTitle()));
788 
789         d->toolsOptions = new QAction("", this);
790         d->toolsOptions->setObjectName("toolsOptions");
791         SM->registerShortcut(d->toolsOptions, tr("Ctrl+O"));
792         d->toolsOptions->setMenuRole(QAction::PreferencesRole);
793         d->toolsOptions->setIcon(WU->getPixmap(WulforUtil::eiCONFIGURE));
794         connect(d->toolsOptions, SIGNAL(triggered()), this, SLOT(slotToolsSettings()));
795 
796         d->toolsADLS = new QAction("", this);
797         d->toolsADLS->setObjectName("toolsADLS");
798         d->toolsADLS->setIcon(WU->getPixmap(WulforUtil::eiADLS));
799         connect(d->toolsADLS, SIGNAL(triggered()), this, SLOT(slotToolsADLS()));
800 
801         d->toolsCmdDebug = new QAction("", this);
802         d->toolsCmdDebug->setObjectName("toolsCmdDebug");
803         connect(d->toolsCmdDebug, SIGNAL(triggered()), this, SLOT(slotToolsCmdDebug()));
804 
805         d->toolsTransfers = new QAction("", this);
806         d->toolsTransfers->setObjectName("toolsTransfers");
807         SM->registerShortcut(d->toolsTransfers, tr("Ctrl+T"));
808         d->toolsTransfers->setIcon(WU->getPixmap(WulforUtil::eiTRANSFER));
809         d->toolsTransfers->setCheckable(true);
810         connect(d->toolsTransfers, SIGNAL(toggled(bool)), this, SLOT(slotToolsTransfer(bool)));
811         //transfer_dock->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
812 
813         d->toolsDownloadQueue = new QAction("", this);
814         d->toolsDownloadQueue->setObjectName("toolsDownloadQueue");
815         SM->registerShortcut(d->toolsDownloadQueue, tr("Ctrl+D"));
816         d->toolsDownloadQueue->setIcon(WU->getPixmap(WulforUtil::eiDOWNLOAD));
817         connect(d->toolsDownloadQueue, SIGNAL(triggered()), this, SLOT(slotToolsDownloadQueue()));
818 
819         d->toolsQueuedUsers = new QAction("", this);
820         d->toolsQueuedUsers->setObjectName("toolsQueuedUsers");
821         SM->registerShortcut(d->toolsQueuedUsers, tr("Ctrl+Shift+U"));
822         d->toolsQueuedUsers->setIcon(WU->getPixmap(WulforUtil::eiUSERS));
823         connect(d->toolsQueuedUsers, SIGNAL(triggered()), this, SLOT(slotToolsQueuedUsers()));
824 
825         d->toolsFinishedDownloads = new QAction("", this);
826         d->toolsFinishedDownloads->setObjectName("toolsFinishedDownloads");
827         SM->registerShortcut(d->toolsFinishedDownloads, tr("Ctrl+["));
828         d->toolsFinishedDownloads->setIcon(WU->getPixmap(WulforUtil::eiDOWNLIST));
829         connect(d->toolsFinishedDownloads, SIGNAL(triggered()), this, SLOT(slotToolsFinishedDownloads()));
830 
831         d->toolsFinishedUploads = new QAction("", this);
832         d->toolsFinishedUploads->setObjectName("toolsFinishedUploads");
833         SM->registerShortcut(d->toolsFinishedUploads, tr("Ctrl+]"));
834         d->toolsFinishedUploads->setIcon(WU->getPixmap(WulforUtil::eiUPLIST));
835         connect(d->toolsFinishedUploads, SIGNAL(triggered()), this, SLOT(slotToolsFinishedUploads()));
836 
837         d->toolsSpy = new QAction("", this);
838         d->toolsSpy->setObjectName("toolsSpy");
839         d->toolsSpy->setIcon(WU->getPixmap(WulforUtil::eiSPY));
840         connect(d->toolsSpy, SIGNAL(triggered()), this, SLOT(slotToolsSpy()));
841 
842         d->toolsAntiSpam = new QAction("", this);
843         d->toolsAntiSpam->setObjectName("toolsAntiSpam");
844         d->toolsAntiSpam->setIcon(WU->getPixmap(WulforUtil::eiSPAM));
845         d->toolsAntiSpam->setCheckable(true);
846         d->toolsAntiSpam->setChecked(AntiSpam::getInstance() != NULL);
847         connect(d->toolsAntiSpam, SIGNAL(triggered()), this, SLOT(slotToolsAntiSpam()));
848 
849         d->toolsIPFilter = new QAction("", this);
850         d->toolsIPFilter->setObjectName("toolsIPFilter");
851         d->toolsIPFilter->setIcon(WU->getPixmap(WulforUtil::eiFILTER));
852         d->toolsIPFilter->setCheckable(true);
853         d->toolsIPFilter->setChecked(IPFilter::getInstance() != NULL);
854         connect(d->toolsIPFilter, SIGNAL(triggered()), this, SLOT(slotToolsIPFilter()));
855 
856         d->toolsAwayOn = new QAction("", this);
857         d->toolsAwayOn->setObjectName("toolsAwayOn");
858         d->toolsAwayOn->setCheckable(true);
859         connect(d->toolsAwayOn, SIGNAL(triggered()), this, SLOT(slotToolsSwitchAway()));
860 
861         d->toolsAwayOff = new QAction("", this);
862         d->toolsAwayOff->setObjectName("toolsAwayOff");
863         d->toolsAwayOff->setCheckable(true);
864         connect(d->toolsAwayOff, SIGNAL(triggered()), this, SLOT(slotToolsSwitchAway()));
865 
866         d->toolsAutoAway = new QAction("", this);
867         d->toolsAutoAway->setCheckable(true);
868         d->toolsAutoAway->setChecked(WBGET(WB_APP_AUTO_AWAY));
869         connect(d->toolsAutoAway, SIGNAL(triggered()), this, SLOT(slotToolsAutoAway()));
870 
871 #ifdef USE_JS
872         d->toolsJS = new QAction("", this);
873         d->toolsJS->setObjectName("toolsJS");
874         d->toolsJS->setIcon(WU->getPixmap(WulforUtil::eiPLUGIN));
875         connect(d->toolsJS, SIGNAL(triggered()), this, SLOT(slotToolsJS()));
876 
877         d->toolsJSConsole = new QAction("", this);
878         d->toolsJSConsole->setObjectName("toolsJSConsole");
879         SM->registerShortcut(d->toolsJSConsole, tr("Ctrl+Alt+J"));
880         d->toolsJSConsole->setIcon(WU->getPixmap(WulforUtil::eiCONSOLE));
881         connect(d->toolsJSConsole, SIGNAL(triggered()), this, SLOT(slotToolsJSConsole()));
882 #endif
883 
884         d->menuAwayAction = new QAction("", this);
885         // submenu
886         QAction *away_sep = new QAction("", this);
887         away_sep->setSeparator(true);
888 
889         d->awayGroup = new QActionGroup(this);
890         d->awayGroup->addAction(d->toolsAwayOn);
891         d->awayGroup->addAction(d->toolsAwayOff);
892 
893         d->menuAway = new QMenu(this);
894         d->menuAway->addActions(QList<QAction*>() << d->toolsAwayOn << d->toolsAwayOff << away_sep << d->toolsAutoAway);
895         {
896             QAction *act = Util::getAway()? d->toolsAwayOn : d->toolsAwayOff;
897             act->setChecked(true);
898         }
899         // end
900         d->menuAwayAction->setMenu(d->menuAway);
901         d->menuAwayAction->setIcon(QIcon(WU->getPixmap(WulforUtil::eiAWAY)));
902 
903         d->toolsSearch = new QAction("", this);
904         d->toolsSearch->setObjectName("toolsSearch");
905         SM->registerShortcut(d->toolsSearch, tr("Ctrl+S"));
906         d->toolsSearch->setIcon(WU->getPixmap(WulforUtil::eiFILEFIND));
907         connect(d->toolsSearch, SIGNAL(triggered()), this, SLOT(slotToolsSearch()));
908 
909         d->toolsHideProgressSpace = new QAction("", this);
910         d->toolsHideProgressSpace->setObjectName("toolsHideProgressSpace");
911 
912 #if (!defined FREE_SPACE_BAR_C)
913         d->toolsHideProgressSpace->setVisible(false);
914 #endif
915         d->toolsHideProgressSpace->setIcon(WU->getPixmap(WulforUtil::eiFREESPACE));
916         connect(d->toolsHideProgressSpace, SIGNAL(triggered()), this, SLOT(slotHideProgressSpace()));
917 
918         d->toolsHideLastStatus = new QAction("", this);
919         d->toolsHideLastStatus->setObjectName("toolsHideLastStatus");
920         d->toolsHideLastStatus->setIcon(WU->getPixmap(WulforUtil::eiSTATUS));
921         connect(d->toolsHideLastStatus, SIGNAL(triggered()), this, SLOT(slotHideLastStatus()));
922 
923         d->toolsHideUsersStatisctics = new QAction("", this);
924         d->toolsHideUsersStatisctics->setObjectName("toolsHideUsersStatisctics");
925         d->toolsHideUsersStatisctics->setIcon(WU->getPixmap(WulforUtil::eiUSERS));
926         connect(d->toolsHideUsersStatisctics, SIGNAL(triggered()), this, SLOT(slotHideUsersStatistics()));
927 
928         d->toolsSwitchSpeedLimit = new QAction("", this);
929         d->toolsSwitchSpeedLimit->setObjectName("toolsSwitchSpeedLimit");
930         SM->registerShortcut(d->toolsSwitchSpeedLimit, tr("Ctrl+K"));
931         d->toolsSwitchSpeedLimit->setIcon(BOOLSETTING(THROTTLE_ENABLE)? WU->getPixmap(WulforUtil::eiSPEED_LIMIT_ON) : WU->getPixmap(WulforUtil::eiSPEED_LIMIT_OFF));
932         d->toolsSwitchSpeedLimit->setCheckable(true);
933         d->toolsSwitchSpeedLimit->setChecked(BOOLSETTING(THROTTLE_ENABLE));
934         connect(d->toolsSwitchSpeedLimit, SIGNAL(triggered()), this, SLOT(slotToolsSwitchSpeedLimit()));
935 
936         d->chatClear = new QAction("", this);
937         d->chatClear->setObjectName("chatClear");
938         d->chatClear->setIcon(WU->getPixmap(WulforUtil::eiCLEAR));
939         connect(d->chatClear, SIGNAL(triggered()), this, SLOT(slotChatClear()));
940 
941         d->findInWidget = new QAction("", this);
942         d->findInWidget->setObjectName("findInWidget");
943         SM->registerShortcut(d->findInWidget, tr("Ctrl+F"));
944         d->findInWidget->setIcon(WU->getPixmap(WulforUtil::eiFIND));
945         connect(d->findInWidget, SIGNAL(triggered()), this, SLOT(slotFind()));
946 
947         d->chatDisable = new QAction("", this);
948         d->chatDisable->setObjectName("chatDisable");
949         d->chatDisable->setIcon(WU->getPixmap(WulforUtil::eiEDITDELETE));
950         connect(d->chatDisable, SIGNAL(triggered()), this, SLOT(slotChatDisable()));
951 
952         QAction *separator0 = new QAction("", this);
953         separator0->setObjectName("separator0");
954         separator0->setSeparator(true);
955         QAction *separator1 = new QAction("", this);
956         separator1->setObjectName("separator1");
957         separator1->setSeparator(true);
958         QAction *separator2 = new QAction("", this);
959         separator2->setObjectName("separator2");
960         separator2->setSeparator(true);
961         QAction *separator3 = new QAction("", this);
962         separator3->setObjectName("separator3");
963         separator3->setSeparator(true);
964         QAction *separator4 = new QAction("", this);
965         separator4->setObjectName("separator4");
966         separator4->setSeparator(true);
967         QAction *separator5 = new QAction("", this);
968         separator5->setObjectName("separator5");
969         separator5->setSeparator(true);
970         QAction *separator6 = new QAction("", this);
971         separator6->setObjectName("separator6");
972         separator6->setSeparator(true);
973 
974         d->fileMenuActions << d->fileOpenMagnet
975                 << separator3
976                 << d->fileFileListBrowser
977                 << d->fileFileListBrowserLocal
978                 << d->fileFileListMatchAll
979                 << d->fileRefreshShareHashProgress
980                 << separator0
981                 << d->fileOpenLogFile
982                 << d->fileOpenDownloadDirectory
983                 << d->fileFileHasher
984                 << separator1
985                 << d->fileHideWindow
986                 << separator2
987                 << d->fileQuit;
988 
989         d->hubsMenuActions << d->hubsHubReconnect
990                 << d->hubsQuickConnect
991                 << d->hubsFavoriteHubs
992                 << d->hubsPublicHubs
993                 << separator0
994                 << d->hubsFavoriteUsers;
995 
996         d->toolsMenuActions << d->toolsSearch
997                 << d->toolsADLS
998                 << d->toolsCmdDebug
999                 << separator0
1000                 << d->toolsTransfers
1001                 << d->toolsDownloadQueue
1002                 << d->toolsQueuedUsers
1003                 << d->toolsFinishedDownloads
1004                 << d->toolsFinishedUploads
1005                 << d->toolsSwitchSpeedLimit
1006                 //<< toolsHubManager
1007                 << separator1
1008                 << d->toolsSpy
1009                 << d->toolsAntiSpam
1010                 << d->toolsIPFilter
1011                 << separator2
1012                 << d->menuAwayAction
1013                 << separator3
1014                 << d->toolsHideProgressSpace
1015                 << d->toolsHideLastStatus
1016                 << d->toolsHideUsersStatisctics
1017 #ifdef USE_JS
1018                 << separator6
1019                 << d->toolsJS
1020                 << d->toolsJSConsole
1021 #endif
1022                 << separator4
1023                 << d->toolsCopyWindowTitle
1024                 << separator5
1025                 << d->toolsOptions;
1026 
1027         d->toolBarActions << d->toolsOptions
1028                 << separator0
1029                 << d->fileFileListBrowserLocal
1030                 << d->fileRefreshShareHashProgress
1031                 << separator1
1032                 << d->hubsHubReconnect
1033                 << d->hubsQuickConnect
1034                 << separator2
1035                 << d->hubsFavoriteHubs
1036                 << d->hubsFavoriteUsers
1037                 << d->toolsQueuedUsers
1038                 << d->toolsSearch
1039                 << d->hubsPublicHubs
1040                 << separator3
1041                 << d->toolsTransfers
1042                 << d->toolsDownloadQueue
1043                 << d->toolsFinishedDownloads
1044                 << d->toolsFinishedUploads
1045                 << d->toolsSwitchSpeedLimit
1046                 << separator4
1047                 << d->chatClear
1048                 << d->findInWidget
1049                 << d->chatDisable
1050                 << separator5
1051                 << d->toolsADLS
1052                 << d->toolsSpy
1053                 << d->toolsAntiSpam
1054                 << d->toolsIPFilter
1055                 << separator6
1056                 << d->fileQuit;
1057     }
1058     {
1059         d->menuWidgets = new QMenu("", this);
1060     }
1061     {
1062         // submenu
1063         d->nextTabShortCut     = new  QAction(this);
1064         d->prevTabShortCut     = new  QAction(this);
1065         d->nextMsgShortCut     = new  QAction(this);
1066         d->prevMsgShortCut     = new  QAction(this);
1067         d->closeWidgetShortCut      = new  QAction(this);
1068         d->toggleMainMenuShortCut   = new  QAction(this);
1069 
1070         d->nextTabShortCut->setObjectName("nextTabShortCut");
1071         d->prevTabShortCut->setObjectName("prevTabShortCut");
1072         d->nextMsgShortCut->setObjectName("nextMsgShortCut");
1073         d->prevMsgShortCut->setObjectName("prevMsgShortCut");
1074         d->closeWidgetShortCut->setObjectName("closeWidgetShortCut");
1075         d->toggleMainMenuShortCut->setObjectName("toggleMainMenuShortCut");
1076 
1077         d->nextTabShortCut->setText(tr("Next widget"));
1078         d->prevTabShortCut->setText(tr("Previous widget"));
1079         d->nextMsgShortCut->setText(tr("Next message"));
1080         d->prevMsgShortCut->setText(tr("Previous message"));
1081         d->closeWidgetShortCut->setText(tr("Close current widget"));
1082         d->toggleMainMenuShortCut->setText(tr("Toggle main menu"));
1083 
1084         d->nextTabShortCut->setShortcutContext(Qt::ApplicationShortcut);
1085         d->prevTabShortCut->setShortcutContext(Qt::ApplicationShortcut);
1086         d->nextMsgShortCut->setShortcutContext(Qt::ApplicationShortcut);
1087         d->prevMsgShortCut->setShortcutContext(Qt::ApplicationShortcut);
1088         d->closeWidgetShortCut->setShortcutContext(Qt::ApplicationShortcut);
1089         d->toggleMainMenuShortCut->setShortcutContext(Qt::ApplicationShortcut);
1090 
1091         SM->registerShortcut(d->nextTabShortCut, tr("Ctrl+PgDown"));
1092         SM->registerShortcut(d->prevTabShortCut, tr("Ctrl+PgUp"));
1093         SM->registerShortcut(d->nextMsgShortCut, tr("Ctrl+Down"));
1094         SM->registerShortcut(d->prevMsgShortCut, tr("Ctrl+Up"));
1095         SM->registerShortcut(d->closeWidgetShortCut, tr("Ctrl+W"));
1096         SM->registerShortcut(d->toggleMainMenuShortCut, tr("Ctrl+M"));
1097 
1098         connect(d->nextMsgShortCut,        SIGNAL(triggered()), this, SLOT(nextMsg()));
1099         connect(d->prevMsgShortCut,        SIGNAL(triggered()), this, SLOT(prevMsg()));
1100         connect(d->closeWidgetShortCut,    SIGNAL(triggered()), this, SLOT(slotCloseCurrentWidget()));
1101         connect(d->toggleMainMenuShortCut, SIGNAL(triggered()), this, SLOT(slotHideMainMenu()));
1102         // end
1103 
1104         d->sh_menu = new QMenu(this);
1105         d->sh_menu->addActions(QList<QAction*>()
1106                             << d->nextTabShortCut
1107                             << d->prevTabShortCut
1108                             << d->nextMsgShortCut
1109                             << d->prevMsgShortCut
1110                             << d->closeWidgetShortCut
1111                             << d->toggleMainMenuShortCut);
1112 
1113         d->panelsWidgets = new QAction("", this);
1114         d->panelsWidgets->setCheckable(true);
1115         connect(d->panelsWidgets, SIGNAL(triggered()), this, SLOT(slotPanelMenuActionClicked()));
1116 
1117         d->panelsTools = new QAction("", this);
1118         d->panelsTools->setCheckable(true);
1119         connect(d->panelsTools, SIGNAL(triggered()), this, SLOT(slotPanelMenuActionClicked()));
1120 
1121         d->panelsSearch = new QAction("", this);
1122         d->panelsSearch->setCheckable(true);
1123         connect(d->panelsSearch, SIGNAL(triggered()), this, SLOT(slotPanelMenuActionClicked()));
1124     }
1125     {
1126         d->aboutHomepage = new QAction("", this);
1127         connect(d->aboutHomepage, SIGNAL(triggered()), this, SLOT(slotAboutOpenUrl()));
1128 
1129         d->aboutSource = new QAction("", this);
1130         connect(d->aboutSource, SIGNAL(triggered()), this, SLOT(slotAboutOpenUrl()));
1131 
1132         d->aboutIssues = new QAction("", this);
1133         connect(d->aboutIssues, SIGNAL(triggered()), this, SLOT(slotAboutOpenUrl()));
1134 
1135         d->aboutWiki = new QAction("", this);
1136         connect(d->aboutWiki, SIGNAL(triggered()), this, SLOT(slotAboutOpenUrl()));
1137 
1138         d->aboutChangelog = new QAction("", this);
1139         connect(d->aboutChangelog, SIGNAL(triggered()), this, SLOT(slotAboutOpenUrl()));
1140 
1141         d->aboutClient = new QAction("", this);
1142         d->aboutClient->setMenuRole(QAction::AboutRole);
1143         d->aboutClient->setIcon(WU->getPixmap(WulforUtil::eiICON_APPL)
1144                     .scaled(22, 22, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
1145         connect(d->aboutClient, SIGNAL(triggered()), this, SLOT(slotAboutClient()));
1146 
1147         d->aboutQt = new QAction("", this);
1148         d->aboutQt->setMenuRole(QAction::AboutQtRole);
1149         d->aboutQt->setIcon(WU->getPixmap(WulforUtil::eiQT_LOGO));
1150         connect(d->aboutQt, SIGNAL(triggered()), this, SLOT(slotAboutQt()));
1151     }
1152 }
1153 
1154 void MainWindow::initMenuBar(){
1155 #if defined(Q_WS_MAC)
1156     setMenuBar(new QMenuBar());
1157     menuBar()->setParent(NULL);
1158     connect(this, SIGNAL(destroyed()), menuBar(), SLOT(deleteLater()));
1159 #endif
1160 
1161     Q_D(MainWindow);
1162 
1163     {
1164         d->menuFile = new QMenu("", this);
1165 
1166         d->menuFile->addActions(d->fileMenuActions);
1167     }
1168     {
1169         d->menuHubs = new QMenu("", this);
1170 
1171         d->menuHubs->addActions(d->hubsMenuActions);
1172     }
1173     {
1174         d->menuTools = new QMenu("", this);
1175 
1176         d->menuTools->addActions(d->toolsMenuActions);
1177     }
1178     {
1179         QAction *sep0 = new QAction("", this);
1180         sep0->setSeparator(true);
1181 
1182         d->menuPanels = new QMenu("", this);
1183 
1184         d->menuPanels->addMenu(d->sh_menu);
1185         d->menuPanels->addAction(sep0);
1186         d->menuPanels->addAction(d->panelsWidgets);
1187         d->menuPanels->addAction(d->panelsTools);
1188         d->menuPanels->addAction(d->panelsSearch);
1189     }
1190     {
1191         QAction *sep0 = new QAction("", this);
1192         sep0->setSeparator(true);
1193         QAction *sep1 = new QAction("", this);
1194         sep1->setSeparator(true);
1195 
1196         d->menuAbout = new QMenu("", this);
1197 
1198         d->menuAbout->addAction(d->aboutHomepage);
1199         d->menuAbout->addAction(d->aboutSource);
1200         d->menuAbout->addAction(d->aboutIssues);
1201         d->menuAbout->addAction(d->aboutWiki);
1202         d->menuAbout->addAction(sep0);
1203         d->menuAbout->addAction(d->aboutChangelog);
1204         d->menuAbout->addAction(sep1);
1205         d->menuAbout->addAction(d->aboutClient);
1206         d->menuAbout->addAction(d->aboutQt);
1207     }
1208 
1209     menuBar()->addMenu(d->menuFile);
1210     menuBar()->addMenu(d->menuHubs);
1211     menuBar()->addMenu(d->menuTools);
1212     menuBar()->addMenu(d->menuWidgets);
1213     menuBar()->addMenu(d->menuPanels);
1214     menuBar()->addMenu(d->menuAbout);
1215     menuBar()->setContextMenuPolicy(Qt::CustomContextMenu);
1216 }
1217 
1218 void MainWindow::initStatusBar(){
1219     Q_D(MainWindow);
1220 
1221     d->statusLabel = new QLabel(statusBar());
1222     d->statusLabel->setFrameShadow(QFrame::Sunken);
1223     d->statusLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
1224     d->statusLabel->setToolTip(tr("Counts"));
1225     d->statusLabel->setContentsMargins(0, 0, 0, 0);
1226 
1227     d->statusSPLabel = new QLabel(statusBar());
1228     d->statusSPLabel->setFrameShadow(QFrame::Sunken);
1229     d->statusSPLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
1230     d->statusSPLabel->setToolTip(tr("Download/Upload speed"));
1231     d->statusSPLabel->setContentsMargins(0, 0, 0, 0);
1232 
1233     d->statusDLabel = new QLabel(statusBar());
1234     d->statusDLabel->setFrameShadow(QFrame::Sunken);
1235     d->statusDLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
1236     d->statusDLabel->setToolTip(tr("Downloaded/Uploaded"));
1237     d->statusDLabel->setContentsMargins(0, 0, 0, 0);
1238 
1239     d->msgLabel = new QLabel(statusBar());
1240     d->msgLabel->setFrameShadow(QFrame::Plain);
1241     d->msgLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
1242     d->msgLabel->setWordWrap(true);
1243     d->msgLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
1244     d->msgLabel->setContentsMargins(0, 0, 0, 0);
1245 
1246 #if (defined FREE_SPACE_BAR_C)
1247     d->progressSpace = new QProgressBar(this);
1248     d->progressSpace->setMaximum(100);
1249     d->progressSpace->setMinimum(0);
1250     d->progressSpace->setAlignment( Qt::AlignHCenter );
1251     d->progressSpace->setMinimumWidth(100);
1252     d->progressSpace->setMaximumWidth(250);
1253     d->progressSpace->setFixedHeight(18);
1254     d->progressSpace->setToolTip(tr("Space free"));
1255     d->progressSpace->installEventFilter(this);
1256 
1257     if (!WBGET(WB_SHOW_FREE_SPACE))
1258         d->progressSpace->hide();
1259 #else //FREE_SPACE_BAR_C
1260     WBSET(WB_SHOW_FREE_SPACE, false);
1261 #endif //FREE_SPACE_BAR_C
1262 
1263     d->progressHashing = new QProgressBar(this);
1264     d->progressHashing->setMaximum(100);
1265     d->progressHashing->setMinimum(0);
1266     d->progressHashing->setAlignment( Qt::AlignHCenter );
1267     d->progressHashing->setFixedHeight(18);
1268     d->progressHashing->setToolTip(tr("Hashing progress"));
1269     d->progressHashing->hide();
1270     d->progressHashing->installEventFilter( this );
1271 
1272     statusBar()->addWidget(d->progressHashing);
1273     statusBar()->addWidget(d->msgLabel, 1);
1274     statusBar()->addPermanentWidget(d->statusDLabel);
1275     statusBar()->addPermanentWidget(d->statusSPLabel);
1276     statusBar()->addPermanentWidget(d->statusLabel);
1277 #if (defined FREE_SPACE_BAR_C)
1278     statusBar()->addPermanentWidget(d->progressSpace);
1279 #endif //FREE_SPACE_BAR_C
1280 }
1281 
1282 void MainWindow::initSearchBar(){
1283     Q_D(MainWindow);
1284 
1285     d->searchLineEdit = new LineEdit(this);
1286 
1287     connect(d->searchLineEdit,   SIGNAL(returnPressed()), this, SLOT(slotToolsSearch()));
1288 }
1289 
1290 void MainWindow::retranslateUi(){
1291     Q_D(MainWindow);
1292 
1293     //Retranslate menu actions
1294     {
1295         d->menuFile->setTitle(tr("&File"));
1296 
1297         d->fileOpenMagnet->setText(tr("Open magnet link"));
1298 
1299         d->fileOpenLogFile->setText(tr("Open log file"));
1300 
1301         d->fileOpenDownloadDirectory->setText(tr("Open download directory"));
1302 
1303         d->fileFileListBrowser->setText(tr("Open filelist..."));
1304 
1305         d->fileFileHasher->setText(tr("Calculate file TTH"));
1306 
1307         d->fileFileListBrowserLocal->setText(tr("Open own filelist"));
1308 
1309         d->fileFileListMatchAll->setText(tr("Match all listings"));
1310 
1311         d->fileRefreshShareHashProgress->setText(tr("Refresh share"));
1312 
1313         d->fileHideWindow->setText(tr("Hide window"));
1314 
1315         if (!WBGET(WB_TRAY_ENABLED))
1316             d->fileHideWindow->setText(tr("Show/hide find frame"));
1317 
1318         d->fileQuit->setText(tr("Quit"));
1319 
1320         d->menuHubs->setTitle(tr("&Hubs"));
1321 
1322         d->hubsHubReconnect->setText(tr("Reconnect to hub"));
1323 
1324         d->hubsFavoriteHubs->setText(tr("Favourite hubs"));
1325 
1326         d->hubsPublicHubs->setText(tr("Public hubs"));
1327 
1328         d->hubsFavoriteUsers->setText(tr("Favourite users"));
1329 
1330         d->hubsQuickConnect->setText(tr("Quick connect"));
1331 
1332         d->menuTools->setTitle(tr("&Tools"));
1333 
1334         d->toolsTransfers->setText(tr("Transfers"));
1335 
1336         d->toolsDownloadQueue->setText(tr("Download queue"));
1337 
1338         d->toolsQueuedUsers->setText(tr("Queued Users"));
1339 
1340         d->toolsHubManager->setText(tr("Hub Manager"));
1341 
1342         d->toolsFinishedDownloads->setText(tr("Finished downloads"));
1343 
1344         d->toolsFinishedUploads->setText(tr("Finished uploads"));
1345 
1346         d->toolsSpy->setText(tr("Search Spy"));
1347 
1348         d->toolsAntiSpam->setText(tr("AntiSpam module"));
1349 
1350         d->toolsIPFilter->setText(tr("IPFilter module"));
1351 
1352         d->toolsHideProgressSpace->setText(tr("Hide free space bar"));
1353 
1354         if (!WBGET(WB_SHOW_FREE_SPACE))
1355             d->toolsHideProgressSpace->setText(tr("Show free space bar"));
1356 
1357         d->toolsHideLastStatus->setText(tr("Hide last status message"));
1358 
1359         if (!WBGET(WB_LAST_STATUS))
1360             d->toolsHideLastStatus->setText(tr("Show last status message"));
1361 
1362         d->toolsHideUsersStatisctics->setText(tr("Hide users statistics"));
1363 
1364         if (!WBGET(WB_USERS_STATISTICS))
1365             d->toolsHideUsersStatisctics->setText(tr("Show users statistics"));
1366 
1367         d->menuAway->setTitle(tr("Away message"));
1368 
1369         d->toolsAwayOn->setText(tr("On"));
1370 
1371         d->toolsAwayOff->setText(tr("Off"));
1372 
1373         d->toolsAutoAway->setText(tr("Away when not visible"));
1374 
1375         d->toolsCopyWindowTitle->setText(tr("Copy window title"));
1376 
1377         d->toolsOptions->setText(tr("Preferences"));
1378 
1379         d->toolsSearch->setText(tr("Search"));
1380 
1381         d->toolsADLS->setText(tr("ADLSearch"));
1382 
1383         d->toolsCmdDebug->setText(tr("CmdDebug"));
1384 
1385         d->toolsSwitchSpeedLimit->setText(tr("Speed limit On/Off"));
1386 
1387 #ifdef USE_JS
1388         d->toolsJS->setText(tr("Scripts Manager"));
1389 
1390         d->toolsJSConsole->setText(tr("Script Console"));
1391 #endif
1392 
1393         d->chatClear->setText(tr("Clear chat"));
1394 
1395         d->findInWidget->setText(tr("Find/Filter"));
1396 
1397         d->chatDisable->setText(tr("Disable/enable chat"));
1398 
1399         d->menuWidgets->setTitle(tr("&Widgets"));
1400 
1401         d->menuPanels->setTitle(tr("&Panels"));
1402 
1403         if (!WBGET(WB_MAINWINDOW_USE_SIDEBAR))
1404             d->panelsWidgets->setText(tr("Widgets panel"));
1405         else
1406             d->panelsWidgets->setText(tr("Widgets side dock"));
1407 
1408         d->panelsTools->setText(tr("Tools panel"));
1409 
1410         d->panelsSearch->setText(tr("Fast search panel"));
1411 
1412         d->menuAbout->setTitle(tr("&Help"));
1413 
1414         d->aboutHomepage->setText(tr("Homepage"));
1415 
1416         d->aboutSource->setText(tr("Source (git)"));
1417 
1418         d->aboutIssues->setText(tr("Report a Bug"));
1419 
1420         d->aboutWiki->setText(tr("Wiki of project"));
1421 
1422         d->aboutChangelog->setText(tr("Changelog (git)"));
1423 
1424         d->aboutClient->setText(tr("About EiskaltDC++"));
1425 
1426         d->aboutQt->setText(tr("About Qt"));
1427     }
1428     {
1429         d->sh_menu->setTitle(tr("Actions"));
1430     }
1431     {
1432         d->arena->setWindowTitle(tr("Main layout"));
1433     }
1434 }
1435 
1436 void MainWindow::initToolbar(){
1437     Q_D(MainWindow);
1438 
1439     d->fBar = new ToolBar(this);
1440     d->fBar->setObjectName("fBar");
1441 
1442     QStringList enabled_actions = QString(QByteArray::fromBase64(WSGET(WS_MAINWINDOW_TOOLBAR_ACTS).toUtf8())).split(";", QString::SkipEmptyParts);
1443 
1444     if (enabled_actions.isEmpty())
1445         d->fBar->addActions(d->toolBarActions);
1446     else {
1447         for (const auto &objName : enabled_actions){
1448             QAction *act = findChild<QAction*>(objName);
1449 
1450             if (act)
1451                 d->fBar->addAction(act);
1452         }
1453     }
1454 
1455     initFavHubMenu();
1456 
1457     d->fBar->setContextMenuPolicy(Qt::CustomContextMenu);
1458     d->fBar->setMovable(true);
1459     d->fBar->setFloatable(true);
1460     d->fBar->setAllowedAreas(Qt::AllToolBarAreas);
1461     d->fBar->setWindowTitle(tr("Actions"));
1462     d->fBar->setToolButtonStyle(static_cast<Qt::ToolButtonStyle>(WIGET(TOOLBUTTON_STYLE, Qt::ToolButtonIconOnly)));
1463 
1464     connect(d->fBar, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotToolbarCustomization()));
1465 
1466     addToolBar(d->fBar);
1467 
1468     if (!WBGET(WB_MAINWINDOW_USE_SIDEBAR) && WBGET(WB_MAINWINDOW_USE_M_TABBAR)){
1469 
1470         MultiLineToolBar *mBar = new MultiLineToolBar(this);
1471         mBar->setContextMenuPolicy(Qt::CustomContextMenu);
1472         mBar->setVisible(WBGET(WB_WIDGETS_PANEL_VISIBLE));
1473 
1474         connect(d->nextTabShortCut, SIGNAL(triggered()), mBar, SIGNAL(nextTab()));
1475         connect(d->prevTabShortCut, SIGNAL(triggered()), mBar, SIGNAL(prevTab()));
1476 
1477         addToolBar(mBar);
1478     }
1479     else if (!WBGET(WB_MAINWINDOW_USE_SIDEBAR) && !WBGET(WB_MAINWINDOW_USE_M_TABBAR)){
1480 
1481         ToolBar *tBar = new ToolBar(this);
1482         tBar->setObjectName("tBar");
1483         tBar->initTabs();
1484         tBar->setMovable(true);
1485         tBar->setFloatable(true);
1486         tBar->setAllowedAreas(Qt::AllToolBarAreas);
1487         tBar->setContextMenuPolicy(Qt::CustomContextMenu);
1488 
1489         addToolBar(tBar);
1490 
1491         connect(d->nextTabShortCut, SIGNAL(triggered()), tBar, SLOT(nextTab()));
1492         connect(d->prevTabShortCut, SIGNAL(triggered()), tBar, SLOT(prevTab()));
1493     }
1494 
1495     d->sBar = new ToolBar(this);
1496     d->sBar->setObjectName("sBar");
1497     d->sBar->addWidget(d->searchLineEdit);
1498     d->sBar->setContextMenuPolicy(Qt::CustomContextMenu);
1499     d->sBar->setMovable(true);
1500     d->sBar->setFloatable(true);
1501     d->sBar->setAllowedAreas(Qt::AllToolBarAreas);
1502 
1503     addToolBar(d->sBar);
1504 }
1505 
1506 void MainWindow::initSideBar(){
1507     if (!WBGET(WB_MAINWINDOW_USE_SIDEBAR))
1508         return;
1509 
1510     Q_D(MainWindow);
1511 
1512     d->sideDock = new QDockWidget("", this);
1513 
1514     d->sideDock->setWidget(new SideBarView(this));
1515     d->sideDock->setFeatures(d->sideDock->features() & (~QDockWidget::DockWidgetClosable));
1516     d->sideDock->setObjectName("sideDock");
1517     d->sideDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
1518     d->sideDock->setContextMenuPolicy(Qt::CustomContextMenu);
1519 
1520     addDockWidget(Qt::LeftDockWidgetArea, d->sideDock);
1521 
1522     connect(d->sideDock, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotSideBarDockMenu()));
1523 }
1524 
1525 void MainWindow::initFavHubMenu() {
1526     Q_D(MainWindow);
1527 
1528     if (!d->fBar)
1529         return;
1530 
1531     if (!d->favHubMenu) {
1532         d->favHubMenu = new QMenu(this);
1533 
1534         connect(d->favHubMenu, SIGNAL(aboutToShow()), this, SLOT(slotUpdateFavHubMenu()));
1535         connect(d->favHubMenu, SIGNAL(triggered(QAction*)), this, SLOT(slotConnectFavHub(QAction*)));
1536     }
1537 
1538     QToolButton * btn = qobject_cast<QToolButton *>(d->fBar->widgetForAction(d->hubsFavoriteHubs));
1539     if (btn) {
1540         btn->setMenu(d->favHubMenu);
1541         btn->setPopupMode(QToolButton::MenuButtonPopup);
1542     }
1543 }
1544 
1545 QObject *MainWindow::getToolBar(){
1546     Q_D(MainWindow);
1547 
1548     if (!d->fBar)
1549         return NULL;
1550 
1551     return qobject_cast<QObject*>(reinterpret_cast<QToolBar*>(d->fBar->qt_metacast("QToolBar")));
1552 }
1553 
1554 ArenaWidget *MainWindow::widgetForRole(ArenaWidget::Role r) const{
1555     ArenaWidget *awgt = NULL;
1556     Q_D(const MainWindow);
1557 
1558     switch (r){
1559     case ArenaWidget::Downloads:
1560         {
1561             awgt = ArenaWidgetFactory().create<dcpp::Singleton, DownloadQueue>();
1562             awgt->setToolButton(d->toolsDownloadQueue);
1563 
1564             break;
1565         }
1566     case ArenaWidget::FinishedUploads:
1567         {
1568             awgt = ArenaWidgetFactory().create<dcpp::Singleton, FinishedUploads>();
1569             awgt->setToolButton(d->toolsFinishedUploads);
1570 
1571             break;
1572         }
1573     case ArenaWidget::FinishedDownloads:
1574         {
1575             awgt = ArenaWidgetFactory().create<dcpp::Singleton, FinishedDownloads>();
1576             awgt->setToolButton(d->toolsFinishedDownloads);
1577 
1578             break;
1579         }
1580     case ArenaWidget::FavoriteHubs:
1581         {
1582             awgt = ArenaWidgetFactory().create<dcpp::Singleton, FavoriteHubs>();
1583             awgt->setToolButton(d->hubsFavoriteHubs);
1584 
1585             break;
1586         }
1587     case ArenaWidget::FavoriteUsers:
1588         {
1589             awgt = ArenaWidgetFactory().create<dcpp::Singleton, FavoriteUsers>();
1590             awgt->setToolButton(d->hubsFavoriteUsers);
1591 
1592             break;
1593         }
1594     case ArenaWidget::PublicHubs:
1595         {
1596             awgt = ArenaWidgetFactory().create<dcpp::Singleton, PublicHubs>();
1597             awgt->setToolButton(d->hubsPublicHubs);
1598 
1599             break;
1600         }
1601     case ArenaWidget::Spy:
1602         {
1603             awgt = ArenaWidgetFactory().create<dcpp::Singleton, SpyFrame>();
1604             awgt->setToolButton(d->toolsSpy);
1605 
1606             break;
1607         }
1608     case ArenaWidget::ADLS:
1609         {
1610             awgt = ArenaWidgetFactory().create<dcpp::Singleton, ADLS>();
1611             awgt->setToolButton(d->toolsADLS);
1612 
1613             break;
1614         }
1615     case ArenaWidget::CmdDebug:
1616     {
1617         awgt = ArenaWidgetFactory().create<dcpp::Singleton, CmdDebug>();
1618         awgt->setToolButton(d->toolsCmdDebug);
1619 
1620         break;
1621     }
1622     case ArenaWidget::QueuedUsers:
1623         {
1624             awgt = ArenaWidgetFactory().create<dcpp::Singleton, QueuedUsers>();
1625             awgt->setToolButton(d->toolsQueuedUsers);
1626 
1627             break;
1628         }
1629     default:
1630         break;
1631     }
1632 
1633     return awgt;
1634 }
1635 
1636 void MainWindow::newHubFrame(QString address, QString enc){
1637     if (address.isEmpty())
1638         return;
1639 
1640     address = QUrl::fromPercentEncoding(address.toUtf8());
1641 
1642     HubFrame *fr = qobject_cast<HubFrame*>(HubManager::getInstance()->getHub(address));
1643 
1644     if (fr){
1645         ArenaWidgetManager::getInstance()->activate(fr);
1646 
1647         return;
1648     }
1649 
1650     fr = ArenaWidgetFactory().create<HubFrame, QWidget*, QString, QString>(this, address, enc);
1651 
1652     ArenaWidgetManager::getInstance()->activate(fr);
1653 }
1654 
1655 void MainWindow::updateStatus(const QMap<QString, QString> &map){
1656     Q_D(MainWindow);
1657 
1658     if (!d->statusLabel)
1659         return;
1660 
1661     QString statsText = map["STATS"];
1662     QFontMetrics metrics(d->statusLabel->font());
1663 
1664     d->statusLabel->setText(statsText);
1665 
1666     QString speedText = tr("%1/s / %2/s").arg(map["DSPEED"]).arg(map["USPEED"]);
1667     QString downText = tr("%1 / %2").arg(map["DOWN"]).arg(map["UP"]);
1668 
1669     d->statusSPLabel->setText(speedText);
1670     d->statusDLabel->setText(downText);
1671 
1672     Notification *N = Notification::getInstance();
1673     if (N)
1674         N->setToolTip(map["DSPEED"]+tr("/s"), map["USPEED"]+tr("/s"), map["DOWN"], map["UP"]);
1675 
1676     int leftM=0, topM=0, rightM=0, bottomM=0;
1677     d->statusSPLabel->getContentsMargins(&leftM, &topM, &rightM, &bottomM);
1678     int boundWidth = leftM + rightM;
1679 
1680     d->statusSPLabel->setFixedWidth(metrics.width(speedText) > d->statusSPLabel->width()? metrics.width(speedText) + boundWidth : d->statusSPLabel->width());
1681     d->statusDLabel->setFixedWidth(metrics.width(downText) > d->statusDLabel->width()? metrics.width(downText) + boundWidth : d->statusDLabel->width());
1682 
1683     if (WBGET(WB_SHOW_FREE_SPACE)) {
1684 #ifdef FREE_SPACE_BAR_C
1685         std::string s = SETTING(DOWNLOAD_DIRECTORY);
1686         unsigned long long available = 0;
1687         unsigned long long total = 0;
1688         if (!s.empty()) {
1689             if (FreeSpace::FreeDiscSpace(s, &available, &total) == false) {
1690                 available = 0;
1691                 total = 0;
1692             }
1693         }
1694         float percent = 100.0f*(total-available)/total;
1695         QString format = tr("Free %1")
1696                          .arg(WulforUtil::formatBytes(available));
1697 
1698         QString tooltip = tr("Free %1 of %2")
1699                           .arg(WulforUtil::formatBytes(available))
1700                           .arg(WulforUtil::formatBytes(total));
1701 
1702         d->progressSpace->setFormat(format);
1703         d->progressSpace->setToolTip(tooltip);
1704         d->progressSpace->setValue(static_cast<unsigned>(percent));
1705 
1706         d->progressSpace->setFixedWidth(metrics.width(format) > d->progressSpace->width()? metrics.width(d->progressSpace->text()) + 40 : d->progressSpace->width());
1707 #endif //FREE_SPACE_BAR_C
1708     }
1709 
1710     if ((Util::getAway() && !d->toolsAwayOn->isChecked()) || (!Util::getAway() && d->toolsAwayOff->isChecked())){
1711         QAction *act = Util::getAway()? d->toolsAwayOn : d->toolsAwayOff;
1712 
1713         act->setChecked(true);
1714     }
1715 
1716     updateHashProgressStatus();
1717 }
1718 
1719 void MainWindow::updateHashProgressStatus() {
1720     WulforUtil *WU = WulforUtil::getInstance();
1721     Q_D(MainWindow);
1722 
1723     switch( HashProgress::getHashStatus() ) {
1724     case HashProgress::IDLE:
1725         d->fileRefreshShareHashProgress->setIcon(WU->getPixmap(WulforUtil::eiREFRLIST));
1726         d->fileRefreshShareHashProgress->setText(tr("Refresh share"));
1727         {
1728             progress_dialog()->resetProgress(); // Here dialog will be actually created
1729             d->progressHashing->hide();
1730         }
1731         //qDebug("idle");
1732         break;
1733     case HashProgress::LISTUPDATE:
1734         d->fileRefreshShareHashProgress->setIcon(WU->getPixmap(WulforUtil::eiHASHING));
1735         d->fileRefreshShareHashProgress->setText(tr("Hash progress"));
1736         {
1737             d->progressHashing->setValue( 100 );
1738             d->progressHashing->setFormat(tr("List update"));
1739             d->progressHashing->show();
1740         }
1741         //qDebug("listupdate");
1742         break;
1743     case HashProgress::DELAYED:
1744         d->fileRefreshShareHashProgress->setIcon(WU->getPixmap(WulforUtil::eiHASHING));
1745         d->fileRefreshShareHashProgress->setText(tr("Hash progress"));
1746         {
1747             if (SETTING(HASHING_START_DELAY) >= 0){
1748                 int left = SETTING(HASHING_START_DELAY) - Util::getUpTime();
1749                 d->progressHashing->setValue( 100 * left / SETTING(HASHING_START_DELAY) );
1750                 d->progressHashing->setFormat(tr("Delayed"));
1751                 d->progressHashing->show();
1752             }
1753             else {
1754                 d->progressHashing->hide();
1755             }
1756         }
1757         //qDebug("delayed");
1758         break;
1759     case HashProgress::PAUSED:
1760         d->fileRefreshShareHashProgress->setIcon(WU->getPixmap(WulforUtil::eiHASHING));
1761         d->fileRefreshShareHashProgress->setText(tr("Hash progress"));
1762         {
1763             if (SETTING(HASHING_START_DELAY) >= 0){
1764                 d->progressHashing->setValue( 100 );
1765                 d->progressHashing->setFormat(tr("Paused"));
1766                 d->progressHashing->show();
1767             }
1768             else {
1769                 d->progressHashing->hide();
1770             }
1771         }
1772         //qDebug("paused");
1773         break;
1774     case HashProgress::RUNNING:
1775         d->fileRefreshShareHashProgress->setIcon(WU->getPixmap(WulforUtil::eiHASHING));
1776         d->fileRefreshShareHashProgress->setText(tr("Hash progress"));
1777         {
1778             int progress = static_cast<int>( progress_dialog()->getProgress()*100 );
1779             d->progressHashing->setFormat(tr("%p%"));
1780             d->progressHashing->setValue( progress );
1781             d->progressHashing->show();
1782         }
1783         //qDebug("running");
1784         break;
1785     default:
1786         //qDebug("unknown");
1787         break;
1788     }
1789 }
1790 
1791 void MainWindow::setStatusMessage(QString msg){
1792     Q_D(MainWindow);
1793 
1794     QFontMetrics m(d->msgLabel->font());
1795     QString pure_msg = msg;
1796 
1797     if (m.width(msg) > d->msgLabel->width())
1798         pure_msg = m.elidedText(msg, Qt::ElideRight, d->msgLabel->width(), 0);
1799 
1800     WulforUtil::getInstance()->textToHtml(pure_msg, true);
1801     WulforUtil::getInstance()->textToHtml(msg, true);
1802 
1803     d->msgLabel->setText(pure_msg);
1804 
1805     d->core_msg_history.push_back(msg);
1806 
1807     if (WIGET(WI_STATUSBAR_HISTORY_SZ) > 0){
1808         while (d->core_msg_history.size() > WIGET(WI_STATUSBAR_HISTORY_SZ))
1809             d->core_msg_history.removeFirst();
1810     }
1811     else
1812         d->core_msg_history.clear();
1813 
1814     d->msgLabel->setToolTip(d->core_msg_history.join("\n"));
1815     d->msgLabel->setMaximumHeight(d->statusLabel->height());
1816 }
1817 
1818 void MainWindow::autoconnect(){
1819     const FavoriteHubEntryList& fl = FavoriteManager::getInstance()->getFavoriteHubs();
1820 
1821     for (const auto &i : fl) {
1822         FavoriteHubEntry* entry = i;
1823 
1824         if (entry->getConnect()) {
1825             if (entry->getNick().empty() && SETTING(NICK).empty())
1826                 continue;
1827 
1828             QString encoding = WulforUtil::getInstance()->dcEnc2QtEnc(QString::fromStdString(entry->getEncoding()));
1829 
1830             newHubFrame(QString::fromStdString(entry->getServer()), encoding);
1831         }
1832     }
1833 }
1834 
1835 void MainWindow::parseCmdLine(const QStringList &args){
1836     for (const auto &arg : args){
1837         if (arg.startsWith("magnet:?")){
1838             Magnet m(this);
1839             m.setLink(arg);
1840             if (WIGET(WI_DEF_MAGNET_ACTION) == 0) {
1841                 m.exec();
1842             }
1843         }
1844         else if (arg.startsWith("dchub://")){
1845             newHubFrame(arg, "");
1846         }
1847         else if (arg.startsWith("adc://") || arg.startsWith("adcs://")){
1848             newHubFrame(arg, "UTF-8");
1849         }
1850     }
1851 }
1852 
1853 void MainWindow::parseInstanceLine(QString data){
1854     if (!isVisible()){
1855         show();
1856         raise();
1857 
1858         redrawToolPanel();
1859     }
1860 
1861     QStringList args = data.split("\n", QString::SkipEmptyParts);
1862     parseCmdLine(args);
1863 }
1864 
1865 void MainWindow::browseOwnFiles(){
1866     slotFileBrowseOwnFilelist();
1867 }
1868 
1869 void MainWindow::slotFileBrowseFilelist(){
1870     QString file = QFileDialog::getOpenFileName(this, tr("Choose file to open"),
1871                 QString::fromStdString(Util::getPath(Util::PATH_FILE_LISTS)),
1872                 tr("Modern XML Filelists") + " (*.xml.bz2);;" +
1873                 tr("Modern XML Filelists uncompressed") + " (*.xml);;" +
1874                 tr("All files") + " (*)");
1875 
1876     if (file.isEmpty())
1877         return;
1878 
1879     file = QDir::toNativeSeparators(file);
1880     UserPtr user = DirectoryListing::getUserFromFilename(_tq(file));
1881 
1882     if (user) {
1883         ArenaWidgetFactory().create<ShareBrowser, UserPtr, QString, QString>(user, file, "");
1884     } else {
1885         setStatusMessage(tr("Unable to load file list: Invalid file list name"));
1886     }
1887 }
1888 
1889 void MainWindow::slotFileMatchAllList(){
1890     QueueManager::getInstance()->matchAllListings();
1891 }
1892 
1893 void MainWindow::redrawToolPanel(){
1894     Q_D(MainWindow);
1895 
1896     auto it = d->menuWidgetsHash.begin();
1897     auto end = d->menuWidgetsHash.end();
1898 
1899     ArenaWidget *awgt = NULL;
1900     PMWindow *pm = NULL;
1901     bool has_unread = false;
1902 
1903     for (; it != end; ++it){ //also redraw all widget menu items and change window title if needed
1904         awgt = it.value();
1905         it.key()->setText(awgt->getArenaShortTitle());
1906         it.key()->setIcon(awgt->getPixmap());
1907 
1908         pm = qobject_cast<PMWindow *>(awgt->getWidget());
1909         if (pm && pm->hasNewMessages())
1910             has_unread = true;
1911 
1912         if (awgt && d->arena->widget() && d->arena->widget() == awgt->getWidget())
1913             setWindowTitle(awgt->getArenaTitle() + " :: " + QString("%1").arg(EISKALTDCPP_WND_TITLE));
1914     }
1915 
1916 #if !defined(Q_WS_MAC)
1917     if (!has_unread)
1918         Notify->resetTrayIcon();
1919 #else // !defined(Q_WS_MAC)
1920     // Change program icon in dock when there are new unread personal messages.
1921     if (has_unread)
1922         qApp->setWindowIcon(WICON(WulforUtil::eiMESSAGE_TRAY_ICON));
1923     else
1924         qApp->setWindowIcon(WICON(WulforUtil::eiICON_APPL));
1925 #endif // !defined(Q_WS_MAC)
1926 
1927     emit redrawWidgetPanels();
1928 }
1929 
1930 void MainWindow::mapWidgetOnArena(ArenaWidget *awgt){
1931     Q_D(MainWindow);
1932 
1933     if (!(awgt && awgt->getWidget())){
1934         d->arena->setWidget(NULL);
1935 
1936         return;
1937     }
1938 
1939     if (d->arena->widget() != awgt->getWidget())
1940         d->arena->setWidget(awgt->getWidget());
1941 
1942     setWindowTitle(awgt->getArenaTitle() + " :: " + QString("%1").arg(EISKALTDCPP_WND_TITLE));
1943 
1944     if (awgt->toolButton())
1945         awgt->toolButton()->setChecked(true);
1946 
1947     ArenaWidget::Role role = awgt->role();
1948 
1949     bool widgetWithFilter = role == ArenaWidget::Hub ||
1950                             role == ArenaWidget::ShareBrowser ||
1951                             role == ArenaWidget::PublicHubs ||
1952                             role == ArenaWidget::Search ||
1953                             role == ArenaWidget::PrivateMessage;
1954 
1955     d->chatClear->setEnabled(role == ArenaWidget::Hub || role == ArenaWidget::PrivateMessage);
1956     d->findInWidget->setEnabled(widgetWithFilter);
1957     d->chatDisable->setEnabled(role == ArenaWidget::Hub);
1958 
1959     awgt->requestFocus();
1960 }
1961 
1962 void MainWindow::insertWidget ( ArenaWidget* awgt ) {
1963     if (!awgt || (awgt && (awgt->state() & ArenaWidget::Hidden)))
1964         return;
1965 
1966     Q_D(MainWindow);
1967 
1968     QAction *act = d->menuWidgets->addAction(awgt->getPixmap(), awgt->getArenaShortTitle());
1969 
1970     d->menuWidgetsHash.insert(act, awgt);
1971 
1972     connect(act, SIGNAL(triggered(bool)), this, SLOT(slotWidgetsToggle()));
1973 }
1974 
1975 void MainWindow::removeWidget ( ArenaWidget* awgt ) {
1976     Q_D(MainWindow);
1977 
1978     QAction *act = d->menuWidgetsHash.key(awgt);
1979 
1980     if (!act)
1981         return;
1982 
1983     d->menuWidgetsHash.remove(act);
1984 
1985     act->deleteLater();
1986 }
1987 
1988 void MainWindow::updated ( ArenaWidget* awgt ) {
1989     if (!awgt)
1990         return;
1991 
1992     if (awgt->state() & ArenaWidget::Hidden)
1993         removeWidget(awgt);
1994     else
1995         insertWidget(awgt);
1996 }
1997 
1998 void MainWindow::addActionOnToolBar(QAction *new_act){
1999     Q_D(MainWindow);
2000 
2001     if (!d->fBar || d->toolBarActions.contains(new_act))
2002         return;
2003 
2004     d->fBar->insertAction(d->toolBarActions.last(), new_act);
2005     d->toolBarActions.append(new_act);
2006 }
2007 
2008 void MainWindow::remActionFromToolBar(QAction *act){
2009     Q_D(MainWindow);
2010 
2011     if (!d->fBar || !d->toolBarActions.contains(act))
2012         return;
2013 
2014     d->fBar->removeAction(act);
2015     d->toolBarActions.removeAt(d->toolBarActions.indexOf(act));
2016 }
2017 
2018 void MainWindow::toggleSingletonWidget(ArenaWidget *a){
2019     if (!a)
2020         throw std::runtime_error(_tq(Q_FUNC_INFO) + ": NULL argument");
2021 
2022     if (sender() && qobject_cast<QAction*>(sender()) && a->getWidget()){
2023         QAction *act = reinterpret_cast<QAction*>(sender());
2024 
2025         act->setCheckable(true);
2026 
2027         a->setToolButton(act);
2028     }
2029 
2030     if (!a->getWidget()->isVisible())
2031         ArenaWidgetManager::getInstance()->activate(a);
2032     else
2033         ArenaWidgetManager::getInstance()->toggle(a);
2034 }
2035 
2036 void MainWindow::toggleMainMenu(bool showMenu){
2037     static QAction *compactMenus = NULL;
2038 
2039     menuBar()->setVisible(showMenu);
2040 
2041     Q_D(MainWindow);
2042 
2043     if (showMenu){
2044         if (compactMenus && d->fBar)
2045             d->fBar->removeAction(compactMenus);
2046     }
2047     else {
2048         if (d->fBar){
2049             if (!compactMenus){
2050                 compactMenus = new QAction(tr("Menu"), this);
2051                 compactMenus->setObjectName("compactMenus");
2052                 compactMenus->setIcon(WICON(WulforUtil::eiEDIT));
2053             }
2054             else {
2055                 compactMenus->menu()->deleteLater();
2056                 compactMenus->setMenu(NULL);
2057             }
2058 
2059             QMenu *m = new QMenu(this);
2060 
2061             for (const auto &a : menuBar()->actions())
2062                 m->addAction(a);
2063 
2064             compactMenus->setMenu(m);
2065 
2066             connect(compactMenus, SIGNAL(triggered()), this, SLOT(slotShowMainMenu()));
2067         }
2068 
2069         if (d->fBar)
2070             d->fBar->insertAction(d->toolBarActions.first(), compactMenus);
2071     }
2072 
2073     WBSET(WB_MAIN_MENU_VISIBLE, showMenu);
2074 }
2075 
2076 void MainWindow::startSocket(bool changed){
2077     if (changed)
2078         ConnectivityManager::getInstance()->updateLast();
2079     try {
2080         ConnectivityManager::getInstance()->setup(true);
2081     } catch (const Exception& e) {
2082         showPortsError(e.getError());
2083     }
2084     ClientManager::getInstance()->infoUpdated();
2085 }
2086 void MainWindow::showPortsError(const string& port) {
2087     QString msg = tr("Unable to open %1 port. Searching or file transfers will not work correctly until you change settings or turn off any application that might be using that port.").arg(_q(port));
2088     QMessageBox::warning(this, tr("Connectivity Manager: Warning"), msg, QMessageBox::Ok);
2089 }
2090 void MainWindow::showShareBrowser(dcpp::UserPtr usr, const QString &file, const QString &jump_to){
2091     ArenaWidgetFactory().create<ShareBrowser, UserPtr, QString, QString>(usr, file, jump_to);
2092 }
2093 
2094 void MainWindow::reloadSomeSettings(){
2095     Q_D(MainWindow);
2096 
2097     for (const auto &awgt : d->menuWidgetsHash.values()){
2098         HubFrame *fr = qobject_cast<HubFrame *>(awgt->getWidget());
2099 
2100         if (fr)
2101             fr->reloadSomeSettings();
2102     }
2103 
2104     d->toolsSwitchSpeedLimit->setChecked(BOOLSETTING(THROTTLE_ENABLE));
2105 }
2106 
2107 void MainWindow::slotFileOpenLogFile(){
2108     QString f = QFileDialog::getOpenFileName(this, tr("Open log file"),_q(SETTING(LOG_DIRECTORY)), tr("Log files (*.log);;All files (*.*)"));
2109 
2110     if (!f.isEmpty()){
2111         f = QDir::toNativeSeparators(f);
2112 
2113         if (f.startsWith("/"))
2114             f = "file://" + f;
2115         else
2116             f = "file:///" + f;
2117 
2118         QDesktopServices::openUrl(QUrl(f));
2119     }
2120 }
2121 
2122 void MainWindow::slotFileOpenDownloadDirectory(){
2123     QString directory = QString::fromStdString(SETTING(DOWNLOAD_DIRECTORY));
2124 
2125     directory.prepend( directory.startsWith("/")? ("file://") : ("file:///"));
2126 
2127     QDesktopServices::openUrl(QUrl::fromEncoded(directory.toUtf8()));
2128 }
2129 
2130 void MainWindow::slotFileBrowseOwnFilelist(){
2131     UserPtr user = ClientManager::getInstance()->getMe();
2132     QString file = QString::fromStdString(ShareManager::getInstance()->getOwnListFile());
2133 
2134     ArenaWidgetFactory().create<ShareBrowser, UserPtr, QString, QString>(user, file, "");
2135 }
2136 
2137 void MainWindow::slotFileHashProgress(){
2138     progress_dialog()->slotAutoClose(false);
2139     progress_dialog()->show();
2140 }
2141 
2142 void MainWindow::slotFileHasher(){
2143     FileHasher *m = new FileHasher(MainWindow::getInstance());
2144     m->setModal(true);
2145     m->exec();
2146     delete m;
2147 }
2148 
2149 void MainWindow::slotFileRefreshShareHashProgress(){
2150     switch( HashProgress::getHashStatus() ) {
2151     case HashProgress::IDLE:
2152     {
2153         ShareManager *SM = ShareManager::getInstance();
2154 
2155         SM->setDirty();
2156         SM->refresh(true);
2157 
2158         updateHashProgressStatus();
2159         progress_dialog()->resetProgress();
2160     }
2161         break;
2162     case HashProgress::LISTUPDATE:
2163     case HashProgress::PAUSED:
2164     case HashProgress::DELAYED:
2165     case HashProgress::RUNNING:
2166         slotFileHashProgress();
2167         break;
2168     default:
2169         break;
2170     }
2171 }
2172 
2173 void MainWindow::slotOpenMagnet(){
2174     QString text = qApp->clipboard()->text(QClipboard::Clipboard);
2175     bool ok = false;
2176 
2177     text = (text.startsWith("magnet:?")? text : "");
2178 
2179     QString result = QInputDialog::getText(this, tr("Open magnet link"), tr("Enter magnet link:"), QLineEdit::Normal, text, &ok);
2180 
2181     if (!ok)
2182         return;
2183 
2184     if (result.startsWith("magnet:?")){
2185         Magnet m(this);
2186 
2187         m.setLink(result);
2188 
2189         m.exec();
2190     }
2191 }
2192 
2193 void MainWindow::slotHubsReconnect(){
2194     HubFrame *fr = qobject_cast<HubFrame*>(HubManager::getInstance()->activeHub());
2195 
2196     if (fr)
2197         fr->reconnect();
2198 }
2199 
2200 void MainWindow::slotToolsADLS(){
2201     toggleSingletonWidget(widgetForRole(ArenaWidget::ADLS));
2202 }
2203 
2204 void MainWindow::slotToolsCmdDebug()
2205 {
2206     toggleSingletonWidget(widgetForRole(ArenaWidget::CmdDebug));
2207 }
2208 
2209 void MainWindow::slotToolsSearch() {
2210     SearchFrame *sf = ArenaWidgetFactory().create<SearchFrame>();
2211 
2212     QLineEdit *le = qobject_cast<QLineEdit *> ( sender() );
2213 
2214     Q_D(MainWindow);
2215 
2216     if ( le != d->searchLineEdit )
2217         return;
2218 
2219     QString text = d->searchLineEdit->text();
2220     bool isTTH = false;
2221 
2222     if ( text.startsWith ( "magnet:" ) ) {
2223         QString link = text;
2224         QString tth = "", name = "";
2225         int64_t size = 0;
2226 
2227         WulforUtil::splitMagnet ( link, size, tth, name );
2228 
2229         text  = tth;
2230         isTTH = true;
2231     }
2232 
2233     sf->fastSearch ( text, isTTH || WulforUtil::isTTH ( text ) );
2234 }
2235 
2236 void MainWindow::slotToolsDownloadQueue(){
2237     toggleSingletonWidget(widgetForRole(ArenaWidget::Downloads));
2238 }
2239 
2240 void MainWindow::slotToolsQueuedUsers(){
2241     toggleSingletonWidget(widgetForRole(ArenaWidget::QueuedUsers));
2242 }
2243 
2244 void MainWindow::slotToolsHubManager(){
2245 }
2246 
2247 void MainWindow::slotToolsFinishedDownloads(){
2248     toggleSingletonWidget(widgetForRole(ArenaWidget::FinishedDownloads));
2249 }
2250 
2251 void MainWindow::slotToolsFinishedUploads(){
2252    toggleSingletonWidget(widgetForRole(ArenaWidget::FinishedUploads));
2253 }
2254 
2255 void MainWindow::slotToolsSpy(){
2256     toggleSingletonWidget(widgetForRole(ArenaWidget::Spy));
2257 }
2258 
2259 void MainWindow::slotToolsAntiSpam(){
2260     AntiSpamFrame fr(this);
2261 
2262     fr.exec();
2263 
2264     Q_D(MainWindow);
2265 
2266     d->toolsAntiSpam->setChecked(AntiSpam::getInstance() != NULL);
2267 }
2268 
2269 void MainWindow::slotToolsIPFilter(){
2270     IPFilterFrame fr(this);
2271 
2272     fr.exec();
2273 
2274     Q_D(MainWindow);
2275 
2276     d->toolsIPFilter->setChecked(IPFilter::getInstance() != NULL);
2277 }
2278 
2279 void MainWindow::slotToolsAutoAway(){
2280     Q_D(MainWindow);
2281 
2282     WBSET(WB_APP_AUTO_AWAY, d->toolsAutoAway->isChecked());
2283 }
2284 
2285 void MainWindow::slotToolsSwitchAway(){
2286     Q_D(MainWindow);
2287 
2288     if ((sender() != d->toolsAwayOff) && (sender() != d->toolsAwayOn))
2289         return;
2290 
2291     bool away = d->toolsAwayOn->isChecked();
2292 
2293     Util::setAway(away);
2294     Util::setManualAway(away);
2295 }
2296 
2297 void MainWindow::slotToolsJS(){
2298 #ifdef USE_JS
2299     ScriptManagerDialog(this).exec();
2300 #endif
2301 }
2302 
2303 #ifdef USE_JS
2304 namespace {
2305     enum class ScriptChangedAction: int {
2306         DoNothing=0,
2307         AskUser,
2308         ReloadIt
2309     };
2310 }
2311 #endif
2312 
2313 void MainWindow::slotJSFileChanged(const QString &script){
2314 #ifdef USE_JS
2315     enum ScriptChangedAction act = (enum ScriptChangedAction)WIGET("scriptmanager/script-changed-action", 0);
2316     bool ask = false;
2317 
2318     switch (act){
2319     case ScriptChangedAction::DoNothing:
2320         break;
2321     case ScriptChangedAction::AskUser:
2322         ask = true;
2323     case ScriptChangedAction::ReloadIt:
2324     {
2325         auto raiseMe = [this]() -> bool {
2326             if (!this->isVisible()){
2327                 this->show();
2328                 this->raise();
2329             }
2330 
2331             return true;
2332         };
2333 
2334         if (ask && raiseMe() && (QMessageBox::warning(this,
2335                                                       tr("Script Engine"),
2336                                                       QString("\'%1\' has been changed. Reload it?").arg(script),
2337                                                       QMessageBox::Yes, QMessageBox::No) != QMessageBox::Yes))
2338             break;
2339 
2340 
2341         ScriptEngine::getInstance()->loadScript(script);
2342 
2343         break;
2344     }
2345     }
2346 #endif
2347 }
2348 
2349 
2350 void MainWindow::slotToolsJSConsole(){
2351     Q_D(MainWindow);
2352 
2353 #ifdef USE_JS
2354     if (!d->scriptConsole)
2355         d->scriptConsole = new ScriptConsole(this);
2356 
2357     d->scriptConsole->setWindowModality(Qt::NonModal);
2358     d->scriptConsole->show();
2359     d->scriptConsole->raise();
2360 #endif
2361 }
2362 
2363 void MainWindow::slotHubsFavoriteHubs(){
2364     toggleSingletonWidget(widgetForRole(ArenaWidget::FavoriteHubs));
2365 }
2366 
2367 void MainWindow::slotHubsPublicHubs(){
2368     toggleSingletonWidget(widgetForRole(ArenaWidget::PublicHubs));
2369 }
2370 
2371 void MainWindow::slotHubsFavoriteUsers(){
2372     toggleSingletonWidget(widgetForRole(ArenaWidget::FavoriteUsers));
2373 }
2374 
2375 void MainWindow::slotToolsCopyWindowTitle(){
2376     QString text = windowTitle();
2377 
2378     if (!text.isEmpty())
2379         qApp->clipboard()->setText(text, QClipboard::Clipboard);
2380 }
2381 
2382 void MainWindow::slotToolsSettings(){
2383     Settings s;
2384 
2385     s.exec();
2386 
2387     reloadSomeSettings();
2388 
2389     Q_D(MainWindow);
2390 
2391     //reload some settings
2392     if (!WBGET(WB_TRAY_ENABLED))
2393         d->fileHideWindow->setText(tr("Show/hide find frame"));
2394     else
2395         d->fileHideWindow->setText(tr("Hide window"));
2396 }
2397 
2398 void MainWindow::slotToolsTransfer(bool toggled){
2399     Q_D(MainWindow);
2400 
2401     if (toggled){
2402         d->transfer_dock->setVisible(true);
2403         d->transfer_dock->setWidget(TransferView::getInstance());
2404     }
2405     else {
2406         d->transfer_dock->setWidget(NULL);
2407         d->transfer_dock->setVisible(false);
2408     }
2409 }
2410 
2411 void MainWindow::slotToolsSwitchSpeedLimit(){
2412     static WulforUtil *WU = WulforUtil::getInstance();
2413     Q_D(MainWindow);
2414 
2415     SettingsManager::getInstance()->set(SettingsManager::THROTTLE_ENABLE, d->toolsSwitchSpeedLimit->isChecked());
2416     d->toolsSwitchSpeedLimit->setIcon(BOOLSETTING(THROTTLE_ENABLE)? WU->getPixmap(WulforUtil::eiSPEED_LIMIT_ON) : WU->getPixmap(WulforUtil::eiSPEED_LIMIT_OFF));
2417 }
2418 
2419 void MainWindow::slotPanelMenuActionClicked(){
2420     QAction *act = qobject_cast<QAction *>(sender());
2421 
2422     if (!act)
2423         return;
2424 
2425     Q_D(MainWindow);
2426 
2427     if (act == d->panelsWidgets){
2428         if (findChild<MultiLineToolBar*>("multiLineTabbar")){
2429             findChild<MultiLineToolBar*>("multiLineTabbar")->setVisible(d->panelsWidgets->isChecked());
2430         }
2431         else if (findChild<ToolBar*>("tBar")){
2432             findChild<ToolBar*>("tBar")->setVisible(d->panelsWidgets->isChecked());
2433         }
2434         else if (d->sideDock)
2435             d->sideDock->setVisible(d->panelsWidgets->isChecked());
2436 
2437         WBSET(WB_WIDGETS_PANEL_VISIBLE, d->panelsWidgets->isChecked());
2438     }
2439     else if (act == d->panelsTools){
2440         d->fBar->setVisible(d->panelsTools->isChecked());
2441         WBSET(WB_TOOLS_PANEL_VISIBLE, d->panelsTools->isChecked());
2442     }
2443     else if (act == d->panelsSearch){
2444         d->sBar->setVisible(d->panelsSearch->isChecked());
2445         WBSET(WB_SEARCH_PANEL_VISIBLE, d->panelsSearch->isChecked());
2446     }
2447 }
2448 
2449 void MainWindow::slotChatClear(){
2450     Q_D(MainWindow);
2451 
2452     HubFrame *fr = qobject_cast<HubFrame *>(d->arena->widget());
2453     PMWindow *pm = qobject_cast<PMWindow *>(d->arena->widget());
2454 
2455     if (fr)
2456         fr->clearChat();
2457     else if (pm)
2458         pm->clearChat();
2459 }
2460 
2461 void MainWindow::slotFind(){
2462     Q_D(MainWindow);
2463 
2464     if (!d->arena->widget() || !qobject_cast<ArenaWidget*>(d->arena->widget()))
2465         return;
2466 
2467     ArenaWidget *awgt = qobject_cast<ArenaWidget*>(d->arena->widget());
2468     awgt->requestFilter();
2469 }
2470 
2471 void MainWindow::slotChatDisable(){
2472     HubFrame *fr = qobject_cast<HubFrame*>(HubManager::getInstance()->activeHub());
2473 
2474     if (fr)
2475         fr->disableChat();
2476 }
2477 
2478 void MainWindow::slotWidgetsToggle(){
2479     Q_D(MainWindow);
2480 
2481     QAction *act = reinterpret_cast<QAction*>(sender());
2482     auto it = d->menuWidgetsHash.find(act);
2483 
2484     if (it == d->menuWidgetsHash.end())
2485         return;
2486 
2487     ArenaWidgetManager::getInstance()->activate(it.value());
2488 }
2489 
2490 void MainWindow::slotQC(){
2491     QuickConnect qc;
2492 
2493     qc.exec();
2494 }
2495 
2496 void MainWindow::slotHideMainMenu(){
2497     toggleMainMenu(!menuBar()->isVisible());
2498 }
2499 
2500 void MainWindow::slotShowMainMenu() {
2501     QAction *act = qobject_cast<QAction*>(sender());
2502 
2503     if (!(act && act->menu()))
2504         return;
2505 
2506     act->menu()->exec(QCursor::pos());
2507 }
2508 
2509 void MainWindow::slotHideWindow(){
2510     Q_D(MainWindow);
2511 
2512     if (!d->isUnload && isActiveWindow() && WBGET(WB_TRAY_ENABLED)) {
2513         hide();
2514     }
2515 }
2516 
2517 void MainWindow::slotHideProgressSpace() {
2518     Q_D(MainWindow);
2519 
2520     if (WBGET(WB_SHOW_FREE_SPACE)) {
2521         d->progressSpace->hide();
2522         d->toolsHideProgressSpace->setText(tr("Show free space bar"));
2523 
2524         WBSET(WB_SHOW_FREE_SPACE, false);
2525     } else {
2526         d->progressSpace->show();
2527         d->toolsHideProgressSpace->setText(tr("Hide free space bar"));
2528 
2529         WBSET(WB_SHOW_FREE_SPACE, true);
2530     }
2531 }
2532 
2533 void MainWindow::slotHideLastStatus(){
2534     Q_D(MainWindow);
2535 
2536     bool st = WBGET(WB_LAST_STATUS);
2537 
2538     st = !st;
2539 
2540     if (!st)
2541         d->toolsHideLastStatus->setText(tr("Show last status message"));
2542     else
2543         d->toolsHideLastStatus->setText(tr("Hide last status message"));
2544 
2545     WBSET(WB_LAST_STATUS, st);
2546 
2547     reloadSomeSettings();
2548 }
2549 
2550 void MainWindow::slotHideUsersStatistics(){
2551     Q_D(MainWindow);
2552 
2553     bool st = WBGET(WB_USERS_STATISTICS);
2554 
2555     st = !st;
2556 
2557     if (!st)
2558         d->toolsHideUsersStatisctics->setText(tr("Show users statistics"));
2559     else
2560         d->toolsHideUsersStatisctics->setText(tr("Hide users statistics"));
2561 
2562     WBSET(WB_USERS_STATISTICS, st);
2563 
2564     reloadSomeSettings();
2565 }
2566 
2567 void MainWindow::slotExit(){
2568     setUnload(true);
2569 
2570     close();
2571 }
2572 
2573 void MainWindow::slotToolbarCustomization() {
2574     Q_D(MainWindow);
2575 
2576     QMenu *m = new QMenu(this);
2577 
2578     QMenu *toolButtonStyle = new QMenu(tr("Button style"), this);
2579     toolButtonStyle->addAction(tr("Icons only"))->setData(Qt::ToolButtonIconOnly);
2580     toolButtonStyle->addAction(tr("Text only"))->setData(Qt::ToolButtonTextOnly);
2581     toolButtonStyle->addAction(tr("Text beside icons"))->setData(Qt::ToolButtonTextBesideIcon);
2582     toolButtonStyle->addAction(tr("Text under icons"))->setData(Qt::ToolButtonTextUnderIcon);
2583 
2584     for (const auto &a : toolButtonStyle->actions()){
2585         a->setCheckable(true);
2586         a->setChecked(d->fBar->toolButtonStyle() == static_cast<Qt::ToolButtonStyle>(a->data().toInt()));
2587     }
2588 
2589     m->addMenu(toolButtonStyle);
2590     m->addSeparator();
2591 
2592     QAction *customize = m->addAction(tr("Customize"));
2593     QAction *ret = m->exec(QCursor::pos());
2594 
2595     m->deleteLater();
2596     toolButtonStyle->deleteLater();
2597 
2598     if (ret == customize){
2599         ActionCustomizer customizer(d->toolBarActions, d->fBar->actions(), this);
2600         connect(&customizer, SIGNAL(done(QList<QAction*>)), this, SLOT(slotToolbarCustomizerDone(QList<QAction*>)));
2601 
2602         customizer.exec();
2603     }
2604     else if (ret){
2605         d->fBar->setToolButtonStyle(static_cast<Qt::ToolButtonStyle>(ret->data().toInt()));
2606 
2607         WISET(TOOLBUTTON_STYLE, static_cast<int>(d->fBar->toolButtonStyle()));
2608     }
2609 }
2610 
2611 void MainWindow::slotToolbarCustomizerDone(const QList<QAction*> &enabled){
2612     Q_D(MainWindow);
2613 
2614     d->fBar->clear();
2615 
2616     QStringList enabled_list;
2617 
2618     for (const auto &act : enabled){
2619         if (!act)
2620             continue;
2621 
2622         d->fBar->addAction(act);
2623         enabled_list.push_back(act->objectName());
2624     }
2625 
2626     initFavHubMenu();
2627 
2628     WSSET(WS_MAINWINDOW_TOOLBAR_ACTS, enabled_list.join(";").toUtf8().toBase64());
2629 }
2630 
2631 void MainWindow::slotAboutOpenUrl(){
2632     Q_D(MainWindow);
2633 
2634     QAction *act = qobject_cast<QAction *>(sender());
2635     if (act == d->aboutHomepage){
2636         QDesktopServices::openUrl(QUrl("http://github.com/eiskaltdcpp/eiskaltdcpp/"));
2637     }
2638     else if (act == d->aboutSource){
2639         QDesktopServices::openUrl(QUrl("http://github.com/eiskaltdcpp/eiskaltdcpp/"));
2640     }
2641     else if (act == d->aboutIssues){
2642         QDesktopServices::openUrl(QUrl("https://github.com/eiskaltdcpp/eiskaltdcpp/issues"));
2643     }
2644     else if (act == d->aboutWiki){
2645         QDesktopServices::openUrl(QUrl("https://github.com/eiskaltdcpp/eiskaltdcpp/wiki"));
2646     }
2647     else if (act == d->aboutChangelog){
2648         // Now available: ChangeLog.txt, ChangeLog_ru.txt, ChangeLog_uk.txt
2649         QDesktopServices::openUrl(QUrl(tr("http://github.com/eiskaltdcpp/eiskaltdcpp/raw/master/ChangeLog.txt")));
2650     }
2651 }
2652 
2653 void MainWindow::slotAboutClient() {
2654     About a(this);
2655 
2656     double ratio;
2657     double down = static_cast<double>(SETTING(TOTAL_DOWNLOAD));
2658     double up   = static_cast<double>(SETTING(TOTAL_UPLOAD));
2659 
2660     if (down > 0)
2661         ratio = up / down;
2662     else
2663         ratio = 0;
2664 
2665     a.label->setText(QString("<b>%1</b> %2 (%3)")
2666                      .arg(EISKALTDCPP_WND_TITLE)
2667                      .arg(EISKALTDCPP_VERSION)
2668                      .arg(EISKALTDCPP_VERSION_SFX));
2669 
2670     QString html_format = "a { text-decoration:none; }\n"
2671                           "a:hover { text-decoration: underline; }\n";
2672 
2673     QString about_text = tr("EiskaltDC++ is a graphical client for Direct Connect and ADC protocols.<br/><br/>"
2674                             ""
2675                             "DC++ core version: %1 (modified)<br/><br/>"
2676                             ""
2677                             "Home page: <a href=\"https://github.com/eiskaltdcpp/eiskaltdcpp/\">"
2678                             "https://github.com/eiskaltdcpp/eiskaltdcpp/</a><br/><br/>"
2679                             ""
2680                             "Total up: <b>%2</b><br/>"
2681                             "Total down: <b>%3</b><br/>"
2682                             "Ratio: <b>%4</b>"
2683                          ).arg(DCVERSIONSTRING)
2684                           .arg(WulforUtil::formatBytes(up))
2685                           .arg(WulforUtil::formatBytes(down))
2686                           .arg(ratio, 0, 'f', 3);
2687 
2688     a.label_ABOUT->setText(about_text);
2689 
2690     a.textBrowser_AUTHORS->document()->setDefaultStyleSheet(html_format);
2691 
2692     a.textBrowser_AUTHORS->setText(
2693         tr("Please use <a href=\"https://github.com/eiskaltdcpp/eiskaltdcpp/issues\">"
2694         "https://github.com/eiskaltdcpp/eiskaltdcpp/issues</a> to report bugs.<br/>")+
2695         QString("<br/>")+
2696         tr("<b>Developers</b><br/>")+
2697         QString("<br/>")+
2698         QString("&nbsp; 2009-2012 <a href=\"mailto:dein.negativ@gmail.com\">Andrey Karlov</a><br/>")+
2699         tr("&nbsp;&nbsp;&nbsp; (main developer since version 0.4.10)<br/>")+
2700         QString("<br/>")+
2701         QString("&nbsp; 2009-2014 <a href=\"mailto:dhamp@ya.ru\">Eugene Petrov</a><br/>")+
2702         tr("&nbsp;&nbsp;&nbsp; (Arch Linux maintainer and developer since version 0.4.10)<br/>")+
2703         QString("<br/>")+
2704         QString("&nbsp; 2010-2014 <a href=\"mailto:tehnick-8@mail.ru\">Boris Pek</a> aka Tehnick<br/>")+
2705         tr("&nbsp;&nbsp;&nbsp; (Debian/Ubuntu maintainer and developer since version 1.89.0)<br/>")+
2706         QString("<br/>")+
2707         QString("&nbsp; 2010-2014 <a href=\"mailto:pavelvat@gmail.com\">Pavel Vatagin</a><br/>")+
2708         tr("&nbsp;&nbsp;&nbsp; (MS Windows maintainer and developer since version 2.2.4)<br/>")+
2709         QString("<br/>")+
2710         QString("&nbsp; 2010-2014 <a href=\"mailto:tka4ev@gmail.com\">Alexandr Tkachev</a><br/>")+
2711         tr("&nbsp;&nbsp;&nbsp; (developer since version 2.0.3)<br/>")+
2712         QString("<br/>")+
2713         tr("<b>Graphic files</b><br/>")+
2714         QString("<br/>")+
2715         QString("&nbsp; 2009-2010 <a href=\"mailto:wiselord1983@gmail.com\">Uladzimir Bely</a><br/>")+
2716         tr("&nbsp;&nbsp;&nbsp; (creator of the logo of the project)<br/>")+
2717         QString("<br/>")
2718         );
2719 
2720     a.textBrowser_TRANSLATION->document()->setDefaultStyleSheet(html_format);
2721 
2722     a.textBrowser_TRANSLATION->setText(
2723         tr("Participate in the translation. It is easy: "
2724         "<a href=\"https://www.transifex.com/projects/p/eiskaltdcpp/\">"
2725         "https://www.transifex.com/projects/p/eiskaltdcpp/</a><br/>")+
2726         QString("<br/>")+
2727         tr("Russian translation<br/>")+
2728         QString("&nbsp;&nbsp;&nbsp; 2009-2010 <a href=\"mailto:wiselord1983@gmail.com\">Uladzimir Bely</a><br/>")+
2729         QString("&nbsp;&nbsp;&nbsp; 2010-2014 <a href=\"mailto:tehnick-8@mail.ru\">Boris Pek</a> aka Tehnick<br/>")+
2730         QString("<br/>")+
2731         tr("Belarusian translation<br/>")+
2732         QString("&nbsp;&nbsp;&nbsp; 2009-2013 <a href=\"mailto:i.kliok@gmail.com\">Paval Shalamitski</a> aka Klyok<br/>")+
2733         QString("<br/>")+
2734         tr("Hungarian translation<br/>")+
2735         QString("&nbsp;&nbsp;&nbsp; 2010-2012 <a href=\"mailto:husumo@gmail.com\">Akos Berki</a> aka sumo<br/>")+
2736         QString("&nbsp;&nbsp;&nbsp; 2011-2014 <a href=\"mailto:marcus@elitemail.hu\">Márk Lutring</a><br/>")+
2737         QString("<br/>")+
2738         tr("French translation<br/>")+
2739         QString("&nbsp;&nbsp;&nbsp; 2010-2014 <a href=\"mailto:alexandre.wallimann@gmail.com\">Alexandre Wallimann</a> aka Jellyffs<br/>")+
2740         QString("<br/>")+
2741         tr("Polish translation<br/>")+
2742         QString("&nbsp;&nbsp;&nbsp; 2010-2012 <a href=\"mailto:arahael@gmail.com\">Arahael</a><br/>")+
2743         QString("<br/>")+
2744         tr("Ukrainian translation<br/>")+
2745         QString("&nbsp;&nbsp;&nbsp; 2010 <a href=\"mailto:dmytro.demenko@gmail.com\">Dmytro Demenko</a><br/>")+
2746         QString("&nbsp;&nbsp;&nbsp; 2013-2014 <a href=\"mailto:grayich@ukr.net\">gray</a> aka grayich<br/>")+
2747         QString("<br/>")+
2748         tr("Serbian (Cyrillic) translation<br/>")+
2749         QString("&nbsp;&nbsp;&nbsp; 2014 <a href=\"mailto:trifunovic@openmailbox.org\">Marko Trifunović</a><br/>")+
2750         QString("<br/>")+
2751         tr("Serbian (Latin) translation<br/>")+
2752         QString("&nbsp;&nbsp;&nbsp; 2010-2014 <a href=\"mailto:miroslav031@gmail.com\">Miroslav Petrovic</a><br/>")+
2753         QString("&nbsp;&nbsp;&nbsp; 2014 <a href=\"mailto:trifunovic@openmailbox.org\">Marko Trifunović</a><br/>")+
2754         QString("<br/>")+
2755         tr("Spanish translation<br/>")+
2756         QString("&nbsp;&nbsp;&nbsp; 2010-2014 <a href=\"mailto:sl1pkn07@gmail.com\">Gustavo Alvarez</a> aka sL1pKn07<br/>")+
2757         QString("&nbsp;&nbsp;&nbsp; 2012-2014 <a href=\"mailto:klondike at klondike.es\">Francisco Blas Izquierdo Riera</a> aka klondike<br/>")+
2758         QString("<br/>")+
2759         tr("Basque translation<br/>")+
2760         QString("&nbsp;&nbsp;&nbsp; 2014-2015 <a href=\"mailto:egoitzro2@hotmail.com\">Egoitz Rodriguez</a><br/>")+
2761         QString("<br/>")+
2762         tr("Bulgarian translation<br/>")+
2763         QString("&nbsp;&nbsp;&nbsp; 2010-2012 <a href=\"mailto:dimitrov.rusi@gmail.com\">Rusi Dimitrov</a> aka PsyTrip<br/>")+
2764         QString("<br/>")+
2765         tr("Slovak translation<br/>")+
2766         QString("&nbsp;&nbsp;&nbsp; 2010-2012 <a href=\"mailto:martin.durisin@gmail.com\">Martin Durisin</a><br/>")+
2767         QString("<br/>")+
2768         tr("Czech translation<br/>")+
2769         QString("&nbsp;&nbsp;&nbsp; 2011-2012 <a href=\"mailto:uhlikx@seznam.cz\">Uhlik</a><br/>")+
2770         QString("<br/>")+
2771         tr("German translation<br/>")+
2772         QString("&nbsp;&nbsp;&nbsp; 2011-2012 <a href=\"mailto:kgeorgokitsos@yahoo.de\">Konstantinos Georgokitsos</a><br/>")+
2773         QString("&nbsp;&nbsp;&nbsp; 2011-2012 <a href=\"mailto:tilkax@gmail.com\">Tillmann Karras</a><br/>")+
2774         QString("&nbsp;&nbsp;&nbsp; 2012-2014 <a href=\"mailto:be.w@mail.ru\">Benjamin Weber</a><br/>")+
2775         QString("<br/>")+
2776         tr("Greek translation<br/>")+
2777         QString("&nbsp;&nbsp;&nbsp; 2011-2012 <a href=\"mailto:kgeorgokitsos@yahoo.de\">Konstantinos Georgokitsos</a><br/>")+
2778         QString("<br/>")+
2779         tr("Italian translation<br/>")+
2780         QString("&nbsp;&nbsp;&nbsp; 2012 <a href=\"mailto:netcelli@gmail.com\">Stefano Simoncelli</a><br/>")+
2781         QString("&nbsp;&nbsp;&nbsp; 2012 <a href=\"mailto:lorenzo.keller@gmail.com\">Lorenzo Keller</a><br/>")+
2782         QString("<br/>")+
2783         tr("Portuguese (Brazil) translation<br/>")+
2784         QString("&nbsp;&nbsp;&nbsp; 2013-2015 <a href=\"mailto:heldercro@gmail.com\">Helder Cesar</a> aka redrum<br/>")+
2785         QString("<br/>")+
2786         tr("Vietnamese translation<br/>")+
2787         QString("&nbsp;&nbsp;&nbsp; 2013 <a href=\"mailto:ppanhh@gmail.com\">Anh Phan</a><br/>")+
2788         QString("<br/>")+
2789         tr("Chinese (China) translation<br/>")+
2790         QString("&nbsp;&nbsp;&nbsp; 2013 <a href=\"mailto:syaomingl@gmail.com\">Syaoming Lai</a><br/>")+
2791         QString("<br/>")+
2792         tr("Swedish (Sweden) translation<br/>")+
2793         QString("&nbsp;&nbsp;&nbsp; 2014 <a href=\"mailto:sopor@hotmail.com\">Sopor</a><br/>")+
2794         QString("<br/>")
2795         );
2796 
2797     a.textBrowser_LICENSE->document()->setDefaultStyleSheet(html_format);
2798 
2799     a.textBrowser_LICENSE->setText(
2800         QString("This program is free software: you can redistribute it and/or modify it under the terms "
2801                 "of the GNU General Public License as published by the Free Software Foundation, either "
2802                 "version 3 of the License, or (at your option) any later version.<br/>"
2803                 "<br/>"
2804                 "This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; "
2805                 "without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. "
2806                 "See the GNU General Public License for more details.<br/>"
2807                 "<br/>"
2808                 "You should have received a copy of the GNU General Public License along with this program. "
2809                 "If not, see &lt;<a href=\"http://www.gnu.org/licenses/\">http://www.gnu.org/licenses/</a>&gt;.<br/>")
2810         );
2811 
2812     a.exec();
2813 }
2814 
2815 void MainWindow::slotUnixSignal(int sig){
2816     printf("Received unix signal %i\n", sig);
2817 }
2818 
2819 void MainWindow::slotCloseCurrentWidget(){
2820     Q_D(MainWindow);
2821 
2822     ArenaWidget *awgt = dynamic_cast<ArenaWidget*>(d->arena->widget());
2823 
2824     if (awgt)
2825         ArenaWidgetManager::getInstance()->rem(awgt);
2826 }
2827 
2828 void MainWindow::slotSideBarDockMenu(){
2829     Q_D(MainWindow);
2830 
2831     QMenu *m = new QMenu(this);
2832     QAction *act = new QAction(tr("Show close buttons"), m);
2833 
2834     act->setCheckable(true);
2835     act->setChecked(WBGET(SIDEBAR_SHOW_CLOSEBUTTONS, true));
2836 
2837     m->addAction(act);
2838 
2839     if (m->exec(QCursor::pos())){
2840         WBSET(SIDEBAR_SHOW_CLOSEBUTTONS, act->isChecked());
2841 
2842         //repaint rows!
2843         if (d->sideDock && act->isChecked())
2844             d->sideDock->resize(d->sideDock->size()+QSize(18, 0));
2845         else if(d->sideDock)
2846             d->sideDock->resize(d->sideDock->size()+QSize(-18, 0));
2847     }
2848 
2849     m->deleteLater();
2850 }
2851 
2852 void MainWindow::slotAboutQt(){
2853     QMessageBox::aboutQt(this);
2854 }
2855 
2856 void MainWindow::slotUpdateFavHubMenu() {
2857     Q_D(MainWindow);
2858 
2859     d->favHubMenu->clear();
2860 
2861     const FavoriteHubEntryList& fl = FavoriteManager::getInstance()->getFavoriteHubs();
2862 
2863     for (auto &i : fl) {
2864         const FavoriteHubEntry &entry = *i;
2865 
2866         QString url = _q(entry.getServer());
2867         QString name = entry.getName().empty() ? tr("[No name]") : _q(entry.getName());
2868         QString encoding = WulforUtil::getInstance()->dcEnc2QtEnc(QString::fromStdString(entry.getEncoding()));
2869         QString menuItem = QString("%1 - %2").arg(name).arg(url);
2870 
2871         QAction *action = new QAction(menuItem, d->favHubMenu);
2872         action->setStatusTip(encoding);
2873         action->setToolTip(url);
2874 
2875         if (qobject_cast<HubFrame*>(HubManager::getInstance()->getHub(url))) {
2876             action->setCheckable(true);
2877             action->setChecked(true);
2878         }
2879 
2880         d->favHubMenu->addAction(action);
2881     }
2882 }
2883 
2884 void MainWindow::slotConnectFavHub(QAction *action) {
2885 
2886     QString url = action->toolTip();
2887     QString encoding = action->statusTip();
2888 
2889     newHubFrame(url, encoding);
2890 }
2891 
2892 void MainWindow::nextMsg(){
2893     Q_D(MainWindow);
2894 
2895     HubFrame *fr = qobject_cast<HubFrame*>(HubManager::getInstance()->activeHub());
2896 
2897     if (fr)
2898         fr->nextMsg();
2899     else{
2900         QWidget *wg = d->arena->widget();
2901 
2902         bool pmw = false;
2903 
2904         if (wg)
2905             pmw = (typeid(*wg) == typeid(PMWindow));
2906 
2907         if(pmw){
2908             PMWindow *pm = qobject_cast<PMWindow *>(wg);
2909 
2910             if (pm)
2911                 pm->nextMsg();
2912         }
2913     }
2914 }
2915 
2916 void MainWindow::prevMsg(){
2917     Q_D(MainWindow);
2918     HubFrame *fr = qobject_cast<HubFrame*>(HubManager::getInstance()->activeHub());
2919 
2920     if (fr)
2921         fr->prevMsg();
2922     else{
2923         QWidget *wg = d->arena->widget();
2924 
2925         bool pmw = false;
2926 
2927         if (wg)
2928             pmw = (typeid(*wg) == typeid(PMWindow));
2929 
2930         if(pmw){
2931             PMWindow *pm = qobject_cast<PMWindow *>(wg);
2932 
2933             if (pm)
2934                 pm->prevMsg();
2935         }
2936     }
2937 }
2938 
2939 void MainWindow::on(dcpp::LogManagerListener::Message, time_t t, const std::string& m) noexcept{
2940     emit coreLogMessage(_q(m.c_str()));
2941 }
2942 
2943 void MainWindow::on(dcpp::QueueManagerListener::Finished, QueueItem *item, const std::string &dir, int64_t) noexcept{
2944     if (item->isSet(QueueItem::FLAG_CLIENT_VIEW | QueueItem::FLAG_USER_LIST)){
2945         UserPtr user = item->getDownloads()[0]->getUser();
2946         QString listName = _q(item->getListName());
2947 
2948         emit coreOpenShare(user, listName, _q(dir));
2949     }
2950 
2951     const int qsize = QueueManager::getInstance()->lockQueue().size();
2952     QueueManager::getInstance()->unlockQueue();
2953 
2954     if (qsize == 1)
2955         emit notifyMessage(Notification::TRANSFER, tr("Download Queue"), tr("All downloads complete"));
2956 }
2957 
2958 void MainWindow::on(dcpp::TimerManagerListener::Second, uint64_t ticks) noexcept{
2959     static quint32 lastUpdate = 0;
2960     static quint64 lastUp = 0, lastDown = 0;
2961 
2962     quint64 now = GET_TICK();
2963 
2964     quint64 diff = now - lastUpdate;
2965     quint64 downBytes = 0;
2966     quint64 upBytes = 0;
2967 
2968     if (diff < 100U)
2969         diff = 1U;
2970 
2971     quint64 downDiff = Socket::getTotalDown() - lastDown;
2972     quint64 upDiff = Socket::getTotalUp() - lastUp;
2973 
2974     downBytes = (downDiff * 1000) / diff;
2975     upBytes = (upDiff * 1000) / diff;
2976 
2977     QMap<QString, QString> map;
2978 
2979     map["STATS"]    = _q(Client::getCounts());
2980     map["DSPEED"]   = WulforUtil::formatBytes(downBytes);
2981     map["DOWN"]     = WulforUtil::formatBytes(Socket::getTotalDown());
2982     map["USPEED"]   = WulforUtil::formatBytes(upBytes);
2983     map["UP"]       = WulforUtil::formatBytes(Socket::getTotalUp());
2984 
2985     lastUpdate = ticks;
2986     lastUp     = Socket::getTotalUp();
2987     lastDown   = Socket::getTotalDown();
2988 
2989     SettingsManager *SM = SettingsManager::getInstance();
2990     SM->set(SettingsManager::TOTAL_UPLOAD,   SETTING(TOTAL_UPLOAD)   + upDiff);
2991     SM->set(SettingsManager::TOTAL_DOWNLOAD, SETTING(TOTAL_DOWNLOAD) + downDiff);
2992 
2993     emit coreUpdateStats(map);
2994 }
2995 
2996 void MainWindow::slotShowSpeedLimits(){
2997     Notification *N = Notification::getInstance();
2998     if (N)
2999         N->slotShowSpeedLimits();
3000 }
3001 
3002 void MainWindow::slotSuppressTxt(){
3003     Notification *N = Notification::getInstance();
3004     QAction *act = qobject_cast<QAction*>(sender());
3005     if (N && act)
3006         N->setSuppressTxt(act->isChecked());
3007 }
3008 
3009 void MainWindow::slotSuppressSnd(){
3010     Notification *N = Notification::getInstance();
3011     QAction *act = qobject_cast<QAction*>(sender());
3012     if (N && act)
3013         N->setSuppressSnd(act->isChecked());
3014 }
3015 
3016 #if defined(Q_WS_MAC)
3017 extern void qt_mac_set_dock_menu(QMenu *menu); // Qt internal function
3018 
3019 void MainWindow::initDockMenuBar(){
3020     QMenu *menu = new QMenu(this);
3021     QAction *setup_speed_lim = new QAction(tr("Setup speed limits"), menu);
3022 
3023     setup_speed_lim->setIcon(WICON(WulforUtil::eiSPEED_LIMIT_ON));
3024 
3025     QMenu *menuAdditional = new QMenu(tr("Additional"), this);
3026     QAction *actSuppressSnd = new QAction(tr("Suppress sound notifications"), menuAdditional);
3027     QAction *actSuppressTxt = new QAction(tr("Suppress text notifications"), menuAdditional);
3028 
3029     actSuppressSnd->setCheckable(true);
3030     actSuppressSnd->setChecked(false);
3031 
3032     actSuppressTxt->setCheckable(true);
3033     actSuppressTxt->setChecked(false);
3034 
3035     connect(setup_speed_lim, SIGNAL(triggered()), this, SLOT(slotShowSpeedLimits()));
3036     connect(actSuppressTxt, SIGNAL(triggered()), this, SLOT(slotSuppressTxt()));
3037     connect(actSuppressSnd, SIGNAL(triggered()), this, SLOT(slotSuppressSnd()));
3038 
3039     menuAdditional->addActions(QList<QAction*>() << actSuppressTxt << actSuppressSnd);
3040     menu->addAction(setup_speed_lim);
3041     menu->addMenu(menuAdditional);
3042 
3043     qt_mac_set_dock_menu(menu);
3044 }
3045 #endif // defined(Q_WS_MAC)
3046 
3047