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