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