Rabbit Remote Control 0.1.0-bate10
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 if(c->GetViewer()) {
624 m_pView->AddView(c->GetViewer());
625 m_pView->SetWidowsTitle(
626 c->GetViewer(), c->Name(), c->Icon(), c->Description());
627 } else {
628 QString szErr;
629 szErr += c->metaObject()->className();
630 szErr += "::GetViewer() ";
631 szErr += "is nullptr.";
632 qWarning(log) << szErr;
633 }
634 }
635 m_pView->SetVisibleTab(m_Parameter.GetTabBar());
636}
637
638void MainWindow::on_actionViewTab_triggered()
639{
640 qDebug(log) << Q_FUNC_INFO;
641 if(!ui->actionViewTab->isChecked()) return;
642 m_Parameter.SetViewType(CParameterApp::ViewType::Tab);
643 SetView(new CViewTable(&m_Parameter, this));
644}
645
646void MainWindow::on_actionViewSplit_triggered()
647{
648 qDebug(log) << Q_FUNC_INFO;
649 if(!ui->actionViewSplit->isChecked()) return;
650 m_Parameter.SetViewType(CParameterApp::ViewType::Splitter);
651 SetView(new CViewSplitter(&m_Parameter, this));
652}
653
654void MainWindow::on_actionAbout_triggered()
655{
656#ifdef HAVE_ABOUT
657 CDlgAbout *about = new CDlgAbout(this);
658 QIcon icon = QIcon::fromTheme("app");
659 if(!icon.isNull()) {
660 auto sizeList = icon.availableSizes();
661 if(!sizeList.isEmpty()) {
662 QPixmap p = icon.pixmap(*sizeList.begin());
663 about->m_AppIcon = p.toImage();
664 }
665 }
666 about->m_szBuildTime = QString("%1/%2").arg(__DATE__, __TIME__);
667 about->m_szCopyrightStartTime = "2020";
668 about->m_szVersionRevision = RabbitRemoteControl_REVISION;
669 about->m_szDetails = m_Manager.Details();
670 RC_SHOW_WINDOW(about);
671#endif
672}
673
674void MainWindow::on_actionUpdate_triggered()
675{
676 if(!qEnvironmentVariable("SNAP").isEmpty()) {
677 QDesktopServices::openUrl(QUrl("https://snapcraft.io/rabbitremotecontrol"));
678 } else if(!qEnvironmentVariable("FLATPAK_ID").isEmpty()) {
679 QDesktopServices::openUrl(QUrl("https://flathub.org/apps/io.github.KangLin.RabbitRemoteControl"));
680 } else {
681#ifdef HAVE_UPDATE
682 CFrmUpdater* m_pfrmUpdater = new CFrmUpdater();
683 QIcon icon = QIcon::fromTheme("app");
684 if(!icon.isNull()) {
685 auto sizeList = icon.availableSizes();
686 if(!sizeList.isEmpty()) {
687 QPixmap p = icon.pixmap(*sizeList.begin());
688 m_pfrmUpdater->SetTitle(p.toImage());
689 }
690 }
691 m_pfrmUpdater->SetInstallAutoStartup();
692 RC_SHOW_WINDOW(m_pfrmUpdater);
693#endif
694 }
695}
696
697void MainWindow::on_actionFull_screen_F_triggered()
698{
699 if(m_pView)
700 {
701 m_pView->SetFullScreen(!isFullScreen());
702 }
703
704 if(isFullScreen())
705 {
706 qDebug(log) << "Exit full screen";
707 ui->actionFull_screen_F->setIcon(QIcon::fromTheme("view-fullscreen"));
708 ui->actionFull_screen_F->setText(tr("Full screen"));
709 ui->actionFull_screen_F->setToolTip(tr("Full screen"));
710 ui->actionFull_screen_F->setStatusTip(tr("Full screen"));
711 ui->actionFull_screen_F->setWhatsThis(tr("Full screen"));
712
713 ui->toolBar->setVisible(m_FullState.toolBar);
714 ui->statusbar->setVisible(m_FullState.statusbar);
715 ui->menubar->setVisible(m_FullState.menubar);
716
717 m_pDockActive->setVisible(m_FullState.dockListActive);
718 m_pDockRecent->setVisible(m_FullState.dockListRecent);
719 m_pDockFavorite->setVisible(m_FullState.dockFavorite);
720 // TODO: This is hade code. it is in RabbitCommon
721 QDockWidget* pDockDebugLog = findChild<QDockWidget*>("dockDebugLog");
722 if(pDockDebugLog)
723 {
724 pDockDebugLog->setVisible(m_FullState.dockDebugLog);
725 }
726
727 if(m_pFullScreenToolBar)
728 {
729 // Delete it when the widget is close
730 m_pFullScreenToolBar->close();
731 m_pFullScreenToolBar = nullptr;
732 }
733
734 emit sigShowNormal();
735 this->showNormal();
736 this->activateWindow();
737
738 emit sigFullScreen(false);
739 return;
740 }
741
742 qDebug(log) << "Entry full screen";
743
744 //setWindowFlags(Qt::FramelessWindowHint | windowFlags());
745 this->showFullScreen();
746 emit sigFullScreen(true);
747
748 ui->actionFull_screen_F->setIcon(QIcon::fromTheme("view-restore"));
749 ui->actionFull_screen_F->setText(tr("Exit full screen"));
750 ui->actionFull_screen_F->setToolTip(tr("Exit full screen"));
751 ui->actionFull_screen_F->setStatusTip(tr("Exit full screen"));
752 ui->actionFull_screen_F->setWhatsThis(tr("Exit full screen"));
753
754 m_FullState.toolBar = ui->toolBar->isVisible();
755 ui->toolBar->setVisible(false);
756 m_FullState.statusbar = ui->statusbar->isVisible();
757 ui->statusbar->setVisible(false);
758 m_FullState.menubar = ui->menubar->isVisible();
759 ui->menubar->setVisible(false);
760
761 m_FullState.dockListActive = m_pDockActive->isVisible();
762 m_pDockActive->setVisible(false);
763 m_FullState.dockListRecent = m_pDockRecent->isVisible();
764 m_pDockRecent->setVisible(false);
765 m_FullState.dockFavorite = m_pDockFavorite->isVisible();
766 m_pDockFavorite->setVisible(false);
767 // This is hade code. it is in RabbitCommon
768 QDockWidget* pDockDebugLog = findChild<QDockWidget*>("dockDebugLog");
769 if(pDockDebugLog)
770 {
771 m_FullState.dockDebugLog = pDockDebugLog->isVisible();
772 pDockDebugLog->setVisible(false);
773 }
774
775 if(m_pFullScreenToolBar) m_pFullScreenToolBar->close();
776 // Delete it when the widget is close
777 m_pFullScreenToolBar = new CFrmFullScreenToolBar(this);
778 QScreen* pScreen = qApp->primaryScreen();
779 if(pScreen) {
780 QPoint pos(pScreen->geometry().left()
781 + (pScreen->geometry().width()
782 - m_pFullScreenToolBar->frameGeometry().width()) / 2,
783 pScreen->geometry().top());
784 qDebug(log) << "Primary screen geometry:" << pScreen->geometry()
785 << "availableGeometry:" << pScreen->availableGeometry()
786 << pos << mapToGlobal(pos);
787 m_pFullScreenToolBar->move(pos);
788 }
789 bool check = connect(m_pFullScreenToolBar, SIGNAL(sigExitFullScreen()),
790 this, SLOT(on_actionFull_screen_F_triggered()));
791 Q_ASSERT(check);
792 check = connect(m_pFullScreenToolBar, SIGNAL(sigExit()),
793 this, SLOT(on_actionExit_E_triggered()));
794 Q_ASSERT(check);
795 Q_ASSERT(check);
796 check = connect(this, SIGNAL(sigOperateMenuChanged(QAction*)),
797 m_pFullScreenToolBar,
798 SLOT(slotOperateMenuChanged(QAction*)));
799 Q_ASSERT(check);
800
801 m_pFullScreenToolBar->show();
802}
803
804void MainWindow::slotViewerFocusIn(QWidget *pView)
805{
806 COperate* c = qobject_cast<COperate*>(sender());
807 qDebug(log) << Q_FUNC_INFO << "Focus:" << c << pView;
808 if(c && m_pView) {
809 m_pView->SetCurrentView(c->GetViewer());
810 }
811}
812
813void MainWindow::slotOperateChanged(COperate *o)
814{
815 if(o && m_pView) {
816 m_pView->SetCurrentView(o->GetViewer());
817 }
818}
819
820void MainWindow::slotCurrentViewChanged(const QWidget* pView)
821{
822 qDebug(log) << Q_FUNC_INFO;
823 if(m_pView && pView)
824 EnableMenu(true);
825 else
826 EnableMenu(false);
827
828 foreach(auto o, m_Operates) {
829 if(o->GetViewer() == pView) {
830 SetSecureLevel(o);
831 foreach (auto a, ui->menuActivity->actions()) {
832 if(a->data().value<COperate*>() == o)
833 a->setChecked(true);
834 }
835 ui->actionStop_other->setText(
836 tr("Stop other except the current \"%1\"").arg(o->Name()));
837 ui->actionStop_other->setStatusTip(ui->actionStop_other->text());
838 ui->actionStop_other->setToolTip(ui->actionStop_other->text());
839 }
840 }
841
842 QTimer::singleShot(0, this, SLOT(slotTimeOut()));
843}
844
845void MainWindow::EnableMenu(bool bEnable)
846{
847 qDebug(log) << Q_FUNC_INFO << bEnable;
848 ui->actionClone->setEnabled(bEnable);
849 ui->actionAdd_to_favorite->setEnabled(bEnable);
850 ui->actionStop->setEnabled(bEnable);
851 ui->actionStop_All->setEnabled(bEnable);
852 ui->actionStop_other->setEnabled(bEnable);
853 if(bEnable) {
854 if(m_Operates.size() > 1)
855 ui->actionStop_other->setEnabled(true);
856 else
857 ui->actionStop_other->setEnabled(false);
858 } else {
859 ui->actionStop_other->setText(tr("Stop other"));
860 }
861 ui->actionTabBar_B->setEnabled(bEnable);
862 ui->menuActivity->setEnabled(bEnable);
863 m_ptbMenuActivity->setEnabled(bEnable);
864 slotLoadOperateMenu();
865}
866
867void MainWindow::slotMenuActivity()
868{
869 QAction* pAction = qobject_cast<QAction*>(sender());
870 Q_ASSERT(pAction);
871 if(!pAction) return;
872 COperate* p = pAction->data().value<COperate*>();
873 if(p)
874 slotOperateChanged(p);
875}
876
877void MainWindow::slotLoadOperateMenu()
878{
879 qDebug(log) << Q_FUNC_INFO;
880
881 if(m_pActionOperateMenu) {
882 ui->menuOperate->removeAction(m_pActionOperateMenu);
883 m_pActionOperateMenu = nullptr;
884 }
885 ui->toolBar->removeAction(m_pActionTBOperate);
886
887 if(!m_pView)
888 return;
889 auto pWin = m_pView->GetCurrentView();
890 if(!pWin) {
891 qDebug(log) << "The current view is empty";
892 return;
893 }
894 foreach(auto op, m_Operates)
895 {
896 if(op->GetViewer() == pWin)
897 {
898 qDebug(log) << "Load plugin menu";
899 auto m = op->GetMenu(ui->menuTools);
900 if(!m) return;
901 // Menu tool bar
902 m_pActionOperateMenu = ui->menuOperate->insertMenu(ui->actionAdd_to_favorite, m);
903 // ToolBar
904 if(!m_pTBOperate)
905 m_pTBOperate = new QToolButton(ui->toolBar);
906 if(m_pTBOperate) {
907 m_pTBOperate->setFocusPolicy(Qt::NoFocus);
908 m_pTBOperate->setPopupMode(QToolButton::InstantPopup);
909 m_pTBOperate->setMenu(m);
910 m_pTBOperate->setIcon(m->icon());
911 m_pTBOperate->setText(m->title());
912 m_pTBOperate->setToolTip(m->toolTip());
913 m_pTBOperate->setStatusTip(m->statusTip());
914 m_pTBOperate->show();
915 m_pActionTBOperate = ui->toolBar->insertWidget(ui->actionAdd_to_favorite, m_pTBOperate);
916 }
917 emit sigOperateMenuChanged(m_pActionOperateMenu);
918 }
919 }
920}
921
929{
930 if(!m_pView)
931 return;
932 auto pWin = m_pView->GetCurrentView();
933 if(!pWin) {
934 qDebug(log) << "The current view is empty";
935 return;
936 }
937 foreach(auto p, m_Operates)
938 {
939 if(p->GetViewer() == pWin)
940 {
941 qDebug(log) << "Load plugin menu";
942 auto m = p->GetMenu(ui->menuTools);
943 if(!m) return;
944 // Note: The view is converted to global coordinates
945 m->exec(pos);
946 }
947 }
948}
949
950void MainWindow::on_actionExit_E_triggered()
951{
952 close();
953}
954
955void MainWindow::keyReleaseEvent(QKeyEvent *event)
956{
957 switch(event->key())
958 {
959 case Qt::Key_Escape:
960 if(isFullScreen())
961 on_actionFull_screen_F_triggered();
962 break;
963 }
964 QMainWindow::keyReleaseEvent(event);
965}
966
967void MainWindow::slotUpdateParameters(COperate *pOperate)
968{
969 m_Manager.SaveOperate(pOperate);
970}
971
972void MainWindow::on_actionClone_triggered()
973{
974 if(!m_pView) return;
975 QWidget* p = m_pView->GetCurrentView();
976 foreach(auto pOperate, m_Operates)
977 {
978 if(pOperate->GetViewer() == p)
979 {
980 QString szFile = pOperate->GetSettingsFile();
981 auto pOperate = m_Manager.LoadOperate(szFile);
982 if(!pOperate) return;
983 Start(pOperate, false, szFile);
984 return;
985 }
986 }
987}
988
989void MainWindow::slotOpenFile(const QString& szFile, bool bOpenSettings)
990{
991 if(szFile.isEmpty()) return;
992 COperate* p = m_Manager.LoadOperate(szFile);
993 if(nullptr == p)
994 {
995 slotStatusMessage(tr("Load file fail: ") + szFile, MessageLevel::Error);
996 return;
997 }
998
999 Start(p, bOpenSettings, szFile);
1000}
1001
1002void MainWindow::on_actionOpenRRCFile_triggered()
1003{
1004 QString szFile = QFileDialog::getOpenFileName(
1005 this,
1006 tr("Open rabbit remote control file"),
1007 RabbitCommon::CDir::Instance()->GetDirUserData(),
1008 tr("Rabbit remote control Files (*.rrc);;All files(*.*)"));
1009 if(szFile.isEmpty()) return;
1010
1011 COperate* p = m_Manager.LoadOperate(szFile);
1012 if(nullptr == p)
1013 {
1014 slotStatusMessage(tr("Load file fail: ") + szFile, MessageLevel::Error);
1015 return;
1016 }
1017
1018 Start(p, true);
1019}
1020
1021void MainWindow::slotStart()
1022{
1023 if(nullptr == m_pView)
1024 {
1025 Q_ASSERT(false);
1026 return;
1027 }
1028 QAction* pAction = qobject_cast<QAction*>(this->sender());
1029 Q_ASSERT(pAction);
1030 COperate* p = m_Manager.CreateOperate(pAction->data().toString());
1031 if(nullptr == p) return;
1032 Start(p, true);
1033}
1034
1045int MainWindow::Start(COperate *pOperate, bool set, QString szFile)
1046{
1047 qDebug(log) << "MainWindow::Start: set:" << set << "; File:" << szFile;
1048 bool bSave = false; //whether is save configure file
1049 Q_ASSERT(pOperate);
1050 bool check = connect(pOperate, SIGNAL(sigRunning()),
1051 this, SLOT(slotRunning()));
1052 Q_ASSERT(check);
1053 check = connect(pOperate, SIGNAL(sigStop()),
1054 this, SLOT(slotStop()));
1055 Q_ASSERT(check);
1056 check = connect(pOperate, SIGNAL(sigFinished()),
1057 this, SLOT(slotFinished()));
1058 Q_ASSERT(check);
1059 check = connect(pOperate, SIGNAL(sigError(const int, const QString &)),
1060 this, SLOT(slotError(const int, const QString&)));
1061 Q_ASSERT(check);
1062 check = connect(pOperate, SIGNAL(sigShowMessageBox(const QString&, const QString&,
1063 const QMessageBox::Icon&)),
1064 this, SLOT(slotShowMessageBox(const QString&, const QString&,
1065 const QMessageBox::Icon&)));
1066 Q_ASSERT(check);
1067 check = connect(pOperate, SIGNAL(sigInformation(const QString&)),
1068 this, SLOT(slotInformation(const QString&)));
1069 Q_ASSERT(check);
1070 check = connect(pOperate, SIGNAL(sigUpdateName(const QString&)),
1071 this, SLOT(slotUpdateName(const QString&)));
1072 Q_ASSERT(check);
1073 check = connect(pOperate, SIGNAL(sigUpdateParameters(COperate*)),
1074 this, SLOT(slotUpdateParameters(COperate*)));
1075 Q_ASSERT(check);
1076 check = connect(pOperate, &COperate::sigFullScreen,
1077 this, [this, pOperate](bool bFull) {
1078 if(m_pView && m_pView->GetCurrentView() == pOperate->GetViewer()) {
1079 if((bFull && !isFullScreen()) || (!bFull && isFullScreen()))
1080 on_actionFull_screen_F_triggered();
1081 }
1082 });
1083 Q_ASSERT(check);
1084 check = connect(pOperate, &COperate::sigSecurityLevel,
1085 this, [this, pOperate]() {
1086 if(m_pView && pOperate) {
1087 if(m_pView->GetCurrentView() == pOperate->GetViewer())
1088 slotCurrentViewChanged(pOperate->GetViewer());
1089 }
1090 });
1091 Q_ASSERT(check);
1092
1093 if(set)
1094 {
1095 int nRet = pOperate->OpenDialogSettings(this);
1096 switch(nRet)
1097 {
1098 case QDialog::Rejected:
1099 m_Manager.DeleteOperate(pOperate);
1100 return 0;
1101 case QDialog::Accepted:
1102 bSave = true;
1103 break;
1104 }
1105 }
1106
1107 if(szFile.isEmpty())
1108 szFile = pOperate->GetSettingsFile();
1109 else
1110 pOperate->SetSettingsFile(szFile);
1111
1112 int nRet = 0;
1113 if(bSave)
1114 nRet = m_Manager.SaveOperate(pOperate);
1115 if(0 == nRet) {
1116 m_pRecentMenu->addRecentFile(szFile, pOperate->Name(), pOperate->Icon());
1118 item.szOperateId = pOperate->Id();
1119 item.icon = pOperate->Icon();
1120 item.szName = pOperate->Name();
1121 item.szProtocol = pOperate->Protocol();
1122 item.szType = pOperate->GetTypeName();
1123 item.szDescription = pOperate->Description();
1124 item.SetFile(szFile);
1125 item.time = QDateTime::currentDateTime();
1126 m_pRecent->AddRecent(item);
1127 }
1128
1129 if(!pOperate->Name().isEmpty())
1130 slotInformation(tr("Starting: ") + pOperate->Name());
1131
1132 //* Show view. \see: slotRunning()
1133 if(m_Operates.contains(pOperate)) {
1134 if(m_pView) {
1135 if(pOperate->GetViewer())
1136 m_pView->SetCurrentView(pOperate->GetViewer());
1137 else {
1138 QString szErr;
1139 szErr += pOperate->metaObject()->className();
1140 szErr += "::GetViewer() ";
1141 szErr += "is nullptr.";
1142 qWarning(log) << szErr;
1143 }
1144 }
1145 return 0;
1146 }
1147 if(m_pView)
1148 {
1149 if(pOperate->GetViewer()) {
1150 m_pView->AddView(pOperate->GetViewer());
1151 m_pView->SetWidowsTitle(pOperate->GetViewer(), pOperate->Name(),
1152 pOperate->Icon(), pOperate->Description());
1153 //qDebug(log) << "View:" << pOperate->GetViewer();
1154 } else {
1155 QString szErr;
1156 szErr += pOperate->metaObject()->className();
1157 szErr += "::GetViewer() ";
1158 szErr += "is nullptr.";
1159 qWarning(log) << szErr;
1160 }
1161 check = connect(pOperate, SIGNAL(sigViewerFocusIn(QWidget*)),
1162 this, SLOT(slotViewerFocusIn(QWidget*)));
1163 Q_ASSERT(check);
1164 }
1165 m_Operates.insert(pOperate);
1166 StartTimer();
1167
1168 m_pFrmActive->slotLoad();
1169 m_pFrmActive->slotViewChanged(m_pView->GetCurrentView());
1170
1171 QVariant vOperate;
1172 vOperate.setValue(pOperate);
1173 QAction* m_pActionmenuActivity = ui->menuActivity->addAction(
1174 pOperate->Icon(), pOperate->Name(), this, SLOT(slotMenuActivity()));
1175 m_pActionmenuActivity->setData(vOperate);
1176 m_pActionmenuActivity->setCheckable(true);
1177 m_pMenuActivityGroup->addAction(m_pActionmenuActivity);
1178 m_pActionmenuActivity->setChecked(true);
1179 //*/
1180
1181 nRet = pOperate->Start();
1182 if(nRet)
1183 pOperate->Stop();
1184 return nRet;
1185}
1186
1188
1192{
1193 COperate* p = qobject_cast<COperate*>(sender());
1194 if(!p) return;
1195
1196 /* If you put it here, when running, the view is not displayed.
1197 So put it in the Start() display view.
1198 See: Start(COperate *p, bool set, QString szFile)
1199 */
1200 /*
1201 if(-1 == m_Operates.indexOf(p)) {
1202 m_Operates.push_back(p);
1203 if(m_pView)
1204 {
1205 m_pView->AddView(p->GetViewer());
1206 m_pView->SetWidowsTitle(p->GetViewer(), p->Name(), p->Icon(), p->Description());
1207 }
1208 } else {
1209 m_pView->SetCurrentView(p->GetViewer());
1210 }
1211 //*/
1212
1213 slotCurrentViewChanged(p->GetViewer());
1214
1215 auto m = p->GetMenu();
1216 if(m) {
1217 m->addSeparator();
1218 m->addAction(ui->actionClone);
1219 m->addAction(ui->actionStop_All);
1220 m->addAction(ui->actionStop_other);
1221 }
1222
1223 slotInformation(tr("Connected to ") + "\"" + p->Name() + "\"");
1224 qDebug(log) << Q_FUNC_INFO << p->Name();
1225}
1227
1228void MainWindow::slotCloseView(const QWidget* pView)
1229{
1230 qDebug(log) << "MainWindow::slotCloseView" << pView;
1231 if(!pView) return;
1232 foreach(auto p, m_Operates)
1233 {
1234 if(p->GetViewer() == pView)
1235 {
1236 //TODO: Whether to save the setting
1237 emit p->sigUpdateParameters(p);
1238 p->Stop();
1239 }
1240 }
1241}
1242
1243void MainWindow::on_actionStop_other_triggered()
1244{
1245 if(!m_pView) return;
1246 foreach(auto p, m_Operates)
1247 {
1248 if(p->GetViewer() != m_pView->GetCurrentView())
1249 {
1250 //TODO: Whether to save the setting
1251 emit p->sigUpdateParameters(p);
1252 p->Stop();
1253 }
1254 }
1255}
1256
1257void MainWindow::on_actionStop_All_triggered()
1258{
1259 foreach(auto p, m_Operates)
1260 {
1261 //TODO: Whether to save the setting
1262 emit p->sigUpdateParameters(p);
1263 p->Stop();
1264 }
1265}
1266
1267void MainWindow::on_actionStop_triggered()
1268{
1269 qDebug(log) << Q_FUNC_INFO;
1270 if(!m_pView) return;
1271
1272 QWidget* pView = m_pView->GetCurrentView();
1273 slotCloseView(pView);
1274}
1275
1276void MainWindow::slotStop()
1277{
1278 COperate* pOperate = qobject_cast<COperate*>(sender());
1279 if(!pOperate) return;
1280 qDebug(log) << Q_FUNC_INFO << pOperate->Name();
1281 //TODO: Whether to save the setting
1282 emit pOperate->sigUpdateParameters(pOperate);
1283 pOperate->Stop();
1284}
1285
1286void MainWindow::slotFinished()
1287{
1288 COperate* pOperate = qobject_cast<COperate*>(sender());
1289 if(!pOperate) return;
1290
1291 qDebug(log) << Q_FUNC_INFO << pOperate->Name();
1292 foreach(auto a, ui->menuActivity->actions()) {
1293 COperate* o = a->data().value<COperate*>();
1294 if(o == pOperate) {
1295 ui->menuActivity->removeAction(a);
1296 m_pMenuActivityGroup->removeAction(a);
1297 }
1298 }
1299 foreach(auto p, m_Operates)
1300 {
1301 if(p == pOperate)
1302 {
1303 m_pView->RemoveView(p->GetViewer());
1304 m_Operates.remove(p);
1305 m_Manager.DeleteOperate(p);
1306 m_pFrmActive->slotLoad();
1307 m_pFrmActive->slotViewChanged(m_pView->GetCurrentView());
1308 break;
1309 }
1310 }
1311 if(m_Operates.isEmpty())
1312 if(m_pActionOperateMenu) {
1313 ui->menuTools->removeAction(m_pActionOperateMenu);
1314 ui->toolBar->removeAction(m_pActionOperateMenu);
1315 m_pActionOperateMenu = nullptr;
1316 }
1317
1318 StartTimer();
1319}
1320
1321// 该函数将label控件变成一个圆形指示灯,需要指定颜色color以及直径size
1322// size 单位是像素
1323void SetIndicator(QLabel* label, QColor color, int size)
1324{
1325 QString min_width = QString("min-width: %1px;").arg(size); // 最小宽度:size
1326 QString min_height = QString("min-height: %1px;").arg(size); // 最小高度:size
1327 QString max_width = QString("max-width: %1px;").arg(size); // 最小宽度:size
1328 QString max_height = QString("max-height: %1px;").arg(size); // 最小高度:size
1329 // 再设置边界形状及边框
1330 QString border_radius = QString("border-radius: %1px;").arg(size / 2); // 边框是圆角,半径为size/2
1331 QString border = QString("border:1px solid ") + color.name() + ";"; // 边框为1px
1332 // 最后设置背景颜色
1333 QString background = "background-color: ";
1334 background += color.name() + ";";
1335 QString SheetStyle = min_width + min_height + max_width + max_height + border_radius + border + background;
1336 label->setStyleSheet(SheetStyle);
1337}
1338
1339void MainWindow::SetSecureLevel(COperate* o)
1340{
1341 if(!m_pSecureLevel) return;
1342 if(o) {
1343 QString szLevel = CSecurityLevel::GetUnicodeIcon(o->GetSecurityLevel());
1344 if(szLevel.isEmpty()) {
1345 m_pSecureLevel->hide();
1346 return;
1347 }
1348 m_pSecureLevel->setText(szLevel);
1349 m_pSecureLevel->setToolTip(CSecurityLevel::GetString(o->GetSecurityLevel()));
1350 m_pSecureLevel->show();
1351 } else
1352 m_pSecureLevel->hide();
1353}
1354
1355void MainWindow::slotSignalConnected()
1356{
1357 m_pSignalStatus->setToolTip(tr("ICE signal status: Connected"));
1358 m_pSignalStatus->setStatusTip(m_pSignalStatus->toolTip());
1359 m_pSignalStatus->setWhatsThis(m_pSignalStatus->toolTip());
1360 //m_pSignalStatus->setText(tr("Connected"));
1361 m_pSignalStatus->setIcon(QIcon::fromTheme("network-wired"));
1362}
1363
1364void MainWindow::slotSignalDisconnected()
1365{
1366 m_pSignalStatus->setToolTip(tr("ICE signal status: Disconnected"));
1367 m_pSignalStatus->setStatusTip(m_pSignalStatus->toolTip());
1368 m_pSignalStatus->setWhatsThis(m_pSignalStatus->toolTip());
1369 //m_pSignalStatus->setText(tr("Disconnected"));
1370 m_pSignalStatus->setIcon(QIcon::fromTheme("network-wireless"));
1371}
1372
1373void MainWindow::slotSignalError(const int nError, const QString &szInfo)
1374{
1375 slotSignalDisconnected();
1376 slotError(nError, szInfo);
1377}
1378
1379void MainWindow::slotSignalPushButtonClicked(bool checked)
1380{
1381#ifdef HAVE_ICE
1382 if(checked)
1383 CICE::Instance()->slotStart();
1384 else
1385 CICE::Instance()->slotStop();
1386#endif
1387}
1388
1389void MainWindow::slotError(const int nError, const QString &szInfo)
1390{
1391 Q_UNUSED(nError);
1392 slotStatusMessage(szInfo, MessageLevel::Error);
1393}
1394
1396 const QString &title, const QString &message,
1397 const QMessageBox::Icon &icon)
1398{
1399 slotInformation(message);
1400 if(!m_Parameter.GetMessageBoxDisplayInformation())
1401 return;
1402
1403 QMessageBox msg(icon, title, message, QMessageBox::Ok, this);
1404 QCheckBox* cb = new QCheckBox(
1405 tr("Use message box to display information"), this);
1406 cb->setChecked(true);
1407 msg.setCheckBox(cb);
1408 RC_SHOW_WINDOW(&msg);
1409 if(!cb->isChecked())
1410 {
1411 m_Parameter.SetMessageBoxDisplayInformation(false);
1412 m_Parameter.Save();
1413 }
1414}
1415
1416void MainWindow::slotInformation(const QString& szInfo)
1417{
1418 slotStatusMessage(szInfo, MessageLevel::Normal);
1419 //statusBar()->showMessage(szInfo);
1420}
1421
1422void MainWindow::slotStatusMessage(QString szMessage, MessageLevel level)
1423{
1424 QString szLevel;
1425 QPalette pe;
1426 switch ((MessageLevel)level) {
1427 case MessageLevel::Error:
1428 pe.setColor(QPalette::WindowText, Qt::red);
1429 szLevel = "X";
1430 break;
1431 case MessageLevel::Warning:
1432 pe.setColor(QPalette::WindowText, Qt::yellow);
1433 szLevel = "!";
1434 break;
1435 default:
1436 break;
1437 }
1438 m_StatusBarMessage.setPalette(pe);
1439 m_StatusBarMessage.setToolTip(szMessage);
1440
1441 //QFontMetrics metrics(m_StatusBarMessage.font());
1442 //szMessage = metrics.elidedText(szMessage, Qt::ElideRight, m_StatusBarMessage.width());
1443
1444 m_StatusBarMessage.setText(szLevel);//*/
1445 statusBar()->showMessage(szMessage);
1446}
1447
1448void MainWindow::slotUpdateName()
1449{
1450 foreach (auto p, m_Operates)
1451 {
1452 if(p->GetViewer()) {
1453 m_pView->SetWidowsTitle(p->GetViewer(),
1454 p->Name(),
1455 p->Icon(),
1456 p->Description());
1457 } else {
1458 QString szErr;
1459 szErr += p->metaObject()->className();
1460 szErr += "::GetViewer() ";
1461 szErr += "is nullptr.";
1462 qWarning(log) << szErr;
1463 }
1464 }
1465}
1466
1467void MainWindow::slotUpdateName(const QString& szName)
1468{
1469 COperate* p = qobject_cast<COperate*>(sender());
1470 if(!p) return;
1471 // Update view
1472 m_pView->SetWidowsTitle(p->GetViewer(), szName,
1473 p->Icon(), p->Description());
1474
1475 // Update recent menu
1476 if(m_pRecentMenu)
1477 m_pRecentMenu->updateRecentFile(p->GetSettingsFile(), szName, p->Icon());
1478
1480 item.SetFile(p->GetSettingsFile());
1481 item.szName = p->Name();
1482 item.szDescription = p->Description();
1483 // Update recent list view dock widget
1484 m_pRecent->UpdateRecent(item);
1485
1486 // Update activity menu
1487 foreach(auto a, ui->menuActivity->actions()) {
1488 if(a->data().value<COperate*>() == p) {
1489 a->setText(szName);
1490 a->setIcon(p->Icon());
1491 break;
1492 }
1493 }
1494
1495 // Update favorite
1496 m_pFavoriteView->slotUpdateFavorite(
1497 p->GetSettingsFile(), szName, p->Description(), p->Icon());
1498
1499 //Update activity list view dock widget
1500 m_pFrmActive->slotLoad();
1501}
1502
1503QAction* MainWindow::GetStartAction(QMenu* pMenu, CPlugin *pPlug)
1504{
1505 QString szTitle;
1506 if(!pPlug->Protocol().isEmpty())
1507 szTitle = pPlug->Protocol() + ": ";
1508 szTitle += pPlug->DisplayName();
1509 QAction* p = pMenu->addAction(szTitle);
1510 p->setToolTip(pPlug->Description());
1511 p->setStatusTip(pPlug->Description());
1512 p->setData(pPlug->Id());
1513 p->setIcon(pPlug->Icon());
1514 return p;
1515}
1516
1517void MainWindow::slotStartByType()
1518{
1519 qDebug(log) << Q_FUNC_INFO;
1520 auto m = ui->menuStart->actions();
1521 foreach(auto a, m) {
1522 a->deleteLater();
1523 }
1524 foreach (auto a, m_MenuStartByType) {
1525 a->deleteLater();
1526 }
1527 ui->menuStart->clear();
1528 m_MenuStartByType.clear();
1529 m_Manager.EnumPlugins(this);
1530}
1531
1532int MainWindow::onProcess(const QString &id, CPlugin *pPlugin)
1533{
1534 Q_UNUSED(id);
1535 QMenu* m = ui->menuStart;
1536 if(m_Parameter.GetStartByType()) {
1537 auto it = m_MenuStartByType.find(pPlugin->Type());
1538 if(it == m_MenuStartByType.end()) {
1539 m = new QMenu(pPlugin->TypeName(pPlugin->Type()), ui->menuStart);
1540 m_MenuStartByType[pPlugin->Type()] = m;
1541 ui->menuStart->addMenu(m);
1542 } else
1543 m = *it;
1544 }
1545 // Start menu and toolbar
1546 QAction* p = GetStartAction(m, pPlugin);
1547 bool check = false;
1548 check = connect(p, SIGNAL(triggered()), this, SLOT(slotStart()));
1549 Q_ASSERT(check);
1550 return 0;
1551}
1552
1553void MainWindow::closeEvent(QCloseEvent *event)
1554{
1555 qDebug(log) << "MainWindow::closeEvent()";
1556
1557 if(m_Parameter.GetSaveMainWindowStatus())
1558 if(isFullScreen())
1559 on_actionFull_screen_F_triggered();
1560
1561 SaveOperateLasterClose();
1562
1563 foreach (auto it, m_Operates)
1564 {
1565 //TODO: Whether to save the setting
1566 emit it->sigUpdateParameters(it);
1567 it->Stop();
1568 }
1569
1570 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
1571 QSettings::IniFormat);
1572 if(m_Parameter.GetSaveMainWindowStatus())
1573 {
1574 set.setValue("MainWindow/Status/Geometry", saveGeometry());
1575 set.setValue("MainWindow/Status/State", saveState());
1576
1577 m_Parameter.SetTabBar(ui->actionTabBar_B->isChecked());
1578 m_Parameter.SetMenuBar(menuBar()->isVisible());
1579 m_Parameter.SetStatusBar(statusBar()->isVisible());
1580 } else {
1581 set.remove("MainWindow/Status/Geometry");
1582 set.remove("MainWindow/Status/State");
1583 }
1584
1585 m_Manager.SaveSettings();
1586 m_Parameter.Save();
1587
1588 QMainWindow::closeEvent(event);
1589
1590 //TODO: Wait for the background thread to exit
1591 QThread::sleep(1);
1592}
1593
1594int MainWindow::LoadOperateLasterClose()
1595{
1596 if(!m_Parameter.GetOpenLasterClose())
1597 return 0;
1598
1599 QFile f(RabbitCommon::CDir::Instance()->GetDirUserConfig()
1600 + QDir::separator() + "LasterClose.dat");
1601 if(f.open(QFile::ReadOnly))
1602 {
1603 QDataStream d(&f);
1604 while(1){
1605 QString szFile;
1606 d >> szFile;
1607 if(szFile.isEmpty())
1608 break;
1609 slotOpenFile(szFile);
1610 }
1611 f.close();
1612 }
1613 return 0;
1614}
1615
1616int MainWindow::SaveOperateLasterClose()
1617{
1618 QFile f(RabbitCommon::CDir::Instance()->GetDirUserConfig()
1619 + QDir::separator() + "LasterClose.dat");
1620 bool bRet = f.open(QFile::WriteOnly);
1621 if(bRet && m_Parameter.GetOpenLasterClose())
1622 {
1623 QDataStream d(&f);
1624 foreach(auto it, m_Operates)
1625 {
1626 d << it->GetSettingsFile();
1627 }
1628 }
1629 f.close();
1630 return 0;
1631}
1632
1633void MainWindow::on_actionTabBar_B_toggled(bool bShow)
1634{
1635 if(m_pView)
1636 {
1637 m_pView->SetVisibleTab(bShow);
1638 m_Parameter.SetTabBar(bShow);
1639 } else {
1640 if(m_pDockActive)
1641 m_pDockActive->setVisible(bShow);
1642 }
1643}
1644
1645void MainWindow::on_actionMain_menu_bar_M_toggled(bool checked)
1646{
1647 qDebug(log) << Q_FUNC_INFO << checked;
1648 if(ui->toolBar->isHidden() && !checked)
1649 {
1650 if( QMessageBox::StandardButton::Yes
1651 == QMessageBox::information(this, tr("Hide menu bar"),
1652 tr("The menu bar will be hidden, the tool bar must be showed."),
1653 QMessageBox::StandardButton::Yes
1654 | QMessageBox::StandardButton::No))
1655 {
1656 ui->actionToolBar_T->setChecked(true);
1657 if(m_pToolBarMenuAction)
1658 m_pToolBarMenuAction->setVisible(true);
1659 } else {
1660 ui->actionMain_menu_bar_M->setChecked(true);
1661#if !defined(Q_OS_ANDROID)
1662 if(m_pToolBarMenuAction)
1663 m_pToolBarMenuAction->setVisible(false);
1664#endif
1665 return;
1666 }
1667 }
1668
1669 menuBar()->setVisible(checked);
1670 m_Parameter.SetMenuBar(checked);
1671#if !defined(Q_OS_ANDROID)
1672 if(m_pToolBarMenuAction)
1673 m_pToolBarMenuAction->setVisible(!checked);
1674#endif
1675}
1676
1677void MainWindow::on_actionToolBar_T_toggled(bool checked)
1678{
1679 qDebug(log) << Q_FUNC_INFO << checked;
1680 if(menuBar()->isHidden() && !checked)
1681 {
1682 if( QMessageBox::StandardButton::Yes
1683 == QMessageBox::information(this, tr("Hide tool bar"),
1684 tr("The tool bar will be hidden, the menu bar must be showed."),
1685 QMessageBox::StandardButton::Yes
1686 | QMessageBox::StandardButton::No))
1687 {
1688 ui->actionMain_menu_bar_M->setChecked(true);
1689 } else {
1690 ui->actionToolBar_T->setChecked(true);
1691 return;
1692 }
1693 }
1694 ui->toolBar->setVisible(checked);
1695}
1696
1697void MainWindow::on_actionStatus_bar_S_toggled(bool checked)
1698{
1699 statusBar()->setVisible(checked);
1700 m_Parameter.SetStatusBar(checked);
1701}
1702
1703void MainWindow::on_actionKeyboard_triggered()
1704{
1705 auto inputMethod = QGuiApplication::inputMethod();
1706 if(inputMethod) {
1707 // QObject *focusObject = QGuiApplication::focusObject();
1708 // if(m_pView && m_pView->GetCurrentView())
1709 // focusObject = m_pView->GetCurrentView();
1710 // if (focusObject) {
1711 // // 可选:强制焦点对象发送输入法请求
1712 // QInputMethodEvent event;
1713 // QCoreApplication::sendEvent(focusObject, &event);
1714 // }
1715 inputMethod->show();
1716 }
1717}
1718
1719// [Get the widget that settings plugin parameters]
1720void MainWindow::on_actionSettings_triggered()
1721{
1722 CParameterDlgSettings set(&m_Parameter, this);
1723 auto viewers = m_Manager.GetSettingsWidgets(&set);
1724 set.AddViewers(viewers);
1725 if(CParameterDlgSettings::Accepted == RC_SHOW_WINDOW(&set))
1726 {
1727 m_Manager.SaveSettings();
1728 m_Parameter.Save();
1729 }
1730 foreach(auto v, viewers) {
1731 v->deleteLater();
1732 }
1733}
1734// [Get the widget that settings plugin parameters]
1735
1736void MainWindow::slotShortCut()
1737{
1738 if(m_Parameter.GetReceiveShortCut())
1739 {
1740 setFocusPolicy(Qt::WheelFocus);
1741 ui->actionFull_screen_F->setShortcuts(QKeySequence::FullScreen);
1742 } else {
1743 setFocusPolicy(Qt::NoFocus);
1744 ui->actionFull_screen_F->setShortcut(QKeySequence());
1745 }
1746}
1747
1748void MainWindow::on_actionOpenListRecent_triggered()
1749{
1750 CFrmRecent* p = new CFrmRecent(this, &m_Manager, m_Parameter, false);
1751 if(!p) return;
1752 bool check = connect(p, SIGNAL(sigStart(const QString&, bool)),
1753 this, SLOT(slotOpenFile(const QString&, bool)));
1754 Q_ASSERT(check);
1755 check = connect(p, SIGNAL(sigAddToFavorite(QString,QString,QString,QIcon)),
1756 m_pFavoriteView, SLOT(slotAddToFavorite(QString,QString,QString,QIcon)));
1757 Q_ASSERT(check);
1758
1759 int nRet = p->Initial();
1760 if(nRet) return;
1761
1762 QDialog d;
1763 d.resize(540, 400);
1764 d.setWindowIcon(windowIcon());
1765 d.setWindowTitle(p->windowTitle());
1766 QGridLayout* pLayout = new QGridLayout(&d);
1767 if(pLayout){
1768 pLayout->addWidget(p);
1769 check = connect(p, SIGNAL(destroyed()), &d, SLOT(reject()));
1770 Q_ASSERT(check);
1771 d.setLayout(pLayout);
1772 }
1773 RC_SHOW_WINDOW(&d);
1774}
1775
1776void MainWindow::on_actionAdd_to_favorite_triggered()
1777{
1778 if(!m_pView || !m_pFavoriteView) return;
1779 QWidget* p = m_pView->GetCurrentView();
1780 foreach(auto c, m_Operates)
1781 {
1782 if(c->GetViewer() == p)
1783 {
1784 m_pFavoriteView->slotAddToFavorite(
1785 c->GetSettingsFile(), c->Name(), c->Description(), c->Icon());
1786 }
1787 }
1788}
1789
1790void MainWindow::dragEnterEvent(QDragEnterEvent *event)
1791{
1792 qDebug(log) << "dragEnterEvent";
1793
1794 if(event->mimeData()->hasUrls())
1795 {
1796 //qDebug(log) << event->mimeData()->urls();
1797 event->acceptProposedAction();
1798 }
1799}
1800
1801void MainWindow::dragMoveEvent(QDragMoveEvent *event)
1802{
1803 //qDebug(log) << "dragMoveEvent";
1804}
1805
1806void MainWindow::dropEvent(QDropEvent *event)
1807{
1808 qDebug(log) << "dropEvent";
1809 bool bRet = false;
1810 if(!event->mimeData()->hasUrls())
1811 return;
1812 auto urls = event->mimeData()->urls();
1813 foreach(auto url, urls)
1814 {
1815 if(url.isLocalFile())
1816 slotOpenFile(url.toLocalFile());
1817 bRet = true;
1818 }
1819 if(bRet)
1820 event->accept();
1821 else
1822 event->ignore();
1823}
1824
1825void MainWindow::slotSystemTrayIconActivated(QSystemTrayIcon::ActivationReason reason)
1826{
1827 //qDebug(log) << "MainWindow::slotSystemTrayIconActivated";
1828
1829 Q_UNUSED(reason)
1830#if defined(Q_OS_ANDROID)
1831 showMaximized();
1832#else
1833 switch(reason)
1834 {
1835 case QSystemTrayIcon::Trigger:
1836 {
1837 showNormal();
1838 activateWindow();
1839 break;
1840 }
1841 default:
1842 break;
1843 }
1844#endif
1845}
1846
1847void MainWindow::slotSystemTrayIconTypeChanged()
1848{
1849 //qDebug(log) << "MainWindow::slotSystemTrayIconTypeChanged:" << m_Parameter.GetEnableSystemTrayIcon();
1850 if(!QSystemTrayIcon::isSystemTrayAvailable())
1851 {
1852 qWarning(log) << "System tray is not available";
1853 return;
1854 }
1855
1856 if(!m_Parameter.GetEnableSystemTrayIcon())
1857 {
1858 qDebug(log) << "Disable system tray icon";
1859 return;
1860 }
1861
1862 if(m_TrayIcon)
1863 m_TrayIcon.reset();
1864
1865 m_TrayIcon = QSharedPointer<QSystemTrayIcon>(new QSystemTrayIcon(this));
1866 if(QSystemTrayIcon::isSystemTrayAvailable())
1867 {
1868 bool check = connect(
1869 m_TrayIcon.data(),
1870 SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
1871 this,
1872 SLOT(slotSystemTrayIconActivated(QSystemTrayIcon::ActivationReason)));
1873 Q_ASSERT(check);
1874 m_TrayIcon->setIcon(this->windowIcon());
1875 m_TrayIcon->setToolTip(windowTitle());
1876 m_TrayIcon->show();
1877 } else
1878 qWarning(log) << "System tray is not available";
1879
1880 switch (m_Parameter.GetSystemTrayIconMenuType())
1881 {
1882 case CParameterApp::SystemTrayIconMenuType::MenuBar:
1883 {
1884 QMenu* pMenu = new QMenu(this);
1885 pMenu->addMenu(ui->menuOperate);
1886 pMenu->addMenu(ui->menuView);
1887 pMenu->addMenu(ui->menuTools);
1888 m_TrayIcon->setContextMenu(pMenu);
1889 break;
1890 }
1891 case CParameterApp::SystemTrayIconMenuType::Operate:
1892 m_TrayIcon->setContextMenu(ui->menuOperate);
1893 break;
1894 case CParameterApp::SystemTrayIconMenuType::RecentOpen:
1895 m_TrayIcon->setContextMenu(m_pRecentMenu);
1896 break;
1897 case CParameterApp::SystemTrayIconMenuType::View:
1898 m_TrayIcon->setContextMenu(ui->menuView);
1899 break;
1900 case CParameterApp::SystemTrayIconMenuType::Tools:
1901 m_TrayIcon->setContextMenu(ui->menuTools);
1902 break;
1903 case CParameterApp::SystemTrayIconMenuType::No:
1904 m_TrayIcon->setContextMenu(nullptr);
1905 break;
1906 }
1907}
1908
1909void MainWindow::slotEnableSystemTrayIcon()
1910{
1911 //qDebug(log) << "MainWindow::slotEnableSystemTryIcon()";
1912 if(m_TrayIcon)
1913 {
1914 if(!m_Parameter.GetEnableSystemTrayIcon())
1915 m_TrayIcon.reset();
1916 } else
1917 slotSystemTrayIconTypeChanged();
1918}
1919
1920void MainWindow::SetStatsVisible(bool visible)
1921{
1922 if(m_SendRate.isVisible() == visible)
1923 return;
1924 m_SendRate.setVisible(visible);
1925 m_ReceivesRate.setVisible(visible);
1926 m_TotalSends.setVisible(visible);
1927 m_TotalReceives.setVisible(visible);
1928}
1929
1930void MainWindow::StartTimer()
1931{
1932 bool bStart = false;
1933 int nMinInterval = 1;
1934 foreach(auto o, m_Operates) {
1935 if(o && o->GetStats()) {
1936 nMinInterval = qMin(nMinInterval, o->GetStats()->GetInterval());
1937 bStart = true;
1938 }
1939 }
1940 if(bStart) {
1941 m_Timer.start(nMinInterval * 1000);
1942 //qDebug(log) << "Time interval:" << nMinInterval;
1943 } else {
1944 m_Timer.stop();
1945 SetStatsVisible(false);
1946 }
1947}
1948
1949void MainWindow::slotTimeOut()
1950{
1951 //qDebug(log) << Q_FUNC_INFO;
1952 auto pWin = m_pView->GetCurrentView();
1953 if(!pWin) {
1954 qDebug(log) << "The current view is empty";
1955 return;
1956 }
1957 foreach(auto p, m_Operates)
1958 {
1959 if(p->GetViewer() == pWin)
1960 {
1961 auto pStats = p->GetStats();
1962 if(!pStats) {
1963 SetStatsVisible(false);
1964 break;
1965 }
1966 SetStatsVisible(true);
1967 pStats->slotCalculating();
1968 m_TotalSends.setText("⇈ " + pStats->TotalSends());
1969 m_TotalReceives.setText("⇊ " + pStats->TotalReceives());
1970 m_SendRate.setText("↑ " + pStats->SendRate());
1971 m_ReceivesRate.setText("↓ " + pStats->ReceiveRate());
1972 break;
1973 }
1974 }
1975}
1976
1977void MainWindow::on_actionUser_manual_triggered()
1978{
1979 QString szUrl = "https://github.com/KangLin/RabbitRemoteControl/wiki/UserManual";
1980 if(RabbitCommon::CTools::GetLanguage() == "zh_CN"
1981 || RabbitCommon::CTools::GetLanguage() == "zh_TW")
1982 szUrl += "_zh_CN";
1983}
1984
1985void MainWindow::on_actionLayoutDefault_triggered()
1986{
1987 qDebug(log) << Q_FUNC_INFO;
1988 if(!m_pDockActive->toggleViewAction()->isChecked())
1989 m_pDockActive->toggleViewAction()->trigger();
1990 if(!m_pDockFavorite->toggleViewAction()->isChecked())
1991 m_pDockFavorite->toggleViewAction()->trigger();
1992 if(!m_pDockRecent->toggleViewAction()->isChecked())
1993 m_pDockRecent->toggleViewAction()->trigger();
1994 m_Parameter.SetTabPosition(QTabWidget::North);
1995 if(!ui->actionTabBar_B->isChecked())
1996 ui->actionTabBar_B->trigger();
1997 if(!ui->actionMain_menu_bar_M->isChecked()) {
1998 ui->actionMain_menu_bar_M->trigger();
1999#if !defined(Q_OS_ANDROID)
2000 m_pToolBarMenuAction->setVisible(false);
2001#endif
2002 }
2003 if(!ui->actionToolBar_T->isChecked())
2004 ui->actionToolBar_T->trigger();
2005 addToolBar(Qt::TopToolBarArea, ui->toolBar);
2006 if(!ui->actionStatus_bar_S->isChecked())
2007 ui->actionStatus_bar_S->trigger();
2008}
2009
2010void MainWindow::on_actionLayoutSimple_triggered()
2011{
2012 qDebug(log) << Q_FUNC_INFO;
2013 if(m_pDockActive->toggleViewAction()->isChecked())
2014 m_pDockActive->toggleViewAction()->trigger();
2015 if(m_pDockFavorite->toggleViewAction()->isChecked())
2016 m_pDockFavorite->toggleViewAction()->trigger();
2017 if(m_pDockRecent->toggleViewAction()->isChecked())
2018 m_pDockRecent->toggleViewAction()->trigger();
2019 m_Parameter.SetTabPosition(QTabWidget::East);
2020 if(!ui->actionTabBar_B->isChecked())
2021 ui->actionTabBar_B->trigger();
2022 if(!ui->actionMain_menu_bar_M->isChecked()) {
2023 ui->actionMain_menu_bar_M->trigger();
2024#if !defined(Q_OS_ANDROID)
2025 m_pToolBarMenuAction->setVisible(false);
2026#endif
2027 }
2028 if(!ui->actionToolBar_T->isChecked())
2029 ui->actionToolBar_T->trigger();
2030 addToolBar(Qt::LeftToolBarArea, ui->toolBar);
2031 if(!ui->actionStatus_bar_S->isChecked())
2032 ui->actionStatus_bar_S->trigger();
2033}
2034
2035void MainWindow::on_actionLayoutMinimalism_triggered()
2036{
2037 qDebug(log) << Q_FUNC_INFO;
2038 if(m_pDockActive->toggleViewAction()->isChecked())
2039 m_pDockActive->toggleViewAction()->trigger();
2040 if(m_pDockFavorite->toggleViewAction()->isChecked())
2041 m_pDockFavorite->toggleViewAction()->trigger();
2042 if(m_pDockRecent->toggleViewAction()->isChecked())
2043 m_pDockRecent->toggleViewAction()->trigger();
2044 m_Parameter.SetTabPosition(QTabWidget::East);
2045 if(ui->actionTabBar_B->isChecked())
2046 ui->actionTabBar_B->trigger();
2047#if !defined(Q_OS_MACOS)
2048 if(ui->actionMain_menu_bar_M->isChecked()) {
2049 ui->actionMain_menu_bar_M->trigger();
2050 m_pToolBarMenuAction->setVisible(true);
2051 }
2052#endif
2053 if(!ui->actionToolBar_T->isChecked())
2054 ui->actionToolBar_T->trigger();
2055#if defined(Q_OS_LINUX)
2056 addToolBar(Qt::RightToolBarArea, ui->toolBar);
2057#else
2058 addToolBar(Qt::LeftToolBarArea, ui->toolBar);
2059#endif
2060 if(ui->actionStatus_bar_S->isChecked())
2061 ui->actionStatus_bar_S->trigger();
2062}
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:560
virtual int EnumPlugins(Handle *handle)
Enum plugins.
Definition Manager.cpp:632
virtual COperate * CreateOperate(const QString &id)
New COperate pointer, the owner is caller.
Definition Manager.cpp:359
virtual COperate * LoadOperate(const QString &szFile)
New COperate pointer from file, the owner is caller.
Definition Manager.cpp:420
virtual int DeleteOperate(COperate *p)
Delete COperate.
Definition Manager.cpp:387
virtual int SaveOperate(COperate *pOperate)
Accept Operate parameters to file.
Definition Manager.cpp:471
int Initial(QString szFile=QString())
Initial.
Definition Manager.cpp:89
virtual int SaveSettings(const QString szFile=QString())
Save Client parameters to file.
Definition Manager.cpp:539
CParameterGlobal * GetGlobalParameters()
Get Global Parameters.
Definition Manager.cpp:553
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.