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