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