Rabbit Remote Control 0.1.0-bate9
Loading...
Searching...
No Matches
mainwindow.cpp
1// Author: Kang Lin <kl222@126.com>
2
3#include <QFontMetrics>
4#include <QGridLayout>
5#include <QMessageBox>
6#include <QCheckBox>
7#include <QScreen>
8#include <QApplication>
9#include <QDebug>
10#include <QDesktopServices>
11#include <QWidgetAction>
12#include <QMouseEvent>
13#include <QDrag>
14#include <QMimeData>
15#include <QKeySequence>
16#include <QPushButton>
17#include <QDateTime>
18#include <QFileDialog>
19#include <QLoggingCategory>
20#include <QThread>
21#include <QInputMethod>
22#include <QGuiApplication>
23
24#include "mainwindow.h"
25#include "ui_mainwindow.h"
26#ifdef HAVE_UPDATE
27 #include "FrmUpdater.h"
28#endif
29#include "RabbitCommonDir.h"
30#include "RabbitCommonTools.h"
31
32#ifdef HAVE_ABOUT
33 #include "DlgAbout.h"
34#endif
35#ifdef BUILD_QUIWidget
36 #include "QUIWidget/QUIWidget.h"
37#endif
38
39#include "Operate.h"
40#include "FrmFullScreenToolBar.h"
41#include "ParameterDlgSettings.h"
42
43#include "ViewTable.h"
44#include "ViewSplitter.h"
45
46#ifdef HAVE_ICE
47 #include "Ice.h"
48#endif
49
50static Q_LOGGING_CATEGORY(log, "App.MainWindow")
51static Q_LOGGING_CATEGORY(logRecord, "App.MainWindow.Record")
52
53MainWindow::MainWindow(QWidget *parent)
54 : QMainWindow(parent)
55 , m_pToolBarMenuAction(nullptr)
56 , m_pMenuActivityGroup(nullptr)
57 , m_ptbMenuActivity(nullptr)
58 , m_pActionOperateMenu(nullptr)
59 , m_pTBOperate(nullptr)
60 , m_pActionTBOperate(nullptr)
61 , m_pDockRecent(nullptr)
62 , m_pRecent(nullptr)
63 , m_pDockActive(nullptr)
64 , m_pFrmActive(nullptr)
65 , m_pSecureLevel(nullptr)
66 , m_pSignalStatus(nullptr)
67 , ui(new Ui::MainWindow)
68 , m_pView(nullptr)
69 , m_pFullScreenToolBar(nullptr)
70 , m_pRecentMenu(nullptr)
71 , m_pDockFavorite(nullptr)
72 , m_pFavoriteView(nullptr)
73 , m_StatusBarMessage(this)
74{
75 bool check = false;
76
77 ui->setupUi(this);
78 ui->menubar->show();
79
84 QWidget* pContain = new QWidget(this);
85 if(pContain) {
86 pContain->setContentsMargins(0, 0, 0, 0);
87 setCentralWidget(pContain);
88 }
89
90 ui->actionKeyboard->setVisible(false);
91#if ANDROID
92 bool bVisible = (nullptr != QGuiApplication::inputMethod());
93 ui->actionKeyboard->setVisible(bVisible);
94 ui->actionKeyboard->setEnabled(bVisible);
95#endif
96
97 check = connect(&m_Manager, &CManager::sigNewOperate,
98 this, [&](COperate* pOperate, bool bOpenSettingsDialog) {
99 Start(pOperate, bOpenSettingsDialog);
100 });
101 Q_ASSERT(check);
102
103#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) && !defined(Q_OS_MACOS)
104 // gnome icon isn't support svg
105 setWindowIcon(QIcon(":/images/app"));
106#endif
107
108 /*
109 QSize screenSize;
110 if(QApplication::primaryScreen()) {
111 screenSize = QApplication::primaryScreen()->availableSize();
112 //TODO: 当支持多屏幕时,修改此处
113 //screenSize = QApplication::primaryScreen()->availableVirtualSize();
114 }
115 if(!screenSize.isEmpty())
116 setMaximumSize(screenSize);
117 //*/
118
119 //m_StatusBarMessage.setSizePolicy(QSizePolicy::Policy::Expanding,
120 // QSizePolicy::Policy::Fixed);
121 //m_StatusBarMessage.setWordWrap(true);
122 this->statusBar()->addPermanentWidget(&m_StatusBarMessage);
123
124 m_SendRate.setToolTip(tr("Send rate"));
125 m_SendRate.setStatusTip(tr("Send rate"));
126 // m_SendRate.setSizePolicy(QSizePolicy::Policy::Preferred,
127 // QSizePolicy::Policy::Fixed);
128 this->statusBar()->addPermanentWidget(&m_SendRate);
129 m_ReceivesRate.setToolTip(tr("Receives rate"));
130 m_ReceivesRate.setStatusTip(tr("Receives rate"));
131 // m_ReceivesRate.setSizePolicy(QSizePolicy::Policy::Preferred,
132 // QSizePolicy::Policy::Fixed);
133 this->statusBar()->addPermanentWidget(&m_ReceivesRate);
134 m_TotalSends.setToolTip(tr("Total sends"));
135 m_TotalSends.setStatusTip(tr("Total sends"));
136 // m_TotalSends.setSizePolicy(QSizePolicy::Policy::Preferred,
137 // QSizePolicy::Policy::Fixed);
138 this->statusBar()->addPermanentWidget(&m_TotalSends);
139 m_TotalReceives.setToolTip(tr("Total receives"));
140 m_TotalReceives.setStatusTip(tr("Total receives"));
141 // m_TotalReceives.setSizePolicy(QSizePolicy::Policy::Preferred,
142 // QSizePolicy::Policy::Fixed);
143 this->statusBar()->addPermanentWidget(&m_TotalReceives);
144
145 check = connect(&m_Timer, SIGNAL(timeout()), this, SLOT(slotTimeOut()));
146 Q_ASSERT(check);
147
148 m_pSecureLevel = new QLabel(statusBar());
149 // QIcon icon = QIcon::fromTheme("network-wired");
150 // QPixmap pixmap = icon.pixmap(icon.actualSize(QSize(64, 64)));
151 // m_pSecureLevel->setPixmap(pixmap);
152 m_pSecureLevel->hide();
153 statusBar()->addPermanentWidget(m_pSecureLevel);
154
155 //setFocusPolicy(Qt::NoFocus);
156 //addToolBar(Qt::LeftToolBarArea, ui->toolBar);
157 setAcceptDrops(true);
158
159 RabbitCommon::CTools::AddStyleMenu(ui->menuTools);
160 ui->menuTools->addMenu(RabbitCommon::CTools::GetLogMenu(this));
161
162 m_pRecentMenu = new RabbitCommon::CRecentMenu(
163 tr("Recently"), QIcon::fromTheme("document-open-recent"), false, this);
164 check = connect(m_pRecentMenu, SIGNAL(recentFileTriggered(const QString&)),
165 this, SLOT(slotOpenFile(const QString&)));
166 Q_ASSERT(check);
167 check = connect(&m_Parameter, SIGNAL(sigRecentMenuMaxCountChanged(int)),
168 m_pRecentMenu, SLOT(setMaxCount(int)));
169 Q_ASSERT(check);
170 QAction* pRecentAction = ui->menuOperate->insertMenu(
171 ui->actionOpenListRecent, m_pRecentMenu);
172 pRecentAction->setStatusTip(pRecentAction->text());
173 QToolButton* tbRecent = new QToolButton(ui->toolBar);
174 tbRecent->setFocusPolicy(Qt::NoFocus);
175 tbRecent->setPopupMode(QToolButton::InstantPopup);
176 tbRecent->setMenu(m_pRecentMenu);
177 tbRecent->setIcon(pRecentAction->icon());
178 tbRecent->setText(pRecentAction->text());
179 tbRecent->setToolTip(pRecentAction->toolTip());
180 tbRecent->setStatusTip(pRecentAction->statusTip());
181 ui->toolBar->insertWidget(ui->actionOpenListRecent, tbRecent);
182
183#ifdef HAVE_UPDATE
184 CFrmUpdater updater;
185 ui->actionUpdate->setIcon(updater.windowIcon());
186#endif
187
188 QToolButton* tbStart = new QToolButton(ui->toolBar);
189 tbStart->setFocusPolicy(Qt::NoFocus);
190 tbStart->setPopupMode(QToolButton::InstantPopup);
191 //tbStart->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
192 tbStart->setMenu(ui->menuStart);
193 tbStart->setIcon(QIcon::fromTheme("media-playback-start"));
194 tbStart->setText(tr("Start"));
195 tbStart->setToolTip(tr("Start"));
196 tbStart->setStatusTip(tr("Start"));
197 ui->toolBar->insertWidget(ui->actionStop, tbStart);
198
199 m_Parameter.Load();
200
201 check = connect(&m_Parameter, SIGNAL(sigReceiveShortCutChanged()),
202 this, SLOT(slotShortCut()));
203 Q_ASSERT(check);
204 slotSystemTrayIconTypeChanged();
205 check = connect(&m_Parameter, SIGNAL(sigSystemTrayIconTypeChanged()),
206 this,
207 SLOT(slotSystemTrayIconTypeChanged()));
208 Q_ASSERT(check);
209 check = connect(&m_Parameter, SIGNAL(sigEnableSystemTrayIcon()),
210 this, SLOT(slotEnableSystemTrayIcon()));
211 Q_ASSERT(check);
212 check = connect(&m_Parameter, SIGNAL(sigEnableTabToolTipChanged()),
213 this, SLOT(slotUpdateName()));
214 Q_ASSERT(check);
215 check = connect(&m_Parameter, SIGNAL(sigEnableTabIconChanged()),
216 this, SLOT(slotUpdateName()));
217 Q_ASSERT(check);
218
219 auto pTbMenu = new QToolButton(ui->toolBar);
220 pTbMenu->setFocusPolicy(Qt::NoFocus);
221 pTbMenu->setPopupMode(QToolButton::InstantPopup);
222 //m_pTbMenu->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
223 pTbMenu->setText(ui->actionMain_menu_bar_M->text());
224 pTbMenu->setIcon(ui->actionMain_menu_bar_M->icon());
225 pTbMenu->setToolTip(ui->actionMain_menu_bar_M->toolTip());
226 pTbMenu->setStatusTip(ui->actionMain_menu_bar_M->statusTip());
227 QMenu *pMenu = new QMenu(pTbMenu);
228 pMenu->addActions(this->menuBar()->actions());
229 pTbMenu->setMenu(pMenu);
230 m_pToolBarMenuAction = ui->toolBar->insertWidget(ui->actionTabBar_B, pTbMenu);
231#if defined(Q_OS_ANDROID)
232 m_pToolBarMenuAction->setVisible(true);
233#else
234 m_pToolBarMenuAction->setVisible(false);
235#endif
236
237 check = connect(&m_Parameter, SIGNAL(sigStartByTypeChanged()),
238 this, SLOT(slotStartByType()));
239 Q_ASSERT(check);
240
241 m_pDockFavorite = new QDockWidget(this);
242 if(m_pDockFavorite)
243 {
244 m_pFavoriteView = new CFavoriteView(&m_Parameter, m_pDockFavorite);
245 if(m_pFavoriteView)
246 {
247 if(m_pFavoriteView->m_pDockTitleBar)
248 m_pDockFavorite->setTitleBarWidget(m_pFavoriteView->m_pDockTitleBar);
249 check = connect(m_pFavoriteView, SIGNAL(sigStart(const QString&, bool)),
250 this, SLOT(slotOpenFile(const QString&, bool)));
251 Q_ASSERT(check);
252 check = connect(m_pFavoriteView, SIGNAL(sigFavorite()),
253 this, SLOT(on_actionAdd_to_favorite_triggered()));
254 Q_ASSERT(check);
255 check = connect(m_pFavoriteView, &CFavoriteView::sigShowMessageBox,
257 Q_ASSERT(check);
258 check = connect(&m_Parameter, SIGNAL(sigFavoriteEditChanged(bool)),
259 m_pFavoriteView, SLOT(slotDoubleEditNode(bool)));
260 Q_ASSERT(check);
261 emit m_Parameter.sigFavoriteEditChanged(m_Parameter.GetFavoriteEdit());
262 m_pDockFavorite->setWidget(m_pFavoriteView);
263 m_pDockFavorite->setWindowTitle(m_pFavoriteView->windowTitle());
264 }
265 // Must set ObjectName then restore it. See: saveState help document
266 m_pDockFavorite->setObjectName("dockFavorite");
267#if defined(Q_OS_ANDROID)
268 m_pDockFavorite->hide();
269#endif
270 ui->menuView->addAction(m_pDockFavorite->toggleViewAction());
271 m_pDockFavorite->toggleViewAction()->setIcon(QIcon::fromTheme("emblem-favorite"));
272 addDockWidget(Qt::DockWidgetArea::LeftDockWidgetArea, m_pDockFavorite);
273 }
274
275 m_pDockRecent = new QDockWidget(this);
276 if(m_pDockRecent)
277 {
278 m_pRecent
279 = new CFrmRecent(this, &m_Manager, m_Parameter, true,
280 m_pDockRecent);
281 if(m_pRecent) {
282 if(m_pRecent->m_pDockTitleBar)
283 m_pDockRecent->setTitleBarWidget(
284 m_pRecent->m_pDockTitleBar);
285 check = connect(m_pRecent,
286 SIGNAL(sigStart(const QString&, bool)),
287 this, SLOT(slotOpenFile(const QString&, bool)));
288 Q_ASSERT(check);
289 check = connect(m_pRecent, &CFrmRecent::sigAddToFavorite,
290 m_pFavoriteView, &CFavoriteView::slotAddToFavorite);
291 Q_ASSERT(check);
292 check = connect(m_pRecent, &CFrmRecent::sigShowMessageBox,
294 Q_ASSERT(check);
295 m_pDockRecent->setWidget(m_pRecent);
296 m_pDockRecent->setWindowTitle(
297 m_pRecent->windowTitle());
298 }
299 // Must set ObjectName then restore it. See: saveState help document
300 m_pDockRecent->setObjectName("dockRecent");
301#if defined(Q_OS_ANDROID)
302 m_pDockRecent->hide();
303#endif
304 ui->menuView->addAction(m_pDockRecent->toggleViewAction());
305 m_pDockRecent->toggleViewAction()->setIcon(QIcon::fromTheme("document-open-recent"));
306 tabifyDockWidget(m_pDockFavorite, m_pDockRecent);
307 }
308
309 m_pDockActive = new QDockWidget(this);
310 if(m_pDockActive)
311 {
312 m_pFrmActive = new CFrmActive(
313 m_Operates, m_Parameter,
314 ui->menuStart, ui->actionStop,
315 m_pRecentMenu, m_pDockActive);
316 if(m_pFrmActive) {
317 m_pDockActive->setWidget(m_pFrmActive);
318 if(m_pFrmActive->m_pDockTitleBar)
319 m_pDockActive->setTitleBarWidget(
320 m_pFrmActive->m_pDockTitleBar);
321 m_pDockActive->setWindowTitle(m_pFrmActive->windowTitle());
322 check = connect(m_pFrmActive, SIGNAL(sigChanged(COperate*)),
323 this, SLOT(slotOperateChanged(COperate*)));
324 Q_ASSERT(check);
325 check = connect(m_pFrmActive, &CFrmActive::sigAddToFavorite,
326 m_pFavoriteView, &CFavoriteView::slotAddToFavorite);
327 Q_ASSERT(check);
328 }
329 m_pDockActive->setObjectName("dockListActive");
330#if defined(Q_OS_ANDROID)
331 m_pDockActive->hide();
332#endif
333 ui->menuView->addAction(m_pDockActive->toggleViewAction());
334 m_pDockActive->toggleViewAction()->setIcon(QIcon::fromTheme("network-wired"));
335 tabifyDockWidget(m_pDockFavorite, m_pDockActive);
336 }
337
338 QActionGroup* pGBView = new QActionGroup(this);
339 if(pGBView) {
340 pGBView->addAction(ui->actionViewTab);
341 pGBView->addAction(ui->actionViewSplit);
342 }
343 qDebug(log) << "View type:" << m_Parameter.GetViewType();
344 if(CParameterApp::ViewType::Tab == m_Parameter.GetViewType()) {
345 ui->actionViewTab->setChecked(true);
346 on_actionViewTab_triggered();
347 }
348 if(CParameterApp::ViewType::Splitter == m_Parameter.GetViewType()) {
349 ui->actionViewSplit->setChecked(true);
350 on_actionViewSplit_triggered();
351 }
352 check = connect(&m_Parameter, &CParameterApp::sigViewTypeChanged,
353 this, [&](){
354 m_Parameter.Save();
355 });
356 Q_ASSERT(check);
357
358 m_pMenuActivityGroup = new QActionGroup(ui->menuActivity);
359 m_ptbMenuActivity = new QToolButton(ui->toolBar);
360 m_ptbMenuActivity->setFocusPolicy(Qt::NoFocus);
361 m_ptbMenuActivity->setPopupMode(QToolButton::InstantPopup);
362 m_ptbMenuActivity->setMenu(ui->menuActivity);
363 m_ptbMenuActivity->setIcon(ui->menuActivity->icon());
364 m_ptbMenuActivity->setText(ui->menuActivity->title());
365 m_ptbMenuActivity->setToolTip(ui->menuActivity->toolTip());
366 m_ptbMenuActivity->setStatusTip(ui->menuActivity->statusTip());
367 ui->toolBar->insertWidget(ui->actionTabBar_B, m_ptbMenuActivity);
368
369 EnableMenu(false);
370 slotShortCut();
371
372#ifdef HAVE_ICE
373 if(CICE::Instance()->GetSignal())
374 {
375 check = connect(CICE::Instance()->GetSignal().data(),
376 SIGNAL(sigConnected()),
377 this, SLOT(slotSignalConnected()));
378 Q_ASSERT(check);
379 check = connect(CICE::Instance()->GetSignal().data(),
380 SIGNAL(sigDisconnected()),
381 this, SLOT(slotSignalDisconnected()));
382 Q_ASSERT(check);
383 check = connect(CICE::Instance()->GetSignal().data(),
384 SIGNAL(sigError(const int, const QString&)),
385 this, SLOT(slotSignalError(const int, const QString&)));
386 Q_ASSERT(check);
387 }
388 CICE::Instance()->slotStart(statusBar());
389 m_pSignalStatus = new QPushButton();
390 m_pSignalStatus->setToolTip(tr("ICE signal status"));
391 m_pSignalStatus->setStatusTip(m_pSignalStatus->toolTip());
392 m_pSignalStatus->setWhatsThis(m_pSignalStatus->toolTip());
393 slotSignalDisconnected();
394 statusBar()->addPermanentWidget(m_pSignalStatus);
395#endif
396
397 if(m_Parameter.GetSaveMainWindowStatus())
398 {
399 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
400 QSettings::IniFormat);
401 QByteArray geometry
402 = set.value("MainWindow/Status/Geometry").toByteArray();
403 if(!geometry.isEmpty())
404 restoreGeometry(geometry);
405 // Restores the state of this mainwindow's toolbars and dockwidgets
406 QByteArray state = set.value("MainWindow/Status/State").toByteArray();
407 if(!state.isEmpty())
408 restoreState(state);
409
410 ui->actionTabBar_B->setChecked(m_Parameter.GetTabBar());
411 on_actionTabBar_B_toggled(m_Parameter.GetTabBar());
412 ui->actionStatus_bar_S->setChecked(m_Parameter.GetStatusBar());
413 statusBar()->setVisible(m_Parameter.GetStatusBar());
414 ui->actionMain_menu_bar_M->setChecked(m_Parameter.GetMenuBar());
415 menuBar()->setVisible(m_Parameter.GetMenuBar());
416 ui->actionToolBar_T->setChecked(!ui->toolBar->isHidden());
417 // macOS: Hide 'Main menu bar' on macOS since it's always visible
418 #ifdef Q_OS_MACOS
419 // Hide 'Main menu bar' on View menu
420 ui->actionMain_menu_bar_M->setVisible(false);
421 #else
422 // Show 'Main menu bar' toolbar icon
423 if(!m_Parameter.GetMenuBar()) {
424 m_pToolBarMenuAction->setVisible(true);
425 }
426 #endif
427 }
428}
429
430MainWindow::~MainWindow()
431{
432 qDebug(log) << "MainWindow::~MainWindow()";
433 if(m_pFullScreenToolBar) m_pFullScreenToolBar->close();
434 delete ui;
435}
436
439{
440 qDebug(log) << Q_FUNC_INFO;
441
442 int nRet = 0;
443 QString szErr;
444
445 setEnabled(false);
446 do {
447 QMessageBox initMsgBox(QMessageBox::Information, tr("Load"), tr("Load ......"));
448 initMsgBox.showNormal();
449 qApp->processEvents();
450
451 QString szMsg;
452 szMsg = tr("Load plugins ......");
453 initMsgBox.setText(szMsg);
454 slotInformation(szMsg);
455 qApp->processEvents();
456 nRet = m_Manager.Initial();
457 if(nRet) {
458 szErr = tr("Initial manage error");
459 break;
460 }
461 m_Manager.EnumPlugins(this);
462
463 auto pg = m_Manager.GetGlobalParameters();
464 if(pg) {
465 //m_Parameter.SetGlobalParameters(pg);
466 bool bRet = QMetaObject::invokeMethod(
467 &m_Parameter,
468 "SetGlobalParameters",
469 Qt::DirectConnection,
470 Q_ARG(CParameterGlobal*, pg));
471 if(!bRet) {
472 szErr = tr("Failed to set global parameters");
473 qCritical(log) << szErr;
474 nRet = -1;
475 break;
476 }
477 }
478
479 if(m_pRecent) {
480 szMsg = tr("Load list recent dock ......");
481 initMsgBox.setText(szMsg);
482 slotInformation(szMsg);
483 qApp->processEvents();
484 nRet = m_pRecent->Initial();
485 if(nRet) {
486 szErr = tr("Initial recent dock error");
487 break;
488 }
489 }
490
491 if(m_pRecentMenu) {
492 szMsg = tr("Load recent menu ......");
493 initMsgBox.setText(szMsg);
494 slotInformation(szMsg);
495 qApp->processEvents();
496 if(m_pRecent) {
497 auto recents = m_pRecent->GetRecents(m_Parameter.GetRecentMenuMaxCount());
498 //qDebug(log) << "recents totaol:" << recents.size() << m_Parameter.GetRecentMenuMaxCount();
499 for(auto it = recents.rbegin(); it != recents.rend(); it++) {
500 m_pRecentMenu->addRecentFile(it->GetFile(), it->szName, it->icon);
501 }
502 m_pRecentMenu->slotShowFileEixst(
503 m_Parameter.GetGlobalParameters()->GetSaveSettingsType() == CParameterGlobal::File);
504 bool check = connect(
505 m_Parameter.GetGlobalParameters(),
506 &CParameterGlobal::sigSaveSettingsTypeChanged,
507 m_pRecentMenu, [this]() {
508 if(!(m_pRecentMenu && m_Parameter.GetGlobalParameters()))
509 return;
510 m_pRecentMenu->slotShowFileEixst(
511 m_Parameter.GetGlobalParameters()->GetSaveSettingsType() == CParameterGlobal::File);
512 });
513 Q_ASSERT(check);
514 }
515 }
516
517 if(m_pFavoriteView) {
518 szMsg = tr("Load favorite ......");
519 initMsgBox.setText(szMsg);
520 slotInformation(szMsg);
521 qApp->processEvents();
522 nRet = m_pFavoriteView->Initial();
523 if(nRet) {
524 szErr = tr("Initial favorite error");
525 break;
526 }
527 }
528
529 slotEnableSystemTrayIcon();
530
531 setEnabled(true);
532
533 szMsg = tr("Load laster operate ......");
534 initMsgBox.setText(szMsg);
535 slotInformation(szMsg);
536 qApp->processEvents();
537 nRet = LoadOperateLasterClose();
538 if(nRet) {
539 szErr = tr("Initial load laster close operate error");
540 break;
541 }
542
543 slotInformation(tr("Ready"));
544
545 return nRet;
546 } while(false);
547
548 setEnabled(true);
549
550 slotError(nRet, szErr);
551 QMessageBox errMsgBox;
552 errMsgBox.setWindowTitle(QObject::tr("Error"));
553 errMsgBox.setText(QObject::tr("Initial error:") + szErr);
554 errMsgBox.setIcon(QMessageBox::Critical);
555
556 auto logMenu = RabbitCommon::CTools::GetLogMenu();
557 QPushButton *pbLog = new QPushButton(logMenu->title());
558 pbLog->setMenu(logMenu);
559
560 QPushButton *pbettings = new QPushButton(ui->actionSettings->text());
561 QMenu* pSettings = new QMenu(pbettings);
562 pSettings->addAction(ui->actionSettings);
563 pbettings->setMenu(pSettings);
564 errMsgBox.addButton(pbettings, QMessageBox::ActionRole);
565 errMsgBox.addButton(pbLog, QMessageBox::ActionRole);
566 errMsgBox.addButton(QMessageBox::Cancel);
567
568 errMsgBox.exec();
569
570 return nRet;
571}
572
573void MainWindow::SetView(CView* pView)
574{
575 qDebug(log) << Q_FUNC_INFO;
576 if(!pView)
577 return;
578 if(m_pView)
579 m_pView->disconnect();
580
581 m_pView = pView;
582 auto* pContain = centralWidget();
583 if(!pContain) return;
584 auto* pOldLayout = pContain->layout();
585 if(pOldLayout) {
586 pContain->setLayout(nullptr);
587 // Remove all child controls from the layout
588 QLayoutItem* item;
589 while ((item = pOldLayout->takeAt(0)) != nullptr) {
590 if (item->widget()) {
591 item->widget()->deleteLater();
592 }
593 delete item;
594 }
595 delete pOldLayout;
596 }
597 auto* pLayout = new QVBoxLayout(pContain);
598 if(pLayout) {
599 pLayout->setContentsMargins(0, 0, 0, 0);
600 pLayout->setSpacing(0);
601 pContain->setLayout(pLayout);
602 pLayout->addWidget(m_pView);
603 }
604
605 bool check = false;
606 //m_pView->setFocusPolicy(Qt::NoFocus);
607 check = connect(m_pView, SIGNAL(sigCloseView(const QWidget*)),
608 this, SLOT(slotCloseView(const QWidget*)));
609 Q_ASSERT(check);
610 check = connect(m_pView, SIGNAL(sigCurrentChanged(const QWidget*)),
611 this, SLOT(slotCurrentViewChanged(const QWidget*)));
612 Q_ASSERT(check);
613 if(m_pFrmActive) {
614 check = connect(m_pView, SIGNAL(sigCurrentChanged(const QWidget*)),
615 m_pFrmActive, SLOT(slotViewChanged(const QWidget*)));
616 Q_ASSERT(check);
617 }
618 check = connect(m_pView, SIGNAL(customContextMenuRequested(const QPoint&)),
619 this, SLOT(slotCustomContextMenuRequested(const QPoint&)));
620 Q_ASSERT(check);
621
622 foreach (auto c, m_Operates) {
623 m_pView->AddView(c->GetViewer());
624 m_pView->SetWidowsTitle(
625 c->GetViewer(), c->Name(), c->Icon(), c->Description());
626 }
627 m_pView->SetVisibleTab(m_Parameter.GetTabBar());
628}
629
630void MainWindow::on_actionViewTab_triggered()
631{
632 qDebug(log) << Q_FUNC_INFO;
633 if(!ui->actionViewTab->isChecked()) return;
634 m_Parameter.SetViewType(CParameterApp::ViewType::Tab);
635 SetView(new CViewTable(&m_Parameter, this));
636}
637
638void MainWindow::on_actionViewSplit_triggered()
639{
640 qDebug(log) << Q_FUNC_INFO;
641 if(!ui->actionViewSplit->isChecked()) return;
642 m_Parameter.SetViewType(CParameterApp::ViewType::Splitter);
643 SetView(new CViewSplitter(&m_Parameter, this));
644}
645
646void MainWindow::on_actionAbout_triggered()
647{
648#ifdef HAVE_ABOUT
649 CDlgAbout *about = new CDlgAbout(this);
650 QIcon icon = QIcon::fromTheme("app");
651 if(!icon.isNull()) {
652 auto sizeList = icon.availableSizes();
653 if(!sizeList.isEmpty()) {
654 QPixmap p = icon.pixmap(*sizeList.begin());
655 about->m_AppIcon = p.toImage();
656 }
657 }
658 about->m_szBuildTime = QString("%1/%2").arg(__DATE__, __TIME__);
659 about->m_szCopyrightStartTime = "2020";
660 about->m_szVersionRevision = RabbitRemoteControl_REVISION;
661 about->m_szDetails = m_Manager.Details();
662 RC_SHOW_WINDOW(about);
663#endif
664}
665
666void MainWindow::on_actionUpdate_triggered()
667{
668 if(!qEnvironmentVariable("SNAP").isEmpty()) {
669 QDesktopServices::openUrl(QUrl("https://snapcraft.io/rabbitremotecontrol"));
670 } else if(!qEnvironmentVariable("FLATPAK_ID").isEmpty()) {
671 QDesktopServices::openUrl(QUrl("https://flathub.org/apps/io.github.KangLin.RabbitRemoteControl"));
672 } else {
673#ifdef HAVE_UPDATE
674 CFrmUpdater* m_pfrmUpdater = new CFrmUpdater();
675 QIcon icon = QIcon::fromTheme("app");
676 if(!icon.isNull()) {
677 auto sizeList = icon.availableSizes();
678 if(!sizeList.isEmpty()) {
679 QPixmap p = icon.pixmap(*sizeList.begin());
680 m_pfrmUpdater->SetTitle(p.toImage());
681 }
682 }
683 m_pfrmUpdater->SetInstallAutoStartup();
684 RC_SHOW_WINDOW(m_pfrmUpdater);
685#endif
686 }
687}
688
689void MainWindow::on_actionFull_screen_F_triggered()
690{
691 if(m_pView)
692 {
693 m_pView->SetFullScreen(!isFullScreen());
694 }
695
696 if(isFullScreen())
697 {
698 qDebug(log) << "Exit full screen";
699 ui->actionFull_screen_F->setIcon(QIcon::fromTheme("view-fullscreen"));
700 ui->actionFull_screen_F->setText(tr("Full screen"));
701 ui->actionFull_screen_F->setToolTip(tr("Full screen"));
702 ui->actionFull_screen_F->setStatusTip(tr("Full screen"));
703 ui->actionFull_screen_F->setWhatsThis(tr("Full screen"));
704
705 ui->toolBar->setVisible(m_FullState.toolBar);
706 ui->statusbar->setVisible(m_FullState.statusbar);
707 ui->menubar->setVisible(m_FullState.menubar);
708
709 m_pDockActive->setVisible(m_FullState.dockListActive);
710 m_pDockRecent->setVisible(m_FullState.dockListRecent);
711 m_pDockFavorite->setVisible(m_FullState.dockFavorite);
712 // TODO: This is hade code. it is in RabbitCommon
713 QDockWidget* pDockDebugLog = findChild<QDockWidget*>("dockDebugLog");
714 if(pDockDebugLog)
715 {
716 pDockDebugLog->setVisible(m_FullState.dockDebugLog);
717 }
718
719 if(m_pFullScreenToolBar)
720 {
721 // Delete it when the widget is close
722 m_pFullScreenToolBar->close();
723 m_pFullScreenToolBar = nullptr;
724 }
725
726 emit sigShowNormal();
727 this->showNormal();
728 this->activateWindow();
729
730 emit sigFullScreen(false);
731 return;
732 }
733
734 qDebug(log) << "Entry full screen";
735
736 //setWindowFlags(Qt::FramelessWindowHint | windowFlags());
737 this->showFullScreen();
738 emit sigFullScreen(true);
739
740 ui->actionFull_screen_F->setIcon(QIcon::fromTheme("view-restore"));
741 ui->actionFull_screen_F->setText(tr("Exit full screen"));
742 ui->actionFull_screen_F->setToolTip(tr("Exit full screen"));
743 ui->actionFull_screen_F->setStatusTip(tr("Exit full screen"));
744 ui->actionFull_screen_F->setWhatsThis(tr("Exit full screen"));
745
746 m_FullState.toolBar = ui->toolBar->isVisible();
747 ui->toolBar->setVisible(false);
748 m_FullState.statusbar = ui->statusbar->isVisible();
749 ui->statusbar->setVisible(false);
750 m_FullState.menubar = ui->menubar->isVisible();
751 ui->menubar->setVisible(false);
752
753 m_FullState.dockListActive = m_pDockActive->isVisible();
754 m_pDockActive->setVisible(false);
755 m_FullState.dockListRecent = m_pDockRecent->isVisible();
756 m_pDockRecent->setVisible(false);
757 m_FullState.dockFavorite = m_pDockFavorite->isVisible();
758 m_pDockFavorite->setVisible(false);
759 // This is hade code. it is in RabbitCommon
760 QDockWidget* pDockDebugLog = findChild<QDockWidget*>("dockDebugLog");
761 if(pDockDebugLog)
762 {
763 m_FullState.dockDebugLog = pDockDebugLog->isVisible();
764 pDockDebugLog->setVisible(false);
765 }
766
767 if(m_pFullScreenToolBar) m_pFullScreenToolBar->close();
768 // Delete it when the widget is close
769 m_pFullScreenToolBar = new CFrmFullScreenToolBar(this);
770 QScreen* pScreen = qApp->primaryScreen();
771 if(pScreen) {
772 QPoint pos(pScreen->geometry().left()
773 + (pScreen->geometry().width()
774 - m_pFullScreenToolBar->frameGeometry().width()) / 2,
775 pScreen->geometry().top());
776 qDebug(log) << "Primary screen geometry:" << pScreen->geometry()
777 << "availableGeometry:" << pScreen->availableGeometry()
778 << pos << mapToGlobal(pos);
779 m_pFullScreenToolBar->move(pos);
780 }
781 bool check = connect(m_pFullScreenToolBar, SIGNAL(sigExitFullScreen()),
782 this, SLOT(on_actionFull_screen_F_triggered()));
783 Q_ASSERT(check);
784 check = connect(m_pFullScreenToolBar, SIGNAL(sigExit()),
785 this, SLOT(on_actionExit_E_triggered()));
786 Q_ASSERT(check);
787 Q_ASSERT(check);
788 check = connect(this, SIGNAL(sigOperateMenuChanged(QAction*)),
789 m_pFullScreenToolBar,
790 SLOT(slotOperateMenuChanged(QAction*)));
791 Q_ASSERT(check);
792
793 m_pFullScreenToolBar->show();
794}
795
796void MainWindow::slotViewerFocusIn(QWidget *pView)
797{
798 COperate* c = qobject_cast<COperate*>(sender());
799 qDebug(log) << Q_FUNC_INFO << "Focus:" << c << pView;
800 if(c && m_pView) {
801 m_pView->SetCurrentView(c->GetViewer());
802 }
803}
804
805void MainWindow::slotOperateChanged(COperate *o)
806{
807 if(o && m_pView) {
808 m_pView->SetCurrentView(o->GetViewer());
809 }
810}
811
812void MainWindow::slotCurrentViewChanged(const QWidget* pView)
813{
814 qDebug(log) << Q_FUNC_INFO;
815 if(m_pView && pView)
816 EnableMenu(true);
817 else
818 EnableMenu(false);
819
820 foreach(auto o, m_Operates) {
821 if(o->GetViewer() == pView) {
822 SetSecureLevel(o);
823 foreach (auto a, ui->menuActivity->actions()) {
824 if(a->data().value<COperate*>() == o)
825 a->setChecked(true);
826 }
827 ui->actionStop_other->setText(
828 tr("Stop other except the current \"%1\"").arg(o->Name()));
829 }
830 }
831
832 QTimer::singleShot(0, this, SLOT(slotTimeOut()));
833}
834
835void MainWindow::EnableMenu(bool bEnable)
836{
837 qDebug(log) << Q_FUNC_INFO << bEnable;
838 ui->actionClone->setEnabled(bEnable);
839 ui->actionAdd_to_favorite->setEnabled(bEnable);
840 ui->actionStop->setEnabled(bEnable);
841 ui->actionStop_All->setEnabled(bEnable);
842 ui->actionStop_other->setEnabled(bEnable);
843 if(bEnable) {
844 if(m_Operates.size() > 1)
845 ui->actionStop_other->setEnabled(true);
846 else
847 ui->actionStop_other->setEnabled(false);
848 } else {
849 ui->actionStop_other->setText(tr("Stop other"));
850 }
851 ui->actionTabBar_B->setEnabled(bEnable);
852 ui->menuActivity->setEnabled(bEnable);
853 m_ptbMenuActivity->setEnabled(bEnable);
854 slotLoadOperateMenu();
855}
856
857void MainWindow::slotMenuActivity()
858{
859 QAction* pAction = qobject_cast<QAction*>(sender());
860 Q_ASSERT(pAction);
861 if(!pAction) return;
862 COperate* p = pAction->data().value<COperate*>();
863 if(p)
864 slotOperateChanged(p);
865}
866
867void MainWindow::slotLoadOperateMenu()
868{
869 qDebug(log) << Q_FUNC_INFO;
870
871 if(m_pActionOperateMenu) {
872 ui->menuOperate->removeAction(m_pActionOperateMenu);
873 m_pActionOperateMenu = nullptr;
874 }
875 ui->toolBar->removeAction(m_pActionTBOperate);
876
877 if(!m_pView)
878 return;
879 auto pWin = m_pView->GetCurrentView();
880 if(!pWin) {
881 qDebug(log) << "The current view is empty";
882 return;
883 }
884 foreach(auto op, m_Operates)
885 {
886 if(op->GetViewer() == pWin)
887 {
888 qDebug(log) << "Load plugin menu";
889 auto m = op->GetMenu(ui->menuTools);
890 if(!m) return;
891 // Menu tool bar
892 m_pActionOperateMenu = ui->menuOperate->insertMenu(ui->actionAdd_to_favorite, m);
893 // ToolBar
894 if(!m_pTBOperate)
895 m_pTBOperate = new QToolButton(ui->toolBar);
896 if(m_pTBOperate) {
897 m_pTBOperate->setFocusPolicy(Qt::NoFocus);
898 m_pTBOperate->setPopupMode(QToolButton::InstantPopup);
899 m_pTBOperate->setMenu(m);
900 m_pTBOperate->setIcon(m->icon());
901 m_pTBOperate->setText(m->title());
902 m_pTBOperate->setToolTip(m->toolTip());
903 m_pTBOperate->setStatusTip(m->statusTip());
904 m_pTBOperate->show();
905 m_pActionTBOperate = ui->toolBar->insertWidget(ui->actionAdd_to_favorite, m_pTBOperate);
906 }
907 emit sigOperateMenuChanged(m_pActionOperateMenu);
908 }
909 }
910}
911
919{
920 if(!m_pView)
921 return;
922 auto pWin = m_pView->GetCurrentView();
923 if(!pWin) {
924 qDebug(log) << "The current view is empty";
925 return;
926 }
927 foreach(auto p, m_Operates)
928 {
929 if(p->GetViewer() == pWin)
930 {
931 qDebug(log) << "Load plugin menu";
932 auto m = p->GetMenu(ui->menuTools);
933 if(!m) return;
934 // Note: The view is converted to global coordinates
935 m->exec(pos);
936 }
937 }
938}
939
940void MainWindow::on_actionExit_E_triggered()
941{
942 close();
943}
944
945void MainWindow::keyReleaseEvent(QKeyEvent *event)
946{
947 switch(event->key())
948 {
949 case Qt::Key_Escape:
950 if(isFullScreen())
951 on_actionFull_screen_F_triggered();
952 break;
953 }
954 QMainWindow::keyReleaseEvent(event);
955}
956
957void MainWindow::slotUpdateParameters(COperate *pOperate)
958{
959 m_Manager.SaveOperate(pOperate);
960}
961
962void MainWindow::on_actionClone_triggered()
963{
964 if(!m_pView) return;
965 QWidget* p = m_pView->GetCurrentView();
966 foreach(auto pOperate, m_Operates)
967 {
968 if(pOperate->GetViewer() == p)
969 {
970 QString szFile = pOperate->GetSettingsFile();
971 auto pOperate = m_Manager.LoadOperate(szFile);
972 if(!pOperate) return;
973 Start(pOperate, false, szFile);
974 return;
975 }
976 }
977}
978
979void MainWindow::slotOpenFile(const QString& szFile, bool bOpenSettings)
980{
981 if(szFile.isEmpty()) return;
982 COperate* p = m_Manager.LoadOperate(szFile);
983 if(nullptr == p)
984 {
985 slotStatusMessage(tr("Load file fail: ") + szFile, MessageLevel::Error);
986 return;
987 }
988
989 Start(p, bOpenSettings, szFile);
990}
991
992void MainWindow::on_actionOpenRRCFile_triggered()
993{
994 QString szFile = QFileDialog::getOpenFileName(
995 this,
996 tr("Open rabbit remote control file"),
997 RabbitCommon::CDir::Instance()->GetDirUserData(),
998 tr("Rabbit remote control Files (*.rrc);;All files(*.*)"));
999 if(szFile.isEmpty()) return;
1000
1001 COperate* p = m_Manager.LoadOperate(szFile);
1002 if(nullptr == p)
1003 {
1004 slotStatusMessage(tr("Load file fail: ") + szFile, MessageLevel::Error);
1005 return;
1006 }
1007
1008 Start(p, true);
1009}
1010
1011void MainWindow::slotStart()
1012{
1013 if(nullptr == m_pView)
1014 {
1015 Q_ASSERT(false);
1016 return;
1017 }
1018 QAction* pAction = qobject_cast<QAction*>(this->sender());
1019 Q_ASSERT(pAction);
1020 COperate* p = m_Manager.CreateOperate(pAction->data().toString());
1021 if(nullptr == p) return;
1022 Start(p, true);
1023}
1024
1035int MainWindow::Start(COperate *pOperate, bool set, QString szFile)
1036{
1037 qDebug(log) << "MainWindow::Start: set:" << set << "; File:" << szFile;
1038 bool bSave = false; //whether is save configure file
1039 Q_ASSERT(pOperate);
1040 bool check = connect(pOperate, SIGNAL(sigRunning()),
1041 this, SLOT(slotRunning()));
1042 Q_ASSERT(check);
1043 check = connect(pOperate, SIGNAL(sigStop()),
1044 this, SLOT(slotStop()));
1045 Q_ASSERT(check);
1046 check = connect(pOperate, SIGNAL(sigFinished()),
1047 this, SLOT(slotFinished()));
1048 Q_ASSERT(check);
1049 check = connect(pOperate, SIGNAL(sigError(const int, const QString &)),
1050 this, SLOT(slotError(const int, const QString&)));
1051 Q_ASSERT(check);
1052 check = connect(pOperate, SIGNAL(sigShowMessageBox(const QString&, const QString&,
1053 const QMessageBox::Icon&)),
1054 this, SLOT(slotShowMessageBox(const QString&, const QString&,
1055 const QMessageBox::Icon&)));
1056 Q_ASSERT(check);
1057 check = connect(pOperate, SIGNAL(sigInformation(const QString&)),
1058 this, SLOT(slotInformation(const QString&)));
1059 Q_ASSERT(check);
1060 check = connect(pOperate, SIGNAL(sigUpdateName(const QString&)),
1061 this, SLOT(slotUpdateName(const QString&)));
1062 Q_ASSERT(check);
1063 check = connect(pOperate, SIGNAL(sigUpdateParameters(COperate*)),
1064 this, SLOT(slotUpdateParameters(COperate*)));
1065 Q_ASSERT(check);
1066 check = connect(pOperate, &COperate::sigFullScreen,
1067 this, [this, pOperate](bool bFull) {
1068 if(m_pView && m_pView->GetCurrentView() == pOperate->GetViewer()) {
1069 if((bFull && !isFullScreen()) || (!bFull && isFullScreen()))
1070 on_actionFull_screen_F_triggered();
1071 }
1072 });
1073 Q_ASSERT(check);
1074 check = connect(pOperate, &COperate::sigSecurityLevel,
1075 this, [this, pOperate]() {
1076 if(m_pView && pOperate) {
1077 if(m_pView->GetCurrentView() == pOperate->GetViewer())
1078 slotCurrentViewChanged(pOperate->GetViewer());
1079 }
1080 });
1081 Q_ASSERT(check);
1082
1083 if(set)
1084 {
1085 int nRet = pOperate->OpenDialogSettings(this);
1086 switch(nRet)
1087 {
1088 case QDialog::Rejected:
1089 m_Manager.DeleteOperate(pOperate);
1090 return 0;
1091 case QDialog::Accepted:
1092 bSave = true;
1093 break;
1094 }
1095 }
1096
1097 if(szFile.isEmpty())
1098 szFile = pOperate->GetSettingsFile();
1099 else
1100 pOperate->SetSettingsFile(szFile);
1101
1102 int nRet = 0;
1103 if(bSave)
1104 nRet = m_Manager.SaveOperate(pOperate);
1105 if(0 == nRet) {
1106 m_pRecentMenu->addRecentFile(szFile, pOperate->Name(), pOperate->Icon());
1108 item.szOperateId = pOperate->Id();
1109 item.icon = pOperate->Icon();
1110 item.szName = pOperate->Name();
1111 item.szProtocol = pOperate->Protocol();
1112 item.szType = pOperate->GetTypeName();
1113 item.szDescription = pOperate->Description();
1114 item.SetFile(szFile);
1115 item.time = QDateTime::currentDateTime();
1116 m_pRecent->AddRecent(item);
1117 }
1118
1119 if(!pOperate->Name().isEmpty())
1120 slotInformation(tr("Starting: ") + pOperate->Name());
1121
1122 //* Show view. \see: slotRunning()
1123 if(m_Operates.contains(pOperate)) {
1124 if(m_pView)
1125 m_pView->SetCurrentView(pOperate->GetViewer());
1126 return 0;
1127 }
1128 if(m_pView)
1129 {
1130 m_pView->AddView(pOperate->GetViewer());
1131 m_pView->SetWidowsTitle(pOperate->GetViewer(), pOperate->Name(),
1132 pOperate->Icon(), pOperate->Description());
1133 //qDebug(log) << "View:" << p->GetViewer();
1134 check = connect(pOperate, SIGNAL(sigViewerFocusIn(QWidget*)),
1135 this, SLOT(slotViewerFocusIn(QWidget*)));
1136 Q_ASSERT(check);
1137 }
1138 m_Operates.insert(pOperate);
1139 StartTimer();
1140
1141 m_pFrmActive->slotLoad();
1142 m_pFrmActive->slotViewChanged(m_pView->GetCurrentView());
1143
1144 QVariant vOperate;
1145 vOperate.setValue(pOperate);
1146 QAction* m_pActionmenuActivity = ui->menuActivity->addAction(
1147 pOperate->Icon(), pOperate->Name(), this, SLOT(slotMenuActivity()));
1148 m_pActionmenuActivity->setData(vOperate);
1149 m_pActionmenuActivity->setCheckable(true);
1150 m_pMenuActivityGroup->addAction(m_pActionmenuActivity);
1151 m_pActionmenuActivity->setChecked(true);
1152 //*/
1153
1154 nRet = pOperate->Start();
1155 if(nRet)
1156 pOperate->Stop();
1157 return nRet;
1158}
1159
1161
1165{
1166 COperate* p = qobject_cast<COperate*>(sender());
1167 if(!p) return;
1168
1169 /* If you put it here, when running, the view is not displayed.
1170 So put it in the Start() display view.
1171 See: Start(COperate *p, bool set, QString szFile)
1172 */
1173 /*
1174 if(-1 == m_Operates.indexOf(p)) {
1175 m_Operates.push_back(p);
1176 if(m_pView)
1177 {
1178 m_pView->AddView(p->GetViewer());
1179 m_pView->SetWidowsTitle(p->GetViewer(), p->Name(), p->Icon(), p->Description());
1180 }
1181 } else {
1182 m_pView->SetCurrentView(p->GetViewer());
1183 }
1184 //*/
1185
1186 slotCurrentViewChanged(p->GetViewer());
1187
1188 auto m = p->GetMenu();
1189 if(m) {
1190 m->addSeparator();
1191 m->addAction(ui->actionClone);
1192 m->addAction(ui->actionStop_All);
1193 m->addAction(ui->actionStop_other);
1194 }
1195
1196 slotInformation(tr("Connected to ") + "\"" + p->Name() + "\"");
1197 qDebug(log) << Q_FUNC_INFO << p->Name();
1198}
1200
1201void MainWindow::slotCloseView(const QWidget* pView)
1202{
1203 qDebug(log) << "MainWindow::slotCloseView" << pView;
1204 if(!pView) return;
1205 foreach(auto p, m_Operates)
1206 {
1207 if(p->GetViewer() == pView)
1208 {
1209 //TODO: Whether to save the setting
1210 emit p->sigUpdateParameters(p);
1211 p->Stop();
1212 }
1213 }
1214}
1215
1216void MainWindow::on_actionStop_other_triggered()
1217{
1218 if(!m_pView) return;
1219 foreach(auto p, m_Operates)
1220 {
1221 if(p->GetViewer() != m_pView->GetCurrentView())
1222 {
1223 //TODO: Whether to save the setting
1224 emit p->sigUpdateParameters(p);
1225 p->Stop();
1226 }
1227 }
1228}
1229
1230void MainWindow::on_actionStop_All_triggered()
1231{
1232 foreach(auto p, m_Operates)
1233 {
1234 //TODO: Whether to save the setting
1235 emit p->sigUpdateParameters(p);
1236 p->Stop();
1237 }
1238}
1239
1240void MainWindow::on_actionStop_triggered()
1241{
1242 qDebug(log) << Q_FUNC_INFO;
1243 if(!m_pView) return;
1244
1245 QWidget* pView = m_pView->GetCurrentView();
1246 slotCloseView(pView);
1247}
1248
1249void MainWindow::slotStop()
1250{
1251 COperate* pOperate = qobject_cast<COperate*>(sender());
1252 if(!pOperate) return;
1253 qDebug(log) << Q_FUNC_INFO << pOperate->Name();
1254 //TODO: Whether to save the setting
1255 emit pOperate->sigUpdateParameters(pOperate);
1256 pOperate->Stop();
1257}
1258
1259void MainWindow::slotFinished()
1260{
1261 COperate* pOperate = qobject_cast<COperate*>(sender());
1262 if(!pOperate) return;
1263
1264 qDebug(log) << Q_FUNC_INFO << pOperate->Name();
1265 foreach(auto a, ui->menuActivity->actions()) {
1266 COperate* o = a->data().value<COperate*>();
1267 if(o == pOperate) {
1268 ui->menuActivity->removeAction(a);
1269 m_pMenuActivityGroup->removeAction(a);
1270 }
1271 }
1272 foreach(auto p, m_Operates)
1273 {
1274 if(p == pOperate)
1275 {
1276 m_pView->RemoveView(p->GetViewer());
1277 m_Operates.remove(p);
1278 m_Manager.DeleteOperate(p);
1279 m_pFrmActive->slotLoad();
1280 m_pFrmActive->slotViewChanged(m_pView->GetCurrentView());
1281 break;
1282 }
1283 }
1284 if(m_Operates.isEmpty())
1285 if(m_pActionOperateMenu) {
1286 ui->menuTools->removeAction(m_pActionOperateMenu);
1287 ui->toolBar->removeAction(m_pActionOperateMenu);
1288 m_pActionOperateMenu = nullptr;
1289 }
1290
1291 StartTimer();
1292}
1293
1294// 该函数将label控件变成一个圆形指示灯,需要指定颜色color以及直径size
1295// size 单位是像素
1296void SetIndicator(QLabel* label, QColor color, int size)
1297{
1298 QString min_width = QString("min-width: %1px;").arg(size); // 最小宽度:size
1299 QString min_height = QString("min-height: %1px;").arg(size); // 最小高度:size
1300 QString max_width = QString("max-width: %1px;").arg(size); // 最小宽度:size
1301 QString max_height = QString("max-height: %1px;").arg(size); // 最小高度:size
1302 // 再设置边界形状及边框
1303 QString border_radius = QString("border-radius: %1px;").arg(size / 2); // 边框是圆角,半径为size/2
1304 QString border = QString("border:1px solid ") + color.name() + ";"; // 边框为1px
1305 // 最后设置背景颜色
1306 QString background = "background-color: ";
1307 background += color.name() + ";";
1308 QString SheetStyle = min_width + min_height + max_width + max_height + border_radius + border + background;
1309 label->setStyleSheet(SheetStyle);
1310}
1311
1312void MainWindow::SetSecureLevel(COperate* o)
1313{
1314 if(!m_pSecureLevel) return;
1315 if(o) {
1316 QString szLevel = CSecurityLevel::GetUnicodeIcon(o->GetSecurityLevel());
1317 if(szLevel.isEmpty()) {
1318 m_pSecureLevel->hide();
1319 return;
1320 }
1321 m_pSecureLevel->setText(szLevel);
1322 m_pSecureLevel->setToolTip(CSecurityLevel::GetString(o->GetSecurityLevel()));
1323 m_pSecureLevel->show();
1324 } else
1325 m_pSecureLevel->hide();
1326}
1327
1328void MainWindow::slotSignalConnected()
1329{
1330 m_pSignalStatus->setToolTip(tr("ICE signal status: Connected"));
1331 m_pSignalStatus->setStatusTip(m_pSignalStatus->toolTip());
1332 m_pSignalStatus->setWhatsThis(m_pSignalStatus->toolTip());
1333 //m_pSignalStatus->setText(tr("Connected"));
1334 m_pSignalStatus->setIcon(QIcon::fromTheme("network-wired"));
1335}
1336
1337void MainWindow::slotSignalDisconnected()
1338{
1339 m_pSignalStatus->setToolTip(tr("ICE signal status: Disconnected"));
1340 m_pSignalStatus->setStatusTip(m_pSignalStatus->toolTip());
1341 m_pSignalStatus->setWhatsThis(m_pSignalStatus->toolTip());
1342 //m_pSignalStatus->setText(tr("Disconnected"));
1343 m_pSignalStatus->setIcon(QIcon::fromTheme("network-wireless"));
1344}
1345
1346void MainWindow::slotSignalError(const int nError, const QString &szInfo)
1347{
1348 slotSignalDisconnected();
1349 slotError(nError, szInfo);
1350}
1351
1352void MainWindow::slotSignalPushButtonClicked(bool checked)
1353{
1354#ifdef HAVE_ICE
1355 if(checked)
1356 CICE::Instance()->slotStart();
1357 else
1358 CICE::Instance()->slotStop();
1359#endif
1360}
1361
1362void MainWindow::slotError(const int nError, const QString &szInfo)
1363{
1364 Q_UNUSED(nError);
1365 slotStatusMessage(szInfo, MessageLevel::Error);
1366}
1367
1369 const QString &title, const QString &message,
1370 const QMessageBox::Icon &icon)
1371{
1372 slotInformation(message);
1373 if(!m_Parameter.GetMessageBoxDisplayInformation())
1374 return;
1375
1376 QMessageBox msg(icon, title, message, QMessageBox::Ok, this);
1377 QCheckBox* cb = new QCheckBox(
1378 tr("Use message box to display information"), this);
1379 cb->setChecked(true);
1380 msg.setCheckBox(cb);
1381 RC_SHOW_WINDOW(&msg);
1382 if(!cb->isChecked())
1383 {
1384 m_Parameter.SetMessageBoxDisplayInformation(false);
1385 m_Parameter.Save();
1386 }
1387}
1388
1389void MainWindow::slotInformation(const QString& szInfo)
1390{
1391 slotStatusMessage(szInfo, MessageLevel::Normal);
1392 //statusBar()->showMessage(szInfo);
1393}
1394
1395void MainWindow::slotStatusMessage(QString szMessage, MessageLevel level)
1396{
1397 QString szLevel;
1398 QPalette pe;
1399 switch ((MessageLevel)level) {
1400 case MessageLevel::Error:
1401 pe.setColor(QPalette::WindowText, Qt::red);
1402 szLevel = "X";
1403 break;
1404 case MessageLevel::Warning:
1405 pe.setColor(QPalette::WindowText, Qt::yellow);
1406 szLevel = "!";
1407 break;
1408 default:
1409 break;
1410 }
1411 m_StatusBarMessage.setPalette(pe);
1412 m_StatusBarMessage.setToolTip(szMessage);
1413
1414 //QFontMetrics metrics(m_StatusBarMessage.font());
1415 //szMessage = metrics.elidedText(szMessage, Qt::ElideRight, m_StatusBarMessage.width());
1416
1417 m_StatusBarMessage.setText(szLevel);//*/
1418 statusBar()->showMessage(szMessage);
1419}
1420
1421void MainWindow::slotUpdateName()
1422{
1423 foreach (auto p, m_Operates)
1424 {
1425 m_pView->SetWidowsTitle(p->GetViewer(),
1426 p->Name(),
1427 p->Icon(),
1428 p->Description());
1429 }
1430}
1431
1432void MainWindow::slotUpdateName(const QString& szName)
1433{
1434 COperate* p = qobject_cast<COperate*>(sender());
1435 if(!p) return;
1436 // Update view
1437 m_pView->SetWidowsTitle(p->GetViewer(), szName,
1438 p->Icon(), p->Description());
1439
1440 // Update recent menu
1441 if(m_pRecentMenu)
1442 m_pRecentMenu->updateRecentFile(p->GetSettingsFile(), szName, p->Icon());
1443
1445 item.SetFile(p->GetSettingsFile());
1446 item.szName = p->Name();
1447 item.szDescription = p->Description();
1448 // Update recent list view dock widget
1449 m_pRecent->UpdateRecent(item);
1450
1451 // Update activity menu
1452 foreach(auto a, ui->menuActivity->actions()) {
1453 if(a->data().value<COperate*>() == p) {
1454 a->setText(szName);
1455 a->setIcon(p->Icon());
1456 break;
1457 }
1458 }
1459
1460 // Update favorite
1461 m_pFavoriteView->slotUpdateFavorite(
1462 p->GetSettingsFile(), szName, p->Description(), p->Icon());
1463
1464 //Update activity list view dock widget
1465 m_pFrmActive->slotLoad();
1466}
1467
1468QAction* MainWindow::GetStartAction(QMenu* pMenu, CPlugin *pPlug)
1469{
1470 QString szTitle;
1471 if(!pPlug->Protocol().isEmpty())
1472 szTitle = pPlug->Protocol() + ": ";
1473 szTitle += pPlug->DisplayName();
1474 QAction* p = pMenu->addAction(szTitle);
1475 p->setToolTip(pPlug->Description());
1476 p->setStatusTip(pPlug->Description());
1477 p->setData(pPlug->Id());
1478 p->setIcon(pPlug->Icon());
1479 return p;
1480}
1481
1482void MainWindow::slotStartByType()
1483{
1484 qDebug(log) << Q_FUNC_INFO;
1485 auto m = ui->menuStart->actions();
1486 foreach(auto a, m) {
1487 a->deleteLater();
1488 }
1489 foreach (auto a, m_MenuStartByType) {
1490 a->deleteLater();
1491 }
1492 ui->menuStart->clear();
1493 m_MenuStartByType.clear();
1494 m_Manager.EnumPlugins(this);
1495}
1496
1497int MainWindow::onProcess(const QString &id, CPlugin *pPlugin)
1498{
1499 Q_UNUSED(id);
1500 QMenu* m = ui->menuStart;
1501 if(m_Parameter.GetStartByType()) {
1502 auto it = m_MenuStartByType.find(pPlugin->Type());
1503 if(it == m_MenuStartByType.end()) {
1504 m = new QMenu(pPlugin->TypeName(pPlugin->Type()), ui->menuStart);
1505 m_MenuStartByType[pPlugin->Type()] = m;
1506 ui->menuStart->addMenu(m);
1507 } else
1508 m = *it;
1509 }
1510 // Start menu and toolbar
1511 QAction* p = GetStartAction(m, pPlugin);
1512 bool check = false;
1513 check = connect(p, SIGNAL(triggered()), this, SLOT(slotStart()));
1514 Q_ASSERT(check);
1515 return 0;
1516}
1517
1518void MainWindow::closeEvent(QCloseEvent *event)
1519{
1520 qDebug(log) << "MainWindow::closeEvent()";
1521
1522 if(m_Parameter.GetSaveMainWindowStatus())
1523 if(isFullScreen())
1524 on_actionFull_screen_F_triggered();
1525
1526 SaveOperateLasterClose();
1527
1528 foreach (auto it, m_Operates)
1529 {
1530 //TODO: Whether to save the setting
1531 emit it->sigUpdateParameters(it);
1532 it->Stop();
1533 }
1534
1535 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
1536 QSettings::IniFormat);
1537 if(m_Parameter.GetSaveMainWindowStatus())
1538 {
1539 set.setValue("MainWindow/Status/Geometry", saveGeometry());
1540 set.setValue("MainWindow/Status/State", saveState());
1541
1542 m_Parameter.SetTabBar(ui->actionTabBar_B->isChecked());
1543 m_Parameter.SetMenuBar(menuBar()->isVisible());
1544 m_Parameter.SetStatusBar(statusBar()->isVisible());
1545 } else {
1546 set.remove("MainWindow/Status/Geometry");
1547 set.remove("MainWindow/Status/State");
1548 }
1549
1550 m_Manager.SaveSettings();
1551 m_Parameter.Save();
1552
1553 QMainWindow::closeEvent(event);
1554
1555 //TODO: Wait for the background thread to exit
1556 QThread::sleep(1);
1557}
1558
1559int MainWindow::LoadOperateLasterClose()
1560{
1561 if(!m_Parameter.GetOpenLasterClose())
1562 return 0;
1563
1564 QFile f(RabbitCommon::CDir::Instance()->GetDirUserConfig()
1565 + QDir::separator() + "LasterClose.dat");
1566 if(f.open(QFile::ReadOnly))
1567 {
1568 QDataStream d(&f);
1569 while(1){
1570 QString szFile;
1571 d >> szFile;
1572 if(szFile.isEmpty())
1573 break;
1574 slotOpenFile(szFile);
1575 }
1576 f.close();
1577 }
1578 return 0;
1579}
1580
1581int MainWindow::SaveOperateLasterClose()
1582{
1583 QFile f(RabbitCommon::CDir::Instance()->GetDirUserConfig()
1584 + QDir::separator() + "LasterClose.dat");
1585 bool bRet = f.open(QFile::WriteOnly);
1586 if(bRet && m_Parameter.GetOpenLasterClose())
1587 {
1588 QDataStream d(&f);
1589 foreach(auto it, m_Operates)
1590 {
1591 d << it->GetSettingsFile();
1592 }
1593 }
1594 f.close();
1595 return 0;
1596}
1597
1598void MainWindow::on_actionTabBar_B_toggled(bool bShow)
1599{
1600 if(m_pView)
1601 {
1602 m_pView->SetVisibleTab(bShow);
1603 m_Parameter.SetTabBar(bShow);
1604 } else {
1605 if(m_pDockActive)
1606 m_pDockActive->setVisible(bShow);
1607 }
1608}
1609
1610void MainWindow::on_actionMain_menu_bar_M_toggled(bool checked)
1611{
1612 qDebug(log) << Q_FUNC_INFO << checked;
1613 if(ui->toolBar->isHidden() && !checked)
1614 {
1615 if( QMessageBox::StandardButton::Yes
1616 == QMessageBox::information(this, tr("Hide menu bar"),
1617 tr("The menu bar will be hidden, the tool bar must be showed."),
1618 QMessageBox::StandardButton::Yes
1619 | QMessageBox::StandardButton::No))
1620 {
1621 ui->actionToolBar_T->setChecked(true);
1622 if(m_pToolBarMenuAction)
1623 m_pToolBarMenuAction->setVisible(true);
1624 } else {
1625 ui->actionMain_menu_bar_M->setChecked(true);
1626#if !defined(Q_OS_ANDROID)
1627 if(m_pToolBarMenuAction)
1628 m_pToolBarMenuAction->setVisible(false);
1629#endif
1630 return;
1631 }
1632 }
1633
1634 menuBar()->setVisible(checked);
1635 m_Parameter.SetMenuBar(checked);
1636#if !defined(Q_OS_ANDROID)
1637 if(m_pToolBarMenuAction)
1638 m_pToolBarMenuAction->setVisible(!checked);
1639#endif
1640}
1641
1642void MainWindow::on_actionToolBar_T_toggled(bool checked)
1643{
1644 qDebug(log) << Q_FUNC_INFO << checked;
1645 if(menuBar()->isHidden() && !checked)
1646 {
1647 if( QMessageBox::StandardButton::Yes
1648 == QMessageBox::information(this, tr("Hide tool bar"),
1649 tr("The tool bar will be hidden, the menu bar must be showed."),
1650 QMessageBox::StandardButton::Yes
1651 | QMessageBox::StandardButton::No))
1652 {
1653 ui->actionMain_menu_bar_M->setChecked(true);
1654 } else {
1655 ui->actionToolBar_T->setChecked(true);
1656 return;
1657 }
1658 }
1659 ui->toolBar->setVisible(checked);
1660}
1661
1662void MainWindow::on_actionStatus_bar_S_toggled(bool checked)
1663{
1664 statusBar()->setVisible(checked);
1665 m_Parameter.SetStatusBar(checked);
1666}
1667
1668void MainWindow::on_actionKeyboard_triggered()
1669{
1670 auto inputMethod = QGuiApplication::inputMethod();
1671 if(inputMethod) {
1672 // QObject *focusObject = QGuiApplication::focusObject();
1673 // if(m_pView && m_pView->GetCurrentView())
1674 // focusObject = m_pView->GetCurrentView();
1675 // if (focusObject) {
1676 // // 可选:强制焦点对象发送输入法请求
1677 // QInputMethodEvent event;
1678 // QCoreApplication::sendEvent(focusObject, &event);
1679 // }
1680 inputMethod->show();
1681 }
1682}
1683
1684// [Get the widget that settings plugin parameters]
1685void MainWindow::on_actionSettings_triggered()
1686{
1687 CParameterDlgSettings set(&m_Parameter, this);
1688 auto viewers = m_Manager.GetSettingsWidgets(&set);
1689 set.AddViewers(viewers);
1690 if(CParameterDlgSettings::Accepted == RC_SHOW_WINDOW(&set))
1691 {
1692 m_Manager.SaveSettings();
1693 m_Parameter.Save();
1694 }
1695 foreach(auto v, viewers) {
1696 v->deleteLater();
1697 }
1698}
1699// [Get the widget that settings plugin parameters]
1700
1701void MainWindow::slotShortCut()
1702{
1703 if(m_Parameter.GetReceiveShortCut())
1704 {
1705 setFocusPolicy(Qt::WheelFocus);
1706 ui->actionFull_screen_F->setShortcuts(QKeySequence::FullScreen);
1707 } else {
1708 setFocusPolicy(Qt::NoFocus);
1709 ui->actionFull_screen_F->setShortcut(QKeySequence());
1710 }
1711}
1712
1713void MainWindow::on_actionOpenListRecent_triggered()
1714{
1715 CFrmRecent* p = new CFrmRecent(this, &m_Manager, m_Parameter, false);
1716 if(!p) return;
1717 bool check = connect(p, SIGNAL(sigStart(const QString&, bool)),
1718 this, SLOT(slotOpenFile(const QString&, bool)));
1719 Q_ASSERT(check);
1720 check = connect(p, SIGNAL(sigAddToFavorite(QString,QString,QString,QIcon)),
1721 m_pFavoriteView, SLOT(slotAddToFavorite(QString,QString,QString,QIcon)));
1722 Q_ASSERT(check);
1723
1724 int nRet = p->Initial();
1725 if(nRet) return;
1726
1727 QDialog d;
1728 d.resize(540, 400);
1729 d.setWindowIcon(windowIcon());
1730 d.setWindowTitle(p->windowTitle());
1731 QGridLayout* pLayout = new QGridLayout(&d);
1732 if(pLayout){
1733 pLayout->addWidget(p);
1734 check = connect(p, SIGNAL(destroyed()), &d, SLOT(reject()));
1735 d.setLayout(pLayout);
1736 }
1737 RC_SHOW_WINDOW(&d);
1738}
1739
1740void MainWindow::on_actionAdd_to_favorite_triggered()
1741{
1742 if(!m_pView || !m_pFavoriteView) return;
1743 QWidget* p = m_pView->GetCurrentView();
1744 foreach(auto c, m_Operates)
1745 {
1746 if(c->GetViewer() == p)
1747 {
1748 m_pFavoriteView->slotAddToFavorite(
1749 c->GetSettingsFile(), c->Name(), c->Description(), c->Icon());
1750 }
1751 }
1752}
1753
1754void MainWindow::dragEnterEvent(QDragEnterEvent *event)
1755{
1756 qDebug(log) << "dragEnterEvent";
1757
1758 if(event->mimeData()->hasUrls())
1759 {
1760 //qDebug(log) << event->mimeData()->urls();
1761 event->acceptProposedAction();
1762 }
1763}
1764
1765void MainWindow::dragMoveEvent(QDragMoveEvent *event)
1766{
1767 //qDebug(log) << "dragMoveEvent";
1768}
1769
1770void MainWindow::dropEvent(QDropEvent *event)
1771{
1772 qDebug(log) << "dropEvent";
1773 bool bRet = false;
1774 if(!event->mimeData()->hasUrls())
1775 return;
1776 auto urls = event->mimeData()->urls();
1777 foreach(auto url, urls)
1778 {
1779 if(url.isLocalFile())
1780 slotOpenFile(url.toLocalFile());
1781 bRet = true;
1782 }
1783 if(bRet)
1784 event->accept();
1785 else
1786 event->ignore();
1787}
1788
1789void MainWindow::slotSystemTrayIconActivated(QSystemTrayIcon::ActivationReason reason)
1790{
1791 //qDebug(log) << "MainWindow::slotSystemTrayIconActivated";
1792
1793 Q_UNUSED(reason)
1794#if defined(Q_OS_ANDROID)
1795 showMaximized();
1796#else
1797 switch(reason)
1798 {
1799 case QSystemTrayIcon::Trigger:
1800 {
1801 showNormal();
1802 activateWindow();
1803 break;
1804 }
1805 default:
1806 break;
1807 }
1808#endif
1809}
1810
1811void MainWindow::slotSystemTrayIconTypeChanged()
1812{
1813 //qDebug(log) << "MainWindow::slotSystemTrayIconTypeChanged:" << m_Parameter.GetEnableSystemTrayIcon();
1814 if(!QSystemTrayIcon::isSystemTrayAvailable())
1815 {
1816 qWarning(log) << "System tray is not available";
1817 return;
1818 }
1819
1820 if(!m_Parameter.GetEnableSystemTrayIcon())
1821 {
1822 qDebug(log) << "Disable system tray icon";
1823 return;
1824 }
1825
1826 if(m_TrayIcon)
1827 m_TrayIcon.reset();
1828
1829 m_TrayIcon = QSharedPointer<QSystemTrayIcon>(new QSystemTrayIcon(this));
1830 if(QSystemTrayIcon::isSystemTrayAvailable())
1831 {
1832 bool check = connect(
1833 m_TrayIcon.data(),
1834 SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
1835 this,
1836 SLOT(slotSystemTrayIconActivated(QSystemTrayIcon::ActivationReason)));
1837 Q_ASSERT(check);
1838 m_TrayIcon->setIcon(this->windowIcon());
1839 m_TrayIcon->setToolTip(windowTitle());
1840 m_TrayIcon->show();
1841 } else
1842 qWarning(log) << "System tray is not available";
1843
1844 switch (m_Parameter.GetSystemTrayIconMenuType())
1845 {
1846 case CParameterApp::SystemTrayIconMenuType::MenuBar:
1847 {
1848 QMenu* pMenu = new QMenu(this);
1849 pMenu->addMenu(ui->menuOperate);
1850 pMenu->addMenu(ui->menuView);
1851 pMenu->addMenu(ui->menuTools);
1852 m_TrayIcon->setContextMenu(pMenu);
1853 break;
1854 }
1855 case CParameterApp::SystemTrayIconMenuType::Operate:
1856 m_TrayIcon->setContextMenu(ui->menuOperate);
1857 break;
1858 case CParameterApp::SystemTrayIconMenuType::RecentOpen:
1859 m_TrayIcon->setContextMenu(m_pRecentMenu);
1860 break;
1861 case CParameterApp::SystemTrayIconMenuType::View:
1862 m_TrayIcon->setContextMenu(ui->menuView);
1863 break;
1864 case CParameterApp::SystemTrayIconMenuType::Tools:
1865 m_TrayIcon->setContextMenu(ui->menuTools);
1866 break;
1867 case CParameterApp::SystemTrayIconMenuType::No:
1868 m_TrayIcon->setContextMenu(nullptr);
1869 break;
1870 }
1871}
1872
1873void MainWindow::slotEnableSystemTrayIcon()
1874{
1875 //qDebug(log) << "MainWindow::slotEnableSystemTryIcon()";
1876 if(m_TrayIcon)
1877 {
1878 if(!m_Parameter.GetEnableSystemTrayIcon())
1879 m_TrayIcon.reset();
1880 } else
1881 slotSystemTrayIconTypeChanged();
1882}
1883
1884void MainWindow::SetStatsVisible(bool visible)
1885{
1886 if(m_SendRate.isVisible() == visible)
1887 return;
1888 m_SendRate.setVisible(visible);
1889 m_ReceivesRate.setVisible(visible);
1890 m_TotalSends.setVisible(visible);
1891 m_TotalReceives.setVisible(visible);
1892}
1893
1894void MainWindow::StartTimer()
1895{
1896 bool bStart = false;
1897 int nMinInterval = 1;
1898 foreach(auto o, m_Operates) {
1899 if(o && o->GetStats()) {
1900 nMinInterval = qMin(nMinInterval, o->GetStats()->GetInterval());
1901 bStart = true;
1902 }
1903 }
1904 if(bStart) {
1905 m_Timer.start(nMinInterval * 1000);
1906 //qDebug(log) << "Time interval:" << nMinInterval;
1907 } else {
1908 m_Timer.stop();
1909 SetStatsVisible(false);
1910 }
1911}
1912
1913void MainWindow::slotTimeOut()
1914{
1915 //qDebug(log) << Q_FUNC_INFO;
1916 auto pWin = m_pView->GetCurrentView();
1917 if(!pWin) {
1918 qDebug(log) << "The current view is empty";
1919 return;
1920 }
1921 foreach(auto p, m_Operates)
1922 {
1923 if(p->GetViewer() == pWin)
1924 {
1925 auto pStats = p->GetStats();
1926 if(!pStats) {
1927 SetStatsVisible(false);
1928 break;
1929 }
1930 SetStatsVisible(true);
1931 pStats->slotCalculating();
1932 m_TotalSends.setText("⇈ " + pStats->TotalSends());
1933 m_TotalReceives.setText("⇊ " + pStats->TotalReceives());
1934 m_SendRate.setText("↑ " + pStats->SendRate());
1935 m_ReceivesRate.setText("↓ " + pStats->ReceiveRate());
1936 break;
1937 }
1938 }
1939}
1940
1941void MainWindow::on_actionUser_manual_triggered()
1942{
1943 QString szUrl = "https://github.com/KangLin/RabbitRemoteControl/wiki/UserManual";
1944 if(RabbitCommon::CTools::GetLanguage() == "zh_CN"
1945 || RabbitCommon::CTools::GetLanguage() == "zh_TW")
1946 szUrl += "_zh_CN";
1947}
1948
1949void MainWindow::on_actionLayoutDefault_triggered()
1950{
1951 qDebug(log) << Q_FUNC_INFO;
1952 if(!m_pDockActive->toggleViewAction()->isChecked())
1953 m_pDockActive->toggleViewAction()->trigger();
1954 if(!m_pDockFavorite->toggleViewAction()->isChecked())
1955 m_pDockFavorite->toggleViewAction()->trigger();
1956 if(!m_pDockRecent->toggleViewAction()->isChecked())
1957 m_pDockRecent->toggleViewAction()->trigger();
1958 m_Parameter.SetTabPosition(QTabWidget::North);
1959 if(!ui->actionTabBar_B->isChecked())
1960 ui->actionTabBar_B->trigger();
1961 if(!ui->actionMain_menu_bar_M->isChecked()) {
1962 ui->actionMain_menu_bar_M->trigger();
1963#if !defined(Q_OS_ANDROID)
1964 m_pToolBarMenuAction->setVisible(false);
1965#endif
1966 }
1967 if(!ui->actionToolBar_T->isChecked())
1968 ui->actionToolBar_T->trigger();
1969 addToolBar(Qt::TopToolBarArea, ui->toolBar);
1970 if(!ui->actionStatus_bar_S->isChecked())
1971 ui->actionStatus_bar_S->trigger();
1972}
1973
1974void MainWindow::on_actionLayoutSimple_triggered()
1975{
1976 qDebug(log) << Q_FUNC_INFO;
1977 if(m_pDockActive->toggleViewAction()->isChecked())
1978 m_pDockActive->toggleViewAction()->trigger();
1979 if(m_pDockFavorite->toggleViewAction()->isChecked())
1980 m_pDockFavorite->toggleViewAction()->trigger();
1981 if(m_pDockRecent->toggleViewAction()->isChecked())
1982 m_pDockRecent->toggleViewAction()->trigger();
1983 m_Parameter.SetTabPosition(QTabWidget::East);
1984 if(!ui->actionTabBar_B->isChecked())
1985 ui->actionTabBar_B->trigger();
1986 if(!ui->actionMain_menu_bar_M->isChecked()) {
1987 ui->actionMain_menu_bar_M->trigger();
1988#if !defined(Q_OS_ANDROID)
1989 m_pToolBarMenuAction->setVisible(false);
1990#endif
1991 }
1992 if(!ui->actionToolBar_T->isChecked())
1993 ui->actionToolBar_T->trigger();
1994 addToolBar(Qt::LeftToolBarArea, ui->toolBar);
1995 if(!ui->actionStatus_bar_S->isChecked())
1996 ui->actionStatus_bar_S->trigger();
1997}
1998
1999void MainWindow::on_actionLayoutMinimalism_triggered()
2000{
2001 qDebug(log) << Q_FUNC_INFO;
2002 if(m_pDockActive->toggleViewAction()->isChecked())
2003 m_pDockActive->toggleViewAction()->trigger();
2004 if(m_pDockFavorite->toggleViewAction()->isChecked())
2005 m_pDockFavorite->toggleViewAction()->trigger();
2006 if(m_pDockRecent->toggleViewAction()->isChecked())
2007 m_pDockRecent->toggleViewAction()->trigger();
2008 m_Parameter.SetTabPosition(QTabWidget::East);
2009 if(ui->actionTabBar_B->isChecked())
2010 ui->actionTabBar_B->trigger();
2011#if !defined(Q_OS_MACOS)
2012 if(ui->actionMain_menu_bar_M->isChecked()) {
2013 ui->actionMain_menu_bar_M->trigger();
2014 m_pToolBarMenuAction->setVisible(true);
2015 }
2016#endif
2017 if(!ui->actionToolBar_T->isChecked())
2018 ui->actionToolBar_T->trigger();
2019#if defined(Q_OS_LINUX)
2020 addToolBar(Qt::RightToolBarArea, ui->toolBar);
2021#else
2022 addToolBar(Qt::LeftToolBarArea, ui->toolBar);
2023#endif
2024 if(ui->actionStatus_bar_S->isChecked())
2025 ui->actionStatus_bar_S->trigger();
2026}
The CFavoriteView class.
virtual void sigShowMessageBox(const QString &title, const QString &message, const QMessageBox::Icon &icon)
Use message box display information.
List the connect of be existed.
Definition FrmRecent.h:23
virtual void sigShowMessageBox(const QString &title, const QString &message, const QMessageBox::Icon &icon)
Use message box display information.
static CICE * Instance()
Single instance.
Definition Ice.cpp:55
virtual QList< QWidget * > GetSettingsWidgets(QWidget *parent)
Get parameter settings widget.
Definition Manager.cpp:565
virtual int EnumPlugins(Handle *handle)
Enum plugins.
Definition Manager.cpp:636
virtual COperate * CreateOperate(const QString &id)
New COperate pointer, the owner is caller.
Definition Manager.cpp:364
virtual COperate * LoadOperate(const QString &szFile)
New COperate pointer from file, the owner is caller.
Definition Manager.cpp:425
virtual int DeleteOperate(COperate *p)
Delete COperate.
Definition Manager.cpp:392
virtual int SaveOperate(COperate *pOperate)
Accept Operate parameters to file.
Definition Manager.cpp:476
int Initial(QString szFile=QString())
Initial.
Definition Manager.cpp:82
virtual int SaveSettings(const QString szFile=QString())
Save Client parameters to file.
Definition Manager.cpp:544
CParameterGlobal * GetGlobalParameters()
Get Global Parameters.
Definition Manager.cpp:558
void sigNewOperate(COperate *pOperate, bool bOpenSettingsDialog)
This signal is triggered when a new operate is created in the plugin.
Operate interface.
Definition Operate.h:51
virtual int OpenDialogSettings(QWidget *parent=nullptr)
Open settings dialog.
Definition Operate.cpp:97
virtual CSecurityLevel::Levels GetSecurityLevel() const
Get Security Level.
Definition Operate.cpp:129
virtual CStats * GetStats()
Get statistics.
Definition Operate.cpp:124
virtual int Start()=0
Start.
void sigFullScreen(bool bFullScreen)
Full screen.
virtual QWidget * GetViewer()=0
Get Viewer.
virtual const QString Name()
Name.
Definition Operate.cpp:46
virtual int Stop()=0
Stop.
virtual const QString Description()
Description.
Definition Operate.cpp:51
void sigUpdateParameters(COperate *pOperate)
Update parameters, notify application to save or show parameters.
void sigSecurityLevel()
Triggered when the security level changes.
virtual QMenu * GetMenu(QWidget *parent=nullptr)
Get menu.
Definition Operate.cpp:117
Global parameters.
virtual int Save(QString szFile=QString(), bool bForce=true)
Save to file.
Definition Parameter.cpp:47
Plugin interface.
Definition Plugin.h:15
virtual const QString DisplayName() const
The plugin display name.
Definition Plugin.cpp:76
virtual const QString Protocol() const =0
Plugin Protocol.
virtual const QString Id() const
ID. Default: Type() + ":" + Protocol() + ":" + Name()
Definition Plugin.cpp:71
virtual const QString Description() const =0
Plugin description.
int GetInterval()
Get interval.
Definition Stats.cpp:84
The split view class.
The CViewTable class.
Definition ViewTable.h:16
The CView class.
Definition View.h:25
virtual int AddView(QWidget *pView)=0
virtual QWidget * GetCurrentView()=0
virtual int RemoveView(QWidget *pView)=0
The MainWindow class.
Definition mainwindow.h:36
Q_INVOKABLE int Start(COperate *pOperate, bool set, QString szFile=QString())
Start.
virtual int onProcess(const QString &id, CPlugin *pPlugin) override
Process plugins.
void slotInformation(const QString &szInfo)
Show information.
virtual void slotShowMessageBox(const QString &title, const QString &message, const QMessageBox::Icon &icon)
Use message box display information.
void slotRunning()
[MainWindow slotRunning]
void slotCloseView(const QWidget *pView)
[MainWindow slotRunning]
void slotCustomContextMenuRequested(const QPoint &pos)
MainWindow::slotCustomContextMenuRequested.
int Initial()
For time-consuming operations.