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